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