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
00053 if (isReadOnly()) {
00054 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
00055 return;
00056 }
00057
00058 if(str == _data.impl) return;
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
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
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
00203
00204 if (offset > str->l) {
00205 exceptioncode = DOMException::INDEX_SIZE_ERR;
00206 return;
00207 }
00208
00209
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 )
00238 {
00239 return getDocument()->createComment( str );
00240 }
00241
00242 NodeImpl::Id CommentImpl::id() const
00243 {
00244 return ID_COMMENT;
00245 }
00246
00247
00248 bool CommentImpl::childTypeAllowed( unsigned short )
00249 {
00250 return false;
00251 }
00252
00253
00254
00255 TextImpl *TextImpl::splitText( const unsigned long offset, int &exceptioncode )
00256 {
00257 exceptioncode = 0;
00258
00259
00260
00261
00262
00263
00264
00265 if (offset > str->l || (long)offset < 0) {
00266 exceptioncode = DOMException::INDEX_SIZE_ERR;
00267 return 0;
00268 }
00269
00270
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 )
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
00336 if (change != NoChange && parentNode()) {
00337
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
00347 bool TextImpl::childTypeAllowed( unsigned short )
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 )
00370 {
00371 return getDocument()->createCDATASection(str);
00372 }
00373
00374
00375 bool CDATASectionImpl::childTypeAllowed( unsigned short )
00376 {
00377 return false;
00378 }
00379
00380 TextImpl *CDATASectionImpl::createNew(DOMStringImpl *_str)
00381 {
00382 return new CDATASectionImpl(docPtr(),_str);
00383 }
00384
00385
00386
00387
This file is part of the documentation for kdelibs Version 3.1.0.