forked from mirrors/gecko-dev
Merge mozilla-central to mozilla-inbound r=merge a=merge on a CLOSED TREE
This commit is contained in:
commit
e1c8aba28f
89 changed files with 1248 additions and 980 deletions
|
|
@ -961,10 +961,6 @@
|
||||||
<prefs/>
|
<prefs/>
|
||||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||||
</emItem>
|
</emItem>
|
||||||
<emItem blockID="i446" id="{E90FA778-C2B7-41D0-9FA9-3FEC1CA54D66}">
|
|
||||||
<prefs/>
|
|
||||||
<versionRange minVersion="0" maxVersion="*" severity="1"/>
|
|
||||||
</emItem>
|
|
||||||
<emItem blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
|
<emItem blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
|
||||||
<prefs/>
|
<prefs/>
|
||||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||||
|
|
@ -1528,6 +1524,10 @@
|
||||||
<prefs/>
|
<prefs/>
|
||||||
<versionRange minVersion="0" maxVersion="*" severity="1"/>
|
<versionRange minVersion="0" maxVersion="*" severity="1"/>
|
||||||
</emItem>
|
</emItem>
|
||||||
|
<emItem blockID="f7569261-f575-4719-8202-552b20d013b0" id="{7e907a15-0a4c-4ff4-b64f-5eeb8f841349}">
|
||||||
|
<prefs/>
|
||||||
|
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||||
|
</emItem>
|
||||||
<emItem blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
|
<emItem blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
|
||||||
<prefs/>
|
<prefs/>
|
||||||
<versionRange minVersion="0" maxVersion="*" severity="1"/>
|
<versionRange minVersion="0" maxVersion="*" severity="1"/>
|
||||||
|
|
@ -2139,6 +2139,10 @@
|
||||||
</targetApplication>
|
</targetApplication>
|
||||||
</versionRange>
|
</versionRange>
|
||||||
</emItem>
|
</emItem>
|
||||||
|
<emItem blockID="i446" id="{E90FA778-C2B7-41D0-9FA9-3FEC1CA54D66}">
|
||||||
|
<prefs/>
|
||||||
|
<versionRange minVersion="0" maxVersion="*" severity="1"/>
|
||||||
|
</emItem>
|
||||||
</emItems>
|
</emItems>
|
||||||
<pluginItems>
|
<pluginItems>
|
||||||
<pluginItem blockID="p416">
|
<pluginItem blockID="p416">
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ skip-if = !e10s
|
||||||
[browser_urlbar_keyed_search_reflows.js]
|
[browser_urlbar_keyed_search_reflows.js]
|
||||||
skip-if = (os == 'linux') || (os == 'win' && debug) # Disabled on Linux and Windows debug due to perma failures. Bug 1392320.
|
skip-if = (os == 'linux') || (os == 'win' && debug) # Disabled on Linux and Windows debug due to perma failures. Bug 1392320.
|
||||||
[browser_urlbar_search_reflows.js]
|
[browser_urlbar_search_reflows.js]
|
||||||
skip-if = (os == 'linux') # Disabled on Linux and OS X opt due to frequent failures. Bug 1385932
|
|
||||||
[browser_windowclose_reflows.js]
|
[browser_windowclose_reflows.js]
|
||||||
[browser_windowopen_reflows.js]
|
[browser_windowopen_reflows.js]
|
||||||
skip-if = os == 'linux' # Disabled due to frequent failures. Bug 1380465.
|
skip-if = os == 'linux' # Disabled due to frequent failures. Bug 1380465.
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
|
||||||
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
|
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
|
||||||
"_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
|
"_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
|
||||||
],
|
],
|
||||||
|
minTimes: 39, // This number should only ever go down - never up.
|
||||||
times: 51, // This number should only ever go down - never up.
|
times: 51, // This number should only ever go down - never up.
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
|
||||||
"_invalidate@chrome://global/content/bindings/autocomplete.xml",
|
"_invalidate@chrome://global/content/bindings/autocomplete.xml",
|
||||||
"invalidate@chrome://global/content/bindings/autocomplete.xml"
|
"invalidate@chrome://global/content/bindings/autocomplete.xml"
|
||||||
],
|
],
|
||||||
times: 60, // This number should only ever go down - never up.
|
times: 36, // This number should only ever go down - never up.
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -102,6 +102,18 @@ const EXPECTED_REFLOWS_SECOND_OPEN = [
|
||||||
times: 3, // This number should only ever go down - never up.
|
times: 3, // This number should only ever go down - never up.
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
stack: [
|
||||||
|
"_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
|
||||||
|
"handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml",
|
||||||
|
"_reuseAcItem@chrome://global/content/bindings/autocomplete.xml",
|
||||||
|
"_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml",
|
||||||
|
"_invalidate@chrome://global/content/bindings/autocomplete.xml",
|
||||||
|
"invalidate@chrome://global/content/bindings/autocomplete.xml"
|
||||||
|
],
|
||||||
|
times: 24, // This number should only ever go down - never up.
|
||||||
|
},
|
||||||
|
|
||||||
// Bug 1359989
|
// Bug 1359989
|
||||||
{
|
{
|
||||||
stack: [
|
stack: [
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ add_task(async function history() {
|
||||||
gURLBar.focus();
|
gURLBar.focus();
|
||||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||||
await promisePopupShown(gURLBar.popup);
|
await promisePopupShown(gURLBar.popup);
|
||||||
|
await waitForAutocompleteResultAt(gMaxResults - 1)
|
||||||
|
|
||||||
assertState(-1, -1, "");
|
assertState(-1, -1, "");
|
||||||
|
|
||||||
|
|
@ -106,7 +107,7 @@ add_task(async function() {
|
||||||
// trigger autofill since that would complicate the test.
|
// trigger autofill since that would complicate the test.
|
||||||
let typedValue = "browser_urlbarOneOffs";
|
let typedValue = "browser_urlbarOneOffs";
|
||||||
await promiseAutocompleteResultPopup(typedValue, window, true);
|
await promiseAutocompleteResultPopup(typedValue, window, true);
|
||||||
|
await waitForAutocompleteResultAt(gMaxResults - 1);
|
||||||
assertState(0, -1, typedValue);
|
assertState(0, -1, typedValue);
|
||||||
|
|
||||||
// Key down through each result. The first result is already selected, which
|
// Key down through each result. The first result is already selected, which
|
||||||
|
|
@ -158,7 +159,7 @@ add_task(async function() {
|
||||||
add_task(async function searchWith() {
|
add_task(async function searchWith() {
|
||||||
let typedValue = "foo";
|
let typedValue = "foo";
|
||||||
await promiseAutocompleteResultPopup(typedValue);
|
await promiseAutocompleteResultPopup(typedValue);
|
||||||
|
await waitForAutocompleteResultAt(0);
|
||||||
assertState(0, -1, typedValue);
|
assertState(0, -1, typedValue);
|
||||||
|
|
||||||
let item = gURLBar.popup.richlistbox.firstChild;
|
let item = gURLBar.popup.richlistbox.firstChild;
|
||||||
|
|
@ -190,7 +191,7 @@ add_task(async function oneOffClick() {
|
||||||
// stricter. Even if it looks like a url, we should search.
|
// stricter. Even if it looks like a url, we should search.
|
||||||
let typedValue = "foo.bar";
|
let typedValue = "foo.bar";
|
||||||
await promiseAutocompleteResultPopup(typedValue);
|
await promiseAutocompleteResultPopup(typedValue);
|
||||||
|
await waitForAutocompleteResultAt(1);
|
||||||
assertState(0, -1, typedValue);
|
assertState(0, -1, typedValue);
|
||||||
|
|
||||||
let oneOffs = gURLBar.popup.oneOffSearchButtons.getSelectableButtons(true);
|
let oneOffs = gURLBar.popup.oneOffSearchButtons.getSelectableButtons(true);
|
||||||
|
|
@ -211,7 +212,7 @@ add_task(async function oneOffReturn() {
|
||||||
// stricter. Even if it looks like a url, we should search.
|
// stricter. Even if it looks like a url, we should search.
|
||||||
let typedValue = "foo.bar";
|
let typedValue = "foo.bar";
|
||||||
await promiseAutocompleteResultPopup(typedValue, window, true);
|
await promiseAutocompleteResultPopup(typedValue, window, true);
|
||||||
|
await waitForAutocompleteResultAt(1);
|
||||||
assertState(0, -1, typedValue);
|
assertState(0, -1, typedValue);
|
||||||
|
|
||||||
// Alt+Down to select the first one-off.
|
// Alt+Down to select the first one-off.
|
||||||
|
|
|
||||||
|
|
@ -320,5 +320,7 @@ async function waitForAutocompleteResultAt(index) {
|
||||||
() => gURLBar.popup.richlistbox.children.length > index &&
|
() => gURLBar.popup.richlistbox.children.length > index &&
|
||||||
gURLBar.popup.richlistbox.children[index].getAttribute("ac-text") == searchString,
|
gURLBar.popup.richlistbox.children[index].getAttribute("ac-text") == searchString,
|
||||||
`Waiting for the autocomplete result for "${searchString}" at [${index}] to appear`);
|
`Waiting for the autocomplete result for "${searchString}" at [${index}] to appear`);
|
||||||
|
// Ensure the addition is complete, for proper mouse events on the entries.
|
||||||
|
await new Promise(resolve => window.requestIdleCallback(resolve, {timeout: 1000}));
|
||||||
return gURLBar.popup.richlistbox.children[index];
|
return gURLBar.popup.richlistbox.children[index];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ const getSender = (extension, target, sender) => {
|
||||||
// page-open listener below).
|
// page-open listener below).
|
||||||
tabId = sender.tabId;
|
tabId = sender.tabId;
|
||||||
delete sender.tabId;
|
delete sender.tabId;
|
||||||
} else if (target instanceof Ci.nsIDOMXULElement) {
|
} else if (target instanceof Ci.nsIDOMXULElement ||
|
||||||
|
ExtensionUtils.instanceOf(target, "HTMLIFrameElement")) {
|
||||||
tabId = tabTracker.getBrowserData(target).tabId;
|
tabId = tabTracker.getBrowserData(target).tabId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,21 +84,35 @@ add_task(async function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startInputSession() {
|
async function waitForAutocompleteResultAt(index) {
|
||||||
|
let searchString = gURLBar.controller.searchString;
|
||||||
|
await BrowserTestUtils.waitForCondition(
|
||||||
|
() => gURLBar.popup.richlistbox.children.length > index &&
|
||||||
|
gURLBar.popup.richlistbox.children[index].getAttribute("ac-text") == searchString,
|
||||||
|
`Waiting for the autocomplete result for "${searchString}" at [${index}] to appear`);
|
||||||
|
// Ensure the addition is complete, for proper mouse events on the entries.
|
||||||
|
await new Promise(resolve => window.requestIdleCallback(resolve, {timeout: 1000}));
|
||||||
|
return gURLBar.popup.richlistbox.children[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
let inputSessionSerial = 0;
|
||||||
|
async function startInputSession(indexToWaitFor) {
|
||||||
gURLBar.focus();
|
gURLBar.focus();
|
||||||
gURLBar.value = keyword;
|
gURLBar.value = keyword;
|
||||||
EventUtils.synthesizeKey(" ", {});
|
EventUtils.synthesizeKey(" ", {});
|
||||||
await expectEvent("on-input-started-fired");
|
await expectEvent("on-input-started-fired");
|
||||||
EventUtils.synthesizeKey("t", {});
|
// Always use a different input at every invokation, so that
|
||||||
await expectEvent("on-input-changed-fired", {text: "t"});
|
// waitForAutocompleteResultAt can distinguish different cases.
|
||||||
|
let char = ((inputSessionSerial++) % 10).toString();
|
||||||
|
EventUtils.synthesizeKey(char, {});
|
||||||
|
|
||||||
|
await expectEvent("on-input-changed-fired", {text: char});
|
||||||
// Wait for the autocomplete search. Note that we cannot wait for the search
|
// Wait for the autocomplete search. Note that we cannot wait for the search
|
||||||
// to be complete, since the add-on doesn't communicate when it's done, so
|
// to be complete, since the add-on doesn't communicate when it's done, so
|
||||||
// just check matches count.
|
// just check matches count.
|
||||||
await BrowserTestUtils.waitForCondition(
|
await waitForAutocompleteResultAt(indexToWaitFor);
|
||||||
() => gURLBar.controller.matchCount >= 2 &&
|
|
||||||
gURLBar.popup.richlistbox.children[1].getAttribute("ac-text") == gURLBar.controller.searchString,
|
return char;
|
||||||
"waiting urlbar search to complete");
|
|
||||||
return "t";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testInputEvents() {
|
async function testInputEvents() {
|
||||||
|
|
@ -174,7 +188,7 @@ add_task(async function() {
|
||||||
await extension.awaitMessage("default-suggestion-set");
|
await extension.awaitMessage("default-suggestion-set");
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = await startInputSession();
|
let text = await startInputSession(0);
|
||||||
|
|
||||||
let item = gURLBar.popup.richlistbox.children[0];
|
let item = gURLBar.popup.richlistbox.children[0];
|
||||||
|
|
||||||
|
|
@ -193,7 +207,7 @@ add_task(async function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testDisposition(suggestionIndex, expectedDisposition, expectedText) {
|
async function testDisposition(suggestionIndex, expectedDisposition, expectedText) {
|
||||||
await startInputSession();
|
await startInputSession(suggestionIndex);
|
||||||
|
|
||||||
// Select the suggestion.
|
// Select the suggestion.
|
||||||
for (let i = 0; i < suggestionIndex; i++) {
|
for (let i = 0; i < suggestionIndex; i++) {
|
||||||
|
|
@ -229,7 +243,7 @@ add_task(async function() {
|
||||||
`Expected suggestion to have displayurl: "${keyword} ${content}".`);
|
`Expected suggestion to have displayurl: "${keyword} ${content}".`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = await startInputSession();
|
let text = await startInputSession(info.suggestions.length - 1);
|
||||||
|
|
||||||
extension.sendMessage(info.test);
|
extension.sendMessage(info.test);
|
||||||
await extension.awaitMessage("test-ready");
|
await extension.awaitMessage("test-ready");
|
||||||
|
|
@ -274,12 +288,10 @@ add_task(async function() {
|
||||||
// Test adding suggestions asynchronously.
|
// Test adding suggestions asynchronously.
|
||||||
await testSuggestions({
|
await testSuggestions({
|
||||||
test: "test-multiple-suggest-calls",
|
test: "test-multiple-suggest-calls",
|
||||||
skipHeuristic: true,
|
|
||||||
suggestions,
|
suggestions,
|
||||||
});
|
});
|
||||||
await testSuggestions({
|
await testSuggestions({
|
||||||
test: "test-suggestions-after-delay",
|
test: "test-suggestions-after-delay",
|
||||||
skipHeuristic: true,
|
|
||||||
suggestions,
|
suggestions,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@
|
||||||
add_task(async function testLastAccessed() {
|
add_task(async function testLastAccessed() {
|
||||||
let past = Date.now();
|
let past = Date.now();
|
||||||
|
|
||||||
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/?1");
|
for (let url of ["https://example.com/?1", "https://example.com/?2"]) {
|
||||||
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/?2");
|
let tab = BrowserTestUtils.addTab(gBrowser, url, {skipAnimation: true});
|
||||||
|
await BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, url);
|
||||||
|
}
|
||||||
|
|
||||||
let extension = ExtensionTestUtils.loadExtension({
|
let extension = ExtensionTestUtils.loadExtension({
|
||||||
manifest: {
|
manifest: {
|
||||||
|
|
@ -12,10 +14,6 @@ add_task(async function testLastAccessed() {
|
||||||
},
|
},
|
||||||
async background() {
|
async background() {
|
||||||
browser.test.onMessage.addListener(async function(msg, past) {
|
browser.test.onMessage.addListener(async function(msg, past) {
|
||||||
if (msg !== "past") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let [tab1] = await browser.tabs.query({url: "https://example.com/?1"});
|
let [tab1] = await browser.tabs.query({url: "https://example.com/?1"});
|
||||||
let [tab2] = await browser.tabs.query({url: "https://example.com/?2"});
|
let [tab2] = await browser.tabs.query({url: "https://example.com/?2"});
|
||||||
|
|
||||||
|
|
@ -23,10 +21,12 @@ add_task(async function testLastAccessed() {
|
||||||
|
|
||||||
let now = Date.now();
|
let now = Date.now();
|
||||||
|
|
||||||
browser.test.assertTrue(past < tab1.lastAccessed &&
|
browser.test.assertTrue(past < tab1.lastAccessed,
|
||||||
tab1.lastAccessed < tab2.lastAccessed &&
|
"lastAccessed of tab 1 is later than the test start time.");
|
||||||
tab2.lastAccessed <= now,
|
browser.test.assertTrue(tab1.lastAccessed < tab2.lastAccessed,
|
||||||
"lastAccessed timestamps are recent and in the right order");
|
"lastAccessed of tab 2 is later than lastAccessed of tab 1.");
|
||||||
|
browser.test.assertTrue(tab2.lastAccessed <= now,
|
||||||
|
"lastAccessed of tab 2 is earlier than now.");
|
||||||
|
|
||||||
await browser.tabs.remove([tab1.id, tab2.id]);
|
await browser.tabs.remove([tab1.id, tab2.id]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,13 @@ charts.totalSize=Size: %S KB
|
||||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||||
# This is the label displayed in the performance analysis view for the
|
# This is the label displayed in the performance analysis view for the
|
||||||
# total requests time, in seconds.
|
# total requests time, in seconds.
|
||||||
charts.totalSeconds=Time: #1 second;Time: #1 seconds
|
charts.totalSeconds=Time: %1$S second;Time: %1$S seconds
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (charts.totalSecondsNonBlocking): Semi-colon list of plural forms.
|
||||||
|
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||||
|
# This is the label displayed in the performance analysis view for the
|
||||||
|
# total requests time (non-blocking), in seconds.
|
||||||
|
charts.totalSecondsNonBlocking=Non blocking time: %1$S second;Non blocking time: %1$S seconds
|
||||||
|
|
||||||
# LOCALIZATION NOTE (charts.totalCached): This is the label displayed
|
# LOCALIZATION NOTE (charts.totalCached): This is the label displayed
|
||||||
# in the performance analysis view for total cached responses.
|
# in the performance analysis view for total cached responses.
|
||||||
|
|
@ -348,6 +354,11 @@ charts.transferred=Transferred
|
||||||
# in the header column in the performance analysis view for time of request.
|
# in the header column in the performance analysis view for time of request.
|
||||||
charts.time=Time
|
charts.time=Time
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (charts.nonBlockingTime): This is the label displayed
|
||||||
|
# in the header column in the performance analysis view for non blocking
|
||||||
|
# time of request.
|
||||||
|
charts.nonBlockingTime=Non blocking time
|
||||||
|
|
||||||
# LOCALIZATION NOTE (netRequest.headers): A label used for Headers tab
|
# LOCALIZATION NOTE (netRequest.headers): A label used for Headers tab
|
||||||
# This tab displays list of HTTP headers
|
# This tab displays list of HTTP headers
|
||||||
netRequest.headers=Headers
|
netRequest.headers=Headers
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ class StatisticsPanel extends Component {
|
||||||
size: L10N.getStr("charts.size"),
|
size: L10N.getStr("charts.size"),
|
||||||
transferredSize: L10N.getStr("charts.transferred"),
|
transferredSize: L10N.getStr("charts.transferred"),
|
||||||
time: L10N.getStr("charts.time"),
|
time: L10N.getStr("charts.time"),
|
||||||
|
nonBlockingTime: L10N.getStr("charts.nonBlockingTime"),
|
||||||
},
|
},
|
||||||
data,
|
data,
|
||||||
strings: {
|
strings: {
|
||||||
|
|
@ -142,6 +143,8 @@ class StatisticsPanel extends Component {
|
||||||
getSizeWithDecimals(value / 1024)),
|
getSizeWithDecimals(value / 1024)),
|
||||||
time: (value) =>
|
time: (value) =>
|
||||||
L10N.getFormatStr("charts.totalS", getTimeWithDecimals(value / 1000)),
|
L10N.getFormatStr("charts.totalS", getTimeWithDecimals(value / 1000)),
|
||||||
|
nonBlockingTime: (value) =>
|
||||||
|
L10N.getFormatStr("charts.totalS", getTimeWithDecimals(value / 1000)),
|
||||||
},
|
},
|
||||||
totals: {
|
totals: {
|
||||||
cached: (total) => L10N.getFormatStr("charts.totalCached", total),
|
cached: (total) => L10N.getFormatStr("charts.totalCached", total),
|
||||||
|
|
@ -155,7 +158,13 @@ class StatisticsPanel extends Component {
|
||||||
let seconds = total / 1000;
|
let seconds = total / 1000;
|
||||||
let string = getTimeWithDecimals(seconds);
|
let string = getTimeWithDecimals(seconds);
|
||||||
return PluralForm.get(seconds,
|
return PluralForm.get(seconds,
|
||||||
L10N.getStr("charts.totalSeconds")).replace("#1", string);
|
L10N.getFormatStr("charts.totalSeconds", string));
|
||||||
|
},
|
||||||
|
nonBlockingTime: (total) => {
|
||||||
|
let seconds = total / 1000;
|
||||||
|
let string = getTimeWithDecimals(seconds);
|
||||||
|
return PluralForm.get(seconds,
|
||||||
|
L10N.getFormatStr("charts.totalSecondsNonBlocking", string));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
sorted: true,
|
sorted: true,
|
||||||
|
|
@ -185,6 +194,7 @@ class StatisticsPanel extends Component {
|
||||||
size: 0,
|
size: 0,
|
||||||
transferredSize: 0,
|
transferredSize: 0,
|
||||||
time: 0,
|
time: 0,
|
||||||
|
nonBlockingTime: 0,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for (let request of requests) {
|
for (let request of requests) {
|
||||||
|
|
@ -224,6 +234,9 @@ class StatisticsPanel extends Component {
|
||||||
data[type].time += request.totalTime || 0;
|
data[type].time += request.totalTime || 0;
|
||||||
data[type].size += request.contentSize || 0;
|
data[type].size += request.contentSize || 0;
|
||||||
data[type].transferredSize += request.transferredSize || 0;
|
data[type].transferredSize += request.transferredSize || 0;
|
||||||
|
let nonBlockingTime =
|
||||||
|
request.eventTimings.totalTime - request.eventTimings.timings.blocked;
|
||||||
|
data[type].nonBlockingTime += nonBlockingTime || 0;
|
||||||
} else {
|
} else {
|
||||||
data[type].cached++;
|
data[type].cached++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,6 @@ function debug(msg) {
|
||||||
* this is used in RDM. The steps described there are copied into the code
|
* this is used in RDM. The steps described there are copied into the code
|
||||||
* below.
|
* below.
|
||||||
*
|
*
|
||||||
* For additional low level details about swapping browser content,
|
|
||||||
* see /devtools/client/responsive.html/docs/browser-swap.md.
|
|
||||||
*
|
|
||||||
* @param tab
|
* @param tab
|
||||||
* A browser tab with content to be swapped.
|
* A browser tab with content to be swapped.
|
||||||
* @param containerURL
|
* @param containerURL
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { Ci } = require("chrome");
|
const { Ci, Cu } = require("chrome");
|
||||||
const Services = require("Services");
|
const Services = require("Services");
|
||||||
const { Task } = require("devtools/shared/task");
|
const { Task } = require("devtools/shared/task");
|
||||||
const { BrowserElementWebNavigation } = require("./web-navigation");
|
const { BrowserElementWebNavigation } = require("./web-navigation");
|
||||||
|
|
@ -20,8 +20,7 @@ function debug(msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties swapped between browsers by browser.xml's `swapDocShells`. See also the
|
* Properties swapped between browsers by browser.xml's `swapDocShells`.
|
||||||
* list at /devtools/client/responsive.html/docs/browser-swap.md.
|
|
||||||
*/
|
*/
|
||||||
const SWAPPED_BROWSER_STATE = [
|
const SWAPPED_BROWSER_STATE = [
|
||||||
"_remoteFinder",
|
"_remoteFinder",
|
||||||
|
|
@ -328,8 +327,8 @@ function MessageManagerTunnel(outer, inner) {
|
||||||
if (outer.isRemoteBrowser) {
|
if (outer.isRemoteBrowser) {
|
||||||
throw new Error("The outer browser must be non-remote.");
|
throw new Error("The outer browser must be non-remote.");
|
||||||
}
|
}
|
||||||
this.outer = outer;
|
this.outerRef = Cu.getWeakReference(outer);
|
||||||
this.inner = inner;
|
this.innerRef = Cu.getWeakReference(inner);
|
||||||
this.tunneledMessageNames = new Set();
|
this.tunneledMessageNames = new Set();
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
@ -415,6 +414,8 @@ MessageManagerTunnel.prototype = {
|
||||||
"Finder:",
|
"Finder:",
|
||||||
// Messages sent from InlineSpellChecker.jsm
|
// Messages sent from InlineSpellChecker.jsm
|
||||||
"InlineSpellChecker:",
|
"InlineSpellChecker:",
|
||||||
|
// Messages sent from MessageChannel.jsm
|
||||||
|
"MessageChannel:",
|
||||||
// Messages sent from pageinfo.js
|
// Messages sent from pageinfo.js
|
||||||
"PageInfo:",
|
"PageInfo:",
|
||||||
// Messages sent from printUtils.js
|
// Messages sent from printUtils.js
|
||||||
|
|
@ -433,6 +434,8 @@ MessageManagerTunnel.prototype = {
|
||||||
"Findbar:",
|
"Findbar:",
|
||||||
// Messages sent to RemoteFinder.jsm
|
// Messages sent to RemoteFinder.jsm
|
||||||
"Finder:",
|
"Finder:",
|
||||||
|
// Messages sent to MessageChannel.jsm
|
||||||
|
"MessageChannel:",
|
||||||
// Messages sent to pageinfo.js
|
// Messages sent to pageinfo.js
|
||||||
"PageInfo:",
|
"PageInfo:",
|
||||||
// Messages sent to printUtils.js
|
// Messages sent to printUtils.js
|
||||||
|
|
@ -447,6 +450,10 @@ MessageManagerTunnel.prototype = {
|
||||||
"resource://devtools/server/child.js"
|
"resource://devtools/server/child.js"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
get outer() {
|
||||||
|
return this.outerRef.get();
|
||||||
|
},
|
||||||
|
|
||||||
get outerParentMM() {
|
get outerParentMM() {
|
||||||
if (!this.outer[FRAME_LOADER]) {
|
if (!this.outer[FRAME_LOADER]) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -463,6 +470,10 @@ MessageManagerTunnel.prototype = {
|
||||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get inner() {
|
||||||
|
return this.innerRef.get();
|
||||||
|
},
|
||||||
|
|
||||||
get innerParentMM() {
|
get innerParentMM() {
|
||||||
if (!this.inner.frameLoader) {
|
if (!this.inner.frameLoader) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -620,4 +631,8 @@ MessageManagerTunnel.prototype = {
|
||||||
this.INNER_TO_OUTER_MESSAGE_PREFIXES.some(prefix => name.startsWith(prefix));
|
this.INNER_TO_OUTER_MESSAGE_PREFIXES.some(prefix => name.startsWith(prefix));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return "[object MessageManagerTunnel]";
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,144 +0,0 @@
|
||||||
# Overview
|
|
||||||
|
|
||||||
The RDM tool uses several forms of tab and browser swapping to integrate the
|
|
||||||
tool UI cleanly into the browser UI. The high level steps of this process are
|
|
||||||
documented at `/devtools/docs/responsive-design-mode.md`.
|
|
||||||
|
|
||||||
This document contains a random assortment of low level notes about the steps
|
|
||||||
the browser goes through when swapping browsers between tabs.
|
|
||||||
|
|
||||||
# Connections between Browsers and Tabs
|
|
||||||
|
|
||||||
Link between tab and browser (`gBrowser._linkBrowserToTab`):
|
|
||||||
|
|
||||||
```
|
|
||||||
aTab.linkedBrowser = browser;
|
|
||||||
gBrowser._tabForBrowser.set(browser, aTab);
|
|
||||||
```
|
|
||||||
|
|
||||||
# Swapping Browsers between Tabs
|
|
||||||
|
|
||||||
## Legend
|
|
||||||
|
|
||||||
* (R): remote browsers only
|
|
||||||
* (!R): non-remote browsers only
|
|
||||||
|
|
||||||
## Functions Called
|
|
||||||
|
|
||||||
When you call `gBrowser.swapBrowsersAndCloseOther` to move tab content from a
|
|
||||||
browser in one tab to a browser in another tab, here are all the code paths
|
|
||||||
involved:
|
|
||||||
|
|
||||||
* `gBrowser.swapBrowsersAndCloseOther`
|
|
||||||
* `gBrowser._beginRemoveTab`
|
|
||||||
* `gBrowser.tabContainer.updateVisibility`
|
|
||||||
* Emit `TabClose`
|
|
||||||
* `browser.webProgress.removeProgressListener`
|
|
||||||
* `filter.removeProgressListener`
|
|
||||||
* `listener.destroy`
|
|
||||||
* `gBrowser._swapBrowserDocShells`
|
|
||||||
* `ourBrowser.webProgress.removeProgressListener`
|
|
||||||
* `filter.removeProgressListener`
|
|
||||||
* `gBrowser._swapRegisteredOpenURIs`
|
|
||||||
* `ourBrowser.swapDocShells(aOtherBrowser)`
|
|
||||||
* Emit `SwapDocShells`
|
|
||||||
* `PopupNotifications._swapBrowserNotifications`
|
|
||||||
* `browser.detachFormFill` (!R)
|
|
||||||
* `browser.swapFrameLoaders`
|
|
||||||
* `browser.attachFormFill` (!R)
|
|
||||||
* `browser._remoteWebNavigationImpl.swapBrowser(browser)` (R)
|
|
||||||
* `browser._remoteWebProgressManager.swapBrowser(browser)` (R)
|
|
||||||
* `browser._remoteFinder.swapBrowser(browser)` (R)
|
|
||||||
* Emit `EndSwapDocShells`
|
|
||||||
* `gBrowser.mTabProgressListener`
|
|
||||||
* `filter.addProgressListener`
|
|
||||||
* `ourBrowser.webProgress.addProgressListener`
|
|
||||||
* `gBrowser._endRemoveTab`
|
|
||||||
* `gBrowser._blurTab`
|
|
||||||
* `gBrowser._tabFilters.delete`
|
|
||||||
* `gBrowser._tabListeners.delete`
|
|
||||||
* `gBrowser._outerWindowIDBrowserMap.delete`
|
|
||||||
* `browser.destroy`
|
|
||||||
* `gBrowser.tabContainer.removeChild`
|
|
||||||
* `gBrowser.tabContainer.adjustTabstrip`
|
|
||||||
* `gBrowser.tabContainer._setPositionalAttributes`
|
|
||||||
* `browser.parentNode.removeChild(browser)`
|
|
||||||
* `gBrowser._tabForBrowser.delete`
|
|
||||||
* `gBrowser.mPanelContainer.removeChild`
|
|
||||||
* `gBrowser.setTabTitle` / `gBrowser.setTabTitleLoading`
|
|
||||||
* `browser.currentURI.spec`
|
|
||||||
* `gBrowser._tabAttrModified`
|
|
||||||
* `gBrowser.updateTitlebar`
|
|
||||||
* `gBrowser.updateCurrentBrowser`
|
|
||||||
* `browser.docShellIsActive` (!R)
|
|
||||||
* `gBrowser.showTab`
|
|
||||||
* `gBrowser._appendStatusPanel`
|
|
||||||
* `gBrowser._callProgressListeners` with `onLocationChange`
|
|
||||||
* `gBrowser._callProgressListeners` with `onSecurityChange`
|
|
||||||
* `gBrowser._callProgressListeners` with `onUpdateCurrentBrowser`
|
|
||||||
* `gBrowser.updateTitlebar`
|
|
||||||
* `gBrowser._callProgressListeners` with `onStateChange`
|
|
||||||
* `gBrowser._setCloseKeyState`
|
|
||||||
* Emit `TabSelect`
|
|
||||||
* `gBrowser._tabAttrModified`
|
|
||||||
* `browser.getInPermitUnload`
|
|
||||||
* `gBrowser.tabContainer._setPositionalAttributes`
|
|
||||||
* `gBrowser._tabAttrModified`
|
|
||||||
|
|
||||||
## Browser State
|
|
||||||
|
|
||||||
When calling `gBrowser.swapBrowsersAndCloseOther`, the browser is not actually
|
|
||||||
moved from one tab to the other. Instead, various properties _on_ each of the
|
|
||||||
browsers are swapped.
|
|
||||||
|
|
||||||
Browser attributes `gBrowser.swapBrowsersAndCloseOther` transfers between
|
|
||||||
browsers:
|
|
||||||
|
|
||||||
* `usercontextid`
|
|
||||||
|
|
||||||
Tab attributes `gBrowser.swapBrowsersAndCloseOther` transfers between tabs:
|
|
||||||
|
|
||||||
* `usercontextid`
|
|
||||||
* `muted`
|
|
||||||
* `soundplaying`
|
|
||||||
* `busy`
|
|
||||||
|
|
||||||
Browser properties `gBrowser.swapBrowsersAndCloseOther` transfers between
|
|
||||||
browsers:
|
|
||||||
|
|
||||||
* `mIconURL`
|
|
||||||
* `getFindBar(aOurTab)._findField.value`
|
|
||||||
|
|
||||||
Browser properties `gBrowser._swapBrowserDocShells` transfers between browsers:
|
|
||||||
|
|
||||||
* `outerWindowID` in `gBrowser._outerWindowIDBrowserMap`
|
|
||||||
* `_outerWindowID` on the browser (R)
|
|
||||||
* `docShellIsActive`
|
|
||||||
* `permanentKey`
|
|
||||||
* `registeredOpenURI`
|
|
||||||
|
|
||||||
Browser properties `browser.swapDocShells` transfers between browsers:
|
|
||||||
|
|
||||||
* `_docShell`
|
|
||||||
* `_webBrowserFind`
|
|
||||||
* `_contentWindow`
|
|
||||||
* `_webNavigation`
|
|
||||||
* `_remoteWebNavigation` (R)
|
|
||||||
* `_remoteWebNavigationImpl` (R)
|
|
||||||
* `_remoteWebProgressManager` (R)
|
|
||||||
* `_remoteWebProgress` (R)
|
|
||||||
* `_remoteFinder` (R)
|
|
||||||
* `_securityUI` (R)
|
|
||||||
* `_documentURI` (R)
|
|
||||||
* `_documentContentType` (R)
|
|
||||||
* `_contentTitle` (R)
|
|
||||||
* `_characterSet` (R)
|
|
||||||
* `_contentPrincipal` (R)
|
|
||||||
* `_imageDocument` (R)
|
|
||||||
* `_fullZoom` (R)
|
|
||||||
* `_textZoom` (R)
|
|
||||||
* `_isSyntheticDocument` (R)
|
|
||||||
* `_innerWindowID` (R)
|
|
||||||
* `_manifestURI` (R)
|
|
||||||
|
|
||||||
`browser.swapFrameLoaders` swaps the actual page content.
|
|
||||||
|
|
@ -27,6 +27,8 @@ support-files =
|
||||||
[browser_device_width.js]
|
[browser_device_width.js]
|
||||||
[browser_dpr_change.js]
|
[browser_dpr_change.js]
|
||||||
[browser_exit_button.js]
|
[browser_exit_button.js]
|
||||||
|
[browser_ext_messaging.js]
|
||||||
|
tags = devtools webextensions
|
||||||
[browser_frame_script_active.js]
|
[browser_frame_script_active.js]
|
||||||
[browser_hide_container.js]
|
[browser_hide_container.js]
|
||||||
[browser_menu_item_01.js]
|
[browser_menu_item_01.js]
|
||||||
|
|
@ -37,7 +39,7 @@ skip-if = true # Bug 1413765
|
||||||
[browser_network_throttling.js]
|
[browser_network_throttling.js]
|
||||||
[browser_page_state.js]
|
[browser_page_state.js]
|
||||||
[browser_permission_doorhanger.js]
|
[browser_permission_doorhanger.js]
|
||||||
tags = geolocation
|
tags = devtools geolocation
|
||||||
skip-if = true # Bug 1413765
|
skip-if = true # Bug 1413765
|
||||||
[browser_resize_cmd.js]
|
[browser_resize_cmd.js]
|
||||||
[browser_screenshot_button.js]
|
[browser_screenshot_button.js]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
/* eslint-env webextensions */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const TEST_URL = "http://example.com/";
|
||||||
|
|
||||||
|
// These allowed rejections are copied from
|
||||||
|
// browser/components/extensions/test/browser/head.js.
|
||||||
|
PromiseTestUtils.whitelistRejectionsGlobally(/Message manager disconnected/);
|
||||||
|
PromiseTestUtils.whitelistRejectionsGlobally(/Receiving end does not exist/);
|
||||||
|
|
||||||
|
add_task(async function () {
|
||||||
|
let tab = await addTab(TEST_URL);
|
||||||
|
await openRDM(tab);
|
||||||
|
|
||||||
|
let extension = ExtensionTestUtils.loadExtension({
|
||||||
|
manifest: {
|
||||||
|
"permissions": ["tabs"],
|
||||||
|
|
||||||
|
"content_scripts": [{
|
||||||
|
"matches": [TEST_URL],
|
||||||
|
"js": ["content-script.js"],
|
||||||
|
"run_at": "document_start",
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
|
||||||
|
async background() {
|
||||||
|
const TEST_URL = "http://example.com/"; // eslint-disable-line no-shadow
|
||||||
|
|
||||||
|
browser.test.log("Background script init");
|
||||||
|
|
||||||
|
let extTab;
|
||||||
|
let contentMessage = new Promise(resolve => {
|
||||||
|
browser.test.log("Listen to content");
|
||||||
|
let listener = async (msg, sender, respond) => {
|
||||||
|
browser.test.assertEq(msg, "hello-from-content",
|
||||||
|
"Background script got hello-from-content message");
|
||||||
|
|
||||||
|
let tabs = await browser.tabs.query({
|
||||||
|
currentWindow: true,
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
browser.test.assertEq(tabs.length, 1,
|
||||||
|
"One tab is active in the current window");
|
||||||
|
extTab = tabs[0];
|
||||||
|
browser.test.log(`Tab: id ${extTab.id}, url ${extTab.url}`);
|
||||||
|
browser.test.assertEq(extTab.url, TEST_URL, "Tab has the test URL");
|
||||||
|
|
||||||
|
browser.test.assertTrue(!!sender, "Message has a sender");
|
||||||
|
browser.test.assertTrue(!!sender.tab, "Message has a sender.tab");
|
||||||
|
browser.test.assertEq(sender.tab.id, extTab.id,
|
||||||
|
"Sender's tab ID matches the RDM tab ID");
|
||||||
|
browser.test.assertEq(sender.tab.url, extTab.url,
|
||||||
|
"Sender's tab URL matches the RDM tab URL");
|
||||||
|
|
||||||
|
browser.runtime.onMessage.removeListener(listener);
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
browser.runtime.onMessage.addListener(listener);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for "resume" message so we know the content script is also ready.
|
||||||
|
await new Promise(resolve => {
|
||||||
|
browser.test.onMessage.addListener(resolve);
|
||||||
|
browser.test.sendMessage("background-script-ready");
|
||||||
|
});
|
||||||
|
|
||||||
|
await contentMessage;
|
||||||
|
|
||||||
|
browser.test.log("Send message from background to content");
|
||||||
|
let contentSender = await browser.tabs.sendMessage(
|
||||||
|
extTab.id,
|
||||||
|
"hello-from-background"
|
||||||
|
);
|
||||||
|
browser.test.assertEq(contentSender.id, browser.runtime.id,
|
||||||
|
"The sender ID in content matches this extension");
|
||||||
|
|
||||||
|
browser.test.notifyPass("rdm-messaging");
|
||||||
|
},
|
||||||
|
|
||||||
|
files: {
|
||||||
|
"content-script.js": async function () {
|
||||||
|
browser.test.log("Content script init");
|
||||||
|
|
||||||
|
browser.test.log("Listen to background");
|
||||||
|
browser.runtime.onMessage.addListener((msg, sender, respond) => {
|
||||||
|
browser.test.assertEq(msg, "hello-from-background",
|
||||||
|
"Content script got hello-from-background message");
|
||||||
|
|
||||||
|
browser.test.assertTrue(!!sender, "Message has a sender");
|
||||||
|
browser.test.assertTrue(!!sender.id, "Message has a sender.id");
|
||||||
|
|
||||||
|
let { id } = sender;
|
||||||
|
respond({ id });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for "resume" message so we know the background script is also ready.
|
||||||
|
await new Promise(resolve => {
|
||||||
|
browser.test.onMessage.addListener(resolve);
|
||||||
|
browser.test.sendMessage("content-script-ready");
|
||||||
|
});
|
||||||
|
|
||||||
|
browser.test.log("Send message from content to background");
|
||||||
|
browser.runtime.sendMessage("hello-from-content");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let contentScriptReady = extension.awaitMessage("content-script-ready");
|
||||||
|
let backgroundScriptReady = extension.awaitMessage("background-script-ready");
|
||||||
|
let finish = extension.awaitFinish("rdm-messaging");
|
||||||
|
|
||||||
|
await extension.startup();
|
||||||
|
|
||||||
|
// It appears the background script and content script can loaded in either order, so
|
||||||
|
// we'll wait for the both to listen before proceeding.
|
||||||
|
await backgroundScriptReady;
|
||||||
|
await contentScriptReady;
|
||||||
|
extension.sendMessage("resume");
|
||||||
|
|
||||||
|
await finish;
|
||||||
|
await extension.unload();
|
||||||
|
|
||||||
|
await closeRDM(tab);
|
||||||
|
await removeTab(tab);
|
||||||
|
});
|
||||||
|
|
@ -13559,6 +13559,12 @@ nsDocShell::ConfirmRepost(bool* aRepost)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make the repost prompt tab modal to prevent malicious pages from locking
|
||||||
|
// up the browser, see bug 1412559 for an example.
|
||||||
|
if (nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompter)) {
|
||||||
|
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), true);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t buttonPressed;
|
int32_t buttonPressed;
|
||||||
// The actual value here is irrelevant, but we can't pass an invalid
|
// The actual value here is irrelevant, but we can't pass an invalid
|
||||||
// bool through XPConnect.
|
// bool through XPConnect.
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "mozilla/EditorBase.h"
|
#include "mozilla/EditorBase.h"
|
||||||
#include "mozilla/dom/Selection.h"
|
#include "mozilla/dom/Selection.h"
|
||||||
#include "mozilla/mozalloc.h"
|
#include "mozilla/mozalloc.h"
|
||||||
|
#include "mozilla/RangeBoundary.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
|
|
@ -56,46 +57,54 @@ DeleteRangeTransaction::DoTransaction()
|
||||||
rangeToDelete.swap(mRangeToDelete);
|
rangeToDelete.swap(mRangeToDelete);
|
||||||
|
|
||||||
// build the child transactions
|
// build the child transactions
|
||||||
nsCOMPtr<nsINode> startContainer = rangeToDelete->GetStartContainer();
|
const RangeBoundary& startRef = rangeToDelete->StartRef();
|
||||||
int32_t startOffset = rangeToDelete->StartOffset();
|
const RangeBoundary& endRef = rangeToDelete->EndRef();
|
||||||
nsCOMPtr<nsINode> endContainer = rangeToDelete->GetEndContainer();
|
MOZ_ASSERT(startRef.IsSetAndValid());
|
||||||
int32_t endOffset = rangeToDelete->EndOffset();
|
MOZ_ASSERT(endRef.IsSetAndValid());
|
||||||
MOZ_ASSERT(startContainer && endContainer);
|
|
||||||
|
|
||||||
if (startContainer == endContainer) {
|
if (startRef.Container() == endRef.Container()) {
|
||||||
// the selection begins and ends in the same node
|
// the selection begins and ends in the same node
|
||||||
nsIContent* startChild = rangeToDelete->GetChildAtStartOffset();
|
nsresult rv = CreateTxnsToDeleteBetween(startRef.AsRaw(), endRef.AsRaw());
|
||||||
nsresult rv =
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
CreateTxnsToDeleteBetween(startContainer, startOffset,
|
return rv;
|
||||||
startChild, endOffset);
|
}
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
} else {
|
} else {
|
||||||
// the selection ends in a different node from where it started. delete
|
// the selection ends in a different node from where it started. delete
|
||||||
// the relevant content in the start node
|
// the relevant content in the start node
|
||||||
nsresult rv =
|
nsresult rv = CreateTxnsToDeleteContent(startRef.AsRaw(), nsIEditor::eNext);
|
||||||
CreateTxnsToDeleteContent(startContainer, startOffset, nsIEditor::eNext);
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
return rv;
|
||||||
|
}
|
||||||
// delete the intervening nodes
|
// delete the intervening nodes
|
||||||
rv = CreateTxnsToDeleteNodesBetween(rangeToDelete);
|
rv = CreateTxnsToDeleteNodesBetween(rangeToDelete);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
// delete the relevant content in the end node
|
// delete the relevant content in the end node
|
||||||
rv = CreateTxnsToDeleteContent(endContainer, endOffset,
|
rv = CreateTxnsToDeleteContent(endRef.AsRaw(), nsIEditor::ePrevious);
|
||||||
nsIEditor::ePrevious);
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
return rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we've successfully built this aggregate transaction, then do it.
|
// if we've successfully built this aggregate transaction, then do it.
|
||||||
nsresult rv = EditAggregateTransaction::DoTransaction();
|
nsresult rv = EditAggregateTransaction::DoTransaction();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// only set selection to deletion point if editor gives permission
|
// only set selection to deletion point if editor gives permission
|
||||||
bool bAdjustSelection;
|
bool bAdjustSelection;
|
||||||
mEditorBase->ShouldTxnSetSelection(&bAdjustSelection);
|
mEditorBase->ShouldTxnSetSelection(&bAdjustSelection);
|
||||||
if (bAdjustSelection) {
|
if (bAdjustSelection) {
|
||||||
RefPtr<Selection> selection = mEditorBase->GetSelection();
|
RefPtr<Selection> selection = mEditorBase->GetSelection();
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
if (NS_WARN_IF(!selection)) {
|
||||||
rv = selection->Collapse(startContainer, startOffset);
|
return NS_ERROR_NULL_POINTER;
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
}
|
||||||
|
rv = selection->Collapse(startRef.AsRaw());
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// else do nothing - dom range gravity will adjust selection
|
// else do nothing - dom range gravity will adjust selection
|
||||||
|
|
||||||
|
|
@ -122,30 +131,36 @@ DeleteRangeTransaction::GetTxnDescription(nsAString& aString)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
DeleteRangeTransaction::CreateTxnsToDeleteBetween(nsINode* aNode,
|
DeleteRangeTransaction::CreateTxnsToDeleteBetween(
|
||||||
int32_t aStartOffset,
|
const RawRangeBoundary& aStart,
|
||||||
nsIContent* aChildAtStartOffset,
|
const RawRangeBoundary& aEnd)
|
||||||
int32_t aEndOffset)
|
|
||||||
{
|
{
|
||||||
|
if (NS_WARN_IF(!aStart.IsSetAndValid()) ||
|
||||||
|
NS_WARN_IF(!aEnd.IsSetAndValid()) ||
|
||||||
|
NS_WARN_IF(aStart.Container() != aEnd.Container())) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(!mEditorBase)) {
|
if (NS_WARN_IF(!mEditorBase)) {
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see what kind of node we have
|
// see what kind of node we have
|
||||||
if (aNode->IsNodeOfType(nsINode::eDATA_NODE)) {
|
if (aStart.Container()->IsNodeOfType(nsINode::eDATA_NODE)) {
|
||||||
// if the node is a chardata node, then delete chardata content
|
// if the node is a chardata node, then delete chardata content
|
||||||
int32_t numToDel;
|
int32_t numToDel;
|
||||||
if (aStartOffset == aEndOffset) {
|
if (aStart == aEnd) {
|
||||||
numToDel = 1;
|
numToDel = 1;
|
||||||
} else {
|
} else {
|
||||||
numToDel = aEndOffset - aStartOffset;
|
numToDel = aEnd.Offset() - aStart.Offset();
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(numToDel > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<nsGenericDOMDataNode> charDataNode =
|
RefPtr<nsGenericDOMDataNode> charDataNode =
|
||||||
static_cast<nsGenericDOMDataNode*>(aNode);
|
static_cast<nsGenericDOMDataNode*>(aStart.Container());
|
||||||
|
|
||||||
RefPtr<DeleteTextTransaction> deleteTextTransaction =
|
RefPtr<DeleteTextTransaction> deleteTextTransaction =
|
||||||
new DeleteTextTransaction(*mEditorBase, *charDataNode, aStartOffset,
|
new DeleteTextTransaction(*mEditorBase, *charDataNode, aStart.Offset(),
|
||||||
numToDel, mRangeUpdater);
|
numToDel, mRangeUpdater);
|
||||||
// If the text node isn't editable, it should be never undone/redone.
|
// If the text node isn't editable, it should be never undone/redone.
|
||||||
// So, the transaction shouldn't be recorded.
|
// So, the transaction shouldn't be recorded.
|
||||||
|
|
@ -156,13 +171,11 @@ DeleteRangeTransaction::CreateTxnsToDeleteBetween(nsINode* aNode,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIContent* child = aChildAtStartOffset;
|
// Even if we detect invalid range, we should ignore it for removing
|
||||||
for (int32_t i = aStartOffset; i < aEndOffset; ++i) {
|
// specified range's nodes as far as possible.
|
||||||
// Even if we detect invalid range, we should ignore it for removing
|
for (nsIContent* child = aStart.GetChildAtOffset();
|
||||||
// specified range's nodes as far as possible.
|
child && child != aEnd.GetChildAtOffset();
|
||||||
if (NS_WARN_IF(!child)) {
|
child = child->GetNextSibling()) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
|
RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
|
||||||
new DeleteNodeTransaction(*mEditorBase, *child, mRangeUpdater);
|
new DeleteNodeTransaction(*mEditorBase, *child, mRangeUpdater);
|
||||||
// XXX This is odd handling. Even if some children are not editable,
|
// XXX This is odd handling. Even if some children are not editable,
|
||||||
|
|
@ -172,48 +185,54 @@ DeleteRangeTransaction::CreateTxnsToDeleteBetween(nsINode* aNode,
|
||||||
if (deleteNodeTransaction->CanDoIt()) {
|
if (deleteNodeTransaction->CanDoIt()) {
|
||||||
AppendChild(deleteNodeTransaction);
|
AppendChild(deleteNodeTransaction);
|
||||||
}
|
}
|
||||||
child = child->GetNextSibling();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
DeleteRangeTransaction::CreateTxnsToDeleteContent(nsINode* aNode,
|
DeleteRangeTransaction::CreateTxnsToDeleteContent(
|
||||||
int32_t aOffset,
|
const RawRangeBoundary& aPoint,
|
||||||
nsIEditor::EDirection aAction)
|
nsIEditor::EDirection aAction)
|
||||||
{
|
{
|
||||||
|
if (NS_WARN_IF(!aPoint.IsSetAndValid())) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(!mEditorBase)) {
|
if (NS_WARN_IF(!mEditorBase)) {
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see what kind of node we have
|
if (!aPoint.Container()->IsNodeOfType(nsINode::eDATA_NODE)) {
|
||||||
if (aNode->IsNodeOfType(nsINode::eDATA_NODE)) {
|
return NS_OK;
|
||||||
// if the node is a chardata node, then delete chardata content
|
|
||||||
uint32_t start, numToDelete;
|
|
||||||
if (nsIEditor::eNext == aAction) {
|
|
||||||
start = aOffset;
|
|
||||||
numToDelete = aNode->Length() - aOffset;
|
|
||||||
} else {
|
|
||||||
start = 0;
|
|
||||||
numToDelete = aOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numToDelete) {
|
|
||||||
RefPtr<nsGenericDOMDataNode> dataNode =
|
|
||||||
static_cast<nsGenericDOMDataNode*>(aNode);
|
|
||||||
RefPtr<DeleteTextTransaction> deleteTextTransaction =
|
|
||||||
new DeleteTextTransaction(*mEditorBase, *dataNode, start, numToDelete,
|
|
||||||
mRangeUpdater);
|
|
||||||
// If the text node isn't editable, it should be never undone/redone.
|
|
||||||
// So, the transaction shouldn't be recorded.
|
|
||||||
if (NS_WARN_IF(!deleteTextTransaction->CanDoIt())) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
AppendChild(deleteTextTransaction);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the node is a chardata node, then delete chardata content
|
||||||
|
uint32_t startOffset, numToDelete;
|
||||||
|
if (nsIEditor::eNext == aAction) {
|
||||||
|
startOffset = aPoint.Offset();
|
||||||
|
numToDelete = aPoint.Container()->Length() - aPoint.Offset();
|
||||||
|
} else {
|
||||||
|
startOffset = 0;
|
||||||
|
numToDelete = aPoint.Offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!numToDelete) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<nsGenericDOMDataNode> dataNode =
|
||||||
|
static_cast<nsGenericDOMDataNode*>(aPoint.Container());
|
||||||
|
RefPtr<DeleteTextTransaction> deleteTextTransaction =
|
||||||
|
new DeleteTextTransaction(*mEditorBase, *dataNode, startOffset, numToDelete,
|
||||||
|
mRangeUpdater);
|
||||||
|
// If the text node isn't editable, it should be never undone/redone.
|
||||||
|
// So, the transaction shouldn't be recorded.
|
||||||
|
if (NS_WARN_IF(!deleteTextTransaction->CanDoIt())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
AppendChild(deleteTextTransaction);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#define DeleteRangeTransaction_h
|
#define DeleteRangeTransaction_h
|
||||||
|
|
||||||
#include "EditAggregateTransaction.h"
|
#include "EditAggregateTransaction.h"
|
||||||
|
#include "mozilla/RangeBoundary.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "nsID.h"
|
#include "nsID.h"
|
||||||
#include "nsIEditor.h"
|
#include "nsIEditor.h"
|
||||||
|
|
@ -50,15 +51,53 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsresult CreateTxnsToDeleteBetween(nsINode* aNode,
|
/**
|
||||||
int32_t aStartOffset,
|
* CreateTxnsToDeleteBetween() creates a DeleteTextTransaction or some
|
||||||
nsIContent* aChildAtStartOffset,
|
* DeleteNodeTransactions to remove text or nodes between aStart and aEnd
|
||||||
int32_t aEndOffset);
|
* and appends the created transactions to the array.
|
||||||
|
*
|
||||||
|
* @param aStart Must be set and valid point.
|
||||||
|
* @param aEnd Must be set and valid point. Additionally, the
|
||||||
|
* container must be same as aStart's container.
|
||||||
|
* And of course, this must not be before aStart in
|
||||||
|
* the DOM tree order.
|
||||||
|
* @return Returns NS_OK in most cases.
|
||||||
|
* When the arguments are invalid, returns
|
||||||
|
* NS_ERROR_INVALID_ARG.
|
||||||
|
* When mEditorBase isn't available, returns
|
||||||
|
* NS_ERROR_NOT_AVAIALBLE.
|
||||||
|
* When created DeleteTextTransaction cannot do its
|
||||||
|
* transaction, returns NS_ERROR_FAILURE.
|
||||||
|
* Note that even if one of created DeleteNodeTransaction
|
||||||
|
* cannot do its transaction, this returns NS_OK.
|
||||||
|
*/
|
||||||
|
nsresult CreateTxnsToDeleteBetween(const RawRangeBoundary& aStart,
|
||||||
|
const RawRangeBoundary& aEnd);
|
||||||
|
|
||||||
nsresult CreateTxnsToDeleteNodesBetween(nsRange* aRangeToDelete);
|
nsresult CreateTxnsToDeleteNodesBetween(nsRange* aRangeToDelete);
|
||||||
|
|
||||||
nsresult CreateTxnsToDeleteContent(nsINode* aParent,
|
/**
|
||||||
int32_t aOffset,
|
* CreateTxnsToDeleteContent() creates a DeleteTextTransaction to delete
|
||||||
|
* text between start of aPoint.Container() and aPoint or aPoint and end of
|
||||||
|
* aPoint.Container() and appends the created transaction to the array.
|
||||||
|
*
|
||||||
|
* @param aPoint Must be set and valid point. If the container is not
|
||||||
|
* a data node, this method does nothing.
|
||||||
|
* @param aAction If nsIEditor::eNext, this method creates a transaction
|
||||||
|
* to delete text from aPoint to the end of the data node.
|
||||||
|
* Otherwise, this method creates a transaction to delete
|
||||||
|
* text from start of the data node to aPoint.
|
||||||
|
* @return Returns NS_OK in most cases.
|
||||||
|
* When the arguments are invalid, returns
|
||||||
|
* NS_ERROR_INVALID_ARG.
|
||||||
|
* When mEditorBase isn't available, returns
|
||||||
|
* NS_ERROR_NOT_AVAIALBLE.
|
||||||
|
* When created DeleteTextTransaction cannot do its
|
||||||
|
* transaction, returns NS_ERROR_FAILURE.
|
||||||
|
* Note that even if no character will be deleted,
|
||||||
|
* this returns NS_OK.
|
||||||
|
*/
|
||||||
|
nsresult CreateTxnsToDeleteContent(const RawRangeBoundary& aPoint,
|
||||||
nsIEditor::EDirection aAction);
|
nsIEditor::EDirection aAction);
|
||||||
|
|
||||||
// The editor for this transaction.
|
// The editor for this transaction.
|
||||||
|
|
|
||||||
|
|
@ -404,8 +404,8 @@ public:
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(IsValid());
|
MOZ_ASSERT(IsValid());
|
||||||
|
|
||||||
if (mLayer->AsContainerLayer()) {
|
if (mLayer->AsRefLayer()) {
|
||||||
return mLayer->AsContainerLayer()->GetEventRegionsOverride();
|
return mLayer->AsRefLayer()->GetEventRegionsOverride();
|
||||||
}
|
}
|
||||||
return EventRegionsOverride::NoOverride;
|
return EventRegionsOverride::NoOverride;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -840,8 +840,7 @@ ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData)
|
||||||
mUseIntermediateSurface(false),
|
mUseIntermediateSurface(false),
|
||||||
mSupportsComponentAlphaChildren(false),
|
mSupportsComponentAlphaChildren(false),
|
||||||
mMayHaveReadbackChild(false),
|
mMayHaveReadbackChild(false),
|
||||||
mChildrenChanged(false),
|
mChildrenChanged(false)
|
||||||
mEventRegionsOverride(EventRegionsOverride::NoOverride)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1035,8 +1034,7 @@ ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||||
{
|
{
|
||||||
aAttrs = ContainerLayerAttributes(mPreXScale, mPreYScale,
|
aAttrs = ContainerLayerAttributes(mPreXScale, mPreYScale,
|
||||||
mInheritedXScale, mInheritedYScale,
|
mInheritedXScale, mInheritedYScale,
|
||||||
mPresShellResolution, mScaleToResolution,
|
mPresShellResolution, mScaleToResolution);
|
||||||
mEventRegionsOverride);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -2062,12 +2060,6 @@ ContainerLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||||
if (mScaleToResolution) {
|
if (mScaleToResolution) {
|
||||||
aStream << nsPrintfCString(" [presShellResolution=%g]", mPresShellResolution).get();
|
aStream << nsPrintfCString(" [presShellResolution=%g]", mPresShellResolution).get();
|
||||||
}
|
}
|
||||||
if (mEventRegionsOverride & EventRegionsOverride::ForceDispatchToContent) {
|
|
||||||
aStream << " [force-dtc]";
|
|
||||||
}
|
|
||||||
if (mEventRegionsOverride & EventRegionsOverride::ForceEmptyHitRegion) {
|
|
||||||
aStream << " [force-ehr]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2244,6 +2236,12 @@ RefLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||||
if (0 != mId) {
|
if (0 != mId) {
|
||||||
AppendToString(aStream, mId, " [id=", "]");
|
AppendToString(aStream, mId, " [id=", "]");
|
||||||
}
|
}
|
||||||
|
if (mEventRegionsOverride & EventRegionsOverride::ForceDispatchToContent) {
|
||||||
|
aStream << " [force-dtc]";
|
||||||
|
}
|
||||||
|
if (mEventRegionsOverride & EventRegionsOverride::ForceEmptyHitRegion) {
|
||||||
|
aStream << " [force-ehr]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -2315,20 +2315,6 @@ public:
|
||||||
mChildrenChanged = aVal;
|
mChildrenChanged = aVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetEventRegionsOverride(EventRegionsOverride aVal) {
|
|
||||||
if (mEventRegionsOverride == aVal) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) EventRegionsOverride", this));
|
|
||||||
mEventRegionsOverride = aVal;
|
|
||||||
Mutated();
|
|
||||||
}
|
|
||||||
|
|
||||||
EventRegionsOverride GetEventRegionsOverride() const {
|
|
||||||
return mEventRegionsOverride;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If |aRect| is null, the entire layer should be considered invalid for
|
// If |aRect| is null, the entire layer should be considered invalid for
|
||||||
// compositing.
|
// compositing.
|
||||||
virtual void SetInvalidCompositeRect(const gfx::IntRect* aRect) {}
|
virtual void SetInvalidCompositeRect(const gfx::IntRect* aRect) {}
|
||||||
|
|
@ -2418,7 +2404,6 @@ protected:
|
||||||
// This is updated by ComputeDifferences. This will be true if we need to invalidate
|
// This is updated by ComputeDifferences. This will be true if we need to invalidate
|
||||||
// the intermediate surface.
|
// the intermediate surface.
|
||||||
bool mChildrenChanged;
|
bool mChildrenChanged;
|
||||||
EventRegionsOverride mEventRegionsOverride;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2837,6 +2822,25 @@ public:
|
||||||
aLayer->SetParent(this);
|
aLayer->SetParent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CONSTRUCTION PHASE ONLY
|
||||||
|
* Set flags that indicate how event regions in the child layer tree need
|
||||||
|
* to be overridden because of properties of the parent layer tree.
|
||||||
|
*/
|
||||||
|
void SetEventRegionsOverride(EventRegionsOverride aVal) {
|
||||||
|
if (mEventRegionsOverride == aVal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) EventRegionsOverride", this));
|
||||||
|
mEventRegionsOverride = aVal;
|
||||||
|
Mutated();
|
||||||
|
}
|
||||||
|
|
||||||
|
EventRegionsOverride GetEventRegionsOverride() const {
|
||||||
|
return mEventRegionsOverride;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DRAWING PHASE ONLY
|
* DRAWING PHASE ONLY
|
||||||
* |aLayer| is the same as the argument to ConnectReferentLayer().
|
* |aLayer| is the same as the argument to ConnectReferentLayer().
|
||||||
|
|
@ -2861,7 +2865,9 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RefLayer(LayerManager* aManager, void* aImplData)
|
RefLayer(LayerManager* aManager, void* aImplData)
|
||||||
: ContainerLayer(aManager, aImplData) , mId(0)
|
: ContainerLayer(aManager, aImplData)
|
||||||
|
, mId(0)
|
||||||
|
, mEventRegionsOverride(EventRegionsOverride::NoOverride)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
|
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
|
||||||
|
|
@ -2870,6 +2876,7 @@ protected:
|
||||||
|
|
||||||
// 0 is a special value that means "no ID".
|
// 0 is a special value that means "no ID".
|
||||||
uint64_t mId;
|
uint64_t mId;
|
||||||
|
EventRegionsOverride mEventRegionsOverride;
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetAntialiasingFlags(Layer* aLayer, gfx::DrawTarget* aTarget);
|
void SetAntialiasingFlags(Layer* aLayer, gfx::DrawTarget* aTarget);
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ struct EventRegions {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bit flags that go on a ContainerLayer (or RefLayer) and override the
|
// Bit flags that go on a RefLayer and override the
|
||||||
// event regions in the entire subtree below. This is needed for propagating
|
// event regions in the entire subtree below. This is needed for propagating
|
||||||
// various flags across processes since the child-process layout code doesn't
|
// various flags across processes since the child-process layout code doesn't
|
||||||
// know about parent-process listeners or CSS rules.
|
// know about parent-process listeners or CSS rules.
|
||||||
|
|
|
||||||
|
|
@ -651,6 +651,10 @@ GetEventRegionsOverride(HitTestingTreeNode* aParent,
|
||||||
// layer in the hit-test tree. This saves having to walk up the tree every
|
// layer in the hit-test tree. This saves having to walk up the tree every
|
||||||
// we want to see if a hit-test node is affected by this flag.
|
// we want to see if a hit-test node is affected by this flag.
|
||||||
EventRegionsOverride result = aLayer.GetEventRegionsOverride();
|
EventRegionsOverride result = aLayer.GetEventRegionsOverride();
|
||||||
|
if (result != EventRegionsOverride::NoOverride) {
|
||||||
|
// Overrides should only ever get set for ref layers.
|
||||||
|
MOZ_ASSERT(aLayer.GetReferentId());
|
||||||
|
}
|
||||||
if (aParent) {
|
if (aParent) {
|
||||||
result |= aParent->GetEventRegionsOverride();
|
result |= aParent->GetEventRegionsOverride();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
60
gfx/layers/apz/test/mochitest/helper_override_root.html
Normal file
60
gfx/layers/apz/test/mochitest/helper_override_root.html
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width; initial-scale=1.0">
|
||||||
|
<title>Simple wheel scroll cancellation</title>
|
||||||
|
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||||
|
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
// Add a non-passive listener on the document, so that we have a document-level
|
||||||
|
// APZ-aware listener, and the entire document is put in the dispatch-to-content
|
||||||
|
// region
|
||||||
|
document.addEventListener('wheel', function(e) {
|
||||||
|
dump("Wheel listener running...\n");
|
||||||
|
|
||||||
|
// spin for 2 seconds to give APZ time to scroll, if the event region override
|
||||||
|
// is broken and it decides not to wait for the main thread. Note that it's
|
||||||
|
// possible the APZ controller thread is busy for whatever reason so APZ
|
||||||
|
// may not scroll. That might cause this test to only fail intermittently
|
||||||
|
// instead of consistently if the behaviour being tested regresses.
|
||||||
|
var now = Date.now();
|
||||||
|
while (Date.now() - now < 2000);
|
||||||
|
|
||||||
|
// Cancel the scroll. If this works then we know APZ waited for this listener
|
||||||
|
// to run.
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
flushApzRepaints(checkScroll);
|
||||||
|
}, 0);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
function scrollPage() {
|
||||||
|
synthesizeNativeWheel(document.body, 100, 100, 0, -50);
|
||||||
|
dump("Finished native wheel, waiting for listener to run...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkScroll() {
|
||||||
|
is(window.scrollY, 0, "check that the window didn't scroll");
|
||||||
|
subtestDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.top != window) {
|
||||||
|
dump("Running inside an iframe! stealing functions from window.top...\n");
|
||||||
|
window.subtestDone = window.top.subtestDone;
|
||||||
|
window.SimpleTest = window.top.SimpleTest;
|
||||||
|
window.is = window.top.is;
|
||||||
|
window.ok = window.top.ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
waitUntilApzStable().then(scrollPage);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body style="height: 5000px; background-image: linear-gradient(green,red);">
|
||||||
|
This page should not be wheel-scrollable.
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
15
gfx/layers/apz/test/mochitest/helper_override_subdoc.html
Normal file
15
gfx/layers/apz/test/mochitest/helper_override_subdoc.html
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width; initial-scale=1.0">
|
||||||
|
<title>Wheel scroll cancellation inside iframe</title>
|
||||||
|
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
This just loads helper_override_root in an iframe, so that we test event
|
||||||
|
regions overriding on in-process subdocuments.
|
||||||
|
<iframe id="ifr" src="helper_override_root.html" onload="document.getElementById('ifr').focus()"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
helper_iframe2.html
|
helper_iframe2.html
|
||||||
helper_key_scroll.html
|
helper_key_scroll.html
|
||||||
helper_long_tap.html
|
helper_long_tap.html
|
||||||
|
helper_override_root.html
|
||||||
|
helper_override_subdoc.html
|
||||||
helper_scroll_inactive_perspective.html
|
helper_scroll_inactive_perspective.html
|
||||||
helper_scroll_inactive_zindex.html
|
helper_scroll_inactive_zindex.html
|
||||||
helper_scroll_on_position_fixed.html
|
helper_scroll_on_position_fixed.html
|
||||||
|
|
@ -72,3 +74,5 @@ skip-if = os == 'win' && os_version == '10.0' # Bug 1404836
|
||||||
skip-if = (os == 'android') # wheel events not supported on mobile
|
skip-if = (os == 'android') # wheel events not supported on mobile
|
||||||
[test_wheel_transactions.html]
|
[test_wheel_transactions.html]
|
||||||
skip-if = (os == 'android') # wheel events not supported on mobile
|
skip-if = (os == 'android') # wheel events not supported on mobile
|
||||||
|
[test_group_overrides.html]
|
||||||
|
skip-if = (os == 'android') # wheel events not supported on mobile
|
||||||
|
|
|
||||||
37
gfx/layers/apz/test/mochitest/test_group_overrides.html
Normal file
37
gfx/layers/apz/test/mochitest/test_group_overrides.html
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Various tests for event regions overrides</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
var prefs = [
|
||||||
|
// turn off smooth scrolling so that we don't have to wait for
|
||||||
|
// APZ animations to finish before sampling the scroll offset
|
||||||
|
['general.smoothScroll', false],
|
||||||
|
// Increase the content response timeout because these tests do preventDefault
|
||||||
|
// and we want to make sure APZ actually waits for them.
|
||||||
|
['apz.content_response_timeout', 10000],
|
||||||
|
]
|
||||||
|
|
||||||
|
var subtests = [
|
||||||
|
{'file': 'helper_override_root.html', 'prefs': prefs},
|
||||||
|
{'file': 'helper_override_subdoc.html', 'prefs': prefs},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isApzEnabled()) {
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
window.onload = function() {
|
||||||
|
runSubtestsSeriallyInFreshWindows(subtests)
|
||||||
|
.then(SimpleTest.finish);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -609,10 +609,6 @@ LayerTransactionParent::SetLayerAttributes(const OpSetLayerAttributes& aOp)
|
||||||
containerLayer->SetInheritedScale(attrs.inheritedXScale(), attrs.inheritedYScale());
|
containerLayer->SetInheritedScale(attrs.inheritedXScale(), attrs.inheritedYScale());
|
||||||
containerLayer->SetScaleToResolution(attrs.scaleToResolution(),
|
containerLayer->SetScaleToResolution(attrs.scaleToResolution(),
|
||||||
attrs.presShellResolution());
|
attrs.presShellResolution());
|
||||||
if (attrs.eventRegionsOverride() != containerLayer->GetEventRegionsOverride()) {
|
|
||||||
UpdateHitTestingTree(layer, "event regions override changed");
|
|
||||||
containerLayer->SetEventRegionsOverride(attrs.eventRegionsOverride());
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Specific::TColorLayerAttributes: {
|
case Specific::TColorLayerAttributes: {
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,6 @@ struct ContainerLayerAttributes {
|
||||||
float inheritedYScale;
|
float inheritedYScale;
|
||||||
float presShellResolution;
|
float presShellResolution;
|
||||||
bool scaleToResolution;
|
bool scaleToResolution;
|
||||||
EventRegionsOverride eventRegionsOverride;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GlyphArray
|
struct GlyphArray
|
||||||
|
|
@ -303,8 +302,6 @@ struct ColorLayerAttributes { LayerColor color; IntRect bounds; };
|
||||||
struct CanvasLayerAttributes { SamplingFilter samplingFilter; IntRect bounds; };
|
struct CanvasLayerAttributes { SamplingFilter samplingFilter; IntRect bounds; };
|
||||||
struct RefLayerAttributes {
|
struct RefLayerAttributes {
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
// TODO: Once bug 1132895 is fixed we shouldn't need to propagate the override
|
|
||||||
// explicitly here.
|
|
||||||
EventRegionsOverride eventRegionsOverride;
|
EventRegionsOverride eventRegionsOverride;
|
||||||
};
|
};
|
||||||
struct ImageLayerAttributes { SamplingFilter samplingFilter; IntSize scaleToSize; ScaleMode scaleMode; };
|
struct ImageLayerAttributes { SamplingFilter samplingFilter; IntSize scaleToSize; ScaleMode scaleMode; };
|
||||||
|
|
|
||||||
|
|
@ -80,12 +80,6 @@ WebRenderCommandBuilder::BuildWebRenderCommands(wr::DisplayListBuilder& aBuilder
|
||||||
// Make a "root" layer data that has everything else as descendants
|
// Make a "root" layer data that has everything else as descendants
|
||||||
mLayerScrollData.emplace_back();
|
mLayerScrollData.emplace_back();
|
||||||
mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
|
mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
|
||||||
if (aDisplayListBuilder->IsBuildingLayerEventRegions()) {
|
|
||||||
nsIPresShell* shell = aDisplayListBuilder->RootReferenceFrame()->PresShell();
|
|
||||||
if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(shell)) {
|
|
||||||
mLayerScrollData.back().SetEventRegionsOverride(EventRegionsOverride::ForceDispatchToContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto callback = [&aScrollData](FrameMetrics::ViewID aScrollId) -> bool {
|
auto callback = [&aScrollData](FrameMetrics::ViewID aScrollId) -> bool {
|
||||||
return aScrollData.HasMetadataFor(aScrollId);
|
return aScrollData.HasMetadataFor(aScrollId);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -225,24 +225,6 @@ WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ int32_t
|
|
||||||
PopulateScrollData(WebRenderScrollData& aTarget, Layer* aLayer)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(aLayer);
|
|
||||||
|
|
||||||
// We want to allocate a WebRenderLayerScrollData object for this layer,
|
|
||||||
// but don't keep a pointer to it since it might get memmove'd during the
|
|
||||||
// recursion below. Instead keep the index and get the pointer later.
|
|
||||||
size_t index = aTarget.AddNewLayerData();
|
|
||||||
|
|
||||||
int32_t descendants = 0;
|
|
||||||
for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) {
|
|
||||||
descendants += PopulateScrollData(aTarget, child);
|
|
||||||
}
|
|
||||||
aTarget.GetLayerDataMutable(index)->Initialize(aTarget, aLayer, descendants);
|
|
||||||
return descendants + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
|
WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
|
||||||
void* aCallbackData,
|
void* aCallbackData,
|
||||||
|
|
|
||||||
|
|
@ -32,37 +32,6 @@ WebRenderLayerScrollData::~WebRenderLayerScrollData()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
WebRenderLayerScrollData::Initialize(WebRenderScrollData& aOwner,
|
|
||||||
Layer* aLayer,
|
|
||||||
int32_t aDescendantCount)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(aDescendantCount >= 0); // Ensure value is valid
|
|
||||||
MOZ_ASSERT(mDescendantCount == -1); // Don't allow re-setting an already set value
|
|
||||||
mDescendantCount = aDescendantCount;
|
|
||||||
|
|
||||||
MOZ_ASSERT(aLayer);
|
|
||||||
for (uint32_t i = 0; i < aLayer->GetScrollMetadataCount(); i++) {
|
|
||||||
mScrollIds.AppendElement(aOwner.AddMetadata(aLayer->GetScrollMetadata(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
mTransform = aLayer->GetTransform();
|
|
||||||
mTransformIsPerspective = aLayer->GetTransformIsPerspective();
|
|
||||||
mEventRegions = aLayer->GetEventRegions();
|
|
||||||
mVisibleRegion = aLayer->GetVisibleRegion();
|
|
||||||
mReferentId = aLayer->AsRefLayer()
|
|
||||||
? Some(aLayer->AsRefLayer()->GetReferentId())
|
|
||||||
: Nothing();
|
|
||||||
mEventRegionsOverride = aLayer->AsContainerLayer()
|
|
||||||
? aLayer->AsContainerLayer()->GetEventRegionsOverride()
|
|
||||||
: EventRegionsOverride::NoOverride;
|
|
||||||
mScrollThumbData = aLayer->GetScrollThumbData();
|
|
||||||
mScrollbarAnimationId = aLayer->GetCompositorAnimationsId();
|
|
||||||
mScrollbarTargetContainerId = aLayer->GetScrollbarTargetContainerId();
|
|
||||||
mIsScrollbarContainer = aLayer->IsScrollbarContainer();
|
|
||||||
mFixedPosScrollContainerId = aLayer->GetFixedPositionScrollContainerId();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WebRenderLayerScrollData::InitializeRoot(int32_t aDescendantCount)
|
WebRenderLayerScrollData::InitializeRoot(int32_t aDescendantCount)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -42,12 +42,6 @@ public:
|
||||||
WebRenderLayerScrollData(); // needed for IPC purposes
|
WebRenderLayerScrollData(); // needed for IPC purposes
|
||||||
~WebRenderLayerScrollData();
|
~WebRenderLayerScrollData();
|
||||||
|
|
||||||
// Actually initialize the object. This is not done during the constructor
|
|
||||||
// for optimization purposes (the call site is hard to write efficiently
|
|
||||||
// if we do this in the constructor).
|
|
||||||
void Initialize(WebRenderScrollData& aOwner,
|
|
||||||
Layer* aLayer,
|
|
||||||
int32_t aDescendantCount);
|
|
||||||
void InitializeRoot(int32_t aDescendantCount);
|
void InitializeRoot(int32_t aDescendantCount);
|
||||||
void Initialize(WebRenderScrollData& aOwner,
|
void Initialize(WebRenderScrollData& aOwner,
|
||||||
nsDisplayItem* aItem,
|
nsDisplayItem* aItem,
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,8 @@ var gFunctions = [
|
||||||
[2, (n) => n%10==1&&n%100!=11?0:1],
|
[2, (n) => n%10==1&&n%100!=11?0:1],
|
||||||
// 16: Breton
|
// 16: Breton
|
||||||
[5, (n) => n%10==1&&n%100!=11&&n%100!=71&&n%100!=91?0:n%10==2&&n%100!=12&&n%100!=72&&n%100!=92?1:(n%10==3||n%10==4||n%10==9)&&n%100!=13&&n%100!=14&&n%100!=19&&n%100!=73&&n%100!=74&&n%100!=79&&n%100!=93&&n%100!=94&&n%100!=99?2:n%1000000==0&&n!=0?3:4],
|
[5, (n) => n%10==1&&n%100!=11&&n%100!=71&&n%100!=91?0:n%10==2&&n%100!=12&&n%100!=72&&n%100!=92?1:(n%10==3||n%10==4||n%10==9)&&n%100!=13&&n%100!=14&&n%100!=19&&n%100!=73&&n%100!=74&&n%100!=79&&n%100!=93&&n%100!=94&&n%100!=99?2:n%1000000==0&&n!=0?3:4],
|
||||||
|
// 17: Shuar
|
||||||
|
[2, (n) => n!=0?1:0],
|
||||||
];
|
];
|
||||||
|
|
||||||
this.PluralForm = {
|
this.PluralForm = {
|
||||||
|
|
|
||||||
|
|
@ -589,6 +589,40 @@ function run_test()
|
||||||
5,5,5,5,5,5,5,5,5,5,
|
5,5,5,5,5,5,5,5,5,5,
|
||||||
5,1,2,3,3,5,5,5,5,3,
|
5,1,2,3,3,5,5,5,5,3,
|
||||||
5,5,5,5,5,5,5,5,5,5,
|
5,5,5,5,5,5,5,5,5,5,
|
||||||
|
], [
|
||||||
|
// 17: Shuar 0-9, 10-19, ..., 90-99
|
||||||
|
1,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
// 100-109, 110-119, ..., 190-199
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
// 200-209, 210-219, ..., 290-299
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,
|
||||||
]];
|
]];
|
||||||
|
|
||||||
for (let [rule, expect] of allExpect.entries()) {
|
for (let [rule, expect] of allExpect.entries()) {
|
||||||
|
|
|
||||||
|
|
@ -3780,6 +3780,9 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
||||||
|
|
||||||
builder.SetVisibleRect(visibleRect);
|
builder.SetVisibleRect(visibleRect);
|
||||||
builder.SetIsBuilding(true);
|
builder.SetIsBuilding(true);
|
||||||
|
builder.SetAncestorHasApzAwareEventHandler(
|
||||||
|
builder.IsBuildingLayerEventRegions() &&
|
||||||
|
nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell));
|
||||||
|
|
||||||
const bool paintedPreviously =
|
const bool paintedPreviously =
|
||||||
aFrame->HasProperty(nsIFrame::ModifiedFrameList());
|
aFrame->HasProperty(nsIFrame::ModifiedFrameList());
|
||||||
|
|
|
||||||
|
|
@ -2528,6 +2528,10 @@ public:
|
||||||
static void
|
static void
|
||||||
CheckForApzAwareEventHandlers(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
CheckForApzAwareEventHandlers(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
|
if (aBuilder->GetAncestorHasApzAwareEventHandler()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsIContent* content = aFrame->GetContent();
|
nsIContent* content = aFrame->GetContent();
|
||||||
if (!content) {
|
if (!content) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -447,12 +447,6 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
needsOwnLayer = true;
|
needsOwnLayer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needsOwnLayer && aBuilder->IsBuildingLayerEventRegions() &&
|
|
||||||
nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell))
|
|
||||||
{
|
|
||||||
needsOwnLayer = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aBuilder->IsRetainingDisplayList()) {
|
if (aBuilder->IsRetainingDisplayList()) {
|
||||||
// The value of needsOwnLayer can change between builds without
|
// The value of needsOwnLayer can change between builds without
|
||||||
// an invalidation recorded for this frame (like if the root
|
// an invalidation recorded for this frame (like if the root
|
||||||
|
|
@ -505,7 +499,11 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
? nsLayoutUtils::FindOrCreateIDFor(rootScrollFrame->GetContent())
|
? nsLayoutUtils::FindOrCreateIDFor(rootScrollFrame->GetContent())
|
||||||
: aBuilder->GetCurrentScrollParentId());
|
: aBuilder->GetCurrentScrollParentId());
|
||||||
|
|
||||||
aBuilder->SetAncestorHasApzAwareEventHandler(false);
|
bool hasDocumentLevelListenersForApzAwareEvents =
|
||||||
|
aBuilder->IsBuildingLayerEventRegions() &&
|
||||||
|
nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell);
|
||||||
|
|
||||||
|
aBuilder->SetAncestorHasApzAwareEventHandler(hasDocumentLevelListenersForApzAwareEvents);
|
||||||
subdocRootFrame->
|
subdocRootFrame->
|
||||||
BuildDisplayListForStackingContext(aBuilder, &childItems);
|
BuildDisplayListForStackingContext(aBuilder, &childItems);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -374,8 +374,8 @@ nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||||
const ContainerLayerParameters& aContainerParameters)
|
const ContainerLayerParameters& aContainerParameters)
|
||||||
{
|
{
|
||||||
RefPtr<Layer> layer = mRemoteFrame->BuildLayer(aBuilder, mFrame, aManager, this, aContainerParameters);
|
RefPtr<Layer> layer = mRemoteFrame->BuildLayer(aBuilder, mFrame, aManager, this, aContainerParameters);
|
||||||
if (layer && layer->AsContainerLayer()) {
|
if (layer && layer->AsRefLayer()) {
|
||||||
layer->AsContainerLayer()->SetEventRegionsOverride(mEventRegionsOverride);
|
layer->AsRefLayer()->SetEventRegionsOverride(mEventRegionsOverride);
|
||||||
}
|
}
|
||||||
return layer.forget();
|
return layer.forget();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2481,12 +2481,6 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
|
||||||
1.0f/containerParameters.mYScale);
|
1.0f/containerParameters.mYScale);
|
||||||
root->SetScaleToResolution(presShell->ScaleToResolution(),
|
root->SetScaleToResolution(presShell->ScaleToResolution(),
|
||||||
containerParameters.mXScale);
|
containerParameters.mXScale);
|
||||||
if (aBuilder->IsBuildingLayerEventRegions() &&
|
|
||||||
nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell)) {
|
|
||||||
root->SetEventRegionsOverride(EventRegionsOverride::ForceDispatchToContent);
|
|
||||||
} else {
|
|
||||||
root->SetEventRegionsOverride(EventRegionsOverride::NoOverride);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto callback = [root](FrameMetrics::ViewID aScrollId) -> bool {
|
auto callback = [root](FrameMetrics::ViewID aScrollId) -> bool {
|
||||||
return nsLayoutUtils::ContainsMetricsWithId(root, aScrollId);
|
return nsLayoutUtils::ContainsMetricsWithId(root, aScrollId);
|
||||||
|
|
@ -6861,9 +6855,6 @@ nsDisplaySubDocument::nsDisplaySubDocument(nsDisplayListBuilder* aBuilder,
|
||||||
, mSubDocFrame(aSubDocFrame)
|
, mSubDocFrame(aSubDocFrame)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsDisplaySubDocument);
|
MOZ_COUNT_CTOR(nsDisplaySubDocument);
|
||||||
mForceDispatchToContentRegion =
|
|
||||||
aBuilder->IsBuildingLayerEventRegions() &&
|
|
||||||
nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(aFrame->PresShell());
|
|
||||||
|
|
||||||
// The SubDocument display item is conceptually outside the viewport frame,
|
// The SubDocument display item is conceptually outside the viewport frame,
|
||||||
// so in cases where the viewport frame is an AGR, the SubDocument's AGR
|
// so in cases where the viewport frame is an AGR, the SubDocument's AGR
|
||||||
|
|
@ -6879,17 +6870,6 @@ nsDisplaySubDocument::~nsDisplaySubDocument() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
already_AddRefed<Layer>
|
|
||||||
nsDisplaySubDocument::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|
||||||
LayerManager* aManager,
|
|
||||||
const ContainerLayerParameters& aContainerParameters) {
|
|
||||||
RefPtr<Layer> layer = nsDisplayOwnLayer::BuildLayer(aBuilder, aManager, aContainerParameters);
|
|
||||||
layer->AsContainerLayer()->SetEventRegionsOverride(mForceDispatchToContentRegion
|
|
||||||
? EventRegionsOverride::ForceDispatchToContent
|
|
||||||
: EventRegionsOverride::NoOverride);
|
|
||||||
return layer.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
UniquePtr<ScrollMetadata>
|
UniquePtr<ScrollMetadata>
|
||||||
nsDisplaySubDocument::ComputeScrollMetadata(LayerManager* aLayerManager,
|
nsDisplaySubDocument::ComputeScrollMetadata(LayerManager* aLayerManager,
|
||||||
const ContainerLayerParameters& aContainerParameters)
|
const ContainerLayerParameters& aContainerParameters)
|
||||||
|
|
|
||||||
|
|
@ -701,7 +701,7 @@ public:
|
||||||
return CurrentPresShellState()->mInsidePointerEventsNoneDoc;
|
return CurrentPresShellState()->mInsidePointerEventsNoneDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetAncestorHasApzAwareEventHandler() { return mAncestorHasApzAwareEventHandler; }
|
bool GetAncestorHasApzAwareEventHandler() const { return mAncestorHasApzAwareEventHandler; }
|
||||||
void SetAncestorHasApzAwareEventHandler(bool aValue)
|
void SetAncestorHasApzAwareEventHandler(bool aValue)
|
||||||
{
|
{
|
||||||
mAncestorHasApzAwareEventHandler = aValue;
|
mAncestorHasApzAwareEventHandler = aValue;
|
||||||
|
|
@ -5111,10 +5111,6 @@ public:
|
||||||
virtual ~nsDisplaySubDocument();
|
virtual ~nsDisplaySubDocument();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
|
||||||
LayerManager* aManager,
|
|
||||||
const ContainerLayerParameters& aContainerParameters) override;
|
|
||||||
|
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
|
||||||
bool* aSnap) const override;
|
bool* aSnap) const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1159,4 +1159,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
||||||
|
|
||||||
static const int32_t kUnknownId = -1;
|
static const int32_t kUnknownId = -1;
|
||||||
|
|
||||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1518637560032000);
|
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1518723892807000);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -8,7 +8,7 @@
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
const PRTime gPreloadListExpirationTime = INT64_C(1521056747051000);
|
const PRTime gPreloadListExpirationTime = INT64_C(1521143078420000);
|
||||||
%%
|
%%
|
||||||
0-1.party, 1
|
0-1.party, 1
|
||||||
0.me.uk, 1
|
0.me.uk, 1
|
||||||
|
|
@ -126,7 +126,9 @@ const PRTime gPreloadListExpirationTime = INT64_C(1521056747051000);
|
||||||
13318522.com, 1
|
13318522.com, 1
|
||||||
1359826938.rsc.cdn77.org, 1
|
1359826938.rsc.cdn77.org, 1
|
||||||
13826145000.com, 1
|
13826145000.com, 1
|
||||||
|
1391kj.com, 1
|
||||||
1395kj.com, 1
|
1395kj.com, 1
|
||||||
|
1396.cc, 1
|
||||||
1453914078.rsc.cdn77.org, 1
|
1453914078.rsc.cdn77.org, 1
|
||||||
1464424382.rsc.cdn77.org, 1
|
1464424382.rsc.cdn77.org, 1
|
||||||
14it.de, 1
|
14it.de, 1
|
||||||
|
|
@ -368,7 +370,6 @@ const PRTime gPreloadListExpirationTime = INT64_C(1521056747051000);
|
||||||
50lakeshore.com, 1
|
50lakeshore.com, 1
|
||||||
50north.de, 1
|
50north.de, 1
|
||||||
50plusnet.nl, 1
|
50plusnet.nl, 1
|
||||||
513vpn.net, 1
|
|
||||||
525.info, 1
|
525.info, 1
|
||||||
52neptune.com, 1
|
52neptune.com, 1
|
||||||
5432.cc, 1
|
5432.cc, 1
|
||||||
|
|
@ -1975,6 +1976,7 @@ arijitdg.net, 1
|
||||||
arikar.eu, 1
|
arikar.eu, 1
|
||||||
arima.co.ke, 1
|
arima.co.ke, 1
|
||||||
arinflatablefun.co.uk, 1
|
arinflatablefun.co.uk, 1
|
||||||
|
aristilabs.com, 0
|
||||||
aristocrates.co, 1
|
aristocrates.co, 1
|
||||||
aristocratps.com, 1
|
aristocratps.com, 1
|
||||||
aritec-la.com, 1
|
aritec-la.com, 1
|
||||||
|
|
@ -2062,6 +2064,7 @@ artionet.ch, 1
|
||||||
artisanhd.com, 1
|
artisanhd.com, 1
|
||||||
artisans-libres.com, 1
|
artisans-libres.com, 1
|
||||||
artisense.de, 1
|
artisense.de, 1
|
||||||
|
artisphere.ch, 1
|
||||||
artisticedgegranite.net, 1
|
artisticedgegranite.net, 1
|
||||||
artlantis.nl, 1
|
artlantis.nl, 1
|
||||||
artleading.ru, 1
|
artleading.ru, 1
|
||||||
|
|
@ -3102,7 +3105,6 @@ besthotsales.com, 1
|
||||||
bestlashesandbrows.com, 1
|
bestlashesandbrows.com, 1
|
||||||
bestlashesandbrows.hu, 1
|
bestlashesandbrows.hu, 1
|
||||||
bestleftwild.com, 1
|
bestleftwild.com, 1
|
||||||
bestmodels.su, 1
|
|
||||||
bestmotherfucking.website, 1
|
bestmotherfucking.website, 1
|
||||||
bestoliveoils.com, 1
|
bestoliveoils.com, 1
|
||||||
bestpartyhire.com, 1
|
bestpartyhire.com, 1
|
||||||
|
|
@ -3367,6 +3369,7 @@ birminghamsunset.com, 1
|
||||||
birthdaytip.com, 1
|
birthdaytip.com, 1
|
||||||
birthmatters.us, 1
|
birthmatters.us, 1
|
||||||
birzan.org, 1
|
birzan.org, 1
|
||||||
|
biscoint.io, 1
|
||||||
biscuits-rec.com, 1
|
biscuits-rec.com, 1
|
||||||
biscuits-shop.com, 1
|
biscuits-shop.com, 1
|
||||||
bismarck-tb.de, 1
|
bismarck-tb.de, 1
|
||||||
|
|
@ -4214,11 +4217,13 @@ brunoramos.org, 1
|
||||||
brunosouza.org, 1
|
brunosouza.org, 1
|
||||||
bruun.co, 1
|
bruun.co, 1
|
||||||
bryankaplan.com, 1
|
bryankaplan.com, 1
|
||||||
|
bryanquigley.com, 1
|
||||||
bs-network.net, 1
|
bs-network.net, 1
|
||||||
bs-security.com, 1
|
bs-security.com, 1
|
||||||
bs.sb, 1
|
bs.sb, 1
|
||||||
bs.to, 1
|
bs.to, 1
|
||||||
bs12v.ru, 1
|
bs12v.ru, 1
|
||||||
|
bsagan.fr, 1
|
||||||
bsalyzer.com, 1
|
bsalyzer.com, 1
|
||||||
bsc-rietz.at, 1
|
bsc-rietz.at, 1
|
||||||
bsc01.dyndns.org, 1
|
bsc01.dyndns.org, 1
|
||||||
|
|
@ -4374,7 +4379,6 @@ busindre.com, 1
|
||||||
business-garden.com, 1
|
business-garden.com, 1
|
||||||
business.facebook.com, 0
|
business.facebook.com, 0
|
||||||
business.medbank.com.mt, 1
|
business.medbank.com.mt, 1
|
||||||
businessadviceperth.com.au, 0
|
|
||||||
businessamongus.com, 1
|
businessamongus.com, 1
|
||||||
businesscentermarin.ch, 1
|
businesscentermarin.ch, 1
|
||||||
businessesdirectory.eu, 1
|
businessesdirectory.eu, 1
|
||||||
|
|
@ -4531,7 +4535,7 @@ cairnterrier.com.br, 1
|
||||||
cais.de, 1
|
cais.de, 1
|
||||||
caitcs.com, 1
|
caitcs.com, 1
|
||||||
caja-pdf.es, 1
|
caja-pdf.es, 1
|
||||||
cajio.ru, 1
|
cajio.ru, 0
|
||||||
cajunuk.co.uk, 1
|
cajunuk.co.uk, 1
|
||||||
cake-time.co.uk, 1
|
cake-time.co.uk, 1
|
||||||
cakestart.net, 1
|
cakestart.net, 1
|
||||||
|
|
@ -5050,7 +5054,6 @@ chambion.ch, 1
|
||||||
chameleon-ents.co.uk, 1
|
chameleon-ents.co.uk, 1
|
||||||
chameth.com, 1
|
chameth.com, 1
|
||||||
chamilo.org, 1
|
chamilo.org, 1
|
||||||
champ.dog, 1
|
|
||||||
champdogs.co.uk, 1
|
champdogs.co.uk, 1
|
||||||
champdogs.com, 1
|
champdogs.com, 1
|
||||||
champicreuse.fr, 1
|
champicreuse.fr, 1
|
||||||
|
|
@ -5206,7 +5209,6 @@ chengl.com, 1
|
||||||
chengtongled.com, 1
|
chengtongled.com, 1
|
||||||
chenky.com, 1
|
chenky.com, 1
|
||||||
chennien.com, 1
|
chennien.com, 1
|
||||||
chentianyi.cn, 1
|
|
||||||
chenzhekl.me, 1
|
chenzhekl.me, 1
|
||||||
cherevoiture.com, 1
|
cherevoiture.com, 1
|
||||||
cherrett.digital, 1
|
cherrett.digital, 1
|
||||||
|
|
@ -5472,7 +5474,6 @@ citizen-cam.de, 1
|
||||||
citizensbankal.com, 1
|
citizensbankal.com, 1
|
||||||
citizenscience.gov, 1
|
citizenscience.gov, 1
|
||||||
citizensleague.org, 1
|
citizensleague.org, 1
|
||||||
citizenspact.eu, 1
|
|
||||||
citizing.org, 1
|
citizing.org, 1
|
||||||
citra-emu.org, 1
|
citra-emu.org, 1
|
||||||
citrusui.me, 1
|
citrusui.me, 1
|
||||||
|
|
@ -5884,6 +5885,7 @@ colorblindprogramming.com, 1
|
||||||
colorbrush.ru, 1
|
colorbrush.ru, 1
|
||||||
colorcentertoner.com.br, 1
|
colorcentertoner.com.br, 1
|
||||||
colorcodedlyrics.com, 1
|
colorcodedlyrics.com, 1
|
||||||
|
colorectalcompounding.com, 1
|
||||||
coloringnotebook.com, 1
|
coloringnotebook.com, 1
|
||||||
coloristcafe.com, 1
|
coloristcafe.com, 1
|
||||||
colorsbycarin.com, 1
|
colorsbycarin.com, 1
|
||||||
|
|
@ -5909,6 +5911,7 @@ comeseetv.com, 1
|
||||||
comestoarra.com, 1
|
comestoarra.com, 1
|
||||||
cometbot.cf, 1
|
cometbot.cf, 1
|
||||||
cometcache.com, 1
|
cometcache.com, 1
|
||||||
|
cometonovascotia.ca, 1
|
||||||
comff.net, 1
|
comff.net, 1
|
||||||
comfintouch.com, 1
|
comfintouch.com, 1
|
||||||
comflores.com.br, 1
|
comflores.com.br, 1
|
||||||
|
|
@ -5936,7 +5939,6 @@ communitycodeofconduct.com, 1
|
||||||
communityflow.info, 1
|
communityflow.info, 1
|
||||||
communote.net, 1
|
communote.net, 1
|
||||||
comocurarlashemorroides.org, 1
|
comocurarlashemorroides.org, 1
|
||||||
comocurarlashemorroidesya.com, 1
|
|
||||||
comodesinflamarlashemorroides.org, 1
|
comodesinflamarlashemorroides.org, 1
|
||||||
comodo.nl, 1
|
comodo.nl, 1
|
||||||
comodormirmasrapido.com, 1
|
comodormirmasrapido.com, 1
|
||||||
|
|
@ -6242,6 +6244,7 @@ cousincouples.com, 1
|
||||||
covbounce.co.uk, 1
|
covbounce.co.uk, 1
|
||||||
cove.sh, 1
|
cove.sh, 1
|
||||||
covenantoftheriver.org, 1
|
covenantoftheriver.org, 1
|
||||||
|
coverdat.com, 1
|
||||||
covermytrip.com.au, 1
|
covermytrip.com.au, 1
|
||||||
covershousing.nl, 1
|
covershousing.nl, 1
|
||||||
covoiturage.fr, 0
|
covoiturage.fr, 0
|
||||||
|
|
@ -7378,6 +7381,7 @@ devdesco.com, 1
|
||||||
devdom.io, 1
|
devdom.io, 1
|
||||||
devdoodle.net, 1
|
devdoodle.net, 1
|
||||||
devel.cz, 1
|
devel.cz, 1
|
||||||
|
develop.cool, 1
|
||||||
developer.mydigipass.com, 0
|
developer.mydigipass.com, 0
|
||||||
developerfair.com, 1
|
developerfair.com, 1
|
||||||
developermail.io, 1
|
developermail.io, 1
|
||||||
|
|
@ -7411,7 +7415,6 @@ devops-survey.com, 1
|
||||||
devops.moe, 1
|
devops.moe, 1
|
||||||
devpgsv.com, 1
|
devpgsv.com, 1
|
||||||
devpsy.info, 1
|
devpsy.info, 1
|
||||||
devstaff.gr, 1
|
|
||||||
devyn.ca, 1
|
devyn.ca, 1
|
||||||
devzero.io, 1
|
devzero.io, 1
|
||||||
dewalch.net, 1
|
dewalch.net, 1
|
||||||
|
|
@ -8118,7 +8121,6 @@ drlazarina.net, 1
|
||||||
drms.us, 1
|
drms.us, 1
|
||||||
drobniuch.pl, 0
|
drobniuch.pl, 0
|
||||||
drogoz.moe, 1
|
drogoz.moe, 1
|
||||||
drogueriaelbarco.com, 1
|
|
||||||
droidapp.nl, 1
|
droidapp.nl, 1
|
||||||
droidgyan.com, 1
|
droidgyan.com, 1
|
||||||
droidhere.com, 1
|
droidhere.com, 1
|
||||||
|
|
@ -8199,11 +8201,11 @@ duelsow.eu, 1
|
||||||
duernberg.at, 1
|
duernberg.at, 1
|
||||||
duesee.org, 1
|
duesee.org, 1
|
||||||
dufrei.com, 1
|
dufrei.com, 1
|
||||||
dugnet.com, 1
|
dugnet.com, 0
|
||||||
dugnet.io, 1
|
dugnet.io, 0
|
||||||
dugnet.net, 1
|
dugnet.net, 0
|
||||||
dugnet.org, 1
|
dugnet.org, 0
|
||||||
dugnet.tech, 1
|
dugnet.tech, 0
|
||||||
dugunedavet.com, 1
|
dugunedavet.com, 1
|
||||||
duh.se, 1
|
duh.se, 1
|
||||||
duijf.info, 1
|
duijf.info, 1
|
||||||
|
|
@ -8226,7 +8228,6 @@ duncancmt.com, 1
|
||||||
duncanfamilytrust.org, 1
|
duncanfamilytrust.org, 1
|
||||||
duncanwinfrey.com, 1
|
duncanwinfrey.com, 1
|
||||||
dundalkdonnie.com, 1
|
dundalkdonnie.com, 1
|
||||||
dune.io, 1
|
|
||||||
dunea.nl, 1
|
dunea.nl, 1
|
||||||
dungeon-bbs.de, 1
|
dungeon-bbs.de, 1
|
||||||
dunmanelectric.com, 1
|
dunmanelectric.com, 1
|
||||||
|
|
@ -8504,7 +8505,6 @@ edited.de, 1
|
||||||
edition-bambou.com, 1
|
edition-bambou.com, 1
|
||||||
edition-sonblom.de, 1
|
edition-sonblom.de, 1
|
||||||
editoraacademiacrista.com.br, 1
|
editoraacademiacrista.com.br, 1
|
||||||
edlinus.cn, 1
|
|
||||||
edmundcelis.com, 1
|
edmundcelis.com, 1
|
||||||
edoss.co.za, 1
|
edoss.co.za, 1
|
||||||
edp-collaborative.com, 1
|
edp-collaborative.com, 1
|
||||||
|
|
@ -8798,7 +8798,6 @@ emailprivacytester.com, 1
|
||||||
emailtools.io, 1
|
emailtools.io, 1
|
||||||
emaily.eu, 1
|
emaily.eu, 1
|
||||||
emanuelduss.ch, 1
|
emanuelduss.ch, 1
|
||||||
emanuelemazzotta.com, 1
|
|
||||||
emavok.eu, 1
|
emavok.eu, 1
|
||||||
embassycargo.eu, 1
|
embassycargo.eu, 1
|
||||||
embellir-aroma.com, 1
|
embellir-aroma.com, 1
|
||||||
|
|
@ -8823,6 +8822,7 @@ emil.click, 1
|
||||||
emilong.com, 1
|
emilong.com, 1
|
||||||
emilstahl.dk, 1
|
emilstahl.dk, 1
|
||||||
emilvarga.com, 1
|
emilvarga.com, 1
|
||||||
|
emilyjohnson.ga, 1
|
||||||
emilyshepherd.me, 1
|
emilyshepherd.me, 1
|
||||||
eminhuseynov.com, 1
|
eminhuseynov.com, 1
|
||||||
emirabiz.com, 0
|
emirabiz.com, 0
|
||||||
|
|
@ -9018,7 +9018,7 @@ epitesz.co, 1
|
||||||
epizentrum.work, 1
|
epizentrum.work, 1
|
||||||
epizentrum.works, 1
|
epizentrum.works, 1
|
||||||
epmcentroitalia.it, 1
|
epmcentroitalia.it, 1
|
||||||
epoch.com, 0
|
epoch.com, 1
|
||||||
epolitiker.com, 1
|
epolitiker.com, 1
|
||||||
epos-distributor.co.uk, 1
|
epos-distributor.co.uk, 1
|
||||||
eposbirmingham.co.uk, 1
|
eposbirmingham.co.uk, 1
|
||||||
|
|
@ -9570,6 +9570,7 @@ fabled.com, 1
|
||||||
fableforge.nl, 1
|
fableforge.nl, 1
|
||||||
fabriceleroux.com, 1
|
fabriceleroux.com, 1
|
||||||
fabriziorocca.it, 1
|
fabriziorocca.it, 1
|
||||||
|
fabrysociety.org, 1
|
||||||
fabse.net, 1
|
fabse.net, 1
|
||||||
fabulouslyyouthfulskin.com, 1
|
fabulouslyyouthfulskin.com, 1
|
||||||
fabulouslyyouthfulskineyeserum.com, 1
|
fabulouslyyouthfulskineyeserum.com, 1
|
||||||
|
|
@ -9792,7 +9793,6 @@ feastr-dev.de, 1
|
||||||
feastr.de, 1
|
feastr.de, 1
|
||||||
feastr.io, 1
|
feastr.io, 1
|
||||||
featherweightlabs.com, 1
|
featherweightlabs.com, 1
|
||||||
featuredmen.com, 1
|
|
||||||
fecik.sk, 1
|
fecik.sk, 1
|
||||||
fed51.com, 1
|
fed51.com, 1
|
||||||
federalinvestments.gov, 1
|
federalinvestments.gov, 1
|
||||||
|
|
@ -10628,7 +10628,6 @@ front-end.dog, 1
|
||||||
fronteers.nl, 0
|
fronteers.nl, 0
|
||||||
frontline.cloud, 1
|
frontline.cloud, 1
|
||||||
frontline6.com, 1
|
frontline6.com, 1
|
||||||
fropky.com, 1
|
|
||||||
frostbytes.net, 1
|
frostbytes.net, 1
|
||||||
frostwarning.com, 1
|
frostwarning.com, 1
|
||||||
frosty-gaming.xyz, 1
|
frosty-gaming.xyz, 1
|
||||||
|
|
@ -10772,7 +10771,6 @@ furtivelook.com, 1
|
||||||
fusa-miyamoto.jp, 1
|
fusa-miyamoto.jp, 1
|
||||||
fuseos.net, 1
|
fuseos.net, 1
|
||||||
fushee.com, 1
|
fushee.com, 1
|
||||||
fuskator.com, 1
|
|
||||||
fussball-xxl.de, 1
|
fussball-xxl.de, 1
|
||||||
fussell.io, 1
|
fussell.io, 1
|
||||||
futbolvivo.tv, 1
|
futbolvivo.tv, 1
|
||||||
|
|
@ -11360,7 +11358,7 @@ gixtools.uk, 1
|
||||||
gizmo.ovh, 1
|
gizmo.ovh, 1
|
||||||
gj-bochum.de, 1
|
gj-bochum.de, 1
|
||||||
gjcampbell.co.uk, 1
|
gjcampbell.co.uk, 1
|
||||||
gjengset.com, 0
|
gjengset.com, 1
|
||||||
gjspunk.de, 0
|
gjspunk.de, 0
|
||||||
gjung.com, 0
|
gjung.com, 0
|
||||||
gkralik.eu, 1
|
gkralik.eu, 1
|
||||||
|
|
@ -11549,7 +11547,6 @@ gorod74.ru, 0
|
||||||
gorschenin.com, 1
|
gorschenin.com, 1
|
||||||
gosccs.com, 1
|
gosccs.com, 1
|
||||||
gosciencegirls.com, 1
|
gosciencegirls.com, 1
|
||||||
gosharewood.com, 1
|
|
||||||
goshawkdb.io, 1
|
goshawkdb.io, 1
|
||||||
goshin-group.co.jp, 1
|
goshin-group.co.jp, 1
|
||||||
gospelfollower.com, 1
|
gospelfollower.com, 1
|
||||||
|
|
@ -12070,6 +12067,7 @@ hanxv.pw, 1
|
||||||
hanys.xyz, 1
|
hanys.xyz, 1
|
||||||
hanzubon.jp, 1
|
hanzubon.jp, 1
|
||||||
hao-zhang.com, 1
|
hao-zhang.com, 1
|
||||||
|
haogoodair.ca, 1
|
||||||
haozhang.org, 1
|
haozhang.org, 1
|
||||||
hapijs.cn, 1
|
hapijs.cn, 1
|
||||||
hapissl.com, 1
|
hapissl.com, 1
|
||||||
|
|
@ -12148,6 +12146,7 @@ hashimah.ca, 1
|
||||||
hashinteractive.com, 1
|
hashinteractive.com, 1
|
||||||
hashish.net, 1
|
hashish.net, 1
|
||||||
hashiura.jp, 1
|
hashiura.jp, 1
|
||||||
|
hashnode.com, 1
|
||||||
hashplex.com, 1
|
hashplex.com, 1
|
||||||
hashru.nl, 1
|
hashru.nl, 1
|
||||||
hashworks.net, 1
|
hashworks.net, 1
|
||||||
|
|
@ -13394,7 +13393,7 @@ immobilien-badlippspringe.de, 1
|
||||||
immobilien-wallat.de, 1
|
immobilien-wallat.de, 1
|
||||||
immobilier-nice.fr, 1
|
immobilier-nice.fr, 1
|
||||||
immobilier92.net, 1
|
immobilier92.net, 1
|
||||||
immobiza.com, 1
|
immobiza.com, 0
|
||||||
immortal.run, 1
|
immortal.run, 1
|
||||||
immunicity.st, 1
|
immunicity.st, 1
|
||||||
imokuri123.com, 1
|
imokuri123.com, 1
|
||||||
|
|
@ -13752,7 +13751,6 @@ intraobes.com, 1
|
||||||
intrasoft.com.au, 1
|
intrasoft.com.au, 1
|
||||||
intraxia.com, 1
|
intraxia.com, 1
|
||||||
introvertedtravel.space, 1
|
introvertedtravel.space, 1
|
||||||
intune.life, 1
|
|
||||||
intux.be, 0
|
intux.be, 0
|
||||||
intvonline.com, 1
|
intvonline.com, 1
|
||||||
intxt.net, 1
|
intxt.net, 1
|
||||||
|
|
@ -13950,6 +13948,7 @@ ispweb.es, 1
|
||||||
isqrl.de, 1
|
isqrl.de, 1
|
||||||
israelbizreg.com, 1
|
israelbizreg.com, 1
|
||||||
israkurort.com, 1
|
israkurort.com, 1
|
||||||
|
isreedyintheuk.com, 1
|
||||||
issasfrissa.se, 1
|
issasfrissa.se, 1
|
||||||
issforum.org, 1
|
issforum.org, 1
|
||||||
issio.net, 1
|
issio.net, 1
|
||||||
|
|
@ -14440,6 +14439,7 @@ jevisite.ca, 1
|
||||||
jeweet.net, 1
|
jeweet.net, 1
|
||||||
jez.nl, 1
|
jez.nl, 1
|
||||||
jf-projects.de, 0
|
jf-projects.de, 0
|
||||||
|
jfnllc.com, 1
|
||||||
jfr.im, 1
|
jfr.im, 1
|
||||||
jfreitag.de, 1
|
jfreitag.de, 1
|
||||||
jgid.de, 1
|
jgid.de, 1
|
||||||
|
|
@ -15281,6 +15281,7 @@ kiapartscenter.net, 1
|
||||||
kiapartsdepartment.com, 1
|
kiapartsdepartment.com, 1
|
||||||
kiapps.ovh, 1
|
kiapps.ovh, 1
|
||||||
kibibit.net, 1
|
kibibit.net, 1
|
||||||
|
kibriscicek.net, 1
|
||||||
kick-in.nl, 1
|
kick-in.nl, 1
|
||||||
kickasscanadians.ca, 1
|
kickasscanadians.ca, 1
|
||||||
kickedmycat.com, 1
|
kickedmycat.com, 1
|
||||||
|
|
@ -15433,7 +15434,9 @@ kiwipayment.com, 1
|
||||||
kiwipayments.com, 1
|
kiwipayments.com, 1
|
||||||
kiwiplace.com, 1
|
kiwiplace.com, 1
|
||||||
kj-prince.com, 1
|
kj-prince.com, 1
|
||||||
|
kj1391.com, 1
|
||||||
kj1396.net, 1
|
kj1396.net, 1
|
||||||
|
kj1397.com, 1
|
||||||
kjaer.io, 1
|
kjaer.io, 1
|
||||||
kjarni.cc, 1
|
kjarni.cc, 1
|
||||||
kjarrval.is, 1
|
kjarrval.is, 1
|
||||||
|
|
@ -16105,6 +16108,7 @@ lattyware.com, 1
|
||||||
laubacher.io, 1
|
laubacher.io, 1
|
||||||
lauchundei.at, 1
|
lauchundei.at, 1
|
||||||
laufcampus.com, 1
|
laufcampus.com, 1
|
||||||
|
laufpix.de, 1
|
||||||
laufseminare-laufreisen.com, 1
|
laufseminare-laufreisen.com, 1
|
||||||
lauftrainer-ausbildung.com, 1
|
lauftrainer-ausbildung.com, 1
|
||||||
lauftreff-himmelgeist.de, 1
|
lauftreff-himmelgeist.de, 1
|
||||||
|
|
@ -16132,7 +16136,7 @@ lavenderx.org, 1
|
||||||
lavita.de, 1
|
lavita.de, 1
|
||||||
lavitrine-une-collection.be, 1
|
lavitrine-une-collection.be, 1
|
||||||
lavolte.net, 1
|
lavolte.net, 1
|
||||||
lavval.com, 1
|
lavval.com, 0
|
||||||
law-peters.de, 1
|
law-peters.de, 1
|
||||||
lawformt.com, 1
|
lawformt.com, 1
|
||||||
lawn-seeds.com, 1
|
lawn-seeds.com, 1
|
||||||
|
|
@ -16382,6 +16386,7 @@ lesyndicat.info, 1
|
||||||
let-go.cc, 1
|
let-go.cc, 1
|
||||||
letemps.ch, 1
|
letemps.ch, 1
|
||||||
leticiagomeztagle.com, 1
|
leticiagomeztagle.com, 1
|
||||||
|
letitfly.me, 1
|
||||||
lets-bounce.com, 1
|
lets-bounce.com, 1
|
||||||
lets-go-acoustic.de, 1
|
lets-go-acoustic.de, 1
|
||||||
lets-ktai.jp, 1
|
lets-ktai.jp, 1
|
||||||
|
|
@ -16727,6 +16732,7 @@ livepaperhelp.com, 1
|
||||||
liveperformersmeeting.net, 1
|
liveperformersmeeting.net, 1
|
||||||
liveregistratie.nl, 1
|
liveregistratie.nl, 1
|
||||||
livesure.com, 1
|
livesure.com, 1
|
||||||
|
livi.co, 1
|
||||||
living-space.co.nz, 1
|
living-space.co.nz, 1
|
||||||
living24.de, 1
|
living24.de, 1
|
||||||
livingforreal.com, 1
|
livingforreal.com, 1
|
||||||
|
|
@ -17006,7 +17012,6 @@ lu.search.yahoo.com, 0
|
||||||
luav.org, 1
|
luav.org, 1
|
||||||
lubar.me, 1
|
lubar.me, 1
|
||||||
lubbockyounglawyers.org, 1
|
lubbockyounglawyers.org, 1
|
||||||
lubomirkazakov.com, 1
|
|
||||||
lubot.net, 0
|
lubot.net, 0
|
||||||
luc-oberson.ch, 1
|
luc-oberson.ch, 1
|
||||||
luca.swiss, 1
|
luca.swiss, 1
|
||||||
|
|
@ -17703,7 +17708,6 @@ matrixmedia.ro, 1
|
||||||
matrixreq.com, 1
|
matrixreq.com, 1
|
||||||
matsu-semi.com, 1
|
matsu-semi.com, 1
|
||||||
mattandyana.com, 1
|
mattandyana.com, 1
|
||||||
mattberryman.com, 1
|
|
||||||
mattbsg.xyz, 1
|
mattbsg.xyz, 1
|
||||||
mattcarr.net, 0
|
mattcarr.net, 0
|
||||||
mattcoles.io, 1
|
mattcoles.io, 1
|
||||||
|
|
@ -17793,7 +17797,6 @@ mazda626.net, 1
|
||||||
maze.fr, 1
|
maze.fr, 1
|
||||||
mazternet.ru, 1
|
mazternet.ru, 1
|
||||||
mazurlabs.tk, 1
|
mazurlabs.tk, 1
|
||||||
mazzotta.me, 1
|
|
||||||
mb-is.info, 1
|
mb-is.info, 1
|
||||||
mbaestlein.de, 1
|
mbaestlein.de, 1
|
||||||
mbainflatables.co.uk, 1
|
mbainflatables.co.uk, 1
|
||||||
|
|
@ -17868,6 +17871,7 @@ mdcloudps.com, 1
|
||||||
mdek.at, 1
|
mdek.at, 1
|
||||||
mdewendt.de, 1
|
mdewendt.de, 1
|
||||||
mdf-bis.com, 1
|
mdf-bis.com, 1
|
||||||
|
mdkr.nl, 1
|
||||||
mdma.net, 1
|
mdma.net, 1
|
||||||
mdmed.clinic, 1
|
mdmed.clinic, 1
|
||||||
mdoering.de, 1
|
mdoering.de, 1
|
||||||
|
|
@ -18021,6 +18025,7 @@ melbourneapartments.website, 1
|
||||||
melchizedek-forum.de, 1
|
melchizedek-forum.de, 1
|
||||||
meldcode-assistent.nl, 1
|
meldcode-assistent.nl, 1
|
||||||
melearning.university, 0
|
melearning.university, 0
|
||||||
|
meledia.com, 1
|
||||||
melenchatsmelenchiens.fr, 1
|
melenchatsmelenchiens.fr, 1
|
||||||
melerpaine.com, 1
|
melerpaine.com, 1
|
||||||
melf.nl, 1
|
melf.nl, 1
|
||||||
|
|
@ -18285,6 +18290,7 @@ miguia.tv, 1
|
||||||
mihnea.net, 1
|
mihnea.net, 1
|
||||||
mijnkerstkaarten.be, 1
|
mijnkerstkaarten.be, 1
|
||||||
mijnreisoverzicht.nl, 1
|
mijnreisoverzicht.nl, 1
|
||||||
|
mijnstembureau.nl, 1
|
||||||
mijntransacties.nl, 1
|
mijntransacties.nl, 1
|
||||||
mika.cat, 1
|
mika.cat, 1
|
||||||
mika.moe, 1
|
mika.moe, 1
|
||||||
|
|
@ -18494,7 +18500,6 @@ mitzpettel.com, 1
|
||||||
miui-germany.de, 1
|
miui-germany.de, 1
|
||||||
miukimodafeminina.com, 1
|
miukimodafeminina.com, 1
|
||||||
mivzakim.net, 1
|
mivzakim.net, 1
|
||||||
miweb.cr, 1
|
|
||||||
mixnshake.com, 1
|
mixnshake.com, 1
|
||||||
mixposure.com, 1
|
mixposure.com, 1
|
||||||
mixtape.moe, 1
|
mixtape.moe, 1
|
||||||
|
|
@ -18882,7 +18887,7 @@ mplicka.cz, 1
|
||||||
mplusm.eu, 1
|
mplusm.eu, 1
|
||||||
mpn.poker, 1
|
mpn.poker, 1
|
||||||
mpnpokertour.com, 1
|
mpnpokertour.com, 1
|
||||||
mpreserver.com, 0
|
mpreserver.com, 1
|
||||||
mpserver12.org, 1
|
mpserver12.org, 1
|
||||||
mpsgarage.com.au, 1
|
mpsgarage.com.au, 1
|
||||||
mpsoundcraft.com, 1
|
mpsoundcraft.com, 1
|
||||||
|
|
@ -19918,7 +19923,6 @@ nickmorri.com, 1
|
||||||
nickrickard.co.uk, 1
|
nickrickard.co.uk, 1
|
||||||
nickstories.de, 1
|
nickstories.de, 1
|
||||||
niclasreich.de, 1
|
niclasreich.de, 1
|
||||||
nico.one, 1
|
|
||||||
nico.st, 1
|
nico.st, 1
|
||||||
nicocourts.com, 1
|
nicocourts.com, 1
|
||||||
nicoknibbe.nl, 1
|
nicoknibbe.nl, 1
|
||||||
|
|
@ -20128,6 +20132,7 @@ noop.ch, 1
|
||||||
noordsee.de, 1
|
noordsee.de, 1
|
||||||
noorsolidarity.com, 1
|
noorsolidarity.com, 1
|
||||||
nootropic.com, 1
|
nootropic.com, 1
|
||||||
|
nootropicsource.com, 1
|
||||||
nopaste.xyz, 1
|
nopaste.xyz, 1
|
||||||
nopaynocure.com, 1
|
nopaynocure.com, 1
|
||||||
nord-sud.be, 1
|
nord-sud.be, 1
|
||||||
|
|
@ -20341,7 +20346,7 @@ nwwc.dk, 1
|
||||||
nwwnetwork.net, 1
|
nwwnetwork.net, 1
|
||||||
nxinfo.ch, 1
|
nxinfo.ch, 1
|
||||||
nyan.it, 1
|
nyan.it, 1
|
||||||
nyanpasu.tv, 1
|
nyanpasu.tv, 0
|
||||||
nyantec.com, 1
|
nyantec.com, 1
|
||||||
nycoyote.org, 1
|
nycoyote.org, 1
|
||||||
nydnxs.com, 1
|
nydnxs.com, 1
|
||||||
|
|
@ -22208,6 +22213,7 @@ postdarwinian.com, 1
|
||||||
postdarwinism.com, 1
|
postdarwinism.com, 1
|
||||||
postdeck.de, 1
|
postdeck.de, 1
|
||||||
posteo.de, 0
|
posteo.de, 0
|
||||||
|
posterspy.com, 1
|
||||||
postfalls-naturopathic.com, 1
|
postfalls-naturopathic.com, 1
|
||||||
postfinance.ch, 1
|
postfinance.ch, 1
|
||||||
postmatescode.com, 1
|
postmatescode.com, 1
|
||||||
|
|
@ -22302,7 +22308,6 @@ preisser-it.de, 1
|
||||||
preisser.it, 1
|
preisser.it, 1
|
||||||
prekladysanca.cz, 1
|
prekladysanca.cz, 1
|
||||||
preloaded-hsts.badssl.com, 1
|
preloaded-hsts.badssl.com, 1
|
||||||
prelogica.com.br, 1
|
|
||||||
preludes.org, 1
|
preludes.org, 1
|
||||||
prelved.com, 1
|
prelved.com, 1
|
||||||
prelved.es, 1
|
prelved.es, 1
|
||||||
|
|
@ -22541,6 +22546,7 @@ proposalonline.com, 1
|
||||||
propr.no, 1
|
propr.no, 1
|
||||||
propseller.com, 1
|
propseller.com, 1
|
||||||
proslimdiets.com, 1
|
proslimdiets.com, 1
|
||||||
|
prosocialmachines.com, 1
|
||||||
prospanek.cz, 1
|
prospanek.cz, 1
|
||||||
prospo.co, 1
|
prospo.co, 1
|
||||||
prostohobby.ru, 1
|
prostohobby.ru, 1
|
||||||
|
|
@ -22563,7 +22569,7 @@ proust.ch, 0
|
||||||
proust.media, 0
|
proust.media, 0
|
||||||
proustmedia.de, 0
|
proustmedia.de, 0
|
||||||
provectus.de, 1
|
provectus.de, 1
|
||||||
proveits.me, 1
|
proveits.me, 0
|
||||||
provence-appartements.com, 1
|
provence-appartements.com, 1
|
||||||
provision-isr.nl, 1
|
provision-isr.nl, 1
|
||||||
provisionaldriving.com, 1
|
provisionaldriving.com, 1
|
||||||
|
|
@ -23427,7 +23433,6 @@ replicaswiss.nl, 1
|
||||||
report-incident.de, 1
|
report-incident.de, 1
|
||||||
report-to.io, 1
|
report-to.io, 1
|
||||||
report-uri.com, 1
|
report-uri.com, 1
|
||||||
report-uri.io, 1
|
|
||||||
report-url.com, 1
|
report-url.com, 1
|
||||||
report-url.io, 1
|
report-url.io, 1
|
||||||
reported.ly, 1
|
reported.ly, 1
|
||||||
|
|
@ -23932,6 +23937,7 @@ royalty-market.com, 1
|
||||||
royalvisiongroup.com, 1
|
royalvisiongroup.com, 1
|
||||||
royzez.com, 1
|
royzez.com, 1
|
||||||
rozalisbengal.ro, 1
|
rozalisbengal.ro, 1
|
||||||
|
rozalynne-dawn.ga, 1
|
||||||
rozhodce.cz, 1
|
rozhodce.cz, 1
|
||||||
rpadovani.com, 1
|
rpadovani.com, 1
|
||||||
rpasafrica.com, 1
|
rpasafrica.com, 1
|
||||||
|
|
@ -24184,6 +24190,7 @@ sahkotyot.eu, 1
|
||||||
said.id, 1
|
said.id, 1
|
||||||
said.my.id, 1
|
said.my.id, 1
|
||||||
saier.me, 1
|
saier.me, 1
|
||||||
|
saifoundation.in, 1
|
||||||
saigonflowers.com, 1
|
saigonflowers.com, 1
|
||||||
saigonstar.de, 1
|
saigonstar.de, 1
|
||||||
saikarra.com, 1
|
saikarra.com, 1
|
||||||
|
|
@ -25290,7 +25297,6 @@ sidium.de, 1
|
||||||
sidnicio.us, 1
|
sidnicio.us, 1
|
||||||
sidonge.com, 1
|
sidonge.com, 1
|
||||||
sidongkim.com, 1
|
sidongkim.com, 1
|
||||||
sidpod.ru, 1
|
|
||||||
siebeve.be, 1
|
siebeve.be, 1
|
||||||
siegemund-frankfurt.de, 1
|
siegemund-frankfurt.de, 1
|
||||||
sieh.es, 1
|
sieh.es, 1
|
||||||
|
|
@ -25407,6 +25413,7 @@ sim-karten.net, 1
|
||||||
sim-sim.appspot.com, 1
|
sim-sim.appspot.com, 1
|
||||||
sim4seed.org, 1
|
sim4seed.org, 1
|
||||||
simam.de, 1
|
simam.de, 1
|
||||||
|
simbeton.nl, 1
|
||||||
simbolo.co.uk, 0
|
simbolo.co.uk, 0
|
||||||
simeonoff.ninja, 1
|
simeonoff.ninja, 1
|
||||||
simetal.ch, 1
|
simetal.ch, 1
|
||||||
|
|
@ -26280,7 +26287,6 @@ srbija-nekretnine.org, 1
|
||||||
src.fedoraproject.org, 1
|
src.fedoraproject.org, 1
|
||||||
srchub.org, 1
|
srchub.org, 1
|
||||||
srinivasan.io, 1
|
srinivasan.io, 1
|
||||||
sritest.io, 1
|
|
||||||
sro.center, 1
|
sro.center, 1
|
||||||
srolim.com, 1
|
srolim.com, 1
|
||||||
srrdb.com, 1
|
srrdb.com, 1
|
||||||
|
|
@ -26470,7 +26476,7 @@ steenackers.be, 1
|
||||||
stefan-bayer.eu, 1
|
stefan-bayer.eu, 1
|
||||||
stefan-schlueter.de, 1
|
stefan-schlueter.de, 1
|
||||||
stefanbayer.de, 1
|
stefanbayer.de, 1
|
||||||
stefanovski.io, 0
|
stefanovski.io, 1
|
||||||
stefany.eu, 1
|
stefany.eu, 1
|
||||||
steffi-in-australien.com, 1
|
steffi-in-australien.com, 1
|
||||||
steidlewirt.de, 1
|
steidlewirt.de, 1
|
||||||
|
|
@ -26545,7 +26551,6 @@ stevenz.xyz, 1
|
||||||
stevesdrivingschooltyneside.com, 1
|
stevesdrivingschooltyneside.com, 1
|
||||||
stewartswines.com, 1
|
stewartswines.com, 1
|
||||||
stewonet.nl, 1
|
stewonet.nl, 1
|
||||||
steyaert.be, 1
|
|
||||||
stfw.info, 1
|
stfw.info, 1
|
||||||
stichtingliab.nl, 1
|
stichtingliab.nl, 1
|
||||||
stichtingscholierenvervoerzeeland.nl, 1
|
stichtingscholierenvervoerzeeland.nl, 1
|
||||||
|
|
@ -26606,6 +26611,7 @@ stonemanbrasil.com.br, 1
|
||||||
stony.com, 1
|
stony.com, 1
|
||||||
stonystratford.org, 1
|
stonystratford.org, 1
|
||||||
stopakwardhandshakes.org, 1
|
stopakwardhandshakes.org, 1
|
||||||
|
stopbreakupnow.org, 1
|
||||||
stopbullying.gov, 1
|
stopbullying.gov, 1
|
||||||
stopfraud.gov, 1
|
stopfraud.gov, 1
|
||||||
stopthethyroidmadness.com, 1
|
stopthethyroidmadness.com, 1
|
||||||
|
|
@ -26644,7 +26650,6 @@ streamchan.org, 1
|
||||||
streamdesk.ca, 1
|
streamdesk.ca, 1
|
||||||
streamer.tips, 1
|
streamer.tips, 1
|
||||||
streamlineautogroup.com, 1
|
streamlineautogroup.com, 1
|
||||||
streampanel.net, 1
|
|
||||||
streams.dyndns.org, 1
|
streams.dyndns.org, 1
|
||||||
streamthemeeting.com, 1
|
streamthemeeting.com, 1
|
||||||
streamzilla.com, 1
|
streamzilla.com, 1
|
||||||
|
|
@ -28017,6 +28022,7 @@ tik.help, 1
|
||||||
tiki-god.co.uk, 1
|
tiki-god.co.uk, 1
|
||||||
tiledailyshop.com, 1
|
tiledailyshop.com, 1
|
||||||
tileyourvisit.pt, 1
|
tileyourvisit.pt, 1
|
||||||
|
tiliaze.biz, 1
|
||||||
tiliaze.info, 1
|
tiliaze.info, 1
|
||||||
tiliaze.net, 1
|
tiliaze.net, 1
|
||||||
till.im, 1
|
till.im, 1
|
||||||
|
|
@ -28053,8 +28059,10 @@ timroes.de, 1
|
||||||
timstoffel.net, 0
|
timstoffel.net, 0
|
||||||
timtaubert.de, 1
|
timtaubert.de, 1
|
||||||
timtelfer.com, 1
|
timtelfer.com, 1
|
||||||
|
timtj.ca, 1
|
||||||
timvandekamp.nl, 1
|
timvandekamp.nl, 1
|
||||||
timvivian.ca, 1
|
timvivian.ca, 1
|
||||||
|
timweb.ca, 1
|
||||||
timysewyn.be, 1
|
timysewyn.be, 1
|
||||||
tinastahlschmidt.de, 1
|
tinastahlschmidt.de, 1
|
||||||
tinf15b4.de, 1
|
tinf15b4.de, 1
|
||||||
|
|
@ -28443,6 +28451,7 @@ towaway.ru, 1
|
||||||
townandcountryus.com, 1
|
townandcountryus.com, 1
|
||||||
townhousedevelopments.com.au, 1
|
townhousedevelopments.com.au, 1
|
||||||
townhouseregister.com.au, 1
|
townhouseregister.com.au, 1
|
||||||
|
townofbridgewater.ca, 1
|
||||||
towywebdesigns.uk, 1
|
towywebdesigns.uk, 1
|
||||||
tox.im, 1
|
tox.im, 1
|
||||||
toxicip.com, 1
|
toxicip.com, 1
|
||||||
|
|
@ -28483,7 +28492,6 @@ trackdays4fun.com, 1
|
||||||
trackdomains.com, 1
|
trackdomains.com, 1
|
||||||
trackersimulator.org, 1
|
trackersimulator.org, 1
|
||||||
trackeye.dk, 1
|
trackeye.dk, 1
|
||||||
trackmeet.io, 1
|
|
||||||
trackrecordpro.co.uk, 1
|
trackrecordpro.co.uk, 1
|
||||||
tractorpumps.com, 1
|
tractorpumps.com, 1
|
||||||
trade.gov.uk, 1
|
trade.gov.uk, 1
|
||||||
|
|
@ -29221,6 +29229,7 @@ urbanietz-immobilien.de, 1
|
||||||
urbanmelbourne.info, 1
|
urbanmelbourne.info, 1
|
||||||
urbannewsservice.com, 1
|
urbannewsservice.com, 1
|
||||||
urbansparrow.in, 1
|
urbansparrow.in, 1
|
||||||
|
urbanstylestaging.com, 1
|
||||||
urbanwildlifealliance.org, 1
|
urbanwildlifealliance.org, 1
|
||||||
urbexdk.nl, 1
|
urbexdk.nl, 1
|
||||||
urcentral.com, 1
|
urcentral.com, 1
|
||||||
|
|
@ -29511,7 +29520,6 @@ vendigital.com, 1
|
||||||
vendorconnect.nyc, 1
|
vendorconnect.nyc, 1
|
||||||
venicerealdeal.com, 1
|
venicerealdeal.com, 1
|
||||||
venmos.com, 1
|
venmos.com, 1
|
||||||
venoom.eu, 1
|
|
||||||
ventesprivees-fr.com, 1
|
ventesprivees-fr.com, 1
|
||||||
ventizo.com, 1
|
ventizo.com, 1
|
||||||
venturavwparts.com, 1
|
venturavwparts.com, 1
|
||||||
|
|
@ -29976,7 +29984,7 @@ wadvisor.com, 1
|
||||||
waelisch.de, 1
|
waelisch.de, 1
|
||||||
waelti.xxx, 1
|
waelti.xxx, 1
|
||||||
wafa4hw.com, 1
|
wafa4hw.com, 1
|
||||||
wafairhaven.com.au, 0
|
wafairhaven.com.au, 1
|
||||||
waffle.at, 1
|
waffle.at, 1
|
||||||
wafni.com, 1
|
wafni.com, 1
|
||||||
wahhoi.net, 0
|
wahhoi.net, 0
|
||||||
|
|
@ -30080,6 +30088,7 @@ watermonitor.gov, 1
|
||||||
watersb.org, 1
|
watersb.org, 1
|
||||||
watertrails.io, 1
|
watertrails.io, 1
|
||||||
watsonwork.me, 1
|
watsonwork.me, 1
|
||||||
|
wattechweb.com, 1
|
||||||
wave-ola.es, 1
|
wave-ola.es, 1
|
||||||
wavesboardshop.com, 1
|
wavesboardshop.com, 1
|
||||||
wavesoftime.com, 1
|
wavesoftime.com, 1
|
||||||
|
|
@ -30909,6 +30918,7 @@ wubify.com, 1
|
||||||
wuchipc.com, 1
|
wuchipc.com, 1
|
||||||
wuerfel.wf, 1
|
wuerfel.wf, 1
|
||||||
wuerfelmail.de, 1
|
wuerfelmail.de, 1
|
||||||
|
wufu.org, 0
|
||||||
wug.jp, 1
|
wug.jp, 1
|
||||||
wug.news, 1
|
wug.news, 1
|
||||||
wuji.cz, 1
|
wuji.cz, 1
|
||||||
|
|
@ -30998,7 +31008,6 @@ www.theguardian.com, 1
|
||||||
www.therapynotes.com, 1
|
www.therapynotes.com, 1
|
||||||
www.tinfoilsecurity.com, 0
|
www.tinfoilsecurity.com, 0
|
||||||
www.torproject.org, 0
|
www.torproject.org, 0
|
||||||
www.tumblr.com, 0
|
|
||||||
www.twitter.com, 0
|
www.twitter.com, 0
|
||||||
www.united.com, 1
|
www.united.com, 1
|
||||||
www.usaa.com, 0
|
www.usaa.com, 0
|
||||||
|
|
@ -31653,9 +31662,9 @@ zabszk.net, 1
|
||||||
zacarias.com.ar, 1
|
zacarias.com.ar, 1
|
||||||
zacavi.com.br, 1
|
zacavi.com.br, 1
|
||||||
zach.codes, 1
|
zach.codes, 1
|
||||||
zacharopoulos.eu, 1
|
zacharopoulos.eu, 0
|
||||||
zacharopoulos.me, 1
|
zacharopoulos.me, 0
|
||||||
zacharopoulos.org, 1
|
zacharopoulos.org, 0
|
||||||
zachborboa.com, 1
|
zachborboa.com, 1
|
||||||
zachgibbens.org, 1
|
zachgibbens.org, 1
|
||||||
zachpeters.org, 1
|
zachpeters.org, 1
|
||||||
|
|
@ -31709,7 +31718,6 @@ zdbl.de, 1
|
||||||
zdenekspacek.cz, 1
|
zdenekspacek.cz, 1
|
||||||
zdorovayasimya.com, 1
|
zdorovayasimya.com, 1
|
||||||
zdrojak.cz, 1
|
zdrojak.cz, 1
|
||||||
zdx.ch, 1
|
|
||||||
ze3kr.com, 1
|
ze3kr.com, 1
|
||||||
zebbra.ro, 1
|
zebbra.ro, 1
|
||||||
zebedeescastles.co.uk, 1
|
zebedeescastles.co.uk, 1
|
||||||
|
|
@ -31925,7 +31933,6 @@ zuppy.pm, 1
|
||||||
zuralski.net, 1
|
zuralski.net, 1
|
||||||
zurgl.com, 1
|
zurgl.com, 1
|
||||||
zurickrelogios.com.br, 1
|
zurickrelogios.com.br, 1
|
||||||
zurret.de, 1
|
|
||||||
zusjesvandenbos.nl, 1
|
zusjesvandenbos.nl, 1
|
||||||
zutsu-raku.com, 1
|
zutsu-raku.com, 1
|
||||||
zuviel.space, 1
|
zuviel.space, 1
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use cssparser::ToCss;
|
use cssparser::ToCss;
|
||||||
use parser::SelectorImpl;
|
use parser::SelectorImpl;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq)]
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ use precomputed_hash::PrecomputedHash;
|
||||||
use servo_arc::ThinArc;
|
use servo_arc::ThinArc;
|
||||||
use sink::Push;
|
use sink::Push;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::borrow::{Borrow, Cow};
|
use std::borrow::{Borrow, Cow};
|
||||||
use std::fmt::{self, Display, Debug, Write};
|
use std::fmt::{self, Display, Debug, Write};
|
||||||
use std::iter::Rev;
|
use std::iter::Rev;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use selectors::attr::AttrSelectorOperation;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use shared_lock::Locked;
|
use shared_lock::Locked;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use str::{HTML_SPACE_CHARACTERS, read_exponent, read_fraction};
|
use str::{HTML_SPACE_CHARACTERS, read_exponent, read_fraction};
|
||||||
use str::{read_numbers, split_commas, split_html_space_chars};
|
use str::{read_numbers, split_commas, split_html_space_chars};
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||||
use parser::{ParserContext, ParserErrorContext, Parse};
|
use parser::{ParserContext, ParserErrorContext, Parse};
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ use selector_map::{PrecomputedHashSet, PrecomputedHashMap};
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::borrow::{Borrow, Cow};
|
use std::borrow::{Borrow, Cow};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
|
||||||
|
|
@ -466,20 +466,6 @@ impl ElementData {
|
||||||
self.is_restyle() || !self.hint.is_empty() || !self.damage.is_empty()
|
self.is_restyle() || !self.hint.is_empty() || !self.damage.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If an ancestor is already getting reconstructed by Gecko's top-down
|
|
||||||
/// frame constructor, no need to apply damage. Similarly if we already
|
|
||||||
/// have an explicitly stored ReconstructFrame hint.
|
|
||||||
///
|
|
||||||
/// See https://bugzilla.mozilla.org/show_bug.cgi?id=1301258#c12
|
|
||||||
/// for followup work to make the optimization here more optimal by considering
|
|
||||||
/// each bit individually.
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
pub fn skip_applying_damage(&self) -> bool { self.reconstructed_self_or_ancestor() }
|
|
||||||
|
|
||||||
/// N/A in Servo.
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
pub fn skip_applying_damage(&self) -> bool { false }
|
|
||||||
|
|
||||||
/// Returns whether it is safe to perform cousin sharing based on the ComputedValues
|
/// Returns whether it is safe to perform cousin sharing based on the ComputedValues
|
||||||
/// identity of the primary style in this ElementData. There are a few subtle things
|
/// identity of the primary style in this ElementData. There are a few subtle things
|
||||||
/// to check.
|
/// to check.
|
||||||
|
|
|
||||||
|
|
@ -1377,7 +1377,7 @@ impl PseudoElement {
|
||||||
/// Returns `None` if the pseudo-element is not recognised.
|
/// Returns `None` if the pseudo-element is not recognised.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(s: &str, in_ua_stylesheet: bool) -> Option<Self> {
|
pub fn from_slice(s: &str, in_ua_stylesheet: bool) -> Option<Self> {
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
|
|
||||||
// We don't need to support tree pseudos because functional
|
// We don't need to support tree pseudos because functional
|
||||||
// pseudo-elements needs arguments, and thus should be created
|
// pseudo-elements needs arguments, and thus should be created
|
||||||
|
|
@ -1747,7 +1747,7 @@ impl PseudoElement {
|
||||||
/// Returns `None` if the pseudo-element is not recognized.
|
/// Returns `None` if the pseudo-element is not recognized.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tree_pseudo_element(name: &str, args: Box<[Atom]>) -> Option<Self> {
|
pub fn tree_pseudo_element(name: &str, args: Box<[Atom]>) -> Option<Self> {
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
debug_assert!(name.starts_with("-moz-tree-"));
|
debug_assert!(name.starts_with("-moz-tree-"));
|
||||||
let tree_part = &name[10..];
|
let tree_part = &name[10..];
|
||||||
if tree_part.eq_ignore_ascii_case("column") {
|
if tree_part.eq_ignore_ascii_case("column") {
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ impl PseudoElement {
|
||||||
/// Returns `None` if the pseudo-element is not recognised.
|
/// Returns `None` if the pseudo-element is not recognised.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(s: &str, in_ua_stylesheet: bool) -> Option<Self> {
|
pub fn from_slice(s: &str, in_ua_stylesheet: bool) -> Option<Self> {
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
|
|
||||||
// We don't need to support tree pseudos because functional
|
// We don't need to support tree pseudos because functional
|
||||||
// pseudo-elements needs arguments, and thus should be created
|
// pseudo-elements needs arguments, and thus should be created
|
||||||
|
|
@ -247,7 +247,7 @@ impl PseudoElement {
|
||||||
/// Returns `None` if the pseudo-element is not recognized.
|
/// Returns `None` if the pseudo-element is not recognized.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tree_pseudo_element(name: &str, args: Box<[Atom]>) -> Option<Self> {
|
pub fn tree_pseudo_element(name: &str, args: Box<[Atom]>) -> Option<Self> {
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
debug_assert!(name.starts_with("-moz-tree-"));
|
debug_assert!(name.starts_with("-moz-tree-"));
|
||||||
let tree_part = &name[10..];
|
let tree_part = &name[10..];
|
||||||
% for pseudo in TREE_PSEUDOS:
|
% for pseudo in TREE_PSEUDOS:
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use gecko_bindings::bindings::Gecko_ReleaseAtom;
|
||||||
use gecko_bindings::structs::{nsAtom, nsAtom_AtomKind, nsStaticAtom};
|
use gecko_bindings::structs::{nsAtom, nsAtom_AtomKind, nsStaticAtom};
|
||||||
use nsstring::{nsAString, nsStr};
|
use nsstring::{nsAString, nsStr};
|
||||||
use precomputed_hash::PrecomputedHash;
|
use precomputed_hash::PrecomputedHash;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::borrow::{Cow, Borrow};
|
use std::borrow::{Cow, Borrow};
|
||||||
use std::char::{self, DecodeUtf16};
|
use std::char::{self, DecodeUtf16};
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,6 @@ trait PrivateMatchMethods: TElement {
|
||||||
fn accumulate_damage_for(
|
fn accumulate_damage_for(
|
||||||
&self,
|
&self,
|
||||||
shared_context: &SharedStyleContext,
|
shared_context: &SharedStyleContext,
|
||||||
skip_applying_damage: bool,
|
|
||||||
damage: &mut RestyleDamage,
|
damage: &mut RestyleDamage,
|
||||||
old_values: &ComputedValues,
|
old_values: &ComputedValues,
|
||||||
new_values: &ComputedValues,
|
new_values: &ComputedValues,
|
||||||
|
|
@ -345,9 +344,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
let difference =
|
let difference =
|
||||||
self.compute_style_difference(old_values, new_values, pseudo);
|
self.compute_style_difference(old_values, new_values, pseudo);
|
||||||
|
|
||||||
if !skip_applying_damage {
|
*damage |= difference.damage;
|
||||||
*damage |= difference.damage;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!(" > style difference: {:?}", difference);
|
debug!(" > style difference: {:?}", difference);
|
||||||
|
|
||||||
|
|
@ -590,7 +587,6 @@ pub trait MatchMethods : TElement {
|
||||||
cascade_requirement,
|
cascade_requirement,
|
||||||
self.accumulate_damage_for(
|
self.accumulate_damage_for(
|
||||||
context.shared,
|
context.shared,
|
||||||
data.skip_applying_damage(),
|
|
||||||
&mut data.damage,
|
&mut data.damage,
|
||||||
&old_primary_style,
|
&old_primary_style,
|
||||||
new_primary_style,
|
new_primary_style,
|
||||||
|
|
@ -612,7 +608,6 @@ pub trait MatchMethods : TElement {
|
||||||
(&Some(ref old), &Some(ref new)) => {
|
(&Some(ref old), &Some(ref new)) => {
|
||||||
self.accumulate_damage_for(
|
self.accumulate_damage_for(
|
||||||
context.shared,
|
context.shared,
|
||||||
data.skip_applying_damage(),
|
|
||||||
&mut data.damage,
|
&mut data.damage,
|
||||||
old,
|
old,
|
||||||
new,
|
new,
|
||||||
|
|
|
||||||
|
|
@ -1577,7 +1577,7 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control-
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, _context: &Context) -> computed_value::T {
|
fn to_computed_value(&self, _context: &Context) -> computed_value::T {
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
match *self {
|
match *self {
|
||||||
SpecifiedValue::Normal => computed_value::T(0),
|
SpecifiedValue::Normal => computed_value::T(0),
|
||||||
SpecifiedValue::Override(ref lang) => {
|
SpecifiedValue::Override(ref lang) => {
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@
|
||||||
impl Parse for computed_value::Keyword {
|
impl Parse for computed_value::Keyword {
|
||||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
-> Result<computed_value::Keyword, ParseError<'i>> {
|
-> Result<computed_value::Keyword, ParseError<'i>> {
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use style_traits::cursor::Cursor;
|
use style_traits::cursor::Cursor;
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
let ident = input.expect_ident()?;
|
let ident = input.expect_ident()?;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use num_traits::ToPrimitive;
|
use num_traits::ToPrimitive;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::convert::AsRef;
|
use std::convert::AsRef;
|
||||||
use std::iter::{Filter, Peekable};
|
use std::iter::{Filter, Peekable};
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use properties::StyleBuilder;
|
||||||
use rule_cache::RuleCacheConditions;
|
use rule_cache::RuleCacheConditions;
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard};
|
use shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard};
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use Atom;
|
||||||
pub use cssparser::{RGBA, Token, Parser, serialize_identifier, CowRcStr, SourceLocation};
|
pub use cssparser::{RGBA, Token, Parser, serialize_identifier, CowRcStr, SourceLocation};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
use std::hash;
|
use std::hash;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use cssparser::Parser;
|
||||||
use gecko_bindings::structs;
|
use gecko_bindings::structs;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use parser::{ParserContext, Parse};
|
use parser::{ParserContext, Parse};
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError};
|
use style_traits::{ToCss, ParseError};
|
||||||
use values::CSSFloat;
|
use values::CSSFloat;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
use style_traits::values::specified::AllowedNumericType;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use cssparser::{Parser, Token, ParseError as CssParseError};
|
use cssparser::{Parser, Token, ParseError as CssParseError};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use style_traits::{ParseError, StyleParseErrorKind};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
use values::{CSSFloat, CustomIdent};
|
use values::{CSSFloat, CustomIdent};
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use euclid::Size2D;
|
||||||
use font_metrics::FontMetricsQueryResult;
|
use font_metrics::FontMetricsQueryResult;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::{cmp, fmt, mem};
|
use std::{cmp, fmt, mem};
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::ops::{Add, Mul};
|
use std::ops::{Add, Mul};
|
||||||
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
use style_traits::values::specified::AllowedNumericType;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use context::QuirksMode;
|
||||||
use cssparser::{Parser, Token, serialize_identifier};
|
use cssparser::{Parser, Token, serialize_identifier};
|
||||||
use parser::{ParserContext, Parse};
|
use parser::{ParserContext, Parse};
|
||||||
use self::url::SpecifiedUrl;
|
use self::url::SpecifiedUrl;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::f32;
|
use std::f32;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ParseError, ToCss};
|
use style_traits::{ParseError, ToCss};
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
use style_traits::values::specified::AllowedNumericType;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use style_traits::ParseError;
|
use style_traits::ParseError;
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
use values::computed::text::LineHeight as ComputedLineHeight;
|
use values::computed::text::LineHeight as ComputedLineHeight;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use parser::{ParserContext, Parse};
|
use parser::{ParserContext, Parse};
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
use style_traits::values::specified::AllowedNumericType;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
use {CSSPixel, PinchZoomFactor, ParseError, ToCss};
|
use {CSSPixel, PinchZoomFactor, ParseError, ToCss};
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use euclid::TypedSize2D;
|
use euclid::TypedSize2D;
|
||||||
use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
define_css_keyword_enum!(UserZoom:
|
define_css_keyword_enum!(UserZoom:
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,6 @@ class MachCommands(CommandBase):
|
||||||
shutil.copy(path.join(self.android_support_dir(), "openssl.sh"), openssl_dir)
|
shutil.copy(path.join(self.android_support_dir(), "openssl.sh"), openssl_dir)
|
||||||
|
|
||||||
# Check if the NDK version is 12
|
# Check if the NDK version is 12
|
||||||
env["ANDROID_NDK_ROOT"] = env["ANDROID_NDK"]
|
|
||||||
with open(path.join(env["ANDROID_NDK"], 'source.properties')) as ndk_properties:
|
with open(path.join(env["ANDROID_NDK"], 'source.properties')) as ndk_properties:
|
||||||
lines = ndk_properties.readlines()
|
lines = ndk_properties.readlines()
|
||||||
if lines[1].split(' = ')[1].split('.')[0] != '12':
|
if lines[1].split(' = ')[1].split('.')[0] != '12':
|
||||||
|
|
|
||||||
|
|
@ -231,26 +231,6 @@ Service::getSingleton()
|
||||||
return service.forget();
|
return service.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIXPConnect *Service::sXPConnect = nullptr;
|
|
||||||
|
|
||||||
// static
|
|
||||||
already_AddRefed<nsIXPConnect>
|
|
||||||
Service::getXPConnect()
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(NS_IsMainThread(),
|
|
||||||
"Must only get XPConnect on the main thread!");
|
|
||||||
NS_PRECONDITION(gService,
|
|
||||||
"Can not get XPConnect without an instance of our service!");
|
|
||||||
|
|
||||||
// If we've been shutdown, sXPConnect will be null. To prevent leaks, we do
|
|
||||||
// not cache the service after this point.
|
|
||||||
nsCOMPtr<nsIXPConnect> xpc(sXPConnect);
|
|
||||||
if (!xpc)
|
|
||||||
xpc = do_GetService(nsIXPConnect::GetCID());
|
|
||||||
NS_ASSERTION(xpc, "Could not get XPConnect!");
|
|
||||||
return xpc.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t Service::sSynchronousPref;
|
int32_t Service::sSynchronousPref;
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
@ -279,8 +259,6 @@ Service::~Service()
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_OK)
|
||||||
NS_WARNING("Failed to unregister sqlite vfs wrapper.");
|
NS_WARNING("Failed to unregister sqlite vfs wrapper.");
|
||||||
|
|
||||||
shutdown(); // To release sXPConnect.
|
|
||||||
|
|
||||||
gService = nullptr;
|
gService = nullptr;
|
||||||
delete mSqliteVFS;
|
delete mSqliteVFS;
|
||||||
mSqliteVFS = nullptr;
|
mSqliteVFS = nullptr;
|
||||||
|
|
@ -395,18 +373,11 @@ Service::minimizeMemory()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Service::shutdown()
|
|
||||||
{
|
|
||||||
NS_IF_RELEASE(sXPConnect);
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_vfs *ConstructTelemetryVFS();
|
sqlite3_vfs *ConstructTelemetryVFS();
|
||||||
const char *GetVFSName();
|
const char *GetVFSName();
|
||||||
|
|
||||||
static const char* sObserverTopics[] = {
|
static const char* sObserverTopics[] = {
|
||||||
"memory-pressure",
|
"memory-pressure",
|
||||||
"xpcom-shutdown",
|
|
||||||
"xpcom-shutdown-threads"
|
"xpcom-shutdown-threads"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -428,8 +399,6 @@ Service::initialize()
|
||||||
NS_WARNING("Failed to register telemetry VFS");
|
NS_WARNING("Failed to register telemetry VFS");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register for xpcom-shutdown so we can cleanup after ourselves. The
|
|
||||||
// observer service can only be used on the main thread.
|
|
||||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||||
NS_ENSURE_TRUE(os, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(os, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
|
@ -440,10 +409,6 @@ Service::initialize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We cache XPConnect for our language helpers. XPConnect can only be
|
|
||||||
// used on the main thread.
|
|
||||||
(void)CallGetService(nsIXPConnect::GetCID(), &sXPConnect);
|
|
||||||
|
|
||||||
// We need to obtain the toolkit.storage.synchronous preferences on the main
|
// We need to obtain the toolkit.storage.synchronous preferences on the main
|
||||||
// thread because the preference service can only be accessed there. This
|
// thread because the preference service can only be accessed there. This
|
||||||
// is cached in the service for all future Open[Unshared]Database calls.
|
// is cached in the service for all future Open[Unshared]Database calls.
|
||||||
|
|
@ -804,8 +769,6 @@ Service::Observe(nsISupports *, const char *aTopic, const char16_t *)
|
||||||
{
|
{
|
||||||
if (strcmp(aTopic, "memory-pressure") == 0) {
|
if (strcmp(aTopic, "memory-pressure") == 0) {
|
||||||
minimizeMemory();
|
minimizeMemory();
|
||||||
} else if (strcmp(aTopic, "xpcom-shutdown") == 0) {
|
|
||||||
shutdown();
|
|
||||||
} else if (strcmp(aTopic, "xpcom-shutdown-threads") == 0) {
|
} else if (strcmp(aTopic, "xpcom-shutdown-threads") == 0) {
|
||||||
// The Service is kept alive by our strong observer references and
|
// The Service is kept alive by our strong observer references and
|
||||||
// references held by Connection instances. Since we're about to remove the
|
// references held by Connection instances. Since we're about to remove the
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
#include "mozIStorageService.h"
|
#include "mozIStorageService.h"
|
||||||
|
|
||||||
class nsIMemoryReporter;
|
class nsIMemoryReporter;
|
||||||
class nsIXPConnect;
|
|
||||||
struct sqlite3_vfs;
|
struct sqlite3_vfs;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
@ -59,12 +58,6 @@ public:
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
NS_DECL_NSIMEMORYREPORTER
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtains an already AddRefed pointer to XPConnect. This is used by
|
|
||||||
* language helpers.
|
|
||||||
*/
|
|
||||||
static already_AddRefed<nsIXPConnect> getXPConnect();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the cached data for the toolkit.storage.synchronous preference.
|
* Obtains the cached data for the toolkit.storage.synchronous preference.
|
||||||
*/
|
*/
|
||||||
|
|
@ -156,11 +149,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void minimizeMemory();
|
void minimizeMemory();
|
||||||
|
|
||||||
/**
|
|
||||||
* Shuts down the storage service, freeing all of the acquired resources.
|
|
||||||
*/
|
|
||||||
void shutdown();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazily creates and returns a collation created from the application's
|
* Lazily creates and returns a collation created from the application's
|
||||||
* locale that all statements of all Connections of this Service may use.
|
* locale that all statements of all Connections of this Service may use.
|
||||||
|
|
@ -185,8 +173,6 @@ private:
|
||||||
|
|
||||||
static Service *gService;
|
static Service *gService;
|
||||||
|
|
||||||
static nsIXPConnect *sXPConnect;
|
|
||||||
|
|
||||||
static int32_t sSynchronousPref;
|
static int32_t sSynchronousPref;
|
||||||
static int32_t sDefaultPageSize;
|
static int32_t sDefaultPageSize;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include "xpc_make_class.h"
|
#include "xpc_make_class.h"
|
||||||
|
|
||||||
|
#include "mozilla/Services.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace storage {
|
namespace storage {
|
||||||
|
|
||||||
|
|
@ -33,7 +35,7 @@ stepFunc(JSContext *aCtx,
|
||||||
uint32_t,
|
uint32_t,
|
||||||
JS::Value *_vp)
|
JS::Value *_vp)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIXPConnect> xpc(Service::getXPConnect());
|
nsCOMPtr<nsIXPConnect> xpc(mozilla::services::GetXPConnect());
|
||||||
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
||||||
JSObject *obj = JS_THIS_OBJECT(aCtx, _vp);
|
JSObject *obj = JS_THIS_OBJECT(aCtx, _vp);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
|
|
|
||||||
|
|
@ -384307,6 +384307,12 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"webdriver/tests/actions/key_shortcuts.py": [
|
||||||
|
[
|
||||||
|
"/webdriver/tests/actions/key_shortcuts.py",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"webdriver/tests/actions/modifier_click.py": [
|
"webdriver/tests/actions/modifier_click.py": [
|
||||||
[
|
[
|
||||||
"/webdriver/tests/actions/modifier_click.py",
|
"/webdriver/tests/actions/modifier_click.py",
|
||||||
|
|
@ -541911,7 +541917,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"html/browsers/origin/cross-origin-objects/cross-origin-objects.html": [
|
"html/browsers/origin/cross-origin-objects/cross-origin-objects.html": [
|
||||||
"9202ebf4d640ffccec49451bae23526c24a1053b",
|
"ce27e8e729f434ce3e908a49a1ffd733bcdcd06a",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"html/browsers/origin/cross-origin-objects/frame.html": [
|
"html/browsers/origin/cross-origin-objects/frame.html": [
|
||||||
|
|
@ -586530,6 +586536,10 @@
|
||||||
"69542dc107d881bf18dfff3203bfd7a9ec31b4ad",
|
"69542dc107d881bf18dfff3203bfd7a9ec31b4ad",
|
||||||
"wdspec"
|
"wdspec"
|
||||||
],
|
],
|
||||||
|
"webdriver/tests/actions/key_shortcuts.py": [
|
||||||
|
"dbe27dd0b1625169fc8cc2055f8fb49d5a4a78d2",
|
||||||
|
"wdspec"
|
||||||
|
],
|
||||||
"webdriver/tests/actions/modifier_click.py": [
|
"webdriver/tests/actions/modifier_click.py": [
|
||||||
"2ec22f44973e6da3b9506ad7cc9fd0949f3ef8b5",
|
"2ec22f44973e6da3b9506ad7cc9fd0949f3ef8b5",
|
||||||
"wdspec"
|
"wdspec"
|
||||||
|
|
@ -586551,7 +586561,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"webdriver/tests/actions/support/keys.py": [
|
"webdriver/tests/actions/support/keys.py": [
|
||||||
"636991372c21e52b623ed4ada9dfb675dd7f7e14",
|
"61fc98ac2abeeb82486e6689c9cc16d0aa444b69",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"webdriver/tests/actions/support/refine.py": [
|
"webdriver/tests/actions/support/refine.py": [
|
||||||
|
|
@ -596623,7 +596633,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"webrtc/RTCDTMFSender-helper.js": [
|
"webrtc/RTCDTMFSender-helper.js": [
|
||||||
"54456b1c74d55552fdad0405f55dcd728205b561",
|
"0c2e8862deffeec71ac925642647bb9ee4ad70ff",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"webrtc/RTCDTMFSender-insertDTMF.https.html": [
|
"webrtc/RTCDTMFSender-insertDTMF.https.html": [
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
from tests.actions.support.keys import Keys, MODIFIER_KEY
|
||||||
|
from tests.actions.support.refine import get_keys
|
||||||
|
|
||||||
|
|
||||||
|
def test_mod_a_and_backspace_deletes_all_text(session, key_reporter, key_chain):
|
||||||
|
key_chain.send_keys("abc d") \
|
||||||
|
.key_down(MODIFIER_KEY) \
|
||||||
|
.key_down("a") \
|
||||||
|
.key_up(MODIFIER_KEY) \
|
||||||
|
.key_up("a") \
|
||||||
|
.key_down(Keys.BACKSPACE) \
|
||||||
|
.perform()
|
||||||
|
assert get_keys(key_reporter) == ""
|
||||||
|
|
||||||
|
|
||||||
|
def test_mod_a_mod_c_right_mod_v_pastes_text(session, key_reporter, key_chain):
|
||||||
|
initial = "abc d"
|
||||||
|
key_chain.send_keys(initial) \
|
||||||
|
.key_down(MODIFIER_KEY) \
|
||||||
|
.key_down("a") \
|
||||||
|
.key_up(MODIFIER_KEY) \
|
||||||
|
.key_up("a") \
|
||||||
|
.key_down(MODIFIER_KEY) \
|
||||||
|
.key_down("c") \
|
||||||
|
.key_up(MODIFIER_KEY) \
|
||||||
|
.key_up("c") \
|
||||||
|
.send_keys([Keys.RIGHT]) \
|
||||||
|
.key_down(MODIFIER_KEY) \
|
||||||
|
.key_down("v") \
|
||||||
|
.key_up(MODIFIER_KEY) \
|
||||||
|
.key_up("v") \
|
||||||
|
.perform()
|
||||||
|
assert get_keys(key_reporter) == initial * 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_mod_a_mod_x_deletes_all_text(session, key_reporter, key_chain):
|
||||||
|
key_chain.send_keys("abc d") \
|
||||||
|
.key_down(MODIFIER_KEY) \
|
||||||
|
.key_down("a") \
|
||||||
|
.key_up(MODIFIER_KEY) \
|
||||||
|
.key_up("a") \
|
||||||
|
.key_down(MODIFIER_KEY) \
|
||||||
|
.key_down("x") \
|
||||||
|
.key_up(MODIFIER_KEY) \
|
||||||
|
.key_up("x") \
|
||||||
|
.perform()
|
||||||
|
assert get_keys(key_reporter) == ""
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,6 +20,7 @@ The Keys implementation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from inspect import getmembers
|
from inspect import getmembers
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
class Keys(object):
|
class Keys(object):
|
||||||
|
|
@ -740,3 +741,8 @@ ALL_EVENTS = {
|
||||||
"value": u"\ue040",
|
"value": u"\ue040",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sys.platform == 'darwin':
|
||||||
|
MODIFIER_KEY = Keys.META
|
||||||
|
else:
|
||||||
|
MODIFIER_KEY = Keys.CONTROL
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ const FRECENCY_DEFAULT = 1000;
|
||||||
const MAXIMUM_ALLOWED_EXTENSION_MATCHES = 6;
|
const MAXIMUM_ALLOWED_EXTENSION_MATCHES = 6;
|
||||||
|
|
||||||
// After this time, we'll give up waiting for the extension to return matches.
|
// After this time, we'll give up waiting for the extension to return matches.
|
||||||
const MAXIMUM_ALLOWED_EXTENSION_TIME_MS = 5000;
|
const MAXIMUM_ALLOWED_EXTENSION_TIME_MS = 3000;
|
||||||
|
|
||||||
// A regex that matches "single word" hostnames for whitelisting purposes.
|
// A regex that matches "single word" hostnames for whitelisting purposes.
|
||||||
// The hostname will already have been checked for general validity, so we
|
// The hostname will already have been checked for general validity, so we
|
||||||
|
|
@ -95,6 +95,9 @@ const REGEXP_USER_CONTEXT_ID = /(?:^| )user-context-id:(\d+)/;
|
||||||
// Regex used to match one or more whitespace.
|
// Regex used to match one or more whitespace.
|
||||||
const REGEXP_SPACES = /\s+/;
|
const REGEXP_SPACES = /\s+/;
|
||||||
|
|
||||||
|
// The result is notified on a delay, to avoid rebuilding the panel at every match.
|
||||||
|
const NOTIFYRESULT_DELAY_MS = 16;
|
||||||
|
|
||||||
// Sqlite result row index constants.
|
// Sqlite result row index constants.
|
||||||
const QUERYINDEX_QUERYTYPE = 0;
|
const QUERYINDEX_QUERYTYPE = 0;
|
||||||
const QUERYINDEX_URL = 1;
|
const QUERYINDEX_URL = 1;
|
||||||
|
|
@ -330,6 +333,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "textURIService",
|
||||||
function setTimeout(callback, ms) {
|
function setTimeout(callback, ms) {
|
||||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||||
timer.initWithCallback(callback, ms, timer.TYPE_ONE_SHOT);
|
timer.initWithCallback(callback, ms, timer.TYPE_ONE_SHOT);
|
||||||
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertBucketsCharPrefToArray(str) {
|
function convertBucketsCharPrefToArray(str) {
|
||||||
|
|
@ -992,6 +996,9 @@ Search.prototype = {
|
||||||
// Avoid multiple calls or re-entrance.
|
// Avoid multiple calls or re-entrance.
|
||||||
if (!this.pending)
|
if (!this.pending)
|
||||||
return;
|
return;
|
||||||
|
if (this._notifyTimer)
|
||||||
|
this._notifyTimer.cancel();
|
||||||
|
this._notifyDelaysCount = 0;
|
||||||
if (this._sleepTimer)
|
if (this._sleepTimer)
|
||||||
this._sleepTimer.cancel();
|
this._sleepTimer.cancel();
|
||||||
if (this._sleepResolve) {
|
if (this._sleepResolve) {
|
||||||
|
|
@ -1127,7 +1134,6 @@ Search.prototype = {
|
||||||
// We're done if we're restricting to search suggestions.
|
// We're done if we're restricting to search suggestions.
|
||||||
// Notify the result completion then stop the search.
|
// Notify the result completion then stop the search.
|
||||||
this._autocompleteSearch.finishSearch(true);
|
this._autocompleteSearch.finishSearch(true);
|
||||||
this.stop();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1667,9 +1673,8 @@ Search.prototype = {
|
||||||
|
|
||||||
// Since the extension has no way to signale when it's done pushing
|
// Since the extension has no way to signale when it's done pushing
|
||||||
// results, we add a timeout racing with the addition.
|
// results, we add a timeout racing with the addition.
|
||||||
let timeoutPromise = new Promise((resolve, reject) => {
|
let timeoutPromise = new Promise(resolve => {
|
||||||
setTimeout(() => reject(new Error("timeout waiting for the extension to add its results to the location bar")),
|
setTimeout(resolve, MAXIMUM_ALLOWED_EXTENSION_TIME_MS);
|
||||||
MAXIMUM_ALLOWED_EXTENSION_TIME_MS);
|
|
||||||
});
|
});
|
||||||
return Promise.race([timeoutPromise, promise]).catch(Cu.reportError);
|
return Promise.race([timeoutPromise, promise]).catch(Cu.reportError);
|
||||||
},
|
},
|
||||||
|
|
@ -1909,7 +1914,7 @@ Search.prototype = {
|
||||||
TelemetryStopwatch.finish(TELEMETRY_1ST_RESULT, this);
|
TelemetryStopwatch.finish(TELEMETRY_1ST_RESULT, this);
|
||||||
if (this._currentMatchCount == 6)
|
if (this._currentMatchCount == 6)
|
||||||
TelemetryStopwatch.finish(TELEMETRY_6_FIRST_RESULTS, this);
|
TelemetryStopwatch.finish(TELEMETRY_6_FIRST_RESULTS, this);
|
||||||
this.notifyResults(true);
|
this.notifyResult(true, match.type == MATCHTYPE.HEURISTIC);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getInsertIndexForMatch(match) {
|
_getInsertIndexForMatch(match) {
|
||||||
|
|
@ -2009,7 +2014,7 @@ Search.prototype = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed && notify) {
|
if (changed && notify) {
|
||||||
this.notifyResults(true);
|
this.notifyResult(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -2364,24 +2369,47 @@ Search.prototype = {
|
||||||
return query;
|
return query;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
// The result is notified to the search listener on a timer, to chunk multiple
|
||||||
* Notifies the listener about results.
|
// match updates together and avoid rebuilding the popup at every new match.
|
||||||
|
_notifyTimer: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the current result to the listener.
|
||||||
*
|
*
|
||||||
* @param searchOngoing
|
* @param searchOngoing
|
||||||
* Indicates whether the search is ongoing.
|
* Indicates whether the search result should be marked as ongoing.
|
||||||
|
* @param skipDelay
|
||||||
|
* Whether to notify immediately.
|
||||||
*/
|
*/
|
||||||
notifyResults(searchOngoing) {
|
_notifyDelaysCount: 0,
|
||||||
let result = this._result;
|
notifyResult(searchOngoing, skipDelay = false) {
|
||||||
let resultCode = this._currentMatchCount ? "RESULT_SUCCESS" : "RESULT_NOMATCH";
|
let notify = () => {
|
||||||
if (searchOngoing) {
|
this._notifyDelaysCount = 0;
|
||||||
resultCode += "_ONGOING";
|
let resultCode = this._currentMatchCount ? "RESULT_SUCCESS" : "RESULT_NOMATCH";
|
||||||
|
if (searchOngoing) {
|
||||||
|
resultCode += "_ONGOING";
|
||||||
|
}
|
||||||
|
let result = this._result;
|
||||||
|
result.setSearchResult(Ci.nsIAutoCompleteResult[resultCode]);
|
||||||
|
this._listener.onSearchResult(this._autocompleteSearch, result);
|
||||||
|
if (!searchOngoing) {
|
||||||
|
// Break possible cycles.
|
||||||
|
this._listener = null;
|
||||||
|
this._autocompleteSearch = null;
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (this._notifyTimer) {
|
||||||
|
this._notifyTimer.cancel();
|
||||||
}
|
}
|
||||||
result.setSearchResult(Ci.nsIAutoCompleteResult[resultCode]);
|
// In the worst case, we may get evenly spaced matches that would end up
|
||||||
this._listener.onSearchResult(this._autocompleteSearch, result);
|
// delaying the UI by N_MATCHES * NOTIFYRESULT_DELAY_MS. Thus, we clamp the
|
||||||
if (!searchOngoing) {
|
// number of times we may delay matches.
|
||||||
// Break possible cycles.
|
if (skipDelay || this._notifyDelaysCount > 3) {
|
||||||
this._listener = null;
|
notify();
|
||||||
this._autocompleteSearch = null;
|
} else {
|
||||||
|
this._notifyDelaysCount++;
|
||||||
|
this._notifyTimer = setTimeout(notify, NOTIFYRESULT_DELAY_MS);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -2579,7 +2607,6 @@ UnifiedComplete.prototype = {
|
||||||
if (!notify || !search.pending)
|
if (!notify || !search.pending)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
// If we are in restrict mode and we reused the previous search results,
|
// If we are in restrict mode and we reused the previous search results,
|
||||||
// it's possible we didn't go through all the cleanup methods due to early
|
// it's possible we didn't go through all the cleanup methods due to early
|
||||||
// bailouts. Thus we could still have nonmatching results to remove.
|
// bailouts. Thus we could still have nonmatching results to remove.
|
||||||
|
|
@ -2591,10 +2618,10 @@ UnifiedComplete.prototype = {
|
||||||
// onSearchComplete.
|
// onSearchComplete.
|
||||||
// If onSearchComplete immediately starts a new search it will set a new
|
// If onSearchComplete immediately starts a new search it will set a new
|
||||||
// _currentSearch, and on return the execution will continue here, after
|
// _currentSearch, and on return the execution will continue here, after
|
||||||
// notifyResults.
|
// notifyResult.
|
||||||
// Thus, ensure that notifyResults is the last call in this method,
|
// Thus, ensure that notifyResult is the last call in this method,
|
||||||
// otherwise you might be touching the wrong search.
|
// otherwise you might be touching the wrong search.
|
||||||
search.notifyResults(false);
|
search.notifyResult(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
// nsIAutoCompleteSearchDescriptor
|
// nsIAutoCompleteSearchDescriptor
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
|
||||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
function check_queries_results(aQueries, aOptions, aExpectedBookmarks) {
|
||||||
getService(Ci.nsINavBookmarksService);
|
var result = PlacesUtils.history.executeQueries(aQueries, aQueries.length, aOptions);
|
||||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
|
||||||
getService(Ci.nsINavHistoryService);
|
|
||||||
|
|
||||||
function check_queries_results(aQueries, aOptions, aExpectedItemIds) {
|
|
||||||
var result = hs.executeQueries(aQueries, aQueries.length, aOptions);
|
|
||||||
var root = result.root;
|
var root = result.root;
|
||||||
root.containerOpen = true;
|
root.containerOpen = true;
|
||||||
|
|
||||||
|
|
@ -20,50 +15,62 @@ function check_queries_results(aQueries, aOptions, aExpectedItemIds) {
|
||||||
dump("nodes[" + i + "]: " + root.getChild(0).title + "\n");
|
dump("nodes[" + i + "]: " + root.getChild(0).title + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
do_check_eq(root.childCount, aExpectedItemIds.length);
|
do_check_eq(root.childCount, aExpectedBookmarks.length);
|
||||||
for (let i = 0; i < root.childCount; i++) {
|
for (let i = 0; i < root.childCount; i++) {
|
||||||
do_check_eq(root.getChild(i).itemId, aExpectedItemIds[i]);
|
do_check_eq(root.getChild(i).bookmarkGuid, aExpectedBookmarks[i].guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
root.containerOpen = false;
|
root.containerOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// main
|
// main
|
||||||
function run_test() {
|
add_task(async function run_test() {
|
||||||
var id1 = bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://foo.tld"),
|
let bookmarks = await PlacesUtils.bookmarks.insertTree({
|
||||||
bs.DEFAULT_INDEX, "123 0");
|
guid: PlacesUtils.bookmarks.menuGuid,
|
||||||
var id2 = bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://foo.tld"),
|
children: [{
|
||||||
bs.DEFAULT_INDEX, "456");
|
title: "123 0",
|
||||||
var id3 = bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://foo.tld"),
|
url: "http://foo.tld",
|
||||||
bs.DEFAULT_INDEX, "123 456");
|
}, {
|
||||||
var id4 = bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://foo.tld"),
|
title: "456",
|
||||||
bs.DEFAULT_INDEX, "789 456");
|
url: "http://foo.tld",
|
||||||
|
}, {
|
||||||
|
title: "123 456",
|
||||||
|
url: "http://foo.tld",
|
||||||
|
}, {
|
||||||
|
title: "789 456",
|
||||||
|
url: "http://foo.tld",
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All of the query objects are ORed together. Within a query, all the terms
|
* All of the query objects are ORed together. Within a query, all the terms
|
||||||
* are ANDed together. See nsINavHistory.idl.
|
* are ANDed together. See nsINavHistory.idl.
|
||||||
*/
|
*/
|
||||||
var queries = [];
|
var queries = [];
|
||||||
queries.push(hs.getNewQuery());
|
queries.push(PlacesUtils.history.getNewQuery());
|
||||||
queries.push(hs.getNewQuery());
|
queries.push(PlacesUtils.history.getNewQuery());
|
||||||
var options = hs.getNewQueryOptions();
|
var options = PlacesUtils.history.getNewQueryOptions();
|
||||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||||
|
|
||||||
// Test 1
|
// Test 1
|
||||||
dump("Test searching for 123 OR 789\n");
|
dump("Test searching for 123 OR 789\n");
|
||||||
queries[0].searchTerms = "123";
|
queries[0].searchTerms = "123";
|
||||||
queries[1].searchTerms = "789";
|
queries[1].searchTerms = "789";
|
||||||
check_queries_results(queries, options, [id1, id3, id4]);
|
check_queries_results(queries, options, [
|
||||||
|
bookmarks[0],
|
||||||
|
bookmarks[2],
|
||||||
|
bookmarks[3]
|
||||||
|
]);
|
||||||
|
|
||||||
// Test 2
|
// Test 2
|
||||||
dump("Test searching for 123 OR 456\n");
|
dump("Test searching for 123 OR 456\n");
|
||||||
queries[0].searchTerms = "123";
|
queries[0].searchTerms = "123";
|
||||||
queries[1].searchTerms = "456";
|
queries[1].searchTerms = "456";
|
||||||
check_queries_results(queries, options, [id1, id2, id3, id4]);
|
check_queries_results(queries, options, bookmarks);
|
||||||
|
|
||||||
// Test 3
|
// Test 3
|
||||||
dump("Test searching for 00 OR 789\n");
|
dump("Test searching for 00 OR 789\n");
|
||||||
queries[0].searchTerms = "00";
|
queries[0].searchTerms = "00";
|
||||||
queries[1].searchTerms = "789";
|
queries[1].searchTerms = "789";
|
||||||
check_queries_results(queries, options, [id4]);
|
check_queries_results(queries, options, [bookmarks[3]]);
|
||||||
}
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
var tests = [];
|
|
||||||
|
|
||||||
// Get database connection
|
// Get database connection
|
||||||
try {
|
try {
|
||||||
var mDBConn = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
var mDBConn = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||||
|
|
@ -19,79 +17,64 @@ try {
|
||||||
- don't try to add invalid uri nodes to a JSON backup
|
- don't try to add invalid uri nodes to a JSON backup
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var invalidURITest = {
|
const ITEM_TITLE = "invalid uri";
|
||||||
_itemTitle: "invalid uri",
|
const ITEM_URL = "http://test.mozilla.org";
|
||||||
_itemUrl: "http://test.mozilla.org/",
|
|
||||||
_itemId: null,
|
|
||||||
|
|
||||||
populate() {
|
function validateResults(expectedValidItemsCount) {
|
||||||
// add a valid bookmark
|
var query = PlacesUtils.history.getNewQuery();
|
||||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.toolbarFolderId,
|
query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1);
|
||||||
PlacesUtils._uri(this._itemUrl),
|
var options = PlacesUtils.history.getNewQueryOptions();
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
var result = PlacesUtils.history.executeQuery(query, options);
|
||||||
this._itemTitle);
|
|
||||||
// this bookmark will go corrupt
|
|
||||||
this._itemId =
|
|
||||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.toolbarFolderId,
|
|
||||||
PlacesUtils._uri(this._itemUrl),
|
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
|
||||||
this._itemTitle);
|
|
||||||
},
|
|
||||||
|
|
||||||
clean() {
|
var toolbar = result.root;
|
||||||
PlacesUtils.bookmarks.removeItem(this._itemId);
|
toolbar.containerOpen = true;
|
||||||
},
|
|
||||||
|
|
||||||
validate(aExpectValidItemsCount) {
|
// test for our bookmark
|
||||||
var query = PlacesUtils.history.getNewQuery();
|
do_check_eq(toolbar.childCount, expectedValidItemsCount);
|
||||||
query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1);
|
for (var i = 0; i < toolbar.childCount; i++) {
|
||||||
var options = PlacesUtils.history.getNewQueryOptions();
|
var folderNode = toolbar.getChild(0);
|
||||||
var result = PlacesUtils.history.executeQuery(query, options);
|
do_check_eq(folderNode.type, folderNode.RESULT_TYPE_URI);
|
||||||
|
do_check_eq(folderNode.title, ITEM_TITLE);
|
||||||
var toolbar = result.root;
|
|
||||||
toolbar.containerOpen = true;
|
|
||||||
|
|
||||||
// test for our bookmark
|
|
||||||
do_check_eq(toolbar.childCount, aExpectValidItemsCount);
|
|
||||||
for (var i = 0; i < toolbar.childCount; i++) {
|
|
||||||
var folderNode = toolbar.getChild(0);
|
|
||||||
do_check_eq(folderNode.type, folderNode.RESULT_TYPE_URI);
|
|
||||||
do_check_eq(folderNode.title, this._itemTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean up
|
|
||||||
toolbar.containerOpen = false;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
tests.push(invalidURITest);
|
// clean up
|
||||||
|
toolbar.containerOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
// make json file
|
// make json file
|
||||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
||||||
|
|
||||||
// populate db
|
// populate db
|
||||||
tests.forEach(function(aTest) {
|
// add a valid bookmark
|
||||||
aTest.populate();
|
await PlacesUtils.bookmarks.insert({
|
||||||
// sanity
|
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||||
aTest.validate(2);
|
title: ITEM_TITLE,
|
||||||
// Something in the code went wrong and we finish up losing the place, so
|
url: ITEM_URL,
|
||||||
// the bookmark uri becomes null.
|
|
||||||
var sql = "UPDATE moz_bookmarks SET fk = 1337 WHERE id = ?1";
|
|
||||||
var stmt = mDBConn.createStatement(sql);
|
|
||||||
stmt.bindByIndex(0, aTest._itemId);
|
|
||||||
try {
|
|
||||||
stmt.execute();
|
|
||||||
} finally {
|
|
||||||
stmt.finalize();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let badBookmark = await PlacesUtils.bookmarks.insert({
|
||||||
|
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||||
|
title: ITEM_TITLE,
|
||||||
|
url: ITEM_URL,
|
||||||
|
});
|
||||||
|
// sanity
|
||||||
|
validateResults(2);
|
||||||
|
// Something in the code went wrong and we finish up losing the place, so
|
||||||
|
// the bookmark uri becomes null.
|
||||||
|
var sql = "UPDATE moz_bookmarks SET fk = 1337 WHERE guid = ?1";
|
||||||
|
var stmt = mDBConn.createStatement(sql);
|
||||||
|
stmt.bindByIndex(0, badBookmark.guid);
|
||||||
|
try {
|
||||||
|
stmt.execute();
|
||||||
|
} finally {
|
||||||
|
stmt.finalize();
|
||||||
|
}
|
||||||
|
|
||||||
await BookmarkJSONUtils.exportToFile(jsonFile);
|
await BookmarkJSONUtils.exportToFile(jsonFile);
|
||||||
|
|
||||||
// clean
|
// clean
|
||||||
tests.forEach(function(aTest) {
|
await PlacesUtils.bookmarks.remove(badBookmark);
|
||||||
aTest.clean();
|
|
||||||
});
|
|
||||||
|
|
||||||
// restore json file
|
// restore json file
|
||||||
try {
|
try {
|
||||||
|
|
@ -99,9 +82,7 @@ add_task(async function() {
|
||||||
} catch (ex) { do_throw("couldn't import the exported file: " + ex); }
|
} catch (ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
tests.forEach(function(aTest) {
|
validateResults(1);
|
||||||
aTest.validate(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
await OS.File.remove(jsonFile);
|
await OS.File.remove(jsonFile);
|
||||||
|
|
|
||||||
|
|
@ -4,114 +4,94 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
var tests = [];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This test is:
|
This test is:
|
||||||
- don't block while doing backup and restore if tag containers contain
|
- don't block while doing backup and restore if tag containers contain
|
||||||
bogus items (separators, folders)
|
bogus items (separators, folders)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var invalidTagChildTest = {
|
const ITEM_TITLE = "invalid uri";
|
||||||
_itemTitle: "invalid uri",
|
const ITEM_URL = "http://test.mozilla.org/";
|
||||||
_itemUrl: "http://test.mozilla.org/",
|
const TAG_NAME = "testTag";
|
||||||
_itemId: -1,
|
|
||||||
_tag: "testTag",
|
|
||||||
_tagItemId: -1,
|
|
||||||
|
|
||||||
populate() {
|
function validateResults() {
|
||||||
// add a valid bookmark
|
var query = PlacesUtils.history.getNewQuery();
|
||||||
this._itemId = PlacesUtils.bookmarks
|
query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1);
|
||||||
.insertBookmark(PlacesUtils.toolbarFolderId,
|
var options = PlacesUtils.history.getNewQueryOptions();
|
||||||
PlacesUtils._uri(this._itemUrl),
|
var result = PlacesUtils.history.executeQuery(query, options);
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
|
||||||
this._itemTitle);
|
|
||||||
|
|
||||||
// create a tag
|
var toolbar = result.root;
|
||||||
PlacesUtils.tagging.tagURI(PlacesUtils._uri(this._itemUrl), [this._tag]);
|
toolbar.containerOpen = true;
|
||||||
// get tag folder id
|
|
||||||
var options = PlacesUtils.history.getNewQueryOptions();
|
|
||||||
var query = PlacesUtils.history.getNewQuery();
|
|
||||||
query.setFolders([PlacesUtils.bookmarks.tagsFolder], 1);
|
|
||||||
var result = PlacesUtils.history.executeQuery(query, options);
|
|
||||||
var tagRoot = result.root;
|
|
||||||
tagRoot.containerOpen = true;
|
|
||||||
do_check_eq(tagRoot.childCount, 1);
|
|
||||||
var tagNode = tagRoot.getChild(0)
|
|
||||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
|
||||||
this._tagItemId = tagNode.itemId;
|
|
||||||
tagRoot.containerOpen = false;
|
|
||||||
|
|
||||||
// add a separator and a folder inside tag folder
|
// test for our bookmark
|
||||||
PlacesUtils.bookmarks.insertSeparator(this._tagItemId,
|
do_check_eq(toolbar.childCount, 1);
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
for (var i = 0; i < toolbar.childCount; i++) {
|
||||||
PlacesUtils.bookmarks.createFolder(this._tagItemId,
|
var folderNode = toolbar.getChild(0);
|
||||||
"test folder",
|
do_check_eq(folderNode.type, folderNode.RESULT_TYPE_URI);
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
do_check_eq(folderNode.title, ITEM_TITLE);
|
||||||
|
|
||||||
// add a separator and a folder inside tag root
|
|
||||||
PlacesUtils.bookmarks.insertSeparator(PlacesUtils.bookmarks.tagsFolder,
|
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
|
||||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.bookmarks.tagsFolder,
|
|
||||||
"test tags root folder",
|
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
|
||||||
},
|
|
||||||
|
|
||||||
clean() {
|
|
||||||
PlacesUtils.tagging.untagURI(PlacesUtils._uri(this._itemUrl), [this._tag]);
|
|
||||||
PlacesUtils.bookmarks.removeItem(this._itemId);
|
|
||||||
},
|
|
||||||
|
|
||||||
validate() {
|
|
||||||
var query = PlacesUtils.history.getNewQuery();
|
|
||||||
query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1);
|
|
||||||
var options = PlacesUtils.history.getNewQueryOptions();
|
|
||||||
var result = PlacesUtils.history.executeQuery(query, options);
|
|
||||||
|
|
||||||
var toolbar = result.root;
|
|
||||||
toolbar.containerOpen = true;
|
|
||||||
|
|
||||||
// test for our bookmark
|
|
||||||
do_check_eq(toolbar.childCount, 1);
|
|
||||||
for (var i = 0; i < toolbar.childCount; i++) {
|
|
||||||
var folderNode = toolbar.getChild(0);
|
|
||||||
do_check_eq(folderNode.type, folderNode.RESULT_TYPE_URI);
|
|
||||||
do_check_eq(folderNode.title, this._itemTitle);
|
|
||||||
}
|
|
||||||
toolbar.containerOpen = false;
|
|
||||||
|
|
||||||
// test for our tag
|
|
||||||
var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(this._itemUrl));
|
|
||||||
do_check_eq(tags.length, 1);
|
|
||||||
do_check_eq(tags[0], this._tag);
|
|
||||||
}
|
}
|
||||||
};
|
toolbar.containerOpen = false;
|
||||||
tests.push(invalidTagChildTest);
|
|
||||||
|
// test for our tag
|
||||||
|
var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(ITEM_URL));
|
||||||
|
do_check_eq(tags.length, 1);
|
||||||
|
do_check_eq(tags[0], TAG_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
||||||
|
|
||||||
// populate db
|
// add a valid bookmark
|
||||||
tests.forEach(function(aTest) {
|
let item = await PlacesUtils.bookmarks.insert({
|
||||||
aTest.populate();
|
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||||
// sanity
|
title: ITEM_TITLE,
|
||||||
aTest.validate();
|
url: ITEM_URL,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// create a tag
|
||||||
|
PlacesUtils.tagging.tagURI(PlacesUtils._uri(ITEM_URL), [TAG_NAME]);
|
||||||
|
// get tag folder id
|
||||||
|
var options = PlacesUtils.history.getNewQueryOptions();
|
||||||
|
var query = PlacesUtils.history.getNewQuery();
|
||||||
|
query.setFolders([PlacesUtils.bookmarks.tagsFolder], 1);
|
||||||
|
var result = PlacesUtils.history.executeQuery(query, options);
|
||||||
|
var tagRoot = result.root;
|
||||||
|
tagRoot.containerOpen = true;
|
||||||
|
do_check_eq(tagRoot.childCount, 1);
|
||||||
|
var tagNode = tagRoot.getChild(0)
|
||||||
|
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||||
|
let tagItemId = tagNode.itemId;
|
||||||
|
tagRoot.containerOpen = false;
|
||||||
|
|
||||||
|
// Currently these use the old API as the new API doesn't support inserting
|
||||||
|
// invalid items into the tag folder.
|
||||||
|
|
||||||
|
// add a separator and a folder inside tag folder
|
||||||
|
PlacesUtils.bookmarks.insertSeparator(tagItemId,
|
||||||
|
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||||
|
PlacesUtils.bookmarks.createFolder(tagItemId,
|
||||||
|
"test folder",
|
||||||
|
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||||
|
|
||||||
|
// add a separator and a folder inside tag root
|
||||||
|
PlacesUtils.bookmarks.insertSeparator(PlacesUtils.bookmarks.tagsFolder,
|
||||||
|
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||||
|
PlacesUtils.bookmarks.createFolder(PlacesUtils.bookmarks.tagsFolder,
|
||||||
|
"test tags root folder",
|
||||||
|
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||||
|
// sanity
|
||||||
|
validateResults();
|
||||||
|
|
||||||
await BookmarkJSONUtils.exportToFile(jsonFile);
|
await BookmarkJSONUtils.exportToFile(jsonFile);
|
||||||
|
|
||||||
// clean
|
// clean
|
||||||
tests.forEach(function(aTest) {
|
PlacesUtils.tagging.untagURI(PlacesUtils._uri(ITEM_URL), [TAG_NAME]);
|
||||||
aTest.clean();
|
await PlacesUtils.bookmarks.remove(item);
|
||||||
});
|
|
||||||
|
|
||||||
// restore json file
|
// restore json file
|
||||||
await BookmarkJSONUtils.importFromFile(jsonFile, true);
|
await BookmarkJSONUtils.importFromFile(jsonFile, true);
|
||||||
|
|
||||||
// validate
|
validateResults();
|
||||||
tests.forEach(function(aTest) {
|
|
||||||
aTest.validate();
|
|
||||||
});
|
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
await OS.File.remove(jsonFile);
|
await OS.File.remove(jsonFile);
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,12 @@ add_task(async function() {
|
||||||
do_check_eq(matches[3], hash);
|
do_check_eq(matches[3], hash);
|
||||||
|
|
||||||
// Add a bookmark and create another backup.
|
// Add a bookmark and create another backup.
|
||||||
let bookmarkId = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.bookmarksMenuFolder,
|
let bookmark = await PlacesUtils.bookmarks.insert({
|
||||||
uri("http://foo.com"),
|
parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
title: "foo",
|
||||||
"foo");
|
url: "http://foo.com",
|
||||||
|
});
|
||||||
|
|
||||||
// We must enforce a backup since one for today already exists. The forced
|
// We must enforce a backup since one for today already exists. The forced
|
||||||
// backup will replace the existing one.
|
// backup will replace the existing one.
|
||||||
await PlacesBackups.create(undefined, true);
|
await PlacesBackups.create(undefined, true);
|
||||||
|
|
@ -50,6 +52,6 @@ add_task(async function() {
|
||||||
do_check_neq(matches[3], hash);
|
do_check_neq(matches[3], hash);
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
PlacesUtils.bookmarks.removeItem(bookmarkId);
|
await PlacesUtils.bookmarks.remove(bookmark);
|
||||||
await PlacesBackups.create(0);
|
await PlacesBackups.create(0);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -30,20 +30,21 @@ add_task(async function compress_bookmark_backups_test() {
|
||||||
do_check_eq((await PlacesBackups.getBackupFiles()).length, 1);
|
do_check_eq((await PlacesBackups.getBackupFiles()).length, 1);
|
||||||
|
|
||||||
// Check if import works from lz4 compressed json
|
// Check if import works from lz4 compressed json
|
||||||
let uri = NetUtil.newURI("http://www.mozilla.org/en-US/");
|
let url = "http://www.mozilla.org/en-US/"
|
||||||
let bm = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
let bm = await PlacesUtils.bookmarks.insert({
|
||||||
uri,
|
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
title: "bookmark",
|
||||||
"bookmark");
|
url,
|
||||||
|
});
|
||||||
|
|
||||||
// Force create a compressed backup, Remove the bookmark, the restore the backup
|
// Force create a compressed backup, Remove the bookmark, the restore the backup
|
||||||
await PlacesBackups.create(undefined, true);
|
await PlacesBackups.create(undefined, true);
|
||||||
let recentBackup = await PlacesBackups.getMostRecentBackup();
|
let recentBackup = await PlacesBackups.getMostRecentBackup();
|
||||||
PlacesUtils.bookmarks.removeItem(bm);
|
await PlacesUtils.bookmarks.remove(bm);
|
||||||
await BookmarkJSONUtils.importFromFile(recentBackup, true);
|
await BookmarkJSONUtils.importFromFile(recentBackup, true);
|
||||||
let root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
let root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||||
let node = root.getChild(0);
|
let node = root.getChild(0);
|
||||||
do_check_eq(node.uri, uri.spec);
|
do_check_eq(node.uri, url);
|
||||||
|
|
||||||
root.containerOpen = false;
|
root.containerOpen = false;
|
||||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@
|
||||||
*/
|
*/
|
||||||
add_task(async function test_saveBookmarksToJSONFile_and_create() {
|
add_task(async function test_saveBookmarksToJSONFile_and_create() {
|
||||||
// Add a bookmark
|
// Add a bookmark
|
||||||
let uri = NetUtil.newURI("http://getfirefox.com/");
|
let bookmark = await PlacesUtils.bookmarks.insert({
|
||||||
let bookmarkId =
|
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||||
PlacesUtils.bookmarks.insertBookmark(
|
title: "Get Firefox!",
|
||||||
PlacesUtils.unfiledBookmarksFolderId, uri,
|
url: "http://getfirefox.com/"
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
|
});
|
||||||
|
|
||||||
// Test saveBookmarksToJSONFile()
|
// Test saveBookmarksToJSONFile()
|
||||||
let backupFile = FileUtils.getFile("TmpD", ["bookmarks.json"]);
|
let backupFile = FileUtils.getFile("TmpD", ["bookmarks.json"]);
|
||||||
|
|
@ -47,5 +47,5 @@ add_task(async function test_saveBookmarksToJSONFile_and_create() {
|
||||||
// Cleanup
|
// Cleanup
|
||||||
backupFile.remove(false);
|
backupFile.remove(false);
|
||||||
await PlacesBackups.create(0);
|
await PlacesBackups.create(0);
|
||||||
PlacesUtils.bookmarks.removeItem(bookmarkId);
|
await PlacesUtils.bookmarks.remove(bookmark);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,34 @@
|
||||||
* ancestor in the bookmarks table.
|
* ancestor in the bookmarks table.
|
||||||
*/
|
*/
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
let bm = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
let bms = await PlacesUtils.bookmarks.insertTree({
|
||||||
NetUtil.newURI("http://mozilla.org/"),
|
guid: PlacesUtils.bookmarks.unfiledGuid,
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
children: [{
|
||||||
"bookmark");
|
title: "bookmark",
|
||||||
let f2 = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId, "f2",
|
url: "http://mozilla.org",
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
}, {
|
||||||
PlacesUtils.bookmarks.moveItem(bm, f2, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
title: "f2",
|
||||||
let f1 = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId, "f1",
|
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
}, {
|
||||||
PlacesUtils.bookmarks.moveItem(f2, f1, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
title: "f1",
|
||||||
|
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
let bookmark = bms[0];
|
||||||
|
let folder2 = bms[1];
|
||||||
|
let folder1 = bms[2];
|
||||||
|
bookmark.parentGuid = folder2.guid;
|
||||||
|
await PlacesUtils.bookmarks.update(bookmark);
|
||||||
|
|
||||||
|
folder2.parentGuid = folder1.guid;
|
||||||
|
await PlacesUtils.bookmarks.update(folder2);
|
||||||
|
|
||||||
// Create a backup.
|
// Create a backup.
|
||||||
await PlacesBackups.create();
|
await PlacesBackups.create();
|
||||||
|
|
||||||
// Remove the bookmarks, then restore the backup.
|
// Remove the bookmarks, then restore the backup.
|
||||||
PlacesUtils.bookmarks.removeItem(f1);
|
await PlacesUtils.bookmarks.remove(folder1);
|
||||||
await BookmarkJSONUtils.importFromFile((await PlacesBackups.getMostRecentBackup()), true);
|
await BookmarkJSONUtils.importFromFile((await PlacesBackups.getMostRecentBackup()), true);
|
||||||
|
|
||||||
do_print("Checking first level");
|
do_print("Checking first level");
|
||||||
|
|
@ -36,7 +48,7 @@ add_task(async function() {
|
||||||
do_check_eq(level2.title, "f2");
|
do_check_eq(level2.title, "f2");
|
||||||
do_print("Checking bookmark");
|
do_print("Checking bookmark");
|
||||||
PlacesUtils.asContainer(level2).containerOpen = true;
|
PlacesUtils.asContainer(level2).containerOpen = true;
|
||||||
let bookmark = level2.getChild(0);
|
bookmark = level2.getChild(0);
|
||||||
do_check_eq(bookmark.title, "bookmark");
|
do_check_eq(bookmark.title, "bookmark");
|
||||||
level2.containerOpen = false;
|
level2.containerOpen = false;
|
||||||
level1.containerOpen = false;
|
level1.containerOpen = false;
|
||||||
|
|
|
||||||
|
|
@ -6,27 +6,28 @@
|
||||||
* Checks that we don't encodeURI twice when creating bookmarks.html.
|
* Checks that we don't encodeURI twice when creating bookmarks.html.
|
||||||
*/
|
*/
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
let uri = NetUtil.newURI("http://bt.ktxp.com/search.php?keyword=%E5%A6%84%E6%83%B3%E5%AD%A6%E7%94%9F%E4%BC%9A");
|
let url = "http://bt.ktxp.com/search.php?keyword=%E5%A6%84%E6%83%B3%E5%AD%A6%E7%94%9F%E4%BC%9A";
|
||||||
let bm = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
let bm = await PlacesUtils.bookmarks.insert({
|
||||||
uri,
|
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
title: "bookmark",
|
||||||
"bookmark");
|
url,
|
||||||
|
});
|
||||||
|
|
||||||
let file = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.exported.997030.html");
|
let file = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.exported.997030.html");
|
||||||
if ((await OS.File.exists(file))) {
|
if ((await OS.File.exists(file))) {
|
||||||
await OS.File.remove(file);
|
await OS.File.remove(file);
|
||||||
}
|
}
|
||||||
await BookmarkHTMLUtils.exportToFile(file);
|
await BookmarkHTMLUtils.exportToFile(file);
|
||||||
|
|
||||||
// Remove the bookmarks, then restore the backup.
|
// Remove the bookmarks, then restore the backup.
|
||||||
PlacesUtils.bookmarks.removeItem(bm);
|
await PlacesUtils.bookmarks.remove(bm);
|
||||||
await BookmarkHTMLUtils.importFromFile(file, true);
|
await BookmarkHTMLUtils.importFromFile(file, true);
|
||||||
|
|
||||||
do_print("Checking first level");
|
do_print("Checking first level");
|
||||||
let root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
let root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||||
let node = root.getChild(0);
|
let node = root.getChild(0);
|
||||||
do_check_eq(node.uri, uri.spec);
|
do_check_eq(node.uri, url);
|
||||||
|
|
||||||
root.containerOpen = false;
|
root.containerOpen = false;
|
||||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
await PlacesUtils.bookmarks.eraseEverything();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,35 +4,38 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
// get bookmarks root id
|
|
||||||
var root = PlacesUtils.bookmarksMenuFolderId;
|
|
||||||
|
|
||||||
// a search term that matches a default bookmark
|
// a search term that matches a default bookmark
|
||||||
const searchTerm = "about";
|
const searchTerm = "about";
|
||||||
|
|
||||||
var testRoot;
|
var testRoot;
|
||||||
|
var testRootId;
|
||||||
|
|
||||||
// main
|
add_task(async function setup() {
|
||||||
function run_test() {
|
|
||||||
// create a folder to hold all the tests
|
// create a folder to hold all the tests
|
||||||
// this makes the tests more tolerant of changes to the default bookmarks set
|
// this makes the tests more tolerant of changes to the default bookmarks set
|
||||||
// also, name it using the search term, for testing that containers that match don't show up in query results
|
// also, name it using the search term, for testing that containers that match don't show up in query results
|
||||||
testRoot = PlacesUtils.bookmarks.createFolder(
|
testRoot = await PlacesUtils.bookmarks.insert({
|
||||||
root, searchTerm, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||||
|
title: searchTerm,
|
||||||
|
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||||
|
});
|
||||||
|
testRootId = await PlacesUtils.promiseItemId(testRoot.guid);
|
||||||
|
});
|
||||||
|
|
||||||
run_next_test();
|
add_task(async function test_savedsearches_bookmarks() {
|
||||||
}
|
|
||||||
|
|
||||||
add_test(function test_savedsearches_bookmarks() {
|
|
||||||
// add a bookmark that matches the search term
|
// add a bookmark that matches the search term
|
||||||
var bookmarkId = PlacesUtils.bookmarks.insertBookmark(
|
let bookmark = await PlacesUtils.bookmarks.insert({
|
||||||
root, uri("http://foo.com"), PlacesUtils.bookmarks.DEFAULT_INDEX,
|
parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||||
searchTerm);
|
title: searchTerm,
|
||||||
|
url: "http://foo.com",
|
||||||
|
});
|
||||||
|
|
||||||
// create a saved-search that matches a default bookmark
|
// create a saved-search that matches a default bookmark
|
||||||
var searchId = PlacesUtils.bookmarks.insertBookmark(
|
let search = await PlacesUtils.bookmarks.insert({
|
||||||
testRoot, uri("place:terms=" + searchTerm + "&excludeQueries=1&expandQueries=1&queryType=1"),
|
parentGuid: testRoot.guid,
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX, searchTerm);
|
title: searchTerm,
|
||||||
|
url: "place:terms=" + searchTerm + "&excludeQueries=1&expandQueries=1&queryType=1",
|
||||||
|
});
|
||||||
|
|
||||||
// query for the test root, expandQueries=0
|
// query for the test root, expandQueries=0
|
||||||
// the query should show up as a regular bookmark
|
// the query should show up as a regular bookmark
|
||||||
|
|
@ -40,7 +43,7 @@ add_test(function test_savedsearches_bookmarks() {
|
||||||
let options = PlacesUtils.history.getNewQueryOptions();
|
let options = PlacesUtils.history.getNewQueryOptions();
|
||||||
options.expandQueries = 0;
|
options.expandQueries = 0;
|
||||||
let query = PlacesUtils.history.getNewQuery();
|
let query = PlacesUtils.history.getNewQuery();
|
||||||
query.setFolders([testRoot], 1);
|
query.setFolders([testRootId], 1);
|
||||||
let result = PlacesUtils.history.executeQuery(query, options);
|
let result = PlacesUtils.history.executeQuery(query, options);
|
||||||
let rootNode = result.root;
|
let rootNode = result.root;
|
||||||
rootNode.containerOpen = true;
|
rootNode.containerOpen = true;
|
||||||
|
|
@ -66,7 +69,7 @@ add_test(function test_savedsearches_bookmarks() {
|
||||||
let options = PlacesUtils.history.getNewQueryOptions();
|
let options = PlacesUtils.history.getNewQueryOptions();
|
||||||
options.expandQueries = 1;
|
options.expandQueries = 1;
|
||||||
let query = PlacesUtils.history.getNewQuery();
|
let query = PlacesUtils.history.getNewQuery();
|
||||||
query.setFolders([testRoot], 1);
|
query.setFolders([testRootId], 1);
|
||||||
let result = PlacesUtils.history.executeQuery(query, options);
|
let result = PlacesUtils.history.executeQuery(query, options);
|
||||||
let rootNode = result.root;
|
let rootNode = result.root;
|
||||||
rootNode.containerOpen = true;
|
rootNode.containerOpen = true;
|
||||||
|
|
@ -88,7 +91,7 @@ add_test(function test_savedsearches_bookmarks() {
|
||||||
|
|
||||||
// test that bookmark shows in query results
|
// test that bookmark shows in query results
|
||||||
var item = node.getChild(0);
|
var item = node.getChild(0);
|
||||||
do_check_eq(item.itemId, bookmarkId);
|
do_check_eq(item.bookmarkGuid, bookmark.guid);
|
||||||
|
|
||||||
// XXX - FAILING - test live-update of query results - add a bookmark that matches the query
|
// XXX - FAILING - test live-update of query results - add a bookmark that matches the query
|
||||||
// var tmpBmId = PlacesUtils.bookmarks.insertBookmark(
|
// var tmpBmId = PlacesUtils.bookmarks.insertBookmark(
|
||||||
|
|
@ -101,13 +104,18 @@ add_test(function test_savedsearches_bookmarks() {
|
||||||
// do_check_eq(query.childCount, 1);
|
// do_check_eq(query.childCount, 1);
|
||||||
|
|
||||||
// test live-update of query results - add a folder that matches the query
|
// test live-update of query results - add a folder that matches the query
|
||||||
PlacesUtils.bookmarks.createFolder(
|
await PlacesUtils.bookmarks.insert({
|
||||||
root, searchTerm + "zaa", PlacesUtils.bookmarks.DEFAULT_INDEX);
|
parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||||
|
title: searchTerm + "zaa",
|
||||||
|
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||||
|
});
|
||||||
do_check_eq(node.childCount, 1);
|
do_check_eq(node.childCount, 1);
|
||||||
// test live-update of query results - add a query that matches the query
|
// test live-update of query results - add a query that matches the query
|
||||||
PlacesUtils.bookmarks.insertBookmark(
|
await PlacesUtils.bookmarks.insert({
|
||||||
root, uri("place:terms=foo&excludeQueries=1&expandQueries=1&queryType=1"),
|
parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX, searchTerm + "blah");
|
title: searchTerm + "blah",
|
||||||
|
url: "place:terms=foo&excludeQueries=1&expandQueries=1&queryType=1",
|
||||||
|
});
|
||||||
do_check_eq(node.childCount, 1);
|
do_check_eq(node.childCount, 1);
|
||||||
}
|
}
|
||||||
rootNode.containerOpen = false;
|
rootNode.containerOpen = false;
|
||||||
|
|
@ -116,9 +124,7 @@ add_test(function test_savedsearches_bookmarks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the bookmark search
|
// delete the bookmark search
|
||||||
PlacesUtils.bookmarks.removeItem(searchId);
|
await PlacesUtils.bookmarks.remove(search);
|
||||||
|
|
||||||
run_next_test();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function test_savedsearches_history() {
|
add_task(async function test_savedsearches_history() {
|
||||||
|
|
@ -127,9 +133,11 @@ add_task(async function test_savedsearches_history() {
|
||||||
await PlacesTestUtils.addVisits({ uri: testURI, title: searchTerm });
|
await PlacesTestUtils.addVisits({ uri: testURI, title: searchTerm });
|
||||||
|
|
||||||
// create a saved-search that matches the visit we added
|
// create a saved-search that matches the visit we added
|
||||||
var searchId = PlacesUtils.bookmarks.insertBookmark(testRoot,
|
var searchItem = await PlacesUtils.bookmarks.insert({
|
||||||
uri("place:terms=" + searchTerm + "&excludeQueries=1&expandQueries=1&queryType=0"),
|
parentGuid: testRoot.guid,
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX, searchTerm);
|
title: searchTerm,
|
||||||
|
url: "place:terms=" + searchTerm + "&excludeQueries=1&expandQueries=1&queryType=0",
|
||||||
|
});
|
||||||
|
|
||||||
// query for the test root, expandQueries=1
|
// query for the test root, expandQueries=1
|
||||||
// the query should show up as a query container, with 1 child
|
// the query should show up as a query container, with 1 child
|
||||||
|
|
@ -137,7 +145,7 @@ add_task(async function test_savedsearches_history() {
|
||||||
var options = PlacesUtils.history.getNewQueryOptions();
|
var options = PlacesUtils.history.getNewQueryOptions();
|
||||||
options.expandQueries = 1;
|
options.expandQueries = 1;
|
||||||
var query = PlacesUtils.history.getNewQuery();
|
var query = PlacesUtils.history.getNewQuery();
|
||||||
query.setFolders([testRoot], 1);
|
query.setFolders([testRootId], 1);
|
||||||
var result = PlacesUtils.history.executeQuery(query, options);
|
var result = PlacesUtils.history.executeQuery(query, options);
|
||||||
var rootNode = result.root;
|
var rootNode = result.root;
|
||||||
rootNode.containerOpen = true;
|
rootNode.containerOpen = true;
|
||||||
|
|
@ -148,7 +156,7 @@ add_task(async function test_savedsearches_history() {
|
||||||
// test that query node type is container when expandQueries=1
|
// test that query node type is container when expandQueries=1
|
||||||
do_check_eq(node.type, node.RESULT_TYPE_QUERY);
|
do_check_eq(node.type, node.RESULT_TYPE_QUERY);
|
||||||
// test that queries (as containers) have valid itemId
|
// test that queries (as containers) have valid itemId
|
||||||
do_check_eq(node.itemId, searchId);
|
do_check_eq(node.bookmarkGuid, searchItem.guid);
|
||||||
node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||||
node.containerOpen = true;
|
node.containerOpen = true;
|
||||||
|
|
||||||
|
|
@ -177,26 +185,29 @@ add_task(async function test_savedsearches_history() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// test live-update of moved queries
|
// test live-update of moved queries
|
||||||
var tmpFolderId = PlacesUtils.bookmarks.createFolder(
|
let tmpFolder = await PlacesUtils.bookmarks.insert({
|
||||||
testRoot, "foo", PlacesUtils.bookmarks.DEFAULT_INDEX);
|
parentGuid: testRoot.guid,
|
||||||
PlacesUtils.bookmarks.moveItem(
|
title: "foo",
|
||||||
searchId, tmpFolderId, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||||
|
});
|
||||||
|
|
||||||
|
searchItem.parentGuid = tmpFolder.guid;
|
||||||
|
await PlacesUtils.bookmarks.update(searchItem);
|
||||||
var tmpFolderNode = rootNode.getChild(0);
|
var tmpFolderNode = rootNode.getChild(0);
|
||||||
do_check_eq(tmpFolderNode.itemId, tmpFolderId);
|
do_check_eq(tmpFolderNode.bookmarkGuid, tmpFolder.guid);
|
||||||
tmpFolderNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
tmpFolderNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||||
tmpFolderNode.containerOpen = true;
|
tmpFolderNode.containerOpen = true;
|
||||||
do_check_eq(tmpFolderNode.childCount, 1);
|
do_check_eq(tmpFolderNode.childCount, 1);
|
||||||
|
|
||||||
// test live-update of renamed queries
|
// test live-update of renamed queries
|
||||||
PlacesUtils.bookmarks.setItemTitle(searchId, "foo");
|
searchItem.title = "foo";
|
||||||
|
await PlacesUtils.bookmarks.update(searchItem);
|
||||||
do_check_eq(tmpFolderNode.title, "foo");
|
do_check_eq(tmpFolderNode.title, "foo");
|
||||||
|
|
||||||
// test live-update of deleted queries
|
// test live-update of deleted queries
|
||||||
PlacesUtils.bookmarks.removeItem(searchId);
|
await PlacesUtils.bookmarks.remove(searchItem);
|
||||||
try {
|
Assert.throws(() => tmpFolderNode = rootNode.getChild(1), /NS_ERROR_ILLEGAL_VALUE/,
|
||||||
tmpFolderNode = root.getChild(1);
|
"getting a deleted child should throw");
|
||||||
do_throw("query was not removed");
|
|
||||||
} catch (ex) {}
|
|
||||||
|
|
||||||
tmpFolderNode.containerOpen = false;
|
tmpFolderNode.containerOpen = false;
|
||||||
rootNode.containerOpen = false;
|
rootNode.containerOpen = false;
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,10 @@ add_task(async function test_removes_suggestion_if_its_content_is_typed_in() {
|
||||||
{content: "bar", description: "second suggestion"},
|
{content: "bar", description: "second suggestion"},
|
||||||
{content: "baz", description: "third suggestion"},
|
{content: "baz", description: "third suggestion"},
|
||||||
]);
|
]);
|
||||||
controller.stopSearch();
|
// The API doesn't have a way to notify when addition is complete.
|
||||||
|
do_timeout(1000, () => {
|
||||||
|
controller.stopSearch();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -302,8 +305,11 @@ add_task(async function test_setting_the_default_suggestion() {
|
||||||
emit(message, text, id) {
|
emit(message, text, id) {
|
||||||
if (message === ExtensionSearchHandler.MSG_INPUT_CHANGED) {
|
if (message === ExtensionSearchHandler.MSG_INPUT_CHANGED) {
|
||||||
ExtensionSearchHandler.addSuggestions(keyword, id, []);
|
ExtensionSearchHandler.addSuggestions(keyword, id, []);
|
||||||
|
// The API doesn't have a way to notify when addition is complete.
|
||||||
|
do_timeout(1000, () => {
|
||||||
|
controller.stopSearch();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
controller.stopSearch();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -358,7 +364,10 @@ add_task(async function test_maximum_number_of_suggestions_is_enforced() {
|
||||||
{content: "i", description: "ninth suggestion"},
|
{content: "i", description: "ninth suggestion"},
|
||||||
{content: "j", description: "tenth suggestion"},
|
{content: "j", description: "tenth suggestion"},
|
||||||
]);
|
]);
|
||||||
controller.stopSearch();
|
// The API doesn't have a way to notify when addition is complete.
|
||||||
|
do_timeout(1000, () => {
|
||||||
|
controller.stopSearch();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,16 @@ clang_checkers:
|
||||||
publish: !!bool yes
|
publish: !!bool yes
|
||||||
- name: clang-analyzer-security.*
|
- name: clang-analyzer-security.*
|
||||||
publish: !!bool no
|
publish: !!bool no
|
||||||
|
- name: misc-argument-comment
|
||||||
|
publish: !!bool yes
|
||||||
- name: misc-assert-side-effect
|
- name: misc-assert-side-effect
|
||||||
publish: !!bool yes
|
publish: !!bool yes
|
||||||
- name: misc-suspicious-missing-comma
|
- name: misc-suspicious-missing-comma
|
||||||
publish: !!bool yes
|
publish: !!bool yes
|
||||||
- name: misc-suspicious-semicolon
|
- name: misc-suspicious-semicolon
|
||||||
publish: !!bool yes
|
publish: !!bool yes
|
||||||
|
- name: misc-unused-using-decls
|
||||||
|
publish: !!bool yes
|
||||||
- name: modernize-avoid-bind
|
- name: modernize-avoid-bind
|
||||||
publish: !!bool yes
|
publish: !!bool yes
|
||||||
- name: modernize-loop-convert
|
- name: modernize-loop-convert
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue