зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound. CLOSED TREE
This commit is contained in:
Коммит
f5599eb934
|
@ -748,7 +748,7 @@ var BookmarksEventHandler = {
|
|||
// is middle-clicked or when a non-bookmark item (except for Open in Tabs)
|
||||
// in a bookmarks menupopup is middle-clicked.
|
||||
if (target.localName == "menu" || target.localName == "toolbarbutton")
|
||||
PlacesUIUtils.openMultipleLinksInTabs(target._placesNode, aEvent, aView);
|
||||
PlacesUIUtils.openContainerNodeInTabs(target._placesNode, aEvent, aView);
|
||||
} else if (aEvent.button == 1) {
|
||||
// left-clicks with modifier are already served by onCommand
|
||||
this.onCommand(aEvent);
|
||||
|
|
|
@ -626,38 +626,28 @@ var PlacesUIUtils = {
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads a selected node's or nodes' URLs in tabs,
|
||||
* warning the user when lots of URLs are being opened
|
||||
*
|
||||
* @param {object|array} nodeOrNodes
|
||||
* Contains the node or nodes that we're opening in tabs
|
||||
* @param {event} event
|
||||
* The DOM mouse/key event with modifier keys set that track the
|
||||
* user's preferred destination window or tab.
|
||||
* @param {object} view
|
||||
* The current view that contains the node or nodes selected for
|
||||
* opening
|
||||
*/
|
||||
openMultipleLinksInTabs(nodeOrNodes, event, view) {
|
||||
let window = view.ownerWindow;
|
||||
let urlsToOpen = [];
|
||||
openContainerNodeInTabs:
|
||||
function PUIU_openContainerInTabs(aNode, aEvent, aView) {
|
||||
let window = aView.ownerWindow;
|
||||
|
||||
if (PlacesUtils.nodeIsContainer(nodeOrNodes)) {
|
||||
urlsToOpen = PlacesUtils.getURLsForContainerNode(nodeOrNodes);
|
||||
} else {
|
||||
for (var i = 0; i < nodeOrNodes.length; i++) {
|
||||
// Skip over separators and folders.
|
||||
if (PlacesUtils.nodeIsURI(nodeOrNodes[i])) {
|
||||
urlsToOpen.push({uri: nodeOrNodes[i].uri, isBookmark: PlacesUtils.nodeIsBookmark(nodeOrNodes[i])});
|
||||
}
|
||||
}
|
||||
}
|
||||
let urlsToOpen = PlacesUtils.getURLsForContainerNode(aNode);
|
||||
if (OpenInTabsUtils.confirmOpenInTabs(urlsToOpen.length, window)) {
|
||||
this._openTabset(urlsToOpen, event, window);
|
||||
this._openTabset(urlsToOpen, aEvent, window);
|
||||
}
|
||||
},
|
||||
|
||||
openURINodesInTabs: function PUIU_openURINodesInTabs(aNodes, aEvent, aView) {
|
||||
let window = aView.ownerWindow;
|
||||
|
||||
let urlsToOpen = [];
|
||||
for (var i = 0; i < aNodes.length; i++) {
|
||||
// Skip over separators and folders.
|
||||
if (PlacesUtils.nodeIsURI(aNodes[i]))
|
||||
urlsToOpen.push({uri: aNodes[i].uri, isBookmark: PlacesUtils.nodeIsBookmark(aNodes[i])});
|
||||
}
|
||||
this._openTabset(urlsToOpen, aEvent, window);
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads the node's URL in the appropriate tab or window given the
|
||||
* user's preference specified by modifier keys tracked by a
|
||||
|
@ -966,7 +956,7 @@ var PlacesUIUtils = {
|
|||
} else if (!mouseInGutter && openInTabs &&
|
||||
event.originalTarget.localName == "treechildren") {
|
||||
tbo.view.selection.select(cell.row);
|
||||
this.openMultipleLinksInTabs(tree.selectedNode, event, tree);
|
||||
this.openContainerNodeInTabs(tree.selectedNode, event, tree);
|
||||
} else if (!mouseInGutter && !isContainer &&
|
||||
event.originalTarget.localName == "treechildren") {
|
||||
// Clear all other selection since we're loading a link now. We must
|
||||
|
|
|
@ -646,7 +646,10 @@ PlacesController.prototype = {
|
|||
if (!node && !nodes.length) {
|
||||
node = this._view.result.root;
|
||||
}
|
||||
PlacesUIUtils.openMultipleLinksInTabs(node ? node : nodes, aEvent, this._view);
|
||||
if (node && PlacesUtils.nodeIsContainer(node))
|
||||
PlacesUIUtils.openContainerNodeInTabs(node, aEvent, this._view);
|
||||
else
|
||||
PlacesUIUtils.openURINodesInTabs(nodes, aEvent, this._view);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -353,7 +353,7 @@ var PlacesOrganizer = {
|
|||
// The command execution function will take care of seeing if the
|
||||
// selection is a folder or a different container type, and will
|
||||
// load its contents in tabs.
|
||||
PlacesUIUtils.openMultipleLinksInTabs(node, aEvent, this._places);
|
||||
PlacesUIUtils.openContainerNodeInTabs(node, aEvent, this._places);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1295,7 +1295,7 @@ var ContentTree = {
|
|||
// The command execution function will take care of seeing if the
|
||||
// selection is a folder or a different container type, and will
|
||||
// load its contents in tabs.
|
||||
PlacesUIUtils.openMultipleLinksInTabs(node, aEvent, this.view);
|
||||
PlacesUIUtils.openContainerNodeInTabs(node, aEvent, this.view);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -73,7 +73,6 @@ skip-if = (verify && debug && (os == 'mac' || os == 'linux'))
|
|||
[browser_library_panel_leak.js]
|
||||
[browser_library_search.js]
|
||||
[browser_library_views_liveupdate.js]
|
||||
[browser_library_warnOnOpen.js]
|
||||
[browser_markPageAsFollowedLink.js]
|
||||
[browser_panelview_bookmarks_delete.js]
|
||||
[browser_paste_bookmarks.js]
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Bug 1435562 - Test that browser.tabs.warnOnOpen is respected when
|
||||
* opening multiple items from the Library. */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gLibrary = null;
|
||||
|
||||
add_task(async function setup() {
|
||||
// Temporarily disable history, so we won't record pages navigation.
|
||||
await SpecialPowers.pushPrefEnv({set: [
|
||||
["places.history.enabled", false],
|
||||
]});
|
||||
|
||||
// Open Library window.
|
||||
gLibrary = await promiseLibrary();
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
// We must close "Other Bookmarks" ready for other tests.
|
||||
gLibrary.PlacesOrganizer.selectLeftPaneBuiltIn("UnfiledBookmarks");
|
||||
gLibrary.PlacesOrganizer._places.selectedNode.containerOpen = false;
|
||||
|
||||
await PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
// Close Library window.
|
||||
await promiseLibraryClosed(gLibrary);
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_warnOnOpenFolder() {
|
||||
// Generate a list of links larger than browser.tabs.maxOpenBeforeWarn
|
||||
const MAX_LINKS = 16;
|
||||
let children = [];
|
||||
for (let i = 0; i < MAX_LINKS; i++) {
|
||||
children.push({
|
||||
title: `Folder Target ${i}`,
|
||||
url: `http://example${i}.com`,
|
||||
});
|
||||
}
|
||||
|
||||
// Create a new folder containing our links.
|
||||
await PlacesUtils.bookmarks.insertTree({
|
||||
guid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
children: [{
|
||||
title: "bigFolder",
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
children,
|
||||
}],
|
||||
});
|
||||
info("Pushed test folder into the bookmarks tree");
|
||||
|
||||
// Select unsorted bookmarks root in the left pane.
|
||||
gLibrary.PlacesOrganizer.selectLeftPaneBuiltIn("UnfiledBookmarks");
|
||||
info("Got selection in the Library left pane");
|
||||
|
||||
// Get our bookmark in the right pane.
|
||||
gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
|
||||
info("Got bigFolder in the right pane");
|
||||
|
||||
gLibrary.PlacesOrganizer._places.selectedNode.containerOpen = true;
|
||||
|
||||
// Middle-click on folder (opens all links in folder) and then cancel opening in the dialog
|
||||
let promiseLoaded = BrowserTestUtils.promiseAlertDialog("cancel");
|
||||
let bookmarkedNode = gLibrary.PlacesOrganizer._places.selectedNode.getChild(0);
|
||||
mouseEventOnCell(gLibrary.PlacesOrganizer._places,
|
||||
gLibrary.PlacesOrganizer._places.view.treeIndexForNode(bookmarkedNode),
|
||||
0,
|
||||
{ button: 1 });
|
||||
|
||||
await promiseLoaded;
|
||||
|
||||
Assert.ok(true, "Expected dialog was shown when attempting to open folder with lots of links");
|
||||
|
||||
await PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(async function test_warnOnOpenLinks() {
|
||||
// Generate a list of links larger than browser.tabs.maxOpenBeforeWarn
|
||||
const MAX_LINKS = 16;
|
||||
let children = [];
|
||||
for (let i = 0; i < MAX_LINKS; i++) {
|
||||
children.push({
|
||||
title: `Highlighted Target ${i}`,
|
||||
url: `http://example${i}.com`,
|
||||
});
|
||||
}
|
||||
|
||||
// Insert the links into the tree
|
||||
await PlacesUtils.bookmarks.insertTree({
|
||||
guid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
children,
|
||||
});
|
||||
info("Pushed test folder into the bookmarks tree");
|
||||
|
||||
gLibrary.PlacesOrganizer.selectLeftPaneBuiltIn("BookmarksToolbar");
|
||||
info("Got selection in the Library left pane");
|
||||
|
||||
// Select all the links
|
||||
gLibrary.ContentTree.view.selectAll();
|
||||
|
||||
let placesContext = gLibrary.document.getElementById("placesContext");
|
||||
let promiseContextMenu = BrowserTestUtils.waitForEvent(placesContext, "popupshown");
|
||||
|
||||
// Open up the context menu and select "Open All In Tabs" (the first item in the list)
|
||||
synthesizeClickOnSelectedTreeCell(gLibrary.ContentTree.view, {
|
||||
button: 2,
|
||||
type: "contextmenu",
|
||||
});
|
||||
|
||||
await promiseContextMenu;
|
||||
info("Context menu opened as expected");
|
||||
|
||||
let openTabs = gLibrary.document.getElementById("placesContext_openLinks:tabs");
|
||||
let promiseLoaded = BrowserTestUtils.promiseAlertDialog("cancel");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(openTabs, {}, gLibrary);
|
||||
|
||||
await promiseLoaded;
|
||||
|
||||
Assert.ok(true, "Expected dialog was shown when attempting to open lots of selected links");
|
||||
|
||||
await PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) {
|
||||
var selection = aTree.view.selection;
|
||||
selection.select(aRowIndex);
|
||||
aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
|
||||
var column = aTree.columns[aColumnIndex];
|
||||
|
||||
// get cell coordinates
|
||||
var rect = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
|
||||
|
||||
EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y,
|
||||
aEventDetails, gLibrary);
|
||||
}
|
|
@ -67,7 +67,7 @@ function promiseClipboard(aPopulateClipboardFn, aFlavor) {
|
|||
|
||||
function synthesizeClickOnSelectedTreeCell(aTree, aOptions) {
|
||||
let tbo = aTree.treeBoxObject;
|
||||
if (tbo.view.selection.count < 1)
|
||||
if (tbo.view.selection.count != 1)
|
||||
throw new Error("The test node should be successfully selected");
|
||||
// Get selection rowID.
|
||||
let min = {}, max = {};
|
||||
|
|
|
@ -26,13 +26,14 @@ class ToolboxTab extends Component {
|
|||
this.renderIcon = this.renderIcon.bind(this);
|
||||
}
|
||||
|
||||
renderIcon(definition, isHighlighted) {
|
||||
renderIcon(definition) {
|
||||
const {icon} = definition;
|
||||
if (!icon) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
img({
|
||||
alt: "",
|
||||
src: icon,
|
||||
}),
|
||||
];
|
||||
|
@ -74,7 +75,7 @@ class ToolboxTab extends Component {
|
|||
className: "devtools-tab-line",
|
||||
}
|
||||
),
|
||||
...this.renderIcon(panelDefinition, isHighlighted),
|
||||
...this.renderIcon(panelDefinition),
|
||||
iconOnly ?
|
||||
null :
|
||||
span(
|
||||
|
|
|
@ -15,106 +15,142 @@ const TEST_URI = `
|
|||
color: blue;
|
||||
border-color: #ff000080;
|
||||
}
|
||||
div {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
<body><span>Test</span> cycling color types in the rule view!</body>
|
||||
<body>
|
||||
<span>Test</span>
|
||||
<div>cycling color types in the rule view!</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
add_task(async function() {
|
||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
const {inspector, view} = await openRuleView();
|
||||
const container = getRuleViewProperty(view, "body", "color").valueSpan;
|
||||
await checkColorCycling(container, view);
|
||||
const { inspector, view } = await openRuleView();
|
||||
|
||||
await checkColorCycling(view);
|
||||
await checkAlphaColorCycling(inspector, view);
|
||||
await checkColorCyclingPersist(inspector, view);
|
||||
await checkColorCyclingWithDifferentDefaultType(inspector, view);
|
||||
});
|
||||
|
||||
async function checkColorCycling(container, view) {
|
||||
const valueNode = container.querySelector(".ruleview-color");
|
||||
const win = view.styleWindow;
|
||||
async function checkColorCycling(view) {
|
||||
const { valueSpan } = getRuleViewProperty(view, "body", "color");
|
||||
|
||||
// Hex
|
||||
is(valueNode.textContent, "#f00", "Color displayed as a hex value.");
|
||||
checkColorValue(valueSpan, "#f00", "Color displayed as a hex value, its authored type");
|
||||
|
||||
const tests = [{
|
||||
await runSwatchShiftClickTests(view, valueSpan, [{
|
||||
value: "hsl(0, 100%, 50%)",
|
||||
comment: "Color displayed as an HSL value.",
|
||||
comment: "Color displayed as an HSL value",
|
||||
}, {
|
||||
value: "rgb(255, 0, 0)",
|
||||
comment: "Color displayed as an RGB value.",
|
||||
comment: "Color displayed as an RGB value",
|
||||
}, {
|
||||
value: "red",
|
||||
comment: "Color displayed as a color name.",
|
||||
comment: "Color displayed as a color name",
|
||||
}, {
|
||||
value: "#f00",
|
||||
comment: "Color displayed as an authored value.",
|
||||
comment: "Color displayed as an authored value",
|
||||
}, {
|
||||
value: "hsl(0, 100%, 50%)",
|
||||
comment: "Color displayed as an HSL value again.",
|
||||
}];
|
||||
|
||||
for (const test of tests) {
|
||||
await checkSwatchShiftClick(container, win, test.value, test.comment);
|
||||
}
|
||||
comment: "Color displayed as an HSL value again",
|
||||
}]);
|
||||
}
|
||||
|
||||
async function checkAlphaColorCycling(inspector, view) {
|
||||
await selectNode("span", inspector);
|
||||
const container = getRuleViewProperty(view, "span", "border-color").valueSpan;
|
||||
const valueNode = container.querySelector(".ruleview-color");
|
||||
const win = view.styleWindow;
|
||||
const { valueSpan } = getRuleViewProperty(view, "span", "border-color");
|
||||
|
||||
is(valueNode.textContent, "#ff000080",
|
||||
"Color displayed as an alpha hex value.");
|
||||
checkColorValue(valueSpan, "#ff000080",
|
||||
"Color displayed as an alpha hex value, its authored type");
|
||||
|
||||
const tests = [{
|
||||
await runSwatchShiftClickTests(view, valueSpan, [{
|
||||
value: "hsla(0, 100%, 50%, 0.5)",
|
||||
comment: "Color displayed as an HSLa value.",
|
||||
comment: "Color displayed as an HSLa value",
|
||||
}, {
|
||||
value: "rgba(255, 0, 0, 0.5)",
|
||||
comment: "Color displayed as an RGBa value.",
|
||||
comment: "Color displayed as an RGBa value",
|
||||
}, {
|
||||
value: "#ff000080",
|
||||
comment: "Color displayed as an alpha hex value again.",
|
||||
}];
|
||||
|
||||
for (const test of tests) {
|
||||
await checkSwatchShiftClick(container, win, test.value, test.comment);
|
||||
}
|
||||
comment: "Color displayed as an alpha hex value again",
|
||||
}]);
|
||||
}
|
||||
|
||||
async function checkColorCyclingPersist(inspector, view) {
|
||||
await selectNode("span", inspector);
|
||||
let container = getRuleViewProperty(view, "span", "color").valueSpan;
|
||||
let valueNode = container.querySelector(".ruleview-color");
|
||||
const win = view.styleWindow;
|
||||
let { valueSpan } = getRuleViewProperty(view, "span", "color");
|
||||
|
||||
is(valueNode.textContent, "blue", "Color displayed as a color name.");
|
||||
checkColorValue(valueSpan, "blue", "Color displayed as color name, its authored type");
|
||||
|
||||
await checkSwatchShiftClick(container, win, "#00f",
|
||||
"Color displayed as a hex value.");
|
||||
await checkSwatchShiftClick(view, valueSpan, "#00f", "Color displayed as a hex value");
|
||||
|
||||
// Select the body and reselect the span to see
|
||||
// if the new color unit persisted
|
||||
info("Select the body and reselect the span to see if the new color unit persisted");
|
||||
await selectNode("body", inspector);
|
||||
await selectNode("span", inspector);
|
||||
|
||||
// We have to query for the container and the swatch because
|
||||
// they've been re-generated
|
||||
container = getRuleViewProperty(view, "span", "color").valueSpan;
|
||||
valueNode = container.querySelector(".ruleview-color");
|
||||
is(valueNode.textContent, "#00f",
|
||||
"Color is still displayed as a hex value.");
|
||||
// We have to query for the value span and the swatch again because they've been
|
||||
// re-generated.
|
||||
({ valueSpan } = getRuleViewProperty(view, "span", "color"));
|
||||
checkColorValue(valueSpan, "#00f", "Color is still displayed as a hex value");
|
||||
}
|
||||
|
||||
async function checkSwatchShiftClick(container, win, expectedValue, comment) {
|
||||
const swatch = container.querySelector(".ruleview-colorswatch");
|
||||
const valueNode = container.querySelector(".ruleview-color");
|
||||
async function checkColorCyclingWithDifferentDefaultType(inspector, view) {
|
||||
info("Change the default color type pref to hex");
|
||||
await pushPref("devtools.defaultColorUnit", "hex");
|
||||
|
||||
const onUnitChange = swatch.once("unit-change");
|
||||
EventUtils.synthesizeMouseAtCenter(swatch, {
|
||||
info("Select a new node that would normally have a color with a different type");
|
||||
await selectNode("div", inspector);
|
||||
const { valueSpan } = getRuleViewProperty(view, "div", "color");
|
||||
|
||||
checkColorValue(valueSpan, "#008000",
|
||||
"Color displayed as a hex value, which is the type just selected");
|
||||
|
||||
info("Cycle through color types again");
|
||||
await runSwatchShiftClickTests(view, valueSpan, [{
|
||||
value: "hsl(120, 100%, 25.1%)",
|
||||
comment: "Color displayed as an HSL value",
|
||||
}, {
|
||||
value: "rgb(0, 128, 0)",
|
||||
comment: "Color displayed as an RGB value",
|
||||
}, {
|
||||
value: "green",
|
||||
comment: "Color displayed as a color name",
|
||||
}, {
|
||||
value: "#008000",
|
||||
comment: "Color displayed as an authored value",
|
||||
}, {
|
||||
value: "hsl(120, 100%, 25.1%)",
|
||||
comment: "Color displayed as an HSL value again",
|
||||
}]);
|
||||
}
|
||||
|
||||
async function runSwatchShiftClickTests(view, valueSpan, tests) {
|
||||
for (const { value, comment } of tests) {
|
||||
await checkSwatchShiftClick(view, valueSpan, value, comment);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkSwatchShiftClick(view, valueSpan, expectedValue, comment) {
|
||||
const swatchNode = valueSpan.querySelector(".ruleview-colorswatch");
|
||||
const colorNode = valueSpan.querySelector(".ruleview-color");
|
||||
|
||||
info("Shift-click the color swatch and wait for the color type and ruleview to update");
|
||||
const onRuleViewChanged = view.once("ruleview-changed");
|
||||
const onUnitChange = swatchNode.once("unit-change");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(swatchNode, {
|
||||
type: "mousedown",
|
||||
shiftKey: true,
|
||||
}, win);
|
||||
}, view.styleWindow);
|
||||
|
||||
await onUnitChange;
|
||||
is(valueNode.textContent, expectedValue, comment);
|
||||
await onRuleViewChanged;
|
||||
|
||||
is(colorNode.textContent, expectedValue, comment);
|
||||
}
|
||||
|
||||
function checkColorValue(valueSpan, expectedColorValue, comment) {
|
||||
const colorNode = valueSpan.querySelector(".ruleview-color");
|
||||
is(colorNode.textContent, expectedColorValue, comment);
|
||||
}
|
||||
|
|
|
@ -396,6 +396,8 @@ TextPropertyEditor.prototype = {
|
|||
gridClass: "ruleview-grid",
|
||||
shapeClass: "ruleview-shape",
|
||||
shapeSwatchClass: SHARED_SWATCH_CLASS + " " + SHAPE_SWATCH_CLASS,
|
||||
// Only ask the parser to convert colors to the default color type specified by the
|
||||
// user if the property hasn't been changed yet.
|
||||
defaultColorType: !propDirty,
|
||||
urlClass: "theme-link",
|
||||
fontFamilyClass: FONT_FAMILY_CLASS,
|
||||
|
|
|
@ -315,7 +315,6 @@ add_task(async function() {
|
|||
urlClass: URL_CLASS,
|
||||
bezierClass: CUBIC_BEZIER_CLASS,
|
||||
angleClass: ANGLE_CLASS,
|
||||
defaultColorType: false,
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1226,10 +1226,15 @@ OutputParser.prototype = {
|
|||
container.appendChild(swatch);
|
||||
}
|
||||
|
||||
if (options.defaultColorType) {
|
||||
color = colorObj.toString();
|
||||
container.dataset.color = color;
|
||||
if (!options.defaultColorType) {
|
||||
// If we're not being asked to convert the color to the default color type
|
||||
// specified by the user, then force the CssColor instance to be set to the type
|
||||
// of the current color.
|
||||
// Not having a type means that the default color type will be automatically used.
|
||||
colorObj.colorUnit = colorUtils.classifyColor(color);
|
||||
}
|
||||
color = colorObj.toString();
|
||||
container.dataset.color = color;
|
||||
|
||||
const value = this._createNode("span", {
|
||||
class: options.colorClass,
|
||||
|
|
|
@ -41,7 +41,7 @@ function test_black_box() {
|
|||
/* eslint-disable no-multi-spaces, no-unreachable, no-undef */
|
||||
Cu.evalInSandbox(
|
||||
"" + function doStuff(k) { // line 1
|
||||
throw new Error("wu tang clan ain't nuthin' ta fuck wit"); // line 2
|
||||
throw new Error("error msg"); // line 2
|
||||
k(100); // line 3
|
||||
}, // line 4
|
||||
gDebuggee,
|
||||
|
|
|
@ -3579,6 +3579,9 @@ void nsIDocument::SetHeaderData(nsAtom* aHeaderField, const nsAString& aData) {
|
|||
|
||||
if (aHeaderField == nsGkAtoms::headerContentLanguage) {
|
||||
CopyUTF16toUTF8(aData, mContentLanguage);
|
||||
if (auto* presContext = GetPresContext()) {
|
||||
presContext->ContentLanguageChanged();
|
||||
}
|
||||
}
|
||||
|
||||
if (aHeaderField == nsGkAtoms::headerDefaultStyle) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<hbox>
|
||||
<groupbox orient="horizontal">
|
||||
<caption label="test description file" />
|
||||
<label value=""/><!-- needed, otherwise groupbox fucks up :-( -->
|
||||
<label value=""/><!-- needed, otherwise groupbox is broken :-( -->
|
||||
<textbox id="config" persist="value" readonly="true"/>
|
||||
<button label="browse..." oncommand="view.browseForConfig();" />
|
||||
</groupbox>
|
||||
|
|
|
@ -1 +1 @@
|
|||
7c4162c581978d1a72ed2271a94382290855e227
|
||||
8a6a53883bc6fe9522730e09b916f4023ee10d51
|
||||
|
|
|
@ -1110,10 +1110,10 @@ impl RenderBackend {
|
|||
txn.blob_rasterizer = blob_rasterizer;
|
||||
}
|
||||
|
||||
if !transaction_msg.use_scene_builder_thread && txn.can_skip_scene_builder() {
|
||||
if let Some(rasterizer) = txn.blob_rasterizer.take() {
|
||||
self.resource_cache.set_blob_rasterizer(rasterizer);
|
||||
}
|
||||
if !transaction_msg.use_scene_builder_thread &&
|
||||
txn.can_skip_scene_builder() &&
|
||||
txn.blob_rasterizer.is_none() {
|
||||
|
||||
self.update_document(
|
||||
txn.document_id,
|
||||
replace(&mut txn.resource_updates, Vec::new()),
|
||||
|
|
|
@ -1082,7 +1082,7 @@ impl ResourceCache {
|
|||
&mut self,
|
||||
keys: &[BlobImageKey]
|
||||
) -> (Option<Box<AsyncBlobImageRasterizer>>, Vec<BlobImageParams>) {
|
||||
if self.blob_image_handler.is_none() {
|
||||
if self.blob_image_handler.is_none() || keys.is_empty() {
|
||||
return (None, Vec::new());
|
||||
}
|
||||
|
||||
|
|
|
@ -1720,6 +1720,11 @@ void nsPresContext::CacheAllLangs() {
|
|||
mFontGroupCacheDirty = false;
|
||||
}
|
||||
|
||||
void nsPresContext::ContentLanguageChanged() {
|
||||
mFontGroupCacheDirty = true;
|
||||
PostRebuildAllStyleDataEvent(nsChangeHint(0), eRestyle_ForceDescendants);
|
||||
}
|
||||
|
||||
void nsPresContext::RebuildAllStyleData(nsChangeHint aExtraHint,
|
||||
nsRestyleHint aRestyleHint) {
|
||||
if (!mShell) {
|
||||
|
|
|
@ -273,6 +273,8 @@ class nsPresContext : public nsISupports,
|
|||
void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
|
||||
nsRestyleHint aRestyleHint);
|
||||
|
||||
void ContentLanguageChanged();
|
||||
|
||||
/**
|
||||
* Handle changes in the values of media features (used in media
|
||||
* queries).
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<!doctype html>
|
||||
<meta http-equiv="Content-Language" content="zh-CN">
|
||||
<p style="font-family: sans-serif">Some test in the default font for zh-CN.
|
|
@ -0,0 +1,2 @@
|
|||
<!doctype html>
|
||||
<p lang="zh-CN" style="font-family: sans-serif">Some test in the default font for zh-CN.
|
|
@ -2094,3 +2094,4 @@ test-pref(layout.css.visited_links_enabled,false) == 1488155.html 1488155-ref.ht
|
|||
== 1492660-1.html 1492660-1-ref.html
|
||||
pref(layout.css.supports-selector.enabled,true) == 1499386.html 1499386-ref.html
|
||||
pref(layout.css.supports-selector.enabled,false) != 1499386.html 1499386-ref.html
|
||||
== 1511570.html 1511570-ref.html
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace {
|
|||
// inline, and we link this file without libxul in some cases (e.g. for our test
|
||||
// setup). So we can't use ErrorResult or IgnoredErrorResult because those call
|
||||
// SuppressException... And we can't use FastErrorResult because we can't
|
||||
// include BindingUtils.h, because our linking is completely fucked up. Use
|
||||
// include BindingUtils.h, because our linking is completely broken. Use
|
||||
// BaseErrorResult directly. Please do not let me see _anyone_ doing this
|
||||
// without really careful review from someone who knows what they are doing.
|
||||
class JSErrorResult : public binding_danger::TErrorResult<
|
||||
|
|
|
@ -2831,11 +2831,19 @@ class StaticAnalysis(MachCommandBase):
|
|||
return 0
|
||||
|
||||
def _run_clang_format_path(self, clang_format, show, paths):
|
||||
import shutil
|
||||
|
||||
# Run clang-format on files or directories directly
|
||||
from subprocess import check_output, CalledProcessError
|
||||
|
||||
args = [clang_format, "-i"]
|
||||
|
||||
if show:
|
||||
# We just want to show the diff, we create the directory to copy it
|
||||
tmpdir = os.path.join(self.topobjdir, 'tmp')
|
||||
if not os.path.exists(tmpdir):
|
||||
os.makedirs(tmpdir)
|
||||
|
||||
path_list = self._generate_path_list(paths)
|
||||
|
||||
if path_list == []:
|
||||
|
@ -2844,9 +2852,24 @@ class StaticAnalysis(MachCommandBase):
|
|||
print("Processing %d file(s)..." % len(path_list))
|
||||
|
||||
batchsize = 200
|
||||
if show:
|
||||
batchsize = 1
|
||||
|
||||
for i in range(0, len(path_list), batchsize):
|
||||
l = path_list[i: (i + batchsize)]
|
||||
if show:
|
||||
# Copy the files into a temp directory
|
||||
# and run clang-format on the temp directory
|
||||
# and show the diff
|
||||
original_path = l[0]
|
||||
local_path = original_path.replace(self.topsrcdir, ".")
|
||||
target_file = os.path.join(tmpdir, local_path)
|
||||
faketmpdir = os.path.dirname(target_file)
|
||||
if not os.path.isdir(faketmpdir):
|
||||
os.makedirs(faketmpdir)
|
||||
shutil.copy(l[0], faketmpdir)
|
||||
l[0] = target_file
|
||||
|
||||
# Run clang-format on the list
|
||||
try:
|
||||
check_output(args + l)
|
||||
|
@ -2855,20 +2878,19 @@ class StaticAnalysis(MachCommandBase):
|
|||
print("clang-format: An error occured while running clang-format.")
|
||||
return e.returncode
|
||||
|
||||
if show:
|
||||
# show the diff
|
||||
diff_command = ["diff", "-u", original_path, target_file]
|
||||
try:
|
||||
output = check_output(diff_command)
|
||||
except CalledProcessError as e:
|
||||
# diff -u returns 0 when no change
|
||||
# here, we expect changes. if we are here, this means that
|
||||
# there is a diff to show
|
||||
if e.output:
|
||||
print(e.output)
|
||||
if show:
|
||||
# show the diff
|
||||
if self.repository.name == 'hg':
|
||||
diff_command = ["hg", "diff"] + paths
|
||||
else:
|
||||
assert self.repository.name == 'git'
|
||||
diff_command = ["git", "diff"] + paths
|
||||
try:
|
||||
output = check_output(diff_command)
|
||||
print(output)
|
||||
except CalledProcessError as e:
|
||||
# Something wrong happend
|
||||
print("clang-format: Unable to run the diff command.")
|
||||
return e.returncode
|
||||
shutil.rmtree(tmpdir)
|
||||
return 0
|
||||
|
||||
@CommandProvider
|
||||
|
|
|
@ -147,57 +147,63 @@ void moz_container_init(MozContainer *container) {
|
|||
container->surface = nullptr;
|
||||
container->subsurface = nullptr;
|
||||
container->eglwindow = nullptr;
|
||||
container->frame_callback_handler = nullptr;
|
||||
container->ready_to_draw = false;
|
||||
container->surface_needs_clear = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MOZ_WAYLAND)
|
||||
static void moz_on_frame_clock_after_paint(GdkFrameClock *clock,
|
||||
MozContainer *container) {
|
||||
container->ready_to_draw = true;
|
||||
g_signal_handler_disconnect(clock,
|
||||
container->frame_clock_after_paint_handler);
|
||||
container->frame_clock_after_paint_handler = 0;
|
||||
}
|
||||
|
||||
static void moz_container_map_wayland(MozContainer *container) {
|
||||
MOZ_ASSERT(!container->ready_to_draw, "MozContainer is already mapped.");
|
||||
MOZ_ASSERT(!container->frame_clock_after_paint_handler,
|
||||
"Repeated gdk_window_get_frame_clock() request?");
|
||||
|
||||
GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container));
|
||||
if (GDK_IS_X11_DISPLAY(display)) return;
|
||||
|
||||
container->surface_needs_clear = true;
|
||||
|
||||
static auto sGdkWindowGetFrameClock = (GdkFrameClock * (*)(GdkWindow *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_window_get_frame_clock");
|
||||
static wl_surface *moz_container_get_gtk_container_surface(
|
||||
MozContainer *container) {
|
||||
static auto sGdkWaylandWindowGetWlSurface = (wl_surface * (*)(GdkWindow *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_window_get_wl_surface");
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||
GdkFrameClock *clock = sGdkWindowGetFrameClock(window);
|
||||
container->frame_clock_after_paint_handler = g_signal_connect_after(
|
||||
clock, "after-paint", G_CALLBACK(moz_on_frame_clock_after_paint),
|
||||
container);
|
||||
return sGdkWaylandWindowGetWlSurface(window);
|
||||
}
|
||||
|
||||
static void frame_callback_handler(void *data, struct wl_callback *callback,
|
||||
uint32_t time) {
|
||||
MozContainer *container = MOZ_CONTAINER(data);
|
||||
g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
|
||||
container->ready_to_draw = true;
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener frame_listener = {
|
||||
frame_callback_handler};
|
||||
|
||||
static void moz_container_map_wayland(MozContainer *container) {
|
||||
container->surface_needs_clear = true;
|
||||
container->ready_to_draw = false;
|
||||
|
||||
static wl_surface *gtk_container_surface =
|
||||
moz_container_get_gtk_container_surface(container);
|
||||
container->frame_callback_handler = wl_surface_frame(gtk_container_surface);
|
||||
wl_callback_add_listener(container->frame_callback_handler, &frame_listener,
|
||||
container);
|
||||
}
|
||||
|
||||
static void moz_container_unmap_wayland(MozContainer *container) {
|
||||
g_clear_pointer(&container->eglwindow, wl_egl_window_destroy);
|
||||
g_clear_pointer(&container->subsurface, wl_subsurface_destroy);
|
||||
g_clear_pointer(&container->surface, wl_surface_destroy);
|
||||
g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
|
||||
|
||||
if (container->frame_clock_after_paint_handler) {
|
||||
static auto sGdkWindowGetFrameClock = (GdkFrameClock * (*)(GdkWindow *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_window_get_frame_clock");
|
||||
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||
GdkFrameClock *clock = sGdkWindowGetFrameClock(window);
|
||||
|
||||
g_signal_handler_disconnect(clock,
|
||||
container->frame_clock_after_paint_handler);
|
||||
container->frame_clock_after_paint_handler = 0;
|
||||
}
|
||||
container->ready_to_draw = false;
|
||||
}
|
||||
|
||||
static gint moz_container_get_scale(MozContainer *container) {
|
||||
static auto sGdkWindowGetScaleFactorPtr = (gint(*)(GdkWindow *))dlsym(
|
||||
RTLD_DEFAULT, "gdk_window_get_scale_factor");
|
||||
|
||||
if (sGdkWindowGetScaleFactorPtr) {
|
||||
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||
return (*sGdkWindowGetScaleFactorPtr)(window);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void moz_container_map(GtkWidget *widget) {
|
||||
|
@ -223,7 +229,9 @@ void moz_container_map(GtkWidget *widget) {
|
|||
if (gtk_widget_get_has_window(widget)) {
|
||||
gdk_window_show(gtk_widget_get_window(widget));
|
||||
#if defined(MOZ_WAYLAND)
|
||||
moz_container_map_wayland(MOZ_CONTAINER(widget));
|
||||
if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
|
||||
moz_container_map_wayland(MOZ_CONTAINER(widget));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +244,9 @@ void moz_container_unmap(GtkWidget *widget) {
|
|||
if (gtk_widget_get_has_window(widget)) {
|
||||
gdk_window_hide(gtk_widget_get_window(widget));
|
||||
#if defined(MOZ_WAYLAND)
|
||||
moz_container_unmap_wayland(MOZ_CONTAINER(widget));
|
||||
if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
|
||||
moz_container_unmap_wayland(MOZ_CONTAINER(widget));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -324,8 +334,10 @@ void moz_container_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
|
|||
wl_subsurface_set_position(container->subsurface, x, y);
|
||||
}
|
||||
if (container->eglwindow) {
|
||||
wl_egl_window_resize(container->eglwindow, allocation->width,
|
||||
allocation->height, 0, 0);
|
||||
gint scale = moz_container_get_scale(container);
|
||||
wl_egl_window_resize(container->eglwindow,
|
||||
allocation->width * scale,
|
||||
allocation->height * scale, 0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -429,34 +441,27 @@ static void moz_container_add(GtkContainer *container, GtkWidget *widget) {
|
|||
|
||||
#ifdef MOZ_WAYLAND
|
||||
struct wl_surface *moz_container_get_wl_surface(MozContainer *container) {
|
||||
// We're not mapped yet.
|
||||
if (!container->ready_to_draw) return nullptr;
|
||||
|
||||
if (!container->surface) {
|
||||
if (!container->ready_to_draw) {
|
||||
return nullptr;
|
||||
}
|
||||
GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container));
|
||||
|
||||
// Available as of GTK 3.8+
|
||||
static auto sGdkWaylandDisplayGetWlCompositor =
|
||||
(wl_compositor * (*)(GdkDisplay *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_compositor");
|
||||
static auto sGdkWaylandWindowGetWlSurface = (wl_surface * (*)(GdkWindow *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_window_get_wl_surface");
|
||||
static auto sGdkWindowGetScaleFactorPtr = (gint(*)(GdkWindow *))dlsym(
|
||||
RTLD_DEFAULT, "gdk_window_get_scale_factor");
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||
GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container));
|
||||
|
||||
struct wl_compositor *compositor =
|
||||
sGdkWaylandDisplayGetWlCompositor(display);
|
||||
container->surface = wl_compositor_create_surface(compositor);
|
||||
|
||||
wl_surface *parent_surface = sGdkWaylandWindowGetWlSurface(window);
|
||||
|
||||
nsWaylandDisplay *waylandDisplay = WaylandDisplayGet(display);
|
||||
wl_subcompositor *subcompositor = waylandDisplay->GetSubcompositor();
|
||||
container->subsurface = wl_subcompositor_get_subsurface(
|
||||
subcompositor, container->surface, parent_surface);
|
||||
waylandDisplay->GetSubcompositor(), container->surface,
|
||||
moz_container_get_gtk_container_surface(container));
|
||||
WaylandDisplayRelease(waylandDisplay);
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||
gint x, y;
|
||||
gdk_window_get_position(window, &x, &y);
|
||||
wl_subsurface_set_position(container->subsurface, x, y);
|
||||
|
@ -468,12 +473,8 @@ struct wl_surface *moz_container_get_wl_surface(MozContainer *container) {
|
|||
wl_surface_set_input_region(container->surface, region);
|
||||
wl_region_destroy(region);
|
||||
|
||||
container->surface_needs_clear = true;
|
||||
|
||||
if (sGdkWindowGetScaleFactorPtr) {
|
||||
gint scaleFactor = (*sGdkWindowGetScaleFactorPtr)(window);
|
||||
wl_surface_set_buffer_scale(container->surface, scaleFactor);
|
||||
}
|
||||
wl_surface_set_buffer_scale(container->surface,
|
||||
moz_container_get_scale(container));
|
||||
}
|
||||
|
||||
return container->surface;
|
||||
|
@ -487,8 +488,10 @@ struct wl_egl_window *moz_container_get_wl_egl_window(MozContainer *container) {
|
|||
}
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||
gint scale = moz_container_get_scale(container);
|
||||
container->eglwindow = wl_egl_window_create(
|
||||
surface, gdk_window_get_width(window), gdk_window_get_height(window));
|
||||
surface, gdk_window_get_width(window) * scale,
|
||||
gdk_window_get_height(window) * scale);
|
||||
}
|
||||
return container->eglwindow;
|
||||
}
|
||||
|
|
|
@ -75,9 +75,9 @@ struct _MozContainer {
|
|||
struct wl_surface *surface;
|
||||
struct wl_subsurface *subsurface;
|
||||
struct wl_egl_window *eglwindow;
|
||||
struct wl_callback *frame_callback_handler;
|
||||
gboolean surface_needs_clear;
|
||||
gboolean ready_to_draw;
|
||||
gulong frame_clock_after_paint_handler;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -93,6 +93,7 @@ void moz_container_put(MozContainer *container, GtkWidget *child_widget, gint x,
|
|||
#ifdef MOZ_WAYLAND
|
||||
struct wl_surface *moz_container_get_wl_surface(MozContainer *container);
|
||||
struct wl_egl_window *moz_container_get_wl_egl_window(MozContainer *container);
|
||||
|
||||
gboolean moz_container_has_wl_egl_window(MozContainer *container);
|
||||
gboolean moz_container_surface_needs_clear(MozContainer *container);
|
||||
#endif
|
||||
|
|
|
@ -1870,13 +1870,6 @@ gboolean nsWindow::OnExposeEvent(cairo_t *cr) {
|
|||
// Windows that are not visible will be painted after they become visible.
|
||||
if (!mGdkWindow || mIsFullyObscured || !mHasMappedToplevel) return FALSE;
|
||||
|
||||
#ifdef MOZ_WAYLAND
|
||||
// Window does not have visible MozContainer/wl_surface yet.
|
||||
if (!mIsX11Display && (!mContainer || !mContainer->ready_to_draw)) {
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsIWidgetListener *listener = GetListener();
|
||||
if (!listener) return FALSE;
|
||||
|
||||
|
@ -3631,10 +3624,6 @@ nsresult nsWindow::Create(nsIWidget *aParent, nsNativeWidget aNativeParent,
|
|||
gdk_window_set_decorations(mGdkWindow, (GdkWMDecoration)wmd);
|
||||
}
|
||||
|
||||
if (!mIsX11Display) {
|
||||
gtk_widget_set_app_paintable(mShell, TRUE);
|
||||
}
|
||||
|
||||
// If the popup ignores mouse events, set an empty input shape.
|
||||
if (aInitData->mMouseTransparent) {
|
||||
cairo_rectangle_int_t rect = {0, 0, 0, 0};
|
||||
|
|
Загрузка…
Ссылка в новой задаче