dom/xbl/nsXBLResourceLoader.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsTArray.h"
michael@0 7 #include "nsString.h"
michael@0 8 #include "nsCSSStyleSheet.h"
michael@0 9 #include "nsIStyleRuleProcessor.h"
michael@0 10 #include "nsIDocument.h"
michael@0 11 #include "nsIContent.h"
michael@0 12 #include "nsIPresShell.h"
michael@0 13 #include "nsXBLService.h"
michael@0 14 #include "nsIServiceManager.h"
michael@0 15 #include "nsXBLResourceLoader.h"
michael@0 16 #include "nsXBLPrototypeResources.h"
michael@0 17 #include "nsIDocumentObserver.h"
michael@0 18 #include "imgILoader.h"
michael@0 19 #include "imgRequestProxy.h"
michael@0 20 #include "mozilla/css/Loader.h"
michael@0 21 #include "nsIURI.h"
michael@0 22 #include "nsNetUtil.h"
michael@0 23 #include "nsGkAtoms.h"
michael@0 24 #include "nsFrameManager.h"
michael@0 25 #include "nsStyleContext.h"
michael@0 26 #include "nsXBLPrototypeBinding.h"
michael@0 27 #include "nsCSSRuleProcessor.h"
michael@0 28 #include "nsContentUtils.h"
michael@0 29 #include "nsStyleSet.h"
michael@0 30 #include "nsIScriptSecurityManager.h"
michael@0 31
michael@0 32 NS_IMPL_CYCLE_COLLECTION(nsXBLResourceLoader, mBoundElements)
michael@0 33
michael@0 34 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLResourceLoader)
michael@0 35 NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
michael@0 36 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 37 NS_INTERFACE_MAP_END
michael@0 38
michael@0 39 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXBLResourceLoader)
michael@0 40 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXBLResourceLoader)
michael@0 41
michael@0 42 struct nsXBLResource
michael@0 43 {
michael@0 44 nsXBLResource* mNext;
michael@0 45 nsIAtom* mType;
michael@0 46 nsString mSrc;
michael@0 47
michael@0 48 nsXBLResource(nsIAtom* aType, const nsAString& aSrc)
michael@0 49 {
michael@0 50 MOZ_COUNT_CTOR(nsXBLResource);
michael@0 51 mNext = nullptr;
michael@0 52 mType = aType;
michael@0 53 mSrc = aSrc;
michael@0 54 }
michael@0 55
michael@0 56 ~nsXBLResource()
michael@0 57 {
michael@0 58 MOZ_COUNT_DTOR(nsXBLResource);
michael@0 59 NS_CONTENT_DELETE_LIST_MEMBER(nsXBLResource, this, mNext);
michael@0 60 }
michael@0 61 };
michael@0 62
michael@0 63 nsXBLResourceLoader::nsXBLResourceLoader(nsXBLPrototypeBinding* aBinding,
michael@0 64 nsXBLPrototypeResources* aResources)
michael@0 65 :mBinding(aBinding),
michael@0 66 mResources(aResources),
michael@0 67 mResourceList(nullptr),
michael@0 68 mLastResource(nullptr),
michael@0 69 mLoadingResources(false),
michael@0 70 mInLoadResourcesFunc(false),
michael@0 71 mPendingSheets(0)
michael@0 72 {
michael@0 73 }
michael@0 74
michael@0 75 nsXBLResourceLoader::~nsXBLResourceLoader()
michael@0 76 {
michael@0 77 delete mResourceList;
michael@0 78 }
michael@0 79
michael@0 80 void
michael@0 81 nsXBLResourceLoader::LoadResources(bool* aResult)
michael@0 82 {
michael@0 83 mInLoadResourcesFunc = true;
michael@0 84
michael@0 85 if (mLoadingResources) {
michael@0 86 *aResult = (mPendingSheets == 0);
michael@0 87 mInLoadResourcesFunc = false;
michael@0 88 return;
michael@0 89 }
michael@0 90
michael@0 91 mLoadingResources = true;
michael@0 92 *aResult = true;
michael@0 93
michael@0 94 // Declare our loaders.
michael@0 95 nsCOMPtr<nsIDocument> doc = mBinding->XBLDocumentInfo()->GetDocument();
michael@0 96
michael@0 97 mozilla::css::Loader* cssLoader = doc->CSSLoader();
michael@0 98 nsIURI *docURL = doc->GetDocumentURI();
michael@0 99 nsIPrincipal* docPrincipal = doc->NodePrincipal();
michael@0 100
michael@0 101 nsCOMPtr<nsIURI> url;
michael@0 102
michael@0 103 for (nsXBLResource* curr = mResourceList; curr; curr = curr->mNext) {
michael@0 104 if (curr->mSrc.IsEmpty())
michael@0 105 continue;
michael@0 106
michael@0 107 if (NS_FAILED(NS_NewURI(getter_AddRefs(url), curr->mSrc,
michael@0 108 doc->GetDocumentCharacterSet().get(), docURL)))
michael@0 109 continue;
michael@0 110
michael@0 111 if (curr->mType == nsGkAtoms::image) {
michael@0 112 if (!nsContentUtils::CanLoadImage(url, doc, doc, docPrincipal)) {
michael@0 113 // We're not permitted to load this image, move on...
michael@0 114 continue;
michael@0 115 }
michael@0 116
michael@0 117 // Now kick off the image load...
michael@0 118 // Passing nullptr for pretty much everything -- cause we don't care!
michael@0 119 // XXX: initialDocumentURI is nullptr!
michael@0 120 nsRefPtr<imgRequestProxy> req;
michael@0 121 nsContentUtils::LoadImage(url, doc, docPrincipal, docURL, nullptr,
michael@0 122 nsIRequest::LOAD_BACKGROUND, EmptyString(),
michael@0 123 getter_AddRefs(req));
michael@0 124 }
michael@0 125 else if (curr->mType == nsGkAtoms::stylesheet) {
michael@0 126 // Kick off the load of the stylesheet.
michael@0 127
michael@0 128 // Always load chrome synchronously
michael@0 129 // XXXbz should that still do a content policy check?
michael@0 130 bool chrome;
michael@0 131 nsresult rv;
michael@0 132 if (NS_SUCCEEDED(url->SchemeIs("chrome", &chrome)) && chrome)
michael@0 133 {
michael@0 134 rv = nsContentUtils::GetSecurityManager()->
michael@0 135 CheckLoadURIWithPrincipal(docPrincipal, url,
michael@0 136 nsIScriptSecurityManager::ALLOW_CHROME);
michael@0 137 if (NS_SUCCEEDED(rv)) {
michael@0 138 nsRefPtr<nsCSSStyleSheet> sheet;
michael@0 139 rv = cssLoader->LoadSheetSync(url, getter_AddRefs(sheet));
michael@0 140 NS_ASSERTION(NS_SUCCEEDED(rv), "Load failed!!!");
michael@0 141 if (NS_SUCCEEDED(rv))
michael@0 142 {
michael@0 143 rv = StyleSheetLoaded(sheet, false, NS_OK);
michael@0 144 NS_ASSERTION(NS_SUCCEEDED(rv), "Processing the style sheet failed!!!");
michael@0 145 }
michael@0 146 }
michael@0 147 }
michael@0 148 else
michael@0 149 {
michael@0 150 rv = cssLoader->LoadSheet(url, docPrincipal, EmptyCString(), this);
michael@0 151 if (NS_SUCCEEDED(rv))
michael@0 152 ++mPendingSheets;
michael@0 153 }
michael@0 154 }
michael@0 155 }
michael@0 156
michael@0 157 *aResult = (mPendingSheets == 0);
michael@0 158 mInLoadResourcesFunc = false;
michael@0 159
michael@0 160 // Destroy our resource list.
michael@0 161 delete mResourceList;
michael@0 162 mResourceList = nullptr;
michael@0 163 }
michael@0 164
michael@0 165 // nsICSSLoaderObserver
michael@0 166 NS_IMETHODIMP
michael@0 167 nsXBLResourceLoader::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
michael@0 168 bool aWasAlternate,
michael@0 169 nsresult aStatus)
michael@0 170 {
michael@0 171 if (!mResources) {
michael@0 172 // Our resources got destroyed -- just bail out
michael@0 173 return NS_OK;
michael@0 174 }
michael@0 175
michael@0 176 mResources->mStyleSheetList.AppendElement(aSheet);
michael@0 177
michael@0 178 if (!mInLoadResourcesFunc)
michael@0 179 mPendingSheets--;
michael@0 180
michael@0 181 if (mPendingSheets == 0) {
michael@0 182 // All stylesheets are loaded.
michael@0 183 mResources->mRuleProcessor =
michael@0 184 new nsCSSRuleProcessor(mResources->mStyleSheetList,
michael@0 185 nsStyleSet::eDocSheet,
michael@0 186 nullptr);
michael@0 187
michael@0 188 // XXX Check for mPendingScripts when scripts also come online.
michael@0 189 if (!mInLoadResourcesFunc)
michael@0 190 NotifyBoundElements();
michael@0 191 }
michael@0 192 return NS_OK;
michael@0 193 }
michael@0 194
michael@0 195 void
michael@0 196 nsXBLResourceLoader::AddResource(nsIAtom* aResourceType, const nsAString& aSrc)
michael@0 197 {
michael@0 198 nsXBLResource* res = new nsXBLResource(aResourceType, aSrc);
michael@0 199 if (!res)
michael@0 200 return;
michael@0 201
michael@0 202 if (!mResourceList)
michael@0 203 mResourceList = res;
michael@0 204 else
michael@0 205 mLastResource->mNext = res;
michael@0 206
michael@0 207 mLastResource = res;
michael@0 208 }
michael@0 209
michael@0 210 void
michael@0 211 nsXBLResourceLoader::AddResourceListener(nsIContent* aBoundElement)
michael@0 212 {
michael@0 213 if (aBoundElement) {
michael@0 214 mBoundElements.AppendObject(aBoundElement);
michael@0 215 }
michael@0 216 }
michael@0 217
michael@0 218 void
michael@0 219 nsXBLResourceLoader::NotifyBoundElements()
michael@0 220 {
michael@0 221 nsXBLService* xblService = nsXBLService::GetInstance();
michael@0 222 if (!xblService)
michael@0 223 return;
michael@0 224
michael@0 225 nsIURI* bindingURI = mBinding->BindingURI();
michael@0 226
michael@0 227 uint32_t eltCount = mBoundElements.Count();
michael@0 228 for (uint32_t j = 0; j < eltCount; j++) {
michael@0 229 nsCOMPtr<nsIContent> content = mBoundElements.ObjectAt(j);
michael@0 230
michael@0 231 bool ready = false;
michael@0 232 xblService->BindingReady(content, bindingURI, &ready);
michael@0 233
michael@0 234 if (ready) {
michael@0 235 // We need the document to flush out frame construction and
michael@0 236 // such, so we want to use the current document.
michael@0 237 nsIDocument* doc = content->GetCurrentDoc();
michael@0 238
michael@0 239 if (doc) {
michael@0 240 // Flush first to make sure we can get the frame for content
michael@0 241 doc->FlushPendingNotifications(Flush_Frames);
michael@0 242
michael@0 243 // If |content| is (in addition to having binding |mBinding|)
michael@0 244 // also a descendant of another element with binding |mBinding|,
michael@0 245 // then we might have just constructed it due to the
michael@0 246 // notification of its parent. (We can know about both if the
michael@0 247 // binding loads were triggered from the DOM rather than frame
michael@0 248 // construction.) So we have to check both whether the element
michael@0 249 // has a primary frame and whether it's in the undisplayed map
michael@0 250 // before sending a ContentInserted notification, or bad things
michael@0 251 // will happen.
michael@0 252 nsIPresShell *shell = doc->GetShell();
michael@0 253 if (shell) {
michael@0 254 nsIFrame* childFrame = content->GetPrimaryFrame();
michael@0 255 if (!childFrame) {
michael@0 256 // Check to see if it's in the undisplayed content map.
michael@0 257 nsStyleContext* sc =
michael@0 258 shell->FrameManager()->GetUndisplayedContent(content);
michael@0 259
michael@0 260 if (!sc) {
michael@0 261 shell->RecreateFramesFor(content);
michael@0 262 }
michael@0 263 }
michael@0 264 }
michael@0 265
michael@0 266 // Flush again
michael@0 267 // XXXbz why is this needed?
michael@0 268 doc->FlushPendingNotifications(Flush_ContentAndNotify);
michael@0 269 }
michael@0 270 }
michael@0 271 }
michael@0 272
michael@0 273 // Clear out the whole array.
michael@0 274 mBoundElements.Clear();
michael@0 275
michael@0 276 // Delete ourselves.
michael@0 277 mResources->ClearLoader();
michael@0 278 }
michael@0 279
michael@0 280 nsresult
michael@0 281 nsXBLResourceLoader::Write(nsIObjectOutputStream* aStream)
michael@0 282 {
michael@0 283 nsresult rv;
michael@0 284
michael@0 285 for (nsXBLResource* curr = mResourceList; curr; curr = curr->mNext) {
michael@0 286 if (curr->mType == nsGkAtoms::image)
michael@0 287 rv = aStream->Write8(XBLBinding_Serialize_Image);
michael@0 288 else if (curr->mType == nsGkAtoms::stylesheet)
michael@0 289 rv = aStream->Write8(XBLBinding_Serialize_Stylesheet);
michael@0 290 else
michael@0 291 continue;
michael@0 292
michael@0 293 NS_ENSURE_SUCCESS(rv, rv);
michael@0 294
michael@0 295 rv = aStream->WriteWStringZ(curr->mSrc.get());
michael@0 296 NS_ENSURE_SUCCESS(rv, rv);
michael@0 297 }
michael@0 298
michael@0 299 return NS_OK;
michael@0 300 }

mercurial