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 if (docImpl->part())
00936 return String(docImpl->part()->encoding());
00937 else
00938 return Undefined();
00939 }
00940 case StyleSheets:
00941
00942 return getDOMStyleSheetList(exec, doc.styleSheets(), doc);
00943 case DOMDocument::DefaultView:
00944 {
00945 KHTMLView *view = node.handle()->getDocument()->view();
00946 if (view)
00947 return Window::retrieve(view->part());
00948 return getDOMAbstractView(exec, doc.defaultView());
00949 }
00950 case PreferredStylesheetSet:
00951 return String(doc.preferredStylesheetSet());
00952 case SelectedStylesheetSet:
00953 return String(doc.selectedStylesheetSet());
00954 case ReadyState:
00955 {
00956 DOM::DocumentImpl* docimpl = node.handle()->getDocument();
00957 if ( docimpl && docimpl->view() )
00958 {
00959 KHTMLPart* part = docimpl->view()->part();
00960 if ( part ) {
00961 if (part->d->m_bComplete) return String("complete");
00962 if (docimpl->parsing()) return String("loading");
00963 return String("loaded");
00964
00965
00966 }
00967 }
00968 return Undefined();
00969 }
00970 case Async:
00971 return Boolean(doc.async());
00972 default:
00973 kdDebug(6070) << "WARNING: DOMDocument::getValueProperty unhandled token " << token << endl;
00974 return Value();
00975 }
00976 }
00977
00978 void DOMDocument::tryPut(ExecState *exec, const Identifier& propertyName, const Value& value, int attr)
00979 {
00980 #ifdef KJS_VERBOSE
00981 kdDebug(6070) << "DOMDocument::tryPut " << propertyName.qstring() << endl;
00982 #endif
00983 DOMObjectLookupPut<DOMDocument,DOMNode>(exec, propertyName, value, attr, &DOMDocumentTable, this );
00984 }
00985
00986 void DOMDocument::putValueProperty(ExecState *exec, int token, const Value& value, int )
00987 {
00988 DOM::Document doc = static_cast<DOM::Document>(node);
00989 switch (token) {
00990 case SelectedStylesheetSet: {
00991 doc.setSelectedStylesheetSet(value.toString(exec).string());
00992 break;
00993 }
00994 case Async: {
00995 doc.setAsync(value.toBoolean(exec));
00996 break;
00997 }
00998 }
00999 }
01000
01001 Value DOMDocumentProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01002 {
01003 KJS_CHECK_THIS( KJS::DOMDocument, thisObj );
01004 DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
01005 DOM::Document doc = static_cast<DOM::Document>(node);
01006 String str = args[0].toString(exec);
01007 DOM::DOMString s = str.value().string();
01008
01009 switch(id) {
01010 case DOMDocument::CreateElement:
01011 return getDOMNode(exec,doc.createElement(s));
01012 case DOMDocument::CreateDocumentFragment:
01013 return getDOMNode(exec,doc.createDocumentFragment());
01014 case DOMDocument::CreateTextNode:
01015 return getDOMNode(exec,doc.createTextNode(s));
01016 case DOMDocument::CreateComment:
01017 return getDOMNode(exec,doc.createComment(s));
01018 case DOMDocument::CreateCDATASection:
01019 return getDOMNode(exec,doc.createCDATASection(s));
01020 case DOMDocument::CreateProcessingInstruction:
01021 return getDOMNode(exec,doc.createProcessingInstruction(args[0].toString(exec).string(),
01022 args[1].toString(exec).string()));
01023 case DOMDocument::CreateAttribute:
01024 return getDOMNode(exec,doc.createAttribute(s));
01025 case DOMDocument::CreateEntityReference:
01026 return getDOMNode(exec,doc.createEntityReference(args[0].toString(exec).string()));
01027 case DOMDocument::GetElementsByTagName:
01028 return getDOMNodeList(exec,doc.getElementsByTagName(s));
01029 case DOMDocument::ImportNode:
01030 return getDOMNode(exec,doc.importNode(toNode(args[0]), args[1].toBoolean(exec)));
01031 case DOMDocument::CreateElementNS:
01032 return getDOMNode(exec,doc.createElementNS(args[0].toString(exec).string(), args[1].toString(exec).string()));
01033 case DOMDocument::CreateAttributeNS:
01034 return getDOMNode(exec,doc.createAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01035 case DOMDocument::GetElementsByTagNameNS:
01036 return getDOMNodeList(exec,doc.getElementsByTagNameNS(args[0].toString(exec).string(),
01037 args[1].toString(exec).string()));
01038 case DOMDocument::GetElementById:
01039 #ifdef KJS_VERBOSE
01040 kdDebug(6070) << "DOMDocument::GetElementById looking for " << args[0].toString(exec).string() << endl;
01041 #endif
01042 return getDOMNode(exec,doc.getElementById(args[0].toString(exec).string()));
01043 case DOMDocument::CreateRange:
01044 return getDOMRange(exec,doc.createRange());
01045 case DOMDocument::CreateNodeIterator:
01046 if (args[2].isA(NullType)) {
01047 DOM::NodeFilter filter;
01048 return getDOMNodeIterator(exec,
01049 doc.createNodeIterator(toNode(args[0]),
01050 (long unsigned int)(args[1].toNumber(exec)),
01051 filter,args[3].toBoolean(exec)));
01052 }
01053 else {
01054 Object obj = Object::dynamicCast(args[2]);
01055 if (obj.isValid())
01056 {
01057 DOM::CustomNodeFilter *customFilter = new JSNodeFilter(obj);
01058 DOM::NodeFilter filter = DOM::NodeFilter::createCustom(customFilter);
01059 return getDOMNodeIterator(exec,
01060 doc.createNodeIterator(
01061 toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
01062 filter,args[3].toBoolean(exec)));
01063 }
01064 }
01065 case DOMDocument::CreateTreeWalker:
01066 return getDOMTreeWalker(exec,doc.createTreeWalker(toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
01067 toNodeFilter(args[2]),args[3].toBoolean(exec)));
01068 case DOMDocument::CreateEvent:
01069 return getDOMEvent(exec,doc.createEvent(s));
01070 case DOMDocument::GetOverrideStyle: {
01071 DOM::Node arg0 = toNode(args[0]);
01072 if (arg0.nodeType() != DOM::Node::ELEMENT_NODE)
01073 return Undefined();
01074 else
01075 return getDOMCSSStyleDeclaration(exec,doc.getOverrideStyle(static_cast<DOM::Element>(arg0),args[1].toString(exec).string()));
01076 }
01077 case DOMDocument::Abort:
01078 doc.abort();
01079 break;
01080 case DOMDocument::Load: {
01081 Window* active = Window::retrieveActive(exec);
01082
01083
01084 KHTMLPart *khtmlpart = ::qt_cast<KHTMLPart *>(active->part());
01085 if (khtmlpart) {
01086
01087 QString dstUrl = khtmlpart->htmlDocument().completeURL(s).string();
01088 KParts::ReadOnlyPart *part = static_cast<KJS::ScriptInterpreter*>(exec->interpreter())->part();
01089 if (part->url().host() == KURL(dstUrl).host()) {
01090 kdDebug(6070) << "JavaScript: access granted for document.load() of " << dstUrl << endl;
01091 doc.load(dstUrl);
01092 }
01093 else {
01094 kdDebug(6070) << "JavaScript: access denied for document.load() of " << dstUrl << endl;
01095 }
01096 }
01097 break;
01098 }
01099 case DOMDocument::LoadXML:
01100 doc.loadXML(s);
01101 break;
01102 default:
01103 break;
01104 }
01105
01106 return Undefined();
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 DEFINE_PROTOTYPE("DOMElement",DOMElementProto)
01131 IMPLEMENT_PROTOFUNC_DOM(DOMElementProtoFunc)
01132 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMElementProto,DOMElementProtoFunc,DOMNodeProto)
01133
01134 IMPLEMENT_PSEUDO_CONSTRUCTOR(ElementPseudoCtor, "Element", DOMElementProto)
01135
01136 const ClassInfo DOMElement::info = { "Element", &DOMNode::info, &DOMElementTable, 0 };
01137
01138
01139
01140
01141
01142
01143 DOMElement::DOMElement(ExecState *exec, const DOM::Element& e)
01144 : DOMNode(DOMElementProto::self(exec), e) { }
01145
01146 DOMElement::DOMElement(const Object& proto, const DOM::Element& e)
01147 : DOMNode(proto, e) { }
01148
01149 Value DOMElement::tryGet(ExecState *exec, const Identifier &propertyName) const
01150 {
01151 #ifdef KJS_VERBOSE
01152 kdDebug(6070) << "DOMElement::tryGet " << propertyName.qstring() << endl;
01153 #endif
01154 DOM::Element element = static_cast<DOM::Element>(node);
01155
01156 const HashEntry* entry = Lookup::findEntry(&DOMElementTable, propertyName);
01157 if (entry)
01158 {
01159 switch( entry->value ) {
01160 case TagName:
01161 return String(element.tagName());
01162 case Style:
01163 return getDOMCSSStyleDeclaration(exec,element.style());
01164 default:
01165 kdDebug(6070) << "WARNING: Unhandled token in DOMElement::tryGet : " << entry->value << endl;
01166 break;
01167 }
01168 }
01169
01170
01171
01172 if (DOMNode::hasProperty(exec, propertyName))
01173 return DOMNode::tryGet(exec, propertyName);
01174
01175 DOM::DOMString attr = element.getAttribute( propertyName.string() );
01176
01177 if ( !attr.isNull() )
01178 return String( attr );
01179
01180 return Undefined();
01181 }
01182
01183 Value DOMElementProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01184 {
01185 KJS_CHECK_THIS( KJS::DOMNode, thisObj );
01186 DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
01187 DOM::Element element = static_cast<DOM::Element>(node);
01188
01189 switch(id) {
01190 case DOMElement::GetAttribute:
01194 return getString(element.getAttribute(args[0].toString(exec).string()));
01195 case DOMElement::SetAttribute:
01196 element.setAttribute(args[0].toString(exec).string(),args[1].toString(exec).string());
01197 return Undefined();
01198 case DOMElement::RemoveAttribute:
01199 element.removeAttribute(args[0].toString(exec).string());
01200 return Undefined();
01201 case DOMElement::GetAttributeNode:
01202 return getDOMNode(exec,element.getAttributeNode(args[0].toString(exec).string()));
01203 case DOMElement::SetAttributeNode:
01204 return getDOMNode(exec,element.setAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
01205 case DOMElement::RemoveAttributeNode:
01206 return getDOMNode(exec,element.removeAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
01207 case DOMElement::GetElementsByTagName:
01208 return getDOMNodeList(exec,element.getElementsByTagName(args[0].toString(exec).string()));
01209 case DOMElement::HasAttribute:
01210 return Boolean(element.hasAttribute(args[0].toString(exec).string()));
01211 case DOMElement::GetAttributeNS:
01212 return String(element.getAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01213 case DOMElement::SetAttributeNS:
01214 element.setAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string());
01215 return Undefined();
01216 case DOMElement::RemoveAttributeNS:
01217 element.removeAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string());
01218 return Undefined();
01219 case DOMElement::GetAttributeNodeNS:
01220 return getDOMNode(exec,element.getAttributeNodeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01221 case DOMElement::SetAttributeNodeNS:
01222 return getDOMNode(exec,element.setAttributeNodeNS((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
01223 case DOMElement::GetElementsByTagNameNS:
01224 return getDOMNodeList(exec,element.getElementsByTagNameNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01225 case DOMElement::HasAttributeNS:
01226 return Boolean(element.hasAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01227 default:
01228 return Undefined();
01229 }
01230 }
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244 DEFINE_PROTOTYPE("DOMImplementation",DOMDOMImplementationProto)
01245 IMPLEMENT_PROTOFUNC_DOM(DOMDOMImplementationProtoFunc)
01246 IMPLEMENT_PROTOTYPE(DOMDOMImplementationProto,DOMDOMImplementationProtoFunc)
01247
01248 const ClassInfo DOMDOMImplementation::info = { "DOMImplementation", 0, 0, 0 };
01249
01250 DOMDOMImplementation::DOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
01251 : DOMObject(DOMDOMImplementationProto::self(exec)), implementation(i) { }
01252
01253 DOMDOMImplementation::~DOMDOMImplementation()
01254 {
01255 ScriptInterpreter::forgetDOMObject(implementation.handle());
01256 }
01257
01258 Value DOMDOMImplementationProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01259 {
01260 KJS_CHECK_THIS( KJS::DOMDOMImplementation, thisObj );
01261 DOM::DOMImplementation implementation = static_cast<DOMDOMImplementation *>( thisObj.imp() )->toImplementation();
01262
01263 switch(id) {
01264 case DOMDOMImplementation::HasFeature:
01265 return Boolean(implementation.hasFeature(args[0].toString(exec).string(),args[1].toString(exec).string()));
01266 case DOMDOMImplementation::CreateDocumentType:
01267 return getDOMNode(exec,implementation.createDocumentType(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string()));
01268 case DOMDOMImplementation::CreateDocument: {
01269
01270
01271 KHTMLPart *part = ::qt_cast<KHTMLPart*>(static_cast<KJS::ScriptInterpreter*>(exec->interpreter())->part());
01272 if (part) {
01273 Document doc = implementation.createDocument(args[0].toString(exec).string(),args[1].toString(exec).string(),toNode(args[2]));
01274 KURL url = static_cast<DocumentImpl*>(part->document().handle())->URL();
01275 static_cast<DocumentImpl*>(doc.handle())->setURL(url.url());
01276 return getDOMNode(exec,doc);
01277 }
01278 break;
01279 }
01280 case DOMDOMImplementation::CreateCSSStyleSheet:
01281 return getDOMStyleSheet(exec,implementation.createCSSStyleSheet(args[0].toString(exec).string(),args[1].toString(exec).string()));
01282 case DOMDOMImplementation::CreateHTMLDocument:
01283 return getDOMNode(exec, implementation.createHTMLDocument(args[0].toString(exec).string()));
01284 default:
01285 break;
01286 }
01287 return Undefined();
01288 }
01289
01290
01291
01292 const ClassInfo DOMDocumentType::info = { "DocumentType", &DOMNode::info, &DOMDocumentTypeTable, 0 };
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305 DOMDocumentType::DOMDocumentType(ExecState *exec, const DOM::DocumentType& dt)
01306 : DOMNode( exec, dt ) { }
01307
01308 Value DOMDocumentType::tryGet(ExecState *exec, const Identifier &propertyName) const
01309 {
01310 #ifdef KJS_VERBOSE
01311 kdDebug(6070) << "DOMDocumentType::tryGet " << propertyName.qstring() << endl;
01312 #endif
01313 return DOMObjectLookupGetValue<DOMDocumentType, DOMNode>(exec, propertyName, &DOMDocumentTypeTable, this);
01314 }
01315
01316 Value DOMDocumentType::getValueProperty(ExecState *exec, int token) const
01317 {
01318 DOM::DocumentType type = static_cast<DOM::DocumentType>(node);
01319 switch (token) {
01320 case Name:
01321 return String(type.name());
01322 case Entities:
01323 return getDOMNamedNodeMap(exec,type.entities());
01324 case Notations:
01325 return getDOMNamedNodeMap(exec,type.notations());
01326 case PublicId:
01327 return String(type.publicId());
01328 case SystemId:
01329 return String(type.systemId());
01330 case InternalSubset:
01331 return getString(type.internalSubset());
01332 default:
01333 kdDebug(6070) << "WARNING: DOMDocumentType::getValueProperty unhandled token " << token << endl;
01334 return Value();
01335 }
01336 }
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355 DEFINE_PROTOTYPE("NamedNodeMap", DOMNamedNodeMapProto)
01356 IMPLEMENT_PROTOFUNC_DOM(DOMNamedNodeMapProtoFunc)
01357 IMPLEMENT_PROTOTYPE(DOMNamedNodeMapProto,DOMNamedNodeMapProtoFunc)
01358
01359 const ClassInfo DOMNamedNodeMap::info = { "NamedNodeMap", 0, &DOMNamedNodeMapTable, 0 };
01360
01361 DOMNamedNodeMap::DOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
01362 : DOMObject(DOMNamedNodeMapProto::self(exec)), map(m) { }
01363
01364 DOMNamedNodeMap::~DOMNamedNodeMap()
01365 {
01366 ScriptInterpreter::forgetDOMObject(map.handle());
01367 }
01368
01369 bool DOMNamedNodeMap::hasProperty(ExecState *exec, const Identifier &p) const
01370 {
01371
01372 return DOMObject::hasProperty(exec, p);
01373 }
01374
01375 Value DOMNamedNodeMap::tryGet(ExecState* exec, const Identifier &p) const
01376 {
01377 if (p == lengthPropertyName)
01378 return Number(map.length());
01379
01380
01381 bool ok;
01382 long unsigned int idx = p.toULong(&ok);
01383 if (ok)
01384 return getDOMNode(exec,map.item(idx));
01385
01386
01387 return DOMObject::tryGet(exec, p);
01388 }
01389
01390 Value DOMNamedNodeMapProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01391 {
01392 KJS_CHECK_THIS( KJS::DOMNamedNodeMap, thisObj );
01393 DOM::NamedNodeMap map = static_cast<DOMNamedNodeMap *>(thisObj.imp())->toMap();
01394
01395 switch(id) {
01396 case DOMNamedNodeMap::GetNamedItem:
01397 return getDOMNode(exec, map.getNamedItem(args[0].toString(exec).string()));
01398 case DOMNamedNodeMap::SetNamedItem:
01399 return getDOMNode(exec, map.setNamedItem((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
01400 case DOMNamedNodeMap::RemoveNamedItem:
01401 return getDOMNode(exec, map.removeNamedItem(args[0].toString(exec).string()));
01402 case DOMNamedNodeMap::Item:
01403 return getDOMNode(exec, map.item(args[0].toInt32(exec)));
01404 case DOMNamedNodeMap::GetNamedItemNS:
01405 return getDOMNode(exec, map.getNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01406 case DOMNamedNodeMap::SetNamedItemNS:
01407 return getDOMNode(exec, map.setNamedItemNS(toNode(args[0])));
01408 case DOMNamedNodeMap::RemoveNamedItemNS:
01409 return getDOMNode(exec, map.removeNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01410 default:
01411 break;
01412 }
01413
01414 return Undefined();
01415 }
01416
01417
01418
01419 const ClassInfo DOMProcessingInstruction::info = { "ProcessingInstruction", &DOMNode::info, &DOMProcessingInstructionTable, 0 };
01420
01421
01422
01423
01424
01425
01426
01427
01428 Value DOMProcessingInstruction::tryGet(ExecState *exec, const Identifier &propertyName) const
01429 {
01430 return DOMObjectLookupGetValue<DOMProcessingInstruction, DOMNode>(exec, propertyName, &DOMProcessingInstructionTable, this);
01431 }
01432
01433 Value DOMProcessingInstruction::getValueProperty(ExecState *exec, int token) const
01434 {
01435 switch (token) {
01436 case Target:
01437 return String(static_cast<DOM::ProcessingInstruction>(node).target());
01438 case Data:
01439 return String(static_cast<DOM::ProcessingInstruction>(node).data());
01440 case Sheet:
01441 return getDOMStyleSheet(exec,static_cast<DOM::ProcessingInstruction>(node).sheet());
01442 default:
01443 kdDebug(6070) << "WARNING: DOMProcessingInstruction::getValueProperty unhandled token " << token << endl;
01444 return Value();
01445 }
01446 }
01447
01448 void DOMProcessingInstruction::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
01449 {
01450
01451 if (propertyName == "data")
01452 static_cast<DOM::ProcessingInstruction>(node).setData(value.toString(exec).string());
01453 else
01454 DOMNode::tryPut(exec, propertyName,value,attr);
01455 }
01456
01457
01458
01459 const ClassInfo DOMNotation::info = { "Notation", &DOMNode::info, &DOMNotationTable, 0 };
01460
01461
01462
01463
01464
01465
01466
01467 Value DOMNotation::tryGet(ExecState *exec, const Identifier &propertyName) const
01468 {
01469 return DOMObjectLookupGetValue<DOMNotation, DOMNode>(exec, propertyName, &DOMNotationTable, this);
01470 }
01471
01472 Value DOMNotation::getValueProperty(ExecState *, int token) const
01473 {
01474 switch (token) {
01475 case PublicId:
01476 return String(static_cast<DOM::Notation>(node).publicId());
01477 case SystemId:
01478 return String(static_cast<DOM::Notation>(node).systemId());
01479 default:
01480 kdDebug(6070) << "WARNING: DOMNotation::getValueProperty unhandled token " << token << endl;
01481 return Value();
01482 }
01483 }
01484
01485
01486
01487 const ClassInfo DOMEntity::info = { "Entity", &DOMNode::info, 0, 0 };
01488
01489
01490
01491
01492
01493
01494
01495
01496 Value DOMEntity::tryGet(ExecState *exec, const Identifier &propertyName) const
01497 {
01498 return DOMObjectLookupGetValue<DOMEntity, DOMNode>(exec, propertyName, &DOMEntityTable, this);
01499 }
01500
01501 Value DOMEntity::getValueProperty(ExecState *, int token) const
01502 {
01503 switch (token) {
01504 case PublicId:
01505 return String(static_cast<DOM::Entity>(node).publicId());
01506 case SystemId:
01507 return String(static_cast<DOM::Entity>(node).systemId());
01508 case NotationName:
01509 return String(static_cast<DOM::Entity>(node).notationName());
01510 default:
01511 kdDebug(6070) << "WARNING: DOMEntity::getValueProperty unhandled token " << token << endl;
01512 return Value();
01513 }
01514 }
01515
01516
01517
01518 bool KJS::checkNodeSecurity(ExecState *exec, const DOM::Node& n)
01519 {
01520
01521 if (n.isNull())
01522 return true;
01523 KHTMLView *view = n.handle()->getDocument()->view();
01524 Window* win = view && view->part() ? Window::retrieveWindow(view->part()) : 0L;
01525 if ( !win || !win->isSafeScript(exec) )
01526 return false;
01527 return true;
01528 }
01529
01530 Value KJS::getDOMNode(ExecState *exec, const DOM::Node& n)
01531 {
01532 DOMObject *ret = 0;
01533 if (n.isNull())
01534 return Null();
01535 ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
01536 if ((ret = interp->getDOMObject(n.handle())))
01537 return Value(ret);
01538
01539 switch (n.nodeType()) {
01540 case DOM::Node::ELEMENT_NODE:
01541 if (static_cast<DOM::Element>(n).isHTMLElement())
01542 ret = new HTMLElement(exec, static_cast<DOM::HTMLElement>(n));
01543 else
01544 ret = new DOMElement(exec, static_cast<DOM::Element>(n));
01545 break;
01546 case DOM::Node::ATTRIBUTE_NODE:
01547 ret = new DOMAttr(exec, static_cast<DOM::Attr>(n));
01548 break;
01549 case DOM::Node::TEXT_NODE:
01550 case DOM::Node::CDATA_SECTION_NODE:
01551 ret = new DOMText(exec, static_cast<DOM::Text>(n));
01552 break;
01553 case DOM::Node::ENTITY_REFERENCE_NODE:
01554 ret = new DOMNode(exec, n);
01555 break;
01556 case DOM::Node::ENTITY_NODE:
01557 ret = new DOMEntity(exec, static_cast<DOM::Entity>(n));
01558 break;
01559 case DOM::Node::PROCESSING_INSTRUCTION_NODE:
01560 ret = new DOMProcessingInstruction(exec, static_cast<DOM::ProcessingInstruction>(n));
01561 break;
01562 case DOM::Node::COMMENT_NODE:
01563 ret = new DOMCharacterData(exec, static_cast<DOM::CharacterData>(n));
01564 break;
01565 case DOM::Node::DOCUMENT_NODE:
01566 if (static_cast<DOM::Document>(n).isHTMLDocument())
01567 ret = new HTMLDocument(exec, static_cast<DOM::HTMLDocument>(n));
01568 else
01569 ret = new DOMDocument(exec, static_cast<DOM::Document>(n));
01570 break;
01571 case DOM::Node::DOCUMENT_TYPE_NODE:
01572 ret = new DOMDocumentType(exec, static_cast<DOM::DocumentType>(n));
01573 break;
01574 case DOM::Node::DOCUMENT_FRAGMENT_NODE:
01575 ret = new DOMNode(exec, n);
01576 break;
01577 case DOM::Node::NOTATION_NODE:
01578 ret = new DOMNotation(exec, static_cast<DOM::Notation>(n));
01579 break;
01580 default:
01581 ret = new DOMNode(exec, n);
01582 }
01583 interp->putDOMObject(n.handle(),ret);
01584
01585 return Value(ret);
01586 }
01587
01588 Value KJS::getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
01589 {
01590 return Value(cacheDOMObject<DOM::NamedNodeMap, KJS::DOMNamedNodeMap>(exec, m));
01591 }
01592
01593 Value KJS::getDOMNodeList(ExecState *exec, const DOM::NodeList& l)
01594 {
01595 return Value(cacheDOMObject<DOM::NodeList, KJS::DOMNodeList>(exec, l));
01596 }
01597
01598 Value KJS::getDOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
01599 {
01600 return Value(cacheDOMObject<DOM::DOMImplementation, KJS::DOMDOMImplementation>(exec, i));
01601 }
01602
01603
01604 IMPLEMENT_PSEUDO_CONSTRUCTOR_WITH_PARENT(NodeConstructor, "NodeConstructor", DOMNodeProto, DOMNodeConstants)
01605
01606
01607 const ClassInfo DOMExceptionConstructor::info = { "DOMExceptionConstructor", 0, 0, 0 };
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629 DOMExceptionConstructor::DOMExceptionConstructor(ExecState* exec)
01630 : DOMObject(exec->interpreter()->builtinObjectPrototype())
01631 {
01632 }
01633
01634 Value DOMExceptionConstructor::tryGet(ExecState *exec, const Identifier &propertyName) const
01635 {
01636 return DOMObjectLookupGetValue<DOMExceptionConstructor, DOMObject>(exec, propertyName, &DOMExceptionConstructorTable, this);
01637 }
01638
01639 Value DOMExceptionConstructor::getValueProperty(ExecState *, int token) const
01640 {
01641
01642 return Number((unsigned int)token);
01643 #if 0
01644 switch (token) {
01645 case INDEX_SIZE_ERR:
01646 return Number((unsigned int)DOM::DOMException::INDEX_SIZE_ERR);
01647 case DOMSTRING_SIZE_ERR:
01648 return Number((unsigned int)DOM::DOMException::DOMSTRING_SIZE_ERR);
01649 case HIERARCHY_REQUEST_ERR:
01650 return Number((unsigned int)DOM::DOMException::HIERARCHY_REQUEST_ERR);
01651 case WRONG_DOCUMENT_ERR:
01652 return Number((unsigned int)DOM::DOMException::WRONG_DOCUMENT_ERR);
01653 case INVALID_CHARACTER_ERR:
01654 return Number((unsigned int)DOM::DOMException::INVALID_CHARACTER_ERR);
01655 case NO_DATA_ALLOWED_ERR:
01656 return Number((unsigned int)DOM::DOMException::NO_DATA_ALLOWED_ERR);
01657 case NO_MODIFICATION_ALLOWED_ERR:
01658 return Number((unsigned int)DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR);
01659 case NOT_FOUND_ERR:
01660 return Number((unsigned int)DOM::DOMException::NOT_FOUND_ERR);
01661 case NOT_SUPPORTED_ERR:
01662 return Number((unsigned int)DOM::DOMException::NOT_SUPPORTED_ERR);
01663 case INUSE_ATTRIBUTE_ERR:
01664 return Number((unsigned int)DOM::DOMException::INUSE_ATTRIBUTE_ERR);
01665 case INVALID_STATE_ERR:
01666 return Number((unsigned int)DOM::DOMException::INVALID_STATE_ERR);
01667 case SYNTAX_ERR:
01668 return Number((unsigned int)DOM::DOMException::SYNTAX_ERR);
01669 case INVALID_MODIFICATION_ERR:
01670 return Number((unsigned int)DOM::DOMException::INVALID_MODIFICATION_ERR);
01671 case NAMESPACE_ERR:
01672 return Number((unsigned int)DOM::DOMException::NAMESPACE_ERR);
01673 case INVALID_ACCESS_ERR:
01674 return Number((unsigned int)DOM::DOMException::INVALID_ACCESS_ERR);
01675 default:
01676 kdDebug(6070) << "WARNING: DOMExceptionConstructor::getValueProperty unhandled token " << token << endl;
01677 return Value();
01678 }
01679 #endif
01680 }
01681
01682 Object KJS::getDOMExceptionConstructor(ExecState *exec)
01683 {
01684 return cacheGlobalObject<DOMExceptionConstructor>(exec, "[[DOMException.constructor]]");
01685 }
01686
01687
01688
01689
01690
01691
01692
01693
01694 const ClassInfo KJS::DOMNamedNodesCollection::info = { "DOMNamedNodesCollection", 0, &DOMNamedNodesCollectionTable, 0 };
01695
01696
01697
01698
01699 DOMNamedNodesCollection::DOMNamedNodesCollection(ExecState *exec, const QValueList<DOM::Node>& nodes )
01700 : DOMObject(exec->interpreter()->builtinObjectPrototype()),
01701 m_nodes(nodes)
01702 {
01703
01704 }
01705
01706 Value DOMNamedNodesCollection::tryGet(ExecState *exec, const Identifier &propertyName) const
01707 {
01708 kdDebug(6070) << k_funcinfo << propertyName.ascii() << endl;
01709 if (propertyName == lengthPropertyName)
01710 return Number(m_nodes.count());
01711
01712 bool ok;
01713 unsigned int u = propertyName.toULong(&ok);
01714 if (ok && u < m_nodes.count()) {
01715 DOM::Node node = m_nodes[u];
01716 return getDOMNode(exec,node);
01717 }
01718 return DOMObject::tryGet(exec,propertyName);
01719 }
01720
01721
01722
01723 const ClassInfo DOMCharacterData::info = { "CharacterImp",
01724 &DOMNode::info, &DOMCharacterDataTable, 0 };
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738 DEFINE_PROTOTYPE("DOMCharacterData",DOMCharacterDataProto)
01739 IMPLEMENT_PROTOFUNC_DOM(DOMCharacterDataProtoFunc)
01740 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMCharacterDataProto,DOMCharacterDataProtoFunc, DOMNodeProto)
01741
01742 DOMCharacterData::DOMCharacterData(ExecState *exec, const DOM::CharacterData& d)
01743 : DOMNode(DOMCharacterDataProto::self(exec), d) {}
01744
01745 DOMCharacterData::DOMCharacterData(const Object& proto, const DOM::CharacterData& d)
01746 : DOMNode(proto, d) {}
01747
01748 Value DOMCharacterData::tryGet(ExecState *exec, const Identifier &p) const
01749 {
01750 #ifdef KJS_VERBOSE
01751 kdDebug(6070)<<"DOMCharacterData::tryGet "<<p.string().string()<<endl;
01752 #endif
01753 return DOMObjectLookupGetValue<DOMCharacterData,DOMNode>(exec,p,&DOMCharacterDataTable,this);
01754 }
01755
01756 Value DOMCharacterData::getValueProperty(ExecState *, int token) const
01757 {
01758 DOM::CharacterData data = static_cast<DOM::CharacterData>(node);
01759 switch (token) {
01760 case Data:
01761 return String(data.data());
01762 case Length:
01763 return Number(data.length());
01764 default:
01765 kdDebug(6070) << "WARNING: Unhandled token in DOMCharacterData::getValueProperty : " << token << endl;
01766 return Value();
01767 }
01768 }
01769
01770 void DOMCharacterData::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
01771 {
01772 if (propertyName == "data")
01773 static_cast<DOM::CharacterData>(node).setData(value.toString(exec).string());
01774 else
01775 DOMNode::tryPut(exec, propertyName,value,attr);
01776 }
01777
01778 Value DOMCharacterDataProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01779 {
01780 KJS_CHECK_THIS( KJS::DOMCharacterData, thisObj );
01781 DOM::CharacterData data = static_cast<DOMCharacterData *>(thisObj.imp())->toData();
01782 switch(id) {
01783 case DOMCharacterData::SubstringData:
01784 return String(data.substringData(args[0].toInteger(exec),args[1].toInteger(exec)));
01785 case DOMCharacterData::AppendData:
01786 data.appendData(args[0].toString(exec).string());
01787 return Undefined();
01788 break;
01789 case DOMCharacterData::InsertData:
01790 data.insertData(args[0].toInteger(exec),args[1].toString(exec).string());
01791 return Undefined();
01792 break;
01793 case DOMCharacterData::DeleteData:
01794 data.deleteData(args[0].toInteger(exec),args[1].toInteger(exec));
01795 return Undefined();
01796 break;
01797 case DOMCharacterData::ReplaceData:
01798 data.replaceData(args[0].toInteger(exec),args[1].toInteger(exec),args[2].toString(exec).string());
01799 return Undefined();
01800 default:
01801 break;
01802 }
01803 return Undefined();
01804 }
01805
01806
01807
01808 const ClassInfo DOMText::info = { "Text",
01809 &DOMCharacterData::info, 0, 0 };
01810
01811
01812
01813
01814
01815 DEFINE_PROTOTYPE("DOMText",DOMTextProto)
01816 IMPLEMENT_PROTOFUNC_DOM(DOMTextProtoFunc)
01817 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMTextProto,DOMTextProtoFunc,DOMCharacterDataProto)
01818
01819 DOMText::DOMText(ExecState *exec, const DOM::Text& t)
01820 : DOMCharacterData(DOMTextProto::self(exec), t) { }
01821
01822 Value DOMText::tryGet(ExecState *exec, const Identifier &p) const
01823 {
01824 if (p.isEmpty())
01825 return Undefined();
01826 else
01827 return DOMCharacterData::tryGet(exec, p);
01828 }
01829
01830 Value DOMTextProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01831 {
01832 KJS_CHECK_THIS( KJS::DOMText, thisObj );
01833 DOM::Text text = static_cast<DOMText *>(thisObj.imp())->toText();
01834 switch(id) {
01835 case DOMText::SplitText:
01836 return getDOMNode(exec,text.splitText(args[0].toInteger(exec)));
01837 default:
01838 break;
01839 }
01840 return Undefined();
01841 }