Merge mozilla-cental to mozilla-inbound. r=merge

--HG--
extra : rebase_source : f7e0a6b0f2925bd159de4d665c02493dab9b6282
This commit is contained in:
Dorel Luca 2018-03-02 00:21:23 +02:00
Родитель a985338445 3ccafa2b66
Коммит 6735016b56
76 изменённых файлов: 1444 добавлений и 1393 удалений

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

@ -1472,7 +1472,7 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
{ {
nsAutoString role; nsAutoString role;
nsCoreUtils::XBLBindingRole(aContent, role); nsCoreUtils::XBLBindingRole(aContent, role);
if (role.IsEmpty() || role.EqualsLiteral("none")) if (role.IsEmpty())
return nullptr; return nullptr;
RefPtr<Accessible> accessible; RefPtr<Accessible> accessible;
@ -1487,9 +1487,6 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
} else if (role.EqualsLiteral("xul:link")) { } else if (role.EqualsLiteral("xul:link")) {
accessible = new XULLinkAccessible(aContent, aDoc); accessible = new XULLinkAccessible(aContent, aDoc);
} else if(role.EqualsLiteral("xul:pane")) {
accessible = new EnumRoleAccessible<roles::PANE>(aContent, aDoc);
} else if (role.EqualsLiteral("xul:panel")) { } else if (role.EqualsLiteral("xul:panel")) {
if (aContent->IsElement() && if (aContent->IsElement() &&
aContent->AsElement()->AttrValueIs(kNameSpaceID_None, aContent->AsElement()->AttrValueIs(kNameSpaceID_None,

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

@ -381,7 +381,7 @@ var FeedHandler = {
// http://foo.com/index.rdf -> feed://foo.com/index.rdf // http://foo.com/index.rdf -> feed://foo.com/index.rdf
// other urls: prepend feed: scheme, e.g. // other urls: prepend feed: scheme, e.g.
// https://foo.com/index.rdf -> feed:https://foo.com/index.rdf // https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
let feedURI = NetUtil.newURI(aSpec); let feedURI = Services.io.newURI(aSpec);
if (feedURI.schemeIs("http")) { if (feedURI.schemeIs("http")) {
feedURI = feedURI.mutate() feedURI = feedURI.mutate()
.setScheme("feed") .setScheme("feed")

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

@ -481,7 +481,7 @@ var PlacesCommandHook = {
let parentGuid = parentId == PlacesUtils.bookmarksMenuFolderId ? let parentGuid = parentId == PlacesUtils.bookmarksMenuFolderId ?
PlacesUtils.bookmarks.menuGuid : PlacesUtils.bookmarks.menuGuid :
await PlacesUtils.promiseItemGuid(parentId); await PlacesUtils.promiseItemGuid(parentId);
let defaultInsertionPoint = new InsertionPoint({ parentId, parentGuid }); let defaultInsertionPoint = new PlacesInsertionPoint({ parentId, parentGuid });
PlacesUIUtils.showBookmarkDialog({ action: "add", PlacesUIUtils.showBookmarkDialog({ action: "add",
type: "bookmark", type: "bookmark",
uri: makeURI(url), uri: makeURI(url),
@ -557,7 +557,7 @@ var PlacesCommandHook = {
* A short description of the feed. Optional. * A short description of the feed. Optional.
*/ */
async addLiveBookmark(url, feedTitle, feedSubtitle) { async addLiveBookmark(url, feedTitle, feedSubtitle) {
let toolbarIP = new InsertionPoint({ let toolbarIP = new PlacesInsertionPoint({
parentId: PlacesUtils.toolbarFolderId, parentId: PlacesUtils.toolbarFolderId,
parentGuid: PlacesUtils.bookmarks.toolbarGuid parentGuid: PlacesUtils.bookmarks.toolbarGuid
}); });
@ -993,7 +993,7 @@ var PlacesMenuDNDHandler = {
* The DragOver event. * The DragOver event.
*/ */
onDragOver: function PMDH_onDragOver(event) { onDragOver: function PMDH_onDragOver(event) {
let ip = new InsertionPoint({ let ip = new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId, parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid parentGuid: PlacesUtils.bookmarks.menuGuid
}); });
@ -1010,7 +1010,7 @@ var PlacesMenuDNDHandler = {
*/ */
onDrop: function PMDH_onDrop(event) { onDrop: function PMDH_onDrop(event) {
// Put the item at the end of bookmark menu. // Put the item at the end of bookmark menu.
let ip = new InsertionPoint({ let ip = new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId, parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid parentGuid: PlacesUtils.bookmarks.menuGuid
}); });

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

@ -34,6 +34,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm", LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
Log: "resource://gre/modules/Log.jsm", Log: "resource://gre/modules/Log.jsm",
LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm", LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm",
NetUtil: "resource://gre/modules/NetUtil.jsm",
NewTabUtils: "resource://gre/modules/NewTabUtils.jsm", NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
OpenInTabsUtils: "resource:///modules/OpenInTabsUtils.jsm", OpenInTabsUtils: "resource:///modules/OpenInTabsUtils.jsm",
PageActions: "resource:///modules/PageActions.jsm", PageActions: "resource:///modules/PageActions.jsm",

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

@ -16,6 +16,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
WebNavigationFrames: "resource://gre/modules/WebNavigationFrames.jsm", WebNavigationFrames: "resource://gre/modules/WebNavigationFrames.jsm",
ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm", ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
DevToolsShim: "chrome://devtools-shim/content/DevToolsShim.jsm", DevToolsShim: "chrome://devtools-shim/content/DevToolsShim.jsm",
NetUtil: "resource://gre/modules/NetUtil.jsm",
}); });
var gContextMenuContentData = null; var gContextMenuContentData = null;

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

@ -69,6 +69,72 @@ let whitelist = [
intermittent: true, intermittent: true,
errorMessage: /Property contained reference to invalid variable.*color/i, errorMessage: /Property contained reference to invalid variable.*color/i,
isFromDevTools: true}, isFromDevTools: true},
// These are CSS custom properties that we found a definition of but
// no reference to.
// Bug 1441837
{propName: "--in-content-category-text-active",
isFromDevTools: false},
// Bug 1441844
{propName: "--chrome-nav-bar-separator-color",
isFromDevTools: false},
// Bug 1441855
{propName: "--chrome-nav-buttons-background",
isFromDevTools: false},
// Bug 1441855
{propName: "--chrome-nav-buttons-hover-background",
isFromDevTools: false},
// Bug 1441857
{propName: "--muteButton-width",
isFromDevTools: false},
// Bug 1441857
{propName: "--closedCaptionButton-width",
isFromDevTools: false},
// Bug 1441857
{propName: "--fullscreenButton-width",
isFromDevTools: false},
// Bug 1441857
{propName: "--durationSpan-width",
isFromDevTools: false},
// Bug 1441857
{propName: "--durationSpan-width-long",
isFromDevTools: false},
// Bug 1441857
{propName: "--positionDurationBox-width",
isFromDevTools: false},
// Bug 1441857
{propName: "--positionDurationBox-width-long",
isFromDevTools: false},
// Bug 1441860
{propName: "--rule-flex-toggle-color",
isFromDevTools: true},
// Bug 1441929
{propName: "--theme-search-overlays-semitransparent",
isFromDevTools: true},
// Bug 1441878
{propName: "--theme-codemirror-gutter-background",
isFromDevTools: true},
// Bug 1441879
{propName: "--arrow-width",
isFromDevTools: true},
// Bug 1442300
{propName: "--in-content-category-background",
isFromDevTools: false},
// Bug 1442314
{propName: "--separator-border-image",
isFromDevTools: true},
// Used on Linux
{propName: "--in-content-box-background-odd",
platforms: ["win", "macosx"],
isFromDevTools: false},
// These properties *are* actually referenced. Need to find why
// their reference isn't getting counted.
{propName: "--bezier-diagonal-color",
isFromDevTools: true},
{propName: "--bezier-grid-color",
isFromDevTools: true},
]; ];
if (!Services.prefs.getBoolPref("full-screen-api.unprefix.enabled")) { if (!Services.prefs.getBoolPref("full-screen-api.unprefix.enabled")) {
@ -194,6 +260,7 @@ function messageIsCSSError(msg) {
} }
let imageURIsToReferencesMap = new Map(); let imageURIsToReferencesMap = new Map();
let customPropsToReferencesMap = new Map();
function processCSSRules(sheet) { function processCSSRules(sheet) {
for (let rule of sheet.cssRules) { for (let rule of sheet.cssRules) {
@ -208,10 +275,11 @@ function processCSSRules(sheet) {
// Note: CSSStyleRule.cssText always has double quotes around URLs even // Note: CSSStyleRule.cssText always has double quotes around URLs even
// when the original CSS file didn't. // when the original CSS file didn't.
let urls = rule.cssText.match(/url\("[^"]*"\)/g); let urls = rule.cssText.match(/url\("[^"]*"\)/g);
if (!urls) let props = rule.cssText.match(/(var\()?(--[\w\-]+)/g);
if (!urls && !props)
continue; continue;
for (let url of urls) { for (let url of (urls || [])) {
// Remove the url(" prefix and the ") suffix. // Remove the url(" prefix and the ") suffix.
url = url.replace(/url\("(.*)"\)/, "$1"); url = url.replace(/url\("(.*)"\)/, "$1");
if (url.startsWith("data:")) if (url.startsWith("data:"))
@ -229,6 +297,16 @@ function processCSSRules(sheet) {
imageURIsToReferencesMap.get(url).add(baseUrl); imageURIsToReferencesMap.get(url).add(baseUrl);
} }
} }
for (let prop of (props || [])) {
if (prop.startsWith("var(")) {
prop = prop.substring(4);
let prevValue = customPropsToReferencesMap.get(prop) || 0;
customPropsToReferencesMap.set(prop, prevValue + 1);
} else if (!customPropsToReferencesMap.has(prop)) {
customPropsToReferencesMap.set(prop, undefined);
}
}
} }
} }
@ -354,6 +432,26 @@ add_task(async function checkAllTheCSS() {
} }
} }
// Check if all the properties that are defined are referenced.
for (let [prop, refCount] of customPropsToReferencesMap) {
if (!refCount) {
let ignored = false;
for (let item of whitelist) {
if (item.propName == prop &&
isDevtools == item.isFromDevTools) {
item.used = true;
if (!item.platforms || item.platforms.includes(AppConstants.platform)) {
ignored = true;
}
break;
}
}
if (!ignored) {
ok(false, "custom property `" + prop + "` is not referenced");
}
}
}
let messages = Services.console.getMessageArray(); let messages = Services.console.getMessageArray();
// Count errors (the test output will list actual issues for us, as well // Count errors (the test output will list actual issues for us, as well
// as the ok(false) in messageIsCSSError. // as the ok(false) in messageIsCSSError.
@ -362,8 +460,12 @@ add_task(async function checkAllTheCSS() {
// Confirm that all whitelist rules have been used. // Confirm that all whitelist rules have been used.
for (let item of whitelist) { for (let item of whitelist) {
if (!item.used && isDevtools == item.isFromDevTools && !item.intermittent) { if (!item.used &&
(!item.platforms || item.platforms.includes(AppConstants.platform)) &&
isDevtools == item.isFromDevTools &&
!item.intermittent) {
ok(false, "Unused whitelist item. " + ok(false, "Unused whitelist item. " +
(item.propName ? " propName: " + item.propName : "") +
(item.sourceName ? " sourceName: " + item.sourceName : "") + (item.sourceName ? " sourceName: " + item.sourceName : "") +
(item.errorMessage ? " errorMessage: " + item.errorMessage : "")); (item.errorMessage ? " errorMessage: " + item.errorMessage : ""));
} }
@ -388,4 +490,5 @@ add_task(async function checkAllTheCSS() {
hiddenFrame.destroy(); hiddenFrame.destroy();
hiddenFrame = null; hiddenFrame = null;
imageURIsToReferencesMap = null; imageURIsToReferencesMap = null;
customPropsToReferencesMap = null;
}); });

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

@ -256,61 +256,6 @@ var PlacesUIUtils = {
return bundle.GetStringFromName(key); return bundle.GetStringFromName(key);
}, },
/**
* Constructs a Places Transaction for the drop or paste of a blob of data
* into a container.
*
* @param aData
* The unwrapped data blob of dropped or pasted data.
* @param aNewParentGuid
* GUID of the container the data was dropped or pasted into.
* @param aIndex
* The index within the container the item was dropped or pasted at.
* @param aCopy
* The drag action was copy, so don't move folders or links.
*
* @return a Places Transaction that can be transacted for performing the
* move/insert command.
*/
getTransactionForData(aData, aNewParentGuid, aIndex, aCopy) {
if (!this.SUPPORTED_FLAVORS.includes(aData.type))
throw new Error(`Unsupported '${aData.type}' data type`);
if ("itemGuid" in aData && "instanceId" in aData &&
aData.instanceId == PlacesUtils.instanceId) {
if (!this.PLACES_FLAVORS.includes(aData.type))
throw new Error(`itemGuid unexpectedly set on ${aData.type} data`);
let info = { guid: aData.itemGuid,
newParentGuid: aNewParentGuid,
newIndex: aIndex };
if (aCopy) {
info.excludingAnnotation = "Places/SmartBookmark";
return PlacesTransactions.Copy(info);
}
return PlacesTransactions.Move(info);
}
// Since it's cheap and harmless, we allow the paste of separators and
// bookmarks from builds that use legacy transactions (i.e. when itemGuid
// was not set on PLACES_FLAVORS data). Containers are a different story,
// and thus disallowed.
if (aData.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER)
throw new Error("Can't copy a container from a legacy-transactions build");
if (aData.type == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR) {
return PlacesTransactions.NewSeparator({ parentGuid: aNewParentGuid,
index: aIndex });
}
let title = aData.type != PlacesUtils.TYPE_UNICODE ? aData.title
: aData.uri;
return PlacesTransactions.NewBookmark({ url: Services.io.newURI(aData.uri),
title,
parentGuid: aNewParentGuid,
index: aIndex });
},
/** /**
* Shows the bookmark dialog corresponding to the specified info. * Shows the bookmark dialog corresponding to the specified info.
* *
@ -404,6 +349,77 @@ var PlacesUIUtils = {
return null; return null;
}, },
/**
* Returns the active PlacesController for a given command.
*
* @param win The window containing the affected view
* @param command The command
* @return a PlacesController
*/
getControllerForCommand(win, command) {
// A context menu may be built for non-focusable views. Thus, we first try
// to look for a view associated with document.popupNode
let popupNode;
try {
popupNode = win.document.popupNode;
} catch (e) {
// The document went away (bug 797307).
return null;
}
if (popupNode) {
let view = this.getViewForNode(popupNode);
if (view && view._contextMenuShown)
return view.controllers.getControllerForCommand(command);
}
// When we're not building a context menu, only focusable views
// are possible. Thus, we can safely use the command dispatcher.
let controller = win.top.document.commandDispatcher
.getControllerForCommand(command);
return controller || null;
},
/**
* Update all the Places commands for the given window.
*
* @param win The window to update.
*/
updateCommands(win) {
// Get the controller for one of the places commands.
let controller = this.getControllerForCommand(win, "placesCmd_open");
for (let command of [
"placesCmd_open",
"placesCmd_open:window",
"placesCmd_open:privatewindow",
"placesCmd_open:tab",
"placesCmd_new:folder",
"placesCmd_new:bookmark",
"placesCmd_new:separator",
"placesCmd_show:info",
"placesCmd_reload",
"placesCmd_sortBy:name",
"placesCmd_cut",
"placesCmd_copy",
"placesCmd_paste",
"placesCmd_delete",
]) {
win.goSetCommandEnabled(command,
controller && controller.isCommandEnabled(command));
}
},
/**
* Executes the given command on the currently active controller.
*
* @param win The window containing the affected view
* @param command The command to execute
*/
doCommand(win, command) {
let controller = this.getControllerForCommand(win, command);
if (controller && controller.isCommandEnabled(command))
controller.doCommand(command);
},
/** /**
* By calling this before visiting an URL, the visit will be associated to a * By calling this before visiting an URL, the visit will be associated to a
* TRANSITION_TYPED transition (if there is no a referrer). * TRANSITION_TYPED transition (if there is no a referrer).
@ -1176,19 +1192,135 @@ var PlacesUIUtils = {
} }
} }
}, },
/**
* Constructs a Places Transaction for the drop or paste of a blob of data
* into a container.
*
* @param aData
* The unwrapped data blob of dropped or pasted data.
* @param aNewParentGuid
* GUID of the container the data was dropped or pasted into.
* @param aIndex
* The index within the container the item was dropped or pasted at.
* @param aCopy
* The drag action was copy, so don't move folders or links.
*
* @return a Places Transaction that can be transacted for performing the
* move/insert command.
*/
getTransactionForData(aData, aNewParentGuid, aIndex, aCopy) {
if (!this.SUPPORTED_FLAVORS.includes(aData.type))
throw new Error(`Unsupported '${aData.type}' data type`);
if ("itemGuid" in aData && "instanceId" in aData &&
aData.instanceId == PlacesUtils.instanceId) {
if (!this.PLACES_FLAVORS.includes(aData.type))
throw new Error(`itemGuid unexpectedly set on ${aData.type} data`);
let info = { guid: aData.itemGuid,
newParentGuid: aNewParentGuid,
newIndex: aIndex };
if (aCopy) {
info.excludingAnnotation = "Places/SmartBookmark";
return PlacesTransactions.Copy(info);
}
return PlacesTransactions.Move(info);
}
// Since it's cheap and harmless, we allow the paste of separators and
// bookmarks from builds that use legacy transactions (i.e. when itemGuid
// was not set on PLACES_FLAVORS data). Containers are a different story,
// and thus disallowed.
if (aData.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER)
throw new Error("Can't copy a container from a legacy-transactions build");
if (aData.type == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR) {
return PlacesTransactions.NewSeparator({ parentGuid: aNewParentGuid,
index: aIndex });
}
let title = aData.type != PlacesUtils.TYPE_UNICODE ? aData.title
: aData.uri;
return PlacesTransactions.NewBookmark({ url: Services.io.newURI(aData.uri),
title,
parentGuid: aNewParentGuid,
index: aIndex });
},
/**
* Processes a set of transfer items that have been dropped or pasted.
* Batching will be applied where necessary.
*
* @param {Array} items A list of unwrapped nodes to process.
* @param {Object} insertionPoint The requested point for insertion.
* @param {Boolean} doCopy Set to true to copy the items, false will move them
* if possible.
* @paramt {Object} view The view that should be used for batching.
* @return {Array} Returns an empty array when the insertion point is a tag, else
* returns an array of copied or moved guids.
*/
async handleTransferItems(items, insertionPoint, doCopy, view) {
let transactions;
let itemsCount;
if (insertionPoint.isTag) {
let urls = items.filter(item => "uri" in item).map(item => item.uri);
itemsCount = urls.length;
transactions = [PlacesTransactions.Tag({ urls, tag: insertionPoint.tagName })];
} else {
let insertionIndex = await insertionPoint.getIndex();
itemsCount = items.length;
transactions = await getTransactionsForTransferItems(
items, insertionIndex, insertionPoint.guid, doCopy);
}
// Check if we actually have something to add, if we don't it probably wasn't
// valid, or it was moving to the same location, so just ignore it.
if (!transactions.length) {
return [];
}
let guidsToSelect = [];
let resultForBatching = getResultForBatching(view);
// If we're inserting into a tag, we don't get the guid, so we'll just
// pass the transactions direct to the batch function.
let batchingItem = transactions;
if (!insertionPoint.isTag) {
// If we're not a tag, then we need to get the ids of the items to select.
batchingItem = async () => {
for (let transaction of transactions) {
let guid = await transaction.transact();
if (guid) {
guidsToSelect.push(guid);
}
}
};
}
await this.batchUpdatesForNode(resultForBatching, itemsCount, async () => {
await PlacesTransactions.batch(batchingItem);
});
return guidsToSelect;
},
}; };
// These are lazy getters to avoid importing PlacesUtils immediately.
PlacesUIUtils.PLACES_FLAVORS = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, XPCOMUtils.defineLazyGetter(PlacesUIUtils, "PLACES_FLAVORS", () => {
PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, return [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
PlacesUtils.TYPE_X_MOZ_PLACE]; PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
PlacesUtils.TYPE_X_MOZ_PLACE];
PlacesUIUtils.URI_FLAVORS = [PlacesUtils.TYPE_X_MOZ_URL, });
TAB_DROP_TYPE, XPCOMUtils.defineLazyGetter(PlacesUIUtils, "URI_FLAVORS", () => {
PlacesUtils.TYPE_UNICODE], return [PlacesUtils.TYPE_X_MOZ_URL,
TAB_DROP_TYPE,
PlacesUIUtils.SUPPORTED_FLAVORS = [...PlacesUIUtils.PLACES_FLAVORS, PlacesUtils.TYPE_UNICODE];
...PlacesUIUtils.URI_FLAVORS]; });
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "SUPPORTED_FLAVORS", () => {
return [...PlacesUIUtils.PLACES_FLAVORS,
...PlacesUIUtils.URI_FLAVORS];
});
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ellipsis", function() { XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ellipsis", function() {
return Services.prefs.getComplexValue("intl.ellipsis", return Services.prefs.getComplexValue("intl.ellipsis",
@ -1201,3 +1333,117 @@ XPCOMUtils.defineLazyPreferenceGetter(PlacesUIUtils, "loadBookmarksInTabs",
PREF_LOAD_BOOKMARKS_IN_TABS, false); PREF_LOAD_BOOKMARKS_IN_TABS, false);
XPCOMUtils.defineLazyPreferenceGetter(PlacesUIUtils, "openInTabClosesMenu", XPCOMUtils.defineLazyPreferenceGetter(PlacesUIUtils, "openInTabClosesMenu",
"browser.bookmarks.openInTabClosesMenu", false); "browser.bookmarks.openInTabClosesMenu", false);
/**
* Determines if an unwrapped node can be moved.
*
* @param unwrappedNode
* A node unwrapped by PlacesUtils.unwrapNodes().
* @return True if the node can be moved, false otherwise.
*/
function canMoveUnwrappedNode(unwrappedNode) {
if ((unwrappedNode.concreteGuid && PlacesUtils.isRootItem(unwrappedNode.concreteGuid)) ||
unwrappedNode.id <= 0 || PlacesUtils.isRootItem(unwrappedNode.id)) {
return false;
}
let parentGuid = unwrappedNode.parentGuid;
// If there's no parent Guid, this was likely a virtual query that returns
// bookmarks, such as a tags query.
if (!parentGuid ||
parentGuid == PlacesUtils.bookmarks.rootGuid) {
return false;
}
// leftPaneFolderId and allBookmarksFolderId are lazy getters running
// at least a synchronous DB query. Therefore we don't want to invoke
// them first, especially because isCommandEnabled may be called way
// before the left pane folder is even necessary.
if (typeof Object.getOwnPropertyDescriptor(PlacesUIUtils, "leftPaneFolderId").get != "function" &&
(unwrappedNode.parent == PlacesUIUtils.leftPaneFolderId)) {
return false;
}
return true;
}
/**
* This gets the most appropriate item for using for batching. In the case of multiple
* views being related, the method returns the most expensive result to batch.
* For example, if it detects the left-hand library pane, then it will look for
* and return the reference to the right-hand pane.
*
* @param {Object} viewOrElement The item to check.
* @return {Object} Will return the best result node to batch, or null
* if one could not be found.
*/
function getResultForBatching(viewOrElement) {
if (viewOrElement && viewOrElement instanceof Ci.nsIDOMElement &&
viewOrElement.id === "placesList") {
// Note: fall back to the existing item if we can't find the right-hane pane.
viewOrElement = viewOrElement.ownerDocument.getElementById("placeContent") || viewOrElement;
}
if (viewOrElement && viewOrElement.result) {
return viewOrElement.result;
}
return null;
}
/**
* Processes a set of transfer items and returns transactions to insert or
* move them.
*
* @param {Array} items A list of unwrapped nodes to get transactions for.
* @param {Integer} insertionIndex The requested index for insertion.
* @param {String} insertionParentGuid The guid of the parent folder to insert
* or move the items to.
* @param {Boolean} doCopy Set to true to copy the items, false will move them
* if possible.
* @return {Array} Returns an array of created PlacesTransactions.
*/
async function getTransactionsForTransferItems(items, insertionIndex,
insertionParentGuid, doCopy) {
let transactions = [];
let index = insertionIndex;
for (let item of items) {
if (index != -1 && item.itemGuid) {
// Note: we use the parent from the existing bookmark as the sidebar
// gives us an unwrapped.parent that is actually a query and not the real
// parent.
let existingBookmark = await PlacesUtils.bookmarks.fetch(item.itemGuid);
// If we're dropping on the same folder, then we may need to adjust
// the index to insert at the correct place.
if (existingBookmark && insertionParentGuid == existingBookmark.parentGuid) {
if (index > existingBookmark.index) {
// If we're dragging down, we need to go one lower to insert at
// the real point as moving the element changes the index of
// everything below by 1.
index--;
} else if (index == existingBookmark.index) {
// This isn't moving so we skip it.
continue;
}
}
}
// If this is not a copy, check for safety that we can move the
// source, otherwise report an error and fallback to a copy.
if (!doCopy && !canMoveUnwrappedNode(item)) {
Cu.reportError("Tried to move an unmovable Places " +
"node, reverting to a copy operation.");
doCopy = true;
}
transactions.push(
PlacesUIUtils.getTransactionForData(item,
insertionParentGuid,
index,
doCopy));
if (index != -1 && item.itemGuid) {
index++;
}
}
return transactions;
}

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

@ -161,7 +161,7 @@ var BookmarkPropertiesPanel = {
this._defaultInsertionPoint = dialogInfo.defaultInsertionPoint; this._defaultInsertionPoint = dialogInfo.defaultInsertionPoint;
} else { } else {
this._defaultInsertionPoint = this._defaultInsertionPoint =
new InsertionPoint({ new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId, parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid parentGuid: PlacesUtils.bookmarks.menuGuid
}); });

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

@ -217,10 +217,10 @@ PlacesViewBase.prototype = {
} }
} }
if (PlacesControllerDragHelper.disallowInsertion(container, this)) if (this.controller.disallowInsertion(container))
return null; return null;
return new InsertionPoint({ return new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(container), parentId: PlacesUtils.getConcreteItemId(container),
parentGuid: PlacesUtils.getConcreteItemGuid(container), parentGuid: PlacesUtils.getConcreteItemGuid(container),
index, orientation, tagName index, orientation, tagName
@ -1519,7 +1519,7 @@ PlacesToolbar.prototype = {
: (aEvent.clientX < eltRect.left + threshold)) { : (aEvent.clientX < eltRect.left + threshold)) {
// Drop before this folder. // Drop before this folder.
dropPoint.ip = dropPoint.ip =
new InsertionPoint({ new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode), parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode), parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
index: eltIndex, index: eltIndex,
@ -1532,7 +1532,7 @@ PlacesToolbar.prototype = {
let tagName = PlacesUtils.nodeIsTagQuery(elt._placesNode) ? let tagName = PlacesUtils.nodeIsTagQuery(elt._placesNode) ?
elt._placesNode.title : null; elt._placesNode.title : null;
dropPoint.ip = dropPoint.ip =
new InsertionPoint({ new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(elt._placesNode), parentId: PlacesUtils.getConcreteItemId(elt._placesNode),
parentGuid: PlacesUtils.getConcreteItemGuid(elt._placesNode), parentGuid: PlacesUtils.getConcreteItemGuid(elt._placesNode),
tagName tagName
@ -1546,7 +1546,7 @@ PlacesToolbar.prototype = {
-1 : eltIndex + 1; -1 : eltIndex + 1;
dropPoint.ip = dropPoint.ip =
new InsertionPoint({ new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode), parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode), parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
index: beforeIndex, index: beforeIndex,
@ -1562,7 +1562,7 @@ PlacesToolbar.prototype = {
: (aEvent.clientX < eltRect.left + threshold)) { : (aEvent.clientX < eltRect.left + threshold)) {
// Drop before this bookmark. // Drop before this bookmark.
dropPoint.ip = dropPoint.ip =
new InsertionPoint({ new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode), parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode), parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
index: eltIndex, index: eltIndex,
@ -1575,7 +1575,7 @@ PlacesToolbar.prototype = {
eltIndex == this._rootElt.childNodes.length - 1 ? eltIndex == this._rootElt.childNodes.length - 1 ?
-1 : eltIndex + 1; -1 : eltIndex + 1;
dropPoint.ip = dropPoint.ip =
new InsertionPoint({ new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode), parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode), parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
index: beforeIndex, index: beforeIndex,
@ -1588,7 +1588,7 @@ PlacesToolbar.prototype = {
// We are most likely dragging on the empty area of the // We are most likely dragging on the empty area of the
// toolbar, we should drop after the last node. // toolbar, we should drop after the last node.
dropPoint.ip = dropPoint.ip =
new InsertionPoint({ new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode), parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode), parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
orientation: Ci.nsITreeView.DROP_BEFORE orientation: Ci.nsITreeView.DROP_BEFORE

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

@ -3,13 +3,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
ChromeUtils.defineModuleGetter(this, "ForgetAboutSite",
"resource://gre/modules/ForgetAboutSite.jsm");
ChromeUtils.defineModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
/** /**
* Represents an insertion point within a container where we can insert * Represents an insertion point within a container where we can insert
* items. * items.
@ -30,11 +23,11 @@ ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
* - dropNearNode * - dropNearNode
* When defined index will be calculated based on this node * When defined index will be calculated based on this node
*/ */
function InsertionPoint({ parentId, parentGuid, function PlacesInsertionPoint({ parentId, parentGuid,
index = PlacesUtils.bookmarks.DEFAULT_INDEX, index = PlacesUtils.bookmarks.DEFAULT_INDEX,
orientation = Ci.nsITreeView.DROP_ON, orientation = Ci.nsITreeView.DROP_ON,
tagName = null, tagName = null,
dropNearNode = null }) { dropNearNode = null }) {
this.itemId = parentId; this.itemId = parentId;
this.guid = parentGuid; this.guid = parentGuid;
this._index = index; this._index = index;
@ -43,7 +36,7 @@ function InsertionPoint({ parentId, parentGuid,
this.dropNearNode = dropNearNode; this.dropNearNode = dropNearNode;
} }
InsertionPoint.prototype = { PlacesInsertionPoint.prototype = {
set index(val) { set index(val) {
return this._index = val; return this._index = val;
}, },
@ -230,7 +223,7 @@ PlacesController.prototype = {
var queries = this._view.selectedNode.getQueries(); var queries = this._view.selectedNode.getQueries();
host = queries[0].domain; host = queries[0].domain;
} else } else
host = NetUtil.newURI(this._view.selectedNode.uri).host; host = Services.io.newURI(this._view.selectedNode.uri).host;
ForgetAboutSite.removeDataFromDomain(host) ForgetAboutSite.removeDataFromDomain(host)
.catch(Cu.reportError); .catch(Cu.reportError);
break; break;
@ -275,7 +268,7 @@ PlacesController.prototype = {
"keyword", "keyword",
"location", "location",
"loadInSidebar" ], "loadInSidebar" ],
uri: NetUtil.newURI(node.uri), uri: Services.io.newURI(node.uri),
title: node.title title: node.title
}, window.top); }, window.top);
break; break;
@ -428,7 +421,7 @@ PlacesController.prototype = {
break; break;
case Ci.nsINavHistoryResultNode.RESULT_TYPE_URI: case Ci.nsINavHistoryResultNode.RESULT_TYPE_URI:
nodeData.link = true; nodeData.link = true;
uri = NetUtil.newURI(node.uri); uri = Services.io.newURI(node.uri);
if (PlacesUtils.nodeIsBookmark(node)) { if (PlacesUtils.nodeIsBookmark(node)) {
nodeData.bookmark = true; nodeData.bookmark = true;
var parentNode = node.parent; var parentNode = node.parent;
@ -1213,7 +1206,7 @@ PlacesController.prototype = {
} }
let doCopy = action == "copy"; let doCopy = action == "copy";
let itemsToSelect = await handleTransferItems(items, ip, doCopy, this._view); let itemsToSelect = await PlacesUIUtils.handleTransferItems(items, ip, doCopy, this._view);
// Cut/past operations are not repeatable, so clear the clipboard. // Cut/past operations are not repeatable, so clear the clipboard.
if (action == "cut") { if (action == "cut") {
@ -1256,7 +1249,41 @@ PlacesController.prototype = {
*/ */
getCachedLivemarkInfo: function PC_getCachedLivemarkInfo(aNode) { getCachedLivemarkInfo: function PC_getCachedLivemarkInfo(aNode) {
return this._cachedLivemarkInfoObjects.get(aNode, null); return this._cachedLivemarkInfoObjects.get(aNode, null);
} },
/**
* Checks if we can insert into a container.
* @param container
* The container were we are want to drop
*/
disallowInsertion(container) {
NS_ASSERT(container, "empty container");
// Allow dropping into Tag containers and editable folders.
return !PlacesUtils.nodeIsTagQuery(container) &&
(!PlacesUtils.nodeIsFolder(container) ||
PlacesUIUtils.isFolderReadOnly(container, this._view));
},
/**
* Determines if a node can be moved.
*
* @param aNode
* A nsINavHistoryResultNode node.
* @return True if the node can be moved, false otherwise.
*/
canMoveNode(node) {
// Only bookmark items are movable.
if (node.itemId == -1)
return false;
// Once tags and bookmarked are divorced, the tag-query check should be
// removed.
let parentNode = node.parent;
return parentNode != null &&
PlacesUtils.nodeIsFolder(parentNode) &&
!PlacesUIUtils.isFolderReadOnly(parentNode, this._view) &&
!PlacesUtils.nodeIsTagQuery(parentNode);
},
}; };
/** /**
@ -1378,62 +1405,6 @@ var PlacesControllerDragHelper = {
return true; return true;
}, },
/**
* Determines if an unwrapped node can be moved.
*
* @param unwrappedNode
* A node unwrapped by PlacesUtils.unwrapNodes().
* @return True if the node can be moved, false otherwise.
*/
canMoveUnwrappedNode(unwrappedNode) {
if ((unwrappedNode.concreteGuid && PlacesUtils.isRootItem(unwrappedNode.concreteGuid)) ||
unwrappedNode.id <= 0 || PlacesUtils.isRootItem(unwrappedNode.id)) {
return false;
}
let parentGuid = unwrappedNode.parentGuid;
// If there's no parent Guid, this was likely a virtual query that returns
// bookmarks, such as a tags query.
if (!parentGuid ||
parentGuid == PlacesUtils.bookmarks.rootGuid) {
return false;
}
// leftPaneFolderId and allBookmarksFolderId are lazy getters running
// at least a synchronous DB query. Therefore we don't want to invoke
// them first, especially because isCommandEnabled may be called way
// before the left pane folder is even necessary.
if (typeof Object.getOwnPropertyDescriptor(PlacesUIUtils, "leftPaneFolderId").get != "function" &&
(unwrappedNode.parent == PlacesUIUtils.leftPaneFolderId)) {
return false;
}
return true;
},
/**
* Determines if a node can be moved.
*
* @param aNode
* A nsINavHistoryResultNode node.
* @param aView
* The view originating the request
* @param [optional] aDOMNode
* A XUL DOM node.
* @return True if the node can be moved, false otherwise.
*/
canMoveNode(aNode, aView) {
// Only bookmark items are movable.
if (aNode.itemId == -1)
return false;
// Once tags and bookmarked are divorced, the tag-query check should be
// removed.
let parentNode = aNode.parent;
return parentNode != null &&
PlacesUtils.nodeIsFolder(parentNode) &&
!PlacesUIUtils.isFolderReadOnly(parentNode, aView) &&
!PlacesUtils.nodeIsTagQuery(parentNode);
},
/** /**
* Handles the drop of one or more items onto a view. * Handles the drop of one or more items onto a view.
* *
@ -1486,221 +1457,10 @@ var PlacesControllerDragHelper = {
} }
} }
await handleTransferItems(nodes, insertionPoint, doCopy, view); await PlacesUIUtils.handleTransferItems(nodes, insertionPoint, doCopy, view);
}, },
/**
* Checks if we can insert into a container.
* @param aContainer
* The container were we are want to drop
* @param aView
* The view generating the request
*/
disallowInsertion(aContainer, aView) {
NS_ASSERT(aContainer, "empty container");
// Allow dropping into Tag containers and editable folders.
return !PlacesUtils.nodeIsTagQuery(aContainer) &&
(!PlacesUtils.nodeIsFolder(aContainer) ||
PlacesUIUtils.isFolderReadOnly(aContainer, aView));
}
}; };
XPCOMUtils.defineLazyServiceGetter(PlacesControllerDragHelper, "dragService", XPCOMUtils.defineLazyServiceGetter(PlacesControllerDragHelper, "dragService",
"@mozilla.org/widget/dragservice;1", "@mozilla.org/widget/dragservice;1",
"nsIDragService"); "nsIDragService");
function goUpdatePlacesCommands() {
// Get the controller for one of the places commands.
var placesController = doGetPlacesControllerForCommand("placesCmd_open");
function updatePlacesCommand(aCommand) {
goSetCommandEnabled(aCommand, placesController &&
placesController.isCommandEnabled(aCommand));
}
updatePlacesCommand("placesCmd_open");
updatePlacesCommand("placesCmd_open:window");
updatePlacesCommand("placesCmd_open:privatewindow");
updatePlacesCommand("placesCmd_open:tab");
updatePlacesCommand("placesCmd_new:folder");
updatePlacesCommand("placesCmd_new:bookmark");
updatePlacesCommand("placesCmd_new:separator");
updatePlacesCommand("placesCmd_show:info");
updatePlacesCommand("placesCmd_reload");
updatePlacesCommand("placesCmd_sortBy:name");
updatePlacesCommand("placesCmd_cut");
updatePlacesCommand("placesCmd_copy");
updatePlacesCommand("placesCmd_paste");
updatePlacesCommand("placesCmd_delete");
}
function doGetPlacesControllerForCommand(aCommand) {
// A context menu may be built for non-focusable views. Thus, we first try
// to look for a view associated with document.popupNode
let popupNode;
try {
popupNode = document.popupNode;
} catch (e) {
// The document went away (bug 797307).
return null;
}
if (popupNode) {
let view = PlacesUIUtils.getViewForNode(popupNode);
if (view && view._contextMenuShown)
return view.controllers.getControllerForCommand(aCommand);
}
// When we're not building a context menu, only focusable views
// are possible. Thus, we can safely use the command dispatcher.
let controller = top.document.commandDispatcher
.getControllerForCommand(aCommand);
if (controller)
return controller;
return null;
}
function goDoPlacesCommand(aCommand) {
let controller = doGetPlacesControllerForCommand(aCommand);
if (controller && controller.isCommandEnabled(aCommand))
controller.doCommand(aCommand);
}
/**
* This gets the most appropriate item for using for batching. In the case of multiple
* views being related, the method returns the most expensive result to batch.
* For example, if it detects the left-hand library pane, then it will look for
* and return the reference to the right-hand pane.
*
* @param {Object} viewOrElement The item to check.
* @return {Object} Will return the best result node to batch, or null
* if one could not be found.
*/
function getResultForBatching(viewOrElement) {
if (viewOrElement && viewOrElement instanceof Ci.nsIDOMElement &&
viewOrElement.id === "placesList") {
// Note: fall back to the existing item if we can't find the right-hane pane.
viewOrElement = document.getElementById("placeContent") || viewOrElement;
}
if (viewOrElement && viewOrElement.result) {
return viewOrElement.result;
}
return null;
}
/**
* Processes a set of transfer items that have been dropped or pasted.
* Batching will be applied where necessary.
*
* @param {Array} items A list of unwrapped nodes to process.
* @param {Object} insertionPoint The requested point for insertion.
* @param {Boolean} doCopy Set to true to copy the items, false will move them
* if possible.
* @return {Array} Returns an empty array when the insertion point is a tag, else
* returns an array of copied or moved guids.
*/
async function handleTransferItems(items, insertionPoint, doCopy, view) {
let transactions;
let itemsCount;
if (insertionPoint.isTag) {
let urls = items.filter(item => "uri" in item).map(item => item.uri);
itemsCount = urls.length;
transactions = [PlacesTransactions.Tag({ urls, tag: insertionPoint.tagName })];
} else {
let insertionIndex = await insertionPoint.getIndex();
itemsCount = items.length;
transactions = await getTransactionsForTransferItems(
items, insertionIndex, insertionPoint.guid, doCopy);
}
// Check if we actually have something to add, if we don't it probably wasn't
// valid, or it was moving to the same location, so just ignore it.
if (!transactions.length) {
return [];
}
let guidsToSelect = [];
let resultForBatching = getResultForBatching(view);
// If we're inserting into a tag, we don't get the guid, so we'll just
// pass the transactions direct to the batch function.
let batchingItem = transactions;
if (!insertionPoint.isTag) {
// If we're not a tag, then we need to get the ids of the items to select.
batchingItem = async () => {
for (let transaction of transactions) {
let guid = await transaction.transact();
if (guid) {
guidsToSelect.push(guid);
}
}
};
}
await PlacesUIUtils.batchUpdatesForNode(resultForBatching, itemsCount, async () => {
await PlacesTransactions.batch(batchingItem);
});
return guidsToSelect;
}
/**
* Processes a set of transfer items and returns transactions to insert or
* move them.
*
* @param {Array} items A list of unwrapped nodes to get transactions for.
* @param {Integer} insertionIndex The requested index for insertion.
* @param {String} insertionParentGuid The guid of the parent folder to insert
* or move the items to.
* @param {Boolean} doCopy Set to true to copy the items, false will move them
* if possible.
* @return {Array} Returns an array of created PlacesTransactions.
*/
async function getTransactionsForTransferItems(items, insertionIndex,
insertionParentGuid, doCopy) {
let transactions = [];
let index = insertionIndex;
for (let item of items) {
if (index != -1 && item.itemGuid) {
// Note: we use the parent from the existing bookmark as the sidebar
// gives us an unwrapped.parent that is actually a query and not the real
// parent.
let existingBookmark = await PlacesUtils.bookmarks.fetch(item.itemGuid);
// If we're dropping on the same folder, then we may need to adjust
// the index to insert at the correct place.
if (existingBookmark && insertionParentGuid == existingBookmark.parentGuid) {
if (index > existingBookmark.index) {
// If we're dragging down, we need to go one lower to insert at
// the real point as moving the element changes the index of
// everything below by 1.
index--;
} else if (index == existingBookmark.index) {
// This isn't moving so we skip it.
continue;
}
}
}
// If this is not a copy, check for safety that we can move the
// source, otherwise report an error and fallback to a copy.
if (!doCopy && !PlacesControllerDragHelper.canMoveUnwrappedNode(item)) {
Cu.reportError("Tried to move an unmovable Places " +
"node, reverting to a copy operation.");
doCopy = true;
}
transactions.push(
PlacesUIUtils.getTransactionForData(item,
insertionParentGuid,
index,
doCopy));
if (index != -1 && item.itemGuid) {
index++;
}
}
return transactions;
}

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

@ -39,7 +39,7 @@ var gEditItemOverlay = {
// so we'll need to fetch it later. // so we'll need to fetch it later.
} }
let isURI = node && PlacesUtils.nodeIsURI(node); let isURI = node && PlacesUtils.nodeIsURI(node);
let uri = isURI ? NetUtil.newURI(node.uri) : null; let uri = isURI ? Services.io.newURI(node.uri) : null;
let title = node ? node.title : null; let title = node ? node.title : null;
let isBookmark = isItem && isURI; let isBookmark = isItem && isURI;
let bulkTagging = !node; let bulkTagging = !node;
@ -932,7 +932,7 @@ var gEditItemOverlay = {
// default to the bookmarks menu folder // default to the bookmarks menu folder
if (!ip) { if (!ip) {
ip = new InsertionPoint({ ip = new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId, parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid parentGuid: PlacesUtils.bookmarks.menuGuid
}); });
@ -1072,7 +1072,7 @@ var gEditItemOverlay = {
switch (aProperty) { switch (aProperty) {
case "uri": case "uri":
let newURI = NetUtil.newURI(aValue); let newURI = Services.ui.newURI(aValue);
if (!newURI.equals(this._paneInfo.uri)) { if (!newURI.equals(this._paneInfo.uri)) {
this._paneInfo.uri = newURI; this._paneInfo.uri = newURI;
if (this._paneInfo.visibleRows.has("locationRow")) if (this._paneInfo.visibleRows.has("locationRow"))

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

@ -90,7 +90,7 @@
if (!elt._placesNode) { if (!elt._placesNode) {
// If we are dragging over a non places node drop at the end. // If we are dragging over a non places node drop at the end.
dropPoint.ip = new InsertionPoint({ dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(resultNode), parentId: PlacesUtils.getConcreteItemId(resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(resultNode) parentGuid: PlacesUtils.getConcreteItemGuid(resultNode)
}); });
@ -113,7 +113,7 @@
// This is a folder or a tag container. // This is a folder or a tag container.
if (eventY - eltY < eltHeight * 0.20) { if (eventY - eltY < eltHeight * 0.20) {
// If mouse is in the top part of the element, drop above folder. // If mouse is in the top part of the element, drop above folder.
dropPoint.ip = new InsertionPoint({ dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(resultNode), parentId: PlacesUtils.getConcreteItemId(resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(resultNode), parentGuid: PlacesUtils.getConcreteItemGuid(resultNode),
orientation: Ci.nsITreeView.DROP_BEFORE, orientation: Ci.nsITreeView.DROP_BEFORE,
@ -123,7 +123,7 @@
return dropPoint; return dropPoint;
} else if (eventY - eltY < eltHeight * 0.80) { } else if (eventY - eltY < eltHeight * 0.80) {
// If mouse is in the middle of the element, drop inside folder. // If mouse is in the middle of the element, drop inside folder.
dropPoint.ip = new InsertionPoint({ dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(elt._placesNode), parentId: PlacesUtils.getConcreteItemId(elt._placesNode),
parentGuid: PlacesUtils.getConcreteItemGuid(elt._placesNode), parentGuid: PlacesUtils.getConcreteItemGuid(elt._placesNode),
tagName tagName
@ -134,7 +134,7 @@
} else if (eventY - eltY <= eltHeight / 2) { } else if (eventY - eltY <= eltHeight / 2) {
// This is a non-folder node or a readonly folder. // This is a non-folder node or a readonly folder.
// If the mouse is above the middle, drop above this item. // If the mouse is above the middle, drop above this item.
dropPoint.ip = new InsertionPoint({ dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(resultNode), parentId: PlacesUtils.getConcreteItemId(resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(resultNode), parentGuid: PlacesUtils.getConcreteItemGuid(resultNode),
orientation: Ci.nsITreeView.DROP_BEFORE, orientation: Ci.nsITreeView.DROP_BEFORE,
@ -145,7 +145,7 @@
} }
// Drop below the item. // Drop below the item.
dropPoint.ip = new InsertionPoint({ dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(resultNode), parentId: PlacesUtils.getConcreteItemId(resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(resultNode), parentGuid: PlacesUtils.getConcreteItemGuid(resultNode),
orientation: Ci.nsITreeView.DROP_AFTER, orientation: Ci.nsITreeView.DROP_AFTER,
@ -350,7 +350,7 @@
// Force a copy action if parent node is a query or we are dragging a // Force a copy action if parent node is a query or we are dragging a
// not-removable node. // not-removable node.
if (!PlacesControllerDragHelper.canMoveNode(draggedElt, this._rootView)) if (!this._rootView.controller.canMoveNode(draggedElt))
event.dataTransfer.effectAllowed = "copyLink"; event.dataTransfer.effectAllowed = "copyLink";
// Activate the view and cache the dragged element. // Activate the view and cache the dragged element.

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

@ -25,11 +25,15 @@
"PlacesUIUtils", "resource:///modules/PlacesUIUtils.jsm"); "PlacesUIUtils", "resource:///modules/PlacesUIUtils.jsm");
ChromeUtils.defineModuleGetter(window, ChromeUtils.defineModuleGetter(window,
"PlacesTransactions", "resource://gre/modules/PlacesTransactions.jsm"); "PlacesTransactions", "resource://gre/modules/PlacesTransactions.jsm");
ChromeUtils.defineModuleGetter(window,
"ForgetAboutSite", "resource://gre/modules/ForgetAboutSite.jsm");
XPCOMUtils.defineLazyScriptGetter(window, "PlacesTreeView", XPCOMUtils.defineLazyScriptGetter(window, "PlacesTreeView",
"chrome://browser/content/places/treeView.js"); "chrome://browser/content/places/treeView.js");
XPCOMUtils.defineLazyScriptGetter(window,
["PlacesInsertionPoint", "PlacesController", "PlacesControllerDragHelper"],
"chrome://browser/content/places/controller.js");
]]></script> ]]></script>
<script type="application/javascript"
src="chrome://browser/content/places/controller.js"/>
<!-- Bookmarks and history tooltip --> <!-- Bookmarks and history tooltip -->
<tooltip id="bhTooltip" noautohide="true" <tooltip id="bhTooltip" noautohide="true"
@ -43,45 +47,45 @@
<commandset id="placesCommands" <commandset id="placesCommands"
commandupdater="true" commandupdater="true"
events="focus,sort,places" events="focus,sort,places"
oncommandupdate="goUpdatePlacesCommands();"> oncommandupdate="PlacesUIUtils.updateCommands(window);">
<command id="placesCmd_open" <command id="placesCmd_open"
oncommand="goDoPlacesCommand('placesCmd_open');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_open');"/>
<command id="placesCmd_open:window" <command id="placesCmd_open:window"
oncommand="goDoPlacesCommand('placesCmd_open:window');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_open:window');"/>
<command id="placesCmd_open:privatewindow" <command id="placesCmd_open:privatewindow"
oncommand="goDoPlacesCommand('placesCmd_open:privatewindow');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_open:privatewindow');"/>
<command id="placesCmd_open:tab" <command id="placesCmd_open:tab"
oncommand="goDoPlacesCommand('placesCmd_open:tab');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_open:tab');"/>
<command id="placesCmd_new:bookmark" <command id="placesCmd_new:bookmark"
oncommand="goDoPlacesCommand('placesCmd_new:bookmark');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_new:bookmark');"/>
<command id="placesCmd_new:folder" <command id="placesCmd_new:folder"
oncommand="goDoPlacesCommand('placesCmd_new:folder');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_new:folder');"/>
<command id="placesCmd_new:separator" <command id="placesCmd_new:separator"
oncommand="goDoPlacesCommand('placesCmd_new:separator');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_new:separator');"/>
<command id="placesCmd_show:info" <command id="placesCmd_show:info"
oncommand="goDoPlacesCommand('placesCmd_show:info');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_show:info');"/>
<command id="placesCmd_rename" <command id="placesCmd_rename"
oncommand="goDoPlacesCommand('placesCmd_show:info');" oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_show:info');"
observes="placesCmd_show:info"/> observes="placesCmd_show:info"/>
<command id="placesCmd_reload" <command id="placesCmd_reload"
oncommand="goDoPlacesCommand('placesCmd_reload');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_reload');"/>
<command id="placesCmd_sortBy:name" <command id="placesCmd_sortBy:name"
oncommand="goDoPlacesCommand('placesCmd_sortBy:name');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_sortBy:name');"/>
<command id="placesCmd_deleteDataHost" <command id="placesCmd_deleteDataHost"
oncommand="goDoPlacesCommand('placesCmd_deleteDataHost');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_deleteDataHost');"/>
<command id="placesCmd_createBookmark" <command id="placesCmd_createBookmark"
oncommand="goDoPlacesCommand('placesCmd_createBookmark');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_createBookmark');"/>
<!-- Special versions of cut/copy/paste/delete which check for an open context menu. --> <!-- Special versions of cut/copy/paste/delete which check for an open context menu. -->
<command id="placesCmd_cut" <command id="placesCmd_cut"
oncommand="goDoPlacesCommand('placesCmd_cut');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_cut');"/>
<command id="placesCmd_copy" <command id="placesCmd_copy"
oncommand="goDoPlacesCommand('placesCmd_copy');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_copy');"/>
<command id="placesCmd_paste" <command id="placesCmd_paste"
oncommand="goDoPlacesCommand('placesCmd_paste');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_paste');"/>
<command id="placesCmd_delete" <command id="placesCmd_delete"
oncommand="goDoPlacesCommand('placesCmd_delete');"/> oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_delete');"/>
</commandset> </commandset>
<menupopup id="placesContext" <menupopup id="placesContext"

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

@ -507,7 +507,7 @@
// Avoid the potentially expensive call to getChildIndex // Avoid the potentially expensive call to getChildIndex
// if we know this container doesn't allow insertion // if we know this container doesn't allow insertion
if (PlacesControllerDragHelper.disallowInsertion(container, this)) if (this.controller.disallowInsertion(container))
return null; return null;
var queryOptions = PlacesUtils.asQuery(result.root).queryOptions; var queryOptions = PlacesUtils.asQuery(result.root).queryOptions;
@ -530,7 +530,7 @@
} }
} }
if (PlacesControllerDragHelper.disallowInsertion(container, this)) if (this.controller.disallowInsertion(container))
return null; return null;
// TODO (Bug 1160193): properly support dropping on a tag root. // TODO (Bug 1160193): properly support dropping on a tag root.
@ -541,7 +541,7 @@
return null; return null;
} }
return new InsertionPoint({ return new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(container), parentId: PlacesUtils.getConcreteItemId(container),
parentGuid: PlacesUtils.getConcreteItemGuid(container), parentGuid: PlacesUtils.getConcreteItemGuid(container),
index, orientation, tagName, dropNearNode index, orientation, tagName, dropNearNode
@ -762,7 +762,7 @@
// If this node is child of a readonly container (e.g. a livemark) // If this node is child of a readonly container (e.g. a livemark)
// or cannot be moved, we must force a copy. // or cannot be moved, we must force a copy.
if (!PlacesControllerDragHelper.canMoveNode(node, this)) { if (!this.controller.canMoveNode(node)) {
event.dataTransfer.effectAllowed = "copyLink"; event.dataTransfer.effectAllowed = "copyLink";
break; break;
} }

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

@ -1436,7 +1436,7 @@ PlacesTreeView.prototype = {
// Avoid the potentially expensive call to getChildIndex // Avoid the potentially expensive call to getChildIndex
// if we know this container doesn't allow insertion. // if we know this container doesn't allow insertion.
if (PlacesControllerDragHelper.disallowInsertion(container, this._tree.element)) if (this._controller.disallowInsertion(container))
return null; return null;
let queryOptions = PlacesUtils.asQuery(this._result.root).queryOptions; let queryOptions = PlacesUtils.asQuery(this._result.root).queryOptions;
@ -1459,7 +1459,7 @@ PlacesTreeView.prototype = {
} }
} }
if (PlacesControllerDragHelper.disallowInsertion(container, this._tree.element)) if (this._controller.disallowInsertion(container))
return null; return null;
// TODO (Bug 1160193): properly support dropping on a tag root. // TODO (Bug 1160193): properly support dropping on a tag root.
@ -1470,7 +1470,7 @@ PlacesTreeView.prototype = {
return null; return null;
} }
return new InsertionPoint({ return new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(container), parentId: PlacesUtils.getConcreteItemId(container),
parentGuid: PlacesUtils.getConcreteItemGuid(container), parentGuid: PlacesUtils.getConcreteItemGuid(container),
index, orientation, tagName, dropNearNode index, orientation, tagName, dropNearNode

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

@ -28,7 +28,7 @@ add_task(async function() {
Assert.equal(tree.selectedNode.bookmarkGuid, folder.guid, Assert.equal(tree.selectedNode.bookmarkGuid, folder.guid,
"Selected the expected node"); "Selected the expected node");
Assert.equal(tree.selectedNode.type, 6, "node is a folder"); Assert.equal(tree.selectedNode.type, 6, "node is a folder");
Assert.ok(PlacesControllerDragHelper.canMoveNode(tree.selectedNode, tree), Assert.ok(tree.controller.canMoveNode(tree.selectedNode),
"can move regular folder node"); "can move regular folder node");
info("Test a folder shortcut"); info("Test a folder shortcut");
@ -43,7 +43,7 @@ add_task(async function() {
Assert.equal(tree.selectedNode.type, 9, "node is a folder shortcut"); Assert.equal(tree.selectedNode.type, 9, "node is a folder shortcut");
Assert.equal(PlacesUtils.getConcreteItemGuid(tree.selectedNode), Assert.equal(PlacesUtils.getConcreteItemGuid(tree.selectedNode),
folder.guid, "shortcut node guid and concrete guid match"); folder.guid, "shortcut node guid and concrete guid match");
Assert.ok(PlacesControllerDragHelper.canMoveNode(tree.selectedNode, tree), Assert.ok(tree.controller.canMoveNode(tree.selectedNode),
"can move folder shortcut node"); "can move folder shortcut node");
info("Test a query"); info("Test a query");
@ -63,7 +63,7 @@ add_task(async function() {
tree.selectItems([query.guid]); tree.selectItems([query.guid]);
Assert.equal(tree.selectedNode.bookmarkGuid, query.guid, Assert.equal(tree.selectedNode.bookmarkGuid, query.guid,
"Selected the expected node"); "Selected the expected node");
Assert.ok(PlacesControllerDragHelper.canMoveNode(tree.selectedNode, tree), Assert.ok(tree.controller.canMoveNode(tree.selectedNode),
"can move query node"); "can move query node");
@ -79,7 +79,7 @@ add_task(async function() {
PlacesUtils.asQuery(tree.selectedNode).containerOpen = true; PlacesUtils.asQuery(tree.selectedNode).containerOpen = true;
Assert.equal(tree.selectedNode.childCount, 1, "has tags"); Assert.equal(tree.selectedNode.childCount, 1, "has tags");
let tagNode = tree.selectedNode.getChild(0); let tagNode = tree.selectedNode.getChild(0);
Assert.ok(!PlacesControllerDragHelper.canMoveNode(tagNode, tree), Assert.ok(!tree.controller.canMoveNode(tagNode),
"should not be able to move tag container node"); "should not be able to move tag container node");
tree.selectedNode.containerOpen = false; tree.selectedNode.containerOpen = false;
@ -92,7 +92,7 @@ add_task(async function() {
for (let guid of roots) { for (let guid of roots) {
tree.selectItems([guid]); tree.selectItems([guid]);
Assert.ok(!PlacesControllerDragHelper.canMoveNode(tree.selectedNode, tree), Assert.ok(!tree.controller.canMoveNode(tree.selectedNode),
"shouldn't be able to move default shortcuts to roots"); "shouldn't be able to move default shortcuts to roots");
let id = await PlacesUtils.promiseItemId(guid); let id = await PlacesUtils.promiseItemId(guid);
let s = await PlacesUtils.bookmarks.insert({ let s = await PlacesUtils.bookmarks.insert({
@ -103,7 +103,7 @@ add_task(async function() {
tree.selectItems([s.guid]); tree.selectItems([s.guid]);
Assert.equal(tree.selectedNode.bookmarkGuid, s.guid, Assert.equal(tree.selectedNode.bookmarkGuid, s.guid,
"Selected the expected node"); "Selected the expected node");
Assert.ok(PlacesControllerDragHelper.canMoveNode(tree.selectedNode, tree), Assert.ok(tree.controller.canMoveNode(tree.selectedNode),
"should be able to move user-created shortcuts to roots"); "should be able to move user-created shortcuts to roots");
} }
}); });

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

@ -34,7 +34,7 @@ add_task(async function test() {
let tree = sidebar.contentDocument.getElementById("bookmarks-view"); let tree = sidebar.contentDocument.getElementById("bookmarks-view");
tree.focus(); tree.focus();
let controller = doGetPlacesControllerForCommand("placesCmd_copy"); let controller = PlacesUIUtils.getControllerForCommand(window, "placesCmd_copy");
let treeController = tree.controllers let treeController = tree.controllers
.getControllerForCommand("placesCmd_copy"); .getControllerForCommand("placesCmd_copy");
ok(controller == treeController, "tree controller was returned"); ok(controller == treeController, "tree controller was returned");
@ -45,7 +45,7 @@ add_task(async function test() {
EventUtils.synthesizeMouse(toolbarItems.childNodes[0], EventUtils.synthesizeMouse(toolbarItems.childNodes[0],
4, 4, { type: "contextmenu", button: 2 }, 4, 4, { type: "contextmenu", button: 2 },
window); window);
controller = doGetPlacesControllerForCommand("placesCmd_copy"); controller = PlacesUIUtils.getControllerForCommand(window, "placesCmd_copy");
let toolbarController = document.getElementById("PlacesToolbar") let toolbarController = document.getElementById("PlacesToolbar")
.controllers .controllers
.getControllerForCommand("placesCmd_copy"); .getControllerForCommand("placesCmd_copy");
@ -55,7 +55,7 @@ add_task(async function test() {
// Now that the context menu is closed, try to get the tree controller again. // Now that the context menu is closed, try to get the tree controller again.
tree.focus(); tree.focus();
controller = doGetPlacesControllerForCommand("placesCmd_copy"); controller = PlacesUIUtils.getControllerForCommand(window, "placesCmd_copy");
ok(controller == treeController, "tree controller was returned"); ok(controller == treeController, "tree controller was returned");
if (wasCollapsed) { if (wasCollapsed) {

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

@ -76,7 +76,7 @@ async function run_drag_test(startBookmarkIndex, insertionIndex, newParentGuid,
// Simulating a drag-drop with a tree view turns out to be really difficult // Simulating a drag-drop with a tree view turns out to be really difficult
// as you can't get a node for the source/target. Hence, we fake the // as you can't get a node for the source/target. Hence, we fake the
// insertion point and drag data and call the function direct. // insertion point and drag data and call the function direct.
let ip = new InsertionPoint({ let ip = new PlacesInsertionPoint({
parentId: await PlacesUtils.promiseItemId(PlacesUtils.bookmarks.unfiledGuid), parentId: await PlacesUtils.promiseItemId(PlacesUtils.bookmarks.unfiledGuid),
parentGuid: newParentGuid, parentGuid: newParentGuid,
index: insertionIndex, index: insertionIndex,

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

@ -69,7 +69,7 @@ async function simulateDrop(selectTargets, sourceBm, dropEffect, targetGuid,
Assert.equal(dataTransfer.dropEffect, dropEffect); Assert.equal(dataTransfer.dropEffect, dropEffect);
let ip = new InsertionPoint({ let ip = new PlacesInsertionPoint({
parentId: await PlacesUtils.promiseItemId(targetGuid), parentId: await PlacesUtils.promiseItemId(targetGuid),
parentGuid: targetGuid, parentGuid: targetGuid,
index: 0, index: 0,

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

@ -56,7 +56,7 @@ async function run_drag_test(startBookmarkIndex, newParentGuid) {
// Simulating a drag-drop with a tree view turns out to be really difficult // Simulating a drag-drop with a tree view turns out to be really difficult
// as you can't get a node for the source/target. Hence, we fake the // as you can't get a node for the source/target. Hence, we fake the
// insertion point and drag data and call the function direct. // insertion point and drag data and call the function direct.
let ip = new InsertionPoint({ let ip = new PlacesInsertionPoint({
isTag: true, isTag: true,
tagName: TAG_NAME, tagName: TAG_NAME,
orientation: Ci.nsITreeView.DROP_ON orientation: Ci.nsITreeView.DROP_ON

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

@ -25,38 +25,38 @@ add_task(async function test_date_container() {
let PO = library.PlacesOrganizer; let PO = library.PlacesOrganizer;
PO.selectLeftPaneBuiltIn("History"); PO.selectLeftPaneBuiltIn("History");
isnot(PO._places.selectedNode, null, "We correctly selected History"); Assert.notEqual(PO._places.selectedNode, null, "We correctly selected History");
// Check that both delete and cut commands are disabled, cause this is // Check that both delete and cut commands are disabled, cause this is
// a child of the left pane folder. // a child of the left pane folder.
ok(PO._places.controller.isCommandEnabled("cmd_copy"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_copy"),
"Copy command is enabled"); "Copy command is enabled");
ok(!PO._places.controller.isCommandEnabled("cmd_cut"), Assert.ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled"); "Cut command is disabled");
ok(!PO._places.controller.isCommandEnabled("cmd_delete"), Assert.ok(!PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is disabled"); "Delete command is disabled");
let historyNode = PlacesUtils.asContainer(PO._places.selectedNode); let historyNode = PlacesUtils.asContainer(PO._places.selectedNode);
historyNode.containerOpen = true; historyNode.containerOpen = true;
// Check that we have a child container. It is "Today" container. // Check that we have a child container. It is "Today" container.
is(historyNode.childCount, 1, "History node has one child"); Assert.equal(historyNode.childCount, 1, "History node has one child");
let todayNode = historyNode.getChild(0); let todayNode = historyNode.getChild(0);
let todayNodeExpectedTitle = PlacesUtils.getString("finduri-AgeInDays-is-0"); let todayNodeExpectedTitle = PlacesUtils.getString("finduri-AgeInDays-is-0");
is(todayNode.title, todayNodeExpectedTitle, Assert.equal(todayNode.title, todayNodeExpectedTitle,
"History child is the expected container"); "History child is the expected container");
// Select "Today" container. // Select "Today" container.
PO._places.selectNode(todayNode); PO._places.selectNode(todayNode);
is(PO._places.selectedNode, todayNode, Assert.equal(PO._places.selectedNode, todayNode,
"We correctly selected Today container"); "We correctly selected Today container");
// Check that delete command is enabled but cut command is disabled, cause // Check that delete command is enabled but cut command is disabled, cause
// this is an history item. // this is an history item.
ok(PO._places.controller.isCommandEnabled("cmd_copy"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_copy"),
"Copy command is enabled"); "Copy command is enabled");
ok(!PO._places.controller.isCommandEnabled("cmd_cut"), Assert.ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled"); "Cut command is disabled");
ok(PO._places.controller.isCommandEnabled("cmd_delete"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is enabled"); "Delete command is enabled");
// Execute the delete command and check visit has been removed. // Execute the delete command and check visit has been removed.
let promiseURIRemoved = PlacesTestUtils.waitForNotification( let promiseURIRemoved = PlacesTestUtils.waitForNotification(
@ -65,11 +65,11 @@ add_task(async function test_date_container() {
await promiseURIRemoved; await promiseURIRemoved;
// Test live update of "History" query. // Test live update of "History" query.
is(historyNode.childCount, 0, "History node has no more children"); Assert.equal(historyNode.childCount, 0, "History node has no more children");
historyNode.containerOpen = false; historyNode.containerOpen = false;
ok(!(await PlacesUtils.history.hasVisits(TEST_URI)), "Visit has been removed"); Assert.ok(!(await PlacesUtils.history.hasVisits(TEST_URI)), "Visit has been removed");
library.close(); library.close();
}); });
@ -82,19 +82,19 @@ add_task(async function test_query_on_toolbar() {
let PO = library.PlacesOrganizer; let PO = library.PlacesOrganizer;
PO.selectLeftPaneBuiltIn("BookmarksToolbar"); PO.selectLeftPaneBuiltIn("BookmarksToolbar");
isnot(PO._places.selectedNode, null, "We have a valid selection"); Assert.notEqual(PO._places.selectedNode, null, "We have a valid selection");
is(PlacesUtils.getConcreteItemId(PO._places.selectedNode), Assert.equal(PlacesUtils.getConcreteItemId(PO._places.selectedNode),
PlacesUtils.toolbarFolderId, PlacesUtils.toolbarFolderId,
"We have correctly selected bookmarks toolbar node."); "We have correctly selected bookmarks toolbar node.");
// Check that both cut and delete commands are disabled, cause this is a child // Check that both cut and delete commands are disabled, cause this is a child
// of the All Bookmarks special query. // of the All Bookmarks special query.
ok(PO._places.controller.isCommandEnabled("cmd_copy"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_copy"),
"Copy command is enabled"); "Copy command is enabled");
ok(!PO._places.controller.isCommandEnabled("cmd_cut"), Assert.ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled"); "Cut command is disabled");
ok(!PO._places.controller.isCommandEnabled("cmd_delete"), Assert.ok(!PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is disabled"); "Delete command is disabled");
let toolbarNode = PlacesUtils.asContainer(PO._places.selectedNode); let toolbarNode = PlacesUtils.asContainer(PO._places.selectedNode);
toolbarNode.containerOpen = true; toolbarNode.containerOpen = true;
@ -107,21 +107,21 @@ add_task(async function test_query_on_toolbar() {
index: 0 }); index: 0 });
// Get first child and check it is the just inserted query. // Get first child and check it is the just inserted query.
ok(toolbarNode.childCount > 0, "Toolbar node has children"); Assert.ok(toolbarNode.childCount > 0, "Toolbar node has children");
let queryNode = toolbarNode.getChild(0); let queryNode = toolbarNode.getChild(0);
is(queryNode.title, "special_query", "Query node is correctly selected"); Assert.equal(queryNode.title, "special_query", "Query node is correctly selected");
// Select query node. // Select query node.
PO._places.selectNode(queryNode); PO._places.selectNode(queryNode);
is(PO._places.selectedNode, queryNode, "We correctly selected query node"); Assert.equal(PO._places.selectedNode, queryNode, "We correctly selected query node");
// Check that both cut and delete commands are enabled. // Check that both cut and delete commands are enabled.
ok(PO._places.controller.isCommandEnabled("cmd_copy"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_copy"),
"Copy command is enabled"); "Copy command is enabled");
ok(PO._places.controller.isCommandEnabled("cmd_cut"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is enabled"); "Cut command is enabled");
ok(PO._places.controller.isCommandEnabled("cmd_delete"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is enabled"); "Delete command is enabled");
// Execute the delete command and check bookmark has been removed. // Execute the delete command and check bookmark has been removed.
let promiseItemRemoved = PlacesTestUtils.waitForNotification( let promiseItemRemoved = PlacesTestUtils.waitForNotification(
@ -129,7 +129,7 @@ add_task(async function test_query_on_toolbar() {
PO._places.controller.doCommand("cmd_delete"); PO._places.controller.doCommand("cmd_delete");
await promiseItemRemoved; await promiseItemRemoved;
is((await PlacesUtils.bookmarks.fetch(query.guid)), null, Assert.equal((await PlacesUtils.bookmarks.fetch(query.guid)), null,
"Query node bookmark has been correctly removed"); "Query node bookmark has been correctly removed");
toolbarNode.containerOpen = false; toolbarNode.containerOpen = false;
@ -151,25 +151,25 @@ add_task(async function test_search_contents() {
let PO = library.PlacesOrganizer; let PO = library.PlacesOrganizer;
PO.selectLeftPaneBuiltIn("BookmarksToolbar"); PO.selectLeftPaneBuiltIn("BookmarksToolbar");
isnot(PO._places.selectedNode, null, "We have a valid selection"); Assert.notEqual(PO._places.selectedNode, null, "We have a valid selection");
is(PlacesUtils.getConcreteItemId(PO._places.selectedNode), Assert.equal(PlacesUtils.getConcreteItemId(PO._places.selectedNode),
PlacesUtils.toolbarFolderId, PlacesUtils.toolbarFolderId,
"We have correctly selected bookmarks toolbar node."); "We have correctly selected bookmarks toolbar node.");
let searchBox = library.document.getElementById("searchFilter"); let searchBox = library.document.getElementById("searchFilter");
searchBox.value = "example"; searchBox.value = "example";
library.PlacesSearchBox.search(searchBox.value); library.PlacesSearchBox.search(searchBox.value);
let bookmarkNode = library.ContentTree.view.selectedNode; let bookmarkNode = library.ContentTree.view.selectedNode;
is(bookmarkNode.uri, "http://example.com/", "Found the expected bookmark"); Assert.equal(bookmarkNode.uri, "http://example.com/", "Found the expected bookmark");
// Check that both cut and delete commands are enabled. // Check that both cut and delete commands are enabled.
ok(library.ContentTree.view.controller.isCommandEnabled("cmd_copy"), Assert.ok(library.ContentTree.view.controller.isCommandEnabled("cmd_copy"),
"Copy command is enabled"); "Copy command is enabled");
ok(library.ContentTree.view.controller.isCommandEnabled("cmd_cut"), Assert.ok(library.ContentTree.view.controller.isCommandEnabled("cmd_cut"),
"Cut command is enabled"); "Cut command is enabled");
ok(library.ContentTree.view.controller.isCommandEnabled("cmd_delete"), Assert.ok(library.ContentTree.view.controller.isCommandEnabled("cmd_delete"),
"Delete command is enabled"); "Delete command is enabled");
library.close(); library.close();
}); });
@ -190,44 +190,44 @@ add_task(async function test_tags() {
PO.selectLeftPaneBuiltIn("Tags"); PO.selectLeftPaneBuiltIn("Tags");
let tagsNode = PO._places.selectedNode; let tagsNode = PO._places.selectedNode;
isnot(tagsNode, null, "We have a valid selection"); Assert.notEqual(tagsNode, null, "We have a valid selection");
let tagsTitle = PlacesUtils.getString("TagsFolderTitle"); let tagsTitle = PlacesUtils.getString("TagsFolderTitle");
is(tagsNode.title, tagsTitle, Assert.equal(tagsNode.title, tagsTitle,
"Tags has been properly selected"); "Tags has been properly selected");
// Check that both cut and delete commands are disabled. // Check that both cut and delete commands are disabled.
ok(PO._places.controller.isCommandEnabled("cmd_copy"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_copy"),
"Copy command is enabled"); "Copy command is enabled");
ok(!PO._places.controller.isCommandEnabled("cmd_cut"), Assert.ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled"); "Cut command is disabled");
ok(!PO._places.controller.isCommandEnabled("cmd_delete"), Assert.ok(!PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is disabled"); "Delete command is disabled");
// Now select the tag. // Now select the tag.
PlacesUtils.asContainer(tagsNode).containerOpen = true; PlacesUtils.asContainer(tagsNode).containerOpen = true;
let tag = tagsNode.getChild(0); let tag = tagsNode.getChild(0);
PO._places.selectNode(tag); PO._places.selectNode(tag);
is(PO._places.selectedNode.title, "test", Assert.equal(PO._places.selectedNode.title, "test",
"The created tag has been properly selected"); "The created tag has been properly selected");
// Check that cut is disabled but delete is enabled. // Check that cut is disabled but delete is enabled.
ok(PO._places.controller.isCommandEnabled("cmd_copy"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_copy"),
"Copy command is enabled"); "Copy command is enabled");
ok(!PO._places.controller.isCommandEnabled("cmd_cut"), Assert.ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled"); "Cut command is disabled");
ok(PO._places.controller.isCommandEnabled("cmd_delete"), Assert.ok(PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is enabled"); "Delete command is enabled");
let bookmarkNode = library.ContentTree.view.selectedNode; let bookmarkNode = library.ContentTree.view.selectedNode;
is(bookmarkNode.uri, "http://example.com/", "Found the expected bookmark"); Assert.equal(bookmarkNode.uri, "http://example.com/", "Found the expected bookmark");
// Check that both cut and delete commands are enabled. // Check that both cut and delete commands are enabled.
ok(library.ContentTree.view.controller.isCommandEnabled("cmd_copy"), Assert.ok(library.ContentTree.view.controller.isCommandEnabled("cmd_copy"),
"Copy command is enabled"); "Copy command is enabled");
ok(!library.ContentTree.view.controller.isCommandEnabled("cmd_cut"), Assert.ok(!library.ContentTree.view.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled"); "Cut command is disabled");
ok(library.ContentTree.view.controller.isCommandEnabled("cmd_delete"), Assert.ok(library.ContentTree.view.controller.isCommandEnabled("cmd_delete"),
"Delete command is enabled"); "Delete command is enabled");
tagsNode.containerOpen = false; tagsNode.containerOpen = false;

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

@ -174,7 +174,6 @@ skip-if = true # Bug 1437843
skip-if = true # Bug 1437844 skip-if = true # Bug 1437844
[browser_console_context_menu_entries.js] [browser_console_context_menu_entries.js]
[browser_console_dead_objects.js] [browser_console_dead_objects.js]
skip-if = true # Bug 1437845
[browser_console_error_source_click.js] [browser_console_error_source_click.js]
[browser_console_filters.js] [browser_console_filters.js]
[browser_console_nsiconsolemessage.js] [browser_console_nsiconsolemessage.js]

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

@ -3,93 +3,41 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */ * http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from head.js */
// Check that Dead Objects do not break the Web/Browser Consoles. // Check that Dead Objects do not break the Web/Browser Consoles.
// See bug 883649. //
// This test does: // This test:
// - opens a new tab, // - Opens the Browser Console.
// - opens the Browser Console, // - Creates a sandbox.
// - stores a reference to the content document of the tab on the chrome // - Stores a reference to the sandbox on the chrome window object.
// window object, // - Nukes the sandbox
// - closes the tab, // - Tries to use the sandbox. This is the dead object.
// - tries to use the object that was pointing to the now-defunct content
// document. This is the dead object.
"use strict"; "use strict";
const TEST_URI = "data:text/html;charset=utf8,<p>dead objects!"; add_task(async function () {
let hud = await HUDService.toggleBrowserConsole();
ok(hud, "browser console opened");
function test() { let jsterm = hud.jsterm;
let hud = null;
registerCleanupFunction(() => { // Add the reference to the nuked sandbox.
Services.prefs.clearUserPref("devtools.chrome.enabled"); await jsterm.execute("window.nukedSandbox = Cu.Sandbox(null);" +
}); "Cu.nukeSandbox(nukedSandbox);");
Task.spawn(runner).then(finishTest); await jsterm.execute("nukedSandbox");
await waitFor(() => findMessage(hud, "DeadObject", ".objectTitle"));
function* runner() { jsterm.execute("nukedSandbox.hello");
Services.prefs.setBoolPref("devtools.chrome.enabled", true); let msg = await waitFor(() => findMessage(hud, "can't access dead object"));
yield loadTab(TEST_URI);
let browser = gBrowser.selectedBrowser;
let winID = browser.outerWindowID;
info("open the browser console"); // Check that the link contains an anchor. We can't click on the link because
// clicking links from tests attempts to access an external URL and crashes
// Firefox.
let anchor = msg.querySelector("a");
is(anchor.textContent, "[Learn More]", "Link text is correct");
hud = yield HUDService.toggleBrowserConsole(); await jsterm.execute("delete window.nukedSandbox; 2013-26");
ok(hud, "browser console opened"); await waitFor(() => findMessage(hud, "1987"));
});
let jsterm = hud.jsterm;
jsterm.clearOutput();
// Add the reference to the content document.
yield jsterm.execute("Cu = Components.utils;" +
"Cu.import('resource://gre/modules/Services.jsm');" +
"chromeWindow = Services.wm.getMostRecentWindow('" +
"navigator:browser');" +
"foobarzTezt = chromeWindow.content.document;" +
"delete chromeWindow");
gBrowser.removeCurrentTab();
yield TestUtils.topicObserved("outer-window-nuked", (subject, data) => {
let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
return id == winID;
});
let msg = yield jsterm.execute("foobarzTezt");
isnot(hud.outputNode.textContent.indexOf("DeadObject"), -1,
"dead object found");
jsterm.setInputValue("foobarzTezt");
for (let c of ".hello") {
EventUtils.synthesizeKey(c, {}, hud.iframeWindow);
}
yield jsterm.execute();
isnot(hud.outputNode.textContent.indexOf("can't access dead object"), -1,
"'cannot access dead object' message found");
// Click the second execute output.
let clickable = msg.querySelector("a");
ok(clickable, "clickable object found");
isnot(clickable.textContent.indexOf("DeadObject"), -1,
"message text check");
msg.scrollIntoView();
executeSoon(() => {
EventUtils.synthesizeMouseAtCenter(clickable, {}, hud.iframeWindow);
});
yield jsterm.once("variablesview-fetched");
ok(true, "variables view fetched");
msg = yield jsterm.execute("delete window.foobarzTezt; 2013-26");
isnot(msg.textContent.indexOf("1987"), -1, "result message found");
}
}

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

@ -2544,14 +2544,7 @@ Console::MonotonicTimer(JSContext* aCx, MethodName aMethodName,
} }
if (NS_IsMainThread()) { if (NS_IsMainThread()) {
double duration = (TimeStamp::Now() - mCreationTimeStamp).ToMilliseconds(); *aTimeStamp = (TimeStamp::Now() - mCreationTimeStamp).ToMilliseconds();
// Round down to the nearest 5us, because if the timer is too accurate
// people can do nasty timing attacks with it. See similar code in the
// worker Performance implementation.
const double maxResolutionMs = 0.005;
*aTimeStamp = nsRFPService::ReduceTimePrecisionAsMSecs(
floor(duration / maxResolutionMs) * maxResolutionMs);
return true; return true;
} }

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

@ -447,7 +447,7 @@ MP3TrackDemuxer::FindFirstFrame()
" Length()=%" PRIu64, " Length()=%" PRIu64,
candidateFrame.mStart, candidateFrame.Length()); candidateFrame.mStart, candidateFrame.Length());
while (candidateFrame.Length() && numSuccFrames < MIN_SUCCESSIVE_FRAMES) { while (candidateFrame.Length()) {
mParser.EndFrameSession(); mParser.EndFrameSession();
mOffset = currentFrame.mEnd; mOffset = currentFrame.mEnd;
const MediaByteRange prevFrame = currentFrame; const MediaByteRange prevFrame = currentFrame;
@ -473,16 +473,26 @@ MP3TrackDemuxer::FindFirstFrame()
MP3LOGV("FindFirst() new candidate frame: mOffset=%" PRIu64 MP3LOGV("FindFirst() new candidate frame: mOffset=%" PRIu64
" Length()=%" PRIu64, " Length()=%" PRIu64,
candidateFrame.mStart, candidateFrame.Length()); candidateFrame.mStart, candidateFrame.Length());
} else if (numSuccFrames >= MIN_SUCCESSIVE_FRAMES) {
MP3LOG("FindFirst() accepting candidate frame: "
"successiveFrames=%d", numSuccFrames);
mFrameLock = true;
return candidateFrame;
} else if (prevFrame.mStart == mParser.ID3Header().TotalTagSize() &&
currentFrame.mEnd == StreamLength()) {
// We accept streams with only two frames if both frames are valid. This
// is to handle very short files and provide parity with Chrome. See
// bug 1432195 for more information. This will not handle short files
// with a trailing tag, but as of writing we lack infrastructure to
// handle such tags.
MP3LOG("FindFirst() accepting candidate frame for short stream: "
"successiveFrames=%d", numSuccFrames);
mFrameLock = true;
return candidateFrame;
} }
} }
if (numSuccFrames >= MIN_SUCCESSIVE_FRAMES) { MP3LOG("FindFirst() no suitable first frame found");
MP3LOG("FindFirst() accepting candidate frame: "
"successiveFrames=%d", numSuccFrames);
mFrameLock = true;
} else {
MP3LOG("FindFirst() no suitable first frame found");
}
return candidateFrame; return candidateFrame;
} }

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

@ -29,10 +29,12 @@ IsWhitelistedH264Codec(const nsAString& aCodec)
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx
// "The Media Foundation H.264 video decoder is a Media Foundation Transform // "The Media Foundation H.264 video decoder is a Media Foundation Transform
// that supports decoding of Baseline, Main, and High profiles, up to level // that supports decoding of Baseline, Main, and High profiles, up to level
// 5.1.". We also report that we can play Extended profile, as there are // 5.1.". We extend the limit to level 5.2, relying on the decoder to handle
// any potential errors, the level limit being rather arbitrary.
// We also report that we can play Extended profile, as there are
// bitstreams that are Extended compliant that are also Baseline compliant. // bitstreams that are Extended compliant that are also Baseline compliant.
return level >= H264_LEVEL_1 && return level >= H264_LEVEL_1 &&
level <= H264_LEVEL_5_1 && level <= H264_LEVEL_5_2 &&
(profile == H264_PROFILE_BASE || (profile == H264_PROFILE_BASE ||
profile == H264_PROFILE_MAIN || profile == H264_PROFILE_MAIN ||
profile == H264_PROFILE_EXTENDED || profile == H264_PROFILE_EXTENDED ||

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

@ -14,7 +14,6 @@
#include "WebRenderTypes.h" #include "WebRenderTypes.h"
#include "webrender_ffi.h" #include "webrender_ffi.h"
#include <iostream>
#include <unordered_map> #include <unordered_map>
#ifdef XP_MACOSX #ifdef XP_MACOSX

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

@ -17,7 +17,6 @@
#include "FrameLayerBuilder.h" #include "FrameLayerBuilder.h"
#include "nsPrintfCString.h" #include "nsPrintfCString.h"
#include <iostream>
#include <stdio.h> #include <stdio.h>
using namespace mozilla; using namespace mozilla;
@ -267,7 +266,7 @@ PrintDisplayItemToStdout(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem)
{ {
std::stringstream stream; std::stringstream stream;
PrintDisplayItemTo(aBuilder, aItem, stream, 0, true, false); PrintDisplayItemTo(aBuilder, aItem, stream, 0, true, false);
std::cout << stream.str() << std::endl; puts(stream.str().c_str());
} }
void void
@ -275,7 +274,7 @@ PrintDisplayListToStdout(nsDisplayListBuilder* aBuilder, const nsDisplayList& aL
{ {
std::stringstream stream; std::stringstream stream;
PrintDisplayListTo(aBuilder, aList, stream, 0, false); PrintDisplayListTo(aBuilder, aList, stream, 0, false);
std::cout << stream.str() << std::endl; puts(stream.str().c_str());
} }
#ifdef MOZ_DUMP_PAINTING #ifdef MOZ_DUMP_PAINTING

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

@ -4,7 +4,6 @@
#include "WebrtcGmpVideoCodec.h" #include "WebrtcGmpVideoCodec.h"
#include <iostream>
#include <vector> #include <vector>
#include "mozilla/CheckedInt.h" #include "mozilla/CheckedInt.h"

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

@ -33,7 +33,6 @@
#ifndef WEBRTCGMPVIDEOCODEC_H_ #ifndef WEBRTCGMPVIDEOCODEC_H_
#define WEBRTCGMPVIDEOCODEC_H_ #define WEBRTCGMPVIDEOCODEC_H_
#include <iostream>
#include <queue> #include <queue>
#include <string> #include <string>

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

@ -3,7 +3,6 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <cstdio> #include <cstdio>
#include <iostream>
#include <queue> #include <queue>
#include "CSFLog.h" #include "CSFLog.h"

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

@ -82,6 +82,10 @@ class CentOSFedoraBootstrapper(StyloInstall, BaseBootstrapper):
'python-dbus', 'python-dbus',
] ]
self.mobile_android_packages += [
'ncurses-compat-libs',
]
def install_system_packages(self): def install_system_packages(self):
self.dnf_groupinstall(*self.group_packages) self.dnf_groupinstall(*self.group_packages)
self.dnf_install(*self.packages) self.dnf_install(*self.packages)

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

@ -1162,4 +1162,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1; static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1528315154580000); static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1528401564528000);

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

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

@ -8,7 +8,7 @@
/*****************************************************************************/ /*****************************************************************************/
#include <stdint.h> #include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1530734341592000); const PRTime gPreloadListExpirationTime = INT64_C(1530820751850000);
%% %%
0-1.party, 1 0-1.party, 1
0.me.uk, 1 0.me.uk, 1
@ -437,7 +437,6 @@ const PRTime gPreloadListExpirationTime = INT64_C(1530734341592000);
4d2.xyz, 1 4d2.xyz, 1
4dbygg.se, 1 4dbygg.se, 1
4decor.org, 1 4decor.org, 1
4elements.com, 1
4flex.info, 1 4flex.info, 1
4freepress.com, 1 4freepress.com, 1
4g-server.eu, 0 4g-server.eu, 0
@ -1215,6 +1214,7 @@ agrarshop4u.de, 1
agrekov.ru, 1 agrekov.ru, 1
agreor.com, 1 agreor.com, 1
agricolo.ch, 1 agricolo.ch, 1
agridir.site, 1
agrikulturchic.com, 1 agrikulturchic.com, 1
agrilinks.org, 1 agrilinks.org, 1
agrios.de, 1 agrios.de, 1
@ -1492,6 +1492,7 @@ algolia.com, 1
aliacraft.net, 1 aliacraft.net, 1
aliantsoft.pl, 1 aliantsoft.pl, 1
aliaswp.com, 1 aliaswp.com, 1
alibababee.com, 1
alibangash.com, 1 alibangash.com, 1
alibip.de, 1 alibip.de, 1
alice-noutore.com, 1 alice-noutore.com, 1
@ -2493,7 +2494,6 @@ artratio.net, 1
artroot.jp, 1 artroot.jp, 1
artroscopiaperlosport.it, 1 artroscopiaperlosport.it, 1
artschmidtoptical.com, 1 artschmidtoptical.com, 1
artsinthevalley.net.au, 1
artspac.es, 1 artspac.es, 1
artstopinc.com, 1 artstopinc.com, 1
arturkohut.com, 1 arturkohut.com, 1
@ -2852,6 +2852,7 @@ autos-retro-plaisir.com, 1
autoscuola.roma.it, 1 autoscuola.roma.it, 1
autosearch.me, 1 autosearch.me, 1
autoshinka72.ru, 1 autoshinka72.ru, 1
autoshun.org, 1
autoskola.hr, 1 autoskola.hr, 1
autoskole.hr, 1 autoskole.hr, 1
autostock.me, 1 autostock.me, 1
@ -2907,7 +2908,6 @@ avid.blue, 1
avietech.com, 1 avietech.com, 1
aviv.nyc, 1 aviv.nyc, 1
avmemo.com, 1 avmemo.com, 1
avmo.pw, 1
avmoo.com, 1 avmoo.com, 1
avnet.ws, 1 avnet.ws, 1
avocode.com, 1 avocode.com, 1
@ -2915,7 +2915,6 @@ avonlearningcampus.com, 1
avotoma.com, 1 avotoma.com, 1
avova.de, 1 avova.de, 1
avpres.net, 1 avpres.net, 1
avso.pw, 1
avsox.com, 1 avsox.com, 1
avspot.net, 1 avspot.net, 1
avticket.ru, 0 avticket.ru, 0
@ -2923,7 +2922,6 @@ avtoforex.ru, 1
avtogara-isperih.com, 1 avtogara-isperih.com, 1
avtovokzaly.ru, 1 avtovokzaly.ru, 1
avvcorda.com, 1 avvcorda.com, 1
avxo.pw, 1
awan.tech, 1 awan.tech, 1
awaremi-tai.com, 1 awaremi-tai.com, 1
awaro.net, 1 awaro.net, 1
@ -3038,6 +3036,7 @@ b8591.com, 1
b8591.net, 1 b8591.net, 1
b8979.com, 1 b8979.com, 1
b8979.net, 1 b8979.net, 1
b8a.me, 1
b9018.com, 1 b9018.com, 1
b9018.net, 1 b9018.net, 1
b9108.com, 1 b9108.com, 1
@ -3968,7 +3967,6 @@ bigbouncetheory.co.uk, 1
bigbounceuk.com, 1 bigbounceuk.com, 1
bigcakes.dk, 1 bigcakes.dk, 1
bigclassaction.com, 1 bigclassaction.com, 1
bigcorporateevents.com, 1
bigdinosaur.org, 1 bigdinosaur.org, 1
bigerbio.com, 1 bigerbio.com, 1
biggreenexchange.com, 1 biggreenexchange.com, 1
@ -4405,7 +4403,6 @@ blogreen.org, 1
blogtroterzy.pl, 1 blogtroterzy.pl, 1
bloodsports.org, 1 bloodsports.org, 1
bloodyexcellent.com, 1 bloodyexcellent.com, 1
bloom-avenue.com, 1
bltc.co.uk, 1 bltc.co.uk, 1
bltc.com, 1 bltc.com, 1
bltc.net, 1 bltc.net, 1
@ -4510,11 +4507,13 @@ bocloud.eu, 1
bocreation.fr, 1 bocreation.fr, 1
bodhi.fedoraproject.org, 1 bodhi.fedoraproject.org, 1
bodixite.com, 1 bodixite.com, 1
bodrumfarm.com, 1
bodsch.com, 1 bodsch.com, 1
bodybuilding.events, 1 bodybuilding.events, 1
bodybuildingworld.com, 1 bodybuildingworld.com, 1
bodyconshop.com, 1 bodyconshop.com, 1
bodygearguide.com, 1 bodygearguide.com, 1
bodymusclejournal.com, 1
bodypainter.pl, 1 bodypainter.pl, 1
bodypainting.waw.pl, 1 bodypainting.waw.pl, 1
bodyworkbymichael.com, 1 bodyworkbymichael.com, 1
@ -5096,7 +5095,6 @@ btcontract.com, 1
btcp.space, 1 btcp.space, 1
btcpop.co, 1 btcpop.co, 1
btcycle.org, 1 btcycle.org, 1
btio.pw, 1
btku.org, 1 btku.org, 1
btmstore.com.br, 1 btmstore.com.br, 1
btnissanparts.com, 1 btnissanparts.com, 1
@ -5161,6 +5159,7 @@ building-cost-estimators.com, 1
buildingclouds.de, 1 buildingclouds.de, 1
buildingcostestimators.co.uk, 1 buildingcostestimators.co.uk, 1
builditsolutions.net, 1 builditsolutions.net, 1
buildkite.com, 1
buildplease.com, 1 buildplease.com, 1
buildrightbuildingservicesltd.co.uk, 1 buildrightbuildingservicesltd.co.uk, 1
builtvisible.com, 1 builtvisible.com, 1
@ -5276,7 +5275,6 @@ buyinginvestmentproperty.com, 1
buyingsellingflorida.com, 1 buyingsellingflorida.com, 1
buyjewel.shop, 1 buyjewel.shop, 1
buymindhack.com, 1 buymindhack.com, 1
buynowdepot.com, 0
buypapercheap.net, 1 buypapercheap.net, 1
buyplussize.shop, 1 buyplussize.shop, 1
buyprofessional.shop, 1 buyprofessional.shop, 1
@ -5707,6 +5705,7 @@ carthedral.com, 1
carto.la, 1 carto.la, 1
cartongesso.roma.it, 1 cartongesso.roma.it, 1
cartooncastles.ie, 1 cartooncastles.ie, 1
cartoonhd.cc, 1
cartouche24.eu, 1 cartouche24.eu, 1
cartucce24.it, 1 cartucce24.it, 1
carusorealestate.com, 1 carusorealestate.com, 1
@ -6251,7 +6250,6 @@ childcounseling.org, 1
childcustodylegalaid.org, 1 childcustodylegalaid.org, 1
childno.de, 1 childno.de, 1
childrenandmedia.org.au, 1 childrenandmedia.org.au, 1
childrendeservebetter.org, 1
childrenfirstalways.org, 1 childrenfirstalways.org, 1
childreninadversity.gov, 1 childreninadversity.gov, 1
childrensentertainmentleicester.co.uk, 1 childrensentertainmentleicester.co.uk, 1
@ -6551,6 +6549,7 @@ clairescastles.co.uk, 1
clanebouncycastles.com, 1 clanebouncycastles.com, 1
clanrose.org.uk, 1 clanrose.org.uk, 1
clanthor.com, 1 clanthor.com, 1
clanwarz.com, 1
clapping-rhymes.com, 1 clapping-rhymes.com, 1
claretandbanter.uk, 1 claretandbanter.uk, 1
claritysrv.com, 1 claritysrv.com, 1
@ -7005,7 +7004,6 @@ cometonovascotia.ca, 1
comff.net, 1 comff.net, 1
comfintouch.com, 1 comfintouch.com, 1
comflores.com.br, 1 comflores.com.br, 1
comfortdom.ua, 1
comfypc.com, 1 comfypc.com, 1
comhack.com, 1 comhack.com, 1
comicrelief.com, 1 comicrelief.com, 1
@ -7471,7 +7469,6 @@ creative-wave.fr, 1
creativebites.de, 1 creativebites.de, 1
creativecaptiv.es, 1 creativecaptiv.es, 1
creativecommons.cl, 1 creativecommons.cl, 1
creativecommons.gr, 1
creativecommons.org, 1 creativecommons.org, 1
creativecommonscatpictures.com, 1 creativecommonscatpictures.com, 1
creativeconceptsvernon.com, 1 creativeconceptsvernon.com, 1
@ -7702,7 +7699,6 @@ cubia.de, 1
cubia3.com, 1 cubia3.com, 1
cubia4.com, 1 cubia4.com, 1
cubile.xyz, 1 cubile.xyz, 1
cubix.host, 1
cublick.com, 1 cublick.com, 1
cubos.io, 0 cubos.io, 0
cubostecnologia.com, 0 cubostecnologia.com, 0
@ -8325,10 +8321,16 @@ deaf.eu.org, 1
deai-life.biz, 1 deai-life.biz, 1
deaktualisierung.org, 0 deaktualisierung.org, 0
dealapp.nl, 1 dealapp.nl, 1
dealbanana.at, 1
dealbanana.be, 1
dealbanana.ch, 1 dealbanana.ch, 1
dealbanana.co.uk, 1
dealbanana.com, 1 dealbanana.com, 1
dealbanana.de, 1 dealbanana.de, 1
dealbanana.fi, 1
dealbanana.fr, 1
dealbanana.it, 1 dealbanana.it, 1
dealbanana.se, 1
dealcruiser.nl, 1 dealcruiser.nl, 1
dealinflatables.co.uk, 1 dealinflatables.co.uk, 1
dealpass.no, 1 dealpass.no, 1
@ -8625,7 +8627,6 @@ dethemium.com, 1
dethikiemtra.com, 1 dethikiemtra.com, 1
detoxetmoi.com, 1 detoxetmoi.com, 1
detoxsinutritie.ro, 1 detoxsinutritie.ro, 1
detroit-english.de, 1
detroitstylepizza.com, 1 detroitstylepizza.com, 1
detroitzoo.org, 1 detroitzoo.org, 1
detskysad.com, 1 detskysad.com, 1
@ -8706,6 +8707,7 @@ devzero.io, 1
dewaard.de, 1 dewaard.de, 1
dewalch.net, 1 dewalch.net, 1
dewapress.com, 1 dewapress.com, 1
dewebwerf.nl, 1
dewinter.com, 1 dewinter.com, 1
dexalo.de, 1 dexalo.de, 1
dezeregio.nl, 1 dezeregio.nl, 1
@ -9207,6 +9209,7 @@ domain001.info, 1
domainedemiolan.ch, 1 domainedemiolan.ch, 1
domainexpress.de, 0 domainexpress.de, 0
domainkauf.de, 1 domainkauf.de, 1
domainoo.com, 1
domains.autos, 1 domains.autos, 1
domains.boats, 1 domains.boats, 1
domains.google.com, 1 domains.google.com, 1
@ -9376,7 +9379,6 @@ dpg.no, 1
dpisecuretests.com, 1 dpisecuretests.com, 1
dprb.biz, 1 dprb.biz, 1
dprd-wonogirikab.go.id, 0 dprd-wonogirikab.go.id, 0
dps.srl, 1
dpsart.it, 1 dpsart.it, 1
dpsg-roden.de, 0 dpsg-roden.de, 0
dpwsweeps.co.uk, 1 dpwsweeps.co.uk, 1
@ -9660,6 +9662,7 @@ dustygroove.com, 1
dustyspokesbnb.ca, 1 dustyspokesbnb.ca, 1
dutch.desi, 1 dutch.desi, 1
dutch1.nl, 1 dutch1.nl, 1
dutchessuganda.com, 1
dutchrank.nl, 1 dutchrank.nl, 1
dutchwanderers.nl, 1 dutchwanderers.nl, 1
dutchweballiance.nl, 1 dutchweballiance.nl, 1
@ -10000,7 +10003,6 @@ edzilla.info, 1
ee-terminals.com, 1 ee-terminals.com, 1
eeb98.com, 1 eeb98.com, 1
eeetrust.org, 1 eeetrust.org, 1
eellak.gr, 1
eelsden.net, 1 eelsden.net, 1
eelzak.nl, 1 eelzak.nl, 1
eeqj.com, 1 eeqj.com, 1
@ -10434,6 +10436,7 @@ enersaveapp.org, 1
enersec.co.uk, 1 enersec.co.uk, 1
enet-navigator.de, 1 enet-navigator.de, 1
enfantsdelarue.ch, 1 enfantsdelarue.ch, 1
enfield-kitchens.co.uk, 1
enflow.nl, 1 enflow.nl, 1
enfoqueseguro.com, 1 enfoqueseguro.com, 1
enfu.se, 1 enfu.se, 1
@ -11051,7 +11054,6 @@ evangelosm.com, 1
evankurniawan.com, 1 evankurniawan.com, 1
evantageglobal.com, 1 evantageglobal.com, 1
evapp.org, 1 evapp.org, 1
evasion-energie.com, 1
evasioncreole.com, 1 evasioncreole.com, 1
evasovova.cz, 1 evasovova.cz, 1
eve0s.com, 1 eve0s.com, 1
@ -11336,6 +11338,7 @@ factuursturen.be, 1
factuursturen.nl, 1 factuursturen.nl, 1
factys.do, 1 factys.do, 1
factys.es, 1 factys.es, 1
fadednet.com, 0
faderweb.de, 1 faderweb.de, 1
fads-center.online, 1 fads-center.online, 1
faehler.de, 1 faehler.de, 1
@ -11815,7 +11818,6 @@ firefart.at, 1
firefighters.dating, 1 firefighters.dating, 1
firefly-iii.org, 1 firefly-iii.org, 1
firegoby.jp, 1 firegoby.jp, 1
firehost.com, 1
firemudfm.com, 1 firemudfm.com, 1
fireportal.cz, 1 fireportal.cz, 1
fireshellsecurity.team, 1 fireshellsecurity.team, 1
@ -11958,7 +11960,6 @@ flikmsg.co, 1
flinch.io, 1 flinch.io, 1
fling.dating, 1 fling.dating, 1
flipagram.com, 0 flipagram.com, 0
flipbell.com, 1
flipneus.net, 1 flipneus.net, 1
fliptable.org, 1 fliptable.org, 1
flirt-norden.de, 1 flirt-norden.de, 1
@ -12822,6 +12823,7 @@ gancedo.com.es, 1
gandalfservice.com, 1 gandalfservice.com, 1
gandalfthefeline.com, 1 gandalfthefeline.com, 1
gandgliquors.com, 1 gandgliquors.com, 1
gangnam-club.com, 1
gangnam-karaoke.com, 1 gangnam-karaoke.com, 1
ganhonet.com.br, 1 ganhonet.com.br, 1
ganztagplus.de, 1 ganztagplus.de, 1
@ -14250,7 +14252,6 @@ hash.works, 1
hashcat.net, 1 hashcat.net, 1
hashes.org, 1 hashes.org, 1
hashi.dk, 1 hashi.dk, 1
hashiconf.com, 1
hashiconf.eu, 1 hashiconf.eu, 1
hashicorp.com, 1 hashicorp.com, 1
hashimah.ca, 1 hashimah.ca, 1
@ -14425,8 +14426,8 @@ heello.es, 1
hefengautoparts.com, 1 hefengautoparts.com, 1
heftkaufen.de, 1 heftkaufen.de, 1
hegen.com.pl, 0 hegen.com.pl, 0
hegen.cz, 1 hegen.cz, 0
hegen.sk, 1 hegen.sk, 0
hegenshop.de, 1 hegenshop.de, 1
heh.ee, 1 heh.ee, 1
heha.co, 0 heha.co, 0
@ -14986,7 +14987,6 @@ hostserv.org, 1
hosyaku.gr.jp, 1 hosyaku.gr.jp, 1
hot-spa.ch, 1 hot-spa.ch, 1
hotcandlestick.com, 1 hotcandlestick.com, 1
hotchillibox.co.za, 0
hotchillibox.com, 0 hotchillibox.com, 0
hotel-kronjuwel.de, 1 hotel-kronjuwel.de, 1
hotel-le-vaisseau.ch, 1 hotel-le-vaisseau.ch, 1
@ -15383,6 +15383,7 @@ iclinic.ua, 1
icmhd.ch, 1 icmhd.ch, 1
icmp2018.org, 1 icmp2018.org, 1
icnsoft.me, 1 icnsoft.me, 1
icnsoft.org, 1
icodeconnect.com, 1 icodeconnect.com, 1
icondoom.nl, 1 icondoom.nl, 1
iconomi.net, 1 iconomi.net, 1
@ -15419,6 +15420,7 @@ idaspis.com, 1
idatha.de, 1 idatha.de, 1
idblab.tk, 1 idblab.tk, 1
idc-business.be, 1 idc-business.be, 1
idconsult.nl, 1
idcrane.com, 1 idcrane.com, 1
iddconnect.com, 1 iddconnect.com, 1
iddconnect.org, 1 iddconnect.org, 1
@ -16140,6 +16142,7 @@ iomstamps.com, 1
ionc.ca, 1 ionc.ca, 1
ionlabs.kr, 1 ionlabs.kr, 1
ionx.co.uk, 1 ionx.co.uk, 1
ioover.net, 1
ioslo.net, 1 ioslo.net, 1
iosnoops.com, 1 iosnoops.com, 1
iossifovlab.com, 1 iossifovlab.com, 1
@ -16765,6 +16768,7 @@ jeanmarieayer.ch, 1
jeannecalment.com, 1 jeannecalment.com, 1
jeannelucienne.fr, 1 jeannelucienne.fr, 1
jeanneret-combustibles.ch, 1 jeanneret-combustibles.ch, 1
jebengotai.com, 1
jec-dekrone.be, 1 jec-dekrone.be, 1
jecho.cn, 1 jecho.cn, 1
jedayoshi.tk, 1 jedayoshi.tk, 1
@ -17418,7 +17422,6 @@ kaffeekrone.de, 1
kafoom.de, 1 kafoom.de, 1
kaheim.de, 0 kaheim.de, 0
kai-ratzeburg.de, 1 kai-ratzeburg.de, 1
kai.cool, 1
kaibol.com, 1 kaibol.com, 1
kaigojj.com, 1 kaigojj.com, 1
kaika-facilitymanagement.de, 1 kaika-facilitymanagement.de, 1
@ -17635,7 +17638,6 @@ kazu.click, 1
kazuhirohigashi.com, 1 kazuhirohigashi.com, 1
kazumi.ro, 1 kazumi.ro, 1
kazy111.info, 1 kazy111.info, 1
kb3.net, 1
kba-online.de, 1 kba-online.de, 1
kbb-ev.de, 1 kbb-ev.de, 1
kbbouncycastlehire.co.uk, 1 kbbouncycastlehire.co.uk, 1
@ -17845,7 +17847,6 @@ kiekin.org, 1
kiekko.pro, 1 kiekko.pro, 1
kiel-kind.de, 1 kiel-kind.de, 1
kielderweather.org.uk, 1 kielderweather.org.uk, 1
kienlen.org, 1
kieranweightman.me, 1 kieranweightman.me, 1
kiesuwkerstkaart.nl, 1 kiesuwkerstkaart.nl, 1
kievradio.com, 1 kievradio.com, 1
@ -18123,7 +18124,6 @@ koertner-muth.de, 1
koethen-markt.de, 1 koethen-markt.de, 1
koetjesenkanker.nl, 1 koetjesenkanker.nl, 1
koez-mangal.ch, 1 koez-mangal.ch, 1
koezmangal.ch, 1
kofler.info, 1 kofler.info, 1
kogak.ninja, 1 kogak.ninja, 1
kogcoder.com, 1 kogcoder.com, 1
@ -18917,7 +18917,6 @@ leet2.com, 1
leetcode.com, 1 leetcode.com, 1
leetcode.net, 1 leetcode.net, 1
leetgamers.asia, 1 leetgamers.asia, 1
leetsaber.com, 1
leevealdc.com, 1 leevealdc.com, 1
lefebvristes.com, 1 lefebvristes.com, 1
lefebvristes.fr, 1 lefebvristes.fr, 1
@ -19456,6 +19455,7 @@ livepaperhelp.com, 1
livepath.ch, 1 livepath.ch, 1
liveperformersmeeting.net, 1 liveperformersmeeting.net, 1
liveregistratie.nl, 1 liveregistratie.nl, 1
livesearch-fukuoka.com, 1
livesure.com, 1 livesure.com, 1
livi.co, 1 livi.co, 1
living-space.co.nz, 1 living-space.co.nz, 1
@ -20200,7 +20200,6 @@ mallner.me, 1
mallonline.com.br, 1 mallonline.com.br, 1
malmoesport.se, 1 malmoesport.se, 1
malnex.de, 1 malnex.de, 1
malone.link, 1
malta-firma.com, 1 malta-firma.com, 1
malte-kiefer.de, 1 malte-kiefer.de, 1
malvy.kiev.ua, 1 malvy.kiev.ua, 1
@ -20224,7 +20223,6 @@ mammaw.com, 1
mammeitalianeavienna.com, 1 mammeitalianeavienna.com, 1
mammooc.org, 1 mammooc.org, 1
mamochka.org.ua, 1 mamochka.org.ua, 1
mamospienas.lt, 1
mamot.fr, 0 mamot.fr, 0
mamout.xyz, 1 mamout.xyz, 1
mamuko.nl, 1 mamuko.nl, 1
@ -20496,7 +20494,6 @@ maskinkultur.com, 1
maslife365.com, 1 maslife365.com, 1
maslin.io, 1 maslin.io, 1
masrur.org, 1 masrur.org, 1
massage-vitalite.fr, 1
massage4u.net, 1 massage4u.net, 1
massagecupping.com, 1 massagecupping.com, 1
massagetainha-hanoi.com, 1 massagetainha-hanoi.com, 1
@ -20516,7 +20513,6 @@ master-net.org, 1
mastercardpac.com, 1 mastercardpac.com, 1
masterdemolitioninc.com, 1 masterdemolitioninc.com, 1
masterdigitale.com, 1 masterdigitale.com, 1
masterhaus.bg, 1
masterhelenaroma.com, 1 masterhelenaroma.com, 1
masterofallscience.com, 1 masterofallscience.com, 1
masterpc.co.uk, 1 masterpc.co.uk, 1
@ -21406,7 +21402,6 @@ misakiya.co.jp, 1
misclick.nl, 1 misclick.nl, 1
misconfigured.io, 1 misconfigured.io, 1
miscreant.me, 1 miscreant.me, 1
misericordiasegrate.org, 1
mishkovskyi.net, 1 mishkovskyi.net, 1
miskatonic.org, 1 miskatonic.org, 1
misoji-resist.com, 1 misoji-resist.com, 1
@ -22238,7 +22233,6 @@ mydna.bio, 1
mydocserve.com, 1 mydocserve.com, 1
mydreamlifelab.com, 1 mydreamlifelab.com, 1
myeberspaecher.com, 1 myeberspaecher.com, 1
myeffect.today, 1
myepass.bg, 1 myepass.bg, 1
myepass.de, 1 myepass.de, 1
myessaygeek.com, 1 myessaygeek.com, 1
@ -22338,6 +22332,7 @@ myprintcard.de, 1
myproblog.com, 1 myproblog.com, 1
myptsite.com, 1 myptsite.com, 1
mypup.nl, 1 mypup.nl, 1
myqdu.cn, 1
myrandomtips.com, 1 myrandomtips.com, 1
myranicol.com, 1 myranicol.com, 1
myrealestatemate.com.au, 1 myrealestatemate.com.au, 1
@ -22813,7 +22808,6 @@ nepageeks.com, 1
nepal-evolution.org, 1 nepal-evolution.org, 1
nephelion.org, 1 nephelion.org, 1
nephos.xyz, 1 nephos.xyz, 1
nephy.jp, 1
nepovolenainternetovahazardnihra.cz, 1 nepovolenainternetovahazardnihra.cz, 1
nepremicninar.com, 1 nepremicninar.com, 1
nepremicnine.click, 1 nepremicnine.click, 1
@ -23185,6 +23179,7 @@ nippon-oku.com, 1
nippon.fr, 1 nippon.fr, 1
nirada.info, 1 nirada.info, 1
nirjonmela.com, 1 nirjonmela.com, 1
nirjonmela.net, 1
nirudo.me, 1 nirudo.me, 1
nirvanashop.com, 1 nirvanashop.com, 1
nishaswonderland.be, 1 nishaswonderland.be, 1
@ -23613,7 +23608,6 @@ oc-minecraft.com, 1
oc-sa.ch, 1 oc-sa.ch, 1
ocad.com.au, 1 ocad.com.au, 1
ocapic.com, 1 ocapic.com, 1
occasion-impro.com, 1
occentus.net, 1 occentus.net, 1
occmon.net, 1 occmon.net, 1
occupymedia.org, 1 occupymedia.org, 1
@ -23982,7 +23976,6 @@ open-infrastructure.net, 1
open-letters.de, 1 open-letters.de, 1
open-mesh.org, 1 open-mesh.org, 1
open-sauce-recipes.co.uk, 1 open-sauce-recipes.co.uk, 1
open-source.gr, 1
open.gl, 1 open.gl, 1
openacademies.com, 1 openacademies.com, 1
openacte.ch, 1 openacte.ch, 1
@ -24030,7 +24023,6 @@ opentuition.com, 1
openverse.com, 1 openverse.com, 1
openvz.org, 1 openvz.org, 1
openwaveguide.de, 1 openwaveguide.de, 1
openwifi.gr, 1
openwireless.org, 1 openwireless.org, 1
operad.fr, 1 operad.fr, 1
operationforever.com, 1 operationforever.com, 1
@ -24370,6 +24362,7 @@ pagure.io, 1
pagure.org, 1 pagure.org, 1
pahae.de, 1 pahae.de, 1
pahealthbilling.com, 1 pahealthbilling.com, 1
pahlawanpulsa.com, 1
paichai.space, 1 paichai.space, 1
paincareehr.com, 1 paincareehr.com, 1
paindata.dk, 1 paindata.dk, 1
@ -24732,6 +24725,7 @@ pbcknd.ml, 1
pbosquet.com, 1 pbosquet.com, 1
pbourhis.me, 1 pbourhis.me, 1
pbqs.site, 1 pbqs.site, 1
pbr.so, 1
pbraunschdash.com, 1 pbraunschdash.com, 1
pbreen.co.uk, 1 pbreen.co.uk, 1
pbrumby.com, 1 pbrumby.com, 1
@ -25387,7 +25381,7 @@ playsharp.com, 1
playsnake.org, 1 playsnake.org, 1
playsoundevents.be, 1 playsoundevents.be, 1
playsource.co, 1 playsource.co, 1
playsprout.industries, 0 playsprout.industries, 1
playtictactoe.org, 1 playtictactoe.org, 1
playtimebouncycastles.co.uk, 1 playtimebouncycastles.co.uk, 1
playwhyyza.com, 1 playwhyyza.com, 1
@ -25418,6 +25412,7 @@ plochka.bg, 1
plomberierenga.com, 1 plomberierenga.com, 1
plongee-phuket.fr, 1 plongee-phuket.fr, 1
ploofer.com, 1 ploofer.com, 1
plot.ly, 1
plotbubble.com, 1 plotbubble.com, 1
ploxel.com, 1 ploxel.com, 1
plr4wp.com, 1 plr4wp.com, 1
@ -25882,6 +25877,7 @@ primorus.lt, 1
primotilesandbathrooms.co.uk, 1 primotilesandbathrooms.co.uk, 1
princeagency.com, 1 princeagency.com, 1
princeofwhales.com, 1 princeofwhales.com, 1
princesparktouch.com, 1
princessbackpack.de, 1 princessbackpack.de, 1
princessmargaretlotto.com, 1 princessmargaretlotto.com, 1
principalstest.com, 1 principalstest.com, 1
@ -26225,6 +26221,7 @@ publick.net, 1
publicsuffix.org, 1 publicsuffix.org, 1
publimepa.it, 0 publimepa.it, 0
publiq.space, 1 publiq.space, 1
publishingshack.com, 1
pubreview.com.au, 1 pubreview.com.au, 1
pubreviews.com, 1 pubreviews.com, 1
pucchi.net, 1 pucchi.net, 1
@ -26320,6 +26317,7 @@ pypi.io, 1
pypi.org, 1 pypi.org, 1
pypi.python.org, 1 pypi.python.org, 1
pyrotechnologie.de, 1 pyrotechnologie.de, 1
pysays.net, 1
pyspace.org, 1 pyspace.org, 1
pythia.nz, 1 pythia.nz, 1
python-hyper.org, 1 python-hyper.org, 1
@ -27036,7 +27034,6 @@ rene-schwarz.com, 1
rene-stolp.de, 1 rene-stolp.de, 1
renearends.nl, 1 renearends.nl, 1
reneleu.ch, 1 reneleu.ch, 1
renem.net, 0
renemayrhofer.com, 1 renemayrhofer.com, 1
renerehelse.no, 0 renerehelse.no, 0
reneschmidt.de, 1 reneschmidt.de, 1
@ -27078,7 +27075,6 @@ reprogrammingpredators.com, 1
reprozip.org, 1 reprozip.org, 1
repsomelt.com, 1 repsomelt.com, 1
reptrax.com, 1 reptrax.com, 1
republic.gr, 1
republique.org, 1 republique.org, 1
repugnant-conclusion.com, 1 repugnant-conclusion.com, 1
repugnantconclusion.com, 1 repugnantconclusion.com, 1
@ -27256,7 +27252,7 @@ rickrongen.nl, 1
rickscastles.co.uk, 1 rickscastles.co.uk, 1
rickvanderzwet.nl, 1 rickvanderzwet.nl, 1
rickweijers.nl, 1 rickweijers.nl, 1
ricky.capital, 1 ricky.capital, 0
rickyromero.com, 1 rickyromero.com, 1
rico-brase.de, 0 rico-brase.de, 0
rico.ovh, 1 rico.ovh, 1
@ -27351,7 +27347,6 @@ rlds.ch, 1
rleh.de, 1 rleh.de, 1
rlnunez.com, 1 rlnunez.com, 1
rlove.org, 1 rlove.org, 1
rlsnet.ru, 0
rm-it.de, 1 rm-it.de, 1
rmb.li, 1 rmb.li, 1
rmcbs.de, 1 rmcbs.de, 1
@ -27731,7 +27726,6 @@ rueg.eu, 1
ruerte.net, 1 ruerte.net, 1
rufabula-com.appspot.com, 1 rufabula-com.appspot.com, 1
ruffbeatz.com, 1 ruffbeatz.com, 1
ruflay.ru, 1
rugby.video, 1 rugby.video, 1
rugk.dedyn.io, 1 rugk.dedyn.io, 1
ruh-veit.de, 1 ruh-veit.de, 1
@ -28167,7 +28161,6 @@ save-me-koeln.de, 1
savecashindia.com, 1 savecashindia.com, 1
savecrypto.org, 1 savecrypto.org, 1
savekorea.net, 1 savekorea.net, 1
savemoneyonenergy.com, 1
savenet.org, 1 savenet.org, 1
saveora.com, 1 saveora.com, 1
saveora.shop, 1 saveora.shop, 1
@ -28424,7 +28417,6 @@ script.google.com, 1
scriptgates.ru, 1 scriptgates.ru, 1
scripthost.org, 1 scripthost.org, 1
scriptjunkie.us, 1 scriptjunkie.us, 1
scriptum.gr, 1
scrisulfacebine.ro, 1 scrisulfacebine.ro, 1
scruffymen.com, 0 scruffymen.com, 0
scrumbleship.com, 1 scrumbleship.com, 1
@ -28753,6 +28745,7 @@ seoquake.com, 1
seoscribe.net, 1 seoscribe.net, 1
seosof.com, 1 seosof.com, 1
seostepbysteplab.com, 1 seostepbysteplab.com, 1
seotronix.net, 1
seoul.dating, 1 seoul.dating, 1
seouniversity.org, 1 seouniversity.org, 1
sepalandseed.com, 1 sepalandseed.com, 1
@ -29111,7 +29104,6 @@ showdepiscinas.com.br, 1
shower.im, 1 shower.im, 1
showmax.com, 1 showmax.com, 1
showmethemoney.ru, 1 showmethemoney.ru, 1
showroom.de, 1
showsonar.com, 1 showsonar.com, 1
shoxmusic.net, 1 shoxmusic.net, 1
shred.ch, 1 shred.ch, 1
@ -29133,7 +29125,6 @@ shushu.media, 1
shutter-shower.com, 1 shutter-shower.com, 1
shux.pro, 1 shux.pro, 1
shuzicai.cn, 1 shuzicai.cn, 1
shwrm.ch, 1
shymeck.pw, 1 shymeck.pw, 1
si-benelux.nl, 1 si-benelux.nl, 1
si.to, 1 si.to, 1
@ -29405,7 +29396,7 @@ sinkip.com, 1
sinktank.de, 1 sinktank.de, 1
sinn.io, 1 sinn.io, 1
sinnersprojects.ro, 1 sinnersprojects.ro, 1
sinnovate.de, 1 sinnovate.de, 0
sinomod.com, 1 sinomod.com, 1
sinonimos.com.br, 1 sinonimos.com.br, 1
sinonimosonline.com, 1 sinonimosonline.com, 1
@ -30165,6 +30156,7 @@ spiellawine.de, 1
spiet.nl, 1 spiet.nl, 1
spiff.eu, 1 spiff.eu, 1
spiga.ch, 1 spiga.ch, 1
spikeykc.me, 1
spillersfamily.net, 1 spillersfamily.net, 1
spilogkoder.dk, 1 spilogkoder.dk, 1
spinalien.net, 1 spinalien.net, 1
@ -30345,7 +30337,6 @@ sslping.com, 1
sslpoint.com, 1 sslpoint.com, 1
ssls.cz, 1 ssls.cz, 1
sslsurvey.de, 1 sslsurvey.de, 1
sslzilla.de, 1
ssmato.me, 1 ssmato.me, 1
ssnet.vip, 1 ssnet.vip, 1
ssready.org, 1 ssready.org, 1
@ -31062,7 +31053,6 @@ sweetair.com, 1
sweetgood.de, 1 sweetgood.de, 1
sweetlegs.jp, 1 sweetlegs.jp, 1
sweetll.me, 0 sweetll.me, 0
sweets-mimatsu.com, 1
sweetvanilla.jp, 1 sweetvanilla.jp, 1
swehack.org, 1 swehack.org, 1
sweharris.org, 1 sweharris.org, 1
@ -31180,6 +31170,8 @@ system.is, 1
system12.pl, 1 system12.pl, 1
system365.eu, 1 system365.eu, 1
systemadmin.uk, 1 systemadmin.uk, 1
systematic-momo.com, 1
systematic-momo.dk, 1
systemd.ch, 1 systemd.ch, 1
systemd.eu.org, 1 systemd.eu.org, 1
systemeprod.fr, 1 systemeprod.fr, 1
@ -32210,7 +32202,6 @@ thw-bernburg.de, 1
thxandbye.de, 1 thxandbye.de, 1
thyngster.com, 1 thyngster.com, 1
thynx.io, 1 thynx.io, 1
thzone.net, 1
ti-js.com, 1 ti-js.com, 1
ti-pla.net, 1 ti-pla.net, 1
ti-planet.org, 1 ti-planet.org, 1
@ -32329,7 +32320,6 @@ tintencenter.com, 1
tintenfix.net, 1 tintenfix.net, 1
tintenfux.de, 1 tintenfux.de, 1
tintenland.de, 1 tintenland.de, 1
tintenprofi.de, 1
tiny.ee, 1 tiny.ee, 1
tinyhousefinance.com.au, 1 tinyhousefinance.com.au, 1
tinylan.com, 1 tinylan.com, 1
@ -33258,7 +33248,6 @@ tworaz.net, 1
twotube.ie, 1 twotube.ie, 1
twun.io, 1 twun.io, 1
twuni.org, 1 twuni.org, 1
txbi.de, 1
txcap.org, 1 txcap.org, 1
txdivorce.org, 1 txdivorce.org, 1
txi.su, 1 txi.su, 1
@ -34580,7 +34569,6 @@ wannaridecostarica.com, 1
wantshow.com.br, 1 wantshow.com.br, 1
wanybug.cn, 1 wanybug.cn, 1
waonui.io, 1 waonui.io, 1
wapking.live, 1
warcraftjournal.org, 1 warcraftjournal.org, 1
wardow.com, 1 wardow.com, 1
warebouncycastles.co.uk, 1 warebouncycastles.co.uk, 1
@ -34634,6 +34622,7 @@ watertrails.io, 1
waterworkscondos.com, 1 waterworkscondos.com, 1
watoo.tech, 1 watoo.tech, 1
watsonwork.me, 1 watsonwork.me, 1
wattechweb.com, 1
wave-ola.es, 1 wave-ola.es, 1
wave.is, 1 wave.is, 1
wavesboardshop.com, 1 wavesboardshop.com, 1
@ -35124,7 +35113,6 @@ whyy.eu.org, 1
wiapply.com, 1 wiapply.com, 1
wibbe.link, 1 wibbe.link, 1
wiberg.nu, 1 wiberg.nu, 1
wibruje.pl, 1
wibuw.com, 1 wibuw.com, 1
wickrath.net, 1 wickrath.net, 1
widdleguy.com, 1 widdleguy.com, 1
@ -35132,6 +35120,7 @@ wideboxmacau.com, 0
widegab.com, 1 widegab.com, 1
wideinfo.org, 1 wideinfo.org, 1
widemann.de, 1 widemann.de, 1
widememory.com, 1
widmer.bz, 1 widmer.bz, 1
widsl.de, 1 widsl.de, 1
wiebetaaltdat.nl, 1 wiebetaaltdat.nl, 1
@ -35373,7 +35362,7 @@ wolfpa.ws, 1
wolfram.io, 1 wolfram.io, 1
wolfsden.cz, 1 wolfsden.cz, 1
wolfwings.us, 1 wolfwings.us, 1
wolfy1339.com, 1 wolfy1339.com, 0
wolkenspeicher.org, 1 wolkenspeicher.org, 1
wollekorb.de, 1 wollekorb.de, 1
wollongongbaptist.hopto.org, 1 wollongongbaptist.hopto.org, 1
@ -36698,6 +36687,7 @@ zorium.org, 1
zorki.nl, 1 zorki.nl, 1
zorntt.fr, 1 zorntt.fr, 1
zorz.info, 1 zorz.info, 1
zotero.org, 1
zouk.info, 1 zouk.info, 1
zouyaoji.top, 1 zouyaoji.top, 1
zravypapir.cz, 1 zravypapir.cz, 1

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

@ -8,7 +8,6 @@
#define security_sandbox_loggingCallbacks_h__ #define security_sandbox_loggingCallbacks_h__
#include <sstream> #include <sstream>
#include <iostream>
#include "mozilla/Logging.h" #include "mozilla/Logging.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"

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

@ -727,7 +727,9 @@ BufferedBookmarksEngine.prototype = {
let buf = await this._store.ensureOpenMirror(); let buf = await this._store.ensureOpenMirror();
let recordsToUpload = await buf.apply({ let recordsToUpload = await buf.apply({
remoteTimeSeconds: Resource.serverTime, remoteTimeSeconds: Resource.serverTime,
weakUpload: [...this._needWeakUpload.keys()],
}); });
this._needWeakUpload.clear();
this._modified.replace(recordsToUpload); this._modified.replace(recordsToUpload);
}, },
@ -736,9 +738,6 @@ BufferedBookmarksEngine.prototype = {
}, },
async _createRecord(id) { async _createRecord(id) {
if (this._needWeakUpload.has(id)) {
return this._store.createRecord(id, this.name);
}
let change = this._modified.changes[id]; let change = this._modified.changes[id];
if (!change) { if (!change) {
this._log.error("Creating record for item ${id} not in strong " + this._log.error("Creating record for item ${id} not in strong " +

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

@ -90,14 +90,14 @@ dependencies = [
[[package]] [[package]]
name = "azure" name = "azure"
version = "0.27.0" version = "0.28.0"
source = "git+https://github.com/servo/rust-azure#46a9c9c6279ba46354b48f6fc849ee20624cbf90" source = "git+https://github.com/servo/rust-azure#29f0c063ad366b5364e06af26d3e9d1ee588e3b2"
dependencies = [ dependencies = [
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-skia 0.30000012.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo-skia 0.30000013.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -270,7 +270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "canvas" name = "canvas"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"azure 0.27.0 (git+https://github.com/servo/rust-azure)", "azure 0.28.0 (git+https://github.com/servo/rust-azure)",
"canvas_traits 0.0.1", "canvas_traits 0.0.1",
"compositing 0.0.1", "compositing 0.0.1",
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -757,6 +757,15 @@ dependencies = [
"dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "dwmapi-sys"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "dwrote" name = "dwrote"
version = "0.4.2" version = "0.4.2"
@ -2634,7 +2643,7 @@ dependencies = [
"osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"script_traits 0.0.1", "script_traits 0.0.1",
"servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-glutin 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)", "servo-glutin 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_config 0.0.1", "servo_config 0.0.1",
"servo_geometry 0.0.1", "servo_geometry 0.0.1",
"servo_url 0.0.1", "servo_url 0.0.1",
@ -2684,7 +2693,7 @@ dependencies = [
[[package]] [[package]]
name = "servo-glutin" name = "servo-glutin"
version = "0.14.2" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"android_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "android_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2692,20 +2701,25 @@ dependencies = [
"cocoa 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "cocoa 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dwmapi-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"x11-dl 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "x11-dl 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "servo-skia" name = "servo-skia"
version = "0.30000012.0" version = "0.30000013.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cgl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cgl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2719,7 +2733,7 @@ dependencies = [
"servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-fontconfig-sys 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "servo-fontconfig-sys 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-glutin 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)", "servo-glutin 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "x11 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -2840,6 +2854,15 @@ dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "shell32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "sig" name = "sig"
version = "0.1.1" version = "0.1.1"
@ -3585,7 +3608,7 @@ dependencies = [
"checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21" "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" "checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860"
"checksum audio-video-metadata 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "71536082079f5ba92c274fba7c2dcd4e2f9d5c13ce6d7f8fe9acbbb258916d18" "checksum audio-video-metadata 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "71536082079f5ba92c274fba7c2dcd4e2f9d5c13ce6d7f8fe9acbbb258916d18"
"checksum azure 0.27.0 (git+https://github.com/servo/rust-azure)" = "<none>" "checksum azure 0.28.0 (git+https://github.com/servo/rust-azure)" = "<none>"
"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76" "checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
"checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff" "checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff"
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
@ -3639,6 +3662,7 @@ dependencies = [
"checksum device 0.0.1 (git+https://github.com/servo/devices)" = "<none>" "checksum device 0.0.1 (git+https://github.com/servo/devices)" = "<none>"
"checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90"
"checksum dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe6f727b406462fd57c95fed84d1b0dbfb5f0136fcac005adba9ea0367c05cc8" "checksum dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe6f727b406462fd57c95fed84d1b0dbfb5f0136fcac005adba9ea0367c05cc8"
"checksum dwmapi-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b44b6442aeab12e609aee505bd1066bdfd36b79c3fe5aad604aae91537623e76"
"checksum dwrote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b26e30aaa6bf31ec830db15fec14ed04f0f2ecfcc486ecfce88c55d3389b237f" "checksum dwrote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b26e30aaa6bf31ec830db15fec14ed04f0f2ecfcc486ecfce88c55d3389b237f"
"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a" "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
"checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9" "checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
@ -3790,11 +3814,12 @@ dependencies = [
"checksum servo-fontconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93f799b649b4a2bf362398910eca35240704c7e765e780349b2bb1070d892262" "checksum servo-fontconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93f799b649b4a2bf362398910eca35240704c7e765e780349b2bb1070d892262"
"checksum servo-fontconfig-sys 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "38b494f03009ee81914b0e7d387ad7c145cafcd69747c2ec89b0e17bb94f303a" "checksum servo-fontconfig-sys 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "38b494f03009ee81914b0e7d387ad7c145cafcd69747c2ec89b0e17bb94f303a"
"checksum servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9232032c2e85118c0282c6562c84cab12316e655491ba0a5d1905b2320060d1b" "checksum servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9232032c2e85118c0282c6562c84cab12316e655491ba0a5d1905b2320060d1b"
"checksum servo-glutin 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf265a35f2d23d3ed2fae943fda4b6dda861c86b25c1c99f9ca77a37cfa6ee7c" "checksum servo-glutin 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a36b9398e9cade5b1e3011d841d9d98d4e86a538a1b639db62100d86134c10f6"
"checksum servo-skia 0.30000012.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80980e6eb854c06e8e45fa3cfbd439bf4223a6840f38c3caec34efa39cf9405e" "checksum servo-skia 0.30000013.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1be5e09cb97ea135d1223fa226f8880f124aed2fa887bf5acf10ef16ad94e072"
"checksum servo-websocket 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efde78dfcf2178d5a11e1e2268e0d8df0627dfe2724546db8585d6678e1af150" "checksum servo-websocket 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efde78dfcf2178d5a11e1e2268e0d8df0627dfe2724546db8585d6678e1af150"
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
"checksum shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04126b6fcfd2710fb5b6d18f4207b6c535f2850a7e1a43bcd526d44f30a79a" "checksum shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04126b6fcfd2710fb5b6d18f4207b6c535f2850a7e1a43bcd526d44f30a79a"
"checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c"
"checksum sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6649e43c1a1e68d29ed56d0dc3b5b6cf3b901da77cf107c4066b9e3da036df5" "checksum sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6649e43c1a1e68d29ed56d0dc3b5b6cf3b901da77cf107c4066b9e3da036df5"
"checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "<none>" "checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "<none>"
"checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0" "checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"

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

@ -76,16 +76,6 @@ fn generate_properties() {
.arg(&script) .arg(&script)
.arg(product) .arg(product)
.arg("style-crate") .arg("style-crate")
.envs(if std::mem::size_of::<Option<bool>>() == 1 {
// FIXME: remove this envs() call
// and make unconditional code that depends on RUSTC_HAS_PR45225
// once Firefox requires Rust 1.23+
// https://github.com/rust-lang/rust/pull/45225
vec![("RUSTC_HAS_PR45225", "1")]
} else {
vec![]
})
.status() .status()
.unwrap(); .unwrap();
if !status.success() { if !status.success() {

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

@ -32,8 +32,7 @@ def main():
properties = data.PropertiesData(product=product) properties = data.PropertiesData(product=product)
template = os.path.join(BASE, "properties.mako.rs") template = os.path.join(BASE, "properties.mako.rs")
rust = render(template, product=product, data=properties, __file__=template, rust = render(template, product=product, data=properties, __file__=template)
RUSTC_HAS_PR45225=os.environ.get("RUSTC_HAS_PR45225"))
if output == "style-crate": if output == "style-crate":
write(os.environ["OUT_DIR"], "properties.rs", rust) write(os.environ["OUT_DIR"], "properties.rs", rust)
if product == "gecko": if product == "gecko":

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

@ -66,9 +66,9 @@ ${helpers.predefined_type(
"stroke-width", "SVGWidth", "stroke-width", "SVGWidth",
"::values::computed::NonNegativeLength::new(1.).into()", "::values::computed::NonNegativeLength::new(1.).into()",
products="gecko", products="gecko",
boxed=not RUSTC_HAS_PR45225,
animation_value_type="::values::computed::SVGWidth", animation_value_type="::values::computed::SVGWidth",
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeWidth")} spec="https://www.w3.org/TR/SVG2/painting.html#StrokeWidth",
)}
${helpers.single_keyword("stroke-linecap", "butt round square", ${helpers.single_keyword("stroke-linecap", "butt round square",
products="gecko", animation_value_type="discrete", products="gecko", animation_value_type="discrete",
@ -101,9 +101,9 @@ ${helpers.predefined_type(
"stroke-dashoffset", "SVGLength", "stroke-dashoffset", "SVGLength",
"Au(0).into()", "Au(0).into()",
products="gecko", products="gecko",
boxed=not RUSTC_HAS_PR45225,
animation_value_type="ComputedValue", animation_value_type="ComputedValue",
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing")} spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing",
)}
// Section 14 - Clipping, Masking and Compositing // Section 14 - Clipping, Masking and Compositing
${helpers.single_keyword("clip-rule", "nonzero evenodd", ${helpers.single_keyword("clip-rule", "nonzero evenodd",

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

@ -47,7 +47,6 @@ ${helpers.predefined_type(
"generics::pointing::CaretColor::Auto", "generics::pointing::CaretColor::Auto",
spec="https://drafts.csswg.org/css-ui/#caret-color", spec="https://drafts.csswg.org/css-ui/#caret-color",
animation_value_type="AnimatedCaretColor", animation_value_type="AnimatedCaretColor",
boxed=not RUSTC_HAS_PR45225,
ignored_when_colors_disabled=True, ignored_when_colors_disabled=True,
products="gecko", products="gecko",
)} )}

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

@ -1 +1 @@
1.23.0 1.24.0

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

@ -35,7 +35,7 @@ log = "0.3.5"
msg = {path = "../../components/msg"} msg = {path = "../../components/msg"}
net_traits = {path = "../../components/net_traits"} net_traits = {path = "../../components/net_traits"}
script_traits = {path = "../../components/script_traits"} script_traits = {path = "../../components/script_traits"}
servo-glutin = "0.14" servo-glutin = "0.15"
servo_geometry = {path = "../../components/geometry"} servo_geometry = {path = "../../components/geometry"}
servo_config = {path = "../../components/config"} servo_config = {path = "../../components/config"}
servo_url = {path = "../../components/url"} servo_url = {path = "../../components/url"}

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

@ -535,6 +535,7 @@ Connection::Connection(Service *aService,
, mAsyncExecutionThreadShuttingDown(false) , mAsyncExecutionThreadShuttingDown(false)
, mConnectionClosed(false) , mConnectionClosed(false)
, mTransactionInProgress(false) , mTransactionInProgress(false)
, mDestroying(false)
, mProgressHandler(nullptr) , mProgressHandler(nullptr)
, mFlags(aFlags) , mFlags(aFlags)
, mIgnoreLockingMode(aIgnoreLockingMode) , mIgnoreLockingMode(aIgnoreLockingMode)
@ -572,56 +573,51 @@ NS_IMETHODIMP_(MozExternalRefCountType) Connection::Release(void)
nsrefcnt count = --mRefCnt; nsrefcnt count = --mRefCnt;
NS_LOG_RELEASE(this, count, "Connection"); NS_LOG_RELEASE(this, count, "Connection");
if (1 == count) { if (1 == count) {
// If the refcount is 1, the single reference must be from // If the refcount went to 1, the single reference must be from
// gService->mConnections (in class |Service|). Which means we can // gService->mConnections (in class |Service|). And the code calling
// perform our failsafe Close() and unregister... // Release is either:
// - The "user" code that had created the connection, releasing on any
// thread.
// - One of Service's getConnections() callers had acquired a strong
// reference to the Connection that out-lived the last "user" reference,
// and now that just got dropped. Note that this reference could be
// getting dropped on the main thread or Connection->threadOpenedOn
// (because of the NewRunnableMethod used by minimizeMemory).
// //
// HOWEVER, there is an edge-case where our failsafe Close() may trigger // Either way, we should now perform our failsafe Close() and unregister.
// a call to AsyncClose() which obtains a strong reference. This reference // However, we only want to do this once, and the reality is that our
// will be released via NS_ReleaseOnMainThreadSystemGroup() before Close() // refcount could go back up above 1 and down again at any time if we are
// returns, which can potentially result in reentrancy into this method and // off the main thread and getConnections() gets called on the main thread,
// this branch a second time. (It may also be deferred if we're not in // so we use an atomic here to do this exactly once.
// that event target ourselves.) To avoid reentrancy madness, we explicitly if (mDestroying.compareExchange(false, true)) {
// bump our refcount up to 2 without going through AddRef(). // Close the connection, dispatching to the opening thread if we're not
++mRefCnt; // on that thread already and that thread is still accepting runnables.
// Okay, now our refcount is 2, we trigger Close(). // We do this because it's possible we're on the main thread because of
Unused << Close(); // getConnections(), and we REALLY don't want to transfer I/O to the main
// Now our refcount should either be at 2 (because nothing happened, or the // thread if we can avoid it.
// addref and release pair happened due to SpinningSynchronousClose) or if (threadOpenedOn->IsOnCurrentThread()) {
// 3 (because SpinningSynchronousClose happened but didn't release yet). // This could cause SpinningSynchronousClose() to be invoked and AddRef
// // triggered for AsyncCloseConnection's strong ref if the conn was ever
// We *really* want to avoid re-entrancy, and we have potentially two strong // use for async purposes. (Main-thread only, though.)
// references remaining that will invoke Release() and potentially trigger Unused << Close();
// a transition to 1 again. Since the second reference would be just a } else {
// proxy release of an already-closed connection, it's not a big deal for us nsCOMPtr<nsIRunnable> event =
// to unregister the connection now. We do need to take care to avoid a NewRunnableMethod("storage::Connection::Close",
// strong refcount transition to 1 from 2 because that would induce this, &Connection::Close);
// reentrancy. Note that we do not have any concerns about other threads if (NS_FAILED(threadOpenedOn->Dispatch(event.forget(),
// being involved here; we MUST be the main thread if AsyncClose() is NS_DISPATCH_NORMAL))) {
// involved. // The target thread was dead and so we've just leaked our runnable.
// // This should not happen because our non-main-thread consumers should
// Note: While Close() potentially spins the nested event loop, it is // be explicitly closing their connections, not relying on us to close
// conceivable that Service::CollectReports or Service::minimizeMemory might // them for them. (It's okay to let a statement go out of scope for
// be invoked. These call Service::getConnections() and will perform // automatic cleanup, but not a Connection.)
// matching AddRef and Release calls but will definitely not retain any MOZ_ASSERT(false, "Leaked Connection::Close(), ownership fail.");
// references. (Because connectionReady() will return false so both loops Unused << Close();
// will immediately "continue" to bypass the connection in question.) }
// Because our refcount is at least 2 at the lowest point, these do not pose }
// a problem.
if (mRefCnt == 3) { // This will drop its strong reference right here, right now.
// pending proxy release, strong release to 2
mStorageService->unregisterConnection(this); mStorageService->unregisterConnection(this);
// now weak release to 1, the outstanding refcount will strong release to
// 0 and result in destruction later.
--mRefCnt;
} else if (mRefCnt == 2) {
// weak release to 1
--mRefCnt;
// strong release to 0, destruction will happen, we must NOT touch
// `this` after this point.
mStorageService->unregisterConnection(this);
} else {
MOZ_ASSERT(false, "Connection refcount invariant violated.");
} }
} else if (0 == count) { } else if (0 == count) {
mRefCnt = 1; /* stabilize */ mRefCnt = 1; /* stabilize */

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

@ -9,6 +9,7 @@
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h" #include "mozilla/Mutex.h"
#include "nsProxyRelease.h" #include "nsProxyRelease.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
@ -380,6 +381,16 @@ private:
*/ */
bool mTransactionInProgress; bool mTransactionInProgress;
/**
* Used to trigger cleanup logic only the first time our refcount hits 1. We
* may trigger a failsafe Close() that invokes SpinningSynchronousClose()
* which invokes AsyncClose() which may bump our refcount back up to 2 (and
* which will then fall back down to 1 again). It's also possible that the
* Service may bump our refcount back above 1 if getConnections() runs before
* we invoke unregisterConnection().
*/
mozilla::Atomic<bool> mDestroying;
/** /**
* Stores the mapping of a given function by name to its instance. Access is * Stores the mapping of a given function by name to its instance. Access is
* protected by sharedDBMutex. * protected by sharedDBMutex.

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

@ -297,17 +297,12 @@ Service::unregisterConnection(Connection *aConnection)
MOZ_ASSERT(forgettingRef, MOZ_ASSERT(forgettingRef,
"Attempt to unregister unknown storage connection!"); "Attempt to unregister unknown storage connection!");
// Ensure the connection is released on its opening thread. We explicitly use // Do not proxy the release anywhere, just let this reference drop here. (We
// aAlwaysDispatch=false because at the time of writing this, LocalStorage's // previously did proxy the release, but that was because we invoked Close()
// StorageDBThread uses a hand-rolled PRThread implementation that cannot // in the destructor and Close() likes to complain if it's not invoked on the
// handle us dispatching events at it during shutdown. However, it is // opener thread, so it was essential that the last reference be dropped on
// arguably also desirable for callers to not be aware of our connection // the opener thread. We now enqueue Close() inside our caller, Release(), so
// tracking mechanism. And by synchronously dropping the reference (when // it doesn't actually matter what thread our reference drops on.)
// on the correct thread), this avoids surprises for the caller and weird
// shutdown edge cases.
nsCOMPtr<nsIThread> thread = forgettingRef->threadOpenedOn;
NS_ProxyRelease(
"storage::Service::mConnections", thread, forgettingRef.forget(), false);
} }
void void

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

@ -20,10 +20,11 @@ XPCOMUtils.defineLazyGetter(this, "log", () => {
}); });
const PREF_ENABLED = "marionette.enabled"; const PREF_ENABLED = "marionette.enabled";
const PREF_PORT = "marionette.port";
const PREF_PORT_FALLBACK = "marionette.defaultPrefs.port";
const PREF_LOG_LEVEL = "marionette.log.level";
const PREF_LOG_LEVEL_FALLBACK = "marionette.logging"; const PREF_LOG_LEVEL_FALLBACK = "marionette.logging";
const PREF_LOG_LEVEL = "marionette.log.level";
const PREF_PORT_FALLBACK = "marionette.defaultPrefs.port";
const PREF_PORT = "marionette.port";
const PREF_RECOMMENDED = "marionette.prefs.recommended";
const DEFAULT_LOG_LEVEL = "info"; const DEFAULT_LOG_LEVEL = "info";
const NOTIFY_RUNNING = "remote-active"; const NOTIFY_RUNNING = "remote-active";
@ -46,6 +47,241 @@ const ENV_ENABLED = "MOZ_MARIONETTE";
// pref being set to 4444. // pref being set to 4444.
const ENV_PRESERVE_PREFS = "MOZ_MARIONETTE_PREF_STATE_ACROSS_RESTARTS"; const ENV_PRESERVE_PREFS = "MOZ_MARIONETTE_PREF_STATE_ACROSS_RESTARTS";
// Marionette sets preferences recommended for automation when it starts,
// unless marionette.prefs.recommended has been set to false.
// Where noted, some prefs should also be set in the profile passed to
// Marionette to prevent them from affecting startup, since some of these
// are checked before Marionette initialises.
const RECOMMENDED_PREFS = new Map([
// Disable automatic downloading of new releases.
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["app.update.auto", false],
// Disable automatically upgrading Firefox.
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["app.update.enabled", false],
// 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 all), resulting in the production timeout value
// sometimes being exceeded and causing false-positive test failures.
//
// (bug 1176798, bug 1177018, bug 1210465)
["apz.content_response_timeout", 60000],
// Indicate that the download panel has been shown once so that
// whichever download test runs first doesn't show the popup
// inconsistently.
["browser.download.panel.shown", true],
// Do not show the EULA notification.
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.EULA.override", true],
// Turn off about:newtab and make use of about:blank instead for new
// opened tabs.
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.newtabpage.enabled", false],
// Assume the about:newtab page's intro panels have been shown to not
// depend on which test runs first and happens to open about:newtab
["browser.newtabpage.introShown", true],
// Never start the browser in offline mode
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.offline", false],
// Background thumbnails in particular cause grief, and disabling
// thumbnails in general cannot hurt
["browser.pagethumbnails.capturing_disabled", true],
// Disable safebrowsing components.
//
// These should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.safebrowsing.blockedURIs.enabled", false],
["browser.safebrowsing.downloads.enabled", false],
["browser.safebrowsing.passwords.enabled", false],
["browser.safebrowsing.malware.enabled", false],
["browser.safebrowsing.phishing.enabled", false],
// Disable updates to search engines.
//
// Should be set in profile.
["browser.search.update", false],
// Do not restore the last open set of tabs if the browser has crashed
["browser.sessionstore.resume_from_crash", false],
// Don't check for the default web browser during startup.
//
// These should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.shell.checkDefaultBrowser", false],
// Start with a blank page (about:blank)
["browser.startup.page", 0],
// Do not redirect user when a milstone upgrade of Firefox is detected
["browser.startup.homepage_override.mstone", "ignore"],
// Disable browser animations
["toolkit.cosmeticAnimations.enabled", false],
// Do not allow background tabs to be zombified, otherwise for tests
// that open additional tabs, the test harness tab itself might get
// unloaded
["browser.tabs.disableBackgroundZombification", false],
// Do not warn when closing all other open tabs
["browser.tabs.warnOnCloseOtherTabs", false],
// Do not warn when multiple tabs will be opened
["browser.tabs.warnOnOpen", false],
// Disable first run splash page on Windows 10
["browser.usedOnWindows10.introURL", ""],
// Disable the UI tour.
//
// Should be set in profile.
["browser.uitour.enabled", false],
// Turn off search suggestions in the location bar so as not to trigger
// network connections.
["browser.urlbar.suggest.searches", false],
// Turn off the location bar search suggestions opt-in. It interferes with
// tests that don't expect it to be there.
["browser.urlbar.userMadeSearchSuggestionsChoice", true],
// Do not show datareporting policy notifications which can
// interfere with tests
[
"datareporting.healthreport.documentServerURI",
"http://%(server)s/dummy/healthreport/",
],
["datareporting.healthreport.logging.consoleEnabled", false],
["datareporting.healthreport.service.enabled", false],
["datareporting.healthreport.service.firstRun", false],
["datareporting.healthreport.uploadEnabled", false],
["datareporting.policy.dataSubmissionEnabled", false],
["datareporting.policy.dataSubmissionPolicyAccepted", false],
["datareporting.policy.dataSubmissionPolicyBypassNotification", true],
// Disable popup-blocker
["dom.disable_open_during_load", false],
// Enabling the support for File object creation in the content process
["dom.file.createInChild", true],
// Disable the ProcessHangMonitor
["dom.ipc.reportProcessHangs", false],
// Disable slow script dialogues
["dom.max_chrome_script_run_time", 0],
["dom.max_script_run_time", 0],
// Only load extensions from the application and user profile
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
//
// Should be set in profile.
["extensions.autoDisableScopes", 0],
["extensions.enabledScopes", 5],
// Disable metadata caching for installed add-ons by default
["extensions.getAddons.cache.enabled", false],
// Disable installing any distribution extensions or add-ons.
// 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
["extensions.update.enabled", false],
["extensions.update.notifyUser", false],
// Make sure opening about:addons will not hit the network
[
"extensions.webservice.discoverURL",
"http://%(server)s/dummy/discoveryURL",
],
// Allow the application to have focus even it runs in the background
["focusmanager.testmode", true],
// Disable useragent updates
["general.useragent.updates.enabled", false],
// Always use network provider for geolocation tests so we bypass the
// macOS dialog raised by the corelocation provider
["geo.provider.testing", true],
// Do not scan Wifi
["geo.wifi.scan", false],
// No hang monitor
["hangmonitor.timeout", 0],
// Show chrome errors and warnings in the error console
["javascript.options.showInConsole", true],
// Do not prompt for temporary redirects
["network.http.prompt-temp-redirect", false],
// Disable speculative connections so they are not reported as leaking
// when they are hanging around
["network.http.speculative-parallel-limit", 0],
// Do not automatically switch between offline and online
["network.manage-offline-status", false],
// Make sure SNTP requests do not hit the network
["network.sntp.pools", "%(server)s"],
// Local documents have access to all other local documents,
// including directory listings
["security.fileuri.strict_origin_policy", false],
// Tests do not wait for the notification button security delay
["security.notification_enable_delay", 0],
// Ensure blocklist updates do not hit the network
["services.settings.server", "http://%(server)s/dummy/blocklist/"],
// Do not automatically fill sign-in forms with known usernames and
// passwords
["signon.autofillForms", false],
// Disable password capture, so that tests that include forms are not
// influenced by the presence of the persistent doorhanger notification
["signon.rememberSignons", false],
// Disable first-run welcome page
["startup.homepage_welcome_url", "about:blank"],
["startup.homepage_welcome_url.additional", ""],
// Prevent starting into safe mode after application crashes
["toolkit.startup.max_resumed_crashes", -1],
]);
const isRemote = Services.appinfo.processType == const isRemote = Services.appinfo.processType ==
Services.appinfo.PROCESS_TYPE_CONTENT; Services.appinfo.PROCESS_TYPE_CONTENT;
@ -155,6 +391,7 @@ class MarionetteMainProcess {
log.level = prefs.logLevel; log.level = prefs.logLevel;
this.enabled = env.exists(ENV_ENABLED); this.enabled = env.exists(ENV_ENABLED);
this.alteredPrefs = new Set();
Services.prefs.addObserver(PREF_ENABLED, this); Services.prefs.addObserver(PREF_ENABLED, this);
Services.ppmm.addMessageListener("Marionette:IsRunning", this); Services.ppmm.addMessageListener("Marionette:IsRunning", this);
@ -225,7 +462,7 @@ class MarionetteMainProcess {
if (this.gfxWindow === null || subject === this.gfxWindow) { if (this.gfxWindow === null || subject === this.gfxWindow) {
Services.obs.removeObserver(this, topic); Services.obs.removeObserver(this, topic);
Services.obs.addObserver(this, "xpcom-shutdown"); Services.obs.addObserver(this, "xpcom-will-shutdown");
this.finalUIStartup = true; this.finalUIStartup = true;
this.init(); this.init();
} }
@ -254,15 +491,15 @@ class MarionetteMainProcess {
if (this.gfxWindow) { if (this.gfxWindow) {
Services.obs.addObserver(this, "domwindowclosed"); Services.obs.addObserver(this, "domwindowclosed");
} else { } else {
Services.obs.addObserver(this, "xpcom-shutdown"); Services.obs.addObserver(this, "xpcom-will-shutdown");
this.finalUIStartup = true; this.finalUIStartup = true;
this.init(); this.init();
} }
break; break;
case "xpcom-shutdown": case "xpcom-will-shutdown":
Services.obs.removeObserver(this, "xpcom-shutdown"); Services.obs.removeObserver(this, "xpcom-will-shutdown");
this.uninit(); this.uninit();
break; break;
} }
@ -295,6 +532,16 @@ class MarionetteMainProcess {
} }
await startupRecorder; await startupRecorder;
if (Preferences.get(PREF_RECOMMENDED)) {
for (let [k, v] of RECOMMENDED_PREFS) {
if (!Preferences.isSet(k)) {
log.debug(`Setting recommended pref ${k} to ${v}`);
Preferences.set(k, v);
this.alteredPrefs.add(k);
}
}
}
try { try {
ChromeUtils.import("chrome://marionette/content/server.js"); ChromeUtils.import("chrome://marionette/content/server.js");
let listener = new server.TCPListener(prefs.port); let listener = new server.TCPListener(prefs.port);
@ -302,9 +549,11 @@ class MarionetteMainProcess {
this.server = listener; this.server = listener;
} catch (e) { } catch (e) {
log.fatal("Remote protocol server failed to start", e); log.fatal("Remote protocol server failed to start", e);
this.uninit();
Services.startup.quit(Ci.nsIAppStartup.eForceQuit); Services.startup.quit(Ci.nsIAppStartup.eForceQuit);
} }
env.set(ENV_ENABLED, "1");
Services.obs.notifyObservers(this, NOTIFY_RUNNING, true); Services.obs.notifyObservers(this, NOTIFY_RUNNING, true);
log.info(`Listening on port ${this.server.port}`); log.info(`Listening on port ${this.server.port}`);
}); });
@ -313,6 +562,11 @@ class MarionetteMainProcess {
uninit() { uninit() {
if (this.running) { if (this.running) {
this.server.stop(); this.server.stop();
for (let k of this.alteredPrefs) {
log.debug(`Resetting recommended pref ${k}`);
Preferences.reset(k);
}
this.alteredPrefs.clear();
Services.obs.notifyObservers(this, NOTIFY_RUNNING); Services.obs.notifyObservers(this, NOTIFY_RUNNING);
} }
} }

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

@ -19,7 +19,7 @@ error module
.. js:autoclass:: InvalidSessionIDError .. js:autoclass:: InvalidSessionIDError
.. js:autoclass:: JavaScriptError .. js:autoclass:: JavaScriptError
.. js:autoclass:: MoveTargetOutOfBoundsError .. js:autoclass:: MoveTargetOutOfBoundsError
.. js:autoclass:: NoAlertOpenError .. js:autoclass:: NoSuchAlertError
.. js:autoclass:: NoSuchElementError .. js:autoclass:: NoSuchElementError
.. js:autoclass:: NoSuchFrameError .. js:autoclass:: NoSuchFrameError
.. js:autoclass:: NoSuchWindowError .. js:autoclass:: NoSuchWindowError

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

@ -32,7 +32,7 @@ const {
InvalidArgumentError, InvalidArgumentError,
InvalidCookieDomainError, InvalidCookieDomainError,
InvalidSelectorError, InvalidSelectorError,
NoAlertOpenError, NoSuchAlertError,
NoSuchFrameError, NoSuchFrameError,
NoSuchWindowError, NoSuchWindowError,
SessionNotCreatedError, SessionNotCreatedError,
@ -3162,7 +3162,7 @@ GeckoDriver.prototype.sendKeysToDialog = async function(cmd) {
GeckoDriver.prototype._checkIfAlertIsPresent = function() { GeckoDriver.prototype._checkIfAlertIsPresent = function() {
if (!this.dialog || !this.dialog.ui) { if (!this.dialog || !this.dialog.ui) {
throw new NoAlertOpenError("No modal dialog is currently open"); throw new NoSuchAlertError("No modal dialog is currently open");
} }
}; };

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

@ -18,7 +18,7 @@ const ERRORS = new Set([
"InvalidSessionIDError", "InvalidSessionIDError",
"JavaScriptError", "JavaScriptError",
"MoveTargetOutOfBoundsError", "MoveTargetOutOfBoundsError",
"NoAlertOpenError", "NoSuchAlertError",
"NoSuchElementError", "NoSuchElementError",
"NoSuchFrameError", "NoSuchFrameError",
"NoSuchWindowError", "NoSuchWindowError",
@ -418,7 +418,7 @@ class MoveTargetOutOfBoundsError extends WebDriverError {
* An attempt was made to operate on a modal dialog when one was * An attempt was made to operate on a modal dialog when one was
* not open. * not open.
*/ */
class NoAlertOpenError extends WebDriverError { class NoSuchAlertError extends WebDriverError {
constructor(message) { constructor(message) {
super(message); super(message);
this.status = "no such alert"; this.status = "no such alert";
@ -554,7 +554,7 @@ const STATUSES = new Map([
["invalid session id", InvalidSessionIDError], ["invalid session id", InvalidSessionIDError],
["javascript error", JavaScriptError], ["javascript error", JavaScriptError],
["move target out of bounds", MoveTargetOutOfBoundsError], ["move target out of bounds", MoveTargetOutOfBoundsError],
["no alert open", NoAlertOpenError], ["no such alert", NoSuchAlertError],
["no such element", NoSuchElementError], ["no such element", NoSuchElementError],
["no such frame", NoSuchFrameError], ["no such frame", NoSuchFrameError],
["no such window", NoSuchWindowError], ["no such window", NoSuchWindowError],

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

@ -6,12 +6,7 @@ from __future__ import absolute_import
import json import json
from marionette_driver.transport import ( from marionette_driver.transport import Command, Response
Command,
Proto2Command,
Proto2Response,
Response,
)
from marionette_harness import MarionetteTestCase from marionette_harness import MarionetteTestCase
@ -116,46 +111,3 @@ class TestResponse(MessageTestCase):
self.assertEquals(msg[1], resp.id) self.assertEquals(msg[1], resp.id)
self.assertEquals(msg[2], resp.error) self.assertEquals(msg[2], resp.error)
self.assertEquals(msg[3], resp.result) self.assertEquals(msg[3], resp.result)
class TestProto2Command(MessageTestCase):
def create(self, name="name", params="params"):
return Proto2Command(name, params)
def test_initialise(self):
cmd = self.create()
self.assert_attr(cmd, "id")
self.assert_attr(cmd, "name")
self.assert_attr(cmd, "params")
self.assertEqual(None, cmd.id)
self.assertEqual("name", cmd.name)
self.assertEqual("params", cmd.params)
def test_from_data_unknown(self):
with self.assertRaises(ValueError):
cmd = Proto2Command.from_data({})
class TestProto2Response(MessageTestCase):
def create(self, error="error", result="result"):
return Proto2Response(error, result)
def test_initialise(self):
resp = self.create()
self.assert_attr(resp, "id")
self.assert_attr(resp, "error")
self.assert_attr(resp, "result")
self.assertEqual(None, resp.id)
self.assertEqual("error", resp.error)
self.assertEqual("result", resp.result)
def test_from_data_error(self):
data = {"error": "error"}
resp = Proto2Response.from_data(data)
self.assertEqual(data, resp.error)
self.assertEqual(None, resp.result)
def test_from_data_result(self):
resp = Proto2Response.from_data("result")
self.assertEqual(None, resp.error)
self.assertEqual("result", resp.result)

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

@ -1,4 +1,5 @@
[test_marionette.py] [test_marionette.py]
[test_transport.py]
[test_cli_arguments.py] [test_cli_arguments.py]
skip-if = manage_instance == false || appname == 'fennec' # Bug 1298921 skip-if = manage_instance == false || appname == 'fennec' # Bug 1298921
[test_geckoinstance.py] [test_geckoinstance.py]

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

@ -14,7 +14,6 @@ const ServerSocket = CC(
ChromeUtils.import("resource://gre/modules/Log.jsm"); ChromeUtils.import("resource://gre/modules/Log.jsm");
ChromeUtils.import("resource://gre/modules/Preferences.jsm"); ChromeUtils.import("resource://gre/modules/Preferences.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("chrome://marionette/content/assert.js"); ChromeUtils.import("chrome://marionette/content/assert.js");
const {GeckoDriver} = ChromeUtils.import("chrome://marionette/content/driver.js", {}); const {GeckoDriver} = ChromeUtils.import("chrome://marionette/content/driver.js", {});
@ -30,9 +29,6 @@ const {
} = ChromeUtils.import("chrome://marionette/content/message.js", {}); } = ChromeUtils.import("chrome://marionette/content/message.js", {});
const {DebuggerTransport} = ChromeUtils.import("chrome://marionette/content/transport.js", {}); const {DebuggerTransport} = ChromeUtils.import("chrome://marionette/content/transport.js", {});
XPCOMUtils.defineLazyServiceGetter(
this, "env", "@mozilla.org/process/environment;1", "nsIEnvironment");
const logger = Log.repository.getLogger("Marionette"); const logger = Log.repository.getLogger("Marionette");
const {KeepWhenOffline, LoopbackOnly} = Ci.nsIServerSocket; const {KeepWhenOffline, LoopbackOnly} = Ci.nsIServerSocket;
@ -44,246 +40,8 @@ this.server = {};
const PROTOCOL_VERSION = 3; const PROTOCOL_VERSION = 3;
const ENV_ENABLED = "MOZ_MARIONETTE";
const PREF_CONTENT_LISTENER = "marionette.contentListener"; const PREF_CONTENT_LISTENER = "marionette.contentListener";
const PREF_PORT = "marionette.port"; const PREF_PORT = "marionette.port";
const PREF_RECOMMENDED = "marionette.prefs.recommended";
// Marionette sets preferences recommended for automation when it starts,
// unless marionette.prefs.recommended has been set to false.
// Where noted, some prefs should also be set in the profile passed to
// Marionette to prevent them from affecting startup, since some of these
// are checked before Marionette initialises.
const RECOMMENDED_PREFS = new Map([
// Disable automatic downloading of new releases.
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["app.update.auto", false],
// Disable automatically upgrading Firefox.
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["app.update.enabled", false],
// 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 all), resulting in the production timeout value
// sometimes being exceeded and causing false-positive test failures.
//
// (bug 1176798, bug 1177018, bug 1210465)
["apz.content_response_timeout", 60000],
// Indicate that the download panel has been shown once so that
// whichever download test runs first doesn't show the popup
// inconsistently.
["browser.download.panel.shown", true],
// Do not show the EULA notification.
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.EULA.override", true],
// Turn off about:newtab and make use of about:blank instead for new
// opened tabs.
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.newtabpage.enabled", false],
// Assume the about:newtab page's intro panels have been shown to not
// depend on which test runs first and happens to open about:newtab
["browser.newtabpage.introShown", true],
// Never start the browser in offline mode
//
// This should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.offline", false],
// Background thumbnails in particular cause grief, and disabling
// thumbnails in general cannot hurt
["browser.pagethumbnails.capturing_disabled", true],
// Disable safebrowsing components.
//
// These should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.safebrowsing.blockedURIs.enabled", false],
["browser.safebrowsing.downloads.enabled", false],
["browser.safebrowsing.passwords.enabled", false],
["browser.safebrowsing.malware.enabled", false],
["browser.safebrowsing.phishing.enabled", false],
// Disable updates to search engines.
//
// Should be set in profile.
["browser.search.update", false],
// Do not restore the last open set of tabs if the browser has crashed
["browser.sessionstore.resume_from_crash", false],
// Don't check for the default web browser during startup.
//
// These should also be set in the profile prior to starting Firefox,
// as it is picked up at runtime.
["browser.shell.checkDefaultBrowser", false],
// Start with a blank page (about:blank)
["browser.startup.page", 0],
// Do not redirect user when a milstone upgrade of Firefox is detected
["browser.startup.homepage_override.mstone", "ignore"],
// Disable browser animations
["toolkit.cosmeticAnimations.enabled", false],
// Do not allow background tabs to be zombified, otherwise for tests
// that open additional tabs, the test harness tab itself might get
// unloaded
["browser.tabs.disableBackgroundZombification", false],
// Do not warn when closing all other open tabs
["browser.tabs.warnOnCloseOtherTabs", false],
// Do not warn when multiple tabs will be opened
["browser.tabs.warnOnOpen", false],
// Disable first run splash page on Windows 10
["browser.usedOnWindows10.introURL", ""],
// Disable the UI tour.
//
// Should be set in profile.
["browser.uitour.enabled", false],
// Turn off search suggestions in the location bar so as not to trigger
// network connections.
["browser.urlbar.suggest.searches", false],
// Turn off the location bar search suggestions opt-in. It interferes with
// tests that don't expect it to be there.
["browser.urlbar.userMadeSearchSuggestionsChoice", true],
// Do not show datareporting policy notifications which can
// interfere with tests
[
"datareporting.healthreport.documentServerURI",
"http://%(server)s/dummy/healthreport/",
],
["datareporting.healthreport.logging.consoleEnabled", false],
["datareporting.healthreport.service.enabled", false],
["datareporting.healthreport.service.firstRun", false],
["datareporting.healthreport.uploadEnabled", false],
["datareporting.policy.dataSubmissionEnabled", false],
["datareporting.policy.dataSubmissionPolicyAccepted", false],
["datareporting.policy.dataSubmissionPolicyBypassNotification", true],
// Disable popup-blocker
["dom.disable_open_during_load", false],
// Enabling the support for File object creation in the content process
["dom.file.createInChild", true],
// Disable the ProcessHangMonitor
["dom.ipc.reportProcessHangs", false],
// Disable slow script dialogues
["dom.max_chrome_script_run_time", 0],
["dom.max_script_run_time", 0],
// Only load extensions from the application and user profile
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
//
// Should be set in profile.
["extensions.autoDisableScopes", 0],
["extensions.enabledScopes", 5],
// Disable metadata caching for installed add-ons by default
["extensions.getAddons.cache.enabled", false],
// Disable installing any distribution extensions or add-ons.
// 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
["extensions.update.enabled", false],
["extensions.update.notifyUser", false],
// Make sure opening about:addons will not hit the network
[
"extensions.webservice.discoverURL",
"http://%(server)s/dummy/discoveryURL",
],
// Allow the application to have focus even it runs in the background
["focusmanager.testmode", true],
// Disable useragent updates
["general.useragent.updates.enabled", false],
// Always use network provider for geolocation tests so we bypass the
// macOS dialog raised by the corelocation provider
["geo.provider.testing", true],
// Do not scan Wifi
["geo.wifi.scan", false],
// No hang monitor
["hangmonitor.timeout", 0],
// Show chrome errors and warnings in the error console
["javascript.options.showInConsole", true],
// Do not prompt for temporary redirects
["network.http.prompt-temp-redirect", false],
// Disable speculative connections so they are not reported as leaking
// when they are hanging around
["network.http.speculative-parallel-limit", 0],
// Do not automatically switch between offline and online
["network.manage-offline-status", false],
// Make sure SNTP requests do not hit the network
["network.sntp.pools", "%(server)s"],
// Local documents have access to all other local documents,
// including directory listings
["security.fileuri.strict_origin_policy", false],
// Tests do not wait for the notification button security delay
["security.notification_enable_delay", 0],
// Ensure blocklist updates do not hit the network
["services.settings.server", "http://%(server)s/dummy/blocklist/"],
// Do not automatically fill sign-in forms with known usernames and
// passwords
["signon.autofillForms", false],
// Disable password capture, so that tests that include forms are not
// influenced by the presence of the persistent doorhanger notification
["signon.rememberSignons", false],
// Disable first-run welcome page
["startup.homepage_welcome_url", "about:blank"],
["startup.homepage_welcome_url.additional", ""],
// Prevent starting into safe mode after application crashes
["toolkit.startup.max_resumed_crashes", -1],
]);
/** /**
* Bootstraps Marionette and handles incoming client connections. * Bootstraps Marionette and handles incoming client connections.
@ -303,7 +61,6 @@ server.TCPListener = class {
this.conns = new Set(); this.conns = new Set();
this.nextConnID = 0; this.nextConnID = 0;
this.alive = false; this.alive = false;
this.alteredPrefs = new Set();
} }
/** /**
@ -350,23 +107,9 @@ server.TCPListener = class {
return; return;
} }
if (Preferences.get(PREF_RECOMMENDED)) {
// set recommended prefs if they are not already user-defined
for (let [k, v] of RECOMMENDED_PREFS) {
if (!Preferences.isSet(k)) {
logger.debug(`Setting recommended pref ${k} to ${v}`);
Preferences.set(k, v);
this.alteredPrefs.add(k);
}
}
}
// Start socket server and listening for connection attempts // Start socket server and listening for connection attempts
this.acceptConnections = true; this.acceptConnections = true;
Preferences.set(PREF_PORT, this.port); Preferences.set(PREF_PORT, this.port);
env.set(ENV_ENABLED, "1");
this.alive = true; this.alive = true;
} }
@ -375,12 +118,6 @@ server.TCPListener = class {
return; return;
} }
for (let k of this.alteredPrefs) {
logger.debug(`Resetting recommended pref ${k}`);
Preferences.reset(k);
}
this.alteredPrefs.clear();
// Shutdown server socket, and no longer listen for new connections // Shutdown server socket, and no longer listen for new connections
this.acceptConnections = false; this.acceptConnections = false;
this.alive = false; this.alive = false;

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

@ -15,7 +15,7 @@ const {
InvalidSessionIDError, InvalidSessionIDError,
JavaScriptError, JavaScriptError,
MoveTargetOutOfBoundsError, MoveTargetOutOfBoundsError,
NoAlertOpenError, NoSuchAlertError,
NoSuchElementError, NoSuchElementError,
NoSuchFrameError, NoSuchFrameError,
NoSuchWindowError, NoSuchWindowError,
@ -333,9 +333,9 @@ add_test(function test_JavaScriptError() {
run_next_test(); run_next_test();
}); });
add_test(function test_NoAlertOpenError() { add_test(function test_NoSuchAlertError() {
let err = new NoAlertOpenError("foo"); let err = new NoSuchAlertError("foo");
equal("NoAlertOpenError", err.name); equal("NoSuchAlertError", err.name);
equal("foo", err.message); equal("foo", err.message);
equal("no such alert", err.status); equal("no such alert", err.status);
ok(err instanceof WebDriverError); ok(err instanceof WebDriverError);

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

@ -155,6 +155,8 @@ class PaymentDialog extends PaymentStateSubscriberMixin(HTMLElement) {
switch (state.completionState) { switch (state.completionState) {
case "initial": case "initial":
case "processing": case "processing":
case "success":
case "fail":
break; break;
default: default:
throw new Error("Invalid completionState"); throw new Error("Invalid completionState");

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

@ -31,6 +31,8 @@
<button id="setShippingError">Shipping Error</button> <button id="setShippingError">Shipping Error</button>
<button id="setStateDefault">Default</button> <button id="setStateDefault">Default</button>
<button id="setStateProcessing">Processing</button> <button id="setStateProcessing">Processing</button>
<button id="setStateSuccess">Success</button>
<button id="setStateFail">Fail</button>
</div> </div>
</body> </body>
</html> </html>

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

@ -293,6 +293,18 @@ let buttonActions = {
completionState: "processing", completionState: "processing",
}); });
}, },
setStateSuccess() {
requestStore.setState({
completionState: "success",
});
},
setStateFail() {
requestStore.setState({
completionState: "fail",
});
},
}; };
window.addEventListener("click", function onButtonClick(evt) { window.addEventListener("click", function onButtonClick(evt) {

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

@ -82,7 +82,9 @@ payment-dialog > footer {
border: none; border: none;
} }
payment-dialog[changes-prevented][completion-state="processing"] #pay { payment-dialog[changes-prevented][completion-state="fail"] #pay,
payment-dialog[changes-prevented][completion-state="processing"] #pay,
payment-dialog[changes-prevented][completion-state="success"] #pay {
/* Show the pay button above #disabled-overlay */ /* Show the pay button above #disabled-overlay */
position: relative; position: relative;
z-index: 1; z-index: 1;

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

@ -13,6 +13,8 @@
<!ENTITY cancelPaymentButton.label "Cancel"> <!ENTITY cancelPaymentButton.label "Cancel">
<!ENTITY approvePaymentButton.label "Pay"> <!ENTITY approvePaymentButton.label "Pay">
<!ENTITY processingPaymentButton.label "Processing"> <!ENTITY processingPaymentButton.label "Processing">
<!ENTITY successPaymentButton.label "Done">
<!ENTITY failPaymentButton.label "Fail">
<!ENTITY orderDetailsLabel "Order Details"> <!ENTITY orderDetailsLabel "Order Details">
<!ENTITY orderTotalLabel "Total"> <!ENTITY orderTotalLabel "Total">
]> ]>
@ -87,7 +89,9 @@
<button id="cancel">&cancelPaymentButton.label;</button> <button id="cancel">&cancelPaymentButton.label;</button>
<button id="pay" <button id="pay"
data-initial-label="&approvePaymentButton.label;" data-initial-label="&approvePaymentButton.label;"
data-processing-label="&processingPaymentButton.label;"></button> data-processing-label="&processingPaymentButton.label;"
data-fail-label="&failPaymentButton.label;"
data-success-label="&successPaymentButton.label;"></button>
</footer> </footer>
</section> </section>
<section id="order-details-overlay" hidden="hidden"> <section id="order-details-overlay" hidden="hidden">

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

@ -36,6 +36,12 @@ Test the payment-dialog custom element
let el1; let el1;
let completionStates = [
["processing", "Processing"],
["success", "Done"],
["fail", "Fail"],
];
/* test that: /* test that:
the view-all-items button exists the view-all-items button exists
that clicking it changes the state on the store that clicking it changes the state on the store
@ -117,10 +123,12 @@ add_task(async function test_completionState() {
let payButton = document.getElementById("pay"); let payButton = document.getElementById("pay");
is(payButton.textContent, "Pay", "Check default label"); is(payButton.textContent, "Pay", "Check default label");
ok(!payButton.disabled, "Button is enabled"); ok(!payButton.disabled, "Button is enabled");
await el1.requestStore.setState({completionState: "processing"}); for (let [completionState, label] of completionStates) {
await asyncElementRendered(); await el1.requestStore.setState({completionState});
is(payButton.textContent, "Processing", "Check processing label"); await asyncElementRendered();
ok(!payButton.disabled, "Button is still enabled"); is(payButton.textContent, label, "Check payButton label");
ok(!payButton.disabled, "Button is still enabled");
}
}); });
add_task(async function test_completionStateChangesPrevented() { add_task(async function test_completionStateChangesPrevented() {
@ -132,21 +140,19 @@ add_task(async function test_completionStateChangesPrevented() {
is(payButton.textContent, "Pay", "Check default label"); is(payButton.textContent, "Pay", "Check default label");
ok(!payButton.disabled, "Button is enabled"); ok(!payButton.disabled, "Button is enabled");
await el1.requestStore.setState({ for (let [completionState, label] of completionStates) {
changesPrevented: true, await el1.requestStore.setState({
completionState: "processing", changesPrevented: true,
}); completionState,
await asyncElementRendered(); });
is(payButton.textContent, "Processing", "Check processing label"); await asyncElementRendered();
ok(payButton.disabled, "Button is disabled"); is(payButton.textContent, label, "Check payButton label");
let { ok(payButton.disabled, "Button is disabled");
x, let rect = payButton.getBoundingClientRect();
y, let visibleElement =
width, document.elementFromPoint(rect.x + rect.width / 2, rect.y + rect.height / 2);
height, ok(payButton === visibleElement, "Pay button is on top of the overlay");
} = payButton.getBoundingClientRect(); }
let visibleElement = document.elementFromPoint(x + width / 2, y + height / 2);
ok(payButton === visibleElement, "Pay button is on top of the overlay");
}); });
add_task(async function test_disconnect() { add_task(async function test_disconnect() {

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

@ -310,14 +310,17 @@ class SyncedBookmarksMirror {
* The current local time, in seconds. * The current local time, in seconds.
* @param {Number} [options.remoteTimeSeconds] * @param {Number} [options.remoteTimeSeconds]
* The current server time, in seconds. * The current server time, in seconds.
* @param {String[]} [options.weakUpload]
* GUIDs of bookmarks to weakly upload.
* @return {Object.<String, BookmarkChangeRecord>} * @return {Object.<String, BookmarkChangeRecord>}
* A changeset containing locally changed and reconciled records to * A changeset containing locally changed and reconciled records to
* upload to the server, and to store in the mirror once upload * upload to the server, and to store in the mirror once upload
* succeeds. * succeeds.
*/ */
async apply({ localTimeSeconds = Date.now() / 1000, async apply({ localTimeSeconds = Date.now() / 1000,
remoteTimeSeconds = 0 } = {}) { remoteTimeSeconds = 0,
let hasChanges = await this.hasChanges(); weakUpload = [] } = {}) {
let hasChanges = weakUpload.length > 0 || (await this.hasChanges());
if (!hasChanges) { if (!hasChanges) {
MirrorLog.debug("No changes detected in both mirror and Places"); MirrorLog.debug("No changes detected in both mirror and Places");
return {}; return {};
@ -425,7 +428,7 @@ class SyncedBookmarksMirror {
await this.noteObserverChanges(observersToNotify); await this.noteObserverChanges(observersToNotify);
MirrorLog.debug("Staging locally changed items for upload"); MirrorLog.debug("Staging locally changed items for upload");
await this.stageItemsToUpload(); await this.stageItemsToUpload(weakUpload);
MirrorLog.debug("Fetching records for local items to upload"); MirrorLog.debug("Fetching records for local items to upload");
let changeRecords = await this.fetchLocalChangeRecords(); let changeRecords = await this.fetchLocalChangeRecords();
@ -1472,8 +1475,21 @@ class SyncedBookmarksMirror {
* items. The change counter in Places is the persistent record of items that * items. The change counter in Places is the persistent record of items that
* we need to upload, so, if upload is interrupted or fails, we'll stage the * we need to upload, so, if upload is interrupted or fails, we'll stage the
* items again on the next sync. * items again on the next sync.
*
* @param {String[]} weakUpload
* GUIDs of bookmarks to weakly upload.
*/ */
async stageItemsToUpload() { async stageItemsToUpload(weakUpload) {
// Stage explicit weak uploads such as repair responses.
for (let chunk of PlacesSyncUtils.chunkArray(weakUpload,
SQLITE_MAX_VARIABLE_NUMBER)) {
await this.db.execute(`
INSERT INTO itemsToWeaklyReupload(id)
SELECT b.id FROM moz_bookmarks b
WHERE b.guid IN (${new Array(chunk.length).fill("?").join(",")})`,
chunk);
}
// Stage remotely changed items with older local creation dates. These are // Stage remotely changed items with older local creation dates. These are
// tracked "weakly": if the upload is interrupted or fails, we won't // tracked "weakly": if the upload is interrupted or fails, we won't
// reupload the record on the next sync. // reupload the record on the next sync.

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

@ -1,3 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function test_missing_children() { add_task(async function test_missing_children() {
let buf = await openMirror("missing_childen"); let buf = await openMirror("missing_childen");

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

@ -1,3 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function test_duping() { add_task(async function test_duping() {
let buf = await openMirror("duping"); let buf = await openMirror("duping");

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

@ -1,3 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function test_complex_orphaning() { add_task(async function test_complex_orphaning() {
let buf = await openMirror("complex_orphaning"); let buf = await openMirror("complex_orphaning");

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

@ -0,0 +1,39 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function test_explicit_weakupload() {
let buf = await openMirror("weakupload");
await PlacesUtils.bookmarks.insertTree({
guid: PlacesUtils.bookmarks.menuGuid,
children: [{
guid: "mozBmk______",
url: "https://mozilla.org",
title: "Mozilla",
tags: ["moz", "dot", "org"],
}],
});
await buf.store(shuffle([{
id: "menu",
type: "folder",
children: ["mozBmk______"],
}, {
id: "mozBmk______",
type: "bookmark",
title: "Mozilla",
bmkUri: "https://mozilla.org",
tags: ["moz", "dot", "org"],
}]), { needsMerge: false });
await PlacesTestUtils.markBookmarksAsSynced();
let changesToUpload = await buf.apply({
weakUpload: ["mozBmk______"]
});
ok("mozBmk______" in changesToUpload);
equal(changesToUpload.mozBmk______.counter, 0);
await buf.finalize();
await PlacesUtils.bookmarks.eraseEverything();
await PlacesSyncUtils.bookmarks.reset();
});

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

@ -1,3 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function test_no_changes() { add_task(async function test_no_changes() {
let buf = await openMirror("nochanges"); let buf = await openMirror("nochanges");

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

@ -1,3 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function test_livemarks() { add_task(async function test_livemarks() {
let { site, stopServer } = makeLivemarkServer(); let { site, stopServer } = makeLivemarkServer();

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

@ -1,3 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function test_value_structure_conflict() { add_task(async function test_value_structure_conflict() {
let buf = await openMirror("value_structure_conflict"); let buf = await openMirror("value_structure_conflict");

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

@ -1,3 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function test_value_combo() { add_task(async function test_value_combo() {
let buf = await openMirror("value_combo"); let buf = await openMirror("value_combo");

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

@ -8,6 +8,7 @@ support-files =
[test_bookmark_corruption.js] [test_bookmark_corruption.js]
[test_bookmark_deduping.js] [test_bookmark_deduping.js]
[test_bookmark_deletion.js] [test_bookmark_deletion.js]
[test_bookmark_explicit_weakupload.js]
[test_bookmark_haschanges.js] [test_bookmark_haschanges.js]
[test_bookmark_kinds.js] [test_bookmark_kinds.js]
[test_bookmark_structure_changes.js] [test_bookmark_structure_changes.js]

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

@ -647,7 +647,7 @@ var AddonRepository = {
if (typeof aEntry.ratings == "object") { if (typeof aEntry.ratings == "object") {
addon.averageRating = Math.min(5, aEntry.ratings.average); addon.averageRating = Math.min(5, aEntry.ratings.average);
addon.reviewCount = aEntry.ratings.count; addon.reviewCount = aEntry.ratings.text_count;
} }
addon.reviewURL = aEntry.ratings_url; addon.reviewURL = aEntry.ratings_url;

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

@ -39,7 +39,8 @@
"32": "http://localhost/repo/1/icon.png" "32": "http://localhost/repo/1/icon.png"
}, },
"ratings": { "ratings": {
"count": 1111, "count": 1234,
"text_count": 1111,
"average": 1 "average": 1
}, },
"homepage": "http://localhost/repo/1/homepage.html", "homepage": "http://localhost/repo/1/homepage.html",
@ -95,7 +96,8 @@
} }
], ],
"ratings": { "ratings": {
"count": 1112, "count": 2223,
"text_count": 1112,
"average": 2 "average": 2
}, },
"homepage": "http://localhost/repo/2/homepage.html", "homepage": "http://localhost/repo/2/homepage.html",

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

@ -49,7 +49,8 @@
} }
], ],
"ratings": { "ratings": {
"count": 1111, "count": 1234,
"text_count": 1111,
"average": 4 "average": 4
}, },
"ratings_url": "http://localhost:%PORT%/review1.html", "ratings_url": "http://localhost:%PORT%/review1.html",

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

@ -66,7 +66,6 @@ toolbarbutton[checked="true"]:not([disabled="true"]) {
padding-bottom: 2px; padding-bottom: 2px;
padding-inline-start: 4px; padding-inline-start: 4px;
padding-inline-end: 2px; padding-inline-end: 2px;
color: ButtonText;
} }
@media (-moz-windows-default-theme) { @media (-moz-windows-default-theme) {

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

@ -16,31 +16,26 @@
var path = require("path"); var path = require("path");
var helpers = require("../helpers"); var helpers = require("../helpers");
var globals = require("../globals"); var globals = require("../globals");
var modules = helpers.modulesGlobalData;
const placesOverlayFiles = [ const placesOverlayFiles = [
"toolkit/content/globalOverlay.js", "toolkit/content/globalOverlay.js",
"browser/base/content/utilityOverlay.js", "browser/base/content/utilityOverlay.js"
"browser/components/places/content/controller.js",
"browser/components/places/content/treeView.js"
]; ];
const extraPlacesDefinitions = [ const extraPlacesDefinitions = [
// Straight definitions. // Via Components.utils, defineModuleGetter, defineLazyModuleGetters or
{name: "Cc", writable: false}, // defineLazyScriptGetter (and map to
{name: "Ci", writable: false},
{name: "Cr", writable: false},
{name: "Cu", writable: false},
// Via Components.utils / XPCOMUtils.defineLazyModuleGetter (and map to
// single) variable. // single) variable.
{name: "XPCOMUtils", writable: false}, {name: "XPCOMUtils", writable: false},
{name: "Task", writable: false}, {name: "Task", writable: false},
{name: "PlacesUtils", writable: false},
{name: "PlacesUIUtils", writable: false}, {name: "PlacesUIUtils", writable: false},
{name: "PlacesTransactions", writable: false} {name: "PlacesTransactions", writable: false},
]; {name: "ForgetAboutSite", writable: false},
{name: "PlacesTreeView", writable: false},
const placesOverlayModules = [ {name: "PlacesInsertionPoint", writable: false},
"PlacesUtils.jsm" {name: "PlacesController", writable: false},
{name: "PlacesControllerDragHelper", writable: false}
]; ];
function getScriptGlobals() { function getScriptGlobals() {
@ -54,14 +49,6 @@ function getScriptGlobals() {
} }
} }
for (let file of placesOverlayModules) {
if (file in modules) {
for (let globalVar of modules[file]) {
fileGlobals.push({name: globalVar, writable: false});
}
}
}
return fileGlobals.concat(extraPlacesDefinitions); return fileGlobals.concat(extraPlacesDefinitions);
} }