зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-cental to mozilla-inbound. r=merge
--HG-- extra : rebase_source : f7e0a6b0f2925bd159de4d665c02493dab9b6282
This commit is contained in:
Коммит
6735016b56
|
@ -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 " +
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче