mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound on a CLOSED TREE.
This commit is contained in:
commit
9a0ba8199c
@ -9,8 +9,6 @@ this.EXPORTED_SYMBOLS = [ "DeveloperToolbar", "CommandUtils" ];
|
||||
const NS_XHTML = "http://www.w3.org/1999/xhtml";
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource:///modules/devtools/Commands.jsm");
|
||||
@ -26,7 +24,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "gcli",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "CmdCommands",
|
||||
"resource:///modules/devtools/BuiltinCommands.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ConsoleServiceListener",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PageErrorListener",
|
||||
"resource://gre/modules/devtools/WebConsoleUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
|
||||
@ -437,8 +435,8 @@ DeveloperToolbar.prototype._initErrorsCount = function DT__initErrorsCount(aTab)
|
||||
}
|
||||
|
||||
let window = aTab.linkedBrowser.contentWindow;
|
||||
let listener = new ConsoleServiceListener(window, {
|
||||
onConsoleServiceMessage: this._onPageError.bind(this, tabId),
|
||||
let listener = new PageErrorListener(window, {
|
||||
onPageError: this._onPageError.bind(this, tabId),
|
||||
});
|
||||
listener.init();
|
||||
|
||||
@ -595,8 +593,7 @@ DeveloperToolbar.prototype.handleEvent = function DT_handleEvent(aEvent)
|
||||
DeveloperToolbar.prototype._onPageError =
|
||||
function DT__onPageError(aTabId, aPageError)
|
||||
{
|
||||
if (!(aPageError instanceof Ci.nsIScriptError) ||
|
||||
aPageError.category == "CSS Parser" ||
|
||||
if (aPageError.category == "CSS Parser" ||
|
||||
aPageError.category == "CSS Loader") {
|
||||
return;
|
||||
}
|
||||
|
@ -130,7 +130,6 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_bug_862916_console_dir_and_filter_off.js \
|
||||
browser_console_native_getters.js \
|
||||
browser_bug_871156_ctrlw_close_tab.js \
|
||||
browser_console_nsiconsolemessage.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Check that nsIConsoleMessages show in the Browser Console and in the Web
|
||||
// Console. See bug 859756.
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<title>bug859756</title>\n" +
|
||||
"<p>hello world\n<p>nsIConsoleMessages ftw!";
|
||||
|
||||
let gWebConsole, gJSTerm, gVariablesView;
|
||||
|
||||
function test()
|
||||
{
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", function onLoad() {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
|
||||
// Test for cached nsIConsoleMessages.
|
||||
sendMessage("test1 for bug859756", "cat2012");
|
||||
|
||||
openConsole(null, consoleOpened);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function sendMessage(aMessage, aCategory)
|
||||
{
|
||||
let windowID = WebConsoleUtils.getInnerWindowId(content);
|
||||
let consoleMsg = Cc["@mozilla.org/consolemessage;1"]
|
||||
.createInstance(Ci.nsIConsoleMessage);
|
||||
consoleMsg.initMessage(aMessage, aCategory, windowID);
|
||||
Services.console.logMessage(consoleMsg);
|
||||
}
|
||||
|
||||
function consoleOpened(hud)
|
||||
{
|
||||
gWebConsole = hud;
|
||||
gJSTerm = hud.jsterm;
|
||||
|
||||
// Send a message with no window ID.
|
||||
Services.console.logStringMessage("do-not-show-me");
|
||||
|
||||
sendMessage("test2 for bug859756", "cat2013");
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "test1 for bug859756",
|
||||
category: CATEGORY_JS,
|
||||
},
|
||||
{
|
||||
text: "test2 for bug859756",
|
||||
category: CATEGORY_JS,
|
||||
},
|
||||
],
|
||||
}).then(onLogMessages);
|
||||
}
|
||||
|
||||
function onLogMessages()
|
||||
{
|
||||
let text = gWebConsole.outputNode.textContent;
|
||||
is(text.indexOf("do-not-show-me"), -1,
|
||||
"message without window ID is not displayed");
|
||||
closeConsole(null, onWebConsoleClose);
|
||||
}
|
||||
|
||||
function onWebConsoleClose()
|
||||
{
|
||||
HUDConsoleUI.toggleBrowserConsole().then(onBrowserConsoleOpen);
|
||||
}
|
||||
|
||||
function onBrowserConsoleOpen(hud)
|
||||
{
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "test1 for bug859756",
|
||||
category: CATEGORY_JS,
|
||||
},
|
||||
{
|
||||
text: "test2 for bug859756",
|
||||
category: CATEGORY_JS,
|
||||
},
|
||||
{
|
||||
text: "do-not-show-me",
|
||||
category: CATEGORY_JS,
|
||||
},
|
||||
],
|
||||
}).then(finishTest);
|
||||
}
|
@ -956,14 +956,11 @@ WebConsoleFrame.prototype = {
|
||||
aRemoteMessages.forEach(function(aMessage) {
|
||||
switch (aMessage._type) {
|
||||
case "PageError": {
|
||||
let category = Utils.categoryForConsoleMessage(aMessage);
|
||||
let category = Utils.categoryForScriptError(aMessage);
|
||||
this.outputMessage(category, this.reportPageError,
|
||||
[category, aMessage]);
|
||||
break;
|
||||
}
|
||||
case "LogMessage":
|
||||
this.handleLogMessage(aMessage);
|
||||
break;
|
||||
case "ConsoleAPI":
|
||||
this.outputMessage(CATEGORY_WEBDEV, this.logConsoleAPIMessage,
|
||||
[aMessage]);
|
||||
@ -1191,26 +1188,10 @@ WebConsoleFrame.prototype = {
|
||||
*/
|
||||
handlePageError: function WCF_handlePageError(aPageError)
|
||||
{
|
||||
let category = Utils.categoryForConsoleMessage(aPageError);
|
||||
let category = Utils.categoryForScriptError(aPageError);
|
||||
this.outputMessage(category, this.reportPageError, [category, aPageError]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle log messages received from the server. This method outputs the given
|
||||
* message.
|
||||
*
|
||||
* @param object aPacket
|
||||
* The message packet received from the server.
|
||||
*/
|
||||
handleLogMessage: function WCF_handleLogMessage(aPacket)
|
||||
{
|
||||
let category = Utils.categoryForConsoleMessage(aPacket.category);
|
||||
this.outputMessage(category, () => {
|
||||
return this.createMessageNode(category, SEVERITY_LOG, aPacket.message,
|
||||
null, null, null, null, aPacket.timeStamp);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Log network event.
|
||||
*
|
||||
@ -4356,17 +4337,17 @@ var Utils = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine the category of a given nsIConsoleMessage.
|
||||
* Determine the category of a given nsIScriptError.
|
||||
*
|
||||
* @param nsIConsoleMessage aMessage
|
||||
* The message you want to determine the category for.
|
||||
* @param nsIScriptError aScriptError
|
||||
* The script error you want to determine the category for.
|
||||
* @return CATEGORY_JS|CATEGORY_CSS|CATEGORY_SECURITY
|
||||
* Depending on the message kind CATEGORY_JS, CATEGORY_CSS, or
|
||||
* Depending on the script error CATEGORY_JS, CATEGORY_CSS, or
|
||||
* CATEGORY_SECURITY can be returned.
|
||||
*/
|
||||
categoryForConsoleMessage: function Utils_categoryForConsoleMessage(aMessage)
|
||||
categoryForScriptError: function Utils_categoryForScriptError(aScriptError)
|
||||
{
|
||||
switch (aMessage.category) {
|
||||
switch (aScriptError.category) {
|
||||
case "CSS Parser":
|
||||
case "CSS Loader":
|
||||
return CATEGORY_CSS;
|
||||
@ -4527,7 +4508,6 @@ function WebConsoleConnectionProxy(aWebConsole, aTarget)
|
||||
this.target = aTarget;
|
||||
|
||||
this._onPageError = this._onPageError.bind(this);
|
||||
this._onLogMessage = this._onLogMessage.bind(this);
|
||||
this._onConsoleAPICall = this._onConsoleAPICall.bind(this);
|
||||
this._onNetworkEvent = this._onNetworkEvent.bind(this);
|
||||
this._onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this);
|
||||
@ -4631,7 +4611,6 @@ WebConsoleConnectionProxy.prototype = {
|
||||
|
||||
let client = this.client = this.target.client;
|
||||
|
||||
client.addListener("logMessage", this._onLogMessage);
|
||||
client.addListener("pageError", this._onPageError);
|
||||
client.addListener("consoleAPICall", this._onConsoleAPICall);
|
||||
client.addListener("networkEvent", this._onNetworkEvent);
|
||||
@ -4752,23 +4731,6 @@ WebConsoleConnectionProxy.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The "logMessage" message type handler. We redirect any message to the UI
|
||||
* for displaying.
|
||||
*
|
||||
* @private
|
||||
* @param string aType
|
||||
* Message type.
|
||||
* @param object aPacket
|
||||
* The message received from the server.
|
||||
*/
|
||||
_onLogMessage: function WCCP__onLogMessage(aType, aPacket)
|
||||
{
|
||||
if (this.owner && aPacket.from == this._consoleActor) {
|
||||
this.owner.handleLogMessage(aPacket);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The "consoleAPICall" message type handler. We redirect any message to
|
||||
* the UI for displaying.
|
||||
@ -4896,7 +4858,6 @@ WebConsoleConnectionProxy.prototype = {
|
||||
}
|
||||
|
||||
this.client.removeListener("pageError", this._onPageError);
|
||||
this.client.removeListener("logMessage", this._onLogMessage);
|
||||
this.client.removeListener("consoleAPICall", this._onConsoleAPICall);
|
||||
this.client.removeListener("networkEvent", this._onNetworkEvent);
|
||||
this.client.removeListener("networkEventUpdate", this._onNetworkEventUpdate);
|
||||
|
@ -1,4 +1,4 @@
|
||||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 0.8.47
|
||||
Current extension version is: 0.8.169
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
/* jshint esnext:true */
|
||||
/* globals Components, Services, XPCOMUtils, NetUtil, PrivateBrowsingUtils,
|
||||
dump */
|
||||
dump, NetworkManager */
|
||||
|
||||
'use strict';
|
||||
|
||||
@ -37,6 +37,7 @@ const MAX_DATABASE_LENGTH = 4096;
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/NetUtil.jsm');
|
||||
Cu.import('resource://pdf.js/network.js');
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils',
|
||||
'resource://gre/modules/PrivateBrowsingUtils.jsm');
|
||||
@ -190,9 +191,8 @@ PdfDataListener.prototype = {
|
||||
};
|
||||
|
||||
// All the priviledged actions.
|
||||
function ChromeActions(domWindow, dataListener, contentDispositionFilename) {
|
||||
function ChromeActions(domWindow, contentDispositionFilename) {
|
||||
this.domWindow = domWindow;
|
||||
this.dataListener = dataListener;
|
||||
this.contentDispositionFilename = contentDispositionFilename;
|
||||
}
|
||||
|
||||
@ -305,39 +305,6 @@ ChromeActions.prototype = {
|
||||
getLocale: function() {
|
||||
return getStringPref('general.useragent.locale', 'en-US');
|
||||
},
|
||||
getLoadingType: function() {
|
||||
return this.dataListener ? 'passive' : 'active';
|
||||
},
|
||||
initPassiveLoading: function() {
|
||||
if (!this.dataListener)
|
||||
return false;
|
||||
|
||||
var domWindow = this.domWindow;
|
||||
this.dataListener.onprogress =
|
||||
function ChromeActions_dataListenerProgress(loaded, total) {
|
||||
|
||||
domWindow.postMessage({
|
||||
pdfjsLoadAction: 'progress',
|
||||
loaded: loaded,
|
||||
total: total
|
||||
}, '*');
|
||||
};
|
||||
|
||||
var self = this;
|
||||
this.dataListener.oncomplete =
|
||||
function ChromeActions_dataListenerComplete(data, errorCode) {
|
||||
|
||||
domWindow.postMessage({
|
||||
pdfjsLoadAction: 'complete',
|
||||
data: data,
|
||||
errorCode: errorCode
|
||||
}, '*');
|
||||
|
||||
delete self.dataListener;
|
||||
};
|
||||
|
||||
return true;
|
||||
},
|
||||
getStrings: function(data) {
|
||||
try {
|
||||
// Lazy initialization of localizedStrings
|
||||
@ -436,6 +403,146 @@ ChromeActions.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
var RangedChromeActions = (function RangedChromeActionsClosure() {
|
||||
/**
|
||||
* This is for range requests
|
||||
*/
|
||||
function RangedChromeActions(
|
||||
domWindow, contentDispositionFilename, originalRequest) {
|
||||
|
||||
ChromeActions.call(this, domWindow, contentDispositionFilename);
|
||||
|
||||
this.pdfUrl = originalRequest.URI.resolve('');
|
||||
this.contentLength = originalRequest.contentLength;
|
||||
|
||||
// Pass all the headers from the original request through
|
||||
var httpHeaderVisitor = {
|
||||
headers: {},
|
||||
visitHeader: function(aHeader, aValue) {
|
||||
if (aHeader === 'Range') {
|
||||
// When loading the PDF from cache, firefox seems to set the Range
|
||||
// request header to fetch only the unfetched portions of the file
|
||||
// (e.g. 'Range: bytes=1024-'). However, we want to set this header
|
||||
// manually to fetch the PDF in chunks.
|
||||
return;
|
||||
}
|
||||
this.headers[aHeader] = aValue;
|
||||
}
|
||||
};
|
||||
originalRequest.visitRequestHeaders(httpHeaderVisitor);
|
||||
|
||||
var getXhr = function getXhr() {
|
||||
const XMLHttpRequest = Components.Constructor(
|
||||
'@mozilla.org/xmlextras/xmlhttprequest;1');
|
||||
return new XMLHttpRequest();
|
||||
};
|
||||
|
||||
this.networkManager = new NetworkManager(this.pdfUrl, {
|
||||
httpHeaders: httpHeaderVisitor.headers,
|
||||
getXhr: getXhr
|
||||
});
|
||||
|
||||
var self = this;
|
||||
// If we are in range request mode, this means we manually issued xhr
|
||||
// requests, which we need to abort when we leave the page
|
||||
domWindow.addEventListener('unload', function unload(e) {
|
||||
self.networkManager.abortAllRequests();
|
||||
domWindow.removeEventListener(e.type, unload);
|
||||
});
|
||||
}
|
||||
|
||||
RangedChromeActions.prototype = Object.create(ChromeActions.prototype);
|
||||
var proto = RangedChromeActions.prototype;
|
||||
proto.constructor = RangedChromeActions;
|
||||
|
||||
proto.initPassiveLoading = function RangedChromeActions_initPassiveLoading() {
|
||||
this.domWindow.postMessage({
|
||||
pdfjsLoadAction: 'supportsRangedLoading',
|
||||
pdfUrl: this.pdfUrl,
|
||||
length: this.contentLength
|
||||
}, '*');
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
proto.requestDataRange = function RangedChromeActions_requestDataRange(args) {
|
||||
var begin = args.begin;
|
||||
var end = args.end;
|
||||
var domWindow = this.domWindow;
|
||||
// TODO(mack): Support error handler. We're not currently not handling
|
||||
// errors from chrome code for non-range requests, so this doesn't
|
||||
// seem high-pri
|
||||
this.networkManager.requestRange(begin, end, {
|
||||
onDone: function RangedChromeActions_onDone(args) {
|
||||
domWindow.postMessage({
|
||||
pdfjsLoadAction: 'range',
|
||||
begin: args.begin,
|
||||
chunk: args.chunk
|
||||
}, '*');
|
||||
},
|
||||
onProgress: function RangedChromeActions_onProgress(evt) {
|
||||
domWindow.postMessage({
|
||||
pdfjsLoadAction: 'rangeProgress',
|
||||
loaded: evt.loaded,
|
||||
}, '*');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return RangedChromeActions;
|
||||
})();
|
||||
|
||||
var StandardChromeActions = (function StandardChromeActionsClosure() {
|
||||
|
||||
/**
|
||||
* This is for a single network stream
|
||||
*/
|
||||
function StandardChromeActions(domWindow, contentDispositionFilename,
|
||||
dataListener) {
|
||||
|
||||
ChromeActions.call(this, domWindow, contentDispositionFilename);
|
||||
this.dataListener = dataListener;
|
||||
}
|
||||
|
||||
StandardChromeActions.prototype = Object.create(ChromeActions.prototype);
|
||||
var proto = StandardChromeActions.prototype;
|
||||
proto.constructor = StandardChromeActions;
|
||||
|
||||
proto.initPassiveLoading =
|
||||
function StandardChromeActions_initPassiveLoading() {
|
||||
|
||||
if (!this.dataListener) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
this.dataListener.onprogress = function ChromeActions_dataListenerProgress(
|
||||
loaded, total) {
|
||||
self.domWindow.postMessage({
|
||||
pdfjsLoadAction: 'progress',
|
||||
loaded: loaded,
|
||||
total: total
|
||||
}, '*');
|
||||
};
|
||||
|
||||
this.dataListener.oncomplete = function ChromeActions_dataListenerComplete(
|
||||
data, errorCode) {
|
||||
self.domWindow.postMessage({
|
||||
pdfjsLoadAction: 'complete',
|
||||
data: data,
|
||||
errorCode: errorCode
|
||||
}, '*');
|
||||
|
||||
delete self.dataListener;
|
||||
};
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
return StandardChromeActions;
|
||||
})();
|
||||
|
||||
// Event listener to trigger chrome privedged code.
|
||||
function RequestListener(actions) {
|
||||
this.actions = actions;
|
||||
@ -552,11 +659,17 @@ PdfStreamConverter.prototype = {
|
||||
/*
|
||||
* This component works as such:
|
||||
* 1. asyncConvertData stores the listener
|
||||
* 2. onStartRequest creates a new channel, streams the viewer and cancels
|
||||
* the request so pdf.js can do the request
|
||||
* Since the request is cancelled onDataAvailable should not be called. The
|
||||
* onStopRequest does nothing. The convert function just returns the stream,
|
||||
* it's just the synchronous version of asyncConvertData.
|
||||
* 2. onStartRequest creates a new channel, streams the viewer
|
||||
* 3. If range requests are supported:
|
||||
* 3.1. Suspends and cancels the request so we can issue range
|
||||
* requests instead.
|
||||
*
|
||||
* If range rquests are not supported:
|
||||
* 3.1. Read the stream as it's loaded in onDataAvailable to send
|
||||
* to the viewer
|
||||
*
|
||||
* The convert function just returns the stream, it's just the synchronous
|
||||
* version of asyncConvertData.
|
||||
*/
|
||||
|
||||
// nsIStreamConverter::convert
|
||||
@ -573,41 +686,76 @@ PdfStreamConverter.prototype = {
|
||||
// nsIStreamListener::onDataAvailable
|
||||
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
|
||||
if (!this.dataListener) {
|
||||
// Do nothing since all the data loading is handled by the viewer.
|
||||
return;
|
||||
}
|
||||
|
||||
var binaryStream = this.binaryStream;
|
||||
binaryStream.setInputStream(aInputStream);
|
||||
this.dataListener.append(binaryStream.readByteArray(aCount));
|
||||
var chunk = binaryStream.readByteArray(aCount);
|
||||
this.dataListener.append(chunk);
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStartRequest
|
||||
onStartRequest: function(aRequest, aContext) {
|
||||
// Setup the request so we can use it below.
|
||||
var isHttpRequest = false;
|
||||
try {
|
||||
aRequest.QueryInterface(Ci.nsIHttpChannel);
|
||||
isHttpRequest = true;
|
||||
} catch (e) {}
|
||||
|
||||
var rangeRequest = false;
|
||||
if (isHttpRequest) {
|
||||
var contentEncoding = 'identity';
|
||||
try {
|
||||
contentEncoding = aRequest.getResponseHeader('Content-Encoding');
|
||||
} catch (e) {}
|
||||
|
||||
var acceptRanges;
|
||||
try {
|
||||
acceptRanges = aRequest.getResponseHeader('Accept-Ranges');
|
||||
} catch (e) {}
|
||||
|
||||
var hash = aRequest.URI.ref;
|
||||
rangeRequest = contentEncoding === 'identity' &&
|
||||
acceptRanges === 'bytes' &&
|
||||
aRequest.contentLength >= 0 &&
|
||||
hash.indexOf('disableRange=true') < 0;
|
||||
}
|
||||
|
||||
aRequest.QueryInterface(Ci.nsIChannel);
|
||||
|
||||
aRequest.QueryInterface(Ci.nsIWritablePropertyBag);
|
||||
// Creating storage for PDF data
|
||||
var contentLength = aRequest.contentLength;
|
||||
var dataListener = new PdfDataListener(contentLength);
|
||||
|
||||
var contentDispositionFilename;
|
||||
try {
|
||||
contentDispositionFilename = aRequest.contentDispositionFilename;
|
||||
} catch (e) {}
|
||||
this.dataListener = dataListener;
|
||||
this.binaryStream = Cc['@mozilla.org/binaryinputstream;1']
|
||||
.createInstance(Ci.nsIBinaryInputStream);
|
||||
|
||||
// Change the content type so we don't get stuck in a loop.
|
||||
aRequest.setProperty('contentType', aRequest.contentType);
|
||||
aRequest.contentType = 'text/html';
|
||||
|
||||
if (!rangeRequest) {
|
||||
// Creating storage for PDF data
|
||||
var contentLength = aRequest.contentLength;
|
||||
this.dataListener = new PdfDataListener(contentLength);
|
||||
this.binaryStream = Cc['@mozilla.org/binaryinputstream;1']
|
||||
.createInstance(Ci.nsIBinaryInputStream);
|
||||
} else {
|
||||
// Suspend the request so we're not consuming any of the stream,
|
||||
// but we can't cancel the request yet. Otherwise, the original
|
||||
// listener will think we do not want to go the new PDF url
|
||||
aRequest.suspend();
|
||||
}
|
||||
|
||||
// Create a new channel that is viewer loaded as a resource.
|
||||
var ioService = Services.io;
|
||||
var channel = ioService.newChannel(
|
||||
PDF_VIEWER_WEB_PAGE, null, null);
|
||||
|
||||
var listener = this.listener;
|
||||
var dataListener = this.dataListener;
|
||||
// Proxy all the request observer calls, when it gets to onStopRequest
|
||||
// we can get the dom window. We also intentionally pass on the original
|
||||
// request(aRequest) below so we don't overwrite the original channel and
|
||||
@ -623,23 +771,28 @@ PdfStreamConverter.prototype = {
|
||||
// We get the DOM window here instead of before the request since it
|
||||
// may have changed during a redirect.
|
||||
var domWindow = getDOMWindow(channel);
|
||||
// Double check the url is still the correct one.
|
||||
if (domWindow.document.documentURIObject.equals(aRequest.URI)) {
|
||||
var actions = new ChromeActions(domWindow, dataListener,
|
||||
contentDispositionFilename);
|
||||
var requestListener = new RequestListener(actions);
|
||||
domWindow.addEventListener(PDFJS_EVENT_ID, function(event) {
|
||||
requestListener.receive(event);
|
||||
}, false, true);
|
||||
if (actions.supportsIntegratedFind()) {
|
||||
var chromeWindow = getChromeWindow(domWindow);
|
||||
var findEventManager = new FindEventManager(chromeWindow.gFindBar,
|
||||
domWindow,
|
||||
chromeWindow);
|
||||
findEventManager.bind();
|
||||
}
|
||||
var actions;
|
||||
if (rangeRequest) {
|
||||
// We are going to be issuing range requests, so cancel the
|
||||
// original request
|
||||
aRequest.resume();
|
||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
actions = new RangedChromeActions(domWindow,
|
||||
contentDispositionFilename, aRequest);
|
||||
} else {
|
||||
log('Dom window url did not match request url.');
|
||||
actions = new StandardChromeActions(
|
||||
domWindow, contentDispositionFilename, dataListener);
|
||||
}
|
||||
var requestListener = new RequestListener(actions);
|
||||
domWindow.addEventListener(PDFJS_EVENT_ID, function(event) {
|
||||
requestListener.receive(event);
|
||||
}, false, true);
|
||||
if (actions.supportsIntegratedFind()) {
|
||||
var chromeWindow = getChromeWindow(domWindow);
|
||||
var findEventManager = new FindEventManager(chromeWindow.gFindBar,
|
||||
domWindow,
|
||||
chromeWindow);
|
||||
findEventManager.bind();
|
||||
}
|
||||
listener.onStopRequest(aRequest, context, statusCode);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
230
browser/extensions/pdfjs/content/network.js
Normal file
230
browser/extensions/pdfjs/content/network.js
Normal file
@ -0,0 +1,230 @@
|
||||
/* -*- 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.
|
||||
*/
|
||||
|
||||
// NOTE: Be careful what goes in this file, as it is also used from the context
|
||||
// of the addon. So using warn/error in here will break the addon.
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
|
||||
Components.utils.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
var EXPORTED_SYMBOLS = ['NetworkManager'];
|
||||
|
||||
function log(aMsg) {
|
||||
var msg = 'network.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
||||
Services.console.logStringMessage(msg);
|
||||
// TODO(mack): dump() doesn't seem to work here...
|
||||
dump(msg + '\n');
|
||||
}
|
||||
|
||||
var NetworkManager = (function NetworkManagerClosure() {
|
||||
|
||||
var OK_RESPONSE = 200;
|
||||
var PARTIAL_CONTENT_RESPONSE = 206;
|
||||
|
||||
function NetworkManager(url, args) {
|
||||
this.url = url;
|
||||
args = args || {};
|
||||
this.httpHeaders = args.httpHeaders || {};
|
||||
this.getXhr = args.getXhr ||
|
||||
function NetworkManager_getXhr() {
|
||||
return new XMLHttpRequest();
|
||||
};
|
||||
|
||||
this.currXhrId = 0;
|
||||
this.pendingRequests = {};
|
||||
this.loadedRequests = {};
|
||||
}
|
||||
|
||||
function getArrayBuffer(xhr) {
|
||||
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
|
||||
xhr.responseArrayBuffer || xhr.response);
|
||||
if (typeof data !== 'string') {
|
||||
return data;
|
||||
}
|
||||
var length = data.length;
|
||||
var buffer = new Uint8Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
buffer[i] = data.charCodeAt(i) & 0xFF;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
NetworkManager.prototype = {
|
||||
requestRange: function NetworkManager_requestRange(begin, end, listeners) {
|
||||
var args = {
|
||||
begin: begin,
|
||||
end: end
|
||||
};
|
||||
for (var prop in listeners) {
|
||||
args[prop] = listeners[prop];
|
||||
}
|
||||
return this.request(args);
|
||||
},
|
||||
|
||||
requestFull: function NetworkManager_requestRange(listeners) {
|
||||
return this.request(listeners);
|
||||
},
|
||||
|
||||
request: function NetworkManager_requestRange(args) {
|
||||
var xhr = this.getXhr();
|
||||
var xhrId = this.currXhrId++;
|
||||
var pendingRequest = this.pendingRequests[xhrId] = {
|
||||
xhr: xhr
|
||||
};
|
||||
|
||||
xhr.open('GET', this.url);
|
||||
for (var property in this.httpHeaders) {
|
||||
var value = this.httpHeaders[property];
|
||||
if (typeof value === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
xhr.setRequestHeader(property, value);
|
||||
}
|
||||
if ('begin' in args && 'end' in args) {
|
||||
var rangeStr = args.begin + '-' + (args.end - 1);
|
||||
xhr.setRequestHeader('Range', 'bytes=' + rangeStr);
|
||||
pendingRequest.expectedStatus = 206;
|
||||
} else {
|
||||
pendingRequest.expectedStatus = 200;
|
||||
}
|
||||
|
||||
xhr.mozResponseType = xhr.responseType = 'arraybuffer';
|
||||
|
||||
if (args.onProgress) {
|
||||
xhr.onprogress = args.onProgress;
|
||||
}
|
||||
if (args.onError) {
|
||||
xhr.onerror = function(evt) {
|
||||
args.onError(xhr.status);
|
||||
};
|
||||
}
|
||||
xhr.onreadystatechange = this.onStateChange.bind(this, xhrId);
|
||||
|
||||
pendingRequest.onHeadersReceived = args.onHeadersReceived;
|
||||
pendingRequest.onDone = args.onDone;
|
||||
pendingRequest.onError = args.onError;
|
||||
|
||||
xhr.send(null);
|
||||
|
||||
return xhrId;
|
||||
},
|
||||
|
||||
onStateChange: function NetworkManager_onStateChange(xhrId, evt) {
|
||||
var pendingRequest = this.pendingRequests[xhrId];
|
||||
if (!pendingRequest) {
|
||||
// Maybe abortRequest was called...
|
||||
return;
|
||||
}
|
||||
|
||||
var xhr = pendingRequest.xhr;
|
||||
if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) {
|
||||
pendingRequest.onHeadersReceived();
|
||||
delete pendingRequest.onHeadersReceived;
|
||||
}
|
||||
|
||||
if (xhr.readyState !== 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(xhrId in this.pendingRequests)) {
|
||||
// The XHR request might have been aborted in onHeadersReceived()
|
||||
// callback, in which case we should abort request
|
||||
return;
|
||||
}
|
||||
|
||||
delete this.pendingRequests[xhrId];
|
||||
|
||||
if (xhr.status === 0) {
|
||||
if (pendingRequest.onError) {
|
||||
pendingRequest.onError(xhr.status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2:
|
||||
// "A server MAY ignore the Range header". This means it's possible to
|
||||
// get a 200 rather than a 206 response from a range request.
|
||||
var ok_response_on_range_request =
|
||||
xhr.status === OK_RESPONSE &&
|
||||
pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE;
|
||||
|
||||
if (!ok_response_on_range_request &&
|
||||
xhr.status !== pendingRequest.expectedStatus) {
|
||||
if (pendingRequest.onError) {
|
||||
pendingRequest.onError(xhr.status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadedRequests[xhrId] = true;
|
||||
|
||||
var chunk = getArrayBuffer(xhr);
|
||||
if (xhr.status === PARTIAL_CONTENT_RESPONSE) {
|
||||
var rangeHeader = xhr.getResponseHeader('Content-Range');
|
||||
var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader);
|
||||
var begin = parseInt(matches[1], 10);
|
||||
pendingRequest.onDone({
|
||||
begin: begin,
|
||||
chunk: chunk
|
||||
});
|
||||
} else {
|
||||
pendingRequest.onDone({
|
||||
begin: 0,
|
||||
chunk: chunk
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
hasPendingRequests: function NetworkManager_hasPendingRequests() {
|
||||
for (var xhrId in this.pendingRequests) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
getRequestXhr: function NetworkManager_getXhr(xhrId) {
|
||||
return this.pendingRequests[xhrId].xhr;
|
||||
},
|
||||
|
||||
isPendingRequest: function NetworkManager_isPendingRequest(xhrId) {
|
||||
return xhrId in this.pendingRequests;
|
||||
},
|
||||
|
||||
isLoadedRequest: function NetworkManager_isLoadedRequest(xhrId) {
|
||||
return xhrId in this.loadedRequests;
|
||||
},
|
||||
|
||||
abortAllRequests: function NetworkManager_abortAllRequests() {
|
||||
for (var xhrId in this.pendingRequests) {
|
||||
this.abortRequest(xhrId | 0);
|
||||
}
|
||||
},
|
||||
|
||||
abortRequest: function NetworkManager_abortRequest(xhrId) {
|
||||
var xhr = this.pendingRequests[xhrId].xhr;
|
||||
delete this.pendingRequests[xhrId];
|
||||
xhr.abort();
|
||||
}
|
||||
};
|
||||
|
||||
return NetworkManager;
|
||||
})();
|
||||
|
||||
|
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 491 B |
@ -105,7 +105,10 @@
|
||||
// Arabic, Hebrew, Farsi, Pashto, Urdu
|
||||
var rtlList = ['ar', 'he', 'fa', 'ps', 'ur'];
|
||||
return (rtlList.indexOf(gLanguage) >= 0) ? 'rtl' : 'ltr';
|
||||
}
|
||||
},
|
||||
|
||||
// translate an element or document fragment
|
||||
translate: translateFragment
|
||||
};
|
||||
})(this);
|
||||
|
||||
|
@ -237,12 +237,14 @@ html[dir='rtl'] #sidebarContent {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.loadingInProgress #viewerContainer {
|
||||
top: 39px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
position: relative;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 32px;
|
||||
z-index: 9999;
|
||||
cursor: default;
|
||||
}
|
||||
@ -254,14 +256,7 @@ html[dir='rtl'] #sidebarContent {
|
||||
#toolbarSidebar {
|
||||
width: 200px;
|
||||
height: 32px;
|
||||
background-image: url(images/texture.png),
|
||||
-webkit-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95));
|
||||
background-image: url(images/texture.png),
|
||||
-moz-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95));
|
||||
background-image: url(images/texture.png),
|
||||
-ms-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95));
|
||||
background-image: url(images/texture.png),
|
||||
-o-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95));
|
||||
background-color: #424242; /* fallback */
|
||||
background-image: url(images/texture.png),
|
||||
linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95));
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.25),
|
||||
@ -271,18 +266,10 @@ html[dir='rtl'] #sidebarContent {
|
||||
0 0 1px hsla(0,0%,0%,.1);
|
||||
}
|
||||
|
||||
#toolbarViewer, .findbar {
|
||||
#toolbarContainer, .findbar {
|
||||
position: relative;
|
||||
height: 32px;
|
||||
background-color: #474747; /* IE9 */
|
||||
background-image: url(images/texture.png),
|
||||
-webkit-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95));
|
||||
background-image: url(images/texture.png),
|
||||
-moz-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95));
|
||||
background-image: url(images/texture.png),
|
||||
-ms-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95));
|
||||
background-image: url(images/texture.png),
|
||||
-o-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95));
|
||||
background-color: #474747; /* fallback */
|
||||
background-image: url(images/texture.png),
|
||||
linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95));
|
||||
box-shadow: inset 1px 0 0 hsla(0,0%,100%,.08),
|
||||
@ -292,6 +279,80 @@ html[dir='rtl'] #sidebarContent {
|
||||
0 1px 1px hsla(0,0%,0%,.1);
|
||||
}
|
||||
|
||||
#toolbarViewer {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
#loadingBar {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
background-color: #333;
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
#loadingBar .progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
background-color: #ddd;
|
||||
overflow: hidden;
|
||||
-moz-transition: width 200ms;
|
||||
-ms-transition: width 200ms;
|
||||
-webkit-transition: width 200ms;
|
||||
transition: width 200ms;
|
||||
}
|
||||
|
||||
@-moz-keyframes progressIndeterminate {
|
||||
0% { left: 0%; }
|
||||
50% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
@-ms-keyframes progressIndeterminate {
|
||||
0% { left: 0%; }
|
||||
50% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes progressIndeterminate {
|
||||
0% { left: 0%; }
|
||||
50% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
@keyframes progressIndeterminate {
|
||||
0% { left: 0%; }
|
||||
50% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
#loadingBar .progress.indeterminate {
|
||||
background-color: #999;
|
||||
-moz-transition: none;
|
||||
-ms-transition: none;
|
||||
-webkit-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
#loadingBar .indeterminate .glimmer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 50px;
|
||||
|
||||
background-image: linear-gradient(to right, #999 0%, #fff 50%, #999 100%);
|
||||
background-size: 100% 100% no-repeat;
|
||||
|
||||
-moz-animation: progressIndeterminate 2s linear infinite;
|
||||
-ms-animation: progressIndeterminate 2s linear infinite;
|
||||
-webkit-animation: progressIndeterminate 2s linear infinite;
|
||||
animation: progressIndeterminate 2s linear infinite;
|
||||
}
|
||||
|
||||
.findbar {
|
||||
top: 32px;
|
||||
position: absolute;
|
||||
@ -462,10 +523,6 @@ html[dir='rtl'] .splitToolbarButton > .toolbarButton {
|
||||
.splitToolbarButton.toggled > .toolbarButton,
|
||||
.toolbarButton.textButton {
|
||||
background-color: hsla(0,0%,0%,.12);
|
||||
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-clip: padding-box;
|
||||
border: 1px solid hsla(0,0%,0%,.35);
|
||||
@ -600,10 +657,6 @@ html[dir='rtl'] .dropdownToolbarButton {
|
||||
.toolbarButton:focus,
|
||||
.dropdownToolbarButton {
|
||||
background-color: hsla(0,0%,0%,.12);
|
||||
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-clip: padding-box;
|
||||
border: 1px solid hsla(0,0%,0%,.35);
|
||||
@ -616,10 +669,6 @@ html[dir='rtl'] .dropdownToolbarButton {
|
||||
.toolbarButton:hover:active,
|
||||
.dropdownToolbarButton:hover:active {
|
||||
background-color: hsla(0,0%,0%,.2);
|
||||
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
border-color: hsla(0,0%,0%,.35) hsla(0,0%,0%,.4) hsla(0,0%,0%,.45);
|
||||
box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset,
|
||||
@ -645,10 +694,6 @@ html[dir='rtl'] .dropdownToolbarButton {
|
||||
.toolbarButton.toggled,
|
||||
.splitToolbarButton.toggled > .toolbarButton.toggled {
|
||||
background-color: hsla(0,0%,0%,.3);
|
||||
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
border-color: hsla(0,0%,0%,.4) hsla(0,0%,0%,.45) hsla(0,0%,0%,.5);
|
||||
box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset,
|
||||
@ -820,9 +865,9 @@ html[dir='rtl'] .toolbarButton.pageDown::before {
|
||||
content: url(images/toolbarButton-zoomIn.png);
|
||||
}
|
||||
|
||||
.toolbarButton.fullscreen::before {
|
||||
.toolbarButton.presentationMode::before {
|
||||
display: inline-block;
|
||||
content: url(images/toolbarButton-fullscreen.png);
|
||||
content: url(images/toolbarButton-presentationMode.png);
|
||||
}
|
||||
|
||||
.toolbarButton.print::before {
|
||||
@ -880,7 +925,7 @@ html[dir='rtl'] .toolbarButton.pageDown::before {
|
||||
border: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
background-color: hsla(0,0%,100%,.09);
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-clip: padding-box;
|
||||
border: 1px solid hsla(0,0%,0%,.35);
|
||||
border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42);
|
||||
@ -977,7 +1022,7 @@ a:focus > .thumbnail > .thumbnailSelectionRing > .thumbnailImage,
|
||||
a:focus > .thumbnail > .thumbnailSelectionRing,
|
||||
.thumbnail:hover > .thumbnailSelectionRing {
|
||||
background-color: hsla(0,0%,100%,.15);
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-clip: padding-box;
|
||||
box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset,
|
||||
0 0 1px hsla(0,0%,100%,.2) inset,
|
||||
@ -992,7 +1037,7 @@ a:focus > .thumbnail > .thumbnailSelectionRing,
|
||||
|
||||
.thumbnail.selected > .thumbnailSelectionRing {
|
||||
background-color: hsla(0,0%,100%,.3);
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-clip: padding-box;
|
||||
box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset,
|
||||
0 0 1px hsla(0,0%,100%,.1) inset,
|
||||
@ -1043,7 +1088,7 @@ html[dir='rtl'] .outlineItem > a {
|
||||
|
||||
.outlineItem > a:hover {
|
||||
background-color: hsla(0,0%,100%,.02);
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-clip: padding-box;
|
||||
box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset,
|
||||
0 0 1px hsla(0,0%,100%,.2) inset,
|
||||
@ -1053,7 +1098,7 @@ html[dir='rtl'] .outlineItem > a {
|
||||
|
||||
.outlineItem.selected {
|
||||
background-color: hsla(0,0%,100%,.08);
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-clip: padding-box;
|
||||
box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset,
|
||||
0 0 1px hsla(0,0%,100%,.1) inset,
|
||||
@ -1123,82 +1168,6 @@ canvas {
|
||||
background: url('images/loading-icon.gif') center no-repeat;
|
||||
}
|
||||
|
||||
#loadingBox {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -25px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
color: #ddd;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#loadingBar {
|
||||
display: inline-block;
|
||||
clear: both;
|
||||
margin: 0px;
|
||||
margin-top: 5px;
|
||||
line-height: 0;
|
||||
border-radius: 2px;
|
||||
width: 200px;
|
||||
height: 25px;
|
||||
|
||||
background-color: hsla(0,0%,0%,.3);
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
border: 1px solid #000;
|
||||
box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset,
|
||||
0 0 1px hsla(0,0%,0%,.2) inset,
|
||||
0 0 1px 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
#loadingBar .progress {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
|
||||
background: #666;
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2b2b2), color-stop(100%,#898989));
|
||||
background: -webkit-linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
background: -moz-linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
background: -ms-linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
background: -o-linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
background: linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
|
||||
border-top-left-radius: 2px;
|
||||
border-bottom-left-radius: 2px;
|
||||
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#loadingBar .progress.full {
|
||||
border-top-right-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
#loadingBar .progress.indeterminate {
|
||||
width: 100%;
|
||||
height: 25px;
|
||||
background-image: -moz-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040);
|
||||
background-image: -webkit-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040);
|
||||
background-image: -ms-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040);
|
||||
background-image: -o-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040);
|
||||
background-size: 75px 25px;
|
||||
-moz-animation: progressIndeterminate 1s linear infinite;
|
||||
-webkit-animation: progressIndeterminate 1s linear infinite;
|
||||
}
|
||||
|
||||
@-moz-keyframes progressIndeterminate {
|
||||
from { background-position: 0px 0px; }
|
||||
to { background-position: 75px 0px; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes progressIndeterminate {
|
||||
from { background-position: 0px 0px; }
|
||||
to { background-position: 75px 0px; }
|
||||
}
|
||||
|
||||
.textLayer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@ -1280,7 +1249,6 @@ canvas {
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 32px;
|
||||
z-index: 1000;
|
||||
padding: 3px;
|
||||
font-size: 0.8em;
|
||||
@ -1380,6 +1348,11 @@ canvas {
|
||||
}
|
||||
|
||||
@media print {
|
||||
/* General rules for printing. */
|
||||
body {
|
||||
background: transparent none;
|
||||
}
|
||||
|
||||
/* Rules for browsers that don't support mozPrintCallback. */
|
||||
#sidebarContainer, .toolbar, #loadingBox, #errorWrapper, .textLayer {
|
||||
display: none;
|
||||
@ -1430,9 +1403,12 @@ canvas {
|
||||
|
||||
@media all and (max-width: 770px) {
|
||||
#sidebarContainer {
|
||||
top: 33px;
|
||||
top: 32px;
|
||||
z-index: 100;
|
||||
}
|
||||
.loadingInProgress #sidebarContainer {
|
||||
top: 39px;
|
||||
}
|
||||
#sidebarContent {
|
||||
top: 32px;
|
||||
background-color: hsla(0,0%,0%,.7);
|
||||
|
@ -36,8 +36,8 @@ limitations under the License.
|
||||
<script type="text/javascript" src="viewer.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="outerContainer">
|
||||
<body tabindex="1">
|
||||
<div id="outerContainer" class="loadingInProgress">
|
||||
|
||||
<div id="sidebarContainer">
|
||||
<div id="toolbarSidebar">
|
||||
@ -105,7 +105,7 @@ limitations under the License.
|
||||
<div id="toolbarViewerRight">
|
||||
<input id="fileInput" class="fileInput" type="file" oncontextmenu="return false;" style="visibility: hidden; position: fixed; right: 0; top: 0" />
|
||||
|
||||
<button id="fullscreen" class="toolbarButton fullscreen hiddenSmallView" title="Switch to Presentation Mode" tabindex="12" data-l10n-id="presentation_mode">
|
||||
<button id="presentationMode" class="toolbarButton presentationMode hiddenSmallView" title="Switch to Presentation Mode" tabindex="12" data-l10n-id="presentation_mode">
|
||||
<span data-l10n-id="presentation_mode_label">Presentation Mode</span>
|
||||
</button>
|
||||
|
||||
@ -126,11 +126,11 @@ limitations under the License.
|
||||
<div class="outerCenter">
|
||||
<div class="innerCenter" id="toolbarViewerMiddle">
|
||||
<div class="splitToolbarButton">
|
||||
<button class="toolbarButton zoomOut" id="zoom_out" title="Zoom Out" tabindex="9" data-l10n-id="zoom_out">
|
||||
<button id="zoomOut" class="toolbarButton zoomOut" title="Zoom Out" tabindex="9" data-l10n-id="zoom_out">
|
||||
<span data-l10n-id="zoom_out_label">Zoom Out</span>
|
||||
</button>
|
||||
<div class="splitToolbarButtonSeparator"></div>
|
||||
<button class="toolbarButton zoomIn" id="zoom_in" title="Zoom In" tabindex="10" data-l10n-id="zoom_in">
|
||||
<button id="zoomIn" class="toolbarButton zoomIn" title="Zoom In" tabindex="10" data-l10n-id="zoom_in">
|
||||
<span data-l10n-id="zoom_in_label">Zoom In</span>
|
||||
</button>
|
||||
</div>
|
||||
@ -152,29 +152,30 @@ limitations under the License.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loadingBar">
|
||||
<div class="progress">
|
||||
<div class="glimmer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<menu type="context" id="viewerContextMenu">
|
||||
<menuitem label="First Page" id="first_page"
|
||||
<menuitem id="firstPage" label="First Page"
|
||||
data-l10n-id="first_page" ></menuitem>
|
||||
<menuitem label="Last Page" id="last_page"
|
||||
<menuitem id="lastPage" label="Last Page"
|
||||
data-l10n-id="last_page" ></menuitem>
|
||||
<menuitem label="Rotate Counter-Clockwise" id="page_rotate_ccw"
|
||||
<menuitem id="pageRotateCcw" label="Rotate Counter-Clockwise"
|
||||
data-l10n-id="page_rotate_ccw" ></menuitem>
|
||||
<menuitem label="Rotate Clockwise" id="page_rotate_cw"
|
||||
<menuitem id="pageRotateCw" label="Rotate Clockwise"
|
||||
data-l10n-id="page_rotate_cw" ></menuitem>
|
||||
</menu>
|
||||
|
||||
<div id="viewerContainer" tabindex="1">
|
||||
<div id="viewerContainer">
|
||||
<div id="viewer" contextmenu="viewerContextMenu"></div>
|
||||
</div>
|
||||
|
||||
<div id="loadingBox">
|
||||
<div id="loading"></div>
|
||||
<div id="loadingBar"><div class="progress"></div></div>
|
||||
</div>
|
||||
|
||||
<div id="errorWrapper" hidden='true'>
|
||||
<div id="errorMessageLeft">
|
||||
<span id="errorMessage"></span>
|
||||
|
@ -28,9 +28,7 @@ var SCROLLBAR_PADDING = 40;
|
||||
var VERTICAL_PADDING = 5;
|
||||
var MIN_SCALE = 0.25;
|
||||
var MAX_SCALE = 4.0;
|
||||
var IMAGE_DIR = './images/';
|
||||
var SETTINGS_MEMORY = 20;
|
||||
var ANNOT_MIN_SIZE = 10;
|
||||
var RenderingStates = {
|
||||
INITIAL: 0,
|
||||
RUNNING: 1,
|
||||
@ -108,6 +106,7 @@ var ProgressBar = (function ProgressBarClosure() {
|
||||
|
||||
// Initialize heights
|
||||
this.div.style.height = this.height + this.units;
|
||||
this.percent = 0;
|
||||
}
|
||||
|
||||
ProgressBar.prototype = {
|
||||
@ -115,17 +114,12 @@ var ProgressBar = (function ProgressBarClosure() {
|
||||
updateBar: function ProgressBar_updateBar() {
|
||||
if (this._indeterminate) {
|
||||
this.div.classList.add('indeterminate');
|
||||
this.div.style.width = this.width + this.units;
|
||||
return;
|
||||
}
|
||||
|
||||
var progressSize = this.width * this._percent / 100;
|
||||
|
||||
if (this._percent > 95)
|
||||
this.div.classList.add('full');
|
||||
else
|
||||
this.div.classList.remove('full');
|
||||
this.div.classList.remove('indeterminate');
|
||||
|
||||
var progressSize = this.width * this._percent / 100;
|
||||
this.div.style.width = progressSize + this.units;
|
||||
},
|
||||
|
||||
@ -742,7 +736,7 @@ var PDFView = {
|
||||
sidebarOpen: false,
|
||||
pageViewScroll: null,
|
||||
thumbnailViewScroll: null,
|
||||
isFullscreen: false,
|
||||
isPresentationMode: false,
|
||||
previousScale: null,
|
||||
pageRotation: 0,
|
||||
mouseScrollTimeStamp: 0,
|
||||
@ -921,11 +915,12 @@ var PDFView = {
|
||||
var support = doc.requestFullscreen || doc.mozRequestFullScreen ||
|
||||
doc.webkitRequestFullScreen;
|
||||
|
||||
// Disable fullscreen button if we're in an iframe
|
||||
if (window.parent !== window)
|
||||
// Disable presentation mode button if we're in an iframe
|
||||
if (window.parent !== window) {
|
||||
support = false;
|
||||
}
|
||||
|
||||
Object.defineProperty(this, 'supportsFullScreen', { value: support,
|
||||
Object.defineProperty(this, 'supportsFullscreen', { value: support,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: false });
|
||||
@ -972,12 +967,57 @@ var PDFView = {
|
||||
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
|
||||
}
|
||||
|
||||
window.addEventListener('message', function window_message(e) {
|
||||
var pdfDataRangeTransport = {
|
||||
rangeListeners: [],
|
||||
progressListeners: [],
|
||||
|
||||
addRangeListener: function PdfDataRangeTransport_addRangeListener(
|
||||
listener) {
|
||||
this.rangeListeners.push(listener);
|
||||
},
|
||||
|
||||
addProgressListener: function PdfDataRangeTransport_addProgressListener(
|
||||
listener) {
|
||||
this.progressListeners.push(listener);
|
||||
},
|
||||
|
||||
onDataRange: function PdfDataRangeTransport_onDataRange(begin, chunk) {
|
||||
var listeners = this.rangeListeners;
|
||||
for (var i = 0, n = listeners.length; i < n; ++i) {
|
||||
listeners[i](begin, chunk);
|
||||
}
|
||||
},
|
||||
|
||||
onDataProgress: function PdfDataRangeTransport_onDataProgress(loaded) {
|
||||
var listeners = this.progressListeners;
|
||||
for (var i = 0, n = listeners.length; i < n; ++i) {
|
||||
listeners[i](loaded);
|
||||
}
|
||||
},
|
||||
|
||||
requestDataRange: function PdfDataRangeTransport_requestDataRange(
|
||||
begin, end) {
|
||||
FirefoxCom.request('requestDataRange', { begin: begin, end: end });
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', function windowMessage(e) {
|
||||
var args = e.data;
|
||||
|
||||
if (typeof args !== 'object' || !('pdfjsLoadAction' in args))
|
||||
return;
|
||||
switch (args.pdfjsLoadAction) {
|
||||
case 'supportsRangedLoading':
|
||||
PDFView.open(args.pdfUrl, 0, undefined, pdfDataRangeTransport, {
|
||||
length: args.length
|
||||
});
|
||||
break;
|
||||
case 'range':
|
||||
pdfDataRangeTransport.onDataRange(args.begin, args.chunk);
|
||||
break;
|
||||
case 'rangeProgress':
|
||||
pdfDataRangeTransport.onDataProgress(args.loaded);
|
||||
break;
|
||||
case 'progress':
|
||||
PDFView.progress(args.loaded / args.total);
|
||||
break;
|
||||
@ -1009,7 +1049,9 @@ var PDFView = {
|
||||
document.title = title;
|
||||
},
|
||||
|
||||
open: function pdfViewOpen(url, scale, password) {
|
||||
// TODO(mack): This function signature should really be pdfViewOpen(url, args)
|
||||
open: function pdfViewOpen(url, scale, password,
|
||||
pdfDataRangeTransport, args) {
|
||||
var parameters = {password: password};
|
||||
if (typeof url === 'string') { // URL
|
||||
this.setTitleUsingUrl(url);
|
||||
@ -1017,6 +1059,11 @@ var PDFView = {
|
||||
} else if (url && 'byteLength' in url) { // ArrayBuffer
|
||||
parameters.data = url;
|
||||
}
|
||||
if (args) {
|
||||
for (var prop in args) {
|
||||
parameters[prop] = args[prop];
|
||||
}
|
||||
}
|
||||
|
||||
if (!PDFView.loadingBar) {
|
||||
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
|
||||
@ -1025,23 +1072,27 @@ var PDFView = {
|
||||
this.pdfDocument = null;
|
||||
var self = this;
|
||||
self.loading = true;
|
||||
PDFJS.getDocument(parameters).then(
|
||||
var passwordNeeded = function passwordNeeded(updatePassword, reason) {
|
||||
var promptString = mozL10n.get('request_password', null,
|
||||
'PDF is protected by a password:');
|
||||
|
||||
if (reason === PDFJS.PasswordResponses.INCORRECT_PASSWORD) {
|
||||
promptString += '\n' + mozL10n.get('invalid_password', null,
|
||||
'Invalid Password.');
|
||||
}
|
||||
|
||||
password = prompt(promptString);
|
||||
if (password && password.length > 0) {
|
||||
return updatePassword(password);
|
||||
}
|
||||
};
|
||||
|
||||
PDFJS.getDocument(parameters, pdfDataRangeTransport, passwordNeeded).then(
|
||||
function getDocumentCallback(pdfDocument) {
|
||||
self.load(pdfDocument, scale);
|
||||
self.loading = false;
|
||||
},
|
||||
function getDocumentError(message, exception) {
|
||||
if (exception && exception.name === 'PasswordException') {
|
||||
if (exception.code === 'needpassword') {
|
||||
var promptString = mozL10n.get('request_password', null,
|
||||
'PDF is protected by a password:');
|
||||
password = prompt(promptString);
|
||||
if (password && password.length > 0) {
|
||||
return PDFView.open(url, scale, password);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var loadingErrorMessage = mozL10n.get('loading_error', null,
|
||||
'An error occurred while loading the PDF.');
|
||||
|
||||
@ -1058,9 +1109,6 @@ var PDFView = {
|
||||
|
||||
}
|
||||
|
||||
var loadingIndicator = document.getElementById('loading');
|
||||
loadingIndicator.textContent = mozL10n.get('loading_error_indicator',
|
||||
null, 'Error');
|
||||
var moreInfo = {
|
||||
message: message
|
||||
};
|
||||
@ -1118,23 +1166,31 @@ var PDFView = {
|
||||
},
|
||||
|
||||
navigateTo: function pdfViewNavigateTo(dest) {
|
||||
if (typeof dest === 'string')
|
||||
dest = this.destinations[dest];
|
||||
if (!(dest instanceof Array))
|
||||
return; // invalid destination
|
||||
// dest array looks like that: <page-ref> </XYZ|FitXXX> <args..>
|
||||
var destRef = dest[0];
|
||||
var pageNumber = destRef instanceof Object ?
|
||||
this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] : (destRef + 1);
|
||||
if (pageNumber > this.pages.length)
|
||||
pageNumber = this.pages.length;
|
||||
if (pageNumber) {
|
||||
this.page = pageNumber;
|
||||
var currentPage = this.pages[pageNumber - 1];
|
||||
if (!this.isFullscreen) { // Avoid breaking fullscreen mode.
|
||||
currentPage.scrollIntoView(dest);
|
||||
var self = this;
|
||||
PDFJS.Promise.all([this.pagesPromise,
|
||||
this.destinationsPromise]).then(function() {
|
||||
if (typeof dest === 'string') {
|
||||
dest = self.destinations[dest];
|
||||
}
|
||||
}
|
||||
if (!(dest instanceof Array)) {
|
||||
return; // invalid destination
|
||||
}
|
||||
// dest array looks like that: <page-ref> </XYZ|FitXXX> <args..>
|
||||
var destRef = dest[0];
|
||||
var pageNumber = destRef instanceof Object ?
|
||||
self.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] :
|
||||
(destRef + 1);
|
||||
if (pageNumber) {
|
||||
if (pageNumber > self.pages.length) {
|
||||
pageNumber = self.pages.length;
|
||||
}
|
||||
self.page = pageNumber;
|
||||
if (!self.isPresentationMode) { // Avoid breaking presentation mode.
|
||||
var currentPage = self.pages[pageNumber - 1];
|
||||
currentPage.scrollIntoView(dest);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getDestinationHash: function pdfViewGetDestinationHash(dest) {
|
||||
@ -1219,16 +1275,19 @@ var PDFView = {
|
||||
}
|
||||
}
|
||||
|
||||
var loadingBox = document.getElementById('loadingBox');
|
||||
loadingBox.setAttribute('hidden', 'true');
|
||||
|
||||
console.error(message + '\n' + moreInfoText);
|
||||
this.fallback();
|
||||
},
|
||||
|
||||
progress: function pdfViewProgress(level) {
|
||||
var percent = Math.round(level * 100);
|
||||
PDFView.loadingBar.percent = percent;
|
||||
// When we transition from full request to range requests, it's possible
|
||||
// that we discard some of the loaded data. This can cause the loading
|
||||
// bar to move backwards. So prevent this by only updating the bar if it
|
||||
// increases.
|
||||
if (percent > PDFView.loadingBar.percent) {
|
||||
PDFView.loadingBar.percent = percent;
|
||||
}
|
||||
},
|
||||
|
||||
load: function pdfViewLoad(pdfDocument, scale) {
|
||||
@ -1244,10 +1303,12 @@ var PDFView = {
|
||||
var errorWrapper = document.getElementById('errorWrapper');
|
||||
errorWrapper.setAttribute('hidden', 'true');
|
||||
|
||||
var loadingBox = document.getElementById('loadingBox');
|
||||
loadingBox.setAttribute('hidden', 'true');
|
||||
var loadingIndicator = document.getElementById('loading');
|
||||
loadingIndicator.textContent = '';
|
||||
pdfDocument.dataLoaded().then(function() {
|
||||
var loadingBar = document.getElementById('loadingBar');
|
||||
loadingBar.classList.add('hidden');
|
||||
var outerContainer = document.getElementById('outerContainer');
|
||||
outerContainer.classList.remove('loadingInProgress');
|
||||
});
|
||||
|
||||
var thumbsView = document.getElementById('thumbnailView');
|
||||
thumbsView.parentNode.scrollTop = 0;
|
||||
@ -1279,7 +1340,7 @@ var PDFView = {
|
||||
var pagesRefMap = this.pagesRefMap = {};
|
||||
var thumbnails = this.thumbnails = [];
|
||||
|
||||
var pagesPromise = new PDFJS.Promise();
|
||||
var pagesPromise = this.pagesPromise = new PDFJS.Promise();
|
||||
var self = this;
|
||||
|
||||
var firstPagePromise = pdfDocument.getPage(1);
|
||||
@ -1345,6 +1406,13 @@ var PDFView = {
|
||||
left + ',' + top;
|
||||
}
|
||||
self.setInitialView(storedHash, scale);
|
||||
|
||||
// Make all navigation keys work on document load,
|
||||
// unless the viewer is embedded in another page.
|
||||
if (window.parent === window) {
|
||||
PDFView.container.focus();
|
||||
PDFView.container.blur();
|
||||
}
|
||||
});
|
||||
|
||||
pagesPromise.then(function() {
|
||||
@ -1369,7 +1437,8 @@ var PDFView = {
|
||||
}
|
||||
});
|
||||
|
||||
var destinationsPromise = pdfDocument.getDestinations();
|
||||
var destinationsPromise =
|
||||
this.destinationsPromise = pdfDocument.getDestinations();
|
||||
destinationsPromise.then(function(destinations) {
|
||||
self.destinations = destinations;
|
||||
});
|
||||
@ -1382,12 +1451,6 @@ var PDFView = {
|
||||
self.outline = new DocumentOutlineView(outline);
|
||||
document.getElementById('viewOutline').disabled = !outline;
|
||||
});
|
||||
|
||||
// Make all navigation keys work on document load,
|
||||
// unless the viewer is embedded in another page.
|
||||
if (window.parent.location === window.location) {
|
||||
PDFView.container.focus();
|
||||
}
|
||||
});
|
||||
|
||||
pdfDocument.getMetadata().then(function(data) {
|
||||
@ -1616,10 +1679,10 @@ var PDFView = {
|
||||
},
|
||||
|
||||
getVisiblePages: function pdfViewGetVisiblePages() {
|
||||
if (!this.isFullscreen) {
|
||||
if (!this.isPresentationMode) {
|
||||
return this.getVisibleElements(this.container, this.pages, true);
|
||||
} else {
|
||||
// The algorithm in getVisibleElements is broken in fullscreen mode.
|
||||
// The algorithm in getVisibleElements is broken in presentation mode.
|
||||
var visible = [], page = this.page;
|
||||
var currentPage = this.pages[page - 1];
|
||||
visible.push({ id: currentPage.id, view: currentPage });
|
||||
@ -1687,7 +1750,7 @@ var PDFView = {
|
||||
var param = parts[i].split('=');
|
||||
var key = param[0];
|
||||
var value = param.length > 1 ? param[1] : null;
|
||||
params[unescape(key)] = unescape(value);
|
||||
params[decodeURIComponent(key)] = decodeURIComponent(value);
|
||||
}
|
||||
return params;
|
||||
},
|
||||
@ -1731,11 +1794,12 @@ var PDFView = {
|
||||
div.removeChild(div.lastChild);
|
||||
},
|
||||
|
||||
fullscreen: function pdfViewFullscreen() {
|
||||
var isFullscreen = document.fullscreenElement || document.mozFullScreen ||
|
||||
document.webkitIsFullScreen;
|
||||
presentationMode: function pdfViewPresentationMode() {
|
||||
var isPresentationMode = document.fullscreenElement ||
|
||||
document.mozFullScreen ||
|
||||
document.webkitIsFullScreen;
|
||||
|
||||
if (isFullscreen) {
|
||||
if (isPresentationMode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1750,12 +1814,12 @@ var PDFView = {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.isFullscreen = true;
|
||||
this.isPresentationMode = true;
|
||||
var currentPage = this.pages[this.page - 1];
|
||||
this.previousScale = this.currentScaleValue;
|
||||
this.parseScale('page-fit', true);
|
||||
|
||||
// Wait for fullscreen to take effect
|
||||
// Wait for presentation mode to take effect
|
||||
setTimeout(function() {
|
||||
currentPage.scrollIntoView();
|
||||
}, 0);
|
||||
@ -1764,15 +1828,15 @@ var PDFView = {
|
||||
return true;
|
||||
},
|
||||
|
||||
exitFullscreen: function pdfViewExitFullscreen() {
|
||||
this.isFullscreen = false;
|
||||
exitPresentationMode: function pdfViewExitPresentationMode() {
|
||||
this.isPresentationMode = false;
|
||||
this.parseScale(this.previousScale);
|
||||
this.page = this.page;
|
||||
this.clearMouseScrollState();
|
||||
this.hidePresentationControls();
|
||||
|
||||
// Ensure that the thumbnail of the current page is visible
|
||||
// when exiting fullscreen mode.
|
||||
// when exiting presentation mode.
|
||||
scrollIntoView(document.getElementById('thumbnailContainer' + this.page));
|
||||
},
|
||||
|
||||
@ -1824,7 +1888,7 @@ var PDFView = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for fullscreen to take effect
|
||||
// Wait for presentation mode to take effect
|
||||
setTimeout(function() {
|
||||
currentPage.scrollIntoView();
|
||||
}, 0);
|
||||
@ -1865,7 +1929,7 @@ var PDFView = {
|
||||
DOWN: 1
|
||||
};
|
||||
|
||||
// In fullscreen mode scroll one page at a time.
|
||||
// In presentation mode scroll one page at a time.
|
||||
var pageFlipDirection = (this.mouseScrollDelta > 0) ?
|
||||
PageFlipDirection.UP :
|
||||
PageFlipDirection.DOWN;
|
||||
@ -1982,7 +2046,8 @@ var PageView = function pageView(container, id, scale,
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
function setupAnnotations(pdfPage, viewport) {
|
||||
function setupAnnotations(annotationsDiv, pdfPage, viewport) {
|
||||
|
||||
function bindLink(link, dest) {
|
||||
link.href = PDFView.getDestinationHash(dest);
|
||||
link.onclick = function pageViewSetupLinksOnclick() {
|
||||
@ -1992,91 +2057,43 @@ var PageView = function pageView(container, id, scale,
|
||||
};
|
||||
link.className = 'internalLink';
|
||||
}
|
||||
function createElementWithStyle(tagName, item, rect) {
|
||||
if (!rect) {
|
||||
rect = viewport.convertToViewportRectangle(item.rect);
|
||||
rect = PDFJS.Util.normalizeRect(rect);
|
||||
}
|
||||
var element = document.createElement(tagName);
|
||||
element.style.left = Math.floor(rect[0]) + 'px';
|
||||
element.style.top = Math.floor(rect[1]) + 'px';
|
||||
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px';
|
||||
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px';
|
||||
return element;
|
||||
}
|
||||
function createTextAnnotation(item) {
|
||||
var container = document.createElement('section');
|
||||
container.className = 'annotText';
|
||||
|
||||
var rect = viewport.convertToViewportRectangle(item.rect);
|
||||
rect = PDFJS.Util.normalizeRect(rect);
|
||||
// sanity check because of OOo-generated PDFs
|
||||
if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) {
|
||||
rect[3] = rect[1] + ANNOT_MIN_SIZE;
|
||||
}
|
||||
if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) {
|
||||
rect[2] = rect[0] + (rect[3] - rect[1]); // make it square
|
||||
}
|
||||
var image = createElementWithStyle('img', item, rect);
|
||||
var iconName = item.name;
|
||||
image.src = IMAGE_DIR + 'annotation-' +
|
||||
iconName.toLowerCase() + '.svg';
|
||||
image.alt = mozL10n.get('text_annotation_type', {type: iconName},
|
||||
'[{{type}} Annotation]');
|
||||
var content = document.createElement('div');
|
||||
content.setAttribute('hidden', true);
|
||||
var title = document.createElement('h1');
|
||||
var text = document.createElement('p');
|
||||
content.style.left = Math.floor(rect[2]) + 'px';
|
||||
content.style.top = Math.floor(rect[1]) + 'px';
|
||||
title.textContent = item.title;
|
||||
|
||||
if (!item.content && !item.title) {
|
||||
content.setAttribute('hidden', true);
|
||||
} else {
|
||||
var e = document.createElement('span');
|
||||
var lines = item.content.split(/(?:\r\n?|\n)/);
|
||||
for (var i = 0, ii = lines.length; i < ii; ++i) {
|
||||
var line = lines[i];
|
||||
e.appendChild(document.createTextNode(line));
|
||||
if (i < (ii - 1))
|
||||
e.appendChild(document.createElement('br'));
|
||||
pdfPage.getAnnotations().then(function(annotationsData) {
|
||||
viewport = viewport.clone({ dontFlip: true });
|
||||
for (var i = 0; i < annotationsData.length; i++) {
|
||||
var data = annotationsData[i];
|
||||
var annotation = PDFJS.Annotation.fromData(data);
|
||||
if (!annotation || !annotation.hasHtml()) {
|
||||
continue;
|
||||
}
|
||||
text.appendChild(e);
|
||||
image.addEventListener('mouseover', function annotationImageOver() {
|
||||
content.removeAttribute('hidden');
|
||||
}, false);
|
||||
|
||||
image.addEventListener('mouseout', function annotationImageOut() {
|
||||
content.setAttribute('hidden', true);
|
||||
}, false);
|
||||
}
|
||||
var element = annotation.getHtmlElement(pdfPage.commonObjs);
|
||||
mozL10n.translate(element);
|
||||
|
||||
content.appendChild(title);
|
||||
content.appendChild(text);
|
||||
container.appendChild(image);
|
||||
container.appendChild(content);
|
||||
data = annotation.getData();
|
||||
var rect = data.rect;
|
||||
var view = pdfPage.view;
|
||||
rect = PDFJS.Util.normalizeRect([
|
||||
rect[0],
|
||||
view[3] - rect[1] + view[1],
|
||||
rect[2],
|
||||
view[3] - rect[3] + view[1]
|
||||
]);
|
||||
element.style.left = rect[0] + 'px';
|
||||
element.style.top = rect[1] + 'px';
|
||||
element.style.position = 'absolute';
|
||||
|
||||
return container;
|
||||
}
|
||||
var transform = viewport.transform;
|
||||
var transformStr = 'matrix(' + transform.join(',') + ')';
|
||||
CustomStyle.setProp('transform', element, transformStr);
|
||||
var transformOriginStr = -rect[0] + 'px ' + -rect[1] + 'px';
|
||||
CustomStyle.setProp('transformOrigin', element, transformOriginStr);
|
||||
|
||||
pdfPage.getAnnotations().then(function(items) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
switch (item.type) {
|
||||
case 'Link':
|
||||
var link = createElementWithStyle('a', item);
|
||||
link.href = item.url || '';
|
||||
if (!item.url)
|
||||
bindLink(link, ('dest' in item) ? item.dest : null);
|
||||
div.appendChild(link);
|
||||
break;
|
||||
case 'Text':
|
||||
var textAnnotation = createTextAnnotation(item);
|
||||
if (textAnnotation)
|
||||
div.appendChild(textAnnotation);
|
||||
break;
|
||||
if (data.subtype === 'Link' && !data.url) {
|
||||
bindLink(element, ('dest' in data) ? data.dest : null);
|
||||
}
|
||||
|
||||
annotationsDiv.appendChild(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -2135,10 +2152,16 @@ var PageView = function pageView(container, id, scale,
|
||||
return;
|
||||
}
|
||||
|
||||
if (scale && scale !== PDFView.currentScale)
|
||||
if (scale && scale !== PDFView.currentScale) {
|
||||
PDFView.parseScale(scale, true, true);
|
||||
else if (PDFView.currentScale === UNKNOWN_SCALE)
|
||||
} else if (PDFView.currentScale === UNKNOWN_SCALE) {
|
||||
PDFView.parseScale(DEFAULT_SCALE, true, true);
|
||||
}
|
||||
|
||||
if (scale === 'page-fit' && !dest[4]) {
|
||||
scrollIntoView(div);
|
||||
return;
|
||||
}
|
||||
|
||||
var boundingRect = [
|
||||
this.viewport.convertToViewportPoint(x, y),
|
||||
@ -2248,8 +2271,10 @@ var PageView = function pageView(container, id, scale,
|
||||
if (self.textLayer && self.textLayer.textDivs &&
|
||||
self.textLayer.textDivs.length > 0 &&
|
||||
!PDFView.supportsDocumentColors) {
|
||||
console.error(mozL10n.get('web_colors_disabled', null,
|
||||
'Web colors are disabled.'));
|
||||
console.error(mozL10n.get('document_colors_disabled', null,
|
||||
'PDF documents are not allowed to use their own colors: ' +
|
||||
'\'Allow pages to choose their own colors\' ' +
|
||||
'is deactivated in the browser.'));
|
||||
PDFView.fallback();
|
||||
}
|
||||
if (error) {
|
||||
@ -2312,7 +2337,7 @@ var PageView = function pageView(container, id, scale,
|
||||
);
|
||||
}
|
||||
|
||||
setupAnnotations(this.pdfPage, this.viewport);
|
||||
setupAnnotations(div, pdfPage, this.viewport);
|
||||
div.setAttribute('data-loaded', true);
|
||||
};
|
||||
|
||||
@ -2990,8 +3015,17 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
|
||||
var hash = document.location.hash.substring(1);
|
||||
var hashParams = PDFView.parseQueryString(hash);
|
||||
|
||||
if ('disableWorker' in hashParams)
|
||||
if ('disableWorker' in hashParams) {
|
||||
PDFJS.disableWorker = (hashParams['disableWorker'] === 'true');
|
||||
}
|
||||
|
||||
if ('disableRange' in hashParams) {
|
||||
PDFJS.disableRange = (hashParams['disableRange'] === 'true');
|
||||
}
|
||||
|
||||
if ('disableAutoFetch' in hashParams) {
|
||||
PDFJS.disableAutoFetch = (hashParams['disableAutoFetch'] === 'true');
|
||||
}
|
||||
|
||||
|
||||
if ('textLayer' in hashParams) {
|
||||
@ -3021,11 +3055,11 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
|
||||
}
|
||||
|
||||
if (!PDFView.supportsFullscreen) {
|
||||
document.getElementById('fullscreen').classList.add('hidden');
|
||||
document.getElementById('presentationMode').classList.add('hidden');
|
||||
}
|
||||
|
||||
if (PDFView.supportsIntegratedFind) {
|
||||
document.querySelector('#viewFind').classList.add('hidden');
|
||||
document.getElementById('viewFind').classList.add('hidden');
|
||||
}
|
||||
|
||||
// Listen for warnings to trigger the fallback UI. Errors should be caught
|
||||
@ -3076,19 +3110,19 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
|
||||
PDFView.page++;
|
||||
});
|
||||
|
||||
document.querySelector('.zoomIn').addEventListener('click',
|
||||
document.getElementById('zoomIn').addEventListener('click',
|
||||
function() {
|
||||
PDFView.zoomIn();
|
||||
});
|
||||
|
||||
document.querySelector('.zoomOut').addEventListener('click',
|
||||
document.getElementById('zoomOut').addEventListener('click',
|
||||
function() {
|
||||
PDFView.zoomOut();
|
||||
});
|
||||
|
||||
document.getElementById('fullscreen').addEventListener('click',
|
||||
document.getElementById('presentationMode').addEventListener('click',
|
||||
function() {
|
||||
PDFView.fullscreen();
|
||||
PDFView.presentationMode();
|
||||
});
|
||||
|
||||
document.getElementById('openFile').addEventListener('click',
|
||||
@ -3126,31 +3160,29 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
|
||||
PDFView.parseScale(this.value);
|
||||
});
|
||||
|
||||
document.getElementById('first_page').addEventListener('click',
|
||||
document.getElementById('firstPage').addEventListener('click',
|
||||
function() {
|
||||
PDFView.page = 1;
|
||||
});
|
||||
|
||||
document.getElementById('last_page').addEventListener('click',
|
||||
document.getElementById('lastPage').addEventListener('click',
|
||||
function() {
|
||||
PDFView.page = PDFView.pdfDocument.numPages;
|
||||
});
|
||||
|
||||
document.getElementById('page_rotate_ccw').addEventListener('click',
|
||||
document.getElementById('pageRotateCcw').addEventListener('click',
|
||||
function() {
|
||||
PDFView.rotatePages(-90);
|
||||
});
|
||||
|
||||
document.getElementById('page_rotate_cw').addEventListener('click',
|
||||
document.getElementById('pageRotateCw').addEventListener('click',
|
||||
function() {
|
||||
PDFView.rotatePages(90);
|
||||
});
|
||||
|
||||
if (FirefoxCom.requestSync('getLoadingType') == 'passive') {
|
||||
PDFView.setTitleUsingUrl(file);
|
||||
PDFView.initPassiveLoading();
|
||||
return;
|
||||
}
|
||||
PDFView.setTitleUsingUrl(file);
|
||||
PDFView.initPassiveLoading();
|
||||
return;
|
||||
|
||||
PDFView.open(file, 0);
|
||||
}, true);
|
||||
@ -3187,7 +3219,7 @@ function updateViewarea() {
|
||||
currentId = visiblePages[0].id;
|
||||
}
|
||||
|
||||
if (!PDFView.isFullscreen) {
|
||||
if (!PDFView.isPresentationMode) {
|
||||
updateViewarea.inProgress = true; // used in "set page"
|
||||
PDFView.page = currentId;
|
||||
updateViewarea.inProgress = false;
|
||||
@ -3285,6 +3317,9 @@ window.addEventListener('localized', function localized(evt) {
|
||||
}, true);
|
||||
|
||||
window.addEventListener('scalechange', function scalechange(evt) {
|
||||
document.getElementById('zoomOut').disabled = (evt.scale === MIN_SCALE);
|
||||
document.getElementById('zoomIn').disabled = (evt.scale === MAX_SCALE);
|
||||
|
||||
var customScaleOption = document.getElementById('customScaleOption');
|
||||
customScaleOption.selected = false;
|
||||
|
||||
@ -3301,10 +3336,6 @@ window.addEventListener('scalechange', function scalechange(evt) {
|
||||
customScaleOption.textContent = Math.round(evt.scale * 10000) / 100 + '%';
|
||||
customScaleOption.selected = true;
|
||||
}
|
||||
|
||||
document.getElementById('zoom_out').disabled = (evt.scale === MIN_SCALE);
|
||||
document.getElementById('zoom_in').disabled = (evt.scale === MAX_SCALE);
|
||||
|
||||
updateViewarea();
|
||||
}, true);
|
||||
|
||||
@ -3343,27 +3374,28 @@ window.addEventListener('DOMMouseScroll', function(evt) {
|
||||
var direction = (ticks > 0) ? 'zoomOut' : 'zoomIn';
|
||||
for (var i = 0, length = Math.abs(ticks); i < length; i++)
|
||||
PDFView[direction]();
|
||||
} else if (PDFView.isFullscreen) {
|
||||
} else if (PDFView.isPresentationMode) {
|
||||
var FIREFOX_DELTA_FACTOR = -40;
|
||||
PDFView.mouseScroll(evt.detail * FIREFOX_DELTA_FACTOR);
|
||||
}
|
||||
}, false);
|
||||
|
||||
window.addEventListener('mousemove', function mousemove(evt) {
|
||||
if (PDFView.isFullscreen) {
|
||||
if (PDFView.isPresentationMode) {
|
||||
PDFView.showPresentationControls();
|
||||
}
|
||||
}, false);
|
||||
|
||||
window.addEventListener('mousedown', function mousedown(evt) {
|
||||
if (PDFView.isFullscreen && evt.button === 0) {
|
||||
// Enable clicking of links in fullscreen mode.
|
||||
if (PDFView.isPresentationMode && evt.button === 0) {
|
||||
// Enable clicking of links in presentation mode.
|
||||
// Note: Only links that point to the currently loaded PDF document works.
|
||||
var targetHref = evt.target.href;
|
||||
var internalLink = targetHref && (targetHref.replace(/#.*$/, '') ===
|
||||
window.location.href.replace(/#.*$/, ''));
|
||||
if (!internalLink) {
|
||||
// Unless an internal link was clicked, advance a page in fullscreen mode.
|
||||
// Unless an internal link was clicked, advance a page in presentation
|
||||
// mode.
|
||||
evt.preventDefault();
|
||||
PDFView.page++;
|
||||
}
|
||||
@ -3371,7 +3403,7 @@ window.addEventListener('mousedown', function mousedown(evt) {
|
||||
}, false);
|
||||
|
||||
window.addEventListener('click', function click(evt) {
|
||||
if (PDFView.isFullscreen && evt.button === 0) {
|
||||
if (PDFView.isPresentationMode && evt.button === 0) {
|
||||
// Necessary since preventDefault() in 'mousedown' won't stop
|
||||
// the event propagation in all circumstances.
|
||||
evt.preventDefault();
|
||||
@ -3443,7 +3475,7 @@ window.addEventListener('keydown', function keydown(evt) {
|
||||
}
|
||||
var controlsElement = document.getElementById('toolbar');
|
||||
while (curElement) {
|
||||
if (curElement === controlsElement && !PDFView.isFullscreen)
|
||||
if (curElement === controlsElement && !PDFView.isPresentationMode)
|
||||
return; // ignoring if the 'toolbar' element is focused
|
||||
curElement = curElement.parentNode;
|
||||
}
|
||||
@ -3453,10 +3485,11 @@ window.addEventListener('keydown', function keydown(evt) {
|
||||
case 38: // up arrow
|
||||
case 33: // pg up
|
||||
case 8: // backspace
|
||||
if (!PDFView.isFullscreen && PDFView.currentScaleValue !== 'page-fit') {
|
||||
if (!PDFView.isPresentationMode &&
|
||||
PDFView.currentScaleValue !== 'page-fit') {
|
||||
break;
|
||||
}
|
||||
/* in fullscreen mode */
|
||||
/* in presentation mode */
|
||||
/* falls through */
|
||||
case 37: // left arrow
|
||||
// horizontal scrolling using arrow keys
|
||||
@ -3478,7 +3511,8 @@ window.addEventListener('keydown', function keydown(evt) {
|
||||
case 40: // down arrow
|
||||
case 34: // pg down
|
||||
case 32: // spacebar
|
||||
if (!PDFView.isFullscreen && PDFView.currentScaleValue !== 'page-fit') {
|
||||
if (!PDFView.isPresentationMode &&
|
||||
PDFView.currentScaleValue !== 'page-fit') {
|
||||
break;
|
||||
}
|
||||
/* falls through */
|
||||
@ -3495,13 +3529,13 @@ window.addEventListener('keydown', function keydown(evt) {
|
||||
break;
|
||||
|
||||
case 36: // home
|
||||
if (PDFView.isFullscreen) {
|
||||
if (PDFView.isPresentationMode) {
|
||||
PDFView.page = 1;
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
case 35: // end
|
||||
if (PDFView.isFullscreen) {
|
||||
if (PDFView.isPresentationMode) {
|
||||
PDFView.page = PDFView.pdfDocument.numPages;
|
||||
handled = true;
|
||||
}
|
||||
@ -3535,19 +3569,21 @@ window.addEventListener('afterprint', function afterPrint(evt) {
|
||||
PDFView.afterPrint();
|
||||
});
|
||||
|
||||
(function fullscreenClosure() {
|
||||
function fullscreenChange(e) {
|
||||
var isFullscreen = document.fullscreenElement || document.mozFullScreen ||
|
||||
document.webkitIsFullScreen;
|
||||
(function presentationModeClosure() {
|
||||
function presentationModeChange(e) {
|
||||
var isPresentationMode = document.fullscreenElement ||
|
||||
document.mozFullScreen ||
|
||||
document.webkitIsFullScreen;
|
||||
|
||||
if (!isFullscreen) {
|
||||
PDFView.exitFullscreen();
|
||||
if (!isPresentationMode) {
|
||||
PDFView.exitPresentationMode();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('fullscreenchange', fullscreenChange, false);
|
||||
window.addEventListener('mozfullscreenchange', fullscreenChange, false);
|
||||
window.addEventListener('webkitfullscreenchange', fullscreenChange, false);
|
||||
window.addEventListener('fullscreenchange', presentationModeChange, false);
|
||||
window.addEventListener('mozfullscreenchange', presentationModeChange, false);
|
||||
window.addEventListener('webkitfullscreenchange', presentationModeChange,
|
||||
false);
|
||||
})();
|
||||
|
||||
(function animationStartedClosure() {
|
||||
|
@ -2,6 +2,7 @@ chrome.manifest
|
||||
components/PdfRedirector.js
|
||||
components/PdfStreamConverter.js
|
||||
content/build/pdf.js
|
||||
content/network.js
|
||||
content/PdfJs.jsm
|
||||
content/web/debugger.js
|
||||
content/web/images/annotation-check.svg
|
||||
@ -22,13 +23,13 @@ content/web/images/shadow.png
|
||||
content/web/images/texture.png
|
||||
content/web/images/toolbarButton-bookmark.png
|
||||
content/web/images/toolbarButton-download.png
|
||||
content/web/images/toolbarButton-fullscreen.png
|
||||
content/web/images/toolbarButton-menuArrows.png
|
||||
content/web/images/toolbarButton-openFile.png
|
||||
content/web/images/toolbarButton-pageDown-rtl.png
|
||||
content/web/images/toolbarButton-pageDown.png
|
||||
content/web/images/toolbarButton-pageUp-rtl.png
|
||||
content/web/images/toolbarButton-pageUp.png
|
||||
content/web/images/toolbarButton-presentationMode.png
|
||||
content/web/images/toolbarButton-print.png
|
||||
content/web/images/toolbarButton-search.png
|
||||
content/web/images/toolbarButton-sidebarToggle.png
|
||||
|
@ -110,14 +110,15 @@ loading_error=An error occurred while loading the PDF.
|
||||
invalid_file_error=Invalid or corrupted PDF file.
|
||||
missing_file_error=Missing PDF file.
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
|
||||
# "{{type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}} Annotation]
|
||||
text_annotation_type.alt=[{{type}} Annotation]
|
||||
request_password=PDF is protected by a password:
|
||||
invalid_password=Invalid Password.
|
||||
|
||||
printing_not_supported=Warning: Printing is not fully supported by this browser.
|
||||
printing_not_ready=Warning: The PDF is not fully loaded for printing.
|
||||
web_fonts_disabled=Web fonts are disabled: unable to use embedded PDF fonts.
|
||||
web_colors_disabled=Web colors are disabled.
|
||||
document_colors_disabled=PDF documents are not allowed to use their own colors: \'Allow pages to choose their own colors\' is deactivated in the browser.
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIConsoleMessage.idl"
|
||||
|
||||
[scriptable, uuid(cac9d8e8-0d53-4fa8-9903-bb367e4fa1fe)]
|
||||
[scriptable, uuid(ec640482-be5f-49a0-a9cb-c87eacce9291)]
|
||||
interface nsIScriptError : nsIConsoleMessage
|
||||
{
|
||||
/** pseudo-flag for default case */
|
||||
@ -41,6 +41,33 @@ interface nsIScriptError : nsIConsoleMessage
|
||||
readonly attribute uint32_t columnNumber;
|
||||
readonly attribute uint32_t flags;
|
||||
|
||||
/**
|
||||
* Categories I know about -
|
||||
* XUL javascript
|
||||
* content javascript (both of these from nsDocShell, currently)
|
||||
* component javascript (errors in JS components)
|
||||
*/
|
||||
readonly attribute string category;
|
||||
|
||||
/*
|
||||
The time (in milliseconds from the Epoch) that the script error instance
|
||||
was initialised, and thus the time when the error occurred.
|
||||
Currently used to display date and time of the message in Error console.
|
||||
The timestamp is initialized as JS_now/1000 so that it can be
|
||||
compared to Date.now in Javascript.
|
||||
*/
|
||||
readonly attribute long long timeStamp;
|
||||
|
||||
/* Get the window id this was initialized with. Zero will be
|
||||
returned if init() was used instead of initWithWindowID(). */
|
||||
readonly attribute unsigned long long outerWindowID;
|
||||
|
||||
/* Get the inner window id this was initialized with. Zero will be
|
||||
returned if init() was used instead of initWithWindowID(). */
|
||||
readonly attribute unsigned long long innerWindowID;
|
||||
|
||||
readonly attribute boolean isFromPrivateWindow;
|
||||
|
||||
void init(in AString message,
|
||||
in AString sourceName,
|
||||
in AString sourceLine,
|
||||
@ -60,11 +87,13 @@ interface nsIScriptError : nsIConsoleMessage
|
||||
in uint32_t flags,
|
||||
in string category,
|
||||
in unsigned long long innerWindowID);
|
||||
|
||||
AUTF8String toString();
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define NS_SCRIPTERROR_CID \
|
||||
{ 0x1950539a, 0x90f0, 0x4d22, { 0xb5, 0xaf, 0x71, 0x32, 0x9c, 0x68, 0xfa, 0x35 }}
|
||||
{ 0xe38e53b9, 0x5bb0, 0x456a, { 0xb5, 0x53, 0x57, 0x93, 0x70, 0xcb, 0x15, 0x67 }}
|
||||
|
||||
#define NS_SCRIPTERROR_CONTRACTID "@mozilla.org/scripterror;1"
|
||||
%}
|
||||
|
@ -93,16 +93,6 @@ nsScriptError::GetCategory(char **result) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIConsoleMessage method
|
||||
NS_IMETHODIMP
|
||||
nsScriptError::InitMessage(const nsAString& message,
|
||||
const char *category,
|
||||
uint64_t innerWindowID)
|
||||
{
|
||||
return InitWithWindowID(message, EmptyString(), EmptyString(), 0, 0, 0,
|
||||
category, innerWindowID);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptError::Init(const nsAString& message,
|
||||
const nsAString& sourceName,
|
||||
|
@ -174,7 +174,6 @@ const UnsolicitedNotifications = {
|
||||
"consoleAPICall": "consoleAPICall",
|
||||
"eventNotification": "eventNotification",
|
||||
"fileActivity": "fileActivity",
|
||||
"logMessage": "logMessage",
|
||||
"networkEvent": "networkEvent",
|
||||
"networkEventUpdate": "networkEventUpdate",
|
||||
"newGlobal": "newGlobal",
|
||||
|
@ -39,7 +39,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "VariablesView",
|
||||
"resource:///modules/devtools/VariablesView.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["WebConsoleUtils", "JSPropertyProvider", "JSTermHelpers",
|
||||
"ConsoleServiceListener", "ConsoleAPIListener",
|
||||
"PageErrorListener", "ConsoleAPIListener",
|
||||
"NetworkResponseListener", "NetworkMonitor",
|
||||
"ConsoleProgressListener"];
|
||||
|
||||
@ -873,25 +873,25 @@ return JSPropertyProvider;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The nsIConsoleService listener. This is used to send all of the console
|
||||
* messages (JavaScript, CSS and more) to the remote Web Console instance.
|
||||
* The nsIConsoleService listener. This is used to send all the page errors
|
||||
* (JavaScript, CSS and more) to the remote Web Console instance.
|
||||
*
|
||||
* @constructor
|
||||
* @param nsIDOMWindow [aWindow]
|
||||
* Optional - the window object for which we are created. This is used
|
||||
* for filtering out messages that belong to other windows.
|
||||
* @param object aListener
|
||||
* The listener object must have one method:
|
||||
* - onConsoleServiceMessage(). This method is invoked with one argument, the
|
||||
* nsIConsoleMessage, whenever a relevant message is received.
|
||||
* The listener object must have a method: onPageError. This method is
|
||||
* invoked with one argument, the nsIScriptError, whenever a relevant
|
||||
* page error is received.
|
||||
*/
|
||||
this.ConsoleServiceListener = function ConsoleServiceListener(aWindow, aListener)
|
||||
this.PageErrorListener = function PageErrorListener(aWindow, aListener)
|
||||
{
|
||||
this.window = aWindow;
|
||||
this.listener = aListener;
|
||||
}
|
||||
|
||||
ConsoleServiceListener.prototype =
|
||||
PageErrorListener.prototype =
|
||||
{
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleListener]),
|
||||
|
||||
@ -902,7 +902,8 @@ ConsoleServiceListener.prototype =
|
||||
window: null,
|
||||
|
||||
/**
|
||||
* The listener object which is notified of messages from the console service.
|
||||
* The listener object which is notified of page errors. It must have
|
||||
* a onPageError method which is invoked with one argument: the nsIScriptError.
|
||||
* @type object
|
||||
*/
|
||||
listener: null,
|
||||
@ -910,7 +911,7 @@ ConsoleServiceListener.prototype =
|
||||
/**
|
||||
* Initialize the nsIConsoleService listener.
|
||||
*/
|
||||
init: function CSL_init()
|
||||
init: function PEL_init()
|
||||
{
|
||||
Services.console.registerListener(this);
|
||||
},
|
||||
@ -920,47 +921,43 @@ ConsoleServiceListener.prototype =
|
||||
* messages belonging to the current window and sends them to the remote Web
|
||||
* Console instance.
|
||||
*
|
||||
* @param nsIConsoleMessage aMessage
|
||||
* The message object coming from the nsIConsoleService.
|
||||
* @param nsIScriptError aScriptError
|
||||
* The script error object coming from the nsIConsoleService.
|
||||
*/
|
||||
observe: function CSL_observe(aMessage)
|
||||
observe: function PEL_observe(aScriptError)
|
||||
{
|
||||
if (!this.listener) {
|
||||
if (!this.listener ||
|
||||
!(aScriptError instanceof Ci.nsIScriptError)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.window) {
|
||||
if (!aMessage.outerWindowID ||
|
||||
!this.isCategoryAllowed(aMessage.category)) {
|
||||
if (!aScriptError.outerWindowID ||
|
||||
!this.isCategoryAllowed(aScriptError.category)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let errorWindow = Services.wm.getOuterWindowWithId(aMessage.outerWindowID);
|
||||
let errorWindow =
|
||||
Services.wm.getOuterWindowWithId(aScriptError.outerWindowID);
|
||||
if (!errorWindow || errorWindow.top != this.window) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aMessage.message) {
|
||||
this.listener.onConsoleServiceMessage(aMessage);
|
||||
}
|
||||
this.listener.onPageError(aScriptError);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the given message category is allowed to be tracked or not.
|
||||
* Check if the given script error category is allowed to be tracked or not.
|
||||
* We ignore chrome-originating errors as we only care about content.
|
||||
*
|
||||
* @param string aCategory
|
||||
* The message category you want to check.
|
||||
* The nsIScriptError category you want to check.
|
||||
* @return boolean
|
||||
* True if the category is allowed to be logged, false otherwise.
|
||||
*/
|
||||
isCategoryAllowed: function CSL_isCategoryAllowed(aCategory)
|
||||
isCategoryAllowed: function PEL_isCategoryAllowed(aCategory)
|
||||
{
|
||||
if (!aCategory) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (aCategory) {
|
||||
case "XPConnect JavaScript":
|
||||
case "component javascript":
|
||||
@ -980,26 +977,28 @@ ConsoleServiceListener.prototype =
|
||||
* Get the cached page errors for the current inner window.
|
||||
*
|
||||
* @return array
|
||||
* The array of cached messages. Each element is an nsIScriptError or
|
||||
* an nsIConsoleMessage.
|
||||
* The array of cached messages. Each element is an nsIScriptError
|
||||
* with an added _type property so the remote Web Console instance can
|
||||
* tell the difference between various types of cached messages.
|
||||
*/
|
||||
getCachedMessages: function CSL_getCachedMessages()
|
||||
getCachedMessages: function PEL_getCachedMessages()
|
||||
{
|
||||
let innerWindowId = this.window ?
|
||||
WebConsoleUtils.getInnerWindowId(this.window) : null;
|
||||
let errors = Services.console.getMessageArray() || [];
|
||||
|
||||
return errors.filter((aError) => {
|
||||
return !innerWindowId ||
|
||||
return errors.filter(function(aError) {
|
||||
return aError instanceof Ci.nsIScriptError &&
|
||||
(!innerWindowId ||
|
||||
(aError.innerWindowID == innerWindowId &&
|
||||
this.isCategoryAllowed(aError.category));
|
||||
});
|
||||
this.isCategoryAllowed(aError.category)));
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the nsIConsoleService listener.
|
||||
*/
|
||||
destroy: function CSL_destroy()
|
||||
destroy: function PEL_destroy()
|
||||
{
|
||||
Services.console.unregisterListener(this);
|
||||
this.listener = this.window = null;
|
||||
@ -1092,7 +1091,8 @@ ConsoleAPIListener.prototype =
|
||||
* Get the cached messages for the current inner window.
|
||||
*
|
||||
* @return array
|
||||
* The array of cached messages.
|
||||
* The array of cached messages. Each element is a Console API
|
||||
* prepared to be sent to the remote Web Console instance.
|
||||
*/
|
||||
getCachedMessages: function CAL_getCachedMessages()
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "WebConsoleUtils",
|
||||
"resource://gre/modules/devtools/WebConsoleUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ConsoleServiceListener",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PageErrorListener",
|
||||
"resource://gre/modules/devtools/WebConsoleUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPIListener",
|
||||
@ -165,10 +165,10 @@ WebConsoleActor.prototype =
|
||||
_window: null,
|
||||
|
||||
/**
|
||||
* The ConsoleServiceListener instance.
|
||||
* The PageErrorListener instance.
|
||||
* @type object
|
||||
*/
|
||||
consoleServiceListener: null,
|
||||
pageErrorListener: null,
|
||||
|
||||
/**
|
||||
* The ConsoleAPIListener instance.
|
||||
@ -211,9 +211,9 @@ WebConsoleActor.prototype =
|
||||
*/
|
||||
disconnect: function WCA_disconnect()
|
||||
{
|
||||
if (this.consoleServiceListener) {
|
||||
this.consoleServiceListener.destroy();
|
||||
this.consoleServiceListener = null;
|
||||
if (this.pageErrorListener) {
|
||||
this.pageErrorListener.destroy();
|
||||
this.pageErrorListener = null;
|
||||
}
|
||||
if (this.consoleAPIListener) {
|
||||
this.consoleAPIListener.destroy();
|
||||
@ -363,10 +363,10 @@ WebConsoleActor.prototype =
|
||||
let listener = aRequest.listeners.shift();
|
||||
switch (listener) {
|
||||
case "PageError":
|
||||
if (!this.consoleServiceListener) {
|
||||
this.consoleServiceListener =
|
||||
new ConsoleServiceListener(window, this);
|
||||
this.consoleServiceListener.init();
|
||||
if (!this.pageErrorListener) {
|
||||
this.pageErrorListener =
|
||||
new PageErrorListener(window, this);
|
||||
this.pageErrorListener.init();
|
||||
}
|
||||
startedListeners.push(listener);
|
||||
break;
|
||||
@ -426,9 +426,9 @@ WebConsoleActor.prototype =
|
||||
let listener = toDetach.shift();
|
||||
switch (listener) {
|
||||
case "PageError":
|
||||
if (this.consoleServiceListener) {
|
||||
this.consoleServiceListener.destroy();
|
||||
this.consoleServiceListener = null;
|
||||
if (this.pageErrorListener) {
|
||||
this.pageErrorListener.destroy();
|
||||
this.pageErrorListener = null;
|
||||
}
|
||||
stoppedListeners.push(listener);
|
||||
break;
|
||||
@ -495,24 +495,13 @@ WebConsoleActor.prototype =
|
||||
}
|
||||
break;
|
||||
case "PageError":
|
||||
if (this.consoleServiceListener) {
|
||||
let cache = this.consoleServiceListener.getCachedMessages();
|
||||
cache.forEach((aMessage) => {
|
||||
let message = null;
|
||||
if (aMessage instanceof Ci.nsIScriptError) {
|
||||
message = this.preparePageErrorForRemote(aMessage);
|
||||
message._type = type;
|
||||
}
|
||||
else {
|
||||
message = {
|
||||
_type: "LogMessage",
|
||||
message: aMessage.message,
|
||||
timeStamp: aMessage.timeStamp,
|
||||
category: aMessage.category,
|
||||
};
|
||||
}
|
||||
if (this.pageErrorListener) {
|
||||
let cache = this.pageErrorListener.getCachedMessages();
|
||||
cache.forEach(function(aMessage) {
|
||||
let message = this.preparePageErrorForRemote(aMessage);
|
||||
message._type = type;
|
||||
messages.push(message);
|
||||
});
|
||||
}, this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -606,10 +595,6 @@ WebConsoleActor.prototype =
|
||||
let windowId = !this._isGlobalActor ?
|
||||
WebConsoleUtils.getInnerWindowId(this.window) : null;
|
||||
ConsoleAPIStorage.clearEvents(windowId);
|
||||
if (this._isGlobalActor) {
|
||||
Services.console.logStringMessage(null); // for the Error Console
|
||||
Services.console.reset();
|
||||
}
|
||||
return {};
|
||||
},
|
||||
|
||||
@ -867,31 +852,19 @@ WebConsoleActor.prototype =
|
||||
//////////////////
|
||||
|
||||
/**
|
||||
* Handler for messages received from the ConsoleServiceListener. This method
|
||||
* sends the nsIConsoleMessage to the remote Web Console client.
|
||||
* Handler for page errors received from the PageErrorListener. This method
|
||||
* sends the nsIScriptError to the remote Web Console client.
|
||||
*
|
||||
* @param nsIConsoleMessage aMessage
|
||||
* The message we need to send to the client.
|
||||
* @param nsIScriptError aPageError
|
||||
* The page error we need to send to the client.
|
||||
*/
|
||||
onConsoleServiceMessage: function WCA_onConsoleServiceMessage(aMessage)
|
||||
onPageError: function WCA_onPageError(aPageError)
|
||||
{
|
||||
let packet;
|
||||
if (aMessage instanceof Ci.nsIScriptError) {
|
||||
packet = {
|
||||
from: this.actorID,
|
||||
type: "pageError",
|
||||
pageError: this.preparePageErrorForRemote(aMessage),
|
||||
};
|
||||
}
|
||||
else {
|
||||
packet = {
|
||||
from: this.actorID,
|
||||
type: "logMessage",
|
||||
message: aMessage.message,
|
||||
timeStamp: aMessage.timeStamp,
|
||||
category: aMessage.category,
|
||||
};
|
||||
}
|
||||
let packet = {
|
||||
from: this.actorID,
|
||||
type: "pageError",
|
||||
pageError: this.preparePageErrorForRemote(aPageError),
|
||||
};
|
||||
this.conn.send(packet);
|
||||
},
|
||||
|
||||
|
@ -24,7 +24,6 @@ MOCHITEST_CHROME_FILES = \
|
||||
test_bug819670_getter_throws.html \
|
||||
test_object_actor_native_getters.html \
|
||||
test_object_actor_native_getters_lenient_this.html \
|
||||
test_nsiconsolemessage.html \
|
||||
network_requests_iframe.html \
|
||||
data.json \
|
||||
data.json^headers^ \
|
||||
|
@ -106,10 +106,7 @@ function checkObject(aObject, aExpected)
|
||||
|
||||
function checkValue(aName, aValue, aExpected)
|
||||
{
|
||||
if (aExpected === null) {
|
||||
ok(!aValue, "'" + aName + "' is null");
|
||||
}
|
||||
else if (aValue === undefined) {
|
||||
if (aValue === undefined) {
|
||||
ok(false, "'" + aName + "' is undefined");
|
||||
}
|
||||
else if (typeof aExpected == "string" || typeof aExpected == "number" ||
|
||||
|
@ -95,7 +95,7 @@ function doConsoleCalls()
|
||||
<script class="testbody" type="text/javascript;version=1.8">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let consoleAPIListener, consoleServiceListener;
|
||||
let consoleAPIListener, pageErrorListener;
|
||||
let consoleAPICalls = 0;
|
||||
let pageErrors = 0;
|
||||
|
||||
@ -108,7 +108,7 @@ let handlers = {
|
||||
}
|
||||
},
|
||||
|
||||
onConsoleServiceMessage: function onConsoleServiceMessage()
|
||||
onPageError: function onPageError()
|
||||
{
|
||||
pageErrors++;
|
||||
if (pageErrors == expectedPageErrors.length) {
|
||||
@ -153,16 +153,16 @@ function onCachedConsoleAPI(aState, aResponse)
|
||||
});
|
||||
|
||||
closeDebugger(aState, function() {
|
||||
consoleServiceListener = new ConsoleServiceListener(null, handlers);
|
||||
consoleServiceListener.init();
|
||||
pageErrorListener = new PageErrorListener(null, handlers);
|
||||
pageErrorListener.init();
|
||||
doPageErrors();
|
||||
});
|
||||
}
|
||||
|
||||
function testPageErrors()
|
||||
{
|
||||
consoleServiceListener.destroy();
|
||||
consoleServiceListener = null;
|
||||
pageErrorListener.destroy();
|
||||
pageErrorListener = null;
|
||||
attachConsole(["PageError"], onAttach2);
|
||||
}
|
||||
|
||||
|
@ -1,126 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Test for nsIConsoleMessages</title>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript;version=1.8" src="common.js"></script>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
</head>
|
||||
<body>
|
||||
<p>Make sure that nsIConsoleMessages are logged. See bug 859756.</p>
|
||||
|
||||
<script class="testbody" type="text/javascript;version=1.8">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let expectedMessages = [];
|
||||
let testingTabActor = false;
|
||||
|
||||
function sendConsoleMessage(aMessage, aCategory, aWindowId)
|
||||
{
|
||||
let consoleMsg = Cc["@mozilla.org/consolemessage;1"]
|
||||
.createInstance(Ci.nsIConsoleMessage);
|
||||
consoleMsg.initMessage(aMessage, aCategory, aWindowId);
|
||||
Services.console.logMessage(consoleMsg);
|
||||
}
|
||||
|
||||
function sendMessages()
|
||||
{
|
||||
expectedMessages = [
|
||||
{
|
||||
message: "hello world! bug859756",
|
||||
category: null,
|
||||
timeStamp: /^\d+$/,
|
||||
},
|
||||
{
|
||||
message: "foobarz",
|
||||
category: null,
|
||||
timeStamp: /^\d+$/,
|
||||
},
|
||||
{
|
||||
message: "boom",
|
||||
category: "cat7",
|
||||
timeStamp: /^\d+$/,
|
||||
},
|
||||
{
|
||||
message: "windowfun",
|
||||
category: "cat9",
|
||||
timeStamp: /^\d+$/,
|
||||
},
|
||||
];
|
||||
|
||||
Services.console.logStringMessage("hello world! bug859756");
|
||||
sendConsoleMessage("foobarz");
|
||||
sendConsoleMessage("boom", "cat7");
|
||||
sendConsoleMessage("windowfun", "cat9", Date.now());
|
||||
}
|
||||
|
||||
function sendMessagesForTab()
|
||||
{
|
||||
sendMessages();
|
||||
expectedMessages = [
|
||||
{
|
||||
message: "windowfun3",
|
||||
category: "cat10",
|
||||
timeStamp: /^\d+$/,
|
||||
},
|
||||
];
|
||||
|
||||
let windowID = WebConsoleUtils.getInnerWindowId(top);
|
||||
sendConsoleMessage("windowfun3", "cat10", windowID);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
removeEventListener("load", startTest);
|
||||
attachConsole(["PageError"], onAttach);
|
||||
}
|
||||
|
||||
function onAttach(aState, aResponse)
|
||||
{
|
||||
window.onLogMessage_ = onLogMessage.bind(null, aState);
|
||||
aState.dbgClient.addListener("logMessage", onLogMessage_);
|
||||
|
||||
if (!testingTabActor) {
|
||||
sendMessages();
|
||||
} else {
|
||||
sendMessagesForTab();
|
||||
}
|
||||
|
||||
info("waiting for messages");
|
||||
}
|
||||
|
||||
let receivedMessages = [];
|
||||
|
||||
function onLogMessage(aState, aType, aPacket)
|
||||
{
|
||||
is(aPacket.from, aState.actor, "packet actor");
|
||||
|
||||
receivedMessages.push(aPacket);
|
||||
if (receivedMessages.length != expectedMessages.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
aState.dbgClient.removeListener("logMessage", onLogMessage_);
|
||||
|
||||
checkObject(receivedMessages, expectedMessages);
|
||||
|
||||
receivedMessages = expectedMessages = [];
|
||||
window.onLogMessage_ = null;
|
||||
|
||||
closeDebugger(aState, () => {
|
||||
if (!testingTabActor) {
|
||||
testingTabActor = true;
|
||||
info("start tab actor test");
|
||||
attachConsole(["PageError"], onAttach, true);
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addEventListener("load", startTest);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -103,7 +103,6 @@ endif
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/../build \
|
||||
-I$(topsrcdir)/xpcom/ds \
|
||||
-I$(topsrcdir)/dom/base \
|
||||
$(NULL)
|
||||
|
||||
# We generate ErrorListCxxDefines.h from ErrorList.h using regex. The -n option
|
||||
|
@ -9,115 +9,29 @@
|
||||
|
||||
#include "nsConsoleMessage.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsConsoleMessage, nsIConsoleMessage)
|
||||
|
||||
nsConsoleMessage::nsConsoleMessage()
|
||||
: mMessage(),
|
||||
mCategory(),
|
||||
mOuterWindowID(0),
|
||||
mInnerWindowID(0),
|
||||
mTimeStamp(0),
|
||||
mIsFromPrivateWindow(false)
|
||||
nsConsoleMessage::nsConsoleMessage()
|
||||
{
|
||||
}
|
||||
|
||||
nsConsoleMessage::nsConsoleMessage(const PRUnichar *message)
|
||||
nsConsoleMessage::nsConsoleMessage(const PRUnichar *message)
|
||||
{
|
||||
nsString m;
|
||||
m.Assign(message);
|
||||
InitMessage(m, nullptr, 0);
|
||||
mMessage.Assign(message);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConsoleMessage::InitMessage(const nsAString& message,
|
||||
const char *category,
|
||||
uint64_t innerWindowID)
|
||||
{
|
||||
mTimeStamp = JS_Now() / 1000;
|
||||
mMessage.Assign(message);
|
||||
mCategory.Assign(category);
|
||||
mInnerWindowID = innerWindowID;
|
||||
nsConsoleMessage::GetMessageMoz(PRUnichar **result) {
|
||||
*result = ToNewUnicode(mMessage);
|
||||
|
||||
if (innerWindowID) {
|
||||
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(innerWindowID);
|
||||
if (window) {
|
||||
nsPIDOMWindow* outer = window->GetOuterWindow();
|
||||
if (outer)
|
||||
mOuterWindowID = outer->WindowID();
|
||||
|
||||
nsIDocShell* docShell = window->GetDocShell();
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
|
||||
|
||||
if (loadContext) {
|
||||
// Never mark exceptions from chrome windows as having come from
|
||||
// private windows, since we always want them to be reported.
|
||||
nsIPrincipal* winPrincipal = window->GetPrincipal();
|
||||
mIsFromPrivateWindow = loadContext->UsePrivateBrowsing() &&
|
||||
!nsContentUtils::IsSystemPrincipal(winPrincipal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConsoleMessage::GetMessageMoz(PRUnichar **result)
|
||||
{
|
||||
*result = ToNewUnicode(mMessage);
|
||||
// NS_IMETHODIMP
|
||||
// nsConsoleMessage::Init(const PRUnichar *message) {
|
||||
// nsAutoString newMessage(message);
|
||||
// mMessage = ToNewUnicode(newMessage);
|
||||
// return NS_OK;
|
||||
// }
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConsoleMessage::GetCategory(char **result)
|
||||
{
|
||||
*result = ToNewCString(mCategory);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConsoleMessage::GetOuterWindowID(uint64_t *aOuterWindowID)
|
||||
{
|
||||
*aOuterWindowID = mOuterWindowID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConsoleMessage::GetInnerWindowID(uint64_t *aInnerWindowID)
|
||||
{
|
||||
*aInnerWindowID = mInnerWindowID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConsoleMessage::GetTimeStamp(int64_t *aTimeStamp)
|
||||
{
|
||||
*aTimeStamp = mTimeStamp;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConsoleMessage::GetIsFromPrivateWindow(bool *aIsFromPrivateWindow)
|
||||
{
|
||||
*aIsFromPrivateWindow = mIsFromPrivateWindow;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConsoleMessage::ToString(nsACString& /*UTF8*/ aResult)
|
||||
{
|
||||
if (!mCategory.IsEmpty())
|
||||
aResult.Assign(mCategory + NS_LITERAL_CSTRING(": ") +
|
||||
NS_ConvertUTF16toUTF8(mMessage));
|
||||
else
|
||||
CopyUTF16toUTF8(mMessage, aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -22,11 +22,6 @@ public:
|
||||
private:
|
||||
~nsConsoleMessage() {}
|
||||
|
||||
int64_t mTimeStamp;
|
||||
nsCString mCategory;
|
||||
uint64_t mOuterWindowID;
|
||||
uint64_t mInnerWindowID;
|
||||
bool mIsFromPrivateWindow;
|
||||
nsString mMessage;
|
||||
};
|
||||
|
||||
|
@ -10,49 +10,13 @@
|
||||
* provide an object that can be qi'ed to provide more specific
|
||||
* message information.
|
||||
*/
|
||||
[scriptable, uuid(c14c151b-5ea4-47ed-8e85-d392cdd3e154)]
|
||||
[scriptable, uuid(41bd8784-1dd2-11b2-9553-8606958fffe1)]
|
||||
interface nsIConsoleMessage : nsISupports
|
||||
{
|
||||
void initMessage(in AString message, [optional] in string category, [optional] in unsigned long long innerWindowID);
|
||||
|
||||
/**
|
||||
* The time (in milliseconds from the Epoch) that the message instance
|
||||
* was initialised.
|
||||
* The timestamp is initialized as JS_now/1000 so that it can be
|
||||
* compared to Date.now in Javascript.
|
||||
*/
|
||||
readonly attribute long long timeStamp;
|
||||
|
||||
/**
|
||||
* Categories I know about
|
||||
* - nsIScriptError:
|
||||
* XUL javascript
|
||||
* content javascript (both of these from nsDocShell, currently)
|
||||
* component javascript (errors in JS components)
|
||||
* - nsIConsoleMessage: none yet.
|
||||
*/
|
||||
readonly attribute string category;
|
||||
|
||||
/**
|
||||
* Get the window id this was initialized with.
|
||||
*/
|
||||
readonly attribute unsigned long long outerWindowID;
|
||||
|
||||
/**
|
||||
* Get the inner window id this was initialized with.
|
||||
*/
|
||||
readonly attribute unsigned long long innerWindowID;
|
||||
|
||||
readonly attribute boolean isFromPrivateWindow;
|
||||
|
||||
[binaryname(MessageMoz)] readonly attribute wstring message;
|
||||
|
||||
AUTF8String toString();
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define NS_CONSOLEMESSAGE_CID \
|
||||
{ 0x024efc9e, 0x54dc, 0x4844, { 0x80, 0x4b, 0x41, 0xd3, 0xf3, 0x69, 0x90, 0x73 }}
|
||||
|
||||
#define NS_CONSOLEMESSAGE_CONTRACTID "@mozilla.org/consolemessage;1"
|
||||
{ 0x56c9d666, 0x1dd2, 0x11b2, { 0xb4, 0x3c, 0xa8, 0x4b, 0xf3, 0xb3, 0xec, 0xbb }}
|
||||
%}
|
||||
|
@ -21,7 +21,6 @@
|
||||
COMPONENT(ARRAY, nsArray::XPCOMConstructor)
|
||||
COMPONENT(CONSOLESERVICE, nsConsoleServiceConstructor)
|
||||
COMPONENT(EXCEPTIONSERVICE, nsExceptionServiceConstructor)
|
||||
COMPONENT(CONSOLEMESSAGE, nsConsoleMessageConstructor)
|
||||
COMPONENT(ATOMSERVICE, nsAtomServiceConstructor)
|
||||
COMPONENT(OBSERVERSERVICE, nsObserverService::Create)
|
||||
#ifdef MOZ_VISUAL_EVENT_TRACER
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "nsSupportsPrimitives.h"
|
||||
#include "nsConsoleService.h"
|
||||
#include "nsExceptionService.h"
|
||||
#include "nsConsoleMessage.h"
|
||||
|
||||
#include "nsComponentManager.h"
|
||||
#include "nsCategoryManagerUtils.h"
|
||||
@ -179,7 +178,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsVoidImpl)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointerImpl)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsConsoleService, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsConsoleMessage)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExceptionService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
|
||||
|
Loading…
Reference in New Issue
Block a user