khtml Library API Documentation

dom_textimpl.cpp

00001 
00023 #include "dom/dom_exception.h"
00024 #include "css/cssstyleselector.h"
00025 #include "xml/dom2_eventsimpl.h"
00026 #include "xml/dom_textimpl.h"
00027 #include "xml/dom_docimpl.h"
00028 
00029 #include "misc/htmlhashes.h"
00030 #include "rendering/render_text.h"
00031 
00032 #include <kdebug.h>
00033 
00034 using namespace DOM;
00035 using namespace khtml;
00036 
00037 
00038 CharacterDataImpl::CharacterDataImpl(DocumentPtr *doc, DOMStringImpl* _text)
00039     : NodeImpl(doc)
00040 {
00041     str = _text ? _text : new DOMStringImpl( 0, 0 );
00042     str->ref();
00043 }
00044 
00045 CharacterDataImpl::~CharacterDataImpl()
00046 {
00047     if(str) str->deref();
00048 }
00049 
00050 void CharacterDataImpl::setData( const DOMString &_data, int &exceptioncode )
00051 {
00052     // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly
00053     if (isReadOnly()) {
00054         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
00055         return;
00056     }
00057 
00058     if(str == _data.impl) return; // ### fire DOMCharacterDataModified if modified?
00059     DOMStringImpl *oldStr = str;
00060     str = _data.impl;
00061     if(str) str->ref();
00062     if (m_render)
00063       (static_cast<RenderText*>(m_render))->setText(str);
00064     setChanged(true);
00065 
00066     dispatchModifiedEvent(oldStr);
00067     if(oldStr) oldStr->deref();
00068 }
00069 
00070 unsigned long CharacterDataImpl::length() const
00071 {
00072     return str->l;
00073 }
00074 
00075 DOMString CharacterDataImpl::substringData( const unsigned long offset, const unsigned long count, int &exceptioncode )
00076 {
00077     exceptioncode = 0;
00078     if ((long)count < 0)
00079         exceptioncode = DOMException::INDEX_SIZE_ERR;
00080     else
00081         checkCharDataOperation(offset, exceptioncode);
00082     if (exceptioncode)
00083         return DOMString();
00084 
00085     return str->substring(offset,count);
00086 }
00087 
00088 void CharacterDataImpl::appendData( const DOMString &arg, int &exceptioncode )
00089 {
00090     exceptioncode = 0;
00091 
00092     // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly
00093     if (isReadOnly()) {
00094         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
00095         return;
00096     }
00097 
00098     DOMStringImpl *oldStr = str;
00099     str = str->copy();
00100     str->ref();
00101     str->append(arg.impl);
00102     if (m_render)
00103       (static_cast<RenderText*>(m_render))->setText(str);
00104     setChanged(true);
00105 
00106     dispatchModifiedEvent(oldStr);
00107     oldStr->deref();
00108 }
00109 
00110 void CharacterDataImpl::insertData( const unsigned long offset, const DOMString &arg, int &exceptioncode )
00111 {
00112     exceptioncode = 0;
00113     checkCharDataOperation(offset, exceptioncode);
00114     if (exceptioncode)
00115         return;
00116 
00117     DOMStringImpl *oldStr = str;
00118     str = str->copy();
00119     str->ref();
00120     str->insert(arg.impl, offset);
00121     if (m_render)
00122       (static_cast<RenderText*>(m_render))->setText(str);
00123     setChanged(true);
00124 
00125     dispatchModifiedEvent(oldStr);
00126     oldStr->deref();
00127 }
00128 
00129 void CharacterDataImpl::deleteData( const unsigned long offset, const unsigned long count, int &exceptioncode )
00130 {
00131     exceptioncode = 0;
00132     if ((long)count < 0)
00133         exceptioncode = DOMException::INDEX_SIZE_ERR;
00134     else
00135         checkCharDataOperation(offset, exceptioncode);
00136     if (exceptioncode)
00137         return;
00138 
00139     DOMStringImpl *oldStr = str;
00140     str = str->copy();
00141     str->ref();
00142     str->remove(offset,count);
00143     if (m_render)
00144       (static_cast<RenderText*>(m_render))->setText(str);
00145     setChanged(true);
00146 
00147     dispatchModifiedEvent(oldStr);
00148     oldStr->deref();
00149 }
00150 
00151 void CharacterDataImpl::replaceData( const unsigned long offset, const unsigned long count, const DOMString &arg, int &exceptioncode )
00152 {
00153     exceptioncode = 0;
00154     if ((long)count < 0)
00155         exceptioncode = DOMException::INDEX_SIZE_ERR;
00156     else
00157         checkCharDataOperation(offset, exceptioncode);
00158     if (exceptioncode)
00159         return;
00160 
00161     unsigned long realCount;
00162     if (offset + count > str->l)
00163         realCount = str->l-offset;
00164     else
00165         realCount = count;
00166 
00167     DOMStringImpl *oldStr = str;
00168     str = str->copy();
00169     str->ref();
00170     str->remove(offset,realCount);
00171     str->insert(arg.impl, offset);
00172     if (m_render)
00173       (static_cast<RenderText*>(m_render))->setText(str);
00174     setChanged(true);
00175 
00176     dispatchModifiedEvent(oldStr);
00177     oldStr->deref();
00178 }
00179 
00180 DOMString CharacterDataImpl::nodeValue() const
00181 {
00182     return str;
00183 }
00184 
00185 void CharacterDataImpl::setNodeValue( const DOMString &_nodeValue, int &exceptioncode )
00186 {
00187     // NO_MODIFICATION_ALLOWED_ERR: taken care of by setData()
00188     setData(_nodeValue, exceptioncode);
00189 }
00190 
00191 void CharacterDataImpl::dispatchModifiedEvent(DOMStringImpl *prevValue)
00192 {
00193     if (parentNode())
00194         parentNode()->childrenChanged();
00195     if (!getDocument()->hasListenerType(DocumentImpl::DOMCHARACTERDATAMODIFIED_LISTENER))
00196         return;
00197 
00198     DOMStringImpl *newValue = str->copy();
00199     newValue->ref();
00200     int exceptioncode = 0;
00201     dispatchEvent(new MutationEventImpl(EventImpl::DOMCHARACTERDATAMODIFIED_EVENT,
00202                   true,false,0,prevValue,newValue,DOMString(),0),exceptioncode);
00203     newValue->deref();
00204     dispatchSubtreeModifiedEvent();
00205 }
00206 
00207 void CharacterDataImpl::checkCharDataOperation( const unsigned long offset, int &exceptioncode )
00208 {
00209     exceptioncode = 0;
00210 
00211     // INDEX_SIZE_ERR: Raised if the specified offset is negative or greater than the number of 16-bit
00212     // units in data.
00213     if (offset > str->l) {
00214         exceptioncode = DOMException::INDEX_SIZE_ERR;
00215         return;
00216     }
00217 
00218     // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly
00219     if (isReadOnly()) {
00220         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
00221         return;
00222     }
00223 }
00224 
00225 #ifndef NDEBUG
00226 void CharacterDataImpl::dump(QTextStream *stream, QString ind) const
00227 {
00228     *stream << " str=\"" << DOMString(str).string().ascii() << "\"";
00229 
00230     NodeImpl::dump(stream,ind);
00231 }
00232 #endif
00233 
00234 // ---------------------------------------------------------------------------
00235 
00236 DOMString CommentImpl::nodeName() const
00237 {
00238     return "#comment";
00239 }
00240 
00241 unsigned short CommentImpl::nodeType() const
00242 {
00243     return Node::COMMENT_NODE;
00244 }
00245 
00246 NodeImpl *CommentImpl::cloneNode(bool /*deep*/)
00247 {
00248     return getDocument()->createComment( str );
00249 }
00250 
00251 NodeImpl::Id CommentImpl::id() const
00252 {
00253     return ID_COMMENT;
00254 }
00255 
00256 // DOM Section 1.1.1
00257 bool CommentImpl::childTypeAllowed( unsigned short /*type*/ )
00258 {
00259     return false;
00260 }
00261 
00262 // ---------------------------------------------------------------------------
00263 
00264 TextImpl *TextImpl::splitText( const unsigned long offset, int &exceptioncode )
00265 {
00266     exceptioncode = 0;
00267 
00268     // INDEX_SIZE_ERR: Raised if the specified offset is negative or greater than
00269     // the number of 16-bit units in data.
00270 
00271     // ### we explicitly check for a negative long that has been cast to an unsigned long
00272     // ... this can happen if JS code passes in -1 - we need to catch this earlier! (in the
00273     // kjs bindings)
00274     if (offset > str->l || (long)offset < 0) {
00275         exceptioncode = DOMException::INDEX_SIZE_ERR;
00276         return 0;
00277     }
00278 
00279     // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
00280     if (isReadOnly()) {
00281         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
00282         return 0;
00283     }
00284 
00285     DOMStringImpl *oldStr = str;
00286     TextImpl *newText = createNew(str->substring(offset,str->l-offset));
00287     str = str->copy();
00288     str->ref();
00289     str->remove(offset,str->l-offset);
00290 
00291     dispatchModifiedEvent(oldStr);
00292     oldStr->deref();
00293 
00294     if (parentNode())
00295         parentNode()->insertBefore(newText,nextSibling(), exceptioncode );
00296     if ( exceptioncode )
00297         return 0;
00298 
00299     if (m_render)
00300         (static_cast<RenderText*>(m_render))->setText(str);
00301     setChanged(true);
00302     return newText;
00303 }
00304 
00305 DOMString TextImpl::nodeName() const
00306 {
00307   return "#text";
00308 }
00309 
00310 unsigned short TextImpl::nodeType() const
00311 {
00312     return Node::TEXT_NODE;
00313 }
00314 
00315 NodeImpl *TextImpl::cloneNode(bool /*deep*/)
00316 {
00317     return getDocument()->createTextNode(str);
00318 }
00319 
00320 void TextImpl::attach()
00321 {
00322     assert(!m_render);
00323     assert(!attached());
00324     assert(parentNode() && parentNode()->isElementNode());
00325 
00326     ElementImpl* element = static_cast<ElementImpl*>(parentNode());
00327     if (!m_render && element->renderer()) {
00328         khtml::RenderStyle* _style = element->renderer()->style();
00329         m_render = new RenderText(this, str);
00330         m_render->setStyle(_style);
00331         parentNode()->renderer()->addChild(m_render, nextRenderer());
00332     }
00333 
00334     CharacterDataImpl::attach();
00335 }
00336 
00337 NodeImpl::Id TextImpl::id() const
00338 {
00339     return ID_TEXT;
00340 }
00341 
00342 void TextImpl::recalcStyle( StyleChange change )
00343 {
00344 //      qDebug("textImpl::recalcStyle");
00345     if (change != NoChange && parentNode()) {
00346 //      qDebug("DomText::recalcStyle");
00347         if(m_render)
00348             m_render->setStyle(parentNode()->renderer()->style());
00349     }
00350     if ( changed() && m_render && m_render->isText() )
00351         static_cast<RenderText*>(m_render)->setText(str);
00352     setChanged( false );
00353 }
00354 
00355 // DOM Section 1.1.1
00356 bool TextImpl::childTypeAllowed( unsigned short /*type*/ )
00357 {
00358     return false;
00359 }
00360 
00361 TextImpl *TextImpl::createNew(DOMStringImpl *_str)
00362 {
00363     return new TextImpl(docPtr(),_str);
00364 }
00365 
00366 // ---------------------------------------------------------------------------
00367 
00368 DOMString CDATASectionImpl::nodeName() const
00369 {
00370   return "#cdata-section";
00371 }
00372 
00373 unsigned short CDATASectionImpl::nodeType() const
00374 {
00375     return Node::CDATA_SECTION_NODE;
00376 }
00377 
00378 NodeImpl *CDATASectionImpl::cloneNode(bool /*deep*/)
00379 {
00380     return getDocument()->createCDATASection(str);
00381 }
00382 
00383 // DOM Section 1.1.1
00384 bool CDATASectionImpl::childTypeAllowed( unsigned short /*type*/ )
00385 {
00386     return false;
00387 }
00388 
00389 TextImpl *CDATASectionImpl::createNew(DOMStringImpl *_str)
00390 {
00391     return new CDATASectionImpl(docPtr(),_str);
00392 }
00393 
00394 
00395 
00396 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:33:48 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001