merge mozilla-central to mozilla-inbound. CLOSED TREE

This commit is contained in:
Sebastian Hengst 2018-03-13 02:11:18 +02:00
Родитель 28138ddc8e 2f1fb39eee
Коммит 33c90f9938
70 изменённых файлов: 865 добавлений и 1346 удалений

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

@ -140,3 +140,4 @@ f7e9777221a34f9f23c2e4933307eb38b621b679 FIREFOX_NIGHTLY_57_END
1f91961bb79ad06fd4caef9e5dfd546afd5bf42c FIREFOX_NIGHTLY_58_END
5faab9e619901b1513fd4ca137747231be550def FIREFOX_NIGHTLY_59_END
e33efdb3e1517d521deb949de3fcd6d9946ea440 FIREFOX_BETA_60_BASE
fdd1a0082c71673239fc2f3a6a93de889c07a1be FIREFOX_NIGHTLY_60_END

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

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1443983: Removing addoncompat.manifest requires clobber.
Merge day clobber

14
Cargo.lock сгенерированный
Просмотреть файл

@ -665,7 +665,7 @@ dependencies = [
[[package]]
name = "geckodriver"
version = "0.19.1"
version = "0.20.0"
dependencies = [
"chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -673,12 +673,12 @@ dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mozprofile 0.3.0",
"mozrunner 0.5.0",
"mozversion 0.1.2",
"mozrunner 0.6.0",
"mozversion 0.1.3",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"webdriver 0.34.0",
"webdriver 0.35.0",
"zip 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1084,7 +1084,7 @@ dependencies = [
[[package]]
name = "mozrunner"
version = "0.5.0"
version = "0.6.0"
dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mozprofile 0.3.0",
@ -1093,7 +1093,7 @@ dependencies = [
[[package]]
name = "mozversion"
version = "0.1.2"
version = "0.1.3"
dependencies = [
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-ini 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1992,7 +1992,7 @@ dependencies = [
[[package]]
name = "webdriver"
version = "0.34.0"
version = "0.35.0"
dependencies = [
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",

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

@ -113,7 +113,7 @@ var tests = [
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
isnot(gBrowser.selectedTab, tab, "new tab isn't selected");
wrongBrowserNotificationObject.browser = gBrowser.getBrowserForTab(tab);
let promiseTopic = promiseTopicObserved("PopupNotifications-backgroundShow");
let promiseTopic = TestUtils.topicObserved("PopupNotifications-backgroundShow");
wrongBrowserNotification = showNotification(wrongBrowserNotificationObject);
await promiseTopic;
is(PopupNotifications.isPanelOpen, false, "panel isn't open");
@ -147,7 +147,7 @@ var tests = [
// test that the removed notification isn't shown on browser re-select
{ id: "Test#6",
async run() {
let promiseTopic = promiseTopicObserved("PopupNotifications-updateNotShowing");
let promiseTopic = TestUtils.topicObserved("PopupNotifications-updateNotShowing");
gBrowser.selectedTab = gBrowser.tabs[gBrowser.tabs.length - 1];
await promiseTopic;
is(PopupNotifications.isPanelOpen, false, "panel isn't open");

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

@ -43,7 +43,7 @@ var SidebarUtils = {
var openInTabs = isContainer &&
(aEvent.button == 1 ||
(aEvent.button == 0 && modifKey)) &&
PlacesUtils.hasChildURIs(tbo.view.nodeForTreeIndex(cell.row));
PlacesUtils.hasChildURIs(aTree.view.nodeForTreeIndex(cell.row));
if (aEvent.button == 0 && isContainer && !openInTabs) {
tbo.view.toggleOpenState(cell.row);

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

@ -11,7 +11,6 @@ support-files =
sidebarpanels_click_test_page.html
keyword_form.html
[browser_0_library_left_pane_migration.js]
[browser_addBookmarkForFrame.js]
[browser_bookmark_add_tags.js]
skip-if = (os == 'win' && ccov) # Bug 1423667
@ -104,6 +103,8 @@ skip-if = (os == 'win' && ccov) # Bug 1423667
[browser_remove_bookmarks.js]
skip-if = (os == 'win' && ccov) # Bug 1423667
subsuite = clipboard
[browser_sidebar_open_bookmarks.js]
skip-if = (os == 'win' && ccov) # Bug 1423667
[browser_sidebarpanels_click.js]
skip-if = (os == 'win' && ccov) || (os == "mac" && debug) # Bug 1423667
[browser_sort_in_library.js]

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

@ -1,87 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Test we correctly migrate Library left pane to the latest version.
* Note: this test MUST be the first between browser chrome tests, or results
* of next tests could be unexpected due to PlacesUIUtils getters.
*/
const TEST_URI = "http://www.mozilla.org/";
add_task(async function() {
ok(PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION > 0,
"Left pane version in chrome context, current version is: " + PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION );
// Check if we have any left pane folder already set, remove it eventually.
let leftPaneItems = PlacesUtils.annotations
.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
if (leftPaneItems.length > 0) {
// The left pane has already been created, touching it now would cause
// next tests to rely on wrong values (and possibly crash)
is(leftPaneItems.length, 1, "We correctly have only 1 left pane folder");
// Check version.
let version = PlacesUtils.annotations.getItemAnnotation(leftPaneItems[0],
PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
is(version, PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION, "Left pane version is actual");
ok(true, "left pane has already been created, skipping test");
return;
}
// Create a fake left pane folder with an old version (current version - 1).
let folder = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.rootGuid,
index: PlacesUtils.bookmarks.DEFAULT_INDEX,
type: PlacesUtils.bookmarks.TYPE_FOLDER,
title: ""
});
let folderId = await PlacesUtils.promiseItemId(folder.guid);
PlacesUtils.annotations.setItemAnnotation(folderId,
PlacesUIUtils.ORGANIZER_FOLDER_ANNO,
PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION - 1,
0,
PlacesUtils.annotations.EXPIRE_NEVER);
// Check fake left pane root has been correctly created.
leftPaneItems =
PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
is(leftPaneItems.length, 1, "We correctly have only 1 left pane folder");
is(leftPaneItems[0], folderId, "left pane root itemId is correct");
// Check version.
let version = PlacesUtils.annotations.getItemAnnotation(folderId,
PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
is(version, PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION - 1, "Left pane version correctly set");
// Open Library, this will upgrade our left pane version.
let organizer = await promiseLibrary();
// Check left pane.
ok(PlacesUIUtils.leftPaneFolderId > 0, "Left pane folder correctly created");
leftPaneItems =
PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
is(leftPaneItems.length, 1, "We correctly have only 1 left pane folder");
let leftPaneRoot = leftPaneItems[0];
is(leftPaneRoot, PlacesUIUtils.leftPaneFolderId,
"leftPaneFolderId getter has correct value");
// Check version has been upgraded.
version = PlacesUtils.annotations.getItemAnnotation(leftPaneRoot,
PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
is(version, PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION,
"Left pane version has been correctly upgraded");
// Check left pane is populated.
organizer.PlacesOrganizer.selectLeftPaneBuiltIn("History");
is(organizer.PlacesOrganizer._places.selectedNode.itemId,
PlacesUIUtils.leftPaneQueries.History,
"Library left pane is populated and working");
await promiseLibraryClosed(organizer);
});

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

@ -0,0 +1,68 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var gBms;
add_task(async function setup() {
gBms = await PlacesUtils.bookmarks.insertTree({
guid: PlacesUtils.bookmarks.unfiledGuid,
children: [{
title: "bm1",
url: "about:buildconfig"
}, {
title: "bm2",
url: "about:mozilla",
}]
});
registerCleanupFunction(async () => {
await PlacesUtils.bookmarks.eraseEverything();
});
});
add_task(async function test_open_bookmark_from_sidebar() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
await withSidebarTree("bookmarks", async (tree) => {
tree.selectItems([gBms[0].guid]);
let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser,
false, gBms[0].url
);
tree.controller.doCommand("placesCmd_open");
await loadedPromise;
// An assert to make the test happy.
Assert.ok(true, "The bookmark was loaded successfully.");
});
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_open_bookmark_folder_from_sidebar() {
await withSidebarTree("bookmarks", async (tree) => {
tree.selectItems([PlacesUtils.bookmarks.virtualUnfiledGuid]);
Assert.equal(tree.view.selection.getRangeCount(), 1,
"Should only have one range selected");
let loadedPromises = [];
for (let bm of gBms) {
loadedPromises.push(BrowserTestUtils.waitForNewTab(gBrowser,
bm.url, false, true));
}
synthesizeClickOnSelectedTreeCell(tree, {button: 1});
let tabs = await Promise.all(loadedPromises);
for (let tab of tabs) {
await BrowserTestUtils.removeTab(tab);
}
});
});

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

@ -2,7 +2,6 @@
support-files = head.js
[test_0_bug510634.xul]
[test_0_multiple_left_pane.xul]
[test_bug1163447_selectItems_through_shortcut.xul]
skip-if = (os == 'win' && ccov) # Bug 1423667
[test_bug427633_no_newfolder_if_noip.xul]

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

@ -1,78 +0,0 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!-- Bug 466422:
- Check that we replace the left pane with a correct one if it gets corrupted
- and we end up having more than one. -->
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Test handling of multiple left pane folders"
onload="runTest();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
</body>
<script type="application/javascript">
<![CDATA[
function runTest() {
SimpleTest.waitForExplicitFinish();
(async function() {
let fakeLeftPanes = [];
// We need 2 left pane folders to simulate a corrupt profile.
do {
let leftPaneItems = PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
// Create a fake left pane folder.
let folder = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.rootGuid,
index: PlacesUtils.bookmarks.DEFAULT_INDEX,
type: PlacesUtils.bookmarks.TYPE_FOLDER
});
let fakeLeftPaneRoot = await PlacesUtils.promiseItemId(folder.guid);
PlacesUtils.annotations.setItemAnnotation(fakeLeftPaneRoot, PlacesUIUtils.ORGANIZER_FOLDER_ANNO,
PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION, 0,
PlacesUtils.annotations.EXPIRE_NEVER);
fakeLeftPanes.push(folder.guid);
} while (fakeLeftPanes.length < 2);
// Initialize the left pane queries.
PlacesUIUtils.leftPaneFolderId;
// Check left pane.
ok(PlacesUIUtils.leftPaneFolderId > 0,
"Left pane folder correctly created");
let leftPaneItems = PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
is(leftPaneItems.length, 1,
"We correctly have only 1 left pane folder");
// Check that all old left pane items have been removed.
for (let guid of fakeLeftPanes) {
ok(!(await PlacesUtils.bookmarks.fetch({guid})), "This folder should have been removed");
}
})().then(() => SimpleTest.finish());
}
]]>
</script>
</window>

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

@ -1 +1 @@
60.0a1
61.0a1

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

@ -1 +1 @@
60.0a1
61.0a1

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

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
60.0a1
61.0a1

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

@ -2,6 +2,7 @@
tags = devtools
subsuite = devtools
support-files =
storage-blank.html
storage-cache-error.html
storage-complex-values.html
storage-cookies.html
@ -55,6 +56,7 @@ tags = usercontextid
[browser_storage_localstorage_add.js]
[browser_storage_localstorage_edit.js]
[browser_storage_localstorage_error.js]
[browser_storage_localstorage_rapid_add_remove.js]
[browser_storage_overflow.js]
[browser_storage_search.js]
[browser_storage_search_keyboard_trap.js]

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

@ -0,0 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* import-globals-from head.js */
// Basic test to check the rapid adding and removing of localStorage entries.
"use strict";
add_task(function* () {
yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-blank.html");
yield selectTreeItem(["localStorage", "http://test1.example.org"]);
ok(isTableEmpty(), "Table empty on init");
for (let i = 0; i < 10; i++) {
yield addRemove(`test${i}`);
}
yield finishTests();
});
function* addRemove(name) {
yield ContentTask.spawn(gBrowser.selectedBrowser, name, innerName => {
content.localStorage.setItem(innerName, "true");
content.localStorage.removeItem(innerName);
});
info("Waiting for store objects to be changed");
yield gUI.once("store-objects-edit");
ok(isTableEmpty(), `Table empty after rapid add/remove of "${name}"`);
}

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

@ -634,6 +634,17 @@ function getRowCells(id, includeHidden = false) {
return cells;
}
/**
* Check for an empty table.
*/
function isTableEmpty() {
let doc = gPanelWindow.document;
let table = gUI.table;
let cells = doc.querySelectorAll(".table-widget-column#" + table.uniqueId +
" .table-widget-cell");
return cells.length === 0;
}
/**
* Get available ids... useful for error reporting.
*/

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

@ -0,0 +1,9 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>storage-blank.html</h2>
</body>
</html>

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

@ -1,3 +1,3 @@
<out><div id="top" class="highlight" xmlns="http://www.w3.org/1999/xhtml"><link href="chrome://global/content/xml/XMLPrettyPrint.css" type="text/css" rel="stylesheet"/><div id="header"><p>
<out><div id="top" xmlns="http://www.w3.org/1999/xhtml"><link href="chrome://global/content/xml/XMLPrettyPrint.css" type="text/css" rel="stylesheet"/><div id="header"><p>
This XML file does not appear to have any style information associated with it. The document tree is shown below.
</p></div><div>&lt;<span class="start-tag">out</span>&gt;<span class="text">Here be sea hags</span>&lt;/<span class="end-tag">out</span>&gt;</div></div></out>
</p></div><main id="tree" class="highlight"><div>&lt;<span class="start-tag">out</span>&gt;<span class="text">Here be sea hags</span>&lt;/<span class="end-tag">out</span>&gt;</div></main></div></out>

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

@ -3,9 +3,8 @@
* 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/. */
@import url("chrome://global/content/xml/XMLPrettyPrint.css");
#top > .expander-open {
#tree,
.expandable-opening::-moz-list-bullet {
font-family: monospace;
white-space: pre;
}

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

@ -12,30 +12,36 @@
margin-bottom: 1em;
}
.expander-content {
padding-left: 1em;
#tree,
.expandable-children {
margin-inline-start: 1em;
}
.expander {
cursor: pointer;
-moz-user-select: none;
text-align: center;
vertical-align: top;
width: 1em;
.expandable-body {
display: inline-block;
margin-left: -1em;
}
#top > .expander-open, #top > .expander-closed {
margin-left: 1em;
.expandable-body[open] {
display: block;
}
.expander-closed > .expander-content {
display: none;
.expandable-opening {
list-style: '+' outside;
}
[open] > .expandable-opening {
list-style-type: '';
}
.expandable-opening::-moz-list-bullet {
cursor: pointer;
padding-inline-end: 2px;
/* Don't want to inherit the styling from pi and comment elements */
color: initial;
font: initial;
}
.comment {
font-family: monospace;
white-space: pre;
}

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

@ -8,29 +8,11 @@
<binding id="prettyprint" bindToUntrustedContent="true">
<content><html:div id='top' class="highlight"/>
<content><html:div id="top"/>
<html:span style="display: none;"><children/></html:span>
</content>
<handlers>
<handler event="click" button="0">
<![CDATA[
try {
var par = event.originalTarget;
if (par.nodeName == 'div' && par.className == 'expander') {
if (par.parentNode.className == 'expander-closed') {
par.parentNode.className = 'expander-open';
event.originalTarget.firstChild.data = '\u2212';
}
else {
par.parentNode.className = 'expander-closed';
event.originalTarget.firstChild.data = '+';
}
}
} catch (e) {
}
]]>
</handler>
<handler event="prettyprint-dom-created" allowuntrusted="false">
<![CDATA[
document.getAnonymousNodes(this).item(0).appendChild(event.detail);

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

@ -24,7 +24,9 @@
&xml.nostylesheet;
</p>
</div>
<xsl:apply-templates/>
<main id="tree" class="highlight">
<xsl:apply-templates/>
</main>
</xsl:template>
<xsl:template match="*">
@ -52,19 +54,23 @@
</xsl:template>
<xsl:template match="*[* or processing-instruction() or comment() or string-length(.) &gt; 50]">
<div class="expander-open">
<xsl:call-template name="expander"/>
<div>
<details open="" class="expandable-body">
<summary class="expandable-opening">
<xsl:text>&lt;</xsl:text>
<span class="start-tag"><xsl:value-of select="name(.)"/></span>
<xsl:apply-templates select="@*"/>
<xsl:text>&gt;</xsl:text>
</summary>
<xsl:text>&lt;</xsl:text>
<span class="start-tag"><xsl:value-of select="name(.)"/></span>
<xsl:apply-templates select="@*"/>
<xsl:text>&gt;</xsl:text>
<div class="expandable-children"><xsl:apply-templates/></div>
<div class="expander-content"><xsl:apply-templates/></div>
<xsl:text>&lt;/</xsl:text>
<span class="end-tag"><xsl:value-of select="name(.)"/></span>
<xsl:text>&gt;</xsl:text>
</details>
<span class="expandable-closing">
<xsl:text>&lt;/</xsl:text>
<span class="end-tag"><xsl:value-of select="name(.)"/></span>
<xsl:text>&gt;</xsl:text>
</span>
</div>
</xsl:template>
@ -92,15 +98,15 @@
</xsl:template>
<xsl:template match="processing-instruction()[string-length(.) &gt; 50]">
<div class="expander-open">
<xsl:call-template name="expander"/>
<span class="pi">
<xsl:text> &lt;?</xsl:text>
<xsl:value-of select="name(.)"/>
</span>
<div class="expander-content pi"><xsl:value-of select="."/></div>
<span class="pi">
<div class="pi">
<details open="" class="expandable-body">
<summary class="expandable-opening">
<xsl:text>&lt;?</xsl:text>
<xsl:value-of select="name(.)"/>
</summary>
<div class="expandable-children"><xsl:value-of select="."/></div>
</details>
<span class="expandable-closing">
<xsl:text>?&gt;</xsl:text>
</span>
</div>
@ -115,23 +121,19 @@
</xsl:template>
<xsl:template match="comment()[string-length(.) &gt; 50]">
<div class="expander-open">
<xsl:call-template name="expander"/>
<span class="comment">
<xsl:text>&lt;!--</xsl:text>
</span>
<div class="expander-content comment">
<xsl:value-of select="."/>
</div>
<span class="comment">
<div class="comment">
<details open="" class="expandable-body">
<summary class="expandable-opening">
<xsl:text>&lt;!--</xsl:text>
</summary>
<div class="expandable-children">
<xsl:value-of select="."/>
</div>
</details>
<span class="expandable-closing">
<xsl:text>--&gt;</xsl:text>
</span>
</span>
</div>
</xsl:template>
<xsl:template name="expander">
<div class="expander">&#x2212;</div>
</xsl:template>
</xsl:stylesheet>

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

@ -3741,7 +3741,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
nsDisplayList list;
nsDisplayList extraPositionedDescendants;
const ActiveScrolledRoot* wrapListASR = aBuilder->CurrentActiveScrolledRoot();
const ActiveScrolledRoot* wrapListASR;
bool canSkipWrapList = false;
if (isStackingContext) {
if (effects->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {

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

@ -3998,7 +3998,6 @@ protected:
typedef class mozilla::layers::ImageLayer ImageLayer;
bool CanBuildWebRenderDisplayItems(LayerManager* aManager);
bool TryOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder);
nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrameForBounds = nullptr);

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

@ -182,7 +182,7 @@ public final class NotificationClient implements NotificationListener {
if (ongoing != isOngoing(mNotifications.get(name))) {
// In order to change notification from ongoing to non-ongoing, or vice versa,
// we have to remove the previous notification, because ongoing notifications
// use a different id value than non-ongoing notifications.
// might use a different id value than non-ongoing notifications.
onNotificationClose(name);
}
@ -200,6 +200,8 @@ public final class NotificationClient implements NotificationListener {
// Shortcut to update the current foreground notification, instead of
// going through the service.
mNotificationManager.notify(R.id.foregroundNotification, notification);
} else {
mNotificationManager.notify(name, 0, notification);
}
}
@ -317,6 +319,10 @@ public final class NotificationClient implements NotificationListener {
for (final String name : mNotifications.keySet()) {
final Notification notification = mNotifications.get(name);
if (isOngoing(notification)) {
// The same reasoning as above applies - the current foreground notification
// uses a special ID, so we need to close its old instantiation and then
// re-add it with the new ID through the NotificationService.
onNotificationClose(name);
setForegroundNotificationLocked(name, notification);
return;
}

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

@ -62,7 +62,7 @@ class GentooBootstrapper(StyloInstall, BaseBootstrapper):
# configuration files and doing so without user supervision is dangerous
self.run_as_root(['emerge', '--noreplace', '--quiet',
'--autounmask-continue', '--ask',
'=dev-java/oracle-jdk-bin-1.8.0.162'])
'=dev-java/oracle-jdk-bin-1.8.0.162-r1'])
from mozboot import android
android.ensure_android('linux', artifact_mode=artifact_mode,

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

@ -1163,4 +1163,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1529264935824000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1529351485588000);

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

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

@ -8,7 +8,7 @@
/*****************************************************************************/
#include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1531684123172000);
const PRTime gPreloadListExpirationTime = INT64_C(1531770672720000);
%%
0-1.party, 1
0.me.uk, 1
@ -178,6 +178,8 @@ const PRTime gPreloadListExpirationTime = INT64_C(1531684123172000);
1359826938.rsc.cdn77.org, 1
135vv.com, 1
13826145000.com, 1
1391kj.com, 1
1395kj.com, 1
1396.net, 1
13th-dover.uk, 1
1453914078.rsc.cdn77.org, 1
@ -228,6 +230,7 @@ const PRTime gPreloadListExpirationTime = INT64_C(1531684123172000);
19hundert84.de, 1
1a-diamantscheiben.de, 1
1a-vermessung.at, 1
1a-werkstattgeraete.de, 1
1aim.com, 1
1cover.co.nz, 1
1cover.com.au, 1
@ -881,7 +884,6 @@ accudraftpaintbooths.com, 1
accuritconsulting.com, 1
accuritpresence.com, 1
accwing.com, 1
aceadvisory.biz, 1
aceanswering.com, 1
acecerts.co.uk, 1
acecolleges.edu.au, 1
@ -1246,7 +1248,6 @@ agiley.se, 1
agilob.net, 1
aging.gov, 1
agingstop.net, 1
agonswim.com, 0
agoodmind.com, 1
agoravm.tk, 1
agoravox.fr, 1
@ -2098,6 +2099,7 @@ annuaire-photographe.fr, 0
anohana.org, 1
anojan.com, 1
anon-next.de, 1
anonboards.com, 1
anoncom.net, 1
anoneko.com, 1
anongoth.pl, 1
@ -2247,7 +2249,6 @@ apk.li, 1
apk4fun.com, 1
apkoyunlar.club, 1
apkriver.com, 1
apl2bits.net, 1
aplikaceproandroid.cz, 1
aplis-online.de, 0
aplpackaging.co.uk, 1
@ -2323,7 +2324,6 @@ apptoutou.com, 1
appuals.com, 1
appui-de-fenetre.fr, 1
appveyor.com, 1
appzoojoo.be, 1
aprefix.com, 1
apretatuercas.es, 1
aprovpn.com, 1
@ -2419,7 +2419,7 @@ arenns.com, 1
arent.kz, 1
arenzanaphotography.com, 1
areqgaming.com, 1
ares-trading.de, 0
ares-trading.de, 1
arethsu.se, 1
arfad.ch, 1
arg.zone, 1
@ -2511,6 +2511,7 @@ arsk1.com, 1
art-et-culture.ch, 1
artansoft.com, 1
artboja.com, 1
artbytik.ru, 1
artdeco-photo.com, 1
artea.ga, 1
arteaga.co.uk, 1
@ -2890,7 +2891,6 @@ auto-anleitung.de, 1
auto-motor-i-sport.pl, 1
auto-plus.tn, 1
autoauctionsohio.com, 1
autoauctionsvirginia.com, 1
autobedrijfschalkoort.nl, 1
autoclean-plus.ch, 1
autocmall.com, 1
@ -4029,6 +4029,7 @@ biboumail.fr, 1
bibuch.com, 1
bicecontracting.com, 1
bicha.net, 1
bichines.es, 1
bichonfrise.com.br, 1
bichonmaltes.com.br, 1
bicranial.io, 1
@ -4304,6 +4305,7 @@ bituptick.com, 1
bitvegas.com, 1
bitvest.io, 1
bitwolk.nl, 1
bitwrought.net, 1
bitxel.com.co, 1
bityes.org, 1
biurokarier.edu.pl, 1
@ -5223,7 +5225,6 @@ bubhub.io, 1
buch-angucken.de, 1
buchverlag-scholz.de, 1
buck.com, 1
buckmulligans.com, 1
buckypaper.com, 1
budaev-shop.ru, 1
buddhismus.net, 1
@ -5439,7 +5440,6 @@ byronwade.com, 1
byrtz.de, 1
bysb.net, 1
byte-time.com, 1
byte128.com, 1
bytearts.net, 1
bytebucket.org, 1
bytecode.no, 1
@ -5488,7 +5488,6 @@ c4539.com, 1
c4k3.net, 1
c7dn.com, 1
ca-key.de, 1
ca-terminal-multiservices.fr, 1
ca.gparent.org, 1
ca.search.yahoo.com, 0
ca5.de, 1
@ -5932,6 +5931,7 @@ cave-reynard.ch, 1
cavevinsdefrance.fr, 1
cavzodiaco.com.br, 1
caylercapital.com, 1
cayounglab.co.jp, 1
cazaviajes.es, 1
cazes.info, 1
cb-crochet.com, 1
@ -6106,6 +6106,7 @@ cfan.space, 1
cfh.com, 1
cfneia.org, 1
cfno.org, 1
cfo.gov, 1
cfpa-formation.fr, 1
cfsh.tk, 1
cftcarouge.com, 1
@ -6617,7 +6618,7 @@ cirugiasplasticas.com.mx, 1
cirujanooral.com, 1
cirurgicagervasio.com.br, 1
cirurgicalucena.com.br, 1
ciscodude.net, 1
ciscodude.net, 0
cisoaid.com, 1
ciss.ltd, 1
cisy.me, 1
@ -6846,7 +6847,6 @@ clownish.co.il, 1
cloxy.com, 1
clr3.com, 1
clsimage.com, 1
clsimplex.com, 1
clsoft.ch, 1
clu-in.org, 1
club-duomo.com, 1
@ -7320,9 +7320,11 @@ constructive.men, 1
consul.io, 1
consultcelerity.com, 1
consultingroupitaly.com, 1
consultorcr.net, 1
consultpetkov.com, 1
consumer.gov, 1
consumeractionlawgroup.com, 1
consumerfiles.com, 1
consumersentinel.gov, 1
consumidor.gov, 1
consuwijzer.nl, 1
@ -7402,7 +7404,6 @@ copycrafter.net, 1
copypoison.com, 1
copyright-watch.org, 1
copytrack.com, 1
corbax.com, 1
corbi.net.au, 1
corbinhesse.com, 1
cordeydesign.ch, 1
@ -7466,7 +7467,6 @@ cosirex.com, 1
coslinker.com, 1
cosmechic.fr, 1
cosmeticappraisal.com, 1
cosmeticasimple.com, 1
cosmeticos-naturales.com, 1
cosmeticosdelivery.com.br, 1
cosmeticosnet.com.br, 1
@ -7580,6 +7580,7 @@ craigsimpson.scot, 1
craigwfox.com, 1
cralarm.de, 1
crandall.io, 1
cranems.com.ua, 1
cranesafe.com, 1
cranforddental.com, 1
crapouill.es, 1
@ -7774,7 +7775,6 @@ cryptoparty.at, 1
cryptoparty.dk, 1
cryptopartynewcastle.org, 1
cryptopartyutah.org, 1
cryptophobia.nl, 0
cryptorival.com, 1
cryptoseb.pw, 1
cryptoshot.pw, 1
@ -7813,7 +7813,7 @@ csmainframe.com, 1
csokolade.hu, 1
csp.ch, 1
cspeti.hu, 1
cspvalidator.org, 0
cspvalidator.org, 1
csru.net, 1
css.direct, 1
css.net, 1
@ -8410,7 +8410,7 @@ dawoud.org, 1
dawson-floridavilla.co.uk, 1
day-peak.com, 1
daylightpirates.org, 1
dayman.net, 0
dayman.net, 1
days.one, 1
daysoftheyear.com, 1
db-sanity.com, 1
@ -8878,7 +8878,6 @@ devzero.io, 1
dewaard.de, 1
dewalch.net, 1
dewapress.com, 1
dewebwerf.nl, 1
dewinter.com, 1
dexalo.de, 1
dezeregio.nl, 1
@ -9440,7 +9439,7 @@ domytermpaper.com, 1
domythesis.net, 1
domyzitrka.cz, 1
donabeneko.jp, 1
donateaday.net, 0
donateaday.net, 1
donfelino.tk, 0
dongkexue.com, 1
dongxuwang.com, 1
@ -9678,6 +9677,7 @@ drjenafernandez.com, 1
drjoe.ca, 1
drjuanitacollier.com, 1
drkhsh.at, 1
drkmtrx.xyz, 1
drlangsdon.com, 1
drmayakato.com, 1
drmcdaniel.com, 1
@ -9849,6 +9849,7 @@ dustygroove.com, 1
dustyspokesbnb.ca, 1
dutch.desi, 1
dutch1.nl, 1
dutchessuganda.com, 1
dutchrank.nl, 1
dutchwanderers.nl, 1
dutchweballiance.nl, 1
@ -9978,6 +9979,7 @@ eames-clayton.us, 1
eapestudioweb.com, 1
earl.org.uk, 1
earlyyearshub.com, 1
earmarks.gov, 1
earn.com, 1
earth-people.org, 1
earthsystemprediction.gov, 1
@ -11982,13 +11984,13 @@ filhin.es, 1
filhodohomem.com, 1
filhomes.ph, 1
fili.org, 1
filidorwiese.nl, 1
filingsmadeeasy.com, 1
filip-prochazka.com, 1
filippo.io, 1
filipsebesta.com, 1
filleritemsindia.com, 1
fillitupchallenge.eu, 1
fillmysuitca.se, 1
fillo.sk, 1
film-tutorial.com, 1
film.photography, 1
@ -13037,7 +13039,6 @@ gamblersgaming.eu, 1
game-files.net, 0
game-gentle.com, 1
game7.de, 1
gamebits.net, 1
gamebrott.com, 1
gamecard-shop.nl, 1
gamecdn.com, 1
@ -13618,6 +13619,7 @@ glenshere.com, 1
glidingshop.cz, 1
glidingshop.de, 1
glidingshop.eu, 1
glittersjabloon.nl, 1
glloq.org, 1
glob-coin.com, 1
global-adult-webcams.com, 1
@ -13661,6 +13663,7 @@ glueckskindter.de, 1
glutenfreelife.co.nz, 1
glyph.ws, 1
glyxins.com, 1
gm-assicurazioni.it, 1
gm.search.yahoo.com, 0
gmail.com, 0
gmantra.org, 1
@ -13816,7 +13819,6 @@ gorognyelv.hu, 1
gorschenin.com, 1
gosccs.com, 1
gosciencegirls.com, 1
gosharewood.com, 1
goshawkdb.io, 1
goshin-group.co.jp, 1
gospelfollower.com, 1
@ -13913,6 +13915,7 @@ grandcastles.co.uk, 1
grandchamproofing.com, 1
grandchene.ch, 1
grande.coffee, 1
grandefratellonews.com, 1
grandeto.com, 1
grandjunctionbrewing.com, 1
grandmasfridge.org, 1
@ -14298,6 +14301,7 @@ hachre.de, 1
hack.club, 1
hack.cz, 1
hackademix.net, 1
hackanders.com, 1
hackattack.com, 1
hackbarth.guru, 1
hackbeil.name, 1
@ -15684,7 +15688,7 @@ icsadviseurs.nl, 1
icsfinomornasco.gov.it, 1
icsfinomornasco.it, 1
ict-concept.nl, 0
ict-crew.nl, 0
ict-crew.nl, 1
ict-radar.com, 1
ict-radar.nl, 1
ictcareer.ch, 1
@ -16429,6 +16433,7 @@ invisibles.ch, 1
invisionita.com, 1
invisiverse.com, 1
invitescene.com, 1
invitethemhome.com, 1
invkao.com, 1
invoiced.com, 1
invoicefinance.com, 1
@ -16486,7 +16491,6 @@ iplog.info, 1
ipmonitoring.hu, 1
ipmotion.ca, 1
ipnetworking.net, 1
ipo-times.com, 1
ipokabu.net, 1
ipomue.com, 0
ipop.gr, 1
@ -16512,7 +16516,6 @@ ir1s.com, 1
iranianholiday.com, 1
irayo.net, 1
irc-results.com, 1
ircmett.de, 1
iready.ro, 1
ireef.tv, 1
irenekauer.com, 1
@ -16691,6 +16694,7 @@ itchimes.com, 1
itchy.nl, 1
itchybrainscentral.com, 1
itcko.sk, 1
itdashboard.gov, 1
itds-consulting.com, 1
itds-consulting.cz, 1
itds-consulting.eu, 1
@ -16706,7 +16710,6 @@ itfh.eu, 1
itfix.cz, 1
itforge.nl, 1
ithenrik.com, 1
itilo.de, 1
itiomassagem.com.br, 1
itis.gov, 1
itis4u.ch, 1
@ -16916,7 +16919,7 @@ jamesheald.com, 1
jameshemmings.co.uk, 1
jameshost.net, 1
jameshunt.us, 0
jamesj.me, 1
jamesj.me, 0
jamesknd.uk, 0
jamesmarsh.net, 1
jamesmcdonald.com, 0
@ -17158,6 +17161,7 @@ jet-stream.fr, 1
jetapi.org, 1
jetbbs.com, 1
jetbrains.pw, 1
jetflex.de, 1
jetkittens.co.uk, 1
jetmirshatri.com, 1
jetsetboyz.net, 1
@ -17224,7 +17228,6 @@ jino-jossy.appspot.com, 1
jinshuju.net, 1
jintaiyang123.org, 1
jiogo.com, 1
jiosongs.com, 1
jirav.com, 1
jiripudil.cz, 1
jiveiaktivno.bg, 1
@ -17565,7 +17568,6 @@ jugendsuenden.info, 1
jugh.de, 1
juhakoho.com, 1
juice.codes, 1
juiced.gs, 1
juku-info.top, 1
juku-wing.jp, 1
jule-spil.dk, 1
@ -18076,7 +18078,6 @@ ketosecology.co.uk, 1
kettner.com, 1
ketty-voyance.com, 1
kevinapease.com, 1
kevinbowers.me, 1
kevincox.ca, 0
kevindekoninck.com, 0
kevinfoley.cc, 1
@ -18305,6 +18306,7 @@ kiwipayments.com, 1
kiwiplace.com, 1
kj-prince.com, 1
kj1396.net, 1
kj1397.com, 1
kjaer.io, 1
kjarni.cc, 1
kjarrval.is, 1
@ -18839,7 +18841,6 @@ la-cave-a-nodo.fr, 1
la-compagnie-des-elfes.fr, 1
la-ganiere.com, 1
la-maison.ch, 1
la-maison.eu, 1
la-petite-entreprise.com, 1
la-tourmaline.ch, 1
laassari.me, 1
@ -18907,7 +18908,6 @@ lagerauftrag.info, 1
lagit.in, 1
laglab.org, 0
laguiadelvaron.com, 1
laguinguette.fr, 1
lahora.com.ec, 1
lain.at, 1
laindonleisure.co.uk, 1
@ -19357,7 +19357,6 @@ leowkahman.com, 1
lep.gov, 1
lepenetapeti.com, 1
lepiquillo.fr, 1
leponton-lorient.fr, 1
leprado.com, 1
lepsos.com, 1
lereporter.ma, 1
@ -19713,7 +19712,6 @@ lionlyrics.com, 1
lionsdeal.com, 1
lipartydepot.com, 1
lipex.com, 1
lipo.lol, 1
lipoabaltimore.org, 1
liqd.net, 1
liquid.cz, 1
@ -20251,7 +20249,6 @@ lunidea.ch, 1
lunidea.com, 1
lunight.ml, 1
lunis.net, 1
lunix.io, 1
lunorian.is, 1
luoe.me, 1
luoh.cc, 1
@ -20813,7 +20810,6 @@ marlonschultz.de, 1
marlosoft.net, 1
marmolesromero.com, 1
marmotte.love, 1
maroc-bivouac.com, 1
marocemploi.co, 1
marocmail.ma, 1
marotero.com, 1
@ -20856,7 +20852,6 @@ maru-life.com, 1
maruhoi.com, 1
marustat.ru, 1
marvelmoviemarathon.com, 1
marvinkeller.de, 1
marxist.party, 1
marxmyths.org, 1
maryeclark.com, 1
@ -20978,7 +20973,7 @@ matthiasott.com, 1
matthiasschwab.de, 1
matthiasweiler.de, 0
matthieuschlosser.fr, 1
matthijssen.info, 0
matthijssen.info, 1
mattia98.org, 1
mattiascibien.net, 1
mattisam.com, 1
@ -21005,6 +21000,7 @@ mawidabp.com, 1
mawidaca.com, 1
max-moeglich.de, 1
max-went.pl, 1
max.gov, 1
maxbruckner.de, 1
maxbruckner.org, 1
maxbytes.nl, 0
@ -21218,7 +21214,6 @@ medicinia.com.br, 1
medicinskavranje.edu.rs, 1
medicocompetente.it, 1
medicoresponde.com.br, 1
medifab.online, 1
medifi.com, 1
medigap-quote.net, 1
medinside.ch, 1
@ -21640,6 +21635,7 @@ mike2k.de, 1
mikebelanger.ca, 1
mikeblog.site, 1
mikecb.org, 1
mikedugan.org, 1
mikegarnett.co.uk, 1
mikegerwitz.com, 1
mikehamburg.com, 1
@ -22054,7 +22050,6 @@ molti.hu, 1
molunerfinn.com, 1
molwick.com, 1
momentumdash.com, 1
momfulfilled.com, 1
momirfarooq.com, 1
momozeit.de, 1
momstableonline.com, 1
@ -22233,7 +22228,6 @@ motorbiketourhanoi.com, 1
motorpointarenacardiff.co.uk, 1
motorring.ru, 1
motorsplus.com, 0
motorsportdiesel.com, 1
motoryachtclub-radolfzell.de, 1
motosikletevi.com, 1
motostorie.blog, 0
@ -22292,6 +22286,7 @@ mpetroff.net, 1
mpg-universal.com, 1
mpg.ovh, 1
mpi-sa.fr, 1
mpintaamalabanna.it, 1
mplanetphl.fr, 1
mplant.io, 1
mplicka.cz, 1
@ -23013,7 +23008,6 @@ navstevnik.sk, 1
navycs.com, 1
nawir.de, 1
nawroth.info, 1
nay.moe, 1
nayahe.ru, 1
nayanaas.com, 1
nazevfirmy.cz, 1
@ -24348,6 +24342,7 @@ onlinelegalmarketing.com, 1
onlinelegalmedia.com, 1
onlinelighting.com.au, 1
onlinemarketingtraining.co.uk, 1
onlinepokerspelen.be, 1
onlinerollout.de, 1
onlinestoreninjas.com, 1
onlineth.com, 0
@ -24935,7 +24930,6 @@ pardnoy.com, 1
parentheseardenne.be, 1
parentinterview.com, 1
parentsintouch.co.uk, 1
parfum-baza.ru, 1
pariga.co.uk, 1
paris-store.com, 1
parisderriere.fr, 1
@ -25003,7 +24997,6 @@ pascal-bourhis.com, 1
pascal-bourhis.net, 1
pascal-kannchen.de, 1
pascal-wittmann.de, 1
pascaline-jouis.fr, 1
pascalleguern.com, 1
pascalmathis.com, 1
pascalmathis.me, 1
@ -25148,6 +25141,7 @@ paylike.io, 1
payloc.io, 1
payme.uz, 1
payment-network.com, 1
paymentaccuracy.gov, 1
payments.google.com, 1
paymerang.com, 1
paymill.com, 1
@ -25730,7 +25724,6 @@ pixelrain.info, 1
pixelsquared.us, 1
pixelurbia.com, 1
pixelution.at, 1
pixiv.cat, 1
pixiv.moe, 1
pixivimg.me, 1
pixlfox.com, 0
@ -26675,7 +26668,6 @@ psychoco.net, 1
psychotherapie-kp.de, 1
psydix.org, 1
psyk.yt, 1
psylab.cc, 1
psylab.re, 1
psylab.vip, 1
psynapse.net.au, 1
@ -28268,6 +28260,7 @@ rulu.tv, 1
rulutv.com, 1
rumlager.de, 1
rummel-platz.de, 1
rumplesinflatables.co.uk, 1
rumtaste.com, 1
rumtaste.de, 1
run-forrest.run, 1
@ -28333,7 +28326,7 @@ ryanbritton.com, 1
ryancarter.co.uk, 1
ryanhowell.io, 0
ryankearney.com, 0
ryanmcdonough.co.uk, 1
ryanmcdonough.co.uk, 0
ryansmithphotography.com, 1
ryazan-region.ru, 1
rybox.info, 1
@ -28785,7 +28778,7 @@ schlabbi.com, 0
schlachter.ca, 1
schlafguru.com, 1
schlagenhauf.info, 1
schlagma.de, 1
schlagma.de, 0
schlarp.com, 1
schlechtewitze.com, 1
schlossereieder.at, 1
@ -28831,7 +28824,6 @@ schrauger.info, 1
schrauger.net, 1
schrauger.org, 1
schrauger.run, 1
schraugerrun.com, 1
schreibers.ca, 1
schreinerei-jahreis.de, 1
schreinerei-wortmann.de, 1
@ -29217,6 +29209,7 @@ sementes.gratis, 1
semianalog.com, 1
seminariruum.ee, 1
semiocast.com, 1
semjonov.de, 1
semmlers.com, 1
semox.de, 1
semps-2fa.de, 1
@ -29749,7 +29742,7 @@ silentkernel.fr, 0
silentmode.com, 1
silentundo.org, 1
silerfamily.net, 1
siliconchip.me, 0
siliconchip.me, 1
silkebaekken.no, 1
sillisalaatti.fi, 1
sillysnapz.co.uk, 1
@ -30214,6 +30207,7 @@ smartandcom.ch, 1
smartandhappychild.ro, 1
smartbiz.vn, 1
smartcheck.gov, 1
smartcleaningcenter.nl, 1
smartcpa.ca, 1
smarterskies.gov, 1
smartest-trading.com, 1
@ -30679,7 +30673,6 @@ speechndraw.com, 1
speeddate.it, 0
speedof.me, 1
speedracer.ca, 1
speeds.vip, 1
speedsportofhull.co.uk, 1
speedtailors.com, 1
speedtest-russia.com, 1
@ -31012,6 +31005,7 @@ startuppeople.co.uk, 1
startupum.ru, 1
starwatches.eu, 1
starwins.co.uk, 1
stassi.ch, 1
stastka.ch, 1
stat.ink, 1
state-of-body-and-mind.com, 1
@ -31200,7 +31194,6 @@ stitchfiddle.com, 1
stivesbouncycastlehire.co.uk, 1
stjohnin.com, 1
stjohnmiami.org, 1
stjohnsc.com, 1
stlu.de, 1
stlucasmuseum.org, 1
stlukesbrandon.org, 1
@ -31965,6 +31958,7 @@ taunhanh.us, 1
tavolaquadrada.com.br, 1
tavsys.net, 1
taxaroo.com, 1
taxi-24std.de, 1
taxi-chamonix.fr, 1
taxi-collectif.ch, 1
taxi-puck.pl, 1
@ -32127,7 +32121,7 @@ techshift.eu, 1
techshift.nl, 1
techshift.se, 1
techtalks.no, 1
techtuts.info, 0
techtuts.info, 1
techunit.org, 1
techvalue.gr, 1
techviewforum.com, 1
@ -32845,7 +32839,6 @@ ticketsvergleichen.de, 1
tickit.ca, 1
tid.jp, 1
tidycustoms.net, 1
tie-online.org, 1
tielectric.ch, 1
tiendafetichista.com, 1
tiendavertigo.com, 1
@ -33000,7 +32993,6 @@ tkn.tokyo, 1
tkts.cl, 1
tkusano.jp, 1
tkw01536.de, 1
tlach.cz, 1
tlca.org, 1
tlcnet.info, 1
tlehseasyads.com, 1
@ -33939,7 +33931,7 @@ u2fsecuritykeys.com, 1
u4mh-dev-accesscontroller.azurewebsites.net, 1
u4mh-dev-portal.azurewebsites.net, 1
u5b.de, 0
u5r.nl, 0
u5r.nl, 1
ua.search.yahoo.com, 0
uae-company-service.com, 1
uahs.org.uk, 1
@ -34007,7 +33999,6 @@ uiberlay.cz, 1
uicchy.com, 1
uiop.link, 1
uitgeverij-deviant.nl, 1
uitslagensoftware.nl, 1
ujob.com.cn, 1
uk.dating, 1
uk.search.yahoo.com, 0
@ -34324,6 +34315,7 @@ uspsoig.gov, 1
ussm.gov, 1
ussuka.com, 1
ust.space, 1
ustr.gov, 0
usualbeings.com, 1
uswitch.com, 1
ut-addicted.com, 1
@ -34809,7 +34801,6 @@ vinicius.sl, 1
vinilosdecorativos.net, 1
vinner.com.au, 1
vinnie.gq, 1
vinogradovka.com, 1
vinolli.de, 1
vinovum.net, 1
vintagebandfestival.org, 1
@ -34909,6 +34900,7 @@ vivamusic.es, 1
vivanosports.com.br, 1
vivatv.com.tw, 1
vivendi.de, 1
vivianmaier.cn, 1
vivid-academy.com, 1
vividinflatables.co.uk, 1
vividlumen.com, 1
@ -34990,9 +34982,11 @@ volcain.io, 1
volcanconcretos.com, 1
volga.us, 1
volgavibes.ru, 0
voliere-info.nl, 0
volker-gropp.de, 1
volkergropp.de, 1
volkerwesselstransfer.nl, 1
volkerwesselswave.nl, 1
volkswurst.de, 1
vollans.id.au, 1
voloevents.com, 1
@ -35020,7 +35014,7 @@ vorodevops.com, 1
vos-fleurs.ch, 1
vos-fleurs.com, 1
vosgym.jp, 1
voshod.org, 0
voshod.org, 1
vosjesweb.nl, 1
vosky.fr, 1
vosn.de, 1
@ -35224,7 +35218,6 @@ waonui.io, 1
warcraftjournal.org, 1
wardow.com, 1
warebouncycastles.co.uk, 1
warekit.io, 1
warekon.com, 1
warekon.dk, 1
warenits.at, 1
@ -35513,12 +35506,10 @@ wegotcookies.com, 1
wegvielfalt.de, 1
wehostdnn.com, 1
weibomiaopai.com, 1
weicn.org, 1
weideheuvel.org, 1
weidmannfibertechnology.com, 1
weien.org, 1
weigelia.nl, 1
weightreviews.com, 1
weiji.ga, 1
weiler.xyz, 0
weils.net, 1
@ -35777,7 +35768,6 @@ wickrath.net, 1
widdleguy.com, 1
wideboxmacau.com, 0
widegab.com, 1
wideinfo.org, 1
widemann.de, 1
widememory.com, 1
widmer.bz, 1
@ -36063,10 +36053,8 @@ wootware.co.za, 1
worcade.net, 1
worcesterbouncycastlehire.co.uk, 1
worcesterbouncycastles.co.uk, 1
worcesterdance.org, 1
worcesterfestival.co.uk, 1
word-grabber.com, 1
wordbits.net, 1
wordcounter.net, 1
wordher.com, 1
wordlessecho.com, 1
@ -36462,7 +36450,6 @@ xin-in.com, 1
xin-in.net, 1
xing-in.net, 1
xing.ml, 1
xingiahanvisa.net, 1
xiqi.us, 1
xirion.net, 1
xiyu.it, 0
@ -37341,7 +37328,6 @@ zokster.net, 1
zolokar.xyz, 1
zombiesecured.com, 1
zomerschoen.nl, 1
zonadebolsa.es, 1
zone-produkte.de, 0
zone39.com, 1
zonecb.com, 1

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

@ -8,7 +8,7 @@ for (let [key, val] of Object.entries({
// Don't manually modify this line, as it is automatically replaced on merge day
// by the gecko_migration.py script.
WEAVE_VERSION: "1.62.0",
WEAVE_VERSION: "1.63.0",
// Sync Server API version that the client supports.
SYNC_API_VERSION: "1.5",

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

@ -200,131 +200,6 @@ function setAnnoUnchecked(itemId, name, value, type) {
);
}
add_task(async function test_leftPaneFolder() {
_("Ensure we never track left pane roots");
try {
await startTracking();
// Creates the organizer queries as a side effect.
let leftPaneId = PlacesUIUtils.maybeRebuildLeftPane();
_(`Left pane root ID: ${leftPaneId}`);
{
await PlacesTestUtils.promiseAsyncUpdates();
let changes = await tracker.getChangedIDs();
deepEqual(changes, {}, "New left pane queries should not be tracked");
Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
}
_("Reset synced bookmarks to simulate a disconnect");
await PlacesSyncUtils.bookmarks.reset();
{
await PlacesTestUtils.promiseAsyncUpdates();
let changes = await tracker.getChangedIDs();
deepEqual(Object.keys(changes).sort(), ["menu", "mobile", "toolbar", "unfiled"],
"Left pane queries should not be tracked after reset");
Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
await PlacesTestUtils.markBookmarksAsSynced();
}
// The following tests corrupt the left pane queries in different ways.
// `PlacesUIUtils.maybeRebuildLeftPane` will rebuild the entire root, but
// none of those changes should be tracked by Sync.
_("Annotate unrelated folder as left pane root");
{
let folder = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.rootGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER,
title: "Fake left pane root",
});
let folderId = await PlacesUtils.promiseItemId(folder.guid);
await setAnnoUnchecked(folderId, PlacesUIUtils.ORGANIZER_FOLDER_ANNO, 0,
PlacesUtils.annotations.TYPE_INT32);
leftPaneId = PlacesUIUtils.maybeRebuildLeftPane();
_(`Left pane root ID after deleting unrelated folder: ${leftPaneId}`);
await PlacesTestUtils.promiseAsyncUpdates();
let changes = await tracker.getChangedIDs();
deepEqual(changes, {},
"Should not track left pane items after deleting unrelated folder");
}
_("Corrupt organizer left pane version");
{
await setAnnoUnchecked(leftPaneId, PlacesUIUtils.ORGANIZER_FOLDER_ANNO,
-1, PlacesUtils.annotations.TYPE_INT32);
leftPaneId = PlacesUIUtils.maybeRebuildLeftPane();
_(`Left pane root ID after restoring version: ${leftPaneId}`);
await PlacesTestUtils.promiseAsyncUpdates();
let changes = await tracker.getChangedIDs();
deepEqual(changes, {},
"Should not track left pane items after restoring version");
}
_("Set left pane anno on nonexistent item");
{
await setAnnoUnchecked(999, PlacesUIUtils.ORGANIZER_QUERY_ANNO,
"Tags", PlacesUtils.annotations.TYPE_STRING);
leftPaneId = PlacesUIUtils.maybeRebuildLeftPane();
_(`Left pane root ID after detecting nonexistent item: ${leftPaneId}`);
await PlacesTestUtils.promiseAsyncUpdates();
let changes = await tracker.getChangedIDs();
deepEqual(changes, {},
"Should not track left pane items after detecting nonexistent item");
}
_("Move query out of left pane root");
{
let queryId = await PlacesUIUtils.leftPaneQueries.Downloads;
let queryGuid = await PlacesUtils.promiseItemGuid(queryId);
await PlacesUtils.bookmarks.update({
guid: queryGuid,
parentGuid: PlacesUtils.bookmarks.rootGuid,
index: PlacesUtils.bookmarks.DEFAULT_INDEX,
});
leftPaneId = PlacesUIUtils.maybeRebuildLeftPane();
_(`Left pane root ID after restoring moved query: ${leftPaneId}`);
await PlacesTestUtils.promiseAsyncUpdates();
let changes = await tracker.getChangedIDs();
deepEqual(changes, {},
"Should not track left pane items after restoring moved query");
}
_("Add duplicate query");
{
let leftPaneGuid = await PlacesUtils.promiseItemGuid(leftPaneId);
let query = await PlacesUtils.bookmarks.insert({
parentGuid: leftPaneGuid,
url: `place:folder=TAGS`,
});
let queryId = await PlacesUtils.promiseItemId(query.guid);
await setAnnoUnchecked(queryId, PlacesUIUtils.ORGANIZER_QUERY_ANNO,
"Tags", PlacesUtils.annotations.TYPE_STRING);
leftPaneId = PlacesUIUtils.maybeRebuildLeftPane();
_(`Left pane root ID after removing dupe query: ${leftPaneId}`);
await PlacesTestUtils.promiseAsyncUpdates();
let changes = await tracker.getChangedIDs();
deepEqual(changes, {},
"Should not track left pane items after removing dupe query");
}
} finally {
_("Clean up.");
await cleanup();
}
});
add_task(async function test_tracking() {
_("Test starting and stopping the tracker");

37
servo/Cargo.lock сгенерированный
Просмотреть файл

@ -26,15 +26,6 @@ name = "android_injected_glue"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "angle"
version = "0.5.0"
source = "git+https://github.com/servo/angle?branch=servo#1599c1d067b4ccbe502f660181d08d49d69e26eb"
dependencies = [
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ansi_term"
version = "0.10.2"
@ -312,8 +303,11 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.1"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cexpr"
@ -395,7 +389,7 @@ name = "cmake"
version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1332,7 +1326,7 @@ name = "jemalloc-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1579,7 +1573,7 @@ name = "libz-sys"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1791,6 +1785,15 @@ name = "mitochondria"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mozangle"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mozjs"
version = "0.1.11"
@ -2066,7 +2069,7 @@ name = "openssl-sys"
version = "0.9.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2423,7 +2426,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "script"
version = "0.0.1"
dependencies = [
"angle 0.5.0 (git+https://github.com/servo/angle?branch=servo)",
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"audio-video-metadata 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2460,6 +2462,7 @@ dependencies = [
"mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mozangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"mozjs 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
@ -3693,7 +3696,6 @@ dependencies = [
"checksum alloc-no-stdlib 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b21f6ad9c9957eb5d70c3dee16d31c092b3cab339628f821766b05e6833d72b8"
"checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407"
"checksum android_injected_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "80b9e34fcbf29c0563547cb2ecce9b49504597cad6166769b1e4efb45c6c2951"
"checksum angle 0.5.0 (git+https://github.com/servo/angle?branch=servo)" = "<none>"
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
"checksum app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4720c83543de184d9f6add2fdb8e8031543497b8506620884c16e125b493c09"
@ -3721,7 +3723,7 @@ dependencies = [
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
"checksum caseless 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3261638034d9db4f94a666ebb16494846341ae5a8456c05c1616d66980cf39a"
"checksum cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c674f0870e3dbd4105184ea035acb1c32c8ae69939c9e228d2b11bbfe29efad"
"checksum cc 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9be26b24e988625409b19736d130f0c7d224f01d06454b5f81d8d23d6c1a618f"
"checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum cgl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "86765cb42c2a2c497e142af72517c1b4d7ae5bb2f25dfa77a5c69642f2342d89"
@ -3839,6 +3841,7 @@ dependencies = [
"checksum mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9e965267d4d58496fc4f740e9861118367f13570cadf66316ed2c3f2f14d87c7"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9de3eca27871df31c33b807f834b94ef7d000956f57aa25c5aed9c5f0aae8f6f"
"checksum mozangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4d916e4f2d39a00eeeb082ceb7c63c741e7c9d4f7915945f9225ae5e3b284092"
"checksum mozjs 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "199f707066bf05b559ef6e46741c20e4f7bca8ae3a9c9d953d728dbb840f4eaa"
"checksum mozjs_sys 0.50.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e61a792a125b1364c5ec50255ed8343ce02dc56098f8868dd209d472c8de006a"
"checksum mp3-metadata 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ab5f1d2693586420208d1200ce5a51cd44726f055b635176188137aff42c7de"

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

@ -99,4 +99,4 @@ webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
webvr_traits = {path = "../webvr_traits"}
[target.'cfg(not(target_os = "ios"))'.dependencies]
angle = {git = "https://github.com/servo/angle", branch = "servo"}
mozangle = "0.1"

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

@ -31,6 +31,46 @@ pub struct WebGLProgram {
renderer: WebGLMsgSender,
}
/// ANGLE adds a `_u` prefix to variable names:
///
/// https://chromium.googlesource.com/angle/angle/+/855d964bd0d05f6b2cb303f625506cf53d37e94f
///
/// To avoid hard-coding this we would need to use the `sh::GetAttributes` and `sh::GetUniforms`
/// API to look up the `x.name` and `x.mappedName` members,
/// then build a data structure for bi-directional lookup (so either linear scan or two hashmaps).
/// Even then, this would probably only support plain variable names like "foo".
/// Strings passed to e.g. `GetUniformLocation` can be expressions like "foo[0].bar",
/// with the mapping for that "bar" name in yet another part of ANGLEs API.
const ANGLE_NAME_PREFIX: &'static str = "_u";
fn to_name_in_compiled_shader(s: &str) -> String {
map_dot_separated(s, |s, mapped| {
mapped.push_str(ANGLE_NAME_PREFIX);
mapped.push_str(s);
})
}
fn from_name_in_compiled_shader(s: &str) -> String {
map_dot_separated(s, |s, mapped| {
mapped.push_str(if s.starts_with(ANGLE_NAME_PREFIX) {
&s[ANGLE_NAME_PREFIX.len()..]
} else {
s
})
})
}
fn map_dot_separated<F: Fn(&str, &mut String)>(s: &str, f: F) -> String {
let mut iter = s.split('.');
let mut mapped = String::new();
f(iter.next().unwrap(), &mut mapped);
for s in iter {
mapped.push('.');
f(s, &mut mapped);
}
mapped
}
impl WebGLProgram {
fn new_inherited(renderer: WebGLMsgSender,
id: WebGLProgramId)
@ -213,8 +253,10 @@ impl WebGLProgram {
return Err(WebGLError::InvalidOperation);
}
let name = to_name_in_compiled_shader(&name);
self.renderer
.send(WebGLCommand::BindAttribLocation(self.id, index, String::from(name)))
.send(WebGLCommand::BindAttribLocation(self.id, index, name))
.unwrap();
Ok(())
}
@ -228,8 +270,10 @@ impl WebGLProgram {
.send(WebGLCommand::GetActiveUniform(self.id, index, sender))
.unwrap();
receiver.recv().unwrap().map(|(size, ty, name)|
WebGLActiveInfo::new(self.global().as_window(), size, ty, DOMString::from(name)))
receiver.recv().unwrap().map(|(size, ty, name)| {
let name = DOMString::from(from_name_in_compiled_shader(&name));
WebGLActiveInfo::new(self.global().as_window(), size, ty, name)
})
}
/// glGetActiveAttrib
@ -242,8 +286,10 @@ impl WebGLProgram {
.send(WebGLCommand::GetActiveAttrib(self.id, index, sender))
.unwrap();
receiver.recv().unwrap().map(|(size, ty, name)|
WebGLActiveInfo::new(self.global().as_window(), size, ty, DOMString::from(name)))
receiver.recv().unwrap().map(|(size, ty, name)| {
let name = DOMString::from(from_name_in_compiled_shader(&name));
WebGLActiveInfo::new(self.global().as_window(), size, ty, name)
})
}
/// glGetAttribLocation
@ -264,9 +310,11 @@ impl WebGLProgram {
return Ok(None);
}
let name = to_name_in_compiled_shader(&name);
let (sender, receiver) = webgl_channel().unwrap();
self.renderer
.send(WebGLCommand::GetAttribLocation(self.id, String::from(name), sender))
.send(WebGLCommand::GetAttribLocation(self.id, name, sender))
.unwrap();
Ok(receiver.recv().unwrap())
}
@ -285,9 +333,11 @@ impl WebGLProgram {
return Ok(None);
}
let name = to_name_in_compiled_shader(&name);
let (sender, receiver) = webgl_channel().unwrap();
self.renderer
.send(WebGLCommand::GetUniformLocation(self.id, String::from(name), sender))
.send(WebGLCommand::GetUniformLocation(self.id, name, sender))
.unwrap();
Ok(receiver.recv().unwrap())
}

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

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use angle::hl::{BuiltInResources, Output, ShaderValidator};
use canvas_traits::webgl::{WebGLSLVersion, WebGLVersion};
use canvas_traits::webgl::{webgl_channel, WebGLCommand, WebGLMsgSender, WebGLParameter, WebGLResult, WebGLShaderId};
use dom::bindings::cell::DomRefCell;
@ -16,6 +15,7 @@ use dom::webgl_extensions::ext::oesstandardderivatives::OESStandardDerivatives;
use dom::webglobject::WebGLObject;
use dom::window::Window;
use dom_struct::dom_struct;
use mozangle::shaders::{BuiltInResources, Output, ShaderValidator};
use std::cell::Cell;
use std::sync::{ONCE_INIT, Once};
@ -47,7 +47,7 @@ impl WebGLShader {
id: WebGLShaderId,
shader_type: u32)
-> WebGLShader {
GLSLANG_INITIALIZATION.call_once(|| ::angle::hl::initialize().unwrap());
GLSLANG_INITIALIZATION.call_once(|| ::mozangle::shaders::initialize().unwrap());
WebGLShader {
webgl_object: WebGLObject::new_inherited(),
id: id,

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

@ -5,6 +5,7 @@
// https://w3c.github.io/webvr/#interface-navigator
[NoInterfaceObject]
interface VR {
[Pref="dom.webvr.enabled"]
Promise<sequence<VRDisplay>> getDisplays();
//readonly attribute FrozenArray<VRDisplay> activeVRDisplays;
};

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

@ -21,7 +21,6 @@
#![plugin(script_plugins)]
#![cfg_attr(not(feature = "unrooted_must_root_lint"), allow(unknown_lints))]
extern crate angle;
extern crate app_units;
extern crate audio_video_metadata;
extern crate base64;
@ -64,6 +63,7 @@ extern crate metrics;
extern crate mime;
extern crate mime_guess;
extern crate mitochondria;
extern crate mozangle;
#[macro_use]
extern crate mozjs as js;
extern crate msg;

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

@ -207,7 +207,7 @@ mod bindings {
let mut builder = Builder::default()
.rust_target(RustTarget::Stable_1_0);
let rustfmt_path = env::var_os("MOZ_AUTOMATION").and_then(|_| {
env::var_os("TOOLTOOL_DIR")
env::var_os("TOOLTOOL_DIR").or_else(|| env::var_os("MOZ_SRC"))
}).map(PathBuf::from);
builder = match rustfmt_path {

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

@ -35,6 +35,9 @@ pub mod effects;
///
/// If the two values are not similar, an error is returned unless a fallback
/// function has been specified through `#[animate(fallback)]`.
///
/// Trait bounds for type parameter `Foo` can be opted out of with
/// `#[animation(no_bound(Foo))]` on the type definition.
pub trait Animate: Sized {
/// Animate a value towards another one, given an animation procedure.
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()>;
@ -78,6 +81,9 @@ pub trait ToAnimatedValue {
///
/// If a variant is annotated with `#[animation(error)]`, the corresponding
/// `match` arm is not generated.
///
/// Trait bounds for type parameter `Foo` can be opted out of with
/// `#[animation(no_bound(Foo))]` on the type definition.
pub trait ToAnimatedZero: Sized {
/// Returns a value that, when added with an underlying value, will produce the underlying
/// value. This is used for SMIL animation's "by-animation" where SMIL first interpolates from

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

@ -21,6 +21,10 @@ use std::ops::Add;
///
/// If the two values are not similar, an error is returned unless a fallback
/// function has been specified through `#[distance(fallback)]`.
///
/// Trait bounds for type parameter `Foo` can be opted out of with
/// `#[animation(no_bound(Foo))]` on the type definition, trait bounds for
/// fields can be opted into with `#[distance(field_bound)]` on the field.
pub trait ComputeSquaredDistance {
/// Computes the squared distance between two animatable values.
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()>;

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

@ -43,6 +43,7 @@ pub enum ShapeBox {
/// A shape source, for some reference box.
#[allow(missing_docs)]
#[animation(no_bound(ImageOrUrl))]
#[derive(Animate, Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
#[animation(error)]

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

@ -15,6 +15,7 @@ use values::distance::{ComputeSquaredDistance, SquaredDistance};
/// An SVG paint value
///
/// <https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint>
#[animation(no_bound(UrlPaintServer))]
#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq)]
#[derive(ToAnimatedValue, ToComputedValue, ToCss)]
pub struct SVGPaint<ColorType, UrlPaintServer> {
@ -29,6 +30,7 @@ pub struct SVGPaint<ColorType, UrlPaintServer> {
/// Whereas the spec only allows PaintServer
/// to have a fallback, Gecko lets the context
/// properties have a fallback as well.
#[animation(no_bound(UrlPaintServer))]
#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq)]
#[derive(ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss)]
pub enum SVGPaintKind<ColorType, UrlPaintServer> {
@ -203,7 +205,11 @@ pub enum SVGLength<LengthType> {
pub enum SVGStrokeDashArray<LengthType> {
/// `[ <length> | <percentage> | <number> ]#`
#[css(comma)]
Values(#[css(if_empty = "none", iterable)] Vec<LengthType>),
Values(
#[css(if_empty = "none", iterable)]
#[distance(field_bound)]
Vec<LengthType>,
),
/// `context-value`
ContextValue,
}

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

@ -2,23 +2,31 @@
* 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/. */
use cg::{self, WhereClause};
use cg;
use darling::util::IdentList;
use quote::Tokens;
use syn::{DeriveInput, Path};
use synstructure::{Structure, VariantInfo};
pub fn derive(input: DeriveInput) -> Tokens {
let name = &input.ident;
let trait_path = parse_quote!(values::animated::Animate);
let (impl_generics, ty_generics, mut where_clause) =
cg::trait_parts(&input, &trait_path);
pub fn derive(mut input: DeriveInput) -> Tokens {
let animation_input_attrs = cg::parse_input_attrs::<AnimationInputAttrs>(&input);
let no_bound = animation_input_attrs.no_bound.unwrap_or_default();
let mut where_clause = input.generics.where_clause.take();
for param in input.generics.type_params() {
if !no_bound.contains(&param.ident) {
cg::add_predicate(
&mut where_clause,
parse_quote!(#param: ::values::animated::Animate),
);
}
}
input.generics.where_clause = where_clause;
let input_attrs = cg::parse_input_attrs::<AnimateInputAttrs>(&input);
let s = Structure::new(&input);
let mut append_error_clause = s.variants().len() > 1;
let mut match_body = s.variants().iter().fold(quote!(), |body, variant| {
let arm = match derive_variant_arm(variant, &mut where_clause) {
let arm = match derive_variant_arm(variant) {
Ok(arm) => arm,
Err(()) => {
append_error_clause = true;
@ -29,6 +37,7 @@ pub fn derive(input: DeriveInput) -> Tokens {
});
if append_error_clause {
let input_attrs = cg::parse_input_attrs::<AnimateInputAttrs>(&input);
if let Some(fallback) = input_attrs.fallback {
match_body.append_all(quote! {
(this, other) => #fallback(this, other, procedure)
@ -38,6 +47,9 @@ pub fn derive(input: DeriveInput) -> Tokens {
}
}
let name = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
quote! {
impl #impl_generics ::values::animated::Animate for #name #ty_generics #where_clause {
#[allow(unused_variables, unused_imports)]
@ -55,10 +67,7 @@ pub fn derive(input: DeriveInput) -> Tokens {
}
}
fn derive_variant_arm(
variant: &VariantInfo,
where_clause: &mut WhereClause,
) -> Result<Tokens, ()> {
fn derive_variant_arm(variant: &VariantInfo) -> Result<Tokens, ()> {
let variant_attrs = cg::parse_variant_attrs::<AnimationVariantAttrs>(&variant.ast());
if variant_attrs.error {
return Err(());
@ -78,7 +87,6 @@ fn derive_variant_arm(
let #result = ::std::clone::Clone::clone(#this);
}
} else {
where_clause.add_trait_bound(&result.ast().ty);
quote! {
let #result =
::values::animated::Animate::animate(#this, #other, procedure)?;
@ -99,10 +107,19 @@ struct AnimateInputAttrs {
fallback: Option<Path>,
}
#[darling(attributes(animation), default)]
#[derive(Default, FromDeriveInput)]
pub struct AnimationInputAttrs {
pub no_bound: Option<IdentList>,
}
#[darling(attributes(animation), default)]
#[derive(Default, FromVariant)]
pub struct AnimationVariantAttrs {
pub error: bool,
// Only here because of structs, where the struct definition acts as a
// variant itself.
pub no_bound: Option<IdentList>,
}
#[darling(attributes(animation), default)]

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

@ -3,83 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use darling::{FromDeriveInput, FromField, FromVariant};
use quote::{ToTokens, Tokens};
use std::collections::HashSet;
use quote::Tokens;
use syn::{self, AngleBracketedGenericArguments, Binding, DeriveInput, Field};
use syn::{GenericArgument, GenericParam, Ident, ImplGenerics, Path};
use syn::{PathArguments, PathSegment, QSelf, Type, TypeArray, TypeGenerics};
use syn::{GenericArgument, GenericParam, Ident, Path};
use syn::{PathArguments, PathSegment, QSelf, Type, TypeArray};
use syn::{TypeParam, TypeParen, TypePath, TypeSlice, TypeTuple};
use syn::{Variant, WherePredicate};
use syn::visit::{self, Visit};
use synstructure::{self, BindingInfo, BindStyle, VariantAst, VariantInfo};
pub struct WhereClause<'input, 'path> {
pub inner: Option<syn::WhereClause>,
pub params: Vec<&'input TypeParam>,
trait_path: &'path Path,
trait_output: Option<Ident>,
bounded_types: HashSet<Type>,
}
impl<'input, 'path> ToTokens for WhereClause<'input, 'path> {
fn to_tokens(&self, tokens: &mut Tokens) {
self.inner.to_tokens(tokens);
}
}
impl<'input, 'path> WhereClause<'input, 'path> {
pub fn add_trait_bound(&mut self, ty: &Type) {
let trait_path = self.trait_path;
let mut found = self.trait_output.map(|_| HashSet::new());
if self.bounded_types.contains(&ty) {
return;
}
if !is_parameterized(&ty, &self.params, found.as_mut()) {
return;
}
self.bounded_types.insert(ty.clone());
let output = if let Some(output) = self.trait_output {
output
} else {
add_predicate(&mut self.inner, where_predicate(ty.clone(), trait_path, None));
return;
};
if let Type::Path(syn::TypePath { ref path, .. }) = *ty {
if path_to_ident(path).is_some() {
add_predicate(&mut self.inner, where_predicate(ty.clone(), trait_path, None));
return;
}
}
let output_type = map_type_params(ty, &self.params, &mut |ident| {
parse_quote!(<#ident as ::#trait_path>::#output)
});
let pred = where_predicate(
ty.clone(),
trait_path,
Some((output, output_type)),
);
add_predicate(&mut self.inner, pred);
if let Some(found) = found {
for ident in found {
let ty = Type::Path(syn::TypePath { qself: None, path: ident.into() });
if !self.bounded_types.contains(&ty) {
self.bounded_types.insert(ty.clone());
add_predicate(
&mut self.inner,
where_predicate(ty, trait_path, None),
);
};
}
}
}
}
pub fn add_predicate(
where_clause: &mut Option<syn::WhereClause>,
pred: WherePredicate,
@ -139,36 +70,6 @@ pub fn fmap_trait_output(
segment.into()
}
pub fn is_parameterized(
ty: &Type,
params: &[&TypeParam],
found: Option<&mut HashSet<Ident>>,
) -> bool {
struct IsParameterized<'a, 'b> {
params: &'a [&'a TypeParam],
has_free: bool,
found: Option<&'b mut HashSet<Ident>>,
}
impl<'a, 'b, 'ast> Visit<'ast> for IsParameterized<'a, 'b> {
fn visit_path(&mut self, path: &'ast Path) {
if let Some(ident) = path_to_ident(path) {
if self.params.iter().any(|param| param.ident == ident) {
self.has_free = true;
if let Some(ref mut found) = self.found {
found.insert(ident.clone());
}
}
}
visit::visit_path(self, path);
}
}
let mut visitor = IsParameterized { params, has_free: false, found };
visitor.visit_type(ty);
visitor.has_free
}
pub fn map_type_params<F>(ty: &Type, params: &[&TypeParam], f: &mut F) -> Type
where
F: FnMut(&Ident) -> Type,
@ -314,33 +215,6 @@ pub fn ref_pattern<'a>(
(v.pat(), v.bindings().iter().cloned().collect())
}
pub fn trait_parts<'input, 'path>(
input: &'input DeriveInput,
trait_path: &'path Path,
) -> (ImplGenerics<'input>, TypeGenerics<'input>, WhereClause<'input, 'path>) {
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let where_clause = WhereClause {
inner: where_clause.cloned(),
params: input.generics.type_params().into_iter().collect::<Vec<&TypeParam>>(),
trait_path,
trait_output: None,
bounded_types: HashSet::new()
};
(impl_generics, ty_generics, where_clause)
}
fn trait_ref(path: &Path, output: Option<(Ident, Type)>) -> Path {
let segments = path.segments.iter().collect::<Vec<&PathSegment>>();
let (name, parent) = segments.split_last().unwrap();
let last_segment: PathSegment = if let Some((param, ty)) = output {
parse_quote!(#name<#param = #ty>)
} else {
parse_quote!(#name)
};
parse_quote!(::#(#parent::)*#last_segment)
}
pub fn value<'a>(
variant: &'a VariantInfo,
prefix: &str,
@ -351,15 +225,6 @@ pub fn value<'a>(
(v.pat(), v.bindings().iter().cloned().collect())
}
pub fn where_predicate(
bounded_ty: Type,
trait_path: &Path,
trait_output: Option<(Ident, Type)>,
) -> WherePredicate {
let trait_ref = trait_ref(trait_path, trait_output);
parse_quote!(#bounded_ty: #trait_ref)
}
/// Transforms "FooBar" to "foo-bar".
///
/// If the first Camel segment is "Moz", "Webkit", or "Servo", the result string

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

@ -2,52 +2,71 @@
* 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/. */
use animate::AnimationVariantAttrs;
use animate::{AnimationInputAttrs, AnimationVariantAttrs};
use cg;
use quote::Tokens;
use syn::{DeriveInput, Path};
use synstructure;
pub fn derive(input: DeriveInput) -> Tokens {
let name = &input.ident;
let trait_path = parse_quote!(values::distance::ComputeSquaredDistance);
let (impl_generics, ty_generics, mut where_clause) =
cg::trait_parts(&input, &trait_path);
let input_attrs = cg::parse_input_attrs::<DistanceInputAttrs>(&input);
let s = synstructure::Structure::new(&input);
let mut append_error_clause = s.variants().len() > 1;
let mut match_body = s.variants().iter().fold(quote!(), |body, variant| {
let attrs = cg::parse_variant_attrs::<AnimationVariantAttrs>(&variant.ast());
if attrs.error {
append_error_clause = true;
return body;
pub fn derive(mut input: DeriveInput) -> Tokens {
let animation_input_attrs = cg::parse_input_attrs::<AnimationInputAttrs>(&input);
let no_bound = animation_input_attrs.no_bound.unwrap_or_default();
let mut where_clause = input.generics.where_clause.take();
for param in input.generics.type_params() {
if !no_bound.contains(&param.ident) {
cg::add_predicate(
&mut where_clause,
parse_quote!(#param: ::values::distance::ComputeSquaredDistance),
);
}
}
let (this_pattern, this_info) = cg::ref_pattern(&variant, "this");
let (other_pattern, other_info) = cg::ref_pattern(&variant, "other");
let sum = if this_info.is_empty() {
quote! { ::values::distance::SquaredDistance::from_sqrt(0.) }
} else {
let mut sum = quote!();
sum.append_separated(this_info.iter().zip(&other_info).map(|(this, other)| {
where_clause.add_trait_bound(&this.ast().ty);
quote! {
::values::distance::ComputeSquaredDistance::compute_squared_distance(#this, #other)?
}
}), quote!(+));
sum
};
quote! {
#body
(&#this_pattern, &#other_pattern) => {
Ok(#sum)
let (mut match_body, append_error_clause) = {
let s = synstructure::Structure::new(&input);
let mut append_error_clause = s.variants().len() > 1;
let match_body = s.variants().iter().fold(quote!(), |body, variant| {
let attrs = cg::parse_variant_attrs::<AnimationVariantAttrs>(&variant.ast());
if attrs.error {
append_error_clause = true;
return body;
}
}
});
let (this_pattern, this_info) = cg::ref_pattern(&variant, "this");
let (other_pattern, other_info) = cg::ref_pattern(&variant, "other");
let sum = if this_info.is_empty() {
quote! { ::values::distance::SquaredDistance::from_sqrt(0.) }
} else {
let mut sum = quote!();
sum.append_separated(this_info.iter().zip(&other_info).map(|(this, other)| {
let field_attrs = cg::parse_field_attrs::<DistanceFieldAttrs>(&this.ast());
if field_attrs.field_bound {
let ty = &this.ast().ty;
cg::add_predicate(
&mut where_clause,
parse_quote!(#ty: ::values::distance::ComputeSquaredDistance),
);
}
quote! {
::values::distance::ComputeSquaredDistance::compute_squared_distance(#this, #other)?
}
}), quote!(+));
sum
};
quote! {
#body
(&#this_pattern, &#other_pattern) => {
Ok(#sum)
}
}
});
(match_body, append_error_clause)
};
input.generics.where_clause = where_clause;
if append_error_clause {
let input_attrs = cg::parse_input_attrs::<DistanceInputAttrs>(&input);
if let Some(fallback) = input_attrs.fallback {
match_body.append_all(quote! {
(this, other) => #fallback(this, other)
@ -57,6 +76,9 @@ pub fn derive(input: DeriveInput) -> Tokens {
}
}
let name = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
quote! {
impl #impl_generics ::values::distance::ComputeSquaredDistance for #name #ty_generics #where_clause {
#[allow(unused_variables, unused_imports)]
@ -78,3 +100,9 @@ pub fn derive(input: DeriveInput) -> Tokens {
struct DistanceInputAttrs {
fallback: Option<Path>,
}
#[darling(attributes(distance), default)]
#[derive(Default, FromField)]
struct DistanceFieldAttrs {
field_bound: bool,
}

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

@ -45,7 +45,7 @@ pub fn derive_parse(stream: TokenStream) -> TokenStream {
parse::derive(input).into()
}
#[proc_macro_derive(ToAnimatedZero, attributes(animation))]
#[proc_macro_derive(ToAnimatedZero, attributes(animation, zero))]
pub fn derive_to_animated_zero(stream: TokenStream) -> TokenStream {
let input = syn::parse(stream).unwrap();
to_animated_zero::derive(input).into()

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

@ -2,20 +2,26 @@
* 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/. */
use animate::{AnimationVariantAttrs, AnimationFieldAttrs};
use animate::{AnimationFieldAttrs, AnimationInputAttrs, AnimationVariantAttrs};
use cg;
use quote;
use syn;
use synstructure;
pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
let name = &input.ident;
let trait_path = parse_quote!(values::animated::ToAnimatedZero);
let (impl_generics, ty_generics, mut where_clause) =
cg::trait_parts(&input, &trait_path);
pub fn derive(mut input: syn::DeriveInput) -> quote::Tokens {
let animation_input_attrs = cg::parse_input_attrs::<AnimationInputAttrs>(&input);
let no_bound = animation_input_attrs.no_bound.unwrap_or_default();
let mut where_clause = input.generics.where_clause.take();
for param in input.generics.type_params() {
if !no_bound.contains(&param.ident) {
cg::add_predicate(
&mut where_clause,
parse_quote!(#param: ::values::animated::ToAnimatedZero),
);
}
}
let s = synstructure::Structure::new(&input);
let to_body = s.each_variant(|variant| {
let to_body = synstructure::Structure::new(&input).each_variant(|variant| {
let attrs = cg::parse_variant_attrs::<AnimationVariantAttrs>(&variant.ast());
if attrs.error {
return Some(quote! { Err(()) });
@ -26,21 +32,10 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
computations.append_all(bindings_pairs.map(|(binding, mapped_binding)| {
let field_attrs = cg::parse_field_attrs::<AnimationFieldAttrs>(&binding.ast());
if field_attrs.constant {
if cg::is_parameterized(&binding.ast().ty, &where_clause.params, None) {
cg::add_predicate(
&mut where_clause.inner,
cg::where_predicate(
binding.ast().ty.clone(),
&parse_quote!(std::clone::Clone),
None,
),
);
}
quote! {
let #mapped_binding = ::std::clone::Clone::clone(#binding);
}
} else {
where_clause.add_trait_bound(&binding.ast().ty);
quote! {
let #mapped_binding =
::values::animated::ToAnimatedZero::to_animated_zero(#binding)?;
@ -50,6 +45,10 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
computations.append_all(quote! { Ok(#mapped) });
Some(computations)
});
input.generics.where_clause = where_clause;
let name = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
quote! {
impl #impl_generics ::values::animated::ToAnimatedZero for #name #ty_generics #where_clause {

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

@ -3,12 +3,12 @@ Change log
All notable changes to this program is documented in this file.
Unreleased
----------
0.20.0 (2018-03-08)
-------------------
### Added
- New `--jsdebugger` flag to open the Browser Toolbox when Firefox
- New `--jsdebugger` flag to open the [Browser Toolbox] when Firefox
launches. This is useful for debugging Marionette internals.
- Introduced the temporary, boolean capability
@ -18,19 +18,35 @@ Unreleased
### Changed
- HTTP status code for the [`StaleElementReference`] error changed
from 400 (Bad Request) to 404 (Not Found)
from 400 (Bad Request) to 404 (Not Found).
- Backtraces from geckodriver no longer substitute for missing
Marionette stacktraces
Marionette stacktraces.
- `Delete Session` now allows Firefox to safely shutdown within 70s before
force-killing the process
- Changed preference used to disable shield studies to `app.normandy.api_url`.
- [webdriver crate] upgraded to 0.35.0.
### Fixed
- Improved error messages for malformed capabilities
- The Firefox process is now given ample time to shut down, allowing
enough time for the Firefox shutdown hang monitor to kick in.
Firefox has an integrated background monitor that observes
long-running threads during shutdown. These threads will be
killed after 63 seconds in the event of a hang. To allow Firefox
to shut down these threads on its own, geckodriver has to wait
that time and some additional seconds.
- Grapheme clusters are now accepted as input for keyboard input
to actions.
Input to the `value` field of the `keyDown` and `keyUp` action
primitives used to only accept single characters, which means
geckodriver would error when a valid grapheme cluster was sent in,
for example with the tamil nadu character U+0BA8 U+0BBF.
Thanks to Greg Fraley for fixing this bug.
- Improved error messages for malformed capability values.
0.19.1 (2017-10-30)
@ -793,9 +809,11 @@ and greater.
[README]: https://github.com/mozilla/geckodriver/blob/master/README.md
[Browser Toolbox]: https://developer.mozilla.org/en-US/docs/Tools/Browser_Toolbox
[`CloseWindowResponse`]: https://docs.rs/webdriver/newest/webdriver/response/struct.CloseWindowResponse.html
[`CookieResponse`]: https://docs.rs/webdriver/newest/webdriver/response/struct.CookieResponse.html
[`DeleteSession`]: https://docs.rs/webdriver/newest/webdriver/command/enum.WebDriverCommand.html#variant.DeleteSession
[`ElementClickIntercepted`]: https://docs.rs/webdriver/newest/webdriver/error/enum.ErrorStatus.html#variant.ElementClickIntercepted
[`ElementNotInteractable`]: https://docs.rs/webdriver/newest/webdriver/error/enum.ErrorStatus.html#variant.ElementNotInteractable
[`FullscreenWindow`]: https://docs.rs/webdriver/newest/webdriver/command/enum.WebDriverCommand.html#variant.FullscreenWindow
@ -821,15 +839,16 @@ and greater.
[webdriver crate]: https://crates.io/crates/webdriver
[Actions]: https://w3c.github.io/webdriver/webdriver-spec.html#actions
[Delete Session]: https://w3c.github.io/webdriver/webdriver-spec.html#delete-session
[Element Click]: https://w3c.github.io/webdriver/webdriver-spec.html#element-click
[Get Timeouts]: https://w3c.github.io/webdriver/webdriver-spec.html#get-timeouts
[Set Timeouts]: https://w3c.github.io/webdriver/webdriver-spec.html#set-timeouts
[Get Window Rect]: https://w3c.github.io/webdriver/webdriver-spec.html#get-window-rect
[Set Window Rect]: https://w3c.github.io/webdriver/webdriver-spec.html#set-window-rect
[insecure certificate]: https://w3c.github.io/webdriver/webdriver-spec.html#dfn-insecure-certificate
[Minimize Window]: https://w3c.github.io/webdriver/webdriver-spec.html#minimize-window
[New Session]: https://w3c.github.io/webdriver/webdriver-spec.html#new-session
[Send Alert Text]: https://w3c.github.io/webdriver/webdriver-spec.html#send-alert-text
[Set Timeouts]: https://w3c.github.io/webdriver/webdriver-spec.html#set-timeouts
[Set Window Rect]: https://w3c.github.io/webdriver/webdriver-spec.html#set-window-rect
[Status]: https://w3c.github.io/webdriver/webdriver-spec.html#status
[Take Element Screenshot]: https://w3c.github.io/webdriver/webdriver-spec.html#take-element-screenshot
[WebDriver errors]: https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors

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

@ -1,7 +1,6 @@
[package]
name = "geckodriver"
version = "0.19.1"
authors = ["Mozilla <tools-marionette@lists.mozilla.org>"]
version = "0.20.0"
description = "Proxy for using WebDriver clients to interact with Gecko-based browsers."
keywords = ["webdriver", "w3c", "httpd", "mozilla", "firefox"]
repository = "https://hg.mozilla.org/mozilla-central/file/tip/testing/geckodriver"

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

@ -33,15 +33,20 @@ use std::fmt;
use std::io;
use std::io::Write;
use std::str;
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
static MAX_LOG_LEVEL: AtomicUsize = ATOMIC_USIZE_INIT;
const LOGGED_TARGETS: &'static [&'static str] = &[
"geckodriver",
"mozprofile",
"mozrunner",
"mozversion",
"webdriver",
];
/// Logger levels from [Log.jsm].
///
/// [Log.jsm]:
/// https://developer.mozilla.org/en/docs/Mozilla/JavaScript_code_modules/Log.
/// jsm
/// [Log.jsm]: https://developer.mozilla.org/en/docs/Mozilla/JavaScript_code_modules/Log.jsm
#[repr(usize)]
#[derive(Clone, Copy, Eq, Debug, Hash, PartialEq)]
pub enum Level {
@ -134,7 +139,8 @@ struct Logger;
impl log::Log for Logger {
fn enabled(&self, meta: &log::Metadata) -> bool {
meta.level() <= log::max_level()
LOGGED_TARGETS.iter().any(|&x| meta.target().starts_with(x))
&& meta.level() <= log::max_level()
}
fn log(&self, record: &log::Record) {

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

@ -1,7 +1,17 @@
use mozprofile::preferences::Pref;
// ALL CHANGES TO THIS FILE MUST HAVE REVIEW FROM A GECKODRIVER PEER!
//
// The Marionette Python client is used out-of-tree with release
// channel builds of Firefox. Removing a preference from this file
// will cause regressions, so please be careful and get review from
// a Testing :: Marionette peer before you make any changes to this file.
lazy_static! {
pub static ref DEFAULT: [(&'static str, Pref); 78] = [
pub static ref DEFAULT: [(&'static str, Pref); 80] = [
// Make sure Shield doesn't hit the network.
("app.normandy.api_url", Pref::new("")),
// Disable automatic downloading of new releases
("app.update.auto", Pref::new(false)),
@ -110,6 +120,7 @@ lazy_static! {
// Do not show datareporting policy notifications which can
// interfere with tests
("datareporting.healthreport.about.reportUrl", Pref::new("http://%(server)s/dummy/abouthealthreport/")), // removed in Firefox 59
("datareporting.healthreport.documentServerURI", Pref::new("http://%(server)s/dummy/healthreport/")),
("datareporting.healthreport.logging.consoleEnabled", Pref::new(false)),
("datareporting.healthreport.service.enabled", Pref::new(false)),
@ -144,7 +155,8 @@ lazy_static! {
("extensions.installDistroAddons", Pref::new(false)),
// Make sure Shield doesn't hit the network.
("app.normandy.api_url", Pref::new("")),
// Removed in Firefox 60.
("extensions.shield-recipe-client.api_url", Pref::new("")),
("extensions.showMismatchUI", Pref::new(false)),

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

@ -22,8 +22,19 @@ from six import reraise
from . import errors
# ALL CHANGES TO THIS FILE MUST HAVE REVIEW FROM A MARIONETTE PEER!
#
# The Marionette Python client is used out-of-tree with release
# channel builds of Firefox. Removing a preference from this file
# will cause regressions, so please be careful and get review from
# a Testing :: Marionette peer before you make any changes to this file.
class GeckoInstance(object):
required_prefs = {
# Make sure Shield doesn't hit the network.
"app.normandy.api_url": "",
# Increase the APZ content response timeout in tests to 1 minute.
# This is to accommodate the fact that test environments tends to be slower
# than production environments (with the b2g emulator being the slowest of them
@ -33,6 +44,8 @@ class GeckoInstance(object):
"apz.content_response_timeout": 60000,
# Do not send Firefox health reports to the production server
# removed in Firefox 59
"datareporting.healthreport.about.reportUrl": "http://%(server)s/dummy/abouthealthreport/",
"datareporting.healthreport.documentServerURI": "http://%(server)s/dummy/healthreport/",
# Do not show datareporting policy notifications which can interfer with tests
@ -53,7 +66,8 @@ class GeckoInstance(object):
# Disable intalling any distribution add-ons
"extensions.installDistroAddons": False,
# Make sure Shield doesn't hit the network.
"app.normandy.api_url": "",
# Removed in Firefox 60.
"extensions.shield-recipe-client.api_url": "",
"extensions.showMismatchUI": False,
# Turn off extension updates so they don't bother tests
"extensions.update.enabled": False,

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

@ -54,6 +54,9 @@ const ENV_PRESERVE_PREFS = "MOZ_MARIONETTE_PREF_STATE_ACROSS_RESTARTS";
// are checked before Marionette initialises.
const RECOMMENDED_PREFS = new Map([
// Make sure Shield doesn't hit the network.
["app.normandy.api_url", ""],
// Disable automatic downloading of new releases.
//
// This should also be set in the profile prior to starting Firefox,
@ -197,9 +200,6 @@ const RECOMMENDED_PREFS = new Map([
// Should be set in profile.
["extensions.installDistroAddons", false],
// Make sure Shield doesn't hit the network.
["extensions.shield-recipe-client.api_url", ""],
["extensions.showMismatchUI", false],
// Turn off extension updates so they do not bother tests

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

@ -32,8 +32,16 @@ class TestPreferences(MarionetteTestCase):
required_prefs = geckoinstance.GeckoInstance.required_prefs
for key, value in required_prefs.iteritems():
self.assertEqual(self.marionette.get_pref(key), value,
"Preference {} hasn't been set to {}".format(key, value))
# The extensions.shield-recipe-client.* prefs branch
# is as of Firefox 60 migrated to app.normandy.*.
#
# This is a workaround that can be removed together
# with extensions.shield-recipe-client.api_url.
if key == "extensions.shield-recipe-client.api_url":
self.assertEqual(self.marionette.get_pref("app.normandy.api_url"), value)
else:
self.assertEqual(self.marionette.get_pref(key), value,
"Preference {} hasn't been set to {}".format(key, repr(value)))
@skip_if_mobile("Only runnable with Firefox")
def test_desktop_instance_preferences(self):

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

@ -1,7 +1,7 @@
[package]
name = "mozrunner"
version = "0.5.0"
authors = ["Mozilla Tools and Automation <auto-tools@mozilla.com>"]
version = "0.6.0"
authors = ["Mozilla"]
description = "Library for starting Firefox binaries."
repository = "https://hg.mozilla.org/mozilla-central/file/tip/testing/mozbase/rust/mozrunner"
license = "MPL-2.0"

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

@ -1,6 +1,6 @@
[package]
name = "mozversion"
version = "0.1.2"
version = "0.1.3"
authors = ["James Graham <james@hoppipolla.co.uk>"]
description = "Utility for accessing Firefox version metadata"
keywords = ["mozilla", "firefox"]

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

@ -1,7 +1,7 @@
[package]
name = "webdriver"
version = "0.34.0"
authors = ["Mozilla <tools-marionette@lists.mozilla.org>"]
version = "0.35.0"
authors = ["Mozilla"]
description = "Library implementing the wire protocol for the W3C WebDriver specification."
keywords = ["webdriver", "browser", "automation", "protocol", "w3c"]
documentation = "https://docs.rs/webdriver"
@ -16,5 +16,5 @@ log = "0.4"
regex = "0.2"
rustc-serialize = "0.3"
time = "0.1"
unicode-segmentation = "1.1.0"
url = "1"
unicode-segmentation = "1.1.0"

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

@ -267,12 +267,10 @@ BookmarkImporter.prototype = {
continue;
}
// Places is moving away from supporting user-defined folders at the top
// of the tree, however, until we have a migration strategy we need to
// ensure any non-built-in folders are created (xref bug 1310299).
// Drop any roots whose guid we don't recognise - we don't support anything
// apart from the built-in roots.
if (!PlacesUtils.bookmarks.userContentRoots.includes(node.guid)) {
node.parentGuid = PlacesUtils.bookmarks.rootGuid;
await PlacesUtils.bookmarks.insert(node);
continue;
}
await PlacesUtils.bookmarks.insertTree(node, { fixupOrSkipInvalidEntries: true });

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

@ -241,7 +241,9 @@ var Bookmarks = Object.freeze({
index: { defaultValue: this.DEFAULT_INDEX },
url: { requiredIf: b => b.type == this.TYPE_BOOKMARK,
validIf: b => b.type == this.TYPE_BOOKMARK },
parentGuid: { required: true },
parentGuid: { required: true,
// Inserting into the root folder is not allowed.
validIf: b => b.parentGuid != this.rootGuid },
title: { defaultValue: "",
validIf: b => b.type == this.TYPE_BOOKMARK ||
b.type == this.TYPE_FOLDER ||
@ -610,6 +612,7 @@ var Bookmarks = Object.freeze({
{ guid: { required: true },
index: { requiredIf: b => b.hasOwnProperty("parentGuid"),
validIf: b => b.index >= 0 || b.index == this.DEFAULT_INDEX },
parentGuid: { validIf: b => b.parentGuid != this.rootGuid },
source: { defaultValue: this.SOURCES.DEFAULT }
});

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

@ -1,142 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Menu, Toolbar, Unsorted, Tags, Mobile
const PLACES_ROOTS_COUNT = 5;
/*
Backup/restore tests example:
var myTest = {
populate: function () { ... add bookmarks ... },
validate: function () { ... query for your bookmarks ... }
}
this.push(myTest);
*/
var test = {
populate: function populate() {
// check initial size
var rootNode = PlacesUtils.getFolderContents(PlacesUtils.placesRootId,
false, false).root;
Assert.equal(rootNode.childCount, PLACES_ROOTS_COUNT );
rootNode.containerOpen = false;
var idx = PlacesUtils.bookmarks.DEFAULT_INDEX;
// create a root to be restore
this._restoreRootTitle = "restore root";
var restoreRootId = PlacesUtils.bookmarks
.createFolder(PlacesUtils.placesRootId,
this._restoreRootTitle, idx);
// add a test bookmark
this._restoreRootURI = uri("http://restore.uri");
PlacesUtils.bookmarks.insertBookmark(restoreRootId, this._restoreRootURI,
idx, "restore uri");
// add a test bookmark to be exclude
this._restoreRootExcludeURI = uri("http://exclude.uri");
var exItemId = PlacesUtils.bookmarks
.insertBookmark(restoreRootId,
this._restoreRootExcludeURI,
idx, "exclude uri");
// Annotate the bookmark for exclusion.
PlacesUtils.annotations.setItemAnnotation(exItemId,
PlacesUtils.EXCLUDE_FROM_BACKUP_ANNO, 1, 0,
PlacesUtils.annotations.EXPIRE_NEVER);
// create a root to be exclude
this._excludeRootTitle = "exclude root";
this._excludeRootId = PlacesUtils.bookmarks
.createFolder(PlacesUtils.placesRootId,
this._excludeRootTitle, idx);
// Annotate the root for exclusion.
PlacesUtils.annotations.setItemAnnotation(this._excludeRootId,
PlacesUtils.EXCLUDE_FROM_BACKUP_ANNO, 1, 0,
PlacesUtils.annotations.EXPIRE_NEVER);
// add a test bookmark exclude by exclusion of its parent
PlacesUtils.bookmarks.insertBookmark(this._excludeRootId,
this._restoreRootExcludeURI,
idx, "exclude uri");
},
validate: function validate(aEmptyBookmarks) {
var rootNode = PlacesUtils.getFolderContents(PlacesUtils.placesRootId,
false, false).root;
if (!aEmptyBookmarks) {
// since restore does not remove backup exclude items both
// roots should still exist.
Assert.equal(rootNode.childCount, PLACES_ROOTS_COUNT + 2);
// open exclude root and check it still contains one item
var restoreRootIndex = PLACES_ROOTS_COUNT;
var excludeRootIndex = PLACES_ROOTS_COUNT + 1;
var excludeRootNode = rootNode.getChild(excludeRootIndex);
Assert.equal(this._excludeRootTitle, excludeRootNode.title);
excludeRootNode.QueryInterface(Ci.nsINavHistoryQueryResultNode);
excludeRootNode.containerOpen = true;
Assert.equal(excludeRootNode.childCount, 1);
var excludeRootChildNode = excludeRootNode.getChild(0);
Assert.equal(excludeRootChildNode.uri, this._restoreRootExcludeURI.spec);
excludeRootNode.containerOpen = false;
} else {
// exclude root should not exist anymore
Assert.equal(rootNode.childCount, PLACES_ROOTS_COUNT + 1);
restoreRootIndex = PLACES_ROOTS_COUNT;
}
var restoreRootNode = rootNode.getChild(restoreRootIndex);
Assert.equal(this._restoreRootTitle, restoreRootNode.title);
restoreRootNode.QueryInterface(Ci.nsINavHistoryQueryResultNode);
restoreRootNode.containerOpen = true;
Assert.equal(restoreRootNode.childCount, 1);
var restoreRootChildNode = restoreRootNode.getChild(0);
Assert.equal(restoreRootChildNode.uri, this._restoreRootURI.spec);
restoreRootNode.containerOpen = false;
rootNode.containerOpen = false;
}
};
// make json file
var jsonFile;
add_task(async function setup() {
jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
});
add_task(async function test_export_import_excluded_file() {
// populate db
test.populate();
await BookmarkJSONUtils.exportToFile(jsonFile);
// restore json file
info("Restoring json file");
await BookmarkJSONUtils.importFromFile(jsonFile, true);
// validate without removing all bookmarks
// restore do not remove backup exclude entries
info("Validating...");
test.validate(false);
});
add_task(async function test_clearing_then_importing() {
// cleanup
await PlacesUtils.bookmarks.eraseEverything();
// manually remove the excluded root
PlacesUtils.bookmarks.removeItem(test._excludeRootId);
// restore json file
await BookmarkJSONUtils.importFromFile(jsonFile, true);
// validate after a complete bookmarks cleanup
test.validate(true);
// clean up
await OS.File.remove(jsonFile);
});

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

@ -1,152 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var tests = [];
/*
Backup/restore tests example:
var myTest = {
populate: function () { ... add bookmarks ... },
validate: function () { ... query for your bookmarks ... }
}
this.push(myTest);
*/
tests.push({
// Initialise something to avoid undefined property warnings in validate.
_litterTitle: "",
async populate() {
// check initial size
var rootNode = PlacesUtils.getFolderContents(PlacesUtils.placesRootId,
false, false).root;
Assert.equal(rootNode.childCount, 5);
// create a test root
this._folderTitle = "test folder";
this._folderId =
PlacesUtils.bookmarks.createFolder(PlacesUtils.placesRootId,
this._folderTitle,
PlacesUtils.bookmarks.DEFAULT_INDEX);
Assert.equal(rootNode.childCount, 6);
// add a tag
this._testURI = Services.io.newURI("http://test");
this._tags = ["a", "b"];
PlacesUtils.tagging.tagURI(this._testURI, this._tags);
// add a child to each root, including our test root
await PlacesUtils.bookmarks.eraseEverything();
this._roots = [PlacesUtils.bookmarksMenuFolderId, PlacesUtils.toolbarFolderId,
PlacesUtils.unfiledBookmarksFolderId, PlacesUtils.mobileFolderId,
this._folderId];
this._roots.forEach(aRootId => {
// add a test bookmark
PlacesUtils.bookmarks.insertBookmark(aRootId, this._testURI,
PlacesUtils.bookmarks.DEFAULT_INDEX, "test");
});
// add a folder to exclude from replacing during restore
// this will still be present post-restore
var excludedFolderId =
PlacesUtils.bookmarks.createFolder(PlacesUtils.placesRootId,
"excluded",
PlacesUtils.bookmarks.DEFAULT_INDEX);
Assert.equal(rootNode.childCount, 7);
// add a test bookmark to it
PlacesUtils.bookmarks.insertBookmark(excludedFolderId, this._testURI,
PlacesUtils.bookmarks.DEFAULT_INDEX, "test");
},
inbetween: function inbetween() {
// add some items that should be removed by the restore
// add a folder
this._litterTitle = "otter";
PlacesUtils.bookmarks.createFolder(PlacesUtils.placesRootId,
this._litterTitle, 0);
// add some tags
PlacesUtils.tagging.tagURI(this._testURI, ["c", "d"]);
},
validate: function validate() {
// validate tags restored
var tags = PlacesUtils.tagging.getTagsForURI(this._testURI);
// also validates that litter tags are gone
Assert.equal(this._tags.toString(), tags.toString());
var rootNode = PlacesUtils.getFolderContents(PlacesUtils.placesRootId,
false, false).root;
// validate litter is gone
Assert.notEqual(rootNode.getChild(0).title, this._litterTitle);
// test root count is the same
Assert.equal(rootNode.childCount, 7);
var foundTestFolder = 0;
for (var i = 0; i < rootNode.childCount; i++) {
var node = rootNode.getChild(i);
info("validating " + node.title);
if (node.itemId != PlacesUtils.tagsFolderId) {
if (node.title == this._folderTitle) {
// check the test folder's properties
Assert.equal(node.type, node.RESULT_TYPE_FOLDER);
Assert.equal(node.title, this._folderTitle);
foundTestFolder++;
}
// test contents
node.QueryInterface(Ci.nsINavHistoryContainerResultNode).containerOpen = true;
Assert.equal(node.childCount, 1);
var child = node.getChild(0);
Assert.ok(Services.io.newURI(child.uri).equals(this._testURI));
// clean up
node.containerOpen = false;
}
}
Assert.equal(foundTestFolder, 1);
rootNode.containerOpen = false;
}
});
add_task(async function() {
// make json file
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
// populate db
for (let test of tests) {
await test.populate();
// sanity
test.validate();
}
await BookmarkJSONUtils.exportToFile(jsonFile);
tests.forEach(function(aTest) {
aTest.inbetween();
});
// restore json file
await BookmarkJSONUtils.importFromFile(jsonFile, true);
// validate
tests.forEach(function(aTest) {
aTest.validate();
});
// clean up
await OS.File.remove(jsonFile);
});

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

@ -91,6 +91,25 @@ add_task(async function invalid_properties_for_bookmark_type() {
/Invalid value for property 'title'/);
});
add_task(async function test_insert_into_root_throws() {
Assert.throws(() =>
PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.rootGuid,
url: "http://example.com",
}),
/Invalid value for property 'parentGuid'/,
"Should throw when inserting a bookmark into the root."
);
Assert.throws(() =>
PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.rootGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER,
}),
/Invalid value for property 'parentGuid'/,
"Should throw when inserting a folder into the root."
);
});
add_task(async function long_title_trim() {
let longtitle = "a";
for (let i = 0; i < 4096; i++) {

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

@ -71,14 +71,6 @@ add_task(async function remove_roots_fail() {
}
});
add_task(async function remove_normal_folder_under_root_succeeds() {
let folder = await PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.rootGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER });
checkBookmarkObject(folder);
await PlacesUtils.bookmarks.remove(folder);
Assert.strictEqual((await PlacesUtils.bookmarks.fetch(folder.guid)), null);
});
add_task(async function remove_bookmark() {
// When removing a bookmark we need to check the frecency. First we confirm
// that there is a normal update when it is inserted.

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

@ -88,7 +88,7 @@ add_task(async function move_roots_fail() {
Assert.rejects(PlacesUtils.bookmarks.update({
guid,
index: -1,
parentGuid: PlacesUtils.bookmarks.rootGuid,
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
}), /It's not possible to move Places root folders\./,
`Should reject when attempting to move ${guid}`);
}
@ -304,6 +304,36 @@ add_task(async function update_move_folder_into_descendant_throws() {
}
});
add_task(async function update_move_into_root_folder_rejects() {
let folder = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER
});
let bm = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: "http://example.com/",
type: PlacesUtils.bookmarks.TYPE_BOOKMARK
});
Assert.throws(() =>
PlacesUtils.bookmarks.update({
guid: bm.guid,
index: -1,
parentGuid: PlacesUtils.bookmarks.rootGuid,
}), /Invalid value for property 'parentGuid'/,
"Should reject when attempting to move a bookmark into the root"
);
Assert.throws(() =>
PlacesUtils.bookmarks.update({
guid: folder.guid,
index: -1,
parentGuid: PlacesUtils.bookmarks.rootGuid,
}), /Invalid value for property 'parentGuid'/,
"Should reject when attempting to move a bookmark into the root"
);
});
add_task(async function update_move() {
let parent = await PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER }) ;

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

@ -10,8 +10,6 @@ skip-if = toolkit == 'android'
[test_393498.js]
[test_395593.js]
[test_405938_restore_queries.js]
[test_417228-exclude-from-backup.js]
[test_417228-other-roots.js]
[test_424958-json-quoted-folders.js]
[test_448584.js]
[test_458683.js]

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

@ -217,7 +217,7 @@ function queryData(obj) {
this.isTag = obj.isTag ? obj.isTag : false;
this.tagArray = obj.tagArray ? obj.tagArray : null;
this.isLivemark = obj.isLivemark ? obj.isLivemark : false;
this.parentGuid = obj.parentGuid || PlacesUtils.bookmarks.rootGuid;
this.parentGuid = obj.parentGuid || PlacesUtils.bookmarks.unfiledGuid;
this.feedURI = obj.feedURI ? obj.feedURI : "";
this.index = obj.index ? obj.index : PlacesUtils.bookmarks.DEFAULT_INDEX;
this.isFolder = obj.isFolder ? obj.isFolder : false;

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

@ -2210,85 +2210,6 @@ add_task(async function test_pullChanges_restore_json_tracked() {
await PlacesSyncUtils.bookmarks.reset();
});
add_task(async function test_pullChanges_custom_roots() {
await ignoreChangedRoots();
info("Append items to Places root");
let unsyncedGuids = await populateTree(PlacesUtils.bookmarks.rootGuid, {
kind: "folder",
title: "rootFolder",
children: [{
kind: "bookmark",
title: "childBmk",
url: "https://example.com",
}, {
kind: "folder",
title: "childFolder",
children: [{
kind: "bookmark",
title: "grandChildBmk",
url: "https://example.org",
}],
}],
}, {
kind: "bookmark",
title: "rootBmk",
url: "https://example.net",
});
info("Append items to menu");
let syncedGuids = await populateTree(PlacesUtils.bookmarks.menuGuid, {
kind: "folder",
title: "childFolder",
children: [{
kind: "bookmark",
title: "grandChildBmk",
url: "https://example.info",
}],
});
{
let newChanges = await PlacesSyncUtils.bookmarks.pullChanges();
deepEqual(Object.keys(newChanges).sort(), ["menu", syncedGuids.childFolder,
syncedGuids.grandChildBmk].sort(),
"Pulling changes should ignore custom roots");
await setChangesSynced(newChanges);
}
info("Append sibling to custom root");
{
let unsyncedSibling = await PlacesUtils.bookmarks.insert({
parentGuid: unsyncedGuids.rootFolder,
url: "https://example.club",
});
let changes = await PlacesSyncUtils.bookmarks.pullChanges();
deepEqual(changes, {}, `Pulling changes should ignore unsynced sibling ${
unsyncedSibling.guid}`);
}
info("Remove custom root");
{
await PlacesUtils.bookmarks.remove(unsyncedGuids.rootFolder);
let changes = await PlacesSyncUtils.bookmarks.pullChanges();
deepEqual(changes, {}, "Removing custom root should not write tombstone");
}
info("Append sibling to menu");
{
let syncedSibling = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.menuGuid,
url: "https://example.ninja",
});
let changes = await PlacesSyncUtils.bookmarks.pullChanges();
deepEqual(Object.keys(changes).sort(), ["menu", syncedSibling.guid].sort(),
"Pulling changes should track synced sibling and parent");
await setChangesSynced(changes);
}
await PlacesUtils.bookmarks.eraseEverything();
await PlacesSyncUtils.bookmarks.reset();
});
add_task(async function test_pullChanges_tombstones() {
await ignoreChangedRoots();

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

@ -8,7 +8,6 @@ const bmsvc = PlacesUtils.bookmarks;
const tagssvc = PlacesUtils.tagging;
const annosvc = PlacesUtils.annotations;
const PT = PlacesTransactions;
const rootGuid = PlacesUtils.bookmarks.rootGuid;
const menuGuid = PlacesUtils.bookmarks.menuGuid;
Cu.importGlobalProperties(["URL"]);
@ -181,7 +180,8 @@ function ensureItemsAdded(...items) {
Assert.equal(info[propName], item[propName]);
}
if ("url" in item)
Assert.ok(info.url.equals(item.url));
Assert.ok(info.url.equals(Services.io.newURI(item.url)),
"Should have the correct url");
}
Assert.equal(observer.itemsAdded.size, expectedResultsCount,
@ -264,7 +264,7 @@ function ensureTimestampsUpdated(aGuid, aCheckDateAdded = false) {
}
function ensureTagsForURI(aURI, aTags) {
let tagsSet = tagssvc.getTagsForURI(aURI);
let tagsSet = tagssvc.getTagsForURI(Services.io.newURI(aURI));
Assert.equal(tagsSet.length, aTags.length);
Assert.ok(aTags.every( t => tagsSet.includes(t)));
}
@ -514,8 +514,8 @@ add_task(async function test_new_folder_with_children() {
});
add_task(async function test_new_bookmark() {
let bm_info = { parentGuid: rootGuid,
url: NetUtil.newURI("http://test_create_item.com"),
let bm_info = { parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: "http://test_create_item.com",
index: bmStartIndex,
title: "Test creating an item" };
@ -553,7 +553,7 @@ add_task(async function test_new_bookmark() {
add_task(async function test_merge_create_folder_and_item() {
let folder_info = createTestFolderInfo();
let bm_info = { url: NetUtil.newURI("http://test_create_item_to_folder.com"),
let bm_info = { url: "http://test_create_item_to_folder.com",
title: "Test Bookmark",
index: bmStartIndex };
@ -591,9 +591,9 @@ add_task(async function test_merge_create_folder_and_item() {
add_task(async function test_move_items_to_folder() {
let folder_a_info = createTestFolderInfo("Folder A");
let bkm_a_info = { url: new URL("http://test_move_items.com"),
let bkm_a_info = { url: "http://test_move_items.com",
title: "Bookmark A" };
let bkm_b_info = { url: NetUtil.newURI("http://test_move_items.com"),
let bkm_b_info = { url: "http://test_move_items.com",
title: "Bookmark B" };
// Test moving items within the same folder.
@ -792,7 +792,7 @@ add_task(async function test_remove_folder() {
});
add_task(async function test_add_and_remove_bookmarks_with_additional_info() {
const testURI = NetUtil.newURI("http://add.remove.tag");
const testURI = "http://add.remove.tag";
const TAG_1 = "TestTag1";
const TAG_2 = "TestTag2";
const ANNO = { name: "TestAnno", value: "TestAnnoValue" };
@ -975,8 +975,8 @@ add_task(async function test_creating_and_removing_a_separator() {
add_task(async function test_add_and_remove_livemark() {
let createLivemarkTxn = PT.NewLivemark(
{ feedUrl: NetUtil.newURI("http://test.remove.livemark"),
parentGuid: rootGuid,
{ feedUrl: "http://test.remove.livemark",
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
title: "Test Remove Livemark" });
let guid = await createLivemarkTxn.transact();
let originalInfo = await PlacesUtils.promiseBookmarksTree(guid);
@ -1018,9 +1018,11 @@ add_task(async function test_add_and_remove_livemark() {
});
add_task(async function test_edit_title() {
let bm_info = { parentGuid: rootGuid,
url: NetUtil.newURI("http://test_create_item.com"),
title: "Original Title" };
let bm_info = {
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: "http://test_create_item.com",
title: "Original Title"
};
function ensureTitleChange(aCurrentTitle) {
ensureItemsChanged({ guid: bm_info.guid,
@ -1054,13 +1056,13 @@ add_task(async function test_edit_title() {
});
add_task(async function test_edit_url() {
let oldURI = NetUtil.newURI("http://old.test_editing_item_uri.com/");
let newURI = NetUtil.newURI("http://new.test_editing_item_uri.com/");
let bm_info = { parentGuid: rootGuid, url: oldURI, tags: ["TestTag"] };
let oldURI = "http://old.test_editing_item_uri.com/";
let newURI = "http://new.test_editing_item_uri.com/";
let bm_info = { parentGuid: PlacesUtils.bookmarks.unfiledGuid, url: oldURI, tags: ["TestTag"] };
function ensureURIAndTags(aPreChangeURI, aPostChangeURI, aOLdURITagsPreserved) {
ensureItemsChanged({ guid: bm_info.guid,
property: "uri",
newValue: aPostChangeURI.spec });
newValue: aPostChangeURI });
ensureTagsForURI(aPostChangeURI, bm_info.tags);
ensureTagsForURI(aPreChangeURI, aOLdURITagsPreserved ? bm_info.tags : []);
}
@ -1118,8 +1120,8 @@ add_task(async function test_edit_url() {
});
add_task(async function test_edit_keyword() {
let bm_info = { parentGuid: rootGuid,
url: NetUtil.newURI("http://test.edit.keyword") };
let bm_info = { parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: "http://test.edit.keyword/" };
const KEYWORD = "test_keyword";
bm_info.guid = await PT.NewBookmark(bm_info).transact();
function ensureKeywordChange(aCurrentKeyword = "") {
@ -1134,7 +1136,7 @@ add_task(async function test_edit_keyword() {
await PT.EditKeyword({ guid: bm_info.guid, keyword: KEYWORD, postData: "postData" }).transact();
ensureKeywordChange(KEYWORD);
let entry = await PlacesUtils.keywords.fetch(KEYWORD);
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, "postData");
observer.reset();
@ -1147,7 +1149,7 @@ add_task(async function test_edit_keyword() {
await PT.redo();
ensureKeywordChange(KEYWORD);
entry = await PlacesUtils.keywords.fetch(KEYWORD);
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, "postData");
// Cleanup
@ -1162,8 +1164,8 @@ add_task(async function test_edit_keyword() {
});
add_task(async function test_edit_keyword_null_postData() {
let bm_info = { parentGuid: rootGuid,
url: NetUtil.newURI("http://test.edit.keyword") };
let bm_info = { parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: "http://test.edit.keyword/" };
const KEYWORD = "test_keyword";
bm_info.guid = await PT.NewBookmark(bm_info).transact();
function ensureKeywordChange(aCurrentKeyword = "") {
@ -1178,7 +1180,7 @@ add_task(async function test_edit_keyword_null_postData() {
await PT.EditKeyword({ guid: bm_info.guid, keyword: KEYWORD, postData: null }).transact();
ensureKeywordChange(KEYWORD);
let entry = await PlacesUtils.keywords.fetch(KEYWORD);
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, null);
observer.reset();
@ -1191,7 +1193,7 @@ add_task(async function test_edit_keyword_null_postData() {
await PT.redo();
ensureKeywordChange(KEYWORD);
entry = await PlacesUtils.keywords.fetch(KEYWORD);
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, null);
// Cleanup
@ -1206,8 +1208,8 @@ add_task(async function test_edit_keyword_null_postData() {
});
add_task(async function test_edit_specific_keyword() {
let bm_info = { parentGuid: rootGuid,
url: NetUtil.newURI("http://test.edit.keyword") };
let bm_info = { parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: "http://test.edit.keyword/" };
bm_info.guid = await PT.NewBookmark(bm_info).transact();
function ensureKeywordChange(aCurrentKeyword = "", aPreviousKeyword = "") {
ensureItemsChanged({ guid: bm_info.guid,
@ -1216,18 +1218,26 @@ add_task(async function test_edit_specific_keyword() {
});
}
await PlacesUtils.keywords.insert({ keyword: "kw1", url: bm_info.url.spec, postData: "postData1" });
await PlacesUtils.keywords.insert({ keyword: "kw2", url: bm_info.url.spec, postData: "postData2" });
await PlacesUtils.keywords.insert({
keyword: "kw1",
url: bm_info.url,
postData: "postData1"
});
await PlacesUtils.keywords.insert({
keyword: "kw2",
url: bm_info.url,
postData: "postData2"
});
bm_info.guid = await PT.NewBookmark(bm_info).transact();
observer.reset();
await PT.EditKeyword({ guid: bm_info.guid, keyword: "keyword", oldKeyword: "kw2" }).transact();
ensureKeywordChange("keyword", "kw2");
let entry = await PlacesUtils.keywords.fetch("kw1");
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, "postData1");
entry = await PlacesUtils.keywords.fetch("keyword");
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, "postData2");
entry = await PlacesUtils.keywords.fetch("kw2");
Assert.equal(entry, null);
@ -1236,10 +1246,10 @@ add_task(async function test_edit_specific_keyword() {
await PT.undo();
ensureKeywordChange("kw2", "keyword");
entry = await PlacesUtils.keywords.fetch("kw1");
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, "postData1");
entry = await PlacesUtils.keywords.fetch("kw2");
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, "postData2");
entry = await PlacesUtils.keywords.fetch("keyword");
Assert.equal(entry, null);
@ -1248,10 +1258,10 @@ add_task(async function test_edit_specific_keyword() {
await PT.redo();
ensureKeywordChange("keyword", "kw2");
entry = await PlacesUtils.keywords.fetch("kw1");
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, "postData1");
entry = await PlacesUtils.keywords.fetch("keyword");
Assert.equal(entry.url.href, bm_info.url.spec);
Assert.equal(entry.url.href, bm_info.url);
Assert.equal(entry.postData, "postData2");
entry = await PlacesUtils.keywords.fetch("kw2");
Assert.equal(entry, null);
@ -1270,10 +1280,10 @@ add_task(async function test_edit_specific_keyword() {
add_task(async function test_tag_uri() {
// This also tests passing uri specs.
let bm_info_a = { url: "http://bookmarked.uri",
parentGuid: rootGuid };
let bm_info_b = { url: NetUtil.newURI("http://bookmarked2.uri"),
parentGuid: rootGuid };
let unbookmarked_uri = NetUtil.newURI("http://un.bookmarked.uri");
parentGuid: PlacesUtils.bookmarks.unfiledGuid };
let bm_info_b = { url: "http://bookmarked2.uri",
parentGuid: PlacesUtils.bookmarks.unfiledGuid };
let unbookmarked_uri = "http://un.bookmarked.uri";
await PT.batch(async function() {
bm_info_a.guid = await PT.NewBookmark(bm_info_a).transact();
@ -1284,9 +1294,6 @@ add_task(async function test_tag_uri() {
let urls = "url" in aInfo ? [aInfo.url] : aInfo.urls;
let tags = "tag" in aInfo ? [aInfo.tag] : aInfo.tags;
let ensureURI = url => typeof(url) == "string" ? NetUtil.newURI(url) : url;
urls = urls.map(ensureURI);
let tagWillAlsoBookmark = new Set();
for (let url of urls) {
if (!(await bmsvc.fetch({ url }))) {
@ -1337,11 +1344,11 @@ add_task(async function test_tag_uri() {
});
add_task(async function test_untag_uri() {
let bm_info_a = { url: NetUtil.newURI("http://bookmarked.uri"),
parentGuid: rootGuid,
let bm_info_a = { url: "http://bookmarked.uri",
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
tags: ["A", "B"] };
let bm_info_b = { url: NetUtil.newURI("http://bookmarked2.uri"),
parentGuid: rootGuid,
let bm_info_b = { url: "http://bookmarked2.uri",
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
tag: "B" };
await PT.batch(async function() {
@ -1353,7 +1360,7 @@ add_task(async function test_untag_uri() {
async function doTest(aInfo) {
let urls, tagsRemoved;
if (aInfo instanceof Ci.nsIURI) {
if (typeof(aInfo) == "string") {
urls = [aInfo];
tagsRemoved = [];
} else if (Array.isArray(aInfo)) {
@ -1366,7 +1373,7 @@ add_task(async function test_untag_uri() {
let preRemovalTags = new Map();
for (let url of urls) {
preRemovalTags.set(url, tagssvc.getTagsForURI(url));
preRemovalTags.set(url, tagssvc.getTagsForURI(Services.io.newURI(url)));
}
function ensureTagsSet() {
@ -1412,8 +1419,8 @@ add_task(async function test_untag_uri() {
});
add_task(async function test_annotate() {
let bm_info = { url: NetUtil.newURI("http://test.item.annotation"),
parentGuid: rootGuid };
let bm_info = { url: "http://test.item.annotation",
parentGuid: PlacesUtils.bookmarks.unfiledGuid };
let anno_info = { name: "TestAnno", value: "TestValue" };
function ensureAnnoState(aSet) {
ensureAnnotationsSet(bm_info.guid,
@ -1513,7 +1520,7 @@ add_task(async function test_annotate_multiple() {
add_task(async function test_sort_folder_by_name() {
let folder_info = createTestFolderInfo();
let url = NetUtil.newURI("http://sort.by.name/");
let url = "http://sort.by.name/";
let preSep = ["3", "2", "1"].map(i => ({ title: i, url }));
let sep = {};
let postSep = ["c", "b", "a"].map(l => ({ title: l, url }));
@ -1557,8 +1564,8 @@ add_task(async function test_sort_folder_by_name() {
add_task(async function test_livemark_txns() {
let livemark_info =
{ feedUrl: NetUtil.newURI("http://test.feed.uri"),
parentGuid: rootGuid,
{ feedUrl: "http://test.feed.uri/",
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
title: "Test Livemark" };
function ensureLivemarkAdded() {
ensureItemsAdded({ guid: livemark_info.guid,
@ -1566,10 +1573,10 @@ add_task(async function test_livemark_txns() {
parentGuid: livemark_info.parentGuid,
itemType: bmsvc.TYPE_FOLDER });
let annos = [{ name: PlacesUtils.LMANNO_FEEDURI,
value: livemark_info.feedUrl.spec }];
value: livemark_info.feedUrl }];
if ("siteUrl" in livemark_info) {
annos.push({ name: PlacesUtils.LMANNO_SITEURI,
value: livemark_info.siteUrl.spec });
value: livemark_info.siteUrl });
}
ensureAnnotationsSet(livemark_info.guid, annos);
}
@ -1596,7 +1603,7 @@ add_task(async function test_livemark_txns() {
}
await _testDoUndoRedoUndo();
livemark_info.siteUrl = NetUtil.newURI("http://feed.site.uri");
livemark_info.siteUrl = "http://feed.site.uri/";
await _testDoUndoRedoUndo();
// Cleanup
@ -1606,7 +1613,9 @@ add_task(async function test_livemark_txns() {
add_task(async function test_copy() {
async function duplicate_and_test(aOriginalGuid) {
let txn = PT.Copy({ guid: aOriginalGuid, newParentGuid: rootGuid });
let txn = PT.Copy({
guid: aOriginalGuid, newParentGuid: PlacesUtils.bookmarks.unfiledGuid
});
let duplicateGuid = await txn.transact();
let originalInfo = await PlacesUtils.promiseBookmarksTree(aOriginalGuid);
let duplicateInfo = await PlacesUtils.promiseBookmarksTree(duplicateGuid);
@ -1644,13 +1653,16 @@ add_task(async function test_copy() {
});
// Test duplicating leafs (bookmark, separator, empty folder)
PT.NewBookmark({ url: new URL("http://test.item.duplicate"),
parentGuid: rootGuid,
PT.NewBookmark({ url: "http://test.item.duplicate",
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
annos: [{ name: "Anno", value: "AnnoValue"}] });
let sepTxn = PT.NewSeparator({ parentGuid: rootGuid, index: 1 });
let sepTxn = PT.NewSeparator({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
index: 1
});
let livemarkTxn = PT.NewLivemark(
{ feedUrl: new URL("http://test.feed.uri"),
parentGuid: rootGuid,
{ feedUrl: "http://test.feed.uri",
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
title: "Test Livemark", index: 1 });
let emptyFolderTxn = PT.NewFolder(createTestFolderInfo());
for (let txn of [livemarkTxn, sepTxn, emptyFolderTxn]) {
@ -1665,12 +1677,12 @@ add_task(async function test_copy() {
await PT.NewFolder({ parentGuid: folderGuid,
title: "Nested Folder" }).transact();
// Insert a bookmark under the nested folder.
await PT.NewBookmark({ url: new URL("http://nested.nested.bookmark"),
await PT.NewBookmark({ url: "http://nested.nested.bookmark",
parentGuid: nestedFolderGuid }).transact();
// Insert a separator below the nested folder
await PT.NewSeparator({ parentGuid: folderGuid }).transact();
// And another bookmark.
await PT.NewBookmark({ url: new URL("http://nested.bookmark"),
await PT.NewBookmark({ url: "http://nested.bookmark",
parentGuid: folderGuid }).transact();
return folderGuid;
});
@ -1730,13 +1742,13 @@ add_task(async function test_copy_excluding_annotations() {
let excluding_a_dupeGuid =
await PT.Copy({ guid: folderGuid,
newParentGuid: rootGuid,
newParentGuid: PlacesUtils.bookmarks.unfiledGuid,
excludingAnnotation: "a" }).transact();
await ensureAnnosSet(excluding_a_dupeGuid, "b", "c");
let excluding_ac_dupeGuid =
await PT.Copy({ guid: folderGuid,
newParentGuid: rootGuid,
newParentGuid: PlacesUtils.bookmarks.unfiledGuid,
excludingAnnotations: ["a", "c"] }).transact();
await ensureAnnosSet(excluding_ac_dupeGuid, "b");
@ -1749,7 +1761,7 @@ add_task(async function test_copy_excluding_annotations() {
add_task(async function test_invalid_uri_spec_throws() {
Assert.throws(() =>
PT.NewBookmark({ parentGuid: rootGuid,
PT.NewBookmark({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: "invalid uri spec",
title: "test bookmark" }));
Assert.throws(() =>
@ -1812,7 +1824,7 @@ add_task(async function test_remove_multiple() {
guids.push(folderGuid);
let bmGuid =
await PT.NewBookmark({ url: new URL("http://test.bookmark.removed"),
await PT.NewBookmark({ url: "http://test.bookmark.removed",
parentGuid: menuGuid }).transact();
guids.push(bmGuid);
});

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

@ -6790,11 +6790,24 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp)
return;
}
}
}
// Recalculate the width and height based on the client area for gecko events.
LayoutDeviceIntSize clientSize(newWidth, newHeight);
// Notify the widget listener for size change of client area for gecko
// events. This needs to be done when either window size is changed,
// or window frame is changed. They may not happen together.
// However, we don't invoke that for popup when window frame changes,
// because popups may trigger frame change before size change via
// {Set,Clear}ThemeRegion they invoke in Resize. That would make the
// code below call OnResize with a wrong client size first, which can
// lead to flickerling for some popups.
if (!(wp->flags & SWP_NOSIZE) ||
((wp->flags & SWP_FRAMECHANGED) && !IsPopup())) {
RECT r;
LayoutDeviceIntSize clientSize;
if (::GetClientRect(mWnd, &r)) {
clientSize = WinUtils::ToIntRect(r).Size();
} else {
clientSize = mBounds.Size();
}
// Send a gecko resize event
OnResize(clientSize);

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

@ -22,7 +22,7 @@ namespace mozilla {
*/
struct Module
{
static const unsigned int kVersion = 60;
static const unsigned int kVersion = 61;
struct CIDEntry;