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