void StyledElement::makePresentationAttributeCacheKey(PresentationAttributeCacheKey& result) const { // FIXME: Enable for SVG. if (namespaceURI() != xhtmlNamespaceURI) return; // Interpretation of the size attributes on <input> depends on the type attribute. if (hasTagName(inputTag)) return; for (const Attribute& attribute : attributesIterator()) { if (!isPresentationAttribute(attribute.name())) continue; if (!attribute.namespaceURI().isNull()) return; // FIXME: Background URL may depend on the base URL and can't be shared. Disallow caching. if (attribute.name() == backgroundAttr) return; result.attributesAndValues.append(std::make_pair(attribute.localName().impl(), attribute.value())); } if (result.attributesAndValues.isEmpty()) return; // Attribute order doesn't matter. Sort for easy equality comparison. std::sort(result.attributesAndValues.begin(), result.attributesAndValues.end(), attributeNameSort); // The cache key is non-null when the tagName is set. result.tagName = localName().impl(); }
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); }
// FIXME: This function should not deal with url or serviceType! void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType) { HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames; String urlParameter; // Scan the PARAM children and store their name/value pairs. // Get the URL and type from the params if we don't already have them. for (auto& param : childrenOfType<HTMLParamElement>(*this)) { String name = param.name(); if (name.isEmpty()) continue; uniqueParamNames.add(name.impl()); paramNames.append(param.name()); paramValues.append(param.value()); // FIXME: url adjustment does not belong in this function. if (url.isEmpty() && urlParameter.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url"))) urlParameter = stripLeadingAndTrailingHTMLSpaces(param.value()); // FIXME: serviceType calculation does not belong in this function. if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) { serviceType = param.value(); size_t pos = serviceType.find(";"); if (pos != notFound) serviceType = serviceType.left(pos); } } // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM, // else our Java plugin will misinterpret it. [4004531] String codebase; if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) { codebase = "codebase"; uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already } // Turn the attributes of the <object> element into arrays, but don't override <param> values. if (hasAttributes()) { for (const Attribute& attribute : attributesIterator()) { const AtomicString& name = attribute.name().localName(); if (!uniqueParamNames.contains(name.impl())) { paramNames.append(name.string()); paramValues.append(attribute.value().string()); } } } mapDataParamToSrc(¶mNames, ¶mValues); // HTML5 says that an object resource's URL is specified by the object's data // attribute, not by a param element. However, for compatibility, allow the // resource's URL to be given by a param named "src", "movie", "code" or "url" // if we know that resource points to a plug-in. #if PLATFORM(IOS) if (shouldNotPerformURLAdjustment()) return; #endif if (url.isEmpty() && !urlParameter.isEmpty()) { SubframeLoader& loader = document().frame()->loader().subframeLoader(); if (loader.resourceWillUsePlugin(urlParameter, serviceType, shouldPreferPlugInsForImages())) url = urlParameter; } }