merge mozilla-central to autoland. r=merge a=merge

This commit is contained in:
Sebastian Hengst 2017-09-22 11:50:19 +02:00
Родитель c886bfb22b 79326d87c8
Коммит 2479eaedbf
123 изменённых файлов: 1090 добавлений и 549 удалений

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

@ -19,6 +19,14 @@ XPCOMUtils.defineLazyModuleGetters(this, {
setTimeout: "resource://gre/modules/Timer.jsm",
});
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
"@mozilla.org/serviceworkers/manager;1",
"nsIServiceWorkerManager");
XPCOMUtils.defineLazyServiceGetter(this, "quotaManagerService",
"@mozilla.org/dom/quota-manager-service;1",
"nsIQuotaManagerService");
var {classes: Cc, interfaces: Ci} = Components;
/**
@ -280,9 +288,41 @@ Sanitizer.prototype = {
offlineApps: {
async clear(range) {
// AppCache
Components.utils.import("resource:///modules/offlineAppCache.jsm");
// This doesn't wait for the cleanup to be complete.
OfflineAppCacheHelper.clear();
// LocalStorage
Services.obs.notifyObservers(null, "extension:purge-localStorage");
// ServiceWorkers
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
for (let i = 0; i < serviceWorkers.length; i++) {
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
let host = sw.principal.URI.host;
serviceWorkerManager.removeAndPropagate(host);
}
// QuotaManager
let promises = [];
await new Promise(resolve => {
quotaManagerService.getUsage(request => {
for (let item of request.result) {
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(item.origin);
let uri = principal.URI;
if (uri.scheme == "http" || uri.scheme == "https" || uri.scheme == "file") {
promises.push(new Promise(r => {
let req = quotaManagerService.clearStoragesForPrincipal(principal, null, true);
req.callback = () => { r(); };
}));
}
}
resolve();
});
});
return Promise.all(promises);
}
},

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

@ -17,6 +17,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "setTimeout",
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
"@mozilla.org/serviceworkers/manager;1",
"nsIServiceWorkerManager");
XPCOMUtils.defineLazyServiceGetter(this, "quotaManagerService",
"@mozilla.org/dom/quota-manager-service;1",
"nsIQuotaManagerService");
/**
* A number of iterations after which to yield time back
@ -80,6 +83,29 @@ const clearHistory = options => {
return sanitizer.items.history.clear(makeRange(options));
};
const clearIndexedDB = async function(options) {
let promises = [];
await new Promise(resolve => {
quotaManagerService.getUsage(request => {
for (let item of request.result) {
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(item.origin);
let uri = principal.URI;
if (uri.scheme == "http" || uri.scheme == "https" || uri.scheme == "file") {
promises.push(new Promise(r => {
let req = quotaManagerService.clearStoragesForPrincipal(principal, null, true);
req.callback = () => { r(); };
}));
}
}
resolve();
});
});
return Promise.all(promises);
};
const clearLocalStorage = async function(options) {
Services.obs.notifyObservers(null, "extension:purge-localStorage");
};
@ -153,6 +179,9 @@ const doRemoval = (options, dataToRemove, extension) => {
case "history":
removalPromises.push(clearHistory(options));
break;
case "indexedDB":
removalPromises.push(clearIndexedDB(options));
break;
case "localStorage":
removalPromises.push(clearLocalStorage(options));
break;
@ -229,6 +258,9 @@ this.browsingData = class extends ExtensionAPI {
removeHistory(options) {
return doRemoval(options, {history: true});
},
removeIndexedDB(options) {
return doRemoval(options, {indexedDB: true});
},
removeLocalStorage(options) {
return doRemoval(options, {localStorage: true});
},

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

@ -22,6 +22,7 @@ support-files =
file_dummy.html
file_title.html
file_inspectedwindow_reload_target.sjs
file_indexedDB.html
file_serviceWorker.html
locale/chrome.manifest
webNav_createdTarget.html
@ -50,6 +51,7 @@ skip-if = (os == 'win' && !debug) # bug 1352668
[browser_ext_browserAction_theme_icons.js]
[browser_ext_browsingData_formData.js]
[browser_ext_browsingData_history.js]
[browser_ext_browsingData_indexedDB.js]
[browser_ext_browsingData_localStorage.js]
[browser_ext_browsingData_pluginData.js]
[browser_ext_browsingData_serviceWorkers.js]

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

@ -0,0 +1,81 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/* eslint-disable mozilla/no-arbitrary-setTimeout */
"use strict";
add_task(async function testIndexedDB() {
function background() {
const PAGE = "/browser/browser/components/extensions/test/browser/file_indexedDB.html";
browser.test.onMessage.addListener(async (msg) => {
await browser.browsingData.remove({}, {indexedDB: true});
browser.test.sendMessage("indexedDBRemoved");
});
// Create two tabs.
browser.tabs.create({url: `http://mochi.test:8888${PAGE}`});
browser.tabs.create({url: `http://example.com${PAGE}`});
}
function contentScript() {
window.addEventListener("message", msg => { // eslint-disable-line mozilla/balanced-listeners
browser.test.sendMessage("indexedDBCreated");
}, true);
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
permissions: ["browsingData", "tabs"],
"content_scripts": [{
"matches": [
"http://mochi.test/*/file_indexedDB.html",
"http://example.com/*/file_indexedDB.html",
],
"js": ["script.js"],
"run_at": "document_start",
}],
},
files: {
"script.js": contentScript,
},
});
let win = await BrowserTestUtils.openNewBrowserWindow();
await focusWindow(win);
await extension.startup();
await extension.awaitMessage("indexedDBCreated");
await extension.awaitMessage("indexedDBCreated");
let qms = SpecialPowers.Cc["@mozilla.org/dom/quota-manager-service;1"]
.getService(Ci.nsIQuotaManagerService);
function getOrigins() {
return new Promise(resolve => {
let origins = [];
qms.getUsage(request => {
for (let i = 0; i < request.result.length; ++i) {
if (request.result[i].origin.startsWith("http://mochi.test") ||
request.result[i].origin.startsWith("http://example.com")) {
origins.push(request.result[i].origin);
}
}
resolve(origins);
});
});
}
let origins = await getOrigins();
is(origins.length, 2, "IndexedDB databases have been populated.");
extension.sendMessage();
await extension.awaitMessage("indexedDBRemoved");
origins = await getOrigins();
is(origins.length, 0, "IndexedDB data has been removed.");
await extension.unload();
await BrowserTestUtils.closeWindow(win);
});

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

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script>
"use strict";
const objectStoreName = "Objects";
let test = {key: 0, value: "test"};
let request = indexedDB.open("WebExtensionTest", 1);
request.onupgradeneeded = event => {
let db = event.target.result;
let objectStore = db.createObjectStore(objectStoreName,
{autoIncrement: 0});
request = objectStore.add(test.value, test.key);
request.onsuccess = event => {
db.close();
window.postMessage("indexedDBCreated", "*");
};
};
</script>
</head>
<body>
This is a test page.
</body>
<html>

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

@ -41,26 +41,3 @@ add_task(async function testInvalidArguments() {
await extension.awaitFinish("invalidArguments");
await extension.unload();
});
add_task(async function testUnimplementedDataType() {
function background() {
browser.browsingData.remove({}, {indexedDB: true});
browser.test.sendMessage("finished");
}
let {messages} = await promiseConsoleOutput(async function() {
let extension = ExtensionTestUtils.loadExtension({
background: background,
manifest: {
permissions: ["browsingData"],
},
});
await extension.startup();
await extension.awaitMessage("finished");
await extension.unload();
});
let warningObserved = messages.find(line => /Firefox does not support dataTypes: indexedDB/.test(line));
ok(warningObserved, "Warning issued when calling remove with an unimplemented dataType.");
});

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

