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