Beispiel #1
0
 virtual DOMNode_implT* cloneNode(bool /*deep*/) const
 {
   AttrImpl* a = dynamic_cast<AttrImpl*>(NodeT::ownerDoc_->createAttribute(*name_));
   cloneChildren(a);
   a->setSpecified(getSpecified());
   return a;
 } // cloneNode
DOMString ElementImpl::openTagStartToString() const
{
    DOMString result = DOMString("<") + tagName();

    NamedAttrMapImpl *attrMap = attributes(true);

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

	    AttributeImpl *attribute = attrMap->attributeItem(i);
	    AttrImpl *attr = attribute->attrImpl();

	    if (attr) {
		result += attr->toString();
	    } else {
		result += getDocument()->attrName(attribute->id());
		if (!attribute->value().isNull()) {
		    result += "=\"";
		    // FIXME: substitute entities for any instances of " or '
		    result += attribute->value();
		    result += "\"";
		}
	    }
	}
    }

    return result;
}
Beispiel #3
0
AttrImpl *NodeIDMap::find(const DOMString &id)
{
    //
    //  Get the hashcode for the supplied string.
    //
	unsigned int initalHash = XMLString::hashN(id.rawBuffer(), id.length(), fSize-1, fMemoryManager);
	initalHash++;
	unsigned int currentHash = initalHash;

	//
	// Loop looking for a slot pointing to an attr with this id.
    //
    while (true)
	{
		AttrImpl *tableSlot = fTable[currentHash];
		if (tableSlot == 0)
        {
            // There is no matching entry in the table
            return 0;
        }


        if ((tableSlot != (AttrImpl *)-1) && tableSlot->getValue().equals(id))
            return tableSlot;

        currentHash += initalHash;  // rehash
        if (currentHash >= fSize)
            currentHash = currentHash % fSize;
    }
    return 0;  // Never gets here, but keeps some compilers happy.
};
Node NamedAttrMapImpl::setNamedItem ( NodeImpl* arg, int &exceptioncode )
{
    if (!element) {
        exceptioncode = DOMException::NOT_FOUND_ERR;
        return 0;
    }

    // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
    if (isReadOnly()) {
        exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
        return 0;
    }

    // WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
    if (arg->getDocument() != element->getDocument()) {
        exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
        return 0;
    }

    // Not mentioned in spec: throw a HIERARCHY_REQUEST_ERROR if the user passes in a non-attribute node
    if (!arg->isAttributeNode()) {
        exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
        return 0;
    }
    AttrImpl *attr = static_cast<AttrImpl*>(arg);

    AttributeImpl* a = attr->attrImpl();
    AttributeImpl* old = getAttributeItem(a->id());
    if (old == a) return arg; // we know about it already

    // INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
    // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
    if (attr->ownerElement()) {
        exceptioncode = DOMException::INUSE_ATTRIBUTE_ERR;
        return 0;
    }

    if (a->id() == ATTR_ID) {
	element->updateId(old ? old->value() : nullAtom, a->value());
    }

    // ### slightly inefficient - resizes attribute array twice.
    Node r;
    if (old) {
        if (!old->attrImpl())
            old->allocateImpl(element);
        r = old->_impl;
        removeAttribute(a->id());
    }

    addAttribute(a);
    return r;
}
Beispiel #5
0
DOMString ElementImpl::openTagStartToString(bool expandurls) const
{
    DOMString result = DOMString("<") + tagName();

    NamedAttrMapImpl *attrMap = attributes(true);

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

            AttributeImpl *attribute = attrMap->attrAt(i);
            AttrImpl *attr = attribute->attr();

            if(attr)
            {
                result += attr->toString();
            }
            else
            {
                result += getDocument()->getName(NodeImpl::AttributeId, attribute->id());
                if(!attribute->value().isNull())
                {
                    result += "=\"";
                    // FIXME: substitute entities for any instances of " or '
                    // Expand out all urls, i.e. the src and href attributes
                    if(expandurls && (attribute->id() == ATTR_SRC || attribute->id() == ATTR_HREF))
                        if(getDocument())
                        {
                            // We need to sanitize the urls - strip out the passwords.
                            // FIXME:   are src=  and href=  the only places that might have a password and need to be sanitized?
                            KURL safeURL(getDocument()->completeURL(attribute->value().string()));
                            safeURL.setPass(QString::null);
                            result += safeURL.htmlURL();
                        }
                        else
                        {
                            kdWarning() << "getDocument() returned false";
                            result += attribute->value();
                        }
                    else
                        result += attribute->value();
                    result += "\"";
                }
            }
        }
    }

    return result;
}
Beispiel #6
0
AttrImpl::AttrImpl(const AttrImpl &other, bool deep)
    : NodeImpl(other)
{
    name = other.name.clone();
	
    isSpecified(other.isSpecified());

    /* We must initialize the void* value to null in *all* cases. Failing to do
     * so would cause, in case of assignment to a DOMString later, its content
     * to be derefenced as a DOMString, which would lead the ref count code to
     * be called on something that is not actually a DOMString... Really bad
     * things would then happen!!!
     */
    value.child = null;
    hasStringValue(other.hasStringValue());

    if (other.isIdAttr())
    {
        isIdAttr(true);
        this->getOwnerDocument()->getNodeIDMap()->add(this);
    }

    // take care of case where there are kids
    if (!hasStringValue()) {
        cloneChildren(other);
    }
    else {
        if(other.value.str == null) 
        {
            if(value.str != null)
            {
                *(value.str) = null;
                delete value.str;
                value.str = null;
            }
       }
       else
       {
            // get the address of the value field of this as a DOMString*
            DOMString *x = (value.str == null
                ?(value.str = new (getOwnerDocument()->getMemoryManager()) DOMString())
                :value.str
            );
            // and the address of the value field of other as a DOMString*
            DOMString *y = other.value.str;
            // We can now safely do the cloning and assignement, both operands
            // being a DOMString their ref counts will be updated appropriately
            *x = y->clone();
        }
    }
};
QString NodeImpl::recursive_toHTML( ) const
{
    QString me;

    // Copy who I am into the htmlText string
    if ( nodeType() == Node::TEXT_NODE )
        me = nodeValue().string();
    else
    {   // If I am an element, not a text
        me = QChar('<') + nodeName().string();

        // print attributes
        if( nodeType() == Node::ELEMENT_NODE )
        {
            ElementImpl *el = const_cast<ElementImpl*>(static_cast<const ElementImpl *>(this));
            AttrImpl *attr;
            int exceptioncode;
            NamedNodeMapImpl *attrs = el->attributes();
            unsigned long lmap = attrs->length(exceptioncode);
            for( unsigned int j=0; j<lmap; j++ )
            {
                attr = static_cast<AttrImpl*>(attrs->item(j,exceptioncode));
                me += " " + attr->name().string() + "=\"" + attr->value().string() + "\"";
            }
        }

        // print ending bracket of start tag
        if( firstChild() == 0 )     // if element has no endtag
            me += " />";
        else                        // if element has endtag
            me += ">";
    }

    NodeImpl* n;

    if( (n = firstChild()) )
    {
        // print firstChild
        me += n->recursive_toHTML( );

        // Print my ending tag
        if ( nodeType() != Node::TEXT_NODE )
            me += "</" + nodeName().string() + ">";
    }
    // print next sibling
    if( (n = nextSibling()) )
        me += n->recursive_toHTML( );

    return me;
}
Beispiel #8
0
AttrImpl *AttributeImpl::createAttr(ElementImpl *element, DocumentImpl *docPtr)
{
    if(m_attrId)
    {
        AttrImpl *attr = new AttrImpl(element, docPtr, m_attrId, m_data.value);
        if(!attr)
            return 0;
        attr->setHTMLCompat(docPtr->htmlMode() != DocumentImpl::XHtml);
        m_data.value->deref();
        m_data.attr = attr;
        m_data.attr->ref();
        m_attrId = 0; /* "has implementation" flag */
    }

    return m_data.attr;
}
Beispiel #9
0
NodeImpl *AttrMapImpl::removeNamedItemNS(const DOMString &namespaceURI, const DOMString &localName)
{
	NodeImpl* removed = NamedNodeMapImpl::removeNamedItemNS(namespaceURI, localName);

	// Replace it if it had a default value
	// (DOM spec level 2 - Element Interface)
	if (hasDefaults() && (removed != null))
	{
		AttrMapImpl* defAttrs = ((ElementImpl*)ownerNode)->getDefaultAttributes();
		AttrImpl* attr = (AttrImpl*)(defAttrs->getNamedItemNS(namespaceURI, localName));
		if (attr != null)
		{
			AttrImpl* newAttr = (AttrImpl*)attr->cloneNode(true);
			setNamedItem(newAttr);
		}
	}

	return removed;
}
void NodeImpl::printTree(int indent)
{
    QString ind;
    QString s;
    ind.fill(' ', indent);

    // ### find out why this isn't working
    if(isElementNode())
    {
        s = ind + "<" + nodeName().string();

        ElementImpl *el = const_cast<ElementImpl*>(static_cast<const ElementImpl *>(this));
        AttrImpl *attr;
        int exceptioncode;
        NamedNodeMapImpl *attrs = el->attributes();
        unsigned long lmap = attrs->length(exceptioncode);
        for( unsigned int j=0; j<lmap; j++ )
        {
            attr = static_cast<AttrImpl*>(attrs->item(j,exceptioncode));
            s += " " + attr->name().string() + "=\"" + attr->value().string() + "\"";
        }
        if(!firstChild())
            s += " />";
        else
            s += ">";
    }
    else
        s = ind + "'" + nodeValue().string() + "'";

    kdDebug() << s << endl;

    NodeImpl *child = firstChild();
    while( child )
    {
        child->printTree(indent+2);
        child = child->nextSibling();
    }
    if(isElementNode() && firstChild())
        kdDebug() << ind << "</" << nodeName().string() << ">" << endl;
}
Beispiel #11
0
NodeImpl *AttrImpl::cloneNode(bool /*deep*/)
{
    AttrImpl *attr = new AttrImpl(0, docPtr(), m_attrId, m_value, m_prefix);
    attr->setHTMLCompat(m_htmlCompat);
    return attr;
}
Beispiel #12
0
Node NamedAttrMapImpl::setNamedItem(NodeImpl *arg, bool nsAware, DOMStringImpl *qName, int &exceptioncode)
{
    if(!m_element)
    {
        exceptioncode = DOMException::NOT_FOUND_ERR;
        return 0;
    }

    // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
    if(isReadOnly())
    {
        exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
        return 0;
    }

    // WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
    if(arg->getDocument() != m_element->getDocument())
    {
        exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
        return 0;
    }

    // HIERARCHY_REQUEST_ERR: Raised if an attempt is made to add a node doesn't belong in this NamedNodeMap
    if(!arg->isAttributeNode())
    {
        exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
        return 0;
    }
    AttrImpl *attr = static_cast< AttrImpl * >(arg);

    // INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
    // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
    if(attr->ownerElement() && attr->ownerElement() != m_element)
    {
        exceptioncode = DOMException::INUSE_ATTRIBUTE_ERR;
        return 0;
    }

    if(attr->ownerElement() == m_element)
    {
        // Already have this attribute.
        // DOMTS core-1 test "hc_elementreplaceattributewithself" says we should return it.
        return attr;
    }
    unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask;
    NodeImpl::Id id = (attr->id() & mask);

    for(unsigned long i = 0; i < m_attrCount; i++)
    {
        if((m_attrs[i].id() & mask) == id)
        {
            // if we are called with a qualified name, filter out NS-aware elements with non-matching name.
            if(qName && (namespacePart(m_attrs[i].id()) != defaultNamespace) && strcasecmp(m_attrs[i].name(), DOMString(qName)))
                continue;
            // Attribute exists; replace it
            if(id == ATTR_ID)
                m_element->updateId(m_attrs[i].val(), attr->val());

            Node replaced = m_attrs[i].createAttr(m_element, m_element->docPtr());
            m_attrs[i].free();
            m_attrs[i].m_attrId = 0; /* "has implementation" flag */
            m_attrs[i].m_data.attr = attr;
            m_attrs[i].m_data.attr->ref();
            attr->setElement(m_element);
            m_element->parseAttribute(&m_attrs[i]);
            m_element->attributeChanged(m_attrs[i].id());
            // ### dispatch mutation events
            return replaced;
        }
    }

    // No existing attribute; add to list
    m_attrCount++;
    m_attrs = (AttributeImpl *)realloc(m_attrs, m_attrCount * sizeof(AttributeImpl));
    m_attrs[m_attrCount - 1].m_attrId = 0; /* "has implementation" flag */
    m_attrs[m_attrCount - 1].m_data.attr = attr;
    m_attrs[m_attrCount - 1].m_data.attr->ref();
    attr->setElement(m_element);
    if(id == ATTR_ID)
        m_element->updateId(0, attr->val());
    m_element->parseAttribute(&m_attrs[m_attrCount - 1]);
    m_element->attributeChanged(m_attrs[m_attrCount - 1].id());
    // ### dispatch mutation events

    return 0;
}