@ -9,6 +9,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "OfflineAppCacheHelper",
"resource:///modules/offlineAppCache.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
"resource://gre/modules/ContextualIdentityService.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
"@mozilla.org/serviceworkers/manager;1",
"nsIServiceWorkerManager");
this.EXPORTED_SYMBOLS = [
"SiteDataManager"
@ -217,6 +220,19 @@ this.SiteDataManager = {
}
},
_removeServiceWorkers(site) {
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
for (let i = 0; i < serviceWorkers.length; i++) {
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
for (let principal of site.principals) {
if (sw.principal.equals(principal)) {
serviceWorkerManager.removeAndPropagate(sw.principal.URI.host);
break;
}
}
}
},
remove(hosts) {
let promises = [];
let unknownHost = "";
@ -226,6 +242,7 @@ this.SiteDataManager = {
this._removePermission(site);
this._removeAppCache(site);
this._removeCookie(site);
this._removeServiceWorkers(site);
promises.push(this._removeQuotaUsage(site));
} else {
unknownHost = host;
@ -244,6 +261,15 @@ this.SiteDataManager = {
Services.cache2.clear();
Services.cookies.removeAll();
OfflineAppCacheHelper.clear();
// Iterate through the service workers and remove them.
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
for (let i = 0; i < serviceWorkers.length; i++) {
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
let host = sw.principal.URI.host;
serviceWorkerManager.removeAndPropagate(host);
}
// Refresh sites using quota usage again.
// This is for the case:
// 1. User goes to the about:preferences Site Data section.

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

@ -1647,6 +1647,13 @@ var gPrivacyPane = {
},
updateA11yPrefs(checked) {
Services.prefs.setIntPref("accessibility.force_disabled", checked ? 1 : 0);
let buttonIndex = confirmRestartPrompt(checked, 0, true, false);
if (buttonIndex == CONFIRM_RESTART_PROMPT_RESTART_NOW) {
Services.prefs.setIntPref("accessibility.force_disabled", checked ? 1 : 0);
Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
}
// Revert the checkbox in case we didn't quit
document.getElementById("a11yPrivacyCheckbox").checked = !checked;
}
};

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

@ -702,11 +702,17 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
host_or_target)
# Check that the additional flags we got are enough to not require any
# more flags.
if info.flags:
flags += info.flags
info = check_compiler(wrapper + [compiler] + flags, language,
host_or_target)
# more flags. If we get an exception, just ignore it; it's liable to be
# invalid command-line flags, which means the compiler we're checking
# doesn't support those command-line flags and will fail one or more of
# the checks below.
try:
if info.flags:
flags += info.flags
info = check_compiler(wrapper + [compiler] + flags, language,
host_or_target)
except FatalCheckError:
pass
if not info.target_cpu or info.target_cpu != host_or_target.cpu:
raise FatalCheckError(
@ -732,10 +738,6 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
info.target_endianness or 'unknown', host_or_target_str,
host_or_target.endianness))
if info.flags:
raise FatalCheckError(
'Unknown compiler or compiler not supported.')
# Compiler version checks
# ===================================================
# Check the compiler version here instead of in `compiler_version` so
@ -747,7 +749,7 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
% info.version)
# If you want to bump the version check here search for
# __cpp_static_assert above, and see the associated comment.
# cxx_alignof above, and see the associated comment.
if info.type == 'clang' and not info.version:
raise FatalCheckError(
'Only clang/llvm 3.6 or newer is supported.')
@ -762,6 +764,10 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
'See https://developer.mozilla.org/en/'
'Windows_Build_Prerequisites' % info.version)
if info.flags:
raise FatalCheckError(
'Unknown compiler or compiler not supported.')
return namespace(
wrapper=wrapper,
compiler=compiler,

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

@ -1609,7 +1609,7 @@ nsDocShell::LoadURI(nsIURI* aURI,
flags,
target,
nullptr, // No type hint
NullString(), // No forced download
VoidString(), // No forced download
postStream,
headersStream,
loadType,
@ -5488,8 +5488,8 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL,
mozilla::net::RP_Unset,
nsContentUtils::GetSystemPrincipal(), nullptr,
INTERNAL_LOAD_FLAGS_NONE, EmptyString(),
nullptr, NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
nullptr, true, NullString(), this, nullptr, false,
nullptr, VoidString(), nullptr, nullptr, LOAD_ERROR_PAGE,
nullptr, true, VoidString(), this, nullptr, false,
nullptr, nullptr);
}
@ -5589,7 +5589,7 @@ nsDocShell::Reload(uint32_t aReloadFlags)
flags,
EmptyString(), // No window target
NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
NullString(), // No forced download
VoidString(), // No forced download
nullptr, // No post data
nullptr, // No headers data
loadType, // Load type
@ -9757,7 +9757,7 @@ public:
mFlags, EmptyString(),
mTypeHint.IsVoid() ? nullptr
: mTypeHint.get(),
NullString(), mPostData, mHeadersData,
VoidString(), mPostData, mHeadersData,
mLoadType, mSHEntry, mFirstParty,
mSrcdoc, mSourceDocShell, mBaseURI,
mCheckForPrerender, nullptr, nullptr);
@ -10226,7 +10226,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
aFlags,
EmptyString(), // No window target
aTypeHint,
NullString(), // No forced download
VoidString(), // No forced download
aPostData,
aHeadersData,
aLoadType,
@ -10837,7 +10837,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
if (aFlags & INTERNAL_LOAD_FLAGS_IS_SRCDOC) {
srcdoc = aSrcdoc;
} else {
srcdoc = NullString();
srcdoc = VoidString();
}
bool isTopLevelDoc = mItemType == typeContent &&
@ -12860,7 +12860,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
aEntry->GetBaseURI(getter_AddRefs(baseURI));
flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
} else {
srcdoc = NullString();
srcdoc = VoidString();
}
if (!triggeringPrincipal) {
@ -12884,7 +12884,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
flags,
EmptyString(), // No window target
contentType.get(), // Type hint
NullString(), // No forced file download
VoidString(), // No forced file download
postData, // Post data stream
nullptr, // No headers stream
aLoadType, // Load type
@ -14454,7 +14454,7 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent,
LOAD_LINK, // Load type
nullptr, // No SHEntry
true, // first party site
NullString(), // No srcdoc
VoidString(), // No srcdoc
this, // We are the source
nullptr, // baseURI not needed
true, // Check for prerendered doc

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

@ -476,7 +476,7 @@ nsSHEntry::Create(nsIURI* aURI, const nsAString& aTitle,
mShared->mExpired = false;
mIsSrcdocEntry = false;
mSrcdocData = NullString();
mSrcdocData = VoidString();
mLoadedInThisProcess = true;

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

@ -593,6 +593,9 @@ CustomElementRegistry::Define(const nsAString& aName,
}
JSContext *cx = jsapi.cx();
// Note: No calls that might run JS or trigger CC before this point, or
// there's a (vanishingly small) chance of our constructor being nulled
// before we access it.
JS::Rooted<JSObject*> constructor(cx, aFunctionConstructor.CallableOrNull());
/**
@ -878,7 +881,7 @@ CustomElementRegistry::Get(JSContext* aCx, const nsAString& aName,
return;
}
aRetVal.setObjectOrNull(data->mConstructor->CallableOrNull());
aRetVal.setObject(*data->mConstructor->Callback(aCx));
}
already_AddRefed<Promise>
@ -970,9 +973,9 @@ CustomElementRegistry::Upgrade(Element* aElement,
LifecycleCallbackArgs args = {
nsDependentAtomString(attrName),
NullString(),
(attrValue.IsEmpty() ? NullString() : attrValue),
(namespaceURI.IsEmpty() ? NullString() : namespaceURI)
VoidString(),
(attrValue.IsEmpty() ? VoidString() : attrValue),
(namespaceURI.IsEmpty() ? VoidString() : namespaceURI)
};
EnqueueLifecycleCallback(nsIDocument::eAttributeChanged, aElement,
&args, aDefinition);

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

@ -70,7 +70,7 @@ DOMImplementation::CreateDocumentType(const nsAString& aQualifiedName,
// Indicate that there is no internal subset (not just an empty one)
RefPtr<DocumentType> docType =
NS_NewDOMDocumentType(mOwner->NodeInfoManager(), name, aPublicId,
aSystemId, NullString(), aRv);
aSystemId, VoidString(), aRv);
return docType.forget();
}
@ -188,7 +188,7 @@ DOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
nsGkAtoms::html, // aName
EmptyString(), // aPublicId
EmptyString(), // aSystemId
NullString()); // aInternalSubset
VoidString()); // aInternalSubset
NS_ENSURE_SUCCESS(rv, rv);
@ -249,8 +249,7 @@ DOMImplementation::CreateHTMLDocument(const Optional<nsAString>& aTitle,
{
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIDOMDocument> domDocument;
aRv = CreateHTMLDocument(aTitle.WasPassed() ? aTitle.Value()
: NullString(),
aRv = CreateHTMLDocument(aTitle.WasPassed() ? aTitle.Value() : VoidString(),
getter_AddRefs(document),
getter_AddRefs(domDocument));
return document.forget();

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

@ -308,7 +308,11 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
}
root = rootFrame->GetContent()->AsElement();
nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
rootRect = scrollFrame->GetScrollPortRect();
// If we end up with a null root frame for some reason, we'll proceed
// with an empty root intersection rect.
if (scrollFrame) {
rootRect = scrollFrame->GetScrollPortRect();
}
}
}
}

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

@ -2642,9 +2642,9 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
LifecycleCallbackArgs args = {
nsDependentAtomString(aName),
aModType == nsIDOMMutationEvent::ADDITION ?
NullString() : nsDependentAtomString(oldValueAtom),
VoidString() : nsDependentAtomString(oldValueAtom),
nsDependentAtomString(newValueAtom),
(ns.IsEmpty() ? NullString() : ns)
(ns.IsEmpty() ? VoidString() : ns)
};
nsContentUtils::EnqueueLifecycleCallback(
@ -2938,8 +2938,8 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
LifecycleCallbackArgs args = {
nsDependentAtomString(aName),
nsDependentAtomString(oldValueAtom),
NullString(),
(ns.IsEmpty() ? NullString() : ns)
VoidString(),
(ns.IsEmpty() ? VoidString() : ns)
};
nsContentUtils::EnqueueLifecycleCallback(

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

@ -39,7 +39,7 @@ public:
typedef nsTArray<RefPtr<mozilla::dom::Animation>> AnimationArray;
nsDOMMutationRecord(nsIAtom* aType, nsISupports* aOwner)
: mType(aType), mAttrNamespace(NullString()), mPrevValue(NullString()), mOwner(aOwner)
: mType(aType), mAttrNamespace(VoidString()), mPrevValue(VoidString()), mOwner(aOwner)
{
}

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

@ -3584,7 +3584,7 @@ nsIDocument::GetSrcdocData(nsAString &aSrcdocData)
return inStrmChan->GetSrcdocData(aSrcdocData);
}
}
aSrcdocData = NullString();
aSrcdocData = VoidString();
return NS_OK;
}
@ -6549,6 +6549,9 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
options.mExtends.Construct(lcName);
}
// Note: No calls that might run JS or trigger CC after this, or there's a
// (vanishingly small) risk of our constructor being nulled before Define()
// can access it.
RefPtr<Function> functionConstructor =
new Function(aCx, wrappedConstructor, sgo);
@ -9793,7 +9796,7 @@ nsDocument::PreloadPictureImageSource(const nsAString& aSrcsetAttr,
// <picture> selects the first matching source, so if this returns a URI we
// needn't consider new sources until a new <picture> is encountered.
bool found =
HTMLImageElement::SelectSourceForTagWithAttrs(this, true, NullString(),
HTMLImageElement::SelectSourceForTagWithAttrs(this, true, VoidString(),
aSrcsetAttr, aSizesAttr,
aTypeAttr, aMediaAttr,
mPreloadPictureFoundSource);
@ -9822,7 +9825,7 @@ nsDocument::ResolvePreloadImage(nsIURI *aBaseURI,
// Otherwise try to use this <img> as a source
HTMLImageElement::SelectSourceForTagWithAttrs(this, false, aSrcAttr,
aSrcsetAttr, aSizesAttr,
NullString(), NullString(),
VoidString(), VoidString(),
sourceURL);
isImgSet = !aSrcsetAttr.IsEmpty();
}
@ -10920,11 +10923,12 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(UnblockParsingPromiseHandler)
explicit UnblockParsingPromiseHandler(nsIDocument* aDocument, Promise* aPromise)
explicit UnblockParsingPromiseHandler(nsIDocument* aDocument, Promise* aPromise,
const BlockParsingOptions& aOptions)
: mPromise(aPromise)
{
nsCOMPtr<nsIParser> parser = aDocument->CreatorParserOrNull();
if (parser) {
if (parser && (aOptions.mBlockScriptCreated || !parser->IsScriptCreated())) {
parser->BlockParser();
mParser = do_GetWeakReference(parser);
mDocument = aDocument;
@ -10987,14 +10991,15 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(UnblockParsingPromiseHandler)
NS_IMPL_CYCLE_COLLECTING_RELEASE(UnblockParsingPromiseHandler)
already_AddRefed<Promise>
nsIDocument::BlockParsing(Promise& aPromise, ErrorResult& aRv)
nsIDocument::BlockParsing(Promise& aPromise, const BlockParsingOptions& aOptions, ErrorResult& aRv)
{
RefPtr<Promise> resultPromise = Promise::Create(aPromise.GetParentObject(), aRv);
if (aRv.Failed()) {
return nullptr;
}
RefPtr<PromiseNativeHandler> promiseHandler = new UnblockParsingPromiseHandler(this, resultPromise);
RefPtr<PromiseNativeHandler> promiseHandler = new UnblockParsingPromiseHandler(this, resultPromise,
aOptions);
aPromise.AppendNativeHandler(promiseHandler);
return resultPromise.forget();
@ -12799,7 +12804,7 @@ nsIDocument::Constructor(const GlobalObject& aGlobal,
nsCOMPtr<nsIDOMDocument> document;
nsresult res =
NS_NewDOMDocument(getter_AddRefs(document),
NullString(),
VoidString(),
EmptyString(),
nullptr,
uri,

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

@ -2952,6 +2952,7 @@ public:
void ObsoleteSheet(const nsAString& aSheetURI, mozilla::ErrorResult& rv);
already_AddRefed<mozilla::dom::Promise> BlockParsing(mozilla::dom::Promise& aPromise,
const mozilla::dom::BlockParsingOptions& aOptions,
mozilla::ErrorResult& aRv);
already_AddRefed<nsIURI> GetMozDocumentURIIfNotForErrorPages();

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

@ -1918,9 +1918,9 @@ GetOrCreateDOMReflectorNoWrap(JSContext* cx, T& value,
template <class T>
inline JSObject*
GetCallbackFromCallbackObject(T* aObj)
GetCallbackFromCallbackObject(JSContext* aCx, T* aObj)
{
return aObj->CallbackOrNull();
return aObj->Callback(aCx);
}
// Helper for getting the callback JSObject* of a smart ptr around a
@ -1929,26 +1929,26 @@ GetCallbackFromCallbackObject(T* aObj)
template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
struct GetCallbackFromCallbackObjectHelper
{
static inline JSObject* Get(const T& aObj)
static inline JSObject* Get(JSContext* aCx, const T& aObj)
{
return GetCallbackFromCallbackObject(aObj.get());
return GetCallbackFromCallbackObject(aCx, aObj.get());
}
};
template <class T>
struct GetCallbackFromCallbackObjectHelper<T, false>
{
static inline JSObject* Get(T& aObj)
static inline JSObject* Get(JSContext* aCx, T& aObj)
{
return GetCallbackFromCallbackObject(&aObj);
return GetCallbackFromCallbackObject(aCx, &aObj);
}
};
template<class T>
inline JSObject*
GetCallbackFromCallbackObject(T& aObj)
GetCallbackFromCallbackObject(JSContext* aCx, T& aObj)
{
return GetCallbackFromCallbackObjectHelper<T>::Get(aObj);
return GetCallbackFromCallbackObjectHelper<T>::Get(aCx, aObj);
}
static inline bool

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

@ -115,6 +115,18 @@ CallbackObject::FinishSlowJSInitIfMoreThanOneOwner(JSContext* aCx)
}
}
JSObject*
CallbackObject::Callback(JSContext* aCx)
{
JSObject* callback = CallbackOrNull();
if (!callback) {
callback = JS_NewDeadWrapper(aCx);
}
MOZ_DIAGNOSTIC_ASSERT(callback);
return callback;
}
CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
ErrorResult& aRv,
const char* aExecutionReason,

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

@ -93,6 +93,10 @@ public:
return CallbackPreserveColor();
}
// Like CallbackOrNull(), but will return a new dead proxy object in the
// caller's compartment if the callback is null.
JSObject* Callback(JSContext* aCx);
JSObject* GetCreationStack() const
{
return mCreationStack;
@ -594,12 +598,17 @@ public:
this->get().operator=(arg);
}
// Codegen relies on being able to do CallbackOrNull() on us.
// Codegen relies on being able to do CallbackOrNull() and Callback() on us.
JS::Handle<JSObject*> CallbackOrNull() const
{
return this->get()->CallbackOrNull();
}
JSObject* Callback(JSContext* aCx) const
{
return this->get()->Callback(aCx);
}
~RootedCallback()
{
// Ensure that our callback starts holding on to its own JS objects as

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

@ -6912,7 +6912,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
# Callbacks can store null if we nuked the compartments their
# objects lived in.
wrapCode = setObjectOrNull(
"GetCallbackFromCallbackObject(%(result)s)",
"GetCallbackFromCallbackObject(cx, %(result)s)",
wrapAsType=type)
if type.nullable():
wrapCode = (

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

@ -132,7 +132,7 @@ ToJSValue(JSContext* aCx,
// Make sure we're called in a compartment
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
aValue.setObjectOrNull(aArgument.CallbackOrNull());
aValue.setObjectOrNull(aArgument.Callback(aCx));
return MaybeWrapValue(aCx, aValue);
}

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

@ -1844,7 +1844,7 @@ Console::ProcessArguments(JSContext* aCx,
int32_t diff = aSequence.Length() - aStyles.Length();
if (diff > 0) {
for (int32_t i = 0; i < diff; i++) {
if (NS_WARN_IF(!aStyles.AppendElement(NullString(), fallible))) {
if (NS_WARN_IF(!aStyles.AppendElement(VoidString(), fallible))) {
return false;
}
}

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

@ -324,7 +324,7 @@ DOMEventTargetHelper::GetEventHandler(nsIAtom* aType,
{
EventHandlerNonNull* handler = GetEventHandler(aType, EmptyString());
if (handler) {
*aValue = JS::ObjectOrNullValue(handler->CallableOrNull());
*aValue = JS::ObjectValue(*handler->Callback(aCx));
} else {
*aValue = JS::NullValue();
}

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

@ -105,12 +105,20 @@ function runTest() {
// browser to 0 using the 'blank' attribute.
// Until the blank attribute is removed, we can't send scroll events.
SimpleTest.waitForFocus(function() {
SpecialPowers.loadChromeScript(_ => {
let chromeScript = SpecialPowers.loadChromeScript(_ => {
Components.utils.import("resource://gre/modules/Services.jsm");
Services.wm.getMostRecentWindow("navigator:browser")
.gBrowser.selectedBrowser.removeAttribute("blank");
let win = Services.wm.getMostRecentWindow("navigator:browser");
win.requestAnimationFrame(() => {
win.gBrowser.selectedBrowser.removeAttribute("blank");
win.requestAnimationFrame(() => {
sendAsyncMessage("blank-attribute-removed");
});
});
});
chromeScript.promiseOneMessage("blank-attribute-removed").then(() => {
chromeScript.destroy();
waitForPaint(win, winUtils, callback);
});
waitForPaint(win, winUtils, callback);
}, win);
};

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

@ -52,12 +52,20 @@
// browser to 0 using the 'blank' attribute.
// Until the blank attribute is removed, we can't send scroll events.
SimpleTest.waitForFocus(function() {
SpecialPowers.loadChromeScript(_ => {
let chromeScript = SpecialPowers.loadChromeScript(_ => {
Components.utils.import("resource://gre/modules/Services.jsm");
Services.wm.getMostRecentWindow("navigator:browser")
.gBrowser.selectedBrowser.removeAttribute("blank");
let win = Services.wm.getMostRecentWindow("navigator:browser");
win.requestAnimationFrame(() => {
win.gBrowser.selectedBrowser.removeAttribute("blank");
win.requestAnimationFrame(() => {
sendAsyncMessage("blank-attribute-removed");
});
});
});
chromeScript.promiseOneMessage("blank-attribute-removed").then(() => {
chromeScript.destroy();
runTests();
});
runTests();
}, window);
SimpleTest.requestFlakyTimeout("untriaged");

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

@ -43,7 +43,7 @@ PendingIPCBlobChild::SetPendingInfoAndDeleteActor(const nsString& aContentType,
RefPtr<BlobImpl> blobImpl;
blobImpl.swap(mBlobImpl);
blobImpl->SetLazyData(NullString(), aContentType, aLength, INT64_MAX);
blobImpl->SetLazyData(VoidString(), aContentType, aLength, INT64_MAX);
PendingIPCBlobData data(nsString(aContentType), aLength, void_t());
Unused << Send__delete__(this, data);

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

@ -44,7 +44,7 @@ IPCResult
PendingIPCBlobParent::Recv__delete__(const PendingIPCBlobData& aData)
{
if (aData.file().type() == PendingIPCFileUnion::Tvoid_t) {
mBlobImpl->SetLazyData(NullString(), aData.type(), aData.size(), INT64_MAX);
mBlobImpl->SetLazyData(VoidString(), aData.type(), aData.size(), INT64_MAX);
} else {
const PendingIPCFileData& fileData =
aData.file().get_PendingIPCFileData();

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

@ -802,7 +802,7 @@ HTMLFormElement::SubmitSubmission(HTMLFormSubmission* aFormSubmission)
rv = linkHandler->OnLinkClickSync(this, actionURI,
target.get(),
NullString(),
VoidString(),
postDataStream, nullptr, false,
getter_AddRefs(docShell),
getter_AddRefs(mSubmittingRequest));

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

@ -353,7 +353,7 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
if (InResponsiveMode()) {
if (mResponsiveSelector &&
mResponsiveSelector->Content() == this) {
mResponsiveSelector->SetDefaultSource(NullString());
mResponsiveSelector->SetDefaultSource(VoidString());
}
QueueImageLoadTask(true);
} else {

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

@ -78,6 +78,7 @@ skip-if = os == "android"
skip-if = os == "android"
[test_input_types_pref.html]
[test_input_typing_sanitization.html]
skip-if = os == "android" && debug # bug 1397615
[test_input_untrusted_key_events.html]
[test_input_url.html]
[test_interactive_content_in_label.html]

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

@ -17378,7 +17378,7 @@ FileManager::InitDirectory(nsIFile* aDirectory,
nsCOMPtr<mozIStorageConnection> connection;
rv = CreateStorageConnection(aDatabaseFile,
aDirectory,
NullString(),
VoidString(),
aPersistenceType,
aGroup,
aOrigin,

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

@ -203,7 +203,7 @@ public:
ReadAsArrayBuffer(uint64_t aSize, ErrorResult& aRv)
{
AssertIsOnOwningThread();
return Read(aSize, false, NullString(), aRv);
return Read(aSize, false, VoidString(), aRv);
}
already_AddRefed<IDBFileRequest>

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

@ -925,7 +925,7 @@ public:
if (aData.tag == SCTAG_DOM_BLOB) {
aFile.mBlob->Impl()->SetLazyData(
NullString(), aData.type, aData.size, INT64_MAX);
VoidString(), aData.type, aData.size, INT64_MAX);
MOZ_ASSERT(!aFile.mBlob->IsFile());
// ActorsParent sends here a kind of half blob and half file wrapped into

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

@ -768,7 +768,7 @@ private:
AppInfo mAppInfo;
bool mIsForBrowser;
nsString mRemoteType = NullString();
nsString mRemoteType = VoidString();
bool mIsAlive;
nsString mProcessName;

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

@ -4696,7 +4696,7 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
CommonCreateWindow(aThisTab, /* aSetOpener = */ true, aChromeFlags,
aCalledFromJS, aPositionSpecified, aSizeSpecified,
nullptr, aFeatures, aBaseURI, aFullZoom,
nextTabParentId, NullString(), rv,
nextTabParentId, VoidString(), rv,
newRemoteTab, &cwi.windowOpened(),
aTriggeringPrincipal);
if (!ipcResult) {

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

@ -1599,8 +1599,8 @@ TabChild::MaybeDispatchCoalescedMouseMoveEvents()
// Dispatch the coalesced mousemove event. Using RecvRealMouseButtonEvent to
// bypass the coalesce handling in RecvRealMouseMoveEvent.
RecvRealMouseButtonEvent(*event,
mCoalescedWheelData.GetScrollableLayerGuid(),
mCoalescedWheelData.GetInputBlockId());
mCoalescedMouseData.GetScrollableLayerGuid(),
mCoalescedMouseData.GetInputBlockId());
if (mCoalescedMouseEventFlusher) {
mCoalescedMouseData.Reset();
mCoalescedMouseEventFlusher->RemoveObserver();

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

@ -426,7 +426,7 @@ public:
if (globalWindow) {
RefPtr<GetUserMediaRequest> req =
new GetUserMediaRequest(globalWindow->AsInner(),
NullString(), NullString());
VoidString(), VoidString());
obs->NotifyObservers(req, "recording-device-stopped", nullptr);
}
return;

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

@ -491,7 +491,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetURL(const char *aURL,
triggeringPrincipal = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
}
rv = lh->OnLinkClick(content, uri, unitarget.get(), NullString(),
rv = lh->OnLinkClick(content, uri, unitarget.get(), VoidString(),
aPostStream, headersDataStream, true, triggeringPrincipal);
return rv;

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

@ -307,7 +307,7 @@ inline nsCString
NullableString(const char* aString)
{
if (!aString) {
return NullCString();
return VoidCString();
}
return nsCString(aString);
}

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

@ -140,7 +140,7 @@ PresentationRequest::WrapObject(JSContext* aCx,
already_AddRefed<Promise>
PresentationRequest::Start(ErrorResult& aRv)
{
return StartWithDevice(NullString(), aRv);
return StartWithDevice(VoidString(), aRv);
}
already_AddRefed<Promise>

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

@ -5843,7 +5843,7 @@ QuotaManager::ShutdownTimerCallback(nsITimer* aTimer, void* aClosure)
// Abort all operations.
for (RefPtr<Client>& client : quotaManager->mClients) {
client->AbortOperations(NullCString());
client->AbortOperations(VoidCString());
}
}

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

@ -154,7 +154,7 @@ LocalStorage::RemoveItem(const nsAString& aKey, nsIPrincipal& aSubjectPrincipal,
}
if (!aRv.ErrorCodeIs(NS_SUCCESS_DOM_NO_OPERATION)) {
BroadcastChangeNotification(aKey, old, NullString());
BroadcastChangeNotification(aKey, old, VoidString());
}
}
@ -172,7 +172,7 @@ LocalStorage::Clear(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv)
}
if (!aRv.ErrorCodeIs(NS_SUCCESS_DOM_NO_OPERATION)) {
BroadcastChangeNotification(NullString(), NullString(), NullString());
BroadcastChangeNotification(VoidString(), VoidString(), VoidString());
}
}

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

