Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Cosmin Sabou 2018-08-27 18:51:27 +03:00
Родитель ef67442423 57b9c2ac11
Коммит 5d011e88d1
63 изменённых файлов: 836 добавлений и 359 удалений

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

@ -159,6 +159,7 @@ skip-if = !e10s || !crashreporter # the tab's process is killed during the test.
[browser_ext_sessions_window_tab_value.js]
[browser_ext_settings_overrides_default_search.js]
[browser_ext_sidebarAction.js]
skip-if = debug #Bug 1483325
[browser_ext_sidebarAction_browser_style.js]
[browser_ext_sidebarAction_context.js]
[browser_ext_sidebarAction_contextMenu.js]

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

@ -974,6 +974,7 @@ autoplay.Allow2.accesskey = A
autoplay.DontAllow.label = Dont Allow
autoplay.DontAllow.accesskey = n
autoplay.remember = Remember this decision
autoplay.remember-private = Remember for this session
# LOCALIZATION NOTE (autoplay.message): %S is the name of the site URL (https://...) trying to autoplay media
autoplay.message = Will you allow %S to autoplay media with sound?
autoplay.messageWithFile = Will you allow this file to autoplay media with sound?

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

@ -800,13 +800,12 @@ AutoplayPermissionPrompt.prototype = {
get popupOptions() {
let learnMoreURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") + "block-autoplay";
let checkbox = {
show: !PrivateBrowsingUtils.isWindowPrivate(this.browser.ownerGlobal) &&
!this.principal.URI.schemeIs("file")
};
let checkbox = {show: !this.principal.URI.schemeIs("file")};
if (checkbox.show) {
checkbox.checked = true;
checkbox.label = gBrowserBundle.GetStringFromName("autoplay.remember");
checkbox.label = PrivateBrowsingUtils.isWindowPrivate(this.browser.ownerGlobal) ?
gBrowserBundle.GetStringFromName("autoplay.remember-private") :
gBrowserBundle.GetStringFromName("autoplay.remember");
}
return {
checkbox,

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

@ -6,8 +6,6 @@
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
const { PureComponent } = require("devtools/client/shared/vendor/react");
/**
@ -19,55 +17,21 @@ class IndicationBar extends PureComponent {
return {
className: PropTypes.string.isRequired,
position: PropTypes.number.isRequired,
sidebarWidth: PropTypes.number.isRequired,
};
}
constructor(props) {
super(props);
this.state = {
// offset of the position for this bar
offset: 0,
};
}
componentDidMount() {
this.updateState(this.props);
}
componentWillReceiveProps(nextProps) {
this.updateState(nextProps);
}
updateState(props) {
const { position } = props;
const parentEl = findDOMNode(this).parentNode;
const offset = parentEl.offsetWidth * position;
this.setState({ offset });
}
render() {
const { className } = this.props;
const { offset } = this.state;
const { className, position } = this.props;
return dom.div(
{
className: `indication-bar ${ className }`,
style: {
marginInlineStart: offset + "px",
marginInlineStart: `${ position * 100 }%`,
},
}
);
}
}
const mapStateToProps = state => {
return {
sidebarWidth: state.animations.sidebarSize ? state.animations.sidebarSize.width : 0
};
};
module.exports = connect(mapStateToProps)(IndicationBar);
module.exports = IndicationBar;

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

@ -59,7 +59,7 @@ async function testCurrentTimeScrubber(isRTL) {
info("Checking draggable on scrubber over animation list");
await clickOnPauseResumeButton(animationInspector, panel);
previousX = scrubberEl.getBoundingClientRect().x;
await dragOnCurrentTimeScrubber(animationInspector, panel, 0.5, 2, 30);
await dragOnCurrentTimeScrubber(animationInspector, panel, 5, 30);
currentX = scrubberEl.getBoundingClientRect().x;
isnot(previousX, currentX, "Scrubber should be draggable");

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

@ -291,34 +291,23 @@ const clickOnTargetNode = async function(animationInspector, panel, index) {
*
* @param {DOMElement} panel
* #animation-container element.
* @param {Number} mouseDownPosition
* rate on scrubber controller pane.
* This method calculates
* `mouseDownPosition * offsetWidth + offsetLeft of scrubber controller pane`
* as the clientX of MouseEvent.
* @param {Number} mouseMovePosition
* @param {Number} mouseMovePixel
* Dispatch mousemove event with mouseMovePosition after mousedown.
* Calculation for clinetX is same to above.
* @param {Number} mouseYPixel
* Y of mouse in pixel.
*/
const dragOnCurrentTimeScrubber = async function(animationInspector,
panel,
mouseDownPosition,
mouseMovePosition,
mouseMovePixel,
mouseYPixel) {
const controllerEl = panel.querySelector(".current-time-scrubber");
const bounds = controllerEl.getBoundingClientRect();
const mousedonwX = bounds.width * mouseDownPosition;
const mousemoveX = bounds.width * mouseMovePosition;
info(`Drag on scrubber from ${ mousedonwX } to ${ mousemoveX }`);
EventUtils.synthesizeMouse(controllerEl, mousedonwX, mouseYPixel,
info(`Drag scrubber to X ${ mouseMovePixel }`);
EventUtils.synthesizeMouse(controllerEl, 0, mouseYPixel,
{ type: "mousedown" }, controllerEl.ownerGlobal);
await waitForSummaryAndDetail(animationInspector);
EventUtils.synthesizeMouse(controllerEl, mousemoveX, mouseYPixel,
EventUtils.synthesizeMouse(controllerEl, mouseMovePixel, mouseYPixel,
{ type: "mousemove" }, controllerEl.ownerGlobal);
EventUtils.synthesizeMouse(controllerEl, mousemoveX, mouseYPixel,
EventUtils.synthesizeMouse(controllerEl, mouseMovePixel, mouseYPixel,
{ type: "mouseup" }, controllerEl.ownerGlobal);
await waitForSummaryAndDetail(animationInspector);
};

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

@ -619,14 +619,17 @@ Inspector.prototype = {
if (window.closed) {
return;
}
// Use window.top because promiseDocumentFlushed() in a subframe doesn't
// work, see https://bugzilla.mozilla.org/show_bug.cgi?id=1441173
const useLandscapeMode = await window.top.promiseDocumentFlushed(() => {
return this.useLandscapeMode();
});
if (window.closed) {
return;
}
this.splitBox.setState({ vert: useLandscapeMode });
this.emit("inspector-resize");
},
@ -636,6 +639,10 @@ Inspector.prototype = {
* to `horizontal` to support portrait view.
*/
onPanelWindowResize: function() {
if (this.toolbox.currentToolId !== "inspector") {
return;
}
if (!this._lazyResizeHandler) {
this._lazyResizeHandler = new DeferredTask(this._onLazyPanelResize.bind(this),
LAZY_RESIZE_INTERVAL_MS, 0);

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

@ -5,7 +5,7 @@ code, and optionally help with indentation.
# Upgrade
Currently used version is 5.39.0. To upgrade: download a new version of
Currently used version is 5.40.0. To upgrade: download a new version of
CodeMirror from the project's page [1] and replace all JavaScript and
CSS files inside the codemirror directory [2].

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Open simple dialogs on top of an editor. Relies on dialog.css.

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@ -136,9 +136,7 @@
var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
else return CodeMirror.Pass;
} else if (opening && (cm.getLine(cur.line).length == cur.ch ||
isClosingBracket(next, pairs) ||
/\s/.test(next))) {
} else if (opening) {
curType = "both";
} else {
return CodeMirror.Pass;
@ -175,11 +173,6 @@
});
}
function isClosingBracket(ch, pairs) {
var pos = pairs.lastIndexOf(ch);
return pos > -1 && pos % 2 == 1;
}
function charsAround(cm, pos) {
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
Pos(pos.line, pos.ch + 1));

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Tag-closer extension for CodeMirror.

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@ -98,7 +98,7 @@
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
(pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close();
} else {
var self = this;
@ -200,7 +200,8 @@
var widget = this, cm = completion.cm;
var hints = this.hints = document.createElement("ul");
hints.className = "CodeMirror-hints";
var theme = completion.cm.options.theme;
hints.className = "CodeMirror-hints " + theme;
this.selectedHint = data.selectedHint || 0;
var completions = data.list;

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Highlighting text that matches the selection
//

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Because sometimes you need to mark the selected *text*.
//

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Glue code between CodeMirror and Tern.
//

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
// A rough approximation of Sublime Text's keybindings
// Depends on addon/search/searchcursor.js and optionally addon/dialog/dialogs.js

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Supported keybindings:

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

@ -1,7 +1,7 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
// This is CodeMirror (http://codemirror.net), a code editor
// This is CodeMirror (https://codemirror.net), a code editor
// implemented in JavaScript on top of the browser's DOM.
//
// You can find some technical background for some of the code below
@ -5694,7 +5694,7 @@ LineWidget.prototype.changed = function () {
this.height = null
var diff = widgetHeight(this) - oldH
if (!diff) { return }
updateLineHeight(line, line.height + diff)
if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff) }
if (cm) {
runInOp(cm, function () {
cm.curOp.forceUpdate = true
@ -6622,7 +6622,7 @@ keyMap.pcDefault = {
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
"Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
fallthrough: "basic"
"fallthrough": "basic"
}
// Very basic readline/emacs-style bindings, which are standard on Mac.
keyMap.emacsy = {
@ -6640,7 +6640,7 @@ keyMap.macDefault = {
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
"Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
"Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
fallthrough: ["basic", "emacsy"]
"fallthrough": ["basic", "emacsy"]
}
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault
@ -7722,6 +7722,7 @@ function defineOptions(CodeMirror) {
option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; })
option("autofocus", null)
option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true)
option("phrases", null)
}
function guttersChanged(cm) {
@ -7773,6 +7774,7 @@ function CodeMirror(place, options) {
var doc = options.value
if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction) }
else if (options.mode) { doc.modeOption = options.mode }
this.doc = doc
var input = new CodeMirror.inputStyles[options.inputStyle](this)
@ -8559,6 +8561,11 @@ function addEditorMethods(CodeMirror) {
return old
}),
phrase: function(phraseText) {
var phrases = this.options.phrases
return phrases && Object.prototype.hasOwnProperty.call(phrases, phraseText) ? phrases[phraseText] : phraseText
},
getInputField: function(){return this.display.input.getField()},
getWrapperElement: function(){return this.display.wrapper},
getScrollerElement: function(){return this.display.scroller},
@ -9676,7 +9683,7 @@ CodeMirror.fromTextArea = fromTextArea
addLegacyProps(CodeMirror)
CodeMirror.version = "5.39.0"
CodeMirror.version = "5.40.0"
return CodeMirror;

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@ -216,15 +216,15 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
var closing = firstChar == ctx.type;
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
if (parserConfig.dontIndentStatements)
while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
ctx = ctx.prev
if (hooks.indent) {
var hook = hooks.indent(state, ctx, textAfter);
var hook = hooks.indent(state, ctx, textAfter, indentUnit);
if (typeof hook == "number") return hook
}
var closing = firstChar == ctx.type;
var switchBlock = ctx.prev && ctx.prev.info == "switch";
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
@ -631,6 +631,17 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
'"': function(stream, state) {
state.tokenize = tokenKotlinString(stream.match('""'));
return state.tokenize(stream, state);
},
indent: function(state, ctx, textAfter, indentUnit) {
var firstChar = textAfter && textAfter.charAt(0);
if ((state.prevToken == "}" || state.prevToken == ")") && textAfter == "")
return state.indented;
if (state.prevToken == "operator" && textAfter != "}" ||
state.prevToken == "variable" && firstChar == "." ||
(state.prevToken == "}" || state.prevToken == ")") && firstChar == ".")
return indentUnit * 2 + ctx.indented;
if (ctx.align && ctx.type == "}")
return ctx.indented + (state.context.type == (textAfter || "").charAt(0) ? 0 : indentUnit);
}
},
modeProps: {closeBrackets: {triples: '"'}}

304
devtools/client/sourceeditor/codemirror/mode/clojure/clojure.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,304 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Author: Hans Engel
* Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
*/
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("clojure", function (options) {
var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2",
ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword", VAR = "variable";
var INDENT_WORD_SKIP = options.indentUnit || 2;
var NORMAL_INDENT_UNIT = options.indentUnit || 2;
function makeKeywords(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
var atoms = makeKeywords("true false nil");
var keywords = makeKeywords(
"defn defn- def def- defonce defmulti defmethod defmacro defstruct deftype defprotocol defrecord defproject deftest " +
"slice defalias defhinted defmacro- defn-memo defnk defnk defonce- defunbound defunbound- defvar defvar- let letfn " +
"do case cond condp for loop recur when when-not when-let when-first if if-let if-not . .. -> ->> doto and or dosync " +
"doseq dotimes dorun doall load import unimport ns in-ns refer try catch finally throw with-open with-local-vars " +
"binding gen-class gen-and-load-class gen-and-save-class handler-case handle");
var builtins = makeKeywords(
"* *' *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* " +
"*compile-path* *compiler-options* *data-readers* *default-data-reader-fn* *e *err* *file* *flush-on-newline* *fn-loader* *in* " +
"*math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-namespace-maps* *print-readably* *read-eval* *reader-resolver* " +
"*source-path* *suppress-read* *unchecked-math* *use-context-classloader* *verbose-defrecords* *warn-on-reflection* + +' - -' -> " +
"->> ->ArrayChunk ->Eduction ->Vec ->VecNode ->VecSeq -cache-protocol-fn -reset-methods .. / < <= = == > >= EMPTY-NODE Inst StackTraceElement->vec Throwable->map accessor " +
"aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! " +
"alter-var-root amap ancestors and any? apply areduce array-map as-> aset aset-boolean aset-byte aset-char aset-double " +
"aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 " +
"bases bean bigdec bigint biginteger binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set " +
"bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array boolean? booleans bound-fn bound-fn* bound? bounded-count butlast " +
"byte byte-array bytes bytes? case cast cat char char-array char-escape-string char-name-string char? chars chunk chunk-append " +
"chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors " +
"clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement completing concat cond cond-> cond->> condp " +
"conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec dec' decimal? " +
"declare dedupe default-data-readers definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol " +
"defrecord defstruct deftype delay delay? deliver denominator deref derive descendants destructure disj disj! dissoc " +
"dissoc! distinct distinct? doall dorun doseq dosync dotimes doto double double-array double? doubles drop drop-last " +
"drop-while eduction empty empty? ensure ensure-reduced enumeration-seq error-handler error-mode eval even? every-pred every? ex-data ex-info " +
"extend extend-protocol extend-type extenders extends? false? ffirst file-seq filter filterv find find-keyword " +
"find-ns find-protocol-impl find-protocol-method find-var first flatten float float-array float? floats flush fn fn? " +
"fnext fnil for force format frequencies future future-call future-cancel future-cancelled? future-done? future? " +
"gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator group-by halt-when hash " +
"hash-combine hash-map hash-ordered-coll hash-set hash-unordered-coll ident? identical? identity if-let if-not if-some ifn? import in-ns inc inc' indexed? init-proxy inst-ms inst-ms* inst? instance? " +
"int int-array int? integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt keep " +
"keep-indexed key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file " +
"load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array " +
"make-hierarchy map map-entry? map-indexed map? mapcat mapv max max-key memfn memoize merge merge-with meta method-sig methods " +
"min min-key mix-collection-hash mod munge name namespace namespace-munge nat-int? neg-int? neg? newline next nfirst nil? nnext not not-any? not-empty " +
"not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias " +
"ns-unmap nth nthnext nthrest num number? numerator object-array odd? or parents partial partition partition-all " +
"partition-by pcalls peek persistent! pmap pop pop! pop-thread-bindings pos-int? pos? pr pr-str prefer-method prefers " +
"primitives-classnames print print-ctor print-dup print-method print-simple print-str printf println println-str " +
"prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues qualified-ident? qualified-keyword? qualified-symbol? " +
"quot rand rand-int rand-nth random-sample range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern " +
"re-seq read read-line read-string reader-conditional reader-conditional? realized? record? reduce reduce-kv reduced reduced? reductions ref ref-history-count ref-max-history " +
"ref-min-history ref-set refer refer-clojure reify release-pending-sends rem remove remove-all-methods " +
"remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! reset-vals! resolve rest " +
"restart-agent resultset-seq reverse reversible? rseq rsubseq run! satisfies? second select-keys send send-off send-via seq seq? seqable? " +
"seque sequence sequential? set set-agent-send-executor! set-agent-send-off-executor! set-error-handler! set-error-mode! set-validator! set? short short-array shorts " +
"shuffle shutdown-agents simple-ident? simple-keyword? simple-symbol? slurp some some-> some->> some-fn some? sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? " +
"special-symbol? spit split-at split-with str string? struct struct-map subs subseq subvec supers swap! swap-vals! symbol " +
"symbol? sync tagged-literal tagged-literal? take take-last take-nth take-while test the-ns thread-bound? time to-array to-array-2d trampoline transduce " +
"transient tree-seq true? type unchecked-add unchecked-add-int unchecked-byte unchecked-char unchecked-dec " +
"unchecked-dec-int unchecked-divide-int unchecked-double unchecked-float unchecked-inc unchecked-inc-int " +
"unchecked-int unchecked-long unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int " +
"unchecked-remainder-int unchecked-short unchecked-subtract unchecked-subtract-int underive unquote " +
"unquote-splicing unreduced unsigned-bit-shift-right update update-in update-proxy uri? use uuid? val vals var-get var-set var? vary-meta vec vector vector-of " +
"vector? volatile! volatile? vreset! vswap! when when-first when-let when-not when-some while with-bindings with-bindings* with-in-str with-loading-context " +
"with-local-vars with-meta with-open with-out-str with-precision with-redefs with-redefs-fn xml-seq zero? zipmap");
var indentKeys = makeKeywords(
// Built-ins
"ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto " +
"locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type " +
"try catch " +
// Binding forms
"let letfn binding loop for doseq dotimes when-let if-let " +
// Data structures
"defstruct struct-map assoc " +
// clojure.test
"testing deftest " +
// contrib
"handler-case handle dotrace deftrace");
var tests = {
digit: /\d/,
digit_or_colon: /[\d:]/,
hex: /[0-9a-f]/i,
sign: /[+-]/,
exponent: /e/i,
keyword_char: /[^\s\(\[\;\)\]]/,
symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/,
block_indent: /^(?:def|with)[^\/]+$|\/(?:def|with)/
};
function stateStack(indent, type, prev) { // represents a state stack object
this.indent = indent;
this.type = type;
this.prev = prev;
}
function pushStack(state, indent, type) {
state.indentStack = new stateStack(indent, type, state.indentStack);
}
function popStack(state) {
state.indentStack = state.indentStack.prev;
}
function isNumber(ch, stream){
// hex
if ( ch === '0' && stream.eat(/x/i) ) {
stream.eatWhile(tests.hex);
return true;
}
// leading sign
if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
stream.eat(tests.sign);
ch = stream.next();
}
if ( tests.digit.test(ch) ) {
stream.eat(ch);
stream.eatWhile(tests.digit);
if ( '.' == stream.peek() ) {
stream.eat('.');
stream.eatWhile(tests.digit);
} else if ('/' == stream.peek() ) {
stream.eat('/');
stream.eatWhile(tests.digit);
}
if ( stream.eat(tests.exponent) ) {
stream.eat(tests.sign);
stream.eatWhile(tests.digit);
}
return true;
}
return false;
}
// Eat character that starts after backslash \
function eatCharacter(stream) {
var first = stream.next();
// Read special literals: backspace, newline, space, return.
// Just read all lowercase letters.
if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {
return;
}
// Read unicode character: \u1000 \uA0a1
if (first === "u") {
stream.match(/[0-9a-z]{4}/i, true);
}
}
return {
startState: function () {
return {
indentStack: null,
indentation: 0,
mode: false
};
},
token: function (stream, state) {
if (state.indentStack == null && stream.sol()) {
// update indentation, but only if indentStack is empty
state.indentation = stream.indentation();
}
// skip spaces
if (state.mode != "string" && stream.eatSpace()) {
return null;
}
var returnType = null;
switch(state.mode){
case "string": // multi-line string parsing mode
var next, escaped = false;
while ((next = stream.next()) != null) {
if (next == "\"" && !escaped) {
state.mode = false;
break;
}
escaped = !escaped && next == "\\";
}
returnType = STRING; // continue on in string mode
break;
default: // default parsing mode
var ch = stream.next();
if (ch == "\"") {
state.mode = "string";
returnType = STRING;
} else if (ch == "\\") {
eatCharacter(stream);
returnType = CHARACTER;
} else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
returnType = ATOM;
} else if (ch == ";") { // comment
stream.skipToEnd(); // rest of the line is a comment
returnType = COMMENT;
} else if (isNumber(ch,stream)){
returnType = NUMBER;
} else if (ch == "(" || ch == "[" || ch == "{" ) {
var keyWord = '', indentTemp = stream.column(), letter;
/**
Either
(indent-word ..
(non-indent-word ..
(;something else, bracket, etc.
*/
if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) {
keyWord += letter;
}
if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
tests.block_indent.test(keyWord))) { // indent-word
pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
} else { // non-indent word
// we continue eating the spaces
stream.eatSpace();
if (stream.eol() || stream.peek() == ";") {
// nothing significant after
// we restart indentation the user defined spaces after
pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);
} else {
pushStack(state, indentTemp + stream.current().length, ch); // else we match
}
}
stream.backUp(stream.current().length - 1); // undo all the eating
returnType = BRACKET;
} else if (ch == ")" || ch == "]" || ch == "}") {
returnType = BRACKET;
if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) {
popStack(state);
}
} else if ( ch == ":" ) {
stream.eatWhile(tests.symbol);
return ATOM;
} else {
stream.eatWhile(tests.symbol);
if (keywords && keywords.propertyIsEnumerable(stream.current())) {
returnType = KEYWORD;
} else if (builtins && builtins.propertyIsEnumerable(stream.current())) {
returnType = BUILTIN;
} else if (atoms && atoms.propertyIsEnumerable(stream.current())) {
returnType = ATOM;
} else {
returnType = VAR;
}
}
}
return returnType;
},
indent: function (state) {
if (state.indentStack == null) return state.indentation;
return state.indentStack.indent;
},
closeBrackets: {pairs: "()[]{}\"\""},
lineComment: ";;"
};
});
CodeMirror.defineMIME("text/x-clojure", "clojure");
CodeMirror.defineMIME("text/x-clojurescript", "clojure");
CodeMirror.defineMIME("application/edn", "clojure");
});

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Link to the project's GitHub page:

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS

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

