khtml Library API Documentation

kjs_dom.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /*
00003  *  This file is part of the KDE libraries
00004  *  Copyright (C) 2000 Harri Porten (porten@kde.org)
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Library General Public
00008  *  License as published by the Free Software Foundation; either
00009  *  version 2 of the License, or (at your option) any later version.
00010  *
00011  *  This library is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  Library General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU Library General Public
00017  *  License along with this library; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 #include <khtmlview.h>
00022 #include "xml/dom2_eventsimpl.h"
00023 #include "rendering/render_root.h"
00024 #include "xml/dom_nodeimpl.h"
00025 #include "xml/dom_docimpl.h"
00026 #include "misc/htmltags.h" // ID_*
00027 #include "html/html_baseimpl.h"
00028 #include <kdebug.h>
00029 #include <khtml_part.h>
00030 
00031 #include "kjs_dom.h"
00032 #include "kjs_html.h"
00033 #include "kjs_css.h"
00034 #include "kjs_range.h"
00035 #include "kjs_traversal.h"
00036 #include "kjs_events.h"
00037 #include "kjs_views.h"
00038 #include "kjs_window.h"
00039 #include "dom/dom_exception.h"
00040 #include "kjs_dom.lut.h"
00041 #include "khtmlpart_p.h"
00042 
00043 using namespace KJS;
00044 
00045 // -------------------------------------------------------------------------
00046 /* Source for DOMNodeProtoTable. Use "make hashtables" to regenerate.
00047 @begin DOMNodeProtoTable 13
00048   insertBefore  DOMNode::InsertBefore   DontDelete|Function 2
00049   replaceChild  DOMNode::ReplaceChild   DontDelete|Function 2
00050   removeChild   DOMNode::RemoveChild    DontDelete|Function 1
00051   appendChild   DOMNode::AppendChild    DontDelete|Function 1
00052   hasAttributes DOMNode::HasAttributes  DontDelete|Function 0
00053   hasChildNodes DOMNode::HasChildNodes  DontDelete|Function 0
00054   cloneNode DOMNode::CloneNode  DontDelete|Function 1
00055 # DOM2
00056   normalize DOMNode::Normalize  DontDelete|Function 0
00057   isSupported   DOMNode::IsSupported    DontDelete|Function 2
00058 # from the EventTarget interface
00059   addEventListener  DOMNode::AddEventListener   DontDelete|Function 3
00060   removeEventListener   DOMNode::RemoveEventListener    DontDelete|Function 3
00061   dispatchEvent     DOMNode::DispatchEvent  DontDelete|Function 1
00062 # IE extensions
00063   contains  DOMNode::Contains       DontDelete|Function 1
00064 @end
00065 */
00066 DEFINE_PROTOTYPE("DOMNode",DOMNodeProto)
00067 IMPLEMENT_PROTOFUNC_DOM(DOMNodeProtoFunc)
00068 IMPLEMENT_PROTOTYPE(DOMNodeProto,DOMNodeProtoFunc)
00069 
00070 const ClassInfo DOMNode::info = { "Node", 0, &DOMNodeTable, 0 };
00071 
00072 DOMNode::DOMNode(ExecState *exec, const DOM::Node& n)
00073   : DOMObject(DOMNodeProto::self(exec)), node(n)
00074 {
00075 }
00076 
00077 DOMNode::DOMNode(const Object& proto, const DOM::Node& n)
00078   : DOMObject(proto), node(n)
00079 {
00080 }
00081 
00082 DOMNode::~DOMNode()
00083 {
00084   ScriptInterpreter::forgetDOMObject(node.handle());
00085 }
00086 
00087 bool DOMNode::toBoolean(ExecState *) const
00088 {
00089     return !node.isNull();
00090 }
00091 
00092 /* Source for DOMNodeTable. Use "make hashtables" to regenerate.
00093 @begin DOMNodeTable 53
00094   nodeName  DOMNode::NodeName   DontDelete|ReadOnly
00095   nodeValue DOMNode::NodeValue  DontDelete
00096   nodeType  DOMNode::NodeType   DontDelete|ReadOnly
00097   parentNode    DOMNode::ParentNode DontDelete|ReadOnly
00098   parentElement DOMNode::ParentElement  DontDelete|ReadOnly
00099   childNodes    DOMNode::ChildNodes DontDelete|ReadOnly
00100   firstChild    DOMNode::FirstChild DontDelete|ReadOnly
00101   lastChild DOMNode::LastChild  DontDelete|ReadOnly
00102   previousSibling  DOMNode::PreviousSibling DontDelete|ReadOnly
00103   nextSibling   DOMNode::NextSibling    DontDelete|ReadOnly
00104   attributes    DOMNode::Attributes DontDelete|ReadOnly
00105   namespaceURI  DOMNode::NamespaceURI   DontDelete|ReadOnly
00106 # DOM2
00107   prefix    DOMNode::Prefix     DontDelete
00108   localName DOMNode::LocalName  DontDelete|ReadOnly
00109   ownerDocument DOMNode::OwnerDocument  DontDelete|ReadOnly
00110 # Event handlers
00111 # IE also has: onactivate, onbefore*, oncontextmenu, oncontrolselect, oncut,
00112 # ondeactivate, ondrag*, ondrop, onfocusin, onfocusout, onhelp, onmousewheel,
00113 # onmove*, onpaste, onpropertychange, onreadystatechange, onresizeend/start,
00114 # onselectionchange, onstop
00115   onabort   DOMNode::OnAbort        DontDelete
00116   onblur    DOMNode::OnBlur         DontDelete
00117   onchange  DOMNode::OnChange       DontDelete
00118   onclick   DOMNode::OnClick        DontDelete
00119   ondblclick    DOMNode::OnDblClick     DontDelete
00120   ondragdrop    DOMNode::OnDragDrop     DontDelete
00121   onerror   DOMNode::OnError        DontDelete
00122   onfocus   DOMNode::OnFocus            DontDelete
00123   onkeydown DOMNode::OnKeyDown      DontDelete
00124   onkeypress    DOMNode::OnKeyPress     DontDelete
00125   onkeyup   DOMNode::OnKeyUp        DontDelete
00126   onload    DOMNode::OnLoad         DontDelete
00127   onmousedown   DOMNode::OnMouseDown        DontDelete
00128   onmousemove   DOMNode::OnMouseMove        DontDelete
00129   onmouseout    DOMNode::OnMouseOut     DontDelete
00130   onmouseover   DOMNode::OnMouseOver        DontDelete
00131   onmouseup DOMNode::OnMouseUp      DontDelete
00132   onmove    DOMNode::OnMove         DontDelete
00133   onreset   DOMNode::OnReset        DontDelete
00134   onresize  DOMNode::OnResize       DontDelete
00135   onselect  DOMNode::OnSelect       DontDelete
00136   onsubmit  DOMNode::OnSubmit       DontDelete
00137   onunload  DOMNode::OnUnload       DontDelete
00138 # IE extensions
00139   offsetLeft    DOMNode::OffsetLeft     DontDelete|ReadOnly
00140   offsetTop DOMNode::OffsetTop      DontDelete|ReadOnly
00141   offsetWidth   DOMNode::OffsetWidth        DontDelete|ReadOnly
00142   offsetHeight  DOMNode::OffsetHeight       DontDelete|ReadOnly
00143   offsetParent  DOMNode::OffsetParent       DontDelete|ReadOnly
00144   clientWidth   DOMNode::ClientWidth        DontDelete|ReadOnly
00145   clientHeight  DOMNode::ClientHeight       DontDelete|ReadOnly
00146   scrollLeft    DOMNode::ScrollLeft     DontDelete|ReadOnly
00147   scrollTop DOMNode::ScrollTop      DontDelete|ReadOnly
00148   sourceIndex   DOMNode::SourceIndex        DontDelete|ReadOnly
00149 @end
00150 */
00151 Value DOMNode::tryGet(ExecState *exec, const UString &propertyName) const
00152 {
00153 #ifdef KJS_VERBOSE
00154   kdDebug(6070) << "DOMNode::tryGet " << propertyName.qstring() << endl;
00155 #endif
00156   return DOMObjectLookupGetValue<DOMNode, DOMObject>(exec, propertyName, &DOMNodeTable, this);
00157 }
00158 
00159 Value DOMNode::getValueProperty(ExecState *exec, int token) const
00160 {
00161   khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
00162 
00163   switch (token) {
00164   case NodeName:
00165     return getString(node.nodeName());
00166   case NodeValue:
00167     return getString(node.nodeValue());
00168   case NodeType:
00169     return Number((unsigned int)node.nodeType());
00170   case ParentNode:
00171     return getDOMNode(exec,node.parentNode());
00172   case ParentElement: // IE only apparently
00173     return getDOMNode(exec,node.parentNode());
00174   case ChildNodes:
00175     return getDOMNodeList(exec,node.childNodes());
00176   case FirstChild:
00177     return getDOMNode(exec,node.firstChild());
00178   case LastChild:
00179     return getDOMNode(exec,node.lastChild());
00180   case PreviousSibling:
00181     return getDOMNode(exec,node.previousSibling());
00182   case NextSibling:
00183     return getDOMNode(exec,node.nextSibling());
00184   case Attributes:
00185     return getDOMNamedNodeMap(exec,node.attributes());
00186   case NamespaceURI:
00187     return getString(node.namespaceURI());
00188   case Prefix:
00189     return getString(node.prefix());
00190   case LocalName:
00191     return getString(node.localName());
00192   case OwnerDocument:
00193     return getDOMNode(exec,node.ownerDocument());
00194   case OnAbort:
00195     return getListener(DOM::EventImpl::ABORT_EVENT);
00196   case OnBlur:
00197     return getListener(DOM::EventImpl::BLUR_EVENT);
00198   case OnChange:
00199     return getListener(DOM::EventImpl::CHANGE_EVENT);
00200   case OnClick:
00201     return getListener(DOM::EventImpl::KHTML_ECMA_CLICK_EVENT);
00202   case OnDblClick:
00203     return getListener(DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT);
00204   case OnDragDrop:
00205     return getListener(DOM::EventImpl::KHTML_DRAGDROP_EVENT);
00206   case OnError:
00207     return getListener(DOM::EventImpl::KHTML_ERROR_EVENT);
00208   case OnFocus:
00209     return getListener(DOM::EventImpl::FOCUS_EVENT);
00210   case OnKeyDown:
00211     return getListener(DOM::EventImpl::KHTML_KEYDOWN_EVENT);
00212   case OnKeyPress:
00213     return getListener(DOM::EventImpl::KHTML_KEYPRESS_EVENT);
00214   case OnKeyUp:
00215     return getListener(DOM::EventImpl::KHTML_KEYUP_EVENT);
00216   case OnLoad:
00217     return getListener(DOM::EventImpl::LOAD_EVENT);
00218   case OnMouseDown:
00219     return getListener(DOM::EventImpl::MOUSEDOWN_EVENT);
00220   case OnMouseMove:
00221     return getListener(DOM::EventImpl::MOUSEMOVE_EVENT);
00222   case OnMouseOut:
00223     return getListener(DOM::EventImpl::MOUSEOUT_EVENT);
00224   case OnMouseOver:
00225     return getListener(DOM::EventImpl::MOUSEOVER_EVENT);
00226   case OnMouseUp:
00227     return getListener(DOM::EventImpl::MOUSEUP_EVENT);
00228   case OnMove:
00229     return getListener(DOM::EventImpl::KHTML_MOVE_EVENT);
00230   case OnReset:
00231     return getListener(DOM::EventImpl::RESET_EVENT);
00232   case OnResize:
00233     return getListener(DOM::EventImpl::RESIZE_EVENT);
00234   case OnSelect:
00235     return getListener(DOM::EventImpl::SELECT_EVENT);
00236   case OnSubmit:
00237     return getListener(DOM::EventImpl::SUBMIT_EVENT);
00238   case OnUnload:
00239     return getListener(DOM::EventImpl::UNLOAD_EVENT);
00240   case OffsetLeft:
00241   case OffsetTop:
00242   case OffsetWidth:
00243   case OffsetHeight:
00244   case OffsetParent:
00245   case ClientWidth:
00246   case ClientHeight:
00247   case ScrollLeft:
00248   case ScrollTop:
00249   {
00250     // no DOM standard, found in IE only
00251 
00252     // make sure our rendering is up to date before
00253     // we allow a query on these attributes.
00254     DOM::DocumentImpl* docimpl = node.handle()->getDocument();
00255     KHTMLView* v = 0;
00256     if ( docimpl ) {
00257       v = docimpl->view();
00258       // Only do a layout if changes have occurred that make it necessary.
00259       if ( v && docimpl->renderer() && !docimpl->renderer()->layouted() )
00260       {
00261         docimpl->updateRendering();
00262         docimpl->view()->layout();
00263       }
00264 
00265       // refetch in case the renderer changed
00266       rend = node.handle() ? node.handle()->renderer() : 0L;
00267     }
00268 
00269     if (rend && rend->isBody())
00270       rend = rend->root();
00271 
00272     switch (token) {
00273     case OffsetLeft:
00274       if ( rend )
00275         return Number(rend->xPos()); // TODO offsetLeft()
00276       else
00277         return Undefined();
00278     case OffsetTop:
00279       if ( rend )
00280         return Number(rend->yPos()); // TODO offsetTop()
00281       else
00282         return Undefined();
00283     case OffsetWidth:
00284       if ( rend )
00285         return Number(rend->width());
00286       else
00287         return Undefined();
00288     case OffsetHeight:
00289       if ( rend )
00290         return Number(rend->height());
00291       else
00292         return Undefined();
00293     case OffsetParent: {
00294       khtml::RenderObject* par = rend ? rend->parent() : 0; // TODO offsetParent
00295       if ( par )
00296         return getDOMNode(exec, par->element() );
00297       else
00298         return Undefined();
00299     }
00300     case ClientWidth:
00301       if (!rend)
00302         return Undefined();
00303       // "Width of the object including padding, but not including margin, border, or scroll bar."
00304       return Number(rend->width() - rend->borderLeft() - rend->borderRight() );
00305     case ClientHeight:
00306       if (!rend)
00307         return Undefined();
00308       // "Height of the object including padding, but not including margin, border, or scroll bar."
00309       return Number(rend->height() - rend->borderTop() - rend->borderBottom() );
00310     case ScrollLeft: {
00311       int x, y;
00312       if ( rend && v && rend->absolutePosition( x, y ) )
00313         return Number(-x + v->contentsX());
00314       else
00315         return Undefined();
00316     }
00317     case ScrollTop: {
00318       int x, y;
00319       if ( rend && v && rend->absolutePosition( x, y ) )
00320         return Number(-y + v->contentsY());
00321       else
00322         return Undefined();
00323     }
00324     }
00325   }
00326   case SourceIndex: {
00327     // Retrieves the ordinal position of the object, in source order, as the object
00328     // appears in the document's all collection
00329     // i.e. document.all[n.sourceIndex] == n
00330     DOM::Document doc = node.ownerDocument();
00331     if (doc.isHTMLDocument()) {
00332       DOM::HTMLCollection all = static_cast<DOM::HTMLDocument>(doc).all();
00333       unsigned long i = 0;
00334       DOM::Node n = all.firstItem();
00335       for ( ; !n.isNull() && n != node; n = all.nextItem() )
00336         ++i;
00337       Q_ASSERT( !n.isNull() ); // node not in document.all !?
00338       return Number(i);
00339     }
00340   }
00341   default:
00342     kdWarning() << "Unhandled token in DOMNode::getValueProperty : " << token << endl;
00343     break;
00344   }
00345 
00346   return Undefined();
00347 }
00348 
00349 void DOMNode::tryPut(ExecState *exec, const UString& propertyName, const Value& value, int attr)
00350 {
00351 #ifdef KJS_VERBOSE
00352   kdDebug(6070) << "DOMNode::tryPut " << propertyName.qstring() << endl;
00353 #endif
00354   DOMObjectLookupPut<DOMNode,DOMObject>(exec, propertyName, value, attr,
00355                                         &DOMNodeTable, this );
00356 }
00357 
00358 void DOMNode::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
00359 {
00360   switch (token) {
00361   case NodeValue:
00362     node.setNodeValue(value.toString(exec).string());
00363     break;
00364   case Prefix:
00365     node.setPrefix(value.toString(exec).string());
00366     break;
00367   case OnAbort:
00368     setListener(exec,DOM::EventImpl::ABORT_EVENT,value);
00369     break;
00370   case OnBlur:
00371     setListener(exec,DOM::EventImpl::BLUR_EVENT,value);
00372     break;
00373   case OnChange:
00374     setListener(exec,DOM::EventImpl::CHANGE_EVENT,value);
00375     break;
00376   case OnClick:
00377     setListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT,value);
00378     break;
00379   case OnDblClick:
00380     setListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT,value);
00381     break;
00382   case OnDragDrop:
00383     setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
00384     break;
00385   case OnError:
00386     setListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT,value);
00387     break;
00388   case OnFocus:
00389     setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
00390     break;
00391   case OnKeyDown:
00392     setListener(exec,DOM::EventImpl::KHTML_KEYDOWN_EVENT,value);
00393     break;
00394   case OnKeyPress:
00395     setListener(exec,DOM::EventImpl::KHTML_KEYPRESS_EVENT,value);
00396     break;
00397   case OnKeyUp:
00398     setListener(exec,DOM::EventImpl::KHTML_KEYUP_EVENT,value);
00399     break;
00400   case OnLoad:
00401     setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
00402     break;
00403   case OnMouseDown:
00404     setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
00405     break;
00406   case OnMouseMove:
00407     setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
00408     break;
00409   case OnMouseOut:
00410     setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
00411     break;
00412   case OnMouseOver:
00413     setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
00414     break;
00415   case OnMouseUp:
00416     setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
00417     break;
00418   case OnMove:
00419     setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
00420     break;
00421   case OnReset:
00422     setListener(exec,DOM::EventImpl::RESET_EVENT,value);
00423     break;
00424   case OnResize:
00425     setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
00426     break;
00427   case OnSelect:
00428     setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
00429     break;
00430   case OnSubmit:
00431     setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
00432     break;
00433   case OnUnload:
00434     setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
00435     break;
00436   default:
00437     kdWarning() << "DOMNode::putValueProperty unhandled token " << token << endl;
00438   }
00439 }
00440 
00441 Value DOMNode::toPrimitive(ExecState *exec, Type /*preferred*/) 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(); // fallback
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     if (listener)
00473     return static_cast<JSEventListener*>(listener)->listenerObj();
00474     else
00475     return Null();
00476 }
00477 
00478 List DOMNode::eventHandlerScope(ExecState *) const
00479 {
00480   return List::empty();
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     }
00529   }
00530 
00531   return Undefined();
00532 }
00533 
00534 // -------------------------------------------------------------------------
00535 
00536 const ClassInfo DOMNodeList::info = { "NodeList", 0, 0, 0 };
00537 
00538 DOMNodeList::DOMNodeList(ExecState *exec, const DOM::NodeList& l)
00539  : DOMObject(exec->interpreter()->builtinObjectPrototype()), list(l) { }
00540 
00541 DOMNodeList::~DOMNodeList()
00542 {
00543   ScriptInterpreter::forgetDOMObject(list.handle());
00544 }
00545 
00546 // We have to implement hasProperty since we don't use a hashtable for 'length' and 'item'
00547 // ## this breaks "for (..in..)" though.
00548 bool DOMNodeList::hasProperty(ExecState *exec, const UString &p) const
00549 {
00550   if (p == "length" || p == "item")
00551     return true;
00552   return ObjectImp::hasProperty(exec, p);
00553 }
00554 
00555 Value DOMNodeList::tryGet(ExecState *exec, const UString &p) const
00556 {
00557 #ifdef KJS_VERBOSE
00558   kdDebug(6070) << "DOMNodeList::tryGet " << p.ascii() << endl;
00559 #endif
00560   Value result;
00561 
00562   if (p == "length")
00563     result = Number(list.length());
00564   else if (p == "item") {
00565     // No need for a complete hashtable for a single func, but we still want
00566     // to use the caching feature of lookupOrCreateFunction.
00567     result = lookupOrCreateFunction<DOMNodeListFunc>(exec, p, this, DOMNodeListFunc::Item, 1, DontDelete|Function);
00568     //result = new DOMNodeListFunc(exec, DOMNodeListFunc::Item, 1);
00569   }
00570   else {
00571     // array index ?
00572     bool ok;
00573     long unsigned int idx = p.toULong(&ok);
00574     if (ok)
00575       result = getDOMNode(exec,list.item(idx));
00576     else {
00577       DOM::HTMLElement e;
00578       unsigned long l = list.length();
00579       bool found = false;
00580 
00581       for ( unsigned long i = 0; i < l; i++ )
00582         if ( ( e = list.item( i ) ).id() == p.string() ) {
00583           result = getDOMNode(exec, list.item( i ) );
00584           found = true;
00585           break;
00586         }
00587 
00588       if ( !found )
00589         result = ObjectImp::get(exec, p);
00590     }
00591   }
00592 
00593   return result;
00594 }
00595 
00596 // Need to support both get and call, so that list[0] and list(0) work.
00597 Value DOMNodeList::call(ExecState *exec, Object &thisObj, const List &args)
00598 {
00599   // This code duplication is necessary, DOMNodeList isn't a DOMFunction
00600   Value val;
00601   try {
00602     val = tryCall(exec, thisObj, args);
00603   }
00604   // pity there's no way to distinguish between these in JS code
00605   catch (...) {
00606     Object err = Error::create(exec, GeneralError, "Exception from DOMNodeList");
00607     exec->setException(err);
00608   }
00609   return val;
00610 }
00611 
00612 Value DOMNodeList::tryCall(ExecState *exec, Object &, const List &args)
00613 {
00614   // Do not use thisObj here. See HTMLCollection.
00615   UString s = args[0].toString(exec);
00616   bool ok;
00617   unsigned int u = s.toULong(&ok);
00618   if (ok)
00619     return getDOMNode(exec,list.item(u));
00620 
00621   kdWarning() << "KJS::DOMNodeList::tryCall " << s.qstring() << " not implemented" << endl;
00622   return Undefined();
00623 }
00624 
00625 DOMNodeListFunc::DOMNodeListFunc(ExecState *exec, int i, int len)
00626   : DOMFunction(), id(i)
00627 {
00628   Value protect(this);
00629   put(exec,"length",Number(len),DontDelete|ReadOnly|DontEnum);
00630 }
00631 
00632 // Not a prototype class currently, but should probably be converted to one
00633 Value DOMNodeListFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00634 {
00635   KJS_CHECK_THIS( KJS::DOMNodeList, thisObj );
00636   DOM::NodeList list = static_cast<DOMNodeList *>(thisObj.imp())->nodeList();
00637   Value result;
00638 
00639   if (id == Item)
00640     result = getDOMNode(exec, list.item(args[0].toInt32(exec)));
00641   return result;
00642 }
00643 
00644 // -------------------------------------------------------------------------
00645 
00646 const ClassInfo DOMAttr::info = { "Attr", &DOMNode::info, &DOMAttrTable, 0 };
00647 
00648 /* Source for DOMAttrTable. Use "make hashtables" to regenerate.
00649 @begin DOMAttrTable 5
00650   name      DOMAttr::Name       DontDelete|ReadOnly
00651   specified DOMAttr::Specified  DontDelete|ReadOnly
00652   value     DOMAttr::ValueProperty  DontDelete|ReadOnly
00653   ownerElement  DOMAttr::OwnerElement   DontDelete|ReadOnly
00654 @end
00655 */
00656 Value DOMAttr::tryGet(ExecState *exec, const UString &propertyName) const
00657 {
00658 #ifdef KJS_VERBOSE
00659   kdDebug(6070) << "DOMAttr::tryPut " << propertyName.qstring() << endl;
00660 #endif
00661   return DOMObjectLookupGetValue<DOMAttr,DOMNode>(exec, propertyName,
00662                                                   &DOMAttrTable, this );
00663 }
00664 
00665 Value DOMAttr::getValueProperty(ExecState *exec, int token) const
00666 {
00667   switch (token) {
00668   case Name:
00669     return getString(static_cast<DOM::Attr>(node).name());
00670   case Specified:
00671     return Boolean(static_cast<DOM::Attr>(node).specified());
00672   case ValueProperty:
00673     return getString(static_cast<DOM::Attr>(node).value());
00674   case OwnerElement: // DOM2
00675     return getDOMNode(exec,static_cast<DOM::Attr>(node).ownerElement());
00676   }
00677   return Value(); // not reached
00678 }
00679 
00680 void DOMAttr::tryPut(ExecState *exec, const UString &propertyName, const Value& value, int attr)
00681 {
00682 #ifdef KJS_VERBOSE
00683   kdDebug(6070) << "DOMAttr::tryPut " << propertyName.qstring() << endl;
00684 #endif
00685   DOMObjectLookupPut<DOMAttr,DOMNode>(exec, propertyName, value, attr,
00686                                       &DOMAttrTable, this );
00687 }
00688 
00689 void DOMAttr::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
00690 {
00691   switch (token) {
00692   case ValueProperty:
00693     static_cast<DOM::Attr>(node).setValue(value.toString(exec).string());
00694     return;
00695   default:
00696     kdWarning() << "DOMAttr::putValueProperty unhandled token " << token << endl;
00697   }
00698 }
00699 
00700 // -------------------------------------------------------------------------
00701 
00702 /* Source for DOMDocumentProtoTable. Use "make hashtables" to regenerate.
00703 @begin DOMDocumentProtoTable 23
00704   createElement   DOMDocument::CreateElement                   DontDelete|Function 1
00705   createDocumentFragment DOMDocument::CreateDocumentFragment   DontDelete|Function 1
00706   createTextNode  DOMDocument::CreateTextNode                  DontDelete|Function 1
00707   createComment   DOMDocument::CreateComment                   DontDelete|Function 1
00708   createCDATASection DOMDocument::CreateCDATASection           DontDelete|Function 1
00709   createProcessingInstruction DOMDocument::CreateProcessingInstruction DontDelete|Function 1
00710   createAttribute DOMDocument::CreateAttribute                 DontDelete|Function 1
00711   createEntityReference DOMDocument::CreateEntityReference     DontDelete|Function 1
00712   getElementsByTagName  DOMDocument::GetElementsByTagName      DontDelete|Function 1
00713   importNode           DOMDocument::ImportNode                 DontDelete|Function 2
00714   createElementNS      DOMDocument::CreateElementNS            DontDelete|Function 2
00715   createAttributeNS    DOMDocument::CreateAttributeNS          DontDelete|Function 2
00716   getElementsByTagNameNS  DOMDocument::GetElementsByTagNameNS  DontDelete|Function 2
00717   getElementById     DOMDocument::GetElementById               DontDelete|Function 1
00718   createRange        DOMDocument::CreateRange                  DontDelete|Function 0
00719   createNodeIterator DOMDocument::CreateNodeIterator           DontDelete|Function 3
00720   createTreeWalker   DOMDocument::CreateTreeWalker             DontDelete|Function 4
00721   createEvent        DOMDocument::CreateEvent                  DontDelete|Function 1
00722   getOverrideStyle   DOMDocument::GetOverrideStyle             DontDelete|Function 2
00723 @end
00724 */
00725 DEFINE_PROTOTYPE("DOMDocument", DOMDocumentProto)
00726 IMPLEMENT_PROTOFUNC_DOM(DOMDocumentProtoFunc)
00727 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMDocumentProto, DOMDocumentProtoFunc, DOMNodeProto)
00728 
00729 const ClassInfo DOMDocument::info = { "Document", &DOMNode::info, &DOMDocumentTable, 0 };
00730 
00731 /* Source for DOMDocumentTable. Use "make hashtables" to regenerate.
00732 @begin DOMDocumentTable 4
00733   doctype         DOMDocument::DocType                         DontDelete|ReadOnly
00734   implementation  DOMDocument::Implementation                  DontDelete|ReadOnly
00735   documentElement DOMDocument::DocumentElement                 DontDelete|ReadOnly
00736   styleSheets     DOMDocument::StyleSheets                     DontDelete|ReadOnly
00737   readyState      DOMDocument::ReadyState                      DontDelete|ReadOnly
00738   defaultView     DOMDocument::DefaultView                     DontDelete|ReadOnly
00739 @end
00740 */
00741 
00742 DOMDocument::DOMDocument(ExecState *exec, const DOM::Document& d)
00743   : DOMNode(DOMDocumentProto::self(exec), d) { }
00744 
00745 DOMDocument::DOMDocument(const Object& proto, const DOM::Document& d)
00746   : DOMNode(proto, d) { }
00747 
00748 DOMDocument::~DOMDocument()
00749 {
00750   //ScriptInterpreter::forgetDOMObject(node.handle());
00751 }
00752 
00753 Value DOMDocument::tryGet(ExecState *exec, const UString &propertyName) const
00754 {
00755 #ifdef KJS_VERBOSE
00756   kdDebug(6070) << "DOMDocument::tryGet " << propertyName.qstring() << endl;
00757 #endif
00758   return DOMObjectLookupGetValue<DOMDocument, DOMNode>(
00759     exec, propertyName, &DOMDocumentTable, this);
00760 }
00761 
00762 Value DOMDocument::getValueProperty(ExecState *exec, int token) const
00763 {
00764   DOM::Document doc = static_cast<DOM::Document>(node);
00765 
00766   switch(token) {
00767   case DocType:
00768     return getDOMNode(exec,doc.doctype());
00769   case Implementation:
00770     return getDOMDOMImplementation(exec,doc.implementation());
00771   case DocumentElement:
00772     return getDOMNode(exec,doc.documentElement());
00773   case StyleSheets:
00774     //kdDebug() << "DOMDocument::StyleSheets, returning " << doc.styleSheets().length() << " stylesheets" << endl;
00775     return getDOMStyleSheetList(exec, doc.styleSheets(), doc);
00776   case DOMDocument::DefaultView: // DOM2
00777     return getDOMAbstractView(exec, doc.defaultView());
00778   case ReadyState:
00779     {
00780     DOM::DocumentImpl* docimpl = node.handle()->getDocument();
00781     if ( docimpl && docimpl->view() )
00782     {
00783       KHTMLPart* part = docimpl->view()->part();
00784       if ( part ) {
00785         if (part->d->m_bComplete) return String("complete");
00786         if (docimpl->parsing()) return String("loading");
00787         return String("loaded");
00788         // What does the interactive value mean ?
00789         // Missing support for "uninitialized"
00790       }
00791     }
00792     return Undefined();
00793     }
00794   default:
00795     kdWarning() << "DOMDocument::getValueProperty unhandled token " << token << endl;
00796     return Value();
00797   }
00798 }
00799 
00800 Value DOMDocumentProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00801 {
00802   KJS_CHECK_THIS( KJS::DOMDocument, thisObj );
00803   DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
00804   DOM::Document doc = static_cast<DOM::Document>(node);
00805   String str = args[0].toString(exec);
00806   DOM::DOMString s = str.value().string();
00807 
00808   switch(id) {
00809   case DOMDocument::CreateElement:
00810     return getDOMNode(exec,doc.createElement(s));
00811   case DOMDocument::CreateDocumentFragment:
00812     return getDOMNode(exec,doc.createDocumentFragment());
00813   case DOMDocument::CreateTextNode:
00814     return getDOMNode(exec,doc.createTextNode(s));
00815   case DOMDocument::CreateComment:
00816     return getDOMNode(exec,doc.createComment(s));
00817   case DOMDocument::CreateCDATASection:
00818     return getDOMNode(exec,doc.createCDATASection(s));  /* TODO: okay ? */
00819   case DOMDocument::CreateProcessingInstruction:
00820     return getDOMNode(exec,doc.createProcessingInstruction(args[0].toString(exec).string(),
00821                                                                  args[1].toString(exec).string()));
00822   case DOMDocument::CreateAttribute:
00823     return getDOMNode(exec,doc.createAttribute(s));
00824   case DOMDocument::CreateEntityReference:
00825     return getDOMNode(exec,doc.createEntityReference(args[0].toString(exec).string()));
00826   case DOMDocument::GetElementsByTagName:
00827     return getDOMNodeList(exec,doc.getElementsByTagName(s));
00828   case DOMDocument::ImportNode: // DOM2
00829     return getDOMNode(exec,doc.importNode(toNode(args[0]), args[1].toBoolean(exec)));
00830   case DOMDocument::CreateElementNS: // DOM2
00831     return getDOMNode(exec,doc.createElementNS(args[0].toString(exec).string(), args[1].toString(exec).string()));
00832   case DOMDocument::CreateAttributeNS: // DOM2
00833     return getDOMNode(exec,doc.createAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
00834   case DOMDocument::GetElementsByTagNameNS: // DOM2
00835     return getDOMNodeList(exec,doc.getElementsByTagNameNS(args[0].toString(exec).string(),
00836                                                           args[1].toString(exec).string()));
00837   case DOMDocument::GetElementById:
00838     return getDOMNode(exec,doc.getElementById(args[0].toString(exec).string()));
00839   case DOMDocument::CreateRange:
00840     return getDOMRange(exec,doc.createRange());
00841   case DOMDocument::CreateNodeIterator:
00842     if (args[2].isA(NullType)) {
00843         DOM::NodeFilter filter;
00844         return getDOMNodeIterator(exec,
00845                                   doc.createNodeIterator(toNode(args[0]),
00846                                                          (long unsigned int)(args[1].toNumber(exec)),
00847                                                          filter,args[3].toBoolean(exec)));
00848     }
00849     else {
00850       Object obj = Object::dynamicCast(args[2]);
00851       if (!obj.isNull())
00852       {
00853         DOM::CustomNodeFilter *customFilter = new JSNodeFilter(obj);
00854         DOM::NodeFilter filter = DOM::NodeFilter::createCustom(customFilter);
00855         return getDOMNodeIterator(exec,
00856           doc.createNodeIterator(
00857             toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
00858             filter,args[3].toBoolean(exec)));
00859       }// else?
00860     }
00861   case DOMDocument::CreateTreeWalker:
00862     return getDOMTreeWalker(exec,doc.createTreeWalker(toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
00863              toNodeFilter(args[2]),args[3].toBoolean(exec)));
00864   case DOMDocument::CreateEvent:
00865     return getDOMEvent(exec,doc.createEvent(s));
00866   case DOMDocument::GetOverrideStyle: {
00867     DOM::Node arg0 = toNode(args[0]);
00868     if (arg0.nodeType() != DOM::Node::ELEMENT_NODE)
00869       return Undefined(); // throw exception?
00870     else
00871       return getDOMCSSStyleDeclaration(exec,doc.getOverrideStyle(static_cast<DOM::Element>(arg0),args[1].toString(exec).string()));
00872   }
00873   default:
00874     break;
00875   }
00876 
00877   return Undefined();
00878 }
00879 
00880 // -------------------------------------------------------------------------
00881 
00882 /* Source for DOMElementProtoTable. Use "make hashtables" to regenerate.
00883 @begin DOMElementProtoTable 17
00884   getAttribute      DOMElement::GetAttribute    DontDelete|Function 1
00885   setAttribute      DOMElement::SetAttribute    DontDelete|Function 2
00886   removeAttribute   DOMElement::RemoveAttribute DontDelete|Function 1
00887   getAttributeNode  DOMElement::GetAttributeNode    DontDelete|Function 1
00888   setAttributeNode  DOMElement::SetAttributeNode    DontDelete|Function 2
00889   removeAttributeNode   DOMElement::RemoveAttributeNode DontDelete|Function 1
00890   getElementsByTagName  DOMElement::GetElementsByTagName    DontDelete|Function 1
00891   hasAttribute      DOMElement::HasAttribute    DontDelete|Function 1
00892   getAttributeNS    DOMElement::GetAttributeNS  DontDelete|Function 2
00893   setAttributeNS    DOMElement::SetAttributeNS  DontDelete|Function 3
00894   removeAttributeNS DOMElement::RemoveAttributeNS   DontDelete|Function 2
00895   getAttributeNodeNS    DOMElement::GetAttributeNodeNS  DontDelete|Function 2
00896   setAttributeNodeNS    DOMElement::SetAttributeNodeNS  DontDelete|Function 1
00897   getElementsByTagNameNS DOMElement::GetElementsByTagNameNS DontDelete|Function 2
00898   hasAttributeNS    DOMElement::HasAttributeNS  DontDelete|Function 2
00899 @end
00900 */
00901 DEFINE_PROTOTYPE("DOMElement",DOMElementProto)
00902 IMPLEMENT_PROTOFUNC_DOM(DOMElementProtoFunc)
00903 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMElementProto,DOMElementProtoFunc,DOMNodeProto)
00904 
00905 const ClassInfo DOMElement::info = { "Element", &DOMNode::info, &DOMElementTable, 0 };
00906 /* Source for DOMElementTable. Use "make hashtables" to regenerate.
00907 @begin DOMElementTable 3
00908   tagName   DOMElement::TagName                         DontDelete|ReadOnly
00909   style     DOMElement::Style                           DontDelete|ReadOnly
00910 @end
00911 */
00912 DOMElement::DOMElement(ExecState *exec, const DOM::Element& e)
00913   : DOMNode(DOMElementProto::self(exec), e) { }
00914 
00915 DOMElement::DOMElement(const Object& proto, const DOM::Element& e)
00916   : DOMNode(proto, e) { }
00917 
00918 Value DOMElement::tryGet(ExecState *exec, const UString &propertyName) const
00919 {
00920 #ifdef KJS_VERBOSE
00921   kdDebug(6070) << "DOMElement::tryGet " << propertyName.qstring() << endl;
00922 #endif
00923   DOM::Element element = static_cast<DOM::Element>(node);
00924 
00925   const HashEntry* entry = Lookup::findEntry(&DOMElementTable, propertyName);
00926   if (entry)
00927   {
00928     switch( entry->value ) {
00929     case TagName:
00930       return getString(element.tagName());
00931     case Style:
00932       return getDOMCSSStyleDeclaration(exec,element.style());
00933     default:
00934       kdWarning() << "Unhandled token in DOMElement::tryGet : " << entry->value << endl;
00935       break;
00936     }
00937   }
00938   // We have to check in DOMNode before giving access to attributes, otherwise
00939   // onload="..." would make onload return the string (attribute value) instead of
00940   // the listener object (function).
00941   if (DOMNode::hasProperty(exec, propertyName))
00942     return DOMNode::tryGet(exec, propertyName);
00943 
00944   DOM::DOMString attr = element.getAttribute( propertyName.string() );
00945   // Give access to attributes
00946   if ( !attr.isNull() )
00947     return getString( attr );
00948 
00949   return Undefined();
00950 }
00951 
00952 Value DOMElementProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
00953 {
00954   KJS_CHECK_THIS( KJS::DOMNode, thisObj ); // node should be enough here, given the cast
00955   DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
00956   DOM::Element element = static_cast<DOM::Element>(node);
00957 
00958   switch(id) {
00959     case DOMElement::GetAttribute:
00960       return String(element.getAttribute(args[0].toString(exec).string()));
00961     case DOMElement::SetAttribute:
00962       element.setAttribute(args[0].toString(exec).string(),args[1].toString(exec).string());
00963       return Undefined();
00964     case DOMElement::RemoveAttribute:
00965       element.removeAttribute(args[0].toString(exec).string());
00966       return Undefined();
00967     case DOMElement::GetAttributeNode:
00968       return getDOMNode(exec,element.getAttributeNode(args[0].toString(exec).string()));
00969     case DOMElement::SetAttributeNode:
00970       return getDOMNode(exec,element.setAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
00971     case DOMElement::RemoveAttributeNode:
00972       return getDOMNode(exec,element.removeAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
00973     case DOMElement::GetElementsByTagName:
00974       return getDOMNodeList(exec,element.getElementsByTagName(args[0].toString(exec).string()));
00975     case DOMElement::HasAttribute: // DOM2
00976       return Boolean(element.hasAttribute(args[0].toString(exec).string()));
00977     case DOMElement::GetAttributeNS: // DOM2
00978       return String(element.getAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
00979     case DOMElement::SetAttributeNS: // DOM2
00980       element.setAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string());
00981       return Undefined();
00982     case DOMElement::RemoveAttributeNS: // DOM2
00983       element.removeAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string());
00984       return Undefined();
00985     case DOMElement::GetAttributeNodeNS: // DOM2
00986       return getDOMNode(exec,element.getAttributeNodeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
00987     case DOMElement::SetAttributeNodeNS: // DOM2
00988       return getDOMNode(exec,element.setAttributeNodeNS((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
00989     case DOMElement::GetElementsByTagNameNS: // DOM2
00990       return getDOMNodeList(exec,element.getElementsByTagNameNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
00991     case DOMElement::HasAttributeNS: // DOM2
00992       return Boolean(element.hasAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
00993   default:
00994     return Undefined();
00995   }
00996 }
00997 
00998 // -------------------------------------------------------------------------
00999 
01000 /* Source for DOMDOMImplementationProtoTable. Use "make hashtables" to regenerate.
01001 @begin DOMDOMImplementationProtoTable 5
01002   hasFeature        DOMDOMImplementation::HasFeature        DontDelete|Function 2
01003   createCSSStyleSheet   DOMDOMImplementation::CreateCSSStyleSheet   DontDelete|Function 2
01004 # DOM2
01005   createDocumentType    DOMDOMImplementation::CreateDocumentType    DontDelete|Function 3
01006   createDocument    DOMDOMImplementation::CreateDocument        DontDelete|Function 3
01007   createHTMLDocument    DOMDOMImplementation::CreateHTMLDocument        DontDelete|Function 1
01008 @end
01009 */
01010 DEFINE_PROTOTYPE("DOMImplementation",DOMDOMImplementationProto)
01011 IMPLEMENT_PROTOFUNC_DOM(DOMDOMImplementationProtoFunc)
01012 IMPLEMENT_PROTOTYPE(DOMDOMImplementationProto,DOMDOMImplementationProtoFunc)
01013 
01014 const ClassInfo DOMDOMImplementation::info = { "DOMImplementation", 0, 0, 0 };
01015 
01016 DOMDOMImplementation::DOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
01017   : DOMObject(DOMDOMImplementationProto::self(exec)), implementation(i) { }
01018 
01019 DOMDOMImplementation::~DOMDOMImplementation()
01020 {
01021   ScriptInterpreter::forgetDOMObject(implementation.handle());
01022 }
01023 
01024 Value DOMDOMImplementationProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01025 {
01026   KJS_CHECK_THIS( KJS::DOMDOMImplementation, thisObj );
01027   DOM::DOMImplementation implementation = static_cast<DOMDOMImplementation *>( thisObj.imp() )->toImplementation();
01028 
01029   switch(id) {
01030   case DOMDOMImplementation::HasFeature:
01031     return Boolean(implementation.hasFeature(args[0].toString(exec).string(),args[1].toString(exec).string()));
01032   case DOMDOMImplementation::CreateDocumentType: // DOM2
01033     return getDOMNode(exec,implementation.createDocumentType(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string()));
01034   case DOMDOMImplementation::CreateDocument: // DOM2
01035     return getDOMNode(exec,implementation.createDocument(args[0].toString(exec).string(),args[1].toString(exec).string(),toNode(args[2])));
01036   case DOMDOMImplementation::CreateCSSStyleSheet: // DOM2
01037     return getDOMStyleSheet(exec,implementation.createCSSStyleSheet(args[0].toString(exec).string(),args[1].toString(exec).string()));
01038   case DOMDOMImplementation::CreateHTMLDocument: // DOM2-HTML
01039     return getDOMNode(exec, implementation.createHTMLDocument(args[0].toString(exec).string()));
01040   default:
01041     break;
01042   }
01043   return Undefined();
01044 }
01045 
01046 // -------------------------------------------------------------------------
01047 
01048 const ClassInfo DOMDocumentType::info = { "DocumentType", &DOMNode::info, &DOMDocumentTypeTable, 0 };
01049 
01050 /* Source for DOMDocumentTypeTable. Use "make hashtables" to regenerate.
01051 @begin DOMDocumentTypeTable 6
01052   name          DOMDocumentType::Name       DontDelete|ReadOnly
01053   entities      DOMDocumentType::Entities   DontDelete|ReadOnly
01054   notations     DOMDocumentType::Notations  DontDelete|ReadOnly
01055 # DOM2
01056   publicId      DOMDocumentType::PublicId   DontDelete|ReadOnly
01057   systemId      DOMDocumentType::SystemId   DontDelete|ReadOnly
01058   internalSubset    DOMDocumentType::InternalSubset DontDelete|ReadOnly
01059 @end
01060 */
01061 DOMDocumentType::DOMDocumentType(ExecState *exec, const DOM::DocumentType& dt)
01062   : DOMNode( /*### no proto yet*/exec, dt ) { }
01063 
01064 Value DOMDocumentType::tryGet(ExecState *exec, const UString &propertyName) const
01065 {
01066   return DOMObjectLookupGetValue<DOMDocumentType, DOMNode>(exec, propertyName, &DOMDocumentTypeTable, this);
01067 }
01068 
01069 Value DOMDocumentType::getValueProperty(ExecState *exec, int token) const
01070 {
01071   DOM::DocumentType type = static_cast<DOM::DocumentType>(node);
01072   switch (token) {
01073   case Name:
01074     return String(type.name()); // not getString, otherwise doctype.name.indexOf() fails.
01075   case Entities:
01076     return getDOMNamedNodeMap(exec,type.entities());
01077   case Notations:
01078     return getDOMNamedNodeMap(exec,type.notations());
01079   case PublicId: // DOM2
01080     return getString(type.publicId());
01081   case SystemId: // DOM2
01082     return getString(type.systemId());
01083   case InternalSubset: // DOM2
01084     return getString(type.internalSubset());
01085   default:
01086     kdWarning() << "DOMDocumentType::getValueProperty unhandled token " << token << endl;
01087     return Value();
01088   }
01089 }
01090 
01091 // -------------------------------------------------------------------------
01092 
01093 /* Source for DOMNamedNodeMapProtoTable. Use "make hashtables" to regenerate.
01094 @begin DOMNamedNodeMapProtoTable 7
01095   getNamedItem      DOMNamedNodeMap::GetNamedItem       DontDelete|Function 1
01096   setNamedItem      DOMNamedNodeMap::SetNamedItem       DontDelete|Function 1
01097   removeNamedItem   DOMNamedNodeMap::RemoveNamedItem    DontDelete|Function 1
01098   item          DOMNamedNodeMap::Item           DontDelete|Function 1
01099 # DOM2
01100   getNamedItemNS    DOMNamedNodeMap::GetNamedItemNS     DontDelete|Function 2
01101   setNamedItemNS    DOMNamedNodeMap::SetNamedItemNS     DontDelete|Function 1
01102   removeNamedItemNS DOMNamedNodeMap::RemoveNamedItemNS  DontDelete|Function 2
01103 @end
01104 */
01105 DEFINE_PROTOTYPE("NamedNodeMap", DOMNamedNodeMapProto)
01106 IMPLEMENT_PROTOFUNC_DOM(DOMNamedNodeMapProtoFunc)
01107 IMPLEMENT_PROTOTYPE(DOMNamedNodeMapProto,DOMNamedNodeMapProtoFunc)
01108 
01109 const ClassInfo DOMNamedNodeMap::info = { "NamedNodeMap", 0, 0, 0 };
01110 
01111 DOMNamedNodeMap::DOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
01112   : DOMObject(DOMNamedNodeMapProto::self(exec)), map(m) { }
01113 
01114 DOMNamedNodeMap::~DOMNamedNodeMap()
01115 {
01116   ScriptInterpreter::forgetDOMObject(map.handle());
01117 }
01118 
01119 // We have to implement hasProperty since we don't use a hashtable for 'length'
01120 // ## this breaks "for (..in..)" though.
01121 bool DOMNamedNodeMap::hasProperty(ExecState *exec, const UString &p) const
01122 {
01123   if (p == "length")
01124     return true;
01125   return DOMObject::hasProperty(exec, p);
01126 }
01127 
01128 Value DOMNamedNodeMap::tryGet(ExecState* exec, const UString &p) const
01129 {
01130   if (p == "length")
01131     return Number(map.length());
01132 
01133   // array index ?
01134   bool ok;
01135   long unsigned int idx = p.toULong(&ok);
01136   if (ok)
01137     return getDOMNode(exec,map.item(idx));
01138 
01139   // Anything else (including functions, defined in the prototype)
01140   return DOMObject::tryGet(exec, p);
01141 }
01142 
01143 Value DOMNamedNodeMapProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01144 {
01145   KJS_CHECK_THIS( KJS::DOMNamedNodeMap, thisObj );
01146   DOM::NamedNodeMap map = static_cast<DOMNamedNodeMap *>(thisObj.imp())->toMap();
01147 
01148   switch(id) {
01149     case DOMNamedNodeMap::GetNamedItem:
01150       return getDOMNode(exec, map.getNamedItem(args[0].toString(exec).string()));
01151     case DOMNamedNodeMap::SetNamedItem:
01152       return getDOMNode(exec, map.setNamedItem((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
01153     case DOMNamedNodeMap::RemoveNamedItem:
01154       return getDOMNode(exec, map.removeNamedItem(args[0].toString(exec).string()));
01155     case DOMNamedNodeMap::Item:
01156       return getDOMNode(exec, map.item(args[0].toInt32(exec)));
01157     case DOMNamedNodeMap::GetNamedItemNS: // DOM2
01158       return getDOMNode(exec, map.getNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01159     case DOMNamedNodeMap::SetNamedItemNS: // DOM2
01160       return getDOMNode(exec, map.setNamedItemNS(toNode(args[0])));
01161     case DOMNamedNodeMap::RemoveNamedItemNS: // DOM2
01162       return getDOMNode(exec, map.removeNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
01163     default:
01164       break;
01165   }
01166 
01167   return Undefined();
01168 }
01169 
01170 // -------------------------------------------------------------------------
01171 
01172 const ClassInfo DOMProcessingInstruction::info = { "ProcessingInstruction", &DOMNode::info, &DOMProcessingInstructionTable, 0 };
01173 
01174 /* Source for DOMProcessingInstructionTable. Use "make hashtables" to regenerate.
01175 @begin DOMProcessingInstructionTable 3
01176   target    DOMProcessingInstruction::Target    DontDelete|ReadOnly
01177   data      DOMProcessingInstruction::Data      DontDelete
01178   sheet     DOMProcessingInstruction::Sheet     DontDelete|ReadOnly
01179 @end
01180 */
01181 Value DOMProcessingInstruction::tryGet(ExecState *exec, const UString &propertyName) const
01182 {
01183   return DOMObjectLookupGetValue<DOMProcessingInstruction, DOMNode>(exec, propertyName, &DOMProcessingInstructionTable, this);
01184 }
01185 
01186 Value DOMProcessingInstruction::getValueProperty(ExecState *exec, int token) const
01187 {
01188   switch (token) {
01189   case Target:
01190     return getString(static_cast<DOM::ProcessingInstruction>(node).target());
01191   case Data:
01192     return getString(static_cast<DOM::ProcessingInstruction>(node).data());
01193   case Sheet:
01194     return getDOMStyleSheet(exec,static_cast<DOM::ProcessingInstruction>(node).sheet());
01195   default:
01196     kdWarning() << "DOMProcessingInstruction::getValueProperty unhandled token " << token << endl;
01197     return Value();
01198   }
01199 }
01200 
01201 void DOMProcessingInstruction::tryPut(ExecState *exec, const UString &propertyName, const Value& value, int attr)
01202 {
01203   // Not worth using the hashtable for this one ;)
01204   if (propertyName == "data")
01205     static_cast<DOM::ProcessingInstruction>(node).setData(value.toString(exec).string());
01206   else
01207     DOMNode::tryPut(exec, propertyName,value,attr);
01208 }
01209 
01210 // -------------------------------------------------------------------------
01211 
01212 const ClassInfo DOMNotation::info = { "Notation", &DOMNode::info, &DOMNotationTable, 0 };
01213 
01214 /* Source for DOMNotationTable. Use "make hashtables" to regenerate.
01215 @begin DOMNotationTable 2
01216   publicId      DOMNotation::PublicId   DontDelete|ReadOnly
01217   systemId      DOMNotation::SystemId   DontDelete|ReadOnly
01218 @end
01219 */
01220 Value DOMNotation::tryGet(ExecState *exec, const UString &propertyName) const
01221 {
01222   return DOMObjectLookupGetValue<DOMNotation, DOMNode>(exec, propertyName, &DOMNotationTable, this);
01223 }
01224 
01225 Value DOMNotation::getValueProperty(ExecState *, int token) const
01226 {
01227   switch (token) {
01228   case PublicId:
01229     return getString(static_cast<DOM::Notation>(node).publicId());
01230   case SystemId:
01231     return getString(static_cast<DOM::Notation>(node).systemId());
01232   default:
01233     kdWarning() << "DOMNotation::getValueProperty unhandled token " << token << endl;
01234     return Value();
01235   }
01236 }
01237 
01238 // -------------------------------------------------------------------------
01239 
01240 const ClassInfo DOMEntity::info = { "Entity", &DOMNode::info, 0, 0 };
01241 
01242 /* Source for DOMEntityTable. Use "make hashtables" to regenerate.
01243 @begin DOMEntityTable 2
01244   publicId      DOMEntity::PublicId     DontDelete|ReadOnly
01245   systemId      DOMEntity::SystemId     DontDelete|ReadOnly
01246   notationName      DOMEntity::NotationName DontDelete|ReadOnly
01247 @end
01248 */
01249 Value DOMEntity::tryGet(ExecState *exec, const UString &propertyName) const
01250 {
01251   return DOMObjectLookupGetValue<DOMEntity, DOMNode>(exec, propertyName, &DOMEntityTable, this);
01252 }
01253 
01254 Value DOMEntity::getValueProperty(ExecState *, int token) const
01255 {
01256   switch (token) {
01257   case PublicId:
01258     return getString(static_cast<DOM::Entity>(node).publicId());
01259   case SystemId:
01260     return getString(static_cast<DOM::Entity>(node).systemId());
01261   case NotationName:
01262     return getString(static_cast<DOM::Entity>(node).notationName());
01263   default:
01264     kdWarning() << "DOMEntity::getValueProperty unhandled token " << token << endl;
01265     return Value();
01266   }
01267 }
01268 
01269 // -------------------------------------------------------------------------
01270 
01271 bool KJS::checkNodeSecurity(ExecState *exec, const DOM::Node& n)
01272 {
01273   // Check to see if the currently executing interpreter is allowed to access the specified node
01274   KHTMLView *view = n.handle()->getDocument()->view();
01275   Window* win = view && view->part() ? Window::retrieveWindow(view->part()) : 0L;
01276   if ( !win || !win->isSafeScript(exec) )
01277     return false;
01278   return true;
01279 }
01280 
01281 Value KJS::getDOMNode(ExecState *exec, const DOM::Node& n)
01282 {
01283   DOMObject *ret = 0;
01284   if (n.isNull())
01285     return Null();
01286   ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
01287   if ((ret = interp->getDOMObject(n.handle())))
01288     return Value(ret);
01289 
01290   switch (n.nodeType()) {
01291     case DOM::Node::ELEMENT_NODE:
01292       if (static_cast<DOM::Element>(n).isHTMLElement())
01293         ret = new HTMLElement(exec, static_cast<DOM::HTMLElement>(n));
01294       else
01295         ret = new DOMElement(exec, static_cast<DOM::Element>(n));
01296       break;
01297     case DOM::Node::ATTRIBUTE_NODE:
01298       ret = new DOMAttr(exec, static_cast<DOM::Attr>(n));
01299       break;
01300     case DOM::Node::TEXT_NODE:
01301     case DOM::Node::CDATA_SECTION_NODE:
01302       ret = new DOMText(exec, static_cast<DOM::Text>(n));
01303       break;
01304     case DOM::Node::ENTITY_REFERENCE_NODE:
01305       ret = new DOMNode(exec, n);
01306       break;
01307     case DOM::Node::ENTITY_NODE:
01308       ret = new DOMEntity(exec, static_cast<DOM::Entity>(n));
01309       break;
01310     case DOM::Node::PROCESSING_INSTRUCTION_NODE:
01311       ret = new DOMProcessingInstruction(exec, static_cast<DOM::ProcessingInstruction>(n));
01312       break;
01313     case DOM::Node::COMMENT_NODE:
01314       ret = new DOMCharacterData(exec, static_cast<DOM::CharacterData>(n));
01315       break;
01316     case DOM::Node::DOCUMENT_NODE:
01317       if (static_cast<DOM::Document>(n).isHTMLDocument())
01318         ret = new HTMLDocument(exec, static_cast<DOM::HTMLDocument>(n));
01319       else
01320         ret = new DOMDocument(exec, static_cast<DOM::Document>(n));
01321       break;
01322     case DOM::Node::DOCUMENT_TYPE_NODE:
01323       ret = new DOMDocumentType(exec, static_cast<DOM::DocumentType>(n));
01324       break;
01325     case DOM::Node::DOCUMENT_FRAGMENT_NODE:
01326       ret = new DOMNode(exec, n);
01327       break;
01328     case DOM::Node::NOTATION_NODE:
01329       ret = new DOMNotation(exec, static_cast<DOM::Notation>(n));
01330       break;
01331     default:
01332       ret = new DOMNode(exec, n);
01333   }
01334   interp->putDOMObject(n.handle(),ret);
01335 
01336   return Value(ret);
01337 }
01338 
01339 Value KJS::getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
01340 {
01341   return Value(cacheDOMObject<DOM::NamedNodeMap, KJS::DOMNamedNodeMap>(exec, m));
01342 }
01343 
01344 Value KJS::getDOMNodeList(ExecState *exec, const DOM::NodeList& l)
01345 {
01346   return Value(cacheDOMObject<DOM::NodeList, KJS::DOMNodeList>(exec, l));
01347 }
01348 
01349 Value KJS::getDOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
01350 {
01351   return Value(cacheDOMObject<DOM::DOMImplementation, KJS::DOMDOMImplementation>(exec, i));
01352 }
01353 
01354 // -------------------------------------------------------------------------
01355 
01356 const ClassInfo NodeConstructor::info = { "NodeConstructor", 0, &NodeConstructorTable, 0 };
01357 /* Source for NodeConstructorTable. Use "make hashtables" to regenerate.
01358 @begin NodeConstructorTable 11
01359   ELEMENT_NODE      DOM::Node::ELEMENT_NODE     DontDelete|ReadOnly
01360   ATTRIBUTE_NODE    DOM::Node::ATTRIBUTE_NODE       DontDelete|ReadOnly
01361   TEXT_NODE     DOM::Node::TEXT_NODE        DontDelete|ReadOnly
01362   CDATA_SECTION_NODE    DOM::Node::CDATA_SECTION_NODE   DontDelete|ReadOnly
01363   ENTITY_REFERENCE_NODE DOM::Node::ENTITY_REFERENCE_NODE    DontDelete|ReadOnly
01364   ENTITY_NODE       DOM::Node::ENTITY_NODE      DontDelete|ReadOnly
01365   PROCESSING_INSTRUCTION_NODE DOM::Node::PROCESSING_INSTRUCTION_NODE DontDelete|ReadOnly
01366   COMMENT_NODE      DOM::Node::COMMENT_NODE     DontDelete|ReadOnly
01367   DOCUMENT_NODE     DOM::Node::DOCUMENT_NODE        DontDelete|ReadOnly
01368   DOCUMENT_TYPE_NODE    DOM::Node::DOCUMENT_TYPE_NODE   DontDelete|ReadOnly
01369   DOCUMENT_FRAGMENT_NODE DOM::Node::DOCUMENT_FRAGMENT_NODE  DontDelete|ReadOnly
01370   NOTATION_NODE     DOM::Node::NOTATION_NODE        DontDelete|ReadOnly
01371 @end
01372 */
01373 
01374 NodeConstructor::NodeConstructor(ExecState *exec)
01375   : DOMObject(exec->interpreter()->builtinObjectPrototype())
01376 {
01377 }
01378 
01379 Value NodeConstructor::tryGet(ExecState *exec, const UString &propertyName) const
01380 {
01381   return DOMObjectLookupGetValue<NodeConstructor, DOMObject>(exec, propertyName, &NodeConstructorTable, this);
01382 }
01383 
01384 Value NodeConstructor::getValueProperty(ExecState *, int token) const
01385 {
01386   // We use the token as the value to return directly
01387   return Number((unsigned int)token);
01388 #if 0
01389   switch (token) {
01390   case ELEMENT_NODE:
01391     return Number((unsigned int)DOM::Node::ELEMENT_NODE);
01392   case ATTRIBUTE_NODE:
01393     return Number((unsigned int)DOM::Node::ATTRIBUTE_NODE);
01394   case TEXT_NODE:
01395     return Number((unsigned int)DOM::Node::TEXT_NODE);
01396   case CDATA_SECTION_NODE:
01397     return Number((unsigned int)DOM::Node::CDATA_SECTION_NODE);
01398   case ENTITY_REFERENCE_NODE:
01399     return Number((unsigned int)DOM::Node::ENTITY_REFERENCE_NODE);
01400   case ENTITY_NODE:
01401     return Number((unsigned int)DOM::Node::ENTITY_NODE);
01402   case PROCESSING_INSTRUCTION_NODE:
01403     return Number((unsigned int)DOM::Node::PROCESSING_INSTRUCTION_NODE);
01404   case COMMENT_NODE:
01405     return Number((unsigned int)DOM::Node::COMMENT_NODE);
01406   case DOCUMENT_NODE:
01407     return Number((unsigned int)DOM::Node::DOCUMENT_NODE);
01408   case DOCUMENT_TYPE_NODE:
01409     return Number((unsigned int)DOM::Node::DOCUMENT_TYPE_NODE);
01410   case DOCUMENT_FRAGMENT_NODE:
01411     return Number((unsigned int)DOM::Node::DOCUMENT_FRAGMENT_NODE);
01412   case NOTATION_NODE:
01413     return Number((unsigned int)DOM::Node::NOTATION_NODE);
01414   default:
01415     kdWarning() << "NodeConstructor::getValueProperty unhandled token " << token << endl;
01416     return Value();
01417   }
01418 #endif
01419 }
01420 
01421 Object KJS::getNodeConstructor(ExecState *exec)
01422 {
01423   return Object(cacheGlobalObject<NodeConstructor>(exec, "[[node.constructor]]"));
01424 }
01425 
01426 // -------------------------------------------------------------------------
01427 
01428 const ClassInfo DOMExceptionConstructor::info = { "DOMExceptionConstructor", 0, 0, 0 };
01429 
01430 /* Source for DOMExceptionConstructorTable. Use "make hashtables" to regenerate.
01431 @begin DOMExceptionConstructorTable 15
01432   INDEX_SIZE_ERR        DOM::DOMException::INDEX_SIZE_ERR       DontDelete|ReadOnly
01433   DOMSTRING_SIZE_ERR        DOM::DOMException::DOMSTRING_SIZE_ERR   DontDelete|ReadOnly
01434   HIERARCHY_REQUEST_ERR     DOM::DOMException::HIERARCHY_REQUEST_ERR    DontDelete|ReadOnly
01435   WRONG_DOCUMENT_ERR        DOM::DOMException::WRONG_DOCUMENT_ERR   DontDelete|ReadOnly
01436   INVALID_CHARACTER_ERR     DOM::DOMException::INVALID_CHARACTER_ERR    DontDelete|ReadOnly
01437   NO_DATA_ALLOWED_ERR       DOM::DOMException::NO_DATA_ALLOWED_ERR  DontDelete|ReadOnly
01438   NO_MODIFICATION_ALLOWED_ERR   DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR  DontDelete|ReadOnly
01439   NOT_FOUND_ERR         DOM::DOMException::NOT_FOUND_ERR        DontDelete|ReadOnly
01440   NOT_SUPPORTED_ERR     DOM::DOMException::NOT_SUPPORTED_ERR    DontDelete|ReadOnly
01441   INUSE_ATTRIBUTE_ERR       DOM::DOMException::INUSE_ATTRIBUTE_ERR  DontDelete|ReadOnly
01442   INVALID_STATE_ERR     DOM::DOMException::INVALID_STATE_ERR    DontDelete|ReadOnly
01443   SYNTAX_ERR            DOM::DOMException::SYNTAX_ERR       DontDelete|ReadOnly
01444   INVALID_MODIFICATION_ERR  DOM::DOMException::INVALID_MODIFICATION_ERR DontDelete|ReadOnly
01445   NAMESPACE_ERR         DOM::DOMException::NAMESPACE_ERR        DontDelete|ReadOnly
01446   INVALID_ACCESS_ERR        DOM::DOMException::INVALID_ACCESS_ERR   DontDelete|ReadOnly
01447 @end
01448 */
01449 
01450 DOMExceptionConstructor::DOMExceptionConstructor(ExecState* exec)
01451   : DOMObject(exec->interpreter()->builtinObjectPrototype())
01452 {
01453 }
01454 
01455 Value DOMExceptionConstructor::tryGet(ExecState *exec, const UString &propertyName) const
01456 {
01457   return DOMObjectLookupGetValue<DOMExceptionConstructor, DOMObject>(exec, propertyName, &DOMExceptionConstructorTable, this);
01458 }
01459 
01460 Value DOMExceptionConstructor::getValueProperty(ExecState *, int token) const
01461 {
01462   // We use the token as the value to return directly
01463   return Number((unsigned int)token);
01464 #if 0
01465   switch (token) {
01466   case INDEX_SIZE_ERR:
01467     return Number((unsigned int)DOM::DOMException::INDEX_SIZE_ERR);
01468   case DOMSTRING_SIZE_ERR:
01469     return Number((unsigned int)DOM::DOMException::DOMSTRING_SIZE_ERR);
01470   case HIERARCHY_REQUEST_ERR:
01471     return Number((unsigned int)DOM::DOMException::HIERARCHY_REQUEST_ERR);
01472   case WRONG_DOCUMENT_ERR:
01473     return Number((unsigned int)DOM::DOMException::WRONG_DOCUMENT_ERR);
01474   case INVALID_CHARACTER_ERR:
01475     return Number((unsigned int)DOM::DOMException::INVALID_CHARACTER_ERR);
01476   case NO_DATA_ALLOWED_ERR:
01477     return Number((unsigned int)DOM::DOMException::NO_DATA_ALLOWED_ERR);
01478   case NO_MODIFICATION_ALLOWED_ERR:
01479     return Number((unsigned int)DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR);
01480   case NOT_FOUND_ERR:
01481     return Number((unsigned int)DOM::DOMException::NOT_FOUND_ERR);
01482   case NOT_SUPPORTED_ERR:
01483     return Number((unsigned int)DOM::DOMException::NOT_SUPPORTED_ERR);
01484   case INUSE_ATTRIBUTE_ERR:
01485     return Number((unsigned int)DOM::DOMException::INUSE_ATTRIBUTE_ERR);
01486   case INVALID_STATE_ERR:
01487     return Number((unsigned int)DOM::DOMException::INVALID_STATE_ERR);
01488   case SYNTAX_ERR:
01489     return Number((unsigned int)DOM::DOMException::SYNTAX_ERR);
01490   case INVALID_MODIFICATION_ERR:
01491     return Number((unsigned int)DOM::DOMException::INVALID_MODIFICATION_ERR);
01492   case NAMESPACE_ERR:
01493     return Number((unsigned int)DOM::DOMException::NAMESPACE_ERR);
01494   case INVALID_ACCESS_ERR:
01495     return Number((unsigned int)DOM::DOMException::INVALID_ACCESS_ERR);
01496   default:
01497     kdWarning() << "DOMExceptionConstructor::getValueProperty unhandled token " << token << endl;
01498     return Value();
01499   }
01500 #endif
01501 }
01502 
01503 Object KJS::getDOMExceptionConstructor(ExecState *exec)
01504 {
01505   return cacheGlobalObject<DOMExceptionConstructor>(exec, "[[DOMException.constructor]]");
01506 }
01507 
01508 // -------------------------------------------------------------------------
01509 
01510 const ClassInfo KJS::DOMNamedNodesCollection::info = { "DOMNamedNodesCollection", 0, 0, 0 };
01511 
01512 // Such a collection is usually very short-lived, it only exists
01513 // for constructs like document.forms.<name>[1],
01514 // so it shouldn't be a problem that it's storing all the nodes (with the same name). (David)
01515 DOMNamedNodesCollection::DOMNamedNodesCollection(ExecState *exec, const QValueList<DOM::Node>& nodes )
01516   : DOMObject(exec->interpreter()->builtinObjectPrototype()),
01517   m_nodes(nodes)
01518 {
01519   // Maybe we should ref (and deref in the dtor) the nodes, though ?
01520 }
01521 
01522 Value DOMNamedNodesCollection::tryGet(ExecState *exec, const UString &propertyName) const
01523 {
01524   kdDebug(6070) << k_funcinfo << propertyName.ascii() << endl;
01525   if (propertyName == "length")
01526     return Number(m_nodes.count());
01527   // index?
01528   bool ok;
01529   unsigned int u = propertyName.toULong(&ok);
01530   if (ok && u < m_nodes.count()) {
01531     DOM::Node node = m_nodes[u];
01532     return getDOMNode(exec,node);
01533   }
01534   return DOMObject::tryGet(exec,propertyName);
01535 }
01536 
01537 // -------------------------------------------------------------------------
01538 
01539 const ClassInfo DOMCharacterData::info = { "CharacterImp",
01540                       &DOMNode::info, &DOMCharacterDataTable, 0 };
01541 /*
01542 @begin DOMCharacterDataTable 2
01543   data      DOMCharacterData::Data      DontDelete
01544   length    DOMCharacterData::Length    DontDelete|ReadOnly
01545 @end
01546 @begin DOMCharacterDataProtoTable 7
01547   substringData DOMCharacterData::SubstringData DontDelete|Function 2
01548   appendData    DOMCharacterData::AppendData    DontDelete|Function 1
01549   insertData    DOMCharacterData::InsertData    DontDelete|Function 2
01550   deleteData    DOMCharacterData::DeleteData    DontDelete|Function 2
01551   replaceData   DOMCharacterData::ReplaceData   DontDelete|Function 2
01552 @end
01553 */
01554 DEFINE_PROTOTYPE("DOMCharacterData",DOMCharacterDataProto)
01555 IMPLEMENT_PROTOFUNC_DOM(DOMCharacterDataProtoFunc)
01556 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMCharacterDataProto,DOMCharacterDataProtoFunc, DOMNodeProto)
01557 
01558 DOMCharacterData::DOMCharacterData(ExecState *exec, const DOM::CharacterData& d)
01559  : DOMNode(DOMCharacterDataProto::self(exec), d) {}
01560 
01561 DOMCharacterData::DOMCharacterData(const Object& proto, const DOM::CharacterData& d)
01562  : DOMNode(proto, d) {}
01563 
01564 Value DOMCharacterData::tryGet(ExecState *exec, const UString &p) const
01565 {
01566 #ifdef KJS_VERBOSE
01567   kdDebug(6070)<<"DOMCharacterData::tryGet "<<p.string().string()<<endl;
01568 #endif
01569   return DOMObjectLookupGetValue<DOMCharacterData,DOMNode>(exec,p,&DOMCharacterDataTable,this);
01570 }
01571 
01572 Value DOMCharacterData::getValueProperty(ExecState *, int token) const
01573 {
01574   DOM::CharacterData data = static_cast<DOM::CharacterData>(node);
01575   switch (token) {
01576   case Data:
01577     return String(data.data());
01578   case Length:
01579     return Number(data.length());
01580  default:
01581    kdWarning() << "Unhandled token in DOMCharacterData::getValueProperty : " << token << endl;
01582    return Value();
01583   }
01584 }
01585 
01586 void DOMCharacterData::tryPut(ExecState *exec, const UString &propertyName, const Value& value, int attr)
01587 {
01588   if (propertyName == "data")
01589     static_cast<DOM::CharacterData>(node).setData(value.toString(exec).string());
01590   else
01591     DOMNode::tryPut(exec, propertyName,value,attr);
01592 }
01593 
01594 Value DOMCharacterDataProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01595 {
01596   KJS_CHECK_THIS( KJS::DOMCharacterData, thisObj );
01597   DOM::CharacterData data = static_cast<DOMCharacterData *>(thisObj.imp())->toData();
01598   switch(id) {
01599     case DOMCharacterData::SubstringData:
01600       return getString(data.substringData(args[0].toInteger(exec),args[1].toInteger(exec)));
01601     case DOMCharacterData::AppendData:
01602       data.appendData(args[0].toString(exec).string());
01603       return Undefined();
01604       break;
01605     case DOMCharacterData::InsertData:
01606       data.insertData(args[0].toInteger(exec),args[1].toString(exec).string());
01607       return  Undefined();
01608       break;
01609     case DOMCharacterData::DeleteData:
01610       data.deleteData(args[0].toInteger(exec),args[1].toInteger(exec));
01611       return  Undefined();
01612       break;
01613     case DOMCharacterData::ReplaceData:
01614       data.replaceData(args[0].toInteger(exec),args[1].toInteger(exec),args[2].toString(exec).string());
01615       return Undefined();
01616       break;
01617     default:
01618       return Undefined();
01619   }
01620 }
01621 
01622 // -------------------------------------------------------------------------
01623 
01624 const ClassInfo DOMText::info = { "Text",
01625                  &DOMCharacterData::info, 0, 0 };
01626 /*
01627 @begin DOMTextProtoTable 1
01628   splitText DOMText::SplitText  DontDelete|Function 1
01629 @end
01630 */
01631 DEFINE_PROTOTYPE("DOMText",DOMTextProto)
01632 IMPLEMENT_PROTOFUNC_DOM(DOMTextProtoFunc)
01633 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMTextProto,DOMTextProtoFunc,DOMCharacterDataProto)
01634 
01635 DOMText::DOMText(ExecState *exec, const DOM::Text& t)
01636   : DOMCharacterData(DOMTextProto::self(exec), t) { }
01637 
01638 Value DOMText::tryGet(ExecState *exec, const UString &p) const
01639 {
01640   if (p == "")
01641     return Undefined(); // ### TODO
01642   else
01643     return DOMCharacterData::tryGet(exec, p);
01644 }
01645 
01646 Value DOMTextProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01647 {
01648   KJS_CHECK_THIS( KJS::DOMText, thisObj );
01649   DOM::Text text = static_cast<DOMText *>(thisObj.imp())->toText();
01650   switch(id) {
01651     case DOMText::SplitText:
01652       return getDOMNode(exec,text.splitText(args[0].toInteger(exec)));
01653       break;
01654     default:
01655       return Undefined();
01656   }
01657 }
01658 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:22:40 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001