@ -155,7 +155,7 @@ SessionStorage::RemoveItem(const nsAString& aKey,
return;
}
BroadcastChangeNotification(aKey, oldValue, NullString());
BroadcastChangeNotification(aKey, oldValue, VoidString());
}
void
@ -168,7 +168,7 @@ SessionStorage::Clear(nsIPrincipal& aSubjectPrincipal,
}
mCache->Clear(DATASET);
BroadcastChangeNotification(NullString(), NullString(), NullString());
BroadcastChangeNotification(VoidString(), VoidString(), VoidString());
}
void

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

@ -385,13 +385,22 @@ partial interface Document {
// Blocks the initial document parser until the given promise is settled.
[ChromeOnly, Throws]
Promise<any> blockParsing(Promise<any> promise);
Promise<any> blockParsing(Promise<any> promise,
optional BlockParsingOptions options);
// like documentURI, except that for error pages, it returns the URI we were
// trying to load when we hit an error, rather than the error page's own URI.
[ChromeOnly] readonly attribute URI? mozDocumentURIIfNotForErrorPages;
};
dictionary BlockParsingOptions {
/**
* If true, blocks script-created parsers (created via document.open()) in
* addition to network-created parsers.
*/
boolean blockScriptCreated = true;
};
// Extension to give chrome JS the ability to determine when a document was
// created to satisfy an iframe with srcdoc attribute.
partial interface Document {

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

@ -2421,7 +2421,7 @@ RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx,
if (!workerPrivate) {
workerPrivate =
WorkerPrivate::Constructor(aCx, aScriptURL, false,
WorkerTypeShared, aName, NullCString(),
WorkerTypeShared, aName, VoidCString(),
aLoadInfo, rv);
NS_ENSURE_TRUE(workerPrivate, rv.StealNSResult());

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

@ -1878,7 +1878,7 @@ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
mWorkerPrivate = WorkerPrivate::Constructor(jsapi.cx(),
scriptSpec,
false, WorkerTypeService,
NullString(),
VoidString(),
mInfo->Scope(),
&info, error);
if (NS_WARN_IF(error.Failed())) {

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

@ -1061,6 +1061,34 @@ ServiceWorkerRegistrar::ProfileStopped()
PBackgroundChild* child = BackgroundChild::GetForCurrentThread();
if (!child) {
// Mutations to the ServiceWorkerRegistrar happen on the PBackground thread,
// issued by the ServiceWorkerManagerService, so the appropriate place to
// trigger shutdown is on that thread.
//
// However, it's quite possible that the PBackground thread was not brought
// into existence for xpcshell tests. We don't cause it to be created
// ourselves for any reason, for example.
//
// In this scenario, we know that:
// - We will receive exactly one call to ourself from BlockShutdown() and
// BlockShutdown() will be called (at most) once.
// - The only way our Shutdown() method gets called is via
// BackgroundParentImpl::RecvShutdownServiceWorkerRegistrar() being
// invoked, which only happens if we get to that send below here that we
// can't get to.
// - All Shutdown() does is set mShuttingDown=true (essential for
// invariants) and invoke MaybeScheduleShutdownCompleted().
// - Since there is no PBackground thread, mRunnableCounter must be 0
// because only ScheduleSaveData() increments it and it only runs on the
// background thread, so it cannot have run. And so we would expect
// MaybeScheduleShutdownCompleted() to schedule an invocation of
// ShutdownCompleted on the main thread.
//
// So it's appropriate for us to set mShuttingDown=true (as Shutdown would
// do) and directly invoke ShutdownCompleted() (as Shutdown would indirectly
// do via MaybeScheduleShutdownCompleted).
mShuttingDown = true;
ShutdownCompleted();
return;
}

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

@ -4646,7 +4646,7 @@ WorkerPrivate::Constructor(const GlobalObject& aGlobal,
{
JSContext* cx = aGlobal.Context();
return Constructor(cx, aScriptURL, aIsChromeWorker, aWorkerType,
aWorkerName, NullCString(), aLoadInfo, aRv);
aWorkerName, VoidCString(), aLoadInfo, aRv);
}
// static

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

@ -1530,7 +1530,7 @@ void
XMLHttpRequestMainThread::Open(const nsACString& aMethod, const nsAString& aUrl,
ErrorResult& aRv)
{
Open(aMethod, aUrl, true, NullString(), NullString(), aRv);
Open(aMethod, aUrl, true, VoidString(), VoidString(), aRv);
}
// This case is hit when the async parameter is specified, even if the

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

@ -1429,8 +1429,8 @@ OpenRunnable::MainThreadRunInternal()
ErrorResult rv2;
mProxy->mXHR->Open(mMethod, mURL, true,
mUser.WasPassed() ? mUser.Value() : NullString(),
mPassword.WasPassed() ? mPassword.Value() : NullString(),
mUser.WasPassed() ? mUser.Value() : VoidString(),
mPassword.WasPassed() ? mPassword.Value() : VoidString(),
rv2);
MOZ_ASSERT(mProxy->mInOpen);
@ -2046,7 +2046,7 @@ XMLHttpRequestWorker::Send(JSContext* aCx,
RefPtr<SendRunnable> sendRunnable;
if (aData.IsNull()) {
sendRunnable = new SendRunnable(mWorkerPrivate, mProxy, NullString());
sendRunnable = new SendRunnable(mWorkerPrivate, mProxy, VoidString());
// Nothing to clone.
}

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

@ -904,7 +904,7 @@ txMozillaXMLOutput::createResultDocument(const nsAString& aName, int32_t aNsID,
doctypeName,
mOutputFormat.mPublicId,
mOutputFormat.mSystemId,
NullString());
VoidString());
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> docType = do_QueryInterface(documentType);

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

@ -487,7 +487,7 @@ nsXULTemplateBuilder::HasGeneratedContent(nsIRDFResource* aResource,
bool* aGenerated)
{
ErrorResult rv;
const nsAString& tag = aTag ? nsDependentAtomString(aTag) : NullString();
const nsAString& tag = aTag ? nsDependentAtomString(aTag) : VoidString();
*aGenerated = HasGeneratedContent(aResource, tag, rv);
return rv.StealNSResult();
}

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

@ -572,7 +572,7 @@ HTMLEditUtils::SupportsAlignAttr(nsINode& aNode)
struct ElementInfo final
{
#ifdef DEBUG
eHTMLTags mTag;
nsHTMLTag mTag;
#endif
uint32_t mGroup;
uint32_t mCanContainGroups;
@ -787,7 +787,7 @@ HTMLEditUtils::CanContain(int32_t aParent, int32_t aChild)
// Special-case button.
if (aParent == eHTMLTag_button) {
static const eHTMLTags kButtonExcludeKids[] = {
static const nsHTMLTag kButtonExcludeKids[] = {
eHTMLTag_a,
eHTMLTag_fieldset,
eHTMLTag_form,

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

@ -21,7 +21,7 @@ TEST_F(InitTest, ZeroCount)
EXPECT_EQ(pp::Token::LAST, token.type);
}
TEST_F(InitTest, NullString)
TEST_F(InitTest, VoidString)
{
EXPECT_FALSE(mPreprocessor.init(1, NULL, NULL));
}

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

@ -135,6 +135,16 @@ ImageContainer::GetImageClient()
return imageClient.forget();
}
void
ImageContainer::DropImageClient()
{
RecursiveMutexAutoLock mon(mRecursiveMutex);
if (mImageClient) {
mImageClient->ClearCachedResources();
mImageClient = nullptr;
}
}
void
ImageContainer::EnsureImageClient()
{

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

@ -618,6 +618,8 @@ public:
*/
static ProducerID AllocateProducerID();
void DropImageClient();
private:
typedef mozilla::RecursiveMutex RecursiveMutex;

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

@ -726,7 +726,24 @@ MessageLoop * ImageBridgeChild::GetMessageLoop() const
ImageBridgeChild::IdentifyCompositorTextureHost(const TextureFactoryIdentifier& aIdentifier)
{
if (RefPtr<ImageBridgeChild> child = GetSingleton()) {
child->IdentifyTextureHost(aIdentifier);
child->UpdateTextureFactoryIdentifier(aIdentifier);
}
}
void
ImageBridgeChild::UpdateTextureFactoryIdentifier(const TextureFactoryIdentifier& aIdentifier)
{
bool disablingWebRender = GetCompositorBackendType() == LayersBackend::LAYERS_WR &&
aIdentifier.mParentBackend != LayersBackend::LAYERS_WR;
IdentifyTextureHost(aIdentifier);
if (disablingWebRender) {
// ImageHost is incompatible between WebRender enabled and WebRender disabled.
// Then drop all ImageContainers' ImageClients during disabling WebRender.
MutexAutoLock lock(mContainerMapLock);
for (auto iter = mImageContainers.Iter(); !iter.Done(); iter.Next()) {
ImageContainer* container = iter.Data();
container->DropImageClient();
}
}
}

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

@ -250,6 +250,8 @@ private:
void ProxyAllocShmemNow(SynchronousTask* aTask, AllocShmemParams* aParams);
void ProxyDeallocShmemNow(SynchronousTask* aTask, Shmem* aShmem, bool* aResult);
void UpdateTextureFactoryIdentifier(const TextureFactoryIdentifier& aIdentifier);
public:
// CompositableForwarder

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

@ -279,18 +279,7 @@ public:
RefPtr<CachedSurface> surface;
mSurfaces.Remove(aSurface->GetSurfaceKey(), getter_AddRefs(surface));
if (IsEmpty() && mFactor2Mode) {
// The last surface for this cache was removed. This can happen if the
// surface was stored in a volatile buffer and got purged, or the surface
// expired from the cache. If the cache itself lingers for some reason
// (e.g. in the process of performing a lookup, the cache itself is
// locked), then we need to reset the factor of 2 state because it
// requires at least one surface present to get the native size
// information from the image.
mFactor2Mode = mFactor2Pruned = false;
}
AfterMaybeRemove();
return surface.forget();
}
@ -537,6 +526,11 @@ public:
if (!hasNotFactorSize) {
mFactor2Pruned = true;
}
// We should never leave factor of 2 mode due to pruning in of itself, but
// if we discarded surfaces due to the volatile buffers getting released,
// it is possible.
AfterMaybeRemove();
}
IntSize SuggestedSize(const IntSize& aSize) const
@ -548,7 +542,10 @@ public:
// We cannot enter factor of 2 mode unless we have a minimum number of
// surfaces, and we should have left it if the cache was emptied.
MOZ_ASSERT(!IsEmpty());
if (MOZ_UNLIKELY(IsEmpty())) {
MOZ_ASSERT_UNREACHABLE("Should not be empty and in factor of 2 mode!");
return aSize;
}
// This bit of awkwardness gets the largest native size of the image.
auto iter = ConstIter();
@ -644,6 +641,8 @@ public:
}
report.Add(surface, factor2Size);
}
AfterMaybeRemove();
}
SurfaceTable::Iterator ConstIter() const
@ -655,6 +654,20 @@ public:
bool IsLocked() const { return mLocked; }
private:
void AfterMaybeRemove()
{
if (IsEmpty() && mFactor2Mode) {
// The last surface for this cache was removed. This can happen if the
// surface was stored in a volatile buffer and got purged, or the surface
// expired from the cache. If the cache itself lingers for some reason
// (e.g. in the process of performing a lookup, the cache itself is
// locked), then we need to reset the factor of 2 state because it
// requires at least one surface present to get the native size
// information from the image.
mFactor2Mode = mFactor2Pruned = false;
}
}
SurfaceTable mSurfaces;
bool mLocked;
@ -816,13 +829,7 @@ public:
// Individual surfaces must be freed outside the lock.
mCachedSurfacesDiscard.AppendElement(cache->Remove(aSurface));
// Remove the per-image cache if it's unneeded now. Keep it if the image is
// locked, since the per-image cache is where we store that state. Note that
// we don't push it into mImageCachesDiscard because all of its surfaces
// have been removed, so it is safe to free while holding the lock.
if (cache->IsEmpty() && !cache->IsLocked()) {
mImageCaches.Remove(imageKey);
}
MaybeRemoveEmptyCache(imageKey, cache);
}
bool StartTracking(NotNull<CachedSurface*> aSurface,
@ -1093,6 +1100,8 @@ public:
// Individual surfaces must be freed outside the lock.
mCachedSurfacesDiscard.AppendElement(aSurface);
});
MaybeRemoveEmptyCache(aImageKey, cache);
}
void DiscardAll(const StaticMutexAutoLock& aAutoLock)
@ -1199,6 +1208,8 @@ public:
// Individual surfaces must be freed outside the lock.
mCachedSurfacesDiscard.AppendElement(aSurface);
});
MaybeRemoveEmptyCache(aImageKey, cache);
}
private:
@ -1209,6 +1220,18 @@ private:
return imageCache.forget();
}
void MaybeRemoveEmptyCache(const ImageKey aImageKey,
ImageSurfaceCache* aCache)
{
// Remove the per-image cache if it's unneeded now. Keep it if the image is
// locked, since the per-image cache is where we store that state. Note that
// we don't push it into mImageCachesDiscard because all of its surfaces
// have been removed, so it is safe to free while holding the lock.
if (aCache->IsEmpty() && !aCache->IsLocked()) {
mImageCaches.Remove(aImageKey);
}
}
// This is similar to CanHold() except that it takes into account the costs of
// locked surfaces. It's used internally in Insert(), but it's not exposed
// publicly because we permit multithreaded access to the surface cache, which

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

