merge fx-team to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2016-08-02 17:04:48 +02:00
Родитель 923cbf5038 ebc9f1764d
Коммит f470e82ee2
11 изменённых файлов: 202 добавлений и 113 удалений

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

@ -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();
});
}