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