mirror of
https://github.com/roytam1/mozilla45esr.git
synced 2026-05-26 15:39:48 +00:00
import changes from tenfourfox:
- instrument script loads for debugging (f71ffd52a) - #541: temporary workaround for infinite errors on github (8c40900ac) - #431: M1385165 (5b2393042) - #575: high-level disable only (b321cdff4) - additional hosts for adblock (a891fb6c0) - #370: M976073 minus tele with backbugs (20c8bb414) - mark JS sites needing flips for confidence testing; #375 (M1275282) (2eda8a4d4) - [partly imported] closes #577: add back general.useragent.override.* (a8f4daa76) - remove google safebrowsing URLs since they are dead (d89529ac0) - #579: M1218456 +backbugs -nsILinkHandler removal, with changes for 45 (5e0cd430c) - #375: M1352323 M1038099 (eb6f62648) - #375: M1334642 +efficiency patch (1d2b06b10) - [with additions] closes #375: M1353187 (partial) (45c95c3da) - [with modification] #578: M1580320 M1584170 (216c8ff73) - #578: update pins, preload, TLDs (46acdd518)
This commit is contained in:
@@ -957,9 +957,9 @@ pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
|
||||
pref("browser.safebrowsing.debug", false);
|
||||
|
||||
pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
|
||||
pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
|
||||
pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
|
||||
pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
|
||||
pref("browser.safebrowsing.provider.google.updateURL", "");
|
||||
pref("browser.safebrowsing.provider.google.gethashURL", "");
|
||||
pref("browser.safebrowsing.provider.google.reportURL", "");
|
||||
|
||||
pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
|
||||
pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
|
||||
|
||||
@@ -604,7 +604,7 @@ var FullScreen = {
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarIconColor.inferFromText();
|
||||
ToolbarIconColor.inferFromText("fullscreen", aEnterFS);
|
||||
|
||||
// For Lion fullscreen, all fullscreen controls are hidden, don't
|
||||
// bother to touch them. If we don't stop here, the following code
|
||||
|
||||
@@ -243,7 +243,7 @@ var TabsInTitlebar = {
|
||||
menubar.style.paddingBottom = "";
|
||||
}
|
||||
|
||||
ToolbarIconColor.inferFromText();
|
||||
ToolbarIconColor.inferFromText("tabsintitlebar", TabsInTitlebar.enabled);
|
||||
if (CustomizationHandler.isCustomizing()) {
|
||||
gCustomizeMode.updateLWTStyling();
|
||||
}
|
||||
|
||||
@@ -5265,8 +5265,6 @@ function setToolbarVisibility(toolbar, isVisible, persist=true) {
|
||||
PlacesToolbarHelper.init();
|
||||
BookmarkingUI.onToolbarVisibilityChange();
|
||||
gBrowser.updateWindowResizers();
|
||||
if (isVisible)
|
||||
ToolbarIconColor.inferFromText();
|
||||
}
|
||||
|
||||
var TabletModeUpdater = {
|
||||
@@ -7982,18 +7980,25 @@ function BrowserOpenNewTabOrWindow(event) {
|
||||
}
|
||||
|
||||
var ToolbarIconColor = {
|
||||
_windowState: {
|
||||
"active": false,
|
||||
"fullscreen": false,
|
||||
"tabsintitlebar": false
|
||||
},
|
||||
init: function () {
|
||||
this._initialized = true;
|
||||
|
||||
window.addEventListener("activate", this);
|
||||
window.addEventListener("deactivate", this);
|
||||
window.addEventListener("toolbarvisibilitychange", this);
|
||||
Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
|
||||
|
||||
// If the window isn't active now, we assume that it has never been active
|
||||
// before and will soon become active such that inferFromText will be
|
||||
// called from the initial activate event.
|
||||
if (Services.focus.activeWindow == window)
|
||||
this.inferFromText();
|
||||
if (Services.focus.activeWindow == window) {
|
||||
this.inferFromText("activate");
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
@@ -8001,14 +8006,18 @@ var ToolbarIconColor = {
|
||||
|
||||
window.removeEventListener("activate", this);
|
||||
window.removeEventListener("deactivate", this);
|
||||
window.removeEventListener("toolbarvisibilitychange", this);
|
||||
Services.obs.removeObserver(this, "lightweight-theme-styling-update");
|
||||
},
|
||||
|
||||
handleEvent: function (event) {
|
||||
switch (event.type) {
|
||||
case "activate":
|
||||
case "activate": // falls through
|
||||
case "deactivate":
|
||||
this.inferFromText();
|
||||
this.inferFromText(event.type);
|
||||
break;
|
||||
case "toolbarvisibilitychange":
|
||||
this.inferFromText(event.type, event.visible);
|
||||
break;
|
||||
}
|
||||
},
|
||||
@@ -8018,32 +8027,67 @@ var ToolbarIconColor = {
|
||||
case "lightweight-theme-styling-update":
|
||||
// inferFromText needs to run after LightweightThemeConsumer.jsm's
|
||||
// lightweight-theme-styling-update observer.
|
||||
setTimeout(() => { this.inferFromText(); }, 0);
|
||||
setTimeout(() => {
|
||||
this.inferFromText(aTopic);
|
||||
}, 0);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
inferFromText: function () {
|
||||
// a cache of luminance values for each toolbar
|
||||
// to avoid unnecessary calls to getComputedStyle
|
||||
_toolbarLuminanceCache: new Map(),
|
||||
|
||||
inferFromText(reason, reasonValue) {
|
||||
if (!this._initialized)
|
||||
return;
|
||||
|
||||
function parseRGB(aColorString) {
|
||||
let rgb = aColorString.match(/^rgba?\((\d+), (\d+), (\d+)/);
|
||||
rgb.shift();
|
||||
return rgb.map(x => parseInt(x));
|
||||
}
|
||||
|
||||
switch (reason) {
|
||||
case "activate": // falls through
|
||||
case "deactivate":
|
||||
this._windowState.active = (reason === "activate");
|
||||
break;
|
||||
case "fullscreen":
|
||||
this._windowState.fullscreen = reasonValue;
|
||||
break;
|
||||
case "lightweight-theme-styling-update":
|
||||
// theme change, we'll need to recalculate all color values
|
||||
this._toolbarLuminanceCache.clear();
|
||||
break;
|
||||
case "toolbarvisibilitychange":
|
||||
// toolbar changes dont require reset of the cached color values
|
||||
break;
|
||||
case "tabsintitlebar":
|
||||
this._windowState.tabsintitlebar = reasonValue;
|
||||
break;
|
||||
}
|
||||
|
||||
let toolbarSelector = "#navigator-toolbox > toolbar:not([collapsed=true]):not(#addon-bar)";
|
||||
if (AppConstants.platform == "macosx")
|
||||
toolbarSelector += ":not([type=menubar])";
|
||||
|
||||
// The getComputedStyle calls and setting the brighttext are separated in
|
||||
// two loops to avoid flushing layout and making it dirty repeatedly.
|
||||
|
||||
let luminances = new Map;
|
||||
let cachedLuminances = this._toolbarLuminanceCache;
|
||||
let luminances = new Map();
|
||||
let windowStateKey = JSON.stringify(this._windowState); // TenFourFox
|
||||
for (let toolbar of document.querySelectorAll(toolbarSelector)) {
|
||||
let [r, g, b] = parseRGB(getComputedStyle(toolbar).color);
|
||||
let luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b;
|
||||
// toolbars *should* all have ids, but guard anyway to avoid blowing up
|
||||
let cacheKey = toolbar.id && toolbar.id + windowStateKey;
|
||||
// lookup cached luminance value for this toolbar in this window state
|
||||
let luminance = cacheKey && cachedLuminances.get(cacheKey);
|
||||
if (isNaN(luminance)) {
|
||||
let [r, g, b] = parseRGB(getComputedStyle(toolbar).color);
|
||||
luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b;
|
||||
if (cacheKey) {
|
||||
cachedLuminances.set(cacheKey, luminance);
|
||||
}
|
||||
}
|
||||
luminances.set(toolbar, luminance);
|
||||
}
|
||||
|
||||
|
||||
@@ -1179,6 +1179,12 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
|
||||
BLOK("serverbid-sync.nyc3.cdn.digitaloceanspaces.com") ||
|
||||
|
||||
BLOK("ml314.com") ||
|
||||
|
||||
BLOK("ads.pro-market.net") ||
|
||||
|
||||
BLOK("tag.crsspxl.com") ||
|
||||
|
||||
#include "shavar-blocklist.h"
|
||||
|
||||
0) {
|
||||
|
||||
+30
-30
@@ -16,6 +16,7 @@
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/dom/Animation.h"
|
||||
#include "mozilla/dom/Attr.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsDOMAttributeMap.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIContentInlines.h"
|
||||
@@ -26,7 +27,6 @@
|
||||
#include "nsIContentIterator.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsContainerFrame.h"
|
||||
@@ -2171,12 +2171,15 @@ Element::GetPrimaryFrame(mozFlushType aType)
|
||||
nsresult
|
||||
Element::LeaveLink(nsPresContext* aPresContext)
|
||||
{
|
||||
nsILinkHandler *handler = aPresContext->GetLinkHandler();
|
||||
if (!handler) {
|
||||
if (!aPresContext || !aPresContext->Document()->LinkHandlingEnabled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return handler->OnLeaveLink();
|
||||
nsIDocShell* shell = aPresContext->Document()->GetDocShell();
|
||||
if (!shell) {
|
||||
return NS_OK;
|
||||
}
|
||||
return nsDocShell::Cast(shell)->OnLeaveLink();
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -2941,7 +2944,6 @@ Element::CheckHandleEventForLinksPrecondition(EventChainVisitor& aVisitor,
|
||||
(aVisitor.mEvent->mMessage != eMouseClick) &&
|
||||
(aVisitor.mEvent->mMessage != eKeyPress) &&
|
||||
(aVisitor.mEvent->mMessage != eLegacyDOMActivate)) ||
|
||||
!aVisitor.mPresContext ||
|
||||
aVisitor.mEvent->mFlags.mMultipleActionsPrevented) {
|
||||
return false;
|
||||
}
|
||||
@@ -2985,7 +2987,7 @@ Element::PreHandleEventForLinks(EventChainPreVisitor& aVisitor)
|
||||
if (!focusEvent || !focusEvent->isRefocus) {
|
||||
nsAutoString target;
|
||||
GetLinkTarget(target);
|
||||
nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
|
||||
nsContentUtils::TriggerLink(this, absURI, target,
|
||||
false, true, true);
|
||||
// Make sure any ancestor links don't also TriggerLink
|
||||
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
@@ -3038,27 +3040,28 @@ Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor)
|
||||
case eMouseDown:
|
||||
{
|
||||
if (aVisitor.mEvent->AsMouseEvent()->button ==
|
||||
WidgetMouseEvent::eLeftButton) {
|
||||
// don't make the link grab the focus if there is no link handler
|
||||
nsILinkHandler *handler = aVisitor.mPresContext->GetLinkHandler();
|
||||
nsIDocument *document = GetComposedDoc();
|
||||
if (handler && document) {
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
WidgetMouseEvent::eLeftButton &&
|
||||
OwnerDoc()->LinkHandlingEnabled()) {
|
||||
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
if (IsInComposedDoc()) {
|
||||
if (nsIFocusManager* fm = nsFocusManager::GetFocusManager()) {
|
||||
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(this);
|
||||
fm->SetFocus(elem, nsIFocusManager::FLAG_BYMOUSE |
|
||||
nsIFocusManager::FLAG_NOSCROLL);
|
||||
}
|
||||
}
|
||||
|
||||
if (aVisitor.mPresContext) {
|
||||
EventStateManager::SetActiveManager(
|
||||
aVisitor.mPresContext->EventStateManager(), this);
|
||||
}
|
||||
|
||||
// OK, we're pretty sure we're going to load, so warm up a speculative
|
||||
// connection to be sure we have one ready when we open the channel.
|
||||
// OK, we're pretty sure we're going to load, so warm up a speculative
|
||||
// connection to be sure we have one ready when we open the channel.
|
||||
if (nsIDocShell* shell = OwnerDoc()->GetDocShell()) {
|
||||
nsCOMPtr<nsISpeculativeConnect>
|
||||
speculator(do_QueryInterface(nsContentUtils::GetIOService()));
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(handler);
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(shell);
|
||||
// We need bug 1304219 for this part, but this will suffice for now.
|
||||
//speculator->SpeculativeConnect2(absURI, NodePrincipal(), ir);
|
||||
speculator->SpeculativeConnect(absURI, ir);
|
||||
@@ -3076,19 +3079,16 @@ Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor)
|
||||
}
|
||||
|
||||
// The default action is simply to dispatch DOMActivate
|
||||
nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
|
||||
if (shell) {
|
||||
// single-click
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
// DOMActive event should be trusted since the activation is actually
|
||||
// occurred even if the cause is an untrusted click event.
|
||||
InternalUIEvent actEvent(true, eLegacyDOMActivate, mouseEvent);
|
||||
actEvent.detail = 1;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
// DOMActive event should be trusted since the activation is actually
|
||||
// occurred even if the cause is an untrusted click event.
|
||||
InternalUIEvent actEvent(true, eLegacyDOMActivate, mouseEvent);
|
||||
actEvent.detail = 1;
|
||||
|
||||
rv = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
rv = EventDispatcher::Dispatch(this, aVisitor.mPresContext, &actEvent,
|
||||
nullptr, &status);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3100,7 +3100,7 @@ Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor)
|
||||
GetLinkTarget(target);
|
||||
const InternalUIEvent* activeEvent = aVisitor.mEvent->AsUIEvent();
|
||||
MOZ_ASSERT(activeEvent);
|
||||
nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
|
||||
nsContentUtils::TriggerLink(this, absURI, target,
|
||||
true, true, activeEvent->IsTrustable());
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "mozilla/EventStates.h" // for member
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsINodeList.h"
|
||||
#include "nsNodeUtils.h"
|
||||
#include "nsAttrAndChildArray.h"
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIContentIterator.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsCycleCollector.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsDocShellCID.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsDOMCID.h"
|
||||
@@ -4795,25 +4796,24 @@ nsContentUtils::CombineResourcePrincipals(nsCOMPtr<nsIPrincipal>* aResourcePrinc
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
|
||||
nsContentUtils::TriggerLink(nsIContent *aContent,
|
||||
nsIURI *aLinkURI, const nsString &aTargetSpec,
|
||||
bool aClick, bool aIsUserTriggered,
|
||||
bool aIsTrusted)
|
||||
{
|
||||
NS_ASSERTION(aPresContext, "Need a nsPresContext");
|
||||
NS_PRECONDITION(aLinkURI, "No link URI");
|
||||
|
||||
if (aContent->IsEditable()) {
|
||||
if (aContent->IsEditable() || !aContent->OwnerDoc()->LinkHandlingEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsILinkHandler *handler = aPresContext->GetLinkHandler();
|
||||
if (!handler) {
|
||||
nsCOMPtr<nsIDocShell> docShell = aContent->OwnerDoc()->GetDocShell();
|
||||
if (!docShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aClick) {
|
||||
handler->OnOverLink(aContent, aLinkURI, aTargetSpec.get());
|
||||
nsDocShell::Cast(docShell)->OnOverLink(aContent, aLinkURI, aTargetSpec.get());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4848,7 +4848,7 @@ nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
|
||||
fileName.SetIsVoid(true); // No actionable download attribute was found.
|
||||
}
|
||||
|
||||
handler->OnLinkClick(aContent, aLinkURI,
|
||||
nsDocShell::Cast(docShell)->OnLinkClick(aContent, aLinkURI,
|
||||
fileName.IsVoid() ? aTargetSpec.get() : EmptyString().get(),
|
||||
fileName, nullptr, nullptr, aIsTrusted);
|
||||
}
|
||||
|
||||
@@ -1506,7 +1506,6 @@ public:
|
||||
* security check using aContent's principal.
|
||||
*
|
||||
* @param aContent the node on which a link was triggered.
|
||||
* @param aPresContext the pres context, must be non-null.
|
||||
* @param aLinkURI the URI of the link, must be non-null.
|
||||
* @param aTargetSpec the target (like target=, may be empty).
|
||||
* @param aClick whether this was a click or not (if false, this method
|
||||
@@ -1517,7 +1516,7 @@ public:
|
||||
* @param aIsTrusted If false, JS Context will be pushed to stack
|
||||
* when the link is triggered.
|
||||
*/
|
||||
static void TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
|
||||
static void TriggerLink(nsIContent *aContent,
|
||||
nsIURI *aLinkURI, const nsString& aTargetSpec,
|
||||
bool aClick, bool aIsUserTriggered,
|
||||
bool aIsTrusted);
|
||||
|
||||
@@ -1435,6 +1435,7 @@ nsIDocument::nsIDocument()
|
||||
mPostedFlushUserFontSet(false),
|
||||
mDidFireDOMContentLoaded(true),
|
||||
mFrameRequestCallbacksScheduled(false),
|
||||
mLinksEnabled(true),
|
||||
mPartID(0),
|
||||
mUserHasInteracted(false)
|
||||
{
|
||||
|
||||
@@ -1358,7 +1358,8 @@ public:
|
||||
virtual void SetContainer(nsDocShell* aContainer);
|
||||
|
||||
/**
|
||||
* Get the container (docshell) for this document.
|
||||
* Get the container (docshell) for this document. Virtual so that
|
||||
* the shell service can call it.
|
||||
*/
|
||||
virtual nsISupports* GetContainer() const;
|
||||
|
||||
@@ -2679,6 +2680,9 @@ public:
|
||||
|
||||
bool InlineScriptAllowedByCSP();
|
||||
|
||||
void SetLinkHandlingEnabled(bool aValue) { mLinksEnabled = aValue; }
|
||||
bool LinkHandlingEnabled() { return mLinksEnabled; }
|
||||
|
||||
protected:
|
||||
bool GetUseCounter(mozilla::UseCounter aUseCounter)
|
||||
{
|
||||
@@ -2960,6 +2964,10 @@ protected:
|
||||
// UpdateFrameRequestCallbackSchedulingState.
|
||||
bool mFrameRequestCallbacksScheduled : 1;
|
||||
|
||||
// False if we've disabled link handling for elements inside this document,
|
||||
// true otherwise.
|
||||
bool mLinksEnabled : 1;
|
||||
|
||||
enum Type {
|
||||
eUnknown, // should never be used
|
||||
eHTML,
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIEditorIMESupport.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "mozilla/dom/NodeInfo.h"
|
||||
#include "mozilla/dom/NodeInfoInlines.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
@@ -53,7 +53,6 @@ static int32_t GetUnicharStringWidth(const char16_t* pwcs, int32_t n);
|
||||
|
||||
// Someday may want to make this non-const:
|
||||
static const uint32_t TagStackSize = 500;
|
||||
static const uint32_t OLStackSize = 100;
|
||||
|
||||
nsresult
|
||||
NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer)
|
||||
@@ -101,10 +100,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
|
||||
mTagStackIndex = 0;
|
||||
mIgnoreAboveIndex = (uint32_t)kNotFound;
|
||||
|
||||
// initialize the OL stack, where numbers for ordered lists are kept
|
||||
mOLStack = new int32_t[OLStackSize];
|
||||
mOLStackIndex = 0;
|
||||
|
||||
mULCount = 0;
|
||||
|
||||
mIgnoredChildNodeLevel = 0;
|
||||
@@ -113,7 +108,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
|
||||
nsPlainTextSerializer::~nsPlainTextSerializer()
|
||||
{
|
||||
delete[] mTagStack;
|
||||
delete[] mOLStack;
|
||||
NS_WARN_IF_FALSE(mHeadLevel == 0, "Wrong head level!");
|
||||
}
|
||||
|
||||
@@ -199,6 +193,8 @@ nsPlainTextSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
|
||||
// XXX We should let the caller decide whether to do this or not
|
||||
mFlags &= ~nsIDocumentEncoder::OutputNoFramesContent;
|
||||
|
||||
MOZ_ASSERT(mOLStack.IsEmpty());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -447,6 +443,8 @@ nsPlainTextSerializer::AppendDocumentStart(nsIDocument *aDocument,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_CONSTEXPR_VAR int32_t kOlStackDummyValue = 0;
|
||||
|
||||
nsresult
|
||||
nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
|
||||
{
|
||||
@@ -625,53 +623,52 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
|
||||
}
|
||||
else if (aTag == nsGkAtoms::ul) {
|
||||
// Indent here to support nested lists, which aren't included in li :-(
|
||||
EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0);
|
||||
EnsureVerticalSpace(IsInOlOrUl() ? 0 : 1);
|
||||
// Must end the current line before we change indention
|
||||
mIndent += kIndentSizeList;
|
||||
mULCount++;
|
||||
}
|
||||
else if (aTag == nsGkAtoms::ol) {
|
||||
EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0);
|
||||
EnsureVerticalSpace(IsInOlOrUl() ? 0 : 1);
|
||||
if (mFlags & nsIDocumentEncoder::OutputFormatted) {
|
||||
// Must end the current line before we change indention
|
||||
if (mOLStackIndex < OLStackSize) {
|
||||
nsAutoString startAttr;
|
||||
int32_t startVal = 1;
|
||||
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) {
|
||||
nsresult rv = NS_OK;
|
||||
startVal = startAttr.ToInteger(&rv);
|
||||
if (NS_FAILED(rv))
|
||||
startVal = 1;
|
||||
nsAutoString startAttr;
|
||||
int32_t startVal = 1;
|
||||
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) {
|
||||
nsresult rv = NS_OK;
|
||||
startVal = startAttr.ToInteger(&rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
startVal = 1;
|
||||
}
|
||||
mOLStack[mOLStackIndex++] = startVal;
|
||||
}
|
||||
mOLStack.AppendElement(startVal);
|
||||
} else {
|
||||
mOLStackIndex++;
|
||||
mOLStack.AppendElement(kOlStackDummyValue);
|
||||
}
|
||||
mIndent += kIndentSizeList; // see ul
|
||||
}
|
||||
else if (aTag == nsGkAtoms::li &&
|
||||
(mFlags & nsIDocumentEncoder::OutputFormatted)) {
|
||||
if (mTagStackIndex > 1 && IsInOL()) {
|
||||
if (mOLStackIndex > 0) {
|
||||
if (!mOLStack.IsEmpty()) {
|
||||
nsAutoString valueAttr;
|
||||
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::value, valueAttr))) {
|
||||
nsresult rv = NS_OK;
|
||||
int32_t valueAttrVal = valueAttr.ToInteger(&rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mOLStack[mOLStackIndex-1] = valueAttrVal;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mOLStack.LastElement() = valueAttrVal;
|
||||
}
|
||||
}
|
||||
// This is what nsBulletFrame does for OLs:
|
||||
mInIndentString.AppendInt(mOLStack[mOLStackIndex-1]++, 10);
|
||||
}
|
||||
else {
|
||||
mInIndentString.AppendInt(mOLStack.LastElement(), 10);
|
||||
mOLStack.LastElement()++;
|
||||
} else {
|
||||
mInIndentString.Append(char16_t('#'));
|
||||
}
|
||||
|
||||
mInIndentString.Append(char16_t('.'));
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
static char bulletCharArray[] = "*o+#";
|
||||
uint32_t index = mULCount > 0 ? (mULCount - 1) : 3;
|
||||
char bulletChar = bulletCharArray[index % 4];
|
||||
@@ -679,33 +676,26 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
|
||||
}
|
||||
|
||||
mInIndentString.Append(char16_t(' '));
|
||||
}
|
||||
else if (aTag == nsGkAtoms::dl) {
|
||||
} else if (aTag == nsGkAtoms::dl) {
|
||||
EnsureVerticalSpace(1);
|
||||
}
|
||||
else if (aTag == nsGkAtoms::dt) {
|
||||
} else if (aTag == nsGkAtoms::dt) {
|
||||
EnsureVerticalSpace(0);
|
||||
}
|
||||
else if (aTag == nsGkAtoms::dd) {
|
||||
} else if (aTag == nsGkAtoms::dd) {
|
||||
EnsureVerticalSpace(0);
|
||||
mIndent += kIndentSizeDD;
|
||||
}
|
||||
else if (aTag == nsGkAtoms::span) {
|
||||
} else if (aTag == nsGkAtoms::span) {
|
||||
++mSpanLevel;
|
||||
}
|
||||
else if (aTag == nsGkAtoms::blockquote) {
|
||||
} else if (aTag == nsGkAtoms::blockquote) {
|
||||
// Push
|
||||
PushBool(mIsInCiteBlockquote, isInCiteBlockquote);
|
||||
if (isInCiteBlockquote) {
|
||||
EnsureVerticalSpace(0);
|
||||
mCiteQuoteLevel++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
EnsureVerticalSpace(1);
|
||||
mIndent += kTabSize; // Check for some maximum value?
|
||||
}
|
||||
}
|
||||
else if (aTag == nsGkAtoms::q) {
|
||||
} else if (aTag == nsGkAtoms::q) {
|
||||
Write(NS_LITERAL_STRING("\""));
|
||||
}
|
||||
|
||||
@@ -887,7 +877,8 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
|
||||
else if (aTag == nsGkAtoms::ul) {
|
||||
FlushLine();
|
||||
mIndent -= kIndentSizeList;
|
||||
if (--mULCount + mOLStackIndex == 0) {
|
||||
--mULCount;
|
||||
if (!IsInOlOrUl()) {
|
||||
mFloatingLines = 1;
|
||||
mLineBreakDue = true;
|
||||
}
|
||||
@@ -895,31 +886,26 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
|
||||
else if (aTag == nsGkAtoms::ol) {
|
||||
FlushLine(); // Doing this after decreasing OLStackIndex would be wrong.
|
||||
mIndent -= kIndentSizeList;
|
||||
NS_ASSERTION(mOLStackIndex, "Wrong OLStack level!");
|
||||
mOLStackIndex--;
|
||||
if (mULCount + mOLStackIndex == 0) {
|
||||
MOZ_ASSERT(!mOLStack.IsEmpty(), "Wrong OLStack level!");
|
||||
mOLStack.RemoveElementAt(mOLStack.Length() - 1); // mOLStack.RemoveLastElement();
|
||||
if (!IsInOlOrUl()) {
|
||||
mFloatingLines = 1;
|
||||
mLineBreakDue = true;
|
||||
}
|
||||
}
|
||||
else if (aTag == nsGkAtoms::dl) {
|
||||
} else if (aTag == nsGkAtoms::dl) {
|
||||
mFloatingLines = 1;
|
||||
mLineBreakDue = true;
|
||||
}
|
||||
else if (aTag == nsGkAtoms::dd) {
|
||||
} else if (aTag == nsGkAtoms::dd) {
|
||||
FlushLine();
|
||||
mIndent -= kIndentSizeDD;
|
||||
}
|
||||
else if (aTag == nsGkAtoms::span) {
|
||||
} else if (aTag == nsGkAtoms::span) {
|
||||
NS_ASSERTION(mSpanLevel, "Span level will be negative!");
|
||||
--mSpanLevel;
|
||||
}
|
||||
else if (aTag == nsGkAtoms::div) {
|
||||
} else if (aTag == nsGkAtoms::div) {
|
||||
if (mFloatingLines < 0)
|
||||
mFloatingLines = 0;
|
||||
mLineBreakDue = true;
|
||||
}
|
||||
else if (aTag == nsGkAtoms::blockquote) {
|
||||
} else if (aTag == nsGkAtoms::blockquote) {
|
||||
FlushLine(); // Is this needed?
|
||||
|
||||
// Pop
|
||||
@@ -930,17 +916,14 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
|
||||
mCiteQuoteLevel--;
|
||||
mFloatingLines = 0;
|
||||
mHasWrittenCiteBlockquote = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mIndent -= kTabSize;
|
||||
mFloatingLines = 1;
|
||||
}
|
||||
mLineBreakDue = true;
|
||||
}
|
||||
else if (aTag == nsGkAtoms::q) {
|
||||
} else if (aTag == nsGkAtoms::q) {
|
||||
Write(NS_LITERAL_STRING("\""));
|
||||
}
|
||||
else if (IsElementBlock(mElement) && aTag != nsGkAtoms::script) {
|
||||
} else if (IsElementBlock(mElement) && aTag != nsGkAtoms::script) {
|
||||
// All other blocks get 1 vertical space after them
|
||||
// in formatted mode, otherwise 0.
|
||||
// This is hard. Sometimes 0 is a better number, but
|
||||
@@ -1866,6 +1849,10 @@ nsPlainTextSerializer::IsInOL()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nsPlainTextSerializer::IsInOlOrUl() const {
|
||||
return (mULCount > 0) || !mOLStack.IsEmpty();
|
||||
}
|
||||
|
||||
/*
|
||||
@return 0 = no header, 1 = h1, ..., 6 = h6
|
||||
*/
|
||||
|
||||
@@ -81,6 +81,7 @@ private:
|
||||
void Write(const nsAString& aString);
|
||||
bool IsInPre();
|
||||
bool IsInOL();
|
||||
bool IsInOlOrUl() const;
|
||||
bool IsCurrentNodeConverted();
|
||||
bool MustSuppressLeaf();
|
||||
|
||||
@@ -222,8 +223,7 @@ private:
|
||||
uint32_t mIgnoreAboveIndex;
|
||||
|
||||
// The stack for ordered lists
|
||||
int32_t *mOLStack;
|
||||
uint32_t mOLStackIndex;
|
||||
nsAutoTArray<int32_t, 100> mOLStack;
|
||||
|
||||
uint32_t mULCount;
|
||||
|
||||
|
||||
@@ -531,6 +531,12 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsAutoCString scriptURISpec;
|
||||
scriptURI->GetAsciiSpec(scriptURISpec);
|
||||
fprintf(stderr, "Processing external script: %s\n", scriptURISpec.get());
|
||||
#endif
|
||||
|
||||
// Double-check that the preload matches what we're asked to load now.
|
||||
mozilla::net::ReferrerPolicy ourRefPolicy = mDocument->GetReferrerPolicy();
|
||||
CORSMode ourCORSMode = aElement->GetCORSMode();
|
||||
@@ -555,6 +561,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
if (NS_FAILED(rv)) {
|
||||
// probably plans have changed; even though the preload was allowed seems
|
||||
// like the actual load is not; let's cancel the preload request.
|
||||
NS_WARNING("Preload was cancelled");
|
||||
request->Cancel();
|
||||
return false;
|
||||
}
|
||||
@@ -607,6 +614,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
|
||||
if (aElement->GetScriptAsync()) {
|
||||
request->mIsAsync = true;
|
||||
NS_WARNING("Current script is async");
|
||||
if (request->IsDoneLoading()) {
|
||||
mLoadedAsyncRequests.AppendElement(request);
|
||||
// The script is available already. Run it ASAP when the event
|
||||
@@ -624,6 +632,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
// Violate the HTML5 spec in order to make LABjs and the "order" plug-in
|
||||
// for RequireJS work with their Gecko-sniffed code path. See
|
||||
// http://lists.w3.org/Archives/Public/public-html/2010Oct/0088.html
|
||||
NS_WARNING("Parser not yet created for this script");
|
||||
request->mIsNonAsyncScriptInserted = true;
|
||||
mNonAsyncExternalScriptInsertedRequests.AppendElement(request);
|
||||
if (request->IsDoneLoading()) {
|
||||
@@ -636,6 +645,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
// we now have a parser-inserted request that may or may not be still
|
||||
// loading
|
||||
if (aElement->GetScriptDeferred()) {
|
||||
NS_WARNING("Current script is deferred");
|
||||
// We don't want to run this yet.
|
||||
// If we come here, the script is a parser-created script and it has
|
||||
// the defer attribute but not the async attribute. Since a
|
||||
@@ -1232,6 +1242,7 @@ nsScriptLoader::ProcessPendingRequests()
|
||||
|
||||
if (mDocumentParsingDone && mXSLTRequests.isEmpty()) {
|
||||
while (!mDeferRequests.isEmpty() && mDeferRequests.getFirst()->IsReadyToRun()) {
|
||||
NS_WARNING("Handling deferred request");
|
||||
request = mDeferRequests.StealFirst();
|
||||
ProcessRequest(request);
|
||||
}
|
||||
|
||||
@@ -215,16 +215,9 @@ HTMLAnchorElement::IsHTMLFocusable(bool aWithMouse,
|
||||
}
|
||||
|
||||
// cannot focus links if there is no link handler
|
||||
nsIDocument* doc = GetComposedDoc();
|
||||
if (doc) {
|
||||
nsIPresShell* presShell = doc->GetShell();
|
||||
if (presShell) {
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
if (presContext && !presContext->GetLinkHandler()) {
|
||||
*aIsFocusable = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!OwnerDoc()->LinkHandlingEnabled()) {
|
||||
*aIsFocusable = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Links that are in an editable region should never be focusable, even if
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsError.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIForm.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIFormControl.h"
|
||||
|
||||
@@ -653,22 +653,9 @@ nsGenericHTMLElement::CheckHandleEventForAnchorsPreconditions(
|
||||
{
|
||||
NS_PRECONDITION(nsCOMPtr<Link>(do_QueryObject(this)),
|
||||
"should be called only when |this| implements |Link|");
|
||||
|
||||
if (!aVisitor.mPresContext) {
|
||||
// We need a pres context to do link stuff. Some events (e.g. mutation
|
||||
// events) don't have one.
|
||||
// XXX: ideally, shouldn't we be able to do what we need without one?
|
||||
return false;
|
||||
}
|
||||
|
||||
//Need to check if we hit an imagemap area and if so see if we're handling
|
||||
//the event on that map or on a link farther up the tree. If we're on a
|
||||
//link farther up, do nothing.
|
||||
nsCOMPtr<nsIContent> target = aVisitor.mPresContext->EventStateManager()->
|
||||
GetEventTargetContent(aVisitor.mEvent);
|
||||
|
||||
return !target || !target->IsHTMLElement(nsGkAtoms::area) ||
|
||||
IsHTMLElement(nsGkAtoms::area);
|
||||
// When disconnected, only <a> should navigate away per
|
||||
// https://html.spec.whatwg.org/#cannot-navigate
|
||||
return IsInComposedDoc() || IsHTMLElement(nsGkAtoms::a);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
||||
@@ -187,6 +187,12 @@ SVGAElement::IsAttributeMapped(const nsIAtom* name) const
|
||||
bool
|
||||
SVGAElement::IsFocusableInternal(int32_t *aTabIndex, bool aWithMouse)
|
||||
{
|
||||
// There are some backbugs in
|
||||
// https://hg.mozilla.org/mozilla-central/rev/fc09b999be43
|
||||
if (!OwnerDoc()->LinkHandlingEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
if (IsLink(getter_AddRefs(uri))) {
|
||||
if (aTabIndex) {
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIInlineSpellChecker.h"
|
||||
|
||||
#include "mozilla/CSSStyleSheet.h"
|
||||
@@ -143,13 +142,10 @@ nsHTMLEditor::~nsHTMLEditor()
|
||||
// free any default style propItems
|
||||
RemoveAllDefaultProperties();
|
||||
|
||||
if (mLinkHandler && mDocWeak)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> ps = GetPresShell();
|
||||
|
||||
if (ps && ps->GetPresContext())
|
||||
{
|
||||
ps->GetPresContext()->SetLinkHandler(mLinkHandler);
|
||||
if (mDisabledLinkHandling) {
|
||||
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||
if (doc) {
|
||||
doc->SetLinkHandlingEnabled(mOldLinkHandlingEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,14 +264,12 @@ nsHTMLEditor::Init(nsIDOMDocument *aDoc,
|
||||
mHTMLCSSUtils = new nsHTMLCSSUtils(this);
|
||||
|
||||
// disable links
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
||||
nsPresContext *context = presShell->GetPresContext();
|
||||
NS_ENSURE_TRUE(context, NS_ERROR_NULL_POINTER);
|
||||
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
|
||||
if (!IsPlaintextEditor() && !IsInteractionAllowed()) {
|
||||
mLinkHandler = context->GetLinkHandler();
|
||||
|
||||
context->SetLinkHandler(nullptr);
|
||||
mDisabledLinkHandling = true;
|
||||
mOldLinkHandlingEnabled = doc->LinkHandlingEnabled();
|
||||
doc->SetLinkHandlingEnabled(false);
|
||||
}
|
||||
|
||||
// init the type-in state
|
||||
|
||||
@@ -46,7 +46,6 @@ class nsITransferable;
|
||||
class nsIClipboard;
|
||||
class TypeInState;
|
||||
class nsIContentFilter;
|
||||
class nsILinkHandler;
|
||||
class nsTableOuterFrame;
|
||||
class nsIDOMRange;
|
||||
class nsRange;
|
||||
@@ -954,7 +953,8 @@ protected:
|
||||
void AddMouseClickListener(nsIDOMElement * aElement);
|
||||
void RemoveMouseClickListener(nsIDOMElement * aElement);
|
||||
|
||||
nsCOMPtr<nsILinkHandler> mLinkHandler;
|
||||
bool mDisabledLinkHandling = false;
|
||||
bool mOldLinkHandlingEnabled = false;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -1176,7 +1176,7 @@ static const JSFunctionSpec object_methods[] = {
|
||||
JS_FN(js_toString_str, obj_toString, 0,0),
|
||||
JS_SELF_HOSTED_FN(js_toLocaleString_str, "Object_toLocaleString", 0,JSPROP_DEFINE_LATE),
|
||||
JS_FN(js_valueOf_str, obj_valueOf, 0,0),
|
||||
#if JS_HAS_OBJ_WATCHPOINT
|
||||
#if (0) // JS_HAS_OBJ_WATCHPOINT // TenFourFox issue 575 // flip this for confidence testing
|
||||
JS_FN(js_watch_str, obj_watch, 2,0),
|
||||
JS_FN(js_unwatch_str, obj_unwatch, 1,0),
|
||||
#endif
|
||||
|
||||
@@ -1258,7 +1258,11 @@ CheckSetConstOp(JSOp op, ParseNode* pn)
|
||||
switch (op) {
|
||||
case JSOP_GETLOCAL: case JSOP_GETALIASEDVAR: break;
|
||||
case JSOP_INITLEXICAL: case JSOP_INITALIASEDLEXICAL: break;
|
||||
#if (0) // flip this for confidence testing
|
||||
case JSOP_SETLOCAL: return JSOP_THROWSETCONST;
|
||||
#else
|
||||
case JSOP_SETLOCAL: break;
|
||||
#endif
|
||||
case JSOP_SETALIASEDVAR: return JSOP_THROWSETALIASEDCONST;
|
||||
default: MOZ_CRASH("unexpected set var op");
|
||||
}
|
||||
|
||||
@@ -71,11 +71,39 @@ InsertSortedList(InlineForwardList<T> &list, T* value)
|
||||
// LiveRange
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void
|
||||
LiveRange::noteAddedUse(UsePosition* use)
|
||||
{
|
||||
LUse::Policy policy = use->usePolicy();
|
||||
usesSpillWeight_ += BacktrackingAllocator::SpillWeightFromUsePolicy(policy);
|
||||
if (policy == LUse::FIXED)
|
||||
++numFixedUses_;
|
||||
}
|
||||
|
||||
inline void
|
||||
LiveRange::noteRemovedUse(UsePosition* use)
|
||||
{
|
||||
LUse::Policy policy = use->usePolicy();
|
||||
usesSpillWeight_ -= BacktrackingAllocator::SpillWeightFromUsePolicy(policy);
|
||||
if (policy == LUse::FIXED)
|
||||
--numFixedUses_;
|
||||
MOZ_ASSERT_IF(!hasUses(), !usesSpillWeight_ && !numFixedUses_);
|
||||
}
|
||||
|
||||
void
|
||||
LiveRange::addUse(UsePosition* use)
|
||||
{
|
||||
MOZ_ASSERT(covers(use->pos));
|
||||
InsertSortedList(uses_, use);
|
||||
noteAddedUse(use);
|
||||
}
|
||||
|
||||
UsePosition*
|
||||
LiveRange::popUse()
|
||||
{
|
||||
UsePosition* ret = uses_.popFront();
|
||||
noteRemovedUse(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -89,6 +117,7 @@ LiveRange::distributeUses(LiveRange* other)
|
||||
UsePosition* use = *iter;
|
||||
if (other->covers(use->pos)) {
|
||||
uses_.removeAndIncrement(iter);
|
||||
noteRemovedUse(use);
|
||||
other->addUse(use);
|
||||
} else {
|
||||
iter++;
|
||||
@@ -2494,28 +2523,9 @@ BacktrackingAllocator::computeSpillWeight(LiveBundle* bundle)
|
||||
}
|
||||
}
|
||||
|
||||
for (UsePositionIterator iter = range->usesBegin(); iter; iter++) {
|
||||
LUse* use = iter->use;
|
||||
|
||||
switch (use->policy()) {
|
||||
case LUse::ANY:
|
||||
usesTotal += 1000;
|
||||
break;
|
||||
|
||||
case LUse::FIXED:
|
||||
fixed = true;
|
||||
case LUse::REGISTER:
|
||||
usesTotal += 2000;
|
||||
break;
|
||||
|
||||
case LUse::KEEPALIVE:
|
||||
break;
|
||||
|
||||
default:
|
||||
// Note: RECOVERED_INPUT will not appear in UsePositionIterator.
|
||||
MOZ_CRASH("Bad use");
|
||||
}
|
||||
}
|
||||
usesTotal += range->usesSpillWeight();
|
||||
if (range->numFixedUses() > 0)
|
||||
fixed = true;
|
||||
}
|
||||
|
||||
// Bundles with fixed uses are given a higher spill weight, since they must
|
||||
|
||||
@@ -123,6 +123,8 @@ class Requirement
|
||||
CodePosition position_;
|
||||
};
|
||||
|
||||
// We may want the cache-friendlier version in
|
||||
// https://hg.mozilla.org/mozilla-central/raw-file/df79199f9f0fcde01ddc2eccf2a5368cb7b801aa/js/src/jit/BacktrackingAllocator.h
|
||||
struct UsePosition : public TempObject,
|
||||
public InlineForwardListNode<UsePosition>
|
||||
{
|
||||
@@ -141,6 +143,9 @@ struct UsePosition : public TempObject,
|
||||
? CodePosition::INPUT
|
||||
: CodePosition::OUTPUT));
|
||||
}
|
||||
LUse::Policy usePolicy() const {
|
||||
return use->policy();
|
||||
}
|
||||
};
|
||||
|
||||
typedef InlineForwardListIterator<UsePosition> UsePositionIterator;
|
||||
@@ -231,15 +236,29 @@ class LiveRange : public TempObject
|
||||
// All uses of the virtual register in this range, ordered by location.
|
||||
InlineForwardList<UsePosition> uses_;
|
||||
|
||||
// Total spill weight that calculate from all the uses' policy. Because the
|
||||
// use's policy can't be changed after initialization, we can update the
|
||||
// weight whenever a use is added to or remove from this range. This way, we
|
||||
// don't need to iterate all the uses every time computeSpillWeight() is
|
||||
// called.
|
||||
size_t usesSpillWeight_;
|
||||
|
||||
// Number of uses that have policy LUse::FIXED.
|
||||
uint32_t numFixedUses_;
|
||||
|
||||
// Whether this range contains the virtual register's definition.
|
||||
bool hasDefinition_;
|
||||
|
||||
LiveRange(uint32_t vreg, Range range)
|
||||
: vreg_(vreg), bundle_(nullptr), range_(range), hasDefinition_(false)
|
||||
: vreg_(vreg), bundle_(nullptr), range_(range), usesSpillWeight_(0),
|
||||
numFixedUses_(0), hasDefinition_(false)
|
||||
{
|
||||
MOZ_ASSERT(!range.empty());
|
||||
}
|
||||
|
||||
void noteAddedUse(UsePosition* use);
|
||||
void noteRemovedUse(UsePosition* use);
|
||||
|
||||
public:
|
||||
static LiveRange* New(TempAllocator& alloc, uint32_t vreg,
|
||||
CodePosition from, CodePosition to) {
|
||||
@@ -287,9 +306,7 @@ class LiveRange : public TempObject
|
||||
bool hasUses() const {
|
||||
return !!usesBegin();
|
||||
}
|
||||
UsePosition* popUse() {
|
||||
return uses_.popFront();
|
||||
}
|
||||
UsePosition* popUse();
|
||||
|
||||
bool hasDefinition() const {
|
||||
return hasDefinition_;
|
||||
@@ -316,6 +333,13 @@ class LiveRange : public TempObject
|
||||
hasDefinition_ = true;
|
||||
}
|
||||
|
||||
size_t usesSpillWeight() {
|
||||
return usesSpillWeight_;
|
||||
}
|
||||
uint32_t numFixedUses() {
|
||||
return numFixedUses_;
|
||||
}
|
||||
|
||||
// Return a string describing this range. This is not re-entrant!
|
||||
#ifdef DEBUG
|
||||
const char* toString() const;
|
||||
@@ -636,6 +660,20 @@ class BacktrackingAllocator : protected RegisterAllocator
|
||||
|
||||
bool go();
|
||||
|
||||
static size_t SpillWeightFromUsePolicy(LUse::Policy policy) {
|
||||
switch (policy) {
|
||||
case LUse::ANY:
|
||||
return 1000;
|
||||
|
||||
case LUse::REGISTER:
|
||||
case LUse::FIXED:
|
||||
return 2000;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef Vector<LiveRange*, 4, SystemAllocPolicy> LiveRangeVector;
|
||||
|
||||
+10
-3
@@ -1535,6 +1535,15 @@ JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
|
||||
return s;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString*)
|
||||
JS_NewMaybeExternalString(JSContext* cx, const char16_t* chars, size_t length,
|
||||
const JSStringFinalizer* fin, bool* isExternal)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return NewMaybeExternalString(cx, chars, length, fin, isExternal);
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_IsExternalString(JSString* str)
|
||||
{
|
||||
@@ -4735,8 +4744,6 @@ JS_NewStringCopyN(JSContext* cx, const char* s, size_t n)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
if (!n)
|
||||
return cx->names().empty;
|
||||
return NewStringCopyN<CanGC>(cx, s, n);
|
||||
}
|
||||
|
||||
@@ -4745,7 +4752,7 @@ JS_NewStringCopyZ(JSContext* cx, const char* s)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
if (!s || !*s)
|
||||
if (!s)
|
||||
return cx->runtime()->emptyString;
|
||||
return NewStringCopyZ<CanGC>(cx, s);
|
||||
}
|
||||
|
||||
@@ -1820,6 +1820,17 @@ extern JS_PUBLIC_API(JSString*)
|
||||
JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
|
||||
const JSStringFinalizer* fin);
|
||||
|
||||
/**
|
||||
* Create a new JSString whose chars member may refer to external memory.
|
||||
* If the returned string refers to the external memory, |*isExternal| is set
|
||||
* to true. Otherwise the returned string is not an external string and
|
||||
* |*isExternal| is set to false. If |*isExternal| is false, |fin| won't be
|
||||
* called.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSString*)
|
||||
JS_NewMaybeExternalString(JSContext* cx, const char16_t* chars, size_t length,
|
||||
const JSStringFinalizer* fin, bool* isExternal);
|
||||
|
||||
/**
|
||||
* Return whether 'str' was created with JS_NewExternalString or
|
||||
* JS_NewExternalStringWithClosure.
|
||||
|
||||
+52
-19
@@ -790,9 +790,11 @@ StaticStrings::init(JSContext* cx)
|
||||
static_assert(UNIT_STATIC_LIMIT - 1 <= JSString::MAX_LATIN1_CHAR,
|
||||
"Unit strings must fit in Latin1Char.");
|
||||
|
||||
using Latin1Range = mozilla::Range<const Latin1Char>;
|
||||
|
||||
for (uint32_t i = 0; i < UNIT_STATIC_LIMIT; i++) {
|
||||
Latin1Char buffer[] = { Latin1Char(i), '\0' };
|
||||
JSFlatString* s = NewStringCopyN<NoGC>(cx, buffer, 1);
|
||||
JSFlatString* s = NewInlineString<NoGC>(cx, Latin1Range(buffer, 1));
|
||||
if (!s)
|
||||
return false;
|
||||
HashNumber hash = mozilla::HashString(buffer, 1);
|
||||
@@ -801,7 +803,7 @@ StaticStrings::init(JSContext* cx)
|
||||
|
||||
for (uint32_t i = 0; i < NUM_SMALL_CHARS * NUM_SMALL_CHARS; i++) {
|
||||
Latin1Char buffer[] = { FROM_SMALL_CHAR(i >> 6), FROM_SMALL_CHAR(i & 0x3F), '\0' };
|
||||
JSFlatString* s = NewStringCopyN<NoGC>(cx, buffer, 2);
|
||||
JSFlatString* s = NewInlineString<NoGC>(cx, Latin1Range(buffer, 2));
|
||||
if (!s)
|
||||
return false;
|
||||
HashNumber hash = mozilla::HashString(buffer, 2);
|
||||
@@ -820,7 +822,7 @@ StaticStrings::init(JSContext* cx)
|
||||
Latin1Char('0' + ((i / 10) % 10)),
|
||||
Latin1Char('0' + (i % 10)),
|
||||
'\0' };
|
||||
JSFlatString* s = NewStringCopyN<NoGC>(cx, buffer, 3);
|
||||
JSFlatString* s = NewInlineString<NoGC>(cx, Latin1Range(buffer, 3));
|
||||
if (!s)
|
||||
return false;
|
||||
HashNumber hash = mozilla::HashString(buffer, 3);
|
||||
@@ -1029,10 +1031,31 @@ NewInlineStringDeflated(ExclusiveContext* cx, mozilla::Range<const char16_t> cha
|
||||
return str;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
static MOZ_ALWAYS_INLINE JSFlatString*
|
||||
TryEmptyOrStaticString(ExclusiveContext* cx, const CharT* chars, size_t n)
|
||||
{
|
||||
// Measurements on popular websites indicate empty strings are pretty common
|
||||
// and most strings with length 1 or 2 are in the StaticStrings table. For
|
||||
// length 3 strings that's only about 1%, so we check n <= 2.
|
||||
if (n <= 2) {
|
||||
if (n == 0)
|
||||
return cx->emptyString();
|
||||
|
||||
if (JSFlatString* str = cx->staticStrings().lookup(chars, n))
|
||||
return str;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JSFlatString*
|
||||
NewStringDeflated(ExclusiveContext* cx, const char16_t* s, size_t n)
|
||||
{
|
||||
if (JSFlatString* str = TryEmptyOrStaticString(cx, s, n))
|
||||
return str;
|
||||
|
||||
if (JSInlineString::lengthFits<Latin1Char>(n))
|
||||
return NewInlineStringDeflated<allowGC>(cx, mozilla::Range<const char16_t>(s, n));
|
||||
|
||||
@@ -1065,14 +1088,11 @@ template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString*
|
||||
js::NewStringDontDeflate(ExclusiveContext* cx, CharT* chars, size_t length)
|
||||
{
|
||||
if (length == 1) {
|
||||
char16_t c = chars[0];
|
||||
if (StaticStrings::hasUnit(c)) {
|
||||
// Free |chars| because we're taking possession of it, but it's no
|
||||
// longer needed because we use the static string instead.
|
||||
js_free(chars);
|
||||
return cx->staticStrings().getUnit(c);
|
||||
}
|
||||
if (JSFlatString* str = TryEmptyOrStaticString(cx, chars, length)) {
|
||||
// Free |chars| because we're taking possession of it, but it's no
|
||||
// longer needed because we use the static string instead.
|
||||
js_free(chars);
|
||||
return str;
|
||||
}
|
||||
|
||||
if (JSInlineString::lengthFits<CharT>(length)) {
|
||||
@@ -1105,14 +1125,6 @@ JSFlatString*
|
||||
js::NewString(ExclusiveContext* cx, CharT* chars, size_t length)
|
||||
{
|
||||
if (IsSame<CharT, char16_t>::value && CanStoreCharsAsLatin1(chars, length)) {
|
||||
if (length == 1) {
|
||||
char16_t c = chars[0];
|
||||
if (StaticStrings::hasUnit(c)) {
|
||||
js_free(chars);
|
||||
return cx->staticStrings().getUnit(c);
|
||||
}
|
||||
}
|
||||
|
||||
JSFlatString* s = NewStringDeflated<allowGC>(cx, chars, length);
|
||||
if (!s)
|
||||
return nullptr;
|
||||
@@ -1143,6 +1155,9 @@ template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString*
|
||||
NewStringCopyNDontDeflate(ExclusiveContext* cx, const CharT* s, size_t n)
|
||||
{
|
||||
if (JSFlatString* str = TryEmptyOrStaticString(cx, s, n))
|
||||
return str;
|
||||
|
||||
if (JSInlineString::lengthFits<CharT>(n))
|
||||
return NewInlineString<allowGC>(cx, mozilla::Range<const CharT>(s, n));
|
||||
|
||||
@@ -1198,6 +1213,24 @@ NewStringCopyN<CanGC>(ExclusiveContext* cx, const Latin1Char* s, size_t n);
|
||||
template JSFlatString*
|
||||
NewStringCopyN<NoGC>(ExclusiveContext* cx, const Latin1Char* s, size_t n);
|
||||
|
||||
JSString*
|
||||
NewMaybeExternalString(JSContext* cx, const char16_t* s, size_t n, const JSStringFinalizer* fin,
|
||||
bool* isExternal)
|
||||
{
|
||||
if (JSString* str = TryEmptyOrStaticString(cx, s, n)) {
|
||||
*isExternal = false;
|
||||
return str;
|
||||
}
|
||||
|
||||
if (JSThinInlineString::lengthFits<Latin1Char>(n) && CanStoreCharsAsLatin1(s, n)) {
|
||||
*isExternal = false;
|
||||
return NewInlineStringDeflated<AllowGC::CanGC>(cx, mozilla::Range<const char16_t>(s, n));
|
||||
}
|
||||
|
||||
*isExternal = true;
|
||||
return JSExternalString::new_(cx, s, n, fin);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -1267,6 +1267,10 @@ NewStringCopyZ(js::ExclusiveContext* cx, const char* s)
|
||||
return NewStringCopyN<allowGC>(cx, s, strlen(s));
|
||||
}
|
||||
|
||||
JSString*
|
||||
NewMaybeExternalString(JSContext* cx, const char16_t* s, size_t n, const JSStringFinalizer* fin,
|
||||
bool* isExternal);
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
@@ -80,9 +80,10 @@ XPCStringConvert::ReadableToJSVal(JSContext* cx,
|
||||
uint32_t length = readable.Length();
|
||||
|
||||
if (readable.IsLiteral()) {
|
||||
JSString* str = JS_NewExternalString(cx,
|
||||
static_cast<const char16_t*>(readable.BeginReading()),
|
||||
length, &sLiteralFinalizer);
|
||||
bool ignored;
|
||||
JSString* str = JS_NewMaybeExternalString(cx,
|
||||
static_cast<const char16_t*>(readable.BeginReading()),
|
||||
length, &sLiteralFinalizer, &ignored);
|
||||
if (!str)
|
||||
return false;
|
||||
vp.setString(str);
|
||||
|
||||
@@ -237,13 +237,22 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
JSString* str = JS_NewExternalString(cx,
|
||||
static_cast<char16_t*>(buf->Data()),
|
||||
length, &sDOMStringFinalizer);
|
||||
bool isExternal;
|
||||
JSString* str = JS_NewMaybeExternalString(cx,
|
||||
static_cast<char16_t*>(buf->Data()),
|
||||
length, &sDOMStringFinalizer, &isExternal);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
rval.setString(str);
|
||||
|
||||
// If JS_NewMaybeExternalString returns non-external string, finalizer
|
||||
// won't be called. Do not store it to cache.
|
||||
if (!isExternal) {
|
||||
*sharedBuffer = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!cache) {
|
||||
cache = new ZoneStringCache();
|
||||
JS_SetZoneUserData(zone, cache);
|
||||
|
||||
@@ -19,6 +19,7 @@ FramePropertyTable::Set(nsIFrame* aFrame, const FramePropertyDescriptor* aProper
|
||||
if (mLastFrame != aFrame || !mLastEntry) {
|
||||
mLastFrame = aFrame;
|
||||
mLastEntry = mEntries.PutEntry(aFrame);
|
||||
aFrame->AddStateBits(NS_FRAME_HAS_PROPERTIES);
|
||||
}
|
||||
Entry* entry = mLastEntry;
|
||||
|
||||
@@ -61,6 +62,7 @@ FramePropertyTable::Set(nsIFrame* aFrame, const FramePropertyDescriptor* aProper
|
||||
void*
|
||||
FramePropertyTable::Get(const nsIFrame* aFrame,
|
||||
const FramePropertyDescriptor* aProperty,
|
||||
bool aSkipBitCheck,
|
||||
bool* aFoundResult)
|
||||
{
|
||||
NS_ASSERTION(aFrame, "Null frame?");
|
||||
@@ -70,11 +72,19 @@ FramePropertyTable::Get(const nsIFrame* aFrame,
|
||||
*aFoundResult = false;
|
||||
}
|
||||
|
||||
if (!aSkipBitCheck && !(aFrame->GetStateBits() & NS_FRAME_HAS_PROPERTIES)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mLastFrame != aFrame) {
|
||||
mLastFrame = const_cast<nsIFrame*>(aFrame);
|
||||
mLastEntry = mEntries.GetEntry(mLastFrame);
|
||||
}
|
||||
Entry* entry = mLastEntry;
|
||||
|
||||
// If this assertion fires, see bug 1353187 (TenFourFox issue 375).
|
||||
MOZ_ASSERT(entry || aSkipBitCheck,
|
||||
"NS_FRAME_HAS_PROPERTIES bit should match whether entry exists");
|
||||
if (!entry)
|
||||
return nullptr;
|
||||
|
||||
@@ -103,7 +113,9 @@ FramePropertyTable::Get(const nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
void*
|
||||
FramePropertyTable::Remove(nsIFrame* aFrame, const FramePropertyDescriptor* aProperty,
|
||||
FramePropertyTable::Remove(nsIFrame* aFrame,
|
||||
const FramePropertyDescriptor* aProperty,
|
||||
bool aSkipBitCheck,
|
||||
bool* aFoundResult)
|
||||
{
|
||||
NS_ASSERTION(aFrame, "Null frame?");
|
||||
@@ -113,11 +125,19 @@ FramePropertyTable::Remove(nsIFrame* aFrame, const FramePropertyDescriptor* aPro
|
||||
*aFoundResult = false;
|
||||
}
|
||||
|
||||
if (!aSkipBitCheck && !(aFrame->GetStateBits() & NS_FRAME_HAS_PROPERTIES)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mLastFrame != aFrame) {
|
||||
mLastFrame = aFrame;
|
||||
mLastEntry = mEntries.GetEntry(aFrame);
|
||||
}
|
||||
Entry* entry = mLastEntry;
|
||||
|
||||
// If this assertion fires, see bug 1353187 (TenFourFox issue 375).
|
||||
MOZ_ASSERT(entry || aSkipBitCheck,
|
||||
"NS_FRAME_HAS_PROPERTIES bit should match whether entry exists");
|
||||
if (!entry)
|
||||
return nullptr;
|
||||
|
||||
@@ -125,6 +145,7 @@ FramePropertyTable::Remove(nsIFrame* aFrame, const FramePropertyDescriptor* aPro
|
||||
// There's only one entry and it's the one we want
|
||||
void* value = entry->mProp.mValue;
|
||||
mEntries.RawRemoveEntry(entry);
|
||||
aFrame->RemoveStateBits(NS_FRAME_HAS_PROPERTIES);
|
||||
mLastEntry = nullptr;
|
||||
if (aFoundResult) {
|
||||
*aFoundResult = true;
|
||||
@@ -164,13 +185,15 @@ FramePropertyTable::Remove(nsIFrame* aFrame, const FramePropertyDescriptor* aPro
|
||||
}
|
||||
|
||||
void
|
||||
FramePropertyTable::Delete(nsIFrame* aFrame, const FramePropertyDescriptor* aProperty)
|
||||
FramePropertyTable::Delete(nsIFrame* aFrame,
|
||||
const FramePropertyDescriptor* aProperty,
|
||||
bool aSkipBitCheck)
|
||||
{
|
||||
NS_ASSERTION(aFrame, "Null frame?");
|
||||
NS_ASSERTION(aProperty, "Null property?");
|
||||
|
||||
bool found;
|
||||
void* v = Remove(aFrame, aProperty, &found);
|
||||
void* v = Remove(aFrame, aProperty, aSkipBitCheck, &found);
|
||||
if (found) {
|
||||
PropertyValue pv(aProperty, v);
|
||||
pv.DestroyValueFor(aFrame);
|
||||
@@ -197,7 +220,14 @@ FramePropertyTable::DeleteAllFor(nsIFrame* aFrame)
|
||||
{
|
||||
NS_ASSERTION(aFrame, "Null frame?");
|
||||
|
||||
if (!(aFrame->GetStateBits() & NS_FRAME_HAS_PROPERTIES)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entry* entry = mEntries.GetEntry(aFrame);
|
||||
// If this assertion fires, see bug 1353187 (TenFourFox issue 375).
|
||||
MOZ_ASSERT(entry,
|
||||
"NS_FRAME_HAS_PROPERTIES bit should match whether entry exists");
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
@@ -210,6 +240,8 @@ FramePropertyTable::DeleteAllFor(nsIFrame* aFrame)
|
||||
|
||||
DeleteAllForEntry(entry);
|
||||
mEntries.RawRemoveEntry(entry);
|
||||
|
||||
// Don't bother unsetting NS_FRAME_HAS_PROPERTIES, since aFrame is going away
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -92,6 +92,7 @@ public:
|
||||
* 'property value is null'.
|
||||
*/
|
||||
void* Get(const nsIFrame* aFrame, const FramePropertyDescriptor* aProperty,
|
||||
bool aSkipBitCheck,
|
||||
bool* aFoundResult = nullptr);
|
||||
/**
|
||||
* Remove a property value for a frame. This requires one hashtable
|
||||
@@ -105,14 +106,30 @@ public:
|
||||
* 'property value is null'.
|
||||
*/
|
||||
void* Remove(nsIFrame* aFrame, const FramePropertyDescriptor* aProperty,
|
||||
bool aSkipBitCheck,
|
||||
bool* aFoundResult = nullptr);
|
||||
/**
|
||||
* Remove and destroy a property value for a frame. This requires one
|
||||
* hashtable lookup (using the frame as the key) and a linear search
|
||||
* through the properties of that frame. If the frame has no such
|
||||
* property, nothing happens.
|
||||
*
|
||||
* The DeleteSkippingBitCheck variant doesn't test
|
||||
* NS_FRAME_HAS_PROPERTIES on aFrame, so it is safe to call after
|
||||
* aFrame has been destroyed as long as, since that destruction
|
||||
* happened, it isn't possible for a new frame to have been created
|
||||
* and the same property added.
|
||||
*/
|
||||
void Delete(nsIFrame* aFrame, const FramePropertyDescriptor* aProperty);
|
||||
void Delete(nsIFrame* aFrame, const FramePropertyDescriptor* aProperty,
|
||||
bool aSkipBitCheck);
|
||||
|
||||
// TenFourFox issue 375, from M1353187.
|
||||
void DeleteSkippingBitCheck(nsIFrame* aFrame,
|
||||
const FramePropertyDescriptor* aProperty)
|
||||
{
|
||||
Delete(aFrame, aProperty, true /* aSkipBitCheck */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and destroy all property values for a frame. This requires one
|
||||
* hashtable lookup (using the frame as the key).
|
||||
@@ -129,7 +146,16 @@ public:
|
||||
bool Has(const nsIFrame* aFrame, const FramePropertyDescriptor* aProperty)
|
||||
{
|
||||
bool foundResult = false;
|
||||
(void)Get(aFrame, aProperty, &foundResult);
|
||||
(void)Get(aFrame, aProperty, false /* aSkipBitCheck */, &foundResult);
|
||||
return foundResult;
|
||||
}
|
||||
|
||||
// TenFourFox issue 375, from M1353187.
|
||||
bool HasSkippingBitCheck(const nsIFrame* aFrame,
|
||||
const FramePropertyDescriptor* aProperty)
|
||||
{
|
||||
bool foundResult = false;
|
||||
(void)Get(aFrame, aProperty, true /* aSkipBitCheck */, &foundResult);
|
||||
return foundResult;
|
||||
}
|
||||
|
||||
@@ -237,22 +263,22 @@ public:
|
||||
void* Get(const FramePropertyDescriptor* aProperty,
|
||||
bool* aFoundResult = nullptr) const
|
||||
{
|
||||
return mTable->Get(mFrame, aProperty, aFoundResult);
|
||||
return mTable->Get(mFrame, aProperty, false /* aSkipBitCheck */, aFoundResult);
|
||||
}
|
||||
void* Remove(const FramePropertyDescriptor* aProperty,
|
||||
bool* aFoundResult = nullptr) const
|
||||
{
|
||||
return mTable->Remove(mFrame, aProperty, aFoundResult);
|
||||
return mTable->Remove(mFrame, aProperty, false /* aSkipBitCheck */, aFoundResult);
|
||||
}
|
||||
void Delete(const FramePropertyDescriptor* aProperty)
|
||||
{
|
||||
mTable->Delete(mFrame, aProperty);
|
||||
mTable->Delete(mFrame, aProperty, false /* aSkipBitCheck */);
|
||||
}
|
||||
// TenFourFox issue 493
|
||||
bool Has(const FramePropertyDescriptor* aProperty)
|
||||
{
|
||||
bool foundResult;
|
||||
(void)mTable->Get(mFrame, aProperty, &foundResult);
|
||||
(void)mTable->Get(mFrame, aProperty, false /* aSkipBitCheck */, &foundResult);
|
||||
return foundResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ GetNextBlockInInlineSibling(FramePropertyTable* aPropTable, nsIFrame* aFrame)
|
||||
}
|
||||
|
||||
return static_cast<nsIFrame*>
|
||||
(aPropTable->Get(aFrame, nsIFrame::IBSplitSibling()));
|
||||
(aPropTable->Get(aFrame, nsIFrame::IBSplitSibling(), false /* aSkipBitCheck */));
|
||||
}
|
||||
|
||||
static nsIFrame*
|
||||
@@ -733,7 +733,7 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||
int32_t index = count;
|
||||
|
||||
while (0 <= --index) {
|
||||
const nsStyleChangeData* changeData;
|
||||
nsStyleChangeData* changeData;
|
||||
aChangeList.ChangeAt(index, &changeData);
|
||||
if (changeData->mFrame) {
|
||||
propTable->Set(changeData->mFrame, ChangeListProperty(),
|
||||
@@ -757,7 +757,13 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||
"Reflow hint bits set without actually asking for a reflow");
|
||||
|
||||
// skip any frame that has been destroyed due to a ripple effect
|
||||
if (frame && !propTable->Get(frame, ChangeListProperty())) {
|
||||
if (frame && !propTable->HasSkippingBitCheck(frame, ChangeListProperty())) {
|
||||
// Null out the pointer since the frame was already destroyed.
|
||||
// This is important so we don't try to delete its
|
||||
// ChangeListProperty() below. (marked as YYYY)
|
||||
nsStyleChangeData* changeData;
|
||||
aChangeList.ChangeAt(index, &changeData);
|
||||
changeData->mFrame = nullptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -806,6 +812,13 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||
}
|
||||
}
|
||||
if (hint & nsChangeHint_ReconstructFrame) {
|
||||
// We're about to destroy data.mFrame, so null out the pointer.
|
||||
// This is important so we don't try to delete its
|
||||
// ChangeListProperty() below. (marked as YYYY)
|
||||
nsStyleChangeData* changeData;
|
||||
aChangeList.ChangeAt(index, &changeData);
|
||||
changeData->mFrame = nullptr;
|
||||
|
||||
// If we ever start passing true here, be careful of restyles
|
||||
// that involve a reframe and animations. In particular, if the
|
||||
// restyle we're processing here is an animation restyle, but
|
||||
@@ -978,10 +991,10 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||
// is not in fact in a consistent state.
|
||||
index = count;
|
||||
while (0 <= --index) {
|
||||
const nsStyleChangeData* changeData;
|
||||
nsStyleChangeData* changeData;
|
||||
aChangeList.ChangeAt(index, &changeData);
|
||||
if (changeData->mFrame) {
|
||||
propTable->Delete(changeData->mFrame, ChangeListProperty());
|
||||
if (changeData->mFrame) { // YYYY see above
|
||||
propTable->DeleteSkippingBitCheck(changeData->mFrame, ChangeListProperty());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -822,7 +822,8 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
|
||||
static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
|
||||
nsPresContext* presContext = aFrame->PresContext();
|
||||
presContext->PropertyTable()->
|
||||
Delete(aFrame, nsDisplayListBuilder::OutOfFlowDisplayDataProperty());
|
||||
Delete(aFrame, nsDisplayListBuilder::OutOfFlowDisplayDataProperty(),
|
||||
false /* aSkipBitCheck */);
|
||||
|
||||
for (nsIFrame* f = aFrame; f;
|
||||
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "nsIWritablePropertyBag2.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsISelectionListener.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
@@ -884,12 +883,7 @@ nsDocumentViewer::InitInternal(nsIWidget* aParentWidget,
|
||||
nsCOMPtr<nsIInterfaceRequestor> requestor(mContainer);
|
||||
if (requestor) {
|
||||
if (mPresContext) {
|
||||
nsCOMPtr<nsILinkHandler> linkHandler;
|
||||
requestor->GetInterface(NS_GET_IID(nsILinkHandler),
|
||||
getter_AddRefs(linkHandler));
|
||||
|
||||
mPresContext->SetContainer(mContainer);
|
||||
mPresContext->SetLinkHandler(linkHandler);
|
||||
}
|
||||
|
||||
// Set script-context-owner in the document
|
||||
@@ -1368,7 +1362,6 @@ AttachContainerRecurse(nsIDocShell* aShell)
|
||||
viewer->GetPresContext(getter_AddRefs(pc));
|
||||
if (pc) {
|
||||
pc->SetContainer(static_cast<nsDocShell*>(aShell));
|
||||
pc->SetLinkHandler(nsCOMPtr<nsILinkHandler>(do_QueryInterface(aShell)));
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
viewer->GetPresShell(getter_AddRefs(presShell));
|
||||
@@ -2081,12 +2074,6 @@ nsDocumentViewer::Show(void)
|
||||
return rv;
|
||||
|
||||
if (mPresContext && base_win) {
|
||||
nsCOMPtr<nsILinkHandler> linkHandler(do_GetInterface(base_win));
|
||||
|
||||
if (linkHandler) {
|
||||
mPresContext->SetLinkHandler(linkHandler);
|
||||
}
|
||||
|
||||
mPresContext->SetContainer(mContainer);
|
||||
}
|
||||
|
||||
|
||||
@@ -1720,7 +1720,6 @@ nsPresContext::GetDocShell() const
|
||||
nsPresContext::Detach()
|
||||
{
|
||||
SetContainer(nullptr);
|
||||
SetLinkHandler(nullptr);
|
||||
if (mShell) {
|
||||
mShell->CancelInvalidatePresShellIfHidden();
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ class nsITheme;
|
||||
class nsIContent;
|
||||
class nsIFrame;
|
||||
class nsFrameManager;
|
||||
class nsILinkHandler;
|
||||
class nsIAtom;
|
||||
class nsIRunnable;
|
||||
class gfxUserFontEntry;
|
||||
@@ -436,13 +435,8 @@ public:
|
||||
|
||||
nsIDocShell* GetDocShell() const;
|
||||
|
||||
// XXX this are going to be replaced with set/get container
|
||||
void SetLinkHandler(nsILinkHandler* aHandler) { mLinkHandler = aHandler; }
|
||||
nsILinkHandler* GetLinkHandler() { return mLinkHandler; }
|
||||
|
||||
/**
|
||||
* Detach this pres context - i.e. cancel relevant timers,
|
||||
* SetLinkHandler(null), SetContainer(null) etc.
|
||||
* Detach this pres context - i.e. cancel relevant timers, etc.
|
||||
* Only to be used by the DocumentViewer.
|
||||
*/
|
||||
virtual void Detach();
|
||||
@@ -1228,10 +1222,6 @@ protected:
|
||||
nsIAtom* MOZ_UNSAFE_REF("always a static atom") mMedium; // initialized by subclass ctors
|
||||
nsCOMPtr<nsIAtom> mMediaEmulated;
|
||||
|
||||
// This pointer is nulled out through SetLinkHandler() in the destructors of
|
||||
// the classes which set it. (using SetLinkHandler() again).
|
||||
nsILinkHandler* MOZ_NON_OWNING_REF mLinkHandler;
|
||||
|
||||
// Formerly mLangGroup; moving from charset-oriented langGroup to
|
||||
// maintaining actual language settings everywhere (see bug 524107).
|
||||
// This may in fact hold a langGroup such as x-western rather than
|
||||
|
||||
@@ -1333,9 +1333,6 @@ PresShell::Destroy()
|
||||
// to us. To avoid the pres context having a dangling reference, set its
|
||||
// pres shell to nullptr
|
||||
mPresContext->SetShell(nullptr);
|
||||
|
||||
// Clear the link handler (weak reference) as well
|
||||
mPresContext->SetLinkHandler(nullptr);
|
||||
}
|
||||
|
||||
mHaveShutDown = true;
|
||||
@@ -1998,7 +1995,8 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
|
||||
// the DisplayItemData destructor will use the destroyed frame when it
|
||||
// tries to remove it from the (array) value of this property.
|
||||
mPresContext->PropertyTable()->
|
||||
Delete(aFrame, FrameLayerBuilder::LayerManagerDataProperty());
|
||||
Delete(aFrame, FrameLayerBuilder::LayerManagerDataProperty(),
|
||||
false /* aSkipBitCheck */);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ nsStyleChangeList::ChangeAt(int32_t aIndex, nsIFrame*& aFrame, nsIContent*& aCon
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsStyleChangeList::ChangeAt(int32_t aIndex, const nsStyleChangeData** aChangeData) const
|
||||
nsStyleChangeList::ChangeAt(int32_t aIndex, nsStyleChangeData** aChangeData) const
|
||||
{
|
||||
if ((0 <= aIndex) && (aIndex < mCount)) {
|
||||
*aChangeData = &mArray[aIndex];
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
* Fills in a pointer to the list entry storage (no reference counting
|
||||
* involved).
|
||||
*/
|
||||
nsresult ChangeAt(int32_t aIndex, const nsStyleChangeData** aChangeData) const;
|
||||
nsresult ChangeAt(int32_t aIndex, nsStyleChangeData** aChangeData) const;
|
||||
|
||||
nsresult AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChangeHint aHint);
|
||||
|
||||
|
||||
@@ -169,12 +169,12 @@ nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
|
||||
// delete the property -- that's why we fetch the property again before
|
||||
// removing each frame rather than fetching it once and iterating the list.
|
||||
while (nsFrameList* frameList =
|
||||
static_cast<nsFrameList*>(aPropTable->Get(this, aProp))) {
|
||||
static_cast<nsFrameList*>(aPropTable->Get(this, aProp, false /* aSkipBitCheck */))) {
|
||||
nsIFrame* frame = frameList->RemoveFirstChild();
|
||||
if (MOZ_LIKELY(frame)) {
|
||||
frame->DestroyFrom(aDestructRoot);
|
||||
} else {
|
||||
aPropTable->Remove(this, aProp);
|
||||
aPropTable->Remove(this, aProp, false /* aSkipBitCheck */);
|
||||
frameList->Delete(aPresShell);
|
||||
return;
|
||||
}
|
||||
@@ -201,8 +201,8 @@ nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
SafelyDestroyFrameListProp(aDestructRoot, shell, props, OverflowProperty());
|
||||
|
||||
MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers) ||
|
||||
!(props->Get(this, nsContainerFrame::OverflowContainersProperty()) ||
|
||||
props->Get(this, nsContainerFrame::ExcessOverflowContainersProperty())),
|
||||
!(props->Get(this, nsContainerFrame::OverflowContainersProperty(), false /* aSkipBitCheck */) ||
|
||||
props->Get(this, nsContainerFrame::ExcessOverflowContainersProperty(), false /* aSkipBitCheck */)),
|
||||
"this type of frame should't have overflow containers");
|
||||
|
||||
SafelyDestroyFrameListProp(aDestructRoot, shell, props,
|
||||
@@ -248,7 +248,7 @@ static void AppendIfNonempty(const nsIFrame* aFrame,
|
||||
nsIFrame::ChildListID aListID)
|
||||
{
|
||||
nsFrameList* list = static_cast<nsFrameList*>(
|
||||
aPropTable->Get(aFrame, aProperty));
|
||||
aPropTable->Get(aFrame, aProperty, false /* aSkipBitCheck */));
|
||||
if (list) {
|
||||
list->AppendIfNonempty(aLists, aListID);
|
||||
}
|
||||
@@ -1337,11 +1337,11 @@ static bool
|
||||
TryRemoveFrame(nsIFrame* aFrame, FramePropertyTable* aPropTable,
|
||||
const FramePropertyDescriptor* aProp, nsIFrame* aChildToRemove)
|
||||
{
|
||||
nsFrameList* list = static_cast<nsFrameList*>(aPropTable->Get(aFrame, aProp));
|
||||
nsFrameList* list = static_cast<nsFrameList*>(aPropTable->Get(aFrame, aProp, false /* aSkipBitCheck */));
|
||||
if (list && list->StartRemoveFrame(aChildToRemove)) {
|
||||
// aChildToRemove *may* have been removed from this list.
|
||||
if (list->IsEmpty()) {
|
||||
aPropTable->Remove(aFrame, aProp);
|
||||
aPropTable->Remove(aFrame, aProp, false /* aSkipBitCheck */);
|
||||
list->Delete(aFrame->PresContext()->PresShell());
|
||||
}
|
||||
return true;
|
||||
@@ -1359,10 +1359,10 @@ nsContainerFrame::StealFrame(nsIFrame* aChild,
|
||||
if (!list || !list->ContainsFrame(aChild)) {
|
||||
FramePropertyTable* propTable = PresContext()->PropertyTable();
|
||||
list = static_cast<nsFrameList*>(
|
||||
propTable->Get(this, OverflowContainersProperty()));
|
||||
propTable->Get(this, OverflowContainersProperty(), false /* aSkipBitCheck */));
|
||||
if (!list || !list->ContainsFrame(aChild)) {
|
||||
list = static_cast<nsFrameList*>(
|
||||
propTable->Get(this, ExcessOverflowContainersProperty()));
|
||||
propTable->Get(this, ExcessOverflowContainersProperty(), false /* aSkipBitCheck */));
|
||||
MOZ_ASSERT(list && list->ContainsFrame(aChild), "aChild isn't our child"
|
||||
" or on a frame list not supported by StealFrame");
|
||||
}
|
||||
@@ -1534,14 +1534,14 @@ nsFrameList*
|
||||
nsContainerFrame::GetPropTableFrames(const FramePropertyDescriptor* aProperty) const
|
||||
{
|
||||
FramePropertyTable* propTable = PresContext()->PropertyTable();
|
||||
return static_cast<nsFrameList*>(propTable->Get(this, aProperty));
|
||||
return static_cast<nsFrameList*>(propTable->Get(this, aProperty, false /* aSkipBitCheck */));
|
||||
}
|
||||
|
||||
nsFrameList*
|
||||
nsContainerFrame::RemovePropTableFrames(const FramePropertyDescriptor* aProperty)
|
||||
{
|
||||
FramePropertyTable* propTable = PresContext()->PropertyTable();
|
||||
return static_cast<nsFrameList*>(propTable->Remove(this, aProperty));
|
||||
return static_cast<nsFrameList*>(propTable->Remove(this, aProperty, false /* aSkipBitCheck */));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1957,10 +1957,12 @@ nsOverflowContinuationTracker::EndFinish(nsIFrame* aChild)
|
||||
nsPresContext* pc = aChild->PresContext();
|
||||
FramePropertyTable* propTable = pc->PropertyTable();
|
||||
nsFrameList* eoc = static_cast<nsFrameList*>(propTable->Get(mParent,
|
||||
nsContainerFrame::ExcessOverflowContainersProperty()));
|
||||
nsContainerFrame::ExcessOverflowContainersProperty(),
|
||||
false /* aSkipBitCheck */));
|
||||
if (eoc != mOverflowContList) {
|
||||
nsFrameList* oc = static_cast<nsFrameList*>(propTable->Get(mParent,
|
||||
nsContainerFrame::OverflowContainersProperty()));
|
||||
nsContainerFrame::OverflowContainersProperty(),
|
||||
false /* aSkipBitCheck */));
|
||||
if (oc != mOverflowContList) {
|
||||
// mOverflowContList was deleted
|
||||
mPrevOverflowCont = nullptr;
|
||||
|
||||
@@ -8914,8 +8914,9 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState,
|
||||
parentReflowState(aPresContext, parentFrame, aRenderingContext,
|
||||
LogicalSize(parentWM, parentSize),
|
||||
nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
|
||||
parentFrame->RemoveStateBits(~nsFrameState(0));
|
||||
parentFrame->AddStateBits(savedState);
|
||||
const nsFrameState bitsToLeaveUntouched = NS_FRAME_HAS_PROPERTIES;
|
||||
parentFrame->RemoveStateBits(~bitsToLeaveUntouched);
|
||||
parentFrame->AddStateBits(savedState & ~bitsToLeaveUntouched);
|
||||
|
||||
// This may not do very much useful, but it's probably worth trying.
|
||||
if (parentSize.width != NS_INTRINSICSIZE)
|
||||
|
||||
@@ -255,13 +255,17 @@ FRAME_STATE_BIT(Generic, 53, NS_FRAME_IS_NONDISPLAY)
|
||||
FRAME_STATE_BIT(Generic, 54, NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)
|
||||
|
||||
// The display list of the frame can be handled by the shortcut for
|
||||
// COMMON CASE. This is bug 1342009, but it uses bit 57. Since we might
|
||||
// implement NS_FRAME_HAS_PROPERTIES (56) in the near future, we will use bit
|
||||
// COMMON CASE. This is bug 1342009, but it uses bit 57. Since we have now
|
||||
// implemented NS_FRAME_HAS_PROPERTIES (56) in TenFourFox, we will use bit
|
||||
// 55. XXX: Dump bit 57 and make it all work out -- we'd need the backout
|
||||
// bits from bug 1250244 and then just not implement the replacement API.
|
||||
// However, that's only worth doing if we're really short on bits later.
|
||||
FRAME_STATE_BIT(Generic, 55, NS_FRAME_SIMPLE_DISPLAYLIST)
|
||||
|
||||
// Frame has properties in the nsIFrame::Properties() hash.
|
||||
// See bug 1353187 (TenFourFox issue 375).
|
||||
FRAME_STATE_BIT(Generic, 56, NS_FRAME_HAS_PROPERTIES)
|
||||
|
||||
// Frame has VR content, and needs VR display items created
|
||||
FRAME_STATE_BIT(Generic, 57, NS_FRAME_HAS_VR_CONTENT)
|
||||
|
||||
|
||||
@@ -2061,7 +2061,7 @@ nsImageFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
clicked = true;
|
||||
}
|
||||
nsContentUtils::TriggerLink(anchorNode, aPresContext, uri, target,
|
||||
nsContentUtils::TriggerLink(anchorNode, uri, target,
|
||||
clicked, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4210,9 +4210,12 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
|
||||
FramePropertyTable *propTable = PresContext()->PropertyTable();
|
||||
// Get all the properties from the prev-in-flow first to take
|
||||
// advantage of the propTable's cache and simplify the assertion below
|
||||
void* embeddingLevel = propTable->Get(aPrevInFlow, EmbeddingLevelProperty());
|
||||
void* baseLevel = propTable->Get(aPrevInFlow, BaseLevelProperty());
|
||||
void* paragraphDepth = propTable->Get(aPrevInFlow, ParagraphDepthProperty());
|
||||
void* embeddingLevel = propTable->Get(aPrevInFlow, EmbeddingLevelProperty(),
|
||||
false /* aSkipBitCheck */);
|
||||
void* baseLevel = propTable->Get(aPrevInFlow, BaseLevelProperty(), false /*
|
||||
aSkipBitCheck */);
|
||||
void* paragraphDepth = propTable->Get(aPrevInFlow, ParagraphDepthProperty(),
|
||||
false /* aSkipBitCheck */);
|
||||
propTable->Set(this, EmbeddingLevelProperty(), embeddingLevel);
|
||||
propTable->Set(this, BaseLevelProperty(), baseLevel);
|
||||
propTable->Set(this, ParagraphDepthProperty(), paragraphDepth);
|
||||
@@ -4224,9 +4227,12 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
|
||||
while (nextContinuation &&
|
||||
nextContinuation->GetContentOffset() < mContentOffset) {
|
||||
NS_ASSERTION(
|
||||
embeddingLevel == propTable->Get(nextContinuation, EmbeddingLevelProperty()) &&
|
||||
baseLevel == propTable->Get(nextContinuation, BaseLevelProperty()) &&
|
||||
paragraphDepth == propTable->Get(nextContinuation, ParagraphDepthProperty()),
|
||||
embeddingLevel == propTable->Get(nextContinuation,
|
||||
EmbeddingLevelProperty(), false /* aSkipBitCheck */) &&
|
||||
baseLevel == propTable->Get(nextContinuation, BaseLevelProperty(),
|
||||
false /* aSkipBitCheck */) &&
|
||||
paragraphDepth == propTable->Get(nextContinuation,
|
||||
ParagraphDepthProperty(), false /* aSkipBitCheck */),
|
||||
"stealing text from different type of BIDI continuation");
|
||||
nextContinuation->mContentOffset = mContentOffset;
|
||||
nextContinuation = static_cast<nsTextFrame*>(nextContinuation->GetNextContinuation());
|
||||
|
||||
@@ -180,7 +180,7 @@ nsMathMLContainerFrame::ClearSavedChildMetrics()
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
FramePropertyTable* props = PresContext()->PropertyTable();
|
||||
while (childFrame) {
|
||||
props->Delete(childFrame, HTMLReflowMetricsProperty());
|
||||
props->Delete(childFrame, HTMLReflowMetricsProperty(), false /* aSkipBitCheck */);
|
||||
childFrame = childFrame->GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,7 +765,7 @@ nsMathMLmtableOuterFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
aAttribute == nsGkAtoms::columnlines_) {
|
||||
// clear any cached property list for this table
|
||||
presContext->PropertyTable()->
|
||||
Delete(tableFrame, AttributeToProperty(aAttribute));
|
||||
Delete(tableFrame, AttributeToProperty(aAttribute), false /* aSkipBitCheck */);
|
||||
// Reparse the new attribute on the table.
|
||||
ParseFrameAttribute(tableFrame, aAttribute, true);
|
||||
} else {
|
||||
@@ -1117,7 +1117,7 @@ nsMathMLmtrFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute));
|
||||
presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute), false /* aSkipBitCheck */);
|
||||
|
||||
bool allowMultiValues = (aAttribute == nsGkAtoms::columnalign_);
|
||||
|
||||
@@ -1175,7 +1175,7 @@ nsMathMLmtdFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
aAttribute == nsGkAtoms::columnalign_) {
|
||||
|
||||
nsPresContext* presContext = PresContext();
|
||||
presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute));
|
||||
presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute), false /* aSkipBitCheck */);
|
||||
|
||||
// Reparse the attribute.
|
||||
ParseFrameAttribute(this, aAttribute, false);
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsImageMap.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsContainerFrame.h"
|
||||
|
||||
@@ -487,7 +487,8 @@ public:
|
||||
void GetFingerprint(nsAString& fingerprint)
|
||||
{
|
||||
char *tmp;
|
||||
GetFingerprint(&tmp);
|
||||
nsresult rv = GetFingerprint(&tmp);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
fingerprint.AssignASCII(tmp);
|
||||
delete[] tmp;
|
||||
}
|
||||
|
||||
@@ -1849,6 +1849,7 @@ pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign
|
||||
pref("network.cookie.cookieBehavior", 0); // Keep the old default of accepting all cookies
|
||||
#endif
|
||||
pref("network.cookie.thirdparty.sessionOnly", false);
|
||||
pref("network.cookie.leave-secure-alone", true);
|
||||
pref("network.cookie.same-site.enabled", true); // Honor the SameSite cookie attribute
|
||||
pref("network.cookie.lifetimePolicy", 0); // 0-accept, 1-dontUse 2-acceptForSession, 3-acceptForNDays
|
||||
pref("network.cookie.alwaysAcceptSessionCookies", false);
|
||||
|
||||
@@ -115,11 +115,12 @@ static const uint32_t kMaxBytesPerCookie = 4096;
|
||||
static const uint32_t kMaxBytesPerPath = 1024;
|
||||
|
||||
// pref string constants
|
||||
static const char kPrefCookieBehavior[] = "network.cookie.cookieBehavior";
|
||||
static const char kPrefMaxNumberOfCookies[] = "network.cookie.maxNumber";
|
||||
static const char kPrefMaxCookiesPerHost[] = "network.cookie.maxPerHost";
|
||||
static const char kPrefCookiePurgeAge[] = "network.cookie.purgeAge";
|
||||
static const char kPrefThirdPartySession[] = "network.cookie.thirdparty.sessionOnly";
|
||||
static const char kPrefCookieBehavior[] = "network.cookie.cookieBehavior";
|
||||
static const char kPrefMaxNumberOfCookies[] = "network.cookie.maxNumber";
|
||||
static const char kPrefMaxCookiesPerHost[] = "network.cookie.maxPerHost";
|
||||
static const char kPrefCookiePurgeAge[] = "network.cookie.purgeAge";
|
||||
static const char kPrefThirdPartySession[] = "network.cookie.thirdparty.sessionOnly";
|
||||
static const char kCookieLeaveSecurityAlone[] = "network.cookie.leave-secure-alone";
|
||||
|
||||
static void
|
||||
bindCookieParameters(mozIStorageBindingParamsArray *aParamsArray,
|
||||
@@ -710,6 +711,7 @@ nsCookieService::nsCookieService()
|
||||
: mDBState(nullptr)
|
||||
, mCookieBehavior(nsICookieService::BEHAVIOR_ACCEPT)
|
||||
, mThirdPartySession(false)
|
||||
, mLeaveSecureAlone(true)
|
||||
, mMaxNumberOfCookies(kMaxNumberOfCookies)
|
||||
, mMaxCookiesPerHost(kMaxCookiesPerHost)
|
||||
, mCookiePurgeAge(kCookiePurgeAge)
|
||||
@@ -732,11 +734,12 @@ nsCookieService::Init()
|
||||
// init our pref and observer
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefBranch) {
|
||||
prefBranch->AddObserver(kPrefCookieBehavior, this, true);
|
||||
prefBranch->AddObserver(kPrefMaxNumberOfCookies, this, true);
|
||||
prefBranch->AddObserver(kPrefMaxCookiesPerHost, this, true);
|
||||
prefBranch->AddObserver(kPrefCookiePurgeAge, this, true);
|
||||
prefBranch->AddObserver(kPrefThirdPartySession, this, true);
|
||||
prefBranch->AddObserver(kPrefCookieBehavior, this, true);
|
||||
prefBranch->AddObserver(kPrefMaxNumberOfCookies, this, true);
|
||||
prefBranch->AddObserver(kPrefMaxCookiesPerHost, this, true);
|
||||
prefBranch->AddObserver(kPrefCookiePurgeAge, this, true);
|
||||
prefBranch->AddObserver(kPrefThirdPartySession, this, true);
|
||||
prefBranch->AddObserver(kCookieLeaveSecurityAlone, this, true);
|
||||
PrefChanged(prefBranch);
|
||||
}
|
||||
|
||||
@@ -2210,6 +2213,9 @@ nsCookieService::PrefChanged(nsIPrefBranch *aPrefBranch)
|
||||
bool boolval;
|
||||
if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kPrefThirdPartySession, &boolval)))
|
||||
mThirdPartySession = boolval;
|
||||
|
||||
if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kCookieLeaveSecurityAlone, &boolval)))
|
||||
mLeaveSecureAlone = boolval;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -2952,6 +2958,47 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static bool
|
||||
DomainMatches(nsCookie* aCookie, const nsACString& aHost) {
|
||||
// first, check for an exact host or domain cookie match, e.g. "google.com"
|
||||
// or ".google.com"; second a subdomain match, e.g.
|
||||
// host = "mail.google.com", cookie domain = ".google.com".
|
||||
return aCookie->RawHost() == aHost ||
|
||||
(aCookie->IsDomain() && StringEndsWith(aHost, aCookie->Host()));
|
||||
}
|
||||
|
||||
static bool
|
||||
PathMatches(nsCookie* aCookie, const nsACString& aPath) {
|
||||
// calculate cookie path length, excluding trailing '/'
|
||||
uint32_t cookiePathLen = aCookie->Path().Length();
|
||||
if (cookiePathLen > 0 && aCookie->Path().Last() == '/')
|
||||
--cookiePathLen;
|
||||
|
||||
// if the given path is shorter than the cookie path, it doesn't match
|
||||
// if the given path doesn't start with the cookie path, it doesn't match.
|
||||
if (!StringBeginsWith(aPath, Substring(aCookie->Path(), 0, cookiePathLen)))
|
||||
return false;
|
||||
|
||||
// if the given path is longer than the cookie path, and the first char after
|
||||
// the cookie path is not a path delimiter, it doesn't match.
|
||||
if (aPath.Length() > cookiePathLen &&
|
||||
!ispathdelimiter(aPath.CharAt(cookiePathLen))) {
|
||||
/*
|
||||
* |ispathdelimiter| tests four cases: '/', '?', '#', and ';'.
|
||||
* '/' is the "standard" case; the '?' test allows a site at host/abc?def
|
||||
* to receive a cookie that has a path attribute of abc. this seems
|
||||
* strange but at least one major site (citibank, bug 156725) depends
|
||||
* on it. The test for # and ; are put in to proactively avoid problems
|
||||
* with other sites - these are the only other chars allowed in the path.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
// either the paths match exactly, or the cookie path is a prefix of
|
||||
// the given path.
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsCookieService::GetCookieStringInternal(nsIURI *aHostURI,
|
||||
bool aIsForeign,
|
||||
@@ -3029,11 +3076,7 @@ nsCookieService::GetCookieStringInternal(nsIURI *aHostURI,
|
||||
cookie = cookies[i];
|
||||
|
||||
// check the host, since the base domain lookup is conservative.
|
||||
// first, check for an exact host or domain cookie match, e.g. "google.com"
|
||||
// or ".google.com"; second a subdomain match, e.g.
|
||||
// host = "mail.google.com", cookie domain = ".google.com".
|
||||
if (cookie->RawHost() != hostFromURI &&
|
||||
!(cookie->IsDomain() && StringEndsWith(hostFromURI, cookie->Host())))
|
||||
if (!DomainMatches(cookie, hostFromURI))
|
||||
continue;
|
||||
|
||||
// if the cookie is secure and the host scheme isn't, we can't send it
|
||||
@@ -3060,28 +3103,10 @@ nsCookieService::GetCookieStringInternal(nsIURI *aHostURI,
|
||||
if (cookie->IsHttpOnly() && !aHttpBound)
|
||||
continue;
|
||||
|
||||
// calculate cookie path length, excluding trailing '/'
|
||||
uint32_t cookiePathLen = cookie->Path().Length();
|
||||
if (cookiePathLen > 0 && cookie->Path().Last() == '/')
|
||||
--cookiePathLen;
|
||||
|
||||
// if the nsIURI path is shorter than the cookie path, don't send it back
|
||||
if (!StringBeginsWith(pathFromURI, Substring(cookie->Path(), 0, cookiePathLen)))
|
||||
// if the nsIURI path doesn't match the cookie path, don't send it back
|
||||
if (!PathMatches(cookie, pathFromURI))
|
||||
continue;
|
||||
|
||||
if (pathFromURI.Length() > cookiePathLen &&
|
||||
!ispathdelimiter(pathFromURI.CharAt(cookiePathLen))) {
|
||||
/*
|
||||
* |ispathdelimiter| tests four cases: '/', '?', '#', and ';'.
|
||||
* '/' is the "standard" case; the '?' test allows a site at host/abc?def
|
||||
* to receive a cookie that has a path attribute of abc. this seems
|
||||
* strange but at least one major site (citibank, bug 156725) depends
|
||||
* on it. The test for # and ; are put in to proactively avoid problems
|
||||
* with other sites - these are the only other chars allowed in the path.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if the cookie has expired
|
||||
if (cookie->Expiry() <= currentTime) {
|
||||
continue;
|
||||
@@ -3345,14 +3370,51 @@ nsCookieService::AddInternal(const nsCookieKey &aKey,
|
||||
return;
|
||||
}
|
||||
|
||||
nsListIter matchIter;
|
||||
bool foundCookie = FindCookie(aKey, aCookie->Host(),
|
||||
aCookie->Name(), aCookie->Path(), matchIter);
|
||||
bool isSecure = true;
|
||||
if (aHostURI && NS_FAILED(aHostURI->SchemeIs("https", &isSecure))) {
|
||||
isSecure = false;
|
||||
}
|
||||
|
||||
// If the new cookie is non-https and wants to set secure flag,
|
||||
// browser have to ignore this new cookie.
|
||||
// (draft-ietf-httpbis-cookie-alone section 3.1)
|
||||
if (mLeaveSecureAlone && aCookie->IsSecure() && !isSecure) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
|
||||
"non-https cookie can't set secure flag");
|
||||
return;
|
||||
}
|
||||
nsListIter exactIter;
|
||||
bool foundCookie = false;
|
||||
if (mLeaveSecureAlone) {
|
||||
// Step1, call FindSecureCookie(). FindSecureCookie() would
|
||||
// find the existing cookie with the security flag and has
|
||||
// the same name, host and path of the new cookie, if there is any.
|
||||
// Step2, Confirm new cookie's security setting. If any targeted
|
||||
// cookie had been found in Step1, then confirm whether the
|
||||
// new cookie could modify it. If the new created cookie’s
|
||||
// "secure-only-flag" is not set, and the "scheme" component
|
||||
// of the "request-uri" does not denote a "secure" protocol,
|
||||
// then ignore the new cookie.
|
||||
// (draft-ietf-httpbis-cookie-alone section 3.2)
|
||||
foundCookie = FindSecureCookie(aKey, aCookie);
|
||||
if (foundCookie && !aCookie->IsSecure()) {
|
||||
if (!isSecure) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
|
||||
"cookie can't save because older cookie is secure cookie but newer cookie is non-secure cookie");
|
||||
return;
|
||||
} else {
|
||||
// A secure site is allowed to downgrade a secure cookie
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foundCookie = FindCookie(aKey, aCookie->Host(),
|
||||
aCookie->Name(), aCookie->Path(), exactIter);
|
||||
|
||||
RefPtr<nsCookie> oldCookie;
|
||||
nsCOMPtr<nsIArray> purgedList;
|
||||
if (foundCookie) {
|
||||
oldCookie = matchIter.Cookie();
|
||||
oldCookie = exactIter.Cookie();
|
||||
|
||||
// Check if the old cookie is stale (i.e. has already expired). If so, we
|
||||
// need to be careful about the semantics of removing it and adding the new
|
||||
@@ -3368,7 +3430,7 @@ nsCookieService::AddInternal(const nsCookieKey &aKey,
|
||||
|
||||
// Remove the stale cookie. We save notification for later, once all list
|
||||
// modifications are complete.
|
||||
RemoveCookieFromList(matchIter);
|
||||
RemoveCookieFromList(exactIter);
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
|
||||
"stale cookie was purged");
|
||||
purgedList = CreatePurgeList(oldCookie);
|
||||
@@ -3405,7 +3467,7 @@ nsCookieService::AddInternal(const nsCookieKey &aKey,
|
||||
}
|
||||
|
||||
// Remove the old cookie.
|
||||
RemoveCookieFromList(matchIter);
|
||||
RemoveCookieFromList(exactIter);
|
||||
|
||||
// If the new cookie has expired -- i.e. the intent was simply to delete
|
||||
// the old cookie -- then we're done.
|
||||
@@ -3432,14 +3494,30 @@ nsCookieService::AddInternal(const nsCookieKey &aKey,
|
||||
nsCookieEntry *entry = mDBState->hostTable.GetEntry(aKey);
|
||||
if (entry && entry->GetCookies().Length() >= mMaxCookiesPerHost) {
|
||||
nsListIter iter;
|
||||
FindStaleCookie(entry, currentTime, iter);
|
||||
// Prioritize evicting insecure cookies.
|
||||
// (draft-ietf-httpbis-cookie-alone section 3.3)
|
||||
mozilla::Maybe<bool> optionalSecurity = mLeaveSecureAlone ? Some(false) :
|
||||
Nothing();
|
||||
int64_t oldestCookieTime = FindStaleCookie(entry, currentTime, optionalSecurity, iter);
|
||||
if (iter.entry == nullptr) {
|
||||
if (aCookie->IsSecure()) {
|
||||
// It's valid to evict a secure cookie for another secure cookie.
|
||||
oldestCookieTime = FindStaleCookie(entry, currentTime, Some(true), iter);
|
||||
} else {
|
||||
COOKIE_LOGEVICTED(aCookie,
|
||||
"Too many cookies for this domain and the new cookie is not a secure cookie");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(iter.entry);
|
||||
|
||||
oldCookie = iter.Cookie();
|
||||
|
||||
// remove the oldest cookie from the domain
|
||||
RemoveCookieFromList(iter);
|
||||
COOKIE_LOGEVICTED(oldCookie, "Too many cookies for this domain");
|
||||
purgedList = CreatePurgeList(oldCookie);
|
||||
|
||||
} else if (mDBState->cookieCount >= ADD_TEN_PERCENT(mMaxNumberOfCookies)) {
|
||||
int64_t maxAge = aCurrentTimeInUsec - mDBState->cookieOldestTime;
|
||||
int64_t purgeAge = ADD_TEN_PERCENT(mCookiePurgeAge);
|
||||
@@ -4286,15 +4364,16 @@ nsCookieService::CookieExists(nsICookie2 *aCookie,
|
||||
|
||||
// For a given base domain, find either an expired cookie or the oldest cookie
|
||||
// by lastAccessed time.
|
||||
void
|
||||
int64_t
|
||||
nsCookieService::FindStaleCookie(nsCookieEntry *aEntry,
|
||||
int64_t aCurrentTime,
|
||||
mozilla::Maybe<bool> aIsSecure,
|
||||
nsListIter &aIter)
|
||||
{
|
||||
aIter.entry = nullptr;
|
||||
|
||||
int64_t oldestTime = 0;
|
||||
const nsCookieEntry::ArrayType &cookies = aEntry->GetCookies();
|
||||
int64_t actualOldestCookieTime = cookies.Length() ? cookies[0]->LastAccessed() : 0;
|
||||
for (nsCookieEntry::IndexType i = 0; i < cookies.Length(); ++i) {
|
||||
nsCookie *cookie = cookies[i];
|
||||
|
||||
@@ -4302,16 +4381,34 @@ nsCookieService::FindStaleCookie(nsCookieEntry *aEntry,
|
||||
if (cookie->Expiry() <= aCurrentTime) {
|
||||
aIter.entry = aEntry;
|
||||
aIter.index = i;
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t lastAccessed = cookie->LastAccessed();
|
||||
// Record the age of the oldest cookie that is stored for this host.
|
||||
// oldestCookieTime is the age of the oldest cookie with a matching
|
||||
// secure flag, which may be more recent than an older cookie with
|
||||
// a non-matching secure flag.
|
||||
if (actualOldestCookieTime > lastAccessed) {
|
||||
actualOldestCookieTime = lastAccessed;
|
||||
}
|
||||
if (aIsSecure.isSome() && !aIsSecure.value()) {
|
||||
// We want to look for the oldest non-secure cookie first time through,
|
||||
// then find the oldest secure cookie the second time we are called.
|
||||
if (cookie->IsSecure()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we've found the oldest cookie so far.
|
||||
if (!aIter.entry || oldestTime > cookie->LastAccessed()) {
|
||||
oldestTime = cookie->LastAccessed();
|
||||
if (!aIter.entry || oldestTime > lastAccessed) {
|
||||
oldestTime = lastAccessed;
|
||||
aIter.entry = aEntry;
|
||||
aIter.index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return actualOldestCookieTime;
|
||||
}
|
||||
|
||||
// count the number of cookies stored by a particular host. this is provided by the
|
||||
@@ -4458,6 +4555,40 @@ nsCookieService::RemoveCookiesForApp(uint32_t aAppId, bool aOnlyBrowserElement)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// find an secure cookie specified by host and name
|
||||
bool
|
||||
nsCookieService::FindSecureCookie(const nsCookieKey &aKey,
|
||||
nsCookie *aCookie)
|
||||
{
|
||||
EnsureReadDomain(aKey);
|
||||
|
||||
nsCookieEntry *entry = mDBState->hostTable.GetEntry(aKey);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
const nsCookieEntry::ArrayType &cookies = entry->GetCookies();
|
||||
for (nsCookieEntry::IndexType i = 0; i < cookies.Length(); ++i) {
|
||||
nsCookie *cookie = cookies[i];
|
||||
// isn't a match if insecure or a different name
|
||||
if (!cookie->IsSecure() || !aCookie->Name().Equals(cookie->Name()))
|
||||
continue;
|
||||
|
||||
// The host must "domain-match" an existing cookie or vice-versa
|
||||
if (DomainMatches(cookie, aCookie->Host()) ||
|
||||
DomainMatches(aCookie, cookie->Host())) {
|
||||
// If the path of new cookie and the path of existing cookie
|
||||
// aren't "/", then this situation needs to compare paths to
|
||||
// ensure only that a newly-created non-secure cookie does not
|
||||
// overlay an existing secure cookie.
|
||||
if (PathMatches(cookie, aCookie->Path())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// find an exact cookie specified by host, name, and path that hasn't expired.
|
||||
bool
|
||||
nsCookieService::FindCookie(const nsCookieKey &aKey,
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
#include "nsIVariant.h"
|
||||
#include "nsIFile.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
using mozilla::NeckoOriginAttributes;
|
||||
|
||||
@@ -295,9 +295,9 @@ class nsCookieService final : public nsICookieService
|
||||
nsresult GetBaseDomain(nsIURI *aHostURI, nsCString &aBaseDomain, bool &aRequireHostMatch);
|
||||
nsresult GetBaseDomainFromHost(const nsACString &aHost, nsCString &aBaseDomain);
|
||||
nsresult GetCookieStringCommon(nsIURI *aHostURI, nsIChannel *aChannel, bool aHttpBound, char** aCookie);
|
||||
void GetCookieStringInternal(nsIURI *aHostURI, bool aIsForeign, bool aHttpBound, bool aIsSafeTopLevelNav, bool aIsTopLevelForeign, const NeckoOriginAttributes aOriginAttrs, bool aIsPrivate, nsCString &aCookie);
|
||||
void GetCookieStringInternal(nsIURI *aHostURI, bool aIsForeign, bool aHttpBound, bool aIsSafeTopLevelNav, bool aIsTopLevelForeign, const NeckoOriginAttributes aOriginAttrs, bool aIsPrivate, nsCString &aCookie);
|
||||
nsresult SetCookieStringCommon(nsIURI *aHostURI, const char *aCookieHeader, const char *aServerTime, nsIChannel *aChannel, bool aFromHttp);
|
||||
void SetCookieStringInternal(nsIURI *aHostURI, bool aIsForeign, nsDependentCString &aCookieHeader, const nsCString &aServerTime, bool aFromHttp, const NeckoOriginAttributes &aOriginAttrs, bool aIsPrivate, nsIChannel* aChannel);
|
||||
void SetCookieStringInternal(nsIURI *aHostURI, bool aIsForeign, nsDependentCString &aCookieHeader, const nsCString &aServerTime, bool aFromHttp, const NeckoOriginAttributes &aOriginAttrs, bool aIsPrivate, nsIChannel* aChannel);
|
||||
bool SetCookieInternal(nsIURI *aHostURI, const nsCookieKey& aKey, bool aRequireHostMatch, CookieStatus aStatus, nsDependentCString &aCookieHeader, int64_t aServerTime, bool aFromHttp, nsIChannel* aChannel);
|
||||
void AddInternal(const nsCookieKey& aKey, nsCookie *aCookie, int64_t aCurrentTimeInUsec, nsIURI *aHostURI, const char *aCookieHeader, bool aFromHttp);
|
||||
void RemoveCookieFromList(const nsListIter &aIter, mozIStorageBindingParamsArray *aParamsArray = nullptr);
|
||||
@@ -313,7 +313,8 @@ class nsCookieService final : public nsICookieService
|
||||
void RemoveAllFromMemory();
|
||||
already_AddRefed<nsIArray> PurgeCookies(int64_t aCurrentTimeInUsec);
|
||||
bool FindCookie(const nsCookieKey& aKey, const nsAFlatCString &aHost, const nsAFlatCString &aName, const nsAFlatCString &aPath, nsListIter &aIter);
|
||||
static void FindStaleCookie(nsCookieEntry *aEntry, int64_t aCurrentTime, nsListIter &aIter);
|
||||
bool FindSecureCookie(const nsCookieKey& aKey, nsCookie* aCookie);
|
||||
static int64_t FindStaleCookie(nsCookieEntry *aEntry, int64_t aCurrentTime, mozilla::Maybe<bool> aIsSecure, nsListIter &aIter);
|
||||
void NotifyRejected(nsIURI *aHostURI);
|
||||
void NotifyThirdParty(nsIURI *aHostURI, bool aAccepted, nsIChannel *aChannel);
|
||||
void NotifyChanged(nsISupports *aSubject, const char16_t *aData);
|
||||
@@ -350,6 +351,7 @@ class nsCookieService final : public nsICookieService
|
||||
// cached prefs
|
||||
uint8_t mCookieBehavior; // BEHAVIOR_{ACCEPT, REJECTFOREIGN, REJECT, LIMITFOREIGN}
|
||||
bool mThirdPartySession;
|
||||
bool mLeaveSecureAlone;
|
||||
uint16_t mMaxNumberOfCookies;
|
||||
uint16_t mMaxCookiesPerHost;
|
||||
int64_t mCookiePurgeAge;
|
||||
|
||||
@@ -1368,7 +1368,7 @@ it
|
||||
gov.it
|
||||
edu.it
|
||||
// Reserved geo-names (regions and provinces):
|
||||
// http://www.nic.it/sites/default/files/docs/Regulation_assignation_v7.1.pdf
|
||||
// https://www.nic.it/sites/default/files/archivio/docs/Regulation_assignation_v7.1.pdf
|
||||
// Regions
|
||||
abr.it
|
||||
abruzzo.it
|
||||
@@ -6038,9 +6038,12 @@ org.sn
|
||||
perso.sn
|
||||
univ.sn
|
||||
|
||||
// so : http://www.soregistry.com/
|
||||
// so : http://sonic.so/policies/
|
||||
so
|
||||
com.so
|
||||
edu.so
|
||||
gov.so
|
||||
me.so
|
||||
net.so
|
||||
org.so
|
||||
|
||||
@@ -7075,7 +7078,7 @@ org.zw
|
||||
|
||||
// newGTLDs
|
||||
|
||||
// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2019-10-13T16:52:09Z
|
||||
// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2019-11-15T17:07:54Z
|
||||
// This list is auto-generated, don't edit it manually.
|
||||
// aaa : 2015-02-26 American Automobile Association, Inc.
|
||||
aaa
|
||||
@@ -7587,9 +7590,6 @@ careers
|
||||
// cars : 2014-11-13 Cars Registry Limited
|
||||
cars
|
||||
|
||||
// cartier : 2014-06-23 Richemont DNS Inc.
|
||||
cartier
|
||||
|
||||
// casa : 2013-11-21 Minds + Machines Group Limited
|
||||
casa
|
||||
|
||||
@@ -8058,9 +8058,6 @@ eus
|
||||
// events : 2013-12-05 Binky Moon, LLC
|
||||
events
|
||||
|
||||
// everbank : 2014-05-15 EverBank
|
||||
everbank
|
||||
|
||||
// exchange : 2014-03-06 Binky Moon, LLC
|
||||
exchange
|
||||
|
||||
@@ -8334,7 +8331,7 @@ gmail
|
||||
// gmbh : 2016-01-29 Binky Moon, LLC
|
||||
gmbh
|
||||
|
||||
// gmo : 2014-01-09 GMO Internet Pte. Ltd.
|
||||
// gmo : 2014-01-09 GMO Internet, Inc.
|
||||
gmo
|
||||
|
||||
// gmx : 2014-04-24 1&1 Mail & Media GmbH
|
||||
@@ -9345,9 +9342,6 @@ photos
|
||||
// physio : 2014-05-01 PhysBiz Pty Ltd
|
||||
physio
|
||||
|
||||
// piaget : 2014-10-16 Richemont DNS Inc.
|
||||
piaget
|
||||
|
||||
// pics : 2013-11-14 Uniregistry, Corp.
|
||||
pics
|
||||
|
||||
@@ -9459,7 +9453,7 @@ qpon
|
||||
// quebec : 2013-12-19 PointQuébec Inc
|
||||
quebec
|
||||
|
||||
// quest : 2015-03-26 Quest ION Limited
|
||||
// quest : 2015-03-26 XYZ.COM LLC
|
||||
quest
|
||||
|
||||
// qvc : 2015-07-30 QVC, Inc.
|
||||
@@ -10362,7 +10356,7 @@ xin
|
||||
// xn--3bst00m : 2013-09-13 Eagle Horizon Limited
|
||||
集团
|
||||
|
||||
// xn--3ds443g : 2013-09-08 TLD REGISTRY LIMITED
|
||||
// xn--3ds443g : 2013-09-08 TLD REGISTRY LIMITED OY
|
||||
在线
|
||||
|
||||
// xn--3oq18vl8pn36a : 2015-07-02 Volkswagen (China) Investment Co., Ltd.
|
||||
@@ -10467,7 +10461,7 @@ xin
|
||||
// xn--fhbei : 2015-01-15 VeriSign Sarl
|
||||
كوم
|
||||
|
||||
// xn--fiq228c5hs : 2013-09-08 TLD REGISTRY LIMITED
|
||||
// xn--fiq228c5hs : 2013-09-08 TLD REGISTRY LIMITED OY
|
||||
中文网
|
||||
|
||||
// xn--fiq64b : 2013-10-14 CITIC Group Corporation
|
||||
@@ -10842,12 +10836,6 @@ sweetpepper.org
|
||||
// Submitted by Vincent Tseng <vincenttseng@asustor.com>
|
||||
myasustor.com
|
||||
|
||||
// Automattic Inc. : https://automattic.com/
|
||||
// Submitted by Alex Concha <alex.concha@automattic.com>
|
||||
go-vip.co
|
||||
go-vip.net
|
||||
wpcomstaging.com
|
||||
|
||||
// AVM : https://avm.de
|
||||
// Submitted by Andreas Weise <a.weise@avm.de>
|
||||
myfritz.net
|
||||
@@ -12665,6 +12653,10 @@ logoip.com
|
||||
// Submitted by Hanno Böck <hanno@schokokeks.org>
|
||||
schokokeks.net
|
||||
|
||||
// Scottish Government: https://www.gov.scot
|
||||
// Submitted by Martin Ellis <martin.ellis@gov.scot>
|
||||
gov.scot
|
||||
|
||||
// Scry Security : http://www.scrysec.com
|
||||
// Submitted by Shante Adam <shante@skyhat.io>
|
||||
scrysec.com
|
||||
|
||||
@@ -29,6 +29,8 @@ var gOverrides = new Map;
|
||||
var gUpdatedOverrides;
|
||||
var gOverrideForHostCache = new Map;
|
||||
var gInitialized = false;
|
||||
var gRegisteredWithNecko = false;
|
||||
|
||||
var gOverrideFunctions = [
|
||||
function (aHttpChannel) { return UserAgentOverrides.getOverrideForURI(aHttpChannel.URI); }
|
||||
];
|
||||
@@ -42,15 +44,6 @@ this.UserAgentOverrides = {
|
||||
gPrefBranch = Services.prefs.getBranch("general.useragent.override.");
|
||||
gPrefBranch.addObserver("", buildOverrides, false);
|
||||
|
||||
ppmm.addMessageListener(OVERRIDE_MESSAGE, this);
|
||||
Services.prefs.addObserver(PREF_OVERRIDES_ENABLED, buildOverrides, false);
|
||||
|
||||
try {
|
||||
Services.obs.addObserver(HTTP_on_modify_request, "http-on-modify-request", false);
|
||||
} catch (x) {
|
||||
// The http-on-modify-request notification is disallowed in content processes.
|
||||
}
|
||||
|
||||
UserAgentUpdates.init(function(overrides) {
|
||||
gOverrideForHostCache.clear();
|
||||
if (overrides) {
|
||||
@@ -72,10 +65,12 @@ this.UserAgentOverrides = {
|
||||
},
|
||||
|
||||
getOverrideForURI: function uao_getOverrideForURI(aURI) {
|
||||
if (!gInitialized || !gRegisteredWithNecko ||
|
||||
(!gOverrides.size && !gUpdatedOverrides))
|
||||
return null;
|
||||
|
||||
let host = aURI.asciiHost;
|
||||
if (!gInitialized ||
|
||||
(!gOverrides.size && !gUpdatedOverrides) ||
|
||||
!(host)) {
|
||||
if (!(host)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -118,7 +113,7 @@ this.UserAgentOverrides = {
|
||||
|
||||
Services.prefs.removeObserver(PREF_OVERRIDES_ENABLED, buildOverrides);
|
||||
|
||||
Services.obs.removeObserver(HTTP_on_modify_request, "http-on-modify-request");
|
||||
unregisterWithNecko();
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
@@ -133,6 +128,30 @@ this.UserAgentOverrides = {
|
||||
}
|
||||
};
|
||||
|
||||
function registerWithNecko() {
|
||||
if (gRegisteredWithNecko) {
|
||||
return;
|
||||
}
|
||||
|
||||
ppmm.addMessageListener(OVERRIDE_MESSAGE, this);
|
||||
Services.prefs.addObserver(PREF_OVERRIDES_ENABLED, buildOverrides, false);
|
||||
|
||||
try {
|
||||
Services.obs.addObserver(HTTP_on_modify_request, "http-on-modify-request", false);
|
||||
gRegisteredWithNecko = true;
|
||||
} catch (x) {
|
||||
// The http-on-modify-request notification is disallowed in content processes.
|
||||
}
|
||||
}
|
||||
|
||||
function unregisterWithNecko() {
|
||||
if (gRegisteredWithNecko == false) {
|
||||
return;
|
||||
}
|
||||
Services.obs.removeObserver(HTTP_on_modify_request, "http-on-modify-request");
|
||||
gRegisteredWithNecko = false;
|
||||
}
|
||||
|
||||
function getUserAgentFromOverride(override)
|
||||
{
|
||||
let userAgent = gBuiltUAs.get(override);
|
||||
@@ -150,6 +169,7 @@ function getUserAgentFromOverride(override)
|
||||
}
|
||||
|
||||
function buildOverrides() {
|
||||
unregisterWithNecko();
|
||||
gOverrides.clear();
|
||||
gOverrideForHostCache.clear();
|
||||
|
||||
@@ -162,11 +182,16 @@ function buildOverrides() {
|
||||
for (let domain of domains) {
|
||||
let override = gPrefBranch.getCharPref(domain);
|
||||
let userAgent = getUserAgentFromOverride(override);
|
||||
|
||||
if (userAgent != DEFAULT_UA) {
|
||||
gOverrides.set(domain, userAgent);
|
||||
}
|
||||
}
|
||||
|
||||
// Only register with Necko if there are actually overrides.
|
||||
// See https://bug896114.bmoattachments.org/attachment.cgi?id=778980
|
||||
if (gOverrides.size > 0) {
|
||||
registerWithNecko();
|
||||
}
|
||||
}
|
||||
|
||||
function HTTP_on_modify_request(aSubject, aTopic, aData) {
|
||||
|
||||
@@ -1137,4 +1137,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
||||
|
||||
static const int32_t kUnknownId = -1;
|
||||
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1579537847247000);
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1582550105358000);
|
||||
|
||||
+5166
-2002
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user