Merge m-c to inbound, a=merge

MozReview-Commit-ID: 9YZdlIARozU
This commit is contained in:
Wes Kocher 2016-04-08 16:47:03 -07:00
commit dfc7e5253f
538 changed files with 6769 additions and 5684 deletions

View File

@ -193,6 +193,7 @@ toolkit/modules/tests/xpcshell/test_task.js
toolkit/components/osfile/** toolkit/components/osfile/**
# External code: # External code:
toolkit/components/microformats/test/**
toolkit/components/reader/Readability.js toolkit/components/reader/Readability.js
toolkit/components/reader/JSDOMParser.js toolkit/components/reader/JSDOMParser.js

View File

@ -304,7 +304,7 @@ pref("browser.urlbar.matchBehavior", 1);
pref("browser.urlbar.filter.javascript", true); pref("browser.urlbar.filter.javascript", true);
// the maximum number of results to show in autocomplete when doing richResults // the maximum number of results to show in autocomplete when doing richResults
pref("browser.urlbar.maxRichResults", 12); pref("browser.urlbar.maxRichResults", 10);
// The amount of time (ms) to wait after the user has stopped typing // The amount of time (ms) to wait after the user has stopped typing
// before starting to perform autocomplete. 50 is the default set in // before starting to perform autocomplete. 50 is the default set in
// autocomplete.xml. // autocomplete.xml.

View File

@ -660,6 +660,7 @@ var LightweightThemeListener = {
if (sheet.href == "chrome://browser/skin/browser-lightweightTheme.css") if (sheet.href == "chrome://browser/skin/browser-lightweightTheme.css")
return sheet; return sheet;
} }
return undefined;
}); });
Services.obs.addObserver(this, "lightweight-theme-styling-update", false); Services.obs.addObserver(this, "lightweight-theme-styling-update", false);

View File

@ -11,7 +11,6 @@ var gPluginHandler = {
"PluginContent:RemoveNotification", "PluginContent:RemoveNotification",
"PluginContent:UpdateHiddenPluginUI", "PluginContent:UpdateHiddenPluginUI",
"PluginContent:HideNotificationBar", "PluginContent:HideNotificationBar",
"PluginContent:ShowInstallNotification",
"PluginContent:InstallSinglePlugin", "PluginContent:InstallSinglePlugin",
"PluginContent:ShowPluginCrashedNotification", "PluginContent:ShowPluginCrashedNotification",
"PluginContent:SubmitReport", "PluginContent:SubmitReport",
@ -56,8 +55,6 @@ var gPluginHandler = {
case "PluginContent:HideNotificationBar": case "PluginContent:HideNotificationBar":
this.hideNotificationBar(msg.target, msg.data.name); this.hideNotificationBar(msg.target, msg.data.name);
break; break;
case "PluginContent:ShowInstallNotification":
return this.showInstallNotification(msg.target, msg.data.pluginInfo);
case "PluginContent:InstallSinglePlugin": case "PluginContent:InstallSinglePlugin":
this.installSinglePlugin(msg.data.pluginInfo); this.installSinglePlugin(msg.data.pluginInfo);
break; break;

View File

@ -251,7 +251,7 @@ var gSyncUI = {
if (needsSetup || this._loginFailed()) { if (needsSetup || this._loginFailed()) {
this.openSetup(); this.openSetup();
} else { } else {
return this.doSync(); this.doSync();
} }
}).catch(err => { }).catch(err => {
this.log.error("Failed to handle toolbar button command", err); this.log.error("Failed to handle toolbar button command", err);

View File

@ -3387,7 +3387,7 @@ const DOMLinkHandler = {
addSearch: function(aBrowser, aEngine, aURL) { addSearch: function(aBrowser, aEngine, aURL) {
let tab = gBrowser.getTabForBrowser(aBrowser); let tab = gBrowser.getTabForBrowser(aBrowser);
if (!tab) if (!tab)
return false; return;
BrowserSearch.addEngine(aBrowser, aEngine, makeURI(aURL)); BrowserSearch.addEngine(aBrowser, aEngine, makeURI(aURL));
}, },

View File

@ -698,7 +698,7 @@
showcommentcolumn="true" showcommentcolumn="true"
showimagecolumn="true" showimagecolumn="true"
enablehistory="true" enablehistory="true"
maxrows="6" maxrows="10"
newlines="stripsurroundingwhitespace" newlines="stripsurroundingwhitespace"
ontextentered="this.handleCommand(param);" ontextentered="this.handleCommand(param);"
ontextreverted="return this.handleRevert();" ontextreverted="return this.handleRevert();"

View File

@ -268,6 +268,7 @@ function getClipboardHelper() {
return Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper); return Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
} catch(e) { } catch(e) {
// do nothing, later code will handle the error // do nothing, later code will handle the error
return null;
} }
} }
const gClipboardHelper = getClipboardHelper(); const gClipboardHelper = getClipboardHelper();

View File

@ -603,6 +603,7 @@ Sanitizer.prototype = {
aWindow.skipNextCanClose = true; aWindow.skipNextCanClose = true;
return true; return true;
} }
return false;
}, },
_resetAllWindowClosures: function(aWindowList) { _resetAllWindowClosures: function(aWindowList) {
for (let win of aWindowList) { for (let win of aWindowList) {
@ -665,6 +666,7 @@ Sanitizer.prototype = {
e.stopPropagation(); e.stopPropagation();
return false; return false;
} }
return undefined;
} }
newWindow.addEventListener("fullscreen", onFullScreen); newWindow.addEventListener("fullscreen", onFullScreen);
} }

View File

@ -147,6 +147,7 @@ var Change = {
return this.doChangePassword(); return this.doChangePassword();
break; break;
} }
return undefined;
}, },
doGeneratePassphrase: function () { doGeneratePassphrase: function () {

View File

@ -123,14 +123,14 @@ var gSyncSetup = {
startNewAccountSetup: function () { startNewAccountSetup: function () {
if (!Weave.Utils.ensureMPUnlocked()) if (!Weave.Utils.ensureMPUnlocked())
return false; return;
this._settingUpNew = true; this._settingUpNew = true;
this.wizard.pageIndex = NEW_ACCOUNT_START_PAGE; this.wizard.pageIndex = NEW_ACCOUNT_START_PAGE;
}, },
useExistingAccount: function () { useExistingAccount: function () {
if (!Weave.Utils.ensureMPUnlocked()) if (!Weave.Utils.ensureMPUnlocked())
return false; return;
this._settingUpNew = false; this._settingUpNew = false;
if (this.wizardType == "pair") { if (this.wizardType == "pair") {
// We're already pairing, so there's no point in pairing again. // We're already pairing, so there's no point in pairing again.

View File

@ -1824,6 +1824,99 @@
</body> </body>
</method> </method>
<method name="_linkBrowserToTab">
<parameter name="aTab"/>
<parameter name="aURI"/>
<parameter name="aParams"/>
<body>
<![CDATA[
"use strict";
let aReferrerURI = aParams.referrerURI;
let aReferrerPolicy = aParams.referrerPolicy;
let aCharset = aParams.charset;
let aPostData = aParams.postData;
let aAllowThirdPartyFixup = aParams.allowThirdPartyFixup;
let aFromExternal = aParams.fromExternal;
let aAllowMixedContent = aParams.allowMixedContent;
let aForceNotRemote = aParams.forceNotRemote;
let aNoReferrer = aParams.noReferrer;
let aUserContextId = aParams.userContextId;
let uriIsAboutBlank = !aURI || aURI == "about:blank";
// The new browser should be remote if this is an e10s window and
// the uri to load can be loaded remotely.
let remote = gMultiProcessBrowser &&
!aForceNotRemote &&
E10SUtils.canLoadURIInProcess(aURI, Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT);
let browser;
let usingPreloadedContent = false;
// If we open a new tab with the newtab URL in the default
// userContext, check if there is a preloaded browser ready.
// Private windows are not included because both the label and the
// icon for the tab would be set incorrectly (see bug 1195981).
if (aURI == BROWSER_NEW_TAB_URL && !aUserContextId &&
!PrivateBrowsingUtils.isWindowPrivate(window)) {
browser = this._getPreloadedBrowser();
usingPreloadedContent = !!browser;
}
if (!browser) {
// No preloaded browser found, create one.
browser = this._createBrowser({remote: remote,
uriIsAboutBlank: uriIsAboutBlank,
userContextId: aUserContextId});
}
let notificationbox = this.getNotificationBox(browser);
let uniqueId = this._generateUniquePanelID();
notificationbox.id = uniqueId;
aTab.linkedPanel = uniqueId;
aTab.linkedBrowser = browser;
this._tabForBrowser.set(browser, aTab);
// Inject the <browser> into the DOM if necessary.
if (!notificationbox.parentNode) {
// NB: this appendChild call causes us to run constructors for the
// browser element, which fires off a bunch of notifications. Some
// of those notifications can cause code to run that inspects our
// state, so it is important that the tab element is fully
// initialized by this point.
this.mPanelContainer.appendChild(notificationbox);
}
// wire up a progress listener for the new browser object.
let tabListener = this.mTabProgressListener(aTab, browser, uriIsAboutBlank, usingPreloadedContent);
const filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
.createInstance(Ci.nsIWebProgress);
filter.addProgressListener(tabListener, Ci.nsIWebProgress.NOTIFY_ALL);
browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
this._tabListeners.set(aTab, tabListener);
this._tabFilters.set(aTab, filter);
browser.droppedLinkHandler = handleDroppedLink;
// We start our browsers out as inactive, and then maintain
// activeness in the tab switcher.
browser.docShellIsActive = false;
// When addTab() is called with an URL that is not "about:blank" we
// set the "nodefaultsrc" attribute that prevents a frameLoader
// from being created as soon as the linked <browser> is inserted
// into the DOM. We thus have to register the new outerWindowID
// for non-remote browsers after we have called browser.loadURI().
if (!remote) {
this._outerWindowIDBrowserMap.set(browser.outerWindowID, browser);
}
return { usingPreloadedContent: usingPreloadedContent };
]]>
</body>
</method>
<method name="addTab"> <method name="addTab">
<parameter name="aURI"/> <parameter name="aURI"/>
<parameter name="aReferrerURI"/> <parameter name="aReferrerURI"/>
@ -1833,6 +1926,8 @@
<parameter name="aAllowThirdPartyFixup"/> <parameter name="aAllowThirdPartyFixup"/>
<body> <body>
<![CDATA[ <![CDATA[
"use strict";
const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var aReferrerPolicy; var aReferrerPolicy;
var aFromExternal; var aFromExternal;
@ -1884,12 +1979,6 @@
t.setAttribute("onerror", "this.removeAttribute('image');"); t.setAttribute("onerror", "this.removeAttribute('image');");
t.className = "tabbrowser-tab"; t.className = "tabbrowser-tab";
// The new browser should be remote if this is an e10s window and
// the uri to load can be loaded remotely.
let remote = gMultiProcessBrowser &&
!aForceNotRemote &&
E10SUtils.canLoadURIInProcess(aURI, Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT);
this.tabContainer._unlockTabSizing(); this.tabContainer._unlockTabSizing();
// When overflowing, new tabs are scrolled into view smoothly, which // When overflowing, new tabs are scrolled into view smoothly, which
@ -1914,59 +2003,35 @@
if (aOwner) if (aOwner)
t.owner = aOwner; t.owner = aOwner;
let b;
let usingPreloadedContent = false;
// If we open a new tab with the newtab URL in the default
// userContext, check if there is a preloaded browser ready.
// Private windows are not included because both the label and the
// icon for the tab would be set incorrectly (see bug 1195981).
if (aURI == BROWSER_NEW_TAB_URL && !aUserContextId &&
!PrivateBrowsingUtils.isWindowPrivate(window)) {
b = this._getPreloadedBrowser();
usingPreloadedContent = !!b;
}
if (!b) {
// No preloaded browser found, create one.
b = this._createBrowser({remote: remote,
uriIsAboutBlank: uriIsAboutBlank,
userContextId: aUserContextId});
}
let notificationbox = this.getNotificationBox(b);
var position = this.tabs.length - 1; var position = this.tabs.length - 1;
var uniqueId = this._generateUniquePanelID();
notificationbox.id = uniqueId;
t.linkedPanel = uniqueId;
t.linkedBrowser = b;
this._tabForBrowser.set(b, t);
t._tPos = position; t._tPos = position;
t.lastAccessed = Date.now(); t.lastAccessed = Date.now();
this.tabContainer._setPositionalAttributes(); this.tabContainer._setPositionalAttributes();
// Inject the <browser> into the DOM if necessary.
if (!notificationbox.parentNode) {
// NB: this appendChild call causes us to run constructors for the
// browser element, which fires off a bunch of notifications. Some
// of those notifications can cause code to run that inspects our
// state, so it is important that the tab element is fully
// initialized by this point.
this.mPanelContainer.appendChild(notificationbox);
}
this.tabContainer.updateVisibility(); this.tabContainer.updateVisibility();
// wire up a progress listener for the new browser object. let options = {
var tabListener = this.mTabProgressListener(t, b, uriIsAboutBlank, usingPreloadedContent); referrerURI : aReferrerURI,
const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"] referrerPolicy : aReferrerPolicy,
.createInstance(Components.interfaces.nsIWebProgress); charset : aCharset,
filter.addProgressListener(tabListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL); postData : aPostData,
b.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL); allowThirdPartyFixup : aAllowThirdPartyFixup,
this._tabListeners.set(t, tabListener); fromExternal : aFromExternal,
this._tabFilters.set(t, filter); allowMixedContent : aAllowMixedContent,
forceNotRemote : aForceNotRemote,
noReferrer : aNoReferrer,
userContextId : aUserContextId
};
b.droppedLinkHandler = handleDroppedLink; // Currently in this incarnation of bug 906076, we are forcing the
// browser to immediately be linked. In future incarnations of this
// bug this will be removed so we can leave the tab in its "lazy"
// state to be exploited for startup optimization. Note that for
// now this must occur before "TabOpen" event is fired, as that will
// trigger SessionStore.jsm to run code that expects the existence
// of tab.linkedBrowser.
let { usingPreloadedContent } = this._linkBrowserToTab(t, aURI, options);
let b = t.linkedBrowser;
// Dispatch a new tab notification. We do this once we're // Dispatch a new tab notification. We do this once we're
// entirely done, so that things are in a consistent state // entirely done, so that things are in a consistent state
@ -2005,23 +2070,6 @@
} }
} }
// We start our browsers out as inactive, and then maintain
// activeness in the tab switcher.
b.docShellIsActive = false;
// When addTab() is called with an URL that is not "about:blank" we
// set the "nodefaultsrc" attribute that prevents a frameLoader
// from being created as soon as the linked <browser> is inserted
// into the DOM. We thus have to register the new outerWindowID
// for non-remote browsers after we have called browser.loadURI().
//
// Note: Only do this of we still have a docShell. The TabOpen
// event was dispatched above and a gBrowser.removeTab() call from
// one of its listeners could cause us to fail here.
if (!remote && b.docShell) {
this._outerWindowIDBrowserMap.set(b.outerWindowID, b);
}
// Check if we're opening a tab related to the current tab and // Check if we're opening a tab related to the current tab and
// move it to after the current tab. // move it to after the current tab.
// aReferrerURI is null or undefined if the tab is opened from // aReferrerURI is null or undefined if the tab is opened from
@ -4266,6 +4314,7 @@
} }
} }
return undefined;
]]></body> ]]></body>
</method> </method>

View File

@ -321,7 +321,7 @@ skip-if = !datareporting
[browser_devices_get_user_media.js] [browser_devices_get_user_media.js]
skip-if = buildapp == 'mulet' || (os == "linux" && debug) # linux: bug 976544 skip-if = buildapp == 'mulet' || (os == "linux" && debug) # linux: bug 976544
[browser_devices_get_user_media_about_urls.js] [browser_devices_get_user_media_about_urls.js]
skip-if = e10s # Bug 1071623 skip-if = e10s && debug
[browser_devices_get_user_media_in_frame.js] [browser_devices_get_user_media_in_frame.js]
[browser_discovery.js] [browser_discovery.js]
[browser_double_close_tab.js] [browser_double_close_tab.js]

View File

@ -16,12 +16,14 @@ add_task(function*() {
Services.prefs.setBoolPref("browser.urlbar.unifiedcomplete", ucpref); Services.prefs.setBoolPref("browser.urlbar.unifiedcomplete", ucpref);
}); });
let maxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");
registerCleanupFunction(function* () { registerCleanupFunction(function* () {
yield PlacesTestUtils.clearHistory(); yield PlacesTestUtils.clearHistory();
}); });
let visits = []; let visits = [];
repeat(10, i => { repeat(maxResults, i => {
visits.push({ visits.push({
uri: makeURI("http://example.com/autocomplete/?" + i), uri: makeURI("http://example.com/autocomplete/?" + i),
}); });
@ -34,20 +36,20 @@ add_task(function*() {
let popup = gURLBar.popup; let popup = gURLBar.popup;
let results = popup.richlistbox.children; let results = popup.richlistbox.children;
// 1 extra for the current search engine match is(results.length, maxResults,
is(results.length, 11, "Should get 11 results"); "Should get maxResults=" + maxResults + " results");
is_selected(0); is_selected(0);
info("Key Down to select the next item"); info("Key Down to select the next item");
EventUtils.synthesizeKey("VK_DOWN", {}); EventUtils.synthesizeKey("VK_DOWN", {});
is_selected(1); is_selected(1);
info("Key Down 11 times should wrap around all the way around"); info("Key Down maxResults times should wrap around all the way around");
repeat(11, () => EventUtils.synthesizeKey("VK_DOWN", {})); repeat(maxResults, () => EventUtils.synthesizeKey("VK_DOWN", {}));
is_selected(1); is_selected(1);
info("Key Up 11 times should wrap around the other way"); info("Key Up maxResults times should wrap around the other way");
repeat(11, () => EventUtils.synthesizeKey("VK_UP", {})); repeat(maxResults, () => EventUtils.synthesizeKey("VK_UP", {}));
is_selected(1); is_selected(1);
info("Page Up will go up the list, but not wrap"); info("Page Up will go up the list, but not wrap");
@ -56,7 +58,7 @@ add_task(function*() {
info("Page Up again will wrap around to the end of the list"); info("Page Up again will wrap around to the end of the list");
EventUtils.synthesizeKey("VK_PAGE_UP", {}) EventUtils.synthesizeKey("VK_PAGE_UP", {})
is_selected(10); is_selected(maxResults - 1);
EventUtils.synthesizeKey("VK_ESCAPE", {}); EventUtils.synthesizeKey("VK_ESCAPE", {});
yield promisePopupHidden(gURLBar.popup); yield promisePopupHidden(gURLBar.popup);

View File

@ -11,6 +11,8 @@ let LOGIN_FILL_ITEMS = [
], null, ], null,
]; ];
let hasPocket = Services.prefs.getBoolPref("extensions.pocket.enabled");
add_task(function* test_setup() { add_task(function* test_setup() {
const example_base = "http://example.com/browser/browser/base/content/test/general/"; const example_base = "http://example.com/browser/browser/base/content/test/general/";
const url = example_base + "subtst_contextmenu.html"; const url = example_base + "subtst_contextmenu.html";
@ -38,6 +40,7 @@ add_task(function* test_plaintext() {
"context-bookmarkpage", true], null, "context-bookmarkpage", true], null,
"---", null, "---", null,
"context-savepage", true, "context-savepage", true,
...(hasPocket ? ["context-pocket", true] : []),
"---", null, "---", null,
"context-viewbgimage", false, "context-viewbgimage", false,
"context-selectall", true, "context-selectall", true,
@ -56,6 +59,7 @@ add_task(function* test_link() {
"---", null, "---", null,
"context-bookmarklink", true, "context-bookmarklink", true,
"context-savelink", true, "context-savelink", true,
...(hasPocket ? ["context-savelinktopocket", true] : []),
"context-copylink", true, "context-copylink", true,
"context-searchselect", true "context-searchselect", true
] ]
@ -196,6 +200,7 @@ add_task(function* test_iframe() {
"context-bookmarkpage", true], null, "context-bookmarkpage", true], null,
"---", null, "---", null,
"context-savepage", true, "context-savepage", true,
...(hasPocket ? ["context-pocket", true] : []),
"---", null, "---", null,
"context-viewbgimage", false, "context-viewbgimage", false,
"context-selectall", true, "context-selectall", true,
@ -460,6 +465,7 @@ add_task(function* test_pagemenu() {
"+Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}], null, "+Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}], null,
"---", null, "---", null,
"context-savepage", true, "context-savepage", true,
...(hasPocket ? ["context-pocket", true] : []),
"---", null, "---", null,
"context-viewbgimage", false, "context-viewbgimage", false,
"context-selectall", true, "context-selectall", true,
@ -490,6 +496,7 @@ add_task(function* test_dom_full_screen() {
"context-leave-dom-fullscreen", true, "context-leave-dom-fullscreen", true,
"---", null, "---", null,
"context-savepage", true, "context-savepage", true,
...(hasPocket ? ["context-pocket", true] : []),
"---", null, "---", null,
"context-viewbgimage", false, "context-viewbgimage", false,
"context-selectall", true, "context-selectall", true,
@ -535,6 +542,7 @@ add_task(function* test_pagemenu2() {
"context-bookmarkpage", true], null, "context-bookmarkpage", true], null,
"---", null, "---", null,
"context-savepage", true, "context-savepage", true,
...(hasPocket ? ["context-pocket", true] : []),
"---", null, "---", null,
"context-viewbgimage", false, "context-viewbgimage", false,
"context-selectall", true, "context-selectall", true,
@ -603,6 +611,7 @@ add_task(function* test_imagelink() {
"---", null, "---", null,
"context-bookmarklink", true, "context-bookmarklink", true,
"context-savelink", true, "context-savelink", true,
...(hasPocket ? ["context-savelinktopocket", true] : []),
"context-copylink", true, "context-copylink", true,
"---", null, "---", null,
"context-viewimage", true, "context-viewimage", true,
@ -701,6 +710,7 @@ add_task(function* test_click_to_play_blocked_plugin() {
"context-ctp-hide", true, "context-ctp-hide", true,
"---", null, "---", null,
"context-savepage", true, "context-savepage", true,
...(hasPocket ? ["context-pocket", true] : []),
"---", null, "---", null,
"context-viewbgimage", false, "context-viewbgimage", false,
"context-selectall", true, "context-selectall", true,
@ -744,6 +754,7 @@ add_task(function* test_srcdoc() {
"context-bookmarkpage", true], null, "context-bookmarkpage", true], null,
"---", null, "---", null,
"context-savepage", true, "context-savepage", true,
...(hasPocket ? ["context-pocket", true] : []),
"---", null, "---", null,
"context-viewbgimage", false, "context-viewbgimage", false,
"context-selectall", true, "context-selectall", true,

View File

@ -1,6 +1,8 @@
"use strict"; "use strict";
let contextMenu; let contextMenu;
let hasPocket = Services.prefs.getBoolPref("extensions.pocket.enabled");
add_task(function* test_setup() { add_task(function* test_setup() {
const example_base = "http://example.com/browser/browser/base/content/test/general/"; const example_base = "http://example.com/browser/browser/base/content/test/general/";
const url = example_base + "subtst_contextmenu_input.html"; const url = example_base + "subtst_contextmenu_input.html";
@ -187,6 +189,7 @@ add_task(function* test_date_time_color_range_input() {
"context-bookmarkpage", true], null, "context-bookmarkpage", true], null,
"---", null, "---", null,
"context-savepage", true, "context-savepage", true,
...(hasPocket ? ["context-pocket", true] : []),
"---", null, "---", null,
"context-viewbgimage", false, "context-viewbgimage", false,
"context-selectall", null, "context-selectall", null,

View File

@ -58,37 +58,8 @@ function loadPage(aUrl) {
return deferred.promise; return deferred.promise;
} }
// A fake about module to map get_user_media.html to different about urls.
function fakeLoopAboutModule() {
}
fakeLoopAboutModule.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
newChannel: function (aURI, aLoadInfo) {
let rootDir = getRootDirectory(gTestPath);
let uri = Services.io.newURI(rootDir + "get_user_media.html", null, null);
let chan = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
chan.owner = Services.scriptSecurityManager.getSystemPrincipal();
return chan;
},
getURIFlags: function (aURI) {
return Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT |
Ci.nsIAboutModule.ALLOW_SCRIPT |
Ci.nsIAboutModule.URI_CAN_LOAD_IN_CHILD |
Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT;
}
};
var factory = XPCOMUtils._getFactory(fakeLoopAboutModule);
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
var classIDLoopconversation, classIDEvil;
registerCleanupFunction(function() { registerCleanupFunction(function() {
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
registrar.unregisterFactory(classIDLoopconversation, factory);
registrar.unregisterFactory(classIDEvil, factory);
}); });
const permissionError = "error: SecurityError: The operation is insecure."; const permissionError = "error: SecurityError: The operation is insecure.";
@ -181,19 +152,46 @@ function test() {
gTab.linkedBrowser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true); gTab.linkedBrowser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
classIDLoopconversation = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator).generateUUID();
registrar.registerFactory(classIDLoopconversation, "",
"@mozilla.org/network/protocol/about;1?what=loopconversation",
factory);
classIDEvil = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator).generateUUID();
registrar.registerFactory(classIDEvil, "",
"@mozilla.org/network/protocol/about;1?what=evil",
factory);
Task.spawn(function () { Task.spawn(function () {
yield ContentTask.spawn(gBrowser.selectedBrowser,
getRootDirectory(gTestPath) + "get_user_media.html",
function* (url) {
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
/* A fake about module to map get_user_media.html to different about urls. */
function fakeLoopAboutModule() {
}
fakeLoopAboutModule.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
newChannel: function (aURI, aLoadInfo) {
let uri = Services.io.newURI(url, null, null);
let chan = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
chan.owner = Services.scriptSecurityManager.getSystemPrincipal();
return chan;
},
getURIFlags: function (aURI) {
return Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT |
Ci.nsIAboutModule.ALLOW_SCRIPT |
Ci.nsIAboutModule.URI_CAN_LOAD_IN_CHILD |
Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT;
}
};
var factory = XPCOMUtils._getFactory(fakeLoopAboutModule);
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
let UUIDGenerator = Components.classes["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator);
registrar.registerFactory(UUIDGenerator.generateUUID(), "",
"@mozilla.org/network/protocol/about;1?what=loopconversation",
factory);
registrar.registerFactory(UUIDGenerator.generateUUID(), "",
"@mozilla.org/network/protocol/about;1?what=evil",
factory);
});
yield new Promise(resolve => SpecialPowers.pushPrefEnv({ yield new Promise(resolve => SpecialPowers.pushPrefEnv({
"set": [[PREF_PERMISSION_FAKE, true], "set": [[PREF_PERMISSION_FAKE, true],
["media.getusermedia.screensharing.enabled", true]], ["media.getusermedia.screensharing.enabled", true]],
@ -206,6 +204,19 @@ function test() {
// Cleanup before the next test // Cleanup before the next test
expectNoObserverCalled(); expectNoObserverCalled();
} }
yield ContentTask.spawn(gBrowser.selectedBrowser, null,
function* () {
const Ci = Components.interfaces;
const Cc = Components.classes;
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
let cid = Cc["@mozilla.org/network/protocol/about;1?what=loopconversation"];
registrar.unregisterFactory(cid,
registrar.getClassObject(cid, Ci.nsIFactory));
cid = Cc["@mozilla.org/network/protocol/about;1?what=evil"];
registrar.unregisterFactory(cid,
registrar.getClassObject(cid, Ci.nsIFactory));
});
}).then(finish, ex => { }).then(finish, ex => {
ok(false, "Unexpected Exception: " + ex); ok(false, "Unexpected Exception: " + ex);
finish(); finish();

View File

@ -15,6 +15,8 @@ function is_selected(index) {
is(gURLBar.popup.richlistbox.selectedIndex, index, `Item ${index + 1} should be selected`); is(gURLBar.popup.richlistbox.selectedIndex, index, `Item ${index + 1} should be selected`);
} }
let gMaxResults;
add_task(function*() { add_task(function*() {
registerCleanupFunction(function* () { registerCleanupFunction(function* () {
yield PlacesTestUtils.clearHistory(); yield PlacesTestUtils.clearHistory();
@ -23,8 +25,10 @@ add_task(function*() {
yield PlacesTestUtils.clearHistory(); yield PlacesTestUtils.clearHistory();
let tabCount = gBrowser.tabs.length; let tabCount = gBrowser.tabs.length;
gMaxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");
let visits = []; let visits = [];
repeat(10, i => { repeat(gMaxResults, i => {
visits.push({ visits.push({
uri: makeURI("http://example.com/autocomplete/?" + i), uri: makeURI("http://example.com/autocomplete/?" + i),
}); });
@ -44,7 +48,8 @@ function* do_test() {
let popup = gURLBar.popup; let popup = gURLBar.popup;
let results = popup.richlistbox.children; let results = popup.richlistbox.children;
is(results.length, 11, "Should get 11 results"); is(results.length, gMaxResults,
"Should get gMaxResults=" + gMaxResults + " results");
let initiallySelected = gURLBar.popup.richlistbox.selectedIndex; let initiallySelected = gURLBar.popup.richlistbox.selectedIndex;

View File

@ -62,6 +62,7 @@ function getVisibleMenuItems(aMenu, aData) {
} else if (item.id.indexOf("spell-check-dictionary-") != 0 && } else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
item.id != "spell-no-suggestions" && item.id != "spell-no-suggestions" &&
item.id != "spell-add-dictionaries-main" && item.id != "spell-add-dictionaries-main" &&
item.id != "context-savelinktopocket" &&
item.id != "fill-login-saved-passwords" && item.id != "fill-login-saved-passwords" &&
item.id != "fill-login-no-logins") { item.id != "fill-login-no-logins") {
ok(key, "menuitem " + item.id + " has an access key"); ok(key, "menuitem " + item.id + " has an access key");

View File

@ -1360,9 +1360,16 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
var popupDirection = aElement.ownerDocument.defaultView.getComputedStyle(aElement).direction; var popupDirection = aElement.ownerDocument.defaultView.getComputedStyle(aElement).direction;
this.style.direction = popupDirection; this.style.direction = popupDirection;
// Move left margin to the window border. // Make the popup's starting margin negaxtive so that the start of the
// popup aligns with the window border.
let elementRect = aElement.getBoundingClientRect(); let elementRect = aElement.getBoundingClientRect();
this.style.marginLeft = "-" + (elementRect.left - rect.left) + "px"; if (popupDirection == "rtl") {
let offset = elementRect.right - rect.right
this.style.marginRight = offset + "px";
} else {
let offset = rect.left - elementRect.left;
this.style.marginLeft = offset + "px";
}
// Position the popup below the navbar. To get the y-coordinate, // Position the popup below the navbar. To get the y-coordinate,
// which is an offset from the bottom of the input, subtract the // which is an offset from the bottom of the input, subtract the

View File

@ -2134,7 +2134,8 @@ var CustomizableUIInternal = {
dispatchToolboxEvent: function(aEventType, aDetails={}, aWindow=null) { dispatchToolboxEvent: function(aEventType, aDetails={}, aWindow=null) {
if (aWindow) { if (aWindow) {
return this._dispatchToolboxEventToWindow(aEventType, aDetails, aWindow); this._dispatchToolboxEventToWindow(aEventType, aDetails, aWindow);
return;
} }
for (let [win, ] of gBuildWindows) { for (let [win, ] of gBuildWindows) {
this._dispatchToolboxEventToWindow(aEventType, aDetails, win); this._dispatchToolboxEventToWindow(aEventType, aDetails, win);
@ -2418,6 +2419,7 @@ var CustomizableUIInternal = {
aArgs); aArgs);
} catch (e) { } catch (e) {
Cu.reportError(e); Cu.reportError(e);
return undefined;
} }
}; };
}, },
@ -3912,7 +3914,7 @@ function XULWidgetGroupWrapper(aWidgetId) {
}); });
this.__defineGetter__("instances", function() { this.__defineGetter__("instances", function() {
return Array.from(gBuildWindows, ([win,]) => this.forWindow(win)); return Array.from(gBuildWindows, (wins) => this.forWindow(wins[0]));
}); });
Object.freeze(this); Object.freeze(this);

View File

@ -128,6 +128,7 @@ function checkBookmarksItemsChevronContextMenu() {
if (child.style.visibility != "hidden") if (child.style.visibility != "hidden")
return true; return true;
} }
return false;
}); });
yield checkPlacesContextMenu(chevronPopup); yield checkPlacesContextMenu(chevronPopup);
info("Waiting for bookmark toolbar item chevron popup to close"); info("Waiting for bookmark toolbar item chevron popup to close");

View File

@ -195,11 +195,11 @@ CommandList.prototype = {
*/ */
getModifiersAttribute(chromeModifiers) { getModifiersAttribute(chromeModifiers) {
let modifiersMap = { let modifiersMap = {
"Alt" : "alt", "Alt": "alt",
"Command" : "accel", "Command": "accel",
"Ctrl" : "accel", "Ctrl": "accel",
"MacCtrl" : "control", "MacCtrl": "control",
"Shift" : "shift", "Shift": "shift",
}; };
return Array.from(chromeModifiers, modifier => { return Array.from(chromeModifiers, modifier => {
return modifiersMap[modifier]; return modifiersMap[modifier];

View File

@ -58,6 +58,7 @@ support-files =
[browser_ext_windows_create.js] [browser_ext_windows_create.js]
tags = fullscreen tags = fullscreen
[browser_ext_windows_create_tabId.js] [browser_ext_windows_create_tabId.js]
[browser_ext_windows_events.js]
[browser_ext_windows.js] [browser_ext_windows.js]
[browser_ext_windows_size.js] [browser_ext_windows_size.js]
skip-if = os == 'mac' # Fails when windows are randomly opened in fullscreen mode skip-if = os == 'mac' # Fails when windows are randomly opened in fullscreen mode

View File

@ -122,11 +122,11 @@ add_task(function* () {
// Set focus to some other window. // Set focus to some other window.
yield focusWindow(window); yield focusWindow(window);
yield triggerPopup(win1, function*() { yield triggerPopup(win1, function* () {
yield checkWindow("popup", winId1, "win1"); yield checkWindow("popup", winId1, "win1");
}); });
yield triggerPopup(win2, function*() { yield triggerPopup(win2, function* () {
yield checkWindow("popup", winId2, "win2"); yield checkWindow("popup", winId2, "win2");
}); });

View File

@ -140,12 +140,12 @@ add_task(function* () {
// short timeout seems to consistently fix it. // short timeout seems to consistently fix it.
yield new Promise(resolve => win1.setTimeout(resolve, 10)); yield new Promise(resolve => win1.setTimeout(resolve, 10));
yield triggerPopup(win1, function*() { yield triggerPopup(win1, function* () {
yield checkViews("background", 2, 1); yield checkViews("background", 2, 1);
yield checkViews("popup", 2, 1); yield checkViews("popup", 2, 1);
}); });
yield triggerPopup(win2, function*() { yield triggerPopup(win2, function* () {
yield checkViews("background", 2, 1); yield checkViews("background", 2, 1);
yield checkViews("popup", 2, 1); yield checkViews("popup", 2, 1);
}); });
@ -165,7 +165,7 @@ add_task(function* () {
info("opening win1 popup"); info("opening win1 popup");
yield triggerPopup(win1, function*() { yield triggerPopup(win1, function* () {
yield checkViews("background", 1, 1); yield checkViews("background", 1, 1);
yield checkViews("tab", 1, 1); yield checkViews("tab", 1, 1);
yield checkViews("popup", 1, 1); yield checkViews("popup", 1, 1);
@ -173,7 +173,7 @@ add_task(function* () {
info("opening win2 popup"); info("opening win2 popup");
yield triggerPopup(win2, function*() { yield triggerPopup(win2, function* () {
yield checkViews("background", 1, 1); yield checkViews("background", 1, 1);
yield checkViews("tab", 1, 1); yield checkViews("tab", 1, 1);
yield checkViews("popup", 1, 1); yield checkViews("popup", 1, 1);

View File

@ -226,3 +226,34 @@ add_task(function* test_tab_options() {
yield BrowserTestUtils.removeTab(tab); yield BrowserTestUtils.removeTab(tab);
}); });
add_task(function* test_options_no_manifest() {
let extension = yield loadExtension({
manifest: {},
background: function() {
browser.test.log("Try to open options page when not specified in the manifest.");
browser.runtime.openOptionsPage().then(
() => {
browser.test.fail("Opening options page without one specified in the manifest generated an error");
browser.test.notifyFail("options-no-manifest");
},
error => {
let expected = "No `options_ui` declared";
browser.test.assertTrue(
error.message.includes(expected),
`Got expected error (got: '${error.message}', expected: '${expected}'`);
}
).then(() => {
browser.test.notifyPass("options-no-manifest");
}).catch(error => {
browser.test.log(`Error: ${error} :: ${error.stack}`);
browser.test.notifyFail("options-no-manifest");
});
},
});
yield extension.awaitFinish("options-no-manifest");
yield extension.unload();
});

View File

@ -13,6 +13,17 @@ add_task(function* testWindowCreate() {
}); });
}; };
let promiseTabUpdated = (expected) => {
return new Promise(resolve => {
browser.tabs.onUpdated.addListener(function listener(tabId, changeInfo, tab) {
if (changeInfo.url === expected) {
browser.tabs.onUpdated.removeListener(listener);
resolve();
}
});
});
};
let windowId; let windowId;
browser.windows.getCurrent().then(window => { browser.windows.getCurrent().then(window => {
windowId = window.id; windowId = window.id;
@ -85,6 +96,35 @@ add_task(function* testWindowCreate() {
browser.test.assertTrue(/`incognito` property must match the incognito state of tab/.test(error.message), browser.test.assertTrue(/`incognito` property must match the incognito state of tab/.test(error.message),
"Create call failed as expected"); "Create call failed as expected");
}); });
}).then(() => {
browser.test.log("Try to create a window with an invalid tabId");
return browser.windows.create({tabId: 0}).then(
window => {
browser.test.fail("Create call should have failed");
},
error => {
browser.test.assertTrue(/Invalid tab ID: 0/.test(error.message),
"Create call failed as expected");
}
);
}).then(() => {
browser.test.log("Try to create a window with two URLs");
return browser.windows.create({url: ["http://example.com/", "http://example.org/"]});
}).then(window => {
return Promise.all([
promiseTabUpdated("http://example.com/"),
promiseTabUpdated("http://example.org/"),
Promise.resolve(window),
]);
}).then(([, , window]) => {
return browser.windows.get(window.id, {populate: true});
}).then(window => {
browser.test.assertEq(2, window.tabs.length, "2 tabs were opened in new window");
browser.test.assertEq("http://example.com/", window.tabs[0].url, "Correct URL was loaded in tab 1");
browser.test.assertEq("http://example.org/", window.tabs[1].url, "Correct URL was loaded in tab 2");
return browser.windows.remove(window.id);
}).then(() => { }).then(() => {
browser.test.notifyPass("window-create"); browser.test.notifyPass("window-create");
}).catch(e => { }).catch(e => {

View File

@ -0,0 +1,39 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
add_task(function* testWindowsEvents() {
function background() {
browser.windows.onCreated.addListener(function listener(window) {
browser.windows.onCreated.removeListener(listener);
browser.test.assertTrue(Number.isInteger(window.id),
"Window object's id is an integer");
browser.test.assertEq("normal", window.type,
"Window object returned with the correct type");
browser.test.sendMessage("window-created", window.id);
});
browser.windows.onRemoved.addListener(function listener(windowId) {
browser.windows.onRemoved.removeListener(listener);
browser.test.assertTrue(Number.isInteger(windowId),
"windowId is an integer");
browser.test.sendMessage(`window-removed-${windowId}`);
browser.test.notifyPass("windows.events");
});
browser.test.sendMessage("ready");
}
let extension = ExtensionTestUtils.loadExtension({
background: `(${background})()`,
});
yield extension.startup();
yield extension.awaitMessage("ready");
let win1 = yield BrowserTestUtils.openNewBrowserWindow();
let windowId = yield extension.awaitMessage("window-created");
yield BrowserTestUtils.closeWindow(win1);
yield extension.awaitMessage(`window-removed-${windowId}`);
yield extension.awaitFinish("windows.events");
yield extension.unload();
});

View File

@ -3,6 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<script type="application/javascript"> <script type="application/javascript">
"use strict";
throw new Error(`WebExt Privilege Escalation: BrowserAction: typeof(browser) = ${typeof(browser)}`); throw new Error(`WebExt Privilege Escalation: BrowserAction: typeof(browser) = ${typeof(browser)}`);
</script> </script>
</head> </head>

View File

@ -3,6 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<script type="application/javascript"> <script type="application/javascript">
"use strict";
throw new Error(`WebExt Privilege Escalation: PageAction: typeof(browser) = ${typeof(browser)}`); throw new Error(`WebExt Privilege Escalation: PageAction: typeof(browser) = ${typeof(browser)}`);
</script> </script>
</head> </head>

View File

@ -78,10 +78,8 @@ function getBrowserActionPopup(extension, win = window) {
if (group.areaType == CustomizableUI.TYPE_TOOLBAR) { if (group.areaType == CustomizableUI.TYPE_TOOLBAR) {
return win.document.getElementById("customizationui-widget-panel"); return win.document.getElementById("customizationui-widget-panel");
} else {
return win.PanelUI.panel;
} }
return null; return win.PanelUI.panel;
} }
var clickBrowserAction = Task.async(function* (extension, win = window) { var clickBrowserAction = Task.async(function* (extension, win = window) {

View File

@ -478,6 +478,7 @@ ESEDB.prototype = {
systemTime.wSecond, systemTime.wSecond,
systemTime.wMilliseconds)); systemTime.wMilliseconds));
} }
return undefined;
}, },
_getColumnInfo(tableName, columns) { _getColumnInfo(tableName, columns) {

View File

@ -872,6 +872,7 @@ WindowsVaultFormPasswords.prototype = {
if (aOnlyCheckExists) { if (aOnlyCheckExists) {
return false; return false;
} }
return undefined;
} }
}; };

View File

@ -161,6 +161,7 @@ var MigrationWizard = {
else else
this._selectedProfile = null; this._selectedProfile = null;
} }
return undefined;
}, },
// 2 - [Profile Selection] // 2 - [Profile Selection]

View File

@ -1436,7 +1436,22 @@
BrowserSearch.searchBar.openSuggestionsPanel(); BrowserSearch.searchBar.openSuggestionsPanel();
}, },
onError: function(errorCode) { onError: function(errorCode) {
Components.utils.reportError("Error adding search engine: " + errorCode); if (errorCode != Ci.nsISearchInstallCallback.ERROR_DUPLICATE_ENGINE) {
// Download error is shown by the search service
return;
}
const kSearchBundleURI = "chrome://global/locale/search/search.properties";
let searchBundle = Services.strings.createBundle(kSearchBundleURI);
let brandBundle = document.getElementById("bundle_brand");
let brandName = brandBundle.getString("brandShortName");
let title = searchBundle.GetStringFromName("error_invalid_engine_title");
let text = searchBundle.formatStringFromName("error_duplicate_engine_msg",
[brandName, target.getAttribute("uri")], 2);
Services.prompt.QueryInterface(Ci.nsIPromptFactory);
let prompt = Services.prompt.getPrompt(gBrowser.contentWindow, Ci.nsIPrompt);
prompt.QueryInterface(Ci.nsIWritablePropertyBag2);
prompt.setPropertyAsBool("allowTabModal", true);
prompt.alert(title, text);
} }
} }
Services.search.addEngine(target.getAttribute("uri"), null, Services.search.addEngine(target.getAttribute("uri"), null,

View File

@ -27,6 +27,7 @@ function waitForConditionPromise(condition, timeoutMsg, tryCount=NUMBER_OF_TRIES
} }
tries++; tries++;
setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
return undefined;
} }
setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
return defer.promise; return defer.promise;

View File

@ -1822,6 +1822,7 @@ Experiments.ExperimentEntry.prototype = {
this._log.error("_installAddon() - onInstallStarted, wrong addon type"); this._log.error("_installAddon() - onInstallStarted, wrong addon type");
return false; return false;
} }
return undefined;
}, },
onInstallEnded: install => { onInstallEnded: install => {

View File

@ -1,3 +1,3 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 1.4.185 Current extension version is: 1.4.213

View File

@ -1023,14 +1023,18 @@ PdfStreamConverter.prototype = {
// Keep the URL the same so the browser sees it as the same. // Keep the URL the same so the browser sees it as the same.
channel.originalURI = aRequest.URI; channel.originalURI = aRequest.URI;
channel.loadGroup = aRequest.loadGroup; channel.loadGroup = aRequest.loadGroup;
channel.loadInfo.originAttributes = aRequest.loadInfo.originAttributes;
// We can use resource principal when data is fetched by the chrome // We can use resource principal when data is fetched by the chrome
// make sure we reuse the origin attributes from the request channel to keep
// isolation consistent.
// e.g. useful for NoScript // e.g. useful for NoScript
var ssm = Cc['@mozilla.org/scriptsecuritymanager;1'] var ssm = Cc['@mozilla.org/scriptsecuritymanager;1']
.getService(Ci.nsIScriptSecurityManager); .getService(Ci.nsIScriptSecurityManager);
var uri = NetUtil.newURI(PDF_VIEWER_WEB_PAGE, null, null); var uri = NetUtil.newURI(PDF_VIEWER_WEB_PAGE, null, null);
var attrs = aRequest.loadInfo.originAttributes;
var resourcePrincipal; var resourcePrincipal;
resourcePrincipal = ssm.createCodebasePrincipal(uri, {}); resourcePrincipal = ssm.createCodebasePrincipal(uri, attrs);
aRequest.owner = resourcePrincipal; aRequest.owner = resourcePrincipal;
channel.asyncOpen(proxy, aContext); channel.asyncOpen(proxy, aContext);
}, },

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* globals PDFJS */ /* globals pdfjsLib */
'use strict'; 'use strict';
@ -307,8 +307,8 @@ var Stepper = (function StepperClosure() {
this.table = table; this.table = table;
if (!opMap) { if (!opMap) {
opMap = Object.create(null); opMap = Object.create(null);
for (var key in PDFJS.OPS) { for (var key in pdfjsLib.OPS) {
opMap[PDFJS.OPS[key]] = key; opMap[pdfjsLib.OPS[key]] = key;
} }
} }
}, },
@ -460,7 +460,7 @@ var Stats = (function Stats() {
manager: null, manager: null,
init: function init() { init: function init() {
this.panel.setAttribute('style', 'padding: 5px;'); this.panel.setAttribute('style', 'padding: 5px;');
PDFJS.enableStats = true; pdfjsLib.PDFJS.enableStats = true;
}, },
enabled: false, enabled: false,
active: false, active: false,

View File

@ -1,4 +1,4 @@
/* Copyright 2012 Mozilla Foundation /* Copyright 2016 Mozilla Foundation
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -12,20 +12,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* globals PDFJS, PDFBug, FirefoxCom, Stats, ProgressBar, DownloadManager, /*globals require, parseQueryString, chrome, PDFViewerApplication */
getPDFFileNameFromURL, PDFHistory, Preferences, SidebarView,
ViewHistory, Stats, PDFThumbnailViewer, URL, noContextMenuHandler,
SecondaryToolbar, PasswordPrompt, PDFPresentationMode, PDFSidebar,
PDFDocumentProperties, HandTool, Promise, PDFLinkService,
PDFOutlineViewer, PDFAttachmentViewer, OverlayManager,
PDFFindController, PDFFindBar, PDFViewer, PDFRenderingQueue,
PresentationModeState, parseQueryString, RenderingStates,
UNKNOWN_SCALE, DEFAULT_SCALE_VALUE,
IGNORE_CURRENT_POSITION_ON_ZOOM: true */
'use strict'; 'use strict';
var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf'; var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf';
var DEFAULT_SCALE_DELTA = 1.1; var DEFAULT_SCALE_DELTA = 1.1;
var MIN_SCALE = 0.25; var MIN_SCALE = 0.25;
var MAX_SCALE = 10.0; var MAX_SCALE = 10.0;
@ -41,8 +34,6 @@ function configure(PDFJS) {
PDFJS.cMapPacked = true; PDFJS.cMapPacked = true;
} }
var mozL10n = document.mozL10n || document.webL10n;
var CSS_UNITS = 96.0 / 72.0; var CSS_UNITS = 96.0 / 72.0;
var DEFAULT_SCALE_VALUE = 'auto'; var DEFAULT_SCALE_VALUE = 'auto';
@ -52,6 +43,56 @@ var MAX_AUTO_SCALE = 1.25;
var SCROLLBAR_PADDING = 40; var SCROLLBAR_PADDING = 40;
var VERTICAL_PADDING = 5; var VERTICAL_PADDING = 5;
var mozL10n = document.mozL10n || document.webL10n;
if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
/**
* Disables fullscreen support, and by extension Presentation Mode,
* in browsers which support the fullscreen API.
* @var {boolean}
*/
PDFJS.disableFullscreen = (PDFJS.disableFullscreen === undefined ?
false : PDFJS.disableFullscreen);
/**
* Enables CSS only zooming.
* @var {boolean}
*/
PDFJS.useOnlyCssZoom = (PDFJS.useOnlyCssZoom === undefined ?
false : PDFJS.useOnlyCssZoom);
/**
* The maximum supported canvas size in total pixels e.g. width * height.
* The default value is 4096 * 4096. Use -1 for no limit.
* @var {number}
*/
PDFJS.maxCanvasPixels = (PDFJS.maxCanvasPixels === undefined ?
16777216 : PDFJS.maxCanvasPixels);
/**
* Disables saving of the last position of the viewed PDF.
* @var {boolean}
*/
PDFJS.disableHistory = (PDFJS.disableHistory === undefined ?
false : PDFJS.disableHistory);
/**
* Disables creation of the text layer that used for text selection and search.
* @var {boolean}
*/
PDFJS.disableTextLayer = (PDFJS.disableTextLayer === undefined ?
false : PDFJS.disableTextLayer);
/**
* Disables maintaining the current position in the document when zooming.
*/
PDFJS.ignoreCurrentPositionOnZoom = (PDFJS.ignoreCurrentPositionOnZoom ===
undefined ? false : PDFJS.ignoreCurrentPositionOnZoom);
/** /**
* Returns scale factor for the canvas. It makes sense for the HiDPI displays. * Returns scale factor for the canvas. It makes sense for the HiDPI displays.
* @return {Object} The object with horizontal (sx) and vertical (sy) * @return {Object} The object with horizontal (sx) and vertical (sy)
@ -585,9 +626,6 @@ var Preferences = {
var FirefoxCom = (function FirefoxComClosure() { var FirefoxCom = (function FirefoxComClosure() {
return { return {
/** /**
@ -659,7 +697,7 @@ var DownloadManager = (function DownloadManagerClosure() {
downloadData: function DownloadManager_downloadData(data, filename, downloadData: function DownloadManager_downloadData(data, filename,
contentType) { contentType) {
var blobUrl = PDFJS.createObjectURL(data, contentType); var blobUrl = pdfjsLib.createObjectURL(data, contentType, false);
FirefoxCom.request('download', { FirefoxCom.request('download', {
blobUrl: blobUrl, blobUrl: blobUrl,
@ -3000,7 +3038,7 @@ var PasswordPrompt = {
var promptString = mozL10n.get('password_label', null, var promptString = mozL10n.get('password_label', null,
'Enter the password to open this PDF file.'); 'Enter the password to open this PDF file.');
if (this.reason === PDFJS.PasswordResponses.INCORRECT_PASSWORD) { if (this.reason === pdfjsLib.PasswordResponses.INCORRECT_PASSWORD) {
promptString = mozL10n.get('password_invalid', null, promptString = mozL10n.get('password_invalid', null,
'Invalid password. Please try again.'); 'Invalid password. Please try again.');
} }
@ -3241,7 +3279,6 @@ var PresentationModeState = {
FULLSCREEN: 3, FULLSCREEN: 3,
}; };
var IGNORE_CURRENT_POSITION_ON_ZOOM = false;
var DEFAULT_CACHE_SIZE = 10; var DEFAULT_CACHE_SIZE = 10;
@ -3552,19 +3589,18 @@ var PDFPageView = (function PDFPageViewClosure() {
}); });
var isScalingRestricted = false; var isScalingRestricted = false;
if (this.canvas && PDFJS.maxCanvasPixels > 0) { if (this.canvas && pdfjsLib.PDFJS.maxCanvasPixels > 0) {
var outputScale = this.outputScale; var outputScale = this.outputScale;
var pixelsInViewport = this.viewport.width * this.viewport.height; var pixelsInViewport = this.viewport.width * this.viewport.height;
var maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport);
if (((Math.floor(this.viewport.width) * outputScale.sx) | 0) * if (((Math.floor(this.viewport.width) * outputScale.sx) | 0) *
((Math.floor(this.viewport.height) * outputScale.sy) | 0) > ((Math.floor(this.viewport.height) * outputScale.sy) | 0) >
PDFJS.maxCanvasPixels) { pdfjsLib.PDFJS.maxCanvasPixels) {
isScalingRestricted = true; isScalingRestricted = true;
} }
} }
if (this.canvas) { if (this.canvas) {
if (PDFJS.useOnlyCssZoom || if (pdfjsLib.PDFJS.useOnlyCssZoom ||
(this.hasRestrictedScaling && isScalingRestricted)) { (this.hasRestrictedScaling && isScalingRestricted)) {
this.cssTransform(this.canvas, true); this.cssTransform(this.canvas, true);
@ -3598,7 +3634,7 @@ var PDFPageView = (function PDFPageViewClosure() {
}, },
cssTransform: function PDFPageView_transform(canvas, redrawAnnotations) { cssTransform: function PDFPageView_transform(canvas, redrawAnnotations) {
var CustomStyle = PDFJS.CustomStyle; var CustomStyle = pdfjsLib.CustomStyle;
// Scale canvas, canvas wrapper, and page container. // Scale canvas, canvas wrapper, and page container.
var width = this.viewport.width; var width = this.viewport.width;
@ -3718,7 +3754,7 @@ var PDFPageView = (function PDFPageViewClosure() {
var outputScale = getOutputScale(ctx); var outputScale = getOutputScale(ctx);
this.outputScale = outputScale; this.outputScale = outputScale;
if (PDFJS.useOnlyCssZoom) { if (pdfjsLib.PDFJS.useOnlyCssZoom) {
var actualSizeViewport = viewport.clone({scale: CSS_UNITS}); var actualSizeViewport = viewport.clone({scale: CSS_UNITS});
// Use a scale that will make the canvas be the original intended size // Use a scale that will make the canvas be the original intended size
// of the page. // of the page.
@ -3727,9 +3763,10 @@ var PDFPageView = (function PDFPageViewClosure() {
outputScale.scaled = true; outputScale.scaled = true;
} }
if (PDFJS.maxCanvasPixels > 0) { if (pdfjsLib.PDFJS.maxCanvasPixels > 0) {
var pixelsInViewport = viewport.width * viewport.height; var pixelsInViewport = viewport.width * viewport.height;
var maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport); var maxScale =
Math.sqrt(pdfjsLib.PDFJS.maxCanvasPixels / pixelsInViewport);
if (outputScale.sx > maxScale || outputScale.sy > maxScale) { if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
outputScale.sx = maxScale; outputScale.sx = maxScale;
outputScale.sy = maxScale; outputScale.sy = maxScale;
@ -3896,7 +3933,7 @@ var PDFPageView = (function PDFPageViewClosure() {
}, },
beforePrint: function PDFPageView_beforePrint() { beforePrint: function PDFPageView_beforePrint() {
var CustomStyle = PDFJS.CustomStyle; var CustomStyle = pdfjsLib.CustomStyle;
var pdfPage = this.pdfPage; var pdfPage = this.pdfPage;
var viewport = pdfPage.getViewport(1); var viewport = pdfPage.getViewport(1);
@ -4020,7 +4057,7 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() {
this.textDivs = []; this.textDivs = [];
var textLayerFrag = document.createDocumentFragment(); var textLayerFrag = document.createDocumentFragment();
this.textLayerRenderTask = PDFJS.renderTextLayer({ this.textLayerRenderTask = pdfjsLib.renderTextLayer({
textContent: this.textContent, textContent: this.textContent,
container: textLayerFrag, container: textLayerFrag,
viewport: this.viewport, viewport: this.viewport,
@ -4323,7 +4360,7 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() {
if (self.div) { if (self.div) {
// If an annotationLayer already exists, refresh its children's // If an annotationLayer already exists, refresh its children's
// transformation matrices. // transformation matrices.
PDFJS.AnnotationLayer.update(parameters); pdfjsLib.AnnotationLayer.update(parameters);
} else { } else {
// Create an annotation layer div and render the annotations // Create an annotation layer div and render the annotations
// if there is at least one annotation. // if there is at least one annotation.
@ -4336,7 +4373,7 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() {
self.pageDiv.appendChild(self.div); self.pageDiv.appendChild(self.div);
parameters.div = self.div; parameters.div = self.div;
PDFJS.AnnotationLayer.render(parameters); pdfjsLib.AnnotationLayer.render(parameters);
if (typeof mozL10n !== 'undefined') { if (typeof mozL10n !== 'undefined') {
mozL10n.translate(self.div); mozL10n.translate(self.div);
} }
@ -4628,7 +4665,7 @@ var PDFViewer = (function pdfViewer() {
var viewport = pdfPage.getViewport(scale * CSS_UNITS); var viewport = pdfPage.getViewport(scale * CSS_UNITS);
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
var textLayerFactory = null; var textLayerFactory = null;
if (!PDFJS.disableTextLayer) { if (!pdfjsLib.PDFJS.disableTextLayer) {
textLayerFactory = this; textLayerFactory = this;
} }
var pageView = new PDFPageView({ var pageView = new PDFPageView({
@ -4650,7 +4687,7 @@ var PDFViewer = (function pdfViewer() {
// starts to create the correct size canvas. Wait until one page is // starts to create the correct size canvas. Wait until one page is
// rendered so we don't tie up too many resources early on. // rendered so we don't tie up too many resources early on.
onePageRendered.then(function () { onePageRendered.then(function () {
if (!PDFJS.disableAutoFetch) { if (!pdfjsLib.PDFJS.disableAutoFetch) {
var getPagesLeft = pagesCount; var getPagesLeft = pagesCount;
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
pdfDocument.getPage(pageNum).then(function (pageNum, pdfPage) { pdfDocument.getPage(pageNum).then(function (pageNum, pdfPage) {
@ -4740,7 +4777,7 @@ var PDFViewer = (function pdfViewer() {
if (!noScroll) { if (!noScroll) {
var page = this._currentPageNumber, dest; var page = this._currentPageNumber, dest;
if (this._location && !IGNORE_CURRENT_POSITION_ON_ZOOM && if (this._location && !pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom &&
!(this.isInPresentationMode || this.isChangingPresentationMode)) { !(this.isInPresentationMode || this.isChangingPresentationMode)) {
page = this._location.pageNumber; page = this._location.pageNumber;
dest = [null, { name: 'XYZ' }, this._location.left, dest = [null, { name: 'XYZ' }, this._location.left,
@ -6074,7 +6111,7 @@ var PDFOutlineViewer = (function PDFOutlineViewerClosure() {
*/ */
_bindLink: function PDFOutlineViewer_bindLink(element, item) { _bindLink: function PDFOutlineViewer_bindLink(element, item) {
if (item.url) { if (item.url) {
PDFJS.addLinkAttributes(element, { url: item.url }); pdfjsLib.addLinkAttributes(element, { url: item.url });
return; return;
} }
var linkService = this.linkService; var linkService = this.linkService;
@ -6183,7 +6220,7 @@ var PDFOutlineViewer = (function PDFOutlineViewerClosure() {
this._bindLink(element, item); this._bindLink(element, item);
this._setStyles(element, item); this._setStyles(element, item);
element.textContent = element.textContent =
PDFJS.removeNullCharacters(item.title) || DEFAULT_TITLE; pdfjsLib.removeNullCharacters(item.title) || DEFAULT_TITLE;
div.appendChild(element); div.appendChild(element);
@ -6297,12 +6334,12 @@ var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() {
for (var i = 0; i < attachmentsCount; i++) { for (var i = 0; i < attachmentsCount; i++) {
var item = attachments[names[i]]; var item = attachments[names[i]];
var filename = PDFJS.getFilenameFromUrl(item.filename); var filename = pdfjsLib.getFilenameFromUrl(item.filename);
var div = document.createElement('div'); var div = document.createElement('div');
div.className = 'attachmentsItem'; div.className = 'attachmentsItem';
var button = document.createElement('button'); var button = document.createElement('button');
this._bindLink(button, item.content, filename); this._bindLink(button, item.content, filename);
button.textContent = PDFJS.removeNullCharacters(filename); button.textContent = pdfjsLib.removeNullCharacters(filename);
div.appendChild(button); div.appendChild(button);
this.container.appendChild(div); this.container.appendChild(div);
} }
@ -6355,6 +6392,8 @@ var PDFViewerApplication = {
// called once when the document is loaded // called once when the document is loaded
initialize: function pdfViewInitialize() { initialize: function pdfViewInitialize() {
configure(pdfjsLib.PDFJS);
var pdfRenderingQueue = new PDFRenderingQueue(); var pdfRenderingQueue = new PDFRenderingQueue();
pdfRenderingQueue.onIdle = this.cleanup.bind(this); pdfRenderingQueue.onIdle = this.cleanup.bind(this);
this.pdfRenderingQueue = pdfRenderingQueue; this.pdfRenderingQueue = pdfRenderingQueue;
@ -6508,6 +6547,7 @@ var PDFViewerApplication = {
this.pdfSidebar.onToggled = this.forceRendering.bind(this); this.pdfSidebar.onToggled = this.forceRendering.bind(this);
var self = this; var self = this;
var PDFJS = pdfjsLib.PDFJS;
var initializedPromise = Promise.all([ var initializedPromise = Promise.all([
Preferences.get('enableWebGL').then(function resolved(value) { Preferences.get('enableWebGL').then(function resolved(value) {
PDFJS.disableWebGL = !value; PDFJS.disableWebGL = !value;
@ -6574,6 +6614,10 @@ var PDFViewerApplication = {
}); });
}, },
run: function pdfViewRun() {
this.initialize().then(webViewerInitialized);
},
zoomIn: function pdfViewZoomIn(ticks) { zoomIn: function pdfViewZoomIn(ticks) {
var newScale = this.pdfViewer.currentScale; var newScale = this.pdfViewer.currentScale;
do { do {
@ -6610,7 +6654,7 @@ var PDFViewerApplication = {
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
var value = 'mozPrintCallback' in canvas; var value = 'mozPrintCallback' in canvas;
return PDFJS.shadow(this, 'supportsPrinting', value); return pdfjsLib.shadow(this, 'supportsPrinting', value);
}, },
get supportsFullscreen() { get supportsFullscreen() {
@ -6624,38 +6668,38 @@ var PDFViewerApplication = {
document.msFullscreenEnabled === false) { document.msFullscreenEnabled === false) {
support = false; support = false;
} }
if (support && PDFJS.disableFullscreen === true) { if (support && pdfjsLib.PDFJS.disableFullscreen === true) {
support = false; support = false;
} }
return PDFJS.shadow(this, 'supportsFullscreen', support); return pdfjsLib.shadow(this, 'supportsFullscreen', support);
}, },
get supportsIntegratedFind() { get supportsIntegratedFind() {
var support = false; var support = false;
support = FirefoxCom.requestSync('supportsIntegratedFind'); support = FirefoxCom.requestSync('supportsIntegratedFind');
return PDFJS.shadow(this, 'supportsIntegratedFind', support); return pdfjsLib.shadow(this, 'supportsIntegratedFind', support);
}, },
get supportsDocumentFonts() { get supportsDocumentFonts() {
var support = true; var support = true;
support = FirefoxCom.requestSync('supportsDocumentFonts'); support = FirefoxCom.requestSync('supportsDocumentFonts');
return PDFJS.shadow(this, 'supportsDocumentFonts', support); return pdfjsLib.shadow(this, 'supportsDocumentFonts', support);
}, },
get supportsDocumentColors() { get supportsDocumentColors() {
var support = true; var support = true;
support = FirefoxCom.requestSync('supportsDocumentColors'); support = FirefoxCom.requestSync('supportsDocumentColors');
return PDFJS.shadow(this, 'supportsDocumentColors', support); return pdfjsLib.shadow(this, 'supportsDocumentColors', support);
}, },
get loadingBar() { get loadingBar() {
var bar = new ProgressBar('#loadingBar', {}); var bar = new ProgressBar('#loadingBar', {});
return PDFJS.shadow(this, 'loadingBar', bar); return pdfjsLib.shadow(this, 'loadingBar', bar);
}, },
get supportedMouseWheelZoomModifierKeys() { get supportedMouseWheelZoomModifierKeys() {
@ -6665,15 +6709,16 @@ var PDFViewerApplication = {
}; };
support = FirefoxCom.requestSync('supportedMouseWheelZoomModifierKeys'); support = FirefoxCom.requestSync('supportedMouseWheelZoomModifierKeys');
return PDFJS.shadow(this, 'supportedMouseWheelZoomModifierKeys', support); return pdfjsLib.shadow(this, 'supportedMouseWheelZoomModifierKeys',
support);
}, },
initPassiveLoading: function pdfViewInitPassiveLoading() { initPassiveLoading: function pdfViewInitPassiveLoading() {
function FirefoxComDataRangeTransport(length, initialData) { function FirefoxComDataRangeTransport(length, initialData) {
PDFJS.PDFDataRangeTransport.call(this, length, initialData); pdfjsLib.PDFDataRangeTransport.call(this, length, initialData);
} }
FirefoxComDataRangeTransport.prototype = FirefoxComDataRangeTransport.prototype =
Object.create(PDFJS.PDFDataRangeTransport.prototype); Object.create(pdfjsLib.PDFDataRangeTransport.prototype);
FirefoxComDataRangeTransport.prototype.requestDataRange = FirefoxComDataRangeTransport.prototype.requestDataRange =
function FirefoxComDataRangeTransport_requestDataRange(begin, end) { function FirefoxComDataRangeTransport_requestDataRange(begin, end) {
FirefoxCom.request('requestDataRange', { begin: begin, end: end }); FirefoxCom.request('requestDataRange', { begin: begin, end: end });
@ -6738,7 +6783,8 @@ var PDFViewerApplication = {
setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) { setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
this.url = url; this.url = url;
try { try {
this.setTitle(decodeURIComponent(PDFJS.getFilenameFromUrl(url)) || url); this.setTitle(decodeURIComponent(
pdfjsLib.getFilenameFromUrl(url)) || url);
} catch (e) { } catch (e) {
// decodeURIComponent may throw URIError, // decodeURIComponent may throw URIError,
// fall back to using the unprocessed url in that case // fall back to using the unprocessed url in that case
@ -6849,7 +6895,7 @@ var PDFViewerApplication = {
var self = this; var self = this;
self.downloadComplete = false; self.downloadComplete = false;
var loadingTask = PDFJS.getDocument(parameters); var loadingTask = pdfjsLib.getDocument(parameters);
this.pdfLoadingTask = loadingTask; this.pdfLoadingTask = loadingTask;
loadingTask.onPassword = function passwordNeeded(updatePassword, reason) { loadingTask.onPassword = function passwordNeeded(updatePassword, reason) {
@ -6874,15 +6920,15 @@ var PDFViewerApplication = {
var loadingErrorMessage = mozL10n.get('loading_error', null, var loadingErrorMessage = mozL10n.get('loading_error', null,
'An error occurred while loading the PDF.'); 'An error occurred while loading the PDF.');
if (exception instanceof PDFJS.InvalidPDFException) { if (exception instanceof pdfjsLib.InvalidPDFException) {
// change error message also for other builds // change error message also for other builds
loadingErrorMessage = mozL10n.get('invalid_file_error', null, loadingErrorMessage = mozL10n.get('invalid_file_error', null,
'Invalid or corrupted PDF file.'); 'Invalid or corrupted PDF file.');
} else if (exception instanceof PDFJS.MissingPDFException) { } else if (exception instanceof pdfjsLib.MissingPDFException) {
// special message for missing PDF's // special message for missing PDF's
loadingErrorMessage = mozL10n.get('missing_file_error', null, loadingErrorMessage = mozL10n.get('missing_file_error', null,
'Missing PDF file.'); 'Missing PDF file.');
} else if (exception instanceof PDFJS.UnexpectedResponseException) { } else if (exception instanceof pdfjsLib.UnexpectedResponseException) {
loadingErrorMessage = mozL10n.get('unexpected_response_error', null, loadingErrorMessage = mozL10n.get('unexpected_response_error', null,
'Unexpected server response.'); 'Unexpected server response.');
} }
@ -6928,7 +6974,7 @@ var PDFViewerApplication = {
this.pdfDocument.getData().then( this.pdfDocument.getData().then(
function getDataSuccess(data) { function getDataSuccess(data) {
var blob = PDFJS.createBlob(data, 'application/pdf'); var blob = pdfjsLib.createBlob(data, 'application/pdf');
downloadManager.download(blob, url, filename); downloadManager.download(blob, url, filename);
}, },
downloadByUrl // Error occurred try downloading with just the url. downloadByUrl // Error occurred try downloading with just the url.
@ -6961,7 +7007,7 @@ var PDFViewerApplication = {
*/ */
error: function pdfViewError(message, moreInfo) { error: function pdfViewError(message, moreInfo) {
var moreInfoText = mozL10n.get('error_version_info', var moreInfoText = mozL10n.get('error_version_info',
{version: PDFJS.version || '?', build: PDFJS.build || '?'}, {version: pdfjsLib.version || '?', build: pdfjsLib.build || '?'},
'PDF.js v{{version}} (build: {{build}})') + '\n'; 'PDF.js v{{version}} (build: {{build}})') + '\n';
if (moreInfo) { if (moreInfo) {
moreInfoText += moreInfoText +=
@ -7003,7 +7049,7 @@ var PDFViewerApplication = {
// the loading bar will not be completely filled, nor will it be hidden. // the loading bar will not be completely filled, nor will it be hidden.
// To prevent displaying a partially filled loading bar permanently, we // To prevent displaying a partially filled loading bar permanently, we
// hide it when no data has been loaded during a certain amount of time. // hide it when no data has been loaded during a certain amount of time.
if (PDFJS.disableAutoFetch && percent) { if (pdfjsLib.PDFJS.disableAutoFetch && percent) {
if (this.disableAutoFetchLoadingBarTimeout) { if (this.disableAutoFetchLoadingBarTimeout) {
clearTimeout(this.disableAutoFetchLoadingBarTimeout); clearTimeout(this.disableAutoFetchLoadingBarTimeout);
this.disableAutoFetchLoadingBarTimeout = null; this.disableAutoFetchLoadingBarTimeout = null;
@ -7063,7 +7109,7 @@ var PDFViewerApplication = {
self.loadingBar.setWidth(document.getElementById('viewer')); self.loadingBar.setWidth(document.getElementById('viewer'));
if (!PDFJS.disableHistory && !self.isViewerEmbedded) { if (!pdfjsLib.PDFJS.disableHistory && !self.isViewerEmbedded) {
// The browsing history is only enabled when the viewer is standalone, // The browsing history is only enabled when the viewer is standalone,
// i.e. not when it is embedded in a web page. // i.e. not when it is embedded in a web page.
if (!self.preferenceShowPreviousViewOnLoad) { if (!self.preferenceShowPreviousViewOnLoad) {
@ -7136,7 +7182,7 @@ var PDFViewerApplication = {
pdfDocument.getJavaScript().then(function(javaScript) { pdfDocument.getJavaScript().then(function(javaScript) {
if (javaScript.length) { if (javaScript.length) {
console.warn('Warning: JavaScript is not supported'); console.warn('Warning: JavaScript is not supported');
self.fallback(PDFJS.UNSUPPORTED_FEATURES.javaScript); self.fallback(pdfjsLib.UNSUPPORTED_FEATURES.javaScript);
} }
// Hack to support auto printing. // Hack to support auto printing.
var regex = /\bprint\s*\(/; var regex = /\bprint\s*\(/;
@ -7173,8 +7219,8 @@ var PDFViewerApplication = {
console.log('PDF ' + pdfDocument.fingerprint + ' [' + console.log('PDF ' + pdfDocument.fingerprint + ' [' +
info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() + info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() +
' / ' + (info.Creator || '-').trim() + ']' + ' / ' + (info.Creator || '-').trim() + ']' +
' (PDF.js: ' + (PDFJS.version || '-') + ' (PDF.js: ' + (pdfjsLib.version || '-') +
(!PDFJS.disableWebGL ? ' [WebGL]' : '') + ')'); (!pdfjsLib.PDFJS.disableWebGL ? ' [WebGL]' : '') + ')');
var pdfTitle; var pdfTitle;
if (metadata && metadata.has('dc:title')) { if (metadata && metadata.has('dc:title')) {
@ -7195,7 +7241,7 @@ var PDFViewerApplication = {
if (info.IsAcroFormPresent) { if (info.IsAcroFormPresent) {
console.warn('Warning: AcroForm/XFA is not supported'); console.warn('Warning: AcroForm/XFA is not supported');
self.fallback(PDFJS.UNSUPPORTED_FEATURES.forms); self.fallback(pdfjsLib.UNSUPPORTED_FEATURES.forms);
} }
var versionId = String(info.PDFFormatVersion).slice(-1) | 0; var versionId = String(info.PDFFormatVersion).slice(-1) | 0;
@ -7398,18 +7444,13 @@ var PDFViewerApplication = {
}; };
function webViewerLoad(evt) {
configure(PDFJS);
PDFViewerApplication.initialize().then(webViewerInitialized);
}
function webViewerInitialized() { function webViewerInitialized() {
var file = window.location.href.split('#')[0]; var file = window.location.href.split('#')[0];
document.getElementById('openFile').setAttribute('hidden', 'true'); document.getElementById('openFile').setAttribute('hidden', 'true');
document.getElementById('secondaryOpenFile').setAttribute('hidden', 'true'); document.getElementById('secondaryOpenFile').setAttribute('hidden', 'true');
var PDFJS = pdfjsLib.PDFJS;
if (PDFViewerApplication.preferencePdfBugEnabled) { if (PDFViewerApplication.preferencePdfBugEnabled) {
// Special debugging flags in the hash section of the URL. // Special debugging flags in the hash section of the URL.
@ -7444,7 +7485,7 @@ function webViewerInitialized() {
PDFJS.verbosity = hashParams['verbosity'] | 0; PDFJS.verbosity = hashParams['verbosity'] | 0;
} }
if ('ignorecurrentpositiononzoom' in hashParams) { if ('ignorecurrentpositiononzoom' in hashParams) {
IGNORE_CURRENT_POSITION_ON_ZOOM = PDFJS.ignoreCurrentPositionOnZoom =
(hashParams['ignorecurrentpositiononzoom'] === 'true'); (hashParams['ignorecurrentpositiononzoom'] === 'true');
} }
if ('textlayer' in hashParams) { if ('textlayer' in hashParams) {
@ -7565,8 +7606,6 @@ function webViewerInitialized() {
} }
document.addEventListener('DOMContentLoaded', webViewerLoad, true);
document.addEventListener('pagerendered', function (e) { document.addEventListener('pagerendered', function (e) {
var pageNumber = e.detail.pageNumber; var pageNumber = e.detail.pageNumber;
var pageIndex = pageNumber - 1; var pageIndex = pageNumber - 1;
@ -7579,7 +7618,7 @@ document.addEventListener('pagerendered', function (e) {
thumbnailView.setImage(pageView); thumbnailView.setImage(pageView);
} }
if (PDFJS.pdfBug && Stats.enabled && pageView.stats) { if (pdfjsLib.PDFJS.pdfBug && Stats.enabled && pageView.stats) {
Stats.add(pageNumber, pageView.stats); Stats.add(pageNumber, pageView.stats);
} }
@ -7830,7 +7869,7 @@ window.addEventListener('pagechange', function pagechange(evt) {
document.getElementById('lastPage').disabled = (page >= numPages); document.getElementById('lastPage').disabled = (page >= numPages);
// we need to update stats // we need to update stats
if (PDFJS.pdfBug && Stats.enabled) { if (pdfjsLib.PDFJS.pdfBug && Stats.enabled) {
var pageView = PDFViewerApplication.pdfViewer.getPageView(page - 1); var pageView = PDFViewerApplication.pdfViewer.getPageView(page - 1);
if (pageView.stats) { if (pageView.stats) {
Stats.add(page, pageView.stats); Stats.add(page, pageView.stats);
@ -7838,6 +7877,7 @@ window.addEventListener('pagechange', function pagechange(evt) {
} }
}, true); }, true);
var zoomDisabled = false, zoomDisabledTimeout;
function handleMouseWheel(evt) { function handleMouseWheel(evt) {
var MOUSE_WHEEL_DELTA_FACTOR = 40; var MOUSE_WHEEL_DELTA_FACTOR = 40;
var ticks = (evt.type === 'DOMMouseScroll') ? -evt.detail : var ticks = (evt.type === 'DOMMouseScroll') ? -evt.detail :
@ -7857,6 +7897,10 @@ function handleMouseWheel(evt) {
} }
// Only zoom the pages, not the entire viewer. // Only zoom the pages, not the entire viewer.
evt.preventDefault(); evt.preventDefault();
// NOTE: this check must be placed *after* preventDefault.
if (zoomDisabled) {
return;
}
var previousScale = pdfViewer.currentScale; var previousScale = pdfViewer.currentScale;
@ -7874,6 +7918,12 @@ function handleMouseWheel(evt) {
pdfViewer.container.scrollLeft += dx * scaleCorrectionFactor; pdfViewer.container.scrollLeft += dx * scaleCorrectionFactor;
pdfViewer.container.scrollTop += dy * scaleCorrectionFactor; pdfViewer.container.scrollTop += dy * scaleCorrectionFactor;
} }
} else {
zoomDisabled = true;
clearTimeout(zoomDisabledTimeout);
zoomDisabledTimeout = setTimeout(function () {
zoomDisabled = false;
}, 1000);
} }
} }
@ -8138,3 +8188,12 @@ window.addEventListener('afterprint', function afterPrint(evt) {
}); });
})(); })();
function webViewerLoad() {
window.pdfjsLib = window.pdfjsDistBuildPdf;
PDFViewerApplication.run();
}
document.addEventListener('DOMContentLoaded', webViewerLoad, true);

View File

@ -273,7 +273,7 @@ var PocketContextMenu = {
"accesskey": gPocketBundle.GetStringFromName("saveLinkToPocketCmd.accesskey"), "accesskey": gPocketBundle.GetStringFromName("saveLinkToPocketCmd.accesskey"),
"oncommand": "Pocket.savePage(gContextMenu.browser, gContextMenu.linkURL);" "oncommand": "Pocket.savePage(gContextMenu.browser, gContextMenu.linkURL);"
}); });
sibling = document.getElementById("context-savelink"); let sibling = document.getElementById("context-savelink");
if (sibling.nextSibling) { if (sibling.nextSibling) {
sibling.parentNode.insertBefore(menu, sibling.nextSibling); sibling.parentNode.insertBefore(menu, sibling.nextSibling);
} else { } else {
@ -360,6 +360,7 @@ function pktUIGetter(prop, window) {
get: function() { get: function() {
// delete any getters for properties loaded from main.js so we only load main.js once // delete any getters for properties loaded from main.js so we only load main.js once
delete window.pktUI; delete window.pktUI;
delete window.pktApi;
delete window.pktUIMessaging; delete window.pktUIMessaging;
Services.scriptloader.loadSubScript("chrome://pocket/content/main.js", window); Services.scriptloader.loadSubScript("chrome://pocket/content/main.js", window);
return window[prop]; return window[prop];
@ -402,6 +403,7 @@ var PocketOverlay = {
this.removeStyles(window); this.removeStyles(window);
// remove script getters/objects // remove script getters/objects
delete window.Pocket; delete window.Pocket;
delete window.pktApi;
delete window.pktUI; delete window.pktUI;
delete window.pktUIMessaging; delete window.pktUIMessaging;
} }
@ -421,6 +423,7 @@ var PocketOverlay = {
"chrome://pocket/content/Pocket.jsm"); "chrome://pocket/content/Pocket.jsm");
// Can't use XPCOMUtils for these because the scripts try to define the variables // Can't use XPCOMUtils for these because the scripts try to define the variables
// on window, and so the defineProperty inside defineLazyGetter fails. // on window, and so the defineProperty inside defineLazyGetter fails.
Object.defineProperty(window, "pktApi", pktUIGetter("pktApi", window));
Object.defineProperty(window, "pktUI", pktUIGetter("pktUI", window)); Object.defineProperty(window, "pktUI", pktUIGetter("pktUI", window));
Object.defineProperty(window, "pktUIMessaging", pktUIGetter("pktUIMessaging", window)); Object.defineProperty(window, "pktUIMessaging", pktUIGetter("pktUIMessaging", window));
}, },

View File

@ -11,13 +11,20 @@ function checkElements(expectPresent, l) {
} }
} }
add_task(function*() { add_task(function* test_setup() {
let enabledOnStartup = yield promisePocketEnabled(); let clearValue = Services.prefs.prefHasUserValue("extensions.pocket.enabled");
let enabledOnStartup = Services.prefs.getBoolPref("extensions.pocket.enabled");
registerCleanupFunction(() => { registerCleanupFunction(() => {
// Extra insurance that this is disabled again, but it should have been set if (clearValue) {
// in promisePocketReset. Services.prefs.clearUserPref("extensions.pocket.enabled");
Services.prefs.setBoolPref("extensions.pocket.enabled", enabledOnStartup); } else {
Services.prefs.setBoolPref("extensions.pocket.enabled", enabledOnStartup);
}
}); });
});
add_task(function*() {
yield promisePocketEnabled();
checkWindowProperties(true, ["Pocket", "pktUI", "pktUIMessaging"]); checkWindowProperties(true, ["Pocket", "pktUI", "pktUIMessaging"]);
checkElements(true, ["pocket-button", "panelMenu_pocket", "menu_pocket", "BMB_pocket", checkElements(true, ["pocket-button", "panelMenu_pocket", "menu_pocket", "BMB_pocket",

View File

@ -21,6 +21,7 @@ function waitForConditionPromise(condition, timeoutMsg, tryCount=NUMBER_OF_TRIES
} }
tries++; tries++;
setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
return undefined;
} }
setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
return defer.promise; return defer.promise;

View File

@ -69,6 +69,10 @@
background-image: linear-gradient(@toolbarHighlight@, @toolbarHighlight@); background-image: linear-gradient(@toolbarHighlight@, @toolbarHighlight@);
} }
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):-moz-lwtheme {
background-image: linear-gradient(@toolbarHighlightLWT@, @toolbarHighlightLWT@);
}
#navigator-toolbox > toolbar:not(:-moz-lwtheme):not(#toolbar-menubar):not(#TabsToolbar) { #navigator-toolbox > toolbar:not(:-moz-lwtheme):not(#toolbar-menubar):not(#TabsToolbar) {
-moz-appearance: none; -moz-appearance: none;
border-style: none; border-style: none;
@ -108,6 +112,10 @@
padding-bottom: 2px; padding-bottom: 2px;
} }
#nav-bar:-moz-lwtheme {
box-shadow: 0 1px 0 @toolbarHighlightLWT@ inset;
}
#nav-bar-overflow-button { #nav-bar-overflow-button {
-moz-image-region: rect(-5px, 12px, 11px, -4px); -moz-image-region: rect(-5px, 12px, 11px, -4px);
} }
@ -1789,7 +1797,13 @@ toolbarbutton.chevron > .toolbarbutton-icon {
%include ../shared/fullscreen/warning.inc.css %include ../shared/fullscreen/warning.inc.css
%include ../../../devtools/client/themes/responsivedesign.inc.css %include ../../../devtools/client/themes/responsivedesign.inc.css
%include ../../../devtools/client/themes/commandline.inc.css %include ../../../devtools/client/themes/commandline.inc.css
%include ../shared/plugin-doorhanger.inc.css %include ../shared/plugin-doorhanger.inc.css
notification.pluginVulnerable > .notification-inner > .messageCloseButton:not(:hover) {
background-image: -moz-image-rect(url("chrome://global/skin/icons/close.svg"), 0, 80, 16, 64);
}
%include ../shared/login-doorhanger.inc.css %include ../shared/login-doorhanger.inc.css
%include downloads/indicator.css %include downloads/indicator.css

View File

@ -4,7 +4,8 @@
%filter substitution %filter substitution
%define toolbarHighlight rgba(255,255,255,.4) %define toolbarHighlight hsla(0,0%,100%,.05)
%define toolbarHighlightLWT rgba(255,255,255,.4)
%define fgTabTexture linear-gradient(transparent 2px, @toolbarHighlight@ 2px, @toolbarHighlight@) %define fgTabTexture linear-gradient(transparent 2px, @toolbarHighlight@ 2px, @toolbarHighlight@)
%define fgTabTextureLWT @fgTabTexture@ %define fgTabTextureLWT linear-gradient(transparent 2px, @toolbarHighlightLWT@ 2px, @toolbarHighlightLWT@)
%define fgTabBackgroundColor -moz-dialog %define fgTabBackgroundColor -moz-dialog

View File

@ -2501,7 +2501,19 @@ notification[value="translation"] {
%include ../shared/fullscreen/warning.inc.css %include ../shared/fullscreen/warning.inc.css
%include ../../../devtools/client/themes/responsivedesign.inc.css %include ../../../devtools/client/themes/responsivedesign.inc.css
%include ../../../devtools/client/themes/commandline.inc.css %include ../../../devtools/client/themes/commandline.inc.css
%include ../shared/plugin-doorhanger.inc.css %include ../shared/plugin-doorhanger.inc.css
notification.pluginVulnerable > .notification-inner > .messageCloseButton {
list-style-image: url("chrome://global/skin/icons/close-inverted.png");
}
@media (min-resolution: 1.1dppx) {
notification.pluginVulnerable > .notification-inner > .messageCloseButton {
list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
}
}
%include ../shared/login-doorhanger.inc.css %include ../shared/login-doorhanger.inc.css
%include downloads/indicator.css %include downloads/indicator.css

View File

@ -24,6 +24,7 @@ this.TabsInTitlebar = {
return Promise.reject("TabsInTitlebar isn't supported on Linux"); return Promise.reject("TabsInTitlebar isn't supported on Linux");
} }
Services.prefs.setBoolPref(PREF_TABS_IN_TITLEBAR, true); Services.prefs.setBoolPref(PREF_TABS_IN_TITLEBAR, true);
return undefined;
}), }),
}, },

View File

@ -37,6 +37,7 @@ this.Toolbars = {
if (browserWindow.fullScreen) { if (browserWindow.fullScreen) {
return Promise.reject("The bookmark toolbar and menubar are not shown in fullscreen."); return Promise.reject("The bookmark toolbar and menubar are not shown in fullscreen.");
} }
return undefined;
}), }),
}, },

View File

@ -71,7 +71,7 @@
// Enforce one true comma style. // Enforce one true comma style.
"comma-style": [2, "last"], "comma-style": [2, "last"],
// Warn about cyclomatic complexity in functions. // Warn about cyclomatic complexity in functions.
"complexity": 2, "complexity": [2, 35],
// Require return statements to either always or never specify values. // Require return statements to either always or never specify values.
"consistent-return": 2, "consistent-return": 2,
// Don't warn for inconsistent naming when capturing this (not so important // Don't warn for inconsistent naming when capturing this (not so important
@ -177,8 +177,6 @@
"no-empty": 2, "no-empty": 2,
// Disallow the use of empty character classes in regular expressions. // Disallow the use of empty character classes in regular expressions.
"no-empty-character-class": 2, "no-empty-character-class": 2,
// Disallow use of labels for anything other then loops and switches.
"no-empty-label": 2,
// Disallow use of eval(). We have other APIs to evaluate code in content. // Disallow use of eval(). We have other APIs to evaluate code in content.
"no-eval": 2, "no-eval": 2,
// Disallow assigning to the exception in a catch block. // Disallow assigning to the exception in a catch block.
@ -324,8 +322,8 @@
"sort-vars": 0, "sort-vars": 0,
// Deprecated, will be removed in 1.0. // Deprecated, will be removed in 1.0.
"space-after-function-name": 0, "space-after-function-name": 0,
// Require a space after keywords. // Require a space around all keywords.
"space-after-keywords": [2, "always"], "keyword-spacing": 2,
// Require a space before the start brace of a block. // Require a space before the start brace of a block.
"space-before-blocks": [2, "always"], "space-before-blocks": [2, "always"],
// Deprecated, will be removed in 1.0. // Deprecated, will be removed in 1.0.
@ -340,8 +338,6 @@
"space-in-parens": [2, "never"], "space-in-parens": [2, "never"],
// Require spaces around operators, except for a|0. // Require spaces around operators, except for a|0.
"space-infix-ops": [2, {"int32Hint": true}], "space-infix-ops": [2, {"int32Hint": true}],
// Require a space after return, throw, and case.
"space-return-throw-case": 2,
// Require spaces before/after unary operators (words on by default, // Require spaces before/after unary operators (words on by default,
// nonwords off by default). // nonwords off by default).
"space-unary-ops": [2, { "words": true, "nonwords": false }], "space-unary-ops": [2, { "words": true, "nonwords": false }],
@ -396,7 +392,7 @@
// disallow labels that share a name with a variable // disallow labels that share a name with a variable
"no-label-var": 0, "no-label-var": 0,
// disallow use of labeled statements // disallow use of labeled statements
"no-labels": 0, "no-labels": 2,
// disallow unnecessary nested blocks // disallow unnecessary nested blocks
"no-lone-blocks": 0, "no-lone-blocks": 0,
// disallow creation of functions within loops // disallow creation of functions within loops

View File

@ -47,20 +47,22 @@ button {
/* Targets */ /* Targets */
.targets { .targets {
margin-bottom: 25px; margin-bottom: 35px;
} }
.target { .target-container {
margin-top: 5px; margin-top: 5px;
min-height: 34px; min-height: 34px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: baseline;
} }
.target-icon { .target-icon {
height: 24px; height: 24px;
margin-right: 5px; margin: 6px 5px 0 0;
/* override the icon alignment and center it using margin-top */
align-self: flex-start;
} }
.target-icon:not([src]) { .target-icon:not([src]) {
@ -71,15 +73,55 @@ button {
filter: invert(30%); filter: invert(30%);
} }
.target-details { .target {
flex: 1; flex: 1;
} }
.target-details {
margin: 0;
padding: 0;
list-style-type: none
}
.target-detail {
font-size: 12px;
margin-top: 7px;
}
.target-detail a {
cursor: pointer;
}
.target-detail > :not(:first-child) {
margin-left: 8px;
}
.addons-controls { .addons-controls {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
} }
.addons-install-error {
background-color: #f3b0b0;
padding: 5px 10px;
margin: 5px 4px 5px 0px;
}
.addons-install-error .warning {
background-image: url(chrome://devtools/skin/images/alerticon-warning.png);
background-size: 13px 12px;
margin-right: 10px;
display: inline-block;
width: 13px;
height: 12px;
}
@media (min-resolution: 1.1dppx) {
.addons-install-error .warning {
background-image: url(chrome://devtools/skin/images/alerticon-warning@2x.png);
}
}
.addons-options { .addons-options {
flex: 1; flex: 1;
} }

View File

@ -23,13 +23,13 @@ module.exports = createClass({
render() { render() {
let { target, debugDisabled } = this.props; let { target, debugDisabled } = this.props;
return dom.div({ className: "target" }, return dom.div({ className: "target-container" },
dom.img({ dom.img({
className: "target-icon", className: "target-icon",
role: "presentation", role: "presentation",
src: target.icon src: target.icon
}), }),
dom.div({ className: "target-details" }, dom.div({ className: "target" },
dom.div({ className: "target-name" }, target.name) dom.div({ className: "target-name" }, target.name)
), ),
dom.button({ dom.button({

View File

@ -11,10 +11,12 @@ loader.lazyImporter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm"); "resource://gre/modules/AddonManager.jsm");
const { Cc, Ci } = require("chrome"); const { Cc, Ci } = require("chrome");
const { createClass, DOM: dom } = const { createFactory, createClass, DOM: dom } =
require("devtools/client/shared/vendor/react"); require("devtools/client/shared/vendor/react");
const Services = require("Services"); const Services = require("Services");
const AddonsInstallError = createFactory(require("./addons-install-error"));
const Strings = Services.strings.createBundle( const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties"); "chrome://devtools/locale/aboutdebugging.properties");
@ -24,10 +26,17 @@ const MORE_INFO_URL = "https://developer.mozilla.org/docs/Tools" +
module.exports = createClass({ module.exports = createClass({
displayName: "AddonsControls", displayName: "AddonsControls",
getInitialState() {
return {
installError: null,
};
},
render() { render() {
let { debugDisabled } = this.props; let { debugDisabled } = this.props;
return dom.div({ className: "addons-controls" }, return dom.div({ className: "addons-top" },
dom.div({ className: "addons-controls" },
dom.div({ className: "addons-options" }, dom.div({ className: "addons-options" },
dom.input({ dom.input({
id: "enable-addon-debugging", id: "enable-addon-debugging",
@ -49,7 +58,8 @@ module.exports = createClass({
id: "load-addon-from-file", id: "load-addon-from-file",
onClick: this.loadAddonFromFile, onClick: this.loadAddonFromFile,
}, Strings.GetStringFromName("loadTemporaryAddon")) }, Strings.GetStringFromName("loadTemporaryAddon"))
); ),
AddonsInstallError({ error: this.state.installError }));
}, },
onEnableAddonDebuggingChange(event) { onEnableAddonDebuggingChange(event) {
@ -59,6 +69,7 @@ module.exports = createClass({
}, },
loadAddonFromFile() { loadAddonFromFile() {
this.setState({ installError: null });
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(window, fp.init(window,
Strings.GetStringFromName("selectAddonFromFile2"), Strings.GetStringFromName("selectAddonFromFile2"),
@ -73,11 +84,10 @@ module.exports = createClass({
if (!file.isDirectory() && !file.leafName.endsWith(".xpi")) { if (!file.isDirectory() && !file.leafName.endsWith(".xpi")) {
file = file.parent; file = file.parent;
} }
try {
AddonManager.installTemporaryAddon(file); AddonManager.installTemporaryAddon(file)
} catch (e) { .catch(e => {
window.alert("Error while installing the addon:\n" + e.message + "\n"); this.setState({ installError: e.message });
throw e; });
}
}, },
}); });

View File

@ -0,0 +1,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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-env browser */
"use strict";
const { createClass, DOM: dom } = require("devtools/client/shared/vendor/react");
module.exports = createClass({
displayName: "AddonsInstallError",
render() {
if (!this.props.error) {
return null;
}
let text = `There was an error during installation: ${this.props.error}`;
return dom.div({ className: "addons-install-error" },
dom.div({ className: "warning" }),
dom.span({}, text));
}
});

View File

@ -6,7 +6,9 @@ DevToolsModules(
'aboutdebugging.js', 'aboutdebugging.js',
'addon-target.js', 'addon-target.js',
'addons-controls.js', 'addons-controls.js',
'addons-install-error.js',
'addons-tab.js', 'addons-tab.js',
'service-worker-target.js',
'tab-header.js', 'tab-header.js',
'tab-menu-entry.js', 'tab-menu-entry.js',
'tab-menu.js', 'tab-menu.js',

View File

@ -0,0 +1,111 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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-env browser */
"use strict";
const { createClass, DOM: dom } =
require("devtools/client/shared/vendor/react");
const { debugWorker } = require("../modules/worker");
const Services = require("Services");
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
module.exports = createClass({
displayName: "ServiceWorkerTarget",
render() {
let { target, debugDisabled } = this.props;
let isRunning = this.isRunning();
return dom.div({ className: "target-container" },
dom.img({
className: "target-icon",
role: "presentation",
src: target.icon
}),
dom.div({ className: "target" },
dom.div({ className: "target-name" }, target.name),
dom.ul({ className: "target-details" },
dom.li({ className: "target-detail" },
dom.strong(null, Strings.GetStringFromName("scope")),
dom.span({ className: "service-worker-scope" }, target.scope),
dom.a({
onClick: this.unregister,
className: "unregister-link"
}, Strings.GetStringFromName("unregister"))
)
)
),
(isRunning ?
[
dom.button({
className: "push-button",
onClick: this.push
}, Strings.GetStringFromName("push")),
dom.button({
className: "debug-button",
onClick: this.debug,
disabled: debugDisabled
}, Strings.GetStringFromName("debug"))
] :
dom.button({
className: "start-button",
onClick: this.start
}, Strings.GetStringFromName("start"))
)
);
},
debug() {
if (!this.isRunning()) {
// If the worker is not running, we can't debug it.
return;
}
let { client, target } = this.props;
debugWorker(client, target.workerActor);
},
push() {
if (!this.isRunning()) {
// If the worker is not running, we can't push to it.
return;
}
let { client, target } = this.props;
client.request({
to: target.workerActor,
type: "push"
});
},
start() {
if (this.isRunning()) {
// If the worker is already running, we can't start it.
return;
}
let { client, target } = this.props;
client.request({
to: target.registrationActor,
type: "start"
});
},
unregister() {
let { client, target } = this.props;
client.request({
to: target.registrationActor,
type: "unregister"
});
},
isRunning() {
// We know the target is running if it has a worker actor.
return !!this.props.target.workerActor;
},
});

View File

@ -3,19 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-env browser */ /* eslint-env browser */
/* globals gDevTools, TargetFactory, Toolbox */
"use strict"; "use strict";
loader.lazyRequireGetter(this, "gDevTools",
"devtools/client/framework/devtools", true);
loader.lazyRequireGetter(this, "TargetFactory",
"devtools/client/framework/target", true);
loader.lazyRequireGetter(this, "Toolbox",
"devtools/client/framework/toolbox", true);
const { createClass, DOM: dom } = const { createClass, DOM: dom } =
require("devtools/client/shared/vendor/react"); require("devtools/client/shared/vendor/react");
const { debugWorker } = require("../modules/worker");
const Services = require("Services"); const Services = require("Services");
const Strings = Services.strings.createBundle( const Strings = Services.strings.createBundle(
@ -26,86 +19,26 @@ module.exports = createClass({
render() { render() {
let { target, debugDisabled } = this.props; let { target, debugDisabled } = this.props;
let isRunning = this.isRunning();
let isServiceWorker = this.isServiceWorker();
return dom.div({ className: "target" }, return dom.div({ className: "target-container" },
dom.img({ dom.img({
className: "target-icon", className: "target-icon",
role: "presentation", role: "presentation",
src: target.icon src: target.icon
}), }),
dom.div({ className: "target-details" }, dom.div({ className: "target" },
dom.div({ className: "target-name" }, target.name) dom.div({ className: "target-name" }, target.name)
), ),
(isRunning && isServiceWorker ? dom.button({
dom.button({ className: "debug-button",
className: "push-button", onClick: this.debug,
onClick: this.push disabled: debugDisabled
}, Strings.GetStringFromName("push")) : }, Strings.GetStringFromName("debug"))
null
),
(isRunning ?
dom.button({
className: "debug-button",
onClick: this.debug,
disabled: debugDisabled
}, Strings.GetStringFromName("debug")) :
dom.button({
className: "start-button",
onClick: this.start
}, Strings.GetStringFromName("start"))
)
); );
}, },
debug() { debug() {
let { client, target } = this.props; let { client, target } = this.props;
if (!this.isRunning()) { debugWorker(client, target.workerActor);
// If the worker is not running, we can't debug it. }
return;
}
client.attachWorker(target.workerActor, (response, workerClient) => {
let workerTarget = TargetFactory.forWorker(workerClient);
gDevTools.showToolbox(workerTarget, "jsdebugger", Toolbox.HostType.WINDOW)
.then(toolbox => {
toolbox.once("destroy", () => workerClient.detach());
});
});
},
push() {
let { client, target } = this.props;
if (!this.isRunning()) {
// If the worker is not running, we can't push to it.
return;
}
client.request({
to: target.workerActor,
type: "push"
});
},
start() {
let { client, target } = this.props;
if (!this.isServiceWorker() || this.isRunning()) {
// Either the worker is already running, or it's not a service worker, in
// which case we don't know how to start it.
return;
}
client.request({
to: target.registrationActor,
type: "start"
});
},
isRunning() {
// We know the target is running if it has a worker actor.
return !!this.props.target.workerActor;
},
isServiceWorker() {
// We know the target is a service worker if it has a registration actor.
return !!this.props.target.registrationActor;
},
}); });

View File

@ -7,12 +7,13 @@
const { Ci } = require("chrome"); const { Ci } = require("chrome");
const { createClass, createFactory, DOM: dom } = const { createClass, createFactory, DOM: dom } =
require("devtools/client/shared/vendor/react"); require("devtools/client/shared/vendor/react");
const { Task } = require("resource://gre/modules/Task.jsm"); const { getWorkerForms } = require("../modules/worker");
const Services = require("Services"); const Services = require("Services");
const TabHeader = createFactory(require("./tab-header")); const TabHeader = createFactory(require("./tab-header"));
const TargetList = createFactory(require("./target-list")); const TargetList = createFactory(require("./target-list"));
const WorkerTarget = createFactory(require("./worker-target")); const WorkerTarget = createFactory(require("./worker-target"));
const ServiceWorkerTarget = createFactory(require("./service-worker-target"));
const Strings = Services.strings.createBundle( const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties"); "chrome://devtools/locale/aboutdebugging.properties");
@ -50,7 +51,6 @@ module.exports = createClass({
render() { render() {
let { client } = this.props; let { client } = this.props;
let { workers } = this.state; let { workers } = this.state;
let targetClass = WorkerTarget;
return dom.div({ return dom.div({
id: "tab-workers", id: "tab-workers",
@ -67,21 +67,21 @@ module.exports = createClass({
client, client,
id: "service-workers", id: "service-workers",
name: Strings.GetStringFromName("serviceWorkers"), name: Strings.GetStringFromName("serviceWorkers"),
targetClass, targetClass: ServiceWorkerTarget,
targets: workers.service targets: workers.service
}), }),
TargetList({ TargetList({
client, client,
id: "shared-workers", id: "shared-workers",
name: Strings.GetStringFromName("sharedWorkers"), name: Strings.GetStringFromName("sharedWorkers"),
targetClass, targetClass: WorkerTarget,
targets: workers.shared targets: workers.shared
}), }),
TargetList({ TargetList({
client, client,
id: "other-workers", id: "other-workers",
name: Strings.GetStringFromName("otherWorkers"), name: Strings.GetStringFromName("otherWorkers"),
targetClass, targetClass: WorkerTarget,
targets: workers.other targets: workers.other
}) })
)); ));
@ -90,7 +90,7 @@ module.exports = createClass({
update() { update() {
let workers = this.getInitialState().workers; let workers = this.getInitialState().workers;
this.getWorkerForms().then(forms => { getWorkerForms(this.props.client).then(forms => {
forms.registrations.forEach(form => { forms.registrations.forEach(form => {
workers.service.push({ workers.service.push({
icon: WorkerIcon, icon: WorkerIcon,
@ -136,40 +136,5 @@ module.exports = createClass({
this.setState({ workers }); this.setState({ workers });
}); });
}, }
getWorkerForms: Task.async(function*() {
let client = this.props.client;
let registrations = [];
let workers = [];
try {
// List service worker registrations
({ registrations } =
yield client.mainRoot.listServiceWorkerRegistrations());
// List workers from the Parent process
({ workers } = yield client.mainRoot.listWorkers());
// And then from the Child processes
let { processes } = yield client.mainRoot.listProcesses();
for (let process of processes) {
// Ignore parent process
if (process.parent) {
continue;
}
let { form } = yield client.getProcess(process.id);
let processActor = form.actor;
let response = yield client.request({
to: processActor,
type: "listWorkers"
});
workers = workers.concat(response.workers);
}
} catch (e) {
// Something went wrong, maybe our client is disconnected?
}
return { registrations, workers };
}),
}); });

View File

@ -0,0 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# 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/.
DevToolsModules(
'worker.js',
)

View File

@ -0,0 +1,77 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
"use strict";
const { Task } = require("resource://gre/modules/Task.jsm");
loader.lazyRequireGetter(this, "gDevTools",
"devtools/client/framework/devtools", true);
loader.lazyRequireGetter(this, "TargetFactory",
"devtools/client/framework/target", true);
loader.lazyRequireGetter(this, "Toolbox",
"devtools/client/framework/toolbox", true);
/**
* Open a window-hosted toolbox to debug the worker associated to the provided
* worker actor.
*
* @param {DebuggerClient} client
* @param {Object} workerActor
* worker actor form to debug
*/
exports.debugWorker = function(client, workerActor) {
client.attachWorker(workerActor, (response, workerClient) => {
let workerTarget = TargetFactory.forWorker(workerClient);
gDevTools.showToolbox(workerTarget, "jsdebugger", Toolbox.HostType.WINDOW)
.then(toolbox => {
toolbox.once("destroy", () => workerClient.detach());
});
});
};
/**
* Retrieve all service worker registrations as well as workers from the parent
* and child processes.
*
* @param {DebuggerClient} client
* @return {Object}
* - {Array} registrations
* Array of ServiceWorkerRegistrationActor forms
* - {Array} workers
* Array of WorkerActor forms
*/
exports.getWorkerForms = Task.async(function* (client) {
let registrations = [];
let workers = [];
try {
// List service worker registrations
({ registrations } =
yield client.mainRoot.listServiceWorkerRegistrations());
// List workers from the Parent process
({ workers } = yield client.mainRoot.listWorkers());
// And then from the Child processes
let { processes } = yield client.mainRoot.listProcesses();
for (let process of processes) {
// Ignore parent process
if (process.parent) {
continue;
}
let { form } = yield client.getProcess(process.id);
let processActor = form.actor;
let response = yield client.request({
to: processActor,
type: "listWorkers"
});
workers = workers.concat(response.workers);
}
} catch (e) {
// Something went wrong, maybe our client is disconnected?
}
return { registrations, workers };
});

View File

@ -6,6 +6,7 @@
DIRS += [ DIRS += [
'components', 'components',
'modules',
] ]
BROWSER_CHROME_MANIFESTS += [ BROWSER_CHROME_MANIFESTS += [

View File

@ -0,0 +1 @@
this is not valid json

View File

@ -5,6 +5,7 @@ support-files =
head.js head.js
addons/unpacked/bootstrap.js addons/unpacked/bootstrap.js
addons/unpacked/install.rdf addons/unpacked/install.rdf
addons/bad/manifest.json
service-workers/empty-sw.html service-workers/empty-sw.html
service-workers/empty-sw.js service-workers/empty-sw.js
service-workers/push-sw.html service-workers/push-sw.html
@ -17,4 +18,5 @@ support-files =
[browser_service_workers_push.js] [browser_service_workers_push.js]
[browser_service_workers_start.js] [browser_service_workers_start.js]
[browser_service_workers_timeout.js] [browser_service_workers_timeout.js]
[browser_service_workers_unregister.js]
skip-if = true # Bug 1232931 skip-if = true # Bug 1232931

View File

@ -28,3 +28,30 @@ add_task(function* () {
yield closeAboutDebugging(tab); yield closeAboutDebugging(tab);
}); });
add_task(function* () {
let { tab, document } = yield openAboutDebugging("addons");
// Start an observer that looks for the install error before
// actually doing the install
let top = document.querySelector(".addons-top");
let promise = waitForMutation(top, { childList: true });
// Mock the file picker to select a test addon
let MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(null);
let file = getSupportsFile("addons/bad/manifest.json");
MockFilePicker.returnFiles = [file.file];
// Trigger the file picker by clicking on the button
document.getElementById("load-addon-from-file").click();
// Now wait for the install error to appear.
yield promise;
// And check that it really is there.
let err = document.querySelector(".addons-install-error");
isnot(err, null, "Addon install error message appeared");
yield closeAboutDebugging(tab);
});

View File

@ -0,0 +1,77 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-disable mozilla/no-cpows-in-tests */
/* global sendAsyncMessage */
"use strict";
// Test that clicking on the unregister link in the Service Worker details works
// as intended in about:debugging.
// It should unregister the service worker, which should trigger an update of
// the displayed list of service workers.
// Service workers can't be loaded from chrome://, but http:// is ok with
// dom.serviceWorkers.testing.enabled turned on.
const HTTP_ROOT = CHROME_ROOT.replace(
"chrome://mochitests/content/", "http://mochi.test:8888/");
const SCOPE = HTTP_ROOT + "service-workers/";
const SERVICE_WORKER = SCOPE + "empty-sw.js";
const TAB_URL = SCOPE + "empty-sw.html";
add_task(function* () {
info("Turn on workers via mochitest http.");
yield new Promise(done => {
let options = { "set": [
// Accept workers from mochitest's http.
["dom.serviceWorkers.testing.enabled", true],
]};
SpecialPowers.pushPrefEnv(options, done);
});
let { tab, document } = yield openAboutDebugging("workers");
// Listen for mutations in the service-workers list.
let serviceWorkersElement = document.getElementById("service-workers");
let onMutation = waitForMutation(serviceWorkersElement, { childList: true });
// Open a tab that registers an empty service worker.
let swTab = yield addTab(TAB_URL);
// Wait for the service workers-list to update.
yield onMutation;
// Check that the service worker appears in the UI.
assertHasTarget(true, document, "service-workers", SERVICE_WORKER);
info("Ensure that the registration resolved before trying to interact with " +
"the service worker.");
yield waitForServiceWorkerRegistered(swTab);
ok(true, "Service worker registration resolved");
let targets = document.querySelectorAll("#service-workers .target");
is(targets.length, 1, "One service worker is now displayed.");
let target = targets[0];
let name = target.querySelector(".target-name");
is(name.textContent, SERVICE_WORKER, "Found the service worker in the list");
info("Check the scope displayed scope is correct");
let scope = target.querySelector(".service-worker-scope");
is(scope.textContent, SCOPE,
"The expected scope is displayed in the service worker info.");
info("Unregister the service worker via the unregister link.");
let unregisterLink = target.querySelector(".unregister-link");
ok(unregisterLink, "Found the unregister link");
onMutation = waitForMutation(serviceWorkersElement, { childList: true });
unregisterLink.click();
yield onMutation;
is(document.querySelector("#service-workers .target"), null,
"No service worker displayed anymore.");
yield removeTab(swTab);
yield closeAboutDebugging(tab);
});

View File

@ -35,7 +35,7 @@ var gToolbox, gInspector;
* Startup the animationinspector controller and view, called by the sidebar * Startup the animationinspector controller and view, called by the sidebar
* widget when loading/unloading the iframe into the tab. * widget when loading/unloading the iframe into the tab.
*/ */
var startup = Task.async(function*(inspector) { var startup = Task.async(function* (inspector) {
gInspector = inspector; gInspector = inspector;
gToolbox = inspector.toolbox; gToolbox = inspector.toolbox;
@ -56,7 +56,7 @@ var startup = Task.async(function*(inspector) {
* Shutdown the animationinspector controller and view, called by the sidebar * Shutdown the animationinspector controller and view, called by the sidebar
* widget when loading/unloading the iframe into the tab. * widget when loading/unloading the iframe into the tab.
*/ */
var shutdown = Task.async(function*() { var shutdown = Task.async(function* () {
yield AnimationsController.destroy(); yield AnimationsController.destroy();
// Don't assume that AnimationsPanel is defined here, it's in another file. // Don't assume that AnimationsPanel is defined here, it's in another file.
if (typeof AnimationsPanel !== "undefined") { if (typeof AnimationsPanel !== "undefined") {
@ -79,7 +79,7 @@ function destroy() {
* @param {Target} target The current toolbox target. * @param {Target} target The current toolbox target.
* @return {Object} An object with boolean properties. * @return {Object} An object with boolean properties.
*/ */
var getServerTraits = Task.async(function*(target) { var getServerTraits = Task.async(function* (target) {
let config = [ let config = [
{ name: "hasToggleAll", actor: "animations", { name: "hasToggleAll", actor: "animations",
method: "toggleAll" }, method: "toggleAll" },
@ -135,7 +135,7 @@ var AnimationsController = {
PLAYERS_UPDATED_EVENT: "players-updated", PLAYERS_UPDATED_EVENT: "players-updated",
ALL_ANIMATIONS_TOGGLED_EVENT: "all-animations-toggled", ALL_ANIMATIONS_TOGGLED_EVENT: "all-animations-toggled",
initialize: Task.async(function*() { initialize: Task.async(function* () {
if (this.initialized) { if (this.initialized) {
yield this.initialized.promise; yield this.initialized.promise;
return; return;
@ -169,7 +169,7 @@ var AnimationsController = {
this.initialized.resolve(); this.initialized.resolve();
}), }),
destroy: Task.async(function*() { destroy: Task.async(function* () {
if (!this.initialized) { if (!this.initialized) {
return; return;
} }
@ -215,13 +215,13 @@ var AnimationsController = {
gInspector.sidebar.getCurrentTabID() == "animationinspector"; gInspector.sidebar.getCurrentTabID() == "animationinspector";
}, },
onPanelVisibilityChange: Task.async(function*() { onPanelVisibilityChange: Task.async(function* () {
if (this.isPanelVisible()) { if (this.isPanelVisible()) {
this.onNewNodeFront(); this.onNewNodeFront();
} }
}), }),
onNewNodeFront: Task.async(function*() { onNewNodeFront: Task.async(function* () {
// Ignore if the panel isn't visible or the node selection hasn't changed. // Ignore if the panel isn't visible or the node selection hasn't changed.
if (!this.isPanelVisible() || if (!this.isPanelVisible() ||
this.nodeFront === gInspector.selection.nodeFront) { this.nodeFront === gInspector.selection.nodeFront) {
@ -265,7 +265,7 @@ var AnimationsController = {
* if they should be played. * if they should be played.
* @return {Promise} Resolves when the playState has been changed. * @return {Promise} Resolves when the playState has been changed.
*/ */
toggleCurrentAnimations: Task.async(function*(shouldPause) { toggleCurrentAnimations: Task.async(function* (shouldPause) {
if (this.traits.hasToggleSeveral) { if (this.traits.hasToggleSeveral) {
yield this.animationsFront.toggleSeveral(this.animationPlayers, yield this.animationsFront.toggleSeveral(this.animationPlayers,
shouldPause); shouldPause);
@ -288,7 +288,7 @@ var AnimationsController = {
* @param {Boolean} shouldPause Should the animations be paused too. * @param {Boolean} shouldPause Should the animations be paused too.
* @return {Promise} Resolves when the current time has been set. * @return {Promise} Resolves when the current time has been set.
*/ */
setCurrentTimeAll: Task.async(function*(time, shouldPause) { setCurrentTimeAll: Task.async(function* (time, shouldPause) {
if (this.traits.hasSetCurrentTimes) { if (this.traits.hasSetCurrentTimes) {
yield this.animationsFront.setCurrentTimes(this.animationPlayers, time, yield this.animationsFront.setCurrentTimes(this.animationPlayers, time,
shouldPause); shouldPause);
@ -309,7 +309,7 @@ var AnimationsController = {
* @param {Number} rate. * @param {Number} rate.
* @return {Promise} Resolves when the rate has been set. * @return {Promise} Resolves when the rate has been set.
*/ */
setPlaybackRateAll: Task.async(function*(rate) { setPlaybackRateAll: Task.async(function* (rate) {
if (this.traits.hasSetPlaybackRates) { if (this.traits.hasSetPlaybackRates) {
// If the backend can set all playback rates at the same time, use that. // If the backend can set all playback rates at the same time, use that.
yield this.animationsFront.setPlaybackRates(this.animationPlayers, rate); yield this.animationsFront.setPlaybackRates(this.animationPlayers, rate);
@ -327,7 +327,7 @@ var AnimationsController = {
// called again. // called again.
animationPlayers: [], animationPlayers: [],
refreshAnimationPlayers: Task.async(function*(nodeFront) { refreshAnimationPlayers: Task.async(function* (nodeFront) {
this.destroyAnimationPlayers(); this.destroyAnimationPlayers();
this.animationPlayers = yield this.animationsFront this.animationPlayers = yield this.animationsFront

View File

@ -22,7 +22,7 @@ var AnimationsPanel = {
UI_UPDATED_EVENT: "ui-updated", UI_UPDATED_EVENT: "ui-updated",
PANEL_INITIALIZED: "panel-initialized", PANEL_INITIALIZED: "panel-initialized",
initialize: Task.async(function*() { initialize: Task.async(function* () {
if (AnimationsController.destroyed) { if (AnimationsController.destroyed) {
console.warn("Could not initialize the animation-panel, controller " + console.warn("Could not initialize the animation-panel, controller " +
"was destroyed"); "was destroyed");
@ -79,7 +79,7 @@ var AnimationsPanel = {
this.emit(this.PANEL_INITIALIZED); this.emit(this.PANEL_INITIALIZED);
}), }),
destroy: Task.async(function*() { destroy: Task.async(function* () {
if (!this.initialized) { if (!this.initialized) {
return; return;
} }
@ -205,7 +205,7 @@ var AnimationsPanel = {
* Toggle (pause/play) all animations in the current target * Toggle (pause/play) all animations in the current target
* and update the UI the toggleAll button. * and update the UI the toggleAll button.
*/ */
toggleAll: Task.async(function*() { toggleAll: Task.async(function* () {
this.toggleAllButtonEl.classList.toggle("paused"); this.toggleAllButtonEl.classList.toggle("paused");
yield AnimationsController.toggleAll(); yield AnimationsController.toggleAll();
}), }),
@ -280,7 +280,9 @@ var AnimationsPanel = {
this.setCurrentTimeAllPromise = this.setCurrentTimeAllPromise =
AnimationsController.setCurrentTimeAll(time, true) AnimationsController.setCurrentTimeAll(time, true)
.catch(error => console.error(error)) .catch(error => console.error(error))
.then(() => this.setCurrentTimeAllPromise = null); .then(() => {
this.setCurrentTimeAllPromise = null;
});
} }
this.displayTimelineCurrentTime(); this.displayTimelineCurrentTime();
@ -296,7 +298,7 @@ var AnimationsPanel = {
* useful after the playState or currentTime has been changed and in case the * useful after the playState or currentTime has been changed and in case the
* animations aren't auto-refreshing), and then refresh the UI. * animations aren't auto-refreshing), and then refresh the UI.
*/ */
refreshAnimationsStateAndUI: Task.async(function*() { refreshAnimationsStateAndUI: Task.async(function* () {
for (let player of AnimationsController.animationPlayers) { for (let player of AnimationsController.animationPlayers) {
yield player.refreshState(); yield player.refreshState();
} }
@ -307,7 +309,7 @@ var AnimationsPanel = {
* Refresh the list of animations UI. This will empty the panel and re-render * Refresh the list of animations UI. This will empty the panel and re-render
* the various components again. * the various components again.
*/ */
refreshAnimationsUI: Task.async(function*() { refreshAnimationsUI: Task.async(function* () {
// Empty the whole panel first. // Empty the whole panel first.
this.togglePlayers(true); this.togglePlayers(true);

View File

@ -62,7 +62,7 @@ AnimationDetails.prototype = {
* @return {Object} A list of tracks, one per animated property, each * @return {Object} A list of tracks, one per animated property, each
* with a list of keyframes * with a list of keyframes
*/ */
getTracks: Task.async(function*() { getTracks: Task.async(function* () {
let tracks = {}; let tracks = {};
/* /*
@ -112,7 +112,7 @@ AnimationDetails.prototype = {
return tracks; return tracks;
}), }),
render: Task.async(function*(animation) { render: Task.async(function* (animation) {
this.unrender(); this.unrender();
if (!animation) { if (!animation) {

View File

@ -41,7 +41,7 @@ AnimationTargetNode.prototype = {
this.isDestroyed = true; this.isDestroyed = true;
}, },
render: Task.async(function*(playerFront) { render: Task.async(function* (playerFront) {
// Get the nodeFront from the cache if it was stored previously. // Get the nodeFront from the cache if it was stored previously.
let nodeFront = nodeFronts.get(playerFront); let nodeFront = nodeFronts.get(playerFront);

View File

@ -21,7 +21,7 @@ const EXPECTED_PROPERTIES = [
"width" "width"
].sort(); ].sort();
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_keyframes.html"); yield addTab(URL_ROOT + "doc_keyframes.html");
let {panel} = yield openAnimationInspector(); let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent; let timeline = panel.animationsTimelineComponent;

View File

@ -7,7 +7,7 @@
// Check that animations displayed in the timeline can be selected by clicking // Check that animations displayed in the timeline can be selected by clicking
// them, and that this emits the right events and adds the right classes. // them, and that this emits the right events and adds the right classes.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector(); let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent; let timeline = panel.animationsTimelineComponent;

View File

@ -7,7 +7,7 @@
// Test that the controller provides the document.timeline currentTime (at least // Test that the controller provides the document.timeline currentTime (at least
// the last known version since new animations were added). // the last known version since new animations were added).
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, controller} = yield openAnimationInspector(); let {panel, controller} = yield openAnimationInspector();

View File

@ -12,7 +12,7 @@ const { LocalizationHelper } = require("devtools/client/shared/l10n");
const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties"; const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties";
const L10N = new LocalizationHelper(STRINGS_URI); const L10N = new LocalizationHelper(STRINGS_URI);
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, window} = yield openAnimationInspector(); let {inspector, panel, window} = yield openAnimationInspector();
let {document} = window; let {document} = window;

View File

@ -7,7 +7,7 @@
// Test that animated properties' keyframes can be clicked, and that doing so // Test that animated properties' keyframes can be clicked, and that doing so
// sets the current time in the timeline. // sets the current time in the timeline.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_keyframes.html"); yield addTab(URL_ROOT + "doc_keyframes.html");
let {panel} = yield openAnimationInspector(); let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent; let timeline = panel.animationsTimelineComponent;

View File

@ -21,7 +21,7 @@ const EXPECTED_PROPERTIES = [
"width" "width"
]; ];
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_keyframes.html"); yield addTab(URL_ROOT + "doc_keyframes.html");
let {panel} = yield openAnimationInspector(); let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent; let timeline = panel.animationsTimelineComponent;

View File

@ -9,7 +9,7 @@
// displayed (which should be true as long as these animations apply to // displayed (which should be true as long as these animations apply to
// different nodes). // different nodes).
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_negative_animation.html"); yield addTab(URL_ROOT + "doc_negative_animation.html");
let {controller, panel} = yield openAnimationInspector(); let {controller, panel} = yield openAnimationInspector();

View File

@ -6,7 +6,7 @@
// Test that the animation panel sidebar exists // Test that the animation panel sidebar exists
add_task(function*() { add_task(function* () {
yield addTab("data:text/html;charset=utf-8,welcome to the animation panel"); yield addTab("data:text/html;charset=utf-8,welcome to the animation panel");
let {panel, controller} = yield openAnimationInspector(); let {panel, controller} = yield openAnimationInspector();

View File

@ -10,7 +10,7 @@ requestLongerTimeout(2);
// inspector-updated event. This means that the test verifies that the // inspector-updated event. This means that the test verifies that the
// inspector-updated event is emitted *after* the animation panel is ready. // inspector-updated event is emitted *after* the animation panel is ready.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, controller} = yield openAnimationInspector(); let {inspector, panel, controller} = yield openAnimationInspector();

View File

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// Check that the AnimationPlayerFront objects lifecycle is managed by the // Check that the AnimationPlayerFront objects lifecycle is managed by the
// AnimationController. // AnimationController.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {controller, inspector} = yield openAnimationInspector(); let {controller, inspector} = yield openAnimationInspector();

View File

@ -9,7 +9,7 @@
const { ANIMATION_TYPES } = require("devtools/server/actors/animation"); const { ANIMATION_TYPES } = require("devtools/server/actors/animation");
add_task(function*() { add_task(function* () {
yield new Promise(resolve => { yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [ SpecialPowers.pushPrefEnv({"set": [
["dom.animations-api.core.enabled", true] ["dom.animations-api.core.enabled", true]

View File

@ -8,7 +8,7 @@ requestLongerTimeout(2);
// Test that player widgets display information about target nodes // Test that player widgets display information about target nodes
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector(); let {inspector, panel} = yield openAnimationInspector();

View File

@ -6,7 +6,7 @@
// Test that animated pseudo-elements do show in the timeline. // Test that animated pseudo-elements do show in the timeline.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_pseudo_elements.html"); yield addTab(URL_ROOT + "doc_pseudo_elements.html");
let {inspector, panel} = yield openAnimationInspector(); let {inspector, panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent; let timeline = panel.animationsTimelineComponent;

View File

@ -8,7 +8,7 @@ requestLongerTimeout(2);
// Test that the panel content refreshes when new animations are added. // Test that the panel content refreshes when new animations are added.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector(); let {inspector, panel} = yield openAnimationInspector();

View File

@ -8,7 +8,7 @@ requestLongerTimeout(2);
// Test that the panel content refreshes when animations are removed. // Test that the panel content refreshes when animations are removed.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector(); let {inspector, panel} = yield openAnimationInspector();

View File

@ -8,7 +8,7 @@ requestLongerTimeout(2);
// Test that the panel only refreshes when it is visible in the sidebar. // Test that the panel only refreshes when it is visible in the sidebar.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector(); let {inspector, panel} = yield openAnimationInspector();

View File

@ -14,7 +14,7 @@ const { LocalizationHelper } = require("devtools/client/shared/l10n");
const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties"; const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties";
const L10N = new LocalizationHelper(STRINGS_URI); const L10N = new LocalizationHelper(STRINGS_URI);
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector(); let {inspector, panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent; let timeline = panel.animationsTimelineComponent;

View File

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// Check that when playerFronts are updated, the same number of playerWidgets // Check that when playerFronts are updated, the same number of playerWidgets
// are created in the panel. // are created in the panel.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, controller} = yield openAnimationInspector(); let {inspector, panel, controller} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent; let timeline = panel.animationsTimelineComponent;

View File

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// Test that the panel shows an animation player when an animated node is // Test that the panel shows an animation player when an animated node is
// selected. // selected.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector(); let {inspector, panel} = yield openAnimationInspector();

View File

@ -10,7 +10,7 @@
// because there's an other test that does this : // because there's an other test that does this :
// browser_animation_toggle_button_toggles_animation.js // browser_animation_toggle_button_toggles_animation.js
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, inspector, window, controller} = yield openAnimationInspector(); let {panel, inspector, window, controller} = yield openAnimationInspector();
let {toggleAllButtonEl} = panel; let {toggleAllButtonEl} = panel;

View File

@ -10,7 +10,7 @@
// There are animations in the test page and since, by default, the <body> node // There are animations in the test page and since, by default, the <body> node
// is selected, animations will be displayed in the timeline, so the timeline // is selected, animations will be displayed in the timeline, so the timeline
// play/resume button will be displayed // play/resume button will be displayed
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, window} = yield openAnimationInspector(); let {panel, window} = yield openAnimationInspector();
let {playTimelineButtonEl} = panel; let {playTimelineButtonEl} = panel;

View File

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// Test that the DOM element targets displayed in animation player widgets can // Test that the DOM element targets displayed in animation player widgets can
// be used to highlight elements in the DOM and select them in the inspector. // be used to highlight elements in the DOM and select them in the inspector.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {toolbox, inspector, panel} = yield openAnimationInspector(); let {toolbox, inspector, panel} = yield openAnimationInspector();

View File

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// Test that the DOM element targets displayed in animation player widgets can // Test that the DOM element targets displayed in animation player widgets can
// be used to highlight elements in the DOM and select them in the inspector. // be used to highlight elements in the DOM and select them in the inspector.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector(); let {panel} = yield openAnimationInspector();

View File

@ -10,7 +10,7 @@ requestLongerTimeout(2);
// changes when animations are playing, gets back to 0 when animations are // changes when animations are playing, gets back to 0 when animations are
// rewound, and stops when animations are paused. // rewound, and stops when animations are paused.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector(); let {panel} = yield openAnimationInspector();

View File

@ -14,7 +14,7 @@ const {findOptimalTimeInterval, TimeScale} = require("devtools/client/animationi
// animation-timeline.js // animation-timeline.js
const TIME_GRADUATION_MIN_SPACING = 40; const TIME_GRADUATION_MIN_SPACING = 40;
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector(); let {panel} = yield openAnimationInspector();

View File

@ -6,7 +6,7 @@
// Check that the iteration start is displayed correctly in time blocks. // Check that the iteration start is displayed correctly in time blocks.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_script_animation.html"); yield addTab(URL_ROOT + "doc_script_animation.html");
let {panel} = yield openAnimationInspector(); let {panel} = yield openAnimationInspector();
let timelineComponent = panel.animationsTimelineComponent; let timelineComponent = panel.animationsTimelineComponent;

View File

@ -16,7 +16,7 @@ requestLongerTimeout(2);
// And test that clicking the button once the scrubber has reached the end of // And test that clicking the button once the scrubber has reached the end of
// the timeline does the right thing. // the timeline does the right thing.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, inspector} = yield openAnimationInspector(); let {panel, inspector} = yield openAnimationInspector();

View File

@ -12,7 +12,7 @@ requestLongerTimeout(2);
// all have the same rate, or that it displays the empty value in case they // all have the same rate, or that it displays the empty value in case they
// have mixed rates. // have mixed rates.
add_task(function*() { add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html"); yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, controller, inspector, toolbox} = yield openAnimationInspector(); let {panel, controller, inspector, toolbox} = yield openAnimationInspector();

Some files were not shown because too many files have changed in this diff Show More