khtml Library API Documentation

css_stylesheetimpl.cpp

00001 
00024 //#define CSS_STYLESHEET_DEBUG
00025 
00026 #include "dom/dom_string.h"
00027 #include "dom/dom_exception.h"
00028 #include "dom/css_stylesheet.h"
00029 #include "dom/css_rule.h"
00030 
00031 #include "css/css_ruleimpl.h"
00032 #include "css/css_valueimpl.h"
00033 #include "css/cssparser.h"
00034 #include "css/css_stylesheetimpl.h"
00035 
00036 #include "xml/dom_nodeimpl.h"
00037 #include "html/html_documentimpl.h"
00038 #include "misc/loader.h"
00039 
00040 #include <kdebug.h>
00041 
00042 using namespace DOM;
00043 using namespace khtml;
00044 // --------------------------------------------------------------------------------
00045 
00046 StyleSheetImpl::StyleSheetImpl(StyleSheetImpl *parentSheet, DOMString href)
00047     : StyleListImpl(parentSheet)
00048 {
00049     m_disabled = false;
00050     m_media = 0;
00051     m_parentNode = 0;
00052     m_strHref = href;
00053 }
00054 
00055 
00056 StyleSheetImpl::StyleSheetImpl(DOM::NodeImpl *parentNode, DOMString href)
00057     : StyleListImpl()
00058 {
00059     m_parentNode = parentNode;
00060     m_disabled = false;
00061     m_media = 0;
00062     m_strHref = href;
00063 }
00064 
00065 StyleSheetImpl::StyleSheetImpl(StyleBaseImpl *owner, DOMString href)
00066     : StyleListImpl(owner)
00067 {
00068     m_disabled = false;
00069     m_media = 0;
00070     m_parentNode = 0;
00071     m_strHref = href;
00072 }
00073 
00074 StyleSheetImpl::~StyleSheetImpl()
00075 {
00076     if(m_media) {
00077     m_media->setParent( 0 );
00078     m_media->deref();
00079     }
00080 }
00081 
00082 bool StyleSheetImpl::disabled() const
00083 {
00084     return m_disabled;
00085 }
00086 
00087 void StyleSheetImpl::setDisabled( bool disabled )
00088 {
00089     m_disabled = disabled;
00090 }
00091 
00092 NodeImpl *StyleSheetImpl::ownerNode() const
00093 {
00094     return m_parentNode;
00095 }
00096 
00097 StyleSheetImpl *StyleSheetImpl::parentStyleSheet() const
00098 {
00099     if( !m_parent ) return 0;
00100     if( m_parent->isStyleSheet() ) return static_cast<StyleSheetImpl *>(m_parent);
00101     return 0;
00102 }
00103 
00104 DOMString StyleSheetImpl::href() const
00105 {
00106     return m_strHref;
00107 }
00108 
00109 DOMString StyleSheetImpl::title() const
00110 {
00111     return m_strTitle;
00112 }
00113 
00114 MediaListImpl *StyleSheetImpl::media() const
00115 {
00116     return m_media;
00117 }
00118 
00119 void StyleSheetImpl::setMedia( MediaListImpl *media )
00120 {
00121     if( media )
00122     media->ref();
00123     if( m_media )
00124     m_media->deref();
00125     m_media = media;
00126 }
00127 
00128 // -----------------------------------------------------------------------
00129 
00130 
00131 CSSStyleSheetImpl::CSSStyleSheetImpl(CSSStyleSheetImpl *parentSheet, DOMString href)
00132     : StyleSheetImpl(parentSheet, href)
00133 {
00134     m_lstChildren = new QPtrList<StyleBaseImpl>;
00135     m_doc = 0;
00136     m_implicit = false;
00137 }
00138 
00139 CSSStyleSheetImpl::CSSStyleSheetImpl(DOM::NodeImpl *parentNode, DOMString href, bool _implicit)
00140     : StyleSheetImpl(parentNode, href)
00141 {
00142     m_lstChildren = new QPtrList<StyleBaseImpl>;
00143     m_doc = parentNode->getDocument();
00144     m_implicit = _implicit;
00145 }
00146 
00147 CSSStyleSheetImpl::CSSStyleSheetImpl(CSSRuleImpl *ownerRule, DOMString href)
00148     : StyleSheetImpl(ownerRule, href)
00149 {
00150     m_lstChildren = new QPtrList<StyleBaseImpl>;
00151     m_doc = 0;
00152     m_implicit = false;
00153 }
00154 
00155 CSSStyleSheetImpl::CSSStyleSheetImpl(DOM::NodeImpl *parentNode, CSSStyleSheetImpl *orig)
00156     : StyleSheetImpl(parentNode, orig->m_strHref)
00157 {
00158     m_lstChildren = new QPtrList<StyleBaseImpl>;
00159     StyleBaseImpl *rule;
00160     for ( rule = orig->m_lstChildren->first(); rule != 0; rule = orig->m_lstChildren->next() )
00161     {
00162         m_lstChildren->append(rule);
00163         rule->setParent(this);
00164     }
00165     m_doc = parentNode->getDocument();
00166     m_implicit = false;
00167 }
00168 
00169 CSSStyleSheetImpl::CSSStyleSheetImpl(CSSRuleImpl *ownerRule, CSSStyleSheetImpl *orig)
00170     : StyleSheetImpl(ownerRule, orig->m_strHref)
00171 {
00172     m_lstChildren = new QPtrList<StyleBaseImpl>;
00173     StyleBaseImpl *rule;
00174     for ( rule = orig->m_lstChildren->first(); rule != 0; rule = orig->m_lstChildren->next() )
00175     {
00176         m_lstChildren->append(rule);
00177         rule->setParent(this);
00178     }
00179     m_doc  = 0;
00180     m_implicit = false;
00181 }
00182 
00183 CSSStyleSheetImpl::~CSSStyleSheetImpl()
00184 {
00185     // m_lstChildren is deleted in StyleListImpl
00186 }
00187 
00188 CSSRuleImpl *CSSStyleSheetImpl::ownerRule() const
00189 {
00190     if( !m_parent ) return 0;
00191     if( m_parent->isRule() ) return static_cast<CSSRuleImpl *>(m_parent);
00192     return 0;
00193 }
00194 
00195 CSSRuleList CSSStyleSheetImpl::cssRules()
00196 {
00197     return this;
00198 }
00199 
00200 unsigned long CSSStyleSheetImpl::insertRule( const DOMString &rule, unsigned long index, int &exceptioncode )
00201 {
00202     exceptioncode = 0;
00203     if(index > m_lstChildren->count()) {
00204         exceptioncode = DOMException::INDEX_SIZE_ERR;
00205         return 0;
00206     }
00207     const QString preprocessed = preprocess(rule.string());
00208     const QChar *curP = preprocessed.unicode();
00209     const QChar *endP = preprocessed.unicode() + preprocessed.length();
00210     CSSRuleImpl *r = parseRule(curP, endP);
00211 
00212     if(!r) {
00213         exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
00214         return 0;
00215     }
00216     // ###
00217     // HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the specified index e.g. if an
00218     //@import rule is inserted after a standard rule set or other at-rule.
00219     m_lstChildren->insert(index, r);
00220     return index;
00221 }
00222 
00223 void CSSStyleSheetImpl::deleteRule( unsigned long index, int &exceptioncode )
00224 {
00225     exceptioncode = 0;
00226     StyleBaseImpl *b = m_lstChildren->take(index);
00227     if(!b) {
00228         exceptioncode = DOMException::INDEX_SIZE_ERR;
00229         return;
00230     }
00231     b->deref();
00232 }
00233 
00234 bool CSSStyleSheetImpl::parseString(const DOMString &string, bool strict)
00235 {
00236     strictParsing = strict;
00237     const QString preprocessed = preprocess(string.string());
00238 
00239 #ifdef CSS_STYLESHEET_DEBUG
00240     kdDebug( 6080 ) << "parsing sheet, len=" << string.length() << ", sheet is " << string.string() << endl;
00241 #endif
00242 
00243     const QChar *curP = preprocessed.unicode();
00244     const QChar *endP = preprocessed.unicode() + preprocessed.length();
00245 
00246 #ifdef CSS_STYLESHEET_DEBUG
00247     kdDebug( 6080 ) << "preprocessed sheet, len=" << preprocessed.length() << ", sheet is " << preprocessed << endl;
00248 #endif
00249 
00250     while (curP && (curP < endP))
00251     {
00252         CSSRuleImpl *rule = parseRule(curP, endP);
00253         if(rule)
00254         {
00255            m_lstChildren->append(rule);
00256            rule->setParent(this);
00257 //           rule->init();
00258         }
00259     }
00260     return true;
00261 }
00262 
00263 bool CSSStyleSheetImpl::isLoading()
00264 {
00265     StyleBaseImpl *rule;
00266     for ( rule = m_lstChildren->first(); rule != 0; rule = m_lstChildren->next() )
00267     {
00268         if(rule->isImportRule())
00269         {
00270             CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(rule);
00271 #ifdef CSS_STYLESHEET_DEBUG
00272             kdDebug( 6080 ) << "found import" << endl;
00273 #endif
00274             if(import->isLoading())
00275             {
00276 #ifdef CSS_STYLESHEET_DEBUG
00277                 kdDebug( 6080 ) << "--> not loaded" << endl;
00278 #endif
00279                 return true;
00280             }
00281         }
00282     }
00283     return false;
00284 }
00285 
00286 void CSSStyleSheetImpl::checkLoaded()
00287 {
00288     if(isLoading()) return;
00289     if(m_parent) m_parent->checkLoaded();
00290     if(m_parentNode) m_parentNode->sheetLoaded();
00291 }
00292 
00293 void CSSStyleSheetImpl::setNonCSSHints()
00294 {
00295     StyleBaseImpl *rule = m_lstChildren->first();
00296     while(rule) {
00297         if(rule->isStyleRule()) {
00298             static_cast<CSSStyleRuleImpl *>(rule)->setNonCSSHints();
00299         }
00300         rule = m_lstChildren->next();
00301     }
00302 }
00303 
00304 khtml::DocLoader *CSSStyleSheetImpl::docLoader()
00305 {
00306     if ( !m_doc ) // doc is 0 for the user- and default-sheet!
00307         return 0;
00308 
00309     // ### remove? (clients just use sheet->doc()->docLoader())
00310     return m_doc->docLoader();
00311 }
00312 
00313 // ---------------------------------------------------------------------------------------------
00314 
00315 StyleSheetListImpl::StyleSheetListImpl()
00316 {
00317 }
00318 
00319 StyleSheetListImpl::~StyleSheetListImpl()
00320 {
00321     for ( QPtrListIterator<StyleSheetImpl> it ( styleSheets ); it.current(); ++it )
00322         it.current()->deref();
00323 }
00324 
00325 void StyleSheetListImpl::add( StyleSheetImpl* s )
00326 {
00327     if ( !styleSheets.containsRef( s ) ) {
00328         s->ref();
00329         styleSheets.append( s );
00330     }
00331 }
00332 
00333 void StyleSheetListImpl::remove( StyleSheetImpl* s )
00334 {
00335     if ( styleSheets.removeRef( s ) )
00336         s->deref();
00337 }
00338 
00339 unsigned long StyleSheetListImpl::length() const
00340 {
00341     // hack so implicit BODY stylesheets don't get counted here
00342     unsigned long l = 0;
00343     QPtrListIterator<StyleSheetImpl> it(styleSheets);
00344     for (; it.current(); ++it) {
00345         if (!it.current()->isCSSStyleSheet() || !static_cast<CSSStyleSheetImpl*>(it.current())->implicit())
00346             l++;
00347     }
00348     return l;
00349 }
00350 
00351 StyleSheetImpl *StyleSheetListImpl::item ( unsigned long index )
00352 {
00353     unsigned long l = 0;
00354     QPtrListIterator<StyleSheetImpl> it(styleSheets);
00355     for (; it.current(); ++it) {
00356         if (!it.current()->isCSSStyleSheet() || !static_cast<CSSStyleSheetImpl*>(it.current())->implicit()) {
00357             if (l == index)
00358                 return it.current();
00359             l++;
00360         }
00361     }
00362     return 0;
00363 }
00364 
00365 // --------------------------------------------------------------------------------------------
00366 
00367 MediaListImpl::MediaListImpl(CSSStyleSheetImpl *parentSheet)
00368     : StyleBaseImpl(parentSheet)
00369 {
00370 }
00371 
00372 MediaListImpl::MediaListImpl( CSSStyleSheetImpl *parentSheet,
00373                               const DOMString &media )
00374     : StyleBaseImpl( parentSheet )
00375 {
00376     setMediaText( media );
00377 }
00378 
00379 MediaListImpl::MediaListImpl(CSSRuleImpl *parentRule)
00380     : StyleBaseImpl(parentRule)
00381 {
00382 }
00383 
00384 MediaListImpl::MediaListImpl( CSSRuleImpl *parentRule, const DOMString &media )
00385     : StyleBaseImpl(parentRule)
00386 {
00387     setMediaText( media );
00388 }
00389 
00390 MediaListImpl::~MediaListImpl()
00391 {
00392 }
00393 
00394 bool MediaListImpl::contains( const DOMString &medium ) const
00395 {
00396     return m_lstMedia.count() == 0 || m_lstMedia.contains( medium ) ||
00397             m_lstMedia.contains( "all" );
00398 }
00399 
00400 CSSStyleSheetImpl *MediaListImpl::parentStyleSheet() const
00401 {
00402     if( m_parent->isCSSStyleSheet() ) return static_cast<CSSStyleSheetImpl *>(m_parent);
00403     return 0;
00404 }
00405 
00406 CSSRuleImpl *MediaListImpl::parentRule() const
00407 {
00408     if( m_parent->isRule() ) return static_cast<CSSRuleImpl *>(m_parent);
00409     return 0;
00410 }
00411 
00412 unsigned long MediaListImpl::length() const
00413 {
00414     return m_lstMedia.count();
00415 }
00416 
00417 DOMString MediaListImpl::item( unsigned long index ) const
00418 {
00419     return m_lstMedia[index];
00420 }
00421 
00422 void MediaListImpl::deleteMedium( const DOMString &oldMedium )
00423 {
00424     for ( QValueList<DOMString>::Iterator it = m_lstMedia.begin(); it != m_lstMedia.end(); ++it ) {
00425         if( (*it) == oldMedium ) {
00426             m_lstMedia.remove( it );
00427             return;
00428         }
00429     }
00430 }
00431 
00432 void MediaListImpl::appendMedium( const DOMString &newMedium )
00433 {
00434     m_lstMedia.append( newMedium );
00435 }
00436 
00437 DOM::DOMString MediaListImpl::mediaText() const
00438 {
00439     DOMString text;
00440     for ( QValueList<DOMString>::ConstIterator it = m_lstMedia.begin(); it != m_lstMedia.end(); ++it ) {
00441         text += *it;
00442         text += ", ";
00443     }
00444     return text;
00445 }
00446 
00447 void MediaListImpl::setMediaText(const DOM::DOMString &value)
00448 {
00449     m_lstMedia.clear();
00450     QString val = value.string();
00451     QStringList list = QStringList::split( ',', value.string() );
00452     for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
00453     {
00454         DOMString medium = (*it).stripWhiteSpace();
00455         if( medium != "" )
00456             m_lstMedia.append( medium );
00457     }
00458 }
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:31 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001