refactoring _NetWebView2_LoadWait() by adding __NetWebView2_WaitForReadyState()#89
Draft
mlipok wants to merge 24 commits intoioa747:mainfrom
Draft
refactoring _NetWebView2_LoadWait() by adding __NetWebView2_WaitForReadyState()#89mlipok wants to merge 24 commits intoioa747:mainfrom
mlipok wants to merge 24 commits intoioa747:mainfrom
Conversation
Contributor
Author
|
@ioa747 please take a look I have such result: |
5 tasks
Contributor
Author
@ioa747 please check it out |
Contributor
Author
|
I notice that the first commit was empty/broken Thus I did it again: |
Owner
I saw it, I left trash inside, I didn't clean it. Here is the clean one. #AutoIt3Wrapper_UseX64=y
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
#include "..\NetWebView2Lib.au3"
; 006-DownloadDemo.au3
Global $_sURLDownload_InProgress = ''
_Example()
Func _Example()
Local $oMyError = ObjEvent("AutoIt.Error", __NetWebView2_COMErrFunc)
#forceref $oMyError
#Region ; GUI CREATION
; Create the GUI
Local $hGUI = GUICreate("WebView2 .NET Manager - [ Press ESC to cancel the download ]", 1000, 800)
; Initialize WebView2 Manager and register events
Local $oWebV2M = _NetWebView2_CreateManager("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0", "__UserEventHandler__", "--mute-audio")
If @error Then Return SetError(@error, @extended, $oWebV2M)
; create JavaScript Bridge object
Local $oJSBridge = _NetWebView2_GetBridge($oWebV2M, "")
If @error Then Return SetError(@error, @extended, $oWebV2M)
; initialize browser - put it on the GUI
Local $sProfileDirectory = @ScriptDir & "\NetWebView2Lib-UserDataFolder"
_NetWebView2_Initialize($oWebV2M, $hGUI, $sProfileDirectory, 0, 0, 0, 0, True, True, True, 1.2, "0x2B2B2B")
; show the GUI after browser was fully initialized
GUISetState(@SW_SHOW)
#EndRegion ; GUI CREATION
; BlockedVirtualKeys
; A comma-separated list of Virtual Key codes to be blocked synchronously (e.g., "116,123").
; `object.BlockedVirtualKeys = "116,123"`
; Block F5 (116) and F12 (123) AcceleratorKey!
$oWebV2M.BlockedVirtualKeys = "116,123"
; Silent Download Setting
$oWebV2M.IsDownloadUIEnabled = False
; Set default Download Path (Create the folder if it doesn't exist)
$oWebV2M.SetDownloadPath(@ScriptDir & "\Downloads_Test")
; navigate to the page
_NetWebView2_Navigate($oWebV2M, "https://www.libreoffice.org/donate/dl/win-x86_64/25.8.4/en-US/LibreOffice_25.8.4_Win_x86-64.msi", $NETWEBVIEW2_MESSAGE__NAV_STARTING)
#Region ; GUI Loop
; Main Loop
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
GUIDelete($hGUI)
#EndRegion ; GUI Loop
_NetWebView2_CleanUp($oWebV2M, $oJSBridge)
EndFunc ;==>_Example
; Advise using 'Volatile' for Event Handlers to ensure the WebView2 COM thread can interrupt the main script safely.
Volatile Func __UserEventHandler__OnDownloadStateChanged($oWebV2M, $hGUI, $sState, $sURL, $iTotal_Bytes, $iReceived_Bytes)
#forceref $oWebV2M
$hGUI = HWnd("0x" & Hex($hGUI, 16))
Local $iPercent = 0
If $iTotal_Bytes > 0 Then $iPercent = Round(($iReceived_Bytes / $iTotal_Bytes), 5) * 100
; Convert to MB for easy-to-read log
Local $iReceived_MegaBytes = Round($iReceived_Bytes / 1024 / 1024)
Local $iTotal_MegaBytes = Round($iTotal_Bytes / 1024 / 1024)
Local Const $s_Message = " " & $iPercent & "% (" & $iReceived_MegaBytes & " / " & $iTotal_MegaBytes & " Mega Bytes)"
Local Static $bProgres_State = 0
Switch $sState
Case "InProgress"
If $bProgres_State = 0 Then
ProgressOn("Dowload in progress", StringRegExpReplace($sURL, '(.+/)(.+)', '$2'), $s_Message, -1, -1, BitOR($DLG_NOTONTOP, $DLG_MOVEABLE))
EndIf
$_sURLDownload_InProgress = $sURL
ProgressSet(Round($iPercent), $s_Message)
$bProgres_State = 1
Case "Interrupted"
ProgressSet(100, "Done", "Interrupted")
Sleep(3000)
ProgressOff()
$bProgres_State = 0
$_sURLDownload_InProgress = ''
Case "Completed"
ProgressSet(100, "Done", "Completed")
Sleep(3000)
ProgressOff()
$bProgres_State = 0
$_sURLDownload_InProgress = ''
EndSwitch
EndFunc ;==>__UserEventHandler__OnDownloadStateChanged
; Advise using 'Volatile' for Event Handlers to ensure the WebView2 COM thread can interrupt the main script safely.
Volatile Func __UserEventHandler__OnAcceleratorKeyPressed($oWebV2M, $hGUI, $oArgs)
Local Const $sArgsList = '[VirtualKey=' & $oArgs.VirtualKey & _ ; The VK code of the key.
'; KeyEventKind=' & $oArgs.KeyEventKind & _ ; Type of key event (Down, Up, etc.).
'; Handled=' & $oArgs.Handled & _ ; Set to `True` to stop the browser from processing the key.
'; RepeatCount=' & $oArgs.RepeatCount & _ ; The number of times the key has repeated.
'; ScanCode=' & $oArgs.ScanCode & _ ; Hardware scan code.
'; IsExtendedKey=' & $oArgs.IsExtendedKey & _ ; True if it's an extended key (e.g., right Alt).
'; IsMenuKeyDown=' & $oArgs.IsMenuKeyDown & _ ; True if Alt is pressed.
'; WasKeyDown=' & $oArgs.WasKeyDown & _ ; True if the key was already down.
'; IsKeyReleased=' & $oArgs.IsKeyReleased & _ ; True if the event is a key up.
'; KeyEventLParam=' & $oArgs.KeyEventLParam & ']' ; Gets the LPARAM value that accompanied the window message.
Local Const $s_Prefix = "[USER:EVENT: OnAcceleratorKeyPressed]:: GUI:" & $hGUI & " ARGS: " & ((IsObj($oArgs)) ? ($sArgsList) : ('ERROR'))
; Example of checking specific keys
Switch $oArgs.VirtualKey
Case Int($VK_F7)
ConsoleWrite("! Blocked: F7 caret browsing." & @CRLF)
$oArgs.Handled = True
Case Int($VK_N)
; Check if Ctrl is pressed (using _IsPressed for Ctrl as IsMenuKeyDown specifically targets Alt)
; Use this to block shortcuts like Ctrl+N (New Window)
If _IsPressed("11") Then
ConsoleWrite("! Blocked: Ctrl+N shortcut." & @CRLF)
$oArgs.Handled = True
EndIf
Case Int($VK_ESCAPE) ; ESC 27 1b 033 Escape
; Cancels active downloads. If `uri` is empty or omitted, cancels all active downloads.
$oWebV2M.CancelDownloads()
EndSwitch
__NetWebView2_Log(@ScriptLineNumber, $s_Prefix, 0)
$oArgs = 0 ; Explicitly release the COM reference inside the volatile scope
EndFunc ;==>__UserEventHandler__OnAcceleratorKeyPressed |
Owner
|
I also worked with the 014-pdfJS-Static_PDF_Viewer.au3 that you suggested. #WIP - this Example is imported from 1.5.0 UDF - and is in "WORK IN PROGRESS" state
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Run_AU3Check=Y
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#Au3Stripper_Ignore_Funcs=__NetWebView2_WebEvents_*,__NetWebView2_JSEvents_*
; 014-pdfJS-Static_PDF_Viewer.au3
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; ⚠️ to make this work, download pdfJS library from https://mozilla.github.io/pdf.js/
; for example:
; https://github.com/mozilla/pdf.js/releases/download/v5.4.624/pdfjs-5.4.624-dist.zip
; and unzip to: @ScriptDir & "\JS_Lib\pdfjs\"
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "..\NetWebView2Lib.au3"
; Global objects
Global $oBridge
Global $hGUI
_Example()
Func _Example()
Local $oMyError = ObjEvent("AutoIt.Error", __NetWebView2_COMErrFunc)
#forceref $oMyError
#Region ; GUI CREATION
; Create the GUI
$hGUI = GUICreate("WebView2 .NET Manager", 800, 1000)
; Get the WebView2 Manager object and register events
Local $oWeb = _NetWebView2_CreateManager("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0", _
"", "--allow-file-access-from-files") ; 👈
; initialize browser - put it on the GUI
Local $sProfileDirectory = @ScriptDir & "\NetWebView2Lib-UserDataFolder"
_NetWebView2_Initialize($oWeb, $hGUI, $sProfileDirectory, 0, 0, 0, 0, True, False, False, 0.7)
; Get the bridge object and register events
_NetWebView2_GetBridge($oWeb, "__MyEVENTS_Bridge_")
; show the GUI after browser was fully initialized
GUISetState(@SW_SHOW)
#EndRegion ; GUI CREATION
; Adds a JavaScript to be executed before any other script when a new page is loaded.
Local $sScriptId = New_NetWebView2_AddInitializationScript($oWeb, @ScriptDir & "\JS_Lib\PDF_Tools.js")
ConsoleWrite("$sScriptId=" & $sScriptId & @CRLF)
; navigate to the page
__SetupStaticPDF($oWeb, @ScriptDir & "\invoice-plugin-sample.pdf", True, False, True)
; now I call the script directly from the js library
_NetWebView2_ExecuteScript($oWeb, "PDF_ExtractToJSON();", $NETWEBVIEW2_EXECUTEJS_MODE0_FIREANDFORGET)
;~ _NetWebView2_ExecuteScript($oWeb, "PDF_ExtractLegacy();", $NETWEBVIEW2_EXECUTEJS_MODE0_FIREANDFORGET)
Sleep(500)
MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "after" & @CRLF & "PDF_ExtractToJSON();")
_NetWebView2_ExecuteScript($oWeb, "PDF_HighlightSpansContainingText('January 31, 2016', 'red', 'yellow');", $NETWEBVIEW2_EXECUTEJS_MODE0_FIREANDFORGET)
MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "after" & @CRLF & "PDF_HighlightSpansContainingText('January 31, 2016', 'red', 'yellow');")
_NetWebView2_ExecuteScript($oWeb, "PDF_HighlightSpansContainingText('Total Due', 'white', 'red');", $NETWEBVIEW2_EXECUTEJS_MODE0_FIREANDFORGET)
MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "after" & @CRLF & "PDF_HighlightSpansContainingText('Total Due', 'white', 'red');")
_NetWebView2_ExecuteScript($oWeb, "PDF_RemoveHighlights('January 31, 2016');", $NETWEBVIEW2_EXECUTEJS_MODE0_FIREANDFORGET)
MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "after" & @CRLF & "PDF_RemoveHighlights('January 31, 2016');")
; Main Loop
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
GUIDelete($hGUI)
_NetWebView2_CleanUp($oWeb, $oBridge)
EndFunc ;==>_Example
; Handles custom messages from JavaScript (window.chrome.webview.postMessage)
Func __MyEVENTS_Bridge_OnMessageReceived($oWebV2M, $hGUI, $sMsg)
#forceref $oWebV2M, $hGUI
ConsoleWrite("$sMsg=" & $sMsg & @CRLF)
ConsoleWrite(">>> [__EVENTS_Bridge]: " & (StringLen($sMsg) > 150 ? StringLeft($sMsg, 150) & "..." : $sMsg) & @CRLF)
Local $sFirstChar = StringLeft($sMsg, 1)
If $sFirstChar = "{" Or $sFirstChar = "[" Then ; 1. JSON Messaging
ConsoleWrite("+> : Processing JSON Messaging..." & @CRLF)
Local $oJson = ObjCreate("NetJson.Parser")
If Not IsObj($oJson) Then Return ConsoleWrite("!> Error: Failed to create NetJson object." & @CRLF)
$oJson.Parse($sMsg)
Local $sJobType = $oJson.GetTokenValue("type")
Switch $sJobType
Case "COM_TEST"
ConsoleWrite("- COM_TEST Confirmed: " & $oJson.GetTokenValue("status") & @CRLF)
Case "PDF_DATA_PACKAGE"
ConsoleWrite("> PDF Metadata: " & $oJson.GetTokenValue("metadata.title") & " by " & $oJson.GetTokenValue("metadata.author") & @CRLF)
; Loop through pages (if your parser supports it)
Local $iPages = $oJson.GetTokenValue("metadata.pagesCount")
For $i = 0 To $iPages - 1
ConsoleWrite("- Page " & ($i + 1) & " content: " & StringLeft($oJson.GetTokenValue("pages[" & $i & "].text"), 150) & "..." & @CRLF)
Next
EndSwitch
Else ; 2. Legacy / Native Pipe-Delimited Messaging
ConsoleWrite("+> : Legacy / Native Pipe-Delimited Messaging..." & @CRLF)
Local $sCommand, $sData, $iSplitPos
$iSplitPos = StringInStr($sMsg, "|") - 1
If $iSplitPos < 0 Then
$sCommand = StringStripWS($sMsg, 3)
$sData = ""
Else
$sCommand = StringStripWS(StringLeft($sMsg, $iSplitPos), 3)
$sData = StringTrimLeft($sMsg, $iSplitPos + 1)
EndIf
Switch $sCommand
Case "COM_TEST"
ConsoleWrite("- Status: Legacy COM_TEST: " & $sData & @CRLF)
Case "PDF_TEXT_RESULT"
ConsoleWrite("- PDF_TEXT_RESULT: " & @CRLF & $sData & @CRLF)
Case "ERROR"
ConsoleWrite("! Status: " & $sData & @CRLF)
EndSwitch
EndIf
EndFunc ;==>__MyEVENTS_Bridge_OnMessageReceived
Func __SetupStaticPDF(ByRef $oWeb, $s_PDF_Path, $bBlockLinks = False, $bBlockSelection = False, $bShowToolbar = False)
; 🏆 https://mozilla.github.io/pdf.js/
Local $sBlockLinksJS = ""
Local $sBlockLinksCSS = ""
Local $sSelectionCSS = ""
; 1. Configuration for BlockLinks
If $bBlockLinks Then
$sBlockLinksJS = _
"window.addEventListener('click', function(e) {" & _
" if (e.target.tagName === 'A' || e.target.closest('a')) {" & _
" e.stopImmediatePropagation();" & _
" e.preventDefault();" & _
" }" & _
"}, { capture: true });"
$sBlockLinksCSS = " .annotationLayer { pointer-events: none !important; } "
EndIf
; 2. Configuration for Text Selection
If $bBlockSelection Then
$sSelectionCSS = " .textLayer, body { -webkit-user-select: none !important; user-select: none !important; cursor: default !important; } "
EndIf
; 3. Final Script Construction
Local $sCleanupJS = _
"/* 1. Block Zoom (Wheel & Keys) */ " & _
"window.addEventListener('wheel', function(e) {" & _
" if (e.ctrlKey) {" & _
" e.stopImmediatePropagation();" & _
" e.preventDefault();" & _
" }" & _
"}, { passive: false, capture: true });" & _
"window.addEventListener('keydown', function(e) {" & _
" if (e.ctrlKey && ['+', '-', '=', '0'].includes(e.key)) {" & _
" e.stopImmediatePropagation();" & _
" e.preventDefault();" & _
" }" & _
"}, { capture: true });" & _
$sBlockLinksJS & _
"/* 2. PDF Text Extraction Function with Auto-Wait */ " & _
"window.extractPDFText = async function() {" & _
" const runExtraction = async () => {" & _
" try {" & _
" if (typeof PDFViewerApplication !== 'undefined' && PDFViewerApplication.pdfDocument) {" & _
" const pdf = PDFViewerApplication.pdfDocument;" & _
" let text = '';" & _
" for (let i = 1; i <= pdf.numPages; i++) {" & _
" const page = await pdf.getPage(i);" & _
" const content = await page.getTextContent();" & _
" text += content.items.map(item => item.str).join(' ') + '\n';" & _
" }" & _
" window.chrome.webview.postMessage('PDF_TEXT|' + text);" & _
" } else {" & _
" setTimeout(runExtraction, 500);" & _
" }" & _
" } catch (e) {" & _
" window.chrome.webview.postMessage('JS_ERROR|extractPDFText() SLN=" & @ScriptLineNumber & "' + e.message);" & _
" }" & _
" };" & _
" runExtraction();" & _
"};" & _
"/* 3. Style Injection */ " & _
"window.addEventListener('DOMContentLoaded', () => {" & _
" const style = document.createElement('style');" & _
" style.innerHTML = " & (($bShowToolbar) ? ("") : ("'#toolbarContainer, #sidebarContainer { display: none !important; } ' + ")) & _
" '#viewerContainer { top: 0 !important; bottom: 0 !important; overflow: hidden !important; } ' + " & _
" '" & $sBlockLinksCSS & "' + " & _
" '" & $sSelectionCSS & "' + " & _
" ' ::-webkit-scrollbar { display: none !important; }';" & _
" document.head.appendChild(style);" & _
"});" & _
"/* 4. HighLight text */ " & _
"function highlightSpansContainingText(searchText, borderColor = 'red', backgroundColor = 'yellow') {" & _
" if (!searchText || typeof searchText !== 'string') return;" & _
" const normalize = str => str.replace(/\s+/g, ' ').trim().toLowerCase();" & _
" const normalizedSearch = normalize(searchText);" & _
" const spans = document.querySelectorAll('span');" & _
" spans.forEach(span => {" & _
" // Reset previous highlights in this SPAN" & _
" if (!span.dataset.originalText) {" & _
" span.dataset.originalText = span.innerHTML; // preserve original content" & _
" } else {" & _
" span.innerHTML = span.dataset.originalText; // restore previous state" & _
" }" & _
" const spanText = span.textContent;" & _
" const spanTextNormalized = normalize(spanText);" & _
" if (spanTextNormalized.includes(normalizedSearch)) {" & _
" const regex = new RegExp(searchText, 'gi');" & _
" span.innerHTML = spanText.replace(regex, match => {" & _
" return `<span data-highlight-by-au3udf='true' style='border:1px solid ${borderColor}; background-color:${backgroundColor}; color:black; padding:1px;'>${match}</span>`;" & _
" });" & _
" }" & _
" });" & _
"};" & _
"function removeHighlights(searchText) {" & _
" if (!searchText || typeof searchText !== 'string') return;" & _
" const normalize = str => str.replace(/\s+/g, ' ').trim().toLowerCase();" & _
" const normalizedSearch = normalize(searchText);" & _
" // Find all highlighted SPANs" & _
" const highlightedSpans = document.querySelectorAll('span[data-highlight-by-au3udf=\'true\']');" & _
" highlightedSpans.forEach(innerSpan => {" & _
" const parentSpan = innerSpan.parentElement;" & _
" if (!parentSpan || !parentSpan.dataset.originalText) return;" & _
" // Check if the highlighted fragment contains searchText" & _
" const spanText = innerSpan.textContent;" & _
" if (normalize(spanText).includes(normalizedSearch)) {" & _
" // Restore parent's original content" & _
" parentSpan.innerHTML = parentSpan.dataset.originalText;" & _
" delete parentSpan.dataset.originalText;" & _
" }" & _
" });" & _
"};" & _
""
$oWeb.AddInitializationScript($sCleanupJS)
; Fix slashes in Path for URL
Local $s_PDF_URL = StringReplace($s_PDF_Path, "\", "/")
$s_PDF_URL = $oWeb.EncodeURI($s_PDF_URL)
Local $s_PDF_JS_URL = StringReplace(@ScriptDir & "\JS_Lib\pdfjs\web\viewer.html" & "?file=", "\", "/")
Local $s_Viewer_URL = "file:///" & $s_PDF_JS_URL & $s_PDF_URL
ConsoleWrite("- $s_Viewer_URL= " & $s_Viewer_URL & @CRLF)
$oWeb.Navigate($s_Viewer_URL)
_NetWebView2_WaitForReadyState($oWeb)
;~ _NetWebView2_Navigate($oWeb, $s_Viewer_URL, $NETWEBVIEW2_MESSAGE__TITLE_CHANGED, 5000)
ConsoleWrite("! we're done with navigation, but check how many more messages there are below. SLN=" & @ScriptLineNumber & @CRLF)
;~ MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, 'Wait for all messages to full loading PDF by pdf.js')
; $oWeb.IsZoomControlEnabled = False ; <--- It doesn't work in PDF.
$oWeb.DisableBrowserFeatures()
$oWeb.LockWebView()
EndFunc ;==>__SetupStaticPDF
; Polls the browser until the document.readyState reaches 'complete'.
Func _NetWebView2_WaitForReadyState($oWebV2M, $iTimeout_ms = 5000)
Local Const $s_Prefix = ">>>[_NetWebView2_WaitForReadyState]:"
If Not IsObj($oWebV2M) Then Return SetError(2, 0, False)
Local $hTimer = TimerInit()
Local $sReadyState = ""
While 1
; Execute JS via the Bridge (Mode 2)
$sReadyState = _NetWebView2_ExecuteScript($oWebV2M, "document.readyState", $NETWEBVIEW2_EXECUTEJS_MODE2_RESULT)
; Check for the 'complete' state
If $sReadyState == "complete" Then
__NetWebView2_Log(@ScriptLineNumber, $s_Prefix & " SUCCESS: Document is ready. Timeout_ms: " & Round(TimerDiff($hTimer), 0), 0)
Return True
EndIf
; Check for C# Bridge internal errors (Timeout/Init)
If StringLeft($sReadyState, 6) == "ERROR:" Then
__NetWebView2_Log(@ScriptLineNumber, $s_Prefix & " BRIDGE " & $sReadyState & " Timeout_ms: " & Round(TimerDiff($hTimer), 0), 1)
Return SetError(3, 0, False)
EndIf
; Check for AutoIt-side Timeout
If $iTimeout_ms > 0 And TimerDiff($hTimer) > $iTimeout_ms Then
__NetWebView2_Log(@ScriptLineNumber, $s_Prefix & " TIMEOUT: Document state is " & $sReadyState & " Timeout_ms: " & Round(TimerDiff($hTimer), 0), 1)
Return SetError(1, 0, False)
EndIf
Sleep(100)
WEnd
EndFunc ;==>_NetWebView2_WaitForReadyState
; New to replace _NetWebView2_AddInitializationScript in UDF
Func New_NetWebView2_AddInitializationScript($oWebV2M, $vScript)
If Not IsObj($oWebV2M) Then Return SetError(1, 0, "ERROR: Invalid Object")
; Smart Detection
If FileExists($vScript) Then $vScript = FileRead($vScript)
Local $sScriptId = $oWebV2M.AddInitializationScript($vScript)
If StringInStr($sScriptId, "ERROR:") Then Return SetError(2, 0, $sScriptId)
Return SetError(0, 0, $sScriptId)
EndFunc ;==>_NetWebView2_AddInitializationScript
|
Owner
|
The PDF_Tools.js file is also needed in the @ScriptDir & "\JS_Lib\PDF_Tools.js" folder /**
* PDF_Tools.js - Final Combined Library
*/
async function PDF_ExtractToJSON() {
try {
const pdfUrl = window.PDFViewerApplication.url;
const pdf = await pdfjsLib.getDocument(pdfUrl).promise;
const meta = await pdf.getMetadata();
let pdfData = {
type: 'PDF_DATA_PACKAGE',
metadata: {
title: meta.info.Title || 'N/A',
author: meta.info.Author || 'N/A',
pagesCount: pdf.numPages
},
pages: []
};
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const content = await page.getTextContent();
pdfData.pages.push({
pageIndex: i,
text: content.items.map(item => item.str).join(' ')
});
}
window.chrome.webview.postMessage(JSON.stringify(pdfData));
} catch (e) {
window.chrome.webview.postMessage(JSON.stringify({type: 'error', message: e.message}));
}
}
async function PDF_ExtractLegacy() {
try {
const pdfUrl = window.PDFViewerApplication.url;
const pdf = await pdfjsLib.getDocument(pdfUrl).promise;
let fullText = "";
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const textContent = await page.getTextContent();
fullText += "[Page " + i + "]\n" + textContent.items.map(item => item.str).join(" ") + "\n\n";
}
window.chrome.webview.postMessage("PDF_TEXT_RESULT|" + fullText);
} catch (error) {
window.chrome.webview.postMessage("ERROR|" + error.message);
}
}
// --- Highlighting Engine ---
function PDF_HighlightSpansContainingText(text, color, backColor) {
const spans = document.querySelectorAll('.textLayer span');
spans.forEach(span => {
if (span.textContent.includes(text)) {
span.style.color = color;
span.style.backgroundColor = backColor;
span.style.opacity = "1";
}
});
}
// Alias for PDF_HighlightAndScroll
function PDF_HighlightAndScroll(text, color, backColor) {
const spans = document.querySelectorAll('.textLayer span');
let firstFound = null;
spans.forEach(span => {
if (span.textContent.includes(text)) {
span.style.color = color;
span.style.backgroundColor = backColor;
span.style.opacity = "1";
if (!firstFound) firstFound = span;
}
});
if (firstFound) firstFound.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
/**
* Removes highlights.
* If 'text' is provided, it only clears matches for that text.
* If 'text' is empty/null, it clears ALL highlights on the page.
*/
function PDF_RemoveHighlights(text = null) {
const spans = document.querySelectorAll('.textLayer span');
spans.forEach(span => {
// If text is null OR if the span contains the target text
if (!text || span.textContent.includes(text)) {
span.style.color = "";
span.style.backgroundColor = "";
span.style.opacity = "";
}
});
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
Thanks for your effort and interest 💛 in improving the project. It's very appreciated.
Description
__NetWebView2_WaitForReadyState() was added to
🔗 Linked GitHub Issues
#87
Closes #\87
📋 What is the current behavior?
#87
🚀 What is the new behavior?
Type of changes
Breaking changes 🔥
How and where was this tested?
🖥️ Describe where you tested your changes
System:
Context:
NetJson.ParserNetWebView2.Manager - WebView2NetWebView2.Manager - Bridge🔬 Describe how you tested your changes
Checklist
Additional context
none
Screenshots
none
Note to reviewers
none