khtml Library API Documentation

css_ruleimpl.cpp

00001 
00023 #include "dom/css_rule.h"
00024 #include "dom/css_stylesheet.h"
00025 #include "dom/dom_exception.h"
00026 #include "dom/dom_string.h"
00027 
00028 #include "css/css_stylesheetimpl.h"
00029 #include "css/css_valueimpl.h"
00030 #include "css/cssparser.h"
00031 #include "css/css_ruleimpl.h"
00032 
00033 #include "misc/loader.h"
00034 #include "misc/htmltags.h"
00035 #include "misc/htmlattrs.h"
00036 #include "xml/dom_docimpl.h"
00037 
00038 using namespace DOM;
00039 
00040 #include <kdebug.h>
00041 
00042 CSSStyleSheetImpl *CSSRuleImpl::parentStyleSheet() const
00043 {
00044     return ( m_parent && m_parent->isCSSStyleSheet() )  ?
00045     static_cast<CSSStyleSheetImpl *>(m_parent) : 0;
00046 }
00047 
00048 CSSRuleImpl *CSSRuleImpl::parentRule() const
00049 {
00050     return ( m_parent && m_parent->isRule() )  ?
00051     static_cast<CSSRuleImpl *>(m_parent) : 0;
00052 }
00053 
00054 DOM::DOMString CSSRuleImpl::cssText() const
00055 {
00056     // ###
00057     return DOMString();
00058 }
00059 
00060 void CSSRuleImpl::setCssText(DOM::DOMString /*str*/)
00061 {
00062     // ###
00063 }
00064 
00065 // ---------------------------------------------------------------------------
00066 
00067 CSSFontFaceRuleImpl::CSSFontFaceRuleImpl(StyleBaseImpl *parent)
00068     : CSSRuleImpl(parent)
00069 {
00070     m_type = CSSRule::FONT_FACE_RULE;
00071     m_style = 0;
00072 }
00073 
00074 CSSFontFaceRuleImpl::~CSSFontFaceRuleImpl()
00075 {
00076     if(m_style) m_style->deref();
00077 }
00078 
00079 // --------------------------------------------------------------------------
00080 
00081 CSSImportRuleImpl::CSSImportRuleImpl( StyleBaseImpl *parent,
00082                                       const DOM::DOMString &href,
00083                                       MediaListImpl *media )
00084     : CSSRuleImpl(parent)
00085 {
00086     m_type = CSSRule::IMPORT_RULE;
00087 
00088     m_lstMedia = media;
00089     if ( !m_lstMedia )
00090     m_lstMedia = new MediaListImpl( this, DOMString() );
00091     m_lstMedia->setParent( this );
00092     m_lstMedia->ref();
00093 
00094     m_strHref = href;
00095     m_styleSheet = 0;
00096 
00097     m_cachedSheet = 0;
00098 
00099     init();
00100 }
00101 CSSImportRuleImpl::CSSImportRuleImpl( StyleBaseImpl *parent,
00102                                       const DOM::DOMString &href,
00103                                       const DOM::DOMString &media )
00104     : CSSRuleImpl(parent)
00105 {
00106     m_type = CSSRule::IMPORT_RULE;
00107 
00108     m_lstMedia = new MediaListImpl( this, media );
00109     m_lstMedia->ref();
00110 
00111     m_strHref = href;
00112     m_styleSheet = 0;
00113 
00114     m_cachedSheet = 0;
00115 
00116     init();
00117 }
00118 
00119 CSSImportRuleImpl::~CSSImportRuleImpl()
00120 {
00121     if( m_lstMedia ) {
00122     m_lstMedia->setParent( 0 );
00123     m_lstMedia->deref();
00124     }
00125     if(m_styleSheet) {
00126         m_styleSheet->setParent(0);
00127         m_styleSheet->deref();
00128     }
00129 
00130     if(m_cachedSheet) m_cachedSheet->deref(this);
00131 }
00132 
00133 void CSSImportRuleImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet)
00134 {
00135     if ( m_styleSheet ) {
00136         m_styleSheet->setParent(0);
00137         m_styleSheet->deref();
00138     }
00139     m_styleSheet = new CSSStyleSheetImpl(this, url);
00140     m_styleSheet->ref();
00141 
00142     CSSStyleSheetImpl *parent = parentStyleSheet();
00143     m_styleSheet->parseString( sheet, parent ? parent->useStrictParsing() : true );
00144     m_loading = false;
00145     m_done = true;
00146 
00147     checkLoaded();
00148 }
00149 
00150 void CSSImportRuleImpl::error(int /*err*/, const QString &/*text*/)
00151 {
00152     if ( m_styleSheet ) {
00153         m_styleSheet->setParent(0);
00154         m_styleSheet->deref();
00155     }
00156     m_styleSheet = 0;
00157 
00158     m_loading = false;
00159     m_done = true;
00160 
00161     checkLoaded();
00162 }
00163 
00164 bool CSSImportRuleImpl::isLoading()
00165 {
00166     return ( m_loading || (m_styleSheet && m_styleSheet->isLoading()) );
00167 }
00168 
00169 void CSSImportRuleImpl::init()
00170 {
00171     m_loading = 0;
00172     m_done = false;
00173     khtml::DocLoader *docLoader = 0;
00174     StyleBaseImpl *root = this;
00175     StyleBaseImpl *parent;
00176     while ( ( parent = root->parent()) )
00177     root = parent;
00178     if (root->isCSSStyleSheet())
00179     docLoader = static_cast<CSSStyleSheetImpl*>(root)->docLoader();
00180 
00181     DOMString absHref = m_strHref;
00182     CSSStyleSheetImpl *parentSheet = parentStyleSheet();
00183     if (!parentSheet->href().isNull()) {
00184       // use parent styleheet's URL as the base URL
00185       absHref = KURL(KURL( parentSheet->href().string() ),m_strHref.string()).url();
00186     }
00187 /*
00188     else {
00189       // use documents's URL as the base URL
00190       DocumentImpl *doc = static_cast<CSSStyleSheetImpl*>(root)->doc();
00191       absHref = KURL(doc->URL(),m_strHref.string()).url();
00192     }
00193 */
00194     // Check for a cycle in our import chain.  If we encounter a stylesheet
00195     // in our parent chain with the same URL, then just bail.
00196     for ( parent = static_cast<StyleBaseImpl*>( this )->parent();
00197          parent;
00198          parent = parent->parent() )
00199         if ( absHref == parent->baseURL().url() )
00200             return;
00201 
00202     // ### pass correct charset here!!
00203     m_cachedSheet = docLoader->requestStyleSheet(absHref, QString::null);
00204 
00205     if (m_cachedSheet)
00206     {
00207       m_cachedSheet->ref(this);
00208 
00209       // If the imported sheet is in the cache, then setStyleSheet gets called,
00210       // and the sheet even gets parsed (via parseString).  In this case we have
00211       // loaded (even if our subresources haven't), so if we have stylesheet after
00212       // checking the cache, then we've clearly loaded. -dwh
00213       // This can also happen when error() is called from within ref(). In either case,
00214       // m_done is set to true.
00215       if (!m_done)
00216     m_loading = true;
00217     }
00218 }
00219 
00220 // --------------------------------------------------------------------------
00221 CSSMediaRuleImpl::CSSMediaRuleImpl( StyleBaseImpl *parent, MediaListImpl *mediaList, CSSRuleListImpl *ruleList )
00222     :   CSSRuleImpl( parent )
00223 {
00224     m_type = CSSRule::MEDIA_RULE;
00225     m_lstMedia = mediaList;
00226     m_lstMedia->ref();
00227     m_lstCSSRules = ruleList;
00228     m_lstCSSRules->ref();
00229 }
00230 
00231 CSSMediaRuleImpl::CSSMediaRuleImpl(StyleBaseImpl *parent)
00232     :   CSSRuleImpl( parent )
00233 {
00234     m_type = CSSRule::MEDIA_RULE;
00235     m_lstMedia = 0;
00236     m_lstCSSRules = new CSSRuleListImpl();
00237     m_lstCSSRules->ref();
00238 }
00239 
00240 CSSMediaRuleImpl::CSSMediaRuleImpl( StyleBaseImpl *parent, const DOM::DOMString &media )
00241 :   CSSRuleImpl( parent )
00242 {
00243     m_type = CSSRule::MEDIA_RULE;
00244     m_lstMedia = new MediaListImpl( this, media );
00245     m_lstMedia->ref();
00246     m_lstCSSRules = new CSSRuleListImpl();
00247     m_lstCSSRules->ref();
00248 }
00249 
00250 CSSMediaRuleImpl::~CSSMediaRuleImpl()
00251 {
00252     if( m_lstMedia ) {
00253     m_lstMedia->setParent( 0 );
00254         m_lstMedia->deref();
00255     }
00256     for ( unsigned int i = 0; i < m_lstCSSRules->length(); ++i )
00257         m_lstCSSRules->item(  i )->setParent(  0 );
00258     m_lstCSSRules->deref();
00259 }
00260 
00261 unsigned long CSSMediaRuleImpl::append( CSSRuleImpl *rule )
00262 {
00263     return rule ? m_lstCSSRules->insertRule( rule, m_lstCSSRules->length() ) : 0;
00264 }
00265 
00266 unsigned long CSSMediaRuleImpl::insertRule( const DOMString &rule,
00267                                             unsigned long index )
00268 {
00269     CSSParser p( strictParsing );
00270     CSSRuleImpl *newRule = p.parseRule( parentStyleSheet(), rule );
00271 
00272     return newRule ? m_lstCSSRules->insertRule( newRule, index ) : 0;
00273 }
00274 
00275 CSSRuleListImpl::~CSSRuleListImpl()
00276 {
00277     CSSRuleImpl* rule;
00278     while ( !m_lstCSSRules.isEmpty() && ( rule = m_lstCSSRules.take( 0 ) ) )
00279         rule->deref();
00280 }
00281 
00282 // ---------------------------------------------------------------------------
00283 
00284 CSSPageRuleImpl::CSSPageRuleImpl(StyleBaseImpl *parent)
00285     : CSSRuleImpl(parent)
00286 {
00287     m_type = CSSRule::PAGE_RULE;
00288     m_style = 0;
00289 }
00290 
00291 CSSPageRuleImpl::~CSSPageRuleImpl()
00292 {
00293     if(m_style) m_style->deref();
00294 }
00295 
00296 DOM::DOMString CSSPageRuleImpl::selectorText() const
00297 {
00298     // ###
00299     return DOMString();
00300 }
00301 
00302 void CSSPageRuleImpl::setSelectorText(DOM::DOMString /*str*/)
00303 {
00304     // ###
00305 }
00306 
00307 // --------------------------------------------------------------------------
00308 
00309 CSSStyleRuleImpl::CSSStyleRuleImpl(StyleBaseImpl *parent)
00310     : CSSRuleImpl(parent)
00311 {
00312     m_type = CSSRule::STYLE_RULE;
00313     m_style = 0;
00314     m_selector = 0;
00315 }
00316 
00317 CSSStyleRuleImpl::~CSSStyleRuleImpl()
00318 {
00319     if(m_style) {
00320     m_style->setParent( 0 );
00321     m_style->deref();
00322     }
00323     delete m_selector;
00324 }
00325 
00326 DOM::DOMString CSSStyleRuleImpl::selectorText() const
00327 {
00328     if ( m_selector && m_selector->first() ) {
00329         // ### m_selector will be a single selector hopefully. so ->first() will disappear
00330         CSSSelector* cs = m_selector->first();
00331         //cs->print(); // debug
00332         return cs->selectorText();
00333     }
00334     return DOMString();
00335 }
00336 
00337 void CSSStyleRuleImpl::setSelectorText(DOM::DOMString /*str*/)
00338 {
00339     // ###
00340 }
00341 
00342 bool CSSStyleRuleImpl::parseString( const DOMString &/*string*/, bool )
00343 {
00344     // ###
00345     return false;
00346 }
00347 
00348 void CSSStyleRuleImpl::setDeclaration( CSSStyleDeclarationImpl *style)
00349 {
00350     if ( m_style != style ) {
00351         if(m_style) m_style->deref();
00352         m_style = style;
00353         if(m_style) m_style->ref();
00354     }
00355 }
00356 
00357 void CSSStyleRuleImpl::setNonCSSHints()
00358 {
00359     CSSSelector *s = m_selector->first();
00360     while ( s ) {
00361     s->nonCSSHint = true;
00362     s = m_selector->next();
00363     }
00364 }
00365 
00366 void CSSRuleListImpl::deleteRule ( unsigned long index )
00367 {
00368     CSSRuleImpl *rule = m_lstCSSRules.take( index );
00369     if( rule )
00370         rule->deref();
00371     else
00372         ; // ### Throw INDEX_SIZE_ERR exception here (TODO)
00373 }
00374 
00375 unsigned long CSSRuleListImpl::insertRule( CSSRuleImpl *rule,
00376                                            unsigned long index )
00377 {
00378     if( rule && m_lstCSSRules.insert( index, rule ) )
00379     {
00380         rule->ref();
00381         return index;
00382     }
00383 
00384     // ### Should throw INDEX_SIZE_ERR exception instead! (TODO)
00385     return 0;
00386 }
00387 
KDE Logo
This file is part of the documentation for khtml Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed May 12 09:09:45 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2003