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 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
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
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
00212
00213 if (offset > str->l) {
00214 exceptioncode = DOMException::INDEX_SIZE_ERR;
00215 return;
00216 }
00217
00218
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 )
00247 {
00248 return getDocument()->createComment( str );
00249 }
00250
00251 NodeImpl::Id CommentImpl::id() const
00252 {
00253 return ID_COMMENT;
00254 }
00255
00256
00257 bool CommentImpl::childTypeAllowed( unsigned short )
00258 {
00259 return false;
00260 }
00261
00262
00263
00264 TextImpl *TextImpl::splitText( const unsigned long offset, int &exceptioncode )
00265 {
00266 exceptioncode = 0;
00267
00268
00269
00270
00271
00272
00273
00274 if (offset > str->l || (long)offset < 0) {
00275 exceptioncode = DOMException::INDEX_SIZE_ERR;
00276 return 0;
00277 }
00278
00279
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 )
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
00345 if (change != NoChange && parentNode()) {
00346
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
00356 bool TextImpl::childTypeAllowed( unsigned short )
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 )
00379 {
00380 return getDocument()->createCDATASection(str);
00381 }
00382
00383
00384 bool CDATASectionImpl::childTypeAllowed( unsigned short )
00385 {
00386 return false;
00387 }
00388
00389 TextImpl *CDATASectionImpl::createNew(DOMStringImpl *_str)
00390 {
00391 return new CDATASectionImpl(docPtr(),_str);
00392 }
00393
00394
00395
00396
This file is part of the documentation for kdelibs Version 3.1.5.