void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackItem* newItem, Vector<HTMLStackItem*>& remainingCandidates) { ASSERT(remainingCandidates.isEmpty()); if (m_entries.size() < kNoahsArkCapacity) return; // Use a vector with inline capacity to avoid a malloc in the common case // of a quickly ensuring the condition. Vector<HTMLStackItem*, 10> candidates; size_t newItemAttributeCount = attributeCount(newItem->token()); for (size_t i = m_entries.size(); i; ) { --i; Entry& entry = m_entries[i]; if (entry.isMarker()) break; // Quickly reject obviously non-matching candidates. HTMLStackItem* candidate = entry.stackItem().get(); if (newItem->localName() != candidate->localName() || newItem->namespaceURI() != candidate->namespaceURI()) continue; if (attributeCount(candidate->token()) != newItemAttributeCount) continue; candidates.append(candidate); } if (candidates.size() < kNoahsArkCapacity) return; // There's room for the new element in the ark. There's no need to copy out the remainingCandidates. remainingCandidates.append(candidates); }
std::wstring TwXmlElement::attributeValue(int index) { if (index < 0 || index >= attributeCount()) { return L""; } return m_dptr->attributes.at(index).value; }
ViAttribute& ViElement::attribute(int index) { if(attributeCount() > index) { return mAttributes[index]; } return dummyAttribute(); }
ViAttribute& ViElement::attribute(QString name) { for(int i = 0; i < attributeCount(); ++i) { if(name == mAttributes[i].name()) { return mAttributes[i]; } } return dummyAttribute(); }
void HTMLFormattingElementList::ensureNoahsArkCondition(HTMLStackItem* newItem) { Vector<HTMLStackItem*> candidates; tryToEnsureNoahsArkConditionQuickly(newItem, candidates); if (candidates.isEmpty()) return; // We pre-allocate and re-use this second vector to save one malloc per // attribute that we verify. Vector<HTMLStackItem*> remainingCandidates; remainingCandidates.reserveInitialCapacity(candidates.size()); const Vector<Attribute>& attributes = newItem->token()->attributes(); for (size_t i = 0; i < attributes.size(); ++i) { const Attribute& attribute = attributes[i]; for (size_t j = 0; j < candidates.size(); ++j) { HTMLStackItem* candidate = candidates[j]; // These properties should already have been checked by tryToEnsureNoahsArkConditionQuickly. ASSERT(attributeCount(newItem->token()) == attributeCount(candidate->token())); ASSERT(newItem->localName() == candidate->localName() && newItem->namespaceURI() == candidate->namespaceURI()); Attribute* candidateAttribute = candidate->token()->getAttributeItem(attribute.name()); if (candidateAttribute && candidateAttribute->value() == attribute.value()) remainingCandidates.append(candidate); } if (remainingCandidates.size() < kNoahsArkCapacity) return; candidates.swap(remainingCandidates); remainingCandidates.shrink(0); } // Inductively, we shouldn't spin this loop very many times. It's possible, // however, that we wil spin the loop more than once because of how the // formatting element list gets permuted. for (size_t i = kNoahsArkCapacity - 1; i < candidates.size(); ++i) remove(candidates[i]->element()); }
QDomNode ViElement::toDom() { QDomDocument document; QDomElement node = document.createElement(name()); for(int i = 0; i < attributeCount(); ++i) { node.setAttribute(mAttributes[i].name(), mAttributes[i].toString()); } if(childrenCount() > 0) { for(int i = 0; i < childrenCount(); ++i) { node.appendChild(mChildren[i].toDom()); } } else { node.appendChild(document.createTextNode(toString())); } return node; }
// 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 (Node* child = firstChild(); child; child = child->nextSibling()) { if (!child->hasTagName(paramTag)) continue; HTMLParamElement* p = static_cast<HTMLParamElement*>(child); String name = p->name(); if (name.isEmpty()) continue; uniqueParamNames.add(name.impl()); paramNames.append(p->name()); paramValues.append(p->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(p->value()); // FIXME: serviceType calculation does not belong in this function. if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) { serviceType = p->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 (unsigned i = 0; i < attributeCount(); ++i) { Attribute* it = attributeItem(i); const AtomicString& name = it->name().localName(); if (!uniqueParamNames.contains(name.impl())) { paramNames.append(name.string()); paramValues.append(it->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 (url.isEmpty() && !urlParameter.isEmpty()) { SubframeLoader* loader = document()->frame()->loader()->subframeLoader(); if (loader->resourceWillUsePlugin(urlParameter, serviceType, shouldPreferPlugInsForImages())) url = urlParameter; } }
WebString WebElement::attributeValue(unsigned index) const { if (index >= attributeCount()) return WebString(); return constUnwrap<Element>()->attributeItem(index)->value(); }
WebString WebElement::attributeLocalName(unsigned index) const { if (index >= attributeCount()) return WebString(); return constUnwrap<Element>()->attributeAt(index).localName(); }
int main(int argc, char* argv[]) { (void) argc; (void) argv; try { register_rtti(); auto lambda = [](std::string const &name, const rtti::variant &value) { std::cout << name << " = " << value.to<std::string>() << std::endl; return true; }; auto nsGlobal = rtti::MetaNamespace::global(); assert(nsGlobal); //gNS->forceDeferredDefine(rtti::MetaContainer::ForceDeferred::Recursive); std::cout << "namespace " << nsGlobal->name() << std::endl; std::cout << "Attribute count: " << nsGlobal->attributeCount() << std::endl; nsGlobal->for_each_attribute(lambda); std::cout << std::endl; auto nsStd = nsGlobal->getNamespace("std"); assert(nsStd); std::cout << "namespace " << nsStd->qualifiedName() << std::endl; std::cout << "Attribute count: " << nsStd->attributeCount() << std::endl; nsStd->for_each_attribute(lambda); std::cout << std::endl; auto nsTest = nsGlobal->getNamespace("test"); assert(nsTest); std::cout << "namespace " << nsTest->qualifiedName() << std::endl; std::cout << "Attribute count: " << nsTest->attributeCount() << std::endl; nsTest->for_each_attribute(lambda); std::cout << std::endl; { auto prop = nsGlobal->getProperty("global_string"); assert(prop); std::cout << prop->qualifiedName() << std::endl; prop->set(std::string{"Qwerty"}); assert(prop->get().cvalue<std::string>() == "Qwerty"); assert(prop->get().value<const std::string>() == "Qwerty"); const auto v = prop->get(); assert(v.value<std::string>() == "Qwerty"); prop->set(std::string{"YouTube"}); assert(v.value<std::string>() == "YouTube"); } { auto prop = nsGlobal->getProperty("global_readonly_string"); assert(prop); std::cout << prop->qualifiedName() << std::endl; const auto v = prop->get(); assert(v.value<std::string>() == "Hello, World"); try { prop->set(std::string{"Qwerty"}); assert(false); } catch (const rtti::runtime_error &e) { LOG_RED(e.what()); }; } { auto itosM = nsGlobal->getMethod("intToStr"); assert(itosM); { bool ok = false; auto r = itosM->invoke(123, ok); assert(r.value<std::string>() == "123" && ok); } { const bool ok = false; try { auto r = itosM->invoke(123, ok); assert(false); } catch (const rtti::runtime_error &e) { LOG_RED(e.what()); }; } { try { auto r = itosM->invoke(123, false); assert(false); } catch (const rtti::runtime_error &e) { LOG_RED(e.what()); }; } { rtti::variant ok = false; auto r = itosM->invoke(123, ok); assert(r.value<std::string>() == "123" && ok.value<bool>()); } { rtti::variant const ok = false; try { auto r = itosM->invoke(123, ok); assert(false); } catch (const rtti::runtime_error &e) { LOG_RED(e.what()); }; } { bool ok = false; rtti::variant vok = std::ref(ok); auto r = itosM->invoke(123, vok); assert(r.value<std::string>() == "123" && ok && vok.value<bool>()); } { const bool ok = false; rtti::variant vok = std::ref(ok); try { auto r = itosM->invoke(123, vok); assert(false); } catch (const rtti::runtime_error &e) { LOG_RED(e.what()); }; } { rtti::variant ok = false; try { auto r = itosM->invoke(123, std::move(ok)); assert(false); } catch (const rtti::runtime_error &e) { LOG_RED(e.what()); }; } } test_cast_1(); test_variant_1(); std::printf("\n"); } catch(const std::exception& e) { LOG_RED(e.what()); } catch (...) { LOG_RED("Unknown exception!"); } return 0; }