void DOMTreeView::recursive(const DOM::Node &pNode, const DOM::Node &node) { QListViewItem *cur_item; if(pNode.ownerDocument() != document) { QString val = node.nodeValue().string(); if ( val.length() > 20 ) val.truncate( 20 ); cur_item = new QListViewItem(static_cast<QListView *>(this), node.nodeName().string(), val ); document = pNode.ownerDocument(); } else { QString val = node.nodeValue().string(); if ( val.length() > 20 ) val.truncate( 20 ); cur_item = new QListViewItem(m_itemdict[pNode.handle()], node.nodeName().string(), val); } if(node.handle()) { m_itemdict.insert(node.handle(), cur_item); m_nodedict.insert(cur_item, new DOM::Node(node)); } DOM::Node cur_child = node.lastChild(); while(!cur_child.isNull()) { recursive(node, cur_child); cur_child = cur_child.previousSibling(); } }
void DOMTreeView::initializeOptionsFromNode(const DOM::Node &node) { infoNode = node; nodeName->clear(); nodeType->clear(); nodeNamespace->clear(); nodeValue->clear(); if (node.isNull()) { nodeInfoStack->raiseWidget(EmptyPanel); return; } nodeName->setText(node.nodeName().string()); nodeType->setText(QString::number(node.nodeType())); nodeNamespace->setText(node.namespaceURI().string()); // nodeValue->setText(node.value().string()); DOM::Element element = node; if (!element.isNull()) { initializeOptionsFromElement(element); return; } DOM::CharacterData cdata = node; if (!cdata.isNull()) { initializeOptionsFromCData(cdata); return; } // Fallback nodeInfoStack->raiseWidget(EmptyPanel); }
bool KHTMLReader::parse_ul(DOM::Element e) { _list_depth++; bool popstateneeded = false; for (DOM::Node items = e.firstChild();!items.isNull();items = items.nextSibling()) { if (items.nodeName().string().toLower() == "li") { if (popstateneeded) { popState(); //popstateneeded = false; } pushNewState(); startNewLayout(); popstateneeded = true; _writer->layoutAttribute(state()->paragraph, "COUNTER", "numberingtype", "1"); _writer->layoutAttribute(state()->paragraph, "COUNTER", "righttext", "."); if (e.tagName().string().toLower() == "ol") { _writer->layoutAttribute(state()->paragraph, "COUNTER", "type", "1"); _writer->layoutAttribute(state()->paragraph, "COUNTER", "numberingtype", "1"); _writer->layoutAttribute(state()->paragraph, "COUNTER", "righttext", "."); } else { _writer->layoutAttribute(state()->paragraph, "COUNTER", "type", "10"); _writer->layoutAttribute(state()->paragraph, "COUNTER", "numberingtype", ""); _writer->layoutAttribute(state()->paragraph, "COUNTER", "righttext", ""); } _writer->layoutAttribute(state()->paragraph, "COUNTER", "depth", QString("%1").arg(_list_depth - 1)); } parseNode(items); } if (popstateneeded) popState(); _list_depth--; return false; }
void DOMTreeView::saveRecursive(const DOM::Node &pNode, int indent) { const QString nodeName(pNode.nodeName().string()); QString text; QString strIndent; strIndent.fill(' ', indent); const DOM::Element element = static_cast<const DOM::Element>(pNode); text = strIndent; if ( !element.isNull() ) { if (nodeName.at(0)=='-') { /* Don't save khtml internal tags '-konq..' * Approximating it with <DIV> */ text += "<DIV> <!-- -KONG_BLOCK -->"; } else { text += "<" + nodeName; QString attributes; DOM::Attr attr; const DOM::NamedNodeMap attrs = element.attributes(); unsigned long lmap = attrs.length(); for( uint j=0; j<lmap; j++ ) { attr = static_cast<DOM::Attr>(attrs.item(j)); attributes += " " + attr.name().string() + "=\"" + attr.value().string() + "\""; } if (!(attributes.isEmpty())){ text += " "; } text += attributes.simplifyWhiteSpace(); if(element.firstChild().isNull()) { text += "/>"; } else { text += ">"; } } } else { text = strIndent + pNode.nodeValue().string(); } kdDebug(90180) << text << endl; if (!(text.isEmpty())) { (*m_textStream) << text << endl; } DOM::Node child = pNode.firstChild(); while(!child.isNull()) { saveRecursive(child, indent+2); child = child.nextSibling(); } if (!(element.isNull()) && (!(element.firstChild().isNull()))) { if (nodeName.at(0)=='-') { text = strIndent + "</DIV> <!-- -KONG_BLOCK -->"; } else { text = strIndent + "</" + pNode.nodeName().string() + ">"; } kdDebug(90180) << text << endl; (*m_textStream) << text << endl; } }
void DOMTreeView::addElement ( const DOM::Node &node, DOMListViewItem *cur_item, bool isLast) { cur_item->setClosing(isLast); const QString nodeName(node.nodeName().string()); QString text; const DOM::Element element = node; if (!element.isNull()) { if (!m_bPure) { if (isLast) { text ="</"; } else { text = "<"; } text += nodeName; } else { text = nodeName; } if (m_bShowAttributes && !isLast) { QString attributes; DOM::Attr attr; DOM::NamedNodeMap attrs = element.attributes(); unsigned long lmap = attrs.length(); for( unsigned int j=0; j<lmap; j++ ) { attr = static_cast<DOM::Attr>(attrs.item(j)); attributes += " " + attr.name().string() + "=\"" + attr.value().string() + "\""; } if (!(attributes.isEmpty())) { text += " "; } text += attributes.simplifyWhiteSpace(); } if (!m_bPure) { if(element.firstChild().isNull()) { text += "/>"; } else { text += ">"; } } cur_item->setText(0, text); } else { text = "`" + node.nodeValue().string() + "'"; // Hacks to deal with PRE QTextStream ts( text, IO_ReadOnly ); while (!ts.eof()) { const QString txt(ts.readLine()); const QFont font(KGlobalSettings::fixedFont()); cur_item->setFont( font ); cur_item->setText(0, txt); if(node.handle()) { m_itemdict.insert(node.handle(), cur_item); } DOMListViewItem *parent; if (cur_item->parent()) { parent = static_cast<DOMListViewItem *>(cur_item->parent()); } else { parent = cur_item; } cur_item = new DOMListViewItem(node, parent, cur_item); } // This is one is too much DOMListViewItem *notLastItem = static_cast<DOMListViewItem *>(cur_item->itemAbove()); delete cur_item; cur_item = notLastItem; } if (m_bHighlightHTML && node.ownerDocument().isHTMLDocument()) { highlightHTML(cur_item, nodeName); } }
bool HTMLEnhancer::enhanceNode(Node *node, DOM::Node parentDNode, DOM::Node nextDNode) { DOM::Node domNode, domNode2, attr, *ptDomNode; bool tbody, goUp; Node *n; QString script, filename, text, oldName; KURL url, baseURL; int oldType; //FIRST update the src attr with the baseURL if(node->rootNode()) { domNode = node->rootNode()->attributes().getNamedItem("src"); if(!domNode.isNull()) { baseURL.setPath(ViewManager::ref()->activeDocument()->url().directory()); QuantaCommon::setUrl(url, domNode.nodeValue().string()); url = QExtFileInfo::toAbsolute(url, baseURL); domNode.setNodeValue(url.url()); #ifdef HEAVY_DEBUG kdDebug(25001)<< "HTMLTranslator::translateNode() - new src : " << url.url() << endl; #endif } } //THEN update the href attr of the LINK node with the baseURL if(node->tag->name.lower() == "link" && node->rootNode()) { domNode = node->rootNode()->attributes().getNamedItem("href"); if(!domNode.isNull()) { baseURL.setPath(ViewManager::ref()->activeDocument()->url().directory()); QuantaCommon::setUrl(url, domNode.nodeValue().string()); url = QExtFileInfo::toAbsolute(url, baseURL); domNode.setNodeValue(url.url()); #ifdef HEAVY_DEBUG kdDebug(25001)<< "HTMLTranslator::translateNode() - new href : " << url.url() << endl; #endif } } //THEN if it is the style element, add a DOM::Node::TEXT_NODE child gathering all the CSS //by default, the parser parse it as a script, which can't be translated in DOM::Nodes. if((node->tag->type == Tag::XmlTag && node->tag->name.lower() == "style") || (node->tag->type == Tag::ScriptTag && node->tag->name.lower().contains("style") != 0)) { //If the style Node doesn't exists, create it if(!node->rootNode()) { oldType = node->tag->type; node->tag->type = Tag::XmlTag; oldName = node->tag->name; node->tag->name = "style"; m_wkafkapart->buildKafkaNodeFromNode(node); node->tag->type = oldType; node->tag->name = oldName; } if(node->rootNode()) { domNode = *node->rootNode(); n = node->child; text = ""; goUp = false; while(n) { text += n->tag->tagStr(); n = kafkaCommon::getNextNode(n, goUp, node); } #ifdef HEAVY_DEBUG kdDebug(25001)<< "HTMLTranslator::translateNode() - CSS code : " << text << endl; #endif domNode2 = kafkaCommon::createTextDomNode(text, m_wkafkapart->getKafkaWidget()->document()); if(!kafkaCommon::insertDomNode(domNode2, domNode)) return false; m_wkafkapart->connectDomNodeToQuantaNode(domNode2, node); } } QTag* qTag = QuantaCommon::tagFromDTD(m_wkafkapart->getCurrentDoc()->defaultDTD(), parentDNode.nodeName().string()); //THEN replace, if asked, scripts by a little icon. if(node->tag->type == Tag::ScriptTag && m_showIconForScripts && qTag->isChild("IMG", false)) { script = node->tag->name.left(node->tag->name.find("block", 0, false) - 1).lower(); #ifdef LIGHT_DEBUG kdDebug(25001)<< "HTMLTranslator::translateNode() - BLOCK:" << script << ":" << endl; #endif filename = m_stddirs->findResource("data", "kafkapart/pics/" + script + ".png" ); if(!filename.isEmpty()) { //FIXME DTD! domNode = kafkaCommon::createDomNode("IMG", m_wkafkapart->defaultDTD(), m_wkafkapart->getKafkaWidget()->document()); kafkaCommon::editDomNodeAttribute(domNode, "IMG", m_wkafkapart->defaultDTD(), "src", filename, m_wkafkapart->getKafkaWidget()->document()); //Add a tooltip indicating the content of the script n = node->child; text = ""; goUp = false; while(n && n != node) { text += n->tag->tagStr(); n = kafkaCommon::getNextNode(n, goUp, node); } //if(text == "") // text = i18n("Empty") kafkaCommon::editDomNodeAttribute(domNode, "img", m_wkafkapart->defaultDTD(), "title", text, m_wkafkapart->getKafkaWidget()->document()); if(!kafkaCommon::insertDomNode(domNode, parentDNode, nextDNode)) return false; m_wkafkapart->connectDomNodeToQuantaNode(domNode, node); } } //THEN if it is a comment, add a little icon ;o) if(node->tag->type == Tag::Comment && m_showIconForScripts && qTag->isChild("IMG", false)) { #ifdef LIGHT_DEBUG kdDebug(25001)<< "HTMLTranslator::translateNode() - Comment" << endl; #endif filename = m_stddirs->findResource("data", "kafkapart/pics/comment.png" ); if(!filename.isEmpty()) { //FIXME DTD! domNode = kafkaCommon::createDomNode("IMG", m_wkafkapart->defaultDTD(), m_wkafkapart->getKafkaWidget()->document()); kafkaCommon::editDomNodeAttribute(domNode, "IMG", m_wkafkapart->defaultDTD(), "src", filename, m_wkafkapart->getKafkaWidget()->document()); //Add a tooltip indicating the content of the script n = node->child; text = ""; goUp = false; while(n && n != node) { text += n->tag->tagStr(); n = kafkaCommon::getNextNode(n, goUp, node); } //if(text == "") // text = i18n("Empty") kafkaCommon::editDomNodeAttribute(domNode, "img", m_wkafkapart->defaultDTD(), "title", text, m_wkafkapart->getKafkaWidget()->document()); if(!kafkaCommon::insertDomNode(domNode, parentDNode, nextDNode)) return false; m_wkafkapart->connectDomNodeToQuantaNode(domNode, node); } } //THEN add a TBODY tag if necessary if(node->rootNode() && node->rootNode()->nodeName().string().lower() == "table") { tbody = false; n = node->child; while(n) { if(n->tag->name.lower() == "tbody") tbody = true; n = n->next; } if(!tbody) { domNode = kafkaCommon::createDomNode("TBODY", m_wkafkapart->defaultDTD(), m_wkafkapart->getKafkaWidget()->htmlDocument()); if(!kafkaCommon::insertDomNode(domNode, *node->rootNode())) return false; m_wkafkapart->connectDomNodeToQuantaNode(domNode, node); ptDomNode = new DOM::Node(domNode); node->setLeafNode(ptDomNode); } } //THEN add a red dotted border to FORM tags. if(node->rootNode() && node->rootNode()->nodeName().string().lower() == "form") { kafkaCommon::editDomNodeAttribute(*node->rootNode(), node, "style", "border: 1px dotted red", m_wkafkapart->getKafkaWidget()->document()); } // THEN add a tooltip indicating the content of the name attribute if(node->rootNode() && node->rootNode()->nodeName().string().lower() == "input") { domNode = *(node->rootNode()); QString text = node->tag->attributeValue("name"); kafkaCommon::editDomNodeAttribute(domNode, "input", m_wkafkapart->defaultDTD(), "title", text, m_wkafkapart->getKafkaWidget()->document()); } //THEN add a blue dotted border to DL, OL, UL tags if(node->rootNode()) { text = node->rootNode()->nodeName().string().lower(); if(text == "dl" || text == "ol" || text == "ul") { kafkaCommon::editDomNodeAttribute(*node->rootNode(), node, "style", "border: 1px dotted blue", m_wkafkapart->getKafkaWidget()->document()); } } //THEN add a minimal border for borderless tables //TODO: make it configurable, and look if CSS hasn't defined a border first if(node->rootNode() && node->rootNode()->nodeName().string().lower() == "table") { attr = node->rootNode()->attributes().getNamedItem("border"); if(attr.isNull() || (!attr.isNull() && attr.nodeValue().string() == "0")) { kafkaCommon::editDomNodeAttribute(*node->rootNode(), node, "border", "1", m_wkafkapart->getKafkaWidget()->document()); } } //THEN add a blue dotted border to DIV tags if(node->rootNode()) { text = node->rootNode()->nodeName().string().lower(); if(text == "div") { kafkaCommon::editDomNodeAttribute(*node->rootNode(), node, "style", "border: 1px dotted green", m_wkafkapart->getKafkaWidget()->document()); } } return true; }
void HTMLEnhancer::postEnhanceNode(DOM::Node domNode) { DOM::Node textNode; kNodeAttrs *props; QTag *qTag; bool isInline; if(domNode.isNull()) return; //If domNode is a Block and there is no text around, and if domNode's parent can handle //text or a P tag, add an empty text DOM::Node // so that the user can access this area. qTag = QuantaCommon::tagFromDTD(m_wkafkapart->getCurrentDoc()->defaultDTD(), domNode.nodeName().string()); isInline = kafkaCommon::isInline(domNode.nodeName().string()); if(domNode.nodeType() == DOM::Node::ELEMENT_NODE && (!isInline || (isInline && qTag && qTag->isSingle()))) { qTag = QuantaCommon::tagFromDTD(m_wkafkapart->getNode(domNode.parentNode())); if((domNode.nextSibling().isNull() || (!domNode.nextSibling().isNull() && domNode.nextSibling().nodeType() == DOM::Node::ELEMENT_NODE && !kafkaCommon::isInline(domNode.nextSibling().nodeName().string()))) && qTag && (qTag->isChild("#text", false) || qTag->isChild("p", false)) && domNode.nodeName().string().lower() != "p") { textNode = kafkaCommon::createTextDomNode("", m_wkafkapart->getKafkaWidget()->document()); props = m_wkafkapart->connectDomNodeToQuantaNode(textNode, 0L); props->setIsLinkedToNode(false); props->setSpecialBehavior(kNodeAttrs::emptyTextSurroundingBlockElementAtTheRight); kafkaCommon::insertDomNode(textNode, domNode.parentNode(), domNode.nextSibling()); } if((domNode.previousSibling().isNull() || (!domNode.previousSibling().isNull() && domNode.previousSibling().nodeType() == DOM::Node::ELEMENT_NODE && !kafkaCommon::isInline(domNode.previousSibling().nodeName().string()))) && qTag && (qTag->isChild("#text", false) || qTag->isChild("p", false)) && domNode.nodeName().string().lower() != "p") { textNode = kafkaCommon::createTextDomNode("", m_wkafkapart->getKafkaWidget()->document()); props = m_wkafkapart->connectDomNodeToQuantaNode(textNode, 0L); props->setIsLinkedToNode(false); props->setSpecialBehavior(kNodeAttrs::emptyTextSurroundingBlockElementAtTheLeft); kafkaCommon::insertDomNode(textNode, domNode.parentNode(), domNode); } } //If domNode is an childless element, and if it can handle Text or a P tag, //add an empty text DOM::Node so that the //user can access this area. qTag = QuantaCommon::tagFromDTD(m_wkafkapart->getNode(domNode)); if(domNode.nodeType() == DOM::Node::ELEMENT_NODE && !domNode.hasChildNodes() && qTag && (qTag->isChild("#text", false) || qTag->isChild("p", false))) { textNode = kafkaCommon::createTextDomNode("", m_wkafkapart->getKafkaWidget()->document()); props = m_wkafkapart->connectDomNodeToQuantaNode(textNode, 0L); props->setIsLinkedToNode(false); props->setSpecialBehavior(kNodeAttrs::emptyTextAsChildOfAChildlessElement); kafkaCommon::insertDomNode(textNode, domNode); } }
bool KHTMLReader::parse_table(DOM::Element e) { if (_writer->isInTable()) { // We are already inside of a table. Tables in tables are not supported // yet. So, just add that table-content as text. for (DOM::Node rows = e.firstChild().firstChild();!rows.isNull();rows = rows.nextSibling()) if (!rows.isNull() && rows.nodeName().string().toLower() == "tr") for (DOM::Node cols = rows.firstChild();!cols.isNull();cols = cols.nextSibling()) if (!cols.isNull()) parseNode(cols); return false; } DOM::Element table_body = e.firstChild(); if (table_body.isNull()) { // If the table_body is empty, we don't continue cause else // KHTML will throw a DOM::DOMException if we try to access // the null element. return true; } int tableno = _writer->createTable(); int nrow = 0; int ncol = 0; bool has_borders = false; QColor bgcolor = parsecolor("#FFFFFF"); if (!table_body.getAttribute("bgcolor").string().isEmpty()) bgcolor = parsecolor(table_body.getAttribute("bgcolor").string()); if ((e.getAttribute("border").string().toInt() > 0)) has_borders = true; // fixme rewrite this proper //(maybe using computed sizes from khtml if thats once exported) for (DOM::Node rowsnode = table_body.firstChild();!rowsnode.isNull();rowsnode = rowsnode.nextSibling()) { DOM::Element rows = rowsnode; if (!rows.isNull() && rows.tagName().string().toLower() == "tr") { QColor obgcolor = bgcolor; if (!rows.getAttribute("bgcolor").string().isEmpty()) bgcolor = parsecolor(rows.getAttribute("bgcolor").string()); ncol = 0; for (DOM::Node colsnode = rows.firstChild();!colsnode.isNull();colsnode = colsnode.nextSibling()) { DOM::Element cols = colsnode; const QString nodename = cols.isNull() ? QString() : cols.nodeName().string().toLower(); if (nodename == "td" || nodename == "th") { QColor bbgcolor = bgcolor; if (!cols.getAttribute("bgcolor").string().isEmpty()) bgcolor = parsecolor(cols.getAttribute("bgcolor").string()); pushNewState(); QRect colrect = cols.getRect(); state()->frameset = _writer->createTableCell(tableno, nrow, ncol, 1, colrect); state()->frameset.firstChild().toElement().setAttribute("bkRed", bgcolor.red()); state()->frameset.firstChild().toElement().setAttribute("bkGreen", bgcolor.green()); state()->frameset.firstChild().toElement().setAttribute("bkBlue", bgcolor.blue()); if (has_borders) { state()->frameset.firstChild().toElement().setAttribute("lWidth", 1); state()->frameset.firstChild().toElement().setAttribute("rWidth", 1); state()->frameset.firstChild().toElement().setAttribute("bWidth", 1); state()->frameset.firstChild().toElement().setAttribute("tWidth", 1); } // fixme don't guess. get it right. state()->paragraph = _writer->addParagraph(state()->frameset); parseNode(cols); _writer->cleanUpParagraph(state()->paragraph); popState(); ncol++; bgcolor = bbgcolor; } } nrow++; bgcolor = obgcolor; } } _writer->finishTable(tableno/*,0,0,r.right()-r.left(),r.bottom()-r.top()*/); // FIXME find something better. startNewParagraph(false, false); _writer->createInline(state()->paragraph, _writer->fetchTableCell(tableno, 0, 0)); startNewParagraph(false, false); return false; // we do our own recursion }