void CharacterDataImpl::replaceData( const unsigned long offset, const unsigned long count, const DOMString &arg, int &exceptioncode ) { exceptioncode = 0; if ((long)count < 0) exceptioncode = DOMException::INDEX_SIZE_ERR; else checkCharDataOperation(offset, exceptioncode); if (exceptioncode) return; unsigned long realCount; if (offset + count > str->l) realCount = str->l-offset; else realCount = count; DOMStringImpl *oldStr = str; str = str->copy(); str->ref(); str->remove(offset,realCount); str->insert(arg.impl, offset); if (m_render) (static_cast<RenderText*>(m_render))->setText(str); setChanged(true); dispatchModifiedEvent(oldStr); oldStr->deref(); }
XMLElementImpl::XMLElementImpl(DocumentPtr *doc, DOMStringImpl *_qualifiedName, DOMStringImpl *_namespaceURI) : ElementImpl(doc) { int colonpos = -1; for (uint i = 0; i < _qualifiedName->l; ++i) if (_qualifiedName->s[i] == ':') { colonpos = i; break; } if (colonpos >= 0) { // we have a prefix DOMStringImpl* localName = _qualifiedName->copy(); localName->ref(); localName->remove(0,colonpos+1); m_id = doc->document()->tagId(_namespaceURI, localName, false /* allocate */); localName->deref(); m_prefix = _qualifiedName->copy(); m_prefix->ref(); m_prefix->truncate(colonpos); } else { // no prefix m_id = doc->document()->tagId(_namespaceURI, _qualifiedName, false /* allocate */); m_prefix = 0; } }
void CharacterDataImpl::detachString() { // make a copy of our string so as not to interfere with other texts that use it DOMStringImpl *newStr = str->copy(); newStr->ref(); str->deref(); str = newStr; }
void IDTableBase::addHiddenMapping(unsigned id, const DOMString& name) { DOMStringImpl* nameImpl = name.implementation(); if (nameImpl) nameImpl->ref(); if (id >= m_mappings.size()) m_mappings.resize(id + 1); m_mappings[id] = Mapping(nameImpl); m_mappings[id].refCount = 1; // Pin it. }
void HTMLFontElementImpl::parseAttribute(AttributeImpl *attr) { switch(attr->id()) { case ATTR_SIZE: { DOMStringImpl* v = attr->val(); if(v) { const QChar* s = v->s; int num = v->toInt(); int len = v->l; while( len && s->isSpace() ) len--,s++; if ( len && *s == '+' ) num += 3; int size; switch (num) { case -2: case 1: size = CSS_VAL_XX_SMALL; break; case -1: case 2: size = CSS_VAL_SMALL; break; case 0: // treat 0 the same as 3, because people // expect it to be between -1 and +1 case 3: size = CSS_VAL_MEDIUM; break; case 4: size = CSS_VAL_LARGE; break; case 5: size = CSS_VAL_X_LARGE; break; case 6: size = CSS_VAL_XX_LARGE; break; default: if (num > 6) size = CSS_VAL__KHTML_XXX_LARGE; else size = CSS_VAL_XX_SMALL; } addCSSProperty(CSS_PROP_FONT_SIZE, size); } break; } case ATTR_COLOR: addHTMLColor(CSS_PROP_COLOR, attr->value()); break; case ATTR_FACE: addCSSProperty(CSS_PROP_FONT_FAMILY, attr->value()); break; default: HTMLElementImpl::parseAttribute(attr); } }
void CharacterDataImpl::dispatchModifiedEvent(DOMStringImpl *prevValue) { if (parentNode()) parentNode()->childrenChanged(); if (!getDocument()->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 CharacterDataImpl::insertData( const unsigned long offset, const DOMString &arg, int &exceptioncode ) { exceptioncode = 0; checkCharDataOperation(offset, exceptioncode); if (exceptioncode) return; DOMStringImpl *oldStr = str; str = str->copy(); str->ref(); str->insert(arg.impl, offset); if (m_render) (static_cast<RenderText*>(m_render))->setText(str); setChanged(true); dispatchModifiedEvent(oldStr); oldStr->deref(); }
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::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(); }
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(); }
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; }
// ### make sure we undo what we did during detach void HTMLHRElementImpl::attach() { if (attributes(true /* readonly */)) { // there are some attributes, lets check DOMString color = getAttribute(ATTR_COLOR); DOMStringImpl* si = getAttribute(ATTR_SIZE).implementation(); int _s = si ? si->toInt() : -1; DOMString n("1"); if (!color.isNull()) { addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID); addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID); addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID); addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID); addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString("0")); addCSSLength(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString(si)); addHTMLColor(CSS_PROP_BORDER_COLOR, color); } else { if (_s > 1 && getAttribute(ATTR_NOSHADE).isNull()) { addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, n); addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, n); addCSSProperty(CSS_PROP_BORDER_LEFT_WIDTH, n); addCSSProperty(CSS_PROP_BORDER_RIGHT_WIDTH, n); addCSSLength(CSS_PROP_HEIGHT, DOMString(QString::number(_s-2))); } else if (_s >= 0) { addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString(QString::number(_s))); addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString("0")); } } if (_s == 0) addCSSProperty(CSS_PROP_MARGIN_BOTTOM, n); } HTMLElementImpl::attach(); }
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 ProspectiveTokenizer::processAttribute() { DOMStringImpl tagNameDS(DOMStringImpl::ShallowCopy, m_tagName.data(), m_tagName.size()); LocalName tagLocal = LocalName::fromString(&tagNameDS, IDS_NormalizeLower); uint tag = tagLocal.id(); switch (tag) { case ID_SCRIPT: case ID_IMAGE: case ID_IMG: { DOMStringImpl attrDS(DOMStringImpl::ShallowCopy, m_attributeName.data(), m_attributeName.size()); LocalName attrLocal = LocalName::fromString(&attrDS, IDS_NormalizeLower); uint attribute = attrLocal.id(); if (attribute == localNamePart(ATTR_SRC) && m_urlToLoad.isEmpty()) m_urlToLoad = parseURL(DOMString(m_attributeValue.data(), m_attributeValue.size())); break; } case ID_LINK: { DOMStringImpl attrDS(DOMStringImpl::ShallowCopy, m_attributeName.data(), m_attributeName.size()); LocalName attrLocal = LocalName::fromString(&attrDS, IDS_NormalizeLower); uint attribute = attrLocal.id(); if (attribute == localNamePart(ATTR_HREF) && m_urlToLoad.isEmpty()) m_urlToLoad = parseURL(DOMString(m_attributeValue.data(), m_attributeValue.size())); else if (attribute == localNamePart(ATTR_REL)) { DOMStringImpl* lowerAttribute = DOMStringImpl(DOMStringImpl::ShallowCopy, m_attributeValue.data(), m_attributeValue.size()).lower(); QString val = lowerAttribute->string(); delete lowerAttribute; m_linkIsStyleSheet = val.contains("stylesheet") && !val.contains("alternate") && !val.contains("icon"); } } default: break; } }
void RenderStyle::setContent(DOMStringImpl* s, bool add) { if (!s) return; // The string is null. Nothing to do. Just bail. ContentData* lastContent = content; while (lastContent && lastContent->_nextContent) lastContent = lastContent->_nextContent; bool reuseContent = !add; if (add) { if (!lastContent) return; // Something's wrong. We had no previous content, and we should have. 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 = 0; if (reuseContent && content) { content->clearContent(); newContentData = content; } else newContentData = new ContentData; if (lastContent && !reuseContent) lastContent->_nextContent = newContentData; else content = newContentData; newContentData->_content.text = s; newContentData->_content.text->ref(); newContentData->_contentType = CONTENT_TEXT; }
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 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; }