Title: [290089] trunk/Source/WebCore
Revision
290089
Author
[email protected]
Date
2022-02-17 16:27:59 -0800 (Thu, 17 Feb 2022)

Log Message

PDF.js viewer should work for all kinds of URLs
https://bugs.webkit.org/show_bug.cgi?id=236525
rdar://problem/88832961

Reviewed by Tim Nguyen.

This patch starts loading the pdf as an array buffer after it's recieved
by calling the PDFJS viewer's open function through the content script's
wrapper. More work is needed to potentially present the data as a
PDFDataRangeTransport.

* Modules/pdfjs-extras/content-script.js:
(const.PDFJSContentScript.init):
(const.PDFJSContentScript.open):
* html/PDFDocument.cpp:
(WebCore::PDFDocumentEventListener::handleEvent):
(WebCore::PDFDocument::createDocumentStructure):
(WebCore::PDFDocument::updateDuringParsing):
(WebCore::PDFDocument::finishedParsing):
(WebCore::PDFDocument::sendPDFArrayBuffer):
(WebCore::PDFDocument::injectContentScript):
* html/PDFDocument.h:
(WebCore::PDFDocumentEventListener::handleEvent):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (290088 => 290089)


--- trunk/Source/WebCore/ChangeLog	2022-02-18 00:14:59 UTC (rev 290088)
+++ trunk/Source/WebCore/ChangeLog	2022-02-18 00:27:59 UTC (rev 290089)
@@ -1,3 +1,29 @@
+2022-02-17  J Pascoe  <[email protected]>
+
+        PDF.js viewer should work for all kinds of URLs
+        https://bugs.webkit.org/show_bug.cgi?id=236525
+        rdar://problem/88832961
+
+        Reviewed by Tim Nguyen.
+
+        This patch starts loading the pdf as an array buffer after it's recieved
+        by calling the PDFJS viewer's open function through the content script's
+        wrapper. More work is needed to potentially present the data as a
+        PDFDataRangeTransport.
+
+        * Modules/pdfjs-extras/content-script.js:
+        (const.PDFJSContentScript.init):
+        (const.PDFJSContentScript.open):
+        * html/PDFDocument.cpp:
+        (WebCore::PDFDocumentEventListener::handleEvent):
+        (WebCore::PDFDocument::createDocumentStructure):
+        (WebCore::PDFDocument::updateDuringParsing):
+        (WebCore::PDFDocument::finishedParsing):
+        (WebCore::PDFDocument::sendPDFArrayBuffer):
+        (WebCore::PDFDocument::injectContentScript):
+        * html/PDFDocument.h:
+        (WebCore::PDFDocumentEventListener::handleEvent):
+
 2022-02-17  Chris Dumez  <[email protected]>
 
         Pass registrable domain to CoreLocation API

Modified: trunk/Source/WebCore/Modules/pdfjs-extras/content-script.js (290088 => 290089)


--- trunk/Source/WebCore/Modules/pdfjs-extras/content-script.js	2022-02-18 00:14:59 UTC (rev 290088)
+++ trunk/Source/WebCore/Modules/pdfjs-extras/content-script.js	2022-02-18 00:27:59 UTC (rev 290089)
@@ -31,6 +31,9 @@
     },
     init() {
         this.injectStyle();
+    },
+    open(data) {
+        PDFViewerApplication.open(data);
     }
 };
 

Modified: trunk/Source/WebCore/html/PDFDocument.cpp (290088 => 290089)


--- trunk/Source/WebCore/html/PDFDocument.cpp	2022-02-18 00:14:59 UTC (rev 290088)
+++ trunk/Source/WebCore/html/PDFDocument.cpp	2022-02-18 00:27:59 UTC (rev 290089)
@@ -107,12 +107,14 @@
 
 void PDFDocumentEventListener::handleEvent(ScriptExecutionContext&, Event& event)
 {
-    auto* iframe = dynamicDowncast<HTMLIFrameElement>(event.target());
-    ASSERT(iframe, "Should have event target");
-
-    if (event.type() == eventNames().loadEvent) {
-        m_document->injectContentScript(*iframe->contentDocument());
-    }
+    if (is<HTMLIFrameElement>(event.target()) && event.type() == eventNames().loadEvent) {
+        m_document->injectContentScript();
+    } else if (is<HTMLScriptElement>(event.target()) && event.type() == eventNames().loadEvent) {
+        m_document->setContentScriptLoaded(true);
+        if (m_document->isFinishedParsing())
+            m_document->sendPDFArrayBuffer();
+    } else
+        ASSERT_NOT_REACHED();
 }
 
 bool PDFDocumentEventListener::operator==(const EventListener& other) const
