Merge autoland to mozilla-central. a=merge

This commit is contained in:
shindli 2019-08-28 03:48:53 +03:00
Родитель 2e7e5f93bc 4ba1487439
Коммит 3c01a01df9
168 изменённых файлов: 3487 добавлений и 2026 удалений

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

@ -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 its 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>Heres 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 dont. 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 wasnt 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 theres an image error we wont flush the style hints since were 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>&lt;p&gt;Tonight is Robbie Burns night, in honour of that great Scottish poet. But tonight had me thinking about another night in my past.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;We had a great night. That ended way too soon.&lt;/p&gt;

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

@ -393,8 +393,6 @@
<link>http://www.agmweb.ca/2016-01-25-robbie-burns/</link>
<description>&lt;p&gt;Tonight is Robbie Burns night, in honour of that great Scottish poet. But tonight had me thinking about another night in my past.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;We had a great night. That ended way too soon.&lt;/p&gt;

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

@ -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;

213
package-lock.json сгенерированный
Просмотреть файл

@ -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

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше