khtml Library API Documentation

html_headimpl.cpp

00001 
00023 // -------------------------------------------------------------------------
00024 
00025 #include "html/html_headimpl.h"
00026 #include "html/html_documentimpl.h"
00027 #include "xml/dom_textimpl.h"
00028 
00029 #include "khtmlview.h"
00030 #include "khtml_part.h"
00031 
00032 #include "misc/htmlhashes.h"
00033 #include "misc/loader.h"
00034 #include "misc/helper.h"
00035 
00036 #include "css/cssstyleselector.h"
00037 #include "css/css_stylesheetimpl.h"
00038 #include "css/csshelper.h"
00039 
00040 #include <kurl.h>
00041 #include <kdebug.h>
00042 
00043 using namespace khtml;
00044 
00045 NodeImpl::Id HTMLBaseElementImpl::id() const
00046 {
00047     return ID_BASE;
00048 }
00049 
00050 void HTMLBaseElementImpl::parseAttribute(AttributeImpl *attr)
00051 {
00052     switch(attr->id())
00053     {
00054     case ATTR_HREF:
00055     m_href = khtml::parseURL(attr->value());
00056     process();
00057     break;
00058     case ATTR_TARGET:
00059     m_target = attr->value();
00060     process();
00061     break;
00062     default:
00063         HTMLElementImpl::parseAttribute(attr);
00064     }
00065 }
00066 
00067 void HTMLBaseElementImpl::insertedIntoDocument()
00068 {
00069     HTMLElementImpl::insertedIntoDocument();
00070     process();
00071 }
00072 
00073 void HTMLBaseElementImpl::removedFromDocument()
00074 {
00075     HTMLElementImpl::removedFromDocument();
00076 
00077     // Since the document doesn't have a base element...
00078     // (This will break in the case of multiple base elements, but that's not valid anyway (?))
00079     getDocument()->setBaseURL( QString::null );
00080     getDocument()->setBaseTarget( QString::null );
00081 }
00082 
00083 void HTMLBaseElementImpl::process()
00084 {
00085     if (!inDocument())
00086     return;
00087 
00088     if(!m_href.isEmpty())
00089     getDocument()->setBaseURL( KURL( getDocument()->view()->part()->url(), m_href.string() ).url() );
00090 
00091     if(!m_target.isEmpty())
00092     getDocument()->setBaseTarget( m_target.string() );
00093 
00094     // ### should changing a document's base URL dynamically automatically update all images, stylesheets etc?
00095 }
00096 
00097 // -------------------------------------------------------------------------
00098 
00099 
00100 HTMLLinkElementImpl::~HTMLLinkElementImpl()
00101 {
00102     if(m_sheet) m_sheet->deref();
00103     if(m_cachedSheet) m_cachedSheet->deref(this);
00104 }
00105 
00106 NodeImpl::Id HTMLLinkElementImpl::id() const
00107 {
00108     return ID_LINK;
00109 }
00110 
00111 void HTMLLinkElementImpl::parseAttribute(AttributeImpl *attr)
00112 {
00113     switch (attr->id())
00114     {
00115     case ATTR_REL:
00116         m_rel = attr->value();
00117     process();
00118         break;
00119     case ATTR_HREF:
00120         m_url = getDocument()->completeURL( khtml::parseURL(attr->value()).string() );
00121     process();
00122         break;
00123     case ATTR_TYPE:
00124         m_type = attr->value();
00125     process();
00126         break;
00127     case ATTR_MEDIA:
00128         m_media = attr->value().string().lower();
00129     process();
00130         break;
00131     case ATTR_DISABLED:
00132         // ###
00133         break;
00134     default:
00135         HTMLElementImpl::parseAttribute(attr);
00136     }
00137 }
00138 
00139 void HTMLLinkElementImpl::process()
00140 {
00141     if (!inDocument())
00142     return;
00143 
00144     QString type = m_type.string().lower();
00145     QString rel = m_rel.string().lower();
00146 
00147     KHTMLPart* part = getDocument()->view() ? getDocument()->view()->part() : 0;
00148 
00149     // IE extension: location of small icon for locationbar / bookmarks
00150     // Uses both "shortcut icon" and "icon"
00151 
00152     if ( part && rel.contains("icon") && !m_url.isEmpty() && !part->parentPart())
00153         part->browserExtension()->setIconURL( KURL(m_url.string()) );
00154 
00155     // Stylesheet
00156     if(type.contains("text/css") || rel.contains("stylesheet")) {
00157         // no need to load style sheets which aren't for the screen output
00158         // ### there may be in some situations e.g. for an editor or script to manipulate
00159         if( m_media.isNull() || m_media.contains("screen") || m_media.contains("all") || m_media.contains("print") ) {
00160             m_loading = true;
00161             QString chset = getAttribute( ATTR_CHARSET ).string();
00162             if (m_cachedSheet)
00163         m_cachedSheet->deref(this);
00164             m_cachedSheet = getDocument()->docLoader()->requestStyleSheet(m_url, chset);
00165             if (m_cachedSheet)
00166         m_cachedSheet->ref(this);
00167         }
00168     }
00169     else if (m_sheet) {
00170     // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
00171     m_sheet->deref();
00172     m_sheet = 0;
00173     getDocument()->updateStyleSelector();
00174     }
00175 }
00176 
00177 void HTMLLinkElementImpl::insertedIntoDocument()
00178 {
00179     HTMLElementImpl::insertedIntoDocument();
00180     process();
00181 }
00182 
00183 void HTMLLinkElementImpl::removedFromDocument()
00184 {
00185     HTMLElementImpl::removedFromDocument();
00186     process();
00187 }
00188 
00189 void HTMLLinkElementImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheetStr)
00190 {
00191 //    kdDebug( 6030 ) << "HTMLLinkElement::setStyleSheet()" << endl;
00192 //    kdDebug( 6030 ) << "**** current medium: " << m_media << endl;
00193 
00194     if (m_sheet)
00195     m_sheet->deref();
00196     m_sheet = new CSSStyleSheetImpl(this, url);
00197     kdDebug( 6030 ) << "style sheet parse mode strict = " << ( getDocument()->parseMode() == DocumentImpl::Strict ) << endl;
00198     m_sheet->ref();
00199     m_sheet->parseString( sheetStr, getDocument()->parseMode() == DocumentImpl::Strict );
00200 
00201     MediaListImpl *media = new MediaListImpl( m_sheet, m_media );
00202     m_sheet->setMedia( media );
00203 
00204     m_loading = false;
00205 
00206     getDocument()->updateStyleSelector();
00207 }
00208 
00209 bool HTMLLinkElementImpl::isLoading() const
00210 {
00211 //    kdDebug( 6030 ) << "link: checking if loading!" << endl;
00212     if(m_loading) return true;
00213     if(!m_sheet) return false;
00214     //if(!m_sheet->isCSSStyleSheet()) return false;
00215     return static_cast<CSSStyleSheetImpl *>(m_sheet)->isLoading();
00216 }
00217 
00218 void HTMLLinkElementImpl::sheetLoaded()
00219 {
00220     getDocument()->updateStyleSelector();
00221 }
00222 
00223 // -------------------------------------------------------------------------
00224 
00225 NodeImpl::Id HTMLMetaElementImpl::id() const
00226 {
00227     return ID_META;
00228 }
00229 
00230 void HTMLMetaElementImpl::parseAttribute(AttributeImpl *attr)
00231 {
00232     switch(attr->id())
00233     {
00234     case ATTR_HTTP_EQUIV:
00235     m_equiv = attr->value();
00236     process();
00237     break;
00238     case ATTR_CONTENT:
00239     m_content = attr->value();
00240     process();
00241     break;
00242     case ATTR_NAME:
00243       break;
00244     default:
00245         HTMLElementImpl::parseAttribute(attr);
00246     }
00247 }
00248 
00249 void HTMLMetaElementImpl::insertedIntoDocument()
00250 {
00251     HTMLElementImpl::insertedIntoDocument();
00252     process();
00253 }
00254 
00255 void HTMLMetaElementImpl::process()
00256 {
00257     // Get the document to process the tag, but only if we're actually part of DOM tree (changing a meta tag while
00258     // it's not in the tree shouldn't have any effect on the document)
00259     if (inDocument() && !m_equiv.isNull() && !m_content.isNull())
00260     getDocument()->processHttpEquiv(m_equiv,m_content);
00261 }
00262 
00263 // -------------------------------------------------------------------------
00264 
00265 NodeImpl::Id HTMLScriptElementImpl::id() const
00266 {
00267     return ID_SCRIPT;
00268 }
00269 
00270 DOMString HTMLScriptElementImpl::text() const
00271 {
00272     if (firstChild() && firstChild()->nodeType() == Node::TEXT_NODE) {
00273         return firstChild()->nodeValue();
00274     }
00275     return "";
00276 }
00277 
00278 void HTMLScriptElementImpl::setText(const DOMString& str)
00279 {
00280     int exceptioncode = 0;
00281     if (firstChild() && firstChild()->nodeType() == Node::TEXT_NODE) {
00282         static_cast<DOM::TextImpl *>(firstChild())->setData(str, exceptioncode);
00283         return;
00284     }
00285     // No child text node found, creating one
00286     DOM::TextImpl* t = getDocument()->createTextNode(str.implementation());
00287     appendChild(t, exceptioncode);
00288 }
00289 
00290 // -------------------------------------------------------------------------
00291 
00292 HTMLStyleElementImpl::~HTMLStyleElementImpl()
00293 {
00294     if(m_sheet) m_sheet->deref();
00295 }
00296 
00297 NodeImpl::Id HTMLStyleElementImpl::id() const
00298 {
00299     return ID_STYLE;
00300 }
00301 
00302 // other stuff...
00303 void HTMLStyleElementImpl::parseAttribute(AttributeImpl *attr)
00304 {
00305     switch (attr->id())
00306     {
00307     case ATTR_TYPE:
00308     case ATTR_MEDIA:
00309     break;
00310     default:
00311         HTMLElementImpl::parseAttribute(attr);
00312     }
00313 }
00314 
00315 void HTMLStyleElementImpl::insertedIntoDocument()
00316 {
00317     HTMLElementImpl::insertedIntoDocument();
00318     getDocument()->updateStyleSelector();
00319 }
00320 
00321 void HTMLStyleElementImpl::removedFromDocument()
00322 {
00323     HTMLElementImpl::removedFromDocument();
00324     getDocument()->updateStyleSelector();
00325 }
00326 
00327 void HTMLStyleElementImpl::childrenChanged()
00328 {
00329     HTMLElementImpl::childrenChanged();
00330 
00331     DOMString text = "";
00332 
00333     for (NodeImpl *c = firstChild(); c != 0; c = c->nextSibling()) {
00334     if ((c->nodeType() == Node::TEXT_NODE) ||
00335         (c->nodeType() == Node::CDATA_SECTION_NODE) ||
00336         (c->nodeType() == Node::COMMENT_NODE))
00337         text += c->nodeValue();
00338     }
00339 
00340     if(m_sheet)
00341     m_sheet->deref();
00342     m_sheet = new CSSStyleSheetImpl(this);
00343     m_sheet->ref();
00344     m_sheet->parseString( text, (getDocument()->parseMode() == DocumentImpl::Strict) );
00345     getDocument()->updateStyleSelector();
00346 }
00347 
00348 bool HTMLStyleElementImpl::isLoading() const
00349 {
00350     if(!m_sheet) return false;
00351     return static_cast<CSSStyleSheetImpl *>(m_sheet)->isLoading();
00352 }
00353 
00354 void HTMLStyleElementImpl::sheetLoaded()
00355 {
00356     getDocument()->updateStyleSelector();
00357 }
00358 
00359 // -------------------------------------------------------------------------
00360 
00361 NodeImpl::Id HTMLTitleElementImpl::id() const
00362 {
00363     return ID_TITLE;
00364 }
00365 
00366 void HTMLTitleElementImpl::insertedIntoDocument()
00367 {
00368     HTMLElementImpl::insertedIntoDocument();
00369     getDocument()->setTitle(m_title);
00370 }
00371 
00372 void HTMLTitleElementImpl::removedFromDocument()
00373 {
00374     HTMLElementImpl::removedFromDocument();
00375     // Title element removed, so we have no title... we ignore the case of multiple title elements, as it's invalid
00376     // anyway (?)
00377     getDocument()->setTitle(DOMString());
00378 }
00379 
00380 void HTMLTitleElementImpl::childrenChanged()
00381 {
00382     HTMLElementImpl::childrenChanged();
00383 
00384     m_title = "";
00385     for (NodeImpl *c = firstChild(); c != 0; c = c->nextSibling()) {
00386     if ((c->nodeType() == Node::TEXT_NODE) || (c->nodeType() == Node::CDATA_SECTION_NODE))
00387         m_title += c->nodeValue();
00388     }
00389     if (inDocument())
00390     getDocument()->setTitle(m_title);
00391 }
00392 
00393 DOMString HTMLTitleElementImpl::text()
00394 {
00395     if (firstChild() && firstChild()->nodeType() == Node::TEXT_NODE) {
00396         return firstChild()->nodeValue();
00397     }
00398     return "";
00399 }
00400 
00401 void HTMLTitleElementImpl::setText( const DOMString& str )
00402 {
00403     int exceptioncode = 0;
00404     // Look for an existing text child node
00405     DOM::NodeListImpl* nl(childNodes());
00406     if (nl)
00407     {
00408         for (unsigned int i = 0; i < nl->length(); i++) {
00409             if (nl->item(i)->nodeType() == DOM::Node::TEXT_NODE) {
00410                 static_cast<DOM::TextImpl *>(nl->item(i))->setData(str, exceptioncode);
00411                 return;
00412             }
00413         }
00414         delete nl;
00415     }
00416     // No child text node found, creating one
00417     DOM::TextImpl* t = getDocument()->createTextNode(str.implementation());
00418     appendChild(t, exceptioncode);
00419 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:16:34 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001