зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
5d011e88d1
|
@ -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 = Don’t 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: '"'}}
|
||||
|
|
|
@ -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(¤t_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");
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче