css_base.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <assert.h>
00029 #include <kdebug.h>
00030
00031 #include "css_base.h"
00032
00033 #ifdef CSS_DEBUG
00034 #include "cssproperties.h"
00035 #endif
00036
00037 #include "css_stylesheetimpl.h"
00038 #include "xml/dom_docimpl.h"
00039 #include "misc/htmlhashes.h"
00040 #include "css_valueimpl.h"
00041 using namespace DOM;
00042
00043 void StyleBaseImpl::checkLoaded() const
00044 {
00045 if(m_parent) m_parent->checkLoaded();
00046 }
00047
00048 StyleSheetImpl* StyleBaseImpl::stylesheet()
00049 {
00050 StyleBaseImpl* b = this;
00051 while(b && !b->isStyleSheet())
00052 b = b->m_parent;
00053 return static_cast<StyleSheetImpl *>(b);
00054 }
00055
00056 KURL StyleBaseImpl::baseURL()
00057 {
00058
00059
00060
00061
00062 StyleSheetImpl *sheet = stylesheet();
00063
00064 if(!sheet) return KURL();
00065
00066 if(!sheet->href().isNull())
00067 return KURL( sheet->href().string() );
00068
00069
00070 if(sheet->parent()) return sheet->parent()->baseURL();
00071
00072 if(!sheet->ownerNode()) return KURL();
00073
00074 return sheet->ownerNode()->getDocument()->baseURL();
00075 }
00076
00077 void StyleBaseImpl::setParsedValue(int propId, const CSSValueImpl *parsedValue,
00078 bool important, bool nonCSSHint, QPtrList<CSSProperty> *propList)
00079 {
00080 QPtrListIterator<CSSProperty> propIt(*propList);
00081 propIt.toLast();
00082 while (propIt.current() &&
00083 ( propIt.current()->m_id != propId || propIt.current()->nonCSSHint != nonCSSHint ||
00084 propIt.current()->m_bImportant != important) )
00085 --propIt;
00086 if (propIt.current())
00087 propList->removeRef(propIt.current());
00088
00089 CSSProperty *prop = new CSSProperty();
00090 prop->m_id = propId;
00091 prop->setValue((CSSValueImpl *) parsedValue);
00092 prop->m_bImportant = important;
00093 prop->nonCSSHint = nonCSSHint;
00094
00095 propList->append(prop);
00096 #ifdef CSS_DEBUG
00097 kdDebug( 6080 ) << "added property: " << getPropertyName(propId).string()
00098
00099 << " important: " << prop->m_bImportant
00100 << " nonCSS: " << prop->nonCSSHint << endl;
00101 #endif
00102 }
00103
00104
00105
00106 StyleListImpl::~StyleListImpl()
00107 {
00108 StyleBaseImpl *n;
00109
00110 if(!m_lstChildren) return;
00111
00112 for( n = m_lstChildren->first(); n != 0; n = m_lstChildren->next() )
00113 {
00114 n->setParent(0);
00115 if( !n->refCount() ) delete n;
00116 }
00117 delete m_lstChildren;
00118 }
00119
00120
00121
00122 void CSSSelector::print(void)
00123 {
00124 kdDebug( 6080 ) << "[Selector: tag = " << QString::number(tag,16) << ", attr = \"" << attr << "\", match = \"" << match
00125 << "\" value = \"" << value.string().latin1() << "\" relation = " << (int)relation
00126 << "]" << endl;
00127 if ( tagHistory )
00128 tagHistory->print();
00129 kdDebug( 6080 ) << " specificity = " << specificity() << endl;
00130 }
00131
00132 unsigned int CSSSelector::specificity() const
00133 {
00134 if ( nonCSSHint )
00135 return 0;
00136
00137 int s = ((( tag & NodeImpl_IdLocalMask ) == 0xffff) ? 0 : 1);
00138 switch(match)
00139 {
00140 case Id:
00141 s += 0x10000;
00142 break;
00143 case Exact:
00144 case Set:
00145 case List:
00146 case Hyphen:
00147 case Pseudo:
00148 case Contain:
00149 case Begin:
00150 case End:
00151 s += 0x100;
00152 case None:
00153 break;
00154 }
00155 if(tagHistory)
00156 s += tagHistory->specificity();
00157
00158 return s & 0xffffff;
00159 }
00160
00161 void CSSSelector::extractPseudoType() const
00162 {
00163 if (match != Pseudo)
00164 return;
00165 _pseudoType = PseudoOther;
00166 if (!value.isEmpty()) {
00167 value = value.lower();
00168 switch (value[0]) {
00169 case 'a':
00170 if (value == "active")
00171 _pseudoType = PseudoActive;
00172 else if (value == "after")
00173 _pseudoType = PseudoAfter;
00174 break;
00175 case 'b':
00176 if (value == "before")
00177 _pseudoType = PseudoBefore;
00178 break;
00179 case 'e':
00180 if (value == "empty")
00181 _pseudoType = PseudoEmpty;
00182 break;
00183 case 'f':
00184 if (value == "first-child")
00185 _pseudoType = PseudoFirstChild;
00186 else if (value == "first-letter")
00187 _pseudoType = PseudoFirstLetter;
00188 else if (value == "first-line")
00189 _pseudoType = PseudoFirstLine;
00190 else if (value == "focus")
00191 _pseudoType = PseudoFocus;
00192 break;
00193 case 'h':
00194 if (value == "hover")
00195 _pseudoType = PseudoHover;
00196 break;
00197 case 'l':
00198 if (value == "link")
00199 _pseudoType = PseudoLink;
00200 else if (value == "lang(")
00201 _pseudoType = PseudoLang;
00202 else if (value == "last-child")
00203 _pseudoType = PseudoLastChild;
00204 break;
00205 case 'n':
00206 if (value == "not(")
00207 _pseudoType = PseudoNot;
00208 break;
00209 case 'o':
00210 if (value == "only-child")
00211 _pseudoType = PseudoOnlyChild;
00212 break;
00213 case 'r':
00214 if (value == "root")
00215 _pseudoType = PseudoRoot;
00216 break;
00217 case 's':
00218 if (value == "selection")
00219 _pseudoType = PseudoSelection;
00220 break;
00221 case 't':
00222 if (value == "target")
00223 _pseudoType = PseudoTarget;
00224 break;
00225 case 'v':
00226 if (value == "visited")
00227 _pseudoType = PseudoVisited;
00228 break;
00229 }
00230 }
00231
00232 value = DOMString();
00233 }
00234
00235
00236 bool CSSSelector::operator == ( const CSSSelector &other ) const
00237 {
00238 const CSSSelector *sel1 = this;
00239 const CSSSelector *sel2 = &other;
00240
00241 while ( sel1 && sel2 ) {
00242
00243
00244 if ( sel1->tag != sel2->tag || sel1->attr != sel2->attr ||
00245 sel1->relation != sel2->relation || sel1->match != sel2->match ||
00246 sel1->nonCSSHint != sel2->nonCSSHint ||
00247 sel1->value != sel2->value ||
00248 sel1->pseudoType() != sel2->pseudoType())
00249 return false;
00250 sel1 = sel1->tagHistory;
00251 sel2 = sel2->tagHistory;
00252 }
00253 if ( sel1 || sel2 )
00254 return false;
00255 return true;
00256 }
00257
00258 DOMString CSSSelector::selectorText() const
00259 {
00260
00261 DOMString str;
00262 const CSSSelector* cs = this;
00263 if ( cs->tag == 0xffff && cs->attr == ATTR_ID && cs->match == CSSSelector::Exact )
00264 {
00265 str = "#";
00266 str += cs->value;
00267 }
00268 else if ( cs->tag == 0xffff && cs->attr == ATTR_CLASS && cs->match == CSSSelector::List )
00269 {
00270 str = ".";
00271 str += cs->value;
00272 }
00273 else if ( cs->tag == 0xffff && cs->match == CSSSelector::Pseudo )
00274 {
00275 str = ":";
00276 str += cs->value;
00277 }
00278 else
00279 {
00280 if ( cs->tag == 0xffff )
00281 str = "*";
00282 else
00283 str = getTagName( cs->tag );
00284 if ( cs->attr == ATTR_ID && cs->match == CSSSelector::Exact )
00285 {
00286 str += "#";
00287 str += cs->value;
00288 }
00289 else if ( cs->attr == ATTR_CLASS && cs->match == CSSSelector::List )
00290 {
00291 str += ".";
00292 str += cs->value;
00293 }
00294 else if ( cs->match == CSSSelector::Pseudo )
00295 {
00296 str += ":";
00297 str += cs->value;
00298 }
00299
00300 if ( cs->attr ) {
00301 DOMString attrName = getAttrName( cs->attr );
00302 str += "[";
00303 str += attrName;
00304 switch (cs->match) {
00305 case CSSSelector::Exact:
00306 str += "=";
00307 break;
00308 case CSSSelector::Set:
00309 str += " ";
00310 break;
00311 case CSSSelector::List:
00312 str += "~=";
00313 break;
00314 case CSSSelector::Hyphen:
00315 str += "|=";
00316 break;
00317 case CSSSelector::Begin:
00318 str += "^=";
00319 break;
00320 case CSSSelector::End:
00321 str += "$=";
00322 break;
00323 case CSSSelector::Contain:
00324 str += "*=";
00325 break;
00326 default:
00327 kdWarning(6080) << "Unhandled case in CSSStyleRuleImpl::selectorText : match=" << cs->match << endl;
00328 }
00329 str += "\"";
00330 str += cs->value;
00331 str += "\"]";
00332 }
00333 }
00334 if ( cs->tagHistory ) {
00335 DOMString tagHistoryText = cs->tagHistory->selectorText();
00336 if ( cs->relation == Sibling )
00337 str = tagHistoryText + " + " + str;
00338 else if ( cs->relation == Child )
00339 str = tagHistoryText + " > " + str;
00340 else if ( cs->relation == SubSelector )
00341 str += tagHistoryText;
00342 else
00343 str = tagHistoryText + " " + str;
00344 }
00345 return str;
00346 }
00347
00348
This file is part of the documentation for khtml Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 23 17:13:14 2004 by
doxygen 1.3.8-20040913 written by
Dimitri van Heesch, © 1997-2003