mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Propagate stylesheet principals through to XBL binding loads; streamline load
security checks in the XBL code (so that all the security checks are gated through LoadBindingDocumentInfo). Bug 204140, r=dbaron for the CSS changes, r=sicking for the XBL changes, sr=sicking. In particular, this change allows user stylesheets loaded from local files to link to local files.
This commit is contained in:
parent
65e081a7db
commit
d074804c35
@ -3605,6 +3605,7 @@ nsContentUtils::CheckSecurityBeforeLoad(nsIURI* aURIToLoad,
|
||||
const nsACString& aMimeGuess,
|
||||
nsISupports* aExtra)
|
||||
{
|
||||
// XXXbz do we want to fast-path skin stylesheets loading XBL here somehow?
|
||||
nsCOMPtr<nsIURI> loadingURI;
|
||||
nsresult rv = aLoadingPrincipal->GetURI(getter_AddRefs(loadingURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -3406,8 +3406,22 @@ nsDocument::AddBinding(nsIDOMElement* aContent, const nsAString& aURI)
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Figure out the right principal to use
|
||||
nsCOMPtr<nsIPrincipal> subject;
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
if (secMan) {
|
||||
rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (!subject) {
|
||||
// Fall back to our principal. Or should we fall back to the null
|
||||
// principal? The latter would just mean no binding loads....
|
||||
subject = NodePrincipal();
|
||||
}
|
||||
|
||||
return mBindingManager->AddLayeredBinding(content, uri);
|
||||
return mBindingManager->AddLayeredBinding(content, uri, subject);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -3439,7 +3453,21 @@ nsDocument::LoadBindingDocument(const nsAString& aURI)
|
||||
static_cast<nsIDocument *>(this)->GetBaseURI());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mBindingManager->LoadBindingDocument(this, uri);
|
||||
// Figure out the right principal to use
|
||||
nsCOMPtr<nsIPrincipal> subject;
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
if (secMan) {
|
||||
rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (!subject) {
|
||||
// Fall back to our principal. Or should we fall back to the null
|
||||
// principal? The latter would just mean no binding loads....
|
||||
subject = NodePrincipal();
|
||||
}
|
||||
|
||||
mBindingManager->LoadBindingDocument(this, uri, subject);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -55,10 +55,11 @@ class nsXBLBinding;
|
||||
class nsIXBLDocumentInfo;
|
||||
class nsIURI;
|
||||
class nsIAtom;
|
||||
class nsIPrincipal;
|
||||
|
||||
#define NS_IXBLSERVICE_IID \
|
||||
{ 0xefda61b3, 0x5d04, 0x43b0, \
|
||||
{ 0x98, 0x0c, 0x32, 0x62, 0x72, 0xc8, 0x5c, 0x68 } }
|
||||
{ 0x98b28f4e, 0x698f, 0x4f77, \
|
||||
{ 0xa8, 0x9e, 0x65, 0xf5, 0xd0, 0xde, 0x6a, 0xbf } }
|
||||
|
||||
class nsIXBLService : public nsISupports
|
||||
{
|
||||
@ -66,8 +67,9 @@ public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXBLSERVICE_IID)
|
||||
|
||||
// This function loads a particular XBL file and installs all of the bindings
|
||||
// onto the element.
|
||||
NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFlag,
|
||||
// onto the element. aOriginPrincipal must not be null here.
|
||||
NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal, PRBool aAugmentFlag,
|
||||
nsXBLBinding** aBinding, PRBool* aResolveStyle) = 0;
|
||||
|
||||
// Indicates whether or not a binding is fully loaded.
|
||||
@ -76,10 +78,15 @@ public:
|
||||
// Retrieves our base class (e.g., tells us what type of frame and content node to build)
|
||||
NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult) = 0;
|
||||
|
||||
// This method checks the hashtable and then calls FetchBindingDocument on a miss.
|
||||
NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
|
||||
// This method checks the hashtable and then calls FetchBindingDocument on a
|
||||
// miss. aOriginPrincipal or aBoundDocument may be null to bypass security
|
||||
// checks.
|
||||
NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement,
|
||||
nsIDocument* aBoundDocument,
|
||||
nsIURI* aBindingURI,
|
||||
PRBool aForceSyncLoad, nsIXBLDocumentInfo** aResult) = 0;
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
PRBool aForceSyncLoad,
|
||||
nsIXBLDocumentInfo** aResult) = 0;
|
||||
|
||||
// Hooks up the global key event handlers to the document root.
|
||||
NS_IMETHOD AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)=0;
|
||||
|
@ -690,7 +690,8 @@ nsBindingManager::GetSingleInsertionPoint(nsIContent* aParent,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBindingManager::AddLayeredBinding(nsIContent* aContent, nsIURI* aURL)
|
||||
nsBindingManager::AddLayeredBinding(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal)
|
||||
{
|
||||
// First we need to load our binding.
|
||||
nsresult rv;
|
||||
@ -702,8 +703,8 @@ nsBindingManager::AddLayeredBinding(nsIContent* aContent, nsIURI* aURL)
|
||||
// Load the bindings.
|
||||
nsRefPtr<nsXBLBinding> binding;
|
||||
PRBool dummy;
|
||||
xblService->LoadBindings(aContent, aURL, PR_TRUE, getter_AddRefs(binding),
|
||||
&dummy);
|
||||
xblService->LoadBindings(aContent, aURL, aOriginPrincipal, PR_TRUE,
|
||||
getter_AddRefs(binding), &dummy);
|
||||
if (binding) {
|
||||
AddToAttachedQueue(binding);
|
||||
ProcessAttachedQueue();
|
||||
@ -766,7 +767,8 @@ nsBindingManager::RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL)
|
||||
|
||||
nsresult
|
||||
nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc,
|
||||
nsIURI* aURL)
|
||||
nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal)
|
||||
{
|
||||
NS_PRECONDITION(aURL, "Must have a URI to load!");
|
||||
|
||||
@ -780,7 +782,8 @@ nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc,
|
||||
// Load the binding doc.
|
||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||
xblService->LoadBindingDocumentInfo(nsnull, aBoundDoc, aURL,
|
||||
PR_TRUE, getter_AddRefs(info));
|
||||
aOriginPrincipal, PR_TRUE,
|
||||
getter_AddRefs(info));
|
||||
if (!info)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -62,6 +62,7 @@ class nsXBLBinding;
|
||||
template<class E> class nsRefPtr;
|
||||
typedef nsTArray<nsRefPtr<nsXBLBinding> > nsBindingList;
|
||||
template<class T> class nsRunnableMethod;
|
||||
class nsIPrincipal;
|
||||
|
||||
class nsBindingManager : public nsIMutationObserver
|
||||
{
|
||||
@ -154,9 +155,11 @@ public:
|
||||
nsIContent* GetSingleInsertionPoint(nsIContent* aParent, PRUint32* aIndex,
|
||||
PRBool* aMultipleInsertionPoints);
|
||||
|
||||
nsresult AddLayeredBinding(nsIContent* aContent, nsIURI* aURL);
|
||||
nsresult AddLayeredBinding(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal);
|
||||
nsresult RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL);
|
||||
nsresult LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL);
|
||||
nsresult LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal);
|
||||
|
||||
nsresult AddToAttachedQueue(nsXBLBinding* aBinding);
|
||||
void ProcessAttachedQueue();
|
||||
|
@ -486,9 +486,12 @@ nsXBLService::~nsXBLService(void)
|
||||
// This function loads a particular XBL file and installs all of the bindings
|
||||
// onto the element.
|
||||
NS_IMETHODIMP
|
||||
nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFlag,
|
||||
nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal, PRBool aAugmentFlag,
|
||||
nsXBLBinding** aBinding, PRBool* aResolveStyle)
|
||||
{
|
||||
{
|
||||
NS_PRECONDITION(aOriginPrincipal, "Must have an origin principal");
|
||||
|
||||
*aBinding = nsnull;
|
||||
*aResolveStyle = PR_FALSE;
|
||||
|
||||
@ -522,26 +525,10 @@ nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFl
|
||||
}
|
||||
}
|
||||
|
||||
// Security check - Enforce same-origin policy, except to chrome.
|
||||
// We have to be careful to not pass aContent as the context here.
|
||||
// Otherwise, if there is a JS-implemented content policy, we will attempt
|
||||
// to wrap the content node, which will try to load XBL bindings for it, if
|
||||
// any. Since we're not done loading this binding yet, that will reenter
|
||||
// this method and we'll end up creating a binding and then immediately
|
||||
// clobbering it in our table. That makes things very confused, leading to
|
||||
// misbehavior and crashes.
|
||||
rv = nsContentUtils::CheckSecurityBeforeLoad(aURL,
|
||||
document->NodePrincipal(),
|
||||
nsIScriptSecurityManager::ALLOW_CHROME,
|
||||
PR_TRUE,
|
||||
nsIContentPolicy::TYPE_XBL,
|
||||
document);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool ready;
|
||||
nsRefPtr<nsXBLBinding> newBinding;
|
||||
if (NS_FAILED(rv = GetBinding(aContent, aURL, PR_FALSE, &ready,
|
||||
getter_AddRefs(newBinding)))) {
|
||||
if (NS_FAILED(rv = GetBinding(aContent, aURL, PR_FALSE, aOriginPrincipal,
|
||||
&ready, getter_AddRefs(newBinding)))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -757,23 +744,25 @@ NS_IMETHODIMP nsXBLService::BindingReady(nsIContent* aBoundElement,
|
||||
nsIURI* aURI,
|
||||
PRBool* aIsReady)
|
||||
{
|
||||
return GetBinding(aBoundElement, aURI, PR_TRUE, aIsReady, nsnull);
|
||||
// Don't do a security check here; we know this binding is set to go.
|
||||
return GetBinding(aBoundElement, aURI, PR_TRUE, nsnull, aIsReady, nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||
PRBool aPeekOnly, PRBool* aIsReady,
|
||||
nsXBLBinding** aResult)
|
||||
PRBool aPeekOnly, nsIPrincipal* aOriginPrincipal,
|
||||
PRBool* aIsReady, nsXBLBinding** aResult)
|
||||
{
|
||||
// More than 6 binding URIs are rare, see bug 55070 comment 18.
|
||||
nsTArray<nsIURI*> uris(6);
|
||||
return GetBinding(aBoundElement, aURI, aPeekOnly, aIsReady, aResult, uris);
|
||||
return GetBinding(aBoundElement, aURI, aPeekOnly, aOriginPrincipal, aIsReady,
|
||||
aResult, uris);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||
PRBool aPeekOnly, PRBool* aIsReady,
|
||||
nsXBLBinding** aResult,
|
||||
PRBool aPeekOnly, nsIPrincipal* aOriginPrincipal,
|
||||
PRBool* aIsReady, nsXBLBinding** aResult,
|
||||
nsTArray<nsIURI*>& aDontExtendURIs)
|
||||
{
|
||||
NS_ASSERTION(aPeekOnly || aResult,
|
||||
@ -796,8 +785,11 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||
nsCOMPtr<nsIDocument> boundDocument = aBoundElement->GetOwnerDoc();
|
||||
|
||||
nsCOMPtr<nsIXBLDocumentInfo> docInfo;
|
||||
LoadBindingDocumentInfo(aBoundElement, boundDocument, aURI, PR_FALSE,
|
||||
getter_AddRefs(docInfo));
|
||||
nsresult rv = LoadBindingDocumentInfo(aBoundElement, boundDocument, aURI,
|
||||
aOriginPrincipal,
|
||||
PR_FALSE, getter_AddRefs(docInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!docInfo)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
@ -830,9 +822,11 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||
PRBool hasBase = protoBinding->HasBasePrototype();
|
||||
nsXBLPrototypeBinding* baseProto = protoBinding->GetBasePrototype();
|
||||
if (baseProto) {
|
||||
nsresult rv = GetBinding(aBoundElement, baseProto->BindingURI(), aPeekOnly,
|
||||
aIsReady, getter_AddRefs(baseBinding),
|
||||
aDontExtendURIs);
|
||||
// Use the NodePrincipal() of the <binding> element in question
|
||||
// for the security check.
|
||||
rv = GetBinding(aBoundElement, baseProto->BindingURI(), aPeekOnly,
|
||||
child->NodePrincipal(), aIsReady,
|
||||
getter_AddRefs(baseBinding), aDontExtendURIs);
|
||||
if (NS_FAILED(rv))
|
||||
return rv; // We aren't ready yet.
|
||||
}
|
||||
@ -899,10 +893,9 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||
// Look up the prefix.
|
||||
// We have a base class binding. Load it right now.
|
||||
nsCOMPtr<nsIURI> bindingURI;
|
||||
nsresult rv =
|
||||
NS_NewURI(getter_AddRefs(bindingURI), value,
|
||||
doc->GetDocumentCharacterSet().get(),
|
||||
doc->GetBaseURI());
|
||||
rv = NS_NewURI(getter_AddRefs(bindingURI), value,
|
||||
doc->GetDocumentCharacterSet().get(),
|
||||
doc->GetBaseURI());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 count = aDontExtendURIs.Length();
|
||||
@ -926,7 +919,10 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||
}
|
||||
}
|
||||
|
||||
rv = GetBinding(aBoundElement, bindingURI, aPeekOnly, aIsReady,
|
||||
// Use the NodePrincipal() of the <binding> element in question
|
||||
// for the security check.
|
||||
rv = GetBinding(aBoundElement, bindingURI, aPeekOnly,
|
||||
child->NodePrincipal(), aIsReady,
|
||||
getter_AddRefs(baseBinding), aDontExtendURIs);
|
||||
if (NS_FAILED(rv))
|
||||
return rv; // Binding not yet ready or an error occurred.
|
||||
@ -960,15 +956,26 @@ NS_IMETHODIMP
|
||||
nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement,
|
||||
nsIDocument* aBoundDocument,
|
||||
nsIURI* aBindingURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
PRBool aForceSyncLoad,
|
||||
nsIXBLDocumentInfo** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aBindingURI, "Must have a binding URI");
|
||||
NS_PRECONDITION(!aOriginPrincipal || aBoundDocument,
|
||||
"If we're doing a security check, we better have a document!");
|
||||
|
||||
nsresult rv;
|
||||
if (aBoundDocument) {
|
||||
if (aOriginPrincipal) {
|
||||
// Security check - Enforce same-origin policy, except to chrome.
|
||||
// We have to be careful to not pass aContent as the context here.
|
||||
// Otherwise, if there is a JS-implemented content policy, we will attempt
|
||||
// to wrap the content node, which will try to load XBL bindings for it, if
|
||||
// any. Since we're not done loading this binding yet, that will reenter
|
||||
// this method and we'll end up creating a binding and then immediately
|
||||
// clobbering it in our table. That makes things very confused, leading to
|
||||
// misbehavior and crashes.
|
||||
rv = nsContentUtils::
|
||||
CheckSecurityBeforeLoad(aBindingURI, aBoundDocument->NodePrincipal(),
|
||||
CheckSecurityBeforeLoad(aBindingURI, aOriginPrincipal,
|
||||
nsIScriptSecurityManager::ALLOW_CHROME,
|
||||
PR_TRUE,
|
||||
nsIContentPolicy::TYPE_XBL,
|
||||
|
@ -65,8 +65,9 @@ class nsXBLService : public nsIXBLService,
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// This function loads a particular XBL file and installs all of the bindings
|
||||
// onto the element.
|
||||
NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFlag,
|
||||
// onto the element. aOriginPrincipal must not be null here.
|
||||
NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal, PRBool aAugmentFlag,
|
||||
nsXBLBinding** aBinding, PRBool* aResolveStyle);
|
||||
|
||||
// Indicates whether or not a binding is fully loaded.
|
||||
@ -75,10 +76,15 @@ class nsXBLService : public nsIXBLService,
|
||||
// Gets the object's base class type.
|
||||
NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult);
|
||||
|
||||
// This method checks the hashtable and then calls FetchBindingDocument on a miss.
|
||||
NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
|
||||
// This method checks the hashtable and then calls FetchBindingDocument on a
|
||||
// miss. aOriginPrincipal or aBoundDocument may be null to bypass security
|
||||
// checks.
|
||||
NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement,
|
||||
nsIDocument* aBoundDocument,
|
||||
nsIURI* aBindingURI,
|
||||
PRBool aForceSyncLoad, nsIXBLDocumentInfo** aResult);
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
PRBool aForceSyncLoad,
|
||||
nsIXBLDocumentInfo** aResult);
|
||||
|
||||
// Used by XUL key bindings and for window XBL.
|
||||
NS_IMETHOD AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget);
|
||||
@ -108,8 +114,8 @@ protected:
|
||||
* This method calls the one below with an empty |aDontExtendURIs| array.
|
||||
*/
|
||||
nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||
PRBool aPeekFlag, PRBool* aIsReady,
|
||||
nsXBLBinding** aResult);
|
||||
PRBool aPeekFlag, nsIPrincipal* aOriginPrincipal,
|
||||
PRBool* aIsReady, nsXBLBinding** aResult);
|
||||
|
||||
/**
|
||||
* This method loads a binding doc and then builds the specific binding
|
||||
@ -124,10 +130,13 @@ protected:
|
||||
* element. If a binding extends any of these then further loading
|
||||
* is aborted (because it would lead to the binding extending itself)
|
||||
* and NS_ERROR_ILLEGAL_VALUE is returned.
|
||||
*
|
||||
* @note This method always calls LoadBindingDocumentInfo(), so it's
|
||||
* enough to funnel all security checks through that function.
|
||||
*/
|
||||
nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||
PRBool aPeekFlag, PRBool* aIsReady,
|
||||
nsXBLBinding** aResult,
|
||||
PRBool aPeekFlag, nsIPrincipal* aOriginPrincipal,
|
||||
PRBool* aIsReady, nsXBLBinding** aResult,
|
||||
nsTArray<nsIURI*>& aDontExtendURIs);
|
||||
|
||||
// MEMBER VARIABLES
|
||||
|
@ -119,6 +119,7 @@ void nsXBLSpecialDocInfo::LoadDocInfo()
|
||||
}
|
||||
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
|
||||
bindingURI,
|
||||
nsnull,
|
||||
PR_TRUE,
|
||||
getter_AddRefs(mHTMLBindings));
|
||||
|
||||
@ -132,6 +133,7 @@ void nsXBLSpecialDocInfo::LoadDocInfo()
|
||||
|
||||
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
|
||||
bindingURI,
|
||||
nsnull,
|
||||
PR_TRUE,
|
||||
getter_AddRefs(mUserHTMLBindings));
|
||||
}
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "xptcall.h"
|
||||
#include "prprf.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsCSSValue.h"
|
||||
|
||||
// JavaScript includes
|
||||
#include "jsapi.h"
|
||||
@ -6954,7 +6955,7 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
nsnull);
|
||||
NS_ENSURE_TRUE(sc, NS_ERROR_FAILURE);
|
||||
|
||||
nsIURI *bindingURL = sc->GetStyleDisplay()->mBinding;
|
||||
nsCSSValue::URL *bindingURL = sc->GetStyleDisplay()->mBinding;
|
||||
if (!bindingURL) {
|
||||
// No binding, nothing left to do here.
|
||||
return NS_OK;
|
||||
@ -6966,7 +6967,8 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
|
||||
NS_ENSURE_TRUE(xblService, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
xblService->LoadBindings(content, bindingURL, PR_FALSE,
|
||||
xblService->LoadBindings(content, bindingURL->mURI,
|
||||
bindingURL->mOriginPrincipal, PR_FALSE,
|
||||
getter_AddRefs(binding), &dummy);
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,7 @@ REQUIRES = xpcom \
|
||||
windowwatcher \
|
||||
accessibility \
|
||||
shistory \
|
||||
caps \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_ENABLE_CAIRO_GFX
|
||||
|
@ -117,7 +117,7 @@
|
||||
#include "nsImageFrame.h"
|
||||
#include "nsIObjectLoadingContent.h"
|
||||
#include "nsContentErrors.h"
|
||||
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
|
||||
#include "nsBox.h"
|
||||
@ -4209,8 +4209,10 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsRefPtr<nsXBLBinding> binding;
|
||||
rv = xblService->LoadBindings(aDocElement, display->mBinding, PR_FALSE,
|
||||
getter_AddRefs(binding), &resolveStyle);
|
||||
rv = xblService->LoadBindings(aDocElement, display->mBinding->mURI,
|
||||
display->mBinding->mOriginPrincipal,
|
||||
PR_FALSE, getter_AddRefs(binding),
|
||||
&resolveStyle);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_OK; // Binding will load asynchronously.
|
||||
|
||||
@ -7460,8 +7462,9 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsFrameConstructorState& aState,
|
||||
if (!xblService)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = xblService->LoadBindings(aContent, display->mBinding, PR_FALSE,
|
||||
getter_AddRefs(binding.mBinding),
|
||||
rv = xblService->LoadBindings(aContent, display->mBinding->mURI,
|
||||
display->mBinding->mOriginPrincipal,
|
||||
PR_FALSE, getter_AddRefs(binding.mBinding),
|
||||
&resolveStyle);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_OK;
|
||||
|
@ -232,6 +232,14 @@ public:
|
||||
mValue.mURL->mURI : mValue.mImage->mURI;
|
||||
}
|
||||
|
||||
URL* GetURLStructValue() const
|
||||
{
|
||||
// Not allowing this for Image values, because if the caller takes
|
||||
// a ref to them they won't be able to delete them properly.
|
||||
NS_ASSERTION(mUnit == eCSSUnit_URL, "not a URL value");
|
||||
return mValue.mURL;
|
||||
}
|
||||
|
||||
const PRUnichar* GetOriginalURLValue() const
|
||||
{
|
||||
NS_ASSERTION(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
|
||||
@ -388,6 +396,12 @@ public:
|
||||
|
||||
NS_HIDDEN_(PRBool) operator==(const URL& aOther) const;
|
||||
|
||||
// URIEquals only compares URIs and principals (unlike operator==, which
|
||||
// also compares the original strings). URIEquals also assumes that the
|
||||
// mURI member of both URL objects is non-null. Do NOT call this method
|
||||
// unless you're sure this is the case.
|
||||
NS_HIDDEN_(PRBool) URIEquals(const URL& aOther) const;
|
||||
|
||||
nsCOMPtr<nsIURI> mURI; // null == invalid URL
|
||||
nsStringBuffer* mString; // Could use nsRefPtr, but it'd add useless
|
||||
// null-checks; this is never null.
|
||||
|
@ -431,7 +431,7 @@ nsComputedDOMStyle::GetBinding(nsIDOMCSSValue** aValue)
|
||||
const nsStyleDisplay* display = GetStyleDisplay();
|
||||
|
||||
if (display->mBinding) {
|
||||
val->SetURI(display->mBinding);
|
||||
val->SetURI(display->mBinding->mURI);
|
||||
} else {
|
||||
val->SetIdent(nsGkAtoms::none);
|
||||
}
|
||||
|
@ -2728,7 +2728,14 @@ nsRuleNode::ComputeDisplayData(nsStyleStruct* aStartStruct,
|
||||
|
||||
// binding: url, none, inherit
|
||||
if (eCSSUnit_URL == displayData.mBinding.GetUnit()) {
|
||||
display->mBinding = displayData.mBinding.GetURLValue();
|
||||
nsCSSValue::URL* url = displayData.mBinding.GetURLStructValue();
|
||||
NS_ASSERTION(url, "What's going on here?");
|
||||
|
||||
if (NS_LIKELY(url->mURI)) {
|
||||
display->mBinding = url;
|
||||
} else {
|
||||
display->mBinding = nsnull;
|
||||
}
|
||||
}
|
||||
else if (eCSSUnit_None == displayData.mBinding.GetUnit()) {
|
||||
display->mBinding = nsnull;
|
||||
|
@ -551,6 +551,15 @@ public:
|
||||
Assign("[none]");
|
||||
}
|
||||
}
|
||||
|
||||
URICString(nsCSSValue::URL* aURI) {
|
||||
if (aURI) {
|
||||
NS_ASSERTION(aURI->mURI, "Must have URI here!");
|
||||
aURI->mURI->GetSpec(*this);
|
||||
} else {
|
||||
Assign("[none]");
|
||||
}
|
||||
}
|
||||
|
||||
URICString& operator=(const URICString& aOther) {
|
||||
Assign(aOther);
|
||||
|
@ -76,6 +76,12 @@ static PRBool EqualURIs(nsIURI *aURI1, nsIURI *aURI2)
|
||||
eq);
|
||||
}
|
||||
|
||||
static PRBool EqualURIs(nsCSSValue::URL *aURI1, nsCSSValue::URL *aURI2)
|
||||
{
|
||||
return aURI1 == aURI2 || // handle null==null, and optimize
|
||||
(aURI1 && aURI2 && aURI1->URIEquals(*aURI2));
|
||||
}
|
||||
|
||||
static PRBool EqualImages(imgIRequest *aImage1, imgIRequest* aImage2)
|
||||
{
|
||||
if (aImage1 == aImage2) {
|
||||
|
@ -760,8 +760,10 @@ struct nsStyleDisplay : public nsStyleStruct {
|
||||
#ifdef DEBUG
|
||||
static nsChangeHint MaxDifference();
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIURI> mBinding; // [reset]
|
||||
|
||||
// We guarantee that if mBinding is non-null, so are mBinding->mURI and
|
||||
// mBinding->mOriginPrincipal.
|
||||
nsRefPtr<nsCSSValue::URL> mBinding; // [reset]
|
||||
#if 0
|
||||
// XXX This is how it is defined in the CSS2 spec, but the errata
|
||||
// changed it to be consistent with the positioning draft and how
|
||||
|
Loading…
Reference in New Issue
Block a user