Commit 83b6d615 authored by esprehn@chromium.org's avatar esprehn@chromium.org

Move custom element definitions into ElementRareData

Instead of keeping a separate hash map we should just store this
information in the ElementRareData. This simplifies the implementation and
in practice will likely reduce memory usage since almost all custom elements
we've seen so far touch something that ends up making them use rare data like
childNodes, attributes, tabIndex, classList or dataset.

Review URL: https://codereview.chromium.org/177063004

git-svn-id: svn://svn.chromium.org/blink/trunk@169609 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 8aecf165
......@@ -102,7 +102,7 @@ v8::Handle<v8::Object> CustomElementWrapper<ElementType, WrapperType>::wrap(Pass
if (!perContextData)
return v8::Handle<v8::Object>();
CustomElementBinding* binding = perContextData->customElementBinding(CustomElement::definitionFor(element.get()));
CustomElementBinding* binding = perContextData->customElementBinding(element->customElementDefinition());
v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, binding->wrapperType(), element.get(), isolate);
if (wrapper.IsEmpty())
return v8::Handle<v8::Object>();
......
......@@ -1765,6 +1765,21 @@ void Element::setNeedsAnimationStyleRecalc()
setAnimationStyleChange(true);
}
void Element::setCustomElementDefinition(PassRefPtr<CustomElementDefinition> definition)
{
if (!hasRareData() && !definition)
return;
ASSERT(!customElementDefinition());
ensureElementRareData().setCustomElementDefinition(definition);
}
CustomElementDefinition* Element::customElementDefinition() const
{
if (hasRareData())
return elementRareData()->customElementDefinition();
return 0;
}
PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionState& exceptionState)
{
if (alwaysCreateUserAgentShadowRoot())
......
......@@ -43,6 +43,7 @@ class Attr;
class Attribute;
class ClientRect;
class ClientRectList;
class CustomElementDefinition;
class DOMStringMap;
class DOMTokenList;
class ElementRareData;
......@@ -521,6 +522,9 @@ public:
void clearHasPendingResources() { clearElementFlag(HasPendingResources); }
virtual void buildPendingResource() { };
void setCustomElementDefinition(PassRefPtr<CustomElementDefinition>);
CustomElementDefinition* customElementDefinition() const;
enum {
ALLOW_KEYBOARD_INPUT = 1 << 0,
LEGACY_MOZILLA_REQUEST = 1 << 1,
......
......@@ -40,7 +40,7 @@ struct SameSizeAsElementRareData : NodeRareData {
unsigned bitfields;
LayoutSize sizeForResizing;
IntSize scrollOffset;
void* pointers[11];
void* pointers[12];
};
CSSStyleDeclaration& ElementRareData::ensureInlineCSSStyleDeclaration(Element* ownerElement)
......
......@@ -27,6 +27,7 @@
#include "core/dom/NamedNodeMap.h"
#include "core/dom/NodeRareData.h"
#include "core/dom/PseudoElement.h"
#include "core/dom/custom/CustomElementDefinition.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/html/ClassList.h"
#include "core/html/ime/InputMethodContext.h"
......@@ -123,6 +124,9 @@ public:
bool hasPseudoElements() const;
void clearPseudoElements();
void setCustomElementDefinition(PassRefPtr<CustomElementDefinition> definition) { m_customElementDefinition = definition; }
CustomElementDefinition* customElementDefinition() const { return m_customElementDefinition.get(); }
private:
short m_tabindex;
unsigned short m_childIndex;
......@@ -130,7 +134,6 @@ private:
LayoutSize m_minimumSizeForResizing;
IntSize m_savedLayerScrollOffset;
RefPtr<RenderStyle> m_computedStyle;
OwnPtr<DatasetDOMStringMap> m_dataset;
OwnPtr<ClassList> m_classList;
......@@ -140,6 +143,9 @@ private:
OwnPtr<ActiveAnimations> m_activeAnimations;
OwnPtr<InlineCSSStyleDeclaration> m_cssomWrapper;
RefPtr<RenderStyle> m_computedStyle;
RefPtr<CustomElementDefinition> m_customElementDefinition;
RefPtr<PseudoElement> m_generatedBefore;
RefPtr<PseudoElement> m_generatedAfter;
RefPtr<PseudoElement> m_backdrop;
......
......@@ -97,23 +97,16 @@ void CustomElement::define(Element* element, PassRefPtr<CustomElementDefinition>
break;
case Element::WaitingForUpgrade:
definitions().add(element, definition);
element->setCustomElementDefinition(definition);
CustomElementScheduler::scheduleCreatedCallback(definition->callbacks(), element);
break;
}
}
CustomElementDefinition* CustomElement::definitionFor(Element* element)
{
CustomElementDefinition* definition = definitions().get(element);
ASSERT(definition);
return definition;
}
void CustomElement::attributeDidChange(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
{
ASSERT(element->customElementState() == Element::Upgraded);
CustomElementScheduler::scheduleAttributeChangedCallback(definitionFor(element)->callbacks(), element, name, oldValue, newValue);
CustomElementScheduler::scheduleAttributeChangedCallback(element->customElementDefinition()->callbacks(), element, name, oldValue, newValue);
}
void CustomElement::didEnterDocument(Element* element, const Document& document)
......@@ -121,7 +114,7 @@ void CustomElement::didEnterDocument(Element* element, const Document& document)
ASSERT(element->customElementState() == Element::Upgraded);
if (!document.domWindow())
return;
CustomElementScheduler::scheduleAttachedCallback(definitionFor(element)->callbacks(), element);
CustomElementScheduler::scheduleAttachedCallback(element->customElementDefinition()->callbacks(), element);
}
void CustomElement::didLeaveDocument(Element* element, const Document& document)
......@@ -129,7 +122,7 @@ void CustomElement::didLeaveDocument(Element* element, const Document& document)
ASSERT(element->customElementState() == Element::Upgraded);
if (!document.domWindow())
return;
CustomElementScheduler::scheduleDetachedCallback(definitionFor(element)->callbacks(), element);
CustomElementScheduler::scheduleDetachedCallback(element->customElementDefinition()->callbacks(), element);
}
void CustomElement::wasDestroyed(Element* element)
......@@ -141,23 +134,9 @@ void CustomElement::wasDestroyed(Element* element)
case Element::WaitingForUpgrade:
case Element::Upgraded:
definitions().remove(element);
CustomElementObserver::notifyElementWasDestroyed(element);
break;
}
}
void CustomElement::DefinitionMap::add(Element* element, PassRefPtr<CustomElementDefinition> definition)
{
ASSERT(definition.get());
DefinitionMap::ElementDefinitionHashMap::AddResult result = m_definitions.add(element, definition);
ASSERT_UNUSED(result, result.isNewEntry);
}
CustomElement::DefinitionMap& CustomElement::definitions()
{
DEFINE_STATIC_LOCAL(DefinitionMap, map, ());
return map;
}
} // namespace WebCore
......@@ -62,9 +62,6 @@ public:
// API for registration contexts
static void define(Element*, PassRefPtr<CustomElementDefinition>);
// API for wrapper creation, which uses a definition as a key
static CustomElementDefinition* definitionFor(Element*);
// API for Element to kick off changes
static void attributeDidChange(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
......@@ -76,24 +73,6 @@ private:
CustomElement();
static Vector<AtomicString>& embedderCustomElementNames();
// Maps resolved elements to their definitions
class DefinitionMap {
WTF_MAKE_NONCOPYABLE(DefinitionMap);
public:
DefinitionMap() { }
~DefinitionMap() { }
void add(Element*, PassRefPtr<CustomElementDefinition>);
void remove(Element* element) { m_definitions.remove(element); }
CustomElementDefinition* get(Element* element) const { return m_definitions.get(element); }
private:
typedef HashMap<Element*, RefPtr<CustomElementDefinition> > ElementDefinitionHashMap;
ElementDefinitionHashMap m_definitions;
};
static DefinitionMap& definitions();
};
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment