Fixed 3922875. Fall back to DOM object is EMBED element
[WebKit-https.git] / WebCore / khtml / ecma / kjs_html.cpp
1 // -*- c-basic-offset: 2 -*-
2 /*
3  *  This file is part of the KDE libraries
4  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
5  *  Copyright (C) 2004 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 Lesser 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  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "misc/loader.h"
23 #include "dom/html_block.h"
24 #include "dom/html_head.h"
25 #include "dom/html_image.h"
26 #include "dom/html_inline.h"
27 #include "dom/html_list.h"
28 #include "dom/html_table.h"
29 #include "dom/html_object.h"
30 #include "dom/dom_exception.h"
31 #include "xml/dom2_eventsimpl.h"
32
33 // ### HACK
34 #include "html/html_baseimpl.h"
35 #include "html/html_canvasimpl.h"
36 #include "html/html_documentimpl.h"
37 #include "html/html_imageimpl.h"
38 #include "html/html_objectimpl.h"
39
40 #include "khtml_part.h"
41 #include "khtmlview.h"
42
43 #include "ecma/kjs_css.h"
44 #include "ecma/kjs_html.h"
45 #include "ecma/kjs_window.h"
46 #include "ecma/kjs_html.lut.h"
47 #include "kjs_events.h"
48
49 #include "misc/htmltags.h"
50
51 #include "rendering/render_canvasimage.h"
52 #include "rendering/render_object.h"
53 #include "rendering/render_layer.h"
54
55 #include <kdebug.h>
56
57 #include "cssparser.h"
58 #include "css_stylesheetimpl.h"
59
60 #include "qcolor.h"
61 #include "qpixmap.h"
62 #include "qpainter.h"
63
64 #include <ApplicationServices/ApplicationServices.h>
65
66 using namespace KJS;
67
68 using DOM::DocumentImpl;
69 using DOM::DOMString;
70 using DOM::HTMLFrameElementImpl;
71 using DOM::HTMLIFrameElementImpl;
72
73 IMPLEMENT_PROTOFUNC(HTMLDocFunction)
74
75 Value KJS::HTMLDocFunction::tryCall(ExecState *exec, Object &thisObj, const List &args)
76 {
77   if (!thisObj.inherits(&HTMLDocument::info)) {
78     Object err = Error::create(exec,TypeError);
79     exec->setException(err);
80     return err;
81   }
82   DOM::HTMLDocument doc = static_cast<KJS::HTMLDocument *>(thisObj.imp())->toDocument();
83
84   switch (id) {
85   case HTMLDocument::Clear: // even IE doesn't support that one...
86     //doc.clear(); // TODO
87     return Undefined();
88   case HTMLDocument::Open:
89     // For compatibility with other browsers, pass open calls with more than 2 parameters to the window.
90     if (args.size() > 2) {
91       KHTMLPart *part = static_cast<DOM::DocumentImpl *>(doc.handle())->part();
92       if (part) {
93         Window *window = Window::retrieveWindow(part);
94         if (window) {
95           Object functionObject = Object::dynamicCast(window->get(exec, "open"));
96           if (functionObject.isNull() || !functionObject.implementsCall()) {
97             Object exception = Error::create(exec, TypeError);
98             exec->setException(exception);
99             return exception;
100           }
101           Object windowObject(window);
102           return functionObject.call(exec, windowObject, args);
103         }
104       }
105       return Undefined();
106     }
107     // In the case of two parameters or fewer, do a normal document open.
108     doc.open();
109     return Undefined();
110   case HTMLDocument::Close:
111     // see khtmltests/ecma/tokenizer-script-recursion.html
112     doc.close();
113     return Undefined();
114   case HTMLDocument::Write:
115   case HTMLDocument::WriteLn: {
116     // DOM only specifies single string argument, but NS & IE allow multiple
117     // or no arguments
118     UString str = "";
119     for (int i = 0; i < args.size(); i++)
120       str += args[i].toString(exec);
121     if (id == HTMLDocument::WriteLn)
122       str += "\n";
123     //kdDebug() << "document.write: " << str.ascii() << endl;
124     doc.write(str.string());
125     return Undefined();
126   }
127   case HTMLDocument::GetElementsByName:
128     return getDOMNodeList(exec,doc.getElementsByName(args[0].toString(exec).string()));
129   case HTMLDocument::CaptureEvents:
130   case HTMLDocument::ReleaseEvents:
131     // Do nothing for now. These are NS-specific legacy calls.
132     break;
133   }
134
135   return Undefined();
136 }
137
138 const ClassInfo KJS::HTMLDocument::info =
139   { "HTMLDocument", &DOMDocument::info, &HTMLDocumentTable, 0 };
140 /* Source for HTMLDocumentTable. Use "make hashtables" to regenerate.
141 @begin HTMLDocumentTable 30
142   title                 HTMLDocument::Title             DontDelete
143   referrer              HTMLDocument::Referrer          DontDelete|ReadOnly
144   domain                HTMLDocument::Domain            DontDelete
145   URL                   HTMLDocument::URL               DontDelete|ReadOnly
146   body                  HTMLDocument::Body              DontDelete
147   location              HTMLDocument::Location          DontDelete
148   cookie                HTMLDocument::Cookie            DontDelete
149   images                HTMLDocument::Images            DontDelete|ReadOnly
150   embeds                HTMLDocument::Embeds            DontDelete|ReadOnly
151   applets               HTMLDocument::Applets           DontDelete|ReadOnly
152   links                 HTMLDocument::Links             DontDelete|ReadOnly
153   forms                 HTMLDocument::Forms             DontDelete|ReadOnly
154   anchors               HTMLDocument::Anchors           DontDelete|ReadOnly
155   scripts               HTMLDocument::Scripts           DontDelete|ReadOnly
156 # We want no document.all at all, not just a function that returns undefined.
157 # That means we lose the "document.all when spoofing as IE" feature, but we don't spoof in Safari.
158 # And this makes sites that set document.all explicitly work when they otherwise wouldn't, 
159 # e.g. https://corporateexchange.airborne.com
160 # (Not in APPLE_CHANGES since we can't do #if in KJS identifier lists.)
161 #  all                  HTMLDocument::All               DontDelete|ReadOnly
162   clear                 HTMLDocument::Clear             DontDelete|Function 0
163   open                  HTMLDocument::Open              DontDelete|Function 0
164   close                 HTMLDocument::Close             DontDelete|Function 0
165   write                 HTMLDocument::Write             DontDelete|Function 1
166   writeln               HTMLDocument::WriteLn           DontDelete|Function 1
167   getElementsByName     HTMLDocument::GetElementsByName DontDelete|Function 1
168   captureEvents         HTMLDocument::CaptureEvents     DontDelete|Function 0
169   releaseEvents         HTMLDocument::ReleaseEvents     DontDelete|Function 0
170   bgColor               HTMLDocument::BgColor           DontDelete
171   fgColor               HTMLDocument::FgColor           DontDelete
172   alinkColor            HTMLDocument::AlinkColor        DontDelete
173   linkColor             HTMLDocument::LinkColor         DontDelete
174   vlinkColor            HTMLDocument::VlinkColor        DontDelete
175   lastModified          HTMLDocument::LastModified      DontDelete|ReadOnly
176   height                HTMLDocument::Height            DontDelete|ReadOnly
177   width                 HTMLDocument::Width             DontDelete|ReadOnly
178   dir                   HTMLDocument::Dir               DontDelete
179   designMode            HTMLDocument::DesignMode        DontDelete
180 #potentially obsolete array properties
181 # layers
182 # plugins
183 # tags
184 #potentially obsolete properties
185 # embeds
186 # ids
187 @end
188 */
189 bool KJS::HTMLDocument::hasProperty(ExecState *exec, const Identifier &p) const
190 {
191 #ifdef KJS_VERBOSE
192   //kdDebug(6070) << "KJS::HTMLDocument::hasProperty " << p.qstring() << endl;
193 #endif
194   DOM::HTMLDocumentImpl *docImpl = static_cast<DOM::HTMLDocumentImpl *>(node.handle());
195
196   return (DOMDocument::hasProperty(exec, p) ||  
197           docImpl->haveNamedImageOrForm(p.qstring()));
198 }
199
200 Value KJS::HTMLDocument::tryGet(ExecState *exec, const Identifier &propertyName) const
201 {
202 #ifdef KJS_VERBOSE
203   kdDebug(6070) << "KJS::HTMLDocument::tryGet " << propertyName.qstring() << endl;
204 #endif
205   DOM::HTMLDocument doc = static_cast<DOM::HTMLDocument>(node);
206   DOM::HTMLBodyElement body = doc.body();
207
208   KHTMLView *view = static_cast<DOM::DocumentImpl*>(doc.handle())->view();
209
210   const HashEntry* entry = Lookup::findEntry(&HTMLDocumentTable, propertyName);
211   if (entry) {
212     switch (entry->value) {
213     case Title:
214       return String(doc.title());
215     case Referrer:
216       return String(doc.referrer());
217     case Domain:
218       return String(doc.domain());
219     case URL:
220       return String(doc.URL());
221     case Body:
222       return getDOMNode(exec,doc.body());
223     case Location:
224       if ( view && view->part() )
225       {
226         Window* win = Window::retrieveWindow(view->part());
227         if (win)
228           return Value(win->location());
229         else
230           return Undefined();
231       }
232       else
233         return Undefined();
234     case Cookie:
235       return String(doc.cookie());
236     case Images:
237       return getHTMLCollection(exec,doc.images());
238     case Embeds:
239       return getHTMLCollection(exec,doc.embeds());
240     case Applets:
241       return getHTMLCollection(exec,doc.applets());
242     case Links:
243       return getHTMLCollection(exec,doc.links());
244     case Forms:
245       return getHTMLCollection(exec,doc.forms());
246     case Anchors:
247       return getHTMLCollection(exec,doc.anchors());
248     case Scripts: // TODO (IE-specific)
249     {
250       // To be implemented. Meanwhile, return an object with a length property set to 0
251       kdWarning() << "KJS::HTMLDocument document.scripts called - not implemented" << endl;
252       Object obj( new ObjectImp() );
253       obj.put( exec, lengthPropertyName, Number(0) );
254       return obj;
255     }
256     case All:
257       // Disable document.all when we try to be Netscape-compatible
258       if ( exec->dynamicInterpreter()->compatMode() == Interpreter::NetscapeCompat )
259         return Undefined();
260       return getHTMLCollection(exec,doc.all());
261     case Clear:
262     case Open:
263     case Close:
264     case Write:
265     case WriteLn:
266     case GetElementsByName:
267     case CaptureEvents:
268     case ReleaseEvents:
269       return lookupOrCreateFunction<HTMLDocFunction>( exec, propertyName, this, entry->value, entry->params, entry->attr );
270     }
271   }
272   // Look for overrides
273   ValueImp * val = ObjectImp::getDirect(propertyName);
274   if (val)
275     return Value(val);
276
277   if (entry) {
278     switch (entry->value) {
279     case BgColor:
280       return String(body.bgColor());
281     case FgColor:
282       return String(body.text());
283     case AlinkColor:
284       return String(body.aLink());
285     case LinkColor:
286       return String(body.link());
287     case VlinkColor:
288       return String(body.vLink());
289     case LastModified:
290       return String(doc.lastModified());
291     case Height:
292       return Number(view ? view->contentsHeight() : 0);
293     case Width:
294       return Number(view ? view->contentsWidth() : 0);
295     case Dir:
296       return String(body.dir());
297     case DesignMode:
298     {
299       DocumentImpl *docimpl = static_cast<DocumentImpl *>(doc.handle());
300       if (!docimpl)
301         return Undefined();
302       return String(docimpl->inDesignMode() ? "on" : "off");  
303     }
304     }
305   }
306
307   if (DOMDocument::hasProperty(exec, propertyName))
308     return DOMDocument::tryGet(exec, propertyName);
309
310   //kdDebug(6070) << "KJS::HTMLDocument::tryGet " << propertyName.qstring() << " not found, returning element" << endl;
311   // image and form elements with the name p will be looked up last
312
313 #if APPLE_CHANGES
314     // Look for named applets.
315     // FIXME:  Factor code that creates RuntimeObjectImp for applet.  It's also
316     // located in applets[0]. 
317     DOM::HTMLCollection applets = doc.applets();
318     DOM::HTMLElement anApplet = applets.namedItem (propertyName.string());
319     if (!anApplet.isNull()) {
320         Value v = getRuntimeObject(exec,anApplet);
321         if (!v.isNull())
322             return v;
323     }
324
325     DOM::HTMLCollection embeds = doc.embeds();
326     DOM::HTMLElement anEmbed = embeds.namedItem (propertyName.string());
327     if (!anEmbed.isNull()) {
328         Value v = getRuntimeObject(exec,anEmbed);
329         if (!v.isNull())
330             return v;
331     }
332 #endif
333
334   DOM::HTMLDocumentImpl *docImpl = static_cast<DOM::HTMLDocumentImpl*>(node.handle());
335   if (!docImpl->haveNamedImageOrForm(propertyName.qstring())) {
336     return Undefined();
337   }
338
339   DOM::HTMLCollection nameableItems = doc.nameableItems();
340   KJS::HTMLCollection kjsCollection(exec,nameableItems);
341   return kjsCollection.getNamedItems(exec, propertyName); // Get all the items with the same name
342
343   return Undefined();
344 }
345
346 void KJS::HTMLDocument::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
347 {
348 #ifdef KJS_VERBOSE
349   kdDebug(6070) << "KJS::HTMLDocument::tryPut " << propertyName.qstring() << endl;
350 #endif
351   DOMObjectLookupPut<HTMLDocument, DOMDocument>( exec, propertyName, value, attr, &HTMLDocumentTable, this );
352 }
353
354 void KJS::HTMLDocument::putValue(ExecState *exec, int token, const Value& value, int /*attr*/)
355 {
356   DOM::HTMLDocument doc = static_cast<DOM::HTMLDocument>(node);
357   DOM::HTMLBodyElement body = doc.body();
358
359   switch (token) {
360   case Title:
361     doc.setTitle(value.toString(exec).string());
362     break;
363   case Body: {
364     DOMNode *node = new DOMNode(exec, KJS::toNode(value));
365     // This is required to avoid leaking the node.
366     Value nodeValue(node);
367     doc.setBody(node->toNode());
368     break;
369   }
370   case Domain: { // not part of the DOM
371     DOM::HTMLDocumentImpl* docimpl = static_cast<DOM::HTMLDocumentImpl*>(doc.handle());
372     if (docimpl)
373       docimpl->setDomain(value.toString(exec).string());
374     break;
375   }
376   case Cookie:
377     doc.setCookie(value.toString(exec).string());
378     break;
379   case Location: {
380     KHTMLPart *part = static_cast<DOM::DocumentImpl *>( doc.handle() )->part();
381     if (part)
382     {
383       QString str = value.toString(exec).qstring();
384
385       // When assigning location, IE and Mozilla both resolve the URL
386       // relative to the frame where the JavaScript is executing not
387       // the target frame.
388       KHTMLPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->dynamicInterpreter() )->part();
389       if (activePart)
390         str = activePart->htmlDocument().completeURL(str).string();
391
392 #if APPLE_CHANGES
393       // We want a new history item if this JS was called via a user gesture
394       bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
395       part->scheduleLocationChange(str, !userGesture);
396 #else
397       part->scheduleLocationChange(str, false/*don't lock history*/);
398 #endif
399     }
400     break;
401   }
402   case BgColor:
403     body.setBgColor(value.toString(exec).string());
404     break;
405   case FgColor:
406     body.setText(value.toString(exec).string());
407     break;
408   case AlinkColor:
409     // this check is a bit silly, but some benchmarks like to set the
410     // document's link colors over and over to the same value and we
411     // don't want to incur a style update each time.
412     {
413       DOM::DOMString newColor = value.toString(exec).string();
414       if (body.aLink() != newColor) {
415         body.setALink(newColor);
416       }
417     }
418     break;
419   case LinkColor:
420     // this check is a bit silly, but some benchmarks like to set the
421     // document's link colors over and over to the same value and we
422     // don't want to incur a style update each time.
423     {
424       DOM::DOMString newColor = value.toString(exec).string();
425       if (body.link() != newColor) {
426         body.setLink(newColor);
427       }
428     }
429     break;
430   case VlinkColor:
431     // this check is a bit silly, but some benchmarks like to set the
432     // document's link colors over and over to the same value and we
433     // don't want to incur a style update each time.
434     {
435       DOM::DOMString newColor = value.toString(exec).string();
436       if (body.vLink() != newColor) {
437         body.setVLink(newColor);
438       }
439     }
440     break;
441   case Dir:
442     body.setDir(value.toString(exec).string());
443     break;
444   case DesignMode:
445     {
446       DocumentImpl *docimpl = static_cast<DocumentImpl *>(doc.handle());
447       if (!docimpl)
448         break;
449       DOMString modeString = value.toString(exec).string();
450       DocumentImpl::InheritedBool mode;
451       if (!strcasecmp(modeString, "on"))
452         mode = DocumentImpl::on;
453       else if (!strcasecmp(modeString, "off"))
454         mode = DocumentImpl::off;
455       else
456         mode = DocumentImpl::inherit;
457       docimpl->setDesignMode(mode);
458      }
459     break;
460   default:
461     kdWarning() << "HTMLDocument::putValue unhandled token " << token << endl;
462   }
463 }
464
465 // -------------------------------------------------------------------------
466
467 const ClassInfo KJS::HTMLElement::info = { "HTMLElement", &DOMElement::info, &HTMLElementTable, 0 };
468 const ClassInfo KJS::HTMLElement::html_info = { "HTMLHtmlElement", &KJS::HTMLElement::info, &HTMLHtmlElementTable, 0 };
469 const ClassInfo KJS::HTMLElement::head_info = { "HTMLHeadElement", &KJS::HTMLElement::info, &HTMLHeadElementTable, 0 };
470 const ClassInfo KJS::HTMLElement::link_info = { "HTMLLinkElement", &KJS::HTMLElement::info, &HTMLLinkElementTable, 0 };
471 const ClassInfo KJS::HTMLElement::title_info = { "HTMLTitleElement", &KJS::HTMLElement::info, &HTMLTitleElementTable, 0 };
472 const ClassInfo KJS::HTMLElement::meta_info = { "HTMLMetaElement", &KJS::HTMLElement::info, &HTMLMetaElementTable, 0 };
473 const ClassInfo KJS::HTMLElement::base_info = { "HTMLBaseElement", &KJS::HTMLElement::info, &HTMLBaseElementTable, 0 };
474 const ClassInfo KJS::HTMLElement::isIndex_info = { "HTMLIsIndexElement", &KJS::HTMLElement::info, &HTMLIsIndexElementTable, 0 };
475 const ClassInfo KJS::HTMLElement::style_info = { "HTMLStyleElement", &KJS::HTMLElement::info, &HTMLStyleElementTable, 0 };
476 const ClassInfo KJS::HTMLElement::body_info = { "HTMLBodyElement", &KJS::HTMLElement::info, &HTMLBodyElementTable, 0 };
477 const ClassInfo KJS::HTMLElement::form_info = { "HTMLFormElement", &KJS::HTMLElement::info, &HTMLFormElementTable, 0 };
478 const ClassInfo KJS::HTMLElement::select_info = { "HTMLSelectElement", &KJS::HTMLElement::info, &HTMLSelectElementTable, 0 };
479 const ClassInfo KJS::HTMLElement::optGroup_info = { "HTMLOptGroupElement", &KJS::HTMLElement::info, &HTMLOptGroupElementTable, 0 };
480 const ClassInfo KJS::HTMLElement::option_info = { "HTMLOptionElement", &KJS::HTMLElement::info, &HTMLOptionElementTable, 0 };
481 const ClassInfo KJS::HTMLElement::input_info = { "HTMLInputElement", &KJS::HTMLElement::info, &HTMLInputElementTable, 0 };
482 const ClassInfo KJS::HTMLElement::textArea_info = { "HTMLTextAreaElement", &KJS::HTMLElement::info, &HTMLTextAreaElementTable, 0 };
483 const ClassInfo KJS::HTMLElement::button_info = { "HTMLButtonElement", &KJS::HTMLElement::info, &HTMLButtonElementTable, 0 };
484 const ClassInfo KJS::HTMLElement::label_info = { "HTMLLabelElement", &KJS::HTMLElement::info, &HTMLLabelElementTable, 0 };
485 const ClassInfo KJS::HTMLElement::fieldSet_info = { "HTMLFieldSetElement", &KJS::HTMLElement::info, &HTMLFieldSetElementTable, 0 };
486 const ClassInfo KJS::HTMLElement::legend_info = { "HTMLLegendElement", &KJS::HTMLElement::info, &HTMLLegendElementTable, 0 };
487 const ClassInfo KJS::HTMLElement::ul_info = { "HTMLUListElement", &KJS::HTMLElement::info, &HTMLUListElementTable, 0 };
488 const ClassInfo KJS::HTMLElement::ol_info = { "HTMLOListElement", &KJS::HTMLElement::info, &HTMLOListElementTable, 0 };
489 const ClassInfo KJS::HTMLElement::dl_info = { "HTMLDListElement", &KJS::HTMLElement::info, &HTMLDListElementTable, 0 };
490 const ClassInfo KJS::HTMLElement::dir_info = { "HTMLDirectoryElement", &KJS::HTMLElement::info, &HTMLDirectoryElementTable, 0 };
491 const ClassInfo KJS::HTMLElement::menu_info = { "HTMLMenuElement", &KJS::HTMLElement::info, &HTMLMenuElementTable, 0 };
492 const ClassInfo KJS::HTMLElement::li_info = { "HTMLLIElement", &KJS::HTMLElement::info, &HTMLLIElementTable, 0 };
493 const ClassInfo KJS::HTMLElement::div_info = { "HTMLDivElement", &KJS::HTMLElement::info, &HTMLDivElementTable, 0 };
494 const ClassInfo KJS::HTMLElement::p_info = { "HTMLParagraphElement", &KJS::HTMLElement::info, &HTMLParagraphElementTable, 0 };
495 const ClassInfo KJS::HTMLElement::heading_info = { "HTMLHeadingElement", &KJS::HTMLElement::info, &HTMLHeadingElementTable, 0 };
496 const ClassInfo KJS::HTMLElement::blockQuote_info = { "HTMLBlockQuoteElement", &KJS::HTMLElement::info, &HTMLBlockQuoteElementTable, 0 };
497 const ClassInfo KJS::HTMLElement::q_info = { "HTMLQuoteElement", &KJS::HTMLElement::info, &HTMLQuoteElementTable, 0 };
498 const ClassInfo KJS::HTMLElement::pre_info = { "HTMLPreElement", &KJS::HTMLElement::info, &HTMLPreElementTable, 0 };
499 const ClassInfo KJS::HTMLElement::br_info = { "HTMLBRElement", &KJS::HTMLElement::info, &HTMLBRElementTable, 0 };
500 const ClassInfo KJS::HTMLElement::baseFont_info = { "HTMLBaseFontElement", &KJS::HTMLElement::info, &HTMLBaseFontElementTable, 0 };
501 const ClassInfo KJS::HTMLElement::font_info = { "HTMLFontElement", &KJS::HTMLElement::info, &HTMLFontElementTable, 0 };
502 const ClassInfo KJS::HTMLElement::hr_info = { "HTMLHRElement", &KJS::HTMLElement::info, &HTMLHRElementTable, 0 };
503 const ClassInfo KJS::HTMLElement::mod_info = { "HTMLModElement", &KJS::HTMLElement::info, &HTMLModElementTable, 0 };
504 const ClassInfo KJS::HTMLElement::a_info = { "HTMLAnchorElement", &KJS::HTMLElement::info, &HTMLAnchorElementTable, 0 };
505 const ClassInfo KJS::HTMLElement::canvas_info = { "HTMLCanvasElement", &KJS::HTMLElement::info, &HTMLCanvasElementTable, 0 };
506 const ClassInfo KJS::HTMLElement::img_info = { "HTMLImageElement", &KJS::HTMLElement::info, &HTMLImageElementTable, 0 };
507 const ClassInfo KJS::HTMLElement::object_info = { "HTMLObjectElement", &KJS::HTMLElement::info, &HTMLObjectElementTable, 0 };
508 const ClassInfo KJS::HTMLElement::param_info = { "HTMLParamElement", &KJS::HTMLElement::info, &HTMLParamElementTable, 0 };
509 const ClassInfo KJS::HTMLElement::applet_info = { "HTMLAppletElement", &KJS::HTMLElement::info, &HTMLAppletElementTable, 0 };
510 const ClassInfo KJS::HTMLElement::map_info = { "HTMLMapElement", &KJS::HTMLElement::info, &HTMLMapElementTable, 0 };
511 const ClassInfo KJS::HTMLElement::area_info = { "HTMLAreaElement", &KJS::HTMLElement::info, &HTMLAreaElementTable, 0 };
512 const ClassInfo KJS::HTMLElement::script_info = { "HTMLScriptElement", &KJS::HTMLElement::info, &HTMLScriptElementTable, 0 };
513 const ClassInfo KJS::HTMLElement::table_info = { "HTMLTableElement", &KJS::HTMLElement::info, &HTMLTableElementTable, 0 };
514 const ClassInfo KJS::HTMLElement::caption_info = { "HTMLTableCaptionElement", &KJS::HTMLElement::info, &HTMLTableCaptionElementTable, 0 };
515 const ClassInfo KJS::HTMLElement::col_info = { "HTMLTableColElement", &KJS::HTMLElement::info, &HTMLTableColElementTable, 0 };
516 const ClassInfo KJS::HTMLElement::tablesection_info = { "HTMLTableSectionElement", &KJS::HTMLElement::info, &HTMLTableSectionElementTable, 0 };
517 const ClassInfo KJS::HTMLElement::tr_info = { "HTMLTableRowElement", &KJS::HTMLElement::info, &HTMLTableRowElementTable, 0 };
518 const ClassInfo KJS::HTMLElement::tablecell_info = { "HTMLTableCellElement", &KJS::HTMLElement::info, &HTMLTableCellElementTable, 0 };
519 const ClassInfo KJS::HTMLElement::frameSet_info = { "HTMLFrameSetElement", &KJS::HTMLElement::info, &HTMLFrameSetElementTable, 0 };
520 const ClassInfo KJS::HTMLElement::frame_info = { "HTMLFrameElement", &KJS::HTMLElement::info, &HTMLFrameElementTable, 0 };
521 const ClassInfo KJS::HTMLElement::iFrame_info = { "HTMLIFrameElement", &KJS::HTMLElement::info, &HTMLIFrameElementTable, 0 };
522 const ClassInfo KJS::HTMLElement::marquee_info = { "HTMLMarqueeElement", &KJS::HTMLElement::info, &HTMLMarqueeElementTable, 0 };
523
524 const ClassInfo* KJS::HTMLElement::classInfo() const
525 {
526   DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
527   switch (element.elementId()) {
528   case ID_HTML:
529     return &html_info;
530   case ID_HEAD:
531     return &head_info;
532   case ID_LINK:
533     return &link_info;
534   case ID_TITLE:
535     return &title_info;
536   case ID_META:
537     return &meta_info;
538   case ID_BASE:
539     return &base_info;
540   case ID_ISINDEX:
541     return &isIndex_info;
542   case ID_STYLE:
543     return &style_info;
544   case ID_BODY:
545     return &body_info;
546   case ID_FORM:
547     return &form_info;
548   case ID_SELECT:
549     return &select_info;
550   case ID_OPTGROUP:
551     return &optGroup_info;
552   case ID_OPTION:
553     return &option_info;
554   case ID_INPUT:
555     return &input_info;
556   case ID_TEXTAREA:
557     return &textArea_info;
558   case ID_BUTTON:
559     return &button_info;
560   case ID_LABEL:
561     return &label_info;
562   case ID_FIELDSET:
563     return &fieldSet_info;
564   case ID_LEGEND:
565     return &legend_info;
566   case ID_UL:
567     return &ul_info;
568   case ID_OL:
569     return &ol_info;
570   case ID_DL:
571     return &dl_info;
572   case ID_DIR:
573     return &dir_info;
574   case ID_MENU:
575     return &menu_info;
576   case ID_LI:
577     return &li_info;
578   case ID_DIV:
579     return &div_info;
580   case ID_P:
581     return &p_info;
582   case ID_H1:
583   case ID_H2:
584   case ID_H3:
585   case ID_H4:
586   case ID_H5:
587   case ID_H6:
588     return &heading_info;
589   case ID_BLOCKQUOTE:
590     return &blockQuote_info;
591   case ID_Q:
592     return &q_info;
593   case ID_PRE:
594     return &pre_info;
595   case ID_BR:
596     return &br_info;
597   case ID_BASEFONT:
598     return &baseFont_info;
599   case ID_FONT:
600     return &font_info;
601   case ID_HR:
602     return &hr_info;
603   case ID_INS:
604   case ID_DEL:
605     return &mod_info;
606   case ID_A:
607     return &a_info;
608   case ID_CANVAS:
609     return &canvas_info;
610   case ID_IMG:
611     return &img_info;
612   case ID_OBJECT:
613     return &object_info;
614   case ID_PARAM:
615     return &param_info;
616   case ID_APPLET:
617     return &applet_info;
618   case ID_MAP:
619     return &map_info;
620   case ID_AREA:
621     return &area_info;
622   case ID_SCRIPT:
623     return &script_info;
624   case ID_TABLE:
625     return &table_info;
626   case ID_CAPTION:
627     return &caption_info;
628   case ID_COL:
629     return &col_info;
630   case ID_THEAD:
631     return &tablesection_info;
632   case ID_TBODY:
633     return &tablesection_info;
634   case ID_TFOOT:
635     return &tablesection_info;
636   case ID_TR:
637     return &tr_info;
638   case ID_TH:
639     return &tablecell_info;
640   case ID_TD:
641     return &tablecell_info;
642   case ID_FRAMESET:
643     return &frameSet_info;
644   case ID_FRAME:
645     return &frame_info;
646   case ID_IFRAME:
647     return &iFrame_info;
648   case ID_MARQUEE:
649     return &marquee_info;
650   default:
651     return &info;
652   }
653 }
654 /*
655 @begin HTMLElementTable 14
656   id            KJS::HTMLElement::ElementId     DontDelete
657   title         KJS::HTMLElement::ElementTitle  DontDelete
658   lang          KJS::HTMLElement::ElementLang   DontDelete
659   dir           KJS::HTMLElement::ElementDir    DontDelete
660 ### isn't this "class" in the HTML spec?
661   className     KJS::HTMLElement::ElementClassName DontDelete
662   innerHTML     KJS::HTMLElement::ElementInnerHTML DontDelete
663   innerText     KJS::HTMLElement::ElementInnerText DontDelete
664   outerHTML     KJS::HTMLElement::ElementOuterHTML DontDelete
665   outerText     KJS::HTMLElement::ElementOuterText DontDelete
666   document      KJS::HTMLElement::ElementDocument  DontDelete|ReadOnly
667 # IE extension
668   children      KJS::HTMLElement::ElementChildren  DontDelete|ReadOnly
669   contentEditable   KJS::HTMLElement::ElementContentEditable  DontDelete
670   isContentEditable KJS::HTMLElement::ElementIsContentEditable  DontDelete|ReadOnly
671 @end
672 @begin HTMLHtmlElementTable 1
673   version       KJS::HTMLElement::HtmlVersion   DontDelete
674 @end
675 @begin HTMLHeadElementTable 1
676   profile       KJS::HTMLElement::HeadProfile   DontDelete
677 @end
678 @begin HTMLLinkElementTable 11
679   disabled      KJS::HTMLElement::LinkDisabled  DontDelete
680   charset       KJS::HTMLElement::LinkCharset   DontDelete
681   href          KJS::HTMLElement::LinkHref      DontDelete
682   hreflang      KJS::HTMLElement::LinkHrefLang  DontDelete
683   media         KJS::HTMLElement::LinkMedia     DontDelete
684   rel           KJS::HTMLElement::LinkRel       DontDelete
685   rev           KJS::HTMLElement::LinkRev       DontDelete
686   target        KJS::HTMLElement::LinkTarget    DontDelete
687   type          KJS::HTMLElement::LinkType      DontDelete
688   sheet         KJS::HTMLElement::LinkSheet     DontDelete|ReadOnly
689 @end
690 @begin HTMLTitleElementTable 1
691   text          KJS::HTMLElement::TitleText     DontDelete
692 @end
693 @begin HTMLMetaElementTable 4
694   content       KJS::HTMLElement::MetaContent   DontDelete
695   httpEquiv     KJS::HTMLElement::MetaHttpEquiv DontDelete
696   name          KJS::HTMLElement::MetaName      DontDelete
697   scheme        KJS::HTMLElement::MetaScheme    DontDelete
698 @end
699 @begin HTMLBaseElementTable 2
700   href          KJS::HTMLElement::BaseHref      DontDelete
701   target        KJS::HTMLElement::BaseTarget    DontDelete
702 @end
703 @begin HTMLIsIndexElementTable 2
704   form          KJS::HTMLElement::IsIndexForm   DontDelete|ReadOnly
705   prompt        KJS::HTMLElement::IsIndexPrompt DontDelete
706 @end
707 @begin HTMLStyleElementTable 4
708   disabled      KJS::HTMLElement::StyleDisabled DontDelete
709   media         KJS::HTMLElement::StyleMedia    DontDelete
710   type          KJS::HTMLElement::StyleType     DontDelete
711   sheet         KJS::HTMLElement::StyleSheet    DontDelete|ReadOnly
712 @end
713 @begin HTMLBodyElementTable 10
714   aLink         KJS::HTMLElement::BodyALink     DontDelete
715   background    KJS::HTMLElement::BodyBackground        DontDelete
716   bgColor       KJS::HTMLElement::BodyBgColor   DontDelete
717   link          KJS::HTMLElement::BodyLink      DontDelete
718   text          KJS::HTMLElement::BodyText      DontDelete
719   vLink         KJS::HTMLElement::BodyVLink     DontDelete
720   scrollLeft    KJS::HTMLElement::BodyScrollLeft        DontDelete
721   scrollTop     KJS::HTMLElement::BodyScrollTop         DontDelete
722   scrollHeight  KJS::HTMLElement::BodyScrollHeight      DontDelete|ReadOnly
723   scrollWidth   KJS::HTMLElement::BodyScrollWidth       DontDelete|ReadOnly
724 @end
725 @begin HTMLFormElementTable 11
726 # Also supported, by name/index
727   elements      KJS::HTMLElement::FormElements  DontDelete|ReadOnly
728   length        KJS::HTMLElement::FormLength    DontDelete|ReadOnly
729   name          KJS::HTMLElement::FormName      DontDelete
730   acceptCharset KJS::HTMLElement::FormAcceptCharset     DontDelete
731   action        KJS::HTMLElement::FormAction    DontDelete
732   enctype       KJS::HTMLElement::FormEncType   DontDelete
733   method        KJS::HTMLElement::FormMethod    DontDelete
734   target        KJS::HTMLElement::FormTarget    DontDelete
735   submit        KJS::HTMLElement::FormSubmit    DontDelete|Function 0
736   reset         KJS::HTMLElement::FormReset     DontDelete|Function 0
737 @end
738 @begin HTMLSelectElementTable 11
739 # Also supported, by index
740   type          KJS::HTMLElement::SelectType    DontDelete|ReadOnly
741   selectedIndex KJS::HTMLElement::SelectSelectedIndex   DontDelete
742   value         KJS::HTMLElement::SelectValue   DontDelete
743   length        KJS::HTMLElement::SelectLength  DontDelete
744   form          KJS::HTMLElement::SelectForm    DontDelete|ReadOnly
745   options       KJS::HTMLElement::SelectOptions DontDelete|ReadOnly
746   disabled      KJS::HTMLElement::SelectDisabled        DontDelete
747   multiple      KJS::HTMLElement::SelectMultiple        DontDelete
748   name          KJS::HTMLElement::SelectName    DontDelete
749   size          KJS::HTMLElement::SelectSize    DontDelete
750   tabIndex      KJS::HTMLElement::SelectTabIndex        DontDelete
751   add           KJS::HTMLElement::SelectAdd     DontDelete|Function 2
752   remove        KJS::HTMLElement::SelectRemove  DontDelete|Function 1
753   blur          KJS::HTMLElement::SelectBlur    DontDelete|Function 0
754   focus         KJS::HTMLElement::SelectFocus   DontDelete|Function 0
755 @end
756 @begin HTMLOptGroupElementTable 2
757   disabled      KJS::HTMLElement::OptGroupDisabled      DontDelete
758   label         KJS::HTMLElement::OptGroupLabel         DontDelete
759 @end
760 @begin HTMLOptionElementTable 8
761   form          KJS::HTMLElement::OptionForm            DontDelete|ReadOnly
762   defaultSelected KJS::HTMLElement::OptionDefaultSelected       DontDelete
763   text          KJS::HTMLElement::OptionText            DontDelete
764   index         KJS::HTMLElement::OptionIndex           DontDelete|ReadOnly
765   disabled      KJS::HTMLElement::OptionDisabled        DontDelete
766   label         KJS::HTMLElement::OptionLabel           DontDelete
767   selected      KJS::HTMLElement::OptionSelected        DontDelete
768   value         KJS::HTMLElement::OptionValue           DontDelete
769 @end
770 @begin HTMLInputElementTable 23
771   defaultValue  KJS::HTMLElement::InputDefaultValue     DontDelete
772   defaultChecked KJS::HTMLElement::InputDefaultChecked  DontDelete
773   form          KJS::HTMLElement::InputForm             DontDelete|ReadOnly
774   accept        KJS::HTMLElement::InputAccept           DontDelete
775   accessKey     KJS::HTMLElement::InputAccessKey        DontDelete
776   align         KJS::HTMLElement::InputAlign            DontDelete
777   alt           KJS::HTMLElement::InputAlt              DontDelete
778   checked       KJS::HTMLElement::InputChecked          DontDelete
779   disabled      KJS::HTMLElement::InputDisabled         DontDelete
780   maxLength     KJS::HTMLElement::InputMaxLength        DontDelete
781   name          KJS::HTMLElement::InputName             DontDelete
782   readOnly      KJS::HTMLElement::InputReadOnly         DontDelete
783   size          KJS::HTMLElement::InputSize             DontDelete
784   src           KJS::HTMLElement::InputSrc              DontDelete
785   tabIndex      KJS::HTMLElement::InputTabIndex         DontDelete
786   type          KJS::HTMLElement::InputType             DontDelete
787   useMap        KJS::HTMLElement::InputUseMap           DontDelete
788   value         KJS::HTMLElement::InputValue            DontDelete
789   blur          KJS::HTMLElement::InputBlur             DontDelete|Function 0
790   focus         KJS::HTMLElement::InputFocus            DontDelete|Function 0
791   select        KJS::HTMLElement::InputSelect           DontDelete|Function 0
792   click         KJS::HTMLElement::InputClick            DontDelete|Function 0
793 @end
794 @begin HTMLTextAreaElementTable 13
795   defaultValue  KJS::HTMLElement::TextAreaDefaultValue  DontDelete
796   form          KJS::HTMLElement::TextAreaForm          DontDelete|ReadOnly
797   accessKey     KJS::HTMLElement::TextAreaAccessKey     DontDelete
798   cols          KJS::HTMLElement::TextAreaCols          DontDelete
799   disabled      KJS::HTMLElement::TextAreaDisabled      DontDelete
800   name          KJS::HTMLElement::TextAreaName          DontDelete
801   readOnly      KJS::HTMLElement::TextAreaReadOnly      DontDelete
802   rows          KJS::HTMLElement::TextAreaRows          DontDelete
803   tabIndex      KJS::HTMLElement::TextAreaTabIndex      DontDelete
804   type          KJS::HTMLElement::TextAreaType          DontDelete|ReadOnly
805   value         KJS::HTMLElement::TextAreaValue         DontDelete
806   blur          KJS::HTMLElement::TextAreaBlur          DontDelete|Function 0
807   focus         KJS::HTMLElement::TextAreaFocus         DontDelete|Function 0
808   select        KJS::HTMLElement::TextAreaSelect        DontDelete|Function 0
809 @end
810 @begin HTMLButtonElementTable 7
811   form          KJS::HTMLElement::ButtonForm            DontDelete|ReadOnly
812   accessKey     KJS::HTMLElement::ButtonAccessKey       DontDelete
813   disabled      KJS::HTMLElement::ButtonDisabled        DontDelete
814   name          KJS::HTMLElement::ButtonName            DontDelete
815   tabIndex      KJS::HTMLElement::ButtonTabIndex        DontDelete
816   type          KJS::HTMLElement::ButtonType            DontDelete|ReadOnly
817   value         KJS::HTMLElement::ButtonValue           DontDelete
818 @end
819 @begin HTMLLabelElementTable 3
820   form          KJS::HTMLElement::LabelForm             DontDelete|ReadOnly
821   accessKey     KJS::HTMLElement::LabelAccessKey        DontDelete
822   htmlFor       KJS::HTMLElement::LabelHtmlFor          DontDelete
823 @end
824 @begin HTMLFieldSetElementTable 1
825   form          KJS::HTMLElement::FieldSetForm          DontDelete|ReadOnly
826 @end
827 @begin HTMLLegendElementTable 3
828   form          KJS::HTMLElement::LegendForm            DontDelete|ReadOnly
829   accessKey     KJS::HTMLElement::LegendAccessKey       DontDelete
830   align         KJS::HTMLElement::LegendAlign           DontDelete
831 @end
832 @begin HTMLUListElementTable 2
833   compact       KJS::HTMLElement::UListCompact          DontDelete
834   type          KJS::HTMLElement::UListType             DontDelete
835 @end
836 @begin HTMLOListElementTable 3
837   compact       KJS::HTMLElement::OListCompact          DontDelete
838   start         KJS::HTMLElement::OListStart            DontDelete
839   type          KJS::HTMLElement::OListType             DontDelete
840 @end
841 @begin HTMLDListElementTable 1
842   compact       KJS::HTMLElement::DListCompact          DontDelete
843 @end
844 @begin HTMLDirectoryElementTable 1
845   compact       KJS::HTMLElement::DirectoryCompact      DontDelete
846 @end
847 @begin HTMLMenuElementTable 1
848   compact       KJS::HTMLElement::MenuCompact           DontDelete
849 @end
850 @begin HTMLLIElementTable 2
851   type          KJS::HTMLElement::LIType                DontDelete
852   value         KJS::HTMLElement::LIValue               DontDelete
853 @end
854 @begin HTMLDivElementTable 1
855   align         KJS::HTMLElement::DivAlign              DontDelete
856 @end
857 @begin HTMLParagraphElementTable 1
858   align         KJS::HTMLElement::ParagraphAlign        DontDelete
859 @end
860 @begin HTMLHeadingElementTable 1
861   align         KJS::HTMLElement::HeadingAlign          DontDelete
862 @end
863 @begin HTMLBlockQuoteElementTable 1
864   cite          KJS::HTMLElement::BlockQuoteCite        DontDelete
865 @end
866 @begin HTMLQuoteElementTable 1
867   cite          KJS::HTMLElement::QuoteCite             DontDelete
868 @end
869 @begin HTMLPreElementTable 1
870   width         KJS::HTMLElement::PreWidth              DontDelete
871 @end
872 @begin HTMLBRElementTable 1
873   clear         KJS::HTMLElement::BRClear               DontDelete
874 @end
875 @begin HTMLBaseFontElementTable 3
876   color         KJS::HTMLElement::BaseFontColor         DontDelete
877   face          KJS::HTMLElement::BaseFontFace          DontDelete
878   size          KJS::HTMLElement::BaseFontSize          DontDelete
879 @end
880 @begin HTMLFontElementTable 3
881   color         KJS::HTMLElement::FontColor             DontDelete
882   face          KJS::HTMLElement::FontFace              DontDelete
883   size          KJS::HTMLElement::FontSize              DontDelete
884 @end
885 @begin HTMLHRElementTable 4
886   align         KJS::HTMLElement::HRAlign               DontDelete
887   noShade       KJS::HTMLElement::HRNoShade             DontDelete
888   size          KJS::HTMLElement::HRSize                DontDelete
889   width         KJS::HTMLElement::HRWidth               DontDelete
890 @end
891 @begin HTMLModElementTable 2
892   cite          KJS::HTMLElement::ModCite               DontDelete
893   dateTime      KJS::HTMLElement::ModDateTime           DontDelete
894 @end
895 @begin HTMLAnchorElementTable 24
896   accessKey     KJS::HTMLElement::AnchorAccessKey       DontDelete
897   charset       KJS::HTMLElement::AnchorCharset         DontDelete
898   coords        KJS::HTMLElement::AnchorCoords          DontDelete
899   href          KJS::HTMLElement::AnchorHref            DontDelete
900   hreflang      KJS::HTMLElement::AnchorHrefLang        DontDelete
901   hash          KJS::HTMLElement::AnchorHash            DontDelete|ReadOnly
902   host          KJS::HTMLElement::AnchorHost            DontDelete|ReadOnly
903   hostname      KJS::HTMLElement::AnchorHostname        DontDelete|ReadOnly
904   name          KJS::HTMLElement::AnchorName            DontDelete
905   pathname      KJS::HTMLElement::AnchorPathName        DontDelete|ReadOnly
906   port          KJS::HTMLElement::AnchorPort            DontDelete|ReadOnly
907   protocol      KJS::HTMLElement::AnchorProtocol        DontDelete|ReadOnly
908   rel           KJS::HTMLElement::AnchorRel             DontDelete
909   rev           KJS::HTMLElement::AnchorRev             DontDelete
910   search        KJS::HTMLElement::AnchorSearch          DontDelete|ReadOnly
911   shape         KJS::HTMLElement::AnchorShape           DontDelete
912   tabIndex      KJS::HTMLElement::AnchorTabIndex        DontDelete
913   target        KJS::HTMLElement::AnchorTarget          DontDelete
914   text          KJS::HTMLElement::AnchorText            DontDelete|ReadOnly
915   type          KJS::HTMLElement::AnchorType            DontDelete
916   blur          KJS::HTMLElement::AnchorBlur            DontDelete|Function 0
917   focus         KJS::HTMLElement::AnchorFocus           DontDelete|Function 0
918   toString      KJS::HTMLElement::AnchorToString        DontDelete|Function 0
919 @end
920 @begin HTMLImageElementTable 14
921   name          KJS::HTMLElement::ImageName             DontDelete
922   align         KJS::HTMLElement::ImageAlign            DontDelete
923   alt           KJS::HTMLElement::ImageAlt              DontDelete
924   border        KJS::HTMLElement::ImageBorder           DontDelete
925   height        KJS::HTMLElement::ImageHeight           DontDelete
926   hspace        KJS::HTMLElement::ImageHspace           DontDelete
927   isMap         KJS::HTMLElement::ImageIsMap            DontDelete
928   longDesc      KJS::HTMLElement::ImageLongDesc         DontDelete
929   src           KJS::HTMLElement::ImageSrc              DontDelete
930   useMap        KJS::HTMLElement::ImageUseMap           DontDelete
931   vspace        KJS::HTMLElement::ImageVspace           DontDelete
932   width         KJS::HTMLElement::ImageWidth            DontDelete
933   x         KJS::HTMLElement::ImageX            DontDelete|ReadOnly
934   y         KJS::HTMLElement::ImageY            DontDelete|ReadOnly
935 @end
936 @begin HTMLObjectElementTable 20
937   form            KJS::HTMLElement::ObjectForm            DontDelete|ReadOnly
938   code            KJS::HTMLElement::ObjectCode            DontDelete
939   align           KJS::HTMLElement::ObjectAlign           DontDelete
940   archive         KJS::HTMLElement::ObjectArchive         DontDelete
941   border          KJS::HTMLElement::ObjectBorder          DontDelete
942   codeBase        KJS::HTMLElement::ObjectCodeBase        DontDelete
943   codeType        KJS::HTMLElement::ObjectCodeType        DontDelete
944   contentDocument KJS::HTMLElement::ObjectContentDocument DontDelete|ReadOnly
945   data            KJS::HTMLElement::ObjectData            DontDelete
946   declare         KJS::HTMLElement::ObjectDeclare         DontDelete
947   height          KJS::HTMLElement::ObjectHeight          DontDelete
948   hspace          KJS::HTMLElement::ObjectHspace          DontDelete
949   name            KJS::HTMLElement::ObjectName            DontDelete
950   standby         KJS::HTMLElement::ObjectStandby         DontDelete
951   tabIndex        KJS::HTMLElement::ObjectTabIndex        DontDelete
952   type            KJS::HTMLElement::ObjectType            DontDelete
953   useMap          KJS::HTMLElement::ObjectUseMap          DontDelete
954   vspace          KJS::HTMLElement::ObjectVspace          DontDelete
955   width           KJS::HTMLElement::ObjectWidth           DontDelete
956 @end
957 @begin HTMLParamElementTable 4
958   name          KJS::HTMLElement::ParamName             DontDelete
959   type          KJS::HTMLElement::ParamType             DontDelete
960   value         KJS::HTMLElement::ParamValue            DontDelete
961   valueType     KJS::HTMLElement::ParamValueType        DontDelete
962 @end
963 @begin HTMLAppletElementTable 11
964   align         KJS::HTMLElement::AppletAlign           DontDelete
965   alt           KJS::HTMLElement::AppletAlt             DontDelete
966   archive       KJS::HTMLElement::AppletArchive         DontDelete
967   code          KJS::HTMLElement::AppletCode            DontDelete
968   codeBase      KJS::HTMLElement::AppletCodeBase        DontDelete
969   height        KJS::HTMLElement::AppletHeight          DontDelete
970   hspace        KJS::HTMLElement::AppletHspace          DontDelete
971   name          KJS::HTMLElement::AppletName            DontDelete
972   object        KJS::HTMLElement::AppletObject          DontDelete
973   vspace        KJS::HTMLElement::AppletVspace          DontDelete
974   width         KJS::HTMLElement::AppletWidth           DontDelete
975 @end
976 @begin HTMLMapElementTable 2
977   areas         KJS::HTMLElement::MapAreas              DontDelete|ReadOnly
978   name          KJS::HTMLElement::MapName               DontDelete
979 @end
980 @begin HTMLAreaElementTable 15
981   accessKey     KJS::HTMLElement::AreaAccessKey         DontDelete
982   alt           KJS::HTMLElement::AreaAlt               DontDelete
983   coords        KJS::HTMLElement::AreaCoords            DontDelete
984   href          KJS::HTMLElement::AreaHref              DontDelete
985   hash          KJS::HTMLElement::AreaHash              DontDelete|ReadOnly
986   host          KJS::HTMLElement::AreaHost              DontDelete|ReadOnly
987   hostname      KJS::HTMLElement::AreaHostName          DontDelete|ReadOnly
988   pathname      KJS::HTMLElement::AreaPathName          DontDelete|ReadOnly
989   port          KJS::HTMLElement::AreaPort              DontDelete|ReadOnly
990   protocol      KJS::HTMLElement::AreaProtocol          DontDelete|ReadOnly
991   search        KJS::HTMLElement::AreaSearch            DontDelete|ReadOnly
992   noHref        KJS::HTMLElement::AreaNoHref            DontDelete
993   shape         KJS::HTMLElement::AreaShape             DontDelete
994   tabIndex      KJS::HTMLElement::AreaTabIndex          DontDelete
995   target        KJS::HTMLElement::AreaTarget            DontDelete
996 @end
997 @begin HTMLScriptElementTable 7
998   text          KJS::HTMLElement::ScriptText            DontDelete
999   htmlFor       KJS::HTMLElement::ScriptHtmlFor         DontDelete
1000   event         KJS::HTMLElement::ScriptEvent           DontDelete
1001   charset       KJS::HTMLElement::ScriptCharset         DontDelete
1002   defer         KJS::HTMLElement::ScriptDefer           DontDelete
1003   src           KJS::HTMLElement::ScriptSrc             DontDelete
1004   type          KJS::HTMLElement::ScriptType            DontDelete
1005 @end
1006 @begin HTMLTableElementTable 23
1007   caption       KJS::HTMLElement::TableCaption          DontDelete
1008   tHead         KJS::HTMLElement::TableTHead            DontDelete
1009   tFoot         KJS::HTMLElement::TableTFoot            DontDelete
1010   rows          KJS::HTMLElement::TableRows             DontDelete|ReadOnly
1011   tBodies       KJS::HTMLElement::TableTBodies          DontDelete|ReadOnly
1012   align         KJS::HTMLElement::TableAlign            DontDelete
1013   bgColor       KJS::HTMLElement::TableBgColor          DontDelete
1014   border        KJS::HTMLElement::TableBorder           DontDelete
1015   cellPadding   KJS::HTMLElement::TableCellPadding      DontDelete
1016   cellSpacing   KJS::HTMLElement::TableCellSpacing      DontDelete
1017   frame         KJS::HTMLElement::TableFrame            DontDelete
1018   rules         KJS::HTMLElement::TableRules            DontDelete
1019   summary       KJS::HTMLElement::TableSummary          DontDelete
1020   width         KJS::HTMLElement::TableWidth            DontDelete
1021   createTHead   KJS::HTMLElement::TableCreateTHead      DontDelete|Function 0
1022   deleteTHead   KJS::HTMLElement::TableDeleteTHead      DontDelete|Function 0
1023   createTFoot   KJS::HTMLElement::TableCreateTFoot      DontDelete|Function 0
1024   deleteTFoot   KJS::HTMLElement::TableDeleteTFoot      DontDelete|Function 0
1025   createCaption KJS::HTMLElement::TableCreateCaption    DontDelete|Function 0
1026   deleteCaption KJS::HTMLElement::TableDeleteCaption    DontDelete|Function 0
1027   insertRow     KJS::HTMLElement::TableInsertRow        DontDelete|Function 1
1028   deleteRow     KJS::HTMLElement::TableDeleteRow        DontDelete|Function 1
1029 @end
1030 @begin HTMLTableCaptionElementTable 1
1031   align         KJS::HTMLElement::TableCaptionAlign     DontDelete
1032 @end
1033 @begin HTMLTableColElementTable 7
1034   align         KJS::HTMLElement::TableColAlign         DontDelete
1035   ch            KJS::HTMLElement::TableColCh            DontDelete
1036   chOff         KJS::HTMLElement::TableColChOff         DontDelete
1037   span          KJS::HTMLElement::TableColSpan          DontDelete
1038   vAlign        KJS::HTMLElement::TableColVAlign        DontDelete
1039   width         KJS::HTMLElement::TableColWidth         DontDelete
1040 @end
1041 @begin HTMLTableSectionElementTable 7
1042   align         KJS::HTMLElement::TableSectionAlign             DontDelete
1043   ch            KJS::HTMLElement::TableSectionCh                DontDelete
1044   chOff         KJS::HTMLElement::TableSectionChOff             DontDelete
1045   vAlign        KJS::HTMLElement::TableSectionVAlign            DontDelete
1046   rows          KJS::HTMLElement::TableSectionRows              DontDelete|ReadOnly
1047   insertRow     KJS::HTMLElement::TableSectionInsertRow         DontDelete|Function 1
1048   deleteRow     KJS::HTMLElement::TableSectionDeleteRow         DontDelete|Function 1
1049 @end
1050 @begin HTMLTableRowElementTable 11
1051   rowIndex      KJS::HTMLElement::TableRowRowIndex              DontDelete|ReadOnly
1052   sectionRowIndex KJS::HTMLElement::TableRowSectionRowIndex     DontDelete|ReadOnly
1053   cells         KJS::HTMLElement::TableRowCells                 DontDelete|ReadOnly
1054   align         KJS::HTMLElement::TableRowAlign                 DontDelete
1055   bgColor       KJS::HTMLElement::TableRowBgColor               DontDelete
1056   ch            KJS::HTMLElement::TableRowCh                    DontDelete
1057   chOff         KJS::HTMLElement::TableRowChOff                 DontDelete
1058   vAlign        KJS::HTMLElement::TableRowVAlign                DontDelete
1059   insertCell    KJS::HTMLElement::TableRowInsertCell            DontDelete|Function 1
1060   deleteCell    KJS::HTMLElement::TableRowDeleteCell            DontDelete|Function 1
1061 @end
1062 @begin HTMLTableCellElementTable 15
1063   cellIndex     KJS::HTMLElement::TableCellCellIndex            DontDelete|ReadOnly
1064   abbr          KJS::HTMLElement::TableCellAbbr                 DontDelete
1065   align         KJS::HTMLElement::TableCellAlign                DontDelete
1066   axis          KJS::HTMLElement::TableCellAxis                 DontDelete
1067   bgColor       KJS::HTMLElement::TableCellBgColor              DontDelete
1068   ch            KJS::HTMLElement::TableCellCh                   DontDelete
1069   chOff         KJS::HTMLElement::TableCellChOff                DontDelete
1070   colSpan       KJS::HTMLElement::TableCellColSpan              DontDelete
1071   headers       KJS::HTMLElement::TableCellHeaders              DontDelete
1072   height        KJS::HTMLElement::TableCellHeight               DontDelete
1073   noWrap        KJS::HTMLElement::TableCellNoWrap               DontDelete
1074   rowSpan       KJS::HTMLElement::TableCellRowSpan              DontDelete
1075   scope         KJS::HTMLElement::TableCellScope                DontDelete
1076   vAlign        KJS::HTMLElement::TableCellVAlign               DontDelete
1077   width         KJS::HTMLElement::TableCellWidth                DontDelete
1078 @end
1079 @begin HTMLFrameSetElementTable 2
1080   cols          KJS::HTMLElement::FrameSetCols                  DontDelete
1081   rows          KJS::HTMLElement::FrameSetRows                  DontDelete
1082 @end
1083 @begin HTMLFrameElementTable 9
1084   contentDocument KJS::HTMLElement::FrameContentDocument        DontDelete|ReadOnly
1085   contentWindow   KJS::HTMLElement::FrameContentWindow          DontDelete|ReadOnly
1086   frameBorder     KJS::HTMLElement::FrameFrameBorder            DontDelete
1087   longDesc        KJS::HTMLElement::FrameLongDesc               DontDelete
1088   marginHeight    KJS::HTMLElement::FrameMarginHeight           DontDelete
1089   marginWidth     KJS::HTMLElement::FrameMarginWidth            DontDelete
1090   name            KJS::HTMLElement::FrameName                   DontDelete
1091   noResize        KJS::HTMLElement::FrameNoResize               DontDelete
1092   scrolling       KJS::HTMLElement::FrameScrolling              DontDelete
1093   src             KJS::HTMLElement::FrameSrc                    DontDelete
1094   location        KJS::HTMLElement::FrameLocation               DontDelete
1095 @end
1096 @begin HTMLIFrameElementTable 12
1097   align           KJS::HTMLElement::IFrameAlign                 DontDelete
1098   contentDocument KJS::HTMLElement::IFrameContentDocument       DontDelete|ReadOnly
1099   contentWindow   KJS::HTMLElement::IFrameContentWindow         DontDelete|ReadOnly
1100   document        KJS::HTMLElement::IFrameDocument              DontDelete|ReadOnly
1101   frameBorder     KJS::HTMLElement::IFrameFrameBorder           DontDelete
1102   height          KJS::HTMLElement::IFrameHeight                DontDelete
1103   longDesc        KJS::HTMLElement::IFrameLongDesc              DontDelete
1104   marginHeight    KJS::HTMLElement::IFrameMarginHeight          DontDelete
1105   marginWidth     KJS::HTMLElement::IFrameMarginWidth           DontDelete
1106   name            KJS::HTMLElement::IFrameName                  DontDelete
1107   scrolling       KJS::HTMLElement::IFrameScrolling             DontDelete
1108   src             KJS::HTMLElement::IFrameSrc                   DontDelete
1109   width           KJS::HTMLElement::IFrameWidth                 DontDelete
1110 @end
1111
1112 @begin HTMLMarqueeElementTable 2
1113   start           KJS::HTMLElement::MarqueeStart                DontDelete|Function 0
1114   stop            KJS::HTMLElement::MarqueeStop                 DontDelete|Function 0
1115 @end
1116
1117 @begin HTMLCanvasElementTable 1
1118   getContext      KJS::HTMLElement::GetContext                  DontDelete|Function 0
1119 @end
1120 */
1121
1122 Value KJS::HTMLElement::tryGet(ExecState *exec, const Identifier &propertyName) const
1123 {
1124   DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
1125 #ifdef KJS_VERBOSE
1126   kdDebug(6070) << "KJS::HTMLElement::tryGet " << propertyName.qstring() << " thisTag=" << element.tagName().string() << endl;
1127 #endif
1128   // First look at dynamic properties
1129   switch (element.elementId()) {
1130     case ID_FORM: {
1131       DOM::HTMLFormElement form = element;
1132       // Check if we're retrieving an element (by index or by name)
1133       bool ok;
1134       uint u = propertyName.toULong(&ok);
1135       if (ok)
1136         return getDOMNode(exec,form.elements().item(u));
1137       KJS::HTMLCollection coll(exec,form.elements());
1138       Value namedItems = coll.getNamedItems(exec, propertyName);
1139       if (namedItems.type() != UndefinedType)
1140         return namedItems;
1141     }
1142       break;
1143     case ID_SELECT: {
1144       DOM::HTMLSelectElement select = element;
1145       bool ok;
1146       uint u = propertyName.toULong(&ok);
1147       if (ok)
1148         return getDOMNode(exec,select.options().item(u)); // not specified by DOM(?) but supported in netscape/IE
1149     }
1150       break;
1151     case ID_FRAME:
1152     case ID_IFRAME: {
1153         DOM::DocumentImpl* doc = static_cast<DOM::HTMLFrameElementImpl *>(element.handle())->contentDocument();
1154         if ( doc ) {
1155             KHTMLPart* part = doc->part();
1156             if ( part ) {
1157               Object globalObject = Object::dynamicCast( Window::retrieve( part ) );
1158               // Calling hasProperty on a Window object doesn't work, it always says true.
1159               // Hence we need to use getDirect instead.
1160               if ( !globalObject.isNull() && static_cast<ObjectImp *>(globalObject.imp())->getDirect( propertyName ) )
1161                 return globalObject.get( exec, propertyName );
1162             }
1163         }
1164     }
1165       break;
1166 #if APPLE_CHANGES
1167     case ID_EMBED:
1168     case ID_APPLET: {
1169         Value v = getRuntimeObject(exec,element);
1170         if (!v.isNull())
1171             return v;
1172     }
1173       break;
1174 #endif
1175     default:
1176         break;
1177     }
1178
1179   const HashTable* table = classInfo()->propHashTable; // get the right hashtable
1180   const HashEntry* entry = Lookup::findEntry(table, propertyName);
1181   if (entry) {
1182     if (entry->attr & Function)
1183       return lookupOrCreateFunction<KJS::HTMLElementFunction>(exec, propertyName, this, entry->value, entry->params, entry->attr);
1184     return getValueProperty(exec, entry->value);
1185   }
1186
1187   // Base HTMLElement stuff or parent class forward, as usual
1188   return DOMObjectLookupGet<KJS::HTMLElementFunction, KJS::HTMLElement, DOMElement>(exec, propertyName, &KJS::HTMLElementTable, this);
1189 }
1190
1191 Value KJS::HTMLElement::getValueProperty(ExecState *exec, int token) const
1192 {
1193   DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
1194   switch (element.elementId()) {
1195   case ID_HTML: {
1196     DOM::HTMLHtmlElement html = element;
1197     if      (token == HtmlVersion)         return String(html.version());
1198   }
1199   break;
1200   case ID_HEAD: {
1201     DOM::HTMLHeadElement head = element;
1202     if      (token == HeadProfile)         return String(head.profile());
1203   }
1204   break;
1205   case ID_LINK: {
1206     DOM::HTMLLinkElement link = element;
1207     switch (token) {
1208     case LinkDisabled:        return Boolean(link.disabled());
1209     case LinkCharset:         return String(link.charset());
1210     case LinkHref:            return String(link.href());
1211     case LinkHrefLang:        return String(link.hreflang());
1212     case LinkMedia:           return String(link.media());
1213     case LinkRel:             return String(link.rel());
1214     case LinkRev:             return String(link.rev());
1215     case LinkTarget:          return String(link.target());
1216     case LinkType:            return String(link.type());
1217     case LinkSheet:           return getDOMStyleSheet(exec,static_cast<DOM::ProcessingInstruction>(node).sheet());
1218     }
1219   }
1220   break;
1221   case ID_TITLE: {
1222     DOM::HTMLTitleElement title = element;
1223     switch (token) {
1224     case TitleText:                 return String(title.text());
1225     }
1226   }
1227   break;
1228   case ID_META: {
1229     DOM::HTMLMetaElement meta = element;
1230     switch (token) {
1231     case MetaContent:         return String(meta.content());
1232     case MetaHttpEquiv:       return String(meta.httpEquiv());
1233     case MetaName:            return String(meta.name());
1234     case MetaScheme:          return String(meta.scheme());
1235     }
1236   }
1237   break;
1238   case ID_BASE: {
1239     DOM::HTMLBaseElement base = element;
1240     switch (token) {
1241     case BaseHref:            return String(base.href());
1242     case BaseTarget:          return String(base.target());
1243     }
1244   }
1245   break;
1246   case ID_ISINDEX: {
1247     DOM::HTMLIsIndexElement isindex = element;
1248     switch (token) {
1249     case IsIndexForm:            return getDOMNode(exec,isindex.form()); // type HTMLFormElement
1250     case IsIndexPrompt:          return String(isindex.prompt());
1251     }
1252   }
1253   break;
1254   case ID_STYLE: {
1255     DOM::HTMLStyleElement style = element;
1256     switch (token) {
1257     case StyleDisabled:        return Boolean(style.disabled());
1258     case StyleMedia:           return String(style.media());
1259     case StyleType:            return String(style.type());
1260     case StyleSheet:           return getDOMStyleSheet(exec,static_cast<DOM::ProcessingInstruction>(node).sheet());
1261     }
1262   }
1263   break;
1264   case ID_BODY: {
1265     DOM::HTMLBodyElement body = element;
1266     switch (token) {
1267     case BodyALink:           return String(body.aLink());
1268     case BodyBackground:      return String(body.background());
1269     case BodyBgColor:         return String(body.bgColor());
1270     case BodyLink:            return String(body.link());
1271     case BodyText:            return String(body.text());
1272     case BodyVLink:           return String(body.vLink());
1273     default:
1274       // Update the document's layout before we compute these attributes.
1275       DOM::DocumentImpl* docimpl = node.handle()->getDocument();
1276       if (docimpl) {
1277         docimpl->updateLayoutIgnorePendingStylesheets();
1278       }
1279       switch (token) {
1280         case BodyScrollLeft:
1281             return Number(body.ownerDocument().view() ? body.ownerDocument().view()->contentsX() : 0);
1282         case BodyScrollTop:
1283             return Number(body.ownerDocument().view() ? body.ownerDocument().view()->contentsY() : 0);
1284         case BodyScrollHeight:   return Number(body.ownerDocument().view() ? body.ownerDocument().view()->contentsHeight() : 0);
1285         case BodyScrollWidth:    return Number(body.ownerDocument().view() ? body.ownerDocument().view()->contentsWidth() : 0);
1286       }
1287     }
1288   }
1289   break;
1290
1291   case ID_FORM: {
1292     DOM::HTMLFormElement form = element;
1293     switch (token) {
1294     case FormElements:        return getHTMLCollection(exec,form.elements());
1295     case FormLength:          return Number(form.length());
1296     case FormName:            return String(form.name());
1297     case FormAcceptCharset:   return String(form.acceptCharset());
1298     case FormAction:          return String(form.action());
1299     case FormEncType:         return String(form.enctype());
1300     case FormMethod:          return String(form.method());
1301     case FormTarget:          return String(form.target());
1302     }
1303   }
1304   break;
1305   case ID_SELECT: {
1306     DOM::HTMLSelectElement select = element;
1307     switch (token) {
1308     case SelectType:            return String(select.type());
1309     case SelectSelectedIndex:   return Number(select.selectedIndex());
1310     case SelectValue:           return String(select.value());
1311     case SelectLength:          return Number(select.length());
1312     case SelectForm:            return getDOMNode(exec,select.form()); // type HTMLFormElement
1313     case SelectOptions:         return getSelectHTMLCollection(exec, select.options(), select); // type HTMLCollection
1314     case SelectDisabled:        return Boolean(select.disabled());
1315     case SelectMultiple:        return Boolean(select.multiple());
1316     case SelectName:            return String(select.name());
1317     case SelectSize:            return Number(select.size());
1318     case SelectTabIndex:        return Number(select.tabIndex());
1319     }
1320   }
1321   break;
1322   case ID_OPTGROUP: {
1323     DOM::HTMLOptGroupElement optgroup = element;
1324     switch (token) {
1325     case OptGroupDisabled:        return Boolean(optgroup.disabled());
1326     case OptGroupLabel:           return String(optgroup.label());
1327     }
1328   }
1329   break;
1330   case ID_OPTION: {
1331     DOM::HTMLOptionElement option = element;
1332     switch (token) {
1333     case OptionForm:            return getDOMNode(exec,option.form()); // type HTMLFormElement
1334     case OptionDefaultSelected: return Boolean(option.defaultSelected());
1335     case OptionText:            return String(option.text());
1336     case OptionIndex:           return Number(option.index());
1337     case OptionDisabled:        return Boolean(option.disabled());
1338     case OptionLabel:           return String(option.label());
1339     case OptionSelected:        return Boolean(option.selected());
1340     case OptionValue:           return String(option.value());
1341     }
1342   }
1343   break;
1344   case ID_INPUT: {
1345     DOM::HTMLInputElement input = element;
1346     switch (token) {
1347     case InputDefaultValue:    return String(input.defaultValue());
1348     case InputDefaultChecked:  return Boolean(input.defaultChecked());
1349     case InputForm:            return getDOMNode(exec,input.form()); // type HTMLFormElement
1350     case InputAccept:          return String(input.accept());
1351     case InputAccessKey:       return String(input.accessKey());
1352     case InputAlign:           return String(input.align());
1353     case InputAlt:             return String(input.alt());
1354     case InputChecked:         return Boolean(input.checked());
1355     case InputDisabled:        return Boolean(input.disabled());
1356     case InputMaxLength:       return Number(input.maxLength());
1357     case InputName:            return String(input.name());
1358     case InputReadOnly:        return Boolean(input.readOnly());
1359     case InputSize:            return String(input.size());
1360     case InputSrc:             return String(input.src());
1361     case InputTabIndex:        return Number(input.tabIndex());
1362     case InputType:            return String(input.type());
1363     case InputUseMap:          return String(input.useMap());
1364     case InputValue:           return String(input.value());
1365     }
1366   }
1367   break;
1368   case ID_TEXTAREA: {
1369     DOM::HTMLTextAreaElement textarea = element;
1370     switch (token) {
1371     case TextAreaDefaultValue:    return String(textarea.defaultValue());
1372     case TextAreaForm:            return getDOMNode(exec,textarea.form()); // type HTMLFormElement
1373     case TextAreaAccessKey:       return String(textarea.accessKey());
1374     case TextAreaCols:            return Number(textarea.cols());
1375     case TextAreaDisabled:        return Boolean(textarea.disabled());
1376     case TextAreaName:            return String(textarea.name());
1377     case TextAreaReadOnly:        return Boolean(textarea.readOnly());
1378     case TextAreaRows:            return Number(textarea.rows());
1379     case TextAreaTabIndex:        return Number(textarea.tabIndex());
1380     case TextAreaType:            return String(textarea.type());
1381     case TextAreaValue:           return String(textarea.value());
1382     }
1383   }
1384   break;
1385   case ID_BUTTON: {
1386     DOM::HTMLButtonElement button = element;
1387     switch (token) {
1388     case ButtonForm:            return getDOMNode(exec,button.form()); // type HTMLFormElement
1389     case ButtonAccessKey:       return String(button.accessKey());
1390     case ButtonDisabled:        return Boolean(button.disabled());
1391     case ButtonName:            return String(button.name());
1392     case ButtonTabIndex:        return Number(button.tabIndex());
1393     case ButtonType:            return String(button.type());
1394     case ButtonValue:           return String(button.value());
1395     }
1396   }
1397   break;
1398   case ID_LABEL: {
1399     DOM::HTMLLabelElement label = element;
1400     switch (token) {
1401     case LabelForm:            return getDOMNode(exec,label.form()); // type HTMLFormElement
1402     case LabelAccessKey:       return String(label.accessKey());
1403     case LabelHtmlFor:         return String(label.htmlFor());
1404     }
1405   }
1406   break;
1407   case ID_FIELDSET: {
1408     DOM::HTMLFieldSetElement fieldSet = element;
1409     switch (token) {
1410     case FieldSetForm:            return getDOMNode(exec,fieldSet.form()); // type HTMLFormElement
1411     }
1412   }
1413   break;
1414   case ID_LEGEND: {
1415     DOM::HTMLLegendElement legend = element;
1416     switch (token) {
1417     case LegendForm:            return getDOMNode(exec,legend.form()); // type HTMLFormElement
1418     case LegendAccessKey:       return String(legend.accessKey());
1419     case LegendAlign:           return String(legend.align());
1420     }
1421   }
1422   break;
1423   case ID_UL: {
1424     DOM::HTMLUListElement uList = element;
1425     switch (token) {
1426     case UListCompact:         return Boolean(uList.compact());
1427     case UListType:            return String(uList.type());
1428     }
1429   }
1430   break;
1431   case ID_OL: {
1432     DOM::HTMLOListElement oList = element;
1433     switch (token) {
1434     case OListCompact:         return Boolean(oList.compact());
1435     case OListStart:           return Number(oList.start());
1436     case OListType:            return String(oList.type());
1437     }
1438   }
1439   break;
1440   case ID_DL: {
1441     DOM::HTMLDListElement dList = element;
1442     switch (token) {
1443     case DListCompact:         return Boolean(dList.compact());
1444     }
1445   }
1446   break;
1447   case ID_DIR: {
1448     DOM::HTMLDirectoryElement directory = element;
1449     switch (token) {
1450     case DirectoryCompact:         return Boolean(directory.compact());
1451     }
1452   }
1453   break;
1454   case ID_MENU: {
1455     DOM::HTMLMenuElement menu = element;
1456     switch (token) {
1457     case MenuCompact:         return Boolean(menu.compact());
1458     }
1459   }
1460   break;
1461   case ID_LI: {
1462     DOM::HTMLLIElement li = element;
1463     switch (token) {
1464     case LIType:            return String(li.type());
1465     case LIValue:           return Number(li.value());
1466     }
1467   }
1468   break;
1469   case ID_DIV: {
1470     DOM::HTMLDivElement div = element;
1471     switch (token) {
1472     case DivAlign:           return String(div.align());
1473     }
1474   }
1475   break;
1476   case ID_P: {
1477     DOM::HTMLParagraphElement paragraph = element;
1478     switch (token) {
1479     case ParagraphAlign:           return String(paragraph.align());
1480     }
1481   }
1482   break;
1483   case ID_H1:
1484   case ID_H2:
1485   case ID_H3:
1486   case ID_H4:
1487   case ID_H5:
1488   case ID_H6: {
1489     DOM::HTMLHeadingElement heading = element;
1490     switch (token) {
1491     case HeadingAlign:           return String(heading.align());
1492     }
1493   }
1494   break;
1495   case ID_BLOCKQUOTE: {
1496     DOM::HTMLBlockquoteElement blockquote = element;
1497     switch (token) {
1498     case BlockQuoteCite:            return String(blockquote.cite());
1499     }
1500   }
1501   case ID_Q: {
1502     DOM::HTMLQuoteElement quote = element;
1503     switch (token) {
1504     case QuoteCite:            return String(quote.cite());
1505     }
1506   }
1507   case ID_PRE: {
1508     DOM::HTMLPreElement pre = element;
1509     switch (token) {
1510     case PreWidth:           return Number(pre.width());
1511     }
1512   }
1513   break;
1514   case ID_BR: {
1515     DOM::HTMLBRElement br = element;
1516     switch (token) {
1517     case BRClear:           return String(br.clear());
1518     }
1519   }
1520   break;
1521   case ID_BASEFONT: {
1522     DOM::HTMLBaseFontElement baseFont = element;
1523     switch (token) {
1524     case BaseFontColor:           return String(baseFont.color());
1525     case BaseFontFace:            return String(baseFont.face());
1526     case BaseFontSize:            return String(baseFont.size());
1527     }
1528   }
1529   break;
1530   case ID_FONT: {
1531     DOM::HTMLFontElement font = element;
1532     switch (token) {
1533     case FontColor:           return String(font.color());
1534     case FontFace:            return String(font.face());
1535     case FontSize:            return String(font.size());
1536     }
1537   }
1538   break;
1539   case ID_HR: {
1540     DOM::HTMLHRElement hr = element;
1541     switch (token) {
1542     case HRAlign:           return String(hr.align());
1543     case HRNoShade:         return Boolean(hr.noShade());
1544     case HRSize:            return String(hr.size());
1545     case HRWidth:           return String(hr.width());
1546     }
1547   }
1548   break;
1549   case ID_INS:
1550   case ID_DEL: {
1551     DOM::HTMLModElement mod = element;
1552     switch (token) {
1553     case ModCite:            return String(mod.cite());
1554     case ModDateTime:        return String(mod.dateTime());
1555     }
1556   }
1557   break;
1558   case ID_A: {
1559     DOM::HTMLAnchorElement anchor = element;
1560     switch (token) {
1561     case AnchorAccessKey:       return String(anchor.accessKey());
1562     case AnchorCharset:         return String(anchor.charset());
1563     case AnchorCoords:          return String(anchor.coords());
1564     case AnchorHref:            return String(anchor.href());
1565     case AnchorHrefLang:        return String(anchor.hreflang());
1566     case AnchorHash:            return String('#'+KURL(anchor.href().string()).ref());
1567     case AnchorHost:            return String(KURL(anchor.href().string()).host());
1568     case AnchorHostname: {
1569       KURL url(anchor.href().string());
1570       kdDebug(6070) << "anchor::hostname uses:" <<url.url()<<endl;
1571       if (url.port()==0)
1572         return String(url.host());
1573       else
1574         return String(url.host() + ":" + QString::number(url.port()));
1575     }
1576     case AnchorPathName:        return String(KURL(anchor.href().string()).path());
1577     case AnchorPort:            return String(QString::number(KURL(anchor.href().string()).port()));
1578     case AnchorProtocol:        return String(KURL(anchor.href().string()).protocol()+":");
1579     case AnchorSearch:          return String(KURL(anchor.href().string()).query());
1580     case AnchorName:            return String(anchor.name());
1581     case AnchorRel:             return String(anchor.rel());
1582     case AnchorRev:             return String(anchor.rev());
1583     case AnchorShape:           return String(anchor.shape());
1584     case AnchorTabIndex:        return Number(anchor.tabIndex());
1585     case AnchorTarget:          return String(anchor.target());
1586     case AnchorType:            return String(anchor.type());
1587     case AnchorText: {
1588         DOM::DocumentImpl* docimpl = node.handle()->getDocument();
1589         if (docimpl) {
1590           docimpl->updateLayoutIgnorePendingStylesheets();
1591         }
1592       }
1593       return String(anchor.innerText());
1594     }
1595   }
1596   break;
1597   case ID_IMG: {
1598     DOM::HTMLImageElement image = element;
1599     switch (token) {
1600     case ImageName:            return String(image.name());
1601     case ImageAlign:           return String(image.align());
1602     case ImageAlt:             return String(image.alt());
1603     case ImageBorder:          return Number(image.border());
1604     case ImageHeight:          return Number(static_cast<DOM::HTMLImageElementImpl *>(image.handle())->height(true));
1605     case ImageHspace:          return Number(image.hspace());
1606     case ImageIsMap:           return Boolean(image.isMap());
1607     case ImageLongDesc:        return String(image.longDesc());
1608     case ImageSrc:             return String(image.src());
1609     case ImageUseMap:          return String(image.useMap());
1610     case ImageVspace:          return Number(image.vspace());
1611     case ImageWidth:           return Number(static_cast<DOM::HTMLImageElementImpl *>(image.handle())->width(true));
1612     case ImageX:               return Number(image.x());
1613     case ImageY:               return Number(image.y());
1614     }
1615   }
1616   break;
1617   case ID_OBJECT: {
1618     DOM::HTMLObjectElement object = element;
1619     switch (token) {
1620     case ObjectForm:            return getDOMNode(exec,object.form()); // type HTMLFormElement
1621     case ObjectCode:            return String(object.code());
1622     case ObjectAlign:           return String(object.align());
1623     case ObjectArchive:         return String(object.archive());
1624     case ObjectBorder:          return String(object.border());
1625     case ObjectCodeBase:        return String(object.codeBase());
1626     case ObjectCodeType:        return String(object.codeType());
1627     case ObjectContentDocument: return checkNodeSecurity(exec,object.contentDocument()) ? 
1628                                        getDOMNode(exec, object.contentDocument()) : Undefined();
1629     case ObjectData:            return String(object.data());
1630     case ObjectDeclare:         return Boolean(object.declare());
1631     case ObjectHeight:          return String(object.height());
1632     case ObjectHspace:          return String(object.hspace());
1633     case ObjectName:            return String(object.name());
1634     case ObjectStandby:         return String(object.standby());
1635     case ObjectTabIndex:        return Number(object.tabIndex());
1636     case ObjectType:            return String(object.type());
1637     case ObjectUseMap:          return String(object.useMap());
1638     case ObjectVspace:          return String(object.vspace());
1639     case ObjectWidth:           return String(object.width());
1640     }
1641   }
1642   break;
1643   case ID_PARAM: {
1644     DOM::HTMLParamElement param = element;
1645     switch (token) {
1646     case ParamName:            return String(param.name());
1647     case ParamType:            return String(param.type());
1648     case ParamValue:           return String(param.value());
1649     case ParamValueType:       return String(param.valueType());
1650     }
1651   }
1652   break;
1653   case ID_APPLET: {
1654     DOM::HTMLAppletElement applet = element;
1655     switch (token) {
1656     case AppletAlign:           return String(applet.align());
1657     case AppletAlt:             return String(applet.alt());
1658     case AppletArchive:         return String(applet.archive());
1659     case AppletCode:            return String(applet.code());
1660     case AppletCodeBase:        return String(applet.codeBase());
1661     case AppletHeight:          return String(applet.height());
1662     case AppletHspace:          return String(applet.hspace());
1663     case AppletName:            return String(applet.name());
1664     case AppletObject:          return String(applet.object());
1665     case AppletVspace:          return String(applet.vspace());
1666     case AppletWidth:           return String(applet.width());
1667     }
1668   }
1669   break;
1670   case ID_MAP: {
1671     DOM::HTMLMapElement map = element;
1672     switch (token) {
1673     case MapAreas:           return getHTMLCollection(exec, map.areas()); // type HTMLCollection
1674     case MapName:            return String(map.name());
1675     }
1676   }
1677   break;
1678   case ID_AREA: {
1679     DOM::HTMLAreaElement area = element;
1680     switch (token) {
1681     case AreaAccessKey:       return String(area.accessKey());
1682     case AreaAlt:             return String(area.alt());
1683     case AreaCoords:          return String(area.coords());
1684     case AreaHref:            return String(area.href());
1685     case AreaHash:            return String('#'+KURL(area.href().string()).ref());
1686     case AreaHost:            return String(KURL(area.href().string()).host());
1687     case AreaHostName: {
1688       KURL url(area.href().string());
1689       kdDebug(6070) << "link::hostname uses:" <<url.url()<<endl;
1690       if (url.port()==0)
1691         return String(url.host());
1692       else
1693         return String(url.host() + ":" + QString::number(url.port()));
1694     }
1695     case AreaPathName:        return String(KURL(area.href().string()).path());
1696     case AreaPort:            return String(QString::number(KURL(area.href().string()).port()));
1697     case AreaProtocol:        return String(KURL(area.href().string()).protocol()+":");
1698     case AreaSearch:          return String(KURL(area.href().string()).query());
1699     case AreaNoHref:          return Boolean(area.noHref());
1700     case AreaShape:           return String(area.shape());
1701     case AreaTabIndex:        return Number(area.tabIndex());
1702     case AreaTarget:          return String(area.target());
1703     }
1704   }
1705   break;
1706   case ID_SCRIPT: {
1707     DOM::HTMLScriptElement script = element;
1708     switch (token) {
1709     case ScriptText:            return String(script.text());
1710     case ScriptHtmlFor:         return String(script.htmlFor());
1711     case ScriptEvent:           return String(script.event());
1712     case ScriptCharset:         return String(script.charset());
1713     case ScriptDefer:           return Boolean(script.defer());
1714     case ScriptSrc:             return String(script.src());
1715     case ScriptType:            return String(script.type());
1716     }
1717   }
1718   break;
1719   case ID_TABLE: {
1720     DOM::HTMLTableElement table = element;
1721     switch (token) {
1722     case TableCaption:         return getDOMNode(exec,table.caption()); // type HTMLTableCaptionElement
1723     case TableTHead:           return getDOMNode(exec,table.tHead()); // type HTMLTableSectionElement
1724     case TableTFoot:           return getDOMNode(exec,table.tFoot()); // type HTMLTableSectionElement
1725     case TableRows:            return getHTMLCollection(exec,table.rows()); // type HTMLCollection
1726     case TableTBodies:         return getHTMLCollection(exec,table.tBodies()); // type HTMLCollection
1727     case TableAlign:           return String(table.align());
1728     case TableBgColor:         return String(table.bgColor());
1729     case TableBorder:          return String(table.border());
1730     case TableCellPadding:     return String(table.cellPadding());
1731     case TableCellSpacing:     return String(table.cellSpacing());
1732     case TableFrame:           return String(table.frame());
1733     case TableRules:           return String(table.rules());
1734     case TableSummary:         return String(table.summary());
1735     case TableWidth:           return String(table.width());
1736     }
1737   }
1738   break;
1739   case ID_CAPTION: {
1740     DOM::HTMLTableCaptionElement tableCaption;
1741     switch (token) {
1742     case TableCaptionAlign:       return String(tableCaption.align());
1743     }
1744   }
1745   break;
1746   case ID_COL: {
1747     DOM::HTMLTableColElement tableCol = element;
1748     switch (token) {
1749     case TableColAlign:           return String(tableCol.align());
1750     case TableColCh:              return String(tableCol.ch());
1751     case TableColChOff:           return String(tableCol.chOff());
1752     case TableColSpan:            return Number(tableCol.span());
1753     case TableColVAlign:          return String(tableCol.vAlign());
1754     case TableColWidth:           return String(tableCol.width());
1755     }
1756   }
1757   break;
1758   case ID_THEAD:
1759   case ID_TBODY:
1760   case ID_TFOOT: {
1761     DOM::HTMLTableSectionElement tableSection = element;
1762     switch (token) {
1763     case TableSectionAlign:           return String(tableSection.align());
1764     case TableSectionCh:              return String(tableSection.ch());
1765     case TableSectionChOff:           return String(tableSection.chOff());
1766     case TableSectionVAlign:          return String(tableSection.vAlign());
1767     case TableSectionRows:            return getHTMLCollection(exec,tableSection.rows()); // type HTMLCollection
1768     }
1769   }
1770   break;
1771   case ID_TR: {
1772    DOM::HTMLTableRowElement tableRow = element;
1773    switch (token) {
1774    case TableRowRowIndex:        return Number(tableRow.rowIndex());
1775    case TableRowSectionRowIndex: return Number(tableRow.sectionRowIndex());
1776    case TableRowCells:           return getHTMLCollection(exec,tableRow.cells()); // type HTMLCollection
1777    case TableRowAlign:           return String(tableRow.align());
1778    case TableRowBgColor:         return String(tableRow.bgColor());
1779    case TableRowCh:              return String(tableRow.ch());
1780    case TableRowChOff:           return String(tableRow.chOff());
1781    case TableRowVAlign:          return String(tableRow.vAlign());
1782    }
1783   }
1784   break;
1785   case ID_TH:
1786   case ID_TD: {
1787     DOM::HTMLTableCellElement tableCell = element;
1788     switch (token) {
1789     case TableCellCellIndex:       return Number(tableCell.cellIndex());
1790     case TableCellAbbr:            return String(tableCell.abbr());
1791     case TableCellAlign:           return String(tableCell.align());
1792     case TableCellAxis:            return String(tableCell.axis());
1793     case TableCellBgColor:         return String(tableCell.bgColor());
1794     case TableCellCh:              return String(tableCell.ch());
1795     case TableCellChOff:           return String(tableCell.chOff());
1796     case TableCellColSpan:         return Number(tableCell.colSpan());
1797     case TableCellHeaders:         return String(tableCell.headers());
1798     case TableCellHeight:          return String(tableCell.height());
1799     case TableCellNoWrap:          return Boolean(tableCell.noWrap());
1800     case TableCellRowSpan:         return Number(tableCell.rowSpan());
1801     case TableCellScope:           return String(tableCell.scope());
1802     case TableCellVAlign:          return String(tableCell.vAlign());
1803     case TableCellWidth:           return String(tableCell.width());
1804     }
1805   }
1806   break;
1807   case ID_FRAMESET: {
1808     DOM::HTMLFrameSetElement frameSet = element;
1809     switch (token) {
1810     case FrameSetCols:            return String(frameSet.cols());
1811     case FrameSetRows:            return String(frameSet.rows());
1812     }
1813   }
1814   break;
1815   case ID_FRAME: {
1816     DOM::HTMLFrameElement frameElement = element;
1817     switch (token) {
1818     case FrameContentDocument: return checkNodeSecurity(exec,frameElement.contentDocument()) ? 
1819                                       getDOMNode(exec, frameElement.contentDocument()) : Undefined();
1820     case FrameContentWindow:   return checkNodeSecurity(exec,frameElement.contentDocument())
1821                                     ? Window::retrieve(static_cast<HTMLFrameElementImpl *>(frameElement.handle())->contentPart())
1822                                     : Undefined();
1823     case FrameFrameBorder:     return String(frameElement.frameBorder());
1824     case FrameLongDesc:        return String(frameElement.longDesc());
1825     case FrameMarginHeight:    return String(frameElement.marginHeight());
1826     case FrameMarginWidth:     return String(frameElement.marginWidth());
1827     case FrameName:            return String(frameElement.name());
1828     case FrameNoResize:        return Boolean(frameElement.noResize());
1829     case FrameScrolling:       return String(frameElement.scrolling());
1830     case FrameSrc:
1831     case FrameLocation:        return String(frameElement.src());
1832     }
1833   }
1834   break;
1835   case ID_IFRAME: {
1836     DOM::HTMLIFrameElement iFrame = element;
1837     switch (token) {
1838     case IFrameAlign:                return String(iFrame.align());
1839       // ### security check ?
1840     case IFrameDocument: // non-standard, mapped to contentDocument
1841     case IFrameContentDocument: return checkNodeSecurity(exec,iFrame.contentDocument()) ? 
1842                                   getDOMNode(exec, iFrame.contentDocument()) : Undefined();
1843     case IFrameContentWindow:   return checkNodeSecurity(exec,iFrame.contentDocument()) 
1844                                     ? Window::retrieve(static_cast<HTMLIFrameElementImpl *>(iFrame.handle())->contentPart())
1845                                     : Undefined();
1846     case IFrameFrameBorder:     return String(iFrame.frameBorder());
1847     case IFrameHeight:          return String(iFrame.height());
1848     case IFrameLongDesc:        return String(iFrame.longDesc());
1849     case IFrameMarginHeight:    return String(iFrame.marginHeight());
1850     case IFrameMarginWidth:     return String(iFrame.marginWidth());
1851     case IFrameName:            return String(iFrame.name());
1852     case IFrameScrolling:       return String(iFrame.scrolling());
1853     case IFrameSrc:             return String(iFrame.src());
1854     case IFrameWidth:           return String(iFrame.width());
1855     }
1856     break;
1857   }
1858   } // xemacs (or arnt) could be a bit smarter when it comes to indenting switch()es ;)
1859   // its not arnt to blame - its the original Stroustrup style we like :) (Dirk)
1860
1861   // generic properties
1862   switch (token) {
1863   case ElementId:
1864       // iht.com relies on this value being "" when no id is present.  Other browsers do this as well.
1865       // So we use String() instead of String() here.
1866     return String(element.id());
1867   case ElementTitle:
1868     return String(element.title());
1869   case ElementLang:
1870     return String(element.lang());
1871   case ElementDir:
1872     return String(element.dir());
1873   case ElementClassName:
1874     return String(element.className());
1875   case ElementInnerHTML:
1876     return String(element.innerHTML());
1877   case ElementInnerText:
1878     {
1879       DOM::DocumentImpl* docimpl = node.handle()->getDocument();
1880       if (docimpl) {
1881         docimpl->updateLayoutIgnorePendingStylesheets();
1882       }
1883     }
1884     return String(element.innerText());
1885   case ElementOuterHTML:
1886     return String(element.outerHTML());
1887   case ElementOuterText:
1888     return String(element.outerText());
1889   case ElementDocument:
1890     return getDOMNode(exec,element.ownerDocument());
1891   case ElementChildren:
1892     return getHTMLCollection(exec,element.children());
1893   case ElementContentEditable:
1894     return String(element.contentEditable());
1895   case ElementIsContentEditable:
1896     return Boolean(element.isContentEditable());
1897   // ### what about style? or is this used instead for DOM2 stylesheets?
1898   }
1899   kdWarning() << "HTMLElement::getValueProperty unhandled token " << token << endl;
1900   return Undefined();
1901 }
1902
1903 bool KJS::HTMLElement::hasProperty(ExecState *exec, const Identifier &propertyName) const
1904 {
1905 #ifdef KJS_VERBOSE
1906   //kdDebug(6070) << "HTMLElement::hasProperty " << propertyName.qstring() << endl;
1907 #endif
1908   DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
1909   // First look at dynamic properties - keep this in sync with tryGet
1910   switch (element.elementId()) {
1911     case ID_FORM: {
1912       DOM::HTMLFormElement form = element;
1913       // Check if we're retrieving an element (by index or by name)
1914       bool ok;
1915       uint u = propertyName.toULong(&ok);
1916       if (ok && !(form.elements().item(u).isNull()))
1917         return true;
1918       DOM::Node testnode = form.elements().namedItem(propertyName.string());
1919       if (!testnode.isNull())
1920         return true;
1921     }
1922     case ID_SELECT: {
1923       DOM::HTMLSelectElement select = element;
1924       bool ok;
1925       uint u = propertyName.toULong(&ok);
1926       if (ok && !(select.options().item(u).isNull()))
1927         return true;
1928     }
1929     default:
1930       break;
1931   }
1932
1933   return DOMElement::hasProperty(exec, propertyName);
1934 }
1935
1936 UString KJS::HTMLElement::toString(ExecState *exec) const
1937 {
1938   if (node.elementId() == ID_A)
1939     return UString(static_cast<const DOM::HTMLAnchorElement&>(node).href());
1940   else
1941     return DOMElement::toString(exec);
1942 }
1943
1944 static void getForm(DOM::HTMLFormElement* form, const DOM::HTMLElement& element)
1945 {
1946     switch (element.elementId()) {
1947         case ID_ISINDEX: {
1948             DOM::HTMLIsIndexElement isindex = element;
1949             *form = isindex.form();
1950             break;
1951         }
1952         case ID_SELECT: {
1953             DOM::HTMLSelectElement select = element;
1954             *form = select.form();
1955             break;
1956         }
1957         case ID_OPTION: {
1958             DOM::HTMLOptionElement option = element;
1959             *form = option.form();
1960             break;
1961         }
1962         case ID_INPUT: {
1963             DOM::HTMLInputElement input = element;
1964             *form = input.form();
1965             break;
1966         }
1967         case ID_TEXTAREA: {
1968             DOM::HTMLTextAreaElement textarea = element;
1969             *form = textarea.form();
1970             break;
1971         }
1972         case ID_LABEL: {
1973             DOM::HTMLLabelElement label = element;
1974             *form = label.form();
1975             break;
1976         }
1977         case ID_FIELDSET: {
1978             DOM::HTMLFieldSetElement fieldset = element;
1979             *form = fieldset.form();
1980             break;
1981         }
1982         case ID_LEGEND: {
1983             DOM::HTMLLegendElement legend = element;
1984             *form = legend.form();
1985             break;
1986         }
1987         case ID_OBJECT: {
1988             DOM::HTMLObjectElement object = element;
1989             *form = object.form();
1990             break;
1991         }
1992         default:
1993             break;
1994     }
1995 }
1996
1997 void KJS::HTMLElement::pushEventHandlerScope(ExecState *exec, ScopeChain &scope) const
1998 {
1999   DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
2000
2001   // The document is put on first, fall back to searching it only after the element and form.
2002   scope.push(static_cast<ObjectImp *>(getDOMNode(exec, element.ownerDocument()).imp()));
2003
2004   // The form is next, searched before the document, but after the element itself.
2005   DOM::HTMLFormElement formElt;
2006   
2007   // First try to obtain the form from the element itself.  We do this to deal with
2008   // the malformed case where <form>s aren't in our parent chain (e.g., when they were inside 
2009   // <table> or <tbody>.
2010   getForm(&formElt, element);
2011   if (!formElt.isNull())
2012     scope.push(static_cast<ObjectImp *>(getDOMNode(exec, formElt).imp()));
2013   else {
2014     DOM::Node form = element.parentNode();
2015     while (!form.isNull() && form.elementId() != ID_FORM)
2016         form = form.parentNode();
2017     
2018     if (!form.isNull())
2019         scope.push(static_cast<ObjectImp *>(getDOMNode(exec, form).imp()));
2020   }
2021   
2022   // The element is on top, searched first.
2023   scope.push(static_cast<ObjectImp *>(getDOMNode(exec, element).imp()));
2024 }
2025
2026 HTMLElementFunction::HTMLElementFunction(ExecState *exec, int i, int len)
2027   : DOMFunction(), id(i)
2028 {
2029   Value protect(this);
2030   put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum);
2031 }
2032
2033 Value KJS::HTMLElementFunction::tryCall(ExecState *exec, Object &thisObj, const List &args)
2034 {
2035   if (!thisObj.inherits(&KJS::HTMLElement::info)) {
2036     Object err = Error::create(exec,TypeError);
2037     exec->setException(err);
2038     return err;
2039   }
2040   kdDebug() << "KJS::HTMLElementFunction::tryCall " << endl;
2041   DOM::HTMLElement element = static_cast<KJS::HTMLElement *>(thisObj.imp())->toElement();
2042
2043   switch (element.elementId()) {
2044     case ID_FORM: {
2045       DOM::HTMLFormElement form = element;
2046       if (id == KJS::HTMLElement::FormSubmit) {
2047         form.submit();
2048         return Undefined();
2049       }
2050       else if (id == KJS::HTMLElement::FormReset) {
2051         form.reset();
2052         return Undefined();
2053       }
2054     }
2055     break;
2056     case ID_SELECT: {
2057       DOM::HTMLSelectElement select = element;
2058       if (id == KJS::HTMLElement::SelectAdd) {
2059         select.add(KJS::toNode(args[0]),KJS::toNode(args[1]));
2060         return Undefined();
2061       }
2062       else if (id == KJS::HTMLElement::SelectRemove) {
2063         select.remove(int(args[0].toNumber(exec)));
2064         return Undefined();
2065       }
2066       else if (id == KJS::HTMLElement::SelectBlur) {
2067         select.blur();
2068         return Undefined();
2069       }
2070       else if (id == KJS::HTMLElement::SelectFocus) {
2071         select.focus();
2072         return Undefined();
2073       }
2074     }
2075     break;
2076     case ID_INPUT: {
2077       DOM::HTMLInputElement input = element;
2078       if (id == KJS::HTMLElement::InputBlur) {
2079         input.blur();
2080         return Undefined();
2081       }
2082       else if (id == KJS::HTMLElement::InputFocus) {
2083         input.focus();
2084         return Undefined();
2085       }
2086       else if (id == KJS::HTMLElement::InputSelect) {
2087         input.select();
2088         return Undefined();
2089       }
2090       else if (id == KJS::HTMLElement::InputClick) {
2091         input.click();
2092         return Undefined();
2093       }
2094     }
2095     break;
2096     case ID_TEXTAREA: {
2097       DOM::HTMLTextAreaElement textarea = element;
2098       if (id == KJS::HTMLElement::TextAreaBlur) {
2099         textarea.blur();
2100         return Undefined();
2101       }
2102       else if (id == KJS::HTMLElement::TextAreaFocus) {
2103         textarea.focus();
2104         return Undefined();
2105       }
2106       else if (id == KJS::HTMLElement::TextAreaSelect) {
2107         textarea.select();
2108         return Undefined();
2109       }
2110     }
2111     break;
2112     case ID_A: {
2113       DOM::HTMLAnchorElement anchor = element;
2114       if (id == KJS::HTMLElement::AnchorBlur) {
2115         anchor.blur();
2116         return Undefined();
2117       }
2118       else if (id == KJS::HTMLElement::AnchorFocus) {
2119         anchor.focus();
2120         return Undefined();
2121       } 
2122       else if (id == KJS::HTMLElement::AnchorToString) {
2123         return String(thisObj.toString(exec));
2124       }
2125     }
2126     break;
2127     case ID_TABLE: {
2128       DOM::HTMLTableElement table = element;
2129       if (id == KJS::HTMLElement::TableCreateTHead)
2130         return getDOMNode(exec,table.createTHead());
2131       else if (id == KJS::HTMLElement::TableDeleteTHead) {
2132         table.deleteTHead();
2133         return Undefined();
2134       }
2135       else if (id == KJS::HTMLElement::TableCreateTFoot)
2136         return getDOMNode(exec,table.createTFoot());
2137       else if (id == KJS::HTMLElement::TableDeleteTFoot) {
2138         table.deleteTFoot();
2139         return Undefined();
2140       }
2141       else if (id == KJS::HTMLElement::TableCreateCaption)
2142         return getDOMNode(exec,table.createCaption());
2143       else if (id == KJS::HTMLElement::TableDeleteCaption) {
2144         table.deleteCaption();
2145         return Undefined();
2146       }
2147       else if (id == KJS::HTMLElement::TableInsertRow)
2148         return getDOMNode(exec,table.insertRow(args[0].toInt32(exec)));
2149       else if (id == KJS::HTMLElement::TableDeleteRow) {
2150         table.deleteRow(args[0].toInt32(exec));
2151         return Undefined();
2152       }
2153     }
2154     break;
2155     case ID_THEAD:
2156     case ID_TBODY:
2157     case ID_TFOOT: {
2158       DOM::HTMLTableSectionElement tableSection = element;
2159       if (id == KJS::HTMLElement::TableSectionInsertRow)
2160         return getDOMNode(exec,tableSection.insertRow(args[0].toInt32(exec)));
2161       else if (id == KJS::HTMLElement::TableSectionDeleteRow) {
2162         tableSection.deleteRow(args[0].toInt32(exec));
2163         return Undefined();
2164       }
2165     }
2166     break;
2167     case ID_TR: {
2168       DOM::HTMLTableRowElement tableRow = element;
2169       if (id == KJS::HTMLElement::TableRowInsertCell)
2170         return getDOMNode(exec,tableRow.insertCell(args[0].toInt32(exec)));
2171       else if (id == KJS::HTMLElement::TableRowDeleteCell) {
2172         tableRow.deleteCell(args[0].toInt32(exec));
2173         return Undefined();
2174       }
2175     }
2176     case ID_MARQUEE: {
2177         if (id == KJS::HTMLElement::MarqueeStart && element.handle()->renderer() && 
2178             element.handle()->renderer()->layer() &&
2179             element.handle()->renderer()->layer()->marquee()) {
2180             element.handle()->renderer()->layer()->marquee()->start();
2181             return Undefined();
2182         }
2183         else if (id == KJS::HTMLElement::MarqueeStop && element.handle()->renderer() && 
2184                  element.handle()->renderer()->layer() &&
2185                  element.handle()->renderer()->layer()->marquee()) {
2186             element.handle()->renderer()->layer()->marquee()->stop();
2187             return Undefined();
2188         }
2189         break;
2190     }
2191     case ID_CANVAS: {
2192         if (id == KJS::HTMLElement::GetContext) {
2193             if (args.size() == 0 || (args.size() == 1 && args[0].toString(exec).qstring().lower() == "2d")) {
2194                 return Object(new Context2D(element));
2195             }
2196             return Undefined();
2197         }
2198     }
2199     
2200     break;
2201   }
2202
2203   return Undefined();
2204 }
2205
2206 void KJS::HTMLElement::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
2207 {
2208 #ifdef KJS_VERBOSE
2209   DOM::DOMString str = value.isA(NullType) ? DOM::DOMString() : value.toString(exec).string();
2210 #endif
2211   DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
2212 #ifdef KJS_VERBOSE
2213   kdDebug(6070) << "KJS::HTMLElement::tryPut " << propertyName.qstring()
2214                 << " thisTag=" << element.tagName().string()
2215                 << " str=" << str.string() << endl;
2216 #endif
2217   // First look at dynamic properties
2218   switch (element.elementId()) {
2219     case ID_SELECT: {
2220       DOM::HTMLSelectElement select = element;
2221       bool ok;
2222       /*uint u =*/ propertyName.toULong(&ok);
2223       if (ok) {
2224         Object coll = Object::dynamicCast( getSelectHTMLCollection(exec, select.options(), select) );
2225         if ( !coll.isNull() )
2226           coll.put(exec,propertyName,value);
2227         return;
2228       }
2229     }
2230     break;
2231   default:
2232       break;
2233   }
2234
2235   const HashTable* table = classInfo()->propHashTable; // get the right hashtable
2236   const HashEntry* entry = Lookup::findEntry(table, propertyName);
2237   if (entry) {
2238     if (entry->attr & Function) // function: put as override property
2239     {
2240       ObjectImp::put(exec, propertyName, value, attr);
2241       return;
2242     }
2243     else if ((entry->attr & ReadOnly) == 0) // let DOMObjectLookupPut print the warning if not
2244     {
2245       putValue(exec, entry->value, value, attr);
2246       return;
2247     }
2248   }
2249   DOMObjectLookupPut<KJS::HTMLElement, DOMElement>(exec, propertyName, value, attr, &KJS::HTMLElementTable, this);
2250 }
2251
2252 void KJS::HTMLElement::putValue(ExecState *exec, int token, const Value& value, int)
2253 {
2254   DOM::DOMString str = value.isA(NullType) ? DOM::DOMString() : value.toString(exec).string();
2255   DOMNode *kjsNode = new DOMNode(exec, KJS::toNode(value));
2256   // Need to create a Value wrapper to avoid leaking the KJS::DOMNode
2257   Value nodeValue(kjsNode);
2258   DOM::Node n = kjsNode->toNode();
2259   DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
2260 #ifdef KJS_VERBOSE
2261   kdDebug(6070) << "KJS::HTMLElement::putValue "
2262                 << " thisTag=" << element.tagName().string()
2263                 << " token=" << token << endl;
2264 #endif
2265
2266   switch (element.elementId()) {
2267   case ID_HTML: {
2268       DOM::HTMLHtmlElement html = element;
2269       switch (token) {
2270       case HtmlVersion:         { html.setVersion(str); return; }
2271       }
2272   }
2273   break;
2274   case ID_HEAD: {
2275     DOM::HTMLHeadElement head = element;
2276     switch (token) {
2277     case HeadProfile:         { head.setProfile(str); return; }
2278     }
2279   }
2280   break;
2281   case ID_LINK: {
2282     DOM::HTMLLinkElement link = element;
2283     switch (token) {
2284       case LinkDisabled:        { link.setDisabled(value.toBoolean(exec)); return; }
2285       case LinkCharset:         { link.setCharset(str); return; }
2286       case LinkHref:            { link.setHref(str); return; }
2287       case LinkHrefLang:        { link.setHreflang(str); return; }
2288       case LinkMedia:           { link.setMedia(str); return; }
2289       case LinkRel:             { link.setRel(str); return; }
2290       case LinkRev:             { link.setRev(str); return; }
2291       case LinkTarget:          { link.setTarget(str); return; }
2292       case LinkType:            { link.setType(str); return; }
2293       }
2294     }
2295     break;
2296     case ID_TITLE: {
2297       DOM::HTMLTitleElement title = element;
2298       switch (token) {
2299       case TitleText:                 { title.setText(str); return; }
2300       }
2301     }
2302     break;
2303     case ID_META: {
2304       DOM::HTMLMetaElement meta = element;
2305       switch (token) {
2306       case MetaContent:         { meta.setContent(str); return; }
2307       case MetaHttpEquiv:       { meta.setHttpEquiv(str); return; }
2308       case MetaName:            { meta.setName(str); return; }
2309       case MetaScheme:          { meta.setScheme(str); return; }
2310       }
2311     }
2312     break;
2313     case ID_BASE: {
2314       DOM::HTMLBaseElement base = element;
2315       switch (token) {
2316       case BaseHref:            { base.setHref(str); return; }
2317       case BaseTarget:          { base.setTarget(str); return; }
2318       }
2319     }
2320     break;
2321     case ID_ISINDEX: {
2322       DOM::HTMLIsIndexElement isindex = element;
2323       switch (token) {
2324       // read-only: form
2325       case IsIndexPrompt:               { isindex.setPrompt(str); return; }
2326       }
2327     }
2328     break;
2329     case ID_STYLE: {
2330       DOM::HTMLStyleElement style = element;
2331       switch (token) {
2332       case StyleDisabled:        { style.setDisabled(value.toBoolean(exec)); return; }
2333       case StyleMedia:           { style.setMedia(str); return; }
2334       case StyleType:            { style.setType(str); return; }
2335       }
2336     }
2337     break;
2338     case ID_BODY: {
2339       DOM::HTMLBodyElement body = element;
2340       switch (token) {
2341       case BodyALink:           { body.setALink(str); return; }
2342       case BodyBackground:      { body.setBackground(str); return; }
2343       case BodyBgColor:         { body.setBgColor(str); return; }
2344       case BodyLink:            { body.setLink(str); return; }
2345       case BodyText:            { body.setText(str); return; }
2346       case BodyVLink:           { body.setVLink(str); return; }
2347       case BodyScrollLeft:
2348       case BodyScrollTop: {
2349           QScrollView* sview = body.ownerDocument().view();
2350           if (sview) {
2351               // Update the document's layout before we compute these attributes.
2352               DOM::DocumentImpl* docimpl = body.handle()->getDocument();
2353               if (docimpl)
2354                   docimpl->updateLayoutIgnorePendingStylesheets();
2355               if (token == BodyScrollLeft)
2356                   sview->setContentsPos(value.toInt32(exec), sview->contentsY());
2357               else
2358                   sview->setContentsPos(sview->contentsX(), value.toInt32(exec));
2359           }
2360           return;
2361         }
2362       }
2363     }
2364     break;
2365     case ID_FORM: {
2366       DOM::HTMLFormElement form = element;
2367       switch (token) {
2368       // read-only: elements
2369       // read-only: length
2370       case FormName:            { form.setName(str); return; }
2371       case FormAcceptCharset:   { form.setAcceptCharset(str); return; }
2372       case FormAction:          { form.setAction(str.string()); return; }
2373       case FormEncType:         { form.setEnctype(str); return; }
2374       case FormMethod:          { form.setMethod(str); return; }
2375       case FormTarget:          { form.setTarget(str); return; }
2376       }
2377     }
2378     break;
2379     case ID_SELECT: {
2380       DOM::HTMLSelectElement select = element;
2381       switch (token) {
2382       // read-only: type
2383       case SelectSelectedIndex:   { select.setSelectedIndex(value.toInt32(exec)); return; }
2384       case SelectValue:           { select.setValue(str); return; }
2385       case SelectLength:          { // read-only according to the NS spec, but webpages need it writeable
2386                                          Object coll = Object::dynamicCast( getSelectHTMLCollection(exec, select.options(), select) );
2387                                          if ( !coll.isNull() )
2388                                            coll.put(exec,lengthPropertyName,value);
2389                                          return;
2390                                        }
2391       // read-only: form
2392       // read-only: options
2393       case SelectDisabled:        { select.setDisabled(value.toBoolean(exec)); return; }
2394       case SelectMultiple:        { select.setMultiple(value.toBoolean(exec)); return; }
2395       case SelectName:            { select.setName(str); return; }
2396       case SelectSize:            { select.setSize(value.toInt32(exec)); return; }
2397       case SelectTabIndex:        { select.setTabIndex(value.toInt32(exec)); return; }
2398       }
2399     }
2400     break;
2401     case ID_OPTGROUP: {
2402       DOM::HTMLOptGroupElement optgroup = element;
2403       switch (token) {
2404       case OptGroupDisabled:        { optgroup.setDisabled(value.toBoolean(exec)); return; }
2405       case OptGroupLabel:           { optgroup.setLabel(str); return; }
2406       }
2407     }
2408     break;
2409     case ID_OPTION: {
2410       DOM::HTMLOptionElement option = element;
2411       switch (token) {
2412       // read-only: form
2413       case OptionDefaultSelected: { option.setDefaultSelected(value.toBoolean(exec)); return; }
2414       // read-only: text  <--- According to the DOM, but JavaScript and JScript both allow changes.
2415       // So, we'll do it here and not add it to our DOM headers.
2416       case OptionText:            { DOM::NodeList nl(option.childNodes());
2417                                     for (unsigned int i = 0; i < nl.length(); i++) {
2418                                         if (nl.item(i).nodeType() == DOM::Node::TEXT_NODE) {
2419                                             static_cast<DOM::Text>(nl.item(i)).setData(str);
2420                                             return;
2421                                         }
2422                                   }
2423                                   // No child text node found, creating one
2424                                   DOM::Text t = option.ownerDocument().createTextNode(str);
2425                                   try { option.appendChild(t); }
2426                                   catch(DOM::DOMException& e) {
2427                                     // #### exec->setException ?
2428                                   }
2429
2430                                   return;
2431       }
2432       // read-only: index
2433       case OptionDisabled:        { option.setDisabled(value.toBoolean(exec)); return; }
2434       case OptionLabel:           { option.setLabel(str); return; }
2435       case OptionSelected:        { option.setSelected(value.toBoolean(exec)); return; }
2436       case OptionValue:           { option.setValue(str); return; }
2437       }
2438     }
2439     break;
2440     case ID_INPUT: {
2441       DOM::HTMLInputElement input = element;
2442       switch (token) {
2443       case InputDefaultValue:    { input.setDefaultValue(str); return; }
2444       case InputDefaultChecked:  { input.setDefaultChecked(value.toBoolean(exec)); return; }
2445       // read-only: form
2446       case InputAccept:          { input.setAccept(str); return; }
2447       case InputAccessKey:       { input.setAccessKey(str); return; }
2448       case InputAlign:           { input.setAlign(str); return; }
2449       case InputAlt:             { input.setAlt(str); return; }
2450       case InputChecked:         { input.setChecked(value.toBoolean(exec)); return; }
2451       case InputDisabled:        { input.setDisabled(value.toBoolean(exec)); return; }
2452       case InputMaxLength:       { input.setMaxLength(value.toInt32(exec)); return; }
2453       case InputName:            { input.setName(str); return; }
2454       case InputReadOnly:        { input.setReadOnly(value.toBoolean(exec)); return; }
2455       case InputSize:            { input.setSize(str); return; }
2456       case InputSrc:             { input.setSrc(str); return; }
2457       case InputTabIndex:        { input.setTabIndex(value.toInt32(exec)); return; }
2458       case InputType:            { input.setType(str); return; }
2459       case InputUseMap:          { input.setUseMap(str); return; }
2460       case InputValue:           { input.setValue(str); return; }
2461       }
2462     }
2463     break;
2464     case ID_TEXTAREA: {
2465       DOM::HTMLTextAreaElement textarea = element;
2466       switch (token) {
2467       case TextAreaDefaultValue:    { textarea.setDefaultValue(str); return; }
2468       // read-only: form
2469       case TextAreaAccessKey:       { textarea.setAccessKey(str); return; }
2470       case TextAreaCols:            { textarea.setCols(value.toInt32(exec)); return; }
2471       case TextAreaDisabled:        { textarea.setDisabled(value.toBoolean(exec)); return; }
2472       case TextAreaName:            { textarea.setName(str); return; }
2473       case TextAreaReadOnly:        { textarea.setReadOnly(value.toBoolean(exec)); return; }
2474       case TextAreaRows:            { textarea.setRows(value.toInt32(exec)); return; }
2475       case TextAreaTabIndex:        { textarea.setTabIndex(value.toInt32(exec)); return; }
2476       // read-only: type
2477       case TextAreaValue:           { textarea.setValue(str); return; }
2478       }
2479     }
2480     break;
2481     case ID_BUTTON: {
2482       DOM::HTMLButtonElement button = element;
2483       switch (token) {
2484       // read-only: form
2485       case ButtonAccessKey:       { button.setAccessKey(str); return; }
2486       case ButtonDisabled:        { button.setDisabled(value.toBoolean(exec)); return; }
2487       case ButtonName:            { button.setName(str); return; }
2488       case ButtonTabIndex:        { button.setTabIndex(value.toInt32(exec)); return; }
2489       // read-only: type
2490       case ButtonValue:           { button.setValue(str); return; }
2491       }
2492     }
2493     break;
2494     case ID_LABEL: {
2495       DOM::HTMLLabelElement label = element;
2496       switch (token) {
2497       // read-only: form
2498       case LabelAccessKey:       { label.setAccessKey(str); return; }
2499       case LabelHtmlFor:         { label.setHtmlFor(str); return; }
2500       }
2501     }
2502     break;
2503 //    case ID_FIELDSET: {
2504 //      DOM::HTMLFieldSetElement fieldSet = element;
2505 //      // read-only: form
2506 //    }
2507 //    break;
2508     case ID_LEGEND: {
2509       DOM::HTMLLegendElement legend = element;
2510       switch (token) {
2511       // read-only: form
2512       case LegendAccessKey:       { legend.setAccessKey(str); return; }
2513       case LegendAlign:           { legend.setAlign(str); return; }
2514       }
2515     }
2516     break;
2517     case ID_UL: {
2518       DOM::HTMLUListElement uList = element;
2519       switch (token) {
2520       case UListCompact:         { uList.setCompact(value.toBoolean(exec)); return; }
2521       case UListType:            { uList.setType(str); return; }
2522       }
2523     }
2524     break;
2525     case ID_OL: {
2526       DOM::HTMLOListElement oList = element;
2527       switch (token) {
2528       case OListCompact:         { oList.setCompact(value.toBoolean(exec)); return; }
2529       case OListStart:           { oList.setStart(value.toInt32(exec)); return; }
2530       case OListType:            { oList.setType(str); return; }
2531       }
2532     }
2533     break;
2534     case ID_DL: {
2535       DOM::HTMLDListElement dList = element;
2536       switch (token) {
2537       case DListCompact:         { dList.setCompact(value.toBoolean(exec)); return; }
2538       }
2539     }
2540     break;
2541     case ID_DIR: {
2542       DOM::HTMLDirectoryElement directory = element;
2543       switch (token) {
2544       case DirectoryCompact:     { directory.setCompact(value.toBoolean(exec)); return; }
2545       }
2546     }
2547     break;
2548     case ID_MENU: {
2549       DOM::HTMLMenuElement menu = element;
2550       switch (token) {
2551       case MenuCompact:         { menu.setCompact(value.toBoolean(exec)); return; }
2552       }
2553     }
2554     break;
2555     case ID_LI: {
2556       DOM::HTMLLIElement li = element;
2557       switch (token) {
2558       case LIType:            { li.setType(str); return; }
2559       case LIValue:           { li.setValue(value.toInt32(exec)); return; }
2560       }
2561     }
2562     break;
2563     case ID_DIV: {
2564       DOM::HTMLDivElement div = element;
2565       switch (token) {
2566       case DivAlign:           { div.setAlign(str); return; }
2567       }
2568     }
2569     break;
2570     case ID_P: {
2571       DOM::HTMLParagraphElement paragraph = element;
2572       switch (token) {
2573       case ParagraphAlign:     { paragraph.setAlign(str); return; }
2574       }
2575     }
2576     break;
2577     case ID_H1:
2578     case ID_H2:
2579     case ID_H3:
2580     case ID_H4:
2581     case ID_H5:
2582     case ID_H6: {
2583       DOM::HTMLHeadingElement heading = element;
2584       switch (token) {
2585       case HeadingAlign:         { heading.setAlign(str); return; }
2586       }
2587     }
2588     break;
2589     case ID_BLOCKQUOTE: {
2590       DOM::HTMLBlockquoteElement blockquote = element;
2591       switch (token) {
2592       case BlockQuoteCite:       { blockquote.setCite(str); return; }
2593       }
2594     }
2595     break;
2596     case ID_Q: {
2597       DOM::HTMLQuoteElement quote = element;
2598       switch (token) {
2599       case QuoteCite:            { quote.setCite(str); return; }
2600       }
2601     }
2602     break;
2603     case ID_PRE: {
2604       DOM::HTMLPreElement pre = element;
2605       switch (token) {
2606       case PreWidth:           { pre.setWidth(value.toInt32(exec)); return; }
2607       }
2608     }
2609     break;
2610     case ID_BR: {
2611       DOM::HTMLBRElement br = element;
2612       switch (token) {
2613       case BRClear:           { br.setClear(str); return; }
2614       }
2615     }
2616     break;
2617     case ID_BASEFONT: {
2618       DOM::HTMLBaseFontElement baseFont = element;
2619       switch (token) {
2620       case BaseFontColor:           { baseFont.setColor(str); return; }
2621       case BaseFontFace:            { baseFont.setFace(str); return; }
2622       case BaseFontSize:            { baseFont.setSize(str); return; }
2623       }
2624     }
2625     break;
2626     case ID_FONT: {
2627       DOM::HTMLFontElement font = element;
2628       switch (token) {
2629       case FontColor:           { font.setColor(str); return; }
2630       case FontFace:            { font.setFace(str); return; }
2631       case FontSize:            { font.setSize(str); return; }
2632       }
2633     }
2634     break;
2635     case ID_HR: {
2636       DOM::HTMLHRElement hr = element;
2637       switch (token) {
2638       case HRAlign:           { hr.setAlign(str); return; }
2639       case HRNoShade:         { hr.setNoShade(value.toBoolean(exec)); return; }
2640       case HRSize:            { hr.setSize(str); return; }
2641       case HRWidth:           { hr.setWidth(str); return; }
2642       }
2643     }
2644     break;
2645     case ID_INS:
2646     case ID_DEL: {
2647       DOM::HTMLModElement mod = element;
2648       switch (token) {
2649       case ModCite:            { mod.setCite(str); return; }
2650       case ModDateTime:        { mod.setDateTime(str); return; }
2651       }
2652     }
2653     break;
2654     case ID_A: {
2655       DOM::HTMLAnchorElement anchor = element;
2656       switch (token) {
2657       case AnchorAccessKey:       { anchor.setAccessKey(str); return; }
2658       case AnchorCharset:         { anchor.setCharset(str); return; }
2659       case AnchorCoords:          { anchor.setCoords(str); return; }
2660       case AnchorHref:            { anchor.setHref(str); return; }
2661       case AnchorHrefLang:        { anchor.setHreflang(str); return; }
2662       case AnchorName:            { anchor.setName(str); return; }
2663       case AnchorRel:             { anchor.setRel(str); return; }
2664       case AnchorRev:             { anchor.setRev(str); return; }
2665       case AnchorShape:           { anchor.setShape(str); return; }
2666       case AnchorTabIndex:        { anchor.setTabIndex(value.toInt32(exec)); return; }
2667       case AnchorTarget:          { anchor.setTarget(str); return; }
2668       case AnchorType:            { anchor.setType(str); return; }
2669       }
2670     }
2671     break;
2672     case ID_IMG: {
2673       DOM::HTMLImageElement image = element;
2674       switch (token) {
2675       case ImageName:            { image.setName(str); return; }
2676       case ImageAlign:           { image.setAlign(str); return; }
2677       case ImageAlt:             { image.setAlt(str); return; }
2678       case ImageBorder:          { image.setBorder(value.toInt32(exec)); return; }
2679       case ImageHeight:          { image.setHeight(value.toInt32(exec)); return; }
2680       case ImageHspace:          { image.setHspace(value.toInt32(exec)); return; }
2681       case ImageIsMap:           { image.setIsMap(value.toBoolean(exec)); return; }
2682       case ImageLongDesc:        { image.setLongDesc(str); return; }
2683       case ImageSrc:             { image.setSrc(str); return; }
2684       case ImageUseMap:          { image.setUseMap(str); return; }
2685       case ImageVspace:          { image.setVspace(value.toInt32(exec)); return; }
2686       case ImageWidth:           { image.setWidth(value.toInt32(exec)); return; }
2687       }
2688     }
2689     break;
2690     case ID_OBJECT: {
2691       DOM::HTMLObjectElement object = element;
2692       switch (token) {
2693       // read-only: form
2694       case ObjectCode:                 { object.setCode(str); return; }
2695       case ObjectAlign:           { object.setAlign(str); return; }
2696       case ObjectArchive:         { object.setArchive(str); return; }
2697       case ObjectBorder:          { object.setBorder(str); return; }
2698       case ObjectCodeBase:        { object.setCodeBase(str); return; }
2699       case ObjectCodeType:        { object.setCodeType(str); return; }
2700       // read-only: ObjectContentDocument
2701       case ObjectData:            { object.setData(str); return; }
2702       case ObjectDeclare:         { object.setDeclare(value.toBoolean(exec)); return; }
2703       case ObjectHeight:          { object.setHeight(str); return; }
2704       case ObjectHspace:          { object.setHspace(str); return; }
2705       case ObjectName:            { object.setName(str); return; }
2706       case ObjectStandby:         { object.setStandby(str); return; }
2707       case ObjectTabIndex:        { object.setTabIndex(value.toInt32(exec)); return; }
2708       case ObjectType:            { object.setType(str); return; }
2709       case ObjectUseMap:          { object.setUseMap(str); return; }
2710       case ObjectVspace:          { object.setVspace(str); return; }
2711       case ObjectWidth:           { object.setWidth(str); return; }
2712       }
2713     }
2714     break;
2715     case ID_PARAM: {
2716       DOM::HTMLParamElement param = element;
2717       switch (token) {
2718       case ParamName:            { param.setName(str); return; }
2719       case ParamType:            { param.setType(str); return; }
2720       case ParamValue:           { param.setValue(str); return; }
2721       case ParamValueType:       { param.setValueType(str); return; }
2722       }
2723     }
2724     break;
2725     case ID_APPLET: {
2726       DOM::HTMLAppletElement applet = element;
2727       switch (token) {
2728       case AppletAlign:           { applet.setAlign(str); return; }
2729       case AppletAlt:             { applet.setAlt(str); return; }
2730       case AppletArchive:         { applet.setArchive(str); return; }
2731       case AppletCode:            { applet.setCode(str); return; }
2732       case AppletCodeBase:        { applet.setCodeBase(str); return; }
2733       case AppletHeight:          { applet.setHeight(str); return; }
2734       case AppletHspace:          { applet.setHspace(str); return; }
2735       case AppletName:            { applet.setName(str); return; }
2736       case AppletObject:          { applet.setObject(str); return; }
2737       case AppletVspace:          { applet.setVspace(str); return; }
2738       case AppletWidth:           { applet.setWidth(str); return; }
2739       }
2740     }
2741     break;
2742     case ID_MAP: {
2743       DOM::HTMLMapElement map = element;
2744       switch (token) {
2745       // read-only: areas
2746       case MapName:                 { map.setName(str); return; }
2747      }
2748     }
2749     break;
2750     case ID_AREA: {
2751       DOM::HTMLAreaElement area = element;
2752       switch (token) {
2753       case AreaAccessKey:       { area.setAccessKey(str); return; }
2754       case AreaAlt:             { area.setAlt(str); return; }
2755       case AreaCoords:          { area.setCoords(str); return; }
2756       case AreaHref:            { area.setHref(str); return; }
2757       case AreaNoHref:          { area.setNoHref(value.toBoolean(exec)); return; }
2758       case AreaShape:           { area.setShape(str); return; }
2759       case AreaTabIndex:        { area.setTabIndex(value.toInt32(exec)); return; }
2760       case AreaTarget:          { area.setTarget(str); return; }
2761       }
2762     }
2763     break;
2764     case ID_SCRIPT: {
2765       DOM::HTMLScriptElement script = element;
2766       switch (token) {
2767       case ScriptText:            { script.setText(str); return; }
2768       case ScriptHtmlFor:         { script.setHtmlFor(str); return; }
2769       case ScriptEvent:           { script.setEvent(str); return; }
2770       case ScriptCharset:         { script.setCharset(str); return; }
2771       case ScriptDefer:           { script.setDefer(value.toBoolean(exec)); return; }
2772       case ScriptSrc:             { script.setSrc(str); return; }
2773       case ScriptType:            { script.setType(str); return; }
2774       }
2775     }
2776     break;
2777     case ID_TABLE: {
2778       DOM::HTMLTableElement table = element;
2779       switch (token) {
2780       case TableCaption:         { table.setCaption(n); return; } // type HTMLTableCaptionElement
2781       case TableTHead:           { table.setTHead(n); return; } // type HTMLTableSectionElement
2782       case TableTFoot:           { table.setTFoot(n); return; } // type HTMLTableSectionElement
2783       // read-only: rows
2784       // read-only: tbodies
2785       case TableAlign:           { table.setAlign(str); return; }
2786       case TableBgColor:         { table.setBgColor(str); return; }
2787       case TableBorder:          { table.setBorder(str); return; }
2788       case TableCellPadding:     { table.setCellPadding(str); return; }
2789       case TableCellSpacing:     { table.setCellSpacing(str); return; }
2790       case TableFrame:           { table.setFrame(str); return; }
2791       case TableRules:           { table.setRules(str); return; }
2792       case TableSummary:         { table.setSummary(str); return; }
2793       case TableWidth:           { table.setWidth(str); return; }
2794       }
2795     }
2796     break;
2797     case ID_CAPTION: {
2798       DOM::HTMLTableCaptionElement tableCaption;
2799       switch (token) {
2800       case TableAlign:           { tableCaption.setAlign(str); return; }
2801       }
2802     }
2803     break;
2804     case ID_COL: {
2805       DOM::HTMLTableColElement tableCol = element;
2806       switch (token) {
2807       case TableColAlign:           { tableCol.setAlign(str); return; }
2808       case TableColCh:              { tableCol.setCh(str); return; }
2809       case TableColChOff:           { tableCol.setChOff(str); return; }
2810       case TableColSpan:            { tableCol.setSpan(value.toInt32(exec)); return; }
2811       case TableColVAlign:          { tableCol.setVAlign(str); return; }
2812       case TableColWidth:           { tableCol.setWidth(str); return; }
2813       }
2814     }
2815     break;
2816     case ID_THEAD:
2817     case ID_TBODY:
2818     case ID_TFOOT: {
2819       DOM::HTMLTableSectionElement tableSection = element;
2820       switch (token) {
2821       case TableSectionAlign:           { tableSection.setAlign(str); return; }
2822       case TableSectionCh:              { tableSection.setCh(str); return; }
2823       case TableSectionChOff:           { tableSection.setChOff(str); return; }
2824       case TableSectionVAlign:          { tableSection.setVAlign(str); return; }
2825       // read-only: rows
2826       }
2827     }
2828     break;
2829     case ID_TR: {
2830       DOM::HTMLTableRowElement tableRow = element;
2831       switch (token) {
2832       // read-only: rowIndex
2833       // read-only: sectionRowIndex
2834       // read-only: cells
2835       case TableRowAlign:           { tableRow.setAlign(str); return; }
2836       case TableRowBgColor:         { tableRow.setBgColor(str); return; }
2837       case TableRowCh:              { tableRow.setCh(str); return; }
2838       case TableRowChOff:           { tableRow.setChOff(str); return; }
2839       case TableRowVAlign:          { tableRow.setVAlign(str); return; }
2840       }
2841     }
2842     break;
2843     case ID_TH:
2844     case ID_TD: {
2845       DOM::HTMLTableCellElement tableCell = element;
2846       switch (token) {
2847       // read-only: cellIndex
2848       case TableCellAbbr:            { tableCell.setAbbr(str); return; }
2849       case TableCellAlign:           { tableCell.setAlign(str); return; }
2850       case TableCellAxis:            { tableCell.setAxis(str); return; }
2851       case TableCellBgColor:         { tableCell.setBgColor(str); return; }
2852       case TableCellCh:              { tableCell.setCh(str); return; }
2853       case TableCellChOff:           { tableCell.setChOff(str); return; }
2854       case TableCellColSpan:         { tableCell.setColSpan(value.toInt32(exec)); return; }
2855       case TableCellHeaders:         { tableCell.setHeaders(str); return; }
2856       case TableCellHeight:          { tableCell.setHeight(str); return; }
2857       case TableCellNoWrap:          { tableCell.setNoWrap(value.toBoolean(exec)); return; }
2858       case TableCellRowSpan:         { tableCell.setRowSpan(value.toInt32(exec)); return; }
2859       case TableCellScope:           { tableCell.setScope(str); return; }
2860       case TableCellVAlign:          { tableCell.setVAlign(str); return; }
2861       case TableCellWidth:           { tableCell.setWidth(str); return; }
2862       }
2863     }
2864     break;
2865     case ID_FRAMESET: {
2866       DOM::HTMLFrameSetElement frameSet = element;
2867       switch (token) {
2868       case FrameSetCols:            { frameSet.setCols(str); return; }
2869       case FrameSetRows:            { frameSet.setRows(str); return; }
2870       }
2871     }
2872     break;
2873     case ID_FRAME: {
2874       DOM::HTMLFrameElement frameElement = element;
2875       switch (token) {
2876        // read-only: FrameContentDocument:
2877       case FrameFrameBorder:     { frameElement.setFrameBorder(str); return; }
2878       case FrameLongDesc:        { frameElement.setLongDesc(str); return; }
2879       case FrameMarginHeight:    { frameElement.setMarginHeight(str); return; }
2880       case FrameMarginWidth:     { frameElement.setMarginWidth(str); return; }
2881       case FrameName:            { frameElement.setName(str); return; }
2882       case FrameNoResize:        { frameElement.setNoResize(value.toBoolean(exec)); return; }
2883       case FrameScrolling:       { frameElement.setScrolling(str); return; }
2884       case FrameSrc:             { frameElement.setSrc(str); return; }
2885       case FrameLocation:        {
2886                                    static_cast<DOM::HTMLFrameElementImpl *>(frameElement.handle())->setLocation(str);
2887                                    return;
2888                                  }
2889       }
2890     }
2891     break;
2892     case ID_IFRAME: {
2893       DOM::HTMLIFrameElement iFrame = element;
2894       switch (token) {
2895       case IFrameAlign:           { iFrame.setAlign(str); return; }
2896       // read-only: IFrameContentDocument
2897       case IFrameFrameBorder:     { iFrame.setFrameBorder(str); return; }
2898       case IFrameHeight:          { iFrame.setHeight(str); return; }
2899       case IFrameLongDesc:        { iFrame.setLongDesc(str); return; }
2900       case IFrameMarginHeight:    { iFrame.setMarginHeight(str); return; }
2901       case IFrameMarginWidth:     { iFrame.setMarginWidth(str); return; }
2902       case IFrameName:            { iFrame.setName(str); return; }
2903       case IFrameScrolling:       { iFrame.setScrolling(str); return; }
2904       case IFrameSrc:             { iFrame.setSrc(str); return; }
2905       case IFrameWidth:           { iFrame.setWidth(str); return; }
2906       }
2907       break;
2908     }
2909   }
2910
2911   // generic properties
2912   switch (token) {
2913   case ElementId:
2914     element.setId(str);
2915     return;
2916   case ElementTitle:
2917     element.setTitle(str);
2918     return;
2919   case ElementLang:
2920     element.setLang(str);
2921     return;
2922   case ElementDir:
2923     element.setDir(str);
2924     return;
2925   case ElementClassName:
2926     element.setClassName(str);
2927     return;
2928   case ElementInnerHTML:
2929     element.setInnerHTML(str);
2930     return;
2931   case ElementInnerText:
2932     element.setInnerText(str);
2933     return;
2934   case ElementOuterHTML:
2935     element.setOuterHTML(str);
2936     return;
2937   case ElementOuterText:
2938     element.setOuterText(str);
2939     return;
2940   case ElementContentEditable:
2941     element.setContentEditable(str);
2942     return;
2943   default:
2944     kdWarning() << "KJS::HTMLElement::putValue unhandled token " << token << " thisTag=" << element.tagName().string() << " str=" << str.string() << endl;
2945   }
2946 }
2947
2948 // -------------------------------------------------------------------------
2949 /* Source for HTMLCollectionProtoTable. Use "make hashtables" to regenerate.
2950 @begin HTMLCollectionProtoTable 3
2951   item          HTMLCollection::Item            DontDelete|Function 1
2952   namedItem     HTMLCollection::NamedItem       DontDelete|Function 1
2953   tags          HTMLCollection::Tags            DontDelete|Function 1
2954 @end
2955 */
2956 DEFINE_PROTOTYPE("HTMLCollection", HTMLCollectionProto)
2957 IMPLEMENT_PROTOFUNC(HTMLCollectionProtoFunc)
2958 IMPLEMENT_PROTOTYPE(HTMLCollectionProto,HTMLCollectionProtoFunc)
2959
2960 const ClassInfo HTMLCollection::info = { "HTMLCollection", 0, 0, 0 };
2961
2962 HTMLCollection::HTMLCollection(ExecState *exec, const DOM::HTMLCollection &c)
2963   : DOMObject(HTMLCollectionProto::self(exec)), collection(c) {}
2964
2965 HTMLCollection::~HTMLCollection()
2966 {
2967   ScriptInterpreter::forgetDOMObject(collection.handle());
2968 }
2969
2970 // We have to implement hasProperty since we don't use a hashtable for 'selectedIndex' and 'length'
2971 // ## this breaks "for (..in..)" though.
2972 bool KJS::HTMLCollection::hasProperty(ExecState *exec, const Identifier &p) const
2973 {
2974   if (p == "selectedIndex" || p == lengthPropertyName)
2975     return true;
2976   return DOMObject::hasProperty(exec, p);
2977 }
2978
2979 Value KJS::HTMLCollection::tryGet(ExecState *exec, const Identifier &propertyName) const
2980 {
2981 #ifdef KJS_VERBOSE
2982   kdDebug() << "KJS::HTMLCollection::tryGet " << propertyName.ascii() << endl;
2983 #endif
2984   if (propertyName == lengthPropertyName)
2985     return Number(collection.length());
2986   else if (propertyName == "selectedIndex" &&
2987            collection.item(0).elementId() == ID_OPTION) {
2988     // NON-STANDARD options.selectedIndex
2989     DOM::Node node = collection.item(0).parentNode();
2990     while(!node.isNull()) {
2991       if(node.elementId() == ID_SELECT) {
2992         DOM::HTMLSelectElement sel = static_cast<DOM::HTMLSelectElement>(node);
2993         return Number(sel.selectedIndex());
2994       }
2995       node = node.parentNode();
2996     }
2997     return Undefined();
2998   } else {
2999     // Look in the prototype (for functions) before assuming it's an item's name
3000     Object proto = Object::dynamicCast(prototype());
3001     if (!proto.isNull() && proto.hasProperty(exec,propertyName))
3002       return proto.get(exec,propertyName);
3003
3004     // name or index ?
3005     bool ok;
3006     unsigned int u = propertyName.toULong(&ok);
3007     if (ok) {
3008       DOM::Node node = collection.item(u);
3009
3010 #if APPLE_CHANGES
3011         if (!node.isNull() && (node.handle()->id() == ID_APPLET || node.handle()->id() == ID_EMBED)) {
3012             Value v = getRuntimeObject(exec,node);
3013             if (!v.isNull())
3014                 return v;
3015         }
3016 #endif
3017       return getDOMNode(exec,node);
3018     }
3019     else
3020       return getNamedItems(exec,propertyName);
3021   }
3022 }
3023
3024 // HTMLCollections are strange objects, they support both get and call,
3025 // so that document.forms.item(0) and document.forms(0) both work.
3026 Value KJS::HTMLCollection::call(ExecState *exec, Object &thisObj, const List &args)
3027 {
3028   // This code duplication is necessary, HTMLCollection isn't a DOMFunction
3029   Value val;
3030   try {
3031     val = tryCall(exec, thisObj, args);
3032   }
3033   // pity there's no way to distinguish between these in JS code
3034   catch (...) {
3035     Object err = Error::create(exec, GeneralError, "Exception from HTMLCollection");
3036     exec->setException(err);
3037   }
3038   return val;
3039 }
3040
3041 Value KJS::HTMLCollection::tryCall(ExecState *exec, Object &, const List &args)
3042 {
3043   // Do not use thisObj here. It can be the HTMLDocument, in the document.forms(i) case.
3044   /*if( thisObj.imp() != this )
3045   {
3046     kdWarning() << "thisObj.imp() != this in HTMLCollection::tryCall" << endl;
3047     KJS::printInfo(exec,"KJS::HTMLCollection::tryCall thisObj",thisObj,-1);
3048     KJS::printInfo(exec,"KJS::HTMLCollection::tryCall this",Value(this),-1);
3049   }*/
3050   // Also, do we need the TypeError test here ?
3051
3052   if (args.size() == 1) {
3053     // support for document.all(<index>) etc.
3054     bool ok;
3055     UString s = args[0].toString(exec);
3056     unsigned int u = s.toULong(&ok);
3057     if (ok) {
3058       DOM::Element element = collection.item(u);
3059       return getDOMNode(exec,element);
3060     }
3061     // support for document.images('<name>') etc.
3062     return getNamedItems(exec, Identifier(s));
3063   }
3064   else if (args.size() >= 1) // the second arg, if set, is the index of the item we want
3065   {
3066     bool ok;
3067     UString s = args[0].toString(exec);
3068     unsigned int u = args[1].toString(exec).toULong(&ok);
3069     if (ok)
3070     {
3071       DOM::DOMString pstr = s.string();
3072       DOM::Node node = collection.namedItem(pstr);
3073       while (!node.isNull()) {
3074         if (!u)
3075           return getDOMNode(exec,node);
3076         node = collection.nextNamedItem(pstr);
3077         --u;
3078       }
3079     }
3080   }
3081   return Undefined();
3082 }
3083
3084 Value KJS::HTMLCollection::getNamedItems(ExecState *exec, const Identifier &propertyName) const
3085 {
3086 #ifdef KJS_VERBOSE
3087   kdDebug(6070) << "KJS::HTMLCollection::getNamedItems " << propertyName.ascii() << endl;
3088 #endif
3089   DOM::DOMString pstr = propertyName.string();
3090
3091   QValueList<DOM::Node> namedItems = collection.namedItems(pstr);
3092
3093   if (namedItems.isEmpty()) {
3094 #ifdef KJS_VERBOSE
3095     kdDebug(6070) << "not found" << endl;
3096 #endif
3097     return Undefined();
3098   }
3099
3100   if (namedItems.count() == 1) {
3101     DOM::Node node = namedItems[0];
3102 #if APPLE_CHANGES
3103     if (!node.isNull() && (node.handle()->id() == ID_APPLET || node.handle()->id() == ID_EMBED)) {
3104       Value v = getRuntimeObject(exec, node);
3105       if (!v.isNull())
3106         return v;
3107     }
3108 #endif
3109
3110     return getDOMNode(exec,node);
3111   }
3112   
3113   return Value(new DOMNamedNodesCollection(exec,namedItems));
3114 }
3115
3116 Value KJS::HTMLCollectionProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
3117 {
3118   if (!thisObj.inherits(&KJS::HTMLCollection::info)) {
3119     Object err = Error::create(exec,TypeError);
3120     exec->setException(err);
3121     return err;
3122   }
3123   DOM::HTMLCollection coll = static_cast<KJS::HTMLCollection *>(thisObj.imp())->toCollection();
3124
3125   switch (id) {
3126   case KJS::HTMLCollection::Item:
3127     return getDOMNode(exec,coll.item(args[0].toUInt32(exec)));
3128   case KJS::HTMLCollection::Tags:
3129   {
3130     DOM::DOMString tagName = args[0].toString(exec).string();
3131     DOM::NodeList list;
3132     // getElementsByTagName exists in Document and in Element, pick up the right one
3133     if ( coll.base().nodeType() == DOM::Node::DOCUMENT_NODE )
3134     {
3135       DOM::Document doc = coll.base();
3136       list = doc.getElementsByTagName(tagName);
3137 #ifdef KJS_VERBOSE
3138       kdDebug() << "KJS::HTMLCollectionProtoFunc::tryCall document.tags(" << tagName.string() << ") -> " << list.length() << " items in node list" << endl;
3139 #endif
3140     } else
3141     {
3142       DOM::Element e = coll.base();
3143       list = e.getElementsByTagName(tagName);
3144 #ifdef KJS_VERBOSE
3145       kdDebug() << "KJS::HTMLCollectionProtoFunc::tryCall element.tags(" << tagName.string() << ") -> " << list.length() << " items in node list" << endl;
3146 #endif
3147     }
3148     return getDOMNodeList(exec, list);
3149   }
3150   case KJS::HTMLCollection::NamedItem:
3151     return static_cast<HTMLCollection *>(thisObj.imp())->getNamedItems(exec, Identifier(args[0].toString(exec)));
3152   default:
3153     return Undefined();
3154   }
3155 }
3156
3157 Value KJS::HTMLSelectCollection::tryGet(ExecState *exec, const Identifier &p) const
3158 {
3159   if (p == "selectedIndex")
3160     return Number(element.selectedIndex());
3161
3162   return  HTMLCollection::tryGet(exec, p);
3163 }
3164
3165 void KJS::HTMLSelectCollection::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int)
3166 {
3167 #ifdef KJS_VERBOSE
3168   kdDebug(6070) << "KJS::HTMLSelectCollection::tryPut " << propertyName.qstring() << endl;
3169 #endif
3170   if ( propertyName == "selectedIndex" ) {
3171     element.setSelectedIndex( value.toInt32( exec ) );
3172     return;
3173   }
3174   // resize ?
3175   else if (propertyName == lengthPropertyName) {
3176     unsigned newLen;
3177     bool converted = value.toUInt32(newLen);
3178
3179     if (!converted) {
3180       return;
3181     }
3182
3183     long diff = element.length() - newLen;
3184
3185     if (diff < 0) { // add dummy elements
3186       do {
3187         element.add(element.ownerDocument().createElement("OPTION"), DOM::HTMLElement());
3188       } while (++diff);
3189     }
3190     else // remove elements
3191       while (diff-- > 0)
3192         element.remove(newLen);
3193
3194     return;
3195   }
3196   // an index ?
3197   bool ok;
3198   unsigned int u = propertyName.toULong(&ok);
3199   if (!ok)
3200     return;
3201
3202   if (value.isA(NullType) || value.isA(UndefinedType)) {
3203     // null and undefined delete. others, too ?
3204     element.remove(u);
3205     return;
3206   }
3207
3208   // is v an option element ?
3209   DOM::Node node = KJS::toNode(value);
3210   if (node.isNull() || node.elementId() != ID_OPTION)
3211     return;
3212
3213   DOM::HTMLOptionElement option = static_cast<DOM::HTMLOptionElement>(node);
3214   long diff = long(u) - element.length();
3215   DOM::HTMLElement before;
3216   // out of array bounds ? first insert empty dummies
3217   if (diff > 0) {
3218     while (diff--) {
3219       element.add(element.ownerDocument().createElement("OPTION"), before);
3220     }
3221     // replace an existing entry ?
3222   } else if (diff < 0) {
3223     before = element.options().item(u+1);
3224     element.remove(u);
3225   }
3226   // finally add the new element
3227   element.add(option, before);
3228 }
3229
3230 ////////////////////// Option Object ////////////////////////
3231
3232 OptionConstructorImp::OptionConstructorImp(ExecState *exec, const DOM::Document &d)
3233     : ObjectImp(), doc(d)
3234 {
3235   // ## isn't there some redundancy between ObjectImp::_proto and the "prototype" property ?
3236   //put(exec,"prototype", ...,DontEnum|DontDelete|ReadOnly);
3237
3238   // no. of arguments for constructor
3239   // ## is 4 correct ? 0 to 4, it seems to be
3240   put(exec,lengthPropertyName, Number(4), ReadOnly|DontDelete|DontEnum);
3241 }
3242
3243 bool OptionConstructorImp::implementsConstruct() const
3244 {
3245   return true;
3246 }
3247
3248 Object OptionConstructorImp::construct(ExecState *exec, const List &args)
3249 {
3250   DOM::Element el = doc.createElement("OPTION");
3251   DOM::HTMLOptionElement opt = static_cast<DOM::HTMLOptionElement>(el);
3252   int sz = args.size();
3253   DOM::Text t = doc.createTextNode("");
3254   try { opt.appendChild(t); }
3255   catch(DOM::DOMException& e) {
3256     // #### exec->setException ?
3257   }
3258   if (sz > 0)
3259     t.setData(args[0].toString(exec).string()); // set the text
3260   if (sz > 1)
3261     opt.setValue(args[1].toString(exec).string());
3262   if (sz > 2)
3263     opt.setDefaultSelected(args[2].toBoolean(exec));
3264   if (sz > 3)
3265     opt.setSelected(args[3].toBoolean(exec));
3266
3267   return Object::dynamicCast(getDOMNode(exec,opt));
3268 }
3269
3270 ////////////////////// Image Object ////////////////////////
3271
3272 ImageConstructorImp::ImageConstructorImp(ExecState *, const DOM::Document &d)
3273     : ObjectImp(), doc(d)
3274 {
3275 }
3276
3277 bool ImageConstructorImp::implementsConstruct() const
3278 {
3279   return true;
3280 }
3281
3282 Object ImageConstructorImp::construct(ExecState *, const List &)
3283 {
3284   /* TODO: fetch optional height & width from arguments */
3285
3286   Object result(new Image(doc));
3287   /* TODO: do we need a prototype ? */
3288
3289   return result;
3290 }
3291
3292 const ClassInfo KJS::Image::info = { "Image", 0, &ImageTable, 0 };
3293
3294 /* Source for ImageTable. Use "make hashtables" to regenerate.
3295 @begin ImageTable 6
3296   src           Image::Src              DontDelete
3297   complete      Image::Complete         DontDelete|ReadOnly
3298   onload        Image::OnLoad           DontDelete
3299   width         Image::Width            DontDelete|ReadOnly
3300   height        Image::Height           DontDelete|ReadOnly
3301 @end
3302 */
3303
3304 Value Image::tryGet(ExecState *exec, const Identifier &propertyName) const
3305 {
3306   return DOMObjectLookupGetValue<Image,DOMObject>(exec, propertyName, &ImageTable, this);
3307 }
3308
3309 Value Image::getValueProperty(ExecState *, int token) const
3310 {
3311   switch (token) {
3312   case Src:
3313     return String(src);
3314   case Complete:
3315     return Boolean(!img || img->status() >= khtml::CachedObject::Persistent);
3316   case OnLoad:
3317     if (onLoadListener && onLoadListener->listenerObjImp()) {
3318       return onLoadListener->listenerObj();
3319     } else {
3320       return Null();
3321     }
3322   case Width: {
3323     int width = 0;
3324     if (img) {
3325       QSize size = img->pixmap_size();
3326       if (size.isValid())
3327         width = size.width();
3328     }
3329     return Number(width);
3330   }
3331   case Height: {
3332     int height = 0;
3333     if (img) {
3334       QSize size = img->pixmap_size();
3335       if (size.isValid())
3336         height = size.height();
3337     }
3338     return Number(height);
3339   }
3340   default: