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