@ -17,6 +17,7 @@
#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "nsAppRunner.h"
#include "mozilla/UniquePtr.h"
#include "nsAutoPtr.h"
#include "nsDebug.h"
#include "nsISupportsImpl.h"
@ -416,7 +417,7 @@ public:
MOZ_RELEASE_ASSERT(aMessage.transaction_id() == mTransaction);
MOZ_RELEASE_ASSERT(!mReply);
IPC_LOG("Reply received on worker thread: seqno=%d", mSeqno);
mReply = new IPC::Message(Move(aMessage));
mReply = MakeUnique<IPC::Message>(Move(aMessage));
MOZ_RELEASE_ASSERT(IsComplete());
}
@ -455,7 +456,7 @@ public:
return mReply->is_reply_error();
}
nsAutoPtr<IPC::Message> GetReply() {
UniquePtr<IPC::Message> GetReply() {
return Move(mReply);
}
@ -480,7 +481,7 @@ private:
AutoEnterTransaction *mNext;
// Pointer the a reply received for this message, if one was received.
nsAutoPtr<IPC::Message> mReply;
UniquePtr<IPC::Message> mReply;
};
class PromiseReporter final : public nsIMemoryReporter
@ -844,7 +845,7 @@ MessageChannel::CommonThreadOpenInit(MessageChannel *aTargetChan, Side aSide)
bool
MessageChannel::Echo(Message* aMsg)
{
nsAutoPtr<Message> msg(aMsg);
UniquePtr<Message> msg(aMsg);
AssertWorkerThread();
mMonitor->AssertNotCurrentThreadOwns();
if (MSG_ROUTING_NONE == msg->routing_id()) {
@ -855,11 +856,11 @@ MessageChannel::Echo(Message* aMsg)
MonitorAutoLock lock(*mMonitor);
if (!Connected()) {
ReportConnectionError("MessageChannel", msg);
ReportConnectionError("MessageChannel", msg.get());
return false;
}
mLink->EchoMessage(msg.forget());
mLink->EchoMessage(msg.release());
return true;
}
@ -887,7 +888,7 @@ MessageChannel::Send(Message* aMsg)
CxxStackFrame frame(*this, OUT_MESSAGE, aMsg);
nsAutoPtr<Message> msg(aMsg);
UniquePtr<Message> msg(aMsg);
AssertWorkerThread();
mMonitor->AssertNotCurrentThreadOwns();
if (MSG_ROUTING_NONE == msg->routing_id()) {
@ -897,11 +898,10 @@ MessageChannel::Send(Message* aMsg)
MonitorAutoLock lock(*mMonitor);
if (!Connected()) {
ReportConnectionError("MessageChannel", msg);
ReportConnectionError("MessageChannel", msg.get());
return false;
}
SendMessageToLink(msg.forget());
SendMessageToLink(msg.release());
return true;
}
@ -1353,7 +1353,7 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
Telemetry::Accumulate(Telemetry::IPC_MESSAGE_SIZE2, aMsg->size());
}
nsAutoPtr<Message> msg(aMsg);
UniquePtr<Message> msg(aMsg);
// Sanity checks.
AssertWorkerThread();
@ -1367,7 +1367,7 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
AutoScopedLabel autolabel("sync message %s", aMsg->name());
#endif
CxxStackFrame f(*this, OUT_MESSAGE, msg);
CxxStackFrame f(*this, OUT_MESSAGE, msg.get());
MonitorAutoLock lock(*mMonitor);
@ -1427,7 +1427,7 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
"not allowed to send messages while dispatching urgent messages");
if (!Connected()) {
ReportConnectionError("MessageChannel::SendAndWait", msg);
ReportConnectionError("MessageChannel::SendAndWait", msg.get());
mLastSendError = SyncSendError::NotConnectedBeforeSend;
return false;
}
@ -1456,7 +1456,7 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
// msg will be destroyed soon, but name() is not owned by msg.
const char* msgName = msg->name();
SendMessageToLink(msg.forget());
SendMessageToLink(msg.release());
while (true) {
MOZ_RELEASE_ASSERT(!transact.IsCanceled());
@ -1534,7 +1534,7 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
IPC_LOG("Got reply: seqno=%d, xid=%d, msgName=%s, latency=%ums",
seqno, transaction, msgName, latencyMs);
nsAutoPtr<Message> reply = transact.GetReply();
UniquePtr<Message> reply = transact.GetReply();
MOZ_RELEASE_ASSERT(reply);
MOZ_RELEASE_ASSERT(reply->is_reply(), "expected reply");
@ -1560,7 +1560,7 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
bool
MessageChannel::Call(Message* aMsg, Message* aReply)
{
nsAutoPtr<Message> msg(aMsg);
UniquePtr<Message> msg(aMsg);
AssertWorkerThread();
mMonitor->AssertNotCurrentThreadOwns();
@ -1573,11 +1573,11 @@ MessageChannel::Call(Message* aMsg, Message* aReply)
// This must come before MonitorAutoLock, as its destructor acquires the
// monitor lock.
CxxStackFrame cxxframe(*this, OUT_MESSAGE, msg);
CxxStackFrame cxxframe(*this, OUT_MESSAGE, msg.get());
MonitorAutoLock lock(*mMonitor);
if (!Connected()) {
ReportConnectionError("MessageChannel::Call", msg);
ReportConnectionError("MessageChannel::Call", msg.get());
return false;
}
@ -1593,7 +1593,7 @@ MessageChannel::Call(Message* aMsg, Message* aReply)
msg->set_interrupt_remote_stack_depth_guess(mRemoteStackDepthGuess);
msg->set_interrupt_local_stack_depth(1 + InterruptStackDepth());
mInterruptStack.push(MessageInfo(*msg));
mLink->SendMessage(msg.forget());
mLink->SendMessage(msg.release());
while (true) {
// if a handler invoked by *Dispatch*() spun a nested event

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

@ -93,6 +93,8 @@ ActivationContext::~ActivationContext()
Release();
}
#if defined(MOZILLA_INTERNAL_API)
/* static */ Result<uintptr_t,HRESULT>
ActivationContext::GetCurrent()
{
@ -104,6 +106,68 @@ ActivationContext::GetCurrent()
return reinterpret_cast<uintptr_t>(actCtx);
}
/* static */ HRESULT
ActivationContext::GetCurrentManifestPath(nsAString& aOutManifestPath)
{
aOutManifestPath.Truncate();
SIZE_T bytesNeeded;
BOOL ok = ::QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, nullptr,
nullptr, ActivationContextDetailedInformation,
nullptr, 0, &bytesNeeded);
if (!ok) {
DWORD err = ::GetLastError();
if (err != ERROR_INSUFFICIENT_BUFFER) {
return HRESULT_FROM_WIN32(err);
}
}
auto ctxBuf = MakeUnique<BYTE[]>(bytesNeeded);
ok = ::QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, nullptr, nullptr,
ActivationContextDetailedInformation, ctxBuf.get(),
bytesNeeded, nullptr);
if (!ok) {
return HRESULT_FROM_WIN32(::GetLastError());
}
auto ctxInfo =
reinterpret_cast<ACTIVATION_CONTEXT_DETAILED_INFORMATION*>(ctxBuf.get());
// assemblyIndex is 1-based, and we want the last index, so we can just copy
// ctxInfo->ulAssemblyCount directly.
DWORD assemblyIndex = ctxInfo->ulAssemblyCount;
ok = ::QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, nullptr,
&assemblyIndex,
AssemblyDetailedInformationInActivationContext, nullptr,
0, &bytesNeeded);
if (!ok) {
DWORD err = ::GetLastError();
if (err != ERROR_INSUFFICIENT_BUFFER) {
return HRESULT_FROM_WIN32(err);
}
}
auto assemblyBuf = MakeUnique<BYTE[]>(bytesNeeded);
ok = ::QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, nullptr,
&assemblyIndex,
AssemblyDetailedInformationInActivationContext,
assemblyBuf.get(), bytesNeeded, &bytesNeeded);
if (!ok) {
return HRESULT_FROM_WIN32(::GetLastError());
}
auto assemblyInfo =
reinterpret_cast<ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION*>(assemblyBuf.get());
aOutManifestPath = nsDependentString(assemblyInfo->lpAssemblyManifestPath,
(assemblyInfo->ulManifestPathLength + 1) / sizeof(wchar_t));
return S_OK;
}
#endif // defined(MOZILLA_INTERNAL_API)
ActivationContextRegion::ActivationContextRegion(const ActivationContext& aActCtx)
: mActCtx(aActCtx)
, mActCookie(0)

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

