Home | History | Annotate | Download | only in custom
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer
     12  *    in the documentation and/or other materials provided with the
     13  *    distribution.
     14  * 3. Neither the name of Google Inc. nor the names of its contributors
     15  *    may be used to endorse or promote products derived from this
     16  *    software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "core/dom/custom/CustomElement.h"
     33 
     34 #include "core/HTMLNames.h"
     35 #include "core/MathMLNames.h"
     36 #include "core/SVGNames.h"
     37 #include "core/dom/Document.h"
     38 #include "core/dom/Element.h"
     39 #include "core/dom/custom/CustomElementObserver.h"
     40 #include "core/dom/custom/CustomElementScheduler.h"
     41 
     42 namespace WebCore {
     43 
     44 CustomElementMicrotaskImportStep* CustomElement::didCreateImport(HTMLImportChild* import)
     45 {
     46     return CustomElementScheduler::scheduleImport(import);
     47 }
     48 
     49 Vector<AtomicString>& CustomElement::embedderCustomElementNames()
     50 {
     51     DEFINE_STATIC_LOCAL(Vector<AtomicString>, names, ());
     52     return names;
     53 }
     54 
     55 void CustomElement::addEmbedderCustomElementName(const AtomicString& name)
     56 {
     57     AtomicString lower = name.lower();
     58     if (isValidName(lower, EmbedderNames))
     59         return;
     60     embedderCustomElementNames().append(lower);
     61 }
     62 
     63 bool CustomElement::isValidName(const AtomicString& name, NameSet validNames)
     64 {
     65     if ((validNames & EmbedderNames) && kNotFound != embedderCustomElementNames().find(name))
     66         return Document::isValidName(name);
     67 
     68     if ((validNames & StandardNames) && kNotFound != name.find('-')) {
     69         DEFINE_STATIC_LOCAL(Vector<AtomicString>, reservedNames, ());
     70         if (reservedNames.isEmpty()) {
     71             reservedNames.append(MathMLNames::annotation_xmlTag.localName());
     72 #if ENABLE(SVG_FONTS)
     73             reservedNames.append(SVGNames::font_faceTag.localName());
     74             reservedNames.append(SVGNames::font_face_srcTag.localName());
     75             reservedNames.append(SVGNames::font_face_uriTag.localName());
     76             reservedNames.append(SVGNames::font_face_formatTag.localName());
     77             reservedNames.append(SVGNames::font_face_nameTag.localName());
     78             reservedNames.append(SVGNames::missing_glyphTag.localName());
     79 #endif
     80         }
     81 
     82         if (kNotFound == reservedNames.find(name))
     83             return Document::isValidName(name.string());
     84     }
     85 
     86     return false;
     87 }
     88 
     89 void CustomElement::define(Element* element, PassRefPtr<CustomElementDefinition> passDefinition)
     90 {
     91     RefPtr<CustomElementDefinition> definition(passDefinition);
     92 
     93     switch (element->customElementState()) {
     94     case Element::NotCustomElement:
     95     case Element::Upgraded:
     96         ASSERT_NOT_REACHED();
     97         break;
     98 
     99     case Element::WaitingForUpgrade:
    100         element->setCustomElementDefinition(definition);
    101         CustomElementScheduler::scheduleCallback(definition->callbacks(), element, CustomElementLifecycleCallbacks::Created);
    102         break;
    103     }
    104 }
    105 
    106 void CustomElement::attributeDidChange(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
    107 {
    108     ASSERT(element->customElementState() == Element::Upgraded);
    109     CustomElementScheduler::scheduleAttributeChangedCallback(element->customElementDefinition()->callbacks(), element, name, oldValue, newValue);
    110 }
    111 
    112 void CustomElement::didEnterDocument(Element* element, const Document& document)
    113 {
    114     ASSERT(element->customElementState() == Element::Upgraded);
    115     if (!document.domWindow())
    116         return;
    117     CustomElementScheduler::scheduleCallback(element->customElementDefinition()->callbacks(), element, CustomElementLifecycleCallbacks::Attached);
    118 }
    119 
    120 void CustomElement::didLeaveDocument(Element* element, const Document& document)
    121 {
    122     ASSERT(element->customElementState() == Element::Upgraded);
    123     if (!document.domWindow())
    124         return;
    125     CustomElementScheduler::scheduleCallback(element->customElementDefinition()->callbacks(), element, CustomElementLifecycleCallbacks::Detached);
    126 }
    127 
    128 void CustomElement::wasDestroyed(Element* element)
    129 {
    130     switch (element->customElementState()) {
    131     case Element::NotCustomElement:
    132         ASSERT_NOT_REACHED();
    133         break;
    134 
    135     case Element::WaitingForUpgrade:
    136     case Element::Upgraded:
    137         CustomElementObserver::notifyElementWasDestroyed(element);
    138         break;
    139     }
    140 }
    141 
    142 } // namespace WebCore
    143