Sat, 03 Jan 2015 20:18:00 +0100
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 | } |