mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 01:35:35 +00:00
Merge autoland to central, a=merge
MozReview-Commit-ID: ARlpf5Z77fz
This commit is contained in:
commit
8419692f73
@ -37,7 +37,6 @@
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
|
@ -318,6 +318,10 @@ pref("browser.urlbar.oneOffSearches", true);
|
||||
pref("browser.urlbar.oneOffSearches", false);
|
||||
#endif
|
||||
|
||||
// If changed to true, copying the entire URL from the location bar will put the
|
||||
// human readable (percent-decoded) URL on the clipboard.
|
||||
pref("browser.urlbar.decodeURLsOnCopy", false);
|
||||
|
||||
pref("browser.altClickSave", false);
|
||||
|
||||
// Enable logging downloads operations to the Console.
|
||||
|
@ -425,6 +425,8 @@ const gXPInstallObserver = {
|
||||
return i.addon.pendingOperations != AddonManager.PENDING_NONE;
|
||||
});
|
||||
|
||||
let secondaryActions = null;
|
||||
|
||||
if (needsRestart) {
|
||||
notificationID = "addon-install-restart";
|
||||
messageString = gNavigatorBundle.getString("addonsInstalledNeedsRestart");
|
||||
@ -435,6 +437,11 @@ const gXPInstallObserver = {
|
||||
BrowserUtils.restartApplication();
|
||||
}
|
||||
};
|
||||
secondaryActions = [{
|
||||
label: gNavigatorBundle.getString("addonInstallRestartIgnoreButton"),
|
||||
accessKey: gNavigatorBundle.getString("addonInstallRestartIgnoreButton.accesskey"),
|
||||
callback: () => {},
|
||||
}];
|
||||
}
|
||||
else {
|
||||
messageString = gNavigatorBundle.getString("addonsInstalled");
|
||||
@ -446,14 +453,14 @@ const gXPInstallObserver = {
|
||||
messageString = messageString.replace("#2", installInfo.installs.length);
|
||||
messageString = messageString.replace("#3", brandShortName);
|
||||
|
||||
// Remove notificaion on dismissal, since it's possible to cancel the
|
||||
// Remove notification on dismissal, since it's possible to cancel the
|
||||
// install through the addons manager UI, making the "restart" prompt
|
||||
// irrelevant.
|
||||
options.removeOnDismissal = true;
|
||||
options.persistent = false;
|
||||
|
||||
PopupNotifications.show(browser, notificationID, messageString, anchorID,
|
||||
action, null, options);
|
||||
action, secondaryActions, options);
|
||||
break; }
|
||||
}
|
||||
},
|
||||
|
@ -3,6 +3,15 @@
|
||||
|
||||
const trimPref = "browser.urlbar.trimURLs";
|
||||
const phishyUserPassPref = "network.http.phishy-userpass-length";
|
||||
const decodeURLpref = "browser.urlbar.decodeURLsOnCopy";
|
||||
|
||||
function toUnicode(input) {
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
|
||||
return converter.ConvertToUnicode(input);
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
@ -12,6 +21,7 @@ function test() {
|
||||
gBrowser.removeTab(tab);
|
||||
Services.prefs.clearUserPref(trimPref);
|
||||
Services.prefs.clearUserPref(phishyUserPassPref);
|
||||
Services.prefs.clearUserPref(decodeURLpref);
|
||||
URLBarSetURI();
|
||||
});
|
||||
|
||||
@ -141,7 +151,17 @@ var tests = [
|
||||
{
|
||||
copyVal: "<data:text/html,(%C3%A9 %25P>)",
|
||||
copyExpected: "data:text/html,(%C3%A9 %25P",
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: function() { Services.prefs.setBoolPref(decodeURLpref, true); },
|
||||
loadURL: "http://example.com/%D0%B1%D0%B8%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%8F",
|
||||
expectedURL: toUnicode("example.com/биография"),
|
||||
copyExpected: toUnicode("http://example.com/биография")
|
||||
},
|
||||
{
|
||||
copyVal: toUnicode("<example.com/би>ография"),
|
||||
copyExpected: toUnicode("http://example.com/би")
|
||||
},
|
||||
];
|
||||
|
||||
function nextTest() {
|
||||
@ -162,6 +182,10 @@ function runTest(testCase, cb) {
|
||||
testCopy(testCase.copyVal, testCase.copyExpected, cb);
|
||||
}
|
||||
|
||||
if (testCase.setup) {
|
||||
testCase.setup();
|
||||
}
|
||||
|
||||
if (testCase.loadURL) {
|
||||
loadURL(testCase.loadURL, doCheck);
|
||||
} else {
|
||||
|
@ -797,19 +797,17 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
uri = uriFixup.createExposableURI(uri);
|
||||
} catch (ex) {}
|
||||
|
||||
// If the entire URL is selected, just use the actual loaded URI.
|
||||
if (inputVal == selectedVal) {
|
||||
// ... but only if isn't a javascript: or data: URI, since those
|
||||
// are hard to read when encoded
|
||||
if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
|
||||
selectedVal = uri.spec;
|
||||
}
|
||||
|
||||
return selectedVal;
|
||||
// If the entire URL is selected, just use the actual loaded URI,
|
||||
// unless we want a decoded URI, or it's a data: or javascript: URI,
|
||||
// since those are hard to read when encoded.
|
||||
if (inputVal == selectedVal &&
|
||||
!uri.schemeIs("javascript") && !uri.schemeIs("data") &&
|
||||
!Services.prefs.getBoolPref("browser.urlbar.decodeURLsOnCopy")) {
|
||||
return uri.spec;
|
||||
}
|
||||
|
||||
// Just the beginning of the URL is selected, check for a trimmed
|
||||
// value
|
||||
// Just the beginning of the URL is selected, or we want a decoded
|
||||
// url. First check for a trimmed value.
|
||||
let spec = uri.spec;
|
||||
let trimmedSpec = this.trimValue(spec);
|
||||
if (spec != trimmedSpec) {
|
||||
|
@ -7,6 +7,12 @@
|
||||
# with a script that invokes the real gcc with -fplugin and its configuration
|
||||
# directives. Instead, duplicate the contents of that mozconfig here:
|
||||
|
||||
MOZ_AUTOMATION_BUILD_SYMBOLS=0
|
||||
MOZ_AUTOMATION_L10N_CHECK=0
|
||||
MOZ_AUTOMATION_PACKAGE=0
|
||||
MOZ_AUTOMATION_PACKAGE_TESTS=0
|
||||
MOZ_AUTOMATION_UPLOAD=0
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common"
|
||||
ac_add_options --enable-elf-hack
|
||||
|
||||
|
@ -77,6 +77,8 @@ addonsInstalled=#1 has been installed successfully.;#2 add-ons have been install
|
||||
addonsInstalledNeedsRestart=#1 will be installed after you restart #3.;#2 add-ons will be installed after you restart #3.
|
||||
addonInstallRestartButton=Restart Now
|
||||
addonInstallRestartButton.accesskey=R
|
||||
addonInstallRestartIgnoreButton=Not Now
|
||||
addonInstallRestartIgnoreButton.accesskey=N
|
||||
|
||||
# LOCALIZATION NOTE (addonInstallError-1, addonInstallError-2, addonInstallError-3, addonInstallError-4, addonInstallError-5, addonLocalInstallError-1, addonLocalInstallError-2, addonLocalInstallError-3, addonLocalInstallError-4, addonLocalInstallError-5):
|
||||
# %1$S is the application name, %2$S is the add-on name
|
||||
|
@ -228,12 +228,20 @@ def early_options():
|
||||
|
||||
early_options = early_options()
|
||||
|
||||
@depends(mozconfig, '--help')
|
||||
@depends(mozconfig, 'MOZ_AUTOMATION', '--help')
|
||||
# This gives access to the sandbox. Don't copy this blindly.
|
||||
@imports('__sandbox__')
|
||||
@imports('os')
|
||||
def mozconfig_options(mozconfig, help):
|
||||
def mozconfig_options(mozconfig, automation, help):
|
||||
if mozconfig['path']:
|
||||
if 'MOZ_AUTOMATION_MOZCONFIG' in mozconfig['env']['added']:
|
||||
if not automation:
|
||||
log.error('%s directly or indirectly includes an in-tree '
|
||||
'mozconfig.', mozconfig['path'])
|
||||
log.error('In-tree mozconfigs make strong assumptions about '
|
||||
'and are only meant to be used by Mozilla'
|
||||
'automation.')
|
||||
die("Please don't use them.")
|
||||
helper = __sandbox__._helper
|
||||
log.info('Adding configure options from %s' % mozconfig['path'])
|
||||
for arg in mozconfig['configure_args']:
|
||||
|
@ -31,3 +31,5 @@ if test "$MOZ_AUTOMATION_PRETTY" = "1"; then
|
||||
# we don't build it without, so this is set to 1.
|
||||
mk_add_options "export MOZ_AUTOMATION_PRETTY_UPDATE_PACKAGING=1"
|
||||
fi
|
||||
|
||||
export MOZ_AUTOMATION_MOZCONFIG=1
|
||||
|
@ -33,11 +33,16 @@ const StackTrace = createClass({
|
||||
|
||||
PropTypes: {
|
||||
stacktrace: PropTypes.array.isRequired,
|
||||
onViewSourceInDebugger: PropTypes.func.isRequired
|
||||
onViewSourceInDebugger: PropTypes.func.isRequired,
|
||||
onViewSourceInScratchpad: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
render() {
|
||||
let { stacktrace, onViewSourceInDebugger } = this.props;
|
||||
let {
|
||||
stacktrace,
|
||||
onViewSourceInDebugger,
|
||||
onViewSourceInScratchpad
|
||||
} = this.props;
|
||||
|
||||
let frames = [];
|
||||
stacktrace.forEach(s => {
|
||||
@ -47,17 +52,20 @@ const StackTrace = createClass({
|
||||
}), "\n");
|
||||
}
|
||||
|
||||
let source = s.filename.split(" -> ").pop();
|
||||
frames.push("\t", Frame({
|
||||
frame: {
|
||||
functionDisplayName: s.functionName,
|
||||
source: s.filename.split(" -> ").pop(),
|
||||
source,
|
||||
line: s.lineNumber,
|
||||
column: s.columnNumber,
|
||||
},
|
||||
showFunctionName: true,
|
||||
showAnonymousFunctionName: true,
|
||||
showFullSourceUrl: true,
|
||||
onClick: onViewSourceInDebugger
|
||||
onClick: (/^Scratchpad\/\d+$/.test(source))
|
||||
? onViewSourceInScratchpad
|
||||
: onViewSourceInDebugger
|
||||
}), "\n");
|
||||
});
|
||||
|
||||
|
@ -44,7 +44,8 @@ window.onload = function () {
|
||||
|
||||
let props = {
|
||||
stacktrace,
|
||||
onViewSourceInDebugger: () => {}
|
||||
onViewSourceInDebugger: () => {},
|
||||
onViewSourceInScratchpad: () => {},
|
||||
};
|
||||
|
||||
let trace = ReactDOM.render(StackTrace(props), window.document.body);
|
||||
|
@ -15,6 +15,7 @@ const {
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const {MESSAGE_SOURCE} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
const CollapseButton = createFactory(require("devtools/client/webconsole/new-console-output/components/collapse-button"));
|
||||
const MessageIndent = createFactory(require("devtools/client/webconsole/new-console-output/components/message-indent").MessageIndent);
|
||||
const MessageIcon = createFactory(require("devtools/client/webconsole/new-console-output/components/message-icon"));
|
||||
@ -45,6 +46,8 @@ const Message = createClass({
|
||||
serviceContainer: PropTypes.shape({
|
||||
emitNewMessage: PropTypes.func.isRequired,
|
||||
onViewSourceInDebugger: PropTypes.func.isRequired,
|
||||
onViewSourceInScratchpad: PropTypes.func.isRequired,
|
||||
onViewSourceInStyleEditor: PropTypes.func.isRequired,
|
||||
sourceMapService: PropTypes.any,
|
||||
}),
|
||||
},
|
||||
@ -112,7 +115,8 @@ const Message = createClass({
|
||||
} else if (stacktrace) {
|
||||
const child = open ? StackTrace({
|
||||
stacktrace: stacktrace,
|
||||
onViewSourceInDebugger: serviceContainer.onViewSourceInDebugger
|
||||
onViewSourceInDebugger: serviceContainer.onViewSourceInDebugger,
|
||||
onViewSourceInScratchpad: serviceContainer.onViewSourceInScratchpad,
|
||||
}) : null;
|
||||
attachment = dom.div({ className: "stacktrace devtools-monospace" }, child);
|
||||
}
|
||||
@ -135,11 +139,24 @@ const Message = createClass({
|
||||
|
||||
const repeat = this.props.repeat ? MessageRepeat({repeat: this.props.repeat}) : null;
|
||||
|
||||
let onFrameClick;
|
||||
if (serviceContainer && frame) {
|
||||
if (source === MESSAGE_SOURCE.CSS) {
|
||||
onFrameClick = serviceContainer.onViewSourceInStyleEditor;
|
||||
} else if (/^Scratchpad\/\d+$/.test(frame.source)) {
|
||||
onFrameClick = serviceContainer.onViewSourceInScratchpad;
|
||||
} else {
|
||||
// Point everything else to debugger, if source not available,
|
||||
// it will fall back to view-source.
|
||||
onFrameClick = serviceContainer.onViewSourceInDebugger;
|
||||
}
|
||||
}
|
||||
|
||||
// Configure the location.
|
||||
const location = dom.span({ className: "message-location devtools-monospace" },
|
||||
frame ? FrameView({
|
||||
frame,
|
||||
onClick: serviceContainer ? serviceContainer.onViewSourceInDebugger : undefined,
|
||||
onClick: onFrameClick,
|
||||
showEmptyPathAsHost: true,
|
||||
sourceMapService: serviceContainer ? serviceContainer.sourceMapService : undefined
|
||||
}) : null
|
||||
|
@ -44,7 +44,21 @@ NewConsoleOutputWrapper.prototype = {
|
||||
}]));
|
||||
},
|
||||
hudProxyClient: this.jsterm.hud.proxy.client,
|
||||
onViewSourceInDebugger: frame => this.toolbox.viewSourceInDebugger.call(
|
||||
onViewSourceInDebugger: frame => {
|
||||
this.toolbox.viewSourceInDebugger.call(
|
||||
this.toolbox,
|
||||
frame.url,
|
||||
frame.line
|
||||
).then(() =>
|
||||
this.jsterm.hud.emit("source-in-debugger-opened")
|
||||
);
|
||||
},
|
||||
onViewSourceInScratchpad: frame => this.toolbox.viewSourceInScratchpad.call(
|
||||
this.toolbox,
|
||||
frame.url,
|
||||
frame.line
|
||||
),
|
||||
onViewSourceInStyleEditor: frame => this.toolbox.viewSourceInStyleEditor.call(
|
||||
this.toolbox,
|
||||
frame.url,
|
||||
frame.line
|
||||
|
@ -8,6 +8,8 @@ module.exports = {
|
||||
emitNewMessage: () => {},
|
||||
hudProxyClient: {},
|
||||
onViewSourceInDebugger: () => {},
|
||||
onViewSourceInStyleEditor: () => {},
|
||||
onViewSourceInScratchpad: () => {},
|
||||
openNetworkPanel: () => {},
|
||||
sourceMapService: {
|
||||
subscribe: () => {},
|
||||
|
@ -8,6 +8,13 @@ support-files =
|
||||
test-console-filters.html
|
||||
test-console-group.html
|
||||
test-console-table.html
|
||||
test-location-debugger-link-console-log.js
|
||||
test-location-debugger-link-errors.js
|
||||
test-location-debugger-link.html
|
||||
test-location-styleeditor-link-1.css
|
||||
test-location-styleeditor-link-2.css
|
||||
test-location-styleeditor-link.html
|
||||
test-stacktrace-location-debugger-link.html
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
|
||||
[browser_webconsole_batching.js]
|
||||
@ -17,7 +24,12 @@ support-files =
|
||||
[browser_webconsole_init.js]
|
||||
[browser_webconsole_input_focus.js]
|
||||
[browser_webconsole_keyboard_accessibility.js]
|
||||
[browser_webconsole_location_debugger_link.js]
|
||||
[browser_webconsole_location_scratchpad_link.js]
|
||||
[browser_webconsole_location_styleeditor_link.js]
|
||||
[browser_webconsole_nodes_highlight.js]
|
||||
[browser_webconsole_observer_notifications.js]
|
||||
[browser_webconsole_stacktrace_location_debugger_link.js]
|
||||
[browser_webconsole_stacktrace_location_scratchpad_link.js]
|
||||
[browser_webconsole_timestamps.js]
|
||||
[browser_webconsole_vview_close_on_esc_key.js]
|
||||
|
@ -0,0 +1,74 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that message source links for js errors and console API calls open in
|
||||
// the jsdebugger when clicked.
|
||||
|
||||
"use strict";
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"new-console-output/test/mochitest/test-location-debugger-link.html";
|
||||
|
||||
add_task(function* () {
|
||||
// Force the new debugger UI, in case this gets uplifted with the old
|
||||
// debugger still turned on
|
||||
yield pushPref("devtools.debugger.new-debugger-frontend", true);
|
||||
yield pushPref("devtools.webconsole.filter.error", true);
|
||||
yield pushPref("devtools.webconsole.filter.log", true);
|
||||
|
||||
// On e10s, the exception thrown in test-location-debugger-link-errors.js
|
||||
// is triggered in child process and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
let hud = yield openNewTabAndConsole(TEST_URI);
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
|
||||
yield testOpenInDebugger(hud, toolbox, "document.bar");
|
||||
|
||||
info("Selecting the console again");
|
||||
yield toolbox.selectTool("webconsole");
|
||||
yield testOpenInDebugger(hud, toolbox, "Blah Blah");
|
||||
|
||||
// // check again the first node.
|
||||
info("Selecting the console again");
|
||||
yield toolbox.selectTool("webconsole");
|
||||
yield testOpenInDebugger(hud, toolbox, "document.bar");
|
||||
});
|
||||
|
||||
function* testOpenInDebugger(hud, toolbox, text) {
|
||||
info(`Testing message with text "${text}"`);
|
||||
let messageNode = yield waitFor(() => findMessage(hud, text));
|
||||
let frameLinkNode = messageNode.querySelector(".message-location .frame-link");
|
||||
ok(frameLinkNode, "The message does have a location link");
|
||||
yield checkClickOnNode(hud, toolbox, frameLinkNode);
|
||||
}
|
||||
|
||||
function* checkClickOnNode(hud, toolbox, frameLinkNode) {
|
||||
info("checking click on node location");
|
||||
|
||||
let url = frameLinkNode.getAttribute("data-url");
|
||||
ok(url, `source url found ("${url}")`);
|
||||
|
||||
let line = frameLinkNode.getAttribute("data-line");
|
||||
ok(line, `source line found ("${line}")`);
|
||||
|
||||
let onSourceInDebuggerOpened = once(hud.ui, "source-in-debugger-opened");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
frameLinkNode.querySelector(".frame-link-filename"));
|
||||
|
||||
yield onSourceInDebuggerOpened;
|
||||
|
||||
let dbg = toolbox.getPanel("jsdebugger");
|
||||
is(
|
||||
dbg._selectors().getSelectedSource(dbg._getState()).get("url"),
|
||||
url,
|
||||
"expected source url"
|
||||
);
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>test Scratchpad panel linking</p>";
|
||||
|
||||
add_task(function* () {
|
||||
yield pushPref("devtools.scratchpad.enabled", true);
|
||||
yield openNewTabAndToolbox(TEST_URI);
|
||||
|
||||
info("Opening toolbox with Scratchpad panel");
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = yield gDevTools.showToolbox(target, "scratchpad", "window");
|
||||
|
||||
let scratchpadPanel = toolbox.getPanel("scratchpad");
|
||||
let { scratchpad } = scratchpadPanel;
|
||||
is(toolbox.getCurrentPanel(), scratchpadPanel,
|
||||
"Scratchpad is currently selected panel");
|
||||
|
||||
info("Switching to webconsole panel");
|
||||
|
||||
let webconsolePanel = yield toolbox.selectTool("webconsole");
|
||||
let { hud } = webconsolePanel;
|
||||
is(toolbox.getCurrentPanel(), webconsolePanel,
|
||||
"Webconsole is currently selected panel");
|
||||
|
||||
info("console.log()ing from Scratchpad");
|
||||
|
||||
let messageText = "foobar-from-scratchpad";
|
||||
scratchpad.setText(`console.log('${messageText}')`);
|
||||
scratchpad.run();
|
||||
let message = yield waitFor(() => findMessage(hud, messageText));
|
||||
|
||||
info("Clicking link to switch to and focus Scratchpad");
|
||||
|
||||
ok(message, "Found logged message from Scratchpad");
|
||||
let anchor = message.querySelector(".message-location .frame-link-filename");
|
||||
|
||||
let onScratchpadSelected = new Promise((resolve) => {
|
||||
toolbox.once("scratchpad-selected", resolve);
|
||||
});
|
||||
|
||||
EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow);
|
||||
yield onScratchpadSelected;
|
||||
|
||||
is(toolbox.getCurrentPanel(), scratchpadPanel,
|
||||
"Clicking link switches to Scratchpad panel");
|
||||
|
||||
is(Services.ww.activeWindow, toolbox.win.parent,
|
||||
"Scratchpad's toolbox is focused");
|
||||
});
|
@ -0,0 +1,86 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield pushPref("devtools.webconsole.filter.css", true);
|
||||
let hud = yield openNewTabAndConsole(TEST_URI);
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
|
||||
yield testViewSource(hud, toolbox, "\u2018font-weight\u2019");
|
||||
|
||||
info("Selecting the console again");
|
||||
yield toolbox.selectTool("webconsole");
|
||||
yield testViewSource(hud, toolbox, "\u2018color\u2019");
|
||||
});
|
||||
|
||||
function* testViewSource(hud, toolbox, text) {
|
||||
info(`Testing message with text "${text}"`);
|
||||
let messageNode = yield waitFor(() => findMessage(hud, text));
|
||||
let frameLinkNode = messageNode.querySelector(".message-location .frame-link");
|
||||
ok(frameLinkNode, "The message does have a location link");
|
||||
|
||||
let onStyleEditorSelected = new Promise((resolve) => {
|
||||
toolbox.once("styleeditor-selected", (event, panel) => {
|
||||
resolve(panel);
|
||||
});
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
messageNode.querySelector(".frame-link-filename"));
|
||||
|
||||
let panel = yield onStyleEditorSelected;
|
||||
ok(true, "The style editor is selected when clicking on the location element");
|
||||
|
||||
yield onStyleEditorReady(panel);
|
||||
|
||||
info("style editor window focused");
|
||||
let href = frameLinkNode.getAttribute("data-url");
|
||||
let line = frameLinkNode.getAttribute("data-line");
|
||||
ok(line, "found source line");
|
||||
|
||||
let editor = getEditorForHref(panel.UI, href);
|
||||
ok(editor, "found style editor for " + href);
|
||||
yield performLineCheck(panel.UI, editor, line - 1);
|
||||
}
|
||||
|
||||
function* onStyleEditorReady(panel) {
|
||||
let win = panel.panelWindow;
|
||||
ok(win, "Style Editor Window is defined");
|
||||
ok(panel.UI, "Style Editor UI is defined");
|
||||
|
||||
info("Waiting the style editor to be focused");
|
||||
return new Promise(resolve => {
|
||||
waitForFocus(function () {
|
||||
resolve();
|
||||
}, win);
|
||||
});
|
||||
}
|
||||
|
||||
function getEditorForHref(styleEditorUI, href) {
|
||||
let foundEditor = null;
|
||||
for (let editor of styleEditorUI.editors) {
|
||||
if (editor.styleSheet.href == href) {
|
||||
foundEditor = editor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return foundEditor;
|
||||
}
|
||||
|
||||
function* performLineCheck(styleEditorUI, editor, line) {
|
||||
info("wait for source editor to load");
|
||||
// Get out of the styleeditor-selected event loop.
|
||||
yield waitForTick();
|
||||
|
||||
is(editor.sourceEditor.getCursor().line, line,
|
||||
"correct line is selected");
|
||||
is(styleEditorUI.selectedStyleSheetIndex, editor.styleSheet.styleSheetIndex,
|
||||
"correct stylesheet is selected in the editor");
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that message source links for js errors and console API calls open in
|
||||
// the jsdebugger when clicked.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"new-console-output/test/mochitest/test-stacktrace-location-debugger-link.html";
|
||||
|
||||
add_task(function* () {
|
||||
// Force the new debugger UI, in case this gets uplifted with the old
|
||||
// debugger still turned on
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true);
|
||||
Services.prefs.setBoolPref("devtools.webconsole.filter.log", true);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
Services.prefs.clearUserPref("devtools.webconsole.filter.log");
|
||||
});
|
||||
|
||||
let hud = yield openNewTabAndConsole(TEST_URI);
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
|
||||
yield testOpenInDebugger(hud, toolbox, "console.trace()");
|
||||
});
|
||||
|
||||
function* testOpenInDebugger(hud, toolbox, text) {
|
||||
info(`Testing message with text "${text}"`);
|
||||
let messageNode = yield waitFor(() => findMessage(hud, text));
|
||||
let frameLinksNode = messageNode.querySelectorAll(".stack-trace .frame-link");
|
||||
is(frameLinksNode.length, 3,
|
||||
"The message does have the expected number of frames in the stacktrace");
|
||||
|
||||
for (let frameLinkNode of frameLinksNode) {
|
||||
yield checkClickOnNode(hud, toolbox, frameLinkNode);
|
||||
|
||||
info("Selecting the console again");
|
||||
yield toolbox.selectTool("webconsole");
|
||||
}
|
||||
}
|
||||
|
||||
function* checkClickOnNode(hud, toolbox, frameLinkNode) {
|
||||
info("checking click on node location");
|
||||
|
||||
let onSourceInDebuggerOpened = once(hud.ui, "source-in-debugger-opened");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
frameLinkNode.querySelector(".frame-link-source"));
|
||||
|
||||
yield onSourceInDebuggerOpened;
|
||||
|
||||
let url = frameLinkNode.getAttribute("data-url");
|
||||
let dbg = toolbox.getPanel("jsdebugger");
|
||||
is(
|
||||
dbg._selectors().getSelectedSource(dbg._getState()).get("url"),
|
||||
url,
|
||||
`Debugger is opened at expected source url (${url})`
|
||||
);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>test stacktrace scratchpad linking</p>";
|
||||
|
||||
add_task(function* () {
|
||||
yield pushPref("devtools.scratchpad.enabled", true);
|
||||
yield openNewTabAndToolbox(TEST_URI);
|
||||
|
||||
info("Opening toolbox with Scratchpad panel");
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = yield gDevTools.showToolbox(target, "scratchpad", "window");
|
||||
|
||||
let scratchpadPanel = toolbox.getPanel("scratchpad");
|
||||
let { scratchpad } = scratchpadPanel;
|
||||
is(toolbox.getCurrentPanel(), scratchpadPanel,
|
||||
"Scratchpad is currently selected panel");
|
||||
|
||||
info("Switching to webconsole panel");
|
||||
|
||||
let webconsolePanel = yield toolbox.selectTool("webconsole");
|
||||
let { hud } = webconsolePanel;
|
||||
is(toolbox.getCurrentPanel(), webconsolePanel,
|
||||
"Webconsole is currently selected panel");
|
||||
|
||||
info("console.trace()ing from Scratchpad");
|
||||
|
||||
scratchpad.setText(`
|
||||
function foo() {
|
||||
bar();
|
||||
}
|
||||
|
||||
function bar() {
|
||||
console.trace();
|
||||
}
|
||||
|
||||
foo();
|
||||
`);
|
||||
scratchpad.run();
|
||||
let message = yield waitFor(() => findMessage(hud, "console.trace()"));
|
||||
|
||||
info("Clicking link to switch to and focus Scratchpad");
|
||||
|
||||
ok(message, "Found console.trace message from Scratchpad");
|
||||
let anchor = message.querySelector(".stack-trace .frame-link .frame-link-filename");
|
||||
|
||||
let onScratchpadSelected = toolbox.once("scratchpad-selected");
|
||||
|
||||
EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow);
|
||||
yield onScratchpadSelected;
|
||||
|
||||
is(toolbox.getCurrentPanel(), scratchpadPanel,
|
||||
"Clicking link in stacktrace switches to Scratchpad panel");
|
||||
|
||||
is(Services.ww.activeWindow, toolbox.win.parent,
|
||||
"Scratchpad's toolbox is focused");
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
function onLoad123() {
|
||||
console.log("Blah Blah");
|
||||
}
|
||||
|
||||
window.addEventListener("load", onLoad123, false);
|
@ -0,0 +1,10 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
window.addEventListener("load", function () {
|
||||
document.bar();
|
||||
}, false);
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Web Console test for opening JS/Console call Links in Debugger</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript" src="test-location-debugger-link-errors.js"></script>
|
||||
<script type="text/javascript" src="test-location-debugger-link-console-log.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Web Console test for opening JS/Console call Links in Debugger.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
body {
|
||||
color: #0f0;
|
||||
font-weight: green;
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
body {
|
||||
color: #0fl;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Web Console test for opening CSS Links in Style Editor</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<link rel="stylesheet" href="test-location-styleeditor-link-1.css">
|
||||
<link rel="stylesheet" href="test-location-styleeditor-link-2.css">
|
||||
</head>
|
||||
<body>
|
||||
<p>Web Console test for opening CSS Links in Style Editor.</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Web Console test for opening console call stacktrace links in Debugger</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
</head>
|
||||
<body>
|
||||
<p>Web Console test for opening console call stacktrace links in Debugger.</p>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
function foo() {
|
||||
bar();
|
||||
}
|
||||
|
||||
function bar() {
|
||||
console.trace();
|
||||
}
|
||||
|
||||
foo();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -68,17 +68,12 @@ function generateCssProperties() {
|
||||
|
||||
let subproperties = DOMUtils.getSubpropertiesForCSSProperty(name);
|
||||
|
||||
// In order to maintain any backwards compatible changes when debugging older
|
||||
// clients, take the definition from the static CSS properties database, and fill it
|
||||
// in with the most recent property definition from the server.
|
||||
const clientDefinition = CSS_PROPERTIES[name] || {};
|
||||
const serverDefinition = {
|
||||
properties[name] = {
|
||||
isInherited: DOMUtils.isInheritedProperty(name),
|
||||
values,
|
||||
supports,
|
||||
subproperties,
|
||||
};
|
||||
properties[name] = Object.assign(clientDefinition, serverDefinition);
|
||||
});
|
||||
|
||||
return properties;
|
||||
|
@ -30,8 +30,7 @@ support-files =
|
||||
[test_css-logic.html]
|
||||
[test_css-logic-media-queries.html]
|
||||
[test_css-logic-specificity.html]
|
||||
[test_css-properties_01.html]
|
||||
[test_css-properties_02.html]
|
||||
[test_css-properties.html]
|
||||
[test_Debugger.Source.prototype.introductionScript.html]
|
||||
[test_Debugger.Source.prototype.introductionType.html]
|
||||
[test_Debugger.Source.prototype.element.html]
|
||||
|
@ -1,86 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Bug 1265798 - Replace inIDOMUtils.cssPropertyIsShorthand
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test CSS Properties Actor</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = function() {
|
||||
const { initCssProperties, getCssProperties } =
|
||||
require("devtools/shared/fronts/css-properties");
|
||||
|
||||
const { CSS_PROPERTIES_DB } = require("devtools/shared/css/properties-db");
|
||||
|
||||
function promiseAttachUrl (url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
attachURL(url, function(err, client, tab, doc) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve({client, tab, doc});
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
addAsyncTest(function* setup() {
|
||||
let url = document.getElementById("cssProperties").href;
|
||||
|
||||
let attachmentA = yield promiseAttachUrl(url);
|
||||
let attachmentB = yield promiseAttachUrl(url);
|
||||
let attachmentC = yield promiseAttachUrl(url);
|
||||
|
||||
const toolboxMatchingVersions = {
|
||||
target: {
|
||||
hasActor: () => true,
|
||||
client: attachmentA.client,
|
||||
form: attachmentA.tab,
|
||||
},
|
||||
win: window
|
||||
};
|
||||
const toolboxDifferentVersions = {
|
||||
target: {
|
||||
hasActor: () => true,
|
||||
client: attachmentB.client,
|
||||
form: attachmentB.tab
|
||||
},
|
||||
win: { navigator: { userAgent:
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 " +
|
||||
"Firefox/30.0" }}
|
||||
};
|
||||
|
||||
// Modify a property on the static database, to differentiate between a generated
|
||||
// and static CSS properties database.
|
||||
CSS_PROPERTIES_DB.properties.color.isStatic = true;
|
||||
|
||||
yield initCssProperties(toolboxMatchingVersions);
|
||||
yield initCssProperties(toolboxDifferentVersions);
|
||||
|
||||
const cssPropertiesMatching = getCssProperties(toolboxMatchingVersions);
|
||||
const cssPropertiesDifferent = getCssProperties(toolboxDifferentVersions);
|
||||
|
||||
is(cssPropertiesMatching.properties.color.isStatic, true,
|
||||
"The static CSS database is used when the client and platform versions match.");
|
||||
isnot(cssPropertiesDifferent.properties.color.isStatic, undefined,
|
||||
"The generated CSS database is used when the client and platform versions do " +
|
||||
"not match, but the client is a Firefox.");
|
||||
|
||||
delete CSS_PROPERTIES_DB.properties.color.isStatic;
|
||||
|
||||
runNextTest();
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runNextTest();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265798">Mozilla Bug 1265798</a>
|
||||
<a id="cssProperties" target="_blank" href="inspector_css-properties.html">Test Document</a>
|
||||
</body>
|
||||
</html>
|
@ -13,6 +13,7 @@ import os
|
||||
import sys
|
||||
import string
|
||||
import subprocess
|
||||
from mozbuild import shellutil
|
||||
from mozbuild.base import (
|
||||
MozbuildObject,
|
||||
MachCommandBase,
|
||||
@ -39,12 +40,46 @@ class MachCommands(MachCommandBase):
|
||||
"""Generate the static css properties database for devtools and write it to file."""
|
||||
|
||||
print("Re-generating the css properties database...")
|
||||
preferences = self.get_preferences()
|
||||
db = self.get_properties_db_from_xpcshell()
|
||||
|
||||
self.output_template({
|
||||
'preferences': stringify(preferences),
|
||||
'cssProperties': stringify(db['cssProperties']),
|
||||
'pseudoElements': stringify(db['pseudoElements'])})
|
||||
|
||||
def get_preferences(self):
|
||||
"""Get all of the preferences associated with enabling and disabling a property."""
|
||||
# Build the command to run the preprocessor on PythonCSSProps.h
|
||||
headerPath = resolve_path(self.topsrcdir, 'layout/style/PythonCSSProps.h')
|
||||
|
||||
cpp = self.substs['CPP']
|
||||
|
||||
if not cpp:
|
||||
print("Unable to find the cpp program. Please do a full, nonartifact")
|
||||
print("build and try this again.")
|
||||
sys.exit(1)
|
||||
|
||||
if type(cpp) is list:
|
||||
cmd = cpp
|
||||
else:
|
||||
cmd = shellutil.split(cpp)
|
||||
cmd += shellutil.split(self.substs['ACDEFINES'])
|
||||
cmd.append(headerPath)
|
||||
|
||||
# The preprocessed list takes the following form:
|
||||
# [ (name, prop, id, flags, pref, proptype), ... ]
|
||||
preprocessed = eval(subprocess.check_output(cmd))
|
||||
|
||||
# Map this list
|
||||
# (name, prop, id, flags, pref, proptype) => (name, pref)
|
||||
preferences = [
|
||||
(name, pref)
|
||||
for name, prop, id, flags, pref, proptype in preprocessed
|
||||
if 'CSS_PROPERTY_INTERNAL' not in flags and pref]
|
||||
|
||||
return preferences
|
||||
|
||||
def get_properties_db_from_xpcshell(self):
|
||||
"""Generate the static css properties db for devtools from an xpcshell script."""
|
||||
build = MozbuildObject.from_environment()
|
||||
|
@ -2222,12 +2222,14 @@ exports.CSS_PROPERTIES = {
|
||||
"border-box",
|
||||
"content-box",
|
||||
"exclude",
|
||||
"fill-box",
|
||||
"inherit",
|
||||
"initial",
|
||||
"intersect",
|
||||
"linear-gradient",
|
||||
"luminance",
|
||||
"match-source",
|
||||
"no-clip",
|
||||
"no-repeat",
|
||||
"none",
|
||||
"padding-box",
|
||||
@ -2239,9 +2241,11 @@ exports.CSS_PROPERTIES = {
|
||||
"repeating-radial-gradient",
|
||||
"round",
|
||||
"space",
|
||||
"stroke-box",
|
||||
"subtract",
|
||||
"unset",
|
||||
"url"
|
||||
"url",
|
||||
"view-box"
|
||||
]
|
||||
},
|
||||
"-webkit-mask-clip": {
|
||||
@ -2253,10 +2257,14 @@ exports.CSS_PROPERTIES = {
|
||||
"values": [
|
||||
"border-box",
|
||||
"content-box",
|
||||
"fill-box",
|
||||
"inherit",
|
||||
"initial",
|
||||
"no-clip",
|
||||
"padding-box",
|
||||
"unset"
|
||||
"stroke-box",
|
||||
"unset",
|
||||
"view-box"
|
||||
]
|
||||
},
|
||||
"-webkit-mask-composite": {
|
||||
@ -2312,10 +2320,13 @@ exports.CSS_PROPERTIES = {
|
||||
"values": [
|
||||
"border-box",
|
||||
"content-box",
|
||||
"fill-box",
|
||||
"inherit",
|
||||
"initial",
|
||||
"padding-box",
|
||||
"unset"
|
||||
"stroke-box",
|
||||
"unset",
|
||||
"view-box"
|
||||
]
|
||||
},
|
||||
"-webkit-mask-position": {
|
||||
@ -3257,6 +3268,7 @@ exports.CSS_PROPERTIES = {
|
||||
"flex",
|
||||
"flex-end",
|
||||
"flex-start",
|
||||
"flow-root",
|
||||
"forwards",
|
||||
"full-width",
|
||||
"geometricprecision",
|
||||
@ -3338,6 +3350,7 @@ exports.CSS_PROPERTIES = {
|
||||
"mixed",
|
||||
"multiply",
|
||||
"no-change",
|
||||
"no-clip",
|
||||
"no-drag",
|
||||
"no-repeat",
|
||||
"non-scaling-stroke",
|
||||
@ -3472,6 +3485,7 @@ exports.CSS_PROPERTIES = {
|
||||
"stretch",
|
||||
"stretch-to-fit",
|
||||
"stroke",
|
||||
"stroke-box",
|
||||
"sub",
|
||||
"subtract",
|
||||
"super",
|
||||
@ -5681,6 +5695,7 @@ exports.CSS_PROPERTIES = {
|
||||
"block",
|
||||
"contents",
|
||||
"flex",
|
||||
"flow-root",
|
||||
"grid",
|
||||
"inherit",
|
||||
"initial",
|
||||
@ -7189,12 +7204,14 @@ exports.CSS_PROPERTIES = {
|
||||
"border-box",
|
||||
"content-box",
|
||||
"exclude",
|
||||
"fill-box",
|
||||
"inherit",
|
||||
"initial",
|
||||
"intersect",
|
||||
"linear-gradient",
|
||||
"luminance",
|
||||
"match-source",
|
||||
"no-clip",
|
||||
"no-repeat",
|
||||
"none",
|
||||
"padding-box",
|
||||
@ -7206,9 +7223,11 @@ exports.CSS_PROPERTIES = {
|
||||
"repeating-radial-gradient",
|
||||
"round",
|
||||
"space",
|
||||
"stroke-box",
|
||||
"subtract",
|
||||
"unset",
|
||||
"url"
|
||||
"url",
|
||||
"view-box"
|
||||
]
|
||||
},
|
||||
"mask-clip": {
|
||||
@ -7220,10 +7239,14 @@ exports.CSS_PROPERTIES = {
|
||||
"values": [
|
||||
"border-box",
|
||||
"content-box",
|
||||
"fill-box",
|
||||
"inherit",
|
||||
"initial",
|
||||
"no-clip",
|
||||
"padding-box",
|
||||
"unset"
|
||||
"stroke-box",
|
||||
"unset",
|
||||
"view-box"
|
||||
]
|
||||
},
|
||||
"mask-composite": {
|
||||
@ -7294,10 +7317,13 @@ exports.CSS_PROPERTIES = {
|
||||
"values": [
|
||||
"border-box",
|
||||
"content-box",
|
||||
"fill-box",
|
||||
"inherit",
|
||||
"initial",
|
||||
"padding-box",
|
||||
"unset"
|
||||
"stroke-box",
|
||||
"unset",
|
||||
"view-box"
|
||||
]
|
||||
},
|
||||
"mask-position": {
|
||||
@ -9377,3 +9403,550 @@ exports.PSEUDO_ELEMENTS = [
|
||||
":placeholder",
|
||||
":-moz-color-swatch"
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the preferences keys for whether a CSS property is enabled or not. This is
|
||||
* exposed for testing purposes.
|
||||
*/
|
||||
exports.PREFERENCES = [
|
||||
[
|
||||
"all",
|
||||
"layout.css.all-shorthand.enabled"
|
||||
],
|
||||
[
|
||||
"background-blend-mode",
|
||||
"layout.css.background-blend-mode.enabled"
|
||||
],
|
||||
[
|
||||
"box-decoration-break",
|
||||
"layout.css.box-decoration-break.enabled"
|
||||
],
|
||||
[
|
||||
"color-adjust",
|
||||
"layout.css.color-adjust.enabled"
|
||||
],
|
||||
[
|
||||
"contain",
|
||||
"layout.css.contain.enabled"
|
||||
],
|
||||
[
|
||||
"font-variation-settings",
|
||||
"layout.css.font-variations.enabled"
|
||||
],
|
||||
[
|
||||
"grid",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-area",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-auto-columns",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-auto-flow",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-auto-rows",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-column",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-column-end",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-column-gap",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-column-start",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-gap",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-row",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-row-end",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-row-gap",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-row-start",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-template",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-template-areas",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-template-columns",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"grid-template-rows",
|
||||
"layout.css.grid.enabled"
|
||||
],
|
||||
[
|
||||
"initial-letter",
|
||||
"layout.css.initial-letter.enabled"
|
||||
],
|
||||
[
|
||||
"image-orientation",
|
||||
"layout.css.image-orientation.enabled"
|
||||
],
|
||||
[
|
||||
"isolation",
|
||||
"layout.css.isolation.enabled"
|
||||
],
|
||||
[
|
||||
"mix-blend-mode",
|
||||
"layout.css.mix-blend-mode.enabled"
|
||||
],
|
||||
[
|
||||
"object-fit",
|
||||
"layout.css.object-fit-and-position.enabled"
|
||||
],
|
||||
[
|
||||
"object-position",
|
||||
"layout.css.object-fit-and-position.enabled"
|
||||
],
|
||||
[
|
||||
"-moz-osx-font-smoothing",
|
||||
"layout.css.osx-font-smoothing.enabled"
|
||||
],
|
||||
[
|
||||
"overflow-clip-box",
|
||||
"layout.css.overflow-clip-box.enabled"
|
||||
],
|
||||
[
|
||||
"paint-order",
|
||||
"svg.paint-order.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-behavior",
|
||||
"layout.css.scroll-behavior.property-enabled"
|
||||
],
|
||||
[
|
||||
"scroll-snap-coordinate",
|
||||
"layout.css.scroll-snap.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-snap-destination",
|
||||
"layout.css.scroll-snap.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-snap-points-x",
|
||||
"layout.css.scroll-snap.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-snap-points-y",
|
||||
"layout.css.scroll-snap.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-snap-type",
|
||||
"layout.css.scroll-snap.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-snap-type-x",
|
||||
"layout.css.scroll-snap.enabled"
|
||||
],
|
||||
[
|
||||
"scroll-snap-type-y",
|
||||
"layout.css.scroll-snap.enabled"
|
||||
],
|
||||
[
|
||||
"shape-outside",
|
||||
"layout.css.shape-outside.enabled"
|
||||
],
|
||||
[
|
||||
"text-combine-upright",
|
||||
"layout.css.text-combine-upright.enabled"
|
||||
],
|
||||
[
|
||||
"-webkit-text-fill-color",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-text-stroke",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-text-stroke-color",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-text-stroke-width",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"touch-action",
|
||||
"layout.css.touch_action.enabled"
|
||||
],
|
||||
[
|
||||
"-moz-transform",
|
||||
"layout.css.prefixes.transforms"
|
||||
],
|
||||
[
|
||||
"transform-box",
|
||||
"svg.transform-box.enabled"
|
||||
],
|
||||
[
|
||||
"-moz-transform-origin",
|
||||
"layout.css.prefixes.transforms"
|
||||
],
|
||||
[
|
||||
"-moz-perspective-origin",
|
||||
"layout.css.prefixes.transforms"
|
||||
],
|
||||
[
|
||||
"-moz-perspective",
|
||||
"layout.css.prefixes.transforms"
|
||||
],
|
||||
[
|
||||
"-moz-transform-style",
|
||||
"layout.css.prefixes.transforms"
|
||||
],
|
||||
[
|
||||
"-moz-backface-visibility",
|
||||
"layout.css.prefixes.transforms"
|
||||
],
|
||||
[
|
||||
"-moz-border-image",
|
||||
"layout.css.prefixes.border-image"
|
||||
],
|
||||
[
|
||||
"-moz-transition",
|
||||
"layout.css.prefixes.transitions"
|
||||
],
|
||||
[
|
||||
"-moz-transition-delay",
|
||||
"layout.css.prefixes.transitions"
|
||||
],
|
||||
[
|
||||
"-moz-transition-duration",
|
||||
"layout.css.prefixes.transitions"
|
||||
],
|
||||
[
|
||||
"-moz-transition-property",
|
||||
"layout.css.prefixes.transitions"
|
||||
],
|
||||
[
|
||||
"-moz-transition-timing-function",
|
||||
"layout.css.prefixes.transitions"
|
||||
],
|
||||
[
|
||||
"-moz-animation",
|
||||
"layout.css.prefixes.animations"
|
||||
],
|
||||
[
|
||||
"-moz-animation-delay",
|
||||
"layout.css.prefixes.animations"
|
||||
],
|
||||
[
|
||||
"-moz-animation-direction",
|
||||
"layout.css.prefixes.animations"
|
||||
],
|
||||
[
|
||||
"-moz-animation-duration",
|
||||
"layout.css.prefixes.animations"
|
||||
],
|
||||
[
|
||||
"-moz-animation-fill-mode",
|
||||
"layout.css.prefixes.animations"
|
||||
],
|
||||
[
|
||||
"-moz-animation-iteration-count",
|
||||
"layout.css.prefixes.animations"
|
||||
],
|
||||
[
|
||||
"-moz-animation-name",
|
||||
"layout.css.prefixes.animations"
|
||||
],
|
||||
[
|
||||
"-moz-animation-play-state",
|
||||
"layout.css.prefixes.animations"
|
||||
],
|
||||
[
|
||||
"-moz-animation-timing-function",
|
||||
"layout.css.prefixes.animations"
|
||||
],
|
||||
[
|
||||
"-moz-box-sizing",
|
||||
"layout.css.prefixes.box-sizing"
|
||||
],
|
||||
[
|
||||
"-moz-font-feature-settings",
|
||||
"layout.css.prefixes.font-features"
|
||||
],
|
||||
[
|
||||
"-moz-font-language-override",
|
||||
"layout.css.prefixes.font-features"
|
||||
],
|
||||
[
|
||||
"-webkit-animation",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-animation-delay",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-animation-direction",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-animation-duration",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-animation-fill-mode",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-animation-iteration-count",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-animation-name",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-animation-play-state",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-animation-timing-function",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-filter",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-text-size-adjust",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-transform",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-transform-origin",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-transform-style",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-backface-visibility",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-perspective",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-perspective-origin",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-transition",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-transition-delay",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-transition-duration",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-transition-property",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-transition-timing-function",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-border-radius",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-border-top-left-radius",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-border-top-right-radius",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-border-bottom-left-radius",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-border-bottom-right-radius",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-background-clip",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-background-origin",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-background-size",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-border-image",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-box-shadow",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-box-sizing",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-box-flex",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-box-ordinal-group",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-box-orient",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-box-direction",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-box-align",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-box-pack",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-flex-direction",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-flex-wrap",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-flex-flow",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-order",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-flex",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-flex-grow",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-flex-shrink",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-flex-basis",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-justify-content",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-align-items",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-align-self",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-align-content",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-user-select",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask-clip",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask-composite",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask-image",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask-origin",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask-position",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask-position-x",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask-position-y",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask-repeat",
|
||||
"layout.css.prefixes.webkit"
|
||||
],
|
||||
[
|
||||
"-webkit-mask-size",
|
||||
"layout.css.prefixes.webkit"
|
||||
]
|
||||
];
|
||||
|
@ -18,3 +18,9 @@ exports.CSS_PROPERTIES = ${cssProperties};
|
||||
* A list of the pseudo elements.
|
||||
*/
|
||||
exports.PSEUDO_ELEMENTS = ${pseudoElements};
|
||||
|
||||
/**
|
||||
* A list of the preferences keys for whether a CSS property is enabled or not. This is
|
||||
* exposed for testing purposes.
|
||||
*/
|
||||
exports.PREFERENCES = ${preferences};
|
||||
|
@ -234,15 +234,7 @@ const initCssProperties = Task.async(function* (toolbox) {
|
||||
// Get the list dynamically if the cssProperties actor exists.
|
||||
if (toolbox.target.hasActor("cssProperties")) {
|
||||
front = CssPropertiesFront(client, toolbox.target.form);
|
||||
const serverDB = yield front.getCSSDatabase();
|
||||
|
||||
// Ensure the database was returned in a format that is understood.
|
||||
// Older versions of the protocol could return a blank database.
|
||||
if (!serverDB.properties && !serverDB.margin) {
|
||||
db = CSS_PROPERTIES_DB;
|
||||
} else {
|
||||
db = serverDB;
|
||||
}
|
||||
db = yield front.getCSSDatabase();
|
||||
} else {
|
||||
// The target does not support this actor, so require a static list of supported
|
||||
// properties.
|
||||
@ -294,9 +286,6 @@ function normalizeCssData(db) {
|
||||
db = { properties: db };
|
||||
}
|
||||
|
||||
// Fill in any missing DB information from the static database.
|
||||
db = Object.assign({}, CSS_PROPERTIES_DB, db);
|
||||
|
||||
let missingSupports = !db.properties.color.supports;
|
||||
let missingValues = !db.properties.color.values;
|
||||
let missingSubproperties = !db.properties.background.subproperties;
|
||||
@ -320,6 +309,10 @@ function normalizeCssData(db) {
|
||||
db.properties[name].subproperties =
|
||||
CSS_PROPERTIES_DB.properties[name].subproperties;
|
||||
}
|
||||
// Add "isInherited" information to the css properties if it's missing.
|
||||
if (db.properties.font.isInherited) {
|
||||
db.properties[name].isInherited = CSS_PROPERTIES_DB.properties[name].isInherited;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,9 @@
|
||||
const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Components.interfaces.inIDOMUtils);
|
||||
|
||||
const {PSEUDO_ELEMENTS, CSS_PROPERTIES} = require("devtools/shared/css/generated/properties-db");
|
||||
const {PSEUDO_ELEMENTS, CSS_PROPERTIES, PREFERENCES} = require("devtools/shared/css/generated/properties-db");
|
||||
const {generateCssProperties} = require("devtools/server/actors/css-properties");
|
||||
const {Preferences} = require("resource://gre/modules/Preferences.jsm");
|
||||
|
||||
function run_test() {
|
||||
const propertiesErrorMessage = "If this assertion fails, then the client side CSS " +
|
||||
@ -38,7 +39,9 @@ function run_test() {
|
||||
|
||||
/**
|
||||
* Check that the platform and client match for the details on their CSS properties.
|
||||
* Enumerate each property to aid in debugging.
|
||||
* Enumerate each property to aid in debugging. Sometimes these properties don't
|
||||
* completely agree due to differences in preferences. Check the currently set
|
||||
* preference for that property to see if it's enabled.
|
||||
*/
|
||||
const platformProperties = generateCssProperties();
|
||||
|
||||
@ -47,17 +50,18 @@ function run_test() {
|
||||
const clientProperty = CSS_PROPERTIES[propertyName];
|
||||
const deepEqual = isJsonDeepEqual(platformProperty, clientProperty);
|
||||
|
||||
// The "all" property can contain information that can be turned on and off by
|
||||
// preferences. These values can be different between OSes, so ignore the equality
|
||||
// check for this property, since this is likely to fail.
|
||||
if (propertyName === "all") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (deepEqual) {
|
||||
ok(true, `The static database and platform match for "${propertyName}".`);
|
||||
} else {
|
||||
const prefMessage = `The static database and platform do not match ` +
|
||||
`for "${propertyName}".`;
|
||||
if (getPreference(propertyName) === false) {
|
||||
ok(true, `${prefMessage} However, there is a preference for disabling this ` +
|
||||
`property on the current build.`);
|
||||
} else {
|
||||
ok(false, `${prefMessage} ${propertiesErrorMessage}`);
|
||||
}
|
||||
ok(false, `The static database and platform do not match for ` + `
|
||||
"${propertyName}". ${propertiesErrorMessage}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,8 +79,14 @@ function run_test() {
|
||||
}
|
||||
|
||||
mismatches.forEach(propertyName => {
|
||||
ok(false, `The static database and platform do not agree on the property ` +
|
||||
`"${propertyName}" ${propertiesErrorMessage}`);
|
||||
if (getPreference(propertyName) === false) {
|
||||
ok(true, `The static database and platform do not agree on the property ` +
|
||||
`"${propertyName}" This is ok because it is currently disabled through ` +
|
||||
`a preference.`);
|
||||
} else {
|
||||
ok(false, `The static database and platform do not agree on the property ` +
|
||||
`"${propertyName}" ${propertiesErrorMessage}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -134,3 +144,21 @@ function getKeyMismatches(a, b) {
|
||||
|
||||
return aMismatches.concat(bMismatches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preference value of whether this property is enabled. Returns an empty string
|
||||
* if no preference exists.
|
||||
*
|
||||
* @param {String} propertyName
|
||||
* @return {Boolean|undefined}
|
||||
*/
|
||||
function getPreference(propertyName) {
|
||||
const preference = PREFERENCES.find(([prefPropertyName, preferenceKey]) => {
|
||||
return prefPropertyName === propertyName && !!preferenceKey;
|
||||
});
|
||||
|
||||
if (preference) {
|
||||
return Preferences.get(preference[1]);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
@ -1257,12 +1257,10 @@ nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden(const nsMappedAttribut
|
||||
if (value) {
|
||||
if (value->Equals(nsGkAtoms::_empty, eCaseMatters) ||
|
||||
value->Equals(nsGkAtoms::_true, eIgnoreCase)) {
|
||||
userModify->SetIntValue(StyleUserModify::ReadWrite,
|
||||
eCSSUnit_Enumerated);
|
||||
userModify->SetEnumValue(StyleUserModify::ReadWrite);
|
||||
}
|
||||
else if (value->Equals(nsGkAtoms::_false, eIgnoreCase)) {
|
||||
userModify->SetIntValue(StyleUserModify::ReadOnly,
|
||||
eCSSUnit_Enumerated);
|
||||
userModify->SetEnumValue(StyleUserModify::ReadOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1281,7 +1279,7 @@ nsGenericHTMLElement::MapCommonAttributesInto(const nsMappedAttributes* aAttribu
|
||||
nsCSSValue* display = aData->ValueForDisplay();
|
||||
if (display->GetUnit() == eCSSUnit_Null) {
|
||||
if (aAttributes->IndexOfAttr(nsGkAtoms::hidden) >= 0) {
|
||||
display->SetIntValue(StyleDisplay::None, eCSSUnit_Enumerated);
|
||||
display->SetEnumValue(StyleDisplay::None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1346,9 +1344,9 @@ nsGenericHTMLElement::MapImageAlignAttributeInto(const nsMappedAttributes* aAttr
|
||||
nsCSSValue* cssFloat = aRuleData->ValueForFloat();
|
||||
if (cssFloat->GetUnit() == eCSSUnit_Null) {
|
||||
if (align == NS_STYLE_TEXT_ALIGN_LEFT) {
|
||||
cssFloat->SetIntValue(StyleFloat::Left, eCSSUnit_Enumerated);
|
||||
cssFloat->SetEnumValue(StyleFloat::Left);
|
||||
} else if (align == NS_STYLE_TEXT_ALIGN_RIGHT) {
|
||||
cssFloat->SetIntValue(StyleFloat::Right, eCSSUnit_Enumerated);
|
||||
cssFloat->SetEnumValue(StyleFloat::Right);
|
||||
}
|
||||
}
|
||||
nsCSSValue* verticalAlign = aRuleData->ValueForVerticalAlign();
|
||||
|
@ -13,7 +13,11 @@ MediaDecoderReaderWrapper::MediaDecoderReaderWrapper(AbstractThread* aOwnerThrea
|
||||
MediaDecoderReader* aReader)
|
||||
: mOwnerThread(aOwnerThread)
|
||||
, mReader(aReader)
|
||||
{}
|
||||
{
|
||||
// Must support either heuristic buffering or WaitForData().
|
||||
MOZ_ASSERT(mReader->UseBufferingHeuristics() ||
|
||||
mReader->IsWaitForDataSupported());
|
||||
}
|
||||
|
||||
MediaDecoderReaderWrapper::~MediaDecoderReaderWrapper()
|
||||
{}
|
||||
@ -92,6 +96,7 @@ RefPtr<MediaDecoderReaderWrapper::WaitForDataPromise>
|
||||
MediaDecoderReaderWrapper::WaitForData(MediaData::Type aType)
|
||||
{
|
||||
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
||||
MOZ_ASSERT(mReader->IsWaitForDataSupported());
|
||||
return InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
|
||||
&MediaDecoderReader::WaitForData, aType);
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ public:
|
||||
void ResetDecode(TrackSet aTracks);
|
||||
|
||||
nsresult Init() { return mReader->Init(); }
|
||||
bool IsWaitForDataSupported() const { return mReader->IsWaitForDataSupported(); }
|
||||
bool IsAsync() const { return mReader->IsAsync(); }
|
||||
bool UseBufferingHeuristics() const { return mReader->UseBufferingHeuristics(); }
|
||||
|
||||
|
@ -194,7 +194,8 @@ public:
|
||||
virtual void HandleCDMProxyReady() {}
|
||||
virtual void HandleAudioDecoded(MediaData* aAudio) {}
|
||||
virtual void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) {}
|
||||
virtual void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError);
|
||||
virtual void HandleAudioNotDecoded(const MediaResult& aError);
|
||||
virtual void HandleVideoNotDecoded(const MediaResult& aError);
|
||||
virtual void HandleAudioWaited(MediaData::Type aType);
|
||||
virtual void HandleVideoWaited(MediaData::Type aType);
|
||||
virtual void HandleNotWaited(const WaitForDataRejectValue& aRejection);
|
||||
@ -236,8 +237,8 @@ protected:
|
||||
// We are expecting more data if either the resource states so, or if we
|
||||
// have a waiting promise pending (such as with non-MSE EME).
|
||||
return Resource()->IsExpectingMoreData() ||
|
||||
(Reader()->IsWaitForDataSupported() &&
|
||||
(mMaster->IsWaitingAudioData() || mMaster->IsWaitingVideoData()));
|
||||
mMaster->IsWaitingAudioData() ||
|
||||
mMaster->IsWaitingVideoData();
|
||||
}
|
||||
MediaQueue<MediaData>& AudioQueue() const { return mMaster->mAudioQueue; }
|
||||
MediaQueue<MediaData>& VideoQueue() const { return mMaster->mVideoQueue; }
|
||||
@ -496,9 +497,17 @@ public:
|
||||
MaybeFinishDecodeFirstFrame();
|
||||
}
|
||||
|
||||
void HandleEndOfStream() override
|
||||
void HandleAudioNotDecoded(const MediaResult& aError) override;
|
||||
void HandleVideoNotDecoded(const MediaResult& aError) override;
|
||||
|
||||
void HandleAudioWaited(MediaData::Type aType) override
|
||||
{
|
||||
MaybeFinishDecodeFirstFrame();
|
||||
mMaster->RequestAudioData();
|
||||
}
|
||||
|
||||
void HandleVideoWaited(MediaData::Type aType) override
|
||||
{
|
||||
mMaster->RequestVideoData(false, media::TimeUnit());
|
||||
}
|
||||
|
||||
void HandleVideoSuspendTimeout() override
|
||||
@ -800,15 +809,11 @@ public:
|
||||
}
|
||||
|
||||
void HandleAudioDecoded(MediaData* aAudio) override = 0;
|
||||
|
||||
void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override = 0;
|
||||
|
||||
void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) override = 0;
|
||||
|
||||
void HandleAudioNotDecoded(const MediaResult& aError) override = 0;
|
||||
void HandleVideoNotDecoded(const MediaResult& aError) override = 0;
|
||||
void HandleAudioWaited(MediaData::Type aType) override = 0;
|
||||
|
||||
void HandleVideoWaited(MediaData::Type aType) override = 0;
|
||||
|
||||
void HandleNotWaited(const WaitForDataRejectValue& aRejection) override = 0;
|
||||
|
||||
void HandleVideoSuspendTimeout() override
|
||||
@ -920,51 +925,8 @@ public:
|
||||
MaybeFinishSeek();
|
||||
}
|
||||
|
||||
void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) override
|
||||
{
|
||||
MOZ_ASSERT(!mDoneAudioSeeking || !mDoneVideoSeeking, "Seek shouldn't be finished");
|
||||
|
||||
// Ignore pending requests from video-only seek.
|
||||
if (aType == MediaData::AUDIO_DATA && mSeekJob.mTarget->IsVideoOnly()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the decoder is waiting for data, we tell it to call us back when the
|
||||
// data arrives.
|
||||
if (aError == NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA) {
|
||||
mMaster->WaitForData(aType);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aError == NS_ERROR_DOM_MEDIA_CANCELED) {
|
||||
if (aType == MediaData::AUDIO_DATA) {
|
||||
RequestAudioData();
|
||||
} else {
|
||||
RequestVideoData();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (aError == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
|
||||
if (aType == MediaData::AUDIO_DATA) {
|
||||
AudioQueue().Finish();
|
||||
mDoneAudioSeeking = true;
|
||||
} else {
|
||||
if (mFirstVideoFrameAfterSeek) {
|
||||
// Hit the end of stream. Move mFirstVideoFrameAfterSeek into
|
||||
// mSeekedVideoData so we have something to display after seeking.
|
||||
mMaster->PushVideo(mFirstVideoFrameAfterSeek);
|
||||
}
|
||||
VideoQueue().Finish();
|
||||
mDoneVideoSeeking = true;
|
||||
}
|
||||
MaybeFinishSeek();
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a decode error, delegate to the generic error path.
|
||||
mMaster->DecodeError(aError);
|
||||
}
|
||||
void HandleAudioNotDecoded(const MediaResult& aError) override;
|
||||
void HandleVideoNotDecoded(const MediaResult& aError) override;
|
||||
|
||||
void HandleAudioWaited(MediaData::Type aType) override
|
||||
{
|
||||
@ -1099,16 +1061,12 @@ private:
|
||||
void RequestAudioData()
|
||||
{
|
||||
MOZ_ASSERT(!mDoneAudioSeeking);
|
||||
MOZ_ASSERT(!mMaster->IsRequestingAudioData());
|
||||
MOZ_ASSERT(!mMaster->IsWaitingAudioData());
|
||||
mMaster->RequestAudioData();
|
||||
}
|
||||
|
||||
void RequestVideoData()
|
||||
{
|
||||
MOZ_ASSERT(!mDoneVideoSeeking);
|
||||
MOZ_ASSERT(!mMaster->IsRequestingVideoData());
|
||||
MOZ_ASSERT(!mMaster->IsWaitingVideoData());
|
||||
mMaster->RequestVideoData(false, media::TimeUnit());
|
||||
}
|
||||
|
||||
@ -1380,48 +1338,8 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) override
|
||||
{
|
||||
MOZ_ASSERT(!mSeekJob.mPromise.IsEmpty(), "Seek shouldn't be finished");
|
||||
MOZ_ASSERT(NeedMoreVideo());
|
||||
|
||||
switch (aType) {
|
||||
case MediaData::AUDIO_DATA:
|
||||
{
|
||||
// We don't care about audio decode errors in this state which will be
|
||||
// handled by other states after seeking.
|
||||
break;
|
||||
}
|
||||
case MediaData::VIDEO_DATA:
|
||||
{
|
||||
if (aError == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
|
||||
VideoQueue().Finish();
|
||||
FinishSeek();
|
||||
break;
|
||||
}
|
||||
|
||||
// Video seek not finished.
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
mMaster->WaitForData(MediaData::VIDEO_DATA);
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
RequestVideoData();
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
MOZ_ASSERT(false, "Shouldn't want more data for ended video.");
|
||||
break;
|
||||
default:
|
||||
// Raise an error since we can't finish video seek anyway.
|
||||
mMaster->DecodeError(aError);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("We cannot handle RAW_DATA or NULL_DATA here.");
|
||||
}
|
||||
}
|
||||
void HandleAudioNotDecoded(const MediaResult& aError) override;
|
||||
void HandleVideoNotDecoded(const MediaResult& aError) override;
|
||||
|
||||
void HandleAudioWaited(MediaData::Type aType) override
|
||||
{
|
||||
@ -1712,10 +1630,8 @@ public:
|
||||
return DECODER_STATE_SHUTDOWN;
|
||||
}
|
||||
|
||||
void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) override
|
||||
{
|
||||
return;
|
||||
}
|
||||
void HandleAudioNotDecoded(const MediaResult& aError) override {}
|
||||
void HandleVideoNotDecoded(const MediaResult& aError) override {}
|
||||
|
||||
RefPtr<MediaDecoder::SeekPromise> HandleSeek(SeekTarget aTarget) override
|
||||
{
|
||||
@ -1740,49 +1656,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
StateObject::HandleNotDecoded(MediaData::Type aType, const MediaResult& aError)
|
||||
{
|
||||
bool isAudio = aType == MediaData::AUDIO_DATA;
|
||||
MOZ_ASSERT_IF(!isAudio, aType == MediaData::VIDEO_DATA);
|
||||
|
||||
// If the decoder is waiting for data, we tell it to call us back when the
|
||||
// data arrives.
|
||||
if (aError == NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA) {
|
||||
MOZ_ASSERT(Reader()->IsWaitForDataSupported(),
|
||||
"Readers that send WAITING_FOR_DATA need to implement WaitForData");
|
||||
mMaster->WaitForData(aType);
|
||||
HandleWaitingForData();
|
||||
return;
|
||||
}
|
||||
|
||||
if (aError == NS_ERROR_DOM_MEDIA_CANCELED) {
|
||||
if (isAudio) {
|
||||
mMaster->EnsureAudioDecodeTaskQueued();
|
||||
} else {
|
||||
mMaster->EnsureVideoDecodeTaskQueued();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a decode error, delegate to the generic error path.
|
||||
if (aError != NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
|
||||
mMaster->DecodeError(aError);
|
||||
return;
|
||||
}
|
||||
|
||||
// This is an EOS. Finish off the queue, and then handle things based on our
|
||||
// state.
|
||||
if (isAudio) {
|
||||
AudioQueue().Finish();
|
||||
} else {
|
||||
VideoQueue().Finish();
|
||||
}
|
||||
|
||||
HandleEndOfStream();
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
StateObject::HandleAudioWaited(MediaData::Type aType)
|
||||
@ -1804,6 +1677,48 @@ StateObject::HandleNotWaited(const WaitForDataRejectValue& aRejection)
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
StateObject::HandleAudioNotDecoded(const MediaResult& aError)
|
||||
{
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
mMaster->WaitForData(MediaData::AUDIO_DATA);
|
||||
HandleWaitingForData();
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
mMaster->EnsureAudioDecodeTaskQueued();
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
AudioQueue().Finish();
|
||||
HandleEndOfStream();
|
||||
break;
|
||||
default:
|
||||
mMaster->DecodeError(aError);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
StateObject::HandleVideoNotDecoded(const MediaResult& aError)
|
||||
{
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
mMaster->WaitForData(MediaData::VIDEO_DATA);
|
||||
HandleWaitingForData();
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
mMaster->EnsureVideoDecodeTaskQueued();
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
VideoQueue().Finish();
|
||||
HandleEndOfStream();
|
||||
break;
|
||||
default:
|
||||
mMaster->DecodeError(aError);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<MediaDecoder::SeekPromise>
|
||||
MediaDecoderStateMachine::
|
||||
StateObject::HandleSeek(SeekTarget aTarget)
|
||||
@ -1992,7 +1907,52 @@ DecodingFirstFrameState::Enter()
|
||||
MOZ_ASSERT(!mMaster->mVideoDecodeSuspended);
|
||||
|
||||
// Dispatch tasks to decode first frames.
|
||||
mMaster->DispatchDecodeTasksIfNeeded();
|
||||
if (mMaster->HasAudio()) {
|
||||
mMaster->RequestAudioData();
|
||||
}
|
||||
if (mMaster->HasVideo()) {
|
||||
mMaster->RequestVideoData(false, media::TimeUnit());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
DecodingFirstFrameState::HandleAudioNotDecoded(const MediaResult& aError)
|
||||
{
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
mMaster->WaitForData(MediaData::AUDIO_DATA);
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
mMaster->RequestAudioData();
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
AudioQueue().Finish();
|
||||
MaybeFinishDecodeFirstFrame();
|
||||
break;
|
||||
default:
|
||||
mMaster->DecodeError(aError);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
DecodingFirstFrameState::HandleVideoNotDecoded(const MediaResult& aError)
|
||||
{
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
mMaster->WaitForData(MediaData::VIDEO_DATA);
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
mMaster->RequestVideoData(false, media::TimeUnit());
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
VideoQueue().Finish();
|
||||
MaybeFinishDecodeFirstFrame();
|
||||
break;
|
||||
default:
|
||||
mMaster->DecodeError(aError);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -2081,7 +2041,6 @@ DecodingState::MaybeStartBuffering()
|
||||
mMaster->HasLowDecodedData() &&
|
||||
mMaster->HasLowBufferedData();
|
||||
} else {
|
||||
MOZ_ASSERT(Reader()->IsWaitForDataSupported());
|
||||
shouldBuffer =
|
||||
(mMaster->OutOfDecodedAudio() && mMaster->IsWaitingAudioData()) ||
|
||||
(mMaster->OutOfDecodedVideo() && mMaster->IsWaitingVideoData());
|
||||
@ -2145,6 +2104,92 @@ SeekingState::SeekCompleted()
|
||||
SetState<DecodingState>();
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
AccurateSeekingState::HandleAudioNotDecoded(const MediaResult& aError)
|
||||
{
|
||||
if (mSeekJob.mTarget->IsVideoOnly()) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(!mDoneAudioSeeking);
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
mMaster->WaitForData(MediaData::AUDIO_DATA);
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
RequestAudioData();
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
AudioQueue().Finish();
|
||||
mDoneAudioSeeking = true;
|
||||
MaybeFinishSeek();
|
||||
break;
|
||||
default:
|
||||
mMaster->DecodeError(aError);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
AccurateSeekingState::HandleVideoNotDecoded(const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(!mDoneVideoSeeking);
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
mMaster->WaitForData(MediaData::VIDEO_DATA);
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
RequestVideoData();
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
if (mFirstVideoFrameAfterSeek) {
|
||||
// Hit the end of stream. Move mFirstVideoFrameAfterSeek into
|
||||
// mSeekedVideoData so we have something to display after seeking.
|
||||
mMaster->PushVideo(mFirstVideoFrameAfterSeek);
|
||||
}
|
||||
VideoQueue().Finish();
|
||||
mDoneVideoSeeking = true;
|
||||
MaybeFinishSeek();
|
||||
break;
|
||||
default:
|
||||
mMaster->DecodeError(aError);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
NextFrameSeekingState::HandleAudioNotDecoded(const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(!mSeekJob.mPromise.IsEmpty(), "Seek shouldn't be finished");
|
||||
MOZ_ASSERT(NeedMoreVideo());
|
||||
// We don't care about audio decode errors in this state which will be
|
||||
// handled by other states after seeking.
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
NextFrameSeekingState::HandleVideoNotDecoded(const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(!mSeekJob.mPromise.IsEmpty(), "Seek shouldn't be finished");
|
||||
MOZ_ASSERT(NeedMoreVideo());
|
||||
// Video seek not finished.
|
||||
switch (aError.Code()) {
|
||||
case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
|
||||
mMaster->WaitForData(MediaData::VIDEO_DATA);
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_CANCELED:
|
||||
RequestVideoData();
|
||||
break;
|
||||
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
||||
VideoQueue().Finish();
|
||||
FinishSeek();
|
||||
break;
|
||||
default:
|
||||
// Raise an error since we can't finish video seek anyway.
|
||||
mMaster->DecodeError(aError);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::
|
||||
BufferingState::Step()
|
||||
@ -2169,8 +2214,6 @@ BufferingState::Step()
|
||||
return;
|
||||
}
|
||||
} else if (mMaster->OutOfDecodedAudio() || mMaster->OutOfDecodedVideo()) {
|
||||
MOZ_ASSERT(Reader()->IsWaitForDataSupported(),
|
||||
"Don't yet have a strategy for non-heuristic + non-WaitForData");
|
||||
mMaster->DispatchDecodeTasksIfNeeded();
|
||||
MOZ_ASSERT(mMaster->mMinimizePreroll ||
|
||||
!mMaster->OutOfDecodedAudio() ||
|
||||
@ -2974,12 +3017,12 @@ MediaDecoderStateMachine::EnsureAudioDecodeTaskQueued()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
|
||||
MOZ_ASSERT(mState != DECODER_STATE_DECODING_FIRSTFRAME);
|
||||
|
||||
SAMPLE_LOG("EnsureAudioDecodeTaskQueued isDecoding=%d status=%s",
|
||||
IsAudioDecoding(), AudioRequestStatus());
|
||||
|
||||
if (mState != DECODER_STATE_DECODING &&
|
||||
mState != DECODER_STATE_DECODING_FIRSTFRAME &&
|
||||
mState != DECODER_STATE_BUFFERING) {
|
||||
return;
|
||||
}
|
||||
@ -2997,6 +3040,9 @@ void
|
||||
MediaDecoderStateMachine::RequestAudioData()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
MOZ_ASSERT(IsAudioDecoding());
|
||||
MOZ_ASSERT(!IsRequestingAudioData());
|
||||
MOZ_ASSERT(!IsWaitingAudioData());
|
||||
SAMPLE_LOG("Queueing audio task - queued=%i, decoder-queued=%o",
|
||||
AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames());
|
||||
|
||||
@ -3014,7 +3060,7 @@ MediaDecoderStateMachine::RequestAudioData()
|
||||
[this] (const MediaResult& aError) {
|
||||
SAMPLE_LOG("OnAudioNotDecoded aError=%u", aError.Code());
|
||||
mAudioDataRequest.Complete();
|
||||
mStateObj->HandleNotDecoded(MediaData::AUDIO_DATA, aError);
|
||||
mStateObj->HandleAudioNotDecoded(aError);
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -3033,12 +3079,12 @@ MediaDecoderStateMachine::EnsureVideoDecodeTaskQueued()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
|
||||
MOZ_ASSERT(mState != DECODER_STATE_DECODING_FIRSTFRAME);
|
||||
|
||||
SAMPLE_LOG("EnsureVideoDecodeTaskQueued isDecoding=%d status=%s",
|
||||
IsVideoDecoding(), VideoRequestStatus());
|
||||
|
||||
if (mState != DECODER_STATE_DECODING &&
|
||||
mState != DECODER_STATE_DECODING_FIRSTFRAME &&
|
||||
mState != DECODER_STATE_BUFFERING) {
|
||||
return;
|
||||
}
|
||||
@ -3058,6 +3104,9 @@ MediaDecoderStateMachine::RequestVideoData(bool aSkipToNextKeyframe,
|
||||
const media::TimeUnit& aCurrentTime)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
MOZ_ASSERT(IsVideoDecoding());
|
||||
MOZ_ASSERT(!IsRequestingVideoData());
|
||||
MOZ_ASSERT(!IsWaitingVideoData());
|
||||
SAMPLE_LOG("Queueing video task - queued=%i, decoder-queued=%o, skip=%i, time=%lld",
|
||||
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), aSkipToNextKeyframe,
|
||||
aCurrentTime.ToMicroseconds());
|
||||
@ -3077,7 +3126,7 @@ MediaDecoderStateMachine::RequestVideoData(bool aSkipToNextKeyframe,
|
||||
[this] (const MediaResult& aError) {
|
||||
SAMPLE_LOG("OnVideoNotDecoded aError=%u", aError.Code());
|
||||
mVideoDataRequest.Complete();
|
||||
mStateObj->HandleNotDecoded(MediaData::VIDEO_DATA, aError);
|
||||
mStateObj->HandleVideoNotDecoded(aError);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -170,8 +170,8 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
|
||||
nsCString keySystem = NS_ConvertUTF16toUTF8(aKeySystem);
|
||||
bool supported = mozilla::java::MediaDrmProxy::IsSchemeSupported(keySystem);
|
||||
if (!supported) {
|
||||
aOutMessage = NS_LITERAL_CSTRING("Widevine CDM is not available");
|
||||
return MediaKeySystemStatus::Cdm_not_installed;
|
||||
aOutMessage = NS_LITERAL_CSTRING("KeySystem or Minimum API level not met for Widevine EME");
|
||||
return MediaKeySystemStatus::Cdm_not_supported;
|
||||
}
|
||||
return MediaKeySystemStatus::Available;
|
||||
#endif
|
||||
|
@ -32,7 +32,6 @@
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
|
@ -37,7 +37,6 @@
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
|
@ -593,6 +593,15 @@ class JS_FRIEND_API(AutoEnterPolicy)
|
||||
inline void recordLeave() {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
// This operator needs to be deleted explicitly, otherwise Visual C++ will
|
||||
// create it automatically when it is part of the export JS API. In that
|
||||
// case, compile would fail because HandleId is not allowed to be assigned
|
||||
// and consequently instantiation of assign operator of mozilla::Maybe
|
||||
// would fail. See bug 1325351 comment 16. Copy constructor is removed at
|
||||
// the same time for consistency.
|
||||
AutoEnterPolicy(const AutoEnterPolicy&) = delete;
|
||||
AutoEnterPolicy& operator=(const AutoEnterPolicy&) = delete;
|
||||
};
|
||||
|
||||
#ifdef JS_DEBUG
|
||||
|
@ -25,7 +25,6 @@
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
|
@ -336,8 +336,7 @@ AppendCSSShadowValue(const nsCSSShadowItem *aShadow,
|
||||
arr->Item(4).SetColorValue(aShadow->mColor);
|
||||
}
|
||||
if (aShadow->mInset) {
|
||||
arr->Item(5).SetIntValue(uint8_t(StyleBoxShadowType::Inset),
|
||||
eCSSUnit_Enumerated);
|
||||
arr->Item(5).SetEnumValue(StyleBoxShadowType::Inset);
|
||||
}
|
||||
|
||||
nsCSSValueList *resultItem = new nsCSSValueList;
|
||||
@ -4179,8 +4178,7 @@ StyleClipBasicShapeToCSSArray(const StyleClipPath& aClipPath,
|
||||
functionArray =
|
||||
aResult->Item(0).InitFunction(functionName,
|
||||
ShapeArgumentCount(functionName));
|
||||
functionArray->Item(1).SetIntValue(shape->GetFillRule(),
|
||||
eCSSUnit_Enumerated);
|
||||
functionArray->Item(1).SetEnumValue(shape->GetFillRule());
|
||||
nsCSSValuePairList* list = functionArray->Item(2).SetPairListValue();
|
||||
const nsTArray<nsStyleCoord>& coords = shape->Coordinates();
|
||||
MOZ_ASSERT((coords.Length() % 2) == 0);
|
||||
@ -4228,8 +4226,7 @@ StyleClipBasicShapeToCSSArray(const StyleClipPath& aClipPath,
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown shape type");
|
||||
return false;
|
||||
}
|
||||
aResult->Item(1).SetIntValue(aClipPath.GetReferenceBox(),
|
||||
eCSSUnit_Enumerated);
|
||||
aResult->Item(1).SetEnumValue(aClipPath.GetReferenceBox());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4525,8 +4522,7 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
|
||||
result->SetURLValue(clipPath.GetURL());
|
||||
aComputedValue.SetAndAdoptCSSValueValue(result.release(), eUnit_URL);
|
||||
} else if (type == StyleShapeSourceType::Box) {
|
||||
aComputedValue.SetIntValue(clipPath.GetReferenceBox(),
|
||||
eUnit_Enumerated);
|
||||
aComputedValue.SetEnumValue(clipPath.GetReferenceBox());
|
||||
} else if (type == StyleShapeSourceType::Shape) {
|
||||
RefPtr<nsCSSValue::Array> result = nsCSSValue::Array::Create(2);
|
||||
if (!StyleClipBasicShapeToCSSArray(clipPath, result)) {
|
||||
|
@ -491,11 +491,11 @@ public:
|
||||
void SetIntValue(int32_t aInt, Unit aUnit);
|
||||
template<typename T,
|
||||
typename = typename std::enable_if<std::is_enum<T>::value>::type>
|
||||
void SetIntValue(T aInt, Unit aUnit)
|
||||
void SetEnumValue(T aInt)
|
||||
{
|
||||
static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
|
||||
"aValue must be an enum that fits within mValue.mInt");
|
||||
SetIntValue(static_cast<int32_t>(aInt), aUnit);
|
||||
SetIntValue(static_cast<int32_t>(aInt), eUnit_Enumerated);
|
||||
}
|
||||
void SetCoordValue(nscoord aCoord);
|
||||
void SetPercentValue(float aPercent);
|
||||
|
@ -12403,8 +12403,7 @@ CSSParserImpl::ParseImageLayersItem(
|
||||
aState.mImage->mValue.SetNoneValue();
|
||||
aState.mAttachment->mValue.SetIntValue(NS_STYLE_IMAGELAYER_ATTACHMENT_SCROLL,
|
||||
eCSSUnit_Enumerated);
|
||||
aState.mClip->mValue.SetIntValue(StyleGeometryBox::Border,
|
||||
eCSSUnit_Enumerated);
|
||||
aState.mClip->mValue.SetEnumValue(StyleGeometryBox::Border);
|
||||
|
||||
aState.mRepeat->mXValue.SetIntValue(NS_STYLE_IMAGELAYER_REPEAT_REPEAT,
|
||||
eCSSUnit_Enumerated);
|
||||
@ -12416,11 +12415,9 @@ CSSParserImpl::ParseImageLayersItem(
|
||||
aState.mPositionY->mValue.SetArrayValue(positionYArr, eCSSUnit_Array);
|
||||
|
||||
if (eCSSProperty_mask == aTable[nsStyleImageLayers::shorthand]) {
|
||||
aState.mOrigin->mValue.SetIntValue(StyleGeometryBox::Border,
|
||||
eCSSUnit_Enumerated);
|
||||
aState.mOrigin->mValue.SetEnumValue(StyleGeometryBox::Border);
|
||||
} else {
|
||||
aState.mOrigin->mValue.SetIntValue(StyleGeometryBox::Padding,
|
||||
eCSSUnit_Enumerated);
|
||||
aState.mOrigin->mValue.SetEnumValue(StyleGeometryBox::Padding);
|
||||
}
|
||||
positionXArr->Item(1).SetPercentValue(0.0f);
|
||||
positionYArr->Item(1).SetPercentValue(0.0f);
|
||||
@ -17219,9 +17216,9 @@ CSSParserImpl::ParseAnimation()
|
||||
initialValues[1].SetIntValue(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE,
|
||||
eCSSUnit_Enumerated);
|
||||
initialValues[2].SetFloatValue(0.0, eCSSUnit_Seconds);
|
||||
initialValues[3].SetIntValue(static_cast<uint32_t>(mozilla::dom::PlaybackDirection::Normal),
|
||||
initialValues[3].SetIntValue(static_cast<int32_t>(dom::PlaybackDirection::Normal),
|
||||
eCSSUnit_Enumerated);
|
||||
initialValues[4].SetIntValue(static_cast<uint32_t>(mozilla::dom::FillMode::None),
|
||||
initialValues[4].SetIntValue(static_cast<int32_t>(dom::FillMode::None),
|
||||
eCSSUnit_Enumerated);
|
||||
initialValues[5].SetFloatValue(1.0f, eCSSUnit_Number);
|
||||
initialValues[6].SetIntValue(NS_STYLE_ANIMATION_PLAY_STATE_RUNNING, eCSSUnit_Enumerated);
|
||||
|
@ -890,11 +890,11 @@ public:
|
||||
void SetIntValue(int32_t aValue, nsCSSUnit aUnit);
|
||||
template<typename T,
|
||||
typename = typename std::enable_if<std::is_enum<T>::value>::type>
|
||||
void SetIntValue(T aValue, nsCSSUnit aUnit)
|
||||
void SetEnumValue(T aValue)
|
||||
{
|
||||
static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
|
||||
"aValue must be an enum that fits within mValue.mInt");
|
||||
SetIntValue(static_cast<int32_t>(aValue), aUnit);
|
||||
SetIntValue(static_cast<int32_t>(aValue), eCSSUnit_Enumerated);
|
||||
}
|
||||
void SetPercentValue(float aValue);
|
||||
void SetFloatValue(float aValue, nsCSSUnit aUnit);
|
||||
|
67
mfbt/Maybe.h
67
mfbt/Maybe.h
@ -103,16 +103,11 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe<T*> can be copy-constructed from a Maybe<U*> if U* and T* are
|
||||
* compatible, or from Maybe<decltype(nullptr)>.
|
||||
* Maybe<T> can be copy-constructed from a Maybe<U> if U is convertible to T.
|
||||
*/
|
||||
template<typename U,
|
||||
typename =
|
||||
typename std::enable_if<std::is_pointer<T>::value &&
|
||||
(std::is_same<U, decltype(nullptr)>::value ||
|
||||
(std::is_pointer<U>::value &&
|
||||
std::is_base_of<typename std::remove_pointer<T>::type,
|
||||
typename std::remove_pointer<U>::type>::value))>::type>
|
||||
typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
MOZ_IMPLICIT
|
||||
Maybe(const Maybe<U>& aOther)
|
||||
: mIsSome(false)
|
||||
@ -132,16 +127,11 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe<T*> can be move-constructed from a Maybe<U*> if U* and T* are
|
||||
* compatible, or from Maybe<decltype(nullptr)>.
|
||||
* Maybe<T> can be move-constructed from a Maybe<U> if U is convertible to T.
|
||||
*/
|
||||
template<typename U,
|
||||
typename =
|
||||
typename std::enable_if<std::is_pointer<T>::value &&
|
||||
(std::is_same<U, decltype(nullptr)>::value ||
|
||||
(std::is_pointer<U>::value &&
|
||||
std::is_base_of<typename std::remove_pointer<T>::type,
|
||||
typename std::remove_pointer<U>::type>::value))>::type>
|
||||
typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
MOZ_IMPLICIT
|
||||
Maybe(Maybe<U>&& aOther)
|
||||
: mIsSome(false)
|
||||
@ -157,13 +147,7 @@ public:
|
||||
if (&aOther != this) {
|
||||
if (aOther.mIsSome) {
|
||||
if (mIsSome) {
|
||||
// XXX(seth): The correct code for this branch, below, can't be used
|
||||
// due to a bug in Visual Studio 2010. See bug 1052940.
|
||||
/*
|
||||
ref() = aOther.ref();
|
||||
*/
|
||||
reset();
|
||||
emplace(*aOther);
|
||||
} else {
|
||||
emplace(*aOther);
|
||||
}
|
||||
@ -174,6 +158,23 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U,
|
||||
typename =
|
||||
typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Maybe& operator=(const Maybe<U>& aOther)
|
||||
{
|
||||
if (aOther.isSome()) {
|
||||
if (mIsSome) {
|
||||
ref() = aOther.ref();
|
||||
} else {
|
||||
emplace(*aOther);
|
||||
}
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Maybe& operator=(Maybe&& aOther)
|
||||
{
|
||||
MOZ_ASSERT(this != &aOther, "Self-moves are prohibited");
|
||||
@ -192,6 +193,25 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U,
|
||||
typename =
|
||||
typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Maybe& operator=(Maybe<U>&& aOther)
|
||||
{
|
||||
if (aOther.isSome()) {
|
||||
if (mIsSome) {
|
||||
ref() = Move(aOther.ref());
|
||||
} else {
|
||||
emplace(Move(*aOther));
|
||||
}
|
||||
aOther.reset();
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Methods that check whether this Maybe contains a value */
|
||||
explicit operator bool() const { return isSome(); }
|
||||
bool isSome() const { return mIsSome; }
|
||||
@ -444,11 +464,12 @@ public:
|
||||
* if you need to construct a Maybe value that holds a const, volatile, or
|
||||
* reference value, you need to use emplace() instead.
|
||||
*/
|
||||
template<typename T>
|
||||
Maybe<typename RemoveCV<typename RemoveReference<T>::Type>::Type>
|
||||
template<typename T,
|
||||
typename U = typename std::remove_cv<
|
||||
typename std::remove_reference<T>::type>::type>
|
||||
Maybe<U>
|
||||
Some(T&& aValue)
|
||||
{
|
||||
typedef typename RemoveCV<typename RemoveReference<T>::Type>::Type U;
|
||||
Maybe<U> value;
|
||||
value.emplace(Forward<T>(aValue));
|
||||
return value;
|
||||
|
@ -47,9 +47,11 @@ enum Status
|
||||
eWasConstructed,
|
||||
eWasCopyConstructed,
|
||||
eWasMoveConstructed,
|
||||
eWasAssigned,
|
||||
eWasCopyAssigned,
|
||||
eWasMoveAssigned,
|
||||
eWasMovedFrom
|
||||
eWasCopiedFrom,
|
||||
eWasMovedFrom,
|
||||
};
|
||||
|
||||
static size_t sUndestroyedObjects = 0;
|
||||
@ -842,6 +844,220 @@ TestSomePointerConversion()
|
||||
return true;
|
||||
}
|
||||
|
||||
struct SourceType1
|
||||
{
|
||||
int mTag;
|
||||
|
||||
operator int() const
|
||||
{
|
||||
return mTag;
|
||||
}
|
||||
};
|
||||
struct DestType
|
||||
{
|
||||
int mTag;
|
||||
Status mStatus;
|
||||
|
||||
DestType()
|
||||
: mTag(0)
|
||||
, mStatus(eWasDefaultConstructed)
|
||||
{}
|
||||
|
||||
MOZ_IMPLICIT DestType(int aTag)
|
||||
: mTag(aTag)
|
||||
, mStatus(eWasConstructed)
|
||||
{}
|
||||
|
||||
MOZ_IMPLICIT DestType(SourceType1&& aSrc)
|
||||
: mTag(aSrc.mTag)
|
||||
, mStatus(eWasMoveConstructed)
|
||||
{}
|
||||
|
||||
MOZ_IMPLICIT DestType(const SourceType1& aSrc)
|
||||
: mTag(aSrc.mTag)
|
||||
, mStatus(eWasCopyConstructed)
|
||||
{}
|
||||
|
||||
DestType& operator=(int aTag)
|
||||
{
|
||||
mTag = aTag;
|
||||
mStatus = eWasAssigned;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DestType& operator=(SourceType1&& aSrc)
|
||||
{
|
||||
mTag = aSrc.mTag;
|
||||
mStatus = eWasMoveAssigned;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DestType& operator=(const SourceType1& aSrc)
|
||||
{
|
||||
mTag = aSrc.mTag;
|
||||
mStatus = eWasCopyAssigned;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
struct SourceType2
|
||||
{
|
||||
int mTag;
|
||||
|
||||
operator DestType() const&
|
||||
{
|
||||
DestType result;
|
||||
result.mTag = mTag;
|
||||
result.mStatus = eWasCopiedFrom;
|
||||
return result;
|
||||
}
|
||||
|
||||
operator DestType() &&
|
||||
{
|
||||
DestType result;
|
||||
result.mTag = mTag;
|
||||
result.mStatus = eWasMovedFrom;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
static bool
|
||||
TestTypeConversion()
|
||||
{
|
||||
{
|
||||
Maybe<SourceType1> src = Some(SourceType1 {1});
|
||||
Maybe<DestType> dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 1);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasCopyConstructed);
|
||||
|
||||
src = Some(SourceType1 {2});
|
||||
dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 2);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasCopyAssigned);
|
||||
}
|
||||
|
||||
{
|
||||
Maybe<SourceType1> src = Some(SourceType1 {1});
|
||||
Maybe<DestType> dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasMoveConstructed);
|
||||
|
||||
src = Some(SourceType1 {2});
|
||||
dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasMoveAssigned);
|
||||
}
|
||||
|
||||
{
|
||||
Maybe<SourceType2> src = Some(SourceType2 {1});
|
||||
Maybe<DestType> dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 1);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasCopiedFrom);
|
||||
|
||||
src = Some(SourceType2 {2});
|
||||
dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 2);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasCopiedFrom);
|
||||
}
|
||||
|
||||
{
|
||||
Maybe<SourceType2> src = Some(SourceType2 {1});
|
||||
Maybe<DestType> dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasMovedFrom);
|
||||
|
||||
src = Some(SourceType2 {2});
|
||||
dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasMovedFrom);
|
||||
}
|
||||
|
||||
{
|
||||
Maybe<int> src = Some(1);
|
||||
Maybe<DestType> dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && *src == 1);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasConstructed);
|
||||
|
||||
src = Some(2);
|
||||
dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && *src == 2);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasAssigned);
|
||||
}
|
||||
|
||||
{
|
||||
Maybe<int> src = Some(1);
|
||||
Maybe<DestType> dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasConstructed);
|
||||
|
||||
src = Some(2);
|
||||
dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2);
|
||||
MOZ_RELEASE_ASSERT(dest->mStatus == eWasAssigned);
|
||||
}
|
||||
|
||||
{
|
||||
Maybe<SourceType1> src = Some(SourceType1 {1});
|
||||
Maybe<int> dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 1);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 1);
|
||||
|
||||
src = Some(SourceType1 {2});
|
||||
dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 2);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 2);
|
||||
}
|
||||
|
||||
{
|
||||
Maybe<SourceType1> src = Some(SourceType1 {1});
|
||||
Maybe<int> dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 1);
|
||||
|
||||
src = Some(SourceType1 {2});
|
||||
dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 2);
|
||||
}
|
||||
|
||||
{
|
||||
Maybe<size_t> src = Some(1);
|
||||
Maybe<char16_t> dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && *src == 1);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 1);
|
||||
|
||||
src = Some(2);
|
||||
dest = src;
|
||||
MOZ_RELEASE_ASSERT(src.isSome() && *src == 2);
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 2);
|
||||
}
|
||||
|
||||
{
|
||||
Maybe<size_t> src = Some(1);
|
||||
Maybe<char16_t> dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 1);
|
||||
|
||||
src = Some(2);
|
||||
dest = Move(src);
|
||||
MOZ_RELEASE_ASSERT(src.isNothing());
|
||||
MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
@ -855,6 +1071,7 @@ main()
|
||||
RUN_TEST(TestVirtualFunction);
|
||||
RUN_TEST(TestSomeNullptrConversion);
|
||||
RUN_TEST(TestSomePointerConversion);
|
||||
RUN_TEST(TestTypeConversion);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ job-defaults:
|
||||
implementation: docker-worker
|
||||
max-run-time: 36000
|
||||
docker-image: {in-tree: desktop-build}
|
||||
env:
|
||||
MOZ_AUTOMATION: "1"
|
||||
|
||||
jobs:
|
||||
linux64-shell-haz/debug:
|
||||
|
@ -196,6 +196,7 @@ class TaskGraphGenerator(object):
|
||||
|
||||
full_task_graph = TaskGraph(all_tasks,
|
||||
Graph(full_task_set.graph.nodes, edges))
|
||||
full_task_graph.for_each_task(verify_task_graph_symbol, scratch_pad={})
|
||||
logger.info("Full task graph contains %d tasks and %d dependencies" % (
|
||||
len(full_task_set.graph.nodes), len(edges)))
|
||||
yield 'full_task_graph', full_task_graph
|
||||
@ -221,7 +222,6 @@ class TaskGraphGenerator(object):
|
||||
target_task_graph = TaskGraph(
|
||||
{l: all_tasks[l] for l in target_graph.nodes},
|
||||
target_graph)
|
||||
target_task_graph.for_each_task(verify_task_graph_symbol, scratch_pad={})
|
||||
target_task_graph.for_each_task(verify_gecko_v2_routes, scratch_pad={})
|
||||
yield 'target_task_graph', target_task_graph
|
||||
|
||||
|
@ -46,7 +46,7 @@ class TestSSLStatusAfterRestart(PuppeteerMixin, MarionetteTestCase):
|
||||
finally:
|
||||
super(TestSSLStatusAfterRestart, self).tearDown()
|
||||
|
||||
@skip_if_e10s
|
||||
@skip_if_e10s("Bug 1325047")
|
||||
def test_ssl_status_after_restart(self):
|
||||
for item in self.test_data:
|
||||
with self.marionette.using_context('content'):
|
||||
|
@ -5,11 +5,15 @@
|
||||
__version__ = '3.1.0'
|
||||
|
||||
|
||||
from .decorators import (
|
||||
from unittest.case import (
|
||||
expectedFailure,
|
||||
skip,
|
||||
SkipTest,
|
||||
)
|
||||
|
||||
from .decorators import (
|
||||
parameterized,
|
||||
run_if_e10s,
|
||||
skip,
|
||||
skip_if_chrome,
|
||||
skip_if_desktop,
|
||||
skip_if_e10s,
|
||||
@ -19,10 +23,6 @@ from .decorators import (
|
||||
with_parameters,
|
||||
)
|
||||
|
||||
from .errors import (
|
||||
SkipTest,
|
||||
)
|
||||
|
||||
from .testcases import (
|
||||
CommonTestCase,
|
||||
MarionetteTestCase,
|
||||
|
@ -3,28 +3,13 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import functools
|
||||
import sys
|
||||
import types
|
||||
|
||||
from .errors import (
|
||||
_ExpectedFailure,
|
||||
_UnexpectedSuccess,
|
||||
from unittest.case import (
|
||||
SkipTest,
|
||||
)
|
||||
|
||||
|
||||
def expectedFailure(func):
|
||||
"""Decorator which marks a test as expected fail."""
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
func(*args, **kwargs)
|
||||
except Exception:
|
||||
raise _ExpectedFailure(sys.exc_info())
|
||||
raise _UnexpectedSuccess
|
||||
return wrapper
|
||||
|
||||
|
||||
def parameterized(func_suffix, *args, **kwargs):
|
||||
r"""Decorator which generates methods given a base method and some data.
|
||||
|
||||
@ -61,85 +46,101 @@ def parameterized(func_suffix, *args, **kwargs):
|
||||
return wrapped
|
||||
|
||||
|
||||
def run_if_e10s(target):
|
||||
def run_if_e10s(reason):
|
||||
"""Decorator which runs a test if e10s mode is active."""
|
||||
def wrapper(self, *args, **kwargs):
|
||||
with self.marionette.using_context('chrome'):
|
||||
multi_process_browser = self.marionette.execute_script("""
|
||||
try {
|
||||
return Services.appinfo.browserTabsRemoteAutostart;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}""")
|
||||
|
||||
if not multi_process_browser:
|
||||
raise SkipTest('skipping due to e10s is disabled')
|
||||
return target(self, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
def skip(reason):
|
||||
"""Decorator which unconditionally skips a test."""
|
||||
def decorator(test_item):
|
||||
if not isinstance(test_item, (type, types.ClassType)):
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(*args, **kwargs):
|
||||
raise SkipTest(reason)
|
||||
test_item = skip_wrapper
|
||||
if not isinstance(test_item, types.FunctionType):
|
||||
raise Exception('Decorator only supported for functions')
|
||||
|
||||
test_item.__unittest_skip__ = True
|
||||
test_item.__unittest_skip_why__ = reason
|
||||
return test_item
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(self, *args, **kwargs):
|
||||
with self.marionette.using_context('chrome'):
|
||||
multi_process_browser = not self.marionette.execute_script("""
|
||||
try {
|
||||
return Services.appinfo.browserTabsRemoteAutostart;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
""")
|
||||
if multi_process_browser:
|
||||
raise SkipTest(reason)
|
||||
return test_item(self, *args, **kwargs)
|
||||
return skip_wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def skip_if_chrome(target):
|
||||
def skip_if_chrome(reason):
|
||||
"""Decorator which skips a test if chrome context is active."""
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if self.marionette._send_message("getContext", key="value") == "chrome":
|
||||
raise SkipTest("skipping test in chrome context")
|
||||
return target(self, *args, **kwargs)
|
||||
return wrapper
|
||||
def decorator(test_item):
|
||||
if not isinstance(test_item, types.FunctionType):
|
||||
raise Exception('Decorator only supported for functions')
|
||||
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(self, *args, **kwargs):
|
||||
if self.marionette._send_message('getContext', key='value') == 'chrome':
|
||||
raise SkipTest(reason)
|
||||
return test_item(self, *args, **kwargs)
|
||||
return skip_wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def skip_if_desktop(target):
|
||||
def skip_if_desktop(reason):
|
||||
"""Decorator which skips a test if run on desktop."""
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if self.marionette.session_capabilities.get('browserName') == 'firefox':
|
||||
raise SkipTest('skipping due to desktop')
|
||||
return target(self, *args, **kwargs)
|
||||
return wrapper
|
||||
def decorator(test_item):
|
||||
if not isinstance(test_item, types.FunctionType):
|
||||
raise Exception('Decorator only supported for functions')
|
||||
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(self, *args, **kwargs):
|
||||
if self.marionette.session_capabilities.get('browserName') == 'firefox':
|
||||
raise SkipTest(reason)
|
||||
return test_item(self, *args, **kwargs)
|
||||
return skip_wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def skip_if_e10s(target):
|
||||
def skip_if_e10s(reason):
|
||||
"""Decorator which skips a test if e10s mode is active."""
|
||||
def wrapper(self, *args, **kwargs):
|
||||
with self.marionette.using_context('chrome'):
|
||||
multi_process_browser = self.marionette.execute_script("""
|
||||
try {
|
||||
return Services.appinfo.browserTabsRemoteAutostart;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}""")
|
||||
def decorator(test_item):
|
||||
if not isinstance(test_item, types.FunctionType):
|
||||
raise Exception('Decorator only supported for functions')
|
||||
|
||||
if multi_process_browser:
|
||||
raise SkipTest('skipping due to e10s')
|
||||
return target(self, *args, **kwargs)
|
||||
return wrapper
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(self, *args, **kwargs):
|
||||
with self.marionette.using_context('chrome'):
|
||||
multi_process_browser = self.marionette.execute_script("""
|
||||
try {
|
||||
return Services.appinfo.browserTabsRemoteAutostart;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
""")
|
||||
if multi_process_browser:
|
||||
raise SkipTest(reason)
|
||||
return test_item(self, *args, **kwargs)
|
||||
return skip_wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def skip_if_mobile(target):
|
||||
def skip_if_mobile(reason):
|
||||
"""Decorator which skips a test if run on mobile."""
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if self.marionette.session_capabilities.get('browserName') == 'fennec':
|
||||
raise SkipTest('skipping due to fennec')
|
||||
return target(self, *args, **kwargs)
|
||||
return wrapper
|
||||
def decorator(test_item):
|
||||
if not isinstance(test_item, types.FunctionType):
|
||||
raise Exception('Decorator only supported for functions')
|
||||
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(self, *args, **kwargs):
|
||||
if self.marionette.session_capabilities.get('browserName') == 'fennec':
|
||||
raise SkipTest(reason)
|
||||
return test_item(self, *args, **kwargs)
|
||||
return skip_wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def skip_unless_browser_pref(pref, predicate=bool):
|
||||
def skip_unless_browser_pref(reason, pref, predicate=bool):
|
||||
"""Decorator which skips a test based on the value of a browser preference.
|
||||
|
||||
:param reason: Message describing why the test need to be skipped.
|
||||
:param pref: the preference name
|
||||
:param predicate: a function that should return false to skip the test.
|
||||
The function takes one parameter, the preference value.
|
||||
@ -150,33 +151,46 @@ def skip_unless_browser_pref(pref, predicate=bool):
|
||||
Example: ::
|
||||
|
||||
class TestSomething(MarionetteTestCase):
|
||||
@skip_unless_browser_pref("accessibility.tabfocus",
|
||||
lambda value: value >= 7)
|
||||
@skip_unless_browser_pref("Sessionstore needs to be enabled for crashes",
|
||||
"browser.sessionstore.resume_from_crash",
|
||||
lambda value: value is True,
|
||||
)
|
||||
def test_foo(self):
|
||||
pass # test implementation here
|
||||
|
||||
"""
|
||||
def wrapper(target):
|
||||
@functools.wraps(target)
|
||||
def wrapped(self, *args, **kwargs):
|
||||
def decorator(test_item):
|
||||
if not isinstance(test_item, types.FunctionType):
|
||||
raise Exception('Decorator only supported for functions')
|
||||
if not callable(predicate):
|
||||
raise ValueError('predicate must be callable')
|
||||
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(self, *args, **kwargs):
|
||||
value = self.marionette.get_pref(pref)
|
||||
if value is None:
|
||||
self.fail("No such browser preference: {0!r}".format(pref))
|
||||
if not predicate(value):
|
||||
raise SkipTest("browser preference {0!r}: {1!r}".format((pref, value)))
|
||||
return target(self, *args, **kwargs)
|
||||
return wrapped
|
||||
return wrapper
|
||||
raise SkipTest(reason)
|
||||
return test_item(self, *args, **kwargs)
|
||||
return skip_wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def skip_unless_protocol(predicate):
|
||||
def skip_unless_protocol(reason, predicate):
|
||||
"""Decorator which skips a test if the predicate does not match the current protocol level."""
|
||||
def decorator(test_item):
|
||||
if not isinstance(test_item, types.FunctionType):
|
||||
raise Exception('Decorator only supported for functions')
|
||||
if not callable(predicate):
|
||||
raise ValueError('predicate must be callable')
|
||||
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(self):
|
||||
def skip_wrapper(self, *args, **kwargs):
|
||||
level = self.marionette.client.protocol
|
||||
if not predicate(level):
|
||||
raise SkipTest('skipping because protocol level is {}'.format(level))
|
||||
return test_item(self)
|
||||
raise SkipTest(reason)
|
||||
return test_item(self, *args, **kwargs)
|
||||
return skip_wrapper
|
||||
return decorator
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
class SkipTest(Exception):
|
||||
"""
|
||||
Raise this exception in a test to skip it.
|
||||
|
||||
Usually you can use TestResult.skip() or one of the skipping decorators
|
||||
instead of raising this directly.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class _ExpectedFailure(Exception):
|
||||
"""
|
||||
Raise this when a test is expected to fail.
|
||||
|
||||
This is an implementation detail.
|
||||
"""
|
||||
|
||||
def __init__(self, exc_info):
|
||||
super(_ExpectedFailure, self).__init__()
|
||||
self.exc_info = exc_info
|
||||
|
||||
|
||||
class _UnexpectedSuccess(Exception):
|
||||
"""The test was supposed to fail, but it didn't."""
|
||||
|
||||
pass
|
@ -12,6 +12,12 @@ import unittest
|
||||
import warnings
|
||||
import weakref
|
||||
|
||||
from unittest.case import (
|
||||
_ExpectedFailure,
|
||||
_UnexpectedSuccess,
|
||||
SkipTest,
|
||||
)
|
||||
|
||||
from marionette_driver.errors import (
|
||||
MarionetteException,
|
||||
ScriptTimeoutException,
|
||||
@ -19,12 +25,6 @@ from marionette_driver.errors import (
|
||||
)
|
||||
from mozlog import get_default_logger
|
||||
|
||||
from .errors import (
|
||||
_ExpectedFailure,
|
||||
_UnexpectedSuccess,
|
||||
SkipTest,
|
||||
)
|
||||
|
||||
|
||||
def _wraps_parameterized(func, func_suffix, args, kwargs):
|
||||
"""Internal: Decorator used in class MetaParameterized."""
|
||||
|
@ -552,6 +552,10 @@ class BaseMarionetteTestRunner(object):
|
||||
self.e10s = e10s
|
||||
|
||||
def gather_debug(test, status):
|
||||
# No screenshots and page source for skipped tests
|
||||
if status == "SKIP":
|
||||
return
|
||||
|
||||
rv = {}
|
||||
marionette = test._marionette_weakref()
|
||||
|
||||
|
@ -26,7 +26,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase):
|
||||
|
||||
super(TestAboutPages, self).tearDown()
|
||||
|
||||
@skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles
|
||||
@skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles")
|
||||
def test_back_forward(self):
|
||||
# Bug 1311041 - Prevent changing of window handle by forcing the test
|
||||
# to be run in a new tab.
|
||||
@ -46,7 +46,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase):
|
||||
self.marionette.close()
|
||||
self.marionette.switch_to_window(self.start_tab)
|
||||
|
||||
@skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles
|
||||
@skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles")
|
||||
def test_navigate_non_remote_about_pages(self):
|
||||
# Bug 1311041 - Prevent changing of window handle by forcing the test
|
||||
# to be run in a new tab.
|
||||
@ -61,7 +61,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase):
|
||||
self.marionette.close()
|
||||
self.marionette.switch_to_window(self.start_tab)
|
||||
|
||||
@skip_if_mobile # On Android no shortcuts are available
|
||||
@skip_if_mobile("On Android no shortcuts are available")
|
||||
def test_navigate_shortcut_key(self):
|
||||
def open_with_shortcut():
|
||||
with self.marionette.using_context("chrome"):
|
||||
@ -76,7 +76,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase):
|
||||
self.marionette.close()
|
||||
self.marionette.switch_to_window(self.start_tab)
|
||||
|
||||
@skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles
|
||||
@skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles")
|
||||
def test_type_to_non_remote_tab(self):
|
||||
# Bug 1311041 - Prevent changing of window handle by forcing the test
|
||||
# to be run in a new tab.
|
||||
@ -93,7 +93,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase):
|
||||
self.marionette.close()
|
||||
self.marionette.switch_to_window(self.start_tab)
|
||||
|
||||
@skip_if_mobile # Interacting with chrome elements not available for Fennec
|
||||
@skip_if_mobile("Interacting with chrome elements not available for Fennec")
|
||||
def test_type_to_remote_tab(self):
|
||||
# about:blank keeps remoteness from remote_uri
|
||||
self.marionette.navigate("about:blank")
|
||||
@ -103,7 +103,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase):
|
||||
|
||||
self.wait_for_condition(lambda mn: mn.get_url() == self.remote_uri)
|
||||
|
||||
@skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles
|
||||
@skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles")
|
||||
def test_hang(self):
|
||||
# Open a new tab and close the first one
|
||||
new_tab = self.open_tab(trigger="menu")
|
||||
|
@ -4,10 +4,12 @@
|
||||
|
||||
from marionette_driver.errors import UnknownException
|
||||
|
||||
from marionette_harness import MarionetteTestCase
|
||||
from marionette_harness import MarionetteTestCase, skip
|
||||
|
||||
|
||||
class TestCertificates(MarionetteTestCase):
|
||||
|
||||
@skip("Bug 1325079")
|
||||
def test_block_insecure_sites(self):
|
||||
self.marionette.delete_session()
|
||||
self.marionette.start_session()
|
||||
@ -17,16 +19,16 @@ class TestCertificates(MarionetteTestCase):
|
||||
with self.assertRaises(UnknownException):
|
||||
self.marionette.navigate(self.fixtures.where_is("test.html", on="https"))
|
||||
|
||||
@skip("Bug 1325079")
|
||||
def test_accept_all_insecure(self):
|
||||
self.marionette.delete_session()
|
||||
self.marionette.start_session({"desiredCapability": {"acceptSslCerts": ["*"]}})
|
||||
self.marionette.navigate(self.fixtures.where_is("test.html", on="https"))
|
||||
self.assertIn("https://", self.marionette.url)
|
||||
|
||||
"""
|
||||
@skip("Bug 1325079")
|
||||
def test_accept_some_insecure(self):
|
||||
self.marionette.delete_session()
|
||||
self.marionette.start_session({"requiredCapabilities": {"acceptSslCerts": ["127.0.0.1"]}})
|
||||
self.marionette.navigate(self.fixtures.where_is("test.html", on="https"))
|
||||
self.assertIn("https://", self.marionette.url)
|
||||
"""
|
@ -43,7 +43,7 @@ class TestClickScrolling(MarionetteTestCase):
|
||||
except MoveTargetOutOfBoundsException:
|
||||
self.fail("Should not be out of bounds")
|
||||
|
||||
@skip("Bug 1003682")
|
||||
@skip("Bug 1200197 - Cannot interact with elements hidden inside overflow:scroll")
|
||||
def test_should_be_able_to_click_on_an_element_hidden_by_overflow(self):
|
||||
test_html = self.marionette.absolute_url("scroll.html")
|
||||
self.marionette.navigate(test_html)
|
||||
|
@ -104,7 +104,7 @@ class TestCrash(BaseCrashTestCase):
|
||||
# chrome and frame script.
|
||||
# self.marionette.get_url()
|
||||
|
||||
@run_if_e10s
|
||||
@run_if_e10s("Content crashes only exist in e10s mode")
|
||||
def test_crash_content_process(self):
|
||||
# If e10s is disabled the chrome process crashes
|
||||
self.marionette.navigate(self.remote_uri)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
from marionette_driver.by import By
|
||||
|
||||
from marionette_harness import MarionetteTestCase
|
||||
from marionette_harness import MarionetteTestCase, skip
|
||||
|
||||
|
||||
class TestIsElementEnabledChrome(MarionetteTestCase):
|
||||
@ -36,9 +36,7 @@ class TestIsElementEnabledChrome(MarionetteTestCase):
|
||||
self.assertTrue(rect['y'] > 0)
|
||||
|
||||
|
||||
# Switched off in bug 896043,
|
||||
# and to be turned on in bug 896046
|
||||
"""
|
||||
@skip("Switched off in bug 896043, and to be turned on in bug 896046")
|
||||
class TestIsElementDisplayed(MarionetteTestCase):
|
||||
def test_isDisplayed(self):
|
||||
l = self.marionette.find_element(By.ID, "textInput")
|
||||
@ -46,7 +44,6 @@ class TestIsElementDisplayed(MarionetteTestCase):
|
||||
self.marionette.execute_script("arguments[0].hidden = true;", [l])
|
||||
self.assertFalse(l.is_displayed())
|
||||
self.marionette.execute_script("arguments[0].hidden = false;", [l])
|
||||
"""
|
||||
|
||||
|
||||
class TestGetElementAttributeChrome(MarionetteTestCase):
|
||||
|
@ -31,6 +31,11 @@ class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase):
|
||||
self.marionette.clear_imported_scripts()
|
||||
self.reset_context()
|
||||
|
||||
def tearDown(self):
|
||||
self.close_all_windows()
|
||||
|
||||
super(TestImportScriptContent, self).tearDown()
|
||||
|
||||
def reset_context(self):
|
||||
self.marionette.set_context("content")
|
||||
|
||||
@ -109,8 +114,8 @@ class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase):
|
||||
self.assert_defined("testFunc")
|
||||
self.assert_defined("testAnotherFunc")
|
||||
|
||||
@skip_if_chrome
|
||||
@skip_if_mobile # New windows not supported in Fennec
|
||||
@skip_if_chrome("Needs content scope")
|
||||
@skip_if_mobile("New windows not supported in Fennec")
|
||||
def test_imports_apply_globally(self):
|
||||
self.marionette.navigate(
|
||||
self.marionette.absolute_url("test_windows.html"))
|
||||
|
@ -157,7 +157,7 @@ class TestTabModals(MarionetteTestCase):
|
||||
alert.accept()
|
||||
self.wait_for_condition(lambda mn: mn.get_url() == "about:blank")
|
||||
|
||||
@skip_if_e10s
|
||||
@skip_if_e10s("Bug 1325044")
|
||||
def test_unrelated_command_when_alert_present(self):
|
||||
click_handler = self.marionette.find_element(By.ID, 'click-handler')
|
||||
text = self.marionette.find_element(By.ID, 'click-result').text
|
||||
|
@ -2,15 +2,17 @@
|
||||
# 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 unittest import skip
|
||||
|
||||
import contextlib
|
||||
import time
|
||||
import urllib
|
||||
|
||||
from marionette_driver import errors, By, Wait
|
||||
|
||||
from marionette_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin
|
||||
from marionette_harness import (
|
||||
MarionetteTestCase,
|
||||
skip,
|
||||
skip_if_mobile,
|
||||
WindowManagerMixin,
|
||||
)
|
||||
|
||||
|
||||
def inline(doc):
|
||||
@ -112,7 +114,7 @@ class TestNavigate(WindowManagerMixin, MarionetteTestCase):
|
||||
self.marionette.switch_to_frame()
|
||||
self.assertTrue('test_iframe.html' in self.marionette.get_url())
|
||||
|
||||
@skip_if_mobile # Bug 1323755 - Socket timeout
|
||||
@skip_if_mobile("Bug 1323755 - Socket timeout")
|
||||
def test_invalid_protocol(self):
|
||||
with self.assertRaises(errors.MarionetteException):
|
||||
self.marionette.navigate("thisprotocoldoesnotexist://")
|
||||
@ -150,7 +152,7 @@ class TestNavigate(WindowManagerMixin, MarionetteTestCase):
|
||||
self.assertTrue(self.marionette.execute_script(
|
||||
"return window.visited", sandbox=None))
|
||||
|
||||
@skip_if_mobile # Fennec doesn't support other chrome windows
|
||||
@skip_if_mobile("Fennec doesn't support other chrome windows")
|
||||
def test_about_blank_for_new_docshell(self):
|
||||
""" Bug 1312674 - Hang when loading about:blank for a new docshell."""
|
||||
# Open a window to get a new docshell created for the first tab
|
||||
|
@ -23,31 +23,31 @@ class TestScreenOrientation(MarionetteTestCase):
|
||||
self.assertEqual(self.marionette.orientation, default_orientation, "invalid state")
|
||||
MarionetteTestCase.tearDown(self)
|
||||
|
||||
@skip_if_desktop
|
||||
@skip_if_desktop("Not supported in Firefox")
|
||||
def test_set_orientation_to_portrait_primary(self):
|
||||
self.marionette.set_orientation("portrait-primary")
|
||||
new_orientation = self.marionette.orientation
|
||||
self.assertEqual(new_orientation, "portrait-primary")
|
||||
|
||||
@skip_if_desktop
|
||||
@skip_if_desktop("Not supported in Firefox")
|
||||
def test_set_orientation_to_landscape_primary(self):
|
||||
self.marionette.set_orientation("landscape-primary")
|
||||
new_orientation = self.marionette.orientation
|
||||
self.assertEqual(new_orientation, "landscape-primary")
|
||||
|
||||
@skip_if_desktop
|
||||
@skip_if_desktop("Not supported in Firefox")
|
||||
def test_set_orientation_to_portrait_secondary(self):
|
||||
self.marionette.set_orientation("portrait-secondary")
|
||||
new_orientation = self.marionette.orientation
|
||||
self.assertEqual(new_orientation, "portrait-secondary")
|
||||
|
||||
@skip_if_desktop
|
||||
@skip_if_desktop("Not supported in Firefox")
|
||||
def test_set_orientation_to_landscape_secondary(self):
|
||||
self.marionette.set_orientation("landscape-secondary")
|
||||
new_orientation = self.marionette.orientation
|
||||
self.assertEqual(new_orientation, "landscape-secondary")
|
||||
|
||||
@skip_if_desktop
|
||||
@skip_if_desktop("Not supported in Firefox")
|
||||
def test_set_orientation_to_shorthand_portrait(self):
|
||||
# Set orientation to something other than portrait-primary first, since the default is
|
||||
# portrait-primary.
|
||||
@ -58,29 +58,29 @@ class TestScreenOrientation(MarionetteTestCase):
|
||||
new_orientation = self.marionette.orientation
|
||||
self.assertEqual(new_orientation, "portrait-primary")
|
||||
|
||||
@skip_if_desktop
|
||||
@skip_if_desktop("Not supported in Firefox")
|
||||
def test_set_orientation_to_shorthand_landscape(self):
|
||||
self.marionette.set_orientation("landscape")
|
||||
new_orientation = self.marionette.orientation
|
||||
self.assertEqual(new_orientation, "landscape-primary")
|
||||
|
||||
@skip_if_desktop
|
||||
@skip_if_desktop("Not supported in Firefox")
|
||||
def test_set_orientation_with_mixed_casing(self):
|
||||
self.marionette.set_orientation("lAnDsCaPe")
|
||||
new_orientation = self.marionette.orientation
|
||||
self.assertEqual(new_orientation, "landscape-primary")
|
||||
|
||||
@skip_if_desktop
|
||||
@skip_if_desktop("Not supported in Firefox")
|
||||
def test_set_invalid_orientation(self):
|
||||
with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("cheese")):
|
||||
self.marionette.set_orientation("cheese")
|
||||
|
||||
@skip_if_desktop
|
||||
@skip_if_desktop("Not supported in Firefox")
|
||||
def test_set_null_orientation(self):
|
||||
with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("null")):
|
||||
self.marionette.set_orientation(None)
|
||||
|
||||
@skip_if_mobile
|
||||
@skip_if_mobile("Specific test for Firefox")
|
||||
def test_unsupported_operation_on_desktop(self):
|
||||
with self.assertRaises(errors.UnsupportedOperationException):
|
||||
self.marionette.set_orientation("landscape-primary")
|
||||
|
@ -8,11 +8,14 @@ import imghdr
|
||||
import struct
|
||||
import urllib
|
||||
|
||||
from unittest import skip
|
||||
|
||||
from marionette_driver import By
|
||||
from marionette_driver.errors import JavascriptException, NoSuchWindowException
|
||||
from marionette_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin
|
||||
from marionette_harness import (
|
||||
MarionetteTestCase,
|
||||
skip,
|
||||
skip_if_mobile,
|
||||
WindowManagerMixin,
|
||||
)
|
||||
|
||||
|
||||
def inline(doc, mime="text/html;charset=utf-8"):
|
||||
@ -149,7 +152,7 @@ class TestScreenCaptureChrome(WindowManagerMixin, ScreenCaptureTestCase):
|
||||
screenshot_chrome = self.marionette.screenshot()
|
||||
self.assertNotEqual(screenshot_content, screenshot_chrome)
|
||||
|
||||
@skip_if_mobile
|
||||
@skip_if_mobile("Fennec doesn't support other chrome windows")
|
||||
def test_capture_element(self):
|
||||
dialog = self.open_dialog()
|
||||
self.marionette.switch_to_window(dialog)
|
||||
@ -212,7 +215,7 @@ class TestScreenCaptureChrome(WindowManagerMixin, ScreenCaptureTestCase):
|
||||
self.marionette.close_chrome_window()
|
||||
self.marionette.switch_to_window(self.start_window)
|
||||
|
||||
@skip("https://bugzilla.mozilla.org/show_bug.cgi?id=1213875")
|
||||
@skip("Bug 1213875")
|
||||
def test_capture_scroll_element_into_view(self):
|
||||
pass
|
||||
|
||||
@ -237,7 +240,7 @@ class TestScreenCaptureChrome(WindowManagerMixin, ScreenCaptureTestCase):
|
||||
with self.assertRaises(ValueError):
|
||||
self.marionette.screenshot(format="cheese")
|
||||
|
||||
@skip_if_mobile
|
||||
@skip_if_mobile("Fennec doesn't support other chrome windows")
|
||||
def test_highlight_elements(self):
|
||||
dialog = self.open_dialog()
|
||||
self.marionette.switch_to_window(dialog)
|
||||
@ -293,7 +296,7 @@ class TestScreenCaptureContent(WindowManagerMixin, ScreenCaptureTestCase):
|
||||
return [document.body.scrollWidth, document.body.scrollHeight]
|
||||
"""))
|
||||
|
||||
@skip_if_mobile # Needs application independent method to open a new tab
|
||||
@skip_if_mobile("Needs application independent method to open a new tab")
|
||||
def test_capture_tab_already_closed(self):
|
||||
tab = self.open_tab()
|
||||
self.marionette.switch_to_window(tab)
|
||||
@ -310,7 +313,7 @@ class TestScreenCaptureContent(WindowManagerMixin, ScreenCaptureTestCase):
|
||||
self.assertEqual(self.scale(self.get_element_dimensions(el)),
|
||||
self.get_image_dimensions(screenshot))
|
||||
|
||||
@skip("https://bugzilla.mozilla.org/show_bug.cgi?id=1213875")
|
||||
@skip("Bug 1213875")
|
||||
def test_capture_element_scrolled_into_view(self):
|
||||
self.marionette.navigate(long)
|
||||
el = self.marionette.find_element(By.TAG_NAME, "p")
|
||||
|
@ -6,9 +6,9 @@ import os
|
||||
import sys
|
||||
|
||||
from marionette_driver.errors import MarionetteException
|
||||
from marionette_driver.by import By
|
||||
from marionette_driver import Actions, By
|
||||
|
||||
from marionette_harness import MarionetteTestCase
|
||||
from marionette_harness import MarionetteTestCase, skip
|
||||
|
||||
# add this directory to the path
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
@ -85,28 +85,30 @@ prefs.setIntPref("ui.click_hold_context_menus.delay", arguments[0]);
|
||||
def test_wait_with_value(self):
|
||||
wait_with_value(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
|
||||
|
||||
"""
|
||||
// Skipping due to Bug 1191066
|
||||
@skip("Bug 1191066")
|
||||
def test_context_menu(self):
|
||||
context_menu(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu", "button1-mousemove-mousedown-contextmenu-mouseup-click")
|
||||
context_menu(self.marionette, self.wait_for_condition,
|
||||
"button1-mousemove-mousedown-contextmenu",
|
||||
"button1-mousemove-mousedown-contextmenu-mouseup-click")
|
||||
|
||||
@skip("Bug 1191066")
|
||||
def test_long_press_action(self):
|
||||
long_press_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click")
|
||||
long_press_action(self.marionette, self.wait_for_condition,
|
||||
"button1-mousemove-mousedown-contextmenu-mouseup-click")
|
||||
|
||||
@skip("Bug 1191066")
|
||||
def test_long_press_on_xy_action(self):
|
||||
long_press_on_xy_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click")
|
||||
"""
|
||||
long_press_on_xy_action(self.marionette, self.wait_for_condition,
|
||||
"button1-mousemove-mousedown-contextmenu-mouseup-click")
|
||||
|
||||
"""
|
||||
//Skipping due to Bug 865334
|
||||
@skip("Bug 865334")
|
||||
def test_long_press_fail(self):
|
||||
testAction = self.marionette.absolute_url("testAction.html")
|
||||
self.marionette.navigate(testAction)
|
||||
button = self.marionette.find_element(By.ID, "button1Copy")
|
||||
action = Actions(self.marionette)
|
||||
action.press(button).long_press(button, 5)
|
||||
assertRaises(MarionetteException, action.perform)
|
||||
"""
|
||||
self.assertRaises(MarionetteException, action.perform)
|
||||
|
||||
def test_chain(self):
|
||||
chain(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "delayed-mousemove-mouseup")
|
||||
|
@ -4,10 +4,10 @@
|
||||
|
||||
from marionette_driver.by import By
|
||||
|
||||
from marionette_harness import MarionetteTestCase, WindowManagerMixin
|
||||
from marionette_harness import MarionetteTestCase, skip, WindowManagerMixin
|
||||
|
||||
|
||||
''' Disabled in bug 896043 and when working on Chrome code re-enable for bug 896046
|
||||
@skip("Disabled in bug 896043 and when working on Chrome code re-enable for bug 896046")
|
||||
class TestTextChrome(WindowManagerMixin, MarionetteTestCase):
|
||||
|
||||
def setUp(self):
|
||||
@ -42,4 +42,3 @@ class TestTextChrome(WindowManagerMixin, MarionetteTestCase):
|
||||
self.assertEqual("test", box.text)
|
||||
box.send_keys("at")
|
||||
self.assertEqual("attest", box.text)
|
||||
'''
|
||||
|
@ -33,14 +33,14 @@ class TestMessageSequencing(MarionetteTestCase):
|
||||
self.marionette.client.send(cmd)
|
||||
return self.last_id
|
||||
|
||||
@skip_unless_protocol(lambda level: level >= 3)
|
||||
@skip_unless_protocol("Skip for level < 3", lambda level: level >= 3)
|
||||
def test_discard_older_messages(self):
|
||||
first = self.send(*get_current_url)
|
||||
second = self.send(*execute_script)
|
||||
resp = self.marionette.client.receive()
|
||||
self.assertEqual(second, resp.id)
|
||||
|
||||
@skip_unless_protocol(lambda level: level >= 3)
|
||||
@skip_unless_protocol("Skip for level < 3", lambda level: level >= 3)
|
||||
def test_last_id_incremented(self):
|
||||
before = self.last_id
|
||||
self.send(*get_current_url)
|
||||
|
@ -8,7 +8,7 @@ from marionette_driver.by import By
|
||||
from marionette_driver.errors import ElementNotVisibleException
|
||||
from marionette_driver.keys import Keys
|
||||
|
||||
from marionette_harness import MarionetteTestCase, skip_if_mobile
|
||||
from marionette_harness import MarionetteTestCase, skip, skip_if_mobile
|
||||
|
||||
|
||||
def inline(doc):
|
||||
@ -32,7 +32,7 @@ class TestTypingChrome(TypingTestCase):
|
||||
super(TestTypingChrome, self).setUp()
|
||||
self.marionette.set_context("chrome")
|
||||
|
||||
@skip_if_mobile # Interacting with chrome elements not available for Fennec
|
||||
@skip_if_mobile("Interacting with chrome elements not available for Fennec")
|
||||
def test_cut_and_paste_shortcuts(self):
|
||||
with self.marionette.using_context("content"):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
@ -213,7 +213,7 @@ class TestTypingContent(TypingTestCase):
|
||||
# filled, we're a letter short here
|
||||
self.assertEqual(result.text, "I like chees")
|
||||
|
||||
@skip_if_mobile # Bug 1324752 - Arrow keys cannot be sent in Fennec
|
||||
@skip_if_mobile("Bug 1324752 - Arrow keys cannot be sent in Fennec")
|
||||
def testShouldReportKeyCodeOfArrowKeysUpDownEvents(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
self.marionette.navigate(test_html)
|
||||
@ -241,7 +241,7 @@ class TestTypingContent(TypingTestCase):
|
||||
# And leave no rubbish/printable keys in the "keyReporter"
|
||||
self.assertEqual("", element.get_property("value"))
|
||||
|
||||
"""Disabled. Reenable in Bug 1068728
|
||||
@skip("Reenable in Bug 1068728")
|
||||
def testNumericShiftKeys(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
self.marionette.navigate(test_html)
|
||||
@ -252,7 +252,6 @@ class TestTypingContent(TypingTestCase):
|
||||
element.send_keys(numericShiftsEtc)
|
||||
self.assertEqual(numericShiftsEtc, element.get_property("value"))
|
||||
self.assertIn(" up: 16", result.text.strip())
|
||||
"""
|
||||
|
||||
def testLowerCaseAlphaKeys(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
@ -263,7 +262,7 @@ class TestTypingContent(TypingTestCase):
|
||||
element.send_keys(lowerAlphas)
|
||||
self.assertEqual(lowerAlphas, element.get_property("value"))
|
||||
|
||||
"""Disabled. Reenable in Bug 1068735
|
||||
@skip("Reenable in Bug 1068735")
|
||||
def testUppercaseAlphaKeys(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
self.marionette.navigate(test_html)
|
||||
@ -274,9 +273,8 @@ class TestTypingContent(TypingTestCase):
|
||||
element.send_keys(upperAlphas)
|
||||
self.assertEqual(upperAlphas, element.get_property("value"))
|
||||
self.assertIn(" up: 16", result.text.strip())
|
||||
"""
|
||||
|
||||
"""Disabled. Reenable in Bug 1068726
|
||||
@skip("Reenable in Bug 1068726")
|
||||
def testAllPrintableKeys(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
self.marionette.navigate(test_html)
|
||||
@ -288,9 +286,8 @@ class TestTypingContent(TypingTestCase):
|
||||
|
||||
self.assertTrue(allPrintable, element.get_property("value"))
|
||||
self.assertIn(" up: 16", result.text.strip())
|
||||
"""
|
||||
|
||||
"""Disabled. Reenable in Bug 1068733
|
||||
@skip("Reenable in Bug 1068733")
|
||||
def testSpecialSpaceKeys(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
self.marionette.navigate(test_html)
|
||||
@ -298,7 +295,6 @@ class TestTypingContent(TypingTestCase):
|
||||
element = self.marionette.find_element(By.ID, "keyReporter")
|
||||
element.send_keys("abcd" + Keys.SPACE + "fgh" + Keys.SPACE + "ij")
|
||||
self.assertEqual("abcd fgh ij", element.get_property("value"))
|
||||
"""
|
||||
|
||||
def testShouldTypeAnInteger(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
|
@ -7,6 +7,7 @@
|
||||
[test_expectedfail.py]
|
||||
expected = fail
|
||||
[test_import_script.py]
|
||||
[test_certificates.py]
|
||||
[test_click.py]
|
||||
[test_click_chrome.py]
|
||||
skip-if = appname == 'fennec'
|
||||
|
@ -9,6 +9,6 @@ moznetwork >= 0.21
|
||||
mozprocess >= 0.9
|
||||
mozprofile >= 0.7
|
||||
mozrunner >= 6.13
|
||||
moztest >= 0.7
|
||||
moztest >= 0.8
|
||||
mozversion >= 1.1
|
||||
wptserve >= 1.3.0
|
||||
|
@ -12,6 +12,8 @@ module.exports = {
|
||||
|
||||
// All globals made available in the test environment.
|
||||
"globals": {
|
||||
// $ is defined in SimpleTest.js
|
||||
"$": false,
|
||||
"add_task": false,
|
||||
"Assert": false,
|
||||
"EventUtils": false,
|
||||
@ -25,6 +27,7 @@ module.exports = {
|
||||
"is": false,
|
||||
"isDeeply": false,
|
||||
"isnot": false,
|
||||
"netscape": false,
|
||||
"ok": false,
|
||||
"promise": false,
|
||||
"registerCleanupFunction": false,
|
||||
|
@ -134,7 +134,7 @@ class StructuredTestResult(TextTestResult):
|
||||
extra=extra)
|
||||
|
||||
def addFailure(self, test, err):
|
||||
extra = self.call_callbacks(test, "ERROR")
|
||||
extra = self.call_callbacks(test, "FAIL")
|
||||
extra.update(self._get_class_method_name(test))
|
||||
self.logger.test_end(test.id(),
|
||||
"FAIL",
|
||||
@ -145,10 +145,13 @@ class StructuredTestResult(TextTestResult):
|
||||
|
||||
def addSuccess(self, test):
|
||||
extra = self._get_class_method_name(test)
|
||||
self.logger.test_end(test.id(), "PASS", expected="PASS", extra=extra)
|
||||
self.logger.test_end(test.id(),
|
||||
"PASS",
|
||||
expected="PASS",
|
||||
extra=extra)
|
||||
|
||||
def addExpectedFailure(self, test, err):
|
||||
extra = self.call_callbacks(test, "ERROR")
|
||||
extra = self.call_callbacks(test, "FAIL")
|
||||
extra.update(self._get_class_method_name(test))
|
||||
self.logger.test_end(test.id(),
|
||||
"FAIL",
|
||||
@ -158,7 +161,7 @@ class StructuredTestResult(TextTestResult):
|
||||
extra=extra)
|
||||
|
||||
def addUnexpectedSuccess(self, test):
|
||||
extra = self.call_callbacks(test, "ERROR")
|
||||
extra = self.call_callbacks(test, "PASS")
|
||||
extra.update(self._get_class_method_name(test))
|
||||
self.logger.test_end(test.id(),
|
||||
"PASS",
|
||||
@ -166,7 +169,7 @@ class StructuredTestResult(TextTestResult):
|
||||
extra=extra)
|
||||
|
||||
def addSkip(self, test, reason):
|
||||
extra = self.call_callbacks(test, "ERROR")
|
||||
extra = self.call_callbacks(test, "SKIP")
|
||||
extra.update(self._get_class_method_name(test))
|
||||
self.logger.test_end(test.id(),
|
||||
"SKIP",
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
PACKAGE_VERSION = '0.7'
|
||||
PACKAGE_VERSION = '0.8'
|
||||
|
||||
# dependencies
|
||||
deps = ['mozinfo']
|
||||
|
@ -8,10 +8,12 @@ module.exports = {
|
||||
|
||||
// All globals made available in the test environment.
|
||||
"globals": {
|
||||
"_TEST_FILE": false,
|
||||
"add_task": false,
|
||||
"add_test": false,
|
||||
"Assert": false,
|
||||
"deepEqual": false,
|
||||
"do_await_remote_message": false,
|
||||
"do_check_eq": false,
|
||||
"do_check_false": false,
|
||||
"do_check_matches": false,
|
||||
@ -30,6 +32,7 @@ module.exports = {
|
||||
"do_print": false,
|
||||
"do_register_cleanup": false,
|
||||
"do_report_unexpected_exception": false,
|
||||
"do_send_remote_message": false,
|
||||
"do_test_finished": false,
|
||||
"do_test_pending": false,
|
||||
"do_throw": false,
|
||||
@ -45,6 +48,7 @@ module.exports = {
|
||||
"notEqual": false,
|
||||
"notStrictEqual": false,
|
||||
"ok": false,
|
||||
"runningInParent": false,
|
||||
"run_next_test": false,
|
||||
"run_test": false,
|
||||
"run_test_in_child": false,
|
||||
@ -53,5 +57,8 @@ module.exports = {
|
||||
"todo": false,
|
||||
"todo_check_false": false,
|
||||
"todo_check_true": false,
|
||||
// Firefox specific function.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/uneval
|
||||
"uneval": false,
|
||||
}
|
||||
};
|
||||
|
@ -208,5 +208,6 @@ module.exports = {
|
||||
"dump": true,
|
||||
"openDialog": false,
|
||||
"sizeToContent": false,
|
||||
"ChromeWorker": false,
|
||||
}
|
||||
};
|
||||
|
@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
|
||||
]
|
||||
};
|
@ -92,7 +92,7 @@ function onload()
|
||||
// use childnodes here, the text can wrap
|
||||
for (var i = 1; i < messageParagraphs.length; i++) {
|
||||
var descriptionNode = document.createElement("description");
|
||||
text = document.createTextNode(messageParagraphs[i]);
|
||||
let text = document.createTextNode(messageParagraphs[i]);
|
||||
descriptionNode.appendChild(text);
|
||||
messageParent.appendChild(descriptionNode);
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ function run_test()
|
||||
// if we want to avoid tests overlapping.
|
||||
function test_cycles(size, tc) {
|
||||
// Now, restart this with unreferenced cycles
|
||||
for (i = 0; i < size / 2; ++i) {
|
||||
for (let i = 0; i < size / 2; ++i) {
|
||||
let a = {
|
||||
a: ctypes.CDataFinalizer(tc.acquire(i * 2), tc.release),
|
||||
b: {
|
||||
@ -325,7 +325,7 @@ function test_result_dispose(size, tc, cleanup) {
|
||||
}
|
||||
do_check_eq(count_finalized(size, tc), 0);
|
||||
|
||||
for (i = 0; i < size; ++i) {
|
||||
for (let i = 0; i < size; ++i) {
|
||||
let witness = ref[i].dispose();
|
||||
ref[i] = null;
|
||||
if (!tc.released(i, witness)) {
|
||||
@ -367,7 +367,7 @@ function test_executing_dispose(size, tc, cleanup)
|
||||
ref = [];
|
||||
|
||||
// Re-acquire data and make sure that everything has been reinialized
|
||||
for (i = 0; i < size; ++i) {
|
||||
for (let i = 0; i < size; ++i) {
|
||||
tc.acquire(i);
|
||||
}
|
||||
|
||||
@ -449,4 +449,3 @@ function test_do_not_execute_finalizers_on_referenced_stuff(size, tc, cleanup)
|
||||
// Check that _nothing_ has been finalized
|
||||
do_check_eq(count_finalized(size, tc), 0);
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@ try {
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
CTYPES_TEST_LIB = ctypes.libraryName("jsctypes-test");
|
||||
CTYPES_UNICODE_LIB = ctypes.libraryName("jsctyp\u00E8s-t\u00EB\u00DFt");
|
||||
const CTYPES_TEST_LIB = ctypes.libraryName("jsctypes-test");
|
||||
const CTYPES_UNICODE_LIB = ctypes.libraryName("jsctyp\u00E8s-t\u00EB\u00DFt");
|
||||
|
||||
function do_check_throws(f, type, stack)
|
||||
{
|
||||
@ -72,9 +72,9 @@ function run_test()
|
||||
run_float_tests(library, ctypes.double, "double", 8);
|
||||
|
||||
// Test the wrapped integer types.
|
||||
s64limits = ["-9223372036854775808", "9223372036854775807",
|
||||
"-9223372036854775809", "9223372036854775808"];
|
||||
u64limits = ["0", "18446744073709551615", "-1", "18446744073709551616"];
|
||||
const s64limits = ["-9223372036854775808", "9223372036854775807",
|
||||
"-9223372036854775809", "9223372036854775808"];
|
||||
const u64limits = ["0", "18446744073709551615", "-1", "18446744073709551616"];
|
||||
|
||||
run_wrapped_integer_tests(library, ctypes.int64_t, "int64_t", 8, true,
|
||||
ctypes.Int64, "ctypes.Int64", s64limits);
|
||||
@ -85,8 +85,8 @@ function run_test()
|
||||
run_wrapped_integer_tests(library, ctypes.unsigned_long_long, "unsigned_long_long", 8, false,
|
||||
ctypes.UInt64, "ctypes.UInt64", u64limits);
|
||||
|
||||
s32limits = [-0x80000000, 0x7fffffff, -0x80000001, 0x80000000];
|
||||
u32limits = [0, 0xffffffff, -1, 0x100000000];
|
||||
const s32limits = [-0x80000000, 0x7fffffff, -0x80000001, 0x80000000];
|
||||
const u32limits = [0, 0xffffffff, -1, 0x100000000];
|
||||
|
||||
let slimits, ulimits;
|
||||
if (ctypes.long.size == 8) {
|
||||
@ -1771,7 +1771,7 @@ function run_PointerType_tests() {
|
||||
" can be converted to " + item_type + " array");
|
||||
|
||||
// Convert ArrayBuffer to array of the right size and check contents
|
||||
c_array = array_type(c_arraybuffer);
|
||||
let c_array = array_type(c_arraybuffer);
|
||||
for (let k = 0; k < number_of_items; ++k) {
|
||||
do_check_eq(c_array[k], view[k]);
|
||||
}
|
||||
@ -2690,14 +2690,14 @@ function run_variadic_tests(library) {
|
||||
|
||||
do_check_eq(result.value, 3 + 5 + 7 + 11);
|
||||
|
||||
result = ctypes.int32_t.array(3)([1, 1, 1]),
|
||||
v1 = ctypes.int32_t.array(4)([1, 2, 3, 5]),
|
||||
v2 = ctypes.int32_t.array(3)([7, 11, 13]),
|
||||
vector_add_va = library.declare("test_vector_add_va_cdecl",
|
||||
result = ctypes.int32_t.array(3)([1, 1, 1]);
|
||||
let v1 = ctypes.int32_t.array(4)([1, 2, 3, 5]);
|
||||
let v2 = ctypes.int32_t.array(3)([7, 11, 13]);
|
||||
let vector_add_va = library.declare("test_vector_add_va_cdecl",
|
||||
ctypes.default_abi, ctypes.int32_t.ptr,
|
||||
ctypes.uint8_t, ctypes.uint8_t, "..."),
|
||||
ctypes.uint8_t, ctypes.uint8_t, "...");
|
||||
// Note that vector_add_va zeroes out result first.
|
||||
vec_sum = vector_add_va(2, 3, result, v1, v2);
|
||||
let vec_sum = vector_add_va(2, 3, result, v1, v2);
|
||||
do_check_eq(vec_sum.contents, 8);
|
||||
do_check_eq(result[0], 8);
|
||||
do_check_eq(result[1], 13);
|
||||
|
@ -8,7 +8,6 @@ module.exports = { // eslint-disable-line no-undef
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"ChromeWorker": false,
|
||||
"onmessage": true,
|
||||
"sendAsyncMessage": false,
|
||||
|
||||
|
@ -155,7 +155,7 @@ function bagHasKey(bag, key) {
|
||||
function makePropGetter(key) {
|
||||
return function FeedPropGetter(bag) {
|
||||
try {
|
||||
return value = bag.getProperty(key);
|
||||
return bag.getProperty(key);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const DEBUG = false; /* set to true to enable debug messages */
|
||||
var debug;
|
||||
|
||||
const LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1";
|
||||
const APPSHELL_SERV_CONTRACTID = "@mozilla.org/appshell/appShellService;1";
|
||||
|
@ -4,9 +4,11 @@
|
||||
/*
|
||||
* Initialization specific to Form Autofill xpcshell tests.
|
||||
*
|
||||
* This file is loaded by "loader.js".
|
||||
* This file is loaded alongside loader.js.
|
||||
*/
|
||||
|
||||
/* import-globals-from loader.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
// The testing framework is fully initialized at this point, you can add
|
||||
|
@ -17,6 +17,7 @@ var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
||||
Cu.import("resource://gre/modules/Services.jsm", this);
|
||||
|
||||
/* import-globals-from ../loader_common.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
Services.io.newFileURI(do_get_file("loader_common.js")).spec, this);
|
||||
|
||||
@ -33,6 +34,7 @@ var add_task_in_parent_process = add_task;
|
||||
var add_task_in_child_process = function() {};
|
||||
var add_task_in_both_processes = add_task;
|
||||
|
||||
/* import-globals-from ../head_common.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
Services.io.newFileURI(do_get_file("head_common.js")).spec, this);
|
||||
|
||||
|
@ -88,6 +88,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "gPrintSettingsService",
|
||||
"@mozilla.org/gfx/printsettings-service;1",
|
||||
Ci.nsIPrintSettingsService);
|
||||
|
||||
/* global DownloadIntegration */
|
||||
Integration.downloads.defineModuleGetter(this, "DownloadIntegration",
|
||||
"resource://gre/modules/DownloadIntegration.jsm");
|
||||
|
||||
|
@ -38,6 +38,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
/* global DownloadIntegration */
|
||||
Integration.downloads.defineModuleGetter(this, "DownloadIntegration",
|
||||
"resource://gre/modules/DownloadIntegration.jsm");
|
||||
|
||||
|
@ -9,6 +9,9 @@
|
||||
* the "copy" and "legacy" saver implementations.
|
||||
*/
|
||||
|
||||
/* import-globals-from head.js */
|
||||
/* global gUseLegacySaver */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Globals
|
||||
|
@ -48,6 +48,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "gExternalHelperAppService",
|
||||
"@mozilla.org/uriloader/external-helper-app-service;1",
|
||||
Ci.nsIExternalHelperAppService);
|
||||
|
||||
/* global DownloadIntegration */
|
||||
Integration.downloads.defineModuleGetter(this, "DownloadIntegration",
|
||||
"resource://gre/modules/DownloadIntegration.jsm");
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
|
7
toolkit/components/mozintl/test/.eslintrc.js
Normal file
7
toolkit/components/mozintl/test/.eslintrc.js
Normal file
@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../testing/xpcshell/xpcshell.eslintrc.js"
|
||||
]
|
||||
};
|
@ -833,7 +833,7 @@ nsPlacesExpiration.prototype = {
|
||||
memSizeBytes = Services.sysinfo.getProperty("memsize");
|
||||
} catch (ex) {}
|
||||
if (memSizeBytes <= 0) {
|
||||
memsize = MEMSIZE_FALLBACK_BYTES;
|
||||
memSizeBytes = MEMSIZE_FALLBACK_BYTES;
|
||||
}
|
||||
|
||||
let diskAvailableBytes = DISKSIZE_FALLBACK_BYTES;
|
||||
|
@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Import common head.
|
||||
{
|
||||
/* import-globals-from ../head_common.js */
|
||||
let commonFile = do_get_file("../head_common.js", false);
|
||||
let uri = Services.io.newFileURI(commonFile);
|
||||
Services.scriptloader.loadSubScript(uri.spec, this);
|
||||
|
@ -58,7 +58,7 @@ add_task(function* test_same_date_diff_hash() {
|
||||
let backupFile = OS.Path.join(backupFolder, filename);
|
||||
yield OS.File.move(tempPath, backupFile);
|
||||
yield PlacesBackups.create(); // Force compressed backup
|
||||
mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
let mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
|
||||
// Decode lz4 compressed file to json and check if json is valid
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
|
@ -46,7 +46,7 @@ add_task(function*() {
|
||||
// backup will replace the existing one.
|
||||
yield PlacesBackups.create(undefined, true);
|
||||
do_check_eq(backupFiles.length, 1);
|
||||
recentBackup = yield PlacesBackups.getMostRecentBackup();
|
||||
let recentBackup = yield PlacesBackups.getMostRecentBackup();
|
||||
do_check_neq(recentBackup, OS.Path.join(backupFolder, oldBackupName));
|
||||
matches = OS.Path.basename(recentBackup).match(PlacesBackups.filenamesRegex);
|
||||
do_check_eq(matches[1], PlacesBackups.toISODateString(new Date()));
|
||||
|
@ -43,7 +43,7 @@ add_task(function* test_saveBookmarksToJSONFile_and_create()
|
||||
yield PlacesBackups.create();
|
||||
do_check_eq((yield PlacesBackups.getBackupFiles()).length, 1);
|
||||
|
||||
mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
let mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
do_check_neq(mostRecentBackupFile, null);
|
||||
matches = OS.Path.basename(recentBackup).match(PlacesBackups.filenamesRegex);
|
||||
do_check_eq(matches[2], nodeCount);
|
||||
@ -54,4 +54,3 @@ add_task(function* test_saveBookmarksToJSONFile_and_create()
|
||||
yield PlacesBackups.create(0);
|
||||
PlacesUtils.bookmarks.removeItem(bookmarkId);
|
||||
});
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user