1 /* 2 * Copyright (C) 2012 Adobe Systems Incorporated. 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 9 * copyright notice, this list of conditions and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following 13 * disclaimer in the documentation and/or other materials 14 * provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 26 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include "config.h" 31 #include "core/dom/NamedFlowCollection.h" 32 33 #include "RuntimeEnabledFeatures.h" 34 #include "core/dom/DOMNamedFlowCollection.h" 35 #include "core/dom/Document.h" 36 #include "core/dom/NamedFlow.h" 37 #include "core/inspector/InspectorInstrumentation.h" 38 #include "wtf/text/StringHash.h" 39 #include "wtf/text/WTFString.h" 40 41 namespace WebCore { 42 43 NamedFlowCollection::NamedFlowCollection(Document* document) 44 : ContextLifecycleObserver(document) 45 { 46 ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled()); 47 } 48 49 Vector<RefPtr<NamedFlow> > NamedFlowCollection::namedFlows() 50 { 51 Vector<RefPtr<NamedFlow> > namedFlows; 52 53 for (NamedFlowSet::iterator it = m_namedFlows.begin(); it != m_namedFlows.end(); ++it) { 54 if ((*it)->flowState() == NamedFlow::FlowStateNull) 55 continue; 56 57 namedFlows.append(RefPtr<NamedFlow>(*it)); 58 } 59 60 return namedFlows; 61 } 62 63 NamedFlow* NamedFlowCollection::flowByName(const String& flowName) 64 { 65 NamedFlowSet::iterator it = m_namedFlows.find<String, NamedFlowHashTranslator>(flowName); 66 if (it == m_namedFlows.end() || (*it)->flowState() == NamedFlow::FlowStateNull) 67 return 0; 68 69 return *it; 70 } 71 72 PassRefPtr<NamedFlow> NamedFlowCollection::ensureFlowWithName(const String& flowName) 73 { 74 NamedFlowSet::iterator it = m_namedFlows.find<String, NamedFlowHashTranslator>(flowName); 75 if (it != m_namedFlows.end()) { 76 NamedFlow* namedFlow = *it; 77 ASSERT(namedFlow->flowState() == NamedFlow::FlowStateNull); 78 79 return namedFlow; 80 } 81 82 RefPtr<NamedFlow> newFlow = NamedFlow::create(this, flowName); 83 m_namedFlows.add(newFlow.get()); 84 85 InspectorInstrumentation::didCreateNamedFlow(document(), newFlow.get()); 86 87 return newFlow.release(); 88 } 89 90 void NamedFlowCollection::discardNamedFlow(NamedFlow* namedFlow) 91 { 92 // The document is not valid anymore so the collection will be destroyed anyway. 93 if (!document()) 94 return; 95 96 ASSERT(namedFlow->flowState() == NamedFlow::FlowStateNull); 97 ASSERT(m_namedFlows.contains(namedFlow)); 98 99 InspectorInstrumentation::willRemoveNamedFlow(document(), namedFlow); 100 101 m_namedFlows.remove(namedFlow); 102 } 103 104 Document* NamedFlowCollection::document() const 105 { 106 ScriptExecutionContext* context = ContextLifecycleObserver::scriptExecutionContext(); 107 return toDocument(context); 108 } 109 110 PassRefPtr<DOMNamedFlowCollection> NamedFlowCollection::createCSSOMSnapshot() 111 { 112 Vector<NamedFlow*> createdFlows; 113 for (NamedFlowSet::iterator it = m_namedFlows.begin(); it != m_namedFlows.end(); ++it) 114 if ((*it)->flowState() == NamedFlow::FlowStateCreated) 115 createdFlows.append(*it); 116 return DOMNamedFlowCollection::create(createdFlows); 117 } 118 119 // The HashFunctions object used by the HashSet to compare between NamedFlows. 120 // It is safe to set safeToCompareToEmptyOrDeleted because the HashSet will never contain null pointers or deleted values. 121 struct NamedFlowCollection::NamedFlowHashFunctions { 122 static unsigned hash(NamedFlow* key) { return DefaultHash<String>::Hash::hash(key->name()); } 123 static bool equal(NamedFlow* a, NamedFlow* b) { return a->name() == b->name(); } 124 static const bool safeToCompareToEmptyOrDeleted = true; 125 }; 126 127 // The HashTranslator is used to lookup a NamedFlow in the set using a name. 128 struct NamedFlowCollection::NamedFlowHashTranslator { 129 static unsigned hash(const String& key) { return DefaultHash<String>::Hash::hash(key); } 130 static bool equal(NamedFlow* a, const String& b) { return a->name() == b; } 131 }; 132 133 } // namespace WebCore 134