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