Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2016-08-09 15:47:44 +02:00
Родитель f906e9a8e1 d9e0b4c565
Коммит c4b39a49eb
401 изменённых файлов: 3712 добавлений и 2019 удалений

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

@ -122,6 +122,7 @@ devtools/server/actors/**
devtools/server/performance/**
devtools/server/tests/**
devtools/shared/*.js
!devtools/shared/async-storage.js
!devtools/shared/async-utils.js
!devtools/shared/css-lexer.js
!devtools/shared/defer.js

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

@ -26,6 +26,7 @@ support-files =
[browser_newtab_disable.js]
[browser_newtab_drag_drop.js]
[browser_newtab_drag_drop_ext.js]
subsuite = clipboard # temporary until determine why more intermittent on VM
[browser_newtab_drop_preview.js]
[browser_newtab_enhanced.js]
[browser_newtab_focus.js]

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

@ -1746,7 +1746,12 @@
let stopEvent = false;
// Tab cycles through the one-offs and moves the focus out at the end.
if (event.keyCode == KeyEvent.DOM_VK_TAB) {
// But only if non-Shift modifiers aren't also pressed, to avoid
// clobbering other shortcuts.
if (event.keyCode == KeyEvent.DOM_VK_TAB &&
!event.altKey &&
!event.ctrlKey &&
!event.metaKey) {
stopEvent = this.advanceSelection(!event.shiftKey, false, true);
}

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

@ -166,6 +166,8 @@
/* CONTENT */
.identity-popup-permission-label,
.identity-popup-permission-state-label,
#identity-popup-security-content > description,
#identity-popup-security-descriptions > description,
#identity-popup-securityView-header > description,
@ -384,6 +386,7 @@ description#identity-popup-content-verifier,
}
.identity-popup-permission-state-label {
margin-inline-end: 5px;
text-align: end;
opacity: 0.6;
}
@ -395,6 +398,7 @@ description#identity-popup-content-verifier,
border-radius: 50%;
min-width: 0;
padding: 2px;
background-color: transparent;
}
.identity-popup-permission-remove-button > .button-box {

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

@ -49,34 +49,11 @@ AC_DEFUN([MOZ_CROSS_COMPILER],
[
echo "cross compiling from $host to $target"
_SAVE_CC="$CC"
_SAVE_CFLAGS="$CFLAGS"
_SAVE_LDFLAGS="$LDFLAGS"
if test -z "$HOST_AR_FLAGS"; then
HOST_AR_FLAGS="$AR_FLAGS"
fi
AC_CHECK_PROGS(HOST_RANLIB, $HOST_RANLIB ranlib, ranlib, :)
AC_CHECK_PROGS(HOST_AR, $HOST_AR ar, ar, :)
CC="$HOST_CC"
CFLAGS="$HOST_CFLAGS"
LDFLAGS="$HOST_LDFLAGS"
AC_MSG_CHECKING([whether the host c compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works])
AC_TRY_COMPILE([], [return(0);],
[ac_cv_prog_hostcc_works=1 AC_MSG_RESULT([yes])],
AC_MSG_ERROR([installation or configuration problem: host compiler $HOST_CC cannot create executables.]) )
CC="$HOST_CXX"
CFLAGS="$HOST_CXXFLAGS"
AC_MSG_CHECKING([whether the host c++ compiler ($HOST_CXX $HOST_CXXFLAGS $HOST_LDFLAGS) works])
AC_TRY_COMPILE([], [return(0);],
[ac_cv_prog_hostcxx_works=1 AC_MSG_RESULT([yes])],
AC_MSG_ERROR([installation or configuration problem: host compiler $HOST_CXX cannot create executables.]) )
CC=$_SAVE_CC
CFLAGS=$_SAVE_CFLAGS
LDFLAGS=$_SAVE_LDFLAGS
dnl AC_CHECK_PROGS manually goes through $PATH, and as such fails to handle
dnl absolute or relative paths. Relative paths wouldn't work anyways, but

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

@ -60,7 +60,7 @@ def checking(what, callback=None):
log.info('no')
else:
log.info(display_ret)
if error:
if error is not None:
die(error)
return ret
return wrapped

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

@ -18,47 +18,14 @@
# - `check_msg` is the message to be printed to accompany compiling the test
# program.
@template
@imports('textwrap')
def try_compile(includes=None, body='', language='C++', flags=None, check_msg=None):
includes = includes or []
source_lines = ['#include <%s>' % f for f in includes]
source = '\n'.join(source_lines) + '\n'
source += textwrap.dedent('''\
int
main(void)
{
%s
;
return 0;
}
''' % body)
compiler = {
'C': c_compiler,
'C++': cxx_compiler,
}[language]
if check_msg:
def checking_fn(fn):
return checking(check_msg, callback=lambda r: r is not None)(fn)
else:
def checking_fn(fn):
return fn
return compiler.try_compile(includes, body, flags, check_msg)
def get_flags():
if flags:
return flags[:]
@depends(cxx_compiler, c_compiler, extra_toolchain_flags)
@checking_fn
def check(cxx_info, c_info, extra_flags):
flags = get_flags() or []
flags += extra_flags
flags.append('-c')
info = {
'C': c_info,
'C++': cxx_info,
}[language]
return try_invoke_compiler(info.wrapper + [info.compiler] + info.flags,
language, source, flags,
onerror=lambda: None)
return check
# Checks for the presence of the given header on the target system by compiling
# a test program including that header. The return value of the template is a

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

@ -0,0 +1,65 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
@template
@imports('textwrap')
@imports(_from='mozbuild.configure', _import='DependsFunction')
def compiler_class(compiler):
class Compiler(DependsFunction):
# Generates a test program and attempts to compile it. In case of
# failure, the resulting check will return None. If the test program
# succeeds, it will return the output of the test program.
# - `includes` are the includes (as file names) that will appear at the
# top of the generated test program.
# - `body` is the code that will appear in the main function of the
# generated test program. `return 0;` is appended to the function
# body automatically.
# - `flags` are the flags to be passed to the compiler, in addition to
# `-c`.
# - `check_msg` is the message to be printed to accompany compiling the
# test program.
def try_compile(self, includes=None, body='', flags=None,
check_msg=None, onerror=lambda: None):
includes = includes or []
source_lines = ['#include <%s>' % f for f in includes]
source = '\n'.join(source_lines) + '\n'
source += textwrap.dedent('''\
int
main(void)
{
%s
;
return 0;
}
''' % body)
if check_msg:
def checking_fn(fn):
return checking(check_msg,
callback=lambda r: r is not None)(fn)
else:
def checking_fn(fn):
return fn
def get_flags():
if flags:
return flags[:]
@depends(self, extra_toolchain_flags)
@checking_fn
def func(compiler, extra_flags):
flags = get_flags() or []
flags += extra_flags
flags.append('-c')
return try_invoke_compiler(
compiler.wrapper + [compiler.compiler] + compiler.flags,
compiler.language, source, flags, onerror=onerror)
return func
compiler.__class__ = Compiler
return compiler

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

@ -171,6 +171,8 @@ add_old_configure_assignment('TOOLCHAIN_PREFIX', toolchain_prefix)
# Compilers
# ==============================================================
include('compilers-util.configure')
def try_preprocess(compiler, language, source):
return try_invoke_compiler(compiler, language, source, ['-E'])
@ -533,7 +535,7 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
'C++': lambda: default_cxx_compilers(c_compiler),
}[language]()
what='the %s %s compiler' % (host_or_target_str, language),
what='the %s %s compiler' % (host_or_target_str, language)
option(env=var, nargs=1, help='Path to %s' % what)
@ -697,6 +699,7 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
flags=flags,
type=info.type,
version=info.version,
language=language,
)
@depends(valid_compiler)
@ -735,6 +738,15 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
add_old_configure_assignment(
'%s_VERSION' % var, delayed_getattr(valid_compiler, 'version'))
valid_compiler = compiler_class(valid_compiler)
def compiler_error():
raise FatalCheckError('Failed compiling a simple %s source with %s'
% (language, what))
valid_compiler.try_compile(check_msg='%s works' % what,
onerror=compiler_error)
return valid_compiler

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

@ -15,6 +15,7 @@
"dump": true,
"exports": true,
"isWorker": true,
"indexedDB": true,
"loader": true,
"module": true,
"reportError": true,

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

@ -1168,7 +1168,6 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
*/
_onConditionalPopupShowing: function () {
this._conditionalPopupVisible = true; // Used in tests.
window.emit(EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
},
/**
@ -1177,6 +1176,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
_onConditionalPopupShown: function () {
this._cbTextbox.focus();
this._cbTextbox.select();
window.emit(EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN);
},
/**
@ -1199,6 +1199,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
*/
_onConditionalPopupHidden: function () {
this._cbPanel.hidden = true;
window.emit(EVENTS.CONDITIONAL_BREAKPOINT_POPUP_HIDDEN);
},
/**

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

@ -51,9 +51,9 @@ const EVENTS = {
BREAKPOINT_HIDDEN_IN_EDITOR: "Debugger:BreakpointHiddenInEditor",
BREAKPOINT_HIDDEN_IN_PANE: "Debugger:BreakpointHiddenInPane",
// When a conditional breakpoint's popup is showing or hiding.
CONDITIONAL_BREAKPOINT_POPUP_SHOWING: "Debugger:ConditionalBreakpointPopupShowing",
CONDITIONAL_BREAKPOINT_POPUP_HIDING: "Debugger:ConditionalBreakpointPopupHiding",
// When a conditional breakpoint's popup is shown/hidden.
CONDITIONAL_BREAKPOINT_POPUP_SHOWN: "Debugger:ConditionalBreakpointPopupShown",
CONDITIONAL_BREAKPOINT_POPUP_HIDDEN: "Debugger:ConditionalBreakpointPopupHidden",
// When event listeners are fetched or event breakpoints are updated.
EVENT_LISTENERS_FETCHED: "Debugger:EventListenersFetched",

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

@ -616,7 +616,11 @@ skip-if = e10s && debug
skip-if = e10s && debug
[browser_dbg_watch-expressions-02.js]
skip-if = e10s && debug
[browser_dbg_worker-console.js]
[browser_dbg_worker-console-01.js]
skip-if = e10s && debug
[browser_dbg_worker-console-02.js]
skip-if = e10s && debug
[browser_dbg_worker-console-03.js]
skip-if = e10s && debug
[browser_dbg_worker-source-map.js]
skip-if = e10s && debug

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

@ -24,6 +24,7 @@ function test() {
const constants = gDebugger.require("./content/constants");
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
const CONDITIONAL_POPUP_SHOWN = gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN;
// This test forces conditional breakpoints to be evaluated on the
// client-side
@ -43,23 +44,32 @@ function test() {
function modBreakpoint2() {
setCaretPosition(19);
let popupShown = waitForDebuggerEvents(gPanel, CONDITIONAL_POPUP_SHOWN);
gSources._onCmdAddConditionalBreakpoint();
return popupShown;
}
function addBreakpoint3() {
function* addBreakpoint3() {
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
let popupShown = waitForDebuggerEvents(gPanel, CONDITIONAL_POPUP_SHOWN);
setCaretPosition(20);
gSources._onCmdAddConditionalBreakpoint();
return finished;
yield finished;
yield popupShown;
}
function modBreakpoint3() {
let finished = waitForDispatch(gPanel, constants.SET_BREAKPOINT_CONDITION);
function* modBreakpoint3() {
setCaretPosition(20);
let popupShown = waitForDebuggerEvents(gPanel, CONDITIONAL_POPUP_SHOWN);
gSources._onCmdAddConditionalBreakpoint();
yield popupShown;
typeText(gSources._cbTextbox, "bamboocha");
let finished = waitForDispatch(gPanel, constants.SET_BREAKPOINT_CONDITION);
EventUtils.sendKey("RETURN", gDebugger);
return finished;
yield finished;
}
function addBreakpoint4() {

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

@ -49,7 +49,7 @@ function test() {
const bp = queries.getBreakpoint(getState(), location);
is(bp.condition, "hello", "The conditional expression is correct.");
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);
@ -63,7 +63,7 @@ function test() {
yield actions.setBreakpointCondition(location, "foo");
yield actions.addBreakpoint(location);
finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);

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

@ -24,6 +24,7 @@ function test() {
const constants = gDebugger.require("./content/constants");
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
const CONDITIONAL_POPUP_SHOWN = gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN;
function addBreakpoint1() {
return actions.addBreakpoint({ actor: gSources.selectedValue, line: 18 });
@ -38,23 +39,34 @@ function test() {
function modBreakpoint2() {
setCaretPosition(19);
let popupShown = waitForDebuggerEvents(gPanel, CONDITIONAL_POPUP_SHOWN);
gSources._onCmdAddConditionalBreakpoint();
return popupShown;
}
function addBreakpoint3() {
function* addBreakpoint3() {
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
let popupShown = waitForDebuggerEvents(gPanel, CONDITIONAL_POPUP_SHOWN);
setCaretPosition(20);
gSources._onCmdAddConditionalBreakpoint();
return finished;
yield finished;
yield popupShown;
}
function modBreakpoint3() {
let finished = waitForDispatch(gPanel, constants.SET_BREAKPOINT_CONDITION);
function* modBreakpoint3() {
setCaretPosition(20);
let popupShown = waitForDebuggerEvents(gPanel, CONDITIONAL_POPUP_SHOWN);
gSources._onCmdAddConditionalBreakpoint();
yield popupShown;
typeText(gSources._cbTextbox, "bamboocha");
let finished = waitForDispatch(gPanel, constants.SET_BREAKPOINT_CONDITION);
EventUtils.sendKey("RETURN", gDebugger);
return finished;
yield finished;
}
function addBreakpoint4() {

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

@ -46,7 +46,7 @@ function test() {
const bp = queries.getBreakpoint(getState(), location);
is(bp.condition, "hello", "The conditional expression is correct.");
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);
@ -60,7 +60,7 @@ function test() {
yield actions.setBreakpointCondition(location, "foo");
yield actions.addBreakpoint(location);
finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);

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

@ -0,0 +1,21 @@
// Check to make sure that a worker can be attached to a toolbox
// and that the console works.
var TAB_URL = EXAMPLE_URL + "doc_WorkerActor.attachThread-tab.html";
var WORKER_URL = "code_WorkerActor.attachThread-worker.js";
add_task(function* testNormalExecution() {
let {client, tab, tabClient, workerClient, toolbox, gDebugger} =
yield initWorkerDebugger(TAB_URL, WORKER_URL);
let jsterm = yield getSplitConsole(toolbox);
let executed = yield jsterm.execute("this.location.toString()");
ok(executed.textContent.includes(WORKER_URL),
"Evaluating the global's location works");
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
yield close(client);
yield removeTab(tab);
});

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

@ -0,0 +1,59 @@
// Check to make sure that a worker can be attached to a toolbox
// and that the console works.
var TAB_URL = EXAMPLE_URL + "doc_WorkerActor.attachThread-tab.html";
var WORKER_URL = "code_WorkerActor.attachThread-worker.js";
add_task(function* testWhilePaused() {
let {client, tab, tabClient, workerClient, toolbox, gDebugger} =
yield initWorkerDebugger(TAB_URL, WORKER_URL);
let gTarget = gDebugger.gTarget;
let gResumeButton = gDebugger.document.getElementById("resume");
let gResumeKey = gDebugger.document.getElementById("resumeKey");
// Execute some basic math to make sure evaluations are working.
let jsterm = yield getSplitConsole(toolbox);
let executed = yield jsterm.execute("10000+1");
ok(executed.textContent.includes("10001"), "Text for message appeared correct");
// Pause the worker by waiting for next execution and then sending a message to
// it from the main thread.
let oncePaused = gTarget.once("thread-paused");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
once(gDebugger.gClient, "willInterrupt").then(() => {
info("Posting message to worker, then waiting for a pause");
postMessageToWorkerInTab(tab, WORKER_URL, "ping");
});
yield oncePaused;
let command1 = jsterm.execute("10000+2");
let command2 = jsterm.execute("10000+3");
let command3 = jsterm.execute("foobar"); // throw an error
info("Trying to get the result of command1");
executed = yield command1;
ok(executed.textContent.includes("10002"),
"command1 executed successfully");
info("Trying to get the result of command2");
executed = yield command2;
ok(executed.textContent.includes("10003"),
"command2 executed successfully");
info("Trying to get the result of command3");
executed = yield command3;
// XXXworkers This is failing until Bug 1215120 is resolved.
todo(executed.textContent.includes("ReferenceError: foobar is not defined"),
"command3 executed successfully");
let onceResumed = gTarget.once("thread-resumed");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
yield onceResumed;
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
yield close(client);
yield removeTab(tab);
});

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

@ -0,0 +1,46 @@
// Check to make sure that a worker can be attached to a toolbox
// and that the console works.
var TAB_URL = EXAMPLE_URL + "doc_WorkerActor.attachThread-tab.html";
var WORKER_URL = "code_WorkerActor.attachThread-worker.js";
// Test to see if creating the pause from the console works.
add_task(function* testPausedByConsole() {
let {client, tab, tabClient, workerClient, toolbox, gDebugger} =
yield initWorkerDebugger(TAB_URL, WORKER_URL);
let gTarget = gDebugger.gTarget;
let gResumeButton = gDebugger.document.getElementById("resume");
let gResumeKey = gDebugger.document.getElementById("resumeKey");
let jsterm = yield getSplitConsole(toolbox);
let executed = yield jsterm.execute("10000+1");
ok(executed.textContent.includes("10001"),
"Text for message appeared correct");
let oncePaused = gTarget.once("thread-paused");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
let pausedExecution = jsterm.execute("10000+2");
info("Executed a command with 'break on next' active, waiting for pause");
yield oncePaused;
executed = yield jsterm.execute("10000+3");
ok(executed.textContent.includes("10003"),
"Text for message appeared correct");
info("Waiting for a resume");
let onceResumed = gTarget.once("thread-resumed");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
yield onceResumed;
executed = yield pausedExecution;
ok(executed.textContent.includes("10002"),
"Text for message appeared correct");
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
yield close(client);
yield removeTab(tab);
});

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

@ -1,145 +0,0 @@
// Check to make sure that a worker can be attached to a toolbox
// and that the console works.
var TAB_URL = EXAMPLE_URL + "doc_WorkerActor.attachThread-tab.html";
var WORKER_URL = "code_WorkerActor.attachThread-worker.js";
function* initWorkerDebugger(TAB_URL, WORKER_URL) {
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
let client = new DebuggerClient(DebuggerServer.connectPipe());
yield connect(client);
let tab = yield addTab(TAB_URL);
let { tabs } = yield listTabs(client);
let [, tabClient] = yield attachTab(client, findTab(tabs, TAB_URL));
yield createWorkerInTab(tab, WORKER_URL);
let { workers } = yield listWorkers(tabClient);
let [, workerClient] = yield attachWorker(tabClient,
findWorker(workers, WORKER_URL));
let toolbox = yield gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
"jsdebugger",
Toolbox.HostType.WINDOW);
let debuggerPanel = toolbox.getCurrentPanel();
let gDebugger = debuggerPanel.panelWin;
return {client, tab, tabClient, workerClient, toolbox, gDebugger};
}
add_task(function* testNormalExecution() {
let {client, tab, tabClient, workerClient, toolbox, gDebugger} =
yield initWorkerDebugger(TAB_URL, WORKER_URL);
let jsterm = yield getSplitConsole(toolbox);
let executed = yield jsterm.execute("this.location.toString()");
ok(executed.textContent.includes(WORKER_URL),
"Evaluating the global's location works");
yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield close(client);
yield removeTab(tab);
});
add_task(function* testWhilePaused() {
let {client, tab, tabClient, workerClient, toolbox, gDebugger} =
yield initWorkerDebugger(TAB_URL, WORKER_URL);
let gTarget = gDebugger.gTarget;
let gResumeButton = gDebugger.document.getElementById("resume");
let gResumeKey = gDebugger.document.getElementById("resumeKey");
// Execute some basic math to make sure evaluations are working.
let jsterm = yield getSplitConsole(toolbox);
let executed = yield jsterm.execute("10000+1");
ok(executed.textContent.includes("10001"), "Text for message appeared correct");
// Pause the worker by waiting for next execution and then sending a message to
// it from the main thread.
let oncePaused = gTarget.once("thread-paused");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
once(gDebugger.gClient, "willInterrupt").then(() => {
info("Posting message to worker, then waiting for a pause");
postMessageToWorkerInTab(tab, WORKER_URL, "ping");
});
yield oncePaused;
let command1 = jsterm.execute("10000+2");
let command2 = jsterm.execute("10000+3");
let command3 = jsterm.execute("foobar"); // throw an error
info("Trying to get the result of command1");
executed = yield command1;
ok(executed.textContent.includes("10002"),
"command1 executed successfully");
info("Trying to get the result of command2");
executed = yield command2;
ok(executed.textContent.includes("10003"),
"command2 executed successfully");
info("Trying to get the result of command3");
executed = yield command3;
// XXXworkers This is failing until Bug 1215120 is resolved.
todo(executed.textContent.includes("ReferenceError: foobar is not defined"),
"command3 executed successfully");
let onceResumed = gTarget.once("thread-resumed");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
yield onceResumed;
yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield close(client);
yield removeTab(tab);
});
// Test to see if creating the pause from the console works.
add_task(function* testPausedByConsole() {
let {client, tab, tabClient, workerClient, toolbox, gDebugger} =
yield initWorkerDebugger(TAB_URL, WORKER_URL);
let gTarget = gDebugger.gTarget;
let gResumeButton = gDebugger.document.getElementById("resume");
let gResumeKey = gDebugger.document.getElementById("resumeKey");
let jsterm = yield getSplitConsole(toolbox);
let executed = yield jsterm.execute("10000+1");
ok(executed.textContent.includes("10001"),
"Text for message appeared correct");
let oncePaused = gTarget.once("thread-paused");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
let pausedExecution = jsterm.execute("10000+2");
info("Executed a command with 'break on next' active, waiting for pause");
yield oncePaused;
executed = yield jsterm.execute("10000+3");
ok(executed.textContent.includes("10003"),
"Text for message appeared correct");
info("Waiting for a resume");
let onceResumed = gTarget.once("thread-resumed");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
yield onceResumed;
executed = yield pausedExecution;
ok(executed.textContent.includes("10002"),
"Text for message appeared correct");
yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield close(client);
yield removeTab(tab);
});

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

@ -44,8 +44,9 @@ add_task(function* () {
is(activeTools.join(","), "webconsole,jsdebugger,scratchpad,options",
"Correct set of tools supported by worker");
yield toolbox.destroy();
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield close(client);
yield toolbox.destroy();
});

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

@ -1324,3 +1324,33 @@ function waitForDispatch(panel, type, eventRepeat = 1) {
}
});
}
function* initWorkerDebugger(TAB_URL, WORKER_URL) {
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
let client = new DebuggerClient(DebuggerServer.connectPipe());
yield connect(client);
let tab = yield addTab(TAB_URL);
let { tabs } = yield listTabs(client);
let [, tabClient] = yield attachTab(client, findTab(tabs, TAB_URL));
yield createWorkerInTab(tab, WORKER_URL);
let { workers } = yield listWorkers(tabClient);
let [, workerClient] = yield attachWorker(tabClient,
findWorker(workers, WORKER_URL));
let toolbox = yield gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
"jsdebugger",
Toolbox.HostType.WINDOW);
let debuggerPanel = toolbox.getCurrentPanel();
let gDebugger = debuggerPanel.panelWin;
return {client, tab, tabClient, workerClient, toolbox, gDebugger};
}

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

@ -767,7 +767,9 @@ WorkerTarget.prototype = {
return this._workerClient.client;
},
destroy: function () {},
destroy: function () {
this._workerClient.detach();
},
hasActor: function (name) {
// console is the only one actor implemented by WorkerActor

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

@ -2904,11 +2904,7 @@ function TextEditor(container, node, templateId) {
stopOnReturn: true,
trigger: "dblclick",
multiline: true,
maxWidth: () => {
let elementRect = this.value.getBoundingClientRect();
let containerRect = this.container.elt.getBoundingClientRect();
return containerRect.right - elementRect.left - 2;
},
maxWidth: () => getAutocompleteMaxWidth(this.value, this.container.elt),
trimOutput: false,
done: (val, commit) => {
if (!commit) {
@ -3003,6 +2999,8 @@ function ElementEditor(container, node) {
this.tag.setAttribute("tabindex", "-1");
editableField({
element: this.tag,
multiline: true,
maxWidth: () => getAutocompleteMaxWidth(this.tag, this.container.elt),
trigger: "dblclick",
stopOnReturn: true,
done: this.onTagEdit.bind(this),
@ -3013,6 +3011,8 @@ function ElementEditor(container, node) {
// Make the new attribute space editable.
this.newAttr.editMode = editableField({
element: this.newAttr,
multiline: true,
maxWidth: () => getAutocompleteMaxWidth(this.newAttr, this.container.elt),
trigger: "dblclick",
stopOnReturn: true,
contentType: InplaceEditor.CONTENT_TYPES.CSS_MIXED,
@ -3233,6 +3233,8 @@ ElementEditor.prototype = {
stopOnReturn: true,
selectAll: false,
initial: initial,
multiline: true,
maxWidth: () => getAutocompleteMaxWidth(inner, this.container.elt),
contentType: InplaceEditor.CONTENT_TYPES.CSS_MIXED,
popup: this.markup.popup,
start: (editor, event) => {
@ -3605,6 +3607,17 @@ function map(value, oldMin, oldMax, newMin, newMax) {
return newMin + (newMax - newMin) * ((value - oldMin) / ratio);
}
/**
* Retrieve the available width between a provided element left edge and a container right
* edge. This used can be used as a max-width for inplace-editor (autocomplete) widgets
* replacing Editor elements of the the markup-view;
*/
function getAutocompleteMaxWidth(element, container) {
let elementRect = element.getBoundingClientRect();
let containerRect = container.getBoundingClientRect();
return containerRect.right - elementRect.left - 2;
}
loader.lazyGetter(MarkupView.prototype, "strings", () => Services.strings.createBundle(
"chrome://devtools/locale/inspector.properties"
));

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

@ -141,6 +141,7 @@ skip-if = e10s # Bug 1036409 - The last selected node isn't reselected
[browser_markup_tag_edit_11.js]
[browser_markup_tag_edit_12.js]
[browser_markup_tag_edit_13-other.js]
[browser_markup_tag_edit_long-classname.js]
[browser_markup_textcontent_display.js]
[browser_markup_textcontent_edit_01.js]
[browser_markup_textcontent_edit_02.js]

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

@ -69,7 +69,7 @@ function* testAttributeDeletion(inspector) {
let focusedAttr = Services.focus.focusedElement;
ok(focusedAttr.classList.contains("styleinspector-propertyeditor"),
"in newattr");
is(focusedAttr.tagName, "input", "newattr is active");
is(focusedAttr.tagName, "textarea", "newattr is active");
}
function* editAttributeAndTab(newValue, inspector, goPrevious) {

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

@ -0,0 +1,41 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that editing long classnames shows the whole class attribute without scrollbars.
const classname = "this-long-class-attribute-should-be-displayed " +
"without-overflow-when-switching-to-edit-mode " +
"AAAAAAAAAAAA-BBBBBBBBBBBBB-CCCCCCCCCCCCC-DDDDDDDDDDDDDD-EEEEEEEEEEEEE";
const TEST_URL = `data:text/html;charset=utf8, <div class="${classname}"></div>`;
add_task(function* () {
let {inspector} = yield openInspectorForURL(TEST_URL);
yield selectNode("div", inspector);
yield clickContainer("div", inspector);
let container = yield focusNode("div", inspector);
ok(container && container.editor, "The markup-container was found");
info("Listening for the markupmutation event");
let nodeMutated = inspector.once("markupmutation");
let attr = container.editor.attrElements.get("class").querySelector(".editable");
attr.focus();
EventUtils.sendKey("return", inspector.panelWin);
let input = inplaceEditor(attr).input;
ok(input, "Found editable field for class attribute");
is(input.scrollHeight, input.clientHeight, "input should not have vertical scrollbars");
is(input.scrollWidth, input.clientWidth, "input should not have horizontal scrollbars");
input.value = "class=\"other value\"";
info("Commit the new class value");
EventUtils.sendKey("return", inspector.panelWin);
info("Wait for the markup-mutation event");
yield nodeMutated;
});

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

@ -389,13 +389,16 @@ function collapseSelectionAndShiftTab(inspector) {
*/
function checkFocusedAttribute(attrName, editMode) {
let focusedAttr = Services.focus.focusedElement;
is(focusedAttr ? focusedAttr.parentNode.dataset.attr : undefined,
attrName, attrName + " attribute editor is currently focused.");
is(focusedAttr ? focusedAttr.tagName : undefined,
editMode ? "input" : "span",
editMode
? attrName + " is in edit mode"
: attrName + " is not in edit mode");
ok(focusedAttr, "Has a focused element");
let dataAttr = focusedAttr.parentNode.dataset.attr;
is(dataAttr, attrName, attrName + " attribute editor is currently focused.");
if (editMode) {
// Using a multiline editor for attributes, the focused element should be a textarea.
is(focusedAttr.tagName, "textarea", attrName + "is in edit mode");
} else {
is(focusedAttr.tagName, "span", attrName + "is not in edit mode");
}
}
/**

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

@ -212,7 +212,6 @@ devtools.jar:
skin/images/breadcrumbs-scrollbutton.png (themes/images/breadcrumbs-scrollbutton.png)
skin/images/breadcrumbs-scrollbutton@2x.png (themes/images/breadcrumbs-scrollbutton@2x.png)
skin/animationinspector.css (themes/animationinspector.css)
skin/eyedropper.css (themes/eyedropper.css)
skin/canvasdebugger.css (themes/canvasdebugger.css)
skin/debugger.css (themes/debugger.css)
skin/netmonitor.css (themes/netmonitor.css)

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

@ -179,16 +179,6 @@ inspectorPasteOuterHTML.accesskey=O
inspectorPasteInnerHTML.label=Inner HTML
inspectorPasteInnerHTML.accesskey=I
# LOCALIZATION NOTE (inspectorHTMLPasteExtraSubmenu.label): This is the label
# shown in the inspector contextual-menu for the sub-menu of the other Paste
# items, which allow to paste HTML:
# - before the current node
# - after the current node
# - as the first child of the current node
# - as the last child of the current node
inspectorHTMLPasteExtraSubmenu.label=Paste…
inspectorHTMLPasteExtraSubmenu.accesskey=t
# LOCALIZATION NOTE (inspectorHTMLPasteBefore.label): This is the label shown
# in the inspector contextual-menu for the item that lets users paste
# the HTML before the current node
@ -240,11 +230,6 @@ inspectorAttributesSubmenu.accesskey=A
inspectorAddAttribute.label=Add Attribute
inspectorAddAttribute.accesskey=A
# LOCALIZATION NOTE (inspectorSearchHTML.label2): This is the label shown as
# the placeholder in inspector search box
inspectorSearchHTML.label2=Search with CSS Selectors
inspectorSearchHTML.key=F
# LOCALIZATION NOTE (inspectorSearchHTML.label3): This is the label that is
# shown as the placeholder for the markup view search in the inspector.
inspectorSearchHTML.label3=Search HTML

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

@ -206,7 +206,6 @@ define(function (require, exports, module) {
role: "presentation",
},
DOM.a({
href: "#",
tabIndex: this.state.tabActive === index ? 0 : -1,
"aria-controls": "panel-" + index,
"aria-selected": isTabSelected,

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

@ -1,47 +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/. */
#canvas {
image-rendering: -moz-crisp-edges;
cursor: none;
border: 3px solid #E0E0E0;
border-radius: 50%;
}
#canvas-overflow {
overflow: hidden;
width: 96px;
height: 96px;
}
#color-preview {
width: 16px;
height: 16px;
box-shadow: 0px 0px 0px black;
border: solid 1px #fff;
margin: 3px;
}
#color-value-box {
background-color: #E0E0E0;
border-radius: 1px;
width: 150px;
}
#color-value {
/* avoid the # appearing at the end for some colours in RTL locales */
direction: ltr;
padding: 0.3em;
text-shadow: 1px 1px 1px #fff;
}
#color-value.highlight {
font-family: inherit;
}
window {
/* inexplicably, otherwise background shows up on Linux */
border: 1px solid transparent;
background-color: transparent;
}

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

@ -8,6 +8,7 @@ DIRS += [
'components',
'reducers',
'selectors',
'test',
'utils',
]

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

@ -29,6 +29,9 @@ let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
let React = browserRequire("devtools/client/shared/vendor/react");
var TestUtils = React.addons.TestUtils;
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/stubs");
// @TODO Remove this.
let testCommands = new Map();
testCommands.set("console.log()", {
command: "console.log('foobar', 'test')",

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

@ -0,0 +1,8 @@
# vim: set filetype=python:
# 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/.
DevToolsModules(
'stubs.js',
)

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

@ -58,20 +58,6 @@ add_task(function* () {
"Non-repeated messages aren't clobbered");
});
/**
* Test getRepeatId().
*/
add_task(function* () {
const message1 = prepareMessage(packet);
let message2 = prepareMessage(packet);
equal(getRepeatId(message1), getRepeatId(message2),
"getRepeatId() returns same repeat id for objects with the same values");
message2 = message2.set("parameters", ["new args"]);
notEqual(getRepeatId(message1), getRepeatId(message2),
"getRepeatId() returns different repeat ids for different values");
});
/**
* Test adding a console.clear message to the store.
*/
@ -122,7 +108,7 @@ add_task(function* () {
let newPacket = Object.assign({}, packet);
for (let i = 1; i <= userSetLimit + 1; i++) {
newPacket.message.parameters = [i];
newPacket.message.arguments = [i];
dispatch(actions.messageAdd(newPacket));
}

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

@ -0,0 +1,99 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {
MESSAGE_SOURCE,
MESSAGE_TYPE,
MESSAGE_LEVEL,
// Legacy
CATEGORY_WEBDEV,
SEVERITY_LOG,
} = require("devtools/client/webconsole/new-console-output/constants");
const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types");
exports.stubConsoleMessages = new Map([
[
"console.log('foobar', 'test')",
new ConsoleMessage({
allowRepeating: true,
source: MESSAGE_SOURCE.CONSOLE_API,
type: MESSAGE_TYPE.LOG,
level: MESSAGE_LEVEL.LOG,
messageText: null,
parameters: ["foobar", "test"],
repeat: 1,
repeatId: null,
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
})
],
[
"console.warn('danger, will robinson!')",
new ConsoleMessage({
allowRepeating: true,
source: MESSAGE_SOURCE.CONSOLE_API,
type: MESSAGE_TYPE.LOG,
level: MESSAGE_LEVEL.WARN,
messageText: null,
parameters: ["danger, will robinson!"],
repeat: 1,
repeatId: null,
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
})
],
[
"console.log(undefined)",
new ConsoleMessage({
allowRepeating: true,
source: MESSAGE_SOURCE.CONSOLE_API,
type: MESSAGE_TYPE.LOG,
level: MESSAGE_LEVEL.LOG,
messageText: null,
parameters: [
{ type: "undefined" }
],
repeat: 1,
repeatId: null,
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
})
],
[
"console.log(NaN)",
new ConsoleMessage({
allowRepeating: true,
source: MESSAGE_SOURCE.CONSOLE_API,
type: MESSAGE_TYPE.LOG,
level: MESSAGE_LEVEL.LOG,
messageText: null,
parameters: [
{ type: "NaN" }
],
repeat: 1,
repeatId: null,
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
})
],
[
"console.log(null)",
new ConsoleMessage({
allowRepeating: true,
source: MESSAGE_SOURCE.CONSOLE_API,
type: MESSAGE_TYPE.LOG,
level: MESSAGE_LEVEL.LOG,
messageText: null,
parameters: [
{ type: "null" }
],
repeat: 1,
repeatId: null,
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
})
],
]);

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

@ -13,47 +13,43 @@
<script type="text/javascript;version=1.8">
window.onload = Task.async(function* () {
const {
prepareMessage,
getRepeatId
} = require("devtools/client/webconsole/new-console-output/utils/messages");
const { getRepeatId } = require("devtools/client/webconsole/new-console-output/utils/messages");
yield testDuplicateValues();
yield testDifferentValues();
yield testDifferentSeverities();
yield testFalsyValues();
yield testConsoleVsJSTerm();
SimpleTest.finish();
function testDuplicateValues() {
const {message: message1} = yield getPacket("console.log('same')", "consoleAPICall");
const {message: message2} = yield getPacket("console.log('same')", "consoleAPICall");
const message1 = stubConsoleMessages.get("console.log('foobar', 'test')");
const message2 = message1.set("repeat", 3);
is(getRepeatId(message1), getRepeatId(message2),
"getRepeatId() returns same repeat id for objects with the same values");
}
function testDifferentValues() {
const {message: message1} = yield getPacket("console.log('same')", "consoleAPICall");
const {message: message2} = yield getPacket("console.log('diff')", "consoleAPICall");
const message1 = stubConsoleMessages.get("console.log('foobar', 'test')");
const message2 = message1.set("parameters", ["funny", "monkey"]);
isnot(getRepeatId(message1), getRepeatId(message2),
"getRepeatId() returns different repeat ids for different values");
}
function testDifferentSeverities() {
const {message: message1} = yield getPacket("console.log('test')", "consoleAPICall");
const {message: message2} = yield getPacket("console.warn('test')", "consoleAPICall");
const message1 = stubConsoleMessages.get("console.log('foobar', 'test')");
const message2 = message1.set("level", "error");
isnot(getRepeatId(message1), getRepeatId(message2),
"getRepeatId() returns different repeat ids for different severities");
}
function testFalsyValues() {
const {message: messageNaN} = yield getPacket("console.log(NaN)", "consoleAPICall");
const {message: messageUnd} = yield getPacket("console.log(undefined)", "consoleAPICall");
const {message: messageNul} = yield getPacket("console.log(null)", "consoleAPICall");
const messageNaN = stubConsoleMessages.get("console.log(NaN)");
const messageUnd = stubConsoleMessages.get("console.log(undefined)");
const messageNul = stubConsoleMessages.get("console.log(null)");
const repeatIds = new Set([
getRepeatId(messageNaN),
@ -62,25 +58,6 @@ window.onload = Task.async(function* () {
);
is(repeatIds.size, 3,
"getRepeatId() handles falsy values distinctly");
const {message: messageNaN2} = yield getPacket("console.log(NaN)", "consoleAPICall");
const {message: messageUnd2} = yield getPacket("console.log(undefined)", "consoleAPICall");
const {message: messageNul2} = yield getPacket("console.log(null)", "consoleAPICall");
is(getRepeatId(messageNaN), getRepeatId(messageNaN2),
"getRepeatId() handles NaN values");
is(getRepeatId(messageUnd), getRepeatId(messageUnd2),
"getRepeatId() handles undefined values");
is(getRepeatId(messageNul), getRepeatId(messageNul2),
"getRepeatId() handles null values");
}
function testConsoleVsJSTerm() {
const {message: message1} = yield getPacket("console.log(undefined)", "consoleAPICall");
const {result: message2} = yield getPacket("undefined");
isnot(getRepeatId(message1), getRepeatId(message2),
"getRepeatId() returns different repeat ids for console vs JSTerm");
}
});
</script>

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

@ -8,6 +8,7 @@
const Immutable = require("devtools/client/shared/vendor/immutable");
exports.ConsoleCommand = Immutable.Record({
id: null,
allowRepeating: false,
messageText: null,
source: null,
@ -17,6 +18,7 @@ exports.ConsoleCommand = Immutable.Record({
});
exports.ConsoleMessage = Immutable.Record({
id: null,
allowRepeating: true,
source: null,
type: null,
@ -27,5 +29,4 @@ exports.ConsoleMessage = Immutable.Record({
repeatId: null,
category: "output",
severity: "log",
id: null,
});

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

@ -30,11 +30,14 @@ function getNextMessageId() {
function prepareMessage(packet) {
// This packet is already in the expected packet structure. Simply return.
if (packet.source) {
return packet;
if (!packet.source) {
packet = transformPacket(packet);
}
return transformPacket(packet);
if (packet.allowRepeating) {
packet = packet.set("repeatId", getRepeatId(packet));
}
return packet.set("id", getNextMessageId());
}
/**
@ -77,10 +80,8 @@ function transformPacket(packet) {
level,
parameters,
messageText,
repeatId: getRepeatId(message),
category: CATEGORY_WEBDEV,
severity: level,
id: getNextMessageId(),
});
}
@ -97,10 +98,8 @@ function transformPacket(packet) {
source: MESSAGE_SOURCE.JAVASCRIPT,
type: MESSAGE_TYPE.LOG,
messageText: pageError.errorMessage,
repeatId: getRepeatId(pageError),
category: CATEGORY_JS,
severity: level,
id: getNextMessageId(),
});
}
@ -113,10 +112,8 @@ function transformPacket(packet) {
type: MESSAGE_TYPE.RESULT,
level: MESSAGE_LEVEL.LOG,
parameters: result,
repeatId: getRepeatId(result),
category: CATEGORY_OUTPUT,
severity: SEVERITY_LOG,
id: getNextMessageId(),
});
}
}
@ -124,10 +121,9 @@ function transformPacket(packet) {
// Helpers
function getRepeatId(message) {
let clonedMessage = JSON.parse(JSON.stringify(message));
delete clonedMessage.id;
delete clonedMessage.timeStamp;
return JSON.stringify(clonedMessage);
message = message.toJS();
delete message.repeat;
return JSON.stringify(message);
}
function convertCachedPacket(packet) {

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

@ -8,7 +8,6 @@ const promise = require("promise");
const EventEmitter = require("devtools/shared/event-emitter");
const {generateUUID} = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
const {indexedDB} = require("sdk/indexed-db");
/**
* IndexedDB wrapper that just save project objects

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

@ -24,6 +24,7 @@
text-indent: initial;
letter-spacing: initial;
word-spacing: initial;
color: initial;
}
:-moz-native-anonymous .highlighter-container {

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

@ -4,7 +4,7 @@
"use strict";
const {Cc, Ci} = require("chrome");
const {Cc, Ci, Cu, CC} = require("chrome");
const events = require("sdk/event/core");
const protocol = require("devtools/shared/protocol");
const {LongStringActor} = require("devtools/server/actors/string");
@ -18,6 +18,20 @@ const { Task } = require("devtools/shared/task");
loader.lazyImporter(this, "OS", "resource://gre/modules/osfile.jsm");
loader.lazyImporter(this, "Sqlite", "resource://gre/modules/Sqlite.jsm");
// We give this a funny name to avoid confusion with the global
// indexedDB.
loader.lazyGetter(this, "indexedDBForStorage", () => {
// On xpcshell, we can't instantiate indexedDB without crashing
try {
let sandbox
= Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(),
{wantGlobalProperties: ["indexedDB"]});
return sandbox.indexedDB;
} catch (e) {
return {};
}
});
var gTrackedMessageManager = new Map();
// Maximum number of cookies/local storage key-value-pairs that can be sent
@ -1736,12 +1750,12 @@ var indexedDBHelpers = {
* database `name`.
*/
openWithPrincipal(principal, name) {
return require("indexedDB").openForPrincipal(principal, name);
return indexedDBForStorage.openForPrincipal(principal, name);
},
removeDB: Task.async(function* (host, principal, name) {
let result = new promise(resolve => {
let request = require("indexedDB").deleteForPrincipal(principal, name);
let request = indexedDBForStorage.deleteForPrincipal(principal, name);
request.onsuccess = () => {
resolve({});

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

@ -863,10 +863,25 @@ var DebuggerServer = {
transport.hooks = {
onClosed: () => {
if (!dbg.isClosed) {
dbg.postMessage(JSON.stringify({
type: "disconnect",
id,
}));
// If the worker happens to be shutting down while we are trying
// to close the connection, there is a small interval during
// which no more runnables can be dispatched to the worker, but
// the worker debugger has not yet been closed. In that case,
// the call to postMessage below will fail. The onClosed hook on
// DebuggerTransport is not supposed to throw exceptions, so we
// need to make sure to catch these early.
try {
dbg.postMessage(JSON.stringify({
type: "disconnect",
id,
}));
} catch (e) {
// We can safely ignore these exceptions. The only time the
// call to postMessage can fail is if the worker is either
// shutting down, or has finished shutting down. In both
// cases, there is nothing to clean up, so we don't care
// whether this message arrives or not.
}
}
connection.cancelForwarding(id);
@ -1444,6 +1459,26 @@ DebuggerServerConnection.prototype = {
* otherwise.
*/
removeActorPool(actorPool, noCleanup) {
// When a connection is closed, it removes each of its actor pools. When an
// actor pool is removed, it calls the disconnect method on each of its
// actors. Some actors, such as ThreadActor, manage their own actor pools.
// When the disconnect method is called on these actors, they manually
// remove their actor pools. Consequently, this method is reentrant.
//
// In addition, some actors, such as ThreadActor, perform asynchronous work
// (in the case of ThreadActor, because they need to resume), before they
// remove each of their actor pools. Since we don't wait for this work to
// be completed, we can end up in this function recursively after the
// connection already set this._extraPools to null.
//
// This is a bug: if the disconnect method can perform asynchronous work,
// then we should wait for that work to be completed before setting this.
// _extraPools to null. As a temporary solution, it should be acceptable
// to just return early (if this._extraPools has been set to null, all
// actors pools for this connection should already have been removed).
if (this._extraPools === null) {
return;
}
let index = this._extraPools.lastIndexOf(actorPool);
if (index > -1) {
let pool = this._extraPools.splice(index, 1);

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

@ -39,155 +39,150 @@
* DOM elements, but they may include things like Blobs and typed arrays.
*
*/
const {Cc, Ci, Cu, Cr} = require("chrome");
const {indexedDB} = require("sdk/indexed-db");
"use strict";
const Promise = require("promise");
module.exports = (function () {
"use strict";
const DBNAME = "devtools-async-storage";
const DBVERSION = 1;
const STORENAME = "keyvaluepairs";
var db = null;
var DBNAME = "devtools-async-storage";
var DBVERSION = 1;
var STORENAME = "keyvaluepairs";
var db = null;
function withStore(type, onsuccess, onerror) {
if (db) {
var transaction = db.transaction(STORENAME, type);
var store = transaction.objectStore(STORENAME);
function withStore(type, onsuccess, onerror) {
if (db) {
let transaction = db.transaction(STORENAME, type);
let store = transaction.objectStore(STORENAME);
onsuccess(store);
} else {
let openreq = indexedDB.open(DBNAME, DBVERSION);
openreq.onerror = function withStoreOnError() {
onerror();
};
openreq.onupgradeneeded = function withStoreOnUpgradeNeeded() {
// First time setup: create an empty object store
openreq.result.createObjectStore(STORENAME);
};
openreq.onsuccess = function withStoreOnSuccess() {
db = openreq.result;
let transaction = db.transaction(STORENAME, type);
let store = transaction.objectStore(STORENAME);
onsuccess(store);
} else {
var openreq = indexedDB.open(DBNAME, DBVERSION);
openreq.onerror = function withStoreOnError() {
onerror();
};
}
}
function getItem(itemKey) {
return new Promise((resolve, reject) => {
let req;
withStore("readonly", (store) => {
store.transaction.oncomplete = function onComplete() {
let value = req.result;
if (value === undefined) {
value = null;
}
resolve(value);
};
openreq.onupgradeneeded = function withStoreOnUpgradeNeeded() {
// First time setup: create an empty object store
openreq.result.createObjectStore(STORENAME);
req = store.get(itemKey);
req.onerror = function getItemOnError() {
reject("Error in asyncStorage.getItem(): ", req.error.name);
};
openreq.onsuccess = function withStoreOnSuccess() {
db = openreq.result;
var transaction = db.transaction(STORENAME, type);
var store = transaction.objectStore(STORENAME);
onsuccess(store);
}, reject);
});
}
function setItem(itemKey, value) {
return new Promise((resolve, reject) => {
withStore("readwrite", (store) => {
store.transaction.oncomplete = resolve;
let req = store.put(value, itemKey);
req.onerror = function setItemOnError() {
reject("Error in asyncStorage.setItem(): ", req.error.name);
};
}, reject);
});
}
function removeItem(itemKey) {
return new Promise((resolve, reject) => {
withStore("readwrite", (store) => {
store.transaction.oncomplete = resolve;
let req = store.delete(itemKey);
req.onerror = function removeItemOnError() {
reject("Error in asyncStorage.removeItem(): ", req.error.name);
};
}, reject);
});
}
function clear() {
return new Promise((resolve, reject) => {
withStore("readwrite", (store) => {
store.transaction.oncomplete = resolve;
let req = store.clear();
req.onerror = function clearOnError() {
reject("Error in asyncStorage.clear(): ", req.error.name);
};
}, reject);
});
}
function length() {
return new Promise((resolve, reject) => {
let req;
withStore("readonly", (store) => {
store.transaction.oncomplete = function onComplete() {
resolve(req.result);
};
req = store.count();
req.onerror = function lengthOnError() {
reject("Error in asyncStorage.length(): ", req.error.name);
};
}, reject);
});
}
function key(n) {
return new Promise((resolve, reject) => {
if (n < 0) {
resolve(null);
return;
}
}
function getItem(key) {
return new Promise((resolve, reject) => {
var req;
withStore("readonly", (store) => {
store.transaction.oncomplete = function onComplete() {
var value = req.result;
if (value === undefined) {
value = null;
}
resolve(value);
};
req = store.get(key);
req.onerror = function getItemOnError() {
reject("Error in asyncStorage.getItem(): ", req.error.name);
};
}, reject);
});
}
let req;
withStore("readonly", (store) => {
store.transaction.oncomplete = function onComplete() {
let cursor = req.result;
resolve(cursor ? cursor.key : null);
};
let advanced = false;
req = store.openCursor();
req.onsuccess = function keyOnSuccess() {
let cursor = req.result;
if (!cursor) {
// this means there weren"t enough keys
return;
}
if (n === 0 || advanced) {
// Either 1) we have the first key, return it if that's what they
// wanted, or 2) we"ve got the nth key.
return;
}
function setItem(key, value) {
return new Promise((resolve, reject) => {
withStore("readwrite", (store) => {
store.transaction.oncomplete = resolve;
var req = store.put(value, key);
req.onerror = function setItemOnError() {
reject("Error in asyncStorage.setItem(): ", req.error.name);
};
}, reject);
});
}
// Otherwise, ask the cursor to skip ahead n records
advanced = true;
cursor.advance(n);
};
req.onerror = function keyOnError() {
reject("Error in asyncStorage.key(): ", req.error.name);
};
}, reject);
});
}
function removeItem(key) {
return new Promise((resolve, reject) => {
withStore("readwrite", (store) => {
store.transaction.oncomplete = resolve;
var req = store.delete(key);
req.onerror = function removeItemOnError() {
reject("Error in asyncStorage.removeItem(): ", req.error.name);
};
}, reject);
});
}
function clear() {
return new Promise((resolve, reject) => {
withStore("readwrite", (store) => {
store.transaction.oncomplete = resolve;
var req = store.clear();
req.onerror = function clearOnError() {
reject("Error in asyncStorage.clear(): ", req.error.name);
};
}, reject);
});
}
function length() {
return new Promise((resolve, reject) => {
var req;
withStore("readonly", (store) => {
store.transaction.oncomplete = function onComplete() {
resolve(req.result);
};
req = store.count();
req.onerror = function lengthOnError() {
reject("Error in asyncStorage.length(): ", req.error.name);
};
}, reject);
});
}
function key(n) {
return new Promise((resolve, reject) => {
if (n < 0) {
resolve(null);
return;
}
var req;
withStore("readonly", (store) => {
store.transaction.oncomplete = function onComplete() {
var cursor = req.result;
resolve(cursor ? cursor.key : null);
};
var advanced = false;
req = store.openCursor();
req.onsuccess = function keyOnSuccess() {
var cursor = req.result;
if (!cursor) {
// this means there weren"t enough keys
return;
}
if (n === 0 || advanced) {
// Either 1) we have the first key, return it if that's what they
// wanted, or 2) we"ve got the nth key.
return;
}
// Otherwise, ask the cursor to skip ahead n records
advanced = true;
cursor.advance(n);
};
req.onerror = function keyOnError() {
reject("Error in asyncStorage.key(): ", req.error.name);
};
}, reject);
});
}
return {
getItem: getItem,
setItem: setItem,
removeItem: removeItem,
clear: clear,
length: length,
key: key
};
}());
exports.getItem = getItem;
exports.setItem = setItem;
exports.removeItem = removeItem;
exports.clear = clear;
exports.length = length;
exports.key = key;

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

@ -204,19 +204,6 @@ defineLazyGetter(exports.modules, "xpcInspector", () => {
return Cc["@mozilla.org/jsinspector;1"].getService(Ci.nsIJSInspector);
});
defineLazyGetter(exports.modules, "indexedDB", () => {
// On xpcshell, we can't instantiate indexedDB without crashing
try {
let sandbox
= Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(),
{wantGlobalProperties: ["indexedDB"]});
return sandbox.indexedDB;
} catch (e) {
return {};
}
});
defineLazyGetter(exports.modules, "FileReader", () => {
let sandbox
= Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(),
@ -295,3 +282,4 @@ defineLazyGetter(globals, "CSS", () => {
defineLazyGetter(globals, "WebSocket", () => {
return Services.appShell.hiddenDOMWindow.WebSocket;
});
lazyRequireGetter(globals, "indexedDB", "sdk/indexed-db", true);

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

@ -89,13 +89,13 @@ class VideoPuppeteer(object):
self.video = videos_found[0]
self.marionette.execute_script("log('video element obtained');")
if autostart:
self.start();
self.start()
def start(self):
# To get an accurate expected_duration, playback must have started
wait = Wait(self, timeout=self.timeout)
verbose_until(wait, self, lambda v: v.current_time > 0,
"Check if video current_time > 0")
verbose_until(wait, self, playback_started,
"Check if video has played some range")
self._start_time = self.current_time
self._start_wall_time = clock()
self.update_expected_duration()
@ -173,6 +173,20 @@ class VideoPuppeteer(object):
"""
return self.expected_duration - self.current_time
@property
def played(self):
"""
:return: A TimeRanges objected containing the played time ranges.
"""
raw_time_ranges = self.execute_video_script(
'var played = arguments[0].wrappedJSObject.played;'
'var timeRanges = [];'
'for (var i = 0; i < played.length; i++) {'
'timeRanges.push([played.start(i), played.end(i)]);'
'}'
'return [played.length, timeRanges];')
return TimeRanges(raw_time_ranges[0], raw_time_ranges[1])
@property
def video_src(self):
"""
@ -277,6 +291,26 @@ class VideoException(Exception):
pass
class TimeRanges:
"""
Class to represent the TimeRanges data returned by played(). Exposes a
similar interface to the JavaScript TimeRanges object.
"""
def __init__(self, length, ranges):
self.length = length
self.ranges = [(pair[0], pair[1]) for pair in ranges]
def __repr__(self):
return 'TimeRanges: length: {}, ranges: {}'\
.format(self.length, self.ranges)
def start(self, index):
return self.ranges[index][0]
def end(self, index):
return self.ranges[index][1]
def playback_started(video):
"""
Determine if video has started
@ -286,9 +320,12 @@ def playback_started(video):
:return: True if is playing; False otherwise
"""
try:
return video.current_time > video._start_time
played_ranges = video.played
return played_ranges.length > 0 and \
played_ranges.start(0) < played_ranges.end(0) and \
played_ranges.end(0) > 0.0
except Exception as e:
print ('Got exception %s' % e)
print ('Got exception {}'.format(e))
return False

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

@ -23,8 +23,8 @@ class TestBasicYouTubePlayback(MediaTestCase):
interval=1)
try:
verbose_until(wait, youtube,
lambda y: y.video_src.startswith('mediasource'),
"Failed to find 'mediasource' in video src url.")
lambda y: y.video_src.startswith('blob'),
"Failed to find 'blob' in video src url.")
except TimeoutException as e:
raise self.failureException(e)

2
dom/media/test/external/requirements.txt поставляемый
Просмотреть файл

@ -17,4 +17,4 @@ mozversion==1.4
wptserve==1.3.0
marionette-client==3.1.0
marionette-driver==2.0.0
firefox-puppeteer >= 50.0.0, <51.0.0
firefox-puppeteer >= 51.0.0, <52.0.0

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

@ -154,12 +154,12 @@ var _fromToTestLists = {
],
URIsAndNone: [
new AnimTestcaseFromTo("url(#idA)", "url(#idB)",
{ fromComp: "url(\"" + document.URL + "#idA\")",
toComp: "url(\"" + document.URL + "#idB\")"}),
{ fromComp: "url(\"#idA\")",
toComp: "url(\"#idB\")"}),
new AnimTestcaseFromTo("none", "url(#idB)",
{ toComp: "url(\"" + document.URL + "#idB\")"}),
{ toComp: "url(\"#idB\")"}),
new AnimTestcaseFromTo("url(#idB)", "inherit",
{ fromComp: "url(\"" + document.URL + "#idB\")",
{ fromComp: "url(\"#idB\")",
toComp: "none"}),
],
};

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

@ -338,18 +338,24 @@ APZCCallbackHelper::InitializeRootDisplayport(nsIPresShell* aPresShell)
}
}
nsPresContext*
APZCCallbackHelper::GetPresContextForContent(nsIContent* aContent)
{
nsIDocument* doc = aContent->GetComposedDoc();
if (!doc) {
return nullptr;
}
nsIPresShell* shell = doc->GetShell();
if (!shell) {
return nullptr;
}
return shell->GetPresContext();
}
nsIPresShell*
APZCCallbackHelper::GetRootContentDocumentPresShellForContent(nsIContent* aContent)
{
nsIDocument* doc = aContent->GetComposedDoc();
if (!doc) {
return nullptr;
}
nsIPresShell* shell = doc->GetShell();
if (!shell) {
return nullptr;
}
nsPresContext* context = shell->GetPresContext();
nsPresContext* context = GetPresContextForContent(aContent);
if (!context) {
return nullptr;
}

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

@ -66,6 +66,9 @@ public:
given presShell. */
static void InitializeRootDisplayport(nsIPresShell* aPresShell);
/* Get the pres context associated with the document enclosing |aContent|. */
static nsPresContext* GetPresContextForContent(nsIContent* aContent);
/* Get the pres shell associated with the root content document enclosing |aContent|. */
static nsIPresShell* GetRootContentDocumentPresShellForContent(nsIContent* aContent);

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

@ -823,6 +823,7 @@ PropertySupportsVariant(nsCSSProperty aPropertyID, uint32_t aVariant)
case eCSSProperty_content:
case eCSSProperty_cursor:
case eCSSProperty_clip_path:
case eCSSProperty_shape_outside:
supported = VARIANT_URL;
break;

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

@ -3493,18 +3493,18 @@ ExtractImageLayerSizePairList(const nsStyleImageLayers& aLayer,
}
static bool
StyleClipBasicShapeToCSSArray(const nsStyleClipPath& aClipPath,
StyleClipBasicShapeToCSSArray(const StyleClipPath& aClipPath,
nsCSSValue::Array* aResult)
{
MOZ_ASSERT(aResult->Count() == 2,
"Expected array to be presized for a function and the sizing-box");
const nsStyleBasicShape* shape = aClipPath.GetBasicShape();
const StyleBasicShape* shape = aClipPath.GetBasicShape();
nsCSSKeyword functionName = shape->GetShapeTypeName();
RefPtr<nsCSSValue::Array> functionArray;
switch (shape->GetShapeType()) {
case nsStyleBasicShape::Type::eCircle:
case nsStyleBasicShape::Type::eEllipse: {
case StyleBasicShapeType::Circle:
case StyleBasicShapeType::Ellipse: {
const nsTArray<nsStyleCoord>& coords = shape->Coordinates();
MOZ_ASSERT(coords.Length() == ShapeArgumentCount(functionName) - 1,
"Unexpected radii count");
@ -3525,7 +3525,7 @@ StyleClipBasicShapeToCSSArray(const nsStyleClipPath& aClipPath,
functionArray->Item(functionArray->Count() - 1));
break;
}
case nsStyleBasicShape::Type::ePolygon: {
case StyleBasicShapeType::Polygon: {
functionArray =
aResult->Item(0).InitFunction(functionName,
ShapeArgumentCount(functionName));
@ -3546,7 +3546,7 @@ StyleClipBasicShapeToCSSArray(const nsStyleClipPath& aClipPath,
}
break;
}
case nsStyleBasicShape::Type::eInset: {
case StyleBasicShapeType::Inset: {
const nsTArray<nsStyleCoord>& coords = shape->Coordinates();
MOZ_ASSERT(coords.Length() == ShapeArgumentCount(functionName) - 1,
"Unexpected offset count");
@ -3578,7 +3578,7 @@ StyleClipBasicShapeToCSSArray(const nsStyleClipPath& aClipPath,
MOZ_ASSERT_UNREACHABLE("Unknown shape type");
return false;
}
aResult->Item(1).SetIntValue(aClipPath.GetSizingBox(),
aResult->Item(1).SetIntValue(aClipPath.GetReferenceBox(),
eCSSUnit_Enumerated);
return true;
}
@ -3953,10 +3953,10 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
case eCSSProperty_clip_path: {
const nsStyleSVGReset* svgReset =
static_cast<const nsStyleSVGReset*>(styleStruct);
const nsStyleClipPath& clipPath = svgReset->mClipPath;
const StyleClipPathType type = clipPath.GetType();
const StyleClipPath& clipPath = svgReset->mClipPath;
const StyleShapeSourceType type = clipPath.GetType();
if (type == StyleClipPathType::URL) {
if (type == StyleShapeSourceType::URL) {
nsIDocument* doc = aStyleContext->PresContext()->Document();
RefPtr<mozilla::css::URLValue> url =
FragmentOrURLToURLValue(clipPath.GetURL(), doc);
@ -3964,10 +3964,10 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
auto result = MakeUnique<nsCSSValue>();
result->SetURLValue(url);
aComputedValue.SetAndAdoptCSSValueValue(result.release(), eUnit_URL);
} else if (type == StyleClipPathType::Box) {
aComputedValue.SetIntValue(clipPath.GetSizingBox(),
} else if (type == StyleShapeSourceType::Box) {
aComputedValue.SetIntValue(clipPath.GetReferenceBox(),
eUnit_Enumerated);
} else if (type == StyleClipPathType::Shape) {
} else if (type == StyleShapeSourceType::Shape) {
RefPtr<nsCSSValue::Array> result = nsCSSValue::Array::Create(2);
if (!StyleClipBasicShapeToCSSArray(clipPath, result)) {
return false;
@ -3975,7 +3975,7 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
aComputedValue.SetCSSValueArrayValue(result, eUnit_Shape);
} else {
MOZ_ASSERT(type == StyleClipPathType::None_, "unknown type");
MOZ_ASSERT(type == StyleShapeSourceType::None_, "unknown type");
aComputedValue.SetNoneValue();
}
break;

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

@ -1066,6 +1066,7 @@ protected:
bool ParseShadowItem(nsCSSValue& aValue, bool aIsBoxShadow);
bool ParseShadowList(nsCSSProperty aProperty);
bool ParseShapeOutside(nsCSSValue& aValue);
bool ParseTransitionProperty();
bool ParseTransitionTimingFunctionValues(nsCSSValue& aValue);
bool ParseTransitionTimingFunctionValueComponent(float& aComponent,
@ -1324,6 +1325,8 @@ protected:
}
/* Functions for basic shapes */
bool ParseReferenceBoxAndBasicShape(nsCSSValue& aValue,
const KTableEntry aBoxKeywordTable[]);
bool ParseBasicShape(nsCSSValue& aValue, bool* aConsumedTokens);
bool ParsePolygonFunction(nsCSSValue& aValue);
bool ParseCircleOrEllipseFunction(nsCSSKeyword, nsCSSValue& aValue);
@ -11759,6 +11762,8 @@ CSSParserImpl::ParseSingleValuePropertyByFunction(nsCSSValue& aValue,
return ParseScrollSnapDestination(aValue);
case eCSSProperty_scroll_snap_coordinate:
return ParseScrollSnapCoordinate(aValue);
case eCSSProperty_shape_outside:
return ParseShapeOutside(aValue);
case eCSSProperty_text_align:
return ParseTextAlign(aValue);
case eCSSProperty_text_align_last:
@ -12078,17 +12083,21 @@ CSSParserImpl::ParseImageLayersItem(
aState.mClip->mValue.SetIntValue(NS_STYLE_IMAGELAYER_CLIP_BORDER,
eCSSUnit_Enumerated);
aState.mRepeat->mXValue.SetIntValue(NS_STYLE_IMAGELAYER_REPEAT_REPEAT,
eCSSUnit_Enumerated);
aState.mRepeat->mYValue.Reset();
if (eCSSProperty_mask == aTable[nsStyleImageLayers::shorthand]) {
aState.mOrigin->mValue.SetIntValue(NS_STYLE_IMAGELAYER_ORIGIN_BORDER,
eCSSUnit_Enumerated);
aState.mRepeat->mXValue.SetIntValue(NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT,
eCSSUnit_Enumerated);
} else {
aState.mOrigin->mValue.SetIntValue(NS_STYLE_IMAGELAYER_ORIGIN_PADDING,
eCSSUnit_Enumerated);
aState.mRepeat->mXValue.SetIntValue(NS_STYLE_IMAGELAYER_REPEAT_REPEAT,
eCSSUnit_Enumerated);
}
aState.mRepeat->mYValue.Reset();
RefPtr<nsCSSValue::Array> positionXArr = nsCSSValue::Array::Create(2);
RefPtr<nsCSSValue::Array> positionYArr = nsCSSValue::Array::Create(2);
@ -16165,6 +16174,48 @@ CSSParserImpl::ParseBasicShape(nsCSSValue& aValue, bool* aConsumedTokens)
}
}
bool
CSSParserImpl::ParseReferenceBoxAndBasicShape(
nsCSSValue& aValue,
const KTableEntry aBoxKeywordTable[])
{
nsCSSValue referenceBox;
bool hasBox = ParseEnum(referenceBox, aBoxKeywordTable);
const bool boxCameFirst = hasBox;
nsCSSValue basicShape;
bool basicShapeConsumedTokens = false;
bool hasShape = ParseBasicShape(basicShape, &basicShapeConsumedTokens);
// Parsing wasn't successful if ParseBasicShape consumed tokens but failed
// or if the token was neither a reference box nor a basic shape.
if ((!hasShape && basicShapeConsumedTokens) || (!hasBox && !hasShape)) {
return false;
}
// Check if the second argument is a reference box if the first wasn't.
if (!hasBox) {
hasBox = ParseEnum(referenceBox, aBoxKeywordTable);
}
RefPtr<nsCSSValue::Array> fullValue =
nsCSSValue::Array::Create((hasBox && hasShape) ? 2 : 1);
if (hasBox && hasShape) {
fullValue->Item(boxCameFirst ? 0 : 1) = referenceBox;
fullValue->Item(boxCameFirst ? 1 : 0) = basicShape;
} else if (hasBox) {
fullValue->Item(0) = referenceBox;
} else {
MOZ_ASSERT(hasShape, "should've bailed if we got neither box nor shape");
fullValue->Item(0) = basicShape;
}
aValue.SetArrayValue(fullValue, eCSSUnit_Array);
return true;
}
/* Parse a clip-path url to a <clipPath> element or a basic shape. */
bool CSSParserImpl::ParseClipPath()
{
@ -16177,46 +16228,29 @@ bool CSSParserImpl::ParseClipPath()
return false;
}
nsCSSValue referenceBox;
bool hasBox = ParseEnum(referenceBox, nsCSSProps::kClipShapeSizingKTable);
const bool boxCameFirst = hasBox;
nsCSSValue basicShape;
bool basicShapeConsumedTokens = false;
bool hasShape = ParseBasicShape(basicShape, &basicShapeConsumedTokens);
// Parsing wasn't successful if ParseBasicShape consumed tokens but failed
// or if the token was neither a reference box nor a basic shape.
if ((!hasShape && basicShapeConsumedTokens) || (!hasBox && !hasShape)) {
if (!ParseReferenceBoxAndBasicShape(
value, nsCSSProps::kClipPathGeometryBoxKTable)) {
return false;
}
// Check if the second argument is a reference box if the first wasn't.
if (!hasBox) {
hasBox = ParseEnum(referenceBox, nsCSSProps::kClipShapeSizingKTable);
}
RefPtr<nsCSSValue::Array> fullValue =
nsCSSValue::Array::Create((hasBox && hasShape) ? 2 : 1);
if (hasBox && hasShape) {
fullValue->Item(boxCameFirst ? 0 : 1) = referenceBox;
fullValue->Item(boxCameFirst ? 1 : 0) = basicShape;
} else if (hasBox) {
fullValue->Item(0) = referenceBox;
} else {
MOZ_ASSERT(hasShape, "should've bailed if we got neither box nor shape");
fullValue->Item(0) = basicShape;
}
value.SetArrayValue(fullValue, eCSSUnit_Array);
}
AppendValue(eCSSProperty_clip_path, value);
return true;
}
// none | [ <basic-shape> || <shape-box> ] | <image>
bool
CSSParserImpl::ParseShapeOutside(nsCSSValue& aValue)
{
if (ParseSingleTokenVariant(aValue, VARIANT_HUO, nullptr)) {
// 'inherit', 'initial', 'unset', 'none', and <image> url must be alone.
return true;
}
return ParseReferenceBoxAndBasicShape(
aValue, nsCSSProps::kShapeOutsideShapeBoxKTable);
}
bool CSSParserImpl::ParseTransformOrigin(bool aPerspective)
{
nsCSSValuePair position;

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

@ -3708,6 +3708,18 @@ CSS_PROP_DISPLAY(
kScrollSnapTypeKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_DISPLAY(
shape-outside,
shape_outside,
ShapeOutside,
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
"layout.css.shape-outside.enabled",
0,
nullptr,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None) // FIXME: Bug 1289049 for adding animation support
CSS_PROP_SVG(
shape-rendering,
shape_rendering,

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

@ -2296,15 +2296,15 @@ const KTableEntry nsCSSProps::kFillRuleKTable[] = {
{ eCSSKeyword_UNKNOWN, -1 }
};
const KTableEntry nsCSSProps::kClipShapeSizingKTable[] = {
{ eCSSKeyword_content_box, StyleClipShapeSizing::Content },
{ eCSSKeyword_padding_box, StyleClipShapeSizing::Padding },
{ eCSSKeyword_border_box, StyleClipShapeSizing::Border },
{ eCSSKeyword_margin_box, StyleClipShapeSizing::Margin },
{ eCSSKeyword_fill_box, StyleClipShapeSizing::Fill },
{ eCSSKeyword_stroke_box, StyleClipShapeSizing::Stroke },
{ eCSSKeyword_view_box, StyleClipShapeSizing::View },
{ eCSSKeyword_UNKNOWN, -1 }
const KTableEntry nsCSSProps::kClipPathGeometryBoxKTable[] = {
{ eCSSKeyword_content_box, StyleClipPathGeometryBox::Content },
{ eCSSKeyword_padding_box, StyleClipPathGeometryBox::Padding },
{ eCSSKeyword_border_box, StyleClipPathGeometryBox::Border },
{ eCSSKeyword_margin_box, StyleClipPathGeometryBox::Margin },
{ eCSSKeyword_fill_box, StyleClipPathGeometryBox::Fill },
{ eCSSKeyword_stroke_box, StyleClipPathGeometryBox::Stroke },
{ eCSSKeyword_view_box, StyleClipPathGeometryBox::View },
{ eCSSKeyword_UNKNOWN, -1 }
};
const KTableEntry nsCSSProps::kShapeRadiusKTable[] = {
@ -2341,6 +2341,14 @@ const KTableEntry nsCSSProps::kMaskTypeKTable[] = {
{ eCSSKeyword_UNKNOWN, -1 }
};
const KTableEntry nsCSSProps::kShapeOutsideShapeBoxKTable[] = {
{ eCSSKeyword_content_box, StyleShapeOutsideShapeBox::Content },
{ eCSSKeyword_padding_box, StyleShapeOutsideShapeBox::Padding },
{ eCSSKeyword_border_box, StyleShapeOutsideShapeBox::Border },
{ eCSSKeyword_margin_box, StyleShapeOutsideShapeBox::Margin },
{ eCSSKeyword_UNKNOWN, -1 }
};
const KTableEntry nsCSSProps::kShapeRenderingKTable[] = {
{ eCSSKeyword_auto, NS_STYLE_SHAPE_RENDERING_AUTO },
{ eCSSKeyword_optimizespeed, NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED },

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

@ -732,7 +732,7 @@ public:
static const KTableEntry kBoxDirectionKTable[];
static const KTableEntry kBoxOrientKTable[];
static const KTableEntry kBoxPackKTable[];
static const KTableEntry kClipShapeSizingKTable[];
static const KTableEntry kClipPathGeometryBoxKTable[];
static const KTableEntry kCounterRangeKTable[];
static const KTableEntry kCounterSpeakAsKTable[];
static const KTableEntry kCounterSymbolsSystemKTable[];
@ -742,6 +742,7 @@ public:
static const KTableEntry kFillRuleKTable[];
static const KTableEntry kFilterFunctionKTable[];
static const KTableEntry kImageRenderingKTable[];
static const KTableEntry kShapeOutsideShapeBoxKTable[];
static const KTableEntry kShapeRenderingKTable[];
static const KTableEntry kStrokeLinecapKTable[];
static const KTableEntry kStrokeLinejoinKTable[];

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

@ -1424,7 +1424,13 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
case eCSSProperty_clip_path:
AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
nsCSSProps::kClipShapeSizingKTable),
nsCSSProps::kClipPathGeometryBoxKTable),
aResult);
break;
case eCSSProperty_shape_outside:
AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
nsCSSProps::kShapeOutsideShapeBoxKTable),
aResult);
break;
@ -2522,7 +2528,8 @@ nsCSSValuePairList::AppendToString(nsCSSProperty aProperty,
if (nsCSSProps::PropHasFlags(aProperty,
CSS_PROPERTY_VALUE_LIST_USES_COMMAS) ||
aProperty == eCSSProperty_clip_path)
aProperty == eCSSProperty_clip_path ||
aProperty == eCSSProperty_shape_outside)
aResult.Append(char16_t(','));
aResult.Append(char16_t(' '));
}

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

@ -2148,7 +2148,7 @@ nsComputedDOMStyle::DoGetImageLayerImage(const nsStyleImageLayers& aLayers)
if (aLayers.mLayers[i].mSourceURI.IsLocalRef()) {
// This is how we represent a 'mask-image' reference for a local URI,
// such as 'mask-image:url(#mymask)' or 'mask:url(#mymask)'
val->SetURI(aLayers.mLayers[i].mSourceURI.GetSourceURL());
SetValueToFragmentOrURL(&aLayers.mLayers[i].mSourceURI, val);
} else {
SetValueToStyleImage(image, val);
}
@ -2387,6 +2387,28 @@ nsComputedDOMStyle::SetValueToPosition(
aValueList->AppendCSSValue(valY.forget());
}
void
nsComputedDOMStyle::SetValueToFragmentOrURL(
const FragmentOrURL* aFragmentOrURL,
nsROCSSPrimitiveValue* aValue)
{
if (aFragmentOrURL->IsLocalRef()) {
nsString fragment;
aFragmentOrURL->GetSourceString(fragment);
fragment.Insert(u"url(\"", 0);
fragment.Append(u"\")");
aValue->SetString(fragment);
} else {
nsCOMPtr<nsIURI> url = aFragmentOrURL->GetSourceURL();
if (url) {
aValue->SetURI(url);
} else {
aValue->SetIdent(eCSSKeyword_none);
}
}
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetBackgroundPosition()
{
@ -5560,12 +5582,9 @@ nsComputedDOMStyle::GetSVGPaintFor(bool aFill)
}
case eStyleSVGPaintType_Server:
{
// Bug 1288812 - we should only serialize fragment for local-ref URL.
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
RefPtr<nsROCSSPrimitiveValue> fallback = new nsROCSSPrimitiveValue;
nsCOMPtr<nsIURI> paintServerURI =
paint->mPaint.mPaintServer->GetSourceURL();
val->SetURI(paintServerURI);
SetValueToFragmentOrURL(paint->mPaint.mPaintServer, val);
SetToRGBAColor(fallback, paint->mFallbackColor);
valueList->AppendCSSValue(val.forget());
@ -5603,13 +5622,7 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetMarkerEnd()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
// Bug 1288812 - we should only serialize fragment for local-ref URL.
nsCOMPtr<nsIURI> markerURI = StyleSVG()->mMarkerEnd.GetSourceURL();
if (markerURI)
val->SetURI(markerURI);
else
val->SetIdent(eCSSKeyword_none);
SetValueToFragmentOrURL(&StyleSVG()->mMarkerEnd, val);
return val.forget();
}
@ -5618,13 +5631,7 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetMarkerMid()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
// Bug 1288812 - we should only serialize fragment for local-ref URL.
nsCOMPtr<nsIURI> markerURI = StyleSVG()->mMarkerMid.GetSourceURL();
if (markerURI)
val->SetURI(markerURI);
else
val->SetIdent(eCSSKeyword_none);
SetValueToFragmentOrURL(&StyleSVG()->mMarkerMid, val);
return val.forget();
}
@ -5633,13 +5640,7 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetMarkerStart()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
// Bug 1288812 - we should only serialize fragment for local-ref URL.
nsCOMPtr<nsIURI> markerURI = StyleSVG()->mMarkerStart.GetSourceURL();
if (markerURI)
val->SetURI(markerURI);
else
val->SetIdent(eCSSKeyword_none);
SetValueToFragmentOrURL(&StyleSVG()->mMarkerStart, val);
return val.forget();
}
@ -5915,11 +5916,11 @@ nsComputedDOMStyle::BasicShapeRadiiToString(nsAString& aCssText,
already_AddRefed<CSSValue>
nsComputedDOMStyle::CreatePrimitiveValueForBasicShape(
const nsStyleBasicShape* aStyleBasicShape)
const StyleBasicShape* aStyleBasicShape)
{
MOZ_ASSERT(aStyleBasicShape, "Expect a valid basic shape pointer!");
nsStyleBasicShape::Type type = aStyleBasicShape->GetShapeType();
StyleBasicShapeType type = aStyleBasicShape->GetShapeType();
// Shape function name and opening parenthesis.
nsAutoString shapeFunctionString;
AppendASCIItoUTF16(nsCSSKeywords::GetStringValue(
@ -5927,7 +5928,7 @@ nsComputedDOMStyle::CreatePrimitiveValueForBasicShape(
shapeFunctionString);
shapeFunctionString.Append('(');
switch (type) {
case nsStyleBasicShape::Type::ePolygon: {
case StyleBasicShapeType::Polygon: {
bool hasEvenOdd = aStyleBasicShape->GetFillRule() ==
NS_STYLE_FILL_RULE_EVENODD;
if (hasEvenOdd) {
@ -5949,11 +5950,11 @@ nsComputedDOMStyle::CreatePrimitiveValueForBasicShape(
}
break;
}
case nsStyleBasicShape::Type::eCircle:
case nsStyleBasicShape::Type::eEllipse: {
case StyleBasicShapeType::Circle:
case StyleBasicShapeType::Ellipse: {
const nsTArray<nsStyleCoord>& radii = aStyleBasicShape->Coordinates();
MOZ_ASSERT(radii.Length() ==
(type == nsStyleBasicShape::Type::eCircle ? 1 : 2),
(type == StyleBasicShapeType::Circle ? 1 : 2),
"wrong number of radii");
for (size_t i = 0; i < radii.Length(); ++i) {
nsAutoString radius;
@ -5974,7 +5975,7 @@ nsComputedDOMStyle::CreatePrimitiveValueForBasicShape(
shapeFunctionString.Append(positionString);
break;
}
case nsStyleBasicShape::Type::eInset: {
case StyleBasicShapeType::Inset: {
BoxValuesToString(shapeFunctionString, aStyleBasicShape->Coordinates());
if (aStyleBasicShape->HasRadius()) {
shapeFunctionString.AppendLiteral(" round ");
@ -5993,10 +5994,12 @@ nsComputedDOMStyle::CreatePrimitiveValueForBasicShape(
return functionValue.forget();
}
template<typename ReferenceBox>
already_AddRefed<CSSValue>
nsComputedDOMStyle::CreatePrimitiveValueForClipPath(
const nsStyleBasicShape* aStyleBasicShape,
StyleClipShapeSizing aSizingBox)
nsComputedDOMStyle::CreatePrimitiveValueForShapeSource(
const StyleBasicShape* aStyleBasicShape,
ReferenceBox aReferenceBox,
const KTableEntry aBoxKeywordTable[])
{
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
if (aStyleBasicShape) {
@ -6004,41 +6007,38 @@ nsComputedDOMStyle::CreatePrimitiveValueForClipPath(
CreatePrimitiveValueForBasicShape(aStyleBasicShape));
}
if (aSizingBox == StyleClipShapeSizing::NoBox) {
if (aReferenceBox == ReferenceBox::NoBox) {
return valueList.forget();
}
nsAutoString boxString;
AppendASCIItoUTF16(
nsCSSProps::ValueToKeyword(aSizingBox,
nsCSSProps::kClipShapeSizingKTable),
boxString);
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetString(boxString);
val->SetIdent(nsCSSProps::ValueToKeywordEnum(aReferenceBox, aBoxKeywordTable));
valueList->AppendCSSValue(val.forget());
return valueList.forget();
}
template<typename ReferenceBox>
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetClipPath()
nsComputedDOMStyle::GetShapeSource(
const StyleShapeSource<ReferenceBox>& aShapeSource,
const KTableEntry aBoxKeywordTable[])
{
const nsStyleSVGReset* svg = StyleSVGReset();
switch (svg->mClipPath.GetType()) {
case StyleClipPathType::Shape:
return CreatePrimitiveValueForClipPath(svg->mClipPath.GetBasicShape(),
svg->mClipPath.GetSizingBox());
case StyleClipPathType::Box:
return CreatePrimitiveValueForClipPath(nullptr,
svg->mClipPath.GetSizingBox());
case StyleClipPathType::URL: {
// Bug 1288812 - we should only serialize fragment for local-ref URL.
nsCOMPtr<nsIURI> pathURI = svg->mClipPath.GetURL()->GetSourceURL();
switch (aShapeSource.GetType()) {
case StyleShapeSourceType::Shape:
return CreatePrimitiveValueForShapeSource(aShapeSource.GetBasicShape(),
aShapeSource.GetReferenceBox(),
aBoxKeywordTable);
case StyleShapeSourceType::Box:
return CreatePrimitiveValueForShapeSource(nullptr,
aShapeSource.GetReferenceBox(),
aBoxKeywordTable);
case StyleShapeSourceType::URL: {
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetURI(pathURI);
SetValueToFragmentOrURL(aShapeSource.GetURL(), val);
return val.forget();
}
case StyleClipPathType::None_: {
case StyleShapeSourceType::None_: {
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetIdent(eCSSKeyword_none);
return val.forget();
@ -6049,6 +6049,20 @@ nsComputedDOMStyle::DoGetClipPath()
return nullptr;
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetClipPath()
{
return GetShapeSource(StyleSVGReset()->mClipPath,
nsCSSProps::kClipPathGeometryBoxKTable);
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetShapeOutside()
{
return GetShapeSource(StyleDisplay()->mShapeOutside,
nsCSSProps::kShapeOutsideShapeBoxKTable);
}
void
nsComputedDOMStyle::SetCssTextToCoord(nsAString& aCssText,
const nsStyleCoord& aCoord)
@ -6066,9 +6080,8 @@ nsComputedDOMStyle::CreatePrimitiveValueForStyleFilter(
RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
// Handle url().
if (aStyleFilter.GetType() == NS_STYLE_FILTER_URL) {
// Bug 1288812 - we should only serialize fragment for local-ref URL.
nsCOMPtr<nsIURI> filterURI = aStyleFilter.GetURL()->GetSourceURL();
value->SetURI(filterURI);
MOZ_ASSERT(aStyleFilter.GetURL()->GetSourceURL());
SetValueToFragmentOrURL(aStyleFilter.GetURL(), value);
return value.forget();
}
@ -6146,7 +6159,7 @@ nsComputedDOMStyle::DoGetMask()
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
if (firstLayer.mSourceURI.GetSourceURL()) {
val->SetURI(firstLayer.mSourceURI.GetSourceURL());
SetValueToFragmentOrURL(&firstLayer.mSourceURI, val);
} else {
val->SetIdent(eCSSKeyword_none);
}

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

@ -481,6 +481,7 @@ private:
already_AddRefed<CSSValue> DoGetScrollSnapPointsY();
already_AddRefed<CSSValue> DoGetScrollSnapDestination();
already_AddRefed<CSSValue> DoGetScrollSnapCoordinate();
already_AddRefed<CSSValue> DoGetShapeOutside();
/* User interface properties */
already_AddRefed<CSSValue> DoGetCursor();
@ -589,6 +590,8 @@ private:
nsROCSSPrimitiveValue* aValue);
void SetValueToPosition(const nsStyleImageLayers::Position& aPosition,
nsDOMCSSValueList* aValueList);
void SetValueToFragmentOrURL(const FragmentOrURL* aFragmentOrURL,
nsROCSSPrimitiveValue* aValue);
/**
* A method to get a percentage base for a percentage value. Returns true
@ -643,13 +646,21 @@ private:
already_AddRefed<CSSValue> CreatePrimitiveValueForStyleFilter(
const nsStyleFilter& aStyleFilter);
already_AddRefed<CSSValue> CreatePrimitiveValueForClipPath(
const nsStyleBasicShape* aStyleBasicShape,
mozilla::StyleClipShapeSizing aSizingBox);
template<typename ReferenceBox>
already_AddRefed<CSSValue>
GetShapeSource(const mozilla::StyleShapeSource<ReferenceBox>& aShapeSource,
const KTableEntry aBoxKeywordTable[]);
template<typename ReferenceBox>
already_AddRefed<CSSValue>
CreatePrimitiveValueForShapeSource(
const mozilla::StyleBasicShape* aStyleBasicShape,
ReferenceBox aReferenceBox,
const KTableEntry aBoxKeywordTable[]);
// Helper function for computing basic shape styles.
already_AddRefed<CSSValue> CreatePrimitiveValueForBasicShape(
const nsStyleBasicShape* aStyleBasicShape);
const mozilla::StyleBasicShape* aStyleBasicShape);
void BoxValuesToString(nsAString& aString,
const nsTArray<nsStyleCoord>& aBoxValues);
void BasicShapeRadiiToString(nsAString& aCssText,

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

@ -217,6 +217,7 @@ COMPUTED_STYLE_PROP(scroll_snap_points_x, ScrollSnapPointsX)
COMPUTED_STYLE_PROP(scroll_snap_points_y, ScrollSnapPointsY)
COMPUTED_STYLE_PROP(scroll_snap_type_x, ScrollSnapTypeX)
COMPUTED_STYLE_PROP(scroll_snap_type_y, ScrollSnapTypeY)
COMPUTED_STYLE_PROP(shape_outside, ShapeOutside)
//// COMPUTED_STYLE_PROP(size, Size)
COMPUTED_STYLE_PROP(table_layout, TableLayout)
COMPUTED_STYLE_PROP(text_align, TextAlign)

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

@ -119,6 +119,14 @@ SetImageRequest(function<void(imgRequestProxy*)> aCallback,
}
}
template<typename ReferenceBox>
static void
SetStyleShapeSourceToCSSValue(StyleShapeSource<ReferenceBox>* aShapeSource,
const nsCSSValue* aValue,
nsStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions);
/* Helper function to convert a CSS <position> specified value into its
* computed-style form. */
static void
@ -6434,6 +6442,35 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
parentDisplay->mOrient,
NS_STYLE_ORIENT_INLINE);
// shape-outside: none | [ <basic-shape> || <shape-box> ] | <image>
const nsCSSValue* shapeOutsideValue = aRuleData->ValueForShapeOutside();
switch (shapeOutsideValue->GetUnit()) {
case eCSSUnit_Null:
break;
case eCSSUnit_None:
case eCSSUnit_Initial:
case eCSSUnit_Unset:
display->mShapeOutside = StyleShapeOutside();
break;
case eCSSUnit_Inherit:
conditions.SetUncacheable();
display->mShapeOutside = parentDisplay->mShapeOutside;
break;
case eCSSUnit_URL: {
display->mShapeOutside = StyleShapeOutside();
display->mShapeOutside.SetURL(shapeOutsideValue);
break;
}
case eCSSUnit_Array: {
display->mShapeOutside = StyleShapeOutside();
SetStyleShapeSourceToCSSValue(&display->mShapeOutside, shapeOutsideValue,
aContext, mPresContext, conditions);
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unrecognized shape-outside unit!");
}
COMPUTE_END_RESET(Display, display)
}
@ -9581,13 +9618,13 @@ nsRuleNode::ComputeSVGData(void* aStartStruct,
COMPUTE_END_INHERITED(SVG, svg)
}
static already_AddRefed<nsStyleBasicShape>
static already_AddRefed<StyleBasicShape>
GetStyleBasicShapeFromCSSValue(const nsCSSValue& aValue,
nsStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
RefPtr<nsStyleBasicShape> basicShape;
RefPtr<StyleBasicShape> basicShape;
nsCSSValue::Array* shapeFunction = aValue.GetArrayValue();
nsCSSKeyword functionName =
@ -9595,7 +9632,7 @@ GetStyleBasicShapeFromCSSValue(const nsCSSValue& aValue,
if (functionName == eCSSKeyword_polygon) {
MOZ_ASSERT(!basicShape, "did not expect value");
basicShape = new nsStyleBasicShape(nsStyleBasicShape::ePolygon);
basicShape = new StyleBasicShape(StyleBasicShapeType::Polygon);
MOZ_ASSERT(shapeFunction->Count() > 1,
"polygon has wrong number of arguments");
size_t j = 1;
@ -9626,17 +9663,17 @@ GetStyleBasicShapeFromCSSValue(const nsCSSValue& aValue,
}
} else if (functionName == eCSSKeyword_circle ||
functionName == eCSSKeyword_ellipse) {
nsStyleBasicShape::Type type = functionName == eCSSKeyword_circle ?
nsStyleBasicShape::eCircle :
nsStyleBasicShape::eEllipse;
StyleBasicShapeType type = functionName == eCSSKeyword_circle ?
StyleBasicShapeType::Circle :
StyleBasicShapeType::Ellipse;
MOZ_ASSERT(!basicShape, "did not expect value");
basicShape = new nsStyleBasicShape(type);
basicShape = new StyleBasicShape(type);
const int32_t mask = SETCOORD_PERCENT | SETCOORD_LENGTH |
SETCOORD_STORE_CALC | SETCOORD_ENUMERATED;
size_t count = type == nsStyleBasicShape::eCircle ? 2 : 3;
size_t count = type == StyleBasicShapeType::Circle ? 2 : 3;
MOZ_ASSERT(shapeFunction->Count() == count + 1,
"unexpected arguments count");
MOZ_ASSERT(type == nsStyleBasicShape::eCircle ||
MOZ_ASSERT(type == StyleBasicShapeType::Circle ||
(shapeFunction->Item(1).GetUnit() == eCSSUnit_Null) ==
(shapeFunction->Item(2).GetUnit() == eCSSUnit_Null),
"ellipse should have two radii or none");
@ -9666,7 +9703,7 @@ GetStyleBasicShapeFromCSSValue(const nsCSSValue& aValue,
}
} else if (functionName == eCSSKeyword_inset) {
MOZ_ASSERT(!basicShape, "did not expect value");
basicShape = new nsStyleBasicShape(nsStyleBasicShape::eInset);
basicShape = new StyleBasicShape(StyleBasicShapeType::Inset);
MOZ_ASSERT(shapeFunction->Count() == 6,
"inset function has wrong number of arguments");
MOZ_ASSERT(shapeFunction->Item(1).GetUnit() != eCSSUnit_Null,
@ -9730,44 +9767,42 @@ GetStyleBasicShapeFromCSSValue(const nsCSSValue& aValue,
return basicShape.forget();
}
template<typename ReferenceBox>
static void
SetStyleClipPathToCSSValue(nsStyleClipPath* aStyleClipPath,
const nsCSSValue* aValue,
nsStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
SetStyleShapeSourceToCSSValue(
StyleShapeSource<ReferenceBox>* aShapeSource,
const nsCSSValue* aValue,
nsStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
MOZ_ASSERT(aValue->GetUnit() == eCSSUnit_Array,
"expected a basic shape or reference box");
const nsCSSValue::Array* array = aValue->GetArrayValue();
MOZ_ASSERT(array->Count() == 1 || array->Count() == 2,
"Expect one or both of a shape function and geometry-box");
"Expect one or both of a shape function and a reference box");
ReferenceBox referenceBox = ReferenceBox::NoBox;
RefPtr<StyleBasicShape> basicShape;
StyleClipShapeSizing sizingBox = StyleClipShapeSizing::NoBox;
RefPtr<nsStyleBasicShape> basicShape;
for (size_t i = 0; i < array->Count(); ++i) {
if (array->Item(i).GetUnit() == eCSSUnit_Enumerated) {
int32_t type = array->Item(i).GetIntValue();
if (type > uint8_t(StyleClipShapeSizing::View) ||
type < uint8_t(StyleClipShapeSizing::NoBox)) {
NS_NOTREACHED("unexpected reference box");
return;
}
sizingBox = static_cast<StyleClipShapeSizing>(type);
} else if (array->Item(i).GetUnit() == eCSSUnit_Function) {
basicShape = GetStyleBasicShapeFromCSSValue(array->Item(i), aStyleContext,
const nsCSSValue& item = array->Item(i);
if (item.GetUnit() == eCSSUnit_Enumerated) {
referenceBox = static_cast<ReferenceBox>(item.GetIntValue());
} else if (item.GetUnit() == eCSSUnit_Function) {
basicShape = GetStyleBasicShapeFromCSSValue(item, aStyleContext,
aPresContext, aConditions);
} else {
NS_NOTREACHED("unexpected value");
MOZ_ASSERT_UNREACHABLE("Unexpected unit!");
return;
}
}
if (basicShape) {
aStyleClipPath->SetBasicShape(basicShape, sizingBox);
aShapeSource->SetBasicShape(basicShape, referenceBox);
} else {
aStyleClipPath->SetSizingBox(sizingBox);
aShapeSource->SetReferenceBox(referenceBox);
}
}
@ -9879,21 +9914,21 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
case eCSSUnit_None:
case eCSSUnit_Initial:
case eCSSUnit_Unset:
svgReset->mClipPath = nsStyleClipPath();
svgReset->mClipPath = StyleClipPath();
break;
case eCSSUnit_Inherit:
conditions.SetUncacheable();
svgReset->mClipPath = parentSVGReset->mClipPath;
break;
case eCSSUnit_URL: {
svgReset->mClipPath = nsStyleClipPath();
svgReset->mClipPath = StyleClipPath();
svgReset->mClipPath.SetURL(clipPathValue);
break;
}
case eCSSUnit_Array: {
svgReset->mClipPath = nsStyleClipPath();
SetStyleClipPathToCSSValue(&svgReset->mClipPath, clipPathValue, aContext,
mPresContext, conditions);
svgReset->mClipPath = StyleClipPath();
SetStyleShapeSourceToCSSValue(&svgReset->mClipPath, clipPathValue, aContext,
mPresContext, conditions);
break;
}
default:

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

@ -54,8 +54,8 @@ static inline css::Side operator++(css::Side& side, int) {
#define NS_SIDE_TO_HALF_CORNER(side_, second_, parallel_) \
((((side_) + !!(second_))*2 + ((side_) + !(parallel_))%2) % 8)
// Basic Shapes (currently unused)
enum class StyleBasicShape : uint8_t{
// Basic shapes
enum class StyleBasicShapeType : uint8_t {
Polygon,
Circle,
Ellipse,
@ -73,17 +73,8 @@ enum class StyleBoxShadowType : uint8_t {
Inset,
};
// clip-path type
// X11 has a #define for None causing conflicts, so we use None_ here
enum class StyleClipPathType : uint8_t {
None_,
URL,
Shape,
Box,
};
// clip-path sizing
enum class StyleClipShapeSizing : uint8_t {
// clip-path geometry box
enum class StyleClipPathGeometryBox : uint8_t {
NoBox,
Content,
Padding,
@ -100,6 +91,24 @@ enum class StyleFloatEdge : uint8_t {
MarginBox,
};
// shape-box for shape-outside
enum class StyleShapeOutsideShapeBox : uint8_t {
NoBox,
Content,
Padding,
Border,
Margin
};
// Shape source type
// X11 has a #define for None causing conflicts, so we use None_ here
enum class StyleShapeSourceType : uint8_t {
None_,
URL,
Shape,
Box,
};
// user-focus
// X11 has a #define for None causing conflicts, so we use None_ here
enum class StyleUserFocus : uint8_t {

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

@ -1086,153 +1086,25 @@ nsStyleSVG::CalcDifference(const nsStyleSVG& aNewData) const
}
// --------------------
// nsStyleBasicShape
// StyleBasicShape
nsCSSKeyword
nsStyleBasicShape::GetShapeTypeName() const
StyleBasicShape::GetShapeTypeName() const
{
switch (mType) {
case nsStyleBasicShape::Type::ePolygon:
case StyleBasicShapeType::Polygon:
return eCSSKeyword_polygon;
case nsStyleBasicShape::Type::eCircle:
case StyleBasicShapeType::Circle:
return eCSSKeyword_circle;
case nsStyleBasicShape::Type::eEllipse:
case StyleBasicShapeType::Ellipse:
return eCSSKeyword_ellipse;
case nsStyleBasicShape::Type::eInset:
case StyleBasicShapeType::Inset:
return eCSSKeyword_inset;
}
NS_NOTREACHED("unexpected type");
return eCSSKeyword_UNKNOWN;
}
// --------------------
// nsStyleClipPath
//
nsStyleClipPath::nsStyleClipPath()
: mURL(nullptr)
, mType(StyleClipPathType::None_)
, mSizingBox(StyleClipShapeSizing::NoBox)
{
}
nsStyleClipPath::nsStyleClipPath(const nsStyleClipPath& aSource)
: mURL(nullptr)
, mType(StyleClipPathType::None_)
, mSizingBox(StyleClipShapeSizing::NoBox)
{
if (aSource.mType == StyleClipPathType::URL) {
CopyURL(aSource);
} else if (aSource.mType == StyleClipPathType::Shape) {
SetBasicShape(aSource.mBasicShape, aSource.mSizingBox);
} else if (aSource.mType == StyleClipPathType::Box) {
SetSizingBox(aSource.mSizingBox);
}
}
nsStyleClipPath::~nsStyleClipPath()
{
ReleaseRef();
}
nsStyleClipPath&
nsStyleClipPath::operator=(const nsStyleClipPath& aOther)
{
if (this == &aOther) {
return *this;
}
if (aOther.mType == StyleClipPathType::URL) {
CopyURL(aOther);
} else if (aOther.mType == StyleClipPathType::Shape) {
SetBasicShape(aOther.mBasicShape, aOther.mSizingBox);
} else if (aOther.mType == StyleClipPathType::Box) {
SetSizingBox(aOther.mSizingBox);
} else {
ReleaseRef();
mSizingBox = StyleClipShapeSizing::NoBox;
mType = StyleClipPathType::None_;
}
return *this;
}
bool
nsStyleClipPath::operator==(const nsStyleClipPath& aOther) const
{
if (mType != aOther.mType) {
return false;
}
if (mType == StyleClipPathType::URL) {
return EqualURIs(mURL, aOther.mURL);
} else if (mType == StyleClipPathType::Shape) {
return *mBasicShape == *aOther.mBasicShape &&
mSizingBox == aOther.mSizingBox;
} else if (mType == StyleClipPathType::Box) {
return mSizingBox == aOther.mSizingBox;
}
return true;
}
void
nsStyleClipPath::ReleaseRef()
{
if (mType == StyleClipPathType::Shape) {
NS_ASSERTION(mBasicShape, "expected pointer");
mBasicShape->Release();
} else if (mType == StyleClipPathType::URL) {
NS_ASSERTION(mURL, "expected pointer");
delete mURL;
}
// mBasicShap, mURL, etc. are all pointers in a union of pointers. Nulling
// one of them nulls all of them:
mURL = nullptr;
}
void
nsStyleClipPath::CopyURL(const nsStyleClipPath& aOther)
{
ReleaseRef();
mURL = new FragmentOrURL(*aOther.mURL);
mType = StyleClipPathType::URL;
}
bool
nsStyleClipPath::SetURL(const nsCSSValue* aValue)
{
if (!aValue->GetURLValue()) {
return false;
}
ReleaseRef();
mURL = new FragmentOrURL();
mURL->SetValue(aValue);
mType = StyleClipPathType::URL;
return true;
}
void
nsStyleClipPath::SetBasicShape(nsStyleBasicShape* aBasicShape,
StyleClipShapeSizing aSizingBox)
{
NS_ASSERTION(aBasicShape, "expected pointer");
ReleaseRef();
mBasicShape = aBasicShape;
mBasicShape->AddRef();
mSizingBox = aSizingBox;
mType = StyleClipPathType::Shape;
}
void
nsStyleClipPath::SetSizingBox(StyleClipShapeSizing aSizingBox)
{
ReleaseRef();
mSizingBox = aSizingBox;
mType = StyleClipPathType::Box;
}
// --------------------
// nsStyleFilter
//
@ -2755,27 +2627,27 @@ nsStyleImageLayers::Size::operator==(const Size& aOther) const
bool
nsStyleImageLayers::Repeat::IsInitialValue(LayerType aType) const
{
if (aType == LayerType::Background ||
aType == LayerType::Mask) {
// bug 1258623 - mask-repeat initial value should be no-repeat
if (aType == LayerType::Background) {
return mXRepeat == NS_STYLE_IMAGELAYER_REPEAT_REPEAT &&
mYRepeat == NS_STYLE_IMAGELAYER_REPEAT_REPEAT;
} else {
MOZ_ASSERT(aType == LayerType::Mask);
return mXRepeat == NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT &&
mYRepeat == NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT;
}
MOZ_ASSERT_UNREACHABLE("unsupported layer type.");
return false;
}
void
nsStyleImageLayers::Repeat::SetInitialValues(LayerType aType)
{
if (aType == LayerType::Background ||
aType == LayerType::Mask) {
// bug 1258623 - mask-repeat initial value should be no-repeat
if (aType == LayerType::Background) {
mXRepeat = NS_STYLE_IMAGELAYER_REPEAT_REPEAT;
mYRepeat = NS_STYLE_IMAGELAYER_REPEAT_REPEAT;
} else {
MOZ_ASSERT_UNREACHABLE("unsupported layer type.");
MOZ_ASSERT(aType == LayerType::Mask);
mXRepeat = NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT;
mYRepeat = NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT;
}
}
@ -3210,6 +3082,7 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
, mAnimationFillModeCount(aSource.mAnimationFillModeCount)
, mAnimationPlayStateCount(aSource.mAnimationPlayStateCount)
, mAnimationIterationCountCount(aSource.mAnimationIterationCountCount)
, mShapeOutside(aSource.mShapeOutside)
{
MOZ_COUNT_CTOR(nsStyleDisplay);
@ -3434,7 +3307,8 @@ nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const
mAnimationFillModeCount != aNewData.mAnimationFillModeCount ||
mAnimationPlayStateCount != aNewData.mAnimationPlayStateCount ||
mAnimationIterationCountCount != aNewData.mAnimationIterationCountCount ||
mScrollSnapCoordinate != aNewData.mScrollSnapCoordinate)) {
mScrollSnapCoordinate != aNewData.mScrollSnapCoordinate ||
mShapeOutside != aNewData.mShapeOutside)) {
hint |= nsChangeHint_NeutralChange;
}

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

@ -2523,6 +2523,259 @@ private:
float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
};
class StyleBasicShape final
{
public:
explicit StyleBasicShape(StyleBasicShapeType type)
: mType(type),
mFillRule(NS_STYLE_FILL_RULE_NONZERO)
{
mPosition.SetInitialPercentValues(0.5f);
}
StyleBasicShapeType GetShapeType() const { return mType; }
nsCSSKeyword GetShapeTypeName() const;
int32_t GetFillRule() const { return mFillRule; }
void SetFillRule(int32_t aFillRule)
{
MOZ_ASSERT(mType == StyleBasicShapeType::Polygon, "expected polygon");
mFillRule = aFillRule;
}
typedef nsStyleImageLayers::Position Position;
Position& GetPosition() {
MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
mType == StyleBasicShapeType::Ellipse,
"expected circle or ellipse");
return mPosition;
}
const Position& GetPosition() const {
MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
mType == StyleBasicShapeType::Ellipse,
"expected circle or ellipse");
return mPosition;
}
bool HasRadius() const {
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
nsStyleCoord zero;
zero.SetCoordValue(0);
NS_FOR_CSS_HALF_CORNERS(corner) {
if (mRadius.Get(corner) != zero) {
return true;
}
}
return false;
}
nsStyleCorners& GetRadius() {
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
return mRadius;
}
const nsStyleCorners& GetRadius() const {
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
return mRadius;
}
// mCoordinates has coordinates for polygon or radii for
// ellipse and circle.
nsTArray<nsStyleCoord>& Coordinates()
{
return mCoordinates;
}
const nsTArray<nsStyleCoord>& Coordinates() const
{
return mCoordinates;
}
bool operator==(const StyleBasicShape& aOther) const
{
return mType == aOther.mType &&
mFillRule == aOther.mFillRule &&
mCoordinates == aOther.mCoordinates &&
mPosition == aOther.mPosition &&
mRadius == aOther.mRadius;
}
bool operator!=(const StyleBasicShape& aOther) const {
return !(*this == aOther);
}
NS_INLINE_DECL_REFCOUNTING(StyleBasicShape);
private:
~StyleBasicShape() {}
StyleBasicShapeType mType;
int32_t mFillRule;
// mCoordinates has coordinates for polygon or radii for
// ellipse and circle.
nsTArray<nsStyleCoord> mCoordinates;
Position mPosition;
nsStyleCorners mRadius;
};
template<typename ReferenceBox>
struct StyleShapeSource
{
StyleShapeSource()
: mURL(nullptr)
{}
StyleShapeSource(const StyleShapeSource& aSource)
: StyleShapeSource()
{
if (aSource.mType == StyleShapeSourceType::URL) {
CopyURL(aSource);
} else if (aSource.mType == StyleShapeSourceType::Shape) {
SetBasicShape(aSource.mBasicShape, aSource.mReferenceBox);
} else if (aSource.mType == StyleShapeSourceType::Box) {
SetReferenceBox(aSource.mReferenceBox);
}
}
~StyleShapeSource()
{
ReleaseRef();
}
StyleShapeSource& operator=(const StyleShapeSource& aOther)
{
if (this == &aOther) {
return *this;
}
if (aOther.mType == StyleShapeSourceType::URL) {
CopyURL(aOther);
} else if (aOther.mType == StyleShapeSourceType::Shape) {
SetBasicShape(aOther.mBasicShape, aOther.mReferenceBox);
} else if (aOther.mType == StyleShapeSourceType::Box) {
SetReferenceBox(aOther.mReferenceBox);
} else {
ReleaseRef();
mReferenceBox = ReferenceBox::NoBox;
mType = StyleShapeSourceType::None_;
}
return *this;
}
bool operator==(const StyleShapeSource& aOther) const
{
if (mType != aOther.mType) {
return false;
}
if (mType == StyleShapeSourceType::URL) {
return mURL == aOther.mURL;
} else if (mType == StyleShapeSourceType::Shape) {
return *mBasicShape == *aOther.mBasicShape &&
mReferenceBox == aOther.mReferenceBox;
} else if (mType == StyleShapeSourceType::Box) {
return mReferenceBox == aOther.mReferenceBox;
}
return true;
}
bool operator!=(const StyleShapeSource& aOther) const
{
return !(*this == aOther);
}
StyleShapeSourceType GetType() const
{
return mType;
}
FragmentOrURL* GetURL() const
{
MOZ_ASSERT(mType == StyleShapeSourceType::URL, "Wrong shape source type!");
return mURL;
}
bool SetURL(const nsCSSValue* aValue)
{
if (!aValue->GetURLValue()) {
return false;
}
ReleaseRef();
mURL = new FragmentOrURL();
mURL->SetValue(aValue);
mType = StyleShapeSourceType::URL;
return true;
}
StyleBasicShape* GetBasicShape() const
{
MOZ_ASSERT(mType == StyleShapeSourceType::Shape, "Wrong shape source type!");
return mBasicShape;
}
void SetBasicShape(StyleBasicShape* aBasicShape,
ReferenceBox aReferenceBox)
{
NS_ASSERTION(aBasicShape, "expected pointer");
ReleaseRef();
mBasicShape = aBasicShape;
mBasicShape->AddRef();
mReferenceBox = aReferenceBox;
mType = StyleShapeSourceType::Shape;
}
ReferenceBox GetReferenceBox() const
{
MOZ_ASSERT(mType == StyleShapeSourceType::Box ||
mType == StyleShapeSourceType::Shape,
"Wrong shape source type!");
return mReferenceBox;
}
void SetReferenceBox(ReferenceBox aReferenceBox)
{
ReleaseRef();
mReferenceBox = aReferenceBox;
mType = StyleShapeSourceType::Box;
}
private:
void ReleaseRef()
{
if (mType == StyleShapeSourceType::Shape) {
NS_ASSERTION(mBasicShape, "expected pointer");
mBasicShape->Release();
} else if (mType == StyleShapeSourceType::URL) {
NS_ASSERTION(mURL, "expected pointer");
delete mURL;
}
// Both mBasicShape and mURL are pointers in a union. Nulling one of them
// nulls both of them.
mURL = nullptr;
}
void CopyURL(const StyleShapeSource& aOther)
{
ReleaseRef();
mURL = new FragmentOrURL(*aOther.mURL);
mType = StyleShapeSourceType::URL;
}
void* operator new(size_t) = delete;
union {
StyleBasicShape* mBasicShape;
FragmentOrURL* mURL;
};
StyleShapeSourceType mType = StyleShapeSourceType::None_;
ReferenceBox mReferenceBox = ReferenceBox::NoBox;
};
using StyleClipPath = StyleShapeSource<StyleClipPathGeometryBox>;
using StyleShapeOutside = StyleShapeSource<StyleShapeOutsideShapeBox>;
} // namespace mozilla
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
@ -2644,6 +2897,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
mAnimationPlayStateCount,
mAnimationIterationCountCount;
mozilla::StyleShapeOutside mShapeOutside; // [reset]
bool IsBlockInsideStyle() const {
return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
@ -3436,153 +3691,6 @@ private:
uint8_t mContextFlags; // [inherited]
};
class nsStyleBasicShape final
{
public:
enum Type {
eInset,
eCircle,
eEllipse,
ePolygon
};
explicit nsStyleBasicShape(Type type)
: mType(type),
mFillRule(NS_STYLE_FILL_RULE_NONZERO)
{
mPosition.SetInitialPercentValues(0.5f);
}
Type GetShapeType() const { return mType; }
nsCSSKeyword GetShapeTypeName() const;
int32_t GetFillRule() const { return mFillRule; }
void SetFillRule(int32_t aFillRule)
{
NS_ASSERTION(mType == ePolygon, "expected polygon");
mFillRule = aFillRule;
}
typedef nsStyleImageLayers::Position Position;
Position& GetPosition() {
NS_ASSERTION(mType == eCircle || mType == eEllipse,
"expected circle or ellipse");
return mPosition;
}
const Position& GetPosition() const {
NS_ASSERTION(mType == eCircle || mType == eEllipse,
"expected circle or ellipse");
return mPosition;
}
bool HasRadius() const {
NS_ASSERTION(mType == eInset, "expected inset");
nsStyleCoord zero;
zero.SetCoordValue(0);
NS_FOR_CSS_HALF_CORNERS(corner) {
if (mRadius.Get(corner) != zero) {
return true;
}
}
return false;
}
nsStyleCorners& GetRadius() {
NS_ASSERTION(mType == eInset, "expected inset");
return mRadius;
}
const nsStyleCorners& GetRadius() const {
NS_ASSERTION(mType == eInset, "expected inset");
return mRadius;
}
// mCoordinates has coordinates for polygon or radii for
// ellipse and circle.
nsTArray<nsStyleCoord>& Coordinates()
{
return mCoordinates;
}
const nsTArray<nsStyleCoord>& Coordinates() const
{
return mCoordinates;
}
bool operator==(const nsStyleBasicShape& aOther) const
{
return mType == aOther.mType &&
mFillRule == aOther.mFillRule &&
mCoordinates == aOther.mCoordinates &&
mPosition == aOther.mPosition &&
mRadius == aOther.mRadius;
}
bool operator!=(const nsStyleBasicShape& aOther) const {
return !(*this == aOther);
}
NS_INLINE_DECL_REFCOUNTING(nsStyleBasicShape);
private:
~nsStyleBasicShape() {}
Type mType;
int32_t mFillRule;
// mCoordinates has coordinates for polygon or radii for
// ellipse and circle.
nsTArray<nsStyleCoord> mCoordinates;
Position mPosition;
nsStyleCorners mRadius;
};
struct nsStyleClipPath
{
nsStyleClipPath();
nsStyleClipPath(const nsStyleClipPath& aSource);
~nsStyleClipPath();
nsStyleClipPath& operator=(const nsStyleClipPath& aOther);
bool operator==(const nsStyleClipPath& aOther) const;
bool operator!=(const nsStyleClipPath& aOther) const {
return !(*this == aOther);
}
mozilla::StyleClipPathType GetType() const {
return mType;
}
FragmentOrURL* GetURL() const {
NS_ASSERTION(mType == mozilla::StyleClipPathType::URL, "wrong clip-path type");
return mURL;
}
bool SetURL(const nsCSSValue* aValue);
nsStyleBasicShape* GetBasicShape() const {
NS_ASSERTION(mType == mozilla::StyleClipPathType::Shape, "wrong clip-path type");
return mBasicShape;
}
void SetBasicShape(nsStyleBasicShape* mBasicShape,
mozilla::StyleClipShapeSizing aSizingBox =
mozilla::StyleClipShapeSizing::NoBox);
mozilla::StyleClipShapeSizing GetSizingBox() const { return mSizingBox; }
void SetSizingBox(mozilla::StyleClipShapeSizing aSizingBox);
private:
void ReleaseRef();
void CopyURL(const nsStyleClipPath& aOther);
void* operator new(size_t) = delete;
union {
nsStyleBasicShape* mBasicShape;
FragmentOrURL* mURL;
};
mozilla::StyleClipPathType mType;
mozilla::StyleClipShapeSizing mSizingBox;
};
struct nsStyleFilter
{
nsStyleFilter();
@ -3670,7 +3778,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset
}
bool HasClipPath() const {
return mClipPath.GetType() != mozilla::StyleClipPathType::None_;
return mClipPath.GetType() != mozilla::StyleShapeSourceType::None_;
}
bool HasNonScalingStroke() const {
@ -3678,7 +3786,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset
}
nsStyleImageLayers mMask;
nsStyleClipPath mClipPath; // [reset]
mozilla::StyleClipPath mClipPath; // [reset]
nscolor mStopColor; // [reset]
nscolor mFloodColor; // [reset]
nscolor mLightingColor; // [reset]

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

@ -5598,6 +5598,173 @@ if (IsCSSPropertyPrefEnabled("svg.transform-box.enabled")) {
};
}
var basicShapeOtherValues = [
"polygon(20px 20px)",
"polygon(20px 20%)",
"polygon(20% 20%)",
"polygon(20rem 20em)",
"polygon(20cm 20mm)",
"polygon(20px 20px, 30px 30px)",
"polygon(20px 20px, 30% 30%, 30px 30px)",
"polygon(nonzero, 20px 20px, 30% 30%, 30px 30px)",
"polygon(evenodd, 20px 20px, 30% 30%, 30px 30px)",
"content-box",
"padding-box",
"border-box",
"margin-box",
"polygon(0 0) content-box",
"border-box polygon(0 0)",
"padding-box polygon( 0 20px , 30px 20% ) ",
"polygon(evenodd, 20% 20em) content-box",
"polygon(evenodd, 20vh 20em) padding-box",
"polygon(evenodd, 20vh calc(20% + 20em)) border-box",
"polygon(evenodd, 20vh 20vw) margin-box",
"circle()",
"circle(at center)",
"circle(at top left 20px)",
"circle(at bottom right)",
"circle(20%)",
"circle(300px)",
"circle(calc(20px + 30px))",
"circle(farthest-side)",
"circle(closest-side)",
"circle(closest-side at center)",
"circle(farthest-side at top)",
"circle(20px at top right)",
"circle(40% at 50% 100%)",
"circle(calc(20% + 20%) at right bottom)",
"circle() padding-box",
"ellipse()",
"ellipse(at center)",
"ellipse(at top left 20px)",
"ellipse(at bottom right)",
"ellipse(20% 20%)",
"ellipse(300px 50%)",
"ellipse(calc(20px + 30px) 10%)",
"ellipse(farthest-side closest-side)",
"ellipse(closest-side farthest-side)",
"ellipse(farthest-side farthest-side)",
"ellipse(closest-side closest-side)",
"ellipse(closest-side closest-side at center)",
"ellipse(20% farthest-side at top)",
"ellipse(20px 50% at top right)",
"ellipse(closest-side 40% at 50% 100%)",
"ellipse(calc(20% + 20%) calc(20px + 20cm) at right bottom)",
"inset(1px)",
"inset(20% -20px)",
"inset(20em 4rem calc(20% + 20px))",
"inset(20vh 20vw 20pt 3%)",
"inset(5px round 3px)",
"inset(1px 2px round 3px / 3px)",
"inset(1px 2px 3px round 3px 2em / 20%)",
"inset(1px 2px 3px 4px round 3px 2vw 20% / 20px 3em 2vh 20%)",
];
var basicShapeInvalidValues = [
"url(#test) url(#tes2)",
"polygon (0 0)",
"polygon(20px, 40px)",
"border-box content-box",
"polygon(0 0) polygon(0 0)",
"polygon(nonzero 0 0)",
"polygon(evenodd 20px 20px)",
"polygon(20px 20px, evenodd)",
"polygon(20px 20px, nonzero)",
"polygon(0 0) conten-box content-box",
"content-box polygon(0 0) conten-box",
"padding-box polygon(0 0) conten-box",
"polygon(0 0) polygon(0 0) content-box",
"polygon(0 0) content-box polygon(0 0)",
"polygon(0 0), content-box",
"polygon(0 0), polygon(0 0)",
"content-box polygon(0 0) polygon(0 0)",
"content-box polygon(0 0) none",
"none content-box polygon(0 0)",
"inherit content-box polygon(0 0)",
"initial polygon(0 0)",
"polygon(0 0) farthest-side",
"farthest-corner polygon(0 0)",
"polygon(0 0) farthest-corner",
"polygon(0 0) conten-box",
"polygon(0 0) polygon(0 0) farthest-corner",
"polygon(0 0) polygon(0 0) polygon(0 0)",
"border-box polygon(0, 0)",
"border-box padding-box",
"margin-box farthest-side",
"nonsense() border-box",
"border-box nonsense()",
"circle(at)",
"circle(at 20% 20% 30%)",
"circle(20px 2px at center)",
"circle(2at center)",
"circle(closest-corner)",
"circle(at center top closest-side)",
"circle(-20px)",
"circle(farthest-side closest-side)",
"circle(20% 20%)",
"circle(at farthest-side)",
"circle(calc(20px + rubbish))",
"ellipse(at)",
"ellipse(at 20% 20% 30%)",
"ellipse(20px at center)",
"ellipse(-20px 20px)",
"ellipse(closest-corner farthest-corner)",
"ellipse(20px -20px)",
"ellipse(-20px -20px)",
"ellipse(farthest-side)",
"ellipse(20%)",
"ellipse(at farthest-side farthest-side)",
"ellipse(at top left calc(20px + rubbish))",
"polygon(at)",
"polygon(at 20% 20% 30%)",
"polygon(20px at center)",
"polygon(2px 2at center)",
"polygon(closest-corner farthest-corner)",
"polygon(at center top closest-side closest-side)",
"polygon(40% at 50% 100%)",
"polygon(40% farthest-side 20px at 50% 100%)",
"inset()",
"inset(round)",
"inset(round 3px)",
"inset(1px round 1px 2px 3px 4px 5px)",
"inset(1px 2px 3px 4px 5px)",
"inset(1px, round 3px)",
"inset(1px, 2px)",
"inset(1px 2px, 3px)",
"inset(1px at 3px)",
"inset(1px round 1px // 2px)",
"inset(1px round)",
"inset(1px calc(2px + rubbish))",
"inset(1px round 2px calc(3px + rubbish))",
];
var basicShapeUnbalancedValues = [
"polygon(30% 30%",
"polygon(nonzero, 20% 20px",
"polygon(evenodd, 20px 20px",
"circle(",
"circle(40% at 50% 100%",
"ellipse(",
"ellipse(40% at 50% 100%",
"inset(1px",
"inset(1px 2px",
"inset(1px 2px 3px",
"inset(1px 2px 3px 4px",
"inset(1px 2px 3px 4px round 5px",
"inset(1px 2px 3px 4px round 5px / 6px",
];
if (IsCSSPropertyPrefEnabled("layout.css.clip-path-shapes.enabled")) {
gCSSProperties["clip-path"] = {
domProp: "clipPath",
@ -5608,175 +5775,30 @@ if (IsCSSPropertyPrefEnabled("layout.css.clip-path-shapes.enabled")) {
// SVG reference clip-path
"url(#my-clip-path)",
"polygon(20px 20px)",
"polygon(20px 20%)",
"polygon(20% 20%)",
"polygon(20rem 20em)",
"polygon(20cm 20mm)",
"polygon(20px 20px, 30px 30px)",
"polygon(20px 20px, 30% 30%, 30px 30px)",
"polygon(nonzero, 20px 20px, 30% 30%, 30px 30px)",
"polygon(evenodd, 20px 20px, 30% 30%, 30px 30px)",
"content-box",
"padding-box",
"border-box",
"margin-box",
"fill-box",
"stroke-box",
"view-box",
"polygon(0 0) content-box",
"border-box polygon(0 0)",
"padding-box polygon( 0 20px , 30px 20% ) ",
"polygon(evenodd, 20% 20em) content-box",
"polygon(evenodd, 20vh 20em) padding-box",
"polygon(evenodd, 20vh calc(20% + 20em)) border-box",
"polygon(evenodd, 20vh 20vw) margin-box",
"polygon(evenodd, 20pt 20cm) fill-box",
"polygon(evenodd, 20ex 20pc) stroke-box",
"polygon(evenodd, 20rem 20in) view-box",
].concat(basicShapeOtherValues),
invalid_values: basicShapeInvalidValues,
unbalanced_values: basicShapeUnbalancedValues,
};
}
"circle()",
"circle(at center)",
"circle(at top left 20px)",
"circle(at bottom right)",
"circle(20%)",
"circle(300px)",
"circle(calc(20px + 30px))",
"circle(farthest-side)",
"circle(closest-side)",
"circle(closest-side at center)",
"circle(farthest-side at top)",
"circle(20px at top right)",
"circle(40% at 50% 100%)",
"circle(calc(20% + 20%) at right bottom)",
"circle() padding-box",
"ellipse()",
"ellipse(at center)",
"ellipse(at top left 20px)",
"ellipse(at bottom right)",
"ellipse(20% 20%)",
"ellipse(300px 50%)",
"ellipse(calc(20px + 30px) 10%)",
"ellipse(farthest-side closest-side)",
"ellipse(closest-side farthest-side)",
"ellipse(farthest-side farthest-side)",
"ellipse(closest-side closest-side)",
"ellipse(closest-side closest-side at center)",
"ellipse(20% farthest-side at top)",
"ellipse(20px 50% at top right)",
"ellipse(closest-side 40% at 50% 100%)",
"ellipse(calc(20% + 20%) calc(20px + 20cm) at right bottom)",
"inset(1px)",
"inset(20% -20px)",
"inset(20em 4rem calc(20% + 20px))",
"inset(20vh 20vw 20pt 3%)",
"inset(5px round 3px)",
"inset(1px 2px round 3px / 3px)",
"inset(1px 2px 3px round 3px 2em / 20%)",
"inset(1px 2px 3px 4px round 3px 2vw 20% / 20px 3em 2vh 20%)",
],
invalid_values: [
"url(#test) url(#tes2)",
"polygon (0 0)",
"polygon(20px, 40px)",
"border-box content-box",
"polygon(0 0) polygon(0 0)",
"polygon(nonzero 0 0)",
"polygon(evenodd 20px 20px)",
"polygon(20px 20px, evenodd)",
"polygon(20px 20px, nonzero)",
"polygon(0 0) conten-box content-box",
"content-box polygon(0 0) conten-box",
"padding-box polygon(0 0) conten-box",
"polygon(0 0) polygon(0 0) content-box",
"polygon(0 0) content-box polygon(0 0)",
"polygon(0 0), content-box",
"polygon(0 0), polygon(0 0)",
"content-box polygon(0 0) polygon(0 0)",
"content-box polygon(0 0) none",
"none content-box polygon(0 0)",
"inherit content-box polygon(0 0)",
"initial polygon(0 0)",
"polygon(0 0) farthest-side",
"farthest-corner polygon(0 0)",
"polygon(0 0) farthest-corner",
"polygon(0 0) conten-box",
"polygon(0 0) polygon(0 0) farthest-corner",
"polygon(0 0) polygon(0 0) polygon(0 0)",
"border-box polygon(0, 0)",
"border-box padding-box",
"margin-box farthest-side",
"nonsense() border-box",
"border-box nonsense()",
"circle(at)",
"circle(at 20% 20% 30%)",
"circle(20px 2px at center)",
"circle(2at center)",
"circle(closest-corner)",
"circle(at center top closest-side)",
"circle(-20px)",
"circle(farthest-side closest-side)",
"circle(20% 20%)",
"circle(at farthest-side)",
"circle(calc(20px + rubbish))",
"ellipse(at)",
"ellipse(at 20% 20% 30%)",
"ellipse(20px at center)",
"ellipse(-20px 20px)",
"ellipse(closest-corner farthest-corner)",
"ellipse(20px -20px)",
"ellipse(-20px -20px)",
"ellipse(farthest-side)",
"ellipse(20%)",
"ellipse(at farthest-side farthest-side)",
"ellipse(at top left calc(20px + rubbish))",
"polygon(at)",
"polygon(at 20% 20% 30%)",
"polygon(20px at center)",
"polygon(2px 2at center)",
"polygon(closest-corner farthest-corner)",
"polygon(at center top closest-side closest-side)",
"polygon(40% at 50% 100%)",
"polygon(40% farthest-side 20px at 50% 100%)",
"inset()",
"inset(round)",
"inset(round 3px)",
"inset(1px round 1px 2px 3px 4px 5px)",
"inset(1px 2px 3px 4px 5px)",
"inset(1px, round 3px)",
"inset(1px, 2px)",
"inset(1px 2px, 3px)",
"inset(1px at 3px)",
"inset(1px round 1px // 2px)",
"inset(1px round)",
"inset(1px calc(2px + rubbish))",
"inset(1px round 2px calc(3px + rubbish))",
],
unbalanced_values: [
"polygon(30% 30%",
"polygon(nonzero, 20% 20px",
"polygon(evenodd, 20px 20px",
"circle(",
"circle(40% at 50% 100%",
"ellipse(",
"ellipse(40% at 50% 100%",
"inset(1px",
"inset(1px 2px",
"inset(1px 2px 3px",
"inset(1px 2px 3px 4px",
"inset(1px 2px 3px 4px round 5px",
"inset(1px 2px 3px 4px round 5px / 6px",
]
if (IsCSSPropertyPrefEnabled("layout.css.shape-outside.enabled")) {
gCSSProperties["shape-outside"] = {
domProp: "shapeOutside",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [
"url(#my-shape-outside)",
].concat(basicShapeOtherValues),
invalid_values: basicShapeInvalidValues,
unbalanced_values: basicShapeUnbalancedValues,
};
}
@ -6893,20 +6915,20 @@ if (SupportsMaskShorthand()) {
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
/* FIXME: All mask-border-* should be added when we implement them. */
subproperties: ["mask-clip", "mask-image", "mask-mode", "mask-origin", "mask-position-x", "mask-position-y", "mask-repeat", "mask-size" , "mask-composite"],
initial_values: [ "match-source", "none", "repeat", "add", "0% 0%", "top left", "left top", "0% 0% / auto", "top left / auto", "left top / auto", "0% 0% / auto auto",
initial_values: [ "match-source", "none", "no-repeat", "add", "0% 0%", "top left", "left top", "0% 0% / auto", "top left / auto", "left top / auto", "0% 0% / auto auto",
"top left none", "left top none", "none left top", "none top left", "none 0% 0%", "left top / auto none", "left top / auto auto none",
"match-source none repeat add top left", "left top repeat none add", "none repeat add top left / auto", "left top / auto repeat none add match-source", "none repeat add 0% 0% / auto auto match-source",
"match-source none no-repeat add top left", "left top no-repeat none add", "none no-repeat add top left / auto", "left top / auto no-repeat none add match-source", "none no-repeat add 0% 0% / auto auto match-source",
"border-box", "border-box border-box" ],
other_values: [
"none alpha repeat add left top",
"none alpha no-repeat add left top",
"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)",
"repeat url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==') alpha left top add",
"no-repeat url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==') alpha left top add",
"repeat-x",
"repeat-y",
"no-repeat",
"repeat",
"none repeat-y alpha add 0% 0%",
"subtract",
"0% top subtract alpha repeat none",
"0% top subtract alpha no-repeat none",
"top",
"left",
"50% 50%",
@ -6920,16 +6942,16 @@ if (SupportsMaskShorthand()) {
"top left / 100px auto",
"top left / 100px 10%",
"top left / 100px calc(20px)",
"bottom right add none alpha repeat",
"bottom right add none alpha no-repeat",
"50% alpha",
"alpha 50%",
"50%",
"url(#mymask)",
"-moz-radial-gradient(10% bottom, #ffffff, black) add no-repeat",
"-moz-linear-gradient(10px 10px -45deg, red, blue) repeat",
"-moz-linear-gradient(10px 10px -0.125turn, red, blue) repeat",
"-moz-repeating-radial-gradient(10% bottom, #ffffff, black) add no-repeat",
"-moz-repeating-linear-gradient(10px 10px -45deg, red, blue) repeat",
"-moz-radial-gradient(10% bottom, #ffffff, black) add repeat",
"-moz-linear-gradient(10px 10px -45deg, red, blue) no-repeat",
"-moz-linear-gradient(10px 10px -0.125turn, red, blue) no-repeat",
"-moz-repeating-radial-gradient(10% bottom, #ffffff, black) add repeat",
"-moz-repeating-linear-gradient(10px 10px -45deg, red, blue) no-repeat",
"-moz-element(#test) alpha",
/* multiple mask-image */
"url(404.png), url(404.png)",
@ -6950,10 +6972,10 @@ if (SupportsMaskShorthand()) {
/* mixes with keywords have to be in correct order */
"50% left", "top 50%",
/* no quirks mode colors */
"-moz-radial-gradient(10% bottom, ffffff, black) add no-repeat",
"-moz-radial-gradient(10% bottom, ffffff, black) add repeat",
/* no quirks mode lengths */
"-moz-linear-gradient(10 10px -45deg, red, blue) repeat",
"-moz-linear-gradient(10px 10 -45deg, red, blue) repeat",
"-moz-linear-gradient(10 10px -45deg, red, blue) no-repeat",
"-moz-linear-gradient(10px 10 -45deg, red, blue) no-repeat",
"linear-gradient(red -99, yellow, green, blue 120%)",
/* bug 258080: don't accept background-position separated */
"left url(404.png) top", "top url(404.png) left",
@ -7113,16 +7135,16 @@ if (SupportsMaskShorthand()) {
domProp: "maskRepeat",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "repeat", "repeat repeat" ],
other_values: [ "repeat-x", "repeat-y", "no-repeat",
initial_values: [ "no-repeat", "no-repeat no-repeat" ],
other_values: [ "repeat-x", "repeat-y", "repeat",
"repeat-x, repeat-x",
"repeat, no-repeat",
"repeat-y, no-repeat, repeat-y",
"repeat, repeat, repeat",
"repeat no-repeat",
"no-repeat, repeat",
"repeat-y, repeat, repeat-y",
"no-repeat, no-repeat, no-repeat",
"no-repeat repeat",
"no-repeat no-repeat",
"repeat repeat, repeat repeat",
"repeat no-repeat",
"repeat repeat",
"no-repeat no-repeat, no-repeat no-repeat",
],
invalid_values: [ "repeat repeat repeat",
"repeat-x repeat-y",

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

@ -857,22 +857,22 @@ var filterTests = [
expected: ["blur", 10] },
// not supported interpolations
{ start: "none", end: "url('#b')",
expected: ["url", "\""+document.URL+"#b\""] },
expected: ["url", "\"#b\""] },
{ start: "url('#a')", end: "none",
expected: ["none"] },
{ start: "url('#a')", end: "url('#b')",
expected: ["url", "\""+document.URL+"#b\""] },
expected: ["url", "\"#b\""] },
{ start: "url('#a')", end: "blur(10px)",
expected: ["blur", 10] },
{ start: "blur(10px)", end: "url('#a')",
expected: ["url", "\""+document.URL+"#a\""] },
expected: ["url", "\"#a\""] },
{ start: "blur(0px) url('#a')", end: "blur(20px)",
expected: ["blur", 20] },
{ start: "blur(0px)", end: "blur(20px) url('#a')",
expected: ["blur", 20, "url", "\""+document.URL+"#a\""] },
expected: ["blur", 20, "url", "\"#a\""] },
{ start: "contrast(0.25) brightness(0.25) blur(25px)",
end: "contrast(0.75) url('#a')",
expected: ["contrast", 0.75, "url", "\""+document.URL+"#a\""] },
expected: ["contrast", 0.75, "url", "\"#a\""] },
{ start: "contrast(0.25) brightness(0.25) blur(75px)",
end: "brightness(0.75) contrast(0.75) blur(25px)",
expected: ["brightness", 0.75, "contrast", 0.75, "blur", 25] },

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

@ -23,11 +23,11 @@ nsCSSClipPathInstance::ApplyBasicShapeClip(gfxContext& aContext,
nsIFrame* aFrame)
{
auto& clipPathStyle = aFrame->StyleSVGReset()->mClipPath;
StyleClipPathType type = clipPathStyle.GetType();
MOZ_ASSERT(type != StyleClipPathType::None_, "unexpected none value");
StyleShapeSourceType type = clipPathStyle.GetType();
MOZ_ASSERT(type != StyleShapeSourceType::None_, "unexpected none value");
// In the future nsCSSClipPathInstance may handle <clipPath> references as
// well. For the time being return early.
if (type == StyleClipPathType::URL) {
if (type == StyleShapeSourceType::URL) {
return;
}
@ -44,11 +44,11 @@ nsCSSClipPathInstance::HitTestBasicShapeClip(nsIFrame* aFrame,
const gfxPoint& aPoint)
{
auto& clipPathStyle = aFrame->StyleSVGReset()->mClipPath;
StyleClipPathType type = clipPathStyle.GetType();
MOZ_ASSERT(type != StyleClipPathType::None_, "unexpected none value");
StyleShapeSourceType type = clipPathStyle.GetType();
MOZ_ASSERT(type != StyleShapeSourceType::None_, "unexpected none value");
// In the future nsCSSClipPathInstance may handle <clipPath> references as
// well. For the time being return early.
if (type == StyleClipPathType::URL) {
if (type == StyleShapeSourceType::URL) {
return false;
}
@ -67,21 +67,21 @@ nsCSSClipPathInstance::CreateClipPath(DrawTarget* aDrawTarget)
{
nsRect r;
// XXXkrit SVG needs to use different boxes.
switch (mClipPathStyle.GetSizingBox()) {
case StyleClipShapeSizing::Content:
switch (mClipPathStyle.GetReferenceBox()) {
case StyleClipPathGeometryBox::Content:
r = mTargetFrame->GetContentRectRelativeToSelf();
break;
case StyleClipShapeSizing::Padding:
case StyleClipPathGeometryBox::Padding:
r = mTargetFrame->GetPaddingRectRelativeToSelf();
break;
case StyleClipShapeSizing::Margin:
case StyleClipPathGeometryBox::Margin:
r = mTargetFrame->GetMarginRectRelativeToSelf();
break;
default: // Use the border box
r = mTargetFrame->GetRectRelativeToSelf();
}
if (mClipPathStyle.GetType() != StyleClipPathType::Shape) {
if (mClipPathStyle.GetType() != StyleShapeSourceType::Shape) {
// TODO Clip to border-radius/reference box if no shape
// was specified.
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
@ -92,15 +92,15 @@ nsCSSClipPathInstance::CreateClipPath(DrawTarget* aDrawTarget)
mTargetFrame->PresContext()->AppUnitsPerDevPixel();
r = ToAppUnits(r.ToNearestPixels(appUnitsPerDevPixel), appUnitsPerDevPixel);
nsStyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
StyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
switch (basicShape->GetShapeType()) {
case nsStyleBasicShape::Type::eCircle:
case StyleBasicShapeType::Circle:
return CreateClipPathCircle(aDrawTarget, r);
case nsStyleBasicShape::Type::eEllipse:
case StyleBasicShapeType::Ellipse:
return CreateClipPathEllipse(aDrawTarget, r);
case nsStyleBasicShape::Type::ePolygon:
case StyleBasicShapeType::Polygon:
return CreateClipPathPolygon(aDrawTarget, r);
case nsStyleBasicShape::Type::eInset:
case StyleBasicShapeType::Inset:
// XXXkrit support all basic shapes
break;
default:
@ -134,7 +134,7 @@ already_AddRefed<Path>
nsCSSClipPathInstance::CreateClipPathCircle(DrawTarget* aDrawTarget,
const nsRect& aRefBox)
{
nsStyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
StyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
@ -177,7 +177,7 @@ already_AddRefed<Path>
nsCSSClipPathInstance::CreateClipPathEllipse(DrawTarget* aDrawTarget,
const nsRect& aRefBox)
{
nsStyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
StyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
@ -217,7 +217,7 @@ already_AddRefed<Path>
nsCSSClipPathInstance::CreateClipPathPolygon(DrawTarget* aDrawTarget,
const nsRect& aRefBox)
{
nsStyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
StyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
const nsTArray<nsStyleCoord>& coords = basicShape->Coordinates();
MOZ_ASSERT(coords.Length() % 2 == 0 &&
coords.Length() >= 2, "wrong number of arguments");

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

@ -28,7 +28,7 @@ public:
const gfxPoint& aPoint);
private:
explicit nsCSSClipPathInstance(nsIFrame* aFrame,
const nsStyleClipPath aClipPathStyle)
const StyleClipPath aClipPathStyle)
: mTargetFrame(aFrame)
, mClipPathStyle(aClipPathStyle)
{
@ -49,7 +49,7 @@ private:
* The frame for the element that is currently being clipped.
*/
nsIFrame* mTargetFrame;
nsStyleClipPath mClipPathStyle;
StyleClipPath mClipPathStyle;
};
} // namespace mozilla

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

@ -579,7 +579,7 @@ nsSVGEffects::GetEffectProperties(nsIFrame* aFrame)
result.mFilter = GetOrCreateFilterProperty(aFrame);
if (style->mClipPath.GetType() == StyleClipPathType::URL) {
if (style->mClipPath.GetType() == StyleShapeSourceType::URL) {
nsCOMPtr<nsIURI> pathURI = nsSVGEffects::GetClipPathURI(aFrame);
result.mClipPath =
GetPaintingProperty(pathURI, aFrame, ClipPathProperty());
@ -929,7 +929,7 @@ already_AddRefed<nsIURI>
nsSVGEffects::GetClipPathURI(nsIFrame* aFrame)
{
const nsStyleSVGReset* svgResetStyle = aFrame->StyleSVGReset();
MOZ_ASSERT(svgResetStyle->mClipPath.GetType() == StyleClipPathType::URL);
MOZ_ASSERT(svgResetStyle->mClipPath.GetType() == StyleShapeSourceType::URL);
FragmentOrURL* url = svgResetStyle->mClipPath.GetURL();
return ResolveFragmentOrURL(aFrame, url);

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

@ -251,7 +251,7 @@ class ReftestRunner(MozbuildObject):
kwargs["printDeviceInfo"] = False
from mozrunner.devices.android_device import grant_runtime_permissions
grant_runtime_permissions(self, kwargs['app'])
grant_runtime_permissions(self)
# A symlink and some path manipulations are required so that test
# manifests can be found both locally and remotely (via a url)

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

@ -887,7 +887,9 @@ void TransportLayerDtls::Handshake() {
}
break;
default:
MOZ_MTLOG(ML_ERROR, LAYER_INFO << "SSL handshake error "<< err);
const char *err_msg = PR_ErrorToName(err);
MOZ_MTLOG(ML_ERROR, LAYER_INFO << "DTLS handshake error " << err << " ("
<< err_msg << ")");
TL_SET_STATE(TS_ERROR);
break;
}

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

@ -109,6 +109,10 @@ public class MediaControlService extends Service implements Tabs.OnTabsChangedLi
return;
}
if (!tab.isAudioPlaying()) {
return;
}
mTabReference = new WeakReference<>(tab);
notifyControlInterfaceChanged(ACTION_PAUSE);
break;

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

@ -118,6 +118,10 @@ public class TelemetryJSONFilePingStore extends TelemetryPingStore {
@Override
public void maybePrunePings() {
final File[] files = storeDir.listFiles(uuidFilenameFilter);
if (files == null) {
return;
}
if (files.length < MAX_PING_COUNT) {
return;
}

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

@ -2603,6 +2603,9 @@ pref("layout.css.scroll-behavior.damping-ratio", "1.0");
// Is support for scroll-snap enabled?
pref("layout.css.scroll-snap.enabled", true);
// Is support for CSS shape-outside enabled?
pref("layout.css.shape-outside.enabled", false);
// Is support for document.fonts enabled?
pref("layout.css.font-loading-api.enabled", true);

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

@ -204,8 +204,6 @@ class BackendMakeFile(object):
self.environment = environment
self.name = mozpath.join(objdir, 'backend.mk')
# XPIDLFiles attached to this file.
self.idls = []
self.xpt_name = None
self.fh = FileAvoidWrite(self.name, capture_diff=True)
@ -433,7 +431,6 @@ class RecursiveMakeBackend(CommonBackend):
# CommonBackend handles XPIDLFile and TestManifest, but we want to do
# some extra things for them.
if isinstance(obj, XPIDLFile):
backend_file.idls.append(obj)
backend_file.xpt_name = '%s.xpt' % obj.module
self._idl_dirs.add(obj.relobjdir)

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

@ -145,6 +145,15 @@ class ConfigureTestSandbox(ConfigureSandbox):
),
)
if what == '_winreg':
def OpenKey(*args, **kwargs):
raise WindowsError()
return ReadOnlyNamespace(
HKEY_LOCAL_MACHINE=0,
OpenKey=OpenKey,
)
return super(ConfigureTestSandbox, self)._get_one_import(what)
def create_unicode_buffer(self, *args, **kwargs):

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

@ -7,6 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals
import os
import textwrap
import unittest
import mozpack.path as mozpath
from StringIO import StringIO
@ -44,32 +45,40 @@ class TestHeaderChecks(unittest.TestCase):
expected_flags=expected_flags),
}
base_dir = os.path.join(topsrcdir, 'build', 'moz.configure')
mock_compiler_defs = textwrap.dedent('''\
@depends('--help')
def extra_toolchain_flags(_):
return []
include('%s/compilers-util.configure')
@compiler_class
@depends('--help')
def c_compiler(_):
return namespace(
flags=[],
compiler=os.path.abspath('/usr/bin/mockcc'),
wrapper=[],
language='C',
)
@compiler_class
@depends('--help')
def cxx_compiler(_):
return namespace(
flags=[],
compiler=os.path.abspath('/usr/bin/mockcc'),
wrapper=[],
language='C++',
)
@depends('--help')
def extra_toolchain_flags(_):
return []
''')
''' % mozpath.normsep(base_dir))
config = {}
out = StringIO()
sandbox = ConfigureTestSandbox(paths, config, {}, ['/bin/configure'],
out, out)
base_dir = os.path.join(topsrcdir, 'build', 'moz.configure')
sandbox.include_file(os.path.join(base_dir, 'util.configure'))
sandbox.include_file(os.path.join(base_dir, 'checks.configure'))
exec_(mock_compiler_defs, sandbox)

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

@ -311,30 +311,35 @@ class LinuxToolchainTest(BaseToolchainTest):
version='4.9.3',
type='gcc',
compiler='/usr/bin/gcc',
language='C',
)
GXX_4_9_RESULT = CompilerResult(
flags=['-std=gnu++11'],
version='4.9.3',
type='gcc',
compiler='/usr/bin/g++',
language='C++',
)
GCC_5_RESULT = CompilerResult(
flags=['-std=gnu99'],
version='5.2.1',
type='gcc',
compiler='/usr/bin/gcc-5',
language='C',
)
GXX_5_RESULT = CompilerResult(
flags=['-std=gnu++11'],
version='5.2.1',
type='gcc',
compiler='/usr/bin/g++-5',
language='C++',
)
CLANG_3_3_RESULT = CompilerResult(
flags=[],
version='3.3.0',
type='clang',
compiler='/usr/bin/clang-3.3',
language='C',
)
CLANGXX_3_3_RESULT = 'Only clang/llvm 3.6 or newer is supported.'
CLANG_3_6_RESULT = CompilerResult(
@ -342,12 +347,14 @@ class LinuxToolchainTest(BaseToolchainTest):
version='3.6.2',
type='clang',
compiler='/usr/bin/clang',
language='C',
)
CLANGXX_3_6_RESULT = CompilerResult(
flags=['-std=gnu++11'],
version='3.6.2',
type='clang',
compiler='/usr/bin/clang++',
language='C++',
)
def test_gcc(self):
@ -753,6 +760,14 @@ class WindowsToolchainTest(BaseToolchainTest):
version='19.00.23918',
type='msvc',
compiler='/usr/bin/cl',
language='C',
)
VSXX_2015u2_RESULT = CompilerResult(
flags=[],
version='19.00.23918',
type='msvc',
compiler='/usr/bin/cl',
language='C++',
)
CLANG_CL_3_9_RESULT = CompilerResult(
flags=['-Xclang', '-std=gnu99',
@ -760,12 +775,14 @@ class WindowsToolchainTest(BaseToolchainTest):
version='18.00.30723',
type='clang-cl',
compiler='/usr/bin/clang-cl',
language='C',
)
CLANGXX_CL_3_9_RESULT = CompilerResult(
flags=['-fms-compatibility-version=18.00.30723', '-fallback'],
version='18.00.30723',
type='clang-cl',
compiler='/usr/bin/clang-cl',
language='C++',
)
CLANG_3_3_RESULT = LinuxToolchainTest.CLANG_3_3_RESULT
CLANGXX_3_3_RESULT = LinuxToolchainTest.CLANGXX_3_3_RESULT
@ -781,7 +798,7 @@ class WindowsToolchainTest(BaseToolchainTest):
def test_msvc(self):
self.do_toolchain_test(self.PATHS, {
'c_compiler': self.VS_2015u2_RESULT,
'cxx_compiler': self.VS_2015u2_RESULT,
'cxx_compiler': self.VSXX_2015u2_RESULT,
})
def test_unsupported_msvc(self):

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

@ -348,7 +348,7 @@ class CompilerResult(ReadOnlyNamespace):
'''
def __init__(self, wrapper=None, compiler='', version='', type='',
flags=None):
language='', flags=None):
if flags is None:
flags = []
if wrapper is None:
@ -359,6 +359,7 @@ class CompilerResult(ReadOnlyNamespace):
type=type,
compiler=mozpath.abspath(compiler),
wrapper=wrapper,
language=language,
)
def __add__(self, other):
@ -380,6 +381,7 @@ class TestCompilerResult(unittest.TestCase):
'compiler': mozpath.abspath(''),
'version': '',
'type': '',
'language': '',
'flags': [],
})
@ -387,6 +389,7 @@ class TestCompilerResult(unittest.TestCase):
compiler='/usr/bin/gcc',
version='4.2.1',
type='gcc',
language='C',
flags=['-std=gnu99'],
)
self.assertEquals(result.__dict__, {
@ -394,6 +397,7 @@ class TestCompilerResult(unittest.TestCase):
'compiler': mozpath.abspath('/usr/bin/gcc'),
'version': '4.2.1',
'type': 'gcc',
'language': 'C',
'flags': ['-std=gnu99'],
})
@ -403,6 +407,7 @@ class TestCompilerResult(unittest.TestCase):
'compiler': mozpath.abspath('/usr/bin/gcc'),
'version': '4.2.1',
'type': 'gcc',
'language': 'C',
'flags': ['-std=gnu99', '-m32'],
})
# Original flags are untouched.
@ -418,6 +423,7 @@ class TestCompilerResult(unittest.TestCase):
'compiler': mozpath.abspath('/usr/bin/gcc-4.7'),
'version': '4.7.3',
'type': 'gcc',
'language': 'C',
'flags': ['-std=gnu99', '-m32'],
})

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

@ -293,9 +293,9 @@ tasks:
root: true
when:
file_patterns:
- 'taskcluster/**.py'
- 'taskcluster/**/*.py'
- 'config/mozunit.py'
- 'python/mach/**.py'
- 'python/mach/**/*.py'
android-api-15-gradle-dependencies:
task: tasks/builds/android_api_15_gradle_dependencies.yml
root: true

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

@ -40,6 +40,7 @@ task:
MH_CUSTOM_BUILD_VARIANT_CFG: api-15
MH_BRANCH: {{project}}
MH_BUILD_POOL: taskcluster
TOOLTOOL_CACHE: '/home/worker/tooltool-cache'
command: ["/bin/bash", "bin/build.sh"]

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

@ -40,6 +40,7 @@ task:
MH_CUSTOM_BUILD_VARIANT_CFG: api-15-debug
MH_BRANCH: {{project}}
MH_BUILD_POOL: taskcluster
TOOLTOOL_CACHE: '/home/worker/tooltool-cache'
command: ["/bin/bash", "bin/build.sh"]

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

@ -45,6 +45,7 @@ task:
MH_BRANCH: {{project}}
MH_BUILD_POOL: taskcluster
GRADLE_USER_HOME: '/home/worker/workspace/build/src/dotgradle-online'
TOOLTOOL_CACHE: '/home/worker/tooltool-cache'
maxRunTime: 36000

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

@ -40,6 +40,7 @@ task:
MH_CUSTOM_BUILD_VARIANT_CFG: api-15-partner-sample1
MH_BRANCH: {{project}}
MH_BUILD_POOL: taskcluster
TOOLTOOL_CACHE: '/home/worker/tooltool-cache'
# space separated list of repositories required for this build
# for each ITEM in list you want checked out, you must also supply tc-vcs args:
@ -61,6 +62,7 @@ task:
- production
- staging
treeherder:
tier: 2
machine:
# see https://github.com/mozilla/treeherder/blob/master/ui/js/values.js
platform: android-4-0-armv7-api15-partner1

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

@ -40,6 +40,7 @@ task:
MH_CUSTOM_BUILD_VARIANT_CFG: x86
MH_BRANCH: {{project}}
MH_BUILD_POOL: taskcluster
TOOLTOOL_CACHE: /home/worker/tooltool-cache
command: ["/bin/bash", "bin/build.sh"]

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

@ -12,12 +12,12 @@ task:
scopes:
- 'docker-worker:cache:tooltool-cache'
- 'docker-worker:relengapi-proxy:tooltool.download.public'
- 'docker-worker:cache:level-{{level}}-{{project}}-build-linux32-workspace'
- 'docker-worker:cache:level-{{level}}-{{project}}-build-linux32-{{build_type}}-workspace'
payload:
cache:
tooltool-cache: '/home/worker/tooltool-cache'
level-{{level}}-{{project}}-build-linux32-workspace: '/home/worker/workspace'
level-{{level}}-{{project}}-build-linux32-{{build_type}}-workspace: '/home/worker/workspace'
features:
relengAPIProxy: true

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

@ -8,12 +8,12 @@ task:
scopes:
- 'docker-worker:cache:tooltool-cache'
- 'docker-worker:relengapi-proxy:tooltool.download.public'
- 'docker-worker:cache:level-{{level}}-{{project}}-build-{{build_name}}-workspace'
- 'docker-worker:cache:level-{{level}}-{{project}}-build-linux64-{{build_type}}-workspace'
payload:
cache:
tooltool-cache: '/home/worker/tooltool-cache'
level-{{level}}-{{project}}-build-{{build_name}}-workspace: '/home/worker/workspace'
level-{{level}}-{{project}}-build-linux64-{{build_type}}-workspace: '/home/worker/workspace'
features:
relengAPIProxy: true

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

@ -11,7 +11,7 @@ task:
routes:
- 'coalesce.v1.builds.{{project}}.dbg_linux32'
workerType: dbg-linux32
workerType: 'gecko-{{level}}-b-linux'
payload:
supersederUrl: 'https://coalesce.mozilla-releng.net/v1/list/builds.{{project}}.dbg_linux32'

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

@ -12,7 +12,7 @@ task:
- 'index.buildbot.branches.{{project}}.linux64-asan'
- 'index.buildbot.revisions.{{head_rev}}.{{project}}.linux64-asan'
workerType: dbg-linux64
workerType: 'gecko-{{level}}-b-linux'
payload:
env:
@ -26,5 +26,6 @@ task:
machine:
# see https://github.com/mozilla/treeherder/blob/master/ui/js/values.js
platform: linux64
tier: 1
collection:
asan: true

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

@ -12,7 +12,7 @@ task:
- 'index.buildbot.branches.{{project}}.linux64-debug'
- 'index.buildbot.revisions.{{head_rev}}.{{project}}.linux64-debug'
workerType: dbg-linux64
workerType: 'gecko-{{level}}-b-linux'
payload:
env:
@ -23,6 +23,7 @@ task:
groupSymbol: tc
groupName: Submitted by taskcluster
symbol: B
tier: 1
collection:
debug: true

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

@ -8,7 +8,7 @@ task:
name: '[TC] Linux32 L10n'
description: 'Linux32 L10n'
workerType: opt-linux32
workerType: 'gecko-{{level}}-b-linux'
extra:
treeherder:

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

@ -8,7 +8,7 @@ task:
name: '[TC] Linux64 L10n'
description: 'Linux64 L10n'
workerType: opt-linux64
workerType: 'gecko-{{level}}-b-linux'
extra:
treeherder:

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

@ -8,7 +8,7 @@ task:
name: '[TC] Browser Hazard Linux'
description: Browser Hazard Analysis Linux
workerType: dbg-linux64
workerType: 'gecko-{{level}}-b-linux'
scopes:
- 'docker-worker:cache:tooltool-cache'
@ -18,14 +18,14 @@ task:
payload:
cache:
level-{{level}}-{{project}}-build-linux64-haz-workspace: '/home/worker/workspace'
tooltool-cache: '/home/worker/tools/tooltool-cache'
tooltool-cache: '/home/worker/tooltool-cache'
features:
relengAPIProxy: true
env:
MOZCONFIG: 'browser/config/mozconfigs/linux64/hazards'
TOOLTOOL_CACHE: '/home/worker/tools/tooltool-cache'
TOOLTOOL_CACHE: '/home/worker/tooltool-cache'
TOOLTOOL_MANIFEST: 'browser/config/tooltool-manifests/linux64/hazard.manifest'
maxRunTime: 36000
@ -49,6 +49,7 @@ task:
groupSymbol: tc
groupName: Submitted by taskcluster for your pleasure
symbol: H
tier: 1
collection:
debug: true
# Rather then enforcing particular conventions we require that all build

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

@ -8,7 +8,7 @@ task:
name: '[TC] JS Shell Hazard Linux'
description: JS Shell Hazard Analysis Linux
workerType: dbg-linux64
workerType: 'gecko-{{level}}-b-linux'
scopes:
- 'docker-worker:cache:tooltool-cache'
@ -18,13 +18,13 @@ task:
payload:
cache:
level-{{level}}-{{project}}-build-linux64-haz-workspace: '/home/worker/workspace'
tooltool-cache: '/home/worker/tools/tooltool-cache'
tooltool-cache: '/home/worker/tooltool-cache'
features:
relengAPIProxy: true
env:
TOOLTOOL_CACHE: '/home/worker/tools/tooltool-cache'
TOOLTOOL_CACHE: '/home/worker/tooltool-cache'
TOOLTOOL_MANIFEST: 'browser/config/tooltool-manifests/linux64/hazard.manifest'
maxRunTime: 36000
@ -48,6 +48,7 @@ task:
groupSymbol: SM-tc
groupName: SpiderMonkey, submitted by taskcluster
symbol: H
tier: 1
collection:
debug: true
# Rather then enforcing particular conventions we require that all build

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

@ -8,7 +8,7 @@ task:
name: '[TC] Clang'
description: 'Clang'
workerType: opt-linux64
workerType: 'gecko-{{level}}-b-linux'
routes:
- 'index.buildbot.branches.{{project}}.clang'

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

@ -8,7 +8,7 @@ task:
name: '[TC] GCC'
description: 'GCC'
workerType: opt-linux64
workerType: 'gecko-{{level}}-b-linux'
routes:
- 'index.buildbot.branches.{{project}}.gcc'

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

@ -22,7 +22,7 @@ task:
payload:
cache:
level-{{level}}-{{project}}-build-mulet-haz-linux-workspace: '/home/worker/workspace'
tooltool-cache: '/home/worker/tools/tooltool-cache'
tooltool-cache: '/home/worker/tooltool-cache'
features:
relengAPIProxy: true
@ -30,6 +30,7 @@ task:
env:
MOZCONFIG: 'b2g/dev/config/mozconfigs/linux64/mulet-hazards'
TOOLTOOL_MANIFEST: 'gecko/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest'
TOOLTOOL_CACHE: '/home/worker/tooltool-cache'
maxRunTime: 36000

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