Merge inbound to mozilla-central. a=merge

This commit is contained in:
Mihai Alexandru Michis 2019-06-05 12:51:25 +03:00
commit 153172de0c
33 changed files with 377 additions and 1145 deletions

View File

@ -1375,7 +1375,7 @@ pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
// Is the sidebar positioned ahead of the content browser
pref("sidebar.position_start", true);
pref("security.identitypopup.recordEventElemetry", true);
pref("security.identitypopup.recordEventTelemetry", true);
// Block insecure active content on https pages
pref("security.mixed_content.block_active_content", true);

View File

@ -1451,7 +1451,10 @@ BrowserGlue.prototype = {
},
_recordContentBlockingTelemetry() {
let recordIdentityPopupEvents = Services.prefs.getBoolPref("security.identitypopup.recordEventElemetry");
let recordIdentityPopupEvents = Services.prefs.prefHasUserValue("security.identitypopup.recordEventElemetry") ?
Services.prefs.getBoolPref("security.identitypopup.recordEventElemetry") :
Services.prefs.getBoolPref("security.identitypopup.recordEventTelemetry");
Services.telemetry.setEventRecordingEnabled("security.ui.identitypopup", recordIdentityPopupEvents);
let tpEnabled = Services.prefs.getBoolPref("privacy.trackingprotection.enabled");

View File

@ -93,7 +93,10 @@ TextEditor.prototype = {
update: async function() {
try {
const value = await getLongString(this.node.getNodeValue());
this.textNode.setState({ value });
if (this.textNode.state.value !== value) {
this.textNode.setState({ value });
}
} catch (e) {
console.error(e);
}

View File

@ -298,7 +298,6 @@
# include "nsXULPopupManager.h"
# include "nsIDocShellTreeOwner.h"
#endif
#include "mozilla/dom/BoxObject.h"
#include "mozilla/DocLoadingTimelineMarker.h"
@ -1247,7 +1246,6 @@ Document::Document(const char* aContentType)
mAutoFocusFired(false),
mScrolledToRefAlready(false),
mChangeScrollPosWhenScrollingToRef(false),
mHasWarnedAboutBoxObjects(false),
mDelayFrameLoaderInitialization(false),
mSynchronousDOMContentLoaded(false),
mMaybeServiceWorkerControlled(false),
@ -1315,7 +1313,6 @@ Document::Document(const char* aContentType)
mFlashClassification(FlashClassification::Unknown),
mScrollAnchorAdjustmentLength(0),
mScrollAnchorAdjustmentCount(0),
mBoxObjectTable(nullptr),
mCurrentOrientationAngle(0),
mCurrentOrientationType(OrientationType::Portrait_primary),
mServoRestyleRootDirtyBits(0),
@ -1471,19 +1468,6 @@ void Document::GetFailedCertSecurityInfo(
aInfo.mSubjectAltNames = subjectAltNames;
}
void Document::ClearAllBoxObjects() {
if (mBoxObjectTable) {
for (auto iter = mBoxObjectTable->Iter(); !iter.Done(); iter.Next()) {
nsPIBoxObject* boxObject = iter.UserData();
if (boxObject) {
boxObject->Clear();
}
}
delete mBoxObjectTable;
mBoxObjectTable = nullptr;
}
}
bool Document::IsAboutPage() const {
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
nsCOMPtr<nsIURI> uri;
@ -1679,8 +1663,6 @@ Document::~Document() {
delete mHeaderData;
ClearAllBoxObjects();
mPendingTitleChangeEvent.Revoke();
mPlugins.Clear();
@ -1817,15 +1799,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
DocumentOrShadowRoot::Traverse(tmp, cb);
// The boxobject for an element will only exist as long as it's in the
// document, so we'll traverse the table here instead of from the element.
if (tmp->mBoxObjectTable) {
for (auto iter = tmp->mBoxObjectTable->Iter(); !iter.Done(); iter.Next()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mBoxObjectTable entry");
cb.NoteXPCOMChild(iter.UserData());
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChannel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLayoutHistoryState)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnloadBlocker)
@ -1956,8 +1929,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntersectionObservers)
tmp->ClearAllBoxObjects();
if (tmp->mListenerManager) {
tmp->mListenerManager->Disconnect();
tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER);
@ -7776,55 +7747,6 @@ void Document::DoNotifyPossibleTitleChange() {
CanBubble::eYes, Cancelable::eYes);
}
already_AddRefed<BoxObject> Document::GetBoxObjectFor(Element* aElement,
ErrorResult& aRv) {
if (!aElement) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
Document* doc = aElement->OwnerDoc();
if (doc != this) {
aRv.Throw(NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
return nullptr;
}
if (!mHasWarnedAboutBoxObjects && !aElement->IsXULElement()) {
mHasWarnedAboutBoxObjects = true;
nsContentUtils::ReportToConsole(
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("BoxObjects"), this,
nsContentUtils::eDOM_PROPERTIES, "UseOfGetBoxObjectForWarning");
}
if (!mBoxObjectTable) {
mBoxObjectTable =
new nsRefPtrHashtable<nsPtrHashKey<nsIContent>, BoxObject>(6);
}
RefPtr<BoxObject> boxObject;
auto entry = mBoxObjectTable->LookupForAdd(aElement);
if (entry) {
boxObject = entry.Data();
return boxObject.forget();
}
boxObject = new BoxObject();
boxObject->Init(aElement);
entry.OrInsert([&boxObject]() { return boxObject; });
return boxObject.forget();
}
void Document::ClearBoxObjectFor(nsIContent* aContent) {
if (mBoxObjectTable) {
if (auto entry = mBoxObjectTable->Lookup(aContent)) {
nsPIBoxObject* boxObject = entry.Data();
boxObject->Clear();
entry.Remove();
}
}
}
already_AddRefed<MediaQueryList> Document::MatchMedia(
const nsAString& aMediaQueryList, CallerType aCallerType) {
RefPtr<MediaQueryList> result =

View File

@ -159,7 +159,6 @@ namespace dom {
class Animation;
class AnonymousContent;
class Attr;
class BoxObject;
class XULBroadcastManager;
class XULPersist;
class ClientInfo;
@ -1623,8 +1622,6 @@ class Document : public nsINode,
void DoUnblockOnload();
void ClearAllBoxObjects();
void MaybeEndOutermostXBLUpdate();
void RetrieveRelevantHeaders(nsIChannel* aChannel);
@ -2532,20 +2529,6 @@ class Document : public nsINode,
// Refreshes the hrefs of all the links in the document.
void RefreshLinkHrefs();
/**
* Resets and removes a box object from the document's box object cache
*
* @param aElement canonical nsIContent pointer of the box object's element
*/
void ClearBoxObjectFor(nsIContent* aContent);
/**
* Get the box object for an element. This is not exposed through a
* scriptable interface except for XUL documents.
*/
already_AddRefed<BoxObject> GetBoxObjectFor(Element* aElement,
ErrorResult& aRv);
/**
* Support for window.matchMedia()
*/
@ -4493,8 +4476,6 @@ class Document : public nsINode,
bool mScrolledToRefAlready : 1;
bool mChangeScrollPosWhenScrollingToRef : 1;
bool mHasWarnedAboutBoxObjects : 1;
bool mDelayFrameLoaderInitialization : 1;
bool mSynchronousDOMContentLoaded : 1;
@ -4889,8 +4870,6 @@ class Document : public nsINode,
RefPtr<dom::ScriptLoader> mScriptLoader;
nsRefPtrHashtable<nsPtrHashKey<nsIContent>, BoxObject>* mBoxObjectTable;
// Tracker for animations that are waiting to start.
// nullptr until GetOrCreatePendingAnimationTracker is called.
RefPtr<PendingAnimationTracker> mPendingAnimationTracker;

View File

@ -94,7 +94,6 @@
#include "nsBindingManager.h"
#include "nsXBLBinding.h"
#include "nsPIDOMWindow.h"
#include "nsPIBoxObject.h"
#include "mozilla/dom/DOMRect.h"
#include "nsSVGUtils.h"
#include "nsLayoutUtils.h"
@ -1942,8 +1941,6 @@ void Element::UnbindFromTree(bool aNullParent) {
}
}
document->ClearBoxObjectFor(this);
// Disconnected must be enqueued whenever a connected custom element becomes
// disconnected.
CustomElementData* data = GetCustomElementData();

View File

@ -75,7 +75,6 @@
#include "nsFrameLoader.h"
#include "nsXBLBinding.h"
#include "nsPIDOMWindow.h"
#include "nsPIBoxObject.h"
#include "nsSVGUtils.h"
#include "nsLayoutUtils.h"
#include "nsGkAtoms.h"
@ -1173,7 +1172,6 @@ void FragmentOrElement::DestroyContent() {
document->BindingManager()->RemovedFromDocument(this, document,
nsBindingManager::eRunDtor);
document->ClearBoxObjectFor(this);
#ifdef DEBUG
uint32_t oldChildCount = GetChildCount();

View File

@ -84,7 +84,6 @@
#include "nsNameSpaceManager.h"
#include "nsNodeInfoManager.h"
#include "nsNodeUtils.h"
#include "nsPIBoxObject.h"
#include "nsPIDOMWindow.h"
#include "nsPresContext.h"
#include "nsString.h"

View File

@ -320,10 +320,8 @@ void nsNodeUtils::LastRelease(nsINode* aNode) {
aNode->UnsetFlags(NODE_HAS_LISTENERMANAGER);
}
if (Element* element = Element::FromNode(aNode)) {
element->OwnerDoc()->ClearBoxObjectFor(element);
NS_ASSERTION(!element->GetXBLBinding(), "Node has binding on destruction");
}
NS_ASSERTION(!Element::FromNode(aNode) ||
!Element::FromNode(aNode)->GetXBLBinding(), "Node has binding on destruction");
aNode->ReleaseWrapper(aNode);
@ -437,7 +435,6 @@ already_AddRefed<nsINode> nsNodeUtils::CloneAndAdopt(
Document* oldDoc = aNode->OwnerDoc();
bool wasRegistered = false;
if (elem) {
oldDoc->ClearBoxObjectFor(elem);
wasRegistered = oldDoc->UnregisterActivityObserver(elem);
}

View File

@ -561,14 +561,6 @@ Document.prototype.writeln = function(text) {};
Document.prototype.ononline;
Document.prototype.onoffline;
// XUL
/**
* @see http://developer.mozilla.org/en/DOM/document.getBoxObjectFor
* @return {BoxObject}
* @nosideeffects
*/
Document.prototype.getBoxObjectFor = function(element) {};
// From:
// http://lxr.mozilla.org/mozilla1.8/source/dom/public/idl/range/nsIDOMNSRange.idl
@ -1076,27 +1068,6 @@ Plugin.prototype.length;
/** @type {string} */
Plugin.prototype.name;
/** @constructor */
function BoxObject() {}
/** @type {Element} */
BoxObject.prototype.element;
/** @type {number} */
BoxObject.prototype.screenX;
/** @type {number} */
BoxObject.prototype.screenY;
/** @type {number} */
BoxObject.prototype.x;
/** @type {number} */
BoxObject.prototype.y;
/** @type {number} */
BoxObject.prototype.width;
/**
* @type {number}

View File

@ -114,7 +114,7 @@ interface XULTreeElement : XULElement
* returns -1 for invalid mouse coordinates.
*
* The coordinate system is the client coordinate system for the
* document this boxObject lives in, and the units are CSS pixels.
* document this tree lives in, and the units are CSS pixels.
*/
long getRowAt(long x, long y);
@ -126,7 +126,7 @@ interface XULTreeElement : XULElement
* "cell", "twisty", "image", and "text".
*
* The coordinate system is the client coordinate system for the
* document this boxObject lives in, and the units are CSS pixels.
* document this tree lives in, and the units are CSS pixels.
*/
[Throws]
TreeCellInfo getCellAt(long x, long y);

View File

@ -2193,13 +2193,13 @@ class LSRequestBase : public DatastoreOperationBase,
public PBackgroundLSRequestParent {
protected:
enum class State {
// Just created on the PBackground thread. Next step is Opening.
// Just created on the PBackground thread. Next step is StartingRequest.
Initial,
// Waiting to open/opening on the main thread. Next step is either
// Nesting if a subclass needs to process more nested states or
// Waiting to start/starting request on the PBackground thread. Next step is
// either Nesting if a subclass needs to process more nested states or
// SendingReadyMessage if a subclass doesn't need any nested processing.
Opening,
StartingRequest,
// Doing nested processing.
Nesting,
@ -2221,18 +2221,22 @@ class LSRequestBase : public DatastoreOperationBase,
};
nsCOMPtr<nsIEventTarget> mMainEventTarget;
const LSRequestParams mParams;
Maybe<ContentParentId> mContentParentId;
State mState;
bool mWaitingForFinish;
public:
explicit LSRequestBase(nsIEventTarget* aMainEventTarget);
LSRequestBase(nsIEventTarget* aMainEventTarget,
const LSRequestParams& aParams,
const Maybe<ContentParentId>& aContentParentId);
void Dispatch();
protected:
~LSRequestBase() override;
virtual nsresult Open() = 0;
virtual nsresult Start() = 0;
virtual nsresult NestedRun();
@ -2245,6 +2249,10 @@ class LSRequestBase : public DatastoreOperationBase,
virtual void LogNestedState() {}
private:
bool VerifyRequestParams();
nsresult StartRequest();
void SendReadyMessage();
nsresult SendReadyMessageInternal();
@ -2336,8 +2344,6 @@ class PrepareDatastoreOp
LoadDataOp* mLoadDataOp;
nsDataHashtable<nsStringHashKey, LSValue> mValues;
nsTArray<LSItemInfo> mOrderedItems;
const LSRequestCommonParams mParams;
Maybe<ContentParentId> mContentParentId;
nsCString mSuffix;
nsCString mGroup;
nsCString mMainThreadOrigin;
@ -2391,7 +2397,7 @@ class PrepareDatastoreOp
private:
~PrepareDatastoreOp() override;
nsresult Open() override;
nsresult Start() override;
nsresult CheckExistingOperations();
@ -2489,15 +2495,15 @@ class PrepareDatastoreOp::CompressibleFunction final
};
class PrepareObserverOp : public LSRequestBase {
const LSRequestPrepareObserverParams mParams;
nsCString mOrigin;
public:
PrepareObserverOp(nsIEventTarget* aMainEventTarget,
const LSRequestParams& aParams);
const LSRequestParams& aParams,
const Maybe<ContentParentId>& aContentParentId);
private:
nsresult Open() override;
nsresult Start() override;
void GetResponse(LSRequestResponse& aResponse) override;
};
@ -2506,11 +2512,12 @@ class LSSimpleRequestBase : public DatastoreOperationBase,
public PBackgroundLSSimpleRequestParent {
protected:
enum class State {
// Just created on the PBackground thread. Next step is Opening.
// Just created on the PBackground thread. Next step is StartingRequest.
Initial,
// Waiting to open/opening on the main thread. Next step is SendingResults.
Opening,
// Waiting to start/starting request on the PBackground thread. Next step is
// SendingResults.
StartingRequest,
// Waiting to send/sending results on the PBackground thread. Next step is
// Completed.
@ -2520,21 +2527,28 @@ class LSSimpleRequestBase : public DatastoreOperationBase,
Completed
};
const LSSimpleRequestParams mParams;
Maybe<ContentParentId> mContentParentId;
State mState;
public:
LSSimpleRequestBase();
LSSimpleRequestBase(const LSSimpleRequestParams& aParams,
const Maybe<ContentParentId>& aContentParentId);
void Dispatch();
protected:
~LSSimpleRequestBase() override;
virtual nsresult Open() = 0;
virtual nsresult Start() = 0;
virtual void GetResponse(LSSimpleRequestResponse& aResponse) = 0;
private:
bool VerifyRequestParams();
nsresult StartRequest();
void SendResults();
// Common nsIRunnable implementation that subclasses may not override.
@ -2546,14 +2560,14 @@ class LSSimpleRequestBase : public DatastoreOperationBase,
};
class PreloadedOp : public LSSimpleRequestBase {
const LSSimpleRequestPreloadedParams mParams;
nsCString mOrigin;
public:
explicit PreloadedOp(const LSSimpleRequestParams& aParams);
PreloadedOp(const LSSimpleRequestParams& aParams,
const Maybe<ContentParentId>& aContentParentId);
private:
nsresult Open() override;
nsresult Start() override;
void GetResponse(LSSimpleRequestResponse& aResponse) override;
};
@ -3134,6 +3148,63 @@ void RequestAllowToCloseIf(P aPredicate) {
databases.Clear();
}
bool VerifyPrincipalInfo(const PrincipalInfo& aPrincipalInfo,
const PrincipalInfo& aStoragePrincipalInfo) {
AssertIsOnBackgroundThread();
if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
return false;
}
if (NS_WARN_IF(!StoragePrincipalHelper::
VerifyValidStoragePrincipalInfoForPrincipalInfo(
aStoragePrincipalInfo, aPrincipalInfo))) {
return false;
}
return true;
}
bool VerifyClientId(const Maybe<ContentParentId>& aContentParentId,
const PrincipalInfo& aPrincipalInfo,
const Maybe<nsID>& aClientId) {
AssertIsOnBackgroundThread();
if (gClientValidation) {
if (NS_WARN_IF(aClientId.isNothing())) {
return false;
}
RefPtr<ClientManagerService> svc = ClientManagerService::GetInstance();
if (svc && NS_WARN_IF(!svc->HasWindow(aContentParentId, aPrincipalInfo,
aClientId.ref()))) {
return false;
}
}
return true;
}
bool VerifyOriginKey(const nsACString& aOriginKey,
const PrincipalInfo& aPrincipalInfo) {
AssertIsOnBackgroundThread();
nsCString originAttrSuffix;
nsCString originKey;
nsresult rv = GenerateOriginKey2(aPrincipalInfo, originAttrSuffix, originKey);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (NS_WARN_IF(originKey != aOriginKey)) {
LS_WARNING("originKey (%s) doesn't match passed one (%s)!", originKey.get(),
nsCString(aOriginKey).get());
return false;
}
return true;
}
} // namespace
/*******************************************************************************
@ -3330,119 +3401,6 @@ bool DeallocPBackgroundLSObserverParent(PBackgroundLSObserverParent* aActor) {
return true;
}
bool VerifyPrincipalInfo(const Maybe<ContentParentId>& aContentParentId,
const PrincipalInfo& aPrincipalInfo,
const PrincipalInfo& aStoragePrincipalInfo,
const Maybe<nsID>& aClientId) {
AssertIsOnBackgroundThread();
if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
ASSERT_UNLESS_FUZZING();
return false;
}
if (aClientId.isSome() && gClientValidation) {
RefPtr<ClientManagerService> svc = ClientManagerService::GetInstance();
if (svc &&
!svc->HasWindow(aContentParentId, aPrincipalInfo, aClientId.ref())) {
ASSERT_UNLESS_FUZZING();
return false;
}
}
return StoragePrincipalHelper::
VerifyValidStoragePrincipalInfoForPrincipalInfo(aStoragePrincipalInfo,
aPrincipalInfo);
}
bool VerifyOriginKey(const nsACString& aOriginKey,
const PrincipalInfo& aPrincipalInfo) {
AssertIsOnBackgroundThread();
nsCString originAttrSuffix;
nsCString originKey;
nsresult rv = GenerateOriginKey2(aPrincipalInfo, originAttrSuffix, originKey);
if (NS_WARN_IF(NS_FAILED(rv))) {
ASSERT_UNLESS_FUZZING();
return false;
}
if (NS_WARN_IF(originKey != aOriginKey)) {
LS_WARNING("originKey (%s) doesn't match passed one (%s)!", originKey.get(),
nsCString(aOriginKey).get());
ASSERT_UNLESS_FUZZING();
return false;
}
return true;
}
bool VerifyRequestParams(const Maybe<ContentParentId>& aContentParentId,
const LSRequestParams& aParams) {
AssertIsOnBackgroundThread();
MOZ_ASSERT(aParams.type() != LSRequestParams::T__None);
switch (aParams.type()) {
case LSRequestParams::TLSRequestPreloadDatastoreParams: {
const LSRequestCommonParams& params =
aParams.get_LSRequestPreloadDatastoreParams().commonParams();
if (NS_WARN_IF(
!VerifyPrincipalInfo(aContentParentId, params.principalInfo(),
params.storagePrincipalInfo(), Nothing()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
if (NS_WARN_IF(
!VerifyOriginKey(params.originKey(), params.principalInfo()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
break;
}
case LSRequestParams::TLSRequestPrepareDatastoreParams: {
const LSRequestPrepareDatastoreParams& params =
aParams.get_LSRequestPrepareDatastoreParams();
const LSRequestCommonParams& commonParams = params.commonParams();
if (NS_WARN_IF(!VerifyPrincipalInfo(
aContentParentId, commonParams.principalInfo(),
commonParams.storagePrincipalInfo(), params.clientId()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
if (NS_WARN_IF(!VerifyOriginKey(commonParams.originKey(),
commonParams.principalInfo()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
break;
}
case LSRequestParams::TLSRequestPrepareObserverParams: {
const LSRequestPrepareObserverParams& params =
aParams.get_LSRequestPrepareObserverParams();
if (NS_WARN_IF(!VerifyPrincipalInfo(
aContentParentId, params.principalInfo(),
params.storagePrincipalInfo(), params.clientId()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
break;
}
default:
MOZ_CRASH("Should never get here!");
}
return true;
}
PBackgroundLSRequestParent* AllocPBackgroundLSRequestParent(
PBackgroundParent* aBackgroundActor, const LSRequestParams& aParams) {
AssertIsOnBackgroundThread();
@ -3452,13 +3410,6 @@ PBackgroundLSRequestParent* AllocPBackgroundLSRequestParent(
return nullptr;
}
#ifdef DEBUG
// Always verify parameters in DEBUG builds!
bool trustParams = false;
#else
bool trustParams = !BackgroundParent::IsOtherProcessActor(aBackgroundActor);
#endif
Maybe<ContentParentId> contentParentId;
uint64_t childID = BackgroundParent::GetChildID(aBackgroundActor);
@ -3466,12 +3417,6 @@ PBackgroundLSRequestParent* AllocPBackgroundLSRequestParent(
contentParentId = Some(ContentParentId(childID));
}
if (!trustParams &&
NS_WARN_IF(!VerifyRequestParams(contentParentId, aParams))) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
// If we're in the same process as the actor, we need to get the target event
// queue from the current RequestHelper.
nsCOMPtr<nsIEventTarget> mainEventTarget;
@ -3499,7 +3444,7 @@ PBackgroundLSRequestParent* AllocPBackgroundLSRequestParent(
case LSRequestParams::TLSRequestPrepareObserverParams: {
RefPtr<PrepareObserverOp> prepareObserverOp =
new PrepareObserverOp(mainEventTarget, aParams);
new PrepareObserverOp(mainEventTarget, aParams, contentParentId);
actor = std::move(prepareObserverOp);
@ -3540,32 +3485,6 @@ bool DeallocPBackgroundLSRequestParent(PBackgroundLSRequestParent* aActor) {
return true;
}
bool VerifyRequestParams(const Maybe<ContentParentId>& aContentParentId,
const LSSimpleRequestParams& aParams) {
AssertIsOnBackgroundThread();
MOZ_ASSERT(aParams.type() != LSSimpleRequestParams::T__None);
switch (aParams.type()) {
case LSSimpleRequestParams::TLSSimpleRequestPreloadedParams: {
const LSSimpleRequestPreloadedParams& params =
aParams.get_LSSimpleRequestPreloadedParams();
if (NS_WARN_IF(
!VerifyPrincipalInfo(aContentParentId, params.principalInfo(),
params.storagePrincipalInfo(), Nothing()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
break;
}
default:
MOZ_CRASH("Should never get here!");
}
return true;
}
PBackgroundLSSimpleRequestParent* AllocPBackgroundLSSimpleRequestParent(
PBackgroundParent* aBackgroundActor, const LSSimpleRequestParams& aParams) {
AssertIsOnBackgroundThread();
@ -3575,32 +3494,19 @@ PBackgroundLSSimpleRequestParent* AllocPBackgroundLSSimpleRequestParent(
return nullptr;
}
#ifdef DEBUG
// Always verify parameters in DEBUG builds!
bool trustParams = false;
#else
bool trustParams = !BackgroundParent::IsOtherProcessActor(aBackgroundActor);
#endif
Maybe<ContentParentId> contentParentId;
if (!trustParams) {
Maybe<ContentParentId> contentParentId;
uint64_t childID = BackgroundParent::GetChildID(aBackgroundActor);
if (childID) {
contentParentId = Some(ContentParentId(childID));
}
if (NS_WARN_IF(!VerifyRequestParams(contentParentId, aParams))) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
uint64_t childID = BackgroundParent::GetChildID(aBackgroundActor);
if (childID) {
contentParentId = Some(ContentParentId(childID));
}
RefPtr<LSSimpleRequestBase> actor;
switch (aParams.type()) {
case LSSimpleRequestParams::TLSSimpleRequestPreloadedParams: {
RefPtr<PreloadedOp> preloadedOp = new PreloadedOp(aParams);
RefPtr<PreloadedOp> preloadedOp =
new PreloadedOp(aParams, contentParentId);
actor = std::move(preloadedOp);
@ -6346,8 +6252,12 @@ mozilla::ipc::IPCResult Observer::RecvDeleteMe() {
* LSRequestBase
******************************************************************************/
LSRequestBase::LSRequestBase(nsIEventTarget* aMainEventTarget)
LSRequestBase::LSRequestBase(nsIEventTarget* aMainEventTarget,
const LSRequestParams& aParams,
const Maybe<ContentParentId>& aContentParentId)
: mMainEventTarget(aMainEventTarget),
mParams(aParams),
mContentParentId(aContentParentId),
mState(State::Initial),
mWaitingForFinish(false) {}
@ -6359,7 +6269,7 @@ LSRequestBase::~LSRequestBase() {
void LSRequestBase::Dispatch() {
AssertIsOnOwningThread();
mState = State::Opening;
mState = State::StartingRequest;
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(this));
}
@ -6382,8 +6292,8 @@ void LSRequestBase::LogState() {
state.AssignLiteral("Initial");
break;
case State::Opening:
state.AssignLiteral("Opening");
case State::StartingRequest:
state.AssignLiteral("StartingRequest");
break;
case State::Nesting:
@ -6421,6 +6331,107 @@ void LSRequestBase::LogState() {
}
}
bool LSRequestBase::VerifyRequestParams() {
AssertIsOnBackgroundThread();
MOZ_ASSERT(mParams.type() != LSRequestParams::T__None);
switch (mParams.type()) {
case LSRequestParams::TLSRequestPreloadDatastoreParams: {
const LSRequestCommonParams& params =
mParams.get_LSRequestPreloadDatastoreParams().commonParams();
if (NS_WARN_IF(!VerifyPrincipalInfo(params.principalInfo(),
params.storagePrincipalInfo()))) {
return false;
}
if (NS_WARN_IF(
!VerifyOriginKey(params.originKey(), params.principalInfo()))) {
return false;
}
break;
}
case LSRequestParams::TLSRequestPrepareDatastoreParams: {
const LSRequestPrepareDatastoreParams& params =
mParams.get_LSRequestPrepareDatastoreParams();
const LSRequestCommonParams& commonParams = params.commonParams();
if (NS_WARN_IF(
!VerifyPrincipalInfo(commonParams.principalInfo(),
commonParams.storagePrincipalInfo()))) {
return false;
}
if (NS_WARN_IF(!VerifyClientId(mContentParentId,
commonParams.principalInfo(),
params.clientId()))) {
return false;
}
if (NS_WARN_IF(!VerifyOriginKey(commonParams.originKey(),
commonParams.principalInfo()))) {
return false;
}
break;
}
case LSRequestParams::TLSRequestPrepareObserverParams: {
const LSRequestPrepareObserverParams& params =
mParams.get_LSRequestPrepareObserverParams();
if (NS_WARN_IF(!VerifyPrincipalInfo(params.principalInfo(),
params.storagePrincipalInfo()))) {
return false;
}
if (NS_WARN_IF(!VerifyClientId(mContentParentId, params.principalInfo(),
params.clientId()))) {
return false;
}
break;
}
default:
MOZ_CRASH("Should never get here!");
}
return true;
}
nsresult LSRequestBase::StartRequest() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::StartingRequest);
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
!MayProceed()) {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG
// Always verify parameters in DEBUG builds!
bool trustParams = false;
#else
bool trustParams = !BackgroundParent::IsOtherProcessActor(Manager());
#endif
if (!trustParams && NS_WARN_IF(!VerifyRequestParams())) {
return NS_ERROR_FAILURE;
}
nsresult rv = Start();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
void LSRequestBase::SendReadyMessage() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::SendingReadyMessage);
@ -6511,8 +6522,8 @@ LSRequestBase::Run() {
nsresult rv;
switch (mState) {
case State::Opening:
rv = Open();
case State::StartingRequest:
rv = StartRequest();
break;
case State::Nesting:
@ -6605,14 +6616,9 @@ mozilla::ipc::IPCResult LSRequestBase::RecvFinish() {
PrepareDatastoreOp::PrepareDatastoreOp(
nsIEventTarget* aMainEventTarget, const LSRequestParams& aParams,
const Maybe<ContentParentId>& aContentParentId)
: LSRequestBase(aMainEventTarget),
: LSRequestBase(aMainEventTarget, aParams, aContentParentId),
mMainEventTarget(aMainEventTarget),
mLoadDataOp(nullptr),
mParams(
aParams.type() == LSRequestParams::TLSRequestPreloadDatastoreParams
? aParams.get_LSRequestPreloadDatastoreParams().commonParams()
: aParams.get_LSRequestPrepareDatastoreParams().commonParams()),
mContentParentId(aContentParentId),
mPrivateBrowsingId(0),
mUsage(0),
mSizeOfKeys(0),
@ -6641,17 +6647,20 @@ PrepareDatastoreOp::~PrepareDatastoreOp() {
MOZ_ASSERT(!mLoadDataOp);
}
nsresult PrepareDatastoreOp::Open() {
nsresult PrepareDatastoreOp::Start() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::Opening);
MOZ_ASSERT(mState == State::StartingRequest);
MOZ_ASSERT(mNestedState == NestedState::BeforeNesting);
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
MOZ_ASSERT(MayProceed());
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
!MayProceedOnNonOwningThread()) {
return NS_ERROR_FAILURE;
}
const LSRequestCommonParams& commonParams =
mForPreload
? mParams.get_LSRequestPreloadDatastoreParams().commonParams()
: mParams.get_LSRequestPrepareDatastoreParams().commonParams();
const PrincipalInfo& storagePrincipalInfo = mParams.storagePrincipalInfo();
const PrincipalInfo& storagePrincipalInfo =
commonParams.storagePrincipalInfo();
if (storagePrincipalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
QuotaManager::GetInfoForChrome(&mSuffix, &mGroup, &mOrigin);
@ -6682,7 +6691,13 @@ nsresult PrepareDatastoreOp::CheckExistingOperations() {
return NS_ERROR_FAILURE;
}
const PrincipalInfo& storagePrincipalInfo = mParams.storagePrincipalInfo();
const LSRequestCommonParams& commonParams =
mForPreload
? mParams.get_LSRequestPreloadDatastoreParams().commonParams()
: mParams.get_LSRequestPrepareDatastoreParams().commonParams();
const PrincipalInfo& storagePrincipalInfo =
commonParams.storagePrincipalInfo();
nsCString originAttrSuffix;
uint32_t privateBrowsingId;
@ -6702,7 +6717,7 @@ nsresult PrepareDatastoreOp::CheckExistingOperations() {
}
mArchivedOriginScope = ArchivedOriginScope::CreateFromOrigin(
originAttrSuffix, mParams.originKey());
originAttrSuffix, commonParams.originKey());
MOZ_ASSERT(mArchivedOriginScope);
// Normally it's safe to access member variables without a mutex because even
@ -7467,6 +7482,8 @@ void PrepareDatastoreOp::GetResponse(LSRequestResponse& aResponse) {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::SendingResults);
MOZ_ASSERT(NS_SUCCEEDED(ResultCode()));
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
MOZ_ASSERT(MayProceed());
// A datastore is not created when we are just trying to preload data and
// there's no database file.
@ -7942,24 +7959,24 @@ PrepareDatastoreOp::CompressibleFunction::OnFunctionCall(
* PrepareObserverOp
******************************************************************************/
PrepareObserverOp::PrepareObserverOp(nsIEventTarget* aMainEventTarget,
const LSRequestParams& aParams)
: LSRequestBase(aMainEventTarget),
mParams(aParams.get_LSRequestPrepareObserverParams()) {
PrepareObserverOp::PrepareObserverOp(
nsIEventTarget* aMainEventTarget, const LSRequestParams& aParams,
const Maybe<ContentParentId>& aContentParentId)
: LSRequestBase(aMainEventTarget, aParams, aContentParentId) {
MOZ_ASSERT(aParams.type() ==
LSRequestParams::TLSRequestPrepareObserverParams);
}
nsresult PrepareObserverOp::Open() {
nsresult PrepareObserverOp::Start() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::Opening);
MOZ_ASSERT(mState == State::StartingRequest);
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
MOZ_ASSERT(MayProceed());
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
!MayProceedOnNonOwningThread()) {
return NS_ERROR_FAILURE;
}
const LSRequestPrepareObserverParams params =
mParams.get_LSRequestPrepareObserverParams();
const PrincipalInfo& storagePrincipalInfo = mParams.storagePrincipalInfo();
const PrincipalInfo& storagePrincipalInfo = params.storagePrincipalInfo();
if (storagePrincipalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
QuotaManager::GetInfoForChrome(nullptr, nullptr, &mOrigin);
@ -7981,6 +7998,8 @@ void PrepareObserverOp::GetResponse(LSRequestResponse& aResponse) {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::SendingResults);
MOZ_ASSERT(NS_SUCCEEDED(ResultCode()));
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
MOZ_ASSERT(MayProceed());
uint64_t observerId = ++gLastObserverId;
@ -8002,7 +8021,12 @@ void PrepareObserverOp::GetResponse(LSRequestResponse& aResponse) {
+
******************************************************************************/
LSSimpleRequestBase::LSSimpleRequestBase() : mState(State::Initial) {}
LSSimpleRequestBase::LSSimpleRequestBase(
const LSSimpleRequestParams& aParams,
const Maybe<ContentParentId>& aContentParentId)
: mParams(aParams),
mContentParentId(aContentParentId),
mState(State::Initial) {}
LSSimpleRequestBase::~LSSimpleRequestBase() {
MOZ_ASSERT_IF(MayProceedOnNonOwningThread(),
@ -8012,11 +8036,64 @@ LSSimpleRequestBase::~LSSimpleRequestBase() {
void LSSimpleRequestBase::Dispatch() {
AssertIsOnOwningThread();
mState = State::Opening;
mState = State::StartingRequest;
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(this));
}
bool LSSimpleRequestBase::VerifyRequestParams() {
AssertIsOnBackgroundThread();
MOZ_ASSERT(mParams.type() != LSSimpleRequestParams::T__None);
switch (mParams.type()) {
case LSSimpleRequestParams::TLSSimpleRequestPreloadedParams: {
const LSSimpleRequestPreloadedParams& params =
mParams.get_LSSimpleRequestPreloadedParams();
if (NS_WARN_IF(!VerifyPrincipalInfo(params.principalInfo(),
params.storagePrincipalInfo()))) {
return false;
}
break;
}
default:
MOZ_CRASH("Should never get here!");
}
return true;
}
nsresult LSSimpleRequestBase::StartRequest() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::StartingRequest);
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
!MayProceed()) {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG
// Always verify parameters in DEBUG builds!
bool trustParams = false;
#else
bool trustParams = !BackgroundParent::IsOtherProcessActor(Manager());
#endif
if (!trustParams && NS_WARN_IF(!VerifyRequestParams())) {
return NS_ERROR_FAILURE;
}
nsresult rv = Start();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
void LSSimpleRequestBase::SendResults() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::SendingResults);
@ -8046,8 +8123,8 @@ LSSimpleRequestBase::Run() {
nsresult rv;
switch (mState) {
case State::Opening:
rv = Open();
case State::StartingRequest:
rv = StartRequest();
break;
case State::SendingResults:
@ -8086,22 +8163,23 @@ void LSSimpleRequestBase::ActorDestroy(ActorDestroyReason aWhy) {
* PreloadedOp
******************************************************************************/
PreloadedOp::PreloadedOp(const LSSimpleRequestParams& aParams)
: mParams(aParams.get_LSSimpleRequestPreloadedParams()) {
PreloadedOp::PreloadedOp(const LSSimpleRequestParams& aParams,
const Maybe<ContentParentId>& aContentParentId)
: LSSimpleRequestBase(aParams, aContentParentId) {
MOZ_ASSERT(aParams.type() ==
LSSimpleRequestParams::TLSSimpleRequestPreloadedParams);
}
nsresult PreloadedOp::Open() {
nsresult PreloadedOp::Start() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::Opening);
MOZ_ASSERT(mState == State::StartingRequest);
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
MOZ_ASSERT(MayProceed());
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
!MayProceedOnNonOwningThread()) {
return NS_ERROR_FAILURE;
}
const LSSimpleRequestPreloadedParams& params =
mParams.get_LSSimpleRequestPreloadedParams();
const PrincipalInfo& storagePrincipalInfo = mParams.storagePrincipalInfo();
const PrincipalInfo& storagePrincipalInfo = params.storagePrincipalInfo();
if (storagePrincipalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
QuotaManager::GetInfoForChrome(nullptr, nullptr, &mOrigin);
@ -8123,6 +8201,8 @@ void PreloadedOp::GetResponse(LSSimpleRequestResponse& aResponse) {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::SendingResults);
MOZ_ASSERT(NS_SUCCEEDED(ResultCode()));
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
MOZ_ASSERT(MayProceed());
bool preloaded;
RefPtr<Datastore> datastore;

View File

@ -405,6 +405,8 @@ nsresult LSObject::CreateForPrincipal(nsPIDOMWindowInner* aWindow,
}
clientId = Some(clientInfo.ref().Id());
} else if (Preferences::GetBool("dom.storage.client_validation")) {
return NS_ERROR_FAILURE;
}
RefPtr<LSObject> object =

View File

@ -53,11 +53,18 @@ function returnToEventLoop() {
function enableTesting() {
Services.prefs.setBoolPref("dom.storage.testing", true);
// xpcshell globals don't have associated clients in the Clients API sense, so
// we need to disable client validation so that the unit tests are allowed to
// use LocalStorage.
Services.prefs.setBoolPref("dom.storage.client_validation", false);
Services.prefs.setBoolPref("dom.quotaManager.testing", true);
}
function resetTesting() {
Services.prefs.clearUserPref("dom.quotaManager.testing");
Services.prefs.clearUserPref("dom.storage.client_validation");
Services.prefs.clearUserPref("dom.storage.testing");
}

View File

@ -0,0 +1,29 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Because this is an xpcshell global, it does not have an associated client id.
* We turn on client validation for LocalStorage and ensure that we don't have
* access to LocalStorage.
*/
async function testSteps() {
const principal = getPrincipal("http://example.com");
info("Setting prefs");
Services.prefs.setBoolPref("dom.storage.next_gen", true);
Services.prefs.setBoolPref("dom.storage.client_validation", true);
info("Getting storage");
try {
getLocalStorage(principal);
ok(false, "Should have thrown");
} catch (ex) {
ok(true, "Did throw");
is(ex.name, "NS_ERROR_FAILURE", "Threw right Exception");
is(ex.result, Cr.NS_ERROR_FAILURE, "Threw with right result");
}
}

View File

@ -14,6 +14,7 @@ support-files =
stringLength_profile.zip
[test_archive.js]
[test_clientValidation.js]
[test_corruptedDatabase.js]
[test_databaseShadowing1.js]
run-sequentially = test_databaseShadowing2.js depends on a file produced by this test

View File

@ -32,6 +32,13 @@ async function testSteps() {
return Services.domStorageManager.createStorage(null, principal, principal, "");
}
info("Setting pref");
// xpcshell globals don't have associated clients in the Clients API sense, so
// we need to disable client validation so that this unit test is allowed to
// use LocalStorage.
Services.prefs.setBoolPref("dom.storage.client_validation", false);
info("Clearing");
let request = clear();

View File

@ -1,33 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Func="IsChromeOrXBL"]
interface BoxObject {
readonly attribute Element? element;
readonly attribute long x;
readonly attribute long y;
[Throws]
readonly attribute long screenX;
[Throws]
readonly attribute long screenY;
readonly attribute long width;
readonly attribute long height;
nsISupports? getPropertyAsSupports(DOMString propertyName);
void setPropertyAsSupports(DOMString propertyName, nsISupports value);
[Throws]
DOMString? getProperty(DOMString propertyName);
void setProperty(DOMString propertyName, DOMString propertyValue);
void removeProperty(DOMString propertyName);
// for stepping through content in the expanded dom with box-ordinal-group order
readonly attribute Element? parentBox;
readonly attribute Element? firstChild;
readonly attribute Element? lastChild;
readonly attribute Element? nextSibling;
readonly attribute Element? previousSibling;
};

View File

@ -192,8 +192,6 @@ partial interface Document {
* etc.
*/
[Func="IsChromeOrXBLOrUAWidget"] readonly attribute boolean mozSyntheticDocument;
[Throws, Func="IsChromeOrXBL"]
BoxObject? getBoxObjectFor(Element? element);
/**
* Returns the script element whose script is currently being processed.
*

View File

@ -76,8 +76,6 @@ interface XULElement : Element {
[Throws, ChromeOnly]
readonly attribute XULControllers controllers;
[Throws]
readonly attribute BoxObject? boxObject;
[SetterThrows]
attribute long tabIndex;

View File

@ -400,7 +400,6 @@ WEBIDL_FILES = [
'BeforeUnloadEvent.webidl',
'BiquadFilterNode.webidl',
'Blob.webidl',
'BoxObject.webidl',
'BroadcastChannel.webidl',
'BrowserElement.webidl',
'BrowserElementDictionaries.webidl',

View File

@ -28,7 +28,6 @@
#include "XULDocument.h"
#include "nsError.h"
#include "nsIBoxObject.h"
#include "nsView.h"
#include "nsViewManager.h"
#include "nsIContentViewer.h"
@ -43,8 +42,6 @@
#include "nsDocElementCreatedNotificationRunner.h"
#include "nsNetUtil.h"
#include "nsParserCIID.h"
#include "nsPIBoxObject.h"
#include "mozilla/dom/BoxObject.h"
#include "nsString.h"
#include "nsPIDOMWindow.h"
#include "nsPIWindowRoot.h"

View File

@ -41,8 +41,6 @@
#include "nsStyleConsts.h"
#include "nsString.h"
#include "nsXULControllers.h"
#include "nsIBoxObject.h"
#include "nsPIBoxObject.h"
#include "XULDocument.h"
#include "nsXULPopupListener.h"
#include "nsContentUtils.h"
@ -81,7 +79,6 @@
#include "XULTreeElement.h"
#include "mozilla/dom/XULElementBinding.h"
#include "mozilla/dom/BoxObject.h"
#include "mozilla/dom/XULBroadcastManager.h"
#include "mozilla/dom/MouseEventBinding.h"
#include "mozilla/dom/MutationEventBinding.h"
@ -1136,11 +1133,6 @@ nsIControllers* nsXULElement::GetControllers(ErrorResult& rv) {
return Controllers();
}
already_AddRefed<BoxObject> nsXULElement::GetBoxObject(ErrorResult& rv) {
// XXX sXBL/XBL2 issue! Owner or current document?
return OwnerDoc()->GetBoxObjectFor(this, rv);
}
void nsXULElement::Click(CallerType aCallerType) {
ClickWithInputSource(MouseEvent_Binding::MOZ_SOURCE_UNKNOWN,
aCallerType == CallerType::System);

View File

@ -46,7 +46,6 @@ namespace css {
class StyleRule;
} // namespace css
namespace dom {
class BoxObject;
class HTMLIFrameElement;
class PrototypeDocumentContentSink;
enum class CallerType : uint32_t;
@ -510,10 +509,6 @@ class nsXULElement : public nsStyledElement {
SetXULBoolAttr(nsGkAtoms::allowevents, aAllowEvents);
}
nsIControllers* GetControllers(mozilla::ErrorResult& rv);
// Note: this can only fail if the do_CreateInstance for the boxobject
// contact fails for some reason.
already_AddRefed<mozilla::dom::BoxObject> GetBoxObject(
mozilla::ErrorResult& rv);
void Click(mozilla::dom::CallerType aCallerType);
MOZ_CAN_RUN_SCRIPT_BOUNDARY void DoCommand();
// Style() inherited from nsStyledElement

View File

@ -48,7 +48,6 @@
#include "nsStyleConsts.h"
#ifdef MOZ_XUL
# include "nsXULElement.h"
# include "mozilla/dom/BoxObject.h"
#endif // MOZ_XUL
#include "nsContainerFrame.h"
#include "nsNameSpaceManager.h"
@ -207,7 +206,6 @@ static FrameCtorDebugFlags gFlags[] = {
# include "nsMenuFrame.h"
# include "nsPopupSetFrame.h"
# include "nsTreeColFrame.h"
# include "nsIBoxObject.h"
# include "nsXULLabelFrame.h"
//------------------------------------------------------------------

View File

@ -14,6 +14,6 @@ fuzzy(0-1,0-4) == unit-vh-vw-overflow-auto.html unit-vh-vw-overflow-auto-ref.htm
fails-if(!Android) == unit-vh-vw-overflow-scroll.html unit-vh-vw-overflow-scroll-ref.html
fails-if(!Android) == unit-vh-vw-overflow-scroll-x.html unit-vh-vw-overflow-scroll-x-ref.html
fails-if(!Android) == unit-vh-vw-overflow-scroll-y.html unit-vh-vw-overflow-scroll-y-ref.html
skip-if(Android) fuzzy-if(gtkWidget,0-1,0-2) fails != unit-vh-vw-overflow-auto.html unit-vh-vw-overflow-scroll.html
skip-if(Android) fuzzy-if(gtkWidget,0-1,0-2) == unit-vh-vw-overflow-auto.html unit-vh-vw-overflow-scroll.html
== ch-width-1.html ch-width-1-ref.html

View File

@ -1,526 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/BoxObject.h"
#include "nsCOMPtr.h"
#include "mozilla/PresShell.h"
#include "mozilla/dom/Document.h"
#include "nsPresContext.h"
#include "nsIContent.h"
#include "nsContainerFrame.h"
#include "nsIDocShell.h"
#include "nsReadableUtils.h"
#include "nsView.h"
#include "nsLayoutUtils.h"
#include "nsISupportsPrimitives.h"
#include "nsSupportsPrimitives.h"
#include "mozilla/dom/Element.h"
#include "nsComponentManagerUtils.h"
#include "mozilla/dom/BoxObjectBinding.h"
// Implementation /////////////////////////////////////////////////////////////
namespace mozilla {
namespace dom {
// Static member variable initialization
// Implement our nsISupports methods
NS_IMPL_CYCLE_COLLECTION_CLASS(BoxObject)
NS_IMPL_CYCLE_COLLECTING_ADDREF(BoxObject)
NS_IMPL_CYCLE_COLLECTING_RELEASE(BoxObject)
// QueryInterface implementation for BoxObject
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BoxObject)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIBoxObject)
NS_INTERFACE_MAP_ENTRY(nsPIBoxObject)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BoxObject)
// XXX jmorton: why aren't we unlinking mPropertyTable?
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BoxObject)
if (tmp->mPropertyTable) {
for (auto iter = tmp->mPropertyTable->Iter(); !iter.Done(); iter.Next()) {
cb.NoteXPCOMChild(iter.UserData());
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(BoxObject)
// Constructors/Destructors
BoxObject::BoxObject() : mContent(nullptr) {}
BoxObject::~BoxObject() {}
NS_IMETHODIMP
BoxObject::GetElement(Element** aResult) {
RefPtr<Element> element = mContent;
element.forget(aResult);
return NS_OK;
}
// nsPIBoxObject //////////////////////////////////////////////////////////////
nsresult BoxObject::Init(Element* aElement) {
mContent = aElement;
return NS_OK;
}
void BoxObject::Clear() {
mPropertyTable = nullptr;
mContent = nullptr;
}
void BoxObject::ClearCachedValues() {}
nsIFrame* BoxObject::GetFrame() const {
if (!GetPresShell() || !mContent) {
return nullptr;
}
return mContent->GetPrimaryFrame();
}
nsIFrame* BoxObject::GetFrameWithFlushPendingNotifications() {
RefPtr<PresShell> presShell = GetPresShellWithFlushPendingNotifications();
if (!presShell) {
return nullptr;
}
// If we didn't flush layout when getting the presshell, we should at least
// flush to make sure our frame model is up to date.
// XXXbz should flush on document, no? Except people call this from
// frame code, maybe?
presShell->FlushPendingNotifications(FlushType::Frames);
// The flush might have killed mContent.
if (!mContent) {
return nullptr;
}
return mContent->GetPrimaryFrame();
}
PresShell* BoxObject::GetPresShell() const {
if (!mContent) {
return nullptr;
}
Document* doc = mContent->GetComposedDoc();
if (!doc) {
return nullptr;
}
return doc->GetPresShell();
}
PresShell* BoxObject::GetPresShellWithFlushPendingNotifications() {
if (!mContent) {
return nullptr;
}
RefPtr<Document> doc = mContent->GetComposedDoc();
if (!doc) {
return nullptr;
}
doc->FlushPendingNotifications(FlushType::Layout);
return doc->GetPresShell();
}
nsresult BoxObject::GetOffsetRect(nsIntRect& aRect) {
aRect.SetRect(0, 0, 0, 0);
if (!mContent) return NS_ERROR_NOT_INITIALIZED;
// Get the Frame for our content
nsIFrame* frame = GetFrameWithFlushPendingNotifications();
if (frame) {
// Get its origin
nsPoint origin = frame->GetPositionIgnoringScrolling();
// Find the frame parent whose content is the document element.
Element* docElement = mContent->GetComposedDoc()->GetRootElement();
nsIFrame* parent = frame->GetParent();
for (;;) {
// If we've hit the document element, break here
if (parent->GetContent() == docElement) {
break;
}
nsIFrame* next = parent->GetParent();
if (!next) {
NS_WARNING("We should have hit the document element...");
origin += parent->GetPosition();
break;
}
// Add the parent's origin to our own to get to the
// right coordinate system
origin += next->GetPositionOfChildIgnoringScrolling(parent);
parent = next;
}
// For the origin, add in the border for the frame
const nsStyleBorder* border = frame->StyleBorder();
origin.x += border->GetComputedBorderWidth(eSideLeft);
origin.y += border->GetComputedBorderWidth(eSideTop);
// And subtract out the border for the parent
const nsStyleBorder* parentBorder = parent->StyleBorder();
origin.x -= parentBorder->GetComputedBorderWidth(eSideLeft);
origin.y -= parentBorder->GetComputedBorderWidth(eSideTop);
aRect.x = nsPresContext::AppUnitsToIntCSSPixels(origin.x);
aRect.y = nsPresContext::AppUnitsToIntCSSPixels(origin.y);
// Get the union of all rectangles in this and continuation frames.
// It doesn't really matter what we use as aRelativeTo here, since
// we only care about the size. Using 'parent' might make things
// a bit faster by speeding up the internal GetOffsetTo operations.
nsRect rcFrame = nsLayoutUtils::GetAllInFlowRectsUnion(frame, parent);
aRect.width = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.width);
aRect.height = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height);
}
return NS_OK;
}
nsresult BoxObject::GetScreenPosition(nsIntPoint& aPoint) {
aPoint.x = aPoint.y = 0;
if (!mContent) return NS_ERROR_NOT_INITIALIZED;
nsIFrame* frame = GetFrameWithFlushPendingNotifications();
if (frame) {
CSSIntRect rect = frame->GetScreenRect();
aPoint.x = rect.x;
aPoint.y = rect.y;
}
return NS_OK;
}
NS_IMETHODIMP
BoxObject::GetX(int32_t* aResult) {
nsIntRect rect;
GetOffsetRect(rect);
*aResult = rect.x;
return NS_OK;
}
NS_IMETHODIMP
BoxObject::GetY(int32_t* aResult) {
nsIntRect rect;
GetOffsetRect(rect);
*aResult = rect.y;
return NS_OK;
}
NS_IMETHODIMP
BoxObject::GetWidth(int32_t* aResult) {
nsIntRect rect;
GetOffsetRect(rect);
*aResult = rect.width;
return NS_OK;
}
NS_IMETHODIMP
BoxObject::GetHeight(int32_t* aResult) {
nsIntRect rect;
GetOffsetRect(rect);
*aResult = rect.height;
return NS_OK;
}
NS_IMETHODIMP
BoxObject::GetScreenX(int32_t* _retval) {
nsIntPoint position;
nsresult rv = GetScreenPosition(position);
if (NS_FAILED(rv)) return rv;
*_retval = position.x;
return NS_OK;
}
NS_IMETHODIMP
BoxObject::GetScreenY(int32_t* _retval) {
nsIntPoint position;
nsresult rv = GetScreenPosition(position);
if (NS_FAILED(rv)) return rv;
*_retval = position.y;
return NS_OK;
}
NS_IMETHODIMP
BoxObject::GetPropertyAsSupports(const char16_t* aPropertyName,
nsISupports** aResult) {
NS_ENSURE_ARG(aPropertyName && *aPropertyName);
if (!mPropertyTable) {
*aResult = nullptr;
return NS_OK;
}
nsDependentString propertyName(aPropertyName);
mPropertyTable->Get(propertyName, aResult); // Addref here.
return NS_OK;
}
NS_IMETHODIMP
BoxObject::SetPropertyAsSupports(const char16_t* aPropertyName,
nsISupports* aValue) {
NS_ENSURE_ARG(aPropertyName && *aPropertyName);
if (!mPropertyTable) {
mPropertyTable = new nsInterfaceHashtable<nsStringHashKey, nsISupports>(4);
}
nsDependentString propertyName(aPropertyName);
mPropertyTable->Put(propertyName, aValue);
return NS_OK;
}
NS_IMETHODIMP
BoxObject::GetProperty(const char16_t* aPropertyName, char16_t** aResult) {
nsCOMPtr<nsISupports> data;
nsresult rv = GetPropertyAsSupports(aPropertyName, getter_AddRefs(data));
NS_ENSURE_SUCCESS(rv, rv);
if (!data) {
*aResult = nullptr;
return NS_OK;
}
nsCOMPtr<nsISupportsString> supportsStr = do_QueryInterface(data);
if (!supportsStr) {
return NS_ERROR_FAILURE;
}
return supportsStr->ToString(aResult);
}
NS_IMETHODIMP
BoxObject::SetProperty(const char16_t* aPropertyName,
const char16_t* aPropertyValue) {
NS_ENSURE_ARG(aPropertyName && *aPropertyName);
nsDependentString propertyName(aPropertyName);
nsDependentString propertyValue;
if (aPropertyValue) {
propertyValue.Rebind(aPropertyValue);
} else {
propertyValue.SetIsVoid(true);
}
nsCOMPtr<nsISupportsString> supportsStr(
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(supportsStr, NS_ERROR_OUT_OF_MEMORY);
supportsStr->SetData(propertyValue);
return SetPropertyAsSupports(aPropertyName, supportsStr);
}
NS_IMETHODIMP
BoxObject::RemoveProperty(const char16_t* aPropertyName) {
NS_ENSURE_ARG(aPropertyName && *aPropertyName);
if (!mPropertyTable) return NS_OK;
nsDependentString propertyName(aPropertyName);
mPropertyTable->Remove(propertyName);
return NS_OK;
}
Element* BoxObject::GetParentBox() {
nsIFrame* frame = GetFrame();
if (!frame) {
return nullptr;
}
nsIFrame* parent = frame->GetParent();
if (!parent) {
return nullptr;
}
nsIContent* parentContent = parent->GetContent();
// In theory parent could be viewport, and then parentContent is null.
if (parentContent && parentContent->IsElement()) {
return parentContent->AsElement();
}
return nullptr;
}
Element* BoxObject::GetFirstChild() {
nsIFrame* frame = GetFrame();
if (!frame) {
return nullptr;
}
nsIFrame* firstFrame = frame->PrincipalChildList().FirstChild();
if (!firstFrame) {
return nullptr;
}
nsIContent* content = firstFrame->GetContent();
if (content->IsElement()) {
return content->AsElement();
}
return nullptr;
}
Element* BoxObject::GetLastChild() {
nsIFrame* frame = GetFrame();
if (!frame) {
return nullptr;
}
return GetPreviousSibling(frame, nullptr);
}
Element* BoxObject::GetNextSibling() {
nsIFrame* frame = GetFrame();
if (!frame) {
return nullptr;
}
nsIFrame* nextFrame = frame->GetNextSibling();
if (!nextFrame) {
return nullptr;
}
nsIContent* content = nextFrame->GetContent();
if (content->IsElement()) {
return content->AsElement();
}
return nullptr;
}
Element* BoxObject::GetPreviousSibling() {
nsIFrame* frame = GetFrame();
if (!frame) {
return nullptr;
}
nsIFrame* parentFrame = frame->GetParent();
if (!parentFrame) {
return nullptr;
}
return GetPreviousSibling(parentFrame, frame);
}
Element* BoxObject::GetPreviousSibling(nsIFrame* aParentFrame,
nsIFrame* aFrame) {
nsIFrame* nextFrame = aParentFrame->PrincipalChildList().FirstChild();
nsIFrame* prevFrame = nullptr;
while (nextFrame) {
if (nextFrame == aFrame) break;
prevFrame = nextFrame;
nextFrame = nextFrame->GetNextSibling();
}
if (!prevFrame) {
return nullptr;
}
nsIContent* content = prevFrame->GetContent();
if (!content->IsElement()) {
return nullptr;
}
return content->AsElement();
}
Element* BoxObject::GetParentObject() const { return mContent; }
JSObject* BoxObject::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return BoxObject_Binding::Wrap(aCx, this, aGivenProto);
}
Element* BoxObject::GetElement() const { return mContent; }
int32_t BoxObject::X() {
int32_t ret = 0;
GetX(&ret);
return ret;
}
int32_t BoxObject::Y() {
int32_t ret = 0;
GetY(&ret);
return ret;
}
int32_t BoxObject::GetScreenX(ErrorResult& aRv) {
int32_t ret = 0;
aRv = GetScreenX(&ret);
return ret;
}
int32_t BoxObject::GetScreenY(ErrorResult& aRv) {
int32_t ret = 0;
aRv = GetScreenY(&ret);
return ret;
}
int32_t BoxObject::Width() {
int32_t ret = 0;
GetWidth(&ret);
return ret;
}
int32_t BoxObject::Height() {
int32_t ret = 0;
GetHeight(&ret);
return ret;
}
already_AddRefed<nsISupports> BoxObject::GetPropertyAsSupports(
const nsAString& propertyName) {
nsCOMPtr<nsISupports> ret;
GetPropertyAsSupports(PromiseFlatString(propertyName).get(),
getter_AddRefs(ret));
return ret.forget();
}
void BoxObject::SetPropertyAsSupports(const nsAString& propertyName,
nsISupports* value) {
SetPropertyAsSupports(PromiseFlatString(propertyName).get(), value);
}
void BoxObject::GetProperty(const nsAString& propertyName, nsString& aRetVal,
ErrorResult& aRv) {
nsCOMPtr<nsISupports> data(GetPropertyAsSupports(propertyName));
if (!data) {
return;
}
nsCOMPtr<nsISupportsString> supportsStr(do_QueryInterface(data));
if (!supportsStr) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
supportsStr->GetData(aRetVal);
}
void BoxObject::SetProperty(const nsAString& propertyName,
const nsAString& propertyValue) {
SetProperty(PromiseFlatString(propertyName).get(),
PromiseFlatString(propertyValue).get());
}
void BoxObject::RemoveProperty(const nsAString& propertyName) {
RemoveProperty(PromiseFlatString(propertyName).get());
}
} // namespace dom
} // namespace mozilla

View File

@ -1,98 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_BoxObject_h__
#define mozilla_dom_BoxObject_h__
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "nsCOMPtr.h"
#include "nsIBoxObject.h"
#include "nsPIBoxObject.h"
#include "nsPoint.h"
#include "nsAutoPtr.h"
#include "nsHashKeys.h"
#include "nsInterfaceHashtable.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "nsRect.h"
class nsIFrame;
namespace mozilla {
class PresShell;
namespace dom {
class Element;
class BoxObject : public nsPIBoxObject, public nsWrapperCache {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BoxObject)
NS_DECL_NSIBOXOBJECT
public:
BoxObject();
// nsPIBoxObject
virtual nsresult Init(Element* aElement) override;
virtual void Clear() override;
virtual void ClearCachedValues() override;
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult GetOffsetRect(nsIntRect& aRect);
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult GetScreenPosition(nsIntPoint& aPoint);
// Given a parent frame and a child frame, find the frame whose
// next sibling is the given child frame and return its element
static Element* GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame);
// WebIDL (wraps old impls)
Element* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
Element* GetElement() const;
int32_t X();
int32_t Y();
int32_t GetScreenX(ErrorResult& aRv);
int32_t GetScreenY(ErrorResult& aRv);
int32_t Width();
int32_t Height();
already_AddRefed<nsISupports> GetPropertyAsSupports(
const nsAString& propertyName);
void SetPropertyAsSupports(const nsAString& propertyName, nsISupports* value);
void GetProperty(const nsAString& propertyName, nsString& aRetVal,
ErrorResult& aRv);
void SetProperty(const nsAString& propertyName,
const nsAString& propertyValue);
void RemoveProperty(const nsAString& propertyName);
Element* GetParentBox();
Element* GetFirstChild();
Element* GetLastChild();
Element* GetNextSibling();
Element* GetPreviousSibling();
protected:
virtual ~BoxObject();
nsIFrame* GetFrame() const;
MOZ_CAN_RUN_SCRIPT nsIFrame* GetFrameWithFlushPendingNotifications();
PresShell* GetPresShell() const;
MOZ_CAN_RUN_SCRIPT PresShell* GetPresShellWithFlushPendingNotifications();
nsAutoPtr<nsInterfaceHashtable<nsStringHashKey, nsISupports>> mPropertyTable;
Element* mContent; // [WEAK]
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -15,26 +15,14 @@ if CONFIG['ENABLE_TESTS']:
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
XPIDL_SOURCES += [
'nsIBoxObject.idl',
]
XPIDL_MODULE = 'layout_xul'
EXPORTS += [
'nsBox.h',
'nsIScrollbarMediator.h',
'nsPIBoxObject.h',
'nsXULPopupManager.h',
'nsXULTooltipListener.h',
]
EXPORTS.mozilla.dom += [
'BoxObject.h',
]
UNIFIED_SOURCES += [
'BoxObject.cpp',
'nsBox.cpp',
'nsBoxFrame.cpp',
'nsBoxLayout.cpp',

View File

@ -1,27 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
webidl Element;
[scriptable, uuid(ce572460-b0f2-4650-a9e7-c53a99d3b6ad)]
interface nsIBoxObject : nsISupports
{
readonly attribute Element element;
readonly attribute long x;
readonly attribute long y;
readonly attribute long screenX;
readonly attribute long screenY;
readonly attribute long width;
readonly attribute long height;
nsISupports getPropertyAsSupports(in wstring propertyName);
void setPropertyAsSupports(in wstring propertyName, in nsISupports value);
wstring getProperty(in wstring propertyName);
void setProperty(in wstring propertyName, in wstring propertyValue);
void removeProperty(in wstring propertyName);
};

View File

@ -1,42 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsPIBoxObject_h___
#define nsPIBoxObject_h___
#include "nsIBoxObject.h"
// {2b8bb262-1b0f-4572-ba87-5d4ae4954445}
#define NS_PIBOXOBJECT_IID \
{ \
0x2b8bb262, 0x1b0f, 0x4572, { \
0xba, 0x87, 0x5d, 0x4a, 0xe4, 0x95, 0x44, 0x45 \
} \
}
namespace mozilla {
namespace dom {
class Element;
} // namespace dom
} // namespace mozilla
class nsPIBoxObject : public nsIBoxObject {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIBOXOBJECT_IID)
virtual nsresult Init(mozilla::dom::Element* aElement) = 0;
// Drop the weak ref to the content node as needed
virtual void Clear() = 0;
// The values cached by the implementation of this interface should be
// cleared when this method is called.
virtual void ClearCachedValues() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIBoxObject, NS_PIBOXOBJECT_IID)
#endif

View File

@ -6,7 +6,6 @@
#include "nsNameSpaceManager.h"
#include "nsGkAtoms.h"
#include "nsIBoxObject.h"
#include "nsTreeColumns.h"
#include "nsTreeUtils.h"
#include "mozilla/ComputedStyle.h"

View File

@ -8,7 +8,6 @@
#include "mozilla/dom/Element.h"
#include "nsCOMPtr.h"
#include "nsTreeSelection.h"
#include "nsIBoxObject.h"
#include "XULTreeElement.h"
#include "nsITreeView.h"
#include "nsString.h"