[Pkg-javascript-commits] [pdf.js] 107/210: <object> / <embed> support in Chromium extension

David Prévot taffit at moszumanska.debian.org
Thu Jun 5 14:21:07 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch upstream
in repository pdf.js.

commit 3fdd334a7321ba2020701492590b669b4a91d8a7
Author: Rob Wu <rob at robwu.nl>
Date:   Mon May 5 14:20:36 2014 +0200

    <object> / <embed> support in Chromium extension
---
 extensions/chromium/contentscript.js | 109 ++++++++++++++++++++++++++++++++---
 extensions/chromium/contentstyle.css |  13 +++++
 extensions/chromium/manifest.json    |   2 +
 3 files changed, 116 insertions(+), 8 deletions(-)

diff --git a/extensions/chromium/contentscript.js b/extensions/chromium/contentscript.js
index 699e3d2..531e0f7 100644
--- a/extensions/chromium/contentscript.js
+++ b/extensions/chromium/contentscript.js
@@ -25,15 +25,108 @@ function getViewerURL(pdf_url) {
   return VIEWER_URL + '?file=' + encodeURIComponent(pdf_url);
 }
 
-document.addEventListener('beforeload', function(event) {
-  var elem = event.target;
-  if (elem.nodeName.toUpperCase() !== 'EMBED') {
+// (un)prefixed property names
+var createShadowRoot, shadowRoot;
+if (typeof Element.prototype.createShadowRoot !== 'undefined') {
+  // Chrome 35+
+  createShadowRoot = 'createShadowRoot';
+  shadowRoot = 'shadowRoot';
+} else if (typeof Element.prototype.webkitCreateShadowRoot !== 'undefined') {
+  // Chrome 25 - 34
+  createShadowRoot = 'webkitCreateShadowRoot';
+  shadowRoot = 'webkitShadowRoot';
+  try {
+    document.createElement('embed').webkitCreateShadowRoot();
+  } catch (e) {
+    // Only supported since Chrome 33.
+    createShadowRoot = shadowRoot = '';
+  }
+}
+
+// Only observe the document if we can make use of Shadow DOM.
+if (createShadowRoot) {
+  if ('animation' in document.documentElement.style) {
+    document.addEventListener('animationstart', onAnimationStart, true);
+  } else {
+    document.addEventListener('webkitAnimationStart', onAnimationStart, true);
+  }
+}
+
+function onAnimationStart(event) {
+  if (event.animationName === 'pdfjs-detected-object-or-embed') {
+    watchObjectOrEmbed(event.target);
+  }
+}
+
+// Called for every <object> or <embed> element in the page.
+// It does not trigger any Mutation observers, but it may modify the
+// shadow DOM rooted under the given element.
+// Calling this function multiple times for the same element is safe, i.e.
+// it has no side effects.
+function watchObjectOrEmbed(elem) {
+  var mimeType = elem.type;
+  if (mimeType && 'application/pdf' !== mimeType.toLowerCase()) {
+    return;
+  }
+  // <embed src> <object data>
+  var srcAttribute = 'src' in elem ? 'src' : 'data';
+  var path = elem[srcAttribute];
+  if (!mimeType && !/\.pdf($|[?#])/i.test(path)) {
     return;
   }
-  if (!/^application\/pdf$/i.test(elem.type)) {
+
+  if (elem[shadowRoot]) {
+    // If the element already has a shadow root, assume that we've already
+    // seen this element.
     return;
   }
-  event.preventDefault();
-  elem.type = 'text/html';
-  elem.src = getViewerURL(elem.src);
-}, true);
+  elem[createShadowRoot]();
+
+  function updateViewerFrame() {
+    var path = elem[srcAttribute];
+    if (!path) {
+      elem[shadowRoot].textContent = '';
+    } else {
+      elem[shadowRoot].innerHTML =
+        // Set display: inline-block; to the host element (<embed>/<object>) to
+        // ensure that the dimensions defined on the host element are applied to
+        // the iframe (http://crbug.com/358648).
+        // The styles are declared in the shadow DOM to allow page authors to
+        // override these styles (e.g. .style.display = 'none';).
+        '<style>\n' +
+        // Chrome 35+
+        ':host { display: inline-block; }\n' +
+        // Chrome 33 and 34 (not 35+ because of http://crbug.com/351248)
+        '*:not(style):not(iframe) { display: inline-block; }\n' +
+        'iframe { width: 100%; height: 100%; border: 0; }\n' +
+        '</style>' +
+        '<iframe allowfullscreen></iframe>';
+      elem[shadowRoot].lastChild.src = getEmbeddedViewerURL(path);
+    }
+  }
+
+  updateViewerFrame();
+
+  // Watch for page-initiated changes of the src/data attribute.
+  var srcObserver = new MutationObserver(updateViewerFrame);
+  srcObserver.observe(elem, {
+    attributes: true,
+    childList: false,
+    characterData: false,
+    attributeFilter: [srcAttribute]
+  });
+}
+
+// Get the viewer URL, provided that the path is a valid URL.
+function getEmbeddedViewerURL(path) {
+  var fragment = /^([^#]*)(#.*)?$/.exec(path);
+  path = fragment[1];
+  fragment = fragment[2] || '';
+
+  // Resolve relative path to document.
+  var a = document.createElement('a');
+  a.href = document.baseURI;
+  a.href = path;
+  path = a.href;
+  return getViewerURL(path) + fragment;
+}
diff --git a/extensions/chromium/contentstyle.css b/extensions/chromium/contentstyle.css
new file mode 100644
index 0000000..1277bb5
--- /dev/null
+++ b/extensions/chromium/contentstyle.css
@@ -0,0 +1,13 @@
+/**
+ * Detect creation of <embed> and <object> tags.
+ */
+ at -webkit-keyframes pdfjs-detected-object-or-embed { from {} }
+ at keyframes         pdfjs-detected-object-or-embed { from {} }
+object, embed {
+  -webkit-animation-delay: 0s !important;
+  -webkit-animation-name: pdfjs-detected-object-or-embed !important;
+  -webkit-animation-play-state: running !important;
+  animation-delay: 0s !important;
+  animation-name: pdfjs-detected-object-or-embed !important;
+  animation-play-state: running !important;
+}
diff --git a/extensions/chromium/manifest.json b/extensions/chromium/manifest.json
index f3c71ab..a8dabb2 100644
--- a/extensions/chromium/manifest.json
+++ b/extensions/chromium/manifest.json
@@ -25,6 +25,8 @@
       "file://*/*"
     ],
     "run_at": "document_start",
+    "all_frames": true,
+    "css": ["contentstyle.css"],
     "js": ["contentscript.js"]
   }],
   "file_browser_handlers": [{

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/pdf.js.git



More information about the Pkg-javascript-commits mailing list