mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-25 03:05:34 +00:00
Merge autoland to mozilla-central. r=merge a=merge
This commit is contained in:
commit
49ce665b6e
@ -40,20 +40,17 @@ AC_DEFUN([MOZ_ANDROID_CPU_ARCH],
|
||||
[
|
||||
|
||||
if test "$OS_TARGET" = "Android"; then
|
||||
case "${CPU_ARCH}-${MOZ_ARCH}" in
|
||||
arm-armv7*)
|
||||
case "${CPU_ARCH}" in
|
||||
arm)
|
||||
ANDROID_CPU_ARCH=armeabi-v7a
|
||||
;;
|
||||
arm-*)
|
||||
ANDROID_CPU_ARCH=armeabi
|
||||
;;
|
||||
x86-*)
|
||||
x86)
|
||||
ANDROID_CPU_ARCH=x86
|
||||
;;
|
||||
mips32-*) # When target_cpu is mipsel, CPU_ARCH is mips32
|
||||
mips32) # When target_cpu is mipsel, CPU_ARCH is mips32
|
||||
ANDROID_CPU_ARCH=mips
|
||||
;;
|
||||
aarch64-*)
|
||||
aarch64)
|
||||
ANDROID_CPU_ARCH=arm64-v8a
|
||||
;;
|
||||
esac
|
||||
|
@ -42,8 +42,7 @@ if test -z "$MOZ_ARCH"; then
|
||||
fi
|
||||
|
||||
if test "$MOZ_ARCH" = "armv6" -a "$OS_TARGET" = "Android"; then
|
||||
MOZ_FPU=vfp
|
||||
MOZ_FLOAT_ABI=softfp
|
||||
AC_MSG_ERROR([Android/armv6 is not supported])
|
||||
fi
|
||||
|
||||
MOZ_ARG_WITH_STRING(thumb,
|
||||
|
@ -363,6 +363,54 @@ Element::SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError)
|
||||
SetAttr(nsGkAtoms::tabindex, value, aError);
|
||||
}
|
||||
|
||||
void
|
||||
Element::SetXBLBinding(nsXBLBinding* aBinding,
|
||||
nsBindingManager* aOldBindingManager)
|
||||
{
|
||||
nsBindingManager* bindingManager;
|
||||
if (aOldBindingManager) {
|
||||
MOZ_ASSERT(!aBinding, "aOldBindingManager should only be provided "
|
||||
"when removing a binding.");
|
||||
bindingManager = aOldBindingManager;
|
||||
} else {
|
||||
bindingManager = OwnerDoc()->BindingManager();
|
||||
}
|
||||
|
||||
// After this point, aBinding will be the most-derived binding for aContent.
|
||||
// If we already have a binding for aContent, make sure to
|
||||
// remove it from the attached stack. Otherwise we might end up firing its
|
||||
// constructor twice (if aBinding inherits from it) or firing its constructor
|
||||
// after aContent has been deleted (if aBinding is null and the content node
|
||||
// dies before we process mAttachedStack).
|
||||
RefPtr<nsXBLBinding> oldBinding = GetXBLBinding();
|
||||
if (oldBinding) {
|
||||
bindingManager->RemoveFromAttachedQueue(oldBinding);
|
||||
}
|
||||
|
||||
if (aBinding) {
|
||||
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
slots->mXBLBinding = aBinding;
|
||||
bindingManager->AddBoundContent(this);
|
||||
} else {
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
slots->mXBLBinding = nullptr;
|
||||
}
|
||||
bindingManager->RemoveBoundContent(this);
|
||||
if (oldBinding) {
|
||||
oldBinding->SetBoundElement(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Element::SetShadowRoot(ShadowRoot* aShadowRoot)
|
||||
{
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
slots->mShadowRoot = aShadowRoot;
|
||||
}
|
||||
|
||||
void
|
||||
Element::Blur(mozilla::ErrorResult& aError)
|
||||
{
|
||||
|
@ -266,6 +266,30 @@ public:
|
||||
*/
|
||||
void SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError);
|
||||
|
||||
/**
|
||||
* Sets or unsets an XBL binding for this element. Setting a
|
||||
* binding on an element that already has a binding will remove the
|
||||
* old binding.
|
||||
*
|
||||
* @param aBinding The binding to bind to this content. If nullptr is
|
||||
* provided as the argument, then existing binding will be
|
||||
* removed.
|
||||
*
|
||||
* @param aOldBindingManager The old binding manager that contains
|
||||
* this content if this content was adopted
|
||||
* to another document.
|
||||
*/
|
||||
void SetXBLBinding(nsXBLBinding* aBinding,
|
||||
nsBindingManager* aOldBindingManager = nullptr);
|
||||
|
||||
/**
|
||||
* Sets the ShadowRoot binding for this element. The contents of the
|
||||
* binding is rendered in place of this node's children.
|
||||
*
|
||||
* @param aShadowRoot The ShadowRoot to be bound to this element.
|
||||
*/
|
||||
void SetShadowRoot(ShadowRoot* aShadowRoot);
|
||||
|
||||
/**
|
||||
* Make focus on this element.
|
||||
*/
|
||||
@ -552,13 +576,11 @@ public:
|
||||
*/
|
||||
inline CustomElementData* GetCustomElementData() const
|
||||
{
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mCustomElementData;
|
||||
}
|
||||
return nullptr;
|
||||
const nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
return slots ? slots->mCustomElementData.get() : nullptr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the custom element data, ownership of the
|
||||
* callback data is taken by this element.
|
||||
@ -1295,9 +1317,11 @@ public:
|
||||
// [deprecated] Shadow DOM v0
|
||||
already_AddRefed<ShadowRoot> CreateShadowRoot(ErrorResult& aError);
|
||||
|
||||
ShadowRoot *FastGetShadowRoot() const
|
||||
// FIXME(emilio): Should just shadow GetShadowRoot(), that way we get the fast
|
||||
// version by default everywhere we already have an Element...
|
||||
ShadowRoot* FastGetShadowRoot() const
|
||||
{
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
const nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
return slots ? slots->mShadowRoot.get() : nullptr;
|
||||
}
|
||||
|
||||
@ -1481,9 +1505,9 @@ public:
|
||||
*
|
||||
* @return existing attribute map or nullptr.
|
||||
*/
|
||||
nsDOMAttributeMap *GetAttributeMap()
|
||||
nsDOMAttributeMap* GetAttributeMap()
|
||||
{
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
nsDOMSlots* slots = GetExistingDOMSlots();
|
||||
|
||||
return slots ? slots->mAttributeMap.get() : nullptr;
|
||||
}
|
||||
|
@ -710,7 +710,7 @@ nsParentNodeChildContentList::ValidateCache()
|
||||
nsIHTMLCollection*
|
||||
FragmentOrElement::Children()
|
||||
{
|
||||
FragmentOrElement::nsDOMSlots *slots = DOMSlots();
|
||||
nsDOMSlots* slots = DOMSlots();
|
||||
|
||||
if (!slots->mChildrenList) {
|
||||
slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard,
|
||||
@ -788,8 +788,36 @@ static_assert(sizeof(nsINode::nsSlots) <= MaxDOMSlotSizeAllowed,
|
||||
static_assert(sizeof(FragmentOrElement::nsDOMSlots) <= MaxDOMSlotSizeAllowed,
|
||||
"DOM slots cannot be grown without consideration");
|
||||
|
||||
void
|
||||
nsIContent::nsExtendedContentSlots::Unlink()
|
||||
{
|
||||
mXBLInsertionPoint = nullptr;
|
||||
mContainingShadow = nullptr;
|
||||
mAssignedSlot = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsIContent::nsExtendedContentSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
|
||||
{
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mContainingShadow");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mAssignedSlot");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mAssignedSlot.get()));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mXBLInsertionPoint");
|
||||
aCb.NoteXPCOMChild(mXBLInsertionPoint.get());
|
||||
}
|
||||
|
||||
nsIContent::nsExtendedContentSlots::nsExtendedContentSlots()
|
||||
: mBindingParent(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
nsIContent::nsExtendedContentSlots::~nsExtendedContentSlots() = default;
|
||||
|
||||
FragmentOrElement::nsDOMSlots::nsDOMSlots()
|
||||
: nsINode::nsSlots(),
|
||||
: nsIContent::nsContentSlots(),
|
||||
mDataset(nullptr)
|
||||
{
|
||||
}
|
||||
@ -802,60 +830,27 @@ FragmentOrElement::nsDOMSlots::~nsDOMSlots()
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
|
||||
FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
|
||||
{
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mStyle");
|
||||
cb.NoteXPCOMChild(mStyle.get());
|
||||
nsIContent::nsContentSlots::Traverse(aCb);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAttributeMap");
|
||||
cb.NoteXPCOMChild(mAttributeMap.get());
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mSlots->mStyle");
|
||||
aCb.NoteXPCOMChild(mStyle.get());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mSlots->mAttributeMap");
|
||||
aCb.NoteXPCOMChild(mAttributeMap.get());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList");
|
||||
cb.NoteXPCOMChild(mClassList.get());
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mSlots->mChildrenList");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
|
||||
|
||||
if (!mExtendedSlots) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mSMILOverrideStyle");
|
||||
cb.NoteXPCOMChild(mExtendedSlots->mSMILOverrideStyle.get());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mControllers");
|
||||
cb.NoteXPCOMChild(mExtendedSlots->mControllers);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mLabelsList");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*,mExtendedSlots-> mLabelsList));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mShadowRoot");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mShadowRoot));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mContainingShadow");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mContainingShadow));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mAssignedSlot");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mAssignedSlot.get()));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mXBLBinding");
|
||||
cb.NoteNativeChild(mExtendedSlots->mXBLBinding,
|
||||
NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mXBLInsertionPoint");
|
||||
cb.NoteXPCOMChild(mExtendedSlots->mXBLInsertionPoint.get());
|
||||
|
||||
if (mExtendedSlots->mCustomElementData) {
|
||||
mExtendedSlots->mCustomElementData->Traverse(cb);
|
||||
}
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mFrameLoaderOrOpener");
|
||||
cb.NoteXPCOMChild(mExtendedSlots->mFrameLoaderOrOpener);
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mSlots->mClassList");
|
||||
aCb.NoteXPCOMChild(mClassList.get());
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::nsDOMSlots::Unlink()
|
||||
{
|
||||
nsIContent::nsContentSlots::Unlink();
|
||||
mStyle = nullptr;
|
||||
if (mAttributeMap) {
|
||||
mAttributeMap->DropReference();
|
||||
@ -863,29 +858,6 @@ FragmentOrElement::nsDOMSlots::Unlink()
|
||||
}
|
||||
mChildrenList = nullptr;
|
||||
mClassList = nullptr;
|
||||
|
||||
if (!mExtendedSlots) {
|
||||
return;
|
||||
}
|
||||
|
||||
mExtendedSlots->mSMILOverrideStyle = nullptr;
|
||||
mExtendedSlots->mControllers = nullptr;
|
||||
mExtendedSlots->mLabelsList = nullptr;
|
||||
mExtendedSlots->mShadowRoot = nullptr;
|
||||
mExtendedSlots->mContainingShadow = nullptr;
|
||||
mExtendedSlots->mAssignedSlot = nullptr;
|
||||
MOZ_ASSERT(!(mExtendedSlots->mXBLBinding));
|
||||
mExtendedSlots->mXBLInsertionPoint = nullptr;
|
||||
if (mExtendedSlots->mCustomElementData) {
|
||||
mExtendedSlots->mCustomElementData->Unlink();
|
||||
mExtendedSlots->mCustomElementData = nullptr;
|
||||
}
|
||||
nsCOMPtr<nsIFrameLoader> frameLoader =
|
||||
do_QueryInterface(mExtendedSlots->mFrameLoaderOrOpener);
|
||||
if (frameLoader) {
|
||||
static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
|
||||
}
|
||||
mExtendedSlots->mFrameLoaderOrOpener = nullptr;
|
||||
}
|
||||
|
||||
size_t
|
||||
@ -915,10 +887,7 @@ FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) c
|
||||
return n;
|
||||
}
|
||||
|
||||
FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots()
|
||||
: mBindingParent(nullptr)
|
||||
{
|
||||
}
|
||||
FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots() = default;
|
||||
|
||||
FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots()
|
||||
{
|
||||
@ -928,6 +897,58 @@ FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::nsExtendedDOMSlots::Unlink()
|
||||
{
|
||||
nsIContent::nsExtendedContentSlots::Unlink();
|
||||
|
||||
// Don't clear mXBLBinding, it'll be done in
|
||||
// BindingManager::RemovedFromDocument from FragmentOrElement::Unlink.
|
||||
mSMILOverrideStyle = nullptr;
|
||||
mControllers = nullptr;
|
||||
mLabelsList = nullptr;
|
||||
mShadowRoot = nullptr;
|
||||
if (mCustomElementData) {
|
||||
mCustomElementData->Unlink();
|
||||
mCustomElementData = nullptr;
|
||||
}
|
||||
nsCOMPtr<nsIFrameLoader> frameLoader =
|
||||
do_QueryInterface(mFrameLoaderOrOpener);
|
||||
if (frameLoader) {
|
||||
static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
|
||||
}
|
||||
mFrameLoaderOrOpener = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::nsExtendedDOMSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
|
||||
{
|
||||
nsIContent::nsExtendedContentSlots::Traverse(aCb);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mSMILOverrideStyle");
|
||||
aCb.NoteXPCOMChild(mSMILOverrideStyle.get());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mControllers");
|
||||
aCb.NoteXPCOMChild(mControllers);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mLabelsList");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mLabelsList));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mShadowRoot");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mShadowRoot));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mXBLBinding");
|
||||
aCb.NoteNativeChild(mXBLBinding,
|
||||
NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
|
||||
|
||||
if (mCustomElementData) {
|
||||
mCustomElementData->Traverse(aCb);
|
||||
}
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mFrameLoaderOrOpener");
|
||||
aCb.NoteXPCOMChild(mFrameLoaderOrOpener);
|
||||
}
|
||||
|
||||
FragmentOrElement::FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
||||
: nsIContent(aNodeInfo)
|
||||
{
|
||||
@ -1162,123 +1183,31 @@ FragmentOrElement::IsLink(nsIURI** aURI) const
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
FragmentOrElement::GetBindingParent() const
|
||||
{
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
|
||||
if (slots) {
|
||||
return slots->mBindingParent;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsXBLBinding*
|
||||
FragmentOrElement::DoGetXBLBinding() const
|
||||
{
|
||||
MOZ_ASSERT(HasFlag(NODE_MAY_BE_IN_BINDING_MNGR));
|
||||
if (nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots()) {
|
||||
return slots->mXBLBinding;
|
||||
}
|
||||
return nullptr;
|
||||
const nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
return slots ? slots->mXBLBinding.get() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::SetXBLBinding(nsXBLBinding* aBinding,
|
||||
nsBindingManager* aOldBindingManager)
|
||||
nsIContent::SetAssignedSlot(HTMLSlotElement* aSlot)
|
||||
{
|
||||
nsBindingManager* bindingManager;
|
||||
if (aOldBindingManager) {
|
||||
MOZ_ASSERT(!aBinding, "aOldBindingManager should only be provided "
|
||||
"when removing a binding.");
|
||||
bindingManager = aOldBindingManager;
|
||||
} else {
|
||||
bindingManager = OwnerDoc()->BindingManager();
|
||||
}
|
||||
|
||||
// After this point, aBinding will be the most-derived binding for aContent.
|
||||
// If we already have a binding for aContent, make sure to
|
||||
// remove it from the attached stack. Otherwise we might end up firing its
|
||||
// constructor twice (if aBinding inherits from it) or firing its constructor
|
||||
// after aContent has been deleted (if aBinding is null and the content node
|
||||
// dies before we process mAttachedStack).
|
||||
RefPtr<nsXBLBinding> oldBinding = GetXBLBinding();
|
||||
if (oldBinding) {
|
||||
bindingManager->RemoveFromAttachedQueue(oldBinding);
|
||||
}
|
||||
|
||||
if (aBinding) {
|
||||
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
slots->mXBLBinding = aBinding;
|
||||
bindingManager->AddBoundContent(this);
|
||||
} else {
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
slots->mXBLBinding = nullptr;
|
||||
}
|
||||
bindingManager->RemoveBoundContent(this);
|
||||
if (oldBinding) {
|
||||
oldBinding->SetBoundElement(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
FragmentOrElement::GetXBLInsertionPoint() const
|
||||
{
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mXBLInsertionPoint;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ShadowRoot*
|
||||
FragmentOrElement::GetContainingShadow() const
|
||||
{
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mContainingShadow;
|
||||
}
|
||||
return nullptr;
|
||||
ExtendedContentSlots()->mAssignedSlot = aSlot;
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::SetShadowRoot(ShadowRoot* aShadowRoot)
|
||||
{
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
slots->mShadowRoot = aShadowRoot;
|
||||
}
|
||||
|
||||
HTMLSlotElement*
|
||||
FragmentOrElement::GetAssignedSlot() const
|
||||
{
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
return slots ? slots->mAssignedSlot.get() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::SetAssignedSlot(HTMLSlotElement* aSlot)
|
||||
{
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
slots->mAssignedSlot = aSlot;
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::SetXBLInsertionPoint(nsIContent* aContent)
|
||||
nsIContent::SetXBLInsertionPoint(nsIContent* aContent)
|
||||
{
|
||||
nsCOMPtr<nsIContent> oldInsertionPoint = nullptr;
|
||||
if (aContent) {
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
nsExtendedContentSlots* slots = ExtendedContentSlots();
|
||||
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
|
||||
oldInsertionPoint = slots->mXBLInsertionPoint.forget();
|
||||
slots->mXBLInsertionPoint = aContent;
|
||||
} else {
|
||||
if (nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots()) {
|
||||
if (nsExtendedContentSlots* slots = GetExistingExtendedContentSlots()) {
|
||||
oldInsertionPoint = slots->mXBLInsertionPoint.forget();
|
||||
slots->mXBLInsertionPoint = nullptr;
|
||||
}
|
||||
@ -1570,15 +1499,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
|
||||
nsIDocument* doc = tmp->OwnerDoc();
|
||||
doc->BindingManager()->RemovedFromDocument(tmp, doc,
|
||||
nsBindingManager::eDoNotRunDtor);
|
||||
|
||||
// Unlink any DOM slots of interest.
|
||||
{
|
||||
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
slots->Unlink();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(FragmentOrElement)
|
||||
@ -2148,14 +2068,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
||||
cb.NoteXPCOMChild(tmp->mAttrsAndChildren.GetSafeChildAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse any DOM slots of interest.
|
||||
{
|
||||
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
slots->Traverse(cb);
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
||||
@ -2501,12 +2413,6 @@ FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult
|
||||
}
|
||||
}
|
||||
|
||||
nsINode::nsSlots*
|
||||
FragmentOrElement::CreateSlots()
|
||||
{
|
||||
return new nsDOMSlots();
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::FireNodeRemovedForChildren()
|
||||
{
|
||||
|
@ -148,16 +148,7 @@ public:
|
||||
virtual void AppendTextTo(nsAString& aResult) override;
|
||||
MOZ_MUST_USE
|
||||
virtual bool AppendTextTo(nsAString& aResult, const mozilla::fallible_t&) override;
|
||||
virtual nsIContent* GetBindingParent() const override;
|
||||
virtual nsXBLBinding* DoGetXBLBinding() const override;
|
||||
virtual void SetXBLBinding(nsXBLBinding* aBinding,
|
||||
nsBindingManager* aOldBindingManager = nullptr) override;
|
||||
virtual ShadowRoot *GetContainingShadow() const override;
|
||||
virtual void SetShadowRoot(ShadowRoot* aBinding) override;
|
||||
virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const override;
|
||||
virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) override;
|
||||
virtual nsIContent *GetXBLInsertionPoint() const override;
|
||||
virtual void SetXBLInsertionPoint(nsIContent* aContent) override;
|
||||
virtual bool IsLink(nsIURI** aURI) const override;
|
||||
|
||||
virtual void DestroyContent() override;
|
||||
@ -246,12 +237,14 @@ public:
|
||||
* accessed through the DOM.
|
||||
*/
|
||||
|
||||
class nsExtendedDOMSlots
|
||||
class nsExtendedDOMSlots final : public nsIContent::nsExtendedContentSlots
|
||||
{
|
||||
public:
|
||||
nsExtendedDOMSlots();
|
||||
~nsExtendedDOMSlots() final;
|
||||
|
||||
~nsExtendedDOMSlots();
|
||||
void Traverse(nsCycleCollectionTraversalCallback&) final;
|
||||
void Unlink() final;
|
||||
|
||||
/**
|
||||
* SMIL Overridde style rules (for SMIL animation of CSS properties)
|
||||
@ -264,12 +257,6 @@ public:
|
||||
*/
|
||||
RefPtr<mozilla::DeclarationBlock> mSMILOverrideStyleDeclaration;
|
||||
|
||||
/**
|
||||
* The nearest enclosing content node with a binding that created us.
|
||||
* @see FragmentOrElement::GetBindingParent
|
||||
*/
|
||||
nsIContent* mBindingParent; // [Weak]
|
||||
|
||||
/**
|
||||
* The controllers of the XUL Element.
|
||||
*/
|
||||
@ -285,26 +272,11 @@ public:
|
||||
*/
|
||||
RefPtr<ShadowRoot> mShadowRoot;
|
||||
|
||||
/**
|
||||
* The root ShadowRoot of this element if it is in a shadow tree.
|
||||
*/
|
||||
RefPtr<ShadowRoot> mContainingShadow;
|
||||
|
||||
/**
|
||||
* The assigned slot associated with this element.
|
||||
*/
|
||||
RefPtr<mozilla::dom::HTMLSlotElement> mAssignedSlot;
|
||||
|
||||
/**
|
||||
* XBL binding installed on the element.
|
||||
*/
|
||||
RefPtr<nsXBLBinding> mXBLBinding;
|
||||
|
||||
/**
|
||||
* XBL binding insertion point.
|
||||
*/
|
||||
nsCOMPtr<nsIContent> mXBLInsertionPoint;
|
||||
|
||||
/**
|
||||
* Web components custom element data.
|
||||
*/
|
||||
@ -317,14 +289,14 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class nsDOMSlots : public nsINode::nsSlots
|
||||
class nsDOMSlots final : public nsIContent::nsContentSlots
|
||||
{
|
||||
public:
|
||||
nsDOMSlots();
|
||||
virtual ~nsDOMSlots();
|
||||
~nsDOMSlots() final;
|
||||
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb);
|
||||
void Unlink();
|
||||
void Traverse(nsCycleCollectionTraversalCallback&) final;
|
||||
void Unlink() final;
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
@ -356,8 +328,6 @@ public:
|
||||
* An object implementing the .classList property for this element.
|
||||
*/
|
||||
RefPtr<nsDOMTokenList> mClassList;
|
||||
|
||||
mozilla::UniquePtr<nsExtendedDOMSlots> mExtendedSlots;
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -365,9 +335,17 @@ protected:
|
||||
void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
|
||||
|
||||
// Override from nsINode
|
||||
virtual nsINode::nsSlots* CreateSlots() override;
|
||||
nsIContent::nsContentSlots* CreateSlots() override
|
||||
{
|
||||
return new nsDOMSlots();
|
||||
}
|
||||
|
||||
nsDOMSlots *DOMSlots()
|
||||
nsIContent::nsExtendedContentSlots* CreateExtendedSlots() final
|
||||
{
|
||||
return new nsExtendedDOMSlots();
|
||||
}
|
||||
|
||||
nsDOMSlots* DOMSlots()
|
||||
{
|
||||
return static_cast<nsDOMSlots*>(Slots());
|
||||
}
|
||||
@ -379,22 +357,18 @@ protected:
|
||||
|
||||
nsExtendedDOMSlots* ExtendedDOMSlots()
|
||||
{
|
||||
nsDOMSlots* slots = DOMSlots();
|
||||
if (!slots->mExtendedSlots) {
|
||||
slots->mExtendedSlots = MakeUnique<nsExtendedDOMSlots>();
|
||||
}
|
||||
|
||||
return slots->mExtendedSlots.get();
|
||||
return static_cast<nsExtendedDOMSlots*>(ExtendedContentSlots());
|
||||
}
|
||||
|
||||
nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const
|
||||
const nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const
|
||||
{
|
||||
nsDOMSlots* slots = GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
return slots->mExtendedSlots.get();
|
||||
}
|
||||
return static_cast<const nsExtendedDOMSlots*>(
|
||||
GetExistingExtendedContentSlots());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
nsExtendedDOMSlots* GetExistingExtendedDOMSlots()
|
||||
{
|
||||
return static_cast<nsExtendedDOMSlots*>(GetExistingExtendedContentSlots());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7758,7 +7758,9 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
|
||||
// have a binding applied. Remove the binding from the element now
|
||||
// that it's getting adopted into a new document.
|
||||
// TODO Fully tear down the binding.
|
||||
adoptedNode->AsContent()->SetXBLBinding(nullptr);
|
||||
if (adoptedNode->IsElement()) {
|
||||
adoptedNode->AsElement()->SetXBLBinding(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -99,24 +99,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGenericDOMDataNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericDOMDataNode, tmp->mRefCnt.get())
|
||||
}
|
||||
|
||||
if (!nsINode::Traverse(tmp, cb)) {
|
||||
if (!nsIContent::Traverse(tmp, cb)) {
|
||||
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
||||
}
|
||||
|
||||
nsDataSlots *slots = tmp->GetExistingDataSlots();
|
||||
if (slots) {
|
||||
slots->Traverse(cb);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericDOMDataNode)
|
||||
nsINode::Unlink(tmp);
|
||||
nsIContent::Unlink(tmp);
|
||||
|
||||
// Clear flag here because unlinking slots will clear the
|
||||
// containing shadow root pointer.
|
||||
tmp->UnsetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||
|
||||
nsDataSlots *slots = tmp->GetExistingDataSlots();
|
||||
nsContentSlots* slots = tmp->GetExistingContentSlots();
|
||||
if (slots) {
|
||||
slots->Unlink();
|
||||
}
|
||||
@ -508,7 +503,7 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
(aParent && aParent->IsInNativeAnonymousSubtree()),
|
||||
"Trying to re-bind content from native anonymous subtree to "
|
||||
"non-native anonymous parent!");
|
||||
DataSlots()->mBindingParent = aBindingParent; // Weak, so no addref happens.
|
||||
ExtendedContentSlots()->mBindingParent = aBindingParent; // Weak, so no addref happens.
|
||||
if (aParent->IsInNativeAnonymousSubtree()) {
|
||||
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
|
||||
}
|
||||
@ -524,7 +519,7 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
}
|
||||
ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
|
||||
if (parentContainingShadow) {
|
||||
DataSlots()->mContainingShadow = parentContainingShadow;
|
||||
ExtendedContentSlots()->mContainingShadow = parentContainingShadow;
|
||||
}
|
||||
}
|
||||
|
||||
@ -620,7 +615,7 @@ nsGenericDOMDataNode::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
}
|
||||
}
|
||||
|
||||
nsDataSlots *slots = GetExistingDataSlots();
|
||||
nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
|
||||
if (slots) {
|
||||
slots->mBindingParent = nullptr;
|
||||
if (aNullParent || !mParent->IsInShadowTree()) {
|
||||
@ -668,82 +663,12 @@ nsGenericDOMDataNode::RemoveChildAt(uint32_t aIndex, bool aNotify)
|
||||
{
|
||||
}
|
||||
|
||||
nsIContent *
|
||||
nsGenericDOMDataNode::GetBindingParent() const
|
||||
{
|
||||
nsDataSlots *slots = GetExistingDataSlots();
|
||||
return slots ? slots->mBindingParent : nullptr;
|
||||
}
|
||||
|
||||
ShadowRoot *
|
||||
nsGenericDOMDataNode::GetContainingShadow() const
|
||||
{
|
||||
nsDataSlots *slots = GetExistingDataSlots();
|
||||
if (!slots) {
|
||||
return nullptr;
|
||||
}
|
||||
return slots->mContainingShadow;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericDOMDataNode::SetShadowRoot(ShadowRoot* aShadowRoot)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLSlotElement*
|
||||
nsGenericDOMDataNode::GetAssignedSlot() const
|
||||
{
|
||||
nsDataSlots *slots = GetExistingDataSlots();
|
||||
return slots ? slots->mAssignedSlot.get() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericDOMDataNode::SetAssignedSlot(HTMLSlotElement* aSlot)
|
||||
{
|
||||
nsDataSlots *slots = DataSlots();
|
||||
slots->mAssignedSlot = aSlot;
|
||||
}
|
||||
|
||||
nsXBLBinding *
|
||||
nsGenericDOMDataNode::DoGetXBLBinding() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericDOMDataNode::SetXBLBinding(nsXBLBinding* aBinding,
|
||||
nsBindingManager* aOldBindingManager)
|
||||
{
|
||||
}
|
||||
|
||||
nsIContent *
|
||||
nsGenericDOMDataNode::GetXBLInsertionPoint() const
|
||||
{
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
nsDataSlots *slots = GetExistingDataSlots();
|
||||
if (slots) {
|
||||
return slots->mXBLInsertionPoint;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericDOMDataNode::SetXBLInsertionPoint(nsIContent* aContent)
|
||||
{
|
||||
if (aContent) {
|
||||
nsDataSlots *slots = DataSlots();
|
||||
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
|
||||
slots->mXBLInsertionPoint = aContent;
|
||||
} else {
|
||||
nsDataSlots *slots = GetExistingDataSlots();
|
||||
if (slots) {
|
||||
slots->mXBLInsertionPoint = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsGenericDOMDataNode::IsNodeOfType(uint32_t aFlags) const
|
||||
{
|
||||
@ -775,38 +700,6 @@ nsGenericDOMDataNode::IsLink(nsIURI** aURI) const
|
||||
return false;
|
||||
}
|
||||
|
||||
nsINode::nsSlots*
|
||||
nsGenericDOMDataNode::CreateSlots()
|
||||
{
|
||||
return new nsDataSlots();
|
||||
}
|
||||
|
||||
nsGenericDOMDataNode::nsDataSlots::nsDataSlots()
|
||||
: nsINode::nsSlots(), mBindingParent(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericDOMDataNode::nsDataSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLInsertionPoint");
|
||||
cb.NoteXPCOMChild(mXBLInsertionPoint.get());
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mContainingShadow");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAssignedSlot");
|
||||
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mAssignedSlot.get()));
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericDOMDataNode::nsDataSlots::Unlink()
|
||||
{
|
||||
mXBLInsertionPoint = nullptr;
|
||||
mContainingShadow = nullptr;
|
||||
mAssignedSlot = nullptr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Implementation of the nsIDOMText interface
|
||||
|
@ -158,16 +158,7 @@ public:
|
||||
virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const override;
|
||||
#endif
|
||||
|
||||
virtual nsIContent* GetBindingParent() const override;
|
||||
virtual nsXBLBinding* DoGetXBLBinding() const override;
|
||||
virtual void SetXBLBinding(nsXBLBinding* aBinding,
|
||||
nsBindingManager* aOldBindingManager = nullptr) override;
|
||||
virtual mozilla::dom::ShadowRoot *GetContainingShadow() const override;
|
||||
virtual void SetShadowRoot(mozilla::dom::ShadowRoot* aShadowRoot) override;
|
||||
virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const override;
|
||||
virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) override;
|
||||
virtual nsIContent *GetXBLInsertionPoint() const override;
|
||||
virtual void SetXBLInsertionPoint(nsIContent* aContent) override;
|
||||
virtual bool IsNodeOfType(uint32_t aFlags) const override;
|
||||
virtual bool IsLink(nsIURI** aURI) const override;
|
||||
|
||||
@ -238,57 +229,6 @@ protected:
|
||||
return parent && parent->IsElement() ? parent->AsElement() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* There are a set of DOM- and scripting-specific instance variables
|
||||
* that may only be instantiated when a content object is accessed
|
||||
* through the DOM. Rather than burn actual slots in the content
|
||||
* objects for each of these instance variables, we put them off
|
||||
* in a side structure that's only allocated when the content is
|
||||
* accessed through the DOM.
|
||||
*/
|
||||
class nsDataSlots : public nsINode::nsSlots
|
||||
{
|
||||
public:
|
||||
nsDataSlots();
|
||||
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb);
|
||||
void Unlink();
|
||||
|
||||
/**
|
||||
* The nearest enclosing content node with a binding that created us.
|
||||
* @see nsIContent::GetBindingParent
|
||||
*/
|
||||
nsIContent* mBindingParent; // [Weak]
|
||||
|
||||
/**
|
||||
* @see nsIContent::GetXBLInsertionPoint
|
||||
*/
|
||||
nsCOMPtr<nsIContent> mXBLInsertionPoint;
|
||||
|
||||
/**
|
||||
* @see nsIContent::GetContainingShadow
|
||||
*/
|
||||
RefPtr<mozilla::dom::ShadowRoot> mContainingShadow;
|
||||
|
||||
/**
|
||||
* @see nsIContent::GetAssignedSlot
|
||||
*/
|
||||
RefPtr<mozilla::dom::HTMLSlotElement> mAssignedSlot;
|
||||
};
|
||||
|
||||
// Override from nsINode
|
||||
virtual nsINode::nsSlots* CreateSlots() override;
|
||||
|
||||
nsDataSlots* DataSlots()
|
||||
{
|
||||
return static_cast<nsDataSlots*>(Slots());
|
||||
}
|
||||
|
||||
nsDataSlots *GetExistingDataSlots() const
|
||||
{
|
||||
return static_cast<nsDataSlots*>(GetExistingSlots());
|
||||
}
|
||||
|
||||
nsresult SplitText(uint32_t aOffset, nsIDOMText** aReturn);
|
||||
|
||||
nsresult GetWholeText(nsAString& aWholeText);
|
||||
|
@ -507,7 +507,11 @@ public:
|
||||
*
|
||||
* @return the binding parent
|
||||
*/
|
||||
virtual nsIContent* GetBindingParent() const = 0;
|
||||
virtual nsIContent* GetBindingParent() const
|
||||
{
|
||||
const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
|
||||
return slots ? slots->mBindingParent : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current XBL binding that is bound to this element.
|
||||
@ -525,30 +529,6 @@ public:
|
||||
|
||||
virtual nsXBLBinding* DoGetXBLBinding() const = 0;
|
||||
|
||||
/**
|
||||
* Sets or unsets an XBL binding for this element. Setting a
|
||||
* binding on an element that already has a binding will remove the
|
||||
* old binding.
|
||||
*
|
||||
* @param aBinding The binding to bind to this content. If nullptr is
|
||||
* provided as the argument, then existing binding will be
|
||||
* removed.
|
||||
*
|
||||
* @param aOldBindingManager The old binding manager that contains
|
||||
* this content if this content was adopted
|
||||
* to another document.
|
||||
*/
|
||||
virtual void SetXBLBinding(nsXBLBinding* aBinding,
|
||||
nsBindingManager* aOldBindingManager = nullptr) = 0;
|
||||
|
||||
/**
|
||||
* Sets the ShadowRoot binding for this element. The contents of the
|
||||
* binding is rendered in place of this node's children.
|
||||
*
|
||||
* @param aShadowRoot The ShadowRoot to be bound to this element.
|
||||
*/
|
||||
virtual void SetShadowRoot(mozilla::dom::ShadowRoot* aShadowRoot) = 0;
|
||||
|
||||
/**
|
||||
* Gets the ShadowRoot binding for this element.
|
||||
*
|
||||
@ -563,21 +543,29 @@ public:
|
||||
*
|
||||
* @return The ShadowRoot that is the root of the node tree.
|
||||
*/
|
||||
virtual mozilla::dom::ShadowRoot *GetContainingShadow() const = 0;
|
||||
mozilla::dom::ShadowRoot* GetContainingShadow() const
|
||||
{
|
||||
const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
|
||||
return slots ? slots->mContainingShadow.get() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the assigned slot associated with this content.
|
||||
*
|
||||
* @return The assigned slot element or null.
|
||||
*/
|
||||
virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const = 0;
|
||||
mozilla::dom::HTMLSlotElement* GetAssignedSlot() const
|
||||
{
|
||||
const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
|
||||
return slots ? slots->mAssignedSlot.get() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the assigned slot associated with this content.
|
||||
*
|
||||
* @param aSlot The assigned slot.
|
||||
*/
|
||||
virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) = 0;
|
||||
void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot);
|
||||
|
||||
/**
|
||||
* Gets the assigned slot associated with this content based on parent's
|
||||
@ -600,14 +588,18 @@ public:
|
||||
*
|
||||
* @return the insertion parent element.
|
||||
*/
|
||||
virtual nsIContent* GetXBLInsertionPoint() const = 0;
|
||||
nsIContent* GetXBLInsertionPoint() const
|
||||
{
|
||||
const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
|
||||
return slots ? slots->mXBLInsertionPoint.get() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the insertion parent element of the XBL binding.
|
||||
*
|
||||
* @param aContent The insertion parent element.
|
||||
*/
|
||||
virtual void SetXBLInsertionPoint(nsIContent* aContent) = 0;
|
||||
void SetXBLInsertionPoint(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Same as GetFlattenedTreeParentNode, but returns null if the parent is
|
||||
@ -849,6 +841,114 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Lazily allocated extended slots to avoid
|
||||
* that may only be instantiated when a content object is accessed
|
||||
* through the DOM. Rather than burn actual slots in the content
|
||||
* objects for each of these instance variables, we put them off
|
||||
* in a side structure that's only allocated when the content is
|
||||
* accessed through the DOM.
|
||||
*/
|
||||
class nsExtendedContentSlots
|
||||
{
|
||||
public:
|
||||
nsExtendedContentSlots();
|
||||
virtual ~nsExtendedContentSlots();
|
||||
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback&);
|
||||
virtual void Unlink();
|
||||
|
||||
/**
|
||||
* The nearest enclosing content node with a binding that created us.
|
||||
* @see nsIContent::GetBindingParent
|
||||
*/
|
||||
nsIContent* mBindingParent; // [Weak]
|
||||
|
||||
/**
|
||||
* @see nsIContent::GetXBLInsertionPoint
|
||||
*/
|
||||
nsCOMPtr<nsIContent> mXBLInsertionPoint;
|
||||
|
||||
/**
|
||||
* @see nsIContent::GetContainingShadow
|
||||
*/
|
||||
RefPtr<mozilla::dom::ShadowRoot> mContainingShadow;
|
||||
|
||||
/**
|
||||
* @see nsIContent::GetAssignedSlot
|
||||
*/
|
||||
RefPtr<mozilla::dom::HTMLSlotElement> mAssignedSlot;
|
||||
};
|
||||
|
||||
class nsContentSlots : public nsINode::nsSlots
|
||||
{
|
||||
public:
|
||||
void Traverse(nsCycleCollectionTraversalCallback& aCb) override
|
||||
{
|
||||
nsINode::nsSlots::Traverse(aCb);
|
||||
if (mExtendedSlots) {
|
||||
mExtendedSlots->Traverse(aCb);
|
||||
}
|
||||
}
|
||||
|
||||
void Unlink() override
|
||||
{
|
||||
nsINode::nsSlots::Unlink();
|
||||
if (mExtendedSlots) {
|
||||
mExtendedSlots->Unlink();
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::UniquePtr<nsExtendedContentSlots> mExtendedSlots;
|
||||
};
|
||||
|
||||
// Override from nsINode
|
||||
nsContentSlots* CreateSlots() override
|
||||
{
|
||||
return new nsContentSlots();
|
||||
}
|
||||
|
||||
nsContentSlots* ContentSlots()
|
||||
{
|
||||
return static_cast<nsContentSlots*>(Slots());
|
||||
}
|
||||
|
||||
const nsContentSlots* GetExistingContentSlots() const
|
||||
{
|
||||
return static_cast<nsContentSlots*>(GetExistingSlots());
|
||||
}
|
||||
|
||||
nsContentSlots* GetExistingContentSlots()
|
||||
{
|
||||
return static_cast<nsContentSlots*>(GetExistingSlots());
|
||||
}
|
||||
|
||||
virtual nsExtendedContentSlots* CreateExtendedSlots()
|
||||
{
|
||||
return new nsExtendedContentSlots();
|
||||
}
|
||||
|
||||
const nsExtendedContentSlots* GetExistingExtendedContentSlots() const
|
||||
{
|
||||
const nsContentSlots* slots = GetExistingContentSlots();
|
||||
return slots ? slots->mExtendedSlots.get() : nullptr;
|
||||
}
|
||||
|
||||
nsExtendedContentSlots* GetExistingExtendedContentSlots()
|
||||
{
|
||||
nsContentSlots* slots = GetExistingContentSlots();
|
||||
return slots ? slots->mExtendedSlots.get() : nullptr;
|
||||
}
|
||||
|
||||
nsExtendedContentSlots* ExtendedContentSlots()
|
||||
{
|
||||
nsContentSlots* slots = ContentSlots();
|
||||
if (!slots->mExtendedSlots) {
|
||||
slots->mExtendedSlots.reset(CreateExtendedSlots());
|
||||
}
|
||||
return slots->mExtendedSlots.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for implementing GetID. This is guaranteed to only be
|
||||
* called if HasID() is true.
|
||||
|
@ -1112,8 +1112,8 @@ public:
|
||||
// putting a DestroySlots function on nsINode
|
||||
virtual ~nsSlots();
|
||||
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb);
|
||||
void Unlink();
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback&);
|
||||
virtual void Unlink();
|
||||
|
||||
/**
|
||||
* A list of mutation observers
|
||||
|
@ -216,7 +216,7 @@ nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent,
|
||||
binding->ChangeDocument(aOldDocument, nullptr);
|
||||
}
|
||||
|
||||
aContent->SetXBLBinding(nullptr, this);
|
||||
aContent->AsElement()->SetXBLBinding(nullptr, this);
|
||||
}
|
||||
|
||||
// Clear out insertion point and content lists.
|
||||
|
@ -1680,12 +1680,6 @@ nsXULElement::DoCommand()
|
||||
}
|
||||
}
|
||||
|
||||
nsIContent *
|
||||
nsXULElement::GetBindingParent() const
|
||||
{
|
||||
return mBindingParent;
|
||||
}
|
||||
|
||||
bool
|
||||
nsXULElement::IsNodeOfType(uint32_t aFlags) const
|
||||
{
|
||||
|
@ -384,7 +384,11 @@ public:
|
||||
bool aIsTrustedEvent) override;
|
||||
void ClickWithInputSource(uint16_t aInputSource, bool aIsTrustedEvent);
|
||||
|
||||
virtual nsIContent *GetBindingParent() const override;
|
||||
nsIContent* GetBindingParent() const final
|
||||
{
|
||||
return mBindingParent;
|
||||
}
|
||||
|
||||
virtual bool IsNodeOfType(uint32_t aFlags) const override;
|
||||
virtual bool IsFocusableInternal(int32_t* aTabIndex, bool aWithMouse) override;
|
||||
|
||||
|
@ -16,7 +16,7 @@ V1_CUTOFF = 20150801000000 # YYYYmmddHHMMSS
|
||||
def android_version_code_v0(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
|
||||
base = int(str(buildid)[:10])
|
||||
# None is interpreted as arm.
|
||||
if not cpu_arch or cpu_arch in ['armeabi', 'armeabi-v7a']:
|
||||
if not cpu_arch or cpu_arch == 'armeabi-v7a':
|
||||
# Increment by MIN_SDK_VERSION -- this adds 9 to every build ID as a
|
||||
# minimum. Our split APK starts at 15.
|
||||
return base + min_sdk + 0
|
||||
@ -114,7 +114,7 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
|
||||
version |= base << 3
|
||||
|
||||
# None is interpreted as arm.
|
||||
if not cpu_arch or cpu_arch in ['armeabi', 'armeabi-v7a']:
|
||||
if not cpu_arch or cpu_arch == 'armeabi-v7a':
|
||||
# 0 is interpreted as SDK 9.
|
||||
if not min_sdk or min_sdk == 9:
|
||||
pass
|
||||
|
@ -775,8 +775,6 @@ pub struct NormalBorder {
|
||||
pub style: SideOffsets2D<border_style::T>,
|
||||
|
||||
/// Border radii.
|
||||
///
|
||||
/// TODO(pcwalton): Elliptical radii.
|
||||
pub radius: BorderRadii<Au>,
|
||||
}
|
||||
|
||||
@ -845,8 +843,6 @@ pub struct BorderDisplayItem {
|
||||
}
|
||||
|
||||
/// Information about the border radii.
|
||||
///
|
||||
/// TODO(pcwalton): Elliptical radii.
|
||||
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
|
||||
pub struct BorderRadii<T> {
|
||||
pub top_left: Size2D<T>,
|
||||
|
@ -798,6 +798,7 @@ fn convert_gradient_stops(gradient_items: &[GradientItem],
|
||||
position_to_offset(position, total_length)
|
||||
}
|
||||
};
|
||||
assert!(offset.is_finite());
|
||||
stops.push(GradientStop {
|
||||
offset: offset,
|
||||
color: stop.color.to_gfx_color()
|
||||
@ -1544,7 +1545,6 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||
Au::from(box_shadow.spread),
|
||||
);
|
||||
|
||||
// TODO(pcwalton): Multiple border radii; elliptical border radii.
|
||||
let base = state.create_base_display_item(&bounds,
|
||||
LocalClip::from(clip.to_rectf()),
|
||||
self.node,
|
||||
@ -3271,6 +3271,9 @@ struct StopRun {
|
||||
}
|
||||
|
||||
fn position_to_offset(position: LengthOrPercentage, total_length: Au) -> f32 {
|
||||
if total_length == Au(0) {
|
||||
return 0.0
|
||||
}
|
||||
match position {
|
||||
LengthOrPercentage::Length(l) => l.to_i32_au() as f32 / total_length.0 as f32,
|
||||
LengthOrPercentage::Percentage(percentage) => percentage.0 as f32,
|
||||
|
File diff suppressed because one or more lines are too long
@ -536,8 +536,9 @@ impl<'le> GeckoElement<'le> {
|
||||
fn get_extended_slots(
|
||||
&self,
|
||||
) -> Option<&structs::FragmentOrElement_nsExtendedDOMSlots> {
|
||||
self.get_dom_slots()
|
||||
.and_then(|s| unsafe { s.mExtendedSlots.mPtr.as_ref() })
|
||||
self.get_dom_slots().and_then(|s| unsafe {
|
||||
(s._base.mExtendedSlots.mPtr as *const structs::FragmentOrElement_nsExtendedDOMSlots).as_ref()
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -592,7 +593,7 @@ impl<'le> GeckoElement<'le> {
|
||||
fn get_non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent {
|
||||
debug_assert!(!self.is_xul_element());
|
||||
self.get_extended_slots()
|
||||
.map_or(ptr::null_mut(), |slots| slots.mBindingParent)
|
||||
.map_or(ptr::null_mut(), |slots| slots._base.mBindingParent)
|
||||
}
|
||||
|
||||
fn has_xbl_binding_parent(&self) -> bool {
|
||||
|
@ -13,229 +13,36 @@
|
||||
//
|
||||
// We allow "display" to apply to placeholders because we need to make the
|
||||
// placeholder pseudo-element an inline-block in the UA stylesheet in Gecko.
|
||||
<%helpers:longhand name="display"
|
||||
animation_value_type="discrete"
|
||||
custom_cascade="${product == 'servo'}"
|
||||
flags="APPLIES_TO_PLACEHOLDER"
|
||||
spec="https://drafts.csswg.org/css-display/#propdef-display">
|
||||
<%
|
||||
values = """inline block inline-block
|
||||
table inline-table table-row-group table-header-group table-footer-group
|
||||
table-row table-column-group table-column table-cell table-caption
|
||||
list-item none
|
||||
""".split()
|
||||
webkit_prefixed_values = "flex inline-flex".split()
|
||||
values += webkit_prefixed_values
|
||||
if product == "gecko":
|
||||
values += """grid inline-grid ruby ruby-base ruby-base-container
|
||||
ruby-text ruby-text-container contents flow-root -webkit-box
|
||||
-webkit-inline-box -moz-box -moz-inline-box -moz-grid -moz-inline-grid
|
||||
-moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck
|
||||
-moz-popup -moz-groupbox""".split()
|
||||
%>
|
||||
use style_traits::ToCss;
|
||||
${helpers.predefined_type(
|
||||
"display",
|
||||
"Display",
|
||||
"computed::Display::inline()",
|
||||
initial_specified_value="specified::Display::inline()",
|
||||
animation_value_type="discrete",
|
||||
needs_context=False,
|
||||
custom_cascade= product == 'servo',
|
||||
custom_cascade_function="specified::Display::cascade_property_custom",
|
||||
flags="APPLIES_TO_PLACEHOLDER",
|
||||
spec="https://drafts.csswg.org/css-display/#propdef-display",
|
||||
)}
|
||||
|
||||
pub mod computed_value {
|
||||
pub use super::SpecifiedValue as T;
|
||||
use super::SpecifiedValue as Display;
|
||||
|
||||
impl Display {
|
||||
/// Returns whether this "display" value is the display of a flex or
|
||||
/// grid container.
|
||||
///
|
||||
/// This is used to implement various style fixups.
|
||||
pub fn is_item_container(&self) -> bool {
|
||||
matches!(*self,
|
||||
Display::Flex
|
||||
| Display::InlineFlex
|
||||
% if product == "gecko":
|
||||
| Display::Grid
|
||||
| Display::InlineGrid
|
||||
% endif
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns whether an element with this display type is a line
|
||||
/// participant, which means it may lay its children on the same
|
||||
/// line as itself.
|
||||
pub fn is_line_participant(&self) -> bool {
|
||||
matches!(*self,
|
||||
Display::Inline
|
||||
% if product == "gecko":
|
||||
| Display::Contents
|
||||
| Display::Ruby
|
||||
| Display::RubyBaseContainer
|
||||
% endif
|
||||
)
|
||||
}
|
||||
|
||||
/// Whether `new_display` should be ignored, given a previous
|
||||
/// `old_display` value.
|
||||
///
|
||||
/// This is used to ignore `display: -moz-box` declarations after an
|
||||
/// equivalent `display: -webkit-box` declaration, since the former
|
||||
/// has a vastly different meaning. See bug 1107378 and bug 1407701.
|
||||
///
|
||||
/// FIXME(emilio): This is a pretty decent hack, we should try to
|
||||
/// remove it.
|
||||
pub fn should_ignore_parsed_value(
|
||||
_old_display: Self,
|
||||
_new_display: Self,
|
||||
) -> bool {
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
match (_old_display, _new_display) {
|
||||
(Display::WebkitBox, Display::MozBox) |
|
||||
(Display::WebkitInlineBox, Display::MozInlineBox) => {
|
||||
return true;
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns whether this "display" value is one of the types for
|
||||
/// ruby.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn is_ruby_type(&self) -> bool {
|
||||
matches!(*self,
|
||||
Display::Ruby |
|
||||
Display::RubyBase |
|
||||
Display::RubyText |
|
||||
Display::RubyBaseContainer |
|
||||
Display::RubyTextContainer)
|
||||
}
|
||||
|
||||
/// Returns whether this "display" value is a ruby level container.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn is_ruby_level_container(&self) -> bool {
|
||||
matches!(*self,
|
||||
Display::RubyBaseContainer |
|
||||
Display::RubyTextContainer)
|
||||
}
|
||||
|
||||
/// Convert this display into an equivalent block display.
|
||||
///
|
||||
/// Also used for style adjustments.
|
||||
pub fn equivalent_block_display(&self, _is_root_element: bool) -> Self {
|
||||
match *self {
|
||||
// Values that have a corresponding block-outside version.
|
||||
Display::InlineTable => Display::Table,
|
||||
Display::InlineFlex => Display::Flex,
|
||||
|
||||
% if product == "gecko":
|
||||
Display::InlineGrid => Display::Grid,
|
||||
Display::WebkitInlineBox => Display::WebkitBox,
|
||||
% endif
|
||||
|
||||
// Special handling for contents and list-item on the root
|
||||
// element for Gecko.
|
||||
% if product == "gecko":
|
||||
Display::Contents | Display::ListItem if _is_root_element => Display::Block,
|
||||
% endif
|
||||
|
||||
// These are not changed by blockification.
|
||||
Display::None |
|
||||
Display::Block |
|
||||
Display::Flex |
|
||||
Display::ListItem |
|
||||
Display::Table => *self,
|
||||
|
||||
% if product == "gecko":
|
||||
Display::Contents |
|
||||
Display::FlowRoot |
|
||||
Display::Grid |
|
||||
Display::WebkitBox => *self,
|
||||
% endif
|
||||
|
||||
// Everything else becomes block.
|
||||
_ => Display::Block,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Convert this display into an inline-outside display.
|
||||
///
|
||||
/// Ideally it should implement spec: https://drafts.csswg.org/css-display/#inlinify
|
||||
/// but the spec isn't stable enough, so we copy what Gecko does for now.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn inlinify(&self) -> Self {
|
||||
match *self {
|
||||
Display::Block |
|
||||
Display::FlowRoot => Display::InlineBlock,
|
||||
Display::Table => Display::InlineTable,
|
||||
Display::Flex => Display::InlineFlex,
|
||||
Display::Grid => Display::InlineGrid,
|
||||
Display::MozBox => Display::MozInlineBox,
|
||||
Display::MozStack => Display::MozInlineStack,
|
||||
Display::WebkitBox => Display::WebkitInlineBox,
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(emilio): Why does this reinvent the wheel, again?
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
pub enum SpecifiedValue {
|
||||
% for value in values:
|
||||
${to_camel_case(value)},
|
||||
% endfor
|
||||
}
|
||||
|
||||
// TODO(emilio): derive.
|
||||
impl ToCss for SpecifiedValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result
|
||||
where W: ::std::fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
% for value in values:
|
||||
SpecifiedValue::${to_camel_case(value)} => dest.write_str("${value}"),
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The initial display value.
|
||||
#[inline]
|
||||
pub fn get_initial_value() -> computed_value::T {
|
||||
computed_value::T::${to_camel_case(values[0])}
|
||||
}
|
||||
|
||||
/// Parse a display value.
|
||||
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<SpecifiedValue, ParseError<'i>> {
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
% for value in values:
|
||||
"${value}" => {
|
||||
Ok(computed_value::T::${to_camel_case(value)})
|
||||
},
|
||||
% endfor
|
||||
% for value in webkit_prefixed_values:
|
||||
"-webkit-${value}" => {
|
||||
Ok(computed_value::T::${to_camel_case(value)})
|
||||
},
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
|
||||
% if product == "servo":
|
||||
fn cascade_property_custom(_declaration: &PropertyDeclaration,
|
||||
context: &mut computed::Context) {
|
||||
longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
|
||||
longhands::_servo_text_decorations_in_effect::derive_from_display(context);
|
||||
}
|
||||
% endif
|
||||
|
||||
${helpers.gecko_keyword_conversion(Keyword('display', ' '.join(values),
|
||||
gecko_enum_prefix='StyleDisplay',
|
||||
gecko_strip_moz_prefix=False))}
|
||||
|
||||
</%helpers:longhand>
|
||||
// FIXME(emilio): Listing all the display values here is very unfortunate, we should teach C++ to use the
|
||||
// Rust enum directly, or generate the conversions to `StyleDisplay`.
|
||||
${helpers.gecko_keyword_conversion(
|
||||
Keyword('display', """
|
||||
inline block inline-block
|
||||
table inline-table table-row-group table-header-group table-footer-group
|
||||
table-row table-column-group table-column table-cell table-caption
|
||||
list-item none flex inline-flex grid inline-grid ruby ruby-base ruby-base-container
|
||||
ruby-text ruby-text-container contents flow-root -webkit-box
|
||||
-webkit-inline-box -moz-box -moz-inline-box -moz-grid -moz-inline-grid
|
||||
-moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck
|
||||
-moz-popup -moz-groupbox
|
||||
""",
|
||||
gecko_enum_prefix='StyleDisplay',
|
||||
gecko_strip_moz_prefix=False),
|
||||
type="::values::specified::Display"
|
||||
)}
|
||||
|
||||
${helpers.single_keyword("-moz-top-layer", "none top",
|
||||
gecko_constant_prefix="NS_STYLE_TOP_LAYER",
|
||||
|
@ -3079,21 +3079,13 @@ bitflags! {
|
||||
/// that it may affect global state, like the Device's root font-size.
|
||||
const IS_ROOT_ELEMENT = 1 << 3;
|
||||
|
||||
/// Whether to convert display:contents into display:inline. This
|
||||
/// is used by Gecko to prevent display:contents on generated
|
||||
/// content.
|
||||
const PROHIBIT_DISPLAY_CONTENTS = 1 << 4;
|
||||
|
||||
/// Whether we're styling the ::-moz-fieldset-content anonymous box.
|
||||
const IS_FIELDSET_CONTENT = 1 << 5;
|
||||
|
||||
/// Whether we're computing the style of a link, either visited or
|
||||
/// unvisited.
|
||||
const IS_LINK = 1 << 6;
|
||||
const IS_LINK = 1 << 4;
|
||||
|
||||
/// Whether we're computing the style of a link element that happens to
|
||||
/// be visited.
|
||||
const IS_VISITED_LINK = 1 << 7;
|
||||
const IS_VISITED_LINK = 1 << 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,12 +320,13 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||
|
||||
/// Native anonymous content converts display:contents into display:inline.
|
||||
#[cfg(feature = "gecko")]
|
||||
fn adjust_for_prohibited_display_contents(&mut self, flags: CascadeFlags) {
|
||||
use properties::CascadeFlags;
|
||||
|
||||
fn adjust_for_prohibited_display_contents(&mut self) {
|
||||
// TODO: We should probably convert display:contents into display:none
|
||||
// in some cases too: https://drafts.csswg.org/css-display/#unbox
|
||||
if !flags.contains(CascadeFlags::PROHIBIT_DISPLAY_CONTENTS) ||
|
||||
//
|
||||
// FIXME(emilio): ::before and ::after should support display: contents,
|
||||
// see bug 1418138.
|
||||
if self.style.pseudo.is_none() ||
|
||||
self.style.get_box().clone_display() != Display::Contents {
|
||||
return;
|
||||
}
|
||||
@ -343,12 +344,12 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||
fn adjust_for_fieldset_content(
|
||||
&mut self,
|
||||
layout_parent_style: &ComputedValues,
|
||||
flags: CascadeFlags,
|
||||
) {
|
||||
use properties::CascadeFlags;
|
||||
if !flags.contains(CascadeFlags::IS_FIELDSET_CONTENT) {
|
||||
return;
|
||||
match self.style.pseudo {
|
||||
Some(ref p) if p.is_fieldset_content() => {},
|
||||
_ => return,
|
||||
}
|
||||
|
||||
debug_assert_eq!(self.style.get_box().clone_display(), Display::Block);
|
||||
// TODO We actually want style from parent rather than layout
|
||||
// parent, so that this fixup doesn't happen incorrectly when
|
||||
@ -569,8 +570,8 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||
self.adjust_for_visited(flags);
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
self.adjust_for_prohibited_display_contents(flags);
|
||||
self.adjust_for_fieldset_content(layout_parent_style, flags);
|
||||
self.adjust_for_prohibited_display_contents();
|
||||
self.adjust_for_fieldset_content(layout_parent_style);
|
||||
}
|
||||
self.adjust_for_top_layer();
|
||||
self.blockify_if_necessary(layout_parent_style, flags);
|
||||
|
@ -566,9 +566,10 @@ where
|
||||
}
|
||||
cascade_flags.insert(CascadeFlags::VISITED_DEPENDENT_ONLY);
|
||||
}
|
||||
if self.element.is_native_anonymous() || pseudo.is_some() {
|
||||
cascade_flags.insert(CascadeFlags::PROHIBIT_DISPLAY_CONTENTS);
|
||||
} else if self.element.is_root() {
|
||||
if !self.element.is_native_anonymous() &&
|
||||
pseudo.is_none() &&
|
||||
self.element.is_root()
|
||||
{
|
||||
cascade_flags.insert(CascadeFlags::IS_ROOT_ELEMENT);
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,8 @@ use values::computed::length::LengthOrPercentage;
|
||||
use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount;
|
||||
use values::generics::box_::VerticalAlign as GenericVerticalAlign;
|
||||
|
||||
pub use values::specified::box_::{AnimationName, OverflowClipBox, OverscrollBehavior};
|
||||
pub use values::specified::box_::{ScrollSnapType, TouchAction, WillChange};
|
||||
pub use values::specified::box_::{AnimationName, Display, OverflowClipBox};
|
||||
pub use values::specified::box_::{OverscrollBehavior, ScrollSnapType, TouchAction, WillChange};
|
||||
|
||||
/// A computed value for the `vertical-align` property.
|
||||
pub type VerticalAlign = GenericVerticalAlign<LengthOrPercentage>;
|
||||
|
@ -40,7 +40,7 @@ pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVa
|
||||
pub use self::font::{FontFamily, FontLanguageOverride, FontVariantSettings, FontVariantEastAsian};
|
||||
pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings};
|
||||
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XTextZoom, XLang};
|
||||
pub use self::box_::{AnimationIterationCount, AnimationName, OverscrollBehavior};
|
||||
pub use self::box_::{AnimationIterationCount, AnimationName, Display, OverscrollBehavior};
|
||||
pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange};
|
||||
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
||||
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
|
||||
|
@ -7,15 +7,231 @@
|
||||
use Atom;
|
||||
use cssparser::Parser;
|
||||
use parser::{Parse, ParserContext};
|
||||
#[cfg(feature = "servo")]
|
||||
use properties::{longhands, PropertyDeclaration};
|
||||
use std::fmt;
|
||||
use style_traits::{ParseError, ToCss};
|
||||
use values::CustomIdent;
|
||||
use values::KeyframesName;
|
||||
#[cfg(feature = "servo")]
|
||||
use values::computed::Context;
|
||||
use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount;
|
||||
use values::generics::box_::VerticalAlign as GenericVerticalAlign;
|
||||
use values::specified::{AllowQuirks, Number};
|
||||
use values::specified::length::LengthOrPercentage;
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
/// Defines an element’s display type, which consists of
|
||||
/// the two basic qualities of how an element generates boxes
|
||||
/// <https://drafts.csswg.org/css-display/#propdef-display>
|
||||
pub enum Display {
|
||||
Inline, Block, InlineBlock,
|
||||
Table, InlineTable, TableRowGroup, TableHeaderGroup,
|
||||
TableFooterGroup, TableRow, TableColumnGroup,
|
||||
TableColumn, TableCell, TableCaption, ListItem, None,
|
||||
#[parse(aliases = "-webkit-flex")]
|
||||
Flex,
|
||||
#[parse(aliases = "-webkit-inline-flex")]
|
||||
InlineFlex,
|
||||
#[cfg(feature = "gecko")]
|
||||
Grid,
|
||||
#[cfg(feature = "gecko")]
|
||||
InlineGrid,
|
||||
#[cfg(feature = "gecko")]
|
||||
Ruby,
|
||||
#[cfg(feature = "gecko")]
|
||||
RubyBase,
|
||||
#[cfg(feature = "gecko")]
|
||||
RubyBaseContainer,
|
||||
#[cfg(feature = "gecko")]
|
||||
RubyText,
|
||||
#[cfg(feature = "gecko")]
|
||||
RubyTextContainer,
|
||||
#[cfg(feature = "gecko")]
|
||||
Contents,
|
||||
#[cfg(feature = "gecko")]
|
||||
FlowRoot,
|
||||
#[cfg(feature = "gecko")]
|
||||
WebkitBox,
|
||||
#[cfg(feature = "gecko")]
|
||||
WebkitInlineBox,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozBox,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozInlineBox,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozGrid,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozInlineGrid,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozGridGroup,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozGridLine,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozStack,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozInlineStack,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozDeck,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozPopup,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozGroupbox,
|
||||
}
|
||||
|
||||
impl Display {
|
||||
/// The initial display value.
|
||||
#[inline]
|
||||
pub fn inline() -> Self {
|
||||
Display::Inline
|
||||
}
|
||||
|
||||
/// Returns whether this "display" value is the display of a flex or
|
||||
/// grid container.
|
||||
///
|
||||
/// This is used to implement various style fixups.
|
||||
pub fn is_item_container(&self) -> bool {
|
||||
match *self {
|
||||
Display::Flex | Display::InlineFlex => true,
|
||||
#[cfg(feature = "gecko")]
|
||||
Display::Grid | Display::InlineGrid => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether an element with this display type is a line
|
||||
/// participant, which means it may lay its children on the same
|
||||
/// line as itself.
|
||||
pub fn is_line_participant(&self) -> bool {
|
||||
match *self {
|
||||
Display::Inline => true,
|
||||
#[cfg(feature = "gecko")]
|
||||
Display::Contents |
|
||||
Display::Ruby |
|
||||
Display::RubyBaseContainer => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether `new_display` should be ignored, given a previous
|
||||
/// `old_display` value.
|
||||
///
|
||||
/// This is used to ignore `display: -moz-box` declarations after an
|
||||
/// equivalent `display: -webkit-box` declaration, since the former
|
||||
/// has a vastly different meaning. See bug 1107378 and bug 1407701.
|
||||
///
|
||||
/// FIXME(emilio): This is a pretty decent hack, we should try to
|
||||
/// remove it.
|
||||
pub fn should_ignore_parsed_value(
|
||||
_old_display: Self,
|
||||
_new_display: Self,
|
||||
) -> bool {
|
||||
#[cfg(feature = "gecko")] {
|
||||
match (_old_display, _new_display) {
|
||||
(Display::WebkitBox, Display::MozBox) |
|
||||
(Display::WebkitInlineBox, Display::MozInlineBox) => {
|
||||
return true;
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns whether this "display" value is one of the types for
|
||||
/// ruby.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn is_ruby_type(&self) -> bool {
|
||||
matches!(*self,
|
||||
Display::Ruby |
|
||||
Display::RubyBase |
|
||||
Display::RubyText |
|
||||
Display::RubyBaseContainer |
|
||||
Display::RubyTextContainer
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns whether this "display" value is a ruby level container.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn is_ruby_level_container(&self) -> bool {
|
||||
matches!(*self,
|
||||
Display::RubyBaseContainer |
|
||||
Display::RubyTextContainer
|
||||
)
|
||||
}
|
||||
|
||||
/// Convert this display into an equivalent block display.
|
||||
///
|
||||
/// Also used for style adjustments.
|
||||
pub fn equivalent_block_display(&self, _is_root_element: bool) -> Self {
|
||||
match *self {
|
||||
// Values that have a corresponding block-outside version.
|
||||
Display::InlineTable => Display::Table,
|
||||
Display::InlineFlex => Display::Flex,
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
Display::InlineGrid => Display::Grid,
|
||||
#[cfg(feature = "gecko")]
|
||||
Display::WebkitInlineBox => Display::WebkitBox,
|
||||
|
||||
// Special handling for contents and list-item on the root
|
||||
// element for Gecko.
|
||||
#[cfg(feature = "gecko")]
|
||||
Display::Contents | Display::ListItem if _is_root_element => Display::Block,
|
||||
|
||||
// These are not changed by blockification.
|
||||
Display::None |
|
||||
Display::Block |
|
||||
Display::Flex |
|
||||
Display::ListItem |
|
||||
Display::Table => *self,
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
Display::Contents |
|
||||
Display::FlowRoot |
|
||||
Display::Grid |
|
||||
Display::WebkitBox => *self,
|
||||
|
||||
// Everything else becomes block.
|
||||
_ => Display::Block,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Convert this display into an inline-outside display.
|
||||
///
|
||||
/// Ideally it should implement spec: https://drafts.csswg.org/css-display/#inlinify
|
||||
/// but the spec isn't stable enough, so we copy what Gecko does for now.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn inlinify(&self) -> Self {
|
||||
match *self {
|
||||
Display::Block |
|
||||
Display::FlowRoot => Display::InlineBlock,
|
||||
Display::Table => Display::InlineTable,
|
||||
Display::Flex => Display::InlineFlex,
|
||||
Display::Grid => Display::InlineGrid,
|
||||
Display::MozBox => Display::MozInlineBox,
|
||||
Display::MozStack => Display::MozInlineStack,
|
||||
Display::WebkitBox => Display::WebkitInlineBox,
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
#[inline]
|
||||
/// Custom cascade for the `display` property in servo
|
||||
pub fn cascade_property_custom(
|
||||
_declaration: &PropertyDeclaration,
|
||||
context: &mut Context
|
||||
) {
|
||||
longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
|
||||
longhands::_servo_text_decorations_in_effect::derive_from_display(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// A specified value for the `vertical-align` property.
|
||||
pub type VerticalAlign = GenericVerticalAlign<LengthOrPercentage>;
|
||||
|
||||
|
@ -34,7 +34,7 @@ pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVa
|
||||
pub use self::font::{FontFamily, FontLanguageOverride, FontVariantSettings, FontVariantEastAsian};
|
||||
pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings};
|
||||
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XTextZoom, XLang};
|
||||
pub use self::box_::{AnimationIterationCount, AnimationName, OverscrollBehavior};
|
||||
pub use self::box_::{AnimationIterationCount, AnimationName, Display, OverscrollBehavior};
|
||||
pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange};
|
||||
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
||||
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
|
||||
|
@ -39,7 +39,7 @@ pub fn derive_to_animated_value(stream: TokenStream) -> TokenStream {
|
||||
to_animated_value::derive(input).to_string().parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Parse)]
|
||||
#[proc_macro_derive(Parse, attributes(parse))]
|
||||
pub fn derive_parse(stream: TokenStream) -> TokenStream {
|
||||
let input = syn::parse_derive_input(&stream.to_string()).unwrap();
|
||||
parse::derive(input).to_string().parse().unwrap()
|
||||
|
@ -19,11 +19,25 @@ pub fn derive(input: DeriveInput) -> Tokens {
|
||||
"Parse is only supported for single-variant enums for now"
|
||||
);
|
||||
|
||||
let variant_attrs = cg::parse_variant_attrs::<ParseVariantAttrs>(variant);
|
||||
let identifier = cg::to_css_identifier(variant.ident.as_ref());
|
||||
let ident = &variant.ident;
|
||||
|
||||
match_body = quote! {
|
||||
#match_body
|
||||
#identifier => Ok(#name::#ident),
|
||||
};
|
||||
|
||||
let aliases = match variant_attrs.aliases {
|
||||
Some(aliases) => aliases,
|
||||
None => return,
|
||||
};
|
||||
|
||||
for alias in aliases.split(",") {
|
||||
match_body = quote! {
|
||||
#match_body
|
||||
#alias => Ok(#name::#ident),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@ -73,3 +87,11 @@ pub fn derive(input: DeriveInput) -> Tokens {
|
||||
#methods_impl
|
||||
}
|
||||
}
|
||||
|
||||
#[darling(attributes(parse), default)]
|
||||
#[derive(Default, FromVariant)]
|
||||
struct ParseVariantAttrs {
|
||||
/// The comma-separated list of aliases this variant should be aliased to at
|
||||
/// parse time.
|
||||
aliases: Option<String>,
|
||||
}
|
||||
|
@ -1987,10 +1987,6 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
|
||||
let pseudo = PseudoElement::from_anon_box_atom(&atom)
|
||||
.expect("Not an anon box pseudo?");
|
||||
|
||||
let mut cascade_flags = CascadeFlags::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
|
||||
if pseudo.is_fieldset_content() {
|
||||
cascade_flags.insert(CascadeFlags::IS_FIELDSET_CONTENT);
|
||||
}
|
||||
let metrics = get_metrics_provider_for_product();
|
||||
|
||||
// If the pseudo element is PageContent, we should append the precomputed
|
||||
@ -2023,6 +2019,7 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
|
||||
page_decls,
|
||||
);
|
||||
|
||||
let cascade_flags = CascadeFlags::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
|
||||
data.stylist.precomputed_values_for_pseudo_with_rule_node(
|
||||
&guards,
|
||||
&pseudo,
|
||||
@ -3629,21 +3626,10 @@ pub extern "C" fn Servo_ReparentStyle(
|
||||
if let Some(element) = element {
|
||||
if element.is_link() {
|
||||
cascade_flags.insert(CascadeFlags::IS_LINK);
|
||||
if element.is_visited_link() &&
|
||||
doc_data.visited_styles_enabled() {
|
||||
if element.is_visited_link() && doc_data.visited_styles_enabled() {
|
||||
cascade_flags.insert(CascadeFlags::IS_VISITED_LINK);
|
||||
}
|
||||
};
|
||||
|
||||
if element.is_native_anonymous() {
|
||||
cascade_flags.insert(CascadeFlags::PROHIBIT_DISPLAY_CONTENTS);
|
||||
}
|
||||
}
|
||||
if let Some(pseudo) = pseudo.as_ref() {
|
||||
cascade_flags.insert(CascadeFlags::PROHIBIT_DISPLAY_CONTENTS);
|
||||
if pseudo.is_fieldset_content() {
|
||||
cascade_flags.insert(CascadeFlags::IS_FIELDSET_CONTENT);
|
||||
}
|
||||
}
|
||||
|
||||
doc_data.stylist.compute_style_with_inputs(
|
||||
|
@ -103,9 +103,6 @@ if CONFIG['MOZ_GECKO_PROFILER']:
|
||||
if not CONFIG['MOZ_CRASHREPORTER'] and CONFIG['OS_TARGET'] == 'Android':
|
||||
SOURCES += ['/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S']
|
||||
|
||||
if CONFIG['ANDROID_CPU_ARCH'] == 'armeabi':
|
||||
DEFINES['ARCH_ARMV6'] = True
|
||||
|
||||
if CONFIG['ENABLE_TESTS']:
|
||||
DIRS += ['tests/gtest']
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user