File indexing completed on 2023-09-24 04:06:07
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 2000 Harri Porten (porten@kde.org) 0004 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 0005 * Copyright (C) 2003 Apple Computer, Inc. 0006 * 0007 * This library is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU Library General Public 0009 * License as published by the Free Software Foundation; either 0010 * version 2 of the License, or (at your option) any later version. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Library General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Library General Public 0018 * License along with this library; if not, write to the Free Software 0019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0020 */ 0021 0022 #include "kjs_css.h" 0023 #include "kjs_css.lut.h" 0024 0025 #include "html/html_headimpl.h" // for HTMLStyleElementImpl 0026 0027 #include "dom/css_value.h" 0028 #include "dom/css_rule.h" 0029 0030 #include "css/css_renderstyledeclarationimpl.h" 0031 #include "css/cssproperties.h" 0032 0033 #include "kjs_dom.h" 0034 0035 using DOM::CSSCharsetRuleImpl; 0036 using DOM::CSSFontFaceRuleImpl; 0037 using DOM::CSSImportRuleImpl; 0038 using DOM::CSSMediaRuleImpl; 0039 using DOM::CSSPageRuleImpl; 0040 using DOM::CSSPrimitiveValue; 0041 using DOM::CSSPrimitiveValueImpl; 0042 using DOM::CSSRule; 0043 using DOM::CSSRuleImpl; 0044 using DOM::CSSRuleListImpl; 0045 using DOM::CSSStyleDeclarationImpl; 0046 using DOM::CSSStyleRuleImpl; 0047 using DOM::CSSStyleSheetImpl; 0048 using DOM::CSSValue; 0049 using DOM::CSSValueImpl; 0050 using DOM::CSSValueListImpl; 0051 using DOM::CounterImpl; 0052 using DOM::DocumentImpl; 0053 using DOM::DOMString; 0054 using DOM::ElementImpl; 0055 using DOM::HTMLStyleElementImpl; 0056 using DOM::MediaListImpl; 0057 using DOM::RectImpl; 0058 using DOM::StyleSheetImpl; 0059 using DOM::StyleSheetListImpl; 0060 0061 #include "khtml_debug.h" 0062 #include <QList> 0063 0064 namespace KJS 0065 { 0066 0067 static QString cssPropertyName(const Identifier &p, bool *hadPixelPrefix) 0068 { 0069 // The point here is to provide compatibility with IE 0070 // syntax for accessing properties, which camel-cases them 0071 // and can add prefixes to produce things like pixelFoo 0072 QString prop = p.qstring(); 0073 for (int i = prop.length() - 1; i >= 0; --i) { 0074 char c = prop[i].toLatin1(); 0075 if (c >= 'A' && c <= 'Z') { 0076 prop.insert(i, '-'); 0077 } 0078 } 0079 0080 prop = prop.toLower(); 0081 *hadPixelPrefix = false; 0082 0083 if (prop.startsWith(QLatin1String("css-"))) { 0084 prop = prop.mid(4); 0085 } else if (prop.startsWith(QLatin1String("pixel-"))) { 0086 prop = prop.mid(6); 0087 *hadPixelPrefix = true; 0088 } else if (prop.startsWith(QLatin1String("pos-"))) { 0089 prop = prop.mid(4); 0090 *hadPixelPrefix = true; 0091 } 0092 0093 return prop; 0094 } 0095 0096 static int cssPropertyId(const QString &p) 0097 { 0098 return DOM::getPropertyID(p.toLatin1().constData(), p.length()); 0099 } 0100 0101 static bool isCSSPropertyName(const Identifier &JSPropertyName) 0102 { 0103 bool dummy; 0104 QString p = cssPropertyName(JSPropertyName, &dummy); 0105 return cssPropertyId(p) != 0; 0106 } 0107 0108 /* 0109 @begin DOMCSSStyleDeclarationProtoTable 7 0110 getPropertyValue DOMCSSStyleDeclaration::GetPropertyValue DontDelete|Function 1 0111 getPropertyCSSValue DOMCSSStyleDeclaration::GetPropertyCSSValue DontDelete|Function 1 0112 removeProperty DOMCSSStyleDeclaration::RemoveProperty DontDelete|Function 1 0113 getPropertyPriority DOMCSSStyleDeclaration::GetPropertyPriority DontDelete|Function 1 0114 setProperty DOMCSSStyleDeclaration::SetProperty DontDelete|Function 3 0115 item DOMCSSStyleDeclaration::Item DontDelete|Function 1 0116 # IE names for it (#36063) 0117 getAttribute DOMCSSStyleDeclaration::GetPropertyValue DontDelete|Function 1 0118 removeAttribute DOMCSSStyleDeclaration::RemoveProperty DontDelete|Function 1 0119 setAttribute DOMCSSStyleDeclaration::SetProperty DontDelete|Function 3 0120 @end 0121 @begin DOMCSSStyleDeclarationTable 3 0122 cssText DOMCSSStyleDeclaration::CssText DontDelete 0123 length DOMCSSStyleDeclaration::Length DontDelete|ReadOnly 0124 parentRule DOMCSSStyleDeclaration::ParentRule DontDelete|ReadOnly 0125 @end 0126 */ 0127 KJS_DEFINE_PROTOTYPE(DOMCSSStyleDeclarationProto) 0128 KJS_IMPLEMENT_PROTOFUNC(DOMCSSStyleDeclarationProtoFunc) 0129 KJS_IMPLEMENT_PROTOTYPE("DOMCSSStyleDeclaration", DOMCSSStyleDeclarationProto, DOMCSSStyleDeclarationProtoFunc, ObjectPrototype) 0130 0131 IMPLEMENT_PSEUDO_CONSTRUCTOR(CSSStyleDeclarationPseudoCtor, "DOMCSSStyleDeclaration", DOMCSSStyleDeclarationProto) 0132 0133 const ClassInfo DOMCSSStyleDeclaration::info = { "CSSStyleDeclaration", nullptr, &DOMCSSStyleDeclarationTable, nullptr }; 0134 0135 DOMCSSStyleDeclaration::DOMCSSStyleDeclaration(ExecState *exec, DOM::CSSStyleDeclarationImpl *s) 0136 : DOMObject(), m_impl(s) 0137 { 0138 setPrototype(DOMCSSStyleDeclarationProto::self(exec)); 0139 } 0140 0141 DOMCSSStyleDeclaration::~DOMCSSStyleDeclaration() 0142 { 0143 ScriptInterpreter::forgetDOMObject(m_impl.get()); 0144 } 0145 0146 JSValue *DOMCSSStyleDeclaration::getValueProperty(ExecState *exec, int token) 0147 { 0148 //### null decls? 0149 switch (token) { 0150 case CssText: 0151 return jsString(m_impl->cssText()); 0152 case Length: 0153 return jsNumber(m_impl->length()); 0154 case ParentRule: 0155 return getDOMCSSRule(exec, m_impl->parentRule()); 0156 } 0157 0158 assert(0); 0159 return jsUndefined(); 0160 } 0161 0162 JSValue *DOMCSSStyleDeclaration::indexGetter(ExecState *, unsigned index) 0163 { 0164 return jsString(m_impl->item(index)); 0165 } 0166 0167 bool DOMCSSStyleDeclaration::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0168 { 0169 #ifdef KJS_VERBOSE 0170 qCDebug(KHTML_LOG) << "DOMCSSStyleDeclaration::getOwnPropertySlot " << propertyName.qstring(); 0171 #endif 0172 0173 if (getStaticOwnValueSlot(&DOMCSSStyleDeclarationTable, this, propertyName, slot)) { 0174 return true; 0175 } 0176 0177 //Check whether it's an index 0178 if (getIndexSlot(this, propertyName, slot)) { 0179 return true; 0180 } 0181 0182 if (isCSSPropertyName(propertyName)) { 0183 // Set up pixelOrPos boolean to handle the fact that 0184 // pixelTop returns "CSS Top" as number value in unit pixels 0185 // posTop returns "CSS top" as number value in unit pixels _if_ its a 0186 // positioned element. if it is not a positioned element, return 0 0187 // from MSIE documentation ### IMPLEMENT THAT (Dirk) 0188 bool asNumber; 0189 DOMString p = cssPropertyName(propertyName, &asNumber); 0190 0191 if (asNumber) { 0192 CSSValueImpl *v = m_impl->getPropertyCSSValue(p); 0193 if (v && v->cssValueType() == DOM::CSSValue::CSS_PRIMITIVE_VALUE) 0194 //### FIXME: should this not set exception when type is wrong, or convert? 0195 return getImmediateValueSlot(this, 0196 jsNumber(static_cast<CSSPrimitiveValueImpl *>(v)->floatValue(DOM::CSSPrimitiveValue::CSS_PX)), slot); 0197 } 0198 0199 DOM::DOMString str = m_impl->getPropertyValue(p); 0200 0201 // We want to return at least an empty string here --- see #152791 0202 return getImmediateValueSlot(this, jsString(str), slot); 0203 } 0204 0205 return DOMObject::getOwnPropertySlot(exec, propertyName, slot); 0206 } 0207 0208 void DOMCSSStyleDeclaration::getOwnPropertyNames(ExecState *exec, PropertyNameArray &arr, PropertyMap::PropertyMode mode) 0209 { 0210 DOMObject::getOwnPropertyNames(exec, arr, mode); 0211 0212 // Add in all properties we support. 0213 for (int p = 1; p < CSS_PROP_TOTAL; ++p) { 0214 QString dashName = getPropertyName(p).string(); 0215 QString camelName; 0216 0217 bool capitalize = false; 0218 for (int c = 0; c < dashName.length(); ++c) { 0219 if (dashName[c] == QLatin1Char('-')) { 0220 capitalize = true; 0221 } else { 0222 camelName += capitalize ? dashName[c].toUpper() : dashName[c]; 0223 capitalize = false; 0224 } 0225 } // char 0226 0227 arr.add(KJS::Identifier(camelName)); 0228 } // prop 0229 } 0230 0231 void DOMCSSStyleDeclaration::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) 0232 { 0233 #ifdef KJS_VERBOSE 0234 qCDebug(KHTML_LOG) << "DOMCSSStyleDeclaration::put " << propertyName.qstring(); 0235 #endif 0236 DOMExceptionTranslator exception(exec); 0237 CSSStyleDeclarationImpl &styleDecl = *m_impl; 0238 0239 if (propertyName == "cssText") { 0240 styleDecl.setCssText(valueToStringWithNullCheck(exec, value)); 0241 } else { 0242 bool pxSuffix; 0243 QString prop = cssPropertyName(propertyName, &pxSuffix); 0244 QString propvalue = valueToStringWithNullCheck(exec, value).string(); 0245 0246 if (pxSuffix) { 0247 propvalue += QLatin1String("px"); 0248 } 0249 #ifdef KJS_VERBOSE 0250 qCDebug(KHTML_LOG) << "DOMCSSStyleDeclaration: prop=" << prop << " propvalue=" << propvalue; 0251 #endif 0252 // Look whether the property is known. In that case add it as a CSS property. 0253 if (int pId = cssPropertyId(prop)) { 0254 if (propvalue.isEmpty()) { 0255 styleDecl.removeProperty(pId); 0256 } else { 0257 int important = propvalue.indexOf("!important", 0, Qt::CaseInsensitive); 0258 if (important == -1) { 0259 styleDecl.setProperty(pId, DOM::DOMString(propvalue), false /*important*/, exception); 0260 } else { 0261 styleDecl.setProperty(pId, DOM::DOMString(propvalue.left(important - 1)), true /*important*/, exception); 0262 } 0263 } 0264 } else 0265 // otherwise add it as a JS property 0266 { 0267 DOMObject::put(exec, propertyName, value, attr); 0268 } 0269 } 0270 } 0271 0272 JSValue *DOMCSSStyleDeclarationProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0273 { 0274 KJS_CHECK_THIS(KJS::DOMCSSStyleDeclaration, thisObj); 0275 CSSStyleDeclarationImpl &styleDecl = *static_cast<DOMCSSStyleDeclaration *>(thisObj)->impl(); 0276 0277 const DOM::DOMString cssProp = args[0]->toString(exec).domString(); 0278 0279 switch (id) { 0280 case DOMCSSStyleDeclaration::GetPropertyValue: 0281 return jsString(styleDecl.getPropertyValue(cssProp)); 0282 case DOMCSSStyleDeclaration::GetPropertyCSSValue: 0283 return getDOMCSSValue(exec, styleDecl.getPropertyCSSValue(cssProp)); 0284 case DOMCSSStyleDeclaration::RemoveProperty: 0285 return jsString(styleDecl.removeProperty(cssProp)); 0286 case DOMCSSStyleDeclaration::GetPropertyPriority: 0287 return jsString(styleDecl.getPropertyPriority(cssProp)); 0288 case DOMCSSStyleDeclaration::SetProperty: { 0289 const DOM::DOMString cssVal = args[1]->toString(exec).domString(); 0290 if (cssVal.isEmpty()) { 0291 styleDecl.removeProperty(cssProp); 0292 } else { 0293 styleDecl.setProperty(cssProp, cssVal, args[2]->toString(exec).domString()); 0294 } 0295 return jsUndefined(); 0296 } 0297 case DOMCSSStyleDeclaration::Item: 0298 return jsString(styleDecl.item(args[0]->toInteger(exec))); 0299 default: 0300 return jsUndefined(); 0301 } 0302 } 0303 0304 JSValue *getDOMCSSStyleDeclaration(ExecState *exec, CSSStyleDeclarationImpl *s) 0305 { 0306 return cacheDOMObject<CSSStyleDeclarationImpl, DOMCSSStyleDeclaration>(exec, s); 0307 } 0308 0309 // ------------------------------------------------------------------------- 0310 0311 const ClassInfo DOMStyleSheet::info = { "StyleSheet", nullptr, &DOMStyleSheetTable, nullptr }; 0312 /* 0313 @begin DOMStyleSheetTable 7 0314 type DOMStyleSheet::Type DontDelete|ReadOnly 0315 disabled DOMStyleSheet::Disabled DontDelete 0316 ownerNode DOMStyleSheet::OwnerNode DontDelete|ReadOnly 0317 parentStyleSheet DOMStyleSheet::ParentStyleSheet DontDelete|ReadOnly 0318 href DOMStyleSheet::Href DontDelete|ReadOnly 0319 title DOMStyleSheet::Title DontDelete|ReadOnly 0320 media DOMStyleSheet::Media DontDelete|ReadOnly 0321 @end 0322 */ 0323 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("StyleSheet", DOMStyleSheetProto, ObjectPrototype) 0324 IMPLEMENT_PSEUDO_CONSTRUCTOR(DOMStyleSheetPseudoCtor, "StyleSheet", DOMStyleSheetProto) 0325 0326 DOMStyleSheet::DOMStyleSheet(ExecState *exec, DOM::StyleSheetImpl *ss) 0327 : m_impl(ss) 0328 { 0329 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 0330 } 0331 0332 DOMStyleSheet::~DOMStyleSheet() 0333 { 0334 ScriptInterpreter::forgetDOMObject(m_impl.get()); 0335 } 0336 0337 bool DOMStyleSheet::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0338 { 0339 return getStaticValueSlot<DOMStyleSheet, DOMObject>(exec, &DOMStyleSheetTable, this, propertyName, slot); 0340 } 0341 0342 JSValue *DOMStyleSheet::getValueProperty(ExecState *exec, int token) const 0343 { 0344 StyleSheetImpl &styleSheet = *m_impl; 0345 switch (token) { 0346 case Type: 0347 return jsString(styleSheet.type()); 0348 case Disabled: 0349 return jsBoolean(styleSheet.disabled()); 0350 case OwnerNode: 0351 return getDOMNode(exec, styleSheet.ownerNode()); 0352 case ParentStyleSheet: 0353 return getDOMStyleSheet(exec, styleSheet.parentStyleSheet()); 0354 case Href: 0355 return getStringOrNull(styleSheet.href()); 0356 case Title: 0357 return jsString(styleSheet.title()); 0358 case Media: 0359 return getDOMMediaList(exec, styleSheet.media()); 0360 } 0361 return nullptr; 0362 } 0363 0364 void DOMStyleSheet::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) 0365 { 0366 StyleSheetImpl &styleSheet = *m_impl; 0367 if (propertyName == "disabled") { 0368 styleSheet.setDisabled(value->toBoolean(exec)); 0369 } else { 0370 DOMObject::put(exec, propertyName, value, attr); 0371 } 0372 } 0373 0374 JSValue *getDOMStyleSheet(ExecState *exec, DOM::StyleSheetImpl *ss) 0375 { 0376 if (!ss) { 0377 return jsNull(); 0378 } 0379 0380 DOMObject *ret; 0381 ScriptInterpreter *interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter()); 0382 if ((ret = interp->getDOMObject(ss))) { 0383 return ret; 0384 } else { 0385 if (ss->isCSSStyleSheet()) { 0386 CSSStyleSheetImpl *cs = static_cast<CSSStyleSheetImpl *>(ss); 0387 ret = new DOMCSSStyleSheet(exec, cs); 0388 } else { 0389 ret = new DOMStyleSheet(exec, ss); 0390 } 0391 interp->putDOMObject(ss, ret); 0392 return ret; 0393 } 0394 } 0395 0396 // ------------------------------------------------------------------------- 0397 0398 const ClassInfo DOMStyleSheetList::info = { "StyleSheetList", nullptr, &DOMStyleSheetListTable, nullptr }; 0399 0400 /* 0401 @begin DOMStyleSheetListTable 2 0402 length DOMStyleSheetList::Length DontDelete|ReadOnly 0403 item DOMStyleSheetList::Item DontDelete|Function 1 0404 @end 0405 */ 0406 KJS_IMPLEMENT_PROTOFUNC(DOMStyleSheetListFunc) // not really a proto, but doesn't matter 0407 0408 DOMStyleSheetList::DOMStyleSheetList(ExecState *exec, DOM::StyleSheetListImpl *ssl, DOM::DocumentImpl *doc) 0409 : m_impl(ssl), m_doc(doc) 0410 { 0411 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 0412 } 0413 0414 DOMStyleSheetList::~DOMStyleSheetList() 0415 { 0416 ScriptInterpreter::forgetDOMObject(m_impl.get()); 0417 } 0418 0419 JSValue *DOMStyleSheetList::getValueProperty(ExecState *, int token) const 0420 { 0421 switch (token) { 0422 case Length: 0423 return jsNumber(m_impl->length()); 0424 default: 0425 assert(0); 0426 return jsUndefined(); 0427 } 0428 } 0429 0430 JSValue *DOMStyleSheetList::indexGetter(ExecState *exec, unsigned index) 0431 { 0432 return getDOMStyleSheet(exec, m_impl->item(index)); 0433 } 0434 0435 JSValue *DOMStyleSheetList::nameGetter(ExecState *exec, JSObject *, const Identifier &propertyName, const PropertySlot &slot) 0436 { 0437 DOMStyleSheetList *thisObj = static_cast<DOMStyleSheetList *>(slot.slotBase()); 0438 ElementImpl *element = thisObj->m_doc->getElementById(propertyName.domString()); 0439 assert(element->id() == ID_STYLE); //Should be from existence check 0440 return getDOMStyleSheet(exec, static_cast<HTMLStyleElementImpl *>(element)->sheet()); 0441 } 0442 0443 bool DOMStyleSheetList::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0444 { 0445 #ifdef KJS_VERBOSE 0446 qCDebug(KHTML_LOG) << "DOMStyleSheetList::getOwnPropertySlot " << propertyName.qstring(); 0447 #endif 0448 if (getStaticOwnPropertySlot<DOMStyleSheetListFunc, DOMStyleSheetList>(&DOMStyleSheetListTable, this, propertyName, slot)) { 0449 return true; 0450 } 0451 0452 StyleSheetListImpl &styleSheetList = *m_impl; 0453 0454 // Retrieve stylesheet by index 0455 if (getIndexSlot(this, styleSheetList, propertyName, slot)) { 0456 return true; 0457 } 0458 0459 // IE also supports retrieving a stylesheet by name, using the name/id of the <style> tag 0460 // (this is consistent with all the other collections) 0461 // ### Bad implementation because returns a single element (are IDs always unique?) 0462 // and doesn't look for name attribute (see implementation above). 0463 // But unicity of stylesheet ids is good practice anyway ;) 0464 ElementImpl *element = m_doc->getElementById(propertyName.domString()); 0465 if (element && element->id() == ID_STYLE) { 0466 slot.setCustom(this, nameGetter); 0467 return true; 0468 } 0469 0470 return DOMObject::getOwnPropertySlot(exec, propertyName, slot); 0471 } 0472 0473 JSValue *DOMStyleSheetList::callAsFunction(ExecState *exec, JSObject * /*thisObj*/, const List &args) 0474 { 0475 if (args.size() == 1) { 0476 // support for styleSheets(<index>) and styleSheets(<name>) 0477 return get(exec, Identifier(args[0]->toString(exec))); 0478 } 0479 return jsUndefined(); 0480 } 0481 0482 JSValue *getDOMStyleSheetList(ExecState *exec, DOM::StyleSheetListImpl *ssl, DOM::DocumentImpl *doc) 0483 { 0484 // Can't use the cacheDOMObject macro because of the doc argument 0485 DOMObject *ret; 0486 if (!ssl) { 0487 return jsNull(); 0488 } 0489 ScriptInterpreter *interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter()); 0490 if ((ret = interp->getDOMObject(ssl))) { 0491 return ret; 0492 } else { 0493 ret = new DOMStyleSheetList(exec, ssl, doc); 0494 interp->putDOMObject(ssl, ret); 0495 return ret; 0496 } 0497 } 0498 0499 JSValue *DOMStyleSheetListFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0500 { 0501 KJS_CHECK_THIS(KJS::DOMStyleSheetList, thisObj); 0502 DOM::StyleSheetListImpl *styleSheetList = static_cast<DOMStyleSheetList *>(thisObj)->impl(); 0503 if (id == DOMStyleSheetList::Item) { 0504 return getDOMStyleSheet(exec, styleSheetList->item(args[0]->toInteger(exec))); 0505 } 0506 return jsUndefined(); 0507 } 0508 0509 // ------------------------------------------------------------------------- 0510 0511 const ClassInfo DOMMediaList::info = { "MediaList", nullptr, &DOMMediaListTable, nullptr }; 0512 0513 /* 0514 @begin DOMMediaListTable 2 0515 mediaText DOMMediaList::MediaText DontDelete|ReadOnly 0516 length DOMMediaList::Length DontDelete|ReadOnly 0517 @end 0518 @begin DOMMediaListProtoTable 3 0519 item DOMMediaList::Item DontDelete|Function 1 0520 deleteMedium DOMMediaList::DeleteMedium DontDelete|Function 1 0521 appendMedium DOMMediaList::AppendMedium DontDelete|Function 1 0522 @end 0523 */ 0524 KJS_DEFINE_PROTOTYPE(DOMMediaListProto) 0525 KJS_IMPLEMENT_PROTOFUNC(DOMMediaListProtoFunc) 0526 KJS_IMPLEMENT_PROTOTYPE("DOMMediaList", DOMMediaListProto, DOMMediaListProtoFunc, ObjectPrototype) 0527 0528 DOMMediaList::DOMMediaList(ExecState *exec, DOM::MediaListImpl *ml) 0529 : m_impl(ml) 0530 { 0531 setPrototype(DOMMediaListProto::self(exec)); 0532 } 0533 0534 DOMMediaList::~DOMMediaList() 0535 { 0536 ScriptInterpreter::forgetDOMObject(m_impl.get()); 0537 } 0538 0539 JSValue *DOMMediaList::getValueProperty(ExecState *, int token) const 0540 { 0541 const MediaListImpl &mediaList = *m_impl; 0542 switch (token) { 0543 case MediaText: 0544 return jsString(mediaList.mediaText()); 0545 case Length: 0546 return jsNumber(mediaList.length()); 0547 default: 0548 assert(0); 0549 return jsUndefined(); 0550 } 0551 } 0552 0553 JSValue *DOMMediaList::indexGetter(ExecState *, unsigned index) 0554 { 0555 return jsString(m_impl->item(index)); 0556 } 0557 0558 bool DOMMediaList::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0559 { 0560 if (getStaticOwnValueSlot(&DOMMediaListTable, this, propertyName, slot)) { 0561 return true; 0562 } 0563 0564 if (getIndexSlot(this, *m_impl, propertyName, slot)) { 0565 return true; 0566 } 0567 0568 return DOMObject::getOwnPropertySlot(exec, propertyName, slot); 0569 } 0570 0571 void DOMMediaList::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) 0572 { 0573 if (propertyName == "mediaText") { 0574 DOMExceptionTranslator exception(exec); 0575 m_impl->setMediaText(value->toString(exec).domString(), exception); 0576 } else { 0577 DOMObject::put(exec, propertyName, value, attr); 0578 } 0579 } 0580 0581 JSValue *getDOMMediaList(ExecState *exec, DOM::MediaListImpl *ml) 0582 { 0583 return cacheDOMObject<DOM::MediaListImpl, KJS::DOMMediaList>(exec, ml); 0584 } 0585 0586 JSValue *DOMMediaListProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0587 { 0588 KJS_CHECK_THIS(KJS::DOMMediaList, thisObj); 0589 DOM::MediaListImpl &mediaList = *static_cast<DOMMediaList *>(thisObj)->impl(); 0590 DOMExceptionTranslator exception(exec); 0591 switch (id) { 0592 case DOMMediaList::Item: 0593 return jsString(mediaList.item(args[0]->toInteger(exec))); 0594 case DOMMediaList::DeleteMedium: 0595 mediaList.deleteMedium(args[0]->toString(exec).domString(), exception); 0596 return jsUndefined(); 0597 case DOMMediaList::AppendMedium: 0598 mediaList.appendMedium(args[0]->toString(exec).domString(), exception); 0599 return jsUndefined(); 0600 default: 0601 return jsUndefined(); 0602 } 0603 } 0604 0605 // ------------------------------------------------------------------------- 0606 0607 const ClassInfo DOMCSSStyleSheet::info = { "CSSStyleSheet", nullptr, &DOMCSSStyleSheetTable, nullptr }; 0608 0609 /* 0610 @begin DOMCSSStyleSheetTable 2 0611 ownerRule DOMCSSStyleSheet::OwnerRule DontDelete|ReadOnly 0612 cssRules DOMCSSStyleSheet::CssRules DontDelete|ReadOnly 0613 # MSIE extension 0614 rules DOMCSSStyleSheet::Rules DontDelete|ReadOnly 0615 @end 0616 @begin DOMCSSStyleSheetProtoTable 2 0617 insertRule DOMCSSStyleSheet::InsertRule DontDelete|Function 2 0618 deleteRule DOMCSSStyleSheet::DeleteRule DontDelete|Function 1 0619 # IE extensions 0620 addRule DOMCSSStyleSheet::AddRule DontDelete|Function 3 0621 removeRule DOMCSSStyleSheet::RemoveRule DontDelete|Function 1 0622 @end 0623 */ 0624 KJS_DEFINE_PROTOTYPE(DOMCSSStyleSheetProto) 0625 KJS_IMPLEMENT_PROTOFUNC(DOMCSSStyleSheetProtoFunc) 0626 KJS_IMPLEMENT_PROTOTYPE("DOMCSSStyleSheet", DOMCSSStyleSheetProto, DOMCSSStyleSheetProtoFunc, DOMStyleSheetProto) 0627 0628 DOMCSSStyleSheet::DOMCSSStyleSheet(ExecState *exec, DOM::CSSStyleSheetImpl *ss): DOMStyleSheet(exec, ss) 0629 { 0630 setPrototype(DOMCSSStyleSheetProto::self(exec)); 0631 } 0632 0633 DOMCSSStyleSheet::~DOMCSSStyleSheet() 0634 {} 0635 0636 JSValue *DOMCSSStyleSheet::getValueProperty(ExecState *exec, int token) 0637 { 0638 CSSStyleSheetImpl &cssStyleSheet = *impl(); 0639 // MSIE does not list the charset rules in its proprietary extension 0640 bool omitCharsetRules = true; 0641 switch (token) { 0642 case OwnerRule: 0643 return getDOMCSSRule(exec, cssStyleSheet.ownerRule()); 0644 case CssRules: 0645 omitCharsetRules = false; 0646 // nobreak 0647 case Rules: { 0648 return getDOMCSSRuleList(exec, cssStyleSheet.cssRules(omitCharsetRules)); 0649 } 0650 default: 0651 assert(0); 0652 return jsUndefined(); 0653 } 0654 } 0655 0656 bool DOMCSSStyleSheet::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0657 { 0658 return getStaticValueSlot<DOMCSSStyleSheet, DOMStyleSheet>(exec, &DOMCSSStyleSheetTable, this, propertyName, slot); 0659 } 0660 0661 JSValue *DOMCSSStyleSheetProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0662 { 0663 KJS_CHECK_THIS(KJS::DOMCSSStyleSheet, thisObj); 0664 DOM::CSSStyleSheetImpl &styleSheet = *static_cast<DOMCSSStyleSheet *>(thisObj)->impl(); 0665 DOMExceptionTranslator exception(exec); 0666 0667 switch (id) { 0668 case DOMCSSStyleSheet::InsertRule: 0669 return jsNumber(styleSheet.insertRule(args[0]->toString(exec).domString(), (long unsigned int)args[1]->toInteger(exec), exception)); 0670 case DOMCSSStyleSheet::DeleteRule: 0671 styleSheet.deleteRule(args[0]->toInteger(exec), exception); 0672 return jsUndefined(); 0673 // IE extensions 0674 case DOMCSSStyleSheet::AddRule: { 0675 //Unpassed/-1 means append. Since insertRule is picky (throws exceptions) 0676 //we adjust it to the desired length 0677 unsigned long index = args[2]->toInteger(exec); 0678 unsigned long length = styleSheet.length(); 0679 if (args[2]->type() == UndefinedType) { 0680 index = length; 0681 } 0682 if (index > length) { 0683 index = length; 0684 } 0685 DOM::DOMString str = args[0]->toString(exec).domString() + " { " + args[1]->toString(exec).domString() + " } "; 0686 return jsNumber(styleSheet.insertRule(str, index, exception)); 0687 } 0688 case DOMCSSStyleSheet::RemoveRule: { 0689 int index = args.size() > 0 ? args[0]->toInteger(exec) : 0 /*first one*/; 0690 styleSheet.deleteRule(index, exception); 0691 return jsUndefined(); 0692 } 0693 default: 0694 return jsUndefined(); 0695 } 0696 } 0697 0698 // ------------------------------------------------------------------------- 0699 0700 const ClassInfo DOMCSSRuleList::info = { "CSSRuleList", nullptr, &DOMCSSRuleListTable, nullptr }; 0701 /* 0702 @begin DOMCSSRuleListTable 3 0703 length DOMCSSRuleList::Length DontDelete|ReadOnly 0704 item DOMCSSRuleList::Item DontDelete|Function 1 0705 @end 0706 */ 0707 KJS_IMPLEMENT_PROTOFUNC(DOMCSSRuleListFunc) // not really a proto, but doesn't matter 0708 0709 DOMCSSRuleList::DOMCSSRuleList(ExecState *exec, DOM::CSSRuleListImpl *rl) 0710 : m_impl(rl) 0711 { 0712 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 0713 } 0714 0715 DOMCSSRuleList::~DOMCSSRuleList() 0716 { 0717 ScriptInterpreter::forgetDOMObject(m_impl.get()); 0718 } 0719 0720 JSValue *DOMCSSRuleList::getValueProperty(ExecState *, int token) const 0721 { 0722 switch (token) { 0723 case Length: 0724 return jsNumber(m_impl->length()); 0725 default: 0726 assert(0); 0727 return jsUndefined(); 0728 } 0729 } 0730 0731 JSValue *DOMCSSRuleList::indexGetter(ExecState *exec, unsigned index) 0732 { 0733 return getDOMCSSRule(exec, m_impl->item(index)); 0734 } 0735 0736 bool DOMCSSRuleList::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0737 { 0738 if (getStaticOwnPropertySlot<DOMCSSRuleListFunc, DOMCSSRuleList>(&DOMCSSRuleListTable, this, propertyName, slot)) { 0739 return true; 0740 } 0741 0742 //Check whether it's an index 0743 //CSSRuleListImpl &cssRuleList = *m_impl; 0744 0745 if (getIndexSlot(this, *m_impl, propertyName, slot)) { 0746 return true; 0747 } 0748 0749 return DOMObject::getOwnPropertySlot(exec, propertyName, slot); 0750 } 0751 0752 JSValue *DOMCSSRuleListFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0753 { 0754 KJS_CHECK_THIS(KJS::DOMCSSRuleList, thisObj); 0755 DOM::CSSRuleListImpl &cssRuleList = *static_cast<DOMCSSRuleList *>(thisObj)->impl(); 0756 switch (id) { 0757 case DOMCSSRuleList::Item: 0758 return getDOMCSSRule(exec, cssRuleList.item(args[0]->toInteger(exec))); 0759 default: 0760 return jsUndefined(); 0761 } 0762 } 0763 0764 JSValue *getDOMCSSRuleList(ExecState *exec, DOM::CSSRuleListImpl *rl) 0765 { 0766 return cacheDOMObject<DOM::CSSRuleListImpl, KJS::DOMCSSRuleList>(exec, rl); 0767 } 0768 0769 // ------------------------------------------------------------------------- 0770 0771 KJS_IMPLEMENT_PROTOFUNC(DOMCSSRuleFunc) // Not a proto, but doesn't matter 0772 0773 DOMCSSRule::DOMCSSRule(ExecState *exec, DOM::CSSRuleImpl *r) 0774 : m_impl(r) 0775 { 0776 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 0777 } 0778 0779 DOMCSSRule::~DOMCSSRule() 0780 { 0781 ScriptInterpreter::forgetDOMObject(m_impl.get()); 0782 } 0783 0784 const ClassInfo DOMCSSRule::info = { "CSSRule", nullptr, &DOMCSSRuleTable, nullptr }; 0785 const ClassInfo DOMCSSRule::style_info = { "CSSStyleRule", &DOMCSSRule::info, &DOMCSSStyleRuleTable, nullptr }; 0786 const ClassInfo DOMCSSRule::media_info = { "CSSMediaRule", &DOMCSSRule::info, &DOMCSSMediaRuleTable, nullptr }; 0787 const ClassInfo DOMCSSRule::fontface_info = { "CSSFontFaceRule", &DOMCSSRule::info, &DOMCSSFontFaceRuleTable, nullptr }; 0788 const ClassInfo DOMCSSRule::page_info = { "CSSPageRule", &DOMCSSRule::info, &DOMCSSPageRuleTable, nullptr }; 0789 const ClassInfo DOMCSSRule::import_info = { "CSSImportRule", &DOMCSSRule::info, &DOMCSSImportRuleTable, nullptr }; 0790 const ClassInfo DOMCSSRule::charset_info = { "CSSCharsetRule", &DOMCSSRule::info, &DOMCSSCharsetRuleTable, nullptr }; 0791 const ClassInfo DOMCSSRule::namespace_info = { "CSSNamespaceRule", &DOMCSSRule::info, &DOMCSSNamespaceRuleTable, nullptr }; 0792 0793 const ClassInfo *DOMCSSRule::classInfo() const 0794 { 0795 switch (m_impl->type()) { 0796 case DOM::CSSRule::STYLE_RULE: 0797 return &style_info; 0798 case DOM::CSSRule::MEDIA_RULE: 0799 return &media_info; 0800 case DOM::CSSRule::FONT_FACE_RULE: 0801 return &fontface_info; 0802 case DOM::CSSRule::PAGE_RULE: 0803 return &page_info; 0804 case DOM::CSSRule::IMPORT_RULE: 0805 return &import_info; 0806 case DOM::CSSRule::CHARSET_RULE: 0807 return &charset_info; 0808 case DOM::CSSRule::NAMESPACE_RULE: 0809 return &namespace_info; 0810 case DOM::CSSRule::UNKNOWN_RULE: 0811 default: 0812 return &info; 0813 } 0814 } 0815 /* 0816 @begin DOMCSSRuleTable 4 0817 type DOMCSSRule::Type DontDelete|ReadOnly 0818 cssText DOMCSSRule::CssText DontDelete|ReadOnly 0819 parentStyleSheet DOMCSSRule::ParentStyleSheet DontDelete|ReadOnly 0820 parentRule DOMCSSRule::ParentRule DontDelete|ReadOnly 0821 @end 0822 @begin DOMCSSStyleRuleTable 2 0823 selectorText DOMCSSRule::Style_SelectorText DontDelete 0824 style DOMCSSRule::Style_Style DontDelete|ReadOnly 0825 @end 0826 @begin DOMCSSMediaRuleTable 4 0827 media DOMCSSRule::Media_Media DontDelete|ReadOnly 0828 cssRules DOMCSSRule::Media_CssRules DontDelete|ReadOnly 0829 insertRule DOMCSSRule::Media_InsertRule DontDelete|Function 2 0830 deleteRule DOMCSSRule::Media_DeleteRule DontDelete|Function 1 0831 @end 0832 @begin DOMCSSFontFaceRuleTable 1 0833 style DOMCSSRule::FontFace_Style DontDelete|ReadOnly 0834 @end 0835 @begin DOMCSSPageRuleTable 2 0836 selectorText DOMCSSRule::Page_SelectorText DontDelete 0837 style DOMCSSRule::Page_Style DontDelete|ReadOnly 0838 @end 0839 @begin DOMCSSImportRuleTable 3 0840 href DOMCSSRule::Import_Href DontDelete|ReadOnly 0841 media DOMCSSRule::Import_Media DontDelete|ReadOnly 0842 styleSheet DOMCSSRule::Import_StyleSheet DontDelete|ReadOnly 0843 @end 0844 @begin DOMCSSCharsetRuleTable 1 0845 encoding DOMCSSRule::Charset_Encoding DontDelete 0846 @end 0847 @begin DOMCSSNamespaceRuleTable 2 0848 namespaceURI DOMCSSRule::Namespace_NamespaceURI DontDelete|ReadOnly 0849 prefix DOMCSSRule::Namespace_Prefix DontDelete|ReadOnly 0850 @end 0851 */ 0852 bool DOMCSSRule::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0853 { 0854 #ifdef KJS_VERBOSE 0855 qCDebug(KHTML_LOG) << "DOMCSSRule::tryGet " << propertyName.qstring(); 0856 #endif 0857 //First do the rule-type-specific stuff 0858 const HashTable *table = classInfo()->propHashTable; // get the right hashtable 0859 if (getStaticOwnPropertySlot<DOMCSSRuleFunc, DOMCSSRule>(table, this, propertyName, slot)) { 0860 return true; 0861 } 0862 0863 //Now do generic stuff 0864 return getStaticPropertySlot<DOMCSSRuleFunc, DOMCSSRule, DOMObject>(exec, &DOMCSSRuleTable, this, propertyName, slot); 0865 } 0866 0867 JSValue *DOMCSSRule::getValueProperty(ExecState *exec, int token) const 0868 { 0869 CSSRuleImpl &cssRule = *m_impl; 0870 switch (token) { 0871 case Type: 0872 return jsNumber(cssRule.type()); 0873 case CssText: 0874 return jsString(cssRule.cssText()); 0875 case ParentStyleSheet: 0876 return getDOMStyleSheet(exec, cssRule.parentStyleSheet()); 0877 case ParentRule: 0878 return getDOMCSSRule(exec, cssRule.parentRule()); 0879 0880 // for DOM::CSSRule::STYLE_RULE: 0881 case Style_SelectorText: 0882 return jsString(static_cast<CSSStyleRuleImpl *>(m_impl.get())->selectorText()); 0883 case Style_Style: 0884 return getDOMCSSStyleDeclaration(exec, static_cast<CSSStyleRuleImpl *>(m_impl.get())->style()); 0885 0886 // for DOM::CSSRule::MEDIA_RULE: 0887 case Media_Media: 0888 return getDOMMediaList(exec, static_cast<CSSMediaRuleImpl *>(m_impl.get())->media()); 0889 case Media_CssRules: 0890 return getDOMCSSRuleList(exec, static_cast<CSSMediaRuleImpl *>(m_impl.get())->cssRules()); 0891 0892 // for DOM::CSSRule::FONT_FACE_RULE: 0893 case FontFace_Style: 0894 return getDOMCSSStyleDeclaration(exec, static_cast<CSSFontFaceRuleImpl *>(m_impl.get())->style()); 0895 0896 // for DOM::CSSRule::PAGE_RULE: 0897 case Page_SelectorText: 0898 return jsString(static_cast<CSSPageRuleImpl *>(m_impl.get())->selectorText()); 0899 case Page_Style: 0900 return getDOMCSSStyleDeclaration(exec, static_cast<CSSPageRuleImpl *>(m_impl.get())->style()); 0901 0902 // for DOM::CSSRule::IMPORT_RULE: 0903 case Import_Href: 0904 return jsString(static_cast<CSSImportRuleImpl *>(m_impl.get())->href()); 0905 case Import_Media: 0906 return getDOMMediaList(exec, static_cast<CSSImportRuleImpl *>(m_impl.get())->media()); 0907 case Import_StyleSheet: 0908 return getDOMStyleSheet(exec, static_cast<CSSImportRuleImpl *>(m_impl.get())->styleSheet()); 0909 0910 // for DOM::CSSRule::CHARSET_RULE: 0911 case Charset_Encoding: 0912 return jsString(static_cast<CSSCharsetRuleImpl *>(m_impl.get())->encoding()); 0913 0914 // for DOM::CSSRule::NAMESPACE_RULE: 0915 case Namespace_Prefix: 0916 return jsString(static_cast<DOM::CSSNamespaceRuleImpl *>(m_impl.get())->prefix()); 0917 case Namespace_NamespaceURI: 0918 return jsString(static_cast<DOM::CSSNamespaceRuleImpl *>(m_impl.get())->namespaceURI()); 0919 default: 0920 assert(0); 0921 } 0922 return jsUndefined(); 0923 } 0924 0925 void DOMCSSRule::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) 0926 { 0927 const HashTable *table = classInfo()->propHashTable; // get the right hashtable 0928 const HashEntry *entry = Lookup::findEntry(table, propertyName); 0929 if (entry) { 0930 if (entry->attr & Function) { // function: put as override property 0931 JSObject::put(exec, propertyName, value, attr); 0932 return; 0933 } else if ((entry->attr & ReadOnly) == 0) { // let lookupPut print the warning if not 0934 putValueProperty(exec, entry->value, value, attr); 0935 return; 0936 } 0937 } 0938 lookupPut<DOMCSSRule, DOMObject>(exec, propertyName, value, attr, &DOMCSSRuleTable, this); 0939 } 0940 0941 void DOMCSSRule::putValueProperty(ExecState *exec, int token, JSValue *value, int) 0942 { 0943 switch (token) { 0944 // for DOM::CSSRule::STYLE_RULE: 0945 case Style_SelectorText: 0946 static_cast<CSSStyleRuleImpl *>(m_impl.get())->setSelectorText(value->toString(exec).domString()); 0947 return; 0948 0949 // for DOM::CSSRule::PAGE_RULE: 0950 case Page_SelectorText: 0951 static_cast<CSSPageRuleImpl *>(m_impl.get())->setSelectorText(value->toString(exec).domString()); 0952 return; 0953 0954 // for DOM::CSSRule::CHARSET_RULE: 0955 case Charset_Encoding: 0956 static_cast<CSSCharsetRuleImpl *>(m_impl.get())->setEncoding(value->toString(exec).domString()); 0957 return; 0958 0959 default: 0960 // qCDebug(KHTML_LOG) << "DOMCSSRule::putValueProperty unhandled token " << token; 0961 return; 0962 } 0963 } 0964 0965 JSValue *DOMCSSRuleFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0966 { 0967 KJS_CHECK_THIS(KJS::DOMCSSRule, thisObj); 0968 DOM::CSSRuleImpl &cssRule = *static_cast<DOMCSSRule *>(thisObj)->impl(); 0969 0970 if (cssRule.type() == DOM::CSSRule::MEDIA_RULE) { 0971 DOM::CSSMediaRuleImpl &rule = static_cast<DOM::CSSMediaRuleImpl &>(cssRule); 0972 if (id == DOMCSSRule::Media_InsertRule) { 0973 return jsNumber(rule.insertRule(args[0]->toString(exec).domString(), args[1]->toInteger(exec))); 0974 } else if (id == DOMCSSRule::Media_DeleteRule) { 0975 rule.deleteRule(args[0]->toInteger(exec)); 0976 } 0977 } 0978 0979 return jsUndefined(); 0980 } 0981 0982 JSValue *getDOMCSSRule(ExecState *exec, DOM::CSSRuleImpl *r) 0983 { 0984 return cacheDOMObject<DOM::CSSRuleImpl, KJS::DOMCSSRule>(exec, r); 0985 } 0986 0987 // ------------------------------------------------------------------------- 0988 0989 const ClassInfo CSSRuleConstructor::info = { "CSSRuleConstructor", nullptr, &CSSRuleConstructorTable, nullptr }; 0990 /* 0991 @begin CSSRuleConstructorTable 7 0992 UNKNOWN_RULE CSSRuleConstructor::UNKNOWN_RULE DontDelete|ReadOnly 0993 STYLE_RULE CSSRuleConstructor::STYLE_RULE DontDelete|ReadOnly 0994 CHARSET_RULE CSSRuleConstructor::CHARSET_RULE DontDelete|ReadOnly 0995 IMPORT_RULE CSSRuleConstructor::IMPORT_RULE DontDelete|ReadOnly 0996 MEDIA_RULE CSSRuleConstructor::MEDIA_RULE DontDelete|ReadOnly 0997 FONT_FACE_RULE CSSRuleConstructor::FONT_FACE_RULE DontDelete|ReadOnly 0998 PAGE_RULE CSSRuleConstructor::PAGE_RULE DontDelete|ReadOnly 0999 @end 1000 */ 1001 1002 CSSRuleConstructor::CSSRuleConstructor(ExecState *exec) 1003 { 1004 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 1005 } 1006 1007 bool CSSRuleConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 1008 { 1009 return getStaticValueSlot<CSSRuleConstructor, DOMObject>(exec, &CSSRuleConstructorTable, this, propertyName, slot); 1010 } 1011 1012 JSValue *CSSRuleConstructor::getValueProperty(ExecState *, int token) const 1013 { 1014 switch (token) { 1015 case UNKNOWN_RULE: 1016 return jsNumber(DOM::CSSRule::UNKNOWN_RULE); 1017 case STYLE_RULE: 1018 return jsNumber(DOM::CSSRule::STYLE_RULE); 1019 case CHARSET_RULE: 1020 return jsNumber(DOM::CSSRule::CHARSET_RULE); 1021 case IMPORT_RULE: 1022 return jsNumber(DOM::CSSRule::IMPORT_RULE); 1023 case MEDIA_RULE: 1024 return jsNumber(DOM::CSSRule::MEDIA_RULE); 1025 case FONT_FACE_RULE: 1026 return jsNumber(DOM::CSSRule::FONT_FACE_RULE); 1027 case PAGE_RULE: 1028 return jsNumber(DOM::CSSRule::PAGE_RULE); 1029 } 1030 return nullptr; 1031 } 1032 1033 JSValue *getCSSRuleConstructor(ExecState *exec) 1034 { 1035 return cacheGlobalObject<CSSRuleConstructor>(exec, "[[cssRule.constructor]]"); 1036 } 1037 1038 // ------------------------------------------------------------------------- 1039 1040 const ClassInfo DOMCSSValue::info = { "CSSValue", nullptr, &DOMCSSValueTable, nullptr }; 1041 1042 /* 1043 @begin DOMCSSValueTable 2 1044 cssText DOMCSSValue::CssText DontDelete|ReadOnly 1045 cssValueType DOMCSSValue::CssValueType DontDelete|ReadOnly 1046 @end 1047 */ 1048 1049 DOMCSSValue::DOMCSSValue(ExecState *exec, DOM::CSSValueImpl *val) 1050 : m_impl(val) 1051 { 1052 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 1053 } 1054 1055 DOMCSSValue::~DOMCSSValue() 1056 { 1057 ScriptInterpreter::forgetDOMObject(m_impl.get()); 1058 } 1059 1060 JSValue *DOMCSSValue::getValueProperty(ExecState *, int token) const 1061 { 1062 CSSValueImpl &cssValue = *m_impl; 1063 switch (token) { 1064 case CssText: 1065 return jsString(cssValue.cssText()); 1066 case CssValueType: 1067 return jsNumber(cssValue.cssValueType()); 1068 default: 1069 assert(0); 1070 return jsUndefined(); 1071 } 1072 } 1073 1074 bool DOMCSSValue::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 1075 { 1076 return getStaticValueSlot<DOMCSSValue, DOMObject>(exec, &DOMCSSValueTable, this, propertyName, slot); 1077 } 1078 1079 void DOMCSSValue::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) 1080 { 1081 CSSValueImpl &cssValue = *m_impl; 1082 if (propertyName == "cssText") { 1083 cssValue.setCssText(value->toString(exec).domString()); 1084 } else { 1085 DOMObject::put(exec, propertyName, value, attr); 1086 } 1087 } 1088 1089 JSValue *getDOMCSSValue(ExecState *exec, DOM::CSSValueImpl *v) 1090 { 1091 DOMObject *ret; 1092 if (!v) { 1093 return jsNull(); 1094 } 1095 ScriptInterpreter *interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter()); 1096 if ((ret = interp->getDOMObject(v))) { 1097 return ret; 1098 } else { 1099 if (v->isValueList()) { 1100 ret = new DOMCSSValueList(exec, static_cast<CSSValueListImpl *>(v)); 1101 } else if (v->isPrimitiveValue()) { 1102 ret = new DOMCSSPrimitiveValue(exec, static_cast<CSSPrimitiveValueImpl *>(v)); 1103 } else { 1104 ret = new DOMCSSValue(exec, v); 1105 } 1106 interp->putDOMObject(v, ret); 1107 return ret; 1108 } 1109 } 1110 1111 // ------------------------------------------------------------------------- 1112 1113 const ClassInfo CSSValueConstructor::info = { "CSSValueConstructor", nullptr, &CSSValueConstructorTable, nullptr }; 1114 /* 1115 @begin CSSValueConstructorTable 5 1116 CSS_INHERIT CSSValueConstructor::CSS_INHERIT DontDelete|ReadOnly 1117 CSS_PRIMITIVE_VALUE CSSValueConstructor::CSS_PRIMITIVE_VALUE DontDelete|ReadOnly 1118 CSS_VALUE_LIST CSSValueConstructor::CSS_VALUE_LIST DontDelete|ReadOnly 1119 CSS_CUSTOM CSSValueConstructor::CSS_CUSTOM DontDelete|ReadOnly 1120 @end 1121 */ 1122 1123 CSSValueConstructor::CSSValueConstructor(ExecState *exec) 1124 { 1125 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 1126 } 1127 1128 bool CSSValueConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 1129 { 1130 return getStaticValueSlot<CSSValueConstructor, DOMObject>(exec, &CSSValueConstructorTable, this, propertyName, slot); 1131 } 1132 1133 JSValue *CSSValueConstructor::getValueProperty(ExecState *, int token) const 1134 { 1135 switch (token) { 1136 case CSS_INHERIT: 1137 return jsNumber(DOM::CSSValue::CSS_INHERIT); 1138 case CSS_PRIMITIVE_VALUE: 1139 return jsNumber(DOM::CSSValue::CSS_PRIMITIVE_VALUE); 1140 case CSS_VALUE_LIST: 1141 return jsNumber(DOM::CSSValue::CSS_VALUE_LIST); 1142 case CSS_CUSTOM: 1143 return jsNumber(DOM::CSSValue::CSS_CUSTOM); 1144 } 1145 return nullptr; 1146 } 1147 1148 JSValue *getCSSValueConstructor(ExecState *exec) 1149 { 1150 return cacheGlobalObject<CSSValueConstructor>(exec, "[[cssValue.constructor]]"); 1151 } 1152 1153 // ------------------------------------------------------------------------- 1154 1155 const ClassInfo DOMCSSPrimitiveValue::info = { "CSSPrimitiveValue", nullptr, &DOMCSSPrimitiveValueTable, nullptr }; 1156 /* 1157 @begin DOMCSSPrimitiveValueTable 1 1158 primitiveType DOMCSSPrimitiveValue::PrimitiveType DontDelete|ReadOnly 1159 @end 1160 @begin DOMCSSPrimitiveValueProtoTable 3 1161 setFloatValue DOMCSSPrimitiveValue::SetFloatValue DontDelete|Function 2 1162 getFloatValue DOMCSSPrimitiveValue::GetFloatValue DontDelete|Function 1 1163 setStringValue DOMCSSPrimitiveValue::SetStringValue DontDelete|Function 2 1164 getStringValue DOMCSSPrimitiveValue::GetStringValue DontDelete|Function 0 1165 getCounterValue DOMCSSPrimitiveValue::GetCounterValue DontDelete|Function 0 1166 getRectValue DOMCSSPrimitiveValue::GetRectValue DontDelete|Function 0 1167 getRGBColorValue DOMCSSPrimitiveValue::GetRGBColorValue DontDelete|Function 0 1168 @end 1169 */ 1170 KJS_DEFINE_PROTOTYPE(DOMCSSPrimitiveValueProto) 1171 KJS_IMPLEMENT_PROTOFUNC(DOMCSSPrimitiveValueProtoFunc) 1172 KJS_IMPLEMENT_PROTOTYPE("DOMCSSPrimitiveValue", DOMCSSPrimitiveValueProto, DOMCSSPrimitiveValueProtoFunc, ObjectPrototype) 1173 1174 DOMCSSPrimitiveValue::DOMCSSPrimitiveValue(ExecState *exec, DOM::CSSPrimitiveValueImpl *v) 1175 : DOMCSSValue(exec, v) 1176 { 1177 setPrototype(DOMCSSPrimitiveValueProto::self(exec)); 1178 } 1179 1180 JSValue *DOMCSSPrimitiveValue::getValueProperty(ExecState *, int token) 1181 { 1182 assert(token == PrimitiveType); 1183 Q_UNUSED(token); 1184 return jsNumber(static_cast<CSSPrimitiveValueImpl *>(impl())->primitiveType()); 1185 } 1186 1187 bool DOMCSSPrimitiveValue::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 1188 { 1189 return getStaticValueSlot<DOMCSSPrimitiveValue, DOMCSSValue>(exec, &DOMCSSPrimitiveValueTable, this, propertyName, slot); 1190 } 1191 1192 JSValue *DOMCSSPrimitiveValueProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 1193 { 1194 KJS_CHECK_THIS(KJS::DOMCSSPrimitiveValue, thisObj); 1195 CSSPrimitiveValueImpl &val = *static_cast<CSSPrimitiveValueImpl *>(static_cast<DOMCSSPrimitiveValue *>(thisObj)->impl()); 1196 DOMExceptionTranslator exception(exec); 1197 switch (id) { 1198 case DOMCSSPrimitiveValue::SetFloatValue: 1199 val.setFloatValue(args[0]->toInteger(exec), args[1]->toNumber(exec), exception); 1200 return jsUndefined(); 1201 case DOMCSSPrimitiveValue::GetFloatValue: 1202 //### FIXME: exception? 1203 return jsNumber(val.floatValue(args[0]->toInteger(exec))); 1204 case DOMCSSPrimitiveValue::SetStringValue: 1205 val.setStringValue(args[0]->toInteger(exec), args[1]->toString(exec).domString(), exception); 1206 return jsUndefined(); 1207 case DOMCSSPrimitiveValue::GetStringValue: 1208 return jsString(DOM::DOMString(val.getStringValue())); 1209 case DOMCSSPrimitiveValue::GetCounterValue: 1210 return getDOMCounter(exec, val.getCounterValue()); 1211 case DOMCSSPrimitiveValue::GetRectValue: 1212 return getDOMRect(exec, val.getRectValue()); 1213 case DOMCSSPrimitiveValue::GetRGBColorValue: 1214 return getDOMRGBColor(exec, val.getRGBColorValue()); 1215 default: 1216 return jsUndefined(); 1217 } 1218 } 1219 1220 // ------------------------------------------------------------------------- 1221 1222 const ClassInfo CSSPrimitiveValueConstructor::info = { "CSSPrimitiveValueConstructor", nullptr, &CSSPrimitiveValueConstructorTable, nullptr }; 1223 1224 /* 1225 @begin CSSPrimitiveValueConstructorTable 28 1226 CSS_UNKNOWN DOM::CSSPrimitiveValue::CSS_UNKNOWN DontDelete|ReadOnly 1227 CSS_NUMBER DOM::CSSPrimitiveValue::CSS_NUMBER DontDelete|ReadOnly 1228 CSS_PERCENTAGE DOM::CSSPrimitiveValue::CSS_PERCENTAGE DontDelete|ReadOnly 1229 CSS_EMS DOM::CSSPrimitiveValue::CSS_EMS DontDelete|ReadOnly 1230 CSS_EXS DOM::CSSPrimitiveValue::CSS_EXS DontDelete|ReadOnly 1231 CSS_CHS DOM::CSSPrimitiveValue::CSS_CHS DontDelete|ReadOnly 1232 CSS_REMS DOM::CSSPrimitiveValue::CSS_REMS DontDelete|ReadOnly 1233 CSS_PX DOM::CSSPrimitiveValue::CSS_PX DontDelete|ReadOnly 1234 CSS_CM DOM::CSSPrimitiveValue::CSS_CM DontDelete|ReadOnly 1235 CSS_MM DOM::CSSPrimitiveValue::CSS_MM DontDelete|ReadOnly 1236 CSS_IN DOM::CSSPrimitiveValue::CSS_IN DontDelete|ReadOnly 1237 CSS_PT DOM::CSSPrimitiveValue::CSS_PT DontDelete|ReadOnly 1238 CSS_PC DOM::CSSPrimitiveValue::CSS_PC DontDelete|ReadOnly 1239 CSS_DEG DOM::CSSPrimitiveValue::CSS_DEG DontDelete|ReadOnly 1240 CSS_RAD DOM::CSSPrimitiveValue::CSS_RAD DontDelete|ReadOnly 1241 CSS_GRAD DOM::CSSPrimitiveValue::CSS_GRAD DontDelete|ReadOnly 1242 CSS_MS DOM::CSSPrimitiveValue::CSS_MS DontDelete|ReadOnly 1243 CSS_S DOM::CSSPrimitiveValue::CSS_S DontDelete|ReadOnly 1244 CSS_HZ DOM::CSSPrimitiveValue::CSS_HZ DontDelete|ReadOnly 1245 CSS_KHZ DOM::CSSPrimitiveValue::CSS_KHZ DontDelete|ReadOnly 1246 CSS_DIMENSION DOM::CSSPrimitiveValue::CSS_DIMENSION DontDelete|ReadOnly 1247 CSS_STRING DOM::CSSPrimitiveValue::CSS_STRING DontDelete|ReadOnly 1248 CSS_URI DOM::CSSPrimitiveValue::CSS_URI DontDelete|ReadOnly 1249 CSS_IDENT DOM::CSSPrimitiveValue::CSS_IDENT DontDelete|ReadOnly 1250 CSS_ATTR DOM::CSSPrimitiveValue::CSS_ATTR DontDelete|ReadOnly 1251 CSS_COUNTER DOM::CSSPrimitiveValue::CSS_COUNTER DontDelete|ReadOnly 1252 CSS_RECT DOM::CSSPrimitiveValue::CSS_RECT DontDelete|ReadOnly 1253 CSS_RGBCOLOR DOM::CSSPrimitiveValue::CSS_RGBCOLOR DontDelete|ReadOnly 1254 @end 1255 */ 1256 1257 bool CSSPrimitiveValueConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 1258 { 1259 return getStaticValueSlot<CSSPrimitiveValueConstructor, DOMObject>(exec, &CSSPrimitiveValueConstructorTable, this, propertyName, slot); 1260 } 1261 1262 JSValue *CSSPrimitiveValueConstructor::getValueProperty(ExecState *, int token) const 1263 { 1264 // We use the token as the value to return directly 1265 return jsNumber(token); 1266 } 1267 1268 JSValue *getCSSPrimitiveValueConstructor(ExecState *exec) 1269 { 1270 return cacheGlobalObject<CSSPrimitiveValueConstructor>(exec, "[[cssPrimitiveValue.constructor]]"); 1271 } 1272 1273 // ------------------------------------------------------------------------- 1274 1275 const ClassInfo DOMCSSValueList::info = { "CSSValueList", nullptr, &DOMCSSValueListTable, nullptr }; 1276 1277 /* 1278 @begin DOMCSSValueListTable 3 1279 length DOMCSSValueList::Length DontDelete|ReadOnly 1280 item DOMCSSValueList::Item DontDelete|Function 1 1281 @end 1282 */ 1283 KJS_IMPLEMENT_PROTOFUNC(DOMCSSValueListFunc) // not really a proto, but doesn't matter 1284 1285 DOMCSSValueList::DOMCSSValueList(ExecState *exec, DOM::CSSValueListImpl *v) 1286 : DOMCSSValue(exec, v) { } 1287 1288 JSValue *DOMCSSValueList::indexGetter(ExecState *exec, unsigned index) 1289 { 1290 return getDOMCSSValue(exec, impl()->item(index)); 1291 } 1292 1293 bool DOMCSSValueList::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 1294 { 1295 if (getStaticOwnPropertySlot<DOMCSSValueListFunc, DOMCSSValueList>( 1296 &DOMCSSValueListTable, this, propertyName, slot)) { 1297 return true; 1298 } 1299 1300 CSSValueListImpl &valueList = *static_cast<CSSValueListImpl *>(impl()); 1301 if (getIndexSlot(this, valueList, propertyName, slot)) { 1302 return true; 1303 } 1304 1305 return DOMCSSValue::getOwnPropertySlot(exec, propertyName, slot); 1306 } 1307 1308 JSValue *DOMCSSValueListFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 1309 { 1310 KJS_CHECK_THIS(KJS::DOMCSSValueList, thisObj); 1311 CSSValueListImpl &valueList = *static_cast<CSSValueListImpl *>(static_cast<DOMCSSValueList *>(thisObj)->impl()); 1312 switch (id) { 1313 case DOMCSSValueList::Item: 1314 return getDOMCSSValue(exec, valueList.item(args[0]->toInteger(exec))); 1315 default: 1316 return jsUndefined(); 1317 } 1318 } 1319 1320 // ------------------------------------------------------------------------- 1321 1322 const ClassInfo DOMRGBColor::info = { "RGBColor", nullptr, &DOMRGBColorTable, nullptr }; 1323 1324 /* 1325 @begin DOMRGBColorTable 3 1326 red DOMRGBColor::Red DontDelete|ReadOnly 1327 green DOMRGBColor::Green DontDelete|ReadOnly 1328 blue DOMRGBColor::Blue DontDelete|ReadOnly 1329 @end 1330 */ 1331 1332 DOMRGBColor::DOMRGBColor(ExecState *exec, QRgb c) 1333 : m_color(c) 1334 { 1335 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 1336 } 1337 1338 bool DOMRGBColor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 1339 { 1340 return getStaticValueSlot<DOMRGBColor, DOMObject>(exec, &DOMRGBColorTable, this, propertyName, slot); 1341 } 1342 1343 JSValue *DOMRGBColor::getValueProperty(ExecState *exec, int token) const 1344 { 1345 int color; 1346 switch (token) { 1347 case Red: 1348 color = qRed(m_color); break; 1349 case Green: 1350 color = qGreen(m_color); break; 1351 case Blue: 1352 color = qBlue(m_color); break; 1353 default: 1354 assert(0); 1355 return jsUndefined(); 1356 } 1357 1358 return new DOMCSSPrimitiveValue(exec, new CSSPrimitiveValueImpl(color, CSSPrimitiveValue::CSS_NUMBER)); 1359 } 1360 1361 JSValue *getDOMRGBColor(ExecState *exec, unsigned color) 1362 { 1363 // ### implement equals for RGBColor since they're not refcounted objects 1364 return new DOMRGBColor(exec, color); 1365 } 1366 1367 // ------------------------------------------------------------------------- 1368 1369 const ClassInfo DOMRect::info = { "Rect", nullptr, &DOMRectTable, nullptr }; 1370 /* 1371 @begin DOMRectTable 4 1372 top DOMRect::Top DontDelete|ReadOnly 1373 right DOMRect::Right DontDelete|ReadOnly 1374 bottom DOMRect::Bottom DontDelete|ReadOnly 1375 left DOMRect::Left DontDelete|ReadOnly 1376 @end 1377 */ 1378 1379 DOMRect::DOMRect(ExecState *exec, DOM::RectImpl *r) 1380 : m_impl(r) 1381 { 1382 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 1383 } 1384 1385 DOMRect::~DOMRect() 1386 { 1387 ScriptInterpreter::forgetDOMObject(m_impl.get()); 1388 } 1389 1390 bool DOMRect::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 1391 { 1392 return getStaticValueSlot<DOMRect, DOMObject>(exec, &DOMRectTable, this, propertyName, slot); 1393 } 1394 1395 JSValue *DOMRect::getValueProperty(ExecState *exec, int token) const 1396 { 1397 DOM::RectImpl &rect = *m_impl; 1398 switch (token) { 1399 case Top: 1400 return getDOMCSSValue(exec, rect.top()); 1401 case Right: 1402 return getDOMCSSValue(exec, rect.right()); 1403 case Bottom: 1404 return getDOMCSSValue(exec, rect.bottom()); 1405 case Left: 1406 return getDOMCSSValue(exec, rect.left()); 1407 default: 1408 return nullptr; 1409 } 1410 } 1411 1412 JSValue *getDOMRect(ExecState *exec, DOM::RectImpl *r) 1413 { 1414 return cacheDOMObject<DOM::RectImpl, KJS::DOMRect>(exec, r); 1415 } 1416 1417 // ------------------------------------------------------------------------- 1418 1419 const ClassInfo DOMCounter::info = { "Counter", nullptr, &DOMCounterTable, nullptr }; 1420 /* 1421 @begin DOMCounterTable 3 1422 identifier DOMCounter::identifier DontDelete|ReadOnly 1423 listStyle DOMCounter::listStyle DontDelete|ReadOnly 1424 separator DOMCounter::separator DontDelete|ReadOnly 1425 @end 1426 */ 1427 DOMCounter::DOMCounter(ExecState *exec, DOM::CounterImpl *c) 1428 : m_impl(c) 1429 { 1430 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 1431 } 1432 1433 DOMCounter::~DOMCounter() 1434 { 1435 ScriptInterpreter::forgetDOMObject(m_impl.get()); 1436 } 1437 1438 bool DOMCounter::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 1439 { 1440 return getStaticValueSlot<DOMCounter, DOMObject>(exec, &DOMCounterTable, this, propertyName, slot); 1441 } 1442 1443 JSValue *DOMCounter::getValueProperty(ExecState *, int token) const 1444 { 1445 CounterImpl &counter = *m_impl; 1446 switch (token) { 1447 case identifier: 1448 return jsString(counter.identifier()); 1449 case listStyle: 1450 return jsString(khtml::stringForListStyleType((khtml::EListStyleType)counter.listStyle())); 1451 case separator: 1452 return jsString(counter.separator()); 1453 default: 1454 return nullptr; 1455 } 1456 } 1457 1458 JSValue *getDOMCounter(ExecState *exec, DOM::CounterImpl *c) 1459 { 1460 return cacheDOMObject<DOM::CounterImpl, KJS::DOMCounter>(exec, c); 1461 } 1462 1463 } 1464