00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <khtmlview.h>
00023 #include "xml/dom2_eventsimpl.h"
00024 #include "rendering/render_canvas.h"
00025 #include "rendering/render_layer.h"
00026 #include "xml/dom_nodeimpl.h"
00027 #include "xml/dom_docimpl.h"
00028 #include "misc/htmltags.h"
00029 #include "misc/htmlattrs.h"
00030 #include "html/html_baseimpl.h"
00031 #include <kdebug.h>
00032 #include <khtml_part.h>
00033
00034 #include "kjs_dom.h"
00035 #include "kjs_html.h"
00036 #include "kjs_css.h"
00037 #include "kjs_range.h"
00038 #include "kjs_traversal.h"
00039 #include "kjs_events.h"
00040 #include "kjs_views.h"
00041 #include "kjs_window.h"
00042 #include "dom/dom_exception.h"
00043 #include "kjs_dom.lut.h"
00044 #include "khtmlpart_p.h"
00045
00046 using namespace KJS;
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 DEFINE_PROTOTYPE("DOMNode",DOMNodeProto)
00073 IMPLEMENT_PROTOFUNC_DOM(DOMNodeProtoFunc)
00074 IMPLEMENT_PROTOTYPE(DOMNodeProto,DOMNodeProtoFunc)
00075
00076 const ClassInfo DOMNode::info = { "Node", 0, &DOMNodeTable, 0 };
00077
00078 DOMNode::DOMNode(ExecState *exec, const DOM::Node& n)
00079 : DOMObject(DOMNodeProto::self(exec)), node(n)
00080 {
00081 }
00082
00083 DOMNode::DOMNode(const Object& proto, const DOM::Node& n)
00084 : DOMObject(proto), node(n)
00085 {
00086 }
00087
00088 DOMNode::~DOMNode()
00089 {
00090 ScriptInterpreter::forgetDOMObject(node.handle());
00091 }
00092
00093 bool DOMNode::toBoolean(ExecState *) const
00094 {
00095 return !node.isNull();
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 Value DOMNode::tryGet(ExecState *exec, const Identifier &propertyName) const
00160 {
00161 #ifdef KJS_VERBOSE
00162 kdDebug(6070) << "DOMNode::tryGet " << propertyName.qstring() << endl;
00163 #endif
00164 return DOMObjectLookupGetValue<DOMNode, DOMObject>(exec, propertyName, &DOMNodeTable, this);
00165 }
00166
00167 Value DOMNode::getValueProperty(ExecState *exec, int token) const
00168 {
00169 switch (token) {
00170 case NodeName:
00171 return String(node.nodeName());
00172 case NodeValue:
00173 return getString(node.nodeValue());
00174 case NodeType:
00175 return Number((unsigned int)node.nodeType());
00176 case ParentNode:
00177 return getDOMNode(exec,node.parentNode());
00178 case ParentElement:
00179 return getDOMNode(exec,node.parentNode());
00180 case ChildNodes:
00181 return getDOMNodeList(exec,node.childNodes());
00182 case FirstChild:
00183 return getDOMNode(exec,node.firstChild());
00184 case LastChild:
00185 return getDOMNode(exec,node.lastChild());
00186 case PreviousSibling:
00187 return getDOMNode(exec,node.previousSibling());
00188 case NextSibling:
00189 return getDOMNode(exec,node.nextSibling());
00190 case Attributes:
00191 return getDOMNamedNodeMap(exec,node.attributes());
00192 case NamespaceURI:
00193 return getString(node.namespaceURI());
00194 case Prefix:
00195 return getString(node.prefix());
00196 case LocalName:
00197 return getString(node.localName());
00198 case OwnerDocument:
00199 return getDOMNode(exec,node.ownerDocument());
00200 case OnAbort:
00201 return getListener(DOM::EventImpl::ABORT_EVENT);
00202 case OnBlur:
00203 return getListener(DOM::EventImpl::BLUR_EVENT);
00204 case OnChange:
00205 return getListener(DOM::EventImpl::CHANGE_EVENT);
00206 case OnClick:
00207 return getListener(DOM::EventImpl::KHTML_ECMA_CLICK_EVENT);
00208 case OnDblClick:
00209 return getListener(DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT);
00210 case OnDragDrop:
00211 return getListener(DOM::EventImpl::KHTML_DRAGDROP_EVENT);
00212 case OnError:
00213 return getListener(DOM::EventImpl::KHTML_ERROR_EVENT);
00214 case OnFocus:
00215 return getListener(DOM::EventImpl::FOCUS_EVENT);
00216 case OnKeyDown:
00217 return getListener(DOM::EventImpl::KEYDOWN_EVENT);
00218 case OnKeyPress:
00219 return getListener(DOM::EventImpl::KHTML_KEYPRESS_EVENT);
00220 case OnKeyUp:
00221 return getListener(DOM::EventImpl::KEYUP_EVENT);
00222 case OnLoad:
00223 return getListener(DOM::EventImpl::LOAD_EVENT);
00224 case OnMouseDown:
00225 return getListener(DOM::EventImpl::MOUSEDOWN_EVENT);
00226 case OnMouseMove:
00227 return getListener(DOM::EventImpl::MOUSEMOVE_EVENT);
00228 case OnMouseOut:
00229 return getListener(DOM::EventImpl::MOUSEOUT_EVENT);
00230 case OnMouseOver:
00231 return getListener(DOM::EventImpl::MOUSEOVER_EVENT);
00232 case OnMouseUp:
00233 return getListener(DOM::EventImpl::MOUSEUP_EVENT);
00234 case OnMove:
00235 return getListener(DOM::EventImpl::KHTML_MOVE_EVENT);
00236 case OnReset:
00237 return getListener(DOM::EventImpl::RESET_EVENT);
00238 case OnResize:
00239 return getListener(DOM::EventImpl::RESIZE_EVENT);
00240 case OnSelect:
00241 return getListener(DOM::EventImpl::SELECT_EVENT);
00242 case OnSubmit:
00243 return getListener(DOM::EventImpl::SUBMIT_EVENT);
00244 case OnUnload:
00245 return getListener(DOM::EventImpl::UNLOAD_EVENT);
00246 case SourceIndex: {
00247
00248
00249
00250 DOM::Document doc = node.ownerDocument();
00251 if (doc.isHTMLDocument()) {
00252 DOM::HTMLCollection all = static_cast<DOM::HTMLDocument>(doc).all();
00253 unsigned long i = 0;
00254 DOM::Node n = all.firstItem();
00255 for ( ; !n.isNull() && n != node; n = all.nextItem() )
00256 ++i;
00257 Q_ASSERT( !n.isNull() );
00258 return Number(i);
00259 }
00260 }
00261 default:
00262
00263
00264
00265 DOM::DocumentImpl* docimpl = node.handle()->getDocument();
00266 if (docimpl) {
00267 docimpl->updateLayout();
00268 }
00269
00270 khtml::RenderObject *rend = node.handle()->renderer();
00271
00272 switch (token) {
00273 case OffsetLeft:
00274 return rend ? static_cast<Value>( Number( rend->offsetLeft() ) ) : Undefined();
00275 case OffsetTop:
00276 return rend ? static_cast<Value>( Number( rend->offsetTop() ) ) : Undefined();
00277 case OffsetWidth:
00278 return rend ? static_cast<Value>( Number( rend->offsetWidth() ) ) : Undefined();
00279 case OffsetHeight:
00280 return rend ? static_cast<Value>( Number( rend->offsetHeight() ) ) : Undefined();
00281 case OffsetParent:
00282 {
00283 khtml::RenderObject* par = rend ? rend->offsetParent() : 0;
00284 return getDOMNode( exec, par ? par->element() : 0 );
00285 }
00286 case ClientWidth:
00287 return rend ? static_cast<Value>( Number( rend->clientWidth() ) ) : Undefined();
00288 case ClientHeight:
00289 return rend ? static_cast<Value>( Number( rend->clientHeight() ) ) : Undefined();
00290 case ScrollWidth:
00291 return rend ? static_cast<Value>( Number(rend->scrollWidth()) ) : Undefined();
00292 case ScrollHeight:
00293 return rend ? static_cast<Value>( Number(rend->scrollHeight()) ) : Undefined();
00294 case ScrollLeft:
00295 return Number( rend && rend->layer() ? rend->layer()->scrollXOffset() : 0 );
00296 case ScrollTop:
00297 return Number( rend && rend->layer() ? rend->layer()->scrollYOffset() : 0 );
00298 default:
00299 kdDebug(6070) << "WARNING: Unhandled token in DOMNode::getValueProperty : " << token << endl;
00300 break;
00301 }
00302 }
00303 return Undefined();
00304 }
00305
00306
00307 void DOMNode::tryPut(ExecState *exec, const Identifier& propertyName, const Value& value, int attr)
00308 {
00309 #ifdef KJS_VERBOSE
00310 kdDebug(6070) << "DOMNode::tryPut " << propertyName.qstring() << endl;
00311 #endif
00312 DOMObjectLookupPut<DOMNode,DOMObject>(exec, propertyName, value, attr,
00313 &DOMNodeTable, this );
00314 }
00315
00316 void DOMNode::putValueProperty(ExecState *exec, int token, const Value& value, int )
00317 {
00318 switch (token) {
00319 case NodeValue:
00320 node.setNodeValue(value.toString(exec).string());
00321 break;
00322 case Prefix:
00323 node.setPrefix(value.toString(exec).string());
00324 break;
00325 case OnAbort:
00326 setListener(exec,DOM::EventImpl::ABORT_EVENT,value);
00327 break;
00328 case OnBlur:
00329 setListener(exec,DOM::EventImpl::BLUR_EVENT,value);
00330 break;
00331 case OnChange:
00332 setListener(exec,DOM::EventImpl::CHANGE_EVENT,value);
00333 break;
00334 case OnClick:
00335 setListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT,value);
00336 break;
00337 case OnDblClick:
00338 setListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT,value);
00339 break;
00340 case OnDragDrop:
00341 setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
00342 break;
00343 case OnError:
00344 setListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT,value);
00345 break;
00346 case OnFocus:
00347 setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
00348 break;
00349 case OnKeyDown:
00350 setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
00351 break;
00352 case OnKeyPress:
00353 setListener(exec,DOM::EventImpl::KHTML_KEYPRESS_EVENT,value);
00354 break;
00355 case OnKeyUp:
00356 setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
00357 break;
00358 case OnLoad:
00359 setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
00360 break;
00361 case OnMouseDown:
00362 setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
00363 break;
00364 case OnMouseMove:
00365 setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
00366 break;
00367 case OnMouseOut:
00368 setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
00369 break;
00370 case OnMouseOver:
00371 setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
00372 break;
00373 case OnMouseUp:
00374 setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
00375 break;
00376 case OnMove:
00377 setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
00378 break;
00379 case OnReset:
00380 setListener(exec,DOM::EventImpl::RESET_EVENT,value);
00381 break;
00382 case OnResize:
00383 setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
00384 break;
00385 case OnSelect:
00386 setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
00387 break;
00388 case OnSubmit:
00389 setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
00390 break;
00391 case OnUnload:
00392 setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
00393 break;
00394 case ScrollTop: {
00395 khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
00396 if (rend && rend->layer() && rend->style()->hidesOverflow())
00397 rend->layer()->scrollToYOffset(value.toInt32(exec));
00398 break;
00399 }
00400 case ScrollLeft: {
00401 khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
00402 if (rend && rend->layer() && rend->style()->hidesOverflow())
00403 rend->layer()->scrollToXOffset(value.toInt32(exec));
00404 break;
00405 }
00406 default:
00407 kdDebug(6070) << "WARNING: DOMNode::putValueProperty unhandled token " << token << endl;
00408 }
00409 }
00410
00411 Value DOMNode::toPrimitive(ExecState *exec, Type ) const
00412 {
00413 if (node.isNull())
00414 return Null();
00415
00416 return String(toString(exec));
00417 }
00418
00419 UString DOMNode::toString(ExecState *) const
00420 {
00421 if (node.isNull())
00422 return "null";
00423 UString s;
00424
00425 DOM::Element e = node;
00426 if ( !e.isNull() ) {
00427 s = e.nodeName().string();
00428 } else
00429 s = className();
00430
00431 return "[object " + s + "]";
00432 }
00433
00434 void DOMNode::setListener(ExecState *exec, int eventId, const Value& func) const
00435 {
00436 node.handle()->setHTMLEventListener(eventId,Window::retrieveActive(exec)->getJSEventListener(func,true));
00437 }
00438
00439 Value DOMNode::getListener(int eventId) const
00440 {
00441 DOM::EventListener *listener = node.handle()->getHTMLEventListener(eventId);
00442 JSEventListener *jsListener = static_cast<JSEventListener*>(listener);
00443 if ( jsListener && jsListener->listenerObjImp() )
00444 return jsListener->listenerObj();
00445 else
00446 return Null();
00447 }
00448
00449 void DOMNode::pushEventHandlerScope(ExecState *, ScopeChain &) const
00450 {
00451 }
00452
00453 Value DOMNodeProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00454 {
00455 KJS_CHECK_THIS( DOMNode, thisObj );
00456 DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
00457 switch (id) {
00458 case DOMNode::HasAttributes:
00459 return Boolean(node.hasAttributes());
00460 case DOMNode::HasChildNodes:
00461 return Boolean(node.hasChildNodes());
00462 case DOMNode::CloneNode:
00463 return getDOMNode(exec,node.cloneNode(args[0].toBoolean(exec)));
00464 case DOMNode::Normalize:
00465 node.normalize();
00466 return Undefined();
00467 case DOMNode::IsSupported:
00468 return Boolean(node.isSupported(args[0].toString(exec).string(),args[1].toString(exec).string()));
00469 case DOMNode::AddEventListener: {
00470 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
00471 node.addEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
00472 return Undefined();
00473 }
00474 case DOMNode::RemoveEventListener: {
00475 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
00476 node.removeEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
00477 return Undefined();
00478 }
00479 case DOMNode::DispatchEvent:
00480 return Boolean(node.dispatchEvent(toEvent(args[0])));
00481 case DOMNode::AppendChild:
00482 return getDOMNode(exec,node.appendChild(toNode(args[0])));
00483 case DOMNode::RemoveChild:
00484 return getDOMNode(exec,node.removeChild(toNode(args[0])));
00485 case DOMNode::InsertBefore:
00486 return getDOMNode(exec,node.insertBefore(toNode(args[0]), toNode(args[1])));
00487 case DOMNode::ReplaceChild:
00488 return getDOMNode(exec,node.replaceChild(toNode(args[0]), toNode(args[1])));
00489 case DOMNode::Contains:
00490 {
00491 DOM::Node other = toNode(args[0]);
00492 if (!other.isNull() && node.nodeType()==DOM::Node::ELEMENT_NODE)
00493 {
00494 DOM::NodeBaseImpl *impl = static_cast<DOM::NodeBaseImpl *>(node.handle());
00495 bool retval = other.handle()->isAncestor(impl);
00496 return Boolean(retval);
00497 }
00498 return Undefined();
00499 }
00500 case DOMNode::InsertAdjacentHTML:
00501 {
00502
00503
00504 Range range = node.ownerDocument().createRange();
00505
00506 range.setStartBefore(node);
00507
00508 DocumentFragment docFrag = range.createContextualFragment(args[1].toString(exec).string());
00509
00510 DOMString where = args[0].toString(exec).string();
00511
00512 if (where == "beforeBegin" || where == "BeforeBegin")
00513 node.parentNode().insertBefore(docFrag, node);
00514 else if (where == "afterBegin" || where == "AfterBegin")
00515 node.insertBefore(docFrag, node.firstChild());
00516 else if (where == "beforeEnd" || where == "BeforeEnd")
00517 return getDOMNode(exec, node.appendChild(docFrag));
00518 else if (where == "afterEnd" || where == "AfterEnd")
00519 if (!node.nextSibling().isNull())
00520 node.parentNode().insertBefore(docFrag, node.nextSibling());
00521 else
00522 node.parentNode().appendChild(docFrag);
00523
00524 return Undefined();
00525 }
00526 case DOMNode::Item:
00527 return getDOMNode(exec, node.childNodes().item(static_cast<unsigned long>(args[0].toNumber(exec))));
00528 }
00529
00530 return Undefined();
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 DEFINE_PROTOTYPE("DOMNodeList", DOMNodeListProto)
00543 IMPLEMENT_PROTOFUNC_DOM(DOMNodeListProtoFunc)
00544 IMPLEMENT_PROTOTYPE(DOMNodeListProto,DOMNodeListProtoFunc)
00545
00546 const ClassInfo DOMNodeList::info = { "NodeList", 0, 0, 0 };
00547
00548 DOMNodeList::DOMNodeList(ExecState *exec, const DOM::NodeList& l)
00549 : DOMObject(DOMNodeListProto::self(exec)), list(l) { }
00550
00551 DOMNodeList::~DOMNodeList()
00552 {
00553 ScriptInterpreter::forgetDOMObject(list.handle());
00554 }
00555
00556
00557
00558 bool DOMNodeList::hasProperty(ExecState *exec, const Identifier &p) const
00559 {
00560 if (p == lengthPropertyName)
00561 return true;
00562
00563 return ObjectImp::hasProperty(exec, p);
00564 }
00565
00566 Value DOMNodeList::tryGet(ExecState *exec, const Identifier &p) const
00567 {
00568 #ifdef KJS_VERBOSE
00569 kdDebug(6070) << "DOMNodeList::tryGet " << p.ascii() << endl;
00570 #endif
00571 if (p == lengthPropertyName)
00572 return Number(list.length());
00573
00574
00575 Object proto = Object::dynamicCast(prototype());
00576 if (!proto.isNull() && proto.hasProperty(exec,p))
00577 return proto.get(exec,p);
00578
00579 Value result;
00580
00581
00582 bool ok;
00583 long unsigned int idx = p.toULong(&ok);
00584 if (ok)
00585 result = getDOMNode(exec,list.item(idx));
00586 else {
00587
00588 DOM::HTMLElement e;
00589 unsigned long l = list.length();
00590 bool found = false;
00591
00592 for ( unsigned long i = 0; i < l; i++ )
00593 if ( ( e = list.item( i ) ).id() == p.string() ) {
00594 result = getDOMNode(exec, list.item( i ) );
00595 found = true;
00596 break;
00597 }
00598
00599 if ( !found )
00600 result = ObjectImp::get(exec, p);
00601 }
00602
00603 return result;
00604 }
00605
00606
00607 Value DOMNodeList::call(ExecState *exec, Object &thisObj, const List &args)
00608 {
00609
00610 Value val;
00611 try {
00612 val = tryCall(exec, thisObj, args);
00613 }
00614
00615 catch (...) {
00616 Object err = Error::create(exec, GeneralError, "Exception from DOMNodeList");
00617 exec->setException(err);
00618 }
00619 return val;
00620 }
00621
00622 Value DOMNodeList::tryCall(ExecState *exec, Object &, const List &args)
00623 {
00624
00625 UString s = args[0].toString(exec);
00626
00627
00628 bool ok;
00629 unsigned int u = s.toULong(&ok);
00630 if (ok)
00631 return getDOMNode(exec,list.item(u));
00632
00633
00634
00635
00636 Value result = tryGet(exec, Identifier(s));
00637
00638 if (result.isValid())
00639 return result;
00640
00641 return Undefined();
00642 }
00643
00644
00645 Value DOMNodeListProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00646 {
00647 KJS_CHECK_THIS( KJS::DOMNodeList, thisObj );
00648 DOM::NodeList list = static_cast<DOMNodeList *>(thisObj.imp())->nodeList();
00649 switch (id) {
00650 case KJS::DOMNodeList::Item:
00651 return getDOMNode(exec, list.item(args[0].toInt32(exec)));
00652 case KJS::DOMNodeList::NamedItem:
00653 {
00654
00655
00656 DOM::HTMLElement e;
00657 unsigned long len = list.length();
00658 DOM::DOMString s = args[0].toString(exec).string();
00659
00660 for ( unsigned long i = 0; i < len; i++ )
00661 {
00662 e = list.item( i );
00663 if ( !e.isNull() && (
00664 e.id() == s || static_cast<ElementImpl *>(e.handle())->getAttribute(ATTR_NAME) == s )
00665 )
00666 {
00667 return getDOMNode(exec, e );
00668 }
00669 }
00670 return Null();
00671 }
00672 default:
00673 return Undefined();
00674 }
00675 }
00676
00677
00678
00679 const ClassInfo DOMAttr::info = { "Attr", &DOMNode::info, &DOMAttrTable, 0 };
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 Value DOMAttr::tryGet(ExecState *exec, const Identifier &propertyName) const
00690 {
00691 #ifdef KJS_VERBOSE
00692 kdDebug(6070) << "DOMAttr::tryGet " << propertyName.qstring() << endl;
00693 #endif
00694 return DOMObjectLookupGetValue<DOMAttr,DOMNode>(exec, propertyName,
00695 &DOMAttrTable, this );
00696 }
00697
00698 Value DOMAttr::getValueProperty(ExecState *exec, int token) const
00699 {
00700 switch (token) {
00701 case Name:
00702 return String(static_cast<DOM::Attr>(node).name());
00703 case Specified:
00704 return Boolean(static_cast<DOM::Attr>(node).specified());
00705 case ValueProperty:
00706 return String(static_cast<DOM::Attr>(node).value());
00707 case OwnerElement:
00708 return getDOMNode(exec,static_cast<DOM::Attr>(node).ownerElement());
00709 }
00710 return Value();
00711 }
00712
00713 void DOMAttr::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
00714 {
00715 #ifdef KJS_VERBOSE
00716 kdDebug(6070) << "DOMAttr::tryPut " << propertyName.qstring() << endl;
00717 #endif
00718 DOMObjectLookupPut<DOMAttr,DOMNode>(exec, propertyName, value, attr,
00719 &DOMAttrTable, this );
00720 }
00721
00722 void DOMAttr::putValueProperty(ExecState *exec, int token, const Value& value, int )
00723 {
00724 switch (token) {
00725 case ValueProperty:
00726 static_cast<DOM::Attr>(node).setValue(value.toString(exec).string());
00727 return;
00728 default:
00729 kdDebug(6070) << "WARNING: DOMAttr::putValueProperty unhandled token " << token << endl;
00730 }
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 DEFINE_PROTOTYPE("DOMDocument", DOMDocumentProto)
00762 IMPLEMENT_PROTOFUNC_DOM(DOMDocumentProtoFunc)
00763 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMDocumentProto, DOMDocumentProtoFunc, DOMNodeProto)
00764
00765 const ClassInfo DOMDocument::info = { "Document", &DOMNode::info, &DOMDocumentTable, 0 };
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781 DOMDocument::DOMDocument(ExecState *exec, const DOM::Document& d)
00782 : DOMNode(DOMDocumentProto::self(exec), d) { }
00783
00784 DOMDocument::DOMDocument(const Object& proto, const DOM::Document& d)
00785 : DOMNode(proto, d) { }
00786
00787 DOMDocument::~DOMDocument()
00788 {
00789 ScriptInterpreter::forgetDOMObject(node.handle());
00790 }
00791
00792 Value DOMDocument::tryGet(ExecState *exec, const Identifier &propertyName) const
00793 {
00794 #ifdef KJS_VERBOSE
00795 kdDebug(6070) << "DOMDocument::tryGet " << propertyName.qstring() << endl;
00796 #endif
00797 return DOMObjectLookupGetValue<DOMDocument, DOMNode>(
00798 exec, propertyName, &DOMDocumentTable, this);
00799 }
00800
00801 Value DOMDocument::getValueProperty(ExecState *exec, int token) const
00802 {
00803 DOM::Document doc = static_cast<DOM::Document>(node);
00804
00805 switch(token) {
00806 case DocType:
00807 return getDOMNode(exec,doc.doctype());
00808 case Implementation:
00809 return getDOMDOMImplementation(exec,doc.implementation());
00810 case DocumentElement:
00811 return getDOMNode(exec,doc.documentElement());
00812 case StyleSheets:
00813
00814 return getDOMStyleSheetList(exec, doc.styleSheets(), doc);
00815 case DOMDocument::DefaultView:
00816 return getDOMAbstractView(exec, doc.defaultView());
00817 case PreferredStylesheetSet:
00818 return String(doc.preferredStylesheetSet());
00819 case SelectedStylesheetSet:
00820 return String(doc.selectedStylesheetSet());
00821 case ReadyState:
00822 {
00823 DOM::DocumentImpl* docimpl = node.handle()->getDocument();
00824 if ( docimpl && docimpl->view() )
00825 {
00826 KHTMLPart* part = docimpl->view()->part();
00827 if ( part ) {
00828 if (part->d->m_bComplete) return String("complete");
00829 if (docimpl->parsing()) return String("loading");
00830 return String("loaded");
00831
00832
00833 }
00834 }
00835 return Undefined();
00836 }
00837 case Async:
00838 return Boolean(doc.async());
00839 default:
00840 kdDebug(6070) << "WARNING: DOMDocument::getValueProperty unhandled token " << token << endl;
00841 return Value();
00842 }
00843 }
00844
00845 void DOMDocument::tryPut(ExecState *exec, const Identifier& propertyName, const Value& value, int attr)
00846 {
00847 #ifdef KJS_VERBOSE
00848 kdDebug(6070) << "DOMDocument::tryPut " << propertyName.qstring() << endl;
00849 #endif
00850 DOMObjectLookupPut<DOMDocument,DOMNode>(exec, propertyName, value, attr, &DOMDocumentTable, this );
00851 }
00852
00853 void DOMDocument::putValueProperty(ExecState *exec, int token, const Value& value, int )
00854 {
00855 DOM::Document doc = static_cast<DOM::Document>(node);
00856 switch (token) {
00857 case SelectedStylesheetSet: {
00858 doc.setSelectedStylesheetSet(value.toString(exec).string());
00859 break;
00860 }
00861 case Async: {
00862 doc.setAsync(value.toBoolean(exec));
00863 break;
00864 }
00865 }
00866 }
00867
00868 Value DOMDocumentProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00869 {
00870 KJS_CHECK_THIS( KJS::DOMDocument, thisObj );
00871 DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
00872 DOM::Document doc = static_cast<DOM::Document>(node);
00873 String str = args[0].toString(exec);
00874 DOM::DOMString s = str.value().string();
00875
00876 switch(id) {
00877 case DOMDocument::CreateElement:
00878 return getDOMNode(exec,doc.createElement(s));
00879 case DOMDocument::CreateDocumentFragment:
00880 return getDOMNode(exec,doc.createDocumentFragment());
00881 case DOMDocument::CreateTextNode:
00882 return getDOMNode(exec,doc.createTextNode(s));
00883 case DOMDocument::CreateComment:
00884 return getDOMNode(exec,doc.createComment(s));
00885 case DOMDocument::CreateCDATASection:
00886 return getDOMNode(exec,doc.createCDATASection(s));
00887 case DOMDocument::CreateProcessingInstruction:
00888 return getDOMNode(exec,doc.createProcessingInstruction(args[0].toString(exec).string(),
00889 args[1].toString(exec).string()));
00890 case DOMDocument::CreateAttribute:
00891 return getDOMNode(exec,doc.createAttribute(s));
00892 case DOMDocument::CreateEntityReference:
00893 return getDOMNode(exec,doc.createEntityReference(args[0].toString(exec).string()));
00894 case DOMDocument::GetElementsByTagName:
00895 return getDOMNodeList(exec,doc.getElementsByTagName(s));
00896 case DOMDocument::ImportNode:
00897 return getDOMNode(exec,doc.importNode(toNode(args[0]), args[1].toBoolean(exec)));
00898 case DOMDocument::CreateElementNS:
00899 return getDOMNode(exec,doc.createElementNS(args[0].toString(exec).string(), args[1].toString(exec).string()));
00900 case DOMDocument::CreateAttributeNS:
00901 return getDOMNode(exec,doc.createAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
00902 case DOMDocument::GetElementsByTagNameNS:
00903 return getDOMNodeList(exec,doc.getElementsByTagNameNS(args[0].toString(exec).string(),
00904 args[1].toString(exec).string()));
00905 case DOMDocument::GetElementById:
00906 #ifdef KJS_VERBOSE
00907 kdDebug(6070) << "DOMDocument::GetElementById looking for " << args[0].toString(exec).string() << endl;
00908 #endif
00909 return getDOMNode(exec,doc.getElementById(args[0].toString(exec).string()));
00910 case DOMDocument::CreateRange:
00911 return getDOMRange(exec,doc.createRange());
00912 case DOMDocument::CreateNodeIterator:
00913 if (args[2].isA(NullType)) {
00914 DOM::NodeFilter filter;
00915 return getDOMNodeIterator(exec,
00916 doc.createNodeIterator(toNode(args[0]),
00917 (long unsigned int)(args[1].toNumber(exec)),
00918 filter,args[3].toBoolean(exec)));
00919 }
00920 else {
00921 Object obj = Object::dynamicCast(args[2]);
00922 if (!obj.isNull())
00923 {
00924 DOM::CustomNodeFilter *customFilter = new JSNodeFilter(obj);
00925 DOM::NodeFilter filter = DOM::NodeFilter::createCustom(customFilter);
00926 return getDOMNodeIterator(exec,
00927 doc.createNodeIterator(
00928 toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
00929 filter,args[3].toBoolean(exec)));
00930 }
00931 }
00932 case DOMDocument::CreateTreeWalker:
00933 return getDOMTreeWalker(exec,doc.createTreeWalker(toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
00934 toNodeFilter(args[2]),args[3].toBoolean(exec)));
00935 case DOMDocument::CreateEvent:
00936 return getDOMEvent(exec,doc.createEvent(s));
00937 case DOMDocument::GetOverrideStyle: {
00938 DOM::Node arg0 = toNode(args[0]);
00939 if (arg0.nodeType() != DOM::Node::ELEMENT_NODE)
00940 return Undefined();
00941 else
00942 return getDOMCSSStyleDeclaration(exec,doc.getOverrideStyle(static_cast<DOM::Element>(arg0),args[1].toString(exec).string()));
00943 }
00944 case DOMDocument::Abort:
00945 doc.abort();
00946 break;
00947 case DOMDocument::Load: {
00948 Window* active = Window::retrieveActive(exec);
00949
00950
00951 KHTMLPart *khtmlpart = ::qt_cast<KHTMLPart *>(active->part());
00952 if (khtmlpart) {
00953
00954 QString dstUrl = khtmlpart->htmlDocument().completeURL(s).string();
00955 KParts::ReadOnlyPart *part = static_cast<KJS::ScriptInterpreter*>(exec->interpreter())->part();
00956 if (part->url().host() == KURL(dstUrl).host()) {
00957 kdDebug(6070) << "JavaScript: access granted for document.load() of " << dstUrl << endl;
00958 doc.load(dstUrl);
00959 }
00960 else {
00961 kdDebug(6070) << "JavaScript: access denied for document.load() of " << dstUrl << endl;
00962 }
00963 }
00964 break;
00965 }
00966 case DOMDocument::LoadXML:
00967 doc.loadXML(s);
00968 break;
00969 default:
00970 break;
00971 }
00972
00973 return Undefined();
00974 }
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 DEFINE_PROTOTYPE("DOMElement",DOMElementProto)
00998 IMPLEMENT_PROTOFUNC_DOM(DOMElementProtoFunc)
00999 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMElementProto,DOMElementProtoFunc,DOMNodeProto)
01000
01001 const ClassInfo DOMElement::info = { "Element", &DOMNode::info, &DOMElementTable, 0 };
01002
01003
01004
01005
01006
01007
01008 DOMElement::DOMElement(ExecState *exec, const DOM::Element& e)
01009 : DOMNode(DOMElementProto::self(exec), e) { }
01010
01011 DOMElement::DOMElement(const Object& proto, const DOM::Element& e)
01012 : DOMNode(proto, e) { }
01013
01014 Value DOMElement::tryGet(ExecState *exec, const Identifier &propertyName) const
01015 {
01016 #ifdef KJS_VERBOSE
01017 kdDebug(6070) << "DOMElement::tryGet " << propertyName.qstring() << endl;
01018 #endif
01019 DOM::Element element = static_cast<DOM::Element>(node);
01020
01021 const HashEntry* entry = Lookup::findEntry(&DOMElementTable, propertyName);
01022 if (entry)
01023 {
01024 switch( entry->value ) {
01025 case TagName:
01026 return String(element.tagName());
01027 case Style:
01028 return getDOMCSSStyleDeclaration(exec,element.style());
01029 default:
01030 kdDebug(6070) << "WARNING: Unhandled token in DOMElement::tryGet : " << entry->value << endl;
01031 break;
01032 }
01033 }
01034
01035
01036
01037 if (DOMNode::hasProperty(exec, propertyName))
01038 return DOMNode::tryGet(exec, propertyName);
01039
01040 DOM::DOMString attr = element.getAttribute( propertyName.string() );
01041
01042 if ( !attr.isNull() )
01043 return String( attr );
01044
01045 return Undefined();
01046 }
01047
01048 Value DOMElementProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01049 {
01050 KJS_CHECK_THIS( KJS::DOMNode, thisObj );
01051 DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
01052 DOM::Element element = static_cast<DOM::Element>(node);
01053
01054 switch(id) {
01055 case DOMElement::GetAttribute:
01056 return String(element.getAttribute(args[0].toString(exec).string()));
01057 case DOMElement::SetAttribute:
01058 element.setAttribute(args[0].toString(exec).string(),args[1].toString(exec).string());
01059 return Undefined();
01060 case DOMElement::RemoveAttribute:
01061 element.removeAttribute(args[0].toString(exec).string());
01062 return Undefined();
01063 case DOMElement::GetAttributeNode:
01064 return getDOMNode(exec,element.getAttributeNode(args[0].toString(exec).string()));
01065 case DOMElement::SetAttributeNode:
01066 return getDOMNode(exec,element.setAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
01067 case DOMElement::RemoveAttributeNode:
01068 return getDOMNode(exec,element.removeAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
01069 case DOMElement::GetElementsByTagName:
01070 return getDOMNodeList(exec,element.getElementsByTagName(args[0].toString(exec).string()));
01071 case DOMElement::HasAttribute:
01072 return Boolean(element.hasAttribute(args[0].toString(exec).string()));
01073 case DOMElement::GetAttributeNS:
01074 return String(element.getAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01075 case DOMElement::SetAttributeNS:
01076 element.setAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string());
01077 return Undefined();
01078 case DOMElement::RemoveAttributeNS:
01079 element.removeAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string());
01080 return Undefined();
01081 case DOMElement::GetAttributeNodeNS:
01082 return getDOMNode(exec,element.getAttributeNodeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01083 case DOMElement::SetAttributeNodeNS:
01084 return getDOMNode(exec,element.setAttributeNodeNS((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
01085 case DOMElement::GetElementsByTagNameNS:
01086 return getDOMNodeList(exec,element.getElementsByTagNameNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01087 case DOMElement::HasAttributeNS:
01088 return Boolean(element.hasAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01089 default:
01090 return Undefined();
01091 }
01092 }
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106 DEFINE_PROTOTYPE("DOMImplementation",DOMDOMImplementationProto)
01107 IMPLEMENT_PROTOFUNC_DOM(DOMDOMImplementationProtoFunc)
01108 IMPLEMENT_PROTOTYPE(DOMDOMImplementationProto,DOMDOMImplementationProtoFunc)
01109
01110 const ClassInfo DOMDOMImplementation::info = { "DOMImplementation", 0, 0, 0 };
01111
01112 DOMDOMImplementation::DOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
01113 : DOMObject(DOMDOMImplementationProto::self(exec)), implementation(i) { }
01114
01115 DOMDOMImplementation::~DOMDOMImplementation()
01116 {
01117 ScriptInterpreter::forgetDOMObject(implementation.handle());
01118 }
01119
01120 Value DOMDOMImplementationProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01121 {
01122 KJS_CHECK_THIS( KJS::DOMDOMImplementation, thisObj );
01123 DOM::DOMImplementation implementation = static_cast<DOMDOMImplementation *>( thisObj.imp() )->toImplementation();
01124
01125 switch(id) {
01126 case DOMDOMImplementation::HasFeature:
01127 return Boolean(implementation.hasFeature(args[0].toString(exec).string(),args[1].toString(exec).string()));
01128 case DOMDOMImplementation::CreateDocumentType:
01129 return getDOMNode(exec,implementation.createDocumentType(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string()));
01130 case DOMDOMImplementation::CreateDocument: {
01131
01132
01133 KHTMLPart *part = ::qt_cast<KHTMLPart*>(static_cast<KJS::ScriptInterpreter*>(exec->interpreter())->part());
01134 if (part) {
01135 Document doc = implementation.createDocument(args[0].toString(exec).string(),args[1].toString(exec).string(),toNode(args[2]));
01136 KURL url = static_cast<DocumentImpl*>(part->document().handle())->URL();
01137 static_cast<DocumentImpl*>(doc.handle())->setURL(url.url());
01138 return getDOMNode(exec,doc);
01139 }
01140 break;
01141 }
01142 case DOMDOMImplementation::CreateCSSStyleSheet:
01143 return getDOMStyleSheet(exec,implementation.createCSSStyleSheet(args[0].toString(exec).string(),args[1].toString(exec).string()));
01144 case DOMDOMImplementation::CreateHTMLDocument:
01145 return getDOMNode(exec, implementation.createHTMLDocument(args[0].toString(exec).string()));
01146 default:
01147 break;
01148 }
01149 return Undefined();
01150 }
01151
01152
01153
01154 const ClassInfo DOMDocumentType::info = { "DocumentType", &DOMNode::info, &DOMDocumentTypeTable, 0 };
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167 DOMDocumentType::DOMDocumentType(ExecState *exec, const DOM::DocumentType& dt)
01168 : DOMNode( exec, dt ) { }
01169
01170 Value DOMDocumentType::tryGet(ExecState *exec, const Identifier &propertyName) const
01171 {
01172 #ifdef KJS_VERBOSE
01173 kdDebug(6070) << "DOMDocumentType::tryGet " << propertyName.qstring() << endl;
01174 #endif
01175 return DOMObjectLookupGetValue<DOMDocumentType, DOMNode>(exec, propertyName, &DOMDocumentTypeTable, this);
01176 }
01177
01178 Value DOMDocumentType::getValueProperty(ExecState *exec, int token) const
01179 {
01180 DOM::DocumentType type = static_cast<DOM::DocumentType>(node);
01181 switch (token) {
01182 case Name:
01183 return String(type.name());
01184 case Entities:
01185 return getDOMNamedNodeMap(exec,type.entities());
01186 case Notations:
01187 return getDOMNamedNodeMap(exec,type.notations());
01188 case PublicId:
01189 return String(type.publicId());
01190 case SystemId:
01191 return String(type.systemId());
01192 case InternalSubset:
01193 return getString(type.internalSubset());
01194 default:
01195 kdDebug(6070) << "WARNING: DOMDocumentType::getValueProperty unhandled token " << token << endl;
01196 return Value();
01197 }
01198 }
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214 DEFINE_PROTOTYPE("NamedNodeMap", DOMNamedNodeMapProto)
01215 IMPLEMENT_PROTOFUNC_DOM(DOMNamedNodeMapProtoFunc)
01216 IMPLEMENT_PROTOTYPE(DOMNamedNodeMapProto,DOMNamedNodeMapProtoFunc)
01217
01218 const ClassInfo DOMNamedNodeMap::info = { "NamedNodeMap", 0, 0, 0 };
01219
01220 DOMNamedNodeMap::DOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
01221 : DOMObject(DOMNamedNodeMapProto::self(exec)), map(m) { }
01222
01223 DOMNamedNodeMap::~DOMNamedNodeMap()
01224 {
01225 ScriptInterpreter::forgetDOMObject(map.handle());
01226 }
01227
01228
01229
01230 bool DOMNamedNodeMap::hasProperty(ExecState *exec, const Identifier &p) const
01231 {
01232 if (p == lengthPropertyName)
01233 return true;
01234
01235 return DOMObject::hasProperty(exec, p);
01236 }
01237
01238 Value DOMNamedNodeMap::tryGet(ExecState* exec, const Identifier &p) const
01239 {
01240 if (p == lengthPropertyName)
01241 return Number(map.length());
01242
01243
01244 bool ok;
01245 long unsigned int idx = p.toULong(&ok);
01246 if (ok)
01247 return getDOMNode(exec,map.item(idx));
01248
01249
01250 return DOMObject::tryGet(exec, p);
01251 }
01252
01253 Value DOMNamedNodeMapProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01254 {
01255 KJS_CHECK_THIS( KJS::DOMNamedNodeMap, thisObj );
01256 DOM::NamedNodeMap map = static_cast<DOMNamedNodeMap *>(thisObj.imp())->toMap();
01257
01258 switch(id) {
01259 case DOMNamedNodeMap::GetNamedItem:
01260 return getDOMNode(exec, map.getNamedItem(args[0].toString(exec).string()));
01261 case DOMNamedNodeMap::SetNamedItem:
01262 return getDOMNode(exec, map.setNamedItem((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
01263 case DOMNamedNodeMap::RemoveNamedItem:
01264 return getDOMNode(exec, map.removeNamedItem(args[0].toString(exec).string()));
01265 case DOMNamedNodeMap::Item:
01266 return getDOMNode(exec, map.item(args[0].toInt32(exec)));
01267 case DOMNamedNodeMap::GetNamedItemNS:
01268 return getDOMNode(exec, map.getNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01269 case DOMNamedNodeMap::SetNamedItemNS:
01270 return getDOMNode(exec, map.setNamedItemNS(toNode(args[0])));
01271 case DOMNamedNodeMap::RemoveNamedItemNS:
01272 return getDOMNode(exec, map.removeNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01273 default:
01274 break;
01275 }
01276
01277 return Undefined();
01278 }
01279
01280
01281
01282 const ClassInfo DOMProcessingInstruction::info = { "ProcessingInstruction", &DOMNode::info, &DOMProcessingInstructionTable, 0 };
01283
01284
01285
01286
01287
01288
01289
01290
01291 Value DOMProcessingInstruction::tryGet(ExecState *exec, const Identifier &propertyName) const
01292 {
01293 return DOMObjectLookupGetValue<DOMProcessingInstruction, DOMNode>(exec, propertyName, &DOMProcessingInstructionTable, this);
01294 }
01295
01296 Value DOMProcessingInstruction::getValueProperty(ExecState *exec, int token) const
01297 {
01298 switch (token) {
01299 case Target:
01300 return String(static_cast<DOM::ProcessingInstruction>(node).target());
01301 case Data:
01302 return String(static_cast<DOM::ProcessingInstruction>(node).data());
01303 case Sheet:
01304 return getDOMStyleSheet(exec,static_cast<DOM::ProcessingInstruction>(node).sheet());
01305 default:
01306 kdDebug(6070) << "WARNING: DOMProcessingInstruction::getValueProperty unhandled token " << token << endl;
01307 return Value();
01308 }
01309 }
01310
01311 void DOMProcessingInstruction::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
01312 {
01313
01314 if (propertyName == "data")
01315 static_cast<DOM::ProcessingInstruction>(node).setData(value.toString(exec).string());
01316 else
01317 DOMNode::tryPut(exec, propertyName,value,attr);
01318 }
01319
01320
01321
01322 const ClassInfo DOMNotation::info = { "Notation", &DOMNode::info, &DOMNotationTable, 0 };
01323
01324
01325
01326
01327
01328
01329
01330 Value DOMNotation::tryGet(ExecState *exec, const Identifier &propertyName) const
01331 {
01332 return DOMObjectLookupGetValue<DOMNotation, DOMNode>(exec, propertyName, &DOMNotationTable, this);
01333 }
01334
01335 Value DOMNotation::getValueProperty(ExecState *, int token) const
01336 {
01337 switch (token) {
01338 case PublicId:
01339 return String(static_cast<DOM::Notation>(node).publicId());
01340 case SystemId:
01341 return String(static_cast<DOM::Notation>(node).systemId());
01342 default:
01343 kdDebug(6070) << "WARNING: DOMNotation::getValueProperty unhandled token " << token << endl;
01344 return Value();
01345 }
01346 }
01347
01348
01349
01350 const ClassInfo DOMEntity::info = { "Entity", &DOMNode::info, 0, 0 };
01351
01352
01353
01354
01355
01356
01357
01358
01359 Value DOMEntity::tryGet(ExecState *exec, const Identifier &propertyName) const
01360 {
01361 return DOMObjectLookupGetValue<DOMEntity, DOMNode>(exec, propertyName, &DOMEntityTable, this);
01362 }
01363
01364 Value DOMEntity::getValueProperty(ExecState *, int token) const
01365 {
01366 switch (token) {
01367 case PublicId:
01368 return String(static_cast<DOM::Entity>(node).publicId());
01369 case SystemId:
01370 return String(static_cast<DOM::Entity>(node).systemId());
01371 case NotationName:
01372 return String(static_cast<DOM::Entity>(node).notationName());
01373 default:
01374 kdDebug(6070) << "WARNING: DOMEntity::getValueProperty unhandled token " << token << endl;
01375 return Value();
01376 }
01377 }
01378
01379
01380
01381 bool KJS::checkNodeSecurity(ExecState *exec, const DOM::Node& n)
01382 {
01383
01384 if (n.isNull())
01385 return true;
01386 KHTMLView *view = n.handle()->getDocument()->view();
01387 Window* win = view && view->part() ? Window::retrieveWindow(view->part()) : 0L;
01388 if ( !win || !win->isSafeScript(exec) )
01389 return false;
01390 return true;
01391 }
01392
01393 Value KJS::getDOMNode(ExecState *exec, const DOM::Node& n)
01394 {
01395 DOMObject *ret = 0;
01396 if (n.isNull())
01397 return Null();
01398 ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
01399 if ((ret = interp->getDOMObject(n.handle())))
01400 return Value(ret);
01401
01402 switch (n.nodeType()) {
01403 case DOM::Node::ELEMENT_NODE:
01404 if (static_cast<DOM::Element>(n).isHTMLElement())
01405 ret = new HTMLElement(exec, static_cast<DOM::HTMLElement>(n));
01406 else
01407 ret = new DOMElement(exec, static_cast<DOM::Element>(n));
01408 break;
01409 case DOM::Node::ATTRIBUTE_NODE:
01410 ret = new DOMAttr(exec, static_cast<DOM::Attr>(n));
01411 break;
01412 case DOM::Node::TEXT_NODE:
01413 case DOM::Node::CDATA_SECTION_NODE:
01414 ret = new DOMText(exec, static_cast<DOM::Text>(n));
01415 break;
01416 case DOM::Node::ENTITY_REFERENCE_NODE:
01417 ret = new DOMNode(exec, n);
01418 break;
01419 case DOM::Node::ENTITY_NODE:
01420 ret = new DOMEntity(exec, static_cast<DOM::Entity>(n));
01421 break;
01422 case DOM::Node::PROCESSING_INSTRUCTION_NODE:
01423 ret = new DOMProcessingInstruction(exec, static_cast<DOM::ProcessingInstruction>(n));
01424 break;
01425 case DOM::Node::COMMENT_NODE:
01426 ret = new DOMCharacterData(exec, static_cast<DOM::CharacterData>(n));
01427 break;
01428 case DOM::Node::DOCUMENT_NODE:
01429 if (static_cast<DOM::Document>(n).isHTMLDocument())
01430 ret = new HTMLDocument(exec, static_cast<DOM::HTMLDocument>(n));
01431 else
01432 ret = new DOMDocument(exec, static_cast<DOM::Document>(n));
01433 break;
01434 case DOM::Node::DOCUMENT_TYPE_NODE:
01435 ret = new DOMDocumentType(exec, static_cast<DOM::DocumentType>(n));
01436 break;
01437 case DOM::Node::DOCUMENT_FRAGMENT_NODE:
01438 ret = new DOMNode(exec, n);
01439 break;
01440 case DOM::Node::NOTATION_NODE:
01441 ret = new DOMNotation(exec, static_cast<DOM::Notation>(n));
01442 break;
01443 default:
01444 ret = new DOMNode(exec, n);
01445 }
01446 interp->putDOMObject(n.handle(),ret);
01447
01448 return Value(ret);
01449 }
01450
01451 Value KJS::getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
01452 {
01453 return Value(cacheDOMObject<DOM::NamedNodeMap, KJS::DOMNamedNodeMap>(exec, m));
01454 }
01455
01456 Value KJS::getDOMNodeList(ExecState *exec, const DOM::NodeList& l)
01457 {
01458 return Value(cacheDOMObject<DOM::NodeList, KJS::DOMNodeList>(exec, l));
01459 }
01460
01461 Value KJS::getDOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
01462 {
01463 return Value(cacheDOMObject<DOM::DOMImplementation, KJS::DOMDOMImplementation>(exec, i));
01464 }
01465
01466
01467
01468 const ClassInfo NodeConstructor::info = { "NodeConstructor", 0, &NodeConstructorTable, 0 };
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486 NodeConstructor::NodeConstructor(ExecState *exec)
01487 : DOMObject(exec->interpreter()->builtinObjectPrototype())
01488 {
01489 }
01490
01491 Value NodeConstructor::tryGet(ExecState *exec, const Identifier &propertyName) const
01492 {
01493 return DOMObjectLookupGetValue<NodeConstructor, DOMObject>(exec, propertyName, &NodeConstructorTable, this);
01494 }
01495
01496 Value NodeConstructor::getValueProperty(ExecState *, int token) const
01497 {
01498
01499 return Number((unsigned int)token);
01500 #if 0
01501 switch (token) {
01502 case ELEMENT_NODE:
01503 return Number((unsigned int)DOM::Node::ELEMENT_NODE);
01504 case ATTRIBUTE_NODE:
01505 return Number((unsigned int)DOM::Node::ATTRIBUTE_NODE);
01506 case TEXT_NODE:
01507 return Number((unsigned int)DOM::Node::TEXT_NODE);
01508 case CDATA_SECTION_NODE:
01509 return Number((unsigned int)DOM::Node::CDATA_SECTION_NODE);
01510 case ENTITY_REFERENCE_NODE:
01511 return Number((unsigned int)DOM::Node::ENTITY_REFERENCE_NODE);
01512 case ENTITY_NODE:
01513 return Number((unsigned int)DOM::Node::ENTITY_NODE);
01514 case PROCESSING_INSTRUCTION_NODE:
01515 return Number((unsigned int)DOM::Node::PROCESSING_INSTRUCTION_NODE);
01516 case COMMENT_NODE:
01517 return Number((unsigned int)DOM::Node::COMMENT_NODE);
01518 case DOCUMENT_NODE:
01519 return Number((unsigned int)DOM::Node::DOCUMENT_NODE);
01520 case DOCUMENT_TYPE_NODE:
01521 return Number((unsigned int)DOM::Node::DOCUMENT_TYPE_NODE);
01522 case DOCUMENT_FRAGMENT_NODE:
01523 return Number((unsigned int)DOM::Node::DOCUMENT_FRAGMENT_NODE);
01524 case NOTATION_NODE:
01525 return Number((unsigned int)DOM::Node::NOTATION_NODE);
01526 default:
01527 kdDebug(6070) << "WARNING: NodeConstructor::getValueProperty unhandled token " << token << endl;
01528 return Value();
01529 }
01530 #endif
01531 }
01532
01533 Object KJS::getNodeConstructor(ExecState *exec)
01534 {
01535 return Object(cacheGlobalObject<NodeConstructor>(exec, "[[node.constructor]]"));
01536 }
01537
01538
01539
01540 const ClassInfo DOMExceptionConstructor::info = { "DOMExceptionConstructor", 0, 0, 0 };
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562 DOMExceptionConstructor::DOMExceptionConstructor(ExecState* exec)
01563 : DOMObject(exec->interpreter()->builtinObjectPrototype())
01564 {
01565 }
01566
01567 Value DOMExceptionConstructor::tryGet(ExecState *exec, const Identifier &propertyName) const
01568 {
01569 return DOMObjectLookupGetValue<DOMExceptionConstructor, DOMObject>(exec, propertyName, &DOMExceptionConstructorTable, this);
01570 }
01571
01572 Value DOMExceptionConstructor::getValueProperty(ExecState *, int token) const
01573 {
01574
01575 return Number((unsigned int)token);
01576 #if 0
01577 switch (token) {
01578 case INDEX_SIZE_ERR:
01579 return Number((unsigned int)DOM::DOMException::INDEX_SIZE_ERR);
01580 case DOMSTRING_SIZE_ERR:
01581 return Number((unsigned int)DOM::DOMException::DOMSTRING_SIZE_ERR);
01582 case HIERARCHY_REQUEST_ERR:
01583 return Number((unsigned int)DOM::DOMException::HIERARCHY_REQUEST_ERR);
01584 case WRONG_DOCUMENT_ERR:
01585 return Number((unsigned int)DOM::DOMException::WRONG_DOCUMENT_ERR);
01586 case INVALID_CHARACTER_ERR:
01587 return Number((unsigned int)DOM::DOMException::INVALID_CHARACTER_ERR);
01588 case NO_DATA_ALLOWED_ERR:
01589 return Number((unsigned int)DOM::DOMException::NO_DATA_ALLOWED_ERR);
01590 case NO_MODIFICATION_ALLOWED_ERR:
01591 return Number((unsigned int)DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR);
01592 case NOT_FOUND_ERR:
01593 return Number((unsigned int)DOM::DOMException::NOT_FOUND_ERR);
01594 case NOT_SUPPORTED_ERR:
01595 return Number((unsigned int)DOM::DOMException::NOT_SUPPORTED_ERR);
01596 case INUSE_ATTRIBUTE_ERR:
01597 return Number((unsigned int)DOM::DOMException::INUSE_ATTRIBUTE_ERR);
01598 case INVALID_STATE_ERR:
01599 return Number((unsigned int)DOM::DOMException::INVALID_STATE_ERR);
01600 case SYNTAX_ERR:
01601 return Number((unsigned int)DOM::DOMException::SYNTAX_ERR);
01602 case INVALID_MODIFICATION_ERR:
01603 return Number((unsigned int)DOM::DOMException::INVALID_MODIFICATION_ERR);
01604 case NAMESPACE_ERR:
01605 return Number((unsigned int)DOM::DOMException::NAMESPACE_ERR);
01606 case INVALID_ACCESS_ERR:
01607 return Number((unsigned int)DOM::DOMException::INVALID_ACCESS_ERR);
01608 default:
01609 kdDebug(6070) << "WARNING: DOMExceptionConstructor::getValueProperty unhandled token " << token << endl;
01610 return Value();
01611 }
01612 #endif
01613 }
01614
01615 Object KJS::getDOMExceptionConstructor(ExecState *exec)
01616 {
01617 return cacheGlobalObject<DOMExceptionConstructor>(exec, "[[DOMException.constructor]]");
01618 }
01619
01620
01621
01622 const ClassInfo KJS::DOMNamedNodesCollection::info = { "DOMNamedNodesCollection", 0, 0, 0 };
01623
01624
01625
01626
01627 DOMNamedNodesCollection::DOMNamedNodesCollection(ExecState *exec, const QValueList<DOM::Node>& nodes )
01628 : DOMObject(exec->interpreter()->builtinObjectPrototype()),
01629 m_nodes(nodes)
01630 {
01631
01632 }
01633
01634 Value DOMNamedNodesCollection::tryGet(ExecState *exec, const Identifier &propertyName) const
01635 {
01636 kdDebug(6070) << k_funcinfo << propertyName.ascii() << endl;
01637 if (propertyName == lengthPropertyName)
01638 return Number(m_nodes.count());
01639
01640 bool ok;
01641 unsigned int u = propertyName.toULong(&ok);
01642 if (ok && u < m_nodes.count()) {
01643 DOM::Node node = m_nodes[u];
01644 return getDOMNode(exec,node);
01645 }
01646 return DOMObject::tryGet(exec,propertyName);
01647 }
01648
01649
01650
01651 const ClassInfo DOMCharacterData::info = { "CharacterImp",
01652 &DOMNode::info, &DOMCharacterDataTable, 0 };
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666 DEFINE_PROTOTYPE("DOMCharacterData",DOMCharacterDataProto)
01667 IMPLEMENT_PROTOFUNC_DOM(DOMCharacterDataProtoFunc)
01668 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMCharacterDataProto,DOMCharacterDataProtoFunc, DOMNodeProto)
01669
01670 DOMCharacterData::DOMCharacterData(ExecState *exec, const DOM::CharacterData& d)
01671 : DOMNode(DOMCharacterDataProto::self(exec), d) {}
01672
01673 DOMCharacterData::DOMCharacterData(const Object& proto, const DOM::CharacterData& d)
01674 : DOMNode(proto, d) {}
01675
01676 Value DOMCharacterData::tryGet(ExecState *exec, const Identifier &p) const
01677 {
01678 #ifdef KJS_VERBOSE
01679 kdDebug(6070)<<"DOMCharacterData::tryGet "<<p.string().string()<<endl;
01680 #endif
01681 return DOMObjectLookupGetValue<DOMCharacterData,DOMNode>(exec,p,&DOMCharacterDataTable,this);
01682 }
01683
01684 Value DOMCharacterData::getValueProperty(ExecState *, int token) const
01685 {
01686 DOM::CharacterData data = static_cast<DOM::CharacterData>(node);
01687 switch (token) {
01688 case Data:
01689 return String(data.data());
01690 case Length:
01691 return Number(data.length());
01692 default:
01693 kdDebug(6070) << "WARNING: Unhandled token in DOMCharacterData::getValueProperty : " << token << endl;
01694 return Value();
01695 }
01696 }
01697
01698 void DOMCharacterData::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
01699 {
01700 if (propertyName == "data")
01701 static_cast<DOM::CharacterData>(node).setData(value.toString(exec).string());
01702 else
01703 DOMNode::tryPut(exec, propertyName,value,attr);
01704 }
01705
01706 Value DOMCharacterDataProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01707 {
01708 KJS_CHECK_THIS( KJS::DOMCharacterData, thisObj );
01709 DOM::CharacterData data = static_cast<DOMCharacterData *>(thisObj.imp())->toData();
01710 switch(id) {
01711 case DOMCharacterData::SubstringData:
01712 return String(data.substringData(args[0].toInteger(exec),args[1].toInteger(exec)));
01713 case DOMCharacterData::AppendData:
01714 data.appendData(args[0].toString(exec).string());
01715 return Undefined();
01716 break;
01717 case DOMCharacterData::InsertData:
01718 data.insertData(args[0].toInteger(exec),args[1].toString(exec).string());
01719 return Undefined();
01720 break;
01721 case DOMCharacterData::DeleteData:
01722 data.deleteData(args[0].toInteger(exec),args[1].toInteger(exec));
01723 return Undefined();
01724 break;
01725 case DOMCharacterData::ReplaceData:
01726 data.replaceData(args[0].toInteger(exec),args[1].toInteger(exec),args[2].toString(exec).string());
01727 return Undefined();
01728 break;
01729 default:
01730 return Undefined();
01731 }
01732 }
01733
01734
01735
01736 const ClassInfo DOMText::info = { "Text",
01737 &DOMCharacterData::info, 0, 0 };
01738
01739
01740
01741
01742
01743 DEFINE_PROTOTYPE("DOMText",DOMTextProto)
01744 IMPLEMENT_PROTOFUNC_DOM(DOMTextProtoFunc)
01745 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMTextProto,DOMTextProtoFunc,DOMCharacterDataProto)
01746
01747 DOMText::DOMText(ExecState *exec, const DOM::Text& t)
01748 : DOMCharacterData(DOMTextProto::self(exec), t) { }
01749
01750 Value DOMText::tryGet(ExecState *exec, const Identifier &p) const
01751 {
01752 if (p.isEmpty())
01753 return Undefined();
01754 else
01755 return DOMCharacterData::tryGet(exec, p);
01756 }
01757
01758 Value DOMTextProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01759 {
01760 KJS_CHECK_THIS( KJS::DOMText, thisObj );
01761 DOM::Text text = static_cast<DOMText *>(thisObj.imp())->toText();
01762 switch(id) {
01763 case DOMText::SplitText:
01764 return getDOMNode(exec,text.splitText(args[0].toInteger(exec)));
01765 break;
01766 default:
01767 return Undefined();
01768 }
01769 }