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