static String imageToMarkup(const String& url, Element* element)
{
    StringBuilder markup;
    markup.append("<img src=\"");
    markup.append(url);
    markup.append("\"");
    // Copy over attributes.  If we are dragging an image, we expect things like
    // the id to be copied as well.
    NamedAttrMap* attrs = element->attributes();
    unsigned length = attrs->length();
    for (unsigned i = 0; i < length; ++i) {
        Attribute* attr = attrs->attributeItem(i);
        if (attr->localName() == "src")
            continue;
        markup.append(" ");
        markup.append(attr->localName());
        markup.append("=\"");
        String escapedAttr = attr->value();
        escapedAttr.replace("\"", "&quot;");
        markup.append(escapedAttr);
        markup.append("\"");
    }

    markup.append("/>");
    return markup.toString();
}
示例#2
0
Value FunLang::doEvaluate() const
{
    String lang = arg(0)->evaluate().toString();

    RefPtr<Node> langNode = 0;
    Node* node = evaluationContext().node.get();
    String xmsnsURI = node->lookupNamespaceURI("xms");
    while (node) {
        NamedAttrMap* attrs = node->attributes();
        langNode = attrs->getNamedItemNS(xmsnsURI, "lang");
        if (langNode)
            break;
        node = node->parentNode();
    }

    if (!langNode)
        return false;

    String langNodeValue = langNode->nodeValue();

    // extract 'en' out of 'en-us'
    int index = langNodeValue.find('-');
    if (index != -1)
        langNodeValue = langNodeValue.left(index);

    return equalIgnoringCase(langNodeValue, lang);
}
bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const
{
    NamedAttrMap* attrs = attributes(true);
    if (!attrs)
        return false;
    return attrs->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
}
示例#4
0
void NamedAttrMap::setAttributes(const NamedAttrMap& other)
{
    // clone all attributes in the other map, but attach to our element
    if (!m_element)
        return;

    // If assigning the map changes the id attribute, we need to call
    // updateId.
    Attribute *oldId = getAttributeItem(idAttr);
    Attribute *newId = other.getAttributeItem(idAttr);

    if (oldId || newId)
        m_element->updateId(oldId ? oldId->value() : nullAtom, newId ? newId->value() : nullAtom);

    clearAttributes();
    unsigned newLength = other.length();
    m_attributes.resize(newLength);
    for (unsigned i = 0; i < newLength; i++)
        m_attributes[i] = other.m_attributes[i]->clone();

    // FIXME: This is wasteful.  The class list could be preserved on a copy, and we
    // wouldn't have to waste time reparsing the attribute.
    // The derived class, HTMLNamedAttrMap, which manages a parsed class list for the CLASS attribute,
    // will update its member variable when parse attribute is called.
    for (unsigned i = 0; i < newLength; i++)
        m_element->attributeChanged(m_attributes[i].get(), true);
}
PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName)
{
    NamedAttrMap* attrs = attributes(true);
    if (!attrs)
        return 0;
    return static_pointer_cast<Attr>(attrs->getNamedItem(QualifiedName(nullAtom, localName, namespaceURI)));
}
示例#6
0
Value FunLang::evaluate() const
{
    String lang = arg(0)->evaluate().toString();

    RefPtr<Node> langNode = 0;
    Node* node = evaluationContext().node.get();
    while (node) {
        NamedAttrMap* attrs = node->attributes();
        if (attrs)
            langNode = attrs->getNamedItemNS(XMLNames::xmlNamespaceURI, "lang");
        if (langNode)
            break;
        node = node->parentNode();
    }

    if (!langNode)
        return false;

    String langNodeValue = langNode->nodeValue();
    while (true) {
        if (equalIgnoringCase(langNodeValue, lang))
            return true;

        // Remove suffixes one by one.
        int index = langNodeValue.reverseFind('-');
        if (index == -1)
            break;
        langNodeValue = langNodeValue.left(index);
    }

    return false;
}
PassRefPtr<Attr> Element::getAttributeNode(const String& name)
{
    NamedAttrMap* attrs = attributes(true);
    if (!attrs)
        return 0;
    String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
    return static_pointer_cast<Attr>(attrs->getNamedItem(localName));
}
bool Element::hasAttribute(const String& name) const
{
    NamedAttrMap* attrs = attributes(true);
    if (!attrs)
        return false;

    // This call to String::lower() seems to be required but
    // there may be a way to remove it.
    String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
    return attrs->getAttributeItem(localName, false);
}
PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
{
    if (!attr) {
        ec = TYPE_MISMATCH_ERR;
        return 0;
    }
    if (attr->ownerElement() != this) {
        ec = NOT_FOUND_ERR;
        return 0;
    }
    if (document() != attr->document()) {
        ec = WRONG_DOCUMENT_ERR;
        return 0;
    }

    NamedAttrMap *attrs = attributes(true);
    if (!attrs)
        return 0;

    return static_pointer_cast<Attr>(attrs->removeNamedItem(attr->qualifiedName(), ec));
}
String Element::openTagStartToString() const
{
    String result = "<" + nodeName();

    NamedAttrMap *attrMap = attributes(true);

    if (attrMap) {
        unsigned numAttrs = attrMap->length();
        for (unsigned i = 0; i < numAttrs; i++) {
            result += " ";

            Attribute *attribute = attrMap->attributeItem(i);
            result += attribute->name().toString();
            if (!attribute->value().isNull()) {
                result += "=\"";
                // FIXME: substitute entities for any instances of " or '
                result += attribute->value();
                result += "\"";
            }
        }
    }

    return result;
}
示例#11
0
void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins)
{
  String url;
  String serviceType;
  Vector<String> paramNames;
  Vector<String> paramValues;
  Frame* frame = m_view->frame();
  
  if (element()->hasTagName(objectTag)) {

      HTMLObjectElement* o = static_cast<HTMLObjectElement*>(element());

      o->setNeedWidgetUpdate(false);
      if (!o->isFinishedParsingChildren())
        return;
      // Check for a child EMBED tag.
      HTMLEmbedElement* embed = 0;
      for (Node* child = o->firstChild(); child;) {
          if (child->hasTagName(embedTag)) {
              embed = static_cast<HTMLEmbedElement*>(child);
              break;
          } else if (child->hasTagName(objectTag))
              child = child->nextSibling();         // Don't descend into nested OBJECT tags
          else
              child = child->traverseNextNode(o);   // Otherwise descend (EMBEDs may be inside COMMENT tags)
      }
      
      // Use the attributes from the EMBED tag instead of the OBJECT tag including WIDTH and HEIGHT.
      HTMLElement *embedOrObject;
      if (embed) {
          embedOrObject = (HTMLElement *)embed;
          url = embed->url();
          serviceType = embed->serviceType();
      } else
          embedOrObject = (HTMLElement *)o;
      
      // If there was no URL or type defined in EMBED, try the OBJECT tag.
      if (url.isEmpty())
          url = o->m_url;
      if (serviceType.isEmpty())
          serviceType = o->m_serviceType;
      
      HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
      
      // Scan the PARAM children.
      // Get the URL and type from the params if we don't already have them.
      // Get the attributes from the params if there is no EMBED tag.
      Node *child = o->firstChild();
      while (child && (url.isEmpty() || serviceType.isEmpty() || !embed)) {
          if (child->hasTagName(paramTag)) {
              HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
              String name = p->name().lower();
              if (url.isEmpty() && (name == "src" || name == "movie" || name == "code" || name == "url"))
                  url = p->value();
              if (serviceType.isEmpty() && name == "type") {
                  serviceType = p->value();
                  int pos = serviceType.find(";");
                  if (pos != -1)
                      serviceType = serviceType.left(pos);
              }
              if (!embed && !name.isEmpty()) {
                  uniqueParamNames.add(p->name().impl());
                  paramNames.append(p->name());
                  paramValues.append(p->value());
              }
          }
          child = child->nextSibling();
      }
      
      // 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 (!embed && MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
          codebase = "codebase";
          uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
      }
      
      // Turn the attributes of either the EMBED tag or OBJECT tag into arrays, but don't override PARAM values.
      NamedAttrMap* attributes = embedOrObject->attributes();
      if (attributes) {
          for (unsigned i = 0; i < attributes->length(); ++i) {
              Attribute* it = attributes->attributeItem(i);
              const AtomicString& name = it->name().localName();
              if (embed || !uniqueParamNames.contains(name.impl())) {
                  paramNames.append(name.string());
                  paramValues.append(it->value().string());
              }
          }
      }
      
      // If we still don't have a type, try to map from a specific CLASSID to a type.
      if (serviceType.isEmpty() && !o->m_classId.isEmpty())
          mapClassIdToServiceType(o->m_classId, serviceType);
      
      if (!isURLAllowed(document(), url))
          return;

      // Find out if we support fallback content.
      m_hasFallbackContent = false;
      for (Node *child = o->firstChild(); child && !m_hasFallbackContent; child = child->nextSibling()) {
          if ((!child->isTextNode() && !child->hasTagName(embedTag) && !child->hasTagName(paramTag)) || // Discount <embed> and <param>
              (child->isTextNode() && !static_cast<Text*>(child)->containsOnlyWhitespace()))
              m_hasFallbackContent = true;
      }
      
      if (onlyCreateNonNetscapePlugins) {
          KURL completedURL;
          if (!url.isEmpty())
              completedURL = frame->loader()->completeURL(url);
        
          if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
              return;
      }
      
      bool success = frame->loader()->requestObject(this, url, AtomicString(o->name()), serviceType, paramNames, paramValues);
      if (!success && m_hasFallbackContent)
          o->renderFallbackContent();
  } else if (element()->hasTagName(embedTag)) {
      HTMLEmbedElement *o = static_cast<HTMLEmbedElement*>(element());
      o->setNeedWidgetUpdate(false);
      url = o->url();
      serviceType = o->serviceType();

      if (url.isEmpty() && serviceType.isEmpty())
          return;
      if (!isURLAllowed(document(), url))
          return;
      
      // add all attributes set on the embed object
      NamedAttrMap* a = o->attributes();
      if (a) {
          for (unsigned i = 0; i < a->length(); ++i) {
              Attribute* it = a->attributeItem(i);
              paramNames.append(it->name().localName().string());
              paramValues.append(it->value().string());
          }
      }
      
      if (onlyCreateNonNetscapePlugins) {
          KURL completedURL;
          if (!url.isEmpty())
              completedURL = frame->loader()->completeURL(url);
          
          if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
              return;
          
      }
      
      frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues);
  }
}
示例#12
0
void Step::nodesInAxis(Node* context, NodeSet& nodes) const
{
    ASSERT(nodes.isEmpty());
    switch (m_axis) {
        case ChildAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->nextSibling())
                if (nodeMatches(n))
                    nodes.append(n);
            return;
        case DescendantAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
                if (nodeMatches(n))
                    nodes.append(n);
            return;
        case ParentAxis:
            if (context->isAttributeNode()) {
                Node* n = static_cast<Attr*>(context)->ownerElement();
                if (nodeMatches(n))
                    nodes.append(n);
            } else {
                Node* n = context->parentNode();
                if (n && nodeMatches(n))
                    nodes.append(n);
            }
            return;
        case AncestorAxis: {
            Node* n = context;
            if (context->isAttributeNode()) {
                n = static_cast<Attr*>(context)->ownerElement();
                if (nodeMatches(n))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n))
                    nodes.append(n);
            nodes.reverse();
            return;
        }
        case FollowingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE) 
                return;
            
            for (Node* n = context->nextSibling(); n; n = n->nextSibling())
                if (nodeMatches(n))
                    nodes.append(n);
            return;
        case PrecedingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE)
                return;
            
            for (Node* n = context->previousSibling(); n; n = n->previousSibling())
                if (nodeMatches(n))
                    nodes.append(n);

            nodes.reverse();
            return;
        case FollowingAxis:
            if (context->isAttributeNode()) {
                Node* p = static_cast<Attr*>(context)->ownerElement();
                while ((p = p->traverseNextNode()))
                    if (nodeMatches(p))
                        nodes.append(p);
            } else {
                for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                    for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
                        if (nodeMatches(n))
                            nodes.append(n);
                        for (Node* c = n->firstChild(); c; c = c->traverseNextNode(n))
                            if (nodeMatches(c))
                                nodes.append(c);
                    }
                }
            }
            return;
        case PrecedingAxis:
            if (context->isAttributeNode())
                context = static_cast<Attr*>(context)->ownerElement();

            for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                for (Node* n = p->previousSibling(); n ; n = n->previousSibling()) {
                    if (nodeMatches(n))
                        nodes.append(n);
                    for (Node* c = n->firstChild(); c; c = c->traverseNextNode(n))
                        if (nodeMatches(c))
                            nodes.append(c);
                }
            }
            nodes.markSorted(false);
            return;
        case AttributeAxis: {
            if (context->nodeType() != Node::ELEMENT_NODE)
                return;

            // Avoid lazily creating attribute nodes for attributes that we do not need anyway.
            if (m_nodeTest.kind() == NodeTest::NameTest && m_nodeTest.data() != "*") {
                RefPtr<Node> n = static_cast<Element*>(context)->getAttributeNodeNS(m_nodeTest.namespaceURI(), m_nodeTest.data());
                if (n && n->namespaceURI() != "http://www.w3.org/2000/xmlns/") // In XPath land, namespace nodes are not accessible on the attribute axis.
                    nodes.append(n.release());
                return;
            }
            
            NamedAttrMap* attrs = context->attributes();
            if (!attrs)
                return;

            for (unsigned long i = 0; i < attrs->length(); ++i) {
                RefPtr<Node> n = attrs->item(i);
                if (nodeMatches(n.get()))
                    nodes.append(n.release());
            }
            return;
        }
        case NamespaceAxis:
            // XPath namespace nodes are not implemented yet.
            return;
        case SelfAxis:
            if (nodeMatches(context))
                nodes.append(context);
            return;
        case DescendantOrSelfAxis:
            if (nodeMatches(context))
                nodes.append(context);
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
            if (nodeMatches(n))
                nodes.append(n);
            return;
        case AncestorOrSelfAxis: {
            if (nodeMatches(context))
                nodes.append(context);
            Node* n = context;
            if (context->isAttributeNode()) {
                n = static_cast<Attr*>(context)->ownerElement();
                if (nodeMatches(n))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n))
                    nodes.append(n);

            nodes.reverse();
            return;
        }
    }
    ASSERT_NOT_REACHED();
}