MozReview-Commit-ID: 77Uz3uceUmk
This commit is contained in:
Wes Kocher 2017-08-31 16:56:23 -07:00
Родитель 6bad4f8ef7 e9c837e8b6
Коммит 6472928439
50 изменённых файлов: 794 добавлений и 543 удалений

Просмотреть файл

@ -64,10 +64,10 @@ var shutdown = Task.async(function* () {
// This is what makes the sidebar widget able to load/unload the panel. // This is what makes the sidebar widget able to load/unload the panel.
function setPanel(panel) { function setPanel(panel) {
return startup(panel).catch(e => console.error(e)); return startup(panel).catch(console.error);
} }
function destroy() { function destroy() {
return shutdown().catch(e => console.error(e)); return shutdown().catch(console.error);
} }
/** /**
@ -261,7 +261,7 @@ var AnimationsController = {
return this.animationsFront.toggleAll() return this.animationsFront.toggleAll()
.then(() => this.emit(this.ALL_ANIMATIONS_TOGGLED_EVENT, this)) .then(() => this.emit(this.ALL_ANIMATIONS_TOGGLED_EVENT, this))
.catch(e => console.error(e)); .catch(console.error);
}, },
/** /**

Просмотреть файл

@ -179,9 +179,9 @@ var AnimationsPanel = {
// the page if the selected node does not have any animation on it. // the page if the selected node does not have any animation on it.
if (event.keyCode === KeyCodes.DOM_VK_SPACE) { if (event.keyCode === KeyCodes.DOM_VK_SPACE) {
if (AnimationsController.animationPlayers.length > 0) { if (AnimationsController.animationPlayers.length > 0) {
this.playPauseTimeline().catch(ex => console.error(ex)); this.playPauseTimeline().catch(console.error);
} else { } else {
this.toggleAll().catch(ex => console.error(ex)); this.toggleAll().catch(console.error);
} }
event.preventDefault(); event.preventDefault();
} }
@ -208,7 +208,7 @@ var AnimationsPanel = {
}, },
onToggleAllClicked: function () { onToggleAllClicked: function () {
this.toggleAll().catch(ex => console.error(ex)); this.toggleAll().catch(console.error);
}, },
/** /**
@ -221,7 +221,7 @@ var AnimationsPanel = {
}), }),
onTimelinePlayClicked: function () { onTimelinePlayClicked: function () {
this.playPauseTimeline().catch(ex => console.error(ex)); this.playPauseTimeline().catch(console.error);
}, },
/** /**
@ -241,7 +241,7 @@ var AnimationsPanel = {
}, },
onTimelineRewindClicked: function () { onTimelineRewindClicked: function () {
this.rewindTimeline().catch(ex => console.error(ex)); this.rewindTimeline().catch(console.error);
}, },
/** /**
@ -263,7 +263,7 @@ var AnimationsPanel = {
onRateChanged: function (e, rate) { onRateChanged: function (e, rate) {
AnimationsController.setPlaybackRateAll(rate) AnimationsController.setPlaybackRateAll(rate)
.then(() => this.refreshAnimationsStateAndUI()) .then(() => this.refreshAnimationsStateAndUI())
.catch(ex => console.error(ex)); .catch(console.error);
}, },
onTabNavigated: function () { onTabNavigated: function () {
@ -289,7 +289,7 @@ var AnimationsPanel = {
if (isUserDrag && !this.setCurrentTimeAllPromise) { if (isUserDrag && !this.setCurrentTimeAllPromise) {
this.setCurrentTimeAllPromise = this.setCurrentTimeAllPromise =
AnimationsController.setCurrentTimeAll(time, true) AnimationsController.setCurrentTimeAll(time, true)
.catch(error => console.error(error)) .catch(console.error)
.then(() => { .then(() => {
this.setCurrentTimeAllPromise = null; this.setCurrentTimeAllPromise = null;
}); });

Просмотреть файл

@ -288,7 +288,7 @@ var CallsListView = Heritage.extend(WidgetMethods, {
frameSnapshot.generateScreenshotFor(functionCall).then(screenshot => { frameSnapshot.generateScreenshotFor(functionCall).then(screenshot => {
this.showScreenshot(screenshot); this.showScreenshot(screenshot);
this.highlightedThumbnail = screenshot.index; this.highlightedThumbnail = screenshot.index;
}).catch(e => console.error(e)); }).catch(console.error);
}); });
}, },

Просмотреть файл

@ -302,14 +302,14 @@ BoxModel.prototype = {
properties[0].name = property.substring(9); properties[0].name = property.substring(9);
} }
session.setProperties(properties).catch(e => console.error(e)); session.setProperties(properties).catch(console.error);
}, },
done: (value, commit) => { done: (value, commit) => {
editor.elt.parentNode.classList.remove("boxmodel-editing"); editor.elt.parentNode.classList.remove("boxmodel-editing");
if (!commit) { if (!commit) {
session.revert().then(() => { session.revert().then(() => {
session.destroy(); session.destroy();
}, e => console.error(e)); }, console.error);
return; return;
} }
@ -322,7 +322,7 @@ BoxModel.prototype = {
autoMargins: true, autoMargins: true,
}).then(layout => { }).then(layout => {
this.store.dispatch(updateLayout(layout)); this.store.dispatch(updateLayout(layout));
}, e => console.error(e)); }, console.error);
}, },
cssProperties: getCssProperties(this.inspector.toolbox) cssProperties: getCssProperties(this.inspector.toolbox)
}, event); }, event);

Просмотреть файл

@ -509,7 +509,7 @@ CssComputedView.prototype = {
); );
this._refreshProcess.schedule(); this._refreshProcess.schedule();
}); });
}).catch((err) => console.error(err)); }).catch(console.error);
}, },
/** /**

Просмотреть файл

@ -58,7 +58,7 @@ exports.items = [{
}], }],
exec: function* (args, context) { exec: function* (args, context) {
if (args.hide) { if (args.hide) {
context.updateExec("eyedropper_server_hide").catch(e => console.error(e)); context.updateExec("eyedropper_server_hide").catch(console.error);
return; return;
} }
@ -74,7 +74,7 @@ exports.items = [{
let telemetry = new Telemetry(); let telemetry = new Telemetry();
telemetry.toolOpened(args.frommenu ? "menueyedropper" : "eyedropper"); telemetry.toolOpened(args.frommenu ? "menueyedropper" : "eyedropper");
context.updateExec("eyedropper_server").catch(e => console.error(e)); context.updateExec("eyedropper_server").catch(console.error);
} }
}, { }, {
item: "command", item: "command",

Просмотреть файл

@ -72,7 +72,7 @@ InspectorSearch.prototype = {
_onSearch: function (reverse = false) { _onSearch: function (reverse = false) {
this.doFullTextSearch(this.searchBox.value, reverse) this.doFullTextSearch(this.searchBox.value, reverse)
.catch(e => console.error(e)); .catch(console.error);
}, },
doFullTextSearch: Task.async(function* (query, reverse) { doFullTextSearch: Task.async(function* (query, reverse) {

Просмотреть файл

@ -224,13 +224,13 @@ Inspector.prototype = {
return promise.all([ return promise.all([
this._target.actorHasMethod("domwalker", "duplicateNode").then(value => { this._target.actorHasMethod("domwalker", "duplicateNode").then(value => {
this._supportsDuplicateNode = value; this._supportsDuplicateNode = value;
}).catch(e => console.error(e)), }).catch(console.error),
this._target.actorHasMethod("domnode", "scrollIntoView").then(value => { this._target.actorHasMethod("domnode", "scrollIntoView").then(value => {
this._supportsScrollIntoView = value; this._supportsScrollIntoView = value;
}).catch(e => console.error(e)), }).catch(console.error),
this._target.actorHasMethod("inspector", "resolveRelativeURL").then(value => { this._target.actorHasMethod("inspector", "resolveRelativeURL").then(value => {
this._supportsResolveRelativeURL = value; this._supportsResolveRelativeURL = value;
}).catch(e => console.error(e)), }).catch(console.error),
]); ]);
}); });
}, },
@ -1627,7 +1627,7 @@ Inspector.prototype = {
this.eyeDropperButton.classList.add("checked"); this.eyeDropperButton.classList.add("checked");
this.startEyeDropperListeners(); this.startEyeDropperListeners();
return this.inspector.pickColorFromPage(this.toolbox, {copyOnSelect: true}) return this.inspector.pickColorFromPage(this.toolbox, {copyOnSelect: true})
.catch(e => console.error(e)); .catch(console.error);
}, },
/** /**
@ -1644,7 +1644,7 @@ Inspector.prototype = {
this.eyeDropperButton.classList.remove("checked"); this.eyeDropperButton.classList.remove("checked");
this.stopEyeDropperListeners(); this.stopEyeDropperListeners();
return this.inspector.cancelPickColorFromPage() return this.inspector.cancelPickColorFromPage()
.catch(e => console.error(e)); .catch(console.error);
}, },
/** /**
@ -1839,7 +1839,7 @@ Inspector.prototype = {
_copyLongString: function (longStringActorPromise) { _copyLongString: function (longStringActorPromise) {
return this._getLongString(longStringActorPromise).then(string => { return this._getLongString(longStringActorPromise).then(string => {
clipboardHelper.copyString(string); clipboardHelper.copyString(string);
}).catch(e => console.error(e)); }).catch(console.error);
}, },
/** /**
@ -1851,10 +1851,10 @@ Inspector.prototype = {
_getLongString: function (longStringActorPromise) { _getLongString: function (longStringActorPromise) {
return longStringActorPromise.then(longStringActor => { return longStringActorPromise.then(longStringActor => {
return longStringActor.string().then(string => { return longStringActor.string().then(string => {
longStringActor.release().catch(e => console.error(e)); longStringActor.release().catch(console.error);
return string; return string;
}); });
}).catch(e => console.error(e)); }).catch(console.error);
}, },
/** /**
@ -1868,7 +1868,7 @@ Inspector.prototype = {
this.telemetry.toolOpened("copyuniquecssselector"); this.telemetry.toolOpened("copyuniquecssselector");
this.selection.nodeFront.getUniqueSelector().then(selector => { this.selection.nodeFront.getUniqueSelector().then(selector => {
clipboardHelper.copyString(selector); clipboardHelper.copyString(selector);
}).catch(e => console.error); }).catch(console.error);
}, },
/** /**
@ -1882,7 +1882,7 @@ Inspector.prototype = {
this.telemetry.toolOpened("copyfullcssselector"); this.telemetry.toolOpened("copyfullcssselector");
this.selection.nodeFront.getCssPath().then(path => { this.selection.nodeFront.getCssPath().then(path => {
clipboardHelper.copyString(path); clipboardHelper.copyString(path);
}).catch(e => console.error); }).catch(console.error);
}, },
/** /**
@ -1896,7 +1896,7 @@ Inspector.prototype = {
this.telemetry.toolOpened("copyxpath"); this.telemetry.toolOpened("copyxpath");
this.selection.nodeFront.getXPath().then(path => { this.selection.nodeFront.getXPath().then(path => {
clipboardHelper.copyString(path); clipboardHelper.copyString(path);
}).catch(e => console.error); }).catch(console.error);
}, },
/** /**
@ -1942,7 +1942,7 @@ Inspector.prototype = {
selection.isPseudoElementNode()) { selection.isPseudoElementNode()) {
return; return;
} }
this.walker.duplicateNode(selection.nodeFront).catch(e => console.error(e)); this.walker.duplicateNode(selection.nodeFront).catch(console.error);
}, },
/** /**
@ -2043,7 +2043,7 @@ Inspector.prototype = {
return this.toolbox.viewSourceInDebugger(url); return this.toolbox.viewSourceInDebugger(url);
} }
return null; return null;
}).catch(e => console.error(e)); }).catch(console.error);
} else if (type == "idref") { } else if (type == "idref") {
// Select the node in the same document. // Select the node in the same document.
this.walker.document(this.selection.nodeFront).then(doc => { this.walker.document(this.selection.nodeFront).then(doc => {
@ -2054,7 +2054,7 @@ Inspector.prototype = {
} }
this.selection.setNodeFront(node); this.selection.setNodeFront(node);
}); });
}).catch(e => console.error(e)); }).catch(console.error);
} }
}, },

Просмотреть файл

@ -184,7 +184,7 @@ MarkupView.prototype = {
_onToolboxPickerHover: function (event, nodeFront) { _onToolboxPickerHover: function (event, nodeFront) {
this.showNode(nodeFront).then(() => { this.showNode(nodeFront).then(() => {
this._showContainerAsHovered(nodeFront); this._showContainerAsHovered(nodeFront);
}, e => console.error(e)); }, console.error);
}, },
/** /**

Просмотреть файл

@ -897,7 +897,7 @@ CssRuleView.prototype = {
// Notify anyone that cares that we refreshed. // Notify anyone that cares that we refreshed.
return onEditorsReady.then(() => { return onEditorsReady.then(() => {
this.emit("ruleview-refreshed"); this.emit("ruleview-refreshed");
}, e => console.error(e)); }, console.error);
}).catch(promiseWarn); }).catch(promiseWarn);
}, },

Просмотреть файл

@ -275,7 +275,7 @@ RuleEditor.prototype = {
this.rule.getOriginalSourceStrings().then((strings) => { this.rule.getOriginalSourceStrings().then((strings) => {
sourceLabel.textContent = strings.short; sourceLabel.textContent = strings.short;
sourceLabel.setAttribute("title", strings.full); sourceLabel.setAttribute("title", strings.full);
}, e => console.error(e)).then(() => { }, console.error).then(() => {
this.emit("source-link-updated"); this.emit("source-link-updated");
}); });
} else { } else {

Просмотреть файл

@ -196,7 +196,7 @@ DomNodePreview.prototype = {
}, },
destroy: function () { destroy: function () {
HighlighterLock.unhighlight().catch(e => console.error(e)); HighlighterLock.unhighlight().catch(console.error);
this.stopListeners(); this.stopListeners();
@ -218,7 +218,7 @@ DomNodePreview.prototype = {
return; return;
} }
this.highlighterUtils.highlightNodeFront(this.nodeFront) this.highlighterUtils.highlightNodeFront(this.nodeFront)
.catch(e => console.error(e)); .catch(console.error);
}, },
onPreviewMouseOut: function () { onPreviewMouseOut: function () {
@ -226,7 +226,7 @@ DomNodePreview.prototype = {
return; return;
} }
this.highlighterUtils.unhighlight() this.highlighterUtils.unhighlight()
.catch(e => console.error(e)); .catch(console.error);
}, },
onSelectElClick: function () { onSelectElClick: function () {
@ -246,12 +246,12 @@ DomNodePreview.prototype = {
classList.remove("selected"); classList.remove("selected");
HighlighterLock.unhighlight().then(() => { HighlighterLock.unhighlight().then(() => {
this.emit("target-highlighter-unlocked"); this.emit("target-highlighter-unlocked");
}, error => console.error(error)); }, console.error);
} else { } else {
classList.add("selected"); classList.add("selected");
HighlighterLock.highlight(this).then(() => { HighlighterLock.highlight(this).then(() => {
this.emit("target-highlighter-locked"); this.emit("target-highlighter-locked");
}, error => console.error(error)); }, console.error);
} }
}, },

Просмотреть файл

@ -535,7 +535,7 @@ HighlightersOverlay.prototype = {
// whether the result is truthy before installing the handler. // whether the result is truthy before installing the handler.
let onHidden = this.highlighters[this.hoveredHighlighterShown].hide(); let onHidden = this.highlighters[this.hoveredHighlighterShown].hide();
if (onHidden) { if (onHidden) {
onHidden.catch(e => console.error(e)); onHidden.catch(console.error);
} }
this.hoveredHighlighterShown = null; this.hoveredHighlighterShown = null;

Просмотреть файл

@ -189,7 +189,7 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
break; break;
default: default:
} }
completed.catch(e => console.error(e)); completed.catch(console.error);
}, },
handleMenuCheck({target}) { handleMenuCheck({target}) {

Просмотреть файл

@ -1736,7 +1736,7 @@ var Scratchpad = {
this.populateRecentFilesMenu(); this.populateRecentFilesMenu();
PreferenceObserver.init(); PreferenceObserver.init();
CloseObserver.init(); CloseObserver.init();
}).catch((err) => console.error(err)); }).catch(console.error);
this._setupCommandListeners(); this._setupCommandListeners();
this._updateViewMenuItems(); this._updateViewMenuItems();
this._setupPopupShowingListeners(); this._setupPopupShowingListeners();

Просмотреть файл

@ -314,7 +314,7 @@ var ShadersListView = Heritage.extend(WidgetMethods, {
getShaders() getShaders()
.then(getSources) .then(getSources)
.then(showSources) .then(showSources)
.catch(e => console.error(e)); .catch(console.error);
}, },
/** /**

Просмотреть файл

@ -575,7 +575,7 @@ CSSFilterEditorWidget.prototype = {
// If the click happened on the remove button. // If the click happened on the remove button.
presets.splice(id, 1); presets.splice(id, 1);
this.setPresets(presets).then(this.renderPresets, this.setPresets(presets).then(this.renderPresets,
ex => console.error(ex)); console.error);
} else { } else {
// Or if the click happened on a preset. // Or if the click happened on a preset.
let p = presets[id]; let p = presets[id];
@ -583,7 +583,7 @@ CSSFilterEditorWidget.prototype = {
this.setCssValue(p.value); this.setCssValue(p.value);
this.addPresetInput.value = p.name; this.addPresetInput.value = p.name;
} }
}, ex => console.error(ex)); }, console.error);
}, },
_togglePresets: function () { _togglePresets: function () {
@ -612,8 +612,8 @@ CSSFilterEditorWidget.prototype = {
} }
this.setPresets(presets).then(this.renderPresets, this.setPresets(presets).then(this.renderPresets,
ex => console.error(ex)); console.error);
}, ex => console.error(ex)); }, console.error);
}, },
/** /**
@ -952,12 +952,12 @@ CSSFilterEditorWidget.prototype = {
} }
return presets; return presets;
}, e => console.error(e)); }, console.error);
}, },
setPresets: function (presets) { setPresets: function (presets) {
return asyncStorage.setItem("cssFilterPresets", presets) return asyncStorage.setItem("cssFilterPresets", presets)
.catch(e => console.error(e)); .catch(console.error);
} }
}; };

Просмотреть файл

@ -171,7 +171,7 @@ SwatchColorPickerTooltip.prototype = extend(SwatchBasedEditorTooltip.prototype,
this.hide(); this.hide();
this.tooltip.emit("eyedropper-opened"); this.tooltip.emit("eyedropper-opened");
}, e => console.error(e)); }, console.error);
inspector.once("color-picked", color => { inspector.once("color-picked", color => {
toolbox.win.focus(); toolbox.win.focus();

Просмотреть файл

@ -237,7 +237,7 @@ function autoComplete({ ed, cm }) {
}); });
popup.openPopup(cursorElement, -1 * left, 0); popup.openPopup(cursorElement, -1 * left, 0);
autocompleteOpts.suggestionInsertedOnce = false; autocompleteOpts.suggestionInsertedOnce = false;
}).catch(e => console.error(e)); }).catch(console.error);
} }
/** /**

Просмотреть файл

@ -234,7 +234,7 @@ StyleEditorUI.prototype = {
_onNewDocument: function () { _onNewDocument: function () {
this._debuggee.getStyleSheets().then((styleSheets) => { this._debuggee.getStyleSheets().then((styleSheets) => {
return this._resetStyleSheetList(styleSheets); return this._resetStyleSheetList(styleSheets);
}).catch(e => console.error(e)); }).catch(console.error);
}, },
/** /**
@ -634,7 +634,7 @@ StyleEditorUI.prototype = {
this.emit("error", { key: "error-compressed", level: "info" }); this.emit("error", { key: "error-compressed", level: "info" });
} }
} }
}.bind(this)).catch(e => console.error(e)); }.bind(this)).catch(console.error);
} }
}); });
}, },
@ -919,7 +919,7 @@ StyleEditorUI.prototype = {
sidebar.hidden = !showSidebar || !inSource; sidebar.hidden = !showSidebar || !inSource;
this.emit("media-list-changed", editor); this.emit("media-list-changed", editor);
}.bind(this)).catch(e => console.error(e)); }.bind(this)).catch(console.error);
}, },
/** /**

Просмотреть файл

@ -127,7 +127,7 @@ function StyleSheetEditor(styleSheet, win, file, isNew, walker, highlighter) {
this.mediaRules = []; this.mediaRules = [];
if (this.cssSheet.getMediaRules) { if (this.cssSheet.getMediaRules) {
this.cssSheet.getMediaRules().then(this._onMediaRulesChanged, this.cssSheet.getMediaRules().then(this._onMediaRulesChanged,
e => console.error(e)); console.error);
} }
this.cssSheet.on("media-rules-changed", this._onMediaRulesChanged); this.cssSheet.on("media-rules-changed", this._onMediaRulesChanged);
this.cssSheet.on("style-applied", this._onStyleApplied); this.cssSheet.on("style-applied", this._onStyleApplied);
@ -518,7 +518,7 @@ StyleSheetEditor.prototype = {
* Toggled the disabled state of the underlying stylesheet. * Toggled the disabled state of the underlying stylesheet.
*/ */
toggleDisabled: function () { toggleDisabled: function () {
this.styleSheet.toggleDisabled().catch(e => console.error(e)); this.styleSheet.toggleDisabled().catch(console.error);
}, },
/** /**
@ -560,7 +560,7 @@ StyleSheetEditor.prototype = {
this._isUpdating = true; this._isUpdating = true;
this.styleSheet.update(this._state.text, this.transitionsEnabled) this.styleSheet.update(this._state.text, this.transitionsEnabled)
.catch(e => console.error(e)); .catch(console.error);
}, },
/** /**

Просмотреть файл

@ -3072,7 +3072,7 @@ Widgets.ObjectRenderers.add({
// the message is destroyed. // the message is destroyed.
this.message.widgets.add(this); this.message.widgets.add(this);
this.linkToInspector().catch(e => console.error(e)); this.linkToInspector().catch(console.error);
}, },
/** /**
@ -3160,7 +3160,7 @@ Widgets.ObjectRenderers.add({
unhighlightDomNode: function () { unhighlightDomNode: function () {
return this.linkToInspector().then(() => { return this.linkToInspector().then(() => {
return this.toolbox.highlighterUtils.unhighlight(); return this.toolbox.highlighterUtils.unhighlight();
}).catch(e => console.error(e)); }).catch(console.error);
}, },
/** /**

Просмотреть файл

@ -97,7 +97,7 @@ function mixedContentOverrideTest2(hud, browser) {
objects: true, objects: true,
}, },
], ],
}).then(msgs => deferred.resolve(msgs), e => console.error(e)); }).then(msgs => deferred.resolve(msgs), console.error);
return deferred.promise; return deferred.promise;
} }

Просмотреть файл

@ -102,7 +102,7 @@ function CheckLockState() {
adbCheckResult.textContent = sNo; adbCheckResult.textContent = sNo;
adbRootAction.removeAttribute("hidden"); adbRootAction.removeAttribute("hidden");
} }
}, e => console.error(e)); }, console.error);
} else { } else {
adbCheckResult.textContent = sUnknown; adbCheckResult.textContent = sUnknown;
} }
@ -120,7 +120,7 @@ function CheckLockState() {
} else { } else {
devtoolsCheckResult.textContent = sYes; devtoolsCheckResult.textContent = sYes;
} }
}, e => console.error(e)); }, console.error);
} catch (e) { } catch (e) {
// Exception. pref actor is only accessible if forbird-certified-apps is false // Exception. pref actor is only accessible if forbird-certified-apps is false
devtoolsCheckResult.textContent = sNo; devtoolsCheckResult.textContent = sNo;
@ -147,5 +147,5 @@ function EnableCertApps() {
function RootADB() { function RootADB() {
let device = AppManager.selectedRuntime.device; let device = AppManager.selectedRuntime.device;
device.summonRoot().then(CheckLockState, (e) => console.error(e)); device.summonRoot().then(CheckLockState, console.error);
} }

Просмотреть файл

@ -43,7 +43,7 @@ The `hasActor` method returns a boolean synchronously.
```js ```js
toolbox.target.actorHasMethod("domwalker", "duplicateNode").then(hasMethod => { toolbox.target.actorHasMethod("domwalker", "duplicateNode").then(hasMethod => {
}).catch(e => console.error(e)); }).catch(console.error);
``` ```
The `actorHasMethod` returns a promise that resolves to a boolean. The `actorHasMethod` returns a promise that resolves to a boolean.

Просмотреть файл

@ -383,7 +383,7 @@ EyeDropper.prototype = {
} }
this.emit("selected", toColorString(this.centerColor, this.format)); this.emit("selected", toColorString(this.centerColor, this.format));
onColorSelected.then(() => this.hide(), e => console.error(e)); onColorSelected.then(() => this.hide(), console.error);
}, },
/** /**

Просмотреть файл

@ -1251,7 +1251,7 @@ Front.prototype = extend(Pool.prototype, {
this.actor().then(actorID => { this.actor().then(actorID => {
packet.to = actorID; packet.to = actorID;
this.conn._transport.send(packet); this.conn._transport.send(packet);
}).catch(e => console.error(e)); }).catch(console.error);
} }
}, },

Просмотреть файл

@ -51,7 +51,7 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
PushLayerLocalClip(aStackingContext); PushLayerLocalClip(aStackingContext);
} }
PushScrollLayer(fm, aStackingContext); DefineAndPushScrollLayer(fm, aStackingContext);
} }
// The scrolled clip on the layer is "inside" all of the scrollable metadatas // The scrolled clip on the layer is "inside" all of the scrollable metadatas
@ -146,10 +146,7 @@ ScrollingLayersHelper::DefineAndPushScrollLayers(nsDisplayItem* aItem,
if (!aAsr) { if (!aAsr) {
return; return;
} }
Maybe<ScrollMetadata> metadata = aAsr->mScrollableFrame->ComputeScrollMetadata( FrameMetrics::ViewID scrollId = nsLayoutUtils::ViewIDForASR(aAsr);
nullptr, aItem->ReferenceFrame(), ContainerLayerParameters(), nullptr);
MOZ_ASSERT(metadata);
FrameMetrics::ViewID scrollId = metadata->GetMetrics().GetScrollId();
if (aBuilder.TopmostScrollId() == scrollId) { if (aBuilder.TopmostScrollId() == scrollId) {
// it's already been pushed, so we don't need to recurse any further. // it's already been pushed, so we don't need to recurse any further.
return; return;
@ -176,11 +173,19 @@ ScrollingLayersHelper::DefineAndPushScrollLayers(nsDisplayItem* aItem,
// push exactly what we want. // push exactly what we want.
DefineAndPushChain(asrClippedBy, aBuilder, aStackingContext, DefineAndPushChain(asrClippedBy, aBuilder, aStackingContext,
aAppUnitsPerDevPixel, aCache); aAppUnitsPerDevPixel, aCache);
// Finally, push the ASR itself as a scroll layer. Note that the // Finally, push the ASR itself as a scroll layer. If it's already defined
// implementation of wr_push_scroll_layer in bindings.rs makes sure the // we can skip the expensive step of computing the ScrollMetadata.
// scroll layer doesn't get defined multiple times so we don't need to worry bool pushed = false;
// about that here. if (mBuilder->IsScrollLayerDefined(scrollId)) {
if (PushScrollLayer(metadata->GetMetrics(), aStackingContext)) { mBuilder->PushScrollLayer(scrollId);
pushed = true;
} else {
Maybe<ScrollMetadata> metadata = aAsr->mScrollableFrame->ComputeScrollMetadata(
nullptr, aItem->ReferenceFrame(), ContainerLayerParameters(), nullptr);
MOZ_ASSERT(metadata);
pushed = DefineAndPushScrollLayer(metadata->GetMetrics(), aStackingContext);
}
if (pushed) {
mPushedClips.push_back(wr::ScrollOrClipId(scrollId)); mPushedClips.push_back(wr::ScrollOrClipId(scrollId));
} }
} }
@ -228,7 +233,7 @@ ScrollingLayersHelper::DefineAndPushChain(const DisplayItemClipChain* aChain,
} }
bool bool
ScrollingLayersHelper::PushScrollLayer(const FrameMetrics& aMetrics, ScrollingLayersHelper::DefineAndPushScrollLayer(const FrameMetrics& aMetrics,
const StackingContextHelper& aStackingContext) const StackingContextHelper& aStackingContext)
{ {
if (!aMetrics.IsScrollable()) { if (!aMetrics.IsScrollable()) {
@ -251,9 +256,10 @@ ScrollingLayersHelper::PushScrollLayer(const FrameMetrics& aMetrics,
// WebRender at all. Instead, we take the position from the composition // WebRender at all. Instead, we take the position from the composition
// bounds. // bounds.
contentRect.MoveTo(clipBounds.TopLeft()); contentRect.MoveTo(clipBounds.TopLeft());
mBuilder->PushScrollLayer(aMetrics.GetScrollId(), mBuilder->DefineScrollLayer(aMetrics.GetScrollId(),
aStackingContext.ToRelativeLayoutRect(contentRect), aStackingContext.ToRelativeLayoutRect(contentRect),
aStackingContext.ToRelativeLayoutRect(clipBounds)); aStackingContext.ToRelativeLayoutRect(clipBounds));
mBuilder->PushScrollLayer(aMetrics.GetScrollId());
return true; return true;
} }

Просмотреть файл

@ -49,7 +49,7 @@ private:
const StackingContextHelper& aStackingContext, const StackingContextHelper& aStackingContext,
int32_t aAppUnitsPerDevPixel, int32_t aAppUnitsPerDevPixel,
WebRenderLayerManager::ClipIdMap& aCache); WebRenderLayerManager::ClipIdMap& aCache);
bool PushScrollLayer(const FrameMetrics& aMetrics, bool DefineAndPushScrollLayer(const FrameMetrics& aMetrics,
const StackingContextHelper& aStackingContext); const StackingContextHelper& aStackingContext);
void PushLayerLocalClip(const StackingContextHelper& aStackingContext); void PushLayerLocalClip(const StackingContextHelper& aStackingContext);
void PushLayerClip(const LayerClip& aClip, void PushLayerClip(const LayerClip& aClip,

Просмотреть файл

@ -694,21 +694,39 @@ DisplayListBuilder::PushBuiltDisplayList(BuiltDisplayList &dl)
&dl.dl.inner); &dl.dl.inner);
} }
bool
DisplayListBuilder::IsScrollLayerDefined(layers::FrameMetrics::ViewID aScrollId) const
{
return mScrollParents.find(aScrollId) != mScrollParents.end();
}
void void
DisplayListBuilder::PushScrollLayer(const layers::FrameMetrics::ViewID& aScrollId, DisplayListBuilder::DefineScrollLayer(const layers::FrameMetrics::ViewID& aScrollId,
const wr::LayoutRect& aContentRect, const wr::LayoutRect& aContentRect,
const wr::LayoutRect& aClipRect) const wr::LayoutRect& aClipRect)
{ {
WRDL_LOG("PushScrollLayer id=%" PRIu64 " co=%s cl=%s\n", mWrState, WRDL_LOG("DefineScrollLayer id=%" PRIu64 " co=%s cl=%s\n", mWrState,
aScrollId, Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str()); aScrollId, Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
wr_dp_push_scroll_layer(mWrState, aScrollId, aContentRect, aClipRect);
if (!mScrollIdStack.empty()) { Maybe<layers::FrameMetrics::ViewID> parent =
auto it = mScrollParents.insert({aScrollId, mScrollIdStack.back()}); mScrollIdStack.empty() ? Nothing() : Some(mScrollIdStack.back());
if (!it.second) { // aScrollId was already a key in mScrollParents auto it = mScrollParents.insert({aScrollId, parent});
// so check that the parent value is the same. if (it.second) {
MOZ_ASSERT(it.first->second == mScrollIdStack.back()); // An insertion took place, which means we haven't defined aScrollId before.
// So let's define it now.
wr_dp_define_scroll_layer(mWrState, aScrollId, aContentRect, aClipRect);
} else {
// aScrollId was already a key in mScrollParents so check that the parent
// value is the same.
MOZ_ASSERT(it.first->second == parent);
} }
} }
void
DisplayListBuilder::PushScrollLayer(const layers::FrameMetrics::ViewID& aScrollId)
{
WRDL_LOG("PushScrollLayer id=%" PRIu64 "\n", mWrState, aScrollId);
wr_dp_push_scroll_layer(mWrState, aScrollId);
mScrollIdStack.push_back(aScrollId); mScrollIdStack.push_back(aScrollId);
} }
@ -1027,7 +1045,7 @@ Maybe<layers::FrameMetrics::ViewID>
DisplayListBuilder::ParentScrollIdFor(layers::FrameMetrics::ViewID aScrollId) DisplayListBuilder::ParentScrollIdFor(layers::FrameMetrics::ViewID aScrollId)
{ {
auto it = mScrollParents.find(aScrollId); auto it = mScrollParents.find(aScrollId);
return (it == mScrollParents.end() ? Nothing() : Some(it->second)); return (it == mScrollParents.end() ? Nothing() : it->second);
} }
} // namespace wr } // namespace wr

Просмотреть файл

@ -203,9 +203,11 @@ public:
void PushBuiltDisplayList(wr::BuiltDisplayList &dl); void PushBuiltDisplayList(wr::BuiltDisplayList &dl);
void PushScrollLayer(const layers::FrameMetrics::ViewID& aScrollId, bool IsScrollLayerDefined(layers::FrameMetrics::ViewID aScrollId) const;
void DefineScrollLayer(const layers::FrameMetrics::ViewID& aScrollId,
const wr::LayoutRect& aContentRect, // TODO: We should work with strongly typed rects const wr::LayoutRect& aContentRect, // TODO: We should work with strongly typed rects
const wr::LayoutRect& aClipRect); const wr::LayoutRect& aClipRect);
void PushScrollLayer(const layers::FrameMetrics::ViewID& aScrollId);
void PopScrollLayer(); void PopScrollLayer();
void PushClipAndScrollInfo(const layers::FrameMetrics::ViewID& aScrollId, void PushClipAndScrollInfo(const layers::FrameMetrics::ViewID& aScrollId,
@ -356,8 +358,10 @@ protected:
std::vector<wr::WrClipId> mClipIdStack; std::vector<wr::WrClipId> mClipIdStack;
std::vector<layers::FrameMetrics::ViewID> mScrollIdStack; std::vector<layers::FrameMetrics::ViewID> mScrollIdStack;
// Track the parent scroll id of each scroll id that we encountered. // Track the parent scroll id of each scroll id that we encountered. A
std::unordered_map<layers::FrameMetrics::ViewID, layers::FrameMetrics::ViewID> mScrollParents; // Nothing() value indicates a root scroll id. We also use this structure to
// ensure that we don't define a particular scroll layer multiple times.
std::unordered_map<layers::FrameMetrics::ViewID, Maybe<layers::FrameMetrics::ViewID>> mScrollParents;
friend class WebRenderAPI; friend class WebRenderAPI;
}; };

Просмотреть файл

@ -1,4 +1,3 @@
use std::collections::HashSet;
use std::ffi::CString; use std::ffi::CString;
use std::{mem, slice}; use std::{mem, slice};
use std::path::PathBuf; use std::path::PathBuf;
@ -954,7 +953,6 @@ pub unsafe extern "C" fn wr_api_get_namespace(dh: &mut DocumentHandle) -> WrIdNa
pub struct WebRenderFrameBuilder { pub struct WebRenderFrameBuilder {
pub root_pipeline_id: WrPipelineId, pub root_pipeline_id: WrPipelineId,
pub dl_builder: webrender_api::DisplayListBuilder, pub dl_builder: webrender_api::DisplayListBuilder,
pub scroll_clips_defined: HashSet<ClipId>,
} }
impl WebRenderFrameBuilder { impl WebRenderFrameBuilder {
@ -963,7 +961,6 @@ impl WebRenderFrameBuilder {
WebRenderFrameBuilder { WebRenderFrameBuilder {
root_pipeline_id: root_pipeline_id, root_pipeline_id: root_pipeline_id,
dl_builder: webrender_api::DisplayListBuilder::new(root_pipeline_id, content_size), dl_builder: webrender_api::DisplayListBuilder::new(root_pipeline_id, content_size),
scroll_clips_defined: HashSet::new(),
} }
} }
} }
@ -1130,21 +1127,22 @@ pub extern "C" fn wr_dp_pop_clip(state: &mut WrState) {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn wr_dp_push_scroll_layer(state: &mut WrState, pub extern "C" fn wr_dp_define_scroll_layer(state: &mut WrState,
scroll_id: u64, scroll_id: u64,
content_rect: LayoutRect, content_rect: LayoutRect,
clip_rect: LayoutRect) { clip_rect: LayoutRect) {
assert!(unsafe { is_in_main_thread() }); assert!(unsafe { is_in_main_thread() });
let clip_id = ClipId::new(scroll_id, state.pipeline_id); let clip_id = ClipId::new(scroll_id, state.pipeline_id);
// Avoid defining multiple scroll clips with the same clip id, as that
// results in undefined behaviour or assertion failures.
if !state.frame_builder.scroll_clips_defined.contains(&clip_id) {
state.frame_builder.dl_builder.define_scroll_frame( state.frame_builder.dl_builder.define_scroll_frame(
Some(clip_id), content_rect, clip_rect, vec![], None, Some(clip_id), content_rect, clip_rect, vec![], None,
ScrollSensitivity::Script); ScrollSensitivity::Script);
state.frame_builder.scroll_clips_defined.insert(clip_id);
} }
#[no_mangle]
pub extern "C" fn wr_dp_push_scroll_layer(state: &mut WrState,
scroll_id: u64) {
assert!(unsafe { is_in_main_thread() });
let clip_id = ClipId::new(scroll_id, state.pipeline_id);
state.frame_builder.dl_builder.push_clip_id(clip_id); state.frame_builder.dl_builder.push_clip_id(clip_id);
} }

Просмотреть файл

@ -920,6 +920,13 @@ uint64_t wr_dp_define_clip(WrState *aState,
const WrImageMask *aMask) const WrImageMask *aMask)
WR_FUNC; WR_FUNC;
WR_INLINE
void wr_dp_define_scroll_layer(WrState *aState,
uint64_t aScrollId,
LayoutRect aContentRect,
LayoutRect aClipRect)
WR_FUNC;
WR_INLINE WR_INLINE
void wr_dp_end(WrState *aState) void wr_dp_end(WrState *aState)
WR_FUNC; WR_FUNC;
@ -1087,9 +1094,7 @@ WR_FUNC;
WR_INLINE WR_INLINE
void wr_dp_push_scroll_layer(WrState *aState, void wr_dp_push_scroll_layer(WrState *aState,
uint64_t aScrollId, uint64_t aScrollId)
LayoutRect aContentRect,
LayoutRect aClipRect)
WR_FUNC; WR_FUNC;
WR_INLINE WR_INLINE

Просмотреть файл

@ -397,11 +397,7 @@ var Addons = {
// Allow the options to use all the available width space. // Allow the options to use all the available width space.
optionsBox.classList.remove("inner"); optionsBox.classList.remove("inner");
// WebExtensions are loaded asynchronously and the optionsURL this.createWebExtensionOptions(optionsBox, addon);
// may not be available via listitem when the add-on has just been
// installed, but it is available on the addon if one is set.
detailItem.setAttribute("optionsURL", addon.optionsURL);
this.createWebExtensionOptions(optionsBox, addon.optionsURL, addon.optionsBrowserStyle);
break; break;
case AddonManager.OPTIONS_TYPE_TAB: case AddonManager.OPTIONS_TYPE_TAB:
// Keep the usual layout for any options related the legacy (or system) add-ons // Keep the usual layout for any options related the legacy (or system) add-ons
@ -441,14 +437,28 @@ var Addons = {
} }
button.onclick = async () => { button.onclick = async () => {
if (addon.isWebExtension) {
// WebExtensions are loaded asynchronously and the optionsURL
// may not be available until the addon has been started.
await addon.startupPromise;
}
const {optionsURL} = addon; const {optionsURL} = addon;
openOptionsInTab(optionsURL); openOptionsInTab(optionsURL);
}; };
}, },
createWebExtensionOptions: async function(destination, optionsURL, browserStyle) { createWebExtensionOptions: async function(destination, addon) {
// WebExtensions are loaded asynchronously and the optionsURL
// may not be available until the addon has been started.
await addon.startupPromise;
const {optionsURL, optionsBrowserStyle} = addon;
let frame = destination.querySelector("iframe#addon-options");
if (!frame) {
let originalHeight; let originalHeight;
let frame = document.createElement("iframe"); frame = document.createElement("iframe");
frame.setAttribute("id", "addon-options"); frame.setAttribute("id", "addon-options");
frame.setAttribute("mozbrowser", "true"); frame.setAttribute("mozbrowser", "true");
frame.setAttribute("style", "width: 100%; overflow: hidden;"); frame.setAttribute("style", "width: 100%; overflow: hidden;");
@ -477,8 +487,8 @@ var Addons = {
}; };
destination.appendChild(frame); destination.appendChild(frame);
originalHeight = frame.getBoundingClientRect().height; originalHeight = frame.getBoundingClientRect().height;
}
// Loading the URL this way prevents the native back // Loading the URL this way prevents the native back
// button from applying to the iframe. // button from applying to the iframe.
@ -585,6 +595,14 @@ var Addons = {
detailItem.setAttribute("opType", opType); detailItem.setAttribute("opType", opType);
else else
detailItem.removeAttribute("opType"); detailItem.removeAttribute("opType");
// Remove any addon options iframe if the currently selected addon has been disabled.
if (!aValue) {
const addonOptionsIframe = document.querySelector("#addon-options");
if (addonOptionsIframe) {
addonOptionsIframe.remove();
}
}
} }
// Sync to the list item // Sync to the list item

Просмотреть файл

@ -84,6 +84,14 @@ function waitAboutAddonsLoaded() {
return waitDOMContentLoaded(url => url === "about:addons"); return waitDOMContentLoaded(url => url === "about:addons");
} }
function clickAddonDisable() {
content.document.querySelector("#disable-btn").click();
}
function clickAddonEnable() {
content.document.querySelector("#enable-btn").click();
}
add_task(async function test_options_ui_iframe_height() { add_task(async function test_options_ui_iframe_height() {
let addonID = "test-options-ui@mozilla.org"; let addonID = "test-options-ui@mozilla.org";
@ -406,6 +414,86 @@ add_task(async function test_options_ui_open_in_tab() {
await extension.unload(); await extension.unload();
}); });
add_task(async function test_options_ui_on_disable_and_enable() {
let addonID = "test-options-ui-disable-enable@mozilla.org";
function optionsScript() {
browser.test.sendMessage("options-page-loaded", window.location.href);
}
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
applications: {
gecko: {id: addonID},
},
name: "Options UI open addon details Extension",
description: "Longer addon description",
options_ui: {
page: "options.html",
},
},
files: {
"options.js": optionsScript,
"options.html": `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>Options page</h1>
<script src="options.js"><\/script>
</body>
</html>
`,
},
});
await extension.startup();
const {BrowserApp} = Services.wm.getMostRecentWindow("navigator:browser");
let onceAboutAddonsLoaded = waitAboutAddonsLoaded();
BrowserApp.addTab("about:addons", {
selected: true,
parentId: BrowserApp.selectedTab.id,
});
await onceAboutAddonsLoaded;
const aboutAddonsTab = BrowserApp.selectedTab;
is(aboutAddonsTab.currentURI.spec, "about:addons",
"about:addons is the currently selected tab");
info("Wait the addon details to have been loaded");
await ContentTask.spawn(aboutAddonsTab.browser, addonID, waitAboutAddonsRendered);
await ContentTask.spawn(aboutAddonsTab.browser, addonID, navigateToAddonDetails);
info("Wait the addon options page to have been loaded");
await extension.awaitMessage("options-page-loaded");
info("Click the addon disable button");
await ContentTask.spawn(aboutAddonsTab.browser, null, clickAddonDisable);
// NOTE: Currently after disabling the addon the extension.awaitMessage seems
// to fail be able to receive events coming from the browser.test.sendMessage API
// (nevertheless `await extension.unload()` seems to be able to remove the extension),
// falling back to wait for the options page to be loaded here.
const onceAddonOptionsLoaded = waitDOMContentLoaded(url => url.endsWith("options.html"));
info("Click the addon enable button");
await ContentTask.spawn(aboutAddonsTab.browser, null, clickAddonEnable);
info("Wait the addon options page to have been loaded after clicking the addon enable button");
await onceAddonOptionsLoaded;
BrowserApp.closeTab(BrowserApp.selectedTab);
await extension.unload();
});
</script> </script>
</body> </body>

Просмотреть файл

@ -1140,4 +1140,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1; static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1512494652111000); static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1512667462291000);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -2064,6 +2064,9 @@ class IDLType(IDLObject):
def isRecord(self): def isRecord(self):
return False return False
def isReadableStream(self):
return False
def isArrayBuffer(self): def isArrayBuffer(self):
return False return False
@ -2091,12 +2094,12 @@ class IDLType(IDLObject):
def isSpiderMonkeyInterface(self): def isSpiderMonkeyInterface(self):
""" Returns a boolean indicating whether this type is an 'interface' """ Returns a boolean indicating whether this type is an 'interface'
type that is implemented in Spidermonkey. At the moment, this type that is implemented in SpiderMonkey. """
only returns true for the types from the TypedArray spec. """
return self.isInterface() and (self.isArrayBuffer() or return self.isInterface() and (self.isArrayBuffer() or
self.isArrayBufferView() or self.isArrayBufferView() or
self.isSharedArrayBuffer() or self.isSharedArrayBuffer() or
self.isTypedArray()) self.isTypedArray() or
self.isReadableStream())
def isDictionary(self): def isDictionary(self):
return False return False
@ -2289,6 +2292,9 @@ class IDLNullableType(IDLParametrizedType):
def isRecord(self): def isRecord(self):
return self.inner.isRecord() return self.inner.isRecord()
def isReadableStream(self):
return self.inner.isReadableStream()
def isArrayBuffer(self): def isArrayBuffer(self):
return self.inner.isArrayBuffer() return self.inner.isArrayBuffer()
@ -2656,6 +2662,9 @@ class IDLTypedefType(IDLType):
def isRecord(self): def isRecord(self):
return self.inner.isRecord() return self.inner.isRecord()
def isReadableStream(self):
return self.inner.isReadableStream()
def isDictionary(self): def isDictionary(self):
return self.inner.isDictionary() return self.inner.isDictionary()
@ -2970,7 +2979,8 @@ class IDLBuiltinType(IDLType):
'Int32Array', 'Int32Array',
'Uint32Array', 'Uint32Array',
'Float32Array', 'Float32Array',
'Float64Array' 'Float64Array',
'ReadableStream',
) )
TagLookup = { TagLookup = {
@ -3005,7 +3015,8 @@ class IDLBuiltinType(IDLType):
Types.Int32Array: IDLType.Tags.interface, Types.Int32Array: IDLType.Tags.interface,
Types.Uint32Array: IDLType.Tags.interface, Types.Uint32Array: IDLType.Tags.interface,
Types.Float32Array: IDLType.Tags.interface, Types.Float32Array: IDLType.Tags.interface,
Types.Float64Array: IDLType.Tags.interface Types.Float64Array: IDLType.Tags.interface,
Types.ReadableStream: IDLType.Tags.interface,
} }
def __init__(self, location, name, type): def __init__(self, location, name, type):
@ -3052,6 +3063,9 @@ class IDLBuiltinType(IDLType):
return (self._typeTag >= IDLBuiltinType.Types.Int8Array and return (self._typeTag >= IDLBuiltinType.Types.Int8Array and
self._typeTag <= IDLBuiltinType.Types.Float64Array) self._typeTag <= IDLBuiltinType.Types.Float64Array)
def isReadableStream(self):
return self._typeTag == IDLBuiltinType.Types.ReadableStream
def isInterface(self): def isInterface(self):
# TypedArray things are interface types per the TypedArray spec, # TypedArray things are interface types per the TypedArray spec,
# but we handle them as builtins because SpiderMonkey implements # but we handle them as builtins because SpiderMonkey implements
@ -3059,7 +3073,8 @@ class IDLBuiltinType(IDLType):
return (self.isArrayBuffer() or return (self.isArrayBuffer() or
self.isArrayBufferView() or self.isArrayBufferView() or
self.isSharedArrayBuffer() or self.isSharedArrayBuffer() or
self.isTypedArray()) self.isTypedArray() or
self.isReadableStream())
def isNonCallbackInterface(self): def isNonCallbackInterface(self):
# All the interfaces we can be are non-callback # All the interfaces we can be are non-callback
@ -3129,6 +3144,7 @@ class IDLBuiltinType(IDLType):
# that's not an ArrayBuffer or a callback interface # that's not an ArrayBuffer or a callback interface
(self.isArrayBuffer() and not other.isArrayBuffer()) or (self.isArrayBuffer() and not other.isArrayBuffer()) or
(self.isSharedArrayBuffer() and not other.isSharedArrayBuffer()) or (self.isSharedArrayBuffer() and not other.isSharedArrayBuffer()) or
(self.isReadableStream() and not other.isReadableStream()) or
# ArrayBufferView is distinguishable from everything # ArrayBufferView is distinguishable from everything
# that's not an ArrayBufferView or typed array. # that's not an ArrayBufferView or typed array.
(self.isArrayBufferView() and not other.isArrayBufferView() and (self.isArrayBufferView() and not other.isArrayBufferView() and
@ -3238,7 +3254,10 @@ BuiltinTypes = {
IDLBuiltinType.Types.Float32Array), IDLBuiltinType.Types.Float32Array),
IDLBuiltinType.Types.Float64Array: IDLBuiltinType.Types.Float64Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array", IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array",
IDLBuiltinType.Types.Float64Array) IDLBuiltinType.Types.Float64Array),
IDLBuiltinType.Types.ReadableStream:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "ReadableStream",
IDLBuiltinType.Types.ReadableStream),
} }
@ -5287,7 +5306,8 @@ class Tokenizer(object):
"maplike": "MAPLIKE", "maplike": "MAPLIKE",
"setlike": "SETLIKE", "setlike": "SETLIKE",
"iterable": "ITERABLE", "iterable": "ITERABLE",
"namespace": "NAMESPACE" "namespace": "NAMESPACE",
"ReadableStream": "READABLESTREAM",
} }
tokens.extend(keywords.values()) tokens.extend(keywords.values())
@ -6475,6 +6495,7 @@ class Parser(Tokenizer):
NonAnyType : PrimitiveType Null NonAnyType : PrimitiveType Null
| ARRAYBUFFER Null | ARRAYBUFFER Null
| SHAREDARRAYBUFFER Null | SHAREDARRAYBUFFER Null
| READABLESTREAM Null
| OBJECT Null | OBJECT Null
""" """
if p[1] == "object": if p[1] == "object":
@ -6483,6 +6504,8 @@ class Parser(Tokenizer):
type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer] type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer]
elif p[1] == "SharedArrayBuffer": elif p[1] == "SharedArrayBuffer":
type = BuiltinTypes[IDLBuiltinType.Types.SharedArrayBuffer] type = BuiltinTypes[IDLBuiltinType.Types.SharedArrayBuffer]
elif p[1] == "ReadableStream":
type = BuiltinTypes[IDLBuiltinType.Types.ReadableStream]
else: else:
type = BuiltinTypes[p[1]] type = BuiltinTypes[p[1]]

Просмотреть файл

@ -11,7 +11,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("chrome://marionette/content/assert.js"); Cu.import("chrome://marionette/content/assert.js");
Cu.import("chrome://marionette/content/element.js"); Cu.import("chrome://marionette/content/element.js");
const { const {
error, pprint,
InvalidArgumentError, InvalidArgumentError,
MoveTargetOutOfBoundsError, MoveTargetOutOfBoundsError,
UnsupportedOperationError, UnsupportedOperationError,
@ -21,8 +21,6 @@ Cu.import("chrome://marionette/content/interaction.js");
this.EXPORTED_SYMBOLS = ["action"]; this.EXPORTED_SYMBOLS = ["action"];
const {pprint} = error;
// TODO? With ES 2016 and Symbol you can make a safer approximation // TODO? With ES 2016 and Symbol you can make a safer approximation
// to an enum e.g. https://gist.github.com/xmlking/e86e4f15ec32b12c4689 // to an enum e.g. https://gist.github.com/xmlking/e86e4f15ec32b12c4689
/** /**

Просмотреть файл

@ -11,10 +11,10 @@ Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
const { const {
error,
InvalidArgumentError, InvalidArgumentError,
InvalidSessionIDError, InvalidSessionIDError,
NoSuchWindowError, NoSuchWindowError,
pprint,
UnexpectedAlertOpenError, UnexpectedAlertOpenError,
UnsupportedOperationError, UnsupportedOperationError,
} = Cu.import("chrome://marionette/content/error.js", {}); } = Cu.import("chrome://marionette/content/error.js", {});
@ -174,7 +174,7 @@ assert.noUserPrompt = function(dialog, msg = "") {
* If |obj| is not defined. * If |obj| is not defined.
*/ */
assert.defined = function(obj, msg = "") { assert.defined = function(obj, msg = "") {
msg = msg || error.pprint`Expected ${obj} to be defined`; msg = msg || pprint`Expected ${obj} to be defined`;
return assert.that(o => typeof o != "undefined", msg)(obj); return assert.that(o => typeof o != "undefined", msg)(obj);
}; };
@ -193,7 +193,7 @@ assert.defined = function(obj, msg = "") {
* If |obj| is not a number. * If |obj| is not a number.
*/ */
assert.number = function(obj, msg = "") { assert.number = function(obj, msg = "") {
msg = msg || error.pprint`Expected ${obj} to be finite number`; msg = msg || pprint`Expected ${obj} to be finite number`;
return assert.that(Number.isFinite, msg)(obj); return assert.that(Number.isFinite, msg)(obj);
}; };
@ -212,7 +212,7 @@ assert.number = function(obj, msg = "") {
* If |obj| is not callable. * If |obj| is not callable.
*/ */
assert.callable = function(obj, msg = "") { assert.callable = function(obj, msg = "") {
msg = msg || error.pprint`${obj} is not callable`; msg = msg || pprint`${obj} is not callable`;
return assert.that(o => typeof o == "function", msg)(obj); return assert.that(o => typeof o == "function", msg)(obj);
}; };
@ -231,7 +231,7 @@ assert.callable = function(obj, msg = "") {
* If |obj| is not an integer. * If |obj| is not an integer.
*/ */
assert.integer = function(obj, msg = "") { assert.integer = function(obj, msg = "") {
msg = msg || error.pprint`Expected ${obj} to be an integer`; msg = msg || pprint`Expected ${obj} to be an integer`;
return assert.that(Number.isInteger, msg)(obj); return assert.that(Number.isInteger, msg)(obj);
}; };
@ -251,7 +251,7 @@ assert.integer = function(obj, msg = "") {
*/ */
assert.positiveInteger = function(obj, msg = "") { assert.positiveInteger = function(obj, msg = "") {
assert.integer(obj, msg); assert.integer(obj, msg);
msg = msg || error.pprint`Expected ${obj} to be >= 0`; msg = msg || pprint`Expected ${obj} to be >= 0`;
return assert.that(n => n >= 0, msg)(obj); return assert.that(n => n >= 0, msg)(obj);
}; };
@ -270,7 +270,7 @@ assert.positiveInteger = function(obj, msg = "") {
* If |obj| is not a boolean. * If |obj| is not a boolean.
*/ */
assert.boolean = function(obj, msg = "") { assert.boolean = function(obj, msg = "") {
msg = msg || error.pprint`Expected ${obj} to be boolean`; msg = msg || pprint`Expected ${obj} to be boolean`;
return assert.that(b => typeof b == "boolean", msg)(obj); return assert.that(b => typeof b == "boolean", msg)(obj);
}; };
@ -289,7 +289,7 @@ assert.boolean = function(obj, msg = "") {
* If |obj| is not a string. * If |obj| is not a string.
*/ */
assert.string = function(obj, msg = "") { assert.string = function(obj, msg = "") {
msg = msg || error.pprint`Expected ${obj} to be a string`; msg = msg || pprint`Expected ${obj} to be a string`;
return assert.that(s => typeof s == "string", msg)(obj); return assert.that(s => typeof s == "string", msg)(obj);
}; };
@ -308,7 +308,7 @@ assert.string = function(obj, msg = "") {
* If |obj| is not an object. * If |obj| is not an object.
*/ */
assert.object = function(obj, msg = "") { assert.object = function(obj, msg = "") {
msg = msg || error.pprint`Expected ${obj} to be an object`; msg = msg || pprint`Expected ${obj} to be an object`;
return assert.that(o => { return assert.that(o => {
// unable to use instanceof because LHS and RHS may come from // unable to use instanceof because LHS and RHS may come from
// different globals // different globals
@ -335,7 +335,7 @@ assert.object = function(obj, msg = "") {
*/ */
assert.in = function(prop, obj, msg = "") { assert.in = function(prop, obj, msg = "") {
assert.object(obj, msg); assert.object(obj, msg);
msg = msg || error.pprint`Expected ${prop} in ${obj}`; msg = msg || pprint`Expected ${prop} in ${obj}`;
assert.that(p => obj.hasOwnProperty(p), msg)(prop); assert.that(p => obj.hasOwnProperty(p), msg)(prop);
return obj[prop]; return obj[prop];
}; };
@ -355,7 +355,7 @@ assert.in = function(prop, obj, msg = "") {
* If |obj| is not an Array. * If |obj| is not an Array.
*/ */
assert.array = function(obj, msg = "") { assert.array = function(obj, msg = "") {
msg = msg || error.pprint`Expected ${obj} to be an Array`; msg = msg || pprint`Expected ${obj} to be an Array`;
return assert.that(Array.isArray, msg)(obj); return assert.that(Array.isArray, msg)(obj);
}; };

Просмотреть файл

@ -10,8 +10,8 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("chrome://marionette/content/assert.js"); Cu.import("chrome://marionette/content/assert.js");
const { const {
error,
InvalidCookieDomainError, InvalidCookieDomainError,
pprint,
} = Cu.import("chrome://marionette/content/error.js", {}); } = Cu.import("chrome://marionette/content/error.js", {});
this.EXPORTED_SYMBOLS = ["cookie"]; this.EXPORTED_SYMBOLS = ["cookie"];
@ -53,7 +53,7 @@ this.cookie = {
cookie.fromJSON = function(json) { cookie.fromJSON = function(json) {
let newCookie = {}; let newCookie = {};
assert.object(json, error.pprint`Expected cookie object, got ${json}`); assert.object(json, pprint`Expected cookie object, got ${json}`);
newCookie.name = assert.string(json.name, "Cookie name must be string"); newCookie.name = assert.string(json.name, "Cookie name must be string");
newCookie.value = assert.string(json.value, "Cookie value must be string"); newCookie.value = assert.string(json.value, "Cookie value must be string");

Просмотреть файл

@ -12,10 +12,10 @@ Cu.import("resource://gre/modules/Log.jsm");
Cu.import("chrome://marionette/content/assert.js"); Cu.import("chrome://marionette/content/assert.js");
Cu.import("chrome://marionette/content/atom.js"); Cu.import("chrome://marionette/content/atom.js");
const { const {
error,
InvalidSelectorError, InvalidSelectorError,
JavaScriptError, JavaScriptError,
NoSuchElementError, NoSuchElementError,
pprint,
StaleElementReferenceError, StaleElementReferenceError,
} = Cu.import("chrome://marionette/content/error.js", {}); } = Cu.import("chrome://marionette/content/error.js", {});
Cu.import("chrome://marionette/content/wait.js"); Cu.import("chrome://marionette/content/wait.js");
@ -180,7 +180,7 @@ element.Store = class {
if (element.isStale(el)) { if (element.isStale(el)) {
throw new StaleElementReferenceError( throw new StaleElementReferenceError(
error.pprint`The element reference of ${el} stale; ` + pprint`The element reference of ${el} stale; ` +
"either the element is no longer attached to the DOM " + "either the element is no longer attached to the DOM " +
"or the document has been refreshed"); "or the document has been refreshed");
} }

Просмотреть файл

@ -45,7 +45,11 @@ const BUILTIN_ERRORS = new Set([
"URIError", "URIError",
]); ]);
this.EXPORTED_SYMBOLS = ["error", "error.pprint"].concat(Array.from(ERRORS)); this.EXPORTED_SYMBOLS = [
"error",
"pprint",
"stack",
].concat(Array.from(ERRORS));
/** @namespace */ /** @namespace */
this.error = {}; this.error = {};
@ -158,7 +162,7 @@ error.stringify = function(err) {
* pprint`Expected element ${htmlElement}`; * pprint`Expected element ${htmlElement}`;
* => 'Expected element <input id="foo" class="bar baz">' * => 'Expected element <input id="foo" class="bar baz">'
*/ */
error.pprint = function(ss, ...values) { this.pprint = function(ss, ...values) {
function prettyObject(obj) { function prettyObject(obj) {
let proto = Object.prototype.toString.call(obj); let proto = Object.prototype.toString.call(obj);
let s = ""; let s = "";
@ -212,6 +216,14 @@ error.pprint = function(ss, ...values) {
return res.join(""); return res.join("");
}; };
/** Create a stacktrace to the current line in the program. */
this.stack = function() {
let trace = new Error().stack;
let sa = trace.split("\n");
sa = sa.slice(1);
return "stacktrace:\n" + sa.join("\n");
};
/** /**
* WebDriverError is the prototypal parent of all WebDriver errors. * WebDriverError is the prototypal parent of all WebDriver errors.
* It should not be used directly, as it does not correspond to a real * It should not be used directly, as it does not correspond to a real
@ -305,17 +317,17 @@ class ElementClickInterceptedError extends WebDriverError {
switch (obscuredEl.style.pointerEvents) { switch (obscuredEl.style.pointerEvents) {
case "none": case "none":
msg = error.pprint`Element ${obscuredEl} is not clickable ` + msg = pprint`Element ${obscuredEl} is not clickable ` +
`at point (${coords.x},${coords.y}) ` + `at point (${coords.x},${coords.y}) ` +
`because it does not have pointer events enabled, ` + `because it does not have pointer events enabled, ` +
error.pprint`and element ${overlayingEl} ` + pprint`and element ${overlayingEl} ` +
`would receive the click instead`; `would receive the click instead`;
break; break;
default: default:
msg = error.pprint`Element ${obscuredEl} is not clickable ` + msg = pprint`Element ${obscuredEl} is not clickable ` +
`at point (${coords.x},${coords.y}) ` + `at point (${coords.x},${coords.y}) ` +
error.pprint`because another element ${overlayingEl} ` + pprint`because another element ${overlayingEl} ` +
`obscures it`; `obscures it`;
break; break;
} }

Просмотреть файл

@ -11,7 +11,6 @@ Cu.import("chrome://marionette/content/atom.js");
const { const {
ElementClickInterceptedError, ElementClickInterceptedError,
ElementNotInteractableError, ElementNotInteractableError,
error,
InvalidArgument, InvalidArgument,
InvalidArgumentError, InvalidArgumentError,
InvalidElementStateError, InvalidElementStateError,
@ -178,7 +177,7 @@ async function webdriverClickElement(el, a11y) {
// there is no point in checking if it is pointer-interactable // there is no point in checking if it is pointer-interactable
if (!element.isInView(containerEl)) { if (!element.isInView(containerEl)) {
throw new ElementNotInteractableError( throw new ElementNotInteractableError(
error.pprint`Element ${el} could not be scrolled into view`); pprint`Element ${el} could not be scrolled into view`);
} }
// step 7 // step 7

Просмотреть файл

@ -4,7 +4,36 @@
const {utils: Cu} = Components; const {utils: Cu} = Components;
Cu.import("chrome://marionette/content/error.js"); const {
ElementClickInterceptedError,
ElementNotAccessibleError,
ElementNotInteractableError,
error,
InsecureCertificateError,
InvalidArgumentError,
InvalidCookieDomainError,
InvalidElementStateError,
InvalidSelectorError,
InvalidSessionIDError,
JavaScriptError,
MoveTargetOutOfBoundsError,
NoAlertOpenError,
NoSuchElementError,
NoSuchFrameError,
NoSuchWindowError,
pprint,
ScriptTimeoutError,
SessionNotCreatedError,
stack,
StaleElementReferenceError,
TimeoutError,
UnableToSetCookieError,
UnexpectedAlertOpenError,
UnknownCommandError,
UnknownError,
UnsupportedOperationError,
WebDriverError,
} = Cu.import("chrome://marionette/content/error.js", {});
function notok(condition) { function notok(condition) {
ok(!(condition)); ok(!(condition));
@ -90,19 +119,19 @@ add_test(function test_stringify() {
}); });
add_test(function test_pprint() { add_test(function test_pprint() {
equal('[object Object] {"foo":"bar"}', error.pprint`${{foo: "bar"}}`); equal('[object Object] {"foo":"bar"}', pprint`${{foo: "bar"}}`);
equal("[object Number] 42", error.pprint`${42}`); equal("[object Number] 42", pprint`${42}`);
equal("[object Boolean] true", error.pprint`${true}`); equal("[object Boolean] true", pprint`${true}`);
equal("[object Undefined] undefined", error.pprint`${undefined}`); equal("[object Undefined] undefined", pprint`${undefined}`);
equal("[object Null] null", error.pprint`${null}`); equal("[object Null] null", pprint`${null}`);
let complexObj = {toJSON: () => "foo"}; let complexObj = {toJSON: () => "foo"};
equal('[object Object] "foo"', error.pprint`${complexObj}`); equal('[object Object] "foo"', pprint`${complexObj}`);
let cyclic = {}; let cyclic = {};
cyclic.me = cyclic; cyclic.me = cyclic;
equal("[object Object] <cyclic object value>", error.pprint`${cyclic}`); equal("[object Object] <cyclic object value>", pprint`${cyclic}`);
let el = { let el = {
nodeType: 1, nodeType: 1,
@ -111,7 +140,15 @@ add_test(function test_pprint() {
classList: {length: 1}, classList: {length: 1},
className: "bar baz", className: "bar baz",
}; };
equal('<input id="foo" class="bar baz">', error.pprint`${el}`); equal('<input id="foo" class="bar baz">', pprint`${el}`);
run_next_test();
});
add_test(function test_stack() {
equal("string", typeof stack());
ok(stack().includes("test_stack"));
ok(!stack().includes("add_test"));
run_next_test(); run_next_test();
}); });

Просмотреть файл

@ -230,6 +230,11 @@ class Talos(TestingMixin, MercurialScript, BlobUploadMixin, TooltoolMixin,
self.gecko_profile_interval = opts[idx + 1] self.gecko_profile_interval = opts[idx + 1]
except ValueError: except ValueError:
pass pass
else:
# no opts, check for '--geckoProfile' in try message text directly
if self.try_message_has_flag('geckoProfile'):
self.gecko_profile = True
# finally, if gecko_profile is set, we add that to the talos options # finally, if gecko_profile is set, we add that to the talos options
if self.gecko_profile: if self.gecko_profile:
gecko_results.append('--geckoProfile') gecko_results.append('--geckoProfile')

Просмотреть файл

@ -163,8 +163,14 @@ class TryToolsMixin(TransferMixin):
repo_path = None repo_path = None
if self.buildbot_config and 'properties' in self.buildbot_config: if self.buildbot_config and 'properties' in self.buildbot_config:
repo_path = self.buildbot_config['properties'].get('branch') repo_path = self.buildbot_config['properties'].get('branch')
return (self.config.get('branch', repo_path) == 'try' or get_branch = self.config.get('branch', repo_path)
'TRY_COMMIT_MSG' in os.environ) if get_branch is not None:
on_try = ('try' in get_branch or 'Try' in get_branch)
elif os.environ is not None:
on_try = ('TRY_COMMIT_MSG' in os.environ)
else:
on_try = False
return on_try
@PostScriptAction('download-and-extract') @PostScriptAction('download-and-extract')
def set_extra_try_arguments(self, action, success=None): def set_extra_try_arguments(self, action, success=None):

Просмотреть файл

@ -207,14 +207,15 @@ this.PlacesTestUtils = Object.freeze({
* @resolves Returns the field value. * @resolves Returns the field value.
* @rejects JavaScript exception. * @rejects JavaScript exception.
*/ */
async fieldInDB(aURI, field) { fieldInDB(aURI, field) {
let url = aURI instanceof Ci.nsIURI ? new URL(aURI.spec) : new URL(aURI); let url = aURI instanceof Ci.nsIURI ? new URL(aURI.spec) : new URL(aURI);
let db = await PlacesUtils.promiseDBConnection(); return PlacesUtils.withConnectionWrapper("PlacesTestUtils.jsm: fieldInDb", async db => {
let rows = await db.executeCached( let rows = await db.executeCached(
`SELECT ${field} FROM moz_places `SELECT ${field} FROM moz_places
WHERE url_hash = hash(:url) AND url = :url`, WHERE url_hash = hash(:url) AND url = :url`,
{ url: url.href }); { url: url.href });
return rows[0].getResultByIndex(0); return rows[0].getResultByIndex(0);
});
}, },
/** /**

Просмотреть файл

@ -2639,6 +2639,46 @@ profiler_get_buffer_info_helper(uint32_t* aCurrentPosition,
*aGeneration = ActivePS::Buffer(lock).mGeneration; *aGeneration = ActivePS::Buffer(lock).mGeneration;
} }
static void
PollJSSamplingForCurrentThread()
{
MOZ_RELEASE_ASSERT(CorePS::Exists());
PSAutoLock lock(gPSMutex);
ThreadInfo* info = TLSInfo::Info(lock);
if (!info) {
return;
}
info->PollJSSampling();
}
// When the profiler is started on a background thread, we can't synchronously
// call PollJSSampling on the main thread's ThreadInfo. And the next regular
// call to PollJSSampling on the main thread would only happen once the main
// thread triggers a JS interrupt callback.
// This means that all the JS execution between profiler_start() and the first
// JS interrupt would happen with JS sampling disabled, and we wouldn't get any
// JS function information for that period of time.
// So in order to start JS sampling as soon as possible, we dispatch a runnable
// to the main thread which manually calls PollJSSamplingForCurrentThread().
// In some cases this runnable will lose the race with the next JS interrupt.
// That's fine; PollJSSamplingForCurrentThread() is immune to redundant calls.
static void
TriggerPollJSSamplingOnMainThread()
{
nsCOMPtr<nsIThread> mainThread;
nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread));
if (NS_SUCCEEDED(rv) && mainThread) {
nsCOMPtr<nsIRunnable> task =
NS_NewRunnableFunction("TriggerPollJSSamplingOnMainThread", []() {
PollJSSamplingForCurrentThread();
});
SystemGroup::Dispatch(TaskCategory::Other, task.forget());
}
}
static void static void
locked_profiler_start(PSLockRef aLock, int aEntries, double aInterval, locked_profiler_start(PSLockRef aLock, int aEntries, double aInterval,
uint32_t aFeatures, uint32_t aFeatures,
@ -2689,6 +2729,11 @@ locked_profiler_start(PSLockRef aLock, int aEntries, double aInterval,
// We can manually poll the current thread so it starts sampling // We can manually poll the current thread so it starts sampling
// immediately. // immediately.
info->PollJSSampling(); info->PollJSSampling();
} else if (info->IsMainThread()) {
// Dispatch a runnable to the main thread to call PollJSSampling(),
// so that we don't have wait for the next JS interrupt callback in
// order to start profiling JS.
TriggerPollJSSamplingOnMainThread();
} }
} }
} }
@ -3076,17 +3121,7 @@ void
profiler_js_interrupt_callback() profiler_js_interrupt_callback()
{ {
// This function runs on JS threads being sampled. // This function runs on JS threads being sampled.
PollJSSamplingForCurrentThread();
MOZ_RELEASE_ASSERT(CorePS::Exists());
PSAutoLock lock(gPSMutex);
ThreadInfo* info = TLSInfo::Info(lock);
if (!info) {
return;
}
info->PollJSSampling();
} }
double double