📄 dom_docimpl.cpp
字号:
// For more info, see the test at: // http://www.hixie.ch/tests/evil/css/import/main/preferred.html // -dwh part->d->m_sheetUsed = content.string(); m_preferredStylesheetSet = content; updateStyleSelector(); } else if(strcasecmp(equiv, "refresh") == 0 && part->metaRefreshEnabled()) { // get delay and url QString str = content.string().stripWhiteSpace(); int pos = str.find(QRegExp("[;,]")); if ( pos == -1 ) pos = str.find(QRegExp("[ \t]")); if (pos == -1) // There can be no url (David) { bool ok = false; int delay = 0; delay = str.toInt(&ok);#if APPLE_CHANGES // We want a new history item if the refresh timeout > 1 second if(ok && part) part->scheduleRedirection(delay, part->url().url(), delay <= 1);#else if(ok && part) part->scheduleRedirection(delay, part->url().url() );#endif } else { double delay = 0; bool ok = false; delay = str.left(pos).stripWhiteSpace().toDouble(&ok); pos++; while(pos < (int)str.length() && str[pos].isSpace()) pos++; str = str.mid(pos); if(str.find("url", 0, false ) == 0) str = str.mid(3); str = str.stripWhiteSpace(); if ( str.length() && str[0] == '=' ) str = str.mid( 1 ).stripWhiteSpace(); str = parseURL( DOMString(str) ).string(); if ( ok && part )#if APPLE_CHANGES // We want a new history item if the refresh timeout > 1 second part->scheduleRedirection(delay, getDocument()->completeURL( str ), delay <= 1);#else part->scheduleRedirection(delay, getDocument()->completeURL( str ));#endif } } else if(strcasecmp(equiv, "expires") == 0) { QString str = content.string().stripWhiteSpace(); time_t expire_date = str.toLong(); if (m_docLoader) m_docLoader->setExpireDate(expire_date); } else if(strcasecmp(equiv, "pragma") == 0 || strcasecmp(equiv, "cache-control") == 0 && part) { QString str = content.string().lower().stripWhiteSpace(); KURL url = part->url(); if ((str == "no-cache") && url.protocol().startsWith("http")) { KIO::http_update_cache(url, true, 0); } } else if( (strcasecmp(equiv, "set-cookie") == 0)) { // ### make setCookie work on XML documents too; e.g. in case of <html:meta .....> HTMLDocumentImpl *d = static_cast<HTMLDocumentImpl *>(this); d->setCookie(content); }}bool DocumentImpl::prepareMouseEvent( bool readonly, int _x, int _y, MouseEvent *ev ){ if ( m_render ) { assert(m_render->isCanvas()); RenderObject::NodeInfo renderInfo(readonly, ev->type == MousePress); bool isInside = m_render->layer()->nodeAtPoint(renderInfo, _x, _y); ev->innerNode = renderInfo.innerNode(); if (renderInfo.URLElement()) { assert(renderInfo.URLElement()->isElementNode()); ElementImpl* e = static_cast<ElementImpl*>(renderInfo.URLElement()); DOMString href = khtml::parseURL(e->getAttribute(ATTR_HREF)); DOMString target = e->getAttribute(ATTR_TARGET); if (!target.isNull() && !href.isNull()) { ev->target = target; ev->url = href; } else ev->url = href;// qDebug("url: *%s*", ev->url.string().latin1()); } if (!readonly) updateRendering(); return isInside; } return false;}// DOM Section 1.1.1bool DocumentImpl::childAllowed( NodeImpl *newChild ){ // Documents may contain a maximum of one Element child if (newChild->nodeType() == Node::ELEMENT_NODE) { NodeImpl *c; for (c = firstChild(); c; c = c->nextSibling()) { if (c->nodeType() == Node::ELEMENT_NODE) return false; } } // Documents may contain a maximum of one DocumentType child if (newChild->nodeType() == Node::DOCUMENT_TYPE_NODE) { NodeImpl *c; for (c = firstChild(); c; c = c->nextSibling()) { if (c->nodeType() == Node::DOCUMENT_TYPE_NODE) return false; } } return childTypeAllowed(newChild->nodeType());}bool DocumentImpl::childTypeAllowed( unsigned short type ){ switch (type) { case Node::ELEMENT_NODE: case Node::PROCESSING_INSTRUCTION_NODE: case Node::COMMENT_NODE: case Node::DOCUMENT_TYPE_NODE: return true; break; default: return false; }}NodeImpl *DocumentImpl::cloneNode ( bool /*deep*/ ){ // Spec says cloning Document nodes is "implementation dependent" // so we do not support it... return 0;}NodeImpl::Id DocumentImpl::attrId(DOMStringImpl* _namespaceURI, DOMStringImpl *_name, bool readonly){ // Each document maintains a mapping of attrname -> id for every attr name // encountered in the document. // For attrnames without a prefix (no qualified element name) and without matching // namespace, the value defined in misc/htmlattrs.h is used. NodeImpl::Id id = 0; // First see if it's a HTML attribute name QConstString n(_name->s, _name->l); if (!_namespaceURI || !strcasecmp(_namespaceURI, XHTML_NAMESPACE)) { // we're in HTML namespace if we know the tag. // xhtml is lower case - case sensitive, easy to implement if ( htmlMode() == XHtml && (id = khtml::getAttrID(n.string().ascii(), _name->l)) ) return id; // compatibility: upper case - case insensitive if ( htmlMode() != XHtml && (id = khtml::getAttrID(n.string().lower().ascii(), _name->l )) ) return id; // ok, the fast path didn't work out, we need the full check } // now lets find out the namespace Q_UINT16 ns = noNamespace; if (_namespaceURI) { DOMString nsU(_namespaceURI); int nsID = XmlNamespaceTable::getNamespaceID(nsU, readonly); if (nsID != -1) ns = (Q_UINT16)nsID; } // Look in the m_attrNames array for the name // ### yeah, this is lame. use a dictionary / map instead DOMString nme(n.string()); // compatibility mode has to store upper case if (htmlMode() != XHtml) nme = nme.upper(); for (id = 0; id < m_attrNameCount; id++) if (DOMString(m_attrNames[id]) == nme) return makeId(ns, ATTR_LAST_ATTR+id); // unknown if (readonly) return 0; // Name not found in m_attrNames, so let's add it // ### yeah, this is lame. use a dictionary / map instead if (m_attrNameCount+1 > m_attrNameAlloc) { m_attrNameAlloc += 100; DOMStringImpl **newNames = new DOMStringImpl* [m_attrNameAlloc]; if (m_attrNames) { unsigned short i; for (i = 0; i < m_attrNameCount; i++) newNames[i] = m_attrNames[i]; delete [] m_attrNames; } m_attrNames = newNames; } id = m_attrNameCount++; m_attrNames[id] = nme.implementation(); m_attrNames[id]->ref(); return makeId(ns, ATTR_LAST_ATTR+id);}DOMString DocumentImpl::attrName(NodeImpl::Id _id) const{ DOMString result; if (localNamePart(_id) >= ATTR_LAST_ATTR) result = m_attrNames[localNamePart(_id)-ATTR_LAST_ATTR]; else result = getAttrName(_id); // Attribute names are always lowercase in the DOM for both // HTML and XHTML. if (getDocument()->isHTMLDocument() || getDocument()->htmlMode() == DocumentImpl::XHtml) return result.lower(); return result;}NodeImpl::Id DocumentImpl::tagId(DOMStringImpl* _namespaceURI, DOMStringImpl *_name, bool readonly){ if (!_name) return 0; // Each document maintains a mapping of tag name -> id for every tag name encountered // in the document. NodeImpl::Id id = 0; // First see if it's a HTML element name QConstString n(_name->s, _name->l); if (!_namespaceURI || !strcasecmp(_namespaceURI, XHTML_NAMESPACE)) { // we're in HTML namespace if we know the tag. // xhtml is lower case - case sensitive, easy to implement if ( htmlMode() == XHtml && (id = khtml::getTagID(n.string().ascii(), _name->l)) ) return id; // compatibility: upper case - case insensitive if ( htmlMode() != XHtml && (id = khtml::getTagID(n.string().lower().ascii(), _name->l )) ) return id; // ok, the fast path didn't work out, we need the full check } // now lets find out the namespace Q_UINT16 ns = noNamespace; if (_namespaceURI) { DOMString nsU(_namespaceURI); int nsID = XmlNamespaceTable::getNamespaceID(nsU, readonly); if (nsID != -1) ns = (Q_UINT16)nsID; } // Look in the m_elementNames array for the name // ### yeah, this is lame. use a dictionary / map instead DOMString nme(n.string()); // compatibility mode has to store upper case if (htmlMode() != XHtml) nme = nme.upper(); for (id = 0; id < m_elementNameCount; id++) if (DOMString(m_elementNames[id]) == nme) return makeId(ns, ID_LAST_TAG+id); // unknown if (readonly) return 0; // Name not found in m_elementNames, so let's add it if (m_elementNameCount+1 > m_elementNameAlloc) { m_elementNameAlloc += 100; DOMStringImpl **newNames = new DOMStringImpl* [m_elementNameAlloc]; // ### yeah, this is lame. use a dictionary / map instead if (m_elementNames) { unsigned short i; for (i = 0; i < m_elementNameCount; i++) newNames[i] = m_elementNames[i]; delete [] m_elementNames; } m_elementNames = newNames; } id = m_elementNameCount++; m_elementNames[id] = nme.implementation(); m_elementNames[id]->ref(); return makeId(ns, ID_LAST_TAG+id);}DOMString DocumentImpl::tagName(NodeImpl::Id _id) const{ if (localNamePart(_id) >= ID_LAST_TAG) return m_elementNames[localNamePart(_id)-ID_LAST_TAG]; else { // ### put them in a cache if (getDocument()->htmlMode() == DocumentImpl::XHtml) return getTagName(_id).lower(); else return getTagName(_id); }}DOMStringImpl* DocumentImpl::namespaceURI(NodeImpl::Id _id) const{ if (_id < ID_LAST_TAG) return htmlMode() == XHtml ? XmlNamespaceTable::getNamespaceURI(xhtmlNamespace).implementation() : 0; unsigned short ns = _id >> 16; if (!ns) return 0; return XmlNamespaceTable::getNamespaceURI(ns).implementation();}StyleSheetListImpl* DocumentImpl::styleSheets(){ return m_styleSheets;}DOMString DocumentImpl::preferredStylesheetSet(){ return m_preferredStylesheetSet;}DOMString DocumentImpl::selectedStylesheetSet(){ return view() ? view()->part()->d->m_sheetUsed : DOMString();}void DocumentImpl::setSelectedStylesheetSet(const DOMString& aString){ if (view()) { view()->part()->d->m_sheetUsed = aString.string(); updateStyleSelector(); if (renderer()) renderer()->repaint(); }}// This method is called whenever a top-level stylesheet has finished loading.void DocumentImpl::stylesheetLoaded(){ // Make sure we knew this sheet was pending, and that our count isn't out of sync. assert(m_pendingStylesheets > 0); m_pendingStylesheets--; updateStyleSelector(); }void DocumentImpl::updateStyleSelector(){ // Don't bother updating, since we haven't loaded all our style info yet. if (!haveStylesheetsLoaded()) return; recalcStyleSelector(); recalcStyle(Force);#if 0 m_styleSelectorDirty = true;#endif#ifdef INSTRUMENT_LAYOUT_SCHEDULING if (!ownerElement()) printf("Dirtying renderer from stylesheet load at time %d\n", elapsedTime());#endif if (renderer()) { renderer()->setNeedsLayoutAndMinMaxRecalc(); if (allDataReceived() && view()->haveDelayedLayoutScheduled()) { view()->unscheduleRelayout(); view()->scheduleRelayout(); } }}QStringList DocumentImpl::availableStyleSheets() const{ return m_availableSheets;}void DocumentImpl::recalcStyleSelector(){ if ( !m_render || !attached() ) return; QPtrList<StyleSheetImpl> oldStyleSheets = m_styleSheets->styleSheets; m_styleSheets->styleSheets.clear(); m_availableSheets.clear(); NodeImpl *n; for (n = this; n; n = n->traverseNextNode()) { StyleSheetImpl *sheet = 0; if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) { // Processing instruction (XML documents only) ProcessingInstructionImpl* pi = static_cast<ProcessingInstructionImpl*>(n); sheet = pi->sheet(); if (!sheet && !pi->localHref().isEmpty()) { // Processing instruction with reference to an element in this document - e.g. // <?xml-stylesheet href="#mystyle">, with the element // <foo id="mystyle">heading { color: red; }</foo> at some location in // the document ElementImpl* elem = getElementById(pi->localHref()); if (elem) { DOMString sheetText(""); NodeImpl *c; for (c = elem->firstChild(); c; c = c->nextSibling()) { if (c->nodeType() == Node::TEXT_NODE || c->nodeType() == Node::CDATA_SECTION_NODE) sheetText += c->nodeValue(); } CSSStyleSheetImpl *cssSheet = new CSSStyleSheetImpl(this); cssSheet->parseString(sheetText); pi->setStyleSheet(cssSheet); sheet = cssSheet; } } } else if (n->isHTMLElement() && (n->id() == ID_LINK || n->id() == ID_STYLE)) { ElementImpl *e = static_cast<ElementImpl *>(n); QString title = e->getAttribute( ATTR_TITLE ).string(); bool enabledViaScript = false; if (n->id() == ID_LINK) { // <LINK> element HTMLLinkElementImpl* l = static_cast<HTMLLinkElementImpl*>(n); if (l->isLoading() || l->isDisabled()) continue; if (!l->sheet()) title = QString::null; enabledViaScript = l->isEnabledViaScript(); } // Get the current preferred styleset. This is the // s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -