183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch/*
283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * Copyright (C) 2013 Google Inc. All rights reserved.
383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch *
483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * Redistribution and use in source and binary forms, with or without
583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * modification, are permitted provided that the following conditions
683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * are met:
783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch *
883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * 1. Redistributions of source code must retain the above copyright
983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch *    notice, this list of conditions and the following disclaimer.
1083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright
1183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch *    notice, this list of conditions and the following disclaimer
1283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch *    in the documentation and/or other materials provided with the
1383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch *    distribution.
1483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * 3. Neither the name of Google Inc. nor the names of its contributors
1583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch *    may be used to endorse or promote products derived from this
1683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch *    software without specific prior written permission.
1783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch *
1883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch */
3083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
3183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch#include "config.h"
321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/custom/CustomElement.h"
3383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
341fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch#include "HTMLNames.h"
351fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch#include "MathMLNames.h"
36e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "RuntimeEnabledFeatures.h"
371fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch#include "SVGNames.h"
3883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch#include "core/dom/Element.h"
391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/custom/CustomElementCallbackScheduler.h"
401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/custom/CustomElementObserver.h"
4183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
4283750176c3ee2cea66c8a9751271026a5901be3aBen Murdochnamespace WebCore {
4383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
44e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)Vector<AtomicString>& CustomElement::embedderCustomElementNames()
451fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
46e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    DEFINE_STATIC_LOCAL(Vector<AtomicString>, names, ());
47e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return names;
481fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
491fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch
50e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void CustomElement::addEmbedderCustomElementName(const AtomicString& name)
511fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
52e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    AtomicString lower = name.lower();
53e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (isValidName(lower, EmbedderNames))
541fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        return;
55e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    embedderCustomElementNames().append(lower);
561fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
571fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch
58e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)static CustomElement::NameSet enabledNameSet()
591fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
60e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return CustomElement::NameSet((RuntimeEnabledFeatures::customElementsEnabled() ? CustomElement::StandardNames : 0) | (RuntimeEnabledFeatures::embedderCustomElementsEnabled() ? CustomElement::EmbedderNames : 0));
611fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
621fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch
63e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)bool CustomElement::isValidName(const AtomicString& name, NameSet validNames)
641fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
65e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    validNames = NameSet(validNames & enabledNameSet());
66e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
6706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if ((validNames & EmbedderNames) && kNotFound != embedderCustomElementNames().find(name))
68e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        return Document::isValidName(name);
69e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
7006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if ((validNames & StandardNames) && kNotFound != name.find('-')) {
71e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        DEFINE_STATIC_LOCAL(Vector<AtomicString>, reservedNames, ());
72e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (reservedNames.isEmpty()) {
73e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            reservedNames.append(MathMLNames::annotation_xmlTag.localName());
74f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            // In principle, "color-profile" should exist in the SVGNames
75f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            // namespace, but we don't implement the color-profile element.
76f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            reservedNames.append("color-profile");
77e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            reservedNames.append(SVGNames::font_faceTag.localName());
78e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            reservedNames.append(SVGNames::font_face_srcTag.localName());
79e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            reservedNames.append(SVGNames::font_face_uriTag.localName());
80e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            reservedNames.append(SVGNames::font_face_formatTag.localName());
81e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            reservedNames.append(SVGNames::font_face_nameTag.localName());
82e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            reservedNames.append(SVGNames::missing_glyphTag.localName());
83e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
84e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
8506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (kNotFound == reservedNames.find(name))
86e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            return Document::isValidName(name.string());
87e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
88e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
89e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return false;
901fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
911fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch
9283750176c3ee2cea66c8a9751271026a5901be3aBen Murdochvoid CustomElement::define(Element* element, PassRefPtr<CustomElementDefinition> passDefinition)
9383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch{
9483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    RefPtr<CustomElementDefinition> definition(passDefinition);
95e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
96e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    switch (element->customElementState()) {
97e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    case Element::NotCustomElement:
98e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    case Element::Upgraded:
99e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        ASSERT_NOT_REACHED();
100e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        break;
101e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
102e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    case Element::WaitingForUpgrade:
103e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        definitions().add(element, definition);
104e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        CustomElementCallbackScheduler::scheduleCreatedCallback(definition->callbacks(), element);
105e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        break;
106e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
10783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch}
10883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
10902772c6a72f1ee0b226341a4f4439970c29fc861Ben MurdochCustomElementDefinition* CustomElement::definitionFor(Element* element)
11002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{
111e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    CustomElementDefinition* definition = definitions().get(element);
112e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT(definition);
113e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return definition;
114e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
115e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
11683750176c3ee2cea66c8a9751271026a5901be3aBen Murdochvoid CustomElement::attributeDidChange(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
11783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch{
11883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    ASSERT(element->customElementState() == Element::Upgraded);
119e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    CustomElementCallbackScheduler::scheduleAttributeChangedCallback(definitionFor(element)->callbacks(), element, name, oldValue, newValue);
12083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch}
12183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
1228abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)void CustomElement::didEnterDocument(Element* element, const Document& document)
12383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch{
12483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    ASSERT(element->customElementState() == Element::Upgraded);
125bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (!document.domWindow())
126fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch        return;
1279243a84568938a3b2704146d90a71e1405b822e4Torne (Richard Coles)    CustomElementCallbackScheduler::scheduleAttachedCallback(definitionFor(element)->callbacks(), element);
12883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch}
12983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
1308abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)void CustomElement::didLeaveDocument(Element* element, const Document& document)
13183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch{
13283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    ASSERT(element->customElementState() == Element::Upgraded);
133bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (!document.domWindow())
134fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch        return;
1359243a84568938a3b2704146d90a71e1405b822e4Torne (Richard Coles)    CustomElementCallbackScheduler::scheduleDetachedCallback(definitionFor(element)->callbacks(), element);
13683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch}
13783750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
13883750176c3ee2cea66c8a9751271026a5901be3aBen Murdochvoid CustomElement::wasDestroyed(Element* element)
13983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch{
14002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    switch (element->customElementState()) {
14102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    case Element::NotCustomElement:
14202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        ASSERT_NOT_REACHED();
14302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        break;
14402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
145e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    case Element::WaitingForUpgrade:
14602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    case Element::Upgraded:
14702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        definitions().remove(element);
148e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        CustomElementObserver::notifyElementWasDestroyed(element);
14902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        break;
15002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    }
15183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch}
15283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
15383750176c3ee2cea66c8a9751271026a5901be3aBen Murdochvoid CustomElement::DefinitionMap::add(Element* element, PassRefPtr<CustomElementDefinition> definition)
15483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch{
15583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    ASSERT(definition.get());
15683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    DefinitionMap::ElementDefinitionHashMap::AddResult result = m_definitions.add(element, definition);
157f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    ASSERT_UNUSED(result, result.isNewEntry);
15883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch}
15983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
16083750176c3ee2cea66c8a9751271026a5901be3aBen MurdochCustomElement::DefinitionMap& CustomElement::definitions()
16183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch{
16202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    DEFINE_STATIC_LOCAL(DefinitionMap, map, ());
16302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    return map;
16483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch}
16583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
16683750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch} // namespace WebCore
167