mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Merge mozilla-central to mozilla-inbound. a=merge on a CLOSED TREE
This commit is contained in:
commit
2056f57259
@ -435,6 +435,9 @@ void DocAccessible::Shutdown() {
|
||||
mDependentIDsHashes.Clear();
|
||||
mNodeToAccessibleMap.Clear();
|
||||
|
||||
mAnchorJumpElm = nullptr;
|
||||
mInvalidationList.Clear();
|
||||
|
||||
for (auto iter = mAccessibleCache.Iter(); !iter.Done(); iter.Next()) {
|
||||
Accessible* accessible = iter.Data();
|
||||
MOZ_ASSERT(accessible);
|
||||
|
@ -21,7 +21,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul");
|
||||
pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindowMac.xhtml");
|
||||
|
||||
// Enables some extra Extension System Logging (can reduce performance)
|
||||
pref("extensions.logging.enabled", false);
|
||||
|
@ -31,7 +31,7 @@
|
||||
<?xml-stylesheet href="chrome://browser/skin/places/editBookmark.css" type="text/css"?>
|
||||
|
||||
# All DTD information is stored in a separate file so that it can be shared by
|
||||
# hiddenWindow.xul.
|
||||
# hiddenWindowMac.xhtml.
|
||||
<!DOCTYPE window [
|
||||
#include browser-doctype.inc
|
||||
]>
|
||||
|
@ -12,7 +12,6 @@
|
||||
]>
|
||||
|
||||
<window id="main-window"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
#include macWindow.inc.xul
|
@ -151,7 +151,7 @@ with Files("browser-sync.js"):
|
||||
with Files("contentSearch*"):
|
||||
BUG_COMPONENT = ("Firefox", "Search")
|
||||
|
||||
with Files("hiddenWindow.xul"):
|
||||
with Files("hiddenWindowMac.xhtml"):
|
||||
BUG_COMPONENT = ("Firefox", "Device Permissions")
|
||||
|
||||
with Files("macWindow.inc.xul"):
|
||||
|
@ -44,7 +44,7 @@ function nonBrowserWindowStartup() {
|
||||
|
||||
// If no windows are active (i.e. we're the hidden window), disable the close, minimize
|
||||
// and zoom menu commands as well
|
||||
if (window.location.href == "chrome://browser/content/hiddenWindow.xul") {
|
||||
if (window.location.href == "chrome://browser/content/hiddenWindowMac.xhtml") {
|
||||
var hiddenWindowDisabledItems = ["cmd_close", "minimizeWindow", "zoomWindow"];
|
||||
for (let hiddenWindowDisabledItem of hiddenWindowDisabledItems) {
|
||||
element = document.getElementById(hiddenWindowDisabledItem);
|
||||
@ -96,7 +96,7 @@ function nonBrowserWindowDelayedStartup() {
|
||||
function nonBrowserWindowShutdown() {
|
||||
// If this is the hidden window being closed, release our reference to
|
||||
// the dock menu element to prevent leaks on shutdown
|
||||
if (window.location.href == "chrome://browser/content/hiddenWindow.xul") {
|
||||
if (window.location.href == "chrome://browser/content/hiddenWindowMac.xhtml") {
|
||||
let dockSupport = Cc["@mozilla.org/widget/macdocksupport;1"]
|
||||
.getService(Ci.nsIMacDockSupport);
|
||||
dockSupport.dockMenu = null;
|
||||
|
@ -11,8 +11,10 @@
|
||||
.tab-icon-image:not([src]):not([pinned]):not([crashed]):not([sharing]),
|
||||
.tab-icon-image[busy],
|
||||
.tab-throbber:not([busy]),
|
||||
.tab-icon-pip:not([pictureinpicture]),
|
||||
.tab-icon-sound:not([soundplaying]):not([muted]):not([activemedia-blocked]),
|
||||
.tab-icon-sound[pinned],
|
||||
.tab-icon-sound[pictureinpicture],
|
||||
.tab-sharing-icon-overlay,
|
||||
.tab-icon-overlay {
|
||||
display: none;
|
||||
|
@ -1951,7 +1951,10 @@
|
||||
xbl:inherits="xbl:text=label,accesskey,fadein,pinned,selected=visuallyselected,attention"
|
||||
role="presentation"/>
|
||||
</xul:hbox>
|
||||
<xul:image xbl:inherits="soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected=visuallyselected,activemedia-blocked"
|
||||
<xul:image xbl:inherits="pictureinpicture"
|
||||
class="tab-icon-pip"
|
||||
role="presentation"/>
|
||||
<xul:image xbl:inherits="soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected=visuallyselected,activemedia-blocked,pictureinpicture"
|
||||
anonid="soundplaying-icon"
|
||||
class="tab-icon-sound"
|
||||
role="presentation"/>
|
||||
@ -2063,6 +2066,12 @@
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="pictureinpicture" readonly="true">
|
||||
<getter>
|
||||
return this.getAttribute("pictureinpicture") == "true";
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="activeMediaBlocked" readonly="true">
|
||||
<getter>
|
||||
return this.getAttribute("activemedia-blocked") == "true";
|
||||
|
@ -104,7 +104,7 @@ browser.jar:
|
||||
content/browser/contentTheme.js (content/contentTheme.js)
|
||||
#ifdef XP_MACOSX
|
||||
# XXX: We should exclude this one as well (bug 71895)
|
||||
* content/browser/hiddenWindow.xul (content/hiddenWindow.xul)
|
||||
* content/browser/hiddenWindowMac.xhtml (content/hiddenWindowMac.xhtml)
|
||||
content/browser/nonbrowser-mac.js (content/nonbrowser-mac.js)
|
||||
#endif
|
||||
#ifndef XP_MACOSX
|
||||
|
@ -263,6 +263,7 @@ class TabsPanel extends TabsListBase {
|
||||
setAttributes(secondaryButton, {
|
||||
muted: tab.muted,
|
||||
soundplaying: tab.soundPlaying,
|
||||
pictureinpicture: tab.pictureinpicture,
|
||||
hidden: !(tab.muted || tab.soundPlaying),
|
||||
});
|
||||
}
|
||||
|
@ -377,6 +377,7 @@
|
||||
padding: 10px calc(@horizontalTabPadding@ - 2px);
|
||||
}
|
||||
|
||||
.tab-icon-pip,
|
||||
.tab-icon-sound {
|
||||
margin-inline-start: 1px;
|
||||
width: 16px;
|
||||
@ -384,6 +385,16 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tab-icon-pip[pictureinpicture] {
|
||||
background-image: url(chrome://global/skin/media/pictureinpicture.svg);
|
||||
-moz-context-properties: fill, stroke;
|
||||
fill: currentColor;
|
||||
stroke: currentColor;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-inline-start: 5px
|
||||
}
|
||||
|
||||
.tab-icon-sound[soundplaying],
|
||||
.tab-icon-sound[muted],
|
||||
.tab-icon-sound[activemedia-blocked] {
|
||||
@ -400,18 +411,21 @@
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio-blocked.svg);
|
||||
}
|
||||
|
||||
:root[lwtheme-image] .tab-icon-pip:-moz-lwtheme-darktext[pictureinpicture],
|
||||
:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-darktext[soundplaying],
|
||||
:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-darktext[muted],
|
||||
:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-darktext[activemedia-blocked] {
|
||||
filter: drop-shadow(1px 1px 1px white);
|
||||
}
|
||||
|
||||
:root[lwtheme-image] .tab-icon-pip:-moz-lwtheme-brighttext[pictureinpicture],
|
||||
:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-brighttext[soundplaying],
|
||||
:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-brighttext[muted],
|
||||
:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-brighttext[activemedia-blocked] {
|
||||
filter: drop-shadow(1px 1px 1px black);
|
||||
}
|
||||
|
||||
.tab-icon-pip[pictureinpicture]:not(:hover),
|
||||
.tab-icon-sound[soundplaying]:not(:hover),
|
||||
.tab-icon-sound[muted]:not(:hover),
|
||||
.tab-icon-sound[activemedia-blocked]:not(:hover) {
|
||||
|
@ -21,6 +21,8 @@ def rust_warning_flags(warnings_as_errors):
|
||||
# we don't need a very complicated setup.
|
||||
if warnings_as_errors:
|
||||
flags.append('-Dwarnings')
|
||||
else:
|
||||
flags.extend(('--cap-lints', 'warn'))
|
||||
|
||||
return flags
|
||||
|
||||
|
@ -58,7 +58,7 @@ if test -n "$bucket"; then
|
||||
else
|
||||
mk_add_options "export SCCACHE_BUCKET=$bucket"
|
||||
fi
|
||||
export CCACHE="$topsrcdir/sccache2/sccache"
|
||||
export CCACHE="$topsrcdir/sccache/sccache"
|
||||
export SCCACHE_VERBOSE_STATS=1
|
||||
mk_add_options MOZBUILD_MANAGE_SCCACHE_DAEMON=${topsrcdir}/sccache2/sccache
|
||||
mk_add_options MOZBUILD_MANAGE_SCCACHE_DAEMON=${topsrcdir}/sccache/sccache
|
||||
fi
|
||||
|
@ -213,7 +213,11 @@ module.exports = {
|
||||
// Require camel case names
|
||||
"camelcase": "error",
|
||||
// Warn about cyclomatic complexity in functions.
|
||||
"complexity": ["error", 40],
|
||||
// 20 is ESLint's default, and we want to keep it this way to prevent new highly
|
||||
// complex functions from being introduced. However, because Mozilla's eslintrc has
|
||||
// some other value defined, we need to override it here. See bug 1553449 for more
|
||||
// information on complex DevTools functions that are currently excluded.
|
||||
"complexity": ["error", 20],
|
||||
// Don't warn for inconsistent naming when capturing this (not so important
|
||||
// with auto-binding fat arrow functions).
|
||||
"consistent-this": "off",
|
||||
|
@ -38,6 +38,7 @@ class SummaryGraph extends PureComponent {
|
||||
this.props.selectAnimation(this.props.animation);
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
getTitleText(state) {
|
||||
const getTime =
|
||||
time => getFormatStr("player.timeLabel", numberWithDecimals(time / 1000, 2));
|
||||
@ -136,6 +137,7 @@ class SummaryGraph extends PureComponent {
|
||||
|
||||
return text;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
render() {
|
||||
const {
|
||||
|
@ -199,6 +199,7 @@ const reducers = {
|
||||
* - when changes cancel each other out leaving the rule unchanged, the rule is removed
|
||||
* from the store. Its parent rule is removed as well if it too ends up unchanged.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
[TRACK_CHANGE](state, { change }) {
|
||||
const defaults = {
|
||||
selector: null,
|
||||
@ -351,6 +352,7 @@ const reducers = {
|
||||
|
||||
return state;
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
[RESET_CHANGES](state) {
|
||||
return INITIAL_STATE;
|
||||
|
@ -325,6 +325,7 @@ CssComputedView.prototype = {
|
||||
* - value {Object} Depends on the type of the node
|
||||
* returns null if the node isn't anything we care about
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
getNodeInfo: function(node) {
|
||||
if (!node) {
|
||||
return null;
|
||||
@ -428,6 +429,7 @@ CssComputedView.prototype = {
|
||||
value,
|
||||
};
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
_createPropertyViews: function() {
|
||||
if (this._createViewsPromise) {
|
||||
|
@ -113,6 +113,7 @@ class FlexItemSizingProperties extends PureComponent {
|
||||
);
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
renderFlexibilitySection(flexItemSizing, mainFinalSize, properties, computedStyle) {
|
||||
const {
|
||||
mainDeltaSize,
|
||||
@ -183,6 +184,7 @@ class FlexItemSizingProperties extends PureComponent {
|
||||
)
|
||||
);
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
renderMinimumSizeSection(flexItemSizing, properties, dimension) {
|
||||
const { clampState, mainMinSize, mainDeltaSize } = flexItemSizing;
|
||||
|
@ -213,6 +213,7 @@ SelectorAutocompleter.prototype = {
|
||||
* '#f' requires an Id suggestion, so the state is States.ID
|
||||
* 'div > .foo' requires class suggestion, so state is States.CLASS
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
get state() {
|
||||
if (!this.searchBox || !this.searchBox.value) {
|
||||
return null;
|
||||
@ -306,6 +307,7 @@ SelectorAutocompleter.prototype = {
|
||||
}
|
||||
return this._state;
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Removes event listeners and cleans up references.
|
||||
|
@ -895,6 +895,7 @@ MarkupView.prototype = {
|
||||
/**
|
||||
* Key shortcut listener.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_onShortcut(name, event) {
|
||||
if (this._isInputOrTextarea(event.target)) {
|
||||
return;
|
||||
@ -1024,6 +1025,7 @@ MarkupView.prototype = {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Check if a node is an input or textarea
|
||||
|
@ -274,6 +274,7 @@ class ElementStyle {
|
||||
* Which pseudo element to flag as overridden.
|
||||
* Empty string or undefined will default to no pseudo element.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
updateDeclarations(pseudo = "") {
|
||||
// Gather all the text properties applied by these rules, ordered
|
||||
// from more- to less-specific. Text properties from keyframes rule are
|
||||
@ -376,6 +377,7 @@ class ElementStyle {
|
||||
}
|
||||
}
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Adds a new declaration to the rule.
|
||||
|
@ -371,6 +371,7 @@ CssRuleView.prototype = {
|
||||
* - value {Object} Depends on the type of the node
|
||||
* returns null of the node isn't anything we care about
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
getNodeInfo: function(node) {
|
||||
if (!node) {
|
||||
return null;
|
||||
@ -486,6 +487,7 @@ CssRuleView.prototype = {
|
||||
value,
|
||||
};
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Retrieve the RuleEditor instance.
|
||||
@ -1142,6 +1144,7 @@ CssRuleView.prototype = {
|
||||
/**
|
||||
* Creates editor UI for each of the rules in _elementStyle.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_createEditors: function() {
|
||||
// Run through the current list of rules, attaching
|
||||
// their editors in order. Create editors if needed.
|
||||
@ -1222,6 +1225,7 @@ CssRuleView.prototype = {
|
||||
|
||||
return promise.all(editorReadyPromises);
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Highlight rules that matches the filter search value and returns a
|
||||
|
@ -389,6 +389,7 @@ TextPropertyEditor.prototype = {
|
||||
/**
|
||||
* Populate the span based on changes to the TextProperty.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
update: function() {
|
||||
if (this.ruleView.isDestroyed) {
|
||||
return;
|
||||
@ -610,6 +611,7 @@ TextPropertyEditor.prototype = {
|
||||
// Update the rule property highlight.
|
||||
this.ruleView._updatePropertyHighlight(this);
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
_onStartEditing: function() {
|
||||
this.element.classList.remove("ruleview-overridden");
|
||||
|
@ -103,6 +103,7 @@ exports.getCustomTreeMapDisplays = function() {
|
||||
* @param {snapshotState | diffingState} state
|
||||
* @return {String}
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
exports.getStatusText = function(state) {
|
||||
assert(state, "Must have a state");
|
||||
|
||||
@ -170,6 +171,7 @@ exports.getStatusText = function(state) {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Returns a string representing a readable form of the snapshot's state;
|
||||
@ -178,6 +180,7 @@ exports.getStatusText = function(state) {
|
||||
* @param {snapshotState | diffingState} state
|
||||
* @return {String}
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
exports.getStatusTextFull = function(state) {
|
||||
assert(!!state, "Must have a state");
|
||||
|
||||
@ -245,6 +248,7 @@ exports.getStatusTextFull = function(state) {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Return true if the snapshot is in a diffable state, false otherwise.
|
||||
|
@ -186,6 +186,7 @@ class RequestListItem extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
render() {
|
||||
const {
|
||||
blocked,
|
||||
@ -284,6 +285,7 @@ class RequestListItem extends Component {
|
||||
)
|
||||
);
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
}
|
||||
|
||||
module.exports = RequestListItem;
|
||||
|
@ -119,6 +119,7 @@ class SecurityPanel extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
render() {
|
||||
const { openLink, request } = this.props;
|
||||
const { securityInfo, url } = request;
|
||||
@ -232,6 +233,7 @@ class SecurityPanel extends Component {
|
||||
})
|
||||
);
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
}
|
||||
|
||||
module.exports = SecurityPanel;
|
||||
|
@ -46,6 +46,7 @@ function Requests() {
|
||||
* This reducer is responsible for maintaining list of request
|
||||
* within the Network panel.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function requestsReducer(state = Requests(), action) {
|
||||
switch (action.type) {
|
||||
// Appending new request into the list/map.
|
||||
@ -182,6 +183,7 @@ function requestsReducer(state = Requests(), action) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
// Helpers
|
||||
|
||||
|
@ -120,6 +120,7 @@ function processFlagFilter(type, value) {
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
function isFlagFilterMatch(item, { type, value, negative }) {
|
||||
if (value == null) {
|
||||
return false;
|
||||
@ -233,6 +234,7 @@ function isFlagFilterMatch(item, { type, value, negative }) {
|
||||
}
|
||||
return match;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
function isSizeMatch(value, size) {
|
||||
return value >= (size - size / 10) && value <= (size + size / 10);
|
||||
|
@ -25,6 +25,7 @@ class RequestListContextMenu {
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
open(event, clickedRequest, requests) {
|
||||
const {
|
||||
id,
|
||||
@ -284,6 +285,7 @@ class RequestListContextMenu {
|
||||
screenY: event.screenY,
|
||||
});
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Opens selected item in the debugger
|
||||
|
@ -35,6 +35,7 @@ const gFrameData = new WeakMap();
|
||||
* Parses the raw location of this function call to retrieve the actual
|
||||
* function name, source url, host name, line and column.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function parseLocation(location, fallbackLine, fallbackColumn) {
|
||||
// Parse the `location` for the function name, source url, line, column etc.
|
||||
|
||||
@ -182,6 +183,7 @@ function parseLocation(location, fallbackLine, fallbackColumn) {
|
||||
|
||||
return { functionName, fileName, host, port, url, line, column };
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Sets the properties of `isContent` and `category` on a frame.
|
||||
|
@ -312,6 +312,8 @@ pref("devtools.editor.detectindentation", true);
|
||||
pref("devtools.editor.enableCodeFolding", true);
|
||||
pref("devtools.editor.autocomplete", true);
|
||||
|
||||
// The angle of the viewport.
|
||||
pref("devtools.responsive.viewport.angle", 0);
|
||||
// The width of the viewport.
|
||||
pref("devtools.responsive.viewport.width", 320);
|
||||
// The height of the viewport.
|
||||
|
@ -22,7 +22,7 @@ const { post } = require("../utils/message");
|
||||
|
||||
const { addDevice, editDevice, getDevices, removeDevice } = require("devtools/client/shared/devices");
|
||||
const { changeUserAgent, toggleTouchSimulation } = require("./ui");
|
||||
const { changeDevice, changePixelRatio } = require("./viewports");
|
||||
const { changeDevice, changePixelRatio, changeViewportAngle } = require("./viewports");
|
||||
|
||||
const DISPLAYED_DEVICES_PREF = "devtools.responsive.html.displayedDeviceList";
|
||||
|
||||
@ -113,6 +113,7 @@ module.exports = {
|
||||
post(window, {
|
||||
type: "change-device",
|
||||
device: newDevice,
|
||||
viewport,
|
||||
});
|
||||
|
||||
// Update UI if the device is selected.
|
||||
@ -212,13 +213,16 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
const viewport = getState().viewports[0];
|
||||
post(window, {
|
||||
type: "change-device",
|
||||
device,
|
||||
viewport,
|
||||
});
|
||||
|
||||
dispatch(changeDevice(id, device.name, deviceType));
|
||||
dispatch(changePixelRatio(id, device.pixelRatio));
|
||||
dispatch(changeViewportAngle(id, viewport.angle));
|
||||
dispatch(changeUserAgent(device.userAgent));
|
||||
dispatch(toggleTouchSimulation(device.touch));
|
||||
};
|
||||
|
@ -48,6 +48,9 @@ createEnum([
|
||||
// selected from the device pixel ratio dropdown.
|
||||
"CHANGE_PIXEL_RATIO",
|
||||
|
||||
// Change the viewport angle.
|
||||
"CHANGE_VIEWPORT_ANGLE",
|
||||
|
||||
// Edit a device.
|
||||
"EDIT_DEVICE",
|
||||
|
||||
|
@ -12,6 +12,7 @@ const {
|
||||
ADD_VIEWPORT,
|
||||
CHANGE_DEVICE,
|
||||
CHANGE_PIXEL_RATIO,
|
||||
CHANGE_VIEWPORT_ANGLE,
|
||||
REMOVE_DEVICE_ASSOCIATION,
|
||||
RESIZE_VIEWPORT,
|
||||
ROTATE_VIEWPORT,
|
||||
@ -63,6 +64,14 @@ module.exports = {
|
||||
};
|
||||
},
|
||||
|
||||
changeViewportAngle(id, angle) {
|
||||
return {
|
||||
type: CHANGE_VIEWPORT_ANGLE,
|
||||
id,
|
||||
angle,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the viewport's device assocation.
|
||||
*/
|
||||
@ -95,18 +104,6 @@ module.exports = {
|
||||
* Rotate the viewport.
|
||||
*/
|
||||
rotateViewport(id) {
|
||||
// TODO: Add `orientation` and `angle` properties to message data. See Bug 1357774.
|
||||
|
||||
// There is no window object to post to when ran on XPCShell as part of the unit
|
||||
// tests and will immediately throw an error as a result.
|
||||
try {
|
||||
post(window, {
|
||||
type: "viewport-orientation-change",
|
||||
});
|
||||
} catch (e) {
|
||||
console.log("Unable to post message to window");
|
||||
}
|
||||
|
||||
return {
|
||||
type: ROTATE_VIEWPORT,
|
||||
id,
|
||||
|
@ -121,6 +121,11 @@ var global = this;
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.removeProgressListener(WebProgressListener);
|
||||
docShell.deviceSizeIsPageSize = gDeviceSizeWasPageSize;
|
||||
// Restore the original physical screen orientation values before RDM is stopped.
|
||||
// This is necessary since the window document's `setCurrentRDMPaneOrientation`
|
||||
// WebIDL operation can only modify the window's screen orientation values while the
|
||||
// window content is in RDM.
|
||||
restoreScreenOrientation();
|
||||
restoreScrollbars();
|
||||
setDocumentInRDMPane(false);
|
||||
stopOnResize();
|
||||
@ -165,6 +170,10 @@ var global = this;
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function restoreScreenOrientation() {
|
||||
docShell.contentViewer.DOMDocument.setRDMPaneOrientation("landscape-primary", 0);
|
||||
}
|
||||
|
||||
function setDocumentInRDMPane(inRDMPane) {
|
||||
// We don't propegate this property to descendent documents.
|
||||
docShell.contentViewer.DOMDocument.inRDMPane = inRDMPane;
|
||||
@ -199,6 +208,13 @@ var global = this;
|
||||
return;
|
||||
}
|
||||
setDocumentInRDMPane(true);
|
||||
// Notify the Responsive UI manager to set orientation state on a location change.
|
||||
// This is necessary since we want to ensure that the RDM Document's orientation
|
||||
// state persists throughout while RDM is opened.
|
||||
sendAsyncMessage("ResponsiveMode:OnLocationChange", {
|
||||
width: content.innerWidth,
|
||||
height: content.innerHeight,
|
||||
});
|
||||
makeScrollbarsFloating();
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener",
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
@ -38,10 +39,12 @@ const {
|
||||
const {
|
||||
changeDevice,
|
||||
changePixelRatio,
|
||||
changeViewportAngle,
|
||||
removeDeviceAssociation,
|
||||
resizeViewport,
|
||||
rotateViewport,
|
||||
} = require("../actions/viewports");
|
||||
const { getOrientation } = require("../utils/orientation");
|
||||
|
||||
const Types = require("../types");
|
||||
|
||||
@ -67,6 +70,7 @@ class App extends PureComponent {
|
||||
this.onChangePixelRatio = this.onChangePixelRatio.bind(this);
|
||||
this.onChangeTouchSimulation = this.onChangeTouchSimulation.bind(this);
|
||||
this.onChangeUserAgent = this.onChangeUserAgent.bind(this);
|
||||
this.onChangeViewportOrientation = this.onChangeViewportOrientation.bind(this);
|
||||
this.onContentResize = this.onContentResize.bind(this);
|
||||
this.onDeviceListUpdate = this.onDeviceListUpdate.bind(this);
|
||||
this.onEditCustomDevice = this.onEditCustomDevice.bind(this);
|
||||
@ -114,7 +118,12 @@ class App extends PureComponent {
|
||||
window.postMessage({
|
||||
type: "change-device",
|
||||
device,
|
||||
viewport: this.props.viewports[id],
|
||||
}, "*");
|
||||
|
||||
const orientation = getOrientation(device, this.props.viewports[0]);
|
||||
|
||||
this.props.dispatch(changeViewportAngle(0, orientation.angle));
|
||||
this.props.dispatch(changeDevice(id, device.name, deviceType));
|
||||
this.props.dispatch(changePixelRatio(id, device.pixelRatio));
|
||||
this.props.dispatch(changeUserAgent(device.userAgent));
|
||||
@ -154,6 +163,15 @@ class App extends PureComponent {
|
||||
this.props.dispatch(changeUserAgent(userAgent));
|
||||
}
|
||||
|
||||
onChangeViewportOrientation(id, { type, angle }) {
|
||||
window.postMessage({
|
||||
type: "viewport-orientation-change",
|
||||
orientationType: type,
|
||||
angle,
|
||||
}, "*");
|
||||
this.props.dispatch(changeViewportAngle(id, angle));
|
||||
}
|
||||
|
||||
onContentResize({ width, height }) {
|
||||
window.postMessage({
|
||||
type: "content-resize",
|
||||
@ -228,7 +246,44 @@ class App extends PureComponent {
|
||||
}, "*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the rotateViewport action creator. This utilized by the RDM toolbar as
|
||||
* a prop.
|
||||
*
|
||||
* @param {Number} id
|
||||
* The viewport ID.
|
||||
*/
|
||||
onRotateViewport(id) {
|
||||
let currentDevice;
|
||||
const viewport = this.props.viewports[id];
|
||||
|
||||
for (const type of this.props.devices.types) {
|
||||
for (const device of this.props.devices[type]) {
|
||||
if (viewport.device === device.name) {
|
||||
currentDevice = device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no device is selected, then assume the selected device's primary orientation is
|
||||
// opposite of the viewport orientation.
|
||||
if (!currentDevice) {
|
||||
currentDevice = {
|
||||
height: viewport.width,
|
||||
width: viewport.height,
|
||||
};
|
||||
}
|
||||
|
||||
const currentAngle = Services.prefs.getIntPref("devtools.responsive.viewport.angle");
|
||||
// TODO: For Firefox Android, when the device is rotated clock-wise, the angle is
|
||||
// updated to 270 degrees. This is valid since the user-agent determines whether it
|
||||
// will be set to 90 or 270. However, we should update the angle based on the how the
|
||||
// user-agent assigns the angle value.
|
||||
// See https://w3c.github.io/screen-orientation/#dfn-screen-orientation-values-table
|
||||
const angleToRotateTo = currentAngle === 270 ? 0 : 270;
|
||||
const orientation = getOrientation(currentDevice, viewport, angleToRotateTo);
|
||||
|
||||
this.onChangeViewportOrientation(id, orientation);
|
||||
this.props.dispatch(rotateViewport(id));
|
||||
}
|
||||
|
||||
@ -276,6 +331,7 @@ class App extends PureComponent {
|
||||
onChangePixelRatio,
|
||||
onChangeTouchSimulation,
|
||||
onChangeUserAgent,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onDeviceListUpdate,
|
||||
onEditCustomDevice,
|
||||
@ -335,6 +391,7 @@ class App extends PureComponent {
|
||||
screenshot,
|
||||
viewports,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
|
@ -12,6 +12,7 @@ const { PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
const { PORTRAIT_PRIMARY, LANDSCAPE_PRIMARY } = require("../constants");
|
||||
const e10s = require("../utils/e10s");
|
||||
const message = require("../utils/message");
|
||||
const { getTopLevelWindow } = require("../utils/window");
|
||||
@ -27,10 +28,12 @@ class Browser extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
onBrowserMounted: PropTypes.func.isRequired,
|
||||
onChangeViewportOrientation: PropTypes.func.isRequired,
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
onResizeViewport: PropTypes.func.isRequired,
|
||||
swapAfterMount: PropTypes.bool.isRequired,
|
||||
userContextId: PropTypes.number.isRequired,
|
||||
viewportId: PropTypes.number.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
@ -38,6 +41,7 @@ class Browser extends PureComponent {
|
||||
super(props);
|
||||
this.onContentResize = this.onContentResize.bind(this);
|
||||
this.onResizeViewport = this.onResizeViewport.bind(this);
|
||||
this.onSetScreenOrientation = this.onSetScreenOrientation.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,11 +112,20 @@ class Browser extends PureComponent {
|
||||
});
|
||||
}
|
||||
|
||||
onSetScreenOrientation(msg) {
|
||||
const { width, height } = msg.data;
|
||||
const angle = Services.prefs.getIntPref("devtools.responsive.viewport.angle");
|
||||
const type = height >= width ? PORTRAIT_PRIMARY : LANDSCAPE_PRIMARY;
|
||||
|
||||
this.props.onChangeViewportOrientation(this.props.viewportId, { type, angle });
|
||||
}
|
||||
|
||||
async startFrameScript() {
|
||||
const {
|
||||
browser,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onSetScreenOrientation,
|
||||
} = this;
|
||||
const mm = browser.frameLoader.messageManager;
|
||||
|
||||
@ -122,6 +135,7 @@ class Browser extends PureComponent {
|
||||
// resized to match.
|
||||
e10s.on(mm, "OnContentResize", onContentResize);
|
||||
e10s.on(mm, "OnResizeViewport", onResizeViewport);
|
||||
e10s.on(mm, "OnLocationChange", onSetScreenOrientation);
|
||||
|
||||
const ready = e10s.once(mm, "ChildScriptReady");
|
||||
mm.loadFrameScript(FRAME_SCRIPT, true);
|
||||
@ -143,11 +157,13 @@ class Browser extends PureComponent {
|
||||
browser,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onSetScreenOrientation,
|
||||
} = this;
|
||||
const mm = browser.frameLoader.messageManager;
|
||||
|
||||
e10s.off(mm, "OnContentResize", onContentResize);
|
||||
e10s.off(mm, "OnResizeViewport", onResizeViewport);
|
||||
e10s.off(mm, "OnLocationChange", onSetScreenOrientation);
|
||||
await e10s.request(mm, "Stop");
|
||||
message.post(window, "stop-frame-script:done");
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class ResizableViewport extends PureComponent {
|
||||
return {
|
||||
leftAlignmentEnabled: PropTypes.bool.isRequired,
|
||||
onBrowserMounted: PropTypes.func.isRequired,
|
||||
onChangeViewportOrientation: PropTypes.func.isRequired,
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
onRemoveDeviceAssociation: PropTypes.func.isRequired,
|
||||
doResizeViewport: PropTypes.func.isRequired,
|
||||
@ -150,6 +151,7 @@ class ResizableViewport extends PureComponent {
|
||||
swapAfterMount,
|
||||
viewport,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
} = this.props;
|
||||
@ -178,7 +180,9 @@ class ResizableViewport extends PureComponent {
|
||||
Browser({
|
||||
swapAfterMount,
|
||||
userContextId: viewport.userContextId,
|
||||
viewportId: viewport.id,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
})
|
||||
|
@ -18,6 +18,7 @@ class Viewports extends PureComponent {
|
||||
return {
|
||||
leftAlignmentEnabled: PropTypes.bool.isRequired,
|
||||
onBrowserMounted: PropTypes.func.isRequired,
|
||||
onChangeViewportOrientation: PropTypes.func.isRequired,
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
onRemoveDeviceAssociation: PropTypes.func.isRequired,
|
||||
doResizeViewport: PropTypes.func.isRequired,
|
||||
@ -31,6 +32,7 @@ class Viewports extends PureComponent {
|
||||
const {
|
||||
leftAlignmentEnabled,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
@ -71,6 +73,7 @@ class Viewports extends PureComponent {
|
||||
key: viewport.id,
|
||||
leftAlignmentEnabled,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
|
@ -6,3 +6,9 @@
|
||||
|
||||
// The minimum viewport width and height
|
||||
exports.MIN_VIEWPORT_DIMENSION = 50;
|
||||
|
||||
// Orientation types
|
||||
exports.PORTRAIT_PRIMARY = "portrait-primary";
|
||||
exports.PORTRAIT_SECONDARY = "portrait-secondary";
|
||||
exports.LANDSCAPE_PRIMARY = "landscape-primary";
|
||||
exports.LANDSCAPE_SECONDARY = "landscape-secondary";
|
||||
|
@ -8,6 +8,7 @@ const { Ci } = require("chrome");
|
||||
const promise = require("promise");
|
||||
const Services = require("Services");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const { getOrientation } = require("./utils/orientation");
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
|
||||
@ -582,9 +583,12 @@ ResponsiveUI.prototype = {
|
||||
},
|
||||
|
||||
async onChangeDevice(event) {
|
||||
const { userAgent, pixelRatio, touch } = event.data.device;
|
||||
const { device, viewport } = event.data;
|
||||
const { pixelRatio, touch, userAgent } = event.data.device;
|
||||
|
||||
let reloadNeeded = false;
|
||||
await this.updateDPPX(pixelRatio);
|
||||
await this.updateScreenOrientation(getOrientation(device, viewport), true);
|
||||
reloadNeeded |= await this.updateUserAgent(userAgent) &&
|
||||
this.reloadOnChange("userAgent");
|
||||
reloadNeeded |= await this.updateTouchSimulation(touch) &&
|
||||
@ -665,15 +669,8 @@ ResponsiveUI.prototype = {
|
||||
},
|
||||
|
||||
async onRotateViewport(event) {
|
||||
const targetFront = await this.client.mainRoot.getTab();
|
||||
|
||||
// Ensure that simulateScreenOrientationChange is supported.
|
||||
if (await targetFront.actorHasMethod("emulation",
|
||||
"simulateScreenOrientationChange")) {
|
||||
// TODO: From event.data, pass orientation and angle as arguments.
|
||||
// See Bug 1357774.
|
||||
await this.emulationFront.simulateScreenOrientationChange();
|
||||
}
|
||||
const { orientationType: type, angle } = event.data;
|
||||
await this.updateScreenOrientation({ type, angle }, false);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -687,15 +684,21 @@ ResponsiveUI.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
const height =
|
||||
Services.prefs.getIntPref("devtools.responsive.viewport.height", 0);
|
||||
const pixelRatio =
|
||||
Services.prefs.getIntPref("devtools.responsive.viewport.pixelRatio", 0);
|
||||
const touchSimulationEnabled =
|
||||
Services.prefs.getBoolPref("devtools.responsive.touchSimulation.enabled", false);
|
||||
const userAgent = Services.prefs.getCharPref("devtools.responsive.userAgent", "");
|
||||
const width =
|
||||
Services.prefs.getIntPref("devtools.responsive.viewport.width", 0);
|
||||
|
||||
let reloadNeeded = false;
|
||||
const viewportOrientation = this.getInitialViewportOrientation({ width, height });
|
||||
|
||||
await this.updateDPPX(pixelRatio);
|
||||
await this.updateScreenOrientation(viewportOrientation, true);
|
||||
|
||||
if (touchSimulationEnabled) {
|
||||
reloadNeeded |= await this.updateTouchSimulation(touchSimulationEnabled) &&
|
||||
@ -791,6 +794,29 @@ ResponsiveUI.prototype = {
|
||||
return reloadNeeded;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the screen orientation values of the simulated device.
|
||||
*
|
||||
* @param {Object} orientation
|
||||
* The orientation to update the current device screen to.
|
||||
* @param {Boolean} changeDevice
|
||||
* Whether or not the reason for updating the screen orientation is a result
|
||||
* of actually rotating the device via the RDM toolbar or if the user switched to
|
||||
* another device.
|
||||
*/
|
||||
async updateScreenOrientation(orientation, changeDevice = false) {
|
||||
const targetFront = await this.client.mainRoot.getTab();
|
||||
const simulateOrientationChangeSupported =
|
||||
await targetFront.actorHasMethod("emulation", "simulateScreenOrientationChange");
|
||||
|
||||
// Ensure that simulateScreenOrientationChange is supported.
|
||||
if (simulateOrientationChangeSupported) {
|
||||
const { type, angle } = orientation;
|
||||
await this.emulationFront.simulateScreenOrientationChange(type, angle,
|
||||
changeDevice);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for tests. Assumes a single viewport for now.
|
||||
*/
|
||||
@ -820,6 +846,12 @@ ResponsiveUI.prototype = {
|
||||
return this.getViewportBrowser().messageManager;
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for getting the initial viewport orientation.
|
||||
*/
|
||||
getInitialViewportOrientation(viewport) {
|
||||
return getOrientation(viewport, viewport);
|
||||
},
|
||||
};
|
||||
|
||||
EventEmitter.decorate(ResponsiveUI.prototype);
|
||||
|
@ -10,6 +10,7 @@ const {
|
||||
ADD_VIEWPORT,
|
||||
CHANGE_DEVICE,
|
||||
CHANGE_PIXEL_RATIO,
|
||||
CHANGE_VIEWPORT_ANGLE,
|
||||
EDIT_DEVICE,
|
||||
REMOVE_DEVICE_ASSOCIATION,
|
||||
RESIZE_VIEWPORT,
|
||||
@ -19,12 +20,14 @@ const {
|
||||
const VIEWPORT_WIDTH_PREF = "devtools.responsive.viewport.width";
|
||||
const VIEWPORT_HEIGHT_PREF = "devtools.responsive.viewport.height";
|
||||
const VIEWPORT_PIXEL_RATIO_PREF = "devtools.responsive.viewport.pixelRatio";
|
||||
const VIEWPORT_ANGLE_PREF = "devtools.responsive.viewport.angle";
|
||||
|
||||
let nextViewportId = 0;
|
||||
|
||||
const INITIAL_VIEWPORTS = [];
|
||||
const INITIAL_VIEWPORT = {
|
||||
id: nextViewportId++,
|
||||
angle: Services.prefs.getIntPref(VIEWPORT_ANGLE_PREF, 0),
|
||||
device: "",
|
||||
deviceType: "",
|
||||
height: Services.prefs.getIntPref(VIEWPORT_HEIGHT_PREF, 480),
|
||||
@ -79,6 +82,21 @@ const reducers = {
|
||||
});
|
||||
},
|
||||
|
||||
[CHANGE_VIEWPORT_ANGLE](viewports, { id, angle }) {
|
||||
return viewports.map(viewport => {
|
||||
if (viewport.id !== id) {
|
||||
return viewport;
|
||||
}
|
||||
|
||||
Services.prefs.setIntPref(VIEWPORT_ANGLE_PREF, angle);
|
||||
|
||||
return {
|
||||
...viewport,
|
||||
angle,
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
[EDIT_DEVICE](viewports, { viewport, newDevice, deviceType }) {
|
||||
if (!viewport) {
|
||||
return viewports;
|
||||
|
@ -9,13 +9,24 @@ const TEST_URL = "data:text/html;charset=utf-8,";
|
||||
|
||||
addRDMTask(TEST_URL, async function({ ui }) {
|
||||
info("Rotate viewport to trigger 'orientationchange' event.");
|
||||
await pushPref("devtools.responsive.viewport.angle", 0);
|
||||
rotateViewport(ui);
|
||||
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), {},
|
||||
async function() {
|
||||
info("Check the original orientation values before the orientationchange");
|
||||
is(content.screen.orientation.type, "portrait-primary",
|
||||
"Primary orientation type is portrait-primary.");
|
||||
is(content.screen.orientation.angle, 0,
|
||||
"Original angle is set at 0 degrees");
|
||||
|
||||
const orientationChange = new Promise(resolve => {
|
||||
content.window.addEventListener("orientationchange", () => {
|
||||
ok(true, "'orientationchange' event fired");
|
||||
is(content.screen.orientation.type, "landscape-primary",
|
||||
"Orientation state was updated to landscape-primary");
|
||||
is(content.screen.orientation.angle, 270,
|
||||
"Orientation angle was updated to 270 degrees.");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
@ -10,5 +10,6 @@ DevToolsModules(
|
||||
'l10n.js',
|
||||
'message.js',
|
||||
'notification.js',
|
||||
'orientation.js',
|
||||
'window.js',
|
||||
)
|
||||
|
75
devtools/client/responsive.html/utils/orientation.js
Normal file
75
devtools/client/responsive.html/utils/orientation.js
Normal file
@ -0,0 +1,75 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PORTRAIT_PRIMARY, LANDSCAPE_PRIMARY } = require("../constants");
|
||||
|
||||
/**
|
||||
* Helper that gets the screen orientation of the device displayed in the RDM viewport.
|
||||
* This function take in both a device and viewport object and an optional rotated angle.
|
||||
* If a rotated angle is passed, then we calculate what the orientation type of the device
|
||||
* would be in relation to its current orientation. Otherwise, return the current
|
||||
* orientation and angle.
|
||||
*
|
||||
* @param {Object} device
|
||||
* The device whose content is displayed in the viewport. Used to determine the
|
||||
* primary orientation.
|
||||
* @param {Object} viewport
|
||||
* The viewport displaying device content. Used to determine the current
|
||||
* orientation type of the device while in RDM.
|
||||
* @param {Number|null} angleToRotateTo
|
||||
* Optional. The rotated angle specifies the degree to which the device WILL be
|
||||
* turned to. If undefined, then only return the current orientation and angle
|
||||
* of the device.
|
||||
* @return {Object} the orientation of the device.
|
||||
*/
|
||||
function getOrientation(device, viewport, angleToRotateTo = null) {
|
||||
const { width: deviceWidth, height: deviceHeight } = device;
|
||||
const { width: viewportWidth, height: viewportHeight } = viewport;
|
||||
|
||||
// Determine the primary orientation of the device screen.
|
||||
const primaryOrientation = deviceHeight >= deviceWidth ?
|
||||
PORTRAIT_PRIMARY :
|
||||
LANDSCAPE_PRIMARY;
|
||||
|
||||
// Determine the current orientation of the device screen.
|
||||
const currentOrientation = viewportHeight >= viewportWidth ?
|
||||
PORTRAIT_PRIMARY :
|
||||
LANDSCAPE_PRIMARY;
|
||||
|
||||
// Calculate the orientation angle of the device.
|
||||
let angle;
|
||||
|
||||
if (typeof angleToRotateTo === "number") {
|
||||
angle = angleToRotateTo;
|
||||
} else if (currentOrientation !== primaryOrientation) {
|
||||
angle = 270;
|
||||
} else {
|
||||
angle = 0;
|
||||
}
|
||||
|
||||
// Calculate the orientation type of the device.
|
||||
let orientationType = currentOrientation;
|
||||
|
||||
// If the viewport orientation is different from the primary orientation and the angle
|
||||
// to rotate to is 0, then we are moving the device orientation back to its primary
|
||||
// orientation.
|
||||
if (currentOrientation !== primaryOrientation && angleToRotateTo === 0) {
|
||||
orientationType = primaryOrientation;
|
||||
} else if (angleToRotateTo === 90 || angleToRotateTo === 270) {
|
||||
if (currentOrientation.includes("portrait")) {
|
||||
orientationType = LANDSCAPE_PRIMARY;
|
||||
} else if (currentOrientation.includes("landscape")) {
|
||||
orientationType = PORTRAIT_PRIMARY;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: orientationType,
|
||||
angle,
|
||||
};
|
||||
}
|
||||
|
||||
exports.getOrientation = getOrientation;
|
@ -106,6 +106,7 @@ class Frame extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
render() {
|
||||
let frame, isSourceMapped;
|
||||
const {
|
||||
@ -250,6 +251,7 @@ class Frame extends Component {
|
||||
|
||||
return dom.span(attributes, ...elements);
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
}
|
||||
|
||||
module.exports = Frame;
|
||||
|
@ -553,6 +553,7 @@ class Tree extends Component {
|
||||
*
|
||||
* @param {Event} e
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_onKeyDown(e) {
|
||||
if (this.props.focused == null) {
|
||||
return;
|
||||
@ -624,6 +625,7 @@ class Tree extends Component {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
get activeElement() {
|
||||
return this.refs.tree.ownerDocument.activeElement;
|
||||
|
@ -199,6 +199,7 @@ class SplitBox extends Component {
|
||||
|
||||
// Rendering
|
||||
|
||||
/* eslint-disable complexity */
|
||||
render() {
|
||||
const { endPanelControl, splitterSize, vert } = this.state;
|
||||
const { startPanel, endPanel, minSize, maxSize } = this.props;
|
||||
@ -290,6 +291,7 @@ class SplitBox extends Component {
|
||||
)
|
||||
);
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
}
|
||||
|
||||
module.exports = SplitBox;
|
||||
|
@ -270,6 +270,7 @@ define(function(require, exports, module) {
|
||||
|
||||
// Event Handlers
|
||||
|
||||
/* eslint-disable complexity */
|
||||
onKeyDown(event) {
|
||||
if (!SUPPORTED_KEYS.includes(event.key)) {
|
||||
return;
|
||||
@ -352,6 +353,7 @@ define(function(require, exports, module) {
|
||||
this.treeRef.current.focus();
|
||||
event.preventDefault();
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
onClickRow(nodePath, event) {
|
||||
const onClickRow = this.props.onClickRow;
|
||||
|
@ -48,6 +48,7 @@ function naturalSortCaseInsensitive(a, b) {
|
||||
* @param {Boolean} insensitive
|
||||
* Should the search be case insensitive?
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function naturalSort(a, b, insensitive) {
|
||||
// convert all to strings strip whitespace
|
||||
const i = function(s) {
|
||||
@ -104,3 +105,4 @@ function naturalSort(a, b, insensitive) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
@ -654,6 +654,7 @@ OutputParser.prototype = {
|
||||
* The node to which spans containing points are added.
|
||||
* @returns {Node} The container to which spans have been added.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_addPolygonPointNodes: function(coords, container) {
|
||||
const tokenStream = getCSSLexer(coords);
|
||||
let token = tokenStream.nextToken();
|
||||
@ -758,6 +759,7 @@ OutputParser.prototype = {
|
||||
}
|
||||
return container;
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Parse the given circle coordinates and populate the given container appropriately
|
||||
@ -769,6 +771,7 @@ OutputParser.prototype = {
|
||||
* The node to which the definition is added.
|
||||
* @returns {Node} The container to which the definition has been added.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_addCirclePointNodes: function(coords, container) {
|
||||
const tokenStream = getCSSLexer(coords);
|
||||
let token = tokenStream.nextToken();
|
||||
@ -874,6 +877,7 @@ OutputParser.prototype = {
|
||||
}
|
||||
return container;
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Parse the given ellipse coordinates and populate the given container appropriately
|
||||
@ -885,6 +889,7 @@ OutputParser.prototype = {
|
||||
* The node to which the definition is added.
|
||||
* @returns {Node} The container to which the definition has been added.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_addEllipsePointNodes: function(coords, container) {
|
||||
const tokenStream = getCSSLexer(coords);
|
||||
let token = tokenStream.nextToken();
|
||||
@ -1000,6 +1005,7 @@ OutputParser.prototype = {
|
||||
}
|
||||
return container;
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Parse the given inset coordinates and populate the given container appropriately.
|
||||
@ -1010,6 +1016,7 @@ OutputParser.prototype = {
|
||||
* The node to which the definition is added.
|
||||
* @returns {Node} The container to which the definition has been added.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_addInsetPointNodes: function(coords, container) {
|
||||
const insetPoints = ["top", "right", "bottom", "left"];
|
||||
const tokenStream = getCSSLexer(coords);
|
||||
@ -1123,6 +1130,7 @@ OutputParser.prototype = {
|
||||
|
||||
return container;
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Append a angle value to the output
|
||||
|
@ -270,6 +270,7 @@ function isContentScheme(location, i = 0) {
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
function isChromeScheme(location, i = 0) {
|
||||
const firstChar = location.charCodeAt(i);
|
||||
|
||||
@ -315,6 +316,7 @@ function isChromeScheme(location, i = 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
function isWASM(location, i = 0) {
|
||||
return (
|
||||
|
@ -671,6 +671,7 @@ class Telemetry {
|
||||
* The ID of the tool that has been opened.
|
||||
*
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function getChartsFromToolId(id) {
|
||||
if (!id) {
|
||||
return null;
|
||||
@ -750,6 +751,7 @@ function getChartsFromToolId(id) {
|
||||
countScalar: countScalar,
|
||||
};
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Displays the first caller and calling line outside of this file in the
|
||||
|
@ -799,6 +799,7 @@ VariablesView.prototype = {
|
||||
/**
|
||||
* Listener handling a key down event on the view.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_onViewKeyDown: function(e) {
|
||||
const item = this.getFocusedItem();
|
||||
|
||||
@ -889,6 +890,7 @@ VariablesView.prototype = {
|
||||
item._onAddProperty(e);
|
||||
}
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Sets the text displayed in this container when there are no available items.
|
||||
@ -2793,6 +2795,7 @@ Variable.prototype = extend(Scope.prototype, {
|
||||
* and specifies if it's a 'this', '<exception>', '<return>' or '__proto__'
|
||||
* reference.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_setAttributes: function() {
|
||||
const ownerView = this.ownerView;
|
||||
if (ownerView.preventDescriptorModifiers) {
|
||||
@ -2850,6 +2853,7 @@ Variable.prototype = extend(Scope.prototype, {
|
||||
target.setAttribute("pseudo-item", "");
|
||||
}
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Adds the necessary event listeners for this variable.
|
||||
|
@ -506,6 +506,7 @@ class JSTerm extends Component {
|
||||
* @param {Object} response
|
||||
* The message received from the server.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
async _executeResultCallback(response) {
|
||||
if (!this.webConsoleUI) {
|
||||
return null;
|
||||
@ -578,6 +579,7 @@ class JSTerm extends Component {
|
||||
|
||||
return null;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
screenshotNotify(results) {
|
||||
const wrappedResults = results.map(message => ({ message, type: "logMessage" }));
|
||||
|
@ -157,6 +157,7 @@ class Message extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
render() {
|
||||
const {
|
||||
open,
|
||||
@ -346,6 +347,7 @@ class Message extends Component {
|
||||
attachment ? null : dom.br(),
|
||||
);
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
}
|
||||
|
||||
module.exports = Message;
|
||||
|
@ -68,6 +68,7 @@ class ReverseSearchInput extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
onInputKeyDown(event) {
|
||||
const {
|
||||
keyCode,
|
||||
@ -127,6 +128,7 @@ class ReverseSearchInput extends Component {
|
||||
}
|
||||
}
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
renderSearchInformation() {
|
||||
const {
|
||||
|
@ -105,6 +105,7 @@ function cloneState(state) {
|
||||
* @param {UiState} uiState: The ui state.
|
||||
* @returns {MessageState} a new messages state.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function addMessage(newMessage, state, filtersState, prefsState, uiState) {
|
||||
const {
|
||||
messagesById,
|
||||
@ -274,7 +275,9 @@ function addMessage(newMessage, state, filtersState, prefsState, uiState) {
|
||||
|
||||
return state;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/* eslint-disable complexity */
|
||||
function messages(state = MessageState(), action, filtersState, prefsState, uiState) {
|
||||
const {
|
||||
messagesById,
|
||||
@ -541,6 +544,7 @@ function messages(state = MessageState(), action, filtersState, prefsState, uiSt
|
||||
|
||||
return state;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Returns the new current group id given the previous current group and the groupsById
|
||||
@ -784,6 +788,7 @@ function getToplevelMessageCount(state) {
|
||||
* - visible {Boolean}: true if the message should be visible
|
||||
* - cause {String}: if visible is false, what causes the message to be hidden.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function getMessageVisibility(message, {
|
||||
messagesState,
|
||||
filtersState,
|
||||
@ -954,6 +959,7 @@ function getMessageVisibility(message, {
|
||||
visible: true,
|
||||
};
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
function isUnfilterable(message) {
|
||||
return [
|
||||
|
@ -75,6 +75,7 @@ global.ChromeUtils = {
|
||||
|
||||
// Point to vendored-in files and mocks when needed.
|
||||
const requireHacker = require("require-hacker");
|
||||
/* eslint-disable complexity */
|
||||
requireHacker.global_hook("default", (path, module) => {
|
||||
switch (path) {
|
||||
// For Enzyme
|
||||
@ -138,6 +139,7 @@ requireHacker.global_hook("default", (path, module) => {
|
||||
|
||||
return undefined;
|
||||
});
|
||||
/* eslint-enable complexity */
|
||||
|
||||
// Configure enzyme with React 16 adapter. This needs to be done after we set the
|
||||
// requireHack hook so `require()` calls in Enzyme are handled as well.
|
||||
|
@ -67,6 +67,7 @@ function transformPacket(packet) {
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
function transformConsoleAPICallPacket(packet) {
|
||||
const { message } = packet;
|
||||
|
||||
@ -198,6 +199,7 @@ function transformConsoleAPICallPacket(packet) {
|
||||
chromeContext: message.chromeContext,
|
||||
});
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
function transformNavigationMessagePacket(packet) {
|
||||
const { url } = packet;
|
||||
|
@ -846,7 +846,7 @@ var UI = {
|
||||
return this.toolboxPromise;
|
||||
}
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
const iframe = document.createXULElement("iframe");
|
||||
iframe.id = "toolbox";
|
||||
|
||||
// Compute a uid on the iframe in order to identify toolbox iframe
|
||||
|
@ -505,6 +505,7 @@ const AccessibleWalkerActor = ActorClassWithSpec(accessibleWalkerSpec, {
|
||||
* @param {Ci.nsIAccessibleEvent} subject
|
||||
* accessible event object.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
observe(subject) {
|
||||
const event = subject.QueryInterface(Ci.nsIAccessibleEvent);
|
||||
const rawAccessible = event.accessible;
|
||||
@ -600,6 +601,7 @@ const AccessibleWalkerActor = ActorClassWithSpec(accessibleWalkerSpec, {
|
||||
break;
|
||||
}
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Ensure that nothing interferes with the audit for an accessible object
|
||||
|
@ -463,6 +463,7 @@ var WebExtensionInspectedWindowActor = protocol.ActorClassWithSpec(
|
||||
* it is called over the remote debugging protocol the target window is always
|
||||
* `targetActor.window`.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
eval(callerInfo, expression, options, customTargetWindow) {
|
||||
const window = customTargetWindow || this.window;
|
||||
options = options || {};
|
||||
@ -639,6 +640,7 @@ var WebExtensionInspectedWindowActor = protocol.ActorClassWithSpec(
|
||||
|
||||
return {value: evalResult};
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -76,6 +76,10 @@ const EmulationActor = protocol.ActorClassWithSpec(emulationSpec, {
|
||||
return this._touchSimulator;
|
||||
},
|
||||
|
||||
get win() {
|
||||
return this.docShell.chromeEventHandler.ownerGlobal;
|
||||
},
|
||||
|
||||
onWillNavigate({ isTopLevel }) {
|
||||
// Make sure that print simulation is stopped before navigating to another page. We
|
||||
// need to do this since the browser will cache the last state of the page in its
|
||||
@ -352,17 +356,38 @@ const EmulationActor = protocol.ActorClassWithSpec(emulationSpec, {
|
||||
this.targetActor.docShell.contentViewer.stopEmulatingMedium();
|
||||
},
|
||||
|
||||
setScreenOrientation(type, angle) {
|
||||
if (this.win.screen.orientation.angle !== angle ||
|
||||
this.win.screen.orientation.type !== type) {
|
||||
this.win.document.setRDMPaneOrientation(type, angle);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates the "orientationchange" event when device screen is rotated.
|
||||
*
|
||||
* TODO: Update `window.screen.orientation` and `window.screen.angle` here.
|
||||
* See Bug 1357774.
|
||||
* @param {String} type
|
||||
* The orientation type of the rotated device.
|
||||
* @param {Number} angle
|
||||
* The rotated angle of the device.
|
||||
* @param {Boolean} deviceChange
|
||||
* Whether or not screen orientation change is a result of changing the device
|
||||
* or rotating the current device. If the latter, then dispatch the
|
||||
* "orientationchange" event on the content window.
|
||||
*/
|
||||
simulateScreenOrientationChange() {
|
||||
const win = this.docShell.chromeEventHandler.ownerGlobal;
|
||||
const { CustomEvent } = win;
|
||||
async simulateScreenOrientationChange(type, angle, deviceChange) {
|
||||
// Don't dispatch the "orientationchange" event if orientation change is a result
|
||||
// of switching to a new device.
|
||||
if (deviceChange) {
|
||||
this.setScreenOrientation(type, angle);
|
||||
return;
|
||||
}
|
||||
|
||||
const { CustomEvent } = this.win;
|
||||
const orientationChangeEvent = new CustomEvent("orientationchange");
|
||||
win.dispatchEvent(orientationChangeEvent);
|
||||
|
||||
this.setScreenOrientation(type, angle);
|
||||
this.win.dispatchEvent(orientationChangeEvent);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -88,6 +88,7 @@ TouchSimulator.prototype = {
|
||||
this._isPicking = state;
|
||||
},
|
||||
|
||||
/* eslint-disable complexity */
|
||||
handleEvent(evt) {
|
||||
// Bail out if devtools is in pick mode in the same tab.
|
||||
if (this._isPicking) {
|
||||
@ -242,6 +243,7 @@ TouchSimulator.prototype = {
|
||||
evt.stopImmediatePropagation();
|
||||
}
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
fireMouseEvent(type, evt) {
|
||||
const content = this.getContent(evt.target);
|
||||
|
@ -550,6 +550,7 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
||||
/**
|
||||
* Clear the whole alignment container along the main axis for each flex item.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
renderJustifyContent() {
|
||||
if (!this.flexData || !this.currentQuads.content || !this.currentQuads.content[0]) {
|
||||
return;
|
||||
@ -630,6 +631,7 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
||||
|
||||
this.ctx.restore();
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Set up the canvas with the given options prior to drawing.
|
||||
@ -824,6 +826,7 @@ function getRectFromFlexItemValues(item, container) {
|
||||
* The new Flex data object.
|
||||
* @return {Boolean} true if the flex data has changed and false otherwise.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function compareFlexData(oldFlexData, newFlexData) {
|
||||
if (!oldFlexData || !newFlexData) {
|
||||
return true;
|
||||
@ -884,5 +887,6 @@ function compareFlexData(oldFlexData, newFlexData) {
|
||||
|
||||
return false;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
exports.FlexboxHighlighter = FlexboxHighlighter;
|
||||
|
@ -478,6 +478,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
||||
this.viewport = { left, right, top, bottom, padding };
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
handleEvent(event, id) {
|
||||
// No event handling if the highlighter is hidden
|
||||
if (this.areShapesHidden()) {
|
||||
@ -577,6 +578,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Handle a mouse click in transform mode.
|
||||
@ -1704,6 +1706,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
||||
* @returns {String} "top", "left", "right", or "bottom" if any of those edges were
|
||||
* clicked. "" if none were clicked.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
getInsetPointAt(pageX, pageY) {
|
||||
const { top, left, right, bottom } = this.coordinates;
|
||||
const zoom = getCurrentZoom(this.win);
|
||||
@ -1741,6 +1744,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
||||
|
||||
return "";
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Parses the CSS definition given and returns the shape type associated
|
||||
|
@ -385,6 +385,7 @@ class DOMEventCollector extends MainEventCollector {
|
||||
* Get or detect jQuery events.
|
||||
*/
|
||||
class JQueryEventCollector extends MainEventCollector {
|
||||
/* eslint-disable complexity */
|
||||
getListeners(node, {checkOnly} = {}) {
|
||||
const jQuery = this.getJQuery(node);
|
||||
const handlers = [];
|
||||
@ -471,12 +472,14 @@ class JQueryEventCollector extends MainEventCollector {
|
||||
}
|
||||
return handlers;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or detect jQuery live events.
|
||||
*/
|
||||
class JQueryLiveEventCollector extends MainEventCollector {
|
||||
/* eslint-disable complexity */
|
||||
getListeners(node, {checkOnly} = {}) {
|
||||
const jQuery = this.getJQuery(node);
|
||||
const handlers = [];
|
||||
@ -569,6 +572,7 @@ class JQueryLiveEventCollector extends MainEventCollector {
|
||||
}
|
||||
return handlers;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
normalizeListener(handlerDO) {
|
||||
function isFunctionInProxy(funcDO) {
|
||||
@ -866,6 +870,7 @@ class EventCollector {
|
||||
* native: false
|
||||
* }
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
processHandlerForEvent(listenerArray, listener, dbg) {
|
||||
let globalDO;
|
||||
|
||||
@ -1013,6 +1018,7 @@ class EventCollector {
|
||||
}
|
||||
}
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
}
|
||||
|
||||
exports.EventCollector = EventCollector;
|
||||
|
@ -728,6 +728,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
||||
* hasLast: true if the last child of the node is included in the list.
|
||||
* nodes: Array of DOMNodes.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_getChildren: function(node, options = {}) {
|
||||
if (isNodeDead(node)) {
|
||||
return { hasFirst: true, hasLast: true, nodes: [] };
|
||||
@ -901,6 +902,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
||||
|
||||
return { hasFirst, hasLast, nodes };
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
getNativeAnonymousChildren: function(rawNode) {
|
||||
// Get an anonymous walker and start on the first child.
|
||||
@ -1093,6 +1095,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
||||
* @param string selectorState
|
||||
* One of "pseudo", "id", "tag", "class", "null"
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
getSuggestionsForQuery: function(query, completing, selectorState) {
|
||||
const sugs = {
|
||||
classes: new Map(),
|
||||
@ -1235,6 +1238,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
||||
suggestions: result,
|
||||
};
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Add a pseudo-class lock to a node.
|
||||
|
@ -329,6 +329,7 @@ const proto = {
|
||||
* An object that maps property names to safe getter descriptors as
|
||||
* defined by the remote debugging protocol.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
_findSafeGetterValues: function(ownProperties, limit = 0) {
|
||||
const safeGetterValues = Object.create(null);
|
||||
let obj = this.obj;
|
||||
@ -432,6 +433,7 @@ const proto = {
|
||||
|
||||
return safeGetterValues;
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Find the safe getters for a given Debugger.Object. Safe getters are native
|
||||
|
@ -355,6 +355,7 @@ function wrappedPrimitivePreviewer(className, classObj, objectActor, grip, rawOb
|
||||
return true;
|
||||
}
|
||||
|
||||
/* eslint-disable complexity */
|
||||
function GenericObject(objectActor, grip, rawObj, specialStringBehavior = false) {
|
||||
const {obj, hooks} = objectActor;
|
||||
if (grip.preview || grip.displayString || hooks.getGripDepth() > 1) {
|
||||
@ -442,6 +443,7 @@ function GenericObject(objectActor, grip, rawObj, specialStringBehavior = false)
|
||||
|
||||
return true;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
// Preview functions that do not rely on the object class.
|
||||
previewers.Object = [
|
||||
@ -672,6 +674,7 @@ previewers.Object = [
|
||||
return true;
|
||||
},
|
||||
|
||||
/* eslint-disable complexity */
|
||||
function DOMEvent({obj, hooks}, grip, rawObj) {
|
||||
if (isWorker || !rawObj || !Event.isInstance(rawObj)) {
|
||||
return false;
|
||||
@ -758,6 +761,7 @@ previewers.Object = [
|
||||
|
||||
return true;
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
function DOMException({obj, hooks}, grip, rawObj) {
|
||||
if (isWorker || !rawObj || obj.class !== "DOMException") {
|
||||
|
@ -835,6 +835,7 @@ var cookieHelpers = {
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
editCookie(data) {
|
||||
let {field, oldValue, newValue} = data;
|
||||
const origName = field === "name" ? oldValue : data.items.name;
|
||||
@ -920,6 +921,7 @@ var cookieHelpers = {
|
||||
cookie.sameSite
|
||||
);
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
_removeCookies(host, opts = {}) {
|
||||
// We use a uniqueId to emulate compound keys for cookies. We need to
|
||||
@ -2775,6 +2777,7 @@ const StorageActor = protocol.ActorClassWithSpec(specs.storageSpec, {
|
||||
* Pass an empty array if the host itself was affected: either completely
|
||||
* removed or cleared.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
update(action, storeType, data) {
|
||||
if (action == "cleared") {
|
||||
this.emit("stores-cleared", { [storeType]: data });
|
||||
@ -2839,6 +2842,7 @@ const StorageActor = protocol.ActorClassWithSpec(specs.storageSpec, {
|
||||
|
||||
return null;
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* This method removes data from the this.boundUpdate object in the same
|
||||
|
@ -534,6 +534,7 @@ WebConsoleActor.prototype =
|
||||
* @return object
|
||||
* The response object which holds the startedListeners array.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
startListeners: async function(request) {
|
||||
const startedListeners = [];
|
||||
const window = !this.parentActor.isRootActor ? this.window : null;
|
||||
@ -692,6 +693,7 @@ WebConsoleActor.prototype =
|
||||
traits: this.traits,
|
||||
};
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Handler for the "stopListeners" request.
|
||||
@ -985,6 +987,7 @@ WebConsoleActor.prototype =
|
||||
* @return object
|
||||
* The evaluation response packet.
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
evaluateJS: function(request) {
|
||||
const input = request.text;
|
||||
const timestamp = Date.now();
|
||||
@ -1154,6 +1157,7 @@ WebConsoleActor.prototype =
|
||||
notes: errorNotes,
|
||||
};
|
||||
},
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* The Autocomplete request handler.
|
||||
|
@ -10,7 +10,7 @@
|
||||
// this file violates some naming conventions and consequently locally
|
||||
// disables some eslint rules.
|
||||
|
||||
/* eslint-disable camelcase, mozilla/no-aArgs, no-else-return */
|
||||
/* eslint-disable camelcase, mozilla/no-aArgs, no-else-return, complexity */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
@ -539,6 +539,7 @@ function parseNamedDeclarations(isCssPropertyKnown, inputString,
|
||||
* @return {Array} an array of objects with the following signature:
|
||||
* [{ "value": string, "type": integer }, ...]
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function parsePseudoClassesAndAttributes(value) {
|
||||
if (!value) {
|
||||
throw new Error("empty input string");
|
||||
@ -624,6 +625,7 @@ function parsePseudoClassesAndAttributes(value) {
|
||||
|
||||
return result;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Expects a single CSS value to be passed as the input and parses the value
|
||||
|
@ -258,6 +258,7 @@ class WalkerFront extends FrontClassWithSpec(walkerSpec) {
|
||||
* Get any unprocessed mutation records and process them.
|
||||
*/
|
||||
getMutations(options = {}) {
|
||||
/* eslint-disable complexity */
|
||||
return super.getMutations(options).then(mutations => {
|
||||
const emitMutations = [];
|
||||
for (const change of mutations) {
|
||||
@ -401,6 +402,7 @@ class WalkerFront extends FrontClassWithSpec(walkerSpec) {
|
||||
|
||||
this.emit("mutations", emitMutations);
|
||||
});
|
||||
/* eslint-enable complexity */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,6 +180,7 @@ function getLineCountInComments(text) {
|
||||
* @param string text The CSS source to prettify.
|
||||
* @return string Prettified CSS source
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function prettifyCSS(text, ruleCount) {
|
||||
if (prettifyCSS.LINE_SEPARATOR == null) {
|
||||
const os = Services.appinfo.OS;
|
||||
@ -405,6 +406,7 @@ function prettifyCSS(text, ruleCount) {
|
||||
|
||||
return result;
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
exports.prettifyCSS = prettifyCSS;
|
||||
|
||||
|
@ -151,7 +151,11 @@ const emulationSpec = generateActorSpec({
|
||||
},
|
||||
|
||||
simulateScreenOrientationChange: {
|
||||
request: {},
|
||||
request: {
|
||||
orientation: Arg(0, "string"),
|
||||
angle: Arg(1, "number"),
|
||||
deviceChange: Arg(2, "boolean"),
|
||||
},
|
||||
response: {},
|
||||
},
|
||||
},
|
||||
|
@ -60,6 +60,7 @@ function hasArrayIndex(str) {
|
||||
* element access (e.g. `x["match`).
|
||||
* }
|
||||
*/
|
||||
/* eslint-disable complexity */
|
||||
function analyzeInputString(str) {
|
||||
const bodyStack = [];
|
||||
|
||||
@ -195,6 +196,7 @@ function analyzeInputString(str) {
|
||||
|
||||
return buildReturnObject();
|
||||
}
|
||||
/* eslint-enable complexity */
|
||||
|
||||
/**
|
||||
* Provides a list of properties, that are possible matches based on the passed
|
||||
|
@ -45,7 +45,7 @@ JSObject* CSSPseudoElement::WrapObject(JSContext* aCx,
|
||||
return CSSPseudoElement_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void CSSPseudoElement::GetAnimations(const AnimationFilter& filter,
|
||||
void CSSPseudoElement::GetAnimations(const GetAnimationsOptions& aOptions,
|
||||
nsTArray<RefPtr<Animation>>& aRetVal) {
|
||||
Document* doc = mOriginatingElement->GetComposedDoc();
|
||||
if (doc) {
|
||||
|
@ -54,7 +54,7 @@ class CSSPseudoElement final : public nsWrapperCache {
|
||||
return retVal.forget();
|
||||
}
|
||||
|
||||
void GetAnimations(const AnimationFilter& filter,
|
||||
void GetAnimations(const GetAnimationsOptions& aOptions,
|
||||
nsTArray<RefPtr<Animation>>& aRetVal);
|
||||
already_AddRefed<Animation> Animate(
|
||||
JSContext* aContext, JS::Handle<JSObject*> aKeyframes,
|
||||
|
@ -1238,8 +1238,8 @@ Document::Document(const char* aContentType)
|
||||
mMaybeServiceWorkerControlled(false),
|
||||
mAllowZoom(false),
|
||||
mValidScaleFloat(false),
|
||||
mValidMinScale(false),
|
||||
mValidMaxScale(false),
|
||||
mScaleStrEmpty(false),
|
||||
mWidthStrEmpty(false),
|
||||
mParserAborted(false),
|
||||
mReportedUseCounters(false),
|
||||
@ -3443,9 +3443,9 @@ void Document::GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations) {
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
AnimationFilter filter;
|
||||
filter.mSubtree = true;
|
||||
root->GetAnimations(filter, aAnimations);
|
||||
GetAnimationsOptions options;
|
||||
options.mSubtree = true;
|
||||
root->GetAnimations(options, aAnimations);
|
||||
}
|
||||
|
||||
SVGSVGElement* Document::GetSVGRootElement() const {
|
||||
@ -5523,6 +5523,17 @@ already_AddRefed<Element> Document::CreateElement(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Temporary check until XULDocument has been removed.
|
||||
if (IsXULDocument()) {
|
||||
#if DEBUG
|
||||
xpc_DumpJSStack(true, true, false);
|
||||
#endif
|
||||
MOZ_DIAGNOSTIC_ASSERT(false,
|
||||
"CreateElement() not allowed in XUL document.");
|
||||
rv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool needsLowercase = IsHTMLDocument() && !IsLowercaseASCII(aTagName);
|
||||
nsAutoString lcTagName;
|
||||
if (needsLowercase) {
|
||||
@ -6832,9 +6843,73 @@ nsINode* Document::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv) {
|
||||
|
||||
bool Document::UseWidthDeviceWidthFallbackViewport() const { return false; }
|
||||
|
||||
void Document::ParseWidthAndHeightInMetaViewport(
|
||||
const nsAString& aWidthString, const nsAString& aHeightString,
|
||||
const nsAString& aScaleString) {
|
||||
static Maybe<LayoutDeviceToScreenScale> ParseScaleString(
|
||||
const nsString& aScaleString) {
|
||||
// https://drafts.csswg.org/css-device-adapt/#min-scale-max-scale
|
||||
if (aScaleString.EqualsLiteral("device-width") ||
|
||||
aScaleString.EqualsLiteral("device-height")) {
|
||||
return Some(LayoutDeviceToScreenScale(10.0f));
|
||||
} else if (aScaleString.EqualsLiteral("yes")) {
|
||||
return Some(LayoutDeviceToScreenScale(1.0f));
|
||||
} else if (aScaleString.EqualsLiteral("no")) {
|
||||
return Some(LayoutDeviceToScreenScale(kViewportMinScale));
|
||||
} else if (aScaleString.IsEmpty()) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
nsresult scaleErrorCode;
|
||||
float scale = aScaleString.ToFloat(&scaleErrorCode);
|
||||
if (NS_FAILED(scaleErrorCode)) {
|
||||
return Some(LayoutDeviceToScreenScale(kViewportMinScale));
|
||||
}
|
||||
|
||||
if (scale < 0) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(clamped(LayoutDeviceToScreenScale(scale), kViewportMinScale,
|
||||
kViewportMaxScale));
|
||||
}
|
||||
|
||||
Maybe<LayoutDeviceToScreenScale> Document::ParseScaleInHeader(
|
||||
nsAtom* aHeaderField) {
|
||||
MOZ_ASSERT(aHeaderField == nsGkAtoms::viewport_initial_scale ||
|
||||
aHeaderField == nsGkAtoms::viewport_maximum_scale ||
|
||||
aHeaderField == nsGkAtoms::viewport_minimum_scale);
|
||||
|
||||
nsAutoString scaleStr;
|
||||
GetHeaderData(aHeaderField, scaleStr);
|
||||
|
||||
return ParseScaleString(scaleStr);
|
||||
}
|
||||
|
||||
void Document::ParseScalesInMetaViewport() {
|
||||
Maybe<LayoutDeviceToScreenScale> scale;
|
||||
|
||||
scale = ParseScaleInHeader(nsGkAtoms::viewport_initial_scale);
|
||||
mScaleFloat = scale.valueOr(LayoutDeviceToScreenScale(0.0f));
|
||||
mValidScaleFloat = scale.isSome();
|
||||
|
||||
scale = ParseScaleInHeader(nsGkAtoms::viewport_maximum_scale);
|
||||
// Chrome uses '5' for the fallback value of maximum-scale, we might
|
||||
// consider matching it in future.
|
||||
// https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/html/html_meta_element.cc?l=452&rcl=65ca4278b42d269ca738fc93ef7ae04a032afeb0
|
||||
mScaleMaxFloat = scale.valueOr(kViewportMaxScale);
|
||||
mValidMaxScale = scale.isSome();
|
||||
|
||||
scale = ParseScaleInHeader(nsGkAtoms::viewport_minimum_scale);
|
||||
mScaleMinFloat = scale.valueOr(kViewportMinScale);
|
||||
mValidMinScale = scale.isSome();
|
||||
|
||||
// Resolve min-zoom and max-zoom values.
|
||||
// https://drafts.csswg.org/css-device-adapt/#constraining-min-max-zoom
|
||||
if (mValidMaxScale && mValidMinScale) {
|
||||
mScaleMaxFloat = std::max(mScaleMinFloat, mScaleMaxFloat);
|
||||
}
|
||||
}
|
||||
|
||||
void Document::ParseWidthAndHeightInMetaViewport(const nsAString& aWidthString,
|
||||
const nsAString& aHeightString,
|
||||
bool aHasValidScale) {
|
||||
// The width and height properties
|
||||
// https://drafts.csswg.org/css-device-adapt/#width-and-height-properties
|
||||
//
|
||||
@ -6865,8 +6940,7 @@ void Document::ParseWidthAndHeightInMetaViewport(
|
||||
mMaxWidth = nsViewportInfo::Auto;
|
||||
}
|
||||
}
|
||||
// FIXME: Check the scale is not 'auto' once we support auto value for it.
|
||||
} else if (!aScaleString.IsEmpty()) {
|
||||
} else if (aHasValidScale) {
|
||||
if (aHeightString.IsEmpty()) {
|
||||
mMinWidth = nsViewportInfo::ExtendToZoom;
|
||||
mMaxWidth = nsViewportInfo::ExtendToZoom;
|
||||
@ -6974,48 +7048,8 @@ nsViewportInfo Document::GetViewportInfo(const ScreenIntSize& aDisplaySize) {
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString minScaleStr;
|
||||
GetHeaderData(nsGkAtoms::viewport_minimum_scale, minScaleStr);
|
||||
|
||||
nsresult scaleMinErrorCode;
|
||||
mScaleMinFloat =
|
||||
LayoutDeviceToScreenScale(minScaleStr.ToFloat(&scaleMinErrorCode));
|
||||
|
||||
if (NS_FAILED(scaleMinErrorCode)) {
|
||||
mScaleMinFloat = kViewportMinScale;
|
||||
}
|
||||
|
||||
mScaleMinFloat = mozilla::clamped(mScaleMinFloat, kViewportMinScale,
|
||||
kViewportMaxScale);
|
||||
|
||||
nsAutoString maxScaleStr;
|
||||
GetHeaderData(nsGkAtoms::viewport_maximum_scale, maxScaleStr);
|
||||
|
||||
// We define a special error code variable for the scale and max scale,
|
||||
// because they are used later (see the width calculations).
|
||||
nsresult scaleMaxErrorCode;
|
||||
mScaleMaxFloat =
|
||||
LayoutDeviceToScreenScale(maxScaleStr.ToFloat(&scaleMaxErrorCode));
|
||||
|
||||
if (NS_FAILED(scaleMaxErrorCode)) {
|
||||
mScaleMaxFloat = kViewportMaxScale;
|
||||
}
|
||||
|
||||
// Resolve min-zoom and max-zoom values.
|
||||
// https://drafts.csswg.org/css-device-adapt/#constraining-min-max-zoom
|
||||
if (NS_SUCCEEDED(scaleMaxErrorCode) && NS_SUCCEEDED(scaleMinErrorCode)) {
|
||||
mScaleMaxFloat = std::max(mScaleMinFloat, mScaleMaxFloat);
|
||||
}
|
||||
|
||||
mScaleMaxFloat = mozilla::clamped(mScaleMaxFloat, kViewportMinScale,
|
||||
kViewportMaxScale);
|
||||
|
||||
nsAutoString scaleStr;
|
||||
GetHeaderData(nsGkAtoms::viewport_initial_scale, scaleStr);
|
||||
|
||||
nsresult scaleErrorCode;
|
||||
mScaleFloat =
|
||||
LayoutDeviceToScreenScale(scaleStr.ToFloat(&scaleErrorCode));
|
||||
// Parse initial-scale, minimum-scale and maximum-scale.
|
||||
ParseScalesInMetaViewport();
|
||||
|
||||
nsAutoString widthStr, heightStr;
|
||||
|
||||
@ -7024,7 +7058,7 @@ nsViewportInfo Document::GetViewportInfo(const ScreenIntSize& aDisplaySize) {
|
||||
|
||||
// Parse width and height properties
|
||||
// This function sets m{Min,Max}{Width,Height}.
|
||||
ParseWidthAndHeightInMetaViewport(widthStr, heightStr, scaleStr);
|
||||
ParseWidthAndHeightInMetaViewport(widthStr, heightStr, mValidScaleFloat);
|
||||
|
||||
mAllowZoom = true;
|
||||
nsAutoString userScalable;
|
||||
@ -7036,11 +7070,7 @@ nsViewportInfo Document::GetViewportInfo(const ScreenIntSize& aDisplaySize) {
|
||||
mAllowZoom = false;
|
||||
}
|
||||
|
||||
mScaleStrEmpty = scaleStr.IsEmpty();
|
||||
mWidthStrEmpty = widthStr.IsEmpty();
|
||||
mValidScaleFloat = !scaleStr.IsEmpty() && NS_SUCCEEDED(scaleErrorCode);
|
||||
mValidMaxScale =
|
||||
!maxScaleStr.IsEmpty() && NS_SUCCEEDED(scaleMaxErrorCode);
|
||||
|
||||
mViewportType = viewportIsEmpty ? Empty : Specified;
|
||||
MOZ_FALLTHROUGH;
|
||||
@ -7224,7 +7254,7 @@ nsViewportInfo Document::GetViewportInfo(const ScreenIntSize& aDisplaySize) {
|
||||
|
||||
// Also recalculate the default zoom, if it wasn't specified in the
|
||||
// metadata, and the width is specified.
|
||||
if (mScaleStrEmpty && !mWidthStrEmpty) {
|
||||
if (!mValidScaleFloat && !mWidthStrEmpty) {
|
||||
CSSToScreenScale bestFitScale(float(aDisplaySize.width) / size.width);
|
||||
scaleFloat = (scaleFloat > bestFitScale) ? scaleFloat : bestFitScale;
|
||||
}
|
||||
|
@ -3687,7 +3687,15 @@ class Document : public nsINode,
|
||||
|
||||
void ParseWidthAndHeightInMetaViewport(const nsAString& aWidthString,
|
||||
const nsAString& aHeightString,
|
||||
const nsAString& aScaleString);
|
||||
bool aIsAutoScale);
|
||||
|
||||
// Parse scale values in viewport meta tag for a given |aHeaderField| which
|
||||
// represents the scale property and returns the scale value if it's valid.
|
||||
Maybe<LayoutDeviceToScreenScale> ParseScaleInHeader(nsAtom* aHeaderField);
|
||||
|
||||
// Parse scale values in viewport meta tag and set the values in
|
||||
// mScaleMinFloat, mScaleMaxFloat and mScaleFloat respectively.
|
||||
void ParseScalesInMetaViewport();
|
||||
|
||||
FlashClassification DocumentFlashClassificationInternal();
|
||||
|
||||
@ -4321,8 +4329,8 @@ class Document : public nsINode,
|
||||
// have to recalculate it each time.
|
||||
bool mAllowZoom : 1;
|
||||
bool mValidScaleFloat : 1;
|
||||
bool mValidMinScale : 1;
|
||||
bool mValidMaxScale : 1;
|
||||
bool mScaleStrEmpty : 1;
|
||||
bool mWidthStrEmpty : 1;
|
||||
|
||||
// Parser aborted. True if the parser of this document was forcibly
|
||||
|
@ -3474,7 +3474,7 @@ already_AddRefed<Animation> Element::Animate(
|
||||
return animation.forget();
|
||||
}
|
||||
|
||||
void Element::GetAnimations(const AnimationFilter& filter,
|
||||
void Element::GetAnimations(const GetAnimationsOptions& aOptions,
|
||||
nsTArray<RefPtr<Animation>>& aAnimations) {
|
||||
Document* doc = GetComposedDoc();
|
||||
if (doc) {
|
||||
@ -3505,7 +3505,7 @@ void Element::GetAnimations(const AnimationFilter& filter,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!filter.mSubtree || pseudoType == PseudoStyleType::before ||
|
||||
if (!aOptions.mSubtree || pseudoType == PseudoStyleType::before ||
|
||||
pseudoType == PseudoStyleType::after ||
|
||||
pseudoType == PseudoStyleType::marker) {
|
||||
GetAnimationsUnsorted(elem, pseudoType, aAnimations);
|
||||
|
@ -84,7 +84,7 @@ namespace css {
|
||||
struct URLValue;
|
||||
} // namespace css
|
||||
namespace dom {
|
||||
struct AnimationFilter;
|
||||
struct GetAnimationsOptions;
|
||||
struct ScrollIntoViewOptions;
|
||||
struct ScrollToOptions;
|
||||
class DOMIntersectionObserver;
|
||||
@ -1339,7 +1339,7 @@ class Element : public FragmentOrElement {
|
||||
// Note: GetAnimations will flush style while GetAnimationsUnsorted won't.
|
||||
// Callers must keep this element alive because flushing style may destroy
|
||||
// this element.
|
||||
void GetAnimations(const AnimationFilter& filter,
|
||||
void GetAnimations(const GetAnimationsOptions& aOptions,
|
||||
nsTArray<RefPtr<Animation>>& aAnimations);
|
||||
static void GetAnimationsUnsorted(Element* aElement,
|
||||
PseudoStyleType aPseudoType,
|
||||
|
@ -64,12 +64,13 @@ function declTest(name, cfg) {
|
||||
|
||||
// Run the provided test
|
||||
info("browser ready");
|
||||
await Promise.resolve(test(browser, win));
|
||||
|
||||
// Clean up after we're done.
|
||||
ChromeUtils.unregisterWindowActor("Test");
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
|
||||
info("Exiting test: " + name);
|
||||
try {
|
||||
await Promise.resolve(test(browser, win));
|
||||
} finally {
|
||||
// Clean up after we're done.
|
||||
ChromeUtils.unregisterWindowActor("Test");
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
info("Exiting test: " + name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -69,18 +69,21 @@ static bool IsSameOriginWithAllParentDocs(nsINode* aDoc) {
|
||||
already_AddRefed<Promise> MediaDevices::GetUserMedia(
|
||||
const MediaStreamConstraints& aConstraints, CallerType aCallerType,
|
||||
ErrorResult& aRv) {
|
||||
if (Document* doc = GetOwner()->GetExtantDoc()) {
|
||||
if (!GetOwner()->IsSecureContext()) {
|
||||
doc->SetDocumentAndPageUseCounter(eUseCounter_custom_GetUserMediaInsec);
|
||||
}
|
||||
if (!IsSameOriginWithAllParentDocs(doc)) {
|
||||
doc->SetDocumentAndPageUseCounter(eUseCounter_custom_GetUserMediaXOrigin);
|
||||
}
|
||||
Document* topDoc = doc->GetTopLevelContentDocument();
|
||||
IgnoredErrorResult ignored;
|
||||
if (topDoc && !topDoc->HasFocus(ignored)) {
|
||||
doc->SetDocumentAndPageUseCounter(
|
||||
eUseCounter_custom_GetUserMediaUnfocused);
|
||||
if (RefPtr<nsPIDOMWindowInner> owner = GetOwner()) {
|
||||
if (Document* doc = owner->GetExtantDoc()) {
|
||||
if (!owner->IsSecureContext()) {
|
||||
doc->SetDocumentAndPageUseCounter(eUseCounter_custom_GetUserMediaInsec);
|
||||
}
|
||||
if (!IsSameOriginWithAllParentDocs(doc)) {
|
||||
doc->SetDocumentAndPageUseCounter(
|
||||
eUseCounter_custom_GetUserMediaXOrigin);
|
||||
}
|
||||
Document* topDoc = doc->GetTopLevelContentDocument();
|
||||
IgnoredErrorResult ignored;
|
||||
if (topDoc && !topDoc->HasFocus(ignored)) {
|
||||
doc->SetDocumentAndPageUseCounter(
|
||||
eUseCounter_custom_GetUserMediaUnfocused);
|
||||
}
|
||||
}
|
||||
}
|
||||
RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
|
||||
@ -112,16 +115,18 @@ already_AddRefed<Promise> MediaDevices::EnumerateDevices(CallerType aCallerType,
|
||||
ErrorResult& aRv) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (Document* doc = GetOwner()->GetExtantDoc()) {
|
||||
if (!GetOwner()->IsSecureContext()) {
|
||||
doc->SetDocumentAndPageUseCounter(
|
||||
eUseCounter_custom_EnumerateDevicesInsec);
|
||||
}
|
||||
Document* topDoc = doc->GetTopLevelContentDocument();
|
||||
IgnoredErrorResult ignored;
|
||||
if (topDoc && !topDoc->HasFocus(ignored)) {
|
||||
doc->SetDocumentAndPageUseCounter(
|
||||
eUseCounter_custom_EnumerateDevicesUnfocused);
|
||||
if (RefPtr<nsPIDOMWindowInner> owner = GetOwner()) {
|
||||
if (Document* doc = owner->GetExtantDoc()) {
|
||||
if (!owner->IsSecureContext()) {
|
||||
doc->SetDocumentAndPageUseCounter(
|
||||
eUseCounter_custom_EnumerateDevicesInsec);
|
||||
}
|
||||
Document* topDoc = doc->GetTopLevelContentDocument();
|
||||
IgnoredErrorResult ignored;
|
||||
if (topDoc && !topDoc->HasFocus(ignored)) {
|
||||
doc->SetDocumentAndPageUseCounter(
|
||||
eUseCounter_custom_EnumerateDevicesUnfocused);
|
||||
}
|
||||
}
|
||||
}
|
||||
RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
|
||||
@ -172,10 +177,12 @@ already_AddRefed<Promise> MediaDevices::EnumerateDevices(CallerType aCallerType,
|
||||
already_AddRefed<Promise> MediaDevices::GetDisplayMedia(
|
||||
const DisplayMediaStreamConstraints& aConstraints, CallerType aCallerType,
|
||||
ErrorResult& aRv) {
|
||||
if (Document* doc = GetOwner()->GetExtantDoc()) {
|
||||
if (!IsSameOriginWithAllParentDocs(doc)) {
|
||||
doc->SetDocumentAndPageUseCounter(
|
||||
eUseCounter_custom_GetDisplayMediaXOrigin);
|
||||
if (RefPtr<nsPIDOMWindowInner> owner = GetOwner()) {
|
||||
if (Document* doc = owner->GetExtantDoc()) {
|
||||
if (!IsSameOriginWithAllParentDocs(doc)) {
|
||||
doc->SetDocumentAndPageUseCounter(
|
||||
eUseCounter_custom_GetDisplayMediaXOrigin);
|
||||
}
|
||||
}
|
||||
}
|
||||
RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
|
||||
|
@ -94,9 +94,21 @@ already_AddRefed<MediaDataDecoder> RemoteDecoderModule::CreateAudioDecoder(
|
||||
|
||||
RefPtr<RemoteAudioDecoderChild> child = new RemoteAudioDecoderChild();
|
||||
MediaResult result(NS_OK);
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"RemoteDecoderModule::CreateAudioDecoder", [&, child]() {
|
||||
// We can use child as a ref here because this is a sync dispatch. In
|
||||
// the error case for InitIPDL, we can't just let the RefPtr go out of
|
||||
// scope at the end of the method because it will release the
|
||||
// RemoteAudioDecoderChild on the wrong thread. This will assert in
|
||||
// RemoteDecoderChild's destructor. Passing the RefPtr by reference
|
||||
// allows us to release the RemoteAudioDecoderChild on the manager
|
||||
// thread during this single dispatch.
|
||||
RefPtr<Runnable> task =
|
||||
NS_NewRunnableFunction("RemoteDecoderModule::CreateAudioDecoder", [&]() {
|
||||
result = child->InitIPDL(aParams.AudioConfig(), aParams.mOptions);
|
||||
if (NS_FAILED(result)) {
|
||||
// Release RemoteAudioDecoderChild here, while we're on
|
||||
// manager thread. Don't just let the RefPtr go out of scope.
|
||||
child = nullptr;
|
||||
}
|
||||
});
|
||||
SyncRunnable::DispatchToThread(mManagerThread, task);
|
||||
|
||||
@ -124,10 +136,22 @@ already_AddRefed<MediaDataDecoder> RemoteDecoderModule::CreateVideoDecoder(
|
||||
|
||||
RefPtr<RemoteVideoDecoderChild> child = new RemoteVideoDecoderChild();
|
||||
MediaResult result(NS_OK);
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"RemoteDecoderModule::CreateVideoDecoder", [&, child]() {
|
||||
// We can use child as a ref here because this is a sync dispatch. In
|
||||
// the error case for InitIPDL, we can't just let the RefPtr go out of
|
||||
// scope at the end of the method because it will release the
|
||||
// RemoteVideoDecoderChild on the wrong thread. This will assert in
|
||||
// RemoteDecoderChild's destructor. Passing the RefPtr by reference
|
||||
// allows us to release the RemoteVideoDecoderChild on the manager
|
||||
// thread during this single dispatch.
|
||||
RefPtr<Runnable> task =
|
||||
NS_NewRunnableFunction("RemoteDecoderModule::CreateVideoDecoder", [&]() {
|
||||
result = child->InitIPDL(aParams.VideoConfig(), aParams.mRate.mValue,
|
||||
aParams.mOptions);
|
||||
if (NS_FAILED(result)) {
|
||||
// Release RemoteVideoDecoderChild here, while we're on
|
||||
// manager thread. Don't just let the RefPtr go out of scope.
|
||||
child = nullptr;
|
||||
}
|
||||
});
|
||||
SyncRunnable::DispatchToThread(mManagerThread, task);
|
||||
|
||||
|
@ -607,7 +607,26 @@ void VideoSink::MaybeResolveEndPromise() {
|
||||
mFrameStats.NotifyPresentedFrame();
|
||||
}
|
||||
}
|
||||
mEndPromiseHolder.ResolveIfExists(true, __func__);
|
||||
|
||||
TimeStamp nowTime;
|
||||
const auto clockTime = mAudioSink->GetPosition(&nowTime);
|
||||
if (clockTime < mVideoFrameEndTime) {
|
||||
VSINK_LOG_V(
|
||||
"Not reach video end time yet, reschedule timer to resolve "
|
||||
"end promise. clockTime=%" PRId64 ", endTime=%" PRId64,
|
||||
clockTime.ToMicroseconds(), mVideoFrameEndTime.ToMicroseconds());
|
||||
int64_t delta = (mVideoFrameEndTime - clockTime).ToMicroseconds() /
|
||||
mAudioSink->GetPlaybackParams().mPlaybackRate;
|
||||
TimeStamp target = nowTime + TimeDuration::FromMicroseconds(delta);
|
||||
auto resolveEndPromise = [self = RefPtr<VideoSink>(this)]() {
|
||||
self->mEndPromiseHolder.ResolveIfExists(true, __func__);
|
||||
self->mUpdateScheduler.CompleteRequest();
|
||||
};
|
||||
mUpdateScheduler.Ensure(target, std::move(resolveEndPromise),
|
||||
std::move(resolveEndPromise));
|
||||
} else {
|
||||
mEndPromiseHolder.ResolveIfExists(true, __func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1214,24 +1214,6 @@ void SVGElement::UpdateContentDeclarationBlock() {
|
||||
continue; // xml:lang has precedence
|
||||
}
|
||||
|
||||
if (IsSVGElement(nsGkAtoms::svg)) {
|
||||
// Special case: we don't want <svg> 'width'/'height' mapped into style
|
||||
// if the attribute value isn't a valid <length> according to SVG (which
|
||||
// only supports a subset of the CSS <length> values). We don't enforce
|
||||
// this by checking the attribute value in SVGSVGElement::
|
||||
// IsAttributeMapped since we don't want that method to depend on the
|
||||
// value of the attribute that is being checked. Rather we just prevent
|
||||
// the actual mapping here, as necessary.
|
||||
if (attrName->Atom() == nsGkAtoms::width &&
|
||||
!GetAnimatedLength(nsGkAtoms::width)->HasBaseVal()) {
|
||||
continue;
|
||||
}
|
||||
if (attrName->Atom() == nsGkAtoms::height &&
|
||||
!GetAnimatedLength(nsGkAtoms::height)->HasBaseVal()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (lengthAffectsStyle) {
|
||||
auto const* length = GetAnimatedLength(attrName->Atom());
|
||||
|
||||
|
@ -14,7 +14,7 @@ dictionary KeyframeAnimationOptions : KeyframeEffectOptions {
|
||||
DOMString id = "";
|
||||
};
|
||||
|
||||
dictionary AnimationFilter {
|
||||
dictionary GetAnimationsOptions {
|
||||
boolean subtree = false;
|
||||
};
|
||||
|
||||
@ -24,5 +24,5 @@ interface Animatable {
|
||||
Animation animate(object? keyframes,
|
||||
optional UnrestrictedDoubleOrKeyframeAnimationOptions options);
|
||||
[Func="Document::IsWebAnimationsGetAnimationsEnabled"]
|
||||
sequence<Animation> getAnimations(optional AnimationFilter filter);
|
||||
sequence<Animation> getAnimations(optional GetAnimationsOptions options);
|
||||
};
|
||||
|
@ -231,12 +231,15 @@ XMLHttpRequestMainThread::XMLHttpRequestMainThread()
|
||||
mIsMappedArrayBuffer(false),
|
||||
mXPCOMifier(nullptr),
|
||||
mEventDispatchingSuspended(false),
|
||||
mEofDecoded(false) {
|
||||
mEofDecoded(false),
|
||||
mDelayedDoneNotifier(nullptr) {
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
||||
XMLHttpRequestMainThread::~XMLHttpRequestMainThread() {
|
||||
DisconnectDoneNotifier();
|
||||
MOZ_ASSERT(
|
||||
!mDelayedDoneNotifier,
|
||||
"How can we have mDelayedDoneNotifier, which owns us, in destructor?");
|
||||
|
||||
mFlagDeleted = true;
|
||||
|
||||
@ -2234,6 +2237,8 @@ void XMLHttpRequestMainThread::MatchCharsetAndDecoderToResponseDocument() {
|
||||
}
|
||||
void XMLHttpRequestMainThread::DisconnectDoneNotifier() {
|
||||
if (mDelayedDoneNotifier) {
|
||||
// Disconnect may release the last reference to 'this'.
|
||||
RefPtr<XMLHttpRequestMainThread> kungfuDeathGrip = this;
|
||||
mDelayedDoneNotifier->Disconnect();
|
||||
mDelayedDoneNotifier = nullptr;
|
||||
}
|
||||
|
@ -724,7 +724,7 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest,
|
||||
// Our parse-end listener, if we are parsing.
|
||||
RefPtr<nsXHRParseEndListener> mParseEndListener;
|
||||
|
||||
RefPtr<XMLHttpRequestDoneNotifier> mDelayedDoneNotifier;
|
||||
XMLHttpRequestDoneNotifier* mDelayedDoneNotifier;
|
||||
void DisconnectDoneNotifier();
|
||||
|
||||
// Any stack information for the point the XHR was opened. This is deleted
|
||||
@ -795,8 +795,9 @@ class XMLHttpRequestDoneNotifier : public Runnable {
|
||||
NS_IMETHOD Run() override {
|
||||
if (mXHR) {
|
||||
RefPtr<XMLHttpRequestMainThread> xhr = mXHR;
|
||||
mXHR = nullptr;
|
||||
// ChangeStateToDoneInternal ends up calling Disconnect();
|
||||
xhr->ChangeStateToDoneInternal();
|
||||
MOZ_ASSERT(!mXHR);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -804,7 +805,7 @@ class XMLHttpRequestDoneNotifier : public Runnable {
|
||||
void Disconnect() { mXHR = nullptr; }
|
||||
|
||||
private:
|
||||
XMLHttpRequestMainThread* mXHR;
|
||||
RefPtr<XMLHttpRequestMainThread> mXHR;
|
||||
};
|
||||
|
||||
class nsXHRParseEndListener : public nsIDOMEventListener {
|
||||
|
@ -1541,6 +1541,7 @@ nsresult HTMLEditRules::WillInsertText(EditSubAction aEditSubAction,
|
||||
return rv;
|
||||
}
|
||||
pos++;
|
||||
MOZ_ASSERT(pointAfterInsertedSpaces.IsSet());
|
||||
currentPoint = pointAfterInsertedSpaces;
|
||||
pointToInsert = pointAfterInsertedSpaces;
|
||||
}
|
||||
@ -1581,6 +1582,7 @@ nsresult HTMLEditRules::WillInsertText(EditSubAction aEditSubAction,
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
MOZ_ASSERT(pointAfterInsertedString.IsSet());
|
||||
currentPoint = pointAfterInsertedString;
|
||||
pointToInsert = pointAfterInsertedString;
|
||||
}
|
||||
|
@ -368,12 +368,18 @@ nsresult WSRunObject::InsertText(Document& aDocument,
|
||||
}
|
||||
}
|
||||
|
||||
// Ready, aim, fire!
|
||||
// XXX If the point is not editable, InsertTextWithTransaction() returns
|
||||
// error, but we keep handling it. But I think that it wastes the
|
||||
// runtime cost. So, perhaps, we should return error code which couldn't
|
||||
// modify it and make each caller of this method decide whether it should
|
||||
// keep or stop handling the edit action.
|
||||
nsresult rv =
|
||||
MOZ_KnownLive(mHTMLEditor)
|
||||
->InsertTextWithTransaction(aDocument, theString, pointToInsert,
|
||||
aPointAfterInsertedString);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// XXX Temporarily, set new insertion point to the original point.
|
||||
*aPointAfterInsertedString = pointToInsert;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_OK;
|
||||
|
29
editor/libeditor/crashtests/1534394.html
Normal file
29
editor/libeditor/crashtests/1534394.html
Normal file
@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function start () {
|
||||
const sel = document.getSelection()
|
||||
const range_1 = new Range()
|
||||
const noscript = document.getElementById('id_24')
|
||||
const map = document.getElementById('id_26')
|
||||
sel.selectAllChildren(noscript)
|
||||
const range_2 = range_1.cloneRange()
|
||||
range_2.selectNode(map)
|
||||
const frag = range_2.extractContents()
|
||||
range_2.insertNode(noscript)
|
||||
document.documentElement.contentEditable = true
|
||||
document.execCommand('removeFormat', false,)
|
||||
noscript.contentEditable = false
|
||||
document.execCommand('insertText', false, '�\n')
|
||||
}
|
||||
|
||||
window.addEventListener('load', start)
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<big class="">
|
||||
<map class="" id="id_26">
|
||||
<noscript class="" id="id_24">
|
||||
</body>
|
||||
</html>
|
@ -108,4 +108,5 @@ load 1446451.html
|
||||
asserts(0-2) load 1464251.html # assertion is that mutation event listener modifies content
|
||||
pref(layout.accessiblecaret.enabled,true) load 1470926.html
|
||||
load 1525481.html
|
||||
load 1534394.html
|
||||
load 1547898.html
|
||||
|
@ -90,39 +90,39 @@ void ScrollMetadata::SetUsesContainerScrolling(bool aValue) {
|
||||
mUsesContainerScrolling = aValue;
|
||||
}
|
||||
|
||||
void ScrollSnapInfo::InitializeScrollSnapType(WritingMode aWritingMode,
|
||||
const nsStyleDisplay* aDisplay) {
|
||||
void ScrollSnapInfo::InitializeScrollSnapStrictness(
|
||||
WritingMode aWritingMode, const nsStyleDisplay* aDisplay) {
|
||||
if (aDisplay->mScrollSnapType.strictness == StyleScrollSnapStrictness::None) {
|
||||
return;
|
||||
}
|
||||
|
||||
mScrollSnapTypeX = StyleScrollSnapStrictness::None;
|
||||
mScrollSnapTypeY = StyleScrollSnapStrictness::None;
|
||||
mScrollSnapStrictnessX = StyleScrollSnapStrictness::None;
|
||||
mScrollSnapStrictnessY = StyleScrollSnapStrictness::None;
|
||||
|
||||
switch (aDisplay->mScrollSnapType.axis) {
|
||||
case StyleScrollSnapAxis::X:
|
||||
mScrollSnapTypeX = aDisplay->mScrollSnapType.strictness;
|
||||
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
|
||||
break;
|
||||
case StyleScrollSnapAxis::Y:
|
||||
mScrollSnapTypeY = aDisplay->mScrollSnapType.strictness;
|
||||
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
|
||||
break;
|
||||
case StyleScrollSnapAxis::Block:
|
||||
if (aWritingMode.IsVertical()) {
|
||||
mScrollSnapTypeX = aDisplay->mScrollSnapType.strictness;
|
||||
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
|
||||
} else {
|
||||
mScrollSnapTypeY = aDisplay->mScrollSnapType.strictness;
|
||||
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
|
||||
}
|
||||
break;
|
||||
case StyleScrollSnapAxis::Inline:
|
||||
if (aWritingMode.IsVertical()) {
|
||||
mScrollSnapTypeY = aDisplay->mScrollSnapType.strictness;
|
||||
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
|
||||
} else {
|
||||
mScrollSnapTypeX = aDisplay->mScrollSnapType.strictness;
|
||||
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
|
||||
}
|
||||
break;
|
||||
case StyleScrollSnapAxis::Both:
|
||||
mScrollSnapTypeX = aDisplay->mScrollSnapType.strictness;
|
||||
mScrollSnapTypeY = aDisplay->mScrollSnapType.strictness;
|
||||
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
|
||||
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -719,8 +719,8 @@ struct ScrollSnapInfo {
|
||||
ScrollSnapInfo() = default;
|
||||
|
||||
bool operator==(const ScrollSnapInfo& aOther) const {
|
||||
return mScrollSnapTypeX == aOther.mScrollSnapTypeX &&
|
||||
mScrollSnapTypeY == aOther.mScrollSnapTypeY &&
|
||||
return mScrollSnapStrictnessX == aOther.mScrollSnapStrictnessX &&
|
||||
mScrollSnapStrictnessY == aOther.mScrollSnapStrictnessY &&
|
||||
mScrollSnapIntervalX == aOther.mScrollSnapIntervalX &&
|
||||
mScrollSnapIntervalY == aOther.mScrollSnapIntervalY &&
|
||||
mScrollSnapDestination == aOther.mScrollSnapDestination &&
|
||||
@ -733,24 +733,25 @@ struct ScrollSnapInfo {
|
||||
}
|
||||
|
||||
bool HasScrollSnapping() const {
|
||||
return mScrollSnapTypeY != mozilla::StyleScrollSnapStrictness::None ||
|
||||
mScrollSnapTypeX != mozilla::StyleScrollSnapStrictness::None;
|
||||
return mScrollSnapStrictnessY != mozilla::StyleScrollSnapStrictness::None ||
|
||||
mScrollSnapStrictnessX != mozilla::StyleScrollSnapStrictness::None;
|
||||
}
|
||||
|
||||
bool HasSnapPositions() const {
|
||||
return (!mSnapPositionX.IsEmpty() &&
|
||||
mScrollSnapTypeX != mozilla::StyleScrollSnapStrictness::None) ||
|
||||
mScrollSnapStrictnessX !=
|
||||
mozilla::StyleScrollSnapStrictness::None) ||
|
||||
(!mSnapPositionY.IsEmpty() &&
|
||||
mScrollSnapTypeY != mozilla::StyleScrollSnapStrictness::None);
|
||||
mScrollSnapStrictnessY != mozilla::StyleScrollSnapStrictness::None);
|
||||
}
|
||||
|
||||
void InitializeScrollSnapType(WritingMode aWritingMode,
|
||||
const nsStyleDisplay* aDisplay);
|
||||
void InitializeScrollSnapStrictness(WritingMode aWritingMode,
|
||||
const nsStyleDisplay* aDisplay);
|
||||
|
||||
// The scroll frame's scroll-snap-type.
|
||||
mozilla::StyleScrollSnapStrictness mScrollSnapTypeX =
|
||||
mozilla::StyleScrollSnapStrictness mScrollSnapStrictnessX =
|
||||
mozilla::StyleScrollSnapStrictness::None;
|
||||
mozilla::StyleScrollSnapStrictness mScrollSnapTypeY =
|
||||
mozilla::StyleScrollSnapStrictness mScrollSnapStrictnessY =
|
||||
mozilla::StyleScrollSnapStrictness::None;
|
||||
|
||||
// The intervals derived from the scroll frame's scroll-snap-points.
|
||||
|
@ -660,6 +660,9 @@ void APZCTreeManager::SampleForWebRender(wr::TransactionWrapper& aTxn,
|
||||
AsyncPanZoomController::eForCompositing);
|
||||
transforms.AppendElement(wr::ToWrTransformProperty(
|
||||
*zoomAnimationId, Matrix4x4::Scaling(zoom.scale, zoom.scale, 1.0f)));
|
||||
|
||||
aTxn.UpdateIsTransformPinchZooming(*zoomAnimationId,
|
||||
apzc->IsPinchZooming());
|
||||
}
|
||||
|
||||
// The positive translation means the painted content is supposed to
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user