mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
967e6f7f03
@ -6,19 +6,27 @@
|
||||
var FullScreen = {
|
||||
_XULNS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
|
||||
|
||||
_MESSAGES: [
|
||||
"DOMFullscreen:Entered",
|
||||
"DOMFullscreen:NewOrigin",
|
||||
"DOMFullscreen:Exited"
|
||||
],
|
||||
|
||||
init: function() {
|
||||
// called when we go into full screen, even if initiated by a web page script
|
||||
window.addEventListener("fullscreen", this, true);
|
||||
window.messageManager.addMessageListener("MozEnteredDomFullscreen", this);
|
||||
window.messageManager.addMessageListener("MozExitedDomFullscreen", this);
|
||||
for (let type of this._MESSAGES) {
|
||||
window.messageManager.addMessageListener(type, this);
|
||||
}
|
||||
|
||||
if (window.fullScreen)
|
||||
this.toggle();
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
window.messageManager.removeMessageListener("MozEnteredDomFullscreen", this);
|
||||
window.messageManager.removeMessageListener("MozExitedDomFullscreen", this);
|
||||
for (let type of this._MESSAGES) {
|
||||
window.messageManager.removeMessageListener(type, this);
|
||||
}
|
||||
this.cleanup();
|
||||
},
|
||||
|
||||
@ -93,34 +101,45 @@ var FullScreen = {
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
if (aMessage.name == "MozEnteredDomFullscreen") {
|
||||
// If we're a multiprocess browser, then the request to enter fullscreen
|
||||
// did not bubble up to the root browser document - it stopped at the root
|
||||
// of the content document. That means we have to kick off the switch to
|
||||
// fullscreen here at the operating system level in the parent process
|
||||
// ourselves.
|
||||
let data = aMessage.data;
|
||||
let browser = aMessage.target;
|
||||
if (gMultiProcessBrowser && browser.getAttribute("remote") == "true") {
|
||||
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
windowUtils.remoteFrameFullscreenChanged(browser, data.origin);
|
||||
let browser = aMessage.target;
|
||||
switch (aMessage.name) {
|
||||
case "DOMFullscreen:Entered": {
|
||||
// If we're a multiprocess browser, then the request to enter
|
||||
// fullscreen did not bubble up to the root browser document -
|
||||
// it stopped at the root of the content document. That means
|
||||
// we have to kick off the switch to fullscreen here at the
|
||||
// operating system level in the parent process ourselves.
|
||||
if (this._isRemoteBrowser(browser)) {
|
||||
this._windowUtils.remoteFrameFullscreenChanged(browser);
|
||||
}
|
||||
this.enterDomFullscreen(browser);
|
||||
break;
|
||||
}
|
||||
this.enterDomFullscreen(browser, data.origin);
|
||||
} else if (aMessage.name == "MozExitedDomFullscreen") {
|
||||
document.documentElement.removeAttribute("inDOMFullscreen");
|
||||
this.cleanupDomFullscreen();
|
||||
this.showNavToolbox();
|
||||
// If we are still in fullscreen mode, re-hide
|
||||
// the toolbox with animation.
|
||||
if (window.fullScreen) {
|
||||
this._shouldAnimate = true;
|
||||
this.hideNavToolbox();
|
||||
case "DOMFullscreen:NewOrigin": {
|
||||
this.showWarning(aMessage.data.origin);
|
||||
break;
|
||||
}
|
||||
case "DOMFullscreen:Exited": {
|
||||
// Like entering DOM fullscreen, we also need to exit fullscreen
|
||||
// at the operating system level in the parent process here.
|
||||
if (this._isRemoteBrowser(browser)) {
|
||||
this._windowUtils.remoteFrameFullscreenReverted();
|
||||
}
|
||||
document.documentElement.removeAttribute("inDOMFullscreen");
|
||||
this.cleanupDomFullscreen();
|
||||
this.showNavToolbox();
|
||||
// If we are still in fullscreen mode, re-hide
|
||||
// the toolbox with animation.
|
||||
if (window.fullScreen) {
|
||||
this._shouldAnimate = true;
|
||||
this.hideNavToolbox();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
enterDomFullscreen : function(aBrowser, aOrigin) {
|
||||
enterDomFullscreen : function(aBrowser) {
|
||||
if (!document.mozFullScreen)
|
||||
return;
|
||||
|
||||
@ -146,8 +165,6 @@ var FullScreen = {
|
||||
if (gFindBarInitialized)
|
||||
gFindBar.close();
|
||||
|
||||
this.showWarning(aOrigin);
|
||||
|
||||
// Exit DOM full-screen mode upon open, close, or change tab.
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
|
||||
gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
|
||||
@ -186,7 +203,16 @@ var FullScreen = {
|
||||
window.removeEventListener("activate", this);
|
||||
|
||||
window.messageManager
|
||||
.broadcastAsyncMessage("DOMFullscreen:Cleanup");
|
||||
.broadcastAsyncMessage("DOMFullscreen:CleanUp");
|
||||
},
|
||||
|
||||
_isRemoteBrowser: function (aBrowser) {
|
||||
return gMultiProcessBrowser && aBrowser.getAttribute("remote") == "true";
|
||||
},
|
||||
|
||||
get _windowUtils() {
|
||||
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
},
|
||||
|
||||
getMouseTargetRect: function()
|
||||
|
@ -591,8 +591,9 @@ let DOMFullscreenHandler = {
|
||||
init: function() {
|
||||
addMessageListener("DOMFullscreen:Approved", this);
|
||||
addMessageListener("DOMFullscreen:CleanUp", this);
|
||||
addEventListener("MozEnteredDomFullscreen", this);
|
||||
addEventListener("MozExitedDomFullscreen", this);
|
||||
addEventListener("MozDOMFullscreen:Entered", this);
|
||||
addEventListener("MozDOMFullscreen:NewOrigin", this);
|
||||
addEventListener("MozDOMFullscreen:Exited", this);
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
@ -606,6 +607,9 @@ let DOMFullscreenHandler = {
|
||||
break;
|
||||
}
|
||||
case "DOMFullscreen:CleanUp": {
|
||||
let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
utils.exitFullscreen();
|
||||
this._fullscreenDoc = null;
|
||||
break;
|
||||
}
|
||||
@ -613,13 +617,22 @@ let DOMFullscreenHandler = {
|
||||
},
|
||||
|
||||
handleEvent: function(aEvent) {
|
||||
if (aEvent.type == "MozEnteredDomFullscreen") {
|
||||
this._fullscreenDoc = aEvent.target;
|
||||
sendAsyncMessage("MozEnteredDomFullscreen", {
|
||||
origin: this._fullscreenDoc.nodePrincipal.origin,
|
||||
});
|
||||
} else if (aEvent.type == "MozExitedDomFullscreen") {
|
||||
sendAsyncMessage("MozExitedDomFullscreen");
|
||||
switch (aEvent.type) {
|
||||
case "MozDOMFullscreen:Entered": {
|
||||
sendAsyncMessage("DOMFullscreen:Entered");
|
||||
break;
|
||||
}
|
||||
case "MozDOMFullscreen:NewOrigin": {
|
||||
this._fullscreenDoc = aEvent.target;
|
||||
sendAsyncMessage("DOMFullscreen:NewOrigin", {
|
||||
origin: this._fullscreenDoc.nodePrincipal.origin,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "MozDOMFullscreen:Exited": {
|
||||
sendAsyncMessage("DOMFullscreen:Exited");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -74,7 +74,7 @@ let SessionStorageInternal = {
|
||||
|
||||
// Get the root domain of the current history entry
|
||||
// and use that as a key for the per-host storage data.
|
||||
let origin = principal.jarPrefix + principal.origin;
|
||||
let origin = principal.jarPrefix + principal.originNoSuffix;
|
||||
if (visitedOrigins.has(origin)) {
|
||||
// Don't read a host twice.
|
||||
return;
|
||||
|
@ -19,7 +19,7 @@ MOZ_ARG_WITH_BOOL(system-icu,
|
||||
if test -n "$MOZ_NATIVE_ICU"; then
|
||||
PKG_CHECK_MODULES(MOZ_ICU, icu-i18n >= 50.1)
|
||||
MOZ_SHARED_ICU=1
|
||||
elif test -n "$gonkdir" -a "$ANDROID_VERSION" -ge 17; then
|
||||
elif test -n "$gonkdir" && test "$ANDROID_VERSION" -ge 17; then
|
||||
dnl Use system's ICU since version is 50.1+.
|
||||
if test -d "$gonkdir/external/icu/icu4c/source"; then
|
||||
dnl gonk-L (API version is 21)
|
||||
|
@ -276,9 +276,24 @@ class B2GRemoteAutomation(Automation):
|
||||
if 'b2g' not in session:
|
||||
raise Exception("bad session value %s returned by start_session" % session)
|
||||
|
||||
if self.context_chrome:
|
||||
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
|
||||
else:
|
||||
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
|
||||
self.marionette.execute_script("""
|
||||
let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Services.prefs.setBoolPref(SECURITY_PREF, true);
|
||||
|
||||
if (!testUtils.hasOwnProperty("specialPowersObserver")) {
|
||||
let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Components.interfaces.mozIJSSubScriptLoader);
|
||||
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.js",
|
||||
testUtils);
|
||||
testUtils.specialPowersObserver = new testUtils.SpecialPowersObserver();
|
||||
testUtils.specialPowersObserver.init();
|
||||
testUtils.specialPowersObserver._loadFrameScript();
|
||||
}
|
||||
""")
|
||||
|
||||
if not self.context_chrome:
|
||||
self.marionette.set_context(self.marionette.CONTEXT_CONTENT)
|
||||
|
||||
# run the script that starts the tests
|
||||
|
@ -8,29 +8,69 @@
|
||||
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
|
||||
#include "nsPrincipal.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
BasePrincipal::OriginAttributes::Serialize(nsIObjectOutputStream* aStream) const
|
||||
OriginAttributes::CreateSuffix(nsACString& aStr)
|
||||
{
|
||||
aStr.Truncate();
|
||||
MOZ_RELEASE_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
int attrCount = 0;
|
||||
|
||||
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
||||
aStr.Append(attrCount++ ? "&appId=" : "!appId=");
|
||||
aStr.AppendInt(mAppId);
|
||||
}
|
||||
|
||||
if (mInBrowser) {
|
||||
aStr.Append(attrCount++ ? "&inBrowser=1" : "!inBrowser=1");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::Serialize(nsIObjectOutputStream* aStream) const
|
||||
{
|
||||
aStream->Write32(mAppId);
|
||||
aStream->WriteBoolean(mIsInBrowserElement);
|
||||
aStream->WriteBoolean(mInBrowser);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BasePrincipal::OriginAttributes::Deserialize(nsIObjectInputStream* aStream)
|
||||
OriginAttributes::Deserialize(nsIObjectInputStream* aStream)
|
||||
{
|
||||
nsresult rv = aStream->Read32(&mAppId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aStream->ReadBoolean(&mIsInBrowserElement);
|
||||
rv = aStream->ReadBoolean(&mInBrowser);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetOrigin(nsACString& aOrigin)
|
||||
{
|
||||
nsresult rv = GetOriginInternal(aOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsAutoCString suffix;
|
||||
mOriginAttributes.CreateSuffix(suffix);
|
||||
aOrigin.Append(suffix);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
|
||||
{
|
||||
return GetOriginInternal(aOrigin);
|
||||
}
|
||||
|
||||
bool
|
||||
BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
|
||||
{
|
||||
@ -104,6 +144,31 @@ BasePrincipal::GetJarPrefix(nsACString& aJarPrefix)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
|
||||
{
|
||||
if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
|
||||
{
|
||||
mOriginAttributes.CreateSuffix(aOriginAttributes);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetCookieJar(nsACString& aCookieJar)
|
||||
{
|
||||
// We just forward to .jarPrefix for now, which is a nice compact
|
||||
// stringification of the (appId, inBrowser) tuple. This will eventaully be
|
||||
// swapped out for an origin attribute - see the comment in nsIPrincipal.idl.
|
||||
return GetJarPrefix(aCookieJar);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetAppStatus(uint16_t* aAppStatus)
|
||||
{
|
||||
@ -144,4 +209,36 @@ BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<BasePrincipal>
|
||||
BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, OriginAttributes& aAttrs)
|
||||
{
|
||||
// If the URI is supposed to inherit the security context of whoever loads it,
|
||||
// we shouldn't make a codebase principal for it.
|
||||
bool inheritsPrincipal;
|
||||
nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
|
||||
&inheritsPrincipal);
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(rv) || inheritsPrincipal) {
|
||||
return nsNullPrincipal::Create();
|
||||
}
|
||||
|
||||
// Check whether the URI knows what its principal is supposed to be.
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
|
||||
if (uriPrinc) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||
if (!principal) {
|
||||
return nsNullPrincipal::Create();
|
||||
}
|
||||
nsRefPtr<BasePrincipal> concrete = Cast(principal);
|
||||
return concrete.forget();
|
||||
}
|
||||
|
||||
// Mint a codebase principal.
|
||||
nsRefPtr<nsPrincipal> codebase = new nsPrincipal();
|
||||
rv = codebase->Init(aURI, aAttrs);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
return codebase.forget();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -11,11 +11,42 @@
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
|
||||
#include "mozilla/dom/SystemDictionariesBinding.h"
|
||||
|
||||
class nsIObjectOutputStream;
|
||||
class nsIObjectInputStream;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes : public dom::OriginAttributesDictionary
|
||||
{
|
||||
public:
|
||||
OriginAttributes() {}
|
||||
OriginAttributes(uint32_t aAppId, bool aInBrowser)
|
||||
{
|
||||
mAppId = aAppId;
|
||||
mInBrowser = aInBrowser;
|
||||
}
|
||||
|
||||
bool operator==(const OriginAttributes& aOther) const
|
||||
{
|
||||
return mAppId == aOther.mAppId &&
|
||||
mInBrowser == aOther.mInBrowser;
|
||||
}
|
||||
bool operator!=(const OriginAttributes& aOther) const
|
||||
{
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
// Serializes non-default values into the suffix format, i.e.
|
||||
// |!key1=value1&key2=value2|. If there are no non-default attributes, this
|
||||
// returns an empty string.
|
||||
void CreateSuffix(nsACString& aStr);
|
||||
|
||||
void Serialize(nsIObjectOutputStream* aStream) const;
|
||||
nsresult Deserialize(nsIObjectInputStream* aStream);
|
||||
};
|
||||
|
||||
/*
|
||||
* Base class from which all nsIPrincipal implementations inherit. Use this for
|
||||
* default implementations and other commonalities between principal
|
||||
@ -31,6 +62,8 @@ public:
|
||||
enum DocumentDomainConsideration { DontConsiderDocumentDomain, ConsiderDocumentDomain};
|
||||
bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration);
|
||||
|
||||
NS_IMETHOD GetOrigin(nsACString& aOrigin) final;
|
||||
NS_IMETHOD GetOriginNoSuffix(nsACString& aOrigin) final;
|
||||
NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval) final;
|
||||
NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval) final;
|
||||
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) final;
|
||||
@ -39,6 +72,9 @@ public:
|
||||
NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
|
||||
NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal) override;
|
||||
NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix) final;
|
||||
NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) final;
|
||||
NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
|
||||
NS_IMETHOD GetCookieJar(nsACString& aCookieJar) final;
|
||||
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) final;
|
||||
NS_IMETHOD GetAppId(uint32_t* aAppStatus) final;
|
||||
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement) final;
|
||||
@ -47,38 +83,16 @@ public:
|
||||
virtual bool IsOnCSSUnprefixingWhitelist() override { return false; }
|
||||
|
||||
static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
|
||||
|
||||
struct OriginAttributes {
|
||||
// NB: If you add any members here, you need to update Serialize/Deserialize
|
||||
// and bump the CIDs of all the principal implementations that invoke those
|
||||
// methods.
|
||||
uint32_t mAppId;
|
||||
bool mIsInBrowserElement;
|
||||
|
||||
OriginAttributes() : mAppId(nsIScriptSecurityManager::NO_APP_ID), mIsInBrowserElement(false) {}
|
||||
OriginAttributes(uint32_t aAppId, bool aIsInBrowserElement)
|
||||
: mAppId(aAppId), mIsInBrowserElement(aIsInBrowserElement) {}
|
||||
bool operator==(const OriginAttributes& aOther) const
|
||||
{
|
||||
return mAppId == aOther.mAppId &&
|
||||
mIsInBrowserElement == aOther.mIsInBrowserElement;
|
||||
}
|
||||
bool operator!=(const OriginAttributes& aOther) const
|
||||
{
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
void Serialize(nsIObjectOutputStream* aStream) const;
|
||||
nsresult Deserialize(nsIObjectInputStream* aStream);
|
||||
};
|
||||
static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(nsIURI* aURI, OriginAttributes& aAttrs);
|
||||
|
||||
const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
|
||||
uint32_t AppId() const { return mOriginAttributes.mAppId; }
|
||||
bool IsInBrowserElement() const { return mOriginAttributes.mIsInBrowserElement; }
|
||||
bool IsInBrowserElement() const { return mOriginAttributes.mInBrowser; }
|
||||
|
||||
protected:
|
||||
virtual ~BasePrincipal() {}
|
||||
|
||||
virtual nsresult GetOriginInternal(nsACString& aOrigin) = 0;
|
||||
virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider) = 0;
|
||||
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
|
||||
|
@ -20,7 +20,7 @@ interface nsIContentSecurityPolicy;
|
||||
[ptr] native JSPrincipals(JSPrincipals);
|
||||
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
|
||||
|
||||
[scriptable, builtinclass, uuid(7e024afa-afd4-48e7-ba11-1c7b9620b1b2)]
|
||||
[scriptable, builtinclass, uuid(749f21f5-8ade-4d0b-a590-2b1d18e890d5)]
|
||||
interface nsIPrincipal : nsISerializable
|
||||
{
|
||||
/**
|
||||
@ -65,15 +65,6 @@ interface nsIPrincipal : nsISerializable
|
||||
*/
|
||||
[noscript] attribute nsIURI domain;
|
||||
|
||||
/**
|
||||
* The origin of this principal's codebase URI.
|
||||
* An origin is defined as: scheme + host + port.
|
||||
*/
|
||||
// XXXcaa this should probably be turned into an nsIURI.
|
||||
// The system principal's origin should be some caps namespace
|
||||
// with a chrome URI. All of chrome should probably be the same.
|
||||
readonly attribute ACString origin;
|
||||
|
||||
/**
|
||||
* Returns whether the other principal is equal to or weaker than this
|
||||
* principal. Principals are equal if they are the same object or they
|
||||
@ -157,6 +148,79 @@ interface nsIPrincipal : nsISerializable
|
||||
*/
|
||||
readonly attribute AUTF8String jarPrefix;
|
||||
|
||||
/**
|
||||
* A dictionary of the non-default origin attributes associated with this
|
||||
* nsIPrincipal.
|
||||
*
|
||||
* Attributes are tokens that are taken into account when determining whether
|
||||
* two principals are same-origin - if any attributes differ, the principals
|
||||
* are cross-origin, even if the scheme, host, and port are the same.
|
||||
* Attributes should also be considered for all security and bucketing decisions,
|
||||
* even those which make non-standard comparisons (like cookies, which ignore
|
||||
* scheme, or quotas, which ignore subdomains).
|
||||
*
|
||||
* If you're looking for an easy-to-use canonical stringification of the origin
|
||||
* attributes, see |originSuffix| below.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval originAttributes;
|
||||
|
||||
/**
|
||||
* A canonical representation of the origin for this principal. This
|
||||
* consists of a base string (which, for codebase principals, is of the
|
||||
* format scheme://host:port), concatenated with |originAttributes| (see
|
||||
* below).
|
||||
*
|
||||
* We maintain the invariant that principalA.equals(principalB) if and only
|
||||
* if principalA.origin == principalB.origin.
|
||||
*/
|
||||
readonly attribute ACString origin;
|
||||
|
||||
/**
|
||||
* The base part of |origin| without the concatenation with |originSuffix|.
|
||||
* This doesn't have the important invariants described above with |origin|,
|
||||
* and as such should only be used for legacy situations.
|
||||
*/
|
||||
readonly attribute ACString originNoSuffix;
|
||||
|
||||
/**
|
||||
* A string of the form !key1=value1&key2=value2, where each pair represents
|
||||
* an attribute with a non-default value. If all attributes have default
|
||||
* values, this is the empty string.
|
||||
*
|
||||
* The value of .originSuffix is automatically serialized into .origin, so any
|
||||
* consumers using that are automatically origin-attribute-aware. Consumers with
|
||||
* special requirements must inspect and compare .originSuffix manually.
|
||||
*
|
||||
* originsuffix are intended to be a replacement for jarPrefix, which will
|
||||
* eventually be removed.
|
||||
*/
|
||||
readonly attribute AUTF8String originSuffix;
|
||||
|
||||
/**
|
||||
* Opaque string token representing the "cookie jar" associated with this
|
||||
* principal. Cookie jars are intended to be a tag associated with persistent
|
||||
* data (like cookies, localStorage data, etc) such that all data associated
|
||||
* with a given cookie jar can be quickly located and (for example) deleted.
|
||||
* Code from many origins may share a given cookie jar, so callers still need
|
||||
* to consult .origin (or equivalent) to compartmentalize data - the cookie
|
||||
* jar should _only_ be used as a tag in the manner described above.
|
||||
*
|
||||
* If two principals are in different cookie jars, they must be cross-origin.
|
||||
* As such, the information making up the cookie jar token must be contained
|
||||
* in the originAttributes (i.e. cookieJar must be a function of / derivable
|
||||
* from originAttributes). Long term, the intention is for the cookie jar
|
||||
* identifier to simply be an origin attribute. But we don't have that
|
||||
* attribute yet, and we also need to concatenate the appId and inBrowser
|
||||
* attributes until those go away.
|
||||
*
|
||||
* This getter is designed to hide these details from consumers so that they
|
||||
* don't need to be updated when we swap out the implementation. For that
|
||||
* reason, callers should treat the string as opaque and not rely on the
|
||||
* current format.
|
||||
*/
|
||||
readonly attribute ACString cookieJar;
|
||||
|
||||
/**
|
||||
* The base domain of the codebase URI to which this principal pertains
|
||||
* (generally the document URI), handling null principals and
|
||||
|
@ -26,7 +26,7 @@ class DomainPolicyClone;
|
||||
[ptr] native JSObjectPtr(JSObject);
|
||||
[ptr] native DomainPolicyClonePtr(mozilla::dom::DomainPolicyClone);
|
||||
|
||||
[scriptable, uuid(ba602ca6-dc7a-457e-a57a-ee5b343fd863)]
|
||||
[scriptable, uuid(f4c578b8-5bac-4ba1-9582-f1140e09a3b4)]
|
||||
interface nsIScriptSecurityManager : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -179,12 +179,28 @@ interface nsIScriptSecurityManager : nsISupports
|
||||
nsIPrincipal getNoAppCodebasePrincipal(in nsIURI uri);
|
||||
|
||||
/**
|
||||
* Legacy name for getNoAppCodebasePrincipal.
|
||||
* Legacy method for getting a principal with no origin attributes.
|
||||
*
|
||||
* @deprecated use getNoAppCodebasePrincipal instead.
|
||||
* @deprecated use createCodebasePrincipal instead.
|
||||
*/
|
||||
[deprecated] nsIPrincipal getCodebasePrincipal(in nsIURI uri);
|
||||
|
||||
/**
|
||||
* Returns a principal whose origin is composed of |uri| and |originAttributes|.
|
||||
* See nsIPrincipal.h for a description of origin attributes, and
|
||||
* SystemDictionaries.webidl for a list of origin attributes and their defaults.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
nsIPrincipal createCodebasePrincipal(in nsIURI uri, in jsval originAttributes);
|
||||
|
||||
/**
|
||||
* Returns a unique nonce principal with |originAttributes|.
|
||||
* See nsIPrincipal.h for a description of origin attributes, and
|
||||
* SystemDictionaries.webidl for a list of origin attributes and their defaults.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
nsIPrincipal createNullPrincipal(in jsval originAttributes);
|
||||
|
||||
/**
|
||||
* Returns OK if aSourceURI and target have the same "origin"
|
||||
* (scheme, host, and port).
|
||||
|
@ -102,8 +102,8 @@ nsNullPrincipal::SetDomain(nsIURI* aDomain)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetOrigin(nsACString& aOrigin)
|
||||
nsresult
|
||||
nsNullPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
{
|
||||
return mURI->GetSpec(aOrigin);
|
||||
}
|
||||
|
@ -44,19 +44,19 @@ public:
|
||||
NS_IMETHOD GetURI(nsIURI** aURI) override;
|
||||
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
|
||||
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
|
||||
NS_IMETHOD GetOrigin(nsACString& aOrigin) override;
|
||||
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) override;
|
||||
NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal) override;
|
||||
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
// Returns null on failure.
|
||||
static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIPrincipal *aInheritFrom);
|
||||
|
||||
// Returns null on failure.
|
||||
static already_AddRefed<nsNullPrincipal>
|
||||
Create(const OriginAttributes& aOriginAttributes = OriginAttributes());
|
||||
Create(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes());
|
||||
|
||||
nsresult Init(const OriginAttributes& aOriginAttributes = OriginAttributes());
|
||||
nsresult Init(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes());
|
||||
|
||||
virtual void GetScriptLocation(nsACString &aStr) override;
|
||||
|
||||
|
@ -149,8 +149,8 @@ nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetOrigin(nsACString& aOrigin)
|
||||
nsresult
|
||||
nsPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
{
|
||||
return GetOriginForURI(mCodebase, aOrigin);
|
||||
}
|
||||
@ -660,8 +660,8 @@ nsExpandedPrincipal::SetDomain(nsIURI* aDomain)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetOrigin(nsACString& aOrigin)
|
||||
nsresult
|
||||
nsExpandedPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
{
|
||||
aOrigin.AssignLiteral("[Expanded Principal [");
|
||||
for (size_t i = 0; i < mPrincipals.Length(); ++i) {
|
||||
|
@ -26,15 +26,15 @@ public:
|
||||
NS_IMETHOD GetURI(nsIURI** aURI) override;
|
||||
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
|
||||
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
|
||||
NS_IMETHOD GetOrigin(nsACString& aOrigin) override;
|
||||
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) override;
|
||||
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
|
||||
virtual bool IsOnCSSUnprefixingWhitelist() override;
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
nsPrincipal();
|
||||
|
||||
// Init() must be called before the principal is in a usable state.
|
||||
nsresult Init(nsIURI* aCodebase, const OriginAttributes& aOriginAttributes);
|
||||
nsresult Init(nsIURI* aCodebase, const mozilla::OriginAttributes& aOriginAttributes);
|
||||
|
||||
virtual void GetScriptLocation(nsACString& aStr) override;
|
||||
void SetURI(nsIURI* aURI);
|
||||
@ -94,11 +94,11 @@ public:
|
||||
NS_IMETHOD GetURI(nsIURI** aURI) override;
|
||||
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
|
||||
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
|
||||
NS_IMETHOD GetOrigin(nsACString& aOrigin) override;
|
||||
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) override;
|
||||
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
|
||||
virtual bool IsOnCSSUnprefixingWhitelist() override;
|
||||
virtual void GetScriptLocation(nsACString &aStr) override;
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsExpandedPrincipal();
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "nsINestedURI.h"
|
||||
#include "nspr.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "nsSystemPrincipal.h"
|
||||
#include "nsPrincipal.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
@ -280,29 +281,21 @@ nsScriptSecurityManager::AppStatusForPrincipal(nsIPrincipal *aPrin)
|
||||
NS_ENSURE_SUCCESS(app->GetAppStatus(&status),
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
|
||||
nsAutoCString origin;
|
||||
NS_ENSURE_SUCCESS(aPrin->GetOrigin(origin),
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
nsString appOrigin;
|
||||
NS_ENSURE_SUCCESS(app->GetOrigin(appOrigin),
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
|
||||
// We go from string -> nsIURI -> origin to be sure we
|
||||
// compare two punny-encoded origins.
|
||||
nsCOMPtr<nsIURI> appURI;
|
||||
NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(appURI), appOrigin),
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
|
||||
nsAutoCString appOriginPunned;
|
||||
NS_ENSURE_SUCCESS(nsPrincipal::GetOriginForURI(appURI, appOriginPunned),
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
|
||||
if (!appOriginPunned.Equals(origin)) {
|
||||
return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
// The app could contain a cross-origin iframe - make sure that the content
|
||||
// is actually same-origin with the app.
|
||||
MOZ_ASSERT(inMozBrowser == false, "Checked this above");
|
||||
OriginAttributes attrs(appId, false);
|
||||
nsCOMPtr<nsIPrincipal> appPrin = BasePrincipal::CreateCodebasePrincipal(appURI, attrs);
|
||||
NS_ENSURE_TRUE(appPrin, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
return aPrin->Equals(appPrin) ? status
|
||||
: nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -378,8 +371,10 @@ nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel,
|
||||
return GetLoadContextCodebasePrincipal(uri, loadContext, aPrincipal);
|
||||
}
|
||||
|
||||
return GetCodebasePrincipalInternal(uri, UNKNOWN_APP_ID,
|
||||
/* isInBrowserElement */ false, aPrincipal);
|
||||
OriginAttributes attrs(UNKNOWN_APP_ID, false);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -979,55 +974,24 @@ nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal **result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId,
|
||||
bool aInMozBrowser,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
// I _think_ it's safe to not create null principals here based on aURI.
|
||||
// At least all the callers would do the right thing in those cases, as far
|
||||
// as I can tell. --bz
|
||||
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
|
||||
if (uriPrinc) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||
if (!principal) {
|
||||
principal = nsNullPrincipal::Create();
|
||||
NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
principal.forget(result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
BasePrincipal::OriginAttributes attrs(aAppId, aInMozBrowser);
|
||||
nsRefPtr<nsPrincipal> codebase = new nsPrincipal();
|
||||
nsresult rv = codebase->Init(aURI, attrs);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
NS_ADDREF(*result = codebase);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetSimpleCodebasePrincipal(nsIURI* aURI,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
return GetCodebasePrincipalInternal(aURI,
|
||||
nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
false, aPrincipal);
|
||||
OriginAttributes attrs(UNKNOWN_APP_ID, false);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetNoAppCodebasePrincipal(nsIURI* aURI,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
return GetCodebasePrincipalInternal(aURI, nsIScriptSecurityManager::NO_APP_ID,
|
||||
false, aPrincipal);
|
||||
OriginAttributes attrs(NO_APP_ID, false);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1037,6 +1001,33 @@ nsScriptSecurityManager::GetCodebasePrincipal(nsIURI* aURI,
|
||||
return GetNoAppCodebasePrincipal(aURI, aPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, JS::Handle<JS::Value> aOriginAttributes,
|
||||
JSContext* aCx, nsIPrincipal** aPrincipal)
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CreateNullPrincipal(JS::Handle<JS::Value> aOriginAttributes,
|
||||
JSContext* aCx, nsIPrincipal** aPrincipal)
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsCOMPtr<nsIPrincipal> prin = nsNullPrincipal::Create(attrs);
|
||||
NS_ENSURE_TRUE(prin, NS_ERROR_FAILURE);
|
||||
prin.forget(aPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetAppCodebasePrincipal(nsIURI* aURI,
|
||||
uint32_t aAppId,
|
||||
@ -1046,7 +1037,10 @@ nsScriptSecurityManager::GetAppCodebasePrincipal(nsIURI* aURI,
|
||||
NS_ENSURE_TRUE(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
return GetCodebasePrincipalInternal(aURI, aAppId, aInMozBrowser, aPrincipal);
|
||||
OriginAttributes attrs(aAppId, aInMozBrowser);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1055,14 +1049,13 @@ nsScriptSecurityManager::
|
||||
nsILoadContext* aLoadContext,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
uint32_t appId;
|
||||
aLoadContext->GetAppId(&appId);
|
||||
bool isInBrowserElement;
|
||||
aLoadContext->GetIsInBrowserElement(&isInBrowserElement);
|
||||
return GetCodebasePrincipalInternal(aURI,
|
||||
appId,
|
||||
isInBrowserElement,
|
||||
aPrincipal);
|
||||
// XXXbholley - Make this more general in bug 1165466.
|
||||
OriginAttributes attrs;
|
||||
aLoadContext->GetAppId(&attrs.mAppId);
|
||||
aLoadContext->GetIsInBrowserElement(&attrs.mInBrowser);
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1070,37 +1063,11 @@ nsScriptSecurityManager::GetDocShellCodebasePrincipal(nsIURI* aURI,
|
||||
nsIDocShell* aDocShell,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
return GetCodebasePrincipalInternal(aURI,
|
||||
aDocShell->GetAppId(),
|
||||
aDocShell->GetIsInBrowserElement(),
|
||||
aPrincipal);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptSecurityManager::GetCodebasePrincipalInternal(nsIURI *aURI,
|
||||
uint32_t aAppId,
|
||||
bool aInMozBrowser,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
NS_ENSURE_ARG(aURI);
|
||||
|
||||
bool inheritsPrincipal;
|
||||
nsresult rv =
|
||||
NS_URIChainHasFlags(aURI,
|
||||
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
|
||||
&inheritsPrincipal);
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(rv) || inheritsPrincipal) {
|
||||
principal = nsNullPrincipal::Create();
|
||||
NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
|
||||
} else {
|
||||
rv = CreateCodebasePrincipal(aURI, aAppId, aInMozBrowser,
|
||||
getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
principal.forget(result);
|
||||
|
||||
return NS_OK;
|
||||
// XXXbholley - Make this more general in bug 1165466.
|
||||
OriginAttributes attrs(aDocShell->GetAppId(), aDocShell->GetIsInBrowserElement());
|
||||
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -22,6 +22,10 @@ class nsIIOService;
|
||||
class nsIStringBundle;
|
||||
class nsSystemPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
class OriginAttributes;
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
// nsScriptSecurityManager //
|
||||
/////////////////////////////
|
||||
@ -99,15 +103,6 @@ private:
|
||||
// should error out at that point.
|
||||
static nsIPrincipal* doGetObjectPrincipal(JSObject* obj);
|
||||
|
||||
nsresult
|
||||
GetCodebasePrincipalInternal(nsIURI* aURI, uint32_t aAppId,
|
||||
bool aInMozBrowser,
|
||||
nsIPrincipal** result);
|
||||
|
||||
nsresult
|
||||
CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId, bool aInMozBrowser,
|
||||
nsIPrincipal** result);
|
||||
|
||||
nsresult
|
||||
Init();
|
||||
|
||||
|
@ -61,8 +61,8 @@ nsSystemPrincipal::GetURI(nsIURI** aURI)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetOrigin(nsACString& aOrigin)
|
||||
nsresult
|
||||
nsSystemPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
{
|
||||
aOrigin.AssignLiteral(SYSTEM_PRINCIPAL_SPEC);
|
||||
return NS_OK;
|
||||
|
@ -29,11 +29,11 @@ public:
|
||||
NS_IMETHOD GetURI(nsIURI** aURI) override;
|
||||
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
|
||||
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
|
||||
NS_IMETHOD GetOrigin(nsACString& aOrigin) override;
|
||||
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) override;
|
||||
NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
|
||||
NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
|
||||
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
nsSystemPrincipal() {}
|
||||
|
||||
|
@ -1,14 +1,101 @@
|
||||
var Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/BrowserUtils.jsm");
|
||||
var ssm = Services.scriptSecurityManager;
|
||||
function makeURI(uri) { return Services.io.newURI(uri, null, null); }
|
||||
|
||||
function checkThrows(f) {
|
||||
var threw = false;
|
||||
try { f(); } catch (e) { threw = true }
|
||||
do_check_true(threw);
|
||||
}
|
||||
|
||||
function checkCrossOrigin(a, b) {
|
||||
do_check_false(a.equals(b));
|
||||
do_check_false(a.equalsConsideringDomain(b));
|
||||
do_check_false(a.subsumes(b));
|
||||
do_check_false(a.subsumesConsideringDomain(b));
|
||||
do_check_false(b.subsumes(a));
|
||||
do_check_false(b.subsumesConsideringDomain(a));
|
||||
do_check_eq(a.cookieJar === b.cookieJar,
|
||||
a.originAttributes.appId == b.originAttributes.appId &&
|
||||
a.originAttributes.inBrowser == b.originAttributes.inBrowser);
|
||||
}
|
||||
|
||||
function checkOriginAttributes(prin, appId, inBrowser, suffix) {
|
||||
do_check_eq(prin.originAttributes.appId, appId || 0);
|
||||
do_check_eq(prin.originAttributes.inBrowser, inBrowser || false);
|
||||
do_check_eq(prin.originSuffix, suffix || '');
|
||||
if (!prin.isNullPrincipal && !prin.origin.startsWith('[')) {
|
||||
do_check_true(BrowserUtils.principalFromOrigin(prin.origin).equals(prin));
|
||||
} else {
|
||||
checkThrows(() => BrowserUtils.principalFromOrigin(prin.origin));
|
||||
}
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_check_eq(Cu.getObjectPrincipal({}).origin, '[System Principal]');
|
||||
var exampleOrg = Cu.getObjectPrincipal(new Cu.Sandbox('http://example.org'));
|
||||
// Attributeless origins.
|
||||
do_check_eq(ssm.getSystemPrincipal().origin, '[System Principal]');
|
||||
checkOriginAttributes(ssm.getSystemPrincipal());
|
||||
var exampleOrg = ssm.createCodebasePrincipal(makeURI('http://example.org'), {});
|
||||
do_check_eq(exampleOrg.origin, 'http://example.org');
|
||||
var exampleCom = Cu.getObjectPrincipal(new Cu.Sandbox('https://www.example.com:123'));
|
||||
checkOriginAttributes(exampleOrg);
|
||||
var exampleCom = ssm.createCodebasePrincipal(makeURI('https://www.example.com:123'), {});
|
||||
do_check_eq(exampleCom.origin, 'https://www.example.com:123');
|
||||
checkOriginAttributes(exampleCom);
|
||||
var nullPrin = Cu.getObjectPrincipal(new Cu.Sandbox(null));
|
||||
do_check_true(/^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(nullPrin.origin));
|
||||
checkOriginAttributes(nullPrin);
|
||||
var ep = Cu.getObjectPrincipal(new Cu.Sandbox([exampleCom, nullPrin, exampleOrg]));
|
||||
checkOriginAttributes(ep);
|
||||
checkCrossOrigin(exampleCom, exampleOrg);
|
||||
checkCrossOrigin(exampleOrg, nullPrin);
|
||||
|
||||
// Origins should be in lexical order.
|
||||
// nsEP origins should be in lexical order.
|
||||
do_check_eq(ep.origin, `[Expanded Principal [${exampleOrg.origin}, ${exampleCom.origin}, ${nullPrin.origin}]]`);
|
||||
|
||||
// Make sure createCodebasePrincipal does what the rest of gecko does.
|
||||
do_check_true(exampleOrg.equals(Cu.getObjectPrincipal(new Cu.Sandbox('http://example.org'))));
|
||||
|
||||
//
|
||||
// Test origin attributes.
|
||||
//
|
||||
|
||||
// Just app.
|
||||
var exampleOrg_app = ssm.createCodebasePrincipal(makeURI('http://example.org'), {appId: 42});
|
||||
var nullPrin_app = ssm.createNullPrincipal({appId: 42});
|
||||
checkOriginAttributes(exampleOrg_app, 42, false, '!appId=42');
|
||||
checkOriginAttributes(nullPrin_app, 42, false, '!appId=42');
|
||||
do_check_eq(exampleOrg_app.origin, 'http://example.org!appId=42');
|
||||
|
||||
// Just browser.
|
||||
var exampleOrg_browser = ssm.createCodebasePrincipal(makeURI('http://example.org'), {inBrowser: true});
|
||||
var nullPrin_browser = ssm.createNullPrincipal({inBrowser: true});
|
||||
checkOriginAttributes(exampleOrg_browser, 0, true, '!inBrowser=1');
|
||||
checkOriginAttributes(nullPrin_browser, 0, true, '!inBrowser=1');
|
||||
do_check_eq(exampleOrg_browser.origin, 'http://example.org!inBrowser=1');
|
||||
|
||||
// App and browser.
|
||||
var exampleOrg_appBrowser = ssm.createCodebasePrincipal(makeURI('http://example.org'), {inBrowser: true, appId: 42});
|
||||
var nullPrin_appBrowser = ssm.createNullPrincipal({inBrowser: true, appId: 42});
|
||||
checkOriginAttributes(exampleOrg_appBrowser, 42, true, '!appId=42&inBrowser=1');
|
||||
checkOriginAttributes(nullPrin_appBrowser, 42, true, '!appId=42&inBrowser=1');
|
||||
do_check_eq(exampleOrg_appBrowser.origin, 'http://example.org!appId=42&inBrowser=1');
|
||||
|
||||
// App and browser, different domain.
|
||||
var exampleCom_appBrowser = ssm.createCodebasePrincipal(makeURI('https://www.example.com:123'), {appId: 42, inBrowser: true});
|
||||
checkOriginAttributes(exampleCom_appBrowser, 42, true, '!appId=42&inBrowser=1');
|
||||
do_check_eq(exampleCom_appBrowser.origin, 'https://www.example.com:123!appId=42&inBrowser=1');
|
||||
|
||||
// Check that all of the above are cross-origin.
|
||||
checkCrossOrigin(exampleOrg_app, exampleOrg);
|
||||
checkCrossOrigin(exampleOrg_app, nullPrin_app);
|
||||
checkCrossOrigin(exampleOrg_browser, exampleOrg_app);
|
||||
checkCrossOrigin(exampleOrg_browser, nullPrin_browser);
|
||||
checkCrossOrigin(exampleOrg_appBrowser, exampleOrg_app);
|
||||
checkCrossOrigin(exampleOrg_appBrowser, nullPrin_appBrowser);
|
||||
checkCrossOrigin(exampleOrg_appBrowser, exampleCom_appBrowser);
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
void *__dso_handle;
|
||||
|
||||
/* Begin all files as hidden visibility */
|
||||
#pragma GCC visibility push(hidden)
|
@ -1305,7 +1305,7 @@ ifndef MOZ_DEBUG
|
||||
endif
|
||||
endif
|
||||
@echo 'Packaging $(XPI_PKGNAME).xpi...'
|
||||
cd $(FINAL_TARGET) && $(ZIP) -qr ../$(XPI_PKGNAME).xpi *
|
||||
$(call py_action,zip,-C $(FINAL_TARGET) ../$(XPI_PKGNAME).xpi '*')
|
||||
endif
|
||||
|
||||
# See comment above about moving this out of the tools tier.
|
||||
|
52
configure.in
52
configure.in
@ -412,8 +412,18 @@ MOZ_TOOL_VARIABLES
|
||||
MOZ_CHECK_COMPILER_WRAPPER
|
||||
|
||||
MOZ_PATH_PROG(RUSTC, rustc)
|
||||
if test -n "$RUSTC"; then
|
||||
AC_MSG_CHECKING([rustc version])
|
||||
RUSTC_VERSION=`$RUSTC --version | cut -d ' ' -f 2`
|
||||
# Parse out semversion elements.
|
||||
_RUSTC_MAJOR_VERSION=`echo ${RUSTC_VERSION} | cut -d . -f 1`
|
||||
_RUSTC_MINOR_VERSION=`echo ${RUSTC_VERSION} | cut -d . -f 2`
|
||||
_RUSTC_EXTRA_VERSION=`echo ${RUSTC_VERSION} | cut -d . -f 3 | cut -d + -f 1`
|
||||
_RUSTC_PATCH_VERSION=`echo ${_RUSTC_EXTRA_VERSION} | cut -d '-' -f 1`
|
||||
AC_MSG_RESULT([$RUSTC_VERSION (v${_RUSTC_MAJOR_VERSION}.${_RUSTC_MINOR_VERSION}.${_RUSTC_PATCH_VERSION})])
|
||||
fi
|
||||
MOZ_ARG_ENABLE_BOOL([rust],
|
||||
[ --enable-rust Include rust language sources],
|
||||
[ --enable-rust Include rust language sources],
|
||||
[MOZ_RUST=1],
|
||||
[MOZ_RUST= ])
|
||||
if test -z "$RUSTC" -a -n "$MOZ_RUST"; then
|
||||
@ -421,6 +431,14 @@ if test -z "$RUSTC" -a -n "$MOZ_RUST"; then
|
||||
To compile rust language sources, you must have 'rustc' in your path.
|
||||
See http://www.rust-lang.org/ for more information.])
|
||||
fi
|
||||
if test -n "$MOZ_RUST" -a -z "$_RUSTC_MAJOR_VERSION" -o \
|
||||
"$_RUSTC_MAJOR_VERSION" -lt 1; then
|
||||
AC_MSG_ERROR([Rust compiler ${RUSTC_VERSION} is too old.
|
||||
To compile rust language sources please install at least
|
||||
version 1.0 of the 'rustc' toolchain and make sure it is
|
||||
first in your path.
|
||||
You can verify this by typing 'rustc --version'.])
|
||||
fi
|
||||
AC_SUBST(MOZ_RUST)
|
||||
|
||||
dnl ========================================================
|
||||
@ -447,6 +465,24 @@ esac
|
||||
|
||||
AC_SUBST(MACOSX_DEPLOYMENT_TARGET)
|
||||
|
||||
dnl ========================================================
|
||||
dnl Special MacOS X checks
|
||||
dnl ========================================================
|
||||
|
||||
if test -n "$MACOSX_DEPLOYMENT_TARGET" -a -n "$MOZ_RUST"; then
|
||||
AC_MSG_CHECKING([MacOS X compatibility with rust])
|
||||
# rustc doesn't support MacOS X 10.6 or earlier.
|
||||
# https://github.com/rust-lang/rust/issues/25342
|
||||
_MACOSX_TARGET_MINOR=`echo "$MACOSX_DEPLOYMENT_TARGET" | cut -d. -f2`
|
||||
if test "$_MACOSX_TARGET_MINOR" -lt 7; then
|
||||
AC_MSG_ERROR([rustc does not support MacOS X $MACOSX_DEPLOYMENT_TARGET
|
||||
Add 'ac_add_options --enable-macos-target=10.7' (or later)
|
||||
to mozconfig, or disable rust support.])
|
||||
else
|
||||
AC_MSG_RESULT([$MACOSX_DEPLOYMENT_TARGET is ok])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl Special win32 checks
|
||||
dnl ========================================================
|
||||
@ -2626,14 +2662,7 @@ if test "$GNU_CC" -a "$OS_TARGET" != WINNT; then
|
||||
VISIBILITY_FLAGS='-fvisibility=hidden'
|
||||
;;
|
||||
*)
|
||||
case $GCC_VERSION in
|
||||
4.6*)
|
||||
VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(MOZILLA_DIR)/config/gcc_hidden_dso_handle.h'
|
||||
;;
|
||||
*)
|
||||
VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(MOZILLA_DIR)/config/gcc_hidden.h'
|
||||
;;
|
||||
esac
|
||||
VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(MOZILLA_DIR)/config/gcc_hidden.h'
|
||||
WRAP_SYSTEM_INCLUDES=1
|
||||
;;
|
||||
esac
|
||||
@ -3904,6 +3933,7 @@ NSS_NO_LIBPKIX=
|
||||
MOZ_CONTENT_SANDBOX=
|
||||
MOZ_GMP_SANDBOX=
|
||||
MOZ_SANDBOX=1
|
||||
MOZ_BINARY_EXTENSIONS=
|
||||
|
||||
case "$target_os" in
|
||||
mingw*)
|
||||
@ -8523,6 +8553,10 @@ AC_SUBST(MOZ_POST_DSO_LIB_COMMAND)
|
||||
AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
|
||||
AC_SUBST(MOZ_LINKER_EXTRACT)
|
||||
|
||||
if test -n "$MOZ_BINARY_EXTENSIONS"; then
|
||||
AC_DEFINE(MOZ_BINARY_EXTENSIONS)
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_JSDOWNLOADS)
|
||||
if test -n "$MOZ_JSDOWNLOADS"; then
|
||||
AC_DEFINE(MOZ_JSDOWNLOADS)
|
||||
|
@ -929,6 +929,13 @@ BlobImplBase::SetMutable(bool aMutable)
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */ uint64_t
|
||||
BlobImplBase::NextSerialNumber()
|
||||
{
|
||||
static Atomic<uint64_t> nextSerialNumber;
|
||||
return nextSerialNumber++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// BlobImplFile implementation
|
||||
|
||||
|
@ -301,6 +301,14 @@ public:
|
||||
|
||||
virtual void GetType(nsAString& aType) = 0;
|
||||
|
||||
/**
|
||||
* An effectively-unique serial number identifying this instance of FileImpl.
|
||||
*
|
||||
* Implementations should obtain a serial number from
|
||||
* FileImplBase::NextSerialNumber().
|
||||
*/
|
||||
virtual uint64_t GetSerialNumber() const = 0;
|
||||
|
||||
already_AddRefed<BlobImpl>
|
||||
Slice(const Optional<int64_t>& aStart, const Optional<int64_t>& aEnd,
|
||||
const nsAString& aContentType, ErrorResult& aRv);
|
||||
@ -368,6 +376,7 @@ public:
|
||||
, mStart(0)
|
||||
, mLength(aLength)
|
||||
, mLastModificationDate(aLastModifiedDate)
|
||||
, mSerialNumber(NextSerialNumber())
|
||||
{
|
||||
// Ensure non-null mContentType by default
|
||||
mContentType.SetIsVoid(false);
|
||||
@ -382,6 +391,7 @@ public:
|
||||
, mStart(0)
|
||||
, mLength(aLength)
|
||||
, mLastModificationDate(INT64_MAX)
|
||||
, mSerialNumber(NextSerialNumber())
|
||||
{
|
||||
// Ensure non-null mContentType by default
|
||||
mContentType.SetIsVoid(false);
|
||||
@ -394,6 +404,7 @@ public:
|
||||
, mStart(0)
|
||||
, mLength(aLength)
|
||||
, mLastModificationDate(INT64_MAX)
|
||||
, mSerialNumber(NextSerialNumber())
|
||||
{
|
||||
// Ensure non-null mContentType by default
|
||||
mContentType.SetIsVoid(false);
|
||||
@ -407,6 +418,7 @@ public:
|
||||
, mStart(aStart)
|
||||
, mLength(aLength)
|
||||
, mLastModificationDate(INT64_MAX)
|
||||
, mSerialNumber(NextSerialNumber())
|
||||
{
|
||||
NS_ASSERTION(aLength != UINT64_MAX,
|
||||
"Must know length when creating slice");
|
||||
@ -434,6 +446,8 @@ public:
|
||||
|
||||
virtual void GetType(nsAString& aType) override;
|
||||
|
||||
virtual uint64_t GetSerialNumber() const override { return mSerialNumber; }
|
||||
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType, ErrorResult& aRv) override
|
||||
@ -521,6 +535,13 @@ public:
|
||||
protected:
|
||||
virtual ~BlobImplBase() {}
|
||||
|
||||
/**
|
||||
* Returns a new, effectively-unique serial number. This should be used
|
||||
* by implementations to obtain a serial number for GetSerialNumber().
|
||||
* The implementation is thread safe.
|
||||
*/
|
||||
static uint64_t NextSerialNumber();
|
||||
|
||||
indexedDB::FileInfo* GetFileInfo() const
|
||||
{
|
||||
NS_ASSERTION(IsStoredFile(), "Should only be called on stored files!");
|
||||
@ -541,6 +562,8 @@ protected:
|
||||
|
||||
int64_t mLastModificationDate;
|
||||
|
||||
const uint64_t mSerialNumber;
|
||||
|
||||
// Protected by IndexedDatabaseManager::FileMutex()
|
||||
nsTArray<nsRefPtr<indexedDB::FileInfo>> mFileInfos;
|
||||
};
|
||||
|
@ -3072,15 +3072,14 @@ nsDOMWindowUtils::SetContentDocumentFixedPositionMargins(float aTop, float aRigh
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
|
||||
const nsAString& aNewOrigin)
|
||||
nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||
NS_ENSURE_STATE(doc);
|
||||
|
||||
doc->RemoteFrameFullscreenChanged(aFrameElement, aNewOrigin);
|
||||
doc->RemoteFrameFullscreenChanged(aFrameElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1713,11 +1713,8 @@ nsDocument::~nsDocument()
|
||||
|
||||
// Kill the subdocument map, doing this will release its strong
|
||||
// references, if any.
|
||||
if (mSubDocuments) {
|
||||
PL_DHashTableDestroy(mSubDocuments);
|
||||
|
||||
mSubDocuments = nullptr;
|
||||
}
|
||||
delete mSubDocuments;
|
||||
mSubDocuments = nullptr;
|
||||
|
||||
// Destroy link map now so we don't waste time removing
|
||||
// links one by one
|
||||
@ -2121,10 +2118,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
tmp->mStyleSheetSetList = nullptr;
|
||||
}
|
||||
|
||||
if (tmp->mSubDocuments) {
|
||||
PL_DHashTableDestroy(tmp->mSubDocuments);
|
||||
tmp->mSubDocuments = nullptr;
|
||||
}
|
||||
delete tmp->mSubDocuments;
|
||||
tmp->mSubDocuments = nullptr;
|
||||
|
||||
tmp->mFrameRequestCallbacks.Clear();
|
||||
|
||||
@ -2320,11 +2315,8 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
|
||||
|
||||
// Delete references to sub-documents and kill the subdocument map,
|
||||
// if any. It holds strong references
|
||||
if (mSubDocuments) {
|
||||
PL_DHashTableDestroy(mSubDocuments);
|
||||
|
||||
mSubDocuments = nullptr;
|
||||
}
|
||||
delete mSubDocuments;
|
||||
mSubDocuments = nullptr;
|
||||
|
||||
// Destroy link map now so we don't waste time removing
|
||||
// links one by one
|
||||
@ -4005,7 +3997,7 @@ nsDocument::SetSubDocumentFor(Element* aElement, nsIDocument* aSubDoc)
|
||||
SubDocInitEntry
|
||||
};
|
||||
|
||||
mSubDocuments = PL_NewDHashTable(&hash_table_ops, sizeof(SubDocMapEntry));
|
||||
mSubDocuments = new PLDHashTable2(&hash_table_ops, sizeof(SubDocMapEntry));
|
||||
}
|
||||
|
||||
// Add a mapping to the hash table
|
||||
@ -11099,35 +11091,6 @@ nsIDocument::ExitFullscreen(nsIDocument* aDoc, bool aRunAsync)
|
||||
nsDocument::ExitFullscreen(aDoc);
|
||||
}
|
||||
|
||||
// Returns true if the document is a direct child of a cross process parent
|
||||
// mozbrowser iframe or TabParent. This is the case when the document has
|
||||
// a null parent and its DocShell reports that it is a browser frame, or
|
||||
// we can get a TabChild from it.
|
||||
static bool
|
||||
HasCrossProcessParent(nsIDocument* aDocument)
|
||||
{
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Content) {
|
||||
return false;
|
||||
}
|
||||
if (aDocument->GetParentDocument() != nullptr) {
|
||||
return false;
|
||||
}
|
||||
nsPIDOMWindow* win = aDocument->GetWindow();
|
||||
if (!win) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsIDocShell> docShell = win->GetDocShell();
|
||||
if (!docShell) {
|
||||
return false;
|
||||
}
|
||||
TabChild* tabChild(TabChild::GetFrom(docShell));
|
||||
if (!tabChild) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CountFullscreenSubDocuments(nsIDocument* aDoc, void* aData)
|
||||
{
|
||||
@ -11167,21 +11130,6 @@ ResetFullScreen(nsIDocument* aDocument, void* aData)
|
||||
NS_ASSERTION(!aDocument->IsFullScreenDoc(), "Should reset full-screen");
|
||||
nsTArray<nsIDocument*>* changed = reinterpret_cast<nsTArray<nsIDocument*>*>(aData);
|
||||
changed->AppendElement(aDocument);
|
||||
|
||||
if (HasCrossProcessParent(aDocument)) {
|
||||
// We're at the top of the content-process side doc tree. Ask the parent
|
||||
// process to exit fullscreen.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(aDocument, "ask-parent-to-exit-fullscreen", nullptr);
|
||||
}
|
||||
|
||||
// Dispatch a notification so that if this document has any
|
||||
// cross-process subdocuments, they'll be notified to exit fullscreen.
|
||||
// The BrowserElementParent listens for this event and performs the
|
||||
// cross process notification if it has a remote child process.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(aDocument, "ask-children-to-exit-fullscreen", nullptr);
|
||||
|
||||
aDocument->EnumerateSubDocuments(ResetFullScreen, aData);
|
||||
}
|
||||
return true;
|
||||
@ -11219,11 +11167,13 @@ ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
|
||||
NS_ASSERTION(!root->IsFullScreenDoc(),
|
||||
"Fullscreen root should no longer be a fullscreen doc...");
|
||||
|
||||
// Dispatch MozExitedDomFullscreen to the last document in
|
||||
// Dispatch MozDOMFullscreen:Exited to the last document in
|
||||
// the list since we want this event to follow the same path
|
||||
// MozEnteredDomFullscreen dispatched.
|
||||
nsRefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
|
||||
changed.LastElement(), NS_LITERAL_STRING("MozExitedDomFullscreen"), true, true);
|
||||
// MozDOMFullscreen:Entered dispatched.
|
||||
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||
new AsyncEventDispatcher(changed.LastElement(),
|
||||
NS_LITERAL_STRING("MozDOMFullscreen:Exited"),
|
||||
true, true);
|
||||
asyncDispatcher->PostDOMEvent();
|
||||
// Move the top-level window out of fullscreen mode.
|
||||
SetWindowFullScreen(root, false);
|
||||
@ -11303,12 +11253,6 @@ nsDocument::RestorePreviousFullScreenState()
|
||||
|
||||
nsCOMPtr<nsIDocument> fullScreenDoc = GetFullscreenLeaf(this);
|
||||
|
||||
// The fullscreen document may contain a <iframe mozbrowser> element which
|
||||
// has a cross process child. So send a notification so that its browser
|
||||
// parent will send a message to its child process to also exit fullscreen.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(fullScreenDoc, "ask-children-to-exit-fullscreen", nullptr);
|
||||
|
||||
// Clear full-screen stacks in all descendant in process documents, bottom up.
|
||||
nsIDocument* doc = fullScreenDoc;
|
||||
while (doc != this) {
|
||||
@ -11326,12 +11270,6 @@ nsDocument::RestorePreviousFullScreenState()
|
||||
UnlockPointer();
|
||||
DispatchFullScreenChange(doc);
|
||||
if (static_cast<nsDocument*>(doc)->mFullScreenStack.IsEmpty()) {
|
||||
if (HasCrossProcessParent(doc)) {
|
||||
// Send notification to the parent process to tell it to rollback to
|
||||
// the previous fullscreen elements in its fullscreen element stacks.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(doc, "ask-parent-to-rollback-fullscreen", nullptr);
|
||||
}
|
||||
// Full-screen stack in document is empty. Go back up to the parent
|
||||
// document. We'll pop the containing element off its stack, and use
|
||||
// its next full-screen element as the full-screen element.
|
||||
@ -11349,25 +11287,12 @@ nsDocument::RestorePreviousFullScreenState()
|
||||
(!nsContentUtils::IsSitePermAllow(doc->NodePrincipal(), "fullscreen") &&
|
||||
!static_cast<nsDocument*>(doc)->mIsApprovedForFullscreen)) {
|
||||
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||
new AsyncEventDispatcher(doc,
|
||||
NS_LITERAL_STRING("MozEnteredDomFullscreen"),
|
||||
true,
|
||||
true);
|
||||
new AsyncEventDispatcher(
|
||||
doc, NS_LITERAL_STRING("MozDOMFullscreen:NewOrigin"),
|
||||
/* Bubbles */ true, /* ChromeOnly */ true);
|
||||
asyncDispatcher->PostDOMEvent();
|
||||
}
|
||||
}
|
||||
|
||||
if (!nsContentUtils::HaveEqualPrincipals(doc, fullScreenDoc)) {
|
||||
// The origin which is fullscreen changed. Send a notification to
|
||||
// the root process so that a warning or approval UI can be shown
|
||||
// as necessary.
|
||||
nsAutoString origin;
|
||||
nsContentUtils::GetUTFOrigin(doc->NodePrincipal(), origin);
|
||||
nsIDocument* root = nsContentUtils::GetRootDocument(doc);
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(root, "fullscreen-origin-change", origin.get());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -11378,7 +11303,7 @@ nsDocument::RestorePreviousFullScreenState()
|
||||
NS_ASSERTION(!nsContentUtils::GetRootDocument(this)->IsFullScreenDoc(),
|
||||
"Should have cleared all docs' stacks");
|
||||
nsRefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
|
||||
this, NS_LITERAL_STRING("MozExitedDomFullscreen"), true, true);
|
||||
this, NS_LITERAL_STRING("MozDOMFullscreen:Exited"), true, true);
|
||||
asyncDispatcher->PostDOMEvent();
|
||||
SetWindowFullScreen(this, false);
|
||||
}
|
||||
@ -11630,32 +11555,17 @@ IsInActiveTab(nsIDocument* aDoc)
|
||||
return activeWindow == rootWin;
|
||||
}
|
||||
|
||||
nsresult nsDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
|
||||
const nsAString& aOrigin)
|
||||
nsresult nsDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
|
||||
{
|
||||
// Ensure the frame element is the fullscreen element in this document.
|
||||
// If the frame element is already the fullscreen element in this document,
|
||||
// this has no effect.
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aFrameElement));
|
||||
FullScreenOptions opts;
|
||||
RequestFullScreen(content->AsElement(),
|
||||
opts,
|
||||
RequestFullScreen(content->AsElement(), opts,
|
||||
/* aWasCallerChrome */ false,
|
||||
/* aNotifyOnOriginChange */ false);
|
||||
|
||||
// Origin changed in child process, send notifiction, so that chrome can
|
||||
// update the UI to reflect the fullscreen origin change if necessary.
|
||||
// The BrowserElementChild listens on this, and forwards it over its
|
||||
// parent process, where it is redispatched. Chrome (in the root process,
|
||||
// which could be *this* process) listens for this notification so that
|
||||
// it can show a warning or approval UI.
|
||||
if (!aOrigin.IsEmpty()) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(nsContentUtils::GetRootDocument(this),
|
||||
"fullscreen-origin-change",
|
||||
PromiseFlatString(aOrigin).get());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -11818,19 +11728,32 @@ nsDocument::RequestFullScreen(Element* aElement,
|
||||
nsContentUtils::IsSitePermAllow(NodePrincipal(), "fullscreen");
|
||||
}
|
||||
|
||||
// If this document, or a document with the same principal has not
|
||||
// already been approved for fullscreen this fullscreen-session, dispatch
|
||||
// an event so that chrome knows to pop up a warning/approval UI.
|
||||
// Note previousFullscreenDoc=nullptr upon first entry, so we always
|
||||
// take this path on the first time we enter fullscreen in a fullscreen
|
||||
// session.
|
||||
if (!mIsApprovedForFullscreen ||
|
||||
// If it is the first entry of the fullscreen, trigger an event so
|
||||
// that the UI can response to this change, e.g. hide chrome, or
|
||||
// notifying parent process to enter fullscreen. Note that chrome
|
||||
// code may also want to listen to MozDOMFullscreen:NewOrigin event
|
||||
// to pop up warning/approval UI.
|
||||
if (!previousFullscreenDoc) {
|
||||
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||
new AsyncEventDispatcher(
|
||||
this, NS_LITERAL_STRING("MozDOMFullscreen:Entered"),
|
||||
/* Bubbles */ true, /* ChromeOnly */ true);
|
||||
asyncDispatcher->PostDOMEvent();
|
||||
}
|
||||
|
||||
// The origin which is fullscreen gets changed. Trigger an event so
|
||||
// that the chrome knows to pop up a warning/approval UI. Note that
|
||||
// previousFullscreenDoc == nullptr upon first entry, so we always
|
||||
// take this path on the first entry. Also note that, in a multi-
|
||||
// process browser, the code in content process is responsible for
|
||||
// sending message with the origin to its parent, and the parent
|
||||
// shouldn't rely on this event itself.
|
||||
if (aNotifyOnOriginChange &&
|
||||
!nsContentUtils::HaveEqualPrincipals(previousFullscreenDoc, this)) {
|
||||
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||
new AsyncEventDispatcher(this,
|
||||
NS_LITERAL_STRING("MozEnteredDomFullscreen"),
|
||||
true,
|
||||
true);
|
||||
new AsyncEventDispatcher(
|
||||
this, NS_LITERAL_STRING("MozDOMFullscreen:NewOrigin"),
|
||||
/* Bubbles */ true, /* ChromeOnly */ true);
|
||||
asyncDispatcher->PostDOMEvent();
|
||||
}
|
||||
|
||||
@ -11847,21 +11770,6 @@ nsDocument::RequestFullScreen(Element* aElement,
|
||||
"GetMozFullScreenElement should match GetFullScreenElement()");
|
||||
#endif
|
||||
|
||||
// The origin which is fullscreen changed, send a notifiction so that the
|
||||
// root document knows the origin of the document which requested fullscreen.
|
||||
// This is used for the fullscreen approval UI. If we're in a child
|
||||
// process, the root BrowserElementChild listens for this notification,
|
||||
// and forwards it across to its BrowserElementParent, which
|
||||
// re-broadcasts the message for the root document in its process.
|
||||
if (aNotifyOnOriginChange &&
|
||||
!nsContentUtils::HaveEqualPrincipals(previousFullscreenDoc, this)) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
nsIDocument* root = nsContentUtils::GetRootDocument(this);
|
||||
nsAutoString origin;
|
||||
nsContentUtils::GetUTFOrigin(NodePrincipal(), origin);
|
||||
os->NotifyObservers(root, "fullscreen-origin-change", origin.get());
|
||||
}
|
||||
|
||||
// Make the window full-screen. Note we must make the state changes above
|
||||
// before making the window full-screen, as then the document reports as
|
||||
// being in full-screen mode when the chrome "fullscreen" event fires,
|
||||
|
@ -1179,8 +1179,8 @@ public:
|
||||
virtual bool IsFullscreenLeaf() override;
|
||||
virtual bool IsFullScreenDoc() override;
|
||||
virtual void SetApprovedForFullscreen(bool aIsApproved) override;
|
||||
virtual nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
|
||||
const nsAString& aNewOrigin) override;
|
||||
virtual nsresult
|
||||
RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement) override;
|
||||
|
||||
virtual nsresult RemoteFrameFullscreenReverted() override;
|
||||
virtual nsIDocument* GetFullscreenRoot() override;
|
||||
@ -1217,13 +1217,13 @@ public:
|
||||
// This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
|
||||
// to move this document into full-screen mode if allowed. aWasCallerChrome
|
||||
// should be true when nsIDocument::AsyncRequestFullScreen() was called
|
||||
// by chrome code. aNotifyOnOriginChange denotes whether we should send a
|
||||
// fullscreen-origin-change notification if requesting fullscreen in this
|
||||
// by chrome code. aNotifyOnOriginChange denotes whether we should trigger
|
||||
// a MozFullscreenOriginChanged event if requesting fullscreen in this
|
||||
// document causes the origin which is fullscreen to change. We may want to
|
||||
// *not* send this notification if we're calling RequestFullscreen() as part
|
||||
// *not* send this notification if we're calling RequestFullScreen() as part
|
||||
// of a continuation of a request in a subdocument, whereupon the caller will
|
||||
// need to send the notification with the origin of the document which
|
||||
// originally requested fullscreen, not *this* document's origin.
|
||||
// need to send some notification itself with the origin of the document
|
||||
// which originally requested fullscreen, not *this* document's origin.
|
||||
void RequestFullScreen(Element* aElement,
|
||||
mozilla::dom::FullScreenOptions& aOptions,
|
||||
bool aWasCallerChrome,
|
||||
@ -1518,7 +1518,7 @@ protected:
|
||||
|
||||
nsTArray<nsIObserver*> mCharSetObservers;
|
||||
|
||||
PLDHashTable *mSubDocuments;
|
||||
PLDHashTable2 *mSubDocuments;
|
||||
|
||||
// Array of owning references to all children
|
||||
nsAttrAndChildArray mChildren;
|
||||
|
@ -464,14 +464,19 @@ nsHostObjectProtocolHandler::Traverse(const nsACString& aUri,
|
||||
aCallback.NoteXPCOMChild(res->mObject);
|
||||
}
|
||||
|
||||
static nsISupports*
|
||||
GetDataObjectForSpec(const nsACString& aSpec)
|
||||
{
|
||||
DataInfo* info = GetDataInfo(aSpec);
|
||||
return info ? info->mObject : nullptr;
|
||||
}
|
||||
|
||||
static nsISupports*
|
||||
GetDataObject(nsIURI* aURI)
|
||||
{
|
||||
nsCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
|
||||
DataInfo* info = GetDataInfo(spec);
|
||||
return info ? info->mObject : nullptr;
|
||||
return GetDataObjectForSpec(spec);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
@ -647,6 +652,20 @@ NS_GetBlobForBlobURI(nsIURI* aURI, BlobImpl** aBlob)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_GetBlobForBlobURISpec(const nsACString& aSpec, BlobImpl** aBlob)
|
||||
{
|
||||
*aBlob = nullptr;
|
||||
|
||||
nsCOMPtr<BlobImpl> blob = do_QueryInterface(GetDataObjectForSpec(aSpec));
|
||||
if (!blob) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
blob.forget(aBlob);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
|
||||
{
|
||||
|
@ -124,6 +124,9 @@ inline bool IsFontTableURI(nsIURI* aUri)
|
||||
extern nsresult
|
||||
NS_GetBlobForBlobURI(nsIURI* aURI, mozilla::dom::BlobImpl** aBlob);
|
||||
|
||||
extern nsresult
|
||||
NS_GetBlobForBlobURISpec(const nsACString& aSpec, mozilla::dom::BlobImpl** aBlob);
|
||||
|
||||
extern nsresult
|
||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
|
||||
|
||||
|
@ -151,8 +151,8 @@ struct FullScreenOptions {
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x0b78eabe, 0x8b94, 0x4ea1, \
|
||||
{ 0x93, 0x31, 0x5d, 0x48, 0xe8, 0x3a, 0xda, 0x95 } }
|
||||
{ 0xdcfa30f2, 0x2197, 0x421f, \
|
||||
{ 0xa7, 0x5a, 0x3e, 0x70, 0x18, 0x08, 0xde, 0x81 } }
|
||||
|
||||
// Enum for requesting a particular type of document when creating a doc
|
||||
enum DocumentFlavor {
|
||||
@ -1094,11 +1094,10 @@ public:
|
||||
* Called when a frame in a child process has entered fullscreen or when a
|
||||
* fullscreen frame in a child process changes to another origin.
|
||||
* aFrameElement is the frame element which contains the child-process
|
||||
* fullscreen document, and aNewOrigin is the origin of the new fullscreen
|
||||
* document.
|
||||
* fullscreen document.
|
||||
*/
|
||||
virtual nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
|
||||
const nsAString& aNewOrigin) = 0;
|
||||
virtual nsresult
|
||||
RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement) = 0;
|
||||
|
||||
/**
|
||||
* Called when a frame in a remote child document has rolled back fullscreen
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||
|
||||
nsCOMPtr<nsIAtom> mName; // property name
|
||||
PLDHashTable mObjectValueMap; // map of object/value pairs
|
||||
PLDHashTable2 mObjectValueMap; // map of object/value pairs
|
||||
NSPropertyDtorFunc mDtorFunc; // property specific value dtor function
|
||||
void* mDtorData; // pointer to pass to dtor
|
||||
bool mTransfer; // whether to transfer in
|
||||
@ -287,21 +287,18 @@ nsPropertyTable::PropertyList::PropertyList(nsIAtom *aName,
|
||||
void *aDtorData,
|
||||
bool aTransfer)
|
||||
: mName(aName),
|
||||
mObjectValueMap(PL_DHashGetStubOps(), sizeof(PropertyListMapEntry)),
|
||||
mDtorFunc(aDtorFunc),
|
||||
mDtorData(aDtorData),
|
||||
mTransfer(aTransfer),
|
||||
mNext(nullptr)
|
||||
{
|
||||
PL_DHashTableInit(&mObjectValueMap, PL_DHashGetStubOps(),
|
||||
sizeof(PropertyListMapEntry));
|
||||
}
|
||||
|
||||
nsPropertyTable::PropertyList::~PropertyList()
|
||||
{
|
||||
PL_DHashTableFinish(&mObjectValueMap);
|
||||
}
|
||||
|
||||
|
||||
static PLDHashOperator
|
||||
DestroyPropertyEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
||||
uint32_t number, void *arg)
|
||||
|
@ -1856,9 +1856,7 @@ nsXMLHttpRequest::StreamReaderFunc(nsIInputStream* in,
|
||||
} else if (xmlHttpRequest->mResponseType == XML_HTTP_RESPONSE_TYPE_DEFAULT &&
|
||||
xmlHttpRequest->mResponseXML) {
|
||||
// Copy for our own use
|
||||
uint32_t previousLength = xmlHttpRequest->mResponseBody.Length();
|
||||
xmlHttpRequest->mResponseBody.Append(fromRawSegment,count);
|
||||
if (count > 0 && xmlHttpRequest->mResponseBody.Length() == previousLength) {
|
||||
if (!xmlHttpRequest->mResponseBody.Append(fromRawSegment, count, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else if (xmlHttpRequest->mResponseType == XML_HTTP_RESPONSE_TYPE_DEFAULT ||
|
||||
|
@ -640,6 +640,8 @@ BluetoothHALInterface::GetRemoteDeviceProperty(
|
||||
|
||||
if (NS_SUCCEEDED(Convert(aRemoteAddr, remoteAddr)) &&
|
||||
false /* TODO: we don't support any values for aName currently */) {
|
||||
// silence uninitialized variable warning for |name|
|
||||
name = static_cast<bt_property_type_t>(0);
|
||||
status = mInterface->get_remote_device_property(&remoteAddr, name);
|
||||
} else {
|
||||
status = BT_STATUS_PARM_INVALID;
|
||||
|
@ -983,7 +983,7 @@ BluetoothAdapter::IsBluetoothCertifiedApp()
|
||||
nsAutoCString appOrigin;
|
||||
|
||||
doc->NodePrincipal()->GetAppStatus(&appStatus);
|
||||
doc->NodePrincipal()->GetOrigin(appOrigin);
|
||||
doc->NodePrincipal()->GetOriginNoSuffix(appOrigin);
|
||||
|
||||
return appStatus == nsIPrincipal::APP_STATUS_CERTIFIED &&
|
||||
appOrigin.EqualsLiteral(BLUETOOTH_APP_ORIGIN);
|
||||
|
@ -50,9 +50,6 @@ function sendSyncMsg(msg, data) {
|
||||
let CERTIFICATE_ERROR_PAGE_PREF = 'security.alternate_certificate_error_page';
|
||||
|
||||
const OBSERVED_EVENTS = [
|
||||
'fullscreen-origin-change',
|
||||
'ask-parent-to-exit-fullscreen',
|
||||
'ask-parent-to-rollback-fullscreen',
|
||||
'xpcom-shutdown',
|
||||
'activity-done'
|
||||
];
|
||||
@ -147,6 +144,21 @@ BrowserElementChild.prototype = {
|
||||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false);
|
||||
|
||||
addEventListener("MozDOMFullscreen:Entered",
|
||||
this._mozEnteredDomFullscreen.bind(this),
|
||||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false);
|
||||
|
||||
addEventListener("MozDOMFullscreen:NewOrigin",
|
||||
this._mozFullscreenOriginChange.bind(this),
|
||||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false);
|
||||
|
||||
addEventListener("MozDOMFullscreen:Exited",
|
||||
this._mozExitedDomFullscreen.bind(this),
|
||||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false);
|
||||
|
||||
addEventListener('DOMMetaAdded',
|
||||
this._metaChangedHandler.bind(this),
|
||||
/* useCapture = */ true,
|
||||
@ -259,15 +271,6 @@ BrowserElementChild.prototype = {
|
||||
if (topic == 'activity-done' && docShell !== subject)
|
||||
return;
|
||||
switch (topic) {
|
||||
case 'fullscreen-origin-change':
|
||||
sendAsyncMsg('fullscreen-origin-change', { _payload_: data });
|
||||
break;
|
||||
case 'ask-parent-to-exit-fullscreen':
|
||||
sendAsyncMsg('exit-fullscreen');
|
||||
break;
|
||||
case 'ask-parent-to-rollback-fullscreen':
|
||||
sendAsyncMsg('rollback-fullscreen');
|
||||
break;
|
||||
case 'activity-done':
|
||||
sendAsyncMsg('activitydone', { success: (data == 'activity-success') });
|
||||
break;
|
||||
@ -956,6 +959,20 @@ BrowserElementChild.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
_mozEnteredDomFullscreen: function(e) {
|
||||
sendAsyncMsg("entered-dom-fullscreen");
|
||||
},
|
||||
|
||||
_mozFullscreenOriginChange: function(e) {
|
||||
sendAsyncMsg("fullscreen-origin-change", {
|
||||
origin: e.target.nodePrincipal.origin
|
||||
});
|
||||
},
|
||||
|
||||
_mozExitedDomFullscreen: function(e) {
|
||||
sendAsyncMsg("exited-dom-fullscreen");
|
||||
},
|
||||
|
||||
_getContentDimensions: function() {
|
||||
return {
|
||||
width: content.document.body.scrollWidth,
|
||||
|
@ -85,7 +85,6 @@ function BrowserElementParent() {
|
||||
this._pendingSetInputMethodActive = [];
|
||||
this._nextPaintListeners = [];
|
||||
|
||||
Services.obs.addObserver(this, 'ask-children-to-exit-fullscreen', /* ownsWeak = */ true);
|
||||
Services.obs.addObserver(this, 'oop-frameloader-crashed', /* ownsWeak = */ true);
|
||||
Services.obs.addObserver(this, 'copypaste-docommand', /* ownsWeak = */ true);
|
||||
}
|
||||
@ -130,6 +129,11 @@ BrowserElementParent.prototype = {
|
||||
BrowserElementPromptService.mapFrameToBrowserElementParent(this._frameElement, this);
|
||||
this._setupMessageListener();
|
||||
this._registerAppManifest();
|
||||
|
||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Ci.nsIEventListenerService);
|
||||
els.addSystemEventListener(this._window.document, "mozfullscreenchange",
|
||||
this._fullscreenChange.bind(this), true);
|
||||
},
|
||||
|
||||
_runPendingAPICall: function() {
|
||||
@ -191,9 +195,9 @@ BrowserElementParent.prototype = {
|
||||
"got-contentdimensions": this._gotDOMRequestResult,
|
||||
"got-can-go-back": this._gotDOMRequestResult,
|
||||
"got-can-go-forward": this._gotDOMRequestResult,
|
||||
"fullscreen-origin-change": this._remoteFullscreenOriginChange,
|
||||
"rollback-fullscreen": this._remoteFrameFullscreenReverted,
|
||||
"exit-fullscreen": this._exitFullscreen,
|
||||
"entered-dom-fullscreen": this._enteredDomFullscreen,
|
||||
"fullscreen-origin-change": this._fullscreenOriginChange,
|
||||
"exited-dom-fullscreen": this._exitedDomFullscreen,
|
||||
"got-visible": this._gotDOMRequestResult,
|
||||
"visibilitychange": this._childVisibilityChange,
|
||||
"got-set-input-method-active": this._gotDOMRequestResult,
|
||||
@ -936,19 +940,27 @@ BrowserElementParent.prototype = {
|
||||
this._fireEventFromMsg(data);
|
||||
},
|
||||
|
||||
_exitFullscreen: function() {
|
||||
this._windowUtils.exitFullscreen();
|
||||
_enteredDomFullscreen: function() {
|
||||
this._windowUtils.remoteFrameFullscreenChanged(this._frameElement);
|
||||
},
|
||||
|
||||
_remoteFullscreenOriginChange: function(data) {
|
||||
let origin = data.json._payload_;
|
||||
this._windowUtils.remoteFrameFullscreenChanged(this._frameElement, origin);
|
||||
_fullscreenOriginChange: function(data) {
|
||||
Services.obs.notifyObservers(
|
||||
this._frameElement, "fullscreen-origin-change", data.json.origin);
|
||||
},
|
||||
|
||||
_remoteFrameFullscreenReverted: function(data) {
|
||||
_exitedDomFullscreen: function(data) {
|
||||
this._windowUtils.remoteFrameFullscreenReverted();
|
||||
},
|
||||
|
||||
_fullscreenChange: function(evt) {
|
||||
if (this._isAlive() && evt.target == this._window.document) {
|
||||
if (!this._window.document.mozFullScreen) {
|
||||
this._sendAsyncMsg("exit-fullscreen");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_fireFatalError: function() {
|
||||
let evt = this._createEvent('error', {type: 'fatal'},
|
||||
/* cancelable = */ false);
|
||||
@ -962,13 +974,6 @@ BrowserElementParent.prototype = {
|
||||
this._fireFatalError();
|
||||
}
|
||||
break;
|
||||
case 'ask-children-to-exit-fullscreen':
|
||||
if (this._isAlive() &&
|
||||
this._frameElement.ownerDocument == subject &&
|
||||
this._frameLoader.QueryInterface(Ci.nsIFrameLoader).tabParent) {
|
||||
this._sendAsyncMsg('exit-fullscreen');
|
||||
}
|
||||
break;
|
||||
case 'copypaste-docommand':
|
||||
if (this._isAlive() && this._frameElement.isEqualNode(subject.wrappedJSObject)) {
|
||||
this._sendAsyncMsg('do-command', { command: data });
|
||||
|
2
dom/cache/ManagerId.cpp
vendored
2
dom/cache/ManagerId.cpp
vendored
@ -33,7 +33,7 @@ ManagerId::Create(nsIPrincipal* aPrincipal, ManagerId** aManagerIdOut)
|
||||
// TODO: consider using QuotaManager's modified origin here (bug 1112071)
|
||||
|
||||
nsAutoCString origin;
|
||||
nsresult rv = aPrincipal->GetOrigin(origin);
|
||||
nsresult rv = aPrincipal->GetOriginNoSuffix(origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
uint32_t appId;
|
||||
|
2
dom/cache/PrincipalVerifier.cpp
vendored
2
dom/cache/PrincipalVerifier.cpp
vendored
@ -150,7 +150,7 @@ PrincipalVerifier::VerifyOnMainThread()
|
||||
// is a synthetic [System Principal] string.
|
||||
if (!ssm->IsSystemPrincipal(principal)) {
|
||||
nsAutoCString origin;
|
||||
rv = principal->GetOrigin(origin);
|
||||
rv = principal->GetOriginNoSuffix(origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
DispatchToInitiatingThread(rv);
|
||||
return;
|
||||
|
@ -146,14 +146,7 @@ this.DataStoreChangeNotifier = {
|
||||
|
||||
// No check has to be done when the message is 'child-process-shutdown'.
|
||||
if (aMessage.name != "child-process-shutdown") {
|
||||
if (!("principal" in aMessage)) {
|
||||
return;
|
||||
}
|
||||
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager);
|
||||
let uri = Services.io.newURI(aMessage.principal.origin, null, null);
|
||||
let principal = secMan.getAppCodebasePrincipal(uri,
|
||||
aMessage.principal.appId, aMessage.principal.isInBrowserElement);
|
||||
let principal = aMessage.principal;
|
||||
if (!principal || !dataStoreService.checkPermission(principal)) {
|
||||
return;
|
||||
}
|
||||
|
@ -92,8 +92,12 @@ function testScriptInitiatedKeyEvents() {
|
||||
|
||||
function testNextKey() {
|
||||
if (!document.mozFullScreen) {
|
||||
addFullscreenChangeContinuation("enter", reallyTestNextKey);
|
||||
document.body.mozRequestFullScreen();
|
||||
// Async request fullscreen to avoid the request be accidentally
|
||||
// cancelled due to unfinished clean-up of exiting fullscreen.
|
||||
setTimeout(() => {
|
||||
addFullscreenChangeContinuation("enter", reallyTestNextKey);
|
||||
document.body.mozRequestFullScreen();
|
||||
}, 0);
|
||||
}
|
||||
else {
|
||||
reallyTestNextKey();
|
||||
|
@ -20,23 +20,6 @@ function inNormalMode() {
|
||||
window.outerHeight == normalSize.h;
|
||||
}
|
||||
|
||||
function ok(condition, msg) {
|
||||
opener.ok(condition, "[rollback] " + msg);
|
||||
if (!condition) {
|
||||
opener.finish();
|
||||
}
|
||||
}
|
||||
|
||||
// On Linux we sometimes receive fullscreenchange events before the window
|
||||
// has finished transitioning to fullscreen. This can cause problems and
|
||||
// test failures, so work around it on Linux until we can get a proper fix.
|
||||
const workAroundFullscreenTransition = navigator.userAgent.indexOf("Linux") != -1;
|
||||
|
||||
if (workAroundFullscreenTransition) {
|
||||
SimpleTest.requestFlakyTimeout("We need to wait an arbitrary and non-zero " +
|
||||
"amount of time in case of the Linux specific workaround to avoid busy-waiting.");
|
||||
}
|
||||
|
||||
// Adds a listener that will be called once a fullscreen transition
|
||||
// is complete. When type==='enter', callback is called when we've
|
||||
// received a fullscreenchange event, and the fullscreen transition is
|
||||
@ -48,53 +31,39 @@ if (workAroundFullscreenTransition) {
|
||||
// the current document.
|
||||
function addFullscreenChangeContinuation(type, callback, inDoc) {
|
||||
var doc = inDoc || document;
|
||||
var listener = null;
|
||||
if (type === "enter") {
|
||||
// when entering fullscreen, ensure we don't call 'callback' until the
|
||||
// enter transition is complete.
|
||||
listener = function(event) {
|
||||
doc.removeEventListener("mozfullscreenchange", listener, false);
|
||||
if (!workAroundFullscreenTransition) {
|
||||
callback(event);
|
||||
return;
|
||||
}
|
||||
if (!inFullscreenMode()) {
|
||||
opener.todo(false, "fullscreenchange before entering fullscreen complete! " +
|
||||
" window.fullScreen=" + window.fullScreen +
|
||||
" normal=(" + normalSize.w + "," + normalSize.h + ")" +
|
||||
" outerWidth=" + window.outerWidth + " width=" + window.screen.width +
|
||||
" outerHeight=" + window.outerHeight + " height=" + window.screen.height);
|
||||
setTimeout(function(){listener(event);}, 100);
|
||||
return;
|
||||
}
|
||||
setTimeout(function(){callback(event)}, 0);
|
||||
};
|
||||
} else if (type === "exit") {
|
||||
listener = function(event) {
|
||||
doc.removeEventListener("mozfullscreenchange", listener, false);
|
||||
if (!workAroundFullscreenTransition) {
|
||||
callback(event);
|
||||
return;
|
||||
}
|
||||
if (!document.mozFullScreenElement && !inNormalMode()) {
|
||||
opener.todo(false, "fullscreenchange before exiting fullscreen complete! " +
|
||||
" window.fullScreen=" + window.fullScreen +
|
||||
" normal=(" + normalSize.w + "," + normalSize.h + ")" +
|
||||
" outerWidth=" + window.outerWidth + " width=" + window.screen.width +
|
||||
" outerHeight=" + window.outerHeight + " height=" + window.screen.height);
|
||||
// 'document' (*not* 'doc') has no fullscreen element, so we're trying
|
||||
// to completely exit fullscreen mode. Wait until the transition
|
||||
// to normal mode is complete before calling callback.
|
||||
setTimeout(function(){listener(event);}, 100);
|
||||
return;
|
||||
}
|
||||
opener.info("[rollback] Exited fullscreen");
|
||||
setTimeout(function(){callback(event);}, 0);
|
||||
};
|
||||
} else {
|
||||
throw "'type' must be either 'enter', or 'exit'.";
|
||||
function checkCondition() {
|
||||
if (type == "enter") {
|
||||
return inFullscreenMode();
|
||||
} else if (type == "exit") {
|
||||
// If we just revert the state to a previous fullscreen state,
|
||||
// the window won't back to the normal mode. Hence we check
|
||||
// mozFullScreenElement first here.
|
||||
return doc.mozFullScreenElement || inNormalMode();
|
||||
} else {
|
||||
throw "'type' must be either 'enter', or 'exit'.";
|
||||
}
|
||||
}
|
||||
doc.addEventListener("mozfullscreenchange", listener, false);
|
||||
function invokeCallback(event) {
|
||||
// Use async call after a paint to workaround unfinished fullscreen
|
||||
// change even when the window size has changed on Linux.
|
||||
requestAnimationFrame(() => setTimeout(() => callback(event), 0), 0);
|
||||
}
|
||||
function onFullscreenChange(event) {
|
||||
doc.removeEventListener("mozfullscreenchange", onFullscreenChange, false);
|
||||
if (checkCondition()) {
|
||||
invokeCallback(event);
|
||||
return;
|
||||
}
|
||||
var win = doc.defaultView;
|
||||
function onResize() {
|
||||
if (checkCondition()) {
|
||||
win.removeEventListener("resize", onResize, false);
|
||||
invokeCallback(event);
|
||||
}
|
||||
}
|
||||
win.addEventListener("resize", onResize, false);
|
||||
}
|
||||
doc.addEventListener("mozfullscreenchange", onFullscreenChange, false);
|
||||
}
|
||||
|
||||
// Calls |callback| when the next fullscreenerror is dispatched to inDoc||document.
|
||||
|
@ -52,6 +52,10 @@ const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
|
||||
const isOSXMtnLion = navigator.userAgent.indexOf("Mac OS X 10.8") != -1;
|
||||
const isOSXYosemite = navigator.userAgent.indexOf("Mac OS X 10.10") != -1;
|
||||
|
||||
function finish() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function nextTest() {
|
||||
if (isWinXP) {
|
||||
todo(false, "Can't reliably run full-screen tests on Windows XP due to bug 704010");
|
||||
@ -73,6 +77,7 @@ function nextTest() {
|
||||
|
||||
function runNextTest() {
|
||||
if (gTestIndex < gTestWindows.length) {
|
||||
info("Run test " + gTestWindows[gTestIndex]);
|
||||
testWindow = window.open(gTestWindows[gTestIndex], "", "width=500,height=500");
|
||||
// We'll wait for the window to load, then make sure our window is refocused
|
||||
// before starting the test, which will get kicked off on "focus".
|
||||
|
@ -277,14 +277,9 @@ this.DOMIdentity = {
|
||||
if (!aMessage.principal) {
|
||||
return false;
|
||||
}
|
||||
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager);
|
||||
let uri = Services.io.newURI(aMessage.principal.origin, null, null);
|
||||
let principal = secMan.getAppCodebasePrincipal(uri,
|
||||
aMessage.principal.appId, aMessage.principal.isInBrowserElement);
|
||||
|
||||
let permission =
|
||||
permissionManager.testPermissionFromPrincipal(principal,
|
||||
permissionManager.testPermissionFromPrincipal(aMessage.principal,
|
||||
FXA_PERMISSION);
|
||||
return permission != Ci.nsIPermissionManager.UNKNOWN_ACTION &&
|
||||
permission != Ci.nsIPermissionManager.DENY_ACTION;
|
||||
|
@ -49,7 +49,7 @@ interface nsIJSRAIIHelper;
|
||||
interface nsIContentPermissionRequest;
|
||||
interface nsIObserver;
|
||||
|
||||
[scriptable, uuid(34a42cdc-7a04-4e71-8a5c-63e092fba58e)]
|
||||
[scriptable, uuid(0ce789cc-3fb6-48b8-a58e-32deefc337b4)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -1183,11 +1183,9 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
* Called when the remote child frame has changed its fullscreen state,
|
||||
* when entering fullscreen, and when the origin which is fullscreen changes.
|
||||
* aFrameElement is the iframe element which contains the child-process
|
||||
* fullscreen document, and aNewOrigin is the origin of the new fullscreen
|
||||
* document.
|
||||
* fullscreen document.
|
||||
*/
|
||||
void remoteFrameFullscreenChanged(in nsIDOMElement aFrameElement,
|
||||
in AString aNewOrigin);
|
||||
void remoteFrameFullscreenChanged(in nsIDOMElement aFrameElement);
|
||||
|
||||
/**
|
||||
* Called when the remote frame has popped all fullscreen elements off its
|
||||
|
@ -2089,6 +2089,9 @@ public:
|
||||
virtual void
|
||||
GetType(nsAString& aType) override;
|
||||
|
||||
virtual uint64_t
|
||||
GetSerialNumber() const override;
|
||||
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart,
|
||||
uint64_t aLength,
|
||||
@ -2797,6 +2800,13 @@ RemoteBlobImpl::GetType(nsAString& aType)
|
||||
mBlobImpl->GetType(aType);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
BlobParent::
|
||||
RemoteBlobImpl::GetSerialNumber() const
|
||||
{
|
||||
return mBlobImpl->GetSerialNumber();
|
||||
}
|
||||
|
||||
already_AddRefed<BlobImpl>
|
||||
BlobParent::
|
||||
RemoteBlobImpl::CreateSlice(uint64_t aStart,
|
||||
|
@ -273,7 +273,9 @@ public:
|
||||
return ((*aData)[4] == 'm' && (*aData)[5] == 'o' && (*aData)[6] == 'o' &&
|
||||
(*aData)[7] == 'f') ||
|
||||
((*aData)[4] == 's' && (*aData)[5] == 't' && (*aData)[6] == 'y' &&
|
||||
(*aData)[7] == 'p');
|
||||
(*aData)[7] == 'p') ||
|
||||
((*aData)[4] == 's' && (*aData)[5] == 'i' && (*aData)[6] == 'd' &&
|
||||
(*aData)[7] == 'x');
|
||||
}
|
||||
|
||||
bool ParseStartAndEndTimestamps(MediaLargeByteBuffer* aData,
|
||||
|
@ -2636,7 +2636,7 @@ QuotaManager::GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
|
||||
}
|
||||
|
||||
nsCString origin;
|
||||
rv = aPrincipal->GetOrigin(origin);
|
||||
rv = aPrincipal->GetOriginNoSuffix(origin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (origin.EqualsLiteral(kChromeOrigin)) {
|
||||
|
@ -209,7 +209,7 @@ this.RequestSyncService = {
|
||||
principalToKey: function(aPrincipal) {
|
||||
return aPrincipal.appId + '|' +
|
||||
aPrincipal.isInBrowserElement + '|' +
|
||||
aPrincipal.origin;
|
||||
aPrincipal.originNoSuffix;
|
||||
},
|
||||
|
||||
// Add a task to the _registrations map and create the timer if it's needed.
|
||||
@ -287,20 +287,7 @@ this.RequestSyncService = {
|
||||
}
|
||||
|
||||
// The principal is used to validate the message.
|
||||
if (!aMessage.principal) {
|
||||
return;
|
||||
}
|
||||
|
||||
let uri = Services.io.newURI(aMessage.principal.origin, null, null);
|
||||
|
||||
let principal;
|
||||
try {
|
||||
principal = secMan.getAppCodebasePrincipal(uri,
|
||||
aMessage.principal.appId, aMessage.principal.isInBrowserElement);
|
||||
} catch(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
let principal = aMessage.principal;
|
||||
if (!principal) {
|
||||
return;
|
||||
}
|
||||
@ -398,7 +385,7 @@ this.RequestSyncService = {
|
||||
let dbKey = aData.task + "|" +
|
||||
aPrincipal.appId + '|' +
|
||||
aPrincipal.isInBrowserElement + '|' +
|
||||
aPrincipal.origin;
|
||||
aPrincipal.originNoSuffix;
|
||||
|
||||
let data = { principal: aPrincipal,
|
||||
dbKey: dbKey,
|
||||
@ -514,7 +501,7 @@ this.RequestSyncService = {
|
||||
}
|
||||
|
||||
if (aObj.principal.isInBrowserElement != aData.isInBrowserElement ||
|
||||
aObj.principal.origin != aData.origin) {
|
||||
aObj.principal.originNoSuffix != aData.origin) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -562,7 +549,7 @@ this.RequestSyncService = {
|
||||
}
|
||||
|
||||
if (aObj.principal.isInBrowserElement != aData.isInBrowserElement ||
|
||||
aObj.principal.origin != aData.origin) {
|
||||
aObj.principal.originNoSuffix != aData.origin) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -607,7 +594,7 @@ this.RequestSyncService = {
|
||||
let obj = this.createPartialTaskObject(aObj);
|
||||
|
||||
obj.app = { manifestURL: '',
|
||||
origin: aObj.principal.origin,
|
||||
origin: aObj.principal.originNoSuffix,
|
||||
isInBrowserElement: aObj.principal.isInBrowserElement };
|
||||
|
||||
let app = appsService.getAppByLocalId(aObj.principal.appId);
|
||||
|
@ -61,8 +61,8 @@ function test_registerFailure() {
|
||||
});
|
||||
}
|
||||
|
||||
function genericError() {
|
||||
ok(false, "Some promise failed");
|
||||
function genericError(name, val) {
|
||||
ok(false, "Promise from " + name + " rejected with value: " + val);
|
||||
}
|
||||
|
||||
function test_register() {
|
||||
@ -70,7 +70,7 @@ function test_register() {
|
||||
function() {
|
||||
ok(true, "navigator.sync.register() worked!");
|
||||
runTests();
|
||||
}, genericError);
|
||||
}, genericError.bind(null, 'register'));
|
||||
}
|
||||
|
||||
function test_unregister() {
|
||||
@ -78,12 +78,12 @@ function test_unregister() {
|
||||
function() {
|
||||
ok(true, "navigator.sync.unregister() worked!");
|
||||
runTests();
|
||||
}, genericError);
|
||||
}, genericError.bind(null, 'unregister'));
|
||||
}
|
||||
|
||||
function test_unregisterDuplicate() {
|
||||
navigator.sync.unregister('foobar').then(
|
||||
genericError,
|
||||
genericError.bind(null, 'unregisterDuplicate'),
|
||||
function(error) {
|
||||
ok(true, "navigator.sync.unregister() should throw if the task doesn't exist.");
|
||||
ok(error, "UnknownTaskError", "Duplicate unregistration error is correct");
|
||||
@ -97,7 +97,7 @@ function test_registrationEmpty() {
|
||||
is(results, null, "navigator.sync.registration() should return null.");
|
||||
runTests();
|
||||
},
|
||||
genericError);
|
||||
genericError.bind(null, 'registrationEmpty'));
|
||||
}
|
||||
|
||||
function test_registration() {
|
||||
@ -113,7 +113,7 @@ function test_registration() {
|
||||
ok(!("app" in results), "navigator.sync.registrations().app is correct");
|
||||
runTests();
|
||||
},
|
||||
genericError);
|
||||
genericError.bind(null, 'registration'));
|
||||
}
|
||||
|
||||
function test_registrationsEmpty() {
|
||||
@ -122,7 +122,7 @@ function test_registrationsEmpty() {
|
||||
is(results.length, 0, "navigator.sync.registrations() should return an empty array.");
|
||||
runTests();
|
||||
},
|
||||
genericError);
|
||||
genericError.bind(null, 'registrationEmpty'));
|
||||
}
|
||||
|
||||
function test_registrations() {
|
||||
@ -139,7 +139,7 @@ function test_registrations() {
|
||||
ok(!("app" in results[0]), "navigator.sync.registrations()[0].app is correct");
|
||||
runTests();
|
||||
},
|
||||
genericError);
|
||||
genericError.bind(null, 'registrations'));
|
||||
}
|
||||
|
||||
function test_managerRegistrationsEmpty() {
|
||||
@ -148,7 +148,7 @@ function test_managerRegistrationsEmpty() {
|
||||
is(results.length, 0, "navigator.syncManager.registrations() should return an empty array.");
|
||||
runTests();
|
||||
},
|
||||
genericError);
|
||||
genericError.bind(null, 'managerRegistrationsEmpty'));
|
||||
}
|
||||
|
||||
function test_managerRegistrations(state, overwrittenMinInterval) {
|
||||
@ -172,7 +172,7 @@ function test_managerRegistrations(state, overwrittenMinInterval) {
|
||||
ok("runNow" in results[0], "navigator.sync.registrations()[0].runNow is correct");
|
||||
runTests();
|
||||
},
|
||||
genericError);
|
||||
genericError.bind(null, 'managerRegistrations'));
|
||||
}
|
||||
|
||||
function test_managerSetPolicy(state, overwrittenMinInterval) {
|
||||
@ -183,6 +183,6 @@ function test_managerSetPolicy(state, overwrittenMinInterval) {
|
||||
ok(state, results[0].state, "State matches");
|
||||
ok(overwrittenMinInterval, results[0].overwrittenMinInterval, "OverwrittenMinInterval matches");
|
||||
runTests();
|
||||
}, genericError);
|
||||
}).catch(genericError);
|
||||
}, genericError.bind(null, 'managerSetPolicy'));
|
||||
}).catch(genericError.bind(null, 'managerSetPolicy_catch'));
|
||||
}
|
||||
|
@ -109,8 +109,8 @@ class ResourceUriFileReader:
|
||||
}
|
||||
|
||||
CODE_OPEN_CHANNEL_BY_URI = '''
|
||||
var Cc = SpecialPowers.Cc;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
|
||||
global.uri = '%(uri)s';
|
||||
@ -129,8 +129,8 @@ class ResourceUriFileReader:
|
||||
'''
|
||||
|
||||
CODE_READ_CONTENT = '''
|
||||
var Cc = SpecialPowers.Cc;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
var zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader);
|
||||
var inputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
|
||||
@ -155,7 +155,9 @@ class ResourceUriFileReader:
|
||||
return cls.URI_PREFIX + cls.URI_PATH[filename]
|
||||
|
||||
def __init__(self, marionette):
|
||||
self.runjs = lambda x: marionette.execute_script(x, new_sandbox=False)
|
||||
self.runjs = lambda x: marionette.execute_script(x,
|
||||
new_sandbox=False,
|
||||
sandbox='system')
|
||||
|
||||
def read_file(self, filename):
|
||||
"""Read file and return the contents as string."""
|
||||
@ -210,7 +212,9 @@ class JSHintEngine:
|
||||
for line in config.splitlines()])
|
||||
|
||||
# Set global (JSHINT, options, global) in js environment.
|
||||
self.runjs = lambda x: marionette.execute_script(x, new_sandbox=False)
|
||||
self.runjs = lambda x: marionette.execute_script(x,
|
||||
new_sandbox=False,
|
||||
sandbox='system')
|
||||
self.runjs(self.CODE_INIT_JSHINT %
|
||||
{'script': script, 'config_string': repr(config)})
|
||||
|
||||
|
@ -2,22 +2,21 @@
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<!--
|
||||
Test that "MozEnteredFullscreen" is dispatched to chrome on documents that enter fullscreen.
|
||||
Test that "MozDOMFullscreen:*" events are dispatched to chrome on documents that use DOM fullscreen.
|
||||
|
||||
Test Description:
|
||||
|
||||
This chrome window has a browser. The browser's contentDocument (the "outer document")
|
||||
in turn has an iframe (the "inner document").
|
||||
|
||||
We request fullscreen in the outer document, and check that MozEnteredDomFullscreen is
|
||||
dispatched to chrome, targeted at the outer document.
|
||||
We request fullscreen in the outer document, and check that MozDOMFullscreen:Entered and
|
||||
MozDOMFullscreen:NewOrigin are dispatched to chrome, targeted at the outer document.
|
||||
|
||||
Then we request fullscreen in the inner document, and check that MozEnteredDomFullscreen
|
||||
Then we request fullscreen in the inner document, and check that MozDOMFullscreen:NewOrigin
|
||||
is dispatched to chrome, targeted at the inner document.
|
||||
|
||||
Then we cancel fullscreen in the inner document, and check that MozEnteredDomFullscreen is
|
||||
dispatched again to chrome, targeted at the outer document. This still happens, since the
|
||||
outer document's domain was never approved for fullscreen.
|
||||
Then we cancel fullscreen in the inner document, and check that MozDOMFullscreen:NewOrigin is
|
||||
dispatched again to chrome, targeted at the outer document.
|
||||
-->
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="start();">
|
||||
|
||||
@ -38,39 +37,55 @@ var gBrowser = null;
|
||||
var gOuterDoc = null;
|
||||
var gInnerDoc = null;
|
||||
|
||||
var gReceivedFullscreenEnteredEvent = false;
|
||||
var gReceivedNewOriginEvent = false;
|
||||
function firstEntry(event) {
|
||||
is(event.target, gOuterDoc, "First MozEnteredDomFullscreen should be targeted at outer doc");
|
||||
window.removeEventListener("MozEnteredDomFullscreen", firstEntry, false);
|
||||
if (event.type == "MozDOMFullscreen:Entered") {
|
||||
window.removeEventListener("MozDOMFullscreen:Entered", firstEntry, false);
|
||||
ok(!gReceivedFullscreenEnteredEvent, "MozDOMFullscreen:Entered shouldn't have been triggered twice");
|
||||
gReceivedFullscreenEnteredEvent = true;
|
||||
} else if (event.type == "MozDOMFullscreen:NewOrigin") {
|
||||
window.removeEventListener("MozDOMFullscreen:NewOrigin", firstEntry, false);
|
||||
ok(!gReceivedNewOriginEvent, "MozDOMFullscreen:NewOrigin shouldn't have been triggered twice");
|
||||
gReceivedNewOriginEvent = true;
|
||||
} else {
|
||||
ok(false, "Unknown event received");
|
||||
}
|
||||
is(event.target, gOuterDoc, "First " + event.type + " should be targeted at outer doc");
|
||||
if (!gReceivedFullscreenEnteredEvent || !gReceivedNewOriginEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
ok(gOuterDoc.mozFullScreenElement != null, "Outer doc should be in fullscreen");
|
||||
gInnerDoc = gOuterDoc.getElementById("innerFrame").contentDocument;
|
||||
window.addEventListener("MozEnteredDomFullscreen", secondEntry, false);
|
||||
window.addEventListener("MozDOMFullscreen:NewOrigin", secondEntry, false);
|
||||
gInnerDoc.defaultView.focus();
|
||||
gInnerDoc.body.mozRequestFullScreen();
|
||||
}
|
||||
|
||||
function secondEntry(event) {
|
||||
is(event.target, gInnerDoc, "Second MozEnteredDomFullscreen should be targeted at inner doc");
|
||||
is(event.target, gInnerDoc, "Second MozDOMFullscreen:NewOrigin should be targeted at inner doc");
|
||||
ok(gInnerDoc.mozFullScreenElement != null, "Inner doc should be in fullscreen");
|
||||
window.removeEventListener("MozEnteredDomFullscreen", secondEntry, false);
|
||||
window.addEventListener("MozEnteredDomFullscreen", thirdEntry, false);
|
||||
window.removeEventListener("MozDOMFullscreen:NewOrigin", secondEntry, false);
|
||||
window.addEventListener("MozDOMFullscreen:NewOrigin", thirdEntry, false);
|
||||
gInnerDoc.mozCancelFullScreen();
|
||||
}
|
||||
|
||||
function thirdEntry(event) {
|
||||
is(event.target, gOuterDoc, "Third MozEnteredDomFullscreen should be targeted at outer doc");
|
||||
is(event.target, gOuterDoc, "Third MozDOMFullscreen:NewOrigin should be targeted at outer doc");
|
||||
ok(gOuterDoc.mozFullScreenElement != null, "Outer doc return to fullscreen after cancel fullscreen in inner doc");
|
||||
window.removeEventListener("MozEnteredDomFullscreen", thirdEntry, false);
|
||||
window.removeEventListener("MozExitedDomFullscreen", earlyExit, false);
|
||||
window.addEventListener("MozExitedDomFullscreen", lastExit, false);
|
||||
window.removeEventListener("MozDOMFullscreen:NewOrigin", thirdEntry, false);
|
||||
window.removeEventListener("MozDOMFullscreen:Exited", earlyExit, false);
|
||||
window.addEventListener("MozDOMFullscreen:Exited", lastExit, false);
|
||||
gOuterDoc.mozCancelFullScreen();
|
||||
}
|
||||
|
||||
function earlyExit(event) {
|
||||
ok(false, "MozExitedDomFullscreen should only be triggered after cancel all fullscreen");
|
||||
ok(false, "MozDOMFullscreen:Exited should only be triggered after cancel all fullscreen");
|
||||
}
|
||||
|
||||
function lastExit(event) {
|
||||
is(event.target, gOuterDoc, "MozExitedDomFullscreen should be targeted at the last exited doc");
|
||||
is(event.target, gOuterDoc, "MozDOMFullscreen:Exited should be targeted at the last exited doc");
|
||||
ok(gOuterDoc.mozFullScreenElement == null, "Fullscreen should have been fully exited");
|
||||
window.opener.wrappedJSObject.done();
|
||||
}
|
||||
@ -81,15 +96,14 @@ function start() {
|
||||
gBrowser = document.getElementById("browser");
|
||||
gOuterDoc = gBrowser.contentDocument;
|
||||
gBrowser.contentWindow.focus();
|
||||
window.addEventListener("MozEnteredDomFullscreen", firstEntry, false);
|
||||
window.addEventListener("MozExitedDomFullscreen", earlyExit, false);
|
||||
window.addEventListener("MozDOMFullscreen:Entered", firstEntry, false);
|
||||
window.addEventListener("MozDOMFullscreen:NewOrigin", firstEntry, false);
|
||||
gOuterDoc.body.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<!-- chrome://mochitests/content/chrome/dom/tests/mochitest/chrome/test_MozEnteredDomFullscreen_event.xul -->
|
||||
<browser type="content" id="browser" width="400" height="400" src="http://mochi.test:8888/tests/dom/tests/mochitest/general/file_MozDomFullscreen.html"/>
|
||||
<browser type="content" id="browser" width="400" height="400" src="file_MozDomFullscreen.html"/>
|
||||
|
||||
</window>
|
||||
|
@ -7,6 +7,7 @@ support-files =
|
||||
MozDomFullscreen_chrome.xul
|
||||
child_focus_frame.html
|
||||
file_DOM_element_instanceof.xul
|
||||
file_MozDomFullscreen.html
|
||||
file_bug799299.xul
|
||||
file_bug800817.xul
|
||||
file_bug830858.xul
|
||||
|
8
dom/tests/mochitest/chrome/file_MozDomFullscreen.html
Normal file
8
dom/tests/mochitest/chrome/file_MozDomFullscreen.html
Normal file
@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body style="background-color: blue;">
|
||||
<p>Outer doc</p>
|
||||
<iframe id="innerFrame" src="http://mochi.test:8888/"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -1,8 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body style="background-color: blue;">
|
||||
<p>Outer doc</p>
|
||||
<iframe id="innerFrame" src="data:text/html,<html><body style='background-color: red;'><p>Inner doc</p></body></html>"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -1,7 +1,6 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
497633.html
|
||||
file_MozDomFullscreen.html
|
||||
file_bug628069.html
|
||||
file_clonewrapper.html
|
||||
file_domWindowUtils_scrollbarSize.html
|
||||
|
@ -129,6 +129,21 @@ interface PopupBoxObject : BoxObject
|
||||
boolean isContextMenu,
|
||||
Event? triggerEvent);
|
||||
|
||||
/**
|
||||
* Open the popup anchored at a specific screen rectangle. This function is
|
||||
* similar to openPopup except that that rectangle of the anchor is supplied
|
||||
* rather than an element. The anchor rectangle arguments are screen
|
||||
* coordinates.
|
||||
*/
|
||||
void openPopupAtScreenRect(optional DOMString position = "",
|
||||
long x,
|
||||
long y,
|
||||
long width,
|
||||
long height,
|
||||
boolean isContextMenu,
|
||||
boolean attributesOverride,
|
||||
Event? triggerEvent);
|
||||
|
||||
/**
|
||||
* Returns the state of the popup:
|
||||
* closed - the popup is closed
|
||||
|
22
dom/webidl/SystemDictionaries.webidl
Normal file
22
dom/webidl/SystemDictionaries.webidl
Normal file
@ -0,0 +1,22 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Used by principals and the script security manager to represent origin
|
||||
* attributes.
|
||||
*
|
||||
* IMPORTANT: If you add any members here, you need to update the
|
||||
* methods on mozilla::OriginAttributes, and bump the CIDs of all
|
||||
* the principal implementations that use OriginAttributes in their
|
||||
* nsISerializable implementations.
|
||||
*/
|
||||
dictionary OriginAttributesDictionary {
|
||||
unsigned long appId = 0;
|
||||
boolean inBrowser = false;
|
||||
};
|
@ -509,6 +509,7 @@ WEBIDL_FILES = [
|
||||
'SVGViewElement.webidl',
|
||||
'SVGZoomAndPan.webidl',
|
||||
'SVGZoomEvent.webidl',
|
||||
'SystemDictionaries.webidl',
|
||||
'Telephony.webidl',
|
||||
'TelephonyCall.webidl',
|
||||
'TelephonyCallGroup.webidl',
|
||||
|
@ -217,9 +217,7 @@ XULDocument::~XULDocument()
|
||||
mPersistenceIds.Clear();
|
||||
|
||||
// Destroy our broadcaster map.
|
||||
if (mBroadcasterMap) {
|
||||
PL_DHashTableDestroy(mBroadcasterMap);
|
||||
}
|
||||
delete mBroadcasterMap;
|
||||
|
||||
delete mTemplateBuilderTable;
|
||||
|
||||
@ -767,7 +765,7 @@ XULDocument::AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener,
|
||||
};
|
||||
|
||||
if (! mBroadcasterMap) {
|
||||
mBroadcasterMap = PL_NewDHashTable(&gOps, sizeof(BroadcasterMapEntry));
|
||||
mBroadcasterMap = new PLDHashTable2(&gOps, sizeof(BroadcasterMapEntry));
|
||||
}
|
||||
|
||||
BroadcasterMapEntry* entry =
|
||||
|
@ -719,7 +719,7 @@ protected:
|
||||
/**
|
||||
* A map from a broadcaster element to a list of listener elements.
|
||||
*/
|
||||
PLDHashTable* mBroadcasterMap;
|
||||
PLDHashTable2* mBroadcasterMap;
|
||||
|
||||
nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIObserver> > mOverlayLoadObservers;
|
||||
nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIObserver> > mPendingOverlayLoadNotifications;
|
||||
|
@ -156,7 +156,7 @@ GetHostForPrincipal(nsIPrincipal* aPrincipal, nsACString& aHost)
|
||||
}
|
||||
|
||||
// Some entries like "file://" uses the origin.
|
||||
rv = aPrincipal->GetOrigin(aHost);
|
||||
rv = aPrincipal->GetOriginNoSuffix(aHost);
|
||||
if (NS_SUCCEEDED(rv) && !aHost.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
|
||||
const __m128 scale = _mm_load_ps(floatScaleX4);
|
||||
|
||||
/* working variables */
|
||||
__m128 vec_r, vec_g, vec_b, result;
|
||||
__m128 vec_r, vec_g, vec_b, result, result_hi;
|
||||
|
||||
/* CYA */
|
||||
if (!length)
|
||||
@ -84,9 +84,11 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
|
||||
result = _mm_mul_ps(vec_r, scale);
|
||||
|
||||
/* store calc'd output tables indices */
|
||||
/* Bug 1163740 temporary investigation:
|
||||
* Write output[0] last, to keep |result| in a register in minidumps */
|
||||
result_hi = _mm_movehl_ps(result, result);
|
||||
*((__m64 *)&output[2]) = _mm_cvtps_pi32(result_hi);
|
||||
*((__m64 *)&output[0]) = _mm_cvtps_pi32(result);
|
||||
result = _mm_movehl_ps(result, result);
|
||||
*((__m64 *)&output[2]) = _mm_cvtps_pi32(result) ;
|
||||
|
||||
/* load for next loop while store completes */
|
||||
vec_r = _mm_load_ss(&igtbl_r[src[0]]);
|
||||
@ -165,7 +167,7 @@ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
|
||||
const __m128 scale = _mm_load_ps(floatScaleX4);
|
||||
|
||||
/* working variables */
|
||||
__m128 vec_r, vec_g, vec_b, result;
|
||||
__m128 vec_r, vec_g, vec_b, result, result_hi;
|
||||
unsigned char alpha;
|
||||
|
||||
/* CYA */
|
||||
@ -206,10 +208,11 @@ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
|
||||
vec_r = _mm_min_ps(max, vec_r);
|
||||
result = _mm_mul_ps(vec_r, scale);
|
||||
|
||||
/* store calc'd output tables indices */
|
||||
/* Bug 1163740 temporary investigation:
|
||||
* Write output[0] last, to keep |result| in a register in minidumps */
|
||||
result_hi = _mm_movehl_ps(result, result);
|
||||
*((__m64 *)&output[2]) = _mm_cvtps_pi32(result_hi);
|
||||
*((__m64 *)&output[0]) = _mm_cvtps_pi32(result);
|
||||
result = _mm_movehl_ps(result, result);
|
||||
*((__m64 *)&output[2]) = _mm_cvtps_pi32(result);
|
||||
|
||||
/* load gamma values for next loop while store completes */
|
||||
vec_r = _mm_load_ss(&igtbl_r[src[0]]);
|
||||
|
@ -4,39 +4,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsUnicodeRange.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
||||
// This table depends on unicode range definitions.
|
||||
// Each item's index must correspond unicode range value
|
||||
// eg. x-cyrillic = LangGroupTable[kRangeCyrillic]
|
||||
static nsIAtom **gUnicodeRangeToLangGroupAtomTable[] =
|
||||
{
|
||||
&nsGkAtoms::x_cyrillic,
|
||||
&nsGkAtoms::el_,
|
||||
&nsGkAtoms::he,
|
||||
&nsGkAtoms::ar,
|
||||
&nsGkAtoms::th,
|
||||
&nsGkAtoms::ko,
|
||||
&nsGkAtoms::Japanese,
|
||||
&nsGkAtoms::zh_cn,
|
||||
&nsGkAtoms::zh_tw,
|
||||
&nsGkAtoms::x_devanagari,
|
||||
&nsGkAtoms::x_tamil,
|
||||
&nsGkAtoms::x_armn,
|
||||
&nsGkAtoms::x_beng,
|
||||
&nsGkAtoms::x_cans,
|
||||
&nsGkAtoms::x_ethi,
|
||||
&nsGkAtoms::x_geor,
|
||||
&nsGkAtoms::x_gujr,
|
||||
&nsGkAtoms::x_guru,
|
||||
&nsGkAtoms::x_khmr,
|
||||
&nsGkAtoms::x_mlym,
|
||||
&nsGkAtoms::x_orya,
|
||||
&nsGkAtoms::x_telu,
|
||||
&nsGkAtoms::x_knda,
|
||||
&nsGkAtoms::x_sinh,
|
||||
&nsGkAtoms::x_tibt
|
||||
};
|
||||
|
||||
/**********************************************************************
|
||||
* Unicode subranges as defined in unicode 3.0
|
||||
@ -450,12 +417,3 @@ uint32_t FindCharUnicodeRange(uint32_t ch)
|
||||
// Yet another table to look at : U+0700 - U+16FF : 128 code point blocks
|
||||
return gUnicodeTertiaryRangeTable[(ch - 0x0700) >> 7];
|
||||
}
|
||||
|
||||
nsIAtom *LangGroupFromUnicodeRange(uint8_t unicodeRange)
|
||||
{
|
||||
if (kRangeSpecificItemNum > unicodeRange) {
|
||||
nsIAtom **atom = gUnicodeRangeToLangGroupAtomTable[unicodeRange];
|
||||
return *atom;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class nsIAtom;
|
||||
|
||||
// The following constants define unicode subranges
|
||||
// values below kRangeNum must be continuous so that we can map to
|
||||
// lang group directly.
|
||||
@ -89,6 +87,5 @@ const uint8_t kRangeTertiaryTable = 145; // leave room for 16 subtable
|
||||
|
||||
|
||||
uint32_t FindCharUnicodeRange(uint32_t ch);
|
||||
nsIAtom* LangGroupFromUnicodeRange(uint8_t unicodeRange);
|
||||
|
||||
#endif
|
||||
|
@ -337,7 +337,17 @@ DecodePool::DecodePool()
|
||||
int32_t prefLimit = gfxPrefs::ImageMTDecodingLimit();
|
||||
uint32_t limit;
|
||||
if (prefLimit <= 0) {
|
||||
limit = max(PR_GetNumberOfProcessors(), 2) - 1;
|
||||
int32_t numCores = PR_GetNumberOfProcessors();
|
||||
if (numCores <= 1) {
|
||||
limit = 1;
|
||||
} else if (numCores == 2) {
|
||||
// On an otherwise mostly idle system, having two image decoding threads
|
||||
// doubles decoding performance, so it's worth doing on dual-core devices,
|
||||
// even if under load we can't actually get that level of parallelism.
|
||||
limit = 2;
|
||||
} else {
|
||||
limit = numCores - 1;
|
||||
}
|
||||
} else {
|
||||
limit = static_cast<uint32_t>(prefLimit);
|
||||
}
|
||||
|
@ -17,37 +17,67 @@ using namespace dom;
|
||||
|
||||
namespace image {
|
||||
|
||||
bool
|
||||
URISchemeIs(ImageURL* aURI, const char* aScheme)
|
||||
{
|
||||
bool schemeMatches = false;
|
||||
if (NS_WARN_IF(NS_FAILED(aURI->SchemeIs(aScheme, &schemeMatches)))) {
|
||||
return false;
|
||||
}
|
||||
return schemeMatches;
|
||||
}
|
||||
|
||||
static Maybe<uint64_t>
|
||||
BlobSerial(ImageURL* aURI)
|
||||
{
|
||||
nsAutoCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
|
||||
nsRefPtr<BlobImpl> blob;
|
||||
if (NS_SUCCEEDED(NS_GetBlobForBlobURISpec(spec, getter_AddRefs(blob))) &&
|
||||
blob) {
|
||||
return Some(blob->GetSerialNumber());
|
||||
}
|
||||
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
ImageCacheKey::ImageCacheKey(nsIURI* aURI)
|
||||
: mURI(new ImageURL(aURI))
|
||||
, mIsChrome(URISchemeIs(mURI, "chrome"))
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mURI);
|
||||
|
||||
bool isChrome;
|
||||
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
|
||||
if (URISchemeIs(mURI, "blob")) {
|
||||
mBlobSerial = BlobSerial(mURI);
|
||||
}
|
||||
|
||||
mHash = ComputeHash(mURI);
|
||||
mHash = ComputeHash(mURI, mBlobSerial);
|
||||
}
|
||||
|
||||
ImageCacheKey::ImageCacheKey(ImageURL* aURI)
|
||||
: mURI(aURI)
|
||||
, mIsChrome(URISchemeIs(mURI, "chrome"))
|
||||
{
|
||||
MOZ_ASSERT(mURI);
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
bool isChrome;
|
||||
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
|
||||
if (URISchemeIs(mURI, "blob")) {
|
||||
mBlobSerial = BlobSerial(mURI);
|
||||
}
|
||||
|
||||
mHash = ComputeHash(mURI);
|
||||
mHash = ComputeHash(mURI, mBlobSerial);
|
||||
}
|
||||
|
||||
ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
|
||||
: mURI(aOther.mURI)
|
||||
, mBlobSerial(aOther.mBlobSerial)
|
||||
, mHash(aOther.mHash)
|
||||
, mIsChrome(aOther.mIsChrome)
|
||||
{ }
|
||||
|
||||
ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
|
||||
: mURI(Move(aOther.mURI))
|
||||
, mBlobSerial(Move(aOther.mBlobSerial))
|
||||
, mHash(aOther.mHash)
|
||||
, mIsChrome(aOther.mIsChrome)
|
||||
{ }
|
||||
@ -55,6 +85,12 @@ ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
|
||||
bool
|
||||
ImageCacheKey::operator==(const ImageCacheKey& aOther) const
|
||||
{
|
||||
if (mBlobSerial || aOther.mBlobSerial) {
|
||||
// If at least one of us has a blob serial, just compare those.
|
||||
return mBlobSerial == aOther.mBlobSerial;
|
||||
}
|
||||
|
||||
// For non-blob URIs, compare the URIs.
|
||||
return *mURI == *aOther.mURI;
|
||||
}
|
||||
|
||||
@ -65,10 +101,19 @@ ImageCacheKey::Spec() const
|
||||
}
|
||||
|
||||
/* static */ uint32_t
|
||||
ImageCacheKey::ComputeHash(ImageURL* aURI)
|
||||
ImageCacheKey::ComputeHash(ImageURL* aURI,
|
||||
const Maybe<uint64_t>& aBlobSerial)
|
||||
{
|
||||
// Since we frequently call Hash() several times in a row on the same
|
||||
// ImageCacheKey, as an optimization we compute our hash once and store it.
|
||||
|
||||
if (aBlobSerial) {
|
||||
// For blob URIs, we hash the serial number of the underlying blob, so that
|
||||
// different blob URIs which point to the same blob share a cache entry.
|
||||
return HashGeneric(*aBlobSerial);
|
||||
}
|
||||
|
||||
// For non-blob URIs, we hash the URI spec.
|
||||
nsAutoCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
return HashString(spec);
|
||||
|
@ -10,6 +10,8 @@
|
||||
#ifndef mozilla_image_src_ImageCacheKey_h
|
||||
#define mozilla_image_src_ImageCacheKey_h
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
@ -42,9 +44,11 @@ public:
|
||||
bool IsChrome() const { return mIsChrome; }
|
||||
|
||||
private:
|
||||
static uint32_t ComputeHash(ImageURL* aURI);
|
||||
static uint32_t ComputeHash(ImageURL* aURI,
|
||||
const Maybe<uint64_t>& aBlobSerial);
|
||||
|
||||
nsRefPtr<ImageURL> mURI;
|
||||
Maybe<uint64_t> mBlobSerial;
|
||||
uint32_t mHash;
|
||||
bool mIsChrome;
|
||||
};
|
||||
|
@ -4858,41 +4858,15 @@ BytecodeEmitter::emitIf(ParseNode* pn)
|
||||
}
|
||||
|
||||
/*
|
||||
* pnLet represents one of:
|
||||
* pnLet represents a let-statement: let (x = y) { ... }
|
||||
*
|
||||
* let-expression: (let (x = y) EXPR)
|
||||
* let-statement: let (x = y) { ... }
|
||||
*
|
||||
* For a let-expression 'let (x = a, [y,z] = b) e', EmitLet produces:
|
||||
*
|
||||
* bytecode stackDepth srcnotes
|
||||
* evaluate a +1
|
||||
* evaluate b +1
|
||||
* dup +1
|
||||
* destructure y
|
||||
* pick 1
|
||||
* dup +1
|
||||
* destructure z
|
||||
* pick 1
|
||||
* pop -1
|
||||
* setlocal 2 -1
|
||||
* setlocal 1 -1
|
||||
* setlocal 0 -1
|
||||
* pushblockscope (if needed)
|
||||
* evaluate e +1
|
||||
* debugleaveblock
|
||||
* popblockscope (if needed)
|
||||
*
|
||||
* Note that, since pushblockscope simply changes fp->scopeChain and does not
|
||||
* otherwise touch the stack, evaluation of the let-var initializers must leave
|
||||
* the initial value in the let-var's future slot.
|
||||
*/
|
||||
/*
|
||||
* Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See
|
||||
* the comment on emitSwitch.
|
||||
*/
|
||||
MOZ_NEVER_INLINE bool
|
||||
BytecodeEmitter::emitLet(ParseNode* pnLet)
|
||||
BytecodeEmitter::emitLetBlock(ParseNode* pnLet)
|
||||
{
|
||||
MOZ_ASSERT(pnLet->isArity(PN_BINARY));
|
||||
ParseNode* varList = pnLet->pn_left;
|
||||
@ -6722,9 +6696,8 @@ BytecodeEmitter::emitConditionalExpression(ConditionalExpression& conditional)
|
||||
* ignore the value pushed by the first branch. Execution will follow
|
||||
* only one path, so we must decrement this->stackDepth.
|
||||
*
|
||||
* Failing to do this will foil code, such as let expression and block
|
||||
* code generation, which must use the stack depth to compute local
|
||||
* stack indexes correctly.
|
||||
* Failing to do this will foil code, such as let block code generation,
|
||||
* which must use the stack depth to compute local stack indexes correctly.
|
||||
*/
|
||||
MOZ_ASSERT(stackDepth > 0);
|
||||
stackDepth--;
|
||||
@ -7542,8 +7515,7 @@ BytecodeEmitter::emitTree(ParseNode* pn)
|
||||
break;
|
||||
|
||||
case PNK_LETBLOCK:
|
||||
case PNK_LETEXPR:
|
||||
ok = emitLet(pn);
|
||||
ok = emitLetBlock(pn);
|
||||
break;
|
||||
|
||||
case PNK_CONST:
|
||||
|
@ -490,7 +490,7 @@ struct BytecodeEmitter
|
||||
bool emitWith(ParseNode* pn);
|
||||
|
||||
MOZ_NEVER_INLINE bool emitLabeledStatement(const LabeledStatement* pn);
|
||||
MOZ_NEVER_INLINE bool emitLet(ParseNode* pnLet);
|
||||
MOZ_NEVER_INLINE bool emitLetBlock(ParseNode* pnLet);
|
||||
MOZ_NEVER_INLINE bool emitLexicalScope(ParseNode* pn);
|
||||
MOZ_NEVER_INLINE bool emitSwitch(ParseNode* pn);
|
||||
MOZ_NEVER_INLINE bool emitTry(ParseNode* pn);
|
||||
|
@ -402,7 +402,6 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
|
||||
case PNK_FALSE:
|
||||
case PNK_NULL:
|
||||
case PNK_THIS:
|
||||
case PNK_LETEXPR:
|
||||
case PNK_ELISION:
|
||||
case PNK_NUMBER:
|
||||
case PNK_NEW:
|
||||
|
@ -591,14 +591,6 @@ class FullParseHandler
|
||||
block->pn_expr = body;
|
||||
}
|
||||
|
||||
ParseNode* newLetExpression(ParseNode* vars, ParseNode* block, const TokenPos& pos) {
|
||||
ParseNode* letExpr = newBinary(PNK_LETEXPR, vars, block);
|
||||
if (!letExpr)
|
||||
return nullptr;
|
||||
letExpr->pn_pos = pos;
|
||||
return letExpr;
|
||||
}
|
||||
|
||||
ParseNode* newLetBlock(ParseNode* vars, ParseNode* block, const TokenPos& pos) {
|
||||
ParseNode* letBlock = newBinary(PNK_LETBLOCK, vars, block);
|
||||
if (!letBlock)
|
||||
|
@ -424,7 +424,6 @@ class NameResolver
|
||||
case PNK_DIVASSIGN:
|
||||
case PNK_MODASSIGN:
|
||||
case PNK_ELEM:
|
||||
case PNK_LETEXPR:
|
||||
case PNK_COLON:
|
||||
case PNK_CASE:
|
||||
case PNK_SHORTHAND:
|
||||
|
@ -266,7 +266,6 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
|
||||
case PNK_MODASSIGN:
|
||||
// ...and a few others.
|
||||
case PNK_ELEM:
|
||||
case PNK_LETEXPR:
|
||||
case PNK_IMPORT_SPEC:
|
||||
case PNK_EXPORT_SPEC:
|
||||
case PNK_COLON:
|
||||
|
@ -133,7 +133,6 @@ class UpvarCookie
|
||||
F(LEXICALSCOPE) \
|
||||
F(LET) \
|
||||
F(LETBLOCK) \
|
||||
F(LETEXPR) \
|
||||
F(IMPORT) \
|
||||
F(IMPORT_SPEC_LIST) \
|
||||
F(IMPORT_SPEC) \
|
||||
|
@ -2989,8 +2989,8 @@ Parser<ParseHandler>::reportRedeclaration(Node pn, Definition::Kind redeclKind,
|
||||
}
|
||||
|
||||
/*
|
||||
* Define a lexical binding in a block, let-expression, or comprehension scope. pc
|
||||
* must already be in such a scope.
|
||||
* Define a lexical binding in a block, or comprehension scope. pc must
|
||||
* already be in such a scope.
|
||||
*
|
||||
* Throw a SyntaxError if 'atom' is an invalid name. Otherwise create a
|
||||
* property for the new variable on the block object, pc->staticScope;
|
||||
@ -3680,14 +3680,13 @@ Parser<SyntaxParseHandler>::pushLetScope(HandleStaticBlockObject blockObj, StmtI
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a let block statement or let expression (determined by 'letContext').
|
||||
* Parse a let block statement.
|
||||
* In both cases, bindings are not hoisted to the top of the enclosing block
|
||||
* and thus must be carefully injected between variables() and the let body.
|
||||
*/
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::deprecatedLetBlockOrExpression(YieldHandling yieldHandling,
|
||||
LetContext letContext)
|
||||
Parser<ParseHandler>::deprecatedLetBlock(YieldHandling yieldHandling)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LET));
|
||||
|
||||
@ -3710,82 +3709,22 @@ Parser<ParseHandler>::deprecatedLetBlockOrExpression(YieldHandling yieldHandling
|
||||
if (!block)
|
||||
return null();
|
||||
|
||||
bool needExprStmt = false;
|
||||
if (letContext == LetStatement) {
|
||||
bool matched;
|
||||
if (!tokenStream.matchToken(&matched, TOK_LC, TokenStream::Operand))
|
||||
return null();
|
||||
if (!matched) {
|
||||
/*
|
||||
* Strict mode eliminates a grammar ambiguity with unparenthesized
|
||||
* LetExpressions in an ExpressionStatement. If followed immediately
|
||||
* by an arguments list, it's ambiguous whether the let expression
|
||||
* is the callee or the call is inside the let expression body.
|
||||
*
|
||||
* function id(x) { return x; }
|
||||
* var x = "outer";
|
||||
* // Does this parse as
|
||||
* // (let (loc = "inner") id)(loc) // "outer"
|
||||
* // or as
|
||||
* // let (loc = "inner") (id(loc)) // "inner"
|
||||
* let (loc = "inner") id(loc);
|
||||
*
|
||||
* See bug 569464.
|
||||
*/
|
||||
if (!reportWithOffset(ParseStrictError, pc->sc->strict(), begin,
|
||||
JSMSG_STRICT_CODE_LET_EXPR_STMT))
|
||||
{
|
||||
return null();
|
||||
}
|
||||
MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_LET);
|
||||
|
||||
/*
|
||||
* If this is really an expression in let statement guise, then we
|
||||
* need to wrap the PNK_LETEXPR node in a PNK_SEMI node so that we
|
||||
* pop the return value of the expression.
|
||||
*/
|
||||
needExprStmt = true;
|
||||
letContext = LetExpression;
|
||||
}
|
||||
}
|
||||
Node expr = statements(yieldHandling);
|
||||
if (!expr)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LET);
|
||||
|
||||
Node expr;
|
||||
if (letContext == LetStatement) {
|
||||
expr = statements(yieldHandling);
|
||||
if (!expr)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LET);
|
||||
addTelemetry(JSCompartment::DeprecatedLetBlock);
|
||||
if (!report(ParseWarning, pc->sc->strict(), expr, JSMSG_DEPRECATED_LET_BLOCK))
|
||||
return null();
|
||||
|
||||
addTelemetry(JSCompartment::DeprecatedLetBlock);
|
||||
if (!report(ParseWarning, pc->sc->strict(), expr, JSMSG_DEPRECATED_LET_BLOCK))
|
||||
return null();
|
||||
} else {
|
||||
MOZ_ASSERT(letContext == LetExpression);
|
||||
expr = assignExpr(InAllowed, yieldHandling);
|
||||
if (!expr)
|
||||
return null();
|
||||
|
||||
addTelemetry(JSCompartment::DeprecatedLetExpression);
|
||||
if (!report(ParseWarning, pc->sc->strict(), expr, JSMSG_DEPRECATED_LET_EXPRESSION))
|
||||
return null();
|
||||
}
|
||||
handler.setLexicalScopeBody(block, expr);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
TokenPos letPos(begin, pos().end);
|
||||
|
||||
if (letContext == LetExpression) {
|
||||
if (needExprStmt) {
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
}
|
||||
|
||||
Node letExpr = handler.newLetExpression(vars, block, letPos);
|
||||
if (!letExpr)
|
||||
return null();
|
||||
|
||||
return needExprStmt ? handler.newExprStatement(letExpr, pos().end) : letExpr;
|
||||
}
|
||||
|
||||
return handler.newLetBlock(vars, block, letPos);
|
||||
}
|
||||
|
||||
@ -4242,24 +4181,17 @@ Parser<FullParseHandler>::letDeclarationOrBlock(YieldHandling yieldHandling)
|
||||
{
|
||||
handler.disableSyntaxParser();
|
||||
|
||||
/* Check for a let statement or let expression. */
|
||||
/* Check for a let statement. */
|
||||
TokenKind tt;
|
||||
if (!tokenStream.peekToken(&tt))
|
||||
return null();
|
||||
if (tt == TOK_LP) {
|
||||
ParseNode* node =
|
||||
deprecatedLetBlockOrExpression(yieldHandling, LetStatement);
|
||||
ParseNode* node = deprecatedLetBlock(yieldHandling);
|
||||
if (!node)
|
||||
return nullptr;
|
||||
|
||||
if (node->isKind(PNK_LETBLOCK)) {
|
||||
MOZ_ASSERT(node->isArity(PN_BINARY));
|
||||
} else {
|
||||
MOZ_ASSERT(node->isKind(PNK_SEMI));
|
||||
MOZ_ASSERT(node->pn_kid->isKind(PNK_LETEXPR));
|
||||
MOZ_ASSERT(node->pn_kid->isArity(PN_BINARY));
|
||||
}
|
||||
|
||||
MOZ_ASSERT(node->isKind(PNK_LETBLOCK));
|
||||
MOZ_ASSERT(node->isArity(PN_BINARY));
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -4750,8 +4682,7 @@ Parser<FullParseHandler>::forStatement(YieldHandling yieldHandling)
|
||||
MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
|
||||
|
||||
/*
|
||||
* True if we have 'for (var/let/const ...)', except in the oddball case
|
||||
* where 'let' begins a let-expression in 'for (let (...) ...)'.
|
||||
* True if we have 'for (var/let/const ...)'.
|
||||
*/
|
||||
bool isForDecl = false;
|
||||
|
||||
@ -4790,19 +4721,13 @@ Parser<FullParseHandler>::forStatement(YieldHandling yieldHandling)
|
||||
handler.disableSyntaxParser();
|
||||
bool constDecl = tt == TOK_CONST;
|
||||
tokenStream.consumeKnownToken(tt);
|
||||
if (!tokenStream.peekToken(&tt))
|
||||
isForDecl = true;
|
||||
blockObj = StaticBlockObject::create(context);
|
||||
if (!blockObj)
|
||||
return null();
|
||||
if (tt == TOK_LP) {
|
||||
pn1 = deprecatedLetBlockOrExpression(yieldHandling, LetExpression);
|
||||
} else {
|
||||
isForDecl = true;
|
||||
blockObj = StaticBlockObject::create(context);
|
||||
if (!blockObj)
|
||||
return null();
|
||||
pn1 = variables(yieldHandling,
|
||||
constDecl ? PNK_CONST : PNK_LET, nullptr, blockObj,
|
||||
DontHoistVars);
|
||||
}
|
||||
pn1 = variables(yieldHandling,
|
||||
constDecl ? PNK_CONST : PNK_LET, nullptr, blockObj,
|
||||
DontHoistVars);
|
||||
} else {
|
||||
pn1 = expr(InProhibited, yieldHandling);
|
||||
}
|
||||
@ -7053,9 +6978,7 @@ LegacyCompExprTransplanter::transplant(ParseNode* pn)
|
||||
// The one remaining thing to patch up is the block scope depth. We need to
|
||||
// compute the maximum block scope depth of a function, so we know how much
|
||||
// space to reserve in the fixed part of a stack frame. Normally this is done
|
||||
// whenever we leave a statement, via AccumulateBlockScopeDepth. However if the
|
||||
// head has a let expression, we need to re-assign that depth to the tail of the
|
||||
// comprehension.
|
||||
// whenever we leave a statement, via AccumulateBlockScopeDepth.
|
||||
//
|
||||
// Thing is, we don't actually know what that depth is, because the only
|
||||
// information we keep is the maximum nested depth within a statement, so we
|
||||
@ -7128,10 +7051,9 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode* bodyExpr, unsigned
|
||||
* the comprehension's block scope. We allocate that id or one above it
|
||||
* here, by calling PushLexicalScope.
|
||||
*
|
||||
* In the case of a comprehension expression that has nested blocks
|
||||
* (e.g., let expressions), we will allocate a higher blockid but then
|
||||
* slide all blocks "to the right" to make room for the comprehension's
|
||||
* block scope.
|
||||
* In the case of a comprehension expression that has nested blocks,
|
||||
* we will allocate a higher blockid but then slide all blocks "to the
|
||||
* right" to make room for the comprehension's block scope.
|
||||
*/
|
||||
adjust = pc->blockid();
|
||||
pn = pushLexicalScope(&stmtInfo);
|
||||
@ -8219,9 +8141,10 @@ Parser<ParseHandler>::arrayInitializer(YieldHandling yieldHandling)
|
||||
*
|
||||
* [i * j for (i in o) for (j in p) if (i != j)]
|
||||
*
|
||||
* translates to roughly the following let expression:
|
||||
* translates to roughly the following code:
|
||||
*
|
||||
* let (array = new Array, i, j) {
|
||||
* {
|
||||
* let array = new Array, i, j;
|
||||
* for (i in o) let {
|
||||
* for (j in p)
|
||||
* if (i != j)
|
||||
@ -8651,9 +8574,6 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TokenKind tt,
|
||||
case TOK_LC:
|
||||
return propertyList(yieldHandling, ObjectLiteral);
|
||||
|
||||
case TOK_LET:
|
||||
return deprecatedLetBlockOrExpression(yieldHandling, LetExpression);
|
||||
|
||||
case TOK_LP: {
|
||||
TokenKind next;
|
||||
if (!tokenStream.peekToken(&next, TokenStream::Operand))
|
||||
|
@ -326,7 +326,6 @@ struct BindData;
|
||||
|
||||
class CompExprTransplanter;
|
||||
|
||||
enum LetContext { LetExpression, LetStatement };
|
||||
enum VarContext { HoistVars, DontHoistVars };
|
||||
enum PropListType { ObjectLiteral, ClassBody };
|
||||
|
||||
@ -629,7 +628,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
Node generatorComprehension(uint32_t begin);
|
||||
|
||||
bool argumentList(YieldHandling yieldHandling, Node listNode, bool* isSpread);
|
||||
Node deprecatedLetBlockOrExpression(YieldHandling yieldHandling, LetContext letContext);
|
||||
Node deprecatedLetBlock(YieldHandling yieldHandling);
|
||||
Node destructuringExpr(YieldHandling yieldHandling, BindData<ParseHandler>* data,
|
||||
TokenKind tt);
|
||||
Node destructuringExprWithoutYield(YieldHandling yieldHandling, BindData<ParseHandler>* data,
|
||||
|
@ -258,10 +258,6 @@ class SyntaxParseHandler
|
||||
Node newLexicalScope(ObjectBox* blockbox) { return NodeGeneric; }
|
||||
void setLexicalScopeBody(Node block, Node body) {}
|
||||
|
||||
Node newLetExpression(Node vars, Node block, const TokenPos& pos) {
|
||||
return NodeGeneric;
|
||||
}
|
||||
|
||||
Node newLetBlock(Node vars, Node block, const TokenPos& pos) {
|
||||
return NodeGeneric;
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
// Binary: cache/js-dbg-64-0ba03471b3b0-linux
|
||||
// Flags:
|
||||
//
|
||||
uneval(new Function("\
|
||||
for(\
|
||||
((let (functional) x) for each ([] in [])); \
|
||||
yield x; \
|
||||
(let (x = true) x));\
|
||||
"))
|
@ -1,15 +0,0 @@
|
||||
// |jit-test| error:ReferenceError
|
||||
|
||||
// Binary: cache/js-dbg-32-525d852c622d-linux
|
||||
// Flags: -j
|
||||
//
|
||||
(function() {
|
||||
let(x)
|
||||
(function() {
|
||||
for (let a in [0, x, 0, 0])
|
||||
(function() {
|
||||
for (let y in [0, 0]) print
|
||||
})();
|
||||
})()
|
||||
with({}) throw x;
|
||||
})()
|
@ -1,18 +0,0 @@
|
||||
// Binary: cache/js-dbg-32-15c46082297d-linux
|
||||
// Flags: -j
|
||||
//
|
||||
(function() {
|
||||
(eval("\
|
||||
(function() {\
|
||||
let(e)((function() { ((function f(a) {\
|
||||
if (a < 1) {\
|
||||
return 1\
|
||||
}\
|
||||
x = arguments;\
|
||||
return f(a - 1) + f(a - 2)\
|
||||
})(6))\
|
||||
})())\
|
||||
})\
|
||||
"))()
|
||||
})()
|
||||
gc()
|
@ -1,9 +0,0 @@
|
||||
// Binary: cache/js-dbg-64-7f7dfb33a33e-linux
|
||||
// Flags:
|
||||
//
|
||||
x = Proxy.create((function () {}), (evalcx('')))
|
||||
try {
|
||||
(function () {
|
||||
((let(e = eval) e).call(x, ("\"\"")))
|
||||
})()
|
||||
} catch (e) {}
|
@ -1,6 +0,0 @@
|
||||
// |jit-test| error:ReferenceError
|
||||
|
||||
// Binary: cache/js-dbg-64-242947d76f73-linux
|
||||
// Flags:
|
||||
//
|
||||
for (b in [evalcx("let(e)eval()", evalcx('split'))]) {}
|
@ -1,14 +0,0 @@
|
||||
// |jit-test| slow;
|
||||
|
||||
// Binary: cache/js-dbg-32-f98c57415d8d-linux
|
||||
// Flags:
|
||||
//
|
||||
|
||||
try {
|
||||
var str = '0123456789';
|
||||
for (var icount = 0; icount < 25; ++icount, let(icount2, printStatus) (function() gczeal(2))[1]++)
|
||||
str = str + str;
|
||||
} catch(ex) {
|
||||
new Date( str, false, (new RegExp('[0-9]{3}')).test('23 2 34 78 9 09'));
|
||||
}
|
||||
this.toSource();
|
@ -59,9 +59,6 @@ function InLeapYear( t ) {\
|
||||
function DayWithinYear( t ) {\
|
||||
return( Day(t) - DayFromYear(YearFromTime(t)));\
|
||||
");
|
||||
lfcode.push("this.__proto__ = []; \
|
||||
let ( _ = this ) Boolean (\"({ set x([, b, c]) { } })\");\
|
||||
");
|
||||
while (true) {
|
||||
var file = lfcode.shift(); if (file == undefined) { break; }
|
||||
if (file == "evaluate") {
|
||||
|
@ -1,8 +0,0 @@
|
||||
// |jit-test| error:TypeError
|
||||
|
||||
// Binary: cache/js-dbg-32-3fa30b0edd15-linux
|
||||
// Flags:
|
||||
//
|
||||
|
||||
let ([] = 1) 3;
|
||||
let (i) new [i][print[i]];
|
@ -1,8 +0,0 @@
|
||||
// |jit-test| error:Error
|
||||
|
||||
// Binary: cache/js-dbg-64-85e31a4bdd41-linux
|
||||
// Flags:
|
||||
//
|
||||
|
||||
function f(x = let([] = c) 1, ... __call__) {}
|
||||
assertEq(this > f, true);
|
@ -1,10 +0,0 @@
|
||||
// Binary: cache/js-dbg-32-5cca0408a73f-linux
|
||||
// Flags:
|
||||
//
|
||||
|
||||
options("strict_mode");
|
||||
function test(str, arg, result) {
|
||||
var fun = new Function('x', str);
|
||||
var got = fun.toSource();
|
||||
}
|
||||
test('return let (y) x;');
|
@ -1,6 +0,0 @@
|
||||
function f() {
|
||||
let(x) yield x;
|
||||
}
|
||||
var g = f();
|
||||
g.next();
|
||||
g.close();
|
@ -1,16 +0,0 @@
|
||||
function TestCase(n, d, e, a)
|
||||
this.passed = getTestCaseResult(e, a);
|
||||
function getTestCaseResult(expected, actual) {
|
||||
if (actual != actual)
|
||||
return gTestcases;
|
||||
}
|
||||
gczeal(4);
|
||||
try {
|
||||
var TEST_STRING = new String("");
|
||||
new TestCase(null, 0,eval("x = new Boolean(true); x.charCodeAt=String.prototype.charCodeAt;x.charCodeAt(0)") );
|
||||
new TestCase(null, null, 0, eval("x.charCodeAt=String.prototype.charCodeAt;x.charCodeAt(1)"));
|
||||
new TestCase(null, null, 0, eval("x.charCodeAt=String.prototype.charCodeAt;x.charCodeAt(2)"));
|
||||
new TestCase(null, null, 0, eval("x.charCodeAt=String.prototype.charCodeAt;x.charCodeAt(3)"));
|
||||
new TestCase(null, null, Number.NaN, eval("x.charCodeAt=String.prototype.charCodeAt;x.charCodeAt(4)"));
|
||||
new new let (r) (function () {}) ();
|
||||
} catch(e) {}
|
@ -1,14 +0,0 @@
|
||||
// Don't crash or assert.
|
||||
|
||||
(function () {
|
||||
var x;
|
||||
(eval("\
|
||||
(function () {\
|
||||
for (y in [0, 0]) let(a)((function () {\
|
||||
for (w in [0, 0])\
|
||||
x = 0\
|
||||
})());\
|
||||
with({}) {}\
|
||||
})\
|
||||
"))()
|
||||
})()
|
@ -1,2 +0,0 @@
|
||||
// |jit-test| error: SyntaxError;
|
||||
let(y = let(d = []) u, x
|
@ -1,2 +0,0 @@
|
||||
// |jit-test| error: SyntaxError;
|
||||
for (let d in [(0)]) let(b = (let(e) {}), d
|
@ -1,7 +0,0 @@
|
||||
var x = 5;
|
||||
let (x = x)
|
||||
assertEq(x, 5);
|
||||
let (x = eval("x"))
|
||||
assertEq(x, 5);
|
||||
let (x = function () { with ({}) return x; })
|
||||
assertEq(x(), 5);
|
@ -1,4 +0,0 @@
|
||||
var x = 5;
|
||||
(let (x = x) assertEq(x, 5));
|
||||
(let (x = eval("x")) assertEq(x, 5));
|
||||
(let (x = function () { with ({}) return x; }) assertEq(x(), 5));
|
@ -1,6 +0,0 @@
|
||||
function test(s) {
|
||||
eval(s);
|
||||
let (a = ({}).q = 0, x = x)
|
||||
assertEq(x, 5);
|
||||
}
|
||||
test('var x = 5;');
|
@ -1,15 +0,0 @@
|
||||
try { let(x = Date(7), y = let(a = x)("")) {} } catch (e) {}
|
||||
|
||||
try {
|
||||
with({
|
||||
y: Float64Array
|
||||
})
|
||||
for each(let y in [y]) {}
|
||||
} catch (e) {}
|
||||
|
||||
try { test(); } catch (e) {}
|
||||
function test() {
|
||||
try {
|
||||
var result, arguments = 'adddb', arguments;
|
||||
} catch (ex) {}
|
||||
}
|
@ -1 +0,0 @@
|
||||
let (parsesSuccessfully = SyntaxError) function () parsesSuccessfully
|
@ -1,4 +0,0 @@
|
||||
gczeal(4);
|
||||
test();
|
||||
function test()
|
||||
eval("with({}) let(x=[])(function(){x})()");
|
@ -1,20 +0,0 @@
|
||||
function f() {
|
||||
try {} catch (e) {}
|
||||
}
|
||||
function g(code) {
|
||||
function m() {
|
||||
return "(function(){return " + code + "})()"
|
||||
}
|
||||
var codeNestedDeep = m(codeNestedDeep)
|
||||
h(m(code), "same-compartment")
|
||||
h(codeNestedDeep, "same-compartment")
|
||||
}
|
||||
function h(code, globalType) {
|
||||
try {
|
||||
evalcx(code, newGlobal(globalType))
|
||||
} catch (e) {
|
||||
"" + f()
|
||||
}
|
||||
}
|
||||
function p()(function() function() {})
|
||||
g("print(let(x=verifyprebarriers(),q)((x(\"\",l('')))?(\"\"):(\"\")))()")
|
@ -1,26 +0,0 @@
|
||||
var summary = '';
|
||||
function printStatus (msg) {
|
||||
var lines = msg.split ("\n");
|
||||
}
|
||||
evaluate("\
|
||||
function f() {\
|
||||
var ss = [\
|
||||
new f(Int8Array, propertyIsEnumerable, '[let (x = 3, y = 4) x].map(0)')\
|
||||
];\
|
||||
}\
|
||||
try {\
|
||||
f();\
|
||||
} catch (e) {}\
|
||||
gczeal(4);\
|
||||
printStatus (summary);\
|
||||
");
|
||||
evaluate("\
|
||||
function g(n, h) {\
|
||||
var a = f;\
|
||||
if (n <= 0) \
|
||||
return f; \
|
||||
var t = g(n - 1, h);\
|
||||
var r = function(x) { };\
|
||||
}\
|
||||
g(80, f);\
|
||||
");
|
@ -92,7 +92,7 @@ function testThrow(pattern, input) {
|
||||
}
|
||||
testAll(testThrow);
|
||||
|
||||
// XXX: Support for let blocks and expressions will be removed in bug 1023609.
|
||||
// XXX: Support for let blocks will be removed in bug 1023609.
|
||||
// However, they test a special code path in destructuring assignment so having
|
||||
// these tests here for now seems like a good idea.
|
||||
function testLetBlock(pattern, input) {
|
||||
@ -103,13 +103,6 @@ function testLetBlock(pattern, input) {
|
||||
}
|
||||
testAll(testLetBlock);
|
||||
|
||||
function testLetExpression(pattern, input) {
|
||||
return new Function('input',
|
||||
'return (let (' + pattern + ' = input) [a, b, c, d, e, f]);'
|
||||
)(input);
|
||||
}
|
||||
testAll(testLetExpression);
|
||||
|
||||
// test global const
|
||||
const [ca = 1, cb = 2] = [];
|
||||
assertEq(ca, 1);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user