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