void CharacterDataImpl::setData( const DOMString &_data, int &exceptioncode ) { // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly if (isReadOnly()) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return; } if(str == _data.impl) return; // ### fire DOMCharacterDataModified if modified? DOMStringImpl *oldStr = str; str = _data.impl; if(str) str->ref(); if (m_render) (static_cast<RenderText*>(m_render))->setText(str); setChanged(true); dispatchModifiedEvent(oldStr); if(oldStr) oldStr->deref(); }
void CharacterDataImpl::deleteData( const unsigned long offset, const unsigned long count, int &exceptioncode ) { exceptioncode = 0; if ((long)count < 0) exceptioncode = DOMException::INDEX_SIZE_ERR; else checkCharDataOperation(offset, exceptioncode); if (exceptioncode) return; DOMStringImpl *oldStr = str; str = str->copy(); str->ref(); str->remove(offset,count); if (m_render) (static_cast<RenderText*>(m_render))->setText(str); setChanged(true); dispatchModifiedEvent(oldStr); oldStr->deref(); }
void CharacterDataImpl::appendData( const DOMString &arg, int &exceptioncode ) { exceptioncode = 0; // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly if (isReadOnly()) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return; } DOMStringImpl *oldStr = str; str = str->copy(); str->ref(); str->append(arg.impl); if (m_render) (static_cast<RenderText*>(m_render))->setText(str); setChanged(true); dispatchModifiedEvent(oldStr); oldStr->deref(); }
TextImpl *TextImpl::splitText( const unsigned long offset, int &exceptioncode ) { exceptioncode = 0; // INDEX_SIZE_ERR: Raised if the specified offset is negative or greater than // the number of 16-bit units in data. // ### we explicitly check for a negative long that has been cast to an unsigned long // ... this can happen if JS code passes in -1 - we need to catch this earlier! (in the // kjs bindings) if (offset > str->l || (long)offset < 0) { exceptioncode = DOMException::INDEX_SIZE_ERR; return 0; } // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. if (isReadOnly()) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return 0; } DOMStringImpl *oldStr = str; TextImpl *newText = createNew(str->substring(offset,str->l-offset)); str = str->copy(); str->ref(); str->remove(offset,str->l-offset); dispatchModifiedEvent(oldStr); oldStr->deref(); if (parentNode()) parentNode()->insertBefore(newText,nextSibling(), exceptioncode ); if ( exceptioncode ) return 0; if (m_render) (static_cast<RenderText*>(m_render))->setText(str); setChanged(true); return newText; }
void RenderStyle::addContent(DOM::DOMStringImpl *s) { if(!s) return; // The string is null. Nothing to do. Just bail. StyleGeneratedData *t_generated = generated.access(); ContentData *lastContent = t_generated->content; while(lastContent && lastContent->_nextContent) lastContent = lastContent->_nextContent; if(lastContent) { if(lastContent->_contentType == CONTENT_TEXT) { // We can augment the existing string and share this ContentData node. DOMStringImpl *oldStr = lastContent->_content.text; DOMStringImpl *newStr = oldStr->copy(); newStr->ref(); oldStr->deref(); newStr->append(s); lastContent->_content.text = newStr; return; } } ContentData *newContentData = new ContentData; if(lastContent) lastContent->_nextContent = newContentData; else t_generated->content = newContentData; newContentData->_content.text = s; newContentData->_content.text->ref(); newContentData->_contentType = CONTENT_TEXT; }
void CharacterDataImpl::dispatchModifiedEvent(DOMStringImpl *prevValue) { if (parentNode()) parentNode()->childrenChanged(); if ((str->length() == 0) != (prevValue->length() == 0)) { // changes in emptiness triggers changes in :empty selector if (parentNode() && parentNode()->isElementNode()) parentNode()->backwardsStructureChanged(); // ### to fully support dynamic changes to :contains selector // backwardsStructureChanged should be called for all changes } if (!document()->hasListenerType(DocumentImpl::DOMCHARACTERDATAMODIFIED_LISTENER)) return; DOMStringImpl *newValue = str->copy(); newValue->ref(); int exceptioncode = 0; MutationEventImpl* const evt = new MutationEventImpl(EventImpl::DOMCHARACTERDATAMODIFIED_EVENT,true,false,0,prevValue,newValue,DOMString(),0); evt->ref(); dispatchEvent(evt,exceptioncode); evt->deref(); newValue->deref(); dispatchSubtreeModifiedEvent(); }
void RenderText::setText(DOMStringImpl *text, bool force) { if( !force && str == text ) return; DOMStringImpl *oldstr = str; if(text && style()) str = text->collapseWhiteSpace(style()->preserveLF(), style()->preserveWS()); else str = text; if(str) str->ref(); if(oldstr) oldstr->deref(); if ( str && style() ) { oldstr = str; switch(style()->textTransform()) { case CAPITALIZE: { RenderObject *o; bool runOnString = false; // find previous non-empty text renderer if one exists for (o = previousRenderer(); o; o = o->previousRenderer()) { if (!o->isInlineFlow()) { if (!o->isText()) break; DOMStringImpl *prevStr = static_cast<RenderText*>(o)->string(); // !prevStr can happen with css like "content:open-quote;" if (!prevStr) break; if (prevStr->length() == 0) continue; QChar c = (*prevStr)[prevStr->length() - 1]; if (!c.isSpace()) runOnString = true; break; } } str = str->capitalize(runOnString); } break; case UPPERCASE: str = str->upper(); break; case LOWERCASE: str = str->lower(); break; case NONE: default:; } str->ref(); oldstr->deref(); } // ### what should happen if we change the text of a // RenderBR object ? KHTMLAssert(!isBR() || (str->l == 1 && (*str->s) == '\n')); KHTMLAssert(!str->l || str->s); setNeedsLayoutAndMinMaxRecalc(); #ifdef BIDI_DEBUG QConstString cstr(str->s, str->l); kdDebug( 6040 ) << "RenderText::setText( " << cstr.string().length() << " ) '" << cstr.string() << "'" << endl; #endif }
unsigned short IDTableBase::grabId(DOMStringImpl* origName, CaseNormalizeMode cnm) { unsigned short newId; // Check for existing one, ignoring case if needed IDTableBase::MappingKey::caseNormalizationMode = cnm; QHash<MappingKey, unsigned short>::const_iterator i = m_mappingLookup.constFind(origName); if (i != m_mappingLookup.constEnd()) { newId = *i; refId(newId); return newId; } // Nope. Allocate new ID. If there is normalization going on, we may now have to // update our case so the canonical mapping is of the expected case. We // may also have to deep-copy DOMStringImpl* name; switch (cnm) { case IDS_CaseSensitive: if (origName->m_shallowCopy) { // Create a new copy of the data since we may be extending its // lifetime indefinitely name = new DOMStringImpl(origName->s, origName->l); name->m_hash = origName->m_hash; } else { name = origName; } break; case IDS_NormalizeUpper: name = origName->upper(); break; case IDS_NormalizeLower: name = origName->lower(); break; } name->ref(); if (!m_idFreeList.isEmpty()) { // Grab from freelist.. newId = m_idFreeList.last(); m_idFreeList.removeLast(); m_mappings[newId].name = name; } else { // Make a new one --- if we can (we keep one spot for "last resort" mapping) if (m_mappings.size() < 0xFFFE) { m_mappings.append(Mapping(name)); newId = m_mappings.size() - 1; } else { // We ran out of resources. Did we add a fallback mapping yet? // We use the same one for everything; and don't even keep track // of what it may go to, as we will have no way of freeing // the aliases. In particular, this means we no longer need the name.. name->deref(); if (m_mappings.size() == 0xFFFE) { // Need a new mapping.. name = new DOMStringImpl("_khtml_fallback"); m_mappings.append(Mapping(name)); m_mappings[0xFFFF].refCount = 1; // pin it. name->ref(); } else { name = m_mappings[0xFFFF].name; // No need to ref the name // here as the entry is eternal anyway } newId = 0xFFFF; } } m_mappingLookup[name] = newId; refId(newId); return newId; }