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