ca8aa3ce7e64c3a28dc61b6436ee91a11a177162
[WebKit-https.git] / WebCore / khtml / ecma / kjs_css.cpp
1 // -*- c-basic-offset: 2 -*-
2 /*
3  *  This file is part of the KDE libraries
4  *  Copyright (C) 2000 Harri Porten (porten@kde.org)
5  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
6  *  Copyright (C) 2004 Apple Computer, Inc.
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "config.h"
24 #include "kjs_css.h"
25
26 #include "css/css_base.h"
27 #include "css/css_ruleimpl.h"
28 #include "css/css_stylesheetimpl.h"
29 #include "css/css_valueimpl.h"
30 #include "DocumentImpl.h"
31 #include "html/html_headimpl.h" // for HTMLStyleElement
32 #include "kjs_dom.h"
33 #include "htmlnames.h"
34
35 #include "kjs_css.lut.h"
36
37 using namespace DOM::HTMLNames;
38
39 using namespace WebCore;
40
41 namespace KJS {
42
43 static DOMString cssPropertyName(const Identifier &p, bool *hadPixelOrPosPrefix = 0)
44 {
45     QString prop = p.qstring();
46
47     int i = prop.length();
48     while (--i) {
49         char c = prop[i].latin1();
50         if (c >= 'A' && c <= 'Z')
51             prop.insert(i, '-');
52     }
53
54     prop = prop.lower();
55
56     if (hadPixelOrPosPrefix)
57         *hadPixelOrPosPrefix = false;
58
59     if (prop.startsWith("css-")) {
60         prop = prop.mid(4);
61     } else if (prop.startsWith("pixel-")) {
62         prop = prop.mid(6);
63         if (hadPixelOrPosPrefix)
64             *hadPixelOrPosPrefix = true;
65     } else if (prop.startsWith("pos-")) {
66         prop = prop.mid(4);
67         if (hadPixelOrPosPrefix)
68             *hadPixelOrPosPrefix = true;
69     } else if (prop.startsWith("khtml-") || prop.startsWith("apple-") || prop.startsWith("moz-")) {
70         prop.insert(0, '-');
71     }
72
73     return prop;
74 }
75
76 static bool isCSSPropertyName(const Identifier &JSPropertyName)
77 {
78     return CSSStyleDeclarationImpl::isPropertyName(cssPropertyName(JSPropertyName));
79 }
80
81 /*
82 @begin DOMCSSStyleDeclarationProtoTable 7
83   getPropertyValue      DOMCSSStyleDeclaration::GetPropertyValue        DontDelete|Function 1
84   getPropertyCSSValue   DOMCSSStyleDeclaration::GetPropertyCSSValue     DontDelete|Function 1
85   removeProperty        DOMCSSStyleDeclaration::RemoveProperty          DontDelete|Function 1
86   getPropertyPriority   DOMCSSStyleDeclaration::GetPropertyPriority     DontDelete|Function 1
87   getPropertyShorthand  DOMCSSStyleDeclaration::GetPropertyShorthand    DontDelete|Function 1
88   isPropertyImplicit    DOMCSSStyleDeclaration::IsPropertyImplicit      DontDelete|Function 1
89   setProperty           DOMCSSStyleDeclaration::SetProperty             DontDelete|Function 3
90   item                  DOMCSSStyleDeclaration::Item                    DontDelete|Function 1
91 @end
92 @begin DOMCSSStyleDeclarationTable 3
93   cssText               DOMCSSStyleDeclaration::CssText         DontDelete
94   length                DOMCSSStyleDeclaration::Length          DontDelete|ReadOnly
95   parentRule            DOMCSSStyleDeclaration::ParentRule      DontDelete|ReadOnly
96 @end
97 */
98 KJS_DEFINE_PROTOTYPE(DOMCSSStyleDeclarationProto)
99 KJS_IMPLEMENT_PROTOFUNC(DOMCSSStyleDeclarationProtoFunc)
100 KJS_IMPLEMENT_PROTOTYPE("DOMCSSStyleDeclaration", DOMCSSStyleDeclarationProto, DOMCSSStyleDeclarationProtoFunc)
101
102 const ClassInfo DOMCSSStyleDeclaration::info = { "CSSStyleDeclaration", 0, &DOMCSSStyleDeclarationTable, 0 };
103
104 DOMCSSStyleDeclaration::DOMCSSStyleDeclaration(ExecState *exec, CSSStyleDeclarationImpl *s)
105   : m_impl(s)
106
107   setPrototype(DOMCSSStyleDeclarationProto::self(exec));
108 }
109
110 DOMCSSStyleDeclaration::~DOMCSSStyleDeclaration()
111 {
112   ScriptInterpreter::forgetDOMObject(m_impl.get());
113 }
114
115 JSValue *DOMCSSStyleDeclaration::indexGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
116 {
117   DOMCSSStyleDeclaration *thisObj = static_cast<DOMCSSStyleDeclaration *>(slot.slotBase());
118   return jsStringOrNull(thisObj->m_impl->item(slot.index()));
119 }
120
121 JSValue *DOMCSSStyleDeclaration::cssPropertyGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
122 {
123   DOMCSSStyleDeclaration *thisObj = static_cast<DOMCSSStyleDeclaration *>(slot.slotBase());
124
125   // Set up pixelOrPos boolean to handle the fact that
126   // pixelTop returns "CSS Top" as number value in unit pixels
127   // posTop returns "CSS top" as number value in unit pixels _if_ its a
128   // positioned element. if it is not a positioned element, return 0
129   // from MSIE documentation ### IMPLEMENT THAT (Dirk)
130   bool pixelOrPos;
131   DOMString prop = cssPropertyName(propertyName, &pixelOrPos);
132   RefPtr<CSSValueImpl> v = thisObj->m_impl->getPropertyCSSValue(prop);
133   if (v) {
134     if (pixelOrPos && v->cssValueType() == CSSValueImpl::CSS_PRIMITIVE_VALUE)
135       return jsNumber(static_pointer_cast<CSSPrimitiveValueImpl>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX));
136     return jsStringOrNull(v->cssText());
137   }
138   // If the property is a shorthand property (such as "padding"), 
139   // it can only be accessed using getPropertyValue.
140   return jsString(thisObj->m_impl->getPropertyValue(prop));
141 }
142
143 bool DOMCSSStyleDeclaration::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
144 {
145   const HashEntry* entry = Lookup::findEntry(&DOMCSSStyleDeclarationTable, propertyName);
146
147   if (entry) {
148     slot.setStaticEntry(this, entry, staticValueGetter<DOMCSSStyleDeclaration>);
149     return true;
150   }
151
152   bool ok;
153   unsigned u = propertyName.toUInt32(&ok);
154   if (ok) {
155     slot.setCustomIndex(this, u, indexGetter);
156     return true;
157   }
158
159   if (isCSSPropertyName(propertyName)) {
160     slot.setCustom(this, cssPropertyGetter);
161     return true;
162   }
163
164   return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
165 }
166
167 JSValue *DOMCSSStyleDeclaration::getValueProperty(ExecState *exec, int token)
168 {
169   switch (token) {
170   case CssText:
171     return jsStringOrNull(m_impl->cssText());
172   case Length:
173     return jsNumber(m_impl->length());
174   case ParentRule:
175     return getDOMCSSRule(exec, m_impl->parentRule());
176   default:
177     assert(0);
178     return jsUndefined();
179   }
180 }
181
182 void DOMCSSStyleDeclaration::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr )
183 {
184 #ifdef KJS_VERBOSE
185   kdDebug(6070) << "DOMCSSStyleDeclaration::put " << propertyName.qstring() << endl;
186 #endif
187   DOMExceptionTranslator exception(exec);
188   CSSStyleDeclarationImpl &styleDecl = *m_impl;
189   if (propertyName == "cssText") {
190     styleDecl.setCssText(value->toString(exec).domString(), exception);
191   } else {
192     if (isCSSPropertyName(propertyName)) {
193       bool pixelOrPos;
194       DOMString prop = cssPropertyName(propertyName, &pixelOrPos);
195       DOMString propvalue = value->toString(exec).domString();
196       if (pixelOrPos)
197         propvalue += "px";
198 #ifdef KJS_VERBOSE
199       kdDebug(6070) << "DOMCSSStyleDeclaration: prop=" << prop << " propvalue=" << propvalue << endl;
200 #endif
201       styleDecl.removeProperty(prop, exception);
202       if (!exception && !propvalue.isEmpty()) {
203         // We have to ignore exceptions here, because of the following unfortunate situation:
204         //   1) Older versions ignored exceptions here by accident, because the put function
205         //      that translated exceptions did not translate CSS exceptions.
206         //   2) Gecko does not raise an exception in this case, although WinIE does.
207         //   3) At least some Dashboard widgets are depending on this behavior.
208         // It would be nice to fix this some day, perhaps with some kind of "quirks mode",
209         // but it's likely that the Dashboard widgets are already using a strict mode DOCTYPE.
210         ExceptionCode ec = 0;
211         styleDecl.setProperty(prop, propvalue, "", ec);
212       }
213     } else {
214       DOMObject::put(exec, propertyName, value, attr);
215     }
216   }
217 }
218
219 JSValue *DOMCSSStyleDeclarationProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
220 {
221   if (!thisObj->inherits(&KJS::DOMCSSStyleDeclaration::info))
222     return throwError(exec, TypeError);
223   DOMExceptionTranslator exception(exec);
224   CSSStyleDeclarationImpl &styleDecl = *static_cast<DOMCSSStyleDeclaration *>(thisObj)->impl();
225   UString str = args[0]->toString(exec);
226   DOM::DOMString s = str.domString();
227
228   switch (id) {
229     case DOMCSSStyleDeclaration::GetPropertyValue:
230       return jsStringOrNull(styleDecl.getPropertyValue(s));
231     case DOMCSSStyleDeclaration::GetPropertyCSSValue:
232       return getDOMCSSValue(exec, styleDecl.getPropertyCSSValue(s).get());
233     case DOMCSSStyleDeclaration::RemoveProperty:
234       return jsStringOrNull(styleDecl.removeProperty(s, exception));
235     case DOMCSSStyleDeclaration::GetPropertyPriority:
236       return jsStringOrNull(styleDecl.getPropertyPriority(s));
237     case DOMCSSStyleDeclaration::GetPropertyShorthand:
238       return jsStringOrNull(styleDecl.getPropertyShorthand(s));
239     case DOMCSSStyleDeclaration::IsPropertyImplicit:
240       return jsBoolean(styleDecl.isPropertyImplicit(s));
241     case DOMCSSStyleDeclaration::SetProperty:
242       styleDecl.setProperty(s, args[1]->toString(exec).domString(), args[2]->toString(exec).domString(), exception);
243       return jsUndefined();
244     case DOMCSSStyleDeclaration::Item:
245       return jsStringOrNull(styleDecl.item(args[0]->toInt32(exec)));
246     default:
247       return jsUndefined();
248   }
249 }
250
251 JSValue *getDOMCSSStyleDeclaration(ExecState *exec, CSSStyleDeclarationImpl *s)
252 {
253   return cacheDOMObject<CSSStyleDeclarationImpl, DOMCSSStyleDeclaration>(exec, s);
254 }
255
256 // -------------------------------------------------------------------------
257
258 const ClassInfo DOMStyleSheet::info = { "StyleSheet", 0, &DOMStyleSheetTable, 0 };
259 /*
260 @begin DOMStyleSheetTable 7
261   type          DOMStyleSheet::Type             DontDelete|ReadOnly
262   disabled      DOMStyleSheet::Disabled         DontDelete
263   ownerNode     DOMStyleSheet::OwnerNode        DontDelete|ReadOnly
264   parentStyleSheet DOMStyleSheet::ParentStyleSheet      DontDelete|ReadOnly
265   href          DOMStyleSheet::Href             DontDelete|ReadOnly
266   title         DOMStyleSheet::Title            DontDelete|ReadOnly
267   media         DOMStyleSheet::Media            DontDelete|ReadOnly
268 @end
269 */
270
271 DOMStyleSheet::~DOMStyleSheet()
272 {
273   ScriptInterpreter::forgetDOMObject(m_impl.get());
274 }
275
276 bool DOMStyleSheet::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
277 {
278   return getStaticValueSlot<DOMStyleSheet, DOMObject>(exec, &DOMStyleSheetTable, this, propertyName, slot);
279 }
280
281 JSValue *DOMStyleSheet::getValueProperty(ExecState *exec, int token) const
282 {
283   StyleSheetImpl &styleSheet = *m_impl;
284   switch (token) {
285   case Type:
286     return jsStringOrNull(styleSheet.type());
287   case Disabled:
288     return jsBoolean(styleSheet.disabled());
289   case OwnerNode:
290     return getDOMNode(exec,styleSheet.ownerNode());
291   case ParentStyleSheet:
292     return getDOMStyleSheet(exec,styleSheet.parentStyleSheet());
293   case Href:
294     return jsStringOrNull(styleSheet.href());
295   case Title:
296     return jsStringOrNull(styleSheet.title());
297   case Media:
298     return getDOMMediaList(exec, styleSheet.media());
299   }
300   return NULL;
301 }
302
303 void DOMStyleSheet::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
304 {
305   if (propertyName == "disabled") {
306     m_impl->setDisabled(value->toBoolean(exec));
307   }
308   else
309     DOMObject::put(exec, propertyName, value, attr);
310 }
311
312 JSValue* getDOMStyleSheet(ExecState *exec, PassRefPtr<StyleSheetImpl> ss)
313 {
314   DOMObject *ret;
315   if (!ss)
316     return jsNull();
317   ScriptInterpreter *interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
318   if ((ret = interp->getDOMObject(ss.get())))
319     return ret;
320   else {
321     if (ss->isCSSStyleSheet())
322       ret = new DOMCSSStyleSheet(exec, static_cast<CSSStyleSheetImpl *>(ss.get()));
323     else
324       ret = new DOMStyleSheet(exec, ss.get());
325     interp->putDOMObject(ss.get(), ret);
326     return ret;
327   }
328 }
329
330 // -------------------------------------------------------------------------
331
332 const ClassInfo DOMStyleSheetList::info = { "StyleSheetList", 0, &DOMStyleSheetListTable, 0 };
333
334 /*
335 @begin DOMStyleSheetListTable 2
336   length        DOMStyleSheetList::Length       DontDelete|ReadOnly
337   item          DOMStyleSheetList::Item         DontDelete|Function 1
338 @end
339 */
340 KJS_IMPLEMENT_PROTOFUNC(DOMStyleSheetListFunc) // not really a proto, but doesn't matter
341
342 DOMStyleSheetList::~DOMStyleSheetList()
343 {
344   ScriptInterpreter::forgetDOMObject(m_impl.get());
345 }
346
347 JSValue *DOMStyleSheetList::getValueProperty(ExecState *exec, int token) const
348 {
349     switch(token) {
350     case Length:
351       return jsNumber(m_impl->length());
352     default:
353       assert(0);
354       return jsUndefined();
355     }
356 }
357
358 JSValue *DOMStyleSheetList::indexGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
359 {
360   DOMStyleSheetList *thisObj = static_cast<DOMStyleSheetList *>(slot.slotBase());
361   return getDOMStyleSheet(exec, thisObj->m_impl->item(slot.index()));
362 }
363
364 JSValue *DOMStyleSheetList::nameGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
365 {
366   DOMStyleSheetList *thisObj = static_cast<DOMStyleSheetList *>(slot.slotBase());
367   ElementImpl *element = thisObj->m_doc->getElementById(propertyName.domString().impl());
368   return getDOMStyleSheet(exec, static_cast<HTMLStyleElementImpl *>(element)->sheet());
369 }
370
371 bool DOMStyleSheetList::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
372 {
373   const HashEntry* entry = Lookup::findEntry(&DOMStyleSheetListTable, propertyName);
374   
375   if (entry) {
376     switch(entry->value) {
377     case Length:
378       slot.setStaticEntry(this, entry, staticValueGetter<DOMStyleSheetList>);
379       return true;
380     case Item:
381       slot.setStaticEntry(this, entry, staticFunctionGetter<DOMStyleSheetListFunc>);
382       return true;
383     }
384   }
385
386   StyleSheetListImpl &styleSheetList = *m_impl;
387
388   // Retrieve stylesheet by index
389   bool ok;
390   unsigned u = propertyName.toUInt32(&ok);
391   if (ok && u < styleSheetList.length()) {
392     slot.setCustomIndex(this, u, indexGetter);
393     return true;
394   }
395
396   // IE also supports retrieving a stylesheet by name, using the name/id of the <style> tag
397   // (this is consistent with all the other collections)
398   // ### Bad implementation because returns a single element (are IDs always unique?)
399   // and doesn't look for name attribute (see implementation above).
400   // But unicity of stylesheet ids is good practice anyway ;)
401   ElementImpl *element = m_doc->getElementById(propertyName.domString().impl());
402   if (element && element->hasTagName(styleTag)) {
403     slot.setCustom(this, nameGetter);
404     return true;
405   }
406
407   return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
408 }
409
410 JSValue *getDOMStyleSheetList(ExecState *exec, StyleSheetListImpl *ssl, DocumentImpl *doc)
411 {
412   // Can't use the cacheDOMObject macro because of the doc argument
413   DOMObject *ret;
414   if (!ssl)
415     return jsNull();
416   ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
417   if ((ret = interp->getDOMObject(ssl)))
418     return ret;
419   else {
420     ret = new DOMStyleSheetList(exec, ssl, doc);
421     interp->putDOMObject(ssl, ret);
422     return ret;
423   }
424 }
425
426 JSValue *DOMStyleSheetListFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
427 {
428   if (!thisObj->inherits(&KJS::DOMStyleSheetList::info))
429     return throwError(exec, TypeError);
430   StyleSheetListImpl &styleSheetList = *static_cast<DOMStyleSheetList *>(thisObj)->impl();
431   if (id == DOMStyleSheetList::Item)
432     return getDOMStyleSheet(exec, styleSheetList.item(args[0]->toInt32(exec)));
433   return jsUndefined();
434 }
435
436 // -------------------------------------------------------------------------
437
438 const ClassInfo DOMMediaList::info = { "MediaList", 0, &DOMMediaListTable, 0 };
439
440 /*
441 @begin DOMMediaListTable 2
442   mediaText     DOMMediaList::MediaText         DontDelete|ReadOnly
443   length        DOMMediaList::Length            DontDelete|ReadOnly
444 @end
445 @begin DOMMediaListProtoTable 3
446   item          DOMMediaList::Item              DontDelete|Function 1
447   deleteMedium  DOMMediaList::DeleteMedium      DontDelete|Function 1
448   appendMedium  DOMMediaList::AppendMedium      DontDelete|Function 1
449 @end
450 */
451 KJS_DEFINE_PROTOTYPE(DOMMediaListProto)
452 KJS_IMPLEMENT_PROTOFUNC(DOMMediaListProtoFunc)
453 KJS_IMPLEMENT_PROTOTYPE("DOMMediaList", DOMMediaListProto, DOMMediaListProtoFunc)
454
455 DOMMediaList::DOMMediaList(ExecState *exec, MediaListImpl *ml)
456     : m_impl(ml)
457 {
458   setPrototype(DOMMediaListProto::self(exec));
459 }
460
461 DOMMediaList::~DOMMediaList()
462 {
463   ScriptInterpreter::forgetDOMObject(m_impl.get());
464 }
465
466 JSValue *DOMMediaList::getValueProperty(ExecState *exec, int token)
467 {
468   switch (token) {
469   case MediaText:
470     return jsStringOrNull(m_impl->mediaText());
471   case Length:
472     return jsNumber(m_impl->length());
473   default:
474     assert(0);
475     return jsUndefined();
476   }
477 }
478
479 JSValue *DOMMediaList::indexGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
480 {
481   DOMMediaList *thisObj = static_cast<DOMMediaList *>(slot.slotBase());
482   return jsStringOrNull(thisObj->m_impl->item(slot.index()));
483 }
484
485 bool DOMMediaList::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
486 {
487   const HashEntry* entry = Lookup::findEntry(&DOMMediaListTable, propertyName);
488   if (entry) {
489     slot.setStaticEntry(this, entry, staticValueGetter<DOMMediaList>);
490     return true;
491   }
492
493   bool ok;
494   unsigned u = propertyName.toUInt32(&ok);
495   if (ok && u < m_impl->length()) {
496     slot.setCustomIndex(this, u, indexGetter);
497     return true;
498   }
499
500   return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
501 }
502
503 void DOMMediaList::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
504 {
505   MediaListImpl &mediaList = *m_impl;
506   if (propertyName == "mediaText")
507     mediaList.setMediaText(value->toString(exec).domString());
508   else
509     DOMObject::put(exec, propertyName, value, attr);
510 }
511
512 JSValue *getDOMMediaList(ExecState *exec, MediaListImpl *ml)
513 {
514   return cacheDOMObject<MediaListImpl, DOMMediaList>(exec, ml);
515 }
516
517 JSValue *KJS::DOMMediaListProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
518 {
519   if (!thisObj->inherits(&KJS::DOMMediaList::info))
520     return throwError(exec, TypeError);
521   MediaListImpl &mediaList = *static_cast<DOMMediaList *>(thisObj)->impl();
522   switch (id) {
523     case DOMMediaList::Item:
524       return jsStringOrNull(mediaList.item(args[0]->toInt32(exec)));
525     case DOMMediaList::DeleteMedium:
526       mediaList.deleteMedium(args[0]->toString(exec).domString());
527       return jsUndefined();
528     case DOMMediaList::AppendMedium:
529       mediaList.appendMedium(args[0]->toString(exec).domString());
530       return jsUndefined();
531     default:
532       return jsUndefined();
533   }
534 }
535
536 // -------------------------------------------------------------------------
537
538 const ClassInfo DOMCSSStyleSheet::info = { "CSSStyleSheet", 0, &DOMCSSStyleSheetTable, 0 };
539
540 /*
541 @begin DOMCSSStyleSheetTable 5
542   ownerRule     DOMCSSStyleSheet::OwnerRule     DontDelete|ReadOnly
543   cssRules      DOMCSSStyleSheet::CssRules      DontDelete|ReadOnly
544 # MSIE extension
545   rules         DOMCSSStyleSheet::Rules         DontDelete|ReadOnly
546 @end
547 @begin DOMCSSStyleSheetProtoTable 6
548   insertRule    DOMCSSStyleSheet::InsertRule    DontDelete|Function 2
549   deleteRule    DOMCSSStyleSheet::DeleteRule    DontDelete|Function 1
550 # MSIE extensions
551   addRule       DOMCSSStyleSheet::AddRule       DontDelete|Function 2
552   removeRule    DOMCSSStyleSheet::RemoveRule    DontDelete|Function 1
553 @end
554 */
555 KJS_DEFINE_PROTOTYPE(DOMCSSStyleSheetProto)
556 KJS_IMPLEMENT_PROTOFUNC(DOMCSSStyleSheetProtoFunc)
557 KJS_IMPLEMENT_PROTOTYPE("DOMCSSStyleSheet",DOMCSSStyleSheetProto,DOMCSSStyleSheetProtoFunc) // warning, use _WITH_PARENT if DOMStyleSheet gets a proto
558
559 DOMCSSStyleSheet::DOMCSSStyleSheet(ExecState *exec, CSSStyleSheetImpl *ss)
560   : DOMStyleSheet(ss) 
561 {
562   setPrototype(DOMCSSStyleSheetProto::self(exec));
563 }
564
565 DOMCSSStyleSheet::~DOMCSSStyleSheet()
566 {
567 }
568
569 JSValue *DOMCSSStyleSheet::getValueProperty(ExecState *exec, int token) const
570 {
571   switch (token) {
572   case OwnerRule:
573     return getDOMCSSRule(exec, static_cast<CSSStyleSheetImpl *>(impl())->ownerRule());
574   case CssRules:
575   case Rules:
576     return getDOMCSSRuleList(exec, static_cast<CSSStyleSheetImpl *>(impl())->cssRules());
577   default:
578     assert(0);
579     return jsUndefined();
580   }
581 }
582
583 bool DOMCSSStyleSheet::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
584 {
585   return getStaticValueSlot<DOMCSSStyleSheet, DOMStyleSheet>(exec, &DOMCSSStyleSheetTable, this, propertyName, slot);
586 }
587
588 JSValue *DOMCSSStyleSheetProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
589 {
590   if (!thisObj->inherits(&KJS::DOMCSSStyleSheet::info))
591     return throwError(exec, TypeError);
592   DOMExceptionTranslator exception(exec);
593   CSSStyleSheetImpl &styleSheet = *static_cast<CSSStyleSheetImpl *>(static_cast<DOMCSSStyleSheet *>(thisObj)->impl());
594   switch (id) {
595     case DOMCSSStyleSheet::InsertRule:
596       return jsNumber(styleSheet.insertRule(args[0]->toString(exec).domString(), args[1]->toInt32(exec), exception));
597     case DOMCSSStyleSheet::DeleteRule:
598       styleSheet.deleteRule(args[0]->toInt32(exec), exception);
599       return jsUndefined();
600     case DOMCSSStyleSheet::AddRule: {
601       int index = args.size() >= 3 ? args[2]->toInt32(exec) : -1;
602       styleSheet.addRule(args[0]->toString(exec).domString(), args[1]->toString(exec).domString(), index, exception);
603       // As per Microsoft documentation, always return -1.
604       return jsNumber(-1);
605     }
606     case DOMCSSStyleSheet::RemoveRule: {
607       int index = args.size() >= 1 ? args[0]->toInt32(exec) : 0;
608       styleSheet.removeRule(index, exception);
609       return jsUndefined();
610     }
611   }
612   return jsUndefined();
613 }
614
615 // -------------------------------------------------------------------------
616
617 const ClassInfo DOMCSSRuleList::info = { "CSSRuleList", 0, &DOMCSSRuleListTable, 0 };
618 /*
619 @begin DOMCSSRuleListTable 2
620   length                DOMCSSRuleList::Length          DontDelete|ReadOnly
621   item                  DOMCSSRuleList::Item            DontDelete|Function 1
622 @end
623 */
624 KJS_IMPLEMENT_PROTOFUNC(DOMCSSRuleListFunc) // not really a proto, but doesn't matter
625
626 DOMCSSRuleList::~DOMCSSRuleList()
627 {
628   ScriptInterpreter::forgetDOMObject(m_impl.get());
629 }
630
631 JSValue *DOMCSSRuleList::getValueProperty(ExecState *exec, int token) const
632 {
633   switch (token) {
634   case Length:
635     return jsNumber(m_impl->length());
636   default:
637     assert(0);
638     return jsUndefined();
639   }
640 }
641
642 JSValue *DOMCSSRuleList::indexGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
643 {
644   DOMCSSRuleList *thisObj = static_cast<DOMCSSRuleList *>(slot.slotBase());
645   return getDOMCSSRule(exec, thisObj->m_impl->item(slot.index()));
646 }
647
648 bool DOMCSSRuleList::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
649 {
650   const HashEntry* entry = Lookup::findEntry(&DOMCSSRuleListTable, propertyName);
651
652   if (entry) {
653     if (entry->attr & Function)
654       slot.setStaticEntry(this, entry, staticFunctionGetter<DOMCSSRuleListFunc>);
655     else
656       slot.setStaticEntry(this, entry, staticValueGetter<DOMCSSRuleList>);
657     return true;
658   }
659
660   CSSRuleListImpl &cssRuleList = *m_impl;
661
662   bool ok;
663   unsigned u = propertyName.toUInt32(&ok);
664   if (ok && u < cssRuleList.length()) {
665     slot.setCustomIndex(this, u, indexGetter);
666     return true;
667   }
668
669   return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
670 }
671
672 JSValue *DOMCSSRuleListFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
673 {
674   if (!thisObj->inherits(&KJS::DOMCSSRuleList::info))
675     return throwError(exec, TypeError);
676   CSSRuleListImpl &cssRuleList = *static_cast<DOMCSSRuleList *>(thisObj)->impl();
677   switch (id) {
678     case DOMCSSRuleList::Item:
679       return getDOMCSSRule(exec,cssRuleList.item(args[0]->toInt32(exec)));
680     default:
681       return jsUndefined();
682   }
683 }
684
685 JSValue *getDOMCSSRuleList(ExecState *exec, CSSRuleListImpl *rl)
686 {
687   return cacheDOMObject<CSSRuleListImpl, DOMCSSRuleList>(exec, rl);
688 }
689
690 // -------------------------------------------------------------------------
691
692 KJS_IMPLEMENT_PROTOFUNC(DOMCSSRuleFunc) // Not a proto, but doesn't matter
693
694 DOMCSSRule::~DOMCSSRule()
695 {
696   ScriptInterpreter::forgetDOMObject(m_impl.get());
697 }
698
699 const ClassInfo DOMCSSRule::info = { "CSSRule", 0, &DOMCSSRuleTable, 0 };
700 const ClassInfo DOMCSSRule::style_info = { "CSSStyleRule", &DOMCSSRule::info, &DOMCSSStyleRuleTable, 0 };
701 const ClassInfo DOMCSSRule::media_info = { "CSSMediaRule", &DOMCSSRule::info, &DOMCSSMediaRuleTable, 0 };
702 const ClassInfo DOMCSSRule::fontface_info = { "CSSFontFaceRule", &DOMCSSRule::info, &DOMCSSFontFaceRuleTable, 0 };
703 const ClassInfo DOMCSSRule::page_info = { "CSSPageRule", &DOMCSSRule::info, &DOMCSSPageRuleTable, 0 };
704 const ClassInfo DOMCSSRule::import_info = { "CSSImportRule", &DOMCSSRule::info, &DOMCSSImportRuleTable, 0 };
705 const ClassInfo DOMCSSRule::charset_info = { "CSSCharsetRule", &DOMCSSRule::info, &DOMCSSCharsetRuleTable, 0 };
706
707 const ClassInfo* DOMCSSRule::classInfo() const
708 {
709   CSSRuleImpl &cssRule = *m_impl;
710   switch (cssRule.type()) {
711   case WebCore::STYLE_RULE:
712     return &style_info;
713   case WebCore::MEDIA_RULE:
714     return &media_info;
715   case WebCore::FONT_FACE_RULE:
716     return &fontface_info;
717   case WebCore::PAGE_RULE:
718     return &page_info;
719   case WebCore::IMPORT_RULE:
720     return &import_info;
721   case WebCore::CHARSET_RULE:
722     return &charset_info;
723   case WebCore::UNKNOWN_RULE:
724   default:
725     return &info;
726   }
727 }
728 /*
729 @begin DOMCSSRuleTable 4
730   type                  DOMCSSRule::Type        DontDelete|ReadOnly
731   cssText               DOMCSSRule::CssText     DontDelete|ReadOnly
732   parentStyleSheet      DOMCSSRule::ParentStyleSheet    DontDelete|ReadOnly
733   parentRule            DOMCSSRule::ParentRule  DontDelete|ReadOnly
734 @end
735 @begin DOMCSSStyleRuleTable 2
736   selectorText          DOMCSSRule::Style_SelectorText  DontDelete
737   style                 DOMCSSRule::Style_Style         DontDelete|ReadOnly
738 @end
739 @begin DOMCSSMediaRuleTable 4
740   media                 DOMCSSRule::Media_Media         DontDelete|ReadOnly
741   cssRules              DOMCSSRule::Media_CssRules      DontDelete|ReadOnly
742   insertRule            DOMCSSRule::Media_InsertRule    DontDelete|Function 2
743   deleteRule            DOMCSSRule::Media_DeleteRule    DontDelete|Function 1
744 @end
745 @begin DOMCSSFontFaceRuleTable 1
746   style                 DOMCSSRule::FontFace_Style      DontDelete|ReadOnly
747 @end
748 @begin DOMCSSPageRuleTable 2
749   selectorText          DOMCSSRule::Page_SelectorText   DontDelete
750   style                 DOMCSSRule::Page_Style          DontDelete|ReadOnly
751 @end
752 @begin DOMCSSImportRuleTable 3
753   href                  DOMCSSRule::Import_Href         DontDelete|ReadOnly
754   media                 DOMCSSRule::Import_Media        DontDelete|ReadOnly
755   styleSheet            DOMCSSRule::Import_StyleSheet   DontDelete|ReadOnly
756 @end
757 @begin DOMCSSCharsetRuleTable 1
758   encoding              DOMCSSRule::Charset_Encoding    DontDelete
759 @end
760 */
761 bool DOMCSSRule::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
762 {
763   // first try the properties specific to this rule type
764   const HashEntry* entry = Lookup::findEntry(classInfo()->propHashTable, propertyName);
765   if (entry) {
766     slot.setStaticEntry(this, entry, staticValueGetter<DOMCSSRule>);
767     return true;
768   }
769   
770   // now the stuff that applies to all rules
771   return getStaticPropertySlot<DOMCSSRuleFunc, DOMCSSRule, DOMObject>(exec, &DOMCSSRuleTable, this, propertyName, slot);
772 }
773
774 JSValue *DOMCSSRule::getValueProperty(ExecState *exec, int token) const
775 {
776   CSSRuleImpl &cssRule = *m_impl;
777   switch (token) {
778   case Type:
779     return jsNumber(cssRule.type());
780   case CssText:
781     return jsStringOrNull(cssRule.cssText());
782   case ParentStyleSheet:
783     return getDOMStyleSheet(exec,cssRule.parentStyleSheet());
784   case ParentRule:
785     return getDOMCSSRule(exec,cssRule.parentRule());
786
787   // for STYLE_RULE:
788   case Style_SelectorText:
789     return jsStringOrNull(static_cast<CSSStyleRuleImpl *>(m_impl.get())->selectorText());
790   case Style_Style:
791     return getDOMCSSStyleDeclaration(exec, static_cast<CSSStyleRuleImpl *>(m_impl.get())->style());
792
793   // for MEDIA_RULE:
794   case Media_Media:
795     return getDOMMediaList(exec, static_cast<CSSMediaRuleImpl *>(m_impl.get())->media());
796   case Media_CssRules:
797     return getDOMCSSRuleList(exec, static_cast<CSSMediaRuleImpl *>(m_impl.get())->cssRules());
798
799   // for FONT_FACE_RULE:
800   case FontFace_Style:
801     return getDOMCSSStyleDeclaration(exec, static_cast<CSSFontFaceRuleImpl *>(m_impl.get())->style());
802
803   // for PAGE_RULE:
804   case Page_SelectorText:
805     return jsStringOrNull(static_cast<CSSPageRuleImpl *>(m_impl.get())->selectorText());
806   case Page_Style:
807     return getDOMCSSStyleDeclaration(exec, static_cast<CSSPageRuleImpl *>(m_impl.get())->style());
808
809   // for IMPORT_RULE:
810   case Import_Href:
811     return jsStringOrNull(static_cast<CSSImportRuleImpl *>(m_impl.get())->href());
812   case Import_Media:
813     return getDOMMediaList(exec, static_cast<CSSImportRuleImpl *>(m_impl.get())->media());
814   case Import_StyleSheet:
815     return getDOMStyleSheet(exec, static_cast<CSSImportRuleImpl *>(m_impl.get())->styleSheet());
816
817   // for CHARSET_RULE:
818   case Charset_Encoding:
819     return jsStringOrNull(static_cast<CSSCharsetRuleImpl *>(m_impl.get())->encoding());
820
821   default:
822     assert(0);
823   }
824   return jsUndefined();
825 }
826
827 void DOMCSSRule::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
828 {
829   const HashTable* table = classInfo()->propHashTable; // get the right hashtable
830   const HashEntry* entry = Lookup::findEntry(table, propertyName);
831   if (entry) {
832     if (entry->attr & Function) // function: put as override property
833     {
834       JSObject::put(exec, propertyName, value, attr);
835       return;
836     }
837     else if ((entry->attr & ReadOnly) == 0) // let lookupPut print the warning if not
838     {
839       putValueProperty(exec, entry->value, value, attr);
840       return;
841     }
842   }
843   lookupPut<DOMCSSRule, DOMObject>(exec, propertyName, value, attr, &DOMCSSRuleTable, this);
844 }
845
846 void DOMCSSRule::putValueProperty(ExecState *exec, int token, JSValue *value, int)
847 {
848   switch (token) {
849   // for STYLE_RULE:
850   case Style_SelectorText:
851     static_cast<CSSStyleRuleImpl *>(m_impl.get())->setSelectorText(value->toString(exec).domString());
852     return;
853
854   // for PAGE_RULE:
855   case Page_SelectorText:
856     static_cast<CSSPageRuleImpl *>(m_impl.get())->setSelectorText(value->toString(exec).domString());
857     return;
858
859   // for CHARSET_RULE:
860   case Charset_Encoding:
861     static_cast<CSSCharsetRuleImpl *>(m_impl.get())->setEncoding(value->toString(exec).domString());
862     return;
863   }
864 }
865
866 JSValue *DOMCSSRuleFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
867 {
868   if (!thisObj->inherits(&KJS::DOMCSSRule::info))
869     return throwError(exec, TypeError);
870   CSSRuleImpl &cssRule = *static_cast<DOMCSSRule *>(thisObj)->impl();
871
872   if (cssRule.type() == WebCore::MEDIA_RULE) {
873     CSSMediaRuleImpl &rule = static_cast<CSSMediaRuleImpl &>(cssRule);
874     if (id == DOMCSSRule::Media_InsertRule)
875       return jsNumber(rule.insertRule(args[0]->toString(exec).domString(), args[1]->toInt32(exec)));
876     else if (id == DOMCSSRule::Media_DeleteRule)
877       rule.deleteRule(args[0]->toInt32(exec));
878   }
879
880   return jsUndefined();
881 }
882
883 JSValue *getDOMCSSRule(ExecState *exec, CSSRuleImpl *r)
884 {
885   return cacheDOMObject<CSSRuleImpl, DOMCSSRule>(exec, r);
886 }
887
888 // -------------------------------------------------------------------------
889
890 const ClassInfo CSSRuleConstructor::info = { "CSSRuleConstructor", 0, &CSSRuleConstructorTable, 0 };
891 /*
892 @begin CSSRuleConstructorTable 7
893   UNKNOWN_RULE  CSSRuleConstructor::UNKNOWN_RULE        DontDelete|ReadOnly
894   STYLE_RULE    CSSRuleConstructor::STYLE_RULE          DontDelete|ReadOnly
895   CHARSET_RULE  CSSRuleConstructor::CHARSET_RULE        DontDelete|ReadOnly
896   IMPORT_RULE   CSSRuleConstructor::IMPORT_RULE         DontDelete|ReadOnly
897   MEDIA_RULE    CSSRuleConstructor::MEDIA_RULE          DontDelete|ReadOnly
898   FONT_FACE_RULE CSSRuleConstructor::FONT_FACE_RULE     DontDelete|ReadOnly
899   PAGE_RULE     CSSRuleConstructor::PAGE_RULE           DontDelete|ReadOnly
900 @end
901 */
902
903 bool CSSRuleConstructor::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
904 {
905   return getStaticValueSlot<CSSRuleConstructor, DOMObject>(exec, &CSSRuleConstructorTable, this, propertyName, slot);
906 }
907
908 JSValue *CSSRuleConstructor::getValueProperty(ExecState *, int token) const
909 {
910   switch (token) {
911   case UNKNOWN_RULE:
912     return jsNumber(WebCore::UNKNOWN_RULE);
913   case STYLE_RULE:
914     return jsNumber(WebCore::STYLE_RULE);
915   case CHARSET_RULE:
916     return jsNumber(WebCore::CHARSET_RULE);
917   case IMPORT_RULE:
918     return jsNumber(WebCore::IMPORT_RULE);
919   case MEDIA_RULE:
920     return jsNumber(WebCore::MEDIA_RULE);
921   case FONT_FACE_RULE:
922     return jsNumber(WebCore::FONT_FACE_RULE);
923   case PAGE_RULE:
924     return jsNumber(WebCore::PAGE_RULE);
925   }
926   return NULL;
927 }
928
929 JSValue *getCSSRuleConstructor(ExecState *exec)
930 {
931   return cacheGlobalObject<CSSRuleConstructor>( exec, "[[cssRule.constructor]]" );
932 }
933
934 // -------------------------------------------------------------------------
935
936 const ClassInfo DOMCSSValue::info = { "CSSValue", 0, &DOMCSSValueTable, 0 };
937
938 /*
939 @begin DOMCSSValueTable 2
940   cssText       DOMCSSValue::CssText            DontDelete|ReadOnly
941   cssValueType  DOMCSSValue::CssValueType       DontDelete|ReadOnly
942 @end
943 */
944 DOMCSSValue::~DOMCSSValue()
945 {
946   ScriptInterpreter::forgetDOMObject(m_impl.get());
947 }
948
949 JSValue *DOMCSSValue::getValueProperty(ExecState *exec, int token) const
950 {
951   CSSValueImpl &cssValue = *m_impl;
952   switch (token) {
953   case CssText:
954     return jsStringOrNull(cssValue.cssText());
955   case CssValueType:
956     return jsNumber(cssValue.cssValueType());
957   default:
958     assert(0);
959     return jsUndefined();
960   }
961 }
962
963 bool DOMCSSValue::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
964 {
965   return getStaticValueSlot<DOMCSSValue, DOMObject>(exec, &DOMCSSValueTable, this, propertyName, slot);
966 }
967
968 void DOMCSSValue::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
969 {
970   CSSValueImpl &cssValue = *m_impl;
971   if (propertyName == "cssText")
972     cssValue.setCssText(value->toString(exec).domString());
973   else
974     DOMObject::put(exec, propertyName, value, attr);
975 }
976
977 JSValue *getDOMCSSValue(ExecState *exec, CSSValueImpl *v)
978 {
979   DOMObject *ret;
980   if (!v)
981     return jsNull();
982   ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
983   if ((ret = interp->getDOMObject(v)))
984     return ret;
985   else {
986     if (v->isValueList())
987       ret = new DOMCSSValueList(exec, static_cast<CSSValueListImpl *>(v));
988     else if (v->isPrimitiveValue())
989       ret = new DOMCSSPrimitiveValue(exec, static_cast<CSSPrimitiveValueImpl *>(v));
990     else
991       ret = new DOMCSSValue(exec,v);
992     interp->putDOMObject(v, ret);
993     return ret;
994   }
995 }
996
997 // -------------------------------------------------------------------------
998
999 const ClassInfo CSSValueConstructor::info = { "CSSValueConstructor", 0, &CSSValueConstructorTable, 0 };
1000 /*
1001 @begin CSSValueConstructorTable 5
1002   CSS_INHERIT           CSSValueConstructor::CSS_INHERIT                DontDelete|ReadOnly
1003   CSS_PRIMITIVE_VALUE   CSSValueConstructor::CSS_PRIMITIVE_VALUE        DontDelete|ReadOnly
1004   CSS_VALUE_LIST        CSSValueConstructor::CSS_VALUE_LIST             DontDelete|ReadOnly
1005   CSS_CUSTOM            CSSValueConstructor::CSS_CUSTOM                 DontDelete|ReadOnly
1006 @end
1007 */
1008 bool CSSValueConstructor::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
1009 {
1010   return getStaticValueSlot<CSSValueConstructor, DOMObject>(exec, &CSSValueConstructorTable, this, propertyName, slot);
1011 }
1012
1013 JSValue *CSSValueConstructor::getValueProperty(ExecState *, int token) const
1014 {
1015   switch (token) {
1016   case CSS_INHERIT:
1017     return jsNumber(WebCore::CSSValueImpl::CSS_INHERIT);
1018   case CSS_PRIMITIVE_VALUE:
1019     return jsNumber(WebCore::CSSValueImpl::CSS_PRIMITIVE_VALUE);
1020   case CSS_VALUE_LIST:
1021     return jsNumber(WebCore::CSSValueImpl::CSS_VALUE_LIST);
1022   case CSS_CUSTOM:
1023     return jsNumber(WebCore::CSSValueImpl::CSS_CUSTOM);
1024   }
1025   return NULL;
1026 }
1027
1028 JSValue *getCSSValueConstructor(ExecState *exec)
1029 {
1030   return cacheGlobalObject<CSSValueConstructor>( exec, "[[cssValue.constructor]]" );
1031 }
1032
1033 // -------------------------------------------------------------------------
1034
1035 const ClassInfo DOMCSSPrimitiveValue::info = { "CSSPrimitiveValue", 0, &DOMCSSPrimitiveValueTable, 0 };
1036 /*
1037 @begin DOMCSSPrimitiveValueTable 1
1038   primitiveType         DOMCSSPrimitiveValue::PrimitiveType     DontDelete|ReadOnly
1039 @end
1040 @begin DOMCSSPrimitiveValueProtoTable 3
1041   setFloatValue         DOMCSSPrimitiveValue::SetFloatValue     DontDelete|Function 2
1042   getFloatValue         DOMCSSPrimitiveValue::GetFloatValue     DontDelete|Function 1
1043   setStringValue        DOMCSSPrimitiveValue::SetStringValue    DontDelete|Function 2
1044   getStringValue        DOMCSSPrimitiveValue::GetStringValue    DontDelete|Function 0
1045   getCounterValue       DOMCSSPrimitiveValue::GetCounterValue   DontDelete|Function 0
1046   getRectValue          DOMCSSPrimitiveValue::GetRectValue      DontDelete|Function 0
1047   getRGBColorValue      DOMCSSPrimitiveValue::GetRGBColorValue  DontDelete|Function 0
1048 @end
1049 */
1050 KJS_DEFINE_PROTOTYPE(DOMCSSPrimitiveValueProto)
1051 KJS_IMPLEMENT_PROTOFUNC(DOMCSSPrimitiveValueProtoFunc)
1052 KJS_IMPLEMENT_PROTOTYPE("DOMCSSPrimitiveValue",DOMCSSPrimitiveValueProto,DOMCSSPrimitiveValueProtoFunc)
1053
1054 DOMCSSPrimitiveValue::DOMCSSPrimitiveValue(ExecState *exec, CSSPrimitiveValueImpl *v)
1055   : DOMCSSValue(v) 
1056
1057   setPrototype(DOMCSSPrimitiveValueProto::self(exec));
1058 }
1059
1060 JSValue *DOMCSSPrimitiveValue::getValueProperty(ExecState *exec, int token)
1061 {
1062   assert(token == PrimitiveType);
1063   return jsNumber(static_cast<CSSPrimitiveValueImpl *>(impl())->primitiveType());
1064 }
1065
1066 bool DOMCSSPrimitiveValue::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
1067 {
1068   return getStaticValueSlot<DOMCSSPrimitiveValue, DOMCSSValue>(exec, &DOMCSSPrimitiveValueTable, this, propertyName, slot);
1069 }
1070
1071 JSValue *DOMCSSPrimitiveValueProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
1072 {
1073   if (!thisObj->inherits(&KJS::DOMCSSPrimitiveValue::info))
1074     return throwError(exec, TypeError);
1075   DOMExceptionTranslator exception(exec);
1076   CSSPrimitiveValueImpl &val = *static_cast<CSSPrimitiveValueImpl *>(static_cast<DOMCSSPrimitiveValue *>(thisObj)->impl());
1077   switch (id) {
1078     case DOMCSSPrimitiveValue::SetFloatValue:
1079       val.setFloatValue(args[0]->toInt32(exec), args[1]->toNumber(exec), exception);
1080       return jsUndefined();
1081     case DOMCSSPrimitiveValue::GetFloatValue:
1082       return jsNumber(val.getFloatValue(args[0]->toInt32(exec)));
1083     case DOMCSSPrimitiveValue::SetStringValue:
1084       val.setStringValue(args[0]->toInt32(exec), args[1]->toString(exec).domString(), exception);
1085       return jsUndefined();
1086     case DOMCSSPrimitiveValue::GetStringValue:
1087       return jsStringOrNull(val.getStringValue());
1088     case DOMCSSPrimitiveValue::GetCounterValue:
1089       return getDOMCounter(exec,val.getCounterValue());
1090     case DOMCSSPrimitiveValue::GetRectValue:
1091       return getDOMRect(exec,val.getRectValue());
1092     case DOMCSSPrimitiveValue::GetRGBColorValue:
1093       return getDOMRGBColor(exec,val.getRGBColorValue());
1094     default:
1095       return jsUndefined();
1096   }
1097 }
1098
1099 // -------------------------------------------------------------------------
1100
1101 const ClassInfo CSSPrimitiveValueConstructor::info = { "CSSPrimitiveValueConstructor", 0, &CSSPrimitiveValueConstructorTable, 0 };
1102
1103 /*
1104 @begin CSSPrimitiveValueConstructorTable 27
1105   CSS_UNKNOWN           WebCore::CSSPrimitiveValue::CSS_UNKNOWN DontDelete|ReadOnly
1106   CSS_NUMBER            WebCore::CSSPrimitiveValue::CSS_NUMBER  DontDelete|ReadOnly
1107   CSS_PERCENTAGE        WebCore::CSSPrimitiveValue::CSS_PERCENTAGE      DontDelete|ReadOnly
1108   CSS_EMS               WebCore::CSSPrimitiveValue::CSS_EMS             DontDelete|ReadOnly
1109   CSS_EXS               WebCore::CSSPrimitiveValue::CSS_EXS             DontDelete|ReadOnly
1110   CSS_PX                WebCore::CSSPrimitiveValue::CSS_PX              DontDelete|ReadOnly
1111   CSS_CM                WebCore::CSSPrimitiveValue::CSS_CM              DontDelete|ReadOnly
1112   CSS_MM                WebCore::CSSPrimitiveValue::CSS_MM              DontDelete|ReadOnly
1113   CSS_IN                WebCore::CSSPrimitiveValue::CSS_IN              DontDelete|ReadOnly
1114   CSS_PT                WebCore::CSSPrimitiveValue::CSS_PT              DontDelete|ReadOnly
1115   CSS_PC                WebCore::CSSPrimitiveValue::CSS_PC              DontDelete|ReadOnly
1116   CSS_DEG               WebCore::CSSPrimitiveValue::CSS_DEG             DontDelete|ReadOnly
1117   CSS_RAD               WebCore::CSSPrimitiveValue::CSS_RAD             DontDelete|ReadOnly
1118   CSS_GRAD              WebCore::CSSPrimitiveValue::CSS_GRAD    DontDelete|ReadOnly
1119   CSS_MS                WebCore::CSSPrimitiveValue::CSS_MS              DontDelete|ReadOnly
1120   CSS_S                 WebCore::CSSPrimitiveValue::CSS_S               DontDelete|ReadOnly
1121   CSS_HZ                WebCore::CSSPrimitiveValue::CSS_HZ              DontDelete|ReadOnly
1122   CSS_KHZ               WebCore::CSSPrimitiveValue::CSS_KHZ             DontDelete|ReadOnly
1123   CSS_DIMENSION         WebCore::CSSPrimitiveValue::CSS_DIMENSION       DontDelete|ReadOnly
1124   CSS_STRING            WebCore::CSSPrimitiveValue::CSS_STRING  DontDelete|ReadOnly
1125   CSS_URI               WebCore::CSSPrimitiveValue::CSS_URI             DontDelete|ReadOnly
1126   CSS_IDENT             WebCore::CSSPrimitiveValue::CSS_IDENT   DontDelete|ReadOnly
1127   CSS_ATTR              WebCore::CSSPrimitiveValue::CSS_ATTR    DontDelete|ReadOnly
1128   CSS_COUNTER           WebCore::CSSPrimitiveValue::CSS_COUNTER DontDelete|ReadOnly
1129   CSS_RECT              WebCore::CSSPrimitiveValue::CSS_RECT    DontDelete|ReadOnly
1130   CSS_RGBCOLOR          WebCore::CSSPrimitiveValue::CSS_RGBCOLOR        DontDelete|ReadOnly
1131 @end
1132 */
1133
1134 bool CSSPrimitiveValueConstructor::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
1135 {
1136   return getStaticValueSlot<CSSPrimitiveValueConstructor, CSSValueConstructor>(exec, &CSSPrimitiveValueConstructorTable, this, propertyName, slot);
1137 }
1138
1139 JSValue *CSSPrimitiveValueConstructor::getValueProperty(ExecState *, int token) const
1140 {
1141   // We use the token as the value to return directly
1142   return jsNumber(token);
1143 }
1144
1145 JSValue *getCSSPrimitiveValueConstructor(ExecState *exec)
1146 {
1147   return cacheGlobalObject<CSSPrimitiveValueConstructor>( exec, "[[cssPrimitiveValue.constructor]]" );
1148 }
1149
1150 // -------------------------------------------------------------------------
1151
1152 const ClassInfo DOMCSSValueList::info = { "CSSValueList", 0, &DOMCSSValueListTable, 0 };
1153
1154 /*
1155 @begin DOMCSSValueListTable 3
1156   length                DOMCSSValueList::Length         DontDelete|ReadOnly
1157   item                  DOMCSSValueList::Item           DontDelete|Function 1
1158 @end
1159 */
1160 KJS_IMPLEMENT_PROTOFUNC(DOMCSSValueListFunc) // not really a proto, but doesn't matter
1161
1162 DOMCSSValueList::DOMCSSValueList(ExecState *exec, CSSValueListImpl *v)
1163   : DOMCSSValue(exec, v) 
1164
1165 }
1166
1167 JSValue *DOMCSSValueList::getValueProperty(ExecState *exec, int token) const
1168 {
1169   assert(token == Length);
1170   return jsNumber(static_cast<CSSValueListImpl *>(impl())->length());
1171 }
1172
1173 JSValue *DOMCSSValueList::indexGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
1174 {
1175   DOMCSSValueList *thisObj = static_cast<DOMCSSValueList *>(slot.slotBase());
1176   return getDOMCSSValue(exec, static_cast<CSSValueListImpl *>(thisObj->impl())->item(slot.index()));
1177 }
1178
1179 bool DOMCSSValueList::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
1180 {
1181   CSSValueListImpl &valueList = *static_cast<CSSValueListImpl *>(impl());
1182   const HashEntry* entry = Lookup::findEntry(&DOMCSSValueListTable, propertyName);
1183   if (entry) {
1184     if (entry->attr & Function)
1185       slot.setStaticEntry(this, entry, staticFunctionGetter<DOMCSSValueListFunc>);
1186     else
1187       slot.setStaticEntry(this, entry, staticValueGetter<DOMCSSValueList>);
1188   }
1189
1190   bool ok;
1191   unsigned u = propertyName.toUInt32(&ok);
1192   if (ok && u < valueList.length()) {
1193     slot.setCustomIndex(this, u, indexGetter);
1194     return true;
1195   }
1196
1197   return DOMCSSValue::getOwnPropertySlot(exec, propertyName, slot);
1198 }
1199
1200 JSValue *DOMCSSValueListFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
1201 {
1202   if (!thisObj->inherits(&KJS::DOMCSSValue::info))
1203     return throwError(exec, TypeError);
1204   CSSValueListImpl &valueList = *static_cast<CSSValueListImpl *>(static_cast<DOMCSSValueList *>(thisObj)->impl());
1205   switch (id) {
1206     case DOMCSSValueList::Item:
1207       return getDOMCSSValue(exec,valueList.item(args[0]->toInt32(exec)));
1208     default:
1209       return jsUndefined();
1210   }
1211 }
1212
1213 // -------------------------------------------------------------------------
1214
1215 const ClassInfo DOMRGBColor::info = { "RGBColor", 0, &DOMRGBColorTable, 0 };
1216
1217 /*
1218 @begin DOMRGBColorTable 3
1219   red   DOMRGBColor::Red        DontDelete|ReadOnly
1220   green DOMRGBColor::Green      DontDelete|ReadOnly
1221   blue  DOMRGBColor::Blue       DontDelete|ReadOnly
1222 @end
1223 */
1224 DOMRGBColor::~DOMRGBColor()
1225 {
1226   //rgbColors.remove(rgbColor.handle());
1227 }
1228
1229 bool DOMRGBColor::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
1230 {
1231   return getStaticValueSlot<DOMRGBColor, DOMObject>(exec, &DOMRGBColorTable, this, propertyName, slot);
1232 }
1233
1234 JSValue *DOMRGBColor::getValueProperty(ExecState *exec, int token) const
1235 {
1236   int color = m_color;
1237   switch (token) {
1238   case Red:
1239     color >>= 8;
1240     // fall through
1241   case Green:
1242     color >>= 8;
1243     // fall through
1244   case Blue:
1245     return new DOMCSSPrimitiveValue(exec, new CSSPrimitiveValueImpl(color & 0xFF, CSSPrimitiveValue::CSS_NUMBER));
1246   default:
1247     return NULL;
1248   }
1249 }
1250
1251 JSValue *getDOMRGBColor(ExecState *, unsigned c)
1252 {
1253   // ### implement equals for RGBColor since they're not refcounted objects
1254   return new DOMRGBColor(c);
1255 }
1256
1257 // -------------------------------------------------------------------------
1258
1259 const ClassInfo DOMRect::info = { "Rect", 0, &DOMRectTable, 0 };
1260 /*
1261 @begin DOMRectTable 4
1262   top   DOMRect::Top    DontDelete|ReadOnly
1263   right DOMRect::Right  DontDelete|ReadOnly
1264   bottom DOMRect::Bottom DontDelete|ReadOnly
1265   left  DOMRect::Left   DontDelete|ReadOnly
1266 @end
1267 */
1268 DOMRect::~DOMRect()
1269 {
1270   ScriptInterpreter::forgetDOMObject(m_rect.get());
1271 }
1272
1273 bool DOMRect::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
1274 {
1275   return getStaticValueSlot<DOMRect, DOMObject>(exec,  &DOMRectTable, this, propertyName, slot);
1276 }
1277
1278 JSValue *DOMRect::getValueProperty(ExecState *exec, int token) const
1279 {
1280   RectImpl &rect = *m_rect;
1281   switch (token) {
1282   case Top:
1283     return getDOMCSSValue(exec, rect.top());
1284   case Right:
1285     return getDOMCSSValue(exec, rect.right());
1286   case Bottom:
1287     return getDOMCSSValue(exec, rect.bottom());
1288   case Left:
1289     return getDOMCSSValue(exec, rect.left());
1290   default:
1291     return NULL;
1292   }
1293 }
1294
1295 JSValue *getDOMRect(ExecState *exec, RectImpl *r)
1296 {
1297   return cacheDOMObject<RectImpl, DOMRect>(exec, r);
1298 }
1299
1300 // -------------------------------------------------------------------------
1301
1302 const ClassInfo DOMCounter::info = { "Counter", 0, &DOMCounterTable, 0 };
1303 /*
1304 @begin DOMCounterTable 3
1305   identifier    DOMCounter::identifier  DontDelete|ReadOnly
1306   listStyle     DOMCounter::listStyle   DontDelete|ReadOnly
1307   separator     DOMCounter::separator   DontDelete|ReadOnly
1308 @end
1309 */
1310
1311 DOMCounter::~DOMCounter()
1312 {
1313   ScriptInterpreter::forgetDOMObject(m_counter.get());
1314 }
1315
1316 bool DOMCounter::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
1317 {
1318   return getStaticValueSlot<DOMCounter, DOMObject>(exec, &DOMCounterTable, this, propertyName, slot);
1319 }
1320
1321 JSValue *DOMCounter::getValueProperty(ExecState *, int token) const
1322 {
1323   CounterImpl &counter = *m_counter;
1324   switch (token) {
1325   case identifier:
1326     return jsStringOrNull(counter.identifier());
1327   case listStyle:
1328     return jsStringOrNull(counter.listStyle());
1329   case separator:
1330     return jsStringOrNull(counter.separator());
1331   default:
1332     return NULL;
1333   }
1334 }
1335
1336 JSValue *getDOMCounter(ExecState *exec, CounterImpl *c)
1337 {
1338   return cacheDOMObject<CounterImpl, DOMCounter>(exec, c);
1339 }
1340
1341 }