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/**
# External code:
toolkit/components/microformats/test/**
toolkit/components/reader/Readability.js
toolkit/components/reader/JSDOMParser.js

View File

@ -304,7 +304,7 @@ pref("browser.urlbar.matchBehavior", 1);
pref("browser.urlbar.filter.javascript", true);
// 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
// before starting to perform autocomplete. 50 is the default set in
// autocomplete.xml.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1824,6 +1824,99 @@
</body>
</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">
<parameter name="aURI"/>
<parameter name="aReferrerURI"/>
@ -1833,6 +1926,8 @@
<parameter name="aAllowThirdPartyFixup"/>
<body>
<![CDATA[
"use strict";
const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var aReferrerPolicy;
var aFromExternal;
@ -1884,12 +1979,6 @@
t.setAttribute("onerror", "this.removeAttribute('image');");
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();
// When overflowing, new tabs are scrolled into view smoothly, which
@ -1914,59 +2003,35 @@
if (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 uniqueId = this._generateUniquePanelID();
notificationbox.id = uniqueId;
t.linkedPanel = uniqueId;
t.linkedBrowser = b;
this._tabForBrowser.set(b, t);
t._tPos = position;
t.lastAccessed = Date.now();
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();
// wire up a progress listener for the new browser object.
var tabListener = this.mTabProgressListener(t, b, uriIsAboutBlank, usingPreloadedContent);
const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
.createInstance(Components.interfaces.nsIWebProgress);
filter.addProgressListener(tabListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
b.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
this._tabListeners.set(t, tabListener);
this._tabFilters.set(t, filter);
let options = {
referrerURI : aReferrerURI,
referrerPolicy : aReferrerPolicy,
charset : aCharset,
postData : aPostData,
allowThirdPartyFixup : aAllowThirdPartyFixup,
fromExternal : aFromExternal,
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
// 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
// move it to after the current tab.
// aReferrerURI is null or undefined if the tab is opened from
@ -4266,6 +4314,7 @@
}
}
return undefined;
]]></body>
</method>

View File

@ -321,7 +321,7 @@ skip-if = !datareporting
[browser_devices_get_user_media.js]
skip-if = buildapp == 'mulet' || (os == "linux" && debug) # linux: bug 976544
[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_discovery.js]
[browser_double_close_tab.js]

View File

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

View File

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

View File

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

View File

@ -58,37 +58,8 @@ function loadPage(aUrl) {
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() {
gBrowser.removeCurrentTab();
registrar.unregisterFactory(classIDLoopconversation, factory);
registrar.unregisterFactory(classIDEvil, factory);
});
const permissionError = "error: SecurityError: The operation is insecure.";
@ -181,19 +152,46 @@ function test() {
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 () {
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({
"set": [[PREF_PERMISSION_FAKE, true],
["media.getusermedia.screensharing.enabled", true]],
@ -206,6 +204,19 @@ function test() {
// Cleanup before the next test
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 => {
ok(false, "Unexpected Exception: " + ex);
finish();

View File

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

View File

@ -62,6 +62,7 @@ function getVisibleMenuItems(aMenu, aData) {
} else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
item.id != "spell-no-suggestions" &&
item.id != "spell-add-dictionaries-main" &&
item.id != "context-savelinktopocket" &&
item.id != "fill-login-saved-passwords" &&
item.id != "fill-login-no-logins") {
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;
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();
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,
// 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) {
if (aWindow) {
return this._dispatchToolboxEventToWindow(aEventType, aDetails, aWindow);
this._dispatchToolboxEventToWindow(aEventType, aDetails, aWindow);
return;
}
for (let [win, ] of gBuildWindows) {
this._dispatchToolboxEventToWindow(aEventType, aDetails, win);
@ -2418,6 +2419,7 @@ var CustomizableUIInternal = {
aArgs);
} catch (e) {
Cu.reportError(e);
return undefined;
}
};
},
@ -3912,7 +3914,7 @@ function XULWidgetGroupWrapper(aWidgetId) {
});
this.__defineGetter__("instances", function() {
return Array.from(gBuildWindows, ([win,]) => this.forWindow(win));
return Array.from(gBuildWindows, (wins) => this.forWindow(wins[0]));
});
Object.freeze(this);

View File

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

View File

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

View File

@ -58,6 +58,7 @@ support-files =
[browser_ext_windows_create.js]
tags = fullscreen
[browser_ext_windows_create_tabId.js]
[browser_ext_windows_events.js]
[browser_ext_windows.js]
[browser_ext_windows_size.js]
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.
yield focusWindow(window);
yield triggerPopup(win1, function*() {
yield triggerPopup(win1, function* () {
yield checkWindow("popup", winId1, "win1");
});
yield triggerPopup(win2, function*() {
yield triggerPopup(win2, function* () {
yield checkWindow("popup", winId2, "win2");
});

View File

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

View File

@ -226,3 +226,34 @@ add_task(function* test_tab_options() {
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;
browser.windows.getCurrent().then(window => {
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),
"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(() => {
browser.test.notifyPass("window-create");
}).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>
<meta charset="utf-8">
<script type="application/javascript">
"use strict";
throw new Error(`WebExt Privilege Escalation: BrowserAction: typeof(browser) = ${typeof(browser)}`);
</script>
</head>

View File

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

View File

@ -78,10 +78,8 @@ function getBrowserActionPopup(extension, win = window) {
if (group.areaType == CustomizableUI.TYPE_TOOLBAR) {
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) {

View File

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

View File

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

View File

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

View File

@ -1436,7 +1436,22 @@
BrowserSearch.searchBar.openSuggestionsPanel();
},
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,

View File

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

View File

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

View File

@ -1,3 +1,3 @@
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.
channel.originalURI = aRequest.URI;
channel.loadGroup = aRequest.loadGroup;
channel.loadInfo.originAttributes = aRequest.loadInfo.originAttributes;
// 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
var ssm = Cc['@mozilla.org/scriptsecuritymanager;1']
.getService(Ci.nsIScriptSecurityManager);
var uri = NetUtil.newURI(PDF_VIEWER_WEB_PAGE, null, null);
var attrs = aRequest.loadInfo.originAttributes;
var resourcePrincipal;
resourcePrincipal = ssm.createCodebasePrincipal(uri, {});
resourcePrincipal = ssm.createCodebasePrincipal(uri, attrs);
aRequest.owner = resourcePrincipal;
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
* limitations under the License.
*/
/* globals PDFJS */
/* globals pdfjsLib */
'use strict';
@ -307,8 +307,8 @@ var Stepper = (function StepperClosure() {
this.table = table;
if (!opMap) {
opMap = Object.create(null);
for (var key in PDFJS.OPS) {
opMap[PDFJS.OPS[key]] = key;
for (var key in pdfjsLib.OPS) {
opMap[pdfjsLib.OPS[key]] = key;
}
}
},
@ -460,7 +460,7 @@ var Stats = (function Stats() {
manager: null,
init: function init() {
this.panel.setAttribute('style', 'padding: 5px;');
PDFJS.enableStats = true;
pdfjsLib.PDFJS.enableStats = true;
},
enabled: 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");
* 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
* limitations under the License.
*/
/* globals PDFJS, PDFBug, FirefoxCom, Stats, ProgressBar, DownloadManager,
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 */
/*globals require, parseQueryString, chrome, PDFViewerApplication */
'use strict';
var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf';
var DEFAULT_SCALE_DELTA = 1.1;
var MIN_SCALE = 0.25;
var MAX_SCALE = 10.0;
@ -41,8 +34,6 @@ function configure(PDFJS) {
PDFJS.cMapPacked = true;
}
var mozL10n = document.mozL10n || document.webL10n;
var CSS_UNITS = 96.0 / 72.0;
var DEFAULT_SCALE_VALUE = 'auto';
@ -52,6 +43,56 @@ var MAX_AUTO_SCALE = 1.25;
var SCROLLBAR_PADDING = 40;
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.
* @return {Object} The object with horizontal (sx) and vertical (sy)
@ -585,9 +626,6 @@ var Preferences = {
var FirefoxCom = (function FirefoxComClosure() {
return {
/**
@ -659,7 +697,7 @@ var DownloadManager = (function DownloadManagerClosure() {
downloadData: function DownloadManager_downloadData(data, filename,
contentType) {
var blobUrl = PDFJS.createObjectURL(data, contentType);
var blobUrl = pdfjsLib.createObjectURL(data, contentType, false);
FirefoxCom.request('download', {
blobUrl: blobUrl,
@ -3000,7 +3038,7 @@ var PasswordPrompt = {
var promptString = mozL10n.get('password_label', null,
'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,
'Invalid password. Please try again.');
}
@ -3241,7 +3279,6 @@ var PresentationModeState = {
FULLSCREEN: 3,
};
var IGNORE_CURRENT_POSITION_ON_ZOOM = false;
var DEFAULT_CACHE_SIZE = 10;
@ -3552,19 +3589,18 @@ var PDFPageView = (function PDFPageViewClosure() {
});
var isScalingRestricted = false;
if (this.canvas && PDFJS.maxCanvasPixels > 0) {
if (this.canvas && pdfjsLib.PDFJS.maxCanvasPixels > 0) {
var outputScale = this.outputScale;
var pixelsInViewport = this.viewport.width * this.viewport.height;
var maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport);
if (((Math.floor(this.viewport.width) * outputScale.sx) | 0) *
((Math.floor(this.viewport.height) * outputScale.sy) | 0) >
PDFJS.maxCanvasPixels) {
pdfjsLib.PDFJS.maxCanvasPixels) {
isScalingRestricted = true;
}
}
if (this.canvas) {
if (PDFJS.useOnlyCssZoom ||
if (pdfjsLib.PDFJS.useOnlyCssZoom ||
(this.hasRestrictedScaling && isScalingRestricted)) {
this.cssTransform(this.canvas, true);
@ -3598,7 +3634,7 @@ var PDFPageView = (function PDFPageViewClosure() {
},
cssTransform: function PDFPageView_transform(canvas, redrawAnnotations) {
var CustomStyle = PDFJS.CustomStyle;
var CustomStyle = pdfjsLib.CustomStyle;
// Scale canvas, canvas wrapper, and page container.
var width = this.viewport.width;
@ -3718,7 +3754,7 @@ var PDFPageView = (function PDFPageViewClosure() {
var outputScale = getOutputScale(ctx);
this.outputScale = outputScale;
if (PDFJS.useOnlyCssZoom) {
if (pdfjsLib.PDFJS.useOnlyCssZoom) {
var actualSizeViewport = viewport.clone({scale: CSS_UNITS});
// Use a scale that will make the canvas be the original intended size
// of the page.
@ -3727,9 +3763,10 @@ var PDFPageView = (function PDFPageViewClosure() {
outputScale.scaled = true;
}
if (PDFJS.maxCanvasPixels > 0) {
if (pdfjsLib.PDFJS.maxCanvasPixels > 0) {
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) {
outputScale.sx = maxScale;
outputScale.sy = maxScale;
@ -3896,7 +3933,7 @@ var PDFPageView = (function PDFPageViewClosure() {
},
beforePrint: function PDFPageView_beforePrint() {
var CustomStyle = PDFJS.CustomStyle;
var CustomStyle = pdfjsLib.CustomStyle;
var pdfPage = this.pdfPage;
var viewport = pdfPage.getViewport(1);
@ -4020,7 +4057,7 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() {
this.textDivs = [];
var textLayerFrag = document.createDocumentFragment();
this.textLayerRenderTask = PDFJS.renderTextLayer({
this.textLayerRenderTask = pdfjsLib.renderTextLayer({
textContent: this.textContent,
container: textLayerFrag,
viewport: this.viewport,
@ -4323,7 +4360,7 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() {
if (self.div) {
// If an annotationLayer already exists, refresh its children's
// transformation matrices.
PDFJS.AnnotationLayer.update(parameters);
pdfjsLib.AnnotationLayer.update(parameters);
} else {
// Create an annotation layer div and render the annotations
// if there is at least one annotation.
@ -4336,7 +4373,7 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() {
self.pageDiv.appendChild(self.div);
parameters.div = self.div;
PDFJS.AnnotationLayer.render(parameters);
pdfjsLib.AnnotationLayer.render(parameters);
if (typeof mozL10n !== 'undefined') {
mozL10n.translate(self.div);
}
@ -4628,7 +4665,7 @@ var PDFViewer = (function pdfViewer() {
var viewport = pdfPage.getViewport(scale * CSS_UNITS);
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
var textLayerFactory = null;
if (!PDFJS.disableTextLayer) {
if (!pdfjsLib.PDFJS.disableTextLayer) {
textLayerFactory = this;
}
var pageView = new PDFPageView({
@ -4650,7 +4687,7 @@ var PDFViewer = (function pdfViewer() {
// starts to create the correct size canvas. Wait until one page is
// rendered so we don't tie up too many resources early on.
onePageRendered.then(function () {
if (!PDFJS.disableAutoFetch) {
if (!pdfjsLib.PDFJS.disableAutoFetch) {
var getPagesLeft = pagesCount;
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
pdfDocument.getPage(pageNum).then(function (pageNum, pdfPage) {
@ -4740,7 +4777,7 @@ var PDFViewer = (function pdfViewer() {
if (!noScroll) {
var page = this._currentPageNumber, dest;
if (this._location && !IGNORE_CURRENT_POSITION_ON_ZOOM &&
if (this._location && !pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom &&
!(this.isInPresentationMode || this.isChangingPresentationMode)) {
page = this._location.pageNumber;
dest = [null, { name: 'XYZ' }, this._location.left,
@ -6074,7 +6111,7 @@ var PDFOutlineViewer = (function PDFOutlineViewerClosure() {
*/
_bindLink: function PDFOutlineViewer_bindLink(element, item) {
if (item.url) {
PDFJS.addLinkAttributes(element, { url: item.url });
pdfjsLib.addLinkAttributes(element, { url: item.url });
return;
}
var linkService = this.linkService;
@ -6183,7 +6220,7 @@ var PDFOutlineViewer = (function PDFOutlineViewerClosure() {
this._bindLink(element, item);
this._setStyles(element, item);
element.textContent =
PDFJS.removeNullCharacters(item.title) || DEFAULT_TITLE;
pdfjsLib.removeNullCharacters(item.title) || DEFAULT_TITLE;
div.appendChild(element);
@ -6297,12 +6334,12 @@ var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() {
for (var i = 0; i < attachmentsCount; i++) {
var item = attachments[names[i]];
var filename = PDFJS.getFilenameFromUrl(item.filename);
var filename = pdfjsLib.getFilenameFromUrl(item.filename);
var div = document.createElement('div');
div.className = 'attachmentsItem';
var button = document.createElement('button');
this._bindLink(button, item.content, filename);
button.textContent = PDFJS.removeNullCharacters(filename);
button.textContent = pdfjsLib.removeNullCharacters(filename);
div.appendChild(button);
this.container.appendChild(div);
}
@ -6355,6 +6392,8 @@ var PDFViewerApplication = {
// called once when the document is loaded
initialize: function pdfViewInitialize() {
configure(pdfjsLib.PDFJS);
var pdfRenderingQueue = new PDFRenderingQueue();
pdfRenderingQueue.onIdle = this.cleanup.bind(this);
this.pdfRenderingQueue = pdfRenderingQueue;
@ -6508,6 +6547,7 @@ var PDFViewerApplication = {
this.pdfSidebar.onToggled = this.forceRendering.bind(this);
var self = this;
var PDFJS = pdfjsLib.PDFJS;
var initializedPromise = Promise.all([
Preferences.get('enableWebGL').then(function resolved(value) {
PDFJS.disableWebGL = !value;
@ -6574,6 +6614,10 @@ var PDFViewerApplication = {
});
},
run: function pdfViewRun() {
this.initialize().then(webViewerInitialized);
},
zoomIn: function pdfViewZoomIn(ticks) {
var newScale = this.pdfViewer.currentScale;
do {
@ -6610,7 +6654,7 @@ var PDFViewerApplication = {
var canvas = document.createElement('canvas');
var value = 'mozPrintCallback' in canvas;
return PDFJS.shadow(this, 'supportsPrinting', value);
return pdfjsLib.shadow(this, 'supportsPrinting', value);
},
get supportsFullscreen() {
@ -6624,38 +6668,38 @@ var PDFViewerApplication = {
document.msFullscreenEnabled === false) {
support = false;
}
if (support && PDFJS.disableFullscreen === true) {
if (support && pdfjsLib.PDFJS.disableFullscreen === true) {
support = false;
}
return PDFJS.shadow(this, 'supportsFullscreen', support);
return pdfjsLib.shadow(this, 'supportsFullscreen', support);
},
get supportsIntegratedFind() {
var support = false;
support = FirefoxCom.requestSync('supportsIntegratedFind');
return PDFJS.shadow(this, 'supportsIntegratedFind', support);
return pdfjsLib.shadow(this, 'supportsIntegratedFind', support);
},
get supportsDocumentFonts() {
var support = true;
support = FirefoxCom.requestSync('supportsDocumentFonts');
return PDFJS.shadow(this, 'supportsDocumentFonts', support);
return pdfjsLib.shadow(this, 'supportsDocumentFonts', support);
},
get supportsDocumentColors() {
var support = true;
support = FirefoxCom.requestSync('supportsDocumentColors');
return PDFJS.shadow(this, 'supportsDocumentColors', support);
return pdfjsLib.shadow(this, 'supportsDocumentColors', support);
},
get loadingBar() {
var bar = new ProgressBar('#loadingBar', {});
return PDFJS.shadow(this, 'loadingBar', bar);
return pdfjsLib.shadow(this, 'loadingBar', bar);
},
get supportedMouseWheelZoomModifierKeys() {
@ -6665,15 +6709,16 @@ var PDFViewerApplication = {
};
support = FirefoxCom.requestSync('supportedMouseWheelZoomModifierKeys');
return PDFJS.shadow(this, 'supportedMouseWheelZoomModifierKeys', support);
return pdfjsLib.shadow(this, 'supportedMouseWheelZoomModifierKeys',
support);
},
initPassiveLoading: function pdfViewInitPassiveLoading() {
function FirefoxComDataRangeTransport(length, initialData) {
PDFJS.PDFDataRangeTransport.call(this, length, initialData);
pdfjsLib.PDFDataRangeTransport.call(this, length, initialData);
}
FirefoxComDataRangeTransport.prototype =
Object.create(PDFJS.PDFDataRangeTransport.prototype);
Object.create(pdfjsLib.PDFDataRangeTransport.prototype);
FirefoxComDataRangeTransport.prototype.requestDataRange =
function FirefoxComDataRangeTransport_requestDataRange(begin, end) {
FirefoxCom.request('requestDataRange', { begin: begin, end: end });
@ -6738,7 +6783,8 @@ var PDFViewerApplication = {
setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
this.url = url;
try {
this.setTitle(decodeURIComponent(PDFJS.getFilenameFromUrl(url)) || url);
this.setTitle(decodeURIComponent(
pdfjsLib.getFilenameFromUrl(url)) || url);
} catch (e) {
// decodeURIComponent may throw URIError,
// fall back to using the unprocessed url in that case
@ -6849,7 +6895,7 @@ var PDFViewerApplication = {
var self = this;
self.downloadComplete = false;
var loadingTask = PDFJS.getDocument(parameters);
var loadingTask = pdfjsLib.getDocument(parameters);
this.pdfLoadingTask = loadingTask;
loadingTask.onPassword = function passwordNeeded(updatePassword, reason) {
@ -6874,15 +6920,15 @@ var PDFViewerApplication = {
var loadingErrorMessage = mozL10n.get('loading_error', null,
'An error occurred while loading the PDF.');
if (exception instanceof PDFJS.InvalidPDFException) {
if (exception instanceof pdfjsLib.InvalidPDFException) {
// change error message also for other builds
loadingErrorMessage = mozL10n.get('invalid_file_error', null,
'Invalid or corrupted PDF file.');
} else if (exception instanceof PDFJS.MissingPDFException) {
} else if (exception instanceof pdfjsLib.MissingPDFException) {
// special message for missing PDF's
loadingErrorMessage = mozL10n.get('missing_file_error', null,
'Missing PDF file.');
} else if (exception instanceof PDFJS.UnexpectedResponseException) {
} else if (exception instanceof pdfjsLib.UnexpectedResponseException) {
loadingErrorMessage = mozL10n.get('unexpected_response_error', null,
'Unexpected server response.');
}
@ -6928,7 +6974,7 @@ var PDFViewerApplication = {
this.pdfDocument.getData().then(
function getDataSuccess(data) {
var blob = PDFJS.createBlob(data, 'application/pdf');
var blob = pdfjsLib.createBlob(data, 'application/pdf');
downloadManager.download(blob, url, filename);
},
downloadByUrl // Error occurred try downloading with just the url.
@ -6961,7 +7007,7 @@ var PDFViewerApplication = {
*/
error: function pdfViewError(message, moreInfo) {
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';
if (moreInfo) {
moreInfoText +=
@ -7003,7 +7049,7 @@ var PDFViewerApplication = {
// the loading bar will not be completely filled, nor will it be hidden.
// To prevent displaying a partially filled loading bar permanently, we
// 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) {
clearTimeout(this.disableAutoFetchLoadingBarTimeout);
this.disableAutoFetchLoadingBarTimeout = null;
@ -7063,7 +7109,7 @@ var PDFViewerApplication = {
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,
// i.e. not when it is embedded in a web page.
if (!self.preferenceShowPreviousViewOnLoad) {
@ -7136,7 +7182,7 @@ var PDFViewerApplication = {
pdfDocument.getJavaScript().then(function(javaScript) {
if (javaScript.length) {
console.warn('Warning: JavaScript is not supported');
self.fallback(PDFJS.UNSUPPORTED_FEATURES.javaScript);
self.fallback(pdfjsLib.UNSUPPORTED_FEATURES.javaScript);
}
// Hack to support auto printing.
var regex = /\bprint\s*\(/;
@ -7173,8 +7219,8 @@ var PDFViewerApplication = {
console.log('PDF ' + pdfDocument.fingerprint + ' [' +
info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() +
' / ' + (info.Creator || '-').trim() + ']' +
' (PDF.js: ' + (PDFJS.version || '-') +
(!PDFJS.disableWebGL ? ' [WebGL]' : '') + ')');
' (PDF.js: ' + (pdfjsLib.version || '-') +
(!pdfjsLib.PDFJS.disableWebGL ? ' [WebGL]' : '') + ')');
var pdfTitle;
if (metadata && metadata.has('dc:title')) {
@ -7195,7 +7241,7 @@ var PDFViewerApplication = {
if (info.IsAcroFormPresent) {
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;
@ -7398,18 +7444,13 @@ var PDFViewerApplication = {
};
function webViewerLoad(evt) {
configure(PDFJS);
PDFViewerApplication.initialize().then(webViewerInitialized);
}
function webViewerInitialized() {
var file = window.location.href.split('#')[0];
document.getElementById('openFile').setAttribute('hidden', 'true');
document.getElementById('secondaryOpenFile').setAttribute('hidden', 'true');
var PDFJS = pdfjsLib.PDFJS;
if (PDFViewerApplication.preferencePdfBugEnabled) {
// Special debugging flags in the hash section of the URL.
@ -7444,7 +7485,7 @@ function webViewerInitialized() {
PDFJS.verbosity = hashParams['verbosity'] | 0;
}
if ('ignorecurrentpositiononzoom' in hashParams) {
IGNORE_CURRENT_POSITION_ON_ZOOM =
PDFJS.ignoreCurrentPositionOnZoom =
(hashParams['ignorecurrentpositiononzoom'] === 'true');
}
if ('textlayer' in hashParams) {
@ -7565,8 +7606,6 @@ function webViewerInitialized() {
}
document.addEventListener('DOMContentLoaded', webViewerLoad, true);
document.addEventListener('pagerendered', function (e) {
var pageNumber = e.detail.pageNumber;
var pageIndex = pageNumber - 1;
@ -7579,7 +7618,7 @@ document.addEventListener('pagerendered', function (e) {
thumbnailView.setImage(pageView);
}
if (PDFJS.pdfBug && Stats.enabled && pageView.stats) {
if (pdfjsLib.PDFJS.pdfBug && Stats.enabled && pageView.stats) {
Stats.add(pageNumber, pageView.stats);
}
@ -7830,7 +7869,7 @@ window.addEventListener('pagechange', function pagechange(evt) {
document.getElementById('lastPage').disabled = (page >= numPages);
// we need to update stats
if (PDFJS.pdfBug && Stats.enabled) {
if (pdfjsLib.PDFJS.pdfBug && Stats.enabled) {
var pageView = PDFViewerApplication.pdfViewer.getPageView(page - 1);
if (pageView.stats) {
Stats.add(page, pageView.stats);
@ -7838,6 +7877,7 @@ window.addEventListener('pagechange', function pagechange(evt) {
}
}, true);
var zoomDisabled = false, zoomDisabledTimeout;
function handleMouseWheel(evt) {
var MOUSE_WHEEL_DELTA_FACTOR = 40;
var ticks = (evt.type === 'DOMMouseScroll') ? -evt.detail :
@ -7857,6 +7897,10 @@ function handleMouseWheel(evt) {
}
// Only zoom the pages, not the entire viewer.
evt.preventDefault();
// NOTE: this check must be placed *after* preventDefault.
if (zoomDisabled) {
return;
}
var previousScale = pdfViewer.currentScale;
@ -7874,6 +7918,12 @@ function handleMouseWheel(evt) {
pdfViewer.container.scrollLeft += dx * 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"),
"oncommand": "Pocket.savePage(gContextMenu.browser, gContextMenu.linkURL);"
});
sibling = document.getElementById("context-savelink");
let sibling = document.getElementById("context-savelink");
if (sibling.nextSibling) {
sibling.parentNode.insertBefore(menu, sibling.nextSibling);
} else {
@ -360,6 +360,7 @@ function pktUIGetter(prop, window) {
get: function() {
// delete any getters for properties loaded from main.js so we only load main.js once
delete window.pktUI;
delete window.pktApi;
delete window.pktUIMessaging;
Services.scriptloader.loadSubScript("chrome://pocket/content/main.js", window);
return window[prop];
@ -402,6 +403,7 @@ var PocketOverlay = {
this.removeStyles(window);
// remove script getters/objects
delete window.Pocket;
delete window.pktApi;
delete window.pktUI;
delete window.pktUIMessaging;
}
@ -421,6 +423,7 @@ var PocketOverlay = {
"chrome://pocket/content/Pocket.jsm");
// Can't use XPCOMUtils for these because the scripts try to define the variables
// 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, "pktUIMessaging", pktUIGetter("pktUIMessaging", window));
},

View File

@ -11,13 +11,20 @@ function checkElements(expectPresent, l) {
}
}
add_task(function*() {
let enabledOnStartup = yield promisePocketEnabled();
add_task(function* test_setup() {
let clearValue = Services.prefs.prefHasUserValue("extensions.pocket.enabled");
let enabledOnStartup = Services.prefs.getBoolPref("extensions.pocket.enabled");
registerCleanupFunction(() => {
// Extra insurance that this is disabled again, but it should have been set
// in promisePocketReset.
Services.prefs.setBoolPref("extensions.pocket.enabled", enabledOnStartup);
if (clearValue) {
Services.prefs.clearUserPref("extensions.pocket.enabled");
} else {
Services.prefs.setBoolPref("extensions.pocket.enabled", enabledOnStartup);
}
});
});
add_task(function*() {
yield promisePocketEnabled();
checkWindowProperties(true, ["Pocket", "pktUI", "pktUIMessaging"]);
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++;
setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
return undefined;
}
setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
return defer.promise;

View File

@ -69,6 +69,10 @@
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) {
-moz-appearance: none;
border-style: none;
@ -108,6 +112,10 @@
padding-bottom: 2px;
}
#nav-bar:-moz-lwtheme {
box-shadow: 0 1px 0 @toolbarHighlightLWT@ inset;
}
#nav-bar-overflow-button {
-moz-image-region: rect(-5px, 12px, 11px, -4px);
}
@ -1789,7 +1797,13 @@ toolbarbutton.chevron > .toolbarbutton-icon {
%include ../shared/fullscreen/warning.inc.css
%include ../../../devtools/client/themes/responsivedesign.inc.css
%include ../../../devtools/client/themes/commandline.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 downloads/indicator.css

View File

@ -4,7 +4,8 @@
%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 fgTabTextureLWT @fgTabTexture@
%define fgTabTextureLWT linear-gradient(transparent 2px, @toolbarHighlightLWT@ 2px, @toolbarHighlightLWT@)
%define fgTabBackgroundColor -moz-dialog

View File

@ -2501,7 +2501,19 @@ notification[value="translation"] {
%include ../shared/fullscreen/warning.inc.css
%include ../../../devtools/client/themes/responsivedesign.inc.css
%include ../../../devtools/client/themes/commandline.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 downloads/indicator.css

View File

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

View File

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

View File

@ -47,20 +47,22 @@ button {
/* Targets */
.targets {
margin-bottom: 25px;
margin-bottom: 35px;
}
.target {
.target-container {
margin-top: 5px;
min-height: 34px;
display: flex;
flex-direction: row;
align-items: center;
align-items: baseline;
}
.target-icon {
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]) {
@ -71,15 +73,55 @@ button {
filter: invert(30%);
}
.target-details {
.target {
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 {
display: flex;
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 {
flex: 1;
}

View File

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

View File

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

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',
'addon-target.js',
'addons-controls.js',
'addons-install-error.js',
'addons-tab.js',
'service-worker-target.js',
'tab-header.js',
'tab-menu-entry.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/. */
/* eslint-env browser */
/* globals gDevTools, TargetFactory, Toolbox */
"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 } =
require("devtools/client/shared/vendor/react");
const { debugWorker } = require("../modules/worker");
const Services = require("Services");
const Strings = Services.strings.createBundle(
@ -26,86 +19,26 @@ module.exports = createClass({
render() {
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({
className: "target-icon",
role: "presentation",
src: target.icon
}),
dom.div({ className: "target-details" },
dom.div({ className: "target" },
dom.div({ className: "target-name" }, target.name)
),
(isRunning && isServiceWorker ?
dom.button({
className: "push-button",
onClick: this.push
}, Strings.GetStringFromName("push")) :
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"))
)
dom.button({
className: "debug-button",
onClick: this.debug,
disabled: debugDisabled
}, Strings.GetStringFromName("debug"))
);
},
debug() {
let { client, target } = this.props;
if (!this.isRunning()) {
// 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;
},
debugWorker(client, target.workerActor);
}
});

View File

@ -7,12 +7,13 @@
const { Ci } = require("chrome");
const { createClass, createFactory, DOM: dom } =
require("devtools/client/shared/vendor/react");
const { Task } = require("resource://gre/modules/Task.jsm");
const { getWorkerForms } = require("../modules/worker");
const Services = require("Services");
const TabHeader = createFactory(require("./tab-header"));
const TargetList = createFactory(require("./target-list"));
const WorkerTarget = createFactory(require("./worker-target"));
const ServiceWorkerTarget = createFactory(require("./service-worker-target"));
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
@ -50,7 +51,6 @@ module.exports = createClass({
render() {
let { client } = this.props;
let { workers } = this.state;
let targetClass = WorkerTarget;
return dom.div({
id: "tab-workers",
@ -67,21 +67,21 @@ module.exports = createClass({
client,
id: "service-workers",
name: Strings.GetStringFromName("serviceWorkers"),
targetClass,
targetClass: ServiceWorkerTarget,
targets: workers.service
}),
TargetList({
client,
id: "shared-workers",
name: Strings.GetStringFromName("sharedWorkers"),
targetClass,
targetClass: WorkerTarget,
targets: workers.shared
}),
TargetList({
client,
id: "other-workers",
name: Strings.GetStringFromName("otherWorkers"),
targetClass,
targetClass: WorkerTarget,
targets: workers.other
})
));
@ -90,7 +90,7 @@ module.exports = createClass({
update() {
let workers = this.getInitialState().workers;
this.getWorkerForms().then(forms => {
getWorkerForms(this.props.client).then(forms => {
forms.registrations.forEach(form => {
workers.service.push({
icon: WorkerIcon,
@ -136,40 +136,5 @@ module.exports = createClass({
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 += [
'components',
'modules',
]
BROWSER_CHROME_MANIFESTS += [

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
// 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.
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;

View File

@ -7,7 +7,7 @@
// Test that the controller provides the document.timeline currentTime (at least
// the last known version since new animations were added).
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
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 L10N = new LocalizationHelper(STRINGS_URI);
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, window} = yield openAnimationInspector();
let {document} = window;

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@
// 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");
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 is emitted *after* the animation panel is ready.
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, controller} = yield openAnimationInspector();

View File

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

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@ requestLongerTimeout(2);
// 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");
let {inspector, panel} = yield openAnimationInspector();

View File

@ -8,7 +8,7 @@ requestLongerTimeout(2);
// Test that the panel content refreshes when animations are removed.
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
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.
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
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 L10N = new LocalizationHelper(STRINGS_URI);
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;

View File

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

View File

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

View File

@ -10,7 +10,7 @@
// 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
// play/resume button will be displayed
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, window} = yield openAnimationInspector();
let {playTimelineButtonEl} = panel;

View File

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// 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.
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
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
// 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");
let {panel} = yield openAnimationInspector();

View File

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

View File

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

View File

@ -6,7 +6,7 @@
// 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");
let {panel} = yield openAnimationInspector();
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
// the timeline does the right thing.
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
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
// have mixed rates.
add_task(function*() {
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, controller, inspector, toolbox} = yield openAnimationInspector();

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