1/* 2 * Copyright (C) 2011 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 are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Neither the name of Google Inc. nor the names of its 11 * contributors may be used to endorse or promote products derived from 12 * this software without specific prior written permission. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28#include "ShadowRoot.h" 29 30#include "ElementTraversal.h" 31#include "InsertionPoint.h" 32#include "RenderElement.h" 33#include "RuntimeEnabledFeatures.h" 34#include "StyleResolver.h" 35#include "markup.h" 36 37namespace WebCore { 38 39struct SameSizeAsShadowRoot : public DocumentFragment, public TreeScope { 40 unsigned countersAndFlags[1]; 41 ContentDistributor distributor; 42 void* host; 43}; 44 45COMPILE_ASSERT(sizeof(ShadowRoot) == sizeof(SameSizeAsShadowRoot), shadowroot_should_stay_small); 46 47enum ShadowRootUsageOriginType { 48 ShadowRootUsageOriginWeb = 0, 49 ShadowRootUsageOriginNotWeb, 50 ShadowRootUsageOriginMax 51}; 52 53ShadowRoot::ShadowRoot(Document& document, ShadowRootType type) 54 : DocumentFragment(document, CreateShadowRoot) 55 , TreeScope(*this, document) 56 , m_resetStyleInheritance(false) 57 , m_type(type) 58 , m_hostElement(0) 59{ 60} 61 62ShadowRoot::~ShadowRoot() 63{ 64 // We cannot let ContainerNode destructor call willBeDeletedFrom() 65 // for this ShadowRoot instance because TreeScope destructor 66 // clears Node::m_treeScope thus ContainerNode is no longer able 67 // to access it Document reference after that. 68 willBeDeletedFrom(document()); 69 70 // We must remove all of our children first before the TreeScope destructor 71 // runs so we don't go through TreeScopeAdopter for each child with a 72 // destructed tree scope in each descendant. 73 removeDetachedChildren(); 74} 75 76PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionCode& ec) 77{ 78 ec = DATA_CLONE_ERR; 79 return 0; 80} 81 82String ShadowRoot::innerHTML() const 83{ 84 return createMarkup(*this, ChildrenOnly); 85} 86 87void ShadowRoot::setInnerHTML(const String& markup, ExceptionCode& ec) 88{ 89 if (isOrphan()) { 90 ec = INVALID_ACCESS_ERR; 91 return; 92 } 93 94 if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, hostElement(), AllowScriptingContent, ec)) 95 replaceChildrenWithFragment(*this, fragment.release(), ec); 96} 97 98bool ShadowRoot::childTypeAllowed(NodeType type) const 99{ 100 switch (type) { 101 case ELEMENT_NODE: 102 case PROCESSING_INSTRUCTION_NODE: 103 case COMMENT_NODE: 104 case TEXT_NODE: 105 case CDATA_SECTION_NODE: 106 case ENTITY_REFERENCE_NODE: 107 return true; 108 default: 109 return false; 110 } 111} 112 113void ShadowRoot::setResetStyleInheritance(bool value) 114{ 115 if (isOrphan()) 116 return; 117 118 if (value != m_resetStyleInheritance) { 119 m_resetStyleInheritance = value; 120 if (hostElement()) 121 setNeedsStyleRecalc(); 122 } 123} 124 125void ShadowRoot::childrenChanged(const ChildChange& change) 126{ 127 if (isOrphan()) 128 return; 129 130 ContainerNode::childrenChanged(change); 131 invalidateDistribution(); 132} 133 134void ShadowRoot::removeAllEventListeners() 135{ 136 DocumentFragment::removeAllEventListeners(); 137 for (Node* node = firstChild(); node; node = NodeTraversal::next(node)) 138 node->removeAllEventListeners(); 139} 140 141} 142