khtml Library API Documentation

css_base.cpp

00001 /* 00002 * This file is part of the DOM implementation for KDE. 00003 * 00004 * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) 00005 * 1999 Waldo Bastian (bastian@kde.org) 00006 * 2001 Andreas Schlapbach (schlpbch@iam.unibe.ch) 00007 * 2001-2003 Dirk Mueller (mueller@kde.org) 00008 * Copyright (C) 2002 Apple Computer, Inc. 00009 * 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Library General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Library General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Library General Public License 00021 * along with this library; see the file COPYING.LIB. If not, write to 00022 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00023 * Boston, MA 02111-1307, USA. 00024 */ 00025 00026 //#define CSS_DEBUG 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 // try to find the style sheet. If found look for its url. 00059 // If it has none, look for the parentsheet, or the parentNode and 00060 // try to find out about their url 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 // find parent 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(); // just remove the top one - not sure what should happen if we have multiple instances of the property 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 // non implemented yet << ", value: " << parsedValue->cssText().string() 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 // make sure it doesn't overflow 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 //assert(sel1->_pseudoType != PseudoNotParsed); 00243 //assert(sel2->_pseudoType != PseudoNotParsed); 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 // #### fix namespace 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 // optional attribute 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 += " "; // ## correct? 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; // the ":" is provided by selectorText() 00342 else // Descendant 00343 str = tagHistoryText + " " + str; 00344 } 00345 return str; 00346 } 00347 00348 // ----------------------------------------------------------------------------
KDE Logo
This file is part of the documentation for khtml Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 10 18:56:11 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003