@@ -135,6 +137,7 @@
 
 void PDFDocument::createDocumentStructure()
 {
+    // The empty file parameter prevents default pdf from loading.
     auto viewerURL = "webkit-pdfjs-viewer://pdfjs/web/viewer.html?file=";
     auto rootElement = HTMLHtmlElement::create(*this);
     appendChild(rootElement);
@@ -146,35 +149,68 @@
     body->setAttribute(styleAttr, AtomString("margin: 0px;height: 100vh;", AtomString::ConstructFromLiteral));
     rootElement->appendChild(body);
 
-    auto iframe = HTMLIFrameElement::create(HTMLNames::iframeTag, *this);
-    iframe->setAttribute(srcAttr, makeString(viewerURL, encodeWithURLEscapeSequences(url().string())));
-    iframe->setAttribute(styleAttr, AtomString("width: 100%; height: 100%; border: 0; display: block;", AtomString::ConstructFromLiteral));
-    body->appendChild(iframe);
+    m_iframe = HTMLIFrameElement::create(HTMLNames::iframeTag, *this);
+    m_iframe->setAttribute(srcAttr, AtomString(viewerURL));
+    m_iframe->setAttribute(styleAttr, AtomString("width: 100%; height: 100%; border: 0; display: block;", AtomString::ConstructFromLiteral));
 
-    auto listener = PDFDocumentEventListener::create(*this);
-    iframe->addEventListener("load", listener.copyRef(), false);
+    m_listener = PDFDocumentEventListener::create(*this);
+    m_iframe->addEventListener("load", *m_listener, false);
 
-    m_viewerRendered = true;
+    body->appendChild(*m_iframe);
 }
 
 void PDFDocument::updateDuringParsing()
 {
-    if (!m_viewerRendered)
+    if (!m_iframe)
         createDocumentStructure();
 }
 
 void PDFDocument::finishedParsing()
 {
-    ASSERT(m_viewerRendered);
+    ASSERT(m_iframe);
+    m_isFinishedParsing = true;
+    if (m_isContentScriptLoaded)
+        sendPDFArrayBuffer();
 }
 
-void PDFDocument::injectContentScript(Document& contentDocument)
+void PDFDocument::sendPDFArrayBuffer()
 {
-    ASSERT(contentDocument.body());
+    using namespace JSC;
 
-    auto script = HTMLScriptElement::create(scriptTag, contentDocument, false, false);
+    auto* frame = m_iframe->contentFrame();
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=236668 - Use postMessage
+    auto openFunction = frame->script().executeScriptIgnoringException("PDFJSContentScript.open").getObject();
+
+    auto globalObject = this->globalObject();
+    auto& vm = globalObject->vm();
+
+    JSLockHolder lock(vm);
+    auto callData = getCallData(vm, openFunction);
+    ASSERT(callData.type != CallData::Type::None);
+    MarkedArgumentBuffer arguments;
+    auto arrayBuffer = loader()->mainResourceData()->tryCreateArrayBuffer();
+    if (!arrayBuffer) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    auto sharingMode = arrayBuffer->sharingMode();
+    arguments.append(JSArrayBuffer::create(vm, globalObject->arrayBufferStructure(sharingMode), WTFMove(arrayBuffer)));
+    ASSERT(!arguments.hasOverflowed());
+
+    call(globalObject, openFunction, callData, globalObject, arguments);
+}
+
+void PDFDocument::injectContentScript()
+{
+    auto contentDocument = m_iframe->contentDocument();
+    ASSERT(contentDocument->body());
+
+    auto script = HTMLScriptElement::create(scriptTag, *contentDocument, false);
+    script->addEventListener("load", m_listener.releaseNonNull(), false);
+
     script->setAttribute(srcAttr, "webkit-pdfjs-viewer://pdfjs/extras/content-script.js");
-    contentDocument.body()->appendChild(script);
+    contentDocument->body()->appendChild(script);
 }
 
 }

Modified: trunk/Source/WebCore/html/PDFDocument.h (290088 => 290089)


--- trunk/Source/WebCore/html/PDFDocument.h	2022-02-18 00:14:59 UTC (rev 290088)
+++ trunk/Source/WebCore/html/PDFDocument.h	2022-02-18 00:27:59 UTC (rev 290089)
@@ -29,6 +29,7 @@
 namespace WebCore {
 
 class HTMLIFrameElement;
+class PDFDocumentEventListener;
 
 class PDFDocument final : public HTMLDocument {
     WTF_MAKE_ISO_ALLOCATED(PDFDocument);
@@ -40,8 +41,12 @@
 
     void updateDuringParsing();
     void finishedParsing();
-    void injectContentScript(Document& contentDocument);
+    void injectContentScript();
 
+    void sendPDFArrayBuffer();
+    bool isFinishedParsing() const { return m_isFinishedParsing; }
+    void setContentScriptLoaded(bool loaded) { m_isContentScriptLoaded = loaded; }
+
 private:
     PDFDocument(Frame&, const URL&);
 
@@ -48,7 +53,10 @@
     Ref<DocumentParser> createParser() override;
 
     void createDocumentStructure();
-    bool m_viewerRendered { false };
+    bool m_isFinishedParsing { false };
+    bool m_isContentScriptLoaded { false };
+    RefPtr<HTMLIFrameElement> m_iframe;
+    RefPtr<PDFDocumentEventListener> m_listener;
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to