Handles embed tags via PlayPreview API
This commit is contained in:
		
							parent
							
								
									4247339d28
								
							
						
					
					
						commit
						61a3b3d035
					
				
							
								
								
									
										36
									
								
								extensions/firefox/bootstrap.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								extensions/firefox/bootstrap.js
									
									
									
									
										vendored
									
									
								
							@ -16,7 +16,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
/* jshint esnext:true */
 | 
					/* jshint esnext:true */
 | 
				
			||||||
/* globals Components, Services, dump, XPCOMUtils, PdfStreamConverter,
 | 
					/* globals Components, Services, dump, XPCOMUtils, PdfStreamConverter,
 | 
				
			||||||
           APP_SHUTDOWN */
 | 
					           PdfRedirector, APP_SHUTDOWN */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,6 +32,9 @@ const Cr = Components.results;
 | 
				
			|||||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 | 
					Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 | 
				
			||||||
Cu.import('resource://gre/modules/Services.jsm');
 | 
					Cu.import('resource://gre/modules/Services.jsm');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var Ph = Cc['@mozilla.org/plugin/host;1'].getService(Ci.nsIPluginHost);
 | 
				
			||||||
 | 
					var registerOverlayPreview = 'getPlayPreviewInfo' in Ph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getBoolPref(pref, def) {
 | 
					function getBoolPref(pref, def) {
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    return Services.prefs.getBoolPref(pref);
 | 
					    return Services.prefs.getBoolPref(pref);
 | 
				
			||||||
@ -53,8 +56,10 @@ function log(str) {
 | 
				
			|||||||
  dump(str + '\n');
 | 
					  dump(str + '\n');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Register/unregister a constructor as a component.
 | 
					// Factory that registers/unregisters a constructor as a component.
 | 
				
			||||||
var Factory = {
 | 
					function Factory() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Factory.prototype = {
 | 
				
			||||||
  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
 | 
					  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
 | 
				
			||||||
  _targetConstructor: null,
 | 
					  _targetConstructor: null,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -88,6 +93,9 @@ var Factory = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var pdfStreamConverterUrl = null;
 | 
					var pdfStreamConverterUrl = null;
 | 
				
			||||||
 | 
					var pdfStreamConverterFactory = new Factory();
 | 
				
			||||||
 | 
					var pdfRedirectorUrl = null;
 | 
				
			||||||
 | 
					var pdfRedirectorFactory = new Factory();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// As of Firefox 13 bootstrapped add-ons don't support automatic registering and
 | 
					// As of Firefox 13 bootstrapped add-ons don't support automatic registering and
 | 
				
			||||||
// unregistering of resource urls and components/contracts. Until then we do
 | 
					// unregistering of resource urls and components/contracts. Until then we do
 | 
				
			||||||
@ -105,7 +113,17 @@ function startup(aData, aReason) {
 | 
				
			|||||||
  pdfStreamConverterUrl = aData.resourceURI.spec +
 | 
					  pdfStreamConverterUrl = aData.resourceURI.spec +
 | 
				
			||||||
                          'components/PdfStreamConverter.js';
 | 
					                          'components/PdfStreamConverter.js';
 | 
				
			||||||
  Cu.import(pdfStreamConverterUrl);
 | 
					  Cu.import(pdfStreamConverterUrl);
 | 
				
			||||||
  Factory.register(PdfStreamConverter);
 | 
					  pdfStreamConverterFactory.register(PdfStreamConverter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (registerOverlayPreview) {
 | 
				
			||||||
 | 
					    pdfRedirectorUrl = aData.resourceURI.spec +
 | 
				
			||||||
 | 
					                       'components/PdfRedirector.js';
 | 
				
			||||||
 | 
					    Cu.import(pdfRedirectorUrl);
 | 
				
			||||||
 | 
					    pdfRedirectorFactory.register(PdfRedirector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ph.registerPlayPreviewMimeType('application/pdf', true,
 | 
				
			||||||
 | 
					      'data:application/x-moz-playpreview-pdfjs;,');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function shutdown(aData, aReason) {
 | 
					function shutdown(aData, aReason) {
 | 
				
			||||||
@ -117,10 +135,18 @@ function shutdown(aData, aReason) {
 | 
				
			|||||||
  // Remove the resource url.
 | 
					  // Remove the resource url.
 | 
				
			||||||
  resProt.setSubstitution(RESOURCE_NAME, null);
 | 
					  resProt.setSubstitution(RESOURCE_NAME, null);
 | 
				
			||||||
  // Remove the contract/component.
 | 
					  // Remove the contract/component.
 | 
				
			||||||
  Factory.unregister();
 | 
					  pdfStreamConverterFactory.unregister();
 | 
				
			||||||
  // Unload the converter
 | 
					  // Unload the converter
 | 
				
			||||||
  Cu.unload(pdfStreamConverterUrl);
 | 
					  Cu.unload(pdfStreamConverterUrl);
 | 
				
			||||||
  pdfStreamConverterUrl = null;
 | 
					  pdfStreamConverterUrl = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (registerOverlayPreview) {
 | 
				
			||||||
 | 
					    pdfRedirectorFactory.unregister();
 | 
				
			||||||
 | 
					    Cu.unload(pdfRedirectorUrl);
 | 
				
			||||||
 | 
					    pdfRedirectorUrl = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ph.unregisterPlayPreviewMimeType('application/pdf');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function install(aData, aReason) {
 | 
					function install(aData, aReason) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										155
									
								
								extensions/firefox/components/PdfRedirector.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								extensions/firefox/components/PdfRedirector.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,155 @@
 | 
				
			|||||||
 | 
					/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | 
				
			||||||
 | 
					/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 | 
				
			||||||
 | 
					/* Copyright 2012 Mozilla Foundation
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/* jshint esnext:true */
 | 
				
			||||||
 | 
					/* globals Components, Services, XPCOMUtils, NetUtil, dump */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var EXPORTED_SYMBOLS = ['PdfRedirector'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Cc = Components.classes;
 | 
				
			||||||
 | 
					const Ci = Components.interfaces;
 | 
				
			||||||
 | 
					const Cr = Components.results;
 | 
				
			||||||
 | 
					const Cu = Components.utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const PDF_CONTENT_TYPE = 'application/pdf';
 | 
				
			||||||
 | 
					const FIREFOX_ID = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 | 
				
			||||||
 | 
					Cu.import('resource://gre/modules/Services.jsm');
 | 
				
			||||||
 | 
					Cu.import('resource://gre/modules/NetUtil.jsm');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getDOMWindow(aChannel) {
 | 
				
			||||||
 | 
					  var requestor = aChannel.notificationCallbacks ?
 | 
				
			||||||
 | 
					                  aChannel.notificationCallbacks :
 | 
				
			||||||
 | 
					                  aChannel.loadGroup.notificationCallbacks;
 | 
				
			||||||
 | 
					  var win = requestor.getInterface(Components.interfaces.nsIDOMWindow);
 | 
				
			||||||
 | 
					  return win;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getObjectUrl(window) {
 | 
				
			||||||
 | 
					  var url;
 | 
				
			||||||
 | 
					  var element = window.frameElement;
 | 
				
			||||||
 | 
					  var isOverlay = false;
 | 
				
			||||||
 | 
					  var params = {};
 | 
				
			||||||
 | 
					  if (element) {
 | 
				
			||||||
 | 
					    var tagName = element.nodeName;
 | 
				
			||||||
 | 
					    while (tagName != 'EMBED' && tagName != 'OBJECT') {
 | 
				
			||||||
 | 
					      // plugin overlay skipping until the target plugin is found
 | 
				
			||||||
 | 
					      isOverlay = true;
 | 
				
			||||||
 | 
					      element = element.parentNode;
 | 
				
			||||||
 | 
					      if (!element)
 | 
				
			||||||
 | 
					        throw 'Plugin element is not found';
 | 
				
			||||||
 | 
					      tagName = element.nodeName;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (tagName == 'EMBED') {
 | 
				
			||||||
 | 
					      for (var i = 0; i < element.attributes.length; ++i) {
 | 
				
			||||||
 | 
					        params[element.attributes[i].localName] = element.attributes[i].value;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      url = params.src;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      for (var i = 0; i < element.childNodes.length; ++i) {
 | 
				
			||||||
 | 
					        var paramElement = element.childNodes[i];
 | 
				
			||||||
 | 
					        if (paramElement.nodeType != Ci.nsIDOMNode.ELEMENT_NODE ||
 | 
				
			||||||
 | 
					            paramElement.nodeName != 'PARAM') {
 | 
				
			||||||
 | 
					          continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params[paramElement.getAttribute('name')] =
 | 
				
			||||||
 | 
					          paramElement.getAttribute('value');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      var dataAttribute = element.getAttribute('data');
 | 
				
			||||||
 | 
					      url = dataAttribute || params.movie || params.src;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!url) {
 | 
				
			||||||
 | 
					    return url; // src is not specified
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var element = window.frameElement;
 | 
				
			||||||
 | 
					  // XXX base uri?
 | 
				
			||||||
 | 
					  var baseUri = !element ? null :
 | 
				
			||||||
 | 
					    Services.io.newURI(element.ownerDocument.location.href, null, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return Services.io.newURI(url, null, baseUri).spec;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function PdfRedirector() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PdfRedirector.prototype = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // properties required for XPCOM registration:
 | 
				
			||||||
 | 
					  classID: Components.ID('{8cbfd8d0-2042-4976-b3ef-d9dee1efb975}'),
 | 
				
			||||||
 | 
					  classDescription: 'pdf.js Redirector',
 | 
				
			||||||
 | 
					  contractID:
 | 
				
			||||||
 | 
					    '@mozilla.org/streamconv;1?from=application/x-moz-playpreview-pdfjs&to=*/*',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  QueryInterface: XPCOMUtils.generateQI([
 | 
				
			||||||
 | 
					      Ci.nsIStreamConverter,
 | 
				
			||||||
 | 
					      Ci.nsIStreamListener,
 | 
				
			||||||
 | 
					      Ci.nsIRequestObserver
 | 
				
			||||||
 | 
					  ]),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // nsIStreamConverter::convert
 | 
				
			||||||
 | 
					  convert: function(aFromStream, aFromType, aToType, aCtxt) {
 | 
				
			||||||
 | 
					    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // nsIStreamConverter::asyncConvertData
 | 
				
			||||||
 | 
					  asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
 | 
				
			||||||
 | 
					    // Store the listener passed to us
 | 
				
			||||||
 | 
					    this.listener = aListener;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // nsIStreamListener::onDataAvailable
 | 
				
			||||||
 | 
					  onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
 | 
				
			||||||
 | 
					    // Do nothing since all the data loading is handled by the viewer.
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // nsIRequestObserver::onStartRequest
 | 
				
			||||||
 | 
					  onStartRequest: function(aRequest, aContext) {
 | 
				
			||||||
 | 
					    // Setup the request so we can use it below.
 | 
				
			||||||
 | 
					    aRequest.QueryInterface(Ci.nsIChannel);
 | 
				
			||||||
 | 
					    // Cancel the request so the viewer can handle it.
 | 
				
			||||||
 | 
					    aRequest.cancel(Cr.NS_BINDING_ABORTED);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var domWindow = getDOMWindow(aRequest);
 | 
				
			||||||
 | 
					    var pdfUrl = getObjectUrl(domWindow);
 | 
				
			||||||
 | 
					    if (!pdfUrl) {
 | 
				
			||||||
 | 
					      Services.console.logStringMessage(
 | 
				
			||||||
 | 
					        'PdfRedirector.js: PDF location is not specified for OBJECT/EMBED tag');
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Create a new channel that is viewer loaded as a resource.
 | 
				
			||||||
 | 
					    var ioService = Services.io;
 | 
				
			||||||
 | 
					    var channel = ioService.newChannel(pdfUrl, null, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    channel.loadGroup = aRequest.loadGroup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    channel.asyncOpen(this.listener, aContext);
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // nsIRequestObserver::onStopRequest
 | 
				
			||||||
 | 
					  onStopRequest: function(aRequest, aContext, aStatusCode) {
 | 
				
			||||||
 | 
					    // Do nothing
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var NSGetFactory = XPCOMUtils.generateNSGetFactory([PdfRedirector]);
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user