1bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)/* 2bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved. 3bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * 4bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 5bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * modification, are permitted provided that the following conditions are 6bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * met: 7bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * 8bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 9bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 10bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 11bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 12bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * in the documentation and/or other materials provided with the 13bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * distribution. 14bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 15bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 16bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * this software without specific prior written permission. 17bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * 18bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) */ 30bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 31bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "config.h" 32bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/dom/PresentationAttributeStyle.h" 33bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 34bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/css/StylePropertySet.h" 35bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/dom/Attribute.h" 36bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/dom/Element.h" 37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/html/HTMLInputElement.h" 385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "platform/Timer.h" 39bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "wtf/HashFunctions.h" 40bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "wtf/HashMap.h" 41bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "wtf/text/CString.h" 42bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 44bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 45bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)using namespace HTMLNames; 46bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 47bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)struct PresentationAttributeCacheKey { 48bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) PresentationAttributeCacheKey() : tagName(0) { } 49bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) StringImpl* tagName; 50bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) Vector<std::pair<StringImpl*, AtomicString>, 3> attributesAndValues; 51bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)}; 52bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 53bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)static bool operator!=(const PresentationAttributeCacheKey& a, const PresentationAttributeCacheKey& b) 54bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 55bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (a.tagName != b.tagName) 56bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return true; 57bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return a.attributesAndValues != b.attributesAndValues; 58bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 59bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 60197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstruct PresentationAttributeCacheEntry FINAL : public NoBaseWillBeGarbageCollectedFinalized<PresentationAttributeCacheEntry> { 61197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 62bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)public: 63197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch void trace(Visitor* visitor) { visitor->trace(value); } 64197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 65bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) PresentationAttributeCacheKey key; 66197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtrWillBeMember<StylePropertySet> value; 67bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)}; 68bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 69197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtypedef WillBeHeapHashMap<unsigned, OwnPtrWillBeMember<PresentationAttributeCacheEntry>, AlreadyHashed> PresentationAttributeCache; 70bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)static PresentationAttributeCache& presentationAttributeCache() 71bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 72197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<PresentationAttributeCache>, cache, (adoptPtrWillBeNoop(new PresentationAttributeCache()))); 73197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return *cache; 74bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 75bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 76bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)class PresentationAttributeCacheCleaner { 77bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) WTF_MAKE_NONCOPYABLE(PresentationAttributeCacheCleaner); WTF_MAKE_FAST_ALLOCATED; 78bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)public: 79bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) PresentationAttributeCacheCleaner() 80bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) : m_hitCount(0) 81bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) , m_cleanTimer(this, &PresentationAttributeCacheCleaner::cleanCache) 82bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) { 83bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 84bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 85bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) void didHitPresentationAttributeCache() 86bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) { 87bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (presentationAttributeCache().size() < minimumPresentationAttributeCacheSizeForCleaning) 88bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 89bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 90bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) m_hitCount++; 91bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 92bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (!m_cleanTimer.isActive()) 93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_cleanTimer.startOneShot(presentationAttributeCacheCleanTimeInSeconds, FROM_HERE); 94bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 95bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 96bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)private: 97bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) static const unsigned presentationAttributeCacheCleanTimeInSeconds = 60; 9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) static const unsigned minimumPresentationAttributeCacheSizeForCleaning = 100; 99bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) static const unsigned minimumPresentationAttributeCacheHitCountPerMinute = (100 * presentationAttributeCacheCleanTimeInSeconds) / 60; 100bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 101bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) void cleanCache(Timer<PresentationAttributeCacheCleaner>* timer) 102bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) { 103bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ASSERT_UNUSED(timer, timer == &m_cleanTimer); 104bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) unsigned hitCount = m_hitCount; 105bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) m_hitCount = 0; 106bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (hitCount > minimumPresentationAttributeCacheHitCountPerMinute) 107bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 108bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) presentationAttributeCache().clear(); 109bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 110bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 111bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) unsigned m_hitCount; 112bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) Timer<PresentationAttributeCacheCleaner> m_cleanTimer; 113bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)}; 114bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 115bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)static bool attributeNameSort(const pair<StringImpl*, AtomicString>& p1, const pair<StringImpl*, AtomicString>& p2) 116bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 117bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Sort based on the attribute name pointers. It doesn't matter what the order is as long as it is always the same. 118bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return p1.first < p2.first; 119bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 120bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 121bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)static void makePresentationAttributeCacheKey(Element& element, PresentationAttributeCacheKey& result) 122bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 123bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // FIXME: Enable for SVG. 124bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (!element.isHTMLElement()) 125bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 126bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Interpretation of the size attributes on <input> depends on the type attribute. 127d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isHTMLInputElement(element)) 128bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 129c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) AttributeCollection attributes = element.attributesWithoutUpdate(); 130e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) AttributeCollection::iterator end = attributes.end(); 131e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) { 132f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (!element.isPresentationAttribute(it->name())) 133bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) continue; 134f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (!it->namespaceURI().isNull()) 135bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 136bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // FIXME: Background URL may depend on the base URL and can't be shared. Disallow caching. 137f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (it->name() == backgroundAttr) 138bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 139f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) result.attributesAndValues.append(std::make_pair(it->localName().impl(), it->value())); 140bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 141bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (result.attributesAndValues.isEmpty()) 142bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 143bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Attribute order doesn't matter. Sort for easy equality comparison. 144bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) std::sort(result.attributesAndValues.begin(), result.attributesAndValues.end(), attributeNameSort); 145bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // The cache key is non-null when the tagName is set. 146bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) result.tagName = element.localName().impl(); 147bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 148bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 149bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)static unsigned computePresentationAttributeCacheHash(const PresentationAttributeCacheKey& key) 150bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 151bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (!key.tagName) 152bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return 0; 153bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ASSERT(key.attributesAndValues.size()); 154bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) unsigned attributeHash = StringHasher::hashMemory(key.attributesAndValues.data(), key.attributesAndValues.size() * sizeof(key.attributesAndValues[0])); 155bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return WTF::pairIntHash(key.tagName->existingHash(), attributeHash); 156bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 157bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 158197021e6b966cfb06891637935ef33fff06433d1Ben MurdochPassRefPtrWillBeRawPtr<StylePropertySet> computePresentationAttributeStyle(Element& element) 159bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 160bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) DEFINE_STATIC_LOCAL(PresentationAttributeCacheCleaner, cacheCleaner, ()); 161bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 162bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ASSERT(element.isStyledElement()); 163bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 164bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) PresentationAttributeCacheKey cacheKey; 165bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) makePresentationAttributeCacheKey(element, cacheKey); 166bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 167bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) unsigned cacheHash = computePresentationAttributeCacheHash(cacheKey); 168bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) PresentationAttributeCache::ValueType* cacheValue; 170bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (cacheHash) { 17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) cacheValue = presentationAttributeCache().add(cacheHash, nullptr).storedValue; 17209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (cacheValue->value && cacheValue->value->key != cacheKey) 173bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) cacheHash = 0; 174bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } else { 17509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) cacheValue = 0; 176bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 177bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 178197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtrWillBeRawPtr<StylePropertySet> style = nullptr; 17909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (cacheHash && cacheValue->value) { 18009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) style = cacheValue->value->value; 181bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) cacheCleaner.didHitPresentationAttributeCache(); 182bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } else { 183f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) style = MutableStylePropertySet::create(element.isSVGElement() ? SVGAttributeMode : HTMLAttributeMode); 184c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) AttributeCollection attributes = element.attributesWithoutUpdate(); 185e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) AttributeCollection::iterator end = attributes.end(); 186e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) 187f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) element.collectStyleForPresentationAttribute(it->name(), it->value(), toMutableStylePropertySet(style)); 188bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 189bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 19009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!cacheHash || cacheValue->value) 191bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return style.release(); 192bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 193197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtrWillBeRawPtr<PresentationAttributeCacheEntry> newEntry = adoptPtrWillBeNoop(new PresentationAttributeCacheEntry); 194bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) newEntry->key = cacheKey; 195bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) newEntry->value = style; 196bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 19751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) static const unsigned presentationAttributeCacheMaximumSize = 4096; 198bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (presentationAttributeCache().size() > presentationAttributeCacheMaximumSize) { 199bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // FIXME: Discarding the entire cache when it gets too big is probably bad 200bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // since it creates a perf "cliff". Perhaps we should use an LRU? 201bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) presentationAttributeCache().clear(); 202bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) presentationAttributeCache().set(cacheHash, newEntry.release()); 203bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } else { 20409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) cacheValue->value = newEntry.release(); 205bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 206bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 207bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return style.release(); 208bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 209bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 210c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 211