зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central r=merge a=merge
This commit is contained in:
Коммит
eb8b0ee85a
|
@ -1,5 +1,8 @@
|
|||
[DEFAULT]
|
||||
prefs =
|
||||
# Skip migration work in BG__migrateUI for browser_startup.js since it isn't
|
||||
# representative of common startup.
|
||||
browser.migration.version=9999999
|
||||
browser.startup.record=true
|
||||
support-files =
|
||||
head.js
|
||||
|
|
|
@ -44,7 +44,7 @@ class TestFirefoxRefresh(MarionetteTestCase):
|
|||
Services.logins.addLogin(myLogin)
|
||||
""", script_args=(self._username, self._password))
|
||||
|
||||
def createBookmark(self):
|
||||
def createBookmarkInMenu(self):
|
||||
self.marionette.execute_script("""
|
||||
let url = arguments[0];
|
||||
let title = arguments[1];
|
||||
|
@ -52,6 +52,14 @@ class TestFirefoxRefresh(MarionetteTestCase):
|
|||
makeURI(url), 0, title);
|
||||
""", script_args=(self._bookmarkURL, self._bookmarkText))
|
||||
|
||||
def createBookmarksOnToolbar(self):
|
||||
self.marionette.execute_script("""
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.toolbarFolderId,
|
||||
makeURI(`about:rights?p=${i}`), 0, `Bookmark ${i}`);
|
||||
}
|
||||
""")
|
||||
|
||||
def createHistory(self):
|
||||
error = self.runAsyncCode("""
|
||||
// Copied from PlacesTestUtils, which isn't available in Marionette tests.
|
||||
|
@ -200,7 +208,7 @@ class TestFirefoxRefresh(MarionetteTestCase):
|
|||
# Note that we expect 2 logins - one from us, one from sync.
|
||||
self.assertEqual(loginCount, 2, "No other logins are present")
|
||||
|
||||
def checkBookmark(self):
|
||||
def checkBookmarkInMenu(self):
|
||||
titleInBookmarks = self.marionette.execute_script("""
|
||||
let url = arguments[0];
|
||||
let bookmarkIds = PlacesUtils.bookmarks.getBookmarkIdsForURI(makeURI(url), {}, {});
|
||||
|
@ -208,6 +216,14 @@ class TestFirefoxRefresh(MarionetteTestCase):
|
|||
""", script_args=(self._bookmarkURL,))
|
||||
self.assertEqual(titleInBookmarks, self._bookmarkText)
|
||||
|
||||
def checkBookmarkToolbarVisibility(self):
|
||||
toolbarVisible = self.marionette.execute_script("""
|
||||
const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
|
||||
let xulStore = Cc["@mozilla.org/xul/xulstore;1"].getService(Ci.nsIXULStore);
|
||||
return xulStore.getValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed")
|
||||
""")
|
||||
self.assertEqual(toolbarVisible, "false")
|
||||
|
||||
def checkHistory(self):
|
||||
historyResult = self.runAsyncCode("""
|
||||
PlacesUtils.history.fetch(arguments[0]).then(pageInfo => {
|
||||
|
@ -378,18 +394,20 @@ class TestFirefoxRefresh(MarionetteTestCase):
|
|||
|
||||
def checkProfile(self, hasMigrated=False):
|
||||
self.checkPassword()
|
||||
self.checkBookmark()
|
||||
self.checkBookmarkInMenu()
|
||||
self.checkHistory()
|
||||
self.checkFormHistory()
|
||||
self.checkFormAutofill()
|
||||
self.checkCookie()
|
||||
self.checkSync(hasMigrated);
|
||||
if hasMigrated:
|
||||
self.checkBookmarkToolbarVisibility()
|
||||
self.checkSession()
|
||||
|
||||
def createProfileData(self):
|
||||
self.savePassword()
|
||||
self.createBookmark()
|
||||
self.createBookmarkInMenu()
|
||||
self.createBookmarksOnToolbar()
|
||||
self.createHistory()
|
||||
self.createFormHistory()
|
||||
self.createFormAutofill()
|
||||
|
|
|
@ -1743,6 +1743,35 @@ BrowserGlue.prototype = {
|
|||
this.AlertsService.showAlertNotification(null, title, body, true, null, clickCallback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Uncollapses PersonalToolbar if its collapsed status is not
|
||||
* persisted, and user customized it or changed default bookmarks.
|
||||
*
|
||||
* If the user does not have a persisted value for the toolbar's
|
||||
* "collapsed" attribute, try to determine whether it's customized.
|
||||
*/
|
||||
_maybeToggleBookmarkToolbarVisibility() {
|
||||
const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
|
||||
const NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE = 3;
|
||||
let xulStore = Cc["@mozilla.org/xul/xulstore;1"].getService(Ci.nsIXULStore);
|
||||
|
||||
if (!xulStore.hasValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed")) {
|
||||
// We consider the toolbar customized if it has more than NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
|
||||
// children, or if it has a persisted currentset value.
|
||||
let toolbarIsCustomized = xulStore.hasValue(BROWSER_DOCURL, "PersonalToolbar", "currentset");
|
||||
let getToolbarFolderCount = () => {
|
||||
let toolbarFolder = PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root;
|
||||
let toolbarChildCount = toolbarFolder.childCount;
|
||||
toolbarFolder.containerOpen = false;
|
||||
return toolbarChildCount;
|
||||
};
|
||||
|
||||
if (toolbarIsCustomized || getToolbarFolderCount() > NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE) {
|
||||
xulStore.setValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed", "false");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
_migrateUI: function BG__migrateUI() {
|
||||
const UI_VERSION = 58;
|
||||
|
@ -1754,6 +1783,15 @@ BrowserGlue.prototype = {
|
|||
} else {
|
||||
// This is a new profile, nothing to migrate.
|
||||
Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
|
||||
|
||||
try {
|
||||
// New profiles may have existing bookmarks (imported from another browser or
|
||||
// copied into the profile) and we want to show the bookmark toolbar for them
|
||||
// in some cases.
|
||||
this._maybeToggleBookmarkToolbarVisibility();
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
skip-if = !updater
|
||||
reason = test depends on update channel
|
||||
[browser_contentpermissionprompt.js]
|
||||
[browser_default_bookmark_toolbar_visibility.js]
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test _maybeToggleBookmarkToolbarVisibility() code running for new profiles.
|
||||
* Ensure that the bookmarks toolbar is hidden in a default configuration.
|
||||
* If new default bookmarks are added to the toolbar then the threshold of > 3
|
||||
* in NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE may need to be adjusted there.
|
||||
*/
|
||||
add_task(async function test_default_bookmark_toolbar_visibility() {
|
||||
const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
|
||||
let xulStore = Cc["@mozilla.org/xul/xulstore;1"].getService(Ci.nsIXULStore);
|
||||
|
||||
is(xulStore.getValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed"), "",
|
||||
"Check that @collapsed isn't persisted");
|
||||
ok(document.getElementById("PersonalToolbar").collapsed,
|
||||
"The bookmarks toolbar should be collapsed by default");
|
||||
});
|
|
@ -355,7 +355,15 @@ flashActivate.noAllow.accesskey=D
|
|||
flashActivate.allow.accesskey=A
|
||||
|
||||
# in-page UI
|
||||
PluginClickToActivate=Activate %S.
|
||||
# LOCALIZATION NOTE (PluginClickToActivate2): Two changes were done to the
|
||||
# previous version of the string. The first is that we changed the wording from
|
||||
# "Activate" to "Run", because it's shorter and feels less technical in English.
|
||||
# Feel free to keep using the previous wording in your language if it's already
|
||||
# the best one.
|
||||
# The second change is that we removed the period at the end of the phrase, because
|
||||
# it's not natural in our UI, and the underline was removed from this, so it doesn't
|
||||
# look like a link anymore. We suggest that everyone removes that period too.
|
||||
PluginClickToActivate2=Run %S
|
||||
PluginVulnerableUpdatable=This plugin is vulnerable and should be updated.
|
||||
PluginVulnerableNoUpdate=This plugin has security vulnerabilities.
|
||||
|
||||
|
|
|
@ -575,7 +575,7 @@ PluginContent.prototype = {
|
|||
case "PluginClickToPlay":
|
||||
this._handleClickToPlayEvent(plugin);
|
||||
let pluginName = this._getPluginInfo(plugin).pluginName;
|
||||
let messageString = gNavigatorBundle.formatStringFromName("PluginClickToActivate", [pluginName], 1);
|
||||
let messageString = gNavigatorBundle.formatStringFromName("PluginClickToActivate2", [pluginName], 1);
|
||||
let overlayText = this.getPluginUI(plugin, "clickToPlay");
|
||||
overlayText.textContent = messageString;
|
||||
if (eventType == "PluginVulnerableUpdatable" ||
|
||||
|
|
|
@ -31,7 +31,7 @@ if test -z "$MOZ_ARCH"; then
|
|||
arm-Android)
|
||||
MOZ_THUMB=yes
|
||||
MOZ_ARCH=armv7-a
|
||||
MOZ_FPU=vfp
|
||||
MOZ_FPU=vfpv3-d16
|
||||
MOZ_FLOAT_ABI=softfp
|
||||
MOZ_ALIGN=no
|
||||
;;
|
||||
|
|
|
@ -598,6 +598,10 @@
|
|||
|
||||
/* Shapes highlighter */
|
||||
|
||||
:-moz-native-anonymous .shapes-root {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
:-moz-native-anonymous .shapes-shape-container {
|
||||
position: absolute;
|
||||
overflow: visible;
|
||||
|
|
|
@ -214,6 +214,35 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the appearance of the mouse cursor on the highlighter.
|
||||
*
|
||||
* Because we can't attach event handlers to individual elements in the
|
||||
* highlighter, we determine if the mouse is hovering over a point by seeing if
|
||||
* it's within 5 pixels of it. This creates a square hitbox that doesn't match
|
||||
* perfectly with the circular markers. So if we were to use the :hover
|
||||
* pseudo-class to apply changes to the mouse cursor, the cursor change would not
|
||||
* always accurately reflect whether you can interact with the point. This is
|
||||
* also the reason we have the hidden marker-hover element instead of using CSS
|
||||
* to fill in the marker.
|
||||
*
|
||||
* In addition, the cursor CSS property is applied to .shapes-root because if
|
||||
* it were attached to .shapes-marker, the cursor change no longer applies if
|
||||
* you are for example resizing the shape and your mouse goes off the point.
|
||||
* Also, if you are dragging a polygon point, the marker plays catch up to your
|
||||
* mouse position, resulting in an undesirable visual effect where the cursor
|
||||
* rapidly flickers between "grab" and "auto".
|
||||
*
|
||||
* @param {String} cursorType the name of the cursor to display
|
||||
*/
|
||||
setCursor(cursorType) {
|
||||
let container = this.getElement("root");
|
||||
let style = container.getAttribute("style");
|
||||
// remove existing cursor definitions in the style
|
||||
style = style.replace(/cursor:.*?;/g, "");
|
||||
container.setAttribute("style", `${style}cursor:${cursorType};`);
|
||||
}
|
||||
|
||||
handleEvent(event, id) {
|
||||
// No event handling if the highlighter is hidden
|
||||
if (this.areShapesHidden()) {
|
||||
|
@ -265,6 +294,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
case "mouseup":
|
||||
if (this[_dragging]) {
|
||||
this[_dragging] = null;
|
||||
this._handleMarkerHover(this.hoveredPoint);
|
||||
}
|
||||
break;
|
||||
case "mousemove":
|
||||
|
@ -674,6 +704,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
let ratioX = (valueX / xComputed) || 1;
|
||||
let ratioY = (valueY / yComputed) || 1;
|
||||
|
||||
this.setCursor("grabbing");
|
||||
this[_dragging] = { point, unitX, unitY, valueX, valueY,
|
||||
ratioX, ratioY, x: pageX, y: pageY };
|
||||
}
|
||||
|
@ -752,6 +783,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
return;
|
||||
}
|
||||
|
||||
this.setCursor("grabbing");
|
||||
if (point === "center") {
|
||||
let { cx, cy } = this.coordUnits;
|
||||
let cxComputed = this.coordinates.cx / 100 * width;
|
||||
|
@ -833,6 +865,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
return;
|
||||
}
|
||||
|
||||
this.setCursor("grabbing");
|
||||
if (point === "center") {
|
||||
let { cx, cy } = this.coordUnits;
|
||||
let cxComputed = this.coordinates.cx / 100 * width;
|
||||
|
@ -932,6 +965,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
return;
|
||||
}
|
||||
|
||||
this.setCursor("grabbing");
|
||||
let value = this.coordUnits[point];
|
||||
let size = (point === "left" || point === "right") ? width : height;
|
||||
let computedValue = this.coordinates[point] / 100 * size;
|
||||
|
@ -1021,40 +1055,51 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the appearance of the given marker when the mouse hovers over it.
|
||||
* @param {String|Number} point if the shape is a polygon, the integer index of the
|
||||
* point being hovered. Otherwise, a string identifying the point being hovered.
|
||||
* Integers < 0 and falsey values excluding 0 indicate no point is being hovered.
|
||||
*/
|
||||
_handleMarkerHover(point) {
|
||||
// Hide hover marker for now, will be shown if point is a valid hover target
|
||||
this.getElement("marker-hover").setAttribute("hidden", true);
|
||||
if (point === null || point === undefined) {
|
||||
// Catch all falsey values except when point === 0, as that's a valid point
|
||||
if (!point && point !== 0) {
|
||||
this.setCursor("auto");
|
||||
return;
|
||||
}
|
||||
let hoverCursor = (this[_dragging]) ? "grabbing" : "grab";
|
||||
|
||||
if (this.transformMode) {
|
||||
if (!point) {
|
||||
return;
|
||||
}
|
||||
let { minX, minY, maxX, maxY } = this.boundingBox;
|
||||
let centerX = (minX + maxX) / 2;
|
||||
let centerY = (minY + maxY) / 2;
|
||||
|
||||
const points = [
|
||||
{ pointName: "translate", x: centerX, y: centerY },
|
||||
{ pointName: "scale-se", x: maxX, y: maxY },
|
||||
{ pointName: "scale-ne", x: maxX, y: minY },
|
||||
{ pointName: "scale-sw", x: minX, y: maxY },
|
||||
{ pointName: "scale-nw", x: minX, y: minY },
|
||||
{ pointName: "translate", x: centerX, y: centerY, cursor: "move" },
|
||||
{ pointName: "scale-se", x: maxX, y: maxY, cursor: "nwse-resize" },
|
||||
{ pointName: "scale-ne", x: maxX, y: minY, cursor: "nesw-resize" },
|
||||
{ pointName: "scale-sw", x: minX, y: maxY, cursor: "nesw-resize" },
|
||||
{ pointName: "scale-nw", x: minX, y: minY, cursor: "nwse-resize" },
|
||||
];
|
||||
|
||||
for (let { pointName, x, y } of points) {
|
||||
for (let { pointName, x, y, cursor } of points) {
|
||||
if (point === pointName) {
|
||||
this._drawHoverMarker([[x, y]]);
|
||||
this.setCursor(cursor);
|
||||
}
|
||||
}
|
||||
} else if (this.shapeType === "polygon") {
|
||||
if (point === -1) {
|
||||
this.setCursor("auto");
|
||||
return;
|
||||
}
|
||||
this.setCursor(hoverCursor);
|
||||
this._drawHoverMarker([this.coordinates[point]]);
|
||||
} else if (this.shapeType === "circle") {
|
||||
this.setCursor(hoverCursor);
|
||||
|
||||
let { cx, cy, rx } = this.coordinates;
|
||||
if (point === "radius") {
|
||||
this._drawHoverMarker([[cx + rx, cy]]);
|
||||
|
@ -1062,6 +1107,8 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
this._drawHoverMarker([[cx, cy]]);
|
||||
}
|
||||
} else if (this.shapeType === "ellipse") {
|
||||
this.setCursor(hoverCursor);
|
||||
|
||||
if (point === "center") {
|
||||
let { cx, cy } = this.coordinates;
|
||||
this._drawHoverMarker([[cx, cy]]);
|
||||
|
@ -1073,9 +1120,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
this._drawHoverMarker([[cx, cy + ry]]);
|
||||
}
|
||||
} else if (this.shapeType === "inset") {
|
||||
if (!point) {
|
||||
return;
|
||||
}
|
||||
this.setCursor(hoverCursor);
|
||||
|
||||
let { top, right, bottom, left } = this.coordinates;
|
||||
let centerX = (left + (100 - right)) / 2;
|
||||
|
@ -1803,12 +1848,12 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
this._updateInsetShape(width, height, zoom);
|
||||
}
|
||||
|
||||
this._handleMarkerHover(this.hoveredPoint);
|
||||
|
||||
let { width: winWidth, height: winHeight } = this._winDimensions;
|
||||
root.removeAttribute("hidden");
|
||||
root.setAttribute("style",
|
||||
`position:absolute; width:${winWidth}px;height:${winHeight}px; overflow:hidden`);
|
||||
`position:absolute; width:${winWidth}px;height:${winHeight}px; overflow:hidden;`);
|
||||
|
||||
this._handleMarkerHover(this.hoveredPoint);
|
||||
|
||||
setIgnoreLayoutChanges(false, this.highlighterEnv.window.document.documentElement);
|
||||
|
||||
|
|
|
@ -33,14 +33,15 @@ promise_test(t => {
|
|||
}, 'Ensure document has been loaded');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: ['translateX(0px)', 'translateX(200px)'],
|
||||
composite: 'accumulate' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: ['translateX(0px)', 'translateX(200px)'],
|
||||
composite: 'accumulate' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
|
@ -50,17 +51,18 @@ promise_test(t => {
|
|||
}, 'Accumulate onto the base value');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
div.animate({ transform: ['translateX(100px)', 'translateX(200px)'],
|
||||
composite: 'replace' },
|
||||
100 * MS_PER_SEC);
|
||||
div.animate({ transform: ['translateX(0px)', 'translateX(100px)'],
|
||||
composite: 'accumulate' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
div.animate({ transform: ['translateX(100px)', 'translateX(200px)'],
|
||||
composite: 'replace' },
|
||||
100 * MS_PER_SEC);
|
||||
div.animate({ transform: ['translateX(0px)', 'translateX(100px)'],
|
||||
composite: 'accumulate' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
|
@ -70,14 +72,15 @@ promise_test(t => {
|
|||
}, 'Accumulate onto an underlying animation value');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate([{ transform: 'translateX(100px)', composite: 'accumulate' },
|
||||
{ transform: 'translateX(300px)', composite: 'replace' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate([{ transform: 'translateX(100px)', composite: 'accumulate' },
|
||||
{ transform: 'translateX(300px)', composite: 'replace' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
|
@ -87,14 +90,14 @@ promise_test(t => {
|
|||
}, 'Composite when mixing accumulate and replace');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate([{ transform: 'translateX(100px)', composite: 'replace' },
|
||||
{ transform: 'translateX(300px)' }],
|
||||
{ duration: 100 * MS_PER_SEC, composite: 'accumulate' });
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate([{ transform: 'translateX(100px)', composite: 'replace' },
|
||||
{ transform: 'translateX(300px)' }],
|
||||
{ duration: 100 * MS_PER_SEC, composite: 'accumulate' });
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
|
@ -105,14 +108,16 @@ promise_test(t => {
|
|||
'effect');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
var anim;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
div.animate({ transform: [ 'scale(2)', 'scale(2)' ] }, 100 * MS_PER_SEC);
|
||||
anim = div.animate({ transform: [ 'scale(4)', 'scale(4)' ] },
|
||||
{ duration: 100 * MS_PER_SEC, composite: 'add' });
|
||||
|
||||
var div = addDiv(t);
|
||||
div.animate({ transform: [ 'scale(2)', 'scale(2)' ] }, 100 * MS_PER_SEC);
|
||||
var anim = div.animate({ transform: [ 'scale(4)', 'scale(4)' ] },
|
||||
{ duration: 100 * MS_PER_SEC, composite: 'add' });
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(8, 0, 0, 8, 0, 0)',
|
||||
|
|
|
@ -35,12 +35,12 @@ promise_test(t => {
|
|||
}, 'Ensure document has been loaded');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'opacity: 0.1' });
|
||||
div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'opacity: 0.1' });
|
||||
div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
assert_equals(opacity, '0.1',
|
||||
|
@ -49,13 +49,14 @@ promise_test(t => {
|
|||
}, 'Initial opacity value for animation with no no keyframe at offset 0');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'opacity: 0.1' });
|
||||
div.animate({ opacity: [ 0.5, 1 ] }, 100 * MS_PER_SEC);
|
||||
div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t, { style: 'opacity: 0.1' });
|
||||
div.animate({ opacity: [ 0.5, 1 ] }, 100 * MS_PER_SEC);
|
||||
div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
assert_equals(opacity, '0.5',
|
||||
|
@ -66,16 +67,16 @@ promise_test(t => {
|
|||
'there is a lower-priority animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'opacity: 0.1; transition: opacity 100s linear' });
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
var div =
|
||||
addDiv(t, { style: 'opacity: 0.1; transition: opacity 100s linear' });
|
||||
getComputedStyle(div).opacity;
|
||||
div.style.opacity = '0.5';
|
||||
div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
div.style.opacity = '0.5';
|
||||
div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
assert_equals(opacity, '0.1',
|
||||
|
@ -86,12 +87,13 @@ promise_test(t => {
|
|||
'there is a transition on the same property');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'opacity: 0' });
|
||||
div.animate([{ offset: 0, opacity: 1 }], 100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t, { style: 'opacity: 0' });
|
||||
div.animate([{ offset: 0, opacity: 1 }], 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var opacity =
|
||||
|
@ -103,13 +105,14 @@ promise_test(t => {
|
|||
}, 'Opacity value for animation with no keyframe at offset 1 at 50% ');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'opacity: 0' });
|
||||
div.animate({ opacity: [ 0.5, 0.5 ] }, 100 * MS_PER_SEC);
|
||||
div.animate([{ offset: 0, opacity: 1 }], 100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t, { style: 'opacity: 0' });
|
||||
div.animate({ opacity: [ 0.5, 0.5 ] }, 100 * MS_PER_SEC);
|
||||
div.animate([{ offset: 0, opacity: 1 }], 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var opacity =
|
||||
|
@ -122,16 +125,16 @@ promise_test(t => {
|
|||
'there is a lower-priority animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'opacity: 0; transition: opacity 100s linear' });
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
var div =
|
||||
addDiv(t, { style: 'opacity: 0; transition: opacity 100s linear' });
|
||||
getComputedStyle(div).opacity;
|
||||
div.style.opacity = '0.5';
|
||||
div.animate([{ offset: 0, opacity: 1 }], 100 * MS_PER_SEC);
|
||||
|
||||
div.style.opacity = '0.5';
|
||||
div.animate([{ offset: 0, opacity: 1 }], 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var opacity =
|
||||
|
@ -144,13 +147,15 @@ promise_test(t => {
|
|||
'there is a transition on the same property');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
var lowerAnimation;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
lowerAnimation = div.animate({ opacity: [ 0.5, 1 ] }, 100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation = div.animate({ opacity: [ 0.5, 1 ] }, 100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
lowerAnimation.pause();
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
|
@ -169,13 +174,15 @@ promise_test(t => {
|
|||
'composed onto a paused underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
var lowerAnimation;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
lowerAnimation = div.animate({ opacity: [ 0.5, 1 ] }, 100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation = div.animate({ opacity: [ 0.5, 1 ] }, 100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
lowerAnimation.playbackRate = 0;
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
|
@ -194,13 +201,15 @@ promise_test(t => {
|
|||
'composed onto a zero playback rate underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
var lowerAnimation;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
lowerAnimation = div.animate({ opacity: [ 1, 0.5 ] }, 100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation = div.animate({ opacity: [ 1, 0.5 ] }, 100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
lowerAnimation.effect.timing.duration = 0;
|
||||
lowerAnimation.effect.timing.fill = 'forwards';
|
||||
return waitForPaintsFlushed();
|
||||
|
@ -220,12 +229,13 @@ promise_test(t => {
|
|||
'composed onto a zero active duration underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: 'translateX(200px)' }, 100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: 'translateX(200px)' }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 100, 0)',
|
||||
|
@ -234,14 +244,15 @@ promise_test(t => {
|
|||
}, 'Initial transform value for animation with no keyframe at offset 0');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: [ 'translateX(200px)', 'translateX(300px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
div.animate({ transform: 'translateX(400px)' }, 100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: [ 'translateX(200px)', 'translateX(300px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
div.animate({ transform: 'translateX(400px)' }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 200, 0)',
|
||||
|
@ -251,17 +262,17 @@ promise_test(t => {
|
|||
'there is a lower-priority animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px);' +
|
||||
'transition: transform 100s linear' });
|
||||
getComputedStyle(div).transform;
|
||||
|
||||
var div =
|
||||
addDiv(t, { style: 'transform: translateX(100px);' +
|
||||
'transition: transform 100s linear' });
|
||||
getComputedStyle(div).transform;
|
||||
div.style.transform = 'translateX(200px)';
|
||||
div.animate({ transform: 'translateX(400px)' }, 100 * MS_PER_SEC);
|
||||
|
||||
div.style.transform = 'translateX(200px)';
|
||||
div.animate({ transform: 'translateX(400px)' }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 100, 0)',
|
||||
|
@ -272,13 +283,14 @@ promise_test(t => {
|
|||
'there is a transition');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate([{ offset: 0, transform: 'translateX(200pX)' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate([{ offset: 0, transform: 'translateX(200pX)' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
|
@ -289,15 +301,16 @@ promise_test(t => {
|
|||
}, 'Transform value for animation with no keyframe at offset 1 at 50%');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: [ 'translateX(200px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
div.animate([{ offset: 0, transform: 'translateX(300px)' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: [ 'translateX(200px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
div.animate([{ offset: 0, transform: 'translateX(300px)' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
|
@ -309,18 +322,18 @@ promise_test(t => {
|
|||
'there is a lower-priority animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px);' +
|
||||
'transition: transform 100s linear' });
|
||||
getComputedStyle(div).transform;
|
||||
|
||||
var div =
|
||||
addDiv(t, { style: 'transform: translateX(100px);' +
|
||||
'transition: transform 100s linear' });
|
||||
getComputedStyle(div).transform;
|
||||
div.style.transform = 'translateX(200px)';
|
||||
div.animate([{ offset: 0, transform: 'translateX(300px)' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
div.style.transform = 'translateX(200px)';
|
||||
div.animate([{ offset: 0, transform: 'translateX(300px)' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
|
@ -333,16 +346,18 @@ promise_test(t => {
|
|||
'there is a transition');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
var lowerAnimation;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
lowerAnimation.pause();
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
|
@ -361,16 +376,18 @@ promise_test(t => {
|
|||
'composed onto a paused underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
var lowerAnimation;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
lowerAnimation.playbackRate = 0;
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
|
@ -389,17 +406,18 @@ promise_test(t => {
|
|||
'composed onto a zero playback rate underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
{ duration: 10 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
{ duration: 10 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
// We need to wait for a paint so that we can send the state of the lower
|
||||
|
@ -417,18 +435,19 @@ promise_test(t => {
|
|||
'composed onto a underlying animation with fill:forwards');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
{ duration: 10 * MS_PER_SEC,
|
||||
endDelay: -5 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
{ duration: 10 * MS_PER_SEC,
|
||||
endDelay: -5 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
// We need to wait for a paint just like the above test.
|
||||
|
@ -446,18 +465,19 @@ promise_test(t => {
|
|||
'endDelay');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
{ duration: 10 * MS_PER_SEC,
|
||||
endDelay: 100 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
{ duration: 10 * MS_PER_SEC,
|
||||
endDelay: 100 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
|
@ -472,13 +492,14 @@ promise_test(t => {
|
|||
'endDelay');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: 'translateX(200px)' },
|
||||
{ duration: 100 * MS_PER_SEC, delay: 50 * MS_PER_SEC });
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: 'translateX(200px)' },
|
||||
{ duration: 100 * MS_PER_SEC, delay: 50 * MS_PER_SEC });
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(100 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
|
@ -491,16 +512,17 @@ promise_test(t => {
|
|||
'positive delay');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate([{ offset: 0, transform: 'translateX(200px)'}],
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
iterationStart: 1,
|
||||
iterationComposite: 'accumulate' });
|
||||
|
||||
div.animate([{ offset: 0, transform: 'translateX(200px)'}],
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
iterationStart: 1,
|
||||
iterationComposite: 'accumulate' });
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 300, 0)',
|
||||
|
@ -511,20 +533,21 @@ promise_test(t => {
|
|||
'iterationComposite is accumulate');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
var div;
|
||||
return useTestRefreshMode(t).then(() => {
|
||||
div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
lowerAnimation.timeline = null;
|
||||
// Set current time at 50% duration.
|
||||
lowerAnimation.currentTime = 50 * MS_PER_SEC;
|
||||
|
||||
lowerAnimation.timeline = null;
|
||||
// Set current time at 50% duration.
|
||||
lowerAnimation.currentTime = 50 * MS_PER_SEC;
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
|
|
|
@ -306,9 +306,24 @@ function waitForDocumentLoad() {
|
|||
* Enters test refresh mode, and restores the mode when |t| finishes.
|
||||
*/
|
||||
function useTestRefreshMode(t) {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(0);
|
||||
t.add_cleanup(() => {
|
||||
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
|
||||
function ensureNoSuppressedPaints() {
|
||||
return new Promise(resolve => {
|
||||
function checkSuppressedPaints() {
|
||||
if (!SpecialPowers.DOMWindowUtils.paintingSuppressed) {
|
||||
resolve();
|
||||
} else {
|
||||
window.requestAnimationFrame(checkSuppressedPaints);
|
||||
}
|
||||
}
|
||||
checkSuppressedPaints();
|
||||
});
|
||||
}
|
||||
|
||||
return ensureNoSuppressedPaints().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(0);
|
||||
t.add_cleanup(() => {
|
||||
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -357,8 +357,8 @@ DOMParser::Init(nsIPrincipal* principal, nsIURI* documentURI,
|
|||
|
||||
mBaseURI = baseURI;
|
||||
|
||||
NS_POSTCONDITION(mPrincipal, "Must have principal");
|
||||
NS_POSTCONDITION(mDocumentURI, "Must have document URI");
|
||||
MOZ_ASSERT(mPrincipal, "Must have principal");
|
||||
MOZ_ASSERT(mDocumentURI, "Must have document URI");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1888,10 +1888,10 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
// XXXbz script execution during binding can trigger some of these
|
||||
// postcondition asserts.... But we do want that, since things will
|
||||
// generally be quite broken when that happens.
|
||||
NS_POSTCONDITION(aDocument == GetUncomposedDoc(), "Bound to wrong document");
|
||||
NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
|
||||
NS_POSTCONDITION(aBindingParent == GetBindingParent(),
|
||||
"Bound to wrong binding parent");
|
||||
MOZ_ASSERT(aDocument == GetUncomposedDoc(), "Bound to wrong document");
|
||||
MOZ_ASSERT(aParent == GetParent(), "Bound to wrong parent");
|
||||
MOZ_ASSERT(aBindingParent == GetBindingParent(),
|
||||
"Bound to wrong binding parent");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2223,7 +2223,7 @@ Element::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
|
|||
const nsAString* aSerialized,
|
||||
bool aNotify)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("Element::SetInlineStyleDeclaration");
|
||||
MOZ_ASSERT_UNREACHABLE("Element::SetInlineStyleDeclaration");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -570,10 +570,10 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
|
||||
UpdateEditableState(false);
|
||||
|
||||
NS_POSTCONDITION(aDocument == GetUncomposedDoc(), "Bound to wrong document");
|
||||
NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
|
||||
NS_POSTCONDITION(aBindingParent == GetBindingParent(),
|
||||
"Bound to wrong binding parent");
|
||||
MOZ_ASSERT(aDocument == GetUncomposedDoc(), "Bound to wrong document");
|
||||
MOZ_ASSERT(aParent == GetParent(), "Bound to wrong parent");
|
||||
MOZ_ASSERT(aBindingParent == GetBindingParent(),
|
||||
"Bound to wrong binding parent");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1284,8 +1284,8 @@ NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsINode)
|
|||
nsresult
|
||||
nsINode::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// This is only here so that we can use the NS_DECL_NSIDOMTARGET macro
|
||||
NS_ABORT();
|
||||
MOZ_ASSERT_UNREACHABLE("GetEventTargetParent is only here so that we can "
|
||||
"use the NS_DECL_NSIDOMTARGET macro");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ nsNameSpaceManager::RegisterNameSpace(const nsAString& aURI,
|
|||
}
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(aNameSpaceID >= -1, "Bogus namespace ID");
|
||||
MOZ_ASSERT(aNameSpaceID >= -1, "Bogus namespace ID");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -159,11 +159,11 @@ nsNameSpaceManager::GetNameSpaceID(nsAtom* aURI,
|
|||
&& mDisabledURIToIDTable.Get(aURI, &nameSpaceID)
|
||||
&& ((mMathMLDisabled && kNameSpaceID_disabled_MathML == nameSpaceID) ||
|
||||
(mSVGDisabled && kNameSpaceID_disabled_SVG == nameSpaceID))) {
|
||||
NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID");
|
||||
MOZ_ASSERT(nameSpaceID >= 0, "Bogus namespace ID");
|
||||
return nameSpaceID;
|
||||
}
|
||||
if (mURIToIDTable.Get(aURI, &nameSpaceID)) {
|
||||
NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID");
|
||||
MOZ_ASSERT(nameSpaceID >= 0, "Bogus namespace ID");
|
||||
return nameSpaceID;
|
||||
}
|
||||
|
||||
|
|
|
@ -459,7 +459,7 @@ nsNodeInfoManager::RemoveNodeInfo(NodeInfo *aNodeInfo)
|
|||
#endif
|
||||
PL_HashTableRemove(mNodeInfoHash, &aNodeInfo->mInner);
|
||||
|
||||
NS_POSTCONDITION(ret, "Can't find mozilla::dom::NodeInfo to remove!!!");
|
||||
MOZ_ASSERT(ret, "Can't find mozilla::dom::NodeInfo to remove!!!");
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -5370,9 +5370,7 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas(
|
|||
// Get any existing transforms on the context, including transformations used
|
||||
// for context shadow.
|
||||
Matrix matrix = tempTarget->GetTransform();
|
||||
gfxMatrix contextMatrix;
|
||||
contextMatrix = gfxMatrix(matrix._11, matrix._12, matrix._21,
|
||||
matrix._22, matrix._31, matrix._32);
|
||||
gfxMatrix contextMatrix = ThebesMatrix(matrix);
|
||||
gfxSize contextScale(contextMatrix.ScaleFactors(true));
|
||||
|
||||
// Scale the dest rect to include the context scale.
|
||||
|
@ -5393,10 +5391,10 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas(
|
|||
gfxDevCrash(LogReason::InvalidContext) << "Canvas context problem";
|
||||
return;
|
||||
}
|
||||
context->SetMatrix(contextMatrix.
|
||||
PreScale(1.0 / contextScale.width,
|
||||
1.0 / contextScale.height).
|
||||
PreTranslate(aDest.x - aSrc.x, aDest.y - aSrc.y));
|
||||
context->SetMatrixDouble(contextMatrix.
|
||||
PreScale(1.0 / contextScale.width,
|
||||
1.0 / contextScale.height).
|
||||
PreTranslate(aDest.x - aSrc.x, aDest.y - aSrc.y));
|
||||
|
||||
// FLAG_CLAMP is added for increased performance, since we never tile here.
|
||||
uint32_t modifiedFlags = aImage.mDrawingFlags | imgIContainer::FLAG_CLAMP;
|
||||
|
@ -5603,8 +5601,7 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindowInner& aWindow, double aX,
|
|||
thebes = gfxContext::CreateOrNull(mTarget);
|
||||
MOZ_ASSERT(thebes); // already checked the draw target above
|
||||
// (in SupportsAzureContentForDrawTarget)
|
||||
thebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21,
|
||||
matrix._22, matrix._31, matrix._32));
|
||||
thebes->SetMatrix(matrix);
|
||||
} else {
|
||||
IntSize dtSize = IntSize::Ceil(sw, sh);
|
||||
if (!Factory::AllowedSurfaceSize(dtSize)) {
|
||||
|
@ -5621,7 +5618,7 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindowInner& aWindow, double aX,
|
|||
|
||||
thebes = gfxContext::CreateOrNull(drawDT);
|
||||
MOZ_ASSERT(thebes); // alrady checked the draw target above
|
||||
thebes->SetMatrix(gfxMatrix::Scaling(matrix._11, matrix._22));
|
||||
thebes->SetMatrix(Matrix::Scaling(matrix._11, matrix._22));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
|
||||
|
|
|
@ -95,7 +95,7 @@ DocumentRendererChild::RenderDocument(nsPIDOMWindowOuter* window,
|
|||
}
|
||||
RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(dt);
|
||||
MOZ_ASSERT(ctx); // already checked the draw target above
|
||||
ctx->SetMatrix(mozilla::gfx::ThebesMatrix(transform));
|
||||
ctx->SetMatrix(transform);
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
|
||||
shell->RenderDocument(documentRect, renderFlags, bgColor, ctx);
|
||||
|
|
|
@ -1294,10 +1294,11 @@ HTMLFormElement::AddElement(nsGenericHTMLFormElement* aChild,
|
|||
}
|
||||
*firstSubmitSlot = aChild;
|
||||
}
|
||||
NS_POSTCONDITION(mDefaultSubmitElement == mFirstSubmitInElements ||
|
||||
mDefaultSubmitElement == mFirstSubmitNotInElements ||
|
||||
!mDefaultSubmitElement,
|
||||
"What happened here?");
|
||||
|
||||
MOZ_ASSERT(mDefaultSubmitElement == mFirstSubmitInElements ||
|
||||
mDefaultSubmitElement == mFirstSubmitNotInElements ||
|
||||
!mDefaultSubmitElement,
|
||||
"What happened here?");
|
||||
|
||||
// Notify that the state of the previous default submit element has changed
|
||||
// if the element which is the default submit element has changed. The new
|
||||
|
@ -1430,9 +1431,9 @@ HTMLFormElement::HandleDefaultSubmitRemoval()
|
|||
mFirstSubmitInElements : mFirstSubmitNotInElements;
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(mDefaultSubmitElement == mFirstSubmitInElements ||
|
||||
mDefaultSubmitElement == mFirstSubmitNotInElements,
|
||||
"What happened here?");
|
||||
MOZ_ASSERT(mDefaultSubmitElement == mFirstSubmitInElements ||
|
||||
mDefaultSubmitElement == mFirstSubmitNotInElements,
|
||||
"What happened here?");
|
||||
|
||||
// Notify about change if needed.
|
||||
if (mDefaultSubmitElement) {
|
||||
|
|
|
@ -6937,7 +6937,7 @@ HTMLInputElement::GetValueMode() const
|
|||
case NS_FORM_INPUT_DATETIME_LOCAL:
|
||||
return VALUE_MODE_VALUE;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in GetValueMode()");
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected input type in GetValueMode()");
|
||||
return VALUE_MODE_VALUE;
|
||||
#else // DEBUG
|
||||
default:
|
||||
|
@ -6985,7 +6985,7 @@ HTMLInputElement::DoesReadOnlyApply() const
|
|||
case NS_FORM_INPUT_DATETIME_LOCAL:
|
||||
return true;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesReadOnlyApply()");
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected input type in DoesReadOnlyApply()");
|
||||
return true;
|
||||
#else // DEBUG
|
||||
default:
|
||||
|
@ -7025,7 +7025,7 @@ HTMLInputElement::DoesRequiredApply() const
|
|||
case NS_FORM_INPUT_DATETIME_LOCAL:
|
||||
return true;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesRequiredApply()");
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected input type in DoesRequiredApply()");
|
||||
return true;
|
||||
#else // DEBUG
|
||||
default:
|
||||
|
@ -7075,7 +7075,7 @@ HTMLInputElement::DoesMinMaxApply() const
|
|||
case NS_FORM_INPUT_COLOR:
|
||||
return false;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesRequiredApply()");
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected input type in DoesRequiredApply()");
|
||||
return false;
|
||||
#else // DEBUG
|
||||
default:
|
||||
|
@ -7115,7 +7115,7 @@ HTMLInputElement::DoesAutocompleteApply() const
|
|||
case NS_FORM_INPUT_FILE:
|
||||
return false;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesAutocompleteApply()");
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected input type in DoesAutocompleteApply()");
|
||||
return false;
|
||||
#else // DEBUG
|
||||
default:
|
||||
|
|
|
@ -2384,8 +2384,7 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
|
|||
// purpose. If the decision is made to permanently rely on the pref, this
|
||||
// should be changed so that it is required to restart firefox for the change
|
||||
// of value to take effect.
|
||||
shouldSandbox = (GetEffectiveContentSandboxLevel() > 0) &&
|
||||
!PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX");
|
||||
shouldSandbox = IsContentSandboxEnabled();
|
||||
|
||||
#ifdef XP_LINUX
|
||||
if (shouldSandbox) {
|
||||
|
|
|
@ -28,14 +28,6 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
|
||||
static bool
|
||||
IsSandboxTempDirRequired()
|
||||
{
|
||||
// On Windows, a sandbox-writable temp directory is only used
|
||||
// when sandbox pref level >= 1.
|
||||
return GetEffectiveContentSandboxLevel() >= 1;
|
||||
}
|
||||
|
||||
static void
|
||||
SetTmpEnvironmentVariable(nsIFile* aValue)
|
||||
{
|
||||
|
@ -55,13 +47,6 @@ SetTmpEnvironmentVariable(nsIFile* aValue)
|
|||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
static bool
|
||||
IsSandboxTempDirRequired()
|
||||
{
|
||||
// On OSX, use the sandbox-writable temp when the pref level >= 1.
|
||||
return (GetEffectiveContentSandboxLevel() >= 1);
|
||||
}
|
||||
|
||||
static void
|
||||
SetTmpEnvironmentVariable(nsIFile* aValue)
|
||||
{
|
||||
|
@ -81,7 +66,9 @@ SetUpSandboxEnvironment()
|
|||
MOZ_ASSERT(nsDirectoryService::gService,
|
||||
"SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
|
||||
|
||||
if (!IsSandboxTempDirRequired()) {
|
||||
// On macOS and Windows, a sandbox-writable temp directory is used whenever
|
||||
// the sandbox is enabled.
|
||||
if (!IsContentSandboxEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3482,7 +3482,7 @@ TabChild::AllocPPluginWidgetChild()
|
|||
#ifdef XP_WIN
|
||||
return new mozilla::plugins::PluginWidgetChild();
|
||||
#else
|
||||
MOZ_ASSERT_UNREACHABLE();
|
||||
MOZ_ASSERT_UNREACHABLE("AllocPPluginWidgetChild only supports Windows");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -3139,7 +3139,7 @@ TabParent::AllocPPluginWidgetParent()
|
|||
#ifdef XP_WIN
|
||||
return new mozilla::plugins::PluginWidgetParent();
|
||||
#else
|
||||
MOZ_ASSERT_UNREACHABLE();
|
||||
MOZ_ASSERT_UNREACHABLE("AllocPPluginWidgetParent only supports Windows");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -64,32 +64,38 @@ static nsTHashtable<nsRefPtrHashKey<MediaRecorder::Session>> gSessions;
|
|||
class MediaRecorderReporter final : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
MediaRecorderReporter() {};
|
||||
static MediaRecorderReporter* UniqueInstance();
|
||||
void InitMemoryReporter();
|
||||
|
||||
static void AddMediaRecorder(MediaRecorder *aRecorder)
|
||||
{
|
||||
GetRecorders().AppendElement(aRecorder);
|
||||
if (!sUniqueInstance) {
|
||||
sUniqueInstance = MakeAndAddRef<MediaRecorderReporter>();
|
||||
RegisterWeakAsyncMemoryReporter(sUniqueInstance);
|
||||
}
|
||||
sUniqueInstance->mRecorders.AppendElement(aRecorder);
|
||||
}
|
||||
|
||||
static void RemoveMediaRecorder(MediaRecorder *aRecorder)
|
||||
{
|
||||
RecordersArray& recorders = GetRecorders();
|
||||
recorders.RemoveElement(aRecorder);
|
||||
if (recorders.IsEmpty()) {
|
||||
if (!sUniqueInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
sUniqueInstance->mRecorders.RemoveElement(aRecorder);
|
||||
if (sUniqueInstance->mRecorders.IsEmpty()) {
|
||||
UnregisterWeakMemoryReporter(sUniqueInstance);
|
||||
sUniqueInstance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
MediaRecorderReporter() = default;
|
||||
|
||||
NS_IMETHOD
|
||||
CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData, bool aAnonymize) override
|
||||
{
|
||||
RecordersArray& recorders = GetRecorders();
|
||||
nsTArray<RefPtr<MediaRecorder::SizeOfPromise>> promises;
|
||||
for (const RefPtr<MediaRecorder>& recorder: recorders) {
|
||||
for (const RefPtr<MediaRecorder>& recorder: mRecorders) {
|
||||
promises.AppendElement(recorder->SizeOfExcludingThis(MallocSizeOf));
|
||||
}
|
||||
|
||||
|
@ -98,6 +104,12 @@ public:
|
|||
MediaRecorder::SizeOfPromise::All(GetCurrentThreadSerialEventTarget(), promises)
|
||||
->Then(GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[handleReport, data](const nsTArray<size_t>& sizes) {
|
||||
nsCOMPtr<nsIMemoryReporterManager> manager =
|
||||
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t sum = 0;
|
||||
for (const size_t& size : sizes) {
|
||||
sum += size;
|
||||
|
@ -108,6 +120,8 @@ public:
|
|||
KIND_HEAP, UNITS_BYTES, sum,
|
||||
NS_LITERAL_CSTRING("Memory used by media recorder."),
|
||||
data);
|
||||
|
||||
manager->EndReport();
|
||||
},
|
||||
[](size_t) { MOZ_CRASH("Unexpected reject"); });
|
||||
|
||||
|
@ -116,14 +130,15 @@ public:
|
|||
|
||||
private:
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
|
||||
virtual ~MediaRecorderReporter();
|
||||
static StaticRefPtr<MediaRecorderReporter> sUniqueInstance;
|
||||
typedef nsTArray<MediaRecorder*> RecordersArray;
|
||||
static RecordersArray& GetRecorders()
|
||||
|
||||
virtual ~MediaRecorderReporter()
|
||||
{
|
||||
return UniqueInstance()->mRecorders;
|
||||
MOZ_ASSERT(mRecorders.IsEmpty(), "All recorders must have been removed");
|
||||
}
|
||||
RecordersArray mRecorders;
|
||||
|
||||
static StaticRefPtr<MediaRecorderReporter> sUniqueInstance;
|
||||
|
||||
nsTArray<RefPtr<MediaRecorder>> mRecorders;
|
||||
};
|
||||
NS_IMPL_ISUPPORTS(MediaRecorderReporter, nsIMemoryReporter);
|
||||
|
||||
|
@ -1750,24 +1765,5 @@ MediaRecorder::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
|||
|
||||
StaticRefPtr<MediaRecorderReporter> MediaRecorderReporter::sUniqueInstance;
|
||||
|
||||
MediaRecorderReporter* MediaRecorderReporter::UniqueInstance()
|
||||
{
|
||||
if (!sUniqueInstance) {
|
||||
sUniqueInstance = new MediaRecorderReporter();
|
||||
sUniqueInstance->InitMemoryReporter();
|
||||
}
|
||||
return sUniqueInstance;
|
||||
}
|
||||
|
||||
void MediaRecorderReporter::InitMemoryReporter()
|
||||
{
|
||||
RegisterWeakAsyncMemoryReporter(this);
|
||||
}
|
||||
|
||||
MediaRecorderReporter::~MediaRecorderReporter()
|
||||
{
|
||||
UnregisterWeakMemoryReporter(this);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1411322: Shutdown after getting memory reports from MediaRecorder</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id="audio"></audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
let recorder = new MediaRecorder(audio.mozCaptureStream());
|
||||
recorder.start();
|
||||
SpecialPowers.getMemoryReports();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -96,6 +96,7 @@ load 1378826.html
|
|||
load 1384248.html
|
||||
load 1389304.html
|
||||
load 1393272.webm
|
||||
load 1411322.html
|
||||
load disconnect-wrong-destination.html
|
||||
load analyser-channels-1.html
|
||||
load audiocontext-double-suspend.html
|
||||
|
|
|
@ -2644,8 +2644,8 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
|||
|
||||
// Renderer::Draw() draws a rectangle with top-left at the aContext origin.
|
||||
gfxContextAutoSaveRestore autoSR(aContext);
|
||||
aContext->SetMatrix(
|
||||
aContext->CurrentMatrix().PreTranslate(pluginRect.TopLeft()));
|
||||
aContext->SetMatrixDouble(
|
||||
aContext->CurrentMatrixDouble().PreTranslate(pluginRect.TopLeft()));
|
||||
|
||||
Renderer renderer(window, this, pluginSize, pluginDirtyRect);
|
||||
|
||||
|
|
|
@ -793,7 +793,7 @@ nsXULTemplateQueryProcessorRDF::OnMove(nsIRDFDataSource* aDataSource,
|
|||
if (mUpdateBatchNest)
|
||||
return NS_OK;
|
||||
|
||||
NS_NOTYETIMPLEMENTED("write me");
|
||||
MOZ_ASSERT_UNREACHABLE("write me");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -474,7 +474,7 @@ GLXLibrary::AfterGLXCall() const
|
|||
sErrorEvent.mError.request_code,
|
||||
sErrorEvent.mError.minor_code,
|
||||
sErrorEvent.mError.serial);
|
||||
NS_ABORT();
|
||||
MOZ_ASSERT_UNREACHABLE("AfterGLXCall sErrorEvent");
|
||||
}
|
||||
XSetErrorHandler(sOldErrorHandler);
|
||||
}
|
||||
|
@ -1087,4 +1087,3 @@ GLContextProviderGLX::Shutdown()
|
|||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ SyncObjectClient::CreateSyncObjectClient(SyncHandle aHandle
|
|||
#ifdef XP_WIN
|
||||
return MakeAndAddRef<SyncObjectD3D11Client>(aHandle, aDevice);
|
||||
#else
|
||||
MOZ_ASSERT_UNREACHABLE();
|
||||
MOZ_ASSERT_UNREACHABLE("CreateSyncObjectClient only supports Windows");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
AutoRestoreTransform autoRestoreTransform(aDT);
|
||||
Matrix transform = aDT->GetTransform();
|
||||
RefPtr<gfxContext> context = gfxContext::CreateOrNull(aDT, aDeviceOffset);
|
||||
context->SetMatrix(ThebesMatrix(transform));
|
||||
context->SetMatrix(transform);
|
||||
|
||||
mItem->Paint(mBuilder, context);
|
||||
}
|
||||
|
|
|
@ -67,8 +67,8 @@ ClipToContain(gfxContext* aContext, const IntRect& aRect)
|
|||
gfxRect deviceRect = aContext->UserToDevice(userRect);
|
||||
deviceRect.RoundOut();
|
||||
|
||||
gfxMatrix currentMatrix = aContext->CurrentMatrix();
|
||||
aContext->SetMatrix(gfxMatrix());
|
||||
Matrix currentMatrix = aContext->CurrentMatrix();
|
||||
aContext->SetMatrix(Matrix());
|
||||
aContext->NewPath();
|
||||
aContext->Rectangle(deviceRect);
|
||||
aContext->Clip();
|
||||
|
@ -130,7 +130,7 @@ BasicLayerManager::PushGroupForLayer(gfxContext* aContext, Layer* aLayer, const
|
|||
// destination. Since the User->Device space transform will be applied
|
||||
// to the mask by PopGroupAndBlend we need to adjust the transform to
|
||||
// transform the mask to user space.
|
||||
Matrix currentTransform = ToMatrix(aGroupResult.mFinalTarget->CurrentMatrix());
|
||||
Matrix currentTransform = aGroupResult.mFinalTarget->CurrentMatrix();
|
||||
currentTransform.Invert();
|
||||
maskTransform = maskTransform * currentTransform;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ public:
|
|||
// it applies an identity.
|
||||
void Apply2DTransform()
|
||||
{
|
||||
mTarget->SetMatrix(ThebesMatrix(mTransform));
|
||||
mTarget->SetMatrix(mTransform);
|
||||
}
|
||||
|
||||
// Set the opaque rect to match the bounds of the visible region.
|
||||
|
@ -591,7 +591,7 @@ BasicLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
|
|||
} else {
|
||||
mSnapEffectiveTransforms = true;
|
||||
}
|
||||
mRoot->ComputeEffectiveTransforms(mTarget ? Matrix4x4::From2D(ToMatrix(mTarget->CurrentMatrix())) : Matrix4x4());
|
||||
mRoot->ComputeEffectiveTransforms(mTarget ? Matrix4x4::From2D(mTarget->CurrentMatrix()) : Matrix4x4());
|
||||
|
||||
ToData(mRoot)->Validate(aCallback, aCallbackData, nullptr);
|
||||
if (mRoot->GetMaskLayer()) {
|
||||
|
@ -788,9 +788,9 @@ InstallLayerClipPreserves3D(gfxContext* aTarget, Layer* aLayer)
|
|||
if (!transform3d.CanDraw2D(&transform)) {
|
||||
gfxDevCrash(LogReason::CannotDraw3D) << "GFX: We should not have a 3D transform that CanDraw2D() is false!";
|
||||
}
|
||||
gfxMatrix oldTransform = aTarget->CurrentMatrix();
|
||||
transform *= ToMatrix(oldTransform);
|
||||
aTarget->SetMatrix(ThebesMatrix(transform));
|
||||
Matrix oldTransform = aTarget->CurrentMatrix();
|
||||
transform *= oldTransform;
|
||||
aTarget->SetMatrix(transform);
|
||||
|
||||
aTarget->NewPath();
|
||||
aTarget->SnappedRectangle(gfxRect(clipRect->x, clipRect->y,
|
||||
|
|
|
@ -64,7 +64,7 @@ PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
|
|||
{
|
||||
AutoMoz2DMaskData mask;
|
||||
if (GetMaskData(aMaskLayer, Point(), &mask)) {
|
||||
aContext->SetMatrix(ThebesMatrix(mask.GetTransform()));
|
||||
aContext->SetMatrix(mask.GetTransform());
|
||||
aContext->Mask(mask.GetSurface(), aOpacity);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -991,7 +991,7 @@ void ClientMultiTiledLayerBuffer::Update(const nsIntRegion& newValidRegion,
|
|||
RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(drawTarget);
|
||||
MOZ_ASSERT(ctx); // already checked the draw target above
|
||||
ctx->SetMatrix(
|
||||
ctx->CurrentMatrix().PreScale(mResolution, mResolution).PreTranslate(ThebesPoint(-mTilingOrigin)));
|
||||
ctx->CurrentMatrix().PreScale(mResolution, mResolution).PreTranslate(-mTilingOrigin));
|
||||
|
||||
mCallback(&mPaintedLayer, ctx, paintRegion, dirtyRegion,
|
||||
DrawRegionClip::DRAW, nsIntRegion(), mCallbackData);
|
||||
|
|
|
@ -426,7 +426,7 @@ nsDeviceContext::CreateRenderingContextCommon(bool aWantReferenceContext)
|
|||
}
|
||||
transform.PreScale(mPrintingScale, mPrintingScale);
|
||||
|
||||
pContext->SetMatrix(transform);
|
||||
pContext->SetMatrixDouble(transform);
|
||||
return pContext.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ gfxAlphaBoxBlur::Init(gfxContext* aDestinationCtx,
|
|||
|
||||
RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
|
||||
MOZ_ASSERT(context); // already checked for target above
|
||||
context->SetMatrix(gfxMatrix::Translation(-mBlur.GetRect().TopLeft()));
|
||||
context->SetMatrix(Matrix::Translation(-mBlur.GetRect().TopLeft()));
|
||||
return context.forget();
|
||||
}
|
||||
|
||||
|
@ -588,7 +588,7 @@ GetBlur(gfxContext* aDestinationCtx,
|
|||
// since our source image is only 1px for some parts, we make thousands of calls.
|
||||
// Instead just render the blur ourself here as one image and send it over for printing.
|
||||
// TODO: May need to change this with the blob renderer in WR since it also records.
|
||||
Matrix destMatrix = ToMatrix(aDestinationCtx->CurrentMatrix());
|
||||
Matrix destMatrix = aDestinationCtx->CurrentMatrix();
|
||||
bool useDestRect = !destMatrix.IsRectilinear() || destMatrix.HasNonIntegerTranslation() ||
|
||||
aDestinationCtx->GetDrawTarget()->IsRecording();
|
||||
if (useDestRect) {
|
||||
|
|
|
@ -112,7 +112,7 @@ gfxContext::CreatePreservingTransformOrNull(DrawTarget* aTarget)
|
|||
|
||||
Matrix transform = aTarget->GetTransform();
|
||||
RefPtr<gfxContext> result = new gfxContext(aTarget);
|
||||
result->SetMatrix(ThebesMatrix(transform));
|
||||
result->SetMatrix(transform);
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
|
@ -318,16 +318,28 @@ gfxContext::Multiply(const gfxMatrix& matrix)
|
|||
}
|
||||
|
||||
void
|
||||
gfxContext::SetMatrix(const gfxMatrix& matrix)
|
||||
gfxContext::SetMatrix(const gfx::Matrix& matrix)
|
||||
{
|
||||
CURRENTSTATE_CHANGED()
|
||||
ChangeTransform(ToMatrix(matrix));
|
||||
ChangeTransform(matrix);
|
||||
}
|
||||
|
||||
void
|
||||
gfxContext::SetMatrixDouble(const gfxMatrix& matrix)
|
||||
{
|
||||
SetMatrix(ToMatrix(matrix));
|
||||
}
|
||||
|
||||
gfx::Matrix
|
||||
gfxContext::CurrentMatrix() const
|
||||
{
|
||||
return mTransform;
|
||||
}
|
||||
|
||||
gfxMatrix
|
||||
gfxContext::CurrentMatrix() const
|
||||
gfxContext::CurrentMatrixDouble() const
|
||||
{
|
||||
return ThebesMatrix(mTransform);
|
||||
return ThebesMatrix(CurrentMatrix());
|
||||
}
|
||||
|
||||
gfxPoint
|
||||
|
|
|
@ -172,12 +172,14 @@ public:
|
|||
/**
|
||||
* Replaces the current transformation matrix with matrix.
|
||||
*/
|
||||
void SetMatrix(const gfxMatrix& matrix);
|
||||
void SetMatrix(const mozilla::gfx::Matrix& matrix);
|
||||
void SetMatrixDouble(const gfxMatrix& matrix);
|
||||
|
||||
/**
|
||||
* Returns the current transformation matrix.
|
||||
*/
|
||||
gfxMatrix CurrentMatrix() const;
|
||||
mozilla::gfx::Matrix CurrentMatrix() const;
|
||||
gfxMatrix CurrentMatrixDouble() const;
|
||||
|
||||
/**
|
||||
* Converts a point from device to user coordinates using the inverse
|
||||
|
@ -628,7 +630,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
const gfxMatrix& Matrix()
|
||||
const mozilla::gfx::Matrix& Matrix()
|
||||
{
|
||||
MOZ_ASSERT(mContext, "mMatrix doesn't contain a useful matrix");
|
||||
return mMatrix;
|
||||
|
@ -638,7 +640,7 @@ public:
|
|||
|
||||
private:
|
||||
gfxContext *mContext;
|
||||
gfxMatrix mMatrix;
|
||||
mozilla::gfx::Matrix mMatrix;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1679,7 +1679,7 @@ private:
|
|||
fillPattern =
|
||||
mFontParams.contextPaint->GetFillPattern(
|
||||
mRunParams.context->GetDrawTarget(),
|
||||
mRunParams.context->CurrentMatrix(),
|
||||
mRunParams.context->CurrentMatrixDouble(),
|
||||
imgParams);
|
||||
}
|
||||
if (!fillPattern) {
|
||||
|
@ -2163,7 +2163,7 @@ gfxFont::Draw(const gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
gfx::ShapedTextFlags::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT)
|
||||
? -M_PI / 2.0 : M_PI / 2.0;
|
||||
gfxMatrix mat =
|
||||
aRunParams.context->CurrentMatrix().
|
||||
aRunParams.context->CurrentMatrixDouble().
|
||||
PreTranslate(p). // translate origin for rotation
|
||||
PreRotate(rotation). // turn 90deg CCW (sideways-left) or CW (*-right)
|
||||
PreTranslate(-p); // undo the translation
|
||||
|
@ -2182,7 +2182,7 @@ gfxFont::Draw(const gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
mat.PreTranslate(baseAdj);
|
||||
}
|
||||
|
||||
aRunParams.context->SetMatrix(mat);
|
||||
aRunParams.context->SetMatrixDouble(mat);
|
||||
}
|
||||
|
||||
RefPtr<SVGContextPaint> contextPaint;
|
||||
|
@ -2193,7 +2193,7 @@ gfxFont::Draw(const gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
RefPtr<gfxPattern> fillPattern = aRunParams.context->GetPattern();
|
||||
contextPaint =
|
||||
new SimpleTextContextPaint(fillPattern, nullptr,
|
||||
aRunParams.context->CurrentMatrix());
|
||||
aRunParams.context->CurrentMatrixDouble());
|
||||
fontParams.contextPaint = contextPaint.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -438,8 +438,8 @@ PrescaleAndTileDrawable(gfxDrawable* aDrawable,
|
|||
gfxFloat aOpacity,
|
||||
ExtendMode aExtendMode)
|
||||
{
|
||||
gfxSize scaleFactor = aContext->CurrentMatrix().ScaleFactors(true);
|
||||
gfxMatrix scaleMatrix = gfxMatrix::Scaling(scaleFactor.width, scaleFactor.height);
|
||||
Size scaleFactor = aContext->CurrentMatrix().ScaleFactors(true);
|
||||
Matrix scaleMatrix = Matrix::Scaling(scaleFactor.width, scaleFactor.height);
|
||||
const float fuzzFactor = 0.01;
|
||||
|
||||
// If we aren't scaling or translating, don't go down this path
|
||||
|
@ -456,13 +456,13 @@ PrescaleAndTileDrawable(gfxDrawable* aDrawable,
|
|||
clipExtents.Inflate(1.0);
|
||||
|
||||
gfxRect needed = aRegion.IntersectAndRestrict(clipExtents);
|
||||
Rect scaledNeededRect = ToMatrix(scaleMatrix).TransformBounds(ToRect(needed));
|
||||
Rect scaledNeededRect = scaleMatrix.TransformBounds(ToRect(needed));
|
||||
scaledNeededRect.RoundOut();
|
||||
if (scaledNeededRect.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Rect scaledImageRect = ToMatrix(scaleMatrix).TransformBounds(aImageRect);
|
||||
Rect scaledImageRect = scaleMatrix.TransformBounds(aImageRect);
|
||||
if (!ShouldUseTempSurface(scaledImageRect, scaledNeededRect)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -485,7 +485,7 @@ PrescaleAndTileDrawable(gfxDrawable* aDrawable,
|
|||
RefPtr<gfxContext> tmpCtx = gfxContext::CreateOrNull(scaledDT);
|
||||
MOZ_ASSERT(tmpCtx); // already checked the target above
|
||||
|
||||
scaledDT->SetTransform(ToMatrix(scaleMatrix));
|
||||
scaledDT->SetTransform(scaleMatrix);
|
||||
gfxRect gfxImageRect(aImageRect.x, aImageRect.y, aImageRect.width, aImageRect.height);
|
||||
|
||||
// Since this is just the scaled image, we don't want to repeat anything yet.
|
||||
|
@ -495,12 +495,12 @@ PrescaleAndTileDrawable(gfxDrawable* aDrawable,
|
|||
|
||||
{
|
||||
gfxContextMatrixAutoSaveRestore autoSR(aContext);
|
||||
Matrix withoutScale = ToMatrix(aContext->CurrentMatrix());
|
||||
Matrix withoutScale = aContext->CurrentMatrix();
|
||||
DrawTarget* destDrawTarget = aContext->GetDrawTarget();
|
||||
|
||||
// The translation still is in scaled units
|
||||
withoutScale.PreScale(1.0 / scaleFactor.width, 1.0 / scaleFactor.height);
|
||||
aContext->SetMatrix(ThebesMatrix(withoutScale));
|
||||
aContext->SetMatrix(withoutScale);
|
||||
|
||||
DrawOptions drawOptions(aOpacity, aContext->CurrentOp(),
|
||||
aContext->CurrentAntialiasMode());
|
||||
|
|
|
@ -68,7 +68,7 @@ gfxWindowsNativeDrawing::BeginNativeDrawing()
|
|||
if (surf && surf->CairoStatus() != 0)
|
||||
return nullptr;
|
||||
|
||||
gfxMatrix m = mContext->CurrentMatrix();
|
||||
gfxMatrix m = mContext->CurrentMatrixDouble();
|
||||
if (!m.HasNonTranslation())
|
||||
mTransformType = TRANSLATION_ONLY;
|
||||
else if (m.HasNonAxisAlignedTransform())
|
||||
|
|
|
@ -467,7 +467,7 @@ void
|
|||
gfxXlibNativeRenderer::Draw(gfxContext* ctx, IntSize size,
|
||||
uint32_t flags, Screen *screen, Visual *visual)
|
||||
{
|
||||
gfxMatrix matrix = ctx->CurrentMatrix();
|
||||
Matrix matrix = ctx->CurrentMatrix();
|
||||
|
||||
// We can only draw direct or onto a copied background if pixels align and
|
||||
// native drawing is compatible with the current operator. (The matrix is
|
||||
|
|
|
@ -302,10 +302,10 @@ SVGDrawingCallback::operator()(gfxContext* aContext,
|
|||
if (!matrix.Invert()) {
|
||||
return false;
|
||||
}
|
||||
aContext->SetMatrix(
|
||||
aContext->CurrentMatrix().PreMultiply(matrix).
|
||||
PreScale(double(mSize.width) / mViewportSize.width,
|
||||
double(mSize.height) / mViewportSize.height));
|
||||
aContext->SetMatrixDouble(
|
||||
aContext->CurrentMatrixDouble().PreMultiply(matrix).
|
||||
PreScale(double(mSize.width) / mViewportSize.width,
|
||||
double(mSize.height) / mViewportSize.height));
|
||||
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
MOZ_ASSERT(presContext, "pres shell w/out pres context");
|
||||
|
|
|
@ -950,8 +950,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
|||
switch (mProcessType) {
|
||||
case GeckoProcessType_Content:
|
||||
# if defined(MOZ_CONTENT_SANDBOX)
|
||||
if (mSandboxLevel > 0 &&
|
||||
!PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX")) {
|
||||
if (mSandboxLevel > 0) {
|
||||
// For now we treat every failure as fatal in SetSecurityLevelForContentProcess
|
||||
// and just crash there right away. Should this change in the future then we
|
||||
// should also handle the error here.
|
||||
|
|
|
@ -4685,10 +4685,10 @@ PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags,
|
|||
// slight rounding errors here. We use NudgeToIntegers() here to adjust
|
||||
// matrix components that are integers up to the accuracy of floats to be
|
||||
// those integers.
|
||||
gfxMatrix newTM = aThebesContext->CurrentMatrix().PreTranslate(offset).
|
||||
PreScale(scale, scale).
|
||||
NudgeToIntegers();
|
||||
aThebesContext->SetMatrix(newTM);
|
||||
gfxMatrix newTM = aThebesContext->CurrentMatrixDouble().PreTranslate(offset).
|
||||
PreScale(scale, scale).
|
||||
NudgeToIntegers();
|
||||
aThebesContext->SetMatrixDouble(newTM);
|
||||
|
||||
AutoSaveRestoreRenderingState _(this);
|
||||
|
||||
|
@ -5088,7 +5088,7 @@ PresShell::PaintRangePaintInfo(const nsTArray<UniquePtr<RangePaintInfo>>& aItems
|
|||
ctx->Clip(path);
|
||||
}
|
||||
|
||||
gfxMatrix initialTM = ctx->CurrentMatrix();
|
||||
gfxMatrix initialTM = ctx->CurrentMatrixDouble();
|
||||
|
||||
if (resize)
|
||||
initialTM.PreScale(scale, scale);
|
||||
|
@ -5118,7 +5118,7 @@ PresShell::PaintRangePaintInfo(const nsTArray<UniquePtr<RangePaintInfo>>& aItems
|
|||
gfxPoint rootOffset =
|
||||
nsLayoutUtils::PointToGfxPoint(rangeInfo->mRootOffset,
|
||||
pc->AppUnitsPerDevPixel());
|
||||
ctx->SetMatrix(gfxMatrix(initialTM).PreTranslate(rootOffset));
|
||||
ctx->SetMatrixDouble(initialTM.PreTranslate(rootOffset));
|
||||
aArea.MoveBy(-rangeInfo->mRootOffset.x, -rangeInfo->mRootOffset.y);
|
||||
nsRegion visible(aArea);
|
||||
RefPtr<LayerManager> layerManager =
|
||||
|
@ -10144,8 +10144,8 @@ void ReflowCountMgr::PaintCount(const char* aName,
|
|||
aRenderingContext->Save();
|
||||
gfxPoint devPixelOffset =
|
||||
nsLayoutUtils::PointToGfxPoint(aOffset, appUnitsPerDevPixel);
|
||||
aRenderingContext->SetMatrix(
|
||||
aRenderingContext->CurrentMatrix().PreTranslate(devPixelOffset));
|
||||
aRenderingContext->SetMatrixDouble(
|
||||
aRenderingContext->CurrentMatrixDouble().PreTranslate(devPixelOffset));
|
||||
|
||||
// We don't care about the document language or user fonts here;
|
||||
// just get a default Latin font.
|
||||
|
|
|
@ -1518,7 +1518,7 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
|
|||
}
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(aFrameItems.IsEmpty(), "How did that happen?");
|
||||
MOZ_ASSERT(aFrameItems.IsEmpty(), "How did that happen?");
|
||||
}
|
||||
|
||||
|
||||
|
@ -9374,7 +9374,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
|
|||
newFrame->SetNextContinuation(nextContinuation);
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(!newFrame->GetNextSibling(), "unexpected sibling");
|
||||
MOZ_ASSERT(!newFrame->GetNextSibling(), "unexpected sibling");
|
||||
return newFrame;
|
||||
}
|
||||
|
||||
|
@ -13207,7 +13207,7 @@ Iterator::AppendItemsToList(nsCSSFrameConstructor* aFCtor, const Iterator& aEnd,
|
|||
|
||||
// Point ourselves to aEnd, as advertised
|
||||
SetToEnd();
|
||||
NS_POSTCONDITION(*this == aEnd, "How did that happen?");
|
||||
MOZ_ASSERT(*this == aEnd, "How did that happen?");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -13222,7 +13222,7 @@ Iterator::InsertItem(FrameConstructionItem* aItem)
|
|||
}
|
||||
mList.AdjustCountsForItem(aItem, 1);
|
||||
|
||||
NS_POSTCONDITION(aItem->getNext() == mCurrent, "How did that happen?");
|
||||
MOZ_ASSERT(aItem->getNext() == mCurrent, "How did that happen?");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1627,7 +1627,7 @@ nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
|
|||
if (!found) {
|
||||
found = parent->GetChildList(nsIFrame::kOverflowList)
|
||||
.ContainsFrame(aChildFrame);
|
||||
NS_POSTCONDITION(found, "not in child list");
|
||||
MOZ_ASSERT(found, "not in child list");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3728,8 +3728,8 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||
gfxPoint devPixelOffset =
|
||||
nsLayoutUtils::PointToGfxPoint(pos,
|
||||
presContext->AppUnitsPerDevPixel());
|
||||
aRenderingContext->SetMatrix(
|
||||
aRenderingContext->CurrentMatrix().PreTranslate(devPixelOffset));
|
||||
aRenderingContext->SetMatrixDouble(
|
||||
aRenderingContext->CurrentMatrixDouble().PreTranslate(devPixelOffset));
|
||||
}
|
||||
}
|
||||
builder.SetIgnoreScrollFrame(rootScrollFrame);
|
||||
|
@ -6674,7 +6674,7 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx,
|
|||
gfxRect devPixelDirty =
|
||||
nsLayoutUtils::RectToGfxRect(aDirty, aAppUnitsPerDevPixel);
|
||||
|
||||
gfxMatrix currentMatrix = aCtx->CurrentMatrix();
|
||||
gfxMatrix currentMatrix = aCtx->CurrentMatrixDouble();
|
||||
gfxRect fill = devPixelFill;
|
||||
gfxRect dest = devPixelDest;
|
||||
bool didSnap;
|
||||
|
@ -6901,7 +6901,7 @@ DrawImageInternal(gfxContext& aContext,
|
|||
{
|
||||
gfxContextMatrixAutoSaveRestore contextMatrixRestorer(&aContext);
|
||||
|
||||
aContext.SetMatrix(params.imageSpaceToDeviceSpace);
|
||||
aContext.SetMatrixDouble(params.imageSpaceToDeviceSpace);
|
||||
|
||||
Maybe<SVGImageContext> fallbackContext;
|
||||
if (!aSVGContext) {
|
||||
|
|
|
@ -2564,6 +2564,6 @@ nsListEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
|||
return mFrame->nsListControlFrame::MouseMove(aEvent);
|
||||
}
|
||||
|
||||
NS_ABORT();
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected eventType");
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1315,7 +1315,7 @@ nsContainerFrame::StealFrame(nsIFrame* aChild)
|
|||
}
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(removed, "StealFrame: can't find aChild");
|
||||
MOZ_ASSERT(removed, "StealFrame: can't find aChild");
|
||||
return removed ? NS_OK : NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
|
@ -1430,7 +1430,7 @@ nsContainerFrame::DeleteNextInFlowChild(nsIFrame* aNextInFlow,
|
|||
// remove it from its next-in-flow/prev-in-flow chain.
|
||||
aNextInFlow->Destroy();
|
||||
|
||||
NS_POSTCONDITION(!prevInFlow->GetNextInFlow(), "non null next-in-flow");
|
||||
MOZ_ASSERT(!prevInFlow->GetNextInFlow(), "non null next-in-flow");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6526,7 +6526,8 @@ nsIFrame* nsIFrame::GetTailContinuation()
|
|||
next = frame->GetNextContinuation()) {
|
||||
frame = next;
|
||||
}
|
||||
NS_POSTCONDITION(frame, "illegal state in continuation chain.");
|
||||
|
||||
MOZ_ASSERT(frame, "illegal state in continuation chain.");
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@ nsFrameList::ExtractTail(FrameLinkEnumerator& aLink)
|
|||
// Now make sure aLink doesn't point to a frame we no longer have.
|
||||
aLink.mFrame = nullptr;
|
||||
|
||||
NS_POSTCONDITION(aLink.AtEnd(), "What's going on here?");
|
||||
MOZ_ASSERT(aLink.AtEnd(), "What's going on here?");
|
||||
|
||||
return nsFrameList(newFirstFrame, newLastFrame);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/HTMLTextAreaElement.h"
|
||||
#include <stdint.h>
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
|
@ -2185,6 +2186,7 @@ ScrollFrameHelper::CompleteAsyncScroll(const nsRect &aRange, nsAtom* aOrigin)
|
|||
// We are done scrolling, set our destination to wherever we actually ended
|
||||
// up scrolling to.
|
||||
mDestination = GetScrollPosition();
|
||||
FireScrollEndEvent();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -4408,6 +4410,17 @@ ScrollFrameHelper::FireScrollPortEvent()
|
|||
mOuter->PresContext(), &event);
|
||||
}
|
||||
|
||||
void
|
||||
ScrollFrameHelper::FireScrollEndEvent()
|
||||
{
|
||||
MOZ_ASSERT(mOuter->GetContent());
|
||||
nsContentUtils::DispatchEventOnlyToChrome(mOuter->GetContent()->OwnerDoc(),
|
||||
mOuter->GetContent(),
|
||||
NS_LITERAL_STRING("scrollend"),
|
||||
true /* aCanBubble */,
|
||||
false /* aCancelable */);
|
||||
}
|
||||
|
||||
void
|
||||
ScrollFrameHelper::ReloadChildFrames()
|
||||
{
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
nsTArray<nsIAnonymousContentCreator::ContentInfo>& aElements);
|
||||
void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter);
|
||||
nsresult FireScrollPortEvent();
|
||||
void FireScrollEndEvent();
|
||||
void PostOverflowEvent();
|
||||
using PostDestroyData = nsIFrame::PostDestroyData;
|
||||
void Destroy(PostDestroyData& aPostDestroyData);
|
||||
|
@ -400,6 +401,9 @@ public:
|
|||
nsExpirationState* GetExpirationState() { return &mActivityExpirationState; }
|
||||
|
||||
void SetTransformingByAPZ(bool aTransforming) {
|
||||
if (mTransformingByAPZ && !aTransforming) {
|
||||
FireScrollEndEvent();
|
||||
}
|
||||
mTransformingByAPZ = aTransforming;
|
||||
if (!mozilla::css::TextOverflow::HasClippedOverflow(mOuter)) {
|
||||
// If the block has some text-overflow stuff we should kick off a paint
|
||||
|
|
|
@ -871,7 +871,7 @@ nsPluginFrame::PaintPrintPlugin(nsIFrame* aFrame, gfxContext* aCtx,
|
|||
nsLayoutUtils::PointToGfxPoint(pt, aFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
|
||||
gfxContextMatrixAutoSaveRestore autoSR(aCtx);
|
||||
aCtx->SetMatrix(aCtx->CurrentMatrix().PreTranslate(devPixelPt));
|
||||
aCtx->SetMatrixDouble(aCtx->CurrentMatrixDouble().PreTranslate(devPixelPt));
|
||||
|
||||
// FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
|
||||
|
||||
|
|
|
@ -606,7 +606,8 @@ ClearAllTextRunReferences(nsTextFrame* aFrame, gfxTextRun* aTextRun,
|
|||
}
|
||||
aFrame = aFrame->GetNextContinuation();
|
||||
}
|
||||
NS_POSTCONDITION(!found || aStartContinuation, "how did we find null?");
|
||||
|
||||
MOZ_ASSERT(!found || aStartContinuation, "how did we find null?");
|
||||
return found;
|
||||
}
|
||||
|
||||
|
@ -5190,9 +5191,9 @@ nsDisplayText::RenderToContext(gfxContext* aCtx, nsDisplayListBuilder* aBuilder,
|
|||
// necessary. This is done here because we want selection be
|
||||
// compressed at the same time as text.
|
||||
gfxPoint pt = nsLayoutUtils::PointToGfxPoint(framePt, A2D);
|
||||
gfxMatrix mat = aCtx->CurrentMatrix()
|
||||
gfxMatrix mat = aCtx->CurrentMatrixDouble()
|
||||
.PreTranslate(pt).PreScale(scaleFactor, 1.0).PreTranslate(-pt);
|
||||
aCtx->SetMatrix (mat);
|
||||
aCtx->SetMatrixDouble(mat);
|
||||
}
|
||||
}
|
||||
nsTextFrame::PaintTextParams params(aCtx);
|
||||
|
@ -7240,10 +7241,10 @@ nsTextFrame::DrawTextRunAndDecorations(Range aRange,
|
|||
float scaleFactor = GetTextCombineScaleFactor(this);
|
||||
if (scaleFactor != 1.0f) {
|
||||
scaledRestorer.SetContext(aParams.context);
|
||||
gfxMatrix unscaled = aParams.context->CurrentMatrix();
|
||||
gfxMatrix unscaled = aParams.context->CurrentMatrixDouble();
|
||||
gfxPoint pt(x / app, y / app);
|
||||
unscaled.PreTranslate(pt).PreScale(1.0f / scaleFactor, 1.0f).PreTranslate(-pt);
|
||||
aParams.context->SetMatrix(unscaled);
|
||||
aParams.context->SetMatrixDouble(unscaled);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9098,9 +9099,11 @@ nsTextFrame::SetLength(int32_t aLength, nsLineLayout* aLineLayout,
|
|||
}
|
||||
f = next;
|
||||
}
|
||||
NS_POSTCONDITION(!framesToRemove || (f && f->mContentOffset == end),
|
||||
"How did we exit the loop if we null out framesToRemove if "
|
||||
"!next || next->mContentOffset > end ?");
|
||||
|
||||
MOZ_ASSERT(!framesToRemove || (f && f->mContentOffset == end),
|
||||
"How did we exit the loop if we null out framesToRemove if "
|
||||
"!next || next->mContentOffset > end ?");
|
||||
|
||||
if (framesToRemove) {
|
||||
// We are guaranteed that we exited the loop with f not null, per the
|
||||
// postcondition above
|
||||
|
|
|
@ -2025,16 +2025,16 @@ nsMathMLChar::ApplyTransforms(gfxContext* aThebesContext,
|
|||
nsPoint pt = r.TopRight();
|
||||
gfxPoint devPixelOffset(NSAppUnitsToFloatPixels(pt.x, aAppUnitsPerGfxUnit),
|
||||
NSAppUnitsToFloatPixels(pt.y, aAppUnitsPerGfxUnit));
|
||||
aThebesContext->SetMatrix(
|
||||
aThebesContext->CurrentMatrix().PreTranslate(devPixelOffset).
|
||||
PreScale(-mScaleX, mScaleY));
|
||||
aThebesContext->SetMatrixDouble(
|
||||
aThebesContext->CurrentMatrixDouble().PreTranslate(devPixelOffset).
|
||||
PreScale(-mScaleX, mScaleY));
|
||||
} else {
|
||||
nsPoint pt = r.TopLeft();
|
||||
gfxPoint devPixelOffset(NSAppUnitsToFloatPixels(pt.x, aAppUnitsPerGfxUnit),
|
||||
NSAppUnitsToFloatPixels(pt.y, aAppUnitsPerGfxUnit));
|
||||
aThebesContext->SetMatrix(
|
||||
aThebesContext->CurrentMatrix().PreTranslate(devPixelOffset).
|
||||
PreScale(mScaleX, mScaleY));
|
||||
aThebesContext->SetMatrixDouble(
|
||||
aThebesContext->CurrentMatrixDouble().PreTranslate(devPixelOffset).
|
||||
PreScale(mScaleX, mScaleY));
|
||||
}
|
||||
|
||||
// update the bounding rectangle.
|
||||
|
|
|
@ -274,7 +274,7 @@ nsMathMLmactionFrame::MouseListener::HandleEvent(nsIDOMEvent* aEvent)
|
|||
mOwner->MouseOut();
|
||||
}
|
||||
else {
|
||||
NS_ABORT();
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected eventType");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -3684,8 +3684,8 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
|
|||
gfxDevCrash(LogReason::InvalidContext) << "PaintInactive context problem " << gfx::hexa(tempDT);
|
||||
return;
|
||||
}
|
||||
context->SetMatrix(gfxMatrix::Translation(-itemVisibleRect.x,
|
||||
-itemVisibleRect.y));
|
||||
context->SetMatrix(Matrix::Translation(-itemVisibleRect.x,
|
||||
-itemVisibleRect.y));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -3914,7 +3914,7 @@ ContainerState::SetupMaskLayerForCSSMask(Layer* aLayer,
|
|||
}
|
||||
|
||||
RefPtr<gfxContext> maskCtx = gfxContext::CreateOrNull(dt);
|
||||
maskCtx->SetMatrix(gfxMatrix::Translation(-itemRect.TopLeft()));
|
||||
maskCtx->SetMatrix(Matrix::Translation(-itemRect.TopLeft()));
|
||||
maskCtx->Multiply(gfxMatrix::Scaling(mParameters.mXScale, mParameters.mYScale));
|
||||
|
||||
bool isPaintFinished = aMaskItem->PaintMask(mBuilder, maskCtx);
|
||||
|
@ -5889,7 +5889,7 @@ static void DebugPaintItem(DrawTarget& aDrawTarget,
|
|||
gfxDevCrash(LogReason::InvalidContext) << "DebugPaintItem context problem " << gfx::hexa(tempDT);
|
||||
return;
|
||||
}
|
||||
context->SetMatrix(gfxMatrix::Translation(-bounds.x, -bounds.y));
|
||||
context->SetMatrix(Matrix::Translation(-bounds.x, -bounds.y));
|
||||
|
||||
aItem->Paint(aBuilder, context);
|
||||
RefPtr<SourceSurface> surface = tempDT->Snapshot();
|
||||
|
@ -6177,9 +6177,9 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
|
|||
// Apply the residual transform if it has been enabled, to ensure that
|
||||
// snapping when we draw into aContext exactly matches the ideal transform.
|
||||
// See above for why this is OK.
|
||||
aContext->SetMatrix(
|
||||
aContext->CurrentMatrix().PreTranslate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y)).
|
||||
PreScale(userData->mXScale, userData->mYScale));
|
||||
aContext->SetMatrixDouble(
|
||||
aContext->CurrentMatrixDouble().PreTranslate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y)).
|
||||
PreScale(userData->mXScale, userData->mYScale));
|
||||
|
||||
layerBuilder->PaintItems(entry->mItems, iterRect, aContext,
|
||||
builder, presContext,
|
||||
|
@ -6193,9 +6193,9 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
|
|||
// Apply the residual transform if it has been enabled, to ensure that
|
||||
// snapping when we draw into aContext exactly matches the ideal transform.
|
||||
// See above for why this is OK.
|
||||
aContext->SetMatrix(
|
||||
aContext->CurrentMatrix().PreTranslate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y)).
|
||||
PreScale(userData->mXScale,userData->mYScale));
|
||||
aContext->SetMatrixDouble(
|
||||
aContext->CurrentMatrixDouble().PreTranslate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y)).
|
||||
PreScale(userData->mXScale,userData->mYScale));
|
||||
|
||||
layerBuilder->PaintItems(entry->mItems, aRegionToDraw.GetBounds(), aContext,
|
||||
builder, presContext,
|
||||
|
|
|
@ -1685,8 +1685,8 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
|
|||
nsLayoutUtils::PointToGfxPoint(nsPoint(shadowItem->mXOffset,
|
||||
shadowItem->mYOffset),
|
||||
aPresContext->AppUnitsPerDevPixel());
|
||||
shadowContext->SetMatrix(
|
||||
shadowContext->CurrentMatrix().PreTranslate(devPixelOffset));
|
||||
shadowContext->SetMatrixDouble(
|
||||
shadowContext->CurrentMatrixDouble().PreTranslate(devPixelOffset));
|
||||
|
||||
nsRect nativeRect = aDirtyRect;
|
||||
nativeRect.MoveBy(-nsPoint(shadowItem->mXOffset, shadowItem->mYOffset));
|
||||
|
@ -4479,7 +4479,7 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius,
|
|||
nsLayoutUtils::RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel);
|
||||
dirtyRect.RoundOut();
|
||||
|
||||
gfxMatrix transform = aDestinationCtx->CurrentMatrix();
|
||||
gfxMatrix transform = aDestinationCtx->CurrentMatrixDouble();
|
||||
rect = transform.TransformBounds(rect);
|
||||
|
||||
mPreTransformed = !transform.IsIdentity();
|
||||
|
@ -4516,7 +4516,7 @@ nsContextBoxBlur::DoPaint()
|
|||
gfxContextMatrixAutoSaveRestore saveMatrix(mDestinationCtx);
|
||||
|
||||
if (mPreTransformed) {
|
||||
mDestinationCtx->SetMatrix(gfxMatrix());
|
||||
mDestinationCtx->SetMatrix(Matrix());
|
||||
}
|
||||
|
||||
mAlphaBoxBlur.Paint(mDestinationCtx);
|
||||
|
@ -4577,12 +4577,12 @@ nsContextBoxBlur::BlurRectangle(gfxContext* aDestinationCtx,
|
|||
// Do blurs in device space when possible.
|
||||
// Chrome/Skia always does the blurs in device space
|
||||
// and will sometimes get incorrect results (e.g. rotated blurs)
|
||||
gfxMatrix transform = aDestinationCtx->CurrentMatrix();
|
||||
gfxMatrix transform = aDestinationCtx->CurrentMatrixDouble();
|
||||
// XXX: we could probably handle negative scales but for now it's easier just to fallback
|
||||
if (!transform.HasNonAxisAlignedTransform() && transform._11 > 0.0 && transform._22 > 0.0) {
|
||||
scaleX = transform._11;
|
||||
scaleY = transform._22;
|
||||
aDestinationCtx->SetMatrix(gfxMatrix());
|
||||
aDestinationCtx->SetMatrix(Matrix());
|
||||
} else {
|
||||
transform = gfxMatrix();
|
||||
}
|
||||
|
@ -4677,13 +4677,13 @@ nsContextBoxBlur::InsetBoxBlur(gfxContext* aDestinationCtx,
|
|||
// input data to the blur. This way, we don't have to scale the min
|
||||
// inset blur to the invert of the dest context, then rescale it back
|
||||
// when we draw to the destination surface.
|
||||
gfxSize scale = aDestinationCtx->CurrentMatrix().ScaleFactors(true);
|
||||
Matrix transform = ToMatrix(aDestinationCtx->CurrentMatrix());
|
||||
gfx::Size scale = aDestinationCtx->CurrentMatrix().ScaleFactors(true);
|
||||
Matrix transform = aDestinationCtx->CurrentMatrix();
|
||||
|
||||
// XXX: we could probably handle negative scales but for now it's easier just to fallback
|
||||
if (!transform.HasNonAxisAlignedTransform() && transform._11 > 0.0 && transform._22 > 0.0) {
|
||||
// If we don't have a rotation, we're pre-transforming all the rects.
|
||||
aDestinationCtx->SetMatrix(gfxMatrix());
|
||||
aDestinationCtx->SetMatrix(Matrix());
|
||||
} else {
|
||||
// Don't touch anything, we have a rotation.
|
||||
transform = Matrix();
|
||||
|
|
|
@ -932,7 +932,7 @@ nsCSSGradientRenderer::Paint(gfxContext& aContext,
|
|||
gfxRect dirtyAreaToFill = nsLayoutUtils::RectToGfxRect(dirty, appUnitsPerDevPixel);
|
||||
dirtyAreaToFill.RoundOut();
|
||||
|
||||
gfxMatrix ctm = aContext.CurrentMatrix();
|
||||
Matrix ctm = aContext.CurrentMatrix();
|
||||
bool isCTMPreservingAxisAlignedRectangles = ctm.PreservesAxisAlignedRectangles();
|
||||
|
||||
// xStart/yStart are the top-left corner of the top-left tile.
|
||||
|
@ -975,7 +975,7 @@ nsCSSGradientRenderer::Paint(gfxContext& aContext,
|
|||
gfxMatrix transform = gfxUtils::TransformRectToRect(fillRect,
|
||||
snappedFillRectTopLeft, snappedFillRectTopRight,
|
||||
snappedFillRectBottomRight);
|
||||
aContext.SetMatrix(transform);
|
||||
aContext.SetMatrixDouble(transform);
|
||||
}
|
||||
aContext.NewPath();
|
||||
aContext.Rectangle(fillRect);
|
||||
|
@ -989,8 +989,8 @@ nsCSSGradientRenderer::Paint(gfxContext& aContext,
|
|||
edgeColor.a *= aOpacity;
|
||||
aContext.SetColor(edgeColor);
|
||||
} else {
|
||||
aContext.SetMatrix(
|
||||
aContext.CurrentMatrix().Copy().PreTranslate(tileRect.TopLeft()));
|
||||
aContext.SetMatrixDouble(
|
||||
aContext.CurrentMatrixDouble().Copy().PreTranslate(tileRect.TopLeft()));
|
||||
aContext.SetPattern(gradientPattern);
|
||||
}
|
||||
aContext.Fill();
|
||||
|
|
|
@ -771,7 +771,7 @@ GenerateAndPushTextMask(nsIFrame* aFrame, gfxContext* aContext,
|
|||
{
|
||||
// Paint text selection background into sourceCtx.
|
||||
gfxContextMatrixAutoSaveRestore save(sourceCtx);
|
||||
sourceCtx->SetMatrix(sourceCtx->CurrentMatrix().PreTranslate(bounds.TopLeft()));
|
||||
sourceCtx->SetMatrixDouble(sourceCtx->CurrentMatrixDouble().PreTranslate(bounds.TopLeft()));
|
||||
|
||||
nsLayoutUtils::PaintFrame(aContext, aFrame,
|
||||
nsRect(nsPoint(0, 0), aFrame->GetSize()),
|
||||
|
@ -793,10 +793,10 @@ GenerateAndPushTextMask(nsIFrame* aFrame, gfxContext* aContext,
|
|||
}
|
||||
RefPtr<gfxContext> maskCtx = gfxContext::CreatePreservingTransformOrNull(maskDT);
|
||||
MOZ_ASSERT(maskCtx);
|
||||
gfxMatrix currentMatrix = sourceCtx->CurrentMatrix();
|
||||
maskCtx->SetMatrix(gfxMatrix::Translation(bounds.TopLeft()) *
|
||||
currentMatrix *
|
||||
gfxMatrix::Translation(-drawRect.TopLeft()));
|
||||
gfxMatrix currentMatrix = sourceCtx->CurrentMatrixDouble();
|
||||
maskCtx->SetMatrixDouble(gfxMatrix::Translation(bounds.TopLeft()) *
|
||||
currentMatrix *
|
||||
gfxMatrix::Translation(-drawRect.TopLeft()));
|
||||
|
||||
// Shade text shape into mask A8 surface.
|
||||
nsLayoutUtils::PaintFrame(maskCtx, aFrame,
|
||||
|
@ -9171,7 +9171,7 @@ ComputeMaskGeometry(PaintFramesParams& aParams)
|
|||
frame->PresContext()->AppUnitsPerDevPixel());
|
||||
|
||||
gfxContextMatrixAutoSaveRestore matSR(&ctx);
|
||||
ctx.SetMatrix(ctx.CurrentMatrix().PreTranslate(devPixelOffsetToUserSpace));
|
||||
ctx.SetMatrixDouble(ctx.CurrentMatrixDouble().PreTranslate(devPixelOffsetToUserSpace));
|
||||
|
||||
// Convert boaderArea and dirtyRect to user space.
|
||||
int32_t appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
|
||||
|
|
|
@ -698,7 +698,7 @@ nsImageRenderer::DrawableForElement(const nsRect& aImageRect,
|
|||
nsSVGIntegrationUtils::DrawableFromPaintServer(
|
||||
mPaintServerFrame, mForFrame, mSize, imageSize,
|
||||
aContext.GetDrawTarget(),
|
||||
aContext.CurrentMatrix(),
|
||||
aContext.CurrentMatrixDouble(),
|
||||
nsSVGIntegrationUtils::FLAG_SYNC_DECODE_IMAGES);
|
||||
|
||||
return drawable.forget();
|
||||
|
|
|
@ -213,8 +213,8 @@ SheetLoadData::SheetLoadData(Loader* aLoader,
|
|||
++(mParentData->mPendingChildren);
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(!mUseSystemPrincipal || mSyncLoad,
|
||||
"Shouldn't use system principal for async loads");
|
||||
MOZ_ASSERT(!mUseSystemPrincipal || mSyncLoad,
|
||||
"Shouldn't use system principal for async loads");
|
||||
}
|
||||
|
||||
SheetLoadData::SheetLoadData(Loader* aLoader,
|
||||
|
@ -248,8 +248,8 @@ SheetLoadData::SheetLoadData(Loader* aLoader,
|
|||
, mPreloadEncoding(aPreloadEncoding)
|
||||
{
|
||||
NS_PRECONDITION(mLoader, "Must have a loader!");
|
||||
NS_POSTCONDITION(!mUseSystemPrincipal || mSyncLoad,
|
||||
"Shouldn't use system principal for async loads");
|
||||
MOZ_ASSERT(!mUseSystemPrincipal || mSyncLoad,
|
||||
"Shouldn't use system principal for async loads");
|
||||
}
|
||||
|
||||
SheetLoadData::~SheetLoadData()
|
||||
|
|
|
@ -106,7 +106,7 @@ nsDOMCSSValueList::SetCssText(const nsAString& aCssText)
|
|||
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
}
|
||||
|
||||
NS_NOTYETIMPLEMENTED("Can't SetCssText yet: please write me!");
|
||||
MOZ_ASSERT_UNREACHABLE("Can't SetCssText yet: please write me!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -3110,12 +3110,12 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, GeckoStyleContext* aCon
|
|||
* @param data_ Variable holding the result of this function.
|
||||
*/
|
||||
#define COMPUTE_END_INHERITED(type_, data_) \
|
||||
NS_POSTCONDITION(!conditions.CacheableWithoutDependencies() || \
|
||||
aRuleDetail == eRuleFullReset || \
|
||||
(aStartStruct && aRuleDetail == eRulePartialReset), \
|
||||
"conditions.CacheableWithoutDependencies() must be false " \
|
||||
"for inherited structs unless all properties have been " \
|
||||
"specified with values other than inherit"); \
|
||||
MOZ_ASSERT(!conditions.CacheableWithoutDependencies() || \
|
||||
aRuleDetail == eRuleFullReset || \
|
||||
(aStartStruct && aRuleDetail == eRulePartialReset), \
|
||||
"conditions.CacheableWithoutDependencies() must be false " \
|
||||
"for inherited structs unless all properties have been " \
|
||||
"specified with values other than inherit"); \
|
||||
if (conditions.CacheableWithoutDependencies()) { \
|
||||
/* We were fully specified and can therefore be cached right on the */ \
|
||||
/* rule node. */ \
|
||||
|
@ -3145,13 +3145,13 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, GeckoStyleContext* aCon
|
|||
* @param data_ Variable holding the result of this function.
|
||||
*/
|
||||
#define COMPUTE_END_RESET(type_, data_) \
|
||||
NS_POSTCONDITION(!conditions.CacheableWithoutDependencies() || \
|
||||
aRuleDetail == eRuleNone || \
|
||||
aRuleDetail == eRulePartialReset || \
|
||||
aRuleDetail == eRuleFullReset, \
|
||||
"conditions.CacheableWithoutDependencies() must be false " \
|
||||
"for reset structs if any properties were specified as " \
|
||||
"inherit"); \
|
||||
MOZ_ASSERT(!conditions.CacheableWithoutDependencies() || \
|
||||
aRuleDetail == eRuleNone || \
|
||||
aRuleDetail == eRulePartialReset || \
|
||||
aRuleDetail == eRuleFullReset, \
|
||||
"conditions.CacheableWithoutDependencies() must be false " \
|
||||
"for reset structs if any properties were specified as " \
|
||||
"inherit"); \
|
||||
if (conditions.CacheableWithoutDependencies()) { \
|
||||
/* We were fully specified and can therefore be cached right on the */ \
|
||||
/* rule node. */ \
|
||||
|
@ -4845,13 +4845,12 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// text-align: enum, string, pair(enum|string), inherit, initial
|
||||
// NOTE: string is not implemented yet.
|
||||
const nsCSSValue* textAlignValue = aRuleData->ValueForTextAlign();
|
||||
text->mTextAlignTrue = false;
|
||||
if (eCSSUnit_String == textAlignValue->GetUnit()) {
|
||||
NS_NOTYETIMPLEMENTED("align string");
|
||||
MOZ_ASSERT_UNREACHABLE("align string");
|
||||
} else if (eCSSUnit_Enumerated == textAlignValue->GetUnit() &&
|
||||
NS_STYLE_TEXT_ALIGN_MOZ_CENTER_OR_INHERIT ==
|
||||
textAlignValue->GetIntValue()) {
|
||||
|
@ -4893,7 +4892,7 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
|
|||
textAlignValue = &textAlignValuePair.mYValue;
|
||||
}
|
||||
} else if (eCSSUnit_String == textAlignValue->GetUnit()) {
|
||||
NS_NOTYETIMPLEMENTED("align string");
|
||||
MOZ_ASSERT_UNREACHABLE("align string");
|
||||
}
|
||||
} else if (eCSSUnit_Inherit == textAlignValue->GetUnit() ||
|
||||
eCSSUnit_Unset == textAlignValue->GetUnit()) {
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
protected:
|
||||
void DoForward(nsIStyleRule* aRule) {
|
||||
mCurrent = mCurrent->Transition(aRule, mLevel, mImportance);
|
||||
NS_POSTCONDITION(mCurrent, "Transition messed up");
|
||||
MOZ_ASSERT(mCurrent, "Transition messed up");
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -277,7 +277,7 @@ SVGGeometryFrame::PaintSVG(gfxContext& aContext,
|
|||
|
||||
// Matrix to the geometry's user space:
|
||||
gfxMatrix newMatrix =
|
||||
aContext.CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers();
|
||||
aContext.CurrentMatrixDouble().PreMultiply(aTransform).NudgeToIntegers();
|
||||
if (newMatrix.IsSingular()) {
|
||||
return;
|
||||
}
|
||||
|
@ -767,7 +767,7 @@ SVGGeometryFrame::Render(gfxContext* aContext,
|
|||
// set it unnecessarily if we return early (it's an expensive operation for
|
||||
// some backends).
|
||||
gfxContextMatrixAutoSaveRestore autoRestoreTransform(aContext);
|
||||
aContext->SetMatrix(aNewTransform);
|
||||
aContext->SetMatrixDouble(aNewTransform);
|
||||
|
||||
if (GetStateBits() & NS_STATE_SVG_CLIPPATH_CHILD) {
|
||||
// We don't complicate this code with GetAsSimplePath since the cost of
|
||||
|
|
|
@ -2943,7 +2943,7 @@ SVGTextDrawPathCallbacks::HandleTextGeometry()
|
|||
} else {
|
||||
// Normal painting.
|
||||
gfxContextMatrixAutoSaveRestore saveMatrix(&mContext);
|
||||
mContext.SetMatrix(mCanvasTM);
|
||||
mContext.SetMatrixDouble(mCanvasTM);
|
||||
|
||||
FillAndStrokeGeometry();
|
||||
}
|
||||
|
@ -3589,7 +3589,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
|||
|
||||
nsPresContext* presContext = PresContext();
|
||||
|
||||
gfxMatrix initialMatrix = aContext.CurrentMatrix();
|
||||
gfxMatrix initialMatrix = aContext.CurrentMatrixDouble();
|
||||
|
||||
if (mState & NS_FRAME_IS_NONDISPLAY) {
|
||||
// If we are in a canvas DrawWindow call that used the
|
||||
|
@ -3650,7 +3650,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
|||
gfxContextMatrixAutoSaveRestore matSR(&aContext);
|
||||
aContext.NewPath();
|
||||
aContext.Multiply(canvasTMForChildren);
|
||||
gfxMatrix currentMatrix = aContext.CurrentMatrix();
|
||||
gfxMatrix currentMatrix = aContext.CurrentMatrixDouble();
|
||||
|
||||
RefPtr<nsCaret> caret = presContext->PresShell()->GetCaret();
|
||||
nsRect caretRect;
|
||||
|
@ -3687,7 +3687,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
|||
gfxMatrix runTransform =
|
||||
run.GetTransformFromUserSpaceForPainting(presContext, item) *
|
||||
currentMatrix;
|
||||
aContext.SetMatrix(runTransform);
|
||||
aContext.SetMatrixDouble(runTransform);
|
||||
|
||||
if (drawMode != DrawMode(0)) {
|
||||
bool paintSVGGlyphs;
|
||||
|
|
|
@ -71,7 +71,7 @@ nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame,
|
|||
UniquePtr<UserSpaceMetrics> metrics = UserSpaceMetricsForFrame(aFilteredFrame);
|
||||
|
||||
gfxContextMatrixAutoSaveRestore autoSR(aCtx);
|
||||
gfxSize scaleFactors = aCtx->CurrentMatrix().ScaleFactors(true);
|
||||
gfxSize scaleFactors = aCtx->CurrentMatrixDouble().ScaleFactors(true);
|
||||
if (scaleFactors.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame,
|
|||
MOZ_ASSERT(invertible);
|
||||
// Pull scale vector out of aCtx's transform, put all scale factors, which
|
||||
// includes css and css-to-dev-px scale, into scaleMatrixInDevUnits.
|
||||
aCtx->SetMatrix(reverseScaleMatrix * aCtx->CurrentMatrix());
|
||||
aCtx->SetMatrixDouble(reverseScaleMatrix * aCtx->CurrentMatrixDouble());
|
||||
|
||||
gfxMatrix scaleMatrixInDevUnits =
|
||||
scaleMatrix * nsSVGUtils::GetCSSPxToDevPxMatrix(aFilteredFrame);
|
||||
|
@ -414,8 +414,8 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource,
|
|||
MOZ_ASSERT(ctx); // already checked the draw target above
|
||||
gfxContextAutoSaveRestore saver(ctx);
|
||||
|
||||
ctx->SetMatrix(mPaintTransform *
|
||||
gfxMatrix::Translation(-neededRect.TopLeft()));
|
||||
ctx->SetMatrixDouble(mPaintTransform *
|
||||
gfxMatrix::Translation(-neededRect.TopLeft()));
|
||||
GeneralPattern pattern;
|
||||
if (aSource == &mFillPaint) {
|
||||
nsSVGUtils::MakeFillPatternFor(mTargetFrame, ctx, &pattern, aImgParams);
|
||||
|
@ -483,8 +483,8 @@ nsFilterInstance::BuildSourceImage(DrawTarget *aDest, imgDrawingParams& aImgPara
|
|||
gfxMatrix devPxToCssPxTM = nsSVGUtils::GetCSSPxToDevPxMatrix(mTargetFrame);
|
||||
DebugOnly<bool> invertible = devPxToCssPxTM.Invert();
|
||||
MOZ_ASSERT(invertible);
|
||||
ctx->SetMatrix(devPxToCssPxTM * mPaintTransform *
|
||||
gfxMatrix::Translation(-neededRect.TopLeft()));
|
||||
ctx->SetMatrixDouble(devPxToCssPxTM * mPaintTransform *
|
||||
gfxMatrix::Translation(-neededRect.TopLeft()));
|
||||
|
||||
mPaintCallback->Paint(*ctx, mTargetFrame, mPaintTransform, &dirty, aImgParams);
|
||||
|
||||
|
|
|
@ -63,9 +63,9 @@ nsSVGClipPathFrame::ApplyClipPath(gfxContext& aContext,
|
|||
PrependLocalTransformsTo(GetClipPathTransform(aClippedFrame) * aMatrix,
|
||||
eUserSpaceToParent);
|
||||
gfxMatrix newMatrix =
|
||||
aContext.CurrentMatrix().PreMultiply(toChildsUserSpace).NudgeToIntegers();
|
||||
aContext.CurrentMatrixDouble().PreMultiply(toChildsUserSpace).NudgeToIntegers();
|
||||
if (!newMatrix.IsSingular()) {
|
||||
aContext.SetMatrix(newMatrix);
|
||||
aContext.SetMatrixDouble(newMatrix);
|
||||
FillRule clipRule =
|
||||
nsSVGUtils::ToFillRule(pathFrame->StyleSVG()->mClipRule);
|
||||
clipPath = pathElement->GetOrBuildPath(aDrawTarget, clipRule);
|
||||
|
@ -103,7 +103,7 @@ nsSVGClipPathFrame::CreateClipMask(gfxContext& aReferenceContext,
|
|||
}
|
||||
|
||||
static void
|
||||
ComposeExtraMask(DrawTarget* aTarget, const gfxMatrix& aMaskTransfrom,
|
||||
ComposeExtraMask(DrawTarget* aTarget,
|
||||
SourceSurface* aExtraMask, const Matrix& aExtraMasksTransform)
|
||||
{
|
||||
MOZ_ASSERT(aExtraMask);
|
||||
|
@ -178,14 +178,14 @@ nsSVGClipPathFrame::PaintClipMask(gfxContext& aMaskContext,
|
|||
}
|
||||
|
||||
// Moz2D transforms in the opposite direction to Thebes
|
||||
gfxMatrix maskTransfrom = aMaskContext.CurrentMatrix();
|
||||
Matrix maskTransfrom = aMaskContext.CurrentMatrix();
|
||||
maskTransfrom.Invert();
|
||||
|
||||
if (aExtraMask) {
|
||||
ComposeExtraMask(maskDT, maskTransfrom, aExtraMask, aExtraMasksTransform);
|
||||
ComposeExtraMask(maskDT, aExtraMask, aExtraMasksTransform);
|
||||
}
|
||||
|
||||
*aMaskTransform = ToMatrix(maskTransfrom);
|
||||
*aMaskTransform = maskTransfrom;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -271,7 +271,7 @@ nsSVGClipPathFrame::GetClipMask(gfxContext& aReferenceContext,
|
|||
return nullptr;
|
||||
}
|
||||
maskContext->SetMatrix(aReferenceContext.CurrentMatrix() *
|
||||
gfxMatrix::Translation(-offset));
|
||||
Matrix::Translation(-offset));
|
||||
|
||||
PaintClipMask(*maskContext, aClippedFrame, aMatrix, aMaskTransform,
|
||||
aExtraMask, aExtraMasksTransform);
|
||||
|
|
|
@ -419,7 +419,7 @@ public:
|
|||
basic->SetTarget(&aContext);
|
||||
|
||||
gfxContextMatrixAutoSaveRestore autoSR(&aContext);
|
||||
aContext.SetMatrix(aContext.CurrentMatrix().PreTranslate(-mUserSpaceToFrameSpaceOffset));
|
||||
aContext.SetMatrixDouble(aContext.CurrentMatrixDouble().PreTranslate(-mUserSpaceToFrameSpaceOffset));
|
||||
|
||||
mLayerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, mBuilder);
|
||||
basic->SetTarget(oldCtx);
|
||||
|
@ -440,7 +440,7 @@ static void
|
|||
PaintMaskSurface(const PaintFramesParams& aParams,
|
||||
DrawTarget* aMaskDT, float aOpacity, nsStyleContext* aSC,
|
||||
const nsTArray<nsSVGMaskFrame*>& aMaskFrames,
|
||||
const gfxMatrix& aMaskSurfaceMatrix,
|
||||
const Matrix& aMaskSurfaceMatrix,
|
||||
const nsPoint& aOffsetToUserSpace)
|
||||
{
|
||||
MOZ_ASSERT(aMaskFrames.Length() > 0);
|
||||
|
@ -573,8 +573,8 @@ CreateAndPaintMaskSurface(const PaintFramesParams& aParams,
|
|||
|
||||
// Set context's matrix on maskContext, offset by the maskSurfaceRect's
|
||||
// position. This makes sure that we combine the masks in device space.
|
||||
gfxMatrix maskSurfaceMatrix =
|
||||
ctx.CurrentMatrix() * gfxMatrix::Translation(-aParams.maskRect.TopLeft());
|
||||
Matrix maskSurfaceMatrix =
|
||||
ctx.CurrentMatrix() * Matrix::Translation(-aParams.maskRect.TopLeft());
|
||||
|
||||
PaintMaskSurface(aParams, maskDT,
|
||||
paintResult.opacityApplied ? aOpacity : 1.0,
|
||||
|
@ -604,7 +604,7 @@ CreateAndPaintMaskSurface(const PaintFramesParams& aParams,
|
|||
return paintResult;
|
||||
}
|
||||
|
||||
paintResult.maskTransform = ToMatrix(maskSurfaceMatrix);
|
||||
paintResult.maskTransform = maskSurfaceMatrix;
|
||||
if (!paintResult.maskTransform.Invert()) {
|
||||
return paintResult;
|
||||
}
|
||||
|
@ -711,8 +711,8 @@ MoveContextOriginToUserSpace(nsIFrame* aFrame, const PaintFramesParams& aParams)
|
|||
{
|
||||
EffectOffsets offset = ComputeEffectOffset(aFrame, aParams);
|
||||
|
||||
aParams.ctx.SetMatrix(
|
||||
aParams.ctx.CurrentMatrix().PreTranslate(offset.offsetToUserSpaceInDevPx));
|
||||
aParams.ctx.SetMatrixDouble(
|
||||
aParams.ctx.CurrentMatrixDouble().PreTranslate(offset.offsetToUserSpaceInDevPx));
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
@ -852,7 +852,7 @@ nsSVGIntegrationUtils::PaintMask(const PaintFramesParams& aParams)
|
|||
maskUsage.shouldGenerateMaskLayer ? maskTarget->Snapshot() : nullptr;
|
||||
clipPathFrame->PaintClipMask(ctx, frame, cssPxToDevPxMatrix,
|
||||
&clipMaskTransform, maskSurface,
|
||||
ToMatrix(ctx.CurrentMatrix()));
|
||||
ctx.CurrentMatrix());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,8 +99,8 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(MaskParams& aParams)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
gfxMatrix maskSurfaceMatrix =
|
||||
context->CurrentMatrix() * gfxMatrix::Translation(-maskSurfaceRect.TopLeft());
|
||||
Matrix maskSurfaceMatrix =
|
||||
context->CurrentMatrix() * ToMatrix(gfxMatrix::Translation(-maskSurfaceRect.TopLeft()));
|
||||
|
||||
RefPtr<gfxContext> tmpCtx = gfxContext::CreateOrNull(maskDT);
|
||||
MOZ_ASSERT(tmpCtx); // already checked the draw target above
|
||||
|
@ -153,7 +153,7 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(MaskParams& aParams)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
*aParams.maskTransform = ToMatrix(maskSurfaceMatrix);
|
||||
*aParams.maskTransform = maskSurfaceMatrix;
|
||||
return surface.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -579,7 +579,7 @@ public:
|
|||
mTargetCtx = gfxContext::CreateOrNull(targetDT);
|
||||
MOZ_ASSERT(mTargetCtx); // already checked the draw target above
|
||||
mTargetCtx->SetMatrix(mSourceCtx->CurrentMatrix() *
|
||||
gfxMatrix::Translation(-drawRect.TopLeft()));
|
||||
Matrix::Translation(-drawRect.TopLeft()));
|
||||
|
||||
mTargetOffset = drawRect.TopLeft();
|
||||
|
||||
|
@ -595,7 +595,7 @@ public:
|
|||
RefPtr<SourceSurface> targetSurf = mTargetCtx->GetDrawTarget()->Snapshot();
|
||||
|
||||
gfxContextAutoSaveRestore save(mSourceCtx);
|
||||
mSourceCtx->SetMatrix(gfxMatrix()); // This will be restored right after.
|
||||
mSourceCtx->SetMatrix(Matrix()); // This will be restored right after.
|
||||
RefPtr<gfxPattern> pattern =
|
||||
new gfxPattern(targetSurf,
|
||||
Matrix::Translation(mTargetOffset.x, mTargetOffset.y));
|
||||
|
@ -854,8 +854,8 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
// have to adjust the scale.
|
||||
gfxMatrix reverseScaleMatrix = nsSVGUtils::GetCSSPxToDevPxMatrix(aFrame);
|
||||
DebugOnly<bool> invertible = reverseScaleMatrix.Invert();
|
||||
target->SetMatrix(reverseScaleMatrix * aTransform *
|
||||
target->CurrentMatrix());
|
||||
target->SetMatrixDouble(reverseScaleMatrix * aTransform *
|
||||
target->CurrentMatrixDouble());
|
||||
|
||||
SVGPaintCallback paintCallback;
|
||||
nsFilterInstance::PaintFilteredFrame(aFrame, target, &paintCallback,
|
||||
|
@ -1509,7 +1509,7 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
|
|||
|
||||
if (ps) {
|
||||
RefPtr<gfxPattern> pattern =
|
||||
ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
|
||||
ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrixDouble(),
|
||||
&nsStyleSVG::mFill, fillOpacity, aImgParams);
|
||||
if (pattern) {
|
||||
pattern->CacheColorStops(dt);
|
||||
|
@ -1524,12 +1524,12 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
|
|||
case eStyleSVGPaintType_ContextFill:
|
||||
pattern =
|
||||
aContextPaint->GetFillPattern(dt, fillOpacity,
|
||||
aContext->CurrentMatrix(), aImgParams);
|
||||
aContext->CurrentMatrixDouble(), aImgParams);
|
||||
break;
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
pattern =
|
||||
aContextPaint->GetStrokePattern(dt, fillOpacity,
|
||||
aContext->CurrentMatrix(), aImgParams);
|
||||
aContext->CurrentMatrixDouble(), aImgParams);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
|
@ -1585,7 +1585,7 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
|
|||
|
||||
if (ps) {
|
||||
RefPtr<gfxPattern> pattern =
|
||||
ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
|
||||
ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrixDouble(),
|
||||
&nsStyleSVG::mStroke, strokeOpacity, aImgParams);
|
||||
if (pattern) {
|
||||
pattern->CacheColorStops(dt);
|
||||
|
@ -1600,12 +1600,12 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
|
|||
case eStyleSVGPaintType_ContextFill:
|
||||
pattern =
|
||||
aContextPaint->GetFillPattern(dt, strokeOpacity,
|
||||
aContext->CurrentMatrix(), aImgParams);
|
||||
aContext->CurrentMatrixDouble(), aImgParams);
|
||||
break;
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
pattern =
|
||||
aContextPaint->GetStrokePattern(dt, strokeOpacity,
|
||||
aContext->CurrentMatrix(), aImgParams);
|
||||
aContext->CurrentMatrixDouble(), aImgParams);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
|
|
|
@ -42,8 +42,7 @@ nsButtonBoxFrame::nsButtonBoxListener::HandleEvent(nsIDOMEvent* aEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ABORT();
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected eventType");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -602,7 +602,6 @@ nsMenuBarListener::HandleEvent(nsIDOMEvent* aEvent)
|
|||
return Fullscreen(aEvent);
|
||||
}
|
||||
|
||||
NS_ABORT();
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected eventType");
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -589,7 +589,7 @@ nsSplitterFrameInner::HandleEvent(nsIDOMEvent* aEvent)
|
|||
eventType.EqualsLiteral("mouseout"))
|
||||
return MouseMove(aEvent);
|
||||
|
||||
NS_ABORT();
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected eventType");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -2612,8 +2612,7 @@ nsXULPopupManager::HandleEvent(nsIDOMEvent* aEvent)
|
|||
return KeyPress(keyEvent);
|
||||
}
|
||||
|
||||
NS_ABORT();
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected eventType");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,9 +8,6 @@ package org.mozilla.gecko.mozglue;
|
|||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
@ -473,15 +470,6 @@ public final class GeckoLoader {
|
|||
|
||||
private static void setupLocaleEnvironment() {
|
||||
putenv("LANG=" + Locale.getDefault().toString());
|
||||
NumberFormat nf = NumberFormat.getInstance();
|
||||
if (nf instanceof DecimalFormat) {
|
||||
DecimalFormat df = (DecimalFormat)nf;
|
||||
DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
|
||||
|
||||
putenv("LOCALE_DECIMAL_POINT=" + dfs.getDecimalSeparator());
|
||||
putenv("LOCALE_THOUSANDS_SEP=" + dfs.getGroupingSeparator());
|
||||
putenv("LOCALE_GROUPING=" + (char)df.getGroupingSize());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
|
|
|
@ -3054,7 +3054,7 @@ nsStandardURL::SetRef(const nsACString &input)
|
|||
NS_IMETHODIMP
|
||||
nsStandardURL::SetDirectory(const nsACString &input)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("");
|
||||
MOZ_ASSERT_UNREACHABLE("SetDirectory");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -772,7 +772,7 @@ HttpBaseChannel::GetContentLength(int64_t *aContentLength)
|
|||
NS_IMETHODIMP
|
||||
HttpBaseChannel::SetContentLength(int64_t value)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("HttpBaseChannel::SetContentLength");
|
||||
MOZ_ASSERT_UNREACHABLE("HttpBaseChannel::SetContentLength");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -5101,6 +5101,7 @@ export HOST_CFLAGS
|
|||
export HOST_CPPFLAGS
|
||||
export HOST_CXXFLAGS
|
||||
export HOST_LDFLAGS
|
||||
export MOZ_PGO
|
||||
|
||||
if ! test -e js; then
|
||||
mkdir js
|
||||
|
|
|
@ -1068,7 +1068,7 @@ CompositeDataSourceImpl::ArcLabelsOut(nsIRDFResource* aSource,
|
|||
NS_IMETHODIMP
|
||||
CompositeDataSourceImpl::GetAllResources(nsISimpleEnumerator** aResult)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("CompositeDataSourceImpl::GetAllResources");
|
||||
MOZ_ASSERT_UNREACHABLE("CompositeDataSourceImpl::GetAllResources");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ FileSystemDataSource::GetSources(nsIRDFResource *property,
|
|||
bool tv,
|
||||
nsISimpleEnumerator **sources /* out */)
|
||||
{
|
||||
// NS_NOTYETIMPLEMENTED("write me");
|
||||
// MOZ_ASSERT_UNREACHABLE("write me");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -705,7 +705,7 @@ NS_IMETHODIMP
|
|||
FileSystemDataSource::ArcLabelsIn(nsIRDFNode *node,
|
||||
nsISimpleEnumerator ** labels /* out */)
|
||||
{
|
||||
// NS_NOTYETIMPLEMENTED("write me");
|
||||
// MOZ_ASSERT_UNREACHABLE("write me");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -762,7 +762,7 @@ FileSystemDataSource::ArcLabelsOut(nsIRDFResource *source,
|
|||
NS_IMETHODIMP
|
||||
FileSystemDataSource::GetAllResources(nsISimpleEnumerator** aCursor)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("sorry!");
|
||||
MOZ_ASSERT_UNREACHABLE("sorry!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,14 @@
|
|||
#include "mozilla/ModuleUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#include "prenv.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
int GetEffectiveContentSandboxLevel() {
|
||||
if (PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX")) {
|
||||
return 0;
|
||||
}
|
||||
int level = Preferences::GetInt("security.sandbox.content.level");
|
||||
// On Windows and macOS, enforce a minimum content sandbox level of 1 (except on
|
||||
// Nightly, where it can be set to 0).
|
||||
|
@ -23,6 +28,10 @@ int GetEffectiveContentSandboxLevel() {
|
|||
return level;
|
||||
}
|
||||
|
||||
bool IsContentSandboxEnabled() {
|
||||
return GetEffectiveContentSandboxLevel() > 0;
|
||||
}
|
||||
|
||||
class SandboxSettings final : public mozISandboxSettings
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -10,8 +10,12 @@ namespace mozilla {
|
|||
|
||||
// Return the current sandbox level. This is the
|
||||
// "security.sandbox.content.level" preference, but rounded up to the current
|
||||
// minimum allowed level.
|
||||
// minimum allowed level. Returns 0 (disabled) if the env var
|
||||
// MOZ_DISABLE_CONTENT_SANDBOX is set.
|
||||
int GetEffectiveContentSandboxLevel();
|
||||
|
||||
// Checks whether the effective content sandbox level is > 0.
|
||||
bool IsContentSandboxEnabled();
|
||||
|
||||
}
|
||||
#endif // mozilla_SandboxPolicies_h
|
||||
|
|
|
@ -22,7 +22,7 @@ MOZ_EXPORT void SandboxEarlyInit(GeckoProcessType aType);
|
|||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
// Call only if SandboxInfo::CanSandboxContent() returns true.
|
||||
// (No-op if MOZ_DISABLE_CONTENT_SANDBOX is set.)
|
||||
// (No-op if the sandbox is disabled.)
|
||||
// aBrokerFd is the filesystem broker client file descriptor,
|
||||
// or -1 to allow direct filesystem access.
|
||||
// isFileProcess determines whether we allow system wide file reads.
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "base/posix/eintr_wrapper.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/SandboxSettings.h"
|
||||
#include "sandbox/linux/system_headers/linux_seccomp.h"
|
||||
#include "sandbox/linux/system_headers/linux_syscalls.h"
|
||||
|
||||
|
@ -226,6 +227,9 @@ SandboxInfo::SandboxInfo() {
|
|||
}
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
// We can't use mozilla::IsContentSandboxEnabled() here because a)
|
||||
// libmozsandbox can't depend on libxul, and b) this is called in a static
|
||||
// initializer before the prefences service is ready.
|
||||
if (!getenv("MOZ_DISABLE_CONTENT_SANDBOX")) {
|
||||
flags |= kEnabledForContent;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ public:
|
|||
enum Flags {
|
||||
// System call filtering; kernel config option CONFIG_SECCOMP_FILTER.
|
||||
kHasSeccompBPF = 1 << 0,
|
||||
// Config flag MOZ_CONTENT_SANDBOX; env var MOZ_DISABLE_CONTENT_SANDBOX.
|
||||
// Config flag MOZ_CONTENT_SANDBOX; runtime
|
||||
// mozilla::IsContentSandboxEnabled().
|
||||
kEnabledForContent = 1 << 1,
|
||||
// Config flag MOZ_GMP_SANDBOX; env var MOZ_DISABLE_GMP_SANDBOX.
|
||||
kEnabledForMedia = 1 << 2,
|
||||
|
|
|
@ -403,7 +403,7 @@ SandboxBrokerPolicyFactory::GetContentPolicy(int aPid, bool aFileProcess)
|
|||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// File broker usage is controlled through a pref.
|
||||
if (GetEffectiveContentSandboxLevel() <= 1) {
|
||||
if (!IsContentSandboxEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ Cu.import("resource://testing-common/PlacesTestUtils.jsm");
|
|||
Cu.import("resource://services-sync/util.js");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
|
||||
Cu.import("resource://gre/modules/ObjectUtils.jsm");
|
||||
|
||||
add_task(async function head_setup() {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
|
||||
Cu.import("resource://gre/modules/BookmarkJSONUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Log.jsm");
|
||||
Cu.import("resource://services-sync/constants.js");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
|
||||
Cu.import("resource://services-common/async.js");
|
||||
Cu.import("resource://gre/modules/Log.jsm");
|
||||
Cu.import("resource://services-sync/engines.js");
|
||||
|
@ -551,8 +550,8 @@ add_task(async function test_dupe_reparented_to_future_arriving_parent_bookmark(
|
|||
|
||||
// As the incoming parent is missing the item should have been annotated
|
||||
// with that missing parent.
|
||||
equal(PlacesUtils.annotations.getItemAnnotation((await store.idForGUID(newGUID)), "sync/parent"),
|
||||
newParentGUID);
|
||||
equal(PlacesUtils.annotations.getItemAnnotation((await store.idForGUID(newGUID)),
|
||||
PlacesSyncUtils.bookmarks.SYNC_PARENT_ANNO), newParentGUID);
|
||||
|
||||
// Check the validator. Sadly, this is known to cause a mismatch between
|
||||
// the server and client views of the tree.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
|
||||
Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||
Cu.import("resource://gre/modules/BookmarkJSONUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Log.jsm");
|
||||
|
@ -113,15 +112,12 @@ add_task(async function bad_record_allIDs() {
|
|||
await SyncTestingInfrastructure(server);
|
||||
|
||||
_("Ensure that bad Places queries don't cause an error in getAllIDs.");
|
||||
let badRecordID = PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.bookmarks.toolbarFolder,
|
||||
CommonUtils.makeURI("place:folder=1138"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
null);
|
||||
let badRecord = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
url: "place:folder=1138",
|
||||
});
|
||||
|
||||
do_check_true(badRecordID > 0);
|
||||
_("Record is " + badRecordID);
|
||||
_("Type: " + PlacesUtils.bookmarks.getItemType(badRecordID));
|
||||
_("Type: " + badRecord.type);
|
||||
|
||||
_("Fetching all IDs.");
|
||||
let all = await fetchAllRecordIds();
|
||||
|
@ -131,7 +127,7 @@ add_task(async function bad_record_allIDs() {
|
|||
do_check_true(all.has("toolbar"));
|
||||
|
||||
_("Clean up.");
|
||||
PlacesUtils.bookmarks.removeItem(badRecordID);
|
||||
await PlacesUtils.bookmarks.eraseEverything();
|
||||
await PlacesSyncUtils.bookmarks.reset();
|
||||
await promiseStopServer(server);
|
||||
});
|
||||
|
@ -149,24 +145,29 @@ add_task(async function test_processIncoming_error_orderChildren() {
|
|||
|
||||
try {
|
||||
|
||||
let folder1_id = PlacesUtils.bookmarks.createFolder(
|
||||
PlacesUtils.bookmarks.toolbarFolder, "Folder 1", 0);
|
||||
let folder1_guid = await store.GUIDForId(folder1_id);
|
||||
let folder1 = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "Folder 1",
|
||||
});
|
||||
|
||||
let fxuri = CommonUtils.makeURI("http://getfirefox.com/");
|
||||
let tburi = CommonUtils.makeURI("http://getthunderbird.com/");
|
||||
|
||||
let bmk1_id = PlacesUtils.bookmarks.insertBookmark(
|
||||
folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
|
||||
let bmk2_id = PlacesUtils.bookmarks.insertBookmark(
|
||||
folder1_id, tburi, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!");
|
||||
let bmk1 = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder1.guid,
|
||||
url: "http://getfirefox.com/",
|
||||
title: "Get Firefox!",
|
||||
});
|
||||
let bmk2 = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder1.guid,
|
||||
url: "http://getthunderbird.com/",
|
||||
title: "Get Thunderbird!",
|
||||
});
|
||||
|
||||
// Create a server record for folder1 where we flip the order of
|
||||
// the children.
|
||||
let folder1_record = await store.createRecord(folder1_guid);
|
||||
let folder1_record = await store.createRecord(folder1.guid);
|
||||
let folder1_payload = folder1_record.cleartext;
|
||||
folder1_payload.children.reverse();
|
||||
collection.insert(folder1_guid, encryptPayload(folder1_payload));
|
||||
collection.insert(folder1.guid, encryptPayload(folder1_payload));
|
||||
|
||||
// Create a bogus record that when synced down will provoke a
|
||||
// network error which in turn provokes an exception in _processIncoming.
|
||||
|
@ -190,14 +191,14 @@ add_task(async function test_processIncoming_error_orderChildren() {
|
|||
ok(!!error);
|
||||
|
||||
// Verify that the bookmark order has been applied.
|
||||
folder1_record = await store.createRecord(folder1_guid);
|
||||
folder1_record = await store.createRecord(folder1.guid);
|
||||
let new_children = folder1_record.children;
|
||||
do_check_eq(new_children.length, 2);
|
||||
do_check_eq(new_children[0], folder1_payload.children[0]);
|
||||
do_check_eq(new_children[1], folder1_payload.children[1]);
|
||||
do_check_matches(new_children,
|
||||
[folder1_payload.children[0], folder1_payload.children[1]]);
|
||||
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk1_id), 1);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk2_id), 0);
|
||||
let localChildIds = await PlacesSyncUtils.bookmarks.fetchChildRecordIds(
|
||||
folder1.guid);
|
||||
do_check_matches(localChildIds, [bmk2.guid, bmk1.guid]);
|
||||
|
||||
} finally {
|
||||
await store.wipe();
|
||||
|
@ -238,19 +239,19 @@ async function test_restoreOrImport(aReplace) {
|
|||
|
||||
try {
|
||||
|
||||
let folder1_id = PlacesUtils.bookmarks.createFolder(
|
||||
PlacesUtils.bookmarks.toolbarFolder, "Folder 1", 0);
|
||||
let folder1_guid = await store.GUIDForId(folder1_id);
|
||||
_("Folder 1: " + folder1_id + ", " + folder1_guid);
|
||||
|
||||
let fxuri = CommonUtils.makeURI("http://getfirefox.com/");
|
||||
let tburi = CommonUtils.makeURI("http://getthunderbird.com/");
|
||||
let folder1 = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "Folder 1",
|
||||
});
|
||||
|
||||
_("Create a single record.");
|
||||
let bmk1_id = PlacesUtils.bookmarks.insertBookmark(
|
||||
folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
|
||||
let bmk1_guid = await store.GUIDForId(bmk1_id);
|
||||
_(`Get Firefox!: ${bmk1_id}, ${bmk1_guid}`);
|
||||
let bmk1 = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder1.guid,
|
||||
url: "http://getfirefox.com/",
|
||||
title: "Get Firefox!",
|
||||
});
|
||||
_(`Get Firefox!: ${bmk1.guid}`);
|
||||
|
||||
let dirSvc = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties);
|
||||
|
@ -264,12 +265,14 @@ async function test_restoreOrImport(aReplace) {
|
|||
await bookmarkUtils.exportToFile(backupFile.path);
|
||||
|
||||
_("Create a different record and sync.");
|
||||
let bmk2_id = PlacesUtils.bookmarks.insertBookmark(
|
||||
folder1_id, tburi, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!");
|
||||
let bmk2_guid = await store.GUIDForId(bmk2_id);
|
||||
_(`Get Thunderbird!: ${bmk2_id}, ${bmk2_guid}`);
|
||||
let bmk2 = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder1.guid,
|
||||
url: "http://getthunderbird.com/",
|
||||
title: "Get Thunderbird!",
|
||||
});
|
||||
_(`Get Thunderbird!: ${bmk2.guid}`);
|
||||
|
||||
PlacesUtils.bookmarks.removeItem(bmk1_id);
|
||||
await PlacesUtils.bookmarks.remove(bmk1.guid);
|
||||
|
||||
let error;
|
||||
try {
|
||||
|
@ -283,10 +286,10 @@ async function test_restoreOrImport(aReplace) {
|
|||
_("Verify that there's only one bookmark on the server, and it's Thunderbird.");
|
||||
// Of course, there's also the Bookmarks Toolbar and Bookmarks Menu...
|
||||
let wbos = collection.keys(function(id) {
|
||||
return ["menu", "toolbar", "mobile", "unfiled", folder1_guid].indexOf(id) == -1;
|
||||
return ["menu", "toolbar", "mobile", "unfiled", folder1.guid].indexOf(id) == -1;
|
||||
});
|
||||
do_check_eq(wbos.length, 1);
|
||||
do_check_eq(wbos[0], bmk2_guid);
|
||||
do_check_eq(wbos[0], bmk2.guid);
|
||||
|
||||
_(`Now ${verb} from a backup.`);
|
||||
await bookmarkUtils.importFromFile(backupFile, aReplace);
|
||||
|
@ -307,24 +310,24 @@ async function test_restoreOrImport(aReplace) {
|
|||
let count = 0;
|
||||
for (let guid of guids) {
|
||||
count++;
|
||||
let id = await store.idForGUID(guid, true);
|
||||
let info = await PlacesUtils.bookmarks.fetch(
|
||||
PlacesSyncUtils.bookmarks.recordIdToGuid(guid));
|
||||
// Only one bookmark, so _all_ should be Firefox!
|
||||
if (PlacesUtils.bookmarks.getItemType(id) == PlacesUtils.bookmarks.TYPE_BOOKMARK) {
|
||||
let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
|
||||
_(`Found URI ${uri.spec} for GUID ${guid}`);
|
||||
bookmarkGuids.set(uri.spec, guid);
|
||||
if (info.type == PlacesUtils.bookmarks.TYPE_BOOKMARK) {
|
||||
_(`Found URI ${info.url.href} for GUID ${guid}`);
|
||||
bookmarkGuids.set(info.url.href, guid);
|
||||
}
|
||||
}
|
||||
do_check_true(bookmarkGuids.has(fxuri.spec));
|
||||
do_check_true(bookmarkGuids.has("http://getfirefox.com/"));
|
||||
if (!aReplace) {
|
||||
do_check_true(bookmarkGuids.has(tburi.spec));
|
||||
do_check_true(bookmarkGuids.has("http://getthunderbird.com/"));
|
||||
}
|
||||
|
||||
_("Have the correct number of IDs locally, too.");
|
||||
let expectedResults = ["menu", "toolbar", "mobile", "unfiled", folder1_id,
|
||||
bmk1_id];
|
||||
let expectedResults = ["menu", "toolbar", "mobile", "unfiled", folder1.guid,
|
||||
bmk1.guid];
|
||||
if (!aReplace) {
|
||||
expectedResults.push("toolbar", folder1_id, bmk2_id);
|
||||
expectedResults.push("toolbar", folder1.guid, bmk2.guid);
|
||||
}
|
||||
do_check_eq(count, expectedResults.length);
|
||||
|
||||
|
@ -354,13 +357,13 @@ async function test_restoreOrImport(aReplace) {
|
|||
});
|
||||
|
||||
let expectedFX = {
|
||||
id: bookmarkGuids.get(fxuri.spec),
|
||||
bmkUri: fxuri.spec,
|
||||
id: bookmarkGuids.get("http://getfirefox.com/"),
|
||||
bmkUri: "http://getfirefox.com/",
|
||||
title: "Get Firefox!"
|
||||
};
|
||||
let expectedTB = {
|
||||
id: bookmarkGuids.get(tburi.spec),
|
||||
bmkUri: tburi.spec,
|
||||
id: bookmarkGuids.get("http://getthunderbird.com/"),
|
||||
bmkUri: "http://getthunderbird.com/",
|
||||
title: "Get Thunderbird!"
|
||||
};
|
||||
|
||||
|
@ -458,10 +461,7 @@ add_task(async function test_mismatched_types() {
|
|||
let server = await serverForFoo(engine);
|
||||
await SyncTestingInfrastructure(server);
|
||||
|
||||
_("GUID: " + (await store.GUIDForId(6, true)));
|
||||
|
||||
try {
|
||||
let bms = PlacesUtils.bookmarks;
|
||||
let oldR = new FakeRecord(BookmarkFolder, oldRecord);
|
||||
let newR = new FakeRecord(Livemark, newRecord);
|
||||
oldR.parentid = PlacesUtils.bookmarks.toolbarGuid;
|
||||
|
@ -469,18 +469,20 @@ add_task(async function test_mismatched_types() {
|
|||
|
||||
await store.applyIncoming(oldR);
|
||||
_("Applied old. It's a folder.");
|
||||
let oldID = await store.idForGUID(oldR.id);
|
||||
let oldID = await PlacesUtils.promiseItemId(oldR.id);
|
||||
_("Old ID: " + oldID);
|
||||
do_check_eq(bms.getItemType(oldID), bms.TYPE_FOLDER);
|
||||
let oldInfo = await PlacesUtils.bookmarks.fetch(oldR.id);
|
||||
do_check_eq(oldInfo.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
do_check_false(PlacesUtils.annotations
|
||||
.itemHasAnnotation(oldID, PlacesUtils.LMANNO_FEEDURI));
|
||||
|
||||
await store.applyIncoming(newR);
|
||||
let newID = await store.idForGUID(newR.id);
|
||||
let newID = await PlacesUtils.promiseItemId(newR.id);
|
||||
_("New ID: " + newID);
|
||||
|
||||
_("Applied new. It's a livemark.");
|
||||
do_check_eq(bms.getItemType(newID), bms.TYPE_FOLDER);
|
||||
let newInfo = await PlacesUtils.bookmarks.fetch(newR.id);
|
||||
do_check_eq(newInfo.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
do_check_true(PlacesUtils.annotations
|
||||
.itemHasAnnotation(newID, PlacesUtils.LMANNO_FEEDURI));
|
||||
|
||||
|
@ -506,12 +508,14 @@ add_task(async function test_bookmark_guidMap_fail() {
|
|||
await SyncTestingInfrastructure(server);
|
||||
|
||||
// Add one item to the server.
|
||||
let itemID = PlacesUtils.bookmarks.createFolder(
|
||||
PlacesUtils.bookmarks.toolbarFolder, "Folder 1", 0);
|
||||
let itemGUID = await store.GUIDForId(itemID);
|
||||
let itemRecord = await store.createRecord(itemGUID);
|
||||
let item = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "Folder 1",
|
||||
});
|
||||
let itemRecord = await store.createRecord(item.guid);
|
||||
let itemPayload = itemRecord.cleartext;
|
||||
coll.insert(itemGUID, encryptPayload(itemPayload));
|
||||
coll.insert(item.guid, encryptPayload(itemPayload));
|
||||
|
||||
engine.lastSync = 1; // So we don't back up.
|
||||
|
||||
|
@ -611,11 +615,13 @@ add_task(async function test_misreconciled_root() {
|
|||
|
||||
// Let's find out where the toolbar is right now.
|
||||
let toolbarBefore = await store.createRecord("toolbar", "bookmarks");
|
||||
let toolbarIDBefore = await store.idForGUID("toolbar");
|
||||
let toolbarIDBefore = await PlacesUtils.promiseItemId(
|
||||
PlacesUtils.bookmarks.toolbarGuid);
|
||||
do_check_neq(-1, toolbarIDBefore);
|
||||
|
||||
let parentGUIDBefore = toolbarBefore.parentid;
|
||||
let parentIDBefore = await store.idForGUID(parentGUIDBefore);
|
||||
let parentIDBefore = await PlacesUtils.promiseItemId(
|
||||
PlacesSyncUtils.bookmarks.recordIdToGuid(parentGUIDBefore));
|
||||
do_check_neq(-1, parentIDBefore);
|
||||
do_check_eq("string", typeof(parentGUIDBefore));
|
||||
|
||||
|
@ -641,8 +647,10 @@ add_task(async function test_misreconciled_root() {
|
|||
// the real GUID, instead using a generated one. Sync does the translation.
|
||||
let toolbarAfter = await store.createRecord("toolbar", "bookmarks");
|
||||
let parentGUIDAfter = toolbarAfter.parentid;
|
||||
let parentIDAfter = await store.idForGUID(parentGUIDAfter);
|
||||
do_check_eq((await store.GUIDForId(toolbarIDBefore)), "toolbar");
|
||||
let parentIDAfter = await PlacesUtils.promiseItemId(
|
||||
PlacesSyncUtils.bookmarks.recordIdToGuid(parentGUIDAfter));
|
||||
do_check_eq((await PlacesUtils.promiseItemGuid(toolbarIDBefore)),
|
||||
PlacesUtils.bookmarks.toolbarGuid);
|
||||
do_check_eq(parentGUIDBefore, parentGUIDAfter);
|
||||
do_check_eq(parentIDBefore, parentIDAfter);
|
||||
|
||||
|
@ -760,12 +768,12 @@ add_task(async function test_sync_dateAdded() {
|
|||
collection.insert(item2GUID, encryptPayload(item2.cleartext), now / 1000 - 50);
|
||||
|
||||
|
||||
// Also, add a local bookmark and make sure it's date added makes it up to the server
|
||||
let bzid = PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.bookmarksMenuFolderId, CommonUtils.makeURI("https://bugzilla.mozilla.org/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "Bugzilla");
|
||||
|
||||
let bzguid = await PlacesUtils.promiseItemGuid(bzid);
|
||||
// Also, add a local bookmark and make sure its date added makes it up to the server
|
||||
let bz = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||
url: "https://bugzilla.mozilla.org/",
|
||||
title: "Bugzilla",
|
||||
});
|
||||
|
||||
// last sync did a POST, which doesn't advance its lastModified value.
|
||||
// Next sync of the engine doesn't hit info/collections, so lastModified
|
||||
|
@ -776,10 +784,10 @@ add_task(async function test_sync_dateAdded() {
|
|||
let newRecord2 = await store.createRecord(item2GUID);
|
||||
equal(newRecord2.dateAdded, item2.dateAdded, "dateAdded update should work for earlier date");
|
||||
|
||||
let bzWBO = JSON.parse(JSON.parse(collection._wbos[bzguid].payload).ciphertext);
|
||||
let bzWBO = JSON.parse(JSON.parse(collection._wbos[bz.guid].payload).ciphertext);
|
||||
ok(bzWBO.dateAdded, "Locally added dateAdded lost");
|
||||
|
||||
let localRecord = await store.createRecord(bzguid);
|
||||
let localRecord = await store.createRecord(bz.guid);
|
||||
equal(bzWBO.dateAdded, localRecord.dateAdded, "dateAdded should not change during upload");
|
||||
|
||||
item2.dateAdded += 10000;
|
||||
|
|
|
@ -19,18 +19,19 @@ add_task(async function test_ignore_invalid_uri() {
|
|||
_("Ensure that we don't die with invalid bookmarks.");
|
||||
|
||||
// First create a valid bookmark.
|
||||
let bmid = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
Services.io.newURI("http://example.com/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"the title");
|
||||
let bmInfo = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/",
|
||||
title: "the title",
|
||||
});
|
||||
|
||||
// Now update moz_places with an invalid url.
|
||||
await PlacesUtils.withConnectionWrapper("test_ignore_invalid_uri", async function(db) {
|
||||
await db.execute(
|
||||
`UPDATE moz_places SET url = :url, url_hash = hash(:url)
|
||||
WHERE id = (SELECT b.fk FROM moz_bookmarks b
|
||||
WHERE b.id = :id LIMIT 1)`,
|
||||
{ id: bmid, url: "<invalid url>" });
|
||||
WHERE b.guid = :guid)`,
|
||||
{ guid: bmInfo.guid, url: "<invalid url>" });
|
||||
});
|
||||
|
||||
// Ensure that this doesn't throw even though the DB is now in a bad state (a
|
||||
|
@ -42,17 +43,18 @@ add_task(async function test_ignore_missing_uri() {
|
|||
_("Ensure that we don't die with a bookmark referencing an invalid bookmark id.");
|
||||
|
||||
// First create a valid bookmark.
|
||||
let bmid = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
Services.io.newURI("http://example.com/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"the title");
|
||||
let bmInfo = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/",
|
||||
title: "the title",
|
||||
});
|
||||
|
||||
// Now update moz_bookmarks to reference a non-existing places ID
|
||||
await PlacesUtils.withConnectionWrapper("test_ignore_missing_uri", async function(db) {
|
||||
await db.execute(
|
||||
`UPDATE moz_bookmarks SET fk = 999999
|
||||
WHERE id = :id`
|
||||
, { id: bmid });
|
||||
WHERE guid = :guid`
|
||||
, { guid: bmInfo.guid });
|
||||
});
|
||||
|
||||
// Ensure that this doesn't throw even though the DB is now in a bad state (a
|
||||
|
|
|
@ -86,7 +86,7 @@ add_task(async function test_livemark_descriptions() {
|
|||
await doRecord(makeLivemark(record));
|
||||
|
||||
// Attempt to provoke an error by adding a bad description anno.
|
||||
let id = await store.idForGUID(record.id);
|
||||
let id = await PlacesUtils.promiseItemId(record.id);
|
||||
PlacesUtils.annotations.setItemAnnotation(id, DESCRIPTION_ANNO, "", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
|
||||
|
@ -102,29 +102,27 @@ add_task(async function test_livemark_invalid() {
|
|||
|
||||
_("Parent is unknown. Will be set to unfiled.");
|
||||
let lateParentRec = makeLivemark(record631361.payload, true);
|
||||
let parentGUID = Utils.makeGUID();
|
||||
lateParentRec.parentid = parentGUID;
|
||||
do_check_eq(-1, (await store.idForGUID(parentGUID)));
|
||||
lateParentRec.parentid = Utils.makeGUID();
|
||||
|
||||
await store.create(lateParentRec);
|
||||
let recID = await store.idForGUID(lateParentRec.id, true);
|
||||
do_check_true(recID > 0);
|
||||
do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(recID),
|
||||
PlacesUtils.bookmarks.unfiledBookmarksFolder);
|
||||
let recInfo = await PlacesUtils.bookmarks.fetch(lateParentRec.id);
|
||||
do_check_eq(recInfo.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
|
||||
_("No feed URI, which is invalid. Will be skipped.");
|
||||
let noFeedURIRec = makeLivemark(record631361.payload, true);
|
||||
delete noFeedURIRec.cleartext.feedUri;
|
||||
await store.create(noFeedURIRec);
|
||||
// No exception, but no creation occurs.
|
||||
do_check_eq(-1, (await store.idForGUID(noFeedURIRec.id, true)));
|
||||
let noFeedURIItem = await PlacesUtils.bookmarks.fetch(noFeedURIRec.id);
|
||||
do_check_null(noFeedURIItem);
|
||||
|
||||
_("Parent is a Livemark. Will be skipped.");
|
||||
let lmParentRec = makeLivemark(record631361.payload, true);
|
||||
lmParentRec.parentid = await store.GUIDForId(recID);
|
||||
lmParentRec.parentid = recInfo.guid;
|
||||
await store.create(lmParentRec);
|
||||
// No exception, but no creation occurs.
|
||||
do_check_eq(-1, (await store.idForGUID(lmParentRec.id, true)));
|
||||
let lmParentItem = await PlacesUtils.bookmarks.fetch(lmParentRec.id);
|
||||
do_check_null(lmParentItem);
|
||||
|
||||
await engine.finalize();
|
||||
});
|
||||
|
|
|
@ -32,18 +32,16 @@ add_task(async function run_test() {
|
|||
_("Folder name: " + tagRecord.folderName);
|
||||
await store.applyIncoming(tagRecord);
|
||||
|
||||
let tags = PlacesUtils.getFolderContents(PlacesUtils.tagsFolderId).root;
|
||||
let tagID;
|
||||
try {
|
||||
for (let i = 0; i < tags.childCount; ++i) {
|
||||
let child = tags.getChild(i);
|
||||
if (child.title == "bar") {
|
||||
tagID = child.itemId;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
tags.containerOpen = false;
|
||||
}
|
||||
let tagID = -1;
|
||||
let db = await PlacesUtils.promiseDBConnection();
|
||||
let rows = await db.execute(`
|
||||
SELECT id FROM moz_bookmarks
|
||||
WHERE parent = :tagsFolderId AND
|
||||
title = :title`,
|
||||
{ tagsFolderId: PlacesUtils.tagsFolderId,
|
||||
title: "bar" });
|
||||
equal(rows.length, 1);
|
||||
tagID = rows[0].getResultByName("id");
|
||||
|
||||
_("Tag ID: " + tagID);
|
||||
let insertedRecord = await store.createRecord("abcdefabcdef", "bookmarks");
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче