bool XMLHandler::startElement(const QString &namespaceURI, const QString & /*localName*/, const QString &qName, const QXmlAttributes &atts) { if(currentNode()->nodeType() == Node::TEXT_NODE) exitText(); DOMString nsURI; if(!namespaceURI.isNull()) nsURI = DOMString(namespaceURI); else // No namespace declared, default to the no namespace nsURI = DOMString(""); ElementImpl *newElement = m_doc->createElementNS(nsURI, qName); if(!newElement) return false; int i; for(i = 0; i < atts.length(); i++) { int exceptioncode = 0; QString uriString = atts.uri(i); QString qnString = atts.qName(i); fixUpNSURI(uriString, qnString); DOMString uri(uriString); DOMString qn(qnString); DOMString val(atts.value(i)); newElement->setAttributeNS(uri, qn, val, exceptioncode); if(exceptioncode) // exception setting attributes return false; } if(newElement->id() == ID_SCRIPT || newElement->id() == makeId(xhtmlNamespace, ID_SCRIPT)) static_cast< HTMLScriptElementImpl * >(newElement)->setCreatedByParser(true); // this is tricky. in general the node doesn't have to attach to the one it's in. as far // as standards go this is wrong, but there's literally thousands of documents where // we see <p><ul>...</ul></p>. the following code is there for those cases. // when we can't attach to the currently holding us node we try to attach to its parent bool attached = false; for(NodeImpl *current = currentNode(); current; current = current->parent()) { attached = current->addChild(newElement); if(attached) break; } if(attached) { if(m_view && !newElement->attached() && !m_doc->hasPendingSheets()) newElement->attach(); pushNode(newElement); return true; } else { delete newElement; return false; } // ### DOM spec states: "if there is no markup inside an element's content, the text is contained in a // single object implementing the Text interface that is the only child of the element."... do we // need to ensure that empty elements always have an empty text child? }
void KHTMLParser::parseToken(Token *t) { if (t->id > 2*ID_CLOSE_TAG) { kdDebug( 6035 ) << "Unknown tag!! tagID = " << t->id << endl; return; } if(discard_until) { if(t->id == discard_until) discard_until = 0; // do not skip </iframe> if ( discard_until || current->id() + ID_CLOSE_TAG != t->id ) return; } #ifdef PARSER_DEBUG kdDebug( 6035 ) << "\n\n==> parser: processing token " << getTagName(t->id).string() << "(" << t->id << ")" << " current = " << getTagName(current->id()).string() << "(" << current->id() << ")" << endl; kdDebug(6035) << " inBody=" << inBody << " haveFrameSet=" << haveFrameSet << endl; #endif // holy shit. apparently some sites use </br> instead of <br> // be compatible with IE and NS if(t->id == ID_BR+ID_CLOSE_TAG && document->document()->inCompatMode()) t->id -= ID_CLOSE_TAG; if(t->id > ID_CLOSE_TAG) { processCloseTag(t); return; } // ignore spaces, if we're not inside a paragraph or other inline code if( t->id == ID_TEXT && t->text ) { if(inBody && !skipMode() && current->id() != ID_STYLE && current->id() != ID_TITLE && current->id() != ID_SCRIPT && !t->text->containsOnlyWhitespace()) haveContent = true; #ifdef PARSER_DEBUG kdDebug(6035) << "length="<< t->text->l << " text='" << QConstString(t->text->s, t->text->l).string() << "'" << endl; #endif } NodeImpl *n = getElement(t); // just to be sure, and to catch currently unimplemented stuff if(!n) return; // set attributes if(n->isElementNode()) { ElementImpl *e = static_cast<ElementImpl *>(n); e->setAttributeMap(t->attrs); // take care of optional close tags if(endTag[e->id()] == DOM::OPTIONAL) popBlock(t->id); } // if this tag is forbidden inside the current context, pop // blocks until we are allowed to add it... while(forbiddenTag[t->id]) { #ifdef PARSER_DEBUG kdDebug( 6035 ) << "t->id: " << t->id << " is forbidden :-( " << endl; #endif popOneBlock(); } if (!insertNode(n, t->flat)) { // we couldn't insert the node... if(n->isElementNode()) { ElementImpl *e = static_cast<ElementImpl *>(n); e->setAttributeMap(0); } #ifdef PARSER_DEBUG kdDebug( 6035 ) << "insertNode failed current=" << current->id() << ", new=" << n->id() << "!" << endl; #endif if (map == n) { #ifdef PARSER_DEBUG kdDebug( 6035 ) << " --> resetting map!" << endl; #endif map = 0; } if (form == n) { #ifdef PARSER_DEBUG kdDebug( 6035 ) << " --> resetting form!" << endl; #endif form = 0; } delete n; } }