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

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

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

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

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

@ -381,7 +381,7 @@ var FeedHandler = {
// http://foo.com/index.rdf -> feed://foo.com/index.rdf
// other urls: prepend feed: scheme, e.g.
// 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")) {
feedURI = feedURI.mutate()
.setScheme("feed")

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

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

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

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

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

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

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

@ -69,6 +69,72 @@ let whitelist = [
intermittent: true,
errorMessage: /Property contained reference to invalid variable.*color/i,
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")) {
@ -194,6 +260,7 @@ function messageIsCSSError(msg) {
}
let imageURIsToReferencesMap = new Map();
let customPropsToReferencesMap = new Map();
function processCSSRules(sheet) {
for (let rule of sheet.cssRules) {
@ -208,10 +275,11 @@ function processCSSRules(sheet) {
// Note: CSSStyleRule.cssText always has double quotes around URLs even
// when the original CSS file didn't.
let urls = rule.cssText.match(/url\("[^"]*"\)/g);
if (!urls)
let props = rule.cssText.match(/(var\()?(--[\w\-]+)/g);
if (!urls && !props)
continue;
for (let url of urls) {
for (let url of (urls || [])) {
// Remove the url(" prefix and the ") suffix.
url = url.replace(/url\("(.*)"\)/, "$1");
if (url.startsWith("data:"))
@ -229,6 +297,16 @@ function processCSSRules(sheet) {
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();
// Count errors (the test output will list actual issues for us, as well
// as the ok(false) in messageIsCSSError.
@ -362,8 +460,12 @@ add_task(async function checkAllTheCSS() {
// Confirm that all whitelist rules have been used.
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. " +
(item.propName ? " propName: " + item.propName : "") +
(item.sourceName ? " sourceName: " + item.sourceName : "") +
(item.errorMessage ? " errorMessage: " + item.errorMessage : ""));
}
@ -388,4 +490,5 @@ add_task(async function checkAllTheCSS() {
hiddenFrame.destroy();
hiddenFrame = null;
imageURIsToReferencesMap = null;
customPropsToReferencesMap = null;
});

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

@ -256,61 +256,6 @@ var PlacesUIUtils = {
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.
*
@ -404,6 +349,77 @@ var PlacesUIUtils = {
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
* 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;
},
};
PlacesUIUtils.PLACES_FLAVORS = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
PlacesUtils.TYPE_X_MOZ_PLACE];
PlacesUIUtils.URI_FLAVORS = [PlacesUtils.TYPE_X_MOZ_URL,
TAB_DROP_TYPE,
PlacesUtils.TYPE_UNICODE],
PlacesUIUtils.SUPPORTED_FLAVORS = [...PlacesUIUtils.PLACES_FLAVORS,
...PlacesUIUtils.URI_FLAVORS];
// These are lazy getters to avoid importing PlacesUtils immediately.
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "PLACES_FLAVORS", () => {
return [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
PlacesUtils.TYPE_X_MOZ_PLACE];
});
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "URI_FLAVORS", () => {
return [PlacesUtils.TYPE_X_MOZ_URL,
TAB_DROP_TYPE,
PlacesUtils.TYPE_UNICODE];
});
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "SUPPORTED_FLAVORS", () => {
return [...PlacesUIUtils.PLACES_FLAVORS,
...PlacesUIUtils.URI_FLAVORS];
});
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ellipsis", function() {
return Services.prefs.getComplexValue("intl.ellipsis",
@ -1201,3 +1333,117 @@ XPCOMUtils.defineLazyPreferenceGetter(PlacesUIUtils, "loadBookmarksInTabs",
PREF_LOAD_BOOKMARKS_IN_TABS, false);
XPCOMUtils.defineLazyPreferenceGetter(PlacesUIUtils, "openInTabClosesMenu",
"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;
} else {
this._defaultInsertionPoint =
new InsertionPoint({
new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid
});

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

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

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

@ -3,13 +3,6 @@
* 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/. */
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
* items.
@ -30,11 +23,11 @@ ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
* - dropNearNode
* When defined index will be calculated based on this node
*/
function InsertionPoint({ parentId, parentGuid,
index = PlacesUtils.bookmarks.DEFAULT_INDEX,
orientation = Ci.nsITreeView.DROP_ON,
tagName = null,
dropNearNode = null }) {
function PlacesInsertionPoint({ parentId, parentGuid,
index = PlacesUtils.bookmarks.DEFAULT_INDEX,
orientation = Ci.nsITreeView.DROP_ON,
tagName = null,
dropNearNode = null }) {
this.itemId = parentId;
this.guid = parentGuid;
this._index = index;
@ -43,7 +36,7 @@ function InsertionPoint({ parentId, parentGuid,
this.dropNearNode = dropNearNode;
}
InsertionPoint.prototype = {
PlacesInsertionPoint.prototype = {
set index(val) {
return this._index = val;
},
@ -230,7 +223,7 @@ PlacesController.prototype = {
var queries = this._view.selectedNode.getQueries();
host = queries[0].domain;
} else
host = NetUtil.newURI(this._view.selectedNode.uri).host;
host = Services.io.newURI(this._view.selectedNode.uri).host;
ForgetAboutSite.removeDataFromDomain(host)
.catch(Cu.reportError);
break;
@ -275,7 +268,7 @@ PlacesController.prototype = {
"keyword",
"location",
"loadInSidebar" ],
uri: NetUtil.newURI(node.uri),
uri: Services.io.newURI(node.uri),
title: node.title
}, window.top);
break;
@ -428,7 +421,7 @@ PlacesController.prototype = {
break;
case Ci.nsINavHistoryResultNode.RESULT_TYPE_URI:
nodeData.link = true;
uri = NetUtil.newURI(node.uri);
uri = Services.io.newURI(node.uri);
if (PlacesUtils.nodeIsBookmark(node)) {
nodeData.bookmark = true;
var parentNode = node.parent;
@ -1213,7 +1206,7 @@ PlacesController.prototype = {
}
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.
if (action == "cut") {
@ -1256,7 +1249,41 @@ PlacesController.prototype = {
*/
getCachedLivemarkInfo: function PC_getCachedLivemarkInfo(aNode) {
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;
},
/**
* 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.
*
@ -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",
"@mozilla.org/widget/dragservice;1",
"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.
}
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 isBookmark = isItem && isURI;
let bulkTagging = !node;
@ -932,7 +932,7 @@ var gEditItemOverlay = {
// default to the bookmarks menu folder
if (!ip) {
ip = new InsertionPoint({
ip = new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid
});
@ -1072,7 +1072,7 @@ var gEditItemOverlay = {
switch (aProperty) {
case "uri":
let newURI = NetUtil.newURI(aValue);
let newURI = Services.ui.newURI(aValue);
if (!newURI.equals(this._paneInfo.uri)) {
this._paneInfo.uri = newURI;
if (this._paneInfo.visibleRows.has("locationRow"))

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

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

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

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

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

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

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

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

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

@ -28,7 +28,7 @@ add_task(async function() {
Assert.equal(tree.selectedNode.bookmarkGuid, folder.guid,
"Selected the expected node");
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");
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(PlacesUtils.getConcreteItemGuid(tree.selectedNode),
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");
info("Test a query");
@ -63,7 +63,7 @@ add_task(async function() {
tree.selectItems([query.guid]);
Assert.equal(tree.selectedNode.bookmarkGuid, query.guid,
"Selected the expected node");
Assert.ok(PlacesControllerDragHelper.canMoveNode(tree.selectedNode, tree),
Assert.ok(tree.controller.canMoveNode(tree.selectedNode),
"can move query node");
@ -79,7 +79,7 @@ add_task(async function() {
PlacesUtils.asQuery(tree.selectedNode).containerOpen = true;
Assert.equal(tree.selectedNode.childCount, 1, "has tags");
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");
tree.selectedNode.containerOpen = false;
@ -92,7 +92,7 @@ add_task(async function() {
for (let guid of roots) {
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");
let id = await PlacesUtils.promiseItemId(guid);
let s = await PlacesUtils.bookmarks.insert({
@ -103,7 +103,7 @@ add_task(async function() {
tree.selectItems([s.guid]);
Assert.equal(tree.selectedNode.bookmarkGuid, s.guid,
"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");
}
});

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

@ -34,7 +34,7 @@ add_task(async function test() {
let tree = sidebar.contentDocument.getElementById("bookmarks-view");
tree.focus();
let controller = doGetPlacesControllerForCommand("placesCmd_copy");
let controller = PlacesUIUtils.getControllerForCommand(window, "placesCmd_copy");
let treeController = tree.controllers
.getControllerForCommand("placesCmd_copy");
ok(controller == treeController, "tree controller was returned");
@ -45,7 +45,7 @@ add_task(async function test() {
EventUtils.synthesizeMouse(toolbarItems.childNodes[0],
4, 4, { type: "contextmenu", button: 2 },
window);
controller = doGetPlacesControllerForCommand("placesCmd_copy");
controller = PlacesUIUtils.getControllerForCommand(window, "placesCmd_copy");
let toolbarController = document.getElementById("PlacesToolbar")
.controllers
.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.
tree.focus();
controller = doGetPlacesControllerForCommand("placesCmd_copy");
controller = PlacesUIUtils.getControllerForCommand(window, "placesCmd_copy");
ok(controller == treeController, "tree controller was returned");
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
// 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.
let ip = new InsertionPoint({
let ip = new PlacesInsertionPoint({
parentId: await PlacesUtils.promiseItemId(PlacesUtils.bookmarks.unfiledGuid),
parentGuid: newParentGuid,
index: insertionIndex,

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

@ -69,7 +69,7 @@ async function simulateDrop(selectTargets, sourceBm, dropEffect, targetGuid,
Assert.equal(dataTransfer.dropEffect, dropEffect);
let ip = new InsertionPoint({
let ip = new PlacesInsertionPoint({
parentId: await PlacesUtils.promiseItemId(targetGuid),
parentGuid: targetGuid,
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
// 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.
let ip = new InsertionPoint({
let ip = new PlacesInsertionPoint({
isTag: true,
tagName: TAG_NAME,
orientation: Ci.nsITreeView.DROP_ON

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

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

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

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

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

@ -3,93 +3,41 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from head.js */
// Check that Dead Objects do not break the Web/Browser Consoles.
// See bug 883649.
// This test does:
// - opens a new tab,
// - opens the Browser Console,
// - stores a reference to the content document of the tab on the chrome
// window object,
// - closes the tab,
// - tries to use the object that was pointing to the now-defunct content
// document. This is the dead object.
//
// This test:
// - Opens the Browser Console.
// - Creates a sandbox.
// - Stores a reference to the sandbox on the chrome window object.
// - Nukes the sandbox
// - Tries to use the sandbox. This is the dead object.
"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 hud = null;
let jsterm = hud.jsterm;
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.chrome.enabled");
});
// Add the reference to the nuked sandbox.
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() {
Services.prefs.setBoolPref("devtools.chrome.enabled", true);
yield loadTab(TEST_URI);
let browser = gBrowser.selectedBrowser;
let winID = browser.outerWindowID;
jsterm.execute("nukedSandbox.hello");
let msg = await waitFor(() => findMessage(hud, "can't access dead object"));
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();
ok(hud, "browser console opened");
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");
}
}
await jsterm.execute("delete window.nukedSandbox; 2013-26");
await waitFor(() => findMessage(hud, "1987"));
});

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

@ -2544,14 +2544,7 @@ Console::MonotonicTimer(JSContext* aCx, MethodName aMethodName,
}
if (NS_IsMainThread()) {
double duration = (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);
*aTimeStamp = (TimeStamp::Now() - mCreationTimeStamp).ToMilliseconds();
return true;
}

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

@ -447,7 +447,7 @@ MP3TrackDemuxer::FindFirstFrame()
" Length()=%" PRIu64,
candidateFrame.mStart, candidateFrame.Length());
while (candidateFrame.Length() && numSuccFrames < MIN_SUCCESSIVE_FRAMES) {
while (candidateFrame.Length()) {
mParser.EndFrameSession();
mOffset = currentFrame.mEnd;
const MediaByteRange prevFrame = currentFrame;
@ -473,16 +473,26 @@ MP3TrackDemuxer::FindFirstFrame()
MP3LOGV("FindFirst() new candidate frame: mOffset=%" PRIu64
" Length()=%" PRIu64,
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() accepting candidate frame: "
"successiveFrames=%d", numSuccFrames);
mFrameLock = true;
} else {
MP3LOG("FindFirst() no suitable first frame found");
}
MP3LOG("FindFirst() no suitable first frame found");
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
// "The Media Foundation H.264 video decoder is a Media Foundation Transform
// 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.
return level >= H264_LEVEL_1 &&
level <= H264_LEVEL_5_1 &&
level <= H264_LEVEL_5_2 &&
(profile == H264_PROFILE_BASE ||
profile == H264_PROFILE_MAIN ||
profile == H264_PROFILE_EXTENDED ||

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -90,14 +90,14 @@ dependencies = [
[[package]]
name = "azure"
version = "0.27.0"
source = "git+https://github.com/servo/rust-azure#46a9c9c6279ba46354b48f6fc849ee20624cbf90"
version = "0.28.0"
source = "git+https://github.com/servo/rust-azure#29f0c063ad366b5364e06af26d3e9d1ee588e3b2"
dependencies = [
"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)",
"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-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]]
@ -270,7 +270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "canvas"
version = "0.0.1"
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",
"compositing 0.0.1",
"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)",
]
[[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]]
name = "dwrote"
version = "0.4.2"
@ -2634,7 +2643,7 @@ dependencies = [
"osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"script_traits 0.0.1",
"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_geometry 0.0.1",
"servo_url 0.0.1",
@ -2684,7 +2693,7 @@ dependencies = [
[[package]]
name = "servo-glutin"
version = "0.14.2"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"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)",
"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)",
"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)",
"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)",
"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)",
"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)",
"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)",
]
[[package]]
name = "servo-skia"
version = "0.30000012.0"
version = "0.30000013.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"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-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-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)",
]
@ -2840,6 +2854,15 @@ dependencies = [
"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]]
name = "sig"
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 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 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-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"
@ -3639,6 +3662,7 @@ dependencies = [
"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-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 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"
@ -3790,11 +3814,12 @@ dependencies = [
"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-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-skia 0.30000012.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80980e6eb854c06e8e45fa3cfbd439bf4223a6840f38c3caec34efa39cf9405e"
"checksum servo-glutin 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a36b9398e9cade5b1e3011d841d9d98d4e86a538a1b639db62100d86134c10f6"
"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 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 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 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"

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

@ -76,16 +76,6 @@ fn generate_properties() {
.arg(&script)
.arg(product)
.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()
.unwrap();
if !status.success() {

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

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

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

@ -66,9 +66,9 @@ ${helpers.predefined_type(
"stroke-width", "SVGWidth",
"::values::computed::NonNegativeLength::new(1.).into()",
products="gecko",
boxed=not RUSTC_HAS_PR45225,
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",
products="gecko", animation_value_type="discrete",
@ -101,9 +101,9 @@ ${helpers.predefined_type(
"stroke-dashoffset", "SVGLength",
"Au(0).into()",
products="gecko",
boxed=not RUSTC_HAS_PR45225,
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
${helpers.single_keyword("clip-rule", "nonzero evenodd",

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

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

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

@ -1 +1 @@
1.23.0
1.24.0

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

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

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

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

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

@ -9,6 +9,7 @@
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"
#include "nsProxyRelease.h"
#include "nsThreadUtils.h"
@ -380,6 +381,16 @@ private:
*/
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
* protected by sharedDBMutex.

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

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

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

@ -20,10 +20,11 @@ XPCOMUtils.defineLazyGetter(this, "log", () => {
});
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 = "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 NOTIFY_RUNNING = "remote-active";
@ -46,6 +47,241 @@ const ENV_ENABLED = "MOZ_MARIONETTE";
// pref being set to 4444.
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 ==
Services.appinfo.PROCESS_TYPE_CONTENT;
@ -155,6 +391,7 @@ class MarionetteMainProcess {
log.level = prefs.logLevel;
this.enabled = env.exists(ENV_ENABLED);
this.alteredPrefs = new Set();
Services.prefs.addObserver(PREF_ENABLED, this);
Services.ppmm.addMessageListener("Marionette:IsRunning", this);
@ -225,7 +462,7 @@ class MarionetteMainProcess {
if (this.gfxWindow === null || subject === this.gfxWindow) {
Services.obs.removeObserver(this, topic);
Services.obs.addObserver(this, "xpcom-shutdown");
Services.obs.addObserver(this, "xpcom-will-shutdown");
this.finalUIStartup = true;
this.init();
}
@ -254,15 +491,15 @@ class MarionetteMainProcess {
if (this.gfxWindow) {
Services.obs.addObserver(this, "domwindowclosed");
} else {
Services.obs.addObserver(this, "xpcom-shutdown");
Services.obs.addObserver(this, "xpcom-will-shutdown");
this.finalUIStartup = true;
this.init();
}
break;
case "xpcom-shutdown":
Services.obs.removeObserver(this, "xpcom-shutdown");
case "xpcom-will-shutdown":
Services.obs.removeObserver(this, "xpcom-will-shutdown");
this.uninit();
break;
}
@ -295,6 +532,16 @@ class MarionetteMainProcess {
}
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 {
ChromeUtils.import("chrome://marionette/content/server.js");
let listener = new server.TCPListener(prefs.port);
@ -302,9 +549,11 @@ class MarionetteMainProcess {
this.server = listener;
} catch (e) {
log.fatal("Remote protocol server failed to start", e);
this.uninit();
Services.startup.quit(Ci.nsIAppStartup.eForceQuit);
}
env.set(ENV_ENABLED, "1");
Services.obs.notifyObservers(this, NOTIFY_RUNNING, true);
log.info(`Listening on port ${this.server.port}`);
});
@ -313,6 +562,11 @@ class MarionetteMainProcess {
uninit() {
if (this.running) {
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);
}
}

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

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

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

@ -32,7 +32,7 @@ const {
InvalidArgumentError,
InvalidCookieDomainError,
InvalidSelectorError,
NoAlertOpenError,
NoSuchAlertError,
NoSuchFrameError,
NoSuchWindowError,
SessionNotCreatedError,
@ -3162,7 +3162,7 @@ GeckoDriver.prototype.sendKeysToDialog = async function(cmd) {
GeckoDriver.prototype._checkIfAlertIsPresent = function() {
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",
"JavaScriptError",
"MoveTargetOutOfBoundsError",
"NoAlertOpenError",
"NoSuchAlertError",
"NoSuchElementError",
"NoSuchFrameError",
"NoSuchWindowError",
@ -418,7 +418,7 @@ class MoveTargetOutOfBoundsError extends WebDriverError {
* An attempt was made to operate on a modal dialog when one was
* not open.
*/
class NoAlertOpenError extends WebDriverError {
class NoSuchAlertError extends WebDriverError {
constructor(message) {
super(message);
this.status = "no such alert";
@ -554,7 +554,7 @@ const STATUSES = new Map([
["invalid session id", InvalidSessionIDError],
["javascript error", JavaScriptError],
["move target out of bounds", MoveTargetOutOfBoundsError],
["no alert open", NoAlertOpenError],
["no such alert", NoSuchAlertError],
["no such element", NoSuchElementError],
["no such frame", NoSuchFrameError],
["no such window", NoSuchWindowError],

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

@ -6,12 +6,7 @@ from __future__ import absolute_import
import json
from marionette_driver.transport import (
Command,
Proto2Command,
Proto2Response,
Response,
)
from marionette_driver.transport import Command, Response
from marionette_harness import MarionetteTestCase
@ -116,46 +111,3 @@ class TestResponse(MessageTestCase):
self.assertEquals(msg[1], resp.id)
self.assertEquals(msg[2], resp.error)
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_transport.py]
[test_cli_arguments.py]
skip-if = manage_instance == false || appname == 'fennec' # Bug 1298921
[test_geckoinstance.py]

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

@ -14,7 +14,6 @@ const ServerSocket = CC(
ChromeUtils.import("resource://gre/modules/Log.jsm");
ChromeUtils.import("resource://gre/modules/Preferences.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("chrome://marionette/content/assert.js");
const {GeckoDriver} = ChromeUtils.import("chrome://marionette/content/driver.js", {});
@ -30,9 +29,6 @@ const {
} = ChromeUtils.import("chrome://marionette/content/message.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 {KeepWhenOffline, LoopbackOnly} = Ci.nsIServerSocket;
@ -44,246 +40,8 @@ this.server = {};
const PROTOCOL_VERSION = 3;
const ENV_ENABLED = "MOZ_MARIONETTE";
const PREF_CONTENT_LISTENER = "marionette.contentListener";
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.
@ -303,7 +61,6 @@ server.TCPListener = class {
this.conns = new Set();
this.nextConnID = 0;
this.alive = false;
this.alteredPrefs = new Set();
}
/**
@ -350,23 +107,9 @@ server.TCPListener = class {
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
this.acceptConnections = true;
Preferences.set(PREF_PORT, this.port);
env.set(ENV_ENABLED, "1");
this.alive = true;
}
@ -375,12 +118,6 @@ server.TCPListener = class {
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
this.acceptConnections = false;
this.alive = false;

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

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

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

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

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

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

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

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

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

@ -82,7 +82,9 @@ payment-dialog > footer {
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 */
position: relative;
z-index: 1;

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

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

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

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

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

@ -310,14 +310,17 @@ class SyncedBookmarksMirror {
* The current local time, in seconds.
* @param {Number} [options.remoteTimeSeconds]
* The current server time, in seconds.
* @param {String[]} [options.weakUpload]
* GUIDs of bookmarks to weakly upload.
* @return {Object.<String, BookmarkChangeRecord>}
* A changeset containing locally changed and reconciled records to
* upload to the server, and to store in the mirror once upload
* succeeds.
*/
async apply({ localTimeSeconds = Date.now() / 1000,
remoteTimeSeconds = 0 } = {}) {
let hasChanges = await this.hasChanges();
remoteTimeSeconds = 0,
weakUpload = [] } = {}) {
let hasChanges = weakUpload.length > 0 || (await this.hasChanges());
if (!hasChanges) {
MirrorLog.debug("No changes detected in both mirror and Places");
return {};
@ -425,7 +428,7 @@ class SyncedBookmarksMirror {
await this.noteObserverChanges(observersToNotify);
MirrorLog.debug("Staging locally changed items for upload");
await this.stageItemsToUpload();
await this.stageItemsToUpload(weakUpload);
MirrorLog.debug("Fetching records for local items to upload");
let changeRecords = await this.fetchLocalChangeRecords();
@ -1472,8 +1475,21 @@ class SyncedBookmarksMirror {
* 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
* 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
// tracked "weakly": if the upload is interrupted or fails, we won't
// 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() {
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() {
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() {
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() {
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() {
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() {
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() {
let buf = await openMirror("value_combo");

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

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

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

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

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

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

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

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

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

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

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

@ -16,31 +16,26 @@
var path = require("path");
var helpers = require("../helpers");
var globals = require("../globals");
var modules = helpers.modulesGlobalData;
const placesOverlayFiles = [
"toolkit/content/globalOverlay.js",
"browser/base/content/utilityOverlay.js",
"browser/components/places/content/controller.js",
"browser/components/places/content/treeView.js"
"browser/base/content/utilityOverlay.js"
];
const extraPlacesDefinitions = [
// Straight definitions.
{name: "Cc", writable: false},
{name: "Ci", writable: false},
{name: "Cr", writable: false},
{name: "Cu", writable: false},
// Via Components.utils / XPCOMUtils.defineLazyModuleGetter (and map to
// Via Components.utils, defineModuleGetter, defineLazyModuleGetters or
// defineLazyScriptGetter (and map to
// single) variable.
{name: "XPCOMUtils", writable: false},
{name: "Task", writable: false},
{name: "PlacesUtils", writable: false},
{name: "PlacesUIUtils", writable: false},
{name: "PlacesTransactions", writable: false}
];
const placesOverlayModules = [
"PlacesUtils.jsm"
{name: "PlacesTransactions", writable: false},
{name: "ForgetAboutSite", writable: false},
{name: "PlacesTreeView", writable: false},
{name: "PlacesInsertionPoint", writable: false},
{name: "PlacesController", writable: false},
{name: "PlacesControllerDragHelper", writable: false}
];
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);
}