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