📄 dom_textimpl.cpp
字号:
/**
* This file is part of the DOM implementation for KDE.
*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "dom/dom_exception.h"
#include "css/cssstyleselector.h"
#include "xml/dom2_eventsimpl.h"
#include "xml/dom_textimpl.h"
#include "xml/dom_docimpl.h"
#include "misc/htmlhashes.h"
#include "rendering/render_text.h"
#include <kdebug.h>
using namespace DOM;
using namespace khtml;
CharacterDataImpl::CharacterDataImpl(DocumentPtr *doc)
: NodeImpl(doc)
{
str = 0;
}
CharacterDataImpl::CharacterDataImpl(DocumentPtr *doc, const DOMString &_text)
: NodeImpl(doc)
{
str = _text.impl ? _text.impl : new DOMStringImpl((QChar*)0, 0);
str->ref();
}
CharacterDataImpl::~CharacterDataImpl()
{
if(str) str->deref();
}
DOMString CharacterDataImpl::data() const
{
return str;
}
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);
dispatchModifiedEvent(oldStr);
if(oldStr) oldStr->deref();
getDocument()->removeAllMarkers(this);
}
unsigned long CharacterDataImpl::length() const
{
return str->l;
}
DOMString CharacterDataImpl::substringData( const unsigned long offset, const unsigned long count, int &exceptioncode )
{
exceptioncode = 0;
checkCharDataOperation(offset, exceptioncode);
if (exceptioncode)
return DOMString();
return str->substring(offset,count);
}
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))->setTextWithOffset(str, oldStr->l, 0);
dispatchModifiedEvent(oldStr);
oldStr->deref();
}
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))->setTextWithOffset(str, offset, 0);
dispatchModifiedEvent(oldStr);
oldStr->deref();
// update the markers for spell checking and grammar checking
uint length = arg.length();
getDocument()->shiftMarkers(this, offset, length);
}
void CharacterDataImpl::deleteData( const unsigned long offset, const unsigned long count, int &exceptioncode )
{
exceptioncode = 0;
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))->setTextWithOffset(str, offset, count);
dispatchModifiedEvent(oldStr);
oldStr->deref();
// update the markers for spell checking and grammar checking
getDocument()->removeAllMarkers(this, offset, count);
getDocument()->shiftMarkers(this, offset + count, -count);
}
void CharacterDataImpl::replaceData( const unsigned long offset, const unsigned long count, const DOMString &arg, int &exceptioncode )
{
exceptioncode = 0;
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))->setTextWithOffset(str, offset, count);
dispatchModifiedEvent(oldStr);
oldStr->deref();
// update the markers for spell checking and grammar checking
int diff = arg.length() - count;
getDocument()->removeAllMarkers(this, offset, count);
getDocument()->shiftMarkers(this, offset + count, diff);
}
DOMString CharacterDataImpl::nodeValue() const
{
return str;
}
bool CharacterDataImpl::containsOnlyWhitespace(unsigned int from, unsigned int len) const
{
if (str)
return str->containsOnlyWhitespace(from, len);
return true;
}
bool CharacterDataImpl::containsOnlyWhitespace() const
{
if (str)
return str->containsOnlyWhitespace();
return true;
}
void CharacterDataImpl::setNodeValue( const DOMString &_nodeValue, int &exceptioncode )
{
// NO_MODIFICATION_ALLOWED_ERR: taken care of by setData()
setData(_nodeValue, exceptioncode);
}
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;
dispatchEvent(new MutationEventImpl(EventImpl::DOMCHARACTERDATAMODIFIED_EVENT,
true,false,0,prevValue,newValue,DOMString(),0),exceptioncode);
newValue->deref();
dispatchSubtreeModifiedEvent();
}
void CharacterDataImpl::checkCharDataOperation( 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.
if (offset > str->l) {
exceptioncode = DOMException::INDEX_SIZE_ERR;
return;
}
// NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly
if (isReadOnly()) {
exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
return;
}
}
long CharacterDataImpl::maxOffset() const
{
return (long)length();
}
long CharacterDataImpl::caretMinOffset() const
{
RenderText *r = static_cast<RenderText *>(renderer());
return r && r->isText() ? r->caretMinOffset() : 0;
}
long CharacterDataImpl::caretMaxOffset() const
{
RenderText *r = static_cast<RenderText *>(renderer());
return r && r->isText() ? r->caretMaxOffset() : (long)length();
}
unsigned long CharacterDataImpl::caretMaxRenderedOffset() const
{
RenderText *r = static_cast<RenderText *>(renderer());
return r ? r->caretMaxRenderedOffset() : length();
}
bool CharacterDataImpl::rendererIsNeeded(RenderStyle *style)
{
if (!str || str->l == 0)
return false;
return NodeImpl::rendererIsNeeded(style);
}
#ifndef NDEBUG
void CharacterDataImpl::dump(QTextStream *stream, QString ind) const
{
*stream << " str=\"" << DOMString(str).string().ascii() << "\"";
NodeImpl::dump(stream,ind);
}
#endif
// ---------------------------------------------------------------------------
CommentImpl::CommentImpl(DocumentPtr *doc, const DOMString &_text)
: CharacterDataImpl(doc, _text)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -