зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to inbound. a=merge on a CLOSED TREE
This commit is contained in:
Коммит
5d28a4b342
|
@ -120,15 +120,13 @@
|
|||
|
||||
<broadcasterset id="mainBroadcasterSet">
|
||||
<broadcaster id="viewBookmarksSidebar" autoCheck="false" label="&bookmarksButton.label;"
|
||||
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/bookmarks/bookmarksPanel.xul"
|
||||
type="checkbox" group="sidebar"
|
||||
sidebarurl="chrome://browser/content/places/bookmarksSidebar.xul"
|
||||
oncommand="SidebarUI.toggle('viewBookmarksSidebar');"/>
|
||||
|
||||
<!-- for both places and non-places, the sidebar lives at
|
||||
chrome://browser/content/history/history-panel.xul so there are no
|
||||
problems when switching between versions -->
|
||||
<broadcaster id="viewHistorySidebar" autoCheck="false" sidebartitle="&historyButton.label;"
|
||||
type="checkbox" group="sidebar"
|
||||
sidebarurl="chrome://browser/content/history/history-panel.xul"
|
||||
sidebarurl="chrome://browser/content/places/historySidebar.xul"
|
||||
oncommand="SidebarUI.toggle('viewHistorySidebar');"/>
|
||||
|
||||
<broadcaster id="viewWebPanelsSidebar" autoCheck="false"
|
||||
|
|
|
@ -1281,7 +1281,7 @@ var gBrowserInit = {
|
|||
|
||||
this._setInitialFocus();
|
||||
|
||||
gBrowser.tabContainer.updateVisibility();
|
||||
window.TabBarVisibility.update();
|
||||
TabsInTitlebar.onDOMContentLoaded();
|
||||
},
|
||||
|
||||
|
|
|
@ -854,7 +854,7 @@ window._gBrowser = {
|
|||
docTitle = tab.getAttribute("label").replace(/\0/g, "");
|
||||
}
|
||||
|
||||
if (!docTitle || docTitle == this.tabContainer.emptyTabTitle)
|
||||
if (!docTitle)
|
||||
docTitle = docElement.getAttribute("titledefault");
|
||||
|
||||
var modifier = docElement.getAttribute("titlemodifier");
|
||||
|
@ -1775,7 +1775,6 @@ window._gBrowser = {
|
|||
|
||||
browser.loadURI(BROWSER_NEW_TAB_URL);
|
||||
browser.docShellIsActive = false;
|
||||
browser.renderLayers = true;
|
||||
browser._urlbarFocused = true;
|
||||
|
||||
// Make sure the preloaded browser is loaded with desired zoom level
|
||||
|
@ -2284,7 +2283,7 @@ window._gBrowser = {
|
|||
t._tPos = position;
|
||||
this.tabContainer._setPositionalAttributes();
|
||||
|
||||
this.tabContainer.updateVisibility();
|
||||
TabBarVisibility.update();
|
||||
|
||||
// If we don't have a preferred remote type, and we have a remote
|
||||
// opener, use the opener's remote type.
|
||||
|
@ -2758,7 +2757,7 @@ window._gBrowser = {
|
|||
if (newTab)
|
||||
this.addTab(BROWSER_NEW_TAB_URL, { skipAnimation: true });
|
||||
else
|
||||
this.tabContainer.updateVisibility();
|
||||
TabBarVisibility.update();
|
||||
|
||||
// We're committed to closing the tab now.
|
||||
// Dispatch a notification.
|
||||
|
@ -4705,3 +4704,28 @@ var StatusPanel = {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
var TabBarVisibility = {
|
||||
_initialUpdateDone: false,
|
||||
|
||||
update() {
|
||||
let toolbar = document.getElementById("TabsToolbar");
|
||||
let collapse = false;
|
||||
if (gBrowser.tabs.length - gBrowser._removingTabs.length == 1) {
|
||||
collapse = !window.toolbar.visible;
|
||||
}
|
||||
|
||||
if (collapse == toolbar.collapsed && this._initialUpdateDone) {
|
||||
return;
|
||||
}
|
||||
this._initialUpdateDone = true;
|
||||
|
||||
toolbar.collapsed = collapse;
|
||||
|
||||
document.getElementById("menu_closeWindow").hidden = collapse;
|
||||
document.getElementById("menu_close").setAttribute("label",
|
||||
gTabBrowserBundle.GetStringFromName(collapse ? "tabs.close" : "tabs.closeTab"));
|
||||
|
||||
TabsInTitlebar.allowedBy("tabs-visible", !collapse);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -369,50 +369,6 @@
|
|||
<field name="_dragOverDelay">350</field>
|
||||
<field name="_dragTime">0</field>
|
||||
|
||||
<field name="_container" readonly="true"><![CDATA[
|
||||
this.parentNode && this.parentNode.localName == "toolbar" ? this.parentNode : this;
|
||||
]]></field>
|
||||
|
||||
<field name="_propagatedVisibilityOnce">false</field>
|
||||
|
||||
<property name="visible"
|
||||
onget="return !this._container.collapsed;">
|
||||
<setter><![CDATA[
|
||||
if (val == this.visible &&
|
||||
this._propagatedVisibilityOnce)
|
||||
return val;
|
||||
|
||||
this._container.collapsed = !val;
|
||||
|
||||
this._propagateVisibility();
|
||||
this._propagatedVisibilityOnce = true;
|
||||
|
||||
return val;
|
||||
]]></setter>
|
||||
</property>
|
||||
|
||||
<method name="_propagateVisibility">
|
||||
<body><![CDATA[
|
||||
let visible = this.visible;
|
||||
|
||||
document.getElementById("menu_closeWindow").hidden = !visible;
|
||||
document.getElementById("menu_close").setAttribute("label",
|
||||
gTabBrowserBundle.GetStringFromName(visible ? "tabs.closeTab" : "tabs.close"));
|
||||
|
||||
TabsInTitlebar.allowedBy("tabs-visible", visible);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="updateVisibility">
|
||||
<body><![CDATA[
|
||||
if (this.childNodes.length - gBrowser._removingTabs.length == 1) {
|
||||
this.visible = window.toolbar.visible;
|
||||
} else {
|
||||
this.visible = true;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<field name="_closeButtonsUpdatePending">false</field>
|
||||
<method name="_updateCloseButtons">
|
||||
<body><![CDATA[
|
||||
|
|
|
@ -10,13 +10,14 @@ ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|||
ChromeUtils.import("resource://gre/modules/Timer.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
OpenInTabsUtils: "resource:///modules/OpenInTabsUtils.jsm",
|
||||
PlacesTransactions: "resource://gre/modules/PlacesTransactions.jsm",
|
||||
PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
|
||||
PluralForm: "resource://gre/modules/PluralForm.jsm",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
|
||||
RecentWindow: "resource:///modules/RecentWindow.jsm",
|
||||
PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
|
||||
PlacesTransactions: "resource://gre/modules/PlacesTransactions.jsm",
|
||||
RecentWindow: "resource:///modules/RecentWindow.jsm",
|
||||
Weave: "resource://services-sync/main.js",
|
||||
});
|
||||
|
||||
|
@ -1031,6 +1032,94 @@ var PlacesUIUtils = {
|
|||
|
||||
return guidsToSelect;
|
||||
},
|
||||
|
||||
onSidebarTreeClick(event) {
|
||||
// right-clicks are not handled here
|
||||
if (event.button == 2)
|
||||
return;
|
||||
|
||||
let tree = event.target.parentNode;
|
||||
let tbo = tree.treeBoxObject;
|
||||
let cell = tbo.getCellAt(event.clientX, event.clientY);
|
||||
if (cell.row == -1 || cell.childElt == "twisty")
|
||||
return;
|
||||
|
||||
// getCoordsForCellItem returns the x coordinate in logical coordinates
|
||||
// (i.e., starting from the left and right sides in LTR and RTL modes,
|
||||
// respectively.) Therefore, we make sure to exclude the blank area
|
||||
// before the tree item icon (that is, to the left or right of it in
|
||||
// LTR and RTL modes, respectively) from the click target area.
|
||||
let win = tree.ownerGlobal;
|
||||
let rect = tbo.getCoordsForCellItem(cell.row, cell.col, "image");
|
||||
let isRTL = win.getComputedStyle(tree).direction == "rtl";
|
||||
let mouseInGutter = isRTL ? event.clientX > rect.x
|
||||
: event.clientX < rect.x;
|
||||
|
||||
let metaKey = AppConstants.platform === "macosx" ? event.metaKey
|
||||
: event.ctrlKey;
|
||||
let modifKey = metaKey || event.shiftKey;
|
||||
let isContainer = tbo.view.isContainer(cell.row);
|
||||
let openInTabs = isContainer &&
|
||||
(event.button == 1 || (event.button == 0 && modifKey)) &&
|
||||
PlacesUtils.hasChildURIs(tree.view.nodeForTreeIndex(cell.row));
|
||||
|
||||
if (event.button == 0 && isContainer && !openInTabs) {
|
||||
tbo.view.toggleOpenState(cell.row);
|
||||
} else if (!mouseInGutter && openInTabs &&
|
||||
event.originalTarget.localName == "treechildren") {
|
||||
tbo.view.selection.select(cell.row);
|
||||
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
|
||||
// do this *before* attempting to load the link since openURL uses
|
||||
// selection as an indication of which link to load.
|
||||
tbo.view.selection.select(cell.row);
|
||||
this.openNodeWithEvent(tree.selectedNode, event);
|
||||
}
|
||||
},
|
||||
|
||||
onSidebarTreeKeyPress(event) {
|
||||
let node = event.target.selectedNode;
|
||||
if (node) {
|
||||
if (event.keyCode == KeyEvent.DOM_VK_RETURN)
|
||||
this.openNodeWithEvent(node, event);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The following function displays the URL of a node that is being
|
||||
* hovered over.
|
||||
*/
|
||||
onSidebarTreeMouseMove(event) {
|
||||
let treechildren = event.target;
|
||||
if (treechildren.localName != "treechildren")
|
||||
return;
|
||||
|
||||
let tree = treechildren.parentNode;
|
||||
let cell = tree.treeBoxObject.getCellAt(event.clientX, event.clientY);
|
||||
|
||||
// cell.row is -1 when the mouse is hovering an empty area within the tree.
|
||||
// To avoid showing a URL from a previously hovered node for a currently
|
||||
// hovered non-url node, we must clear the moused-over URL in these cases.
|
||||
if (cell.row != -1) {
|
||||
let node = tree.view.nodeForTreeIndex(cell.row);
|
||||
if (PlacesUtils.nodeIsURI(node)) {
|
||||
this.setMouseoverURL(node.uri, tree.ownerGlobal);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.setMouseoverURL("", tree.ownerGlobal);
|
||||
},
|
||||
|
||||
setMouseoverURL(url, win) {
|
||||
// When the browser window is closed with an open sidebar, the sidebar
|
||||
// unload event happens after the browser's one. In this case
|
||||
// top.XULBrowserWindow has been nullified already.
|
||||
if (win.top.XULBrowserWindow) {
|
||||
win.top.XULBrowserWindow.setOverLink(url, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// These are lazy getters to avoid importing PlacesUtils immediately.
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
/* import-globals-from ../../../../toolkit/components/places/PlacesUtils.jsm */
|
||||
|
||||
function init() {
|
||||
let uidensity = window.top.document.documentElement.getAttribute("uidensity");
|
||||
if (uidensity) {
|
||||
document.documentElement.setAttribute("uidensity", uidensity);
|
||||
}
|
||||
|
||||
document.getElementById("bookmarks-view").place =
|
||||
"place:type=" + Ci.nsINavHistoryQueryOptions.RESULTS_AS_ROOTS_QUERY;
|
||||
}
|
|
@ -1,29 +1,27 @@
|
|||
<?xml version="1.0"?> <!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
|
||||
<?xml version="1.0"?> <!-- -*- Mode: xml; indent-tabs-mode: nil; -*- -->
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
|
||||
|
||||
<!DOCTYPE page [
|
||||
<!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
|
||||
%placesDTD;
|
||||
<!ENTITY % editMenuOverlayDTD SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
|
||||
%editMenuOverlayDTD;
|
||||
<!ENTITY % editMenuDTD SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
|
||||
%editMenuDTD;
|
||||
]>
|
||||
|
||||
<page id="bookmarksPanel"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="init();"
|
||||
onunload="SidebarUtils.setMouseoverURL('');">
|
||||
onunload="PlacesUIUtils.setMouseoverURL('', window);">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/bookmarks/sidebarUtils.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/bookmarks/bookmarksPanel.js"/>
|
||||
src="chrome://browser/content/places/bookmarksSidebar.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://global/content/globalOverlay.js"/>
|
||||
<script type="application/javascript"
|
||||
|
@ -56,18 +54,20 @@
|
|||
oncommand="searchBookmarks(this.value);"/>
|
||||
</hbox>
|
||||
|
||||
<tree id="bookmarks-view" class="sidebar-placesTree" type="places"
|
||||
<tree id="bookmarks-view"
|
||||
class="sidebar-placesTree"
|
||||
type="places"
|
||||
flex="1"
|
||||
hidecolumnpicker="true"
|
||||
context="placesContext"
|
||||
onkeypress="SidebarUtils.handleTreeKeyPress(event);"
|
||||
onclick="SidebarUtils.handleTreeClick(this, event, true);"
|
||||
onmousemove="SidebarUtils.handleTreeMouseMove(event);"
|
||||
onmouseout="SidebarUtils.setMouseoverURL('');">
|
||||
onkeypress="PlacesUIUtils.onSidebarTreeKeyPress(event);"
|
||||
onclick="PlacesUIUtils.onSidebarTreeClick(event);"
|
||||
onmousemove="PlacesUIUtils.onSidebarTreeMouseMove(event);"
|
||||
onmouseout="PlacesUIUtils.setMouseoverURL('', window);">
|
||||
<treecols>
|
||||
<treecol id="title" flex="1" primary="true" hideheader="true"/>
|
||||
</treecols>
|
||||
<treechildren id="bookmarks-view-children" view="bookmarks-view"
|
||||
<treechildren view="bookmarks-view"
|
||||
class="sidebar-placesTreechildren" flex="1" tooltip="bhTooltip"/>
|
||||
</tree>
|
||||
</page>
|
|
@ -13,6 +13,11 @@ var gHistoryGrouping = "";
|
|||
var gSearching = false;
|
||||
|
||||
function HistorySidebarInit() {
|
||||
let uidensity = window.top.document.documentElement.getAttribute("uidensity");
|
||||
if (uidensity) {
|
||||
document.documentElement.setAttribute("uidensity", uidensity);
|
||||
}
|
||||
|
||||
gHistoryTree = document.getElementById("historyTree");
|
||||
gSearchBox = document.getElementById("search-box");
|
||||
|
||||
|
@ -84,7 +89,7 @@ function searchHistory(aInput) {
|
|||
this.TelemetryStopwatch.start("HISTORY_LASTVISITED_TREE_QUERY_TIME_MS");
|
||||
|
||||
// call load() on the tree manually
|
||||
// instead of setting the place attribute in history-panel.xul
|
||||
// instead of setting the place attribute in historySidebar.xul
|
||||
// otherwise, we will end up calling load() twice
|
||||
gHistoryTree.load(query, options);
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
<?xml version="1.0"?> <!-- -*- Mode: xml; indent-tabs-mode: nil; -*- -->
|
||||
|
||||
# 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/.
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
@ -15,18 +14,14 @@
|
|||
%editMenuDTD;
|
||||
]>
|
||||
|
||||
<!-- we need to keep id="history-panel" for upgrade and switching
|
||||
between versions of the browser -->
|
||||
|
||||
<page id="history-panel" orient="vertical"
|
||||
<page id="history-panel"
|
||||
orient="vertical"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="HistorySidebarInit();"
|
||||
onunload="SidebarUtils.setMouseoverURL('');">
|
||||
onunload="PlacesUIUtils.setMouseoverURL('', window);">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/bookmarks/sidebarUtils.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/places/history-panel.js"/>
|
||||
src="chrome://browser/content/places/historySidebar.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://global/content/globalOverlay.js"/>
|
||||
<script type="application/javascript"
|
||||
|
@ -96,12 +91,12 @@
|
|||
class="sidebar-placesTree"
|
||||
flex="1"
|
||||
type="places"
|
||||
context="placesContext"
|
||||
hidecolumnpicker="true"
|
||||
onkeypress="SidebarUtils.handleTreeKeyPress(event);"
|
||||
onclick="SidebarUtils.handleTreeClick(this, event, true);"
|
||||
onmousemove="SidebarUtils.handleTreeMouseMove(event);"
|
||||
onmouseout="SidebarUtils.setMouseoverURL('');">
|
||||
context="placesContext"
|
||||
onkeypress="PlacesUIUtils.onSidebarTreeKeyPress(event);"
|
||||
onclick="PlacesUIUtils.onSidebarTreeClick(event);"
|
||||
onmousemove="PlacesUIUtils.onSidebarTreeMouseMove(event);"
|
||||
onmouseout="PlacesUIUtils.setMouseoverURL('', window);">
|
||||
<treecols>
|
||||
<treecol id="title" flex="1" primary="true" hideheader="true"/>
|
||||
</treecols>
|
|
@ -1,7 +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/. */
|
||||
|
||||
#searchFilter {
|
||||
width: 23em;
|
||||
}
|
|
@ -35,3 +35,7 @@ menupopup[placespopup="true"] {
|
|||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
}
|
||||
|
||||
#searchFilter {
|
||||
max-width: 23em;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/places/organizer.css"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
|
||||
|
@ -353,6 +352,7 @@
|
|||
<spacer id="libraryToolbarSpacer" flex="1"/>
|
||||
|
||||
<textbox id="searchFilter"
|
||||
flex="1"
|
||||
type="search"
|
||||
aria-controls="placeContent"
|
||||
oncommand="PlacesSearchBox.search(this.value);"
|
||||
|
|
|
@ -1,108 +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/. */
|
||||
|
||||
/* import-globals-from ../PlacesUIUtils.jsm */
|
||||
/* import-globals-from ../../../../toolkit/components/places/PlacesUtils.jsm */
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
|
||||
let uidensity = window.top.document.documentElement.getAttribute("uidensity");
|
||||
if (uidensity) {
|
||||
document.documentElement.setAttribute("uidensity", uidensity);
|
||||
}
|
||||
|
||||
var SidebarUtils = {
|
||||
handleTreeClick: function SU_handleTreeClick(aTree, aEvent, aGutterSelect) {
|
||||
// right-clicks are not handled here
|
||||
if (aEvent.button == 2)
|
||||
return;
|
||||
|
||||
var tbo = aTree.treeBoxObject;
|
||||
var cell = tbo.getCellAt(aEvent.clientX, aEvent.clientY);
|
||||
|
||||
if (cell.row == -1 || cell.childElt == "twisty")
|
||||
return;
|
||||
|
||||
var mouseInGutter = false;
|
||||
if (aGutterSelect) {
|
||||
var rect = tbo.getCoordsForCellItem(cell.row, cell.col, "image");
|
||||
// getCoordsForCellItem returns the x coordinate in logical coordinates
|
||||
// (i.e., starting from the left and right sides in LTR and RTL modes,
|
||||
// respectively.) Therefore, we make sure to exclude the blank area
|
||||
// before the tree item icon (that is, to the left or right of it in
|
||||
// LTR and RTL modes, respectively) from the click target area.
|
||||
var isRTL = window.getComputedStyle(aTree).direction == "rtl";
|
||||
if (isRTL)
|
||||
mouseInGutter = aEvent.clientX > rect.x;
|
||||
else
|
||||
mouseInGutter = aEvent.clientX < rect.x;
|
||||
}
|
||||
|
||||
var metaKey = AppConstants.platform === "macosx" ? aEvent.metaKey
|
||||
: aEvent.ctrlKey;
|
||||
var modifKey = metaKey || aEvent.shiftKey;
|
||||
var isContainer = tbo.view.isContainer(cell.row);
|
||||
var openInTabs = isContainer &&
|
||||
(aEvent.button == 1 ||
|
||||
(aEvent.button == 0 && modifKey)) &&
|
||||
PlacesUtils.hasChildURIs(aTree.view.nodeForTreeIndex(cell.row));
|
||||
|
||||
if (aEvent.button == 0 && isContainer && !openInTabs) {
|
||||
tbo.view.toggleOpenState(cell.row);
|
||||
} else if (!mouseInGutter && openInTabs &&
|
||||
aEvent.originalTarget.localName == "treechildren") {
|
||||
tbo.view.selection.select(cell.row);
|
||||
PlacesUIUtils.openContainerNodeInTabs(aTree.selectedNode, aEvent, aTree);
|
||||
} else if (!mouseInGutter && !isContainer &&
|
||||
aEvent.originalTarget.localName == "treechildren") {
|
||||
// Clear all other selection since we're loading a link now. We must
|
||||
// do this *before* attempting to load the link since openURL uses
|
||||
// selection as an indication of which link to load.
|
||||
tbo.view.selection.select(cell.row);
|
||||
PlacesUIUtils.openNodeWithEvent(aTree.selectedNode, aEvent);
|
||||
}
|
||||
},
|
||||
|
||||
handleTreeKeyPress: function SU_handleTreeKeyPress(aEvent) {
|
||||
let node = aEvent.target.selectedNode;
|
||||
if (node) {
|
||||
if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN)
|
||||
PlacesUIUtils.openNodeWithEvent(node, aEvent);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The following function displays the URL of a node that is being
|
||||
* hovered over.
|
||||
*/
|
||||
handleTreeMouseMove: function SU_handleTreeMouseMove(aEvent) {
|
||||
if (aEvent.target.localName != "treechildren")
|
||||
return;
|
||||
|
||||
var tree = aEvent.target.parentNode;
|
||||
var tbo = tree.treeBoxObject;
|
||||
var cell = tbo.getCellAt(aEvent.clientX, aEvent.clientY);
|
||||
|
||||
// cell.row is -1 when the mouse is hovering an empty area within the tree.
|
||||
// To avoid showing a URL from a previously hovered node for a currently
|
||||
// hovered non-url node, we must clear the moused-over URL in these cases.
|
||||
if (cell.row != -1) {
|
||||
var node = tree.view.nodeForTreeIndex(cell.row);
|
||||
if (PlacesUtils.nodeIsURI(node))
|
||||
this.setMouseoverURL(node.uri);
|
||||
else
|
||||
this.setMouseoverURL("");
|
||||
} else
|
||||
this.setMouseoverURL("");
|
||||
},
|
||||
|
||||
setMouseoverURL: function SU_setMouseoverURL(aURL) {
|
||||
// When the browser window is closed with an open sidebar, the sidebar
|
||||
// unload event happens after the browser's one. In this case
|
||||
// top.XULBrowserWindow has been nullified already.
|
||||
if (top.XULBrowserWindow) {
|
||||
top.XULBrowserWindow.setOverLink(aURL, null);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -9,7 +9,6 @@ browser.jar:
|
|||
* content/browser/places/places.xul (content/places.xul)
|
||||
content/browser/places/places.js (content/places.js)
|
||||
content/browser/places/places.css (content/places.css)
|
||||
content/browser/places/organizer.css (content/organizer.css)
|
||||
* content/browser/places/bookmarkProperties.xul (content/bookmarkProperties.xul)
|
||||
content/browser/places/bookmarkProperties.js (content/bookmarkProperties.js)
|
||||
content/browser/places/menu.xml (content/menu.xml)
|
||||
|
@ -17,12 +16,8 @@ browser.jar:
|
|||
content/browser/places/controller.js (content/controller.js)
|
||||
content/browser/places/treeView.js (content/treeView.js)
|
||||
content/browser/places/browserPlacesViews.js (content/browserPlacesViews.js)
|
||||
# keep the Places version of the history sidebar at history/history-panel.xul
|
||||
# to prevent having to worry about between versions of the browser
|
||||
* content/browser/history/history-panel.xul (content/history-panel.xul)
|
||||
content/browser/places/history-panel.js (content/history-panel.js)
|
||||
# ditto for the bookmarks sidebar
|
||||
* content/browser/bookmarks/bookmarksPanel.xul (content/bookmarksPanel.xul)
|
||||
content/browser/bookmarks/bookmarksPanel.js (content/bookmarksPanel.js)
|
||||
content/browser/bookmarks/sidebarUtils.js (content/sidebarUtils.js)
|
||||
* content/browser/places/historySidebar.xul (content/historySidebar.xul)
|
||||
content/browser/places/historySidebar.js (content/historySidebar.js)
|
||||
* content/browser/places/bookmarksSidebar.xul (content/bookmarksSidebar.xul)
|
||||
content/browser/places/bookmarksSidebar.js (content/bookmarksSidebar.js)
|
||||
content/browser/places/editBookmark.js (content/editBookmark.js)
|
||||
|
|
|
@ -33,7 +33,6 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
if (!aboutCapabilities.isWindowPrivate()) {
|
||||
document.documentElement.classList.remove("private");
|
||||
document.documentElement.classList.add("normal");
|
||||
document.title = document.querySelector("title").getAttribute("notprivatetitle");
|
||||
document.getElementById("favicon").setAttribute("href", FAVICON_QUESTION);
|
||||
document.getElementById("startPrivateBrowsing").addEventListener("click", function() {
|
||||
aboutCapabilities.sendAsyncMessage("OpenPrivateWindow", null);
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
<link id="favicon" rel="icon" type="image/png" href="chrome://browser/skin/privatebrowsing/favicon.svg"/>
|
||||
<link rel="stylesheet" href="chrome://browser/content/aboutPrivateBrowsing.css" type="text/css" media="all"/>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/privatebrowsing/aboutPrivateBrowsing.css" type="text/css" media="all"/>
|
||||
<title notprivatetitle="&aboutPrivateBrowsing.notPrivate.title;">&aboutPrivateBrowsing.title;</title>
|
||||
<script type="application/javascript" src="chrome://browser/content/aboutPrivateBrowsing.js"></script>
|
||||
</head>
|
||||
|
||||
|
|
|
@ -23,14 +23,14 @@ add_task(async function test() {
|
|||
if (isOSX) {
|
||||
page_with_title = test_title;
|
||||
page_without_title = app_name;
|
||||
about_pb_title = "Open a private window?";
|
||||
about_pb_title = app_name;
|
||||
pb_page_with_title = test_title + " - (Private Browsing)";
|
||||
pb_page_without_title = app_name + " - (Private Browsing)";
|
||||
pb_about_pb_title = app_name + " - (Private Browsing)";
|
||||
} else {
|
||||
page_with_title = test_title + " - " + app_name;
|
||||
page_without_title = app_name;
|
||||
about_pb_title = "Open a private window? - " + app_name;
|
||||
about_pb_title = app_name;
|
||||
pb_page_with_title = test_title + " - " + app_name + " (Private Browsing)";
|
||||
pb_page_without_title = app_name + " (Private Browsing)";
|
||||
pb_about_pb_title = app_name + " (Private Browsing)";
|
||||
|
|
|
@ -2,11 +2,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/. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE (aboutPrivateBrowsing.title):
|
||||
Please ensure this exactly matches tabs.emptyPrivateTabTitle in tabbrowser.properties -->
|
||||
<!ENTITY aboutPrivateBrowsing.title "Private Browsing">
|
||||
<!ENTITY aboutPrivateBrowsing.notPrivate.title "Open a private window?">
|
||||
|
||||
<!ENTITY aboutPrivateBrowsing.notPrivate "You are currently not in a private window.">
|
||||
<!ENTITY privatebrowsingpage.openPrivateWindow.label "Open a Private Window">
|
||||
<!ENTITY privatebrowsingpage.openPrivateWindow.accesskey "P">
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
tabs.restoreLastTabs=Restore Tabs From Last Time
|
||||
tabs.emptyTabTitle=New Tab
|
||||
# LOCALIZATION NOTE (tabs.emptyPrivateTabTitle)
|
||||
# Please ensure this exactly matches aboutPrivateBrowsing.dtd's window title (aboutPrivateBrowsing.title).
|
||||
tabs.emptyPrivateTabTitle=Private Browsing
|
||||
tabs.closeTab=Close Tab
|
||||
tabs.close=Close
|
||||
|
|
|
@ -132,7 +132,7 @@ async function allTabTitlesDisplayed(browserWindow) {
|
|||
"about:home": "New Tab",
|
||||
"about:newtab": "New Tab",
|
||||
"about:addons": "Add-ons Manager",
|
||||
"about:privatebrowsing": "Open a private window?"
|
||||
"about:privatebrowsing": "about:privatebrowsing"
|
||||
};
|
||||
specToTitleMap[PREFS_TAB] = "browser/skin/settings.svg";
|
||||
specToTitleMap[CUST_TAB] = "browser/skin/customize.svg";
|
||||
|
|
|
@ -25,9 +25,13 @@ registerCleanupFunction(async function() {
|
|||
}
|
||||
});
|
||||
|
||||
// Disable new animation inspector.
|
||||
Services.prefs.setBoolPref("devtools.new-animationinspector.enabled", false);
|
||||
|
||||
// Clean-up all prefs that might have been changed during a test run
|
||||
// (safer here because if the test fails, then the pref is never reverted)
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.new-animationinspector.enabled");
|
||||
Services.prefs.clearUserPref("devtools.debugger.log");
|
||||
});
|
||||
|
||||
|
|
|
@ -15,14 +15,10 @@ const TAB_NAME = "newanimationinspector";
|
|||
const ANIMATION_L10N =
|
||||
new LocalizationHelper("devtools/client/locales/animationinspector.properties");
|
||||
|
||||
// Enable new animation inspector.
|
||||
Services.prefs.setBoolPref("devtools.new-animationinspector.enabled", true);
|
||||
|
||||
// Auto clean-up when a test ends.
|
||||
// Clean-up all prefs that might have been changed during a test run
|
||||
// (safer here because if the test fails, then the pref is never reverted)
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.new-animationinspector.enabled");
|
||||
Services.prefs.clearUserPref("devtools.toolsidebar-width.inspector");
|
||||
});
|
||||
|
||||
|
|
|
@ -55,14 +55,19 @@ add_task(async function() {
|
|||
|
||||
info("Click on the animation inspector tab");
|
||||
let onHighlighterHidden = toolbox.once("node-unhighlight");
|
||||
let onTabInspectorSelected = inspector.sidebar.once("animationinspector-selected");
|
||||
let animationInspectorTab = inspector.panelDoc.querySelector("#animationinspector-tab");
|
||||
let onTabInspectorSelected = inspector.sidebar.once("newanimationinspector-selected");
|
||||
let onInspectorUpdated = inspector.once("inspector-updated");
|
||||
let animationInspectorTab =
|
||||
inspector.panelDoc.querySelector("#newanimationinspector-tab");
|
||||
EventUtils.synthesizeMouseAtCenter(animationInspectorTab, {},
|
||||
inspector.panelDoc.defaultView);
|
||||
|
||||
await onTabInspectorSelected;
|
||||
info("animation inspector was selected");
|
||||
|
||||
await onInspectorUpdated;
|
||||
info("animation inspector was updated");
|
||||
|
||||
await onHighlighterHidden;
|
||||
info("box model highlighter hidden after moving the mouse out of the markup view");
|
||||
});
|
||||
|
|
|
@ -72,8 +72,12 @@ pref("devtools.changesview.enabled", false);
|
|||
pref("devtools.eventsview.enabled", false);
|
||||
// Enable the Flexbox Inspector panel
|
||||
pref("devtools.flexboxinspector.enabled", false);
|
||||
// Enable the new Animation Inspector
|
||||
// Enable the new Animation Inspector in Nightly only
|
||||
#if defined(NIGHTLY_BUILD)
|
||||
pref("devtools.new-animationinspector.enabled", true);
|
||||
#else
|
||||
pref("devtools.new-animationinspector.enabled", false);
|
||||
#endif
|
||||
// Enable the Variable Fonts editor
|
||||
pref("devtools.inspector.fonteditor.enabled", false);
|
||||
|
||||
|
|
|
@ -1141,11 +1141,11 @@ class CssGridHighlighter extends AutoRefreshHighlighter {
|
|||
* The grid line breadth value.
|
||||
* @param {String} dimensionType
|
||||
* The grid dimension type which is either the constant COLUMNS or ROWS.
|
||||
* @param {Number||undefined} stackedLineIndex
|
||||
* The line index position of the stacked line.
|
||||
* @param {Boolean||undefined} isStackedLine
|
||||
* Boolean indicating if the line is stacked.
|
||||
*/
|
||||
renderGridLineNumber(lineNumber, linePos, startPos, breadth, dimensionType,
|
||||
stackedLineIndex) {
|
||||
isStackedLine) {
|
||||
let displayPixelRatio = getDisplayPixelRatio(this.win);
|
||||
let { devicePixelRatio } = this.win;
|
||||
let offset = (displayPixelRatio / 2) % 1;
|
||||
|
@ -1206,7 +1206,7 @@ class CssGridHighlighter extends AutoRefreshHighlighter {
|
|||
|
||||
[x, y] = apply(this.currentMatrix, [x, y]);
|
||||
|
||||
if (stackedLineIndex) {
|
||||
if (isStackedLine) {
|
||||
// Offset the stacked line number by half of the box's width/height.
|
||||
const xOffset = boxWidth / 4;
|
||||
const yOffset = boxHeight / 4;
|
||||
|
@ -1354,7 +1354,7 @@ class CssGridHighlighter extends AutoRefreshHighlighter {
|
|||
this.ctx.textAlign = "center";
|
||||
this.ctx.textBaseline = "middle";
|
||||
this.ctx.fillStyle = "black";
|
||||
const numberText = stackedLineIndex ? "" : lineNumber;
|
||||
const numberText = isStackedLine ? "" : lineNumber;
|
||||
this.ctx.fillText(numberText, x, y);
|
||||
this.ctx.restore();
|
||||
}
|
||||
|
@ -1472,8 +1472,6 @@ class CssGridHighlighter extends AutoRefreshHighlighter {
|
|||
*/
|
||||
renderLineNumbers(gridDimension, dimensionType, startPos) {
|
||||
const { lines, tracks } = gridDimension;
|
||||
// Keep track of the number of collapsed lines per line position.
|
||||
let stackedLines = [];
|
||||
|
||||
for (let i = 0, line; (line = lines[i++]);) {
|
||||
// If you place something using negative numbers, you can trigger some implicit
|
||||
|
@ -1489,21 +1487,17 @@ class CssGridHighlighter extends AutoRefreshHighlighter {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Check for overlapping lines. We render a second box beneath the last overlapping
|
||||
// Check for overlapping lines by measuring the track width between them.
|
||||
// We render a second box beneath the last overlapping
|
||||
// line number to indicate there are lines beneath it.
|
||||
const gridLine = tracks[line.number - 1];
|
||||
const gridTrack = tracks[i - 1];
|
||||
|
||||
if (gridLine) {
|
||||
const { breadth } = gridLine;
|
||||
if (gridTrack) {
|
||||
const { breadth } = gridTrack;
|
||||
|
||||
if (breadth === 0) {
|
||||
stackedLines.push(lines[i].number);
|
||||
|
||||
if (stackedLines.length > 0) {
|
||||
this.renderGridLineNumber(line.number, line.start, startPos, line.breadth,
|
||||
dimensionType, 1);
|
||||
}
|
||||
|
||||
dimensionType, true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1527,8 +1521,6 @@ class CssGridHighlighter extends AutoRefreshHighlighter {
|
|||
*/
|
||||
renderNegativeLineNumbers(gridDimension, dimensionType, startPos) {
|
||||
const { lines, tracks } = gridDimension;
|
||||
// Keep track of the number of collapsed lines per line position.
|
||||
let stackedLines = [];
|
||||
|
||||
for (let i = 0, line; (line = lines[i++]);) {
|
||||
let linePos = line.start;
|
||||
|
@ -1539,32 +1531,21 @@ class CssGridHighlighter extends AutoRefreshHighlighter {
|
|||
break;
|
||||
}
|
||||
|
||||
// Check for overlapping lines. We render a second box beneath the last overlapping
|
||||
// Check for overlapping lines by measuring the track width between them.
|
||||
// We render a second box beneath the last overlapping
|
||||
// line number to indicate there are lines beneath it.
|
||||
const gridLine = tracks[line.number - 1];
|
||||
const gridTrack = tracks[i - 1];
|
||||
if (gridTrack) {
|
||||
const { breadth } = gridTrack;
|
||||
|
||||
if (gridLine) {
|
||||
const { breadth } = gridLine;
|
||||
|
||||
if (breadth === 0) {
|
||||
stackedLines.push(negativeLineNumber);
|
||||
|
||||
if (stackedLines.length > 0) {
|
||||
// Ensure "-1" is always visible, since it is always the largest number.
|
||||
if (breadth === 0 && negativeLineNumber != -1) {
|
||||
this.renderGridLineNumber(negativeLineNumber, linePos, startPos,
|
||||
line.breadth, dimensionType, 1);
|
||||
}
|
||||
|
||||
line.breadth, dimensionType, true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// For negative line numbers, we want to display the smallest
|
||||
// value at the front of the stack.
|
||||
if (stackedLines.length) {
|
||||
negativeLineNumber = stackedLines[0];
|
||||
stackedLines = [];
|
||||
}
|
||||
|
||||
this.renderGridLineNumber(negativeLineNumber, linePos, startPos, line.breadth,
|
||||
dimensionType);
|
||||
}
|
||||
|
|
|
@ -630,7 +630,7 @@ waitForAllPaints(() => {
|
|||
|
||||
const expectedRestyleCount = tweakExpectedRestyleCount(animation, 20);
|
||||
|
||||
var markers = await observeStyling(expectedRestyleCount);
|
||||
var markers = await observeStyling(20);
|
||||
is(markers.length, expectedRestyleCount,
|
||||
'Finite transform animation in out-of-view element should never be ' +
|
||||
'throttled');
|
||||
|
|
|
@ -275,10 +275,6 @@ ShadowRoot::ApplicableRulesChanged()
|
|||
return;
|
||||
}
|
||||
|
||||
if (!IsComposedDocParticipant()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIDocument* doc = OwnerDoc();
|
||||
if (nsIPresShell* shell = doc->GetShell()) {
|
||||
doc->BeginUpdate(UPDATE_STYLE);
|
||||
|
|
|
@ -246,14 +246,6 @@ public:
|
|||
return IsInNativeAnonymousSubtree() || (!IsInShadowTree() && GetBindingParent() != nullptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if this node is the shadow root of an use-element shadow tree.
|
||||
*/
|
||||
bool IsRootOfUseElementShadowTree() const {
|
||||
return GetParent() && GetParent()->IsSVGElement(nsGkAtoms::use) &&
|
||||
IsRootOfAnonymousSubtree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true iff this node is in an HTML document (in the HTML5 sense of
|
||||
* the term, i.e. not in an XHTML/XML document).
|
||||
|
|
|
@ -227,14 +227,8 @@
|
|||
</span>
|
||||
<script><![CDATA[
|
||||
window.onload = function() {
|
||||
if (window.parent && window.parent.SpecialPowers) {
|
||||
window.parent.SpecialPowers.pushPrefEnv(
|
||||
{ 'set': [[ "layout.css.scope-pseudo.enabled", true]] },
|
||||
doTest);
|
||||
} else {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
function doTest(){
|
||||
if ( !window.location.hash.includes("target") )
|
||||
|
|
|
@ -27,19 +27,18 @@
|
|||
class txStringToDouble
|
||||
{
|
||||
public:
|
||||
typedef char16_t input_type;
|
||||
typedef char16_t value_type;
|
||||
txStringToDouble(): mState(eWhitestart), mSign(ePositive) {}
|
||||
|
||||
void
|
||||
write(const input_type* aSource, uint32_t aSourceLength)
|
||||
Parse(const nsAString& aSource)
|
||||
{
|
||||
if (mState == eIllegal) {
|
||||
return;
|
||||
}
|
||||
uint32_t i = 0;
|
||||
char16_t c;
|
||||
for ( ; i < aSourceLength; ++i) {
|
||||
auto len = aSource.Length();
|
||||
for ( ; i < len; ++i) {
|
||||
c = aSource[i];
|
||||
switch (mState) {
|
||||
case eWhitestart:
|
||||
|
@ -127,8 +126,7 @@ private:
|
|||
double txDouble::toDouble(const nsAString& aSrc)
|
||||
{
|
||||
txStringToDouble sink;
|
||||
nsAString::const_iterator fromBegin, fromEnd;
|
||||
copy_string(aSrc.BeginReading(fromBegin), aSrc.EndReading(fromEnd), sink);
|
||||
sink.Parse(aSrc);
|
||||
return sink.getDouble();
|
||||
}
|
||||
|
||||
|
|
|
@ -175,7 +175,8 @@ js::InitMallocAllocator()
|
|||
void
|
||||
js::ShutDownMallocAllocator()
|
||||
{
|
||||
moz_dispose_arena(MallocArena);
|
||||
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
||||
// moz_dispose_arena(MallocArena);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "nsCSSKeywords.h"
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsCSSPseudoClasses.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsGenericHTMLFrameElement.h"
|
||||
|
@ -144,7 +143,6 @@ nsLayoutStatics::Initialize()
|
|||
// Register static atoms. Note that nsGkAtoms must be initialized earlier
|
||||
// than here, so it's done in NS_InitAtomTable() instead.
|
||||
nsCSSAnonBoxes::RegisterStaticAtoms();
|
||||
nsCSSPseudoClasses::RegisterStaticAtoms();
|
||||
nsCSSPseudoElements::RegisterStaticAtoms();
|
||||
nsCSSKeywords::AddRefTable();
|
||||
nsCSSProps::AddRefTable();
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "mozilla/StyleSheetInlines.h"
|
||||
#include "mozilla/dom/CharacterData.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsCSSPseudoClasses.h"
|
||||
#include "mozilla/dom/CSSLexer.h"
|
||||
#include "mozilla/dom/InspectorUtilsBinding.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
|
@ -980,39 +979,11 @@ InspectorUtils::GetUsedFontFaces(GlobalObject& aGlobalObject,
|
|||
static EventStates
|
||||
GetStatesForPseudoClass(const nsAString& aStatePseudo)
|
||||
{
|
||||
// An array of the states that are relevant for various pseudoclasses.
|
||||
// XXXbz this duplicates code in nsCSSRuleProcessor
|
||||
static const EventStates sPseudoClassStates[] = {
|
||||
#define CSS_PSEUDO_CLASS(_name, _value, _flags, _pref) \
|
||||
EventStates(),
|
||||
#define CSS_STATE_PSEUDO_CLASS(_name, _value, _flags, _pref, _states) \
|
||||
_states,
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_STATE_PSEUDO_CLASS
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
|
||||
// Add more entries for our fake values to make sure we can't
|
||||
// index out of bounds into this array no matter what.
|
||||
EventStates(),
|
||||
EventStates()
|
||||
};
|
||||
static_assert(MOZ_ARRAY_LENGTH(sPseudoClassStates) ==
|
||||
static_cast<size_t>(CSSPseudoClassType::MAX),
|
||||
"Length of PseudoClassStates array is incorrect");
|
||||
|
||||
RefPtr<nsAtom> atom = NS_Atomize(aStatePseudo);
|
||||
CSSPseudoClassType type = nsCSSPseudoClasses::
|
||||
GetPseudoType(atom, CSSEnabledState::eIgnoreEnabledState);
|
||||
|
||||
// Ignore :any-link so we don't give the element simultaneous
|
||||
// visited and unvisited style state
|
||||
if (type == CSSPseudoClassType::anyLink ||
|
||||
type == CSSPseudoClassType::mozAnyLink) {
|
||||
if (aStatePseudo.IsEmpty() || aStatePseudo[0] != u':') {
|
||||
return EventStates();
|
||||
}
|
||||
// Our array above is long enough that indexing into it with
|
||||
// NotPseudo is ok.
|
||||
return sPseudoClassStates[static_cast<CSSPseudoClassTypeBase>(type)];
|
||||
NS_ConvertUTF16toUTF8 statePseudo(Substring(aStatePseudo, 1));
|
||||
return EventStates(Servo_PseudoClass_GetStates(&statePseudo));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
|
|
@ -7,20 +7,22 @@
|
|||
#ifndef mozilla_dom_CSSKeyframesRule_h
|
||||
#define mozilla_dom_CSSKeyframesRule_h
|
||||
|
||||
#include "mozilla/css/GroupRule.h"
|
||||
#include "mozilla/css/Rule.h"
|
||||
#include "mozilla/dom/CSSKeyframeRule.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class CSSKeyframesRule : public css::GroupRule
|
||||
class CSSKeyframesRule : public css::Rule
|
||||
{
|
||||
protected:
|
||||
using css::GroupRule::GroupRule;
|
||||
using css::Rule::Rule;
|
||||
virtual ~CSSKeyframesRule() {}
|
||||
|
||||
public:
|
||||
int32_t GetType() const final { return Rule::KEYFRAMES_RULE; }
|
||||
// Let's not worry for now about sorting out whether we're a leaf or not.
|
||||
bool IsCCLeaf() const override { return false; }
|
||||
|
||||
// WebIDL interface
|
||||
uint16_t Type() const final { return CSSRuleBinding::KEYFRAMES_RULE; }
|
||||
|
|
|
@ -18,66 +18,20 @@ using namespace mozilla::dom;
|
|||
namespace mozilla {
|
||||
namespace css {
|
||||
|
||||
#define CALL_INNER(inner_, call_) \
|
||||
((inner_).is<DummyGroupRuleRules>() \
|
||||
? (inner_).as<DummyGroupRuleRules>().call_ \
|
||||
: (inner_).as<ServoGroupRuleRules>().call_)
|
||||
|
||||
|
||||
// -------------------------------
|
||||
// ServoGroupRuleRules
|
||||
//
|
||||
|
||||
ServoGroupRuleRules::~ServoGroupRuleRules()
|
||||
{
|
||||
if (mRuleList) {
|
||||
mRuleList->DropReference();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
ServoGroupRuleRules::List(FILE* out, int32_t aIndent) const
|
||||
{
|
||||
// TODO list something reasonable?
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t
|
||||
ServoGroupRuleRules::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// TODO how to implement?
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// GroupRule
|
||||
//
|
||||
|
||||
GroupRule::GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber)
|
||||
: Rule(aLineNumber, aColumnNumber)
|
||||
, mInner(DummyGroupRuleRules())
|
||||
{
|
||||
}
|
||||
|
||||
GroupRule::GroupRule(already_AddRefed<ServoCssRules> aRules,
|
||||
uint32_t aLineNumber, uint32_t aColumnNumber)
|
||||
: Rule(aLineNumber, aColumnNumber)
|
||||
, mInner(ServoGroupRuleRules(Move(aRules)))
|
||||
, mRuleList(new ServoCSSRuleList(Move(aRules), nullptr))
|
||||
{
|
||||
mInner.as<ServoGroupRuleRules>().SetParentRule(this);
|
||||
}
|
||||
|
||||
GroupRule::GroupRule(const GroupRule& aCopy)
|
||||
: Rule(aCopy)
|
||||
, mInner(aCopy.mInner)
|
||||
{
|
||||
CALL_INNER(mInner, SetParentRule(this));
|
||||
mRuleList->SetParentRule(this);
|
||||
}
|
||||
|
||||
GroupRule::~GroupRule()
|
||||
{
|
||||
MOZ_ASSERT(!mSheet, "SetStyleSheet should have been called");
|
||||
if (mRuleList) {
|
||||
mRuleList->DropReference();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(GroupRule, Rule)
|
||||
|
@ -96,23 +50,34 @@ GroupRule::IsCCLeaf() const
|
|||
NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GroupRule, Rule)
|
||||
CALL_INNER(tmp->mInner, SetParentRule(nullptr));
|
||||
// If tmp does not have a stylesheet, neither do its descendants. In that
|
||||
// case, don't try to null out their stylesheet, to avoid O(N^2) behavior in
|
||||
// depth of group rule nesting. But if tmp _does_ have a stylesheet (which
|
||||
// can happen if it gets unlinked earlier than its owning stylesheet), then we
|
||||
// need to null out the stylesheet pointer on descendants now, before we clear
|
||||
// tmp->mRules.
|
||||
if (tmp->mRuleList) {
|
||||
tmp->mRuleList->SetParentRule(nullptr);
|
||||
// If tmp does not have a stylesheet, neither do its descendants.
|
||||
// In that case, don't try to null out their stylesheet, to avoid
|
||||
// O(N^2) behavior in depth of group rule nesting. But if tmp
|
||||
// _does_ have a stylesheet (which can happen if it gets unlinked
|
||||
// earlier than its owning stylesheet), then we need to null out the
|
||||
// stylesheet pointer on descendants now, before we clear mRuleList.
|
||||
if (tmp->GetStyleSheet()) {
|
||||
CALL_INNER(tmp->mInner, SetStyleSheet(nullptr));
|
||||
tmp->mRuleList->SetStyleSheet(nullptr);
|
||||
}
|
||||
tmp->mRuleList->DropReference();
|
||||
tmp->mRuleList = nullptr;
|
||||
}
|
||||
CALL_INNER(tmp->mInner, Clear());
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GroupRule, Rule)
|
||||
CALL_INNER(tmp->mInner, Traverse(cb));
|
||||
ImplCycleCollectionTraverse(cb, tmp->mRuleList, "mRuleList");
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
GroupRule::List(FILE* out, int32_t aIndent) const
|
||||
{
|
||||
// TODO list something reasonable?
|
||||
}
|
||||
#endif
|
||||
|
||||
/* virtual */ void
|
||||
GroupRule::SetStyleSheet(StyleSheet* aSheet)
|
||||
{
|
||||
|
@ -121,18 +86,13 @@ GroupRule::SetStyleSheet(StyleSheet* aSheet)
|
|||
// depth when seting the sheet to null during unlink, if we happen to unlin in
|
||||
// order from most nested rule up to least nested rule.
|
||||
if (aSheet != GetStyleSheet()) {
|
||||
CALL_INNER(mInner, SetStyleSheet(aSheet));
|
||||
if (mRuleList) {
|
||||
mRuleList->SetStyleSheet(aSheet);
|
||||
}
|
||||
Rule::SetStyleSheet(aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSSRuleList*
|
||||
GroupRule::CssRules()
|
||||
{
|
||||
return CALL_INNER(mInner, CssRules(this));
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GroupRule::InsertRule(const nsAString& aRule, uint32_t aIndex, ErrorResult& aRv)
|
||||
{
|
||||
|
@ -181,7 +141,12 @@ GroupRule::DeleteRule(uint32_t aIndex, ErrorResult& aRv)
|
|||
}
|
||||
}
|
||||
|
||||
#undef CALL_INNER
|
||||
size_t
|
||||
GroupRule::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// TODO how to implement?
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace css
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -16,13 +16,9 @@
|
|||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/ServoCSSRuleList.h"
|
||||
#include "mozilla/Variant.h"
|
||||
#include "mozilla/css/Rule.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsPresContext;
|
||||
class nsMediaQueryResultCacheKey;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class StyleSheet;
|
||||
|
@ -33,97 +29,14 @@ class CSSRuleList;
|
|||
|
||||
namespace css {
|
||||
|
||||
class GroupRule;
|
||||
class GroupRuleRuleList;
|
||||
|
||||
|
||||
struct ServoGroupRuleRules
|
||||
{
|
||||
explicit ServoGroupRuleRules(already_AddRefed<ServoCssRules> aRawRules)
|
||||
: mRuleList(new ServoCSSRuleList(Move(aRawRules), nullptr)) {}
|
||||
ServoGroupRuleRules(ServoGroupRuleRules&& aOther)
|
||||
: mRuleList(Move(aOther.mRuleList)) {}
|
||||
ServoGroupRuleRules(const ServoGroupRuleRules& aCopy) {
|
||||
// Do we ever clone Servo rules?
|
||||
MOZ_ASSERT_UNREACHABLE("stylo: Cloning GroupRule not implemented");
|
||||
}
|
||||
~ServoGroupRuleRules();
|
||||
|
||||
void SetParentRule(GroupRule* aParentRule) {
|
||||
if (mRuleList) {
|
||||
mRuleList->SetParentRule(aParentRule);
|
||||
}
|
||||
}
|
||||
void SetStyleSheet(StyleSheet* aSheet) {
|
||||
if (mRuleList) {
|
||||
mRuleList->SetStyleSheet(aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
if (mRuleList) {
|
||||
mRuleList->DropReference();
|
||||
mRuleList = nullptr;
|
||||
}
|
||||
}
|
||||
void Traverse(nsCycleCollectionTraversalCallback& cb) {
|
||||
ImplCycleCollectionTraverse(cb, mRuleList, "mRuleList");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void List(FILE* out, int32_t aIndent) const;
|
||||
#endif
|
||||
|
||||
int32_t StyleRuleCount() const { return mRuleList->Length(); }
|
||||
Rule* GetStyleRuleAt(int32_t aIndex) const {
|
||||
return mRuleList->GetRule(aIndex);
|
||||
}
|
||||
|
||||
nsresult DeleteStyleRuleAt(uint32_t aIndex) {
|
||||
return mRuleList->DeleteRule(aIndex);
|
||||
}
|
||||
|
||||
dom::CSSRuleList* CssRules(GroupRule* aParentRule) {
|
||||
return mRuleList;
|
||||
}
|
||||
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
RefPtr<ServoCSSRuleList> mRuleList;
|
||||
};
|
||||
|
||||
struct DummyGroupRuleRules
|
||||
{
|
||||
void SetParentRule(GroupRule* aParentRule) {}
|
||||
void SetStyleSheet(StyleSheet* aSheet) {}
|
||||
void Clear() {}
|
||||
void Traverse(nsCycleCollectionTraversalCallback& cb) {}
|
||||
#ifdef DEBUG
|
||||
void List(FILE* out, int32_t aIndex) const {}
|
||||
#endif
|
||||
int32_t StyleRuleCount() const { return 0; }
|
||||
Rule* GetStyleRuleAt(int32_t aIndex) const { return nullptr; }
|
||||
nsresult DeleteStyleRuleAt(uint32_t aIndex) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
dom::CSSRuleList* CssRules(GroupRule* aParentRule) { return nullptr; }
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { return 0; }
|
||||
};
|
||||
|
||||
#define REDIRECT_TO_INNER(call_) \
|
||||
if (mInner.is<DummyGroupRuleRules>()) { \
|
||||
return mInner.as<DummyGroupRuleRules>().call_; \
|
||||
} else { \
|
||||
return mInner.as<ServoGroupRuleRules>().call_; \
|
||||
}
|
||||
|
||||
// inherits from Rule so it can be shared between
|
||||
// MediaRule and DocumentRule
|
||||
class GroupRule : public Rule
|
||||
{
|
||||
protected:
|
||||
GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber);
|
||||
GroupRule(already_AddRefed<ServoCssRules> aRules,
|
||||
uint32_t aLineNumber, uint32_t aColumnNumber);
|
||||
GroupRule(const GroupRule& aCopy);
|
||||
GroupRule(const GroupRule& aCopy) = delete;
|
||||
virtual ~GroupRule();
|
||||
public:
|
||||
|
||||
|
@ -132,55 +45,41 @@ public:
|
|||
virtual bool IsCCLeaf() const override;
|
||||
|
||||
#ifdef DEBUG
|
||||
void List(FILE* out = stdout, int32_t aIndent = 0) const override {
|
||||
REDIRECT_TO_INNER(List(out, aIndent))
|
||||
}
|
||||
void List(FILE* out = stdout, int32_t aIndent = 0) const override;
|
||||
#endif
|
||||
virtual void SetStyleSheet(StyleSheet* aSheet) override;
|
||||
|
||||
public:
|
||||
|
||||
int32_t StyleRuleCount() const {
|
||||
REDIRECT_TO_INNER(StyleRuleCount())
|
||||
}
|
||||
Rule* GetStyleRuleAt(uint32_t aIndex) const {
|
||||
REDIRECT_TO_INNER(GetStyleRuleAt(aIndex))
|
||||
}
|
||||
int32_t StyleRuleCount() const { return mRuleList->Length(); }
|
||||
|
||||
Rule* GetStyleRuleAt(int32_t aIndex) const {
|
||||
return mRuleList->GetRule(aIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
* The next two methods should never be called unless you have first
|
||||
* called WillDirty() on the parent stylesheet. After they are
|
||||
* called, DidDirty() needs to be called on the sheet.
|
||||
* The next method should never be called unless you have first called
|
||||
* WillDirty() on the parent stylesheet. After it's called, DidDirty()
|
||||
* needs to be called on the sheet.
|
||||
*/
|
||||
nsresult DeleteStyleRuleAt(uint32_t aIndex) {
|
||||
REDIRECT_TO_INNER(DeleteStyleRuleAt(aIndex));
|
||||
return mRuleList->DeleteRule(aIndex);
|
||||
}
|
||||
|
||||
// non-virtual -- it is only called by subclasses
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
REDIRECT_TO_INNER(SizeOfExcludingThis(aMallocSizeOf))
|
||||
}
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override = 0;
|
||||
|
||||
// WebIDL API
|
||||
dom::CSSRuleList* CssRules();
|
||||
dom::CSSRuleList* CssRules() { return mRuleList; }
|
||||
uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
|
||||
ErrorResult& aRv);
|
||||
void DeleteRule(uint32_t aIndex, ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// This only reason for the DummyGroupRuleRules is that ServoKeyframesRule
|
||||
// inherits from CSSKeyframesRules (and thus GroupRule). Once
|
||||
// ServoKeyframesRule can be made to inherit from Rule, the
|
||||
// DummyGroupRuleRules can be removed.
|
||||
Variant<DummyGroupRuleRules, ServoGroupRuleRules> mInner;
|
||||
RefPtr<ServoCSSRuleList> mRuleList;
|
||||
};
|
||||
|
||||
#undef REDIRECT_TO_INNER
|
||||
|
||||
// Implementation of WebIDL CSSConditionRule.
|
||||
class ConditionRule : public GroupRule
|
||||
{
|
||||
|
|
|
@ -93,10 +93,19 @@ public:
|
|||
|
||||
virtual void SetStyleSheet(StyleSheet* aSheet);
|
||||
|
||||
void SetParentRule(GroupRule* aRule) {
|
||||
// We don't reference count this up reference. The group rule
|
||||
// will tell us when it's going away or when we're detached from
|
||||
// it.
|
||||
// We don't reference count this up reference. The rule will tell us
|
||||
// when it's going away or when we're detached from it.
|
||||
void SetParentRule(Rule* aRule) {
|
||||
#ifdef DEBUG
|
||||
if (aRule) {
|
||||
int16_t type = aRule->Type();
|
||||
MOZ_ASSERT(type == dom::CSSRuleBinding::MEDIA_RULE ||
|
||||
type == dom::CSSRuleBinding::DOCUMENT_RULE ||
|
||||
type == dom::CSSRuleBinding::SUPPORTS_RULE ||
|
||||
(type == dom::CSSRuleBinding::KEYFRAMES_RULE &&
|
||||
Type() == dom::CSSRuleBinding::KEYFRAME_RULE));
|
||||
}
|
||||
#endif
|
||||
mParentRule = aRule;
|
||||
}
|
||||
|
||||
|
@ -129,7 +138,7 @@ protected:
|
|||
StyleSheet* mSheet;
|
||||
// When the parent GroupRule is destroyed, it will call SetParentRule(nullptr)
|
||||
// on this object. (Through SetParentRuleReference);
|
||||
GroupRule* MOZ_NON_OWNING_REF mParentRule;
|
||||
Rule* MOZ_NON_OWNING_REF mParentRule;
|
||||
|
||||
// Keep the same type so that MSVC packs them.
|
||||
uint32_t mLineNumber;
|
||||
|
|
|
@ -820,6 +820,8 @@ SERVO_BINDING_FUNC(Servo_ParseFontShorthandForMatching, bool,
|
|||
|
||||
SERVO_BINDING_FUNC(Servo_Property_IsShorthand, bool,
|
||||
const nsACString* name, bool* found);
|
||||
SERVO_BINDING_FUNC(Servo_PseudoClass_GetStates, uint64_t,
|
||||
const nsACString* name)
|
||||
|
||||
// AddRef / Release functions
|
||||
#define SERVO_ARC_TYPE(name_, type_) \
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsILoadContext.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsIMozBrowserFrame.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIPresShellInlines.h"
|
||||
|
@ -301,13 +302,6 @@ Gecko_IsRootElement(RawGeckoElementBorrowed aElement)
|
|||
return aElement->OwnerDoc()->GetRootElement() == aElement;
|
||||
}
|
||||
|
||||
bool
|
||||
Gecko_MatchesElement(CSSPseudoClassType aType,
|
||||
RawGeckoElementBorrowed aElement)
|
||||
{
|
||||
return nsCSSPseudoClasses::MatchesElement(aType, aElement).value();
|
||||
}
|
||||
|
||||
// Dirtiness tracking.
|
||||
void
|
||||
Gecko_SetNodeFlags(RawGeckoNodeBorrowed aNode, uint32_t aFlags)
|
||||
|
@ -851,11 +845,38 @@ Gecko_MatchLang(RawGeckoElementBorrowed aElement,
|
|||
{
|
||||
MOZ_ASSERT(!(aOverrideLang && !aHasOverrideLang),
|
||||
"aHasOverrideLang should only be set when aOverrideLang is null");
|
||||
MOZ_ASSERT(aValue, "null lang parameter");
|
||||
if (!aValue || !*aValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return nsCSSPseudoClasses::LangPseudoMatches(
|
||||
aElement,
|
||||
aHasOverrideLang ? aOverrideLang : nullptr,
|
||||
aHasOverrideLang, aValue, aElement->OwnerDoc());
|
||||
// We have to determine the language of the current element. Since
|
||||
// this is currently no property and since the language is inherited
|
||||
// from the parent we have to be prepared to look at all parent
|
||||
// nodes. The language itself is encoded in the LANG attribute.
|
||||
if (auto* language = aHasOverrideLang ? aOverrideLang : aElement->GetLang()) {
|
||||
return nsStyleUtil::DashMatchCompare(nsDependentAtomString(language),
|
||||
nsDependentString(aValue),
|
||||
nsASCIICaseInsensitiveStringComparator());
|
||||
}
|
||||
|
||||
// Try to get the language from the HTTP header or if this
|
||||
// is missing as well from the preferences.
|
||||
// The content language can be a comma-separated list of
|
||||
// language codes.
|
||||
nsAutoString language;
|
||||
aElement->OwnerDoc()->GetContentLanguage(language);
|
||||
|
||||
nsDependentString langString(aValue);
|
||||
language.StripWhitespace();
|
||||
for (auto const& lang : language.Split(char16_t(','))) {
|
||||
if (nsStyleUtil::DashMatchCompare(lang,
|
||||
langString,
|
||||
nsASCIICaseInsensitiveStringComparator())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAtom*
|
||||
|
@ -880,6 +901,25 @@ Gecko_GetDocumentLWTheme(const nsIDocument* aDocument)
|
|||
return aDocument->ThreadSafeGetDocumentLWTheme();
|
||||
}
|
||||
|
||||
bool
|
||||
Gecko_IsTableBorderNonzero(RawGeckoElementBorrowed aElement)
|
||||
{
|
||||
if (!aElement->IsHTMLElement(nsGkAtoms::table)) {
|
||||
return false;
|
||||
}
|
||||
const nsAttrValue *val = aElement->GetParsedAttr(nsGkAtoms::border);
|
||||
return val && (val->Type() != nsAttrValue::eInteger ||
|
||||
val->GetIntegerValue() != 0);
|
||||
}
|
||||
|
||||
bool
|
||||
Gecko_IsBrowserFrame(RawGeckoElementBorrowed aElement)
|
||||
{
|
||||
nsIMozBrowserFrame* browserFrame =
|
||||
const_cast<Element*>(aElement)->GetAsMozBrowserFrame();
|
||||
return browserFrame && browserFrame->GetReallyIsBrowser();
|
||||
}
|
||||
|
||||
template <typename Implementor>
|
||||
static nsAtom*
|
||||
AtomAttrValue(Implementor* aElement, nsAtom* aName)
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "mozilla/EffectCompositor.h"
|
||||
#include "mozilla/ComputedTimingFunction.h"
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsCSSPseudoClasses.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsStyleStruct.h"
|
||||
|
||||
|
@ -190,12 +189,13 @@ Gecko_LoadStyleSheet(mozilla::css::Loader* loader,
|
|||
// Selector Matching.
|
||||
uint64_t Gecko_ElementState(RawGeckoElementBorrowed element);
|
||||
bool Gecko_IsRootElement(RawGeckoElementBorrowed element);
|
||||
bool Gecko_MatchesElement(mozilla::CSSPseudoClassType type, RawGeckoElementBorrowed element);
|
||||
bool Gecko_MatchLang(RawGeckoElementBorrowed element,
|
||||
nsAtom* override_lang, bool has_override_lang,
|
||||
const char16_t* value);
|
||||
nsAtom* Gecko_GetXMLLangValue(RawGeckoElementBorrowed element);
|
||||
nsIDocument::DocumentTheme Gecko_GetDocumentLWTheme(const nsIDocument* aDocument);
|
||||
bool Gecko_IsTableBorderNonzero(RawGeckoElementBorrowed element);
|
||||
bool Gecko_IsBrowserFrame(RawGeckoElementBorrowed element);
|
||||
|
||||
// Attributes.
|
||||
#define SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_) \
|
||||
|
|
|
@ -187,7 +187,6 @@ rusty-enums = [
|
|||
"nsStyleSVGFallbackType",
|
||||
"nsINode_BooleanFlag",
|
||||
"mozilla::CSSPseudoElementType",
|
||||
"mozilla::CSSPseudoClassType",
|
||||
"mozilla::LookAndFeel_ColorID",
|
||||
"mozilla::LookAndFeel_FontID",
|
||||
"nsStyleTransformMatrix::MatrixTransformOperator",
|
||||
|
@ -232,7 +231,6 @@ whitelist-types = [
|
|||
"mozilla::ServoStyleSheetInner",
|
||||
"mozilla::ServoStyleSetSizes",
|
||||
"mozilla::ServoTraversalStatistics",
|
||||
"mozilla::CSSPseudoClassType",
|
||||
"mozilla::css::ErrorReporter",
|
||||
"mozilla::css::LoaderReusableStyleSheets",
|
||||
"mozilla::css::SheetLoadData",
|
||||
|
@ -515,7 +513,6 @@ structs-types = [
|
|||
"RawServoSourceSizeList",
|
||||
"RefPtr",
|
||||
"RustString",
|
||||
"CSSPseudoClassType",
|
||||
"CSSPseudoElementType",
|
||||
"ServoTraversalFlags",
|
||||
"ComputedTimingFunction_BeforeFlag",
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ServoElementSnapshot.h"
|
||||
#include "mozilla/ServoBindings.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -36,12 +37,8 @@ ServoElementSnapshot::AddOtherPseudoClassState(Element* aElement)
|
|||
return;
|
||||
}
|
||||
|
||||
mIsTableBorderNonzero =
|
||||
*nsCSSPseudoClasses::MatchesElement(CSSPseudoClassType::mozTableBorderNonzero,
|
||||
aElement);
|
||||
mIsMozBrowserFrame =
|
||||
*nsCSSPseudoClasses::MatchesElement(CSSPseudoClassType::mozBrowserFrame,
|
||||
aElement);
|
||||
mIsTableBorderNonzero = Gecko_IsTableBorderNonzero(aElement);
|
||||
mIsMozBrowserFrame = Gecko_IsBrowserFrame(aElement);
|
||||
|
||||
mContains |= Flags::OtherPseudoClassState;
|
||||
}
|
||||
|
|
|
@ -158,10 +158,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|||
|
||||
ServoKeyframesRule::ServoKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
|
||||
uint32_t aLine, uint32_t aColumn)
|
||||
// Although this class inherits from GroupRule, we don't want to use
|
||||
// it at all, so it is fine to call the constructor for Gecko. We can
|
||||
// make CSSKeyframesRule inherit from Rule directly once we can get
|
||||
// rid of nsCSSKeyframeRule.
|
||||
: dom::CSSKeyframesRule(aLine, aColumn)
|
||||
, mRawRule(Move(aRawRule))
|
||||
{
|
||||
|
@ -347,7 +343,6 @@ ServoKeyframesRule::FindRule(const nsAString& aKey)
|
|||
ServoKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
|
||||
if (mKeyframeList) {
|
||||
n += mKeyframeList->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "mozilla/ServoBindings.h"
|
||||
#include "mozilla/ServoDeclarationBlock.h"
|
||||
#include "mozilla/dom/CSSStyleRuleBinding.h"
|
||||
#include "nsCSSPseudoClasses.h"
|
||||
|
||||
#include "mozAutoDocUpdate.h"
|
||||
|
||||
|
|
|
@ -41,8 +41,6 @@ EXPORTS += [
|
|||
'nsCSSPropertyIDSet.h',
|
||||
'nsCSSPropList.h',
|
||||
'nsCSSProps.h',
|
||||
'nsCSSPseudoClasses.h',
|
||||
'nsCSSPseudoClassList.h',
|
||||
'nsCSSPseudoElementList.h',
|
||||
'nsCSSPseudoElements.h',
|
||||
'nsCSSScanner.h',
|
||||
|
@ -189,7 +187,6 @@ UNIFIED_SOURCES += [
|
|||
'nsCSSFontFaceRule.cpp',
|
||||
'nsCSSKeywords.cpp',
|
||||
'nsCSSProps.cpp',
|
||||
'nsCSSPseudoClasses.cpp',
|
||||
'nsCSSScanner.cpp',
|
||||
'nsCSSValue.cpp',
|
||||
'nsDOMCSSAttrDeclaration.cpp',
|
||||
|
@ -240,8 +237,6 @@ UNIFIED_SOURCES += [
|
|||
|
||||
SOURCES += [
|
||||
'nsCSSAnonBoxes.cpp',
|
||||
# Both nsCSSPseudoElements.cpp and nsCSSPseudoClasses.cpp defined a
|
||||
# 'mozPlaceholder' static atom.
|
||||
'nsCSSPseudoElements.cpp',
|
||||
# nsLayoutStylesheetCache.cpp uses nsExceptionHandler.h, which includes
|
||||
# windows.h.
|
||||
|
|
|
@ -1,269 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
/* atom list for CSS pseudo-classes */
|
||||
|
||||
/*
|
||||
* This file contains the list of nsAtoms and their values for CSS
|
||||
* pseudo-classes. It is designed to be used as inline input to
|
||||
* nsCSSPseudoClasses.cpp *only* through the magic of C preprocessing.
|
||||
* All entries must be enclosed in the macros CSS_PSEUDO_CLASS,
|
||||
* CSS_STATE_DEPENDENT_PSEUDO_CLASS, or CSS_STATE_PSEUDO_CLASS which
|
||||
* will have cruel and unusual things done to them. The entries should
|
||||
* be kept in some sort of logical order. The common arguments to these
|
||||
* macros are:
|
||||
* name_ : The C++ identifier used for the atom (which will be a member
|
||||
* of nsCSSPseudoClasses)
|
||||
* value_ : The pseudo-class as a string, including the initial colon,
|
||||
* used as the string value of the atom.
|
||||
* flags_ : A bitfield containing flags defined in nsCSSPseudoClasses.h
|
||||
* pref_ : The name of the preference controlling whether the
|
||||
* pseudo-class is recognized by the parser, or the empty
|
||||
* string if it's unconditional.
|
||||
* CSS_STATE_PSEUDO_CLASS has an additional argument:
|
||||
* bit_ : The event state bit or bits that corresponds to the
|
||||
* pseudo-class, i.e., causes it to match (only one bit
|
||||
* required to match).
|
||||
* CSS_STATE_DEPENDENT_PSEUDO_CLASS has an additional argument:
|
||||
* bit_ : The event state bits that affect whether the pseudo-class
|
||||
* matches. Matching depends on a customized per-class
|
||||
* algorithm which should be defined in SelectorMatches() in
|
||||
* nsCSSRuleProcessor.cpp.
|
||||
*
|
||||
* If CSS_STATE_PSEUDO_CLASS is not defined, it'll be automatically
|
||||
* defined to CSS_STATE_DEPENDENT_PSEUDO_CLASS;
|
||||
* if CSS_STATE_DEPENDENT_PSEUDO_CLASS is not defined, it'll be
|
||||
* automatically defined to CSS_PSEUDO_CLASS.
|
||||
*/
|
||||
|
||||
// OUTPUT_CLASS=nsCSSPseudoClasses
|
||||
// MACRO_NAME=CSS_PSEUDO_CLASS
|
||||
|
||||
#ifdef DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#error "CSS_STATE_DEPENDENT_PSEUDO_CLASS shouldn't be defined"
|
||||
#endif
|
||||
|
||||
#ifndef CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#define CSS_STATE_DEPENDENT_PSEUDO_CLASS(_name, _value, _flags, _pref, _bit) \
|
||||
CSS_PSEUDO_CLASS(_name, _value, _flags, _pref)
|
||||
#define DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#endif
|
||||
|
||||
#ifdef DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
#error "CSS_STATE_PSEUDO_CLASS shouldn't be defined"
|
||||
#endif
|
||||
|
||||
#ifndef CSS_STATE_PSEUDO_CLASS
|
||||
#define CSS_STATE_PSEUDO_CLASS(_name, _value, _flags, _pref, _bit) \
|
||||
CSS_STATE_DEPENDENT_PSEUDO_CLASS(_name, _value, _flags, _pref, _bit)
|
||||
#define DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
#endif
|
||||
|
||||
// The CSS_PSEUDO_CLASS entries should all come before the
|
||||
// CSS_STATE_PSEUDO_CLASS entries. The CSS_PSEUDO_CLASS entry order
|
||||
// must be the same as the order of cases in SelectorMatches. :not
|
||||
// must be the last CSS_PSEUDO_CLASS.
|
||||
|
||||
CSS_PSEUDO_CLASS(empty, ":empty", 0, "")
|
||||
CSS_PSEUDO_CLASS(mozOnlyWhitespace, ":-moz-only-whitespace", 0, "")
|
||||
CSS_PSEUDO_CLASS(lang, ":lang", 0, "")
|
||||
CSS_PSEUDO_CLASS(root, ":root", 0, "")
|
||||
CSS_PSEUDO_CLASS(any, ":-moz-any", 0, "")
|
||||
|
||||
CSS_PSEUDO_CLASS(firstChild, ":first-child", 0, "")
|
||||
CSS_PSEUDO_CLASS(firstNode, ":-moz-first-node", 0, "")
|
||||
CSS_PSEUDO_CLASS(lastChild, ":last-child", 0, "")
|
||||
CSS_PSEUDO_CLASS(lastNode, ":-moz-last-node", 0, "")
|
||||
CSS_PSEUDO_CLASS(onlyChild, ":only-child", 0, "")
|
||||
CSS_PSEUDO_CLASS(firstOfType, ":first-of-type", 0, "")
|
||||
CSS_PSEUDO_CLASS(lastOfType, ":last-of-type", 0, "")
|
||||
CSS_PSEUDO_CLASS(onlyOfType, ":only-of-type", 0, "")
|
||||
CSS_PSEUDO_CLASS(nthChild, ":nth-child", 0, "")
|
||||
CSS_PSEUDO_CLASS(nthLastChild, ":nth-last-child", 0, "")
|
||||
CSS_PSEUDO_CLASS(nthOfType, ":nth-of-type", 0, "")
|
||||
CSS_PSEUDO_CLASS(nthLastOfType, ":nth-last-of-type", 0, "")
|
||||
|
||||
// Match nodes that are HTML but not XHTML
|
||||
CSS_PSEUDO_CLASS(mozIsHTML, ":-moz-is-html", 0, "")
|
||||
|
||||
// Matches nodes that are in a native-anonymous subtree (i.e., nodes in
|
||||
// a subtree of C++ anonymous content constructed by Gecko for its own
|
||||
// purposes).
|
||||
CSS_PSEUDO_CLASS(mozNativeAnonymous, ":-moz-native-anonymous",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS, "")
|
||||
|
||||
CSS_PSEUDO_CLASS(mozUseShadowTreeRoot, ":-moz-use-shadow-tree-root",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS, "")
|
||||
|
||||
// -moz-locale-dir(ltr) and -moz-locale-dir(rtl) may be used
|
||||
// to match based on the locale's chrome direction
|
||||
CSS_PSEUDO_CLASS(mozLocaleDir, ":-moz-locale-dir", 0, "")
|
||||
|
||||
// -moz-lwtheme may be used to match a document that has a lightweight theme
|
||||
CSS_PSEUDO_CLASS(mozLWTheme, ":-moz-lwtheme", 0, "")
|
||||
|
||||
// -moz-lwtheme-brighttext matches a document that has a dark lightweight theme
|
||||
CSS_PSEUDO_CLASS(mozLWThemeBrightText, ":-moz-lwtheme-brighttext", 0, "")
|
||||
|
||||
// -moz-lwtheme-darktext matches a document that has a bright lightweight theme
|
||||
CSS_PSEUDO_CLASS(mozLWThemeDarkText, ":-moz-lwtheme-darktext", 0, "")
|
||||
|
||||
// Matches anything when the containing window is inactive
|
||||
CSS_PSEUDO_CLASS(mozWindowInactive, ":-moz-window-inactive", 0, "")
|
||||
|
||||
// Matches any table elements that have a nonzero border attribute,
|
||||
// according to HTML integer attribute parsing rules.
|
||||
CSS_PSEUDO_CLASS(mozTableBorderNonzero, ":-moz-table-border-nonzero",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS, "")
|
||||
|
||||
// Matches HTML frame/iframe elements which are mozbrowser.
|
||||
CSS_PSEUDO_CLASS(mozBrowserFrame, ":-moz-browser-frame",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "")
|
||||
|
||||
// Matches whatever the contextual reference elements are for the
|
||||
// matching operation.
|
||||
CSS_PSEUDO_CLASS(scope, ":scope", 0, "layout.css.scope-pseudo.enabled")
|
||||
|
||||
// :not needs to come at the end of the non-bit pseudo-class list, since
|
||||
// it doesn't actually get directly matched on in SelectorMatches.
|
||||
CSS_PSEUDO_CLASS(negation, ":not", 0, "")
|
||||
|
||||
// :dir(ltr) and :dir(rtl) match elements whose resolved
|
||||
// directionality in the markup language is ltr or rtl respectively.
|
||||
CSS_STATE_DEPENDENT_PSEUDO_CLASS(dir, ":dir", 0, "",
|
||||
NS_EVENT_STATE_LTR | NS_EVENT_STATE_RTL)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(link, ":link", 0, "", NS_EVENT_STATE_UNVISITED)
|
||||
// what matches :link or :visited
|
||||
CSS_STATE_PSEUDO_CLASS(mozAnyLink, ":-moz-any-link", 0, "",
|
||||
NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)
|
||||
CSS_STATE_PSEUDO_CLASS(anyLink, ":any-link", 0, "",
|
||||
NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)
|
||||
CSS_STATE_PSEUDO_CLASS(visited, ":visited", 0, "", NS_EVENT_STATE_VISITED)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(active, ":active", 0, "", NS_EVENT_STATE_ACTIVE)
|
||||
CSS_STATE_PSEUDO_CLASS(checked, ":checked", 0, "", NS_EVENT_STATE_CHECKED)
|
||||
CSS_STATE_PSEUDO_CLASS(disabled, ":disabled", 0, "", NS_EVENT_STATE_DISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(enabled, ":enabled", 0, "", NS_EVENT_STATE_ENABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(focus, ":focus", 0, "", NS_EVENT_STATE_FOCUS)
|
||||
CSS_STATE_PSEUDO_CLASS(focusWithin, ":focus-within", 0, "", NS_EVENT_STATE_FOCUS_WITHIN)
|
||||
CSS_STATE_PSEUDO_CLASS(hover, ":hover", 0, "", NS_EVENT_STATE_HOVER)
|
||||
CSS_STATE_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over", 0, "", NS_EVENT_STATE_DRAGOVER)
|
||||
CSS_STATE_PSEUDO_CLASS(target, ":target", 0, "", NS_EVENT_STATE_URLTARGET)
|
||||
CSS_STATE_PSEUDO_CLASS(indeterminate, ":indeterminate", 0, "",
|
||||
NS_EVENT_STATE_INDETERMINATE)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(mozDevtoolsHighlighted, ":-moz-devtools-highlighted",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS, "",
|
||||
NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozStyleeditorTransitioning, ":-moz-styleeditor-transitioning",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS, "",
|
||||
NS_EVENT_STATE_STYLEEDITOR_TRANSITIONING)
|
||||
|
||||
// Matches the element which is being displayed full-screen, and
|
||||
// any containing frames.
|
||||
CSS_STATE_PSEUDO_CLASS(fullscreen, ":fullscreen",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME,
|
||||
"full-screen-api.unprefix.enabled",
|
||||
NS_EVENT_STATE_FULL_SCREEN)
|
||||
CSS_STATE_PSEUDO_CLASS(mozFullScreen, ":-moz-full-screen", 0, "", NS_EVENT_STATE_FULL_SCREEN)
|
||||
|
||||
// Matches if the element is focused and should show a focus ring
|
||||
CSS_STATE_PSEUDO_CLASS(mozFocusRing, ":-moz-focusring", 0, "", NS_EVENT_STATE_FOCUSRING)
|
||||
|
||||
// Image, object, etc state pseudo-classes
|
||||
CSS_STATE_PSEUDO_CLASS(mozBroken, ":-moz-broken", 0, "", NS_EVENT_STATE_BROKEN)
|
||||
CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", 0, "", NS_EVENT_STATE_LOADING)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(mozUserDisabled, ":-moz-user-disabled",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_USERDISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_SUPPRESSED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerClickToPlay, ":-moz-handler-clicktoplay",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_TYPE_CLICK_TO_PLAY)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableUpdatable, ":-moz-handler-vulnerable-updatable",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_VULNERABLE_UPDATABLE)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableNoUpdate, ":-moz-handler-vulnerable-no-update",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_VULNERABLE_NO_UPDATE)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_HANDLER_DISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_HANDLER_BLOCKED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerCrashed, ":-moz-handler-crashed",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_HANDLER_CRASHED)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(mozMathIncrementScriptLevel,
|
||||
":-moz-math-increment-script-level", 0, "",
|
||||
NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(mozHasDirAttr, ":-moz-has-dir-attr",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS, "",
|
||||
NS_EVENT_STATE_HAS_DIR_ATTR)
|
||||
CSS_STATE_PSEUDO_CLASS(mozDirAttrLTR, ":-moz-dir-attr-ltr",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS, "",
|
||||
NS_EVENT_STATE_DIR_ATTR_LTR)
|
||||
CSS_STATE_PSEUDO_CLASS(mozDirAttrRTL, ":-moz-dir-attr-rtl",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS, "",
|
||||
NS_EVENT_STATE_DIR_ATTR_RTL)
|
||||
CSS_STATE_PSEUDO_CLASS(mozDirAttrLikeAuto, ":-moz-dir-attr-like-auto",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS, "",
|
||||
NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(mozAutofill, ":-moz-autofill",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_AUTOFILL)
|
||||
CSS_STATE_PSEUDO_CLASS(mozAutofillPreview, ":-moz-autofill-preview",
|
||||
CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
|
||||
NS_EVENT_STATE_AUTOFILL_PREVIEW)
|
||||
|
||||
// CSS 3 UI
|
||||
// http://www.w3.org/TR/2004/CR-css3-ui-20040511/#pseudo-classes
|
||||
CSS_STATE_PSEUDO_CLASS(required, ":required", 0, "", NS_EVENT_STATE_REQUIRED)
|
||||
CSS_STATE_PSEUDO_CLASS(optional, ":optional", 0, "", NS_EVENT_STATE_OPTIONAL)
|
||||
CSS_STATE_PSEUDO_CLASS(valid, ":valid", 0, "", NS_EVENT_STATE_VALID)
|
||||
CSS_STATE_PSEUDO_CLASS(invalid, ":invalid", 0, "", NS_EVENT_STATE_INVALID)
|
||||
CSS_STATE_PSEUDO_CLASS(inRange, ":in-range", 0, "", NS_EVENT_STATE_INRANGE)
|
||||
CSS_STATE_PSEUDO_CLASS(outOfRange, ":out-of-range", 0, "", NS_EVENT_STATE_OUTOFRANGE)
|
||||
CSS_STATE_PSEUDO_CLASS(defaultPseudo, ":default", 0, "", NS_EVENT_STATE_DEFAULT)
|
||||
CSS_STATE_PSEUDO_CLASS(placeholderShown, ":placeholder-shown", 0, "",
|
||||
NS_EVENT_STATE_PLACEHOLDERSHOWN)
|
||||
CSS_STATE_PSEUDO_CLASS(mozReadOnly, ":-moz-read-only", 0, "",
|
||||
NS_EVENT_STATE_MOZ_READONLY)
|
||||
CSS_STATE_PSEUDO_CLASS(mozReadWrite, ":-moz-read-write", 0, "",
|
||||
NS_EVENT_STATE_MOZ_READWRITE)
|
||||
CSS_STATE_PSEUDO_CLASS(mozSubmitInvalid, ":-moz-submit-invalid", 0, "",
|
||||
NS_EVENT_STATE_MOZ_SUBMITINVALID)
|
||||
CSS_STATE_PSEUDO_CLASS(mozUIInvalid, ":-moz-ui-invalid", 0, "",
|
||||
NS_EVENT_STATE_MOZ_UI_INVALID)
|
||||
CSS_STATE_PSEUDO_CLASS(mozUIValid, ":-moz-ui-valid", 0, "",
|
||||
NS_EVENT_STATE_MOZ_UI_VALID)
|
||||
CSS_STATE_PSEUDO_CLASS(mozMeterOptimum, ":-moz-meter-optimum", 0, "",
|
||||
NS_EVENT_STATE_OPTIMUM)
|
||||
CSS_STATE_PSEUDO_CLASS(mozMeterSubOptimum, ":-moz-meter-sub-optimum", 0, "",
|
||||
NS_EVENT_STATE_SUB_OPTIMUM)
|
||||
CSS_STATE_PSEUDO_CLASS(mozMeterSubSubOptimum, ":-moz-meter-sub-sub-optimum", 0, "",
|
||||
NS_EVENT_STATE_SUB_SUB_OPTIMUM)
|
||||
|
||||
// Those values should be parsed but do nothing.
|
||||
CSS_STATE_PSEUDO_CLASS(mozPlaceholder, ":-moz-placeholder", 0, "", NS_EVENT_STATE_IGNORE)
|
||||
|
||||
#ifdef DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
#undef DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
#undef CSS_STATE_PSEUDO_CLASS
|
||||
#endif
|
||||
|
||||
#ifdef DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#undef DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#undef CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#endif
|
|
@ -1,335 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
/* atom list for CSS pseudo-classes */
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
#include "nsCSSPseudoClasses.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsStaticAtom.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsString.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsIMozBrowserFrame.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
static_assert(!((flags_) & CSS_PSEUDO_CLASS_ENABLED_IN_CHROME) || \
|
||||
((flags_) & CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), \
|
||||
"Pseudo-class '" #name_ "' is enabled in chrome, so it " \
|
||||
"should also be enabled in UA sheets");
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct CSSPseudoClassAtoms
|
||||
{
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
NS_STATIC_ATOM_DECL_STRING(name_, value_)
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
NS_STATIC_ATOM_DECL_ATOM(name_)
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
};
|
||||
|
||||
MOZ_PUSH_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING
|
||||
static constexpr CSSPseudoClassAtoms sCSSPseudoClassAtoms = {
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
NS_STATIC_ATOM_INIT_STRING(value_)
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
NS_STATIC_ATOM_INIT_ATOM(CSSPseudoClassAtoms, name_, value_)
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
};
|
||||
MOZ_POP_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class CSSPseudoClassAtoms
|
||||
{
|
||||
public:
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
NS_STATIC_ATOM_DECL_PTR(name_)
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
};
|
||||
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
NS_STATIC_ATOM_DEFN_PTR(CSSPseudoClassAtoms, name_)
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
|
||||
static const nsStaticAtomSetup sCSSPseudoClassAtomSetup[] = {
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
NS_STATIC_ATOM_SETUP( \
|
||||
::detail::sCSSPseudoClassAtoms, CSSPseudoClassAtoms, name_)
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
};
|
||||
|
||||
// Flags data for each of the pseudo-classes, which must be separate
|
||||
// from the previous array since there's no place for it in
|
||||
// nsStaticAtomSetup.
|
||||
/* static */ const uint32_t
|
||||
nsCSSPseudoClasses::kPseudoClassFlags[] = {
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
flags_,
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
};
|
||||
|
||||
/* static */ bool
|
||||
nsCSSPseudoClasses::sPseudoClassEnabled[] = {
|
||||
// If the pseudo class has any "ENABLED_IN" flag set, it is disabled by
|
||||
// default. Note that, if a pseudo class has pref, whatever its default value
|
||||
// is, it'll later be changed in nsCSSPseudoClasses::RegisterStaticAtoms() If
|
||||
// the pseudo class has "ENABLED_IN" flags but doesn't have a pref, it is an
|
||||
// internal pseudo class which is disabled elsewhere.
|
||||
#define IS_ENABLED_BY_DEFAULT(flags_) \
|
||||
(!((flags_) & CSS_PSEUDO_CLASS_ENABLED_MASK))
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
IS_ENABLED_BY_DEFAULT(flags_),
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
#undef IS_ENABLED_BY_DEFAULT
|
||||
};
|
||||
|
||||
void nsCSSPseudoClasses::RegisterStaticAtoms()
|
||||
{
|
||||
NS_RegisterStaticAtoms(sCSSPseudoClassAtomSetup);
|
||||
|
||||
#define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
|
||||
if (pref_[0]) { \
|
||||
auto idx = static_cast<CSSPseudoElementTypeBase>(Type::name_); \
|
||||
Preferences::AddBoolVarCache(&sPseudoClassEnabled[idx], pref_); \
|
||||
}
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSSPseudoClasses::HasStringArg(Type aType)
|
||||
{
|
||||
return aType == Type::lang ||
|
||||
aType == Type::mozLocaleDir ||
|
||||
aType == Type::dir;
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSSPseudoClasses::HasNthPairArg(Type aType)
|
||||
{
|
||||
return aType == Type::nthChild ||
|
||||
aType == Type::nthLastChild ||
|
||||
aType == Type::nthOfType ||
|
||||
aType == Type::nthLastOfType;
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSPseudoClasses::PseudoTypeToString(Type aType, nsAString& aString)
|
||||
{
|
||||
MOZ_ASSERT(aType < Type::Count, "Unexpected type");
|
||||
auto idx = static_cast<CSSPseudoClassTypeBase>(aType);
|
||||
(*sCSSPseudoClassAtomSetup[idx].mAtomp)->ToString(aString);
|
||||
}
|
||||
|
||||
/* static */ CSSPseudoClassType
|
||||
nsCSSPseudoClasses::GetPseudoType(nsAtom* aAtom, EnabledState aEnabledState)
|
||||
{
|
||||
Maybe<uint32_t> index =
|
||||
nsStaticAtomUtils::Lookup(aAtom, sCSSPseudoClassAtomSetup);
|
||||
if (index.isSome()) {
|
||||
Type type = Type(*index);
|
||||
if (IsEnabled(type, aEnabledState)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return Type::NotPseudo;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsCSSPseudoClasses::IsUserActionPseudoClass(Type aType)
|
||||
{
|
||||
// See http://dev.w3.org/csswg/selectors4/#useraction-pseudos
|
||||
return aType == Type::hover ||
|
||||
aType == Type::active ||
|
||||
aType == Type::focus;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsCSSPseudoClasses::LangPseudoMatches(const mozilla::dom::Element* aElement,
|
||||
const nsAtom* aOverrideLang,
|
||||
bool aHasOverrideLang,
|
||||
const char16_t* aString,
|
||||
const nsIDocument* aDocument)
|
||||
{
|
||||
NS_ASSERTION(aString, "null lang parameter");
|
||||
if (!aString || !*aString) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We have to determine the language of the current element. Since
|
||||
// this is currently no property and since the language is inherited
|
||||
// from the parent we have to be prepared to look at all parent
|
||||
// nodes. The language itself is encoded in the LANG attribute.
|
||||
if (auto* language = aHasOverrideLang ? aOverrideLang : aElement->GetLang()) {
|
||||
return nsStyleUtil::DashMatchCompare(nsDependentAtomString(language),
|
||||
nsDependentString(aString),
|
||||
nsASCIICaseInsensitiveStringComparator());
|
||||
}
|
||||
|
||||
if (!aDocument) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to get the language from the HTTP header or if this
|
||||
// is missing as well from the preferences.
|
||||
// The content language can be a comma-separated list of
|
||||
// language codes.
|
||||
nsAutoString language;
|
||||
aDocument->GetContentLanguage(language);
|
||||
|
||||
nsDependentString langString(aString);
|
||||
language.StripWhitespace();
|
||||
for (auto const& lang : language.Split(char16_t(','))) {
|
||||
if (nsStyleUtil::DashMatchCompare(lang,
|
||||
langString,
|
||||
nsASCIICaseInsensitiveStringComparator())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsCSSPseudoClasses::StringPseudoMatches(const mozilla::dom::Element* aElement,
|
||||
CSSPseudoClassType aPseudo,
|
||||
const char16_t* aString,
|
||||
const nsIDocument* aDocument,
|
||||
EventStates aStateMask,
|
||||
bool* const aDependence)
|
||||
{
|
||||
|
||||
switch (aPseudo) {
|
||||
case CSSPseudoClassType::mozLocaleDir:
|
||||
{
|
||||
const bool docIsRTL =
|
||||
aDocument->GetDocumentState().HasState(NS_DOCUMENT_STATE_RTL_LOCALE);
|
||||
nsDependentString dirString(aString);
|
||||
|
||||
if (dirString.EqualsLiteral("rtl")) {
|
||||
if (!docIsRTL) {
|
||||
return false;
|
||||
}
|
||||
} else if (dirString.EqualsLiteral("ltr")) {
|
||||
if (docIsRTL) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Selectors specifying other directions never match.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSSPseudoClassType::dir:
|
||||
{
|
||||
if (aDependence) {
|
||||
EventStates states = sPseudoClassStateDependences[
|
||||
static_cast<CSSPseudoClassTypeBase>(aPseudo)];
|
||||
if (aStateMask.HasAtLeastOneOfStates(states)) {
|
||||
*aDependence = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If we only had to consider HTML, directionality would be
|
||||
// exclusively LTR or RTL.
|
||||
//
|
||||
// However, in markup languages where there is no direction attribute
|
||||
// we have to consider the possibility that neither dir(rtl) nor
|
||||
// dir(ltr) matches.
|
||||
EventStates state = aElement->StyleState();
|
||||
nsDependentString dirString(aString);
|
||||
|
||||
if (dirString.EqualsLiteral("rtl")) {
|
||||
if (!state.HasState(NS_EVENT_STATE_RTL)) {
|
||||
return false;
|
||||
}
|
||||
} else if (dirString.EqualsLiteral("ltr")) {
|
||||
if (!state.HasState(NS_EVENT_STATE_LTR)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Selectors specifying other directions never match.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSSPseudoClassType::lang:
|
||||
if (LangPseudoMatches(aElement, nullptr, false, aString, aDocument)) {
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
||||
default: MOZ_ASSERT_UNREACHABLE("Called StringPseudoMatches() with unknown string-like pseudo");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ Maybe<bool>
|
||||
nsCSSPseudoClasses::MatchesElement(Type aType, const dom::Element* aElement)
|
||||
{
|
||||
switch (aType) {
|
||||
case CSSPseudoClassType::mozNativeAnonymous:
|
||||
return Some(aElement->IsInNativeAnonymousSubtree());
|
||||
case CSSPseudoClassType::mozUseShadowTreeRoot:
|
||||
return Some(aElement->IsRootOfUseElementShadowTree());
|
||||
case CSSPseudoClassType::mozTableBorderNonzero: {
|
||||
if (!aElement->IsHTMLElement(nsGkAtoms::table)) {
|
||||
return Some(false);
|
||||
}
|
||||
const nsAttrValue *val = aElement->GetParsedAttr(nsGkAtoms::border);
|
||||
return Some(val && (val->Type() != nsAttrValue::eInteger ||
|
||||
val->GetIntegerValue() != 0));
|
||||
}
|
||||
case CSSPseudoClassType::mozBrowserFrame: {
|
||||
nsIMozBrowserFrame* browserFrame =
|
||||
const_cast<Element*>(aElement)->GetAsMozBrowserFrame();
|
||||
return Some(browserFrame && browserFrame->GetReallyIsBrowser());
|
||||
}
|
||||
default:
|
||||
return Nothing();
|
||||
}
|
||||
}
|
||||
|
||||
// The dependencies for all state dependent pseudo-classes (i.e. those declared
|
||||
// using CSS_STATE_DEPENDENT_PSEUDO_CLASS, the only one of which is :dir(...)).
|
||||
const EventStates
|
||||
nsCSSPseudoClasses::sPseudoClassStateDependences[size_t(CSSPseudoClassType::Count) + 2] = {
|
||||
#define CSS_PSEUDO_CLASS(_name, _value, _flags, _pref) \
|
||||
EventStates(),
|
||||
#define CSS_STATE_DEPENDENT_PSEUDO_CLASS(_name, _value, _flags, _pref, _states) \
|
||||
_states,
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
// Add more entries for our fake values to make sure we can't
|
||||
// index out of bounds into this array no matter what.
|
||||
EventStates(),
|
||||
EventStates()
|
||||
};
|
|
@ -1,139 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
/* atom list for CSS pseudo-classes */
|
||||
|
||||
#ifndef nsCSSPseudoClasses_h___
|
||||
#define nsCSSPseudoClasses_h___
|
||||
|
||||
#include "nsStringFwd.h"
|
||||
#include "mozilla/CSSEnabledState.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
// The following two flags along with the pref defines where this pseudo
|
||||
// class can be used:
|
||||
// * If none of the two flags is presented, the pref completely controls
|
||||
// the availability of this pseudo class. And in that case, if it has
|
||||
// no pref, this property is usable everywhere.
|
||||
// * If any of the flags is set, this pseudo class is always enabled in
|
||||
// the specific contexts regardless of the value of the pref. If there
|
||||
// is no pref for this pseudo class at all in this case, it is an
|
||||
// internal-only pseudo class, which cannot be used anywhere else.
|
||||
#define CSS_PSEUDO_CLASS_ENABLED_MASK (3<<0)
|
||||
#define CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS (1<<0)
|
||||
#define CSS_PSEUDO_CLASS_ENABLED_IN_CHROME (1<<1)
|
||||
#define CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME \
|
||||
(CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS | CSS_PSEUDO_CLASS_ENABLED_IN_CHROME)
|
||||
|
||||
class nsAtom;
|
||||
class nsIDocument;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Element;
|
||||
} // namespace dom
|
||||
|
||||
// The total count of CSSPseudoClassType is less than 256,
|
||||
// so use uint8_t as its underlying type.
|
||||
typedef uint8_t CSSPseudoClassTypeBase;
|
||||
enum class CSSPseudoClassType : CSSPseudoClassTypeBase
|
||||
{
|
||||
#define CSS_PSEUDO_CLASS(_name, _value, _flags, _pref) \
|
||||
_name,
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
Count,
|
||||
NotPseudo, // This value MUST be second last! SelectorMatches depends on it.
|
||||
MAX
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
class nsCSSPseudoClasses
|
||||
{
|
||||
typedef mozilla::CSSPseudoClassType Type;
|
||||
typedef mozilla::CSSEnabledState EnabledState;
|
||||
|
||||
public:
|
||||
static void RegisterStaticAtoms();
|
||||
|
||||
static Type GetPseudoType(nsAtom* aAtom, EnabledState aEnabledState);
|
||||
static bool HasStringArg(Type aType);
|
||||
static bool HasNthPairArg(Type aType);
|
||||
static bool HasSelectorListArg(Type aType) {
|
||||
return aType == Type::any;
|
||||
}
|
||||
static bool IsUserActionPseudoClass(Type aType);
|
||||
|
||||
// Should only be used on types other than Count and NotPseudoClass
|
||||
static void PseudoTypeToString(Type aType, nsAString& aString);
|
||||
|
||||
static bool IsEnabled(Type aType, EnabledState aEnabledState)
|
||||
{
|
||||
auto index = static_cast<size_t>(aType);
|
||||
MOZ_ASSERT(index < static_cast<size_t>(Type::Count));
|
||||
if (sPseudoClassEnabled[index] ||
|
||||
aEnabledState == EnabledState::eIgnoreEnabledState) {
|
||||
return true;
|
||||
}
|
||||
auto flags = kPseudoClassFlags[index];
|
||||
if (((aEnabledState & EnabledState::eInChrome) &&
|
||||
(flags & CSS_PSEUDO_CLASS_ENABLED_IN_CHROME)) ||
|
||||
((aEnabledState & EnabledState::eInUASheets) &&
|
||||
(flags & CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks whether the given pseudo class matches the element.
|
||||
// It returns Some(result) if this function is able to check
|
||||
// the pseudo-class, Nothing() otherwise.
|
||||
static mozilla::Maybe<bool>
|
||||
MatchesElement(Type aType, const mozilla::dom::Element* aElement);
|
||||
|
||||
/**
|
||||
* Checks if a function-like ident-containing pseudo (:pseudo(ident))
|
||||
* matches a given element.
|
||||
*
|
||||
* Returns true if it parses and matches, Some(false) if it
|
||||
* parses but does not match. Asserts if it fails to parse; only
|
||||
* call this when you're sure it's a string-like pseudo.
|
||||
*
|
||||
* In Servo mode, please ensure that UpdatePossiblyStaleDocumentState()
|
||||
* has been called first.
|
||||
*
|
||||
* @param aElement The element we are trying to match
|
||||
* @param aPseudo The name of the pseudoselector
|
||||
* @param aString The identifier inside the pseudoselector (cannot be null)
|
||||
* @param aDocument The document
|
||||
* @param aStateMask Mask containing states which we should exclude.
|
||||
* Ignored if aDependence is null
|
||||
* @param aDependence Pointer to be set to true if we ignored a state due to
|
||||
* aStateMask. Can be null.
|
||||
*/
|
||||
static bool StringPseudoMatches(const mozilla::dom::Element* aElement,
|
||||
mozilla::CSSPseudoClassType aPseudo,
|
||||
const char16_t* aString,
|
||||
const nsIDocument* aDocument,
|
||||
mozilla::EventStates aStateMask,
|
||||
bool* const aDependence = nullptr);
|
||||
|
||||
static bool LangPseudoMatches(const mozilla::dom::Element* aElement,
|
||||
const nsAtom* aOverrideLang,
|
||||
bool aHasOverrideLang,
|
||||
const char16_t* aString,
|
||||
const nsIDocument* aDocument);
|
||||
|
||||
static const mozilla::EventStates sPseudoClassStateDependences[size_t(Type::Count) + 2];
|
||||
|
||||
private:
|
||||
static const uint32_t kPseudoClassFlags[size_t(Type::Count)];
|
||||
static bool sPseudoClassEnabled[size_t(Type::Count)];
|
||||
};
|
||||
|
||||
#endif /* nsCSSPseudoClasses_h___ */
|
|
@ -4549,7 +4549,6 @@ ArenaCollection::GetById(arena_id_t aArenaId, bool aIsPrivate)
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
template<>
|
||||
inline arena_id_t
|
||||
MozJemalloc::moz_create_arena_with_params(arena_params_t* aParams)
|
||||
|
@ -4565,6 +4564,10 @@ template<>
|
|||
inline void
|
||||
MozJemalloc::moz_dispose_arena(arena_id_t aArenaId)
|
||||
{
|
||||
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
||||
// We want to catch any such occurances of that behavior.
|
||||
MOZ_CRASH("Do not call moz_dispose_arena until Bug 1364359 is fixed.");
|
||||
|
||||
arena_t* arena = gArenas.GetById(aArenaId, /* IsPrivate = */ true);
|
||||
MOZ_RELEASE_ASSERT(arena);
|
||||
gArenas.DisposeArena(arena);
|
||||
|
@ -4582,20 +4585,6 @@ MozJemalloc::moz_dispose_arena(arena_id_t aArenaId)
|
|||
#define MALLOC_FUNCS MALLOC_FUNCS_MALLOC_BASE
|
||||
#include "malloc_decls.h"
|
||||
|
||||
#else
|
||||
|
||||
#define MALLOC_DECL(name, return_type, ...) \
|
||||
template<> \
|
||||
inline return_type MozJemalloc::name(ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
|
||||
{ \
|
||||
return DummyArenaAllocator<MozJemalloc>::name( \
|
||||
ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
|
||||
}
|
||||
#define MALLOC_FUNCS MALLOC_FUNCS_ARENA
|
||||
#include "malloc_decls.h"
|
||||
|
||||
#endif
|
||||
|
||||
// End non-standard functions.
|
||||
// ***************************************************************************
|
||||
// Begin library-private functions, used by threading libraries for protection
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "gtest/gtest.h"
|
||||
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
#if defined(DEBUG) && !defined(XP_WIN) && !defined(ANDROID)
|
||||
#define HAS_GDB_SLEEP_DURATION 1
|
||||
extern unsigned int _gdb_sleep_duration;
|
||||
|
@ -41,7 +40,7 @@ static void DisableCrashReporter()
|
|||
#else
|
||||
#define ASSERT_DEATH_WRAP(a, b)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -255,7 +254,6 @@ TEST(Jemalloc, PtrInfo)
|
|||
jemalloc_thread_local_arena(false);
|
||||
}
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
size_t sSizes[] = { 1, 42, 79, 918, 1.5_KiB,
|
||||
73_KiB, 129_KiB, 1.1_MiB, 2.6_MiB, 5.1_MiB };
|
||||
|
||||
|
@ -271,7 +269,8 @@ TEST(Jemalloc, Arenas)
|
|||
ptr = moz_arena_calloc(arena, 24, 2);
|
||||
// For convenience, free can be used to free arena pointers.
|
||||
free(ptr);
|
||||
moz_dispose_arena(arena);
|
||||
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
||||
// moz_dispose_arena(arena);
|
||||
|
||||
#ifdef HAS_GDB_SLEEP_DURATION
|
||||
// Avoid death tests adding some unnecessary (long) delays.
|
||||
|
@ -280,13 +279,15 @@ TEST(Jemalloc, Arenas)
|
|||
#endif
|
||||
|
||||
// Can't use an arena after it's disposed.
|
||||
ASSERT_DEATH_WRAP(moz_arena_malloc(arena, 80), "");
|
||||
// ASSERT_DEATH_WRAP(moz_arena_malloc(arena, 80), "");
|
||||
|
||||
// Arena id 0 can't be used to somehow get to the main arena.
|
||||
ASSERT_DEATH_WRAP(moz_arena_malloc(0, 80), "");
|
||||
|
||||
arena = moz_create_arena();
|
||||
arena_id_t arena2 = moz_create_arena();
|
||||
// Ensure arena2 is used to prevent OSX errors:
|
||||
(void)arena2;
|
||||
|
||||
// For convenience, realloc can also be used to reallocate arena pointers.
|
||||
// The result should be in the same arena. Test various size class transitions.
|
||||
|
@ -305,8 +306,10 @@ TEST(Jemalloc, Arenas)
|
|||
}
|
||||
}
|
||||
|
||||
moz_dispose_arena(arena2);
|
||||
moz_dispose_arena(arena);
|
||||
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
||||
// moz_dispose_arena(arena2);
|
||||
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
||||
// moz_dispose_arena(arena);
|
||||
|
||||
#ifdef HAS_GDB_SLEEP_DURATION
|
||||
_gdb_sleep_duration = old_gdb_sleep_duration;
|
||||
|
@ -429,7 +432,8 @@ TEST(Jemalloc, InPlace)
|
|||
}
|
||||
}
|
||||
|
||||
moz_dispose_arena(arena);
|
||||
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
||||
// moz_dispose_arena(arena);
|
||||
}
|
||||
|
||||
TEST(Jemalloc, JunkPoison)
|
||||
|
@ -610,10 +614,11 @@ TEST(Jemalloc, JunkPoison)
|
|||
}
|
||||
}
|
||||
|
||||
moz_dispose_arena(arena);
|
||||
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
||||
// moz_dispose_arena(arena);
|
||||
|
||||
moz_arena_free(buf_arena, poison_buf);
|
||||
moz_arena_free(buf_arena, junk_buf);
|
||||
moz_dispose_arena(buf_arena);
|
||||
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
||||
// moz_dispose_arena(buf_arena);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -3062,9 +3062,6 @@ pref("layout.css.prefixes.webkit", true);
|
|||
// pref is set to false.)
|
||||
pref("layout.css.prefixes.device-pixel-ratio-webkit", false);
|
||||
|
||||
// Is support for the :scope selector enabled?
|
||||
pref("layout.css.scope-pseudo.enabled", true);
|
||||
|
||||
// Is support for background-blend-mode enabled?
|
||||
pref("layout.css.background-blend-mode.enabled", true);
|
||||
|
||||
|
|
|
@ -62,24 +62,6 @@ interface nsISAXXMLReader : nsIStreamListener {
|
|||
*/
|
||||
attribute nsISAXErrorHandler errorHandler;
|
||||
|
||||
/**
|
||||
* @param str The UTF16 string to be parsed
|
||||
* @param contentType The content type of the string (see parseFromStream)
|
||||
*/
|
||||
void parseFromString(in AString str, in string contentType);
|
||||
|
||||
/**
|
||||
* @param stream The byte stream whose contents are parsed
|
||||
* @param charset The character set that was used to encode the byte
|
||||
* stream. NULL if not specified.
|
||||
* @param contentType The content type of the string - either text/xml,
|
||||
* application/xml, or application/xhtml+xml.
|
||||
* Must not be NULL.
|
||||
*/
|
||||
void parseFromStream(in nsIInputStream stream,
|
||||
in string charset,
|
||||
in string contentType);
|
||||
|
||||
/**
|
||||
* Begin an asynchronous parse. This method initializes the parser,
|
||||
* and must be called before any nsIStreamListener methods. It is
|
||||
|
|
|
@ -241,112 +241,6 @@ nsSAXXMLReader::SetErrorHandler(nsISAXErrorHandler *aErrorHandler)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSAXXMLReader::ParseFromString(const nsAString &aStr,
|
||||
const char *aContentType)
|
||||
{
|
||||
// Don't call this in the middle of an async parse
|
||||
NS_ENSURE_TRUE(!mIsAsyncParse, NS_ERROR_FAILURE);
|
||||
|
||||
NS_ConvertUTF16toUTF8 data(aStr);
|
||||
|
||||
// The new stream holds a reference to the buffer
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
|
||||
data.get(), data.Length(),
|
||||
NS_ASSIGNMENT_DEPEND);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return ParseFromStream(stream, "UTF-8", aContentType);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSAXXMLReader::ParseFromStream(nsIInputStream *aStreamPtr,
|
||||
const char *aCharset,
|
||||
const char *aContentType)
|
||||
{
|
||||
// Don't call this in the middle of an async parse
|
||||
NS_ENSURE_TRUE(!mIsAsyncParse, NS_ERROR_FAILURE);
|
||||
|
||||
NS_ENSURE_ARG(aStreamPtr);
|
||||
NS_ENSURE_ARG(aContentType);
|
||||
|
||||
// Put the nsCOMPtr out here so we hold a ref to the stream as needed
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIInputStream> stream = aStreamPtr;
|
||||
if (!NS_InputStreamIsBuffered(stream)) {
|
||||
nsCOMPtr<nsIInputStream> bufferedStream;
|
||||
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
|
||||
stream.forget(), 4096);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
stream = bufferedStream;
|
||||
}
|
||||
|
||||
rv = EnsureBaseURI();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> nullPrincipal = NullPrincipal::Create();
|
||||
|
||||
// The following channel is never openend, so it does not matter what
|
||||
// securityFlags we pass; let's follow the principle of least privilege.
|
||||
nsCOMPtr<nsIChannel> parserChannel;
|
||||
nsCOMPtr<nsIInputStream> tmpStream = stream;
|
||||
rv = NS_NewInputStreamChannel(getter_AddRefs(parserChannel),
|
||||
mBaseURI,
|
||||
tmpStream.forget(),
|
||||
nullPrincipal,
|
||||
nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
|
||||
nsIContentPolicy::TYPE_OTHER,
|
||||
nsDependentCString(aContentType));
|
||||
if (!parserChannel || NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aCharset)
|
||||
parserChannel->SetContentCharset(nsDependentCString(aCharset));
|
||||
|
||||
rv = InitParser(nullptr, parserChannel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mListener->OnStartRequest(parserChannel, nullptr);
|
||||
if (NS_FAILED(rv))
|
||||
parserChannel->Cancel(rv);
|
||||
|
||||
nsresult status;
|
||||
parserChannel->GetStatus(&status);
|
||||
|
||||
uint64_t offset = 0;
|
||||
while (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
|
||||
uint64_t available;
|
||||
rv = stream->Available(&available);
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
rv = NS_OK;
|
||||
available = 0;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
parserChannel->Cancel(rv);
|
||||
break;
|
||||
}
|
||||
if (! available)
|
||||
break; // blocking input stream has none available when done
|
||||
|
||||
if (available > UINT32_MAX)
|
||||
available = UINT32_MAX;
|
||||
|
||||
rv = mListener->OnDataAvailable(parserChannel, nullptr,
|
||||
stream,
|
||||
offset,
|
||||
(uint32_t)available);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
offset += available;
|
||||
else
|
||||
parserChannel->Cancel(rv);
|
||||
parserChannel->GetStatus(&status);
|
||||
}
|
||||
rv = mListener->OnStopRequest(parserChannel, nullptr, status);
|
||||
mListener = nullptr;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSAXXMLReader::ParseAsync(nsIRequestObserver *aObserver)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
function updateDocumentSourceMaps(source) {
|
||||
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
function updateDocumentSourceMaps(src) {
|
||||
const nsIDOMNode = Ci.nsIDOMNode;
|
||||
|
||||
const nsISAXXMLReader = Ci.nsISAXXMLReader;
|
||||
|
@ -76,7 +78,34 @@ function updateDocumentSourceMaps(source) {
|
|||
saxReader.contentHandler = contentHandler;
|
||||
saxReader.errorHandler = errorHandler;
|
||||
|
||||
saxReader.parseFromString(source, "application/xml");
|
||||
let type = "application/xml";
|
||||
let uri = NetUtil.newURI("http://example.org/");
|
||||
|
||||
let sStream = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||
.createInstance(Ci.nsIStringInputStream);
|
||||
sStream.setData(src, src.length);
|
||||
var bStream = Cc["@mozilla.org/network/buffered-input-stream;1"]
|
||||
.createInstance(Ci.nsIBufferedInputStream);
|
||||
bStream.init(sStream, 4096);
|
||||
|
||||
let channel = Cc["@mozilla.org/network/input-stream-channel;1"].
|
||||
createInstance(Ci.nsIInputStreamChannel);
|
||||
channel.setURI(uri);
|
||||
channel.contentStream = bStream;
|
||||
channel.QueryInterface(Ci.nsIChannel);
|
||||
channel.contentType = type;
|
||||
|
||||
saxReader.parseAsync(null, uri);
|
||||
saxReader.onStartRequest(channel, uri);
|
||||
|
||||
let pos = 0;
|
||||
let count = bStream.available();
|
||||
while (count > 0) {
|
||||
saxReader.onDataAvailable(channel, null, bStream, pos, count);
|
||||
pos += count;
|
||||
count = bStream.available();
|
||||
}
|
||||
saxReader.onStopRequest(channel, null, Cr.NS_OK);
|
||||
|
||||
// Just in case it leaks.
|
||||
saxReader.contentHandler = null;
|
||||
|
@ -97,6 +126,7 @@ function run_test() {
|
|||
src = "<!DOCTYPE foo>\n<!-- all your foo are belong to bar -->";
|
||||
src += "<foo id='foo'>\n<?foo wooly bully?>\nfoo";
|
||||
src += "<![CDATA[foo fighters]]></foo>\n";
|
||||
|
||||
var parseErrorLog = updateDocumentSourceMaps(src);
|
||||
|
||||
if (parseErrorLog.length > 0) {
|
||||
|
|
|
@ -1172,16 +1172,13 @@ class PackageFrontend(MachCommandBase):
|
|||
state_dir = self._mach_context.state_dir
|
||||
cache_dir = os.path.join(state_dir, 'package-frontend')
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
build_obj = MozbuildObject.from_environment(cwd=here)
|
||||
|
||||
hg = None
|
||||
if conditions.is_hg(build_obj):
|
||||
hg = build_obj.substs['HG']
|
||||
if conditions.is_hg(self):
|
||||
hg = self.substs['HG']
|
||||
|
||||
git = None
|
||||
if conditions.is_git(build_obj):
|
||||
git = build_obj.substs['GIT']
|
||||
if conditions.is_git(self):
|
||||
git = self.substs['GIT']
|
||||
|
||||
from mozbuild.artifacts import Artifacts
|
||||
artifacts = Artifacts(tree, self.substs, self.defines, job,
|
||||
|
|
|
@ -25,58 +25,6 @@
|
|||
|
||||
using namespace mozilla;
|
||||
|
||||
/* Object Identifier constants */
|
||||
#define CONST_OID static const unsigned char
|
||||
#define MICROSOFT_OID 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0x37
|
||||
#define PKIX_OID 0x2b, 0x6, 0x01, 0x05, 0x05, 0x07
|
||||
CONST_OID msCertExtCerttype[] = { MICROSOFT_OID, 20, 2 };
|
||||
CONST_OID msNTPrincipalName[] = { MICROSOFT_OID, 20, 2, 3 };
|
||||
CONST_OID msCertsrvCAVersion[] = { MICROSOFT_OID, 21, 1 };
|
||||
CONST_OID msNTDSReplication[] = { MICROSOFT_OID, 25, 1 };
|
||||
CONST_OID pkixLogotype[] = { PKIX_OID, 1, 12 };
|
||||
|
||||
#define OI(x) \
|
||||
{ \
|
||||
siDEROID, (unsigned char*)x, sizeof x \
|
||||
}
|
||||
#define OD(oid, desc, mech, ext) \
|
||||
{ \
|
||||
OI(oid), SEC_OID_UNKNOWN, desc, mech, ext \
|
||||
}
|
||||
#define SEC_OID(tag) more_oids[tag].offset
|
||||
|
||||
static SECOidData more_oids[] = {
|
||||
/* Microsoft OIDs */
|
||||
#define MS_CERT_EXT_CERTTYPE 0
|
||||
OD(msCertExtCerttype,
|
||||
"Microsoft Certificate Template Name",
|
||||
CKM_INVALID_MECHANISM,
|
||||
INVALID_CERT_EXTENSION),
|
||||
|
||||
#define MS_NT_PRINCIPAL_NAME 1
|
||||
OD(msNTPrincipalName,
|
||||
"Microsoft Principal Name",
|
||||
CKM_INVALID_MECHANISM,
|
||||
INVALID_CERT_EXTENSION),
|
||||
|
||||
#define MS_CERTSERV_CA_VERSION 2
|
||||
OD(msCertsrvCAVersion,
|
||||
"Microsoft CA Version",
|
||||
CKM_INVALID_MECHANISM,
|
||||
INVALID_CERT_EXTENSION),
|
||||
|
||||
#define MS_NTDS_REPLICATION 3
|
||||
OD(msNTDSReplication,
|
||||
"Microsoft Domain GUID",
|
||||
CKM_INVALID_MECHANISM,
|
||||
INVALID_CERT_EXTENSION),
|
||||
|
||||
#define PKIX_LOGOTYPE 4
|
||||
OD(pkixLogotype, "Logotype", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
|
||||
};
|
||||
|
||||
static const unsigned int numOids = (sizeof more_oids) / (sizeof more_oids[0]);
|
||||
|
||||
static nsresult
|
||||
GetPIPNSSBundle(nsIStringBundle** pipnssBundle)
|
||||
{
|
||||
|
@ -591,20 +539,8 @@ GetOIDText(SECItem* oid, nsAString& text)
|
|||
bundlekey = "CertDumpECsect571r1";
|
||||
break;
|
||||
default:
|
||||
if (oidTag == SEC_OID(MS_CERT_EXT_CERTTYPE)) {
|
||||
bundlekey = "CertDumpMSCerttype";
|
||||
break;
|
||||
}
|
||||
if (oidTag == SEC_OID(MS_CERTSERV_CA_VERSION)) {
|
||||
bundlekey = "CertDumpMSCAVersion";
|
||||
break;
|
||||
}
|
||||
if (oidTag == SEC_OID(PKIX_LOGOTYPE)) {
|
||||
bundlekey = "CertDumpLogotype";
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
}
|
||||
|
||||
if (bundlekey) {
|
||||
rv = GetPIPNSSBundleString(bundlekey, text);
|
||||
|
@ -944,24 +880,6 @@ AppendBMPtoUTF16(const UniquePLArenaPool& arena,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ProcessBMPString(SECItem* extData, nsAString& text)
|
||||
{
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
if (!arena) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SECItem item;
|
||||
if (SEC_ASN1DecodeItem(
|
||||
arena.get(), &item, SEC_ASN1_GET(SEC_BMPStringTemplate), extData) !=
|
||||
SECSuccess) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return AppendBMPtoUTF16(arena, item.data, item.len, text);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ProcessGeneralName(const UniquePLArenaPool& arena, CERTGeneralName* current,
|
||||
nsAString& text)
|
||||
|
@ -973,69 +891,13 @@ ProcessGeneralName(const UniquePLArenaPool& arena, CERTGeneralName* current,
|
|||
nsresult rv = NS_OK;
|
||||
|
||||
switch (current->type) {
|
||||
case certOtherName: {
|
||||
SECOidTag oidTag = SECOID_FindOIDTag(¤t->name.OthName.oid);
|
||||
if (oidTag == SEC_OID(MS_NT_PRINCIPAL_NAME)) {
|
||||
/* The type of this name is apparently nowhere explicitly
|
||||
documented. However, in the generated templates, it is always
|
||||
UTF-8. So try to decode this as UTF-8; if that fails, dump the
|
||||
raw data. */
|
||||
SECItem decoded;
|
||||
GetPIPNSSBundleString("CertDumpMSNTPrincipal", key);
|
||||
if (SEC_ASN1DecodeItem(arena.get(),
|
||||
&decoded,
|
||||
SEC_ASN1_GET(SEC_UTF8StringTemplate),
|
||||
¤t->name.OthName.name) == SECSuccess) {
|
||||
AppendUTF8toUTF16(nsAutoCString((char*)decoded.data, decoded.len),
|
||||
value);
|
||||
} else {
|
||||
ProcessRawBytes(¤t->name.OthName.name, value);
|
||||
}
|
||||
break;
|
||||
} else if (oidTag == SEC_OID(MS_NTDS_REPLICATION)) {
|
||||
/* This should be a 16-byte GUID */
|
||||
SECItem guid;
|
||||
GetPIPNSSBundleString("CertDumpMSDomainGUID", key);
|
||||
if (SEC_ASN1DecodeItem(arena.get(),
|
||||
&guid,
|
||||
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
||||
¤t->name.OthName.name) == SECSuccess &&
|
||||
guid.len == 16) {
|
||||
char buf[40];
|
||||
unsigned char* d = guid.data;
|
||||
SprintfLiteral(buf,
|
||||
"{%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%"
|
||||
".2x%.2x%.2x%.2x%.2x}",
|
||||
d[3],
|
||||
d[2],
|
||||
d[1],
|
||||
d[0],
|
||||
d[5],
|
||||
d[4],
|
||||
d[7],
|
||||
d[6],
|
||||
d[8],
|
||||
d[9],
|
||||
d[10],
|
||||
d[11],
|
||||
d[12],
|
||||
d[13],
|
||||
d[14],
|
||||
d[15]);
|
||||
value.AssignASCII(buf);
|
||||
} else {
|
||||
ProcessRawBytes(¤t->name.OthName.name, value);
|
||||
}
|
||||
} else {
|
||||
rv = GetDefaultOIDFormat(
|
||||
¤t->name.OthName.oid, key, ' ');
|
||||
case certOtherName:
|
||||
rv = GetDefaultOIDFormat(¤t->name.OthName.oid, key, ' ');
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
ProcessRawBytes(¤t->name.OthName.name, value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case certRFC822Name:
|
||||
GetPIPNSSBundleString("CertDumpRFC822Name", key);
|
||||
value.AssignASCII((char*)current->name.other.data,
|
||||
|
@ -1493,38 +1355,6 @@ ProcessAuthInfoAccess(SECItem* extData, nsAString& text)
|
|||
return rv;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ProcessMSCAVersion(SECItem* extData, nsAString& text)
|
||||
{
|
||||
MOZ_ASSERT(extData);
|
||||
NS_ENSURE_ARG(extData);
|
||||
|
||||
ScopedAutoSECItem decoded;
|
||||
if (SEC_ASN1DecodeItem(
|
||||
nullptr, &decoded, SEC_ASN1_GET(SEC_IntegerTemplate), extData) !=
|
||||
SECSuccess) {
|
||||
/* This extension used to be an Integer when this code
|
||||
was written, but apparently isn't anymore. Display
|
||||
the raw bytes instead. */
|
||||
return ProcessRawBytes(extData, text);
|
||||
}
|
||||
|
||||
unsigned long version;
|
||||
if (SEC_ASN1DecodeInteger(&decoded, &version) != SECSuccess) {
|
||||
/* Value out of range, display raw bytes */
|
||||
return ProcessRawBytes(extData, text);
|
||||
}
|
||||
|
||||
/* Apparently, the encoding is <minor><major>, with 16 bits each */
|
||||
char buf[50];
|
||||
if (SprintfLiteral(buf, "%lu.%lu", version & 0xFFFF, version >> 16) <= 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
text.AppendASCII(buf);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ProcessExtensionData(SECOidTag oidTag, SECItem* extData, nsAString& text)
|
||||
{
|
||||
|
@ -1559,14 +1389,6 @@ ProcessExtensionData(SECOidTag oidTag, SECItem* extData, nsAString& text)
|
|||
rv = ProcessAuthInfoAccess(extData, text);
|
||||
break;
|
||||
default:
|
||||
if (oidTag == SEC_OID(MS_CERT_EXT_CERTTYPE)) {
|
||||
rv = ProcessBMPString(extData, text);
|
||||
break;
|
||||
}
|
||||
if (oidTag == SEC_OID(MS_CERTSERV_CA_VERSION)) {
|
||||
rv = ProcessMSCAVersion(extData, text);
|
||||
break;
|
||||
}
|
||||
rv = ProcessRawBytes(extData, text);
|
||||
break;
|
||||
}
|
||||
|
@ -1809,34 +1631,9 @@ ProcessExtensions(CERTCertExtension** extensions,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool registered;
|
||||
static SECStatus
|
||||
RegisterDynamicOids()
|
||||
{
|
||||
unsigned int i;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
if (registered)
|
||||
return rv;
|
||||
|
||||
for (i = 0; i < numOids; i++) {
|
||||
SECOidTag tag = SECOID_AddEntry(&more_oids[i]);
|
||||
if (tag == SEC_OID_UNKNOWN) {
|
||||
rv = SECFailure;
|
||||
continue;
|
||||
}
|
||||
more_oids[i].offset = tag;
|
||||
}
|
||||
registered = true;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSSCertificate::CreateTBSCertificateASN1Struct(nsIASN1Sequence** retSequence)
|
||||
{
|
||||
if (RegisterDynamicOids() != SECSuccess)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
//
|
||||
// TBSCertificate ::= SEQUENCE {
|
||||
// version [0] EXPLICIT Version DEFAULT v1,
|
||||
|
|
|
@ -11,6 +11,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "categoryManager",
|
|||
"@mozilla.org/categorymanager;1",
|
||||
"nsICategoryManager");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "resProto",
|
||||
"@mozilla.org/network/protocol;1?name=resource",
|
||||
"nsISubstitutingProtocolHandler");
|
||||
|
||||
const Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
|
||||
const CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1";
|
||||
|
@ -89,9 +93,11 @@ TPSCmdLine.prototype = {
|
|||
|
||||
function startup(data, reason) {
|
||||
TPSCmdLine.prototype.register();
|
||||
resProto.setSubstitution("tps", Services.io.newURI("resource", null, data.resourceURI));
|
||||
}
|
||||
|
||||
function shutdown(data, reason) {
|
||||
resProto.setSubstitution("tps", null);
|
||||
TPSCmdLine.prototype.unregister();
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
resource tps resource/
|
|
@ -15,7 +15,7 @@
|
|||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>24.0.*</em:minVersion>
|
||||
<em:maxVersion>31.0.*</em:maxVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
|
|
@ -1635,7 +1635,7 @@ dependencies = [
|
|||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashglobe 0.1.0",
|
||||
"mozjs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozjs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"selectors 0.19.0",
|
||||
"serde_bytes 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_arc 0.1.1",
|
||||
|
@ -1813,7 +1813,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mozjs"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2490,6 +2490,7 @@ dependencies = [
|
|||
"hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jstraceable_derive 0.0.1",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2501,7 +2502,7 @@ dependencies = [
|
|||
"mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozjs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozjs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3903,7 +3904,7 @@ dependencies = [
|
|||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||
"checksum mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9de3eca27871df31c33b807f834b94ef7d000956f57aa25c5aed9c5f0aae8f6f"
|
||||
"checksum mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1f0583e6792917f498bb3a7440f777a59353102063445ab7f5e9d1dc4ed593aa"
|
||||
"checksum mozjs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ab870a85b83df2a5def5a941e5a50493994da0989067b16ab254ce1c770add"
|
||||
"checksum mozjs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71268984a252907b3ee8c7dec2c0dffcf6acaba8af35a45865fa7626bc393c38"
|
||||
"checksum mozjs_sys 0.50.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e61a792a125b1364c5ec50255ed8343ce02dc56098f8868dd209d472c8de006a"
|
||||
"checksum mp3-metadata 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ab5f1d2693586420208d1200ce5a51cd44726f055b635176188137aff42c7de"
|
||||
"checksum mp4parse 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f821e3799bc0fd16d9b861fb02fa7ee1b5fba29f45ad591dade105c48ca9a1a0"
|
||||
|
|
|
@ -23,7 +23,7 @@ app_units = "0.6"
|
|||
cssparser = "0.23.0"
|
||||
euclid = "0.17"
|
||||
hashglobe = { path = "../hashglobe" }
|
||||
mozjs = { version = "0.4", features = ["promises"], optional = true }
|
||||
mozjs = { version = "0.5.0", features = ["promises"], optional = true }
|
||||
selectors = { path = "../selectors" }
|
||||
serde_bytes = { version = "0.10", optional = true }
|
||||
servo_arc = { path = "../servo_arc" }
|
||||
|
|
|
@ -52,6 +52,7 @@ hyper = "0.10"
|
|||
hyper_serde = "0.8"
|
||||
image = "0.18"
|
||||
ipc-channel = "0.10"
|
||||
itertools = "0.7.6"
|
||||
jstraceable_derive = {path = "../jstraceable_derive"}
|
||||
lazy_static = "1"
|
||||
libc = "0.2"
|
||||
|
@ -62,7 +63,7 @@ metrics = {path = "../metrics"}
|
|||
mitochondria = "1.1.2"
|
||||
mime = "0.2.1"
|
||||
mime_guess = "1.8.0"
|
||||
mozjs = { version = "0.4", features = ["promises"]}
|
||||
mozjs = { version = "0.5.0", features = ["promises"]}
|
||||
msg = {path = "../msg"}
|
||||
net_traits = {path = "../net_traits"}
|
||||
num-traits = "0.1.32"
|
||||
|
|
|
@ -16,8 +16,10 @@ use js::jsapi::Heap;
|
|||
use js::jsapi::JSContext;
|
||||
use js::jsapi::JSObject;
|
||||
use js::jsapi::JS_ClearPendingException;
|
||||
use js::jsapi::JS_GetPendingException;
|
||||
use js::jsapi::JS_ParseJSON;
|
||||
use js::jsapi::Value as JSValue;
|
||||
use js::jsval::JSVal;
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::typedarray::{ArrayBuffer, CreateWith};
|
||||
use mime::{Mime, TopLevel, SubLevel};
|
||||
|
@ -42,6 +44,7 @@ pub enum FetchedData {
|
|||
BlobData(DomRoot<Blob>),
|
||||
FormData(DomRoot<FormData>),
|
||||
ArrayBuffer(RootedTraceableBox<Heap<*mut JSObject>>),
|
||||
JSException(RootedTraceableBox<Heap<JSVal>>)
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-body-consume-body
|
||||
|
@ -90,7 +93,8 @@ pub fn consume_body_with_promise<T: BodyOperations + DomObject>(object: &T,
|
|||
FetchedData::Json(j) => promise.resolve_native(&j),
|
||||
FetchedData::BlobData(b) => promise.resolve_native(&b),
|
||||
FetchedData::FormData(f) => promise.resolve_native(&f),
|
||||
FetchedData::ArrayBuffer(a) => promise.resolve_native(&a)
|
||||
FetchedData::ArrayBuffer(a) => promise.resolve_native(&a),
|
||||
FetchedData::JSException(e) => promise.reject_native(&e.handle()),
|
||||
};
|
||||
},
|
||||
Err(err) => promise.reject_error(err),
|
||||
|
@ -133,9 +137,10 @@ fn run_json_data_algorithm(cx: *mut JSContext,
|
|||
json_text.as_ptr(),
|
||||
json_text.len() as u32,
|
||||
rval.handle_mut()) {
|
||||
rooted!(in(cx) let mut exception = UndefinedValue());
|
||||
assert!(JS_GetPendingException(cx, exception.handle_mut()));
|
||||
JS_ClearPendingException(cx);
|
||||
// TODO: See issue #13464. Exception should be thrown instead of cleared.
|
||||
return Err(Error::Type("Failed to parse JSON".to_string()));
|
||||
return Ok(FetchedData::JSException(RootedTraceableBox::from_box(Heap::boxed(exception.get()))));
|
||||
}
|
||||
let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(rval.get()));
|
||||
Ok(FetchedData::Json(rooted_heap))
|
||||
|
|
|
@ -107,7 +107,6 @@ extern crate xml5ever;
|
|||
|
||||
#[macro_use]
|
||||
mod task;
|
||||
|
||||
mod body;
|
||||
pub mod clipboard_provider;
|
||||
mod devtools;
|
||||
|
@ -150,7 +149,10 @@ pub mod layout_exports {
|
|||
}
|
||||
|
||||
use dom::bindings::codegen::RegisterBindings;
|
||||
use dom::bindings::conversions::is_dom_proxy;
|
||||
use dom::bindings::proxyhandler;
|
||||
use dom::bindings::utils::is_platform_object;
|
||||
use js::jsapi::JSObject;
|
||||
use script_traits::SWManagerSenders;
|
||||
use serviceworker_manager::ServiceWorkerManager;
|
||||
|
||||
|
@ -200,6 +202,11 @@ pub fn init_service_workers(sw_senders: SWManagerSenders) {
|
|||
ServiceWorkerManager::spawn_manager(sw_senders);
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe extern "C" fn is_dom_object(obj: *mut JSObject) -> bool {
|
||||
!obj.is_null() && (is_platform_object(obj) || is_dom_proxy(obj))
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub fn init() {
|
||||
unsafe {
|
||||
|
@ -208,6 +215,8 @@ pub fn init() {
|
|||
// Create the global vtables used by the (generated) DOM
|
||||
// bindings to implement JS proxies.
|
||||
RegisterBindings::RegisterProxyHandlers();
|
||||
|
||||
js::glue::InitializeMemoryReporter(Some(is_dom_object));
|
||||
}
|
||||
|
||||
perform_platform_specific_initialization();
|
||||
|
|
|
@ -4,24 +4,9 @@
|
|||
|
||||
//! Routines for handling measuring the memory usage of arbitrary DOM nodes.
|
||||
|
||||
use dom::bindings::conversions::get_dom_class;
|
||||
use dom::bindings::reflector::DomObject;
|
||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||
use std::os::raw::c_void;
|
||||
|
||||
// This is equivalent to measuring a Box<T>, except that DOM objects lose their
|
||||
// associated box in order to stash their pointers in a reserved slot of their
|
||||
// JS reflector.
|
||||
#[allow(unsafe_code)]
|
||||
pub fn malloc_size_of_including_self<T: DomObject + MallocSizeOf>(
|
||||
ops: &mut MallocSizeOfOps, obj: &T) -> usize
|
||||
{
|
||||
unsafe {
|
||||
let class = get_dom_class(obj.reflector().get_jsobject().get()).unwrap();
|
||||
(class.malloc_size_of)(ops, obj as *const T as *const c_void)
|
||||
}
|
||||
}
|
||||
|
||||
/// Used by codegen to include the pointer to the `MallocSizeOf` implementation of each
|
||||
/// IDL interface. This way we don't have to find the most-derived interface of DOM
|
||||
/// objects by hand in code.
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
//! script thread, the dom, and the worker threads.
|
||||
|
||||
use dom::bindings::codegen::Bindings::PromiseBinding::PromiseJobCallback;
|
||||
use dom::bindings::conversions::get_dom_class;
|
||||
use dom::bindings::conversions::private_from_object;
|
||||
use dom::bindings::refcounted::{LiveDOMReferences, trace_refcounted_objects};
|
||||
use dom::bindings::root::trace_roots;
|
||||
use dom::bindings::settings_stack;
|
||||
|
@ -21,6 +23,7 @@ use js::jsapi::{JSJitCompilerOption, JS_SetOffthreadIonCompilationEnabled, JS_Se
|
|||
use js::jsapi::{JSObject, RuntimeOptionsRef, SetPreserveWrapperCallback, SetEnqueuePromiseJobCallback};
|
||||
use js::panic::wrap_panic;
|
||||
use js::rust::Runtime as RustRuntime;
|
||||
use malloc_size_of::MallocSizeOfOps;
|
||||
use microtask::{EnqueuedPromiseCallback, Microtask};
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use profile_traits::mem::{Report, ReportKind, ReportsChan};
|
||||
|
@ -312,6 +315,24 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
|
|||
Runtime(runtime)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe extern "C" fn get_size(obj: *mut JSObject) -> usize {
|
||||
match get_dom_class(obj) {
|
||||
Ok(v) => {
|
||||
let dom_object = private_from_object(obj) as *const c_void;
|
||||
|
||||
if dom_object.is_null() {
|
||||
return 0;
|
||||
}
|
||||
let mut ops = MallocSizeOfOps::new(::servo_allocator::usable_size, None, None);
|
||||
(v.malloc_size_of)(&mut ops, dom_object)
|
||||
}
|
||||
Err(_e) => {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub fn get_reports(cx: *mut JSContext, path_seg: String) -> Vec<Report> {
|
||||
let mut reports = vec![];
|
||||
|
@ -319,7 +340,7 @@ pub fn get_reports(cx: *mut JSContext, path_seg: String) -> Vec<Report> {
|
|||
unsafe {
|
||||
let rt = JS_GetRuntime(cx);
|
||||
let mut stats = ::std::mem::zeroed();
|
||||
if CollectServoSizes(rt, &mut stats) {
|
||||
if CollectServoSizes(rt, &mut stats, Some(get_size)) {
|
||||
let mut report = |mut path_suffix, kind, size| {
|
||||
let mut path = path![path_seg, "js"];
|
||||
path.append(&mut path_suffix);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
//! a page runs its course and the script thread returns to processing events in the main event
|
||||
//! loop.
|
||||
|
||||
extern crate itertools;
|
||||
|
||||
use bluetooth_traits::BluetoothRequest;
|
||||
use canvas_traits::webgl::WebGLPipeline;
|
||||
use devtools;
|
||||
|
@ -72,8 +74,6 @@ use js::glue::GetWindowProxyClass;
|
|||
use js::jsapi::{JSAutoCompartment, JSContext, JS_SetWrapObjectCallbacks};
|
||||
use js::jsapi::{JSTracer, SetWindowProxyClass};
|
||||
use js::jsval::UndefinedValue;
|
||||
use malloc_size_of::MallocSizeOfOps;
|
||||
use mem::malloc_size_of_including_self;
|
||||
use metrics::{MAX_TASK_NS, PaintTimeMetrics};
|
||||
use microtask::{MicrotaskQueue, Microtask};
|
||||
use msg::constellation_msg::{BrowsingContextId, PipelineId, PipelineNamespace, TopLevelBrowsingContextId};
|
||||
|
@ -82,7 +82,7 @@ use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads};
|
|||
use net_traits::image_cache::{ImageCache, PendingImageResponse};
|
||||
use net_traits::request::{CredentialsMode, Destination, RedirectMode, RequestInit};
|
||||
use net_traits::storage_thread::StorageType;
|
||||
use profile_traits::mem::{self, OpaqueSender, Report, ReportKind, ReportsChan};
|
||||
use profile_traits::mem::{self, OpaqueSender, ReportsChan};
|
||||
use profile_traits::time::{self, ProfilerCategory, profile};
|
||||
use script_layout_interface::message::{self, Msg, NewLayoutThreadInfo, ReflowGoal};
|
||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory};
|
||||
|
@ -1580,34 +1580,11 @@ impl ScriptThread {
|
|||
}
|
||||
|
||||
fn collect_reports(&self, reports_chan: ReportsChan) {
|
||||
let mut path_seg = String::from("url(");
|
||||
let mut dom_tree_size = 0;
|
||||
let documents = self.documents.borrow();
|
||||
let urls = itertools::join(documents.iter().map(|(_, d)| d.url().to_string()), ", ");
|
||||
let path_seg = format!("url({})", urls);
|
||||
|
||||
let mut reports = vec![];
|
||||
// Servo uses vanilla jemalloc, which doesn't have a
|
||||
// malloc_enclosing_size_of function.
|
||||
let mut ops = MallocSizeOfOps::new(::servo_allocator::usable_size, None, None);
|
||||
|
||||
for (_, document) in self.documents.borrow().iter() {
|
||||
let current_url = document.url();
|
||||
|
||||
for child in document.upcast::<Node>().traverse_preorder() {
|
||||
dom_tree_size += malloc_size_of_including_self(&mut ops, &*child);
|
||||
}
|
||||
dom_tree_size += malloc_size_of_including_self(&mut ops, document.window());
|
||||
|
||||
if reports.len() > 0 {
|
||||
path_seg.push_str(", ");
|
||||
}
|
||||
path_seg.push_str(current_url.as_str());
|
||||
|
||||
reports.push(Report {
|
||||
path: path![format!("url({})", current_url.as_str()), "dom-tree"],
|
||||
kind: ReportKind::ExplicitJemallocHeapSize,
|
||||
size: dom_tree_size,
|
||||
});
|
||||
}
|
||||
|
||||
path_seg.push_str(")");
|
||||
reports.extend(get_reports(self.get_cx(), path_seg));
|
||||
reports_chan.send(reports);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@ use gecko_bindings::structs::RawServoSelectorList;
|
|||
use gecko_bindings::structs::RawServoSourceSizeList;
|
||||
use gecko_bindings::structs::RefPtr;
|
||||
use gecko_bindings::structs::RustString;
|
||||
use gecko_bindings::structs::CSSPseudoClassType;
|
||||
use gecko_bindings::structs::CSSPseudoElementType;
|
||||
use gecko_bindings::structs::ServoTraversalFlags;
|
||||
use gecko_bindings::structs::ComputedTimingFunction_BeforeFlag;
|
||||
|
@ -627,12 +626,6 @@ extern "C" {
|
|||
extern "C" {
|
||||
pub fn Gecko_IsRootElement(element: RawGeckoElementBorrowed) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_MatchesElement(
|
||||
type_: CSSPseudoClassType,
|
||||
element: RawGeckoElementBorrowed,
|
||||
) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_MatchLang(
|
||||
element: RawGeckoElementBorrowed,
|
||||
|
@ -647,6 +640,12 @@ extern "C" {
|
|||
extern "C" {
|
||||
pub fn Gecko_GetDocumentLWTheme(aDocument: *const nsIDocument) -> nsIDocument_DocumentTheme;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_IsTableBorderNonzero(element: RawGeckoElementBorrowed) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_IsBrowserFrame(element: RawGeckoElementBorrowed) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_AtomAttrValue(
|
||||
element: RawGeckoElementBorrowed,
|
||||
|
|
|
@ -12267,97 +12267,6 @@ pub mod root {
|
|||
)
|
||||
);
|
||||
}
|
||||
pub type CSSPseudoClassTypeBase = u8;
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum CSSPseudoClassType {
|
||||
empty = 0,
|
||||
mozOnlyWhitespace = 1,
|
||||
lang = 2,
|
||||
root = 3,
|
||||
any = 4,
|
||||
firstChild = 5,
|
||||
firstNode = 6,
|
||||
lastChild = 7,
|
||||
lastNode = 8,
|
||||
onlyChild = 9,
|
||||
firstOfType = 10,
|
||||
lastOfType = 11,
|
||||
onlyOfType = 12,
|
||||
nthChild = 13,
|
||||
nthLastChild = 14,
|
||||
nthOfType = 15,
|
||||
nthLastOfType = 16,
|
||||
mozIsHTML = 17,
|
||||
mozNativeAnonymous = 18,
|
||||
mozUseShadowTreeRoot = 19,
|
||||
mozLocaleDir = 20,
|
||||
mozLWTheme = 21,
|
||||
mozLWThemeBrightText = 22,
|
||||
mozLWThemeDarkText = 23,
|
||||
mozWindowInactive = 24,
|
||||
mozTableBorderNonzero = 25,
|
||||
mozBrowserFrame = 26,
|
||||
scope = 27,
|
||||
negation = 28,
|
||||
dir = 29,
|
||||
link = 30,
|
||||
mozAnyLink = 31,
|
||||
anyLink = 32,
|
||||
visited = 33,
|
||||
active = 34,
|
||||
checked = 35,
|
||||
disabled = 36,
|
||||
enabled = 37,
|
||||
focus = 38,
|
||||
focusWithin = 39,
|
||||
hover = 40,
|
||||
mozDragOver = 41,
|
||||
target = 42,
|
||||
indeterminate = 43,
|
||||
mozDevtoolsHighlighted = 44,
|
||||
mozStyleeditorTransitioning = 45,
|
||||
fullscreen = 46,
|
||||
mozFullScreen = 47,
|
||||
mozFocusRing = 48,
|
||||
mozBroken = 49,
|
||||
mozLoading = 50,
|
||||
mozUserDisabled = 51,
|
||||
mozSuppressed = 52,
|
||||
mozHandlerClickToPlay = 53,
|
||||
mozHandlerVulnerableUpdatable = 54,
|
||||
mozHandlerVulnerableNoUpdate = 55,
|
||||
mozHandlerDisabled = 56,
|
||||
mozHandlerBlocked = 57,
|
||||
mozHandlerCrashed = 58,
|
||||
mozMathIncrementScriptLevel = 59,
|
||||
mozHasDirAttr = 60,
|
||||
mozDirAttrLTR = 61,
|
||||
mozDirAttrRTL = 62,
|
||||
mozDirAttrLikeAuto = 63,
|
||||
mozAutofill = 64,
|
||||
mozAutofillPreview = 65,
|
||||
required = 66,
|
||||
optional = 67,
|
||||
valid = 68,
|
||||
invalid = 69,
|
||||
inRange = 70,
|
||||
outOfRange = 71,
|
||||
defaultPseudo = 72,
|
||||
placeholderShown = 73,
|
||||
mozReadOnly = 74,
|
||||
mozReadWrite = 75,
|
||||
mozSubmitInvalid = 76,
|
||||
mozUIInvalid = 77,
|
||||
mozUIValid = 78,
|
||||
mozMeterOptimum = 79,
|
||||
mozMeterSubOptimum = 80,
|
||||
mozMeterSubSubOptimum = 81,
|
||||
mozPlaceholder = 82,
|
||||
Count = 83,
|
||||
NotPseudo = 84,
|
||||
MAX = 85,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct GeckoFont {
|
||||
pub gecko: root::nsStyleFont,
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
*
|
||||
* :scope -> <style scoped>, pending discussion.
|
||||
*
|
||||
* This follows the order defined in layout/style/nsCSSPseudoClassList.h when
|
||||
* possible.
|
||||
*
|
||||
* $gecko_type can be either "_" or an ident in Gecko's CSSPseudoClassType.
|
||||
* $state can be either "_" or an expression of type ElementState. If present,
|
||||
* the semantics are that the pseudo-class matches if any of the bits in
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use cssparser::{BasicParseError, BasicParseErrorKind, Parser, ToCss, Token, CowRcStr, SourceLocation};
|
||||
use element_state::{DocumentState, ElementState};
|
||||
use gecko_bindings::structs::{self, CSSPseudoClassType};
|
||||
use gecko_bindings::structs;
|
||||
use gecko_bindings::structs::RawServoSelectorList;
|
||||
use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
|
||||
use invalidation::element::document_state::InvalidationMatchingData;
|
||||
|
@ -133,6 +133,22 @@ impl Visit for NonTSPseudoClass {
|
|||
|
||||
|
||||
impl NonTSPseudoClass {
|
||||
/// Parses the name and returns a non-ts-pseudo-class if succeeds.
|
||||
/// None otherwise. It doesn't check whether the pseudo-class is enabled
|
||||
/// in a particular state.
|
||||
pub fn parse_non_functional(name: &str) -> Option<Self> {
|
||||
macro_rules! pseudo_class_parse {
|
||||
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
|
||||
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
|
||||
match_ignore_ascii_case! { &name,
|
||||
$($css => Some(NonTSPseudoClass::$name),)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
apply_non_ts_list!(pseudo_class_parse)
|
||||
}
|
||||
|
||||
/// Returns true if this pseudo-class has any of the given flags set.
|
||||
fn has_any_flag(&self, flags: NonTSPseudoClassFlag) -> bool {
|
||||
macro_rules! check_flag {
|
||||
|
@ -242,28 +258,6 @@ impl NonTSPseudoClass {
|
|||
)
|
||||
}
|
||||
|
||||
/// Convert NonTSPseudoClass to Gecko's CSSPseudoClassType.
|
||||
pub fn to_gecko_pseudoclasstype(&self) -> Option<CSSPseudoClassType> {
|
||||
macro_rules! gecko_type {
|
||||
(_) => (None);
|
||||
($gecko_type:ident) =>
|
||||
(Some(::gecko_bindings::structs::CSSPseudoClassType::$gecko_type));
|
||||
}
|
||||
macro_rules! pseudo_class_geckotype {
|
||||
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
|
||||
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
|
||||
match *self {
|
||||
$(NonTSPseudoClass::$name => gecko_type!($gecko_type),)*
|
||||
$(NonTSPseudoClass::$s_name(..) => gecko_type!($s_gecko_type),)*
|
||||
NonTSPseudoClass::MozLocaleDir(_) => gecko_type!(mozLocaleDir),
|
||||
NonTSPseudoClass::Dir(_) => gecko_type!(dir),
|
||||
NonTSPseudoClass::MozAny(_) => gecko_type!(any),
|
||||
}
|
||||
}
|
||||
}
|
||||
apply_non_ts_list!(pseudo_class_geckotype)
|
||||
}
|
||||
|
||||
/// Returns true if the evaluation of the pseudo-class depends on the
|
||||
/// element's attributes.
|
||||
pub fn is_attr_based(&self) -> bool {
|
||||
|
@ -373,24 +367,13 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
|||
location: SourceLocation,
|
||||
name: CowRcStr<'i>,
|
||||
) -> Result<NonTSPseudoClass, ParseError<'i>> {
|
||||
macro_rules! pseudo_class_parse {
|
||||
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
|
||||
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
|
||||
match_ignore_ascii_case! { &name,
|
||||
$($css => NonTSPseudoClass::$name,)*
|
||||
_ => return Err(location.new_custom_error(
|
||||
SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
let pseudo_class = apply_non_ts_list!(pseudo_class_parse);
|
||||
if let Some(pseudo_class) = NonTSPseudoClass::parse_non_functional(&name) {
|
||||
if self.is_pseudo_class_enabled(&pseudo_class) {
|
||||
Ok(pseudo_class)
|
||||
} else {
|
||||
Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||
return Ok(pseudo_class);
|
||||
}
|
||||
}
|
||||
Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||
}
|
||||
|
||||
fn parse_non_ts_functional_pseudo_class<'t>(
|
||||
&self,
|
||||
|
|
|
@ -32,7 +32,6 @@ use gecko_bindings::bindings;
|
|||
use gecko_bindings::bindings::{Gecko_ConstructStyleChildrenIterator, Gecko_DestroyStyleChildrenIterator};
|
||||
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme};
|
||||
use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetNextStyleChild};
|
||||
use gecko_bindings::bindings::{Gecko_IsRootElement, Gecko_MatchesElement};
|
||||
use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
|
||||
use gecko_bindings::bindings::Gecko_ClassOrClassList;
|
||||
use gecko_bindings::bindings::Gecko_ElementHasAnimations;
|
||||
|
@ -814,6 +813,21 @@ impl<'le> GeckoElement<'le> {
|
|||
(!self.as_node().is_in_shadow_tree() && self.has_xbl_binding_parent())
|
||||
}
|
||||
|
||||
/// Returns true if this node is the shadow root of an use-element shadow tree.
|
||||
#[inline]
|
||||
fn is_root_of_use_element_shadow_tree(&self) -> bool {
|
||||
if !self.is_root_of_anonymous_subtree() {
|
||||
return false
|
||||
}
|
||||
match self.parent_element() {
|
||||
Some(e) => {
|
||||
e.local_name() == &*local_name!("use") &&
|
||||
e.namespace() == &*ns!("http://www.w3.org/2000/svg")
|
||||
},
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn css_transitions_info(&self) -> FnvHashMap<LonghandId, Arc<AnimationValue>> {
|
||||
use gecko_bindings::bindings::Gecko_ElementTransitions_EndValueAt;
|
||||
use gecko_bindings::bindings::Gecko_ElementTransitions_Length;
|
||||
|
@ -1981,7 +1995,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
Gecko_IsRootElement(self.0)
|
||||
bindings::Gecko_IsRootElement(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2103,11 +2117,17 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
}
|
||||
true
|
||||
}
|
||||
NonTSPseudoClass::MozTableBorderNonzero |
|
||||
NonTSPseudoClass::MozBrowserFrame |
|
||||
NonTSPseudoClass::MozNativeAnonymous |
|
||||
NonTSPseudoClass::MozUseShadowTreeRoot => unsafe {
|
||||
Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0)
|
||||
NonTSPseudoClass::MozNativeAnonymous => {
|
||||
self.is_in_native_anonymous_subtree()
|
||||
}
|
||||
NonTSPseudoClass::MozUseShadowTreeRoot => {
|
||||
self.is_root_of_use_element_shadow_tree()
|
||||
}
|
||||
NonTSPseudoClass::MozTableBorderNonzero => unsafe {
|
||||
bindings::Gecko_IsTableBorderNonzero(self.0)
|
||||
}
|
||||
NonTSPseudoClass::MozBrowserFrame => unsafe {
|
||||
bindings::Gecko_IsBrowserFrame(self.0)
|
||||
},
|
||||
NonTSPseudoClass::MozIsHTML => {
|
||||
self.is_html_element_in_html_document()
|
||||
|
@ -2235,20 +2255,10 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
|
||||
#[inline]
|
||||
fn blocks_ancestor_combinators(&self) -> bool {
|
||||
if !self.is_root_of_anonymous_subtree() {
|
||||
return false
|
||||
}
|
||||
|
||||
match self.parent_element() {
|
||||
Some(e) => {
|
||||
// If this element is the shadow root of an use-element shadow
|
||||
// tree, according to the spec, we should not match rules
|
||||
// cross the shadow DOM boundary.
|
||||
e.local_name() == &*local_name!("use") &&
|
||||
e.namespace() == &*ns!("http://www.w3.org/2000/svg")
|
||||
},
|
||||
None => false,
|
||||
}
|
||||
// If this element is the shadow root of an use-element shadow tree,
|
||||
// according to the spec, we should not match rules cross the shadow
|
||||
// DOM boundary.
|
||||
self.is_root_of_use_element_shadow_tree()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ use style::font_metrics::{FontMetricsProvider, get_metrics_provider_for_product}
|
|||
use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyleDataImpl};
|
||||
use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData, STYLE_THREAD_POOL};
|
||||
use style::gecko::restyle_damage::GeckoRestyleDamage;
|
||||
use style::gecko::selector_parser::PseudoElement;
|
||||
use style::gecko::selector_parser::{NonTSPseudoClass, PseudoElement};
|
||||
use style::gecko::traversal::RecalcStyleOnly;
|
||||
use style::gecko::wrapper::{GeckoElement, GeckoNode};
|
||||
use style::gecko_bindings::bindings;
|
||||
|
@ -5115,3 +5115,14 @@ pub extern "C" fn Servo_ParseCounterStyleDescriptor(
|
|||
result,
|
||||
).is_ok()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_PseudoClass_GetStates(name: *const nsACString) -> u64 {
|
||||
let name = name.as_ref().unwrap().as_str_unchecked();
|
||||
match NonTSPseudoClass::parse_non_functional(name) {
|
||||
None => 0,
|
||||
// Ignore :any-link since it contains both visited and unvisited state.
|
||||
Some(NonTSPseudoClass::AnyLink) => 0,
|
||||
Some(pseudo_class) => pseudo_class.state_flag().bits(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1246,19 +1246,6 @@ FeedProcessor.prototype = {
|
|||
},
|
||||
|
||||
// Parsing functions
|
||||
parseFromStream: function FP_parseFromStream(stream, uri) {
|
||||
this._init(uri);
|
||||
this._reader.parseFromStream(stream, null, stream.available(),
|
||||
"application/xml");
|
||||
this._reader = null;
|
||||
},
|
||||
|
||||
parseFromString: function FP_parseFromString(inputString, uri) {
|
||||
this._init(uri);
|
||||
this._reader.parseFromString(inputString, "application/xml");
|
||||
this._reader = null;
|
||||
},
|
||||
|
||||
parseAsync: function FP_parseAsync(requestObserver, uri) {
|
||||
this._init(uri);
|
||||
this._reader.parseAsync(requestObserver);
|
||||
|
|
|
@ -27,22 +27,6 @@ interface nsIFeedProcessor : nsIStreamListener {
|
|||
// XXX todo void registerExtensionHandler(in
|
||||
// nsIFeedExtensionHandler, in long level);
|
||||
|
||||
/**
|
||||
* Parse a feed from an nsIInputStream.
|
||||
*
|
||||
* @param stream The input stream.
|
||||
* @param uri The base URI.
|
||||
*/
|
||||
void parseFromStream(in nsIInputStream stream, in nsIURI uri);
|
||||
|
||||
/**
|
||||
* Parse a feed from a string.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
* @param uri The base URI.
|
||||
*/
|
||||
void parseFromString(in AString str, in nsIURI uri);
|
||||
|
||||
/**
|
||||
* Parse a feed asynchronously. The caller must then call the
|
||||
* nsIFeedProcessor's nsIStreamListener methods to drive the
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
// Listens to feeds being loaded. Runs the tests built into the feed afterwards to veryify they
|
||||
// were parsed correctly.
|
||||
function FeedListener(testcase) {
|
||||
|
@ -67,16 +69,35 @@ function createTest(data) {
|
|||
var parser = Cc["@mozilla.org/feed-processor;1"].createInstance(Ci.nsIFeedProcessor);
|
||||
var stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
|
||||
stream.init(data.file, 0x01, parseInt("0444", 8), 0);
|
||||
var bStream = Cc["@mozilla.org/network/buffered-input-stream;1"].createInstance(Ci.nsIBufferedInputStream);
|
||||
bStream.init(stream, 4096);
|
||||
parser.listener = new FeedListener(data);
|
||||
|
||||
try {
|
||||
parser.parseFromStream(stream, uri);
|
||||
let channel = Cc["@mozilla.org/network/input-stream-channel;1"].
|
||||
createInstance(Ci.nsIInputStreamChannel);
|
||||
channel.setURI(uri);
|
||||
channel.contentStream = bStream;
|
||||
channel.QueryInterface(Ci.nsIChannel);
|
||||
channel.contentType = "text/xml";
|
||||
|
||||
parser.parseAsync(null, uri);
|
||||
parser.onStartRequest(channel, uri);
|
||||
|
||||
let pos = 0;
|
||||
let count = bStream.available();
|
||||
while (count > 0) {
|
||||
parser.onDataAvailable(channel, null, bStream, pos, count);
|
||||
pos += count;
|
||||
count = bStream.available();
|
||||
}
|
||||
parser.onStopRequest(channel, null, Cr.NS_OK);
|
||||
} catch (e) {
|
||||
Assert.ok(false, "parse failed for " + data.file.leafName + " ---- " + e.message);
|
||||
// If the parser failed, the listener won't be notified, run the next test here.
|
||||
run_next_test();
|
||||
} finally {
|
||||
stream.close();
|
||||
bStream.close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче