1 /*
2 * This file is part of the KDE libraries
3 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
4 * Copyright (C) 2001-2003 David Faure (faure@kde.org)
5 * Copyright (C) 2004 Apple Computer, Inc.
6 * Copyright (C) 2005 Maksim Orlovich (maksim@kde.org)
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include "kjs_html.h"
24 #include "kjs_html.lut.h"
25
26 #include <misc/loader.h>
27 #include <html/html_blockimpl.h>
28 #include <html/html_headimpl.h>
29 #include <html/html_imageimpl.h>
30 #include <html/html_inlineimpl.h>
31 #include <html/html_listimpl.h>
32 #include <html/html_tableimpl.h>
33 #include <html/html_objectimpl.h>
34 #include <html/html_canvasimpl.h>
35 #include <dom/dom_exception.h>
36
37 #include <html/html_baseimpl.h>
38 #include <html/html_documentimpl.h>
39 #include <html/html_formimpl.h>
40 #include <html/html_miscimpl.h>
41 #include <xml/dom2_eventsimpl.h>
42
43 #include <kparts/browserextension.h>
44
45 #include <khtml_part.h>
46 #include <khtmlview.h>
47
48 #include "kjs_css.h"
49 #include "kjs_events.h"
50 #include "kjs_window.h"
51 #include "kjs_context2d.h"
52 #include <kjs/PropertyNameArray.h>
53
54 #include <rendering/render_object.h>
55 #include <rendering/render_canvas.h>
56 #include <rendering/render_frames.h>
57 #include <rendering/render_layer.h>
58
59 #include <kmessagebox.h>
60 #include <kstringhandler.h>
61 #include <klocalizedstring.h>
62
63 #include "khtml_debug.h"
64 #include <QList>
65 #include <QHash>
66
67 #undef FOCUS_EVENT // for win32, MinGW
68
69 using namespace DOM;
70
71 namespace KJS
72 {
73
74 KJS_DEFINE_PROTOTYPE(HTMLDocumentProto)
KJS_IMPLEMENT_PROTOFUNC(HTMLDocFunction)75 KJS_IMPLEMENT_PROTOFUNC(HTMLDocFunction)
76 KJS_IMPLEMENT_PROTOTYPE("HTMLDocument", HTMLDocumentProto, HTMLDocFunction, DOMDocumentProto)
77
78 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLDocumentPseudoCtor, "HTMLDocument", HTMLDocumentProto)
79
80 /* Source for HTMLDocumentProtoTable.
81 @begin HTMLDocumentProtoTable 11
82 clear HTMLDocument::Clear DontDelete|Function 0
83 open HTMLDocument::Open DontDelete|Function 0
84 close HTMLDocument::Close DontDelete|Function 0
85 write HTMLDocument::Write DontDelete|Function 1
86 writeln HTMLDocument::WriteLn DontDelete|Function 1
87 getElementsByName HTMLDocument::GetElementsByName DontDelete|Function 1
88 getSelection HTMLDocument::GetSelection DontDelete|Function 1
89 captureEvents HTMLDocument::CaptureEvents DontDelete|Function 0
90 releaseEvents HTMLDocument::ReleaseEvents DontDelete|Function 0
91 @end
92 */
93
94 JSValue *KJS::HTMLDocFunction::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
95 {
96 KJS_CHECK_THIS(HTMLDocument, thisObj);
97
98 DOM::HTMLDocumentImpl &doc = *static_cast<KJS::HTMLDocument *>(thisObj)->impl();
99
100 switch (id) {
101 case HTMLDocument::Clear: // even IE doesn't support that one...
102 //doc.clear(); // TODO
103 return jsUndefined();
104 case HTMLDocument::Open:
105 if (args.size() >= 3) { // IE extension for document.open: it means window.open if it has 3 args or more
106 KHTMLPart *part = doc.part();
107 if (part) {
108 Window *win = Window::retrieveWindow(part);
109 if (win) {
110 win->openWindow(exec, args);
111 }
112 }
113 }
114
115 doc.open();
116 return jsUndefined();
117 case HTMLDocument::Close:
118 // see khtmltests/ecma/tokenizer-script-recursion.html
119 doc.close();
120 return jsUndefined();
121 case HTMLDocument::Write:
122 case HTMLDocument::WriteLn: {
123 // DOM only specifies single string argument, but NS & IE allow multiple
124 // or no arguments
125 UString str = "";
126 for (int i = 0; i < args.size(); i++) {
127 str += args[i]->toString(exec);
128 }
129 if (id == HTMLDocument::WriteLn) {
130 str += "\n";
131 }
132 #ifdef KJS_VERBOSE
133 qCDebug(KHTML_LOG) << "document.write: " << str.qstring();
134 #endif
135 doc.write(str.qstring());
136 return jsUndefined();
137 }
138 case HTMLDocument::GetElementsByName:
139 return getDOMNodeList(exec, doc.getElementsByName(args[0]->toString(exec).domString()));
140 case HTMLDocument::GetSelection: {
141 // NS4 and Mozilla specific. IE uses document.selection.createRange()
142 // http://docs.sun.com/source/816-6408-10/document.htm#1195981
143 KHTMLPart *part = doc.part();
144 if (part) {
145 return jsString(part->selectedText());
146 } else {
147 return jsUndefined();
148 }
149 }
150 case HTMLDocument::CaptureEvents:
151 case HTMLDocument::ReleaseEvents:
152 // Do nothing for now. These are NS-specific legacy calls.
153 break;
154 }
155
156 return jsUndefined();
157 }
158
159 const ClassInfo KJS::HTMLDocument::info =
160 { "HTMLDocument", &DOMDocument::info, &HTMLDocumentTable, nullptr };
161 /* Source for HTMLDocumentTable.
162 @begin HTMLDocumentTable 31
163 referrer HTMLDocument::Referrer DontDelete|ReadOnly
164 domain HTMLDocument::Domain DontDelete
165 URL HTMLDocument::URL DontDelete|ReadOnly
166 body HTMLDocument::Body DontDelete
167 location HTMLDocument::Location DontDelete
168 cookie HTMLDocument::Cookie DontDelete
169 images HTMLDocument::Images DontDelete|ReadOnly
170 applets HTMLDocument::Applets DontDelete|ReadOnly
171 links HTMLDocument::Links DontDelete|ReadOnly
172 forms HTMLDocument::Forms DontDelete|ReadOnly
173 anchors HTMLDocument::Anchors DontDelete|ReadOnly
174 scripts HTMLDocument::Scripts DontDelete|ReadOnly
175 all HTMLDocument::All DontDelete|ReadOnly
176 bgColor HTMLDocument::BgColor DontDelete
177 fgColor HTMLDocument::FgColor DontDelete
178 alinkColor HTMLDocument::AlinkColor DontDelete
179 linkColor HTMLDocument::LinkColor DontDelete
180 vlinkColor HTMLDocument::VlinkColor DontDelete
181 lastModified HTMLDocument::LastModified DontDelete|ReadOnly
182 height HTMLDocument::Height DontDelete|ReadOnly
183 width HTMLDocument::Width DontDelete|ReadOnly
184 dir HTMLDocument::Dir DontDelete
185 compatMode HTMLDocument::CompatMode DontDelete|ReadOnly
186 designMode HTMLDocument::DesignMode DontDelete
187 #IE extension
188 frames HTMLDocument::Frames DontDelete|ReadOnly
189 #NS4 extension
190 layers HTMLDocument::Layers DontDelete|ReadOnly
191 # HTML5
192 activeElement HTMLDocument::ActiveElement DontDelete|ReadOnly
193 #potentially obsolete array properties
194 # plugins
195 # tags
196 #potentially obsolete properties
197 # embeds
198 # ids
199 @end
200 */
201
HTMLDocument(ExecState * exec,DOM::HTMLDocumentImpl * d)202 KJS::HTMLDocument::HTMLDocument(ExecState *exec, DOM::HTMLDocumentImpl *d)
203 : DOMDocument(HTMLDocumentProto::self(exec), d) { }
204
205 /* Should this property be checked after overrides? */
isLateProperty(unsigned token)206 static bool isLateProperty(unsigned token)
207 {
208 switch (token) {
209 case HTMLDocument::BgColor:
210 case HTMLDocument::FgColor:
211 case HTMLDocument::AlinkColor:
212 case HTMLDocument::LinkColor:
213 case HTMLDocument::VlinkColor:
214 case HTMLDocument::LastModified:
215 case HTMLDocument::Height: // NS-only, not available in IE
216 case HTMLDocument::Width: // NS-only, not available in IE
217 case HTMLDocument::Dir:
218 case HTMLDocument::Frames:
219 return true;
220 default:
221 return false;
222 }
223 }
224
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)225 bool KJS::HTMLDocument::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
226 {
227 #ifdef KJS_VERBOSE
228 qCDebug(KHTML_LOG) << "KJS::HTMLDocument::getOwnPropertySlot " << propertyName.qstring();
229 #endif
230
231 DOM::DocumentImpl *docImpl = impl();
232 KHTMLPart *part = docImpl->part();
233
234 Window *win = part ? Window::retrieveWindow(part) : nullptr;
235 if (!win || !win->isSafeScript(exec)) {
236 slot.setUndefined(this);
237 return true;
238 }
239
240 DOM::DOMString propertyDOMString = propertyName.domString();
241
242 //See whether to return named items under document.
243 ElementMappingCache::ItemInfo *info = docImpl->underDocNamedCache().get(propertyDOMString);
244 if (info) {
245 //May be a false positive, but we can try to avoid doing it the hard way in
246 //simpler cases. The trickiness here is that the cache is kept under both
247 //name and id, but we sometimes ignore id for IE compat
248
249 bool matched = false;
250 if (info->nd && DOM::HTMLMappedNameCollectionImpl::matchesName(info->nd,
251 HTMLCollectionImpl::DOCUMENT_NAMED_ITEMS, propertyDOMString)) {
252 matched = true;
253 } else {
254 //Can't tell it just like that, so better go through collection and count stuff. This is the slow path...
255 DOM::HTMLMappedNameCollectionImpl coll(impl(), HTMLCollectionImpl::DOCUMENT_NAMED_ITEMS, propertyDOMString);
256 matched = coll.firstItem() != nullptr;
257 }
258
259 if (matched) {
260 slot.setCustom(this, nameGetter);
261 return true;
262 }
263 }
264
265 // Check for frames/iframes with name==propertyName
266 if (part) {
267 if (part->findFrame(propertyName.qstring())) {
268 slot.setCustom(this, frameNameGetter);
269 return true;
270 }
271 }
272
273 // Static properties
274 const HashEntry *entry = Lookup::findEntry(&HTMLDocumentTable, propertyName);
275 if (entry && !isLateProperty(entry->value)) {
276 getSlotFromEntry<HTMLDocFunction, HTMLDocument>(entry, this, slot);
277 return true;
278 }
279
280 // Look for overrides
281 JSValue **val = getDirectLocation(propertyName);
282 if (val) {
283 fillDirectLocationSlot(slot, val);
284 return true;
285 }
286
287 // The rest of static properties -- the late ones.
288 if (entry) {
289 getSlotFromEntry<HTMLDocFunction, HTMLDocument>(entry, this, slot);
290 return true;
291 }
292
293 return DOMDocument::getOwnPropertySlot(exec, propertyName, slot);
294 }
295
nameGetter(ExecState * exec,JSObject *,const Identifier & propertyName,const PropertySlot & slot)296 JSValue *HTMLDocument::nameGetter(ExecState *exec, JSObject *, const Identifier &propertyName, const PropertySlot &slot)
297 {
298 HTMLDocument *thisObj = static_cast<HTMLDocument *>(slot.slotBase());
299 DOM::DocumentImpl *docImpl = thisObj->impl();
300
301 //Return named items under document (e.g. images, applets, etc.)
302 DOMString name = propertyName.domString();
303 ElementMappingCache::ItemInfo *info = docImpl->underDocNamedCache().get(name);
304 if (info && info->nd) {
305 return getDOMNode(exec, info->nd);
306 } else {
307 //No cached mapping, do it the hard way..
308 DOM::HTMLMappedNameCollectionImpl *coll = new DOM::HTMLMappedNameCollectionImpl(docImpl,
309 HTMLCollectionImpl::DOCUMENT_NAMED_ITEMS, name);
310
311 if (info && coll->length() == 1) {
312 info->nd = static_cast<DOM::ElementImpl *>(coll->firstItem());
313 delete coll;
314 return getDOMNode(exec, info->nd);
315 }
316
317 return getHTMLCollection(exec, coll);
318 }
319
320 assert(0);
321 return jsUndefined();
322 }
323
frameNameGetter(ExecState *,JSObject *,const Identifier & name,const PropertySlot & slot)324 JSValue *HTMLDocument::frameNameGetter(ExecState *, JSObject *, const Identifier &name, const PropertySlot &slot)
325 {
326 HTMLDocument *thisObj = static_cast<HTMLDocument *>(slot.slotBase());
327 // Check for frames/iframes with name==propertyName
328 return Window::retrieve(thisObj->impl()->part()->findFrame(name.qstring()));
329 }
330
objectNameGetter(ExecState * exec,JSObject *,const Identifier & name,const PropertySlot & slot)331 JSValue *HTMLDocument::objectNameGetter(ExecState *exec, JSObject *, const Identifier &name, const PropertySlot &slot)
332 {
333 HTMLDocument *thisObj = static_cast<HTMLDocument *>(slot.slotBase());
334 DOM::HTMLCollectionImpl objectLike(thisObj->impl(), DOM::HTMLCollectionImpl::DOC_APPLETS);
335 return getDOMNode(exec, objectLike.namedItem(name.domString()));
336 }
337
layerNameGetter(ExecState * exec,JSObject *,const Identifier & name,const PropertySlot & slot)338 JSValue *HTMLDocument::layerNameGetter(ExecState *exec, JSObject *, const Identifier &name, const PropertySlot &slot)
339 {
340 HTMLDocument *thisObj = static_cast<HTMLDocument *>(slot.slotBase());
341 DOM::HTMLCollectionImpl layerLike(thisObj->impl(), DOM::HTMLCollectionImpl::DOC_LAYERS);
342 return getDOMNode(exec, layerLike.namedItem(name.domString()));
343 }
344
getValueProperty(ExecState * exec,int token)345 JSValue *HTMLDocument::getValueProperty(ExecState *exec, int token)
346 {
347 DOM::HTMLDocumentImpl &doc = *impl();
348 KHTMLView *view = doc.view();
349 KHTMLPart *part = doc.part();
350 Window *win = part ? Window::retrieveWindow(part) : nullptr;
351 DOM::HTMLElementImpl *body = doc.body();
352
353 switch (token) {
354 case Referrer:
355 return jsString(doc.referrer());
356 case Domain:
357 return jsString(doc.domain());
358 case URL:
359 return jsString(doc.URL().url());
360 case Body:
361 return getDOMNode(exec, doc.body());
362 case Location:
363 if (win) {
364 return win->location();
365 } else {
366 return jsUndefined();
367 }
368 case Cookie:
369 return jsString(doc.cookie());
370 case Images:
371 return getHTMLCollection(exec, doc.images());
372 case Applets:
373 return getHTMLCollection(exec, doc.applets());
374 case Links:
375 return getHTMLCollection(exec, doc.links());
376 case Forms:
377 return getHTMLCollection(exec, doc.forms());
378 case Layers:
379 // ### Should not be hidden when we emulate Netscape4
380 return getHTMLCollection(exec, doc.layers(), true);
381 case Anchors:
382 return getHTMLCollection(exec, doc.anchors());
383 case Scripts:
384 return getHTMLCollection(exec, doc.scripts());
385 case All:
386 if (exec->dynamicInterpreter()->compatMode() == Interpreter::IECompat) {
387 return getHTMLCollection(exec, doc.all());
388 } else { // enabled but hidden
389 return getHTMLCollection(exec, doc.all(), true);
390 }
391 case CompatMode:
392 return jsString(doc.parseMode()
393 == DocumentImpl::Compat ? "BackCompat" : "CSS1Compat");
394 case DesignMode:
395 return jsString((doc.designMode() ? "on" : "off"));
396 case ActiveElement:
397 return getDOMNode(exec, doc.activeElement());
398 case BgColor:
399 return jsString(body ? body->getAttribute(ATTR_BGCOLOR) : DOMString());
400 case FgColor:
401 return jsString(body ? body->getAttribute(ATTR_TEXT) : DOMString());
402 case AlinkColor:
403 return jsString(body ? body->getAttribute(ATTR_ALINK) : DOMString());
404 case LinkColor:
405 return jsString(body ? body->getAttribute(ATTR_LINK) : DOMString());
406 case VlinkColor:
407 return jsString(body ? body->getAttribute(ATTR_VLINK) : DOMString());
408 case LastModified:
409 return jsString(doc.lastModified());
410 case Height: // NS-only, not available in IE
411 return jsNumber(view ? view->contentsHeight() : 0);
412 case Width: // NS-only, not available in IE
413 return jsNumber(view ? view->contentsWidth() : 0);
414 case Dir:
415 return body ? jsString(body->getAttribute(ATTR_DIR)) : jsUndefined();
416 case Frames:
417 if (win) {
418 return win;
419 } else {
420 return jsUndefined();
421 }
422 }
423 assert(0);
424 return nullptr;
425 }
426
put(ExecState * exec,const Identifier & propertyName,JSValue * value,int attr)427 void KJS::HTMLDocument::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
428 {
429 #ifdef KJS_VERBOSE
430 qCDebug(KHTML_LOG) << "KJS::HTMLDocument::out " << propertyName.qstring();
431 #endif
432 KHTMLPart *part = impl()->part();
433 Window *win = part ? Window::retrieveWindow(part) : nullptr;
434 if (!win || !win->isSafeScript(exec)) {
435 return;
436 }
437
438 lookupPut<HTMLDocument, DOMDocument>(exec, propertyName, value, attr, &HTMLDocumentTable, this);
439 }
440
putValueProperty(ExecState * exec,int token,JSValue * value,int)441 void KJS::HTMLDocument::putValueProperty(ExecState *exec, int token, JSValue *value, int /*attr*/)
442 {
443 DOM::HTMLDocumentImpl &doc = *impl();
444 DOM::DOMString val = value->toString(exec).domString();
445 DOMExceptionTranslator exception(exec);
446
447 switch (token) {
448 case Body: {
449 DOM::NodeImpl *body = toNode(value);
450 if (body && body->isHTMLElement()) {
451 doc.setBody(static_cast<DOM::HTMLElementImpl *>(body), exception);
452 }
453 return;
454 }
455 case Domain: { // not part of the DOM
456 doc.setDomain(val);
457 return;
458 }
459 case Cookie:
460 doc.setCookie(val);
461 return;
462 case Location: {
463 KHTMLPart *part = doc.part();
464 if (part) {
465 Window::retrieveWindow(part)->goURL(exec, value->toString(exec).qstring());
466 }
467 return;
468 }
469 case DesignMode:
470 doc.setDesignMode((value->toString(exec).qstring().toLower() == "on"));
471 return;
472 }
473
474 /* The rest of the properties require a body. Note that Doc::body may be the
475 frameset(!!) so we have to be a bit careful here. I am not sure this is
476 100% right, but it should match previous behavior - M.O. */
477 DOM::HTMLElementImpl *bodyCand = doc.body();
478 if (!bodyCand || bodyCand->id() != ID_BODY) {
479 return; //Just ignore.
480 }
481
482 DOM::HTMLBodyElementImpl &body = *static_cast<DOM::HTMLBodyElementImpl *>(bodyCand);
483
484 switch (token) {
485 case BgColor:
486 if (body.bgColor() != val) {
487 body.setBgColor(val);
488 }
489 break;
490 case FgColor:
491 if (body.text() != val) {
492 body.setText(val);
493 }
494 break;
495 case AlinkColor:
496 if (body.aLink() != val) {
497 body.setALink(val);
498 }
499 break;
500 case LinkColor:
501 if (body.link() != val) {
502 body.setLink(val);
503 }
504 break;
505 case VlinkColor:
506 if (body.vLink() != val) {
507 body.setVLink(val);
508 }
509 break;
510 case Dir:
511 body.setAttribute(ID_DIR, value->toString(exec).domString());
512 break;
513 default:
514 // qCDebug(KHTML_LOG) << "WARNING: HTMLDocument::putValueProperty unhandled token " << token;
515 break;
516 }
517 }
518
519 // -------------------------------------------------------------------------
520
521 const ClassInfo KJS::HTMLElement::info = { "HTMLElement", &DOMElement::info, &HTMLElementTable, nullptr };
522 const ClassInfo KJS::HTMLElement::html_info = { "HTMLHtmlElement", &KJS::HTMLElement::info, &HTMLHtmlElementTable, nullptr };
523 const ClassInfo KJS::HTMLElement::head_info = { "HTMLHeadElement", &KJS::HTMLElement::info, &HTMLHeadElementTable, nullptr };
524 const ClassInfo KJS::HTMLElement::link_info = { "HTMLLinkElement", &KJS::HTMLElement::info, &HTMLLinkElementTable, nullptr };
525 const ClassInfo KJS::HTMLElement::title_info = { "HTMLTitleElement", &KJS::HTMLElement::info, &HTMLTitleElementTable, nullptr };
526 const ClassInfo KJS::HTMLElement::meta_info = { "HTMLMetaElement", &KJS::HTMLElement::info, &HTMLMetaElementTable, nullptr };
527 const ClassInfo KJS::HTMLElement::base_info = { "HTMLBaseElement", &KJS::HTMLElement::info, &HTMLBaseElementTable, nullptr };
528 const ClassInfo KJS::HTMLElement::isIndex_info = { "HTMLIsIndexElement", &KJS::HTMLElement::info, &HTMLIsIndexElementTable, nullptr };
529 const ClassInfo KJS::HTMLElement::style_info = { "HTMLStyleElement", &KJS::HTMLElement::info, &HTMLStyleElementTable, nullptr };
530 const ClassInfo KJS::HTMLElement::body_info = { "HTMLBodyElement", &KJS::HTMLElement::info, &HTMLBodyElementTable, nullptr };
531 const ClassInfo KJS::HTMLElement::form_info = { "HTMLFormElement", &KJS::HTMLElement::info, &HTMLFormElementTable, nullptr };
532 const ClassInfo KJS::HTMLElement::select_info = { "HTMLSelectElement", &KJS::HTMLElement::info, &HTMLSelectElementTable, nullptr };
533 const ClassInfo KJS::HTMLElement::optGroup_info = { "HTMLOptGroupElement", &KJS::HTMLElement::info, &HTMLOptGroupElementTable, nullptr };
534 const ClassInfo KJS::HTMLElement::option_info = { "HTMLOptionElement", &KJS::HTMLElement::info, &HTMLOptionElementTable, nullptr };
535 const ClassInfo KJS::HTMLElement::input_info = { "HTMLInputElement", &KJS::HTMLElement::info, &HTMLInputElementTable, nullptr };
536 const ClassInfo KJS::HTMLElement::textArea_info = { "HTMLTextAreaElement", &KJS::HTMLElement::info, &HTMLTextAreaElementTable, nullptr };
537 const ClassInfo KJS::HTMLElement::button_info = { "HTMLButtonElement", &KJS::HTMLElement::info, &HTMLButtonElementTable, nullptr };
538 const ClassInfo KJS::HTMLElement::label_info = { "HTMLLabelElement", &KJS::HTMLElement::info, &HTMLLabelElementTable, nullptr };
539 const ClassInfo KJS::HTMLElement::fieldSet_info = { "HTMLFieldSetElement", &KJS::HTMLElement::info, &HTMLFieldSetElementTable, nullptr };
540 const ClassInfo KJS::HTMLElement::legend_info = { "HTMLLegendElement", &KJS::HTMLElement::info, &HTMLLegendElementTable, nullptr };
541 const ClassInfo KJS::HTMLElement::ul_info = { "HTMLUListElement", &KJS::HTMLElement::info, &HTMLUListElementTable, nullptr };
542 const ClassInfo KJS::HTMLElement::ol_info = { "HTMLOListElement", &KJS::HTMLElement::info, &HTMLOListElementTable, nullptr };
543 const ClassInfo KJS::HTMLElement::dl_info = { "HTMLDListElement", &KJS::HTMLElement::info, &HTMLDListElementTable, nullptr };
544 const ClassInfo KJS::HTMLElement::dir_info = { "HTMLDirectoryElement", &KJS::HTMLElement::info, &HTMLDirectoryElementTable, nullptr };
545 const ClassInfo KJS::HTMLElement::menu_info = { "HTMLMenuElement", &KJS::HTMLElement::info, &HTMLMenuElementTable, nullptr };
546 const ClassInfo KJS::HTMLElement::li_info = { "HTMLLIElement", &KJS::HTMLElement::info, &HTMLLIElementTable, nullptr };
547 const ClassInfo KJS::HTMLElement::div_info = { "HTMLDivElement", &KJS::HTMLElement::info, &HTMLDivElementTable, nullptr };
548 const ClassInfo KJS::HTMLElement::p_info = { "HTMLParagraphElement", &KJS::HTMLElement::info, &HTMLParagraphElementTable, nullptr };
549 const ClassInfo KJS::HTMLElement::heading_info = { "HTMLHeadingElement", &KJS::HTMLElement::info, &HTMLHeadingElementTable, nullptr };
550 const ClassInfo KJS::HTMLElement::blockQuote_info = { "HTMLBlockQuoteElement", &KJS::HTMLElement::info, &HTMLBlockQuoteElementTable, nullptr };
551 const ClassInfo KJS::HTMLElement::q_info = { "HTMLQuoteElement", &KJS::HTMLElement::info, &HTMLQuoteElementTable, nullptr };
552 const ClassInfo KJS::HTMLElement::pre_info = { "HTMLPreElement", &KJS::HTMLElement::info, &HTMLPreElementTable, nullptr };
553 const ClassInfo KJS::HTMLElement::br_info = { "HTMLBRElement", &KJS::HTMLElement::info, &HTMLBRElementTable, nullptr };
554 const ClassInfo KJS::HTMLElement::baseFont_info = { "HTMLBaseFontElement", &KJS::HTMLElement::info, &HTMLBaseFontElementTable, nullptr };
555 const ClassInfo KJS::HTMLElement::font_info = { "HTMLFontElement", &KJS::HTMLElement::info, &HTMLFontElementTable, nullptr };
556 const ClassInfo KJS::HTMLElement::hr_info = { "HTMLHRElement", &KJS::HTMLElement::info, &HTMLHRElementTable, nullptr };
557 const ClassInfo KJS::HTMLElement::mod_info = { "HTMLModElement", &KJS::HTMLElement::info, &HTMLModElementTable, nullptr };
558 const ClassInfo KJS::HTMLElement::a_info = { "HTMLAnchorElement", &KJS::HTMLElement::info, &HTMLAnchorElementTable, nullptr };
559 const ClassInfo KJS::HTMLElement::canvas_info = { "HTMLCanvasElement", &KJS::HTMLElement::info, &HTMLCanvasElementTable, nullptr };
560 const ClassInfo KJS::HTMLElement::img_info = { "HTMLImageElement", &KJS::HTMLElement::info, &HTMLImageElementTable, nullptr };
561 const ClassInfo KJS::HTMLElement::object_info = { "HTMLObjectElement", &KJS::HTMLElement::info, &HTMLObjectElementTable, nullptr };
562 const ClassInfo KJS::HTMLElement::param_info = { "HTMLParamElement", &KJS::HTMLElement::info, &HTMLParamElementTable, nullptr };
563 const ClassInfo KJS::HTMLElement::applet_info = { "HTMLAppletElement", &KJS::HTMLElement::info, &HTMLAppletElementTable, nullptr };
564 const ClassInfo KJS::HTMLElement::map_info = { "HTMLMapElement", &KJS::HTMLElement::info, &HTMLMapElementTable, nullptr };
565 const ClassInfo KJS::HTMLElement::area_info = { "HTMLAreaElement", &KJS::HTMLElement::info, &HTMLAreaElementTable, nullptr };
566 const ClassInfo KJS::HTMLElement::script_info = { "HTMLScriptElement", &KJS::HTMLElement::info, &HTMLScriptElementTable, nullptr };
567 const ClassInfo KJS::HTMLElement::table_info = { "HTMLTableElement", &KJS::HTMLElement::info, &HTMLTableElementTable, nullptr };
568 const ClassInfo KJS::HTMLElement::caption_info = { "HTMLTableCaptionElement", &KJS::HTMLElement::info, &HTMLTableCaptionElementTable, nullptr };
569 const ClassInfo KJS::HTMLElement::col_info = { "HTMLTableColElement", &KJS::HTMLElement::info, &HTMLTableColElementTable, nullptr };
570 const ClassInfo KJS::HTMLElement::tablesection_info = { "HTMLTableSectionElement", &KJS::HTMLElement::info, &HTMLTableSectionElementTable, nullptr };
571 const ClassInfo KJS::HTMLElement::tr_info = { "HTMLTableRowElement", &KJS::HTMLElement::info, &HTMLTableRowElementTable, nullptr };
572 const ClassInfo KJS::HTMLElement::tablecell_info = { "HTMLTableCellElement", &KJS::HTMLElement::info, &HTMLTableCellElementTable, nullptr };
573 const ClassInfo KJS::HTMLElement::frameSet_info = { "HTMLFrameSetElement", &KJS::HTMLElement::info, &HTMLFrameSetElementTable, nullptr };
574 const ClassInfo KJS::HTMLElement::frame_info = { "HTMLFrameElement", &KJS::HTMLElement::info, &HTMLFrameElementTable, nullptr };
575 const ClassInfo KJS::HTMLElement::iFrame_info = { "HTMLIFrameElement", &KJS::HTMLElement::info, &HTMLIFrameElementTable, nullptr };
576 const ClassInfo KJS::HTMLElement::marquee_info = { "HTMLMarqueeElement", &KJS::HTMLElement::info, nullptr, nullptr };
577 const ClassInfo KJS::HTMLElement::layer_info = { "HTMLLayerElement", &KJS::HTMLElement::info, &HTMLLayerElementTable, nullptr };
578
579 static JSObject *prototypeForID(ExecState *exec, DOM::NodeImpl::Id id);
580
HTMLElement(ExecState * exec,DOM::HTMLElementImpl * e)581 KJS::HTMLElement::HTMLElement(ExecState *exec, DOM::HTMLElementImpl *e) :
582 DOMElement(prototypeForID(exec, e->id()), e) { }
583
classInfo() const584 const ClassInfo *KJS::HTMLElement::classInfo() const
585 {
586 DOM::HTMLElementImpl &element = *impl();
587 switch (element.id()) {
588 case ID_HTML:
589 return &html_info;
590 case ID_HEAD:
591 return &head_info;
592 case ID_LINK:
593 return &link_info;
594 case ID_TITLE:
595 return &title_info;
596 case ID_META:
597 return &meta_info;
598 case ID_BASE:
599 return &base_info;
600 case ID_ISINDEX:
601 return &isIndex_info;
602 case ID_STYLE:
603 return &style_info;
604 case ID_BODY:
605 return &body_info;
606 case ID_FORM:
607 return &form_info;
608 case ID_SELECT:
609 return &select_info;
610 case ID_OPTGROUP:
611 return &optGroup_info;
612 case ID_OPTION:
613 return &option_info;
614 case ID_INPUT:
615 return &input_info;
616 case ID_TEXTAREA:
617 return &textArea_info;
618 case ID_BUTTON:
619 return &button_info;
620 case ID_LABEL:
621 return &label_info;
622 case ID_FIELDSET:
623 return &fieldSet_info;
624 case ID_LEGEND:
625 return &legend_info;
626 case ID_UL:
627 return &ul_info;
628 case ID_OL:
629 return &ol_info;
630 case ID_DL:
631 return &dl_info;
632 case ID_DIR:
633 return &dir_info;
634 case ID_MENU:
635 return &menu_info;
636 case ID_LI:
637 return &li_info;
638 case ID_DIV:
639 return &div_info;
640 case ID_P:
641 return &p_info;
642 case ID_H1:
643 case ID_H2:
644 case ID_H3:
645 case ID_H4:
646 case ID_H5:
647 case ID_H6:
648 return &heading_info;
649 case ID_BLOCKQUOTE:
650 return &blockQuote_info;
651 case ID_Q:
652 return &q_info;
653 case ID_PRE:
654 return &pre_info;
655 case ID_BR:
656 return &br_info;
657 case ID_BASEFONT:
658 return &baseFont_info;
659 case ID_FONT:
660 return &font_info;
661 case ID_HR:
662 return &hr_info;
663 case ID_INS:
664 case ID_DEL:
665 return &mod_info;
666 case ID_A:
667 return &a_info;
668 case ID_IMG:
669 return &img_info;
670 case ID_CANVAS:
671 return &canvas_info;
672 case ID_OBJECT:
673 return &object_info;
674 case ID_PARAM:
675 return ¶m_info;
676 case ID_APPLET:
677 return &applet_info;
678 case ID_MAP:
679 return &map_info;
680 case ID_AREA:
681 return &area_info;
682 case ID_SCRIPT:
683 return &script_info;
684 case ID_TABLE:
685 return &table_info;
686 case ID_CAPTION:
687 return &caption_info;
688 case ID_COL:
689 case ID_COLGROUP:
690 return &col_info;
691 case ID_THEAD:
692 case ID_TBODY:
693 case ID_TFOOT:
694 return &tablesection_info;
695 case ID_TR:
696 return &tr_info;
697 case ID_TH:
698 case ID_TD:
699 return &tablecell_info;
700 case ID_FRAMESET:
701 return &frameSet_info;
702 case ID_FRAME:
703 return &frame_info;
704 case ID_IFRAME:
705 return &iFrame_info;
706 case ID_MARQUEE:
707 return &marquee_info;
708 case ID_LAYER:
709 return &layer_info;
710 default:
711 return &info;
712 }
713 }
714 /*
715 @begin HTMLElementTable 11
716 id KJS::HTMLElement::ElementId DontDelete
717 title KJS::HTMLElement::ElementTitle DontDelete
718 lang KJS::HTMLElement::ElementLang DontDelete
719 dir KJS::HTMLElement::ElementDir DontDelete
720 className KJS::HTMLElement::ElementClassName DontDelete
721 innerHTML KJS::HTMLElement::ElementInnerHTML DontDelete
722 innerText KJS::HTMLElement::ElementInnerText DontDelete
723 document KJS::HTMLElement::ElementDocument DontDelete|ReadOnly
724 tabIndex KJS::HTMLElement::ElementTabIndex DontDelete
725 # IE extension
726 children KJS::HTMLElement::ElementChildren DontDelete|ReadOnly
727 all KJS::HTMLElement::ElementAll DontDelete|ReadOnly
728 contentEditable KJS::HTMLElement::ElementContentEditable DontDelete
729 isContentEditable KJS::HTMLElement::ElementIsContentEditable DontDelete|ReadOnly
730 @end
731 @begin HTMLElementProtoTable 1
732 scrollIntoView KJS::HTMLElement::ElementScrollIntoView DontDelete|Function 0
733 @end
734 @begin HTMLHtmlElementTable 1
735 version KJS::HTMLElement::HtmlVersion DontDelete
736 @end
737 @begin HTMLHeadElementTable 1
738 profile KJS::HTMLElement::HeadProfile DontDelete
739 @end
740 @begin HTMLLinkElementTable 11
741 disabled KJS::HTMLElement::LinkDisabled DontDelete
742 charset KJS::HTMLElement::LinkCharset DontDelete
743 href KJS::HTMLElement::LinkHref DontDelete
744 hreflang KJS::HTMLElement::LinkHrefLang DontDelete
745 media KJS::HTMLElement::LinkMedia DontDelete
746 rel KJS::HTMLElement::LinkRel DontDelete
747 rev KJS::HTMLElement::LinkRev DontDelete
748 target KJS::HTMLElement::LinkTarget DontDelete
749 type KJS::HTMLElement::LinkType DontDelete
750 sheet KJS::HTMLElement::LinkSheet DontDelete|ReadOnly
751 @end
752 @begin HTMLTitleElementTable 1
753 text KJS::HTMLElement::TitleText DontDelete
754 @end
755 @begin HTMLMetaElementTable 4
756 content KJS::HTMLElement::MetaContent DontDelete
757 httpEquiv KJS::HTMLElement::MetaHttpEquiv DontDelete
758 name KJS::HTMLElement::MetaName DontDelete
759 scheme KJS::HTMLElement::MetaScheme DontDelete
760 @end
761 @begin HTMLBaseElementTable 2
762 href KJS::HTMLElement::BaseHref DontDelete
763 target KJS::HTMLElement::BaseTarget DontDelete
764 @end
765 @begin HTMLIsIndexElementTable 2
766 form KJS::HTMLElement::IsIndexForm DontDelete|ReadOnly
767 prompt KJS::HTMLElement::IsIndexPrompt DontDelete
768 @end
769 @begin HTMLStyleElementTable 4
770 disabled KJS::HTMLElement::StyleDisabled DontDelete
771 media KJS::HTMLElement::StyleMedia DontDelete
772 type KJS::HTMLElement::StyleType DontDelete
773 sheet KJS::HTMLElement::StyleSheet DontDelete|ReadOnly
774 @end
775 @begin HTMLBodyElementTable 12
776 aLink KJS::HTMLElement::BodyALink DontDelete
777 background KJS::HTMLElement::BodyBackground DontDelete
778 bgColor KJS::HTMLElement::BodyBgColor DontDelete
779 link KJS::HTMLElement::BodyLink DontDelete
780 text KJS::HTMLElement::BodyText DontDelete
781 vLink KJS::HTMLElement::BodyVLink DontDelete
782 # HTML5 specifies these as shadowing normal ones and forwarding to window
783 onload KJS::HTMLElement::BodyOnLoad DontDelete
784 onerror KJS::HTMLElement::BodyOnError DontDelete
785 onfocus KJS::HTMLElement::BodyOnFocus DontDelete
786 onblur KJS::HTMLElement::BodyOnBlur DontDelete
787 onmessage KJS::HTMLElement::BodyOnMessage DontDelete
788 onhashchange KJS::HTMLElement::BodyOnHashChange DontDelete
789 @end
790 @begin HTMLBodyElementProtoTable 2
791 # Even though we do blur/focus everywhere, we still handle body.focus()
792 # specially for now
793 focus KJS::HTMLElement::BodyFocus DontDelete|Function 0
794 @end
795 @begin HTMLFormElementTable 11
796 # Also supported, by name/index
797 elements KJS::HTMLElement::FormElements DontDelete|ReadOnly
798 length KJS::HTMLElement::FormLength DontDelete|ReadOnly
799 name KJS::HTMLElement::FormName DontDelete
800 acceptCharset KJS::HTMLElement::FormAcceptCharset DontDelete
801 action KJS::HTMLElement::FormAction DontDelete
802 encoding KJS::HTMLElement::FormEncType DontDelete
803 enctype KJS::HTMLElement::FormEncType DontDelete
804 method KJS::HTMLElement::FormMethod DontDelete
805 target KJS::HTMLElement::FormTarget DontDelete
806 @end
807 @begin HTMLFormElementProtoTable 2
808 submit KJS::HTMLElement::FormSubmit DontDelete|Function 0
809 reset KJS::HTMLElement::FormReset DontDelete|Function 0
810 @end
811 @begin HTMLSelectElementTable 11
812 # Also supported, by index
813 type KJS::HTMLElement::SelectType DontDelete|ReadOnly
814 selectedIndex KJS::HTMLElement::SelectSelectedIndex DontDelete
815 value KJS::HTMLElement::SelectValue DontDelete
816 length KJS::HTMLElement::SelectLength DontDelete
817 form KJS::HTMLElement::SelectForm DontDelete|ReadOnly
818 options KJS::HTMLElement::SelectOptions DontDelete|ReadOnly
819 disabled KJS::HTMLElement::SelectDisabled DontDelete
820 multiple KJS::HTMLElement::SelectMultiple DontDelete
821 name KJS::HTMLElement::SelectName DontDelete
822 size KJS::HTMLElement::SelectSize DontDelete
823 @end
824 @begin HTMLSelectElementProtoTable 4
825 add KJS::HTMLElement::SelectAdd DontDelete|Function 2
826 item KJS::HTMLElement::SelectItem DontDelete|Function 1
827 remove KJS::HTMLElement::SelectRemove DontDelete|Function 1
828 @end
829 @begin HTMLOptGroupElementTable 2
830 disabled KJS::HTMLElement::OptGroupDisabled DontDelete
831 label KJS::HTMLElement::OptGroupLabel DontDelete
832 @end
833 @begin HTMLOptionElementTable 8
834 form KJS::HTMLElement::OptionForm DontDelete|ReadOnly
835 defaultSelected KJS::HTMLElement::OptionDefaultSelected DontDelete
836 text KJS::HTMLElement::OptionText DontDelete
837 index KJS::HTMLElement::OptionIndex DontDelete|ReadOnly
838 disabled KJS::HTMLElement::OptionDisabled DontDelete
839 label KJS::HTMLElement::OptionLabel DontDelete
840 selected KJS::HTMLElement::OptionSelected DontDelete
841 value KJS::HTMLElement::OptionValue DontDelete
842 @end
843 @begin HTMLInputElementTable 25
844 defaultValue KJS::HTMLElement::InputDefaultValue DontDelete
845 defaultChecked KJS::HTMLElement::InputDefaultChecked DontDelete
846 form KJS::HTMLElement::InputForm DontDelete|ReadOnly
847 accept KJS::HTMLElement::InputAccept DontDelete
848 accessKey KJS::HTMLElement::InputAccessKey DontDelete
849 align KJS::HTMLElement::InputAlign DontDelete
850 alt KJS::HTMLElement::InputAlt DontDelete
851 checked KJS::HTMLElement::InputChecked DontDelete
852 indeterminate KJS::HTMLElement::InputIndeterminate DontDelete
853 status KJS::HTMLElement::InputChecked DontDelete
854 disabled KJS::HTMLElement::InputDisabled DontDelete
855 maxLength KJS::HTMLElement::InputMaxLength DontDelete
856 name KJS::HTMLElement::InputName DontDelete
857 readOnly KJS::HTMLElement::InputReadOnly DontDelete
858 size KJS::HTMLElement::InputSize DontDelete
859 src KJS::HTMLElement::InputSrc DontDelete
860 type KJS::HTMLElement::InputType DontDelete
861 useMap KJS::HTMLElement::InputUseMap DontDelete
862 value KJS::HTMLElement::InputValue DontDelete
863 selectionStart KJS::HTMLElement::InputSelectionStart DontDelete
864 selectionEnd KJS::HTMLElement::InputSelectionEnd DontDelete
865 placeholder KJS::HTMLElement::InputPlaceholder DontDelete
866 @end
867 @begin HTMLInputElementProtoTable 5
868 select KJS::HTMLElement::InputSelect DontDelete|Function 0
869 click KJS::HTMLElement::InputClick DontDelete|Function 0
870 setSelectionRange KJS::HTMLElement::InputSetSelectionRange DontDelete|Function 2
871 @end
872 @begin HTMLTextAreaElementTable 13
873 defaultValue KJS::HTMLElement::TextAreaDefaultValue DontDelete
874 form KJS::HTMLElement::TextAreaForm DontDelete|ReadOnly
875 accessKey KJS::HTMLElement::TextAreaAccessKey DontDelete
876 cols KJS::HTMLElement::TextAreaCols DontDelete
877 disabled KJS::HTMLElement::TextAreaDisabled DontDelete
878 name KJS::HTMLElement::TextAreaName DontDelete
879 readOnly KJS::HTMLElement::TextAreaReadOnly DontDelete
880 rows KJS::HTMLElement::TextAreaRows DontDelete
881 type KJS::HTMLElement::TextAreaType DontDelete|ReadOnly
882 value KJS::HTMLElement::TextAreaValue DontDelete
883 selectionStart KJS::HTMLElement::TextAreaSelectionStart DontDelete
884 selectionEnd KJS::HTMLElement::TextAreaSelectionEnd DontDelete
885 textLength KJS::HTMLElement::TextAreaTextLength DontDelete|ReadOnly
886 placeholder KJS::HTMLElement::TextAreaPlaceholder DontDelete
887 @end
888 @begin HTMLTextAreaElementProtoTable 4
889 select KJS::HTMLElement::TextAreaSelect DontDelete|Function 0
890 setSelectionRange KJS::HTMLElement::TextAreaSetSelectionRange DontDelete|Function 2
891 @end
892 @begin HTMLButtonElementTable 9
893 form KJS::HTMLElement::ButtonForm DontDelete|ReadOnly
894 accessKey KJS::HTMLElement::ButtonAccessKey DontDelete
895 disabled KJS::HTMLElement::ButtonDisabled DontDelete
896 name KJS::HTMLElement::ButtonName DontDelete
897 type KJS::HTMLElement::ButtonType DontDelete|ReadOnly
898 value KJS::HTMLElement::ButtonValue DontDelete
899 @end
900 @begin HTMLButtonElementProtoTable 3
901 click KJS::HTMLElement::ButtonClick DontDelete|Function 0
902 @end
903 @begin HTMLLabelElementTable 3
904 form KJS::HTMLElement::LabelForm DontDelete|ReadOnly
905 accessKey KJS::HTMLElement::LabelAccessKey DontDelete
906 htmlFor KJS::HTMLElement::LabelHtmlFor DontDelete
907 @end
908 @begin HTMLFieldSetElementTable 1
909 form KJS::HTMLElement::FieldSetForm DontDelete|ReadOnly
910 @end
911 @begin HTMLLegendElementTable 3
912 form KJS::HTMLElement::LegendForm DontDelete|ReadOnly
913 accessKey KJS::HTMLElement::LegendAccessKey DontDelete
914 align KJS::HTMLElement::LegendAlign DontDelete
915 @end
916 @begin HTMLUListElementTable 2
917 compact KJS::HTMLElement::UListCompact DontDelete
918 type KJS::HTMLElement::UListType DontDelete
919 @end
920 @begin HTMLOListElementTable 3
921 compact KJS::HTMLElement::OListCompact DontDelete
922 start KJS::HTMLElement::OListStart DontDelete
923 type KJS::HTMLElement::OListType DontDelete
924 @end
925 @begin HTMLDListElementTable 1
926 compact KJS::HTMLElement::DListCompact DontDelete
927 @end
928 @begin HTMLDirectoryElementTable 1
929 compact KJS::HTMLElement::DirectoryCompact DontDelete
930 @end
931 @begin HTMLMenuElementTable 1
932 compact KJS::HTMLElement::MenuCompact DontDelete
933 @end
934 @begin HTMLLIElementTable 2
935 type KJS::HTMLElement::LIType DontDelete
936 value KJS::HTMLElement::LIValue DontDelete
937 @end
938 @begin HTMLDivElementTable 1
939 align KJS::HTMLElement::DivAlign DontDelete
940 @end
941 @begin HTMLParagraphElementTable 1
942 align KJS::HTMLElement::ParagraphAlign DontDelete
943 @end
944 @begin HTMLHeadingElementTable 1
945 align KJS::HTMLElement::HeadingAlign DontDelete
946 @end
947 @begin HTMLBlockQuoteElementTable 1
948 cite KJS::HTMLElement::BlockQuoteCite DontDelete
949 @end
950 @begin HTMLQuoteElementTable 1
951 cite KJS::HTMLElement::QuoteCite DontDelete
952 @end
953 @begin HTMLPreElementTable 1
954 width KJS::HTMLElement::PreWidth DontDelete
955 @end
956 @begin HTMLBRElementTable 1
957 clear KJS::HTMLElement::BRClear DontDelete
958 @end
959 @begin HTMLBaseFontElementTable 3
960 color KJS::HTMLElement::BaseFontColor DontDelete
961 face KJS::HTMLElement::BaseFontFace DontDelete
962 size KJS::HTMLElement::BaseFontSize DontDelete
963 @end
964 @begin HTMLFontElementTable 3
965 color KJS::HTMLElement::FontColor DontDelete
966 face KJS::HTMLElement::FontFace DontDelete
967 size KJS::HTMLElement::FontSize DontDelete
968 @end
969 @begin HTMLHRElementTable 4
970 align KJS::HTMLElement::HRAlign DontDelete
971 noShade KJS::HTMLElement::HRNoShade DontDelete
972 size KJS::HTMLElement::HRSize DontDelete
973 width KJS::HTMLElement::HRWidth DontDelete
974 @end
975 @begin HTMLModElementTable 2
976 cite KJS::HTMLElement::ModCite DontDelete
977 dateTime KJS::HTMLElement::ModDateTime DontDelete
978 @end
979 @begin HTMLAnchorElementTable 23
980 accessKey KJS::HTMLElement::AnchorAccessKey DontDelete
981 charset KJS::HTMLElement::AnchorCharset DontDelete
982 coords KJS::HTMLElement::AnchorCoords DontDelete
983 href KJS::HTMLElement::AnchorHref DontDelete
984 hreflang KJS::HTMLElement::AnchorHrefLang DontDelete
985 hash KJS::HTMLElement::AnchorHash DontDelete|ReadOnly
986 host KJS::HTMLElement::AnchorHost DontDelete|ReadOnly
987 hostname KJS::HTMLElement::AnchorHostname DontDelete|ReadOnly
988 name KJS::HTMLElement::AnchorName DontDelete
989 pathname KJS::HTMLElement::AnchorPathName DontDelete|ReadOnly
990 port KJS::HTMLElement::AnchorPort DontDelete|ReadOnly
991 protocol KJS::HTMLElement::AnchorProtocol DontDelete|ReadOnly
992 rel KJS::HTMLElement::AnchorRel DontDelete
993 rev KJS::HTMLElement::AnchorRev DontDelete
994 search KJS::HTMLElement::AnchorSearch DontDelete
995 shape KJS::HTMLElement::AnchorShape DontDelete
996 target KJS::HTMLElement::AnchorTarget DontDelete
997 text KJS::HTMLElement::AnchorText DontDelete|ReadOnly
998 type KJS::HTMLElement::AnchorType DontDelete
999 @end
1000 @begin HTMLAnchorElementProtoTable 3
1001 click KJS::HTMLElement::AnchorClick DontDelete|Function 0
1002 toString KJS::HTMLElement::AnchorToString DontDelete|Function 0
1003 @end
1004 @begin HTMLImageElementTable 15
1005 name KJS::HTMLElement::ImageName DontDelete
1006 align KJS::HTMLElement::ImageAlign DontDelete
1007 alt KJS::HTMLElement::ImageAlt DontDelete
1008 border KJS::HTMLElement::ImageBorder DontDelete
1009 complete KJS::HTMLElement::ImageComplete DontDelete|ReadOnly
1010 height KJS::HTMLElement::ImageHeight DontDelete
1011 hspace KJS::HTMLElement::ImageHspace DontDelete
1012 isMap KJS::HTMLElement::ImageIsMap DontDelete
1013 longDesc KJS::HTMLElement::ImageLongDesc DontDelete
1014 src KJS::HTMLElement::ImageSrc DontDelete
1015 useMap KJS::HTMLElement::ImageUseMap DontDelete
1016 vspace KJS::HTMLElement::ImageVspace DontDelete
1017 width KJS::HTMLElement::ImageWidth DontDelete
1018 x KJS::HTMLElement::ImageX DontDelete|ReadOnly
1019 y KJS::HTMLElement::ImageY DontDelete|ReadOnly
1020 @end
1021 @begin HTMLObjectElementTable 23
1022 form KJS::HTMLElement::ObjectForm DontDelete|ReadOnly
1023 code KJS::HTMLElement::ObjectCode DontDelete
1024 align KJS::HTMLElement::ObjectAlign DontDelete
1025 archive KJS::HTMLElement::ObjectArchive DontDelete
1026 border KJS::HTMLElement::ObjectBorder DontDelete
1027 codeBase KJS::HTMLElement::ObjectCodeBase DontDelete
1028 codeType KJS::HTMLElement::ObjectCodeType DontDelete
1029 contentDocument KJS::HTMLElement::ObjectContentDocument DontDelete|ReadOnly
1030 data KJS::HTMLElement::ObjectData DontDelete
1031 declare KJS::HTMLElement::ObjectDeclare DontDelete
1032 height KJS::HTMLElement::ObjectHeight DontDelete
1033 hspace KJS::HTMLElement::ObjectHspace DontDelete
1034 name KJS::HTMLElement::ObjectName DontDelete
1035 standby KJS::HTMLElement::ObjectStandby DontDelete
1036 type KJS::HTMLElement::ObjectType DontDelete
1037 useMap KJS::HTMLElement::ObjectUseMap DontDelete
1038 vspace KJS::HTMLElement::ObjectVspace DontDelete
1039 width KJS::HTMLElement::ObjectWidth DontDelete
1040 @end
1041 @begin HTMLObjectElementProtoTable 1
1042 # half deprecated - cf. https://lists.w3.org/Archives/Public/www-svg/2008Feb/0031.html
1043 # only implemented in ecma, because of acid3 dependency
1044 getSVGDocument KJS::HTMLElement::ObjectGetSVGDocument DontDelete|Function 0
1045 @end
1046 @begin HTMLParamElementTable 4
1047 name KJS::HTMLElement::ParamName DontDelete
1048 type KJS::HTMLElement::ParamType DontDelete
1049 value KJS::HTMLElement::ParamValue DontDelete
1050 valueType KJS::HTMLElement::ParamValueType DontDelete
1051 @end
1052 @begin HTMLAppletElementTable 11
1053 align KJS::HTMLElement::AppletAlign DontDelete
1054 alt KJS::HTMLElement::AppletAlt DontDelete
1055 archive KJS::HTMLElement::AppletArchive DontDelete
1056 code KJS::HTMLElement::AppletCode DontDelete
1057 codeBase KJS::HTMLElement::AppletCodeBase DontDelete
1058 height KJS::HTMLElement::AppletHeight DontDelete
1059 hspace KJS::HTMLElement::AppletHspace DontDelete
1060 name KJS::HTMLElement::AppletName DontDelete
1061 object KJS::HTMLElement::AppletObject DontDelete
1062 vspace KJS::HTMLElement::AppletVspace DontDelete
1063 width KJS::HTMLElement::AppletWidth DontDelete
1064 @end
1065 @begin HTMLMapElementTable 2
1066 areas KJS::HTMLElement::MapAreas DontDelete|ReadOnly
1067 name KJS::HTMLElement::MapName DontDelete
1068 @end
1069 @begin HTMLAreaElementTable 15
1070 accessKey KJS::HTMLElement::AreaAccessKey DontDelete
1071 alt KJS::HTMLElement::AreaAlt DontDelete
1072 coords KJS::HTMLElement::AreaCoords DontDelete
1073 href KJS::HTMLElement::AreaHref DontDelete
1074 hash KJS::HTMLElement::AreaHash DontDelete|ReadOnly
1075 host KJS::HTMLElement::AreaHost DontDelete|ReadOnly
1076 hostname KJS::HTMLElement::AreaHostName DontDelete|ReadOnly
1077 pathname KJS::HTMLElement::AreaPathName DontDelete|ReadOnly
1078 port KJS::HTMLElement::AreaPort DontDelete|ReadOnly
1079 protocol KJS::HTMLElement::AreaProtocol DontDelete|ReadOnly
1080 search KJS::HTMLElement::AreaSearch DontDelete|ReadOnly
1081 noHref KJS::HTMLElement::AreaNoHref DontDelete
1082 shape KJS::HTMLElement::AreaShape DontDelete
1083 target KJS::HTMLElement::AreaTarget DontDelete
1084 @end
1085 @begin HTMLScriptElementTable 7
1086 text KJS::HTMLElement::ScriptText DontDelete
1087 htmlFor KJS::HTMLElement::ScriptHtmlFor DontDelete
1088 event KJS::HTMLElement::ScriptEvent DontDelete
1089 charset KJS::HTMLElement::ScriptCharset DontDelete
1090 defer KJS::HTMLElement::ScriptDefer DontDelete
1091 src KJS::HTMLElement::ScriptSrc DontDelete
1092 type KJS::HTMLElement::ScriptType DontDelete
1093 @end
1094 @begin HTMLTableElementTable 23
1095 caption KJS::HTMLElement::TableCaption DontDelete
1096 tHead KJS::HTMLElement::TableTHead DontDelete
1097 tFoot KJS::HTMLElement::TableTFoot DontDelete
1098 rows KJS::HTMLElement::TableRows DontDelete|ReadOnly
1099 tBodies KJS::HTMLElement::TableTBodies DontDelete|ReadOnly
1100 align KJS::HTMLElement::TableAlign DontDelete
1101 bgColor KJS::HTMLElement::TableBgColor DontDelete
1102 border KJS::HTMLElement::TableBorder DontDelete
1103 cellPadding KJS::HTMLElement::TableCellPadding DontDelete
1104 cellSpacing KJS::HTMLElement::TableCellSpacing DontDelete
1105 frame KJS::HTMLElement::TableFrame DontDelete
1106 rules KJS::HTMLElement::TableRules DontDelete
1107 summary KJS::HTMLElement::TableSummary DontDelete
1108 width KJS::HTMLElement::TableWidth DontDelete
1109 @end
1110 @begin HTMLTableElementProtoTable 8
1111 createTHead KJS::HTMLElement::TableCreateTHead DontDelete|Function 0
1112 deleteTHead KJS::HTMLElement::TableDeleteTHead DontDelete|Function 0
1113 createTFoot KJS::HTMLElement::TableCreateTFoot DontDelete|Function 0
1114 deleteTFoot KJS::HTMLElement::TableDeleteTFoot DontDelete|Function 0
1115 createCaption KJS::HTMLElement::TableCreateCaption DontDelete|Function 0
1116 deleteCaption KJS::HTMLElement::TableDeleteCaption DontDelete|Function 0
1117 insertRow KJS::HTMLElement::TableInsertRow DontDelete|Function 1
1118 deleteRow KJS::HTMLElement::TableDeleteRow DontDelete|Function 1
1119 @end
1120 @begin HTMLTableCaptionElementTable 1
1121 align KJS::HTMLElement::TableCaptionAlign DontDelete
1122 @end
1123 @begin HTMLTableColElementTable 7
1124 align KJS::HTMLElement::TableColAlign DontDelete
1125 ch KJS::HTMLElement::TableColCh DontDelete
1126 chOff KJS::HTMLElement::TableColChOff DontDelete
1127 span KJS::HTMLElement::TableColSpan DontDelete
1128 vAlign KJS::HTMLElement::TableColVAlign DontDelete
1129 width KJS::HTMLElement::TableColWidth DontDelete
1130 @end
1131 @begin HTMLTableSectionElementTable 7
1132 align KJS::HTMLElement::TableSectionAlign DontDelete
1133 ch KJS::HTMLElement::TableSectionCh DontDelete
1134 chOff KJS::HTMLElement::TableSectionChOff DontDelete
1135 vAlign KJS::HTMLElement::TableSectionVAlign DontDelete
1136 rows KJS::HTMLElement::TableSectionRows DontDelete|ReadOnly
1137 @end
1138 @begin HTMLTableSectionElementProtoTable 2
1139 insertRow KJS::HTMLElement::TableSectionInsertRow DontDelete|Function 1
1140 deleteRow KJS::HTMLElement::TableSectionDeleteRow DontDelete|Function 1
1141 @end
1142 @begin HTMLTableRowElementTable 11
1143 rowIndex KJS::HTMLElement::TableRowRowIndex DontDelete|ReadOnly
1144 sectionRowIndex KJS::HTMLElement::TableRowSectionRowIndex DontDelete|ReadOnly
1145 cells KJS::HTMLElement::TableRowCells DontDelete|ReadOnly
1146 align KJS::HTMLElement::TableRowAlign DontDelete
1147 bgColor KJS::HTMLElement::TableRowBgColor DontDelete
1148 ch KJS::HTMLElement::TableRowCh DontDelete
1149 chOff KJS::HTMLElement::TableRowChOff DontDelete
1150 vAlign KJS::HTMLElement::TableRowVAlign DontDelete
1151 @end
1152 @begin HTMLTableRowElementProtoTable 2
1153 insertCell KJS::HTMLElement::TableRowInsertCell DontDelete|Function 1
1154 deleteCell KJS::HTMLElement::TableRowDeleteCell DontDelete|Function 1
1155 @end
1156 @begin HTMLTableCellElementTable 15
1157 cellIndex KJS::HTMLElement::TableCellCellIndex DontDelete|ReadOnly
1158 abbr KJS::HTMLElement::TableCellAbbr DontDelete
1159 align KJS::HTMLElement::TableCellAlign DontDelete
1160 axis KJS::HTMLElement::TableCellAxis DontDelete
1161 bgColor KJS::HTMLElement::TableCellBgColor DontDelete
1162 ch KJS::HTMLElement::TableCellCh DontDelete
1163 chOff KJS::HTMLElement::TableCellChOff DontDelete
1164 colSpan KJS::HTMLElement::TableCellColSpan DontDelete
1165 headers KJS::HTMLElement::TableCellHeaders DontDelete
1166 height KJS::HTMLElement::TableCellHeight DontDelete
1167 noWrap KJS::HTMLElement::TableCellNoWrap DontDelete
1168 rowSpan KJS::HTMLElement::TableCellRowSpan DontDelete
1169 scope KJS::HTMLElement::TableCellScope DontDelete
1170 vAlign KJS::HTMLElement::TableCellVAlign DontDelete
1171 width KJS::HTMLElement::TableCellWidth DontDelete
1172 @end
1173 @begin HTMLFrameSetElementTable 2
1174 cols KJS::HTMLElement::FrameSetCols DontDelete
1175 rows KJS::HTMLElement::FrameSetRows DontDelete
1176 onmessage KJS::HTMLElement::FrameSetOnMessage DontDelete
1177 @end
1178 @begin HTMLLayerElementTable 6
1179 top KJS::HTMLElement::LayerTop DontDelete
1180 left KJS::HTMLElement::LayerLeft DontDelete
1181 visibility KJS::HTMLElement::LayerVisibility DontDelete
1182 bgColor KJS::HTMLElement::LayerBgColor DontDelete
1183 document KJS::HTMLElement::LayerDocument DontDelete|ReadOnly
1184 clip KJS::HTMLElement::LayerClip DontDelete|ReadOnly
1185 layers KJS::HTMLElement::LayerLayers DontDelete|ReadOnly
1186 @end
1187 @begin HTMLFrameElementTable 13
1188 contentDocument KJS::HTMLElement::FrameContentDocument DontDelete|ReadOnly
1189 contentWindow KJS::HTMLElement::FrameContentWindow DontDelete|ReadOnly
1190 frameBorder KJS::HTMLElement::FrameFrameBorder DontDelete
1191 longDesc KJS::HTMLElement::FrameLongDesc DontDelete
1192 marginHeight KJS::HTMLElement::FrameMarginHeight DontDelete
1193 marginWidth KJS::HTMLElement::FrameMarginWidth DontDelete
1194 name KJS::HTMLElement::FrameName DontDelete
1195 noResize KJS::HTMLElement::FrameNoResize DontDelete
1196 scrolling KJS::HTMLElement::FrameScrolling DontDelete
1197 src KJS::HTMLElement::FrameSrc DontDelete
1198 location KJS::HTMLElement::FrameLocation DontDelete
1199 # IE extension
1200 width KJS::HTMLElement::FrameWidth DontDelete|ReadOnly
1201 height KJS::HTMLElement::FrameHeight DontDelete|ReadOnly
1202 @end
1203 @begin HTMLIFrameElementTable 13
1204 align KJS::HTMLElement::IFrameAlign DontDelete
1205 contentDocument KJS::HTMLElement::IFrameContentDocument DontDelete|ReadOnly
1206 contentWindow KJS::HTMLElement::IFrameContentWindow DontDelete|ReadOnly
1207 frameBorder KJS::HTMLElement::IFrameFrameBorder DontDelete
1208 height KJS::HTMLElement::IFrameHeight DontDelete
1209 longDesc KJS::HTMLElement::IFrameLongDesc DontDelete
1210 marginHeight KJS::HTMLElement::IFrameMarginHeight DontDelete
1211 marginWidth KJS::HTMLElement::IFrameMarginWidth DontDelete
1212 name KJS::HTMLElement::IFrameName DontDelete
1213 scrolling KJS::HTMLElement::IFrameScrolling DontDelete
1214 src KJS::HTMLElement::IFrameSrc DontDelete
1215 width KJS::HTMLElement::IFrameWidth DontDelete
1216 @end
1217 @begin HTMLIFrameElementProtoTable 1
1218 # half deprecated - cf. https://lists.w3.org/Archives/Public/www-svg/2008Feb/0031.html
1219 # only implemented in ecma, because of acid3 dependency
1220 getSVGDocument KJS::HTMLElement::IFrameGetSVGDocument DontDelete|Function 0
1221 @end
1222
1223 @begin HTMLMarqueeElementProtoTable 2
1224 start KJS::HTMLElement::MarqueeStart DontDelete|Function 0
1225 stop KJS::HTMLElement::MarqueeStop DontDelete|Function 0
1226 @end
1227
1228 @begin HTMLCanvasElementTable 2
1229 width KJS::HTMLElement::CanvasWidth DontDelete
1230 height KJS::HTMLElement::CanvasHeight DontDelete
1231 @end
1232
1233 @begin HTMLCanvasElementProtoTable 1
1234 getContext KJS::HTMLElement::CanvasGetContext DontDelete|Function 1
1235 toDataURL KJS::HTMLElement::CanvasToDataURL DontDelete|Function 0
1236 @end
1237 */
KJS_IMPLEMENT_PROTOFUNC(HTMLElementFunction)1238 KJS_IMPLEMENT_PROTOFUNC(HTMLElementFunction)
1239
1240 KParts::ScriptableExtension *HTMLElement::getScriptableExtension(const DOM::HTMLElementImpl &element)
1241 {
1242 DOM::DocumentImpl *doc = element.document();
1243 if (doc->part()) {
1244 return doc->part()->scriptableExtension(&element);
1245 }
1246 return nullptr;
1247 }
1248
formNameGetter(ExecState * exec,JSObject *,const Identifier & propertyName,const PropertySlot & slot)1249 JSValue *HTMLElement::formNameGetter(ExecState *exec, JSObject *, const Identifier &propertyName, const PropertySlot &slot)
1250 {
1251 HTMLElement *thisObj = static_cast<HTMLElement *>(slot.slotBase());
1252 HTMLFormElementImpl *form = static_cast<HTMLFormElementImpl *>(thisObj->impl());
1253
1254 KJS::HTMLCollection coll(exec, form->elements());
1255 JSValue *result = coll.getNamedItems(exec, propertyName);
1256
1257 // In case of simple result, remember in past names map
1258 // ### our HTMLFormElementsCollection is a bit too IE-compatey rather than HTML5ey
1259 if (DOM::NodeImpl *node = toNode(result)) {
1260 if (node->isGenericFormElement()) {
1261 form->bindPastName(static_cast<HTMLGenericFormElementImpl *>(node));
1262 }
1263 }
1264 return result;
1265 }
1266
1267 //JSValue* KJS::HTMLElement::tryGet(ExecState *exec, const Identifier &propertyName) const
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)1268 bool KJS::HTMLElement::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
1269 {
1270 DOM::HTMLElementImpl &element = *impl();
1271 #ifdef KJS_VERBOSE
1272 qCDebug(KHTML_LOG) << "KJS::HTMLElement::getOwnPropertySlot " << propertyName.qstring() << " thisTag=" << element.tagName().string();
1273 #endif
1274 // First look at dynamic properties
1275 switch (element.id()) {
1276 case ID_FORM: {
1277 DOM::HTMLFormElementImpl &form = static_cast<DOM::HTMLFormElementImpl &>(element);
1278 // Check if we're retrieving an element (by index or by name)
1279
1280 if (getIndexSlot(this, propertyName, slot)) {
1281 return true;
1282 }
1283
1284 KJS::HTMLCollection coll(exec, form.elements());
1285 JSValue *namedItems = coll.getNamedItems(exec, propertyName);
1286 if (namedItems->type() != UndefinedType) {
1287 slot.setCustom(this, formNameGetter);
1288 return true;
1289 }
1290
1291 // Try with past names map
1292 if (HTMLGenericFormElementImpl *r = form.lookupByPastName(propertyName.domString())) {
1293 return getImmediateValueSlot(this, getDOMNode(exec, r), slot);
1294 }
1295
1296 break;
1297 }
1298 case ID_SELECT:
1299 if (getIndexSlot(this, propertyName, slot)) {
1300 return true;
1301 }
1302 break;
1303 case ID_APPLET:
1304 case ID_OBJECT:
1305 case ID_EMBED: {
1306 KParts::ScriptableExtension *se = getScriptableExtension(*impl());
1307 if (pluginRootGet(exec, se, propertyName, slot)) {
1308 return true;
1309 }
1310 break;
1311 }
1312 }
1313
1314 const HashTable *table = classInfo()->propHashTable; // get the right hashtable
1315 if (table && getStaticOwnPropertySlot<HTMLElementFunction, HTMLElement>(table, this, propertyName, slot)) {
1316 return true;
1317 }
1318
1319 // Base HTMLElement stuff or parent class forward, as usual
1320 return getStaticPropertySlot<KJS::HTMLElementFunction, KJS::HTMLElement, DOMElement>(
1321 exec, &KJS::HTMLElementTable, this, propertyName, slot);
1322 }
1323
indexGetter(ExecState * exec,unsigned index)1324 JSValue *HTMLElement::indexGetter(ExecState *exec, unsigned index)
1325 {
1326 switch (impl()->id()) {
1327 case ID_FORM: {
1328 DOM::HTMLFormElementImpl *form = static_cast<DOM::HTMLFormElementImpl *>(impl());
1329 SharedPtr<DOM::HTMLCollectionImpl> elems = form->elements();
1330 return getDOMNode(exec, elems->item(index));
1331 }
1332 case ID_SELECT: {
1333 DOM::HTMLSelectElementImpl *select = static_cast<DOM::HTMLSelectElementImpl *>(impl());
1334 SharedPtr<DOM::HTMLCollectionImpl> opts = select->options();
1335 return getDOMNode(exec, opts->item(index)); // not specified by DOM(?) but supported in netscape/IE
1336 }
1337 default:
1338 assert(0);
1339 return jsUndefined();
1340 }
1341 }
1342
1343 #if 0
1344 // First look at dynamic properties
1345 switch (element.id())
1346 {
1347 case ID_FORM: {
1348 DOM::HTMLFormElementImpl &form = static_cast<DOM::HTMLFormElementImpl &>(element);
1349 // Check if we're retrieving an element (by index or by name)
1350 KJS::HTMLCollection coll(exec, form.elements());
1351 JSValue *namedItems = coll.getNamedItems(exec, propertyName);
1352 if (namedItems->type() != UndefinedType) {
1353 return namedItems;
1354 }
1355 }
1356 }
1357
1358 #endif
1359
1360 /**
1361 Table of how to connect JS tokens to attributes
1362 */
1363 const KJS::HTMLElement::BoundPropInfo KJS::HTMLElement::bpTable[] = {
1364 {ID_HTML, HtmlVersion, T_String, ATTR_VERSION},
1365 {ID_HEAD, HeadProfile, T_String, ATTR_PROFILE},
1366 {ID_LINK, LinkDisabled, T_Bool, ATTR_DISABLED},
1367 {ID_LINK, LinkCharset, T_String, ATTR_CHARSET},
1368 {ID_LINK, LinkHref, T_URL, ATTR_HREF},
1369 {ID_LINK, LinkHrefLang, T_String, ATTR_HREFLANG},
1370 {ID_LINK, LinkMedia, T_String, ATTR_MEDIA},
1371 {ID_LINK, LinkRel, T_String, ATTR_REL},
1372 {ID_LINK, LinkRev, T_String, ATTR_REV},
1373 {ID_LINK, LinkTarget, T_String, ATTR_TARGET},
1374 {ID_LINK, LinkType, T_String, ATTR_TYPE},
1375 {ID_BASE, BaseHref, T_URL, ATTR_HREF},
1376 {ID_BASE, BaseTarget, T_String, ATTR_TARGET},
1377 {ID_META, MetaContent, T_String, ATTR_CONTENT},
1378 {ID_META, MetaHttpEquiv, T_String, ATTR_HTTP_EQUIV},
1379 {ID_META, MetaName, T_String, ATTR_NAME},
1380 {ID_META, MetaScheme, T_String, ATTR_SCHEME},
1381 {ID_STYLE, StyleDisabled, T_Bool, ATTR_DISABLED},
1382 {ID_STYLE, StyleMedia, T_String, ATTR_MEDIA},
1383 {ID_STYLE, StyleType, T_String, ATTR_TYPE},
1384 {ID_BODY, BodyALink, T_String, ATTR_ALINK},
1385 {ID_BODY, BodyBackground, T_String, ATTR_BACKGROUND},
1386 {ID_BODY, BodyBgColor, T_String, ATTR_BGCOLOR},
1387 {ID_BODY, BodyLink, T_String, ATTR_LINK},
1388 {ID_BODY, BodyText, T_String, ATTR_TEXT},//### odd?
1389 {ID_BODY, BodyVLink, T_String, ATTR_VLINK},
1390 {ID_FORM, FormName, T_String, ATTR_NAME}, // NOT getString (IE gives empty string)
1391 {ID_FORM, FormAcceptCharset, T_String, ATTR_ACCEPT_CHARSET},
1392 {ID_FORM, FormAction, T_String, ATTR_ACTION},
1393 {ID_FORM, FormEncType, T_String, ATTR_ENCTYPE},
1394 {ID_FORM, FormMethod, T_String, ATTR_METHOD},
1395 {ID_FORM, FormTarget, T_String, ATTR_TARGET},
1396 {ID_SELECT, SelectDisabled, T_Bool, ATTR_DISABLED},
1397 {ID_SELECT, SelectMultiple, T_Bool, ATTR_MULTIPLE},
1398 {ID_SELECT, SelectSize, T_Int, ATTR_SIZE}, //toInt on attr, then number
1399 {ID_OPTGROUP, OptGroupDisabled, T_Bool, ATTR_DISABLED},
1400 {ID_OPTGROUP, OptGroupLabel, T_String, ATTR_LABEL},
1401 {ID_OPTION, OptionDefaultSelected, T_Bool, ATTR_SELECTED},
1402 {ID_OPTION, OptionDisabled, T_Bool, ATTR_DISABLED},
1403 {ID_OPTION, OptionLabel, T_String, ATTR_LABEL},
1404 {ID_INPUT, InputDefaultValue, T_String, ATTR_VALUE},
1405 {ID_INPUT, InputDefaultChecked, T_Bool, ATTR_CHECKED},
1406 {ID_INPUT, InputAccept, T_String, ATTR_ACCEPT},
1407 {ID_INPUT, InputAccessKey, T_String, ATTR_ACCESSKEY},
1408 {ID_INPUT, InputAlign, T_String, ATTR_ALIGN},
1409 {ID_INPUT, InputAlt, T_String, ATTR_ALT},
1410 {ID_INPUT, InputDisabled, T_Bool, ATTR_DISABLED},
1411 {ID_INPUT, InputMaxLength, T_Int, ATTR_MAXLENGTH},
1412 {ID_INPUT, InputReadOnly, T_Bool, ATTR_READONLY},
1413 {ID_INPUT, InputSize, T_Int, ATTR_SIZE},
1414 {ID_INPUT, InputSrc, T_URL, ATTR_SRC},
1415 {ID_INPUT, InputUseMap, T_String, ATTR_USEMAP},
1416 {ID_TEXTAREA, TextAreaAccessKey, T_String, ATTR_ACCESSKEY},
1417 {ID_TEXTAREA, TextAreaCols, T_Int, ATTR_COLS},
1418 {ID_TEXTAREA, TextAreaDisabled, T_Bool, ATTR_DISABLED},
1419 {ID_TEXTAREA, TextAreaReadOnly, T_Bool, ATTR_READONLY},
1420 {ID_TEXTAREA, TextAreaRows, T_Int, ATTR_ROWS},
1421 {ID_BUTTON, ButtonAccessKey, T_String, ATTR_ACCESSKEY},
1422 {ID_BUTTON, ButtonDisabled, T_Bool, ATTR_DISABLED},
1423 {ID_BUTTON, ButtonName, T_String, ATTR_NAME},
1424 {ID_BUTTON, ButtonValue, T_String, ATTR_VALUE},
1425 {ID_LABEL, LabelAccessKey, T_String, ATTR_ACCESSKEY},
1426 {ID_LABEL, LabelHtmlFor, T_String, ATTR_FOR},
1427 {ID_LEGEND, LegendAccessKey, T_String, ATTR_ACCESSKEY},
1428 {ID_LEGEND, LegendAlign, T_String, ATTR_ALIGN},
1429 {ID_UL, UListCompact, T_Bool, ATTR_COMPACT},
1430 {ID_UL, UListType, T_String, ATTR_TYPE},
1431 {ID_OL, OListCompact, T_Bool, ATTR_COMPACT},
1432 {ID_OL, OListStart, T_Int, ATTR_START},
1433 {ID_OL, OListType, T_String, ATTR_TYPE},
1434 {ID_DL, DListCompact, T_Bool, ATTR_COMPACT},
1435 {ID_DIR, DirectoryCompact, T_Bool, ATTR_COMPACT},
1436 {ID_MENU, MenuCompact, T_Bool, ATTR_COMPACT},
1437 {ID_LI, LIType, T_String, ATTR_TYPE},
1438 {ID_LI, LIValue, T_Int, ATTR_VALUE},
1439 {ID_DIV, DivAlign, T_String, ATTR_ALIGN},
1440 {ID_P, ParagraphAlign, T_String, ATTR_ALIGN},
1441 {NotApplicable, HeadingAlign, T_String, ATTR_ALIGN},
1442 {ID_BLOCKQUOTE, BlockQuoteCite, T_String, ATTR_CITE},
1443 {ID_Q, QuoteCite, T_String, ATTR_CITE},
1444 {ID_PRE, PreWidth, T_Int, ATTR_WIDTH},
1445 {ID_BR, BRClear, T_String, ATTR_CLEAR},
1446 {ID_BASEFONT, BaseFontColor, T_String, ATTR_COLOR},
1447 {ID_BASEFONT, BaseFontFace, T_String, ATTR_FACE},
1448 {ID_BASEFONT, BaseFontSize, T_Int, ATTR_SIZE},
1449 {ID_FONT, FontColor, T_String, ATTR_COLOR},
1450 {ID_FONT, FontFace, T_String, ATTR_FACE},
1451 {ID_FONT, FontSize, T_String, ATTR_SIZE},
1452 {ID_HR, HRAlign, T_String, ATTR_ALIGN},
1453 {ID_HR, HRNoShade, T_Bool, ATTR_NOSHADE},
1454 {ID_HR, HRSize, T_String, ATTR_SIZE},
1455 {ID_HR, HRWidth, T_String, ATTR_WIDTH},
1456 {NotApplicable, ModCite, T_String, ATTR_CITE},
1457 {NotApplicable, ModDateTime, T_String, ATTR_DATETIME},
1458 {ID_A, AnchorAccessKey, T_String, ATTR_ACCESSKEY},
1459 {ID_A, AnchorCharset, T_String, ATTR_CHARSET},
1460 {ID_A, AnchorCoords, T_String, ATTR_COORDS},
1461 {ID_A, AnchorHref, T_URL, ATTR_HREF},
1462 {ID_A, AnchorHrefLang, T_String, ATTR_HREFLANG},
1463 {ID_A, AnchorName, T_String, ATTR_NAME},
1464 {ID_A, AnchorRel, T_String, ATTR_REL},
1465 {ID_A, AnchorRev, T_String, ATTR_REV},
1466 {ID_A, AnchorShape, T_String, ATTR_SHAPE},
1467 {ID_A, AnchorTarget, T_String, ATTR_TARGET},
1468 {ID_A, AnchorType, T_String, ATTR_TYPE},
1469 {ID_IMG, ImageName, T_String, ATTR_NAME},
1470 {ID_IMG, ImageAlign, T_String, ATTR_ALIGN},
1471 {ID_IMG, ImageAlt, T_String, ATTR_ALT},
1472 {ID_IMG, ImageBorder, T_String, ATTR_BORDER},
1473 {ID_IMG, ImageHspace, T_Int, ATTR_HSPACE}, // ### return actual value
1474 {ID_IMG, ImageIsMap, T_Bool, ATTR_ISMAP},
1475 {ID_IMG, ImageLongDesc, T_String, ATTR_LONGDESC},
1476 {ID_IMG, ImageSrc, T_URL, ATTR_SRC},
1477 {ID_IMG, ImageUseMap, T_String, ATTR_USEMAP},
1478 {ID_IMG, ImageVspace, T_Int, ATTR_VSPACE}, // ### return actual value
1479 {ID_OBJECT, ObjectCode, T_String, ATTR_CODE},
1480 {ID_OBJECT, ObjectAlign, T_String, ATTR_ALIGN},
1481 {ID_OBJECT, ObjectArchive, T_String, ATTR_ARCHIVE},
1482 {ID_OBJECT, ObjectBorder, T_String, ATTR_BORDER},
1483 {ID_OBJECT, ObjectCodeBase, T_String, ATTR_CODEBASE},
1484 {ID_OBJECT, ObjectCodeType, T_String, ATTR_CODETYPE},
1485 {ID_OBJECT, ObjectData, T_URL, ATTR_DATA},
1486 {ID_OBJECT, ObjectDeclare, T_Bool, ATTR_DECLARE},
1487 {ID_OBJECT, ObjectHeight, T_String, ATTR_HEIGHT},
1488 {ID_OBJECT, ObjectHspace, T_Int, ATTR_HSPACE},
1489 {ID_OBJECT, ObjectName, T_String, ATTR_NAME},
1490 {ID_OBJECT, ObjectStandby, T_String, ATTR_STANDBY},
1491 {ID_OBJECT, ObjectType, T_String, ATTR_TYPE},
1492 {ID_OBJECT, ObjectUseMap, T_String, ATTR_USEMAP},
1493 {ID_OBJECT, ObjectVspace, T_Int, ATTR_VSPACE},
1494 {ID_OBJECT, ObjectWidth, T_String, ATTR_WIDTH},
1495 {ID_PARAM, ParamName, T_String, ATTR_NAME},
1496 {ID_PARAM, ParamType, T_String, ATTR_TYPE},
1497 {ID_PARAM, ParamValue, T_String, ATTR_VALUE},
1498 {ID_PARAM, ParamValueType, T_String, ATTR_VALUETYPE},
1499 {ID_APPLET, AppletAlign, T_String, ATTR_ALIGN},
1500 {ID_APPLET, AppletAlt, T_String, ATTR_ALT},
1501 {ID_APPLET, AppletArchive, T_String, ATTR_ARCHIVE},
1502 {ID_APPLET, AppletCode, T_String, ATTR_CODE},
1503 {ID_APPLET, AppletCodeBase, T_String, ATTR_CODEBASE},
1504 {ID_APPLET, AppletHeight, T_String, ATTR_HEIGHT},
1505 {ID_APPLET, AppletHspace, T_Int, ATTR_HSPACE},
1506 {ID_APPLET, AppletName, T_String, ATTR_NAME},
1507 {ID_APPLET, AppletObject, T_String, ATTR_OBJECT},
1508 {ID_APPLET, AppletVspace, T_Int, ATTR_VSPACE},
1509 {ID_APPLET, AppletWidth, T_String, ATTR_WIDTH},
1510 {ID_MAP, MapName, T_String, ATTR_NAME},
1511 {ID_MAP, MapAreas, T_Coll, HTMLCollectionImpl::MAP_AREAS},
1512 {ID_AREA, AreaAccessKey, T_String, ATTR_ACCESSKEY},
1513 {ID_AREA, AreaAlt, T_String, ATTR_ALT},
1514 {ID_AREA, AreaCoords, T_String, ATTR_COORDS},
1515 {ID_AREA, AreaHref, T_URL, ATTR_HREF},
1516 {ID_AREA, AreaNoHref, T_Bool, ATTR_NOHREF},
1517 {ID_AREA, AreaShape, T_String, ATTR_SHAPE},
1518 {ID_AREA, AreaTarget, T_String, ATTR_TARGET},
1519 {ID_SCRIPT, ScriptHtmlFor, T_Res, NotApplicable},
1520 {ID_SCRIPT, ScriptEvent, T_Res, NotApplicable},
1521 {ID_SCRIPT, ScriptCharset, T_String, ATTR_CHARSET},
1522 {ID_SCRIPT, ScriptDefer, T_Bool, ATTR_DEFER},
1523 {ID_SCRIPT, ScriptSrc, T_URL, ATTR_SRC},
1524 {ID_SCRIPT, ScriptType, T_String, ATTR_TYPE},
1525 {ID_TABLE, TableAlign, T_String, ATTR_ALIGN},
1526 {ID_TABLE, TableBgColor, T_String, ATTR_BGCOLOR},
1527 {ID_TABLE, TableBorder, T_String, ATTR_BORDER},
1528 {ID_TABLE, TableCellPadding, T_String, ATTR_CELLPADDING},
1529 {ID_TABLE, TableCellSpacing, T_String, ATTR_CELLSPACING},
1530 {ID_TABLE, TableFrame, T_String, ATTR_FRAME},
1531 {ID_TABLE, TableRules, T_String, ATTR_RULES},
1532 {ID_TABLE, TableSummary, T_String, ATTR_SUMMARY},
1533 {ID_TABLE, TableWidth, T_String, ATTR_WIDTH},
1534 {ID_TABLE, TableRows, T_Coll, HTMLCollectionImpl::TABLE_ROWS},
1535 {ID_TABLE, TableTBodies, T_Coll, HTMLCollectionImpl::TABLE_TBODIES},
1536 {ID_CAPTION, TableCaptionAlign, T_String, ATTR_ALIGN},
1537 {NotApplicable, TableColAlign, T_String, ATTR_ALIGN}, //Col/ColGroup
1538 {NotApplicable, TableColCh, T_String, ATTR_CHAR},
1539 {NotApplicable, TableColChOff, T_String, ATTR_CHAROFF},
1540 {NotApplicable, TableColSpan, T_Int, ATTR_SPAN},
1541 {NotApplicable, TableColVAlign, T_String, ATTR_VALIGN},
1542 {NotApplicable, TableColWidth, T_String, ATTR_WIDTH},
1543 {NotApplicable, TableSectionAlign, T_String, ATTR_ALIGN}, //THead/TBody/TFoot
1544 {NotApplicable, TableSectionCh, T_String, ATTR_CHAR},
1545 {NotApplicable, TableSectionChOff, T_String, ATTR_CHAROFF},
1546 {NotApplicable, TableSectionVAlign, T_String, ATTR_VALIGN},
1547 {NotApplicable, TableSectionRows, T_Coll, HTMLCollectionImpl::TSECTION_ROWS},
1548 {ID_TR, TableRowAlign, T_String, ATTR_ALIGN}, //TR
1549 {ID_TR, TableRowBgColor, T_String, ATTR_BGCOLOR},
1550 {ID_TR, TableRowCh, T_String, ATTR_CHAR},
1551 {ID_TR, TableRowChOff, T_String, ATTR_CHAROFF},
1552 {ID_TR, TableRowVAlign, T_String, ATTR_VALIGN},
1553 {ID_TR, TableRowCells, T_Coll, HTMLCollectionImpl::TR_CELLS},
1554 {NotApplicable, TableCellAbbr, T_String, ATTR_ABBR}, //TD/TH
1555 {NotApplicable, TableCellAlign, T_String, ATTR_ALIGN},
1556 {NotApplicable, TableCellAxis, T_String, ATTR_AXIS},
1557 {NotApplicable, TableCellBgColor, T_String, ATTR_BGCOLOR},
1558 {NotApplicable, TableCellCh, T_String, ATTR_CHAR},
1559 {NotApplicable, TableCellChOff, T_String, ATTR_CHAROFF},
1560 {NotApplicable, TableCellColSpan, T_Int, ATTR_COLSPAN},
1561 {NotApplicable, TableCellHeaders, T_String, ATTR_HEADERS},
1562 {NotApplicable, TableCellHeight, T_String, ATTR_HEIGHT},
1563 {NotApplicable, TableCellNoWrap, T_Bool, ATTR_NOWRAP},
1564 {NotApplicable, TableCellRowSpan, T_Int, ATTR_ROWSPAN},
1565 {NotApplicable, TableCellScope, T_String, ATTR_SCOPE},
1566 {NotApplicable, TableCellVAlign, T_String, ATTR_VALIGN},
1567 {NotApplicable, TableCellWidth, T_String, ATTR_WIDTH},
1568 {ID_FRAMESET, FrameSetCols, T_String, ATTR_COLS},
1569 {ID_FRAMESET, FrameSetRows, T_String, ATTR_ROWS},
1570 {ID_LAYER, LayerTop, T_Int, ATTR_TOP},
1571 {ID_LAYER, LayerLeft, T_Int, ATTR_LEFT},
1572 {ID_LAYER, LayerVisibility, T_StrOrNl, ATTR_VISIBILITY},
1573 {ID_LAYER, LayerBgColor, T_StrOrNl, ATTR_BGCOLOR},
1574 {ID_LAYER, LayerLayers, T_Coll, HTMLCollectionImpl::DOC_LAYERS},
1575 {ID_FRAME, FrameFrameBorder, T_String, ATTR_FRAMEBORDER},
1576 {ID_FRAME, FrameLongDesc, T_String, ATTR_LONGDESC},
1577 {ID_FRAME, FrameMarginHeight, T_String, ATTR_MARGINHEIGHT},
1578 {ID_FRAME, FrameMarginWidth, T_String, ATTR_MARGINWIDTH},
1579 {ID_FRAME, FrameName, T_String, ATTR_NAME},
1580 {ID_FRAME, FrameNoResize, T_Bool, ATTR_NORESIZE},
1581 {ID_FRAME, FrameScrolling, T_String, ATTR_SCROLLING},
1582 {ID_FRAME, FrameSrc, T_URL, ATTR_SRC},
1583 {ID_FRAME, FrameLocation, BoundPropType(T_String | T_ReadOnly), ATTR_SRC},
1584 {ID_IFRAME, IFrameFrameBorder, T_String, ATTR_FRAMEBORDER},
1585 {ID_IFRAME, IFrameLongDesc, T_String, ATTR_LONGDESC},
1586 {ID_IFRAME, IFrameMarginHeight, T_String, ATTR_MARGINHEIGHT},
1587 {ID_IFRAME, IFrameMarginWidth, T_String, ATTR_MARGINWIDTH},
1588 {ID_IFRAME, IFrameName, T_String, ATTR_NAME},
1589 {ID_IFRAME, IFrameScrolling, T_String, ATTR_SCROLLING},
1590 {ID_IFRAME, IFrameSrc, T_URL, ATTR_SRC},
1591 {ID_IFRAME, IFrameAlign, T_String, ATTR_ALIGN},
1592 {ID_IFRAME, IFrameHeight, T_String, ATTR_HEIGHT},
1593 {ID_IFRAME, IFrameWidth, T_String, ATTR_WIDTH},
1594 {NotApplicable, ElementId, T_String, ATTR_ID},
1595 {NotApplicable, ElementTitle, T_String, ATTR_TITLE},
1596 {NotApplicable, ElementLang, T_String, ATTR_LANG},
1597 {NotApplicable, ElementDir, T_String, ATTR_DIR},
1598 {NotApplicable, ElementClassName, T_String, ATTR_CLASS},
1599 {NotApplicable, ElementChildren, T_Coll, HTMLCollectionImpl::NODE_CHILDREN},
1600 {0, 0, T_Res, 0},
1601 };
1602
1603 QHash<int, const HTMLElement::BoundPropInfo *> *HTMLElement::s_boundPropInfo = nullptr;
1604
boundPropInfo()1605 QHash<int, const HTMLElement::BoundPropInfo *> *HTMLElement::boundPropInfo()
1606 {
1607 if (!s_boundPropInfo) {
1608 s_boundPropInfo = new QHash<int, const BoundPropInfo *>();
1609 for (int c = 0; bpTable[c].elId; ++c) {
1610 s_boundPropInfo->insert(bpTable[c].token, &bpTable[c]);
1611 }
1612 }
1613 return s_boundPropInfo;
1614 }
1615
getURLArg(unsigned id) const1616 QString KJS::HTMLElement::getURLArg(unsigned id) const
1617 {
1618 const DOMString rel = impl()->getAttribute(id).trimSpaces();
1619 return !rel.isNull() ? impl()->document()->completeURL(rel.string()) : QString();
1620 }
1621
toHTMLElement(JSValue * val)1622 DOM::HTMLElementImpl *toHTMLElement(JSValue *val)
1623 {
1624 DOM::ElementImpl *e = toElement(val);
1625 if (e && e->isHTMLElement()) {
1626 return static_cast<HTMLElementImpl *>(e);
1627 }
1628 return nullptr;
1629 }
1630
toHTMLTableCaptionElement(JSValue * val)1631 DOM::HTMLTableCaptionElementImpl *toHTMLTableCaptionElement(JSValue *val)
1632 {
1633 DOM::ElementImpl *e = toElement(val);
1634 if (e && e->id() == ID_CAPTION) {
1635 return static_cast<HTMLTableCaptionElementImpl *>(e);
1636 }
1637 return nullptr;
1638 }
1639
toHTMLTableSectionElement(JSValue * val)1640 HTMLTableSectionElementImpl *toHTMLTableSectionElement(JSValue *val)
1641 {
1642 DOM::ElementImpl *e = toElement(val);
1643 if (e && (e->id() == ID_THEAD || e->id() == ID_TBODY || e->id() == ID_TFOOT)) {
1644 return static_cast<HTMLTableSectionElementImpl *>(e);
1645 }
1646 return nullptr;
1647 }
1648
handleBoundRead(ExecState * exec,int token) const1649 JSValue *KJS::HTMLElement::handleBoundRead(ExecState *exec, int token) const
1650 {
1651 const BoundPropInfo *prop = boundPropInfo()->value(token);
1652 if (!prop) {
1653 return nullptr;
1654 }
1655
1656 assert(prop->elId == NotApplicable || prop->elId == impl()->id());
1657
1658 switch (prop->type & ~T_ReadOnly) {
1659 case T_String:
1660 return jsString(impl()->getAttribute(prop->attrId));
1661 case T_StrOrNl:
1662 return getStringOrNull(impl()->getAttribute(prop->attrId));
1663 case T_Bool:
1664 return jsBoolean(!impl()->getAttribute(prop->attrId).isNull());
1665 case T_Int:
1666 return jsNumber(impl()->getAttribute(prop->attrId).toInt());
1667 case T_URL:
1668 return jsString(getURLArg(prop->attrId));
1669 case T_Res:
1670 return jsString("");
1671 case T_Coll:
1672 return getHTMLCollection(exec, new HTMLCollectionImpl(impl(), prop->attrId));
1673 }
1674 assert(0);
1675 return nullptr;
1676 }
1677
ourWindow() const1678 KJS::Window *KJS::HTMLElement::ourWindow() const
1679 {
1680 KHTMLPart *part = impl()->document()->part();
1681 if (part) {
1682 return Window::retrieveWindow(part);
1683 } else {
1684 return nullptr;
1685 }
1686 }
1687
getWindowListener(ExecState * exec,int ev) const1688 JSValue *KJS::HTMLElement::getWindowListener(ExecState *exec, int ev) const
1689 {
1690 if (KJS::Window *win = ourWindow()) {
1691 return win->getListener(exec, ev);
1692 } else {
1693 return jsNull();
1694 }
1695 }
1696
setWindowListener(ExecState * exec,int ev,JSValue * val) const1697 void KJS::HTMLElement::setWindowListener(ExecState *exec, int ev, JSValue *val) const
1698 {
1699 if (KJS::Window *win = ourWindow()) {
1700 win->setListener(exec, ev, val);
1701 }
1702 }
1703
getValueProperty(ExecState * exec,int token) const1704 JSValue *KJS::HTMLElement::getValueProperty(ExecState *exec, int token) const
1705 {
1706 JSValue *cand = handleBoundRead(exec, token);
1707 if (cand) {
1708 return cand;
1709 }
1710
1711 DOM::HTMLElementImpl &element = *impl();
1712 switch (element.id()) {
1713 case ID_LINK: {
1714 DOM::HTMLLinkElementImpl &link = static_cast<DOM::HTMLLinkElementImpl &>(element);
1715 switch (token) {
1716 case LinkSheet: return getDOMStyleSheet(exec, link.sheet());
1717 }
1718 }
1719 break;
1720 case ID_TITLE: {
1721 DOM::HTMLTitleElementImpl &title = static_cast<DOM::HTMLTitleElementImpl &>(element);
1722 switch (token) {
1723 case TitleText: return jsString(title.text());
1724 }
1725 }
1726 break;
1727 case ID_ISINDEX: {
1728 DOM::HTMLIsIndexElementImpl &isindex = static_cast<DOM::HTMLIsIndexElementImpl &>(element);
1729 switch (token) {
1730 case IsIndexForm: return getDOMNode(exec, isindex.form()); // type HTMLFormElement
1731 case IsIndexPrompt: return jsString(isindex.prompt());
1732 }
1733 }
1734 break;
1735 case ID_STYLE: {
1736 DOM::HTMLStyleElementImpl &style = static_cast<DOM::HTMLStyleElementImpl &>(element);
1737 switch (token) {
1738 case StyleSheet: return getDOMStyleSheet(exec, style.sheet());
1739 }
1740 }
1741 break;
1742 case ID_BODY: {
1743 switch (token) {
1744 case BodyOnLoad:
1745 return getWindowListener(exec, DOM::EventImpl::LOAD_EVENT);
1746 case BodyOnError:
1747 return getWindowListener(exec, DOM::EventImpl::ERROR_EVENT);
1748 case BodyOnBlur:
1749 return getWindowListener(exec, DOM::EventImpl::BLUR_EVENT);
1750 case BodyOnFocus:
1751 return getWindowListener(exec, DOM::EventImpl::FOCUS_EVENT);
1752 case BodyOnMessage:
1753 return getWindowListener(exec, DOM::EventImpl::MESSAGE_EVENT);
1754 case BodyOnHashChange:
1755 return getWindowListener(exec, DOM::EventImpl::HASHCHANGE_EVENT);
1756
1757 }
1758 }
1759 break;
1760
1761 case ID_FRAMESET: {
1762 switch (token) {
1763 case FrameSetOnMessage:
1764 return getWindowListener(exec, DOM::EventImpl::MESSAGE_EVENT);
1765 }
1766 }
1767 break;
1768
1769 case ID_FORM: {
1770 DOM::HTMLFormElementImpl &form = static_cast<DOM::HTMLFormElementImpl &>(element);
1771 switch (token) {
1772 case FormElements: return getHTMLCollection(exec, form.elements());
1773 case FormLength: return jsNumber(form.length());
1774 }
1775 }
1776 break;
1777
1778 case ID_SELECT: {
1779 DOM::HTMLSelectElementImpl &select = static_cast<DOM::HTMLSelectElementImpl &>(element);
1780 switch (token) {
1781 case SelectType: return jsString(select.type());
1782 case SelectSelectedIndex: return jsNumber(select.selectedIndex());
1783 case SelectValue: return jsString(select.value());
1784 case SelectLength: return jsNumber(select.length());
1785 case SelectForm: return getDOMNode(exec, select.form()); // type HTMLFormElement
1786 case SelectOptions: return getSelectHTMLCollection(exec, select.options(), &select); // type HTMLCollection
1787 case SelectName: return jsString(select.name());
1788 }
1789 }
1790 break;
1791 case ID_OPTION: {
1792 DOM::HTMLOptionElementImpl &option = static_cast<DOM::HTMLOptionElementImpl &>(element);
1793 switch (token) {
1794 case OptionForm: return getDOMNode(exec, option.form()); // type HTMLFormElement
1795 case OptionText: return jsString(option.text());
1796 case OptionIndex: return jsNumber(option.index());
1797 case OptionSelected: return jsBoolean(option.selected());
1798 case OptionValue: return jsString(option.value());
1799 }
1800 }
1801 break;
1802
1803 case ID_INPUT: {
1804 DOM::HTMLInputElementImpl &input = static_cast<DOM::HTMLInputElementImpl &>(element);
1805 switch (token) {
1806 case InputForm: return getDOMNode(exec, input.form()); // type HTMLFormElement
1807 case InputChecked: return jsBoolean(input.checked());
1808 case InputIndeterminate: return jsBoolean(input.indeterminate());
1809 case InputName: return jsString(input.name()); // NOT getString (IE gives empty string)
1810 case InputType: return jsString(input.type());
1811 case InputValue: return jsString(input.value());
1812 case InputSelectionStart: {
1813 long val = input.selectionStart();
1814 if (val != -1) {
1815 return jsNumber(val);
1816 } else {
1817 return jsUndefined();
1818 }
1819 }
1820 case InputSelectionEnd: {
1821 long val = input.selectionEnd();
1822 if (val != -1) {
1823 return jsNumber(val);
1824 } else {
1825 return jsUndefined();
1826 }
1827 }
1828 case InputPlaceholder: {
1829 return jsString(input.placeholder());
1830 }
1831 }
1832 }
1833 break;
1834 case ID_TEXTAREA: {
1835 DOM::HTMLTextAreaElementImpl &textarea = static_cast<DOM::HTMLTextAreaElementImpl &>(element);
1836 switch (token) {
1837 case TextAreaDefaultValue: return jsString(textarea.defaultValue());
1838 case TextAreaForm: return getDOMNode(exec, textarea.form()); // type HTMLFormElement
1839 case TextAreaName: return jsString(textarea.name());
1840 case TextAreaType: return jsString(textarea.type());
1841 case TextAreaValue: return jsString(textarea.value());
1842 case TextAreaSelectionStart: return jsNumber(textarea.selectionStart());
1843 case TextAreaSelectionEnd: return jsNumber(textarea.selectionEnd());
1844 case TextAreaTextLength: return jsNumber(textarea.textLength());
1845 case TextAreaPlaceholder: return jsString(textarea.placeholder());
1846 }
1847 }
1848 break;
1849
1850 case ID_BUTTON: {
1851 DOM::HTMLButtonElementImpl &button = static_cast<DOM::HTMLButtonElementImpl &>(element);
1852 switch (token) {
1853 case ButtonForm: return getDOMNode(exec, button.form()); // type HTMLFormElement
1854 case ButtonType: return jsString(button.type());
1855 }
1856 }
1857 break;
1858 case ID_LABEL: {
1859 DOM::HTMLLabelElementImpl &label = static_cast<DOM::HTMLLabelElementImpl &>(element);
1860 switch (token) {
1861 case LabelForm: return getDOMNode(exec, label.form()); // type HTMLFormElement
1862 }
1863 }
1864 break;
1865 case ID_FIELDSET: {
1866 DOM::HTMLFieldSetElementImpl &fieldSet = static_cast<DOM::HTMLFieldSetElementImpl &>(element);
1867 switch (token) {
1868 case FieldSetForm: return getDOMNode(exec, fieldSet.form()); // type HTMLFormElement
1869 }
1870 }
1871 break;
1872 case ID_LEGEND: {
1873 DOM::HTMLLegendElementImpl &legend = static_cast<DOM::HTMLLegendElementImpl &>(element);
1874 switch (token) {
1875 case LegendForm: return getDOMNode(exec, legend.form()); // type HTMLFormElement
1876 }
1877 }
1878 break;
1879 case ID_A: {
1880 DOM::HTMLAnchorElementImpl &anchor = static_cast<DOM::HTMLAnchorElementImpl &>(element);
1881 QString href = getURLArg(ATTR_HREF);
1882 switch (token) {
1883 case AnchorHash: {
1884 const QString encodedHash = QUrl(href).fragment(QUrl::FullyEncoded);
1885 if (encodedHash.isEmpty()) {
1886 return jsString("");
1887 }
1888 return jsString(QLatin1Char('#') + encodedHash);
1889 }
1890 case AnchorHost: return jsString(QUrl(href).host());
1891 case AnchorHostname: {
1892 QUrl url(href);
1893 // qCDebug(KHTML_LOG) << "anchor::hostname uses:" <<url.toString();
1894 if (url.port() <= 0) {
1895 return jsString(url.host());
1896 } else {
1897 return jsString(url.host() + ":" + QString::number(url.port()));
1898 }
1899 }
1900 case AnchorPathName: return jsString(QUrl(href).path());
1901 case AnchorPort: {
1902 int port = QUrl(href).port();
1903 if (port > 0) {
1904 return jsString(QString::number(port));
1905 }
1906 return jsString("");
1907 }
1908 case AnchorProtocol: return jsString(QUrl(href).scheme() + ":");
1909 case AnchorSearch: {
1910 QUrl u(href);
1911 QString q = u.query();
1912 if (q.length() == 1) {
1913 return jsString("");
1914 }
1915 return jsString(q);
1916 }
1917 // Not specified in http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/a.asp
1918 // Mozilla returns the inner text.
1919 case AnchorText: return jsString(anchor.innerText());
1920 }
1921 }
1922 break;
1923 case ID_IMG: {
1924 DOM::HTMLImageElementImpl &image = static_cast<DOM::HTMLImageElementImpl &>(element);
1925 switch (token) {
1926 case ImageComplete: return jsBoolean(image.complete());
1927 case ImageHeight: return jsNumber(image.height());
1928 case ImageWidth: return jsNumber(image.width());
1929 case ImageX: return jsNumber(image.x());
1930 case ImageY: return jsNumber(image.y());
1931 }
1932 }
1933 break;
1934 case ID_CANVAS: {
1935 DOM::HTMLCanvasElementImpl &canvas = static_cast<DOM::HTMLCanvasElementImpl &>(element);
1936 switch (token) {
1937 case CanvasHeight: return jsNumber(canvas.height());
1938 case CanvasWidth: return jsNumber(canvas.width());
1939 }
1940 }
1941 break;
1942 case ID_OBJECT: {
1943 DOM::HTMLObjectElementImpl &object = static_cast<DOM::HTMLObjectElementImpl &>(element);
1944 switch (token) {
1945 case ObjectForm: return getDOMNode(exec, object.form()); // type HTMLFormElement
1946 case ObjectContentDocument: return checkNodeSecurity(exec, object.contentDocument()) ?
1947 getDOMNode(exec, object.contentDocument()) : jsUndefined();
1948 }
1949 }
1950 break;
1951 case ID_AREA: {
1952 DOM::HTMLAreaElementImpl &area = static_cast<DOM::HTMLAreaElementImpl &>(element);
1953 // Everything here needs href
1954 DOM::Document doc = area.ownerDocument();
1955 DOM::DOMString href = getURLArg(ATTR_HREF);
1956 QUrl url;
1957 if (!href.isNull()) {
1958 url = QUrl(href.string());
1959 if (href.isEmpty()) {
1960 url = url.adjusted(QUrl::RemoveFilename); // href="" clears the filename (in IE)
1961 }
1962 }
1963 switch (token) {
1964 case AreaHref:
1965 return jsString(url.url());
1966 case AreaHash: {
1967 const QString encodedHash = url.fragment(QUrl::FullyEncoded);
1968 if (encodedHash.isEmpty()) {
1969 return jsString("");
1970 }
1971 return jsString(QLatin1Char('#') + encodedHash);
1972 }
1973 case AreaHost: return jsString(url.host());
1974 case AreaHostName: {
1975 if (url.port() <= 0) {
1976 return jsString(url.host());
1977 } else {
1978 return jsString(url.host() + ":" + QString::number(url.port()));
1979 }
1980 }
1981 case AreaPathName: {
1982 return jsString(url.path());
1983 }
1984 case AreaPort: return jsString(QString::number(url.port()));
1985 case AreaProtocol: return jsString(url.isEmpty() ? "" : QString(url.scheme() + ":"));
1986 case AreaSearch: return jsString(url.query());
1987 }
1988 }
1989 break;
1990 case ID_SCRIPT: {
1991 DOM::HTMLScriptElementImpl &script = static_cast<DOM::HTMLScriptElementImpl &>(element);
1992 switch (token) {
1993 case ScriptText: return jsString(script.text());
1994 }
1995 }
1996 break;
1997 case ID_TABLE: {
1998 DOM::HTMLTableElementImpl &table = static_cast<DOM::HTMLTableElementImpl &>(element);
1999 switch (token) {
2000 case TableCaption: return getDOMNode(exec, table.caption()); // type HTMLTableCaptionElement
2001 case TableTHead: return getDOMNode(exec, table.tHead()); // type HTMLTableSectionElement
2002 case TableTFoot: return getDOMNode(exec, table.tFoot()); // type HTMLTableSectionElement
2003 }
2004 }
2005 break;
2006 case ID_TR: {
2007 DOM::HTMLTableRowElementImpl &tableRow = static_cast<DOM::HTMLTableRowElementImpl &>(element);
2008 switch (token) {
2009 case TableRowRowIndex: return jsNumber(tableRow.rowIndex());
2010 case TableRowSectionRowIndex: return jsNumber(tableRow.sectionRowIndex());
2011 }
2012 }
2013 break;
2014 case ID_TH:
2015 case ID_TD: {
2016 DOM::HTMLTableCellElementImpl &tableCell = static_cast<DOM::HTMLTableCellElementImpl &>(element);
2017 switch (token) {
2018 case TableCellCellIndex: return jsNumber(tableCell.cellIndex());
2019 }
2020 }
2021 break;
2022 case ID_LAYER: {
2023 //DOM::HTMLLayerElementImpl& layerElement = static_cast<DOM::HTMLLayerElementImpl&>(element);
2024 switch (token) {
2025 /*case LayerClip: return getLayerClip(exec, layerElement); */
2026 case LayerDocument: return jsUndefined();
2027 }
2028 }
2029 break;
2030 case ID_FRAME: {
2031 DOM::HTMLFrameElementImpl &frameElement = static_cast<DOM::HTMLFrameElementImpl &>(element);
2032 switch (token) {
2033 case FrameContentDocument: return checkNodeSecurity(exec, frameElement.contentDocument()) ?
2034 getDOMNode(exec, frameElement.contentDocument()) : jsUndefined();
2035 case FrameContentWindow: {
2036 KHTMLPart *part = frameElement.contentPart();
2037 if (part) {
2038 Window *w = Window::retrieveWindow(part);
2039 if (w) {
2040 return w;
2041 }
2042 }
2043 return jsUndefined();
2044 }
2045 // IE only
2046 case FrameWidth:
2047 case FrameHeight: {
2048 frameElement.document()->updateLayout();
2049 khtml::RenderObject *r = frameElement.renderer();
2050 return jsNumber(r ? (token == FrameWidth ? r->width() : r->height()) : 0);
2051 }
2052 }
2053 }
2054 break;
2055 case ID_IFRAME: {
2056 DOM::HTMLIFrameElementImpl &iFrame = static_cast<DOM::HTMLIFrameElementImpl &>(element);
2057 switch (token) {
2058 case IFrameContentDocument: return checkNodeSecurity(exec, iFrame.contentDocument()) ?
2059 getDOMNode(exec, iFrame.contentDocument()) : jsUndefined();
2060 case IFrameContentWindow: {
2061 KHTMLPart *part = iFrame.contentPart();
2062 if (part) {
2063 Window *w = Window::retrieveWindow(part);
2064 if (w) {
2065 return w;
2066 }
2067 }
2068 return jsUndefined();
2069 }
2070 }
2071 break;
2072 }
2073 } // xemacs (or arnt) could be a bit smarter when it comes to indenting switch()es ;)
2074 // it is not arnt to blame - it is the original Stroustrup style we like :) (Dirk)
2075
2076 // generic properties
2077 switch (token) {
2078 case ElementInnerHTML:
2079 return jsString(element.innerHTML());
2080 case ElementInnerText:
2081 return jsString(element.innerText());
2082 case ElementDocument:
2083 return getDOMNode(exec, element.ownerDocument());
2084 case ElementAll:
2085 // Disable element.all when we try to be Netscape-compatible
2086 if (exec->dynamicInterpreter()->compatMode() == Interpreter::NetscapeCompat) {
2087 return jsUndefined();
2088 } else if (exec->dynamicInterpreter()->compatMode() == Interpreter::IECompat) {
2089 return getHTMLCollection(exec, new HTMLCollectionImpl(&element, HTMLCollectionImpl::DOC_ALL));
2090 } else { // Enabled but hidden by default
2091 return getHTMLCollection(exec, new HTMLCollectionImpl(&element, HTMLCollectionImpl::DOC_ALL), true);
2092 }
2093 case ElementTabIndex:
2094 return jsNumber(element.tabIndex());
2095 // ### what about style? or is this used instead for DOM2 stylesheets?
2096 case ElementContentEditable:
2097 return jsString(element.contentEditable());
2098 case ElementIsContentEditable:
2099 return jsBoolean(element.isContentEditable());
2100 }
2101 qCCritical(KHTML_LOG) << "HTMLElement::getValueProperty unhandled token " << token;
2102 return jsUndefined();
2103 }
2104
toString(ExecState * exec) const2105 UString KJS::HTMLElement::toString(ExecState *exec) const
2106 {
2107 if (impl()->id() == ID_A) {
2108 return UString(getURLArg(ATTR_HREF));
2109 }
2110 #if 0 // ### debug stuff?
2111 else if (impl()->id() == ID_APPLET) {
2112 KParts::LiveConnectExtension *lc = getLiveConnectExtension(*impl());
2113 QStringList qargs;
2114 QString retvalue;
2115 KParts::LiveConnectExtension::Type rettype;
2116 unsigned long retobjid;
2117 if (lc && lc->call(0, "hashCode", qargs, rettype, retobjid, retvalue)) {
2118 QString str("[object APPLET ref=");
2119 return UString(str + retvalue + QString("]"));
2120 }
2121 }
2122 #endif
2123 else if (impl()->id() == ID_IMG) {
2124 DOMString alt = impl()->getAttribute(ATTR_ALT);
2125 if (!alt.isEmpty()) {
2126 return UString(alt) + " " + DOMElement::toString(exec);
2127 }
2128 }
2129 return DOMElement::toString(exec);
2130 }
2131
getForm(const DOM::HTMLElementImpl * element)2132 static DOM::HTMLFormElementImpl *getForm(const DOM::HTMLElementImpl *element)
2133 {
2134 switch (element->id()) {
2135 case ID_ISINDEX:
2136 case ID_SELECT:
2137 case ID_OPTION:
2138 case ID_INPUT:
2139 case ID_TEXTAREA:
2140 case ID_LABEL:
2141 case ID_FIELDSET:
2142 case ID_LEGEND: {
2143 const DOM::HTMLGenericFormElementImpl *fEl = static_cast<const HTMLGenericFormElementImpl *>(element);
2144 return fEl->form();
2145 }
2146 case ID_OBJECT: {
2147 const DOM::HTMLObjectElementImpl *oEl = static_cast<const HTMLObjectElementImpl *>(element);
2148 return oEl->form();
2149 }
2150 default:
2151 return nullptr;
2152 }
2153 }
2154
pushEventHandlerScope(ExecState * exec,ScopeChain & scope) const2155 void KJS::HTMLElement::pushEventHandlerScope(ExecState *exec, ScopeChain &scope) const
2156 {
2157 DOM::HTMLElementImpl &element = *impl();
2158
2159 // The document is put on first, fall back to searching it only after the element and form.
2160 scope.push(static_cast<JSObject *>(getDOMNode(exec, element.document())));
2161
2162 // The form is next, searched before the document, but after the element itself.
2163 DOM::HTMLFormElementImpl *formElt;
2164
2165 // First try to obtain the form from the element itself. We do this to deal with
2166 // the malformed case where <form>s aren't in our parent chain (e.g., when they were inside
2167 // <table> or <tbody>.
2168 formElt = getForm(impl());
2169 if (formElt) {
2170 scope.push(static_cast<JSObject *>(getDOMNode(exec, formElt)));
2171 } else {
2172 DOM::NodeImpl *form = element.parentNode();
2173 while (form && form->id() != ID_FORM) {
2174 form = form->parentNode();
2175 }
2176
2177 if (form) {
2178 scope.push(static_cast<JSObject *>(getDOMNode(exec, form)));
2179 }
2180 }
2181
2182 // The element is on top, searched first.
2183 scope.push(static_cast<JSObject *>(getDOMNode(exec, &element)));
2184 }
2185
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)2186 JSValue *KJS::HTMLElementFunction::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
2187 {
2188 KJS_CHECK_THIS(HTMLElement, thisObj);
2189 DOMExceptionTranslator exception(exec);
2190
2191 #ifdef KJS_VERBOSE
2192 qCDebug(KHTML_LOG) << "KJS::HTMLElementFunction::callAsFunction ";
2193 #endif
2194 DOM::HTMLElementImpl &element = *static_cast<KJS::HTMLElement *>(thisObj)->impl();
2195
2196 switch (element.id()) {
2197 case ID_FORM: {
2198 DOM::HTMLFormElementImpl &form = static_cast<DOM::HTMLFormElementImpl &>(element);
2199 if (id == KJS::HTMLElement::FormSubmit) {
2200
2201 KHTMLPart *part = element.document()->part();
2202 KHTMLSettings::KJSWindowOpenPolicy policy = KHTMLSettings::KJSWindowOpenAllow;
2203 if (part) {
2204 policy = part->settings()->windowOpenPolicy(part->url().host());
2205 }
2206
2207 bool block = false;
2208 if (policy != KHTMLSettings::KJSWindowOpenAllow) {
2209 block = true;
2210
2211 // if this is a form without a target, don't block
2212 if (form.target().isEmpty()) {
2213 block = false;
2214 }
2215
2216 QString caption;
2217
2218 // if there is a frame with the target name, don't block
2219 if (part) {
2220 if (!part->url().host().isEmpty()) {
2221 caption = part->url().host() + " - ";
2222 }
2223
2224 if (Window::targetIsExistingWindow(part, form.target().string())) {
2225 block = false;
2226 }
2227 }
2228
2229 if (block && policy == KHTMLSettings::KJSWindowOpenAsk && part) {
2230 if (part) {
2231 emit part->browserExtension()->requestFocus(part);
2232 }
2233 caption += i18n("Confirmation: JavaScript Popup");
2234 if (KMessageBox::questionYesNo(part->view(), form.action().isEmpty() ?
2235 i18n("This site is submitting a form which will open up a new browser "
2236 "window via JavaScript.\n"
2237 "Do you want to allow the form to be submitted?") :
2238 i18n("<qt>This site is submitting a form which will open <p>%1</p> in a new browser window via JavaScript.<br />"
2239 "Do you want to allow the form to be submitted?</qt>", KStringHandler::csqueeze(form.action().string(), 100)),
2240 caption, KGuiItem(i18n("Allow")), KGuiItem(i18n("Do Not Allow"))) == KMessageBox::Yes) {
2241 block = false;
2242 }
2243
2244 } else if (block && policy == KHTMLSettings::KJSWindowOpenSmart) {
2245 if (static_cast<KJS::ScriptInterpreter *>(exec->dynamicInterpreter())->isWindowOpenAllowed()) {
2246 // This submission has been triggered by the user
2247 block = false;
2248 }
2249 }
2250 }
2251
2252 if (!block) {
2253 form.submit();
2254 }
2255
2256 return jsUndefined();
2257 } else if (id == KJS::HTMLElement::FormReset) {
2258 form.reset();
2259 return jsUndefined();
2260 }
2261 }
2262 break;
2263 case ID_BODY: {
2264 if (id == KJS::HTMLElement::BodyFocus) {
2265 // Just blur everything. Not perfect, but good enough for now
2266 element.document()->setFocusNode(nullptr);
2267 }
2268 }
2269 break;
2270 case ID_SELECT: {
2271 DOM::HTMLSelectElementImpl &select = static_cast<DOM::HTMLSelectElementImpl &>(element);
2272 if (id == KJS::HTMLElement::SelectAdd) {
2273 select.add(toHTMLElement(args[0]), toHTMLElement(args[1]), exception);
2274 return jsUndefined();
2275 } else if (id == KJS::HTMLElement::SelectItem) {
2276 SharedPtr<DOM::HTMLCollectionImpl> opts = select.options();
2277 return getDOMNode(exec, opts->item(static_cast<unsigned long>(args[0]->toNumber(exec))));
2278 } else if (id == KJS::HTMLElement::SelectRemove) {
2279 // Apparently this takes both elements and indices (ebay.fr)
2280 DOM::NodeImpl *node = toNode(args[0]);
2281 if (node && node->id() == ID_OPTION) {
2282 select.removeChild(node, exception);
2283 } else {
2284 select.remove(int(args[0]->toNumber(exec)));
2285 }
2286 return jsUndefined();
2287 }
2288 }
2289 break;
2290 case ID_INPUT: {
2291 DOM::HTMLInputElementImpl &input = static_cast<DOM::HTMLInputElementImpl &>(element);
2292 if (id == KJS::HTMLElement::InputSelect) {
2293 input.select();
2294 return jsUndefined();
2295 } else if (id == KJS::HTMLElement::InputClick) {
2296 input.click();
2297 return jsUndefined();
2298 } else if (id == KJS::HTMLElement::InputSetSelectionRange) {
2299 input.setSelectionRange(args[0]->toNumber(exec), args[1]->toNumber(exec));
2300 return jsUndefined();
2301 }
2302 }
2303 break;
2304 case ID_BUTTON: {
2305 DOM::HTMLButtonElementImpl &button = static_cast<DOM::HTMLButtonElementImpl &>(element);
2306 if (id == KJS::HTMLElement::ButtonClick) {
2307 button.click();
2308 return jsUndefined();
2309 }
2310 }
2311 break;
2312 case ID_TEXTAREA: {
2313 DOM::HTMLTextAreaElementImpl &textarea = static_cast<DOM::HTMLTextAreaElementImpl &>(element);
2314 if (id == KJS::HTMLElement::TextAreaSelect) {
2315 textarea.select();
2316 return jsUndefined();
2317 } else if (id == KJS::HTMLElement::TextAreaSetSelectionRange) {
2318 textarea.setSelectionRange(args[0]->toNumber(exec), args[1]->toNumber(exec));
2319 return jsUndefined();
2320 }
2321
2322 }
2323 break;
2324 case ID_A: {
2325 DOM::HTMLAnchorElementImpl &anchor = static_cast<DOM::HTMLAnchorElementImpl &>(element);
2326 if (id == KJS::HTMLElement::AnchorClick) {
2327 anchor.click();
2328 return jsUndefined();
2329 } else if (id == KJS::HTMLElement::AnchorToString) {
2330 return jsString(static_cast<KJS::HTMLElement *>(thisObj)->toString(exec));
2331 }
2332 }
2333 break;
2334 case ID_TABLE: {
2335 DOM::HTMLTableElementImpl &table = static_cast<DOM::HTMLTableElementImpl &>(element);
2336 if (id == KJS::HTMLElement::TableCreateTHead) {
2337 return getDOMNode(exec, table.createTHead());
2338 } else if (id == KJS::HTMLElement::TableDeleteTHead) {
2339 table.deleteTHead();
2340 return jsUndefined();
2341 } else if (id == KJS::HTMLElement::TableCreateTFoot) {
2342 return getDOMNode(exec, table.createTFoot());
2343 } else if (id == KJS::HTMLElement::TableDeleteTFoot) {
2344 table.deleteTFoot();
2345 return jsUndefined();
2346 } else if (id == KJS::HTMLElement::TableCreateCaption) {
2347 return getDOMNode(exec, table.createCaption());
2348 } else if (id == KJS::HTMLElement::TableDeleteCaption) {
2349 table.deleteCaption();
2350 return jsUndefined();
2351 } else if (id == KJS::HTMLElement::TableInsertRow) {
2352 return getDOMNode(exec, table.insertRow(args[0]->toInteger(exec), exception));
2353 } else if (id == KJS::HTMLElement::TableDeleteRow) {
2354 table.deleteRow(args[0]->toInteger(exec), exception);
2355 return jsUndefined();
2356 }
2357 }
2358 break;
2359 case ID_THEAD:
2360 case ID_TBODY:
2361 case ID_TFOOT: {
2362 DOM::HTMLTableSectionElementImpl &tableSection = static_cast<DOM::HTMLTableSectionElementImpl &>(element);
2363 if (id == KJS::HTMLElement::TableSectionInsertRow) {
2364 return getDOMNode(exec, tableSection.insertRow(args[0]->toInteger(exec), exception));
2365 } else if (id == KJS::HTMLElement::TableSectionDeleteRow) {
2366 tableSection.deleteRow(args[0]->toInteger(exec), exception);
2367 return jsUndefined();
2368 }
2369 }
2370 break;
2371 case ID_TR: {
2372 DOM::HTMLTableRowElementImpl &tableRow = static_cast<DOM::HTMLTableRowElementImpl &>(element);
2373 if (id == KJS::HTMLElement::TableRowInsertCell) {
2374 return getDOMNode(exec, tableRow.insertCell(args[0]->toInteger(exec), exception));
2375 } else if (id == KJS::HTMLElement::TableRowDeleteCell) {
2376 tableRow.deleteCell(args[0]->toInteger(exec), exception);
2377 return jsUndefined();
2378 }
2379 break;
2380 }
2381 case ID_MARQUEE: {
2382 if (id == KJS::HTMLElement::MarqueeStart && element.renderer() &&
2383 element.renderer()->layer() &&
2384 element.renderer()->layer()->marquee()) {
2385 element.renderer()->layer()->marquee()->start();
2386 return jsUndefined();
2387 } else if (id == KJS::HTMLElement::MarqueeStop && element.renderer() &&
2388 element.renderer()->layer() &&
2389 element.renderer()->layer()->marquee()) {
2390 element.renderer()->layer()->marquee()->stop();
2391 return jsUndefined();
2392 }
2393 break;
2394 }
2395 case ID_CANVAS: {
2396 DOM::HTMLCanvasElementImpl &canvasEl = static_cast<DOM::HTMLCanvasElementImpl &>(element);
2397 if (id == KJS::HTMLElement::CanvasGetContext) {
2398 if (args[0]->toString(exec) == "2d") {
2399 return getWrapper<Context2D>(exec, canvasEl.getContext2D());
2400 }
2401 return jsNull();
2402 } else if (id == KJS::HTMLElement::CanvasToDataURL) {
2403 return jsString(canvasEl.toDataURL(exception));
2404 }
2405 break;
2406 }
2407 case ID_IFRAME: {
2408 DOM::HTMLIFrameElementImpl &iFrame = static_cast<DOM::HTMLIFrameElementImpl &>(element);
2409 if (id == KJS::HTMLElement::IFrameGetSVGDocument) {
2410 if (!checkNodeSecurity(exec, iFrame.contentDocument()) || !iFrame.contentDocument() || !iFrame.contentDocument()->isSVGDocument()) {
2411 return jsUndefined();
2412 }
2413 return getDOMNode(exec, iFrame.contentDocument());
2414 }
2415 }
2416 case ID_OBJECT: {
2417 DOM::HTMLObjectElementImpl &object = static_cast<DOM::HTMLObjectElementImpl &>(element);
2418 if (id == KJS::HTMLElement::ObjectGetSVGDocument) {
2419 if (!checkNodeSecurity(exec, object.contentDocument()) || !object.contentDocument() || !object.contentDocument()->isSVGDocument()) {
2420 return jsUndefined();
2421 }
2422 return getDOMNode(exec, object.contentDocument());
2423 }
2424 }
2425 }
2426
2427 if (id == HTMLElement::ElementScrollIntoView) {
2428 bool alignToTop = true;
2429 if (args.size() > 0) {
2430 alignToTop = args[0]->toBoolean(exec);
2431 }
2432 element.scrollIntoView(alignToTop);
2433 return jsUndefined();
2434 }
2435
2436 return jsUndefined();
2437 }
2438
put(ExecState * exec,const Identifier & propertyName,JSValue * value,int attr)2439 void KJS::HTMLElement::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
2440 {
2441 #ifdef KJS_VERBOSE
2442 DOM::DOMString str = value->type() == NullType ? DOM::DOMString() : value->toString(exec).domString();
2443 #endif
2444 DOM::HTMLElementImpl &element = *impl();
2445 #ifdef KJS_VERBOSE
2446 qCDebug(KHTML_LOG) << "KJS::HTMLElement::tryPut " << propertyName.qstring()
2447 << " thisTag=" << element.tagName().string()
2448 << " str=" << str.string();
2449 #endif
2450 //
2451
2452 // First look at dynamic properties
2453 switch (element.id()) {
2454 case ID_SELECT: {
2455 DOM::HTMLSelectElementImpl &select = static_cast<DOM::HTMLSelectElementImpl &>(element);
2456 bool ok;
2457 /*uint u =*/ propertyName.qstring().toULong(&ok);
2458 if (ok) {
2459 JSObject *coll = getSelectHTMLCollection(exec, select.options(), &select)->getObject();
2460 if (coll) {
2461 coll->put(exec, propertyName, value);
2462 }
2463 return;
2464 }
2465 break;
2466 }
2467 case ID_APPLET:
2468 case ID_OBJECT:
2469 case ID_EMBED: {
2470 KParts::ScriptableExtension *se = getScriptableExtension(element);
2471 if (pluginRootPut(exec, se, propertyName, value)) {
2472 return;
2473 }
2474
2475 break;
2476 }
2477 default:
2478 break;
2479 }
2480
2481 const HashTable *table = classInfo()->propHashTable; // get the right hashtable
2482 const HashEntry *entry = table ? Lookup::findEntry(table, propertyName) : nullptr;
2483 if (entry) {
2484 if (entry->attr & Function) { // function: put as override property
2485 JSObject::put(exec, propertyName, value, attr);
2486 return;
2487 } else if (!(entry->attr & ReadOnly)) { // let lookupPut print the warning if read-only
2488 putValueProperty(exec, entry->value, value, attr);
2489 return;
2490 }
2491 }
2492
2493 lookupPut<KJS::HTMLElement, DOMElement>(exec, propertyName, value, attr, &HTMLElementTable, this);
2494 }
2495
handleBoundWrite(ExecState * exec,int token,JSValue * value)2496 bool KJS::HTMLElement::handleBoundWrite(ExecState *exec, int token, JSValue *value)
2497 {
2498 const BoundPropInfo *prop = boundPropInfo()->value(token);
2499 if (!prop) {
2500 return false;
2501 }
2502 if (prop->type & T_ReadOnly) {
2503 return false;
2504 }
2505
2506 DOM::DOMString str = value->type() == NullType ? DOM::DOMString() : value->toString(exec).domString();
2507
2508 assert(prop->elId == NotApplicable || prop->elId == impl()->id());
2509
2510 switch (prop->type) {
2511 case T_String:
2512 case T_StrOrNl:
2513 case T_URL:
2514 impl()->setAttribute(prop->attrId, str);
2515 return true;
2516 case T_Int:
2517 impl()->setAttribute(prop->attrId, QString::number(value->toInteger(exec)));
2518 return true;
2519 case T_Bool:
2520 impl()->setAttribute(prop->attrId, value->toBoolean(exec) ? "" : nullptr);
2521 return true;
2522 case T_Res: //ignored
2523 return true;
2524 default:
2525 assert(0);
2526 return false;
2527 }
2528 }
2529
putValueProperty(ExecState * exec,int token,JSValue * value,int)2530 void KJS::HTMLElement::putValueProperty(ExecState *exec, int token, JSValue *value, int)
2531 {
2532 if (handleBoundWrite(exec, token, value)) {
2533 return;
2534 }
2535
2536 DOMExceptionTranslator exception(exec);
2537 DOM::DOMString str = value->type() == NullType ? DOM::DOMString() : value->toString(exec).domString();
2538 DOM::HTMLElementImpl &element = *impl();
2539 #ifdef KJS_VERBOSE
2540 qCDebug(KHTML_LOG) << "KJS::HTMLElement::putValueProperty "
2541 << " thisTag=" << element.tagName().string()
2542 << " token=" << token;
2543 #endif
2544
2545 switch (element.id()) {
2546 case ID_TITLE: {
2547 DOM::HTMLTitleElementImpl &title = static_cast<DOM::HTMLTitleElementImpl &>(element);
2548 switch (token) {
2549 case TitleText: {
2550 title.setText(str);
2551 return;
2552 }
2553 }
2554 }
2555 break;
2556 case ID_ISINDEX: {
2557 DOM::HTMLIsIndexElementImpl &isindex = static_cast<DOM::HTMLIsIndexElementImpl &>(element);
2558 switch (token) {
2559 // read-only: form
2560 case IsIndexPrompt: {
2561 isindex.setPrompt(str);
2562 return;
2563 }
2564 }
2565 }
2566 break;
2567 case ID_BODY: {
2568 //DOM::HTMLBodyElementImpl& body = static_cast<DOM::HTMLBodyElementImpl&>(element);
2569 switch (token) {
2570 case BodyOnLoad:
2571 setWindowListener(exec, DOM::EventImpl::LOAD_EVENT, value);
2572 break;
2573 case BodyOnError:
2574 setWindowListener(exec, DOM::EventImpl::ERROR_EVENT, value);
2575 break;
2576 case BodyOnBlur:
2577 setWindowListener(exec, DOM::EventImpl::BLUR_EVENT, value);
2578 break;
2579 case BodyOnFocus:
2580 setWindowListener(exec, DOM::EventImpl::FOCUS_EVENT, value);
2581 break;
2582 case BodyOnMessage:
2583 setWindowListener(exec, DOM::EventImpl::MESSAGE_EVENT, value);
2584 break;
2585 case BodyOnHashChange:
2586 setWindowListener(exec, DOM::EventImpl::HASHCHANGE_EVENT, value);
2587 break;
2588 }
2589 }
2590 case ID_FRAMESET: {
2591 switch (token) {
2592 case FrameSetOnMessage:
2593 setWindowListener(exec, DOM::EventImpl::MESSAGE_EVENT, value);
2594 break;
2595 }
2596 }
2597 break;
2598 case ID_SELECT: {
2599 DOM::HTMLSelectElementImpl &select = static_cast<DOM::HTMLSelectElementImpl &>(element);
2600 switch (token) {
2601 // read-only: type
2602 case SelectSelectedIndex: {
2603 select.setSelectedIndex(value->toInteger(exec));
2604 return;
2605 }
2606 case SelectValue: {
2607 select.setValue(str.implementation());
2608 return;
2609 }
2610 case SelectLength: { // read-only according to the NS spec, but webpages need it writeable
2611 JSObject *coll = getSelectHTMLCollection(exec, select.options(), &select)->getObject();
2612
2613 if (coll) {
2614 coll->put(exec, "length", value);
2615 }
2616 return;
2617 }
2618 // read-only: form
2619 // read-only: options
2620 case SelectName: {
2621 select.setName(str);
2622 return;
2623 }
2624 }
2625 }
2626 break;
2627 case ID_OPTION: {
2628 DOM::HTMLOptionElementImpl &option = static_cast<DOM::HTMLOptionElementImpl &>(element);
2629 switch (token) {
2630 // read-only: form
2631 // read-only: text <--- According to the DOM, but JavaScript and JScript both allow changes.
2632 // So, we'll do it here and not add it to our DOM headers.
2633 case OptionText: {
2634 RefPtr<DOM::NodeListImpl> nl(option.childNodes());
2635 const unsigned int length = nl->length();
2636 for (unsigned int i = 0; i < length; ++i) {
2637 if (nl->item(i)->nodeType() == DOM::Node::TEXT_NODE) {
2638 static_cast<DOM::TextImpl *>(nl->item(i))->setData(str, exception);
2639 return;
2640 }
2641 }
2642 // No child text node found, creating one
2643 DOM::TextImpl *t = option.document()->createTextNode(str.implementation());
2644 int dummyexception;
2645 option.appendChild(t, dummyexception); // #### exec->setException ?
2646 return;
2647 }
2648 // read-only: index
2649 case OptionSelected: {
2650 option.setSelected(value->toBoolean(exec));
2651 return;
2652 }
2653 case OptionValue: {
2654 option.setValue(str.implementation());
2655 return;
2656 }
2657 }
2658 }
2659 break;
2660 case ID_INPUT: {
2661 DOM::HTMLInputElementImpl &input = static_cast<DOM::HTMLInputElementImpl &>(element);
2662 switch (token) {
2663 case InputChecked: {
2664 input.setChecked(value->toBoolean(exec));
2665 return;
2666 }
2667 case InputIndeterminate: {
2668 input.setIndeterminate(value->toBoolean(exec));
2669 return;
2670 }
2671 case InputName: {
2672 input.setName(str);
2673 return;
2674 }
2675 case InputType: {
2676 input.setType(str);
2677 return;
2678 }
2679 case InputValue: {
2680 input.setValue(str);
2681 return;
2682 }
2683 case InputSelectionStart: {
2684 input.setSelectionStart(value->toInteger(exec));
2685 return;
2686 }
2687 case InputSelectionEnd: {
2688 input.setSelectionEnd(value->toInteger(exec));
2689 return;
2690 }
2691 case InputPlaceholder: {
2692 input.setPlaceholder(str);
2693 return;
2694 }
2695 }
2696 }
2697 break;
2698 case ID_TEXTAREA: {
2699 DOM::HTMLTextAreaElementImpl &textarea = static_cast<DOM::HTMLTextAreaElementImpl &>(element);
2700 switch (token) {
2701 case TextAreaDefaultValue: {
2702 textarea.setDefaultValue(str);
2703 return;
2704 }
2705 case TextAreaName: {
2706 textarea.setName(str);
2707 return;
2708 }
2709 case TextAreaValue: {
2710 textarea.setValue(str);
2711 return;
2712 }
2713 case TextAreaSelectionStart: {
2714 textarea.setSelectionStart(value->toInteger(exec));
2715 return;
2716 }
2717 case TextAreaSelectionEnd: {
2718 textarea.setSelectionEnd(value->toInteger(exec));
2719 return;
2720 }
2721 case TextAreaPlaceholder: {
2722 textarea.setPlaceholder(str);
2723 return;
2724 }
2725 }
2726 }
2727 break;
2728 case ID_A: {
2729 DOM::HTMLAnchorElementImpl &anchor = static_cast<DOM::HTMLAnchorElementImpl &>(element);
2730 switch (token) {
2731 case AnchorSearch: {
2732 QString href = getURLArg(ATTR_HREF);
2733 QUrl u(href);
2734 QString q = str.isEmpty() ? QString() : str.string();
2735 u.setQuery(q);
2736 anchor.setAttribute(ATTR_HREF, u.url());
2737 return;
2738 }
2739 }
2740 }
2741 break;
2742 case ID_IMG: {
2743 DOM::HTMLImageElementImpl &image = static_cast<DOM::HTMLImageElementImpl &>(element);
2744 switch (token) {
2745 case ImageHeight: {
2746 image.setHeight(value->toInteger(exec));
2747 return;
2748 }
2749 case ImageWidth: {
2750 image.setWidth(value->toInteger(exec));
2751 return;
2752 }
2753 }
2754 }
2755 break;
2756 case ID_CANVAS: {
2757 DOM::HTMLCanvasElementImpl &canvas = static_cast<DOM::HTMLCanvasElementImpl &>(element);
2758 switch (token) {
2759 // ### it may make sense to do something different here, to at least
2760 // emulate reflecting properties somewhat.
2761 case CanvasWidth:
2762 canvas.setAttribute(ATTR_WIDTH, value->toString(exec).domString());
2763 return;
2764 case CanvasHeight:
2765 canvas.setAttribute(ATTR_HEIGHT, value->toString(exec).domString());
2766 return;
2767 }
2768 }
2769 break;
2770
2771 // case ID_FIELDSET: {
2772 // DOM::HTMLFieldSetElementImpl& fieldSet = static_cast<DOM::HTMLFieldSetElementImpl&>(element);
2773 // // read-only: form
2774 // }
2775 // break;
2776 case ID_SCRIPT: {
2777 DOM::HTMLScriptElementImpl &script = static_cast<DOM::HTMLScriptElementImpl &>(element);
2778 switch (token) {
2779 case ScriptText: {
2780 script.setText(str);
2781 return;
2782 }
2783 }
2784 }
2785 break;
2786 case ID_TABLE: {
2787 DOM::HTMLTableElementImpl &table = static_cast<DOM::HTMLTableElementImpl &>(element);
2788 switch (token) {
2789 case TableCaption: {
2790 table.setCaption(toHTMLTableCaptionElement(value)); // type HTMLTableCaptionElement
2791 return;
2792 }
2793 case TableTHead: {
2794 table.setTHead(toHTMLTableSectionElement(value)); // type HTMLTableSectionElement
2795 return;
2796 }
2797 case TableTFoot: {
2798 table.setTFoot(toHTMLTableSectionElement(value)); // type HTMLTableSectionElement
2799 return;
2800 }
2801 }
2802 }
2803 break;
2804 case ID_FRAME: {
2805 DOM::HTMLFrameElementImpl &frameElement = static_cast<DOM::HTMLFrameElementImpl &>(element);
2806 switch (token) {
2807 // read-only: FrameContentDocument:
2808 case FrameLocation: {
2809 frameElement.setLocation(str.string());
2810 return;
2811 }
2812 }
2813 }
2814 break;
2815 }
2816
2817 // generic properties
2818 switch (token) {
2819 case ElementInnerHTML:
2820 element.setInnerHTML(str, exception);
2821 return;
2822 case ElementInnerText:
2823 element.setInnerText(str, exception);
2824 return;
2825 case ElementContentEditable:
2826 element.setContentEditable(str);
2827 return;
2828 case ElementTabIndex:
2829 element.setTabIndex(value->toInteger(exec));
2830 return;
2831 default:
2832 // qCDebug(KHTML_LOG) << "WARNING: KJS::HTMLElement::putValueProperty unhandled token " << token << " thisTag=" << element.tagName().string() << " str=" << str.string();
2833 break;
2834 }
2835 }
2836
2837 //Prototype mess for this...
2838 KJS_DEFINE_PROTOTYPE(HTMLElementProto)
2839 KJS_IMPLEMENT_PROTOTYPE("HTMLElement", HTMLElementProto, HTMLElementFunction, DOMElementProto)
2840 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLElementPseudoCtor, "HTMLElement", HTMLElementProto)
2841
2842 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLHtmlElement", HTMLHtmlElementProto, HTMLElementProto)
2843 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLHtmlElementPseudoCtor, "HTMLHtmlElement", HTMLHtmlElementProto)
2844
2845 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLHeadElement", HTMLHeadElementProto, HTMLElementProto)
2846 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLHeadElementPseudoCtor, "HTMLHeadElement", HTMLHeadElementProto)
2847
2848 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLinkElement", HTMLLinkElementProto, HTMLElementProto)
2849 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLinkElementPseudoCtor, "HTMLLinkElement", HTMLLinkElementProto)
2850
2851 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLTitleElement", HTMLTitleElementProto, HTMLElementProto)
2852 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTitleElementPseudoCtor, "HTMLTitleElement", HTMLTitleElementProto)
2853
2854 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLMetaElement", HTMLMetaElementProto, HTMLElementProto)
2855 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLMetaElementPseudoCtor, "HTMLMetaElement", HTMLMetaElementProto)
2856
2857 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLBaseElement", HTMLBaseElementProto, HTMLElementProto)
2858 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBaseElementPseudoCtor, "HTMLBaseElement", HTMLBaseElementProto)
2859
2860 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLIsIndexElement", HTMLIsIndexElementProto, HTMLElementProto)
2861 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLIsIndexElementPseudoCtor, "HTMLIsIndexElement", HTMLIsIndexElementProto)
2862
2863 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLStyleElement", HTMLStyleElementProto, HTMLElementProto)
2864 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLStyleElementPseudoCtor, "HTMLStyleElement", HTMLStyleElementProto)
2865
KJS_DEFINE_PROTOTYPE(HTMLBodyElementProto)2866 KJS_DEFINE_PROTOTYPE(HTMLBodyElementProto)
2867 KJS_IMPLEMENT_PROTOTYPE("HTMLBodyElement", HTMLBodyElementProto, HTMLElementFunction, HTMLElementProto)
2868 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBodyElementPseudoCtor, "HTMLBodyElement", HTMLBodyElementProto)
2869
2870 KJS_DEFINE_PROTOTYPE(HTMLFormElementProto)
2871 KJS_IMPLEMENT_PROTOTYPE("HTMLFormElement", HTMLFormElementProto, HTMLElementFunction, HTMLElementProto)
2872 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFormElementPseudoCtor, "HTMLFormElement", HTMLFormElementProto)
2873
2874 KJS_DEFINE_PROTOTYPE(HTMLSelectElementProto)
2875 KJS_IMPLEMENT_PROTOTYPE("HTMLSelectElement", HTMLSelectElementProto, HTMLElementFunction, HTMLElementProto)
2876 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLSelectElementPseudoCtor, "HTMLSelectElement", HTMLSelectElementProto)
2877
2878 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLOptGroupElement", HTMLOptGroupElementProto, HTMLElementProto)
2879 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLOptGroupElementPseudoCtor, "HTMLOptGroupElement", HTMLOptGroupElementProto)
2880
2881 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLOptionElement", HTMLOptionElementProto, HTMLElementProto)
2882 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLOptionElementPseudoCtor, "HTMLOptionElement", HTMLOptionElementProto)
2883
2884 KJS_DEFINE_PROTOTYPE(HTMLInputElementProto)
2885 KJS_IMPLEMENT_PROTOTYPE("HTMLInputElement", HTMLInputElementProto, HTMLElementFunction, HTMLElementProto)
2886 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLInputElementPseudoCtor, "HTMLInputElement", HTMLInputElementProto)
2887
2888 KJS_DEFINE_PROTOTYPE(HTMLTextAreaElementProto)
2889 KJS_IMPLEMENT_PROTOTYPE("HTMLTextAreaElement", HTMLTextAreaElementProto, HTMLElementFunction, HTMLElementProto)
2890 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTextAreaElementPseudoCtor, "HTMLTextAreaElement", HTMLTextAreaElementProto)
2891
2892 KJS_DEFINE_PROTOTYPE(HTMLButtonElementProto)
2893 KJS_IMPLEMENT_PROTOTYPE("HTMLButtonElement", HTMLButtonElementProto, HTMLElementFunction, HTMLElementProto)
2894 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLButtonElementPseudoCtor, "HTMLButtonElement", HTMLButtonElementProto)
2895
2896 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLabelElement", HTMLLabelElementProto, HTMLElementProto)
2897 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLabelElementPseudoCtor, "HTMLLabelElement", HTMLLabelElementProto)
2898
2899 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLFieldSetElement", HTMLFieldSetElementProto, HTMLElementProto)
2900 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFieldSetElementPseudoCtor, "HTMLFieldSetElement", HTMLFieldSetElementProto)
2901
2902 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLegendElement", HTMLLegendElementProto, HTMLElementProto)
2903 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLegendElementPseudoCtor, "HTMLLegendElement", HTMLLegendElementProto)
2904
2905 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLUListElement", HTMLUListElementProto, HTMLElementProto)
2906 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLUListElementPseudoCtor, "HTMLUListElement", HTMLUListElementProto)
2907
2908 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLOListElement", HTMLOListElementProto, HTMLElementProto)
2909 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLOListElementPseudoCtor, "HTMLOListElement", HTMLOListElementProto)
2910
2911 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLDListElement", HTMLDListElementProto, HTMLElementProto)
2912 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLDListElementPseudoCtor, "HTMLDListElement", HTMLDListElementProto)
2913
2914 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLDirectoryElement", HTMLDirectoryElementProto, HTMLElementProto)
2915 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLDirectoryElementPseudoCtor, "HTMLDirectoryElement", HTMLDirectoryElementProto)
2916
2917 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLMenuElement", HTMLMenuElementProto, HTMLElementProto)
2918 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLMenuElementPseudoCtor, "HTMLMenuElement", HTMLMenuElementProto)
2919
2920 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLIElement", HTMLLIElementProto, HTMLElementProto)
2921 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLIElementPseudoCtor, "HTMLLIElement", HTMLLIElementProto)
2922
2923 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLDivElement", HTMLDivElementProto, HTMLElementProto)
2924 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLDivElementPseudoCtor, "HTMLDivElement", HTMLDivElementProto)
2925
2926 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLParagraphElement", HTMLParagraphElementProto, HTMLElementProto)
2927 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLParagraphElementPseudoCtor, "HTMLParagraphElement", HTMLParagraphElementProto)
2928
2929 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLHeadingElement", HTMLHeadingElementProto, HTMLElementProto)
2930 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLHeadingElementPseudoCtor, "HTMLHeadingElement", HTMLHeadingElementProto)
2931
2932 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLBlockQuoteElement", HTMLBlockQuoteElementProto, HTMLElementProto)
2933 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBlockQuoteElementPseudoCtor, "HTMLBlockQuoteElement", HTMLBlockQuoteElementProto)
2934
2935 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLQuoteElement", HTMLQuoteElementProto, HTMLElementProto)
2936 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLQuoteElementPseudoCtor, "HTMLQuoteElement", HTMLQuoteElementProto)
2937
2938 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLPreElement", HTMLPreElementProto, HTMLElementProto)
2939 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLPreElementPseudoCtor, "HTMLPreElement", HTMLPreElementProto)
2940
2941 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLBRElement", HTMLBRElementProto, HTMLElementProto)
2942 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBRElementPseudoCtor, "HTMLBRElement", HTMLBRElementProto)
2943
2944 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLBaseFontElement", HTMLBaseFontElementProto, HTMLElementProto)
2945 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBaseFontElementPseudoCtor, "HTMLBaseFontElement", HTMLBaseFontElementProto)
2946
2947 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLFontElement", HTMLFontElementProto, HTMLElementProto)
2948 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFontElementPseudoCtor, "HTMLFontElement", HTMLFontElementProto)
2949
2950 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLHRElement", HTMLHRElementProto, HTMLElementProto)
2951 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLHRElementPseudoCtor, "HTMLHRElement", HTMLHRElementProto)
2952
2953 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLModElement", HTMLModElementProto, HTMLElementProto)
2954 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLModElementPseudoCtor, "HTMLModElement", HTMLModElementProto)
2955
2956 KJS_DEFINE_PROTOTYPE(HTMLAnchorElementProto)
2957 KJS_IMPLEMENT_PROTOTYPE("HTMLAnchorElement", HTMLAnchorElementProto, HTMLElementFunction, HTMLElementProto)
2958 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLAnchorElementPseudoCtor, "HTMLAnchorElement", HTMLAnchorElementProto)
2959
2960 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLImageElement", HTMLImageElementProto, HTMLElementProto)
2961 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLImageElementPseudoCtor, "HTMLImageElement", HTMLImageElementProto)
2962
2963 KJS_DEFINE_PROTOTYPE(HTMLObjectElementProto)
2964 KJS_IMPLEMENT_PROTOTYPE("HTMLObjectElement", HTMLObjectElementProto, HTMLElementFunction, HTMLElementProto)
2965 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLObjectElementPseudoCtor, "HTMLObjectElement", HTMLObjectElementProto)
2966
2967 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLParamElement", HTMLParamElementProto, HTMLElementProto)
2968 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLParamElementPseudoCtor, "HTMLParamElement", HTMLParamElementProto)
2969
2970 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLAppletElement", HTMLAppletElementProto, HTMLElementProto)
2971 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLAppletElementPseudoCtor, "HTMLAppletElement", HTMLAppletElementProto)
2972
2973 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLMapElement", HTMLMapElementProto, HTMLElementProto)
2974 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLMapElementPseudoCtor, "HTMLMapElement", HTMLMapElementProto)
2975
2976 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLAreaElement", HTMLAreaElementProto, HTMLElementProto)
2977 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLAreaElementPseudoCtor, "HTMLAreaElement", HTMLAreaElementProto)
2978
2979 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLScriptElement", HTMLScriptElementProto, HTMLElementProto)
2980 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLScriptElementPseudoCtor, "HTMLScriptElement", HTMLScriptElementProto)
2981
2982 KJS_DEFINE_PROTOTYPE(HTMLTableElementProto)
2983 KJS_IMPLEMENT_PROTOTYPE("HTMLTableElement", HTMLTableElementProto, HTMLElementFunction, HTMLElementProto)
2984 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableElementPseudoCtor, "HTMLTableElement", HTMLTableElementProto)
2985
2986 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLTableCaptionElement", HTMLTableCaptionElementProto, HTMLElementProto)
2987 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableCaptionElementPseudoCtor, "HTMLTableCaptionElement", HTMLTableCaptionElementProto)
2988
2989 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLTableColElement", HTMLTableColElementProto, HTMLElementProto)
2990 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableColElementPseudoCtor, "HTMLTableColElement", HTMLTableColElementProto)
2991
2992 KJS_DEFINE_PROTOTYPE(HTMLTableSectionElementProto)
2993 KJS_IMPLEMENT_PROTOTYPE("HTMLTableSectionElement", HTMLTableSectionElementProto, HTMLElementFunction, HTMLElementProto)
2994 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableSectionElementPseudoCtor, "HTMLTableSectionElement", HTMLTableSectionElementProto)
2995
2996 KJS_DEFINE_PROTOTYPE(HTMLTableRowElementProto)
2997 KJS_IMPLEMENT_PROTOTYPE("HTMLTableRowElement", HTMLTableRowElementProto, HTMLElementFunction, HTMLElementProto)
2998 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableRowElementPseudoCtor, "HTMLTableRowElement", HTMLTableRowElementProto)
2999
3000 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLTableCellElement", HTMLTableCellElementProto, HTMLElementProto)
3001 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableCellElementPseudoCtor, "HTMLTableCellElement", HTMLTableCellElementProto)
3002
3003 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLFrameSetElement", HTMLFrameSetElementProto, HTMLElementProto)
3004 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFrameSetElementPseudoCtor, "HTMLFrameSetElement", HTMLFrameSetElementProto)
3005
3006 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLayerElement", HTMLLayerElementProto, HTMLElementProto)
3007 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLayerElementPseudoCtor, "HTMLLayerElement", HTMLLayerElementProto)
3008
3009 KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLFrameElement", HTMLFrameElementProto, HTMLElementProto)
3010 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFrameElementPseudoCtor, "HTMLFrameElement", HTMLFrameElementProto)
3011
3012 KJS_DEFINE_PROTOTYPE(HTMLIFrameElementProto)
3013 KJS_IMPLEMENT_PROTOTYPE("HTMLIFrameElement", HTMLIFrameElementProto, HTMLElementFunction, HTMLElementProto)
3014 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLIFrameElementPseudoCtor, "HTMLIFrameElement", HTMLIFrameElementProto)
3015
3016 KJS_DEFINE_PROTOTYPE(HTMLMarqueeElementProto)
3017 KJS_IMPLEMENT_PROTOTYPE("HTMLMarqueeElement", HTMLMarqueeElementProto, HTMLElementFunction, HTMLElementProto)
3018 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLMarqueeElementPseudoCtor, "HTMLMarqueeElement", HTMLMarqueeElementProto)
3019
3020 KJS_DEFINE_PROTOTYPE(HTMLCanvasElementProto)
3021 KJS_IMPLEMENT_PROTOTYPE("HTMLCanvasElement", HTMLCanvasElementProto, HTMLElementFunction, HTMLElementProto)
3022 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLCanvasElementPseudoCtor, "HTMLCanvasElement", HTMLCanvasElementProto)
3023
3024 static JSObject *prototypeForID(ExecState *exec, DOM::NodeImpl::Id id)
3025 {
3026 switch (id) {
3027 case ID_HTML:
3028 return HTMLHtmlElementProto::self(exec);
3029 case ID_HEAD:
3030 return HTMLHeadElementProto::self(exec);
3031 case ID_LINK:
3032 return HTMLLinkElementProto::self(exec);
3033 case ID_TITLE:
3034 return HTMLTitleElementProto::self(exec);
3035 case ID_META:
3036 return HTMLMetaElementProto::self(exec);
3037 case ID_BASE:
3038 return HTMLBaseElementProto::self(exec);
3039 case ID_ISINDEX:
3040 return HTMLIsIndexElementProto::self(exec);
3041 case ID_STYLE:
3042 return HTMLStyleElementProto::self(exec);
3043 case ID_BODY:
3044 return HTMLBodyElementProto::self(exec);
3045 case ID_FORM:
3046 return HTMLFormElementProto::self(exec);
3047 case ID_SELECT:
3048 return HTMLSelectElementProto::self(exec);
3049 case ID_OPTGROUP:
3050 return HTMLOptGroupElementProto::self(exec);
3051 case ID_OPTION:
3052 return HTMLOptionElementProto::self(exec);
3053 case ID_INPUT:
3054 return HTMLInputElementProto::self(exec);
3055 case ID_TEXTAREA:
3056 return HTMLTextAreaElementProto::self(exec);
3057 case ID_BUTTON:
3058 return HTMLButtonElementProto::self(exec);
3059 case ID_LABEL:
3060 return HTMLLabelElementProto::self(exec);
3061 case ID_FIELDSET:
3062 return HTMLFieldSetElementProto::self(exec);
3063 case ID_LEGEND:
3064 return HTMLLegendElementProto::self(exec);
3065 case ID_UL:
3066 return HTMLUListElementProto::self(exec);
3067 case ID_OL:
3068 return HTMLOListElementProto::self(exec);
3069 case ID_DL:
3070 return HTMLDListElementProto::self(exec);
3071 case ID_DIR:
3072 return HTMLDirectoryElementProto::self(exec);
3073 case ID_MENU:
3074 return HTMLMenuElementProto::self(exec);
3075 case ID_LI:
3076 return HTMLLIElementProto::self(exec);
3077 case ID_DIV:
3078 return HTMLDivElementProto::self(exec);
3079 case ID_P:
3080 return HTMLParagraphElementProto::self(exec);
3081 case ID_H1:
3082 case ID_H2:
3083 case ID_H3:
3084 case ID_H4:
3085 case ID_H5:
3086 case ID_H6:
3087 return HTMLHeadingElementProto::self(exec);
3088 case ID_BLOCKQUOTE:
3089 return HTMLBlockQuoteElementProto::self(exec);
3090 case ID_Q:
3091 return HTMLQuoteElementProto::self(exec);
3092 case ID_PRE:
3093 return HTMLPreElementProto::self(exec);
3094 case ID_BR:
3095 return HTMLBRElementProto::self(exec);
3096 case ID_BASEFONT:
3097 return HTMLBaseFontElementProto::self(exec);
3098 case ID_FONT:
3099 return HTMLFontElementProto::self(exec);
3100 case ID_HR:
3101 return HTMLHRElementProto::self(exec);
3102 case ID_INS:
3103 case ID_DEL:
3104 return HTMLModElementProto::self(exec);
3105 case ID_A:
3106 return HTMLAnchorElementProto::self(exec);
3107 case ID_IMG:
3108 return HTMLImageElementProto::self(exec);
3109 case ID_OBJECT:
3110 return HTMLObjectElementProto::self(exec);
3111 case ID_PARAM:
3112 return HTMLParamElementProto::self(exec);
3113 case ID_APPLET:
3114 return HTMLAppletElementProto::self(exec);
3115 case ID_MAP:
3116 return HTMLMapElementProto::self(exec);
3117 case ID_AREA:
3118 return HTMLAreaElementProto::self(exec);
3119 case ID_SCRIPT:
3120 return HTMLScriptElementProto::self(exec);
3121 case ID_TABLE:
3122 return HTMLTableElementProto::self(exec);
3123 case ID_CAPTION:
3124 return HTMLTableCaptionElementProto::self(exec);
3125 case ID_COL:
3126 case ID_COLGROUP:
3127 return HTMLTableColElementProto::self(exec);
3128 case ID_THEAD:
3129 case ID_TBODY:
3130 case ID_TFOOT:
3131 return HTMLTableSectionElementProto::self(exec);
3132 case ID_TR:
3133 return HTMLTableRowElementProto::self(exec);
3134 case ID_TD:
3135 case ID_TH:
3136 return HTMLTableCellElementProto::self(exec);
3137 case ID_FRAMESET:
3138 return HTMLFrameSetElementProto::self(exec);
3139 case ID_LAYER:
3140 return HTMLLayerElementProto::self(exec);
3141 case ID_FRAME:
3142 return HTMLFrameElementProto::self(exec);
3143 case ID_IFRAME:
3144 return HTMLIFrameElementProto::self(exec);
3145 case ID_MARQUEE:
3146 return HTMLMarqueeElementProto::self(exec);
3147 case ID_CANVAS:
3148 return HTMLCanvasElementProto::self(exec);
3149 default:
3150 return HTMLElementProto::self(exec);
3151 }
3152 }
3153
3154 // -------------------------------------------------------------------------
3155 /* Source for HTMLCollectionProtoTable.
3156 @begin HTMLCollectionProtoTable 3
3157 item HTMLCollection::Item DontDelete|Function 1
3158 namedItem HTMLCollection::NamedItem DontDelete|Function 1
3159 tags HTMLCollection::Tags DontDelete|Function 1
3160 @end
3161 */
3162 KJS_DEFINE_PROTOTYPE(HTMLCollectionProto)
3163 KJS_IMPLEMENT_PROTOFUNC(HTMLCollectionProtoFunc)
3164 KJS_IMPLEMENT_PROTOTYPE("HTMLCollection", HTMLCollectionProto, HTMLCollectionProtoFunc, ObjectPrototype)
3165 IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLCollectionPseudoCtor, "HTMLCollection", HTMLCollectionProto)
3166
3167 const ClassInfo KJS::HTMLCollection::info = { "HTMLCollection", nullptr, nullptr, nullptr };
3168
HTMLCollection(ExecState * exec,DOM::HTMLCollectionImpl * c)3169 KJS::HTMLCollection::HTMLCollection(ExecState *exec, DOM::HTMLCollectionImpl *c)
3170 : DOMObject(HTMLCollectionProto::self(exec)), m_impl(c), hidden(false) {}
3171
HTMLCollection(JSObject * proto,DOM::HTMLCollectionImpl * c)3172 KJS::HTMLCollection::HTMLCollection(JSObject *proto, DOM::HTMLCollectionImpl *c)
3173 : DOMObject(proto), m_impl(c), hidden(false) {}
3174
~HTMLCollection()3175 KJS::HTMLCollection::~HTMLCollection()
3176 {
3177 ScriptInterpreter::forgetDOMObject(m_impl.get());
3178 }
3179
masqueradeAsUndefined() const3180 bool KJS::HTMLCollection::masqueradeAsUndefined() const
3181 {
3182 return hidden;
3183 }
3184
toBoolean(ExecState *) const3185 bool KJS::HTMLCollection::toBoolean(ExecState *) const
3186 {
3187 return !hidden;
3188 }
3189
indexGetter(ExecState * exec,unsigned index)3190 JSValue *HTMLCollection::indexGetter(ExecState *exec, unsigned index)
3191 {
3192 return getDOMNode(exec, m_impl->item(index));
3193 }
3194
getOwnPropertyNames(ExecState * exec,PropertyNameArray & propertyNames,PropertyMap::PropertyMode mode)3195 void KJS::HTMLCollection::getOwnPropertyNames(ExecState *exec, PropertyNameArray &propertyNames, PropertyMap::PropertyMode mode)
3196 {
3197 for (unsigned i = 0; i < m_impl->length(); ++i) {
3198 propertyNames.add(Identifier::from(i));
3199 }
3200
3201 propertyNames.add(exec->propertyNames().length);
3202
3203 JSObject::getOwnPropertyNames(exec, propertyNames, mode);
3204 }
3205
lengthGetter(ExecState *,JSObject *,const Identifier &,const PropertySlot & slot)3206 JSValue *HTMLCollection::lengthGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot &slot)
3207 {
3208 HTMLCollection *thisObj = static_cast<HTMLCollection *>(slot.slotBase());
3209 return jsNumber(thisObj->m_impl->length());
3210 }
3211
nameGetter(ExecState * exec,JSObject *,const Identifier & propertyName,const PropertySlot & slot)3212 JSValue *HTMLCollection::nameGetter(ExecState *exec, JSObject *, const Identifier &propertyName, const PropertySlot &slot)
3213 {
3214 HTMLCollection *thisObj = static_cast<HTMLCollection *>(slot.slotBase());
3215 return thisObj->getNamedItems(exec, propertyName);
3216 }
3217
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)3218 bool KJS::HTMLCollection::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
3219 {
3220 #ifdef KJS_VERBOSE
3221 qCDebug(KHTML_LOG) << "KJS::HTMLCollection::getOwnPropertySlot " << propertyName.ascii();
3222 #endif
3223 if (propertyName.isEmpty()) {
3224 return false;
3225 }
3226 if (propertyName == exec->propertyNames().length) {
3227 #ifdef KJS_VERBOSE
3228 qCDebug(KHTML_LOG) << " collection length is " << m_impl->length();
3229 #endif
3230 slot.setCustom(this, lengthGetter);
3231 return true;
3232 }
3233
3234 // Look in the prototype (for functions) before assuming it's an item's name
3235 JSValue *proto = prototype();
3236 if (proto->isObject() && static_cast<JSObject *>(proto)->hasProperty(exec, propertyName)) {
3237 return false;
3238 }
3239
3240 // name or index ?
3241 if (getIndexSlot(this, *m_impl, propertyName, slot)) {
3242 return true;
3243 }
3244
3245 if (!getNamedItems(exec, propertyName)->isUndefined()) {
3246 slot.setCustom(this, nameGetter);
3247 return true;
3248 }
3249
3250 return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
3251 }
3252
3253 // HTMLCollections are strange objects, they support both get and call,
3254 // so that document.forms.item(0) and document.forms(0) both work.
callAsFunction(ExecState * exec,JSObject *,const List & args)3255 JSValue *KJS::HTMLCollection::callAsFunction(ExecState *exec, JSObject *, const List &args)
3256 {
3257 // Do not use thisObj here. It can be the HTMLDocument, in the document.forms(i) case.
3258 /*if( thisObj.imp() != this )
3259 {
3260 // qCDebug(KHTML_LOG) << "WARNING: thisObj.imp() != this in HTMLCollection::tryCall";
3261 KJS::printInfo(exec,"KJS::HTMLCollection::tryCall thisObj",thisObj,-1);
3262 KJS::printInfo(exec,"KJS::HTMLCollection::tryCall this",Value(this),-1);
3263 }*/
3264 // Also, do we need the TypeError test here ?
3265
3266 HTMLCollectionImpl &collection = *m_impl;
3267
3268 // Also, do we need the TypeError test here ?
3269
3270 if (args.size() == 1) {
3271 // support for document.all(<index>) etc.
3272 bool ok;
3273 UString s = args[0]->toString(exec);
3274 unsigned int u = s.toArrayIndex(&ok);
3275 if (ok) {
3276 return getDOMNode(exec, collection.item(u));
3277 }
3278 // support for document.images('<name>') etc.
3279 return getNamedItems(exec, Identifier(s));
3280 } else if (args.size() >= 1) { // the second arg, if set, is the index of the item we want
3281 bool ok;
3282 UString s = args[0]->toString(exec);
3283 unsigned int u = args[1]->toString(exec).toArrayIndex(&ok);
3284 if (ok) {
3285 DOM::DOMString pstr = s.domString();
3286 DOM::NodeImpl *node = collection.namedItem(pstr);
3287 while (node) {
3288 if (!u) {
3289 return getDOMNode(exec, node);
3290 }
3291 node = collection.nextNamedItem(pstr);
3292 --u;
3293 }
3294 }
3295 }
3296 return jsUndefined();
3297 }
3298
getNamedItems(ExecState * exec,const Identifier & propertyName) const3299 JSValue *KJS::HTMLCollection::getNamedItems(ExecState *exec, const Identifier &propertyName) const
3300 {
3301 #ifdef KJS_VERBOSE
3302 qCDebug(KHTML_LOG) << "KJS::HTMLCollection::getNamedItems " << propertyName.ascii();
3303 #endif
3304
3305 DOM::DOMString pstr = propertyName.domString();
3306
3307 const QList<DOM::NodeImpl *> matches = m_impl->namedItems(pstr);
3308
3309 if (!matches.isEmpty()) {
3310 if (matches.size() == 1) {
3311 #ifdef KJS_VERBOSE
3312 qCDebug(KHTML_LOG) << "returning single node";
3313 #endif
3314 return getDOMNode(exec, matches[0]);
3315 } else {
3316 // multiple items, return a collection
3317 QList<SharedPtr<DOM::NodeImpl> > nodes;
3318 foreach (DOM::NodeImpl *node, matches) {
3319 nodes.append(node);
3320 }
3321 #ifdef KJS_VERBOSE
3322 qCDebug(KHTML_LOG) << "returning list of " << matches.count() << " nodes";
3323 #endif
3324 return new DOMNamedNodesCollection(exec, nodes);
3325 }
3326 }
3327 #ifdef KJS_VERBOSE
3328 qCDebug(KHTML_LOG) << "not found";
3329 #endif
3330 return jsUndefined();
3331 }
3332
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)3333 JSValue *KJS::HTMLCollectionProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
3334 {
3335 KJS_CHECK_THIS(KJS::HTMLCollection, thisObj);
3336 HTMLCollectionImpl &coll = *static_cast<HTMLCollection *>(thisObj)->impl();
3337
3338 switch (id) {
3339 case KJS::HTMLCollection::Item: {
3340 // support for item(<index>) (DOM)
3341 UString s = args[0]->toString(exec);
3342 bool ok;
3343 unsigned int u = s.toArrayIndex(&ok);
3344 if (ok) {
3345 return getDOMNode(exec, coll.item(u));
3346 }
3347
3348 // support for item('<name>') (IE only)
3349 qCWarning(KHTML_LOG) << "non-standard HTMLCollection.item('" << s.ascii() << "') called, use namedItem instead";
3350 return static_cast<HTMLCollection *>(thisObj)->getNamedItems(exec, Identifier(s));
3351 }
3352 case KJS::HTMLCollection::Tags: {
3353 DOM::DOMString tagName = args[0]->toString(exec).domString();
3354 DOM::NodeListImpl *list;
3355 // getElementsByTagName exists in Document and in Element, pick up the right one
3356 if (coll.base()->nodeType() == DOM::Node::DOCUMENT_NODE) {
3357 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl *>(coll.base());
3358 list = doc->getElementsByTagName(tagName);
3359 #ifdef KJS_VERBOSE
3360 qCDebug(KHTML_LOG) << "KJS::HTMLCollectionProtoFunc::callAsFunction document.tags(" << tagName.string() << ") -> " << list->length() << " items in node list";
3361 #endif
3362 } else {
3363 DOM::ElementImpl *e = static_cast<DOM::ElementImpl *>(coll.base());
3364 list = e->getElementsByTagName(tagName);
3365 #ifdef KJS_VERBOSE
3366 qCDebug(KHTML_LOG) << "KJS::HTMLCollectionProtoFunc::tryCall element.tags(" << tagName.string() << ") -> " << list->length() << " items in node list";
3367 #endif
3368 }
3369 return getDOMNodeList(exec, list);
3370 }
3371 case KJS::HTMLCollection::NamedItem: {
3372 JSValue *val = static_cast<HTMLCollection *>(thisObj)->getNamedItems(exec, Identifier(args[0]->toString(exec)));
3373 // Must return null when asking for a named item that isn't in the collection
3374 // (DOM2 testsuite, HTMLCollection12 test)
3375 if (val->type() == KJS::UndefinedType) {
3376 return jsNull();
3377 } else {
3378 return val;
3379 }
3380 }
3381 default:
3382 return jsUndefined();
3383 }
3384 }
3385
3386 // -------------------------------------------------------------------------
3387 /* Source for HTMLSelectCollectionProtoTable.
3388 @begin HTMLSelectCollectionProtoTable 1
3389 add HTMLSelectCollection::Add DontDelete|Function 2
3390 remove HTMLSelectCollection::Remove DontDelete|Function 1
3391 @end
3392 */
3393 KJS_DEFINE_PROTOTYPE(HTMLSelectCollectionProto)
3394 KJS_IMPLEMENT_PROTOFUNC(HTMLSelectCollectionProtoFunc)
3395 KJS_IMPLEMENT_PROTOTYPE("HTMLOptionsCollection", HTMLSelectCollectionProto, HTMLSelectCollectionProtoFunc, HTMLCollectionProto)
3396
3397 const ClassInfo KJS::HTMLSelectCollection::info = { "HTMLOptionsCollection", &HTMLCollection::info, nullptr, nullptr };
3398
HTMLSelectCollection(ExecState * exec,DOM::HTMLCollectionImpl * c,DOM::HTMLSelectElementImpl * e)3399 KJS::HTMLSelectCollection::HTMLSelectCollection(ExecState *exec, DOM::HTMLCollectionImpl *c,
3400 DOM::HTMLSelectElementImpl *e)
3401 : HTMLCollection(HTMLSelectCollectionProto::self(exec), c), element(e) { }
3402
selectedIndexGetter(ExecState *,JSObject *,const Identifier &,const PropertySlot & slot)3403 JSValue *HTMLSelectCollection::selectedIndexGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot &slot)
3404 {
3405 HTMLSelectCollection *thisObj = static_cast<HTMLSelectCollection *>(slot.slotBase());
3406 return jsNumber(thisObj->element->selectedIndex());
3407 }
3408
selectedValueGetter(ExecState *,JSObject *,const Identifier & propertyName,const PropertySlot & slot)3409 JSValue *HTMLSelectCollection::selectedValueGetter(ExecState *, JSObject *, const Identifier &propertyName, const PropertySlot &slot)
3410 {
3411 Q_UNUSED(propertyName);
3412 HTMLSelectCollection *thisObj = static_cast<HTMLSelectCollection *>(slot.slotBase());
3413 return jsString(thisObj->element->value());
3414 }
3415
getOwnPropertySlot(ExecState * exec,const Identifier & p,PropertySlot & slot)3416 bool KJS::HTMLSelectCollection::getOwnPropertySlot(ExecState *exec, const Identifier &p, PropertySlot &slot)
3417 {
3418 if (p == "selectedIndex") {
3419 slot.setCustom(this, selectedIndexGetter);
3420 return true;
3421 } else if (p == "value") {
3422 slot.setCustom(this, selectedValueGetter);
3423 return true;
3424 }
3425
3426 return HTMLCollection::getOwnPropertySlot(exec, p, slot);
3427 }
3428
put(ExecState * exec,const Identifier & propertyName,JSValue * value,int)3429 void KJS::HTMLSelectCollection::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int)
3430 {
3431 DOMExceptionTranslator exception(exec);
3432 #ifdef KJS_VERBOSE
3433 qCDebug(KHTML_LOG) << "KJS::HTMLSelectCollection::put " << propertyName.qstring();
3434 #endif
3435 if (propertyName == "selectedIndex") {
3436 element->setSelectedIndex(value->toInteger(exec));
3437 return;
3438 }
3439 // resize ?
3440 else if (propertyName == exec->propertyNames().length) {
3441 uint32_t newLen;
3442 bool converted = value->getUInt32(newLen);
3443
3444 if (!converted) {
3445 return;
3446 }
3447
3448 // CVE-2009-2537 (vendors agreed on max 10000 elements)
3449 if (newLen > 10000) {
3450 setDOMException(exec, DOMException::INDEX_SIZE_ERR);
3451 return;
3452 }
3453
3454 long diff = element->length() - newLen;
3455
3456 if (diff < 0) { // add dummy elements
3457 do {
3458 ElementImpl *option = element->document()->createElement("option", exception);
3459 if (exception.triggered()) {
3460 return;
3461 }
3462 element->add(static_cast<HTMLElementImpl *>(option), nullptr, exception);
3463 if (exception.triggered()) {
3464 return;
3465 }
3466 } while (++diff);
3467 } else // remove elements
3468 while (diff-- > 0) {
3469 element->remove(newLen + diff);
3470 }
3471
3472 return;
3473 }
3474 // an index ?
3475 bool ok;
3476 unsigned int u = propertyName.qstring().toULong(&ok);
3477 if (!ok) {
3478 return;
3479 }
3480
3481 if (value->type() == NullType || value->type() == UndefinedType) {
3482 // null and undefined delete. others, too ?
3483 element->remove(u);
3484 return;
3485 }
3486
3487 // is v an option element ?
3488 DOM::NodeImpl *node = KJS::toNode(value);
3489 if (!node || node->id() != ID_OPTION) {
3490 return;
3491 }
3492
3493 DOM::HTMLOptionElementImpl *option = static_cast<DOM::HTMLOptionElementImpl *>(node);
3494 if (option->document() != element->document()) {
3495 option = static_cast<DOM::HTMLOptionElementImpl *>(element->ownerDocument()->importNode(option, true, exception));
3496 }
3497 if (exception.triggered()) {
3498 delete option;
3499 return;
3500 }
3501
3502 long diff = long(u) - element->length();
3503 DOM::HTMLElementImpl *before = nullptr;
3504 // out of array bounds ? first insert empty dummies
3505 if (diff > 0) {
3506 while (diff--) {
3507 element->add(
3508 static_cast<DOM::HTMLElementImpl *>(element->document()->createElement("OPTION")),
3509 before, exception);
3510 if (exception.triggered()) {
3511 delete option;
3512 return;
3513 }
3514 }
3515 // replace an existing entry ?
3516 } else if (diff < 0) {
3517 SharedPtr<DOM::HTMLCollectionImpl> options = element->options();
3518 before = static_cast<DOM::HTMLElementImpl *>(options->item(u + 1));
3519 element->remove(u);
3520 }
3521 // finally add the new element
3522 element->add(option, before, exception);
3523 }
3524
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)3525 JSValue *KJS::HTMLSelectCollectionProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
3526 {
3527 KJS_CHECK_THIS(KJS::HTMLSelectCollection, thisObj);
3528 DOM::HTMLSelectElementImpl *element = static_cast<KJS::HTMLSelectCollection *>(thisObj)->toElement();
3529
3530 switch (id) {
3531 case KJS::HTMLSelectCollection::Add: {
3532 //Non-standard select.options.add.
3533 //The first argument is the item, 2nd is offset.
3534 //IE and Mozilla are both quite picky here, too...
3535 DOM::NodeImpl *node = KJS::toNode(args[0]);
3536 if (!node || node->id() != ID_OPTION) {
3537 return throwError(exec, GeneralError, "Invalid argument to HTMLOptionsCollection::add");
3538 }
3539
3540 DOM::HTMLOptionElementImpl *option = static_cast<DOM::HTMLOptionElementImpl *>(node);
3541
3542 int pos = 0;
3543 //By default append, if not specified or null..
3544 if (args[1]->isUndefined()) {
3545 pos = element->length();
3546 } else {
3547 pos = (int)args[1]->toNumber(exec);
3548 }
3549
3550 if (pos < 0) {
3551 return throwError(exec, GeneralError, "Invalid index argument to HTMLOptionsCollection::add");
3552 }
3553
3554 DOMExceptionTranslator exception(exec);
3555 if (pos >= element->length()) {
3556 //Append
3557 element->add(option, nullptr, exception);
3558 } else {
3559 //Find what to prepend before..
3560 QVector<HTMLGenericFormElementImpl *> items = element->listItems();
3561 int dummy;
3562 element->insertBefore(option, items.at(pos), dummy);
3563 }
3564 return jsUndefined();
3565 break;
3566 }
3567 case KJS::HTMLSelectCollection::Remove: {
3568 double index;
3569 if (!args[0]->getNumber(index)) {
3570 index = 0;
3571 } else {
3572 if (static_cast<long int>(index) >= element->length()) {
3573 index = 0;
3574 }
3575 }
3576 element->remove(static_cast<long int>(index));
3577 return jsUndefined();
3578 break;
3579 }
3580 default:
3581 break;
3582 }
3583 return jsUndefined();
3584 }
3585
3586 ////////////////////// Option Object ////////////////////////
3587
OptionConstructorImp(ExecState * exec,DOM::DocumentImpl * d)3588 OptionConstructorImp::OptionConstructorImp(ExecState *exec, DOM::DocumentImpl *d)
3589 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), doc(d)
3590 {
3591 // ## isn't there some redundancy between JSObject::_proto and the "prototype" property ?
3592 //put(exec,"prototype", ...,DontEnum|DontDelete|ReadOnly);
3593
3594 // no. of arguments for constructor
3595 // ## is 4 correct ? 0 to 4, it seems to be
3596 put(exec, exec->propertyNames().length, jsNumber(4), ReadOnly | DontDelete | DontEnum);
3597 }
3598
implementsConstruct() const3599 bool OptionConstructorImp::implementsConstruct() const
3600 {
3601 return true;
3602 }
3603
construct(ExecState * exec,const List & args)3604 JSObject *OptionConstructorImp::construct(ExecState *exec, const List &args)
3605 {
3606 DOMExceptionTranslator exception(exec);
3607 DOM::ElementImpl *el = doc->createElement("OPTION");
3608 DOM::HTMLOptionElementImpl *opt = static_cast<DOM::HTMLOptionElementImpl *>(el);
3609 int sz = args.size();
3610 SharedPtr<DOM::TextImpl> t = doc->createTextNode("");
3611
3612 int dummyexception = 0;// #### exec->setException ?
3613 opt->appendChild(t.get(), dummyexception);
3614
3615 if (sz > 0) {
3616 t->setData(args[0]->toString(exec).domString(), exception); // set the text
3617 }
3618 if (sz > 1) {
3619 opt->setValue(args[1]->toString(exec).domString().implementation());
3620 }
3621 if (sz > 2) {
3622 opt->setDefaultSelected(args[2]->toBoolean(exec));
3623 }
3624 if (sz > 3) {
3625 opt->setSelected(args[3]->toBoolean(exec));
3626 }
3627
3628 return getDOMNode(exec, opt)->getObject();
3629 }
3630
3631 ////////////////////// Image Object ////////////////////////
3632
3633 //Like in other browsers, we merely make a new HTMLImageElement
3634 //not in tree for this.
ImageConstructorImp(ExecState * exec,DOM::DocumentImpl * d)3635 ImageConstructorImp::ImageConstructorImp(ExecState *exec, DOM::DocumentImpl *d)
3636 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), doc(d)
3637 {
3638 }
3639
implementsConstruct() const3640 bool ImageConstructorImp::implementsConstruct() const
3641 {
3642 return true;
3643 }
3644
construct(ExecState * exec,const List & list)3645 JSObject *ImageConstructorImp::construct(ExecState *exec, const List &list)
3646 {
3647 bool widthSet = false, heightSet = false;
3648 int width = 0, height = 0;
3649 if (list.size() > 0) {
3650 widthSet = true;
3651 JSValue *w = list.at(0);
3652 width = w->toInt32(exec);
3653 }
3654 if (list.size() > 1) {
3655 heightSet = true;
3656 JSValue *h = list.at(1);
3657 height = h->toInt32(exec);
3658 }
3659
3660 HTMLImageElementImpl *image = static_cast<HTMLImageElementImpl *>(doc->createElement("img"));
3661
3662 if (widthSet) {
3663 image->setAttribute(ATTR_WIDTH, QString::number(width));
3664 }
3665
3666 if (heightSet) {
3667 image->setAttribute(ATTR_HEIGHT, QString::number(height));
3668 }
3669
3670 return getDOMNode(exec, image)->getObject();
3671 }
3672
getHTMLCollection(ExecState * exec,DOM::HTMLCollectionImpl * c,bool hide)3673 JSValue *getHTMLCollection(ExecState *exec, DOM::HTMLCollectionImpl *c, bool hide)
3674 {
3675 assert(!c || c->getType() != HTMLCollectionImpl::SELECT_OPTIONS);
3676 JSValue *coll = cacheDOMObject<DOM::HTMLCollectionImpl, KJS::HTMLCollection>(exec, c);
3677 if (hide) {
3678 KJS::HTMLCollection *impl = static_cast<KJS::HTMLCollection *>(coll);
3679 impl->hide();
3680 }
3681 return coll;
3682 }
3683
getSelectHTMLCollection(ExecState * exec,DOM::HTMLCollectionImpl * c,DOM::HTMLSelectElementImpl * e)3684 JSValue *getSelectHTMLCollection(ExecState *exec, DOM::HTMLCollectionImpl *c, DOM::HTMLSelectElementImpl *e)
3685 {
3686 assert(!c || c->getType() == HTMLCollectionImpl::SELECT_OPTIONS);
3687 DOMObject *ret;
3688 if (!c) {
3689 return jsNull();
3690 }
3691 ScriptInterpreter *interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
3692 if ((ret = interp->getDOMObject(c))) {
3693 return ret;
3694 } else {
3695 ret = new HTMLSelectCollection(exec, c, e);
3696 interp->putDOMObject(c, ret);
3697 return ret;
3698 }
3699 }
3700
3701 } //namespace KJS
3702