@ -82,6 +82,7 @@ const CM_MAPPING = [
const editors = new WeakMap();
Editor.modes = {
cljs: { name: "text/x-clojure" },
css: { name: "css" },
fs: { name: "x-shader/x-fragment" },
haxe: { name: "haxe" },

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

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");

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

@ -1658,6 +1658,56 @@ testCM("lineWidgetChanged", function(cm) {
eq(info0.top + expectedWidgetHeight, info2.top);
});
testCM("lineWidgetIssue5486", function(cm) {
// [prepare]
// 2nd line is combined to 1st line due to markText
// 2nd line has a lineWidget below
cm.setValue("Lorem\nIpsue\nDollar")
var el = document.createElement('div')
el.style.height='50px'
el.textContent = '[[LINE WIDGET]]'
var lineWidget = cm.addLineWidget(1, el, {
above: false,
coverGutter: false,
noHScroll: false,
showIfHidden: false,
})
var marker = document.createElement('span')
marker.textContent = '[--]'
cm.markText({line:0, ch: 1}, {line:1, ch: 4}, {
replacedWith: marker
})
// before resizing the lineWidget, measure 3rd line position
var measure_1 = Math.round(cm.charCoords({line:2, ch:0}).top)
// resize lineWidget, height + 50 px
el.style.height='100px'
el.textContent += "\nlineWidget size changed.\nTry moving cursor to line 3?"
lineWidget.changed()
// re-measure 3rd line position
var measure_2 = Math.round(cm.charCoords({line:2, ch:0}).top)
eq(measure_2, measure_1 + 50)
// (extra test)
//
// add char to the right of the folded marker
// and re-measure 3rd line position
cm.replaceRange('-', {line:1, ch: 5})
var measure_3 = Math.round(cm.charCoords({line:2, ch:0}).top)
eq(measure_3, measure_2)
});
testCM("getLineNumber", function(cm) {
addDoc(cm, 2, 20);
var h1 = cm.getLineHandle(1);

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

@ -104,11 +104,11 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch
/* Current Time Scrubber */
.current-time-scrubber-area {
grid-column: 2 / 3;
position: relative;
z-index: 2;
}
.current-time-scrubber-area:dir(ltr)::before,
.current-time-scrubber-area:dir(rtl)::after {
.current-time-scrubber-area::before {
content: "";
cursor: col-resize;
height: var(--devtools-toolbar-height);
@ -118,7 +118,7 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch
width: calc(100% + 1px);
}
.current-time-scrubber-area:dir(rtl)::after {
.current-time-scrubber-area:dir(rtl)::before {
/* In order to click on the start edge of current-time-scrubber-area element on RTL */
margin-inline-start: -1px;
}
@ -126,22 +126,22 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch
.indication-bar.current-time-scrubber {
cursor: col-resize;
pointer-events: auto;
width: 12px;
transform: translateX(-6px);
}
.indication-bar.current-time-scrubber:dir(rtl) {
.indication-bar.current-time-scrubber:dir(rtl)::before {
transform: translateX(6px);
}
.indication-bar.current-time-scrubber:dir(rtl)::after {
transform: translateX(1px);
}
.indication-bar.current-time-scrubber::before {
border-top-color: var(--scrubber-color);
left: 0;
}
.indication-bar.current-time-scrubber::after {
border-inline-start-color: var(--scrubber-color);
left: 5px;
background-color: var(--scrubber-color);
}
/* Animation Item */
@ -427,6 +427,7 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch
background: none;
grid-column: 2 / 3;
pointer-events: none;
position: relative;
z-index: 2;
}
@ -435,7 +436,7 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch
}
.indication-bar.keyframes-progress-bar::after {
border-inline-start-color: var(--progress-bar-color);
background-color: var(--progress-bar-color);
}
/* Animated Property Item */
@ -664,7 +665,6 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch
/* Indication Bar */
.indication-bar {
height: 100%;
position: absolute;
}
@ -673,19 +673,18 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch
border-inline-end: 5px solid transparent;
border-top: 5px solid;
content: "";
left: -5px;
position: absolute;
top: 0;
width: 0;
height: 100vh;
position: fixed;
transform: translateX(-6px);
width: 1px;
}
.indication-bar::after {
border-inline-start: 1px solid;
content: "";
height: 100%;
position: absolute;
top: 0;
width: 0;
height: 100vh;
position: fixed;
transform: translateX(-1px);
width: 1px;
}
/* No Animation Panel */

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

@ -6,6 +6,7 @@
#include <MediaStreamGraphImpl.h>
#include "mozilla/dom/AudioContext.h"
#include "mozilla/dom/AudioDeviceInfo.h"
#include "mozilla/SharedThreadPool.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Unused.h"

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

@ -22,7 +22,6 @@ support-files =
[test_basics.js]
[test_bad_origin_directory.js]
skip-if = release_or_beta
[test_defaultStorageUpgrade.js]
[test_getUsage.js]
[test_idbSubdirUpgrade.js]

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

@ -456,7 +456,7 @@ def write_mozbuild(sources):
write_sources(f, sources['linux'], 4)
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':\n")
f.write(" if CONFIG['CC_TYPE'] not in ('gcc', 'clang'):\n")
f.write(" if CONFIG['CC_TYPE'] not in ('gcc', 'clang') and CONFIG['CPU_ARCH'] != 'aarch64':\n")
write_list(f, "SOURCES", sources['no-mingw'], 8)
# Windows-specific files don't get unification because of nasty headers.
# Luckily there are not many files in this.

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

@ -626,7 +626,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
'skia/src/ports/SkFontHost_FreeType_common.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
if CONFIG['CC_TYPE'] not in ('gcc', 'clang'):
if CONFIG['CC_TYPE'] not in ('gcc', 'clang') and CONFIG['CPU_ARCH'] != 'aarch64':
SOURCES += [
'skia/src/jumper/SkJumper_generated_win.S',
]

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

@ -10,7 +10,7 @@ use ellipse::Ellipse;
use display_list_flattener::DisplayListFlattener;
use gpu_types::{BorderInstance, BorderSegment, BrushFlags};
use prim_store::{BrushKind, BrushPrimitive, BrushSegment};
use prim_store::{BorderSource, EdgeAaSegmentMask, PrimitiveContainer, ScrollNodeAndClipChain};
use prim_store::{EdgeAaSegmentMask, PrimitiveContainer, ScrollNodeAndClipChain};
use util::{lerp, RectHelpers};
// Using 2048 as the maximum radius in device space before which we
@ -116,6 +116,20 @@ pub struct BorderCacheKey {
pub scale: Au,
}
impl BorderCacheKey {
pub fn new(border: &NormalBorder, widths: &BorderWidths) -> Self {
BorderCacheKey {
left: border.left.into(),
top: border.top.into(),
right: border.right.into(),
bottom: border.bottom.into(),
widths: (*widths).into(),
radius: border.radius.into(),
scale: Au::from_f32_px(0.0),
}
}
}
pub fn ensure_no_corner_overlap(
radius: &mut BorderRadius,
rect: &LayoutRect,
@ -173,23 +187,7 @@ impl<'a> DisplayListFlattener<'a> {
ensure_no_corner_overlap(&mut border.radius, &info.rect);
let prim = BrushPrimitive::new(
BrushKind::Border {
source: BorderSource::Border {
border,
widths: *widths,
cache_key: BorderCacheKey {
left: border.left.into(),
top: border.top.into(),
right: border.right.into(),
bottom: border.bottom.into(),
widths: (*widths).into(),
radius: border.radius.into(),
scale: Au::from_f32_px(0.0),
},
task_info: None,
handle: None,
},
},
BrushKind::new_border(border, *widths),
None,
);

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

@ -4,18 +4,20 @@
use api::{BorderRadius, ClipMode, ComplexClipRegion, DeviceIntRect, DevicePixelScale, ImageMask};
use api::{ImageRendering, LayoutRect, LayoutSize, LayoutPoint, LayoutVector2D, LocalClip};
use api::{BoxShadowClipMode, LayoutToWorldScale, LineOrientation, LineStyle, LayoutTransform};
use api::{BoxShadowClipMode, LayoutToWorldScale, LineOrientation, LineStyle};
use api::{LayoutToWorldTransform, WorldPixel, WorldRect, WorldPoint, WorldSize};
use border::{ensure_no_corner_overlap};
use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowClipSource, BoxShadowCacheKey};
use clip_scroll_tree::{ClipScrollTree, CoordinateSystemId, SpatialNodeIndex};
use ellipse::Ellipse;
use gpu_cache::{GpuCache, GpuCacheHandle, ToGpuBlocks};
use gpu_types::BoxShadowStretchMode;
use prim_store::{BrushClipMaskKind, ClipData, ImageMaskData};
use plane_split::{Clipper, Polygon};
use prim_store::{ClipData, ImageMaskData};
use render_task::to_cache_size;
use resource_cache::{ImageRequest, ResourceCache};
use std::u32;
use util::{extract_inner_rect_safe, pack_as_float, recycle_vec, MatrixHelpers};
use std::{cmp, u32};
use util::{extract_inner_rect_safe, pack_as_float, recycle_vec, MaxRect};
/*
@ -199,41 +201,7 @@ pub struct ClipNodeRange {
enum ClipSpaceConversion {
Local,
Offset(LayoutVector2D),
Transform(LayoutTransform, LayoutTransform),
}
impl ClipSpaceConversion {
fn transform_to_prim_space(&self, rect: &LayoutRect) -> Option<LayoutRect> {
match *self {
ClipSpaceConversion::Local => {
Some(*rect)
}
ClipSpaceConversion::Offset(ref offset) => {
Some(rect.translate(offset))
}
ClipSpaceConversion::Transform(ref transform, _) => {
if transform.has_perspective_component() {
None
} else {
transform.transform_rect(rect)
}
}
}
}
fn transform_from_prim_space(&self, rect: &LayoutRect) -> Option<LayoutRect> {
match *self {
ClipSpaceConversion::Local => {
Some(*rect)
}
ClipSpaceConversion::Offset(offset) => {
Some(rect.translate(&-offset))
}
ClipSpaceConversion::Transform(_, ref inv_transform) => {
inv_transform.transform_rect(rect)
}
}
}
Transform(LayoutToWorldTransform),
}
// Temporary information that is cached and reused
@ -356,8 +324,7 @@ pub struct ClipChainInstance {
pub clips_range: ClipNodeRange,
pub local_clip_rect: LayoutRect,
pub has_non_root_coord_system: bool,
pub local_bounding_rect: LayoutRect,
pub clip_mask_kind: BrushClipMaskKind,
pub world_clip_rect: WorldRect,
}
impl ClipStore {
@ -453,17 +420,12 @@ impl ClipStore {
resource_cache: &mut ResourceCache,
device_pixel_scale: DevicePixelScale,
) -> Option<ClipChainInstance> {
// Trivial check to see if the primitive is clipped out by the
// local clip rect of the primitive itself.
let mut local_bounding_rect = match local_prim_rect.intersection(&local_prim_clip_rect) {
Some(rect) => rect,
None => return None,
};
let mut current_local_clip_rect = local_prim_clip_rect;
let mut local_clip_rect = local_prim_clip_rect;
let mut world_clip_rect = WorldRect::max_rect();
let spatial_nodes = &clip_scroll_tree.spatial_nodes;
// Walk the clip chain to build local rects, and collect the
// smallest possible local clip area.
// smallest possible local/device clip area.
self.clip_node_info.clear();
let ref_spatial_node = &spatial_nodes[spatial_node_index.0];
@ -491,13 +453,11 @@ impl ClipStore {
} else {
let xf = clip_scroll_tree.get_relative_transform(
clip_node.spatial_node_index,
spatial_node_index,
SpatialNodeIndex(0),
);
xf.and_then(|xf| {
xf.inverse().map(|inv| {
ClipSpaceConversion::Transform(xf, inv)
})
xf.map(|xf| {
ClipSpaceConversion::Transform(xf.with_destination::<WorldPixel>())
})
};
@ -505,20 +465,33 @@ impl ClipStore {
// requested, and cache the conversion information for the next step.
if let Some(conversion) = conversion {
if let Some(clip_rect) = clip_node.item.get_local_clip_rect() {
let clip_rect = conversion.transform_to_prim_space(&clip_rect);
if let Some(clip_rect) = clip_rect {
local_bounding_rect = match local_bounding_rect.intersection(&clip_rect) {
Some(new_local_bounding_rect) => new_local_bounding_rect,
None => return None,
};
match conversion {
ClipSpaceConversion::Local => {
local_clip_rect = match local_clip_rect.intersection(&clip_rect) {
Some(local_clip_rect) => local_clip_rect,
None => return None,
};
}
ClipSpaceConversion::Offset(ref offset) => {
let clip_rect = clip_rect.translate(offset);
local_clip_rect = match local_clip_rect.intersection(&clip_rect) {
Some(local_clip_rect) => local_clip_rect,
None => return None,
};
}
ClipSpaceConversion::Transform(ref transform) => {
let world_clip_rect_for_item = match project_rect(
transform,
&clip_rect,
) {
Some(rect) => rect,
None => return None,
};
if ref_spatial_node.coordinate_system_id == clip_spatial_node.coordinate_system_id {
current_local_clip_rect = match current_local_clip_rect.intersection(&clip_rect) {
Some(new_local_clip_rect) => new_local_clip_rect,
None => {
return None
}
}
world_clip_rect = match world_clip_rect.intersection(&world_clip_rect_for_item) {
Some(world_clip_rect) => world_clip_rect,
None => return None,
};
}
}
}
@ -533,6 +506,24 @@ impl ClipStore {
current_clip_chain_id = clip_chain_node.parent_clip_chain_id;
}
let local_bounding_rect = match local_prim_rect.intersection(&local_clip_rect) {
Some(rect) => rect,
None => return None,
};
let world_bounding_rect = match project_rect(
&ref_spatial_node.world_content_transform.to_transform(),
&local_bounding_rect,
) {
Some(world_bounding_rect) => world_bounding_rect,
None => return None,
};
let world_clip_rect = match world_clip_rect.intersection(&world_bounding_rect) {
Some(world_clip_rect) => world_clip_rect,
None => return None,
};
// Now, we've collected all the clip nodes that *potentially* affect this
// primitive region, and reduced the size of the prim region as much as possible.
@ -540,36 +531,24 @@ impl ClipStore {
let first_clip_node_index = self.clip_node_indices.len() as u32;
let mut has_non_root_coord_system = false;
let mut clip_mask_kind = BrushClipMaskKind::Individual;
// For each potential clip node
for node_info in self.clip_node_info.drain(..) {
let node = &mut self.clip_nodes[node_info.node_index.0 as usize];
// TODO(gw): We can easily extend the segment builder to support these clip sources in
// the future, but they are rarely used.
// We must do this check here in case we continue early below.
if node.item.is_image_or_line_decoration_clip() {
clip_mask_kind = BrushClipMaskKind::Global;
}
// Convert the prim rect into the clip nodes local space
let prim_rect = node_info
.conversion
.transform_from_prim_space(&current_local_clip_rect);
// See how this clip affects the prim region.
let clip_result = match prim_rect {
Some(prim_rect) => {
node.item.get_clip_result(&prim_rect)
let clip_result = match node_info.conversion {
ClipSpaceConversion::Local => {
node.item.get_clip_result(&local_bounding_rect)
}
None => {
// If we can't get a local rect due to perspective
// weirdness, just assume that we need a clip mask
// for this case.
// TODO(gw): We can probably improve on this once
// we support local space picture raster.
ClipResult::Partial
ClipSpaceConversion::Offset(offset) => {
node.item.get_clip_result(&local_bounding_rect.translate(&-offset))
}
ClipSpaceConversion::Transform(ref transform) => {
node.item.get_clip_result_complex(
transform,
&world_bounding_rect,
)
}
};
@ -598,15 +577,9 @@ impl ClipStore {
ClipNodeFlags::SAME_SPATIAL_NODE | ClipNodeFlags::SAME_COORD_SYSTEM
}
ClipSpaceConversion::Offset(..) => {
if !node.item.is_rect() {
clip_mask_kind = BrushClipMaskKind::Global;
}
ClipNodeFlags::SAME_COORD_SYSTEM
}
ClipSpaceConversion::Transform(..) => {
// If this primitive is clipped by clips from a different coordinate system, then we
// need to apply a clip mask for the entire primitive.
clip_mask_kind = BrushClipMaskKind::Global;
ClipNodeFlags::empty()
}
};
@ -630,9 +603,8 @@ impl ClipStore {
Some(ClipChainInstance {
clips_range,
has_non_root_coord_system,
local_clip_rect: current_local_clip_rect,
local_bounding_rect,
clip_mask_kind,
local_clip_rect,
world_clip_rect,
})
}
}
@ -873,20 +845,6 @@ impl ClipItem {
}
}
pub fn is_rect(&self) -> bool {
match *self {
ClipItem::Rectangle(..) => true,
_ => false,
}
}
pub fn is_image_or_line_decoration_clip(&self) -> bool {
match *self {
ClipItem::Image(..) | ClipItem::LineDecoration(..) => true,
_ => false,
}
}
// Get an optional clip rect that a clip source can provide to
// reduce the size of a primitive region. This is typically
// used to eliminate redundant clips, and reduce the size of
@ -904,6 +862,53 @@ impl ClipItem {
}
}
fn get_clip_result_complex(
&self,
transform: &LayoutToWorldTransform,
prim_rect: &WorldRect,
) -> ClipResult {
let (clip_rect, inner_rect) = match *self {
ClipItem::Rectangle(clip_rect, ClipMode::Clip) => {
(clip_rect, Some(clip_rect))
}
ClipItem::RoundedRectangle(ref clip_rect, ref radius, ClipMode::Clip) => {
let inner_clip_rect = extract_inner_rect_safe(clip_rect, radius);
(*clip_rect, inner_clip_rect)
}
ClipItem::Rectangle(_, ClipMode::ClipOut) |
ClipItem::RoundedRectangle(_, _, ClipMode::ClipOut) |
ClipItem::Image(..) |
ClipItem::BoxShadow(..) |
ClipItem::LineDecoration(..) => {
return ClipResult::Partial
}
};
let inner_clip_rect = inner_rect.and_then(|ref inner_rect| {
project_inner_rect(transform, inner_rect)
});
if let Some(inner_clip_rect) = inner_clip_rect {
if inner_clip_rect.contains_rect(prim_rect) {
return ClipResult::Accept;
}
}
let outer_clip_rect = match project_rect(transform, &clip_rect) {
Some(outer_clip_rect) => outer_clip_rect,
None => return ClipResult::Partial,
};
match outer_clip_rect.intersection(prim_rect) {
Some(..) => {
ClipResult::Partial
}
None => {
ClipResult::Reject
}
}
}
// Check how a given clip source affects a local primitive region.
fn get_clip_result(
&self,
@ -1056,3 +1061,71 @@ pub fn rounded_rectangle_contains_point(
true
}
fn project_rect(
transform: &LayoutToWorldTransform,
rect: &LayoutRect,
) -> Option<WorldRect> {
let homogens = [
transform.transform_point2d_homogeneous(&rect.origin),
transform.transform_point2d_homogeneous(&rect.top_right()),
transform.transform_point2d_homogeneous(&rect.bottom_left()),
transform.transform_point2d_homogeneous(&rect.bottom_right()),
];
// Note: we only do the full frustum collision when the polygon approaches the camera plane.
// Otherwise, it will be clamped to the screen bounds anyway.
if homogens.iter().any(|h| h.w <= 0.0) {
let mut clipper = Clipper::new();
clipper.add_frustum(
transform,
None,
);
let polygon = Polygon::from_rect(*rect, 1);
let results = clipper.clip(polygon);
if results.is_empty() {
return None
}
Some(WorldRect::from_points(results
.into_iter()
// filter out parts behind the view plane
.flat_map(|poly| &poly.points)
.map(|p| {
let mut homo = transform.transform_point2d_homogeneous(&p.to_2d());
homo.w = homo.w.max(0.00000001); // avoid infinite values
homo.to_point2d().unwrap()
})
))
} else {
// we just checked for all the points to be in positive hemisphere, so `unwrap` is valid
Some(WorldRect::from_points(&[
homogens[0].to_point2d().unwrap(),
homogens[1].to_point2d().unwrap(),
homogens[2].to_point2d().unwrap(),
homogens[3].to_point2d().unwrap(),
]))
}
}
pub fn project_inner_rect(
transform: &LayoutToWorldTransform,
rect: &LayoutRect,
) -> Option<WorldRect> {
let points = [
transform.transform_point2d(&rect.origin)?,
transform.transform_point2d(&rect.top_right())?,
transform.transform_point2d(&rect.bottom_left())?,
transform.transform_point2d(&rect.bottom_right())?,
];
let mut xs = [points[0].x, points[1].x, points[2].x, points[3].x];
let mut ys = [points[0].y, points[1].y, points[2].y, points[3].y];
xs.sort_by(|a, b| a.partial_cmp(b).unwrap_or(cmp::Ordering::Equal));
ys.sort_by(|a, b| a.partial_cmp(b).unwrap_or(cmp::Ordering::Equal));
Some(WorldRect::new(
WorldPoint::new(xs[1], ys[1]),
WorldSize::new(xs[2] - xs[1], ys[2] - ys[1]),
))
}

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

@ -24,7 +24,7 @@ use hit_test::{HitTestingItem, HitTestingRun};
use image::simplify_repeated_primitive;
use internal_types::{FastHashMap, FastHashSet};
use picture::{PictureCompositeMode, PictureId, PicturePrimitive};
use prim_store::{BrushClipMaskKind, BrushKind, BrushPrimitive, BrushSegmentDescriptor};
use prim_store::{BrushKind, BrushPrimitive, BrushSegmentDescriptor};
use prim_store::{EdgeAaSegmentMask, ImageSource};
use prim_store::{BorderSource, BrushSegment, PrimitiveContainer, PrimitiveIndex, PrimitiveStore};
use prim_store::{OpacityBinding, ScrollNodeAndClipChain, TextRunPrimitive};
@ -1706,7 +1706,6 @@ impl<'a> DisplayListFlattener<'a> {
);
let descriptor = BrushSegmentDescriptor {
segments,
clip_mask_kind: BrushClipMaskKind::Unknown,
};
let brush_kind = match border.source {

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

@ -28,7 +28,7 @@ use renderer::{MAX_VERTEX_TEXTURE_WIDTH};
use resource_cache::{ImageProperties, ImageRequest, ResourceCache};
use scene::SceneProperties;
use segment::SegmentBuilder;
use std::{mem, usize};
use std::{cmp, mem, usize};
use util::{MatrixHelpers, calculate_screen_bounding_rect};
use util::{pack_as_float, recycle_vec, TransformedRectKind};
@ -420,6 +420,41 @@ impl BrushKind {
opacity_binding: OpacityBinding::new(),
}
}
// Construct a brush that is a border with `border` style and `widths`
// dimensions.
pub fn new_border(border: NormalBorder, widths: BorderWidths) -> BrushKind {
let cache_key = BorderCacheKey::new(&border, &widths);
BrushKind::Border {
source: BorderSource::Border {
border,
widths,
cache_key,
task_info: None,
handle: None,
}
}
}
// Construct a brush that is an image wisth `stretch_size` dimensions and
// `color`.
pub fn new_image(
request: ImageRequest,
stretch_size: LayoutSize,
color: ColorF
) -> BrushKind {
BrushKind::Image {
request,
alpha_type: AlphaType::PremultipliedAlpha,
stretch_size,
tile_spacing: LayoutSize::new(0., 0.),
color,
source: ImageSource::Default,
sub_rect: None,
opacity_binding: OpacityBinding::new(),
visible_tiles: Vec::new(),
}
}
}
bitflags! {
@ -482,17 +517,9 @@ impl BrushSegment {
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BrushClipMaskKind {
Unknown,
Individual,
Global,
}
#[derive(Debug)]
pub struct BrushSegmentDescriptor {
pub segments: Vec<BrushSegment>,
pub clip_mask_kind: BrushClipMaskKind,
}
#[derive(Debug)]
@ -1242,11 +1269,35 @@ impl PrimitiveContainer {
None,
))
}
BrushKind::Border { ref source } => {
let source = match *source {
BorderSource::Image(request) => {
BrushKind::Border {
source: BorderSource::Image(request)
}
},
BorderSource::Border { border, widths, .. } => {
let border = border.with_color(shadow.color);
BrushKind::new_border(border, widths)
}
};
PrimitiveContainer::Brush(BrushPrimitive::new(
source,
None,
))
}
BrushKind::Image { request, stretch_size, .. } => {
PrimitiveContainer::Brush(BrushPrimitive::new(
BrushKind::new_image(request.clone(),
stretch_size.clone(),
shadow.color),
None,
))
}
BrushKind::Clear |
BrushKind::Picture { .. } |
BrushKind::Image { .. } |
BrushKind::YuvImage { .. } |
BrushKind::Border { .. } |
BrushKind::RadialGradient { .. } |
BrushKind::LinearGradient { .. } => {
panic!("bug: other brush kinds not expected here yet");
@ -1659,21 +1710,9 @@ impl PrimitiveStore {
}
};
let clipped_device_rect = match calculate_screen_bounding_rect(
&prim_context.spatial_node.world_content_transform,
&clip_chain.local_bounding_rect,
frame_context.device_pixel_scale,
None,
) {
Some(rect) => rect,
None => {
if cfg!(debug_assertions) && is_chased {
println!("\tculled for being behind the near plane of transform: {:?}",
prim_context.spatial_node.world_content_transform);
}
return None
}
};
let clipped_device_rect = (clip_chain.world_clip_rect * frame_context.device_pixel_scale)
.round_out()
.to_i32();
let clipped_device_rect = match clipped_device_rect.intersection(&frame_context.screen_rect) {
Some(clipped_device_rect) => clipped_device_rect,
@ -1971,12 +2010,9 @@ fn write_brush_segment_description(
frame_state: &mut FrameBuildingState,
) {
match brush.segment_desc {
Some(ref segment_desc) => {
// If we already have a segment descriptor, only run through the
// clips list if we haven't already determined the mask kind.
if segment_desc.clip_mask_kind == clip_chain.clip_mask_kind {
return;
}
Some(..) => {
// If we already have a segment descriptor, skip segment build.
return;
}
None => {
// If no segment descriptor built yet, see if it is a brush
@ -2006,6 +2042,7 @@ fn write_brush_segment_description(
);
// Segment the primitive on all the local-space clip sources that we can.
let mut local_clip_count = 0;
for i in 0 .. clip_chain.clips_range.count {
let (clip_node, flags) = frame_state.clip_store.get_node_from_range(&clip_chain.clips_range, i);
@ -2018,6 +2055,8 @@ fn write_brush_segment_description(
continue;
}
local_clip_count += 1;
let (local_clip_rect, radius, mode) = match clip_node.item {
ClipItem::RoundedRectangle(rect, radii, clip_mode) => {
rect_clips_only = false;
@ -2063,10 +2102,40 @@ fn write_brush_segment_description(
}
if is_large || rect_clips_only {
match brush.segment_desc {
Some(ref mut segment_desc) => {
segment_desc.clip_mask_kind = clip_chain.clip_mask_kind;
// If there were no local clips, then we will subdivide the primitive into
// a uniform grid (up to 8x8 segments). This will typically result in
// a significant number of those segments either being completely clipped,
// or determined to not need a clip mask for that segment.
if local_clip_count == 0 && clip_chain.clips_range.count > 0 {
let x_clip_count = cmp::min(8, (metadata.local_rect.size.width / 128.0).ceil() as i32);
let y_clip_count = cmp::min(8, (metadata.local_rect.size.height / 128.0).ceil() as i32);
for y in 0 .. y_clip_count {
let y0 = metadata.local_rect.size.height * y as f32 / y_clip_count as f32;
let y1 = metadata.local_rect.size.height * (y+1) as f32 / y_clip_count as f32;
for x in 0 .. x_clip_count {
let x0 = metadata.local_rect.size.width * x as f32 / x_clip_count as f32;
let x1 = metadata.local_rect.size.width * (x+1) as f32 / x_clip_count as f32;
let rect = LayoutRect::new(
LayoutPoint::new(
x0 + metadata.local_rect.origin.x,
y0 + metadata.local_rect.origin.y,
),
LayoutSize::new(
x1 - x0,
y1 - y0,
),
);
segment_builder.push_mask_region(rect, LayoutRect::zero(), None);
}
}
}
match brush.segment_desc {
Some(..) => panic!("bug: should not already have descriptor"),
None => {
// TODO(gw): We can probably make the allocation
// patterns of this and the segment
@ -2088,7 +2157,6 @@ fn write_brush_segment_description(
brush.segment_desc = Some(BrushSegmentDescriptor {
segments,
clip_mask_kind: clip_chain.clip_mask_kind,
});
}
}
@ -2099,7 +2167,7 @@ impl Primitive {
fn update_clip_task_for_brush(
&mut self,
prim_context: &PrimitiveContext,
clip_chain: &ClipChainInstance,
prim_clip_chain: &ClipChainInstance,
combined_outer_rect: &DeviceIntRect,
pic_state: &mut PictureState,
frame_context: &FrameBuildingContext,
@ -2115,7 +2183,7 @@ impl Primitive {
write_brush_segment_description(
brush,
&self.metadata,
clip_chain,
prim_clip_chain,
frame_state,
);
@ -2123,42 +2191,51 @@ impl Primitive {
Some(ref mut description) => description,
None => return false,
};
let clip_mask_kind = segment_desc.clip_mask_kind;
for segment in &mut segment_desc.segments {
if !segment.may_need_clip_mask && clip_mask_kind != BrushClipMaskKind::Global {
segment.clip_task_id = BrushSegmentTaskId::Opaque;
continue;
}
let intersected_rect = calculate_screen_bounding_rect(
&prim_context.spatial_node.world_content_transform,
&segment.local_rect,
frame_context.device_pixel_scale,
Some(&combined_outer_rect),
);
let bounds = match intersected_rect {
Some(bounds) => bounds,
None => {
segment.clip_task_id = BrushSegmentTaskId::Empty;
continue;
}
};
if clip_chain.clips_range.count > 0 {
let clip_task = RenderTask::new_mask(
bounds,
clip_chain.clips_range,
frame_state.clip_store,
// Build a clip chain for the smaller segment rect. This will
// often manage to eliminate most/all clips, and sometimes
// clip the segment completely.
let segment_clip_chain = frame_state
.clip_store
.build_clip_chain_instance(
self.metadata.clip_chain_id,
segment.local_rect,
self.metadata.local_clip_rect,
prim_context.spatial_node_index,
&frame_context.clip_scroll_tree,
frame_state.gpu_cache,
frame_state.resource_cache,
frame_state.render_tasks,
frame_context.device_pixel_scale,
);
let clip_task_id = frame_state.render_tasks.add(clip_task);
pic_state.tasks.push(clip_task_id);
segment.clip_task_id = BrushSegmentTaskId::RenderTaskId(clip_task_id);
match segment_clip_chain {
Some(segment_clip_chain) => {
if segment_clip_chain.clips_range.count == 0 {
segment.clip_task_id = BrushSegmentTaskId::Opaque;
continue;
}
let bounds = (segment_clip_chain.world_clip_rect * frame_context.device_pixel_scale)
.round_out()
.to_i32();
let clip_task = RenderTask::new_mask(
bounds,
segment_clip_chain.clips_range,
frame_state.clip_store,
frame_state.gpu_cache,
frame_state.resource_cache,
frame_state.render_tasks,
);
let clip_task_id = frame_state.render_tasks.add(clip_task);
pic_state.tasks.push(clip_task_id);
segment.clip_task_id = BrushSegmentTaskId::RenderTaskId(clip_task_id);
}
None => {
segment.clip_task_id = BrushSegmentTaskId::Empty;
}
}
}
@ -2754,7 +2831,6 @@ impl Primitive {
if needs_update {
brush.segment_desc = Some(BrushSegmentDescriptor {
segments: new_segments,
clip_mask_kind: BrushClipMaskKind::Unknown,
});
// The segments have changed, so force the GPU cache to

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

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderRadius, DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixelScale};
use api::{DevicePoint, DeviceRect, DeviceSize, LayoutPixel, LayoutPoint, LayoutRect, LayoutSize};
use api::{DeviceRect, LayoutPixel, LayoutRect};
use api::{WorldPixel, WorldRect};
use euclid::{Point2D, Rect, Size2D, TypedPoint2D, TypedRect, TypedSize2D};
use euclid::{TypedTransform2D, TypedTransform3D, TypedVector2D};
@ -331,15 +331,6 @@ pub trait MaxRect {
fn max_rect() -> Self;
}
impl MaxRect for LayoutRect {
fn max_rect() -> Self {
LayoutRect::new(
LayoutPoint::new(f32::MIN / 2.0, f32::MIN / 2.0),
LayoutSize::new(f32::MAX, f32::MAX),
)
}
}
impl MaxRect for DeviceIntRect {
fn max_rect() -> Self {
DeviceIntRect::new(
@ -349,7 +340,7 @@ impl MaxRect for DeviceIntRect {
}
}
impl MaxRect for DeviceRect {
impl<U> MaxRect for TypedRect<f32, U> {
fn max_rect() -> Self {
// Having an unlimited bounding box is fine up until we try
// to cast it to `i32`, where we get `-2147483648` for any
@ -359,9 +350,9 @@ impl MaxRect for DeviceRect {
// with explanation left as an exercise for the reader.
const MAX_COORD: f32 = 1.0e9;
DeviceRect::new(
DevicePoint::new(-MAX_COORD, -MAX_COORD),
DeviceSize::new(2.0 * MAX_COORD, 2.0 * MAX_COORD),
TypedRect::new(
TypedPoint2D::new(-MAX_COORD, -MAX_COORD),
TypedSize2D::new(2.0 * MAX_COORD, 2.0 * MAX_COORD),
)
}
}

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

@ -263,6 +263,18 @@ pub struct NormalBorder {
pub radius: BorderRadius,
}
impl NormalBorder {
// Construct a border based upon self with color
pub fn with_color(&self, color: ColorF) -> Self {
let mut b = *self;
b.left.color = color;
b.right.color = color;
b.top.color = color;
b.bottom.color = color;
b
}
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum RepeatMode {

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

@ -1 +1 @@
93997662842b6d8bafbdb3dde79009c930db66ca
816ff14c1805c145ccd60d0227d82b1541fc24eb

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

@ -43,7 +43,7 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-1) fuzzy-if(skiaConten
# Tests for clipping the contents of replaced elements and overflow!=visible
!= clipping-4-ref.html clipping-4-notref.html
fuzzy-if(true,0-1,0-20) fuzzy-if(d2d,0-72,0-196) fuzzy-if(cocoaWidget,0-1,0-180) fuzzy-if(Android,0-140,0-237) == clipping-4-canvas.html clipping-4-ref.html # bug 732535
fuzzy-if(true,0-1,0-20) fuzzy-if(d2d,0-72,0-196) fuzzy-if(cocoaWidget,0-1,0-180) fuzzy-if(Android,0-140,0-237) fuzzy-if(webrender&&cocoaWidget,8-8,1-1) == clipping-4-canvas.html clipping-4-ref.html # bug 732535
fuzzy-if(Android,0-5,0-54) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),0-1,0-10) fuzzy-if(skiaContent,0-1,0-172) == clipping-4-image.html clipping-4-ref.html
fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),0-1,0-10) fuzzy-if(skiaContent,0-1,0-77) == clipping-4-overflow-hidden.html clipping-4-ref.html
== clipping-5-canvas.html clipping-5-refc.html

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

@ -33,6 +33,7 @@ public final class PrefsHelper {
INT_TO_STRING_PREFS.add("network.cookie.cookieBehavior");
INT_TO_STRING_PREFS.add("home.sync.updateMode");
INT_TO_STRING_PREFS.add("browser.image_blocking");
INT_TO_STRING_PREFS.add("media.autoplay.default");
INT_TO_BOOL_PREFS.add("browser.display.use_document_fonts");
}