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, const DOM::DOMString &charset)
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->setCharset(charset);
00141     m_styleSheet->ref();
00142 
00143     CSSStyleSheetImpl *parent = parentStyleSheet();
00144     m_styleSheet->parseString( sheet, parent ? parent->useStrictParsing() : true );
00145     m_loading = false;
00146     m_done = true;
00147 
00148     checkLoaded();
00149 }
00150 
00151 void CSSImportRuleImpl::error(int /*err*/, const QString &/*text*/)
00152 {
00153     if ( m_styleSheet ) {
00154         m_styleSheet->setParent(0);
00155         m_styleSheet->deref();
00156     }
00157     m_styleSheet = 0;
00158 
00159     m_loading = false;
00160     m_done = true;
00161 
00162     checkLoaded();
00163 }
00164 
00165 bool CSSImportRuleImpl::isLoading()
00166 {
00167     return ( m_loading || (m_styleSheet && m_styleSheet->isLoading()) );
00168 }
00169 
00170 void CSSImportRuleImpl::init()
00171 {
00172     m_loading = 0;
00173     m_done = false;
00174     khtml::DocLoader *docLoader = 0;
00175     StyleBaseImpl *root = this;
00176     StyleBaseImpl *parent;
00177     while ( ( parent = root->parent()) )
00178     root = parent;
00179     if (root->isCSSStyleSheet())
00180     docLoader = static_cast<CSSStyleSheetImpl*>(root)->docLoader();
00181 
00182     DOMString absHref = m_strHref;
00183     CSSStyleSheetImpl *parentSheet = parentStyleSheet();
00184     if (!parentSheet->href().isNull()) {
00185       // use parent styleheet's URL as the base URL
00186       absHref = KURL(KURL( parentSheet->href().string() ),m_strHref.string()).url();
00187     }
00188 /*
00189     else {
00190       // use documents's URL as the base URL
00191       DocumentImpl *doc = static_cast<CSSStyleSheetImpl*>(root)->doc();
00192       absHref = KURL(doc->URL(),m_strHref.string()).url();
00193     }
00194 */
00195     // Check for a cycle in our import chain.  If we encounter a stylesheet
00196     // in our parent chain with the same URL, then just bail.
00197     for ( parent = static_cast<StyleBaseImpl*>( this )->parent();
00198          parent;
00199          parent = parent->parent() )
00200         if ( absHref == parent->baseURL().url() )
00201             return;
00202 
00203     m_cachedSheet = docLoader->requestStyleSheet(absHref, parentStyleSheet()->charset().string());
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) {
00329         DOMString str;
00330         for (CSSSelector *s = m_selector->first(); s; s = m_selector->next()) {
00331             if (s != m_selector->getFirst())
00332                 str += ", ";
00333             str += s->selectorText();
00334         }
00335         return str;
00336     }
00337     return DOMString();
00338 }
00339 
00340 void CSSStyleRuleImpl::setSelectorText(DOM::DOMString /*str*/)
00341 {
00342     // ###
00343 }
00344 
00345 bool CSSStyleRuleImpl::parseString( const DOMString &/*string*/, bool )
00346 {
00347     // ###
00348     return false;
00349 }
00350 
00351 void CSSStyleRuleImpl::setDeclaration( CSSStyleDeclarationImpl *style)
00352 {
00353     if ( m_style != style ) {
00354         if(m_style) m_style->deref();
00355         m_style = style;
00356         if(m_style) m_style->ref();
00357     }
00358 }
00359 
00360 void CSSStyleRuleImpl::setNonCSSHints()
00361 {
00362     CSSSelector *s = m_selector->first();
00363     while ( s ) {
00364     s->nonCSSHint = true;
00365     s = m_selector->next();
00366     }
00367 }
00368 
00369 void CSSRuleListImpl::deleteRule ( unsigned long index )
00370 {
00371     CSSRuleImpl *rule = m_lstCSSRules.take( index );
00372     if( rule )
00373         rule->deref();
00374     else {
00375          // ### Throw INDEX_SIZE_ERR exception here (TODO)
00376     }
00377 }
00378 
00379 unsigned long CSSRuleListImpl::insertRule( CSSRuleImpl *rule,
00380                                            unsigned long index )
00381 {
00382     if( rule && m_lstCSSRules.insert( index, rule ) )
00383     {
00384         rule->ref();
00385         return index;
00386     }
00387 
00388     // ### Should throw INDEX_SIZE_ERR exception instead! (TODO)
00389     return 0;
00390 }
00391 
KDE Home | KDE Accessibility Home | Description of Access Keys