Example #1
0
void StyledElement::rebuildPresentationAttributeStyle()
{
    PresentationAttributeCacheKey cacheKey;
    makePresentationAttributeCacheKey(cacheKey);

    unsigned cacheHash = computePresentationAttributeCacheHash(cacheKey);

    PresentationAttributeCache::iterator cacheIterator;
    if (cacheHash) {
        cacheIterator = presentationAttributeCache().add(cacheHash, nullptr).iterator;
        if (cacheIterator->value && cacheIterator->value->key != cacheKey)
            cacheHash = 0;
    } else
        cacheIterator = presentationAttributeCache().end();

    RefPtr<StyleProperties> style;
    if (cacheHash && cacheIterator->value) {
        style = cacheIterator->value->value;
        presentationAttributeCacheCleaner().didHitPresentationAttributeCache();
    } else {
        style = MutableStyleProperties::create(isSVGElement() ? SVGAttributeMode : CSSQuirksMode);
        for (const Attribute& attribute : attributesIterator())
            collectStyleForPresentationAttribute(attribute.name(), attribute.value(), static_cast<MutableStyleProperties&>(*style));
    }

    // ShareableElementData doesn't store presentation attribute style, so make sure we have a UniqueElementData.
    UniqueElementData& elementData = ensureUniqueElementData();

    elementData.setPresentationAttributeStyleIsDirty(false);
    elementData.m_presentationAttributeStyle = style->isEmpty() ? 0 : style;

    if (!cacheHash || cacheIterator->value)
        return;

    std::unique_ptr<PresentationAttributeCacheEntry> newEntry = std::make_unique<PresentationAttributeCacheEntry>();
    newEntry->key = cacheKey;
    newEntry->value = style.release();

    static const int presentationAttributeCacheMaximumSize = 4096;
    if (presentationAttributeCache().size() > presentationAttributeCacheMaximumSize) {
        // Start building from scratch if the cache ever gets big.
        presentationAttributeCache().clear();
        presentationAttributeCache().set(cacheHash, WTF::move(newEntry));
    } else
        cacheIterator->value = WTF::move(newEntry);
}
  DCHECK(key.attributesAndValues.size());
  unsigned attributeHash = StringHasher::hashMemory(
      key.attributesAndValues.data(),
      key.attributesAndValues.size() * sizeof(key.attributesAndValues[0]));
  return WTF::hashInts(key.tagName->existingHash(), attributeHash);
}

StylePropertySet* computePresentationAttributeStyle(Element& element) {
  DEFINE_STATIC_LOCAL(PresentationAttributeCacheCleaner, cacheCleaner, ());

  DCHECK(element.isStyledElement());

  PresentationAttributeCacheKey cacheKey;
  makePresentationAttributeCacheKey(element, cacheKey);

  unsigned cacheHash = computePresentationAttributeCacheHash(cacheKey);

  PresentationAttributeCache::ValueType* cacheValue;
  if (cacheHash) {
    cacheValue =
        presentationAttributeCache().add(cacheHash, nullptr).storedValue;
    if (cacheValue->value && cacheValue->value->key != cacheKey)
      cacheHash = 0;
  } else {
    cacheValue = nullptr;
  }

  StylePropertySet* style = nullptr;
  if (cacheHash && cacheValue->value) {
    style = cacheValue->value->value;
    cacheCleaner.didHitPresentationAttributeCache();