@ -11,6 +11,10 @@
#include "mozilla/Move.h"
#include "mozilla/Result.h"
#if defined(MOZILLA_INTERNAL_API)
#include "nsString.h"
#endif // defined(MOZILLA_INTERNAL_API)
#include <windows.h>
namespace mozilla {
@ -35,7 +39,10 @@ public:
return mActCtx != INVALID_HANDLE_VALUE;
}
#if defined(MOZILLA_INTERNAL_API)
static Result<uintptr_t,HRESULT> GetCurrent();
static HRESULT GetCurrentManifestPath(nsAString& aOutManifestPath);
#endif // defined(MOZILLA_INTERNAL_API)
private:
void Init(ACTCTX& aActCtx);

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

@ -83,6 +83,7 @@ ProxyStream::ProxyStream(REFIID aIID, const BYTE* aInitBuf,
#if defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
const uint32_t expectedStreamLen = GetOBJREFSize(WrapNotNull(mStream));
nsAutoCString strActCtx;
nsAutoString manifestPath;
#endif // defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
HRESULT unmarshalResult = S_OK;
@ -92,7 +93,7 @@ ProxyStream::ProxyStream(REFIID aIID, const BYTE* aInitBuf,
// actual interface later.
#if defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
auto marshalFn = [this, &strActCtx, &unmarshalResult, &aIID]() -> void
auto marshalFn = [this, &strActCtx, &manifestPath, &unmarshalResult, &aIID]() -> void
#else
auto marshalFn = [this, &unmarshalResult, &aIID]() -> void
#endif // defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
@ -104,6 +105,8 @@ ProxyStream::ProxyStream(REFIID aIID, const BYTE* aInitBuf,
} else {
strActCtx.AppendPrintf("HRESULT 0x%08X", curActCtx.unwrapErr());
}
ActivationContext::GetCurrentManifestPath(manifestPath);
#endif // defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
unmarshalResult =
@ -137,6 +140,8 @@ ProxyStream::ProxyStream(REFIID aIID, const BYTE* aInitBuf,
AnnotateClassRegistration(CLSID_AccessibleHandler);
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtx"),
strActCtx);
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtxManifestPath"),
NS_ConvertUTF16toUTF8(manifestPath));
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("A11yHandlerRegistered"),
a11y::IsHandlerRegistered() ?
NS_LITERAL_CSTRING("true") :
@ -285,13 +290,28 @@ ProxyStream::ProxyStream(REFIID aIID, IUnknown* aObject,
HRESULT statResult = S_OK;
HRESULT getHGlobalResult = S_OK;
auto marshalFn = [&]() -> void
#if defined(MOZ_CRASHREPORTER)
nsAutoString manifestPath;
auto marshalFn = [this, &aIID, aObject, mshlFlags, &stream, &streamSize,
&hglobal, &createStreamResult, &marshalResult, &statResult,
&getHGlobalResult, &manifestPath]() -> void
#else
auto marshalFn = [this, &aIID, aObject, mshlFlags, &stream, &streamSize,
&hglobal, &createStreamResult, &marshalResult, &statResult,
&getHGlobalResult]() -> void
#endif // defined(MOZ_CRASHREPORTER)
{
createStreamResult = ::CreateStreamOnHGlobal(nullptr, TRUE, getter_AddRefs(stream));
createStreamResult = ::CreateStreamOnHGlobal(nullptr, TRUE,
getter_AddRefs(stream));
if (FAILED(createStreamResult)) {
return;
}
#if defined(MOZ_CRASHREPORTER)
ActivationContext::GetCurrentManifestPath(manifestPath);
#endif // defined(MOZ_CRASHREPORTER)
marshalResult = ::CoMarshalInterface(stream, aIID, aObject, MSHCTX_LOCAL,
nullptr, mshlFlags);
MOZ_DIAGNOSTIC_ASSERT(marshalResult != E_INVALIDARG);
@ -333,6 +353,8 @@ ProxyStream::ProxyStream(REFIID aIID, IUnknown* aObject,
nsPrintfCString hrAsStr("0x%08X", marshalResult);
CrashReporter::AnnotateCrashReport(
NS_LITERAL_CSTRING("CoMarshalInterfaceFailure"), hrAsStr);
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("MarshalActCtxManifestPath"),
NS_ConvertUTF16toUTF8(manifestPath));
}
if (FAILED(statResult)) {

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

@ -669,12 +669,16 @@ BaselineScript::maybeICEntryFromPCOffset(uint32_t pcOffset)
if (!ComputeBinarySearchMid(this, pcOffset, &mid))
return nullptr;
MOZ_ASSERT(mid < numICEntries());
// Found an IC entry with a matching PC offset. Search backward, and then
// forward from this IC entry, looking for one with the same PC offset which
// has isForOp() set.
for (size_t i = mid; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i--) {
for (size_t i = mid; icEntry(i).pcOffset() == pcOffset; i--) {
if (icEntry(i).isForOp())
return &icEntry(i);
if (i == 0)
break;
}
for (size_t i = mid+1; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i++) {
if (icEntry(i).isForOp())
@ -728,10 +732,13 @@ BaselineScript::callVMEntryFromPCOffset(uint32_t pcOffset)
// inserted by VM calls.
size_t mid;
MOZ_ALWAYS_TRUE(ComputeBinarySearchMid(this, pcOffset, &mid));
MOZ_ASSERT(mid < numICEntries());
for (size_t i = mid; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i--) {
for (size_t i = mid; icEntry(i).pcOffset() == pcOffset; i--) {
if (icEntry(i).kind() == ICEntry::Kind_CallVM)
return icEntry(i);
if (i == 0)
break;
}
for (size_t i = mid+1; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i++) {
if (icEntry(i).kind() == ICEntry::Kind_CallVM)

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

@ -1619,7 +1619,7 @@ ControlFlowGenerator::processBreak(JSOp op, jssrcnote* sn)
DebugOnly<bool> found = false;
if (SN_TYPE(sn) == SRC_BREAK2LABEL) {
for (size_t i = labels_.length() - 1; i < labels_.length(); i--) {
for (size_t i = labels_.length() - 1; ; i--) {
CFGState& cfg = cfgStack_[labels_[i].cfgEntry];
MOZ_ASSERT(cfg.state == CFGState::LABEL);
if (cfg.stopAt == target) {
@ -1627,9 +1627,11 @@ ControlFlowGenerator::processBreak(JSOp op, jssrcnote* sn)
found = true;
break;
}
if (i == 0)
break;
}
} else {
for (size_t i = loops_.length() - 1; i < loops_.length(); i--) {
for (size_t i = loops_.length() - 1; ; i--) {
CFGState& cfg = cfgStack_[loops_[i].cfgEntry];
MOZ_ASSERT(cfg.isLoop());
if (cfg.loop.exitpc == target) {
@ -1637,6 +1639,8 @@ ControlFlowGenerator::processBreak(JSOp op, jssrcnote* sn)
found = true;
break;
}
if (i == 0)
break;
}
}
@ -1665,7 +1669,7 @@ ControlFlowGenerator::processContinue(JSOp op)
// Find the target loop.
CFGState* found = nullptr;
jsbytecode* target = pc + GetJumpOffset(pc);
for (size_t i = loops_.length() - 1; i < loops_.length(); i--) {
for (size_t i = loops_.length() - 1; ; i--) {
// +1 to skip JSOP_JUMPTARGET.
if (loops_[i].continuepc == target + 1 ||
EffectiveContinue(loops_[i].continuepc) == target)
@ -1673,6 +1677,8 @@ ControlFlowGenerator::processContinue(JSOp op)
found = &cfgStack_[loops_[i].cfgEntry];
break;
}
if (i == 0)
break;
}
// There must always be a valid target loop structure. If not, there's
@ -1698,11 +1704,13 @@ ControlFlowGenerator::processSwitchBreak(JSOp op)
// Find the target switch.
CFGState* found = nullptr;
jsbytecode* target = pc + GetJumpOffset(pc);
for (size_t i = switches_.length() - 1; i < switches_.length(); i--) {
for (size_t i = switches_.length() - 1; ; i--) {
if (switches_[i].continuepc == target) {
found = &cfgStack_[switches_[i].cfgEntry];
break;
}
if (i == 0)
break;
}
// There must always be a valid target loop structure. If not, there's

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

@ -224,7 +224,7 @@ private:
{
MOZ_IMPLICIT URLEntry(const CacheKey& key)
: CacheKey(key)
, mData(NullCString())
, mData(VoidCString())
{}
explicit URLEntry(nsIFile* file)

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

@ -46,7 +46,7 @@ public:
JSObject* options = nullptr)
: OptionsBase(cx, options)
, target(cx)
, charset(NullString())
, charset(VoidString())
, ignoreCache(false)
, async(false)
, wantReturnValue(false)

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

@ -8,7 +8,7 @@
#define XPCJSMemoryReporter_h
class nsISupports;
class nsIMemoryReporterCallback;
class nsIHandleReportCallback;
namespace xpc {
@ -23,7 +23,7 @@ class JSReporter
public:
static void CollectReports(WindowPaths* windowPaths,
WindowPaths* topWindowPaths,
nsIMemoryReporterCallback* handleReport,
nsIHandleReportCallback* handleReport,
nsISupports* data,
bool anonymize);
};

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

@ -30,7 +30,7 @@
class nsGlobalWindow;
class nsIPrincipal;
class nsScriptNameSpaceManager;
class nsIMemoryReporterCallback;
class nsIHandleReportCallback;
namespace mozilla {
namespace dom {
@ -431,7 +431,7 @@ private:
void
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats& rtStats,
const nsACString& rtPath,
nsIMemoryReporterCallback* handleReport,
nsIHandleReportCallback* handleReport,
nsISupports* data,
bool anonymize,
size_t* rtTotal = nullptr);

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

@ -29,6 +29,8 @@ add_task(async function() {
let sandbox = Cu.Sandbox(window, {sandboxPrototype: window});
function sandboxContent() {
window.onload = function SandboxOnLoad() {};
window.addEventListener("FromTest", () => {
window.dispatchEvent(new CustomEvent("FromSandbox"));
}, true);
@ -40,6 +42,11 @@ add_task(async function() {
let fromTestPromise = promiseEvent(window, "FromTest");
let fromSandboxPromise = promiseEvent(window, "FromSandbox");
equal(typeof window.onload, "function",
"window.onload should contain sandbox event listener");
equal(window.onload.name, "SandboxOnLoad",
"window.onload have the correct function name");
do_print("Dispatch FromTest event");
window.dispatchEvent(new window.CustomEvent("FromTest"));
@ -70,6 +77,8 @@ add_task(async function() {
Cu.forceGC();
Cu.forceCC();
ok(Cu.isDeadWrapper(window.onload),
"window.onload should contain a dead wrapper after sandbox is nuked");
do_print("Dispatch FromTest event");
fromTestPromise = promiseEvent(window, "FromTest");

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

@ -323,6 +323,7 @@ skip-if = toolkit == 'android' # bug 775227 for android
[test_value_computation.html]
skip-if = toolkit == 'android'
[test_value_storage.html]
skip-if = toolkit == 'android' && debug # bug 1397615
[test_variable_serialization_computed.html]
[test_variable_serialization_specified.html]
[test_variables.html]

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

@ -14,6 +14,23 @@
#include "mozilla/Attributes.h"
#include "mozilla/IntegerTypeTraits.h"
// Probe for builtin math overflow support. Disabled for 32-bit builds for now
// since "gcc -m32" claims to support these but its implementation is buggy.
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82274
#if defined(HAVE_64BIT_BUILD)
#if defined(__has_builtin)
#define MOZ_HAS_BUILTIN_OP_OVERFLOW (__has_builtin(__builtin_add_overflow))
#elif defined(__GNUC__)
// (clang also defines __GNUC__ but it supports __has_builtin since at least
// v3.1 (released in 2012) so it won't get here.)
#define MOZ_HAS_BUILTIN_OP_OVERFLOW (__GNUC__ >= 5)
#else
#define MOZ_HAS_BUILTIN_OP_OVERFLOW (0)
#endif
#else
#define MOZ_HAS_BUILTIN_OP_OVERFLOW (0)
#endif
namespace mozilla {
template<typename T> class CheckedInt;
@ -255,6 +272,10 @@ template<typename T>
inline bool
IsAddValid(T aX, T aY)
{
#if MOZ_HAS_BUILTIN_OP_OVERFLOW
T dummy;
return !__builtin_add_overflow(aX, aY, &dummy);
#else
// Addition is valid if the sign of aX+aY is equal to either that of aX or
// that of aY. Since the value of aX+aY is undefined if we have a signed
// type, we compute it using the unsigned type of the same size. Beware!
@ -267,12 +288,17 @@ IsAddValid(T aX, T aY)
return IsSigned<T>::value
? HasSignBit(BinaryComplement(T((result ^ aX) & (result ^ aY))))
: BinaryComplement(aX) >= aY;
#endif
}
template<typename T>
inline bool
IsSubValid(T aX, T aY)
{
#if MOZ_HAS_BUILTIN_OP_OVERFLOW
T dummy;
return !__builtin_sub_overflow(aX, aY, &dummy);
#else
// Subtraction is valid if either aX and aY have same sign, or aX-aY and aX
// have same sign. Since the value of aX-aY is undefined if we have a signed
// type, we compute it using the unsigned type of the same size.
@ -283,6 +309,7 @@ IsSubValid(T aX, T aY)
return IsSigned<T>::value
? HasSignBit(BinaryComplement(T((result ^ aX) & (aX ^ aY))))
: aX >= aY;
#endif
}
template<typename T,
@ -339,7 +366,12 @@ template<typename T>
inline bool
IsMulValid(T aX, T aY)
{
#if MOZ_HAS_BUILTIN_OP_OVERFLOW
T dummy;
return !__builtin_mul_overflow(aX, aY, &dummy);
#else
return IsMulValidImpl<T>::run(aX, aY);
#endif
}
template<typename T>
@ -687,12 +719,30 @@ private:
aLhs.mIsValid && aRhs.mIsValid); \
}
#if MOZ_HAS_BUILTIN_OP_OVERFLOW
#define MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR2(NAME, OP, FUN) \
template<typename T> \
inline CheckedInt<T> \
operator OP(const CheckedInt<T>& aLhs, const CheckedInt<T>& aRhs) \
{ \
T result; \
if (FUN(aLhs.mValue, aRhs.mValue, &result)) { \
return CheckedInt<T>(0, false); \
} \
return CheckedInt<T>(result, aLhs.mIsValid && aRhs.mIsValid); \
}
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR2(Add, +, __builtin_add_overflow)
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR2(Sub, -, __builtin_sub_overflow)
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR2(Mul, *, __builtin_mul_overflow)
#undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR2
#else
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +)
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -)
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *)
#endif
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /)
MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mod, %)
#undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR
// Implement castToCheckedInt<T>(x), making sure that

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

@ -136,6 +136,13 @@
<item>wifi</item>
<item>disabled</item>
</string-array>
<!-- This value is similar to config_longPressVibePattern in android frameworks/base/core/res/res/values/config.xml-->
<integer-array name="long_press_vibrate_msec">
<item>0</item>
<item>1</item>
<item>20</item>
<item>21</item>
</integer-array>
<!-- browser.image_blocking -->
<string-array name="pref_browser_image_blocking_entries">
<item>@string/pref_tap_to_load_images_enabled</item>

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

@ -49,7 +49,6 @@ import android.support.v4.view.MenuItemCompat;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@ -699,7 +698,7 @@ public class BrowserApp extends GeckoApp
final TabHistoryFragment fragment = TabHistoryFragment.newInstance(historyPageList, toIndex);
final FragmentManager fragmentManager = getSupportFragmentManager();
GeckoAppShell.getHapticFeedbackDelegate().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
GeckoAppShell.vibrateOnHapticFeedbackEnabled(getResources().getIntArray(R.array.long_press_vibrate_msec));
fragment.show(R.id.tab_history_panel, fragmentManager.beginTransaction(), TAB_HISTORY_FRAGMENT_TAG);
}
});
@ -1659,6 +1658,7 @@ public class BrowserApp extends GeckoApp
mLayerView.getDynamicToolbarAnimator().addMetricsListener(this);
mLayerView.getDynamicToolbarAnimator().setToolbarChromeProxy(this);
}
mDynamicToolbar.setLayerView(mLayerView);
setDynamicToolbarEnabled(mDynamicToolbar.isEnabled());
// Intercept key events for gamepad shortcuts

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

@ -673,7 +673,7 @@ public abstract class GeckoApp extends GeckoActivity
GeckoAccessibility.updateAccessibilitySettings(this);
} else if ("Accessibility:Event".equals(event)) {
GeckoAccessibility.sendAccessibilityEvent(mLayerView, message);
GeckoAccessibility.sendAccessibilityEvent(message);
} else if ("Bookmark:Insert".equals(event)) {
final BrowserDB db = BrowserDB.from(getProfile());

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

@ -57,8 +57,7 @@ import java.io.File;
import java.lang.reflect.Method;
import java.util.UUID;
public class GeckoApplication extends Application
implements HapticFeedbackDelegate {
public class GeckoApplication extends Application {
private static final String LOG_TAG = "GeckoApplication";
private static final String MEDIA_DECODING_PROCESS_CRASH = "MEDIA_DECODING_PROCESS_CRASH";
@ -230,7 +229,6 @@ public class GeckoApplication extends Application
final Context context = getApplicationContext();
GeckoAppShell.setApplicationContext(context);
GeckoAppShell.setHapticFeedbackDelegate(this);
GeckoAppShell.setGeckoInterface(new GeckoAppShell.GeckoInterface() {
@Override
public boolean openUriExternal(final String targetURI, final String mimeType,
@ -636,13 +634,4 @@ public class GeckoApplication extends Application
return bitmap;
}
@Override // HapticFeedbackDelegate
public void performHapticFeedback(final int effect) {
final Activity currentActivity =
GeckoActivityMonitor.getInstance().getCurrentActivity();
if (currentActivity != null) {
currentActivity.getWindow().getDecorView().performHapticFeedback(effect);
}
}
}

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

@ -71,10 +71,22 @@ public class GeckoService extends Service {
private static final EventListener EVENT_LISTENER = new EventListener();
private static RuntimeException bug1401737Diag;
public static void register() {
if (DEBUG) {
Log.d(LOGTAG, "Registered listener");
}
// Diagnose bug 1401737. register() is unexpectedly getting called a second time.
// We know the stack for the second call, but we want to collect stack for the first call.
if (bug1401737Diag == null) {
bug1401737Diag = new IllegalStateException("Bug 1401737 diagnostic crash");
} else {
Log.e(LOGTAG, "register() is called a second time", new Exception());
throw bug1401737Diag;
}
EventDispatcher.getInstance().registerGeckoThreadListener(EVENT_LISTENER,
"Gecko:ScheduleRun");
}

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

@ -218,6 +218,10 @@ public class CustomTabsActivity extends AppCompatActivity
@Override
public void finish() {
if (mGeckoView != null) {
mGeckoView.loadUri("about:blank");
}
super.finish();
final SafeIntent intent = new SafeIntent(getIntent());

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

@ -17,7 +17,6 @@ import android.content.Intent;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
@ -260,8 +259,7 @@ public class GeckoMenu extends ListView
@Override
public boolean onLongClick(View view) {
if (handleMenuItemLongClick(menuItem)) {
GeckoAppShell.getHapticFeedbackDelegate().performHapticFeedback(
HapticFeedbackConstants.LONG_PRESS);
GeckoAppShell.vibrateOnHapticFeedbackEnabled(getResources().getIntArray(R.array.long_press_vibrate_msec));
return true;
}
return false;
@ -278,8 +276,7 @@ public class GeckoMenu extends ListView
@Override
public boolean onLongClick(View view) {
if (handleMenuItemLongClick(menuItem)) {
GeckoAppShell.getHapticFeedbackDelegate().performHapticFeedback(
HapticFeedbackConstants.LONG_PRESS);
GeckoAppShell.vibrateOnHapticFeedbackEnabled(getResources().getIntArray(R.array.long_press_vibrate_msec));
return true;
}
return false;

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

@ -415,7 +415,6 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x
'gfx/SurfaceTextureListener.java',
'gfx/ViewTransform.java',
'gfx/VsyncSource.java',
'HapticFeedbackDelegate.java',
'InputConnectionListener.java',
'InputMethods.java',
'media/AsyncCodec.java',

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

@ -7,6 +7,8 @@ package org.mozilla.gecko;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.ThreadUtils;
@ -108,8 +110,7 @@ public class GeckoAccessibility {
return sEnabled;
}
public static void sendAccessibilityEvent(final GeckoView view,
final GeckoBundle message) {
public static void sendAccessibilityEvent(final GeckoBundle message) {
if (!sEnabled)
return;
@ -119,11 +120,10 @@ public class GeckoAccessibility {
return;
}
sendAccessibilityEvent(view, message, eventType);
sendAccessibilityEvent(message, eventType);
}
public static void sendAccessibilityEvent(final GeckoView view, final GeckoBundle message,
final int eventType) {
public static void sendAccessibilityEvent(final GeckoBundle message, final int eventType) {
if (!sEnabled)
return;
@ -148,6 +148,10 @@ public class GeckoAccessibility {
} else {
// In Jelly Bean we populate an AccessibilityNodeInfo with the minimal amount of data to have
// it work with TalkBack.
final LayerView view = GeckoAppShell.getLayerView();
if (view == null)
return;
if (sVirtualCursorNode == null) {
sVirtualCursorNode = AccessibilityNodeInfo.obtain(view, VIRTUAL_CURSOR_POSITION);
}
@ -262,12 +266,7 @@ public class GeckoAccessibility {
AccessibilityNodeProvider mAccessibilityNodeProvider;
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider(final View hostView) {
if (!(hostView instanceof GeckoView)) {
return super.getAccessibilityNodeProvider(hostView);
}
final GeckoView host = (GeckoView) hostView;
public AccessibilityNodeProvider getAccessibilityNodeProvider(final View host) {
if (mAccessibilityNodeProvider == null)
// The accessibility node structure for web content consists of 3 LayerView child nodes:
// 1. VIRTUAL_ENTRY_POINT_BEFORE: Represents the entry point before the LayerView.
@ -320,7 +319,7 @@ public class GeckoAccessibility {
// The accessibility focus is permanently on the middle node, VIRTUAL_CURSOR_POSITION.
// When we enter the view forward or backward we just ask Gecko to get focus, keeping the current position.
if (virtualViewId == VIRTUAL_CURSOR_POSITION && sHoverEnter != null) {
GeckoAccessibility.sendAccessibilityEvent(host, sHoverEnter, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
GeckoAccessibility.sendAccessibilityEvent(sHoverEnter, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
} else {
final GeckoBundle data = new GeckoBundle(1);
data.putBoolean("gainFocus", true);

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

@ -28,6 +28,7 @@ import org.mozilla.gecko.annotation.JNITarget;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.gfx.BitmapUtils;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.permissions.Permissions;
import org.mozilla.gecko.process.GeckoProcessManager;
import org.mozilla.gecko.util.HardwareCodecCapabilityUtils;
@ -221,8 +222,21 @@ public class GeckoAppShell
@WrapForJNI(dispatchTo = "gecko")
public static native void notifyUriVisited(String uri);
private static LayerView sLayerView;
private static Rect sScreenSize;
public static void setLayerView(LayerView lv) {
if (sLayerView == lv) {
return;
}
sLayerView = lv;
}
@RobocopTarget
public static LayerView getLayerView() {
return sLayerView;
}
@WrapForJNI(stubName = "NotifyObservers", dispatchTo = "gecko")
private static native void nativeNotifyObservers(String topic, String data);
@ -367,8 +381,7 @@ public class GeckoAppShell
LocationListener,
NotificationListener,
ScreenOrientationDelegate,
WakeLockDelegate,
HapticFeedbackDelegate {
WakeLockDelegate {
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@ -548,22 +561,6 @@ public class GeckoAppShell
mWakeLocks.remove(lock);
}
}
@Override
public void performHapticFeedback(final int effect) {
final int[] pattern;
// Use default platform values.
if (effect == HapticFeedbackConstants.KEYBOARD_TAP) {
pattern = new int[] { 40 };
} else if (effect == HapticFeedbackConstants.LONG_PRESS) {
pattern = new int[] { 0, 1, 20, 21 };
} else if (effect == HapticFeedbackConstants.VIRTUAL_KEY) {
pattern = new int[] { 0, 10, 20, 30 };
} else {
return;
}
vibrateOnHapticFeedbackEnabled(pattern);
}
}
private static final DefaultListeners DEFAULT_LISTENERS = new DefaultListeners();
@ -571,7 +568,6 @@ public class GeckoAppShell
private static LocationListener sLocationListener = DEFAULT_LISTENERS;
private static NotificationListener sNotificationListener = DEFAULT_LISTENERS;
private static WakeLockDelegate sWakeLockDelegate = DEFAULT_LISTENERS;
private static HapticFeedbackDelegate sHapticFeedbackDelegate = DEFAULT_LISTENERS;
/**
* A delegate for supporting the Screen Orientation API.
@ -618,14 +614,6 @@ public class GeckoAppShell
sWakeLockDelegate = (delegate != null) ? delegate : DEFAULT_LISTENERS;
}
public static HapticFeedbackDelegate getHapticFeedbackDelegate() {
return sHapticFeedbackDelegate;
}
public static void setHapticFeedbackDelegate(final HapticFeedbackDelegate delegate) {
sHapticFeedbackDelegate = (delegate != null) ? delegate : DEFAULT_LISTENERS;
}
@WrapForJNI(calledFrom = "gecko")
private static void enableSensor(int aSensortype) {
final SensorManager sm = (SensorManager)
@ -1014,11 +1002,10 @@ public class GeckoAppShell
// Don't perform haptic feedback if a vibration is currently playing,
// because the haptic feedback will nuke the vibration.
if (!sVibrationMaybePlaying || System.nanoTime() >= sVibrationEndTime) {
getHapticFeedbackDelegate().performHapticFeedback(
aIsLongPress ? HapticFeedbackConstants.LONG_PRESS
: HapticFeedbackConstants.VIRTUAL_KEY);
sVibrationMaybePlaying = false;
sVibrationEndTime = 0;
LayerView layerView = getLayerView();
layerView.performHapticFeedback(aIsLongPress ?
HapticFeedbackConstants.LONG_PRESS :
HapticFeedbackConstants.VIRTUAL_KEY);
}
}
@ -1036,14 +1023,10 @@ public class GeckoAppShell
}
// Vibrate only if haptic feedback is enabled.
private static void vibrateOnHapticFeedbackEnabled(int[] milliseconds) {
public static void vibrateOnHapticFeedbackEnabled(int[] milliseconds) {
if (Settings.System.getInt(getApplicationContext().getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) > 0) {
if (milliseconds.length == 1) {
vibrate(milliseconds[0]);
} else {
vibrate(convertIntToLongArray(milliseconds), -1);
}
vibrate(convertIntToLongArray(milliseconds), -1);
}
}
@ -1056,10 +1039,10 @@ public class GeckoAppShell
@WrapForJNI(calledFrom = "gecko")
private static void vibrate(long[] pattern, int repeat) {
// If pattern.length is odd, the last element in the pattern is a
// If pattern.length is even, the last element in the pattern is a
// meaningless delay, so don't include it in vibrationDuration.
long vibrationDuration = 0;
int iterLen = pattern.length & ~1;
int iterLen = pattern.length - (pattern.length % 2 == 0 ? 1 : 0);
for (int i = 0; i < iterLen; i++) {
vibrationDuration += pattern[i];
}
@ -1570,6 +1553,21 @@ public class GeckoAppShell
return HardwareUtils.isTablet();
}
private static boolean sImeWasEnabledOnLastResize = false;
public static void viewSizeChanged() {
GeckoView v = (GeckoView) getLayerView();
if (v == null) {
return;
}
boolean imeIsEnabled = v.isIMEEnabled();
if (imeIsEnabled && !sImeWasEnabledOnLastResize) {
// The IME just came up after not being up, so let's scroll
// to the focused input.
EventDispatcher.getInstance().dispatch("ScrollTo:FocusedInput", null);
}
sImeWasEnabledOnLastResize = imeIsEnabled;
}
@WrapForJNI(calledFrom = "gecko")
private static double[] getCurrentNetworkInformation() {
return GeckoNetworkManager.getInstance().getCurrentInformation();

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

@ -72,7 +72,7 @@ class GeckoInputConnection
private String mCurrentInputMethod = "";
private final GeckoView mView;
private final View mView;
private final GeckoEditableClient mEditableClient;
protected int mBatchEditCount;
private ExtractedTextRequest mUpdateRequest;
@ -83,7 +83,7 @@ class GeckoInputConnection
// Prevent showSoftInput and hideSoftInput from causing reentrant calls on some devices.
private volatile boolean mSoftInputReentrancyGuard;
public static GeckoEditableListener create(GeckoView targetView,
public static GeckoEditableListener create(View targetView,
GeckoEditableClient editable) {
if (DEBUG)
return DebugGeckoInputConnection.create(targetView, editable);
@ -91,7 +91,7 @@ class GeckoInputConnection
return new GeckoInputConnection(targetView, editable);
}
protected GeckoInputConnection(GeckoView targetView,
protected GeckoInputConnection(View targetView,
GeckoEditableClient editable) {
super(targetView, true);
mView = targetView;
@ -204,7 +204,7 @@ class GeckoInputConnection
return extract;
}
private GeckoView getView() {
private View getView() {
return mView;
}
@ -236,10 +236,7 @@ class GeckoInputConnection
v.clearFocus();
v.requestFocus();
}
final GeckoView view = getView();
if (view != null) {
view.getDynamicToolbarAnimator().showToolbar(/*immediately*/ true);
}
GeckoAppShell.getLayerView().getDynamicToolbarAnimator().showToolbar(/*immediately*/true);
mSoftInputReentrancyGuard = true;
imm.showSoftInput(v, 0);
mSoftInputReentrancyGuard = false;
@ -362,18 +359,18 @@ class GeckoInputConnection
mCursorAnchorInfoBuilder.reset();
// Calculate Gecko logical coords to screen coords
final GeckoView view = getView();
if (view == null) {
final View v = getView();
if (v == null) {
return;
}
int[] viewCoords = new int[2];
view.getLocationOnScreen(viewCoords);
v.getLocationOnScreen(viewCoords);
DynamicToolbarAnimator animator = view.getDynamicToolbarAnimator();
float toolbarHeight = (float) animator.getCurrentToolbarHeight();
DynamicToolbarAnimator animator = GeckoAppShell.getLayerView().getDynamicToolbarAnimator();
float toolbarHeight = (float)animator.getCurrentToolbarHeight();
Matrix matrix = view.getMatrixForLayerRectToViewRect();
Matrix matrix = GeckoAppShell.getLayerView().getMatrixForLayerRectToViewRect();
if (matrix == null) {
if (DEBUG) {
Log.d(LOGTAG, "Cannot get Matrix to convert from Gecko coords to layer view coords");
@ -1037,13 +1034,13 @@ final class DebugGeckoInputConnection
private InputConnection mProxy;
private final StringBuilder mCallLevel;
private DebugGeckoInputConnection(GeckoView targetView,
private DebugGeckoInputConnection(View targetView,
GeckoEditableClient editable) {
super(targetView, editable);
mCallLevel = new StringBuilder();
}
public static GeckoEditableListener create(GeckoView targetView,
public static GeckoEditableListener create(View targetView,
GeckoEditableClient editable) {
final Class<?>[] PROXY_INTERFACES = { InputConnection.class,
InputConnectionListener.class,

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

@ -488,6 +488,9 @@ public class GeckoView extends LayerView {
private void init(final Context context, final GeckoViewSettings settings) {
preload(context);
// Perform common initialization for Fennec/GeckoView.
GeckoAppShell.setLayerView(this);
initializeView();
mListener.registerListeners();
@ -748,8 +751,7 @@ public class GeckoView extends LayerView {
mInputConnectionListener.onKeyMultiple(keyCode, repeatCount, event);
}
@Override
public boolean isIMEEnabled() {
/* package */ boolean isIMEEnabled() {
return mInputConnectionListener != null &&
mInputConnectionListener.isIMEEnabled();
}

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

@ -1,20 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import android.view.HapticFeedbackConstants;
/**
* A <code>HapticFeedbackDelegate</code> is responsible for performing haptic feedback.
*/
public interface HapticFeedbackDelegate {
/**
* Perform a haptic feedback effect. Called from the Gecko thread.
*
* @param effect Effect to perform from <code>android.view.HapticFeedbackConstants</code>.
*/
void performHapticFeedback(int effect);
}

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

@ -33,7 +33,6 @@ class GeckoLayerClient implements LayerView.Listener
private IntSize mWindowSize;
private boolean mForceRedraw;
private boolean mImeWasEnabledOnLastResize;
/* The current viewport metrics.
* This is volatile so that we can read and write to it from different threads.
@ -154,13 +153,7 @@ class GeckoLayerClient implements LayerView.Listener
// the following call also sends gecko a message, which will be processed after the resize
// message above has updated the viewport. this message ensures that if we have just put
// focus in a text field, we scroll the content so that the text field is in view.
final boolean imeIsEnabled = mView.isIMEEnabled();
if (imeIsEnabled && !mImeWasEnabledOnLastResize) {
// The IME just came up after not being up, so let's scroll
// to the focused input.
EventDispatcher.getInstance().dispatch("ScrollTo:FocusedInput", null);
}
mImeWasEnabledOnLastResize = imeIsEnabled;
GeckoAppShell.viewSizeChanged();
}
return true;
}

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

@ -824,9 +824,5 @@ public class LayerView extends FrameLayout {
if (isCompositorReady()) {
mCompositor.setDefaultClearColor(mDefaultClearColor);
}
}
public boolean isIMEEnabled() {
return false;
}
}
}

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

@ -356,7 +356,7 @@ public class FennecNativeActions implements Actions {
PaintExpecter() {
final PaintExpecter expecter = this;
mLayerView = (LayerView) mSolo.getView(R.id.layer_view);
mLayerView = GeckoAppShell.getLayerView();
mDrawListener = new DrawListener() {
@Override
public void drawFinished() {

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

@ -356,8 +356,7 @@ abstract class BaseTest extends BaseRobocopTest {
// If we don't see the item, scroll down once in case it's off-screen.
// Hacky way to scroll down. solo.scroll* does not work in dialogs.
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mSolo,
mDriver.getGeckoLeft(), mDriver.getGeckoTop());
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
meh.dragSync(mScreenMidWidth, mScreenMidHeight+100, mScreenMidWidth, mScreenMidHeight-100);
foundText = mSolo.waitForText(txt);

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

@ -5,11 +5,8 @@
package org.mozilla.gecko.tests;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.PrefsHelper;
import org.mozilla.gecko.R;
import org.mozilla.gecko.gfx.LayerView;
import com.robotium.solo.Solo;
import org.mozilla.gecko.PrefsHelper;
import android.app.Instrumentation;
import android.os.SystemClock;
@ -29,12 +26,11 @@ class MotionEventHelper {
private float mTouchStartTolerance;
private final int mDpi;
public MotionEventHelper(Instrumentation inst, Solo solo,
int surfaceOffsetX, int surfaceOffsetY) {
public MotionEventHelper(Instrumentation inst, int surfaceOffsetX, int surfaceOffsetY) {
mInstrumentation = inst;
mSurfaceOffsetX = surfaceOffsetX;
mSurfaceOffsetY = surfaceOffsetY;
layerView = (LayerView) solo.getView(R.id.layer_view);
layerView = GeckoAppShell.getLayerView();
mApzEnabled = false;
mTouchStartTolerance = 0.0f;
mDpi = GeckoAppShell.getDpi();

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

@ -19,8 +19,7 @@ public class testAxisLocking extends PixelTest {
public void testAxisLocking() {
String url = getAbsoluteUrl(mStringHelper.ROBOCOP_BOXES_URL);
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mSolo,
mDriver.getGeckoLeft(), mDriver.getGeckoTop());
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
blockForGeckoReady();

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

@ -17,8 +17,7 @@ public class testFlingCorrectness extends PixelTest {
public void testFlingCorrectness() {
String url = getAbsoluteUrl(mStringHelper.ROBOCOP_BOXES_URL);
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mSolo,
mDriver.getGeckoLeft(), mDriver.getGeckoTop());
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
blockForGeckoReady();

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

@ -17,8 +17,7 @@ public class testPanCorrectness extends PixelTest {
public void testPanCorrectness() {
String url = getAbsoluteUrl(mStringHelper.ROBOCOP_BOXES_URL);
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mSolo,
mDriver.getGeckoLeft(), mDriver.getGeckoTop());
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
blockForGeckoReady();

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

@ -29,8 +29,7 @@ public class testVkbOverlap extends PixelTest {
// scroll to the bottom of the page and let it settle
Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mSolo,
mDriver.getGeckoLeft(), mDriver.getGeckoTop());
MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
meh.dragSync(10, 150, 10, 50);
// the input field has a green background, so let's count the number of green pixels

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

@ -684,7 +684,7 @@ nsHtml5TreeOperation::AppendDoctypeToDocument(nsIAtom* aName,
aName,
aPublicId,
aSystemId,
NullString());
VoidString());
NS_ASSERTION(docType, "Doctype creation failed.");
nsCOMPtr<nsIContent> asContent = do_QueryInterface(docType);
return AppendToDocument(asContent, aBuilder);

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

@ -1,18 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIAtom.h"
#include "nsElementTable.h"
/*****************************************************************************
Now it's time to list all the html elements all with their capabilities...
******************************************************************************/
static const int kNone= 0x0;
// The Element Table (sung to the tune of Modern Major General)
static const int kHTMLContent = 0x0001; // HEAD, (FRAMESET | BODY)
static const int kHeadContent = 0x0002; // Elements that *must* be in the head.
static const int kHeadMisc = 0x0004; // Elements that *can* be in the head.
static const int kSpecial = 0x0008; // A, IMG, APPLET, OBJECT, FONT, BASEFONT, BR, SCRIPT,
// MAP, Q, SUB, SUP, SPAN, BDO, IFRAME
static const int kFormControl = 0x0010; // INPUT SELECT TEXTAREA LABEL BUTTON
static const int kPreformatted = 0x0020; // PRE
static const int kPreExclusion = 0x0040; // IMG, OBJECT, APPLET, BIG, SMALL, SUB, SUP, FONT, BASEFONT
static const int kFontStyle = 0x0080; // TT, I, B, U, S, STRIKE, BIG, SMALL
static const int kPhrase = 0x0100; // EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ABBR, ACRONYM
static const int kHeading = 0x0200; // H1..H6
static const int kBlockMisc = 0x0400; // OBJECT, SCRIPT
static const int kBlock = 0x0800; // ADDRESS, BLOCKQUOTE, CENTER, DIV, DL, FIELDSET, FORM,
// ISINDEX, HR, NOSCRIPT, NOFRAMES, P, TABLE
static const int kList = 0x1000; // UL, OL, DIR, MENU
static const int kPCDATA = 0x2000; // plain text and entities...
static const int kSelf = 0x4000; // whatever THIS tag is...
static const int kExtensions = 0x8000; // BGSOUND, WBR, NOBR
static const int kTable = 0x10000;// TR,TD,THEAD,TBODY,TFOOT,CAPTION,TH
static const int kDLChild = 0x20000;// DL, DT
static const int kCDATA = 0x40000;// just plain text...
static const int kInlineEntity = (kPCDATA|kFontStyle|kPhrase|kSpecial|kFormControl|kExtensions); // #PCDATA, %fontstyle, %phrase, %special, %formctrl
static const int kBlockEntity = (kHeading|kList|kPreformatted|kBlock); // %heading, %list, %preformatted, %block
static const int kFlowEntity = (kBlockEntity|kInlineEntity); // %blockentity, %inlineentity
static const int kAllTags = 0xffffff;
// Is aTest a member of aBitset?
static bool
TestBits(int32_t aBitset, int32_t aTest)
{
if (aTest) {
int32_t result = aBitset & aTest;
return result == aTest;
}
return false;
}
struct HTMLElement
{
bool IsMemberOf(int32_t aBitset) const
{
return TestBits(aBitset, mParentBits);
}
#ifdef DEBUG
nsHTMLTag mTagID;
#endif
int mParentBits; // defines groups that can contain this element
bool mLeaf;
};
#ifdef DEBUG
#define ELEM(tag, parent, leaf) { eHTMLTag_##tag, parent, leaf },
@ -20,7 +68,7 @@
#define ELEM(tag, parent, leaf) { parent, leaf },
#endif
const nsHTMLElement gHTMLElements[] = {
static const HTMLElement gHTMLElements[] = {
ELEM(unknown, kNone, true)
ELEM(a, kSpecial, false)
ELEM(abbr, kPhrase, false)
@ -172,19 +220,14 @@ const nsHTMLElement gHTMLElements[] = {
#undef ELEM
/*********************************************************************************************/
bool nsHTMLElement::IsMemberOf(int32_t aSet) const
{
return TestBits(aSet, mParentBits);
}
bool nsHTMLElement::IsContainer(eHTMLTags aId)
bool
nsHTMLElement::IsContainer(nsHTMLTag aId)
{
return !gHTMLElements[aId].mLeaf;
}
bool nsHTMLElement::IsBlock(eHTMLTags aId)
bool
nsHTMLElement::IsBlock(nsHTMLTag aId)
{
return gHTMLElements[aId].IsMemberOf(kBlock) ||
gHTMLElements[aId].IsMemberOf(kBlockEntity) ||
@ -194,10 +237,14 @@ bool nsHTMLElement::IsBlock(eHTMLTags aId)
}
#ifdef DEBUG
void CheckElementTable()
void
CheckElementTable()
{
for (eHTMLTags t = eHTMLTag_unknown; t <= eHTMLTag_userdefined; t = eHTMLTags(t + 1)) {
NS_ASSERTION(gHTMLElements[t].mTagID == t, "gHTMLElements entries does match tag list.");
for (nsHTMLTag t = eHTMLTag_unknown;
t <= eHTMLTag_userdefined;
t = nsHTMLTag(t + 1)) {
MOZ_ASSERT(gHTMLElements[t].mTagID == t,
"gHTMLElements entries does match tag list.");
}
}
#endif

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

@ -1,95 +1,22 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* MODULE NOTES:
* @update gess 4/1/98
*
*/
#ifndef _NSELEMENTABLE
#define _NSELEMENTABLE
#ifndef nsElementTable_h
#define nsElementTable_h
#include "nsHTMLTags.h"
#include "nsIDTD.h"
//*********************************************************************************************
// The following ints define the standard groups of HTML elements...
//*********************************************************************************************
static const int kNone= 0x0;
static const int kHTMLContent = 0x0001; // HEAD, (FRAMESET | BODY)
static const int kHeadContent = 0x0002; // Elements that *must* be in the head.
static const int kHeadMisc = 0x0004; // Elements that *can* be in the head.
static const int kSpecial = 0x0008; // A, IMG, APPLET, OBJECT, FONT, BASEFONT, BR, SCRIPT,
// MAP, Q, SUB, SUP, SPAN, BDO, IFRAME
static const int kFormControl = 0x0010; // INPUT SELECT TEXTAREA LABEL BUTTON
static const int kPreformatted = 0x0020; // PRE
static const int kPreExclusion = 0x0040; // IMG, OBJECT, APPLET, BIG, SMALL, SUB, SUP, FONT, BASEFONT
static const int kFontStyle = 0x0080; // TT, I, B, U, S, STRIKE, BIG, SMALL
static const int kPhrase = 0x0100; // EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ABBR, ACRONYM
static const int kHeading = 0x0200; // H1..H6
static const int kBlockMisc = 0x0400; // OBJECT, SCRIPT
static const int kBlock = 0x0800; // ADDRESS, BLOCKQUOTE, CENTER, DIV, DL, FIELDSET, FORM,
// ISINDEX, HR, NOSCRIPT, NOFRAMES, P, TABLE
static const int kList = 0x1000; // UL, OL, DIR, MENU
static const int kPCDATA = 0x2000; // plain text and entities...
static const int kSelf = 0x4000; // whatever THIS tag is...
static const int kExtensions = 0x8000; // BGSOUND, WBR, NOBR
static const int kTable = 0x10000;// TR,TD,THEAD,TBODY,TFOOT,CAPTION,TH
static const int kDLChild = 0x20000;// DL, DT
static const int kCDATA = 0x40000;// just plain text...
static const int kInlineEntity = (kPCDATA|kFontStyle|kPhrase|kSpecial|kFormControl|kExtensions); // #PCDATA, %fontstyle, %phrase, %special, %formctrl
static const int kBlockEntity = (kHeading|kList|kPreformatted|kBlock); // %heading, %list, %preformatted, %block
static const int kFlowEntity = (kBlockEntity|kInlineEntity); // %blockentity, %inlineentity
static const int kAllTags = 0xffffff;
//*********************************************************************************************
// The following ints define the standard groups of HTML elements...
//*********************************************************************************************
#ifdef DEBUG
extern void CheckElementTable();
void CheckElementTable();
#endif
/**
* We're asking the question: is aTest a member of bitset.
*
* @param
* @return TRUE or FALSE
*/
inline bool TestBits(int aBitset,int aTest) {
if(aTest) {
int32_t result=(aBitset & aTest);
return bool(result==aTest);
}
return false;
}
struct nsHTMLElement {
bool IsMemberOf(int32_t aType) const;
#ifdef DEBUG
eHTMLTags mTagID;
#endif
int mParentBits; //defines groups that can contain this element
bool mLeaf;
static bool IsContainer(eHTMLTags aTag);
static bool IsBlock(eHTMLTags aTag);
struct nsHTMLElement
{
static bool IsContainer(nsHTMLTag aTag);
static bool IsBlock(nsHTMLTag aTag);
};
extern const nsHTMLElement gHTMLElements[];
#endif
#endif // nsElementTable_h

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

@ -84,6 +84,4 @@ private:
static PLHashTable* gTagAtomTable;
};
#define eHTMLTags nsHTMLTag
#endif /* nsHTMLTags_h___ */

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше