KHtml

kjs_css.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2000 Harri Porten ([email protected])
4  * Copyright (C) 2001 Peter Kelly ([email protected])
5  * Copyright (C) 2003 Apple Computer, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "kjs_css.h"
23 #include "kjs_css.lut.h"
24 
25 #include "html/html_headimpl.h" // for HTMLStyleElementImpl
26 
27 #include "dom/css_value.h"
28 #include "dom/css_rule.h"
29 
30 #include "css/css_renderstyledeclarationimpl.h"
31 #include "css/cssproperties.h"
32 
33 #include "kjs_dom.h"
34 
35 using DOM::CSSCharsetRuleImpl;
36 using DOM::CSSFontFaceRuleImpl;
37 using DOM::CSSImportRuleImpl;
38 using DOM::CSSMediaRuleImpl;
39 using DOM::CSSPageRuleImpl;
41 using DOM::CSSPrimitiveValueImpl;
42 using DOM::CSSRule;
43 using DOM::CSSRuleImpl;
44 using DOM::CSSRuleListImpl;
45 using DOM::CSSStyleDeclarationImpl;
46 using DOM::CSSStyleRuleImpl;
47 using DOM::CSSStyleSheetImpl;
48 using DOM::CSSValue;
49 using DOM::CSSValueImpl;
50 using DOM::CSSValueListImpl;
51 using DOM::CounterImpl;
52 using DOM::DocumentImpl;
53 using DOM::DOMString;
54 using DOM::ElementImpl;
55 using DOM::HTMLStyleElementImpl;
56 using DOM::MediaListImpl;
57 using DOM::RectImpl;
58 using DOM::StyleSheetImpl;
59 using DOM::StyleSheetListImpl;
60 
61 #include "khtml_debug.h"
62 #include <QList>
63 
64 namespace KJS
65 {
66 
67 static QString cssPropertyName(const Identifier &p, bool *hadPixelPrefix)
68 {
69  // The point here is to provide compatibility with IE
70  // syntax for accessing properties, which camel-cases them
71  // and can add prefixes to produce things like pixelFoo
72  QString prop = p.qstring();
73  for (int i = prop.length() - 1; i >= 0; --i) {
74  char c = prop[i].toLatin1();
75  if (c >= 'A' && c <= 'Z') {
76  prop.insert(i, '-');
77  }
78  }
79 
80  prop = prop.toLower();
81  *hadPixelPrefix = false;
82 
83  if (prop.startsWith(QLatin1String("css-"))) {
84  prop = prop.mid(4);
85  } else if (prop.startsWith(QLatin1String("pixel-"))) {
86  prop = prop.mid(6);
87  *hadPixelPrefix = true;
88  } else if (prop.startsWith(QLatin1String("pos-"))) {
89  prop = prop.mid(4);
90  *hadPixelPrefix = true;
91  }
92 
93  return prop;
94 }
95 
96 static int cssPropertyId(const QString &p)
97 {
98  return DOM::getPropertyID(p.toLatin1().constData(), p.length());
99 }
100 
101 static bool isCSSPropertyName(const Identifier &JSPropertyName)
102 {
103  bool dummy;
104  QString p = cssPropertyName(JSPropertyName, &dummy);
105  return cssPropertyId(p) != 0;
106 }
107 
108 /*
109 @begin DOMCSSStyleDeclarationProtoTable 7
110  getPropertyValue DOMCSSStyleDeclaration::GetPropertyValue DontDelete|Function 1
111  getPropertyCSSValue DOMCSSStyleDeclaration::GetPropertyCSSValue DontDelete|Function 1
112  removeProperty DOMCSSStyleDeclaration::RemoveProperty DontDelete|Function 1
113  getPropertyPriority DOMCSSStyleDeclaration::GetPropertyPriority DontDelete|Function 1
114  setProperty DOMCSSStyleDeclaration::SetProperty DontDelete|Function 3
115  item DOMCSSStyleDeclaration::Item DontDelete|Function 1
116 # IE names for it (#36063)
117  getAttribute DOMCSSStyleDeclaration::GetPropertyValue DontDelete|Function 1
118  removeAttribute DOMCSSStyleDeclaration::RemoveProperty DontDelete|Function 1
119  setAttribute DOMCSSStyleDeclaration::SetProperty DontDelete|Function 3
120 @end
121 @begin DOMCSSStyleDeclarationTable 3
122  cssText DOMCSSStyleDeclaration::CssText DontDelete
123  length DOMCSSStyleDeclaration::Length DontDelete|ReadOnly
124  parentRule DOMCSSStyleDeclaration::ParentRule DontDelete|ReadOnly
125 @end
126 */
127 KJS_DEFINE_PROTOTYPE(DOMCSSStyleDeclarationProto)
128 KJS_IMPLEMENT_PROTOFUNC(DOMCSSStyleDeclarationProtoFunc)
129 KJS_IMPLEMENT_PROTOTYPE("DOMCSSStyleDeclaration", DOMCSSStyleDeclarationProto, DOMCSSStyleDeclarationProtoFunc, ObjectPrototype)
130 
131 IMPLEMENT_PSEUDO_CONSTRUCTOR(CSSStyleDeclarationPseudoCtor, "DOMCSSStyleDeclaration", DOMCSSStyleDeclarationProto)
132 
133 const ClassInfo DOMCSSStyleDeclaration::info = { "CSSStyleDeclaration", nullptr, &DOMCSSStyleDeclarationTable, nullptr };
134 
135 DOMCSSStyleDeclaration::DOMCSSStyleDeclaration(ExecState *exec, DOM::CSSStyleDeclarationImpl *s)
136  : DOMObject(), m_impl(s)
137 {
138  setPrototype(DOMCSSStyleDeclarationProto::self(exec));
139 }
140 
141 DOMCSSStyleDeclaration::~DOMCSSStyleDeclaration()
142 {
143  ScriptInterpreter::forgetDOMObject(m_impl.get());
144 }
145 
146 JSValue *DOMCSSStyleDeclaration::getValueProperty(ExecState *exec, int token)
147 {
148  //### null decls?
149  switch (token) {
150  case CssText:
151  return jsString(m_impl->cssText());
152  case Length:
153  return jsNumber(m_impl->length());
154  case ParentRule:
155  return getDOMCSSRule(exec, m_impl->parentRule());
156  }
157 
158  assert(0);
159  return jsUndefined();
160 }
161 
162 JSValue *DOMCSSStyleDeclaration::indexGetter(ExecState *, unsigned index)
163 {
164  return jsString(m_impl->item(index));
165 }
166 
167 bool DOMCSSStyleDeclaration::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
168 {
169 #ifdef KJS_VERBOSE
170  qCDebug(KHTML_LOG) << "DOMCSSStyleDeclaration::getOwnPropertySlot " << propertyName.qstring();
171 #endif
172 
173  if (getStaticOwnValueSlot(&DOMCSSStyleDeclarationTable, this, propertyName, slot)) {
174  return true;
175  }
176 
177  //Check whether it's an index
178  if (getIndexSlot(this, propertyName, slot)) {
179  return true;
180  }
181 
182  if (isCSSPropertyName(propertyName)) {
183  // Set up pixelOrPos boolean to handle the fact that
184  // pixelTop returns "CSS Top" as number value in unit pixels
185  // posTop returns "CSS top" as number value in unit pixels _if_ its a
186  // positioned element. if it is not a positioned element, return 0
187  // from MSIE documentation ### IMPLEMENT THAT (Dirk)
188  bool asNumber;
189  DOMString p = cssPropertyName(propertyName, &asNumber);
190 
191  if (asNumber) {
192  CSSValueImpl *v = m_impl->getPropertyCSSValue(p);
193  if (v && v->cssValueType() == DOM::CSSValue::CSS_PRIMITIVE_VALUE)
194  //### FIXME: should this not set exception when type is wrong, or convert?
195  return getImmediateValueSlot(this,
196  jsNumber(static_cast<CSSPrimitiveValueImpl *>(v)->floatValue(DOM::CSSPrimitiveValue::CSS_PX)), slot);
197  }
198 
199  DOM::DOMString str = m_impl->getPropertyValue(p);
200 
201  // We want to return at least an empty string here --- see #152791
202  return getImmediateValueSlot(this, jsString(str), slot);
203  }
204 
205  return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
206 }
207 
208 void DOMCSSStyleDeclaration::getOwnPropertyNames(ExecState *exec, PropertyNameArray &arr, PropertyMap::PropertyMode mode)
209 {
210  DOMObject::getOwnPropertyNames(exec, arr, mode);
211 
212  // Add in all properties we support.
213  for (int p = 1; p < CSS_PROP_TOTAL; ++p) {
214  QString dashName = getPropertyName(p).string();
215  QString camelName;
216 
217  bool capitalize = false;
218  for (int c = 0; c < dashName.length(); ++c) {
219  if (dashName[c] == QLatin1Char('-')) {
220  capitalize = true;
221  } else {
222  camelName += capitalize ? dashName[c].toUpper() : dashName[c];
223  capitalize = false;
224  }
225  } // char
226 
227  arr.add(KJS::Identifier(camelName));
228  } // prop
229 }
230 
231 void DOMCSSStyleDeclaration::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
232 {
233 #ifdef KJS_VERBOSE
234  qCDebug(KHTML_LOG) << "DOMCSSStyleDeclaration::put " << propertyName.qstring();
235 #endif
236  DOMExceptionTranslator exception(exec);
237  CSSStyleDeclarationImpl &styleDecl = *m_impl;
238 
239  if (propertyName == "cssText") {
240  styleDecl.setCssText(valueToStringWithNullCheck(exec, value));
241  } else {
242  bool pxSuffix;
243  QString prop = cssPropertyName(propertyName, &pxSuffix);
244  QString propvalue = valueToStringWithNullCheck(exec, value).string();
245 
246  if (pxSuffix) {
247  propvalue += QLatin1String("px");
248  }
249 #ifdef KJS_VERBOSE
250  qCDebug(KHTML_LOG) << "DOMCSSStyleDeclaration: prop=" << prop << " propvalue=" << propvalue;
251 #endif
252  // Look whether the property is known. In that case add it as a CSS property.
253  if (int pId = cssPropertyId(prop)) {
254  if (propvalue.isEmpty()) {
255  styleDecl.removeProperty(pId);
256  } else {
257  int important = propvalue.indexOf("!important", 0, Qt::CaseInsensitive);
258  if (important == -1) {
259  styleDecl.setProperty(pId, DOM::DOMString(propvalue), false /*important*/, exception);
260  } else {
261  styleDecl.setProperty(pId, DOM::DOMString(propvalue.left(important - 1)), true /*important*/, exception);
262  }
263  }
264  } else
265  // otherwise add it as a JS property
266  {
267  DOMObject::put(exec, propertyName, value, attr);
268  }
269  }
270 }
271 
272 JSValue *DOMCSSStyleDeclarationProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
273 {
274  KJS_CHECK_THIS(KJS::DOMCSSStyleDeclaration, thisObj);
275  CSSStyleDeclarationImpl &styleDecl = *static_cast<DOMCSSStyleDeclaration *>(thisObj)->impl();
276 
277  const DOM::DOMString cssProp = args[0]->toString(exec).domString();
278 
279  switch (id) {
280  case DOMCSSStyleDeclaration::GetPropertyValue:
281  return jsString(styleDecl.getPropertyValue(cssProp));
282  case DOMCSSStyleDeclaration::GetPropertyCSSValue:
283  return getDOMCSSValue(exec, styleDecl.getPropertyCSSValue(cssProp));
284  case DOMCSSStyleDeclaration::RemoveProperty:
285  return jsString(styleDecl.removeProperty(cssProp));
286  case DOMCSSStyleDeclaration::GetPropertyPriority:
287  return jsString(styleDecl.getPropertyPriority(cssProp));
288  case DOMCSSStyleDeclaration::SetProperty: {
289  const DOM::DOMString cssVal = args[1]->toString(exec).domString();
290  if (cssVal.isEmpty()) {
291  styleDecl.removeProperty(cssProp);
292  } else {
293  styleDecl.setProperty(cssProp, cssVal, args[2]->toString(exec).domString());
294  }
295  return jsUndefined();
296  }
297  case DOMCSSStyleDeclaration::Item:
298  return jsString(styleDecl.item(args[0]->toInteger(exec)));
299  default:
300  return jsUndefined();
301  }
302 }
303 
304 JSValue *getDOMCSSStyleDeclaration(ExecState *exec, CSSStyleDeclarationImpl *s)
305 {
306  return cacheDOMObject<CSSStyleDeclarationImpl, DOMCSSStyleDeclaration>(exec, s);
307 }
308 
309 // -------------------------------------------------------------------------
310 
311 const ClassInfo DOMStyleSheet::info = { "StyleSheet", nullptr, &DOMStyleSheetTable, nullptr };
312 /*
313 @begin DOMStyleSheetTable 7
314  type DOMStyleSheet::Type DontDelete|ReadOnly
315  disabled DOMStyleSheet::Disabled DontDelete
316  ownerNode DOMStyleSheet::OwnerNode DontDelete|ReadOnly
317  parentStyleSheet DOMStyleSheet::ParentStyleSheet DontDelete|ReadOnly
318  href DOMStyleSheet::Href DontDelete|ReadOnly
319  title DOMStyleSheet::Title DontDelete|ReadOnly
320  media DOMStyleSheet::Media DontDelete|ReadOnly
321 @end
322 */
323 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("StyleSheet", DOMStyleSheetProto, ObjectPrototype)
324 IMPLEMENT_PSEUDO_CONSTRUCTOR(DOMStyleSheetPseudoCtor, "StyleSheet", DOMStyleSheetProto)
325 
326 DOMStyleSheet::DOMStyleSheet(ExecState *exec, DOM::StyleSheetImpl *ss)
327  : m_impl(ss)
328 {
329  setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
330 }
331 
332 DOMStyleSheet::~DOMStyleSheet()
333 {
334  ScriptInterpreter::forgetDOMObject(m_impl.get());
335 }
336 
337 bool DOMStyleSheet::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
338 {
339  return getStaticValueSlot<DOMStyleSheet, DOMObject>(exec, &DOMStyleSheetTable, this, propertyName, slot);
340 }
341 
342 JSValue *DOMStyleSheet::getValueProperty(ExecState *exec, int token) const
343 {
344  StyleSheetImpl &styleSheet = *m_impl;
345  switch (token) {
346  case Type:
347  return jsString(styleSheet.type());
348  case Disabled:
349  return jsBoolean(styleSheet.disabled());
350  case OwnerNode:
351  return getDOMNode(exec, styleSheet.ownerNode());
352  case ParentStyleSheet:
353  return getDOMStyleSheet(exec, styleSheet.parentStyleSheet());
354  case Href:
355  return getStringOrNull(styleSheet.href());
356  case Title:
357  return jsString(styleSheet.title());
358  case Media:
359  return getDOMMediaList(exec, styleSheet.media());
360  }
361  return nullptr;
362 }
363 
364 void DOMStyleSheet::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
365 {
366  StyleSheetImpl &styleSheet = *m_impl;
367  if (propertyName == "disabled") {
368  styleSheet.setDisabled(value->toBoolean(exec));
369  } else {
370  DOMObject::put(exec, propertyName, value, attr);
371  }
372 }
373 
374 JSValue *getDOMStyleSheet(ExecState *exec, DOM::StyleSheetImpl *ss)
375 {
376  if (!ss) {
377  return jsNull();
378  }
379 
380  DOMObject *ret;
381  ScriptInterpreter *interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
382  if ((ret = interp->getDOMObject(ss))) {
383  return ret;
384  } else {
385  if (ss->isCSSStyleSheet()) {
386  CSSStyleSheetImpl *cs = static_cast<CSSStyleSheetImpl *>(ss);
387  ret = new DOMCSSStyleSheet(exec, cs);
388  } else {
389  ret = new DOMStyleSheet(exec, ss);
390  }
391  interp->putDOMObject(ss, ret);
392  return ret;
393  }
394 }
395 
396 // -------------------------------------------------------------------------
397 
398 const ClassInfo DOMStyleSheetList::info = { "StyleSheetList", nullptr, &DOMStyleSheetListTable, nullptr };
399 
400 /*
401 @begin DOMStyleSheetListTable 2
402  length DOMStyleSheetList::Length DontDelete|ReadOnly
403  item DOMStyleSheetList::Item DontDelete|Function 1
404 @end
405 */
406 KJS_IMPLEMENT_PROTOFUNC(DOMStyleSheetListFunc) // not really a proto, but doesn't matter
407 
408 DOMStyleSheetList::DOMStyleSheetList(ExecState *exec, DOM::StyleSheetListImpl *ssl, DOM::DocumentImpl *doc)
409  : m_impl(ssl), m_doc(doc)
410 {
411  setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
412 }
413 
414 DOMStyleSheetList::~DOMStyleSheetList()
415 {
416  ScriptInterpreter::forgetDOMObject(m_impl.get());
417 }
418 
419 JSValue *DOMStyleSheetList::getValueProperty(ExecState *, int token) const
420 {
421  switch (token) {
422  case Length:
423  return jsNumber(m_impl->length());
424  default:
425  assert(0);
426  return jsUndefined();
427  }
428 }
429 
430 JSValue *DOMStyleSheetList::indexGetter(ExecState *exec, unsigned index)
431 {
432  return getDOMStyleSheet(exec, m_impl->item(index));
433 }
434 
435 JSValue *DOMStyleSheetList::nameGetter(ExecState *exec, JSObject *, const Identifier &propertyName, const PropertySlot &slot)
436 {
437  DOMStyleSheetList *thisObj = static_cast<DOMStyleSheetList *>(slot.slotBase());
438  ElementImpl *element = thisObj->m_doc->getElementById(propertyName.domString());
439  assert(element->id() == ID_STYLE); //Should be from existence check
440  return getDOMStyleSheet(exec, static_cast<HTMLStyleElementImpl *>(element)->sheet());
441 }
442 
443 bool DOMStyleSheetList::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
444 {
445 #ifdef KJS_VERBOSE
446  qCDebug(KHTML_LOG) << "DOMStyleSheetList::getOwnPropertySlot " << propertyName.qstring();
447 #endif
448  if (getStaticOwnPropertySlot<DOMStyleSheetListFunc, DOMStyleSheetList>(&DOMStyleSheetListTable, this, propertyName, slot)) {
449  return true;
450  }
451 
452  StyleSheetListImpl &styleSheetList = *m_impl;
453 
454  // Retrieve stylesheet by index
455  if (getIndexSlot(this, styleSheetList, propertyName, slot)) {
456  return true;
457  }
458 
459  // IE also supports retrieving a stylesheet by name, using the name/id of the <style> tag
460  // (this is consistent with all the other collections)
461  // ### Bad implementation because returns a single element (are IDs always unique?)
462  // and doesn't look for name attribute (see implementation above).
463  // But unicity of stylesheet ids is good practice anyway ;)
464  ElementImpl *element = m_doc->getElementById(propertyName.domString());
465  if (element && element->id() == ID_STYLE) {
466  slot.setCustom(this, nameGetter);
467  return true;
468  }
469 
470  return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
471 }
472 
473 JSValue *DOMStyleSheetList::callAsFunction(ExecState *exec, JSObject * /*thisObj*/, const List &args)
474 {
475  if (args.size() == 1) {
476  // support for styleSheets(<index>) and styleSheets(<name>)
477  return get(exec, Identifier(args[0]->toString(exec)));
478  }
479  return jsUndefined();
480 }
481 
482 JSValue *getDOMStyleSheetList(ExecState *exec, DOM::StyleSheetListImpl *ssl, DOM::DocumentImpl *doc)
483 {
484  // Can't use the cacheDOMObject macro because of the doc argument
485  DOMObject *ret;
486  if (!ssl) {
487  return jsNull();
488  }
489  ScriptInterpreter *interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
490  if ((ret = interp->getDOMObject(ssl))) {
491  return ret;
492  } else {
493  ret = new DOMStyleSheetList(exec, ssl, doc);
494  interp->putDOMObject(ssl, ret);
495  return ret;
496  }
497 }
498 
499 JSValue *DOMStyleSheetListFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
500 {
501  KJS_CHECK_THIS(KJS::DOMStyleSheetList, thisObj);
502  DOM::StyleSheetListImpl *styleSheetList = static_cast<DOMStyleSheetList *>(thisObj)->impl();
503  if (id == DOMStyleSheetList::Item) {
504  return getDOMStyleSheet(exec, styleSheetList->item(args[0]->toInteger(exec)));
505  }
506  return jsUndefined();
507 }
508 
509 // -------------------------------------------------------------------------
510 
511 const ClassInfo DOMMediaList::info = { "MediaList", nullptr, &DOMMediaListTable, nullptr };
512 
513 /*
514 @begin DOMMediaListTable 2
515  mediaText DOMMediaList::MediaText DontDelete|ReadOnly
516  length DOMMediaList::Length DontDelete|ReadOnly
517 @end
518 @begin DOMMediaListProtoTable 3
519  item DOMMediaList::Item DontDelete|Function 1
520  deleteMedium DOMMediaList::DeleteMedium DontDelete|Function 1
521  appendMedium DOMMediaList::AppendMedium DontDelete|Function 1
522 @end
523 */
524 KJS_DEFINE_PROTOTYPE(DOMMediaListProto)
525 KJS_IMPLEMENT_PROTOFUNC(DOMMediaListProtoFunc)
526 KJS_IMPLEMENT_PROTOTYPE("DOMMediaList", DOMMediaListProto, DOMMediaListProtoFunc, ObjectPrototype)
527 
528 DOMMediaList::DOMMediaList(ExecState *exec, DOM::MediaListImpl *ml)
529  : m_impl(ml)
530 {
531  setPrototype(DOMMediaListProto::self(exec));
532 }
533 
534 DOMMediaList::~DOMMediaList()
535 {
536  ScriptInterpreter::forgetDOMObject(m_impl.get());
537 }
538 
539 JSValue *DOMMediaList::getValueProperty(ExecState *, int token) const
540 {
541  const MediaListImpl &mediaList = *m_impl;
542  switch (token) {
543  case MediaText:
544  return jsString(mediaList.mediaText());
545  case Length:
546  return jsNumber(mediaList.length());
547  default:
548  assert(0);
549  return jsUndefined();
550  }
551 }
552 
553 JSValue *DOMMediaList::indexGetter(ExecState *, unsigned index)
554 {
555  return jsString(m_impl->item(index));
556 }
557 
558 bool DOMMediaList::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
559 {
560  if (getStaticOwnValueSlot(&DOMMediaListTable, this, propertyName, slot)) {
561  return true;
562  }
563 
564  if (getIndexSlot(this, *m_impl, propertyName, slot)) {
565  return true;
566  }
567 
568  return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
569 }
570 
571 void DOMMediaList::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
572 {
573  if (propertyName == "mediaText") {
574  DOMExceptionTranslator exception(exec);
575  m_impl->setMediaText(value->toString(exec).domString(), exception);
576  } else {
577  DOMObject::put(exec, propertyName, value, attr);
578  }
579 }
580 
581 JSValue *getDOMMediaList(ExecState *exec, DOM::MediaListImpl *ml)
582 {
583  return cacheDOMObject<DOM::MediaListImpl, KJS::DOMMediaList>(exec, ml);
584 }
585 
586 JSValue *DOMMediaListProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
587 {
588  KJS_CHECK_THIS(KJS::DOMMediaList, thisObj);
589  DOM::MediaListImpl &mediaList = *static_cast<DOMMediaList *>(thisObj)->impl();
590  DOMExceptionTranslator exception(exec);
591  switch (id) {
592  case DOMMediaList::Item:
593  return jsString(mediaList.item(args[0]->toInteger(exec)));
594  case DOMMediaList::DeleteMedium:
595  mediaList.deleteMedium(args[0]->toString(exec).domString(), exception);
596  return jsUndefined();
597  case DOMMediaList::AppendMedium:
598  mediaList.appendMedium(args[0]->toString(exec).domString(), exception);
599  return jsUndefined();
600  default:
601  return jsUndefined();
602  }
603 }
604 
605 // -------------------------------------------------------------------------
606 
607 const ClassInfo DOMCSSStyleSheet::info = { "CSSStyleSheet", nullptr, &DOMCSSStyleSheetTable, nullptr };
608 
609 /*
610 @begin DOMCSSStyleSheetTable 2
611  ownerRule DOMCSSStyleSheet::OwnerRule DontDelete|ReadOnly
612  cssRules DOMCSSStyleSheet::CssRules DontDelete|ReadOnly
613 # MSIE extension
614  rules DOMCSSStyleSheet::Rules DontDelete|ReadOnly
615 @end
616 @begin DOMCSSStyleSheetProtoTable 2
617  insertRule DOMCSSStyleSheet::InsertRule DontDelete|Function 2
618  deleteRule DOMCSSStyleSheet::DeleteRule DontDelete|Function 1
619 # IE extensions
620  addRule DOMCSSStyleSheet::AddRule DontDelete|Function 3
621  removeRule DOMCSSStyleSheet::RemoveRule DontDelete|Function 1
622 @end
623 */
624 KJS_DEFINE_PROTOTYPE(DOMCSSStyleSheetProto)
625 KJS_IMPLEMENT_PROTOFUNC(DOMCSSStyleSheetProtoFunc)
626 KJS_IMPLEMENT_PROTOTYPE("DOMCSSStyleSheet", DOMCSSStyleSheetProto, DOMCSSStyleSheetProtoFunc, DOMStyleSheetProto)
627 
628 DOMCSSStyleSheet::DOMCSSStyleSheet(ExecState *exec, DOM::CSSStyleSheetImpl *ss): DOMStyleSheet(exec, ss)
629 {
630  setPrototype(DOMCSSStyleSheetProto::self(exec));
631 }
632 
633 DOMCSSStyleSheet::~DOMCSSStyleSheet()
634 {}
635 
636 JSValue *DOMCSSStyleSheet::getValueProperty(ExecState *exec, int token)
637 {
638  CSSStyleSheetImpl &cssStyleSheet = *impl();
639  // MSIE does not list the charset rules in its proprietary extension
640  bool omitCharsetRules = true;
641  switch (token) {
642  case OwnerRule:
643  return getDOMCSSRule(exec, cssStyleSheet.ownerRule());
644  case CssRules:
645  omitCharsetRules = false;
646  // nobreak
647  case Rules: {
648  return getDOMCSSRuleList(exec, cssStyleSheet.cssRules(omitCharsetRules));
649  }
650  default:
651  assert(0);
652  return jsUndefined();
653  }
654 }
655 
656 bool DOMCSSStyleSheet::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
657 {
658  return getStaticValueSlot<DOMCSSStyleSheet, DOMStyleSheet>(exec, &DOMCSSStyleSheetTable, this, propertyName, slot);
659 }
660 
661 JSValue *DOMCSSStyleSheetProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
662 {
663  KJS_CHECK_THIS(KJS::DOMCSSStyleSheet, thisObj);
664  DOM::CSSStyleSheetImpl &styleSheet = *static_cast<DOMCSSStyleSheet *>(thisObj)->impl();
665  DOMExceptionTranslator exception(exec);
666 
667  switch (id) {
668  case DOMCSSStyleSheet::InsertRule:
669  return jsNumber(styleSheet.insertRule(args[0]->toString(exec).domString(), (long unsigned int)args[1]->toInteger(exec), exception));
670  case DOMCSSStyleSheet::DeleteRule:
671  styleSheet.deleteRule(args[0]->toInteger(exec), exception);
672  return jsUndefined();
673  // IE extensions
674  case DOMCSSStyleSheet::AddRule: {
675  //Unpassed/-1 means append. Since insertRule is picky (throws exceptions)
676  //we adjust it to the desired length
677  unsigned long index = args[2]->toInteger(exec);
678  unsigned long length = styleSheet.length();
679  if (args[2]->type() == UndefinedType) {
680  index = length;
681  }
682  if (index > length) {
683  index = length;
684  }
685  DOM::DOMString str = args[0]->toString(exec).domString() + " { " + args[1]->toString(exec).domString() + " } ";
686  return jsNumber(styleSheet.insertRule(str, index, exception));
687  }
688  case DOMCSSStyleSheet::RemoveRule: {
689  int index = args.size() > 0 ? args[0]->toInteger(exec) : 0 /*first one*/;
690  styleSheet.deleteRule(index, exception);
691  return jsUndefined();
692  }
693  default:
694  return jsUndefined();
695  }
696 }
697 
698 // -------------------------------------------------------------------------
699 
700 const ClassInfo DOMCSSRuleList::info = { "CSSRuleList", nullptr, &DOMCSSRuleListTable, nullptr };
701 /*
702 @begin DOMCSSRuleListTable 3
703  length DOMCSSRuleList::Length DontDelete|ReadOnly
704  item DOMCSSRuleList::Item DontDelete|Function 1
705 @end
706 */
707 KJS_IMPLEMENT_PROTOFUNC(DOMCSSRuleListFunc) // not really a proto, but doesn't matter
708 
709 DOMCSSRuleList::DOMCSSRuleList(ExecState *exec, DOM::CSSRuleListImpl *rl)
710  : m_impl(rl)
711 {
712  setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
713 }
714 
715 DOMCSSRuleList::~DOMCSSRuleList()
716 {
717  ScriptInterpreter::forgetDOMObject(m_impl.get());
718 }
719 
720 JSValue *DOMCSSRuleList::getValueProperty(ExecState *, int token) const
721 {
722  switch (token) {
723  case Length:
724  return jsNumber(m_impl->length());
725  default:
726  assert(0);
727  return jsUndefined();
728  }
729 }
730 
731 JSValue *DOMCSSRuleList::indexGetter(ExecState *exec, unsigned index)
732 {
733  return getDOMCSSRule(exec, m_impl->item(index));
734 }
735 
736 bool DOMCSSRuleList::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
737 {
738  if (getStaticOwnPropertySlot<DOMCSSRuleListFunc, DOMCSSRuleList>(&DOMCSSRuleListTable, this, propertyName, slot)) {
739  return true;
740  }
741 
742  //Check whether it's an index
743  //CSSRuleListImpl &cssRuleList = *m_impl;
744 
745  if (getIndexSlot(this, *m_impl, propertyName, slot)) {
746  return true;
747  }
748 
749  return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
750 }
751 
752 JSValue *DOMCSSRuleListFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
753 {
754  KJS_CHECK_THIS(KJS::DOMCSSRuleList, thisObj);
755  DOM::CSSRuleListImpl &cssRuleList = *static_cast<DOMCSSRuleList *>(thisObj)->impl();
756  switch (id) {
757  case DOMCSSRuleList::Item:
758  return getDOMCSSRule(exec, cssRuleList.item(args[0]->toInteger(exec)));
759  default:
760  return jsUndefined();
761  }
762 }
763 
764 JSValue *getDOMCSSRuleList(ExecState *exec, DOM::CSSRuleListImpl *rl)
765 {
766  return cacheDOMObject<DOM::CSSRuleListImpl, KJS::DOMCSSRuleList>(exec, rl);
767 }
768 
769 // -------------------------------------------------------------------------
770 
771 KJS_IMPLEMENT_PROTOFUNC(DOMCSSRuleFunc) // Not a proto, but doesn't matter
772 
773 DOMCSSRule::DOMCSSRule(ExecState *exec, DOM::CSSRuleImpl *r)
774  : m_impl(r)
775 {
776  setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
777 }
778 
779 DOMCSSRule::~DOMCSSRule()
780 {
781  ScriptInterpreter::forgetDOMObject(m_impl.get());
782 }
783 
784 const ClassInfo DOMCSSRule::info = { "CSSRule", nullptr, &DOMCSSRuleTable, nullptr };
785 const ClassInfo DOMCSSRule::style_info = { "CSSStyleRule", &DOMCSSRule::info, &DOMCSSStyleRuleTable, nullptr };
786 const ClassInfo DOMCSSRule::media_info = { "CSSMediaRule", &DOMCSSRule::info, &DOMCSSMediaRuleTable, nullptr };
787 const ClassInfo DOMCSSRule::fontface_info = { "CSSFontFaceRule", &DOMCSSRule::info, &DOMCSSFontFaceRuleTable, nullptr };
788 const ClassInfo DOMCSSRule::page_info = { "CSSPageRule", &DOMCSSRule::info, &DOMCSSPageRuleTable, nullptr };
789 const ClassInfo DOMCSSRule::import_info = { "CSSImportRule", &DOMCSSRule::info, &DOMCSSImportRuleTable, nullptr };
790 const ClassInfo DOMCSSRule::charset_info = { "CSSCharsetRule", &DOMCSSRule::info, &DOMCSSCharsetRuleTable, nullptr };
791 const ClassInfo DOMCSSRule::namespace_info = { "CSSNamespaceRule", &DOMCSSRule::info, &DOMCSSNamespaceRuleTable, nullptr };
792 
793 const ClassInfo *DOMCSSRule::classInfo() const
794 {
795  switch (m_impl->type()) {
796  case DOM::CSSRule::STYLE_RULE:
797  return &style_info;
798  case DOM::CSSRule::MEDIA_RULE:
799  return &media_info;
800  case DOM::CSSRule::FONT_FACE_RULE:
801  return &fontface_info;
802  case DOM::CSSRule::PAGE_RULE:
803  return &page_info;
804  case DOM::CSSRule::IMPORT_RULE:
805  return &import_info;
806  case DOM::CSSRule::CHARSET_RULE:
807  return &charset_info;
809  return &namespace_info;
810  case DOM::CSSRule::UNKNOWN_RULE:
811  default:
812  return &info;
813  }
814 }
815 /*
816 @begin DOMCSSRuleTable 4
817  type DOMCSSRule::Type DontDelete|ReadOnly
818  cssText DOMCSSRule::CssText DontDelete|ReadOnly
819  parentStyleSheet DOMCSSRule::ParentStyleSheet DontDelete|ReadOnly
820  parentRule DOMCSSRule::ParentRule DontDelete|ReadOnly
821 @end
822 @begin DOMCSSStyleRuleTable 2
823  selectorText DOMCSSRule::Style_SelectorText DontDelete
824  style DOMCSSRule::Style_Style DontDelete|ReadOnly
825 @end
826 @begin DOMCSSMediaRuleTable 4
827  media DOMCSSRule::Media_Media DontDelete|ReadOnly
828  cssRules DOMCSSRule::Media_CssRules DontDelete|ReadOnly
829  insertRule DOMCSSRule::Media_InsertRule DontDelete|Function 2
830  deleteRule DOMCSSRule::Media_DeleteRule DontDelete|Function 1
831 @end
832 @begin DOMCSSFontFaceRuleTable 1
833  style DOMCSSRule::FontFace_Style DontDelete|ReadOnly
834 @end
835 @begin DOMCSSPageRuleTable 2
836  selectorText DOMCSSRule::Page_SelectorText DontDelete
837  style DOMCSSRule::Page_Style DontDelete|ReadOnly
838 @end
839 @begin DOMCSSImportRuleTable 3
840  href DOMCSSRule::Import_Href DontDelete|ReadOnly
841  media DOMCSSRule::Import_Media DontDelete|ReadOnly
842  styleSheet DOMCSSRule::Import_StyleSheet DontDelete|ReadOnly
843 @end
844 @begin DOMCSSCharsetRuleTable 1
845  encoding DOMCSSRule::Charset_Encoding DontDelete
846 @end
847 @begin DOMCSSNamespaceRuleTable 2
848  namespaceURI DOMCSSRule::Namespace_NamespaceURI DontDelete|ReadOnly
849  prefix DOMCSSRule::Namespace_Prefix DontDelete|ReadOnly
850 @end
851 */
852 bool DOMCSSRule::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
853 {
854 #ifdef KJS_VERBOSE
855  qCDebug(KHTML_LOG) << "DOMCSSRule::tryGet " << propertyName.qstring();
856 #endif
857  //First do the rule-type-specific stuff
858  const HashTable *table = classInfo()->propHashTable; // get the right hashtable
859  if (getStaticOwnPropertySlot<DOMCSSRuleFunc, DOMCSSRule>(table, this, propertyName, slot)) {
860  return true;
861  }
862 
863  //Now do generic stuff
864  return getStaticPropertySlot<DOMCSSRuleFunc, DOMCSSRule, DOMObject>(exec, &DOMCSSRuleTable, this, propertyName, slot);
865 }
866 
867 JSValue *DOMCSSRule::getValueProperty(ExecState *exec, int token) const
868 {
869  CSSRuleImpl &cssRule = *m_impl;
870  switch (token) {
871  case Type:
872  return jsNumber(cssRule.type());
873  case CssText:
874  return jsString(cssRule.cssText());
875  case ParentStyleSheet:
876  return getDOMStyleSheet(exec, cssRule.parentStyleSheet());
877  case ParentRule:
878  return getDOMCSSRule(exec, cssRule.parentRule());
879 
880  // for DOM::CSSRule::STYLE_RULE:
881  case Style_SelectorText:
882  return jsString(static_cast<CSSStyleRuleImpl *>(m_impl.get())->selectorText());
883  case Style_Style:
884  return getDOMCSSStyleDeclaration(exec, static_cast<CSSStyleRuleImpl *>(m_impl.get())->style());
885 
886  // for DOM::CSSRule::MEDIA_RULE:
887  case Media_Media:
888  return getDOMMediaList(exec, static_cast<CSSMediaRuleImpl *>(m_impl.get())->media());
889  case Media_CssRules:
890  return getDOMCSSRuleList(exec, static_cast<CSSMediaRuleImpl *>(m_impl.get())->cssRules());
891 
892  // for DOM::CSSRule::FONT_FACE_RULE:
893  case FontFace_Style:
894  return getDOMCSSStyleDeclaration(exec, static_cast<CSSFontFaceRuleImpl *>(m_impl.get())->style());
895 
896  // for DOM::CSSRule::PAGE_RULE:
897  case Page_SelectorText:
898  return jsString(static_cast<CSSPageRuleImpl *>(m_impl.get())->selectorText());
899  case Page_Style:
900  return getDOMCSSStyleDeclaration(exec, static_cast<CSSPageRuleImpl *>(m_impl.get())->style());
901 
902  // for DOM::CSSRule::IMPORT_RULE:
903  case Import_Href:
904  return jsString(static_cast<CSSImportRuleImpl *>(m_impl.get())->href());
905  case Import_Media:
906  return getDOMMediaList(exec, static_cast<CSSImportRuleImpl *>(m_impl.get())->media());
907  case Import_StyleSheet:
908  return getDOMStyleSheet(exec, static_cast<CSSImportRuleImpl *>(m_impl.get())->styleSheet());
909 
910  // for DOM::CSSRule::CHARSET_RULE:
911  case Charset_Encoding:
912  return jsString(static_cast<CSSCharsetRuleImpl *>(m_impl.get())->encoding());
913 
914  // for DOM::CSSRule::NAMESPACE_RULE:
915  case Namespace_Prefix:
916  return jsString(static_cast<DOM::CSSNamespaceRuleImpl *>(m_impl.get())->prefix());
917  case Namespace_NamespaceURI:
918  return jsString(static_cast<DOM::CSSNamespaceRuleImpl *>(m_impl.get())->namespaceURI());
919  default:
920  assert(0);
921  }
922  return jsUndefined();
923 }
924 
925 void DOMCSSRule::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
926 {
927  const HashTable *table = classInfo()->propHashTable; // get the right hashtable
928  const HashEntry *entry = Lookup::findEntry(table, propertyName);
929  if (entry) {
930  if (entry->attr & Function) { // function: put as override property
931  JSObject::put(exec, propertyName, value, attr);
932  return;
933  } else if ((entry->attr & ReadOnly) == 0) { // let lookupPut print the warning if not
934  putValueProperty(exec, entry->value, value, attr);
935  return;
936  }
937  }
938  lookupPut<DOMCSSRule, DOMObject>(exec, propertyName, value, attr, &DOMCSSRuleTable, this);
939 }
940 
941 void DOMCSSRule::putValueProperty(ExecState *exec, int token, JSValue *value, int)
942 {
943  switch (token) {
944  // for DOM::CSSRule::STYLE_RULE:
945  case Style_SelectorText:
946  static_cast<CSSStyleRuleImpl *>(m_impl.get())->setSelectorText(value->toString(exec).domString());
947  return;
948 
949  // for DOM::CSSRule::PAGE_RULE:
950  case Page_SelectorText:
951  static_cast<CSSPageRuleImpl *>(m_impl.get())->setSelectorText(value->toString(exec).domString());
952  return;
953 
954  // for DOM::CSSRule::CHARSET_RULE:
955  case Charset_Encoding:
956  static_cast<CSSCharsetRuleImpl *>(m_impl.get())->setEncoding(value->toString(exec).domString());
957  return;
958 
959  default:
960  // qCDebug(KHTML_LOG) << "DOMCSSRule::putValueProperty unhandled token " << token;
961  return;
962  }
963 }
964 
965 JSValue *DOMCSSRuleFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
966 {
967  KJS_CHECK_THIS(KJS::DOMCSSRule, thisObj);
968  DOM::CSSRuleImpl &cssRule = *static_cast<DOMCSSRule *>(thisObj)->impl();
969 
970  if (cssRule.type() == DOM::CSSRule::MEDIA_RULE) {
971  DOM::CSSMediaRuleImpl &rule = static_cast<DOM::CSSMediaRuleImpl &>(cssRule);
972  if (id == DOMCSSRule::Media_InsertRule) {
973  return jsNumber(rule.insertRule(args[0]->toString(exec).domString(), args[1]->toInteger(exec)));
974  } else if (id == DOMCSSRule::Media_DeleteRule) {
975  rule.deleteRule(args[0]->toInteger(exec));
976  }
977  }
978 
979  return jsUndefined();
980 }
981 
982 JSValue *getDOMCSSRule(ExecState *exec, DOM::CSSRuleImpl *r)
983 {
984  return cacheDOMObject<DOM::CSSRuleImpl, KJS::DOMCSSRule>(exec, r);
985 }
986 
987 // -------------------------------------------------------------------------
988 
989 const ClassInfo CSSRuleConstructor::info = { "CSSRuleConstructor", nullptr, &CSSRuleConstructorTable, nullptr };
990 /*
991 @begin CSSRuleConstructorTable 7
992  UNKNOWN_RULE CSSRuleConstructor::UNKNOWN_RULE DontDelete|ReadOnly
993  STYLE_RULE CSSRuleConstructor::STYLE_RULE DontDelete|ReadOnly
994  CHARSET_RULE CSSRuleConstructor::CHARSET_RULE DontDelete|ReadOnly
995  IMPORT_RULE CSSRuleConstructor::IMPORT_RULE DontDelete|ReadOnly
996  MEDIA_RULE CSSRuleConstructor::MEDIA_RULE DontDelete|ReadOnly
997  FONT_FACE_RULE CSSRuleConstructor::FONT_FACE_RULE DontDelete|ReadOnly
998  PAGE_RULE CSSRuleConstructor::PAGE_RULE DontDelete|ReadOnly
999 @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 
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
QString toUpper() const const
The CSSNamespaceRule interface represents an.
Definition: css_rule.h:455
Left
QString & insert(int position, QChar ch)
Type type(const QSqlDatabase &db)
CaseInsensitive
The CSSPrimitiveValue interface represents a single CSS value .
Definition: css_value.h:367
const char * constData() const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
QString toLower() const const
Right
static const HashEntry * findEntry(const struct HashTable *table, const Identifier &s)
This library provides a full-featured HTML parser and widget.
Top
QByteArray toLatin1() const const
QString mid(int position, int n) const const
char * toString(const T &value)
The CSSRule interface is the abstract base interface for any type of CSS statement ...
Definition: css_rule.h:53
int length() const const
Title
The CSSValue interface represents a simple or a complexe value.
Definition: css_value.h:237
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 22:47:57 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.