зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to central, a=merge
MozReview-Commit-ID: B7tVdcR40eh
This commit is contained in:
Коммит
f831128354
|
@ -83,6 +83,8 @@ devtools/client/canvasdebugger/**
|
|||
devtools/client/commandline/**
|
||||
devtools/client/debugger/**
|
||||
devtools/client/framework/**
|
||||
!devtools/client/framework/devtools.js
|
||||
!devtools/client/framework/devtools-browser.js
|
||||
!devtools/client/framework/selection.js
|
||||
!devtools/client/framework/target*
|
||||
!devtools/client/framework/toolbox*
|
||||
|
|
|
@ -699,6 +699,8 @@ pref("browser.preferences.offlineGroup.enabled", false);
|
|||
pref("browser.preferences.offlineGroup.enabled", true);
|
||||
#endif
|
||||
|
||||
pref("browser.preferences.defaultPerformanceSettings.enabled", true);
|
||||
|
||||
pref("browser.download.show_plugins_in_list", true);
|
||||
pref("browser.download.hide_plugins_without_extensions", true);
|
||||
|
||||
|
@ -1455,6 +1457,8 @@ pref("browser.translation.engine", "bing");
|
|||
// Telemetry settings.
|
||||
// Determines if Telemetry pings can be archived locally.
|
||||
pref("toolkit.telemetry.archive.enabled", true);
|
||||
// Enables sending the shutdown ping when Firefox shuts down.
|
||||
pref("toolkit.telemetry.shutdownPingSender.enabled", true);
|
||||
|
||||
// Telemetry experiments settings.
|
||||
pref("experiments.enabled", true);
|
||||
|
|
|
@ -3488,23 +3488,41 @@ function getPEMString(cert) {
|
|||
|
||||
var PrintPreviewListener = {
|
||||
_printPreviewTab: null,
|
||||
_simplifiedPrintPreviewTab: null,
|
||||
_tabBeforePrintPreview: null,
|
||||
_simplifyPageTab: null,
|
||||
_lastRequestedPrintPreviewTab: null,
|
||||
|
||||
_createPPBrowser() {
|
||||
if (!this._tabBeforePrintPreview) {
|
||||
this._tabBeforePrintPreview = gBrowser.selectedTab;
|
||||
}
|
||||
let browser = this._tabBeforePrintPreview.linkedBrowser;
|
||||
let preferredRemoteType = browser.remoteType;
|
||||
return gBrowser.loadOneTab("about:printpreview", {
|
||||
inBackground: true,
|
||||
preferredRemoteType,
|
||||
sameProcessAsFrameLoader: browser.frameLoader
|
||||
});
|
||||
},
|
||||
getPrintPreviewBrowser() {
|
||||
if (!this._printPreviewTab) {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let preferredRemoteType = browser.remoteType;
|
||||
this._tabBeforePrintPreview = gBrowser.selectedTab;
|
||||
this._printPreviewTab = gBrowser.loadOneTab("about:printpreview", {
|
||||
inBackground: false,
|
||||
preferredRemoteType,
|
||||
sameProcessAsFrameLoader: browser.frameLoader
|
||||
});
|
||||
gBrowser.selectedTab = this._printPreviewTab;
|
||||
this._printPreviewTab = this._createPPBrowser();
|
||||
}
|
||||
gBrowser._allowTabChange = true;
|
||||
this._lastRequestedPrintPreviewTab = gBrowser.selectedTab = this._printPreviewTab;
|
||||
gBrowser._allowTabChange = false;
|
||||
return gBrowser.getBrowserForTab(this._printPreviewTab);
|
||||
},
|
||||
getSimplifiedPrintPreviewBrowser() {
|
||||
if (!this._simplifiedPrintPreviewTab) {
|
||||
this._simplifiedPrintPreviewTab = this._createPPBrowser();
|
||||
}
|
||||
gBrowser._allowTabChange = true;
|
||||
this._lastRequestedPrintPreviewTab = gBrowser.selectedTab = this._simplifiedPrintPreviewTab;
|
||||
gBrowser._allowTabChange = false;
|
||||
return gBrowser.getBrowserForTab(this._simplifiedPrintPreviewTab);
|
||||
},
|
||||
createSimplifiedBrowser() {
|
||||
let browser = this._tabBeforePrintPreview.linkedBrowser;
|
||||
this._simplifyPageTab = gBrowser.loadOneTab("about:printpreview", {
|
||||
|
@ -3527,8 +3545,8 @@ var PrintPreviewListener = {
|
|||
onEnter() {
|
||||
// We might have accidentally switched tabs since the user invoked print
|
||||
// preview
|
||||
if (gBrowser.selectedTab != this._printPreviewTab) {
|
||||
gBrowser.selectedTab = this._printPreviewTab;
|
||||
if (gBrowser.selectedTab != this._lastRequestedPrintPreviewTab) {
|
||||
gBrowser.selectedTab = this._lastRequestedPrintPreviewTab;
|
||||
}
|
||||
gInPrintPreviewMode = true;
|
||||
this._toggleAffectedChrome();
|
||||
|
@ -3538,13 +3556,15 @@ var PrintPreviewListener = {
|
|||
this._tabBeforePrintPreview = null;
|
||||
gInPrintPreviewMode = false;
|
||||
this._toggleAffectedChrome();
|
||||
if (this._simplifyPageTab) {
|
||||
gBrowser.removeTab(this._simplifyPageTab);
|
||||
this._simplifyPageTab = null;
|
||||
let tabsToRemove = ["_simplifyPageTab", "_printPreviewTab", "_simplifiedPrintPreviewTab"];
|
||||
for (let tabProp of tabsToRemove) {
|
||||
if (this[tabProp]) {
|
||||
gBrowser.removeTab(this[tabProp]);
|
||||
this[tabProp] = null;
|
||||
}
|
||||
}
|
||||
gBrowser.removeTab(this._printPreviewTab);
|
||||
gBrowser.deactivatePrintPreviewBrowsers();
|
||||
this._printPreviewTab = null;
|
||||
this._lastRequestedPrintPreviewTab = null;
|
||||
},
|
||||
_toggleAffectedChrome() {
|
||||
gNavToolbox.collapsed = gInPrintPreviewMode;
|
||||
|
|
|
@ -3394,7 +3394,7 @@
|
|||
</getter>
|
||||
<setter>
|
||||
<![CDATA[
|
||||
if (gNavToolbox.collapsed) {
|
||||
if (gNavToolbox.collapsed && !this._allowTabChange) {
|
||||
return this.mTabBox.selectedTab;
|
||||
}
|
||||
// Update the tab
|
||||
|
|
|
@ -90,7 +90,9 @@ add_task(function* test_plaintext() {
|
|||
"context-viewsource", true,
|
||||
"context-viewinfo", true
|
||||
];
|
||||
yield test_contextmenu("#test-text", plainTextItems);
|
||||
yield test_contextmenu("#test-text", plainTextItems, {
|
||||
maybeScreenshotsPresent: true
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* test_link() {
|
||||
|
@ -139,7 +141,9 @@ add_task(function* test_canvas() {
|
|||
["context-viewimage", true,
|
||||
"context-saveimage", true,
|
||||
"context-selectall", true
|
||||
]
|
||||
], {
|
||||
maybeScreenshotsPresent: true
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -433,7 +437,9 @@ add_task(function* test_textarea_spellcheck() {
|
|||
});
|
||||
|
||||
add_task(function* test_plaintext2() {
|
||||
yield test_contextmenu("#test-text", plainTextItems);
|
||||
yield test_contextmenu("#test-text", plainTextItems, {
|
||||
maybeScreenshotsPresent: true
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* test_undo_add_to_dictionary() {
|
||||
|
@ -569,7 +575,8 @@ add_task(function* test_pagemenu() {
|
|||
let pagemenu = content.document.getElementById("test-pagemenu");
|
||||
Assert.ok(!pagemenu.hasAttribute("hopeless"), "attribute got removed");
|
||||
});
|
||||
}
|
||||
},
|
||||
maybeScreenshotsPresent: true
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -593,6 +600,7 @@ add_task(function* test_dom_full_screen() {
|
|||
"context-viewinfo", true
|
||||
],
|
||||
{
|
||||
maybeScreenshotsPresent: true,
|
||||
shiftkey: true,
|
||||
*preCheckContextMenuFn() {
|
||||
yield pushPrefs(["full-screen-api.allow-trusted-requests-only", false],
|
||||
|
@ -638,7 +646,8 @@ add_task(function* test_pagemenu2() {
|
|||
"context-viewsource", true,
|
||||
"context-viewinfo", true
|
||||
],
|
||||
{shiftkey: true}
|
||||
{maybeScreenshotsPresent: true,
|
||||
shiftkey: true}
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -817,6 +826,7 @@ add_task(function* test_click_to_play_blocked_plugin() {
|
|||
"context-viewinfo", true
|
||||
],
|
||||
{
|
||||
maybeScreenshotsPresent: true,
|
||||
*preCheckContextMenuFn() {
|
||||
pushPrefs(["plugins.click_to_play", true]);
|
||||
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
|
||||
|
@ -922,6 +932,7 @@ add_task(function* test_plaintext_sendpagetodevice() {
|
|||
"context-viewinfo", true
|
||||
];
|
||||
yield test_contextmenu("#test-text", plainTextItemsWithSendPage, {
|
||||
maybeScreenshotsPresent: true,
|
||||
*onContextMenuShown() {
|
||||
yield openMenuItemSubmenu("context-sendpagetodevice");
|
||||
}
|
||||
|
|
|
@ -174,9 +174,13 @@ add_task(function* test_tel_email_url_number_input() {
|
|||
"context-paste", null, // ignore clipboard state
|
||||
"context-delete", false,
|
||||
"---", null,
|
||||
"context-selectall", null],
|
||||
{skipFocusChange: true}
|
||||
);
|
||||
"context-selectall", null], {
|
||||
// XXX Bug 1345081. Currently the Screenshots menu option is shown for
|
||||
// various text elements even though it is set to type "page". That bug
|
||||
// should remove the need for next line.
|
||||
maybeScreenshotsPresent: true,
|
||||
skipFocusChange: true
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -198,9 +202,13 @@ add_task(function* test_date_time_color_range_month_week_datetimelocal_input() {
|
|||
"context-selectall", null,
|
||||
"---", null,
|
||||
"context-viewsource", true,
|
||||
"context-viewinfo", true],
|
||||
{skipFocusChange: true}
|
||||
);
|
||||
"context-viewinfo", true], {
|
||||
// XXX Bug 1345081. Currently the Screenshots menu option is shown for
|
||||
// various text elements even though it is set to type "page". That bug
|
||||
// should remove the need for next line.
|
||||
maybeScreenshotsPresent: true,
|
||||
skipFocusChange: true
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -234,9 +242,13 @@ add_task(function* test_text_input_readonly() {
|
|||
"context-paste", null, // ignore clipboard state
|
||||
"context-delete", false,
|
||||
"---", null,
|
||||
"context-selectall", null],
|
||||
{skipFocusChange: true}
|
||||
);
|
||||
"context-selectall", null], {
|
||||
// XXX Bug 1345081. Currently the Screenshots menu option is shown for
|
||||
// various text elements even though it is set to type "page". That bug
|
||||
// should remove the need for next line.
|
||||
maybeScreenshotsPresent: true,
|
||||
skipFocusChange: true
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* test_cleanup() {
|
||||
|
|
|
@ -69,7 +69,10 @@ function getVisibleMenuItems(aMenu, aData) {
|
|||
item.id != "spell-add-dictionaries-main" &&
|
||||
item.id != "context-savelinktopocket" &&
|
||||
item.id != "fill-login-saved-passwords" &&
|
||||
item.id != "fill-login-no-logins") {
|
||||
item.id != "fill-login-no-logins" &&
|
||||
// XXX Screenshots doesn't have an access key. This needs
|
||||
// at least bug 1320462 fixing first.
|
||||
item.id != "screenshots_mozilla_org_create-screenshot") {
|
||||
ok(key, "menuitem " + item.id + " has an access key");
|
||||
if (accessKeys[key])
|
||||
ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
|
||||
|
@ -246,6 +249,9 @@ let lastElementSelector = null;
|
|||
* to true if offsetX and offsetY are not provided
|
||||
* waitForSpellCheck: wait until spellcheck is initialized before
|
||||
* starting test
|
||||
* maybeScreenshotsPresent: if true, the screenshots menu entry is
|
||||
* expected to be present in the menu if
|
||||
* screenshots is enabled, optional
|
||||
* preCheckContextMenuFn: callback to run before opening menu
|
||||
* onContextMenuShown: callback to run when the context menu is shown
|
||||
* postCheckContextMenuFn: callback to run after opening menu
|
||||
|
@ -315,6 +321,17 @@ function* test_contextmenu(selector, menuItems, options = {}) {
|
|||
menuItems = menuItems.concat(inspectItems);
|
||||
}
|
||||
|
||||
if (options.maybeScreenshotsPresent &&
|
||||
!Services.prefs.getBoolPref("extensions.screenshots.disabled", false) &&
|
||||
!Services.prefs.getBoolPref("extensions.screenshots.system-disabled", false)) {
|
||||
let screenshotItems = [
|
||||
"---", null,
|
||||
"screenshots_mozilla_org_create-screenshot", true
|
||||
];
|
||||
|
||||
menuItems = menuItems.concat(screenshotItems);
|
||||
}
|
||||
|
||||
checkContextMenu(menuItems);
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,10 @@ var whitelist = new Set([
|
|||
// Add-on API introduced in bug 1118285
|
||||
{file: "resource://app/modules/NewTabURL.jsm"},
|
||||
|
||||
// browser/components/newtab bug 1355166
|
||||
{file: "resource://app/modules/NewTabSearchProvider.jsm"},
|
||||
{file: "resource://app/modules/NewTabWebChannel.jsm"},
|
||||
|
||||
// layout/mathml/nsMathMLChar.cpp
|
||||
{file: "resource://gre/res/fonts/mathfontSTIXGeneral.properties"},
|
||||
{file: "resource://gre/res/fonts/mathfontUnicode.properties"},
|
||||
|
|
|
@ -267,6 +267,8 @@
|
|||
{
|
||||
"type": "object",
|
||||
"name": "createData",
|
||||
"optional": true,
|
||||
"default": {},
|
||||
"properties": {
|
||||
"url": {
|
||||
"description": "A URL or array of URLs to open as tabs in the window. Fully-qualified URLs must include a scheme (i.e. 'http://www.google.com', not 'www.google.com'). Relative URLs will be relative to the current page within the extension. Defaults to the New Tab Page.",
|
||||
|
|
|
@ -23,7 +23,9 @@ add_task(function* testWindowCreate() {
|
|||
}
|
||||
|
||||
async function createWindow(params, expected, keep = false) {
|
||||
let window = await browser.windows.create(params);
|
||||
let window = await browser.windows.create(...params);
|
||||
// params is null when testing create without createData
|
||||
params = params[0] || {};
|
||||
|
||||
for (let key of Object.keys(params)) {
|
||||
if (key == "state" && os == "mac" && params.state == "normal") {
|
||||
|
@ -54,13 +56,19 @@ add_task(function* testWindowCreate() {
|
|||
try {
|
||||
({os} = await browser.runtime.getPlatformInfo());
|
||||
|
||||
await createWindow({state: "maximized"}, {state: "STATE_MAXIMIZED"});
|
||||
await createWindow({state: "minimized"}, {state: "STATE_MINIMIZED"});
|
||||
await createWindow({state: "normal"}, {state: "STATE_NORMAL", hiddenChrome: []});
|
||||
await createWindow({state: "fullscreen"}, {state: "STATE_FULLSCREEN"});
|
||||
// Set the current window to state: "normal" because the test is failing on Windows
|
||||
// where the current window is maximized.
|
||||
let currentWindow = await browser.windows.getCurrent();
|
||||
await browser.windows.update(currentWindow.id, {state: "normal"});
|
||||
|
||||
await createWindow([], {state: "STATE_NORMAL"});
|
||||
await createWindow([{state: "maximized"}], {state: "STATE_MAXIMIZED"});
|
||||
await createWindow([{state: "minimized"}], {state: "STATE_MINIMIZED"});
|
||||
await createWindow([{state: "normal"}], {state: "STATE_NORMAL", hiddenChrome: []});
|
||||
await createWindow([{state: "fullscreen"}], {state: "STATE_FULLSCREEN"});
|
||||
|
||||
let window = await createWindow(
|
||||
{type: "popup"},
|
||||
[{type: "popup"}],
|
||||
{hiddenChrome: ["menubar", "toolbar", "location", "directories", "status", "extrachrome"],
|
||||
chromeFlags: ["CHROME_OPENAS_DIALOG"]},
|
||||
true);
|
||||
|
|
|
@ -1,242 +0,0 @@
|
|||
/* global
|
||||
NewTabWebChannel,
|
||||
NewTabPrefsProvider,
|
||||
PlacesProvider,
|
||||
PreviewProvider,
|
||||
NewTabSearchProvider,
|
||||
Preferences,
|
||||
XPCOMUtils,
|
||||
Task
|
||||
*/
|
||||
|
||||
/* exported NewTabMessages */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {utils: Cu} = Components;
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesProvider",
|
||||
"resource:///modules/PlacesProvider.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PreviewProvider",
|
||||
"resource:///modules/PreviewProvider.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
|
||||
"resource:///modules/NewTabPrefsProvider.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabSearchProvider",
|
||||
"resource:///modules/NewTabSearchProvider.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabWebChannel",
|
||||
"resource:///modules/NewTabWebChannel.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["NewTabMessages"];
|
||||
|
||||
const PREF_ENABLED = "browser.newtabpage.remote";
|
||||
const CURRENT_ENGINE = "browser-search-engine-modified";
|
||||
|
||||
// Action names are from the content's perspective. in from chrome == out from content
|
||||
// Maybe replace the ACTION objects by a bi-directional Map a bit later?
|
||||
const ACTIONS = {
|
||||
inboundActions: [
|
||||
"REQUEST_PREFS",
|
||||
"REQUEST_THUMB",
|
||||
"REQUEST_FRECENT",
|
||||
"REQUEST_UISTRINGS",
|
||||
"REQUEST_SEARCH_SUGGESTIONS",
|
||||
"REQUEST_MANAGE_ENGINES",
|
||||
"REQUEST_SEARCH_STATE",
|
||||
"REQUEST_REMOVE_FORM_HISTORY",
|
||||
"REQUEST_PERFORM_SEARCH",
|
||||
"REQUEST_CYCLE_ENGINE",
|
||||
],
|
||||
prefs: {
|
||||
inPrefs: "REQUEST_PREFS",
|
||||
outPrefs: "RECEIVE_PREFS",
|
||||
},
|
||||
preview: {
|
||||
inThumb: "REQUEST_THUMB",
|
||||
outThumb: "RECEIVE_THUMB",
|
||||
},
|
||||
links: {
|
||||
inFrecent: "REQUEST_FRECENT",
|
||||
outFrecent: "RECEIVE_FRECENT",
|
||||
outPlacesChange: "RECEIVE_PLACES_CHANGE",
|
||||
},
|
||||
search: {
|
||||
inSearch: {
|
||||
UIStrings: "REQUEST_UISTRINGS",
|
||||
suggestions: "REQUEST_SEARCH_SUGGESTIONS",
|
||||
manageEngines: "REQUEST_MANAGE_ENGINES",
|
||||
state: "REQUEST_SEARCH_STATE",
|
||||
removeFormHistory: "REQUEST_REMOVE_FORM_HISTORY",
|
||||
performSearch: "REQUEST_PERFORM_SEARCH",
|
||||
cycleEngine: "REQUEST_CYCLE_ENGINE"
|
||||
},
|
||||
outSearch: {
|
||||
UIStrings: "RECEIVE_UISTRINGS",
|
||||
suggestions: "RECEIVE_SEARCH_SUGGESTIONS",
|
||||
state: "RECEIVE_SEARCH_STATE",
|
||||
currentEngine: "RECEIVE_CURRENT_ENGINE"
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let NewTabMessages = {
|
||||
|
||||
_prefs: {},
|
||||
|
||||
/** NEWTAB EVENT HANDLERS **/
|
||||
|
||||
handleContentRequest(actionName, {data, target}) {
|
||||
switch (actionName) {
|
||||
case ACTIONS.prefs.inPrefs:
|
||||
// Return to the originator all newtabpage prefs
|
||||
let results = NewTabPrefsProvider.prefs.newtabPagePrefs;
|
||||
NewTabWebChannel.send(ACTIONS.prefs.outPrefs, results, target);
|
||||
break;
|
||||
case ACTIONS.preview.inThumb:
|
||||
// Return to the originator a preview URL
|
||||
PreviewProvider.getThumbnail(data).then(imgData => {
|
||||
NewTabWebChannel.send(ACTIONS.preview.outThumb, {url: data, imgData}, target);
|
||||
});
|
||||
break;
|
||||
case ACTIONS.links.inFrecent:
|
||||
// Return to the originator the top frecent links
|
||||
PlacesProvider.links.getLinks().then(links => {
|
||||
NewTabWebChannel.send(ACTIONS.links.outFrecent, links, target);
|
||||
});
|
||||
break;
|
||||
case ACTIONS.search.inSearch.UIStrings:
|
||||
// Return to the originator all search strings to display
|
||||
let strings = NewTabSearchProvider.search.searchSuggestionUIStrings;
|
||||
NewTabWebChannel.send(ACTIONS.search.outSearch.UIStrings, strings, target);
|
||||
break;
|
||||
case ACTIONS.search.inSearch.suggestions:
|
||||
// Return to the originator all search suggestions
|
||||
Task.spawn(function*() {
|
||||
try {
|
||||
let {engineName, searchString} = data;
|
||||
let suggestions = yield NewTabSearchProvider.search.asyncGetSuggestions(engineName, searchString, target);
|
||||
NewTabWebChannel.send(ACTIONS.search.outSearch.suggestions, suggestions, target);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case ACTIONS.search.inSearch.manageEngines:
|
||||
// Open about:preferences to manage search state
|
||||
NewTabSearchProvider.search.manageEngines(target.browser);
|
||||
break;
|
||||
case ACTIONS.search.inSearch.state:
|
||||
// Return the state of the search component (i.e current engine and visible engine details)
|
||||
Task.spawn(function*() {
|
||||
try {
|
||||
let state = yield NewTabSearchProvider.search.asyncGetState();
|
||||
NewTabWebChannel.broadcast(ACTIONS.search.outSearch.state, state);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case ACTIONS.search.inSearch.removeFormHistory:
|
||||
// Remove a form history entry from the search component
|
||||
let suggestion = data;
|
||||
NewTabSearchProvider.search.removeFormHistory(target, suggestion);
|
||||
break;
|
||||
case ACTIONS.search.inSearch.performSearch:
|
||||
// Perform a search
|
||||
NewTabSearchProvider.search.asyncPerformSearch(target, data).catch(Cu.reportError);
|
||||
break;
|
||||
case ACTIONS.search.inSearch.cycleEngine:
|
||||
// Set the new current engine
|
||||
NewTabSearchProvider.search.asyncCycleEngine(data).catch(Cu.reportError);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Broadcast places change to all open newtab pages
|
||||
*/
|
||||
handlePlacesChange(type, data) {
|
||||
NewTabWebChannel.broadcast(ACTIONS.links.outPlacesChange, {type, data});
|
||||
},
|
||||
|
||||
/*
|
||||
* Broadcast current engine has changed to all open newtab pages
|
||||
*/
|
||||
_handleCurrentEngineChange(name, value) { // jshint unused: false
|
||||
let engine = value;
|
||||
NewTabWebChannel.broadcast(ACTIONS.search.outSearch.currentEngine, engine);
|
||||
},
|
||||
|
||||
/*
|
||||
* Broadcast preference changes to all open newtab pages
|
||||
*/
|
||||
handlePrefChange(actionName, value) {
|
||||
let prefChange = {};
|
||||
prefChange[actionName] = value;
|
||||
NewTabWebChannel.broadcast(ACTIONS.prefs.outPrefs, prefChange);
|
||||
},
|
||||
|
||||
_handleEnabledChange(prefName, value) {
|
||||
if (prefName === PREF_ENABLED) {
|
||||
if (this._prefs.enabled && !value) {
|
||||
this.uninit();
|
||||
} else if (!this._prefs.enabled && value) {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
init() {
|
||||
this.handleContentRequest = this.handleContentRequest.bind(this);
|
||||
this._handleEnabledChange = this._handleEnabledChange.bind(this);
|
||||
this._handleCurrentEngineChange = this._handleCurrentEngineChange.bind(this);
|
||||
|
||||
PlacesProvider.links.init();
|
||||
NewTabPrefsProvider.prefs.init();
|
||||
NewTabSearchProvider.search.init();
|
||||
NewTabWebChannel.init();
|
||||
|
||||
this._prefs.enabled = Preferences.get(PREF_ENABLED, false);
|
||||
|
||||
if (this._prefs.enabled) {
|
||||
for (let action of ACTIONS.inboundActions) {
|
||||
NewTabWebChannel.on(action, this.handleContentRequest);
|
||||
}
|
||||
|
||||
NewTabPrefsProvider.prefs.on(PREF_ENABLED, this._handleEnabledChange);
|
||||
NewTabSearchProvider.search.on(CURRENT_ENGINE, this._handleCurrentEngineChange);
|
||||
|
||||
for (let pref of NewTabPrefsProvider.newtabPagePrefSet) {
|
||||
NewTabPrefsProvider.prefs.on(pref, this.handlePrefChange);
|
||||
}
|
||||
|
||||
PlacesProvider.links.on("deleteURI", this.handlePlacesChange);
|
||||
PlacesProvider.links.on("clearHistory", this.handlePlacesChange);
|
||||
PlacesProvider.links.on("linkChanged", this.handlePlacesChange);
|
||||
PlacesProvider.links.on("manyLinksChanged", this.handlePlacesChange);
|
||||
}
|
||||
},
|
||||
|
||||
uninit() {
|
||||
this._prefs.enabled = Preferences.get(PREF_ENABLED, false);
|
||||
|
||||
if (this._prefs.enabled) {
|
||||
NewTabPrefsProvider.prefs.off(PREF_ENABLED, this._handleEnabledChange);
|
||||
NewTabSearchProvider.search.off(CURRENT_ENGINE, this._handleCurrentEngineChange);
|
||||
|
||||
for (let action of ACTIONS.inboundActions) {
|
||||
NewTabWebChannel.off(action, this.handleContentRequest);
|
||||
}
|
||||
|
||||
for (let pref of NewTabPrefsProvider.newtabPagePrefSet) {
|
||||
NewTabPrefsProvider.prefs.off(pref, this.handlePrefChange);
|
||||
}
|
||||
}
|
||||
|
||||
NewTabPrefsProvider.prefs.uninit();
|
||||
NewTabSearchProvider.search.uninit();
|
||||
NewTabWebChannel.uninit();
|
||||
}
|
||||
};
|
|
@ -1,244 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
/* global XPCOMUtils, Services, PlacesUtils, EventEmitter */
|
||||
/* global gLinks */
|
||||
/* exported PlacesProvider */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["PlacesProvider"];
|
||||
|
||||
const {interfaces: Ci, utils: Cu} = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
|
||||
const {EventEmitter} = Cu.import("resource://gre/modules/EventEmitter.jsm", {});
|
||||
return EventEmitter;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils",
|
||||
"resource://gre/modules/NewTabUtils.jsm");
|
||||
|
||||
// The maximum number of results PlacesProvider retrieves from history.
|
||||
const HISTORY_RESULTS_LIMIT = 100;
|
||||
|
||||
/* Queries history to retrieve the most visited sites. Emits events when the
|
||||
* history changes.
|
||||
* Implements the EventEmitter interface.
|
||||
*/
|
||||
let Links = function Links() {
|
||||
EventEmitter.decorate(this);
|
||||
};
|
||||
|
||||
Links.prototype = {
|
||||
/**
|
||||
* Set this to change the maximum number of links the provider will provide.
|
||||
*/
|
||||
get maxNumLinks() {
|
||||
// getter, so it can't be replaced dynamically
|
||||
return HISTORY_RESULTS_LIMIT;
|
||||
},
|
||||
|
||||
/**
|
||||
* A set of functions called by @mozilla.org/browser/nav-historyservice
|
||||
* All history events are emitted from this object.
|
||||
*/
|
||||
historyObserver: {
|
||||
_batchProcessingDepth: 0,
|
||||
_batchCalledFrecencyChanged: false,
|
||||
|
||||
/**
|
||||
* Called by the history service.
|
||||
*/
|
||||
onBeginUpdateBatch() {
|
||||
this._batchProcessingDepth += 1;
|
||||
},
|
||||
|
||||
onEndUpdateBatch() {
|
||||
this._batchProcessingDepth -= 1;
|
||||
if (this._batchProcessingDepth == 0 && this._batchCalledFrecencyChanged) {
|
||||
this.onManyFrecenciesChanged();
|
||||
this._batchCalledFrecencyChanged = false;
|
||||
}
|
||||
},
|
||||
|
||||
onDeleteURI: function historyObserver_onDeleteURI(aURI) {
|
||||
// let observers remove sensetive data associated with deleted visit
|
||||
gLinks.emit("deleteURI", {
|
||||
url: aURI.spec,
|
||||
});
|
||||
},
|
||||
|
||||
onClearHistory: function historyObserver_onClearHistory() {
|
||||
gLinks.emit("clearHistory");
|
||||
},
|
||||
|
||||
onFrecencyChanged: function historyObserver_onFrecencyChanged(aURI,
|
||||
aNewFrecency, aGUID, aHidden, aLastVisitDate) { // jshint ignore:line
|
||||
|
||||
// If something is doing a batch update of history entries we don't want
|
||||
// to do lots of work for each record. So we just track the fact we need
|
||||
// to call onManyFrecenciesChanged() once the batch is complete.
|
||||
if (this._batchProcessingDepth > 0) {
|
||||
this._batchCalledFrecencyChanged = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// The implementation of the query in getLinks excludes hidden and
|
||||
// unvisited pages, so it's important to exclude them here, too.
|
||||
if (!aHidden && aLastVisitDate &&
|
||||
NewTabUtils.linkChecker.checkLoadURI(aURI.spec)) {
|
||||
gLinks.emit("linkChanged", {
|
||||
url: aURI.spec,
|
||||
frecency: aNewFrecency,
|
||||
lastVisitDate: aLastVisitDate,
|
||||
type: "history",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onManyFrecenciesChanged: function historyObserver_onManyFrecenciesChanged() {
|
||||
// Called when frecencies are invalidated and also when clearHistory is called
|
||||
// See toolkit/components/places/tests/unit/test_frecency_observers.js
|
||||
gLinks.emit("manyLinksChanged");
|
||||
},
|
||||
|
||||
onVisit(aURI, aVisitId, aTime, aSessionId, aReferrerVisitId, aTransitionType,
|
||||
aGuid, aHidden, aVisitCount, aTyped, aLastKnownTitle) {
|
||||
// For new visits, if we're not batch processing, notify for a title update
|
||||
if (!this._batchProcessingDepth && aVisitCount == 1 && aLastKnownTitle) {
|
||||
this.onTitleChanged(aURI, aLastKnownTitle, aGuid);
|
||||
}
|
||||
},
|
||||
|
||||
onTitleChanged: function historyObserver_onTitleChanged(aURI, aNewTitle) {
|
||||
if (NewTabUtils.linkChecker.checkLoadURI(aURI.spec)) {
|
||||
gLinks.emit("linkChanged", {
|
||||
url: aURI.spec,
|
||||
title: aNewTitle
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver,
|
||||
Ci.nsISupportsWeakReference])
|
||||
},
|
||||
|
||||
/**
|
||||
* Must be called before the provider is used.
|
||||
* Makes it easy to disable under pref
|
||||
*/
|
||||
init: function PlacesProvider_init() {
|
||||
try {
|
||||
PlacesUtils.history.addObserver(this.historyObserver, true);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the current set of links delivered by this provider.
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the array of links as payload.
|
||||
*/
|
||||
getLinks: Task.async(function*() {
|
||||
// Select a single page per host with highest frecency, highest recency.
|
||||
// Choose N top such pages. Note +rev_host, to turn off optimizer per :mak
|
||||
// suggestion.
|
||||
let sqlQuery = `SELECT url, title, frecency,
|
||||
last_visit_date as lastVisitDate,
|
||||
"history" as type
|
||||
FROM moz_places
|
||||
WHERE frecency in (
|
||||
SELECT MAX(frecency) as frecency
|
||||
FROM moz_places
|
||||
WHERE hidden = 0 AND last_visit_date NOTNULL
|
||||
GROUP BY +rev_host
|
||||
ORDER BY frecency DESC
|
||||
LIMIT :limit
|
||||
)
|
||||
GROUP BY rev_host HAVING MAX(lastVisitDate)
|
||||
ORDER BY frecency DESC, lastVisitDate DESC, url`;
|
||||
|
||||
let links = yield this.executePlacesQuery(sqlQuery, {
|
||||
columns: ["url", "title", "lastVisitDate", "frecency", "type"],
|
||||
params: {limit: this.maxNumLinks}
|
||||
});
|
||||
|
||||
return links.filter(link => NewTabUtils.linkChecker.checkLoadURI(link.url));
|
||||
}),
|
||||
|
||||
/**
|
||||
* Executes arbitrary query against places database
|
||||
*
|
||||
* @param {String} aSql
|
||||
* SQL query to execute
|
||||
* @param {Object} [optional] aOptions
|
||||
* aOptions.columns - an array of column names. if supplied the returned
|
||||
* items will consist of objects keyed on column names. Otherwise
|
||||
* an array of raw values is returned in the select order
|
||||
* aOptions.param - an object of SQL binding parameters
|
||||
* aOptions.callback - a callback to handle query rows
|
||||
*
|
||||
* @returns {Promise} Returns a promise with the array of retrieved items
|
||||
*/
|
||||
executePlacesQuery: Task.async(function*(aSql, aOptions = {}) {
|
||||
let {columns, params, callback} = aOptions;
|
||||
let items = [];
|
||||
let queryError = null;
|
||||
let conn = yield PlacesUtils.promiseDBConnection();
|
||||
yield conn.executeCached(aSql, params, aRow => {
|
||||
try {
|
||||
// check if caller wants to handle query raws
|
||||
if (callback) {
|
||||
callback(aRow);
|
||||
} else {
|
||||
// otherwise fill in the item and add items array
|
||||
let item = null;
|
||||
// if columns array is given construct an object
|
||||
if (columns && Array.isArray(columns)) {
|
||||
item = {};
|
||||
columns.forEach(column => {
|
||||
item[column] = aRow.getResultByName(column);
|
||||
});
|
||||
} else {
|
||||
// if no columns - make an array of raw values
|
||||
item = [];
|
||||
for (let i = 0; i < aRow.numEntries; i++) {
|
||||
item.push(aRow.getResultByIndex(i));
|
||||
}
|
||||
}
|
||||
items.push(item);
|
||||
}
|
||||
} catch (e) {
|
||||
queryError = e;
|
||||
throw StopIteration;
|
||||
}
|
||||
});
|
||||
if (queryError) {
|
||||
throw new Error(queryError);
|
||||
}
|
||||
return items;
|
||||
}),
|
||||
};
|
||||
|
||||
/**
|
||||
* Singleton that serves as the default link provider for the grid.
|
||||
*/
|
||||
const gLinks = new Links(); // jshint ignore:line
|
||||
|
||||
let PlacesProvider = {
|
||||
links: gLinks,
|
||||
};
|
||||
|
||||
// Kept only for backwards-compatibility
|
||||
XPCOMUtils.defineLazyGetter(PlacesProvider, "LinkChecker",
|
||||
() => NewTabUtils.linkChecker);
|
|
@ -14,13 +14,11 @@ XPCSHELL_TESTS_MANIFESTS += [
|
|||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'NewTabMessages.jsm',
|
||||
'NewTabPrefsProvider.jsm',
|
||||
'NewTabRemoteResources.jsm',
|
||||
'NewTabSearchProvider.jsm',
|
||||
'NewTabURL.jsm',
|
||||
'NewTabWebChannel.jsm',
|
||||
'PlacesProvider.jsm',
|
||||
'PreviewProvider.jsm'
|
||||
]
|
||||
|
||||
|
|
|
@ -1,357 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
/* global XPCOMUtils, PlacesUtils, PlacesTestUtils, PlacesProvider, NetUtil */
|
||||
/* global do_get_profile, run_next_test, add_task */
|
||||
/* global equal, ok */
|
||||
|
||||
const {
|
||||
utils: Cu,
|
||||
interfaces: Ci,
|
||||
} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesProvider",
|
||||
"resource:///modules/PlacesProvider.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
|
||||
"resource://testing-common/PlacesTestUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
// ensure a profile exists
|
||||
do_get_profile();
|
||||
|
||||
function run_test() {
|
||||
PlacesProvider.links.init();
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
// url prefix for test history population
|
||||
const TEST_URL = "https://mozilla.com/";
|
||||
// time when the test starts execution
|
||||
const TIME_NOW = new Date();
|
||||
|
||||
// utility function to compute past timestap
|
||||
function timeDaysAgo(numDays) {
|
||||
return new Date(TIME_NOW - (numDays * 24 * 60 * 60 * 1000));
|
||||
}
|
||||
|
||||
// utility function to make a visit for insetion into places db
|
||||
function makeVisit(index, daysAgo, isTyped, domain = TEST_URL) {
|
||||
let {
|
||||
TRANSITION_TYPED,
|
||||
TRANSITION_LINK
|
||||
} = PlacesUtils.history;
|
||||
|
||||
return {
|
||||
uri: NetUtil.newURI(`${domain}${index}`),
|
||||
visitDate: timeDaysAgo(daysAgo),
|
||||
transition: (isTyped) ? TRANSITION_TYPED : TRANSITION_LINK,
|
||||
};
|
||||
}
|
||||
|
||||
/** Test LinkChecker **/
|
||||
|
||||
add_task(function test_LinkChecker_securityCheck() {
|
||||
|
||||
let urls = [
|
||||
{url: "javascript:alert('hello')", expected: false}, // jshint ignore:line
|
||||
{url: "data:image/png;base64,XXX", expected: false},
|
||||
{url: "about:newtab", expected: true},
|
||||
{url: "https://example.com", expected: true},
|
||||
{url: "ftp://example.com", expected: true},
|
||||
{url: "file://home/file/image.png", expected: true},
|
||||
{url: "resource:///modules/PlacesProvider.jsm", expected: true},
|
||||
];
|
||||
for (let {url, expected} of urls) {
|
||||
let observed = PlacesProvider.LinkChecker.checkLoadURI(url);
|
||||
equal(observed, expected, `can load "${url}"?`);
|
||||
}
|
||||
});
|
||||
|
||||
/** Test Provider **/
|
||||
|
||||
add_task(function* test_Links_getLinks() {
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
let provider = PlacesProvider.links;
|
||||
|
||||
let links = yield provider.getLinks();
|
||||
equal(links.length, 0, "empty history yields empty links");
|
||||
|
||||
// add a visit
|
||||
let testURI = NetUtil.newURI("http://mozilla.com");
|
||||
yield PlacesTestUtils.addVisits(testURI);
|
||||
|
||||
links = yield provider.getLinks();
|
||||
equal(links.length, 1, "adding a visit yields a link");
|
||||
equal(links[0].url, testURI.spec, "added visit corresponds to added url");
|
||||
});
|
||||
|
||||
add_task(function* test_Links_getLinks_Order() {
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
let provider = PlacesProvider.links;
|
||||
|
||||
// all four visits must come from different domains to avoid deduplication
|
||||
let visits = [
|
||||
makeVisit(0, 0, true, "http://bar.com/"), // frecency 200, today
|
||||
makeVisit(1, 0, true, "http://foo.com/"), // frecency 200, today
|
||||
makeVisit(2, 2, true, "http://buz.com/"), // frecency 200, 2 days ago
|
||||
makeVisit(3, 2, false, "http://aaa.com/"), // frecency 10, 2 days ago, transition
|
||||
];
|
||||
|
||||
let links = yield provider.getLinks();
|
||||
equal(links.length, 0, "empty history yields empty links");
|
||||
yield PlacesTestUtils.addVisits(visits);
|
||||
|
||||
links = yield provider.getLinks();
|
||||
equal(links.length, visits.length, "number of links added is the same as obtain by getLinks");
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
equal(links[i].url, visits[i].uri.spec, "links are obtained in the expected order");
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_Links_getLinks_Deduplication() {
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
let provider = PlacesProvider.links;
|
||||
|
||||
// all for visits must come from different domains to avoid deduplication
|
||||
let visits = [
|
||||
makeVisit(0, 2, true, "http://bar.com/"), // frecency 200, 2 days ago
|
||||
makeVisit(1, 0, true, "http://bar.com/"), // frecency 200, today
|
||||
makeVisit(2, 0, false, "http://foo.com/"), // frecency 10, today
|
||||
makeVisit(3, 0, true, "http://foo.com/"), // frecency 200, today
|
||||
];
|
||||
|
||||
let links = yield provider.getLinks();
|
||||
equal(links.length, 0, "empty history yields empty links");
|
||||
yield PlacesTestUtils.addVisits(visits);
|
||||
|
||||
links = yield provider.getLinks();
|
||||
equal(links.length, 2, "only two links must be left after deduplication");
|
||||
equal(links[0].url, visits[1].uri.spec, "earliest link is present");
|
||||
equal(links[1].url, visits[3].uri.spec, "most fresent link is present");
|
||||
});
|
||||
|
||||
add_task(function* test_Links_onLinkChanged() {
|
||||
let provider = PlacesProvider.links;
|
||||
|
||||
let url = "https://example.com/onFrecencyChanged1";
|
||||
let linkChangedMsgCount = 0;
|
||||
|
||||
let linkChangedPromise = new Promise(resolve => {
|
||||
let handler = (_, link) => { // jshint ignore:line
|
||||
/* There are 2 linkChanged events:
|
||||
* 1. visit insertion (-1 frecency by default)
|
||||
* 2. frecency score update (after transition type calculation etc)
|
||||
*/
|
||||
if (link.url === url) {
|
||||
equal(link.url, url, `expected url on linkChanged event`);
|
||||
linkChangedMsgCount += 1;
|
||||
if (linkChangedMsgCount === 2) {
|
||||
ok(true, `all linkChanged events captured`);
|
||||
provider.off("linkChanged", this);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
};
|
||||
provider.on("linkChanged", handler);
|
||||
});
|
||||
|
||||
// add a visit
|
||||
let testURI = NetUtil.newURI(url);
|
||||
yield PlacesUtils.history.insert({
|
||||
url: testURI,
|
||||
visits: [{ transition: PlacesUtils.history.TRANSITIONS.LINK }]
|
||||
});
|
||||
yield linkChangedPromise;
|
||||
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
||||
|
||||
add_task(function* test_Links_onClearHistory() {
|
||||
let provider = PlacesProvider.links;
|
||||
|
||||
let clearHistoryPromise = new Promise(resolve => {
|
||||
let handler = () => {
|
||||
ok(true, `clearHistory event captured`);
|
||||
provider.off("clearHistory", handler);
|
||||
resolve();
|
||||
};
|
||||
provider.on("clearHistory", handler);
|
||||
});
|
||||
|
||||
// add visits
|
||||
for (let i = 0; i <= 10; i++) {
|
||||
let url = `https://example.com/onClearHistory${i}`;
|
||||
let testURI = NetUtil.newURI(url);
|
||||
yield PlacesTestUtils.addVisits(testURI);
|
||||
}
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
yield clearHistoryPromise;
|
||||
});
|
||||
|
||||
add_task(function* test_Links_onDeleteURI() {
|
||||
let provider = PlacesProvider.links;
|
||||
|
||||
let testURL = "https://example.com/toDelete";
|
||||
|
||||
let deleteURIPromise = new Promise(resolve => {
|
||||
let handler = (_, {url}) => { // jshint ignore:line
|
||||
equal(testURL, url, "deleted url and expected url are the same");
|
||||
provider.off("deleteURI", handler);
|
||||
resolve();
|
||||
};
|
||||
|
||||
provider.on("deleteURI", handler);
|
||||
});
|
||||
|
||||
let testURI = NetUtil.newURI(testURL);
|
||||
yield PlacesTestUtils.addVisits(testURI);
|
||||
yield PlacesUtils.history.remove(testURL);
|
||||
yield deleteURIPromise;
|
||||
});
|
||||
|
||||
add_task(function* test_Links_onManyLinksChanged() {
|
||||
let provider = PlacesProvider.links;
|
||||
|
||||
let promise = new Promise(resolve => {
|
||||
let handler = () => {
|
||||
ok(true);
|
||||
provider.off("manyLinksChanged", handler);
|
||||
resolve();
|
||||
};
|
||||
|
||||
provider.on("manyLinksChanged", handler);
|
||||
});
|
||||
|
||||
let testURL = "https://example.com/toDelete";
|
||||
let testURI = NetUtil.newURI(testURL);
|
||||
yield PlacesTestUtils.addVisits(testURI);
|
||||
|
||||
// trigger DecayFrecency
|
||||
PlacesUtils.history.QueryInterface(Ci.nsIObserver).
|
||||
observe(null, "idle-daily", "");
|
||||
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* test_Links_execute_query() {
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
let provider = PlacesProvider.links;
|
||||
|
||||
let visits = [
|
||||
makeVisit(0, 0, true), // frecency 200, today
|
||||
makeVisit(1, 0, true), // frecency 200, today
|
||||
makeVisit(2, 2, true), // frecency 200, 2 days ago
|
||||
makeVisit(3, 2, false), // frecency 10, 2 days ago, transition
|
||||
];
|
||||
|
||||
yield PlacesTestUtils.addVisits(visits);
|
||||
|
||||
function testItemValue(results, index, value) {
|
||||
equal(results[index][0], `${TEST_URL}${value}`, "raw url");
|
||||
equal(results[index][1], `test visit for ${TEST_URL}${value}`, "raw title");
|
||||
}
|
||||
|
||||
function testItemObject(results, index, columnValues) {
|
||||
Object.keys(columnValues).forEach(name => {
|
||||
equal(results[index][name], columnValues[name], "object name " + name);
|
||||
});
|
||||
}
|
||||
|
||||
// select all 4 records
|
||||
let results = yield provider.executePlacesQuery("select url, title from moz_places");
|
||||
equal(results.length, 4, "expect 4 items");
|
||||
// check for insert order sequence
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
testItemValue(results, i, i);
|
||||
}
|
||||
|
||||
// test parameter passing
|
||||
results = yield provider.executePlacesQuery(
|
||||
"select url, title from moz_places limit :limit",
|
||||
{params: {limit: 2}}
|
||||
);
|
||||
equal(results.length, 2, "expect 2 items");
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
testItemValue(results, i, i);
|
||||
}
|
||||
|
||||
// test extracting items by name
|
||||
results = yield provider.executePlacesQuery(
|
||||
"select url, title from moz_places limit :limit",
|
||||
{columns: ["url", "title"], params: {limit: 4}}
|
||||
);
|
||||
equal(results.length, 4, "expect 4 items");
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
testItemObject(results, i, {
|
||||
"url": `${TEST_URL}${i}`,
|
||||
"title": `test visit for ${TEST_URL}${i}`,
|
||||
});
|
||||
}
|
||||
|
||||
// test ordering
|
||||
results = yield provider.executePlacesQuery(
|
||||
"select url, title, last_visit_date, frecency from moz_places " +
|
||||
"order by frecency DESC, last_visit_date DESC, url DESC limit :limit",
|
||||
{columns: ["url", "title", "last_visit_date", "frecency"], params: {limit: 4}}
|
||||
);
|
||||
equal(results.length, 4, "expect 4 items");
|
||||
testItemObject(results, 0, {url: `${TEST_URL}1`});
|
||||
testItemObject(results, 1, {url: `${TEST_URL}0`});
|
||||
testItemObject(results, 2, {url: `${TEST_URL}2`});
|
||||
testItemObject(results, 3, {url: `${TEST_URL}3`});
|
||||
|
||||
// test callback passing
|
||||
results = [];
|
||||
function handleRow(aRow) {
|
||||
results.push({
|
||||
url: aRow.getResultByName("url"),
|
||||
title: aRow.getResultByName("title"),
|
||||
last_visit_date: aRow.getResultByName("last_visit_date"),
|
||||
frecency: aRow.getResultByName("frecency")
|
||||
});
|
||||
}
|
||||
yield provider.executePlacesQuery(
|
||||
"select url, title, last_visit_date, frecency from moz_places " +
|
||||
"order by frecency DESC, last_visit_date DESC, url DESC",
|
||||
{callback: handleRow}
|
||||
);
|
||||
equal(results.length, 4, "expect 4 items");
|
||||
testItemObject(results, 0, {url: `${TEST_URL}1`});
|
||||
testItemObject(results, 1, {url: `${TEST_URL}0`});
|
||||
testItemObject(results, 2, {url: `${TEST_URL}2`});
|
||||
testItemObject(results, 3, {url: `${TEST_URL}3`});
|
||||
|
||||
// negative test cases
|
||||
// bad sql
|
||||
try {
|
||||
yield provider.executePlacesQuery("select from moz");
|
||||
do_throw("bad sql should've thrown");
|
||||
} catch (e) {
|
||||
do_check_true("expected failure - bad sql");
|
||||
}
|
||||
// missing bindings
|
||||
try {
|
||||
yield provider.executePlacesQuery("select * from moz_places limit :limit");
|
||||
do_throw("bad sql should've thrown");
|
||||
} catch (e) {
|
||||
do_check_true("expected failure - missing bidning");
|
||||
}
|
||||
// non-existent column name
|
||||
try {
|
||||
yield provider.executePlacesQuery("select * from moz_places limit :limit",
|
||||
{columns: ["no-such-column"], params: {limit: 4}});
|
||||
do_throw("bad sql should've thrown");
|
||||
} catch (e) {
|
||||
do_check_true("expected failure - wrong column name");
|
||||
}
|
||||
|
||||
// cleanup
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
|
@ -7,4 +7,3 @@ skip-if = toolkit == 'android'
|
|||
[test_NewTabPrefsProvider.js]
|
||||
[test_NewTabSearchProvider.js]
|
||||
[test_NewTabURL.js]
|
||||
[test_PlacesProvider.js]
|
||||
|
|
|
@ -27,7 +27,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "AlertsService", "@mozilla.org/alerts-s
|
|||
ExtensionsUI:false, Feeds:false,
|
||||
FileUtils:false, FormValidationHandler:false, Integration:false,
|
||||
LightweightThemeManager:false, LoginHelper:false, LoginManagerParent:false,
|
||||
NetUtil:false, NewTabMessages:false, NewTabUtils:false, OS:false,
|
||||
NetUtil:false, NewTabUtils:false, OS:false,
|
||||
PageThumbs:false, PdfJs:false, PermissionUI:false, PlacesBackups:false,
|
||||
PlacesUtils:false, PluralForm:false, PrivateBrowsingUtils:false,
|
||||
ProcessHangMonitor:false, ReaderParent:false, RecentWindow:false,
|
||||
|
@ -65,7 +65,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "AlertsService", "@mozilla.org/alerts-s
|
|||
["LoginHelper", "resource://gre/modules/LoginHelper.jsm"],
|
||||
["LoginManagerParent", "resource://gre/modules/LoginManagerParent.jsm"],
|
||||
["NetUtil", "resource://gre/modules/NetUtil.jsm"],
|
||||
["NewTabMessages", "resource:///modules/NewTabMessages.jsm"],
|
||||
["NewTabUtils", "resource://gre/modules/NewTabUtils.jsm"],
|
||||
["OS", "resource://gre/modules/osfile.jsm"],
|
||||
["PageThumbs", "resource://gre/modules/PageThumbs.jsm"],
|
||||
|
@ -509,8 +508,6 @@ BrowserGlue.prototype = {
|
|||
NewTabUtils.links.addProvider(DirectoryLinksProvider);
|
||||
AboutNewTab.init();
|
||||
|
||||
NewTabMessages.init();
|
||||
|
||||
SessionStore.init();
|
||||
BrowserUsageTelemetry.init();
|
||||
BrowserUITelemetry.init();
|
||||
|
@ -896,8 +893,8 @@ BrowserGlue.prototype = {
|
|||
BrowserUsageTelemetry.uninit();
|
||||
SelfSupportBackend.uninit();
|
||||
PageThumbs.uninit();
|
||||
NewTabMessages.uninit();
|
||||
AboutNewTab.uninit();
|
||||
NewTabUtils.uninit();
|
||||
webrtcUI.uninit();
|
||||
FormValidationHandler.uninit();
|
||||
AutoCompletePopup.uninit();
|
||||
|
|
|
@ -16,7 +16,8 @@ function searchBookmarks(aSearchString) {
|
|||
tree.applyFilter(aSearchString,
|
||||
[PlacesUtils.bookmarksMenuFolderId,
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.toolbarFolderId]);
|
||||
PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils.mobileFolderId]);
|
||||
}
|
||||
|
||||
window.addEventListener("SidebarFocused",
|
||||
|
|
|
@ -757,7 +757,8 @@ var PlacesSearchBox = {
|
|||
if (this._folders.length == 0) {
|
||||
this._folders.push(PlacesUtils.bookmarksMenuFolderId,
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.toolbarFolderId);
|
||||
PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils.mobileFolderId);
|
||||
}
|
||||
return this._folders;
|
||||
},
|
||||
|
@ -943,7 +944,8 @@ var PlacesQueryBuilder = {
|
|||
filterCollection = "bookmarks";
|
||||
folders.push(PlacesUtils.bookmarksMenuFolderId,
|
||||
PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils.unfiledBookmarksFolderId);
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.mobileFolderId);
|
||||
break;
|
||||
case "downloads":
|
||||
filterCollection = "downloads";
|
||||
|
|
|
@ -52,11 +52,11 @@
|
|||
<!-- Update -->
|
||||
<groupbox id="updateApp" data-category="paneAdvanced" hidden="true">
|
||||
<caption><label>&updateApplication.label;</label></caption>
|
||||
#ifdef MOZ_UPDATER
|
||||
<description>&updateApplication.description;</description>
|
||||
<hbox align="start">
|
||||
<vbox flex="1">
|
||||
#ifdef MOZ_UPDATER
|
||||
<radiogroup id="updateRadioGroup" align="start">
|
||||
<radiogroup id="updateRadioGroup">
|
||||
<radio id="autoDesktop"
|
||||
value="auto"
|
||||
label="&updateAuto2.label;"
|
||||
|
@ -68,19 +68,7 @@
|
|||
label="&updateManual2.label;"
|
||||
accesskey="&updateManual2.accesskey;"/>
|
||||
</radiogroup>
|
||||
#ifdef MOZ_MAINTENANCE_SERVICE
|
||||
<checkbox id="useService"
|
||||
label="&useService.label;"
|
||||
accesskey="&useService.accesskey;"
|
||||
preference="app.update.service.enabled"/>
|
||||
#endif
|
||||
#endif
|
||||
<checkbox id="enableSearchUpdate"
|
||||
label="&enableSearchUpdate2.label;"
|
||||
accesskey="&enableSearchUpdate2.accesskey;"
|
||||
preference="browser.search.update"/>
|
||||
</vbox>
|
||||
#ifdef MOZ_UPDATER
|
||||
<spacer flex="1"/>
|
||||
<vbox>
|
||||
<button id="showUpdateHistory"
|
||||
|
@ -89,6 +77,16 @@
|
|||
accesskey="&updateHistory2.accesskey;"
|
||||
preference="app.update.disable_button.showUpdateHistory"/>
|
||||
</vbox>
|
||||
#endif
|
||||
</hbox>
|
||||
#ifdef MOZ_MAINTENANCE_SERVICE
|
||||
<checkbox id="useService"
|
||||
label="&useService.label;"
|
||||
accesskey="&useService.accesskey;"
|
||||
preference="app.update.service.enabled"/>
|
||||
#endif
|
||||
#endif
|
||||
<checkbox id="enableSearchUpdate"
|
||||
label="&enableSearchUpdate2.label;"
|
||||
accesskey="&enableSearchUpdate2.accesskey;"
|
||||
preference="browser.search.update"/>
|
||||
</groupbox>
|
||||
|
|
|
@ -100,12 +100,10 @@
|
|||
#endif
|
||||
/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<radio id="alwaysAsk"
|
||||
value="false"
|
||||
label="&alwaysAskWhere.label;"
|
||||
accesskey="&alwaysAskWhere.accesskey;"/>
|
||||
</hbox>
|
||||
<radio id="alwaysAsk"
|
||||
value="false"
|
||||
label="&alwaysAskWhere.label;"
|
||||
accesskey="&alwaysAskWhere.accesskey;"/>
|
||||
</radiogroup>
|
||||
</groupbox>
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ var gMainPane = {
|
|||
document.getElementById("engineList").view = gEngineView;
|
||||
this.buildDefaultEngineDropDown();
|
||||
|
||||
this.buildContentProcessCountMenuList();
|
||||
|
||||
let addEnginesLink = document.getElementById("addEngines");
|
||||
let searchEnginesURL = Services.wm.getMostRecentWindow("navigator:browser")
|
||||
.BrowserSearch.searchEnginesURL;
|
||||
|
@ -91,6 +93,25 @@ var gMainPane = {
|
|||
});
|
||||
this.updateSuggestsCheckbox();
|
||||
|
||||
let processCountPref =
|
||||
document.getElementById("dom.ipc.processCount");
|
||||
processCountPref.addEventListener("change", () => {
|
||||
this.updateDefaultPerformanceSettingsPref();
|
||||
});
|
||||
let accelerationPref =
|
||||
document.getElementById("layers.acceleration.disabled");
|
||||
accelerationPref.addEventListener("change", () => {
|
||||
this.updateDefaultPerformanceSettingsPref();
|
||||
});
|
||||
this.updateDefaultPerformanceSettingsPref();
|
||||
|
||||
let defaultPerformancePref =
|
||||
document.getElementById("browser.preferences.defaultPerformanceSettings.enabled");
|
||||
defaultPerformancePref.addEventListener("change", () => {
|
||||
this.updatePerformanceSettingsBox();
|
||||
});
|
||||
this.updatePerformanceSettingsBox();
|
||||
|
||||
// set up the "use current page" label-changing listener
|
||||
this._updateUseCurrentButton();
|
||||
window.addEventListener("focus", this._updateUseCurrentButton.bind(this));
|
||||
|
@ -792,6 +813,43 @@ var gMainPane = {
|
|||
permanentPBLabel.hidden = urlbarSuggests.hidden || !permanentPB;
|
||||
},
|
||||
|
||||
updateDefaultPerformanceSettingsPref() {
|
||||
let defaultPerformancePref =
|
||||
document.getElementById("browser.preferences.defaultPerformanceSettings.enabled");
|
||||
let processCountPref = document.getElementById("dom.ipc.processCount");
|
||||
let accelerationPref = document.getElementById("layers.acceleration.disabled");
|
||||
if (processCountPref.value != processCountPref.defaultValue ||
|
||||
accelerationPref.value != accelerationPref.defaultValue) {
|
||||
defaultPerformancePref.value = false;
|
||||
}
|
||||
},
|
||||
|
||||
updatePerformanceSettingsBox() {
|
||||
let defaultPerformancePref =
|
||||
document.getElementById("browser.preferences.defaultPerformanceSettings.enabled");
|
||||
let performanceSettings = document.getElementById("performanceSettings");
|
||||
if (defaultPerformancePref.value) {
|
||||
let processCountPref = document.getElementById("dom.ipc.processCount");
|
||||
let accelerationPref = document.getElementById("layers.acceleration.disabled");
|
||||
processCountPref.value = processCountPref.defaultValue;
|
||||
accelerationPref.value = accelerationPref.defaultValue;
|
||||
performanceSettings.hidden = true;
|
||||
} else {
|
||||
performanceSettings.hidden = false;
|
||||
}
|
||||
},
|
||||
|
||||
buildContentProcessCountMenuList() {
|
||||
let processCountPref = document.getElementById("dom.ipc.processCount");
|
||||
let bundlePreferences = document.getElementById("bundlePreferences");
|
||||
let label = bundlePreferences.getFormattedString("defaultContentProcessCount",
|
||||
[processCountPref.defaultValue]);
|
||||
let contentProcessCount =
|
||||
document.querySelector(`#contentProcessCount > menupopup >
|
||||
menuitem[value="${processCountPref.defaultValue}"]`);
|
||||
contentProcessCount.label = label;
|
||||
},
|
||||
|
||||
buildDefaultEngineDropDown() {
|
||||
// This is called each time something affects the list of engines.
|
||||
let list = document.getElementById("defaultEngine");
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
<stringbundle id="engineManagerBundle" src="chrome://browser/locale/engineManager.properties"/>
|
||||
|
||||
<stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences.properties"/>
|
||||
|
||||
<preferences id="mainPreferences" hidden="true" data-category="paneGeneral">
|
||||
|
||||
#ifdef E10S_TESTING_ONLY
|
||||
|
@ -177,10 +179,6 @@
|
|||
<preference id="general.smoothScroll"
|
||||
name="general.smoothScroll"
|
||||
type="bool"/>
|
||||
<preference id="layers.acceleration.disabled"
|
||||
name="layers.acceleration.disabled"
|
||||
type="bool"
|
||||
inverted="true"/>
|
||||
#ifdef XP_WIN
|
||||
<preference id="gfx.direct2d.disabled"
|
||||
name="gfx.direct2d.disabled"
|
||||
|
@ -196,6 +194,19 @@
|
|||
name="toolkit.telemetry.enabled"
|
||||
type="bool"/>
|
||||
#endif
|
||||
|
||||
<preference id="browser.preferences.defaultPerformanceSettings.enabled"
|
||||
name="browser.preferences.defaultPerformanceSettings.enabled"
|
||||
type="bool"/>
|
||||
|
||||
<preference id="dom.ipc.processCount"
|
||||
name="dom.ipc.processCount"
|
||||
type="int"/>
|
||||
|
||||
<preference id="layers.acceleration.disabled"
|
||||
name="layers.acceleration.disabled"
|
||||
type="bool"
|
||||
inverted="true"/>
|
||||
</preferences>
|
||||
|
||||
<hbox id="header-general"
|
||||
|
@ -232,10 +243,8 @@
|
|||
|
||||
#ifdef HAVE_SHELL_SERVICE
|
||||
<vbox id="defaultBrowserBox">
|
||||
<hbox align="center">
|
||||
<checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser"
|
||||
label="&alwaysCheckDefault2.label;" accesskey="&alwaysCheckDefault2.accesskey;"/>
|
||||
</hbox>
|
||||
<checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser"
|
||||
label="&alwaysCheckDefault2.label;" accesskey="&alwaysCheckDefault2.accesskey;"/>
|
||||
<deck id="setDefaultPane">
|
||||
<hbox align="center" class="indent">
|
||||
<label id="isNotDefaultLabel" flex="1">&isNotDefault.label;</label>
|
||||
|
@ -318,12 +327,14 @@
|
|||
</groupbox>
|
||||
|
||||
<!-- Default Search Engine -->
|
||||
<groupbox id="defaultEngineGroup" align="start" data-category="paneGeneral" data-subcategory="search">
|
||||
<groupbox id="defaultEngineGroup" data-category="paneGeneral" data-subcategory="search">
|
||||
<caption label="&defaultSearchEngine.label;"/>
|
||||
<label>&chooseYourDefaultSearchEngine.label;</label>
|
||||
<menulist id="defaultEngine">
|
||||
<menupopup/>
|
||||
</menulist>
|
||||
<box align="start">
|
||||
<menulist id="defaultEngine">
|
||||
<menupopup/>
|
||||
</menulist>
|
||||
</box>
|
||||
<checkbox id="suggestionsInSearchFieldsCheckbox"
|
||||
label="&provideSearchSuggestions.label;"
|
||||
accesskey="&provideSearchSuggestions.accesskey;"
|
||||
|
@ -375,7 +386,7 @@
|
|||
|
||||
<!-- Tab preferences -->
|
||||
<groupbox data-category="paneGeneral"
|
||||
hidden="true" align="start">
|
||||
hidden="true">
|
||||
<caption><label>&tabsGroup.label;</label></caption>
|
||||
|
||||
<checkbox id="ctrlTabRecentlyUsedOrder" label="&ctrlTabRecentlyUsedOrder.label;"
|
||||
|
@ -408,7 +419,7 @@
|
|||
</groupbox>
|
||||
|
||||
<!-- Accessibility -->
|
||||
<groupbox data-category="paneGeneral" id="accessibilityGroup" align="start">
|
||||
<groupbox data-category="paneGeneral" id="accessibilityGroup">
|
||||
<caption><label>&accessibility.label;</label></caption>
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
@ -464,14 +475,12 @@
|
|||
label="&translateExceptions.label;"
|
||||
accesskey="&translateExceptions.accesskey;"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<checkbox id="checkSpelling"
|
||||
label="&checkUserSpelling.label;"
|
||||
accesskey="&checkUserSpelling.accesskey;"
|
||||
onsyncfrompreference="return gMainPane.readCheckSpelling();"
|
||||
onsynctopreference="return gMainPane.writeCheckSpelling();"
|
||||
preference="layout.spellcheckDefault"/>
|
||||
</hbox>
|
||||
<checkbox id="checkSpelling"
|
||||
label="&checkUserSpelling.label;"
|
||||
accesskey="&checkUserSpelling.accesskey;"
|
||||
onsyncfrompreference="return gMainPane.readCheckSpelling();"
|
||||
onsynctopreference="return gMainPane.writeCheckSpelling();"
|
||||
preference="layout.spellcheckDefault"/>
|
||||
</groupbox>
|
||||
|
||||
|
||||
|
@ -539,7 +548,7 @@
|
|||
</groupbox>
|
||||
|
||||
<!-- Browsing -->
|
||||
<groupbox id="browsingGroup" align="start" data-category="paneGeneral">
|
||||
<groupbox id="browsingGroup" data-category="paneGeneral">
|
||||
<caption><label>&browsing.label;</label></caption>
|
||||
|
||||
<checkbox id="useAutoScroll"
|
||||
|
@ -550,8 +559,37 @@
|
|||
label="&useSmoothScrolling.label;"
|
||||
accesskey="&useSmoothScrolling.accesskey;"
|
||||
preference="general.smoothScroll"/>
|
||||
<checkbox id="allowHWAccel"
|
||||
label="&allowHWAccel.label;"
|
||||
accesskey="&allowHWAccel.accesskey;"
|
||||
preference="layers.acceleration.disabled"/>
|
||||
</groupbox>
|
||||
|
||||
<!-- Performance -->
|
||||
<groupbox id="performanceGroup" data-category="paneGeneral" hidden="true">
|
||||
<caption><label>&performance.label;</label></caption>
|
||||
|
||||
<checkbox id="useRecommendedPerformanceSettings"
|
||||
label="&useRecommendedPerformanceSettings.label;"
|
||||
accesskey="&useRecommendedPerformanceSettings.accesskey;"
|
||||
preference="browser.preferences.defaultPerformanceSettings.enabled"/>
|
||||
<description class="indent">&useRecommendedPerformanceSettings.description;</description>
|
||||
|
||||
<vbox id="performanceSettings" class="indent" hidden="true">
|
||||
<checkbox id="allowHWAccel"
|
||||
label="&allowHWAccel.label;"
|
||||
accesskey="&allowHWAccel.accesskey;"
|
||||
preference="layers.acceleration.disabled"/>
|
||||
<hbox align="center">
|
||||
<label id="limitContentProcess" accesskey="&limitContentProcess.accesskey;" control="contentProcessCount">&limitContentProcess.label;</label>
|
||||
<menulist id="contentProcessCount" preference="dom.ipc.processCount">
|
||||
<menupopup>
|
||||
<menuitem label="1" value="1"/>
|
||||
<menuitem label="2" value="2"/>
|
||||
<menuitem label="3" value="3"/>
|
||||
<menuitem label="4" value="4"/>
|
||||
<menuitem label="5" value="5"/>
|
||||
<menuitem label="6" value="6"/>
|
||||
<menuitem label="7" value="7"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
<description>&limitContentProcess.description;</description>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
|
|
|
@ -239,9 +239,9 @@ var gPrivacyPane = {
|
|||
gPrivacyPane.toggleDoNotDisturbNotifications);
|
||||
|
||||
if (AlertsServiceDND) {
|
||||
let notificationsDoNotDisturbRow =
|
||||
document.getElementById("notificationsDoNotDisturbRow");
|
||||
notificationsDoNotDisturbRow.removeAttribute("hidden");
|
||||
let notificationsDoNotDisturbBox =
|
||||
document.getElementById("notificationsDoNotDisturbBox");
|
||||
notificationsDoNotDisturbBox.removeAttribute("hidden");
|
||||
if (AlertsServiceDND.manualDoNotDisturb) {
|
||||
let notificationsDoNotDisturb =
|
||||
document.getElementById("notificationsDoNotDisturb");
|
||||
|
|
|
@ -225,30 +225,26 @@
|
|||
<vbox id="historyCustomPane">
|
||||
<separator class="thin"/>
|
||||
<vbox>
|
||||
<vbox align="start">
|
||||
<checkbox id="privateBrowsingAutoStart"
|
||||
label="&privateBrowsingPermanent2.label;"
|
||||
accesskey="&privateBrowsingPermanent2.accesskey;"
|
||||
preference="browser.privatebrowsing.autostart"/>
|
||||
</vbox>
|
||||
<checkbox id="privateBrowsingAutoStart"
|
||||
label="&privateBrowsingPermanent2.label;"
|
||||
accesskey="&privateBrowsingPermanent2.accesskey;"
|
||||
preference="browser.privatebrowsing.autostart"/>
|
||||
<vbox class="indent">
|
||||
<vbox align="start">
|
||||
<checkbox id="rememberHistory"
|
||||
label="&rememberHistory2.label;"
|
||||
accesskey="&rememberHistory2.accesskey;"
|
||||
preference="places.history.enabled"/>
|
||||
<checkbox id="rememberForms"
|
||||
label="&rememberSearchForm.label;"
|
||||
accesskey="&rememberSearchForm.accesskey;"
|
||||
preference="browser.formfill.enable"/>
|
||||
</vbox>
|
||||
<checkbox id="rememberHistory"
|
||||
label="&rememberHistory2.label;"
|
||||
accesskey="&rememberHistory2.accesskey;"
|
||||
preference="places.history.enabled"/>
|
||||
<checkbox id="rememberForms"
|
||||
label="&rememberSearchForm.label;"
|
||||
accesskey="&rememberSearchForm.accesskey;"
|
||||
preference="browser.formfill.enable"/>
|
||||
<hbox id="cookiesBox">
|
||||
<checkbox id="acceptCookies" label="&acceptCookies.label;"
|
||||
preference="network.cookie.cookieBehavior"
|
||||
accesskey="&acceptCookies.accesskey;"
|
||||
onsyncfrompreference="return gPrivacyPane.readAcceptCookies();"
|
||||
onsynctopreference="return gPrivacyPane.writeAcceptCookies();"/>
|
||||
<spacer flex="1" />
|
||||
onsynctopreference="return gPrivacyPane.writeAcceptCookies();"
|
||||
flex="1" />
|
||||
<button id="cookieExceptions"
|
||||
class="accessory-button"
|
||||
label="&cookieExceptions.label;" accesskey="&cookieExceptions.accesskey;"
|
||||
|
@ -293,8 +289,8 @@
|
|||
<checkbox id="alwaysClear"
|
||||
preference="privacy.sanitize.sanitizeOnShutdown"
|
||||
label="&clearOnClose.label;"
|
||||
accesskey="&clearOnClose.accesskey;"/>
|
||||
<spacer flex="1"/>
|
||||
accesskey="&clearOnClose.accesskey;"
|
||||
flex="1" />
|
||||
<button id="clearDataSettings"
|
||||
class="accessory-button"
|
||||
label="&clearOnCloseSettings.label;"
|
||||
|
@ -314,8 +310,8 @@
|
|||
<checkbox id="savePasswords"
|
||||
label="&rememberLogins1.label;" accesskey="&rememberLogins1.accesskey;"
|
||||
preference="signon.rememberSignons"
|
||||
onsyncfrompreference="return gPrivacyPane.readSavePasswords();"/>
|
||||
<spacer flex="1"/>
|
||||
onsyncfrompreference="return gPrivacyPane.readSavePasswords();"
|
||||
flex="1" />
|
||||
<button id="passwordExceptions"
|
||||
class="accessory-button"
|
||||
label="&passwordExceptions.label;"
|
||||
|
@ -332,8 +328,8 @@
|
|||
<hbox id="masterPasswordBox">
|
||||
<checkbox id="useMasterPassword"
|
||||
label="&useMasterPassword.label;"
|
||||
accesskey="&useMasterPassword.accesskey;"/>
|
||||
<spacer flex="1"/>
|
||||
accesskey="&useMasterPassword.accesskey;"
|
||||
flex="1" />
|
||||
</hbox>
|
||||
<button id="changeMasterPassword"
|
||||
class="accessory-button"
|
||||
|
@ -366,17 +362,6 @@
|
|||
control="trackingProtectionRadioGroup">
|
||||
&trackingProtection.radioGroupLabel;
|
||||
</description>
|
||||
<radiogroup id="trackingProtectionRadioGroup" aria-labelledby="trackingProtectionDesc">
|
||||
<radio value="always"
|
||||
label="&trackingProtectionAlways.label;"
|
||||
accesskey="&trackingProtectionAlways.accesskey;"/>
|
||||
<radio value="private"
|
||||
label="&trackingProtectionPrivate.label;"
|
||||
accesskey="&trackingProtectionPrivate.accesskey;"/>
|
||||
<radio value="never"
|
||||
label="&trackingProtectionNever.label;"
|
||||
accesskey="&trackingProtectionNever.accesskey;"/>
|
||||
</radiogroup>
|
||||
</vbox>
|
||||
<spacer flex="1"/>
|
||||
<vbox id="trackingProtectionAdvancedSettings">
|
||||
|
@ -392,6 +377,17 @@
|
|||
preference="pref.privacy.disable_button.change_blocklist"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<radiogroup id="trackingProtectionRadioGroup" aria-labelledby="trackingProtectionDesc">
|
||||
<radio value="always"
|
||||
label="&trackingProtectionAlways.label;"
|
||||
accesskey="&trackingProtectionAlways.accesskey;"/>
|
||||
<radio value="private"
|
||||
label="&trackingProtectionPrivate.label;"
|
||||
accesskey="&trackingProtectionPrivate.accesskey;"/>
|
||||
<radio value="never"
|
||||
label="&trackingProtectionNever.label;"
|
||||
accesskey="&trackingProtectionNever.accesskey;"/>
|
||||
</radiogroup>
|
||||
</vbox>
|
||||
<vbox id="trackingprotectionpbmbox">
|
||||
<caption><label>&tracking.label;</label></caption>
|
||||
|
@ -419,28 +415,17 @@
|
|||
<!-- Pop-ups -->
|
||||
<groupbox id="miscGroup" data-category="panePrivacy" hidden="true">
|
||||
<caption><label>&popups.label;</label></caption>
|
||||
<grid id="contentGrid">
|
||||
<columns>
|
||||
<column flex="1"/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows id="contentRows-1">
|
||||
<row id="popupPolicyRow">
|
||||
<vbox align="start">
|
||||
<checkbox id="popupPolicy" preference="dom.disable_open_during_load"
|
||||
label="&blockPopups.label;" accesskey="&blockPopups.accesskey;"
|
||||
onsyncfrompreference="return gPrivacyPane.updateButtons('popupPolicyButton',
|
||||
'dom.disable_open_during_load');"/>
|
||||
</vbox>
|
||||
<hbox pack="end">
|
||||
<button id="popupPolicyButton"
|
||||
class="accessory-button"
|
||||
label="&popupExceptions.label;"
|
||||
accesskey="&popupExceptions.accesskey;"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<hbox align="start">
|
||||
<checkbox id="popupPolicy" preference="dom.disable_open_during_load"
|
||||
label="&blockPopups.label;" accesskey="&blockPopups.accesskey;"
|
||||
onsyncfrompreference="return gPrivacyPane.updateButtons('popupPolicyButton',
|
||||
'dom.disable_open_during_load');"
|
||||
flex="1" />
|
||||
<button id="popupPolicyButton"
|
||||
class="accessory-button"
|
||||
label="&popupExceptions.label;"
|
||||
accesskey="&popupExceptions.accesskey;"/>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<!-- Notifications -->
|
||||
|
@ -453,7 +438,7 @@
|
|||
</columns>
|
||||
<rows>
|
||||
<row id="notificationsPolicyRow" align="center">
|
||||
<hbox align="start">
|
||||
<hbox flex="1">
|
||||
<label id="notificationsPolicy">¬ificationsPolicyDesc3.label;</label>
|
||||
<label id="notificationsPolicyLearnMore"
|
||||
class="learnMore text-link"
|
||||
|
@ -466,17 +451,15 @@
|
|||
accesskey="¬ificationsPolicyButton.accesskey;"/>
|
||||
</hbox>
|
||||
</row>
|
||||
<row id="notificationsDoNotDisturbRow" hidden="true">
|
||||
<vbox align="start">
|
||||
<checkbox id="notificationsDoNotDisturb" label="¬ificationsDoNotDisturb.label;"
|
||||
accesskey="¬ificationsDoNotDisturb.accesskey;"/>
|
||||
<label id="notificationsDoNotDisturbDetails"
|
||||
class="indent"
|
||||
value="¬ificationsDoNotDisturbDetails.value;"/>
|
||||
</vbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<vbox id="notificationsDoNotDisturbBox" hidden="true">
|
||||
<checkbox id="notificationsDoNotDisturb" label="¬ificationsDoNotDisturb.label;"
|
||||
accesskey="¬ificationsDoNotDisturb.accesskey;"/>
|
||||
<label id="notificationsDoNotDisturbDetails"
|
||||
class="indent"
|
||||
value="¬ificationsDoNotDisturbDetails.value;"/>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
|
||||
<!-- Location Bar -->
|
||||
|
@ -508,8 +491,8 @@
|
|||
label="&warnOnAddonInstall.label;"
|
||||
accesskey="&warnOnAddonInstall.accesskey;"
|
||||
preference="xpinstall.whitelist.required"
|
||||
onsyncfrompreference="return gPrivacyPane.readWarnAddonInstall();"/>
|
||||
<spacer flex="1"/>
|
||||
onsyncfrompreference="return gPrivacyPane.readWarnAddonInstall();"
|
||||
flex="1" />
|
||||
<button id="addonExceptions"
|
||||
class="accessory-button"
|
||||
label="&addonExceptions.label;"
|
||||
|
@ -517,18 +500,16 @@
|
|||
</hbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
<vbox align="start">
|
||||
<checkbox id="enableSafeBrowsing"
|
||||
label="&enableSafeBrowsing.label;"
|
||||
accesskey="&enableSafeBrowsing.accesskey;" />
|
||||
<vbox class="indent">
|
||||
<checkbox id="blockDownloads"
|
||||
label="&blockDownloads.label;"
|
||||
accesskey="&blockDownloads.accesskey;" />
|
||||
<checkbox id="blockUncommonUnwanted"
|
||||
label="&blockUncommonAndUnwanted.label;"
|
||||
accesskey="&blockUncommonAndUnwanted.accesskey;" />
|
||||
</vbox>
|
||||
<checkbox id="enableSafeBrowsing"
|
||||
label="&enableSafeBrowsing.label;"
|
||||
accesskey="&enableSafeBrowsing.accesskey;" />
|
||||
<vbox class="indent">
|
||||
<checkbox id="blockDownloads"
|
||||
label="&blockDownloads.label;"
|
||||
accesskey="&blockDownloads.accesskey;" />
|
||||
<checkbox id="blockUncommonUnwanted"
|
||||
label="&blockUncommonAndUnwanted.label;"
|
||||
accesskey="&blockUncommonAndUnwanted.accesskey;" />
|
||||
</vbox>
|
||||
</groupbox>
|
||||
|
||||
|
@ -557,11 +538,10 @@
|
|||
<checkbox id="enableOCSP"
|
||||
label="&enableOCSP.label;"
|
||||
accesskey="&enableOCSP.accesskey;"
|
||||
flex="1"
|
||||
onsyncfrompreference="return gPrivacyPane.readEnableOCSP();"
|
||||
onsynctopreference="return gPrivacyPane.writeEnableOCSP();"
|
||||
preference="security.OCSP.enabled"/>
|
||||
<spacer flex="1"/>
|
||||
preference="security.OCSP.enabled"
|
||||
flex="1" />
|
||||
<vbox>
|
||||
<button id="viewCertificatesButton"
|
||||
class="accessory-button"
|
||||
|
@ -644,13 +624,11 @@
|
|||
icon="clear"
|
||||
label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<checkbox preference="browser.cache.disk.smart_size.enabled"
|
||||
id="allowSmartSize"
|
||||
onsyncfrompreference="return gPrivacyPane.readSmartSizeEnabled();"
|
||||
label="&overrideSmartCacheSize.label;"
|
||||
accesskey="&overrideSmartCacheSize.accesskey;"/>
|
||||
</hbox>
|
||||
<checkbox preference="browser.cache.disk.smart_size.enabled"
|
||||
id="allowSmartSize"
|
||||
onsyncfrompreference="return gPrivacyPane.readSmartSizeEnabled();"
|
||||
label="&overrideSmartCacheSize.label;"
|
||||
accesskey="&overrideSmartCacheSize.accesskey;"/>
|
||||
<hbox align="center" class="indent">
|
||||
<label id="useCacheBefore" control="cacheSize"
|
||||
accesskey="&limitCacheSizeBefore.accesskey;">
|
||||
|
@ -677,8 +655,8 @@
|
|||
<checkbox id="offlineNotify"
|
||||
label="&offlineStorageNotify.label;" accesskey="&offlineStorageNotify.accesskey;"
|
||||
preference="browser.offline-apps.notify"
|
||||
onsyncfrompreference="return gPrivacyPane.readOfflineNotify();"/>
|
||||
<spacer flex="1"/>
|
||||
onsyncfrompreference="return gPrivacyPane.readOfflineNotify();"
|
||||
flex="1" />
|
||||
<button id="offlineNotifyExceptions"
|
||||
class="accessory-button"
|
||||
label="&offlineStorageNotifyExceptions.label;"
|
||||
|
|
|
@ -31,6 +31,7 @@ skip-if = true || !healthreport # Bug 1185403 for the "true"
|
|||
[browser_layersacceleration.js]
|
||||
[browser_masterpassword.js]
|
||||
[browser_notifications_do_not_disturb.js]
|
||||
[browser_performance.js]
|
||||
[browser_permissions_urlFieldHidden.js]
|
||||
[browser_proxy_backup.js]
|
||||
[browser_privacypane_1.js]
|
||||
|
|
|
@ -12,8 +12,8 @@ add_task(function*() {
|
|||
is(prefs.selectedPane, "panePrivacy", "Privacy pane was selected");
|
||||
|
||||
let doc = gBrowser.contentDocument;
|
||||
let notificationsDoNotDisturbRow = doc.getElementById("notificationsDoNotDisturbRow");
|
||||
if (notificationsDoNotDisturbRow.hidden) {
|
||||
let notificationsDoNotDisturbBox = doc.getElementById("notificationsDoNotDisturbBox");
|
||||
if (notificationsDoNotDisturbBox.hidden) {
|
||||
todo(false, "Do not disturb is not available on this platform");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
SpecialPowers.pushPrefEnv({set: [
|
||||
["browser.preferences.defaultPerformanceSettings.enabled", true],
|
||||
["dom.ipc.processCount", 4],
|
||||
["layers.acceleration.disabled", false],
|
||||
]});
|
||||
|
||||
add_task(function*() {
|
||||
let prefs = yield openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
|
||||
is(prefs.selectedPane, "paneGeneral", "General pane was selected");
|
||||
|
||||
let doc = gBrowser.contentDocument;
|
||||
let useRecommendedPerformanceSettings = doc.querySelector("#useRecommendedPerformanceSettings");
|
||||
|
||||
is(Services.prefs.getBoolPref("browser.preferences.defaultPerformanceSettings.enabled"), true,
|
||||
"pref value should be true before clicking on checkbox");
|
||||
ok(useRecommendedPerformanceSettings.checked, "checkbox should be checked before clicking on checkbox");
|
||||
|
||||
useRecommendedPerformanceSettings.click();
|
||||
|
||||
let performanceSettings = doc.querySelector("#performanceSettings");
|
||||
is(performanceSettings.hidden, false, "performance settings section is shown");
|
||||
|
||||
is(Services.prefs.getBoolPref("browser.preferences.defaultPerformanceSettings.enabled"), false,
|
||||
"pref value should be false after clicking on checkbox");
|
||||
ok(!useRecommendedPerformanceSettings.checked, "checkbox should not be checked after clicking on checkbox");
|
||||
|
||||
let allowHWAccel = doc.querySelector("#allowHWAccel");
|
||||
is(Services.prefs.getBoolPref("layers.acceleration.disabled"), false,
|
||||
"pref value should be false before clicking on checkbox");
|
||||
ok(allowHWAccel.checked, "checkbox should be checked");
|
||||
|
||||
let contentProcessCount = doc.querySelector("#contentProcessCount");
|
||||
is(Services.prefs.getIntPref("dom.ipc.processCount"), 4, "default pref value should be default value");
|
||||
is(contentProcessCount.selectedItem.value, 4, "selected item should be the default one");
|
||||
|
||||
allowHWAccel.click();
|
||||
is(Services.prefs.getBoolPref("layers.acceleration.disabled"), true,
|
||||
"pref value should be true after clicking on checkbox");
|
||||
ok(!allowHWAccel.checked, "checkbox should not be checked");
|
||||
|
||||
contentProcessCount.value = 7;
|
||||
contentProcessCount.doCommand();
|
||||
is(Services.prefs.getIntPref("dom.ipc.processCount"), 7, "pref value should be 7");
|
||||
is(contentProcessCount.selectedItem.value, 7, "selected item should be 7");
|
||||
|
||||
allowHWAccel.click();
|
||||
is(Services.prefs.getBoolPref("layers.acceleration.disabled"), false,
|
||||
"pref value should be false after clicking on checkbox");
|
||||
ok(allowHWAccel.checked, "checkbox should not be checked");
|
||||
|
||||
contentProcessCount.value = 4;
|
||||
contentProcessCount.doCommand();
|
||||
is(Services.prefs.getIntPref("dom.ipc.processCount"), 4, "pref value should be default value");
|
||||
is(contentProcessCount.selectedItem.value, 4, "selected item should be default one");
|
||||
|
||||
is(performanceSettings.hidden, false, "performance settings section should be still shown");
|
||||
|
||||
Services.prefs.setBoolPref("browser.preferences.defaultPerformanceSettings.enabled", true);
|
||||
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
add_task(function*() {
|
||||
let prefs = yield openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
|
||||
is(prefs.selectedPane, "paneGeneral", "General pane was selected");
|
||||
|
||||
let doc = gBrowser.contentDocument;
|
||||
let performanceSettings = doc.querySelector("#performanceSettings");
|
||||
|
||||
is(performanceSettings.hidden, true, "performance settings section should not be shown");
|
||||
|
||||
Services.prefs.setBoolPref("browser.preferences.defaultPerformanceSettings.enabled", false);
|
||||
|
||||
is(performanceSettings.hidden, false, "performance settings section should be shown");
|
||||
|
||||
Services.prefs.setBoolPref("browser.preferences.defaultPerformanceSettings.enabled", true);
|
||||
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
add_task(function*() {
|
||||
Services.prefs.setIntPref("dom.ipc.processCount", 7);
|
||||
|
||||
let prefs = yield openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
|
||||
is(prefs.selectedPane, "paneGeneral", "General pane was selected");
|
||||
|
||||
let doc = gBrowser.contentDocument;
|
||||
|
||||
let performanceSettings = doc.querySelector("#performanceSettings");
|
||||
is(performanceSettings.hidden, false, "performance settings section should be shown");
|
||||
|
||||
let contentProcessCount = doc.querySelector("#contentProcessCount");
|
||||
is(Services.prefs.getIntPref("dom.ipc.processCount"), 7, "pref value should be 7");
|
||||
is(contentProcessCount.selectedItem.value, 7, "selected item should be 7");
|
||||
|
||||
Services.prefs.setBoolPref("browser.preferences.defaultPerformanceSettings.enabled", true);
|
||||
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
add_task(function*() {
|
||||
Services.prefs.setBoolPref("layers.acceleration.disabled", true);
|
||||
|
||||
let prefs = yield openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
|
||||
is(prefs.selectedPane, "paneGeneral", "General pane was selected");
|
||||
|
||||
let doc = gBrowser.contentDocument;
|
||||
|
||||
let performanceSettings = doc.querySelector("#performanceSettings");
|
||||
is(performanceSettings.hidden, false, "performance settings section should be shown");
|
||||
|
||||
let allowHWAccel = doc.querySelector("#allowHWAccel");
|
||||
is(Services.prefs.getBoolPref("layers.acceleration.disabled"), true,
|
||||
"pref value is false");
|
||||
ok(!allowHWAccel.checked, "checkbox should not be checked");
|
||||
|
||||
Services.prefs.setBoolPref("browser.preferences.defaultPerformanceSettings.enabled", true);
|
||||
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
|
@ -109,6 +109,7 @@ add_task(function*() {
|
|||
|| child.id == "languagesGroup"
|
||||
|| child.id == "fontsGroup"
|
||||
|| child.id == "browsingGroup"
|
||||
|| child.id == "performanceGroup"
|
||||
|| child.id == "header-general") {
|
||||
is_element_visible(child, "Should be in general tab");
|
||||
} else if (child.id) {
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 112206132,
|
||||
"digest": "9ec214f971676369be07b13f5638f9ae1fa12400488d898193fb7a6adbb73ecc120337b569b200bc07630ef9d661a75c2710537422b57eebd9053e60bdc771c5",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 121925324,
|
||||
"digest": "218ec1fd0a00b50fc3f0ce497d2bb9eb2230c1998a1c22cfe8f61ac44d9b57a081e12e8cd946e9d960a1683ed50d625d62f35f2db6fa6aab82454f96f32cd7b2",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 112206132,
|
||||
"digest": "9ec214f971676369be07b13f5638f9ae1fa12400488d898193fb7a6adbb73ecc120337b569b200bc07630ef9d661a75c2710537422b57eebd9053e60bdc771c5",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 121925324,
|
||||
"digest": "218ec1fd0a00b50fc3f0ce497d2bb9eb2230c1998a1c22cfe8f61ac44d9b57a081e12e8cd946e9d960a1683ed50d625d62f35f2db6fa6aab82454f96f32cd7b2",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 112206132,
|
||||
"digest": "9ec214f971676369be07b13f5638f9ae1fa12400488d898193fb7a6adbb73ecc120337b569b200bc07630ef9d661a75c2710537422b57eebd9053e60bdc771c5",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 121925324,
|
||||
"digest": "218ec1fd0a00b50fc3f0ce497d2bb9eb2230c1998a1c22cfe8f61ac44d9b57a081e12e8cd946e9d960a1683ed50d625d62f35f2db6fa6aab82454f96f32cd7b2",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 112206132,
|
||||
"digest": "9ec214f971676369be07b13f5638f9ae1fa12400488d898193fb7a6adbb73ecc120337b569b200bc07630ef9d661a75c2710537422b57eebd9053e60bdc771c5",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 121925324,
|
||||
"digest": "218ec1fd0a00b50fc3f0ce497d2bb9eb2230c1998a1c22cfe8f61ac44d9b57a081e12e8cd946e9d960a1683ed50d625d62f35f2db6fa6aab82454f96f32cd7b2",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
"size": 12072532
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 112206132,
|
||||
"digest": "9ec214f971676369be07b13f5638f9ae1fa12400488d898193fb7a6adbb73ecc120337b569b200bc07630ef9d661a75c2710537422b57eebd9053e60bdc771c5",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 121925324,
|
||||
"digest": "218ec1fd0a00b50fc3f0ce497d2bb9eb2230c1998a1c22cfe8f61ac44d9b57a081e12e8cd946e9d960a1683ed50d625d62f35f2db6fa6aab82454f96f32cd7b2",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 112206132,
|
||||
"digest": "9ec214f971676369be07b13f5638f9ae1fa12400488d898193fb7a6adbb73ecc120337b569b200bc07630ef9d661a75c2710537422b57eebd9053e60bdc771c5",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 121925324,
|
||||
"digest": "218ec1fd0a00b50fc3f0ce497d2bb9eb2230c1998a1c22cfe8f61ac44d9b57a081e12e8cd946e9d960a1683ed50d625d62f35f2db6fa6aab82454f96f32cd7b2",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 112206132,
|
||||
"digest": "9ec214f971676369be07b13f5638f9ae1fa12400488d898193fb7a6adbb73ecc120337b569b200bc07630ef9d661a75c2710537422b57eebd9053e60bdc771c5",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 121925324,
|
||||
"digest": "218ec1fd0a00b50fc3f0ce497d2bb9eb2230c1998a1c22cfe8f61ac44d9b57a081e12e8cd946e9d960a1683ed50d625d62f35f2db6fa6aab82454f96f32cd7b2",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 80381089,
|
||||
"digest": "01bc5c4d25ffd16f51643d36449ca469eccc362b8315945edd9b7e174462659a3d5d4bd5d2738f449557254ba930ca0d70d22f8717b51ba36af68193bd3c39f7",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 81913425,
|
||||
"digest": "41a9dc3f1c0df56f125a4f16cac3635bd3cc2af7167388f54eb4346a599cd8be875475a87a8dd1720d52281ecd361a1050d9523f052f424bce686ba061af6d6c",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.bz2",
|
||||
"unpack": true
|
||||
|
|
|
@ -42,9 +42,9 @@
|
|||
"filename": "dmg.tar.xz"
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 107393796,
|
||||
"digest": "90dca0af2ddd14b8dc4414c8ece52498f8f96e98bb0e4c228e2af27d4f8bd7689dda5160a6994e514e516cb4851f26d94b1bf50456c4dd5c485eaa8b02ba9f95",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 116855168,
|
||||
"digest": "89e414870a398369c745e38e5ce757b98c8f0bbde0ea92ca9fa0a8a72d970e8575fe5493128c1b6b1134ed336c1a7265b1d1ea77fe3673e73a87d0b774f10fac",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 80381089,
|
||||
"digest": "01bc5c4d25ffd16f51643d36449ca469eccc362b8315945edd9b7e174462659a3d5d4bd5d2738f449557254ba930ca0d70d22f8717b51ba36af68193bd3c39f7",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 81913425,
|
||||
"digest": "41a9dc3f1c0df56f125a4f16cac3635bd3cc2af7167388f54eb4346a599cd8be875475a87a8dd1720d52281ecd361a1050d9523f052f424bce686ba061af6d6c",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.bz2",
|
||||
"unpack": true
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
"filename": "mozmake.exe"
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 68401632,
|
||||
"digest": "d55a50d61f3dbd34e68daf985c95773f6f66fa9b88364eefde03d2b009f2f4e9df7e7e72006347bb4ba0f65ff5190b4b6367fde01e79827e10534cd03fe720df",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 76516077,
|
||||
"digest": "6ed02db3ae678fa222ee3680172dc0bc0f0cec735fbc17e67926d4960cb0f6693416d7da8dd2e91d84ba862d7add4ac36e37d7891270e10ed0540fca8b446b68",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.bz2",
|
||||
"unpack": true
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
"filename": "mozmake.exe"
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 68401632,
|
||||
"digest": "d55a50d61f3dbd34e68daf985c95773f6f66fa9b88364eefde03d2b009f2f4e9df7e7e72006347bb4ba0f65ff5190b4b6367fde01e79827e10534cd03fe720df",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 76516077,
|
||||
"digest": "6ed02db3ae678fa222ee3680172dc0bc0f0cec735fbc17e67926d4960cb0f6693416d7da8dd2e91d84ba862d7add4ac36e37d7891270e10ed0540fca8b446b68",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.bz2",
|
||||
"unpack": true
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
"filename": "mozmake.exe"
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 68401632,
|
||||
"digest": "d55a50d61f3dbd34e68daf985c95773f6f66fa9b88364eefde03d2b009f2f4e9df7e7e72006347bb4ba0f65ff5190b4b6367fde01e79827e10534cd03fe720df",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 76516077,
|
||||
"digest": "6ed02db3ae678fa222ee3680172dc0bc0f0cec735fbc17e67926d4960cb0f6693416d7da8dd2e91d84ba862d7add4ac36e37d7891270e10ed0540fca8b446b68",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.bz2",
|
||||
"unpack": true
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
"filename": "mozmake.exe"
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 73942095,
|
||||
"digest": "22be87ae8b6aaf1016dc4a24858caadda47dabc6f44b5730b15489727c900ff7c12e01df8d12aa1775f4b83a4fae73a1c12f69fd15b2ab7fe2603a08637f187d",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 83368214,
|
||||
"digest": "2f1dda29e495e9707a0e22cde5c80525bd202be9a3381dd053edf08e1a54cd7fa4106e8f1cec336daaae62252ef02cf5b76079c0495a90f1ac0b823a16fd27dc",
|
||||
"algorithm": "sha512",
|
||||
"visibility": "public",
|
||||
"filename": "rustc.tar.bz2",
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
"filename": "mozmake.exe"
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack with cargo 0.19.0-nightly (8326a3683 2017-04-19)",
|
||||
"size": 73942095,
|
||||
"digest": "22be87ae8b6aaf1016dc4a24858caadda47dabc6f44b5730b15489727c900ff7c12e01df8d12aa1775f4b83a4fae73a1c12f69fd15b2ab7fe2603a08637f187d",
|
||||
"version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
|
||||
"size": 83368214,
|
||||
"digest": "2f1dda29e495e9707a0e22cde5c80525bd202be9a3381dd053edf08e1a54cd7fa4106e8f1cec336daaae62252ef02cf5b76079c0495a90f1ac0b823a16fd27dc",
|
||||
"algorithm": "sha512",
|
||||
"visibility": "public",
|
||||
"filename": "rustc.tar.bz2",
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/* 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/. */
|
||||
/* globals PlacesProvider, PreviewProvider */
|
||||
/* globals NewTabUtils, PreviewProvider */
|
||||
"use strict";
|
||||
|
||||
const {utils: Cu} = Components;
|
||||
const {actionTypes: at, actionCreators: ac} = Cu.import("resource://activity-stream/common/Actions.jsm", {});
|
||||
|
||||
Cu.import("resource:///modules/PlacesProvider.jsm");
|
||||
Cu.import("resource://gre/modules/NewTabUtils.jsm");
|
||||
Cu.import("resource:///modules/PreviewProvider.jsm");
|
||||
|
||||
const TOP_SITES_SHOWMORE_LENGTH = 12;
|
||||
|
@ -31,7 +31,7 @@ this.TopSitesFeed = class TopSitesFeed {
|
|||
this.store.dispatch(ac.BroadcastToContent(action));
|
||||
}
|
||||
async getLinksWithDefaults(action) {
|
||||
let links = await PlacesProvider.links.getLinks();
|
||||
let links = await NewTabUtils.activityStreamLinks.getTopSites();
|
||||
|
||||
if (!links) {
|
||||
links = [];
|
||||
|
|
|
@ -17,7 +17,7 @@ describe("Top Sites Feed", () => {
|
|||
sandbox = globals.sandbox;
|
||||
});
|
||||
beforeEach(() => {
|
||||
globals.set("PlacesProvider", {links: {getLinks: sandbox.spy(() => Promise.resolve(links))}});
|
||||
globals.set("NewTabUtils", {activityStreamLinks: {getTopSites: sandbox.spy(() => Promise.resolve(links))}});
|
||||
globals.set("PreviewProvider", {getThumbnail: sandbox.spy(() => Promise.resolve(FAKE_SCREENSHOT))});
|
||||
feed = new TopSitesFeed();
|
||||
feed.store = {dispatch: sinon.spy(), getState() { return {TopSites: {rows: Array(12).fill("site")}}; }};
|
||||
|
@ -34,10 +34,10 @@ describe("Top Sites Feed", () => {
|
|||
});
|
||||
|
||||
describe("#getLinksWithDefaults", () => {
|
||||
it("should get the links from Places Provider", async () => {
|
||||
it("should get the links from NewTabUtils", async () => {
|
||||
const result = await feed.getLinksWithDefaults();
|
||||
assert.deepEqual(result, links);
|
||||
assert.calledOnce(global.PlacesProvider.links.getLinks);
|
||||
assert.calledOnce(global.NewTabUtils.activityStreamLinks.getTopSites);
|
||||
});
|
||||
it("should add defaults if there are are not enough links", async () => {
|
||||
links = [{url: "foo.com"}];
|
||||
|
@ -50,7 +50,7 @@ describe("Top Sites Feed", () => {
|
|||
assert.lengthOf(result, TOP_SITES_SHOWMORE_LENGTH);
|
||||
assert.deepEqual(result, [...links, DEFAULT_TOP_SITES[0]]);
|
||||
});
|
||||
it("should not throw if PlacesProvider returns null", () => {
|
||||
it("should not throw if NewTabUtils returns null", () => {
|
||||
links = null;
|
||||
assert.doesNotThrow(() => {
|
||||
feed.getLinksWithDefaults(action);
|
||||
|
|
|
@ -22,6 +22,9 @@ this.FormAutofillHeuristics = {
|
|||
"family-name",
|
||||
"organization",
|
||||
"street-address",
|
||||
"address-line1",
|
||||
"address-line2",
|
||||
"address-line3",
|
||||
"address-level2",
|
||||
"address-level1",
|
||||
"postal-code",
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
/*
|
||||
* Implements an interface of the storage of Form Autofill.
|
||||
*
|
||||
* The data is stored in JSON format, without indentation, using UTF-8 encoding.
|
||||
* With indentation applied, the file would look like this:
|
||||
* The data is stored in JSON format, without indentation and the computed
|
||||
* fields, using UTF-8 encoding. With indentation and computed fields applied,
|
||||
* the schema would look like this:
|
||||
*
|
||||
* {
|
||||
* version: 1,
|
||||
|
@ -19,14 +20,20 @@
|
|||
* additional-name,
|
||||
* family-name,
|
||||
* organization, // Company
|
||||
* street-address, // (Multiline)
|
||||
* address-level2, // City/Town
|
||||
* address-level1, // Province (Standardized code if possible)
|
||||
* street-address, // (Multiline)
|
||||
* address-level2, // City/Town
|
||||
* address-level1, // Province (Standardized code if possible)
|
||||
* postal-code,
|
||||
* country, // ISO 3166
|
||||
* tel,
|
||||
* email,
|
||||
*
|
||||
* // computed fields (These fields are not stored in the file as they are
|
||||
* // generated at runtime.)
|
||||
* address-line1,
|
||||
* address-line2,
|
||||
* address-line3,
|
||||
*
|
||||
* // metadata
|
||||
* timeCreated, // in ms
|
||||
* timeLastUsed, // in ms
|
||||
|
@ -66,7 +73,6 @@ FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
|
|||
|
||||
const SCHEMA_VERSION = 1;
|
||||
|
||||
// Name-related fields will be handled in follow-up bugs due to the complexity.
|
||||
const VALID_FIELDS = [
|
||||
"given-name",
|
||||
"additional-name",
|
||||
|
@ -128,7 +134,8 @@ ProfileStorage.prototype = {
|
|||
log.debug("add:", profile);
|
||||
this._store.ensureDataReady();
|
||||
|
||||
let profileToSave = this._normalizeProfile(profile);
|
||||
let profileToSave = this._clone(profile);
|
||||
this._normalizeProfile(profileToSave);
|
||||
|
||||
profileToSave.guid = gUUIDGenerator.generateUUID().toString()
|
||||
.replace(/[{}-]/g, "").substring(0, 12);
|
||||
|
@ -163,7 +170,9 @@ ProfileStorage.prototype = {
|
|||
throw new Error("No matching profile.");
|
||||
}
|
||||
|
||||
let profileToUpdate = this._normalizeProfile(profile);
|
||||
let profileToUpdate = this._clone(profile);
|
||||
this._normalizeProfile(profileToUpdate);
|
||||
|
||||
for (let field of VALID_FIELDS) {
|
||||
if (profileToUpdate[field] !== undefined) {
|
||||
profileFound[field] = profileToUpdate[field];
|
||||
|
@ -234,7 +243,9 @@ ProfileStorage.prototype = {
|
|||
}
|
||||
|
||||
// Profile is cloned to avoid accidental modifications from outside.
|
||||
return this._clone(profileFound);
|
||||
let clonedProfile = this._clone(profileFound);
|
||||
this._computeFields(clonedProfile);
|
||||
return clonedProfile;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -248,7 +259,9 @@ ProfileStorage.prototype = {
|
|||
this._store.ensureDataReady();
|
||||
|
||||
// Profiles are cloned to avoid accidental modifications from outside.
|
||||
return this._store.data.profiles.map(this._clone);
|
||||
let clonedProfiles = this._store.data.profiles.map(this._clone);
|
||||
clonedProfiles.forEach(this._computeFields);
|
||||
return clonedProfiles;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -259,10 +272,21 @@ ProfileStorage.prototype = {
|
|||
*/
|
||||
getByFilter({info, searchString}) {
|
||||
log.debug("getByFilter:", info, searchString);
|
||||
this._store.ensureDataReady();
|
||||
|
||||
// Profiles are cloned to avoid accidental modifications from outside.
|
||||
let result = this._findByFilter({info, searchString}).map(this._clone);
|
||||
let lcSearchString = searchString.toLowerCase();
|
||||
let result = this.getAll().filter(profile => {
|
||||
// Return true if string is not provided and field exists.
|
||||
// TODO: We'll need to check if the address is for billing or shipping.
|
||||
// (Bug 1358941)
|
||||
let name = profile[info.fieldName];
|
||||
|
||||
if (!searchString) {
|
||||
return !!name;
|
||||
}
|
||||
|
||||
return name.toLowerCase().startsWith(lcSearchString);
|
||||
});
|
||||
|
||||
log.debug("getByFilter: Returning", result.length, "result(s)");
|
||||
return result;
|
||||
},
|
||||
|
@ -275,25 +299,47 @@ ProfileStorage.prototype = {
|
|||
return this._store.data.profiles.find(profile => profile.guid == guid);
|
||||
},
|
||||
|
||||
_findByFilter({info, searchString}) {
|
||||
let profiles = this._store.data.profiles;
|
||||
let lcSearchString = searchString.toLowerCase();
|
||||
_computeFields(profile) {
|
||||
if (profile["street-address"]) {
|
||||
let streetAddress = profile["street-address"].split("\n");
|
||||
// TODO: we should prevent the dataloss by concatenating the rest of lines
|
||||
// with a locale-specific character in the future (bug 1360114).
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (streetAddress[i]) {
|
||||
profile["address-line" + (i + 1)] = streetAddress[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
return profiles.filter(profile => {
|
||||
// Return true if string is not provided and field exists.
|
||||
// TODO: We'll need to check if the address is for billing or shipping.
|
||||
let name = profile[info.fieldName];
|
||||
|
||||
if (!searchString) {
|
||||
return !!name;
|
||||
_normalizeAddress(profile) {
|
||||
if (profile["address-line1"] || profile["address-line2"] ||
|
||||
profile["address-line3"]) {
|
||||
// Treat "street-address" as "address-line1" if it contains only one line
|
||||
// and "address-line1" is omitted.
|
||||
if (!profile["address-line1"] && profile["street-address"] &&
|
||||
!profile["street-address"].includes("\n")) {
|
||||
profile["address-line1"] = profile["street-address"];
|
||||
delete profile["street-address"];
|
||||
}
|
||||
|
||||
return name.toLowerCase().startsWith(lcSearchString);
|
||||
});
|
||||
// Remove "address-line*" but keep the values.
|
||||
let addressLines = [1, 2, 3].map(i => {
|
||||
let value = profile["address-line" + i];
|
||||
delete profile["address-line" + i];
|
||||
return value;
|
||||
});
|
||||
|
||||
// Concatenate "address-line*" if "street-address" is omitted.
|
||||
if (!profile["street-address"]) {
|
||||
profile["street-address"] = addressLines.join("\n");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_normalizeProfile(profile) {
|
||||
let result = {};
|
||||
this._normalizeAddress(profile);
|
||||
|
||||
for (let key in profile) {
|
||||
if (!VALID_FIELDS.includes(key)) {
|
||||
throw new Error(`"${key}" is not a valid field.`);
|
||||
|
@ -302,10 +348,7 @@ ProfileStorage.prototype = {
|
|||
typeof profile[key] !== "number") {
|
||||
throw new Error(`"${key}" contains invalid data type.`);
|
||||
}
|
||||
|
||||
result[key] = profile[key];
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
_dataPostProcessor(data) {
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
/**
|
||||
* Tests the transform algorithm in profileStorage.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://formautofill/ProfileStorage.jsm");
|
||||
|
||||
const TEST_STORE_FILE_NAME = "test-profile.json";
|
||||
|
||||
const COMPUTE_TESTCASES = [
|
||||
// Empty
|
||||
{
|
||||
description: "Empty profile",
|
||||
profile: {
|
||||
},
|
||||
expectedResult: {
|
||||
},
|
||||
},
|
||||
|
||||
// Address
|
||||
{
|
||||
description: "\"street-address\" with single line",
|
||||
profile: {
|
||||
"street-address": "single line",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-address": "single line",
|
||||
"address-line1": "single line",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "\"street-address\" with multiple lines",
|
||||
profile: {
|
||||
"street-address": "line1\nline2\nline3",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-address": "line1\nline2\nline3",
|
||||
"address-line1": "line1",
|
||||
"address-line2": "line2",
|
||||
"address-line3": "line3",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "\"street-address\" with multiple lines but line2 is omitted",
|
||||
profile: {
|
||||
"street-address": "line1\n\nline3",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-address": "line1\n\nline3",
|
||||
"address-line1": "line1",
|
||||
"address-line2": "",
|
||||
"address-line3": "line3",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "\"street-address\" with 4 lines",
|
||||
profile: {
|
||||
"street-address": "line1\nline2\nline3\nline4",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-address": "line1\nline2\nline3\nline4",
|
||||
"address-line1": "line1",
|
||||
"address-line2": "line2",
|
||||
"address-line3": "line3",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const NORMALIZE_TESTCASES = [
|
||||
// Empty
|
||||
{
|
||||
description: "Empty profile",
|
||||
profile: {
|
||||
},
|
||||
expectedResult: {
|
||||
},
|
||||
},
|
||||
|
||||
// Address
|
||||
{
|
||||
description: "Has \"address-line1~3\" and \"street-address\" is omitted",
|
||||
profile: {
|
||||
"address-line1": "line1",
|
||||
"address-line2": "line2",
|
||||
"address-line3": "line3",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-address": "line1\nline2\nline3",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Has both \"address-line1~3\" and \"street-address\"",
|
||||
profile: {
|
||||
"street-address": "street address",
|
||||
"address-line1": "line1",
|
||||
"address-line2": "line2",
|
||||
"address-line3": "line3",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-address": "street address",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Has \"address-line2~3\" and single-line \"street-address\"",
|
||||
profile: {
|
||||
"street-address": "street address",
|
||||
"address-line2": "line2",
|
||||
"address-line3": "line3",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-address": "street address\nline2\nline3",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Has \"address-line2~3\" and multiple-line \"street-address\"",
|
||||
profile: {
|
||||
"street-address": "street address\nstreet address line 2",
|
||||
"address-line2": "line2",
|
||||
"address-line3": "line3",
|
||||
},
|
||||
expectedResult: {
|
||||
"street-address": "street address\nstreet address line 2",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
let do_check_profile_matches = (expectedProfile, profile) => {
|
||||
for (let key in expectedProfile) {
|
||||
do_check_eq(expectedProfile[key], profile[key] || "");
|
||||
}
|
||||
};
|
||||
|
||||
add_task(function* test_computeFields() {
|
||||
let path = getTempFile(TEST_STORE_FILE_NAME).path;
|
||||
|
||||
let profileStorage = new ProfileStorage(path);
|
||||
yield profileStorage.initialize();
|
||||
|
||||
COMPUTE_TESTCASES.forEach(testcase => profileStorage.add(testcase.profile));
|
||||
yield profileStorage._saveImmediately();
|
||||
|
||||
profileStorage = new ProfileStorage(path);
|
||||
yield profileStorage.initialize();
|
||||
|
||||
let profiles = profileStorage.getAll();
|
||||
|
||||
for (let i in profiles) {
|
||||
do_print("Verify testcase: " + COMPUTE_TESTCASES[i].description);
|
||||
do_check_profile_matches(COMPUTE_TESTCASES[i].expectedResult, profiles[i]);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_normalizeProfile() {
|
||||
let path = getTempFile(TEST_STORE_FILE_NAME).path;
|
||||
|
||||
let profileStorage = new ProfileStorage(path);
|
||||
yield profileStorage.initialize();
|
||||
|
||||
NORMALIZE_TESTCASES.forEach(testcase => profileStorage.add(testcase.profile));
|
||||
yield profileStorage._saveImmediately();
|
||||
|
||||
profileStorage = new ProfileStorage(path);
|
||||
yield profileStorage.initialize();
|
||||
|
||||
let profiles = profileStorage.getAll();
|
||||
|
||||
for (let i in profiles) {
|
||||
do_print("Verify testcase: " + NORMALIZE_TESTCASES[i].description);
|
||||
do_check_profile_matches(NORMALIZE_TESTCASES[i].expectedResult, profiles[i]);
|
||||
}
|
||||
});
|
|
@ -15,3 +15,4 @@ support-files =
|
|||
[test_profileAutocompleteResult.js]
|
||||
[test_profileStorage.js]
|
||||
[test_savedFieldNames.js]
|
||||
[test_transformFields.js]
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
<!ENTITY useAutoScroll.accesskey "a">
|
||||
<!ENTITY useSmoothScrolling.label "Use smooth scrolling">
|
||||
<!ENTITY useSmoothScrolling.accesskey "m">
|
||||
<!ENTITY allowHWAccel.label "Use hardware acceleration when available">
|
||||
<!ENTITY allowHWAccel.accesskey "r">
|
||||
<!ENTITY checkUserSpelling.label "Check your spelling as you type">
|
||||
<!ENTITY checkUserSpelling.accesskey "t">
|
||||
|
||||
|
@ -126,3 +124,17 @@
|
|||
<!ENTITY viewCerts.accesskey "C">
|
||||
<!ENTITY viewSecurityDevices.label "Security Devices">
|
||||
<!ENTITY viewSecurityDevices.accesskey "D">
|
||||
|
||||
<!ENTITY performance.label "Performance">
|
||||
<!ENTITY useRecommendedPerformanceSettings.label
|
||||
"Use recommended performance settings">
|
||||
<!ENTITY useRecommendedPerformanceSettings.description
|
||||
"Recommended performance settings are tailored to your computer.">
|
||||
<!ENTITY useRecommendedPerformanceSettings.accesskey
|
||||
"U">
|
||||
<!ENTITY limitContentProcess.label "Content process limit">
|
||||
<!ENTITY limitContentProcess.description
|
||||
"More content processes can make &brandShortName; more responsive when using multiple tabs, but will also consume more memory.">
|
||||
<!ENTITY limitContentProcess.accesskey "L">
|
||||
<!ENTITY allowHWAccel.label "Use hardware acceleration when available">
|
||||
<!ENTITY allowHWAccel.accesskey "r">
|
||||
|
|
|
@ -260,3 +260,6 @@ removeContainerButton2=Don’t remove this Container
|
|||
searchResults.sorryMessage=Sorry! No results were found for “%S”
|
||||
# LOCALIZATION NOTE %S gets replaced with the browser name
|
||||
searchResults.needHelp=Need help? Visit <html:a id="need-help-link">%S Support</html:a>
|
||||
|
||||
# LOCALIZATION NOTE %S is the default value of the `dom.ipc.processCount` pref.
|
||||
defaultContentProcessCount=%S (default)
|
||||
|
|
|
@ -14,10 +14,9 @@
|
|||
|
||||
const {Cc, Ci, Cu} = require("chrome");
|
||||
const Services = require("Services");
|
||||
const promise = require("promise");
|
||||
const defer = require("devtools/shared/defer");
|
||||
const Telemetry = require("devtools/client/shared/telemetry");
|
||||
const { gDevTools } = require("./devtools");
|
||||
const {gDevTools} = require("./devtools");
|
||||
|
||||
// Load target and toolbox lazily as they need gDevTools to be fully initialized
|
||||
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
|
||||
|
@ -68,7 +67,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* of there
|
||||
*/
|
||||
// used by browser-sets.inc, command
|
||||
toggleToolboxCommand: function (gBrowser) {
|
||||
toggleToolboxCommand(gBrowser) {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
|
||||
|
@ -84,7 +83,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* depending on their relevant prefs. It gets run when a window is registered,
|
||||
* or when any of the devtools prefs change.
|
||||
*/
|
||||
updateCommandAvailability: function (win) {
|
||||
updateCommandAvailability(win) {
|
||||
let doc = win.document;
|
||||
|
||||
function toggleMenuItem(id, isEnabled) {
|
||||
|
@ -124,10 +123,12 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
|
||||
// Enable Browser Toolbox?
|
||||
let chromeEnabled = Services.prefs.getBoolPref("devtools.chrome.enabled");
|
||||
let devtoolsRemoteEnabled = Services.prefs.getBoolPref("devtools.debugger.remote-enabled");
|
||||
let devtoolsRemoteEnabled = Services.prefs.getBoolPref(
|
||||
"devtools.debugger.remote-enabled");
|
||||
let remoteEnabled = chromeEnabled && devtoolsRemoteEnabled;
|
||||
toggleMenuItem("menu_browserToolbox", remoteEnabled);
|
||||
toggleMenuItem("menu_browserContentToolbox", remoteEnabled && win.gMultiProcessBrowser);
|
||||
toggleMenuItem("menu_browserContentToolbox",
|
||||
remoteEnabled && win.gMultiProcessBrowser);
|
||||
|
||||
// Enable DevTools connection screen, if the preference allows this.
|
||||
toggleMenuItem("menu_devtools_connect", devtoolsRemoteEnabled);
|
||||
|
@ -138,7 +139,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* window to make it possible to change colors on elements in the browser (like gcli,
|
||||
* or the splitter between the toolbox and web content).
|
||||
*/
|
||||
updateDevtoolsThemeAttribute: function(win) {
|
||||
updateDevtoolsThemeAttribute(win) {
|
||||
// Set an attribute on root element of each window to make it possible
|
||||
// to change colors based on the selected devtools theme.
|
||||
let devtoolsTheme = Services.prefs.getCharPref("devtools.theme");
|
||||
|
@ -147,9 +148,12 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
}
|
||||
|
||||
// Style gcli and the splitter between the toolbox and page content. This used to
|
||||
// set the attribute on the browser's root node but that regressed tpaint: bug 1331449.
|
||||
win.document.getElementById("browser-bottombox").setAttribute("devtoolstheme", devtoolsTheme);
|
||||
win.document.getElementById("content").setAttribute("devtoolstheme", devtoolsTheme);
|
||||
// set the attribute on the browser's root node but that regressed tpaint:
|
||||
// bug 1331449.
|
||||
win.document.getElementById("browser-bottombox")
|
||||
.setAttribute("devtoolstheme", devtoolsTheme);
|
||||
win.document.getElementById("content")
|
||||
.setAttribute("devtoolstheme", devtoolsTheme);
|
||||
|
||||
// If the toolbox color changes and we have the opposite compact theme applied,
|
||||
// change it to match. For example:
|
||||
|
@ -161,14 +165,16 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
let currentTheme = LightweightThemeManager.currentTheme;
|
||||
let currentThemeID = currentTheme && currentTheme.id;
|
||||
if (currentThemeID == COMPACT_LIGHT_ID && devtoolsTheme == "dark") {
|
||||
LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_DARK_ID);
|
||||
LightweightThemeManager.currentTheme =
|
||||
LightweightThemeManager.getUsedTheme(COMPACT_DARK_ID);
|
||||
}
|
||||
if (currentThemeID == COMPACT_DARK_ID && devtoolsTheme == "light") {
|
||||
LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_LIGHT_ID);
|
||||
LightweightThemeManager.currentTheme =
|
||||
LightweightThemeManager.getUsedTheme(COMPACT_LIGHT_ID);
|
||||
}
|
||||
},
|
||||
|
||||
observe: function (subject, topic, prefName) {
|
||||
observe(subject, topic, prefName) {
|
||||
switch (topic) {
|
||||
case "browser-delayed-startup-finished":
|
||||
this._registerBrowserWindow(subject);
|
||||
|
@ -191,7 +197,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
case "sdk:loader:destroy":
|
||||
// This event is fired when the devtools loader unloads, which happens
|
||||
// only when the add-on workflow ask devtools to be reloaded.
|
||||
if (subject.wrappedJSObject == require('@loader/unload')) {
|
||||
if (subject.wrappedJSObject == require("@loader/unload")) {
|
||||
gDevToolsBrowser.destroy({ shuttingDown: false });
|
||||
}
|
||||
break;
|
||||
|
@ -206,7 +212,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
Services.prefs.setCharPref("devtools.theme", "light");
|
||||
}
|
||||
if (currentThemeID == COMPACT_DARK_ID && devtoolsTheme == "light") {
|
||||
Services.prefs.setCharPref("devtools.theme", "dark");
|
||||
Services.prefs.setCharPref("devtools.theme", "dark");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -214,7 +220,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
|
||||
_prefObserverRegistered: false,
|
||||
|
||||
ensurePrefObserver: function () {
|
||||
ensurePrefObserver() {
|
||||
if (!this._prefObserverRegistered) {
|
||||
this._prefObserverRegistered = true;
|
||||
Services.prefs.addObserver("devtools.", this);
|
||||
|
@ -237,29 +243,26 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
*/
|
||||
// Used when: - registering a new tool
|
||||
// - new xul window, to add menu items
|
||||
selectToolCommand: function (gBrowser, toolId) {
|
||||
selectToolCommand(gBrowser, toolId) {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
let toolDefinition = gDevTools.getToolDefinition(toolId);
|
||||
|
||||
if (toolbox &&
|
||||
(toolbox.currentToolId == toolId ||
|
||||
(toolId == "webconsole" && toolbox.splitConsole)))
|
||||
{
|
||||
(toolId == "webconsole" && toolbox.splitConsole))) {
|
||||
toolbox.fireCustomKey(toolId);
|
||||
|
||||
if (toolDefinition.preventClosingOnKey || toolbox.hostType == Toolbox.HostType.WINDOW) {
|
||||
if (toolDefinition.preventClosingOnKey ||
|
||||
toolbox.hostType == Toolbox.HostType.WINDOW) {
|
||||
toolbox.raise();
|
||||
} else {
|
||||
gDevTools.closeToolbox(target);
|
||||
}
|
||||
gDevTools.emit("select-tool-command", toolId);
|
||||
} else {
|
||||
gDevTools.showToolbox(target, toolId).then(() => {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
|
||||
toolbox.fireCustomKey(toolId);
|
||||
gDevTools.showToolbox(target, toolId).then(newToolbox => {
|
||||
newToolbox.fireCustomKey(toolId);
|
||||
gDevTools.emit("select-tool-command", toolId);
|
||||
});
|
||||
}
|
||||
|
@ -269,7 +272,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* Open a tab on "about:debugging", optionally pre-select a given tab.
|
||||
*/
|
||||
// Used by browser-sets.inc, command
|
||||
openAboutDebugging: function (gBrowser, hash) {
|
||||
openAboutDebugging(gBrowser, hash) {
|
||||
let url = "about:debugging" + (hash ? "#" + hash : "");
|
||||
gBrowser.selectedTab = gBrowser.addTab(url);
|
||||
},
|
||||
|
@ -278,7 +281,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* Open a tab to allow connects to a remote browser
|
||||
*/
|
||||
// Used by browser-sets.inc, command
|
||||
openConnectScreen: function (gBrowser) {
|
||||
openConnectScreen(gBrowser) {
|
||||
gBrowser.selectedTab = gBrowser.addTab("chrome://devtools/content/framework/connect/connect.xhtml");
|
||||
},
|
||||
|
||||
|
@ -287,7 +290,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
*/
|
||||
// Used by browser-sets.inc, command
|
||||
// itself, webide widget
|
||||
openWebIDE: function () {
|
||||
openWebIDE() {
|
||||
let win = Services.wm.getMostRecentWindow("devtools:webide");
|
||||
if (win) {
|
||||
win.focus();
|
||||
|
@ -296,55 +299,49 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
}
|
||||
},
|
||||
|
||||
inspectNode: function (tab, node) {
|
||||
async inspectNode(tab, node) {
|
||||
let target = TargetFactory.forTab(tab);
|
||||
|
||||
// Generate a cross iframes query selector
|
||||
let selectors = [];
|
||||
while(node) {
|
||||
while (node) {
|
||||
selectors.push(findCssSelector(node));
|
||||
node = node.ownerDocument.defaultView.frameElement;
|
||||
}
|
||||
|
||||
return gDevTools.showToolbox(target, "inspector").then(toolbox => {
|
||||
let inspector = toolbox.getCurrentPanel();
|
||||
let toolbox = await gDevTools.showToolbox(target, "inspector");
|
||||
let inspector = toolbox.getCurrentPanel();
|
||||
|
||||
// new-node-front tells us when the node has been selected, whether the
|
||||
// browser is remote or not.
|
||||
let onNewNode = inspector.selection.once("new-node-front");
|
||||
// new-node-front tells us when the node has been selected, whether the
|
||||
// browser is remote or not.
|
||||
let onNewNode = inspector.selection.once("new-node-front");
|
||||
|
||||
// Evaluate the cross iframes query selectors
|
||||
function querySelectors(nodeFront) {
|
||||
let selector = selectors.pop();
|
||||
if (!selector) {
|
||||
return Promise.resolve(nodeFront);
|
||||
}
|
||||
return inspector.walker.querySelector(nodeFront, selector)
|
||||
.then(node => {
|
||||
if (selectors.length > 0) {
|
||||
return inspector.walker.children(node).then(({ nodes }) => {
|
||||
return nodes[0]; // This is the NodeFront for the document node inside the iframe
|
||||
});
|
||||
}
|
||||
return node;
|
||||
}).then(querySelectors);
|
||||
// Evaluate the cross iframes query selectors
|
||||
async function querySelectors(nodeFront) {
|
||||
let selector = selectors.pop();
|
||||
if (!selector) {
|
||||
return nodeFront;
|
||||
}
|
||||
inspector.walker.getRootNode()
|
||||
.then(querySelectors)
|
||||
.then(node => {
|
||||
// Select the final node
|
||||
inspector.selection.setNodeFront(node, "browser-context-menu");
|
||||
});
|
||||
nodeFront = await inspector.walker.querySelector(nodeFront, selector);
|
||||
if (selectors.length > 0) {
|
||||
let { nodes } = await inspector.walker.children(nodeFront);
|
||||
// This is the NodeFront for the document node inside the iframe
|
||||
nodeFront = nodes[0];
|
||||
}
|
||||
return querySelectors(nodeFront);
|
||||
}
|
||||
let nodeFront = await inspector.walker.getRootNode();
|
||||
nodeFront = await querySelectors(nodeFront);
|
||||
// Select the final node
|
||||
inspector.selection.setNodeFront(nodeFront, "browser-context-menu");
|
||||
|
||||
return onNewNode.then(() => {
|
||||
// Now that the node has been selected, wait until the inspector is
|
||||
// fully updated.
|
||||
return inspector.once("inspector-updated");
|
||||
});
|
||||
});
|
||||
await onNewNode;
|
||||
// Now that the node has been selected, wait until the inspector is
|
||||
// fully updated.
|
||||
await inspector.once("inspector-updated");
|
||||
},
|
||||
|
||||
_getContentProcessTarget: function (processId) {
|
||||
_getContentProcessTarget(processId) {
|
||||
// Create a DebuggerServer in order to connect locally to it
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
|
@ -382,7 +379,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
},
|
||||
|
||||
// Used by menus.js
|
||||
openContentProcessToolbox: function (gBrowser) {
|
||||
openContentProcessToolbox(gBrowser) {
|
||||
let { childCount } = Services.ppmm;
|
||||
// Get the process message manager for the current tab
|
||||
let mm = gBrowser.selectedBrowser.messageManager.processMessageManager;
|
||||
|
@ -410,7 +407,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
/**
|
||||
* Install Developer widget
|
||||
*/
|
||||
installDeveloperWidget: function () {
|
||||
installDeveloperWidget() {
|
||||
let id = "developer-button";
|
||||
let widget = CustomizableUI.getWidget(id);
|
||||
if (widget && widget.provider == CustomizableUI.PROVIDER_API) {
|
||||
|
@ -425,12 +422,11 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
defaultArea: AppConstants.MOZ_DEV_EDITION ?
|
||||
CustomizableUI.AREA_NAVBAR :
|
||||
CustomizableUI.AREA_PANEL,
|
||||
onViewShowing: function (aEvent) {
|
||||
onViewShowing(event) {
|
||||
// Populate the subview with whatever menuitems are in the developer
|
||||
// menu. We skip menu elements, because the menu panel has no way
|
||||
// of dealing with those right now.
|
||||
let doc = aEvent.target.ownerDocument;
|
||||
let win = doc.defaultView;
|
||||
let doc = event.target.ownerDocument;
|
||||
|
||||
let menu = doc.getElementById("menuWebDeveloperPopup");
|
||||
|
||||
|
@ -446,7 +442,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
clearSubview(developerItems);
|
||||
fillSubviewFromMenuItems(itemsToDisplay, developerItems);
|
||||
},
|
||||
onBeforeCreated: function (doc) {
|
||||
onBeforeCreated(doc) {
|
||||
// Bug 1223127, CUI should make this easier to do.
|
||||
if (doc.getElementById("PanelUI-developerItems")) {
|
||||
return;
|
||||
|
@ -465,7 +461,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* Install WebIDE widget
|
||||
*/
|
||||
// Used by itself
|
||||
installWebIDEWidget: function () {
|
||||
installWebIDEWidget() {
|
||||
if (this.isWebIDEWidgetInstalled()) {
|
||||
return;
|
||||
}
|
||||
|
@ -483,13 +479,13 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
label: "devtools-webide-button2.label",
|
||||
tooltiptext: "devtools-webide-button2.tooltiptext",
|
||||
defaultArea: defaultArea,
|
||||
onCommand: function (aEvent) {
|
||||
onCommand(event) {
|
||||
gDevToolsBrowser.openWebIDE();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
isWebIDEWidgetInstalled: function () {
|
||||
isWebIDEWidgetInstalled() {
|
||||
let widgetWrapper = CustomizableUI.getWidget("webide-button");
|
||||
return !!(widgetWrapper && widgetWrapper.provider == CustomizableUI.PROVIDER_API);
|
||||
},
|
||||
|
@ -502,7 +498,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
/**
|
||||
* Uninstall WebIDE widget
|
||||
*/
|
||||
uninstallWebIDEWidget: function () {
|
||||
uninstallWebIDEWidget() {
|
||||
if (this.isWebIDEWidgetInstalled()) {
|
||||
CustomizableUI.removeWidgetFromArea("webide-button");
|
||||
}
|
||||
|
@ -513,7 +509,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* Move WebIDE widget to the navbar
|
||||
*/
|
||||
// Used by webide.js
|
||||
moveWebIDEWidgetInNavbar: function () {
|
||||
moveWebIDEWidgetInNavbar() {
|
||||
CustomizableUI.addWidgetToArea("webide-button", CustomizableUI.AREA_NAVBAR);
|
||||
},
|
||||
|
||||
|
@ -523,7 +519,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* @param {XULDocument} doc
|
||||
* The document to which devtools should be hooked to.
|
||||
*/
|
||||
_registerBrowserWindow: function (win) {
|
||||
_registerBrowserWindow(win) {
|
||||
if (gDevToolsBrowser._trackedBrowserWindows.has(win)) {
|
||||
return;
|
||||
}
|
||||
|
@ -558,13 +554,13 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* Hook the JS debugger tool to the "Debug Script" button of the slow script
|
||||
* dialog.
|
||||
*/
|
||||
setSlowScriptDebugHandler: function DT_setSlowScriptDebugHandler() {
|
||||
setSlowScriptDebugHandler() {
|
||||
let debugService = Cc["@mozilla.org/dom/slow-script-debug;1"]
|
||||
.getService(Ci.nsISlowScriptDebug);
|
||||
let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
|
||||
|
||||
function slowScriptDebugHandler(aTab, aCallback) {
|
||||
let target = TargetFactory.forTab(aTab);
|
||||
function slowScriptDebugHandler(tab, callback) {
|
||||
let target = TargetFactory.forTab(tab);
|
||||
|
||||
gDevTools.showToolbox(target, "jsdebugger").then(toolbox => {
|
||||
let threadClient = toolbox.threadClient;
|
||||
|
@ -575,13 +571,13 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
case "paused":
|
||||
// When the debugger is already paused.
|
||||
threadClient.resumeThenPause();
|
||||
aCallback();
|
||||
callback();
|
||||
break;
|
||||
case "attached":
|
||||
// When the debugger is already open.
|
||||
threadClient.interrupt(() => {
|
||||
threadClient.resumeThenPause();
|
||||
aCallback();
|
||||
callback();
|
||||
});
|
||||
break;
|
||||
case "resuming":
|
||||
|
@ -589,7 +585,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
threadClient.addOneTimeListener("resumed", () => {
|
||||
threadClient.interrupt(() => {
|
||||
threadClient.resumeThenPause();
|
||||
aCallback();
|
||||
callback();
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
@ -600,8 +596,8 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
});
|
||||
}
|
||||
|
||||
debugService.activationHandler = function (aWindow) {
|
||||
let chromeWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
debugService.activationHandler = function (window) {
|
||||
let chromeWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
|
@ -611,11 +607,13 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
|
||||
let setupFinished = false;
|
||||
slowScriptDebugHandler(chromeWindow.gBrowser.selectedTab,
|
||||
() => { setupFinished = true; });
|
||||
() => {
|
||||
setupFinished = true;
|
||||
});
|
||||
|
||||
// Don't return from the interrupt handler until the debugger is brought
|
||||
// up; no reason to continue executing the slow script.
|
||||
let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
utils.enterModalState();
|
||||
while (!setupFinished) {
|
||||
|
@ -624,23 +622,21 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
utils.leaveModalState();
|
||||
};
|
||||
|
||||
debugService.remoteActivationHandler = function (aBrowser, aCallback) {
|
||||
let chromeWindow = aBrowser.ownerDocument.defaultView;
|
||||
let tab = chromeWindow.gBrowser.getTabForBrowser(aBrowser);
|
||||
debugService.remoteActivationHandler = function (browser, callback) {
|
||||
let chromeWindow = browser.ownerDocument.defaultView;
|
||||
let tab = chromeWindow.gBrowser.getTabForBrowser(browser);
|
||||
chromeWindow.gBrowser.selected = tab;
|
||||
|
||||
function callback() {
|
||||
aCallback.finishDebuggerStartup();
|
||||
}
|
||||
|
||||
slowScriptDebugHandler(tab, callback);
|
||||
slowScriptDebugHandler(tab, function () {
|
||||
callback.finishDebuggerStartup();
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Unset the slow script debug handler.
|
||||
*/
|
||||
unsetSlowScriptDebugHandler: function DT_unsetSlowScriptDebugHandler() {
|
||||
unsetSlowScriptDebugHandler() {
|
||||
let debugService = Cc["@mozilla.org/dom/slow-script-debug;1"]
|
||||
.getService(Ci.nsISlowScriptDebug);
|
||||
debugService.activationHandler = undefined;
|
||||
|
@ -652,7 +648,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* @param {object} toolDefinition
|
||||
* properties of the tool to add
|
||||
*/
|
||||
_addToolToWindows: function DT_addToolToWindows(toolDefinition) {
|
||||
_addToolToWindows(toolDefinition) {
|
||||
// No menu item or global shortcut is required for options panel.
|
||||
if (!toolDefinition.inMenu) {
|
||||
return;
|
||||
|
@ -664,7 +660,9 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
!Services.prefs.getBoolPref(toolDefinition.visibilityswitch)) {
|
||||
return;
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// Prevent breaking everything if the pref doesn't exists.
|
||||
}
|
||||
|
||||
// We need to insert the new tool in the right place, which means knowing
|
||||
// the tool that comes before the tool that we're trying to add
|
||||
|
@ -689,9 +687,9 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
}
|
||||
},
|
||||
|
||||
hasToolboxOpened: function (win) {
|
||||
hasToolboxOpened(win) {
|
||||
let tab = win.gBrowser.selectedTab;
|
||||
for (let [target, toolbox] of gDevTools._toolboxes) {
|
||||
for (let [target, ] of gDevTools._toolboxes) {
|
||||
if (target.tab == tab) {
|
||||
return true;
|
||||
}
|
||||
|
@ -703,9 +701,8 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* Update the "Toggle Tools" checkbox in the developer tools menu. This is
|
||||
* called when a toolbox is created or destroyed.
|
||||
*/
|
||||
_updateMenuCheckbox: function DT_updateMenuCheckbox() {
|
||||
_updateMenuCheckbox() {
|
||||
for (let win of gDevToolsBrowser._trackedBrowserWindows) {
|
||||
|
||||
let hasToolbox = gDevToolsBrowser.hasToolboxOpened(win);
|
||||
|
||||
let menu = win.document.getElementById("menu_devToolbox");
|
||||
|
@ -723,7 +720,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* @param {string} toolId
|
||||
* id of the tool to remove
|
||||
*/
|
||||
_removeToolFromWindows: function DT_removeToolFromWindows(toolId) {
|
||||
_removeToolFromWindows(toolId) {
|
||||
for (let win of gDevToolsBrowser._trackedBrowserWindows) {
|
||||
BrowserMenus.removeToolFromMenu(toolId, win.document);
|
||||
}
|
||||
|
@ -740,7 +737,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* @param {XULWindow} win
|
||||
* The window containing the menu entry
|
||||
*/
|
||||
_forgetBrowserWindow: function (win) {
|
||||
_forgetBrowserWindow(win) {
|
||||
if (!gDevToolsBrowser._trackedBrowserWindows.has(win)) {
|
||||
return;
|
||||
}
|
||||
|
@ -770,7 +767,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
tabContainer.removeEventListener("TabUnpinned", this);
|
||||
},
|
||||
|
||||
handleEvent: function (event) {
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "TabOpen":
|
||||
case "TabClose":
|
||||
|
@ -803,7 +800,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
}
|
||||
},
|
||||
|
||||
_pingTelemetry: function () {
|
||||
_pingTelemetry() {
|
||||
let mean = function (arr) {
|
||||
if (arr.length === 0) {
|
||||
return 0;
|
||||
|
@ -829,9 +826,9 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
* some cleanups to speed it up. Otherwise everything need to be
|
||||
* cleaned up in order to be able to load devtools again.
|
||||
*/
|
||||
destroy: function ({ shuttingDown }) {
|
||||
destroy({ shuttingDown }) {
|
||||
Services.prefs.removeObserver("devtools.", gDevToolsBrowser);
|
||||
Services.obs.removeObserver(gDevToolsBrowser, "lightweight-theme-changed", false);
|
||||
Services.obs.removeObserver(gDevToolsBrowser, "lightweight-theme-changed");
|
||||
Services.obs.removeObserver(gDevToolsBrowser, "browser-delayed-startup-finished");
|
||||
Services.obs.removeObserver(gDevToolsBrowser, "quit-application");
|
||||
Services.obs.removeObserver(gDevToolsBrowser, "sdk:loader:destroy");
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
const {Cu} = require("chrome");
|
||||
const Services = require("Services");
|
||||
const promise = require("promise");
|
||||
const defer = require("devtools/shared/defer");
|
||||
|
||||
// Load gDevToolsBrowser toolbox lazily as they need gDevTools to be fully initialized
|
||||
loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
|
||||
|
@ -46,7 +44,7 @@ function DevTools() {
|
|||
// start registering all default tools and themes: create menuitems, keys, emit
|
||||
// related events.
|
||||
this.registerDefaults();
|
||||
};
|
||||
}
|
||||
|
||||
DevTools.prototype = {
|
||||
// The windowtype of the main window, used in various tools. This may be set
|
||||
|
@ -100,7 +98,7 @@ DevTools.prototype = {
|
|||
* markup from |url|, and also the toolbox containing the panel.
|
||||
* And returns an instance of ToolPanel (function|required)
|
||||
*/
|
||||
registerTool: function DT_registerTool(toolDefinition) {
|
||||
registerTool(toolDefinition) {
|
||||
let toolId = toolDefinition.id;
|
||||
|
||||
if (!toolId || FORBIDDEN_IDS.has(toolId)) {
|
||||
|
@ -130,17 +128,16 @@ DevTools.prototype = {
|
|||
* true to indicate that the call is due to app quit, so we should not
|
||||
* cause a cascade of costly events
|
||||
*/
|
||||
unregisterTool: function DT_unregisterTool(tool, isQuitApplication) {
|
||||
unregisterTool(tool, isQuitApplication) {
|
||||
let toolId = null;
|
||||
if (typeof tool == "string") {
|
||||
toolId = tool;
|
||||
tool = this._tools.get(tool);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let {Deprecated} = Cu.import("resource://gre/modules/Deprecated.jsm", {});
|
||||
Deprecated.warning("Deprecation WARNING: gDevTools.unregisterTool(tool) is deprecated. " +
|
||||
"You should unregister a tool using its toolId: " +
|
||||
"gDevTools.unregisterTool(toolId).");
|
||||
Deprecated.warning("Deprecation WARNING: gDevTools.unregisterTool(tool) is " +
|
||||
"deprecated. You should unregister a tool using its toolId: " +
|
||||
"gDevTools.unregisterTool(toolId).");
|
||||
toolId = tool.id;
|
||||
}
|
||||
this._tools.delete(toolId);
|
||||
|
@ -153,19 +150,19 @@ DevTools.prototype = {
|
|||
/**
|
||||
* Sorting function used for sorting tools based on their ordinals.
|
||||
*/
|
||||
ordinalSort: function DT_ordinalSort(d1, d2) {
|
||||
ordinalSort(d1, d2) {
|
||||
let o1 = (typeof d1.ordinal == "number") ? d1.ordinal : MAX_ORDINAL;
|
||||
let o2 = (typeof d2.ordinal == "number") ? d2.ordinal : MAX_ORDINAL;
|
||||
return o1 - o2;
|
||||
},
|
||||
|
||||
getDefaultTools: function DT_getDefaultTools() {
|
||||
getDefaultTools() {
|
||||
return DefaultTools.sort(this.ordinalSort);
|
||||
},
|
||||
|
||||
getAdditionalTools: function DT_getAdditionalTools() {
|
||||
getAdditionalTools() {
|
||||
let tools = [];
|
||||
for (let [key, value] of this._tools) {
|
||||
for (let [, value] of this._tools) {
|
||||
if (DefaultTools.indexOf(value) == -1) {
|
||||
tools.push(value);
|
||||
}
|
||||
|
@ -186,7 +183,7 @@ DevTools.prototype = {
|
|||
* @return {ToolDefinition|null} tool
|
||||
* The ToolDefinition for the id or null.
|
||||
*/
|
||||
getToolDefinition: function DT_getToolDefinition(toolId) {
|
||||
getToolDefinition(toolId) {
|
||||
let tool = this._tools.get(toolId);
|
||||
if (!tool) {
|
||||
return null;
|
||||
|
@ -206,7 +203,7 @@ DevTools.prototype = {
|
|||
* @return {Map} tools
|
||||
* A map of the the tool definitions registered in this instance
|
||||
*/
|
||||
getToolDefinitionMap: function DT_getToolDefinitionMap() {
|
||||
getToolDefinitionMap() {
|
||||
let tools = new Map();
|
||||
|
||||
for (let [id, definition] of this._tools) {
|
||||
|
@ -226,7 +223,7 @@ DevTools.prototype = {
|
|||
* @return {Array} tools
|
||||
* A sorted array of the tool definitions registered in this instance
|
||||
*/
|
||||
getToolDefinitionArray: function DT_getToolDefinitionArray() {
|
||||
getToolDefinitionArray() {
|
||||
let definitions = [];
|
||||
|
||||
for (let [id, definition] of this._tools) {
|
||||
|
@ -260,7 +257,7 @@ DevTools.prototype = {
|
|||
* is unapplied. The function takes the current iframe window
|
||||
* and the new theme id as arguments (function)
|
||||
*/
|
||||
registerTheme: function DT_registerTheme(themeDefinition) {
|
||||
registerTheme(themeDefinition) {
|
||||
let themeId = themeDefinition.id;
|
||||
|
||||
if (!themeId) {
|
||||
|
@ -283,13 +280,12 @@ DevTools.prototype = {
|
|||
* @param {string|object} theme
|
||||
* Definition or the id of the theme to unregister.
|
||||
*/
|
||||
unregisterTheme: function DT_unregisterTheme(theme) {
|
||||
unregisterTheme(theme) {
|
||||
let themeId = null;
|
||||
if (typeof theme == "string") {
|
||||
themeId = theme;
|
||||
theme = this._themes.get(theme);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
themeId = theme.id;
|
||||
}
|
||||
|
||||
|
@ -323,7 +319,7 @@ DevTools.prototype = {
|
|||
* @return {ThemeDefinition|null} theme
|
||||
* The ThemeDefinition for the id or null.
|
||||
*/
|
||||
getThemeDefinition: function DT_getThemeDefinition(themeId) {
|
||||
getThemeDefinition(themeId) {
|
||||
let theme = this._themes.get(themeId);
|
||||
if (!theme) {
|
||||
return null;
|
||||
|
@ -337,7 +333,7 @@ DevTools.prototype = {
|
|||
* @return {Map} themes
|
||||
* A map of the the theme definitions registered in this instance
|
||||
*/
|
||||
getThemeDefinitionMap: function DT_getThemeDefinitionMap() {
|
||||
getThemeDefinitionMap() {
|
||||
let themes = new Map();
|
||||
|
||||
for (let [id, definition] of this._themes) {
|
||||
|
@ -355,7 +351,7 @@ DevTools.prototype = {
|
|||
* @return {Array} themes
|
||||
* A sorted array of the theme definitions registered in this instance
|
||||
*/
|
||||
getThemeDefinitionArray: function DT_getThemeDefinitionArray() {
|
||||
getThemeDefinitionArray() {
|
||||
let definitions = [];
|
||||
|
||||
for (let [id, definition] of this._themes) {
|
||||
|
@ -390,7 +386,6 @@ DevTools.prototype = {
|
|||
showToolbox: Task.async(function* (target, toolId, hostType, hostOptions) {
|
||||
let toolbox = this._toolboxes.get(target);
|
||||
if (toolbox) {
|
||||
|
||||
if (hostType != null && toolbox.hostType != hostType) {
|
||||
yield toolbox.switchHost(hostType);
|
||||
}
|
||||
|
@ -449,7 +444,7 @@ DevTools.prototype = {
|
|||
* @return {Toolbox} toolbox
|
||||
* The toolbox that is debugging the given target
|
||||
*/
|
||||
getToolbox: function DT_getToolbox(target) {
|
||||
getToolbox(target) {
|
||||
return this._toolboxes.get(target);
|
||||
},
|
||||
|
||||
|
@ -482,17 +477,17 @@ DevTools.prototype = {
|
|||
* some cleanups to speed it up. Otherwise everything need to be
|
||||
* cleaned up in order to be able to load devtools again.
|
||||
*/
|
||||
destroy: function ({ shuttingDown }) {
|
||||
destroy({ shuttingDown }) {
|
||||
// Do not cleanup everything during firefox shutdown, but only when
|
||||
// devtools are reloaded via the add-on contribution workflow.
|
||||
if (!shuttingDown) {
|
||||
for (let [target, toolbox] of this._toolboxes) {
|
||||
for (let [, toolbox] of this._toolboxes) {
|
||||
toolbox.destroy();
|
||||
}
|
||||
AboutDevTools.unregister();
|
||||
}
|
||||
|
||||
for (let [key, tool] of this.getToolDefinitionMap()) {
|
||||
for (let [key, ] of this.getToolDefinitionMap()) {
|
||||
this.unregisterTool(key, true);
|
||||
}
|
||||
|
||||
|
@ -508,7 +503,7 @@ DevTools.prototype = {
|
|||
/**
|
||||
* Iterator that yields each of the toolboxes.
|
||||
*/
|
||||
*[Symbol.iterator ]() {
|
||||
* [Symbol.iterator ]() {
|
||||
for (let toolbox of this._toolboxes) {
|
||||
yield toolbox;
|
||||
}
|
||||
|
|
|
@ -143,6 +143,18 @@ networkMenu.sortedAsc=Sorted ascending
|
|||
# in the network table toolbar, for any column that is sorted descending.
|
||||
networkMenu.sortedDesc=Sorted descending
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary.tooltip.perf): A tooltip explaining
|
||||
# what the perf button does
|
||||
networkMenu.summary.tooltip.perf=Start performance analysis
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary.tooltip.domContentLoaded): A tooltip explaining
|
||||
# what the DOMContentLoaded label displays
|
||||
networkMenu.summary.tooltip.domContentLoaded=Time when “DOMContentLoad” event occurred
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary.tooltip.load): A tooltip explaining
|
||||
# what the load label displays
|
||||
networkMenu.summary.tooltip.load=Time when “load” event occurred
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary.requestsCount): This label is displayed
|
||||
# in the network table footer providing the number of requests
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
|
@ -152,14 +164,25 @@ networkMenu.summary.requestsCount=One request;%S requests
|
|||
# in the network table footer when there are no requests
|
||||
networkMenu.summary.requestsCountEmpty=No requests
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary.tooltip.requestsCount): A tooltip explaining
|
||||
# what the requestsCount label displays
|
||||
networkMenu.summary.tooltip.requestsCount=Number of requests
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary.transferred): This label is displayed
|
||||
# in the network table footer providing the transferred size.
|
||||
networkMenu.summary.transferred=%S / %S transferred
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary.tooltip.transferred): A tooltip explaining
|
||||
# what the transferred label displays
|
||||
networkMenu.summary.tooltip.transferred=Size/transferred size of all requests
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary.finish): This label is displayed
|
||||
# in the network table footer providing the transfer time.
|
||||
networkMenu.summary.finish=Finish: %S
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary.tooltip.finish): A tooltip explaining
|
||||
# what the finish label displays
|
||||
networkMenu.summary.tooltip.finish=Total time needed to load all requests
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.sizeB): This is the label displayed
|
||||
# in the network menu specifying the size of a request (in bytes).
|
||||
|
@ -196,6 +219,34 @@ networkMenu.sizeServiceWorker=service worker
|
|||
# in the network menu specifying the time for a request to finish (in milliseconds).
|
||||
networkMenu.totalMS=→ %S ms
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.waterfall.tooltip.total): This is part of the tooltip
|
||||
# displayed in the requests waterfall for total time (in milliseconds).
|
||||
netmonitor.waterfall.tooltip.total=Total %S ms
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.waterfall.tooltip.blocked): This is part of the tooltip
|
||||
# displayed in the requests waterfall for blocked time (in milliseconds).
|
||||
netmonitor.waterfall.tooltip.blocked=Blocked %S ms
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.waterfall.tooltip.dns): This is part of the tooltip
|
||||
# displayed in the requests waterfall for dns time (in milliseconds).
|
||||
netmonitor.waterfall.tooltip.dns=DNS %S ms
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.waterfall.tooltip.connect): This is part of the tooltip
|
||||
# displayed in the requests waterfall for connect time (in milliseconds).
|
||||
netmonitor.waterfall.tooltip.connect=Connect %S ms
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.waterfall.tooltip.send): This is part of the tooltip
|
||||
# displayed in the requests waterfall for send time (in milliseconds).
|
||||
netmonitor.waterfall.tooltip.send=Send %S ms
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.waterfall.tooltip.wait): This is part of the tooltip
|
||||
# displayed in the requests waterfall for wait time (in milliseconds).
|
||||
netmonitor.waterfall.tooltip.wait=Wait %S ms
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.waterfall.tooltip.receive): This is part of the tooltip
|
||||
# displayed in the requests waterfall for receive time (in milliseiconds).
|
||||
netmonitor.waterfall.tooltip.receive=Receive %S ms
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.millisecond): This is the label displayed
|
||||
# in the network menu specifying timing interval divisions (in milliseconds).
|
||||
networkMenu.millisecond=%S ms
|
||||
|
|
|
@ -51,6 +51,37 @@
|
|||
return NetMonitorController.shutdownNetMonitor();
|
||||
}
|
||||
};
|
||||
|
||||
// Implement support for chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs
|
||||
// where 1234 is the tab id, you can retrieve from about:debugging#tabs links.
|
||||
// Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs.
|
||||
|
||||
// URL constructor doesn't support chrome: scheme
|
||||
let href = window.location.href.replace(/chrome:/, "http://");
|
||||
let url = new window.URL(href);
|
||||
|
||||
// If query parameters are given in a chrome tab, the inspector is running in standalone.
|
||||
if (window.location.protocol === "chrome:" && url.search.length > 1) {
|
||||
const { targetFromURL } = require("devtools/client/framework/target-from-url");
|
||||
|
||||
(async function () {
|
||||
let target = await targetFromURL(url);
|
||||
// Start the network event listening as it is done in the toolbox code
|
||||
await target.activeConsole.startListeners([
|
||||
"NetworkActivity",
|
||||
]);
|
||||
// Create a fake toolbox object
|
||||
let toolbox = {
|
||||
target,
|
||||
viewSourceInDebugger() {
|
||||
throw new Error("toolbox.viewSourceInDebugger is not implement from a tab");
|
||||
}
|
||||
};
|
||||
window.Netmonitor.bootstrap({ toolbox });
|
||||
})().catch(e => {
|
||||
window.alert("Unable to start the network monitor:" + e.message + "\n" + e.stack);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -38,16 +38,17 @@ const RequestListColumnWaterfall = createClass({
|
|||
|
||||
render() {
|
||||
let { firstRequestStartedMillis, item } = this.props;
|
||||
const { boxes, tooltip } = timingBoxes(item);
|
||||
|
||||
return (
|
||||
div({ className: "requests-list-column requests-list-waterfall" },
|
||||
div({ className: "requests-list-column requests-list-waterfall", title: tooltip },
|
||||
div({
|
||||
className: "requests-list-timings",
|
||||
style: {
|
||||
paddingInlineStart: `${item.startedMillis - firstRequestStartedMillis}px`,
|
||||
},
|
||||
},
|
||||
timingBoxes(item),
|
||||
boxes,
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -57,9 +58,10 @@ const RequestListColumnWaterfall = createClass({
|
|||
function timingBoxes(item) {
|
||||
let { eventTimings, fromCache, fromServiceWorker, totalTime } = item;
|
||||
let boxes = [];
|
||||
let tooltip = [];
|
||||
|
||||
if (fromCache || fromServiceWorker) {
|
||||
return boxes;
|
||||
return { boxes, tooltip };
|
||||
}
|
||||
|
||||
if (eventTimings) {
|
||||
|
@ -77,6 +79,7 @@ function timingBoxes(item) {
|
|||
style: { width },
|
||||
})
|
||||
);
|
||||
tooltip.push(L10N.getFormatStr("netmonitor.waterfall.tooltip." + key, width));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,9 +93,10 @@ function timingBoxes(item) {
|
|||
title,
|
||||
}, title)
|
||||
);
|
||||
tooltip.push(L10N.getFormatStr("netmonitor.waterfall.tooltip.total", totalTime));
|
||||
}
|
||||
|
||||
return boxes;
|
||||
return { boxes, tooltip: tooltip.join(", ") };
|
||||
}
|
||||
|
||||
module.exports = RequestListColumnWaterfall;
|
||||
|
|
|
@ -43,29 +43,35 @@ function StatusBar({ summary, openStatistics, timingMarkers }) {
|
|||
div({ className: "devtools-toolbar devtools-status-bottom" },
|
||||
button({
|
||||
className: "devtools-button requests-list-network-summary-button",
|
||||
title: L10N.getStr("networkMenu.summary.tooltip.perf"),
|
||||
onClick: openStatistics,
|
||||
},
|
||||
div({ className: "summary-info-icon" }),
|
||||
),
|
||||
div({ className: "status-bar-label requests-list-network-summary-count" },
|
||||
countText
|
||||
),
|
||||
div({
|
||||
className: "status-bar-label requests-list-network-summary-count",
|
||||
title: L10N.getStr("networkMenu.summary.tooltip.requestsCount"),
|
||||
}, countText),
|
||||
count !== 0 &&
|
||||
div({ className: "status-bar-label requests-list-network-summary-transfer" },
|
||||
transferText
|
||||
),
|
||||
div({
|
||||
className: "status-bar-label requests-list-network-summary-transfer",
|
||||
title: L10N.getStr("networkMenu.summary.tooltip.transferred"),
|
||||
}, transferText),
|
||||
count !== 0 &&
|
||||
div({ className: "status-bar-label requests-list-network-summary-finish" },
|
||||
finishText
|
||||
),
|
||||
div({
|
||||
className: "status-bar-label requests-list-network-summary-finish",
|
||||
title: L10N.getStr("networkMenu.summary.tooltip.finish"),
|
||||
}, finishText),
|
||||
DOMContentLoaded > -1 &&
|
||||
div({ className: "status-bar-label dom-content-loaded" },
|
||||
`DOMContentLoaded: ${getFormattedTime(DOMContentLoaded)}`
|
||||
),
|
||||
div({
|
||||
className: "status-bar-label dom-content-loaded",
|
||||
title: L10N.getStr("networkMenu.summary.tooltip.domContentLoaded"),
|
||||
}, `DOMContentLoaded: ${getFormattedTime(DOMContentLoaded)}`),
|
||||
load > -1 &&
|
||||
div({ className: "status-bar-label load" },
|
||||
`load: ${getFormattedTime(load)}`
|
||||
),
|
||||
div({
|
||||
className: "status-bar-label load",
|
||||
title: L10N.getStr("networkMenu.summary.tooltip.load"),
|
||||
}, `load: ${getFormattedTime(load)}`),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ const HEADER_FILTERS = HEADERS
|
|||
const FILTER_FLAGS = [
|
||||
...HEADER_FILTERS,
|
||||
"scheme",
|
||||
"set-cookie-domain",
|
||||
"set-cookie-name",
|
||||
"set-cookie-value",
|
||||
"mime-type",
|
||||
"larger-than",
|
||||
"is",
|
||||
|
@ -117,6 +120,8 @@ function getSizeOrder(size) {
|
|||
|
||||
function isFlagFilterMatch(item, { type, value, negative }) {
|
||||
let match = true;
|
||||
let { responseCookies = { cookies: [] } } = item;
|
||||
responseCookies = responseCookies.cookies || responseCookies;
|
||||
switch (type) {
|
||||
case "status-code":
|
||||
match = item.status === value;
|
||||
|
@ -177,6 +182,24 @@ function isFlagFilterMatch(item, { type, value, negative }) {
|
|||
let scheme = new URL(item.url).protocol.replace(":", "").toLowerCase();
|
||||
match = scheme === value;
|
||||
break;
|
||||
case "set-cookie-domain":
|
||||
if (responseCookies.length > 0) {
|
||||
let host = item.urlDetails.host;
|
||||
let i = responseCookies.findIndex(c => {
|
||||
let domain = c.hasOwnProperty("domain") ? c.domain : host;
|
||||
return domain === value;
|
||||
});
|
||||
match = i > -1;
|
||||
} else {
|
||||
match = false;
|
||||
}
|
||||
break;
|
||||
case "set-cookie-name":
|
||||
match = responseCookies.findIndex(c => c.name.toLowerCase() === value) > -1;
|
||||
break;
|
||||
case "set-cookie-value":
|
||||
match = responseCookies.findIndex(c => c.value.toLowerCase() === value) > -1;
|
||||
break;
|
||||
}
|
||||
if (negative) {
|
||||
return !match;
|
||||
|
|
|
@ -61,7 +61,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
parseURLEncodedText,
|
||||
parseURLParams,
|
||||
getSelectableInInspectorGrips,
|
||||
maybeEscapePropertyName
|
||||
maybeEscapePropertyName,
|
||||
getGripPreviewItems
|
||||
} = __webpack_require__(3);
|
||||
|
||||
module.exports = {
|
||||
|
@ -72,7 +73,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
maybeEscapePropertyName,
|
||||
parseURLEncodedText,
|
||||
parseURLParams,
|
||||
getSelectableInInspectorGrips
|
||||
getSelectableInInspectorGrips,
|
||||
getGripPreviewItems
|
||||
};
|
||||
|
||||
/***/ },
|
||||
|
@ -576,13 +578,23 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
// Event Grip
|
||||
if (grip.preview && grip.preview.target) {
|
||||
return [grip.preview.target];
|
||||
let keys = Object.keys(grip.preview.properties);
|
||||
let values = Object.values(grip.preview.properties);
|
||||
return [grip.preview.target, ...keys, ...values];
|
||||
}
|
||||
|
||||
// RegEx Grip
|
||||
if (grip.displayString) {
|
||||
return [grip.displayString];
|
||||
}
|
||||
|
||||
// Generic Grip
|
||||
if (grip.preview && grip.preview.ownProperties) {
|
||||
let propertiesValues = Object.values(grip.preview.ownProperties).map(property => property.value || property);
|
||||
|
||||
let propertyKeys = Object.keys(grip.preview.ownProperties);
|
||||
propertiesValues = propertiesValues.concat(propertyKeys);
|
||||
|
||||
// ArrayBuffer Grip
|
||||
if (grip.preview.safeGetterValues) {
|
||||
propertiesValues = propertiesValues.concat(Object.values(grip.preview.safeGetterValues).map(property => property.getterValue || property));
|
||||
|
@ -596,7 +608,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
/**
|
||||
* Returns a new element wrapped with a component, props.objectLink if it exists,
|
||||
* or a span if there are multiple childs, or directly the child if only one is passed.
|
||||
* or a span if there are multiple children, or directly the child if only one is passed.
|
||||
*
|
||||
* @param {Object} props A Rep "props" object that may contain `objectLink`
|
||||
* and `object` properties.
|
||||
|
@ -639,7 +651,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
getURLDisplayString,
|
||||
getSelectableInInspectorGrips,
|
||||
maybeEscapePropertyName,
|
||||
safeObjectLink
|
||||
safeObjectLink,
|
||||
getGripPreviewItems
|
||||
};
|
||||
|
||||
/***/ },
|
||||
|
|
|
@ -20,26 +20,26 @@
|
|||
}
|
||||
|
||||
@keyframes anim-simple {
|
||||
from { color: black; }
|
||||
to { color: white; }
|
||||
from { color: rgb(0, 0, 0); }
|
||||
to { color: rgb(255, 255, 255); }
|
||||
}
|
||||
|
||||
@keyframes anim-simple-three {
|
||||
from { color: black; }
|
||||
50% { color: blue; }
|
||||
to { color: white; }
|
||||
from { color: rgb(0, 0, 0); }
|
||||
50% { color: rgb(0, 0, 255); }
|
||||
to { color: rgb(255, 255, 255); }
|
||||
}
|
||||
|
||||
@keyframes anim-simple-timing {
|
||||
from { color: black; animation-timing-function: linear; }
|
||||
50% { color: blue; animation-timing-function: ease-in-out; }
|
||||
to { color: white; animation-timing-function: step-end; }
|
||||
from { color: rgb(0, 0, 0); animation-timing-function: linear; }
|
||||
50% { color: rgb(0, 0, 255); animation-timing-function: ease-in-out; }
|
||||
to { color: rgb(255, 255, 255); animation-timing-function: step-end; }
|
||||
}
|
||||
|
||||
@keyframes anim-simple-timing-some {
|
||||
from { color: black; animation-timing-function: linear; }
|
||||
50% { color: blue; }
|
||||
to { color: white; }
|
||||
from { color: rgb(0, 0, 0); animation-timing-function: linear; }
|
||||
50% { color: rgb(0, 0, 255); }
|
||||
to { color: rgb(255, 255, 255); }
|
||||
}
|
||||
|
||||
@keyframes anim-simple-shorthand {
|
||||
|
@ -48,15 +48,15 @@
|
|||
}
|
||||
|
||||
@keyframes anim-omit-to {
|
||||
from { color: blue; }
|
||||
from { color: rgb(0, 0, 255); }
|
||||
}
|
||||
|
||||
@keyframes anim-omit-from {
|
||||
to { color: blue; }
|
||||
to { color: rgb(0, 0, 255); }
|
||||
}
|
||||
|
||||
@keyframes anim-omit-from-to {
|
||||
50% { color: blue; }
|
||||
50% { color: rgb(0, 0, 255); }
|
||||
}
|
||||
|
||||
@keyframes anim-partially-omit-to {
|
||||
|
@ -67,29 +67,29 @@
|
|||
}
|
||||
|
||||
@keyframes anim-different-props {
|
||||
from { color: black; margin-top: 8px; }
|
||||
25% { color: blue; }
|
||||
from { color: rgb(0, 0, 0); margin-top: 8px; }
|
||||
25% { color: rgb(0, 0, 255); }
|
||||
75% { margin-top: 12px; }
|
||||
to { color: white; margin-top: 16px }
|
||||
to { color: rgb(255, 255, 255); margin-top: 16px }
|
||||
}
|
||||
|
||||
@keyframes anim-different-props-and-easing {
|
||||
from { color: black; margin-top: 8px; animation-timing-function: linear; }
|
||||
25% { color: blue; animation-timing-function: step-end; }
|
||||
from { color: rgb(0, 0, 0); margin-top: 8px; animation-timing-function: linear; }
|
||||
25% { color: rgb(0, 0, 255); animation-timing-function: step-end; }
|
||||
75% { margin-top: 12px; animation-timing-function: ease-in; }
|
||||
to { color: white; margin-top: 16px }
|
||||
to { color: rgb(255, 255, 255); margin-top: 16px }
|
||||
}
|
||||
|
||||
@keyframes anim-merge-offset {
|
||||
from { color: black; }
|
||||
to { color: white; }
|
||||
from { color: rgb(0, 0, 0); }
|
||||
to { color: rgb(255, 255, 255); }
|
||||
from { margin-top: 8px; }
|
||||
to { margin-top: 16px; }
|
||||
}
|
||||
|
||||
@keyframes anim-merge-offset-and-easing {
|
||||
from { color: black; animation-timing-function: step-end; }
|
||||
to { color: white; }
|
||||
from { color: rgb(0, 0, 0); animation-timing-function: step-end; }
|
||||
to { color: rgb(255, 255, 255); }
|
||||
from { margin-top: 8px; animation-timing-function: linear; }
|
||||
to { margin-top: 16px; }
|
||||
from { font-size: 16px; animation-timing-function: step-end; }
|
||||
|
@ -300,7 +300,7 @@ test(function(t) {
|
|||
var div = addDiv(t);
|
||||
|
||||
div.style.animation = 'anim-omit-to 100s';
|
||||
div.style.color = 'white';
|
||||
div.style.color = 'rgb(255, 255, 255)';
|
||||
var frames = getKeyframes(div);
|
||||
|
||||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
@ -322,7 +322,7 @@ test(function(t) {
|
|||
var div = addDiv(t);
|
||||
|
||||
div.style.animation = 'anim-omit-from 100s';
|
||||
div.style.color = 'white';
|
||||
div.style.color = 'rgb(255, 255, 255)';
|
||||
var frames = getKeyframes(div);
|
||||
|
||||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
@ -344,7 +344,7 @@ test(function(t) {
|
|||
var div = addDiv(t);
|
||||
|
||||
div.style.animation = 'anim-omit-from-to 100s';
|
||||
div.style.color = 'white';
|
||||
div.style.color = 'rgb(255, 255, 255)';
|
||||
var frames = getKeyframes(div);
|
||||
|
||||
assert_equals(frames.length, 3, "number of frames");
|
||||
|
@ -570,7 +570,9 @@ test(function(t) {
|
|||
test(function(t) {
|
||||
var div = addDiv(t);
|
||||
|
||||
div.style.textShadow = '1px 1px 2px black, 0 0 16px blue, 0 0 3.2px blue';
|
||||
div.style.textShadow = '1px 1px 2px rgb(0, 0, 0), ' +
|
||||
'0 0 16px rgb(0, 0, 255), ' +
|
||||
'0 0 3.2px rgb(0, 0, 255)';
|
||||
div.style.animation = 'anim-text-shadow 100s';
|
||||
var frames = getKeyframes(div);
|
||||
|
||||
|
|
|
@ -258,11 +258,6 @@ DOMInterfaces = {
|
|||
'binaryNames': { 'ownerRule': 'DOMOwnerRule' },
|
||||
},
|
||||
|
||||
'CSSSupportsRule': {
|
||||
'nativeType': 'mozilla::CSSSupportsRule',
|
||||
'headerFile': 'nsCSSRules.h',
|
||||
},
|
||||
|
||||
'CSSValue': {
|
||||
'concrete': False
|
||||
},
|
||||
|
|
|
@ -3713,6 +3713,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
|||
mDefaultPlaybackStartPosition(0.0),
|
||||
mIsAudioTrackAudible(false),
|
||||
mHasSuspendTaint(false),
|
||||
mMediaTracksConstructed(false),
|
||||
mVisibilityState(Visibility::UNTRACKED),
|
||||
mErrorSink(new ErrorSink(this)),
|
||||
mAudioChannelWrapper(new AudioChannelAgentCallback(this, mAudioChannel))
|
||||
|
@ -7341,7 +7342,11 @@ HTMLMediaElement::GetDocument() const
|
|||
void
|
||||
HTMLMediaElement::ConstructMediaTracks(const MediaInfo* aInfo)
|
||||
{
|
||||
MOZ_ASSERT(aInfo);
|
||||
if (mMediaTracksConstructed || !aInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMediaTracksConstructed = true;
|
||||
|
||||
AudioTrackList* audioList = AudioTracks();
|
||||
if (audioList && aInfo->HasAudio()) {
|
||||
|
@ -7366,15 +7371,15 @@ HTMLMediaElement::ConstructMediaTracks(const MediaInfo* aInfo)
|
|||
void
|
||||
HTMLMediaElement::RemoveMediaTracks()
|
||||
{
|
||||
AudioTrackList* audioList = AudioTracks();
|
||||
if (audioList) {
|
||||
audioList->RemoveTracks();
|
||||
if (mAudioTrackList) {
|
||||
mAudioTrackList->RemoveTracks();
|
||||
}
|
||||
|
||||
VideoTrackList* videoList = VideoTracks();
|
||||
if (videoList) {
|
||||
videoList->RemoveTracks();
|
||||
if (mVideoTrackList) {
|
||||
mVideoTrackList->RemoveTracks();
|
||||
}
|
||||
|
||||
mMediaTracksConstructed = false;
|
||||
}
|
||||
|
||||
class MediaElementGMPCrashHelper : public GMPCrashHelper
|
||||
|
|
|
@ -1747,6 +1747,10 @@ private:
|
|||
// participate in video decoder suspending.
|
||||
bool mHasSuspendTaint;
|
||||
|
||||
// True if audio tracks and video tracks are constructed and added into the
|
||||
// track list, false if all tracks are removed from the track list.
|
||||
bool mMediaTracksConstructed;
|
||||
|
||||
Visibility mVisibilityState;
|
||||
|
||||
UniquePtr<ErrorSink> mErrorSink;
|
||||
|
|
|
@ -385,7 +385,6 @@ MediaDecoder::MediaDecoder(MediaDecoderOwner* aOwner)
|
|||
, mPlaybackStatistics(new MediaChannelStatistics())
|
||||
, mPinnedForSeek(false)
|
||||
, mMinimizePreroll(false)
|
||||
, mMediaTracksConstructed(false)
|
||||
, mFiredMetadataLoaded(false)
|
||||
, mIsDocumentVisible(false)
|
||||
, mElementVisibility(Visibility::UNTRACKED)
|
||||
|
@ -504,6 +503,9 @@ MediaDecoder::Shutdown()
|
|||
mResource->Close();
|
||||
}
|
||||
|
||||
// Ask the owner to remove its audio/video tracks.
|
||||
GetOwner()->RemoveMediaTracks();
|
||||
|
||||
ChangeState(PLAY_STATE_SHUTDOWN);
|
||||
mOwner = nullptr;
|
||||
}
|
||||
|
@ -774,7 +776,7 @@ void
|
|||
MediaDecoder::OnMetadataUpdate(TimedMetadata&& aMetadata)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RemoveMediaTracks();
|
||||
GetOwner()->RemoveMediaTracks();
|
||||
MetadataLoaded(nsAutoPtr<MediaInfo>(new MediaInfo(*aMetadata.mInfo)),
|
||||
Move(aMetadata.mTags),
|
||||
MediaDecoderEventVisibility::Observable);
|
||||
|
@ -797,7 +799,7 @@ MediaDecoder::MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
|
|||
mMediaSeekable = aInfo->mMediaSeekable;
|
||||
mMediaSeekableOnlyInBufferedRanges = aInfo->mMediaSeekableOnlyInBufferedRanges;
|
||||
mInfo = aInfo.forget();
|
||||
ConstructMediaTracks();
|
||||
GetOwner()->ConstructMediaTracks(mInfo);
|
||||
|
||||
// Make sure the element and the frame (if any) are told about
|
||||
// our new size.
|
||||
|
@ -1164,9 +1166,9 @@ MediaDecoder::ChangeState(PlayState aState)
|
|||
mPlayState = aState;
|
||||
|
||||
if (mPlayState == PLAY_STATE_PLAYING) {
|
||||
ConstructMediaTracks();
|
||||
GetOwner()->ConstructMediaTracks(mInfo);
|
||||
} else if (IsEnded()) {
|
||||
RemoveMediaTracks();
|
||||
GetOwner()->RemoveMediaTracks();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1709,32 +1711,6 @@ MediaDecoder::GetOwner() const
|
|||
return mOwner;
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoder::ConstructMediaTracks()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
|
||||
if (mMediaTracksConstructed || !mInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
GetOwner()->ConstructMediaTracks(mInfo);
|
||||
|
||||
mMediaTracksConstructed = true;
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoder::RemoveMediaTracks()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
|
||||
GetOwner()->RemoveMediaTracks();
|
||||
|
||||
mMediaTracksConstructed = false;
|
||||
}
|
||||
|
||||
MediaDecoderOwner::NextFrameStatus
|
||||
MediaDecoder::NextFrameBufferedStatus()
|
||||
{
|
||||
|
|
|
@ -387,17 +387,6 @@ private:
|
|||
// change. Call on the main thread only.
|
||||
virtual void ChangeState(PlayState aState);
|
||||
|
||||
// Called from MetadataLoaded(). Ask its owner to create audio/video tracks
|
||||
// and adds them to its owner's audio/video track list.
|
||||
// Call on the main thread only.
|
||||
void ConstructMediaTracks();
|
||||
|
||||
// Ask its owner to remove all audio tracks and video tracks that are
|
||||
// previously added into the track list.
|
||||
// Call on the main thread only.
|
||||
void RemoveMediaTracks();
|
||||
|
||||
|
||||
// Called when the video has completed playing.
|
||||
// Call on the main thread only.
|
||||
void PlaybackEnded();
|
||||
|
@ -685,11 +674,6 @@ protected:
|
|||
// or play the media again.
|
||||
bool mMinimizePreroll;
|
||||
|
||||
// True if audio tracks and video tracks are constructed and added into the
|
||||
// owenr's track list, false if all tracks are removed from the owner's track
|
||||
// list.
|
||||
bool mMediaTracksConstructed;
|
||||
|
||||
// True if we've already fired metadataloaded.
|
||||
bool mFiredMetadataLoaded;
|
||||
|
||||
|
|
|
@ -1168,6 +1168,14 @@ class RTCPeerConnection {
|
|||
this._impl.selectSsrc(receiver.track, ssrcIndex);
|
||||
}
|
||||
|
||||
mozAddRIDExtension(receiver, extensionId) {
|
||||
this._impl.addRIDExtension(receiver.track, extensionId);
|
||||
}
|
||||
|
||||
mozAddRIDFilter(receiver, rid) {
|
||||
this._impl.addRIDFilter(receiver.track, rid);
|
||||
}
|
||||
|
||||
get localDescription() {
|
||||
this._checkClosed();
|
||||
let sdp = this._impl.localDescription;
|
||||
|
|
|
@ -192,12 +192,10 @@ skip-if = toolkit == 'android'
|
|||
skip-if = toolkit == 'android'
|
||||
[test_peerConnection_scaleResolution.html]
|
||||
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
# disable test_peerConnection_simulcastOffer.html for Bug 1351590
|
||||
#[test_peerConnection_simulcastOffer.html]
|
||||
#skip-if = android_version # no simulcast support on android
|
||||
# disable test_peerConnection_simulcastAnswer.html for Bug 1351531
|
||||
#[test_peerConnection_simulcastAnswer.html]
|
||||
#skip-if = android_version # no simulcast support on android
|
||||
[test_peerConnection_simulcastOffer.html]
|
||||
skip-if = android_version # no simulcast support on android
|
||||
[test_peerConnection_simulcastAnswer.html]
|
||||
skip-if = android_version # no simulcast support on android
|
||||
#[test_peerConnection_relayOnly.html]
|
||||
[test_peerConnection_callbacks.html]
|
||||
skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
|
|
|
@ -16,12 +16,20 @@
|
|||
var test;
|
||||
var pushPrefs = (...p) => SpecialPowers.pushPrefEnv({set: p});
|
||||
|
||||
function selectRecvSsrc(pc, index) {
|
||||
function addRIDExtension(pc, extensionId) {
|
||||
var receivers = pc._pc.getReceivers();
|
||||
is(receivers.length, 1, "We have exactly one RTP receiver");
|
||||
var receiver = receivers[0];
|
||||
|
||||
SpecialPowers.wrap(pc._pc).mozSelectSsrc(receiver, index);
|
||||
SpecialPowers.wrap(pc._pc).mozAddRIDExtension(receiver, extensionId);
|
||||
}
|
||||
|
||||
function selectRecvRID(pc, rid) {
|
||||
var receivers = pc._pc.getReceivers();
|
||||
is(receivers.length, 1, "We have exactly one RTP receiver");
|
||||
var receiver = receivers[0];
|
||||
|
||||
SpecialPowers.wrap(pc._pc).mozAddRIDFilter(receiver, rid);
|
||||
}
|
||||
|
||||
runNetworkTest(() =>
|
||||
|
@ -76,11 +84,17 @@
|
|||
}
|
||||
]);
|
||||
|
||||
test.chain.insertAfter('PC_REMOTE_WAIT_FOR_MEDIA_FLOW',[
|
||||
function PC_REMOTE_SET_RTP_FIRST_RID(test) {
|
||||
// Cause pcLocal to filter out everything but the first SSRC. This
|
||||
// lets only one of the simulcast streams through.
|
||||
selectRecvSsrc(test.pcLocal, 0);
|
||||
// do this after set remote description so the MediaPipeline
|
||||
// has been created.
|
||||
test.chain.insertAfter('PC_LOCAL_SET_REMOTE_DESCRIPTION',[
|
||||
function PC_LOCAL_SET_RTP_FIRST_RID(test) {
|
||||
var extmap_id = test._local_offer.sdp.match(
|
||||
"a=extmap:([0-9+])/recvonly urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id");
|
||||
ok(extmap_id, "Local offer has extmap id for simulcast: " + extmap_id[1]);
|
||||
// Cause pcLocal to filter out everything but RID "bar", only
|
||||
// allowing one of the simulcast streams through.
|
||||
addRIDExtension(test.pcLocal, extmap_id[1]);
|
||||
selectRecvRID(test.pcLocal, "bar");
|
||||
}
|
||||
]);
|
||||
|
||||
|
@ -101,9 +115,9 @@
|
|||
is(vremote.videoHeight, vlocal.videoHeight / 2, "sink is 1/2 height of source");
|
||||
},
|
||||
function PC_LOCAL_SET_RTP_SECOND_RID(test) {
|
||||
// Now, cause pcLocal to filter out everything but the second SSRC.
|
||||
// This lets only the other simulcast stream through.
|
||||
selectRecvSsrc(test.pcLocal, 1);
|
||||
// Now, cause pcLocal to filter out everything but RID "foo", only
|
||||
// allowing the other simulcast stream through.
|
||||
selectRecvRID(test.pcLocal, "foo");
|
||||
},
|
||||
function PC_LOCAL_WAIT_FOR_SECOND_MEDIA_FLOW(test) {
|
||||
return test.pcLocal.waitForMediaFlow();
|
||||
|
|
|
@ -16,12 +16,20 @@
|
|||
var test;
|
||||
var pushPrefs = (...p) => SpecialPowers.pushPrefEnv({set: p});
|
||||
|
||||
function selectRecvSsrc(pc, index) {
|
||||
function addRIDExtension(pc, extensionId) {
|
||||
var receivers = pc._pc.getReceivers();
|
||||
is(receivers.length, 1, "We have exactly one RTP receiver");
|
||||
var receiver = receivers[0];
|
||||
|
||||
SpecialPowers.wrap(pc._pc).mozSelectSsrc(receiver, index);
|
||||
SpecialPowers.wrap(pc._pc).mozAddRIDExtension(receiver, extensionId);
|
||||
}
|
||||
|
||||
function selectRecvRID(pc, rid) {
|
||||
var receivers = pc._pc.getReceivers();
|
||||
is(receivers.length, 1, "We have exactly one RTP receiver");
|
||||
var receiver = receivers[0];
|
||||
|
||||
SpecialPowers.wrap(pc._pc).mozAddRIDFilter(receiver, rid);
|
||||
}
|
||||
|
||||
runNetworkTest(() =>
|
||||
|
@ -68,11 +76,17 @@
|
|||
}
|
||||
]);
|
||||
|
||||
test.chain.insertAfter('PC_REMOTE_WAIT_FOR_MEDIA_FLOW',[
|
||||
// do this after set local description so the MediaPipeline
|
||||
// has been created.
|
||||
test.chain.insertAfter('PC_REMOTE_SET_LOCAL_DESCRIPTION',[
|
||||
function PC_REMOTE_SET_RTP_FIRST_RID(test) {
|
||||
// Cause pcRemote to filter out everything but the first SSRC. This
|
||||
// lets only one of the simulcast streams through.
|
||||
selectRecvSsrc(test.pcRemote, 0);
|
||||
var extmap_id = test.originalOffer.sdp.match(
|
||||
"a=extmap:([0-9+])/sendonly urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id");
|
||||
ok(extmap_id, "Original offer has extmap id for simulcast: " + extmap_id[1]);
|
||||
// Cause pcRemote to filter out everything but RID "foo", only
|
||||
// allowing one of the simulcast streams through.
|
||||
addRIDExtension(test.pcRemote, extmap_id[1]);
|
||||
selectRecvRID(test.pcRemote, "foo");
|
||||
}
|
||||
]);
|
||||
|
||||
|
@ -89,13 +103,13 @@
|
|||
ok(vremote, "Should have remote video element for pcRemote");
|
||||
ok(vlocal.videoWidth > 0, "source width is positive");
|
||||
ok(vlocal.videoHeight > 0, "source height is positive");
|
||||
is(vremote.videoWidth, vlocal.videoWidth / 2, "sink is 1/2 width of source");
|
||||
is(vremote.videoHeight, vlocal.videoHeight / 2, "sink is 1/2 height of source");
|
||||
is(vremote.videoWidth, vlocal.videoWidth, "sink is same width as source");
|
||||
is(vremote.videoHeight, vlocal.videoHeight, "sink is same height as source");
|
||||
},
|
||||
function PC_REMOTE_SET_RTP_SECOND_RID(test) {
|
||||
// Now, cause pcRemote to filter out everything but the second SSRC.
|
||||
// This lets only the other simulcast stream through.
|
||||
selectRecvSsrc(test.pcRemote, 1);
|
||||
// Now, cause pcRemote to filter out everything but RID "bar", only
|
||||
// allowing the other simulcast stream through.
|
||||
selectRecvRID(test.pcRemote, "bar");
|
||||
},
|
||||
function PC_REMOTE_WAIT_FOR_SECOND_MEDIA_FLOW(test) {
|
||||
return test.pcRemote.waitForMediaFlow();
|
||||
|
@ -119,8 +133,8 @@
|
|||
ok(vremote, "Should have remote video element for pcRemote");
|
||||
ok(vlocal.videoWidth > 0, "source width is positive");
|
||||
ok(vlocal.videoHeight > 0, "source height is positive");
|
||||
is(vremote.videoWidth, vlocal.videoWidth, "sink is same width as source");
|
||||
is(vremote.videoHeight, vlocal.videoHeight, "sink is same height as source");
|
||||
is(vremote.videoWidth, vlocal.videoWidth / 2, "sink is 1/2 width of source");
|
||||
is(vremote.videoHeight, vlocal.videoHeight / 2, "sink is 1/2 height of source");
|
||||
},
|
||||
]);
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ skip-if = !crashreporter
|
|||
skip-if = !crashreporter
|
||||
[test_bug1028200-7.html]
|
||||
skip-if = !crashreporter
|
||||
[test_bug406541.html]
|
||||
[test_bug532208.html]
|
||||
[test_bug539565-1.html]
|
||||
[test_bug539565-2.html]
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 406541</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="plugin-utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/x-child-payload" id="child-payload">
|
||||
// This is injected into the file:/// origin iframe, see below.
|
||||
|
||||
// appletA should spawn, appletB, with a codebase outside the temp directory,
|
||||
// should not.
|
||||
var appletA = document.createElement("applet");
|
||||
var appletB = document.createElement("applet");
|
||||
var appletC = document.createElement("applet");
|
||||
appletA.type = appletB.type = appletC.type = "application/x-java-test";
|
||||
appletB.setAttribute("codebase", "file:///");
|
||||
appletC.setAttribute("codebase", "./subdir_bug406541/");
|
||||
document.body.appendChild(appletA);
|
||||
document.body.appendChild(appletB);
|
||||
document.body.appendChild(appletC);
|
||||
function isSpawned(plugin) {
|
||||
try {
|
||||
var x = plugin.getJavaCodebase();
|
||||
return true;
|
||||
} catch (e) {}
|
||||
return false;
|
||||
}
|
||||
window.parent.postMessage({ "A": isSpawned(appletA),
|
||||
"B": isSpawned(appletB),
|
||||
"C": isSpawned(appletC) }, "*");
|
||||
</script>
|
||||
<script type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED,
|
||||
"Java Test Plug-in");
|
||||
SpecialPowers.pushPrefEnv({ "set": [
|
||||
['plugin.java.mime', 'application/x-java-test']
|
||||
] }, runTest);
|
||||
|
||||
function runTest() {
|
||||
// Create a empty file and point an iframe at it
|
||||
var Cc = SpecialPowers.Cc;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var file = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("TmpD", Ci.nsIFile);
|
||||
var subdir = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("TmpD", Ci.nsIFile);
|
||||
file.append("test_bug406541.html");
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
|
||||
subdir.append("subdir_bug406541");
|
||||
subdir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0600);
|
||||
|
||||
var i = document.createElement("iframe");
|
||||
var loaded = false;
|
||||
i.addEventListener("load", function initialLoad() {
|
||||
if (!loaded) {
|
||||
// Once loaded, use special powers to point it at the file
|
||||
SpecialPowers.wrap(i.contentWindow).location.href = "file://" + file.path;
|
||||
loaded = true;
|
||||
} else {
|
||||
// Inject the child-payload script to the file:/// origin. Let it test
|
||||
// applet spawning and send the results in a postMessage. (Because I
|
||||
// couldn't get SpecialPowers to let me touch applets cross-origin, then
|
||||
// gave up.)
|
||||
var innerdoc = SpecialPowers.wrap(i.contentWindow).document;
|
||||
var s = innerdoc.createElement("script");
|
||||
s.type = "text/javascript";
|
||||
s.textContent = document.getElementById("child-payload").textContent;
|
||||
var finished = false;
|
||||
window.onmessage = function(message) {
|
||||
ok(message.data.A, "Plugin A should spawn");
|
||||
ok(!message.data.B, "Plugin B should NOT spawn");
|
||||
ok(message.data.C, "Plugin C should spawn");
|
||||
file.remove(false);
|
||||
subdir.remove(false);
|
||||
finished = true;
|
||||
SimpleTest.finish();
|
||||
};
|
||||
innerdoc.body.appendChild(s);
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
if (!finished) {
|
||||
ok(finished, "Should have received callback by now");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
document.body.appendChild(i);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -9,6 +9,7 @@
|
|||
interface ListBoxObject : BoxObject {
|
||||
|
||||
long getRowCount();
|
||||
long getRowHeight();
|
||||
long getNumberOfVisibleRows();
|
||||
long getIndexOfFirstVisibleRow();
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ interface PeerConnectionImpl {
|
|||
sequence<MediaStream> getRemoteStreams();
|
||||
|
||||
void selectSsrc(MediaStreamTrack recvTrack, unsigned short ssrcIndex);
|
||||
void addRIDExtension(MediaStreamTrack recvTrack, unsigned short extensionId);
|
||||
void addRIDFilter(MediaStreamTrack recvTrack, DOMString rid);
|
||||
|
||||
/* As the ICE candidates roll in this one should be called each time
|
||||
* in order to keep the candidate list up-to-date for the next SDP-related
|
||||
|
|
|
@ -121,6 +121,10 @@ interface RTCPeerConnection : EventTarget {
|
|||
|
||||
[ChromeOnly]
|
||||
void mozSelectSsrc(RTCRtpReceiver receiver, unsigned short ssrcIndex);
|
||||
[ChromeOnly]
|
||||
void mozAddRIDExtension(RTCRtpReceiver receiver, unsigned short extensionId);
|
||||
[ChromeOnly]
|
||||
void mozAddRIDFilter(RTCRtpReceiver receiver, DOMString rid);
|
||||
|
||||
void close ();
|
||||
attribute EventHandler onnegotiationneeded;
|
||||
|
|
|
@ -248,13 +248,15 @@ nsXBLResourceLoader::NotifyBoundElements()
|
|||
if (shell) {
|
||||
nsIFrame* childFrame = content->GetPrimaryFrame();
|
||||
if (!childFrame) {
|
||||
// Check to see if it's in the undisplayed content map.
|
||||
//
|
||||
// FIXME(emilio, bug 1359384): What about display: contents stuff?
|
||||
// Looks like this would be inefficient in that case?
|
||||
// Check to see if it's in the undisplayed content map, or the
|
||||
// display: contents map.
|
||||
nsStyleContext* sc =
|
||||
shell->FrameManager()->GetUndisplayedContent(content);
|
||||
|
||||
if (!sc) {
|
||||
sc = shell->FrameManager()->GetDisplayContentsStyleFor(content);
|
||||
}
|
||||
|
||||
if (!sc) {
|
||||
shell->PostRecreateFramesFor(content->AsElement());
|
||||
}
|
||||
|
|
|
@ -504,6 +504,9 @@ public:
|
|||
/**
|
||||
* Returns a DataSourceSurface with the same data as this one, but
|
||||
* guaranteed to have surface->GetType() == SurfaceType::DATA.
|
||||
*
|
||||
* The returning surface might be null, because of OOM or gfx device reset.
|
||||
* The caller needs to do null-check before using it.
|
||||
*/
|
||||
virtual already_AddRefed<DataSourceSurface> GetDataSurface() override;
|
||||
|
||||
|
|
|
@ -2712,6 +2712,7 @@ gfxFont::ShapeText(DrawTarget *aDrawTarget,
|
|||
if (gfxPlatform::GetPlatform()->UseGraphiteShaping()) {
|
||||
if (!mGraphiteShaper) {
|
||||
mGraphiteShaper = MakeUnique<gfxGraphiteShaper>(this);
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::BROWSER_USAGE_GRAPHITE, 1);
|
||||
}
|
||||
ok = mGraphiteShaper->ShapeText(aDrawTarget, aText, aOffset, aLength,
|
||||
aScript, aVertical, aRounding,
|
||||
|
|
|
@ -16,7 +16,7 @@ struct nsCSSSelector;
|
|||
|
||||
// Defines for various style related constants
|
||||
|
||||
enum nsChangeHint {
|
||||
enum nsChangeHint : uint32_t {
|
||||
nsChangeHint_Empty = 0,
|
||||
|
||||
// change was visual only (e.g., COLOR=)
|
||||
|
@ -472,7 +472,7 @@ NS_RemoveSubsumedHints(nsChangeHint aOurChange, nsChangeHint aHintsHandled)
|
|||
* NOTE: When adding new restyle hints, please also add them to
|
||||
* RestyleManager::RestyleHintToString.
|
||||
*/
|
||||
enum nsRestyleHint {
|
||||
enum nsRestyleHint : uint32_t {
|
||||
// Rerun selector matching on the element. If a new style context
|
||||
// results, update the style contexts of descendants. (Irrelevant if
|
||||
// eRestyle_Subtree is also set, since that implies a superset of the
|
||||
|
|
|
@ -636,7 +636,7 @@ load 1233191.html
|
|||
asserts-if(stylo,0-15) load 1271765.html # bug 1324684
|
||||
asserts(2) load 1272983-1.html # bug 586628
|
||||
asserts(2) load 1272983-2.html # bug 586628
|
||||
asserts-if(stylo,2) load 1275059.html # Bug 1360221
|
||||
load 1275059.html
|
||||
load 1278007.html
|
||||
load 1278080.html
|
||||
load 1279814.html
|
||||
|
|
|
@ -5526,7 +5526,7 @@ nsTextFrame::UpdateTextEmphasis(WritingMode aWM, PropertyProvider& aProvider)
|
|||
nsStyleContext* styleContext = StyleContext();
|
||||
bool isTextCombined = styleContext->IsTextCombined();
|
||||
if (isTextCombined) {
|
||||
styleContext = styleContext->GetParent();
|
||||
styleContext = GetParent()->StyleContext();
|
||||
}
|
||||
RefPtr<nsFontMetrics> fm = nsLayoutUtils::
|
||||
GetFontMetricsOfEmphasisMarks(styleContext, GetFontSizeInflation());
|
||||
|
|
|
@ -354,7 +354,7 @@ static inline void PrintAsStringNewline(const char *s = nullptr) {
|
|||
fflush (stderr);
|
||||
}
|
||||
|
||||
static inline void PrintAsFormatString(const char *fmt, ...) {
|
||||
static inline MOZ_FORMAT_PRINTF(1, 2) void PrintAsFormatString(const char *fmt, ...) {
|
||||
va_list vl;
|
||||
va_start(vl, fmt);
|
||||
vfprintf (stderr, fmt, vl);
|
||||
|
@ -368,7 +368,7 @@ static inline void PrintAsString(const mozilla::gfx::Rect& r) {}
|
|||
static inline void PrintAsString(const mozilla::gfx::Float f) {}
|
||||
static inline void PrintAsString(const char *s) {}
|
||||
static inline void PrintAsStringNewline(const char *s = nullptr) {}
|
||||
static inline void PrintAsFormatString(const char *fmt, ...) {}
|
||||
static inline MOZ_FORMAT_PRINTF(1, 2) void PrintAsFormatString(const char *fmt, ...) {}
|
||||
#endif
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -756,10 +756,10 @@ fuzzy-if(OSX||winWidget,93,300) == css-writing-modes-3/float-vrl-006.xht css21/r
|
|||
fuzzy-if(OSX||winWidget,93,300) == css-writing-modes-3/float-vrl-008.xht css21/reference/ref-filled-green-100px-square.xht
|
||||
fuzzy-if(OSX||winWidget,93,300) == css-writing-modes-3/float-vrl-010.xht css21/reference/ref-filled-green-100px-square.xht
|
||||
fuzzy-if(OSX||winWidget,93,300) == css-writing-modes-3/float-vrl-012.xht css21/reference/ref-filled-green-100px-square.xht
|
||||
fails-if(stylo) != css-writing-modes-3/full-width-001.html css-writing-modes-3/reference/full-width-001-horizontal-notref.html
|
||||
fails-if(stylo) != css-writing-modes-3/full-width-001.html css-writing-modes-3/reference/full-width-001-nofullwidth-notref.html
|
||||
fails-if(stylo) != css-writing-modes-3/full-width-002.html css-writing-modes-3/reference/full-width-002-notcu-notref.html
|
||||
fails-if(stylo) != css-writing-modes-3/full-width-002.html css-writing-modes-3/reference/full-width-002-horizontal-notref.html
|
||||
!= css-writing-modes-3/full-width-001.html css-writing-modes-3/reference/full-width-001-horizontal-notref.html
|
||||
!= css-writing-modes-3/full-width-001.html css-writing-modes-3/reference/full-width-001-nofullwidth-notref.html
|
||||
!= css-writing-modes-3/full-width-002.html css-writing-modes-3/reference/full-width-002-notcu-notref.html
|
||||
!= css-writing-modes-3/full-width-002.html css-writing-modes-3/reference/full-width-002-horizontal-notref.html
|
||||
skip != css-writing-modes-3/full-width-003.html css-writing-modes-3/reference/full-width-002-notcu-notref.html
|
||||
skip != css-writing-modes-3/full-width-003.html css-writing-modes-3/reference/full-width-002-horizontal-notref.html
|
||||
fuzzy-if(OSX||winWidget,62,404) == css-writing-modes-3/height-width-inline-non-replaced-vlr-003.xht css21/reference/ref-filled-green-100px-square.xht
|
||||
|
@ -937,15 +937,15 @@ fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-vrl-002.xh
|
|||
fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-vrl-004.xht css-writing-modes-3/text-baseline-vrl-002-ref.xht
|
||||
fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-vrl-006.xht css-writing-modes-3/text-baseline-vrl-006-ref.xht
|
||||
fuzzy-if(OSX,15,16) == css-writing-modes-3/text-combine-upright-decorations-001.html css-writing-modes-3/reference/text-combine-upright-decorations-001.html
|
||||
fails-if(stylo) == css-writing-modes-3/text-combine-upright-inherit-all-001.html css-writing-modes-3/reference/text-combine-upright-inherit-all-001.html
|
||||
fails-if(stylo) == css-writing-modes-3/text-combine-upright-inherit-all-002.html css-writing-modes-3/reference/text-combine-upright-inherit-all-002.html
|
||||
fails-if(stylo) == css-writing-modes-3/text-combine-upright-layout-rules-001.html css-writing-modes-3/reference/text-combine-upright-layout-rules-001-ref.html
|
||||
fails-if(stylo) == css-writing-modes-3/text-combine-upright-line-breaking-rules-001.html css-writing-modes-3/text-combine-upright-line-breaking-rules-001-ref.html
|
||||
fuzzy(255,960) fails-if(stylo) == css-writing-modes-3/text-combine-upright-value-all-001.html css-writing-modes-3/reference/text-combine-upright-value-single-character.html
|
||||
fuzzy(255,960) fails-if(stylo) == css-writing-modes-3/text-combine-upright-value-all-002.html css-writing-modes-3/reference/vertical-ahem-1x1-ref.html
|
||||
fuzzy(255,960) fails-if(stylo) != css-writing-modes-3/text-combine-upright-value-all-002.html css-writing-modes-3/reference/horizontal-ahem-1x1-notref.html
|
||||
fuzzy(255,960) fails-if(stylo) == css-writing-modes-3/text-combine-upright-value-all-003.html css-writing-modes-3/reference/vertical-ahem-1x1-ref.html
|
||||
fuzzy(255,960) fails-if(stylo) != css-writing-modes-3/text-combine-upright-value-all-003.html css-writing-modes-3/reference/horizontal-ahem-1x1-notref.html
|
||||
== css-writing-modes-3/text-combine-upright-inherit-all-001.html css-writing-modes-3/reference/text-combine-upright-inherit-all-001.html
|
||||
== css-writing-modes-3/text-combine-upright-inherit-all-002.html css-writing-modes-3/reference/text-combine-upright-inherit-all-002.html
|
||||
== css-writing-modes-3/text-combine-upright-layout-rules-001.html css-writing-modes-3/reference/text-combine-upright-layout-rules-001-ref.html
|
||||
== css-writing-modes-3/text-combine-upright-line-breaking-rules-001.html css-writing-modes-3/text-combine-upright-line-breaking-rules-001-ref.html
|
||||
fuzzy(255,960) == css-writing-modes-3/text-combine-upright-value-all-001.html css-writing-modes-3/reference/text-combine-upright-value-single-character.html
|
||||
fuzzy(255,960) == css-writing-modes-3/text-combine-upright-value-all-002.html css-writing-modes-3/reference/vertical-ahem-1x1-ref.html
|
||||
fuzzy(255,960) != css-writing-modes-3/text-combine-upright-value-all-002.html css-writing-modes-3/reference/horizontal-ahem-1x1-notref.html
|
||||
fuzzy(255,960) == css-writing-modes-3/text-combine-upright-value-all-003.html css-writing-modes-3/reference/vertical-ahem-1x1-ref.html
|
||||
fuzzy(255,960) != css-writing-modes-3/text-combine-upright-value-all-003.html css-writing-modes-3/reference/horizontal-ahem-1x1-notref.html
|
||||
skip == css-writing-modes-3/text-combine-upright-value-digits2-001.html css-writing-modes-3/reference/text-combine-upright-value-single-character.html
|
||||
skip == css-writing-modes-3/text-combine-upright-value-digits2-002.html css-writing-modes-3/reference/vertical-ahem-1x1-ref.html
|
||||
skip != css-writing-modes-3/text-combine-upright-value-digits2-002.html css-writing-modes-3/reference/horizontal-ahem-1x1-notref.html
|
||||
|
|
|
@ -14,8 +14,8 @@ skip-if(stylo) == ruby-inlinize-blocks-005.html ruby-inlinize-blocks-005-ref.htm
|
|||
# Tests for ruby with text-combine-upright
|
||||
fails-if(stylo) == ruby-text-combine-upright-001a.html ruby-text-combine-upright-001-ref.html
|
||||
fails-if(stylo) == ruby-text-combine-upright-001b.html ruby-text-combine-upright-001-ref.html
|
||||
fails-if(stylo) == ruby-text-combine-upright-002a.html ruby-text-combine-upright-002-ref.html
|
||||
fails-if(stylo) == ruby-text-combine-upright-002b.html ruby-text-combine-upright-002-ref.html
|
||||
== ruby-text-combine-upright-002a.html ruby-text-combine-upright-002-ref.html
|
||||
== ruby-text-combine-upright-002b.html ruby-text-combine-upright-002-ref.html
|
||||
|
||||
# Tests for nested ruby
|
||||
fails-if(stylo) == nested-ruby-pairing-001.html nested-ruby-pairing-001-ref.html
|
||||
|
|
|
@ -2,14 +2,14 @@ default-preferences pref(layout.css.text-combine-upright.enabled,true)
|
|||
|
||||
== text-combine-upright-break-inside-001.html text-combine-upright-break-inside-001-ref.html
|
||||
== text-combine-upright-break-inside-001a.html text-combine-upright-break-inside-001-ref.html
|
||||
fails-if(stylo) == text-combine-upright-compression-001.html text-combine-upright-compression-001-ref.html
|
||||
fails-if(stylo) == text-combine-upright-compression-002.html text-combine-upright-compression-002-ref.html
|
||||
fails-if(stylo) == text-combine-upright-compression-003.html text-combine-upright-compression-003-ref.html
|
||||
fails-if(stylo) == text-combine-upright-compression-004.html text-combine-upright-compression-004-ref.html
|
||||
fails-if(stylo) == text-combine-upright-compression-005.html text-combine-upright-compression-005-ref.html
|
||||
fails-if(stylo) == text-combine-upright-compression-005a.html text-combine-upright-compression-005-ref.html
|
||||
fails-if(stylo) == text-combine-upright-compression-006.html text-combine-upright-compression-006-ref.html
|
||||
fails-if(stylo) == text-combine-upright-compression-006a.html text-combine-upright-compression-006-ref.html
|
||||
== text-combine-upright-compression-001.html text-combine-upright-compression-001-ref.html
|
||||
== text-combine-upright-compression-002.html text-combine-upright-compression-002-ref.html
|
||||
== text-combine-upright-compression-003.html text-combine-upright-compression-003-ref.html
|
||||
== text-combine-upright-compression-004.html text-combine-upright-compression-004-ref.html
|
||||
== text-combine-upright-compression-005.html text-combine-upright-compression-005-ref.html
|
||||
== text-combine-upright-compression-005a.html text-combine-upright-compression-005-ref.html
|
||||
== text-combine-upright-compression-006.html text-combine-upright-compression-006-ref.html
|
||||
== text-combine-upright-compression-006a.html text-combine-upright-compression-006-ref.html
|
||||
== text-combine-upright-compression-007.html text-combine-upright-compression-007-ref.html
|
||||
|
||||
== text-orientation-upright-directionality-001.html text-orientation-upright-directionality-001-ref.html
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "mozilla/dom/CSSSupportsRule.h"
|
||||
|
||||
#include "mozilla/dom/CSSSupportsRuleBinding.h"
|
||||
|
||||
using namespace mozilla::css;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, css::ConditionRule)
|
||||
NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, css::ConditionRule)
|
||||
|
||||
// QueryInterface implementation for CSSSupportsRule
|
||||
NS_INTERFACE_MAP_BEGIN(CSSSupportsRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSSupportsRule)
|
||||
NS_INTERFACE_MAP_END_INHERITING(ConditionRule)
|
||||
|
||||
// nsIDOMCSSGroupingRule methods
|
||||
NS_IMETHODIMP
|
||||
CSSSupportsRule::GetCssRules(nsIDOMCSSRuleList** aRuleList)
|
||||
{
|
||||
return GroupRule::GetCssRules(aRuleList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSSupportsRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
|
||||
{
|
||||
return GroupRule::InsertRule(aRule, aIndex, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSSupportsRule::DeleteRule(uint32_t aIndex)
|
||||
{
|
||||
return GroupRule::DeleteRule(aIndex);
|
||||
}
|
||||
|
||||
void
|
||||
CSSSupportsRule::SetConditionText(const nsAString& aConditionText,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv = SetConditionText(aConditionText);
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
CSSSupportsRule::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return CSSSupportsRuleBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_CSSSupportsRule_h
|
||||
#define mozilla_dom_CSSSupportsRule_h
|
||||
|
||||
#include "mozilla/css/GroupRule.h"
|
||||
#include "nsIDOMCSSSupportsRule.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class CSSSupportsRule : public css::ConditionRule
|
||||
, public nsIDOMCSSSupportsRule
|
||||
{
|
||||
protected:
|
||||
using ConditionRule::ConditionRule;
|
||||
virtual ~CSSSupportsRule() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
int32_t GetType() const override { return css::Rule::SUPPORTS_RULE; }
|
||||
using Rule::GetType;
|
||||
|
||||
// nsIDOMCSSGroupingRule interface
|
||||
NS_DECL_NSIDOMCSSGROUPINGRULE
|
||||
|
||||
// nsIDOMCSSConditionRule interface
|
||||
NS_IMETHOD SetConditionText(const nsAString& aConditionText) override = 0;
|
||||
|
||||
// nsIDOMCSSSupportsRule interface
|
||||
NS_DECL_NSIDOMCSSSUPPORTSRULE
|
||||
|
||||
// WebIDL interface
|
||||
uint16_t Type() const override { return nsIDOMCSSRule::SUPPORTS_RULE; }
|
||||
// Our XPCOM GetConditionText is OK
|
||||
void SetConditionText(const nsAString& aConditionText,
|
||||
ErrorResult& aRv) final;
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_CSSSupportsRule_h
|
|
@ -18,3 +18,4 @@ SERVO_ARC_TYPE(MediaList, RawServoMediaList)
|
|||
SERVO_ARC_TYPE(MediaRule, RawServoMediaRule)
|
||||
SERVO_ARC_TYPE(NamespaceRule, RawServoNamespaceRule)
|
||||
SERVO_ARC_TYPE(PageRule, RawServoPageRule)
|
||||
SERVO_ARC_TYPE(SupportsRule, RawServoSupportsRule)
|
||||
|
|
|
@ -98,10 +98,16 @@ SERVO_BINDING_FUNC(Servo_CssRules_DeleteRule, nsresult,
|
|||
RawServo##type_##RuleBorrowed rule, nsACString* result) \
|
||||
SERVO_BINDING_FUNC(Servo_##type_##Rule_GetCssText, void, \
|
||||
RawServo##type_##RuleBorrowed rule, nsAString* result)
|
||||
#define GROUP_RULE_FUNCS(type_) \
|
||||
BASIC_RULE_FUNCS(type_) \
|
||||
SERVO_BINDING_FUNC(Servo_##type_##Rule_GetRules, ServoCssRulesStrong, \
|
||||
RawServo##type_##RuleBorrowed rule)
|
||||
BASIC_RULE_FUNCS(Style)
|
||||
BASIC_RULE_FUNCS(Media)
|
||||
GROUP_RULE_FUNCS(Media)
|
||||
BASIC_RULE_FUNCS(Namespace)
|
||||
BASIC_RULE_FUNCS(Page)
|
||||
GROUP_RULE_FUNCS(Supports)
|
||||
#undef GROUP_RULE_FUNCS
|
||||
#undef BASIC_RULE_FUNCS
|
||||
SERVO_BINDING_FUNC(Servo_CssRules_GetFontFaceRuleAt, nsCSSFontFaceRule*,
|
||||
ServoCssRulesBorrowed rules, uint32_t index)
|
||||
|
@ -114,8 +120,6 @@ SERVO_BINDING_FUNC(Servo_StyleRule_GetSelectorText, void,
|
|||
RawServoStyleRuleBorrowed rule, nsAString* result)
|
||||
SERVO_BINDING_FUNC(Servo_MediaRule_GetMedia, RawServoMediaListStrong,
|
||||
RawServoMediaRuleBorrowed rule)
|
||||
SERVO_BINDING_FUNC(Servo_MediaRule_GetRules, ServoCssRulesStrong,
|
||||
RawServoMediaRuleBorrowed rule)
|
||||
SERVO_BINDING_FUNC(Servo_NamespaceRule_GetPrefix, nsIAtom*,
|
||||
RawServoNamespaceRuleBorrowed rule)
|
||||
SERVO_BINDING_FUNC(Servo_NamespaceRule_GetURI, nsIAtom*,
|
||||
|
@ -125,6 +129,8 @@ SERVO_BINDING_FUNC(Servo_PageRule_GetStyle, RawServoDeclarationBlockStrong,
|
|||
SERVO_BINDING_FUNC(Servo_PageRule_SetStyle, void,
|
||||
RawServoPageRuleBorrowed rule,
|
||||
RawServoDeclarationBlockBorrowed declarations)
|
||||
SERVO_BINDING_FUNC(Servo_SupportsRule_GetConditionText, void,
|
||||
RawServoSupportsRuleBorrowed rule, nsAString* result)
|
||||
|
||||
// Animations API
|
||||
SERVO_BINDING_FUNC(Servo_ParseProperty,
|
||||
|
@ -332,7 +338,8 @@ SERVO_BINDING_FUNC(Servo_ComputedValues_GetForAnonymousBox,
|
|||
RawServoStyleSetBorrowed set)
|
||||
SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoComputedValuesStrong,
|
||||
RawServoStyleSetBorrowed set,
|
||||
ServoComputedValuesBorrowedOrNull parent_style)
|
||||
ServoComputedValuesBorrowedOrNull parent_style,
|
||||
mozilla::InheritTarget target)
|
||||
|
||||
// Initialize Servo components. Should be called exactly once at startup.
|
||||
SERVO_BINDING_FUNC(Servo_Initialize, void,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/ServoMediaRule.h"
|
||||
#include "mozilla/ServoNamespaceRule.h"
|
||||
#include "mozilla/ServoPageRule.h"
|
||||
#include "mozilla/ServoSupportsRule.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -89,6 +90,7 @@ ServoCSSRuleList::GetRule(uint32_t aIndex)
|
|||
CASE_RULE(MEDIA, Media)
|
||||
CASE_RULE(NAMESPACE, Namespace)
|
||||
CASE_RULE(PAGE, Page)
|
||||
CASE_RULE(SUPPORTS, Supports)
|
||||
#undef CASE_RULE
|
||||
case nsIDOMCSSRule::FONT_FACE_RULE: {
|
||||
// Returns a borrowed nsCSSFontFaceRule object directly, so we
|
||||
|
@ -213,8 +215,9 @@ ServoCSSRuleList::FillStyleRuleHashtable(StyleRuleHashtable& aTable)
|
|||
ServoStyleRule* castedRule = static_cast<ServoStyleRule*>(GetRule(i));
|
||||
RawServoStyleRule* rawRule = castedRule->Raw();
|
||||
aTable.Put(rawRule, castedRule);
|
||||
} else if (type == nsIDOMCSSRule::MEDIA_RULE) {
|
||||
ServoMediaRule* castedRule = static_cast<ServoMediaRule*>(GetRule(i));
|
||||
} else if (type == nsIDOMCSSRule::MEDIA_RULE ||
|
||||
type == nsIDOMCSSRule::SUPPORTS_RULE) {
|
||||
GroupRule* castedRule = static_cast<GroupRule*>(GetRule(i));
|
||||
|
||||
// Call this method recursively on the ServoCSSRuleList in the rule.
|
||||
ServoCSSRuleList* castedRuleList = static_cast<ServoCSSRuleList*>(
|
||||
|
|
|
@ -366,7 +366,9 @@ ServoStyleSet::ResolveStyleForText(nsIContent* aTextNode,
|
|||
const ServoComputedValues* parentComputedValues =
|
||||
aParentContext->StyleSource().AsServoComputedValues();
|
||||
RefPtr<ServoComputedValues> computedValues =
|
||||
Servo_ComputedValues_Inherit(mRawSet.get(), parentComputedValues).Consume();
|
||||
Servo_ComputedValues_Inherit(mRawSet.get(),
|
||||
parentComputedValues,
|
||||
InheritTarget::Text).Consume();
|
||||
|
||||
return GetContext(computedValues.forget(), aParentContext,
|
||||
nsCSSAnonBoxes::mozText,
|
||||
|
@ -377,9 +379,13 @@ ServoStyleSet::ResolveStyleForText(nsIContent* aTextNode,
|
|||
already_AddRefed<nsStyleContext>
|
||||
ServoStyleSet::ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext)
|
||||
{
|
||||
const ServoComputedValues* parent = aParentContext->StyleSource().AsServoComputedValues();
|
||||
const ServoComputedValues* parent =
|
||||
aParentContext->StyleSource().AsServoComputedValues();
|
||||
RefPtr<ServoComputedValues> computedValues =
|
||||
Servo_ComputedValues_Inherit(mRawSet.get(), parent).Consume();
|
||||
Servo_ComputedValues_Inherit(mRawSet.get(),
|
||||
parent,
|
||||
InheritTarget::FirstLetterContinuation)
|
||||
.Consume();
|
||||
MOZ_ASSERT(computedValues);
|
||||
|
||||
return GetContext(computedValues.forget(), aParentContext,
|
||||
|
@ -399,7 +405,10 @@ ServoStyleSet::ResolveStyleForPlaceholder()
|
|||
}
|
||||
|
||||
RefPtr<ServoComputedValues> computedValues =
|
||||
Servo_ComputedValues_Inherit(mRawSet.get(), nullptr).Consume();
|
||||
Servo_ComputedValues_Inherit(mRawSet.get(),
|
||||
nullptr,
|
||||
InheritTarget::PlaceholderFrame)
|
||||
.Consume();
|
||||
MOZ_ASSERT(computedValues);
|
||||
|
||||
RefPtr<nsStyleContext> retval =
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
/* representation of CSSSupportsRule for stylo */
|
||||
|
||||
#include "mozilla/ServoSupportsRule.h"
|
||||
|
||||
#include "mozilla/ServoBindings.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
ServoSupportsRule::ServoSupportsRule(RefPtr<RawServoSupportsRule> aRawRule)
|
||||
: CSSSupportsRule(Servo_SupportsRule_GetRules(aRawRule).Consume())
|
||||
, mRawRule(Move(aRawRule))
|
||||
{
|
||||
}
|
||||
|
||||
ServoSupportsRule::~ServoSupportsRule()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(ServoSupportsRule, CSSSupportsRule)
|
||||
NS_IMPL_RELEASE_INHERITED(ServoSupportsRule, CSSSupportsRule)
|
||||
|
||||
// QueryInterface implementation for SupportsRule
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoSupportsRule)
|
||||
NS_INTERFACE_MAP_END_INHERITING(CSSSupportsRule)
|
||||
|
||||
/* virtual */ already_AddRefed<css::Rule>
|
||||
ServoSupportsRule::Clone() const
|
||||
{
|
||||
// Rule::Clone is only used when CSSStyleSheetInner is cloned in
|
||||
// preparation of being mutated. However, ServoStyleSheet never clones
|
||||
// anything, so this method should never be called.
|
||||
MOZ_ASSERT_UNREACHABLE("Shouldn't be cloning ServoSupportsRule");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* virtual */ bool
|
||||
ServoSupportsRule::UseForPresentation(nsPresContext* aPresContext,
|
||||
nsMediaQueryResultCacheKey& aKey)
|
||||
{
|
||||
// GroupRule::UseForPresentation is only used in nsCSSRuleProcessor,
|
||||
// so this should never be called.
|
||||
MOZ_ASSERT_UNREACHABLE("Shouldn't be calling UseForPresentation");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* virtual */ void
|
||||
ServoSupportsRule::List(FILE* out, int32_t aIndent) const
|
||||
{
|
||||
nsAutoCString str;
|
||||
for (int32_t i = 0; i < aIndent; i++) {
|
||||
str.AppendLiteral(" ");
|
||||
}
|
||||
Servo_SupportsRule_Debug(mRawRule, &str);
|
||||
fprintf_stderr(out, "%s\n", str.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
// nsIDOMCSSConditionRule methods
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServoSupportsRule::GetConditionText(nsAString& aConditionText)
|
||||
{
|
||||
Servo_SupportsRule_GetConditionText(mRawRule, &aConditionText);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServoSupportsRule::SetConditionText(const nsAString& aConditionText)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
ServoSupportsRule::GetCssTextImpl(nsAString& aCssText) const
|
||||
{
|
||||
Servo_SupportsRule_GetCssText(mRawRule, &aCssText);
|
||||
}
|
||||
|
||||
/* virtual */ size_t
|
||||
ServoSupportsRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
||||
const
|
||||
{
|
||||
// TODO Implement this!
|
||||
return aMallocSizeOf(this);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
/* representation of CSSSupportsRule for stylo */
|
||||
|
||||
#ifndef mozilla_ServoSupportsRule_h
|
||||
#define mozilla_ServoSupportsRule_h
|
||||
|
||||
#include "mozilla/dom/CSSSupportsRule.h"
|
||||
#include "mozilla/ServoBindingTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ServoSupportsRule final : public dom::CSSSupportsRule
|
||||
{
|
||||
public:
|
||||
explicit ServoSupportsRule(RefPtr<RawServoSupportsRule> aRawRule);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
already_AddRefed<css::Rule> Clone() const override;
|
||||
bool UseForPresentation(nsPresContext* aPresContext,
|
||||
nsMediaQueryResultCacheKey& aKey) final;
|
||||
#ifdef DEBUG
|
||||
void List(FILE* out = stdout, int32_t aIndent = 0) const final;
|
||||
#endif
|
||||
|
||||
RawServoSupportsRule* Raw() const { return mRawRule; }
|
||||
|
||||
// nsIDOMCSSConditionRule interface
|
||||
NS_DECL_NSIDOMCSSCONDITIONRULE
|
||||
|
||||
// WebIDL interface
|
||||
void GetCssTextImpl(nsAString& aCssText) const override;
|
||||
using CSSSupportsRule::SetConditionText;
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
||||
const override;
|
||||
|
||||
private:
|
||||
virtual ~ServoSupportsRule();
|
||||
|
||||
RefPtr<RawServoSupportsRule> mRawRule;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_ServoSupportsRule_h
|
|
@ -71,6 +71,8 @@ enum class UpdateAnimationsTasks : uint8_t {
|
|||
CascadeResults = 1 << 3,
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(UpdateAnimationsTasks)
|
||||
|
||||
// The mode to use when parsing lengths.
|
||||
enum class LengthParsingMode {
|
||||
// In CSS, lengths must have units, except for zero values, where the unit can
|
||||
|
@ -83,7 +85,16 @@ enum class LengthParsingMode {
|
|||
SVG,
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(UpdateAnimationsTasks)
|
||||
// The kind of style we're generating when requesting Servo to give us an
|
||||
// inherited style.
|
||||
enum class InheritTarget {
|
||||
// We're requesting a text style.
|
||||
Text,
|
||||
// We're requesting a first-letter continuation frame style.
|
||||
FirstLetterContinuation,
|
||||
// We're requesting a style for a placeholder frame.
|
||||
PlaceholderFrame,
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ EXPORTS.mozilla += [
|
|||
'ServoStyleRule.h',
|
||||
'ServoStyleSet.h',
|
||||
'ServoStyleSheet.h',
|
||||
'ServoSupportsRule.h',
|
||||
'ServoTypes.h',
|
||||
'ServoUtils.h',
|
||||
'SheetType.h',
|
||||
|
@ -134,6 +135,7 @@ EXPORTS.mozilla.dom += [
|
|||
'CSSNamespaceRule.h',
|
||||
'CSSPageRule.h',
|
||||
'CSSRuleList.h',
|
||||
'CSSSupportsRule.h',
|
||||
'CSSValue.h',
|
||||
'FontFace.h',
|
||||
'FontFaceSet.h',
|
||||
|
@ -165,6 +167,7 @@ UNIFIED_SOURCES += [
|
|||
'CSSPageRule.cpp',
|
||||
'CSSRuleList.cpp',
|
||||
'CSSStyleSheet.cpp',
|
||||
'CSSSupportsRule.cpp',
|
||||
'CSSVariableDeclarations.cpp',
|
||||
'CSSVariableResolver.cpp',
|
||||
'CSSVariableValues.cpp',
|
||||
|
@ -231,6 +234,7 @@ UNIFIED_SOURCES += [
|
|||
'ServoStyleRule.cpp',
|
||||
'ServoStyleSet.cpp',
|
||||
'ServoStyleSheet.cpp',
|
||||
'ServoSupportsRule.cpp',
|
||||
'StyleAnimationValue.cpp',
|
||||
'StyleRule.cpp',
|
||||
'StyleSheet.cpp',
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "nsDOMClassInfoID.h"
|
||||
#include "mozilla/dom/CSSStyleDeclarationBinding.h"
|
||||
#include "mozilla/dom/CSSImportRuleBinding.h"
|
||||
#include "mozilla/dom/CSSSupportsRuleBinding.h"
|
||||
#include "mozilla/dom/CSSMozDocumentRuleBinding.h"
|
||||
#include "mozilla/dom/CSSFontFaceRuleBinding.h"
|
||||
#include "mozilla/dom/CSSFontFeatureValuesRuleBinding.h"
|
||||
|
@ -2272,7 +2271,7 @@ namespace mozilla {
|
|||
CSSSupportsRule::CSSSupportsRule(bool aConditionMet,
|
||||
const nsString& aCondition,
|
||||
uint32_t aLineNumber, uint32_t aColumnNumber)
|
||||
: css::ConditionRule(aLineNumber, aColumnNumber)
|
||||
: dom::CSSSupportsRule(aLineNumber, aColumnNumber)
|
||||
, mUseGroup(aConditionMet)
|
||||
, mCondition(aCondition)
|
||||
{
|
||||
|
@ -2283,7 +2282,7 @@ CSSSupportsRule::~CSSSupportsRule()
|
|||
}
|
||||
|
||||
CSSSupportsRule::CSSSupportsRule(const CSSSupportsRule& aCopy)
|
||||
: css::ConditionRule(aCopy),
|
||||
: dom::CSSSupportsRule(aCopy),
|
||||
mUseGroup(aCopy.mUseGroup),
|
||||
mCondition(aCopy.mCondition)
|
||||
{
|
||||
|
@ -2307,12 +2306,6 @@ CSSSupportsRule::List(FILE* out, int32_t aIndent) const
|
|||
}
|
||||
#endif
|
||||
|
||||
/* virtual */ int32_t
|
||||
CSSSupportsRule::GetType() const
|
||||
{
|
||||
return Rule::SUPPORTS_RULE;
|
||||
}
|
||||
|
||||
/* virtual */ already_AddRefed<mozilla::css::Rule>
|
||||
CSSSupportsRule::Clone() const
|
||||
{
|
||||
|
@ -2332,16 +2325,7 @@ NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, css::ConditionRule)
|
|||
|
||||
// QueryInterface implementation for CSSSupportsRule
|
||||
NS_INTERFACE_MAP_BEGIN(CSSSupportsRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSSupportsRule)
|
||||
NS_INTERFACE_MAP_END_INHERITING(ConditionRule)
|
||||
|
||||
uint16_t
|
||||
CSSSupportsRule::Type() const
|
||||
{
|
||||
return nsIDOMCSSRule::SUPPORTS_RULE;
|
||||
}
|
||||
NS_INTERFACE_MAP_END_INHERITING(dom::CSSSupportsRule)
|
||||
|
||||
void
|
||||
CSSSupportsRule::GetCssTextImpl(nsAString& aCssText) const
|
||||
|
@ -2351,25 +2335,6 @@ CSSSupportsRule::GetCssTextImpl(nsAString& aCssText) const
|
|||
css::GroupRule::AppendRulesToCssText(aCssText);
|
||||
}
|
||||
|
||||
// nsIDOMCSSGroupingRule methods
|
||||
NS_IMETHODIMP
|
||||
CSSSupportsRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
|
||||
{
|
||||
return css::GroupRule::GetCssRules(aRuleList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSSupportsRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
|
||||
{
|
||||
return css::GroupRule::InsertRule(aRule, aIndex, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSSupportsRule::DeleteRule(uint32_t aIndex)
|
||||
{
|
||||
return css::GroupRule::DeleteRule(aIndex);
|
||||
}
|
||||
|
||||
// nsIDOMCSSConditionRule methods
|
||||
NS_IMETHODIMP
|
||||
CSSSupportsRule::GetConditionText(nsAString& aConditionText)
|
||||
|
@ -2384,13 +2349,6 @@ CSSSupportsRule::SetConditionText(const nsAString& aConditionText)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void
|
||||
CSSSupportsRule::SetConditionText(const nsAString& aConditionText,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/* virtual */ size_t
|
||||
CSSSupportsRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
|
@ -2400,13 +2358,6 @@ CSSSupportsRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|||
return n;
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
CSSSupportsRule::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return CSSSupportsRuleBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
// -------------------------------------------
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "mozilla/css/GroupRule.h"
|
||||
#include "mozilla/dom/CSSMediaRule.h"
|
||||
#include "mozilla/dom/CSSPageRule.h"
|
||||
#include "mozilla/dom/CSSSupportsRule.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCSSPropertyID.h"
|
||||
#include "nsCSSValue.h"
|
||||
|
@ -446,8 +447,7 @@ private:
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
class CSSSupportsRule final : public css::ConditionRule,
|
||||
public nsIDOMCSSSupportsRule
|
||||
class CSSSupportsRule final : public dom::CSSSupportsRule
|
||||
{
|
||||
public:
|
||||
CSSSupportsRule(bool aConditionMet, const nsString& aCondition,
|
||||
|
@ -458,35 +458,21 @@ public:
|
|||
#ifdef DEBUG
|
||||
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
|
||||
#endif
|
||||
virtual int32_t GetType() const override;
|
||||
using Rule::GetType;
|
||||
virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
|
||||
virtual bool UseForPresentation(nsPresContext* aPresContext,
|
||||
nsMediaQueryResultCacheKey& aKey) override;
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMCSSGroupingRule interface
|
||||
NS_DECL_NSIDOMCSSGROUPINGRULE
|
||||
|
||||
// nsIDOMCSSConditionRule interface
|
||||
NS_DECL_NSIDOMCSSCONDITIONRULE
|
||||
|
||||
// nsIDOMCSSSupportsRule interface
|
||||
NS_DECL_NSIDOMCSSSUPPORTSRULE
|
||||
|
||||
// WebIDL interface
|
||||
uint16_t Type() const override;
|
||||
void GetCssTextImpl(nsAString& aCssText) const override;
|
||||
// Our XPCOM GetConditionText is OK
|
||||
virtual void SetConditionText(const nsAString& aConditionText,
|
||||
ErrorResult& aRv) override;
|
||||
using dom::CSSSupportsRule::SetConditionText;
|
||||
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
virtual ~CSSSupportsRule();
|
||||
|
||||
|
|
|
@ -631,49 +631,31 @@ private:
|
|||
return newData; \
|
||||
} \
|
||||
/** \
|
||||
* Always forward to the parent to grab the inherited style struct\
|
||||
* we're a text node. \
|
||||
* Also (conservatively) set the owning bit in the parent style \
|
||||
* context if we're a text node. \
|
||||
* \
|
||||
* This causes the parent element's style context to cache any \
|
||||
* inherited structs we request for a text node, which means we \
|
||||
* don't have to compute change hints for the text node, as \
|
||||
* handling the change on the parent element is sufficient. \
|
||||
* \
|
||||
* Note that adding the inherit bit is ok, because the struct \
|
||||
* pointer returned by the parent and the child is owned by \
|
||||
* Servo. This is fine if the pointers are the same (as it \
|
||||
* should, read below), because both style context sources will \
|
||||
* hold it. \
|
||||
* Note, however, that we still need to request the style struct \
|
||||
* of the text node itself, since we may run some fixups on it, \
|
||||
* like for text-combine. \
|
||||
* \
|
||||
* In the case of a mishandled frame, we could end up with the \
|
||||
* pointer to and old parent style, but that's fine too, since \
|
||||
* the parent style context will remain alive until we reframe, \
|
||||
* in which case we'll discard both style contexts. Also, we \
|
||||
* hold a strong reference to the parent style context, which \
|
||||
* makes it a non-issue. \
|
||||
* This model is sound because for the fixed-up values to change, \
|
||||
* other properties on the parent need to change too, and we'll \
|
||||
* handle those change hints correctly. \
|
||||
* \
|
||||
* Also, note that the assertion below should be true, except \
|
||||
* for those frames we still don't handle correctly, like \
|
||||
* anonymous table wrappers, in which case the pointers will \
|
||||
* differ. \
|
||||
* \
|
||||
* That means we're not going to restyle correctly text frames \
|
||||
* of anonymous table wrappers, for example. It's kind of \
|
||||
* embarrassing, but I think it's not worth it to add more \
|
||||
* logic here unconditionally, given that's going to be fixed. \
|
||||
* \
|
||||
* TODO(emilio): Convert to a strong assertion once we support \
|
||||
* all kinds of random frames. In fact, this can be a great \
|
||||
* assertion to debug them. \
|
||||
* TODO(emilio): Perhaps we should remove those fixups and handle \
|
||||
* those in layout instead. Those fixups are kind of expensive \
|
||||
* for style sharing, and computed style of text nodes is not \
|
||||
* observable. If we do that, we could assert here that the \
|
||||
* inherited structs of both are the same. \
|
||||
*/ \
|
||||
if (mPseudoTag == nsCSSAnonBoxes::mozText) { \
|
||||
if (mPseudoTag == nsCSSAnonBoxes::mozText && aComputeData) { \
|
||||
MOZ_ASSERT(mParent); \
|
||||
const nsStyle##name_* data = \
|
||||
mParent->DoGetStyle##name_<aComputeData>(); \
|
||||
NS_WARNING_ASSERTION(!data || \
|
||||
data == Servo_GetStyle##name_(mSource.AsServoComputedValues()), \
|
||||
"bad data"); \
|
||||
return data; \
|
||||
mParent->AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
|
||||
} \
|
||||
\
|
||||
const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_));\
|
||||
|
|
|
@ -61,7 +61,7 @@ to mochitest command.
|
|||
* test_keyframes_rules.html [1]
|
||||
* test_rules_out_of_sheets.html [1]
|
||||
* \@support bug 1355394
|
||||
* test_supports_rules.html [1]
|
||||
* test_supports_rules.html [6]
|
||||
* test_bug357614.html: case-insensitivity for old attrs in attr selector servo/servo#15006 [2]
|
||||
* test_bug387615.html: servo/servo#15006 [1]
|
||||
* test_bug397427.html: @import issue bug 1331291 and CSSOM support of @import [1]
|
||||
|
@ -261,7 +261,7 @@ to mochitest command.
|
|||
* test_rule_serialization.html [2]
|
||||
* test_moz_document_rules.html [13]
|
||||
* test_bug511909.html `@-moz-document` [4]
|
||||
* test_condition_text.html: also \@supports [7]
|
||||
* test_condition_text.html: also \@supports [11]
|
||||
* getComputedStyle style doesn't contain custom properties bug 1336891
|
||||
* test_variable_serialization_computed.html [35]
|
||||
* test_variables.html `custom property name` [2]
|
||||
|
|
|
@ -277,7 +277,8 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(MaskParams& aParams)
|
|||
}
|
||||
RefPtr<DataSourceSurface> maskSurface = maskSnapshot->GetDataSurface();
|
||||
DataSourceSurface::MappedSurface map;
|
||||
if (!maskSurface->Map(DataSourceSurface::MapType::READ, &map)) {
|
||||
if (!maskSurface ||
|
||||
!maskSurface->Map(DataSourceSurface::MapType::READ, &map)) {
|
||||
return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,16 @@ ListBoxObject::GetRowCount()
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
ListBoxObject::GetRowHeight()
|
||||
{
|
||||
nsListBoxBodyFrame* body = GetListBoxBody(true);
|
||||
if (body) {
|
||||
return body->GetRowHeightPixels();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
ListBoxObject::GetNumberOfVisibleRows()
|
||||
{
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче