mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Merge m-c to graphics
This commit is contained in:
commit
3fe2c02ee1
@ -46,6 +46,18 @@ public:
|
||||
|
||||
bool IsShutdown() const { return mShutdown; }
|
||||
|
||||
/**
|
||||
* Mark this actor as shutdown without doing any cleanup. This should only
|
||||
* be called on actors that have just been initialized, so probably only from
|
||||
* RecvPDocAccessibleConstructor.
|
||||
*/
|
||||
void MarkAsShutdown()
|
||||
{
|
||||
MOZ_ASSERT(mChildDocs.IsEmpty());
|
||||
MOZ_ASSERT(mAccessibles.Count() == 0);
|
||||
mShutdown = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when a message from a document in a child process notifies the main
|
||||
* process it is firing an event.
|
||||
|
@ -38,7 +38,7 @@ support-files =
|
||||
[browser_treeupdate_gencontent.js]
|
||||
[browser_treeupdate_hidden.js]
|
||||
[browser_treeupdate_imagemap.js]
|
||||
skip-if = (os == 'mac' && debug && e10s) # Bug 1318569
|
||||
skip-if = e10s # Bug 1318569
|
||||
[browser_treeupdate_list.js]
|
||||
[browser_treeupdate_list_editabledoc.js]
|
||||
[browser_treeupdate_listener.js]
|
||||
|
@ -1029,8 +1029,12 @@ pref("security.sandbox.content.tempDirSuffix", "");
|
||||
#if defined(MOZ_SANDBOX)
|
||||
// This pref determines if messages relevant to sandbox violations are
|
||||
// logged.
|
||||
#if defined(XP_WIN)
|
||||
pref("security.sandbox.logging.enabled", false);
|
||||
#else
|
||||
pref("security.sandbox.logging.enabled", true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// This pref governs whether we attempt to work around problems caused by
|
||||
// plugins using OS calls to manipulate the cursor while running out-of-
|
||||
|
@ -296,6 +296,7 @@ var FullScreen = {
|
||||
this._fullScrToggler = document.getElementById("fullscr-toggler");
|
||||
this._fullScrToggler.addEventListener("mouseover", this._expandCallback);
|
||||
this._fullScrToggler.addEventListener("dragenter", this._expandCallback);
|
||||
this._fullScrToggler.addEventListener("touchmove", this._expandCallback, {passive: true});
|
||||
}
|
||||
|
||||
if (enterFS) {
|
||||
|
@ -92,24 +92,18 @@ var security = {
|
||||
break;
|
||||
}
|
||||
|
||||
// Select status text to display for Certificate Transparency.
|
||||
// Select the status text to display for Certificate Transparency.
|
||||
// Since we do not yet enforce the CT Policy on secure connections,
|
||||
// we must not complain on policy discompliance (it might be viewed
|
||||
// as a security issue by the user).
|
||||
switch (status.certificateTransparencyStatus) {
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE:
|
||||
// CT compliance checks were not performed,
|
||||
// do not display any status text.
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS:
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS:
|
||||
retval.certificateTransparency = null;
|
||||
break;
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_NONE:
|
||||
retval.certificateTransparency = "None";
|
||||
break;
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_OK:
|
||||
retval.certificateTransparency = "OK";
|
||||
break;
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_UNKNOWN_LOG:
|
||||
retval.certificateTransparency = "UnknownLog";
|
||||
break;
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_INVALID:
|
||||
retval.certificateTransparency = "Invalid";
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT:
|
||||
retval.certificateTransparency = "Compliant";
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ function checkIdentityPopup(icon) {
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser);
|
||||
|
||||
// check that a warning is shown when loading a page with mixed content and an overridden certificate
|
||||
yield loadBadCertPage(MIXED_CONTENT_URL);
|
||||
@ -47,5 +48,7 @@ add_task(function* () {
|
||||
let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
|
||||
.getService(Ci.nsICertOverrideService);
|
||||
certOverrideService.clearValidityOverride("self-signed.example.com", -1);
|
||||
|
||||
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
|
@ -1015,16 +1015,9 @@ function* loadBadCertPage(url) {
|
||||
"cert-exception-ui-ready", false);
|
||||
});
|
||||
|
||||
// Sometimes clearing the cert override is not immediately picked up,
|
||||
// so we reload until we are on an actual cert error page.
|
||||
yield BrowserTestUtils.waitForCondition(function*() {
|
||||
yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, url);
|
||||
yield promiseErrorPageLoaded(gBrowser.selectedBrowser);
|
||||
let isErrorPage = yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
|
||||
return content.document.documentURI.startsWith("about:certerror");
|
||||
});
|
||||
return isErrorPage;
|
||||
}, "Could not load error page", 1000);
|
||||
let loaded = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser);
|
||||
yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, url);
|
||||
yield loaded;
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
|
||||
content.document.getElementById("exceptionDialogButton").click();
|
||||
|
@ -39,13 +39,14 @@ var gTests = [
|
||||
info("request audio+video and check if there is no prompt");
|
||||
yield promiseRequestDevice(true, true, null, null, win.gBrowser.selectedBrowser);
|
||||
yield promiseObserverCalled("getUserMedia:request");
|
||||
yield promiseNoPopupNotification("webRTC-shareDevices");
|
||||
yield expectObserverCalled("getUserMedia:response:allow");
|
||||
yield expectObserverCalled("recording-device-events");
|
||||
let promises = [promiseNoPopupNotification("webRTC-shareDevices"),
|
||||
promiseObserverCalled("getUserMedia:response:allow"),
|
||||
promiseObserverCalled("recording-device-events")];
|
||||
yield Promise.all(promises);
|
||||
|
||||
let promises = [promiseObserverCalled("recording-device-events"),
|
||||
promiseObserverCalled("recording-device-events"),
|
||||
promiseObserverCalled("recording-window-ended")];
|
||||
promises = [promiseObserverCalled("recording-device-events"),
|
||||
promiseObserverCalled("recording-device-events"),
|
||||
promiseObserverCalled("recording-window-ended")];
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
yield Promise.all(promises);
|
||||
|
||||
|
@ -320,7 +320,7 @@ extensions.registerSchemaAPI("bookmarks", "addon_parent", context => {
|
||||
|
||||
onCreated: new SingletonEventManager(context, "bookmarks.onCreated", fire => {
|
||||
let listener = (event, bookmark) => {
|
||||
context.runSafe(fire, bookmark.id, bookmark);
|
||||
fire.sync(bookmark.id, bookmark);
|
||||
};
|
||||
|
||||
observer.on("created", listener);
|
||||
@ -333,7 +333,7 @@ extensions.registerSchemaAPI("bookmarks", "addon_parent", context => {
|
||||
|
||||
onRemoved: new SingletonEventManager(context, "bookmarks.onRemoved", fire => {
|
||||
let listener = (event, data) => {
|
||||
context.runSafe(fire, data.guid, data.info);
|
||||
fire.sync(data.guid, data.info);
|
||||
};
|
||||
|
||||
observer.on("removed", listener);
|
||||
@ -346,7 +346,7 @@ extensions.registerSchemaAPI("bookmarks", "addon_parent", context => {
|
||||
|
||||
onChanged: new SingletonEventManager(context, "bookmarks.onChanged", fire => {
|
||||
let listener = (event, data) => {
|
||||
context.runSafe(fire, data.guid, data.info);
|
||||
fire.sync(data.guid, data.info);
|
||||
};
|
||||
|
||||
observer.on("changed", listener);
|
||||
@ -359,7 +359,7 @@ extensions.registerSchemaAPI("bookmarks", "addon_parent", context => {
|
||||
|
||||
onMoved: new SingletonEventManager(context, "bookmarks.onMoved", fire => {
|
||||
let listener = (event, data) => {
|
||||
context.runSafe(fire, data.guid, data.info);
|
||||
fire.sync(data.guid, data.info);
|
||||
};
|
||||
|
||||
observer.on("moved", listener);
|
||||
|
@ -18,7 +18,7 @@ Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
var {
|
||||
EventManager,
|
||||
SingletonEventManager,
|
||||
IconDetails,
|
||||
} = ExtensionUtils;
|
||||
|
||||
@ -446,10 +446,10 @@ extensions.registerSchemaAPI("browserAction", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
browserAction: {
|
||||
onClicked: new EventManager(context, "browserAction.onClicked", fire => {
|
||||
onClicked: new SingletonEventManager(context, "browserAction.onClicked", fire => {
|
||||
let listener = () => {
|
||||
let tab = TabManager.activeTab;
|
||||
fire(TabManager.convert(extension, tab));
|
||||
fire.async(TabManager.convert(extension, tab));
|
||||
};
|
||||
BrowserAction.for(extension).on("click", listener);
|
||||
return () => {
|
||||
|
@ -5,7 +5,6 @@
|
||||
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
|
||||
var {
|
||||
runSafeSyncWithoutClone,
|
||||
SingletonEventManager,
|
||||
} = ExtensionUtils;
|
||||
|
||||
@ -14,7 +13,7 @@ extensions.registerSchemaAPI("omnibox", "addon_child", context => {
|
||||
omnibox: {
|
||||
onInputChanged: new SingletonEventManager(context, "omnibox.onInputChanged", fire => {
|
||||
let listener = (text, id) => {
|
||||
runSafeSyncWithoutClone(fire, text, suggestions => {
|
||||
fire.asyncWithoutClone(text, suggestions => {
|
||||
// TODO: Switch to using callParentFunctionNoReturn once bug 1314903 is fixed.
|
||||
context.childManager.callParentAsyncFunction("omnibox_internal.addSuggestions", [
|
||||
id,
|
||||
|
@ -6,7 +6,7 @@ Cu.import("resource://devtools/shared/event-emitter.js");
|
||||
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
|
||||
var {
|
||||
EventManager,
|
||||
SingletonEventManager,
|
||||
PlatformInfo,
|
||||
} = ExtensionUtils;
|
||||
|
||||
@ -245,9 +245,9 @@ extensions.registerSchemaAPI("commands", "addon_parent", context => {
|
||||
});
|
||||
}));
|
||||
},
|
||||
onCommand: new EventManager(context, "commands.onCommand", fire => {
|
||||
onCommand: new SingletonEventManager(context, "commands.onCommand", fire => {
|
||||
let listener = (eventName, commandName) => {
|
||||
fire(commandName);
|
||||
fire.async(commandName);
|
||||
};
|
||||
commandsMap.get(extension).on("command", listener);
|
||||
return () => {
|
||||
|
@ -8,9 +8,9 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
var {
|
||||
EventManager,
|
||||
ExtensionError,
|
||||
IconDetails,
|
||||
SingletonEventManager,
|
||||
} = ExtensionUtils;
|
||||
|
||||
const ACTION_MENU_TOP_LEVEL_LIMIT = 6;
|
||||
@ -625,9 +625,9 @@ extensions.registerSchemaAPI("contextMenus", "addon_parent", context => {
|
||||
}
|
||||
},
|
||||
|
||||
onClicked: new EventManager(context, "contextMenus.onClicked", fire => {
|
||||
onClicked: new SingletonEventManager(context, "contextMenus.onClicked", fire => {
|
||||
let listener = (event, info, tab) => {
|
||||
fire(info, tab);
|
||||
fire.async(info, tab);
|
||||
};
|
||||
|
||||
extension.on("webext-contextmenu-menuitem-click", listener);
|
||||
|
@ -222,7 +222,7 @@ extensions.registerSchemaAPI("history", "addon_parent", context => {
|
||||
|
||||
onVisited: new SingletonEventManager(context, "history.onVisited", fire => {
|
||||
let listener = (event, data) => {
|
||||
context.runSafe(fire, data);
|
||||
fire.sync(data);
|
||||
};
|
||||
|
||||
getObserver().on("visited", listener);
|
||||
@ -233,7 +233,7 @@ extensions.registerSchemaAPI("history", "addon_parent", context => {
|
||||
|
||||
onVisitRemoved: new SingletonEventManager(context, "history.onVisitRemoved", fire => {
|
||||
let listener = (event, data) => {
|
||||
context.runSafe(fire, data);
|
||||
fire.sync(data);
|
||||
};
|
||||
|
||||
getObserver().on("visitRemoved", listener);
|
||||
|
@ -50,7 +50,7 @@ extensions.registerSchemaAPI("omnibox", "addon_parent", context => {
|
||||
|
||||
onInputStarted: new SingletonEventManager(context, "omnibox.onInputStarted", fire => {
|
||||
let listener = (eventName) => {
|
||||
fire();
|
||||
fire.sync();
|
||||
};
|
||||
extension.on(ExtensionSearchHandler.MSG_INPUT_STARTED, listener);
|
||||
return () => {
|
||||
@ -60,7 +60,7 @@ extensions.registerSchemaAPI("omnibox", "addon_parent", context => {
|
||||
|
||||
onInputCancelled: new SingletonEventManager(context, "omnibox.onInputCancelled", fire => {
|
||||
let listener = (eventName) => {
|
||||
fire();
|
||||
fire.sync();
|
||||
};
|
||||
extension.on(ExtensionSearchHandler.MSG_INPUT_CANCELLED, listener);
|
||||
return () => {
|
||||
@ -70,7 +70,7 @@ extensions.registerSchemaAPI("omnibox", "addon_parent", context => {
|
||||
|
||||
onInputEntered: new SingletonEventManager(context, "omnibox.onInputEntered", fire => {
|
||||
let listener = (eventName, text, disposition) => {
|
||||
fire(text, disposition);
|
||||
fire.sync(text, disposition);
|
||||
};
|
||||
extension.on(ExtensionSearchHandler.MSG_INPUT_ENTERED, listener);
|
||||
return () => {
|
||||
@ -92,7 +92,7 @@ extensions.registerSchemaAPI("omnibox", "addon_parent", context => {
|
||||
|
||||
onInputChanged: new SingletonEventManager(context, "omnibox_internal.onInputChanged", fire => {
|
||||
let listener = (eventName, text, id) => {
|
||||
fire(text, id);
|
||||
fire.sync(text, id);
|
||||
};
|
||||
extension.on(ExtensionSearchHandler.MSG_INPUT_CHANGED, listener);
|
||||
return () => {
|
||||
|
@ -5,7 +5,7 @@
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
var {
|
||||
EventManager,
|
||||
SingletonEventManager,
|
||||
IconDetails,
|
||||
} = ExtensionUtils;
|
||||
|
||||
@ -244,9 +244,9 @@ extensions.registerSchemaAPI("pageAction", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
pageAction: {
|
||||
onClicked: new EventManager(context, "pageAction.onClicked", fire => {
|
||||
onClicked: new SingletonEventManager(context, "pageAction.onClicked", fire => {
|
||||
let listener = (evt, tab) => {
|
||||
fire(TabManager.convert(extension, tab));
|
||||
fire.async(TabManager.convert(extension, tab));
|
||||
};
|
||||
let pageAction = PageAction.for(extension);
|
||||
|
||||
|
@ -94,7 +94,7 @@ extensions.registerSchemaAPI("sessions", "addon_parent", context => {
|
||||
|
||||
onChanged: new SingletonEventManager(context, "sessions.onChanged", fire => {
|
||||
let observer = () => {
|
||||
context.runSafe(fire);
|
||||
fire.async();
|
||||
};
|
||||
|
||||
Services.obs.addObserver(observer, SS_ON_CLOSED_OBJECTS_CHANGED, false);
|
||||
|
@ -18,7 +18,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
|
||||
var {
|
||||
EventManager,
|
||||
SingletonEventManager,
|
||||
ignoreEvent,
|
||||
} = ExtensionUtils;
|
||||
|
||||
@ -283,12 +283,12 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
let tab = event.originalTarget;
|
||||
let tabId = TabManager.getId(tab);
|
||||
let windowId = WindowManager.getId(tab.ownerGlobal);
|
||||
fire({tabId, windowId});
|
||||
fire.async({tabId, windowId});
|
||||
}).api(),
|
||||
|
||||
onCreated: new EventManager(context, "tabs.onCreated", fire => {
|
||||
onCreated: new SingletonEventManager(context, "tabs.onCreated", fire => {
|
||||
let listener = (eventName, event) => {
|
||||
fire(TabManager.convert(extension, event.tab));
|
||||
fire.async(TabManager.convert(extension, event.tab));
|
||||
};
|
||||
|
||||
tabListener.on("tab-created", listener);
|
||||
@ -307,12 +307,12 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
let tab = event.originalTarget;
|
||||
let tabIds = [TabManager.getId(tab)];
|
||||
let windowId = WindowManager.getId(tab.ownerGlobal);
|
||||
fire({tabIds, windowId});
|
||||
fire.async({tabIds, windowId});
|
||||
}).api(),
|
||||
|
||||
onAttached: new EventManager(context, "tabs.onAttached", fire => {
|
||||
onAttached: new SingletonEventManager(context, "tabs.onAttached", fire => {
|
||||
let listener = (eventName, event) => {
|
||||
fire(event.tabId, {newWindowId: event.newWindowId, newPosition: event.newPosition});
|
||||
fire.async(event.tabId, {newWindowId: event.newWindowId, newPosition: event.newPosition});
|
||||
};
|
||||
|
||||
tabListener.on("tab-attached", listener);
|
||||
@ -321,9 +321,9 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
};
|
||||
}).api(),
|
||||
|
||||
onDetached: new EventManager(context, "tabs.onDetached", fire => {
|
||||
onDetached: new SingletonEventManager(context, "tabs.onDetached", fire => {
|
||||
let listener = (eventName, event) => {
|
||||
fire(event.tabId, {oldWindowId: event.oldWindowId, oldPosition: event.oldPosition});
|
||||
fire.async(event.tabId, {oldWindowId: event.oldWindowId, oldPosition: event.oldPosition});
|
||||
};
|
||||
|
||||
tabListener.on("tab-detached", listener);
|
||||
@ -332,9 +332,9 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
};
|
||||
}).api(),
|
||||
|
||||
onRemoved: new EventManager(context, "tabs.onRemoved", fire => {
|
||||
onRemoved: new SingletonEventManager(context, "tabs.onRemoved", fire => {
|
||||
let listener = (eventName, event) => {
|
||||
fire(event.tabId, {windowId: event.windowId, isWindowClosing: event.isWindowClosing});
|
||||
fire.async(event.tabId, {windowId: event.windowId, isWindowClosing: event.isWindowClosing});
|
||||
};
|
||||
|
||||
tabListener.on("tab-removed", listener);
|
||||
@ -345,7 +345,7 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
|
||||
onReplaced: ignoreEvent(context, "tabs.onReplaced"),
|
||||
|
||||
onMoved: new EventManager(context, "tabs.onMoved", fire => {
|
||||
onMoved: new SingletonEventManager(context, "tabs.onMoved", fire => {
|
||||
// There are certain circumstances where we need to ignore a move event.
|
||||
//
|
||||
// Namely, the first time the tab is moved after it's created, we need
|
||||
@ -373,7 +373,7 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
return;
|
||||
}
|
||||
|
||||
fire(TabManager.getId(tab), {
|
||||
fire.async(TabManager.getId(tab), {
|
||||
windowId: WindowManager.getId(tab.ownerGlobal),
|
||||
fromIndex: event.detail,
|
||||
toIndex: tab._tPos,
|
||||
@ -388,7 +388,7 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
};
|
||||
}).api(),
|
||||
|
||||
onUpdated: new EventManager(context, "tabs.onUpdated", fire => {
|
||||
onUpdated: new SingletonEventManager(context, "tabs.onUpdated", fire => {
|
||||
const restricted = ["url", "favIconUrl", "title"];
|
||||
|
||||
function sanitize(extension, changeInfo) {
|
||||
@ -410,7 +410,7 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
let tabElem = gBrowser.getTabForBrowser(browser);
|
||||
|
||||
let tab = TabManager.convert(extension, tabElem);
|
||||
fire(tab.id, changeInfo, tab);
|
||||
fire.async(tab.id, changeInfo, tab);
|
||||
}
|
||||
};
|
||||
|
||||
@ -447,7 +447,7 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
for (let prop of needed) {
|
||||
changeInfo[prop] = tab[prop];
|
||||
}
|
||||
fire(tab.id, changeInfo, tab);
|
||||
fire.async(tab.id, changeInfo, tab);
|
||||
}
|
||||
};
|
||||
let progressListener = {
|
||||
@ -1025,7 +1025,7 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
onZoomChange: new EventManager(context, "tabs.onZoomChange", fire => {
|
||||
onZoomChange: new SingletonEventManager(context, "tabs.onZoomChange", fire => {
|
||||
let getZoomLevel = browser => {
|
||||
let {ZoomManager} = browser.ownerGlobal;
|
||||
|
||||
@ -1075,7 +1075,7 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
zoomLevels.set(browser, newZoomFactor);
|
||||
|
||||
let tabId = TabManager.getId(tab);
|
||||
fire({
|
||||
fire.async({
|
||||
tabId,
|
||||
oldZoomFactor,
|
||||
newZoomFactor,
|
||||
|
@ -28,8 +28,8 @@ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
var {
|
||||
DefaultWeakMap,
|
||||
EventManager,
|
||||
promiseEvent,
|
||||
SingletonEventManager,
|
||||
} = ExtensionUtils;
|
||||
|
||||
// This file provides some useful code for the |tabs| and |windows|
|
||||
@ -1281,16 +1281,16 @@ global.AllWindowEvents = {
|
||||
|
||||
AllWindowEvents.openListener = AllWindowEvents.openListener.bind(AllWindowEvents);
|
||||
|
||||
// Subclass of EventManager where we just need to call
|
||||
// Subclass of SingletonEventManager where we just need to call
|
||||
// add/removeEventListener on each XUL window.
|
||||
global.WindowEventManager = function(context, name, event, listener) {
|
||||
EventManager.call(this, context, name, fire => {
|
||||
let listener2 = (...args) => listener(fire, ...args);
|
||||
AllWindowEvents.addListener(event, listener2);
|
||||
return () => {
|
||||
AllWindowEvents.removeListener(event, listener2);
|
||||
};
|
||||
});
|
||||
global.WindowEventManager = class extends SingletonEventManager {
|
||||
constructor(context, name, event, listener) {
|
||||
super(context, name, fire => {
|
||||
let listener2 = (...args) => listener(fire, ...args);
|
||||
AllWindowEvents.addListener(event, listener2);
|
||||
return () => {
|
||||
AllWindowEvents.removeListener(event, listener2);
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
WindowEventManager.prototype = Object.create(EventManager.prototype);
|
||||
|
@ -12,7 +12,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
||||
|
||||
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
var {
|
||||
EventManager,
|
||||
SingletonEventManager,
|
||||
promiseObserved,
|
||||
} = ExtensionUtils;
|
||||
|
||||
@ -26,15 +26,15 @@ extensions.registerSchemaAPI("windows", "addon_parent", context => {
|
||||
windows: {
|
||||
onCreated:
|
||||
new WindowEventManager(context, "windows.onCreated", "domwindowopened", (fire, window) => {
|
||||
fire(WindowManager.convert(extension, window));
|
||||
fire.async(WindowManager.convert(extension, window));
|
||||
}).api(),
|
||||
|
||||
onRemoved:
|
||||
new WindowEventManager(context, "windows.onRemoved", "domwindowclosed", (fire, window) => {
|
||||
fire(WindowManager.getId(window));
|
||||
fire.async(WindowManager.getId(window));
|
||||
}).api(),
|
||||
|
||||
onFocusChanged: new EventManager(context, "windows.onFocusChanged", fire => {
|
||||
onFocusChanged: new SingletonEventManager(context, "windows.onFocusChanged", fire => {
|
||||
// Keep track of the last windowId used to fire an onFocusChanged event
|
||||
let lastOnFocusChangedWindowId;
|
||||
|
||||
@ -45,7 +45,7 @@ extensions.registerSchemaAPI("windows", "addon_parent", context => {
|
||||
let window = Services.focus.activeWindow;
|
||||
let windowId = window ? WindowManager.getId(window) : WindowManager.WINDOW_ID_NONE;
|
||||
if (windowId !== lastOnFocusChangedWindowId) {
|
||||
fire(windowId);
|
||||
fire.async(windowId);
|
||||
lastOnFocusChangedWindowId = windowId;
|
||||
}
|
||||
});
|
||||
|
@ -4,8 +4,11 @@ module.exports = { // eslint-disable-line no-undef
|
||||
"extends": "../../.eslintrc.js",
|
||||
|
||||
"globals": {
|
||||
"addMessageListener": false,
|
||||
"Components": true,
|
||||
"dump": true,
|
||||
"removeMessageListener": false,
|
||||
"sendAsyncMessage": false,
|
||||
"TextDecoder": false,
|
||||
"TextEncoder": false,
|
||||
},
|
||||
|
@ -56,6 +56,7 @@ let FormAutofillParent = {
|
||||
let mm = Cc["@mozilla.org/globalmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageListenerManager);
|
||||
mm.addMessageListener("FormAutofill:PopulateFieldValues", this);
|
||||
mm.addMessageListener("FormAutofill:GetProfiles", this);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -70,6 +71,9 @@ let FormAutofillParent = {
|
||||
case "FormAutofill:PopulateFieldValues":
|
||||
this._populateFieldValues(data, target);
|
||||
break;
|
||||
case "FormAutofill:GetProfiles":
|
||||
this._getProfiles(data, target);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@ -98,6 +102,7 @@ let FormAutofillParent = {
|
||||
let mm = Cc["@mozilla.org/globalmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageListenerManager);
|
||||
mm.removeMessageListener("FormAutofill:PopulateFieldValues", this);
|
||||
mm.removeMessageListener("FormAutofill:GetProfiles", this);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -118,6 +123,29 @@ let FormAutofillParent = {
|
||||
target.sendAsyncMessage("FormAutofill:fillForm", {fields});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the profile data from profile store and return profiles back to content process.
|
||||
*
|
||||
* @private
|
||||
* @param {string} data.searchString
|
||||
* The typed string for filtering out the matched profile.
|
||||
* @param {string} data.info
|
||||
* The input autocomplete property's information.
|
||||
* @param {nsIFrameMessageManager} target
|
||||
* Content's message manager.
|
||||
*/
|
||||
_getProfiles({searchString, info}, target) {
|
||||
let profiles = [];
|
||||
|
||||
if (info && info.fieldName) {
|
||||
profiles = this._profileStore.getByFilter({searchString, info});
|
||||
} else {
|
||||
profiles = this._profileStore.getAll();
|
||||
}
|
||||
|
||||
target.messageManager.sendAsyncMessage("FormAutofill:Profiles", profiles);
|
||||
},
|
||||
|
||||
/**
|
||||
* Transforms a word with hyphen into camel case.
|
||||
* (e.g. transforms "address-type" into "addressType".)
|
||||
|
@ -66,6 +66,20 @@ const VALID_FIELDS = [
|
||||
"email",
|
||||
];
|
||||
|
||||
// TODO: Remove this once we can add profile from preference.
|
||||
const MOCK_MODE = false;
|
||||
const MOCK_STORAGE = [{
|
||||
guid: "test-guid-1",
|
||||
organization: "Sesame Street",
|
||||
streetAddress: "123 Sesame Street.",
|
||||
tel: "1-345-345-3456",
|
||||
}, {
|
||||
guid: "test-guid-2",
|
||||
organization: "Mozilla",
|
||||
streetAddress: "331 E. Evelyn Avenue",
|
||||
tel: "1-650-903-0800",
|
||||
}];
|
||||
|
||||
function ProfileStorage(path) {
|
||||
this._path = path;
|
||||
}
|
||||
@ -210,6 +224,19 @@ ProfileStorage.prototype = {
|
||||
return this._store.data.profiles.map(this._clone);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the filtered profiles based on input's information and searchString.
|
||||
*
|
||||
* @returns {Array.<Profile>}
|
||||
* An array containing clones of matched profiles.
|
||||
*/
|
||||
getByFilter({info, searchString}) {
|
||||
this._store.ensureDataReady();
|
||||
|
||||
// Profiles are cloned to avoid accidental modifications from outside.
|
||||
return this._findByFilter({info, searchString}).map(this._clone);
|
||||
},
|
||||
|
||||
_clone(profile) {
|
||||
return Object.assign({}, profile);
|
||||
},
|
||||
@ -218,6 +245,23 @@ ProfileStorage.prototype = {
|
||||
return this._store.data.profiles.find(profile => profile.guid == guid);
|
||||
},
|
||||
|
||||
_findByFilter({info, searchString}) {
|
||||
let profiles = MOCK_MODE ? MOCK_STORAGE : this._store.data.profiles;
|
||||
let lcSearchString = searchString.toLowerCase();
|
||||
|
||||
return profiles.filter(profile => {
|
||||
// Return true if string is not provided and field exists.
|
||||
// TODO: We'll need to check if the address is for billing or shipping.
|
||||
let name = profile[info.fieldName];
|
||||
|
||||
if (!searchString) {
|
||||
return !!name;
|
||||
}
|
||||
|
||||
return name.toLowerCase().startsWith(lcSearchString);
|
||||
});
|
||||
},
|
||||
|
||||
_normalizeProfile(profile) {
|
||||
let result = {};
|
||||
for (let key in profile) {
|
||||
|
@ -2,6 +2,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* eslint-disable no-use-before-define */
|
||||
|
||||
/*
|
||||
* Form Autofill frame script.
|
||||
*/
|
||||
@ -227,28 +229,74 @@ AutofillProfileAutoCompleteSearch.prototype = {
|
||||
* @param {Object} listener the listener to notify when the search is complete
|
||||
*/
|
||||
startSearch(searchString, searchParam, previousResult, listener) {
|
||||
// TODO: These mock data should be replaced by form autofill API
|
||||
let fieldName = "name";
|
||||
let profiles = [{
|
||||
guid: "test-guid-1",
|
||||
organization: "Sesame Street",
|
||||
streetAddress: "123 Sesame Street.",
|
||||
tel: "1-345-345-3456.",
|
||||
}, {
|
||||
guid: "test-guid-2",
|
||||
organization: "Mozilla",
|
||||
streetAddress: "331 E. Evelyn Avenue",
|
||||
tel: "1-650-903-0800",
|
||||
}];
|
||||
let result = new ProfileAutoCompleteResult(searchString, fieldName, profiles, {});
|
||||
this.forceStop = false;
|
||||
let info = this.getInputDetails();
|
||||
|
||||
listener.onSearchResult(this, result);
|
||||
this.getProfiles({info, searchString}).then((profiles) => {
|
||||
if (this.forceStop) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Set formInfo for ProfileAutoCompleteResult
|
||||
// let formInfo = this.getFormDetails();
|
||||
let result = new ProfileAutoCompleteResult(searchString, info, profiles, {});
|
||||
|
||||
listener.onSearchResult(this, result);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops an asynchronous search that is in progress
|
||||
*/
|
||||
stopSearch() {
|
||||
this.forceStop = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the profile data from parent process for AutoComplete result.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} data
|
||||
* Parameters for querying the corresponding result.
|
||||
* @param {string} data.searchString
|
||||
* The typed string for filtering out the matched profile.
|
||||
* @param {string} data.info
|
||||
* The input autocomplete property's information.
|
||||
* @returns {Promise}
|
||||
* Promise that resolves when profiles returned from parent process.
|
||||
*/
|
||||
getProfiles(data) {
|
||||
return new Promise((resolve) => {
|
||||
addMessageListener("FormAutofill:Profiles", function getResult(result) {
|
||||
removeMessageListener("FormAutofill:Profiles", getResult);
|
||||
resolve(result.data);
|
||||
});
|
||||
|
||||
sendAsyncMessage("FormAutofill:GetProfiles", data);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Get the input's information from FormAutofillContent's cache.
|
||||
*
|
||||
* @returns {Object}
|
||||
* Target input's information that cached in FormAutofillContent.
|
||||
*/
|
||||
getInputDetails() {
|
||||
// TODO: Maybe we'll need to wait for cache ready if detail is empty.
|
||||
return FormAutofillContent.getInputDetails(formFillController.getFocusedInput());
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the form's information from FormAutofillContent's cache.
|
||||
*
|
||||
* @returns {Array<Object>}
|
||||
* Array of the inputs' information for the target form.
|
||||
*/
|
||||
getFormDetails() {
|
||||
// TODO: Maybe we'll need to wait for cache ready if details is empty.
|
||||
return FormAutofillContent.getFormDetails(formFillController.getFocusedInput());
|
||||
},
|
||||
};
|
||||
|
||||
@ -307,11 +355,69 @@ var FormAutofillContent = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the input's information from cache which is created after page identified.
|
||||
*
|
||||
* @param {HTMLInputElement} element Focused input which triggered profile searching
|
||||
* @returns {Object|null}
|
||||
* Return target input's information that cloned from content cache
|
||||
* (or return null if the information is not found in the cache).
|
||||
*/
|
||||
getInputDetails(element) {
|
||||
for (let formDetails of this._formsDetails) {
|
||||
for (let detail of formDetails) {
|
||||
if (element == detail.element) {
|
||||
return this._serializeInfo(detail);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the form's information from cache which is created after page identified.
|
||||
*
|
||||
* @param {HTMLInputElement} element Focused input which triggered profile searching
|
||||
* @returns {Array<Object>|null}
|
||||
* Return target form's information that cloned from content cache
|
||||
* (or return null if the information is not found in the cache).
|
||||
*
|
||||
*/
|
||||
getFormDetails(element) {
|
||||
for (let formDetails of this._formsDetails) {
|
||||
if (formDetails.some((detail) => detail.element == element)) {
|
||||
return formDetails.map((detail) => this._serializeInfo(detail));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a clone the information object without element reference.
|
||||
*
|
||||
* @param {Object} detail Profile autofill information for specific input.
|
||||
* @returns {Object}
|
||||
* Return a copy of cached information object without element reference
|
||||
* since it's not needed for creating result.
|
||||
*/
|
||||
_serializeInfo(detail) {
|
||||
let info = Object.assign({}, detail);
|
||||
delete info.element;
|
||||
return info;
|
||||
},
|
||||
|
||||
_identifyAutofillFields(doc) {
|
||||
let forms = [];
|
||||
this._formsDetails = [];
|
||||
|
||||
// Collects root forms from inputs.
|
||||
for (let field of doc.getElementsByTagName("input")) {
|
||||
// We only consider text-like fields for now until we support radio and
|
||||
// checkbox buttons in the future.
|
||||
if (!field.mozIsTextField(true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let formLike = FormLikeFactory.createFromField(field);
|
||||
if (!forms.some(form => form.rootElement === formLike.rootElement)) {
|
||||
forms.push(formLike);
|
||||
@ -327,6 +433,7 @@ var FormAutofillContent = {
|
||||
return;
|
||||
}
|
||||
|
||||
this._formsDetails.push(formHandler.fieldDetails);
|
||||
formHandler.fieldDetails.forEach(
|
||||
detail => this._markAsAutofillField(detail.element));
|
||||
});
|
||||
@ -337,4 +444,5 @@ var FormAutofillContent = {
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
FormAutofillContent.init();
|
||||
|
@ -0,0 +1,90 @@
|
||||
"use strict";
|
||||
|
||||
let {FormAutofillContent} = loadFormAutofillContent();
|
||||
|
||||
const TESTCASES = [
|
||||
{
|
||||
description: "Form containing 5 fields with autocomplete attribute.",
|
||||
document: `<form>
|
||||
<input id="street-addr" autocomplete="street-address">
|
||||
<input id="city" autocomplete="address-level2">
|
||||
<input id="country" autocomplete="country">
|
||||
<input id="email" autocomplete="email">
|
||||
<input id="tel" autocomplete="tel">
|
||||
</form>`,
|
||||
targetInput: ["street-addr", "country"],
|
||||
expectedResult: [{
|
||||
input: {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
form: [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
|
||||
],
|
||||
},
|
||||
{
|
||||
input: {"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
|
||||
form: [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
|
||||
],
|
||||
}],
|
||||
},
|
||||
{
|
||||
description: "2 forms that are able to be auto filled",
|
||||
document: `<form>
|
||||
<input id="home-addr" autocomplete="street-address">
|
||||
<input id="city" autocomplete="address-level2">
|
||||
<input id="country" autocomplete="country">
|
||||
</form>
|
||||
<form>
|
||||
<input id="office-addr" autocomplete="street-address">
|
||||
<input id="email" autocomplete="email">
|
||||
<input id="tel" autocomplete="tel">
|
||||
</form>`,
|
||||
targetInput: ["home-addr", "office-addr"],
|
||||
expectedResult: [{
|
||||
input: {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
form: [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
|
||||
],
|
||||
},
|
||||
{
|
||||
input: {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
form: [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
|
||||
],
|
||||
}],
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
TESTCASES.forEach(testcase => {
|
||||
add_task(function* () {
|
||||
do_print("Starting testcase: " + testcase.description);
|
||||
|
||||
let doc = MockDocument.createTestDocument(
|
||||
"http://localhost:8080/test/", testcase.document);
|
||||
FormAutofillContent._identifyAutofillFields(doc);
|
||||
|
||||
for (let i in testcase.targetInput) {
|
||||
let input = doc.getElementById(testcase.targetInput[i]);
|
||||
|
||||
Assert.deepEqual(FormAutofillContent.getInputDetails(input),
|
||||
testcase.expectedResult[i].input,
|
||||
"Check if returned input information is correct.");
|
||||
|
||||
Assert.deepEqual(FormAutofillContent.getFormDetails(input),
|
||||
testcase.expectedResult[i].form,
|
||||
"Check if returned form information is correct.");
|
||||
}
|
||||
});
|
||||
});
|
@ -109,6 +109,38 @@ add_task(function* test_get() {
|
||||
/No matching profile\./);
|
||||
});
|
||||
|
||||
add_task(function* test_getByFilter() {
|
||||
let path = getTempFile(TEST_STORE_FILE_NAME).path;
|
||||
yield prepareTestProfiles(path);
|
||||
|
||||
let profileStorage = new ProfileStorage(path);
|
||||
yield profileStorage.initialize();
|
||||
|
||||
let filter = {info: {fieldName: "streetAddress"}, searchString: "Some"};
|
||||
let profiles = profileStorage.getByFilter(filter);
|
||||
do_check_eq(profiles.length, 1);
|
||||
do_check_profile_matches(profiles[0], TEST_PROFILE_2);
|
||||
|
||||
filter = {info: {fieldName: "country"}, searchString: "u"};
|
||||
profiles = profileStorage.getByFilter(filter);
|
||||
do_check_eq(profiles.length, 2);
|
||||
do_check_profile_matches(profiles[0], TEST_PROFILE_1);
|
||||
do_check_profile_matches(profiles[1], TEST_PROFILE_2);
|
||||
|
||||
filter = {info: {fieldName: "streetAddress"}, searchString: "test"};
|
||||
profiles = profileStorage.getByFilter(filter);
|
||||
do_check_eq(profiles.length, 0);
|
||||
|
||||
filter = {info: {fieldName: "streetAddress"}, searchString: ""};
|
||||
profiles = profileStorage.getByFilter(filter);
|
||||
do_check_eq(profiles.length, 2);
|
||||
|
||||
// Check if the filtering logic is free from searching special chars.
|
||||
filter = {info: {fieldName: "streetAddress"}, searchString: ".*"};
|
||||
profiles = profileStorage.getByFilter(filter);
|
||||
do_check_eq(profiles.length, 0);
|
||||
});
|
||||
|
||||
add_task(function* test_add() {
|
||||
let path = getTempFile(TEST_STORE_FILE_NAME).path;
|
||||
yield prepareTestProfiles(path);
|
||||
|
@ -5,6 +5,7 @@ support-files =
|
||||
|
||||
[test_autofillFormFields.js]
|
||||
[test_collectFormFields.js]
|
||||
[test_getFormInputDetails.js]
|
||||
[test_markAsAutofillField.js]
|
||||
[test_populateFieldValues.js]
|
||||
[test_profileAutocompleteResult.js]
|
||||
|
@ -1,3 +1,3 @@
|
||||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 1.6.467
|
||||
Current extension version is: 1.7.227
|
||||
|
@ -21,30 +21,14 @@ Components.utils.import('resource://gre/modules/Services.jsm');
|
||||
var EXPORTED_SYMBOLS = ['NetworkManager'];
|
||||
|
||||
function log(aMsg) {
|
||||
var msg = 'network.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
||||
var msg = 'PdfJsNetwork.jsm: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
||||
Services.console.logStringMessage(msg);
|
||||
}
|
||||
|
||||
var NetworkManager = (function NetworkManagerClosure() {
|
||||
|
||||
var OK_RESPONSE = 200;
|
||||
var PARTIAL_CONTENT_RESPONSE = 206;
|
||||
|
||||
function NetworkManager(url, args) {
|
||||
this.url = url;
|
||||
args = args || {};
|
||||
this.isHttp = /^https?:/i.test(url);
|
||||
this.httpHeaders = (this.isHttp && args.httpHeaders) || {};
|
||||
this.withCredentials = args.withCredentials || false;
|
||||
this.getXhr = args.getXhr ||
|
||||
function NetworkManager_getXhr() {
|
||||
return new XMLHttpRequest();
|
||||
};
|
||||
|
||||
this.currXhrId = 0;
|
||||
this.pendingRequests = Object.create(null);
|
||||
this.loadedRequests = Object.create(null);
|
||||
}
|
||||
const OK_RESPONSE = 200;
|
||||
const PARTIAL_CONTENT_RESPONSE = 206;
|
||||
|
||||
function getArrayBuffer(xhr) {
|
||||
var data = xhr.response;
|
||||
@ -59,27 +43,43 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||
return array.buffer;
|
||||
}
|
||||
|
||||
NetworkManager.prototype = {
|
||||
requestRange: function NetworkManager_requestRange(begin, end, listeners) {
|
||||
class NetworkManagerClass {
|
||||
constructor(url, args) {
|
||||
this.url = url;
|
||||
args = args || {};
|
||||
this.isHttp = /^https?:/i.test(url);
|
||||
this.httpHeaders = (this.isHttp && args.httpHeaders) || {};
|
||||
this.withCredentials = args.withCredentials || false;
|
||||
this.getXhr = args.getXhr ||
|
||||
function NetworkManager_getXhr() {
|
||||
return new XMLHttpRequest();
|
||||
};
|
||||
|
||||
this.currXhrId = 0;
|
||||
this.pendingRequests = Object.create(null);
|
||||
this.loadedRequests = Object.create(null);
|
||||
}
|
||||
|
||||
requestRange(begin, end, listeners) {
|
||||
var args = {
|
||||
begin: begin,
|
||||
end: end
|
||||
begin,
|
||||
end,
|
||||
};
|
||||
for (var prop in listeners) {
|
||||
args[prop] = listeners[prop];
|
||||
}
|
||||
return this.request(args);
|
||||
},
|
||||
}
|
||||
|
||||
requestFull: function NetworkManager_requestFull(listeners) {
|
||||
requestFull(listeners) {
|
||||
return this.request(listeners);
|
||||
},
|
||||
}
|
||||
|
||||
request: function NetworkManager_request(args) {
|
||||
request(args) {
|
||||
var xhr = this.getXhr();
|
||||
var xhrId = this.currXhrId++;
|
||||
var pendingRequest = this.pendingRequests[xhrId] = {
|
||||
xhr: xhr
|
||||
xhr,
|
||||
};
|
||||
|
||||
xhr.open('GET', this.url);
|
||||
@ -124,9 +124,9 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||
xhr.send(null);
|
||||
|
||||
return xhrId;
|
||||
},
|
||||
}
|
||||
|
||||
onProgress: function NetworkManager_onProgress(xhrId, evt) {
|
||||
onProgress(xhrId, evt) {
|
||||
var pendingRequest = this.pendingRequests[xhrId];
|
||||
if (!pendingRequest) {
|
||||
// Maybe abortRequest was called...
|
||||
@ -142,9 +142,9 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||
if (onProgress) {
|
||||
onProgress(evt);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
onStateChange: function NetworkManager_onStateChange(xhrId, evt) {
|
||||
onStateChange(xhrId, evt) {
|
||||
var pendingRequest = this.pendingRequests[xhrId];
|
||||
if (!pendingRequest) {
|
||||
// Maybe abortRequest was called...
|
||||
@ -201,57 +201,57 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||
var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader);
|
||||
var begin = parseInt(matches[1], 10);
|
||||
pendingRequest.onDone({
|
||||
begin: begin,
|
||||
chunk: chunk
|
||||
begin,
|
||||
chunk,
|
||||
});
|
||||
} else if (pendingRequest.onProgressiveData) {
|
||||
pendingRequest.onDone(null);
|
||||
} else if (chunk) {
|
||||
pendingRequest.onDone({
|
||||
begin: 0,
|
||||
chunk: chunk
|
||||
chunk,
|
||||
});
|
||||
} else if (pendingRequest.onError) {
|
||||
pendingRequest.onError(xhr.status);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
hasPendingRequests: function NetworkManager_hasPendingRequests() {
|
||||
hasPendingRequests() {
|
||||
for (var xhrId in this.pendingRequests) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
}
|
||||
|
||||
getRequestXhr: function NetworkManager_getXhr(xhrId) {
|
||||
getRequestXhr(xhrId) {
|
||||
return this.pendingRequests[xhrId].xhr;
|
||||
},
|
||||
}
|
||||
|
||||
isStreamingRequest: function NetworkManager_isStreamingRequest(xhrId) {
|
||||
isStreamingRequest(xhrId) {
|
||||
return !!(this.pendingRequests[xhrId].onProgressiveData);
|
||||
},
|
||||
}
|
||||
|
||||
isPendingRequest: function NetworkManager_isPendingRequest(xhrId) {
|
||||
isPendingRequest(xhrId) {
|
||||
return xhrId in this.pendingRequests;
|
||||
},
|
||||
}
|
||||
|
||||
isLoadedRequest: function NetworkManager_isLoadedRequest(xhrId) {
|
||||
isLoadedRequest(xhrId) {
|
||||
return xhrId in this.loadedRequests;
|
||||
},
|
||||
}
|
||||
|
||||
abortAllRequests: function NetworkManager_abortAllRequests() {
|
||||
abortAllRequests() {
|
||||
for (var xhrId in this.pendingRequests) {
|
||||
this.abortRequest(xhrId | 0);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
abortRequest: function NetworkManager_abortRequest(xhrId) {
|
||||
abortRequest(xhrId) {
|
||||
var xhr = this.pendingRequests[xhrId].xhr;
|
||||
delete this.pendingRequests[xhrId];
|
||||
xhr.abort();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return NetworkManager;
|
||||
return NetworkManagerClass;
|
||||
})();
|
||||
|
||||
|
@ -23,47 +23,47 @@ const Cu = Components.utils;
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
this.PdfJsTelemetry = {
|
||||
onViewerIsUsed: function () {
|
||||
onViewerIsUsed() {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_USED');
|
||||
histogram.add(true);
|
||||
},
|
||||
onFallback: function () {
|
||||
onFallback() {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FALLBACK_SHOWN');
|
||||
histogram.add(true);
|
||||
},
|
||||
onDocumentSize: function (size) {
|
||||
onDocumentSize(size) {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_SIZE_KB');
|
||||
histogram.add(size / 1024);
|
||||
},
|
||||
onDocumentVersion: function (versionId) {
|
||||
onDocumentVersion(versionId) {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_VERSION');
|
||||
histogram.add(versionId);
|
||||
},
|
||||
onDocumentGenerator: function (generatorId) {
|
||||
onDocumentGenerator(generatorId) {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_DOCUMENT_GENERATOR');
|
||||
histogram.add(generatorId);
|
||||
},
|
||||
onEmbed: function (isObject) {
|
||||
onEmbed(isObject) {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_EMBED');
|
||||
histogram.add(isObject);
|
||||
},
|
||||
onFontType: function (fontTypeId) {
|
||||
onFontType(fontTypeId) {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FONT_TYPES');
|
||||
histogram.add(fontTypeId);
|
||||
},
|
||||
onForm: function (isAcroform) {
|
||||
onForm(isAcroform) {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_FORM');
|
||||
histogram.add(isAcroform);
|
||||
},
|
||||
onPrint: function () {
|
||||
onPrint() {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_PRINT');
|
||||
histogram.add(true);
|
||||
},
|
||||
onStreamType: function (streamTypeId) {
|
||||
onStreamType(streamTypeId) {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_STREAM_TYPES');
|
||||
histogram.add(streamTypeId);
|
||||
},
|
||||
onTimeToView: function (ms) {
|
||||
onTimeToView(ms) {
|
||||
let histogram = Services.telemetry.getHistogramById('PDF_VIEWER_TIME_TO_VIEW_MS');
|
||||
histogram.add(ms);
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ PdfDataListener.prototype = {
|
||||
this.oncompleteCallback(null, errorCode);
|
||||
}
|
||||
},
|
||||
onprogress: function() {},
|
||||
onprogress() {},
|
||||
get oncomplete() {
|
||||
return this.oncompleteCallback;
|
||||
},
|
||||
@ -205,24 +205,27 @@ PdfDataListener.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
// All the priviledged actions.
|
||||
function ChromeActions(domWindow, contentDispositionFilename) {
|
||||
this.domWindow = domWindow;
|
||||
this.contentDispositionFilename = contentDispositionFilename;
|
||||
this.telemetryState = {
|
||||
documentInfo: false,
|
||||
firstPageInfo: false,
|
||||
streamTypesUsed: [],
|
||||
fontTypesUsed: [],
|
||||
startAt: Date.now()
|
||||
};
|
||||
}
|
||||
/**
|
||||
* All the privileged actions.
|
||||
*/
|
||||
class ChromeActions {
|
||||
constructor(domWindow, contentDispositionFilename) {
|
||||
this.domWindow = domWindow;
|
||||
this.contentDispositionFilename = contentDispositionFilename;
|
||||
this.telemetryState = {
|
||||
documentInfo: false,
|
||||
firstPageInfo: false,
|
||||
streamTypesUsed: [],
|
||||
fontTypesUsed: [],
|
||||
startAt: Date.now()
|
||||
};
|
||||
}
|
||||
|
||||
ChromeActions.prototype = {
|
||||
isInPrivateBrowsing: function() {
|
||||
isInPrivateBrowsing() {
|
||||
return PrivateBrowsingUtils.isContentWindowPrivate(this.domWindow);
|
||||
},
|
||||
download: function(data, sendResponse) {
|
||||
}
|
||||
|
||||
download(data, sendResponse) {
|
||||
var self = this;
|
||||
var originalUrl = data.originalUrl;
|
||||
var blobUrl = data.blobUrl || originalUrl;
|
||||
@ -279,7 +282,7 @@ ChromeActions.prototype = {
|
||||
|
||||
var listener = {
|
||||
extListener: null,
|
||||
onStartRequest: function(aRequest, aContext) {
|
||||
onStartRequest(aRequest, aContext) {
|
||||
var loadContext = self.domWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
@ -290,7 +293,7 @@ ChromeActions.prototype = {
|
||||
aRequest, loadContext, false);
|
||||
this.extListener.onStartRequest(aRequest, aContext);
|
||||
},
|
||||
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||
onStopRequest(aRequest, aContext, aStatusCode) {
|
||||
if (this.extListener) {
|
||||
this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
|
||||
}
|
||||
@ -299,20 +302,21 @@ ChromeActions.prototype = {
|
||||
sendResponse(false);
|
||||
}
|
||||
},
|
||||
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset,
|
||||
aCount) {
|
||||
this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
|
||||
onDataAvailable(aRequest, aContext, aDataInputStream, aOffset, aCount) {
|
||||
this.extListener.onDataAvailable(aRequest, aContext, aDataInputStream,
|
||||
aOffset, aCount);
|
||||
}
|
||||
};
|
||||
|
||||
channel.asyncOpen2(listener);
|
||||
});
|
||||
},
|
||||
getLocale: function() {
|
||||
}
|
||||
|
||||
getLocale() {
|
||||
return getStringPref('general.useragent.locale', 'en-US');
|
||||
},
|
||||
getStrings: function(data) {
|
||||
}
|
||||
|
||||
getStrings(data) {
|
||||
try {
|
||||
// Lazy initialization of localizedStrings
|
||||
if (!('localizedStrings' in this)) {
|
||||
@ -324,8 +328,9 @@ ChromeActions.prototype = {
|
||||
log('Unable to retrieve localized strings: ' + e);
|
||||
return 'null';
|
||||
}
|
||||
},
|
||||
supportsIntegratedFind: function() {
|
||||
}
|
||||
|
||||
supportsIntegratedFind() {
|
||||
// Integrated find is only supported when we're not in a frame
|
||||
if (this.domWindow.frameElement !== null) {
|
||||
return false;
|
||||
@ -339,22 +344,26 @@ ChromeActions.prototype = {
|
||||
// ... or when the new find events code exists.
|
||||
var findBar = getFindBar(this.domWindow);
|
||||
return !!findBar && ('updateControlState' in findBar);
|
||||
},
|
||||
supportsDocumentFonts: function() {
|
||||
}
|
||||
|
||||
supportsDocumentFonts() {
|
||||
var prefBrowser = getIntPref('browser.display.use_document_fonts', 1);
|
||||
var prefGfx = getBoolPref('gfx.downloadable_fonts.enabled', true);
|
||||
return (!!prefBrowser && prefGfx);
|
||||
},
|
||||
supportsDocumentColors: function() {
|
||||
}
|
||||
|
||||
supportsDocumentColors() {
|
||||
return getIntPref('browser.display.document_color_use', 0) !== 2;
|
||||
},
|
||||
supportedMouseWheelZoomModifierKeys: function() {
|
||||
}
|
||||
|
||||
supportedMouseWheelZoomModifierKeys() {
|
||||
return {
|
||||
ctrlKey: getIntPref('mousewheel.with_control.action', 3) === 3,
|
||||
metaKey: getIntPref('mousewheel.with_meta.action', 1) === 3,
|
||||
};
|
||||
},
|
||||
reportTelemetry: function (data) {
|
||||
}
|
||||
|
||||
reportTelemetry(data) {
|
||||
var probeInfo = JSON.parse(data);
|
||||
switch (probeInfo.type) {
|
||||
case 'documentInfo':
|
||||
@ -409,12 +418,15 @@ ChromeActions.prototype = {
|
||||
PdfJsTelemetry.onPrint();
|
||||
break;
|
||||
}
|
||||
},
|
||||
fallback: function(args, sendResponse) {
|
||||
var featureId = args.featureId;
|
||||
var url = args.url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} args - Object with `featureId` and `url` properties.
|
||||
* @param {function} sendResponse - Callback function.
|
||||
*/
|
||||
fallback(args, sendResponse) {
|
||||
var featureId = args.featureId;
|
||||
|
||||
var self = this;
|
||||
var domWindow = this.domWindow;
|
||||
var strings = getLocalizedStrings('chrome.properties');
|
||||
var message;
|
||||
@ -441,8 +453,9 @@ ChromeActions.prototype = {
|
||||
winmm.removeMessageListener('PDFJS:Child:fallbackDownload',
|
||||
fallbackDownload);
|
||||
});
|
||||
},
|
||||
updateFindControlState: function(data) {
|
||||
}
|
||||
|
||||
updateFindControlState(data) {
|
||||
if (!this.supportsIntegratedFind()) {
|
||||
return;
|
||||
}
|
||||
@ -461,8 +474,9 @@ ChromeActions.prototype = {
|
||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
|
||||
winmm.sendAsyncMessage('PDFJS:Parent:updateControlState', data);
|
||||
},
|
||||
setPreferences: function(prefs, sendResponse) {
|
||||
}
|
||||
|
||||
setPreferences(prefs, sendResponse) {
|
||||
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
|
||||
var numberOfPrefs = 0;
|
||||
var prefValue, prefName;
|
||||
@ -496,8 +510,9 @@ ChromeActions.prototype = {
|
||||
if (sendResponse) {
|
||||
sendResponse(true);
|
||||
}
|
||||
},
|
||||
getPreferences: function(prefs, sendResponse) {
|
||||
}
|
||||
|
||||
getPreferences(prefs, sendResponse) {
|
||||
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
|
||||
var currentPrefs = {}, numberOfPrefs = 0;
|
||||
var prefValue, prefName;
|
||||
@ -529,17 +544,16 @@ ChromeActions.prototype = {
|
||||
return JSON.stringify(currentPrefs);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var RangedChromeActions = (function RangedChromeActionsClosure() {
|
||||
/**
|
||||
* This is for range requests
|
||||
*/
|
||||
function RangedChromeActions(
|
||||
domWindow, contentDispositionFilename, originalRequest,
|
||||
/**
|
||||
* This is for range requests.
|
||||
*/
|
||||
class RangedChromeActions extends ChromeActions {
|
||||
constructor(domWindow, contentDispositionFilename, originalRequest,
|
||||
rangeEnabled, streamingEnabled, dataListener) {
|
||||
|
||||
ChromeActions.call(this, domWindow, contentDispositionFilename);
|
||||
super(domWindow, contentDispositionFilename);
|
||||
this.dataListener = dataListener;
|
||||
this.originalRequest = originalRequest;
|
||||
this.rangeEnabled = rangeEnabled;
|
||||
@ -551,7 +565,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
|
||||
// Pass all the headers from the original request through
|
||||
var httpHeaderVisitor = {
|
||||
headers: {},
|
||||
visitHeader: function(aHeader, aValue) {
|
||||
visitHeader(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
|
||||
@ -587,7 +601,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
|
||||
|
||||
this.networkManager = new NetworkManager(this.pdfUrl, {
|
||||
httpHeaders: httpHeaderVisitor.headers,
|
||||
getXhr: getXhr
|
||||
getXhr,
|
||||
});
|
||||
|
||||
// If we are in range request mode, this means we manually issued xhr
|
||||
@ -598,12 +612,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
|
||||
});
|
||||
}
|
||||
|
||||
RangedChromeActions.prototype = Object.create(ChromeActions.prototype);
|
||||
var proto = RangedChromeActions.prototype;
|
||||
proto.constructor = RangedChromeActions;
|
||||
|
||||
proto.initPassiveLoading = function RangedChromeActions_initPassiveLoading() {
|
||||
var self = this;
|
||||
initPassiveLoading() {
|
||||
var data;
|
||||
if (!this.streamingEnabled) {
|
||||
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
@ -613,16 +622,16 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
|
||||
} else {
|
||||
data = this.dataListener.readData();
|
||||
|
||||
this.dataListener.onprogress = function (loaded, total) {
|
||||
self.domWindow.postMessage({
|
||||
this.dataListener.onprogress = (loaded, total) => {
|
||||
this.domWindow.postMessage({
|
||||
pdfjsLoadAction: 'progressiveRead',
|
||||
loaded: loaded,
|
||||
total: total,
|
||||
chunk: self.dataListener.readData()
|
||||
loaded,
|
||||
total,
|
||||
chunk: this.dataListener.readData(),
|
||||
}, '*');
|
||||
};
|
||||
this.dataListener.oncomplete = function () {
|
||||
self.dataListener = null;
|
||||
this.dataListener.oncomplete = () => {
|
||||
this.dataListener = null;
|
||||
};
|
||||
}
|
||||
|
||||
@ -632,13 +641,13 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
|
||||
streamingEnabled: this.streamingEnabled,
|
||||
pdfUrl: this.pdfUrl,
|
||||
length: this.contentLength,
|
||||
data: data
|
||||
data,
|
||||
}, '*');
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
proto.requestDataRange = function RangedChromeActions_requestDataRange(args) {
|
||||
requestDataRange(args) {
|
||||
if (!this.rangeEnabled) {
|
||||
return;
|
||||
}
|
||||
@ -650,11 +659,11 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
|
||||
// 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) {
|
||||
onDone: function RangedChromeActions_onDone(aArgs) {
|
||||
domWindow.postMessage({
|
||||
pdfjsLoadAction: 'range',
|
||||
begin: args.begin,
|
||||
chunk: args.chunk
|
||||
begin: aArgs.begin,
|
||||
chunk: aArgs.chunk,
|
||||
}, '*');
|
||||
},
|
||||
onProgress: function RangedChromeActions_onProgress(evt) {
|
||||
@ -664,162 +673,155 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
|
||||
}, '*');
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
proto.abortLoading = function RangedChromeActions_abortLoading() {
|
||||
abortLoading() {
|
||||
this.networkManager.abortAllRequests();
|
||||
if (this.originalRequest) {
|
||||
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
this.originalRequest = null;
|
||||
}
|
||||
this.dataListener = null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return RangedChromeActions;
|
||||
})();
|
||||
|
||||
var StandardChromeActions = (function StandardChromeActionsClosure() {
|
||||
|
||||
/**
|
||||
* This is for a single network stream
|
||||
*/
|
||||
function StandardChromeActions(domWindow, contentDispositionFilename,
|
||||
originalRequest, dataListener) {
|
||||
|
||||
ChromeActions.call(this, domWindow, contentDispositionFilename);
|
||||
/**
|
||||
* This is for a single network stream.
|
||||
*/
|
||||
class StandardChromeActions extends ChromeActions {
|
||||
constructor(domWindow, contentDispositionFilename, originalRequest,
|
||||
dataListener) {
|
||||
super(domWindow, contentDispositionFilename);
|
||||
this.originalRequest = originalRequest;
|
||||
this.dataListener = dataListener;
|
||||
}
|
||||
|
||||
StandardChromeActions.prototype = Object.create(ChromeActions.prototype);
|
||||
var proto = StandardChromeActions.prototype;
|
||||
proto.constructor = StandardChromeActions;
|
||||
|
||||
proto.initPassiveLoading =
|
||||
function StandardChromeActions_initPassiveLoading() {
|
||||
|
||||
initPassiveLoading() {
|
||||
if (!this.dataListener) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
this.dataListener.onprogress = function ChromeActions_dataListenerProgress(
|
||||
loaded, total) {
|
||||
self.domWindow.postMessage({
|
||||
this.dataListener.onprogress = (loaded, total) => {
|
||||
this.domWindow.postMessage({
|
||||
pdfjsLoadAction: 'progress',
|
||||
loaded: loaded,
|
||||
total: total
|
||||
loaded,
|
||||
total,
|
||||
}, '*');
|
||||
};
|
||||
|
||||
this.dataListener.oncomplete =
|
||||
function StandardChromeActions_dataListenerComplete(data, errorCode) {
|
||||
self.domWindow.postMessage({
|
||||
this.dataListener.oncomplete = (data, errorCode) => {
|
||||
this.domWindow.postMessage({
|
||||
pdfjsLoadAction: 'complete',
|
||||
data: data,
|
||||
errorCode: errorCode
|
||||
data,
|
||||
errorCode,
|
||||
}, '*');
|
||||
|
||||
self.dataListener = null;
|
||||
self.originalRequest = null;
|
||||
this.dataListener = null;
|
||||
this.originalRequest = null;
|
||||
};
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
proto.abortLoading = function StandardChromeActions_abortLoading() {
|
||||
abortLoading() {
|
||||
if (this.originalRequest) {
|
||||
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
this.originalRequest = null;
|
||||
}
|
||||
this.dataListener = null;
|
||||
};
|
||||
|
||||
return StandardChromeActions;
|
||||
})();
|
||||
|
||||
// Event listener to trigger chrome privileged code.
|
||||
function RequestListener(actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
// Receive an event and synchronously or asynchronously responds.
|
||||
RequestListener.prototype.receive = function(event) {
|
||||
var message = event.target;
|
||||
var doc = message.ownerDocument;
|
||||
var action = event.detail.action;
|
||||
var data = event.detail.data;
|
||||
var sync = event.detail.sync;
|
||||
var actions = this.actions;
|
||||
if (!(action in actions)) {
|
||||
log('Unknown action: ' + action);
|
||||
return;
|
||||
}
|
||||
var response;
|
||||
if (sync) {
|
||||
response = actions[action].call(this.actions, data);
|
||||
event.detail.response = Cu.cloneInto(response, doc.defaultView);
|
||||
} else {
|
||||
if (!event.detail.responseExpected) {
|
||||
doc.documentElement.removeChild(message);
|
||||
response = null;
|
||||
} else {
|
||||
response = function sendResponse(response) {
|
||||
try {
|
||||
var listener = doc.createEvent('CustomEvent');
|
||||
let detail = Cu.cloneInto({ response: response }, doc.defaultView);
|
||||
listener.initCustomEvent('pdf.js.response', true, false, detail);
|
||||
return message.dispatchEvent(listener);
|
||||
} catch (e) {
|
||||
// doc is no longer accessible because the requestor is already
|
||||
// gone. unloaded content cannot receive the response anyway.
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Event listener to trigger chrome privileged code.
|
||||
*/
|
||||
class RequestListener {
|
||||
constructor(actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
// Receive an event and synchronously or asynchronously responds.
|
||||
receive(event) {
|
||||
var message = event.target;
|
||||
var doc = message.ownerDocument;
|
||||
var action = event.detail.action;
|
||||
var data = event.detail.data;
|
||||
var sync = event.detail.sync;
|
||||
var actions = this.actions;
|
||||
if (!(action in actions)) {
|
||||
log('Unknown action: ' + action);
|
||||
return;
|
||||
}
|
||||
var response;
|
||||
if (sync) {
|
||||
response = actions[action].call(this.actions, data);
|
||||
event.detail.response = Cu.cloneInto(response, doc.defaultView);
|
||||
} else {
|
||||
if (!event.detail.responseExpected) {
|
||||
doc.documentElement.removeChild(message);
|
||||
response = null;
|
||||
} else {
|
||||
response = function sendResponse(aResponse) {
|
||||
try {
|
||||
var listener = doc.createEvent('CustomEvent');
|
||||
let detail = Cu.cloneInto({ response: aResponse }, doc.defaultView);
|
||||
listener.initCustomEvent('pdf.js.response', true, false, detail);
|
||||
return message.dispatchEvent(listener);
|
||||
} catch (e) {
|
||||
// doc is no longer accessible because the requestor is already
|
||||
// gone. unloaded content cannot receive the response anyway.
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
actions[action].call(this.actions, data, response);
|
||||
}
|
||||
actions[action].call(this.actions, data, response);
|
||||
}
|
||||
};
|
||||
|
||||
// Forwards events from the eventElement to the contentWindow only if the
|
||||
// content window matches the currently selected browser window.
|
||||
function FindEventManager(contentWindow) {
|
||||
this.contentWindow = contentWindow;
|
||||
this.winmm = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
}
|
||||
|
||||
FindEventManager.prototype.bind = function() {
|
||||
var unload = function(e) {
|
||||
this.unbind();
|
||||
this.contentWindow.removeEventListener(e.type, unload);
|
||||
}.bind(this);
|
||||
this.contentWindow.addEventListener('unload', unload);
|
||||
/**
|
||||
* Forwards events from the eventElement to the contentWindow only if the
|
||||
* content window matches the currently selected browser window.
|
||||
*/
|
||||
class FindEventManager {
|
||||
constructor(contentWindow) {
|
||||
this.contentWindow = contentWindow;
|
||||
this.winmm = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
}
|
||||
|
||||
// We cannot directly attach listeners to for the find events
|
||||
// since the FindBar is in the parent process. Instead we're
|
||||
// asking the PdfjsChromeUtils to do it for us and forward
|
||||
// all the find events to us.
|
||||
this.winmm.sendAsyncMessage('PDFJS:Parent:addEventListener');
|
||||
this.winmm.addMessageListener('PDFJS:Child:handleEvent', this);
|
||||
};
|
||||
bind() {
|
||||
var unload = function(e) {
|
||||
this.unbind();
|
||||
this.contentWindow.removeEventListener(e.type, unload);
|
||||
}.bind(this);
|
||||
this.contentWindow.addEventListener('unload', unload);
|
||||
|
||||
FindEventManager.prototype.receiveMessage = function(msg) {
|
||||
var detail = msg.data.detail;
|
||||
var type = msg.data.type;
|
||||
var contentWindow = this.contentWindow;
|
||||
// We cannot directly attach listeners to for the find events
|
||||
// since the FindBar is in the parent process. Instead we're
|
||||
// asking the PdfjsChromeUtils to do it for us and forward
|
||||
// all the find events to us.
|
||||
this.winmm.sendAsyncMessage('PDFJS:Parent:addEventListener');
|
||||
this.winmm.addMessageListener('PDFJS:Child:handleEvent', this);
|
||||
}
|
||||
|
||||
detail = Cu.cloneInto(detail, contentWindow);
|
||||
var forward = contentWindow.document.createEvent('CustomEvent');
|
||||
forward.initCustomEvent(type, true, true, detail);
|
||||
contentWindow.dispatchEvent(forward);
|
||||
};
|
||||
receiveMessage(msg) {
|
||||
var detail = msg.data.detail;
|
||||
var type = msg.data.type;
|
||||
var contentWindow = this.contentWindow;
|
||||
|
||||
FindEventManager.prototype.unbind = function() {
|
||||
this.winmm.sendAsyncMessage('PDFJS:Parent:removeEventListener');
|
||||
};
|
||||
detail = Cu.cloneInto(detail, contentWindow);
|
||||
var forward = contentWindow.document.createEvent('CustomEvent');
|
||||
forward.initCustomEvent(type, true, true, detail);
|
||||
contentWindow.dispatchEvent(forward);
|
||||
}
|
||||
|
||||
unbind() {
|
||||
this.winmm.sendAsyncMessage('PDFJS:Parent:removeEventListener');
|
||||
}
|
||||
}
|
||||
|
||||
function PdfStreamConverter() {
|
||||
}
|
||||
@ -858,18 +860,18 @@ PdfStreamConverter.prototype = {
|
||||
*/
|
||||
|
||||
// nsIStreamConverter::convert
|
||||
convert: function(aFromStream, aFromType, aToType, aCtxt) {
|
||||
convert(aFromStream, aFromType, aToType, aCtxt) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
// nsIStreamConverter::asyncConvertData
|
||||
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
||||
asyncConvertData(aFromType, aToType, aListener, aCtxt) {
|
||||
// Store the listener passed to us
|
||||
this.listener = aListener;
|
||||
},
|
||||
|
||||
// nsIStreamListener::onDataAvailable
|
||||
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
|
||||
onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) {
|
||||
if (!this.dataListener) {
|
||||
return;
|
||||
}
|
||||
@ -881,7 +883,7 @@ PdfStreamConverter.prototype = {
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStartRequest
|
||||
onStartRequest: function(aRequest, aContext) {
|
||||
onStartRequest(aRequest, aContext) {
|
||||
// Setup the request so we can use it below.
|
||||
var isHttpRequest = false;
|
||||
try {
|
||||
@ -960,14 +962,14 @@ PdfStreamConverter.prototype = {
|
||||
// request(aRequest) below so we don't overwrite the original channel and
|
||||
// trigger an assertion.
|
||||
var proxy = {
|
||||
onStartRequest: function(request, context) {
|
||||
onStartRequest(request, context) {
|
||||
listener.onStartRequest(aRequest, aContext);
|
||||
},
|
||||
onDataAvailable: function(request, context, inputStream, offset, count) {
|
||||
onDataAvailable(request, context, inputStream, offset, count) {
|
||||
listener.onDataAvailable(aRequest, aContext, inputStream,
|
||||
offset, count);
|
||||
},
|
||||
onStopRequest: function(request, context, statusCode) {
|
||||
onStopRequest(request, context, statusCode) {
|
||||
// We get the DOM window here instead of before the request since it
|
||||
// may have changed during a redirect.
|
||||
var domWindow = getDOMWindow(channel);
|
||||
@ -1017,7 +1019,7 @@ PdfStreamConverter.prototype = {
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStopRequest
|
||||
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||
onStopRequest(aRequest, aContext, aStatusCode) {
|
||||
if (!this.dataListener) {
|
||||
// Do nothing
|
||||
return;
|
||||
|
@ -67,7 +67,7 @@ var PdfjsChromeUtils = {
|
||||
* Public API
|
||||
*/
|
||||
|
||||
init: function () {
|
||||
init() {
|
||||
this._browsers = new WeakSet();
|
||||
if (!this._ppmm) {
|
||||
// global parent process message manager (PPMM)
|
||||
@ -94,7 +94,7 @@ var PdfjsChromeUtils = {
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
uninit() {
|
||||
if (this._ppmm) {
|
||||
this._ppmm.removeMessageListener('PDFJS:Parent:clearUserPref', this);
|
||||
this._ppmm.removeMessageListener('PDFJS:Parent:setIntPref', this);
|
||||
@ -123,7 +123,7 @@ var PdfjsChromeUtils = {
|
||||
* instruct the child to refresh its configuration and (possibly)
|
||||
* the module's registration.
|
||||
*/
|
||||
notifyChildOfSettingsChange: function () {
|
||||
notifyChildOfSettingsChange() {
|
||||
if (Services.appinfo.processType ===
|
||||
Services.appinfo.PROCESS_TYPE_DEFAULT && this._ppmm) {
|
||||
// XXX kinda bad, we want to get the parent process mm associated
|
||||
@ -139,13 +139,13 @@ var PdfjsChromeUtils = {
|
||||
* Events
|
||||
*/
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
observe(aSubject, aTopic, aData) {
|
||||
if (aTopic === 'quit-application') {
|
||||
this.uninit();
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function (aMsg) {
|
||||
receiveMessage(aMsg) {
|
||||
switch (aMsg.name) {
|
||||
case 'PDFJS:Parent:clearUserPref':
|
||||
this._clearUserPref(aMsg.data.name);
|
||||
@ -182,20 +182,20 @@ var PdfjsChromeUtils = {
|
||||
* Internal
|
||||
*/
|
||||
|
||||
_findbarFromMessage: function(aMsg) {
|
||||
_findbarFromMessage(aMsg) {
|
||||
let browser = aMsg.target;
|
||||
let tabbrowser = browser.getTabBrowser();
|
||||
let tab = tabbrowser.getTabForBrowser(browser);
|
||||
return tabbrowser.getFindBar(tab);
|
||||
},
|
||||
|
||||
_updateControlState: function (aMsg) {
|
||||
_updateControlState(aMsg) {
|
||||
let data = aMsg.data;
|
||||
this._findbarFromMessage(aMsg)
|
||||
.updateControlState(data.result, data.findPrevious);
|
||||
},
|
||||
|
||||
handleEvent: function(aEvent) {
|
||||
handleEvent(aEvent) {
|
||||
// To avoid forwarding the message as a CPOW, create a structured cloneable
|
||||
// version of the event for both performance, and ease of usage, reasons.
|
||||
let type = aEvent.type;
|
||||
@ -213,8 +213,7 @@ var PdfjsChromeUtils = {
|
||||
}
|
||||
// Only forward the events if the current browser is a registered browser.
|
||||
let mm = browser.messageManager;
|
||||
mm.sendAsyncMessage('PDFJS:Child:handleEvent',
|
||||
{ type: type, detail: detail });
|
||||
mm.sendAsyncMessage('PDFJS:Child:handleEvent', { type, detail, });
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
|
||||
@ -223,7 +222,7 @@ var PdfjsChromeUtils = {
|
||||
'findhighlightallchange',
|
||||
'findcasesensitivitychange'],
|
||||
|
||||
_addEventListener: function (aMsg) {
|
||||
_addEventListener(aMsg) {
|
||||
let browser = aMsg.target;
|
||||
if (this._browsers.has(browser)) {
|
||||
throw new Error('FindEventManager was bound 2nd time ' +
|
||||
@ -242,7 +241,7 @@ var PdfjsChromeUtils = {
|
||||
}
|
||||
},
|
||||
|
||||
_removeEventListener: function (aMsg) {
|
||||
_removeEventListener(aMsg) {
|
||||
let browser = aMsg.target;
|
||||
if (!this._browsers.has(browser)) {
|
||||
throw new Error('FindEventManager was unbound without binding it first.');
|
||||
@ -258,7 +257,7 @@ var PdfjsChromeUtils = {
|
||||
}
|
||||
},
|
||||
|
||||
_ensurePreferenceAllowed: function (aPrefName) {
|
||||
_ensurePreferenceAllowed(aPrefName) {
|
||||
let unPrefixedName = aPrefName.split(PREF_PREFIX + '.');
|
||||
if (unPrefixedName[0] !== '' ||
|
||||
this._allowedPrefNames.indexOf(unPrefixedName[1]) === -1) {
|
||||
@ -268,27 +267,27 @@ var PdfjsChromeUtils = {
|
||||
}
|
||||
},
|
||||
|
||||
_clearUserPref: function (aPrefName) {
|
||||
_clearUserPref(aPrefName) {
|
||||
this._ensurePreferenceAllowed(aPrefName);
|
||||
Services.prefs.clearUserPref(aPrefName);
|
||||
},
|
||||
|
||||
_setIntPref: function (aPrefName, aPrefValue) {
|
||||
_setIntPref(aPrefName, aPrefValue) {
|
||||
this._ensurePreferenceAllowed(aPrefName);
|
||||
Services.prefs.setIntPref(aPrefName, aPrefValue);
|
||||
},
|
||||
|
||||
_setBoolPref: function (aPrefName, aPrefValue) {
|
||||
_setBoolPref(aPrefName, aPrefValue) {
|
||||
this._ensurePreferenceAllowed(aPrefName);
|
||||
Services.prefs.setBoolPref(aPrefName, aPrefValue);
|
||||
},
|
||||
|
||||
_setCharPref: function (aPrefName, aPrefValue) {
|
||||
_setCharPref(aPrefName, aPrefValue) {
|
||||
this._ensurePreferenceAllowed(aPrefName);
|
||||
Services.prefs.setCharPref(aPrefName, aPrefValue);
|
||||
},
|
||||
|
||||
_setStringPref: function (aPrefName, aPrefValue) {
|
||||
_setStringPref(aPrefName, aPrefValue) {
|
||||
this._ensurePreferenceAllowed(aPrefName);
|
||||
let str = Cc['@mozilla.org/supports-string;1']
|
||||
.createInstance(Ci.nsISupportsString);
|
||||
@ -301,7 +300,7 @@ var PdfjsChromeUtils = {
|
||||
* we bounce this pdfjs enabled configuration check over to the
|
||||
* parent.
|
||||
*/
|
||||
isDefaultHandlerApp: function () {
|
||||
isDefaultHandlerApp() {
|
||||
var handlerInfo = Svc.mime.getFromTypeAndExtension(PDF_CONTENT_TYPE, 'pdf');
|
||||
return (!handlerInfo.alwaysAskBeforeHandling &&
|
||||
handlerInfo.preferredAction === Ci.nsIHandlerInfo.handleInternally);
|
||||
@ -311,7 +310,7 @@ var PdfjsChromeUtils = {
|
||||
* Display a notification warning when the renderer isn't sure
|
||||
* a pdf displayed correctly.
|
||||
*/
|
||||
_displayWarning: function (aMsg) {
|
||||
_displayWarning(aMsg) {
|
||||
let data = aMsg.data;
|
||||
let browser = aMsg.target;
|
||||
|
||||
@ -324,13 +323,12 @@ var PdfjsChromeUtils = {
|
||||
let messageSent = false;
|
||||
function sendMessage(download) {
|
||||
let mm = browser.messageManager;
|
||||
mm.sendAsyncMessage('PDFJS:Child:fallbackDownload',
|
||||
{ download: download });
|
||||
mm.sendAsyncMessage('PDFJS:Child:fallbackDownload', { download, });
|
||||
}
|
||||
let buttons = [{
|
||||
label: data.label,
|
||||
accessKey: data.accessKey,
|
||||
callback: function() {
|
||||
callback() {
|
||||
messageSent = true;
|
||||
sendMessage(true);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ var PdfjsContentUtils = {
|
||||
Services.appinfo.PROCESS_TYPE_CONTENT);
|
||||
},
|
||||
|
||||
init: function () {
|
||||
init() {
|
||||
// child *process* mm, or when loaded into the parent for in-content
|
||||
// support the psuedo child process mm 'child PPMM'.
|
||||
if (!this._mm) {
|
||||
@ -49,7 +49,7 @@ var PdfjsContentUtils = {
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
uninit() {
|
||||
if (this._mm) {
|
||||
this._mm.removeMessageListener('PDFJS:Child:refreshSettings', this);
|
||||
Services.obs.removeObserver(this, 'quit-application');
|
||||
@ -63,34 +63,34 @@ var PdfjsContentUtils = {
|
||||
* approved pdfjs prefs in chrome utils.
|
||||
*/
|
||||
|
||||
clearUserPref: function (aPrefName) {
|
||||
clearUserPref(aPrefName) {
|
||||
this._mm.sendSyncMessage('PDFJS:Parent:clearUserPref', {
|
||||
name: aPrefName
|
||||
});
|
||||
},
|
||||
|
||||
setIntPref: function (aPrefName, aPrefValue) {
|
||||
setIntPref(aPrefName, aPrefValue) {
|
||||
this._mm.sendSyncMessage('PDFJS:Parent:setIntPref', {
|
||||
name: aPrefName,
|
||||
value: aPrefValue
|
||||
});
|
||||
},
|
||||
|
||||
setBoolPref: function (aPrefName, aPrefValue) {
|
||||
setBoolPref(aPrefName, aPrefValue) {
|
||||
this._mm.sendSyncMessage('PDFJS:Parent:setBoolPref', {
|
||||
name: aPrefName,
|
||||
value: aPrefValue
|
||||
});
|
||||
},
|
||||
|
||||
setCharPref: function (aPrefName, aPrefValue) {
|
||||
setCharPref(aPrefName, aPrefValue) {
|
||||
this._mm.sendSyncMessage('PDFJS:Parent:setCharPref', {
|
||||
name: aPrefName,
|
||||
value: aPrefValue
|
||||
});
|
||||
},
|
||||
|
||||
setStringPref: function (aPrefName, aPrefValue) {
|
||||
setStringPref(aPrefName, aPrefValue) {
|
||||
this._mm.sendSyncMessage('PDFJS:Parent:setStringPref', {
|
||||
name: aPrefName,
|
||||
value: aPrefValue
|
||||
@ -101,7 +101,7 @@ var PdfjsContentUtils = {
|
||||
* Forwards default app query to the parent where we check various
|
||||
* handler app settings only available in the parent process.
|
||||
*/
|
||||
isDefaultHandlerApp: function () {
|
||||
isDefaultHandlerApp() {
|
||||
return this._mm.sendSyncMessage('PDFJS:Parent:isDefaultHandlerApp')[0];
|
||||
},
|
||||
|
||||
@ -109,7 +109,7 @@ var PdfjsContentUtils = {
|
||||
* Request the display of a notification warning in the associated window
|
||||
* when the renderer isn't sure a pdf displayed correctly.
|
||||
*/
|
||||
displayWarning: function (aWindow, aMessage, aLabel, accessKey) {
|
||||
displayWarning(aWindow, aMessage, aLabel, aAccessKey) {
|
||||
// the child's dom frame mm associated with the window.
|
||||
let winmm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
@ -118,7 +118,7 @@ var PdfjsContentUtils = {
|
||||
winmm.sendAsyncMessage('PDFJS:Parent:displayWarning', {
|
||||
message: aMessage,
|
||||
label: aLabel,
|
||||
accessKey: accessKey
|
||||
accessKey: aAccessKey,
|
||||
});
|
||||
},
|
||||
|
||||
@ -126,13 +126,13 @@ var PdfjsContentUtils = {
|
||||
* Events
|
||||
*/
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
observe(aSubject, aTopic, aData) {
|
||||
if (aTopic === 'quit-application') {
|
||||
this.uninit();
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function (aMsg) {
|
||||
receiveMessage(aMsg) {
|
||||
switch (aMsg.name) {
|
||||
case 'PDFJS:Child:refreshSettings':
|
||||
// Only react to this if we are remote.
|
||||
|
@ -23,8 +23,8 @@
|
||||
}
|
||||
}(this, function (exports) {
|
||||
'use strict';
|
||||
var pdfjsVersion = '1.6.467';
|
||||
var pdfjsBuild = '54d55e8b';
|
||||
var pdfjsVersion = '1.7.227';
|
||||
var pdfjsBuild = 'e132fa97';
|
||||
var pdfjsFilePath = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : null;
|
||||
var pdfjsLibs = {};
|
||||
(function pdfjsWrapper() {
|
||||
@ -1434,6 +1434,7 @@
|
||||
var warn = sharedUtil.warn;
|
||||
var deprecated = sharedUtil.deprecated;
|
||||
var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
|
||||
var DEFAULT_LINK_REL = 'noopener noreferrer nofollow';
|
||||
var CustomStyle = function CustomStyleClosure() {
|
||||
var prefixes = [
|
||||
'ms',
|
||||
@ -1559,7 +1560,7 @@
|
||||
globalSettings.externalLinkTarget = LinkTarget.NONE;
|
||||
return LinkTarget.NONE;
|
||||
case 'externalLinkRel':
|
||||
return globalSettings ? globalSettings.externalLinkRel : 'noreferrer';
|
||||
return globalSettings ? globalSettings.externalLinkRel : DEFAULT_LINK_REL;
|
||||
case 'enableStats':
|
||||
return !!(globalSettings && globalSettings.enableStats);
|
||||
default:
|
||||
@ -1591,6 +1592,7 @@
|
||||
exports.LinkTarget = LinkTarget;
|
||||
exports.hasCanvasTypedArrays = hasCanvasTypedArrays;
|
||||
exports.getDefaultSetting = getDefaultSetting;
|
||||
exports.DEFAULT_LINK_REL = DEFAULT_LINK_REL;
|
||||
}));
|
||||
(function (root, factory) {
|
||||
factory(root.pdfjsDisplayFontLoader = {}, root.pdfjsSharedUtil);
|
||||
@ -5084,15 +5086,13 @@
|
||||
}
|
||||
return pattern;
|
||||
},
|
||||
setStrokeColorN: function CanvasGraphics_setStrokeColorN()
|
||||
{
|
||||
this.current.strokeColor = this.getColorN_Pattern(arguments);
|
||||
},
|
||||
setFillColorN: function CanvasGraphics_setFillColorN()
|
||||
{
|
||||
this.current.fillColor = this.getColorN_Pattern(arguments);
|
||||
this.current.patternFill = true;
|
||||
},
|
||||
setStrokeColorN: function CanvasGraphics_setStrokeColorN() {
|
||||
this.current.strokeColor = this.getColorN_Pattern(arguments);
|
||||
},
|
||||
setFillColorN: function CanvasGraphics_setFillColorN() {
|
||||
this.current.fillColor = this.getColorN_Pattern(arguments);
|
||||
this.current.patternFill = true;
|
||||
},
|
||||
setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) {
|
||||
var color = Util.makeCssRgb(r, g, b);
|
||||
this.ctx.strokeStyle = color;
|
||||
@ -6824,7 +6824,7 @@
|
||||
return;
|
||||
}
|
||||
if (this.task.onContinue) {
|
||||
this.task.onContinue.call(this.task, this._scheduleNextBound);
|
||||
this.task.onContinue(this._scheduleNextBound);
|
||||
} else {
|
||||
this._scheduleNext();
|
||||
}
|
||||
@ -6886,6 +6886,7 @@
|
||||
var deprecated = sharedUtil.deprecated;
|
||||
var warn = sharedUtil.warn;
|
||||
var LinkTarget = displayDOMUtils.LinkTarget;
|
||||
var DEFAULT_LINK_REL = displayDOMUtils.DEFAULT_LINK_REL;
|
||||
var isWorker = typeof window === 'undefined';
|
||||
if (!globalScope.PDFJS) {
|
||||
globalScope.PDFJS = {};
|
||||
@ -6953,7 +6954,7 @@
|
||||
PDFJS.disableCreateObjectURL = PDFJS.disableCreateObjectURL === undefined ? false : PDFJS.disableCreateObjectURL;
|
||||
PDFJS.disableWebGL = PDFJS.disableWebGL === undefined ? true : PDFJS.disableWebGL;
|
||||
PDFJS.externalLinkTarget = PDFJS.externalLinkTarget === undefined ? LinkTarget.NONE : PDFJS.externalLinkTarget;
|
||||
PDFJS.externalLinkRel = PDFJS.externalLinkRel === undefined ? 'noreferrer' : PDFJS.externalLinkRel;
|
||||
PDFJS.externalLinkRel = PDFJS.externalLinkRel === undefined ? DEFAULT_LINK_REL : PDFJS.externalLinkRel;
|
||||
PDFJS.isEvalSupported = PDFJS.isEvalSupported === undefined ? true : PDFJS.isEvalSupported;
|
||||
PDFJS.getDocument = displayAPI.getDocument;
|
||||
PDFJS.PDFDataRangeTransport = displayAPI.PDFDataRangeTransport;
|
||||
|
@ -23,8 +23,8 @@
|
||||
}
|
||||
}(this, function (exports) {
|
||||
'use strict';
|
||||
var pdfjsVersion = '1.6.467';
|
||||
var pdfjsBuild = '54d55e8b';
|
||||
var pdfjsVersion = '1.7.227';
|
||||
var pdfjsBuild = 'e132fa97';
|
||||
var pdfjsFilePath = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : null;
|
||||
var pdfjsLibs = {};
|
||||
(function pdfjsWrapper() {
|
||||
@ -38197,7 +38197,7 @@
|
||||
var stackDelta = op <= 0x8E ? TTOpsStackDeltas[op] : op >= 0xC0 && op <= 0xDF ? -1 : op >= 0xE0 ? -2 : 0;
|
||||
if (op >= 0x71 && op <= 0x75) {
|
||||
n = stack.pop();
|
||||
if (n === n) {
|
||||
if (!isNaN(n)) {
|
||||
stackDelta = -n * 2;
|
||||
}
|
||||
}
|
||||
|
@ -1,617 +0,0 @@
|
||||
/* 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';
|
||||
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define('pdfjs/core/network', ['exports', 'pdfjs/shared/util',
|
||||
'pdfjs/core/worker'], factory);
|
||||
} else if (typeof exports !== 'undefined') {
|
||||
factory(exports, require('../shared/util.js'), require('./worker.js'));
|
||||
} else {
|
||||
factory((root.pdfjsCoreNetwork = {}), root.pdfjsSharedUtil,
|
||||
root.pdfjsCoreWorker);
|
||||
}
|
||||
}(this, function (exports, sharedUtil, coreWorker) {
|
||||
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
||||
throw new Error('Module "pdfjs/core/network" shall not ' +
|
||||
'be used with FIREFOX or MOZCENTRAL build.');
|
||||
}
|
||||
|
||||
var OK_RESPONSE = 200;
|
||||
var PARTIAL_CONTENT_RESPONSE = 206;
|
||||
|
||||
function NetworkManager(url, args) {
|
||||
this.url = url;
|
||||
args = args || {};
|
||||
this.isHttp = /^https?:/i.test(url);
|
||||
this.httpHeaders = (this.isHttp && args.httpHeaders) || {};
|
||||
this.withCredentials = args.withCredentials || false;
|
||||
this.getXhr = args.getXhr ||
|
||||
function NetworkManager_getXhr() {
|
||||
return new XMLHttpRequest();
|
||||
};
|
||||
|
||||
this.currXhrId = 0;
|
||||
this.pendingRequests = Object.create(null);
|
||||
this.loadedRequests = Object.create(null);
|
||||
}
|
||||
|
||||
function getArrayBuffer(xhr) {
|
||||
var data = xhr.response;
|
||||
if (typeof data !== 'string') {
|
||||
return data;
|
||||
}
|
||||
var length = data.length;
|
||||
var array = new Uint8Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
array[i] = data.charCodeAt(i) & 0xFF;
|
||||
}
|
||||
return array.buffer;
|
||||
}
|
||||
|
||||
var supportsMozChunked =
|
||||
typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') ? false :
|
||||
(function supportsMozChunkedClosure() {
|
||||
try {
|
||||
var x = new XMLHttpRequest();
|
||||
// Firefox 37- required .open() to be called before setting responseType.
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=707484
|
||||
// Even though the URL is not visited, .open() could fail if the URL is
|
||||
// blocked, e.g. via the connect-src CSP directive or the NoScript addon.
|
||||
// When this error occurs, this feature detection method will mistakenly
|
||||
// report that moz-chunked-arraybuffer is not supported in Firefox 37-.
|
||||
x.open('GET', 'https://example.com');
|
||||
x.responseType = 'moz-chunked-arraybuffer';
|
||||
return x.responseType === 'moz-chunked-arraybuffer';
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
|
||||
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_requestFull(listeners) {
|
||||
return this.request(listeners);
|
||||
},
|
||||
|
||||
request: function NetworkManager_request(args) {
|
||||
var xhr = this.getXhr();
|
||||
var xhrId = this.currXhrId++;
|
||||
var pendingRequest = this.pendingRequests[xhrId] = {
|
||||
xhr: xhr
|
||||
};
|
||||
|
||||
xhr.open('GET', this.url);
|
||||
xhr.withCredentials = this.withCredentials;
|
||||
for (var property in this.httpHeaders) {
|
||||
var value = this.httpHeaders[property];
|
||||
if (typeof value === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
xhr.setRequestHeader(property, value);
|
||||
}
|
||||
if (this.isHttp && '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;
|
||||
}
|
||||
|
||||
var useMozChunkedLoading = supportsMozChunked && !!args.onProgressiveData;
|
||||
if (useMozChunkedLoading) {
|
||||
xhr.responseType = 'moz-chunked-arraybuffer';
|
||||
pendingRequest.onProgressiveData = args.onProgressiveData;
|
||||
pendingRequest.mozChunked = true;
|
||||
} else {
|
||||
xhr.responseType = 'arraybuffer';
|
||||
}
|
||||
|
||||
if (args.onError) {
|
||||
xhr.onerror = function(evt) {
|
||||
args.onError(xhr.status);
|
||||
};
|
||||
}
|
||||
xhr.onreadystatechange = this.onStateChange.bind(this, xhrId);
|
||||
xhr.onprogress = this.onProgress.bind(this, xhrId);
|
||||
|
||||
pendingRequest.onHeadersReceived = args.onHeadersReceived;
|
||||
pendingRequest.onDone = args.onDone;
|
||||
pendingRequest.onError = args.onError;
|
||||
pendingRequest.onProgress = args.onProgress;
|
||||
|
||||
xhr.send(null);
|
||||
|
||||
return xhrId;
|
||||
},
|
||||
|
||||
onProgress: function NetworkManager_onProgress(xhrId, evt) {
|
||||
var pendingRequest = this.pendingRequests[xhrId];
|
||||
if (!pendingRequest) {
|
||||
// Maybe abortRequest was called...
|
||||
return;
|
||||
}
|
||||
|
||||
if (pendingRequest.mozChunked) {
|
||||
var chunk = getArrayBuffer(pendingRequest.xhr);
|
||||
pendingRequest.onProgressiveData(chunk);
|
||||
}
|
||||
|
||||
var onProgress = pendingRequest.onProgress;
|
||||
if (onProgress) {
|
||||
onProgress(evt);
|
||||
}
|
||||
},
|
||||
|
||||
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];
|
||||
|
||||
// success status == 0 can be on ftp, file and other protocols
|
||||
if (xhr.status === 0 && this.isHttp) {
|
||||
if (pendingRequest.onError) {
|
||||
pendingRequest.onError(xhr.status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var xhrStatus = xhr.status || OK_RESPONSE;
|
||||
|
||||
// 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 =
|
||||
xhrStatus === OK_RESPONSE &&
|
||||
pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE;
|
||||
|
||||
if (!ok_response_on_range_request &&
|
||||
xhrStatus !== pendingRequest.expectedStatus) {
|
||||
if (pendingRequest.onError) {
|
||||
pendingRequest.onError(xhr.status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadedRequests[xhrId] = true;
|
||||
|
||||
var chunk = getArrayBuffer(xhr);
|
||||
if (xhrStatus === 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 if (pendingRequest.onProgressiveData) {
|
||||
pendingRequest.onDone(null);
|
||||
} else if (chunk) {
|
||||
pendingRequest.onDone({
|
||||
begin: 0,
|
||||
chunk: chunk
|
||||
});
|
||||
} else if (pendingRequest.onError) {
|
||||
pendingRequest.onError(xhr.status);
|
||||
}
|
||||
},
|
||||
|
||||
hasPendingRequests: function NetworkManager_hasPendingRequests() {
|
||||
for (var xhrId in this.pendingRequests) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
getRequestXhr: function NetworkManager_getXhr(xhrId) {
|
||||
return this.pendingRequests[xhrId].xhr;
|
||||
},
|
||||
|
||||
isStreamingRequest: function NetworkManager_isStreamingRequest(xhrId) {
|
||||
return !!(this.pendingRequests[xhrId].onProgressiveData);
|
||||
},
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
var assert = sharedUtil.assert;
|
||||
var createPromiseCapability = sharedUtil.createPromiseCapability;
|
||||
var isInt = sharedUtil.isInt;
|
||||
var MissingPDFException = sharedUtil.MissingPDFException;
|
||||
var UnexpectedResponseException = sharedUtil.UnexpectedResponseException;
|
||||
|
||||
/** @implements {IPDFStream} */
|
||||
function PDFNetworkStream(options) {
|
||||
this._options = options;
|
||||
var source = options.source;
|
||||
this._manager = new NetworkManager(source.url, {
|
||||
httpHeaders: source.httpHeaders,
|
||||
withCredentials: source.withCredentials
|
||||
});
|
||||
this._rangeChunkSize = source.rangeChunkSize;
|
||||
this._fullRequestReader = null;
|
||||
this._rangeRequestReaders = [];
|
||||
}
|
||||
|
||||
PDFNetworkStream.prototype = {
|
||||
_onRangeRequestReaderClosed:
|
||||
function PDFNetworkStream_onRangeRequestReaderClosed(reader) {
|
||||
var i = this._rangeRequestReaders.indexOf(reader);
|
||||
if (i >= 0) {
|
||||
this._rangeRequestReaders.splice(i, 1);
|
||||
}
|
||||
},
|
||||
|
||||
getFullReader: function PDFNetworkStream_getFullReader() {
|
||||
assert(!this._fullRequestReader);
|
||||
this._fullRequestReader =
|
||||
new PDFNetworkStreamFullRequestReader(this._manager, this._options);
|
||||
return this._fullRequestReader;
|
||||
},
|
||||
|
||||
getRangeReader: function PDFNetworkStream_getRangeReader(begin, end) {
|
||||
var reader = new PDFNetworkStreamRangeRequestReader(this._manager,
|
||||
begin, end);
|
||||
reader.onClosed = this._onRangeRequestReaderClosed.bind(this);
|
||||
this._rangeRequestReaders.push(reader);
|
||||
return reader;
|
||||
},
|
||||
|
||||
cancelAllRequests: function PDFNetworkStream_cancelAllRequests(reason) {
|
||||
if (this._fullRequestReader) {
|
||||
this._fullRequestReader.cancel(reason);
|
||||
}
|
||||
var readers = this._rangeRequestReaders.slice(0);
|
||||
readers.forEach(function (reader) {
|
||||
reader.cancel(reason);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/** @implements {IPDFStreamReader} */
|
||||
function PDFNetworkStreamFullRequestReader(manager, options) {
|
||||
this._manager = manager;
|
||||
|
||||
var source = options.source;
|
||||
var args = {
|
||||
onHeadersReceived: this._onHeadersReceived.bind(this),
|
||||
onProgressiveData: source.disableStream ? null :
|
||||
this._onProgressiveData.bind(this),
|
||||
onDone: this._onDone.bind(this),
|
||||
onError: this._onError.bind(this),
|
||||
onProgress: this._onProgress.bind(this)
|
||||
};
|
||||
this._url = source.url;
|
||||
this._fullRequestId = manager.requestFull(args);
|
||||
this._headersReceivedCapability = createPromiseCapability();
|
||||
this._disableRange = options.disableRange || false;
|
||||
this._contentLength = source.length; // optional
|
||||
this._rangeChunkSize = source.rangeChunkSize;
|
||||
if (!this._rangeChunkSize && !this._disableRange) {
|
||||
this._disableRange = true;
|
||||
}
|
||||
|
||||
this._isStreamingSupported = false;
|
||||
this._isRangeSupported = false;
|
||||
|
||||
this._cachedChunks = [];
|
||||
this._requests = [];
|
||||
this._done = false;
|
||||
this._storedError = undefined;
|
||||
|
||||
this.onProgress = null;
|
||||
}
|
||||
|
||||
PDFNetworkStreamFullRequestReader.prototype = {
|
||||
_validateRangeRequestCapabilities: function
|
||||
PDFNetworkStreamFullRequestReader_validateRangeRequestCapabilities() {
|
||||
|
||||
if (this._disableRange) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var networkManager = this._manager;
|
||||
if (!networkManager.isHttp) {
|
||||
return false;
|
||||
}
|
||||
var fullRequestXhrId = this._fullRequestId;
|
||||
var fullRequestXhr = networkManager.getRequestXhr(fullRequestXhrId);
|
||||
if (fullRequestXhr.getResponseHeader('Accept-Ranges') !== 'bytes') {
|
||||
return false;
|
||||
}
|
||||
|
||||
var contentEncoding =
|
||||
fullRequestXhr.getResponseHeader('Content-Encoding') || 'identity';
|
||||
if (contentEncoding !== 'identity') {
|
||||
return false;
|
||||
}
|
||||
|
||||
var length = fullRequestXhr.getResponseHeader('Content-Length');
|
||||
length = parseInt(length, 10);
|
||||
if (!isInt(length)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._contentLength = length; // setting right content length
|
||||
|
||||
if (length <= 2 * this._rangeChunkSize) {
|
||||
// The file size is smaller than the size of two chunks, so it does
|
||||
// not make any sense to abort the request and retry with a range
|
||||
// request.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_onHeadersReceived:
|
||||
function PDFNetworkStreamFullRequestReader_onHeadersReceived() {
|
||||
|
||||
if (this._validateRangeRequestCapabilities()) {
|
||||
this._isRangeSupported = true;
|
||||
}
|
||||
|
||||
var networkManager = this._manager;
|
||||
var fullRequestXhrId = this._fullRequestId;
|
||||
if (networkManager.isStreamingRequest(fullRequestXhrId)) {
|
||||
// We can continue fetching when progressive loading is enabled,
|
||||
// and we don't need the autoFetch feature.
|
||||
this._isStreamingSupported = true;
|
||||
} else if (this._isRangeSupported) {
|
||||
// NOTE: by cancelling the full request, and then issuing range
|
||||
// requests, there will be an issue for sites where you can only
|
||||
// request the pdf once. However, if this is the case, then the
|
||||
// server should not be returning that it can support range
|
||||
// requests.
|
||||
networkManager.abortRequest(fullRequestXhrId);
|
||||
}
|
||||
|
||||
this._headersReceivedCapability.resolve();
|
||||
},
|
||||
|
||||
_onProgressiveData:
|
||||
function PDFNetworkStreamFullRequestReader_onProgressiveData(chunk) {
|
||||
if (this._requests.length > 0) {
|
||||
var requestCapability = this._requests.shift();
|
||||
requestCapability.resolve({value: chunk, done: false});
|
||||
} else {
|
||||
this._cachedChunks.push(chunk);
|
||||
}
|
||||
},
|
||||
|
||||
_onDone: function PDFNetworkStreamFullRequestReader_onDone(args) {
|
||||
if (args) {
|
||||
this._onProgressiveData(args.chunk);
|
||||
}
|
||||
this._done = true;
|
||||
if (this._cachedChunks.length > 0) {
|
||||
return;
|
||||
}
|
||||
this._requests.forEach(function (requestCapability) {
|
||||
requestCapability.resolve({value: undefined, done: true});
|
||||
});
|
||||
this._requests = [];
|
||||
},
|
||||
|
||||
_onError: function PDFNetworkStreamFullRequestReader_onError(status) {
|
||||
var url = this._url;
|
||||
var exception;
|
||||
if (status === 404 || status === 0 && /^file:/.test(url)) {
|
||||
exception = new MissingPDFException('Missing PDF "' + url + '".');
|
||||
} else {
|
||||
exception = new UnexpectedResponseException(
|
||||
'Unexpected server response (' + status +
|
||||
') while retrieving PDF "' + url + '".', status);
|
||||
}
|
||||
this._storedError = exception;
|
||||
this._headersReceivedCapability.reject(exception);
|
||||
this._requests.forEach(function (requestCapability) {
|
||||
requestCapability.reject(exception);
|
||||
});
|
||||
this._requests = [];
|
||||
this._cachedChunks = [];
|
||||
},
|
||||
|
||||
_onProgress: function PDFNetworkStreamFullRequestReader_onProgress(data) {
|
||||
if (this.onProgress) {
|
||||
this.onProgress({
|
||||
loaded: data.loaded,
|
||||
total: data.lengthComputable ? data.total : this._contentLength
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
get isRangeSupported() {
|
||||
return this._isRangeSupported;
|
||||
},
|
||||
|
||||
get isStreamingSupported() {
|
||||
return this._isStreamingSupported;
|
||||
},
|
||||
|
||||
get contentLength() {
|
||||
return this._contentLength;
|
||||
},
|
||||
|
||||
get headersReady() {
|
||||
return this._headersReceivedCapability.promise;
|
||||
},
|
||||
|
||||
read: function PDFNetworkStreamFullRequestReader_read() {
|
||||
if (this._storedError) {
|
||||
return Promise.reject(this._storedError);
|
||||
}
|
||||
if (this._cachedChunks.length > 0) {
|
||||
var chunk = this._cachedChunks.shift();
|
||||
return Promise.resolve(chunk);
|
||||
}
|
||||
if (this._done) {
|
||||
return Promise.resolve({value: undefined, done: true});
|
||||
}
|
||||
var requestCapability = createPromiseCapability();
|
||||
this._requests.push(requestCapability);
|
||||
return requestCapability.promise;
|
||||
},
|
||||
|
||||
cancel: function PDFNetworkStreamFullRequestReader_cancel(reason) {
|
||||
this._done = true;
|
||||
this._headersReceivedCapability.reject(reason);
|
||||
this._requests.forEach(function (requestCapability) {
|
||||
requestCapability.resolve({value: undefined, done: true});
|
||||
});
|
||||
this._requests = [];
|
||||
if (this._manager.isPendingRequest(this._fullRequestId)) {
|
||||
this._manager.abortRequest(this._fullRequestId);
|
||||
}
|
||||
this._fullRequestReader = null;
|
||||
}
|
||||
};
|
||||
|
||||
/** @implements {IPDFStreamRangeReader} */
|
||||
function PDFNetworkStreamRangeRequestReader(manager, begin, end) {
|
||||
this._manager = manager;
|
||||
var args = {
|
||||
onDone: this._onDone.bind(this),
|
||||
onProgress: this._onProgress.bind(this)
|
||||
};
|
||||
this._requestId = manager.requestRange(begin, end, args);
|
||||
this._requests = [];
|
||||
this._queuedChunk = null;
|
||||
this._done = false;
|
||||
|
||||
this.onProgress = null;
|
||||
this.onClosed = null;
|
||||
}
|
||||
|
||||
PDFNetworkStreamRangeRequestReader.prototype = {
|
||||
_close: function PDFNetworkStreamRangeRequestReader_close() {
|
||||
if (this.onClosed) {
|
||||
this.onClosed(this);
|
||||
}
|
||||
},
|
||||
|
||||
_onDone: function PDFNetworkStreamRangeRequestReader_onDone(data) {
|
||||
var chunk = data.chunk;
|
||||
if (this._requests.length > 0) {
|
||||
var requestCapability = this._requests.shift();
|
||||
requestCapability.resolve({value: chunk, done: false});
|
||||
} else {
|
||||
this._queuedChunk = chunk;
|
||||
}
|
||||
this._done = true;
|
||||
this._requests.forEach(function (requestCapability) {
|
||||
requestCapability.resolve({value: undefined, done: true});
|
||||
});
|
||||
this._requests = [];
|
||||
this._close();
|
||||
},
|
||||
|
||||
_onProgress: function PDFNetworkStreamRangeRequestReader_onProgress(evt) {
|
||||
if (!this.isStreamingSupported && this.onProgress) {
|
||||
this.onProgress({
|
||||
loaded: evt.loaded
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
get isStreamingSupported() {
|
||||
return false; // TODO allow progressive range bytes loading
|
||||
},
|
||||
|
||||
read: function PDFNetworkStreamRangeRequestReader_read() {
|
||||
if (this._queuedChunk !== null) {
|
||||
var chunk = this._queuedChunk;
|
||||
this._queuedChunk = null;
|
||||
return Promise.resolve({value: chunk, done: false});
|
||||
}
|
||||
if (this._done) {
|
||||
return Promise.resolve({value: undefined, done: true});
|
||||
}
|
||||
var requestCapability = createPromiseCapability();
|
||||
this._requests.push(requestCapability);
|
||||
return requestCapability.promise;
|
||||
},
|
||||
|
||||
cancel: function PDFNetworkStreamRangeRequestReader_cancel(reason) {
|
||||
this._done = true;
|
||||
this._requests.forEach(function (requestCapability) {
|
||||
requestCapability.resolve({value: undefined, done: true});
|
||||
});
|
||||
this._requests = [];
|
||||
if (this._manager.isPendingRequest(this._requestId)) {
|
||||
this._manager.abortRequest(this._requestId);
|
||||
}
|
||||
this._close();
|
||||
}
|
||||
};
|
||||
|
||||
coreWorker.setPDFNetworkStreamClass(PDFNetworkStream);
|
||||
|
||||
exports.PDFNetworkStream = PDFNetworkStream;
|
||||
exports.NetworkManager = NetworkManager;
|
||||
}));
|
||||
|
@ -121,12 +121,12 @@
|
||||
get: translateString,
|
||||
|
||||
// get the document language
|
||||
getLanguage: function() {
|
||||
getLanguage() {
|
||||
return gLanguage;
|
||||
},
|
||||
|
||||
// get the direction (ltr|rtl) of the current language
|
||||
getDirection: function() {
|
||||
getDirection() {
|
||||
// http://www.w3.org/International/questions/qa-scripts
|
||||
// Arabic, Hebrew, Farsi, Pashto, Urdu
|
||||
var rtlList = ['ar', 'he', 'fa', 'ps', 'ur'];
|
||||
@ -137,9 +137,11 @@
|
||||
return (rtlList.indexOf(shortCode) >= 0) ? 'rtl' : 'ltr';
|
||||
},
|
||||
|
||||
getReadyState: function() { return gReadyState; },
|
||||
getReadyState() {
|
||||
return gReadyState;
|
||||
},
|
||||
|
||||
setExternalLocalizerServices: function (externalLocalizerServices) {
|
||||
setExternalLocalizerServices(externalLocalizerServices) {
|
||||
gExternalLocalizerServices = externalLocalizerServices;
|
||||
|
||||
// ... in case if we missed DOMContentLoaded above.
|
||||
|
@ -2478,8 +2478,8 @@ var pdfjsWebLibs;
|
||||
};
|
||||
this.anchor = anchor;
|
||||
var div = document.createElement('div');
|
||||
div.id = 'thumbnailContainer' + id;
|
||||
div.className = 'thumbnail';
|
||||
div.setAttribute('data-page-number', this.id);
|
||||
this.div = div;
|
||||
if (id === 1) {
|
||||
div.classList.add('selected');
|
||||
@ -3873,7 +3873,7 @@ var pdfjsWebLibs;
|
||||
this.annotationLayerFactory = annotationLayerFactory;
|
||||
this.renderer = options.renderer || RendererType.CANVAS;
|
||||
this.paintTask = null;
|
||||
this.paintedViewport = null;
|
||||
this.paintedViewportMap = new WeakMap();
|
||||
this.renderingState = RenderingStates.INITIAL;
|
||||
this.resume = null;
|
||||
this.error = null;
|
||||
@ -3883,7 +3883,6 @@ var pdfjsWebLibs;
|
||||
this.zoomLayer = null;
|
||||
this.annotationLayer = null;
|
||||
var div = document.createElement('div');
|
||||
div.id = 'pageContainer' + this.id;
|
||||
div.className = 'page';
|
||||
div.style.width = Math.floor(this.viewport.width) + 'px';
|
||||
div.style.height = Math.floor(this.viewport.height) + 'px';
|
||||
@ -3929,16 +3928,15 @@ var pdfjsWebLibs;
|
||||
this.annotationLayer = null;
|
||||
}
|
||||
if (this.canvas && !currentZoomLayerNode) {
|
||||
this.paintedViewportMap.delete(this.canvas);
|
||||
this.canvas.width = 0;
|
||||
this.canvas.height = 0;
|
||||
delete this.canvas;
|
||||
}
|
||||
if (this.svg) {
|
||||
this.paintedViewportMap.delete(this.svg);
|
||||
delete this.svg;
|
||||
}
|
||||
if (!currentZoomLayerNode) {
|
||||
this.paintedViewport = null;
|
||||
}
|
||||
this.loadingIconDiv = document.createElement('div');
|
||||
this.loadingIconDiv.className = 'loadingIcon';
|
||||
div.appendChild(this.loadingIconDiv);
|
||||
@ -4013,7 +4011,7 @@ var pdfjsWebLibs;
|
||||
var div = this.div;
|
||||
target.style.width = target.parentNode.style.width = div.style.width = Math.floor(width) + 'px';
|
||||
target.style.height = target.parentNode.style.height = div.style.height = Math.floor(height) + 'px';
|
||||
var relativeRotation = this.viewport.rotation - this.paintedViewport.rotation;
|
||||
var relativeRotation = this.viewport.rotation - this.paintedViewportMap.get(target).rotation;
|
||||
var absRotation = Math.abs(relativeRotation);
|
||||
var scaleX = 1, scaleY = 1;
|
||||
if (absRotation === 90 || absRotation === 270) {
|
||||
@ -4131,6 +4129,7 @@ var pdfjsWebLibs;
|
||||
}
|
||||
if (self.zoomLayer) {
|
||||
var zoomLayerCanvas = self.zoomLayer.firstChild;
|
||||
self.paintedViewportMap.delete(zoomLayerCanvas);
|
||||
zoomLayerCanvas.width = 0;
|
||||
zoomLayerCanvas.height = 0;
|
||||
if (div.contains(self.zoomLayer)) {
|
||||
@ -4238,7 +4237,7 @@ var pdfjsWebLibs;
|
||||
canvas.height = roundToDivide(viewport.height * outputScale.sy, sfy[0]);
|
||||
canvas.style.width = roundToDivide(viewport.width, sfx[1]) + 'px';
|
||||
canvas.style.height = roundToDivide(viewport.height, sfy[1]) + 'px';
|
||||
this.paintedViewport = viewport;
|
||||
this.paintedViewportMap.set(canvas, viewport);
|
||||
var transform = !outputScale.scaled ? null : [
|
||||
outputScale.sx,
|
||||
0,
|
||||
@ -4324,7 +4323,7 @@ var pdfjsWebLibs;
|
||||
if (selected) {
|
||||
selected.classList.remove('selected');
|
||||
}
|
||||
var thumbnail = document.getElementById('thumbnailContainer' + page);
|
||||
var thumbnail = document.querySelector('div.thumbnail[data-page-number="' + page + '"]');
|
||||
if (thumbnail) {
|
||||
thumbnail.classList.add('selected');
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
<!ENTITY healthReportLearnMore.label "Learn More">
|
||||
|
||||
<!ENTITY telemetryDesc.label "Shares performance, usage, hardware and customization data about your browser with &vendorShortName; to help us make &brandShortName; better">
|
||||
<!ENTITY enableTelemetryData.label "Share additional data (i.e., Telemetry)">
|
||||
<!ENTITY enableTelemetryData.label "Share Additional Data (i.e., Telemetry)">
|
||||
<!ENTITY enableTelemetryData.accesskey "T">
|
||||
<!ENTITY telemetryLearnMore.label "Learn More">
|
||||
|
||||
@ -83,7 +83,7 @@
|
||||
|
||||
<!ENTITY updateTab.label "Update">
|
||||
|
||||
<!ENTITY updateApplication.label "&brandShortName; updates">
|
||||
<!ENTITY updateApplication.label "&brandShortName; Updates">
|
||||
<!ENTITY updateAuto1.label "Automatically install updates (recommended: improved security)">
|
||||
<!ENTITY updateAuto1.accesskey "A">
|
||||
<!ENTITY updateCheckChoose.label "Check for updates, but let you choose whether to install them">
|
||||
@ -97,7 +97,7 @@
|
||||
<!ENTITY useService.label "Use a background service to install updates">
|
||||
<!ENTITY useService.accesskey "b">
|
||||
|
||||
<!ENTITY autoUpdateOthers.label "Automatically update">
|
||||
<!ENTITY autoUpdateOthers.label "Automatically Update">
|
||||
<!ENTITY enableSearchUpdate.label "Search Engines">
|
||||
<!ENTITY enableSearchUpdate.accesskey "E">
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
<!ENTITY translation.options.attribution.beforeLogo "Translations by">
|
||||
<!ENTITY translation.options.attribution.afterLogo "">
|
||||
|
||||
<!ENTITY drmContent.label "DRM content">
|
||||
<!ENTITY drmContent.label "DRM Content">
|
||||
|
||||
<!ENTITY playDRMContent.label "Play DRM content">
|
||||
<!ENTITY playDRMContent.accesskey "P">
|
||||
|
@ -13,7 +13,7 @@
|
||||
<!ENTITY showURLBarSuggestions.accesskey "l">
|
||||
<!ENTITY urlBarSuggestionsPermanentPB.label "Search suggestions will not be shown in location bar results because you have configured &brandShortName; to never remember history.">
|
||||
|
||||
<!ENTITY oneClickSearchEngines.label "One-click search engines">
|
||||
<!ENTITY oneClickSearchEngines.label "One-click Search Engines">
|
||||
|
||||
<!ENTITY chooseWhichOneToDisplay.label "The search bar lets you search alternate engines directly. Choose which ones to display.">
|
||||
|
||||
|
@ -90,7 +90,7 @@ both, to better adapt this sentence to their language.
|
||||
|
||||
<!ENTITY welcome.useOldSync.label "Using an older version of Sync?">
|
||||
|
||||
<!ENTITY signedOut.caption "Take your Web with you">
|
||||
<!ENTITY signedOut.caption "Take Your Web With You">
|
||||
<!ENTITY signedOut.description "Synchronize your bookmarks, history, tabs, passwords, add-ons, and preferences across all your devices.">
|
||||
<!ENTITY signedOut.accountBox.title "Connect with a &syncBrand.fxAccount.label;">
|
||||
<!ENTITY signedOut.accountBox.create "Create Account">
|
||||
@ -98,7 +98,7 @@ both, to better adapt this sentence to their language.
|
||||
<!ENTITY signedOut.accountBox.signin "Sign In">
|
||||
<!ENTITY signedOut.accountBox.signin.accesskey "I">
|
||||
|
||||
<!ENTITY signedIn.engines.label "Sync across all devices">
|
||||
<!ENTITY signedIn.engines.label "Sync Across All Devices">
|
||||
|
||||
<!-- LOCALIZATION NOTE (mobilePromo3.*): the following strings will be used to
|
||||
create a single sentence with active links.
|
||||
|
@ -273,9 +273,9 @@ this.ExtensionsUI = {
|
||||
let doc = this.browser.ownerDocument;
|
||||
doc.getElementById("addon-webext-perm-header").innerHTML = header;
|
||||
|
||||
if (text) {
|
||||
doc.getElementById("addon-webext-perm-text").innerHTML = text;
|
||||
}
|
||||
let textEl = doc.getElementById("addon-webext-perm-text");
|
||||
textEl.innerHTML = text;
|
||||
textEl.hidden = !text;
|
||||
|
||||
let listIntroEl = doc.getElementById("addon-webext-perm-intro");
|
||||
listIntroEl.value = listIntro;
|
||||
|
@ -417,6 +417,23 @@ def split_triplet(triplet):
|
||||
)
|
||||
|
||||
|
||||
# This defines a fake target/host namespace for when running with --help
|
||||
@depends('--help')
|
||||
def help_host_target(help):
|
||||
if help:
|
||||
return namespace(
|
||||
alias='unknown-unknown-unknown',
|
||||
cpu='unknown',
|
||||
bitness='unknown',
|
||||
kernel='unknown',
|
||||
os='unknown',
|
||||
endianness='unknown',
|
||||
raw_cpu='unknown',
|
||||
raw_os='unknown',
|
||||
toolchain='unknown-unknown',
|
||||
)
|
||||
|
||||
|
||||
@imports('subprocess')
|
||||
def config_sub(shell, triplet):
|
||||
config_sub = os.path.join(os.path.dirname(__file__), '..',
|
||||
@ -437,6 +454,8 @@ def host(value, shell):
|
||||
|
||||
return split_triplet(config_sub(shell, host))
|
||||
|
||||
host = help_host_target | host
|
||||
|
||||
|
||||
@depends('--target', host, shell)
|
||||
@checking('for target system type', lambda t: t.alias)
|
||||
@ -445,6 +464,8 @@ def target(value, host, shell):
|
||||
return host
|
||||
return split_triplet(config_sub(shell, value[0]))
|
||||
|
||||
target = help_host_target | target
|
||||
|
||||
|
||||
@depends(host, target)
|
||||
@checking('whether cross compiling')
|
||||
|
@ -27,9 +27,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=995943
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestCompleteLog();
|
||||
if (navigator.userAgent.indexOf("Mac OS X 10.10") != -1)
|
||||
SimpleTest.expectAssertions(5, 9); // See bug 1067022
|
||||
SimpleTest.expectAssertions(5, 11); // See bug 1067022, 1307988
|
||||
else if (Services.appinfo.OS == "WINNT")
|
||||
SimpleTest.expectAssertions(0, 1); // See bug 1067022
|
||||
else
|
||||
SimpleTest.expectAssertions(0, 2); // See bug 1305241
|
||||
|
||||
var rootdir = Services.appinfo.OS == "WINNT" ? "file:///C:" : "file:///";
|
||||
|
||||
|
@ -922,7 +922,9 @@ cargo_build_flags += --features "quantum_render"
|
||||
endif
|
||||
|
||||
cargo_build_flags += --manifest-path $(CARGO_FILE)
|
||||
ifdef BUILD_VERBOSE_LOG
|
||||
cargo_build_flags += --verbose
|
||||
endif
|
||||
|
||||
# Enable color output if original stdout was a TTY and color settings
|
||||
# aren't already present. This essentially restores the default behavior
|
||||
|
@ -58581,7 +58581,7 @@ var Debugger =
|
||||
onFocus: e => this.setState({ focused: true }),
|
||||
onBlur: e => this.setState({ focused: false }),
|
||||
onKeyDown: this.onKeyDown,
|
||||
placeholder: L10N.getStr("sourceSearch.search1")
|
||||
placeholder: L10N.getStr("sourceSearch.search")
|
||||
});
|
||||
},
|
||||
|
||||
@ -58600,7 +58600,7 @@ var Debugger =
|
||||
|
||||
var resultCountSummary = "";
|
||||
if (this.state.inputValue) {
|
||||
resultCountSummary = L10N.getFormatStr("sourceSearch1.resultsSummary", searchResults.length, this.state.inputValue);
|
||||
resultCountSummary = L10N.getFormatStr("sourceSearch.resultsSummary", searchResults.length, this.state.inputValue);
|
||||
}
|
||||
return dom.div({ className: "results-summary" }, resultCountSummary);
|
||||
},
|
||||
@ -82185,7 +82185,7 @@ var Debugger =
|
||||
|
||||
renderStepButtons() {
|
||||
var className = this.props.pause ? "active" : "disabled";
|
||||
return [debugBtn(this.props.stepOver, "stepOver", className, L10N.getFormatStr("stepOverTooltip1", formatKey("stepOver"))), debugBtn(this.props.stepIn, "stepIn", className, L10N.getFormatStr("stepInTooltip1", formatKey("stepIn"))), debugBtn(this.props.stepOut, "stepOut", className, L10N.getFormatStr("stepOutTooltip1", formatKey("stepOut")))];
|
||||
return [debugBtn(this.props.stepOver, "stepOver", className, L10N.getFormatStr("stepOverTooltip", formatKey("stepOver"))), debugBtn(this.props.stepIn, "stepIn", className, L10N.getFormatStr("stepInTooltip", formatKey("stepIn"))), debugBtn(this.props.stepOut, "stepOut", className, L10N.getFormatStr("stepOutTooltip", formatKey("stepOut")))];
|
||||
},
|
||||
|
||||
renderPauseButton() {
|
||||
@ -82196,14 +82196,14 @@ var Debugger =
|
||||
|
||||
|
||||
if (pause) {
|
||||
return debugBtn(this.props.resume, "resume", "active", L10N.getFormatStr("resumeButtonTooltip1", formatKey("resume")));
|
||||
return debugBtn(this.props.resume, "resume", "active", L10N.getFormatStr("resumeButtonTooltip", formatKey("resume")));
|
||||
}
|
||||
|
||||
if (isWaitingOnBreak) {
|
||||
return debugBtn(null, "pause", "disabled", L10N.getStr("pausePendingButtonTooltip"));
|
||||
}
|
||||
|
||||
return debugBtn(breakOnNext, "pause", "active", L10N.getFormatStr("pauseButtonTooltip1", formatKey("pause")));
|
||||
return debugBtn(breakOnNext, "pause", "active", L10N.getFormatStr("pauseButtonTooltip", formatKey("pause")));
|
||||
},
|
||||
|
||||
/*
|
||||
@ -82308,7 +82308,7 @@ var Debugger =
|
||||
},
|
||||
|
||||
render() {
|
||||
var searchLabel = L10N.getFormatStr("welcome.search1", formatKeyShortcut(`CmdOrCtrl+${ L10N.getStr("sources.search.key") }`));
|
||||
var searchLabel = L10N.getFormatStr("welcome.search", formatKeyShortcut(`CmdOrCtrl+${ L10N.getStr("sources.search.key") }`));
|
||||
return dom.div({ className: "welcomebox" }, searchLabel, this.renderToggleButton());
|
||||
}
|
||||
});
|
||||
@ -82786,22 +82786,22 @@ var Debugger =
|
||||
"sources.search.key": "P",
|
||||
"watchExpressions.header": "Watch Expressions",
|
||||
"watchExpressions.refreshButton": "Refresh",
|
||||
"welcome.search1": "%S to search for sources",
|
||||
"sourceSearch.search1": "Search Sources...",
|
||||
"welcome.search": "%S to search for sources",
|
||||
"sourceSearch.search": "Search Sources...",
|
||||
"sourceSearch.search.key": "F",
|
||||
"sourceSearch.search.again.key": "G",
|
||||
"sourceSearch1.resultsSummary": "%d instances of \"%S\"",
|
||||
"sourceSearch.resultsSummary": "%d instances of \"%S\"",
|
||||
"sourceSearch.noResults": "No files matching %S found",
|
||||
"sourceFooter.debugBtnTooltip": "Prettify Source",
|
||||
"ignoreExceptions": "Ignore exceptions. Click to pause on uncaught exceptions",
|
||||
"pauseOnUncaughtExceptions": "Pause on uncaught exceptions. Click to pause on all exceptions",
|
||||
"pauseOnExceptions": "Pause on all exceptions. Click to ignore exceptions",
|
||||
"stepOutTooltip1": "Step Out %S",
|
||||
"stepInTooltip1": "Step In %S",
|
||||
"stepOverTooltip1": "Step Over %S",
|
||||
"resumeButtonTooltip1": "Resume %S",
|
||||
"stepOutTooltip": "Step Out %S",
|
||||
"stepInTooltip": "Step In %S",
|
||||
"stepOverTooltip": "Step Over %S",
|
||||
"resumeButtonTooltip": "Resume %S",
|
||||
"pausePendingButtonTooltip": "Waiting for next execution",
|
||||
"pauseButtonTooltip1": "Pause %S",
|
||||
"pauseButtonTooltip": "Pause %S",
|
||||
"sourceTabs.closeTab": "Close tab",
|
||||
"sourceTabs.closeOtherTabs": "Close others",
|
||||
"sourceTabs.closeTabsToRight": "Close tabs to the right",
|
||||
@ -82826,4 +82826,4 @@ var Debugger =
|
||||
|
||||
/***/ }
|
||||
/******/ ]);
|
||||
//# sourceMappingURL=debugger.js.map
|
||||
//# sourceMappingURL=debugger.js.map
|
||||
|
@ -273,7 +273,7 @@ skip-if = e10s && debug
|
||||
[browser_dbg_searchbox-help-popup-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_searchbox-parse.js]
|
||||
skip-if = (e10s && debug) || (os == 'linux' && asan) # asan, bug 1313861
|
||||
skip-if = (debug) || (os == 'linux' && asan) # asan, bug 1313861, debug: bug 1313861
|
||||
[browser_dbg_source-maps-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_source-maps-02.js]
|
||||
|
@ -18,59 +18,29 @@ collapsePanes=Collapse panes
|
||||
# that expands the left and right panes in the debugger UI.
|
||||
expandPanes=Expand panes
|
||||
|
||||
# LOCALIZATION NOTE (pauseButtonTooltip1): The tooltip that is displayed for the pause
|
||||
# button when the debugger is in a running state.
|
||||
pauseButtonTooltip1=Pause %S
|
||||
|
||||
# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for
|
||||
# the pause button after it's been clicked but before the next JavaScript to run.
|
||||
pausePendingButtonTooltip=Waiting for next execution
|
||||
|
||||
# LOCALIZATION NOTE (resumeButtonTooltip1): The label that is displayed on the pause
|
||||
# button when the debugger is in a paused state.
|
||||
resumeButtonTooltip1=Resume %S
|
||||
|
||||
# LOCALIZATION NOTE (stepOverTooltip1): The label that is displayed on the
|
||||
# button that steps over a function call.
|
||||
stepOverTooltip1=Step Over %S
|
||||
|
||||
# LOCALIZATION NOTE (stepInTooltip1): The label that is displayed on the
|
||||
# button that steps into a function call.
|
||||
stepInTooltip1=Step In %S
|
||||
|
||||
# LOCALIZATION NOTE (stepOutTooltip1): The label that is displayed on the
|
||||
# button that steps out of a function call.
|
||||
stepOutTooltip1=Step Out %S
|
||||
|
||||
# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause
|
||||
# button when the debugger is in a running state.
|
||||
# Used in the old debugger frontend.
|
||||
pauseButtonTooltip=Click to pause (%S)
|
||||
pauseButtonTooltip=Pause %S
|
||||
|
||||
# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for
|
||||
# the pause button after it's been clicked but before the next JavaScript to run.
|
||||
# Used in the old debugger frontend.
|
||||
pausePendingButtonTooltip=Waiting for next execution
|
||||
|
||||
# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause
|
||||
# button when the debugger is in a paused state.
|
||||
# Used in the old debugger frontend.
|
||||
resumeButtonTooltip=Click to resume (%S)
|
||||
resumeButtonTooltip=Resume %S
|
||||
|
||||
# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the
|
||||
# button that steps over a function call.
|
||||
# Used in the old debugger frontend.
|
||||
stepOverTooltip=Step Over (%S)
|
||||
stepOverTooltip=Step Over %S
|
||||
|
||||
# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the
|
||||
# button that steps into a function call.
|
||||
# Used in the old debugger frontend.
|
||||
stepInTooltip=Step In (%S)
|
||||
stepInTooltip=Step In %S
|
||||
|
||||
# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the
|
||||
# button that steps out of a function call.
|
||||
# Used in the old debugger frontend.
|
||||
stepOutTooltip=Step Out (%S)
|
||||
stepOutTooltip=Step Out %S
|
||||
|
||||
# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list
|
||||
# when there are no workers.
|
||||
@ -154,9 +124,9 @@ sourceSearch.search.key=F
|
||||
# the search for re-searching the same search triggered from a sourceSearch
|
||||
sourceSearch.search.again.key=G
|
||||
|
||||
# LOCALIZATION NOTE (sourceSearch1.resultsSummary): Shows a summary of
|
||||
# LOCALIZATION NOTE (sourceSearch.resultsSummary): Shows a summary of
|
||||
# the number of matches for autocomplete
|
||||
sourceSearch1.resultsSummary=%d instances of “%S”
|
||||
sourceSearch.resultsSummary=%d instances of “%S”
|
||||
|
||||
# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the
|
||||
# global search results when there are no matching strings after filtering.
|
||||
@ -281,7 +251,7 @@ editor.addConditionalBreakpoint=Add Conditional Breakpoint
|
||||
# input element inside ConditionalPanel component
|
||||
editor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true
|
||||
|
||||
# LOCALIZATION NOTE(editor.jumpToMappedLocation1): Context menu item
|
||||
# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item
|
||||
# for navigating to a source mapped location
|
||||
editor.jumpToMappedLocation1=Jump to %S location
|
||||
|
||||
@ -350,14 +320,14 @@ watchExpressions.header=Watch Expressions
|
||||
# button for refreshing the expressions.
|
||||
watchExpressions.refreshButton=Refresh
|
||||
|
||||
# LOCALIZATION NOTE (welcome.search1): The center pane welcome panel's
|
||||
# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's
|
||||
# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on
|
||||
# a mac we use the unicode character.
|
||||
welcome.search1=%S to search for sources
|
||||
welcome.search=%S to search for sources
|
||||
|
||||
# LOCALIZATION NOTE (sourceSearch.search1): The center pane Source Search
|
||||
# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search
|
||||
# prompt for searching for files.
|
||||
sourceSearch.search1=Search Sources…
|
||||
sourceSearch.search=Search Sources…
|
||||
|
||||
# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search
|
||||
# prompt for searching for files.
|
||||
|
@ -48,12 +48,12 @@ function resizeWaterfall(width) {
|
||||
/**
|
||||
* Change the selected tab for details panel.
|
||||
*
|
||||
* @param {number} index - tab index to be selected
|
||||
* @param {string} id - tab id to be selected
|
||||
*/
|
||||
function selectDetailsPanelTab(index) {
|
||||
function selectDetailsPanelTab(id) {
|
||||
return {
|
||||
type: SELECT_DETAILS_PANEL_TAB,
|
||||
index,
|
||||
id,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ module.exports = connect(
|
||||
const { securityState } = item;
|
||||
// Choose the security tab.
|
||||
if (securityState && securityState !== "insecure") {
|
||||
dispatch(Actions.selectDetailsPanelTab(5));
|
||||
dispatch(Actions.selectDetailsPanelTab("security"));
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -59,15 +59,9 @@ const EVENTS = {
|
||||
RESPONSE_IMAGE_THUMBNAIL_DISPLAYED:
|
||||
"NetMonitor:ResponseImageThumbnailAvailable",
|
||||
|
||||
// When a tab is selected in the NetworkDetailsView and subsequently rendered.
|
||||
TAB_UPDATED: "NetMonitor:TabUpdated",
|
||||
|
||||
// Fired when Sidebar has finished being populated.
|
||||
SIDEBAR_POPULATED: "NetMonitor:SidebarPopulated",
|
||||
|
||||
// Fired when NetworkDetailsView has finished being populated.
|
||||
NETWORKDETAILSVIEW_POPULATED: "NetMonitor:NetworkDetailsViewPopulated",
|
||||
|
||||
// Fired when CustomRequestView has finished being populated.
|
||||
CUSTOMREQUESTVIEW_POPULATED: "NetMonitor:CustomRequestViewPopulated",
|
||||
|
||||
|
@ -13,7 +13,7 @@ const {
|
||||
} = require("../constants");
|
||||
|
||||
const UI = I.Record({
|
||||
detailsPanelSelectedTab: 0,
|
||||
detailsPanelSelectedTab: "headers",
|
||||
sidebarOpen: false,
|
||||
statisticsOpen: false,
|
||||
waterfallWidth: null,
|
||||
@ -35,7 +35,7 @@ function openStatistics(state, action) {
|
||||
}
|
||||
|
||||
function setDetailsPanelTab(state, action) {
|
||||
return state.set("detailsPanelSelectedTab", action.index);
|
||||
return state.set("detailsPanelSelectedTab", action.id);
|
||||
}
|
||||
|
||||
function ui(state = new UI(), action) {
|
||||
|
@ -38,10 +38,10 @@ const PREVIEW_TITLE = L10N.getStr("netmonitor.tab.preview");
|
||||
* Display the network request details
|
||||
*/
|
||||
function DetailsPanel({
|
||||
activeTabId,
|
||||
cloneSelectedRequest,
|
||||
request,
|
||||
setTabIndex,
|
||||
tabIndex,
|
||||
selectTab,
|
||||
toolbox,
|
||||
}) {
|
||||
if (!request) {
|
||||
@ -50,9 +50,10 @@ function DetailsPanel({
|
||||
|
||||
return (
|
||||
Tabbar({
|
||||
onSelect: setTabIndex,
|
||||
activeTabId,
|
||||
onSelect: selectTab,
|
||||
renderOnlySelected: true,
|
||||
showAllTabsMenu: true,
|
||||
tabActive: tabIndex,
|
||||
toolbox,
|
||||
},
|
||||
TabPanel({
|
||||
@ -109,17 +110,17 @@ DetailsPanel.propTypes = {
|
||||
cloneSelectedRequest: PropTypes.func.isRequired,
|
||||
request: PropTypes.object,
|
||||
setTabIndex: PropTypes.func.isRequired,
|
||||
tabIndex: PropTypes.number.isRequired,
|
||||
selectedTab: PropTypes.number.isRequired,
|
||||
toolbox: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
module.exports = connect(
|
||||
(state) => ({
|
||||
activeTabId: state.ui.detailsPanelSelectedTab,
|
||||
request: getSelectedRequest(state),
|
||||
tabIndex: state.ui.detailsPanelSelectedTab,
|
||||
}),
|
||||
(dispatch) => ({
|
||||
cloneSelectedRequest: () => dispatch(Actions.cloneSelectedRequest()),
|
||||
setTabIndex: (index) => dispatch(Actions.selectDetailsPanelTab(index)),
|
||||
selectTab: (tabId) => dispatch(Actions.selectDetailsPanelTab(tabId)),
|
||||
}),
|
||||
)(DetailsPanel);
|
||||
|
@ -10,6 +10,7 @@ const { createClass, DOM, PropTypes } = require("devtools/client/shared/vendor/r
|
||||
const SourceEditor = require("devtools/client/sourceeditor/editor");
|
||||
|
||||
const { div } = DOM;
|
||||
const SYNTAX_HIGHLIGHT_MAX_SIZE = 102400;
|
||||
|
||||
/**
|
||||
* CodeMirror editor as a React component
|
||||
@ -39,7 +40,7 @@ const Editor = createClass({
|
||||
|
||||
this.editor = new SourceEditor({
|
||||
lineNumbers: true,
|
||||
mode,
|
||||
mode: text.length < SYNTAX_HIGHLIGHT_MAX_SIZE ? mode : null,
|
||||
readOnly: true,
|
||||
value: text,
|
||||
});
|
||||
@ -54,7 +55,7 @@ const Editor = createClass({
|
||||
return;
|
||||
}
|
||||
|
||||
if (prevProps.mode !== mode) {
|
||||
if (prevProps.mode !== mode && text.length < SYNTAX_HIGHLIGHT_MAX_SIZE) {
|
||||
this.deferEditor.then(() => {
|
||||
this.editor.setMode(mode);
|
||||
});
|
||||
|
@ -64,7 +64,11 @@ const ResponsePanel = createClass({
|
||||
try {
|
||||
json = JSON.parse(response);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
try {
|
||||
json = JSON.parse(atob(response));
|
||||
} catch (err64) {
|
||||
error = err;
|
||||
}
|
||||
}
|
||||
|
||||
if (/\bjson/.test(mimeType) || json) {
|
||||
|
@ -16,6 +16,7 @@ support-files =
|
||||
html_frame-subdocument.html
|
||||
html_filter-test-page.html
|
||||
html_infinite-get-page.html
|
||||
html_json-b64.html
|
||||
html_json-custom-mime-test-page.html
|
||||
html_json-long-test-page.html
|
||||
html_json-malformed-test-page.html
|
||||
@ -94,8 +95,6 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
|
||||
[browser_net_cors_requests.js]
|
||||
[browser_net_cyrillic-01.js]
|
||||
[browser_net_cyrillic-02.js]
|
||||
[browser_net_details-no-duplicated-content.js]
|
||||
skip-if = true # Test broken in React version, is too low-level
|
||||
[browser_net_frame.js]
|
||||
skip-if = (os == 'linux' && debug && bits == 32) # Bug 1321434
|
||||
[browser_net_filter-01.js]
|
||||
@ -107,6 +106,7 @@ skip-if = (os == 'linux' && debug && bits == 32) # Bug 1303439
|
||||
[browser_net_html-preview.js]
|
||||
[browser_net_icon-preview.js]
|
||||
[browser_net_image-tooltip.js]
|
||||
[browser_net_json-b64.js]
|
||||
[browser_net_json-long.js]
|
||||
[browser_net_json-malformed.js]
|
||||
[browser_net_json_custom_mime.js]
|
||||
|
@ -38,10 +38,10 @@ add_task(function* () {
|
||||
time: true
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3 .editor-mount iframe");
|
||||
wait = waitForDOM(document, "#response-panel .editor-mount iframe");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
let [editorFrame] = yield wait;
|
||||
|
||||
yield once(editorFrame, "DOMContentLoaded");
|
||||
|
@ -25,43 +25,43 @@ add_task(function* () {
|
||||
});
|
||||
yield wait;
|
||||
|
||||
wait = waitForDOM(document, "#panel-2 .tree-section", 2);
|
||||
wait = waitForDOM(document, "#params-panel .tree-section", 2);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-2 a").click();
|
||||
document.querySelector("#params-tab").click();
|
||||
yield wait;
|
||||
testParamsTab1("a", '""', '{ "foo": "bar" }', '""');
|
||||
|
||||
wait = waitForDOM(document, "#panel-2 .tree-section", 2);
|
||||
wait = waitForDOM(document, "#params-panel .tree-section", 2);
|
||||
RequestsMenu.selectedIndex = 1;
|
||||
yield wait;
|
||||
testParamsTab1("a", '"b"', '{ "foo": "bar" }', '""');
|
||||
|
||||
wait = waitForDOM(document, "#panel-2 .tree-section", 2);
|
||||
wait = waitForDOM(document, "#params-panel .tree-section", 2);
|
||||
RequestsMenu.selectedIndex = 2;
|
||||
yield wait;
|
||||
testParamsTab1("a", '"b"', "foo", '"bar"');
|
||||
|
||||
wait = waitForDOM(document, "#panel-2 tr:not(.tree-section).treeRow", 2);
|
||||
wait = waitForDOM(document, "#params-panel tr:not(.tree-section).treeRow", 2);
|
||||
RequestsMenu.selectedIndex = 3;
|
||||
yield wait;
|
||||
testParamsTab2("a", '""', '{ "foo": "bar" }', "js");
|
||||
|
||||
wait = waitForDOM(document, "#panel-2 tr:not(.tree-section).treeRow", 2);
|
||||
wait = waitForDOM(document, "#params-panel tr:not(.tree-section).treeRow", 2);
|
||||
RequestsMenu.selectedIndex = 4;
|
||||
yield wait;
|
||||
testParamsTab2("a", '"b"', '{ "foo": "bar" }', "js");
|
||||
|
||||
// Wait for all tree sections and editor updated by react
|
||||
let waitSections = waitForDOM(document, "#panel-2 .tree-section", 2);
|
||||
let waitEditor = waitForDOM(document, "#panel-2 .editor-mount iframe");
|
||||
let waitSections = waitForDOM(document, "#params-panel .tree-section", 2);
|
||||
let waitEditor = waitForDOM(document, "#params-panel .editor-mount iframe");
|
||||
RequestsMenu.selectedIndex = 5;
|
||||
let [, editorFrames] = yield Promise.all([waitSections, waitEditor]);
|
||||
yield once(editorFrames[0], "DOMContentLoaded");
|
||||
yield waitForDOM(editorFrames[0].contentDocument, ".CodeMirror-code");
|
||||
testParamsTab2("a", '"b"', "?foo=bar", "text");
|
||||
|
||||
wait = waitForDOM(document, "#panel-2 .empty-notice");
|
||||
wait = waitForDOM(document, "#params-panel .empty-notice");
|
||||
RequestsMenu.selectedIndex = 6;
|
||||
yield wait;
|
||||
testParamsTab3();
|
||||
@ -70,7 +70,7 @@ add_task(function* () {
|
||||
|
||||
function testParamsTab1(queryStringParamName, queryStringParamValue,
|
||||
formDataParamName, formDataParamValue) {
|
||||
let tabpanel = document.querySelector("#panel-2");
|
||||
let tabpanel = document.querySelector("#params-panel");
|
||||
|
||||
is(tabpanel.querySelectorAll(".tree-section").length, 2,
|
||||
"The number of param tree sections displayed in this tabpanel is incorrect.");
|
||||
@ -111,7 +111,7 @@ add_task(function* () {
|
||||
function testParamsTab2(queryStringParamName, queryStringParamValue,
|
||||
requestPayload, editorMode) {
|
||||
let isJSON = editorMode === "js";
|
||||
let tabpanel = document.querySelector("#panel-2");
|
||||
let tabpanel = document.querySelector("#params-panel");
|
||||
|
||||
is(tabpanel.querySelectorAll(".tree-section").length, 2,
|
||||
"The number of param tree sections displayed in this tabpanel is incorrect.");
|
||||
@ -164,7 +164,7 @@ add_task(function* () {
|
||||
}
|
||||
|
||||
function testParamsTab3() {
|
||||
let tabpanel = document.querySelector("#panel-2");
|
||||
let tabpanel = document.querySelector("#params-panel");
|
||||
|
||||
is(tabpanel.querySelectorAll(".tree-section").length, 0,
|
||||
"The number of param tree sections displayed in this tabpanel is incorrect.");
|
||||
|
@ -90,14 +90,6 @@ add_task(function* () {
|
||||
time: true
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
yield wait;
|
||||
|
||||
RequestsMenu.selectedIndex = -1;
|
||||
|
||||
yield selectIndexAndWaitForEditor(0);
|
||||
yield testResponseTab("xml");
|
||||
|
||||
@ -122,7 +114,7 @@ add_task(function* () {
|
||||
yield teardown(monitor);
|
||||
|
||||
function* testResponseTab(type) {
|
||||
let tabpanel = document.querySelector("#panel-3");
|
||||
let tabpanel = document.querySelector("#response-panel");
|
||||
|
||||
function checkVisibility(box) {
|
||||
is(tabpanel.querySelector(".response-error-header") === null,
|
||||
@ -232,10 +224,11 @@ add_task(function* () {
|
||||
}
|
||||
|
||||
function* selectIndexAndWaitForEditor(index) {
|
||||
let editor = document.querySelector("#panel-3 .editor-mount iframe");
|
||||
let editor = document.querySelector("#response-panel .editor-mount iframe");
|
||||
if (!editor) {
|
||||
let waitDOM = waitForDOM(document, ".editor-mount iframe");
|
||||
let waitDOM = waitForDOM(document, "#response-panel .editor-mount iframe");
|
||||
RequestsMenu.selectedIndex = index;
|
||||
document.querySelector("#response-tab").click();
|
||||
[editor] = yield waitDOM;
|
||||
yield once(editor, "DOMContentLoaded");
|
||||
} else {
|
||||
@ -246,14 +239,14 @@ add_task(function* () {
|
||||
}
|
||||
|
||||
function* selectIndexAndWaitForJSONView(index) {
|
||||
let tabpanel = document.querySelector("#panel-3");
|
||||
let tabpanel = document.querySelector("#response-panel");
|
||||
let waitDOM = waitForDOM(tabpanel, ".treeTable");
|
||||
RequestsMenu.selectedIndex = index;
|
||||
yield waitDOM;
|
||||
}
|
||||
|
||||
function* selectIndexAndWaitForImageView(index) {
|
||||
let tabpanel = document.querySelector("#panel-3");
|
||||
let tabpanel = document.querySelector("#response-panel");
|
||||
let waitDOM = waitForDOM(tabpanel, ".response-image");
|
||||
RequestsMenu.selectedIndex = index;
|
||||
let [imageNode] = yield waitDOM;
|
||||
|
@ -28,10 +28,10 @@ add_task(function* () {
|
||||
statusText: "DA DA DA"
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3 .editor-mount iframe");
|
||||
wait = waitForDOM(document, "#response-panel .editor-mount iframe");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
let [editor] = yield wait;
|
||||
yield once(editor, "DOMContentLoaded");
|
||||
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
|
||||
|
@ -27,10 +27,10 @@ add_task(function* () {
|
||||
statusText: "OK"
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3 .editor-mount iframe");
|
||||
wait = waitForDOM(document, "#response-panel .editor-mount iframe");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
let [editor] = yield wait;
|
||||
yield once(editor, "DOMContentLoaded");
|
||||
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
|
||||
|
@ -1,171 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// A test to ensure that the content in details pane is not duplicated.
|
||||
|
||||
add_task(function* () {
|
||||
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
|
||||
let panel = monitor.panelWin;
|
||||
let { NetMonitorView, EVENTS } = panel;
|
||||
let { RequestsMenu, NetworkDetails } = NetMonitorView;
|
||||
|
||||
const COOKIE_UNIQUE_PATH = "/do-not-use-in-other-tests-using-cookies";
|
||||
|
||||
let TEST_CASES = [
|
||||
{
|
||||
desc: "Test headers tab",
|
||||
pageURI: CUSTOM_GET_URL,
|
||||
requestURI: null,
|
||||
isPost: false,
|
||||
tabIndex: 0,
|
||||
variablesView: NetworkDetails._headers,
|
||||
expectedScopeLength: 2,
|
||||
},
|
||||
{
|
||||
desc: "Test cookies tab",
|
||||
pageURI: CUSTOM_GET_URL,
|
||||
requestURI: COOKIE_UNIQUE_PATH,
|
||||
isPost: false,
|
||||
tabIndex: 1,
|
||||
variablesView: NetworkDetails._cookies,
|
||||
expectedScopeLength: 1,
|
||||
},
|
||||
{
|
||||
desc: "Test params tab",
|
||||
pageURI: POST_RAW_URL,
|
||||
requestURI: null,
|
||||
isPost: true,
|
||||
tabIndex: 2,
|
||||
variablesView: NetworkDetails._params,
|
||||
expectedScopeLength: 1,
|
||||
},
|
||||
];
|
||||
|
||||
info("Adding a cookie for the \"Cookie\" tab test");
|
||||
yield setDocCookie("a=b; path=" + COOKIE_UNIQUE_PATH);
|
||||
|
||||
info("Running tests");
|
||||
for (let spec of TEST_CASES) {
|
||||
yield runTestCase(spec);
|
||||
}
|
||||
|
||||
// Remove the cookie. If an error occurs the path of the cookie ensures it
|
||||
// doesn't mess with the other tests.
|
||||
info("Removing the added cookie.");
|
||||
yield setDocCookie(
|
||||
"a=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=" + COOKIE_UNIQUE_PATH);
|
||||
|
||||
yield teardown(monitor);
|
||||
|
||||
/**
|
||||
* Set a content document cookie
|
||||
*/
|
||||
function setDocCookie(cookie) {
|
||||
return ContentTask.spawn(tab.linkedBrowser, cookie, function* (cookieArg) {
|
||||
content.document.cookie = cookieArg;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper that handles the execution of each case.
|
||||
*/
|
||||
function* runTestCase(spec) {
|
||||
info("Running case: " + spec.desc);
|
||||
let wait = waitForNetworkEvents(monitor, 1);
|
||||
tab.linkedBrowser.loadURI(spec.pageURI);
|
||||
yield wait;
|
||||
|
||||
RequestsMenu.clear();
|
||||
yield waitForFinalDetailTabUpdate(spec.tabIndex, spec.isPost, spec.requestURI);
|
||||
|
||||
is(spec.variablesView._store.length, spec.expectedScopeLength,
|
||||
"View contains " + spec.expectedScopeLength + " scope headers");
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper that prepares the variables view for the actual testing. It
|
||||
* - selects the correct tab
|
||||
* - performs the specified request to specified URI
|
||||
* - opens the details view
|
||||
* - waits for the final update to happen
|
||||
*/
|
||||
function* waitForFinalDetailTabUpdate(tabIndex, isPost, uri) {
|
||||
let onNetworkEvent = panel.once(EVENTS.NETWORK_EVENT);
|
||||
let onDetailsPopulated = panel.once(EVENTS.NETWORKDETAILSVIEW_POPULATED);
|
||||
let onRequestFinished = isPost ?
|
||||
waitForNetworkEvents(monitor, 0, 1) :
|
||||
waitForNetworkEvents(monitor, 1);
|
||||
|
||||
info("Performing a request");
|
||||
yield ContentTask.spawn(tab.linkedBrowser, uri, function* (url) {
|
||||
content.wrappedJSObject.performRequests(1, url);
|
||||
});
|
||||
|
||||
info("Waiting for NETWORK_EVENT");
|
||||
yield onNetworkEvent;
|
||||
|
||||
if (!RequestsMenu.getItemAtIndex(0)) {
|
||||
info("Waiting for the request to be added to the view");
|
||||
yield monitor.panelWin.once(EVENTS.REQUEST_ADDED);
|
||||
}
|
||||
|
||||
ok(true, "Received NETWORK_EVENT. Selecting the item.");
|
||||
let item = RequestsMenu.getItemAtIndex(0);
|
||||
RequestsMenu.selectedItem = item;
|
||||
|
||||
info("Item selected. Waiting for NETWORKDETAILSVIEW_POPULATED");
|
||||
yield onDetailsPopulated;
|
||||
|
||||
info("Received populated event. Selecting tab at index " + tabIndex);
|
||||
NetworkDetails.widget.selectedIndex = tabIndex;
|
||||
|
||||
info("Waiting for request to finish.");
|
||||
yield onRequestFinished;
|
||||
|
||||
ok(true, "Request finished.");
|
||||
|
||||
/**
|
||||
* Because this test uses lazy updates there's four scenarios to consider:
|
||||
* #1: Everything is updated and test is ready to continue.
|
||||
* #2: There's updates that are waiting to be flushed.
|
||||
* #3: Updates are flushed but the tab update is still running.
|
||||
* #4: There's pending updates and a tab update is still running.
|
||||
*
|
||||
* For case #1 there's not going to be a TAB_UPDATED event so don't wait for
|
||||
* it (bug 1106181).
|
||||
*
|
||||
* For cases #2 and #3 it's enough to wait for one TAB_UPDATED event as for
|
||||
* - case #2 the next flush will perform the final update and single
|
||||
* TAB_UPDATED event is emitted.
|
||||
* - case #3 the running update is the final update that'll emit one
|
||||
* TAB_UPDATED event.
|
||||
*
|
||||
* For case #4 we must wait for the updates to be flushed before we can
|
||||
* start waiting for TAB_UPDATED event or we'll continue the test right
|
||||
* after the pending update finishes.
|
||||
*/
|
||||
let hasQueuedUpdates = RequestsMenu._updateQueue.length !== 0;
|
||||
let hasRunningTabUpdate = NetworkDetails._viewState.updating[tabIndex];
|
||||
|
||||
if (hasQueuedUpdates || hasRunningTabUpdate) {
|
||||
info("There's pending updates - waiting for them to finish.");
|
||||
info(" hasQueuedUpdates: " + hasQueuedUpdates);
|
||||
info(" hasRunningTabUpdate: " + hasRunningTabUpdate);
|
||||
|
||||
if (hasQueuedUpdates && hasRunningTabUpdate) {
|
||||
info("Waiting for updates to be flushed.");
|
||||
// _flushRequests calls .populate which emits the following event
|
||||
yield panel.once(EVENTS.NETWORKDETAILSVIEW_POPULATED);
|
||||
|
||||
info("Requests flushed.");
|
||||
}
|
||||
|
||||
info("Waiting for final tab update.");
|
||||
yield waitFor(panel, EVENTS.TAB_UPDATED);
|
||||
}
|
||||
|
||||
info("All updates completed.");
|
||||
}
|
||||
});
|
@ -25,26 +25,26 @@ add_task(function* () {
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
|
||||
ok(document.querySelector("#tab-0.is-active"),
|
||||
ok(document.querySelector("#headers-tab[aria-selected=true]"),
|
||||
"The headers tab in the details panel should be selected.");
|
||||
ok(!document.querySelector("#tab-5"),
|
||||
ok(!document.querySelector("#preview-tab"),
|
||||
"The preview tab should be hidden for non html responses.");
|
||||
ok(!document.querySelector("#panel-5"),
|
||||
ok(!document.querySelector("#preview-panel"),
|
||||
"The preview panel is hidden for non html responses.");
|
||||
|
||||
wait = waitForDOM(document, "#tab-5");
|
||||
wait = waitForDOM(document, ".tabs");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[4]);
|
||||
yield wait;
|
||||
|
||||
document.querySelector("#tab-5 a").click();
|
||||
document.querySelector("#preview-tab").click();
|
||||
|
||||
ok(document.querySelector("#tab-5.is-active"),
|
||||
ok(document.querySelector("#preview-tab[aria-selected=true]"),
|
||||
"The preview tab in the details panel should be selected.");
|
||||
ok(document.querySelector("#panel-5"),
|
||||
ok(document.querySelector("#preview-panel"),
|
||||
"The preview panel should be visible now.");
|
||||
|
||||
let iframe = document.querySelector("#panel-5 iframe");
|
||||
let iframe = document.querySelector("#preview-panel iframe");
|
||||
yield once(iframe, "DOMContentLoaded");
|
||||
|
||||
ok(iframe,
|
||||
@ -57,11 +57,11 @@ add_task(function* () {
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[5]);
|
||||
|
||||
ok(document.querySelector("#tab-0.is-active"),
|
||||
ok(document.querySelector("#headers-tab[aria-selected=true]"),
|
||||
"The headers tab in the details panel should be selected again.");
|
||||
ok(!document.querySelector("#tab-5"),
|
||||
ok(!document.querySelector("#preview-tab"),
|
||||
"The preview tab should be hidden again for non html responses.");
|
||||
ok(!document.querySelector("#panel-5"),
|
||||
ok(!document.querySelector("#preview-panel"),
|
||||
"The preview panel is hidden again for non html responses.");
|
||||
|
||||
yield teardown(monitor);
|
||||
|
62
devtools/client/netmonitor/test/browser_net_json-b64.js
Normal file
62
devtools/client/netmonitor/test/browser_net_json-b64.js
Normal file
@ -0,0 +1,62 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Tests if JSON responses encoded in base64 are handled correctly.
|
||||
*/
|
||||
|
||||
add_task(function* () {
|
||||
let { L10N } = require("devtools/client/netmonitor/l10n");
|
||||
let { tab, monitor } = yield initNetMonitor(JSON_B64_URL);
|
||||
info("Starting test... ");
|
||||
|
||||
let { document, NetMonitorView } = monitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
let wait = waitForNetworkEvents(monitor, 1);
|
||||
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.performRequests();
|
||||
});
|
||||
yield wait;
|
||||
|
||||
wait = waitForDOM(document, "#response-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#response-tab").click();
|
||||
yield wait;
|
||||
|
||||
let tabpanel = document.querySelector("#response-panel");
|
||||
|
||||
is(tabpanel.querySelector(".response-error-header") === null, true,
|
||||
"The response error header doesn't have the intended visibility.");
|
||||
let jsonView = tabpanel.querySelector(".tree-section .treeLabel") || {};
|
||||
is(jsonView.textContent === L10N.getStr("jsonScopeName"), true,
|
||||
"The response json view has the intended visibility.");
|
||||
is(tabpanel.querySelector(".editor-mount iframe") === null, true,
|
||||
"The response editor doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector(".response-image-box") === null, true,
|
||||
"The response image box doesn't have the intended visibility.");
|
||||
|
||||
is(tabpanel.querySelectorAll(".tree-section").length, 1,
|
||||
"There should be 1 tree sections displayed in this tabpanel.");
|
||||
is(tabpanel.querySelectorAll(".treeRow:not(.tree-section)").length, 1,
|
||||
"There should be 1 json properties displayed in this tabpanel.");
|
||||
is(tabpanel.querySelectorAll(".empty-notice").length, 0,
|
||||
"The empty notice should not be displayed in this tabpanel.");
|
||||
|
||||
let labels = tabpanel
|
||||
.querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
|
||||
let values = tabpanel
|
||||
.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
|
||||
|
||||
is(labels[0].textContent, "greeting",
|
||||
"The first json property name was incorrect.");
|
||||
is(values[0].textContent, "\"This is a base 64 string.\"",
|
||||
"The first json property value was incorrect.");
|
||||
|
||||
yield teardown(monitor);
|
||||
});
|
@ -39,10 +39,10 @@ add_task(function* () {
|
||||
time: true
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3");
|
||||
wait = waitForDOM(document, "#response-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
yield wait;
|
||||
|
||||
testResponseTab();
|
||||
@ -50,7 +50,7 @@ add_task(function* () {
|
||||
yield teardown(monitor);
|
||||
|
||||
function testResponseTab() {
|
||||
let tabpanel = document.querySelector("#panel-3");
|
||||
let tabpanel = document.querySelector("#response-panel");
|
||||
|
||||
is(tabpanel.querySelector(".response-error-header") === null, true,
|
||||
"The response error header doesn't have the intended visibility.");
|
||||
|
@ -31,15 +31,15 @@ add_task(function* () {
|
||||
fullMimeType: "text/json; charset=utf-8"
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3 .editor-mount iframe");
|
||||
wait = waitForDOM(document, "#response-panel .editor-mount iframe");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
let [editor] = yield wait;
|
||||
yield once(editor, "DOMContentLoaded");
|
||||
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
|
||||
|
||||
let tabpanel = document.querySelector("#panel-3");
|
||||
let tabpanel = document.querySelector("#response-panel");
|
||||
is(tabpanel.querySelector(".response-error-header") === null, false,
|
||||
"The response error header doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector(".response-error-header").textContent,
|
||||
|
@ -34,10 +34,10 @@ add_task(function* () {
|
||||
time: true
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3");
|
||||
wait = waitForDOM(document, "#response-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
yield wait;
|
||||
|
||||
testResponseTab();
|
||||
@ -45,7 +45,7 @@ add_task(function* () {
|
||||
yield teardown(monitor);
|
||||
|
||||
function testResponseTab() {
|
||||
let tabpanel = document.querySelector("#panel-3");
|
||||
let tabpanel = document.querySelector("#response-panel");
|
||||
|
||||
is(tabpanel.querySelector(".response-error-header") === null, true,
|
||||
"The response error header doesn't have the intended visibility.");
|
||||
|
@ -34,10 +34,10 @@ add_task(function* () {
|
||||
time: true
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3");
|
||||
wait = waitForDOM(document, "#response-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
yield wait;
|
||||
|
||||
testResponseTab();
|
||||
@ -45,7 +45,7 @@ add_task(function* () {
|
||||
yield teardown(monitor);
|
||||
|
||||
function testResponseTab() {
|
||||
let tabpanel = document.querySelector("#panel-3");
|
||||
let tabpanel = document.querySelector("#response-panel");
|
||||
|
||||
is(tabpanel.querySelector(".response-error-header") === null, true,
|
||||
"The response error header doesn't have the intended visibility.");
|
||||
|
@ -43,15 +43,15 @@ add_task(function* () {
|
||||
time: true
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3");
|
||||
wait = waitForDOM(document, "#response-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
yield wait;
|
||||
|
||||
testResponseTab("$_0123Fun", "\"Hello JSONP!\"");
|
||||
|
||||
wait = waitForDOM(document, "#panel-3 .tree-section");
|
||||
wait = waitForDOM(document, "#response-panel .tree-section");
|
||||
RequestsMenu.selectedIndex = 1;
|
||||
yield wait;
|
||||
|
||||
@ -60,7 +60,7 @@ add_task(function* () {
|
||||
yield teardown(monitor);
|
||||
|
||||
function testResponseTab(func, greeting) {
|
||||
let tabpanel = document.querySelector("#panel-3");
|
||||
let tabpanel = document.querySelector("#response-panel");
|
||||
|
||||
is(tabpanel.querySelector(".response-error-header") === null, true,
|
||||
"The response error header doesn't have the intended visibility.");
|
||||
|
@ -34,10 +34,10 @@ add_task(function* () {
|
||||
statusText: "OK"
|
||||
});
|
||||
|
||||
let waitDOM = waitForDOM(document, "#panel-3 .editor-mount iframe");
|
||||
let waitDOM = waitForDOM(document, "#response-panel .editor-mount iframe");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
let [editor] = yield waitDOM;
|
||||
yield once(editor, "DOMContentLoaded");
|
||||
yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
|
||||
|
@ -47,16 +47,16 @@ add_task(function* () {
|
||||
});
|
||||
|
||||
// Wait for all tree sections updated by react
|
||||
wait = waitForDOM(document, "#panel-2 .tree-section", 2);
|
||||
wait = waitForDOM(document, "#params-panel .tree-section", 2);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-2 a").click();
|
||||
document.querySelector("#params-tab").click();
|
||||
yield wait;
|
||||
yield testParamsTab("urlencoded");
|
||||
|
||||
// Wait for all tree sections and editor updated by react
|
||||
let waitForSections = waitForDOM(document, "#panel-2 .tree-section", 2);
|
||||
let waitForEditor = waitForDOM(document, "#panel-2 .editor-mount iframe");
|
||||
let waitForSections = waitForDOM(document, "#params-panel .tree-section", 2);
|
||||
let waitForEditor = waitForDOM(document, "#params-panel .editor-mount iframe");
|
||||
RequestsMenu.selectedIndex = 1;
|
||||
let [, editorFrames] = yield Promise.all([waitForSections, waitForEditor]);
|
||||
yield once(editorFrames[0], "DOMContentLoaded");
|
||||
@ -66,7 +66,7 @@ add_task(function* () {
|
||||
return teardown(monitor);
|
||||
|
||||
function* testParamsTab(type) {
|
||||
let tabpanel = document.querySelector("#panel-2");
|
||||
let tabpanel = document.querySelector("#params-panel");
|
||||
|
||||
function checkVisibility(box) {
|
||||
is(!tabpanel.querySelector(".treeTable"), !box.includes("params"),
|
||||
|
@ -26,13 +26,13 @@ add_task(function* () {
|
||||
yield wait;
|
||||
|
||||
// Wait for all tree view updated by react
|
||||
wait = waitForDOM(document, "#panel-2 .tree-section");
|
||||
wait = waitForDOM(document, "#params-panel .tree-section");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-2 a").click();
|
||||
document.querySelector("#params-tab").click();
|
||||
yield wait;
|
||||
|
||||
let tabpanel = document.querySelector("#panel-2");
|
||||
let tabpanel = document.querySelector("#params-panel");
|
||||
|
||||
ok(tabpanel.querySelector(".treeTable"),
|
||||
"The request params doesn't have the indended visibility.");
|
||||
|
@ -26,13 +26,13 @@ add_task(function* () {
|
||||
yield wait;
|
||||
|
||||
// Wait for all tree view updated by react
|
||||
wait = waitForDOM(document, "#panel-0");
|
||||
wait = waitForDOM(document, "#headers-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-0 a").click();
|
||||
document.querySelector("#headers-tab").click();
|
||||
yield wait;
|
||||
|
||||
let tabpanel = document.querySelector("#panel-0");
|
||||
let tabpanel = document.querySelector("#headers-panel");
|
||||
|
||||
is(tabpanel.querySelectorAll(".tree-section .treeLabel").length, 3,
|
||||
"There should be 3 header sections displayed in this tabpanel.");
|
||||
@ -57,11 +57,11 @@ add_task(function* () {
|
||||
"The second request header value was incorrect.");
|
||||
|
||||
// Wait for all tree sections updated by react
|
||||
wait = waitForDOM(document, "#panel-2 .tree-section");
|
||||
document.querySelector("#tab-2 a").click();
|
||||
wait = waitForDOM(document, "#params-panel .tree-section");
|
||||
document.querySelector("#params-tab").click();
|
||||
yield wait;
|
||||
|
||||
tabpanel = document.querySelector("#panel-2");
|
||||
tabpanel = document.querySelector("#params-panel");
|
||||
|
||||
ok(tabpanel.querySelector(".treeTable"),
|
||||
"The params tree view should be displayed.");
|
||||
|
@ -26,13 +26,13 @@ add_task(function* () {
|
||||
yield wait;
|
||||
|
||||
// Wait for all tree view updated by react
|
||||
wait = waitForDOM(document, "#panel-2 .tree-section");
|
||||
wait = waitForDOM(document, "#params-panel .tree-section");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-2 a").click();
|
||||
document.querySelector("#params-tab").click();
|
||||
yield wait;
|
||||
|
||||
let tabpanel = document.querySelector("#panel-2");
|
||||
let tabpanel = document.querySelector("#params-panel");
|
||||
|
||||
ok(tabpanel.querySelector(".treeTable"),
|
||||
"The request params doesn't have the indended visibility.");
|
||||
|
@ -22,13 +22,13 @@ add_task(function* () {
|
||||
});
|
||||
yield wait;
|
||||
|
||||
wait = waitForDOM(document, "#panel-5");
|
||||
wait = waitForDOM(document, "#security-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelector("#details-pane-toggle"));
|
||||
document.querySelector("#tab-5 a").click();
|
||||
document.querySelector("#security-tab").click();
|
||||
yield wait;
|
||||
|
||||
let tabpanel = document.querySelector("#panel-5");
|
||||
let tabpanel = document.querySelector("#security-panel");
|
||||
let textboxes = tabpanel.querySelectorAll(".textbox-input");
|
||||
|
||||
// Connection
|
||||
|
@ -21,10 +21,10 @@ add_task(function* () {
|
||||
});
|
||||
yield wait;
|
||||
|
||||
wait = waitForDOM(document, "#panel-5");
|
||||
wait = waitForDOM(document, "#security-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelector("#details-pane-toggle"));
|
||||
document.querySelector("#tab-5 a").click();
|
||||
document.querySelector("#security-tab").click();
|
||||
yield wait;
|
||||
|
||||
let errormsg = document.querySelector(".security-info-value");
|
||||
|
@ -24,7 +24,7 @@ add_task(function* () {
|
||||
|
||||
info("Selecting headers panel again.");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelector("#tab-0 a"));
|
||||
document.querySelector("#headers-tab"));
|
||||
|
||||
info("Sorting the items by filename.");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
@ -47,10 +47,11 @@ add_task(function* () {
|
||||
let item = RequestsMenu.getItemAtIndex(0);
|
||||
let icon = document.querySelector(".requests-security-state-icon");
|
||||
|
||||
let wait = waitForDOM(document, "#panel-5");
|
||||
let wait = waitForDOM(document, "#security-panel");
|
||||
info("Clicking security icon of the first request and waiting for panel update.");
|
||||
EventUtils.synthesizeMouseAtCenter(icon, {}, monitor.panelWin);
|
||||
yield wait;
|
||||
ok(document.querySelector("#tab-5.is-active"), "Security tab is selected.");
|
||||
|
||||
ok(document.querySelector("#security-tab[aria-selected=true]"), "Security tab is selected.");
|
||||
}
|
||||
});
|
||||
|
@ -36,13 +36,13 @@ add_task(function* () {
|
||||
|
||||
info("Selecting security tab.");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelector("#tab-5 a"));
|
||||
document.querySelector("#security-tab"));
|
||||
|
||||
info("Selecting insecure request.");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[1]);
|
||||
|
||||
ok(document.querySelector("#tab-0.is-active"),
|
||||
ok(document.querySelector("#headers-tab[aria-selected=true]"),
|
||||
"Selected tab was reset when selected security tab was hidden.");
|
||||
|
||||
return teardown(monitor);
|
||||
|
@ -58,34 +58,25 @@ add_task(function* () {
|
||||
|
||||
is(RequestsMenu.selectedItem.securityState, undefined,
|
||||
"Security state has not yet arrived.");
|
||||
is(!!document.querySelector("#tab-5"), testcase.visibleOnNewEvent,
|
||||
is(!!document.querySelector("#security-tab"), testcase.visibleOnNewEvent,
|
||||
"Security tab is " + (testcase.visibleOnNewEvent ? "visible" : "hidden") +
|
||||
" after new request was added to the menu.");
|
||||
is(!!document.querySelector("#panel-5"), testcase.visibleOnNewEvent,
|
||||
"Security panel is " + (testcase.visibleOnNewEvent ? "visible" : "hidden") +
|
||||
" after new request was added to the menu.");
|
||||
|
||||
info("Waiting for security information to arrive.");
|
||||
yield onSecurityInfo;
|
||||
|
||||
ok(RequestsMenu.selectedItem.securityState,
|
||||
"Security state arrived.");
|
||||
is(!!document.querySelector("#tab-5"), testcase.visibleOnSecurityInfo,
|
||||
is(!!document.querySelector("#security-tab"), testcase.visibleOnSecurityInfo,
|
||||
"Security tab is " + (testcase.visibleOnSecurityInfo ? "visible" : "hidden") +
|
||||
" after security information arrived.");
|
||||
is(!!document.querySelector("#panel-5"), testcase.visibleOnSecurityInfo,
|
||||
"Security panel is " + (testcase.visibleOnSecurityInfo? "visible" : "hidden") +
|
||||
" after security information arrived.");
|
||||
|
||||
info("Waiting for request to complete.");
|
||||
yield onComplete;
|
||||
|
||||
is(!!document.querySelector("#tab-5"), testcase.visibleOnceComplete,
|
||||
is(!!document.querySelector("#security-tab"), testcase.visibleOnceComplete,
|
||||
"Security tab is " + (testcase.visibleOnceComplete ? "visible" : "hidden") +
|
||||
" after request has been completed.");
|
||||
is(!!document.querySelector("#panel-5"), testcase.visibleOnceComplete,
|
||||
"Security panel is " + (testcase.visibleOnceComplete? "visible" : "hidden") +
|
||||
" after request has been completed.");
|
||||
|
||||
info("Clearing requests.");
|
||||
RequestsMenu.clear();
|
||||
|
@ -38,10 +38,10 @@ add_task(function* () {
|
||||
document.querySelectorAll(".request-list-item")[0]);
|
||||
yield wait;
|
||||
|
||||
if (!document.querySelector("#tab-5.is-active")) {
|
||||
if (!document.querySelector("#security-tab[aria-selected=true]")) {
|
||||
info("Selecting security tab.");
|
||||
wait = waitForDOM(document, "#panel-5 .properties-view");
|
||||
document.querySelector("#tab-5 a").click();
|
||||
wait = waitForDOM(document, "#security-panel .properties-view");
|
||||
document.querySelector("#security-tab").click();
|
||||
yield wait;
|
||||
}
|
||||
|
||||
|
@ -145,12 +145,12 @@ add_task(function* () {
|
||||
* A function that tests "Headers" panel contains correct information.
|
||||
*/
|
||||
function* testHeaders(data, index) {
|
||||
let wait = waitForDOM(document, "#panel-0");
|
||||
let wait = waitForDOM(document, "#headers-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[index]);
|
||||
yield wait;
|
||||
|
||||
let panel = document.querySelector("#panel-0");
|
||||
let panel = document.querySelector("#headers-panel");
|
||||
let summaryValues = panel.querySelectorAll(".tabpanel-summary-value.textbox-input");
|
||||
let { method, uri, details: { status, statusText } } = data;
|
||||
|
||||
@ -166,13 +166,13 @@ add_task(function* () {
|
||||
* A function that tests "Params" panel contains correct information.
|
||||
*/
|
||||
function* testParams(data, index) {
|
||||
let wait = waitForDOM(document, "#panel-2 .properties-view");
|
||||
let wait = waitForDOM(document, "#params-panel .properties-view");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[index]);
|
||||
document.querySelector("#tab-2 a").click();
|
||||
document.querySelector("#params-tab").click();
|
||||
yield wait;
|
||||
|
||||
let panel = document.querySelector("#panel-2");
|
||||
let panel = document.querySelector("#params-panel");
|
||||
let statusParamValue = data.uri.split("=").pop();
|
||||
let statusParamShownValue = "\"" + statusParamValue + "\"";
|
||||
let treeSections = panel.querySelectorAll(".tree-section");
|
||||
|
@ -40,10 +40,10 @@ add_task(function* () {
|
||||
});
|
||||
});
|
||||
|
||||
wait = waitForDOM(document, "#panel-3");
|
||||
wait = waitForDOM(document, "#response-panel");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
document.querySelector("#tab-3 a").click();
|
||||
document.querySelector("#response-tab").click();
|
||||
yield wait;
|
||||
|
||||
RequestsMenu.selectedIndex = -1;
|
||||
@ -59,10 +59,11 @@ add_task(function* () {
|
||||
return teardown(monitor);
|
||||
|
||||
function* selectIndexAndWaitForEditor(index) {
|
||||
let editor = document.querySelector("#panel-3 .editor-mount iframe");
|
||||
let editor = document.querySelector("#response-panel .editor-mount iframe");
|
||||
if (!editor) {
|
||||
let waitDOM = waitForDOM(document, "#panel-3 .editor-mount iframe");
|
||||
let waitDOM = waitForDOM(document, "#response-panel .editor-mount iframe");
|
||||
RequestsMenu.selectedIndex = index;
|
||||
document.querySelector("#response-tab").click();
|
||||
[editor] = yield waitDOM;
|
||||
yield once(editor, "DOMContentLoaded");
|
||||
} else {
|
||||
@ -73,7 +74,7 @@ add_task(function* () {
|
||||
}
|
||||
|
||||
function testEditorContent([ fmt, textRe ]) {
|
||||
let editor = document.querySelector("#panel-3 .editor-mount iframe");
|
||||
let editor = document.querySelector("#response-panel .editor-mount iframe");
|
||||
let text = editor.contentDocument
|
||||
.querySelector(".CodeMirror-line").textContent;
|
||||
|
||||
|
@ -39,6 +39,7 @@ const JSON_LONG_URL = EXAMPLE_URL + "html_json-long-test-page.html";
|
||||
const JSON_MALFORMED_URL = EXAMPLE_URL + "html_json-malformed-test-page.html";
|
||||
const JSON_CUSTOM_MIME_URL = EXAMPLE_URL + "html_json-custom-mime-test-page.html";
|
||||
const JSON_TEXT_MIME_URL = EXAMPLE_URL + "html_json-text-mime-test-page.html";
|
||||
const JSON_B64_URL = EXAMPLE_URL + "html_json-b64.html";
|
||||
const SORTING_URL = EXAMPLE_URL + "html_sorting-test-page.html";
|
||||
const FILTERING_URL = EXAMPLE_URL + "html_filter-test-page.html";
|
||||
const INFINITE_GET_URL = EXAMPLE_URL + "html_infinite-get-page.html";
|
||||
|
38
devtools/client/netmonitor/test/html_json-b64.html
Normal file
38
devtools/client/netmonitor/test/html_json-b64.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<title>Network Monitor test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>JSON b64 test</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
function get(aAddress, aCallback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", aAddress, true);
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == this.DONE) {
|
||||
aCallback();
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
function performRequests() {
|
||||
get("sjs_content-type-test-server.sjs?fmt=json-b64", function() {
|
||||
// Done.
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -137,6 +137,14 @@ function handleRequest(request, response) {
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "json-b64": {
|
||||
response.setStatusLine(request.httpVersion, status, "OK");
|
||||
response.setHeader("Content-Type", "text/json; charset=utf-8", false);
|
||||
setCacheHeaders();
|
||||
response.write(btoa("{ \"greeting\": \"This is a base 64 string.\" }"));
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "json-long": {
|
||||
let str = "{ \"greeting\": \"Hello long string JSON!\" },";
|
||||
response.setStatusLine(request.httpVersion, status, "OK");
|
||||
|
@ -25,30 +25,39 @@ let Tabbar = createClass({
|
||||
children: PropTypes.object,
|
||||
onSelect: PropTypes.func,
|
||||
showAllTabsMenu: PropTypes.bool,
|
||||
tabActive: PropTypes.number,
|
||||
activeTabId: PropTypes.string,
|
||||
toolbox: PropTypes.object,
|
||||
renderOnlySelected: PropTypes.bool,
|
||||
},
|
||||
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
showAllTabsMenu: false,
|
||||
tabActive: 0,
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function () {
|
||||
let { children } = this.props;
|
||||
let { activeTabId, children = [] } = this.props;
|
||||
let tabs = this.createTabs(children);
|
||||
let activeTab = tabs.findIndex((tab, index) => tab.id === activeTabId);
|
||||
|
||||
return {
|
||||
tabs: children ? this.createTabs(children) : [],
|
||||
activeTab: 0
|
||||
activeTab: activeTab === -1 ? 0 : activeTab,
|
||||
tabs,
|
||||
};
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function (nextProps) {
|
||||
let { children } = nextProps;
|
||||
let { activeTabId, children = [] } = nextProps;
|
||||
let tabs = this.createTabs(children);
|
||||
let activeTab = tabs.findIndex((tab, index) => tab.id === activeTabId);
|
||||
|
||||
if (children && children !== this.props.children) {
|
||||
this.setState({ tabs: this.createTabs(children) });
|
||||
if (activeTab !== this.state.activeTab ||
|
||||
(children !== this.props.children)) {
|
||||
this.setState({
|
||||
activeTab: activeTab === -1 ? 0 : activeTab,
|
||||
tabs,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@ -57,7 +66,7 @@ let Tabbar = createClass({
|
||||
.filter((panel) => panel)
|
||||
.map((panel, index) =>
|
||||
Object.assign({}, children[index], {
|
||||
id: index,
|
||||
id: panel.props.id || index,
|
||||
panel,
|
||||
title: panel.props.title,
|
||||
})
|
||||
@ -137,7 +146,7 @@ let Tabbar = createClass({
|
||||
getTabIndex: function (tabId) {
|
||||
let tabIndex = -1;
|
||||
this.state.tabs.forEach((tab, index) => {
|
||||
if (tab.id == tabId) {
|
||||
if (tab.id === tabId) {
|
||||
tabIndex = index;
|
||||
}
|
||||
});
|
||||
@ -213,8 +222,9 @@ let Tabbar = createClass({
|
||||
div({className: "devtools-sidebar-tabs"},
|
||||
Tabs({
|
||||
onAllTabsMenuClick: this.onAllTabsMenuClick,
|
||||
renderOnlySelected: this.props.renderOnlySelected,
|
||||
showAllTabsMenu: this.props.showAllTabsMenu,
|
||||
tabActive: this.props.tabActive || this.state.activeTab,
|
||||
tabActive: this.state.activeTab,
|
||||
onAfterChange: this.onTabChanged,
|
||||
},
|
||||
tabs
|
||||
|
@ -50,12 +50,18 @@ define(function (require, exports, module) {
|
||||
]).isRequired,
|
||||
showAllTabsMenu: React.PropTypes.bool,
|
||||
onAllTabsMenuClick: React.PropTypes.func,
|
||||
|
||||
// Set true will only render selected panel on DOM. It's complete
|
||||
// opposite of the created array, and it's useful if panels content
|
||||
// is unpredictable and update frequently.
|
||||
renderOnlySelected: React.PropTypes.bool,
|
||||
},
|
||||
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
tabActive: 0,
|
||||
showAllTabsMenu: false,
|
||||
renderOnlySelected: false,
|
||||
};
|
||||
},
|
||||
|
||||
@ -105,8 +111,9 @@ define(function (require, exports, module) {
|
||||
if (typeof tabActive === "number") {
|
||||
let panels = children.filter((panel) => panel);
|
||||
|
||||
// Reset to index 0 if index larger than number of panels
|
||||
tabActive = tabActive < panels.length ? tabActive : 0;
|
||||
// Reset to index 0 if index overflows the range of panel array
|
||||
tabActive = (tabActive < panels.length && tabActive >= 0) ?
|
||||
tabActive : 0;
|
||||
|
||||
let created = [...this.state.created];
|
||||
created[tabActive] = true;
|
||||
@ -224,17 +231,16 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
let tabs = this.props.children
|
||||
.map(tab => {
|
||||
return typeof tab === "function" ? tab() : tab;
|
||||
}).filter(tab => {
|
||||
return tab;
|
||||
}).map((tab, index) => {
|
||||
let ref = ("tab-menu-" + index);
|
||||
.map((tab) => typeof tab === "function" ? tab() : tab)
|
||||
.filter((tab) => tab)
|
||||
.map((tab, index) => {
|
||||
let id = tab.props.id;
|
||||
let ref = "tab-menu-" + index;
|
||||
let title = tab.props.title;
|
||||
let tabClassName = tab.props.className;
|
||||
let isTabSelected = this.state.tabActive === index;
|
||||
|
||||
let classes = [
|
||||
let className = [
|
||||
"tabs-menu-item",
|
||||
tabClassName,
|
||||
isTabSelected ? "is-active" : ""
|
||||
@ -247,15 +253,15 @@ define(function (require, exports, module) {
|
||||
// See also `onKeyDown()` event handler.
|
||||
return (
|
||||
DOM.li({
|
||||
ref: ref,
|
||||
className,
|
||||
key: index,
|
||||
id: "tab-" + index,
|
||||
className: classes,
|
||||
ref,
|
||||
role: "presentation",
|
||||
},
|
||||
DOM.a({
|
||||
tabIndex: this.state.tabActive === index ? 0 : -1,
|
||||
"aria-controls": "panel-" + index,
|
||||
id: id ? id + "-tab" : "tab-" + index,
|
||||
tabIndex: isTabSelected ? 0 : -1,
|
||||
"aria-controls": id ? id + "-panel" : "panel-" + index,
|
||||
"aria-selected": isTabSelected,
|
||||
role: "tab",
|
||||
onClick: this.onClickTab.bind(this, index),
|
||||
@ -286,23 +292,28 @@ define(function (require, exports, module) {
|
||||
},
|
||||
|
||||
renderPanels: function () {
|
||||
if (!this.props.children) {
|
||||
let { children, renderOnlySelected } = this.props;
|
||||
|
||||
if (!children) {
|
||||
throw new Error("There must be at least one Tab");
|
||||
}
|
||||
|
||||
if (!Array.isArray(this.props.children)) {
|
||||
this.props.children = [this.props.children];
|
||||
if (!Array.isArray(children)) {
|
||||
children = [children];
|
||||
}
|
||||
|
||||
let selectedIndex = this.state.tabActive;
|
||||
|
||||
let panels = this.props.children
|
||||
.map(tab => {
|
||||
return typeof tab === "function" ? tab() : tab;
|
||||
}).filter(tab => {
|
||||
return tab;
|
||||
}).map((tab, index) => {
|
||||
let selected = selectedIndex == index;
|
||||
let panels = children
|
||||
.map((tab) => typeof tab === "function" ? tab() : tab)
|
||||
.filter((tab) => tab)
|
||||
.map((tab, index) => {
|
||||
let selected = selectedIndex === index;
|
||||
if (renderOnlySelected && !selected) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let id = tab.props.id;
|
||||
|
||||
// Use 'visibility:hidden' + 'width/height:0' for hiding
|
||||
// content of non-selected tab. It's faster (not sure why)
|
||||
@ -315,12 +326,12 @@ define(function (require, exports, module) {
|
||||
|
||||
return (
|
||||
DOM.div({
|
||||
id: id ? id + "-panel" : "panel-" + index,
|
||||
key: index,
|
||||
id: "panel-" + index,
|
||||
style: style,
|
||||
className: "tab-panel-box",
|
||||
role: "tabpanel",
|
||||
"aria-labelledby": "tab-" + index,
|
||||
"aria-labelledby": id ? id + "-tab" : "tab-" + index,
|
||||
},
|
||||
(selected || this.state.created[index]) ? tab : null
|
||||
)
|
||||
@ -335,12 +346,10 @@ define(function (require, exports, module) {
|
||||
},
|
||||
|
||||
render: function () {
|
||||
let classNames = ["tabs", this.props.className].join(" ");
|
||||
|
||||
return (
|
||||
DOM.div({className: classNames},
|
||||
DOM.div({ className: ["tabs", this.props.className].join(" ") },
|
||||
this.renderMenuItems(),
|
||||
this.renderPanels()
|
||||
this.renderPanels(),
|
||||
)
|
||||
);
|
||||
},
|
||||
|
@ -40,11 +40,11 @@ window.onload = Task.async(function* () {
|
||||
is(tabAnchors[0].parentElement.getAttribute("role"), "presentation", "li role is set correctly");
|
||||
is(tabAnchors[0].getAttribute("role"), "tab", "Anchor role is set correctly");
|
||||
is(tabAnchors[0].getAttribute("aria-selected"), "true", "Anchor aria-selected is set correctly by default");
|
||||
is(tabAnchors[0].getAttribute("aria-controls"), "panel-0", "Anchor aria-controls is set correctly");
|
||||
is(tabAnchors[0].getAttribute("aria-controls"), "sidebar-0-panel", "Anchor aria-controls is set correctly");
|
||||
is(tabAnchors[1].parentElement.getAttribute("role"), "presentation", "li role is set correctly");
|
||||
is(tabAnchors[1].getAttribute("role"), "tab", "Anchor role is set correctly");
|
||||
is(tabAnchors[1].getAttribute("aria-selected"), "false", "Anchor aria-selected is set correctly by default");
|
||||
is(tabAnchors[1].getAttribute("aria-controls"), "panel-1", "Anchor aria-controls is set correctly");
|
||||
is(tabAnchors[1].getAttribute("aria-controls"), "sidebar-1-panel", "Anchor aria-controls is set correctly");
|
||||
|
||||
yield setState(tabbarReact, Object.assign({}, tabbarReact.state, {
|
||||
activeTab: 1
|
||||
@ -56,12 +56,12 @@ window.onload = Task.async(function* () {
|
||||
function addTabWithPanel(tabId) {
|
||||
// Setup for InspectorTabPanel
|
||||
let panel = document.createElement("div");
|
||||
panel.id = `sidebar-panel-${tabId}`;
|
||||
panel.id = `sidebar-${tabId}`;
|
||||
document.body.appendChild(panel);
|
||||
|
||||
return setState(tabbarReact, Object.assign({}, tabbarReact.state, {
|
||||
tabs: tabbarReact.state.tabs.concat({
|
||||
id: `sidebar-panel-${tabId}`,
|
||||
id: `sidebar-${tabId}`,
|
||||
title: `tab-${tabId}`,
|
||||
panel: InspectorTabPanel
|
||||
}),
|
||||
|
@ -8,42 +8,25 @@
|
||||
#define mozilla_dom_Dispatcher_h
|
||||
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/TaskCategory.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIEventTarget;
|
||||
class nsIRunnable;
|
||||
|
||||
// This file defines basic functionality for dispatching runnables to various
|
||||
// groups: either the SystemGroup or a DocGroup or TabGroup. Ideally all
|
||||
// runnables destined for the main thread should be dispatched to a group
|
||||
// instead so that we know what kind of web content they'll be
|
||||
// touching. Runnables sent to the SystemGroup never touch web
|
||||
// content. Runnables sent to a DocGroup can only touch documents belonging to
|
||||
// that DocGroup. Runnables sent to a TabGroup can touch any document in any of
|
||||
// the tabs belonging to the TabGroup.
|
||||
|
||||
namespace mozilla {
|
||||
class AbstractThread;
|
||||
namespace dom {
|
||||
|
||||
class TabGroup;
|
||||
class DocGroup;
|
||||
|
||||
enum class TaskCategory {
|
||||
// User input (clicks, keypresses, etc.)
|
||||
UI,
|
||||
|
||||
// Data from the network
|
||||
Network,
|
||||
|
||||
// setTimeout, setInterval
|
||||
Timer,
|
||||
|
||||
// Runnables posted from a worker to the main thread
|
||||
Worker,
|
||||
|
||||
// requestIdleCallback
|
||||
IdleCallback,
|
||||
|
||||
// Vsync notifications
|
||||
RefreshDriver,
|
||||
|
||||
// Most DOM events (postMessage, media, plugins)
|
||||
Other,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
// This trait should be attached to classes like nsIGlobalObject and nsIDocument
|
||||
// that have a DocGroup or TabGroup attached to them. The methods here should
|
||||
@ -83,7 +66,7 @@ public:
|
||||
// off the main thread.
|
||||
virtual AbstractThread* AbstractMainThreadFor(TaskCategory aCategory) = 0;
|
||||
|
||||
// These methods perform a safe cast. They return null if |this| is not of the
|
||||
// This method performs a safe cast. It returns null if |this| is not of the
|
||||
// requested type.
|
||||
virtual TabGroup* AsTabGroup() { return nullptr; }
|
||||
|
||||
|
@ -689,11 +689,11 @@ EventSourceImpl::StreamReaderFunc(nsIInputStream* aInputStream,
|
||||
uint32_t* aWriteCount)
|
||||
{
|
||||
EventSourceImpl* thisObject = static_cast<EventSourceImpl*>(aClosure);
|
||||
thisObject->AssertIsOnTargetThread();
|
||||
if (!thisObject || !aWriteCount) {
|
||||
NS_WARNING("EventSource cannot read from stream: no aClosure or aWriteCount");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
thisObject->AssertIsOnTargetThread();
|
||||
thisObject->ParseSegment((const char*)aFromRawSegment, aCount);
|
||||
*aWriteCount = aCount;
|
||||
return NS_OK;
|
||||
|
@ -12,7 +12,11 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsICancelableRunnable.h"
|
||||
#include "nsIIncrementalRunnable.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsITimeoutHandler.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
|
||||
|
@ -3013,7 +3013,7 @@ nsIDocument::EventTargetFor(TaskCategory aCategory) const
|
||||
}
|
||||
|
||||
AbstractThread*
|
||||
nsIDocument::AbstractMainThreadFor(mozilla::dom::TaskCategory aCategory)
|
||||
nsIDocument::AbstractMainThreadFor(mozilla::TaskCategory aCategory)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mDocGroup) {
|
||||
|
@ -1777,14 +1777,14 @@ private:
|
||||
public:
|
||||
// Dispatch a runnable related to the global.
|
||||
virtual nsresult Dispatch(const char* aName,
|
||||
mozilla::dom::TaskCategory aCategory,
|
||||
mozilla::TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable) override;
|
||||
|
||||
virtual nsIEventTarget*
|
||||
EventTargetFor(mozilla::dom::TaskCategory aCategory) const override;
|
||||
EventTargetFor(mozilla::TaskCategory aCategory) const override;
|
||||
|
||||
virtual mozilla::AbstractThread*
|
||||
AbstractMainThreadFor(mozilla::dom::TaskCategory aCategory) override;
|
||||
AbstractMainThreadFor(mozilla::TaskCategory aCategory) override;
|
||||
|
||||
protected:
|
||||
// These members are only used on outer window objects. Make sure
|
||||
|
@ -2876,14 +2876,14 @@ public:
|
||||
|
||||
// Dispatch a runnable related to the document.
|
||||
virtual nsresult Dispatch(const char* aName,
|
||||
mozilla::dom::TaskCategory aCategory,
|
||||
mozilla::TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable) override;
|
||||
|
||||
virtual nsIEventTarget*
|
||||
EventTargetFor(mozilla::dom::TaskCategory aCategory) const override;
|
||||
EventTargetFor(mozilla::TaskCategory aCategory) const override;
|
||||
|
||||
virtual mozilla::AbstractThread*
|
||||
AbstractMainThreadFor(mozilla::dom::TaskCategory aCategory) override;
|
||||
AbstractMainThreadFor(mozilla::TaskCategory aCategory) override;
|
||||
|
||||
// The URLs passed to these functions should match what
|
||||
// JS::DescribeScriptedCaller() returns, since these APIs are used to
|
||||
|
@ -604,7 +604,7 @@ public:
|
||||
mozilla::dom::DocGroup* GetDocGroup() const;
|
||||
|
||||
virtual nsIEventTarget*
|
||||
EventTargetFor(mozilla::dom::TaskCategory aCategory) const = 0;
|
||||
EventTargetFor(mozilla::TaskCategory aCategory) const = 0;
|
||||
|
||||
protected:
|
||||
// The nsPIDOMWindow constructor. The aOuterWindow argument should
|
||||
|
@ -1338,6 +1338,7 @@ XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
desc.setSetter(nullptr);
|
||||
}
|
||||
desc.object().set(wrapper);
|
||||
desc.value().setUndefined();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
6
dom/cache/Action.h
vendored
6
dom/cache/Action.h
vendored
@ -28,11 +28,7 @@ public:
|
||||
// Action::RunOnTarget().
|
||||
virtual void Resolve(nsresult aRv) = 0;
|
||||
|
||||
NS_IMETHOD_(MozExternalRefCountType)
|
||||
AddRef(void) = 0;
|
||||
|
||||
NS_IMETHOD_(MozExternalRefCountType)
|
||||
Release(void) = 0;
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
};
|
||||
|
||||
// Class containing data that can be opportunistically shared between
|
||||
|
6
dom/cache/ReadStream.h
vendored
6
dom/cache/ReadStream.h
vendored
@ -67,11 +67,7 @@ public:
|
||||
virtual bool
|
||||
HasEverBeenRead() const = 0;
|
||||
|
||||
NS_IMETHOD_(MozExternalRefCountType)
|
||||
AddRef(void) = 0;
|
||||
|
||||
NS_IMETHOD_(MozExternalRefCountType)
|
||||
Release(void) = 0;
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
};
|
||||
|
||||
static already_AddRefed<ReadStream>
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "mozilla/dom/CloseEvent.h"
|
||||
#include "mozilla/dom/CustomEvent.h"
|
||||
#include "mozilla/dom/DeviceOrientationEvent.h"
|
||||
#include "mozilla/dom/ErrorEvent.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "mozilla/dom/FocusEvent.h"
|
||||
#include "mozilla/dom/HashChangeEvent.h"
|
||||
@ -37,8 +38,10 @@
|
||||
#include "mozilla/dom/PageTransitionEvent.h"
|
||||
#include "mozilla/dom/PointerEvent.h"
|
||||
#include "mozilla/dom/PopStateEvent.h"
|
||||
#include "mozilla/dom/RootedDictionary.h"
|
||||
#include "mozilla/dom/ScrollAreaEvent.h"
|
||||
#include "mozilla/dom/SimpleGestureEvent.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/StorageEvent.h"
|
||||
#include "mozilla/dom/SVGZoomEvent.h"
|
||||
#include "mozilla/dom/TimeEvent.h"
|
||||
@ -1164,6 +1167,14 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
|
||||
event->MarkUninitialized();
|
||||
return event.forget();
|
||||
}
|
||||
if (aEventType.LowerCaseEqualsLiteral("errorevent")) {
|
||||
LOG_EVENT_CREATION(ERROREVENT);
|
||||
RootedDictionary<ErrorEventInit> init(RootingCx());
|
||||
RefPtr<Event> event =
|
||||
ErrorEvent::Constructor(aOwner, EmptyString(), init);
|
||||
event->MarkUninitialized();
|
||||
return event.forget();
|
||||
}
|
||||
|
||||
#undef LOG_EVENT_CREATION
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user