зеркало из https://github.com/mozilla/gecko-dev.git
merge fx-team to mozilla-central a=merge
This commit is contained in:
Коммит
f470e82ee2
|
@ -5,7 +5,8 @@
|
|||
"use strict";
|
||||
|
||||
const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
|
||||
const { getSourceNames, parseURL, isScratchpadScheme } = require("devtools/client/shared/source-utils");
|
||||
const { getSourceNames, parseURL,
|
||||
isScratchpadScheme, getSourceMappedFile } = require("devtools/client/shared/source-utils");
|
||||
const { LocalizationHelper } = require("devtools/client/shared/l10n");
|
||||
|
||||
const l10n = new LocalizationHelper("chrome://devtools/locale/components.properties");
|
||||
|
@ -181,15 +182,8 @@ module.exports = createClass({
|
|||
}
|
||||
|
||||
let displaySource = showFullSourceUrl ? long : short;
|
||||
// SourceMapped locations might not be parsed properly by parseURL.
|
||||
// Eg: sourcemapped location could be /folder/file.coffee instead of a url
|
||||
// and so the url parser would not parse non-url locations properly
|
||||
// Check for "/" in displaySource. If "/" is in displaySource,
|
||||
// take everything after last "/".
|
||||
if (isSourceMapped) {
|
||||
displaySource = displaySource.lastIndexOf("/") < 0 ?
|
||||
displaySource :
|
||||
displaySource.slice(displaySource.lastIndexOf("/") + 1);
|
||||
displaySource = getSourceMappedFile(displaySource);
|
||||
} else if (showEmptyPathAsHost && (displaySource === "" || displaySource === "/")) {
|
||||
displaySource = host;
|
||||
}
|
||||
|
|
|
@ -299,9 +299,30 @@ function isChromeScheme(location, i = 0) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method to get the file name from a sourcemapped location
|
||||
* The sourcemap location can be in any form. This method returns a
|
||||
* formatted file name for different cases like Windows or OSX.
|
||||
* @param source
|
||||
* @returns String
|
||||
*/
|
||||
function getSourceMappedFile(source) {
|
||||
// If sourcemapped source is a OSX path, return
|
||||
// the characters after last "/".
|
||||
// If sourcemapped source is a Windowss path, return
|
||||
// the characters after last "\\".
|
||||
if (source.lastIndexOf("/") >= 0) {
|
||||
source = source.slice(source.lastIndexOf("/") + 1);
|
||||
} else if (source.lastIndexOf("\\") >= 0) {
|
||||
source = source.slice(source.lastIndexOf("\\") + 1);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
exports.parseURL = parseURL;
|
||||
exports.getSourceNames = getSourceNames;
|
||||
exports.isScratchpadScheme = isScratchpadScheme;
|
||||
exports.isChromeScheme = isChromeScheme;
|
||||
exports.isContentScheme = isContentScheme;
|
||||
exports.isDataScheme = isDataScheme;
|
||||
exports.getSourceMappedFile = getSourceMappedFile;
|
||||
|
|
|
@ -152,6 +152,22 @@ add_task(function* () {
|
|||
"example.com");
|
||||
});
|
||||
|
||||
// Test for source mapped file name
|
||||
add_task(function* () {
|
||||
const { getSourceMappedFile } = sourceUtils;
|
||||
const source = "baz.js";
|
||||
const output = getSourceMappedFile(source);
|
||||
equal(output, "baz.js", "correctly formats file name");
|
||||
// Test for OSX file path
|
||||
const source1 = "/foo/bar/baz.js";
|
||||
const output1 = getSourceMappedFile(source1);
|
||||
equal(output1, "baz.js", "correctly formats Linux file path");
|
||||
// Test for Windows file path
|
||||
const source2 = "Z:\\foo\\bar\\baz.js";
|
||||
const output2 = getSourceMappedFile(source2);
|
||||
equal(output2, "baz.js", "correctly formats Windows file path");
|
||||
});
|
||||
|
||||
function testAbbreviation(source, short, long, host) {
|
||||
let results = sourceUtils.getSourceNames(source);
|
||||
equal(results.short, short, `${source} has correct "short" name`);
|
||||
|
|
|
@ -15,12 +15,10 @@ var contentSecManager = Cc["@mozilla.org/contentsecuritymanager;1"]
|
|||
|
||||
function forEachWindow(f)
|
||||
{
|
||||
let wins = Services.ww.getWindowEnumerator("navigator:browser");
|
||||
let wins = Services.wm.getEnumerator("navigator:browser");
|
||||
while (wins.hasMoreElements()) {
|
||||
let win = wins.getNext();
|
||||
if (win.gBrowser) {
|
||||
f(win);
|
||||
}
|
||||
f(win);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,10 @@ const baseURL = "http://mochi.test:8888/browser/" +
|
|||
|
||||
function forEachWindow(f)
|
||||
{
|
||||
let wins = Services.ww.getWindowEnumerator("navigator:browser");
|
||||
let wins = Services.wm.getEnumerator("navigator:browser");
|
||||
while (wins.hasMoreElements()) {
|
||||
let win = wins.getNext();
|
||||
if (win.gBrowser) {
|
||||
f(win);
|
||||
}
|
||||
f(win);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -587,6 +587,23 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_setHighlightTimeout">
|
||||
<body><![CDATA[
|
||||
if (this._highlightTimeout)
|
||||
clearTimeout(this._highlightTimeout);
|
||||
|
||||
let word = this._findField.value;
|
||||
// Bug 429723. Don't attempt to highlight ""
|
||||
if (!this._highlightAll || !word)
|
||||
return;
|
||||
|
||||
this._highlightTimeout = setTimeout(() => {
|
||||
this.browser.finder.highlight(true, word,
|
||||
this._findMode == this.FIND_LINKS);
|
||||
}, 500);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
- Updates the case-sensitivity mode of the findbar and its UI.
|
||||
- @param [optional] aString
|
||||
|
@ -681,8 +698,7 @@
|
|||
// Just set the pref; our observer will change the find bar behavior.
|
||||
prefsvc.setBoolPref("findbar.entireword", aEntireWord);
|
||||
|
||||
if (this.getElement("highlight").checked)
|
||||
this._setHighlightTimeout();
|
||||
this._setHighlightTimeout();
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -1026,8 +1042,7 @@
|
|||
}
|
||||
|
||||
this._enableFindButtons(val);
|
||||
if (this.getElement("highlight").checked)
|
||||
this._setHighlightTimeout();
|
||||
this._setHighlightTimeout();
|
||||
|
||||
this._updateCaseSensitivity(val);
|
||||
this._updateEntireWord();
|
||||
|
@ -1070,18 +1085,6 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_setHighlightTimeout">
|
||||
<body><![CDATA[
|
||||
if (this._highlightTimeout)
|
||||
clearTimeout(this._highlightTimeout);
|
||||
this._highlightTimeout =
|
||||
setTimeout(function(aSelf) {
|
||||
aSelf.toggleHighlight(false);
|
||||
aSelf.toggleHighlight(true);
|
||||
}, 500, this);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_findAgain">
|
||||
<parameter name="aFindPrevious"/>
|
||||
<body><![CDATA[
|
||||
|
|
|
@ -134,10 +134,12 @@ Finder.prototype = {
|
|||
|
||||
set caseSensitive(aSensitive) {
|
||||
this._fastFind.caseSensitive = aSensitive;
|
||||
this.iterator.reset();
|
||||
},
|
||||
|
||||
set entireWord(aEntireWord) {
|
||||
this._fastFind.entireWord = aEntireWord;
|
||||
this.iterator.reset();
|
||||
},
|
||||
|
||||
get highlighter() {
|
||||
|
|
|
@ -19,6 +19,7 @@ XPCOMUtils.defineLazyGetter(this, "kDebug", () => {
|
|||
});
|
||||
|
||||
const kModalHighlightRepaintFreqMs = 10;
|
||||
const kHighlightAllPref = "findbar.highlightAll";
|
||||
const kModalHighlightPref = "findbar.modalHighlight";
|
||||
const kFontPropsCSS = ["color", "font-family", "font-kerning", "font-size",
|
||||
"font-size-adjust", "font-stretch", "font-variant", "font-weight", "letter-spacing",
|
||||
|
@ -100,7 +101,6 @@ const kModalStyle = `
|
|||
.findbar-modalHighlight-outlineMask[brighttext] > .findbar-modalHighlight-rect {
|
||||
background: #000;
|
||||
}`;
|
||||
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
function mockAnonymousContentNode(domNode) {
|
||||
return {
|
||||
|
@ -137,8 +137,11 @@ function mockAnonymousContentNode(domNode) {
|
|||
* @param {Finder} finder Finder.jsm instance
|
||||
*/
|
||||
function FinderHighlighter(finder) {
|
||||
this.finder = finder;
|
||||
this._currentFoundRange = null;
|
||||
this._modal = Services.prefs.getBoolPref(kModalHighlightPref);
|
||||
this._highlightAll = Services.prefs.getBoolPref(kHighlightAllPref);
|
||||
this.finder = finder;
|
||||
this.visible = false;
|
||||
}
|
||||
|
||||
FinderHighlighter.prototype = {
|
||||
|
@ -259,50 +262,47 @@ FinderHighlighter.prototype = {
|
|||
* If modal highlighting is enabled, show the dimmed background that will overlay
|
||||
* the page.
|
||||
*
|
||||
* @param {nsIDOMWindow} window The dimmed background will overlay this window.
|
||||
* Optional, defaults to the finder window.
|
||||
* @return {AnonymousContent} Reference to the node inserted into the
|
||||
* CanvasFrame. It'll also be stored in the
|
||||
* `_modalHighlightOutline` member variable.
|
||||
* @param {nsIDOMWindow} window The dimmed background will overlay this window.
|
||||
* Optional, defaults to the finder window.
|
||||
*/
|
||||
show(window = null) {
|
||||
if (!this._modal)
|
||||
return null;
|
||||
if (!this._modal || this.visible)
|
||||
return;
|
||||
|
||||
this.visible = true;
|
||||
window = window || this.finder._getWindow();
|
||||
let anonNode = this._maybeCreateModalHighlightNodes(window);
|
||||
this._maybeCreateModalHighlightNodes(window);
|
||||
this._addModalHighlightListeners(window);
|
||||
|
||||
return anonNode;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all highlighted matches. If modal highlighting is enabled and
|
||||
* the outline + dimmed background is currently visible, both will be hidden.
|
||||
*
|
||||
* @param {nsIDOMWindow} window The dimmed background will overlay this window.
|
||||
* Optional, defaults to the finder window.
|
||||
* @param {nsIDOMRange} skipRange A range that should not be removed from the
|
||||
* find selection.
|
||||
*/
|
||||
hide(window = null) {
|
||||
hide(window = null, skipRange = null) {
|
||||
window = window || this.finder._getWindow();
|
||||
|
||||
let doc = window.document;
|
||||
let controller = this.finder._getSelectionController(window);
|
||||
let sel = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);
|
||||
sel.removeAllRanges();
|
||||
this._clearSelection(this.finder._getSelectionController(window), skipRange);
|
||||
|
||||
// Next, check our editor cache, for editors belonging to this
|
||||
// document
|
||||
if (this._editors) {
|
||||
for (let x = this._editors.length - 1; x >= 0; --x) {
|
||||
if (this._editors[x].document == doc) {
|
||||
sel = this._editors[x].selectionController
|
||||
.getSelection(Ci.nsISelectionController.SELECTION_FIND);
|
||||
sel.removeAllRanges();
|
||||
this._clearSelection(this._editors[x].selectionController, skipRange);
|
||||
// We don't need to listen to this editor any more
|
||||
this._unhookListenersAtIndex(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._modal)
|
||||
if (!this._modal || !this.visible)
|
||||
return;
|
||||
|
||||
if (this._modalHighlightOutline)
|
||||
|
@ -311,6 +311,8 @@ FinderHighlighter.prototype = {
|
|||
this._removeHighlightAllMask(window);
|
||||
this._removeModalHighlightListeners(window);
|
||||
delete this._brightText;
|
||||
|
||||
this.visible = false;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -335,52 +337,69 @@ FinderHighlighter.prototype = {
|
|||
* by the consumer of the Finder.
|
||||
*/
|
||||
update(data) {
|
||||
if (!this._modal)
|
||||
let window = this.finder._getWindow();
|
||||
let foundRange = this.finder._fastFind.getFoundRange();
|
||||
if (!this._modal) {
|
||||
if (this._highlightAll) {
|
||||
this.hide(window, foundRange);
|
||||
let params = this.iterator.params;
|
||||
if (params.word)
|
||||
this.highlight(true, params.word, params.linksOnly);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Place the match placeholder on top of the current found range.
|
||||
let foundRange = this.finder._fastFind.getFoundRange();
|
||||
if (data.result == Ci.nsITypeAheadFind.FIND_NOTFOUND || !foundRange) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
let window = this.finder._getWindow();
|
||||
let textContent = this._getRangeContentArray(foundRange);
|
||||
if (!textContent.length) {
|
||||
this.hide(window);
|
||||
return;
|
||||
let outlineNode;
|
||||
if (foundRange !== this._currentFoundRange || data.findAgain) {
|
||||
this._currentFoundRange = foundRange;
|
||||
|
||||
let textContent = this._getRangeContentArray(foundRange);
|
||||
if (!textContent.length) {
|
||||
this.hide(window);
|
||||
return;
|
||||
}
|
||||
|
||||
let rect = foundRange.getBoundingClientRect();
|
||||
let fontStyle = this._getRangeFontStyle(foundRange);
|
||||
if (typeof this._brightText == "undefined") {
|
||||
this._brightText = this._isColorBright(fontStyle.color);
|
||||
}
|
||||
|
||||
// Text color in the outline is determined by our stylesheet.
|
||||
delete fontStyle.color;
|
||||
|
||||
if (!this.visible)
|
||||
this.show(window);
|
||||
else
|
||||
this._maybeCreateModalHighlightNodes(window);
|
||||
|
||||
outlineNode = this._modalHighlightOutline;
|
||||
outlineNode.setTextContentForElement(kModalOutlineId + "-text", textContent.join(" "));
|
||||
outlineNode.setAttributeForElement(kModalOutlineId + "-text", "style",
|
||||
this._getHTMLFontStyle(fontStyle));
|
||||
|
||||
if (typeof outlineNode.getAttributeForElement(kModalOutlineId, "hidden") == "string")
|
||||
outlineNode.removeAttributeForElement(kModalOutlineId, "hidden");
|
||||
let { scrollX, scrollY } = this._getScrollPosition(window);
|
||||
outlineNode.setAttributeForElement(kModalOutlineId, "style",
|
||||
`top: ${scrollY + rect.top}px; left: ${scrollX + rect.left}px`);
|
||||
}
|
||||
|
||||
let rect = foundRange.getBoundingClientRect();
|
||||
let fontStyle = this._getRangeFontStyle(foundRange);
|
||||
if (typeof this._brightText == "undefined") {
|
||||
this._brightText = this._isColorBright(fontStyle.color);
|
||||
}
|
||||
|
||||
// Text color in the outline is determined by our stylesheet.
|
||||
delete fontStyle.color;
|
||||
|
||||
let anonNode = this.show(window);
|
||||
|
||||
anonNode.setTextContentForElement(kModalOutlineId + "-text", textContent.join(" "));
|
||||
anonNode.setAttributeForElement(kModalOutlineId + "-text", "style",
|
||||
this._getHTMLFontStyle(fontStyle));
|
||||
|
||||
if (typeof anonNode.getAttributeForElement(kModalOutlineId, "hidden") == "string")
|
||||
anonNode.removeAttributeForElement(kModalOutlineId, "hidden");
|
||||
let { scrollX, scrollY } = this._getScrollPosition(window);
|
||||
anonNode.setAttributeForElement(kModalOutlineId, "style",
|
||||
`top: ${scrollY + rect.top}px; left: ${scrollX + rect.left}px`);
|
||||
|
||||
if (typeof anonNode.getAttributeForElement(kModalOutlineId, "grow") == "string")
|
||||
outlineNode = this._modalHighlightOutline;
|
||||
if (typeof outlineNode.getAttributeForElement(kModalOutlineId, "grow") == "string")
|
||||
return;
|
||||
|
||||
window.requestAnimationFrame(() => {
|
||||
anonNode.setAttributeForElement(kModalOutlineId, "grow", true);
|
||||
outlineNode.setAttributeForElement(kModalOutlineId, "grow", true);
|
||||
this._listenForOutlineEvent(kModalOutlineId, "transitionend", () => {
|
||||
try {
|
||||
anonNode.removeAttributeForElement(kModalOutlineId, "grow");
|
||||
outlineNode.removeAttributeForElement(kModalOutlineId, "grow");
|
||||
} catch (ex) {}
|
||||
});
|
||||
});
|
||||
|
@ -441,12 +460,33 @@ FinderHighlighter.prototype = {
|
|||
* @param {Boolean} highlightAll
|
||||
*/
|
||||
onHighlightAllChange(highlightAll) {
|
||||
this._highlightAll = highlightAll;
|
||||
if (this._modal && !highlightAll) {
|
||||
this.clear();
|
||||
this._scheduleRepaintOfMask(this.finder._getWindow());
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Utility; removes all ranges from the find selection that belongs to a
|
||||
* controller. Optionally skips a specific range.
|
||||
*
|
||||
* @param {nsISelectionController} controller
|
||||
* @param {nsIDOMRange} skipRange
|
||||
*/
|
||||
_clearSelection(controller, skipRange = null) {
|
||||
let sel = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);
|
||||
if (!skipRange) {
|
||||
sel.removeAllRanges();
|
||||
} else {
|
||||
for (let i = sel.rangeCount - 1; i >= 0; --i) {
|
||||
let range = sel.getRangeAt(i);
|
||||
if (range !== skipRange)
|
||||
sel.removeRange(range);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Utility; get the nsIDOMWindowUtils for a window.
|
||||
*
|
||||
|
@ -605,14 +645,16 @@ FinderHighlighter.prototype = {
|
|||
* Lazily insert the nodes we need as anonymous content into the CanvasFrame
|
||||
* of a window.
|
||||
*
|
||||
* @param {nsIDOMWindow} window Window to draw in.
|
||||
* @return {AnonymousContent} The reference to the outline node, NOT the mask.
|
||||
* @param {nsIDOMWindow} window Window to draw in.
|
||||
*/
|
||||
_maybeCreateModalHighlightNodes(window) {
|
||||
if (this._modalHighlightOutline) {
|
||||
if (!this._modalHighlightAllMask)
|
||||
this._repaintHighlightAllMask(window);
|
||||
return this._modalHighlightOutline;
|
||||
if (!this._modalHighlightAllMask) {
|
||||
// Make sure to at least show the dimmed background.
|
||||
this._repaintHighlightAllMask(window, false);
|
||||
this._scheduleRepaintOfMask(window);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let document = window.document;
|
||||
|
@ -623,7 +665,7 @@ FinderHighlighter.prototype = {
|
|||
this._maybeCreateModalHighlightNodes(window);
|
||||
};
|
||||
document.addEventListener("visibilitychange", onVisibilityChange);
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
this._maybeInstallStyleSheet(window);
|
||||
|
@ -641,13 +683,12 @@ FinderHighlighter.prototype = {
|
|||
outlineBox.appendChild(outlineBoxText);
|
||||
|
||||
container.appendChild(outlineBox);
|
||||
|
||||
this._repaintHighlightAllMask(window);
|
||||
|
||||
this._modalHighlightOutline = kDebug ?
|
||||
mockAnonymousContentNode(document.body.appendChild(container.firstChild)) :
|
||||
document.insertAnonymousContent(container);
|
||||
return this._modalHighlightOutline;
|
||||
|
||||
// Make sure to at least show the dimmed background.
|
||||
this._repaintHighlightAllMask(window, false);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -656,8 +697,9 @@ FinderHighlighter.prototype = {
|
|||
* the ranges that were found.
|
||||
*
|
||||
* @param {nsIDOMWindow} window Window to draw in.
|
||||
* @param {Boolean} [paintContent]
|
||||
*/
|
||||
_repaintHighlightAllMask(window) {
|
||||
_repaintHighlightAllMask(window, paintContent = true) {
|
||||
let document = window.document;
|
||||
|
||||
const kMaskId = kModalIdPrefix + "-findbar-modalHighlight-outlineMask";
|
||||
|
@ -671,18 +713,20 @@ FinderHighlighter.prototype = {
|
|||
if (this._brightText)
|
||||
maskNode.setAttribute("brighttext", "true");
|
||||
|
||||
// Create a DOM node for each rectangle representing the ranges we found.
|
||||
let maskContent = [];
|
||||
const kRectClassName = kModalIdPrefix + "-findbar-modalHighlight-rect";
|
||||
if (this._modalHighlightRectsMap) {
|
||||
for (let rects of this._modalHighlightRectsMap.values()) {
|
||||
for (let rect of rects) {
|
||||
maskContent.push(`<div class="${kRectClassName}" style="top: ${rect.y}px;
|
||||
left: ${rect.x}px; height: ${rect.height}px; width: ${rect.width}px;"></div>`);
|
||||
if (paintContent) {
|
||||
// Create a DOM node for each rectangle representing the ranges we found.
|
||||
let maskContent = [];
|
||||
const kRectClassName = kModalIdPrefix + "-findbar-modalHighlight-rect";
|
||||
if (this._modalHighlightRectsMap) {
|
||||
for (let rects of this._modalHighlightRectsMap.values()) {
|
||||
for (let rect of rects) {
|
||||
maskContent.push(`<div class="${kRectClassName}" style="top: ${rect.y}px;
|
||||
left: ${rect.x}px; height: ${rect.height}px; width: ${rect.width}px;"></div>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
maskNode.innerHTML = maskContent.join("");
|
||||
}
|
||||
maskNode.innerHTML = maskContent.join("");
|
||||
|
||||
// Always remove the current mask and insert it a-fresh, because we're not
|
||||
// free to alter DOM nodes inside the CanvasFrame.
|
||||
|
|
|
@ -29,6 +29,10 @@ this.FinderIterator = {
|
|||
// Expose `kIterationSizeMax` to the outside world for unit tests to use.
|
||||
get kIterationSizeMax() { return kIterationSizeMax },
|
||||
|
||||
get params() {
|
||||
return Object.assign({}, this._currentParams || this._previousParams);
|
||||
},
|
||||
|
||||
/**
|
||||
* Start iterating the active Finder docShell, using the options below. When
|
||||
* it already started at the request of another consumer, we first yield the
|
||||
|
|
|
@ -209,7 +209,7 @@ var dataProviders = {
|
|||
|
||||
data.numTotalWindows = 0;
|
||||
data.numRemoteWindows = 0;
|
||||
let winEnumer = Services.ww.getWindowEnumerator("navigator:browser");
|
||||
let winEnumer = Services.wm.getEnumerator("navigator:browser");
|
||||
while (winEnumer.hasMoreElements()) {
|
||||
data.numTotalWindows++;
|
||||
let remote = winEnumer.getNext().
|
||||
|
|
|
@ -65,6 +65,7 @@ function* testInstall(browser, url, steps, description) {
|
|||
];
|
||||
let eventWaiter = null;
|
||||
let receivedEvents = [];
|
||||
let prevEvent = null;
|
||||
events.forEach(event => {
|
||||
install.addEventListener(event, e => {
|
||||
receivedEvents.push({
|
||||
|
@ -87,6 +88,21 @@ function* testInstall(browser, url, steps, description) {
|
|||
return new Promise((resolve, reject) => {
|
||||
function check() {
|
||||
let received = receivedEvents.shift();
|
||||
// Skip any repeated onDownloadProgress events.
|
||||
while (received &&
|
||||
received.event == prevEvent &&
|
||||
prevEvent == "onDownloadProgress") {
|
||||
received = receivedEvents.shift();
|
||||
}
|
||||
// Wait for more events if we skipped all there were.
|
||||
if (!received) {
|
||||
eventWaiter = () => {
|
||||
eventWaiter = null;
|
||||
check();
|
||||
}
|
||||
return;
|
||||
}
|
||||
prevEvent = received.event;
|
||||
if (received.event != event) {
|
||||
let err = new Error(`expected ${event} but got ${received.event}`);
|
||||
reject(err);
|
||||
|
@ -100,14 +116,7 @@ function* testInstall(browser, url, steps, description) {
|
|||
}
|
||||
resolve();
|
||||
}
|
||||
if (receivedEvents.length > 0) {
|
||||
check();
|
||||
} else {
|
||||
eventWaiter = () => {
|
||||
eventWaiter = null;
|
||||
check();
|
||||
}
|
||||
}
|
||||
check();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче