зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
Коммит
5f00ae3a8b
|
@ -305,7 +305,13 @@ testing/modules/ajv-4.1.1.js
|
|||
testing/modules/sinon-2.3.2.js
|
||||
# octothorpe used for pref file comment causes parsing error
|
||||
testing/mozbase/mozprofile/tests/files/prefs_with_comments.js
|
||||
testing/talos/**
|
||||
testing/talos/talos/scripts/jszip.min.js
|
||||
testing/talos/talos/startup_test/sessionrestore/profile/sessionstore.js
|
||||
testing/talos/talos/tests/canvasmark/**
|
||||
testing/talos/talos/tests/dromaeo/**
|
||||
testing/talos/talos/tests/v8_7/**
|
||||
testing/talos/talos/tests/kraken/**
|
||||
|
||||
testing/web-platform/**
|
||||
testing/xpcshell/moz-http2/**
|
||||
testing/xpcshell/node-http2/**
|
||||
|
|
2
CLOBBER
2
CLOBBER
|
@ -22,4 +22,4 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1341285: From experience, due to all the build changes in a webrtc.org landing make a clobber usually necessary
|
||||
Bug 1353650 - Update to ICU 59 requires clobber
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: window.location is null");
|
||||
|
||||
|
||||
add_task(async function checkIdentityOfAboutSupport() {
|
||||
let tab = gBrowser.loadOneTab("about:support", {
|
||||
referrerURI: null,
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: this.docShell is null");
|
||||
|
||||
function test() {
|
||||
ok(!!gBrowser, "gBrowser exists");
|
||||
is(gBrowser, getBrowser(), "both ways of getting tabbrowser work");
|
||||
|
|
|
@ -1,15 +1,3 @@
|
|||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: gBrowser._finalizeTabSwitch is not a function");
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: gBrowser._finalizeTabSwitch is not a function");
|
||||
|
||||
function test() {
|
||||
BrowserTestUtils.addTab(gBrowser);
|
||||
BrowserTestUtils.addTab(gBrowser);
|
||||
|
|
|
@ -2,13 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: Assert is null");
|
||||
|
||||
|
||||
var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
|
||||
var tabsToRemove = [];
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: window.location is null");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
|
||||
|
|
|
@ -31,7 +31,6 @@ module.exports = {
|
|||
"SimpleTest": false,
|
||||
"SpecialPowers": false,
|
||||
"TestUtils": false,
|
||||
"thisTestLeaksUncaughtRejectionsAndShouldBeFixed": false,
|
||||
"todo": false,
|
||||
"todo_is": false,
|
||||
"todo_isnot": false,
|
||||
|
|
|
@ -15,7 +15,7 @@ MOZ_ARG_WITH_BOOL(system-icu,
|
|||
MOZ_SYSTEM_ICU=1)
|
||||
|
||||
if test -n "$MOZ_SYSTEM_ICU"; then
|
||||
PKG_CHECK_MODULES(MOZ_ICU, icu-i18n >= 58.1)
|
||||
PKG_CHECK_MODULES(MOZ_ICU, icu-i18n >= 59.1)
|
||||
CFLAGS="$CFLAGS $MOZ_ICU_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $MOZ_ICU_CFLAGS"
|
||||
fi
|
||||
|
|
|
@ -11,17 +11,18 @@ SOURCES += [
|
|||
'/intl/icu/source/common/caniter.cpp',
|
||||
'/intl/icu/source/common/chariter.cpp',
|
||||
'/intl/icu/source/common/charstr.cpp',
|
||||
'/intl/icu/source/common/cmemory.c',
|
||||
'/intl/icu/source/common/cmemory.cpp',
|
||||
'/intl/icu/source/common/cstr.cpp',
|
||||
'/intl/icu/source/common/cstring.c',
|
||||
'/intl/icu/source/common/cwchar.c',
|
||||
'/intl/icu/source/common/cstring.cpp',
|
||||
'/intl/icu/source/common/cwchar.cpp',
|
||||
'/intl/icu/source/common/dictbe.cpp',
|
||||
'/intl/icu/source/common/dictionarydata.cpp',
|
||||
'/intl/icu/source/common/dtintrv.cpp',
|
||||
'/intl/icu/source/common/edits.cpp',
|
||||
'/intl/icu/source/common/errorcode.cpp',
|
||||
'/intl/icu/source/common/filteredbrk.cpp',
|
||||
'/intl/icu/source/common/filterednormalizer2.cpp',
|
||||
'/intl/icu/source/common/icudataver.c',
|
||||
'/intl/icu/source/common/icudataver.cpp',
|
||||
'/intl/icu/source/common/icuplug.cpp',
|
||||
'/intl/icu/source/common/listformatter.cpp',
|
||||
'/intl/icu/source/common/loadednormalizer2impl.cpp',
|
||||
|
@ -31,7 +32,7 @@ SOURCES += [
|
|||
'/intl/icu/source/common/locdspnm.cpp',
|
||||
'/intl/icu/source/common/locid.cpp',
|
||||
'/intl/icu/source/common/loclikely.cpp',
|
||||
'/intl/icu/source/common/locmap.c',
|
||||
'/intl/icu/source/common/locmap.cpp',
|
||||
'/intl/icu/source/common/locresdata.cpp',
|
||||
'/intl/icu/source/common/locutil.cpp',
|
||||
'/intl/icu/source/common/messagepattern.cpp',
|
||||
|
@ -42,7 +43,7 @@ SOURCES += [
|
|||
'/intl/icu/source/common/patternprops.cpp',
|
||||
'/intl/icu/source/common/pluralmap.cpp',
|
||||
'/intl/icu/source/common/propname.cpp',
|
||||
'/intl/icu/source/common/propsvec.c',
|
||||
'/intl/icu/source/common/propsvec.cpp',
|
||||
'/intl/icu/source/common/punycode.cpp',
|
||||
'/intl/icu/source/common/putil.cpp',
|
||||
'/intl/icu/source/common/rbbi.cpp',
|
||||
|
@ -69,66 +70,66 @@ SOURCES += [
|
|||
'/intl/icu/source/common/simpleformatter.cpp',
|
||||
'/intl/icu/source/common/stringpiece.cpp',
|
||||
'/intl/icu/source/common/stringtriebuilder.cpp',
|
||||
'/intl/icu/source/common/uarrsort.c',
|
||||
'/intl/icu/source/common/ubidi.c',
|
||||
'/intl/icu/source/common/ubidi_props.c',
|
||||
'/intl/icu/source/common/ubidiln.c',
|
||||
'/intl/icu/source/common/ubiditransform.c',
|
||||
'/intl/icu/source/common/ubidiwrt.c',
|
||||
'/intl/icu/source/common/uarrsort.cpp',
|
||||
'/intl/icu/source/common/ubidi.cpp',
|
||||
'/intl/icu/source/common/ubidi_props.cpp',
|
||||
'/intl/icu/source/common/ubidiln.cpp',
|
||||
'/intl/icu/source/common/ubiditransform.cpp',
|
||||
'/intl/icu/source/common/ubidiwrt.cpp',
|
||||
'/intl/icu/source/common/ubrk.cpp',
|
||||
'/intl/icu/source/common/ucase.cpp',
|
||||
'/intl/icu/source/common/ucasemap.cpp',
|
||||
'/intl/icu/source/common/ucasemap_titlecase_brkiter.cpp',
|
||||
'/intl/icu/source/common/ucat.c',
|
||||
'/intl/icu/source/common/uchar.c',
|
||||
'/intl/icu/source/common/ucat.cpp',
|
||||
'/intl/icu/source/common/uchar.cpp',
|
||||
'/intl/icu/source/common/ucharstrie.cpp',
|
||||
'/intl/icu/source/common/ucharstriebuilder.cpp',
|
||||
'/intl/icu/source/common/ucharstrieiterator.cpp',
|
||||
'/intl/icu/source/common/uchriter.cpp',
|
||||
'/intl/icu/source/common/ucln_cmn.cpp',
|
||||
'/intl/icu/source/common/ucmndata.c',
|
||||
'/intl/icu/source/common/ucnv.c',
|
||||
'/intl/icu/source/common/ucmndata.cpp',
|
||||
'/intl/icu/source/common/ucnv.cpp',
|
||||
'/intl/icu/source/common/ucnv2022.cpp',
|
||||
'/intl/icu/source/common/ucnv_bld.cpp',
|
||||
'/intl/icu/source/common/ucnv_cb.c',
|
||||
'/intl/icu/source/common/ucnv_cnv.c',
|
||||
'/intl/icu/source/common/ucnv_ct.c',
|
||||
'/intl/icu/source/common/ucnv_err.c',
|
||||
'/intl/icu/source/common/ucnv_cb.cpp',
|
||||
'/intl/icu/source/common/ucnv_cnv.cpp',
|
||||
'/intl/icu/source/common/ucnv_ct.cpp',
|
||||
'/intl/icu/source/common/ucnv_err.cpp',
|
||||
'/intl/icu/source/common/ucnv_ext.cpp',
|
||||
'/intl/icu/source/common/ucnv_io.cpp',
|
||||
'/intl/icu/source/common/ucnv_lmb.c',
|
||||
'/intl/icu/source/common/ucnv_set.c',
|
||||
'/intl/icu/source/common/ucnv_u16.c',
|
||||
'/intl/icu/source/common/ucnv_u32.c',
|
||||
'/intl/icu/source/common/ucnv_u7.c',
|
||||
'/intl/icu/source/common/ucnv_u8.c',
|
||||
'/intl/icu/source/common/ucnv_lmb.cpp',
|
||||
'/intl/icu/source/common/ucnv_set.cpp',
|
||||
'/intl/icu/source/common/ucnv_u16.cpp',
|
||||
'/intl/icu/source/common/ucnv_u32.cpp',
|
||||
'/intl/icu/source/common/ucnv_u7.cpp',
|
||||
'/intl/icu/source/common/ucnv_u8.cpp',
|
||||
'/intl/icu/source/common/ucnvbocu.cpp',
|
||||
'/intl/icu/source/common/ucnvdisp.c',
|
||||
'/intl/icu/source/common/ucnvhz.c',
|
||||
'/intl/icu/source/common/ucnvisci.c',
|
||||
'/intl/icu/source/common/ucnvlat1.c',
|
||||
'/intl/icu/source/common/ucnvdisp.cpp',
|
||||
'/intl/icu/source/common/ucnvhz.cpp',
|
||||
'/intl/icu/source/common/ucnvisci.cpp',
|
||||
'/intl/icu/source/common/ucnvlat1.cpp',
|
||||
'/intl/icu/source/common/ucnvmbcs.cpp',
|
||||
'/intl/icu/source/common/ucnvscsu.c',
|
||||
'/intl/icu/source/common/ucnvscsu.cpp',
|
||||
'/intl/icu/source/common/ucnvsel.cpp',
|
||||
'/intl/icu/source/common/ucol_swp.cpp',
|
||||
'/intl/icu/source/common/ucurr.cpp',
|
||||
'/intl/icu/source/common/udata.cpp',
|
||||
'/intl/icu/source/common/udatamem.c',
|
||||
'/intl/icu/source/common/udataswp.c',
|
||||
'/intl/icu/source/common/uenum.c',
|
||||
'/intl/icu/source/common/uhash.c',
|
||||
'/intl/icu/source/common/udatamem.cpp',
|
||||
'/intl/icu/source/common/udataswp.cpp',
|
||||
'/intl/icu/source/common/uenum.cpp',
|
||||
'/intl/icu/source/common/uhash.cpp',
|
||||
'/intl/icu/source/common/uhash_us.cpp',
|
||||
'/intl/icu/source/common/uidna.cpp',
|
||||
'/intl/icu/source/common/uinit.cpp',
|
||||
'/intl/icu/source/common/uinvchar.c',
|
||||
'/intl/icu/source/common/uinvchar.cpp',
|
||||
'/intl/icu/source/common/uiter.cpp',
|
||||
'/intl/icu/source/common/ulist.c',
|
||||
'/intl/icu/source/common/ulist.cpp',
|
||||
'/intl/icu/source/common/ulistformatter.cpp',
|
||||
'/intl/icu/source/common/uloc.cpp',
|
||||
'/intl/icu/source/common/uloc_keytype.cpp',
|
||||
'/intl/icu/source/common/uloc_tag.c',
|
||||
'/intl/icu/source/common/umapfile.c',
|
||||
'/intl/icu/source/common/umath.c',
|
||||
'/intl/icu/source/common/uloc_tag.cpp',
|
||||
'/intl/icu/source/common/umapfile.cpp',
|
||||
'/intl/icu/source/common/umath.cpp',
|
||||
'/intl/icu/source/common/umutex.cpp',
|
||||
'/intl/icu/source/common/unames.cpp',
|
||||
'/intl/icu/source/common/unifiedcache.cpp',
|
||||
|
@ -148,11 +149,11 @@ SOURCES += [
|
|||
'/intl/icu/source/common/unormcmp.cpp',
|
||||
'/intl/icu/source/common/uobject.cpp',
|
||||
'/intl/icu/source/common/uprops.cpp',
|
||||
'/intl/icu/source/common/ures_cnv.c',
|
||||
'/intl/icu/source/common/ures_cnv.cpp',
|
||||
'/intl/icu/source/common/uresbund.cpp',
|
||||
'/intl/icu/source/common/uresdata.cpp',
|
||||
'/intl/icu/source/common/usc_impl.c',
|
||||
'/intl/icu/source/common/uscript.c',
|
||||
'/intl/icu/source/common/usc_impl.cpp',
|
||||
'/intl/icu/source/common/uscript.cpp',
|
||||
'/intl/icu/source/common/uscript_props.cpp',
|
||||
'/intl/icu/source/common/uset.cpp',
|
||||
'/intl/icu/source/common/uset_props.cpp',
|
||||
|
@ -166,23 +167,23 @@ SOURCES += [
|
|||
'/intl/icu/source/common/ustrcase.cpp',
|
||||
'/intl/icu/source/common/ustrcase_locale.cpp',
|
||||
'/intl/icu/source/common/ustrenum.cpp',
|
||||
'/intl/icu/source/common/ustrfmt.c',
|
||||
'/intl/icu/source/common/ustrfmt.cpp',
|
||||
'/intl/icu/source/common/ustring.cpp',
|
||||
'/intl/icu/source/common/ustrtrns.cpp',
|
||||
'/intl/icu/source/common/utext.cpp',
|
||||
'/intl/icu/source/common/utf_impl.c',
|
||||
'/intl/icu/source/common/utf_impl.cpp',
|
||||
'/intl/icu/source/common/util.cpp',
|
||||
'/intl/icu/source/common/util_props.cpp',
|
||||
'/intl/icu/source/common/utrace.c',
|
||||
'/intl/icu/source/common/utrace.cpp',
|
||||
'/intl/icu/source/common/utrie.cpp',
|
||||
'/intl/icu/source/common/utrie2.cpp',
|
||||
'/intl/icu/source/common/utrie2_builder.cpp',
|
||||
'/intl/icu/source/common/uts46.cpp',
|
||||
'/intl/icu/source/common/utypes.c',
|
||||
'/intl/icu/source/common/utypes.cpp',
|
||||
'/intl/icu/source/common/uvector.cpp',
|
||||
'/intl/icu/source/common/uvectr32.cpp',
|
||||
'/intl/icu/source/common/uvectr64.cpp',
|
||||
'/intl/icu/source/common/wintz.c',
|
||||
'/intl/icu/source/common/wintz.cpp',
|
||||
]
|
||||
|
||||
EXPORTS.unicode += [
|
||||
|
@ -192,10 +193,13 @@ EXPORTS.unicode += [
|
|||
'/intl/icu/source/common/unicode/bytestrie.h',
|
||||
'/intl/icu/source/common/unicode/bytestriebuilder.h',
|
||||
'/intl/icu/source/common/unicode/caniter.h',
|
||||
'/intl/icu/source/common/unicode/casemap.h',
|
||||
'/intl/icu/source/common/unicode/char16ptr.h',
|
||||
'/intl/icu/source/common/unicode/chariter.h',
|
||||
'/intl/icu/source/common/unicode/dbbi.h',
|
||||
'/intl/icu/source/common/unicode/docmain.h',
|
||||
'/intl/icu/source/common/unicode/dtintrv.h',
|
||||
'/intl/icu/source/common/unicode/edits.h',
|
||||
'/intl/icu/source/common/unicode/enumset.h',
|
||||
'/intl/icu/source/common/unicode/errorcode.h',
|
||||
'/intl/icu/source/common/unicode/filteredbrk.h',
|
||||
|
|
Двоичные данные
config/external/icu/data/icudt58l.dat → config/external/icu/data/icudt59l.dat
поставляемый
Двоичные данные
config/external/icu/data/icudt58l.dat → config/external/icu/data/icudt59l.dat
поставляемый
Двоичный файл не отображается.
|
@ -53,12 +53,12 @@ SOURCES += [
|
|||
'/intl/icu/source/i18n/datefmt.cpp',
|
||||
'/intl/icu/source/i18n/dayperiodrules.cpp',
|
||||
'/intl/icu/source/i18n/dcfmtsym.cpp',
|
||||
'/intl/icu/source/i18n/decContext.c',
|
||||
'/intl/icu/source/i18n/decContext.cpp',
|
||||
'/intl/icu/source/i18n/decfmtst.cpp',
|
||||
'/intl/icu/source/i18n/decimalformatpattern.cpp',
|
||||
'/intl/icu/source/i18n/decimfmt.cpp',
|
||||
'/intl/icu/source/i18n/decimfmtimpl.cpp',
|
||||
'/intl/icu/source/i18n/decNumber.c',
|
||||
'/intl/icu/source/i18n/decNumber.cpp',
|
||||
'/intl/icu/source/i18n/digitaffix.cpp',
|
||||
'/intl/icu/source/i18n/digitaffixesandpadding.cpp',
|
||||
'/intl/icu/source/i18n/digitformatter.cpp',
|
||||
|
@ -167,7 +167,7 @@ SOURCES += [
|
|||
'/intl/icu/source/i18n/udatpg.cpp',
|
||||
'/intl/icu/source/i18n/ufieldpositer.cpp',
|
||||
'/intl/icu/source/i18n/uitercollationiterator.cpp',
|
||||
'/intl/icu/source/i18n/ulocdata.c',
|
||||
'/intl/icu/source/i18n/ulocdata.cpp',
|
||||
'/intl/icu/source/i18n/umsg.cpp',
|
||||
'/intl/icu/source/i18n/unesctrn.cpp',
|
||||
'/intl/icu/source/i18n/uni2name.cpp',
|
||||
|
@ -184,7 +184,7 @@ SOURCES += [
|
|||
'/intl/icu/source/i18n/uspoof_impl.cpp',
|
||||
'/intl/icu/source/i18n/utf16collationiterator.cpp',
|
||||
'/intl/icu/source/i18n/utf8collationiterator.cpp',
|
||||
'/intl/icu/source/i18n/utmscale.c',
|
||||
'/intl/icu/source/i18n/utmscale.cpp',
|
||||
'/intl/icu/source/i18n/utrans.cpp',
|
||||
'/intl/icu/source/i18n/valueformatter.cpp',
|
||||
'/intl/icu/source/i18n/visibledigits.cpp',
|
||||
|
|
|
@ -10,4 +10,4 @@
|
|||
|
||||
Library('icustubdata')
|
||||
|
||||
SOURCES += ['/intl/icu/source/stubdata/stubdata.c']
|
||||
SOURCES += ['/intl/icu/source/stubdata/stubdata.cpp']
|
||||
|
|
|
@ -1326,6 +1326,7 @@ unicode/ucol.h
|
|||
unicode/udat.h
|
||||
unicode/udatpg.h
|
||||
unicode/uenum.h
|
||||
unicode/unistr.h
|
||||
unicode/unorm.h
|
||||
unicode/unum.h
|
||||
unicode/upluralrules.h
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
"SimpleTest": false,
|
||||
"SpecialPowers": false,
|
||||
"TestUtils": false,
|
||||
"thisTestLeaksUncaughtRejectionsAndShouldBeFixed": false,
|
||||
"todo": false,
|
||||
"todo_is": false,
|
||||
"todo_isnot": false,
|
||||
|
|
|
@ -3,12 +3,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejections should be fixed.
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("[object Object]");
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed(
|
||||
"TypeError: this.transport is null");
|
||||
|
||||
/**
|
||||
* Tests that event listeners aren't fetched when the events tab isn't selected.
|
||||
*/
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejections should be fixed.
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("[object Object]");
|
||||
|
||||
/**
|
||||
* Tests that debuggee scripts are terminated on tab closure.
|
||||
*/
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejections should be fixed.
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("[object Object]");
|
||||
|
||||
// The following "connectionClosed" rejection should not be left uncaught. This
|
||||
// test has been whitelisted until the issue is fixed.
|
||||
Cu.import("resource://testing-common/PromiseTestUtils.jsm", this);
|
||||
|
|
|
@ -3,15 +3,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejections should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: this.docShell is null");
|
||||
|
||||
// When running in a standalone directory, we get this error
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: this.doc is undefined");
|
||||
|
||||
// Tests devtools API
|
||||
|
||||
"use strict";
|
||||
|
|
|
@ -7,13 +7,6 @@
|
|||
|
||||
requestLongerTimeout(5);
|
||||
|
||||
/**
|
||||
* Whitelisting this test.
|
||||
* As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
*/
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Shader Editor is " +
|
||||
"still waiting for a WebGL context to be created.");
|
||||
|
||||
function performChecks(target) {
|
||||
return Task.spawn(function* () {
|
||||
let toolIds = gDevTools.getToolDefinitionArray()
|
||||
|
|
|
@ -5,13 +5,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Whitelisting this test.
|
||||
* As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
*/
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Shader Editor is " +
|
||||
"still waiting for a WebGL context to be created.");
|
||||
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Unknown sheet source");
|
||||
|
||||
// Tests the links from the computed view to the style editor.
|
||||
|
||||
const STYLESHEET_URL = "data:text/css," + encodeURIComponent(
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
// FIXME: Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Unknown sheet source");
|
||||
|
||||
// Test the links from the rule-view to the styleeditor
|
||||
|
||||
const STYLESHEET_URL = "data:text/css," + encodeURIComponent(
|
||||
|
|
|
@ -5,12 +5,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("false");
|
||||
|
||||
// Test that hovering over the markup-view's containers doesn't always show the
|
||||
// highlighter, depending on the type of node hovered over.
|
||||
|
||||
|
|
|
@ -206,21 +206,22 @@ function initialHTML(doc) {
|
|||
os = "linux";
|
||||
}
|
||||
|
||||
let base = doc.createElement("base");
|
||||
base.href = "resource://devtools/client/jsonview/";
|
||||
// The base URI is prepended to all URIs instead of using a <base> element
|
||||
// because the latter can be blocked by a CSP base-uri directive (bug 1316393)
|
||||
let baseURI = "resource://devtools/client/jsonview/";
|
||||
|
||||
let style = doc.createElement("link");
|
||||
style.rel = "stylesheet";
|
||||
style.type = "text/css";
|
||||
style.href = "css/main.css";
|
||||
style.href = baseURI + "css/main.css";
|
||||
|
||||
let script = doc.createElement("script");
|
||||
script.src = "lib/require.js";
|
||||
script.dataset.main = "viewer-config";
|
||||
script.src = baseURI + "lib/require.js";
|
||||
script.dataset.main = baseURI + "viewer-config.js";
|
||||
script.defer = true;
|
||||
|
||||
let head = doc.createElement("head");
|
||||
head.append(base, style, script);
|
||||
head.append(style, script);
|
||||
|
||||
return "<!DOCTYPE html>\n" +
|
||||
startTag("html", {
|
||||
|
|
|
@ -4,6 +4,8 @@ subsuite = devtools
|
|||
support-files =
|
||||
array_json.json
|
||||
array_json.json^headers^
|
||||
csp_json.json
|
||||
csp_json.json^headers^
|
||||
doc_frame_script.js
|
||||
head.js
|
||||
invalid_json.json
|
||||
|
@ -27,6 +29,7 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
|
|||
[browser_jsonview_copy_rawdata.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_jsonview_csp_json.js]
|
||||
[browser_jsonview_empty_object.js]
|
||||
[browser_jsonview_filter.js]
|
||||
[browser_jsonview_invalid_json.js]
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_JSON_URL = URL_ROOT + "csp_json.json";
|
||||
|
||||
add_task(function* () {
|
||||
info("Test CSP JSON started");
|
||||
|
||||
yield addJsonViewTab(TEST_JSON_URL);
|
||||
|
||||
let count = yield getElementCount(".jsonPanelBox .treeTable .treeRow");
|
||||
is(count, 1, "There must be one row");
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
{"csp": true}
|
|
@ -0,0 +1,2 @@
|
|||
Content-Type: application/json
|
||||
Content-Security-Policy: default-src 'none'; base-uri 'none';
|
|
@ -21,7 +21,7 @@
|
|||
* of the code base, so it's consistent and modules can be easily reused.
|
||||
*/
|
||||
require.config({
|
||||
baseUrl: ".",
|
||||
baseUrl: "resource://devtools/client/jsonview/",
|
||||
paths: {
|
||||
"devtools/client/shared": "resource://devtools/client/shared",
|
||||
"devtools/shared": "resource://devtools/shared",
|
||||
|
|
|
@ -3,12 +3,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy");
|
||||
|
||||
function test() {
|
||||
let manager = ResponsiveUIManager;
|
||||
let done;
|
||||
|
|
|
@ -3,13 +3,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed(
|
||||
"Error: Shader Editor is still waiting for a WebGL context to be created.");
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"<p>browser_telemetry_toolboxtabs_shadereditor.js</p>";
|
||||
|
||||
|
|
|
@ -5,14 +5,6 @@
|
|||
|
||||
// Tests that the developer toolbar works properly
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed(
|
||||
"Protocol error (unknownError): Error: Got an invalid root window in DocumentWalker"
|
||||
);
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<p>Tooltip Tests</p>";
|
||||
const PREF_DEVTOOLS_THEME = "devtools.theme";
|
||||
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Connection closed");
|
||||
|
||||
/**
|
||||
* Tests that the reloading/onContentLoaded hooks work.
|
||||
*/
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Connection closed");
|
||||
|
||||
/**
|
||||
* Tests that reloading a tab will properly listen for the `start-context`
|
||||
* event and reshow the tools after reloading.
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
//
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
|
||||
//
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Connection closed");
|
||||
|
||||
/**
|
||||
* Tests that switching to an iframe works fine.
|
||||
*/
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("null");
|
||||
|
||||
// Test the webconsole output for various types of objects.
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,test for console output - 01";
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("null");
|
||||
|
||||
// Test the webconsole output for various types of objects.
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
|
|
|
@ -8,10 +8,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed(null);
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed(
|
||||
"TypeError: this.toolbox is null");
|
||||
|
||||
// Test the webconsole output for various types of DOM Nodes.
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("null");
|
||||
|
||||
// Test the webconsole output for DOM events.
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
|
|
|
@ -634,7 +634,12 @@ AudioChannelService::IsWindowActive(nsPIDOMWindowOuter* aWindow)
|
|||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
AudioChannelWindow* winData = GetOrCreateWindowData(window);
|
||||
|
||||
AudioChannelWindow* winData = GetWindowData(window->WindowID());
|
||||
if (!winData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !winData->mAudibleAgents.IsEmpty();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/net/WebSocketChannel.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
|
@ -853,11 +852,16 @@ WebSocketImpl::OnAcknowledge(nsISupports *aContext, uint32_t aSize)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aSize > mWebSocket->mOutgoingBufferedAmount) {
|
||||
MOZ_RELEASE_ASSERT(mWebSocket->mOutgoingBufferedAmount.isValid());
|
||||
if (aSize > mWebSocket->mOutgoingBufferedAmount.value()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mWebSocket->mOutgoingBufferedAmount -= aSize;
|
||||
if (!mWebSocket->mOutgoingBufferedAmount.isValid()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2173,7 +2177,7 @@ WebSocket::UpdateMustKeepAlive()
|
|||
if (mListenerManager->HasListenersFor(MESSAGE_EVENT_STRING) ||
|
||||
mListenerManager->HasListenersFor(ERROR_EVENT_STRING) ||
|
||||
mListenerManager->HasListenersFor(CLOSE_EVENT_STRING) ||
|
||||
mOutgoingBufferedAmount != 0) {
|
||||
mOutgoingBufferedAmount.value() != 0) {
|
||||
shouldKeepAlive = true;
|
||||
}
|
||||
}
|
||||
|
@ -2355,7 +2359,8 @@ uint32_t
|
|||
WebSocket::BufferedAmount() const
|
||||
{
|
||||
AssertIsOnTargetThread();
|
||||
return mOutgoingBufferedAmount;
|
||||
MOZ_RELEASE_ASSERT(mOutgoingBufferedAmount.isValid());
|
||||
return mOutgoingBufferedAmount.value();
|
||||
}
|
||||
|
||||
// webIDL: attribute BinaryType binaryType;
|
||||
|
@ -2488,15 +2493,12 @@ WebSocket::Send(nsIInputStream* aMsgStream,
|
|||
}
|
||||
|
||||
// Always increment outgoing buffer len, even if closed
|
||||
CheckedUint32 size = mOutgoingBufferedAmount;
|
||||
size += aMsgLength;
|
||||
if (!size.isValid()) {
|
||||
mOutgoingBufferedAmount += aMsgLength;
|
||||
if (!mOutgoingBufferedAmount.isValid()) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
mOutgoingBufferedAmount = size.value();
|
||||
|
||||
if (readyState == CLOSING ||
|
||||
readyState == CLOSED) {
|
||||
return;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define WebSocket_h__
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "mozilla/dom/WebSocketBinding.h" // for BinaryType
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
|
@ -189,7 +190,7 @@ private:
|
|||
bool mKeepingAlive;
|
||||
bool mCheckMustKeepAlive;
|
||||
|
||||
uint32_t mOutgoingBufferedAmount;
|
||||
CheckedUint32 mOutgoingBufferedAmount;
|
||||
|
||||
// related to the WebSocket constructor steps
|
||||
nsString mURI;
|
||||
|
|
|
@ -326,6 +326,7 @@ nsHtml5StringParser* nsContentUtils::sHTMLFragmentParser = nullptr;
|
|||
nsIParser* nsContentUtils::sXMLFragmentParser = nullptr;
|
||||
nsIFragmentContentSink* nsContentUtils::sXMLFragmentSink = nullptr;
|
||||
bool nsContentUtils::sFragmentParsingActive = false;
|
||||
nsISerialEventTarget* nsContentUtils::sStableStateEventTarget = nullptr;
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
bool nsContentUtils::sDOMWindowDumpEnabled;
|
||||
|
@ -519,6 +520,52 @@ class SameOriginCheckerImpl final : public nsIChannelEventSink,
|
|||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
};
|
||||
|
||||
class StableStateEventTarget final : public nsISerialEventTarget
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIEVENTTARGET_FULL
|
||||
private:
|
||||
~StableStateEventTarget() {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(StableStateEventTarget, nsISerialEventTarget);
|
||||
|
||||
bool
|
||||
StableStateEventTarget::IsOnCurrentThreadInfallible()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StableStateEventTarget::IsOnCurrentThread(bool* aResult)
|
||||
{
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StableStateEventTarget::Dispatch(already_AddRefed<nsIRunnable> aEvent, uint32_t aFlags)
|
||||
{
|
||||
if (NS_WARN_IF(!CycleCollectedJSContext::Get())) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
nsContentUtils::RunInStableState(Move(aEvent));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StableStateEventTarget::DispatchFromScript(nsIRunnable* aEvent, uint32_t aFlags)
|
||||
{
|
||||
return Dispatch(nsCOMPtr<nsIRunnable>(aEvent).forget(), aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StableStateEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable> aEvent, uint32_t aDelay)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
|
@ -539,7 +586,7 @@ public:
|
|||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
virtual void AnnotateHang(HangMonitor::HangAnnotations& aAnnotations) override;
|
||||
void AnnotateHang(HangMonitor::HangAnnotations& aAnnotations) override;
|
||||
|
||||
static Atomic<bool> sUserActive;
|
||||
|
||||
|
@ -730,6 +777,9 @@ nsContentUtils::Init()
|
|||
|
||||
Unused << nsRFPService::GetOrCreate();
|
||||
|
||||
RefPtr<StableStateEventTarget> stableStateEventTarget = new StableStateEventTarget();
|
||||
stableStateEventTarget.forget(&sStableStateEventTarget);
|
||||
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
|
||||
do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
@ -2156,6 +2206,8 @@ nsContentUtils::Shutdown()
|
|||
|
||||
NS_IF_RELEASE(sSameOriginChecker);
|
||||
|
||||
NS_IF_RELEASE(sStableStateEventTarget);
|
||||
|
||||
if (sUserInteractionObserver) {
|
||||
sUserInteractionObserver->Shutdown();
|
||||
NS_RELEASE(sUserInteractionObserver);
|
||||
|
@ -5661,6 +5713,13 @@ nsContentUtils::RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable)
|
|||
CycleCollectedJSContext::Get()->RunInMetastableState(Move(aRunnable));
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsISerialEventTarget*
|
||||
nsContentUtils::GetStableStateEventTarget()
|
||||
{
|
||||
return sStableStateEventTarget;
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::EnterMicroTask()
|
||||
{
|
||||
|
@ -7211,7 +7270,7 @@ nsContentUtils::IsRequestFullScreenAllowed(CallerType aCallerType)
|
|||
|
||||
if (EventStateManager::IsHandlingUserInput()) {
|
||||
TimeDuration timeout = HandlingUserInputTimeout();
|
||||
return timeout <= TimeDuration(0) ||
|
||||
return timeout <= TimeDuration(nullptr) ||
|
||||
(TimeStamp::Now() -
|
||||
EventStateManager::GetHandlingInputStart()) <= timeout;
|
||||
}
|
||||
|
|
|
@ -1885,6 +1885,16 @@ public:
|
|||
*/
|
||||
static void RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable);
|
||||
|
||||
/**
|
||||
* Returns a nsISerialEventTarget which will run any event dispatched to it
|
||||
* once the event loop has reached a "stable state". Runnables dispatched to
|
||||
* this event target must not cause any queued events to be processed (i.e.
|
||||
* must not spin the event loop).
|
||||
*
|
||||
* See RunInStableState for more information about stable states
|
||||
*/
|
||||
static nsISerialEventTarget* GetStableStateEventTarget();
|
||||
|
||||
// Call EnterMicroTask when you're entering JS execution.
|
||||
// Usually the best way to do this is to use nsAutoMicroTask.
|
||||
static void EnterMicroTask();
|
||||
|
@ -3233,6 +3243,8 @@ private:
|
|||
*/
|
||||
static bool sFragmentParsingActive;
|
||||
|
||||
static nsISerialEventTarget* sStableStateEventTarget;
|
||||
|
||||
static nsString* sShiftText;
|
||||
static nsString* sControlText;
|
||||
static nsString* sMetaText;
|
||||
|
|
|
@ -2733,7 +2733,8 @@ nsDOMWindowUtils::ZoomToFocusedInput()
|
|||
while (currentFrame) {
|
||||
if (currentFrame == rootFrame) {
|
||||
break;
|
||||
} else if (currentFrame == scrolledFrame) {
|
||||
}
|
||||
if (currentFrame == scrolledFrame) {
|
||||
// we are in the rootScrollFrame so this element is not fixed
|
||||
isFixedPos = false;
|
||||
break;
|
||||
|
|
|
@ -547,7 +547,7 @@ public:
|
|||
nsresult Call() override;
|
||||
|
||||
private:
|
||||
~IdleRequestExecutorTimeoutHandler() {}
|
||||
~IdleRequestExecutorTimeoutHandler() override {}
|
||||
RefPtr<IdleRequestExecutor> mExecutor;
|
||||
};
|
||||
|
||||
|
@ -612,7 +612,7 @@ private:
|
|||
|
||||
void DelayedDispatch(uint32_t aDelay);
|
||||
|
||||
~IdleRequestExecutor() {}
|
||||
~IdleRequestExecutor() override {}
|
||||
|
||||
bool mDispatched;
|
||||
TimeStamp mDeadline;
|
||||
|
@ -897,7 +897,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
~IdleRequestTimeoutHandler() {}
|
||||
~IdleRequestTimeoutHandler() override {}
|
||||
|
||||
RefPtr<IdleRequest> mIdleRequest;
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
|
@ -1088,8 +1088,7 @@ public:
|
|||
bool* isOrdinary,
|
||||
JS::MutableHandle<JSObject*> protop) const override;
|
||||
|
||||
bool enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandle<JSObject*> vp) const override;
|
||||
JSObject* enumerate(JSContext *cx, JS::Handle<JSObject*> proxy) const override;
|
||||
bool preventExtensions(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::ObjectOpResult& result) const override;
|
||||
|
@ -1418,13 +1417,12 @@ nsOuterWindowProxy::getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObj
|
|||
return js::AppendUnique(cx, props, innerProps);
|
||||
}
|
||||
|
||||
bool
|
||||
nsOuterWindowProxy::enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandle<JSObject*> objp) const
|
||||
JSObject*
|
||||
nsOuterWindowProxy::enumerate(JSContext *cx, JS::Handle<JSObject*> proxy) const
|
||||
{
|
||||
// BaseProxyHandler::enumerate seems to do what we want here: fall
|
||||
// back on the property names returned from js::GetPropertyKeys()
|
||||
return js::BaseProxyHandler::enumerate(cx, proxy, objp);
|
||||
return js::BaseProxyHandler::enumerate(cx, proxy);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -3952,7 +3950,7 @@ nsGlobalWindow::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
|||
// will receive a vrdisplayactive event to indicate that it should
|
||||
// immediately begin vr presentation. This should occur when navigating
|
||||
// forwards, navigating backwards, and on page reload.
|
||||
for (auto display : mVRDisplays) {
|
||||
for (const auto& display : mVRDisplays) {
|
||||
if (display->IsPresenting()) {
|
||||
// Save this VR display ID to trigger vrdisplayactivate event
|
||||
// after the next load event.
|
||||
|
@ -8900,7 +8898,7 @@ nsGlobalWindow::FireAbuseEvents(const nsAString &aPopupURL,
|
|||
// use the base URI to build what would have been the popup's URI
|
||||
nsCOMPtr<nsIIOService> ios(do_GetService(NS_IOSERVICE_CONTRACTID));
|
||||
if (ios)
|
||||
ios->NewURI(NS_ConvertUTF16toUTF8(aPopupURL), 0, baseURL,
|
||||
ios->NewURI(NS_ConvertUTF16toUTF8(aPopupURL), nullptr, baseURL,
|
||||
getter_AddRefs(popupURI));
|
||||
|
||||
// fire an event chock full of informative URIs
|
||||
|
@ -10757,7 +10755,9 @@ void nsGlobalWindow::SetIsBackground(bool aIsBackground)
|
|||
inner->StopGamepadHaptics();
|
||||
}
|
||||
return;
|
||||
} else if (inner) {
|
||||
}
|
||||
|
||||
if (inner) {
|
||||
inner->SyncGamepadState();
|
||||
}
|
||||
}
|
||||
|
@ -13771,7 +13771,7 @@ nsGlobalWindow::IsVRContentDetected() const
|
|||
bool
|
||||
nsGlobalWindow::IsVRContentPresenting() const
|
||||
{
|
||||
for (auto display : mVRDisplays) {
|
||||
for (const auto& display : mVRDisplays) {
|
||||
if (display->IsAnyPresenting(gfx::kVRGroupAll)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -13977,7 +13977,7 @@ nsGlobalWindow::DispatchVRDisplayActivate(uint32_t aDisplayID,
|
|||
{
|
||||
// Search for the display identified with aDisplayID and fire the
|
||||
// event if found.
|
||||
for (auto display : mVRDisplays) {
|
||||
for (const auto& display : mVRDisplays) {
|
||||
if (display->DisplayId() == aDisplayID) {
|
||||
if (aReason != VRDisplayEventReason::Navigation &&
|
||||
display->IsAnyPresenting(gfx::kVRGroupContent)) {
|
||||
|
@ -14021,7 +14021,7 @@ nsGlobalWindow::DispatchVRDisplayDeactivate(uint32_t aDisplayID,
|
|||
{
|
||||
// Search for the display identified with aDisplayID and fire the
|
||||
// event if found.
|
||||
for (auto display : mVRDisplays) {
|
||||
for (const auto& display : mVRDisplays) {
|
||||
if (display->DisplayId() == aDisplayID && display->IsPresenting()) {
|
||||
// We only want to trigger this event to content that is presenting to
|
||||
// the display already.
|
||||
|
@ -14051,7 +14051,7 @@ nsGlobalWindow::DispatchVRDisplayConnect(uint32_t aDisplayID)
|
|||
{
|
||||
// Search for the display identified with aDisplayID and fire the
|
||||
// event if found.
|
||||
for (auto display : mVRDisplays) {
|
||||
for (const auto& display : mVRDisplays) {
|
||||
if (display->DisplayId() == aDisplayID) {
|
||||
// Fire event even if not presenting to the display.
|
||||
VRDisplayEventInit init;
|
||||
|
@ -14079,7 +14079,7 @@ nsGlobalWindow::DispatchVRDisplayDisconnect(uint32_t aDisplayID)
|
|||
{
|
||||
// Search for the display identified with aDisplayID and fire the
|
||||
// event if found.
|
||||
for (auto display : mVRDisplays) {
|
||||
for (const auto& display : mVRDisplays) {
|
||||
if (display->DisplayId() == aDisplayID) {
|
||||
// Fire event even if not presenting to the display.
|
||||
VRDisplayEventInit init;
|
||||
|
@ -14107,7 +14107,7 @@ nsGlobalWindow::DispatchVRDisplayPresentChange(uint32_t aDisplayID)
|
|||
{
|
||||
// Search for the display identified with aDisplayID and fire the
|
||||
// event if found.
|
||||
for (auto display : mVRDisplays) {
|
||||
for (const auto& display : mVRDisplays) {
|
||||
if (display->DisplayId() == aDisplayID) {
|
||||
// Fire event even if not presenting to the display.
|
||||
VRDisplayEventInit init;
|
||||
|
@ -14115,7 +14115,6 @@ nsGlobalWindow::DispatchVRDisplayPresentChange(uint32_t aDisplayID)
|
|||
init.mCancelable = false;
|
||||
init.mDisplay = display;
|
||||
// VRDisplayEvent.reason is not set for vrdisplaypresentchange
|
||||
|
||||
RefPtr<VRDisplayEvent> event =
|
||||
VRDisplayEvent::Constructor(this,
|
||||
NS_LITERAL_STRING("vrdisplaypresentchange"),
|
||||
|
|
|
@ -151,15 +151,22 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest,
|
|||
}
|
||||
|
||||
{
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
// Calling Notify on observers can modify the list of observers so make
|
||||
// a local copy.
|
||||
AutoTArray<nsCOMPtr<imgINotificationObserver>, 2> observers;
|
||||
for (ImageObserver* observer = &mObserverList, *next; observer;
|
||||
observer = next) {
|
||||
next = observer->mNext;
|
||||
if (observer->mObserver) {
|
||||
observer->mObserver->Notify(aRequest, aType, aData);
|
||||
observers.AppendElement(observer->mObserver);
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
for (auto& observer : observers) {
|
||||
observer->Notify(aRequest, aType, aData);
|
||||
}
|
||||
}
|
||||
|
||||
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
#include "mozilla/dom/DOMExceptionBinding.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ErrorEvent.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "nsAXPCNativeCallContext.h"
|
||||
|
@ -125,12 +126,12 @@ const size_t gStackSize = 8192;
|
|||
static const int64_t kForgetSkippableSliceDuration = 2;
|
||||
|
||||
// Maximum amount of time that should elapse between incremental CC slices
|
||||
static const int64_t kICCIntersliceDelay = 32; // ms
|
||||
static const int64_t kICCIntersliceDelay = 64; // ms
|
||||
|
||||
// Time budget for an incremental CC slice when using timer to run it.
|
||||
static const int64_t kICCSliceBudget = 5; // ms
|
||||
static const int64_t kICCSliceBudget = 3; // ms
|
||||
// Minimum budget for an incremental CC slice when using idle time to run it.
|
||||
static const int64_t kIdleICCSliceBudget = 3; // ms
|
||||
static const int64_t kIdleICCSliceBudget = 2; // ms
|
||||
|
||||
// Maximum total duration for an ICC
|
||||
static const uint32_t kMaxICCDuration = 2000; // ms
|
||||
|
@ -1741,7 +1742,10 @@ nsJSContext::RunCycleCollectorSlice(TimeStamp aDeadline)
|
|||
}
|
||||
}
|
||||
|
||||
nsCycleCollector_collectSlice(budget);
|
||||
nsCycleCollector_collectSlice(budget,
|
||||
aDeadline.IsNull() ||
|
||||
(aDeadline - TimeStamp::Now()).ToMilliseconds() <
|
||||
kICCSliceBudget);
|
||||
|
||||
gCCStats.FinishCycleCollectionSlice();
|
||||
}
|
||||
|
@ -2103,6 +2107,11 @@ CCRunnerFired(TimeStamp aDeadline, void* aData)
|
|||
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
|
||||
// Our efforts to avoid a CC have failed, so we return to let the
|
||||
// timer fire once more to trigger a CC.
|
||||
|
||||
// Clear content unbinder before the first CC slice.
|
||||
Element::ClearContentUnbinder();
|
||||
// And trigger deferred deletion too.
|
||||
nsCycleCollector_doDeferredDeletion();
|
||||
return didDoWork;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -399,8 +399,8 @@ nsPluginArray::EnsurePlugins()
|
|||
}
|
||||
|
||||
if (mPlugins.Length() == 0 && mCTPPlugins.Length() != 0) {
|
||||
nsCOMPtr<nsPluginTag> hiddenTag = new nsPluginTag("Hidden Plugin", NULL, "dummy.plugin", NULL, NULL,
|
||||
NULL, NULL, NULL, 0, 0, false);
|
||||
nsCOMPtr<nsPluginTag> hiddenTag = new nsPluginTag("Hidden Plugin", nullptr, "dummy.plugin", nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, 0, 0, false);
|
||||
mPlugins.AppendElement(new nsPluginElement(mWindow, hiddenTag));
|
||||
}
|
||||
|
||||
|
@ -408,7 +408,6 @@ nsPluginArray::EnsurePlugins()
|
|||
// fingerprintable entropy based on plugins' installation file times.
|
||||
mPlugins.Sort();
|
||||
}
|
||||
|
||||
// nsPluginElement implementation.
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginElement)
|
||||
|
|
|
@ -159,7 +159,7 @@ DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
|||
|
||||
// There is nothing else we can do to recover. Also, this data can
|
||||
// be deleted by QuotaManager at any time anyways.
|
||||
rv = WipeDatabase(dbFile, aDBDir);
|
||||
rv = WipeDatabase(aQuotaInfo, dbFile, aDBDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
|
||||
|
@ -172,7 +172,7 @@ DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
|||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
if (schemaVersion > 0 && schemaVersion < db::kFirstShippedSchemaVersion) {
|
||||
conn = nullptr;
|
||||
rv = WipeDatabase(dbFile, aDBDir);
|
||||
rv = WipeDatabase(aQuotaInfo, dbFile, aDBDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
|
||||
|
@ -188,16 +188,20 @@ DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
|||
}
|
||||
|
||||
nsresult
|
||||
DBAction::WipeDatabase(nsIFile* aDBFile, nsIFile* aDBDir)
|
||||
DBAction::WipeDatabase(const QuotaInfo& aQuotaInfo, nsIFile* aDBFile,
|
||||
nsIFile* aDBDir)
|
||||
{
|
||||
nsresult rv = aDBFile->Remove(false);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aDBFile);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aDBDir);
|
||||
|
||||
nsresult rv = RemoveNsIFile(aQuotaInfo, aDBFile);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
// Note, the -wal journal file will be automatically deleted by sqlite when
|
||||
// the new database is created. No need to explicitly delete it here.
|
||||
|
||||
// Delete the morgue as well.
|
||||
rv = BodyDeleteDir(aDBDir);
|
||||
rv = BodyDeleteDir(aQuotaInfo, aDBDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -49,7 +49,8 @@ private:
|
|||
nsresult OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aQuotaDir,
|
||||
mozIStorageConnection** aConnOut);
|
||||
|
||||
nsresult WipeDatabase(nsIFile* aDBFile, nsIFile* aDBDir);
|
||||
nsresult WipeDatabase(const QuotaInfo& aQuotaInfo, nsIFile* aDBFile,
|
||||
nsIFile* aDBDir);
|
||||
|
||||
const Mode mMode;
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "mozilla/dom/cache/FileUtils.h"
|
||||
|
||||
#include "mozilla/dom/quota/FileStreams.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/SnappyCompressOutputStream.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIFile.h"
|
||||
|
@ -24,6 +25,7 @@ namespace cache {
|
|||
using mozilla::dom::quota::FileInputStream;
|
||||
using mozilla::dom::quota::FileOutputStream;
|
||||
using mozilla::dom::quota::PERSISTENCE_TYPE_DEFAULT;
|
||||
using mozilla::dom::quota::QuotaManager;
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -63,7 +65,7 @@ BodyCreateDir(nsIFile* aBaseDir)
|
|||
|
||||
// static
|
||||
nsresult
|
||||
BodyDeleteDir(nsIFile* aBaseDir)
|
||||
BodyDeleteDir(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
|
||||
|
||||
|
@ -74,11 +76,7 @@ BodyDeleteDir(nsIFile* aBaseDir)
|
|||
rv = aBodyDir->Append(NS_LITERAL_STRING("morgue"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = aBodyDir->Remove(/* recursive = */ true);
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND ||
|
||||
rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
|
||||
rv = NS_OK;
|
||||
}
|
||||
rv = RemoveNsIFileRecursively(aQuotaInfo, aBodyDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
return rv;
|
||||
|
@ -211,6 +209,9 @@ BodyFinalizeWrite(nsIFile* aBaseDir, const nsID& aId)
|
|||
rv = finalFile->GetLeafName(finalFileName);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
// It's fine to not notify the QuotaManager that the path has been changed,
|
||||
// because its path will be updated and its size will be recalculated when
|
||||
// opening file next time.
|
||||
rv = tmpFile->RenameTo(nullptr, finalFileName);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
|
@ -247,7 +248,8 @@ BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir, const nsID& aId,
|
|||
|
||||
// static
|
||||
nsresult
|
||||
BodyDeleteFiles(nsIFile* aBaseDir, const nsTArray<nsID>& aIdList)
|
||||
BodyDeleteFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
const nsTArray<nsID>& aIdList)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -257,12 +259,7 @@ BodyDeleteFiles(nsIFile* aBaseDir, const nsTArray<nsID>& aIdList)
|
|||
getter_AddRefs(tmpFile));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = tmpFile->Remove(false /* recursive */);
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND ||
|
||||
rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
rv = RemoveNsIFile(aQuotaInfo, tmpFile);
|
||||
// Only treat file deletion as a hard failure in DEBUG builds. Users
|
||||
// can unfortunately hit this on windows if anti-virus is scanning files,
|
||||
// etc.
|
||||
|
@ -273,12 +270,7 @@ BodyDeleteFiles(nsIFile* aBaseDir, const nsTArray<nsID>& aIdList)
|
|||
getter_AddRefs(finalFile));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = finalFile->Remove(false /* recursive */);
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND ||
|
||||
rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
rv = RemoveNsIFile(aQuotaInfo, finalFile);
|
||||
// Again, only treat removal as hard failure in debug build.
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
@ -321,7 +313,8 @@ BodyIdToFile(nsIFile* aBaseDir, const nsID& aId, BodyFileType aType,
|
|||
} // namespace
|
||||
|
||||
nsresult
|
||||
BodyDeleteOrphanedFiles(nsIFile* aBaseDir, nsTArray<nsID>& aKnownBodyIdList)
|
||||
BodyDeleteOrphanedFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
nsTArray<nsID>& aKnownBodyIdList)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
|
||||
|
||||
|
@ -357,7 +350,7 @@ BodyDeleteOrphanedFiles(nsIFile* aBaseDir, nsTArray<nsID>& aKnownBodyIdList)
|
|||
|
||||
// If a file got in here somehow, try to remove it and move on
|
||||
if (NS_WARN_IF(!isDir)) {
|
||||
rv = subdir->Remove(false /* recursive */);
|
||||
rv = RemoveNsIFile(aQuotaInfo, subdir);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
continue;
|
||||
}
|
||||
|
@ -384,7 +377,7 @@ BodyDeleteOrphanedFiles(nsIFile* aBaseDir, nsTArray<nsID>& aKnownBodyIdList)
|
|||
// all considered orphans.
|
||||
if (StringEndsWith(leafName, NS_LITERAL_CSTRING(".tmp"))) {
|
||||
// remove recursively in case its somehow a directory
|
||||
rv = file->Remove(true /* recursive */);
|
||||
rv = RemoveNsIFileRecursively(aQuotaInfo, file);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
continue;
|
||||
}
|
||||
|
@ -407,7 +400,7 @@ BodyDeleteOrphanedFiles(nsIFile* aBaseDir, nsTArray<nsID>& aKnownBodyIdList)
|
|||
|
||||
if (!aKnownBodyIdList.Contains(id)) {
|
||||
// remove recursively in case its somehow a directory
|
||||
rv = file->Remove(true /* recursive */);
|
||||
rv = RemoveNsIFileRecursively(aQuotaInfo, file);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
|
@ -468,11 +461,8 @@ DeleteMarkerFile(const QuotaInfo& aQuotaInfo)
|
|||
nsresult rv = GetMarkerFileHandle(aQuotaInfo, getter_AddRefs(marker));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = marker->Remove(/* recursive = */ false);
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND ||
|
||||
rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
|
||||
rv = NS_OK;
|
||||
}
|
||||
rv = RemoveNsIFile(aQuotaInfo, marker);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// Again, no fsync is necessary. If the OS crashes before the file
|
||||
// removal is flushed, then the Cache will search for stale data on
|
||||
|
@ -496,6 +486,78 @@ MarkerFileExists(const QuotaInfo& aQuotaInfo)
|
|||
return exists;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
RemoveNsIFileRecursively(const QuotaInfo& aQuotaInfo, nsIFile* aFile)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aFile);
|
||||
|
||||
bool isDirectory = false;
|
||||
nsresult rv = aFile->IsDirectory(&isDirectory);
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND ||
|
||||
rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
if (!isDirectory) {
|
||||
return RemoveNsIFile(aQuotaInfo, aFile);
|
||||
}
|
||||
|
||||
// Unfortunately, we need to traverse all the entries and delete files one by
|
||||
// one to update their usages to the QuotaManager.
|
||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||
rv = aFile->GetDirectoryEntries(getter_AddRefs(entries));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
bool hasMore = false;
|
||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) && hasMore) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
rv = RemoveNsIFileRecursively(aQuotaInfo, file);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
// In the end, remove the folder
|
||||
rv = aFile->Remove(/* recursive */ false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
RemoveNsIFile(const QuotaInfo& aQuotaInfo, nsIFile* aFile)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aFile);
|
||||
|
||||
int64_t fileSize = 0;
|
||||
nsresult rv = aFile->GetFileSize(&fileSize);
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND ||
|
||||
rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = aFile->Remove( /* recursive */ false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
MOZ_DIAGNOSTIC_ASSERT(quotaManager);
|
||||
|
||||
quotaManager->DecreaseUsageForOrigin(PERSISTENCE_TYPE_DEFAULT,
|
||||
aQuotaInfo.mGroup, aQuotaInfo.mOrigin,
|
||||
fileSize);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -26,7 +26,7 @@ BodyCreateDir(nsIFile* aBaseDir);
|
|||
// database. We're unlikely to be able to delete the DB successfully past
|
||||
// that point due to the file being in use.
|
||||
nsresult
|
||||
BodyDeleteDir(nsIFile* aBaseDir);
|
||||
BodyDeleteDir(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir);
|
||||
|
||||
nsresult
|
||||
BodyGetCacheDir(nsIFile* aBaseDir, const nsID& aId, nsIFile** aCacheDirOut);
|
||||
|
@ -48,10 +48,12 @@ BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir, const nsID& aId,
|
|||
nsIInputStream** aStreamOut);
|
||||
|
||||
nsresult
|
||||
BodyDeleteFiles(nsIFile* aBaseDir, const nsTArray<nsID>& aIdList);
|
||||
BodyDeleteFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
const nsTArray<nsID>& aIdList);
|
||||
|
||||
nsresult
|
||||
BodyDeleteOrphanedFiles(nsIFile* aBaseDir, nsTArray<nsID>& aKnownBodyIdList);
|
||||
BodyDeleteOrphanedFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
nsTArray<nsID>& aKnownBodyIdList);
|
||||
|
||||
nsresult
|
||||
CreateMarkerFile(const QuotaInfo& aQuotaInfo);
|
||||
|
@ -62,6 +64,12 @@ DeleteMarkerFile(const QuotaInfo& aQuotaInfo);
|
|||
bool
|
||||
MarkerFileExists(const QuotaInfo& aQuotaInfo);
|
||||
|
||||
nsresult
|
||||
RemoveNsIFileRecursively(const QuotaInfo& aQuotaInfo, nsIFile* aFile);
|
||||
|
||||
nsresult
|
||||
RemoveNsIFile(const QuotaInfo& aQuotaInfo, nsIFile* aFile);
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -82,7 +82,7 @@ public:
|
|||
rv = db::DeleteCacheId(aConn, orphanedCacheIdList[i], deletedBodyIdList);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = BodyDeleteFiles(aDBDir, deletedBodyIdList);
|
||||
rv = BodyDeleteFiles(aQuotaInfo, aDBDir, deletedBodyIdList);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
AutoTArray<nsID, 64> knownBodyIdList;
|
||||
rv = db::GetKnownBodyIds(aConn, knownBodyIdList);
|
||||
|
||||
rv = BodyDeleteOrphanedFiles(aDBDir, knownBodyIdList);
|
||||
rv = BodyDeleteOrphanedFiles(aQuotaInfo, aDBDir, knownBodyIdList);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
rv = BodyDeleteFiles(dbDir, mDeletedBodyIdList);
|
||||
rv = BodyDeleteFiles(aQuotaInfo, dbDir, mDeletedBodyIdList);
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
|
||||
aResolver->Resolve(rv);
|
||||
|
@ -661,6 +661,7 @@ private:
|
|||
mResolver = aResolver;
|
||||
mDBDir = aDBDir;
|
||||
mConn = aConn;
|
||||
mQuotaInfo.emplace(aQuotaInfo);
|
||||
|
||||
// File bodies are streamed to disk via asynchronous copying. Start
|
||||
// this copying now. Each copy will eventually result in a call
|
||||
|
@ -935,7 +936,7 @@ private:
|
|||
|
||||
// Clean up any files we might have written before hitting the error.
|
||||
if (NS_FAILED(aRv)) {
|
||||
BodyDeleteFiles(mDBDir, mBodyIdWrittenList);
|
||||
BodyDeleteFiles(mQuotaInfo.ref(), mDBDir, mBodyIdWrittenList);
|
||||
}
|
||||
|
||||
// Must be released on the target thread where it was opened.
|
||||
|
@ -977,6 +978,8 @@ private:
|
|||
// accessed from any thread while mMutex locked
|
||||
Mutex mMutex;
|
||||
nsTArray<nsCOMPtr<nsISupports>> mCopyContextList;
|
||||
|
||||
Maybe<QuotaInfo> mQuotaInfo;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -46,6 +46,7 @@ support-files =
|
|||
[test_cache_orphaned_body.html]
|
||||
scheme=https
|
||||
[test_cache_untrusted.html]
|
||||
[test_cache_updateUsage.html]
|
||||
[test_chrome_constructor.html]
|
||||
[test_cache_worker_gc.html]
|
||||
scheme=https
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Cache update its usage to QuotaManager</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="large_url_list.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
function setupTestIframe() {
|
||||
return new Promise(function(resolve) {
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = "empty.html";
|
||||
iframe.onload = function() {
|
||||
window.caches = iframe.contentWindow.caches;
|
||||
resolve();
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}
|
||||
|
||||
function clearStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var request = qms.clearStoragesForPrincipal(principal);
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
function resetStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var request = qms.reset();
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
function getStorageUsage(fromMemory) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var cb = SpecialPowers.wrapCallback(function(request) {
|
||||
var result = request.result;
|
||||
resolve(result.usage);
|
||||
});
|
||||
|
||||
// Actually, the flag is used to distingulish getting group usage and origin
|
||||
// usage, but we utilize this to get usage from in-memory and the disk.
|
||||
// Default value for "fromMemory" is false.
|
||||
qms.getUsageForPrincipal(principal, cb, !!fromMemory);
|
||||
});
|
||||
}
|
||||
|
||||
async function verifyUsage() {
|
||||
// Although it returns group usage when passing true, it calculate the usage
|
||||
// from tracking usage object (in-memory object) in QuotaManager.
|
||||
let memoryUsage = await getStorageUsage(/* fromMemory */ true);
|
||||
// This will returns the origin usage by re-calculating usage from directory.
|
||||
let diskUsage = await getStorageUsage(/* fromMemory */ false);
|
||||
|
||||
is(memoryUsage, diskUsage,
|
||||
"In-memory usage and disk usage should be the same.");
|
||||
return memoryUsage;
|
||||
}
|
||||
|
||||
async function waitForIOToComplete(cache, request) {
|
||||
info("Wait for IO complete.");
|
||||
// The following lines ensure we've deleted orphaned body.
|
||||
// First, wait for cache operation delete the orphaned body.
|
||||
await cache.match(request);
|
||||
|
||||
// Finally, wait for -wal file finish its job.
|
||||
return await resetStorage();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [["dom.caches.enabled", true],
|
||||
["dom.caches.testing.enabled", true],
|
||||
["dom.quotaManager.testing", true]]
|
||||
}, async function() {
|
||||
const name = 'cacheUpdateUsage';
|
||||
const url = 'test_cache_add.js';
|
||||
const other_url = 'test_cache_put.js';
|
||||
|
||||
// This test mainly ensure DOM Cache updates its usage to QuotaManager when
|
||||
// executing an operation which creates/deletes files. To do this, we verify
|
||||
// usage by calling getUsageFromPrincipal twice with different flag(aGroup).
|
||||
// The reason is we get group usage by collecting in-memory data, and getting
|
||||
// origin usage by collecting storage usage from files.
|
||||
|
||||
await setupTestIframe();
|
||||
|
||||
info("Stage 1: Clean storage.");
|
||||
await clearStorage();
|
||||
await verifyUsage();
|
||||
|
||||
info("Stage 2: Verify CacheStorage.");
|
||||
info("Stage 2.1: Verify caches.open.");
|
||||
await caches.open(name);
|
||||
await verifyUsage();
|
||||
|
||||
info("Stage 2.2: Verify caches.delete.");
|
||||
var deleted = await caches.delete(name);
|
||||
ok(deleted, 'Cache storage should be deleted');
|
||||
// Reference from test_cache_orphanced_body.html. It ensures that all
|
||||
// the runnables have been flushed through the threads.
|
||||
await caches.has(name);
|
||||
await resetStorage();
|
||||
await verifyUsage();
|
||||
|
||||
info("Stage 3: Verify Cache.");
|
||||
let cache = await caches.open(name);
|
||||
info("Stage 3.1: Verify cache.addAll.");
|
||||
await cache.addAll([url, other_url]);
|
||||
await verifyUsage();
|
||||
info("Stage 3.1.1: Delete all cached requests.");
|
||||
await cache.delete(url);
|
||||
await cache.delete(other_url);
|
||||
await waitForIOToComplete(cache, other_url);
|
||||
let emptyUsage1 = await verifyUsage();
|
||||
|
||||
info("Stage 3.2: Verify cache.add.");
|
||||
cache = await caches.open(name);
|
||||
await cache.add(url);
|
||||
await verifyUsage();
|
||||
info("Stage 3.2.1: Delete cache.");
|
||||
await cache.delete(url);
|
||||
await waitForIOToComplete(cache, url);
|
||||
let emptyUsage2 = await verifyUsage();
|
||||
|
||||
info("Stage 3.3: Verify cache.put.");
|
||||
cache = await caches.open(name);
|
||||
response = await fetch(other_url);
|
||||
await cache.put(other_url, response);
|
||||
await verifyUsage();
|
||||
info("Stage 3.3.1: Delete cache.");
|
||||
await cache.delete(other_url);
|
||||
await waitForIOToComplete(cache, other_url);
|
||||
let emptyUsage3 = await verifyUsage();
|
||||
|
||||
// Adding same requests twice will make Cache create morgue file twice, and
|
||||
// then delete the previous one.
|
||||
info("Stage 4: Add same request twice to make removing a morgue file.");
|
||||
cache = await caches.open(name);
|
||||
info("Stage 4.1: First cache.add.");
|
||||
await cache.add(url);
|
||||
await verifyUsage();
|
||||
|
||||
info("Stage 4.2: Second cache.add.");
|
||||
await cache.add(url);
|
||||
|
||||
// Since we trigger the action to delete orphaned body, we need to wait for
|
||||
// the action is done.
|
||||
await waitForIOToComplete(cache, url);
|
||||
await verifyUsage();
|
||||
cache = await caches.open(name);
|
||||
info("Stage 4.2.1: cache.delete.");
|
||||
await cache.delete(url);
|
||||
await waitForIOToComplete(cache, url);
|
||||
let emptyUsage4 = await verifyUsage();
|
||||
|
||||
info("Stage 5: Clean caches.");
|
||||
await caches.delete(name);
|
||||
|
||||
info("Stage 6: Final Check.");
|
||||
ok(emptyUsage1 == emptyUsage2 &&
|
||||
emptyUsage1 == emptyUsage3 &&
|
||||
emptyUsage1 == emptyUsage4,
|
||||
"Empty usages should be the same");
|
||||
|
||||
await SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -395,9 +395,7 @@ FetchBodyConsumer<Derived>::FetchBodyConsumer(nsIEventTarget* aMainThreadEventTa
|
|||
, mWorkerPrivate(aWorkerPrivate)
|
||||
, mConsumeType(aType)
|
||||
, mConsumePromise(aPromise)
|
||||
#ifdef DEBUG
|
||||
, mReadDone(false)
|
||||
#endif
|
||||
, mBodyConsumed(false)
|
||||
{
|
||||
MOZ_ASSERT(aMainThreadEventTarget);
|
||||
MOZ_ASSERT(aBody);
|
||||
|
@ -533,10 +531,11 @@ FetchBodyConsumer<Derived>::ContinueConsumeBody(nsresult aStatus,
|
|||
// Just a precaution to ensure ContinueConsumeBody is not called out of
|
||||
// sync with a body read.
|
||||
MOZ_ASSERT(mBody->BodyUsed());
|
||||
MOZ_ASSERT(!mReadDone);
|
||||
#ifdef DEBUG
|
||||
mReadDone = true;
|
||||
#endif
|
||||
|
||||
if (mBodyConsumed) {
|
||||
return;
|
||||
}
|
||||
mBodyConsumed = true;
|
||||
|
||||
auto autoFree = mozilla::MakeScopeExit([&] {
|
||||
free(aResult);
|
||||
|
@ -672,11 +671,12 @@ FetchBodyConsumer<Derived>::ContinueConsumeBlobBody(BlobImpl* aBlobImpl)
|
|||
// Just a precaution to ensure ContinueConsumeBody is not called out of
|
||||
// sync with a body read.
|
||||
MOZ_ASSERT(mBody->BodyUsed());
|
||||
MOZ_ASSERT(!mReadDone);
|
||||
MOZ_ASSERT(mConsumeType == CONSUME_BLOB);
|
||||
#ifdef DEBUG
|
||||
mReadDone = true;
|
||||
#endif
|
||||
|
||||
if (mBodyConsumed) {
|
||||
return;
|
||||
}
|
||||
mBodyConsumed = true;
|
||||
|
||||
MOZ_ASSERT(mConsumePromise);
|
||||
RefPtr<Promise> localPromise = mConsumePromise.forget();
|
||||
|
|
|
@ -106,9 +106,7 @@ private:
|
|||
FetchConsumeType mConsumeType;
|
||||
RefPtr<Promise> mConsumePromise;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool mReadDone;
|
||||
#endif
|
||||
bool mBodyConsumed;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -1430,8 +1430,7 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
if (!mDoneCreating) {
|
||||
mShouldInitChecked = true;
|
||||
} else {
|
||||
DoSetChecked(DefaultChecked(), true, true);
|
||||
SetCheckedChanged(false);
|
||||
DoSetChecked(DefaultChecked(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6555,8 +6554,7 @@ HTMLInputElement::DoneCreatingElement()
|
|||
// property.
|
||||
//
|
||||
if (!restoredCheckedState && mShouldInitChecked) {
|
||||
DoSetChecked(DefaultChecked(), false, true);
|
||||
DoSetCheckedChanged(false, false);
|
||||
DoSetChecked(DefaultChecked(), false, false);
|
||||
}
|
||||
|
||||
// Sanitize the value.
|
||||
|
|
|
@ -859,6 +859,17 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
|||
uint32_t maxTouchPoints = 0;
|
||||
DimensionInfo dimensionInfo;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow;
|
||||
if (aParent) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow =
|
||||
nsPIDOMWindowOuter::From(aParent)->GetTop();
|
||||
if (parentTopWindow) {
|
||||
parentTopInnerWindow = parentTopWindow->GetCurrentInnerWindow();
|
||||
}
|
||||
}
|
||||
|
||||
// Send down the request to open the window.
|
||||
RefPtr<CreateWindowPromise> windowCreated;
|
||||
if (aIframeMoz) {
|
||||
MOZ_ASSERT(aTabOpener);
|
||||
nsAutoCString url;
|
||||
|
@ -871,10 +882,11 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
|||
url.SetIsVoid(true);
|
||||
}
|
||||
|
||||
newChild->SendBrowserFrameOpenWindow(aTabOpener, renderFrame, NS_ConvertUTF8toUTF16(url),
|
||||
name, NS_ConvertUTF8toUTF16(features),
|
||||
aWindowIsNew, &textureFactoryIdentifier,
|
||||
&layersId, &compositorOptions, &maxTouchPoints);
|
||||
// NOTE: BrowserFrameOpenWindowPromise is the same type as
|
||||
// CreateWindowPromise, and this code depends on that fact.
|
||||
windowCreated =
|
||||
newChild->SendBrowserFrameOpenWindow(aTabOpener, renderFrame, NS_ConvertUTF8toUTF16(url),
|
||||
name, NS_ConvertUTF8toUTF16(features));
|
||||
} else {
|
||||
nsAutoCString baseURIString;
|
||||
float fullZoom;
|
||||
|
@ -883,30 +895,98 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (!SendCreateWindow(aTabOpener, newChild, renderFrame,
|
||||
aChromeFlags, aCalledFromJS, aPositionSpecified,
|
||||
aSizeSpecified,
|
||||
features,
|
||||
baseURIString,
|
||||
fullZoom,
|
||||
&rv,
|
||||
aWindowIsNew,
|
||||
&frameScripts,
|
||||
&urlToLoad,
|
||||
&textureFactoryIdentifier,
|
||||
&layersId,
|
||||
&compositorOptions,
|
||||
&maxTouchPoints,
|
||||
&dimensionInfo)) {
|
||||
PRenderFrameChild::Send__delete__(renderFrame);
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
PRenderFrameChild::Send__delete__(renderFrame);
|
||||
return rv;
|
||||
}
|
||||
windowCreated =
|
||||
SendCreateWindow(aTabOpener, newChild, renderFrame,
|
||||
aChromeFlags, aCalledFromJS, aPositionSpecified,
|
||||
aSizeSpecified,
|
||||
features,
|
||||
baseURIString,
|
||||
fullZoom);
|
||||
}
|
||||
|
||||
// Await the promise being resolved. When the promise is resolved, we'll set
|
||||
// the `ready` local variable, which will cause us to exit our nested event
|
||||
// loop.
|
||||
//
|
||||
// NOTE: We need to run this callback on the StableStateEventTarget because we
|
||||
// need to resolve our runnable and exit from the nested event loop before
|
||||
// processing any events which were sent after the reply to CreateWindow was
|
||||
// sent.
|
||||
bool ready = false;
|
||||
windowCreated->Then(nsContentUtils::GetStableStateEventTarget(), __func__,
|
||||
[&] (const CreatedWindowInfo& info) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread(),
|
||||
"windowCreated->Then must run on the main thread");
|
||||
rv = info.rv();
|
||||
*aWindowIsNew = info.windowOpened();
|
||||
frameScripts = info.frameScripts();
|
||||
urlToLoad = info.urlToLoad();
|
||||
textureFactoryIdentifier = info.textureFactoryIdentifier();
|
||||
layersId = info.layersId();
|
||||
compositorOptions = info.compositorOptions();
|
||||
maxTouchPoints = info.maxTouchPoints();
|
||||
dimensionInfo = info.dimensions();
|
||||
ready = true;
|
||||
},
|
||||
[&] (const CreateWindowPromise::RejectValueType aReason) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread(),
|
||||
"windowCreated->Then must run on the main thread");
|
||||
NS_WARNING("windowCreated promise rejected");
|
||||
rv = NS_ERROR_NOT_AVAILABLE;
|
||||
ready = true;
|
||||
});
|
||||
|
||||
// =======================
|
||||
// Begin Nested Event Loop
|
||||
// =======================
|
||||
|
||||
// We have to wait for a response from either SendCreateWindow or
|
||||
// SendBrowserFrameOpenWindow with information we're going to need to return
|
||||
// from this function, So we spin a nested event loop until they get back to
|
||||
// us.
|
||||
|
||||
// Prevent the docshell from becoming active while the nested event loop is
|
||||
// spinning.
|
||||
newChild->AddPendingDocShellBlocker();
|
||||
auto removePendingDocShellBlocker = MakeScopeExit([&] {
|
||||
if (newChild) {
|
||||
newChild->RemovePendingDocShellBlocker();
|
||||
}
|
||||
});
|
||||
|
||||
// Suspend our window if we have one to make sure we don't re-enter it.
|
||||
if (parentTopInnerWindow) {
|
||||
parentTopInnerWindow->Suspend();
|
||||
}
|
||||
|
||||
{
|
||||
AutoNoJSAPI nojsapi;
|
||||
|
||||
// Spin the event loop until we get a response. Callers of this function
|
||||
// already have to guard against an inner event loop spinning in the
|
||||
// non-e10s case because of the need to spin one to create a new chrome
|
||||
// window.
|
||||
SpinEventLoopUntil([&] () { return ready; });
|
||||
MOZ_RELEASE_ASSERT(ready,
|
||||
"We are on the main thread, so we should not exit this "
|
||||
"loop without ready being true.");
|
||||
}
|
||||
|
||||
if (parentTopInnerWindow) {
|
||||
parentTopInnerWindow->Resume();
|
||||
}
|
||||
|
||||
// =====================
|
||||
// End Nested Event Loop
|
||||
// =====================
|
||||
|
||||
// Handle the error which we got back from the parent process, if we got
|
||||
// one.
|
||||
if (NS_FAILED(rv)) {
|
||||
PRenderFrameChild::Send__delete__(renderFrame);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!*aWindowIsNew) {
|
||||
PRenderFrameChild::Send__delete__(renderFrame);
|
||||
return NS_ERROR_ABORT;
|
||||
|
|
|
@ -4664,25 +4664,30 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
|||
const nsCString& aFeatures,
|
||||
const nsCString& aBaseURI,
|
||||
const float& aFullZoom,
|
||||
nsresult* aResult,
|
||||
bool* aWindowIsNew,
|
||||
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
||||
nsCString* aURLToLoad,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
uint64_t* aLayersId,
|
||||
CompositorOptions* aCompositorOptions,
|
||||
uint32_t* aMaxTouchPoints,
|
||||
DimensionInfo* aDimensions)
|
||||
CreateWindowResolver&& aResolve)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
CreatedWindowInfo cwi;
|
||||
|
||||
// We always expect to open a new window here. If we don't, it's an error.
|
||||
*aWindowIsNew = true;
|
||||
*aResult = NS_OK;
|
||||
cwi.windowOpened() = true;
|
||||
cwi.layersId() = 0;
|
||||
cwi.maxTouchPoints() = 0;
|
||||
|
||||
// Make sure to resolve the resolver when this function exits, even if we
|
||||
// failed to generate a valid response.
|
||||
auto resolveOnExit = MakeScopeExit([&] {
|
||||
// Copy over the nsresult, and then resolve.
|
||||
cwi.rv() = rv;
|
||||
aResolve(cwi);
|
||||
});
|
||||
|
||||
TabParent* newTab = TabParent::GetFrom(aNewTab);
|
||||
MOZ_ASSERT(newTab);
|
||||
|
||||
auto destroyNewTabOnError = MakeScopeExit([&] {
|
||||
if (!*aWindowIsNew || NS_FAILED(*aResult)) {
|
||||
// We always expect to open a new window here. If we don't, it's an error.
|
||||
if (!cwi.windowOpened() || NS_FAILED(rv)) {
|
||||
if (newTab) {
|
||||
newTab->Destroy();
|
||||
}
|
||||
|
@ -4693,7 +4698,7 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
|||
// we must have an opener.
|
||||
newTab->SetHasContentOpener(true);
|
||||
|
||||
TabParent::AutoUseNewTab aunt(newTab, aURLToLoad);
|
||||
TabParent::AutoUseNewTab aunt(newTab, &cwi.urlToLoad());
|
||||
const uint64_t nextTabParentId = ++sNextTabParentId;
|
||||
sNextTabParents.Put(nextTabParentId, newTab);
|
||||
|
||||
|
@ -4702,35 +4707,35 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
|||
CommonCreateWindow(aThisTab, /* aSetOpener = */ true, aChromeFlags,
|
||||
aCalledFromJS, aPositionSpecified, aSizeSpecified,
|
||||
nullptr, aFeatures, aBaseURI, aFullZoom,
|
||||
nextTabParentId, NullString(), *aResult,
|
||||
newRemoteTab, aWindowIsNew);
|
||||
nextTabParentId, NullString(), rv,
|
||||
newRemoteTab, &cwi.windowOpened());
|
||||
if (!ipcResult) {
|
||||
return ipcResult;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (sNextTabParents.GetAndRemove(nextTabParentId).valueOr(nullptr)) {
|
||||
*aWindowIsNew = false;
|
||||
cwi.windowOpened() = false;
|
||||
}
|
||||
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
|
||||
|
||||
newTab->SwapFrameScriptsFrom(*aFrameScripts);
|
||||
newTab->SwapFrameScriptsFrom(cwi.frameScripts());
|
||||
|
||||
RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
|
||||
if (!newTab->SetRenderFrame(rfp) ||
|
||||
!newTab->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) {
|
||||
*aResult = NS_ERROR_FAILURE;
|
||||
!newTab->GetRenderFrameInfo(&cwi.textureFactoryIdentifier(), &cwi.layersId())) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
*aCompositorOptions = rfp->GetCompositorOptions();
|
||||
cwi.compositorOptions() = rfp->GetCompositorOptions();
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = newTab->GetWidget();
|
||||
*aMaxTouchPoints = widget ? widget->GetMaxTouchPoints() : 0;
|
||||
|
||||
// NOTE: widget must be set for this to return a meaningful value.
|
||||
*aDimensions = widget ? newTab->GetDimensionInfo() : DimensionInfo();
|
||||
if (widget) {
|
||||
cwi.maxTouchPoints() = widget->GetMaxTouchPoints();
|
||||
cwi.dimensions() = newTab->GetDimensionInfo();
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
|
|
@ -536,15 +536,7 @@ public:
|
|||
const nsCString& aFeatures,
|
||||
const nsCString& aBaseURI,
|
||||
const float& aFullZoom,
|
||||
nsresult* aResult,
|
||||
bool* aWindowIsNew,
|
||||
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
||||
nsCString* aURLToLoad,
|
||||
layers::TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
uint64_t* aLayersId,
|
||||
mozilla::layers::CompositorOptions* aCompositorOptions,
|
||||
uint32_t* aMaxTouchPoints,
|
||||
DimensionInfo* aDimensions) override;
|
||||
CreateWindowResolver&& aResolve) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvCreateWindowInDifferentProcess(
|
||||
PBrowserParent* aThisTab,
|
||||
|
|
|
@ -22,6 +22,8 @@ using CSSRect from "Units.h";
|
|||
using CSSSize from "Units.h";
|
||||
using mozilla::LayoutDeviceIntPoint from "Units.h";
|
||||
using mozilla::dom::ScreenOrientationInternal from "mozilla/dom/ScreenOrientation.h";
|
||||
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
|
||||
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -96,5 +98,27 @@ struct DimensionInfo
|
|||
LayoutDeviceIntPoint chromeDisp;
|
||||
};
|
||||
|
||||
struct FrameScriptInfo
|
||||
{
|
||||
nsString url;
|
||||
bool runInGlobalScope;
|
||||
};
|
||||
|
||||
/**
|
||||
* The information required to complete a window creation request.
|
||||
*/
|
||||
struct CreatedWindowInfo
|
||||
{
|
||||
nsresult rv;
|
||||
bool windowOpened;
|
||||
FrameScriptInfo[] frameScripts;
|
||||
nsCString urlToLoad;
|
||||
TextureFactoryIdentifier textureFactoryIdentifier;
|
||||
uint64_t layersId;
|
||||
CompositorOptions compositorOptions;
|
||||
uint32_t maxTouchPoints;
|
||||
DimensionInfo dimensions;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -148,11 +148,6 @@ parent:
|
|||
|
||||
async PPaymentRequest();
|
||||
|
||||
/**
|
||||
* Return native data of root widget
|
||||
*/
|
||||
nested(inside_cpow) sync GetWidgetNativeData() returns (WindowsHandle value);
|
||||
|
||||
/**
|
||||
* Sends an NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW to be adopted by the
|
||||
* widget's shareable window on the chrome side. Only used on Windows.
|
||||
|
@ -458,13 +453,9 @@ parent:
|
|||
*
|
||||
* @param opener the PBrowser whose content called window.open.
|
||||
*/
|
||||
sync BrowserFrameOpenWindow(PBrowser opener, PRenderFrame renderFrame,
|
||||
nsString aURL, nsString aName, nsString aFeatures)
|
||||
returns (bool windowOpened,
|
||||
TextureFactoryIdentifier textureFactoryIdentifier,
|
||||
uint64_t layersId,
|
||||
CompositorOptions compositorOptions,
|
||||
uint32_t maxTouchPoints);
|
||||
async BrowserFrameOpenWindow(PBrowser opener, PRenderFrame renderFrame,
|
||||
nsString aURL, nsString aName, nsString aFeatures)
|
||||
returns (CreatedWindowInfo window);
|
||||
|
||||
/**
|
||||
* Tells the containing widget whether the given input block results in a
|
||||
|
@ -897,6 +888,12 @@ child:
|
|||
*/
|
||||
async SetOriginAttributes(OriginAttributes aOriginAttributes);
|
||||
|
||||
/**
|
||||
* Pass the current handle for the current native widget to the content
|
||||
* process, so it can be used by PuppetWidget.
|
||||
*/
|
||||
async SetWidgetNativeData(WindowsHandle aHandle);
|
||||
|
||||
/*
|
||||
* FIXME: write protocol!
|
||||
|
||||
|
|
|
@ -177,14 +177,6 @@ struct DomainPolicyClone
|
|||
URIParams[] superWhitelist;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct FrameScriptInfo
|
||||
{
|
||||
nsString url;
|
||||
bool runInGlobalScope;
|
||||
};
|
||||
|
||||
struct AndroidSystemInfo
|
||||
{
|
||||
nsString device;
|
||||
|
@ -990,25 +982,17 @@ parent:
|
|||
sync GetGraphicsDeviceInitData()
|
||||
returns (ContentDeviceData aData);
|
||||
|
||||
sync CreateWindow(nullable PBrowser aThisTab,
|
||||
PBrowser aNewTab,
|
||||
PRenderFrame aRenderFrame,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
bool aSizeSpecified,
|
||||
nsCString aFeatures,
|
||||
nsCString aBaseURI,
|
||||
float aFullZoom)
|
||||
returns (nsresult rv,
|
||||
bool windowOpened,
|
||||
FrameScriptInfo[] frameScripts,
|
||||
nsCString urlToLoad,
|
||||
TextureFactoryIdentifier textureFactoryIdentifier,
|
||||
uint64_t layersId,
|
||||
CompositorOptions compositorOptions,
|
||||
uint32_t maxTouchPoints,
|
||||
DimensionInfo dimensions);
|
||||
async CreateWindow(nullable PBrowser aThisTab,
|
||||
PBrowser aNewTab,
|
||||
PRenderFrame aRenderFrame,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
bool aSizeSpecified,
|
||||
nsCString aFeatures,
|
||||
nsCString aBaseURI,
|
||||
float aFullZoom)
|
||||
returns (CreatedWindowInfo window);
|
||||
|
||||
async CreateWindowInDifferentProcess(
|
||||
PBrowser aThisTab,
|
||||
|
|
|
@ -407,6 +407,11 @@ TabChild::TabChild(nsIContentChild* aManager,
|
|||
#if defined(ACCESSIBILITY)
|
||||
, mTopLevelDocAccessibleChild(nullptr)
|
||||
#endif
|
||||
, mPendingDocShellIsActive(false)
|
||||
, mPendingDocShellPreserveLayers(false)
|
||||
, mPendingDocShellReceivedMessage(false)
|
||||
, mPendingDocShellBlockers(0)
|
||||
, mWidgetNativeData(0)
|
||||
{
|
||||
nsWeakPtr weakPtrThis(do_GetWeakReference(static_cast<nsITabChild*>(this))); // for capture by the lambda
|
||||
mSetAllowedTouchBehaviorCallback = [weakPtrThis](uint64_t aInputBlockId,
|
||||
|
@ -2362,20 +2367,26 @@ TabChild::RecvDestroy()
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
|
||||
const bool& aPreserveLayers,
|
||||
const uint64_t& aLayerObserverEpoch)
|
||||
void
|
||||
TabChild::AddPendingDocShellBlocker()
|
||||
{
|
||||
// Since SetDocShellIsActive requests come in from both the hang monitor
|
||||
// channel and the PContent channel, we have an ordering problem. This code
|
||||
// ensures that we respect the order in which the requests were made and
|
||||
// ignore stale requests.
|
||||
if (mLayerObserverEpoch >= aLayerObserverEpoch) {
|
||||
return IPC_OK();
|
||||
}
|
||||
mLayerObserverEpoch = aLayerObserverEpoch;
|
||||
mPendingDocShellBlockers++;
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::RemovePendingDocShellBlocker()
|
||||
{
|
||||
mPendingDocShellBlockers--;
|
||||
if (!mPendingDocShellBlockers && mPendingDocShellReceivedMessage) {
|
||||
mPendingDocShellReceivedMessage = false;
|
||||
InternalSetDocShellIsActive(mPendingDocShellIsActive,
|
||||
mPendingDocShellPreserveLayers);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
|
||||
{
|
||||
auto clearForcePaint = MakeScopeExit([&] {
|
||||
// We might force a paint, or we might already have painted and this is a
|
||||
// no-op. In either case, once we exit this scope, we need to alert the
|
||||
|
@ -2401,7 +2412,7 @@ TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
|
|||
// We send the current layer observer epoch to the compositor so that
|
||||
// TabParent knows whether a layer update notification corresponds to the
|
||||
// latest SetDocShellIsActive request that was made.
|
||||
mPuppetWidget->GetLayerManager()->SetLayerObserverEpoch(aLayerObserverEpoch);
|
||||
mPuppetWidget->GetLayerManager()->SetLayerObserverEpoch(mLayerObserverEpoch);
|
||||
}
|
||||
|
||||
// docshell is consider prerendered only if not active yet
|
||||
|
@ -2415,8 +2426,8 @@ TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
|
|||
// notification to fire in the parent (so that it knows that the child has
|
||||
// updated its epoch). ForcePaintNoOp does that.
|
||||
if (IPCOpen()) {
|
||||
Unused << SendForcePaintNoOp(aLayerObserverEpoch);
|
||||
return IPC_OK();
|
||||
Unused << SendForcePaintNoOp(mLayerObserverEpoch);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2457,7 +2468,33 @@ TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
|
|||
} else if (!aPreserveLayers) {
|
||||
MakeHidden();
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
|
||||
const bool& aPreserveLayers,
|
||||
const uint64_t& aLayerObserverEpoch)
|
||||
{
|
||||
// Since requests to change the active docshell come in from both the hang
|
||||
// monitor channel and the PContent channel, we have an ordering problem. This
|
||||
// code ensures that we respect the order in which the requests were made and
|
||||
// ignore stale requests.
|
||||
if (mLayerObserverEpoch >= aLayerObserverEpoch) {
|
||||
return IPC_OK();
|
||||
}
|
||||
mLayerObserverEpoch = aLayerObserverEpoch;
|
||||
|
||||
// If we're currently waiting for window opening to complete, we need to hold
|
||||
// off on setting the docshell active. We queue up the values we're receiving
|
||||
// in the mWindowOpenDocShellActiveStatus.
|
||||
if (mPendingDocShellBlockers > 0) {
|
||||
mPendingDocShellReceivedMessage = true;
|
||||
mPendingDocShellIsActive = aIsActive;
|
||||
mPendingDocShellPreserveLayers = aPreserveLayers;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
InternalSetDocShellIsActive(aIsActive, aPreserveLayers);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -3175,6 +3212,13 @@ TabChild::RecvSetOriginAttributes(const OriginAttributes& aOriginAttributes)
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvSetWidgetNativeData(const WindowsHandle& aWidgetNativeData)
|
||||
{
|
||||
mWidgetNativeData = aWidgetNativeData;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::plugins::PPluginWidgetChild*
|
||||
TabChild::AllocPPluginWidgetChild()
|
||||
{
|
||||
|
|
|
@ -694,6 +694,15 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
void AddPendingDocShellBlocker();
|
||||
void RemovePendingDocShellBlocker();
|
||||
|
||||
// The HANDLE object for the widget this TabChild in.
|
||||
WindowsHandle WidgetNativeData()
|
||||
{
|
||||
return mWidgetNativeData;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~TabChild();
|
||||
|
||||
|
@ -735,6 +744,8 @@ protected:
|
|||
|
||||
virtual mozilla::ipc::IPCResult RecvSetOriginAttributes(const OriginAttributes& aOriginAttributes) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvSetWidgetNativeData(const WindowsHandle& aWidgetNativeData) override;
|
||||
|
||||
private:
|
||||
void HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
|
||||
const ScrollableLayerGuid& aGuid);
|
||||
|
@ -790,6 +801,9 @@ private:
|
|||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId);
|
||||
|
||||
void InternalSetDocShellIsActive(bool aIsActive,
|
||||
bool aPreserveLayers);
|
||||
|
||||
class DelayedDeleteRunnable;
|
||||
|
||||
TextureFactoryIdentifier mTextureFactoryIdentifier;
|
||||
|
@ -870,6 +884,13 @@ private:
|
|||
PDocAccessibleChild* mTopLevelDocAccessibleChild;
|
||||
#endif
|
||||
|
||||
bool mPendingDocShellIsActive;
|
||||
bool mPendingDocShellPreserveLayers;
|
||||
bool mPendingDocShellReceivedMessage;
|
||||
uint32_t mPendingDocShellBlockers;
|
||||
|
||||
WindowsHandle mWidgetNativeData;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
};
|
||||
|
||||
|
|
|
@ -292,6 +292,17 @@ TabParent::SetOwnerElement(Element* aElement)
|
|||
|
||||
AddWindowListeners();
|
||||
TryCacheDPIAndScale();
|
||||
|
||||
// Try to send down WidgetNativeData, now that this TabParent is associated
|
||||
// with a widget.
|
||||
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
|
||||
if (widget) {
|
||||
WindowsHandle widgetNativeData = reinterpret_cast<WindowsHandle>(
|
||||
widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
|
||||
if (widgetNativeData) {
|
||||
Unused << SendSetWidgetNativeData(widgetNativeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2308,18 +2319,6 @@ TabParent::GetTopLevelWidget()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
|
||||
{
|
||||
*aValue = 0;
|
||||
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
|
||||
if (widget) {
|
||||
*aValue = reinterpret_cast<WindowsHandle>(
|
||||
widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvSetNativeChildOfShareableWindow(const uintptr_t& aChildWindow)
|
||||
{
|
||||
|
@ -2573,21 +2572,31 @@ TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
|
|||
const nsString& aURL,
|
||||
const nsString& aName,
|
||||
const nsString& aFeatures,
|
||||
bool* aOutWindowOpened,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
uint64_t* aLayersId,
|
||||
CompositorOptions* aCompositorOptions,
|
||||
uint32_t* aMaxTouchPoints)
|
||||
BrowserFrameOpenWindowResolver&& aResolve)
|
||||
{
|
||||
CreatedWindowInfo cwi;
|
||||
cwi.rv() = NS_OK;
|
||||
cwi.layersId() = 0;
|
||||
cwi.maxTouchPoints() = 0;
|
||||
|
||||
BrowserElementParent::OpenWindowResult opened =
|
||||
BrowserElementParent::OpenWindowOOP(TabParent::GetFrom(aOpener),
|
||||
this, aRenderFrame, aURL, aName, aFeatures,
|
||||
aTextureFactoryIdentifier, aLayersId);
|
||||
*aCompositorOptions = static_cast<RenderFrameParent*>(aRenderFrame)->GetCompositorOptions();
|
||||
*aOutWindowOpened = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
|
||||
&cwi.textureFactoryIdentifier(),
|
||||
&cwi.layersId());
|
||||
cwi.compositorOptions() =
|
||||
static_cast<RenderFrameParent*>(aRenderFrame)->GetCompositorOptions();
|
||||
cwi.windowOpened() = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
*aMaxTouchPoints = widget ? widget->GetMaxTouchPoints() : 0;
|
||||
if (!*aOutWindowOpened) {
|
||||
if (widget) {
|
||||
cwi.maxTouchPoints() = widget->GetMaxTouchPoints();
|
||||
cwi.dimensions() = GetDimensionInfo();
|
||||
}
|
||||
|
||||
// Resolve the request with the information we collected.
|
||||
aResolve(cwi);
|
||||
|
||||
if (!cwi.windowOpened()) {
|
||||
Destroy();
|
||||
}
|
||||
return IPC_OK();
|
||||
|
|
|
@ -165,16 +165,13 @@ public:
|
|||
virtual mozilla::ipc::IPCResult
|
||||
RecvSetHasBeforeUnload(const bool& aHasBeforeUnload) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
|
||||
PRenderFrameParent* aRenderFrame,
|
||||
const nsString& aURL,
|
||||
const nsString& aName,
|
||||
const nsString& aFeatures,
|
||||
bool* aOutWindowOpened,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
uint64_t* aLayersId,
|
||||
CompositorOptions* aCompositorOptions,
|
||||
uint32_t* aMaxTouchPoints) override;
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
|
||||
PRenderFrameParent* aRenderFrame,
|
||||
const nsString& aURL,
|
||||
const nsString& aName,
|
||||
const nsString& aFeatures,
|
||||
BrowserFrameOpenWindowResolver&& aResolve) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvSyncMessage(const nsString& aMessage,
|
||||
|
@ -308,8 +305,6 @@ public:
|
|||
|
||||
virtual mozilla::ipc::IPCResult RecvGetWidgetRounding(int32_t* aValue) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvGetWidgetNativeData(WindowsHandle* aValue) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvSetNativeChildOfShareableWindow(const uintptr_t& childWindow) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvDispatchFocusToTopLevelWindow() override;
|
||||
|
|
|
@ -91,7 +91,7 @@ static int g_log_level = GL_CRIT;
|
|||
} while(0)
|
||||
|
||||
|
||||
GMPPlatformAPI* g_platform_api = NULL;
|
||||
GMPPlatformAPI* g_platform_api = nullptr;
|
||||
|
||||
class FakeVideoEncoder;
|
||||
class FakeVideoDecoder;
|
||||
|
@ -151,7 +151,7 @@ class FakeVideoEncoder : public GMPVideoEncoder {
|
|||
public:
|
||||
explicit FakeVideoEncoder (GMPVideoHost* hostAPI) :
|
||||
host_ (hostAPI),
|
||||
callback_ (NULL),
|
||||
callback_ (nullptr),
|
||||
frames_encoded_(0) {}
|
||||
|
||||
void InitEncode (const GMPVideoCodec& codecSettings,
|
||||
|
@ -337,7 +337,7 @@ class FakeVideoDecoder : public GMPVideoDecoder {
|
|||
public:
|
||||
explicit FakeVideoDecoder (GMPVideoHost* hostAPI) :
|
||||
host_ (hostAPI),
|
||||
callback_ (NULL) {}
|
||||
callback_ (nullptr) {}
|
||||
|
||||
~FakeVideoDecoder() override = default;
|
||||
|
||||
|
@ -415,7 +415,7 @@ class FakeVideoDecoder : public GMPVideoDecoder {
|
|||
<< " timestamp="
|
||||
<< inputFrame->TimeStamp());
|
||||
|
||||
GMPVideoFrame* ftmp = NULL;
|
||||
GMPVideoFrame* ftmp = nullptr;
|
||||
|
||||
// Translate the image.
|
||||
GMPErr err = host_->CreateFrame (kGMPI420VideoFrame, &ftmp);
|
||||
|
@ -488,7 +488,7 @@ extern "C" {
|
|||
|
||||
PUBLIC_FUNC void
|
||||
GMPShutdown (void) {
|
||||
g_platform_api = NULL;
|
||||
g_platform_api = nullptr;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
#define PUBLIC_FUNC
|
||||
#endif
|
||||
|
||||
GMPPlatformAPI* g_platform_api = NULL;
|
||||
GMPPlatformAPI* g_platform_api = nullptr;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
@ -83,7 +83,7 @@ extern "C" {
|
|||
|
||||
PUBLIC_FUNC void
|
||||
GMPShutdown (void) {
|
||||
g_platform_api = NULL;
|
||||
g_platform_api = nullptr;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
@ -2161,7 +2161,7 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
|
|||
TimeStamp start;
|
||||
if (Telemetry::CanRecordExtended()) {
|
||||
// Only record telemetry for scripts which are above the threshold.
|
||||
if (aRequest->mCacheInfo && aRequest->mScriptText.length() < 1024) {
|
||||
if (aRequest->mCacheInfo && aRequest->mScriptText.length() >= 1024) {
|
||||
start = TimeStamp::Now();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[Global=(Worker,DedicatedWorker),
|
||||
Exposed=DedicatedWorker]
|
||||
interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
|
||||
[Replaceable]
|
||||
readonly attribute DOMString name;
|
||||
|
||||
[Throws]
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[Global=(Worker,SharedWorker),
|
||||
Exposed=SharedWorker]
|
||||
interface SharedWorkerGlobalScope : WorkerGlobalScope {
|
||||
[Replaceable]
|
||||
readonly attribute DOMString name;
|
||||
|
||||
void close();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef mozilla_EditorUtils_h
|
||||
#define mozilla_EditorUtils_h
|
||||
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/EditorBase.h"
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -26,10 +27,6 @@ class nsRange;
|
|||
namespace mozilla {
|
||||
template <class T> class OwningNonNull;
|
||||
|
||||
namespace dom {
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
|
||||
/***************************************************************************
|
||||
* EditActionResult is useful to return multiple results of an editor
|
||||
* action handler without out params.
|
||||
|
@ -322,6 +319,23 @@ protected:
|
|||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoRangeArray final
|
||||
{
|
||||
public:
|
||||
explicit AutoRangeArray(dom::Selection* aSelection)
|
||||
{
|
||||
if (!aSelection) {
|
||||
return;
|
||||
}
|
||||
uint32_t rangeCount = aSelection->RangeCount();
|
||||
for (uint32_t i = 0; i < rangeCount; i++) {
|
||||
mRanges.AppendElement(*aSelection->GetRangeAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
AutoTArray<mozilla::OwningNonNull<nsRange>, 8> mRanges;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* some helper classes for iterating the dom tree
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -2458,10 +2458,8 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
|
|||
// except table elements.
|
||||
join = true;
|
||||
|
||||
uint32_t rangeCount = aSelection->RangeCount();
|
||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
|
||||
OwningNonNull<nsRange> range = *aSelection->GetRangeAt(rangeIdx);
|
||||
|
||||
AutoRangeArray arrayOfRanges(aSelection);
|
||||
for (auto& range : arrayOfRanges.mRanges) {
|
||||
// Build a list of nodes in the range
|
||||
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
|
||||
TrivialFunctor functor;
|
||||
|
|
|
@ -135,10 +135,8 @@ HTMLEditor::SetInlineProperty(nsIAtom* aProperty,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!cancel && !handled) {
|
||||
// Loop through the ranges in the selection
|
||||
uint32_t rangeCount = selection->RangeCount();
|
||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; rangeIdx++) {
|
||||
RefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
|
||||
|
||||
AutoRangeArray arrayOfRanges(selection);
|
||||
for (auto& range : arrayOfRanges.mRanges) {
|
||||
// Adjust range to include any ancestors whose children are entirely
|
||||
// selected
|
||||
rv = PromoteInlineRange(*range);
|
||||
|
@ -1240,25 +1238,21 @@ HTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!cancel && !handled) {
|
||||
// Loop through the ranges in the selection
|
||||
uint32_t rangeCount = selection->RangeCount();
|
||||
// Since ranges might be modified by SplitStyleAboveRange, we need hold
|
||||
// current ranges
|
||||
AutoTArray<OwningNonNull<nsRange>, 8> arrayOfRanges;
|
||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
|
||||
arrayOfRanges.AppendElement(*selection->GetRangeAt(rangeIdx));
|
||||
}
|
||||
for (auto& range : arrayOfRanges) {
|
||||
AutoRangeArray arrayOfRanges(selection);
|
||||
for (auto& range : arrayOfRanges.mRanges) {
|
||||
if (aProperty == nsGkAtoms::name) {
|
||||
// Promote range if it starts or end in a named anchor and we want to
|
||||
// remove named anchors
|
||||
rv = PromoteRangeIfStartsOrEndsInNamedAnchor(range);
|
||||
rv = PromoteRangeIfStartsOrEndsInNamedAnchor(*range);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
// Adjust range to include any ancestors whose children are entirely
|
||||
// selected
|
||||
rv = PromoteInlineRange(range);
|
||||
rv = PromoteInlineRange(*range);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1394,10 +1388,8 @@ HTMLEditor::RelativeFontChange(FontSize aDir)
|
|||
AutoTransactionsConserveSelection dontSpazMySelection(this);
|
||||
|
||||
// Loop through the ranges in the selection
|
||||
uint32_t rangeCount = selection->RangeCount();
|
||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
|
||||
RefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
|
||||
|
||||
AutoRangeArray arrayOfRanges(selection);
|
||||
for (auto& range : arrayOfRanges.mRanges) {
|
||||
// Adjust range to include any ancestors with entirely selected children
|
||||
nsresult rv = PromoteInlineRange(*range);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript">
|
||||
document.designMode = 'on';
|
||||
|
||||
let div = document.createElement('div');
|
||||
let p = document.createElement('p');
|
||||
document.documentElement.appendChild(div);
|
||||
document.documentElement.appendChild(
|
||||
document.createElement('body'));
|
||||
document.documentElement.appendChild(p);
|
||||
document.execCommand('insertimage', false, 'http://localhost/');
|
||||
document.execCommand('insertparagraph', false, null);
|
||||
|
||||
document.elementFromPoint(0, 0);
|
||||
|
||||
let selection = window.getSelection();
|
||||
selection.modify('extend', 'forward', 'character');
|
||||
|
||||
let range = document.createRange();
|
||||
range.selectNode(p);
|
||||
selection.addRange(range);
|
||||
range.setStart(div, 0);
|
||||
|
||||
range = document.createRange();
|
||||
range.selectNode(p);
|
||||
selection.addRange(range);
|
||||
|
||||
document.execCommand('delete', false, null);
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
|
@ -76,3 +76,4 @@ needs-focus load 1343918.html
|
|||
load 1348851.html
|
||||
load 1350772.html
|
||||
load 1366176.html
|
||||
load 1375131.html
|
||||
|
|
|
@ -204,6 +204,11 @@ void
|
|||
DrawTargetCaptureImpl::SetTransform(const Matrix& aTransform)
|
||||
{
|
||||
AppendCommand(SetTransformCommand)(aTransform);
|
||||
|
||||
// Have to update the transform for this DT
|
||||
// because some code paths query the current transform
|
||||
// to render specific things.
|
||||
DrawTarget::SetTransform(aTransform);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -179,6 +179,13 @@ GPUProcessManager::DisableGPUProcess(const char* aMessage)
|
|||
|
||||
DestroyProcess();
|
||||
ShutdownVsyncIOThread();
|
||||
|
||||
// We may have been in the middle of guaranteeing our various services are
|
||||
// available when one failed. Some callers may fallback to using the same
|
||||
// process equivalent, and we need to make sure those services are setup
|
||||
// correctly. We cannot re-enter DisableGPUProcess from this call because we
|
||||
// know that it is disabled in the config above.
|
||||
EnsureProtocolsReady();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -200,6 +207,14 @@ GPUProcessManager::EnsureGPUReady()
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::EnsureProtocolsReady()
|
||||
{
|
||||
EnsureCompositorManagerChild();
|
||||
EnsureImageBridgeChild();
|
||||
EnsureVRManager();
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::EnsureCompositorManagerChild()
|
||||
{
|
||||
|
@ -641,9 +656,7 @@ GPUProcessManager::CreateTopLevelCompositor(nsBaseWidget* aWidget,
|
|||
{
|
||||
uint64_t layerTreeId = AllocateLayerTreeId();
|
||||
|
||||
EnsureCompositorManagerChild();
|
||||
EnsureImageBridgeChild();
|
||||
EnsureVRManager();
|
||||
EnsureProtocolsReady();
|
||||
|
||||
RefPtr<CompositorSession> session;
|
||||
|
||||
|
|
|
@ -221,6 +221,7 @@ private:
|
|||
void EnsureVsyncIOThread();
|
||||
void ShutdownVsyncIOThread();
|
||||
|
||||
void EnsureProtocolsReady();
|
||||
void EnsureCompositorManagerChild();
|
||||
void EnsureImageBridgeChild();
|
||||
void EnsureVRManager();
|
||||
|
|
|
@ -197,6 +197,18 @@ struct TextureFactoryIdentifier
|
|||
, mUsingAdvancedLayers(false)
|
||||
, mSyncHandle(aSyncHandle)
|
||||
{}
|
||||
|
||||
bool operator==(const TextureFactoryIdentifier& aOther) const {
|
||||
return
|
||||
mParentBackend == aOther.mParentBackend &&
|
||||
mParentProcessType == aOther.mParentProcessType &&
|
||||
mMaxTextureSize == aOther.mMaxTextureSize &&
|
||||
mCompositorUseANGLE == aOther.mCompositorUseANGLE &&
|
||||
mSupportsTextureBlitting == aOther.mSupportsTextureBlitting &&
|
||||
mSupportsPartialUploads == aOther.mSupportsPartialUploads &&
|
||||
mSupportsComponentAlpha == aOther.mSupportsComponentAlpha &&
|
||||
mSyncHandle == aOther.mSyncHandle;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -693,6 +693,23 @@ public:
|
|||
return mImages.IsEmpty() ? nullptr : mImages[0].mImage.get();
|
||||
}
|
||||
|
||||
Image* GetImage(TimeStamp aTimeStamp) const
|
||||
{
|
||||
if (mImages.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!aTimeStamp.IsNull());
|
||||
uint32_t chosenIndex = 0;
|
||||
|
||||
while (chosenIndex + 1 < mImages.Length() &&
|
||||
mImages[chosenIndex + 1].mTimeStamp <= aTimeStamp) {
|
||||
++chosenIndex;
|
||||
}
|
||||
|
||||
return mImages[chosenIndex].mImage.get();
|
||||
}
|
||||
|
||||
private:
|
||||
AutoTArray<ImageContainer::OwningImage,4> mImages;
|
||||
};
|
||||
|
|
|
@ -84,6 +84,11 @@ FocusTarget::FocusTarget(nsIPresShell* aRootPresShell,
|
|||
// Key events can be retargeted to a child PresShell when there is an iframe
|
||||
nsCOMPtr<nsIPresShell> presShell = GetRetargetEventPresShell(aRootPresShell);
|
||||
|
||||
if (!presShell) {
|
||||
mType = FocusTarget::eNone;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the content that should be scrolled for this PresShell, which is
|
||||
// the current focused element or the current DOM selection
|
||||
nsCOMPtr<nsIContent> scrollTarget = presShell->GetContentForScrolling();
|
||||
|
|
|
@ -72,7 +72,7 @@ BasicImageLayer::Paint(DrawTarget* aDT,
|
|||
mContainer->SetImageFactory(mManager->IsCompositingCheap() ? nullptr : BasicManager()->GetImageFactory());
|
||||
|
||||
AutoLockImage autoLock(mContainer);
|
||||
Image *image = autoLock.GetImage();
|
||||
Image *image = autoLock.GetImage(BasicManager()->GetCompositionTime());
|
||||
if (!image) {
|
||||
mContainer->SetImageFactory(originalIF);
|
||||
return;
|
||||
|
|
|
@ -572,6 +572,8 @@ BasicLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
|
|||
NS_ASSERTION(InConstruction(), "Should be in construction phase");
|
||||
mPhase = PHASE_DRAWING;
|
||||
|
||||
SetCompositionTime(TimeStamp::Now());
|
||||
|
||||
RenderTraceLayers(mRoot, "FF00");
|
||||
|
||||
mTransactionIncomplete = false;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/Attributes.h" // for override
|
||||
#include "mozilla/WidgetUtils.h" // for ScreenRotation
|
||||
#include "mozilla/layers/LayersTypes.h" // for BufferMode, LayersBackend, etc
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
#include "nsISupportsImpl.h" // for gfxContext::AddRef, etc
|
||||
|
@ -168,6 +169,11 @@ public:
|
|||
virtual int32_t GetMaxTextureSize() const override { return INT32_MAX; }
|
||||
bool CompositorMightResample() { return mCompositorMightResample; }
|
||||
|
||||
TimeStamp GetCompositionTime() const
|
||||
{
|
||||
return mCompositionTime;
|
||||
}
|
||||
|
||||
protected:
|
||||
enum TransactionPhase {
|
||||
PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
|
||||
|
@ -198,6 +204,11 @@ protected:
|
|||
|
||||
void FlashWidgetUpdateArea(gfxContext* aContext);
|
||||
|
||||
void SetCompositionTime(TimeStamp aTimeStamp)
|
||||
{
|
||||
mCompositionTime = aTimeStamp;
|
||||
}
|
||||
|
||||
// Widget whose surface should be used as the basis for PaintedLayer
|
||||
// buffers.
|
||||
nsIWidget* mWidget;
|
||||
|
@ -213,6 +224,8 @@ protected:
|
|||
bool mUsingDefaultTarget;
|
||||
bool mTransactionIncomplete;
|
||||
bool mCompositorMightResample;
|
||||
|
||||
TimeStamp mCompositionTime;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -617,7 +617,7 @@ public:
|
|||
// register the RenderTextureHost into render thread.
|
||||
virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("No CreateRenderTexture() implementation for this TextureHost type.");
|
||||
MOZ_RELEASE_ASSERT(false, "No CreateRenderTexture() implementation for this TextureHost type.");
|
||||
}
|
||||
|
||||
// Create all necessary image keys for this textureHost rendering.
|
||||
|
|
|
@ -8,11 +8,16 @@
|
|||
#include "LayersLogging.h"
|
||||
#include "LayerManagerMLGPU.h"
|
||||
#include "MLGDevice.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/gfx/Types.h"
|
||||
#include "UnitTransforms.h"
|
||||
#include "UtilityMLGPU.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
ContainerLayerMLGPU::ContainerLayerMLGPU(LayerManagerMLGPU* aManager)
|
||||
: ContainerLayer(aManager, nullptr)
|
||||
, LayerMLGPU(aManager)
|
||||
|
@ -33,6 +38,24 @@ ContainerLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder)
|
|||
return true;
|
||||
}
|
||||
|
||||
if ((!mRenderTarget || mChildrenChanged) &&
|
||||
gfxPrefs::AdvancedLayersEnableContainerResizing())
|
||||
{
|
||||
// Try to compute a more accurate visible region.
|
||||
AL_LOG("Computing new surface size for container %p:\n", GetLayer());
|
||||
|
||||
Maybe<IntRect> bounds = ComputeIntermediateSurfaceBounds();
|
||||
if (bounds) {
|
||||
LayerIntRegion region = Move(GetShadowVisibleRegion());
|
||||
region.AndWith(LayerIntRect::FromUnknownRect(bounds.value()));
|
||||
AL_LOG(" computed bounds: %s\n", Stringify(bounds.value()).c_str());
|
||||
AL_LOG(" new visible: %s\n", Stringify(region).c_str());
|
||||
|
||||
SetShadowVisibleRegion(Move(region));
|
||||
}
|
||||
}
|
||||
mChildrenChanged = false;
|
||||
|
||||
mTargetOffset = GetIntermediateSurfaceRect().TopLeft().ToUnknownPoint();
|
||||
mTargetSize = GetIntermediateSurfaceRect().Size().ToUnknownSize();
|
||||
|
||||
|
@ -51,6 +74,89 @@ ContainerLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder)
|
|||
return true;
|
||||
}
|
||||
|
||||
static IntRect
|
||||
GetTransformedBounds(Layer* aLayer)
|
||||
{
|
||||
IntRect bounds = aLayer->GetLocalVisibleRegion().GetBounds().ToUnknownRect();
|
||||
if (bounds.IsEmpty()) {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
const Matrix4x4& transform = aLayer->GetEffectiveTransform();
|
||||
Rect rect = transform.TransformAndClipBounds(Rect(bounds), Rect::MaxIntRect());
|
||||
rect.RoundOut();
|
||||
rect.ToIntRect(&bounds);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
static Maybe<IntRect>
|
||||
FindVisibleBounds(Layer* aLayer, const Maybe<RenderTargetIntRect>& aClip)
|
||||
{
|
||||
AL_LOG(" visiting child %p\n", aLayer);
|
||||
AL_LOG_IF(aClip, " parent clip: %s\n", Stringify(aClip.value()).c_str());
|
||||
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
if (container && !container->UseIntermediateSurface()) {
|
||||
Maybe<IntRect> accumulated = Some(IntRect());
|
||||
|
||||
// Traverse children.
|
||||
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||
Maybe<RenderTargetIntRect> clip = aClip;
|
||||
if (const Maybe<ParentLayerIntRect>& childClip = child->AsHostLayer()->GetShadowClipRect()) {
|
||||
RenderTargetIntRect rtChildClip =
|
||||
TransformBy(ViewAs<ParentLayerToRenderTargetMatrix4x4>(
|
||||
aLayer->GetEffectiveTransform(),
|
||||
PixelCastJustification::RenderTargetIsParentLayerForRoot),
|
||||
childClip.value());
|
||||
clip = IntersectMaybeRects(clip, Some(rtChildClip));
|
||||
AL_LOG(" target clip: %s\n", Stringify(rtChildClip).c_str());
|
||||
AL_LOG_IF(clip, " full clip: %s\n", Stringify(clip.value()).c_str());
|
||||
}
|
||||
|
||||
Maybe<IntRect> childBounds = FindVisibleBounds(child, clip);
|
||||
if (!childBounds) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
accumulated = accumulated->SafeUnion(childBounds.value());
|
||||
if (!accumulated) {
|
||||
return Nothing();
|
||||
}
|
||||
}
|
||||
return accumulated;
|
||||
}
|
||||
|
||||
IntRect bounds = GetTransformedBounds(aLayer);
|
||||
AL_LOG(" layer bounds: %s\n", Stringify(bounds).c_str());
|
||||
|
||||
if (aClip) {
|
||||
bounds = bounds.Intersect(aClip.value().ToUnknownRect());
|
||||
AL_LOG(" clipped bounds: %s\n", Stringify(bounds).c_str());
|
||||
}
|
||||
return Some(bounds);
|
||||
}
|
||||
|
||||
Maybe<IntRect>
|
||||
ContainerLayerMLGPU::ComputeIntermediateSurfaceBounds()
|
||||
{
|
||||
Maybe<IntRect> bounds = Some(IntRect());
|
||||
for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||
Maybe<RenderTargetIntRect> clip =
|
||||
ViewAs<RenderTargetPixel>(child->AsHostLayer()->GetShadowClipRect(),
|
||||
PixelCastJustification::RenderTargetIsParentLayerForRoot);
|
||||
Maybe<IntRect> childBounds = FindVisibleBounds(child, clip);
|
||||
if (!childBounds) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
bounds = bounds->SafeUnion(childBounds.value());
|
||||
if (!bounds) {
|
||||
return Nothing();
|
||||
}
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayerMLGPU::OnLayerManagerChange(LayerManagerMLGPU* aManager)
|
||||
{
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
protected:
|
||||
bool OnPrepareToRender(FrameBuilder* aBuilder) override;
|
||||
void OnLayerManagerChange(LayerManagerMLGPU* aManager) override;
|
||||
Maybe<gfx::IntRect> ComputeIntermediateSurfaceBounds();
|
||||
|
||||
private:
|
||||
RefPtr<MLGRenderTarget> mRenderTarget;
|
||||
|
|
|
@ -32,8 +32,10 @@ template <> struct AlignUp<0>
|
|||
|
||||
#ifdef ENABLE_AL_LOGGING
|
||||
# define AL_LOG(...) printf_stderr("AL: " __VA_ARGS__)
|
||||
# define AL_LOG_IF(cond, ...) do { if (cond) { printf_stderr("AL: " __VA_ARGS__); } } while(0)
|
||||
#else
|
||||
# define AL_LOG(...)
|
||||
# define AL_LOG_IF(...)
|
||||
#endif
|
||||
|
||||
#endif // mozilla_gfx_layers_mlgpu_UtilityMLGPU_h
|
||||
|
|
|
@ -393,7 +393,7 @@ WebRenderBridgeParent::UpdateAPZ()
|
|||
}
|
||||
if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) {
|
||||
apzc->UpdateFocusState(rootLayersId, GetLayersId(),
|
||||
rootWrbp->GetScrollData().GetFocusTarget());
|
||||
mScrollData.GetFocusTarget());
|
||||
apzc->UpdateHitTestingTree(rootLayersId, rootWrbp->GetScrollData(),
|
||||
mScrollData.IsFirstPaint(), GetLayersId(),
|
||||
mScrollData.GetPaintSequenceNumber());
|
||||
|
|
|
@ -80,6 +80,7 @@ WebRenderPaintedLayerBlob::RenderLayer(wr::DisplayListBuilder& aBuilder,
|
|||
}
|
||||
mImageKey = Some(GetImageKey());
|
||||
WrBridge()->SendAddBlobImage(mImageKey.value(), imageSize, size.width * 4, dt->GetFormat(), bytes);
|
||||
mImageBounds = visibleRegion.GetBounds();
|
||||
} else {
|
||||
MOZ_ASSERT(GetInvalidRegion().IsEmpty());
|
||||
}
|
||||
|
@ -89,8 +90,9 @@ WebRenderPaintedLayerBlob::RenderLayer(wr::DisplayListBuilder& aBuilder,
|
|||
LayerRect rect = Bounds();
|
||||
DumpLayerInfo("PaintedLayer", rect);
|
||||
|
||||
WrRect r = sc.ToRelativeWrRect(rect);
|
||||
aBuilder.PushImage(r, r, wr::ImageRendering::Auto, mImageKey.value());
|
||||
aBuilder.PushImage(sc.ToRelativeWrRect(LayerRect(mImageBounds)),
|
||||
sc.ToRelativeWrRect(rect),
|
||||
wr::ImageRendering::Auto, mImageKey.value());
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -56,6 +56,7 @@ private:
|
|||
RefPtr<ImageContainer> mImageContainer;
|
||||
RefPtr<ImageClient> mImageClient;
|
||||
Maybe<WrImageKey> mImageKey;
|
||||
LayerIntRect mImageBounds;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include <unicode/unistr.h>
|
||||
#include <unicode/uversion.h>
|
||||
|
||||
#include "sfntly/table/bitmap/eblc_table.h"
|
||||
#include "sfntly/table/bitmap/ebdt_table.h"
|
||||
#include "sfntly/table/bitmap/index_sub_table.h"
|
||||
|
|
|
@ -581,6 +581,7 @@ private:
|
|||
DECL_GFX_PREF(Once, "layers.mlgpu.enable-depth-buffer", AdvancedLayersEnableDepthBuffer, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.mlgpu.enable-invalidation", AdvancedLayersUseInvalidation, bool, true);
|
||||
DECL_GFX_PREF(Once, "layers.mlgpu.enable-on-windows7", AdvancedLayersEnableOnWindows7, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.mlgpu.enable-container-resizing", AdvancedLayersEnableContainerResizing, bool, true);
|
||||
DECL_GFX_PREF(Once, "layers.offmainthreadcomposition.force-disabled", LayersOffMainThreadCompositionForceDisabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.offmainthreadcomposition.frame-rate", LayersCompositionFrameRate, int32_t,-1);
|
||||
DECL_GFX_PREF(Live, "layers.orientation.sync.timeout", OrientationSyncMillis, uint32_t, (uint32_t)0);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
diff --git a/intl/icu/source/Makefile.in b/intl/icu/source/Makefile.in
|
||||
index 9db6c52..1b9a964 100644
|
||||
--- a/intl/icu/source/Makefile.in
|
||||
+++ b/intl/icu/source/Makefile.in
|
||||
@@ -134,28 +134,32 @@ endif
|
||||
@@ -134,32 +134,36 @@ endif
|
||||
|
||||
LOCAL_SUBDIRS = $(SUBDIRS)
|
||||
CLEAN_FIRST_SUBDIRS = $(TOOLS)
|
||||
|
@ -16,6 +15,11 @@ index 9db6c52..1b9a964 100644
|
|||
+## favor of RECURSIVE=YES when the submake in the subdirectory restarts itself
|
||||
+## after dependency files have been created.
|
||||
all-recursive install-recursive clean-recursive distclean-recursive dist-recursive check-recursive check-exhaustive-recursive: $(LIBDIR) $(BINDIR)
|
||||
ifneq ($(NEED_ESCAPING),)
|
||||
@echo "building tools/escapesrc (Needed for this platform with NEED_ESCAPING)"
|
||||
- @(cd tools/escapesrc && $(MAKE) RECURSIVE=YES $$local_target) || exit
|
||||
+ @(cd tools/escapesrc && $(MAKE) $(MAKEOVERRIDES) RECURSIVE=YES $$local_target) || exit
|
||||
endif
|
||||
@dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
list='$(LOCAL_SUBDIRS)'; for subdir in $$list; do \
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
Limit libstdc++ workaround to not upset libc++ with pragma visibility.
|
||||
|
||||
https://ssl.icu-project.org/trac/ticket/12023
|
||||
|
||||
diff --git a/intl/icu/source/common/unicode/std_string.h b/intl/icu/source/common/unicode/std_string.h
|
||||
--- a/intl/icu/source/common/unicode/std_string.h
|
||||
+++ b/intl/icu/source/common/unicode/std_string.h
|
||||
@@ -24,16 +24,16 @@
|
||||
* \brief C++ API: Central ICU header for including the C++ standard <string>
|
||||
* header and for related definitions.
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if U_HAVE_STD_STRING
|
||||
|
||||
-#if !defined(_MSC_VER)
|
||||
+#if defined(__GLIBCXX__)
|
||||
namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
#endif // U_HAVE_STD_STRING
|
||||
|
||||
#endif // __STD_STRING_H__
|
||||
diff --git a/intl/icu/source/common/utypeinfo.h b/intl/icu/source/common/utypeinfo.h
|
||||
--- a/intl/icu/source/common/utypeinfo.h
|
||||
+++ b/intl/icu/source/common/utypeinfo.h
|
||||
@@ -19,14 +19,14 @@
|
||||
// Whenever 'typeid' is used, this header has to be included
|
||||
// instead of <typeinfo>.
|
||||
// Visual Studio 10 emits warning 4275 with this change. If you compile
|
||||
// with exception disabled, you have to suppress warning 4275.
|
||||
#if defined(_MSC_VER) && _HAS_EXCEPTIONS == 0
|
||||
#include <exception>
|
||||
using std::exception;
|
||||
#endif
|
||||
-#if !defined(_MSC_VER)
|
||||
+#if defined(__GLIBCXX__)
|
||||
namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364
|
||||
#endif
|
||||
#include <typeinfo> // for 'typeid' to work
|
||||
|
||||
#endif
|
||||
diff --git a/intl/icu/source/io/unicode/ustream.h b/intl/icu/source/io/unicode/ustream.h
|
||||
--- a/intl/icu/source/io/unicode/ustream.h
|
||||
+++ b/intl/icu/source/io/unicode/ustream.h
|
||||
@@ -25,17 +25,17 @@
|
||||
* \file
|
||||
* \brief C++ API: Unicode iostream like API
|
||||
*
|
||||
* At this time, this API is very limited. It contains
|
||||
* operator<< and operator>> for UnicodeString manipulation with the
|
||||
* C++ I/O stream API.
|
||||
*/
|
||||
|
||||
-#if !defined(_MSC_VER)
|
||||
+#if defined(__GLIBCXX__)
|
||||
namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364
|
||||
#endif
|
||||
|
||||
#if U_IOSTREAM_SOURCE >= 199711
|
||||
#if (__GNUC__ == 2)
|
||||
#include <iostream>
|
||||
#else
|
||||
#include <istream>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче