* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2011, 2013, 2014 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
#ifndef Element_h
#define Element_h
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSSelector.h"
#include "core/dom/Attribute.h"
-#include "core/dom/Document.h"
+#include "core/dom/ContainerNode.h"
#include "core/dom/ElementData.h"
#include "core/dom/SpaceSplitString.h"
#include "core/html/CollectionType.h"
-#include "core/page/FocusDirection.h"
-#include "core/rendering/RegionOversetState.h"
-#include "platform/scroll/ScrollTypes.h"
+#include "core/page/FocusType.h"
+#include "platform/heap/Handle.h"
-namespace WebCore {
+namespace blink {
class ActiveAnimations;
class Attr;
class Attribute;
+class CSSStyleDeclaration;
class ClientRect;
class ClientRectList;
+class CustomElementDefinition;
class DOMStringMap;
class DOMTokenList;
+class Document;
class ElementRareData;
class ElementShadow;
class ExceptionState;
class MutableStylePropertySet;
class PropertySetCSSStyleDeclaration;
class PseudoElement;
-class RenderRegion;
class ShadowRoot;
class StylePropertySet;
-enum AffectedSelectorType {
- AffectedSelectorChecked = 1,
- AffectedSelectorEnabled = 1 << 1,
- AffectedSelectorDisabled = 1 << 2,
- AffectedSelectorIndeterminate = 1 << 3,
- AffectedSelectorLink = 1 << 4,
- AffectedSelectorTarget = 1 << 5,
- AffectedSelectorVisited = 1 << 6
-};
-typedef int AffectedSelectorMask;
-
enum SpellcheckAttributeState {
SpellcheckAttributeTrue,
SpellcheckAttributeFalse,
SpellcheckAttributeDefault
};
+enum ElementFlags {
+ TabIndexWasSetExplicitly = 1 << 0,
+ StyleAffectedByEmpty = 1 << 1,
+ IsInCanvasSubtree = 1 << 2,
+ ContainsFullScreenElement = 1 << 3,
+ IsInTopLayer = 1 << 4,
+ HasPendingResources = 1 << 5,
+
+ NumberOfElementFlags = 6, // Required size of bitfield used to store the flags.
+};
+
class Element : public ContainerNode {
+ DEFINE_WRAPPERTYPEINFO();
public:
- static PassRefPtr<Element> create(const QualifiedName&, Document*);
+ static PassRefPtrWillBeRawPtr<Element> create(const QualifiedName&, Document*);
virtual ~Element();
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror);
DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel);
bool hasAttribute(const QualifiedName&) const;
// Typed getters and setters for language bindings.
int getIntegralAttribute(const QualifiedName& attributeName) const;
void setIntegralAttribute(const QualifiedName& attributeName, int value);
- unsigned getUnsignedIntegralAttribute(const QualifiedName& attributeName) const;
void setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value);
double getFloatingPointAttribute(const QualifiedName& attributeName, double fallbackValue = std::numeric_limits<double>::quiet_NaN()) const;
void setFloatingPointAttribute(const QualifiedName& attributeName, double value);
// attribute or one of the SVG animatable attributes.
bool fastHasAttribute(const QualifiedName&) const;
const AtomicString& fastGetAttribute(const QualifiedName&) const;
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
bool fastAttributeLookupAllowed(const QualifiedName&) const;
#endif
bool hasNamedNodeMap() const;
#endif
bool hasAttributes() const;
- // This variant will not update the potentially invalid attributes. To be used when not interested
- // in style attribute or one of the SVG animation attributes.
- bool hasAttributesWithoutUpdate() const;
bool hasAttribute(const AtomicString& name) const;
bool hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
// so this function is not suitable for non-style uses.
const AtomicString& idForStyleResolution() const;
- // Internal methods that assume the existence of attribute storage, one should use hasAttributes()
- // before calling them.
- size_t attributeCount() const;
- const Attribute* attributeItem(unsigned index) const;
- const Attribute* getAttributeItem(const QualifiedName&) const;
- size_t getAttributeItemIndex(const QualifiedName& name) const { return elementData()->getAttributeItemIndex(name); }
- size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->getAttributeItemIndex(name, shouldIgnoreAttributeCase); }
+ // This getter takes care of synchronizing all attributes before returning the
+ // AttributeCollection. If the Element has no attributes, an empty AttributeCollection
+ // will be returned. This is not a trivial getter and its return value should be cached
+ // for performance.
+ AttributeCollection attributes() const;
+ // This variant will not update the potentially invalid attributes. To be used when not interested
+ // in style attribute or one of the SVG animation attributes.
+ AttributeCollection attributesWithoutUpdate() const;
void scrollIntoView(bool alignToTop = true);
void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
- void scrollByLines(int lines);
- void scrollByPages(int pages);
-
int offsetLeft();
int offsetTop();
int offsetWidth();
int clientTop();
int clientWidth();
int clientHeight();
- virtual int scrollLeft();
- virtual int scrollTop();
- virtual void setScrollLeft(int);
- virtual void setScrollTop(int);
+ virtual double scrollLeft();
+ virtual double scrollTop();
+ virtual void setScrollLeft(double);
+ virtual void setScrollLeft(const Dictionary& scrollOptionsHorizontal, ExceptionState&);
+ virtual void setScrollTop(double);
+ virtual void setScrollTop(const Dictionary& scrollOptionsVertical, ExceptionState&);
virtual int scrollWidth();
virtual int scrollHeight();
IntRect boundsInRootViewSpace();
- PassRefPtr<ClientRectList> getClientRects();
- PassRefPtr<ClientRect> getBoundingClientRect();
+ PassRefPtrWillBeRawPtr<ClientRectList> getClientRects();
+ PassRefPtrWillBeRawPtr<ClientRect> getBoundingClientRect();
// Returns the absolute bounding box translated into screen coordinates:
IntRect screenRect() const;
void removeAttribute(const AtomicString& name);
void removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName);
- PassRefPtr<Attr> detachAttribute(size_t index);
+ PassRefPtrWillBeRawPtr<Attr> detachAttribute(size_t index);
- PassRefPtr<Attr> getAttributeNode(const AtomicString& name);
- PassRefPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
- PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionState&);
- PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionState&);
- PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> getAttributeNode(const AtomicString& name);
+ PassRefPtrWillBeRawPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
+ PassRefPtrWillBeRawPtr<Attr> setAttributeNode(Attr*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> setAttributeNodeNS(Attr*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> removeAttributeNode(Attr*, ExceptionState&);
- PassRefPtr<Attr> attrIfExists(const QualifiedName&);
- PassRefPtr<Attr> ensureAttr(const QualifiedName&);
+ PassRefPtrWillBeRawPtr<Attr> attrIfExists(const QualifiedName&);
+ PassRefPtrWillBeRawPtr<Attr> ensureAttr(const QualifiedName&);
- const Vector<RefPtr<Attr> >& attrNodeList();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >* attrNodeList();
CSSStyleDeclaration* style();
const QualifiedName& tagQName() const { return m_tagName; }
String tagName() const { return nodeName(); }
+
bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
+ bool hasTagName(const HTMLQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); }
+ bool hasTagName(const SVGQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); }
// Should be called only by Document::createElementNS to fix up m_tagName immediately after construction.
void setTagNameForCreateElementNS(const QualifiedName&);
// A fast function for checking the local name against another atomic string.
bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
- bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
virtual const AtomicString& localName() const OVERRIDE FINAL { return m_tagName.localName(); }
const AtomicString& prefix() const { return m_tagName.prefix(); }
virtual String nodeName() const OVERRIDE;
- PassRefPtr<Element> cloneElementWithChildren();
- PassRefPtr<Element> cloneElementWithoutChildren();
+ PassRefPtrWillBeRawPtr<Element> cloneElementWithChildren();
+ PassRefPtrWillBeRawPtr<Element> cloneElementWithoutChildren();
- void scheduleLayerUpdate();
+ void scheduleSVGFilterLayerUpdateHack();
void normalizeAttributes();
- String nodeNamePreservingCase() const;
void setBooleanAttribute(const QualifiedName& name, bool);
const StylePropertySet* inlineStyle() const { return elementData() ? elementData()->m_inlineStyle.get() : 0; }
bool setInlineStyleProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
- bool setInlineStyleProperty(CSSPropertyID, CSSPropertyID identifier, bool important = false);
- bool setInlineStyleProperty(CSSPropertyID, double value, CSSPrimitiveValue::UnitTypes, bool important = false);
+ bool setInlineStyleProperty(CSSPropertyID, double value, CSSPrimitiveValue::UnitType, bool important = false);
bool setInlineStyleProperty(CSSPropertyID, const String& value, bool important = false);
bool removeInlineStyleProperty(CSSPropertyID);
void removeAllInlineStyleProperties();
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) { }
// For exposing to DOM only.
- NamedNodeMap* attributes() const;
+ NamedNodeMap* attributesForBindings() const;
enum AttributeModificationReason {
ModifiedDirectly,
};
// This method is called whenever an attribute is added, changed or removed.
+ virtual void attributeWillChange(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue) { }
virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly);
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) { }
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&);
+
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const;
+ virtual const QualifiedName& subResourceAttributeName() const;
// Only called by the parser immediately after element construction.
void parserSetAttributes(const Vector<Attribute>&);
// Remove attributes that might introduce scripting from the vector leaving the element unchanged.
void stripScriptingAttributes(Vector<Attribute>&) const;
- const ElementData* elementData() const { return m_elementData.get(); }
- UniqueElementData* ensureUniqueElementData();
-
- void synchronizeAllAttributes() const;
+ bool sharesSameElementData(const Element& other) const { return elementData() == other.elementData(); }
// Clones attributes only.
void cloneAttributesFromElement(const Element&);
virtual RenderObject* createRenderer(RenderStyle*);
virtual bool rendererIsNeeded(const RenderStyle&);
void recalcStyle(StyleRecalcChange, Text* nextTextSibling = 0);
- void didAffectSelector(AffectedSelectorMask);
+ void pseudoStateChanged(CSSSelector::PseudoType);
void setAnimationStyleChange(bool);
void setNeedsAnimationStyleRecalc();
+ void setNeedsCompositingUpdate();
+
bool supportsStyleSharing() const;
ElementShadow* shadow() const;
ElementShadow& ensureShadow();
- PassRefPtr<ShadowRoot> createShadowRoot(ExceptionState&);
+ PassRefPtrWillBeRawPtr<ShadowRoot> createShadowRoot(ExceptionState&);
ShadowRoot* shadowRoot() const;
ShadowRoot* youngestShadowRoot() const;
bool hasAuthorShadowRoot() const { return shadowRoot(); }
- virtual void didAddShadowRoot(ShadowRoot&);
ShadowRoot* userAgentShadowRoot() const;
ShadowRoot& ensureUserAgentShadowRoot();
+ virtual void willAddFirstAuthorShadowRoot() { }
+
bool isInDescendantTreeOf(const Element* shadowHost) const;
RenderStyle* computedStyle(PseudoId = NOPSEUDO);
// Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
- bool styleAffectedByEmpty() const { return hasRareData() && rareDataStyleAffectedByEmpty(); }
- bool childrenAffectedByFocus() const { return hasRareData() && rareDataChildrenAffectedByFocus(); }
- bool childrenAffectedByHover() const { return hasRareData() && rareDataChildrenAffectedByHover(); }
- bool childrenAffectedByActive() const { return hasRareData() && rareDataChildrenAffectedByActive(); }
- bool childrenAffectedByDrag() const { return hasRareData() && rareDataChildrenAffectedByDrag(); }
- bool childrenAffectedByPositionalRules() const { return hasRareData() && (rareDataChildrenAffectedByForwardPositionalRules() || rareDataChildrenAffectedByBackwardPositionalRules()); }
- bool childrenAffectedByFirstChildRules() const { return hasRareData() && rareDataChildrenAffectedByFirstChildRules(); }
- bool childrenAffectedByLastChildRules() const { return hasRareData() && rareDataChildrenAffectedByLastChildRules(); }
- bool childrenAffectedByDirectAdjacentRules() const { return hasRareData() && rareDataChildrenAffectedByDirectAdjacentRules(); }
- bool childrenAffectedByForwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByForwardPositionalRules(); }
- bool childrenAffectedByBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByBackwardPositionalRules(); }
- unsigned childIndex() const { return hasRareData() ? rareDataChildIndex() : 0; }
-
- bool childrenSupportStyleSharing() const;
-
- void setStyleAffectedByEmpty();
- void setChildrenAffectedByFocus();
- void setChildrenAffectedByHover();
- void setChildrenAffectedByActive();
- void setChildrenAffectedByDrag();
- void setChildrenAffectedByFirstChildRules();
- void setChildrenAffectedByLastChildRules();
- void setChildrenAffectedByDirectAdjacentRules();
- void setChildrenAffectedByForwardPositionalRules();
- void setChildrenAffectedByBackwardPositionalRules();
- void setChildIndex(unsigned);
-
- void setIsInCanvasSubtree(bool);
- bool isInCanvasSubtree() const;
+ bool styleAffectedByEmpty() const { return hasElementFlag(StyleAffectedByEmpty); }
+ void setStyleAffectedByEmpty() { setElementFlag(StyleAffectedByEmpty); }
+
+ void setIsInCanvasSubtree(bool value) { setElementFlag(IsInCanvasSubtree, value); }
+ bool isInCanvasSubtree() const { return hasElementFlag(IsInCanvasSubtree); }
bool isUpgradedCustomElement() { return customElementState() == Upgraded; }
bool isUnresolvedCustomElement() { return customElementState() == WaitingForUpgrade; }
- void setIsInsideRegion(bool);
- bool isInsideRegion() const;
-
- void setRegionOversetState(RegionOversetState);
- RegionOversetState regionOversetState() const;
-
AtomicString computeInheritedLanguage() const;
Locale& locale() const;
virtual bool isURLAttribute(const Attribute&) const { return false; }
virtual bool isHTMLContentAttribute(const Attribute&) const { return false; }
+ virtual bool isLiveLink() const { return false; }
+ KURL hrefURL() const;
+
KURL getURLAttribute(const QualifiedName&) const;
KURL getNonEmptyURLAttribute(const QualifiedName&) const;
virtual const AtomicString imageSourceURL() const;
virtual Image* imageContents() { return 0; }
- virtual void focus(bool restorePreviousSelection = true, FocusDirection = FocusDirectionNone);
+ virtual void focus(bool restorePreviousSelection = true, FocusType = FocusTypeNone);
virtual void updateFocusAppearance(bool restorePreviousSelection);
virtual void blur();
// Whether this element can receive focus at all. Most elements are not
bool isFocusable() const;
virtual bool isKeyboardFocusable() const;
virtual bool isMouseFocusable() const;
- virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusDirection);
+ virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType);
virtual void dispatchBlurEvent(Element* newFocusedElement);
- void dispatchFocusInEvent(const AtomicString& eventType, Element* oldFocusedElement);
+ virtual void dispatchFocusInEvent(const AtomicString& eventType, Element* oldFocusedElement, FocusType);
void dispatchFocusOutEvent(const AtomicString& eventType, Element* newFocusedElement);
String innerText();
String outerHTML() const;
void setInnerHTML(const String&, ExceptionState&);
void setOuterHTML(const String&, ExceptionState&);
+
+ Element* insertAdjacentElement(const String& where, Element* newChild, ExceptionState&);
+ void insertAdjacentText(const String& where, const String& text, ExceptionState&);
void insertAdjacentHTML(const String& where, const String& html, ExceptionState&);
String textFromChildren();
virtual void didBecomeFullscreenElement() { }
virtual void willStopBeingFullscreenElement() { }
- // FIXME: Pick one name and remove the other method.
- bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
-
// Called by the parser when this element's close tag is reached,
// signaling that all child tags have been parsed and added.
// This is needed for <applet> and <object> elements, which can't lay themselves out
// but making parsing a special case in this respect should be avoided if possible.
virtual void finishParsingChildren();
- void beginParsingChildren() { setIsParsingChildrenFinished(false); }
+ void beginParsingChildren() { setIsFinishedParsingChildren(false); }
PseudoElement* pseudoElement(PseudoId) const;
RenderObject* pseudoElementRenderer(PseudoId) const;
bool matches(const String& selectors, ExceptionState&);
virtual bool shouldAppearIndeterminate() const { return false; }
- DOMTokenList* classList();
+ DOMTokenList& classList();
- DOMStringMap* dataset();
+ DOMStringMap& dataset();
- virtual bool isMediaElement() const { return false; }
-
-#if ENABLE(INPUT_SPEECH)
- virtual bool isInputFieldSpeechButtonElement() const { return false; }
-#endif
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
virtual bool isDateTimeEditElement() const { return false; }
virtual bool isDateTimeFieldElement() const { return false; }
virtual bool isValidFormControlElement() { return false; }
virtual bool isInRange() const { return false; }
virtual bool isOutOfRange() const { return false; }
- virtual bool isFrameElementBase() const { return false; }
- virtual bool isPasswordGeneratorButtonElement() const { return false; }
virtual bool isClearButtonElement() const { return false; }
virtual bool canContainRangeEndPoint() const OVERRIDE { return true; }
- virtual const AtomicString& formControlType() const { return nullAtom; }
-
- // FIXME: Only HTMLInputElement uses these, they don't need to be virtual.
- virtual bool wasChangedSinceLastFormControlChangeEvent() const { return false; }
- virtual void setChangedSinceLastFormControlChangeEvent(bool) { }
- virtual void dispatchFormControlChangeEvent() { }
-
// Used for disabled form elements; if true, prevents mouse events from being dispatched
// to event listeners, and prevents DOMActivate events from being sent at all.
virtual bool isDisabledFormControl() const { return false; }
- bool hasPendingResources() const;
- void setHasPendingResources();
- void clearHasPendingResources();
+ bool hasPendingResources() const { return hasElementFlag(HasPendingResources); }
+ void setHasPendingResources() { setElementFlag(HasPendingResources); }
+ void clearHasPendingResources() { clearElementFlag(HasPendingResources); }
virtual void buildPendingResource() { };
- enum {
- ALLOW_KEYBOARD_INPUT = 1 << 0,
- LEGACY_MOZILLA_REQUEST = 1 << 1,
- };
+ void setCustomElementDefinition(PassRefPtr<CustomElementDefinition>);
+ CustomElementDefinition* customElementDefinition() const;
- void webkitRequestFullScreen(unsigned short flags);
- bool containsFullScreenElement() const;
+ bool containsFullScreenElement() const { return hasElementFlag(ContainsFullScreenElement); }
void setContainsFullScreenElement(bool);
void setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool);
- // W3C API
- void webkitRequestFullscreen();
-
- bool isInTopLayer() const;
+ bool isInTopLayer() const { return hasElementFlag(IsInTopLayer); }
void setIsInTopLayer(bool);
- void webkitRequestPointerLock();
+ void requestPointerLock();
bool isSpellCheckingEnabled() const;
// FIXME: public for RenderTreeBuilder, we shouldn't expose this though.
PassRefPtr<RenderStyle> styleForRenderer();
- RenderRegion* renderRegion() const;
- const AtomicString& webkitRegionOverset() const;
- Vector<RefPtr<Range> > webkitGetRegionFlowRanges() const;
-
bool hasID() const;
bool hasClass() const;
const SpaceSplitString& classNames() const;
void setSavedLayerScrollOffset(const IntSize&);
ActiveAnimations* activeAnimations() const;
- ActiveAnimations* ensureActiveAnimations();
+ ActiveAnimations& ensureActiveAnimations();
bool hasActiveAnimations() const;
- InputMethodContext* inputMethodContext();
+ InputMethodContext& inputMethodContext();
bool hasInputMethodContext() const;
void setPrefix(const AtomicString&, ExceptionState&);
void synchronizeAttribute(const AtomicString& localName) const;
- MutableStylePropertySet* ensureMutableInlineStyle();
+ MutableStylePropertySet& ensureMutableInlineStyle();
void clearMutableInlineStyleIfEmpty();
+ void setTabIndex(int);
+ virtual short tabIndex() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ virtual v8::Handle<v8::Object> wrap(v8::Handle<v8::Object> creationContext, v8::Isolate*) OVERRIDE;
+
protected:
- Element(const QualifiedName& tagName, Document* document, ConstructionType type)
- : ContainerNode(document, type)
- , m_tagName(tagName)
- {
- ScriptWrappable::init(this);
- }
+ Element(const QualifiedName& tagName, Document*, ConstructionType);
+
+ const ElementData* elementData() const { return m_elementData.get(); }
+ UniqueElementData& ensureUniqueElementData();
void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, CSSValueID identifier);
- void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, double value, CSSPrimitiveValue::UnitTypes);
+ void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, double value, CSSPrimitiveValue::UnitType);
void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, const String& value);
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void removeAllEventListeners() OVERRIDE;
+ virtual void childrenChanged(const ChildrenChange&) OVERRIDE;
virtual void willRecalcStyle(StyleRecalcChange);
virtual void didRecalcStyle(StyleRecalcChange);
virtual bool shouldRegisterAsNamedItem() const { return false; }
virtual bool shouldRegisterAsExtraNamedItem() const { return false; }
+ bool supportsSpatialNavigationFocus() const;
+
void clearTabIndexExplicitlyIfNeeded();
void setTabIndexExplicitly(short);
- virtual short tabIndex() const OVERRIDE;
// Subclasses may override this method to affect focusability. Unlike
// supportsFocus, this method must be called on an up-to-date layout, so it
// may use the renderer to reason about focusability. This method cannot be
// moved to RenderObject because some focusable nodes don't have renderers,
// e.g., HTMLOptionElement.
virtual bool rendererIsFocusable() const;
- PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
- HTMLCollection* cachedHTMLCollection(CollectionType);
// classAttributeChanged() exists to share code between
// parseAttribute (called via setAttribute()) and
Node* insertAdjacent(const String& where, Node* newChild, ExceptionState&);
private:
+ bool hasElementFlag(ElementFlags mask) const { return hasRareData() && hasElementFlagInternal(mask); }
+ void setElementFlag(ElementFlags, bool value = true);
+ void clearElementFlag(ElementFlags);
+ bool hasElementFlagInternal(ElementFlags) const;
+
+ bool isElementNode() const WTF_DELETED_FUNCTION; // This will catch anyone doing an unnecessary check.
+ bool isDocumentFragment() const WTF_DELETED_FUNCTION; // This will catch anyone doing an unnecessary check.
+ bool isDocumentNode() const WTF_DELETED_FUNCTION; // This will catch anyone doing an unnecessary check.
+
void styleAttributeChanged(const AtomicString& newStyleString, AttributeModificationReason);
void updatePresentationAttributeStyle();
void setInlineStyleFromString(const AtomicString&);
StyleRecalcChange recalcOwnStyle(StyleRecalcChange);
- void recalcChildStyle(StyleRecalcChange);
- // FIXME: These methods should all be renamed to something better than "check",
- // since it's not clear that they alter the style bits of siblings and children.
- void checkForChildrenAdjacentRuleChanges();
- void checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta);
- inline void checkForEmptyStyleChange(RenderStyle*);
+ inline void checkForEmptyStyleChange();
void updatePseudoElement(PseudoId, StyleRecalcChange);
void didModifyAttribute(const QualifiedName&, const AtomicString&);
void didRemoveAttribute(const QualifiedName&);
+ void synchronizeAllAttributes() const;
void synchronizeAttribute(const QualifiedName&) const;
void updateId(const AtomicString& oldId, const AtomicString& newId);
void updateId(TreeScope&, const AtomicString& oldId, const AtomicString& newId);
void updateName(const AtomicString& oldName, const AtomicString& newName);
- void updateLabel(TreeScope&, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue);
-
- void scrollByUnits(int units, ScrollGranularity);
virtual NodeType nodeType() const OVERRIDE FINAL;
virtual bool childTypeAllowed(NodeType) const OVERRIDE FINAL;
void setAttributeInternal(size_t index, const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
- void addAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
+ void appendAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
void removeAttributeInternal(size_t index, SynchronizationOfLazyAttribute);
void attributeChangedFromParserOrByCloning(const QualifiedName&, const AtomicString&, AttributeModificationReason);
// cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
// are used instead.
- virtual PassRefPtr<Node> cloneNode(bool deep) OVERRIDE;
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren();
QualifiedName m_tagName;
- bool rareDataStyleAffectedByEmpty() const;
- bool rareDataChildrenAffectedByFocus() const;
- bool rareDataChildrenAffectedByHover() const;
- bool rareDataChildrenAffectedByActive() const;
- bool rareDataChildrenAffectedByDrag() const;
- bool rareDataChildrenAffectedByFirstChildRules() const;
- bool rareDataChildrenAffectedByLastChildRules() const;
- bool rareDataChildrenAffectedByDirectAdjacentRules() const;
- bool rareDataChildrenAffectedByForwardPositionalRules() const;
- bool rareDataChildrenAffectedByBackwardPositionalRules() const;
- unsigned rareDataChildIndex() const;
SpellcheckAttributeState spellcheckAttributeState() const;
void updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName);
void updateExtraNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName);
- void unregisterNamedFlowContentNode();
-
void createUniqueElementData();
bool shouldInvalidateDistributionWhenAttributeChanged(ElementShadow*, const QualifiedName&, const AtomicString&);
ElementRareData* elementRareData() const;
ElementRareData& ensureElementRareData();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >& ensureAttrNodeList();
+ void removeAttrNodeList();
void detachAllAttrNodesFromElement();
void detachAttrNodeFromElementWithValue(Attr*, const AtomicString& value);
void detachAttrNodeAtIndex(Attr*, size_t index);
bool isJavaScriptURLAttribute(const Attribute&) const;
- RefPtr<ElementData> m_elementData;
+ v8::Handle<v8::Object> wrapCustomElement(v8::Handle<v8::Object> creationContext, v8::Isolate*);
+
+ RefPtrWillBeMember<ElementData> m_elementData;
};
DEFINE_NODE_TYPE_CASTS(Element, isElementNode());
+template <typename T> bool isElementOfType(const Node&);
+template <> inline bool isElementOfType<const Element>(const Node& node) { return node.isElementNode(); }
+template <typename T> inline bool isElementOfType(const Element& element) { return isElementOfType<T>(static_cast<const Node&>(element)); }
+template <> inline bool isElementOfType<const Element>(const Element&) { return true; }
-inline bool isDisabledFormControl(const Node* node)
+// Type casting.
+template<typename T> inline T& toElement(Node& node)
{
- return node->isElementNode() && toElement(node)->isDisabledFormControl();
+ ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
+ return static_cast<T&>(node);
}
-
-inline bool Node::hasTagName(const QualifiedName& name) const
+template<typename T> inline T* toElement(Node* node)
{
- return isElementNode() && toElement(this)->hasTagName(name);
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
+ return static_cast<T*>(node);
}
-
-inline Element* Node::parentElement() const
+template<typename T> inline const T& toElement(const Node& node)
{
- ContainerNode* parent = parentNode();
- return parent && parent->isElementNode() ? toElement(parent) : 0;
+ ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
+ return static_cast<const T&>(node);
+}
+template<typename T> inline const T* toElement(const Node* node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
+ return static_cast<const T*>(node);
}
+template<typename T, typename U> inline T* toElement(const RefPtr<U>& node) { return toElement<T>(node.get()); }
-inline Element* Node::previousElementSibling() const
+inline bool isDisabledFormControl(const Node* node)
{
- Node* n = previousSibling();
- while (n && !n->isElementNode())
- n = n->previousSibling();
- return toElement(n);
+ return node->isElementNode() && toElement(node)->isDisabledFormControl();
}
-inline Element* Node::nextElementSibling() const
+inline Element* Node::parentElement() const
{
- Node* n = nextSibling();
- while (n && !n->isElementNode())
- n = n->nextSibling();
- return toElement(n);
+ ContainerNode* parent = parentNode();
+ return parent && parent->isElementNode() ? toElement(parent) : 0;
}
inline bool Element::fastHasAttribute(const QualifiedName& name) const
{
ASSERT(fastAttributeLookupAllowed(name));
- return elementData() && getAttributeItem(name);
+ return elementData() && elementData()->attributes().findIndex(name) != kNotFound;
}
inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name) const
{
ASSERT(fastAttributeLookupAllowed(name));
if (elementData()) {
- if (const Attribute* attribute = getAttributeItem(name))
+ if (const Attribute* attribute = elementData()->attributes().find(name))
return attribute->value();
}
return nullAtom;
}
-inline bool Element::hasAttributesWithoutUpdate() const
+inline AttributeCollection Element::attributes() const
{
- return elementData() && !elementData()->isEmpty();
+ if (!elementData())
+ return AttributeCollection();
+ synchronizeAllAttributes();
+ return elementData()->attributes();
+}
+
+inline AttributeCollection Element::attributesWithoutUpdate() const
+{
+ if (!elementData())
+ return AttributeCollection();
+ return elementData()->attributes();
+}
+
+inline bool Element::hasAttributes() const
+{
+ return !attributes().isEmpty();
}
inline const AtomicString& Element::idForStyleResolution() const
return fastGetAttribute(HTMLNames::classAttr);
}
-inline bool Element::shouldIgnoreAttributeCase() const
-{
- return isHTMLElement() && document().isHTMLDocument();
-}
-
inline void Element::setIdAttribute(const AtomicString& value)
{
setAttribute(HTMLNames::idAttr, value);
return elementData()->classNames();
}
-inline size_t Element::attributeCount() const
-{
- ASSERT(elementData());
- return elementData()->length();
-}
-
-inline const Attribute* Element::attributeItem(unsigned index) const
-{
- ASSERT(elementData());
- return elementData()->attributeItem(index);
-}
-
-inline const Attribute* Element::getAttributeItem(const QualifiedName& name) const
-{
- ASSERT(elementData());
- return elementData()->getAttributeItem(name);
-}
-
inline bool Element::hasID() const
{
return elementData() && elementData()->hasID();
return elementData() && elementData()->hasClass();
}
-inline UniqueElementData* Element::ensureUniqueElementData()
+inline UniqueElementData& Element::ensureUniqueElementData()
{
if (!elementData() || !elementData()->isUnique())
createUniqueElementData();
- return static_cast<UniqueElementData*>(m_elementData.get());
-}
-
-// Put here to make them inline.
-inline bool Node::hasID() const
-{
- return isElementNode() && toElement(this)->hasID();
-}
-
-inline bool Node::hasClass() const
-{
- return isElementNode() && toElement(this)->hasClass();
+ return toUniqueElementData(*m_elementData);
}
inline Node::InsertionNotificationRequest Node::insertedInto(ContainerNode* insertionPoint)
{
+ ASSERT(!childNeedsStyleInvalidation());
+ ASSERT(!needsStyleInvalidation());
ASSERT(insertionPoint->inDocument() || isContainerNode());
if (insertionPoint->inDocument())
setFlag(InDocumentFlag);
return element && element->shadow();
}
+inline bool isAtShadowBoundary(const Element* element)
+{
+ if (!element)
+ return false;
+ ContainerNode* parentNode = element->parentNode();
+ return parentNode && parentNode->isShadowRoot();
+}
+
+// These macros do the same as their NODE equivalents but additionally provide a template specialization
+// for isElementOfType<>() so that the Traversal<> API works for these Element types.
+#define DEFINE_ELEMENT_TYPE_CASTS(thisType, predicate) \
+ template <> inline bool isElementOfType<const thisType>(const Node& node) { return node.predicate; } \
+ DEFINE_NODE_TYPE_CASTS(thisType, predicate)
+
+#define DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
+ template <> inline bool isElementOfType<const thisType>(const Node& node) { return is##thisType(node); } \
+ DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType)
+
+#define DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(T) \
+ static PassRefPtrWillBeRawPtr<T> create(const QualifiedName&, Document&)
+#define DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(T) \
+ PassRefPtrWillBeRawPtr<T> T::create(const QualifiedName& tagName, Document& document) \
+ { \
+ return adoptRefWillBeNoop(new T(tagName, document)); \
+ }
+
} // namespace
-#endif
+#endif // Element_h