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/CustomElementMicrotaskRunQueue.h"
     40 #include "core/dom/custom/CustomElementObserver.h"
     41 #include "core/dom/custom/CustomElementScheduler.h"
     42 
     43 namespace blink {
     44 
     45 CustomElementMicrotaskImportStep* CustomElement::didCreateImport(HTMLImportChild* import)
     46 {
     47     return CustomElementScheduler::scheduleImport(import);
     48 }
     49 
     50 void CustomElement::didFinishLoadingImport(Document& master)
     51 {
     52     master.customElementMicrotaskRunQueue()->requestDispatchIfNeeded();
     53 }
     54 
     55 Vector<AtomicString>& CustomElement::embedderCustomElementNames()
     56 {
     57     DEFINE_STATIC_LOCAL(Vector<AtomicString>, names, ());
     58     return names;
     59 }
     60 
     61 void CustomElement::addEmbedderCustomElementName(const AtomicString& name)
     62 {
     63     AtomicString lower = name.lower();
     64     if (isValidName(lower, EmbedderNames))
     65         return;
     66     embedderCustomElementNames().append(lower);
     67 }
     68 
     69 bool CustomElement::isValidName(const AtomicString& name, NameSet validNames)
     70 {
     71     if ((validNames & EmbedderNames) && kNotFound != embedderCustomElementNames().find(name))
     72         return Document::isValidName(name);
     73 
     74     if ((validNames & StandardNames) && kNotFound != name.find('-')) {
     75         DEFINE_STATIC_LOCAL(Vector<AtomicString>, reservedNames, ());
     76         if (reservedNames.isEmpty()) {
     77             reservedNames.append(MathMLNames::annotation_xmlTag.localName());
     78 #if ENABLE(SVG_FONTS)
     79             reservedNames.append(SVGNames::font_faceTag.localName());
     80             reservedNames.append(SVGNames::font_face_srcTag.localName());
     81             reservedNames.append(SVGNames::font_face_uriTag.localName());
     82             reservedNames.append(SVGNames::font_face_formatTag.localName());
     83             reservedNames.append(SVGNames::font_face_nameTag.localName());
     84             reservedNames.append(SVGNames::missing_glyphTag.localName());
     85 #endif
     86         }
     87 
     88         if (kNotFound == reservedNames.find(name))
     89             return Document::isValidName(name.string());
     90     }
     91 
     92     return false;
     93 }
     94 
     95 void CustomElement::define(Element* element, PassRefPtr<CustomElementDefinition> passDefinition)
     96 {
     97     RefPtr<CustomElementDefinition> definition(passDefinition);
     98 
     99     switch (element->customElementState()) {
    100     case Element::NotCustomElement:
    101     case Element::Upgraded:
    102         ASSERT_NOT_REACHED();
    103         break;
    104 
    105     case Element::WaitingForUpgrade:
    106         element->setCustomElementDefinition(definition);
    107         CustomElementScheduler::scheduleCallback(definition->callbacks(), element, CustomElementLifecycleCallbacks::CreatedCallback);
    108         break;
    109     }
    110 }
    111 
    112 void CustomElement::attributeDidChange(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
    113 {
    114     ASSERT(element->customElementState() == Element::Upgraded);
    115     CustomElementScheduler::scheduleAttributeChangedCallback(element->customElementDefinition()->callbacks(), element, name, oldValue, newValue);
    116 }
    117 
    118 void CustomElement::didAttach(Element* element, const Document& document)
    119 {
    120     ASSERT(element->customElementState() == Element::Upgraded);
    121     if (!document.domWindow())
    122         return;
    123     CustomElementScheduler::scheduleCallback(element->customElementDefinition()->callbacks(), element, CustomElementLifecycleCallbacks::AttachedCallback);
    124 }
    125 
    126 void CustomElement::didDetach(Element* element, const Document& document)
    127 {
    128     ASSERT(element->customElementState() == Element::Upgraded);
    129     if (!document.domWindow())
    130         return;
    131     CustomElementScheduler::scheduleCallback(element->customElementDefinition()->callbacks(), element, CustomElementLifecycleCallbacks::DetachedCallback);
    132 }
    133 
    134 void CustomElement::wasDestroyed(Element* element)
    135 {
    136     switch (element->customElementState()) {
    137     case Element::NotCustomElement:
    138         ASSERT_NOT_REACHED();
    139         break;
    140 
    141     case Element::WaitingForUpgrade:
    142     case Element::Upgraded:
    143         CustomElementObserver::notifyElementWasDestroyed(element);
    144         break;
    145     }
    146 }
    147 
    148 } // namespace blink
    149