зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
3c01a01df9
|
@ -159,6 +159,12 @@ var gIdentityHandler = {
|
|||
"identity-popup-mainView-panel-header-span"
|
||||
));
|
||||
},
|
||||
get _identityPopupSecurityView() {
|
||||
delete this._identityPopupSecurityView;
|
||||
return (this._identityPopupSecurityView = document.getElementById(
|
||||
"identity-popup-securityView"
|
||||
));
|
||||
},
|
||||
get _identityPopupSecurityEVContentOwner() {
|
||||
delete this._identityPopupSecurityEVContentOwner;
|
||||
return (this._identityPopupSecurityEVContentOwner = document.getElementById(
|
||||
|
@ -1072,6 +1078,13 @@ var gIdentityHandler = {
|
|||
[host]
|
||||
);
|
||||
|
||||
this._identityPopupSecurityView.setAttribute(
|
||||
"title",
|
||||
gNavigatorBundle.getFormattedString("identity.headerSecurityWithHost", [
|
||||
host,
|
||||
])
|
||||
);
|
||||
|
||||
this._identityPopupSecurityEVContentOwner.textContent = gNavigatorBundle.getFormattedString(
|
||||
"identity.ev.contentOwner",
|
||||
[owner]
|
||||
|
|
|
@ -615,6 +615,9 @@ add_task(async function testQuickSwitchTabAfterTogglingTPSwitch() {
|
|||
"The ETP state of the second tab has been changed to disabled."
|
||||
);
|
||||
|
||||
// Clean up the state of the allow list for the second tab.
|
||||
ContentBlockingAllowList.remove(tabTwo.linkedBrowser);
|
||||
|
||||
BrowserTestUtils.removeTab(tabOne);
|
||||
BrowserTestUtils.removeTab(tabTwo);
|
||||
|
||||
|
|
|
@ -50,6 +50,12 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||
"signon.management.page.breach-alerts.enabled",
|
||||
false
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"FXA_ENABLED",
|
||||
"identity.fxaccounts.enabled",
|
||||
false
|
||||
);
|
||||
|
||||
const ABOUT_LOGINS_ORIGIN = "about:logins";
|
||||
const MASTER_PASSWORD_NOTIFICATION_ID = "master-password-login-required";
|
||||
|
@ -287,9 +293,11 @@ var AboutLoginsParent = {
|
|||
try {
|
||||
messageManager.sendAsyncMessage("AboutLogins:AllLogins", logins);
|
||||
|
||||
let syncState = this.getSyncState();
|
||||
messageManager.sendAsyncMessage("AboutLogins:SyncState", syncState);
|
||||
this.updatePasswordSyncNotificationState();
|
||||
if (FXA_ENABLED) {
|
||||
let syncState = this.getSyncState();
|
||||
messageManager.sendAsyncMessage("AboutLogins:SyncState", syncState);
|
||||
this.updatePasswordSyncNotificationState();
|
||||
}
|
||||
|
||||
// App store badges sourced from https://developer.apple.com/app-store/marketing/guidelines/#section-badges.
|
||||
// This array mirrors the file names from the App store directory (./content/third-party/app-store)
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<header>
|
||||
<img id="branding-logo" src="chrome://branding/content/aboutlogins.svg" alt=""/>
|
||||
<login-filter></login-filter>
|
||||
<fxaccounts-button></fxaccounts-button>
|
||||
<fxaccounts-button hidden></fxaccounts-button>
|
||||
<menu-button></menu-button>
|
||||
</header>
|
||||
<login-list></login-list>
|
||||
|
|
|
@ -7,7 +7,6 @@ export default class FxAccountsButton extends HTMLElement {
|
|||
if (this.shadowRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
let template = document.querySelector("#fxaccounts-button-template");
|
||||
let shadowRoot = this.attachShadow({ mode: "open" });
|
||||
document.l10n.connectRoot(shadowRoot);
|
||||
|
@ -65,6 +64,7 @@ export default class FxAccountsButton extends HTMLElement {
|
|||
* be empty if `loggedIn` is false.
|
||||
*/
|
||||
updateState(state) {
|
||||
this.hidden = false;
|
||||
this._loggedIn = state.loggedIn;
|
||||
this._email = state.email;
|
||||
this._avatarURL = state.avatarURL;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
[DEFAULT]
|
||||
scheme = https
|
||||
prefs =
|
||||
identity.fxaccounts.enabled=true
|
||||
support-files =
|
||||
aboutlogins_common.js
|
||||
|
||||
|
|
|
@ -91,7 +91,6 @@
|
|||
<!-- Security SubView -->
|
||||
<panelview id="identity-popup-securityView"
|
||||
role="document"
|
||||
title="&identity.securityView.label2;"
|
||||
descriptionheightworkaround="true">
|
||||
<vbox class="identity-popup-security-content">
|
||||
<vbox class="identity-popup-security-connection">
|
||||
|
|
|
@ -233,7 +233,7 @@ var CustomizableUIInternal = {
|
|||
];
|
||||
|
||||
if (AppConstants.MOZ_DEV_EDITION) {
|
||||
navbarPlacements.splice(2, 0, "developer-button");
|
||||
navbarPlacements.splice(7, 0, "developer-button");
|
||||
}
|
||||
|
||||
this.registerArea(
|
||||
|
|
|
@ -61,14 +61,7 @@ add_task(async function setup() {
|
|||
|
||||
// Move the mouse away from the results panel, because hovering a result may
|
||||
// change its aspect (e.g. by showing a " - search with Engine" suffix).
|
||||
await new Promise(resolve => {
|
||||
EventUtils.synthesizeNativeMouseMove(
|
||||
window.document.documentElement,
|
||||
0,
|
||||
0,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
await EventUtils.synthesizeNativeMouseMove(gURLBar.inputField);
|
||||
});
|
||||
|
||||
add_task(async function test_tab_switch_result() {
|
||||
|
|
|
@ -670,10 +670,6 @@ you can use these alternative items. Otherwise, their values should be empty. -
|
|||
<!ENTITY editBookmark.showForNewBookmarks.label "Show editor when saving">
|
||||
<!ENTITY editBookmark.showForNewBookmarks.accesskey "S">
|
||||
|
||||
<!-- LOCALIZATION NOTE (identity.securityView.label2)
|
||||
This is the header of the security subview in the Site Identity panel. -->
|
||||
<!ENTITY identity.securityView.label2 "Connection Security">
|
||||
|
||||
<!ENTITY identity.connectionSecure2 "Connection Secure">
|
||||
<!ENTITY identity.connectionNotSecure "Connection Is Not Secure">
|
||||
<!ENTITY identity.connectionNotSecureSecurityView "You are not securely connected to this site.">
|
||||
|
|
|
@ -474,9 +474,10 @@ webauthn.anonymize=Anonymize anyway
|
|||
# Spoof Accept-Language prompt
|
||||
privacy.spoof_english=Changing your language setting to English will make you more difficult to identify and enhance your privacy. Do you want to request English language versions of web pages?
|
||||
|
||||
# LOCALIZATION NOTE (identity.headerMainWithHost):
|
||||
# LOCALIZATION NOTE (identity.headerMainWithHost, identity.headerSecurityWithHost):
|
||||
# %S is the hostname of the site that is being displayed.
|
||||
identity.headerMainWithHost=Site Information for %S
|
||||
identity.headerSecurityWithHost=Connection Security for %S
|
||||
identity.identified.verifier=Verified by: %S
|
||||
identity.identified.verified_by_you=You have added a security exception for this site.
|
||||
identity.identified.state_and_country=%S, %S
|
||||
|
|
|
@ -165,9 +165,9 @@ endif
|
|||
|
||||
ifeq ($(HOST_OS_ARCH),WINNT)
|
||||
HOST_PDBFILE=$(basename $(@F)).pdb
|
||||
HOST_PDB_FLAG ?= -Fd$(HOST_PDBFILE)
|
||||
HOST_C_LDFLAGS += $(HOST_PDB_FLAG)
|
||||
HOST_CXX_LDFLAGS += $(HOST_PDB_FLAG)
|
||||
HOST_PDB_FLAG ?= -PDB:$(HOST_PDBFILE)
|
||||
HOST_C_LDFLAGS += -DEBUG $(HOST_PDB_FLAG)
|
||||
HOST_CXX_LDFLAGS += -DEBUG $(HOST_PDB_FLAG)
|
||||
endif
|
||||
|
||||
# Don't build SIMPLE_PROGRAMS during the MOZ_PROFILE_GENERATE pass, and do not
|
||||
|
|
|
@ -28,18 +28,14 @@ support-files =
|
|||
|
||||
[browser_aboutdebugging_addons_debug_console.js]
|
||||
tags = webextensions
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_addons_debug_debugger.js]
|
||||
tags = webextensions
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_addons_debug_inspector.js]
|
||||
tags = webextensions
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_addons_debug_nobg.js]
|
||||
tags = webextensions
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_addons_debug_popup.js]
|
||||
skip-if = fission || (verify && debug) || (debug && os == "linux" && bits == 64) # verify: crashes on shutdown, timeouts linux debug Bug 1299001
|
||||
skip-if = (verify && debug) || (debug && os == "linux" && bits == 64) # verify: crashes on shutdown, timeouts linux debug Bug 1299001
|
||||
tags = webextensions
|
||||
[browser_aboutdebugging_addons_manifest_url.js]
|
||||
skip-if = (os == 'linux' && bits == 32) || (os == 'mac' && debug) # ADB start() fails on linux 32, see Bug 1499638, macosx1014 debug due to 1514751
|
||||
|
@ -59,40 +55,30 @@ skip-if = (os == 'linux' && bits == 32) # ADB start() fails on linux 32, see Bug
|
|||
[browser_aboutdebugging_debug-target-pane_collapsibilities_interaction.js]
|
||||
[browser_aboutdebugging_debug-target-pane_collapsibilities_preference.js]
|
||||
[browser_aboutdebugging_debug-target-pane_empty.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_debug-target-pane_usb_runtime.js]
|
||||
[browser_aboutdebugging_devtools.js]
|
||||
[browser_aboutdebugging_devtoolstoolbox_contextmenu.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_devtoolstoolbox_contextmenu_markupview.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_devtoolstoolbox_focus.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_devtoolstoolbox_menubar.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_devtoolstoolbox_performance.js]
|
||||
skip-if = fission || os == 'linux' && e10s && (asan || debug) # Same skip-if as old perf panel test suite. Bug 1254821
|
||||
skip-if = os == 'linux' && e10s && (asan || debug) # Same skip-if as old perf panel test suite. Bug 1254821
|
||||
[browser_aboutdebugging_devtoolstoolbox_reload.js]
|
||||
skip-if = fission || verify || ccov || (os == 'linux' && debug) #bug 1544828, test loads the toolbox 2 times for each panel, might timeout or OOM
|
||||
skip-if = verify || ccov || (os == 'linux' && debug) #bug 1544828, test loads the toolbox 2 times for each panel, might timeout or OOM
|
||||
[browser_aboutdebugging_devtoolstoolbox_shortcuts.js]
|
||||
skip-if = fission || ccov || (os == 'linux' && bits == 64) # Bug 1521349, Bug 1548015, Bug 1544828
|
||||
skip-if = ccov || (os == 'linux' && bits == 64) # Bug 1521349, Bug 1548015, Bug 1544828
|
||||
[browser_aboutdebugging_devtoolstoolbox_splitconsole_key.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_devtoolstoolbox_target_destroyed.js]
|
||||
skip-if = fission || debug || asan # This test leaks. See bug 1529005
|
||||
skip-if = debug || asan # This test leaks. See bug 1529005
|
||||
[browser_aboutdebugging_devtoolstoolbox_tooltip_markupview.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_fenix_runtime_display.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_message_close.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_navigate.js]
|
||||
[browser_aboutdebugging_persist_connection.js]
|
||||
[browser_aboutdebugging_process_category.js]
|
||||
[browser_aboutdebugging_process_main.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_process_main_local.js]
|
||||
skip-if = fission || debug
|
||||
skip-if = debug
|
||||
[browser_aboutdebugging_profiler_dialog.js]
|
||||
[browser_aboutdebugging_real_usb_runtime_page_runtime_info.js]
|
||||
[browser_aboutdebugging_real_usb_sidebar.js]
|
||||
|
@ -113,7 +99,7 @@ skip-if = debug || asan || serviceworker_e10s # Frequent intermittent failures,
|
|||
[browser_aboutdebugging_serviceworker_start.js]
|
||||
[browser_aboutdebugging_serviceworker_status.js]
|
||||
[browser_aboutdebugging_serviceworker_timeout.js]
|
||||
skip-if = fission || debug || asan # Frequent intermittent failures, Bug 1522800
|
||||
skip-if = debug || asan # Frequent intermittent failures, Bug 1522800
|
||||
[browser_aboutdebugging_serviceworker_unregister.js]
|
||||
[browser_aboutdebugging_sidebar_connection_state.js]
|
||||
[browser_aboutdebugging_sidebar_network_runtimes.js]
|
||||
|
@ -129,7 +115,6 @@ skip-if = fission || debug || asan # Frequent intermittent failures, Bug 1522800
|
|||
[browser_aboutdebugging_telemetry_basic.js]
|
||||
[browser_aboutdebugging_telemetry_connection_attempt.js]
|
||||
[browser_aboutdebugging_telemetry_inspect.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_telemetry_navigate.js]
|
||||
[browser_aboutdebugging_telemetry_runtime_actions.js]
|
||||
[browser_aboutdebugging_telemetry_runtime_connected_details.js]
|
||||
|
@ -139,5 +124,4 @@ skip-if = fission
|
|||
[browser_aboutdebugging_thisfirefox.js]
|
||||
[browser_aboutdebugging_thisfirefox_runtime_info.js]
|
||||
[browser_aboutdebugging_thisfirefox_worker_inspection.js]
|
||||
skip-if = fission
|
||||
[browser_aboutdebugging_workers_remote_runtime.js]
|
||||
|
|
|
@ -257,12 +257,6 @@ async function toolboxTestScript(toolbox, devtoolsTab) {
|
|||
|
||||
const waitForNavigated = toolbox.target.once("navigate");
|
||||
popupFrameBtn.click();
|
||||
// Clicking the menu item may do highlighting.
|
||||
await waitUntil(() => toolbox.highlighter);
|
||||
await Promise.race([
|
||||
toolbox.highlighter.once("node-highlight"),
|
||||
wait(1000),
|
||||
]);
|
||||
await waitForNavigated;
|
||||
consoleWrapper.dispatchEvaluateExpression(
|
||||
"myWebExtensionPopupAddonFunction()"
|
||||
|
|
|
@ -192,20 +192,22 @@ class Accessible extends Component {
|
|||
this.setState({ expanded });
|
||||
}
|
||||
|
||||
showHighlighter(nodeFront) {
|
||||
async showHighlighter(nodeFront) {
|
||||
if (!gToolbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
gToolbox.highlighter.highlight(nodeFront);
|
||||
const { highlighterFront } = nodeFront;
|
||||
await highlighterFront.highlight(nodeFront);
|
||||
}
|
||||
|
||||
hideHighlighter() {
|
||||
async hideHighlighter(nodeFront) {
|
||||
if (!gToolbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
gToolbox.highlighter.unhighlight();
|
||||
const { highlighterFront } = nodeFront;
|
||||
await highlighterFront.unhighlight();
|
||||
}
|
||||
|
||||
showAccessibleHighlighter(accessible) {
|
||||
|
@ -288,7 +290,8 @@ class Accessible extends Component {
|
|||
|
||||
if (isNode(object)) {
|
||||
valueProps.defaultRep = ElementNode;
|
||||
valueProps.onDOMNodeMouseOut = () => this.hideHighlighter();
|
||||
valueProps.onDOMNodeMouseOut = () =>
|
||||
this.hideHighlighter(this.props.DOMNode);
|
||||
valueProps.onDOMNodeMouseOver = () =>
|
||||
this.showHighlighter(this.props.DOMNode);
|
||||
valueProps.onInspectIconClick = () => this.selectNode(this.props.DOMNode);
|
||||
|
|
|
@ -24,8 +24,10 @@ async function getNodeFront(gripOrFront, toolbox) {
|
|||
if ("actorID" in gripOrFront) {
|
||||
return new Promise(resolve => resolve(gripOrFront));
|
||||
}
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
// Given a grip
|
||||
return toolbox.walker.gripToNodeFront(gripOrFront);
|
||||
const walkerFront = (await toolbox.target.getFront("inspector")).walker;
|
||||
return walkerFront.gripToNodeFront(gripOrFront);
|
||||
}
|
||||
|
||||
DebuggerPanel.prototype = {
|
||||
|
@ -91,7 +93,6 @@ DebuggerPanel.prototype = {
|
|||
},
|
||||
|
||||
openElementInInspector: async function(gripOrFront) {
|
||||
await this.toolbox.initInspector();
|
||||
const onSelectInspector = this.toolbox.selectTool("inspector");
|
||||
const onGripNodeToFront = getNodeFront(gripOrFront, this.toolbox);
|
||||
|
||||
|
@ -109,18 +110,18 @@ DebuggerPanel.prototype = {
|
|||
},
|
||||
|
||||
highlightDomElement: async function(gripOrFront) {
|
||||
await this.toolbox.initInspector();
|
||||
if (!this.toolbox.highlighter) {
|
||||
return null;
|
||||
}
|
||||
const front = await getNodeFront(gripOrFront, this.toolbox);
|
||||
return this.toolbox.highlighter.highlight(front);
|
||||
const nodeFront = await getNodeFront(gripOrFront, this.toolbox);
|
||||
nodeFront.highlighterFront.highlight(nodeFront);
|
||||
},
|
||||
|
||||
unHighlightDomElement: function() {
|
||||
return this.toolbox.highlighter
|
||||
? this.toolbox.highlighter.unhighlight(false)
|
||||
: null;
|
||||
unHighlightDomElement: async function(gripOrFront) {
|
||||
try {
|
||||
const nodeFront = await getNodeFront(gripOrFront, this.toolbox);
|
||||
nodeFront.highlighterFront.unhighlight();
|
||||
} catch (e) {
|
||||
// This call might fail if called asynchrously after the toolbox is finished
|
||||
// closing.
|
||||
}
|
||||
},
|
||||
|
||||
getFrames: function() {
|
||||
|
|
|
@ -89,6 +89,13 @@ export default class ColumnBreakpoint extends PureComponent<Props> {
|
|||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const { cx, columnBreakpoint, breakpointActions } = this.props;
|
||||
|
||||
// disable column breakpoint on shift-click.
|
||||
if (event.shiftKey) {
|
||||
const breakpoint: breakpoint = columnBreakpoint.breakpoint;
|
||||
return breakpointActions.toggleDisabledBreakpoint(cx, breakpoint);
|
||||
}
|
||||
|
||||
if (columnBreakpoint.breakpoint) {
|
||||
breakpointActions.removeBreakpoint(cx, columnBreakpoint.breakpoint);
|
||||
} else {
|
||||
|
|
|
@ -23,6 +23,24 @@ async function enableSecondBreakpoint(dbg) {
|
|||
await waitForAllElements(dbg, "breakpointItems", 2);
|
||||
}
|
||||
|
||||
// disable active column bp with shift-click.
|
||||
async function shiftClickDisable(dbg) {
|
||||
let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints");
|
||||
debugger;
|
||||
shiftClickElement(dbg, "columnBreakpoints");
|
||||
bpMarkers = findAllElements(dbg, "columnBreakpoints");
|
||||
debugger;
|
||||
assertClass(bpMarkers[0], "disabled");
|
||||
}
|
||||
|
||||
// re-enable disabled column bp with shift-click.
|
||||
async function shiftClickEnable(dbg) {
|
||||
let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints");
|
||||
shiftClickElement(dbg, "columnBreakpoints");
|
||||
bpMarkers = findAllElements(dbg, "columnBreakpoints");
|
||||
assertClass(bpMarkers[0], "active");
|
||||
}
|
||||
|
||||
async function setConditionalBreakpoint(dbg, index, condition) {
|
||||
let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints");
|
||||
rightClickEl(dbg, bpMarkers[index]);
|
||||
|
@ -84,21 +102,27 @@ add_task(async function() {
|
|||
info("2. Click on the second breakpoint on line 32");
|
||||
await enableSecondBreakpoint(dbg);
|
||||
|
||||
info("3. Add a condition to the first breakpoint");
|
||||
info("3. Disable second breakpoint using shift-click");
|
||||
await shiftClickDisable(dbg);
|
||||
|
||||
info("4. Re-enable second breakpoint using shift-click");
|
||||
await shiftClickEnable(dbg);
|
||||
|
||||
info("5. Add a condition to the first breakpoint");
|
||||
await setConditionalBreakpoint(dbg, 0, "foo");
|
||||
|
||||
info("4. Add a log to the first breakpoint");
|
||||
info("6. Add a log to the first breakpoint");
|
||||
await setLogPoint(dbg, 0, "bar");
|
||||
|
||||
info("5. Disable the first breakpoint");
|
||||
info("7. Disable the first breakpoint");
|
||||
await disableBreakpoint(dbg, 0);
|
||||
|
||||
info("6. Remove the first breakpoint");
|
||||
info("8. Remove the first breakpoint");
|
||||
await removeFirstBreakpoint(dbg);
|
||||
|
||||
info("7. Add a condition to the second breakpoint");
|
||||
info("9. Add a condition to the second breakpoint");
|
||||
await setConditionalBreakpoint(dbg, 1, "foo2");
|
||||
|
||||
info("8. test removing the breakpoints by clicking in the gutter");
|
||||
info("10. Test removing the breakpoints by clicking in the gutter");
|
||||
await removeAllBreakpoints(dbg, 32, 0);
|
||||
});
|
||||
|
|
|
@ -77,25 +77,26 @@ class DomTree extends Component {
|
|||
const toolbox = DomProvider.getToolbox();
|
||||
if (toolbox) {
|
||||
onDOMNodeMouseOver = async (grip, options = {}) => {
|
||||
await toolbox.initInspector();
|
||||
if (!toolbox.highlighter) {
|
||||
return null;
|
||||
}
|
||||
const nodeFront = await toolbox.walker.gripToNodeFront(grip);
|
||||
return toolbox.highlighter.highlight(nodeFront, options);
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
const walkerFront = (await toolbox.target.getFront("inspector")).walker;
|
||||
const nodeFront = await walkerFront.gripToNodeFront(grip);
|
||||
const { highlighterFront } = nodeFront;
|
||||
return highlighterFront.highlight(nodeFront, options);
|
||||
};
|
||||
onDOMNodeMouseOut = (forceHide = false) => {
|
||||
return toolbox.highlighter
|
||||
? toolbox.highlighter.unhighlight(forceHide)
|
||||
: null;
|
||||
onDOMNodeMouseOut = async grip => {
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
const walkerFront = (await toolbox.target.getFront("inspector")).walker;
|
||||
const nodeFront = await walkerFront.gripToNodeFront(grip);
|
||||
nodeFront.highlighterFront.unhighlight();
|
||||
};
|
||||
onInspectIconClick = async grip => {
|
||||
await toolbox.initInspector();
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
const walkerFront = (await toolbox.target.getFront("inspector")).walker;
|
||||
const onSelectInspector = toolbox.selectTool(
|
||||
"inspector",
|
||||
"inspect_dom"
|
||||
);
|
||||
const onGripNodeToFront = toolbox.walker.gripToNodeFront(grip);
|
||||
const onGripNodeToFront = walkerFront.gripToNodeFront(grip);
|
||||
const [front, inspector] = await Promise.all([
|
||||
onGripNodeToFront,
|
||||
onSelectInspector,
|
||||
|
|
|
@ -31,7 +31,7 @@ add_task(async function() {
|
|||
is(nodeFront.displayName, "h1", "The correct node was highlighted");
|
||||
|
||||
info("Unhighlight the node by moving away from the node");
|
||||
let onNodeUnhighlight = toolbox.highlighter.once("node-unhighlight");
|
||||
let onNodeUnhighlight = inspectorFront.highlighter.once("node-unhighlight");
|
||||
const btn = toolbox.doc.querySelector("#toolbox-meatball-menu-button");
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
btn,
|
||||
|
@ -56,7 +56,7 @@ add_task(async function() {
|
|||
},
|
||||
node.ownerDocument.defaultView
|
||||
);
|
||||
onNodeHighlight = toolbox.highlighter.once("node-highlight");
|
||||
onNodeHighlight = inspectorFront.highlighter.once("node-highlight");
|
||||
nodeFront = await onNodeHighlight;
|
||||
is(nodeFront.displayName, "h2", "The correct node was highlighted");
|
||||
|
||||
|
@ -68,7 +68,7 @@ add_task(async function() {
|
|||
},
|
||||
btn.ownerDocument.defaultView
|
||||
);
|
||||
onNodeUnhighlight = toolbox.highlighter.once("node-unhighlight");
|
||||
onNodeUnhighlight = inspectorFront.highlighter.once("node-unhighlight");
|
||||
await onNodeUnhighlight;
|
||||
ok(true, "node-unhighlight event was fired when moving away from the node");
|
||||
});
|
||||
|
|
|
@ -272,10 +272,11 @@ class ToolboxToolbar extends Component {
|
|||
}`,
|
||||
ref: "frameMenuButton",
|
||||
title: description,
|
||||
onCloseButton: async () => {
|
||||
onCloseButton: () => {
|
||||
// Only try to unhighlight if the highlighter has been started
|
||||
if (toolbox.highlighter) {
|
||||
toolbox.highlighter.unhighlight();
|
||||
const inspectorFront = toolbox.target.getCachedFront("inspector");
|
||||
if (inspectorFront) {
|
||||
inspectorFront.highlighter.unhighlight();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -512,14 +512,6 @@ Toolbox.prototype = {
|
|||
return this.win.document;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the toolbox highlighter front. Note that it may not always have been
|
||||
* initialized first. Use `initInspector()` if needed.
|
||||
*/
|
||||
get highlighter() {
|
||||
return this._highlighter;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the toolbox's inspector front. Note that it may not always have been
|
||||
* initialized first. Use `initInspector()` if needed.
|
||||
|
@ -2980,14 +2972,14 @@ Toolbox.prototype = {
|
|||
* Highlight a frame in the page
|
||||
*/
|
||||
onHighlightFrame: async function(frameId) {
|
||||
// Need to initInspector to check presence of getNodeActorFromWindowID
|
||||
// and use the highlighter later
|
||||
await this.initInspector();
|
||||
const inspectorFront = await this.target.getFront("inspector");
|
||||
|
||||
// Only enable frame highlighting when the top level document is targeted
|
||||
if (this.rootFrameSelected) {
|
||||
const frameActor = await this.walker.getNodeActorFromWindowID(frameId);
|
||||
this.highlighter.highlight(frameActor);
|
||||
const frameActor = await inspectorFront.walker.getNodeActorFromWindowID(
|
||||
frameId
|
||||
);
|
||||
inspectorFront.highlighter.highlight(frameActor);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -3334,7 +3326,6 @@ Toolbox.prototype = {
|
|||
// TODO: remove these bindings
|
||||
this._inspector = await this.target.getFront("inspector");
|
||||
this._walker = this.inspectorFront.walker;
|
||||
this._highlighter = this.inspectorFront.highlighter;
|
||||
this.nodePicker = new NodePicker(this.target, this.selection);
|
||||
|
||||
this.nodePicker.on("picker-starting", this._onPickerStarting);
|
||||
|
@ -3371,16 +3362,14 @@ Toolbox.prototype = {
|
|||
return {
|
||||
highlight: async (nodeFront, options) => {
|
||||
pendingHighlight = (async () => {
|
||||
await this.initInspector();
|
||||
if (!this.highlighter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (fromGrip) {
|
||||
nodeFront = await this.walker.gripToNodeFront(nodeFront);
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
const walkerFront = (await this.target.getFront("inspector"))
|
||||
.walker;
|
||||
nodeFront = await walkerFront.gripToNodeFront(nodeFront);
|
||||
}
|
||||
|
||||
return this.highlighter.highlight(nodeFront, options);
|
||||
return nodeFront.highlighterFront.highlight(nodeFront, options);
|
||||
})();
|
||||
return pendingHighlight;
|
||||
},
|
||||
|
@ -3390,8 +3379,9 @@ Toolbox.prototype = {
|
|||
pendingHighlight = null;
|
||||
}
|
||||
|
||||
return this.highlighter
|
||||
? this.highlighter.unhighlight(forceHide)
|
||||
const inspectorFront = this.target.getCachedFront("inspector");
|
||||
return inspectorFront
|
||||
? inspectorFront.highlighter.unhighlight(forceHide)
|
||||
: null;
|
||||
},
|
||||
};
|
||||
|
@ -3460,7 +3450,6 @@ Toolbox.prototype = {
|
|||
this._inspector.destroy();
|
||||
|
||||
this._inspector = null;
|
||||
this._highlighter = null;
|
||||
this._walker = null;
|
||||
},
|
||||
|
||||
|
|
|
@ -21,17 +21,16 @@ add_task(async function() {
|
|||
animationInspector,
|
||||
inspector,
|
||||
panel,
|
||||
toolbox,
|
||||
} = await openAnimationInspector();
|
||||
|
||||
info("Check highlighting when mouse over on a target node");
|
||||
const onHighlight = toolbox.highlighter.once("node-highlight");
|
||||
const onHighlight = inspector.highlighter.once("node-highlight");
|
||||
mouseOverOnTargetNode(animationInspector, panel, 0);
|
||||
let nodeFront = await onHighlight;
|
||||
assertNodeFront(nodeFront, "DIV", "ball animated");
|
||||
|
||||
info("Check unhighlighting when mouse out on a target node");
|
||||
const onUnhighlight = toolbox.highlighter.once("node-unhighlight");
|
||||
const onUnhighlight = inspector.highlighter.once("node-unhighlight");
|
||||
mouseOutOnTargetNode(animationInspector, panel, 0);
|
||||
await onUnhighlight;
|
||||
ok(true, "Unhighlighted the targe node");
|
||||
|
@ -65,11 +64,11 @@ add_task(async function() {
|
|||
const highlightEventCounter = () => {
|
||||
highlightEventCount += 1;
|
||||
};
|
||||
toolbox.highlighter.on("node-highlight", highlightEventCounter);
|
||||
inspector.highlighter.on("node-highlight", highlightEventCounter);
|
||||
mouseOverOnTargetNode(animationInspector, panel, 0);
|
||||
await wait(500);
|
||||
is(highlightEventCount, 0, "Highlight event should not occur");
|
||||
toolbox.highlighter.off("node-highlight", highlightEventCounter);
|
||||
inspector.highlighter.off("node-highlight", highlightEventCounter);
|
||||
|
||||
info("Highlighting another animation target");
|
||||
onHighlighterShown = inspector.highlighters.once(
|
||||
|
|
|
@ -20,11 +20,11 @@ var highlightedNodeFront, highlighterOptions;
|
|||
|
||||
add_task(async function() {
|
||||
await addTab(TEST_URL);
|
||||
const { toolbox, inspector, boxmodel } = await openLayoutView();
|
||||
const { inspector, boxmodel } = await openLayoutView();
|
||||
await selectNode("div", inspector);
|
||||
|
||||
// Mock the highlighter by replacing the showBoxModel method.
|
||||
toolbox.highlighter.showBoxModel = function(nodeFront, options) {
|
||||
inspector.highlighter.showBoxModel = function(nodeFront, options) {
|
||||
highlightedNodeFront = nodeFront;
|
||||
highlighterOptions = options;
|
||||
};
|
||||
|
|
|
@ -84,15 +84,18 @@ class ExtensionSidebar {
|
|||
this.inspector.toolbox.target.client.release(actor);
|
||||
},
|
||||
highlightDomElement: async (grip, options = {}) => {
|
||||
const { highlighter } = this.inspector;
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
const nodeFront = await this.inspector.walker.gripToNodeFront(
|
||||
grip
|
||||
);
|
||||
return highlighter.highlight(nodeFront, options);
|
||||
return nodeFront.highlighterFront.highlight(nodeFront, options);
|
||||
},
|
||||
unHighlightDomElement: (forceHide = false) => {
|
||||
const { highlighter } = this.inspector;
|
||||
return highlighter.unhighlight(forceHide);
|
||||
unHighlightDomElement: async grip => {
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
const nodeFront = await this.inspector.walker.gripToNodeFront(
|
||||
grip
|
||||
);
|
||||
return nodeFront.highlighterFront.unhighlight();
|
||||
},
|
||||
openNodeInInspector: async grip => {
|
||||
const { walker } = this.inspector;
|
||||
|
|
|
@ -227,7 +227,7 @@ add_task(async function testSidebarDOMNodeHighlighting() {
|
|||
// Test highlight DOMNode on mouseover.
|
||||
info("Highlight the node by moving the cursor on it");
|
||||
|
||||
const onNodeHighlight = toolbox.highlighter.once("node-highlight");
|
||||
const onNodeHighlight = inspector.highlighter.once("node-highlight");
|
||||
|
||||
moveMouseOnObjectInspectorDOMNode(sidebarPanelContent);
|
||||
|
||||
|
@ -236,7 +236,7 @@ add_task(async function testSidebarDOMNodeHighlighting() {
|
|||
|
||||
// Test unhighlight DOMNode on mousemove.
|
||||
info("Unhighlight the node by moving away from the node");
|
||||
const onNodeUnhighlight = toolbox.highlighter.once("node-unhighlight");
|
||||
const onNodeUnhighlight = inspector.highlighter.once("node-unhighlight");
|
||||
|
||||
moveMouseOnPanelCenter(sidebarPanelContent);
|
||||
|
||||
|
@ -266,8 +266,8 @@ add_task(async function testSidebarDOMNodeOpenInspector() {
|
|||
|
||||
// Once we click the open-inspector icon we expect a new node front to be selected
|
||||
// and the node to have been highlighted and unhighlighted.
|
||||
const onNodeHighlight = toolbox.highlighter.once("node-highlight");
|
||||
const onNodeUnhighlight = toolbox.highlighter.once("node-unhighlight");
|
||||
const onNodeHighlight = inspector.highlighter.once("node-highlight");
|
||||
const onNodeUnhighlight = inspector.highlighter.once("node-unhighlight");
|
||||
onceNewNodeFront = inspector.selection.once("new-node-front");
|
||||
|
||||
clickOpenInspectorIcon(sidebarPanelContent);
|
||||
|
|
|
@ -10,7 +10,7 @@ const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html";
|
|||
|
||||
add_task(async function() {
|
||||
await addTab(TEST_URI);
|
||||
const { inspector, flexboxInspector, toolbox } = await openLayoutView();
|
||||
const { inspector, flexboxInspector } = await openLayoutView();
|
||||
const { document: doc } = flexboxInspector;
|
||||
|
||||
const onFlexContainerRepRendered = waitForDOM(
|
||||
|
@ -23,7 +23,7 @@ add_task(async function() {
|
|||
ok(flexContainerRep, "The flex container element rep is rendered.");
|
||||
|
||||
info("Listen to node-highlight event and mouse over the rep");
|
||||
const onHighlight = toolbox.highlighter.once("node-highlight");
|
||||
const onHighlight = inspector.highlighter.once("node-highlight");
|
||||
EventUtils.synthesizeMouse(
|
||||
flexContainerRep,
|
||||
10,
|
||||
|
|
|
@ -20,7 +20,7 @@ const TEST_URI = `
|
|||
|
||||
add_task(async function() {
|
||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
const { inspector, gridInspector, toolbox } = await openLayoutView();
|
||||
const { inspector, gridInspector } = await openLayoutView();
|
||||
const { document: doc } = gridInspector;
|
||||
const { store } = inspector;
|
||||
|
||||
|
@ -30,7 +30,7 @@ add_task(async function() {
|
|||
elementRep.scrollIntoView();
|
||||
|
||||
info("Listen to node-highlight event and mouse over the widget");
|
||||
const onHighlight = toolbox.highlighter.once("node-highlight");
|
||||
const onHighlight = inspector.highlighter.once("node-highlight");
|
||||
EventUtils.synthesizeMouse(
|
||||
elementRep,
|
||||
10,
|
||||
|
|
|
@ -481,7 +481,7 @@ SelectorAutocompleter.prototype = {
|
|||
* Suggests classes,ids and tags based on the user input as user types in the
|
||||
* searchbox.
|
||||
*/
|
||||
showSuggestions: function() {
|
||||
showSuggestions: async function() {
|
||||
let query = this.searchBox.value;
|
||||
const state = this.state;
|
||||
let firstPart = "";
|
||||
|
@ -514,37 +514,51 @@ SelectorAutocompleter.prototype = {
|
|||
query += "*";
|
||||
}
|
||||
|
||||
const suggestionsPromise = this.walker.getSuggestionsForQuery(
|
||||
query,
|
||||
firstPart,
|
||||
state
|
||||
);
|
||||
this._lastQuery = suggestionsPromise.then(result => {
|
||||
this.emit("processing-done");
|
||||
if (result.query !== query) {
|
||||
// This means that this response is for a previous request and the user
|
||||
// as since typed something extra leading to a new request.
|
||||
return promise.resolve(null);
|
||||
}
|
||||
const inspectorFront = this.inspector.inspectorFront;
|
||||
const remoteInspectors = await inspectorFront.getChildInspectors();
|
||||
const inspectors = [inspectorFront, ...remoteInspectors];
|
||||
|
||||
if (state === this.States.CLASS) {
|
||||
firstPart = "." + firstPart;
|
||||
} else if (state === this.States.ID) {
|
||||
firstPart = "#" + firstPart;
|
||||
}
|
||||
|
||||
// If there is a single tag match and it's what the user typed, then
|
||||
// don't need to show a popup.
|
||||
if (
|
||||
result.suggestions.length === 1 &&
|
||||
result.suggestions[0][0] === firstPart
|
||||
) {
|
||||
result.suggestions = [];
|
||||
}
|
||||
|
||||
// Wait for the autocomplete-popup to fire its popup-opened event, to make sure
|
||||
// the autoSelect item has been selected.
|
||||
return this._showPopup(result.suggestions, state);
|
||||
const suggestionsPromises = inspectors.map(async inspector => {
|
||||
const walker = inspector.walker;
|
||||
return walker.getSuggestionsForQuery(query, firstPart, state);
|
||||
});
|
||||
|
||||
this._lastQuery = Promise.all(suggestionsPromises)
|
||||
.then(suggestions => {
|
||||
// Merge all the results
|
||||
const result = { query: "", suggestions: [] };
|
||||
for (const r of suggestions) {
|
||||
result.query = r.query;
|
||||
result.suggestions = result.suggestions.concat(r.suggestions);
|
||||
}
|
||||
return result;
|
||||
})
|
||||
.then(result => {
|
||||
this.emit("processing-done");
|
||||
if (result.query !== query) {
|
||||
// This means that this response is for a previous request and the user
|
||||
// as since typed something extra leading to a new request.
|
||||
return promise.resolve(null);
|
||||
}
|
||||
|
||||
if (state === this.States.CLASS) {
|
||||
firstPart = "." + firstPart;
|
||||
} else if (state === this.States.ID) {
|
||||
firstPart = "#" + firstPart;
|
||||
}
|
||||
|
||||
// If there is a single tag match and it's what the user typed, then
|
||||
// don't need to show a popup.
|
||||
if (
|
||||
result.suggestions.length === 1 &&
|
||||
result.suggestions[0][0] === firstPart
|
||||
) {
|
||||
result.suggestions = [];
|
||||
}
|
||||
|
||||
// Wait for the autocomplete-popup to fire its popup-opened event, to make sure
|
||||
// the autoSelect item has been selected.
|
||||
return this._showPopup(result.suggestions, state);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1822,11 +1822,11 @@ Inspector.prototype = {
|
|||
* Options passed to the highlighter actor.
|
||||
*/
|
||||
onShowBoxModelHighlighterForNode(nodeFront, options) {
|
||||
const toolbox = this.toolbox;
|
||||
toolbox.highlighter.highlight(nodeFront, options);
|
||||
nodeFront.highlighterFront.highlight(nodeFront, options);
|
||||
},
|
||||
|
||||
async inspectNodeActor(nodeActor, inspectFromAnnotation) {
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
const nodeFront = await this.walker.gripToNodeFront({ actor: nodeActor });
|
||||
if (!nodeFront) {
|
||||
console.error(
|
||||
|
|
|
@ -698,7 +698,10 @@ MarkupView.prototype = {
|
|||
* requests queued up
|
||||
*/
|
||||
_showBoxModel: function(nodeFront) {
|
||||
return this.toolbox.highlighter
|
||||
// Hold onto a reference to the highlighted NodeFront so that we can get the correct
|
||||
// HighlighterFront when calling _hideBoxModel.
|
||||
this._highlightedNodeFront = nodeFront;
|
||||
return nodeFront.highlighterFront
|
||||
.highlight(nodeFront)
|
||||
.catch(this._handleRejectionIfNotDestroyed);
|
||||
},
|
||||
|
@ -713,7 +716,7 @@ MarkupView.prototype = {
|
|||
* requests queued up
|
||||
*/
|
||||
_hideBoxModel: function(forceHide) {
|
||||
return this.toolbox.highlighter
|
||||
return this._highlightedNodeFront.highlighterFront
|
||||
.unhighlight(forceHide)
|
||||
.catch(this._handleRejectionIfNotDestroyed);
|
||||
},
|
||||
|
@ -2232,6 +2235,7 @@ MarkupView.prototype = {
|
|||
|
||||
this._clearBriefBoxModelTimer();
|
||||
|
||||
this._highlightedNodeFront = null;
|
||||
this._hoveredContainer = null;
|
||||
|
||||
if (this._contextMenu) {
|
||||
|
|
|
@ -20,7 +20,7 @@ const TEST_URL = `
|
|||
`;
|
||||
|
||||
add_task(async function() {
|
||||
const { inspector, toolbox } = await openInspectorForURL(
|
||||
const { inspector } = await openInspectorForURL(
|
||||
"data:text/html;charset=utf-8," + encodeURI(TEST_URL)
|
||||
);
|
||||
|
||||
|
@ -74,7 +74,7 @@ add_task(async function() {
|
|||
await onShown;
|
||||
|
||||
info("Click on the computed view tab");
|
||||
const onHighlighterHidden = toolbox.highlighter.once("node-unhighlight");
|
||||
const onHighlighterHidden = inspector.highlighter.once("node-unhighlight");
|
||||
const onTabComputedViewSelected = inspector.sidebar.once(
|
||||
"computedview-selected"
|
||||
);
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
// shows the highlighter over those nodes
|
||||
add_task(async function() {
|
||||
info("Loading the test document and opening the inspector");
|
||||
const { toolbox, inspector, testActor } = await openInspectorForURL(
|
||||
const { inspector, testActor } = await openInspectorForURL(
|
||||
"data:text/html;charset=utf-8,<h1>foo</h1><span>bar</span>"
|
||||
);
|
||||
info("Selecting the test node");
|
||||
await selectNode("span", inspector);
|
||||
const bcButtons = inspector.breadcrumbs.container;
|
||||
|
||||
let onNodeHighlighted = toolbox.highlighter.once("node-highlight");
|
||||
let onNodeHighlighted = inspector.highlighter.once("node-highlight");
|
||||
let button = bcButtons.childNodes[1];
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
button,
|
||||
|
@ -32,7 +32,7 @@ add_task(async function() {
|
|||
"The highlighter highlights the right node"
|
||||
);
|
||||
|
||||
const onNodeUnhighlighted = toolbox.highlighter.once("node-unhighlight");
|
||||
const onNodeUnhighlighted = inspector.highlighter.once("node-unhighlight");
|
||||
// move outside of the breadcrumb trail to trigger unhighlight
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
inspector.addNodeButton,
|
||||
|
@ -41,7 +41,7 @@ add_task(async function() {
|
|||
);
|
||||
await onNodeUnhighlighted;
|
||||
|
||||
onNodeHighlighted = toolbox.highlighter.once("node-highlight");
|
||||
onNodeHighlighted = inspector.highlighter.once("node-highlight");
|
||||
button = bcButtons.childNodes[2];
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
button,
|
||||
|
|
|
@ -46,7 +46,7 @@ const TEST_DATA = [
|
|||
];
|
||||
|
||||
add_task(async function() {
|
||||
const { toolbox, inspector } = await openInspectorForURL(TEST_URL);
|
||||
const { inspector } = await openInspectorForURL(TEST_URL);
|
||||
const doc = inspector.panelDoc;
|
||||
const { breadcrumbs } = inspector;
|
||||
|
||||
|
@ -56,7 +56,7 @@ add_task(async function() {
|
|||
const container = doc.getElementById("inspector-breadcrumbs");
|
||||
|
||||
const button = container.querySelector("button[checked]");
|
||||
const onHighlight = toolbox.highlighter.once("node-highlight");
|
||||
const onHighlight = inspector.highlighter.once("node-highlight");
|
||||
button.click();
|
||||
await onHighlight;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ add_task(async function() {
|
|||
await selectNode("span", inspector);
|
||||
const container = await getContainerForSelector("h1", inspector);
|
||||
|
||||
const onHighlight = toolbox.highlighter.once("node-highlight");
|
||||
const onHighlight = inspector.highlighter.once("node-highlight");
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
container.tagLine,
|
||||
{ type: "mousemove" },
|
||||
|
|
|
@ -20,11 +20,11 @@ add_task(async function() {
|
|||
// We don't need to test here that the highlighter is actually visible, we
|
||||
// just care about whether the markup-view asks it to be shown
|
||||
let highlightedNode = null;
|
||||
inspector.toolbox._highlighter.showBoxModel = function(nodeFront) {
|
||||
inspector.highlighter.showBoxModel = function(nodeFront) {
|
||||
highlightedNode = nodeFront;
|
||||
return promise.resolve();
|
||||
};
|
||||
inspector.toolbox._highlighter.hideBoxModel = function() {
|
||||
inspector.highlighter.hideBoxModel = function() {
|
||||
return promise.resolve();
|
||||
};
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ function openLayoutView() {
|
|||
return promise.resolve();
|
||||
};
|
||||
}
|
||||
mockHighlighter(data.toolbox);
|
||||
mockHighlighter(data.inspector);
|
||||
|
||||
return {
|
||||
toolbox: data.toolbox,
|
||||
|
|
|
@ -1140,6 +1140,15 @@ netmonitor.context.copyAsCurl=Copy as cURL
|
|||
# for the Copy as cURL menu item displayed in the context menu for a request
|
||||
netmonitor.context.copyAsCurl.accesskey=C
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.context.copyAsCurl.*): This is the template used to add
|
||||
# a target platform to the label for "Copy as cURL" command
|
||||
# e.g. Copy as cURL (Windows)
|
||||
# Localized label for "Copy as cURL": %S
|
||||
netmonitor.context.copyAsCurl.win=%S (Windows)
|
||||
netmonitor.context.copyAsCurl.win.accesskey=C
|
||||
netmonitor.context.copyAsCurl.posix=%S (POSIX)
|
||||
netmonitor.context.copyAsCurl.posix.accesskey=P
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.context.copyAsFetch): This is the label displayed
|
||||
# on the context menu that copies the selected request as a fetch request.
|
||||
netmonitor.context.copyAsFetch=Copy as Fetch
|
||||
|
|
|
@ -35,6 +35,8 @@ loader.lazyRequireGetter(
|
|||
true
|
||||
);
|
||||
|
||||
const OS = Services.appinfo.OS;
|
||||
|
||||
class RequestListContextMenu {
|
||||
constructor(props) {
|
||||
this.props = props;
|
||||
|
@ -102,23 +104,69 @@ class RequestListContextMenu {
|
|||
click: () => this.copyPostData(id, formDataSections, requestPostData),
|
||||
});
|
||||
|
||||
copySubmenu.push({
|
||||
id: "request-list-context-copy-as-curl",
|
||||
label: L10N.getStr("netmonitor.context.copyAsCurl"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyAsCurl.accesskey"),
|
||||
// Menu item will be visible even if data hasn't arrived, so we need to check
|
||||
// *Available property and then fetch data lazily once user triggers the action.
|
||||
visible: !!clickedRequest,
|
||||
click: () =>
|
||||
this.copyAsCurl(
|
||||
id,
|
||||
url,
|
||||
method,
|
||||
httpVersion,
|
||||
requestHeaders,
|
||||
requestPostData
|
||||
if (OS === "WINNT") {
|
||||
copySubmenu.push({
|
||||
id: "request-list-context-copy-as-curl-win",
|
||||
label: L10N.getFormatStr(
|
||||
"netmonitor.context.copyAsCurl.win",
|
||||
L10N.getStr("netmonitor.context.copyAsCurl")
|
||||
),
|
||||
});
|
||||
accesskey: L10N.getStr("netmonitor.context.copyAsCurl.win.accesskey"),
|
||||
// Menu item will be visible even if data hasn't arrived, so we need to check
|
||||
// *Available property and then fetch data lazily once user triggers the action.
|
||||
visible: !!clickedRequest,
|
||||
click: () =>
|
||||
this.copyAsCurl(
|
||||
id,
|
||||
url,
|
||||
method,
|
||||
httpVersion,
|
||||
requestHeaders,
|
||||
requestPostData,
|
||||
"WINNT"
|
||||
),
|
||||
});
|
||||
|
||||
copySubmenu.push({
|
||||
id: "request-list-context-copy-as-curl-posix",
|
||||
label: L10N.getFormatStr(
|
||||
"netmonitor.context.copyAsCurl.posix",
|
||||
L10N.getStr("netmonitor.context.copyAsCurl")
|
||||
),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyAsCurl.posix.accesskey"),
|
||||
// Menu item will be visible even if data hasn't arrived, so we need to check
|
||||
// *Available property and then fetch data lazily once user triggers the action.
|
||||
visible: !!clickedRequest,
|
||||
click: () =>
|
||||
this.copyAsCurl(
|
||||
id,
|
||||
url,
|
||||
method,
|
||||
httpVersion,
|
||||
requestHeaders,
|
||||
requestPostData,
|
||||
"Linux"
|
||||
),
|
||||
});
|
||||
} else {
|
||||
copySubmenu.push({
|
||||
id: "request-list-context-copy-as-curl",
|
||||
label: L10N.getStr("netmonitor.context.copyAsCurl"),
|
||||
accesskey: L10N.getStr("netmonitor.context.copyAsCurl.accesskey"),
|
||||
// Menu item will be visible even if data hasn't arrived, so we need to check
|
||||
// *Available property and then fetch data lazily once user triggers the action.
|
||||
visible: !!clickedRequest,
|
||||
click: () =>
|
||||
this.copyAsCurl(
|
||||
id,
|
||||
url,
|
||||
method,
|
||||
httpVersion,
|
||||
requestHeaders,
|
||||
requestPostData
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
copySubmenu.push({
|
||||
id: "request-list-context-copy-as-fetch",
|
||||
|
@ -417,7 +465,8 @@ class RequestListContextMenu {
|
|||
method,
|
||||
httpVersion,
|
||||
requestHeaders,
|
||||
requestPostData
|
||||
requestPostData,
|
||||
platform
|
||||
) {
|
||||
requestHeaders =
|
||||
requestHeaders ||
|
||||
|
@ -435,7 +484,7 @@ class RequestListContextMenu {
|
|||
httpVersion,
|
||||
postDataText: requestPostData ? requestPostData.postData.text : "",
|
||||
};
|
||||
copyString(Curl.generateCommand(data));
|
||||
copyString(Curl.generateCommand(data, platform));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,13 +7,41 @@
|
|||
* Tests if Copy as cURL works.
|
||||
*/
|
||||
|
||||
const POST_PAYLOAD = "Plaintext value as a payload";
|
||||
|
||||
add_task(async function() {
|
||||
const { tab, monitor } = await initNetMonitor(CURL_URL);
|
||||
info("Starting test... ");
|
||||
|
||||
// Different quote chars are used for Windows and POSIX
|
||||
const QUOTE = Services.appinfo.OS == "WINNT" ? '"' : "'";
|
||||
const QUOTE_WIN = '"';
|
||||
const QUOTE_POSIX = "'";
|
||||
|
||||
const isWin = Services.appinfo.OS === "WINNT";
|
||||
const testData = isWin
|
||||
? [
|
||||
{
|
||||
menuItemId: "request-list-context-copy-as-curl-win",
|
||||
data: buildTestData(QUOTE_WIN),
|
||||
},
|
||||
{
|
||||
menuItemId: "request-list-context-copy-as-curl-posix",
|
||||
data: buildTestData(QUOTE_POSIX),
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
menuItemId: "request-list-context-copy-as-curl",
|
||||
data: buildTestData(QUOTE_POSIX),
|
||||
},
|
||||
];
|
||||
|
||||
await testForPlatform(tab, monitor, testData);
|
||||
|
||||
await teardown(monitor);
|
||||
});
|
||||
|
||||
function buildTestData(QUOTE) {
|
||||
// Quote a string, escape the quotes inside the string
|
||||
function quote(str) {
|
||||
return QUOTE + str.replace(new RegExp(QUOTE, "g"), `\\${QUOTE}`) + QUOTE;
|
||||
|
@ -43,7 +71,6 @@ add_task(async function() {
|
|||
|
||||
const COOKIE_PARTIAL_RESULT = [header("Cookie: bob=true; tom=cool")];
|
||||
|
||||
const POST_PAYLOAD = "Plaintext value as a payload";
|
||||
const POST_PARTIAL_RESULT = [
|
||||
"--data " + quote(POST_PAYLOAD),
|
||||
header("Content-Type: text/plain;charset=UTF-8"),
|
||||
|
@ -52,20 +79,45 @@ add_task(async function() {
|
|||
|
||||
const HEAD_PARTIAL_RESULT = ["-I"];
|
||||
|
||||
return {
|
||||
SIMPLE_BASE,
|
||||
SLOW_BASE,
|
||||
BASE_RESULT,
|
||||
COOKIE_PARTIAL_RESULT,
|
||||
POST_PAYLOAD,
|
||||
POST_PARTIAL_RESULT,
|
||||
ORIGIN_RESULT,
|
||||
HEAD_PARTIAL_RESULT,
|
||||
};
|
||||
}
|
||||
|
||||
async function testForPlatform(tab, monitor, testData) {
|
||||
// GET request, no cookies (first request)
|
||||
await performRequest("GET");
|
||||
await testClipboardContent([...SIMPLE_BASE, ...BASE_RESULT]);
|
||||
for (const test of testData) {
|
||||
await testClipboardContent(test.menuItemId, [
|
||||
...test.data.SIMPLE_BASE,
|
||||
...test.data.BASE_RESULT,
|
||||
]);
|
||||
}
|
||||
// Check to make sure it is still OK after we view the response (bug#1452442)
|
||||
await selectIndexAndWaitForSourceEditor(monitor, 0);
|
||||
await testClipboardContent([...SIMPLE_BASE, ...BASE_RESULT]);
|
||||
for (const test of testData) {
|
||||
await testClipboardContent(test.menuItemId, [
|
||||
...test.data.SIMPLE_BASE,
|
||||
...test.data.BASE_RESULT,
|
||||
]);
|
||||
}
|
||||
|
||||
// GET request, cookies set by previous response
|
||||
await performRequest("GET");
|
||||
await testClipboardContent([
|
||||
...SIMPLE_BASE,
|
||||
...BASE_RESULT,
|
||||
...COOKIE_PARTIAL_RESULT,
|
||||
]);
|
||||
for (const test of testData) {
|
||||
await testClipboardContent(test.menuItemId, [
|
||||
...test.data.SIMPLE_BASE,
|
||||
...test.data.BASE_RESULT,
|
||||
...test.data.COOKIE_PARTIAL_RESULT,
|
||||
]);
|
||||
}
|
||||
|
||||
// Unfinished request (bug#1378464, bug#1420513)
|
||||
const waitSlow = waitForNetworkEvents(monitor, 0);
|
||||
|
@ -73,32 +125,36 @@ add_task(async function() {
|
|||
content.wrappedJSObject.performRequest(url, "GET", null);
|
||||
});
|
||||
await waitSlow;
|
||||
await testClipboardContent([
|
||||
...SLOW_BASE,
|
||||
...BASE_RESULT,
|
||||
...COOKIE_PARTIAL_RESULT,
|
||||
]);
|
||||
for (const test of testData) {
|
||||
await testClipboardContent(test.menuItemId, [
|
||||
...test.data.SLOW_BASE,
|
||||
...test.data.BASE_RESULT,
|
||||
...test.data.COOKIE_PARTIAL_RESULT,
|
||||
]);
|
||||
}
|
||||
|
||||
// POST request
|
||||
await performRequest("POST", POST_PAYLOAD);
|
||||
await testClipboardContent([
|
||||
...SIMPLE_BASE,
|
||||
...BASE_RESULT,
|
||||
...COOKIE_PARTIAL_RESULT,
|
||||
...POST_PARTIAL_RESULT,
|
||||
...ORIGIN_RESULT,
|
||||
]);
|
||||
for (const test of testData) {
|
||||
await testClipboardContent(test.menuItemId, [
|
||||
...test.data.SIMPLE_BASE,
|
||||
...test.data.BASE_RESULT,
|
||||
...test.data.COOKIE_PARTIAL_RESULT,
|
||||
...test.data.POST_PARTIAL_RESULT,
|
||||
...test.data.ORIGIN_RESULT,
|
||||
]);
|
||||
}
|
||||
|
||||
// HEAD request
|
||||
await performRequest("HEAD");
|
||||
await testClipboardContent([
|
||||
...SIMPLE_BASE,
|
||||
...BASE_RESULT,
|
||||
...COOKIE_PARTIAL_RESULT,
|
||||
...HEAD_PARTIAL_RESULT,
|
||||
]);
|
||||
|
||||
await teardown(monitor);
|
||||
for (const test of testData) {
|
||||
await testClipboardContent(test.menuItemId, [
|
||||
...test.data.SIMPLE_BASE,
|
||||
...test.data.BASE_RESULT,
|
||||
...test.data.COOKIE_PARTIAL_RESULT,
|
||||
...test.data.HEAD_PARTIAL_RESULT,
|
||||
]);
|
||||
}
|
||||
|
||||
async function performRequest(method, payload) {
|
||||
const waitRequest = waitForNetworkEvents(monitor, 1);
|
||||
|
@ -116,25 +172,23 @@ add_task(async function() {
|
|||
await waitRequest;
|
||||
}
|
||||
|
||||
async function testClipboardContent(expectedResult) {
|
||||
async function testClipboardContent(menuItemId, expectedResult) {
|
||||
const { document } = monitor.panelWin;
|
||||
|
||||
const items = document.querySelectorAll(".request-list-item");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, items[items.length - 1]);
|
||||
const itemIndex = items.length - 1;
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, items[itemIndex]);
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "contextmenu" },
|
||||
document.querySelectorAll(".request-list-item")[0]
|
||||
);
|
||||
|
||||
/* Ensure that the copy as cURL option is always visible */
|
||||
const copyUrlParamsNode = getContextMenuItem(
|
||||
monitor,
|
||||
"request-list-context-copy-as-curl"
|
||||
);
|
||||
const copyUrlParamsNode = getContextMenuItem(monitor, menuItemId);
|
||||
is(
|
||||
!!copyUrlParamsNode,
|
||||
true,
|
||||
'The "Copy as cURL" context menu item should not be hidden.'
|
||||
`The "Copy as cURL" context menu item "${menuItemId}" should not be hidden.`
|
||||
);
|
||||
|
||||
await waitForClipboardPromise(
|
||||
|
@ -169,6 +223,8 @@ add_task(async function() {
|
|||
}
|
||||
);
|
||||
|
||||
info("Clipboard contains a cURL command for item " + (items.length - 1));
|
||||
info(
|
||||
`Clipboard contains a cURL command for item ${itemIndex} by "${menuItemId}"`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ add_task(async function() {
|
|||
|
||||
store.dispatch(Actions.batchEnable(false));
|
||||
|
||||
const wait = waitForNetworkEvents(monitor, 5);
|
||||
const wait = waitForNetworkEvents(monitor, 6);
|
||||
await ContentTask.spawn(tab.linkedBrowser, SIMPLE_SJS, async function(url) {
|
||||
content.wrappedJSObject.performRequests(url);
|
||||
});
|
||||
|
@ -31,9 +31,10 @@ add_task(async function() {
|
|||
const requests = {
|
||||
get: getSortedRequests(store.getState()).get(0),
|
||||
post: getSortedRequests(store.getState()).get(1),
|
||||
patch: getSortedRequests(store.getState()).get(2),
|
||||
multipart: getSortedRequests(store.getState()).get(3),
|
||||
multipartForm: getSortedRequests(store.getState()).get(4),
|
||||
postJson: getSortedRequests(store.getState()).get(2),
|
||||
patch: getSortedRequests(store.getState()).get(3),
|
||||
multipart: getSortedRequests(store.getState()).get(4),
|
||||
multipartForm: getSortedRequests(store.getState()).get(5),
|
||||
};
|
||||
|
||||
let data = await createCurlData(requests.get, getLongString, requestData);
|
||||
|
@ -49,6 +50,9 @@ add_task(async function() {
|
|||
testWritePostDataTextParams(data);
|
||||
testDataArgumentOnGeneratedCommand(data);
|
||||
|
||||
data = await createCurlData(requests.postJson, getLongString, requestData);
|
||||
testDataEscapeOnGeneratedCommand(data);
|
||||
|
||||
data = await createCurlData(requests.multipart, getLongString, requestData);
|
||||
testIsMultipartRequest(data);
|
||||
testGetMultipartBoundary(data);
|
||||
|
@ -139,6 +143,23 @@ function testDataArgumentOnGeneratedCommand(data) {
|
|||
);
|
||||
}
|
||||
|
||||
function testDataEscapeOnGeneratedCommand(data) {
|
||||
const paramsWin = `--data "{""param1"":""value1"",""param2"":""value2""}"`;
|
||||
const paramsPosix = `--data '{"param1":"value1","param2":"value2"}'`;
|
||||
|
||||
let curlCommand = Curl.generateCommand(data, "WINNT");
|
||||
ok(
|
||||
curlCommand.includes(paramsWin),
|
||||
"Should return a curl command with --data escaped for Windows systems"
|
||||
);
|
||||
|
||||
curlCommand = Curl.generateCommand(data, "Linux");
|
||||
ok(
|
||||
curlCommand.includes(paramsPosix),
|
||||
"Should return a curl command with --data escaped for Posix systems"
|
||||
);
|
||||
}
|
||||
|
||||
function testGetMultipartBoundary(data) {
|
||||
const boundary = CurlUtils.getMultipartBoundary(data);
|
||||
ok(
|
||||
|
|
|
@ -55,6 +55,22 @@
|
|||
xhr.send(params);
|
||||
}
|
||||
|
||||
function ajaxPostJson(url, callback) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", url, true);
|
||||
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
|
||||
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
||||
xhr.onload = function() {
|
||||
callback();
|
||||
};
|
||||
const params = {
|
||||
param1: "value1",
|
||||
param2: "value2",
|
||||
};
|
||||
const jsonParams = JSON.stringify(params);
|
||||
xhr.send(jsonParams);
|
||||
}
|
||||
|
||||
function ajaxPatch(url, callback) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("PATCH", url, true);
|
||||
|
@ -102,9 +118,11 @@
|
|||
function performRequests(url) {
|
||||
ajaxGet(url, () => {
|
||||
ajaxPost(url, () => {
|
||||
ajaxPatch(url, () => {
|
||||
ajaxMultipart(url, () => {
|
||||
submitForm();
|
||||
ajaxPostJson(url, () => {
|
||||
ajaxPatch(url, () => {
|
||||
ajaxMultipart(url, () => {
|
||||
submitForm();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -155,10 +155,19 @@ input:-moz-focusring {
|
|||
max-content;
|
||||
}
|
||||
|
||||
#toolbar:not(.left-aligned) #toolbar-center-controls {
|
||||
#toolbar:not(.left-aligned) {
|
||||
grid-template-columns: 1fr auto 1fr min-content;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#toolbar:not(.left-aligned) #toolbar-center-controls {
|
||||
grid-column-start: 2;
|
||||
}
|
||||
|
||||
#toolbar:not(.left-aligned) #toolbar-end-controls {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
#user-agent-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -5714,7 +5714,7 @@ function ElementNode(props) {
|
|||
|
||||
if (onDOMNodeMouseOut) {
|
||||
Object.assign(baseConfig, {
|
||||
onMouseOut: onDOMNodeMouseOut
|
||||
onMouseOut: _ => onDOMNodeMouseOut(object)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -50,19 +50,25 @@ const Curl = {
|
|||
* - httpVersion:string, http protocol version rfc2616 formatted. Eg. "HTTP/1.1"
|
||||
* - postDataText:string, optional - the request payload.
|
||||
*
|
||||
* @param string platform
|
||||
* Optional parameter to override platform,
|
||||
* Fallbacks to current platform if not defined.
|
||||
*
|
||||
* @return string
|
||||
* A cURL command.
|
||||
*/
|
||||
generateCommand: function(data) {
|
||||
generateCommand: function(data, platform) {
|
||||
const utils = CurlUtils;
|
||||
|
||||
let command = ["curl"];
|
||||
const ignoredHeaders = new Set();
|
||||
|
||||
const currentPlatform = platform || Services.appinfo.OS;
|
||||
|
||||
// The cURL command is expected to run on the same platform that Firefox runs
|
||||
// (it may be different from the inspected page platform).
|
||||
const escapeString =
|
||||
Services.appinfo.OS == "WINNT"
|
||||
currentPlatform == "WINNT"
|
||||
? utils.escapeStringWin
|
||||
: utils.escapeStringPosix;
|
||||
|
||||
|
|
|
@ -88,14 +88,18 @@
|
|||
return fetch(uri).then(({ content }) => content);
|
||||
};
|
||||
|
||||
const getTestActor = async function(client, tab, toolbox) {
|
||||
const getTestActor = async function(client, tab, toolbox = null) {
|
||||
// We may have to update the form in order to get the dynamically registered
|
||||
// test actor.
|
||||
const form = await getUpdatedForm(client, tab);
|
||||
|
||||
const { TestActorFront } = await loadFront();
|
||||
|
||||
const front = new TestActorFront(client, toolbox);
|
||||
let highlighter;
|
||||
if (toolbox) {
|
||||
highlighter = (await toolbox.target.getFront("inspector")).highlighter;
|
||||
}
|
||||
|
||||
const front = new TestActorFront(client, highlighter);
|
||||
// Since we manually instantiate this front instead of going through protocol.js,
|
||||
// we have to manually set its actor ID and manage it.
|
||||
front.actorID = form.testActor;
|
||||
|
|
|
@ -855,9 +855,9 @@ var TestActor = (exports.TestActor = protocol.ActorClassWithSpec(testSpec, {
|
|||
}));
|
||||
|
||||
class TestActorFront extends protocol.FrontClassWithSpec(testSpec) {
|
||||
constructor(client, toolbox) {
|
||||
constructor(client, highlighter) {
|
||||
super(client);
|
||||
this.toolbox = toolbox;
|
||||
this.highlighter = highlighter;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -867,7 +867,7 @@ class TestActorFront extends protocol.FrontClassWithSpec(testSpec) {
|
|||
* @return {Promise} The returned promise will only resolve when the
|
||||
* highlighter has updated to the new zoom level.
|
||||
*/
|
||||
zoomPageTo(level, actorID = this.toolbox.highlighter.actorID) {
|
||||
zoomPageTo(level, actorID = this.highlighter.actorID) {
|
||||
return this.changeZoomLevel(level, actorID);
|
||||
}
|
||||
|
||||
|
@ -877,7 +877,7 @@ class TestActorFront extends protocol.FrontClassWithSpec(testSpec) {
|
|||
return super.changeHighlightedNodeWaitForUpdate(
|
||||
name,
|
||||
value,
|
||||
(highlighter || this.toolbox.highlighter).actorID
|
||||
(highlighter || this.highlighter).actorID
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -892,14 +892,14 @@ class TestActorFront extends protocol.FrontClassWithSpec(testSpec) {
|
|||
return this.getHighlighterAttribute(
|
||||
nodeID,
|
||||
name,
|
||||
(highlighter || this.toolbox.highlighter).actorID
|
||||
(highlighter || this.highlighter).actorID
|
||||
);
|
||||
}
|
||||
|
||||
getHighlighterNodeTextContent(nodeID, highlighter) {
|
||||
return super.getHighlighterNodeTextContent(
|
||||
nodeID,
|
||||
(highlighter || this.toolbox.highlighter).actorID
|
||||
(highlighter || this.highlighter).actorID
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -947,8 +947,8 @@ class TestActorFront extends protocol.FrontClassWithSpec(testSpec) {
|
|||
/**
|
||||
* Get the current rect of the border region of the box-model highlighter
|
||||
*/
|
||||
async getSimpleBorderRect(toolbox) {
|
||||
const { border } = await this._getBoxModelStatus(toolbox);
|
||||
async getSimpleBorderRect() {
|
||||
const { border } = await this._getBoxModelStatus();
|
||||
const { p1, p2, p4 } = border.points;
|
||||
|
||||
return {
|
||||
|
@ -1143,10 +1143,7 @@ class TestActorFront extends protocol.FrontClassWithSpec(testSpec) {
|
|||
}
|
||||
|
||||
waitForHighlighterEvent(event) {
|
||||
return super.waitForHighlighterEvent(
|
||||
event,
|
||||
this.toolbox.highlighter.actorID
|
||||
);
|
||||
return super.waitForHighlighterEvent(event, this.highlighter.actorID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2908,6 +2908,7 @@ Variable.prototype = extend(Scope.prototype, {
|
|||
|
||||
let nodeFront = this._nodeFront;
|
||||
if (!nodeFront) {
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
nodeFront = await this.toolbox.walker.gripToNodeFront(this._valueGrip);
|
||||
}
|
||||
|
||||
|
@ -2931,15 +2932,18 @@ Variable.prototype = extend(Scope.prototype, {
|
|||
* linked to the toolbox's inspector, then highlight the corresponding node
|
||||
*/
|
||||
highlightDomNode: async function() {
|
||||
if (this.toolbox) {
|
||||
await this.toolbox.initInspector();
|
||||
if (!this._nodeFront) {
|
||||
this.nodeFront = await this.toolbox.walker.gripToNodeFront(
|
||||
this._valueGrip
|
||||
);
|
||||
}
|
||||
await this.toolbox.highlighter.highlight(this._nodeFront);
|
||||
if (!this.toolbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._nodeFront) {
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
const walkerFront = (await this.toolbox.target.getFront("inspector"))
|
||||
.walker;
|
||||
this.nodeFront = await walkerFront.gripToNodeFront(this._valueGrip);
|
||||
}
|
||||
|
||||
await this.nodeFront.highlighterFront.highlight(this._nodeFront);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2947,9 +2951,11 @@ Variable.prototype = extend(Scope.prototype, {
|
|||
* @see highlightDomNode
|
||||
*/
|
||||
unhighlightDomNode: function() {
|
||||
if (this.toolbox) {
|
||||
this.toolbox.highlighter.unhighlight();
|
||||
if (!this.toolbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.nodeFront.highlighterFront.unhighlight();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@ support-files =
|
|||
code_bundle_invalidmap.js.map
|
||||
code_bundle_nosource.js
|
||||
code_bundle_nosource.js.map
|
||||
cookieSetter.html
|
||||
head.js
|
||||
sjs_cors-test-server.sjs
|
||||
sjs_slow-response-test-server.sjs
|
||||
|
@ -72,6 +73,7 @@ support-files =
|
|||
test-iframe-wrong-hud-iframe.html
|
||||
test-iframe-wrong-hud.html
|
||||
test-image.png
|
||||
test-image.png^headers^
|
||||
test-ineffective-iframe-sandbox-warning-inner.html
|
||||
test-ineffective-iframe-sandbox-warning-nested1.html
|
||||
test-ineffective-iframe-sandbox-warning-nested2.html
|
||||
|
|
|
@ -61,7 +61,7 @@ add_task(async function() {
|
|||
ok(isVisible, "Highlighter is displayed");
|
||||
|
||||
info("Unhighlight the node by moving away from the node");
|
||||
let onNodeUnhighlight = toolbox.highlighter.once("node-unhighlight");
|
||||
let onNodeUnhighlight = inspectorFront.highlighter.once("node-unhighlight");
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
nonHighlightEl,
|
||||
{ type: "mousemove" },
|
||||
|
@ -72,8 +72,8 @@ add_task(async function() {
|
|||
ok(true, "node-unhighlight event was fired when moving away from the node");
|
||||
|
||||
info("Check we don't have zombie highlighters when briefly hovering a node");
|
||||
onNodeHighlight = toolbox.highlighter.once("node-highlight");
|
||||
onNodeUnhighlight = toolbox.highlighter.once("node-unhighlight");
|
||||
onNodeHighlight = inspectorFront.highlighter.once("node-highlight");
|
||||
onNodeUnhighlight = inspectorFront.highlighter.once("node-unhighlight");
|
||||
// Move hover the node and then right after move out.
|
||||
EventUtils.synthesizeMouseAtCenter(node, { type: "mousemove" }, view);
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
"use strict";
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const TEST_FILE =
|
||||
"browser/devtools/client/webconsole/test/browser/" +
|
||||
"test-trackingprotection-securityerrors.html";
|
||||
const TEST_PATH = "browser/devtools/client/webconsole/test/browser/";
|
||||
const TEST_FILE = TEST_PATH + "test-trackingprotection-securityerrors.html";
|
||||
const TEST_URI = "http://example.com/" + TEST_FILE;
|
||||
const TRACKER_URL = "http://tracking.example.org/";
|
||||
const BLOCKED_URL = `\u201c${TRACKER_URL}\u201d`;
|
||||
const BLOCKED_URL = `\u201c${TRACKER_URL +
|
||||
TEST_PATH +
|
||||
"cookieSetter.html"}\u201d`;
|
||||
|
||||
const COOKIE_BEHAVIOR_PREF = "network.cookie.cookieBehavior";
|
||||
const COOKIE_BEHAVIORS = {
|
||||
|
|
|
@ -42,6 +42,16 @@ registerCleanupFunction(function() {
|
|||
pushPref("privacy.trackingprotection.enabled", true);
|
||||
pushPref("devtools.webconsole.groupWarningMessages", true);
|
||||
|
||||
async function cleanUp() {
|
||||
await new Promise(resolve => {
|
||||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value =>
|
||||
resolve()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
add_task(cleanUp);
|
||||
|
||||
add_task(async function testContentBlockingMessage() {
|
||||
const { hud, tab, win } = await openNewWindowAndConsole(
|
||||
"http://tracking.example.org/" + TEST_FILE
|
||||
|
@ -155,6 +165,8 @@ add_task(async function testCookieBlockedByPermissionMessage() {
|
|||
Services.perms.removeFromPrincipal(p, "cookie");
|
||||
});
|
||||
|
||||
add_task(cleanUp);
|
||||
|
||||
/**
|
||||
* Test that storage access blocked messages are grouped by emitting 2 messages.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<script>
|
||||
"use strict";
|
||||
document.cookie = "name=value";
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Set-Cookie: name=value
|
|
@ -7,7 +7,7 @@
|
|||
<meta charset="utf8">
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="http://tracking.example.org/"></iframe>
|
||||
<iframe src="http://tracking.example.org/browser/devtools/client/webconsole/test/browser/cookieSetter.html"></iframe>
|
||||
<iframe src="http://tracking.example.com/"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -41,7 +41,9 @@ function getObjectInspector(grip, serviceContainer, override = {}) {
|
|||
onDOMNodeMouseOver = serviceContainer.highlightDomElement
|
||||
? object => serviceContainer.highlightDomElement(object)
|
||||
: null;
|
||||
onDOMNodeMouseOut = serviceContainer.unHighlightDomElement;
|
||||
onDOMNodeMouseOut = serviceContainer.unHighlightDomElement
|
||||
? object => serviceContainer.unHighlightDomElement(object)
|
||||
: null;
|
||||
onInspectIconClick = serviceContainer.openNodeInInspector
|
||||
? (object, e) => {
|
||||
// Stop the event propagation so we don't trigger ObjectInspector expand/collapse.
|
||||
|
|
|
@ -381,6 +381,7 @@ class WebConsoleWrapper {
|
|||
"inspector",
|
||||
"inspect_dom"
|
||||
);
|
||||
// TODO: Bug1574506 - Use the contextual WalkerFront for gripToNodeFront.
|
||||
const onGripNodeToFront = this.toolbox.walker.gripToNodeFront(grip);
|
||||
const [front, inspector] = await Promise.all([
|
||||
onGripNodeToFront,
|
||||
|
|
|
@ -30,6 +30,7 @@ const TELEMETRY_EYEDROPPER_OPENED_MENU =
|
|||
const SHOW_ALL_ANONYMOUS_CONTENT_PREF =
|
||||
"devtools.inspector.showAllAnonymousContent";
|
||||
const SHOW_UA_SHADOW_ROOTS_PREF = "devtools.inspector.showUserAgentShadowRoots";
|
||||
const FISSION_ENABLED = "devtools.browsertoolbox.fission";
|
||||
|
||||
const telemetry = new Telemetry();
|
||||
|
||||
|
@ -459,6 +460,9 @@ class WalkerFront extends FrontClassWithSpec(walkerSpec) {
|
|||
// Finally retrieve the NodeFront of the remote frame's document
|
||||
const documentNode = await walker.getRootNode();
|
||||
|
||||
// Force reparenting through the remote frame boundary.
|
||||
documentNode.reparent(node);
|
||||
|
||||
// And return the same kind of response `walker.children` returns
|
||||
return {
|
||||
nodes: [documentNode],
|
||||
|
@ -564,6 +568,25 @@ class InspectorFront extends FrontClassWithSpec(inspectorSpec) {
|
|||
telemetry.getHistogramById(TELEMETRY_EYEDROPPER_OPENED).add(true);
|
||||
}
|
||||
}
|
||||
|
||||
async getChildInspectors() {
|
||||
const fissionEnabled = Services.prefs.getBoolPref(FISSION_ENABLED);
|
||||
const childInspectors = [];
|
||||
const target = this.targetFront;
|
||||
// this line can be removed when we are ready for fission frames
|
||||
if (fissionEnabled && target.chrome && !target.isAddon) {
|
||||
const { frames } = await target.listRemoteFrames();
|
||||
// attempt to get targets and filter by targets that could connect
|
||||
for (const descriptor of frames) {
|
||||
const remoteTarget = await descriptor.getTarget();
|
||||
if (remoteTarget) {
|
||||
const remoteInspectorFront = await remoteTarget.getFront("inspector");
|
||||
childInspectors.push(remoteInspectorFront);
|
||||
}
|
||||
}
|
||||
}
|
||||
return childInspectors;
|
||||
}
|
||||
}
|
||||
|
||||
exports.InspectorFront = InspectorFront;
|
||||
|
|
|
@ -405,6 +405,14 @@ class NodeFront extends FrontClassWithSpec(nodeSpec) {
|
|||
return true;
|
||||
}
|
||||
|
||||
get inspectorFront() {
|
||||
return this.parentFront.parentFront;
|
||||
}
|
||||
|
||||
get highlighterFront() {
|
||||
return this.inspectorFront.highlighter;
|
||||
}
|
||||
|
||||
get walkerFront() {
|
||||
return this.parentFront;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
const {
|
||||
types,
|
||||
Option,
|
||||
RetVal,
|
||||
generateActorSpec,
|
||||
} = require("devtools/shared/protocol");
|
||||
|
@ -37,6 +38,10 @@ const contentProcessTargetSpec = generateActorSpec({
|
|||
newSource: {
|
||||
type: "newSource",
|
||||
},
|
||||
tabDetached: {
|
||||
type: "tabDetached",
|
||||
from: Option(0, "string"),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -7,3 +7,4 @@ These linked pages contain design documents for the DOM implementation in Gecko.
|
|||
:maxdepth: 1
|
||||
|
||||
Fission
|
||||
workersAndStorage/index
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
====================================
|
||||
DOM Workers & Storage C++ Code Style
|
||||
====================================
|
||||
|
||||
This page describes the code style for the components maintained by the DOM Workers & Storage team. They live in-tree under the 'dom/docs/indexedDB' directory.
|
||||
|
||||
.. contents::
|
||||
:depth: 4
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This code style currently applies to the components living in the following directories:
|
||||
|
||||
* ``dom/indexedDB``
|
||||
* ``dom/localstorage``
|
||||
* ``dom/quota``
|
||||
|
||||
In the long-term, the code is intended to use the
|
||||
`Mozilla Coding Style <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style>`_,
|
||||
which references the `Google C++ Coding Style <https://google.github.io/styleguide/cppguide.html>`_.
|
||||
|
||||
However, large parts of the code were written before rules and in particular
|
||||
the reference to the Google C++ Coding Style were enacted, and due to the
|
||||
size of the code, this misalignment cannot be fixed in the short term.
|
||||
To avoid that an arbitrary mixture of old-style and new-style code grows,
|
||||
this document makes deviations from the "global" code style explicit, and
|
||||
will be amended to describe migration paths in the future.
|
||||
|
||||
In addition, to achieve higher consistency within the components maintained by
|
||||
the team and to reduce style discussions during reviews, allowing them to focus
|
||||
on more substantial issues, more specific rules are described here that go
|
||||
beyond the global code style. These topics might have been deliberately or
|
||||
accidentally omitted from the global code style. Depending on wider agreement
|
||||
and applicability, these specific rules might be migrated into the global code
|
||||
style in the future.
|
||||
|
||||
Note that this document does not cover pure formatting issues. The code is and
|
||||
must be kept formatted automatically by clang-format using the supplied
|
||||
configuration file, and whatever clang-format does takes precedence over any
|
||||
other stated rules regarding formatting.
|
||||
|
||||
Deviations from the Google C++ Coding Style
|
||||
===========================================
|
||||
|
||||
Deviations not documented yet.
|
||||
|
||||
Deviations from the Mozilla C++ Coding Style
|
||||
============================================
|
||||
|
||||
.. the table renders impractically, cf. https://github.com/readthedocs/sphinx_rtd_theme/issues/117
|
||||
|
||||
.. tabularcolumns:: |p{4cm}|p{4cm}|p{2cm}|p{2cm}|
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-----------------+-------------------------------------------------------------------------------------+
|
||||
| Mozilla style | Prevalent WAS style | Deviation scope | Evolution |
|
||||
+========================================================================================================+============================================================================================+=================+=====================================================================================+
|
||||
| `We prefer using "static", instead of anonymous C++ namespaces. | Place all symbols that should have internal linkage in a single anonymous | All files | Unclear. The recommendation in the Mozilla code style says this might change in the |
|
||||
| <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style#Anonymous_namespaces>`_ | namespace block at the top of an implementation file, rather than declarating them static. | | future depending on debugger support, so this deviation might become obsolete. |
|
||||
| | | | |
|
||||
+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-----------------+-------------------------------------------------------------------------------------+
|
||||
| `All parameters passed by lvalue reference must be labeled const. [...] Input parameters may be const | Non-const reference parameters may be used. | All files | Unclear. Maybe at least restrict the use of non-const reference parameters to |
|
||||
| pointers, but we never allow non-const reference parameters except when required by convention, e.g., | | | cases that are not clearly output parameters (i.e. which are assigned to). |
|
||||
| swap(). <https://google.github.io/styleguide/cppguide.html#Reference_Arguments>`_ | | | |
|
||||
+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-----------------+-------------------------------------------------------------------------------------+
|
||||
|
||||
Additions to the Google/Mozilla C++ Code Style
|
||||
==============================================
|
||||
|
||||
This section contains style guidelines that do not conflict with the Google or
|
||||
Mozilla C++ Code Style, but may make guidelines more specific or add guidelines
|
||||
on topics not covered by those style guides at all.
|
||||
|
||||
Naming
|
||||
------
|
||||
|
||||
gtest test names
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
gtest constructs a full test name from different fragments. Test names are
|
||||
constructed somewhat differently for basic and parametrized tests.
|
||||
|
||||
The *prefix* for a test should start with an identifier of the component
|
||||
and class, based on the name of the source code directory, transformed to
|
||||
PascalCase and underscores as separators, so e.g. for a class ``Key`` in
|
||||
``dom/indexedDB``, use ``DOM_IndexedDB_Key`` as a prefix.
|
||||
|
||||
For basic tests constructed with ``TEST(test_case_name, test_name)``: Use
|
||||
the *prefix* as the ``test_case_name``. Test ``test_name`` should start with
|
||||
the name of tested method(s), and a . Use underscores as a separator within
|
||||
the ``test_name``.
|
||||
|
||||
Value-parametrized tests are constructed with
|
||||
``TEST_P(parametrized_test_case_name, parametrized_test_name)``. They require a
|
||||
custom test base class, whose name is used as the ``parametrized_test_case_name``.
|
||||
Start the class name with ``TestWithParam_``, and end it with a transliteration
|
||||
of the parameter type (e.g. ``String_Int_Pair`` for ``std::pair<nsString, int>``),
|
||||
and place it in an (anonymous) namespace.
|
||||
|
||||
.. attention::
|
||||
It is important to place the class in an (anonymous) namespace, since its
|
||||
name according to this guideline is not unique within libxul-gtest, and name
|
||||
clashes are likely, which would lead to ODR violations otherwise.
|
||||
|
||||
A ``parametrized_test_name`` is constructed according to the same rules
|
||||
described for ``test_name`` above.
|
||||
|
||||
Instances of value-parametrized tests are constructed using
|
||||
``INSTANTIATE_TEST_CASE_P(prefix, parametrized_test_case_name, generator, ...)``.
|
||||
As ``prefix``, use the prefix as described above.
|
||||
|
||||
Similar considerations apply to type-parametrized tests. If necessary, specific
|
||||
rules for type-parametrized tests will be added here.
|
||||
|
||||
Rationale
|
||||
All gtests (not only from the WAS components) are linked into libxul-gtest,
|
||||
which requires names to be unique within that large scope. In addition, it
|
||||
should be clear from the test name (e.g. in the test execution log) in what
|
||||
source file (or at least which directory) the test code can be found.
|
||||
Optimally, test names should be structured hierarchically to allow
|
||||
easy selection of groups of tests for execution. However, gtest has some
|
||||
restrictions that do not allow that completely. The guidelines try to
|
||||
accomodate for these as far as possible. Note that gtest recommends not to
|
||||
use underscores in test names in general, because this may lead to reserved
|
||||
names and naming conflicts, but the rules stated here should avoid that.
|
||||
In case of any problems arising, we can evolve the rules to accomodate
|
||||
for that.
|
||||
|
||||
Specifying types
|
||||
----------------
|
||||
|
||||
Use of ``auto`` for declaring variables
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The `Google C++ Code Style on auto <https://google.github.io/styleguide/cppguide.html#auto>`_
|
||||
allows the use of ``auto`` generally with encouragements for specific cases, which still
|
||||
leaves a rather wide range for interpretation.
|
||||
|
||||
We extend this by some more encouragements and discouragements:
|
||||
|
||||
* DO use ``auto`` when the type is already present in the
|
||||
initialization expression (esp. a template argument or similar),
|
||||
e.g. ``auto c = static_cast<uint16_t>(*(iter++)) << 8;`` or
|
||||
``auto x = MakeRefPtr<MediaStreamError>(mWindow, *aError);``
|
||||
|
||||
* DO use ``auto`` if the spelled out type were complex otherwise,
|
||||
e.g. a nested typedef or type alias, e.g. ``foo_container::value_type``.
|
||||
|
||||
* DO NOT use ``auto`` if the type were spelled out as a builtin
|
||||
integer type or one of the types from ``<cstdint>``, e.g.
|
||||
instead of ``auto foo = funcThatReturnsUint16();`` use
|
||||
``uint16_t foo = funcThatReturnsUint16();``.
|
||||
|
||||
.. note::
|
||||
Some disadvantages of using ``auto`` relate to the unavailability of type
|
||||
information outside an appropriate IDE/editor. This may be somewhat remedied
|
||||
by resolving `Bug 1567464 <https://bugzilla.mozilla.org/show_bug.cgi?id=1567464>`_
|
||||
which will make the type information available in searchfox. In consequence,
|
||||
the guidelines might be amended to promote a more widespread use of ``auto``.
|
||||
|
||||
Plain pointers
|
||||
--------------
|
||||
|
||||
The use of plain pointers is error-prone. Avoid using owning plain pointers. In
|
||||
particular, avoid using literal, non-placement new. There are various kinds
|
||||
of smart pointers, not all of which provide appropriate factory functions.
|
||||
However, where such factory functions exist, do use them (along with auto).
|
||||
The following is an incomplete list of smart pointer types and corresponding
|
||||
factory functions:
|
||||
|
||||
+------------------------+-------------------------+------------------------+
|
||||
| Type | Factory function | Header file |
|
||||
+========================+=========================+========================+
|
||||
| ``mozilla::RefPtr`` | ``mozilla::MakeRefPtr`` | ``"mfbt/RefPtr.h"`` |
|
||||
+------------------------+-------------------------+------------------------+
|
||||
| ``mozilla::UniquePtr`` | ``mozilla::MakeUnique`` | ``"mfbt/UniquePtr.h"`` |
|
||||
+------------------------+-------------------------+------------------------+
|
||||
| ``std::unique_ptr`` | ``std::make_unique`` | ``<memory>`` |
|
||||
+------------------------+-------------------------+------------------------+
|
||||
| ``std::shared_ptr`` | ``std::make_shared`` | ``<memory>`` |
|
||||
+------------------------+-------------------------+------------------------+
|
|
@ -0,0 +1,9 @@
|
|||
DOM Workers & Storage
|
||||
=====================
|
||||
|
||||
These linked pages contain design documents for the Workers & Storage implementations in Gecko. They live in-tree under the 'dom/docs/workerAndStorage' directory.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
CodeStyle
|
|
@ -87,7 +87,7 @@ bool MediaCodecs::ContainsPrefix(const nsAString& aCodecPrefix) const {
|
|||
const size_t prefixLength = aCodecPrefix.Length();
|
||||
for (const auto& myCodec : Range()) {
|
||||
if (myCodec.Length() >= prefixLength &&
|
||||
memcmp(myCodec.Data(), aCodecPrefix.Data(), prefixLength) == 0) {
|
||||
memcmp(myCodec.Data(), aCodecPrefix.Data(), prefixLength * sizeof(char16_t)) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -307,7 +307,7 @@ MochiKit.Logging.__new__ = function () {
|
|||
if (typeof(printfire) == "undefined" &&
|
||||
typeof(document) != "undefined" && document.createEvent &&
|
||||
typeof(dispatchEvent) != "undefined") {
|
||||
// FireBug really should be less lame about this global function
|
||||
// FireBug really should be less stupid about this global function
|
||||
printfire = function () {
|
||||
printfire.args = arguments;
|
||||
var ev = document.createEvent("Events");
|
||||
|
|
|
@ -1077,7 +1077,6 @@ function TypedArrayCompareInt(x, y) {
|
|||
// TypedArray SortCompare specialization for BigInt values.
|
||||
function TypedArrayCompareBigInt(x, y) {
|
||||
// Step 1.
|
||||
// eslint-disable-next-line valid-typeof
|
||||
assert(typeof x === "bigint" && typeof y === "bigint",
|
||||
"x and y are not BigInts.");
|
||||
|
||||
|
|
|
@ -59,10 +59,10 @@ if not CONFIG['JS_DISABLE_SHELL']:
|
|||
'tests',
|
||||
]
|
||||
|
||||
if CONFIG['FUZZING_INTERFACES']:
|
||||
TEST_DIRS += [
|
||||
'fuzz-tests',
|
||||
]
|
||||
if CONFIG['FUZZING_INTERFACES']:
|
||||
TEST_DIRS += [
|
||||
'fuzz-tests',
|
||||
]
|
||||
|
||||
if CONFIG['FUZZING_INTERFACES'] and CONFIG['LIBFUZZER']:
|
||||
# In addition to regular coverage provided by trace-pc-guard,
|
||||
|
|
|
@ -2704,8 +2704,7 @@ bool js::SynchronouslyCompressSource(JSContext* cx,
|
|||
|
||||
void ScriptSource::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
|
||||
JS::ScriptSourceInfo* info) const {
|
||||
info->misc += mallocSizeOf(this) + mallocSizeOf(filename_.get()) +
|
||||
mallocSizeOf(introducerFilename_.get());
|
||||
info->misc += mallocSizeOf(this);
|
||||
info->numScripts++;
|
||||
}
|
||||
|
||||
|
@ -3333,70 +3332,58 @@ XDRResult ScriptSource::XDR(XDRState<mode>* xdr,
|
|||
MOZ_TRY(xdr->codeUint8(&haveSourceMap));
|
||||
|
||||
if (haveSourceMap) {
|
||||
UniqueTwoByteChars& sourceMapURL(ss->sourceMapURL_);
|
||||
uint32_t sourceMapURLLen =
|
||||
(mode == XDR_DECODE) ? 0 : js_strlen(sourceMapURL.get());
|
||||
MOZ_TRY(xdr->codeUint32(&sourceMapURLLen));
|
||||
XDRTranscodeString<char16_t> chars;
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
chars.construct<const char16_t*>(ss->sourceMapURL());
|
||||
}
|
||||
MOZ_TRY(xdr->codeCharsZ(chars));
|
||||
if (mode == XDR_DECODE) {
|
||||
sourceMapURL =
|
||||
xdr->cx()->template make_pod_array<char16_t>(sourceMapURLLen + 1);
|
||||
if (!sourceMapURL) {
|
||||
if (!ss->setSourceMapURL(cx,
|
||||
std::move(chars.ref<UniqueTwoByteChars>()))) {
|
||||
return xdr->fail(JS::TranscodeResult_Throw);
|
||||
}
|
||||
}
|
||||
auto guard = mozilla::MakeScopeExit([&] {
|
||||
if (mode == XDR_DECODE) {
|
||||
sourceMapURL = nullptr;
|
||||
}
|
||||
});
|
||||
MOZ_TRY(xdr->codeChars(sourceMapURL.get(), sourceMapURLLen));
|
||||
guard.release();
|
||||
sourceMapURL[sourceMapURLLen] = '\0';
|
||||
}
|
||||
|
||||
uint8_t haveDisplayURL = ss->hasDisplayURL();
|
||||
MOZ_TRY(xdr->codeUint8(&haveDisplayURL));
|
||||
|
||||
if (haveDisplayURL) {
|
||||
UniqueTwoByteChars& displayURL(ss->displayURL_);
|
||||
uint32_t displayURLLen =
|
||||
(mode == XDR_DECODE) ? 0 : js_strlen(displayURL.get());
|
||||
MOZ_TRY(xdr->codeUint32(&displayURLLen));
|
||||
XDRTranscodeString<char16_t> chars;
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
chars.construct<const char16_t*>(ss->displayURL());
|
||||
}
|
||||
MOZ_TRY(xdr->codeCharsZ(chars));
|
||||
if (mode == XDR_DECODE) {
|
||||
displayURL =
|
||||
xdr->cx()->template make_pod_array<char16_t>(displayURLLen + 1);
|
||||
if (!displayURL) {
|
||||
if (!ss->setDisplayURL(cx, std::move(chars.ref<UniqueTwoByteChars>()))) {
|
||||
return xdr->fail(JS::TranscodeResult_Throw);
|
||||
}
|
||||
}
|
||||
auto guard = mozilla::MakeScopeExit([&] {
|
||||
if (mode == XDR_DECODE) {
|
||||
displayURL = nullptr;
|
||||
}
|
||||
});
|
||||
MOZ_TRY(xdr->codeChars(displayURL.get(), displayURLLen));
|
||||
guard.release();
|
||||
displayURL[displayURLLen] = '\0';
|
||||
}
|
||||
|
||||
uint8_t haveFilename = !!ss->filename_;
|
||||
MOZ_TRY(xdr->codeUint8(&haveFilename));
|
||||
|
||||
if (haveFilename) {
|
||||
const char* fn = ss->filename();
|
||||
MOZ_TRY(xdr->codeCString(&fn));
|
||||
// Note: If the decoder has an option, then the filename is defined by
|
||||
// the CompileOption from the document.
|
||||
MOZ_ASSERT_IF(mode == XDR_DECODE && xdr->hasOptions(), ss->filename());
|
||||
if (mode == XDR_DECODE && !xdr->hasOptions() &&
|
||||
!ss->setFilename(xdr->cx(), fn)) {
|
||||
return xdr->fail(JS::TranscodeResult_Throw);
|
||||
}
|
||||
XDRTranscodeString<char> chars;
|
||||
|
||||
// Note the content of sources decoded when recording or replaying.
|
||||
if (mode == XDR_ENCODE) {
|
||||
chars.construct<const char*>(ss->filename());
|
||||
}
|
||||
MOZ_TRY(xdr->codeCharsZ(chars));
|
||||
if (mode == XDR_DECODE) {
|
||||
// NOTE: If the decoder has an option, then the filename is defined by
|
||||
// the CompileOption from the document.
|
||||
if (!xdr->hasOptions()) {
|
||||
if (!ss->setFilename(cx, std::move(chars.ref<UniqueChars>()))) {
|
||||
return xdr->fail(JS::TranscodeResult_Throw);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(ss->filename());
|
||||
|
||||
// Note the content of sources decoded when recording or replaying.
|
||||
if (!MaybeNoteContentParse(xdr->cx(), ss)) {
|
||||
return xdr->fail(JS::TranscodeResult_Throw);
|
||||
}
|
||||
|
@ -3455,9 +3442,12 @@ bool ScriptSource::initFromOptions(JSContext* cx,
|
|||
MOZ_ASSERT(options.introductionType != nullptr);
|
||||
const char* filename =
|
||||
options.filename() ? options.filename() : "<unknown>";
|
||||
filename_ = FormatIntroducedFilename(
|
||||
UniqueChars formatted = FormatIntroducedFilename(
|
||||
cx, filename, options.introductionLineno, options.introductionType);
|
||||
if (!filename_) {
|
||||
if (!formatted) {
|
||||
return false;
|
||||
}
|
||||
if (!setFilename(cx, std::move(formatted))) {
|
||||
return false;
|
||||
}
|
||||
} else if (options.filename()) {
|
||||
|
@ -3467,8 +3457,7 @@ bool ScriptSource::initFromOptions(JSContext* cx,
|
|||
}
|
||||
|
||||
if (options.introducerFilename()) {
|
||||
introducerFilename_ = DuplicateString(cx, options.introducerFilename());
|
||||
if (!introducerFilename_) {
|
||||
if (!setIntroducerFilename(cx, options.introducerFilename())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3476,43 +3465,104 @@ bool ScriptSource::initFromOptions(JSContext* cx,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ScriptSource::setFilename(JSContext* cx, const char* filename) {
|
||||
MOZ_ASSERT(!filename_);
|
||||
filename_ = DuplicateString(cx, filename);
|
||||
return filename_ != nullptr;
|
||||
// Use the SharedImmutableString map to deduplicate input string. The input
|
||||
// string must be null-terminated.
|
||||
template <typename SharedT, typename CharT>
|
||||
static Maybe<SharedT> GetOrCreateStringZ(
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy>&& str) {
|
||||
JSRuntime* rt = cx->zone()->runtimeFromAnyThread();
|
||||
size_t lengthWithNull = std::char_traits<CharT>::length(str.get()) + 1;
|
||||
auto res =
|
||||
rt->sharedImmutableStrings().getOrCreate(std::move(str), lengthWithNull);
|
||||
if (!res) {
|
||||
ReportOutOfMemory(cx);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool ScriptSource::setDisplayURL(JSContext* cx, const char16_t* displayURL) {
|
||||
MOZ_ASSERT(displayURL);
|
||||
Maybe<SharedImmutableString> ScriptSource::getOrCreateStringZ(
|
||||
JSContext* cx, UniqueChars&& str) {
|
||||
return GetOrCreateStringZ<SharedImmutableString>(cx, std::move(str));
|
||||
}
|
||||
|
||||
Maybe<SharedImmutableTwoByteString> ScriptSource::getOrCreateStringZ(
|
||||
JSContext* cx, UniqueTwoByteChars&& str) {
|
||||
return GetOrCreateStringZ<SharedImmutableTwoByteString>(cx, std::move(str));
|
||||
}
|
||||
|
||||
bool ScriptSource::setFilename(JSContext* cx, const char* filename) {
|
||||
UniqueChars owned = DuplicateString(cx, filename);
|
||||
if (!owned) {
|
||||
return false;
|
||||
}
|
||||
return setFilename(cx, std::move(owned));
|
||||
}
|
||||
|
||||
bool ScriptSource::setFilename(JSContext* cx, UniqueChars&& filename) {
|
||||
MOZ_ASSERT(!filename_);
|
||||
filename_ = getOrCreateStringZ(cx, std::move(filename));
|
||||
return filename_.isSome();
|
||||
}
|
||||
|
||||
bool ScriptSource::setIntroducerFilename(JSContext* cx, const char* filename) {
|
||||
UniqueChars owned = DuplicateString(cx, filename);
|
||||
if (!owned) {
|
||||
return false;
|
||||
}
|
||||
return setIntroducerFilename(cx, std::move(owned));
|
||||
}
|
||||
|
||||
bool ScriptSource::setIntroducerFilename(JSContext* cx,
|
||||
UniqueChars&& filename) {
|
||||
MOZ_ASSERT(!introducerFilename_);
|
||||
introducerFilename_ = getOrCreateStringZ(cx, std::move(filename));
|
||||
return introducerFilename_.isSome();
|
||||
}
|
||||
|
||||
bool ScriptSource::setDisplayURL(JSContext* cx, const char16_t* url) {
|
||||
UniqueTwoByteChars owned = DuplicateString(cx, url);
|
||||
if (!owned) {
|
||||
return false;
|
||||
}
|
||||
return setDisplayURL(cx, std::move(owned));
|
||||
}
|
||||
|
||||
bool ScriptSource::setDisplayURL(JSContext* cx, UniqueTwoByteChars&& url) {
|
||||
if (hasDisplayURL()) {
|
||||
// FIXME: filename_.get() should be UTF-8 (bug 987069).
|
||||
// FIXME: filename() should be UTF-8 (bug 987069).
|
||||
if (!cx->isHelperThreadContext() &&
|
||||
!JS_ReportErrorFlagsAndNumberLatin1(
|
||||
cx, JSREPORT_WARNING, GetErrorMessage, nullptr,
|
||||
JSMSG_ALREADY_HAS_PRAGMA, filename_.get(), "//# sourceURL")) {
|
||||
JSMSG_ALREADY_HAS_PRAGMA, filename(), "//# sourceURL")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
size_t len = js_strlen(displayURL) + 1;
|
||||
if (len == 1) {
|
||||
|
||||
MOZ_ASSERT(url);
|
||||
if (url[0] == '\0') {
|
||||
return true;
|
||||
}
|
||||
|
||||
displayURL_ = DuplicateString(cx, displayURL);
|
||||
return displayURL_ != nullptr;
|
||||
displayURL_ = getOrCreateStringZ(cx, std::move(url));
|
||||
return displayURL_.isSome();
|
||||
}
|
||||
|
||||
bool ScriptSource::setSourceMapURL(JSContext* cx,
|
||||
const char16_t* sourceMapURL) {
|
||||
MOZ_ASSERT(sourceMapURL);
|
||||
bool ScriptSource::setSourceMapURL(JSContext* cx, const char16_t* url) {
|
||||
UniqueTwoByteChars owned = DuplicateString(cx, url);
|
||||
if (!owned) {
|
||||
return false;
|
||||
}
|
||||
return setSourceMapURL(cx, std::move(owned));
|
||||
}
|
||||
|
||||
size_t len = js_strlen(sourceMapURL) + 1;
|
||||
if (len == 1) {
|
||||
bool ScriptSource::setSourceMapURL(JSContext* cx, UniqueTwoByteChars&& url) {
|
||||
MOZ_ASSERT(url);
|
||||
if (url[0] == '\0') {
|
||||
return true;
|
||||
}
|
||||
|
||||
sourceMapURL_ = DuplicateString(cx, sourceMapURL);
|
||||
return sourceMapURL_ != nullptr;
|
||||
sourceMapURL_ = getOrCreateStringZ(cx, std::move(url));
|
||||
return sourceMapURL_.isSome();
|
||||
}
|
||||
|
||||
/* static */ mozilla::Atomic<uint32_t, mozilla::SequentiallyConsistent,
|
||||
|
|
|
@ -611,7 +611,7 @@ class ScriptSource {
|
|||
pendingCompressed_;
|
||||
|
||||
// The filename of this script.
|
||||
UniqueChars filename_ = nullptr;
|
||||
mozilla::Maybe<SharedImmutableString> filename_;
|
||||
|
||||
// If this ScriptSource was generated by a code-introduction mechanism such
|
||||
// as |eval| or |new Function|, the debugger needs access to the "raw"
|
||||
|
@ -621,12 +621,12 @@ class ScriptSource {
|
|||
// "foo.js line 30 > eval line 10 > Function", we can obtain the original
|
||||
// raw filename of "foo.js".
|
||||
//
|
||||
// In the case described above, this field will be non-null and will be the
|
||||
// original raw filename from above. Otherwise this field will be null.
|
||||
UniqueChars introducerFilename_ = nullptr;
|
||||
// In the case described above, this field will be set to to the original raw
|
||||
// filename from above, otherwise it will be mozilla::Nothing.
|
||||
mozilla::Maybe<SharedImmutableString> introducerFilename_;
|
||||
|
||||
UniqueTwoByteChars displayURL_ = nullptr;
|
||||
UniqueTwoByteChars sourceMapURL_ = nullptr;
|
||||
mozilla::Maybe<SharedImmutableTwoByteString> displayURL_;
|
||||
mozilla::Maybe<SharedImmutableTwoByteString> sourceMapURL_;
|
||||
|
||||
// The bytecode cache encoder is used to encode only the content of function
|
||||
// which are delazified. If this value is not nullptr, then each delazified
|
||||
|
@ -714,6 +714,11 @@ class ScriptSource {
|
|||
*/
|
||||
static constexpr size_t MinimumCompressibleLength = 256;
|
||||
|
||||
mozilla::Maybe<SharedImmutableString> getOrCreateStringZ(JSContext* cx,
|
||||
UniqueChars&& str);
|
||||
mozilla::Maybe<SharedImmutableTwoByteString> getOrCreateStringZ(
|
||||
JSContext* cx, UniqueTwoByteChars&& str);
|
||||
|
||||
private:
|
||||
class LoadSourceMatcher;
|
||||
|
||||
|
@ -1101,35 +1106,38 @@ class ScriptSource {
|
|||
XDRState<mode>* xdr, uint8_t sourceCharSize, uint32_t uncompressedLength);
|
||||
|
||||
public:
|
||||
MOZ_MUST_USE bool setFilename(JSContext* cx, const char* filename);
|
||||
const char* introducerFilename() const {
|
||||
return introducerFilename_ ? introducerFilename_.get() : filename_.get();
|
||||
const char* filename() const {
|
||||
return filename_ ? filename_.ref().chars() : nullptr;
|
||||
}
|
||||
MOZ_MUST_USE bool setFilename(JSContext* cx, const char* filename);
|
||||
MOZ_MUST_USE bool setFilename(JSContext* cx, UniqueChars&& filename);
|
||||
|
||||
const char* introducerFilename() const {
|
||||
return introducerFilename_ ? introducerFilename_.ref().chars() : filename();
|
||||
}
|
||||
MOZ_MUST_USE bool setIntroducerFilename(JSContext* cx, const char* filename);
|
||||
MOZ_MUST_USE bool setIntroducerFilename(JSContext* cx,
|
||||
UniqueChars&& filename);
|
||||
|
||||
bool hasIntroductionType() const { return introductionType_; }
|
||||
const char* introductionType() const {
|
||||
MOZ_ASSERT(hasIntroductionType());
|
||||
return introductionType_;
|
||||
}
|
||||
const char* filename() const { return filename_.get(); }
|
||||
|
||||
uint32_t id() const { return id_; }
|
||||
|
||||
// Display URLs
|
||||
MOZ_MUST_USE bool setDisplayURL(JSContext* cx, const char16_t* displayURL);
|
||||
bool hasDisplayURL() const { return displayURL_ != nullptr; }
|
||||
const char16_t* displayURL() {
|
||||
MOZ_ASSERT(hasDisplayURL());
|
||||
return displayURL_.get();
|
||||
}
|
||||
MOZ_MUST_USE bool setDisplayURL(JSContext* cx, const char16_t* url);
|
||||
MOZ_MUST_USE bool setDisplayURL(JSContext* cx, UniqueTwoByteChars&& url);
|
||||
bool hasDisplayURL() const { return displayURL_.isSome(); }
|
||||
const char16_t* displayURL() { return displayURL_.ref().chars(); }
|
||||
|
||||
// Source maps
|
||||
MOZ_MUST_USE bool setSourceMapURL(JSContext* cx,
|
||||
const char16_t* sourceMapURL);
|
||||
bool hasSourceMapURL() const { return sourceMapURL_ != nullptr; }
|
||||
const char16_t* sourceMapURL() {
|
||||
MOZ_ASSERT(hasSourceMapURL());
|
||||
return sourceMapURL_.get();
|
||||
}
|
||||
MOZ_MUST_USE bool setSourceMapURL(JSContext* cx, const char16_t* url);
|
||||
MOZ_MUST_USE bool setSourceMapURL(JSContext* cx, UniqueTwoByteChars&& url);
|
||||
bool hasSourceMapURL() const { return sourceMapURL_.isSome(); }
|
||||
const char16_t* sourceMapURL() { return sourceMapURL_.ref().chars(); }
|
||||
|
||||
bool mutedErrors() const { return mutedErrors_; }
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ class JSString : public js::gc::CellWithLengthAndFlags<js::gc::Cell> {
|
|||
"shadow::String::EXTERNAL_FLAGS must match JSString::EXTERNAL_FLAGS");
|
||||
}
|
||||
|
||||
/* Avoid lame compile errors in JSRope::flatten */
|
||||
/* Avoid silly compile errors in JSRope::flatten */
|
||||
friend class JSRope;
|
||||
|
||||
friend class js::gc::RelocationOverlay;
|
||||
|
|
|
@ -42,6 +42,11 @@ bool XDRCoderBase::validateResultCode(JSContext* cx,
|
|||
}
|
||||
#endif
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRState<mode>::codeChars(char* chars, size_t nchars) {
|
||||
return codeBytes(chars, nchars);
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRState<mode>::codeChars(Latin1Char* chars, size_t nchars) {
|
||||
static_assert(sizeof(Latin1Char) == 1,
|
||||
|
@ -107,6 +112,62 @@ XDRResult XDRState<mode>::codeChars(char16_t* chars, size_t nchars) {
|
|||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode, typename CharT>
|
||||
static XDRResult XDRCodeCharsZ(XDRState<mode>* xdr,
|
||||
XDRTranscodeString<CharT>& buffer) {
|
||||
MOZ_ASSERT_IF(mode == XDR_ENCODE, !buffer.empty());
|
||||
MOZ_ASSERT_IF(mode == XDR_DECODE, buffer.empty());
|
||||
|
||||
using OwnedString = js::UniquePtr<CharT[], JS::FreePolicy>;
|
||||
OwnedString owned;
|
||||
|
||||
static_assert(JSString::MAX_LENGTH <= INT32_MAX,
|
||||
"String length must fit in int32_t");
|
||||
|
||||
uint32_t length = 0;
|
||||
CharT* chars = nullptr;
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
chars = const_cast<CharT*>(buffer.template ref<const CharT*>());
|
||||
|
||||
// Set a reasonable limit on string length.
|
||||
size_t lengthSizeT = std::char_traits<CharT>::length(chars);
|
||||
if (lengthSizeT > JSString::MAX_LENGTH) {
|
||||
ReportAllocationOverflow(xdr->cx());
|
||||
return xdr->fail(JS::TranscodeResult_Throw);
|
||||
}
|
||||
length = static_cast<uint32_t>(lengthSizeT);
|
||||
}
|
||||
MOZ_TRY(xdr->codeUint32(&length));
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
owned = xdr->cx()->template make_pod_array<CharT>(length + 1);
|
||||
if (!owned) {
|
||||
return xdr->fail(JS::TranscodeResult_Throw);
|
||||
}
|
||||
chars = owned.get();
|
||||
}
|
||||
|
||||
MOZ_TRY(xdr->codeChars(chars, length));
|
||||
if (mode == XDR_DECODE) {
|
||||
// Null-terminate and transfer ownership to caller.
|
||||
owned[length] = '\0';
|
||||
buffer.template construct<OwnedString>(std::move(owned));
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRState<mode>::codeCharsZ(XDRTranscodeString<char>& buffer) {
|
||||
return XDRCodeCharsZ(this, buffer);
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRState<mode>::codeCharsZ(XDRTranscodeString<char16_t>& buffer) {
|
||||
return XDRCodeCharsZ(this, buffer);
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult VersionCheck(XDRState<mode>* xdr) {
|
||||
JS::BuildIdCharVector buildId;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define vm_Xdr_h
|
||||
|
||||
#include "mozilla/EndianUtils.h"
|
||||
#include "mozilla/MaybeOneOf.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#include "mozilla/Utf8.h"
|
||||
|
||||
|
@ -79,11 +80,6 @@ class XDRBuffer<XDR_ENCODE> : public XDRBufferBase {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
uintptr_t uptr() const {
|
||||
// Note: Avoid bounds check assertion if the buffer is not yet allocated.
|
||||
return reinterpret_cast<uintptr_t>(buffer_.begin() + cursor_);
|
||||
}
|
||||
|
||||
private:
|
||||
JS::TranscodeBuffer& buffer_;
|
||||
};
|
||||
|
@ -115,11 +111,6 @@ class XDRBuffer<XDR_DECODE> : public XDRBufferBase {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
uintptr_t uptr() const {
|
||||
// Note: Avoid bounds check assertion at the end of the buffer.
|
||||
return reinterpret_cast<uintptr_t>(buffer_.begin().get() + cursor_);
|
||||
}
|
||||
|
||||
private:
|
||||
const JS::TranscodeRange buffer_;
|
||||
};
|
||||
|
@ -168,6 +159,10 @@ class MOZ_RAII AutoXDRTree {
|
|||
XDRCoderBase* xdr_;
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
using XDRTranscodeString =
|
||||
mozilla::MaybeOneOf<const CharT*, js::UniquePtr<CharT[], JS::FreePolicy>>;
|
||||
|
||||
class XDRCoderBase {
|
||||
private:
|
||||
#ifdef DEBUG
|
||||
|
@ -387,42 +382,20 @@ class XDRState : public XDRCoderBase {
|
|||
return Ok();
|
||||
}
|
||||
|
||||
/*
|
||||
* During encoding the string is written into the buffer together with its
|
||||
* terminating '\0'. During decoding the method returns a pointer into the
|
||||
* decoding buffer and the caller must copy the string if it will outlive
|
||||
* the decoding buffer.
|
||||
*/
|
||||
XDRResult codeCString(const char** sp) {
|
||||
uint64_t len64;
|
||||
if (mode == XDR_ENCODE) {
|
||||
len64 = (uint64_t)(strlen(*sp) + 1);
|
||||
}
|
||||
MOZ_TRY(codeUint64(&len64));
|
||||
size_t len = (size_t)len64;
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
uint8_t* ptr = buf.write(len);
|
||||
if (!ptr) {
|
||||
return fail(JS::TranscodeResult_Throw);
|
||||
}
|
||||
memcpy(ptr, *sp, len);
|
||||
MOZ_ASSERT(ptr[len - 1] == '\0');
|
||||
} else {
|
||||
const uint8_t* ptr = buf.read(len);
|
||||
if (!ptr || ptr[len - 1] != '\0') {
|
||||
return fail(JS::TranscodeResult_Failure_BadDecode);
|
||||
}
|
||||
*sp = reinterpret_cast<const char*>(ptr);
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
// Prefer using a variant below that is encoding aware.
|
||||
XDRResult codeChars(char* chars, size_t nchars);
|
||||
|
||||
XDRResult codeChars(JS::Latin1Char* chars, size_t nchars);
|
||||
XDRResult codeChars(mozilla::Utf8Unit* units, size_t nchars);
|
||||
|
||||
XDRResult codeChars(char16_t* chars, size_t nchars);
|
||||
|
||||
// Transcode null-terminated strings. When decoding, a new buffer is
|
||||
// allocated and ownership is returned to caller.
|
||||
//
|
||||
// NOTE: Throws if string longer than JSString::MAX_LENGTH.
|
||||
XDRResult codeCharsZ(XDRTranscodeString<char>& buffer);
|
||||
XDRResult codeCharsZ(XDRTranscodeString<char16_t>& buffer);
|
||||
|
||||
XDRResult codeFunction(JS::MutableHandleFunction objp,
|
||||
HandleScriptSourceObject sourceObject = nullptr);
|
||||
XDRResult codeScript(MutableHandleScript scriptp);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>Testcase, bug 1576864</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<style>
|
||||
|
||||
fieldset {
|
||||
background: aqua;
|
||||
color: black;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<fieldset id="set" style="width:200px; height:200px;">
|
||||
This should be in a square.
|
||||
</fieldset>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>Testcase, bug 1576864</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<style>
|
||||
|
||||
fieldset {
|
||||
background: aqua;
|
||||
color: black;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
window.onload=function(){
|
||||
document.body.offsetHeight;
|
||||
document.getElementById("set").style.height = "200px";
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<fieldset id="set" style="width:200px; height:40px;">
|
||||
This should be in a square.
|
||||
</fieldset>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -27,3 +27,4 @@ fuzzy-if(skiaContent,0-1,0-40768) == abs-pos-child-sizing.html abs-pos-child-siz
|
|||
== fieldset-border-image-2a.html fieldset-border-image-2-ref.html
|
||||
== fieldset-border-image-2b.html fieldset-border-image-2-ref.html
|
||||
== dynamic-text-indent.html dynamic-text-indent-ref.html
|
||||
== fieldset-height-resize-1.html fieldset-height-resize-1-ref.html
|
||||
|
|
|
@ -28,9 +28,7 @@
|
|||
<p>
|
||||
Here is specified the decoration style as -moz-none.
|
||||
</p>
|
||||
<!-- "text-decoration-skip-ink: none" is hackaround for bug 1575338 -->
|
||||
<p style="text-decoration-skip-ink: none;
|
||||
text-decoration: underline line-through overline;">
|
||||
<p style="text-decoration: underline line-through overline;">
|
||||
Here has solid decoration lines even if its style is specified as dotted
|
||||
before text-decoration.
|
||||
</p>
|
||||
|
|
|
@ -27,9 +27,7 @@
|
|||
text-decoration-style: -moz-none;">
|
||||
Here is specified the decoration style as -moz-none.
|
||||
</p>
|
||||
<!-- "text-decoration-skip-ink: none" is hackaround for bug 1575338 -->
|
||||
<p style="text-decoration-skip-ink: none;
|
||||
text-decoration-style: dotted;
|
||||
<p style="text-decoration-style: dotted;
|
||||
text-decoration: underline line-through overline;">
|
||||
Here has solid decoration lines even if its style is specified as dotted
|
||||
before text-decoration.
|
||||
|
|
|
@ -419,7 +419,7 @@ nsresult nsMenuBarListener::KeyDown(Event* aKeyEvent) {
|
|||
bool defaultPrevented = aKeyEvent->DefaultPrevented();
|
||||
|
||||
// No other modifiers can be down.
|
||||
// Especially CTRL. CTRL+ALT == AltGR, and we'll fuck up on non-US
|
||||
// Especially CTRL. CTRL+ALT == AltGR, and we'll break on non-US
|
||||
// enhanced 102-key keyboards if we don't check this.
|
||||
bool isAccessKeyDownEvent =
|
||||
((theChar == (uint32_t)mAccessKey) &&
|
||||
|
|
|
@ -417,7 +417,7 @@ int TestNrSocket::recvfrom(void* buf, size_t maxlen, size_t* len, int flags,
|
|||
}
|
||||
}
|
||||
|
||||
// Kinda lame that we are forced to give the app a readable callback and then
|
||||
// Kinda bad that we are forced to give the app a readable callback and then
|
||||
// say "Oh, never mind...", but the alternative is to totally decouple the
|
||||
// callbacks from STS and the callbacks the app sets. On the bright side, this
|
||||
// speeds up unit tests where we are verifying that ingress is forbidden,
|
||||
|
|
|
@ -163,7 +163,6 @@
|
|||
<p>First given a offending pixel I was able to set a breakpoint on it using <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Hacking_Tips#rr_with_reftest">these instructions</a>. Next using <a href="https://github.com/jrmuizel/rr-dataflow">rr-dataflow</a> I was able to step from the offending bad pixel to the display item responsible for this pixel. Let me emphasize this for a second since it’s incredibly impressive. rr + rr-dataflow allows you to go from a buffer, through an intermediate surface, to the compositor on another thread, through another intermediate surface, back to the main thread and eventually back to the relevant display item. All of this was automated except for when the two pixels are blended together which is logically ambiguous. The speed at which rr was able to reverse continue through this execution was very impressive!</p>
|
||||
<p>Here’s the trace of this part: <a href="https://gist.github.com/bgirard/e707e9b97556b500d9ae">rr-trace-reftest-pixel-origin</a></p>
|
||||
<h3>Understanding the decoding step</h3>
|
||||
<p>From here I started comparing a replay of a failing test and a non failing step and it was clear that the DisplayList was different. In one we have a nsDisplayBackgroundColor in the other we don’t. From here I was able to step through the decoder and compare the sequence. This was very useful in ruling out possible theories. It was easy to step forward and backwards in the good and bad replay debugging sessions to test out various theories about race conditions and understanding at which part of the decode process the image was rejected. It turned out that we sent two decodes, one for the metadata that is used to sized the frame tree and the other one for the image data itself.</p>
|
||||
<h3>Comparing the frame tree</h3>
|
||||
<p>In hindsight, it would have been more effective to start debugging this test by looking at the frame tree (and I imagine for other tests looking at the display list and layer tree) first would have been a quicker start. It works even better if you have a good and a bad trace to compare the difference in the frame tree. From here, I found that the difference in the layer tree came from a change hint that wasn’t guaranteed to come in before the draw.</p>
|
||||
<p>The problem is now well understood: When we do a sync decode on reftest draw, if there’s an image error we wont flush the style hints since we’re already too deep in the painting pipeline.</p>
|
||||
|
@ -408,8 +407,6 @@
|
|||
<title xml:lang="en-us">Robbie Burns</title>
|
||||
<content type="xhtml" xml:lang="en-us"><div xmlns="http://www.w3.org/1999/xhtml"><p>Tonight is Robbie Burns night, in honour of that great Scottish poet. But tonight had me thinking about another night in my past.</p>
|
||||
|
||||
<p>It was about 5 years ago, maybe less, I struggle to remember now. I was in the UK visiting family and my Dad was sick. Cancer and it's treatment is tough, you have good weeks, you have bad weeks and you have really fucking bad weeks. This was a good week and for some reason I was in the UK.</p>
|
||||
|
||||
<p>Myself, my brother and my sister-in-law went down to see him that night. It was Robbie Burns night and that meant an excuse for haggis, really, truly terrible scotch, Scottish dancing and all that. There are many times when I look back at time with my Dad in those last few years. This was definitely one of those times. He was my Dad at his best, cracking jokes and having fun. Living life to the absolute fullest, while you still have that chance.</p>
|
||||
|
||||
<p>We had a great night. That ended way too soon.</p>
|
||||
|
|
|
@ -463,8 +463,6 @@
|
|||
<link>http://www.agmweb.ca/2016-01-25-robbie-burns/</link>
|
||||
<content:encoded><p>Tonight is Robbie Burns night, in honour of that great Scottish poet. But tonight had me thinking about another night in my past.</p>
|
||||
|
||||
<p>It was about 5 years ago, maybe less, I struggle to remember now. I was in the UK visiting family and my Dad was sick. Cancer and it's treatment is tough, you have good weeks, you have bad weeks and you have really fucking bad weeks. This was a good week and for some reason I was in the UK.</p>
|
||||
|
||||
<p>Myself, my brother and my sister-in-law went down to see him that night. It was Robbie Burns night and that meant an excuse for haggis, really, truly terrible scotch, Scottish dancing and all that. There are many times when I look back at time with my Dad in those last few years. This was definitely one of those times. He was my Dad at his best, cracking jokes and having fun. Living life to the absolute fullest, while you still have that chance.</p>
|
||||
|
||||
<p>We had a great night. That ended way too soon.</p>
|
||||
|
|
|
@ -393,8 +393,6 @@
|
|||
<link>http://www.agmweb.ca/2016-01-25-robbie-burns/</link>
|
||||
<description><p>Tonight is Robbie Burns night, in honour of that great Scottish poet. But tonight had me thinking about another night in my past.</p>
|
||||
|
||||
<p>It was about 5 years ago, maybe less, I struggle to remember now. I was in the UK visiting family and my Dad was sick. Cancer and it's treatment is tough, you have good weeks, you have bad weeks and you have really fucking bad weeks. This was a good week and for some reason I was in the UK.</p>
|
||||
|
||||
<p>Myself, my brother and my sister-in-law went down to see him that night. It was Robbie Burns night and that meant an excuse for haggis, really, truly terrible scotch, Scottish dancing and all that. There are many times when I look back at time with my Dad in those last few years. This was definitely one of those times. He was my Dad at his best, cracking jokes and having fun. Living life to the absolute fullest, while you still have that chance.</p>
|
||||
|
||||
<p>We had a great night. That ended way too soon.</p>
|
||||
|
|
|
@ -6449,6 +6449,12 @@
|
|||
value: 2592000 # 30 days (in seconds)
|
||||
mirror: always
|
||||
|
||||
# Report Anti-tracking warnings to console lazily
|
||||
- name: privacy.restrict3rdpartystorage.console.lazy
|
||||
type: bool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Anti-tracking user-interaction expiration.
|
||||
- name: privacy.userInteraction.expiration
|
||||
type: uint32_t
|
||||
|
@ -6714,7 +6720,7 @@
|
|||
mirror: always
|
||||
|
||||
- name: toolkit.telemetry.geckoview.batchDurationMS
|
||||
type: uint32_t
|
||||
type: RelaxedAtomicUint32
|
||||
value: 5000
|
||||
mirror: always
|
||||
|
||||
|
|
|
@ -3035,7 +3035,10 @@ void nsCookieService::GetCookiesForURI(
|
|||
// (but not if there was an error)
|
||||
switch (cookieStatus) {
|
||||
case STATUS_REJECTED:
|
||||
NotifyRejected(aHostURI, aChannel, rejectedReason, OPERATION_READ);
|
||||
// If we don't have any cookies from this host, fail silently.
|
||||
if (priorCookieCount) {
|
||||
NotifyRejected(aHostURI, aChannel, rejectedReason, OPERATION_READ);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -191,18 +191,15 @@
|
|||
}
|
||||
},
|
||||
"ansi-escapes": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz",
|
||||
"integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.5.2"
|
||||
}
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
|
||||
"integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
|
@ -265,17 +262,17 @@
|
|||
}
|
||||
},
|
||||
"babel-eslint": {
|
||||
"version": "10.0.2",
|
||||
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.2.tgz",
|
||||
"integrity": "sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q==",
|
||||
"version": "10.0.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz",
|
||||
"integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"@babel/parser": "^7.0.0",
|
||||
"@babel/traverse": "^7.0.0",
|
||||
"@babel/types": "^7.0.0",
|
||||
"eslint-scope": "3.7.1",
|
||||
"eslint-visitor-keys": "^1.0.0"
|
||||
"eslint-visitor-keys": "^1.0.0",
|
||||
"resolve": "^1.12.0"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
|
@ -318,12 +315,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
|
||||
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"restore-cursor": "^3.1.0"
|
||||
"restore-cursor": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"cli-width": {
|
||||
|
@ -475,9 +472,9 @@
|
|||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
|
||||
"dev": true
|
||||
},
|
||||
"entities": {
|
||||
|
@ -527,9 +524,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"eslint": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz",
|
||||
"integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.2.2.tgz",
|
||||
"integrity": "sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
|
@ -539,9 +536,9 @@
|
|||
"debug": "^4.0.1",
|
||||
"doctrine": "^3.0.0",
|
||||
"eslint-scope": "^5.0.0",
|
||||
"eslint-utils": "^1.3.1",
|
||||
"eslint-visitor-keys": "^1.0.0",
|
||||
"espree": "^6.0.0",
|
||||
"eslint-utils": "^1.4.2",
|
||||
"eslint-visitor-keys": "^1.1.0",
|
||||
"espree": "^6.1.1",
|
||||
"esquery": "^1.0.1",
|
||||
"esutils": "^2.0.2",
|
||||
"file-entry-cache": "^5.0.1",
|
||||
|
@ -569,24 +566,12 @@
|
|||
"table": "^5.2.3",
|
||||
"text-table": "^0.2.0",
|
||||
"v8-compile-cache": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-scope": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
|
||||
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esrecurse": "^4.1.0",
|
||||
"estraverse": "^4.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-config-prettier": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz",
|
||||
"integrity": "sha512-vDrcCFE3+2ixNT5H83g28bO/uYAwibJxerXPj+E7op4qzBCsAV36QfvdAyVOoNxKAH2Os/e01T/2x++V0LPukA==",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.1.0.tgz",
|
||||
"integrity": "sha512-k9fny9sPjIBQ2ftFTesJV21Rg4R/7a7t7LCtZVrYQiHEp8Nnuk3EGaDmsKSAnsPj0BYcgB2zxzHa2NTkIxcOLg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"get-stdin": "^6.0.0"
|
||||
|
@ -732,9 +717,9 @@
|
|||
}
|
||||
},
|
||||
"eslint-plugin-jest": {
|
||||
"version": "22.15.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.15.1.tgz",
|
||||
"integrity": "sha512-CWq/RR/3tLaKFB+FZcCJwU9hH5q/bKeO3rFP8G07+q7hcDCFNqpvdphVbEbGE6o6qo1UbciEev4ejUWv7brUhw==",
|
||||
"version": "22.15.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.15.2.tgz",
|
||||
"integrity": "sha512-p4NME9TgXIt+KgpxcXyNBvO30ZKxwFAO1dJZBc2OGfDnXVEtPwEyNs95GSr6RIE3xLHdjd8ngDdE2icRRXrbxg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/experimental-utils": "^1.13.0"
|
||||
|
@ -755,14 +740,6 @@
|
|||
"emoji-regex": "^7.0.2",
|
||||
"has": "^1.0.3",
|
||||
"jsx-ast-utils": "^2.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-plugin-mozilla": {
|
||||
|
@ -828,9 +805,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
|
||||
"integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
|
||||
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esrecurse": "^4.1.0",
|
||||
|
@ -853,13 +830,13 @@
|
|||
"dev": true
|
||||
},
|
||||
"espree": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-6.1.0.tgz",
|
||||
"integrity": "sha512-boA7CHRLlVWUSg3iL5Kmlt/xT3Q+sXnKoRYYzj1YeM10A76TEJBbotV5pKbnK42hEUIr121zTv+QLRM5LsCPXQ==",
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz",
|
||||
"integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "^7.0.0",
|
||||
"acorn-jsx": "^5.0.0",
|
||||
"acorn-jsx": "^5.0.2",
|
||||
"eslint-visitor-keys": "^1.1.0"
|
||||
}
|
||||
},
|
||||
|
@ -935,9 +912,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"figures": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz",
|
||||
"integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
|
||||
"integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"escape-string-regexp": "^1.0.5"
|
||||
|
@ -1132,22 +1109,22 @@
|
|||
"dev": true
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.1.tgz",
|
||||
"integrity": "sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw==",
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
|
||||
"integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"ansi-escapes": "^3.2.0",
|
||||
"chalk": "^2.4.2",
|
||||
"cli-cursor": "^3.1.0",
|
||||
"cli-cursor": "^2.1.0",
|
||||
"cli-width": "^2.0.0",
|
||||
"external-editor": "^3.0.3",
|
||||
"figures": "^3.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"mute-stream": "0.0.8",
|
||||
"figures": "^2.0.0",
|
||||
"lodash": "^4.17.12",
|
||||
"mute-stream": "0.0.7",
|
||||
"run-async": "^2.2.0",
|
||||
"rxjs": "^6.4.0",
|
||||
"string-width": "^4.1.0",
|
||||
"string-width": "^2.1.0",
|
||||
"strip-ansi": "^5.1.0",
|
||||
"through": "^2.3.6"
|
||||
}
|
||||
|
@ -1177,9 +1154,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
},
|
||||
"is-glob": {
|
||||
|
@ -1325,9 +1302,9 @@
|
|||
}
|
||||
},
|
||||
"mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
|
||||
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
|
||||
"dev": true
|
||||
},
|
||||
"minimatch": {
|
||||
|
@ -1361,9 +1338,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
|
||||
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
|
||||
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
|
||||
"dev": true
|
||||
},
|
||||
"natural-compare": {
|
||||
|
@ -1468,12 +1445,12 @@
|
|||
}
|
||||
},
|
||||
"onetime": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
|
||||
"integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
|
||||
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
"mimic-fn": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"optionator": {
|
||||
|
@ -1696,12 +1673,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"restore-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
|
||||
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"onetime": "^5.1.0",
|
||||
"onetime": "^2.0.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
}
|
||||
},
|
||||
|
@ -1786,14 +1763,6 @@
|
|||
"ansi-styles": "^3.2.0",
|
||||
"astral-regex": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
|
@ -1841,14 +1810,24 @@
|
|||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz",
|
||||
"integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
|
||||
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^5.2.0"
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"strip-ansi": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
|
@ -1867,6 +1846,14 @@
|
|||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"strip-bom": {
|
||||
|
@ -1902,18 +1889,6 @@
|
|||
"string-width": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||
|
@ -1975,12 +1950,6 @@
|
|||
"prelude-ls": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz",
|
||||
"integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==",
|
||||
"dev": true
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||
|
|
|
@ -7,16 +7,16 @@
|
|||
"yarn": "^1.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "10.0.2",
|
||||
"eslint": "6.1.0",
|
||||
"eslint-config-prettier": "6.0.0",
|
||||
"babel-eslint": "10.0.3",
|
||||
"eslint": "6.2.2",
|
||||
"eslint-config-prettier": "6.1.0",
|
||||
"eslint-plugin-babel": "5.3.0",
|
||||
"eslint-plugin-fetch-options": "0.0.5",
|
||||
"eslint-plugin-file-header": "0.0.1",
|
||||
"eslint-plugin-flowtype": "4.2.0",
|
||||
"eslint-plugin-html": "6.0.0",
|
||||
"eslint-plugin-import": "2.18.2",
|
||||
"eslint-plugin-jest": "22.15.1",
|
||||
"eslint-plugin-jest": "22.15.2",
|
||||
"eslint-plugin-jsx-a11y": "6.2.3",
|
||||
"eslint-plugin-mozilla": "file:tools/lint/eslint/eslint-plugin-mozilla",
|
||||
"eslint-plugin-no-unsanitized": "3.0.2",
|
||||
|
|
|
@ -68,14 +68,17 @@ nsHtml5Highlighter::~nsHtml5Highlighter() {
|
|||
|
||||
void nsHtml5Highlighter::Start(const nsAutoString& aTitle) {
|
||||
// Doctype
|
||||
mOpQueue.AppendElement()->Init(nsGkAtoms::html, EmptyString(), EmptyString());
|
||||
opAppendDoctypeToDocument operation(nsGkAtoms::html, EmptyString(),
|
||||
EmptyString());
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
|
||||
mOpQueue.AppendElement()->Init(STANDARDS_MODE);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(STANDARDS_MODE));
|
||||
|
||||
// <html> uses NS_NewHTMLSharedElement creator
|
||||
nsIContent** root =
|
||||
CreateElement(nsGkAtoms::html, nullptr, nullptr, NS_NewHTMLSharedElement);
|
||||
mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
|
||||
opAppendToDocument appendOp(root);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(appendOp));
|
||||
mStack.AppendElement(root);
|
||||
|
||||
// <head> uses NS_NewHTMLSharedElement creator
|
||||
|
@ -97,7 +100,8 @@ void nsHtml5Highlighter::Start(const nsAutoString& aTitle) {
|
|||
Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes(),
|
||||
NS_NewHTMLLinkElement);
|
||||
|
||||
mOpQueue.AppendElement()->Init(eTreeOpUpdateStyleSheet, CurrentNode());
|
||||
opUpdateStyleSheet updateOp(CurrentNode());
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(updateOp));
|
||||
|
||||
Pop(); // link
|
||||
|
||||
|
@ -113,7 +117,7 @@ void nsHtml5Highlighter::Start(const nsAutoString& aTitle) {
|
|||
|
||||
StartCharacters();
|
||||
|
||||
mOpQueue.AppendElement()->Init(eTreeOpStartLayout);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(opStartLayout()));
|
||||
}
|
||||
|
||||
int32_t nsHtml5Highlighter::Transition(int32_t aState, bool aReconsume,
|
||||
|
@ -466,7 +470,7 @@ void nsHtml5Highlighter::End() {
|
|||
}
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(eTreeOpStreamEnded);
|
||||
treeOp->Init(mozilla::AsVariant(opStreamEnded()));
|
||||
FlushOps();
|
||||
}
|
||||
|
||||
|
@ -561,7 +565,8 @@ void nsHtml5Highlighter::FlushChars() {
|
|||
Push(nsGkAtoms::span, nullptr, NS_NewHTMLSpanElement);
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
|
||||
opAddLineNumberId operation(CurrentNode(), mLineNumber);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
Pop();
|
||||
break;
|
||||
}
|
||||
|
@ -628,11 +633,11 @@ nsIContent** nsHtml5Highlighter::CreateElement(
|
|||
nsIContent** aIntendedParent,
|
||||
mozilla::dom::HTMLContentCreatorFunction aCreator) {
|
||||
MOZ_ASSERT(aName, "Got null name.");
|
||||
nsHtml5ContentCreatorFunction creator;
|
||||
creator.html = aCreator;
|
||||
nsIContent** content = AllocateContentHandle();
|
||||
mOpQueue.AppendElement()->Init(kNameSpaceID_XHTML, aName, aAttributes,
|
||||
content, aIntendedParent, true, creator);
|
||||
opCreateHTMLElement opeation(content, aName, aAttributes, aCreator,
|
||||
aIntendedParent,
|
||||
mozilla::dom::FROM_PARSER_NETWORK);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(opeation));
|
||||
return content;
|
||||
}
|
||||
|
||||
|
@ -647,7 +652,8 @@ void nsHtml5Highlighter::Push(
|
|||
MOZ_ASSERT(mStack.Length() >= 1, "Pushing without root.");
|
||||
nsIContent** elt = CreateElement(aName, aAttributes, CurrentNode(),
|
||||
aCreator); // Don't inline below!
|
||||
mOpQueue.AppendElement()->Init(eTreeOpAppend, elt, CurrentNode());
|
||||
opAppend operation(elt, CurrentNode());
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
mStack.AppendElement(elt);
|
||||
}
|
||||
|
||||
|
@ -663,12 +669,13 @@ void nsHtml5Highlighter::AppendCharacters(const char16_t* aBuffer,
|
|||
char16_t* bufferCopy = new char16_t[aLength];
|
||||
memcpy(bufferCopy, aBuffer + aStart, aLength * sizeof(char16_t));
|
||||
|
||||
mOpQueue.AppendElement()->Init(eTreeOpAppendText, bufferCopy, aLength,
|
||||
CurrentNode());
|
||||
opAppendText operation(CurrentNode(), bufferCopy, aLength);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5Highlighter::AddClass(const char16_t* aClass) {
|
||||
mOpQueue.AppendElement()->InitAddClass(CurrentNode(), aClass);
|
||||
opAddClass operation(CurrentNode(), (char16_t*)aClass);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5Highlighter::AddViewSourceHref(nsHtml5String aValue) {
|
||||
|
@ -676,8 +683,8 @@ void nsHtml5Highlighter::AddViewSourceHref(nsHtml5String aValue) {
|
|||
aValue.CopyToBuffer(bufferCopy);
|
||||
bufferCopy[aValue.Length()] = 0;
|
||||
|
||||
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref, bufferCopy,
|
||||
aValue.Length(), CurrentNode());
|
||||
opAddViewSourceHref operation(CurrentNode(), bufferCopy, aValue.Length());
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5Highlighter::AddBase(nsHtml5String aValue) {
|
||||
|
@ -689,21 +696,23 @@ void nsHtml5Highlighter::AddBase(nsHtml5String aValue) {
|
|||
aValue.CopyToBuffer(bufferCopy);
|
||||
bufferCopy[aValue.Length()] = 0;
|
||||
|
||||
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceBase, bufferCopy,
|
||||
aValue.Length());
|
||||
opAddViewSourceBase operation(bufferCopy, aValue.Length());
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5Highlighter::AddErrorToCurrentNode(const char* aMsgId) {
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(CurrentNode(), aMsgId);
|
||||
opAddErrorType operation(CurrentNode(), (char*)aMsgId);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId) {
|
||||
MOZ_ASSERT(mCurrentRun, "Adding error to run without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mCurrentRun, aMsgId);
|
||||
opAddErrorType operation(mCurrentRun, (char*)aMsgId);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
|
||||
|
@ -711,7 +720,8 @@ void nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
|
|||
MOZ_ASSERT(mCurrentRun, "Adding error to run without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mCurrentRun, aMsgId, aName);
|
||||
opAddErrorType operation(mCurrentRun, (char*)aMsgId, aName);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId, nsAtom* aName,
|
||||
|
@ -719,19 +729,22 @@ void nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId, nsAtom* aName,
|
|||
MOZ_ASSERT(mCurrentRun, "Adding error to run without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mCurrentRun, aMsgId, aName, aOther);
|
||||
opAddErrorType operation(mCurrentRun, (char*)aMsgId, aName, aOther);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5Highlighter::AddErrorToCurrentAmpersand(const char* aMsgId) {
|
||||
MOZ_ASSERT(mAmpersand, "Adding error to ampersand without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mAmpersand, aMsgId);
|
||||
opAddErrorType operation(mAmpersand, (char*)aMsgId);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5Highlighter::AddErrorToCurrentSlash(const char* aMsgId) {
|
||||
MOZ_ASSERT(mSlash, "Adding error to slash without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mSlash, aMsgId);
|
||||
opAddErrorType operation(mSlash, (char*)aMsgId);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
|
|
@ -141,8 +141,26 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
treeOp->Init(aNamespace, aName, aAttributes, content, aIntendedParent,
|
||||
!!mSpeculativeLoadStage, aCreator);
|
||||
|
||||
if (aNamespace == kNameSpaceID_XHTML) {
|
||||
opCreateHTMLElement opeation(
|
||||
content, aName, aAttributes, aCreator.html, aIntendedParent,
|
||||
(!!mSpeculativeLoadStage) ? mozilla::dom::FROM_PARSER_NETWORK
|
||||
: dom::FROM_PARSER_DOCUMENT_WRITE);
|
||||
treeOp->Init(mozilla::AsVariant(opeation));
|
||||
} else if (aNamespace == kNameSpaceID_SVG) {
|
||||
opCreateSVGElement operation(
|
||||
content, aName, aAttributes, aCreator.svg, aIntendedParent,
|
||||
(!!mSpeculativeLoadStage) ? mozilla::dom::FROM_PARSER_NETWORK
|
||||
: dom::FROM_PARSER_DOCUMENT_WRITE);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
} else {
|
||||
// kNameSpaceID_MathML
|
||||
opCreateMathMLElement operation(content, aName, aAttributes,
|
||||
aIntendedParent);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
// mSpeculativeLoadStage is non-null only in the off-the-main-thread
|
||||
// tree builder, which handles the network stream
|
||||
|
||||
|
@ -188,8 +206,9 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
|
|||
NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content,
|
||||
tokenizer->getLineNumber());
|
||||
opSetScriptLineNumberAndFreeze operation(content,
|
||||
tokenizer->getLineNumber());
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
|
||||
nsHtml5String url =
|
||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
|
||||
|
@ -262,8 +281,8 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
|
|||
NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
treeOp->Init(eTreeOpSetStyleLineNumber, content,
|
||||
tokenizer->getLineNumber());
|
||||
opSetStyleLineNumber operation(content, tokenizer->getLineNumber());
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
} else if (nsGkAtoms::html == aName) {
|
||||
nsHtml5String url =
|
||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
|
||||
|
@ -314,8 +333,9 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
|
|||
NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content,
|
||||
tokenizer->getLineNumber());
|
||||
opSetScriptLineNumberAndFreeze operation(content,
|
||||
tokenizer->getLineNumber());
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
|
||||
nsHtml5String url =
|
||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
|
||||
|
@ -340,8 +360,8 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
|
|||
NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
treeOp->Init(eTreeOpSetStyleLineNumber, content,
|
||||
tokenizer->getLineNumber());
|
||||
opSetStyleLineNumber operation(content, tokenizer->getLineNumber());
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
|
||||
nsHtml5String url =
|
||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
|
||||
|
@ -366,16 +386,17 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
treeOp->Init(eTreeOpSetStyleLineNumber, content,
|
||||
tokenizer->getLineNumber());
|
||||
opSetStyleLineNumber operation(content, tokenizer->getLineNumber());
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
} else if (nsGkAtoms::script == aName) {
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
|
||||
if (MOZ_UNLIKELY(!treeOp)) {
|
||||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content,
|
||||
tokenizer->getLineNumber());
|
||||
opSetScriptLineNumberAndFreeze operation(content,
|
||||
tokenizer->getLineNumber());
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
if (aNamespace == kNameSpaceID_XHTML) {
|
||||
mCurrentHtmlScriptIsAsyncOrDefer =
|
||||
aAttributes->contains(nsHtml5AttributeName::ATTR_SRC) &&
|
||||
|
@ -397,9 +418,11 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
|
|||
nsString
|
||||
urlString; // Not Auto, because using it to hold nsStringBuffer*
|
||||
url.ToString(urlString);
|
||||
treeOp->Init(eTreeOpProcessOfflineManifest, urlString);
|
||||
opProcessOfflineManifest operation(ToNewUnicode(urlString));
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
} else {
|
||||
treeOp->Init(eTreeOpProcessOfflineManifest, EmptyString());
|
||||
opProcessOfflineManifest operation(ToNewUnicode(EmptyString()));
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
} else if (nsGkAtoms::base == aName && mViewSource) {
|
||||
nsHtml5String url =
|
||||
|
@ -433,7 +456,8 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
treeOp->Init(eTreeOpSetFormElement, content, aFormElement);
|
||||
opSetFormElement operation(content, aFormElement);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
}
|
||||
return content;
|
||||
|
@ -458,7 +482,8 @@ nsIContentHandle* nsHtml5TreeBuilder::createHtmlElementSetAsRoot(
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
treeOp->Init(eTreeOpAppendToDocument, content);
|
||||
opAppendToDocument operation(content);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
@ -490,8 +515,8 @@ nsIContentHandle* nsHtml5TreeBuilder::createAndInsertFosterParentedElement(
|
|||
nsHtml5TreeOperation* fosterParentTreeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(fosterParentTreeOp, "Tree op allocation failed.");
|
||||
nsIContentHandle* fosterParentHandle = AllocateContentHandle();
|
||||
fosterParentTreeOp->Init(eTreeOpGetFosterParent, aTable, aStackParent,
|
||||
fosterParentHandle);
|
||||
opGetFosterParent operation(aTable, aStackParent, fosterParentHandle);
|
||||
fosterParentTreeOp->Init(mozilla::AsVariant(operation));
|
||||
|
||||
// Create the element with the correct intended parent.
|
||||
nsIContentHandle* child =
|
||||
|
@ -517,7 +542,8 @@ void nsHtml5TreeBuilder::detachFromParent(nsIContentHandle* aElement) {
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpDetach, aElement);
|
||||
opDetach operation(aElement);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild,
|
||||
|
@ -540,7 +566,8 @@ void nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpAppend, aChild, aParent);
|
||||
opAppend operation(aChild, aParent);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::appendChildrenToNewParent(
|
||||
|
@ -563,7 +590,8 @@ void nsHtml5TreeBuilder::appendChildrenToNewParent(
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpAppendChildrenToNewParent, aOldParent, aNewParent);
|
||||
opAppendChildrenToNewParent operation(aOldParent, aNewParent);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::insertFosterParentedCharacters(
|
||||
|
@ -601,8 +629,9 @@ void nsHtml5TreeBuilder::insertFosterParentedCharacters(
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpFosterParentText, bufferCopy.release(), aLength,
|
||||
aStackParent, aTable);
|
||||
opFosterParentText operation(aStackParent, bufferCopy.release(), aTable,
|
||||
aLength);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::insertFosterParentedChild(
|
||||
|
@ -628,7 +657,8 @@ void nsHtml5TreeBuilder::insertFosterParentedChild(
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpFosterParent, aChild, aStackParent, aTable);
|
||||
opFosterParent operation(aChild, aStackParent, aTable);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent,
|
||||
|
@ -664,7 +694,8 @@ void nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpAppendText, bufferCopy.release(), aLength, aParent);
|
||||
opAppendText operation(aParent, bufferCopy.release(), aLength);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::appendComment(nsIContentHandle* aParent,
|
||||
|
@ -701,7 +732,8 @@ void nsHtml5TreeBuilder::appendComment(nsIContentHandle* aParent,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpAppendComment, bufferCopy.release(), aLength, aParent);
|
||||
opAppendComment operation(aParent, bufferCopy.release(), aLength);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::appendCommentToDocument(char16_t* aBuffer,
|
||||
|
@ -736,7 +768,8 @@ void nsHtml5TreeBuilder::appendCommentToDocument(char16_t* aBuffer,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpAppendCommentToDocument, bufferCopy.release(), aLength);
|
||||
opAppendCommentToDocument data(bufferCopy.release(), aLength);
|
||||
treeOp->Init(mozilla::AsVariant(data));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::addAttributesToElement(
|
||||
|
@ -765,7 +798,8 @@ void nsHtml5TreeBuilder::addAttributesToElement(
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(aElement, aAttributes);
|
||||
opAddAttributes opeation(aElement, aAttributes);
|
||||
treeOp->Init(mozilla::AsVariant(opeation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::markMalformedIfScript(nsIContentHandle* aElement) {
|
||||
|
@ -782,7 +816,8 @@ void nsHtml5TreeBuilder::markMalformedIfScript(nsIContentHandle* aElement) {
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpMarkMalformedIfScript, aElement);
|
||||
opMarkMalformedIfScript operation(aElement);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::start(bool fragment) {
|
||||
|
@ -821,7 +856,8 @@ void nsHtml5TreeBuilder::appendDoctypeToDocument(nsAtom* aName,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(aName, publicId, systemId);
|
||||
opAppendDoctypeToDocument operation(aName, publicId, systemId);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
// nsXMLContentSink can flush here, but what's the point?
|
||||
// It can also interrupt here, but we can't.
|
||||
}
|
||||
|
@ -866,7 +902,7 @@ void nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsAtom* aName,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpStartLayout);
|
||||
treeOp->Init(mozilla::AsVariant(opStartLayout()));
|
||||
return;
|
||||
}
|
||||
if (aName == nsGkAtoms::input || aName == nsGkAtoms::button) {
|
||||
|
@ -874,7 +910,8 @@ void nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsAtom* aName,
|
|||
nsHtml5TreeOperation::DoneCreatingElement(
|
||||
static_cast<nsIContent*>(aElement));
|
||||
} else {
|
||||
mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
|
||||
opDoneCreatingElement operation(aElement);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -884,7 +921,8 @@ void nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsAtom* aName,
|
|||
nsHtml5TreeOperation::DoneCreatingElement(
|
||||
static_cast<nsIContent*>(aElement));
|
||||
} else {
|
||||
mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
|
||||
opDoneCreatingElement operation(aElement);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -916,7 +954,8 @@ void nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsAtom* aName,
|
|||
static_cast<nsIContent*>(aElement));
|
||||
return;
|
||||
}
|
||||
mOpQueue.AppendElement()->Init(eTreeOpPreventScriptExecution, aElement);
|
||||
opPreventScriptExecution operation(aElement);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
return;
|
||||
}
|
||||
if (mBuilder) {
|
||||
|
@ -930,7 +969,8 @@ void nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsAtom* aName,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpRunScriptAsyncDefer, aElement);
|
||||
opRunScriptAsyncDefer operation(aElement);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
mCurrentHtmlScriptIsAsyncOrDefer = false;
|
||||
return;
|
||||
}
|
||||
|
@ -940,7 +980,8 @@ void nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsAtom* aName,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->InitScript(aElement);
|
||||
opRunScript operation(aElement, nullptr);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
return;
|
||||
}
|
||||
if (aName == nsGkAtoms::title) {
|
||||
|
@ -954,7 +995,8 @@ void nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsAtom* aName,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpDoneAddingChildren, aElement);
|
||||
opDoneAddingChildren operation(aElement);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
return;
|
||||
}
|
||||
if (aName == nsGkAtoms::style ||
|
||||
|
@ -970,7 +1012,8 @@ void nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsAtom* aName,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpUpdateStyleSheet, aElement);
|
||||
opUpdateStyleSheet operation(aElement);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
return;
|
||||
}
|
||||
if (aNamespace == kNameSpaceID_SVG) {
|
||||
|
@ -984,7 +1027,8 @@ void nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsAtom* aName,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpSvgLoad, aElement);
|
||||
opSvgLoad operation(aElement);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1005,7 +1049,8 @@ void nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsAtom* aName,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpDoneAddingChildren, aElement);
|
||||
opDoneAddingChildren operation(aElement);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
return;
|
||||
}
|
||||
if (aName == nsGkAtoms::meta && !fragment && !mBuilder) {
|
||||
|
@ -1014,7 +1059,8 @@ void nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsAtom* aName,
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpProcessMeta, aElement);
|
||||
opProcessMeta operation(aElement);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
return;
|
||||
}
|
||||
if (mSpeculativeLoadStage && aName == nsGkAtoms::picture) {
|
||||
|
@ -1157,8 +1203,8 @@ void nsHtml5TreeBuilder::SetDocumentCharset(NotNull<const Encoding*> aEncoding,
|
|||
mSpeculativeLoadQueue.AppendElement()->InitSetDocumentCharset(
|
||||
aEncoding, aCharsetSource);
|
||||
} else {
|
||||
mOpQueue.AppendElement()->Init(eTreeOpSetDocumentCharset, aEncoding,
|
||||
aCharsetSource);
|
||||
opSetDocumentCharset opearation(aEncoding, aCharsetSource);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(opearation));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1170,7 +1216,7 @@ void nsHtml5TreeBuilder::StreamEnded() {
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpStreamEnded);
|
||||
treeOp->Init(mozilla::AsVariant(opStreamEnded()));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::NeedsCharsetSwitchTo(
|
||||
|
@ -1185,8 +1231,8 @@ void nsHtml5TreeBuilder::NeedsCharsetSwitchTo(
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpNeedsCharsetSwitchTo, aEncoding, aCharsetSource,
|
||||
aLineNumber);
|
||||
opCharsetSwitchTo opeation(aEncoding, aCharsetSource, aLineNumber);
|
||||
treeOp->Init(mozilla::AsVariant(opeation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::MaybeComplainAboutCharset(const char* aMsgId,
|
||||
|
@ -1196,7 +1242,9 @@ void nsHtml5TreeBuilder::MaybeComplainAboutCharset(const char* aMsgId,
|
|||
MOZ_ASSERT_UNREACHABLE("Must never complain about charset with builder.");
|
||||
return;
|
||||
}
|
||||
mOpQueue.AppendElement()->Init(aMsgId, aError, aLineNumber);
|
||||
opMaybeComplainAboutCharset opeartion(const_cast<char*>(aMsgId), aError,
|
||||
aLineNumber);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(opeartion));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::TryToEnableEncodingMenu() {
|
||||
|
@ -1206,7 +1254,7 @@ void nsHtml5TreeBuilder::TryToEnableEncodingMenu() {
|
|||
}
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(eTreeOpEnableEncodingMenu);
|
||||
treeOp->Init(mozilla::AsVariant(opEnableEncodingMenu()));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::AddSnapshotToScript(
|
||||
|
@ -1233,7 +1281,8 @@ void nsHtml5TreeBuilder::MarkAsBroken(nsresult aRv) {
|
|||
}
|
||||
mBroken = aRv;
|
||||
mOpQueue.Clear(); // Previous ops don't matter anymore
|
||||
mOpQueue.AppendElement()->Init(aRv);
|
||||
opMarkAsBroken operation(aRv);
|
||||
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::MarkAsBrokenFromPortability(nsresult aRv) {
|
||||
|
@ -1304,7 +1353,7 @@ void nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m) {
|
|||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(m);
|
||||
treeOp->Init(mozilla::AsVariant(m));
|
||||
}
|
||||
|
||||
nsIContentHandle* nsHtml5TreeBuilder::getDocumentFragmentForTemplate(
|
||||
|
@ -1319,7 +1368,8 @@ nsIContentHandle* nsHtml5TreeBuilder::getDocumentFragmentForTemplate(
|
|||
return nullptr;
|
||||
}
|
||||
nsIContentHandle* fragHandle = AllocateContentHandle();
|
||||
treeOp->Init(eTreeOpGetDocumentFragmentForTemplate, aTemplate, fragHandle);
|
||||
opGetDocumentFragmentForTemplate operation(aTemplate, fragHandle);
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
return fragHandle;
|
||||
}
|
||||
|
||||
|
@ -1368,7 +1418,8 @@ void nsHtml5TreeBuilder::errDeepTree() {
|
|||
} else if (!mBuilder) {
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
MOZ_ASSERT(treeOp, "Tree op allocation failed.");
|
||||
treeOp->InitDeepTree(tokenizer->getLineNumber());
|
||||
opMaybeComplainAboutDeepTree operation(tokenizer->getLineNumber());
|
||||
treeOp->Init(mozilla::AsVariant(operation));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,60 +71,141 @@ class MOZ_STACK_CLASS nsHtml5OtherDocUpdate {
|
|||
RefPtr<Document> mDocument;
|
||||
};
|
||||
|
||||
nsHtml5TreeOperation::nsHtml5TreeOperation()
|
||||
: mOpCode(eTreeOpUninitialized),
|
||||
mOne{},
|
||||
mTwo{},
|
||||
mThree{},
|
||||
mFour{},
|
||||
mFive{} {
|
||||
nsHtml5TreeOperation::nsHtml5TreeOperation() : mOperation(uninitialized()) {
|
||||
MOZ_COUNT_CTOR(nsHtml5TreeOperation);
|
||||
}
|
||||
|
||||
nsHtml5TreeOperation::~nsHtml5TreeOperation() {
|
||||
MOZ_COUNT_DTOR(nsHtml5TreeOperation);
|
||||
NS_ASSERTION(mOpCode != eTreeOpUninitialized, "Uninitialized tree op.");
|
||||
switch (mOpCode) {
|
||||
case eTreeOpAddAttributes:
|
||||
delete mTwo.attributes;
|
||||
break;
|
||||
case eTreeOpCreateHTMLElementNetwork:
|
||||
case eTreeOpCreateHTMLElementNotNetwork:
|
||||
case eTreeOpCreateSVGElementNetwork:
|
||||
case eTreeOpCreateSVGElementNotNetwork:
|
||||
case eTreeOpCreateMathMLElement:
|
||||
mTwo.atom->Release();
|
||||
delete mThree.attributes;
|
||||
break;
|
||||
case eTreeOpAddError:
|
||||
if (mThree.atom) {
|
||||
mThree.atom->Release();
|
||||
|
||||
struct TreeOperationMatcher {
|
||||
void operator()(const opAppend& aOperation) {}
|
||||
|
||||
void operator()(const opDetach& aOperation) {}
|
||||
|
||||
void operator()(const opAppendChildrenToNewParent& aOperation) {}
|
||||
|
||||
void operator()(const opFosterParent& aOperation) {}
|
||||
|
||||
void operator()(const opAppendToDocument& aOperation) {}
|
||||
|
||||
void operator()(const opAddAttributes& aOperation) {
|
||||
delete aOperation.mAttributes;
|
||||
}
|
||||
|
||||
void operator()(const nsHtml5DocumentMode& aMode) {}
|
||||
|
||||
void operator()(const opCreateHTMLElement& aOperation) {
|
||||
aOperation.mName->Release();
|
||||
delete aOperation.mAttributes;
|
||||
}
|
||||
|
||||
void operator()(const opCreateSVGElement& aOperation) {
|
||||
aOperation.mName->Release();
|
||||
delete aOperation.mAttributes;
|
||||
}
|
||||
|
||||
void operator()(const opCreateMathMLElement& aOperation) {
|
||||
aOperation.mName->Release();
|
||||
delete aOperation.mAttributes;
|
||||
}
|
||||
|
||||
void operator()(const opSetFormElement& aOperation) {}
|
||||
|
||||
void operator()(const opAppendText& aOperation) {
|
||||
delete[] aOperation.mBuffer;
|
||||
}
|
||||
|
||||
void operator()(const opFosterParentText& aOperation) {
|
||||
delete[] aOperation.mBuffer;
|
||||
}
|
||||
|
||||
void operator()(const opAppendComment& aOperation) {
|
||||
delete[] aOperation.mBuffer;
|
||||
}
|
||||
|
||||
void operator()(const opAppendCommentToDocument& aOperation) {
|
||||
delete[] aOperation.mBuffer;
|
||||
}
|
||||
|
||||
void operator()(const opAppendDoctypeToDocument& aOperation) {
|
||||
aOperation.mName->Release();
|
||||
delete aOperation.mStringPair;
|
||||
}
|
||||
|
||||
void operator()(const opGetDocumentFragmentForTemplate& aOperation) {}
|
||||
|
||||
void operator()(const opGetFosterParent& aOperation) {}
|
||||
|
||||
void operator()(const opMarkAsBroken& aOperation) {}
|
||||
|
||||
void operator()(const opRunScript& aOperation) {}
|
||||
|
||||
void operator()(const opRunScriptAsyncDefer& aOperation) {}
|
||||
|
||||
void operator()(const opPreventScriptExecution& aOperation) {}
|
||||
|
||||
void operator()(const opDoneAddingChildren& aOperation) {}
|
||||
|
||||
void operator()(const opDoneCreatingElement& aOperation) {}
|
||||
|
||||
void operator()(const opSetDocumentCharset& aOperation) {}
|
||||
|
||||
void operator()(const opCharsetSwitchTo& aOperation) {}
|
||||
|
||||
void operator()(const opUpdateStyleSheet& aOperation) {}
|
||||
|
||||
void operator()(const opProcessMeta& aOperation) {}
|
||||
|
||||
void operator()(const opProcessOfflineManifest& aOperation) {
|
||||
free(aOperation.mUrl);
|
||||
}
|
||||
|
||||
void operator()(const opMarkMalformedIfScript& aOperation) {}
|
||||
|
||||
void operator()(const opStreamEnded& aOperation) {}
|
||||
|
||||
void operator()(const opSetStyleLineNumber& aOperation) {}
|
||||
|
||||
void operator()(const opSetScriptLineNumberAndFreeze& aOperation) {}
|
||||
|
||||
void operator()(const opSvgLoad& aOperation) {}
|
||||
|
||||
void operator()(const opMaybeComplainAboutCharset& aOperation) {}
|
||||
|
||||
void operator()(const opMaybeComplainAboutDeepTree& aOperation) {}
|
||||
|
||||
void operator()(const opAddClass& aOperation) {}
|
||||
|
||||
void operator()(const opAddViewSourceHref& aOperation) {
|
||||
delete[] aOperation.mBuffer;
|
||||
}
|
||||
|
||||
void operator()(const opAddViewSourceBase& aOperation) {
|
||||
delete[] aOperation.mBuffer;
|
||||
}
|
||||
|
||||
void operator()(const opAddErrorType& aOperation) {
|
||||
if (aOperation.mName) {
|
||||
aOperation.mName->Release();
|
||||
}
|
||||
if (mFour.atom) {
|
||||
mFour.atom->Release();
|
||||
if (aOperation.mOther) {
|
||||
aOperation.mOther->Release();
|
||||
}
|
||||
break;
|
||||
case eTreeOpAppendDoctypeToDocument:
|
||||
mOne.atom->Release();
|
||||
delete mTwo.stringPair;
|
||||
break;
|
||||
case eTreeOpFosterParentText:
|
||||
case eTreeOpAppendText:
|
||||
case eTreeOpAppendComment:
|
||||
case eTreeOpAppendCommentToDocument:
|
||||
case eTreeOpAddViewSourceHref:
|
||||
case eTreeOpAddViewSourceBase:
|
||||
delete[] mTwo.unicharPtr;
|
||||
break;
|
||||
case eTreeOpSetDocumentCharset:
|
||||
case eTreeOpNeedsCharsetSwitchTo:
|
||||
break;
|
||||
case eTreeOpProcessOfflineManifest:
|
||||
free(mOne.unicharPtr);
|
||||
break;
|
||||
default: // keep the compiler happy
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const opAddLineNumberId& aOperation) {}
|
||||
|
||||
void operator()(const opStartLayout& aOperation) {}
|
||||
|
||||
void operator()(const opEnableEncodingMenu& aOperation) {}
|
||||
|
||||
void operator()(const uninitialized& aOperation) {
|
||||
NS_WARNING("Uninitialized tree op.");
|
||||
}
|
||||
};
|
||||
|
||||
mOperation.match(TreeOperationMatcher());
|
||||
}
|
||||
|
||||
nsresult nsHtml5TreeOperation::AppendTextToTextNode(
|
||||
|
@ -674,241 +755,263 @@ void nsHtml5TreeOperation::MarkMalformedIfScript(nsIContent* aNode) {
|
|||
nsresult nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
||||
nsIContent** aScriptElement,
|
||||
bool* aInterrupted, bool* aStreamEnded) {
|
||||
switch (mOpCode) {
|
||||
case eTreeOpUninitialized: {
|
||||
MOZ_CRASH("eTreeOpUninitialized");
|
||||
struct TreeOperationMatcher {
|
||||
TreeOperationMatcher(nsHtml5TreeOpExecutor* aBuilder,
|
||||
nsIContent** aScriptElement, bool* aInterrupted,
|
||||
bool* aStreamEnded)
|
||||
: mBuilder(aBuilder),
|
||||
mScriptElement(aScriptElement),
|
||||
mInterrupted(aInterrupted),
|
||||
mStreamEnded(aStreamEnded) {}
|
||||
|
||||
nsHtml5TreeOpExecutor* mBuilder;
|
||||
nsIContent** mScriptElement;
|
||||
bool* mInterrupted;
|
||||
bool* mStreamEnded;
|
||||
|
||||
nsresult operator()(const opAppend& aOperation) {
|
||||
return Append(*(aOperation.mChild), *(aOperation.mParent), mBuilder);
|
||||
}
|
||||
case eTreeOpAppend: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
nsIContent* parent = *(mTwo.node);
|
||||
return Append(node, parent, aBuilder);
|
||||
}
|
||||
case eTreeOpDetach: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
Detach(node, aBuilder);
|
||||
|
||||
nsresult operator()(const opDetach& aOperation) {
|
||||
Detach(*(aOperation.mElement), mBuilder);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpAppendChildrenToNewParent: {
|
||||
nsCOMPtr<nsIContent> node = *(mOne.node);
|
||||
nsIContent* parent = *(mTwo.node);
|
||||
return AppendChildrenToNewParent(node, parent, aBuilder);
|
||||
}
|
||||
case eTreeOpFosterParent: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
nsIContent* parent = *(mTwo.node);
|
||||
nsIContent* table = *(mThree.node);
|
||||
return FosterParent(node, parent, table, aBuilder);
|
||||
}
|
||||
case eTreeOpAppendToDocument: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
nsresult rv = AppendToDocument(node, aBuilder);
|
||||
|
||||
aBuilder->PauseDocUpdate(aInterrupted);
|
||||
nsresult operator()(const opAppendChildrenToNewParent& aOperation) {
|
||||
nsCOMPtr<nsIContent> node = *(aOperation.mOldParent);
|
||||
nsIContent* parent = *(aOperation.mNewParent);
|
||||
return AppendChildrenToNewParent(node, parent, mBuilder);
|
||||
}
|
||||
|
||||
nsresult operator()(const opFosterParent& aOperation) {
|
||||
nsIContent* node = *(aOperation.mChild);
|
||||
nsIContent* parent = *(aOperation.mStackParent);
|
||||
nsIContent* table = *(aOperation.mTable);
|
||||
return FosterParent(node, parent, table, mBuilder);
|
||||
}
|
||||
|
||||
nsresult operator()(const opAppendToDocument& aOperation) {
|
||||
nsresult rv = AppendToDocument(*(aOperation.mContent), mBuilder);
|
||||
mBuilder->PauseDocUpdate(mInterrupted);
|
||||
return rv;
|
||||
}
|
||||
case eTreeOpAddAttributes: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
nsHtml5HtmlAttributes* attributes = mTwo.attributes;
|
||||
return AddAttributes(node, attributes, aBuilder);
|
||||
|
||||
nsresult operator()(const opAddAttributes& aOperation) {
|
||||
nsIContent* node = *(aOperation.mElement);
|
||||
nsHtml5HtmlAttributes* attributes = aOperation.mAttributes;
|
||||
return AddAttributes(node, attributes, mBuilder);
|
||||
}
|
||||
case eTreeOpDocumentMode: {
|
||||
aBuilder->SetDocumentMode(mOne.mode);
|
||||
|
||||
nsresult operator()(const nsHtml5DocumentMode& aMode) {
|
||||
mBuilder->SetDocumentMode(aMode);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpCreateHTMLElementNetwork:
|
||||
case eTreeOpCreateHTMLElementNotNetwork: {
|
||||
nsIContent** target = mOne.node;
|
||||
mozilla::dom::HTMLContentCreatorFunction creator = mFour.htmlCreator;
|
||||
nsAtom* name = mTwo.atom;
|
||||
nsHtml5HtmlAttributes* attributes = mThree.attributes;
|
||||
nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
|
||||
|
||||
nsresult operator()(const opCreateHTMLElement& aOperation) {
|
||||
nsIContent** target = aOperation.mContent;
|
||||
mozilla::dom::HTMLContentCreatorFunction creator = aOperation.mCreator;
|
||||
nsAtom* name = aOperation.mName;
|
||||
nsHtml5HtmlAttributes* attributes = aOperation.mAttributes;
|
||||
nsIContent* intendedParent =
|
||||
aOperation.mIntendedParent ? *(aOperation.mIntendedParent) : nullptr;
|
||||
|
||||
// intendedParent == nullptr is a special case where the
|
||||
// intended parent is the document.
|
||||
nsNodeInfoManager* nodeInfoManager =
|
||||
intendedParent ? intendedParent->OwnerDoc()->NodeInfoManager()
|
||||
: aBuilder->GetNodeInfoManager();
|
||||
: mBuilder->GetNodeInfoManager();
|
||||
|
||||
*target = CreateHTMLElement(name, attributes,
|
||||
mOpCode == eTreeOpCreateHTMLElementNetwork
|
||||
? dom::FROM_PARSER_NETWORK
|
||||
: dom::FROM_PARSER_DOCUMENT_WRITE,
|
||||
nodeInfoManager, aBuilder, creator);
|
||||
*target = CreateHTMLElement(name, attributes, aOperation.mFromNetwork,
|
||||
nodeInfoManager, mBuilder, creator);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpCreateSVGElementNetwork:
|
||||
case eTreeOpCreateSVGElementNotNetwork: {
|
||||
nsIContent** target = mOne.node;
|
||||
mozilla::dom::SVGContentCreatorFunction creator = mFour.svgCreator;
|
||||
nsAtom* name = mTwo.atom;
|
||||
nsHtml5HtmlAttributes* attributes = mThree.attributes;
|
||||
nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
|
||||
|
||||
nsresult operator()(const opCreateSVGElement& aOperation) {
|
||||
nsIContent** target = aOperation.mContent;
|
||||
mozilla::dom::SVGContentCreatorFunction creator = aOperation.mCreator;
|
||||
nsAtom* name = aOperation.mName;
|
||||
nsHtml5HtmlAttributes* attributes = aOperation.mAttributes;
|
||||
nsIContent* intendedParent =
|
||||
aOperation.mIntendedParent ? *(aOperation.mIntendedParent) : nullptr;
|
||||
|
||||
// intendedParent == nullptr is a special case where the
|
||||
// intended parent is the document.
|
||||
nsNodeInfoManager* nodeInfoManager =
|
||||
intendedParent ? intendedParent->OwnerDoc()->NodeInfoManager()
|
||||
: aBuilder->GetNodeInfoManager();
|
||||
: mBuilder->GetNodeInfoManager();
|
||||
|
||||
*target = CreateSVGElement(name, attributes,
|
||||
mOpCode == eTreeOpCreateSVGElementNetwork
|
||||
? dom::FROM_PARSER_NETWORK
|
||||
: dom::FROM_PARSER_DOCUMENT_WRITE,
|
||||
nodeInfoManager, aBuilder, creator);
|
||||
*target = CreateSVGElement(name, attributes, aOperation.mFromNetwork,
|
||||
nodeInfoManager, mBuilder, creator);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpCreateMathMLElement: {
|
||||
nsIContent** target = mOne.node;
|
||||
nsAtom* name = mTwo.atom;
|
||||
nsHtml5HtmlAttributes* attributes = mThree.attributes;
|
||||
nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
|
||||
|
||||
nsresult operator()(const opCreateMathMLElement& aOperation) {
|
||||
nsIContent** target = aOperation.mContent;
|
||||
nsAtom* name = aOperation.mName;
|
||||
nsHtml5HtmlAttributes* attributes = aOperation.mAttributes;
|
||||
nsIContent* intendedParent =
|
||||
aOperation.mIntendedParent ? *(aOperation.mIntendedParent) : nullptr;
|
||||
|
||||
// intendedParent == nullptr is a special case where the
|
||||
// intended parent is the document.
|
||||
nsNodeInfoManager* nodeInfoManager =
|
||||
intendedParent ? intendedParent->OwnerDoc()->NodeInfoManager()
|
||||
: aBuilder->GetNodeInfoManager();
|
||||
: mBuilder->GetNodeInfoManager();
|
||||
|
||||
*target =
|
||||
CreateMathMLElement(name, attributes, nodeInfoManager, aBuilder);
|
||||
CreateMathMLElement(name, attributes, nodeInfoManager, mBuilder);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpSetFormElement: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
nsIContent* parent = *(mTwo.node);
|
||||
SetFormElement(node, parent);
|
||||
|
||||
nsresult operator()(const opSetFormElement& aOperation) {
|
||||
SetFormElement(*(aOperation.mContent), *(aOperation.mFormElement));
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpAppendText: {
|
||||
nsIContent* parent = *mOne.node;
|
||||
char16_t* buffer = mTwo.unicharPtr;
|
||||
uint32_t length = mFour.integer;
|
||||
return AppendText(buffer, length, parent, aBuilder);
|
||||
|
||||
nsresult operator()(const opAppendText& aOperation) {
|
||||
nsIContent* parent = *aOperation.mParent;
|
||||
char16_t* buffer = aOperation.mBuffer;
|
||||
uint32_t length = aOperation.mLength;
|
||||
return AppendText(buffer, length, parent, mBuilder);
|
||||
}
|
||||
case eTreeOpFosterParentText: {
|
||||
nsIContent* stackParent = *mOne.node;
|
||||
char16_t* buffer = mTwo.unicharPtr;
|
||||
uint32_t length = mFour.integer;
|
||||
nsIContent* table = *mThree.node;
|
||||
return FosterParentText(stackParent, buffer, length, table, aBuilder);
|
||||
|
||||
nsresult operator()(const opFosterParentText& aOperation) {
|
||||
nsIContent* stackParent = *aOperation.mStackParent;
|
||||
char16_t* buffer = aOperation.mBuffer;
|
||||
uint32_t length = aOperation.mLength;
|
||||
nsIContent* table = *aOperation.mTable;
|
||||
return FosterParentText(stackParent, buffer, length, table, mBuilder);
|
||||
}
|
||||
case eTreeOpAppendComment: {
|
||||
nsIContent* parent = *mOne.node;
|
||||
char16_t* buffer = mTwo.unicharPtr;
|
||||
int32_t length = mFour.integer;
|
||||
return AppendComment(parent, buffer, length, aBuilder);
|
||||
|
||||
nsresult operator()(const opAppendComment& aOperation) {
|
||||
nsIContent* parent = *aOperation.mParent;
|
||||
char16_t* buffer = aOperation.mBuffer;
|
||||
uint32_t length = aOperation.mLength;
|
||||
return AppendComment(parent, buffer, length, mBuilder);
|
||||
}
|
||||
case eTreeOpAppendCommentToDocument: {
|
||||
char16_t* buffer = mTwo.unicharPtr;
|
||||
int32_t length = mFour.integer;
|
||||
return AppendCommentToDocument(buffer, length, aBuilder);
|
||||
|
||||
nsresult operator()(const opAppendCommentToDocument& aOperation) {
|
||||
char16_t* buffer = aOperation.mBuffer;
|
||||
int32_t length = aOperation.mLength;
|
||||
return AppendCommentToDocument(buffer, length, mBuilder);
|
||||
}
|
||||
case eTreeOpAppendDoctypeToDocument: {
|
||||
nsAtom* name = mOne.atom;
|
||||
nsHtml5TreeOperationStringPair* pair = mTwo.stringPair;
|
||||
|
||||
nsresult operator()(const opAppendDoctypeToDocument& aOperation) {
|
||||
nsAtom* name = aOperation.mName;
|
||||
nsHtml5TreeOperationStringPair* pair = aOperation.mStringPair;
|
||||
nsString publicId;
|
||||
nsString systemId;
|
||||
pair->Get(publicId, systemId);
|
||||
return AppendDoctypeToDocument(name, publicId, systemId, aBuilder);
|
||||
return AppendDoctypeToDocument(name, publicId, systemId, mBuilder);
|
||||
}
|
||||
case eTreeOpGetDocumentFragmentForTemplate: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
*mTwo.node = GetDocumentFragmentForTemplate(node);
|
||||
|
||||
nsresult operator()(const opGetDocumentFragmentForTemplate& aOperation) {
|
||||
nsIContent* node = *(aOperation.mTemplate);
|
||||
*(aOperation.mFragHandle) = GetDocumentFragmentForTemplate(node);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpGetFosterParent: {
|
||||
nsIContent* table = *(mOne.node);
|
||||
nsIContent* stackParent = *(mTwo.node);
|
||||
|
||||
nsresult operator()(const opGetFosterParent& aOperation) {
|
||||
nsIContent* table = *(aOperation.mTable);
|
||||
nsIContent* stackParent = *(aOperation.mStackParent);
|
||||
nsIContent* fosterParent = GetFosterParent(table, stackParent);
|
||||
*mThree.node = fosterParent;
|
||||
*aOperation.mParentHandle = fosterParent;
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpMarkAsBroken: {
|
||||
return mOne.result;
|
||||
|
||||
nsresult operator()(const opMarkAsBroken& aOperation) {
|
||||
return aOperation.mResult;
|
||||
}
|
||||
case eTreeOpRunScript: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
nsAHtml5TreeBuilderState* snapshot = mTwo.state;
|
||||
|
||||
nsresult operator()(const opRunScript& aOperation) {
|
||||
nsIContent* node = *(aOperation.mElement);
|
||||
nsAHtml5TreeBuilderState* snapshot = aOperation.mBuilderState;
|
||||
if (snapshot) {
|
||||
aBuilder->InitializeDocWriteParserState(snapshot, mFour.integer);
|
||||
mBuilder->InitializeDocWriteParserState(snapshot,
|
||||
aOperation.mLineNumber);
|
||||
}
|
||||
*aScriptElement = node;
|
||||
*mScriptElement = node;
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpRunScriptAsyncDefer: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
aBuilder->RunScript(node);
|
||||
|
||||
nsresult operator()(const opRunScriptAsyncDefer& aOperation) {
|
||||
mBuilder->RunScript(*(aOperation.mElement));
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpPreventScriptExecution: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
PreventScriptExecution(node);
|
||||
|
||||
nsresult operator()(const opPreventScriptExecution& aOperation) {
|
||||
PreventScriptExecution(*(aOperation.mElement));
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpDoneAddingChildren: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
|
||||
nsresult operator()(const opDoneAddingChildren& aOperation) {
|
||||
nsIContent* node = *(aOperation.mElement);
|
||||
node->DoneAddingChildren(node->HasParserNotified());
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpDoneCreatingElement: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
DoneCreatingElement(node);
|
||||
|
||||
nsresult operator()(const opDoneCreatingElement& aOperation) {
|
||||
DoneCreatingElement(*(aOperation.mElement));
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpSetDocumentCharset: {
|
||||
auto encoding = WrapNotNull(mOne.encoding);
|
||||
int32_t charsetSource = mFour.integer;
|
||||
aBuilder->SetDocumentCharsetAndSource(encoding, charsetSource);
|
||||
|
||||
nsresult operator()(const opSetDocumentCharset& aOperation) {
|
||||
auto encoding = WrapNotNull(aOperation.mEncoding);
|
||||
mBuilder->SetDocumentCharsetAndSource(encoding,
|
||||
aOperation.mCharsetSource);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpNeedsCharsetSwitchTo: {
|
||||
auto encoding = WrapNotNull(mOne.encoding);
|
||||
int32_t charsetSource = mFour.integer;
|
||||
int32_t lineNumber = mTwo.integer;
|
||||
aBuilder->NeedsCharsetSwitchTo(encoding, charsetSource,
|
||||
(uint32_t)lineNumber);
|
||||
|
||||
nsresult operator()(const opCharsetSwitchTo& aOperation) {
|
||||
auto encoding = WrapNotNull(aOperation.mEncoding);
|
||||
mBuilder->NeedsCharsetSwitchTo(encoding, aOperation.mCharsetSource,
|
||||
(uint32_t)aOperation.mLineNumber);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpUpdateStyleSheet: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
aBuilder->UpdateStyleSheet(node);
|
||||
|
||||
nsresult operator()(const opUpdateStyleSheet& aOperation) {
|
||||
mBuilder->UpdateStyleSheet(*(aOperation.mElement));
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpProcessMeta: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
return aBuilder->ProcessMETATag(node);
|
||||
|
||||
nsresult operator()(const opProcessMeta& aOperation) {
|
||||
return mBuilder->ProcessMETATag(*(aOperation.mElement));
|
||||
}
|
||||
case eTreeOpProcessOfflineManifest: {
|
||||
char16_t* str = mOne.unicharPtr;
|
||||
nsDependentString dependentString(str);
|
||||
aBuilder->ProcessOfflineManifest(dependentString);
|
||||
|
||||
nsresult operator()(const opProcessOfflineManifest& aOperation) {
|
||||
nsDependentString dependentString(aOperation.mUrl);
|
||||
mBuilder->ProcessOfflineManifest(dependentString);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpMarkMalformedIfScript: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
MarkMalformedIfScript(node);
|
||||
|
||||
nsresult operator()(const opMarkMalformedIfScript& aOperation) {
|
||||
MarkMalformedIfScript(*(aOperation.mElement));
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpStreamEnded: {
|
||||
*aStreamEnded = true;
|
||||
|
||||
nsresult operator()(const opStreamEnded& aOperation) {
|
||||
*mStreamEnded = true;
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpSetStyleLineNumber: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
|
||||
nsresult operator()(const opSetStyleLineNumber& aOperation) {
|
||||
nsIContent* node = *(aOperation.mContent);
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle = do_QueryInterface(node);
|
||||
if (ssle) {
|
||||
ssle->SetLineNumber(mFour.integer);
|
||||
ssle->SetLineNumber(aOperation.mLineNumber);
|
||||
} else {
|
||||
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled,
|
||||
"Node didn't QI to style, but SVG wasn't disabled.");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpSetScriptLineNumberAndFreeze: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
|
||||
nsresult operator()(const opSetScriptLineNumberAndFreeze& aOperation) {
|
||||
nsIContent* node = *(aOperation.mContent);
|
||||
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(node);
|
||||
if (sele) {
|
||||
sele->SetScriptLineNumber(mFour.integer);
|
||||
sele->SetScriptLineNumber(aOperation.mLineNumber);
|
||||
sele->FreezeExecutionAttrs(node->OwnerDoc());
|
||||
} else {
|
||||
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled,
|
||||
|
@ -916,31 +1019,28 @@ nsresult nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||
}
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpSvgLoad: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
SvgLoad(node);
|
||||
|
||||
nsresult operator()(const opSvgLoad& aOperation) {
|
||||
SvgLoad(*(aOperation.mElement));
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpMaybeComplainAboutCharset: {
|
||||
char* msgId = mOne.charPtr;
|
||||
bool error = mTwo.integer;
|
||||
int32_t lineNumber = mThree.integer;
|
||||
aBuilder->MaybeComplainAboutCharset(msgId, error, (uint32_t)lineNumber);
|
||||
|
||||
nsresult operator()(const opMaybeComplainAboutCharset& aOperation) {
|
||||
char* msgId = aOperation.mMsgId;
|
||||
bool error = aOperation.mError;
|
||||
int32_t lineNumber = aOperation.mLineNumber;
|
||||
mBuilder->MaybeComplainAboutCharset(msgId, error, (uint32_t)lineNumber);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpEnableEncodingMenu: {
|
||||
Document* doc = aBuilder->GetDocument();
|
||||
doc->EnableEncodingMenu();
|
||||
|
||||
nsresult operator()(const opMaybeComplainAboutDeepTree& aOperation) {
|
||||
mBuilder->MaybeComplainAboutDeepTree((uint32_t)aOperation.mLineNumber);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpMaybeComplainAboutDeepTree: {
|
||||
int32_t lineNumber = mOne.integer;
|
||||
aBuilder->MaybeComplainAboutDeepTree((uint32_t)lineNumber);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpAddClass: {
|
||||
Element* element = (*(mOne.node))->AsElement();
|
||||
char16_t* str = mTwo.unicharPtr;
|
||||
|
||||
nsresult operator()(const opAddClass& aOperation) {
|
||||
Element* element = (*(aOperation.mElement))->AsElement();
|
||||
char16_t* str = aOperation.mClass;
|
||||
nsDependentString depStr(str);
|
||||
// See viewsource.css for the possible classes
|
||||
nsAutoString klass;
|
||||
|
@ -954,19 +1054,19 @@ nsresult nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||
}
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpAddViewSourceHref: {
|
||||
Element* element = (*mOne.node)->AsElement();
|
||||
char16_t* buffer = mTwo.unicharPtr;
|
||||
int32_t length = mFour.integer;
|
||||
|
||||
nsresult operator()(const opAddViewSourceHref& aOperation) {
|
||||
Element* element = (*aOperation.mElement)->AsElement();
|
||||
char16_t* buffer = aOperation.mBuffer;
|
||||
int32_t length = aOperation.mLength;
|
||||
nsDependentString relative(buffer, length);
|
||||
|
||||
Document* doc = aBuilder->GetDocument();
|
||||
Document* doc = mBuilder->GetDocument();
|
||||
|
||||
auto encoding = doc->GetDocumentCharacterSet();
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), relative, encoding,
|
||||
aBuilder->GetViewSourceBaseURI());
|
||||
mBuilder->GetViewSourceBaseURI());
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
|
||||
// Reuse the fix for bug 467852
|
||||
|
@ -1008,18 +1108,18 @@ nsresult nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||
element->SetAttr(kNameSpaceID_None, nsGkAtoms::href, utf16, true);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpAddViewSourceBase: {
|
||||
char16_t* buffer = mTwo.unicharPtr;
|
||||
int32_t length = mFour.integer;
|
||||
nsDependentString baseUrl(buffer, length);
|
||||
aBuilder->AddBase(baseUrl);
|
||||
|
||||
nsresult operator()(const opAddViewSourceBase& aOperation) {
|
||||
nsDependentString baseUrl(aOperation.mBuffer, aOperation.mLength);
|
||||
mBuilder->AddBase(baseUrl);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpAddError: {
|
||||
Element* element = (*(mOne.node))->AsElement();
|
||||
char* msgId = mTwo.charPtr;
|
||||
nsAtom* atom = mThree.atom;
|
||||
nsAtom* otherAtom = mFour.atom;
|
||||
|
||||
nsresult operator()(const opAddErrorType& aOperation) {
|
||||
Element* element = (*(aOperation.mElement))->AsElement();
|
||||
char* msgId = aOperation.mMsgId;
|
||||
nsAtom* atom = aOperation.mName;
|
||||
nsAtom* otherAtom = aOperation.mOther;
|
||||
// See viewsource.css for the possible classes in addition to "error".
|
||||
nsAutoString klass;
|
||||
element->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
|
||||
|
@ -1060,22 +1160,34 @@ nsresult nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||
}
|
||||
return rv;
|
||||
}
|
||||
case eTreeOpAddLineNumberId: {
|
||||
Element* element = (*(mOne.node))->AsElement();
|
||||
int32_t lineNumber = mFour.integer;
|
||||
|
||||
nsresult operator()(const opAddLineNumberId& aOperation) {
|
||||
Element* element = (*(aOperation.mElement))->AsElement();
|
||||
int32_t lineNumber = aOperation.mLineNumber;
|
||||
nsAutoString val(NS_LITERAL_STRING("line"));
|
||||
val.AppendInt(lineNumber);
|
||||
element->SetAttr(kNameSpaceID_None, nsGkAtoms::id, val, true);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpStartLayout: {
|
||||
aBuilder->StartLayout(
|
||||
aInterrupted); // this causes a notification flush anyway
|
||||
|
||||
nsresult operator()(const opStartLayout& aOperation) {
|
||||
mBuilder->StartLayout(
|
||||
mInterrupted); // this causes a notification flush anyway
|
||||
return NS_OK;
|
||||
}
|
||||
default: {
|
||||
MOZ_CRASH("Bogus tree op");
|
||||
|
||||
nsresult operator()(const opEnableEncodingMenu& aOperation) {
|
||||
Document* doc = mBuilder->GetDocument();
|
||||
doc->EnableEncodingMenu();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_OK; // keep compiler happy
|
||||
|
||||
nsresult operator()(const uninitialized& aOperation) {
|
||||
MOZ_CRASH("uninitialized");
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
return mOperation.match(TreeOperationMatcher(aBuilder, aScriptElement,
|
||||
aInterrupted, aStreamEnded));
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "nsHtml5HtmlAttributes.h"
|
||||
#include "mozilla/dom/FromParser.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/Variant.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsHtml5TreeOpExecutor;
|
||||
|
@ -21,55 +22,197 @@ class Text;
|
|||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
enum eHtml5TreeOperation {
|
||||
eTreeOpUninitialized,
|
||||
// main HTML5 ops
|
||||
eTreeOpAppend,
|
||||
eTreeOpDetach,
|
||||
eTreeOpAppendChildrenToNewParent,
|
||||
eTreeOpFosterParent,
|
||||
eTreeOpAppendToDocument,
|
||||
eTreeOpAddAttributes,
|
||||
eTreeOpDocumentMode,
|
||||
eTreeOpCreateHTMLElementNetwork,
|
||||
eTreeOpCreateHTMLElementNotNetwork,
|
||||
eTreeOpCreateSVGElementNetwork,
|
||||
eTreeOpCreateSVGElementNotNetwork,
|
||||
eTreeOpCreateMathMLElement,
|
||||
eTreeOpSetFormElement,
|
||||
eTreeOpAppendText,
|
||||
eTreeOpFosterParentText,
|
||||
eTreeOpAppendComment,
|
||||
eTreeOpAppendCommentToDocument,
|
||||
eTreeOpAppendDoctypeToDocument,
|
||||
eTreeOpGetDocumentFragmentForTemplate,
|
||||
eTreeOpGetFosterParent,
|
||||
// Gecko-specific on-pop ops
|
||||
eTreeOpMarkAsBroken,
|
||||
eTreeOpRunScript,
|
||||
eTreeOpRunScriptAsyncDefer,
|
||||
eTreeOpPreventScriptExecution,
|
||||
eTreeOpDoneAddingChildren,
|
||||
eTreeOpDoneCreatingElement,
|
||||
eTreeOpSetDocumentCharset,
|
||||
eTreeOpNeedsCharsetSwitchTo,
|
||||
eTreeOpUpdateStyleSheet,
|
||||
eTreeOpProcessMeta,
|
||||
eTreeOpProcessOfflineManifest,
|
||||
eTreeOpMarkMalformedIfScript,
|
||||
eTreeOpStreamEnded,
|
||||
eTreeOpSetStyleLineNumber,
|
||||
eTreeOpSetScriptLineNumberAndFreeze,
|
||||
eTreeOpSvgLoad,
|
||||
eTreeOpMaybeComplainAboutCharset,
|
||||
eTreeOpMaybeComplainAboutDeepTree,
|
||||
eTreeOpAddClass,
|
||||
eTreeOpAddViewSourceHref,
|
||||
eTreeOpAddViewSourceBase,
|
||||
eTreeOpAddError,
|
||||
eTreeOpAddLineNumberId,
|
||||
eTreeOpStartLayout,
|
||||
eTreeOpEnableEncodingMenu
|
||||
struct uninitialized {};
|
||||
|
||||
// main HTML5 ops
|
||||
struct opDetach {
|
||||
nsIContent** mElement;
|
||||
|
||||
explicit opDetach(nsIContentHandle* aElement) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opAppend {
|
||||
nsIContent** mChild;
|
||||
nsIContent** mParent;
|
||||
|
||||
explicit opAppend(nsIContentHandle* aChild, nsIContentHandle* aParent) {
|
||||
mChild = static_cast<nsIContent**>(aChild);
|
||||
mParent = static_cast<nsIContent**>(aParent);
|
||||
};
|
||||
};
|
||||
|
||||
struct opAppendChildrenToNewParent {
|
||||
nsIContent** mOldParent;
|
||||
nsIContent** mNewParent;
|
||||
|
||||
explicit opAppendChildrenToNewParent(nsIContentHandle* aOldParent,
|
||||
nsIContentHandle* aNewParent) {
|
||||
mOldParent = static_cast<nsIContent**>(aOldParent);
|
||||
mNewParent = static_cast<nsIContent**>(aNewParent);
|
||||
};
|
||||
};
|
||||
|
||||
struct opFosterParent {
|
||||
nsIContent** mChild;
|
||||
nsIContent** mStackParent;
|
||||
nsIContent** mTable;
|
||||
|
||||
explicit opFosterParent(nsIContentHandle* aChild,
|
||||
nsIContentHandle* aStackParent,
|
||||
nsIContentHandle* aTable) {
|
||||
mChild = static_cast<nsIContent**>(aChild);
|
||||
mStackParent = static_cast<nsIContent**>(aStackParent);
|
||||
mTable = static_cast<nsIContent**>(aTable);
|
||||
};
|
||||
};
|
||||
|
||||
struct opAppendToDocument {
|
||||
nsIContent** mContent;
|
||||
|
||||
explicit opAppendToDocument(nsIContentHandle* aContent) {
|
||||
mContent = static_cast<nsIContent**>(aContent);
|
||||
};
|
||||
};
|
||||
|
||||
struct opAddAttributes {
|
||||
nsIContent** mElement;
|
||||
nsHtml5HtmlAttributes* mAttributes;
|
||||
|
||||
explicit opAddAttributes(nsIContentHandle* aElement,
|
||||
nsHtml5HtmlAttributes* aAttributes)
|
||||
: mAttributes(aAttributes) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opCreateHTMLElement {
|
||||
nsIContent** mContent;
|
||||
nsAtom* mName;
|
||||
nsHtml5HtmlAttributes* mAttributes;
|
||||
mozilla::dom::HTMLContentCreatorFunction mCreator;
|
||||
nsIContent** mIntendedParent;
|
||||
mozilla::dom::FromParser mFromNetwork;
|
||||
|
||||
explicit opCreateHTMLElement(
|
||||
nsIContentHandle* aContent, nsAtom* aName,
|
||||
nsHtml5HtmlAttributes* aAttributes,
|
||||
mozilla::dom::HTMLContentCreatorFunction aCreator,
|
||||
nsIContentHandle* aIntendedParent, mozilla::dom::FromParser mFromNetwork)
|
||||
: mName(aName),
|
||||
mAttributes(aAttributes),
|
||||
mCreator(aCreator),
|
||||
mFromNetwork(mFromNetwork) {
|
||||
mContent = static_cast<nsIContent**>(aContent);
|
||||
mIntendedParent = static_cast<nsIContent**>(aIntendedParent);
|
||||
aName->AddRef();
|
||||
if (mAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
|
||||
mAttributes = nullptr;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct opCreateSVGElement {
|
||||
nsIContent** mContent;
|
||||
nsAtom* mName;
|
||||
nsHtml5HtmlAttributes* mAttributes;
|
||||
mozilla::dom::SVGContentCreatorFunction mCreator;
|
||||
nsIContent** mIntendedParent;
|
||||
mozilla::dom::FromParser mFromNetwork;
|
||||
|
||||
explicit opCreateSVGElement(nsIContentHandle* aContent, nsAtom* aName,
|
||||
nsHtml5HtmlAttributes* aAttributes,
|
||||
mozilla::dom::SVGContentCreatorFunction aCreator,
|
||||
nsIContentHandle* aIntendedParent,
|
||||
mozilla::dom::FromParser mFromNetwork)
|
||||
: mName(aName),
|
||||
mAttributes(aAttributes),
|
||||
mCreator(aCreator),
|
||||
mFromNetwork(mFromNetwork) {
|
||||
mContent = static_cast<nsIContent**>(aContent);
|
||||
mIntendedParent = static_cast<nsIContent**>(aIntendedParent);
|
||||
aName->AddRef();
|
||||
if (mAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
|
||||
mAttributes = nullptr;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct opCreateMathMLElement {
|
||||
nsIContent** mContent;
|
||||
nsAtom* mName;
|
||||
nsHtml5HtmlAttributes* mAttributes;
|
||||
nsIContent** mIntendedParent;
|
||||
|
||||
explicit opCreateMathMLElement(nsIContentHandle* aContent, nsAtom* aName,
|
||||
nsHtml5HtmlAttributes* aAttributes,
|
||||
nsIContentHandle* aIntendedParent)
|
||||
: mName(aName), mAttributes(aAttributes) {
|
||||
mContent = static_cast<nsIContent**>(aContent);
|
||||
mIntendedParent = static_cast<nsIContent**>(aIntendedParent);
|
||||
aName->AddRef();
|
||||
if (mAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
|
||||
mAttributes = nullptr;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct opSetFormElement {
|
||||
nsIContent** mContent;
|
||||
nsIContent** mFormElement;
|
||||
|
||||
explicit opSetFormElement(nsIContentHandle* aContent,
|
||||
nsIContentHandle* aFormElement) {
|
||||
mContent = static_cast<nsIContent**>(aContent);
|
||||
mFormElement = static_cast<nsIContent**>(aFormElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opAppendText {
|
||||
nsIContent** mParent;
|
||||
char16_t* mBuffer;
|
||||
int32_t mLength;
|
||||
|
||||
explicit opAppendText(nsIContentHandle* aParent, char16_t* aBuffer,
|
||||
int32_t aLength)
|
||||
: mBuffer(aBuffer), mLength(aLength) {
|
||||
mParent = static_cast<nsIContent**>(aParent);
|
||||
};
|
||||
};
|
||||
|
||||
struct opFosterParentText {
|
||||
nsIContent** mStackParent;
|
||||
char16_t* mBuffer;
|
||||
nsIContent** mTable;
|
||||
int32_t mLength;
|
||||
|
||||
explicit opFosterParentText(nsIContentHandle* aStackParent, char16_t* aBuffer,
|
||||
nsIContentHandle* aTable, int32_t aLength)
|
||||
: mBuffer(aBuffer), mLength(aLength) {
|
||||
mStackParent = static_cast<nsIContent**>(aStackParent);
|
||||
mTable = static_cast<nsIContent**>(aTable);
|
||||
};
|
||||
};
|
||||
|
||||
struct opAppendComment {
|
||||
nsIContent** mParent;
|
||||
char16_t* mBuffer;
|
||||
int32_t mLength;
|
||||
|
||||
explicit opAppendComment(nsIContentHandle* aParent, char16_t* aBuffer,
|
||||
int32_t aLength)
|
||||
: mBuffer(aBuffer), mLength(aLength) {
|
||||
mParent = static_cast<nsIContent**>(aParent);
|
||||
};
|
||||
};
|
||||
|
||||
struct opAppendCommentToDocument {
|
||||
char16_t* mBuffer;
|
||||
int32_t mLength;
|
||||
|
||||
explicit opAppendCommentToDocument(char16_t* aBuffer, int32_t aLength)
|
||||
: mBuffer(aBuffer), mLength(aLength){};
|
||||
};
|
||||
|
||||
class nsHtml5TreeOperationStringPair {
|
||||
|
@ -94,6 +237,276 @@ class nsHtml5TreeOperationStringPair {
|
|||
}
|
||||
};
|
||||
|
||||
struct opAppendDoctypeToDocument {
|
||||
nsAtom* mName;
|
||||
nsHtml5TreeOperationStringPair* mStringPair;
|
||||
|
||||
explicit opAppendDoctypeToDocument(nsAtom* aName, const nsAString& aPublicId,
|
||||
const nsAString& aSystemId) {
|
||||
mName = aName;
|
||||
aName->AddRef();
|
||||
mStringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
|
||||
}
|
||||
};
|
||||
|
||||
struct opGetDocumentFragmentForTemplate {
|
||||
nsIContent** mTemplate;
|
||||
nsIContent** mFragHandle;
|
||||
|
||||
explicit opGetDocumentFragmentForTemplate(nsIContentHandle* aTemplate,
|
||||
nsIContentHandle* aFragHandle) {
|
||||
mTemplate = static_cast<nsIContent**>(aTemplate);
|
||||
mFragHandle = static_cast<nsIContent**>(aFragHandle);
|
||||
}
|
||||
};
|
||||
|
||||
struct opGetFosterParent {
|
||||
nsIContent** mTable;
|
||||
nsIContent** mStackParent;
|
||||
nsIContent** mParentHandle;
|
||||
|
||||
explicit opGetFosterParent(nsIContentHandle* aTable,
|
||||
nsIContentHandle* aStackParent,
|
||||
nsIContentHandle* aParentHandle) {
|
||||
mTable = static_cast<nsIContent**>(aTable);
|
||||
mStackParent = static_cast<nsIContent**>(aStackParent);
|
||||
mParentHandle = static_cast<nsIContent**>(aParentHandle);
|
||||
};
|
||||
};
|
||||
|
||||
// Gecko-specific on-pop ops
|
||||
struct opMarkAsBroken {
|
||||
nsresult mResult;
|
||||
|
||||
explicit opMarkAsBroken(nsresult aResult) : mResult(aResult){};
|
||||
};
|
||||
|
||||
struct opRunScript {
|
||||
nsIContent** mElement;
|
||||
nsAHtml5TreeBuilderState* mBuilderState;
|
||||
int32_t mLineNumber;
|
||||
|
||||
explicit opRunScript(nsIContentHandle* aElement,
|
||||
nsAHtml5TreeBuilderState* aBuilderState)
|
||||
: mBuilderState(aBuilderState), mLineNumber(0) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opRunScriptAsyncDefer {
|
||||
nsIContent** mElement;
|
||||
|
||||
explicit opRunScriptAsyncDefer(nsIContentHandle* aElement) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opPreventScriptExecution {
|
||||
nsIContent** mElement;
|
||||
|
||||
explicit opPreventScriptExecution(nsIContentHandle* aElement) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opDoneAddingChildren {
|
||||
nsIContent** mElement;
|
||||
|
||||
explicit opDoneAddingChildren(nsIContentHandle* aElement) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opDoneCreatingElement {
|
||||
nsIContent** mElement;
|
||||
|
||||
explicit opDoneCreatingElement(nsIContentHandle* aElement) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opSetDocumentCharset {
|
||||
const mozilla::Encoding* mEncoding;
|
||||
int32_t mCharsetSource;
|
||||
|
||||
explicit opSetDocumentCharset(const mozilla::Encoding* aEncoding,
|
||||
int32_t aCharsetSource)
|
||||
: mEncoding(aEncoding), mCharsetSource(aCharsetSource){};
|
||||
};
|
||||
|
||||
struct opCharsetSwitchTo {
|
||||
const mozilla::Encoding* mEncoding;
|
||||
int32_t mCharsetSource;
|
||||
int32_t mLineNumber;
|
||||
|
||||
explicit opCharsetSwitchTo(const mozilla::Encoding* aEncoding,
|
||||
int32_t aCharsetSource, int32_t aLineNumber)
|
||||
: mEncoding(aEncoding),
|
||||
mCharsetSource(aCharsetSource),
|
||||
mLineNumber(aLineNumber){};
|
||||
};
|
||||
|
||||
struct opUpdateStyleSheet {
|
||||
nsIContent** mElement;
|
||||
|
||||
explicit opUpdateStyleSheet(nsIContentHandle* aElement) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opProcessMeta {
|
||||
nsIContent** mElement;
|
||||
|
||||
explicit opProcessMeta(nsIContentHandle* aElement) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opProcessOfflineManifest {
|
||||
char16_t* mUrl;
|
||||
|
||||
explicit opProcessOfflineManifest(char16_t* aUrl) : mUrl(aUrl){};
|
||||
};
|
||||
|
||||
struct opMarkMalformedIfScript {
|
||||
nsIContent** mElement;
|
||||
|
||||
explicit opMarkMalformedIfScript(nsIContentHandle* aElement) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
}
|
||||
};
|
||||
|
||||
struct opStreamEnded {};
|
||||
|
||||
struct opSetStyleLineNumber {
|
||||
nsIContent** mContent;
|
||||
int32_t mLineNumber;
|
||||
|
||||
explicit opSetStyleLineNumber(nsIContentHandle* aContent, int32_t aLineNumber)
|
||||
: mLineNumber(aLineNumber) {
|
||||
mContent = static_cast<nsIContent**>(aContent);
|
||||
};
|
||||
};
|
||||
|
||||
struct opSetScriptLineNumberAndFreeze {
|
||||
nsIContent** mContent;
|
||||
int32_t mLineNumber;
|
||||
|
||||
explicit opSetScriptLineNumberAndFreeze(nsIContentHandle* aContent,
|
||||
int32_t aLineNumber)
|
||||
: mLineNumber(aLineNumber) {
|
||||
mContent = static_cast<nsIContent**>(aContent);
|
||||
};
|
||||
};
|
||||
|
||||
struct opSvgLoad {
|
||||
nsIContent** mElement;
|
||||
|
||||
explicit opSvgLoad(nsIContentHandle* aElement) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opMaybeComplainAboutCharset {
|
||||
char* mMsgId;
|
||||
bool mError;
|
||||
int32_t mLineNumber;
|
||||
|
||||
explicit opMaybeComplainAboutCharset(char* aMsgId, bool aError,
|
||||
int32_t aLineNumber)
|
||||
: mMsgId(aMsgId), mError(aError), mLineNumber(aLineNumber){};
|
||||
};
|
||||
|
||||
struct opMaybeComplainAboutDeepTree {
|
||||
int32_t mLineNumber;
|
||||
|
||||
explicit opMaybeComplainAboutDeepTree(int32_t aLineNumber)
|
||||
: mLineNumber(aLineNumber){};
|
||||
};
|
||||
|
||||
struct opAddClass {
|
||||
nsIContent** mElement;
|
||||
char16_t* mClass;
|
||||
|
||||
explicit opAddClass(nsIContentHandle* aElement, char16_t* aClass)
|
||||
: mClass(aClass) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opAddViewSourceHref {
|
||||
nsIContent** mElement;
|
||||
char16_t* mBuffer;
|
||||
int32_t mLength;
|
||||
|
||||
explicit opAddViewSourceHref(nsIContentHandle* aElement, char16_t* aBuffer,
|
||||
int32_t aLength)
|
||||
: mBuffer(aBuffer), mLength(aLength) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opAddViewSourceBase {
|
||||
char16_t* mBuffer;
|
||||
int32_t mLength;
|
||||
|
||||
explicit opAddViewSourceBase(char16_t* aBuffer, int32_t aLength)
|
||||
: mBuffer(aBuffer), mLength(aLength){};
|
||||
};
|
||||
|
||||
struct opAddErrorType {
|
||||
nsIContent** mElement;
|
||||
char* mMsgId;
|
||||
nsAtom* mName;
|
||||
nsAtom* mOther;
|
||||
|
||||
explicit opAddErrorType(nsIContentHandle* aElement, char* aMsgId,
|
||||
nsAtom* aName = nullptr, nsAtom* aOther = nullptr)
|
||||
: mMsgId(aMsgId), mName(aName), mOther(aOther) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
if (aName) {
|
||||
aName->AddRef();
|
||||
}
|
||||
if (aOther) {
|
||||
aOther->AddRef();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct opAddLineNumberId {
|
||||
nsIContent** mElement;
|
||||
int32_t mLineNumber;
|
||||
|
||||
explicit opAddLineNumberId(nsIContentHandle* aElement, int32_t aLineNumber)
|
||||
: mLineNumber(aLineNumber) {
|
||||
mElement = static_cast<nsIContent**>(aElement);
|
||||
};
|
||||
};
|
||||
|
||||
struct opStartLayout {};
|
||||
|
||||
struct opEnableEncodingMenu {};
|
||||
|
||||
typedef mozilla::Variant<
|
||||
uninitialized,
|
||||
// main HTML5 ops
|
||||
opAppend, opDetach, opAppendChildrenToNewParent, opFosterParent,
|
||||
opAppendToDocument, opAddAttributes, nsHtml5DocumentMode,
|
||||
opCreateHTMLElement, opCreateSVGElement, opCreateMathMLElement,
|
||||
opSetFormElement, opAppendText, opFosterParentText, opAppendComment,
|
||||
opAppendCommentToDocument, opAppendDoctypeToDocument,
|
||||
opGetDocumentFragmentForTemplate, opGetFosterParent,
|
||||
// Gecko-specific on-pop ops
|
||||
opMarkAsBroken, opRunScript, opRunScriptAsyncDefer,
|
||||
opPreventScriptExecution, opDoneAddingChildren, opDoneCreatingElement,
|
||||
opSetDocumentCharset, opCharsetSwitchTo, opUpdateStyleSheet, opProcessMeta,
|
||||
opProcessOfflineManifest, opMarkMalformedIfScript, opStreamEnded,
|
||||
opSetStyleLineNumber, opSetScriptLineNumberAndFreeze, opSvgLoad,
|
||||
opMaybeComplainAboutCharset, opMaybeComplainAboutDeepTree, opAddClass,
|
||||
opAddViewSourceHref, opAddViewSourceBase, opAddErrorType, opAddLineNumberId,
|
||||
opStartLayout, opEnableEncodingMenu>
|
||||
treeOperation;
|
||||
|
||||
class nsHtml5TreeOperation final {
|
||||
template <typename T>
|
||||
using NotNull = mozilla::NotNull<T>;
|
||||
|
@ -190,291 +603,25 @@ class nsHtml5TreeOperation final {
|
|||
|
||||
~nsHtml5TreeOperation();
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
mOpCode = aOpCode;
|
||||
inline void Init(const treeOperation& aOperation) {
|
||||
NS_ASSERTION(mOperation.is<uninitialized>(),
|
||||
"Op code must be uninitialized when initializing.");
|
||||
mOperation = aOperation;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aNode, "Initialized tree op with null node.");
|
||||
mOpCode = aOpCode;
|
||||
mOne.node = static_cast<nsIContent**>(aNode);
|
||||
}
|
||||
inline bool IsRunScript() { return mOperation.is<opRunScript>(); }
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode,
|
||||
nsIContentHandle* aParent) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aNode, "Initialized tree op with null node.");
|
||||
MOZ_ASSERT(aParent, "Initialized tree op with null parent.");
|
||||
mOpCode = aOpCode;
|
||||
mOne.node = static_cast<nsIContent**>(aNode);
|
||||
mTwo.node = static_cast<nsIContent**>(aParent);
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, const nsACString& aString,
|
||||
int32_t aInt32) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
|
||||
int32_t len = aString.Length();
|
||||
char* str = new char[len + 1];
|
||||
const char* start = aString.BeginReading();
|
||||
for (int32_t i = 0; i < len; ++i) {
|
||||
str[i] = start[i];
|
||||
}
|
||||
str[len] = '\0';
|
||||
|
||||
mOpCode = aOpCode;
|
||||
mOne.charPtr = str;
|
||||
mFour.integer = aInt32;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, const nsACString& aString,
|
||||
int32_t aInt32, int32_t aLineNumber) {
|
||||
Init(aOpCode, aString, aInt32);
|
||||
mTwo.integer = aLineNumber;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode,
|
||||
NotNull<const Encoding*> aEncoding, int32_t aInt32) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
|
||||
mOpCode = aOpCode;
|
||||
mOne.encoding = aEncoding;
|
||||
mFour.integer = aInt32;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode,
|
||||
NotNull<const Encoding*> aEncoding, int32_t aInt32,
|
||||
int32_t aLineNumber) {
|
||||
Init(aOpCode, aEncoding, aInt32);
|
||||
mTwo.integer = aLineNumber;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode,
|
||||
nsIContentHandle* aParent, nsIContentHandle* aTable) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aNode, "Initialized tree op with null node.");
|
||||
MOZ_ASSERT(aParent, "Initialized tree op with null parent.");
|
||||
MOZ_ASSERT(aTable, "Initialized tree op with null table.");
|
||||
mOpCode = aOpCode;
|
||||
mOne.node = static_cast<nsIContent**>(aNode);
|
||||
mTwo.node = static_cast<nsIContent**>(aParent);
|
||||
mThree.node = static_cast<nsIContent**>(aTable);
|
||||
}
|
||||
|
||||
inline void Init(nsHtml5DocumentMode aMode) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
mOpCode = eTreeOpDocumentMode;
|
||||
mOne.mode = aMode;
|
||||
}
|
||||
|
||||
inline void InitScript(nsIContentHandle* aNode) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aNode, "Initialized tree op with null node.");
|
||||
mOpCode = eTreeOpRunScript;
|
||||
mOne.node = static_cast<nsIContent**>(aNode);
|
||||
mTwo.state = nullptr;
|
||||
}
|
||||
|
||||
inline void Init(int32_t aNamespace, nsAtom* aName,
|
||||
nsHtml5HtmlAttributes* aAttributes,
|
||||
nsIContentHandle* aTarget, nsIContentHandle* aIntendedParent,
|
||||
bool aFromNetwork, nsHtml5ContentCreatorFunction aCreator) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aName, "Initialized tree op with null name.");
|
||||
MOZ_ASSERT(aTarget, "Initialized tree op with null target node.");
|
||||
|
||||
if (aNamespace == kNameSpaceID_XHTML) {
|
||||
mOpCode = aFromNetwork ? eTreeOpCreateHTMLElementNetwork
|
||||
: eTreeOpCreateHTMLElementNotNetwork;
|
||||
mFour.htmlCreator = aCreator.html;
|
||||
} else if (aNamespace == kNameSpaceID_SVG) {
|
||||
mOpCode = aFromNetwork ? eTreeOpCreateSVGElementNetwork
|
||||
: eTreeOpCreateSVGElementNotNetwork;
|
||||
mFour.svgCreator = aCreator.svg;
|
||||
} else {
|
||||
MOZ_ASSERT(aNamespace == kNameSpaceID_MathML);
|
||||
mOpCode = eTreeOpCreateMathMLElement;
|
||||
}
|
||||
mFive.node = static_cast<nsIContent**>(aIntendedParent);
|
||||
mOne.node = static_cast<nsIContent**>(aTarget);
|
||||
mTwo.atom = aName;
|
||||
aName->AddRef();
|
||||
if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
|
||||
mThree.attributes = nullptr;
|
||||
} else {
|
||||
mThree.attributes = aAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, char16_t* aBuffer,
|
||||
int32_t aLength, nsIContentHandle* aStackParent,
|
||||
nsIContentHandle* aTable) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aBuffer, "Initialized tree op with null buffer.");
|
||||
mOpCode = aOpCode;
|
||||
mOne.node = static_cast<nsIContent**>(aStackParent);
|
||||
mTwo.unicharPtr = aBuffer;
|
||||
mThree.node = static_cast<nsIContent**>(aTable);
|
||||
mFour.integer = aLength;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, char16_t* aBuffer,
|
||||
int32_t aLength, nsIContentHandle* aParent) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aBuffer, "Initialized tree op with null buffer.");
|
||||
mOpCode = aOpCode;
|
||||
mOne.node = static_cast<nsIContent**>(aParent);
|
||||
mTwo.unicharPtr = aBuffer;
|
||||
mFour.integer = aLength;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, char16_t* aBuffer,
|
||||
int32_t aLength) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aBuffer, "Initialized tree op with null buffer.");
|
||||
mOpCode = aOpCode;
|
||||
mTwo.unicharPtr = aBuffer;
|
||||
mFour.integer = aLength;
|
||||
}
|
||||
|
||||
inline void Init(nsIContentHandle* aElement,
|
||||
nsHtml5HtmlAttributes* aAttributes) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aElement, "Initialized tree op with null element.");
|
||||
mOpCode = eTreeOpAddAttributes;
|
||||
mOne.node = static_cast<nsIContent**>(aElement);
|
||||
mTwo.attributes = aAttributes;
|
||||
}
|
||||
|
||||
inline void Init(nsAtom* aName, const nsAString& aPublicId,
|
||||
const nsAString& aSystemId) {
|
||||
MOZ_ASSERT(aName);
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
mOpCode = eTreeOpAppendDoctypeToDocument;
|
||||
mOne.atom = aName;
|
||||
aName->AddRef();
|
||||
mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
|
||||
}
|
||||
|
||||
inline void Init(nsIContentHandle* aElement, const char* aMsgId,
|
||||
nsAtom* aAtom, nsAtom* aOtherAtom) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
mOpCode = eTreeOpAddError;
|
||||
mOne.node = static_cast<nsIContent**>(aElement);
|
||||
mTwo.charPtr = (char*)aMsgId;
|
||||
mThree.atom = aAtom;
|
||||
mFour.atom = aOtherAtom;
|
||||
if (aAtom) {
|
||||
aAtom->AddRef();
|
||||
}
|
||||
if (aOtherAtom) {
|
||||
aOtherAtom->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
inline void Init(nsIContentHandle* aElement, const char* aMsgId,
|
||||
nsAtom* aAtom) {
|
||||
Init(aElement, aMsgId, aAtom, nullptr);
|
||||
}
|
||||
|
||||
inline void Init(nsIContentHandle* aElement, const char* aMsgId) {
|
||||
Init(aElement, aMsgId, nullptr, nullptr);
|
||||
}
|
||||
|
||||
inline void Init(const char* aMsgId, bool aError, int32_t aLineNumber) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
mOpCode = eTreeOpMaybeComplainAboutCharset;
|
||||
mOne.charPtr = const_cast<char*>(aMsgId);
|
||||
mTwo.integer = aError;
|
||||
mThree.integer = aLineNumber;
|
||||
}
|
||||
|
||||
inline void InitDeepTree(int32_t aLineNumber) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
mOpCode = eTreeOpMaybeComplainAboutDeepTree;
|
||||
mOne.integer = aLineNumber;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, const nsAString& aString) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
|
||||
char16_t* str = ToNewUnicode(aString);
|
||||
mOpCode = aOpCode;
|
||||
mOne.unicharPtr = str;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode,
|
||||
int32_t aInt) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aNode, "Initialized tree op with null node.");
|
||||
mOpCode = aOpCode;
|
||||
mOne.node = static_cast<nsIContent**>(aNode);
|
||||
mFour.integer = aInt;
|
||||
}
|
||||
|
||||
inline void Init(nsresult aRv) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(NS_FAILED(aRv), "Initialized tree op with non-failure.");
|
||||
mOpCode = eTreeOpMarkAsBroken;
|
||||
mOne.result = aRv;
|
||||
}
|
||||
|
||||
inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aNode, "Initialized tree op with null node.");
|
||||
MOZ_ASSERT(aClass, "Initialized tree op with null string.");
|
||||
// aClass must be a literal string that does not need freeing
|
||||
mOpCode = eTreeOpAddClass;
|
||||
mOne.node = static_cast<nsIContent**>(aNode);
|
||||
mTwo.unicharPtr = (char16_t*)aClass;
|
||||
}
|
||||
|
||||
inline void InitAddLineNumberId(nsIContentHandle* aNode,
|
||||
const int32_t aLineNumber) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
MOZ_ASSERT(aNode, "Initialized tree op with null node.");
|
||||
MOZ_ASSERT(aLineNumber > 0, "Initialized tree op with line number.");
|
||||
// aClass must be a literal string that does not need freeing
|
||||
mOpCode = eTreeOpAddLineNumberId;
|
||||
mOne.node = static_cast<nsIContent**>(aNode);
|
||||
mFour.integer = aLineNumber;
|
||||
}
|
||||
|
||||
inline bool IsRunScript() { return mOpCode == eTreeOpRunScript; }
|
||||
|
||||
inline bool IsMarkAsBroken() { return mOpCode == eTreeOpMarkAsBroken; }
|
||||
inline bool IsMarkAsBroken() { return mOperation.is<opMarkAsBroken>(); }
|
||||
|
||||
inline void SetSnapshot(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine) {
|
||||
NS_ASSERTION(
|
||||
IsRunScript(),
|
||||
"Setting a snapshot for a tree operation other than eTreeOpRunScript!");
|
||||
MOZ_ASSERT(aSnapshot, "Initialized tree op with null snapshot.");
|
||||
mTwo.state = aSnapshot;
|
||||
mFour.integer = aLine;
|
||||
opRunScript data = mOperation.as<opRunScript>();
|
||||
data.mBuilderState = aSnapshot;
|
||||
data.mLineNumber = aLine;
|
||||
mOperation = mozilla::AsVariant(data);
|
||||
}
|
||||
|
||||
nsresult Perform(nsHtml5TreeOpExecutor* aBuilder, nsIContent** aScriptElement,
|
||||
|
@ -484,25 +631,7 @@ class nsHtml5TreeOperation final {
|
|||
nsHtml5TreeOperation(const nsHtml5TreeOperation&) = delete;
|
||||
nsHtml5TreeOperation& operator=(const nsHtml5TreeOperation&) = delete;
|
||||
|
||||
// possible optimization:
|
||||
// Make the queue take items the size of pointer and make the op code
|
||||
// decide how many operands it dequeues after it.
|
||||
eHtml5TreeOperation mOpCode;
|
||||
union {
|
||||
nsIContent** node;
|
||||
nsAtom* atom;
|
||||
nsHtml5HtmlAttributes* attributes;
|
||||
nsHtml5DocumentMode mode;
|
||||
char16_t* unicharPtr;
|
||||
char* charPtr;
|
||||
nsHtml5TreeOperationStringPair* stringPair;
|
||||
nsAHtml5TreeBuilderState* state;
|
||||
int32_t integer;
|
||||
nsresult result;
|
||||
const Encoding* encoding;
|
||||
mozilla::dom::HTMLContentCreatorFunction htmlCreator;
|
||||
mozilla::dom::SVGContentCreatorFunction svgCreator;
|
||||
} mOne, mTwo, mThree, mFour, mFive;
|
||||
treeOperation mOperation;
|
||||
};
|
||||
|
||||
#endif // nsHtml5TreeOperation_h
|
||||
|
|
|
@ -313,7 +313,7 @@ void nsScannerString::UngetReadable(const nsAString& aReadable,
|
|||
|
||||
Buffer* new_buffer = AllocBufferFromString(aReadable);
|
||||
// make a new buffer with all the data to insert...
|
||||
// BULLSHIT ALERT: we may have empty space to re-use in the split buffer,
|
||||
// ALERT: we may have empty space to re-use in the split buffer,
|
||||
// measure the cost of this and decide if we should do the work to fill
|
||||
// it
|
||||
|
||||
|
|
|
@ -10,35 +10,39 @@
|
|||
# bootstrap support. It does this through various means, including fetching
|
||||
# content from the upstream source repository.
|
||||
|
||||
# If we add unicode_literals, optparse breaks on Python 2.6.1 (which is needed
|
||||
# to support OS X 10.6).
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
WRONG_PYTHON_VERSION_MESSAGE = '''
|
||||
Bootstrap currently only runs on Python 2.7 or Python 2.6.
|
||||
Please try re-running with python2.7 or python2.6.
|
||||
Bootstrap currently only runs on Python 2.7 or Python 3.5+.
|
||||
Please try re-running with python2.7 or python3.5+.
|
||||
|
||||
If these aren't available on your system, you may need to install them.
|
||||
Look for a "python2" or "python27" package in your package manager.
|
||||
Look for a "python2" or "python3.5" package in your package manager.
|
||||
'''
|
||||
|
||||
import sys
|
||||
if sys.version_info[:2] not in [(2, 6), (2, 7)]:
|
||||
|
||||
major, minor = sys.version_info[:2]
|
||||
if (major == 2 and minor < 7) or (major == 3 and minor < 5):
|
||||
print(WRONG_PYTHON_VERSION_MESSAGE)
|
||||
sys.exit(1)
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from StringIO import StringIO
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
from io import BytesIO
|
||||
from optparse import OptionParser
|
||||
|
||||
# NOTE: This script is intended to be run with a vanilla Python install. We
|
||||
# have to rely on the standard library instead of Python 2+3 helpers like
|
||||
# the six module.
|
||||
try:
|
||||
from urllib2 import urlopen
|
||||
except ImportError:
|
||||
from urllib.request import urlopen
|
||||
import zipfile
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
# The next two variables define where in the repository the Python files
|
||||
# reside. This is used to remotely download file content when it isn't
|
||||
|
@ -67,7 +71,7 @@ def fetch_files(repo_url, repo_rev, repo_type):
|
|||
if repo_type == 'hgweb':
|
||||
url = repo_url + '/archive/%s.zip/python/mozboot' % repo_rev
|
||||
req = urlopen(url=url, timeout=30)
|
||||
data = StringIO(req.read())
|
||||
data = BytesIO(req.read())
|
||||
data.seek(0)
|
||||
zip = zipfile.ZipFile(data, 'r')
|
||||
for f in zip.infolist():
|
||||
|
@ -154,6 +158,9 @@ def main(args):
|
|||
'instead of using the default interactive prompt.')
|
||||
parser.add_option('--no-interactive', dest='no_interactive', action='store_true',
|
||||
help='Answer yes to any (Y/n) interactive prompts.')
|
||||
parser.add_option('--debug', dest='debug', action='store_true',
|
||||
help='Print extra runtime information useful for debugging and '
|
||||
'bug reports.')
|
||||
|
||||
options, leftover = parser.parse_args(args)
|
||||
|
||||
|
@ -165,8 +172,14 @@ def main(args):
|
|||
print('Could not load the bootstrap Python environment.\n')
|
||||
print('This should never happen. Consider filing a bug.\n')
|
||||
print('\n')
|
||||
|
||||
if options.debug:
|
||||
# Raise full tracebacks during debugging and for bug reporting.
|
||||
raise
|
||||
|
||||
print(e)
|
||||
return 1
|
||||
|
||||
dasboot = cls(choice=options.application_choice, no_interactive=options.no_interactive,
|
||||
vcs=options.vcs)
|
||||
dasboot.bootstrap()
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
# 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/.
|
||||
|
||||
# If we add unicode_literals, Python 2.6.1 (required for OS X 10.6) breaks.
|
||||
from __future__ import absolute_import, print_function
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import errno
|
||||
import os
|
||||
|
@ -281,7 +280,7 @@ def ensure_android_packages(sdkmanager_tool, packages=None, no_interactive=False
|
|||
|
||||
# Emulate yes. For a discussion of passing input to check_output,
|
||||
# see https://stackoverflow.com/q/10103551.
|
||||
yes = '\n'.join(['y']*100)
|
||||
yes = '\n'.join(['y']*100).encode("UTF-8")
|
||||
proc = subprocess.Popen(args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# 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/.
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -18,6 +18,12 @@ from mozboot.linux_common import (
|
|||
StyloInstall,
|
||||
)
|
||||
|
||||
# NOTE: This script is intended to be run with a vanilla Python install. We
|
||||
# have to rely on the standard library instead of Python 2+3 helpers like
|
||||
# the six module.
|
||||
if sys.version_info < (3,):
|
||||
input = raw_input
|
||||
|
||||
|
||||
class ArchlinuxBootstrapper(NodeInstall, StyloInstall, SccacheInstall,
|
||||
ClangStaticAnalysisInstall, BaseBootstrapper):
|
||||
|
@ -190,7 +196,7 @@ class ArchlinuxBootstrapper(NodeInstall, StyloInstall, SccacheInstall,
|
|||
'This is potentially unsecure so I recommend that you carefully '
|
||||
'read each package description and check the sources.'
|
||||
'These packages will be built in ' + path + '.')
|
||||
choice = raw_input('Do you want to continue? (yes/no) [no]')
|
||||
choice = input('Do you want to continue? (yes/no) [no]')
|
||||
if choice != 'yes':
|
||||
sys.exit(1)
|
||||
|
||||
|
|
|
@ -9,11 +9,20 @@ import os
|
|||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib2
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from mozboot import rust
|
||||
|
||||
# NOTE: This script is intended to be run with a vanilla Python install. We
|
||||
# have to rely on the standard library instead of Python 2+3 helpers like
|
||||
# the six module.
|
||||
if sys.version_info < (3,):
|
||||
from urllib2 import urlopen
|
||||
input = raw_input
|
||||
else:
|
||||
from urllib.request import urlopen
|
||||
|
||||
|
||||
NO_MERCURIAL = '''
|
||||
Could not find Mercurial (hg) in the current shell's path. Try starting a new
|
||||
shell and running the bootstrapper again.
|
||||
|
@ -403,30 +412,18 @@ class BaseBootstrapper(object):
|
|||
|
||||
def check_output(self, *args, **kwargs):
|
||||
"""Run subprocess.check_output even if Python doesn't provide it."""
|
||||
fn = getattr(subprocess, 'check_output', BaseBootstrapper._check_output)
|
||||
|
||||
return fn(*args, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def _check_output(*args, **kwargs):
|
||||
"""Python 2.6 compatible implementation of subprocess.check_output."""
|
||||
proc = subprocess.Popen(stdout=subprocess.PIPE, *args, **kwargs)
|
||||
output, unused_err = proc.communicate()
|
||||
retcode = proc.poll()
|
||||
if retcode:
|
||||
cmd = kwargs.get('args', args[0])
|
||||
e = subprocess.CalledProcessError(retcode, cmd)
|
||||
e.output = output
|
||||
raise e
|
||||
|
||||
return output
|
||||
# TODO Legacy Python 2.6 code, can be removed.
|
||||
# We had a custom check_output() function for Python 2.6 backward
|
||||
# compatibility. Since py2.6 support was dropped we can remove this
|
||||
# method.
|
||||
return subprocess.check_output(*args, **kwargs)
|
||||
|
||||
def prompt_int(self, prompt, low, high, limit=5):
|
||||
''' Prompts the user with prompt and requires an integer between low and high. '''
|
||||
valid = False
|
||||
while not valid and limit > 0:
|
||||
try:
|
||||
choice = int(raw_input(prompt))
|
||||
choice = int(input(prompt))
|
||||
if not low <= choice <= high:
|
||||
print("ERROR! Please enter a valid option!")
|
||||
limit -= 1
|
||||
|
@ -445,7 +442,7 @@ class BaseBootstrapper(object):
|
|||
''' Prompts the user with prompt and requires a yes/no answer.'''
|
||||
valid = False
|
||||
while not valid:
|
||||
choice = raw_input(prompt + ' (Yn): ').strip().lower()[:1]
|
||||
choice = input(prompt + ' (Yn): ').strip().lower()[:1]
|
||||
if choice == '':
|
||||
choice = 'y'
|
||||
if choice not in ('y', 'n'):
|
||||
|
@ -490,7 +487,8 @@ class BaseBootstrapper(object):
|
|||
|
||||
info = self.check_output([path, version_param],
|
||||
env=env,
|
||||
stderr=subprocess.STDOUT)
|
||||
stderr=subprocess.STDOUT,
|
||||
universal_newlines=True)
|
||||
match = re.search(name + ' ([a-z0-9\.]+)', info)
|
||||
if not match:
|
||||
print('ERROR! Unable to identify %s version.' % name)
|
||||
|
@ -703,7 +701,9 @@ class BaseBootstrapper(object):
|
|||
|
||||
def ensure_rust_targets(self, rustup, rust_version):
|
||||
"""Make sure appropriate cross target libraries are installed."""
|
||||
target_list = subprocess.check_output([rustup, 'target', 'list'])
|
||||
target_list = subprocess.check_output(
|
||||
[rustup, 'target', 'list'], universal_newlines=True
|
||||
)
|
||||
targets = [line.split()[0] for line in target_list.splitlines()
|
||||
if 'installed' in line or 'default' in line]
|
||||
print('Rust supports %s targets.' % ', '.join(targets))
|
||||
|
@ -772,7 +772,7 @@ class BaseBootstrapper(object):
|
|||
that will be used to validate the downloaded file using the given
|
||||
digest algorithm. The value of digest can be any value accepted by
|
||||
hashlib.new. The default digest used is 'sha256'."""
|
||||
f = urllib2.urlopen(url)
|
||||
f = urlopen(url)
|
||||
h = hashlib.new(digest)
|
||||
with open(dest, 'wb') as out:
|
||||
while True:
|
||||
|
@ -812,7 +812,8 @@ class BaseBootstrapper(object):
|
|||
output = subprocess.check_output([java,
|
||||
'-XshowSettings:properties',
|
||||
'-version'],
|
||||
stderr=subprocess.STDOUT).rstrip()
|
||||
stderr=subprocess.STDOUT,
|
||||
universal_newlines=True).rstrip()
|
||||
|
||||
# -version strings are pretty free-form, like: 'java version
|
||||
# "1.8.0_192"' or 'openjdk version "11.0.1" 2018-10-16', but the
|
||||
|
|
|
@ -2,19 +2,23 @@
|
|||
# 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/.
|
||||
|
||||
# If we add unicode_literals, Python 2.6.1 (required for OS X 10.6) breaks.
|
||||
from __future__ import absolute_import, print_function
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import platform
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
try:
|
||||
|
||||
# NOTE: This script is intended to be run with a vanilla Python install. We
|
||||
# have to rely on the standard library instead of Python 2+3 helpers like
|
||||
# the six module.
|
||||
if sys.version_info < (3,):
|
||||
from ConfigParser import (
|
||||
Error as ConfigParserError,
|
||||
RawConfigParser,
|
||||
)
|
||||
except ImportError:
|
||||
input = raw_input
|
||||
else:
|
||||
from configparser import (
|
||||
Error as ConfigParserError,
|
||||
RawConfigParser,
|
||||
|
@ -58,6 +62,7 @@ APPLICATIONS_LIST = [
|
|||
('GeckoView/Firefox for Android', 'mobile_android'),
|
||||
]
|
||||
|
||||
# TODO Legacy Python 2.6 code, can be removed.
|
||||
# This is a workaround for the fact that we must support python2.6 (which has
|
||||
# no OrderedDict)
|
||||
APPLICATIONS = dict(
|
||||
|
@ -218,7 +223,7 @@ def update_or_create_build_telemetry_config(path):
|
|||
if not config.has_section('build'):
|
||||
config.add_section('build')
|
||||
config.set('build', 'telemetry', 'true')
|
||||
with open(path, 'wb') as f:
|
||||
with open(path, 'w') as f:
|
||||
config.write(f)
|
||||
return True
|
||||
|
||||
|
@ -298,7 +303,7 @@ class Bootstrapper(object):
|
|||
print(CLONE_VCS.format(repo_name, vcs))
|
||||
|
||||
while True:
|
||||
dest = raw_input(CLONE_VCS_PROMPT.format(vcs))
|
||||
dest = input(CLONE_VCS_PROMPT.format(vcs))
|
||||
dest = dest.strip()
|
||||
if not dest:
|
||||
return ''
|
||||
|
@ -643,7 +648,8 @@ def current_firefox_checkout(check_output, env, hg=None):
|
|||
try:
|
||||
node = check_output([hg, 'log', '-r', '0', '--template', '{node}'],
|
||||
cwd=path,
|
||||
env=env)
|
||||
env=env,
|
||||
universal_newlines=True)
|
||||
if node in HG_ROOT_REVISIONS:
|
||||
return ('hg', path)
|
||||
# Else the root revision is different. There could be nested
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# 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/.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import platform
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# 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/.
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
from mozboot.base import BaseBootstrapper
|
||||
from mozboot.linux_common import (
|
||||
|
@ -109,8 +109,8 @@ class DebianBootstrapper(NasmInstall, NodeInstall, StyloInstall, ClangStaticAnal
|
|||
self.which('python3.5')])
|
||||
|
||||
if not have_python3:
|
||||
python3_packages = self.check_output([
|
||||
'apt-cache', 'pkgnames', 'python3'])
|
||||
python3_packages = self.check_output(
|
||||
['apt-cache', 'pkgnames', 'python3'], universal_newlines=True)
|
||||
python3_packages = python3_packages.splitlines()
|
||||
|
||||
if 'python3' in python3_packages:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# 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/.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
import sys
|
||||
|
||||
from mozboot.base import BaseBootstrapper
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# 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/.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
from mozboot.base import BaseBootstrapper
|
||||
from mozboot.linux_common import (
|
||||
|
@ -54,7 +54,8 @@ class GentooBootstrapper(NasmInstall, NodeInstall, StyloInstall, ClangStaticAnal
|
|||
@staticmethod
|
||||
def _get_distdir():
|
||||
# Obtain the path held in the DISTDIR portage variable
|
||||
output = subprocess.check_output(['emerge', '--info'])
|
||||
output = subprocess.check_output(
|
||||
['emerge', '--info'], universal_newlines=True)
|
||||
match = re.search('^DISTDIR="(?P<distdir>.*)"$', output, re.MULTILINE)
|
||||
return match.group('distdir')
|
||||
|
||||
|
@ -98,7 +99,8 @@ class GentooBootstrapper(NasmInstall, NodeInstall, StyloInstall, ClangStaticAnal
|
|||
output = self.check_output(['emerge', '--pretend', '--fetchonly',
|
||||
'oracle-jdk-bin'],
|
||||
env=None,
|
||||
stderr=subprocess.STDOUT)
|
||||
stderr=subprocess.STDOUT,
|
||||
universal_newlines=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
output = e.output
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче