Merge m-c to inbound a=merge

This commit is contained in:
Wes Kocher 2016-08-17 17:24:02 -07:00
commit a177bd0ff1
397 changed files with 6069 additions and 2690 deletions

View File

@ -94,10 +94,6 @@ ifneq (,$(filter WINNT Darwin Android,$(OS_TARGET)))
DEFINES += -DMOZ_SHARED_MOZGLUE=1
endif
ifneq (,$(filter rtsp,$(NECKO_PROTOCOLS)))
DEFINES += -DMOZ_RTSP
endif
DEFINES += -DMOZ_ICU_VERSION=$(MOZ_ICU_VERSION)
ifdef MOZ_SYSTEM_ICU
DEFINES += -DMOZ_SYSTEM_ICU

View File

@ -273,9 +273,6 @@
@RESPATH@/components/necko_websocket.xpt
@RESPATH@/components/necko_wifi.xpt
@RESPATH@/components/necko_wyciwyg.xpt
#ifdef MOZ_RTSP
@RESPATH@/components/necko_rtsp.xpt
#endif
@RESPATH@/components/necko.xpt
@RESPATH@/components/loginmgr.xpt
@RESPATH@/components/parentalcontrols.xpt

View File

@ -1318,7 +1318,18 @@ pref("ui.key.menuAccessKeyFocuses", true);
#endif
// Encrypted media extensions.
#ifdef XP_LINUX
// On Linux EME is visible but disabled by default. This is so that the
// "Play DRM content" checkbox in the Firefox UI is unchecked by default.
// DRM requires downloading and installing proprietary binaries, which
// users on an open source operating systems didn't opt into. The first
// time a site using EME is encountered, the user will be prompted to
// enable DRM, whereupon the EME plugin binaries will be downloaded if
// permission is granted.
pref("media.eme.enabled", false);
#else
pref("media.eme.enabled", true);
#endif
pref("media.eme.apiVisible", true);
// Decode using Gecko Media Plugins in <video>, if a system decoder is not
@ -1350,17 +1361,8 @@ pref("media.gmp-eme-adobe.enabled", true);
#ifdef MOZ_WIDEVINE_EME
pref("media.gmp-widevinecdm.visible", true);
// On Linux Widevine is visible but disabled by default. This is because
// enabling Widevine downloads a proprietary binary, which users on an open
// source operating system didn't opt into. The first time a site using EME
// is encountered, the user will be prompted to enable EME, whereupon the
// EME plugin binary will be downloaded if permission is granted.
#ifdef XP_LINUX
pref("media.gmp-widevinecdm.enabled", false);
#else
pref("media.gmp-widevinecdm.enabled", true);
#endif
#endif
// Play with different values of the decay time and get telemetry,
// 0 means to randomize (and persist) the experiment value in users' profiles,

View File

@ -42,7 +42,7 @@ function init(aEvent)
let version = Services.appinfo.version;
if (/a\d+$/.test(version)) {
let buildID = Services.appinfo.appBuildID;
let buildDate = buildID.slice(0,4) + "-" + buildID.slice(4,6) + "-" + buildID.slice(6,8);
let buildDate = buildID.slice(0, 4) + "-" + buildID.slice(4, 6) + "-" + buildID.slice(6, 8);
document.getElementById("version").textContent += " (" + buildDate + ")";
document.getElementById("experimental").hidden = false;
document.getElementById("communityDesc").hidden = true;

View File

@ -150,7 +150,7 @@ var healthReportWrapper = {
initRemotePage: function () {
let iframe = document.getElementById("remote-report").contentDocument;
iframe.addEventListener("RemoteHealthReportCommand",
function onCommand(e) {healthReportWrapper.handleRemoteCommand(e);},
function onCommand(e) { healthReportWrapper.handleRemoteCommand(e); },
false);
healthReportWrapper.updatePrefState();
},

View File

@ -54,7 +54,7 @@ Cu.import("resource://gre/modules/NotificationDB.jsm");
["fxAccounts", "resource://gre/modules/FxAccounts.jsm"],
["gDevTools", "resource://devtools/client/framework/gDevTools.jsm"],
["gDevToolsBrowser", "resource://devtools/client/framework/gDevTools.jsm"],
["webrtcUI", "resource:///modules/webrtcUI.jsm",],
["webrtcUI", "resource:///modules/webrtcUI.jsm", ]
].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource));
if (AppConstants.MOZ_SAFE_BROWSING) {
@ -741,7 +741,7 @@ function gKeywordURIFixup({ target: browser, data: fixupInfo }) {
}
];
let notification =
notificationBox.appendNotification(message,"keyword-uri-fixup", null,
notificationBox.appendNotification(message, "keyword-uri-fixup", null,
notificationBox.PRIORITY_INFO_HIGH,
buttons);
notification.persistence = 1;
@ -2850,7 +2850,7 @@ var BrowserOnClick = {
}
window.openDialog('chrome://pippki/content/exceptionDialog.xul',
'','chrome,centerscreen,modal', params);
'', 'chrome,centerscreen,modal', params);
// If the user added the exception cert, attempt to reload the page
if (params.exceptionAdded) {
@ -5205,7 +5205,7 @@ var gHomeButton = {
homeButton = document.getElementById("home-button");
if (homeButton) {
var homePage = this.getHomePage();
homePage = homePage.replace(/\|/g,', ');
homePage = homePage.replace(/\|/g, ', ');
if (homePage.toLowerCase() == "about:home")
homeButton.setAttribute("tooltiptext", homeButton.getAttribute("aboutHomeOverrideTooltip"));
else

View File

@ -1194,7 +1194,7 @@ var PageInfoListener = {
// TODO: Reimplement once bug 714757 is fixed.
let strVal = val.getStringValue();
if (strVal.search(/^.*url\(\"?/) > -1) {
let url = strVal.replace(/^.*url\(\"?/,"").replace(/\"?\).*$/,"");
let url = strVal.replace(/^.*url\(\"?/, "").replace(/\"?\).*$/, "");
addImage(url, label, strings.notSet, elem, true);
}
}

View File

@ -643,7 +643,7 @@ function openURL(target)
window.open(url, "_blank", "chrome");
}
function onBeginLinkDrag(event,urlField,descField)
function onBeginLinkDrag(event, urlField, descField)
{
if (event.originalTarget.localName != "treechildren")
return;

View File

@ -4661,8 +4661,8 @@
return [];
},
// Also support adding event listeners (forward to the tab container)
addEventListener: function (a,b,c) { this.self.tabContainer.addEventListener(a,b,c); },
removeEventListener: function (a,b,c) { this.self.tabContainer.removeEventListener(a,b,c); }
addEventListener: function (a, b, c) { this.self.tabContainer.addEventListener(a, b, c); },
removeEventListener: function (a, b, c) { this.self.tabContainer.removeEventListener(a, b, c); }
});
]]>
</getter>

View File

@ -543,7 +543,7 @@ function isBidiEnabled() {
try {
var localeService = Components.classes["@mozilla.org/intl/nslocaleservice;1"]
.getService(Components.interfaces.nsILocaleService);
var systemLocale = localeService.getSystemLocale().getCategory("NSILOCALE_CTYPE").substr(0,3);
var systemLocale = localeService.getSystemLocale().getCategory("NSILOCALE_CTYPE").substr(0, 3);
switch (systemLocale) {
case "ar-":

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1074,7 +1074,7 @@ var CustomizableUIInternal = {
}
}
for (let [,widget] of gPalette) {
for (let [, widget] of gPalette) {
widget.instances.delete(document);
this.notifyListeners("onWidgetInstanceRemoved", widget.id, document);
}
@ -2545,7 +2545,7 @@ var CustomizableUIInternal = {
// Clear the saved state to ensure that defaults will be used.
gSavedState = null;
// Restore the state for each area to its defaults
for (let [areaId,] of gAreas) {
for (let [areaId, ] of gAreas) {
this.restoreStateForArea(areaId);
}
},
@ -2665,7 +2665,7 @@ var CustomizableUIInternal = {
if (!widgetNode) {
// Pick any of the build windows to look at.
let [window,] = [...gBuildWindows][0];
let [window, ] = [...gBuildWindows][0];
[, widgetNode] = this.getWidgetNode(widgetId, window);
}
// If we don't have a node, we assume it's removable. This can happen because
@ -2899,7 +2899,7 @@ this.CustomizableUI = {
*/
windows: {
*[Symbol.iterator]() {
for (let [window,] of gBuildWindows)
for (let [window, ] of gBuildWindows)
yield window;
}
},
@ -3771,7 +3771,7 @@ function WidgetGroupWrapper(aWidget) {
this.__defineSetter__("disabled", function(aValue) {
aValue = !!aValue;
aWidget.disabled = aValue;
for (let [,instance] of aWidget.instances) {
for (let [, instance] of aWidget.instances) {
instance.disabled = aValue;
}
});

View File

@ -363,7 +363,7 @@ Settings.prototype = {
// Final string is sorted by quality (q=) param.
function parseAcceptLanguageList(v) {
return v.match(/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/gi)
.sort(function (a , b) {
.sort(function (a, b) {
let qA = parseFloat(a.split(";q=")[1]) || 1.0;
let qB = parseFloat(b.split(";q=")[1]) || 1.0;
return qB - qA;

View File

@ -70,7 +70,7 @@ add_task(function test_LinkChecker_securityCheck() {
];
for (let {url, expected} of urls) {
let observed = PlacesProvider.LinkChecker.checkLoadURI(url);
equal(observed , expected, `can load "${url}"?`);
equal(observed, expected, `can load "${url}"?`);
}
});

View File

@ -727,12 +727,12 @@ BrowserGlue.prototype = {
let buildID = Services.appinfo.appBuildID;
let today = new Date().getTime();
let buildDate = new Date(buildID.slice(0,4), // year
buildID.slice(4,6) - 1, // months are zero-based.
buildID.slice(6,8), // day
buildID.slice(8,10), // hour
buildID.slice(10,12), // min
buildID.slice(12,14)) // ms
let buildDate = new Date(buildID.slice(0, 4), // year
buildID.slice(4, 6) - 1, // months are zero-based.
buildID.slice(6, 8), // day
buildID.slice(8, 10), // hour
buildID.slice(10, 12), // min
buildID.slice(12, 14)) // ms
.getTime();
const millisecondsIn24Hours = 86400000;

View File

@ -736,7 +736,7 @@ var PlacesOrganizer = {
ctx.fillStyle = "GrayText";
ctx.mozTextStyle = "12pt sans serif";
var len = ctx.mozMeasureText(notAvailableText);
ctx.translate(-len/2,0);
ctx.translate(-len/2, 0);
ctx.mozDrawText(notAvailableText);
ctx.restore();
},

View File

@ -30,7 +30,7 @@ add_task(function* () {
yield waitForCondition(function* () {
entry = yield PlacesUtils.keywords.fetch("kw");
return !!entry;
},"Unable to find the expected keyword");
}, "Unable to find the expected keyword");
is(entry.keyword, "kw", "keyword is correct");
is(entry.url.href, TEST_URL, "URL is correct");
is(entry.postData, "accenti%3D%E0%E8%EC%F2%F9&search%3D%25s", "POST data is correct");

View File

@ -72,7 +72,7 @@ function synthesizeDragWithDirection(aElement, aExpectedDragData, aDirection, aC
aCallback()
}, false);
var prevent = function(aEvent) {aEvent.preventDefault();}
var prevent = function(aEvent) { aEvent.preventDefault(); }
var xIncrement = 0;
var yIncrement = 0;

View File

@ -20,7 +20,7 @@ var gConnectionsDialog = {
var shareProxiesPref = document.getElementById("network.proxy.share_proxy_settings");
// If the port is 0 and the proxy server is specified, focus on the port and cancel submission.
for (let prefName of ["http","ssl","ftp","socks"]) {
for (let prefName of ["http", "ssl", "ftp", "socks"]) {
let proxyPortPref = document.getElementById("network.proxy." + prefName + "_port");
let proxyPref = document.getElementById("network.proxy." + prefName);
// Only worry about ports which are currently active. If the share option is on, then ignore

View File

@ -167,7 +167,7 @@ function helpButtonCommand() {
function friendlyPrefCategoryNameToInternalName(aName) {
if (aName.startsWith("pane"))
return aName;
return "pane" + aName.substring(0,1).toUpperCase() + aName.substr(1);
return "pane" + aName.substring(0, 1).toUpperCase() + aName.substr(1);
}
// This function is duplicated inside of utilityOverlay.js's openPreferences.

View File

@ -18,13 +18,13 @@ function initTest() {
cm.removeAll();
// data for cookies
var vals = [[searchTerm+".com", dummyTerm, dummyTerm], // match
[searchTerm+".org", dummyTerm, dummyTerm], // match
[dummyTerm+".com", searchTerm, dummyTerm], // match
[dummyTerm+".edu", searchTerm+dummyTerm, dummyTerm],// match
[dummyTerm+".net", dummyTerm, searchTerm], // match
[dummyTerm+".org", dummyTerm, searchTerm+dummyTerm],// match
[dummyTerm+".int", dummyTerm, dummyTerm]]; // no match
var vals = [[searchTerm+".com", dummyTerm, dummyTerm], // match
[searchTerm+".org", dummyTerm, dummyTerm], // match
[dummyTerm+".com", searchTerm, dummyTerm], // match
[dummyTerm+".edu", searchTerm+dummyTerm, dummyTerm], // match
[dummyTerm+".net", dummyTerm, searchTerm], // match
[dummyTerm+".org", dummyTerm, searchTerm+dummyTerm], // match
[dummyTerm+".int", dummyTerm, dummyTerm]]; // no match
// matches must correspond to above data
const matches = 6;
@ -46,7 +46,7 @@ function initTest() {
"Browser:Cookies", "", {});
// when it has loaded, run actual tests
cmd.addEventListener("load", function() {executeSoon(function() {runTest(cmd, searchTerm, vals.length, matches);});}, false);
cmd.addEventListener("load", function() { executeSoon(function() { runTest(cmd, searchTerm, vals.length, matches); }); }, false);
}
function isDisabled(win, expectation) {

View File

@ -51,7 +51,7 @@ var gPermissionManager = {
cycleHeader: function(column) {},
getRowProperties: function(row) { return ""; },
getColumnProperties: function(column) { return ""; },
getCellProperties: function(row,column) {
getCellProperties: function(row, column) {
if (column.element.getAttribute("id") == "siteCol")
return "ltr";

View File

@ -111,6 +111,7 @@ skip-if = e10s # Bug 1271024
[browser_scrollPositionsReaderMode.js]
[browser_sessionHistory.js]
[browser_sessionStorage.js]
[browser_sessionStorage_size.js]
[browser_swapDocShells.js]
[browser_switch_remoteness.js]
run-if = e10s

View File

@ -183,46 +183,6 @@ add_task(function respect_privacy_level() {
"https sessionStorage data has been saved");
});
// Test that we record the size of messages.
add_task(function* test_telemetry() {
Services.telemetry.canRecordExtended = true;
let histogram = Services.telemetry.getHistogramById("FX_SESSION_RESTORE_DOM_STORAGE_SIZE_ESTIMATE_CHARS");
let snap1 = histogram.snapshot();
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
// Flush to make sure chrome received all data.
yield TabStateFlusher.flush(browser);
let snap2 = histogram.snapshot();
Assert.ok(snap2.counts[5] > snap1.counts[5]);
yield promiseRemoveTab(tab);
Services.telemetry.canRecordExtended = false;
});
// Lower the size limit for DOM Storage content. Check that DOM Storage
// is not updated, but that other things remain updated.
add_task(function* test_large_content() {
Services.prefs.setIntPref("browser.sessionstore.dom_storage_limit", 5);
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
// Flush to make sure chrome received all data.
yield TabStateFlusher.flush(browser);
let state = JSON.parse(ss.getTabState(tab));
info(JSON.stringify(state, null, "\t"));
Assert.equal(state.storage, null, "We have no storage for the tab");
Assert.equal(state.entries[0].title, OUTER_VALUE);
yield promiseRemoveTab(tab);
Services.prefs.clearUserPref("browser.sessionstore.dom_storage_limit");
});
function purgeDomainData(browser, domain) {
return sendMessage(browser, "ss-test:purgeDomainData", domain);
}

View File

@ -0,0 +1,51 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const RAND = Math.random();
const URL = "http://mochi.test:8888/browser/" +
"browser/components/sessionstore/test/browser_sessionStorage.html" +
"?" + RAND;
const OUTER_VALUE = "outer-value-" + RAND;
// Test that we record the size of messages.
add_task(function* test_telemetry() {
Services.telemetry.canRecordExtended = true;
let histogram = Services.telemetry.getHistogramById("FX_SESSION_RESTORE_DOM_STORAGE_SIZE_ESTIMATE_CHARS");
let snap1 = histogram.snapshot();
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
// Flush to make sure chrome received all data.
yield TabStateFlusher.flush(browser);
let snap2 = histogram.snapshot();
Assert.ok(snap2.counts[5] > snap1.counts[5]);
yield promiseRemoveTab(tab);
Services.telemetry.canRecordExtended = false;
});
// Lower the size limit for DOM Storage content. Check that DOM Storage
// is not updated, but that other things remain updated.
add_task(function* test_large_content() {
Services.prefs.setIntPref("browser.sessionstore.dom_storage_limit", 5);
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
// Flush to make sure chrome received all data.
yield TabStateFlusher.flush(browser);
let state = JSON.parse(ss.getTabState(tab));
info(JSON.stringify(state, null, "\t"));
Assert.equal(state.storage, null, "We have no storage for the tab");
Assert.equal(state.entries[0].title, OUTER_VALUE);
yield promiseRemoveTab(tab);
Services.prefs.clearUserPref("browser.sessionstore.dom_storage_limit");
});

View File

@ -91,12 +91,12 @@ add_task(function* testSyncedTabsSidebarList() {
SyncedTabs._internal = {
isConfiguredToSyncTabs: true,
hasSyncedThisSession: true,
getTabClients() { return Promise.resolve([])},
syncTabs() {return Promise.resolve();},
getTabClients() { return Promise.resolve([]) },
syncTabs() { return Promise.resolve(); },
};
sinon.stub(syncedTabsDeckComponent, "_accountStatus", ()=> Promise.resolve(true));
sinon.stub(SyncedTabs._internal, "getTabClients", ()=> Promise.resolve(Cu.cloneInto(FIXTURE, {})));
sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.resolve(true));
sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve(Cu.cloneInto(FIXTURE, {})));
yield syncedTabsDeckComponent.updatePanel();
// This is a hacky way of waiting for the view to render. The view renders
@ -144,12 +144,12 @@ add_task(function* testSyncedTabsSidebarFilteredList() {
SyncedTabs._internal = {
isConfiguredToSyncTabs: true,
hasSyncedThisSession: true,
getTabClients() { return Promise.resolve([])},
syncTabs() {return Promise.resolve();},
getTabClients() { return Promise.resolve([]) },
syncTabs() { return Promise.resolve(); },
};
sinon.stub(syncedTabsDeckComponent, "_accountStatus", ()=> Promise.resolve(true));
sinon.stub(SyncedTabs._internal, "getTabClients", ()=> Promise.resolve(Cu.cloneInto(FIXTURE, {})));
sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.resolve(true));
sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve(Cu.cloneInto(FIXTURE, {})));
yield syncedTabsDeckComponent.updatePanel();
// This is a hacky way of waiting for the view to render. The view renders
@ -204,7 +204,7 @@ add_task(function* testSyncedTabsSidebarStatus() {
isConfiguredToSyncTabs: false,
hasSyncedThisSession: false,
getTabClients() {},
syncTabs() {return Promise.resolve();},
syncTabs() { return Promise.resolve(); },
};
Assert.ok(syncedTabsDeckComponent, "component exists");
@ -212,7 +212,7 @@ add_task(function* testSyncedTabsSidebarStatus() {
sinon.spy(syncedTabsDeckComponent, "updatePanel");
sinon.spy(syncedTabsDeckComponent, "observe");
sinon.stub(syncedTabsDeckComponent, "_accountStatus", ()=> Promise.reject("Test error"));
sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.reject("Test error"));
yield syncedTabsDeckComponent.updatePanel();
let selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
@ -220,7 +220,7 @@ add_task(function* testSyncedTabsSidebarStatus() {
"not-authed panel is selected on auth error");
syncedTabsDeckComponent._accountStatus.restore();
sinon.stub(syncedTabsDeckComponent, "_accountStatus", ()=> Promise.resolve(accountExists));
sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.resolve(accountExists));
yield syncedTabsDeckComponent.updatePanel();
selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
Assert.ok(selectedPanel.classList.contains("notAuthedInfo"),
@ -239,14 +239,14 @@ add_task(function* testSyncedTabsSidebarStatus() {
"tabs fetch panel is selected");
SyncedTabs._internal.hasSyncedThisSession = true;
sinon.stub(SyncedTabs._internal, "getTabClients", ()=> Promise.resolve([]));
sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve([]));
yield syncedTabsDeckComponent.updatePanel();
selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
Assert.ok(selectedPanel.classList.contains("singleDeviceInfo"),
"tabs fetch panel is selected");
SyncedTabs._internal.getTabClients.restore();
sinon.stub(SyncedTabs._internal, "getTabClients", ()=> Promise.resolve([{id: "mock"}]));
sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve([{id: "mock"}]));
yield syncedTabsDeckComponent.updatePanel();
selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
Assert.ok(selectedPanel.classList.contains("tabs-container"),
@ -266,12 +266,12 @@ add_task(function* testSyncedTabsSidebarContextMenu() {
SyncedTabs._internal = {
isConfiguredToSyncTabs: true,
hasSyncedThisSession: true,
getTabClients() { return Promise.resolve([])},
syncTabs() {return Promise.resolve();},
getTabClients() { return Promise.resolve([]) },
syncTabs() { return Promise.resolve(); },
};
sinon.stub(syncedTabsDeckComponent, "_accountStatus", ()=> Promise.resolve(true));
sinon.stub(SyncedTabs._internal, "getTabClients", ()=> Promise.resolve(Cu.cloneInto(FIXTURE, {})));
sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.resolve(true));
sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve(Cu.cloneInto(FIXTURE, {})));
yield syncedTabsDeckComponent.updatePanel();
// This is a hacky way of waiting for the view to render. The view renders

View File

@ -17,7 +17,7 @@ add_task(function* testInitUninit() {
let view = {render: sinon.spy(), destroy: sinon.spy(), container: {}};
ViewMock.returns(view);
sinon.stub(SyncedTabs, "syncTabs", ()=> Promise.resolve());
sinon.stub(SyncedTabs, "syncTabs", () => Promise.resolve());
sinon.spy(deckStore, "on");
sinon.stub(deckStore, "setPanels");
@ -86,7 +86,7 @@ add_task(function* testObserver() {
let view = {render: sinon.spy(), destroy: sinon.spy(), container: {}};
ViewMock.returns(view);
sinon.stub(SyncedTabs, "syncTabs", ()=> Promise.resolve());
sinon.stub(SyncedTabs, "syncTabs", () => Promise.resolve());
sinon.spy(deckStore, "on");
sinon.stub(deckStore, "setPanels");
@ -146,7 +146,7 @@ add_task(function* testPanelStatus() {
});
let isAuthed = false;
sinon.stub(fxAccounts, "accountStatus", ()=> Promise.resolve(isAuthed));
sinon.stub(fxAccounts, "accountStatus", () => Promise.resolve(isAuthed));
let result = yield component.getPanelStatus();
Assert.equal(result, component.PANELS.NOT_AUTHED_INFO);
@ -165,7 +165,7 @@ add_task(function* testPanelStatus() {
SyncedTabsMock.hasSyncedThisSession = true;
let clients = [];
sinon.stub(SyncedTabsMock, "getTabClients", ()=> Promise.resolve(clients));
sinon.stub(SyncedTabsMock, "getTabClients", () => Promise.resolve(clients));
result = yield component.getPanelStatus();
Assert.equal(result, component.PANELS.SINGLE_DEVICE_INFO);
@ -174,11 +174,11 @@ add_task(function* testPanelStatus() {
Assert.equal(result, component.PANELS.TABS_CONTAINER);
fxAccounts.accountStatus.restore();
sinon.stub(fxAccounts, "accountStatus", ()=> Promise.reject("err"));
sinon.stub(fxAccounts, "accountStatus", () => Promise.reject("err"));
result = yield component.getPanelStatus();
Assert.equal(result, component.PANELS.NOT_AUTHED_INFO);
sinon.stub(component, "getPanelStatus", ()=> Promise.resolve("mock-panelId"));
sinon.stub(component, "getPanelStatus", () => Promise.resolve("mock-panelId"));
sinon.spy(deckStore, "selectPanel");
yield component.updatePanel();
Assert.ok(deckStore.selectPanel.calledWith("mock-panelId"));

View File

@ -60,7 +60,7 @@ function is_hidden(element) {
if (style.visibility != "visible")
return true;
if (style.display == "-moz-popup")
return ["hiding","closed"].indexOf(element.state) != -1;
return ["hiding", "closed"].indexOf(element.state) != -1;
// Hiding a parent element will hide all its children
if (element.parentNode != element.ownerDocument)

View File

@ -245,7 +245,7 @@ add_task(function* test_times() {
{startTime: nowSec - 5 * SEC_IN_ONE_DAY,
endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
[true, null, now,
{startTime: nowSec ,
{startTime: nowSec,
endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
[false, "startTime", now,
{startTime: nowSec + 5 * SEC_IN_ONE_DAY,

View File

@ -28,7 +28,7 @@ var pktPanelMessaging = (function() {
// TODO: Figure out why e.target.parentNode is null
// e.target.parentNode.removeChild(e.target);
},false);
}, false);
}

View File

@ -27,7 +27,7 @@ var PKT_SAVED_OVERLAY = function (options)
this.cxt_suggested = 0;
this.cxt_removed = 0;
this.justaddedsuggested = false;
this.fillTagContainer = function(tags,container,tagclass) {
this.fillTagContainer = function(tags, container, tagclass) {
var newtagleft = 0;
container.children().remove();
for (var i = 0; i < tags.length; i++) {
@ -39,7 +39,7 @@ var PKT_SAVED_OVERLAY = function (options)
}
};
this.fillUserTags = function() {
thePKT_SAVED.sendMessage("getTags",{},function(resp)
thePKT_SAVED.sendMessage("getTags", {}, function(resp)
{
if (typeof resp == 'object' && typeof resp.tags == 'object')
{
@ -73,7 +73,7 @@ var PKT_SAVED_OVERLAY = function (options)
if (!myself.mouseInside) {
myself.startCloseTimer();
}
myself.fillTagContainer(newtags,$('.pkt_ext_suggestedtag_detail ul'),'token_suggestedtag');
myself.fillTagContainer(newtags, $('.pkt_ext_suggestedtag_detail ul'), 'token_suggestedtag');
}
else if (resp.status == 'error') {
var msg = $('<p class="suggestedtag_msg">');
@ -87,15 +87,15 @@ var PKT_SAVED_OVERLAY = function (options)
});
}
this.initAutoCloseEvents = function() {
this.wrapper.on('mouseenter',function() {
this.wrapper.on('mouseenter', function() {
myself.mouseInside = true;
myself.stopCloseTimer();
});
this.wrapper.on('mouseleave',function() {
this.wrapper.on('mouseleave', function() {
myself.mouseInside = false;
myself.startCloseTimer();
});
this.wrapper.on('click',function(e) {
this.wrapper.on('click', function(e) {
myself.closeValid = false;
});
};
@ -148,21 +148,21 @@ var PKT_SAVED_OVERLAY = function (options)
if ((inputleft + listleft + 20) > leftwidth)
{
$('.token-input-list').css('left',Math.min(((inputleft + listleftnatural - leftwidth + 20)*-1),0) + 'px');
$('.token-input-list').css('left', Math.min(((inputleft + listleftnatural - leftwidth + 20)*-1), 0) + 'px');
}
else
{
$('.token-input-list').css('left','0');
$('.token-input-list').css('left', '0');
}
};
this.checkPlaceholderStatus = function() {
if (this.wrapper.find('.pkt_ext_tag_input_wrapper').find('.token-input-token').length)
{
this.wrapper.find('.token-input-input-token input').attr('placeholder','');
this.wrapper.find('.token-input-input-token input').attr('placeholder', '');
}
else
{
this.wrapper.find('.token-input-input-token input').attr('placeholder',$('.pkt_ext_tag_input').attr('placeholder')).css('width','200px');
this.wrapper.find('.token-input-input-token input').attr('placeholder', $('.pkt_ext_tag_input').attr('placeholder')).css('width', '200px');
}
};
this.initTagInput = function() {
@ -187,7 +187,7 @@ var PKT_SAVED_OVERLAY = function (options)
}
}
if (!$('.token-input-dropdown-tag').data('init')) {
$('.token-input-dropdown-tag').css('width',inputwrapper.outerWidth()).data('init');
$('.token-input-dropdown-tag').css('width', inputwrapper.outerWidth()).data('init');
inputwrapper.append($('.token-input-dropdown-tag'));
}
cb(returnlist);
@ -199,7 +199,7 @@ var PKT_SAVED_OVERLAY = function (options)
changestamp = Date.now();
setTimeout(function() {
$('.token-input-input-token input').val(text).focus();
},10);
}, 10);
}
return null;
}
@ -208,32 +208,32 @@ var PKT_SAVED_OVERLAY = function (options)
},
onReady: function() {
$('.token-input-dropdown').addClass('token-input-dropdown-tag');
inputwrapper.find('.token-input-input-token input').attr('placeholder',$('.tag-input').attr('placeholder')).css('width','200px');
inputwrapper.find('.token-input-input-token input').attr('placeholder', $('.tag-input').attr('placeholder')).css('width', '200px');
if ($('.pkt_ext_suggestedtag_detail').length) {
myself.wrapper.find('.pkt_ext_suggestedtag_detail').on('click','.token_tag',function(e) {
myself.wrapper.find('.pkt_ext_suggestedtag_detail').on('click', '.token_tag', function(e) {
e.preventDefault();
var tag = $(e.target);
if ($(this).parents('.pkt_ext_suggestedtag_detail_disabled').length) {
return;
}
myself.justaddedsuggested = true;
inputwrapper.find('.pkt_ext_tag_input').tokenInput('add',{id:inputwrapper.find('.token-input-token').length,name:tag.text()});
inputwrapper.find('.pkt_ext_tag_input').tokenInput('add', {id:inputwrapper.find('.token-input-token').length, name:tag.text()});
tag.addClass('token-suggestedtag-inactive');
$('.token-input-input-token input').focus();
});
}
$('.token-input-list').on('keydown','input',function(e) {
$('.token-input-list').on('keydown', 'input', function(e) {
if (e.which == 37) {
myself.updateSlidingTagList();
}
}).on('keypress','input',function(e) {
}).on('keypress', 'input', function(e) {
if (e.which == 13) {
if (typeof changestamp == 'undefined' || (Date.now() - changestamp > 250)) {
e.preventDefault();
myself.wrapper.find('.pkt_ext_btn').trigger('click');
}
}
}).on('keyup','input',function(e) {
}).on('keyup', 'input', function(e) {
myself.checkValidTagSubmit();
});
myself.checkPlaceholderStatus();
@ -257,14 +257,14 @@ var PKT_SAVED_OVERLAY = function (options)
thePKT_SAVED.sendMessage("collapseSavePanel");
}
});
$('body').on('keydown',function(e) {
$('body').on('keydown', function(e) {
var key = e.keyCode || e.which;
if (key == 8) {
var selected = $('.token-input-selected-token');
if (selected.length) {
e.preventDefault();
e.stopImmediatePropagation();
inputwrapper.find('.pkt_ext_tag_input').tokenInput('remove',{name:selected.find('p').text()});
inputwrapper.find('.pkt_ext_tag_input').tokenInput('remove', {name:selected.find('p').text()});
}
}
else if ($(e.target).parent().hasClass('token-input-input-token')) {
@ -338,7 +338,7 @@ var PKT_SAVED_OVERLAY = function (options)
thePKT_SAVED.sendMessage("deleteItem",
{
itemId: myself.savedItemId
},function(resp) {
}, function(resp) {
if (resp.status == 'success') {
myself.showStateFinalMsg(myself.dictJSON.pageremoved);
}
@ -379,7 +379,7 @@ var PKT_SAVED_OVERLAY = function (options)
});
var inactivetags = $('.pkt_ext_suggestedtag_detail').find('.token_tag_inactive');
inactivetags.each(function(index,element) {
inactivetags.each(function(index, element) {
if (activetokenstext.indexOf('|' + $(element).text() + '|') == -1) {
$(element).removeClass('token_tag_inactive');
}
@ -394,7 +394,7 @@ var PKT_SAVED_OVERLAY = function (options)
activetokenstext += $(element).find('p').text() + '|';
});
var activesuggestedtags = $('.token_tag').not('.token_tag_inactive');
activesuggestedtags.each(function(index,element) {
activesuggestedtags.each(function(index, element) {
if (activetokenstext.indexOf('|' + $(element).text() + '|') > -1) {
$(element).addClass('token_tag_inactive');
}
@ -435,7 +435,7 @@ var PKT_SAVED_OVERLAY = function (options)
});
};
this.showStateFinalMsg = function(msg) {
this.wrapper.find('.pkt_ext_tag_detail').one('webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd',function(e)
this.wrapper.find('.pkt_ext_tag_detail').one('webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd', function(e)
{
$(this).off('webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd');
myself.preventCloseTimerCancel = true;
@ -444,7 +444,7 @@ var PKT_SAVED_OVERLAY = function (options)
});
this.wrapper.addClass('pkt_ext_container_finalstate');
};
this.showStateError = function(headline,detail) {
this.showStateError = function(headline, detail) {
this.wrapper.find('.pkt_ext_detail h2').text(headline);
this.wrapper.find('.pkt_ext_detail h3').text(detail);
this.wrapper.addClass('pkt_ext_container_detailactive pkt_ext_container_finalstate pkt_ext_container_finalerrorstate');
@ -560,23 +560,23 @@ PKT_SAVED.prototype = {
thePKT_SAVED.sendMessage("show");
// wait confirmation of save before flipping to final saved state
thePKT_SAVED.addMessageListener("saveLink",function(resp)
thePKT_SAVED.addMessageListener("saveLink", function(resp)
{
if (resp.status == 'error') {
if (typeof resp.error == 'object')
{
if (resp.error.localizedKey)
{
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved,myself.overlay.dictJSON[resp.error.localizedKey]);
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved, myself.overlay.dictJSON[resp.error.localizedKey]);
}
else
{
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved,resp.error.message);
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved, resp.error.message);
}
}
else
{
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved,myself.overlay.dictJSON.errorgeneric);
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved, myself.overlay.dictJSON.errorgeneric);
}
return;
}

View File

@ -1,150 +1,150 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['saved_premiumextras'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
templates['saved_premiumextras'] = template({"compiler":[6, ">= 2.0.0-beta.1"], "main":function(depth0, helpers, partials, data) {
return "<div class=\"pkt_ext_suggestedtag_detailshown\">\n</div>";
},"useData":true});
templates['saved_premiumshell'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
}, "useData":true});
templates['saved_premiumshell'] = template({"compiler":[6, ">= 2.0.0-beta.1"], "main":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return "<div class=\"pkt_ext_suggestedtag_detail pkt_ext_suggestedtag_detail_loading\">\n <h4>"
+ escapeExpression(((helper = (helper = helpers.suggestedtags || (depth0 != null ? depth0.suggestedtags : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"suggestedtags","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.suggestedtags || (depth0 != null ? depth0.suggestedtags : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"suggestedtags", "hash":{}, "data":data}) : helper)))
+ "</h4>\n <div class=\"pkt_ext_loadingspinner\"><div></div></div>\n <ul class=\"pkt_ext_cf\">\n </ul>\n</div>";
},"useData":true});
templates['saved_shell'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
}, "useData":true});
templates['saved_shell'] = template({"compiler":[6, ">= 2.0.0-beta.1"], "main":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return "<div class=\"pkt_ext_initload\">\n <div class=\"pkt_ext_logo\"></div> \n <div class=\"pkt_ext_topdetail\">\n <h2>"
+ escapeExpression(((helper = (helper = helpers.saving || (depth0 != null ? depth0.saving : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"saving","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.saving || (depth0 != null ? depth0.saving : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"saving", "hash":{}, "data":data}) : helper)))
+ "</h2>\n </div> \n <div class=\"pkt_ext_loadingspinner\"><div></div></div>\n</div> \n<div class=\"pkt_ext_detail\"> \n <div class=\"pkt_ext_logo\"></div>\n <div class=\"pkt_ext_topdetail\">\n <h2>"
+ escapeExpression(((helper = (helper = helpers.pagesaved || (depth0 != null ? depth0.pagesaved : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pagesaved","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pagesaved || (depth0 != null ? depth0.pagesaved : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pagesaved", "hash":{}, "data":data}) : helper)))
+ "</h2>\n <h3 class=\"pkt_ext_errordetail\"></h3>\n <nav class=\"pkt_ext_item_actions pkt_ext_cf\">\n <ul>\n <li><a class=\"pkt_ext_removeitem\" href=\"#\">"
+ escapeExpression(((helper = (helper = helpers.removepage || (depth0 != null ? depth0.removepage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"removepage","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.removepage || (depth0 != null ? depth0.removepage : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"removepage", "hash":{}, "data":data}) : helper)))
+ "</a></li>\n <li class=\"pkt_ext_actions_separator\"></li> \n <li><a class=\"pkt_ext_openpocket\" href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "/a?src=ff_ext_saved\" target=\"_blank\">"
+ escapeExpression(((helper = (helper = helpers.viewlist || (depth0 != null ? depth0.viewlist : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"viewlist","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.viewlist || (depth0 != null ? depth0.viewlist : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"viewlist", "hash":{}, "data":data}) : helper)))
+ "</a></li>\n </ul>\n </nav> \n </div>\n <div class=\"pkt_ext_tag_detail pkt_ext_cf\">\n <div class=\"pkt_ext_tag_input_wrapper\">\n <div class=\"pkt_ext_tag_input_blocker\"></div>\n <input class=\"pkt_ext_tag_input\" type=\"text\" placeholder=\""
+ escapeExpression(((helper = (helper = helpers.addtags || (depth0 != null ? depth0.addtags : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"addtags","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.addtags || (depth0 != null ? depth0.addtags : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"addtags", "hash":{}, "data":data}) : helper)))
+ "\">\n </div>\n <a href=\"#\" class=\"pkt_ext_btn pkt_ext_btn_disabled\">"
+ escapeExpression(((helper = (helper = helpers.save || (depth0 != null ? depth0.save : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"save","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.save || (depth0 != null ? depth0.save : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"save", "hash":{}, "data":data}) : helper)))
+ "</a>\n </div>\n <p class=\"pkt_ext_edit_msg\"></p> \n</div>";
},"useData":true});
templates['signup_shell'] = template({"1":function(depth0,helpers,partials,data) {
}, "useData":true});
templates['signup_shell'] = template({"1":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return " <p class=\"pkt_ext_learnmorecontainer\"><a class=\"pkt_ext_learnmore\" href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "?s=ffi&t=learnmore&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\">"
+ escapeExpression(((helper = (helper = helpers.learnmore || (depth0 != null ? depth0.learnmore : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"learnmore","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.learnmore || (depth0 != null ? depth0.learnmore : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"learnmore", "hash":{}, "data":data}) : helper)))
+ "</a></p>\n";
},"3":function(depth0,helpers,partials,data) {
}, "3":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return " <p class=\"pkt_ext_learnmorecontainer\"><a class=\"pkt_ext_learnmore pkt_ext_learnmoreinactive\" href=\"#\">"
+ escapeExpression(((helper = (helper = helpers.learnmore || (depth0 != null ? depth0.learnmore : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"learnmore","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.learnmore || (depth0 != null ? depth0.learnmore : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"learnmore", "hash":{}, "data":data}) : helper)))
+ "</a></p>\n";
},"5":function(depth0,helpers,partials,data) {
}, "5":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return " <p class=\"btn-container\"><a href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "/ff_signup?s=ffi&t=signupff&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\" class=\"btn signup-btn-firefox\"><span class=\"logo\"></span><span class=\"text\">"
+ escapeExpression(((helper = (helper = helpers.signinfirefox || (depth0 != null ? depth0.signinfirefox : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signinfirefox","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.signinfirefox || (depth0 != null ? depth0.signinfirefox : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"signinfirefox", "hash":{}, "data":data}) : helper)))
+ "</span></a></p>\n";
},"7":function(depth0,helpers,partials,data) {
}, "7":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return " <p class=\"btn-container\"><a href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "/ff_signup?s=ffi&t=signupff&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\" class=\"btn signup-btn-firefox\"><span class=\"logo\"></span><span class=\"text\">"
+ escapeExpression(((helper = (helper = helpers.signupfirefox || (depth0 != null ? depth0.signupfirefox : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signupfirefox","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.signupfirefox || (depth0 != null ? depth0.signupfirefox : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"signupfirefox", "hash":{}, "data":data}) : helper)))
+ "</span></a></p>\n <p class=\"btn-container\"><a href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "/signup?force=email&src=extension&s=ffi&t=signupemail&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\" class=\"btn btn-secondary signup-btn-email signup-btn-initstate\">"
+ escapeExpression(((helper = (helper = helpers.signupemail || (depth0 != null ? depth0.signupemail : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signupemail","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.signupemail || (depth0 != null ? depth0.signupemail : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"signupemail", "hash":{}, "data":data}) : helper)))
+ "</a></p>\n";
},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
}, "compiler":[6, ">= 2.0.0-beta.1"], "main":function(depth0, helpers, partials, data) {
var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class=\"pkt_ext_introdetail pkt_ext_introdetailhero\">\n <h2 class=\"pkt_ext_logo\">Pocket</h2>\n <p class=\"pkt_ext_tagline\">"
+ escapeExpression(((helper = (helper = helpers.tagline || (depth0 != null ? depth0.tagline : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"tagline","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.tagline || (depth0 != null ? depth0.tagline : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"tagline", "hash":{}, "data":data}) : helper)))
+ "</p>\n";
stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showlearnmore : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});
stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showlearnmore : depth0), {"name":"if", "hash":{}, "fn":this.program(1, data), "inverse":this.program(3, data), "data":data});
if (stack1 != null) { buffer += stack1; }
buffer += " <div class=\"pkt_ext_introimg\"></div>\n</div>\n<div class=\"pkt_ext_signupdetail pkt_ext_signupdetail_hero\">\n <h4>"
+ escapeExpression(((helper = (helper = helpers.signuptosave || (depth0 != null ? depth0.signuptosave : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signuptosave","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.signuptosave || (depth0 != null ? depth0.signuptosave : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"signuptosave", "hash":{}, "data":data}) : helper)))
+ "</h4>\n";
stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.fxasignedin : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data});
stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.fxasignedin : depth0), {"name":"if", "hash":{}, "fn":this.program(5, data), "inverse":this.program(7, data), "data":data});
if (stack1 != null) { buffer += stack1; }
return buffer + " <p class=\"alreadyhave\">"
+ escapeExpression(((helper = (helper = helpers.alreadyhaveacct || (depth0 != null ? depth0.alreadyhaveacct : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"alreadyhaveacct","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.alreadyhaveacct || (depth0 != null ? depth0.alreadyhaveacct : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"alreadyhaveacct", "hash":{}, "data":data}) : helper)))
+ " <a href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "/login?ep=3&src=extension&s=ffi&t=login&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\">"
+ escapeExpression(((helper = (helper = helpers.loginnow || (depth0 != null ? depth0.loginnow : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"loginnow","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.loginnow || (depth0 != null ? depth0.loginnow : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"loginnow", "hash":{}, "data":data}) : helper)))
+ "</a>.</p>\n</div>";
},"useData":true});
templates['signupstoryboard_shell'] = template({"1":function(depth0,helpers,partials,data) {
}, "useData":true});
templates['signupstoryboard_shell'] = template({"1":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return " <p><a class=\"pkt_ext_learnmore\" href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "?s=ffi&t=learnmore&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\">"
+ escapeExpression(((helper = (helper = helpers.learnmore || (depth0 != null ? depth0.learnmore : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"learnmore","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.learnmore || (depth0 != null ? depth0.learnmore : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"learnmore", "hash":{}, "data":data}) : helper)))
+ "</a></p>\n";
},"3":function(depth0,helpers,partials,data) {
}, "3":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return " <p><a class=\"pkt_ext_learnmore pkt_ext_learnmoreinactive\" href=\"#\">"
+ escapeExpression(((helper = (helper = helpers.learnmore || (depth0 != null ? depth0.learnmore : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"learnmore","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.learnmore || (depth0 != null ? depth0.learnmore : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"learnmore", "hash":{}, "data":data}) : helper)))
+ "</a></p>\n";
},"5":function(depth0,helpers,partials,data) {
}, "5":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return " <p class=\"btn-container\"><a href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "/ff_signup?s=ffi&t=signupff&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\" class=\"btn signup-btn-firefox\"><span class=\"logo\"></span><span class=\"text\">"
+ escapeExpression(((helper = (helper = helpers.signinfirefox || (depth0 != null ? depth0.signinfirefox : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signinfirefox","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.signinfirefox || (depth0 != null ? depth0.signinfirefox : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"signinfirefox", "hash":{}, "data":data}) : helper)))
+ "</span></a></p>\n";
},"7":function(depth0,helpers,partials,data) {
}, "7":function(depth0, helpers, partials, data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return " <p class=\"btn-container\"><a href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "/ff_signup?s=ffi&t=signupff&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\" class=\"btn signup-btn-firefox\"><span class=\"logo\"></span><span class=\"text\">"
+ escapeExpression(((helper = (helper = helpers.signupfirefox || (depth0 != null ? depth0.signupfirefox : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signupfirefox","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.signupfirefox || (depth0 != null ? depth0.signupfirefox : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"signupfirefox", "hash":{}, "data":data}) : helper)))
+ "</span></a></p>\n <p class=\"btn-container\"><a href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "/signup?force=email&src=extension&s=ffi&t=signupemail&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\" class=\"btn btn-secondary signup-btn-email signup-btn-initstate\">"
+ escapeExpression(((helper = (helper = helpers.signupemail || (depth0 != null ? depth0.signupemail : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signupemail","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.signupemail || (depth0 != null ? depth0.signupemail : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"signupemail", "hash":{}, "data":data}) : helper)))
+ "</a></p>\n";
},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
}, "compiler":[6, ">= 2.0.0-beta.1"], "main":function(depth0, helpers, partials, data) {
var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class=\"pkt_ext_introdetail pkt_ext_introdetailstoryboard\">\n <div class=\"pkt_ext_introstory pkt_ext_introstoryone\">\n <div class=\"pkt_ext_introstory_text\">\n <p class=\"pkt_ext_tagline\">"
+ escapeExpression(((helper = (helper = helpers.taglinestory_one || (depth0 != null ? depth0.taglinestory_one : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"taglinestory_one","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.taglinestory_one || (depth0 != null ? depth0.taglinestory_one : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"taglinestory_one", "hash":{}, "data":data}) : helper)))
+ "</p>\n </div>\n <div class=\"pkt_ext_introstoryone_img\"></div>\n </div>\n <div class=\"pkt_ext_introstorydivider\"></div>\n <div class=\"pkt_ext_introstory pkt_ext_introstorytwo\">\n <div class=\"pkt_ext_introstory_text\">\n <p class=\"pkt_ext_tagline\">"
+ escapeExpression(((helper = (helper = helpers.taglinestory_two || (depth0 != null ? depth0.taglinestory_two : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"taglinestory_two","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.taglinestory_two || (depth0 != null ? depth0.taglinestory_two : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"taglinestory_two", "hash":{}, "data":data}) : helper)))
+ "</p>\n";
stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showlearnmore : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});
stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showlearnmore : depth0), {"name":"if", "hash":{}, "fn":this.program(1, data), "inverse":this.program(3, data), "data":data});
if (stack1 != null) { buffer += stack1; }
buffer += " </div>\n <div class=\"pkt_ext_introstorytwo_img\"></div>\n </div>\n</div>\n<div class=\"pkt_ext_signupdetail\">\n <h4>"
+ escapeExpression(((helper = (helper = helpers.signuptosave || (depth0 != null ? depth0.signuptosave : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signuptosave","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.signuptosave || (depth0 != null ? depth0.signuptosave : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"signuptosave", "hash":{}, "data":data}) : helper)))
+ "</h4>\n";
stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.fxasignedin : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data});
stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.fxasignedin : depth0), {"name":"if", "hash":{}, "fn":this.program(5, data), "inverse":this.program(7, data), "data":data});
if (stack1 != null) { buffer += stack1; }
return buffer + " <p class=\"alreadyhave\">"
+ escapeExpression(((helper = (helper = helpers.alreadyhaveacct || (depth0 != null ? depth0.alreadyhaveacct : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"alreadyhaveacct","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.alreadyhaveacct || (depth0 != null ? depth0.alreadyhaveacct : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"alreadyhaveacct", "hash":{}, "data":data}) : helper)))
+ " <a href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"pockethost", "hash":{}, "data":data}) : helper)))
+ "/login?ep=3&src=extension&s=ffi&t=login&v="
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"variant","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.variant || (depth0 != null ? depth0.variant : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"variant", "hash":{}, "data":data}) : helper)))
+ "\" target=\"_blank\">"
+ escapeExpression(((helper = (helper = helpers.loginnow || (depth0 != null ? depth0.loginnow : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"loginnow","hash":{},"data":data}) : helper)))
+ escapeExpression(((helper = (helper = helpers.loginnow || (depth0 != null ? depth0.loginnow : depth0)) != null ? helper : helperMissing), (typeof helper === functionType ? helper.call(depth0, {"name":"loginnow", "hash":{}, "data":data}) : helper)))
+ "</a>.</p>\n</div>";
},"useData":true});
}, "useData":true});
})();

View File

@ -295,7 +295,7 @@ var pktApi = (function() {
// Set headers
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.setRequestHeader('X-Accept',' application/json');
request.setRequestHeader('X-Accept', ' application/json');
// Serialize and Fire off the request
var str = [];

View File

@ -280,7 +280,7 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY fileMenu.label "File">
<!ENTITY fileMenu.accesskey "F">
<!ENTITY newUserContext.label "New Container Tab">
<!ENTITY newUserContext.accesskey "C">
<!ENTITY newUserContext.accesskey "B">
<!ENTITY newNavigatorCmd.label "New Window">
<!ENTITY newNavigatorCmd.key "N">
<!ENTITY newNavigatorCmd.accesskey "N">

View File

@ -1206,7 +1206,7 @@ var DirectoryLinksProvider = {
*/
_removeTileClick: function DirectoryLinksProvider_removeTileClick(url = "") {
// remove trailing slash, to accomodate Places sending site urls ending with '/'
let noTrailingSlashUrl = url.replace(/\/$/,"");
let noTrailingSlashUrl = url.replace(/\/$/, "");
let capObject = this._frequencyCaps[url] || this._frequencyCaps[noTrailingSlashUrl];
// return resolved promise if capObject is not found
if (!capObject) {

View File

@ -13,7 +13,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils","resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode", "resource://gre/modules/ReaderMode.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UITour", "resource:///modules/UITour.jsm");

View File

@ -42,7 +42,7 @@ function test() {
for (let preview of AeroPeek.previews)
ok(preview.visible, "Preview is shown as expected after re-enabling");
[1,2,3,4].forEach(function (idx) {
[1, 2, 3, 4].forEach(function (idx) {
gBrowser.selectedTab = gBrowser.tabs[idx];
ok(checkSelectedTab(), "Current tab is correctly selected");
});

View File

@ -52,7 +52,7 @@ add_task(function* asyncCleanup() {
is(ZoomManager.zoom, 1, "Zoom level was restored");
if (document.getElementById("zoom-controls")) {
CustomizableUI.removeWidgetFromArea("zoom-controls", CustomizableUI.AREA_NAVBAR);
ok(!document.getElementById("zoom-controls"),"Customizable zoom widget removed from toolbar");
ok(!document.getElementById("zoom-controls"), "Customizable zoom widget removed from toolbar");
}
});

View File

@ -30,7 +30,7 @@ do_get_profile();
const DIRECTORY_LINKS_FILE = "directoryLinks.json";
const DIRECTORY_FRECENCY = 1000;
const SUGGESTED_FRECENCY = Infinity;
const kURLData = {"directory": [{"url":"http://example.com","title":"LocalSource"}]};
const kURLData = {"directory": [{"url":"http://example.com", "title":"LocalSource"}]};
const kTestURL = 'data:application/json,' + JSON.stringify(kURLData);
// DirectoryLinksProvider preferences
@ -57,7 +57,7 @@ Services.prefs.setCharPref(kPingUrlPref, kPingUrl);
Services.prefs.setBoolPref(kNewtabEnhancedPref, true);
const kHttpHandlerData = {};
kHttpHandlerData[kExamplePath] = {"directory": [{"url":"http://example.com","title":"RemoteSource"}]};
kHttpHandlerData[kExamplePath] = {"directory": [{"url":"http://example.com", "title":"RemoteSource"}]};
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream",
@ -1438,7 +1438,7 @@ add_task(function* test_DirectoryLinksProvider_getFrequencyCapLogic() {
// now step into the furture
let _wasTodayOrig = DirectoryLinksProvider._wasToday;
DirectoryLinksProvider._wasToday = function () {return false;}
DirectoryLinksProvider._wasToday = function () { return false; }
// exhaust total views
DirectoryLinksProvider._addFrequencyCapView("1")
do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("1"));
@ -1487,7 +1487,7 @@ add_task(function* test_DirectoryLinksProvider_getFrequencyCapReportSiteAction()
targetedSite: "foo.com",
url: "bar.com"
},
isPinned: function() {return false;},
isPinned: function() { return false; },
}], "view", 0);
// read file content and ensure that view counters are updated
@ -1531,9 +1531,9 @@ add_task(function* test_DirectoryLinksProvider_ClickRemoval() {
}]
},
{
handleError: function () {do_check_true(false);},
handleError: function () { do_check_true(false); },
handleResult: function () {},
handleCompletion: function () {resolve();}
handleCompletion: function () { resolve(); }
}
);
});
@ -1828,8 +1828,8 @@ add_task(function* test_blockSuggestedTiles() {
// block suggested tile in a regular way
DirectoryLinksProvider.reportSitesAction([{
isPinned: function() {return false;},
link: Object.assign({frecency: 1000},suggestedLink)
isPinned: function() { return false; },
link: Object.assign({frecency: 1000}, suggestedLink)
}], "block", 0);
// suggested tile still must be recommended

View File

@ -8,8 +8,8 @@ Components.utils.import("resource://gre/modules/Services.jsm");
add_task(function* testPermissionsListing() {
Assert.deepEqual(SitePermissions.listPermissions().sort(),
["camera","cookie","desktop-notification","geo","image",
"indexedDB","install","microphone","popup", "screen"],
["camera", "cookie", "desktop-notification", "geo", "image",
"indexedDB", "install", "microphone", "popup", "screen"],
"Correct list of all permissions");
});

View File

@ -1071,11 +1071,6 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-ic
#panic-button@toolbarButtonPressed@ {
-moz-image-region: rect(36px, 1404px, 72px, 1368px);
}
#add-share-provider {
list-style-image: url(chrome://browser/skin/menuPanel-small@2x.png);
-moz-image-region: rect(0px, 192px, 32px, 160px);
}
}
toolbar .toolbarbutton-1:not([type="menu-button"]),

View File

@ -314,6 +314,11 @@
-moz-image-region: rect(0, 1664px, 64px, 1600px);
}
#add-share-provider {
list-style-image: url(chrome://browser/skin/menuPanel-small@2x.png);
-moz-image-region: rect(0px, 192px, 32px, 160px);
}
/* Footer and wide panel control icons */
#edit-controls@inAnyPanel@ > toolbarbutton,
#zoom-controls@inAnyPanel@ > toolbarbutton,

View File

@ -20,7 +20,7 @@ this.Buttons = {
configurations: {
navBarButtons: {
applyConfig: Task.async(() =>{
applyConfig: Task.async(() => {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
CustomizableUI.addWidgetToArea("screenshot-widget", CustomizableUI.AREA_NAVBAR);
}),

View File

@ -12,6 +12,7 @@
const {AnimationsTimeline} = require("devtools/client/animationinspector/components/animation-timeline");
const {RateSelector} = require("devtools/client/animationinspector/components/rate-selector");
const {formatStopwatchTime} = require("devtools/client/animationinspector/utils");
const {KeyCodes} = require("devtools/client/shared/keycodes");
var $ = (selector, target = document) => target.querySelector(selector);
@ -162,12 +163,10 @@ var AnimationsPanel = {
},
onKeyDown: function (event) {
let keyEvent = Ci.nsIDOMKeyEvent;
// If the space key is pressed, it should toggle the play state of
// the animations displayed in the panel, or of all the animations on
// the page if the selected node does not have any animation on it.
if (event.keyCode === keyEvent.DOM_VK_SPACE) {
if (event.keyCode === KeyCodes.DOM_VK_SPACE) {
if (AnimationsController.animationPlayers.length > 0) {
this.playPauseTimeline().catch(ex => console.error(ex));
} else {

View File

@ -28,6 +28,7 @@ const {
const { Task } = require("devtools/shared/task");
const { SideMenuWidget } = require("resource://devtools/client/shared/widgets/SideMenuWidget.jsm");
const { gDevTools } = require("devtools/client/framework/devtools");
const {KeyCodes} = require("devtools/client/shared/keycodes");
const NEW_SOURCE_DISPLAY_DELAY = 200; // ms
const FUNCTION_SEARCH_POPUP_POSITION = "topcenter bottomleft";
@ -1206,7 +1207,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
* The keypress listener for the breakpoints conditional expression textbox.
*/
_onConditionalTextboxKeyPress: function (e) {
if (e.keyCode == e.DOM_VK_RETURN) {
if (e.keyCode == KeyCodes.DOM_VK_RETURN) {
this._hideConditionalPopup();
}
},

View File

@ -442,12 +442,6 @@ function waitForClientEvents(aPanel, aEventName, aEventRepeat = 1) {
return deferred.promise;
}
function waitForClipboardPromise(setup, expected) {
return new Promise((resolve, reject) => {
SimpleTest.waitForClipboard(expected, setup, resolve, reject);
});
}
function ensureThreadClientState(aPanel, aState) {
let thread = aPanel.panelWin.gThreadClient;
let state = thread.state;

View File

@ -9,7 +9,6 @@
/* globals document, window */
"use strict";
/**
* Functions handling the filtering UI.
*/
@ -321,15 +320,15 @@ FilterView.prototype = {
// Return, enter, down and up keys focus next or previous matches, while
// the escape key switches focus from the search container.
else switch (e.keyCode) {
case e.DOM_VK_RETURN:
case KeyCodes.DOM_VK_RETURN:
var isReturnKey = true;
// If the shift key is pressed, focus on the previous result
actionToPerform = e.shiftKey ? "selectPrev" : "selectNext";
break;
case e.DOM_VK_DOWN:
case KeyCodes.DOM_VK_DOWN:
actionToPerform = "selectNext";
break;
case e.DOM_VK_UP:
case KeyCodes.DOM_VK_UP:
actionToPerform = "selectPrev";
break;
}

View File

@ -9,6 +9,8 @@
/* globals document */
"use strict";
const {KeyCodes} = require("devtools/client/shared/keycodes");
/**
* Functions handling the watch expressions UI.
*/
@ -289,8 +291,8 @@ WatchExpressionsView.prototype = Heritage.extend(WidgetMethods, {
*/
_onKeyPress: function (e) {
switch (e.keyCode) {
case e.DOM_VK_RETURN:
case e.DOM_VK_ESCAPE:
case KeyCodes.DOM_VK_RETURN:
case KeyCodes.DOM_VK_ESCAPE:
e.stopPropagation();
this.DebuggerView.editor.focus();
}

View File

@ -459,6 +459,15 @@ function waitForContextMenu(popup, button, onShown, onHidden) {
return deferred.promise;
}
/**
* Promise wrapper around SimpleTest.waitForClipboard
*/
function waitForClipboardPromise(setup, expected) {
return new Promise((resolve, reject) => {
SimpleTest.waitForClipboard(expected, setup, resolve, reject);
});
}
/**
* Simple helper to push a temporary preference. Wrapper on SpecialPowers
* pushPrefEnv that returns a promise resolving when the preferences have been

View File

@ -27,6 +27,7 @@ var { attachThread, detachThread } = require("./attach-thread");
var Menu = require("devtools/client/framework/menu");
var MenuItem = require("devtools/client/framework/menu-item");
var { DOMHelpers } = require("resource://devtools/client/shared/DOMHelpers.jsm");
const { KeyCodes } = require("devtools/client/shared/keycodes");
const { BrowserLoader } =
Cu.import("resource://devtools/client/shared/browser-loader.js", {});
@ -549,7 +550,7 @@ Toolbox.prototype = {
},
_splitConsoleOnKeypress: function (e) {
if (e.keyCode === e.DOM_VK_ESCAPE) {
if (e.keyCode === KeyCodes.DOM_VK_ESCAPE) {
this.toggleSplitConsole();
// If the debugger is paused, don't let the ESC key stop any pending
// navigation.

View File

@ -6,6 +6,7 @@
const promise = require("promise");
const {Task} = require("devtools/shared/task");
const {KeyCodes} = require("devtools/client/shared/keycodes");
const system = require("devtools/shared/system");
const EventEmitter = require("devtools/shared/event-emitter");
@ -119,13 +120,13 @@ InspectorSearch.prototype = {
this.searchClearButton.hidden = false;
this.searchBox.setAttribute("filled", true);
}
if (event.keyCode === event.DOM_VK_RETURN) {
if (event.keyCode === KeyCodes.DOM_VK_RETURN) {
this._onSearch(event.shiftKey);
}
const modifierKey = system.constants.platform === "macosx"
? event.metaKey : event.ctrlKey;
if (event.keyCode === event.DOM_VK_G && modifierKey) {
if (event.keyCode === KeyCodes.DOM_VK_G && modifierKey) {
this._onSearch(event.shiftKey);
event.preventDefault();
}
@ -330,8 +331,8 @@ SelectorAutocompleter.prototype = {
let popup = this.searchPopup;
switch (event.keyCode) {
case event.DOM_VK_RETURN:
case event.DOM_VK_TAB:
case KeyCodes.DOM_VK_RETURN:
case KeyCodes.DOM_VK_TAB:
if (popup.isOpen) {
if (popup.selectedItem) {
this.searchBox.value = popup.selectedItem.label;
@ -346,7 +347,7 @@ SelectorAutocompleter.prototype = {
}
break;
case event.DOM_VK_UP:
case KeyCodes.DOM_VK_UP:
if (popup.isOpen && popup.itemCount > 0) {
if (popup.selectedIndex === 0) {
popup.selectedIndex = popup.itemCount - 1;
@ -357,7 +358,7 @@ SelectorAutocompleter.prototype = {
}
break;
case event.DOM_VK_DOWN:
case KeyCodes.DOM_VK_DOWN:
if (popup.isOpen && popup.itemCount > 0) {
if (popup.selectedIndex === popup.itemCount - 1) {
popup.selectedIndex = 0;
@ -368,7 +369,7 @@ SelectorAutocompleter.prototype = {
}
break;
case event.DOM_VK_ESCAPE:
case KeyCodes.DOM_VK_ESCAPE:
if (popup.isOpen) {
this.hidePopup();
}

View File

@ -1,30 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* 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/. */
/* Set the minimum width for the side bar so, all tabs are
properly visible. The value can be decreased when bug 1281789
is fixed and the all-tabs-menu is available again. */
#inspector-sidebar-container {
overflow: hidden;
min-width: 450px;
position: relative;
}
#inspector-sidebar {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
/* Override `-moz-user-focus:ignore;` from toolkit/content/minimal-xul.css */
.inspector-tabpanel > * {
-moz-user-focus: normal;
}
#inspector-sidebar-toggle-box {
line-height: initial;
}

View File

@ -4,7 +4,6 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/inspector/inspector.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/inspector.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/rules.css" type="text/css"?>

View File

@ -60,6 +60,7 @@ const nodeFilterConstants = require("devtools/shared/dom-node-filter-constants")
const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
/* eslint-enable mozilla/reject-some-requires */
const {getCssProperties} = require("devtools/shared/fronts/css-properties");
const {KeyCodes} = require("devtools/client/shared/keycodes");
const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
@ -2273,12 +2274,12 @@ MarkupContainer.prototype = {
// Ignore all keystrokes that originated in editors except for when 'Tab' is
// pressed.
if (isInput && keyCode !== event.DOM_VK_TAB) {
if (isInput && keyCode !== KeyCodes.DOM_VK_TAB) {
return;
}
switch (keyCode) {
case event.DOM_VK_TAB:
case KeyCodes.DOM_VK_TAB:
// Only handle 'Tab' if tabbable element is on the edge (first or last).
if (isInput) {
// Corresponding tabbable element is editor's next sibling.
@ -2299,7 +2300,7 @@ MarkupContainer.prototype = {
}
}
break;
case event.DOM_VK_ESCAPE:
case KeyCodes.DOM_VK_ESCAPE:
this.clearFocus();
this.markup.getContainer(this.markup._rootNode).elt.focus();
if (this.isDragging) {

View File

@ -6,12 +6,10 @@
"use strict";
/* eslint-disable mozilla/reject-some-requires */
const {Ci} = require("chrome");
/* eslint-enable mozilla/reject-some-requires */
const {parseDeclarations} = require("devtools/shared/css-parsing-utils");
const promise = require("promise");
const {getCSSLexer} = require("devtools/shared/css-lexer");
const {KeyCodes} = require("devtools/client/shared/keycodes");
const HTML_NS = "http://www.w3.org/1999/xhtml";
@ -75,7 +73,7 @@ exports.appendText = appendText;
*/
function advanceValidate(keyCode, value, insertionPoint) {
// Only ";" has special handling here.
if (keyCode !== Ci.nsIDOMKeyEvent.DOM_VK_SEMICOLON) {
if (keyCode !== KeyCodes.DOM_VK_SEMICOLON) {
return false;
}

View File

@ -143,7 +143,6 @@ devtools.jar:
* content/framework/dev-edition-promo/dev-edition-promo.css (framework/dev-edition-promo/dev-edition-promo.css)
content/framework/dev-edition-promo/dev-edition-logo.png (framework/dev-edition-promo/dev-edition-logo.png)
content/inspector/inspector.xul (inspector/inspector.xul)
content/inspector/inspector.css (inspector/inspector.css)
content/framework/connect/connect.xhtml (framework/connect/connect.xhtml)
content/framework/connect/connect.css (framework/connect/connect.css)
content/framework/connect/connect.js (framework/connect/connect.js)

View File

@ -136,12 +136,6 @@ function waitForTime(delay) {
return deferred.promise;
}
function waitForClipboardPromise(setup, expected) {
return new Promise((resolve, reject) => {
SimpleTest.waitForClipboard(expected, setup, resolve, reject);
});
}
function waitForFilter() {
return executeInContent("Test:JsonView:WaitForFilter");
}

View File

@ -6,8 +6,6 @@
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
/* import-globals-from ../../test/head.js */
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
// Load the NetMonitor head.js file to share its API.
var netMonitorHead = "chrome://mochitests/content/browser/devtools/client/netmonitor/test/head.js";
Services.scriptloader.loadSubScript(netMonitorHead, this);

View File

@ -41,6 +41,7 @@ support-files =
test-image.png
service-workers/status-codes.html
service-workers/status-codes-service-worker.js
!/devtools/client/framework/test/shared-head.js
[browser_net_aaa_leaktest.js]
[browser_net_accessibility-01.js]
@ -77,7 +78,6 @@ subsuite = clipboard
subsuite = clipboard
[browser_net_copy_as_curl.js]
subsuite = clipboard
skip-if = e10s # Bug 1091596
[browser_net_cors_requests.js]
[browser_net_cyrillic-01.js]
[browser_net_cyrillic-02.js]

View File

@ -1,106 +1,88 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if Copy as cURL works.
*/
function test() {
initNetMonitor(CURL_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
add_task(function* () {
let [tab, , monitor] = yield initNetMonitor(CURL_URL);
info("Starting test... ");
const EXPECTED_POSIX_RESULT = [
"curl",
"'" + SIMPLE_SJS + "'",
"-H 'Host: example.com'",
"-H 'User-Agent: " + navigator.userAgent + "'",
"-H 'Accept: */*'",
"-H 'Accept-Language: " + navigator.language + "'",
"--compressed",
"-H 'X-Custom-Header-1: Custom value'",
"-H 'X-Custom-Header-2: 8.8.8.8'",
"-H 'X-Custom-Header-3: Mon, 3 Mar 2014 11:11:11 GMT'",
"-H 'Referer: " + CURL_URL + "'",
"-H 'Connection: keep-alive'",
"-H 'Pragma: no-cache'",
"-H 'Cache-Control: no-cache'"
].join(" ");
// Different quote chars are used for Windows and POSIX
const QUOTE = Services.appinfo.OS == "WINNT" ? "\"" : "'";
const EXPECTED_WIN_RESULT = [
"curl",
'"' + SIMPLE_SJS + '"',
'-H "Host: example.com"',
'-H "User-Agent: ' + navigator.userAgent + '"',
'-H "Accept: */*"',
'-H "Accept-Language: ' + navigator.language + '"',
"--compressed",
'-H "X-Custom-Header-1: Custom value"',
'-H "X-Custom-Header-2: 8.8.8.8"',
'-H "X-Custom-Header-3: Mon, 3 Mar 2014 11:11:11 GMT"',
'-H "Referer: ' + CURL_URL + '"',
'-H "Connection: keep-alive"',
'-H "Pragma: no-cache"',
'-H "Cache-Control: no-cache"'
].join(" ");
// Quote a string, escape the quotes inside the string
function quote(str) {
return QUOTE + str.replace(new RegExp(QUOTE, "g"), `\\${QUOTE}`) + QUOTE;
}
const EXPECTED_RESULT = Services.appinfo.OS == "WINNT"
? EXPECTED_WIN_RESULT
: EXPECTED_POSIX_RESULT;
// Header param is formatted as -H "Header: value" or -H 'Header: value'
function header(h) {
return "-H " + quote(h);
}
let { NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
// Construct the expected command
const EXPECTED_RESULT = [
"curl " + quote(SIMPLE_SJS),
"--compressed",
header("Host: example.com"),
header("User-Agent: " + navigator.userAgent),
header("Accept: */*"),
header("Accept-Language: " + navigator.language),
header("X-Custom-Header-1: Custom value"),
header("X-Custom-Header-2: 8.8.8.8"),
header("X-Custom-Header-3: Mon, 3 Mar 2014 11:11:11 GMT"),
header("Referer: " + CURL_URL),
header("Connection: keep-alive"),
header("Pragma: no-cache"),
header("Cache-Control: no-cache")
];
RequestsMenu.lazyUpdate = false;
let { NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
waitForNetworkEvents(aMonitor, 1).then(() => {
let requestItem = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = requestItem;
waitForClipboard(function validate(aResult) {
if (typeof aResult !== "string") {
return false;
}
// Different setups may produce the same command, but with the
// parameters in a different order in the commandline (which is fine).
// Here we confirm that the commands are the same even in that case.
var expected = EXPECTED_RESULT.toString().match(/[-A-Za-z1-9]+ ([\"'])(?:\\\1|.)*?\1/g),
actual = aResult.match(/[-A-Za-z1-9]+ ([\"'])(?:\\\1|.)*?\1/g);
// Must begin with the same "curl 'URL'" segment
if (!actual || expected[0] != actual[0]) {
return false;
}
// Must match each of the params in the middle (headers)
var expectedSet = new Set(expected);
var actualSet = new Set(actual);
if (expected.size != actual.size) {
return false;
}
for (let param of expectedSet) {
if (!actualSet.has(param)) {
return false;
}
}
return true;
}, function setup() {
RequestsMenu.copyAsCurl();
}, function onSuccess() {
ok(true, "Clipboard contains a cURL command for the currently selected item's url.");
cleanUp();
}, function onFailure() {
ok(false, "Creating a cURL command for the currently selected item was unsuccessful.");
cleanUp();
});
});
aDebuggee.performRequest(SIMPLE_SJS);
function cleanUp() {
teardown(aMonitor).then(finish);
}
let wait = waitForNetworkEvents(monitor, 1);
yield ContentTask.spawn(tab.linkedBrowser, SIMPLE_SJS, function* (url) {
content.wrappedJSObject.performRequest(url);
});
}
yield wait;
let requestItem = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = requestItem;
yield waitForClipboardPromise(function setup() {
RequestsMenu.copyAsCurl();
}, function validate(result) {
if (typeof result !== "string") {
return false;
}
// Different setups may produce the same command, but with the
// parameters in a different order in the commandline (which is fine).
// Here we confirm that the commands are the same even in that case.
// This monster regexp parses the command line into an array of arguments,
// recognizing quoted args with matching quotes and escaped quotes inside:
// [ "curl 'url'", "--standalone-arg", "-arg-with-quoted-string 'value\'s'" ]
let matchRe = /[-A-Za-z1-9]+(?: ([\"'])(?:\\\1|.)*?\1)?/g;
let actual = result.match(matchRe);
// Must begin with the same "curl 'URL'" segment
if (!actual || EXPECTED_RESULT[0] != actual[0]) {
return false;
}
// Must match each of the params in the middle (headers and --compressed)
return EXPECTED_RESULT.length === actual.length &&
EXPECTED_RESULT.every(param => actual.includes(param));
});
info("Clipboard contains a cURL command for the currently selected item's url.");
yield teardown(monitor);
});

View File

@ -1,79 +1,76 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if toggling the details pane works as expected.
*/
function test() {
initNetMonitor(SIMPLE_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
add_task(function* () {
let [tab, , monitor] = yield initNetMonitor(SIMPLE_URL);
info("Starting test... ");
let { document, NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
let { $, NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
let { NETWORK_EVENT, TAB_UPDATED } = monitor.panelWin.EVENTS;
RequestsMenu.lazyUpdate = false;
RequestsMenu.lazyUpdate = false;
let toggleButton = $("#details-pane-toggle");
is(document.querySelector("#details-pane-toggle")
.hasAttribute("disabled"), true,
"The pane toggle button should be disabled when the frontend is opened.");
is(document.querySelector("#details-pane-toggle")
.classList.contains("pane-collapsed"), true,
"The pane toggle button should indicate that the details pane is " +
"collapsed when the frontend is opened.");
is(NetMonitorView.detailsPaneHidden, true,
"The details pane should be hidden when the frontend is opened.");
is(RequestsMenu.selectedItem, null,
"There should be no selected item in the requests menu.");
is(toggleButton.hasAttribute("disabled"), true,
"The pane toggle button should be disabled when the frontend is opened.");
is(toggleButton.classList.contains("pane-collapsed"), true,
"The pane toggle button should indicate that the details pane is " +
"collapsed when the frontend is opened.");
is(NetMonitorView.detailsPaneHidden, true,
"The details pane should be hidden when the frontend is opened.");
is(RequestsMenu.selectedItem, null,
"There should be no selected item in the requests menu.");
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.NETWORK_EVENT, () => {
is(document.querySelector("#details-pane-toggle")
.hasAttribute("disabled"), false,
"The pane toggle button should be enabled after the first request.");
is(document.querySelector("#details-pane-toggle")
.classList.contains("pane-collapsed"), true,
"The pane toggle button should still indicate that the details pane is " +
"collapsed after the first request.");
is(NetMonitorView.detailsPaneHidden, true,
"The details pane should still be hidden after the first request.");
is(RequestsMenu.selectedItem, null,
"There should still be no selected item in the requests menu.");
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
is(document.querySelector("#details-pane-toggle")
.hasAttribute("disabled"), false,
"The pane toggle button should still be enabled after being pressed.");
is(document.querySelector("#details-pane-toggle")
.classList.contains("pane-collapsed"), false,
"The pane toggle button should now indicate that the details pane is " +
"not collapsed anymore after being pressed.");
is(NetMonitorView.detailsPaneHidden, false,
"The details pane should not be hidden after toggle button was pressed.");
isnot(RequestsMenu.selectedItem, null,
"There should be a selected item in the requests menu.");
is(RequestsMenu.selectedIndex, 0,
"The first item should be selected in the requests menu.");
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
is(document.querySelector("#details-pane-toggle")
.hasAttribute("disabled"), false,
"The pane toggle button should still be enabled after being pressed again.");
is(document.querySelector("#details-pane-toggle")
.classList.contains("pane-collapsed"), true,
"The pane toggle button should now indicate that the details pane is " +
"collapsed after being pressed again.");
is(NetMonitorView.detailsPaneHidden, true,
"The details pane should now be hidden after the toggle button was pressed again.");
is(RequestsMenu.selectedItem, null,
"There should now be no selected item in the requests menu.");
teardown(aMonitor).then(finish);
});
aDebuggee.location.reload();
let networkEvent = monitor.panelWin.once(NETWORK_EVENT);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.location.reload();
});
}
yield networkEvent;
is(toggleButton.hasAttribute("disabled"), false,
"The pane toggle button should be enabled after the first request.");
is(toggleButton.classList.contains("pane-collapsed"), true,
"The pane toggle button should still indicate that the details pane is " +
"collapsed after the first request.");
is(NetMonitorView.detailsPaneHidden, true,
"The details pane should still be hidden after the first request.");
is(RequestsMenu.selectedItem, null,
"There should still be no selected item in the requests menu.");
EventUtils.sendMouseEvent({ type: "mousedown" }, toggleButton);
yield monitor.panelWin.once(TAB_UPDATED);
is(toggleButton.hasAttribute("disabled"), false,
"The pane toggle button should still be enabled after being pressed.");
is(toggleButton.classList.contains("pane-collapsed"), false,
"The pane toggle button should now indicate that the details pane is " +
"not collapsed anymore after being pressed.");
is(NetMonitorView.detailsPaneHidden, false,
"The details pane should not be hidden after toggle button was pressed.");
isnot(RequestsMenu.selectedItem, null,
"There should be a selected item in the requests menu.");
is(RequestsMenu.selectedIndex, 0,
"The first item should be selected in the requests menu.");
EventUtils.sendMouseEvent({ type: "mousedown" }, toggleButton);
is(toggleButton.hasAttribute("disabled"), false,
"The pane toggle button should still be enabled after being pressed again.");
is(toggleButton.classList.contains("pane-collapsed"), true,
"The pane toggle button should now indicate that the details pane is " +
"collapsed after being pressed again.");
is(NetMonitorView.detailsPaneHidden, true,
"The details pane should now be hidden after the toggle button was pressed again.");
is(RequestsMenu.selectedItem, null,
"There should now be no selected item in the requests menu.");
yield teardown(monitor);
});

View File

@ -2,18 +2,15 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
/* import-globals-from ../../framework/test/shared-head.js */
// shared-head.js handles imports, constants, and utility functions
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
this);
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
var { gDevTools } = require("devtools/client/framework/devtools");
var { Task } = require("devtools/shared/task");
var { CurlUtils } = Cu.import("resource://devtools/client/shared/Curl.jsm", {});
var Services = require("Services");
var promise = require("promise");
var NetworkHelper = require("devtools/shared/webconsole/network-helper");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var flags = require("devtools/shared/flags");
var { TargetFactory } = require("devtools/client/framework/target");
var { Toolbox } = require("devtools/client/framework/toolbox");
const EXAMPLE_URL = "http://example.com/browser/devtools/client/netmonitor/test/";
@ -61,11 +58,6 @@ const TEST_IMAGE_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAA
const FRAME_SCRIPT_UTILS_URL = "chrome://devtools/content/shared/frame-script-utils.js";
flags.testing = true;
SimpleTest.registerCleanupFunction(() => {
flags.testing = false;
});
// All tests are asynchronous.
waitForExplicitFinish();
@ -85,38 +77,8 @@ registerCleanupFunction(() => {
Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
Services.prefs.setCharPref("devtools.netmonitor.filters", gDefaultFilters);
Services.prefs.clearUserPref("devtools.cache.disabled");
Services.prefs.clearUserPref("devtools.dump.emit");
});
function addTab(aUrl, aWindow) {
info("Adding tab: " + aUrl);
let deferred = promise.defer();
let targetWindow = aWindow || window;
let targetBrowser = targetWindow.gBrowser;
targetWindow.focus();
let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
let browser = tab.linkedBrowser;
browser.addEventListener("load", function onLoad() {
browser.removeEventListener("load", onLoad, true);
deferred.resolve(tab);
}, true);
return deferred.promise;
}
function removeTab(aTab, aWindow) {
info("Removing tab.");
let targetWindow = aWindow || window;
let targetBrowser = targetWindow.gBrowser;
// browser_net_pane-toggle.js relies on synchronous removeTab behavior.
targetBrowser.removeTab(aTab, {skipPermitUnload: true});
}
function waitForNavigation(aTarget) {
let deferred = promise.defer();
aTarget.once("will-navigate", () => {

View File

@ -5,6 +5,10 @@
"use strict";
const Cu = Components.utils;
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const {KeyCodes} = require("devtools/client/shared/keycodes");
this.EXPORTED_SYMBOLS = ["SplitView"];
/* this must be kept in sync with CSS (ie. splitview.css) */
@ -56,16 +60,16 @@ this.SplitView = function SplitView(aRoot)
// handle keyboard navigation within the items list
let newFocusOrdinal;
if (aEvent.keyCode == aEvent.DOM_VK_PAGE_UP ||
aEvent.keyCode == aEvent.DOM_VK_HOME) {
if (aEvent.keyCode == KeyCodes.DOM_VK_PAGE_UP ||
aEvent.keyCode == KeyCodes.DOM_VK_HOME) {
newFocusOrdinal = 0;
} else if (aEvent.keyCode == aEvent.DOM_VK_PAGE_DOWN ||
aEvent.keyCode == aEvent.DOM_VK_END) {
} else if (aEvent.keyCode == KeyCodes.DOM_VK_PAGE_DOWN ||
aEvent.keyCode == KeyCodes.DOM_VK_END) {
newFocusOrdinal = this._nav.childNodes.length - 1;
} else if (aEvent.keyCode == aEvent.DOM_VK_UP) {
} else if (aEvent.keyCode == KeyCodes.DOM_VK_UP) {
newFocusOrdinal = getFocusedItemWithin(this._nav).getAttribute("data-ordinal");
newFocusOrdinal--;
} else if (aEvent.keyCode == aEvent.DOM_VK_DOWN) {
} else if (aEvent.keyCode == KeyCodes.DOM_VK_DOWN) {
newFocusOrdinal = getFocusedItemWithin(this._nav).getAttribute("data-ordinal");
newFocusOrdinal++;
}

View File

@ -26,6 +26,7 @@
const {Ci, Cc} = require("chrome");
const Services = require("Services");
const focusManager = Services.focus;
const {KeyCodes} = require("devtools/client/shared/keycodes");
const HTML_NS = "http://www.w3.org/1999/xhtml";
const CONTENT_TYPES = {
@ -48,7 +49,7 @@ const { findMostRelevantCssPropertyIndex } = require("./suggestion-picker");
/**
* Helper to check if the provided key matches one of the expected keys.
* Keys will be prefixed with DOM_VK_ and should match a key in nsIDOMKeyEvent.
* Keys will be prefixed with DOM_VK_ and should match a key in KeyCodes.
*
* @param {String} key
* the key to check (can be a keyCode).
@ -58,7 +59,7 @@ const { findMostRelevantCssPropertyIndex } = require("./suggestion-picker");
*/
function isKeyIn(key, ...keys) {
return keys.some(expectedKey => {
return key === Ci.nsIDOMKeyEvent["DOM_VK_" + expectedKey];
return key === KeyCodes["DOM_VK_" + expectedKey];
});
}

View File

@ -7,6 +7,7 @@
const Services = require("Services");
const EventEmitter = require("devtools/shared/event-emitter");
const isOSX = Services.appinfo.OS === "Darwin";
const {KeyCodes} = require("devtools/client/shared/keycodes");
// List of electron keys mapped to DOM API (DOM_VK_*) key code
const ElectronKeysMapping = {
@ -139,7 +140,7 @@ KeyShortcuts.parseElectronKey = function (window, str) {
} else if (key in ElectronKeysMapping) {
// Maps the others manually to DOM API DOM_VK_*
key = ElectronKeysMapping[key];
shortcut.keyCode = window.KeyboardEvent[key];
shortcut.keyCode = KeyCodes[key];
// Used only to stringify the shortcut
shortcut.keyCodeString = key;
} else {

View File

@ -0,0 +1,146 @@
/* 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";
// This was copied (and slightly modified) from
// devtools/shared/gcli/source/lib/gcli/util/util.js, which in turn
// says:
/**
* Keyboard handling is a mess. http://unixpapa.com/js/key.html
* It would be good to use DOM L3 Keyboard events,
* http://www.w3.org/TR/2010/WD-DOM-Level-3-Events-20100907/#events-keyboardevents
* however only Webkit supports them, and there isn't a shim on Modernizr:
* https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills
* and when the code that uses this KeyEvent was written, nothing was clear,
* so instead, we're using this unmodern shim:
* http://stackoverflow.com/questions/5681146/chrome-10-keyevent-or-something-similar-to-firefoxs-keyevent
* See BUG 664991: GCLI's keyboard handling should be updated to use DOM-L3
* https://bugzilla.mozilla.org/show_bug.cgi?id=664991
*/
exports.KeyCodes = {
DOM_VK_CANCEL: 3,
DOM_VK_HELP: 6,
DOM_VK_BACK_SPACE: 8,
DOM_VK_TAB: 9,
DOM_VK_CLEAR: 12,
DOM_VK_RETURN: 13,
DOM_VK_SHIFT: 16,
DOM_VK_CONTROL: 17,
DOM_VK_ALT: 18,
DOM_VK_PAUSE: 19,
DOM_VK_CAPS_LOCK: 20,
DOM_VK_ESCAPE: 27,
DOM_VK_SPACE: 32,
DOM_VK_PAGE_UP: 33,
DOM_VK_PAGE_DOWN: 34,
DOM_VK_END: 35,
DOM_VK_HOME: 36,
DOM_VK_LEFT: 37,
DOM_VK_UP: 38,
DOM_VK_RIGHT: 39,
DOM_VK_DOWN: 40,
DOM_VK_PRINTSCREEN: 44,
DOM_VK_INSERT: 45,
DOM_VK_DELETE: 46,
DOM_VK_0: 48,
DOM_VK_1: 49,
DOM_VK_2: 50,
DOM_VK_3: 51,
DOM_VK_4: 52,
DOM_VK_5: 53,
DOM_VK_6: 54,
DOM_VK_7: 55,
DOM_VK_8: 56,
DOM_VK_9: 57,
DOM_VK_SEMICOLON: 59,
DOM_VK_EQUALS: 61,
DOM_VK_A: 65,
DOM_VK_B: 66,
DOM_VK_C: 67,
DOM_VK_D: 68,
DOM_VK_E: 69,
DOM_VK_F: 70,
DOM_VK_G: 71,
DOM_VK_H: 72,
DOM_VK_I: 73,
DOM_VK_J: 74,
DOM_VK_K: 75,
DOM_VK_L: 76,
DOM_VK_M: 77,
DOM_VK_N: 78,
DOM_VK_O: 79,
DOM_VK_P: 80,
DOM_VK_Q: 81,
DOM_VK_R: 82,
DOM_VK_S: 83,
DOM_VK_T: 84,
DOM_VK_U: 85,
DOM_VK_V: 86,
DOM_VK_W: 87,
DOM_VK_X: 88,
DOM_VK_Y: 89,
DOM_VK_Z: 90,
DOM_VK_CONTEXT_MENU: 93,
DOM_VK_NUMPAD0: 96,
DOM_VK_NUMPAD1: 97,
DOM_VK_NUMPAD2: 98,
DOM_VK_NUMPAD3: 99,
DOM_VK_NUMPAD4: 100,
DOM_VK_NUMPAD5: 101,
DOM_VK_NUMPAD6: 102,
DOM_VK_NUMPAD7: 103,
DOM_VK_NUMPAD8: 104,
DOM_VK_NUMPAD9: 105,
DOM_VK_MULTIPLY: 106,
DOM_VK_ADD: 107,
DOM_VK_SEPARATOR: 108,
DOM_VK_SUBTRACT: 109,
DOM_VK_DECIMAL: 110,
DOM_VK_DIVIDE: 111,
DOM_VK_F1: 112,
DOM_VK_F2: 113,
DOM_VK_F3: 114,
DOM_VK_F4: 115,
DOM_VK_F5: 116,
DOM_VK_F6: 117,
DOM_VK_F7: 118,
DOM_VK_F8: 119,
DOM_VK_F9: 120,
DOM_VK_F10: 121,
DOM_VK_F11: 122,
DOM_VK_F12: 123,
DOM_VK_F13: 124,
DOM_VK_F14: 125,
DOM_VK_F15: 126,
DOM_VK_F16: 127,
DOM_VK_F17: 128,
DOM_VK_F18: 129,
DOM_VK_F19: 130,
DOM_VK_F20: 131,
DOM_VK_F21: 132,
DOM_VK_F22: 133,
DOM_VK_F23: 134,
DOM_VK_F24: 135,
DOM_VK_NUM_LOCK: 144,
DOM_VK_SCROLL_LOCK: 145,
DOM_VK_COMMA: 188,
DOM_VK_PERIOD: 190,
DOM_VK_SLASH: 191,
DOM_VK_BACK_QUOTE: 192,
DOM_VK_OPEN_BRACKET: 219,
DOM_VK_BACK_SLASH: 220,
DOM_VK_CLOSE_BRACKET: 221,
DOM_VK_QUOTE: 222,
DOM_VK_META: 224,
// A few that did not appear in gcli, but that are apparently used
// in devtools.
DOM_VK_COLON: 58,
DOM_VK_VOLUME_MUTE: 181,
DOM_VK_VOLUME_DOWN: 182,
DOM_VK_VOLUME_UP: 183,
};

View File

@ -35,6 +35,7 @@ DevToolsModules(
'inplace-editor.js',
'Jsbeautify.jsm',
'key-shortcuts.js',
'keycodes.js',
'l10n.js',
'node-attribute-parser.js',
'options-view.js',

View File

@ -133,6 +133,7 @@ skip-if = e10s # Bug 1221911, bug 1222289, frequent e10s timeouts
[browser_inplace-editor_autocomplete_02.js]
[browser_inplace-editor_autocomplete_offset.js]
[browser_inplace-editor_maxwidth.js]
[browser_keycodes.js]
[browser_key_shortcuts.js]
[browser_layoutHelpers.js]
skip-if = e10s # Layouthelpers test should not run in a content page.

View File

@ -80,10 +80,18 @@ function* testGraph(host, graph) {
function pressKeyForTime(graph, keyCode, ms) {
let deferred = defer();
graph._onKeyDown({ keyCode });
graph._onKeyDown({
keyCode,
preventDefault: () => { },
stopPropagation: () => { },
});
setTimeout(() => {
graph._onKeyUp({ keyCode });
graph._onKeyUp({
keyCode,
preventDefault: () => { },
stopPropagation: () => { },
});
deferred.resolve();
}, ms);

View File

@ -0,0 +1,12 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {KeyCodes} = require("devtools/client/shared/keycodes");
add_task(function* () {
for (let key in KeyCodes) {
is(KeyCodes[key], Ci.nsIDOMKeyEvent[key], "checking value for " + key);
}
});

View File

@ -10,6 +10,7 @@ const { interfaces: Ci, utils: Cu } = Components;
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
const { ViewHelpers } = require("devtools/client/shared/widgets/view-helpers");
const { KeyCodes } = require("devtools/client/shared/keycodes");
XPCOMUtils.defineLazyModuleGetter(this, "EventEmitter",
"resource://devtools/shared/event-emitter.js");
@ -588,15 +589,15 @@ AbstractTreeItem.prototype = {
ViewHelpers.preventScrolling(e);
switch (e.keyCode) {
case e.DOM_VK_UP:
case KeyCodes.DOM_VK_UP:
this._focusPrevNode();
return;
case e.DOM_VK_DOWN:
case KeyCodes.DOM_VK_DOWN:
this._focusNextNode();
return;
case e.DOM_VK_LEFT:
case KeyCodes.DOM_VK_LEFT:
if (this._expanded && this._populated) {
this.collapse();
} else {
@ -604,7 +605,7 @@ AbstractTreeItem.prototype = {
}
return;
case e.DOM_VK_RIGHT:
case KeyCodes.DOM_VK_RIGHT:
if (!this._expanded) {
this.expand();
} else {
@ -612,7 +613,7 @@ AbstractTreeItem.prototype = {
}
return;
case e.DOM_VK_PAGE_UP:
case KeyCodes.DOM_VK_PAGE_UP:
let pageUpElement =
this._getSiblingAtDelta(-this._getNodesPerPageSize());
// There's a chance that the root node is hidden. In this case, its
@ -624,7 +625,7 @@ AbstractTreeItem.prototype = {
}
return;
case e.DOM_VK_PAGE_DOWN:
case KeyCodes.DOM_VK_PAGE_DOWN:
let pageDownElement =
this._getSiblingAtDelta(this._getNodesPerPageSize());
if (pageDownElement) {
@ -634,11 +635,11 @@ AbstractTreeItem.prototype = {
}
return;
case e.DOM_VK_HOME:
case KeyCodes.DOM_VK_HOME:
this._focusFirstNode();
return;
case e.DOM_VK_END:
case KeyCodes.DOM_VK_END:
this._focusLastNode();
return;
}

View File

@ -8,6 +8,7 @@ loader.lazyRequireGetter(this, "setNamedTimeout",
"devtools/client/shared/widgets/view-helpers", true);
loader.lazyRequireGetter(this, "clearNamedTimeout",
"devtools/client/shared/widgets/view-helpers", true);
const {KeyCodes} = require("devtools/client/shared/keycodes");
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const HTML_NS = "http://www.w3.org/1999/xhtml";
@ -469,7 +470,7 @@ TableWidget.prototype = {
let cell;
switch (event.keyCode) {
case event.DOM_VK_UP:
case KeyCodes.DOM_VK_UP:
event.preventDefault();
colName = selectedCell.parentNode.id;
@ -487,7 +488,7 @@ TableWidget.prototype = {
this.emit(EVENTS.ROW_SELECTED, cell.getAttribute("data-id"));
break;
case event.DOM_VK_DOWN:
case KeyCodes.DOM_VK_DOWN:
event.preventDefault();
colName = selectedCell.parentNode.id;
@ -1664,14 +1665,14 @@ EditableFieldsEngine.prototype = {
}
switch (event.keyCode) {
case event.DOM_VK_ESCAPE:
case KeyCodes.DOM_VK_ESCAPE:
this.cancelEdit();
event.preventDefault();
break;
case event.DOM_VK_RETURN:
case KeyCodes.DOM_VK_RETURN:
this.completeEdit();
break;
case event.DOM_VK_TAB:
case KeyCodes.DOM_VK_TAB:
if (this.onTab) {
this.onTab(event);
}

View File

@ -4,7 +4,6 @@
"use strict";
const {Ci} = require("chrome");
const defer = require("devtools/shared/defer");
const {Spectrum} = require("devtools/client/shared/widgets/Spectrum");
const {CubicBezierWidget} =
@ -18,6 +17,7 @@ const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip");
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
const {Task} = require("devtools/shared/task");
const {KeyCodes} = require("devtools/client/shared/keycodes");
loader.lazyRequireGetter(this, "beautify", "devtools/shared/jsbeautify/beautify");
loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true);
@ -30,7 +30,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "VariablesViewController",
"resource://devtools/client/shared/widgets/VariablesViewController.jsm");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
const ESCAPE_KEYCODE = Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE;
const ESCAPE_KEYCODE = KeyCodes.DOM_VK_ESCAPE;
const POPUP_EVENTS = ["shown", "hidden", "showing", "hiding"];
/**

View File

@ -8,6 +8,7 @@
const HTML_NS = "http://www.w3.org/1999/xhtml";
const EventEmitter = require("devtools/shared/event-emitter");
const {KeyCodes} = require("devtools/client/shared/keycodes");
/**
* A tree widget with keyboard navigation and collapsable structure.
@ -345,15 +346,15 @@ TreeWidget.prototype = {
*/
onKeypress: function (event) {
switch (event.keyCode) {
case event.DOM_VK_UP:
case KeyCodes.DOM_VK_UP:
this.selectPreviousItem();
break;
case event.DOM_VK_DOWN:
case KeyCodes.DOM_VK_DOWN:
this.selectNextItem();
break;
case event.DOM_VK_RIGHT:
case KeyCodes.DOM_VK_RIGHT:
if (this._selectedLabel.hasAttribute("expanded")) {
this.selectNextItem();
} else {
@ -361,7 +362,7 @@ TreeWidget.prototype = {
}
break;
case event.DOM_VK_LEFT:
case KeyCodes.DOM_VK_LEFT:
if (this._selectedLabel.hasAttribute("expanded") &&
!this._selectedLabel.hasAttribute("empty")) {
this._selectedLabel.removeAttribute("expanded");

View File

@ -28,6 +28,7 @@ const { Heritage, ViewHelpers, setNamedTimeout } =
require("devtools/client/shared/widgets/view-helpers");
const { Task } = require("devtools/shared/task");
const nodeConstants = require("devtools/shared/dom-node-constants");
const {KeyCodes} = require("devtools/client/shared/keycodes");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
@ -513,10 +514,10 @@ VariablesView.prototype = {
*/
_onSearchboxKeyPress: function (e) {
switch (e.keyCode) {
case e.DOM_VK_RETURN:
case KeyCodes.DOM_VK_RETURN:
this._onSearchboxInput();
return;
case e.DOM_VK_ESCAPE:
case KeyCodes.DOM_VK_ESCAPE:
this._searchboxNode.value = "";
this._onSearchboxInput();
return;
@ -826,17 +827,17 @@ VariablesView.prototype = {
ViewHelpers.preventScrolling(e);
switch (e.keyCode) {
case e.DOM_VK_UP:
case KeyCodes.DOM_VK_UP:
// Always rewind focus.
this.focusPrevItem(true);
return;
case e.DOM_VK_DOWN:
case KeyCodes.DOM_VK_DOWN:
// Always advance focus.
this.focusNextItem(true);
return;
case e.DOM_VK_LEFT:
case KeyCodes.DOM_VK_LEFT:
// Collapse scopes, variables and properties before rewinding focus.
if (item._isExpanded && item._isArrowVisible) {
item.collapse();
@ -845,7 +846,7 @@ VariablesView.prototype = {
}
return;
case e.DOM_VK_RIGHT:
case KeyCodes.DOM_VK_RIGHT:
// Nothing to do here if this item never expands.
if (!item._isArrowVisible) {
return;
@ -858,29 +859,29 @@ VariablesView.prototype = {
}
return;
case e.DOM_VK_PAGE_UP:
case KeyCodes.DOM_VK_PAGE_UP:
// Rewind a certain number of elements based on the container height.
this.focusItemAtDelta(-(this.scrollPageSize || Math.min(Math.floor(this._list.scrollHeight /
PAGE_SIZE_SCROLL_HEIGHT_RATIO),
PAGE_SIZE_MAX_JUMPS)));
return;
case e.DOM_VK_PAGE_DOWN:
case KeyCodes.DOM_VK_PAGE_DOWN:
// Advance a certain number of elements based on the container height.
this.focusItemAtDelta(+(this.scrollPageSize || Math.min(Math.floor(this._list.scrollHeight /
PAGE_SIZE_SCROLL_HEIGHT_RATIO),
PAGE_SIZE_MAX_JUMPS)));
return;
case e.DOM_VK_HOME:
case KeyCodes.DOM_VK_HOME:
this.focusFirstVisibleItem();
return;
case e.DOM_VK_END:
case KeyCodes.DOM_VK_END:
this.focusLastVisibleItem();
return;
case e.DOM_VK_RETURN:
case KeyCodes.DOM_VK_RETURN:
// Start editing the value or name of the Variable or Property.
if (item instanceof Variable) {
if (e.metaKey || e.altKey || e.shiftKey) {
@ -891,15 +892,15 @@ VariablesView.prototype = {
}
return;
case e.DOM_VK_DELETE:
case e.DOM_VK_BACK_SPACE:
case KeyCodes.DOM_VK_DELETE:
case KeyCodes.DOM_VK_BACK_SPACE:
// Delete the Variable or Property if allowed.
if (item instanceof Variable) {
item._onDelete(e);
}
return;
case e.DOM_VK_INSERT:
case KeyCodes.DOM_VK_INSERT:
item._onAddProperty(e);
return;
}
@ -909,7 +910,7 @@ VariablesView.prototype = {
* Listener handling a key down event on the view.
*/
_onViewKeyDown: function (e) {
if (e.keyCode == e.DOM_VK_C) {
if (e.keyCode == KeyCodes.DOM_VK_C) {
// Copy current selection to clipboard.
if (e.ctrlKey || e.metaKey) {
let item = this.getFocusedItem();
@ -4082,13 +4083,13 @@ Editable.prototype = {
e.stopPropagation();
switch (e.keyCode) {
case e.DOM_VK_TAB:
case KeyCodes.DOM_VK_TAB:
this._next();
break;
case e.DOM_VK_RETURN:
case KeyCodes.DOM_VK_RETURN:
this._save();
break;
case e.DOM_VK_ESCAPE:
case KeyCodes.DOM_VK_ESCAPE:
this._reset();
break;
}

View File

@ -42,10 +42,6 @@
border-left: 1px solid var(--theme-splitter-color);
}
.presets-list .add {
margin-top: 4px;
}
#filter-container:not(.show-presets) .presets-list {
width: 0;
border-left: none;
@ -73,6 +69,7 @@
.footer {
display: flex;
margin: 10px 3px;
align-items: center;
}
.footer :not(button) {

View File

@ -5,6 +5,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {KeyCodes} = require("devtools/client/shared/keycodes");
const PANE_APPEARANCE_DELAY = 50;
const PAGE_SIZE_ITEM_COUNT_RATIO = 5;
const WIDGET_FOCUSABLE_NODES = new Set(["vbox", "hbox"]);
@ -201,14 +203,14 @@ const ViewHelpers = exports.ViewHelpers = {
*/
preventScrolling: function (e) {
switch (e.keyCode) {
case e.DOM_VK_UP:
case e.DOM_VK_DOWN:
case e.DOM_VK_LEFT:
case e.DOM_VK_RIGHT:
case e.DOM_VK_PAGE_UP:
case e.DOM_VK_PAGE_DOWN:
case e.DOM_VK_HOME:
case e.DOM_VK_END:
case KeyCodes.DOM_VK_UP:
case KeyCodes.DOM_VK_DOWN:
case KeyCodes.DOM_VK_LEFT:
case KeyCodes.DOM_VK_RIGHT:
case KeyCodes.DOM_VK_PAGE_UP:
case KeyCodes.DOM_VK_PAGE_DOWN:
case KeyCodes.DOM_VK_HOME:
case KeyCodes.DOM_VK_END:
e.preventDefault();
e.stopPropagation();
}
@ -221,8 +223,8 @@ const ViewHelpers = exports.ViewHelpers = {
* The event triggered by a keypress on an element
*/
isSpaceOrReturn: function (event) {
return event.keyCode === event.DOM_VK_SPACE ||
event.keyCode === event.DOM_VK_RETURN;
return event.keyCode === KeyCodes.DOM_VK_SPACE ||
event.keyCode === KeyCodes.DOM_VK_RETURN;
},
/**
@ -1501,26 +1503,26 @@ const WidgetMethods = exports.WidgetMethods = {
ViewHelpers.preventScrolling(event);
switch (event.keyCode) {
case event.DOM_VK_UP:
case event.DOM_VK_LEFT:
case KeyCodes.DOM_VK_UP:
case KeyCodes.DOM_VK_LEFT:
this.focusPrevItem();
return;
case event.DOM_VK_DOWN:
case event.DOM_VK_RIGHT:
case KeyCodes.DOM_VK_DOWN:
case KeyCodes.DOM_VK_RIGHT:
this.focusNextItem();
return;
case event.DOM_VK_PAGE_UP:
case KeyCodes.DOM_VK_PAGE_UP:
this.focusItemAtDelta(-(this.pageSize ||
(this.itemCount / PAGE_SIZE_ITEM_COUNT_RATIO)));
return;
case event.DOM_VK_PAGE_DOWN:
case KeyCodes.DOM_VK_PAGE_DOWN:
this.focusItemAtDelta(+(this.pageSize ||
(this.itemCount / PAGE_SIZE_ITEM_COUNT_RATIO)));
return;
case event.DOM_VK_HOME:
case KeyCodes.DOM_VK_HOME:
this.focusFirstVisibleItem();
return;
case event.DOM_VK_END:
case KeyCodes.DOM_VK_END:
this.focusLastVisibleItem();
return;
}

View File

@ -7,6 +7,7 @@
const CSSCompleter = require("devtools/client/sourceeditor/css-autocompleter");
const { AutocompletePopup } = require("devtools/client/shared/autocomplete-popup");
const {KeyCodes} = require("devtools/client/shared/keycodes");
const CM_TERN_SCRIPTS = [
"chrome://devtools/content/sourceeditor/codemirror/addon/tern/tern.js",
@ -316,7 +317,7 @@ function onEditorKeypress({ ed, Editor }, cm, event) {
return;
}
if ((event.ctrlKey || event.metaKey) && event.keyCode == event.DOM_VK_SPACE) {
if ((event.ctrlKey || event.metaKey) && event.keyCode == KeyCodes.DOM_VK_SPACE) {
// When Ctrl/Cmd + Space is pressed, two simultaneous keypresses are emitted
// first one for just the Ctrl/Cmd and second one for combo. The first one
// leave the autocompleteOpts.doNotAutocomplete as true, so we have to make
@ -332,23 +333,23 @@ function onEditorKeypress({ ed, Editor }, cm, event) {
}
switch (event.keyCode) {
case event.DOM_VK_RETURN:
case KeyCodes.DOM_VK_RETURN:
autocompleteOpts.doNotAutocomplete = true;
break;
case event.DOM_VK_ESCAPE:
case KeyCodes.DOM_VK_ESCAPE:
if (autocompleteOpts.popup.isOpen) {
event.preventDefault();
}
break;
case event.DOM_VK_LEFT:
case event.DOM_VK_RIGHT:
case event.DOM_VK_HOME:
case event.DOM_VK_END:
case KeyCodes.DOM_VK_LEFT:
case KeyCodes.DOM_VK_RIGHT:
case KeyCodes.DOM_VK_HOME:
case KeyCodes.DOM_VK_END:
autocompleteOpts.doNotAutocomplete = true;
autocompleteOpts.popup.hidePopup();
break;
case event.DOM_VK_BACK_SPACE:
case event.DOM_VK_DELETE:
case KeyCodes.DOM_VK_BACK_SPACE:
case KeyCodes.DOM_VK_DELETE:
if (ed.config.mode == Editor.modes.css) {
autocompleteOpts.completer.invalidateCache(ed.getCursor().line);
}

View File

@ -10,6 +10,7 @@ const EventEmitter = require("devtools/shared/event-emitter");
const {LocalizationHelper} = require("devtools/client/shared/l10n");
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
const JSOL = require("devtools/client/shared/vendor/jsol");
const {KeyCodes} = require("devtools/client/shared/keycodes");
loader.lazyRequireGetter(this, "TreeWidget",
"devtools/client/shared/widgets/TreeWidget", true);
@ -845,7 +846,7 @@ StorageUI.prototype = {
* The event passed by the keypress event.
*/
handleKeypress: function (event) {
if (event.keyCode == event.DOM_VK_ESCAPE && !this.sidebar.hidden) {
if (event.keyCode == KeyCodes.DOM_VK_ESCAPE && !this.sidebar.hidden) {
// Stop Propagation to prevent opening up of split console
this.hideSidebar();
event.stopPropagation();

View File

@ -34,6 +34,7 @@ const promise = require("promise");
const defer = require("devtools/shared/defer");
const {ResponsiveUIManager} =
require("resource://devtools/client/responsivedesign/responsivedesign.jsm");
const {KeyCodes} = require("devtools/client/shared/keycodes");
const LOAD_ERROR = "error-load";
const STYLE_EDITOR_TEMPLATE = "stylesheet";
@ -532,7 +533,7 @@ StyleEditorUI.prototype = {
wire(summary, ".stylesheet-name", {
events: {
"keypress": (event) => {
if (event.keyCode == event.DOM_VK_RETURN) {
if (event.keyCode == KeyCodes.DOM_VK_RETURN) {
this._view.activeSummary = summary;
}
}

View File

@ -25,6 +25,13 @@
display: inline-block;
}
/* Add element toolbar button */
#inspector-element-add-button::before {
background-image: url("chrome://devtools/skin/images/add.svg");
list-style-image: url("chrome://devtools/skin/images/add.svg");
-moz-user-focus: normal;
}
#inspector-searchlabel {
overflow: hidden;
margin-inline-end: 2px;
@ -52,6 +59,21 @@
line-height: 17px;
}
/* Eyedropper toolbar button */
#inspector-eyedropper-toggle {
/* hidden by default, until we can check that the required highlighter exists */
display: none;
}
#inspector-eyedropper-toggle::before {
background-image: var(--eyedropper-image);
}
#inspector-sidebar-toggle-box {
line-height: initial;
}
#inspector-breadcrumbs-toolbar {
padding: 0px;
border-bottom-width: 0px;
@ -97,21 +119,25 @@
font: message-box;
}
/* Eyedropper toolbar button */
#inspector-eyedropper-toggle {
/* hidden by default, until we can check that the required highlighter exists */
display: none;
/* Set the minimum width for the side bar so, all tabs are
properly visible. The value can be decreased when bug 1281789
is fixed and the all-tabs-menu is available again. */
#inspector-sidebar-container {
overflow: hidden;
min-width: 450px;
position: relative;
}
#inspector-eyedropper-toggle::before {
background-image: var(--eyedropper-image);
#inspector-sidebar {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
/* Add element toolbar button */
#inspector-element-add-button::before {
background-image: url("chrome://devtools/skin/images/add.svg");
list-style-image: url("chrome://devtools/skin/images/add.svg");
/* Override `-moz-user-focus:ignore;` from toolkit/content/minimal-xul.css */
.inspector-tabpanel > * {
-moz-user-focus: normal;
}

View File

@ -6,13 +6,12 @@
"use strict";
const {Ci} = require("chrome");
const {Utils: WebConsoleUtils} =
require("devtools/client/webconsole/utils");
const promise = require("promise");
const Debugger = require("Debugger");
const Services = require("Services");
const {KeyCodes} = require("devtools/client/shared/keycodes");
loader.lazyServiceGetter(this, "clipboardHelper",
"@mozilla.org/widget/clipboardhelper;1",
@ -688,7 +687,7 @@ JSTerm.prototype = {
*/
_onKeypressInVariablesView: function (event) {
let tag = event.target.nodeName;
if (event.keyCode != Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE || event.shiftKey ||
if (event.keyCode != KeyCodes.DOM_VK_ESCAPE || event.shiftKey ||
event.altKey || event.ctrlKey || event.metaKey ||
["input", "textarea", "select", "textbox"].indexOf(tag) > -1) {
return;
@ -1117,7 +1116,7 @@ JSTerm.prototype = {
break;
}
return;
} else if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN) {
} else if (event.keyCode == KeyCodes.DOM_VK_RETURN) {
let autoMultiline = Services.prefs.getBoolPref(PREF_AUTO_MULTILINE);
if (event.shiftKey ||
(!Debugger.isCompilableUnit(inputNode.value) && autoMultiline)) {
@ -1127,7 +1126,7 @@ JSTerm.prototype = {
}
switch (event.keyCode) {
case Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE:
case KeyCodes.DOM_VK_ESCAPE:
if (this.autocompletePopup.isOpen) {
this.clearCompletion();
event.preventDefault();
@ -1139,7 +1138,7 @@ JSTerm.prototype = {
}
break;
case Ci.nsIDOMKeyEvent.DOM_VK_RETURN:
case KeyCodes.DOM_VK_RETURN:
if (this._autocompletePopupNavigated &&
this.autocompletePopup.isOpen &&
this.autocompletePopup.selectedIndex > -1) {
@ -1151,7 +1150,7 @@ JSTerm.prototype = {
event.preventDefault();
break;
case Ci.nsIDOMKeyEvent.DOM_VK_UP:
case KeyCodes.DOM_VK_UP:
if (this.autocompletePopup.isOpen) {
inputUpdated = this.complete(this.COMPLETE_BACKWARD);
if (inputUpdated) {
@ -1165,7 +1164,7 @@ JSTerm.prototype = {
}
break;
case Ci.nsIDOMKeyEvent.DOM_VK_DOWN:
case KeyCodes.DOM_VK_DOWN:
if (this.autocompletePopup.isOpen) {
inputUpdated = this.complete(this.COMPLETE_FORWARD);
if (inputUpdated) {
@ -1179,7 +1178,7 @@ JSTerm.prototype = {
}
break;
case Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP:
case KeyCodes.DOM_VK_PAGE_UP:
if (this.autocompletePopup.isOpen) {
inputUpdated = this.complete(this.COMPLETE_PAGEUP);
if (inputUpdated) {
@ -1195,7 +1194,7 @@ JSTerm.prototype = {
event.preventDefault();
break;
case Ci.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN:
case KeyCodes.DOM_VK_PAGE_DOWN:
if (this.autocompletePopup.isOpen) {
inputUpdated = this.complete(this.COMPLETE_PAGEDOWN);
if (inputUpdated) {
@ -1211,7 +1210,7 @@ JSTerm.prototype = {
event.preventDefault();
break;
case Ci.nsIDOMKeyEvent.DOM_VK_HOME:
case KeyCodes.DOM_VK_HOME:
if (this.autocompletePopup.isOpen) {
this.autocompletePopup.selectedIndex = 0;
event.preventDefault();
@ -1221,7 +1220,7 @@ JSTerm.prototype = {
}
break;
case Ci.nsIDOMKeyEvent.DOM_VK_END:
case KeyCodes.DOM_VK_END:
if (this.autocompletePopup.isOpen) {
this.autocompletePopup.selectedIndex =
this.autocompletePopup.itemCount - 1;
@ -1233,13 +1232,13 @@ JSTerm.prototype = {
}
break;
case Ci.nsIDOMKeyEvent.DOM_VK_LEFT:
case KeyCodes.DOM_VK_LEFT:
if (this.autocompletePopup.isOpen || this.lastCompletion.value) {
this.clearCompletion();
}
break;
case Ci.nsIDOMKeyEvent.DOM_VK_RIGHT:
case KeyCodes.DOM_VK_RIGHT:
let cursorAtTheEnd = this.inputNode.selectionStart ==
this.inputNode.selectionEnd &&
this.inputNode.selectionStart ==
@ -1258,7 +1257,7 @@ JSTerm.prototype = {
}
break;
case Ci.nsIDOMKeyEvent.DOM_VK_TAB:
case KeyCodes.DOM_VK_TAB:
// Generate a completion and accept the first proposed value.
if (this.complete(this.COMPLETE_HINT_ONLY) &&
this.lastCompletion &&

View File

@ -156,6 +156,15 @@ var inputTests = [
inspectable: true,
variablesViewLabel: "Object",
},
// 17
{
input: '({" ": "a"})',
output: 'Object { : "a" }',
printOutput: "[object Object]",
inspectable: true,
variablesViewLabel: "Object",
},
];
function test() {

View File

@ -1795,13 +1795,18 @@ DebuggerServer.ObjectActorPreviewers.Object = [
function PseudoArray({obj, hooks}, grip, rawObj) {
let length = 0;
// Making sure all keys are numbers from 0 to length-1
let keys = obj.getOwnPropertyNames();
if (keys.length == 0) {
return false;
}
// Making sure that all keys are array indices, that is:
// `ToString(ToUint32(key)) === key && key !== "4294967295"`.
// Also ensuring that the keys are consecutive and start at "0",
// this implies checking `key !== "4294967295"` is not necessary.
for (let key of keys) {
if (isNaN(key) || key != length++) {
let numKey = key >>> 0; // ToUint32(key)
if (numKey + '' != key || numKey != length++) {
return false;
}
}

View File

@ -559,7 +559,7 @@ exports.createEmptyNodeList = function(doc) {
* Keyboard handling is a mess. http://unixpapa.com/js/key.html
* It would be good to use DOM L3 Keyboard events,
* http://www.w3.org/TR/2010/WD-DOM-Level-3-Events-20100907/#events-keyboardevents
* however only Webkit supports them, and there isn't a shim on Monernizr:
* however only Webkit supports them, and there isn't a shim on Modernizr:
* https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills
* and when the code that uses this KeyEvent was written, nothing was clear,
* so instead, we're using this unmodern shim:

View File

@ -482,11 +482,6 @@ this.PermissionsTable = { geolocation: {
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"presentation": {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"open-hidden-window": {
app: DENY_ACTION,
privileged: DENY_ACTION,

View File

@ -2331,58 +2331,6 @@ Navigator::HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal)
}
#endif
/* static */
bool
Navigator::HasPresentationSupport(JSContext* aCx, JSObject* aGlobal)
{
JS::Rooted<JSObject*> global(aCx, aGlobal);
nsCOMPtr<nsPIDOMWindowInner> inner = GetWindowFromGlobal(global);
if (NS_WARN_IF(!inner)) {
return false;
}
// Grant access if it has the permission.
if (CheckPermission(inner, "presentation")) {
return true;
}
// Grant access to browser receiving pages and their same-origin iframes. (App
// pages should be controlled by "presentation" permission in app manifests.)
nsCOMPtr<nsIDocShell> docshell = inner->GetDocShell();
if (!docshell) {
return false;
}
if (!docshell->GetIsInMozBrowserOrApp()) {
return false;
}
nsAutoString presentationURL;
nsContentUtils::GetPresentationURL(docshell, presentationURL);
if (presentationURL.IsEmpty()) {
return false;
}
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
if (!securityManager) {
return false;
}
nsCOMPtr<nsIURI> presentationURI;
nsresult rv = NS_NewURI(getter_AddRefs(presentationURI), presentationURL);
if (NS_FAILED(rv)) {
return false;
}
nsCOMPtr<nsIURI> docURI = inner->GetDocumentURI();
return NS_SUCCEEDED(securityManager->CheckSameOriginURI(presentationURI,
docURI,
false));
}
/* static */
bool
Navigator::IsE10sEnabled(JSContext* aCx, JSObject* aGlobal)

View File

@ -323,8 +323,6 @@ public:
static bool HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal);
#endif
static bool HasPresentationSupport(JSContext* aCx, JSObject* aGlobal);
static bool IsE10sEnabled(JSContext* aCx, JSObject* aGlobal);
nsPIDOMWindowInner* GetParentObject() const

View File

@ -1218,7 +1218,8 @@ protected:
// (1) error occurs during reading of the object
// (2) the image data is not in a supported file format
// (3) the image data is corrupted
// All these three cases should reject promise with null value
// All these three cases should reject the promise with "InvalidStateError"
// DOMException
if (!imageBitmap) {
return false;
}
@ -1279,7 +1280,7 @@ private:
RefPtr<layers::Image> data = DecodeAndCropBlob(*mBlob, mCropRect, sourceSize);
if (NS_WARN_IF(!data)) {
mPromise->MaybeRejectWithNull();
mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
@ -1375,7 +1376,7 @@ private:
}
if (NS_WARN_IF(!data)) {
mPromise->MaybeRejectWithNull();
mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}

View File

@ -2,15 +2,15 @@ function testBug1239300() {
return new Promise(function(resolve, reject) {
createImageBitmap(new Blob()).then(
function() {
ok(false, "The promise should be rejected with null.");
ok(false, "The promise should be rejected with InvalidStateError.");
reject();
},
function(result) {
if (result == null) {
ok(true, "The promise should be rejected with null.");
if (result.name == "InvalidStateError") {
ok(true, "The promise should be rejected with InvalidStateError.");
resolve();
} else {
ok(false, "The promise should be rejected with null.");
ok(false, "The promise should be rejected with InvalidStateError.");
reject();
}
}

View File

@ -1553,7 +1553,11 @@ ContentEventHandler::GetLastFrameInRangeForTextRect(nsRange* aRange)
// include the last frame when its content isn't really in aRange.
nsINode* nextNodeOfRangeEnd = nullptr;
if (endNode->IsNodeOfType(nsINode::eTEXT)) {
if (!endOffset) {
// Don't set nextNodeOfRangeEnd to the start node of aRange because if
// endNode is same as start node of the range, the text node shouldn't be
// next of range end even if the offset is 0. This could occur with empty
// text node.
if (!endOffset && aRange->GetStartParent() != endNode) {
nextNodeOfRangeEnd = endNode;
}
} else if (endOffset < endNode->GetChildCount()) {
@ -1577,6 +1581,13 @@ ContentEventHandler::GetLastFrameInRangeForTextRect(nsRange* aRange)
} else {
nodePosition.mOffset = node->Length();
}
// If the text node is empty or the last node of the range but the index
// is 0, we should store current position but continue looking for
// previous node (If there are no nodes before it, we should use current
// node position for returning its frame).
if (!nodePosition.mOffset) {
continue;
}
break;
}
@ -1612,10 +1623,10 @@ ContentEventHandler::GetLastFrameInRangeForTextRect(nsRange* aRange)
}
// If the start offset in the node is same as the computed offset in the
// node, the frame shouldn't be added to the text rect. So, this should
// return previous text frame and its last offset.
if (nodePosition.mOffset == start) {
MOZ_ASSERT(nodePosition.mOffset);
// node and it's not 0, the frame shouldn't be added to the text rect. So,
// this should return previous text frame and its last offset if there is
// at least one text frame.
if (nodePosition.mOffset && nodePosition.mOffset == start) {
GetFrameForTextRect(nodePosition.mNode, --nodePosition.mOffset,
true, &lastFrame);
if (NS_WARN_IF(!lastFrame)) {

View File

@ -163,7 +163,7 @@ private:
}
aReader->SetIsSuspended(true);
aReader->ReleaseMediaResources();
aReader->ReleaseResources();
}
static void DispatchResume(MediaDecoderReader* aReader)
@ -520,7 +520,7 @@ MediaDecoderReader::Shutdown()
mDataArrivedListener.DisconnectIfExists();
ReleaseMediaResources();
ReleaseResources();
mDuration.DisconnectIfConnected();
mBuffered.DisconnectAll();
mIsSuspended.DisconnectAll();

View File

@ -102,9 +102,10 @@ public:
// on failure.
virtual nsresult Init() { return NS_OK; }
// Release media resources they should be released in dormant state
// The reader can be made usable again by calling ReadMetadata().
virtual void ReleaseMediaResources() {}
// Called by MDSM in dormant state to release resources allocated by this
// reader. The reader can resume decoding by calling Seek() to a specific
// position.
virtual void ReleaseResources() {}
// Destroys the decoding state. The reader cannot be made usable again.
// This is different from ReleaseMediaResources() as it is irreversable,

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