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