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