diff options
Diffstat (limited to 'khtml/xml')
26 files changed, 0 insertions, 15427 deletions
diff --git a/khtml/xml/CMakeLists.txt b/khtml/xml/CMakeLists.txt deleted file mode 100644 index 82fe99d4c..000000000 --- a/khtml/xml/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -################################################# -# -# (C) 2010 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${TQT_INCLUDE_DIRS} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/kjs - ${CMAKE_BINARY_DIR}/tdecore - ${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/dcop - ${CMAKE_SOURCE_DIR}/khtml - ${CMAKE_SOURCE_DIR}/tdecore - ${CMAKE_SOURCE_DIR}/tdeui - ${CMAKE_SOURCE_DIR}/kio - ${CMAKE_SOURCE_DIR}/kio/kio - ${CMAKE_SOURCE_DIR}/kwallet/client - ${CMAKE_SOURCE_DIR}/kutils -) - - -##### khtmlxml-static ############################ - -set( target khtmlxml ) - -set( ${target}_SRCS - dom_docimpl.cpp dom_nodeimpl.cpp dom_textimpl.cpp - dom_elementimpl.cpp dom_stringimpl.cpp dom2_rangeimpl.cpp - dom2_traversalimpl.cpp xml_tokenizer.cpp dom_xmlimpl.cpp - dom2_eventsimpl.cpp dom2_viewsimpl.cpp dom_restyler.cpp -) - -tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES ${${target}_SRCS} -) diff --git a/khtml/xml/Makefile.am b/khtml/xml/Makefile.am deleted file mode 100644 index 17a9779aa..000000000 --- a/khtml/xml/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -# This file is part of the KDE libraries -# Copyright (C) 1997 Martin Jones (mjones@kde.org) -# (C) 1997 Torben Weis (weis@kde.org) - -# 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., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301, USA. - -KDE_CXXFLAGS = $(WOVERLOADED_VIRTUAL) - -noinst_LTLIBRARIES = libkhtmlxml.la -libkhtmlxml_la_SOURCES = \ - dom_docimpl.cpp dom_nodeimpl.cpp dom_textimpl.cpp \ - dom_elementimpl.cpp dom_stringimpl.cpp dom2_rangeimpl.cpp \ - dom2_traversalimpl.cpp xml_tokenizer.cpp dom_xmlimpl.cpp \ - dom2_eventsimpl.cpp dom2_viewsimpl.cpp dom_restyler.cpp - -#libkhtmlxml_la_LDFLAGS = -no-undefined -libkhtmlxml_la_METASOURCES = AUTO - -noinst_HEADERS = \ - dom_docimpl.h dom_nodeimpl.h dom_textimpl.h \ - dom_elementimpl.h dom_stringimpl.h dom2_rangeimpl.h \ - dom2_traversalimpl.h xml_tokenizer.h dom_xmlimpl.h \ - dom2_eventsimpl.h dom2_viewsimpl.h dom_restyler.h - -INCLUDES = -I$(top_srcdir)/kimgio -I$(top_srcdir)/kio -I$(top_srcdir)/dcop \ - -I$(top_srcdir)/khtml -I$(top_srcdir) -I$(top_srcdir)/kwallet/client \ - -I$(top_srcdir)/kutils -I$(top_builddir)/kjs $(all_includes) - -SRCDOC_DEST=$(kde_htmldir)/en/tdelibs/khtml - -## generate lib documentation -srcdoc: - $(mkinstalldirs) $(SRCDOC_DEST) - kdoc -H -d $(SRCDOC_DEST) tdecore -lqt - diff --git a/khtml/xml/dom2_eventsimpl.cpp b/khtml/xml/dom2_eventsimpl.cpp deleted file mode 100644 index 5121e9caf..000000000 --- a/khtml/xml/dom2_eventsimpl.cpp +++ /dev/null @@ -1,969 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de) - * (C) 2003 Apple Computer, Inc. - * (C) 2006 Maksim Orlovich (maksim@kde.org) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "dom/dom2_views.h" - -#include "xml/dom2_eventsimpl.h" -#include "xml/dom_stringimpl.h" -#include "xml/dom_nodeimpl.h" -#include "xml/dom_docimpl.h" -#include "rendering/render_layer.h" -#include "khtmlview.h" - -#include <kdebug.h> - -using namespace DOM; -using namespace khtml; - -EventImpl::EventImpl() -{ - m_type = 0; - m_canBubble = false; - m_cancelable = false; - - m_propagationStopped = false; - m_defaultPrevented = false; - m_id = UNKNOWN_EVENT; - m_currentTarget = 0; - m_eventPhase = 0; - m_target = 0; - m_createTime = TQDateTime::currentDateTime(); - m_defaultHandled = false; -} - -EventImpl::EventImpl(EventId _id, bool canBubbleArg, bool cancelableArg) -{ - DOMString t = EventImpl::idToType(_id); - m_type = t.implementation(); - if (m_type) - m_type->ref(); - m_canBubble = canBubbleArg; - m_cancelable = cancelableArg; - - m_propagationStopped = false; - m_defaultPrevented = false; - m_id = _id; - m_currentTarget = 0; - m_eventPhase = 0; - m_target = 0; - m_createTime = TQDateTime::currentDateTime(); - m_defaultHandled = false; -} - -EventImpl::~EventImpl() -{ - if (m_type) - m_type->deref(); - if (m_target) - m_target->deref(); -} - -void EventImpl::setTarget(NodeImpl *_target) -{ - if (m_target) - m_target->deref(); - m_target = _target; - if (m_target) - m_target->ref(); -} - -DOMTimeStamp EventImpl::timeStamp() -{ - TQDateTime epoch(TQDate(1970,1,1),TQTime(0,0)); - // ### kjs does not yet support long long (?) so the value wraps around - return epoch.secsTo(m_createTime)*1000+m_createTime.time().msec(); -} - -void EventImpl::initEvent(const DOMString &eventTypeArg, bool canBubbleArg, bool cancelableArg) -{ - // ### ensure this is not called after we have been dispatched (also for subclasses) - - if (m_type) - m_type->deref(); - - m_type = eventTypeArg.implementation(); - if (m_type) - m_type->ref(); - - m_id = typeToId(eventTypeArg); - - m_canBubble = canBubbleArg; - m_cancelable = cancelableArg; -} - -EventImpl::EventId EventImpl::typeToId(DOMString type) -{ - if (type == "DOMFocusIn") - return DOMFOCUSIN_EVENT; - else if (type == "DOMFocusOut") - return DOMFOCUSOUT_EVENT; - else if (type == "DOMActivate") - return DOMACTIVATE_EVENT; - else if (type == "click") - return CLICK_EVENT; - else if (type == "mousedown") - return MOUSEDOWN_EVENT; - else if (type == "mouseup") - return MOUSEUP_EVENT; - else if (type == "mouseover") - return MOUSEOVER_EVENT; - else if (type == "mousemove") - return MOUSEMOVE_EVENT; - else if (type == "mouseout") - return MOUSEOUT_EVENT; - else if (type == "DOMSubtreeModified") - return DOMSUBTREEMODIFIED_EVENT; - else if (type == "DOMNodeInserted") - return DOMNODEINSERTED_EVENT; - else if (type == "DOMNodeRemoved") - return DOMNODEREMOVED_EVENT; - else if (type == "DOMNodeRemovedFromDocument") - return DOMNODEREMOVEDFROMDOCUMENT_EVENT; - else if (type == "DOMNodeInsertedIntoDocument") - return DOMNODEINSERTEDINTODOCUMENT_EVENT; - else if (type == "DOMAttrModified") - return DOMATTRMODIFIED_EVENT; - else if (type == "DOMCharacterDataModified") - return DOMCHARACTERDATAMODIFIED_EVENT; - else if (type == "load") - return LOAD_EVENT; - else if (type == "unload") - return UNLOAD_EVENT; - else if (type == "abort") - return ABORT_EVENT; - else if (type == "error") - return ERROR_EVENT; - else if (type == "select") - return SELECT_EVENT; - else if (type == "change") - return CHANGE_EVENT; - else if (type == "submit") - return SUBMIT_EVENT; - else if (type == "reset") - return RESET_EVENT; - else if (type == "focus") - return FOCUS_EVENT; - else if (type == "blur") - return BLUR_EVENT; - else if (type == "resize") - return RESIZE_EVENT; - else if (type == "scroll") - return SCROLL_EVENT; - else if ( type == "keydown" ) - return KEYDOWN_EVENT; - else if ( type == "keyup" ) - return KEYUP_EVENT; - else if ( type == "textInput" ) - return KEYPRESS_EVENT; - else if ( type == "keypress" ) - return KEYPRESS_EVENT; - else if ( type == "readystatechange" ) - return KHTML_READYSTATECHANGE_EVENT; - else if ( type == "dblclick" ) - return KHTML_ECMA_DBLCLICK_EVENT; - - // ignore: KHTML_CLICK_EVENT - return UNKNOWN_EVENT; -} - -DOMString EventImpl::idToType(EventImpl::EventId id) -{ - switch (id) { - case DOMFOCUSIN_EVENT: - return "DOMFocusIn"; - case DOMFOCUSOUT_EVENT: - return "DOMFocusOut"; - case DOMACTIVATE_EVENT: - return "DOMActivate"; - case CLICK_EVENT: - return "click"; - case MOUSEDOWN_EVENT: - return "mousedown"; - case MOUSEUP_EVENT: - return "mouseup"; - case MOUSEOVER_EVENT: - return "mouseover"; - case MOUSEMOVE_EVENT: - return "mousemove"; - case MOUSEOUT_EVENT: - return "mouseout"; - case DOMSUBTREEMODIFIED_EVENT: - return "DOMSubtreeModified"; - case DOMNODEINSERTED_EVENT: - return "DOMNodeInserted"; - case DOMNODEREMOVED_EVENT: - return "DOMNodeRemoved"; - case DOMNODEREMOVEDFROMDOCUMENT_EVENT: - return "DOMNodeRemovedFromDocument"; - case DOMNODEINSERTEDINTODOCUMENT_EVENT: - return "DOMNodeInsertedIntoDocument"; - case DOMATTRMODIFIED_EVENT: - return "DOMAttrModified"; - case DOMCHARACTERDATAMODIFIED_EVENT: - return "DOMCharacterDataModified"; - case LOAD_EVENT: - return "load"; - case UNLOAD_EVENT: - return "unload"; - case ABORT_EVENT: - return "abort"; - case ERROR_EVENT: - return "error"; - case SELECT_EVENT: - return "select"; - case CHANGE_EVENT: - return "change"; - case SUBMIT_EVENT: - return "submit"; - case RESET_EVENT: - return "reset"; - case FOCUS_EVENT: - return "focus"; - case BLUR_EVENT: - return "blur"; - case RESIZE_EVENT: - return "resize"; - case SCROLL_EVENT: - return "scroll"; - case KEYDOWN_EVENT: - return "keydown"; - case KEYUP_EVENT: - return "keyup"; - case KEYPRESS_EVENT: - return "keypress"; //DOM3 ev. suggests textInput, but it's better for compat this way - - //khtml extensions - case KHTML_ECMA_DBLCLICK_EVENT: - return "dblclick"; - case KHTML_ECMA_CLICK_EVENT: - return "click"; - case KHTML_DRAGDROP_EVENT: - return "khtml_dragdrop"; - case KHTML_MOVE_EVENT: - return "khtml_move"; - case KHTML_READYSTATECHANGE_EVENT: - return "readystatechange"; - - default: - return DOMString(); - break; - } -} - -bool EventImpl::isUIEvent() const -{ - return false; -} - -bool EventImpl::isMouseEvent() const -{ - return false; -} - -bool EventImpl::isMutationEvent() const -{ - return false; -} - -bool EventImpl::isTextInputEvent() const -{ - return false; -} - -bool EventImpl::isKeyboardEvent() const -{ - return false; -} - -// ----------------------------------------------------------------------------- - -UIEventImpl::UIEventImpl(EventId _id, bool canBubbleArg, bool cancelableArg, - AbstractViewImpl *viewArg, long detailArg) - : EventImpl(_id,canBubbleArg,cancelableArg) -{ - m_view = viewArg; - if (m_view) - m_view->ref(); - m_detail = detailArg; -} - -UIEventImpl::~UIEventImpl() -{ - if (m_view) - m_view->deref(); -} - -void UIEventImpl::initUIEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - long detailArg) -{ - EventImpl::initEvent(typeArg,canBubbleArg,cancelableArg); - - if (m_view) - m_view->deref(); - - m_view = viewArg.handle(); - if (m_view) - m_view->ref(); - m_detail = detailArg; -} - -bool UIEventImpl::isUIEvent() const -{ - return true; -} - -// ----------------------------------------------------------------------------- - -MouseEventImpl::MouseEventImpl() -{ - m_screenX = 0; - m_screenY = 0; - m_clientX = 0; - m_clientY = 0; - m_pageX = 0; - m_pageY = 0; - m_ctrlKey = false; - m_altKey = false; - m_shiftKey = false; - m_metaKey = false; - m_button = 0; - m_relatedTarget = 0; - m_qevent = 0; - m_isDoubleClick = false; -} - -MouseEventImpl::MouseEventImpl(EventId _id, - bool canBubbleArg, - bool cancelableArg, - AbstractViewImpl *viewArg, - long detailArg, - long screenXArg, - long screenYArg, - long clientXArg, - long clientYArg, - long pageXArg, - long pageYArg, - bool ctrlKeyArg, - bool altKeyArg, - bool shiftKeyArg, - bool metaKeyArg, - unsigned short buttonArg, - NodeImpl *relatedTargetArg, - TQMouseEvent *qe, - bool isDoubleClick) - : UIEventImpl(_id,canBubbleArg,cancelableArg,viewArg,detailArg) -{ - m_screenX = screenXArg; - m_screenY = screenYArg; - m_clientX = clientXArg; - m_clientY = clientYArg; - m_pageX = pageXArg; - m_pageY = pageYArg; - m_ctrlKey = ctrlKeyArg; - m_altKey = altKeyArg; - m_shiftKey = shiftKeyArg; - m_metaKey = metaKeyArg; - m_button = buttonArg; - m_relatedTarget = relatedTargetArg; - if (m_relatedTarget) - m_relatedTarget->ref(); - computeLayerPos(); - m_qevent = qe; - m_isDoubleClick = isDoubleClick; -} - -MouseEventImpl::~MouseEventImpl() -{ - if (m_relatedTarget) - m_relatedTarget->deref(); -} - -void MouseEventImpl::computeLayerPos() -{ - m_layerX = m_pageX; - m_layerY = m_pageY; - - DocumentImpl* doc = view() ? view()->document() : 0; - if (doc) { - khtml::RenderObject::NodeInfo renderInfo(true, false); - doc->renderer()->layer()->nodeAtPoint(renderInfo, m_pageX, m_pageY); - - NodeImpl *node = renderInfo.innerNonSharedNode(); - while (node && !node->renderer()) - node = node->parent(); - - if (node) { - node->renderer()->enclosingLayer()->updateLayerPosition(); - for (RenderLayer* layer = node->renderer()->enclosingLayer(); layer; - layer = layer->parent()) { - m_layerX -= layer->xPos(); - m_layerY -= layer->yPos(); - } - } - } -} - -void MouseEventImpl::initMouseEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - long detailArg, - long screenXArg, - long screenYArg, - long clientXArg, - long clientYArg, - bool ctrlKeyArg, - bool altKeyArg, - bool shiftKeyArg, - bool metaKeyArg, - unsigned short buttonArg, - const Node &relatedTargetArg) -{ - UIEventImpl::initUIEvent(typeArg,canBubbleArg,cancelableArg,viewArg,detailArg); - - if (m_relatedTarget) - m_relatedTarget->deref(); - - m_screenX = screenXArg; - m_screenY = screenYArg; - m_clientX = clientXArg; - m_clientY = clientYArg; - m_pageX = clientXArg; - m_pageY = clientYArg; - KHTMLView* v; - if ( view() && view()->document() && ( v = view()->document()->view() ) ) { - m_pageX += v->contentsX(); - m_pageY += v->contentsY(); - } - m_ctrlKey = ctrlKeyArg; - m_altKey = altKeyArg; - m_shiftKey = shiftKeyArg; - m_metaKey = metaKeyArg; - m_button = buttonArg; - m_relatedTarget = relatedTargetArg.handle(); - if (m_relatedTarget) - m_relatedTarget->ref(); - - - // ### make this on-demand. its soo sloooow - computeLayerPos(); - m_qevent = 0; -} - -bool MouseEventImpl::isMouseEvent() const -{ - return true; -} - -//--------------------------------------------------------------------------------------------- -/* This class is used to do remapping between different encodings reasonably compactly */ - -template<typename L, typename R, typename MemL> -class IDTranslator -{ -public: - struct Info { - MemL l; - R r; - }; - - IDTranslator(const Info* table) { - for (const Info* cursor = table; cursor->l; ++cursor) { - m_lToR.insert(cursor->l, cursor->r); - m_rToL.insert(cursor->r, cursor->l); - } - } - - L toLeft(R r) { - TQMapIterator<R,L> i( m_rToL.find(r) ); - if (i != m_rToL.end()) - return *i; - return L(); - } - - R toRight(L l) { - TQMapIterator<L,R> i = m_lToR.find(l); - if (i != m_lToR.end()) - return *i; - return R(); - } - -private: - TQMap<L, R> m_lToR; - TQMap<R, L> m_rToL; -}; - -#define MAKE_TRANSLATOR(name,L,R,MR,table) static IDTranslator<L,R,MR>* s_##name; \ - static IDTranslator<L,R,MR>* name() { if (!s_##name) s_##name = new IDTranslator<L,R,MR>(table); \ - return s_##name; } - -//--------------------------------------------------------------------------------------------- - -/* Mapping between special Qt keycodes and virtual DOM codes */ -IDTranslator<unsigned, unsigned, unsigned>::Info virtKeyToQtKeyTable[] = -{ - {KeyEventBaseImpl::DOM_VK_BACK_SPACE, Qt::Key_Backspace}, - {KeyEventBaseImpl::DOM_VK_ENTER, Qt::Key_Enter}, - {KeyEventBaseImpl::DOM_VK_ENTER, Qt::Key_Return}, - {KeyEventBaseImpl::DOM_VK_NUM_LOCK, Qt::Key_NumLock}, - {KeyEventBaseImpl::DOM_VK_RIGHT_ALT, Qt::Key_Alt}, - {KeyEventBaseImpl::DOM_VK_LEFT_CONTROL, Qt::Key_Control}, - {KeyEventBaseImpl::DOM_VK_LEFT_SHIFT, Qt::Key_Shift}, - {KeyEventBaseImpl::DOM_VK_META, Qt::Key_Meta}, - {KeyEventBaseImpl::DOM_VK_CAPS_LOCK, Qt::Key_CapsLock}, - {KeyEventBaseImpl::DOM_VK_DELETE, Qt::Key_Delete}, - {KeyEventBaseImpl::DOM_VK_END, Qt::Key_End}, - {KeyEventBaseImpl::DOM_VK_ESCAPE, Qt::Key_Escape}, - {KeyEventBaseImpl::DOM_VK_HOME, Qt::Key_Home}, - {KeyEventBaseImpl::DOM_VK_PAUSE, Qt::Key_Pause}, - {KeyEventBaseImpl::DOM_VK_PRINTSCREEN, Qt::Key_Print}, - {KeyEventBaseImpl::DOM_VK_SCROLL_LOCK, Qt::Key_ScrollLock}, - {KeyEventBaseImpl::DOM_VK_LEFT, Qt::Key_Left}, - {KeyEventBaseImpl::DOM_VK_RIGHT, Qt::Key_Right}, - {KeyEventBaseImpl::DOM_VK_UP, Qt::Key_Up}, - {KeyEventBaseImpl::DOM_VK_DOWN, Qt::Key_Down}, - {KeyEventBaseImpl::DOM_VK_PAGE_DOWN, TQt::Key_Next}, - {KeyEventBaseImpl::DOM_VK_PAGE_UP, TQt::Key_Prior}, - {KeyEventBaseImpl::DOM_VK_F1, Qt::Key_F1}, - {KeyEventBaseImpl::DOM_VK_F2, Qt::Key_F2}, - {KeyEventBaseImpl::DOM_VK_F3, Qt::Key_F3}, - {KeyEventBaseImpl::DOM_VK_F4, Qt::Key_F4}, - {KeyEventBaseImpl::DOM_VK_F5, Qt::Key_F5}, - {KeyEventBaseImpl::DOM_VK_F6, Qt::Key_F6}, - {KeyEventBaseImpl::DOM_VK_F7, Qt::Key_F7}, - {KeyEventBaseImpl::DOM_VK_F8, Qt::Key_F8}, - {KeyEventBaseImpl::DOM_VK_F9, Qt::Key_F9}, - {KeyEventBaseImpl::DOM_VK_F10, Qt::Key_F10}, - {KeyEventBaseImpl::DOM_VK_F11, Qt::Key_F11}, - {KeyEventBaseImpl::DOM_VK_F12, Qt::Key_F12}, - {KeyEventBaseImpl::DOM_VK_F13, Qt::Key_F13}, - {KeyEventBaseImpl::DOM_VK_F14, Qt::Key_F14}, - {KeyEventBaseImpl::DOM_VK_F15, Qt::Key_F15}, - {KeyEventBaseImpl::DOM_VK_F16, Qt::Key_F16}, - {KeyEventBaseImpl::DOM_VK_F17, Qt::Key_F17}, - {KeyEventBaseImpl::DOM_VK_F18, Qt::Key_F18}, - {KeyEventBaseImpl::DOM_VK_F19, Qt::Key_F19}, - {KeyEventBaseImpl::DOM_VK_F20, Qt::Key_F20}, - {KeyEventBaseImpl::DOM_VK_F21, Qt::Key_F21}, - {KeyEventBaseImpl::DOM_VK_F22, Qt::Key_F22}, - {KeyEventBaseImpl::DOM_VK_F23, Qt::Key_F23}, - {KeyEventBaseImpl::DOM_VK_F24, Qt::Key_F24}, - {0, 0} -}; - -MAKE_TRANSLATOR(virtKeyToQtKey, unsigned, unsigned, unsigned, virtKeyToQtKeyTable) - -KeyEventBaseImpl::KeyEventBaseImpl(EventId id, bool canBubbleArg, bool cancelableArg, AbstractViewImpl *viewArg, - TQKeyEvent *key) : - UIEventImpl(id, canBubbleArg, cancelableArg, viewArg, 0) -{ - m_synthetic = false; - - //Here, we need to map Qt's internal info to browser-style info. - m_keyEvent = new TQKeyEvent(key->type(), key->key(), key->ascii(), key->state(), key->text(), key->isAutoRepeat(), key->count() ); - - m_detail = key->count(); - m_keyVal = key->ascii(); - m_virtKeyVal = virtKeyToQtKey()->toLeft(key->key()); - - // m_keyVal should contain the unicode value - // of the pressed key if available. - if (m_virtKeyVal == DOM_VK_UNDEFINED && !key->text().isEmpty()) - m_keyVal = TQString(key->text()).unicode()[0]; - - // key->state returns enum ButtonState, which is ShiftButton, ControlButton and AltButton or'ed together. - m_modifier = key->state(); -} - -KeyEventBaseImpl::~KeyEventBaseImpl() -{ - delete m_keyEvent; -} - -void KeyEventBaseImpl::initKeyBaseEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - unsigned long keyValArg, - unsigned long virtKeyValArg, - unsigned long modifiersArg) -{ - m_synthetic = true; - delete m_keyEvent; - m_keyEvent = 0; - initUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, 1); - m_virtKeyVal = virtKeyValArg; - m_keyVal = keyValArg; - m_modifier = modifiersArg; -} - -bool KeyEventBaseImpl::checkModifier(unsigned long modifierArg) -{ - return ((m_modifier & modifierArg) == modifierArg); -} - -void KeyEventBaseImpl::initModifier(unsigned long modifierArg, - bool valueArg) -{ - if (valueArg) - m_modifier |= modifierArg; - else - m_modifier &= (modifierArg ^ 0xFFFFFFFF); -} - -void KeyEventBaseImpl::buildQKeyEvent() const -{ - delete m_keyEvent; - - assert(m_synthetic); - //IMPORTANT: we ignore modifers on purpose. - //this is to prevent a website from synthesizing something - //like Ctrl-V or Shift-Insert and stealing contents of the user's clipboard. - unsigned modifiers = 0; - - int key = 0; - int ascii = 0; - TQString text; - if (m_virtKeyVal) - key = virtKeyToQtKey()->toRight(m_virtKeyVal); - if (!key) { - ascii = m_keyVal; //###? - key = m_keyVal; - text = TQChar(key); - } - - //Neuter F keys as well. - if (key >= Qt::Key_F1 && key <= Qt::Key_F35) - key = Qt::Key_ScrollLock; - - m_keyEvent = new TQKeyEvent(id() == KEYUP_EVENT ? TQEvent::KeyRelease : TQEvent::KeyPress, - key, ascii, modifiers, text); -} - -//------------------------------------------------------------------------------ - - -static const IDTranslator<TQCString, unsigned, const char*>::Info keyIdentifiersToVirtKeysTable[] = { - {"Alt", KeyEventBaseImpl::DOM_VK_LEFT_ALT}, - {"Control", KeyEventBaseImpl::DOM_VK_LEFT_CONTROL}, - {"Shift", KeyEventBaseImpl::DOM_VK_LEFT_SHIFT}, - {"Meta", KeyEventBaseImpl::DOM_VK_META}, - {"\0x08", KeyEventBaseImpl::DOM_VK_SPACE}, //1-char virt! - {"CapsLock", KeyEventBaseImpl::DOM_VK_CAPS_LOCK}, - {"\x7F", KeyEventBaseImpl::DOM_VK_DELETE}, //1-char virt! - {"End", KeyEventBaseImpl::DOM_VK_END}, - {"Enter", KeyEventBaseImpl::DOM_VK_ENTER}, - {"\x1b", KeyEventBaseImpl::DOM_VK_ESCAPE}, //1-char virt! - {"Home", KeyEventBaseImpl::DOM_VK_HOME}, - {"NumLock", KeyEventBaseImpl::DOM_VK_NUM_LOCK}, - {"Pause", KeyEventBaseImpl::DOM_VK_PAUSE}, - {"PrintScreen", KeyEventBaseImpl::DOM_VK_PRINTSCREEN}, - {"Scroll", KeyEventBaseImpl::DOM_VK_SCROLL_LOCK}, - {" ", KeyEventBaseImpl::DOM_VK_SPACE}, //1-char virt! - {"\t", KeyEventBaseImpl::DOM_VK_TAB}, //1-char virt! - {"Left", KeyEventBaseImpl::DOM_VK_LEFT}, - {"Left", KeyEventBaseImpl::DOM_VK_LEFT}, - {"Right", KeyEventBaseImpl::DOM_VK_RIGHT}, - {"Up", KeyEventBaseImpl::DOM_VK_UP}, - {"Down", KeyEventBaseImpl::DOM_VK_DOWN}, - {"PageDown", KeyEventBaseImpl::DOM_VK_PAGE_DOWN}, - {"PageUp", KeyEventBaseImpl::DOM_VK_PAGE_UP}, - {"F1", KeyEventBaseImpl::DOM_VK_F1}, - {"F2", KeyEventBaseImpl::DOM_VK_F2}, - {"F3", KeyEventBaseImpl::DOM_VK_F3}, - {"F4", KeyEventBaseImpl::DOM_VK_F4}, - {"F5", KeyEventBaseImpl::DOM_VK_F5}, - {"F6", KeyEventBaseImpl::DOM_VK_F6}, - {"F7", KeyEventBaseImpl::DOM_VK_F7}, - {"F8", KeyEventBaseImpl::DOM_VK_F8}, - {"F9", KeyEventBaseImpl::DOM_VK_F9}, - {"F10", KeyEventBaseImpl::DOM_VK_F10}, - {"F11", KeyEventBaseImpl::DOM_VK_F11}, - {"F12", KeyEventBaseImpl::DOM_VK_F12}, - {"F13", KeyEventBaseImpl::DOM_VK_F13}, - {"F14", KeyEventBaseImpl::DOM_VK_F14}, - {"F15", KeyEventBaseImpl::DOM_VK_F15}, - {"F16", KeyEventBaseImpl::DOM_VK_F16}, - {"F17", KeyEventBaseImpl::DOM_VK_F17}, - {"F18", KeyEventBaseImpl::DOM_VK_F18}, - {"F19", KeyEventBaseImpl::DOM_VK_F19}, - {"F20", KeyEventBaseImpl::DOM_VK_F20}, - {"F21", KeyEventBaseImpl::DOM_VK_F21}, - {"F22", KeyEventBaseImpl::DOM_VK_F22}, - {"F23", KeyEventBaseImpl::DOM_VK_F23}, - {"F24", KeyEventBaseImpl::DOM_VK_F24}, - {0, 0} -}; - -MAKE_TRANSLATOR(keyIdentifiersToVirtKeys, TQCString, unsigned, const char*, keyIdentifiersToVirtKeysTable) - -/** These are the modifiers we currently support */ -static const IDTranslator<TQCString, unsigned, const char*>::Info keyModifiersToCodeTable[] = { - {"Alt", TQt::AltButton}, - {"Control", TQt::ControlButton}, - {"Shift", TQt::ShiftButton}, - {"Meta", TQt::MetaButton}, - {0, 0} -}; - -MAKE_TRANSLATOR(keyModifiersToCode, TQCString, unsigned, const char*, keyModifiersToCodeTable) - -KeyboardEventImpl::KeyboardEventImpl() : m_keyLocation(DOM_KEY_LOCATION_STANDARD) -{} - -DOMString KeyboardEventImpl::keyIdentifier() const -{ - if (unsigned special = virtKeyVal()) - if (const char* id = keyIdentifiersToVirtKeys()->toLeft(special)) - return TQString::fromLatin1(id); - - if (unsigned unicode = keyVal()) - return TQString(TQChar(unicode)); - - return "Unidentified"; -} - -bool KeyboardEventImpl::getModifierState (const DOMString& keyIdentifierArg) const -{ - unsigned mask = keyModifiersToCode()->toRight(keyIdentifierArg.string().latin1()); - return m_modifier & mask; -} - -bool KeyboardEventImpl::isKeyboardEvent() const -{ - return true; -} - -void KeyboardEventImpl::initKeyboardEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - const DOMString &keyIdentifierArg, - unsigned long keyLocationArg, - const DOMString& modifiersList) -{ - unsigned keyVal = 0; - unsigned virtKeyVal = 0; - - m_keyLocation = keyLocationArg; - - //Figure out the code information from the key identifier. - if (keyIdentifierArg.length() == 1) { - //Likely to be normal unicode id, unless it's one of the few - //special values. - unsigned short code = keyIdentifierArg.unicode()[0]; - if (code > 0x20 && code != 0x7F) - keyVal = code; - } - - if (!keyVal) //One of special keys, likely. - virtKeyVal = keyIdentifiersToVirtKeys()->toRight(keyIdentifierArg.string().latin1()); - - //Process modifier list. - TQStringList mods = - TQStringList::split(' ', - modifiersList.string().stripWhiteSpace().simplifyWhiteSpace()); - - unsigned modifiers = 0; - for (TQStringList::Iterator i = mods.begin(); i != mods.end(); ++i) - if (unsigned mask = keyModifiersToCode()->toRight((*i).latin1())) - modifiers |= mask; - - initKeyBaseEvent(typeArg, canBubbleArg, cancelableArg, viewArg, - keyVal, virtKeyVal, modifiers); -} - -KeyboardEventImpl::KeyboardEventImpl(TQKeyEvent* key, DOM::AbstractViewImpl* view) : - KeyEventBaseImpl(key->type() == TQEvent::KeyRelease ? KEYUP_EVENT : KEYDOWN_EVENT, true, true, view, key) -{ - //Try to put something reasonable in location... - //we don't know direction, so guess left - m_keyLocation = DOM_KEY_LOCATION_STANDARD; - switch (m_virtKeyVal) { - case DOM_VK_LEFT_ALT: - case DOM_VK_LEFT_SHIFT: - case DOM_VK_LEFT_CONTROL: - case DOM_VK_META: - m_keyLocation = DOM_KEY_LOCATION_LEFT; - } -} - -int KeyboardEventImpl::keyCode() const -{ - //Keycode on key events always identifies the -key- and not the input, - //so e.g. 'a' will get 'A' - if (m_virtKeyVal != DOM_VK_UNDEFINED) - return m_virtKeyVal; - else - return TQChar((unsigned short)m_keyVal).upper().unicode(); -} - -int KeyboardEventImpl::charCode() const -{ - //IE doesn't support charCode at all, and mozilla returns 0 - //on key events. So return 0 here - return 0; -} - - -// ----------------------------------------------------------------------------- -TextEventImpl::TextEventImpl() -{} - -bool TextEventImpl::isTextInputEvent() const -{ - return true; -} - -TextEventImpl::TextEventImpl(TQKeyEvent* key, DOM::AbstractViewImpl* view) : - KeyEventBaseImpl(KEYPRESS_EVENT, true, true, view, key) -{ - m_outputString = TQString(key->text()); -} - -void TextEventImpl::initTextEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - const DOMString& text) -{ - m_outputString = text; - - //See whether we can get a key out of this. - unsigned keyCode = 0; - if (text.length() == 1) - keyCode = text.unicode()[0].unicode(); - initKeyBaseEvent(typeArg, canBubbleArg, cancelableArg, viewArg, - keyCode, 0, 0); -} - -int TextEventImpl::keyCode() const -{ - //Mozilla returns 0 here unless this is a non-unicode key. - //IE stuffs everything here, and so we try to match it.. - if (m_keyVal) - return m_keyVal; - return m_virtKeyVal; -} - -int TextEventImpl::charCode() const -{ - //On text events, in Mozilla charCode is 0 for non-unicode keys, - //and the unicode key otherwise... IE doesn't support this. - if (m_virtKeyVal) - return 0; - return m_keyVal; -} - - -// ----------------------------------------------------------------------------- -MutationEventImpl::MutationEventImpl() -{ - m_relatedNode = 0; - m_prevValue = 0; - m_newValue = 0; - m_attrName = 0; - m_attrChange = 0; -} - -MutationEventImpl::MutationEventImpl(EventId _id, - bool canBubbleArg, - bool cancelableArg, - const Node &relatedNodeArg, - const DOMString &prevValueArg, - const DOMString &newValueArg, - const DOMString &attrNameArg, - unsigned short attrChangeArg) - : EventImpl(_id,canBubbleArg,cancelableArg) -{ - m_relatedNode = relatedNodeArg.handle(); - if (m_relatedNode) - m_relatedNode->ref(); - m_prevValue = prevValueArg.implementation(); - if (m_prevValue) - m_prevValue->ref(); - m_newValue = newValueArg.implementation(); - if (m_newValue) - m_newValue->ref(); - m_attrName = attrNameArg.implementation(); - if (m_attrName) - m_attrName->ref(); - m_attrChange = attrChangeArg; -} - -MutationEventImpl::~MutationEventImpl() -{ - if (m_relatedNode) - m_relatedNode->deref(); - if (m_prevValue) - m_prevValue->deref(); - if (m_newValue) - m_newValue->deref(); - if (m_attrName) - m_attrName->deref(); -} - -void MutationEventImpl::initMutationEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const Node &relatedNodeArg, - const DOMString &prevValueArg, - const DOMString &newValueArg, - const DOMString &attrNameArg, - unsigned short attrChangeArg) -{ - EventImpl::initEvent(typeArg,canBubbleArg,cancelableArg); - - if (m_relatedNode) - m_relatedNode->deref(); - if (m_prevValue) - m_prevValue->deref(); - if (m_newValue) - m_newValue->deref(); - if (m_attrName) - m_attrName->deref(); - - m_relatedNode = relatedNodeArg.handle(); - if (m_relatedNode) - m_relatedNode->ref(); - m_prevValue = prevValueArg.implementation(); - if (m_prevValue) - m_prevValue->ref(); - m_newValue = newValueArg.implementation(); - if (m_newValue) - m_newValue->ref(); - m_attrName = attrNameArg.implementation(); - if (m_newValue) - m_newValue->ref(); - m_attrChange = attrChangeArg; -} - -bool MutationEventImpl::isMutationEvent() const -{ - return true; -} - diff --git a/khtml/xml/dom2_eventsimpl.h b/khtml/xml/dom2_eventsimpl.h deleted file mode 100644 index fab2225e5..000000000 --- a/khtml/xml/dom2_eventsimpl.h +++ /dev/null @@ -1,513 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de) - * (C) 2002 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _DOM_EventsImpl_h_ -#define _DOM_EventsImpl_h_ - -#include "dom/dom2_events.h" -#include "xml/dom2_viewsimpl.h" - -class KHTMLPart; -class TQMouseEvent; - -namespace DOM { - -class AbstractViewImpl; -class DOMStringImpl; -class NodeImpl; - -// ### support user-defined events - -class EventImpl : public khtml::Shared<EventImpl> -{ -public: - enum EventId { - UNKNOWN_EVENT = 0, - // UI events - DOMFOCUSIN_EVENT, - DOMFOCUSOUT_EVENT, - DOMACTIVATE_EVENT, - // Mouse events - CLICK_EVENT, - MOUSEDOWN_EVENT, - MOUSEUP_EVENT, - MOUSEOVER_EVENT, - MOUSEMOVE_EVENT, - MOUSEOUT_EVENT, - // Mutation events - DOMSUBTREEMODIFIED_EVENT, - DOMNODEINSERTED_EVENT, - DOMNODEREMOVED_EVENT, - DOMNODEREMOVEDFROMDOCUMENT_EVENT, - DOMNODEINSERTEDINTODOCUMENT_EVENT, - DOMATTRMODIFIED_EVENT, - DOMCHARACTERDATAMODIFIED_EVENT, - // HTML events - LOAD_EVENT, - UNLOAD_EVENT, - ABORT_EVENT, - ERROR_EVENT, - SELECT_EVENT, - CHANGE_EVENT, - SUBMIT_EVENT, - RESET_EVENT, - FOCUS_EVENT, - BLUR_EVENT, - RESIZE_EVENT, - SCROLL_EVENT, - // keyboard events - KEYDOWN_EVENT, - KEYUP_EVENT, - KEYPRESS_EVENT, //Mostly corresponds to DOM3 textInput event. - // khtml events (not part of DOM) - KHTML_ECMA_DBLCLICK_EVENT, // for html ondblclick - KHTML_ECMA_CLICK_EVENT, // for html onclick - KHTML_DRAGDROP_EVENT, - KHTML_MOVE_EVENT, - // XMLHttpRequest events - KHTML_READYSTATECHANGE_EVENT - }; - - EventImpl(); - EventImpl(EventId _id, bool canBubbleArg, bool cancelableArg); - virtual ~EventImpl(); - - EventId id() const { return m_id; } - - DOMString type() const { return m_type; } - NodeImpl *target() const { return m_target; } - void setTarget(NodeImpl *_target); - NodeImpl *currentTarget() const { return m_currentTarget; } - void setCurrentTarget(NodeImpl *_currentTarget) { m_currentTarget = _currentTarget; } - unsigned short eventPhase() const { return m_eventPhase; } - void setEventPhase(unsigned short _eventPhase) { m_eventPhase = _eventPhase; } - bool bubbles() const { return m_canBubble; } - bool cancelable() const { return m_cancelable; } - DOMTimeStamp timeStamp(); - void stopPropagation(bool stop) { m_propagationStopped = stop; } - void preventDefault(bool prevent) { if ( m_cancelable ) m_defaultPrevented = prevent; } - - void initEvent(const DOMString &eventTypeArg, bool canBubbleArg, bool cancelableArg); - - virtual bool isUIEvent() const; - virtual bool isMouseEvent() const; - virtual bool isMutationEvent() const; - virtual bool isTextInputEvent() const; - virtual bool isKeyboardEvent() const; - bool isKeyRelatedEvent() const { return isTextInputEvent() || isKeyboardEvent(); } - - bool propagationStopped() const { return m_propagationStopped; } - bool defaultPrevented() const { return m_defaultPrevented; } - - static EventId typeToId(DOMString type); - static DOMString idToType(EventId id); - - void setDefaultHandled() { m_defaultHandled = true; } - bool defaultHandled() const { return m_defaultHandled; } - - DOMString message() const { return m_message; } - void setMessage(const DOMString &_message) { m_message = _message; } - -protected: - DOMStringImpl *m_type; - bool m_canBubble; - bool m_cancelable; - - bool m_propagationStopped; - bool m_defaultPrevented; - bool m_defaultHandled; - EventId m_id : 6; - unsigned short m_eventPhase : 2; - NodeImpl *m_currentTarget; // ref > 0 maintained externally - NodeImpl *m_target; - TQDateTime m_createTime; - DOMString m_message; -}; - - - -class UIEventImpl : public EventImpl -{ -public: - UIEventImpl() : m_view(0), m_detail(0) {} - UIEventImpl(EventId _id, - bool canBubbleArg, - bool cancelableArg, - AbstractViewImpl *viewArg, - long detailArg); - virtual ~UIEventImpl(); - AbstractViewImpl *view() const { return m_view; } - long detail() const { return m_detail; } - void initUIEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - long detailArg); - virtual bool isUIEvent() const; - -protected: - AbstractViewImpl *m_view; - long m_detail; - -}; - -// Introduced in DOM Level 2: - internal -class MouseEventImpl : public UIEventImpl { -public: - MouseEventImpl(); - MouseEventImpl(EventId _id, - bool canBubbleArg, - bool cancelableArg, - AbstractViewImpl *viewArg, - long detailArg, - long screenXArg, - long screenYArg, - long clientXArg, - long clientYArg, - long pageXArg, - long pageYArg, - bool ctrlKeyArg, - bool altKeyArg, - bool shiftKeyArg, - bool metaKeyArg, - unsigned short buttonArg, - NodeImpl *relatedTargetArg, - TQMouseEvent *qe = 0, - bool isDoubleClick = false); - virtual ~MouseEventImpl(); - long screenX() const { return m_screenX; } - long screenY() const { return m_screenY; } - long clientX() const { return m_clientX; } - long clientY() const { return m_clientY; } - long layerX() const { return m_layerX; } // non-DOM extension - long layerY() const { return m_layerY; } // non-DOM extension - long pageX() const { return m_pageX; } // non-DOM extension - long pageY() const { return m_pageY; } // non-DOM extension - bool isDoubleClick() const { return m_isDoubleClick; } // non-DOM extension - bool ctrlKey() const { return m_ctrlKey; } - bool shiftKey() const { return m_shiftKey; } - bool altKey() const { return m_altKey; } - bool metaKey() const { return m_metaKey; } - unsigned short button() const { return m_button; } - NodeImpl *relatedTarget() const { return m_relatedTarget; } - - void computeLayerPos(); - - void initMouseEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - long detailArg, - long screenXArg, - long screenYArg, - long clientXArg, - long clientYArg, - bool ctrlKeyArg, - bool altKeyArg, - bool shiftKeyArg, - bool metaKeyArg, - unsigned short buttonArg, - const Node &relatedTargetArg); - virtual bool isMouseEvent() const; - - TQMouseEvent *qEvent() const { return m_qevent; } -protected: - long m_screenX; - long m_screenY; - long m_clientX; - long m_clientY; - long m_layerX; - long m_layerY; - long m_pageX; - long m_pageY; - bool m_ctrlKey : 1; - bool m_altKey : 1; - bool m_shiftKey : 1; - bool m_metaKey : 1; - bool m_isDoubleClick : 1; - unsigned short m_button; - NodeImpl *m_relatedTarget; - TQMouseEvent *m_qevent; -}; - - -class KeyEventBaseImpl : public UIEventImpl { -public: - // VirtualKeyCode - enum KeyCodes { - DOM_VK_UNDEFINED = 0x0, - DOM_VK_RIGHT_ALT = 0x12, - DOM_VK_LEFT_ALT = 0x12, - DOM_VK_LEFT_CONTROL = 0x11, - DOM_VK_RIGHT_CONTROL = 0x11, - DOM_VK_LEFT_SHIFT = 0x10, - DOM_VK_RIGHT_SHIFT = 0x10, - DOM_VK_META = 0x9D, - DOM_VK_BACK_SPACE = 0x08, - DOM_VK_CAPS_LOCK = 0x14, - DOM_VK_DELETE = 0x7F, - DOM_VK_END = 0x23, - DOM_VK_ENTER = 0x0D, - DOM_VK_ESCAPE = 0x1B, - DOM_VK_HOME = 0x24, - DOM_VK_NUM_LOCK = 0x90, - DOM_VK_PAUSE = 0x13, - DOM_VK_PRINTSCREEN = 0x9A, - DOM_VK_SCROLL_LOCK = 0x91, - DOM_VK_SPACE = 0x20, - DOM_VK_TAB = 0x09, - DOM_VK_LEFT = 0x25, - DOM_VK_RIGHT = 0x27, - DOM_VK_UP = 0x26, - DOM_VK_DOWN = 0x28, - DOM_VK_PAGE_DOWN = 0x22, - DOM_VK_PAGE_UP = 0x21, - DOM_VK_F1 = 0x70, - DOM_VK_F2 = 0x71, - DOM_VK_F3 = 0x72, - DOM_VK_F4 = 0x73, - DOM_VK_F5 = 0x74, - DOM_VK_F6 = 0x75, - DOM_VK_F7 = 0x76, - DOM_VK_F8 = 0x77, - DOM_VK_F9 = 0x78, - DOM_VK_F10 = 0x79, - DOM_VK_F11 = 0x7A, - DOM_VK_F12 = 0x7B, - DOM_VK_F13 = 0xF000, - DOM_VK_F14 = 0xF001, - DOM_VK_F15 = 0xF002, - DOM_VK_F16 = 0xF003, - DOM_VK_F17 = 0xF004, - DOM_VK_F18 = 0xF005, - DOM_VK_F19 = 0xF006, - DOM_VK_F20 = 0xF007, - DOM_VK_F21 = 0xF008, - DOM_VK_F22 = 0xF009, - DOM_VK_F23 = 0xF00A, - DOM_VK_F24 = 0xF00B - }; - - void initKeyBaseEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - unsigned long keyVal, - unsigned long virtKeyVal, - unsigned long modifiers); - - bool ctrlKey() const { return m_modifier & TQt::ControlButton; } - bool shiftKey() const { return m_modifier & TQt::ShiftButton; } - bool altKey() const { return m_modifier & TQt::AltButton; } - bool metaKey() const { return m_modifier & TQt::MetaButton; } - - bool inputGenerated() const { return m_virtKeyVal == 0; } - unsigned long keyVal() const { return m_keyVal; } - unsigned long virtKeyVal() const { return m_virtKeyVal; } - - TQKeyEvent *qKeyEvent() const { if (!m_keyEvent) buildQKeyEvent(); return m_keyEvent; } - - //Legacy key stuff... - virtual int keyCode() const = 0; - virtual int charCode() const = 0; - - //### KDE4: remove these 2 - void initModifier(unsigned long modifierArg, bool valueArg); - bool checkModifier(unsigned long modifierArg); - - ~KeyEventBaseImpl(); - - //Returns true if the event was synthesized by client use of DOM - bool isSynthetic() const { return m_synthetic; } -protected: - KeyEventBaseImpl(): m_keyEvent(0), m_keyVal(0), m_virtKeyVal(0), m_modifier(0), m_synthetic(false) - { m_detail = 0; } - - KeyEventBaseImpl(EventId id, - bool canBubbleArg, - bool cancelableArg, - AbstractViewImpl *viewArg, - TQKeyEvent *key); - - - mutable TQKeyEvent *m_keyEvent; - unsigned long m_keyVal; //Unicode key value - unsigned long m_virtKeyVal; //Virtual key value for keys like arrows, Fn, etc. - - // bitfield containing state of modifiers. not part of the dom. - unsigned long m_modifier; - - bool m_synthetic; - - void buildQKeyEvent() const; //Construct a Qt key event from m_keyVal/m_virtKeyVal -}; - -class TextEventImpl : public KeyEventBaseImpl { -public: - TextEventImpl(); - - TextEventImpl(TQKeyEvent* key, DOM::AbstractViewImpl* view); - - void initTextEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - const DOMString& text); - - virtual bool isTextInputEvent() const; - - //Legacy key stuff... - int keyCode() const; - int charCode() const; - - DOMString data() const { return m_outputString; } -private: - DOMString m_outputString; -}; - -class KeyboardEventImpl : public KeyEventBaseImpl { -public: - KeyboardEventImpl(); - KeyboardEventImpl(TQKeyEvent* key, DOM::AbstractViewImpl* view); - - virtual bool isKeyboardEvent() const; - - enum KeyLocation { - DOM_KEY_LOCATION_STANDARD = 0x00, - DOM_KEY_LOCATION_LEFT = 0x01, - DOM_KEY_LOCATION_RIGHT = 0x02, - DOM_KEY_LOCATION_NUMPAD = 0x03 - }; - - //Legacy key stuff... - int keyCode() const; - int charCode() const; - - DOMString keyIdentifier() const; - unsigned long keyLocation() const { return m_keyLocation; } - - bool getModifierState(const DOMString& keyIdentifierArg) const; - - void initKeyboardEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - const DOMString &keyIdentifierArg, - unsigned long keyLocationArg, - const DOMString& modifiersList); - - //### KDE4: remove this, it's only for compatibility with - //the old TextEvent wrapper - void initKeyboardEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const AbstractView &viewArg, - unsigned long keyVal, - unsigned long virtKeyVal, - unsigned long modifiers, - unsigned long keyLocationArg) { - initKeyBaseEvent(typeArg, canBubbleArg, cancelableArg, viewArg, - keyVal, virtKeyVal, modifiers); - m_keyLocation = keyLocationArg; - } -private: - unsigned long m_keyLocation; -}; - - - -class MutationEventImpl : public EventImpl { -// ### fire these during parsing (if necessary) -public: - MutationEventImpl(); - MutationEventImpl(EventId _id, - bool canBubbleArg, - bool cancelableArg, - const Node &relatedNodeArg, - const DOMString &prevValueArg, - const DOMString &newValueArg, - const DOMString &attrNameArg, - unsigned short attrChangeArg); - ~MutationEventImpl(); - - Node relatedNode() const { return m_relatedNode; } - DOMString prevValue() const { return m_prevValue; } - DOMString newValue() const { return m_newValue; } - DOMString attrName() const { return m_attrName; } - unsigned short attrChange() const { return m_attrChange; } - void initMutationEvent(const DOMString &typeArg, - bool canBubbleArg, - bool cancelableArg, - const Node &relatedNodeArg, - const DOMString &prevValueArg, - const DOMString &newValueArg, - const DOMString &attrNameArg, - unsigned short attrChangeArg); - virtual bool isMutationEvent() const; -protected: - NodeImpl *m_relatedNode; - DOMStringImpl *m_prevValue; - DOMStringImpl *m_newValue; - DOMStringImpl *m_attrName; - unsigned short m_attrChange; -}; - - -class RegisteredEventListener { -public: - RegisteredEventListener() : id(EventImpl::EventId(0)), useCapture(false), listener(0) {} - - RegisteredEventListener(EventImpl::EventId _id, EventListener *_listener, bool _useCapture) - : id(_id), useCapture(_useCapture), listener(_listener) { if (listener) listener->ref(); } - - ~RegisteredEventListener() { if (listener) listener->deref(); listener = 0; } - - bool operator==(const RegisteredEventListener &other) const - { return id == other.id && listener == other.listener && useCapture == other.useCapture; } - - - EventImpl::EventId id : 6; - bool useCapture; - EventListener *listener; - - RegisteredEventListener( const RegisteredEventListener &other ) : - id(other.id), useCapture(other.useCapture), listener(other.listener) - { if (listener) listener->ref(); } - - RegisteredEventListener & operator=( const RegisteredEventListener &other ) { - id = other.id; - useCapture = other.useCapture; - if (other.listener) - other.listener->ref(); - if (listener) - listener->deref(); - listener = other.listener; - return *this; - } -}; - - - -} //namespace -#endif diff --git a/khtml/xml/dom2_rangeimpl.cpp b/khtml/xml/dom2_rangeimpl.cpp deleted file mode 100644 index b160ce23f..000000000 --- a/khtml/xml/dom2_rangeimpl.cpp +++ /dev/null @@ -1,1640 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 2001-2003 Dirk Mueller (mueller@kde.org) - * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) - * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) - * (C) 2001 Peter Kelly (pmk@post.com) - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "dom/dom_exception.h" -#include "dom_docimpl.h" -#include "dom2_rangeimpl.h" -#include "dom_textimpl.h" -#include "dom_xmlimpl.h" -#include "html/html_elementimpl.h" -#include "misc/htmltags.h" - -using namespace DOM; - - -RangeImpl::RangeImpl(DocumentImpl *_ownerDocument) -{ - m_ownerDocument = _ownerDocument; - m_ownerDocument->ref(); - m_startContainer = _ownerDocument; - m_startContainer->ref(); - m_endContainer = _ownerDocument; - m_endContainer->ref(); - m_startOffset = 0; - m_endOffset = 0; - m_detached = false; -} - -RangeImpl::RangeImpl(DocumentImpl *_ownerDocument, - NodeImpl *_startContainer, long _startOffset, - NodeImpl *_endContainer, long _endOffset) -{ - m_ownerDocument = _ownerDocument; - m_ownerDocument->ref(); - m_startContainer = _startContainer; - m_startContainer->ref(); - m_startOffset = _startOffset; - m_endContainer = _endContainer; - m_endContainer->ref(); - m_endOffset = _endOffset; - m_detached = false; -} - -RangeImpl::~RangeImpl() -{ - m_ownerDocument->deref(); - int exceptioncode = 0; - if (!m_detached) - detach(exceptioncode); -} - -NodeImpl *RangeImpl::startContainer(int &exceptioncode) const -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - return m_startContainer; -} - -long RangeImpl::startOffset(int &exceptioncode) const -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - return m_startOffset; -} - -NodeImpl *RangeImpl::endContainer(int &exceptioncode) const -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - return m_endContainer; -} - -long RangeImpl::endOffset(int &exceptioncode) const -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - return m_endOffset; -} - -NodeImpl *RangeImpl::commonAncestorContainer(int &exceptioncode) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - NodeImpl *com = commonAncestorContainer(m_startContainer,m_endContainer); - if (!com) // should never happen - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return com; -} - -NodeImpl *RangeImpl::commonAncestorContainer(NodeImpl *containerA, NodeImpl *containerB) -{ - NodeImpl *parentStart; - - for (parentStart = containerA; parentStart; parentStart = parentStart->parentNode()) { - NodeImpl *parentEnd = containerB; - while( parentEnd && (parentStart != parentEnd) ) - parentEnd = parentEnd->parentNode(); - - if(parentStart == parentEnd) break; - } - - return parentStart; -} - -bool RangeImpl::collapsed(int &exceptioncode) const -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - return (m_startContainer == m_endContainer && m_startOffset == m_endOffset); -} - -void RangeImpl::setStart( NodeImpl *refNode, long offset, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if (!refNode) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - if (refNode->getDocument() != m_ownerDocument) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return; - } - - checkNodeWOffset( refNode, offset, exceptioncode ); - if (exceptioncode) - return; - - setStartContainer(refNode); - m_startOffset = offset; - - // check if different root container - NodeImpl *endRootContainer = m_endContainer; - while (endRootContainer->parentNode()) - endRootContainer = endRootContainer->parentNode(); - NodeImpl *startRootContainer = m_startContainer; - while (startRootContainer->parentNode()) - startRootContainer = startRootContainer->parentNode(); - if (startRootContainer != endRootContainer) - collapse(true,exceptioncode); - // check if new start after end - else if (compareBoundaryPoints(m_startContainer,m_startOffset,m_endContainer,m_endOffset) > 0) - collapse(true,exceptioncode); -} - -void RangeImpl::setEnd( NodeImpl *refNode, long offset, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if (!refNode) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - if (refNode->getDocument() != m_ownerDocument) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return; - } - - checkNodeWOffset( refNode, offset, exceptioncode ); - if (exceptioncode) - return; - - setEndContainer(refNode); - m_endOffset = offset; - - // check if different root container - NodeImpl *endRootContainer = m_endContainer; - while (endRootContainer->parentNode()) - endRootContainer = endRootContainer->parentNode(); - NodeImpl *startRootContainer = m_startContainer; - while (startRootContainer->parentNode()) - startRootContainer = startRootContainer->parentNode(); - if (startRootContainer != endRootContainer) - collapse(false,exceptioncode); - // check if new end before start - if (compareBoundaryPoints(m_startContainer,m_startOffset,m_endContainer,m_endOffset) > 0) - collapse(false,exceptioncode); -} - -void RangeImpl::collapse( bool toStart, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if( toStart ) // collapse to start - { - setEndContainer(m_startContainer); - m_endOffset = m_startOffset; - } - else // collapse to end - { - setStartContainer(m_endContainer); - m_startOffset = m_endOffset; - } -} - -short RangeImpl::compareBoundaryPoints( Range::CompareHow how, RangeImpl *sourceRange, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - if (!sourceRange) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return 0; - } - - NodeImpl *thisCont = commonAncestorContainer(exceptioncode); - NodeImpl *sourceCont = sourceRange->commonAncestorContainer(exceptioncode); - if (exceptioncode) - return 0; - - if (thisCont->getDocument() != sourceCont->getDocument()) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return 0; - } - - NodeImpl *thisTop = thisCont; - NodeImpl *sourceTop = sourceCont; - while (thisTop->parentNode()) - thisTop = thisTop->parentNode(); - while (sourceTop->parentNode()) - sourceTop = sourceTop->parentNode(); - if (thisTop != sourceTop) { // in different DocumentFragments - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return 0; - } - - switch(how) - { - case Range::START_TO_START: - return compareBoundaryPoints( m_startContainer, m_startOffset, - sourceRange->startContainer(exceptioncode), sourceRange->startOffset(exceptioncode) ); - break; - case Range::START_TO_END: - return compareBoundaryPoints( m_startContainer, m_startOffset, - sourceRange->endContainer(exceptioncode), sourceRange->endOffset(exceptioncode) ); - break; - case Range::END_TO_END: - return compareBoundaryPoints( m_endContainer, m_endOffset, - sourceRange->endContainer(exceptioncode), sourceRange->endOffset(exceptioncode) ); - break; - case Range::END_TO_START: - return compareBoundaryPoints( m_endContainer, m_endOffset, - sourceRange->startContainer(exceptioncode), sourceRange->startOffset(exceptioncode) ); - break; - default: - exceptioncode = DOMException::SYNTAX_ERR; - return 0; - } -} - -short RangeImpl::compareBoundaryPoints( NodeImpl *containerA, long offsetA, NodeImpl *containerB, long offsetB ) -{ - // see DOM2 traversal & range section 2.5 - - // case 1: both points have the same container - if( containerA == containerB ) - { - if( offsetA == offsetB ) return 0; // A is equal to B - if( offsetA < offsetB ) return -1; // A is before B - else return 1; // A is after B - } - - // case 2: node C (container B or an ancestor) is a child node of A - NodeImpl *c = containerB; - while (c && c->parentNode() != containerA) - c = c->parentNode(); - if (c) { - int offsetC = 0; - NodeImpl* n = containerA->firstChild(); - while (n != c) { - offsetC++; - n = n->nextSibling(); - } - - if( offsetA <= offsetC ) return -1; // A is before B - else return 1; // A is after B - } - - // case 3: node C (container A or an ancestor) is a child node of B - c = containerA; - while (c && c->parentNode() != containerB) - c = c->parentNode(); - if (c) { - int offsetC = 0; - NodeImpl* n = containerB->firstChild(); - while (n != c) { - offsetC++; - n = n->nextSibling(); - } - - if( offsetC < offsetB ) return -1; // A is before B - else return 1; // A is after B - } - - // case 4: containers A & B are siblings, or children of siblings - // ### we need to do a traversal here instead - NodeImpl *cmnRoot = commonAncestorContainer(containerA,containerB); - if (!cmnRoot) return -1; // Whatever... - NodeImpl *childA = containerA; - while (childA->parentNode() != cmnRoot) - childA = childA->parentNode(); - NodeImpl *childB = containerB; - while (childB->parentNode() != cmnRoot) - childB = childB->parentNode(); - - NodeImpl *n = cmnRoot->firstChild(); - int i = 0; - int childAOffset = -1; - int childBOffset = -1; - while (childAOffset < 0 || childBOffset < 0) { - if (n == childA) - childAOffset = i; - if (n == childB) - childBOffset = i; - n = n->nextSibling(); - i++; - } - - if( childAOffset == childBOffset ) return 0; // A is equal to B - if( childAOffset < childBOffset ) return -1; // A is before B - else return 1; // A is after B -} - -bool RangeImpl::boundaryPointsValid( ) -{ - short valid = compareBoundaryPoints( m_startContainer, m_startOffset, - m_endContainer, m_endOffset ); - if( valid == 1 ) return false; - else return true; - -} - -void RangeImpl::deleteContents( int &exceptioncode ) { - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - checkDeleteExtract(exceptioncode); - if (exceptioncode) - return; - - processContents(DELETE_CONTENTS,exceptioncode); -} - -DocumentFragmentImpl *RangeImpl::processContents ( ActionType action, int &exceptioncode ) -{ - // ### when mutation events are implemented, we will have to take into account - // situations where the tree is being transformed while we delete - ugh! - - // ### perhaps disable node deletion notification for this range while we do this? - - if (collapsed(exceptioncode)) - return 0; - if (exceptioncode) - return 0; - - NodeImpl *cmnRoot = commonAncestorContainer(exceptioncode); - if (exceptioncode) - return 0; - - // what is the highest node that partially selects the start of the range? - NodeImpl *partialStart = 0; - if (m_startContainer != cmnRoot) { - partialStart = m_startContainer; - while (partialStart->parentNode() != cmnRoot) - partialStart = partialStart->parentNode(); - } - - // what is the highest node that partially selects the end of the range? - NodeImpl *partialEnd = 0; - if (m_endContainer != cmnRoot) { - partialEnd = m_endContainer; - while (partialEnd->parentNode() != cmnRoot) - partialEnd = partialEnd->parentNode(); - } - - DocumentFragmentImpl *fragment = 0; - if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) - fragment = new DocumentFragmentImpl(m_ownerDocument); - - // Simple case: the start and end containers are the same. We just grab - // everything >= start offset and < end offset - if (m_startContainer == m_endContainer) { - if(m_startContainer->nodeType() == Node::TEXT_NODE || - m_startContainer->nodeType() == Node::CDATA_SECTION_NODE || - m_startContainer->nodeType() == Node::COMMENT_NODE) { - - if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { - CharacterDataImpl *c = static_cast<CharacterDataImpl*>(m_startContainer->cloneNode(true)); - c->deleteData(m_endOffset,static_cast<CharacterDataImpl*>(m_startContainer)->length()-m_endOffset,exceptioncode); - c->deleteData(0,m_startOffset,exceptioncode); - fragment->appendChild(c,exceptioncode); - } - if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) - static_cast<CharacterDataImpl*>(m_startContainer)->deleteData(m_startOffset,m_endOffset-m_startOffset,exceptioncode); - } - else if (m_startContainer->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) { - // ### operate just on data ? - } - else { - NodeImpl *n = m_startContainer->firstChild(); - unsigned long i; - for(i = 0; i < m_startOffset; i++) // skip until m_startOffset - n = n->nextSibling(); - while (n && i < m_endOffset) { // delete until m_endOffset - NodeImpl *next = n->nextSibling(); - if (action == EXTRACT_CONTENTS) - fragment->appendChild(n,exceptioncode); // will remove n from its parent - else if (action == CLONE_CONTENTS) - fragment->appendChild(n->cloneNode(true),exceptioncode); - else - m_startContainer->removeChild(n,exceptioncode); - n = next; - i++; - } - } - collapse(true,exceptioncode); - return fragment; - } - - // Complex case: Start and end containers are different. - // There are three possiblities here: - // 1. Start container == cmnRoot (End container must be a descendant) - // 2. End container == cmnRoot (Start container must be a descendant) - // 3. Neither is cmnRoot, they are both descendants - // - // In case 3, we grab everything after the start (up until a direct child - // of cmnRoot) into leftContents, and everything before the end (up until - // a direct child of cmnRoot) into rightContents. Then we process all - // cmnRoot children between leftContents and rightContents - // - // In case 1 or 2, we skip either processing of leftContents or rightContents, - // in which case the last lot of nodes either goes from the first or last - // child of cmnRoot. - // - // These are deleted, cloned, or extracted (i.e. both) depending on action. - - NodeImpl *leftContents = 0; - if (m_startContainer != cmnRoot) { - // process the left-hand side of the range, up until the last ancestor of - // m_startContainer before cmnRoot - if(m_startContainer->nodeType() == Node::TEXT_NODE || - m_startContainer->nodeType() == Node::CDATA_SECTION_NODE || - m_startContainer->nodeType() == Node::COMMENT_NODE) { - - if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { - CharacterDataImpl *c = static_cast<CharacterDataImpl*>(m_startContainer->cloneNode(true)); - c->deleteData(0,m_startOffset,exceptioncode); - leftContents = c; - } - if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) - static_cast<CharacterDataImpl*>(m_startContainer)->deleteData( - m_startOffset,static_cast<CharacterDataImpl*>(m_startContainer)->length()-m_startOffset,exceptioncode); - } - else if (m_startContainer->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) { - // ### operate just on data ? - // leftContents = ... - } - else { - if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) - leftContents = m_startContainer->cloneNode(false); - NodeImpl *n = m_startContainer->firstChild(); - unsigned long i; - for(i = 0; i < m_startOffset; i++) // skip until m_startOffset - n = n->nextSibling(); - while (n) { // process until end - NodeImpl *next = n->nextSibling(); - if (action == EXTRACT_CONTENTS) - leftContents->appendChild(n,exceptioncode); // will remove n from m_startContainer - else if (action == CLONE_CONTENTS) - leftContents->appendChild(n->cloneNode(true),exceptioncode); - else - m_startContainer->removeChild(n,exceptioncode); - n = next; - } - } - - NodeImpl *leftParent = m_startContainer->parentNode(); - NodeImpl *n = m_startContainer->nextSibling(); - for (; leftParent != cmnRoot; leftParent = leftParent->parentNode()) { - if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { - NodeImpl *leftContentsParent = leftParent->cloneNode(false); - leftContentsParent->appendChild(leftContents,exceptioncode); - leftContents = leftContentsParent; - } - - NodeImpl *next; - for (; n; n = next ) { - next = n->nextSibling(); - if (action == EXTRACT_CONTENTS) - leftContents->appendChild(n,exceptioncode); // will remove n from leftParent - else if (action == CLONE_CONTENTS) - leftContents->appendChild(n->cloneNode(true),exceptioncode); - else - leftParent->removeChild(n,exceptioncode); - } - n = leftParent->nextSibling(); - } - } - - NodeImpl *rightContents = 0; - if (m_endContainer != cmnRoot) { - // delete the right-hand side of the range, up until the last ancestor of - // m_endContainer before cmnRoot - if(m_endContainer->nodeType() == Node::TEXT_NODE || - m_endContainer->nodeType() == Node::CDATA_SECTION_NODE || - m_endContainer->nodeType() == Node::COMMENT_NODE) { - - if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { - CharacterDataImpl *c = static_cast<CharacterDataImpl*>(m_endContainer->cloneNode(true)); - c->deleteData(m_endOffset,static_cast<CharacterDataImpl*>(m_endContainer)->length()-m_endOffset,exceptioncode); - rightContents = c; - } - if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) - static_cast<CharacterDataImpl*>(m_endContainer)->deleteData(0,m_endOffset,exceptioncode); - } - else if (m_startContainer->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) { - // ### operate just on data ? - // rightContents = ... - } - else { - if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) - rightContents = m_endContainer->cloneNode(false); - NodeImpl *n = m_endContainer->firstChild(); - unsigned long i; - for(i = 0; i+1 < m_endOffset; i++) // skip to m_endOffset - n = n->nextSibling(); - NodeImpl *prev; - for (; n; n = prev ) { - prev = n->previousSibling(); - if (action == EXTRACT_CONTENTS) - rightContents->insertBefore(n,rightContents->firstChild(),exceptioncode); // will remove n from its parent - else if (action == CLONE_CONTENTS) - rightContents->insertBefore(n->cloneNode(true),rightContents->firstChild(),exceptioncode); - else - m_endContainer->removeChild(n,exceptioncode); - } - } - - NodeImpl *rightParent = m_endContainer->parentNode(); - NodeImpl *n = m_endContainer->previousSibling(); - for (; rightParent != cmnRoot; rightParent = rightParent->parentNode()) { - if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { - NodeImpl *rightContentsParent = rightParent->cloneNode(false); - rightContentsParent->appendChild(rightContents,exceptioncode); - rightContents = rightContentsParent; - } - - NodeImpl *prev; - for (; n; n = prev ) { - prev = n->previousSibling(); - if (action == EXTRACT_CONTENTS) - rightContents->insertBefore(n,rightContents->firstChild(),exceptioncode); // will remove n from its parent - else if (action == CLONE_CONTENTS) - rightContents->insertBefore(n->cloneNode(true),rightContents->firstChild(),exceptioncode); - else - rightParent->removeChild(n,exceptioncode); - - } - n = rightParent->previousSibling(); - } - } - - // delete all children of cmnRoot between the start and end container - - NodeImpl *processStart; // child of cmnRooot - if (m_startContainer == cmnRoot) { - unsigned long i; - processStart = m_startContainer->firstChild(); - for (i = 0; i < m_startOffset; i++) - processStart = processStart->nextSibling(); - } - else { - processStart = m_startContainer; - while (processStart->parentNode() != cmnRoot) - processStart = processStart->parentNode(); - processStart = processStart->nextSibling(); - } - NodeImpl *processEnd; // child of cmnRooot - if (m_endContainer == cmnRoot) { - unsigned long i; - processEnd = m_endContainer->firstChild(); - for (i = 0; i < m_endOffset; i++) - processEnd = processEnd->nextSibling(); - } - else { - processEnd = m_endContainer; - while (processEnd->parentNode() != cmnRoot) - processEnd = processEnd->parentNode(); - } - - // Now add leftContents, stuff in between, and rightContents to the fragment - // (or just delete the stuff in between) - - if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && leftContents) - fragment->appendChild(leftContents,exceptioncode); - - NodeImpl *next; - NodeImpl *n; - if (processStart) { - for (n = processStart; n && n != processEnd; n = next) { - next = n->nextSibling(); - - if (action == EXTRACT_CONTENTS) - fragment->appendChild(n,exceptioncode); // will remove from cmnRoot - else if (action == CLONE_CONTENTS) - fragment->appendChild(n->cloneNode(true),exceptioncode); - else - cmnRoot->removeChild(n,exceptioncode); - } - } - - if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && rightContents) - fragment->appendChild(rightContents,exceptioncode); - - // collapse to the proper position - see spec section 2.6 - if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) { - if (!partialStart && !partialEnd) - collapse(true,exceptioncode); - else if (partialStart) { - setStartContainer(partialStart->parentNode()); - setEndContainer(partialStart->parentNode()); - m_startOffset = m_endOffset = partialStart->nodeIndex()+1; - } - else if (partialEnd) { - setStartContainer(partialEnd->parentNode()); - setEndContainer(partialEnd->parentNode()); - m_startOffset = m_endOffset = partialEnd->nodeIndex(); - } - } - return fragment; -} - - -DocumentFragmentImpl *RangeImpl::extractContents( int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - checkDeleteExtract(exceptioncode); - if (exceptioncode) - return 0; - - return processContents(EXTRACT_CONTENTS,exceptioncode); -} - -DocumentFragmentImpl *RangeImpl::cloneContents( int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - return processContents(CLONE_CONTENTS,exceptioncode); -} - -void RangeImpl::insertNode( NodeImpl *newNode, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - // NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of either boundary-point of - // the Range is read-only. - NodeImpl *n = m_startContainer; - while (n && !n->isReadOnly()) - n = n->parentNode(); - if (n) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - n = m_endContainer; - while (n && !n->isReadOnly()) - n = n->parentNode(); - if (n) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - // WRONG_DOCUMENT_ERR: Raised if newParent and the container of the start of the Range were - // not created from the same document. - if (newNode->getDocument() != m_startContainer->getDocument()) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return; - } - - - // HIERARCHY_REQUEST_ERR: Raised if the container of the start of the Range is of a type that - // does not allow children of the type of newNode or if newNode is an ancestor of the container. - - // an extra one here - if a text node is going to split, it must have a parent to insert into - if (m_startContainer->nodeType() == Node::TEXT_NODE && !m_startContainer->parentNode()) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - - // In the case where the container is a text node, we check against the container's parent, because - // text nodes get split up upon insertion. - NodeImpl *checkAgainst; - if (m_startContainer->nodeType() == Node::TEXT_NODE) - checkAgainst = m_startContainer->parentNode(); - else - checkAgainst = m_startContainer; - - if (newNode->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) { - // check each child node, not the DocumentFragment itself - NodeImpl *c; - for (c = newNode->firstChild(); c; c = c->nextSibling()) { - if (!checkAgainst->childTypeAllowed(c->nodeType())) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - } - } - else { - if (!checkAgainst->childTypeAllowed(newNode->nodeType())) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - } - - for (n = m_startContainer; n; n = n->parentNode()) { - if (n == newNode) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - } - - // INVALID_NODE_TYPE_ERR: Raised if newNode is an Attr, Entity, Notation, or Document node. - if( newNode->nodeType() == Node::ATTRIBUTE_NODE || - newNode->nodeType() == Node::ENTITY_NODE || - newNode->nodeType() == Node::NOTATION_NODE || - newNode->nodeType() == Node::DOCUMENT_NODE) { - exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET; - return; - } - - if( m_startContainer->nodeType() == Node::TEXT_NODE || - m_startContainer->nodeType() == Node::CDATA_SECTION_NODE ) - { - TextImpl *newText = static_cast<TextImpl*>(m_startContainer)->splitText(m_startOffset,exceptioncode); - if (exceptioncode) - return; - m_startContainer->parentNode()->insertBefore( newNode, newText, exceptioncode ); - } - else { - m_startContainer->insertBefore( newNode, m_startContainer->childNode( m_startOffset ), exceptioncode ); - } -} - -DOMString RangeImpl::toString( int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return DOMString(); - } - - DOMString text = ""; - NodeImpl *n = m_startContainer; - - /* This function converts a dom range to the plain text string that the user would see in this - * portion of rendered html. - * - * There are several ways ranges can be used. - * - * The simplest is the start and endContainer is a text node. The start and end offset is the - * number of characters into the text to remove/truncate. - * - * The next case is the start and endContainer is, well, a container, such a P tag or DIV tag. - * In this case the start and end offset is the number of children into the container to start - * from and end at. - * - * The other cases are different arrangements of the first two. - * - * psuedo code: - * - * if start container is not text: - * count through the children to find where we start (m_startOffset children) - * - * loop from the start position: - * if the current node is text, add the text to our variable 'text', truncating/removing if at the end/start. - * - * if the node has children, step to the first child. - * if the node has no children but does have siblings, step to the next sibling - * until we find a sibling, go to next the parent but: - * make sure this sibling isn't past the end of where we are supposed to go. (position > endOffset and the parent is the endContainer) - * - */ - - - if( m_startContainer == m_endContainer && m_startOffset >= m_endOffset) - return text; - - - if(n->firstChild()) { - n = n->firstChild(); - int current_offset = m_startOffset; - while(current_offset-- && n) { - n = n->nextSibling(); - } - } - - while(n) { - if(n->nodeType() == DOM::Node::TEXT_NODE || - n->nodeType() == DOM::Node::CDATA_SECTION_NODE) { - - DOMString str; - str = static_cast<TextImpl *>(n)->string(); - if( n == m_endContainer || n == m_startContainer) - str = str.copy(); //copy if we are going to modify. - - if (n == m_endContainer) - str.truncate(m_endOffset); - if (n == m_startContainer) - str.remove(0,m_startOffset); - text += str; - if (n == m_endContainer) - break; - } - - - NodeImpl *next = n->firstChild(); - if(!next) - next = n->nextSibling(); - - while( !next && n->parentNode() ) { - if (n == m_endContainer) return text; - n = n->parentNode(); - if (n == m_endContainer) return text; - next = n->nextSibling(); - } - - if(n->parentNode() == m_endContainer) { - if(!next) break; - unsigned long current_offset = 0; - NodeImpl *it = n; - while((it = it->previousSibling())) ++current_offset; - if(current_offset >= m_endOffset) { - break; - } - } - - n = next; - } - return text; -} - -DOMString RangeImpl::toHTML( int &exceptioncode ) -{ - bool hasHtmlTag = false; - bool hasBodyTag = false; - //FIXME: What is this section of code below exactly? Do I want it here? - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return DOMString(); - } - DOMString text = ""; - NodeImpl *n = m_startContainer; - int num_tables=0; - bool in_li = false; //whether we have an li in the text, without an ol/ul - int depth_difference = 0; - int lowest_depth_difference = 0; - - if( m_startContainer == m_endContainer && m_startOffset >= m_endOffset) - return text; - - while(n) { - /* First, we could have an tag <tagname key=value>otherstuff</tagname> */ - if(n->nodeType() == DOM::Node::ELEMENT_NODE) { - int elementId = static_cast<ElementImpl *>(n)->id(); - if(elementId == ID_TABLE) num_tables++; - if(elementId == ID_BODY) hasBodyTag = true; - if(elementId == ID_HTML) hasHtmlTag = true; - if(elementId == ID_LI) in_li=true; - if(num_tables==0 && ( elementId == ID_TD || elementId == ID_TR || elementId == ID_TH || elementId == ID_TBODY || elementId == ID_TFOOT || elementId == ID_THEAD)) num_tables++; - if(!( !n->hasChildNodes() && (elementId == ID_H1 || elementId == ID_H2 || elementId == ID_H3 || elementId == ID_H4 || elementId ==ID_H5))) { //Don't add <h1/> etc. Just skip these nodes just to make the output html a bit nicer. - text += static_cast<ElementImpl *>(n)->openTagStartToString(true /*safely expand img urls*/); // adds "<tagname key=value" - if(n->hasChildNodes()) { - depth_difference++; - text += ">"; - } else { - text += "/>"; - } - } - } else - if(n->nodeType() == DOM::Node::TEXT_NODE || - n->nodeType() == DOM::Node::CDATA_SECTION_NODE) { - if(n->nodeType() == DOM::Node::CDATA_SECTION_NODE) text += "<![CDATA[ "; - long long startOffset = (n == m_startContainer)?(long long)m_startOffset:-1; - long long endOffset = (n == m_endContainer)?(long long) m_endOffset:-1; - text += static_cast<TextImpl *>(n)->toString(startOffset, endOffset); //Note this should always work since CDataImpl inherits TextImpl - if(n->nodeType() == DOM::Node::CDATA_SECTION_NODE) text += " ]]>"; - if(n == m_endContainer) { - break; - } - } - if(n->parentNode() == m_endContainer && !n->nextSibling()) { - break; - } - - //if (n == m_endContainer) break; - NodeImpl *next = n->firstChild(); - if(next) { - if(n == m_startContainer) { - //This is the start of our selection, so we have to move to where we have started selecting. - //For example, if 'n' is "hello <img src='hello.png'> how are you? <img src='goodbye.png'>" - //then this has four children. If our selection started on the image, then we need to start from there. - unsigned long current_offset = 0; - while(current_offset < m_startOffset && next) { - next = next->nextSibling(); - ++current_offset; - } - } - } else { - next = n->nextSibling(); - - if(n->parentNode() == m_endContainer) { - unsigned long current_offset = 1; - NodeImpl *it = n; - while((it = it->previousSibling())) ++current_offset; - - if(current_offset >= m_endOffset) { - break; - } - } - } - - while( !next && n->parentNode() ) { - n = n->parentNode(); - if(n->nodeType() == DOM::Node::ELEMENT_NODE) { - text += "</"; - text += static_cast<ElementImpl *>(n)->tagName(); - int elementId = static_cast<ElementImpl *>(n)->id(); - if(elementId == ID_TABLE) num_tables--; - depth_difference--; - if(lowest_depth_difference > depth_difference) lowest_depth_difference=depth_difference; - if(num_tables==0 && ( elementId == ID_TD || elementId == ID_TR || elementId == ID_TH || elementId == ID_TBODY || elementId == ID_TFOOT || elementId == ID_THEAD)) num_tables--; - if(elementId == ID_OL || elementId == ID_UL) in_li=false; - text += ">"; - } - next = n->nextSibling(); - } - n = next; - } - - //We have the html in the selection. But now we need to properly add the opening and closing tags. - //For example say we have: "Hello <b>Mr. John</b> How are you?" and we select "John" or even - //"John</b> How" and copy. We want to return "<b>John</b>" and "<b>John</b> How" respectively - - //To do this, we need to go up the tree from the start, and prepend those tags. - //Imagine our selection was this: - // - // hello</b></p><p>there - // - // The difference in depths between the start and end is -1, and the lowest depth - // difference from the starting point is -2 - // - // So from the start of the selection, we want to go down to the lowest_depth_difference - // and prepend those tags. (<p><b>) - // - // From the end of the selection, we want to also go down to the lowest_depth_difference. - // We know the depth of the end of the selection - i.e. depth_difference. - // - // - n = m_startContainer; - int startdepth = 0; //by definition - we are counting from zero. - while((n = n->parentNode()) && startdepth>lowest_depth_difference) { - if(n->nodeType() == DOM::Node::ELEMENT_NODE) { //This should always be true.. right? - switch (static_cast<ElementImpl *>(n)->id()) { - case ID_TABLE: - num_tables--; - break; - case ID_BODY: - hasBodyTag = true; - break; - case ID_HTML: - hasHtmlTag = true; - break; - case ID_LI: - in_li = true; - break; - } - text = static_cast<ElementImpl *>(n)->openTagStartToString(true /*expand img urls*/)+">" +text; // prepends "<tagname key=value>" - } - startdepth--; - } - n = m_endContainer; - while( depth_difference>lowest_depth_difference && (n = n->parentNode())) { - if(n->nodeType() == DOM::Node::ELEMENT_NODE) { //This should always be true.. right? - switch (static_cast<ElementImpl *>(n)->id()) { - case ID_TABLE: - num_tables++; - break; - case ID_OL: - case ID_UL: - in_li=false; - break; - } - text += "</"; - text += static_cast<ElementImpl *>(n)->tagName(); - text += ">"; - } - depth_difference--; - } - - // Now our text string is the same depth on both sides, with nothing lower (in other words all the - // tags in it match up.) This also means that the end value for n in the first loop is a sibling of the - // end value for n in the second loop. - // - // We now need to go down the tree, and for certain tags, add them in on both ends of the text. - // For example, if have: "<b>hello</b>" and we select "ll", then we want to go down the tree and - // add "<b>" and "</b>" to it, to produce "<b>ll</b>". - // - // I just guessed at which tags you'd want to keep (bold, italic etc) and which you wouldn't (tables etc). - // It's just wild guessing. feel free to change. - // - // Note we can carry on with the value of n - if(n) { - while((n = n->parentNode())) { - if(n->nodeType() == DOM::Node::ELEMENT_NODE) { //This should always be true.. right? - int elementId = static_cast<ElementImpl *>(n)->id(); - switch (elementId) { - case ID_TABLE: - case ID_TD: - case ID_TR: - case ID_TH: - case ID_TBODY: - case ID_TFOOT: - case ID_THEAD: - if(num_tables>0) { - if(elementId == ID_TABLE) num_tables--; - text = static_cast<ElementImpl *>(n)->openTagStartToString(true /*expand img urls*/)+">" +text; - text += "</"; - text += static_cast<ElementImpl *>(n)->tagName(); - text += ">"; - - } - break; - - case ID_LI: - if(!in_li) break; - text = static_cast<ElementImpl *>(n)->openTagStartToString(true /*expand img urls*/)+">" +text; - text += "</"; - text += static_cast<ElementImpl *>(n)->tagName(); - text += ">"; - break; - - case ID_UL: - case ID_OL: - if(!in_li) break; - in_li = false; - case ID_B: - case ID_I: - case ID_U: - case ID_FONT: - case ID_S: - case ID_STRONG: - case ID_STRIKE: - case ID_DEL: - case ID_A: - case ID_H1: - case ID_H2: - case ID_H3: - case ID_H4: - case ID_H5: - //should small, etc be here? so hard to decide. this is such a hack :( - //There's probably tons of others you'd want here. - text = static_cast<ElementImpl *>(n)->openTagStartToString(true /*expand img urls*/)+">" +text; - text += "</"; - text += static_cast<ElementImpl *>(n)->tagName(); - text += ">"; - break; - } - } - } - } - - - if(!hasBodyTag) text = DOMString("<body>") + text + "</body>"; - else if(!hasHtmlTag) { - text = DOMString("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" - "<head>\n" - "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" - "<meta name=\"Generator\" content=\"KHTML, the KDE Web Page Viewer\" />\n" - "</head>\n") + - text + - "</html>"; - } - text = DOMString("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n") + text; - - return text; - -} - -DocumentFragment RangeImpl::createContextualFragment ( const DOMString &html, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return DocumentFragment(); - } - - if (! m_startContainer->isHTMLElement()) { - exceptioncode = DOMException::NOT_SUPPORTED_ERR; - return DocumentFragment(); - } - - HTMLElementImpl *e = static_cast<HTMLElementImpl *>(m_startContainer); - DocumentFragment fragment = e->createContextualFragment(html); - if (fragment.isNull()) { - exceptioncode = DOMException::NOT_SUPPORTED_ERR; - return DocumentFragment(); - } - - return fragment; -} - - -void RangeImpl::detach( int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if (m_startContainer) - m_startContainer->deref(); - m_startContainer = 0; - if (m_endContainer) - m_endContainer->deref(); - m_endContainer = 0; - m_detached = true; -} - -bool RangeImpl::isDetached() const -{ - return m_detached; -} - -void RangeImpl::checkNodeWOffset( NodeImpl *n, int offset, int &exceptioncode) const -{ - if( offset < 0 ) { - exceptioncode = DOMException::INDEX_SIZE_ERR; - } - - switch (n->nodeType()) { - case Node::ENTITY_NODE: - case Node::NOTATION_NODE: - case Node::DOCUMENT_TYPE_NODE: - exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET; - break; - case Node::TEXT_NODE: - case Node::COMMENT_NODE: - case Node::CDATA_SECTION_NODE: - if ( (unsigned long)offset > static_cast<CharacterDataImpl*>(n)->length() ) - exceptioncode = DOMException::INDEX_SIZE_ERR; - break; - case Node::PROCESSING_INSTRUCTION_NODE: - // ### are we supposed to check with just data or the whole contents? - if ( (unsigned long)offset > static_cast<ProcessingInstructionImpl*>(n)->data().length() ) - exceptioncode = DOMException::INDEX_SIZE_ERR; - break; - default: - if ( (unsigned long)offset > n->childNodeCount() ) - exceptioncode = DOMException::INDEX_SIZE_ERR; - break; - } -} - -void RangeImpl::checkNodeBA( NodeImpl *n, int &exceptioncode ) const -{ - // INVALID_NODE_TYPE_ERR: Raised if the root container of refNode is not an - // Attr, Document or DocumentFragment node or if refNode is a Document, - // DocumentFragment, Attr, Entity, or Notation node. - NodeImpl *root = n; - while (root->parentNode()) - root = root->parentNode(); - if (!(root->nodeType() == Node::ATTRIBUTE_NODE || - root->nodeType() == Node::DOCUMENT_NODE || - root->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)) { - exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET; - return; - } - - if( n->nodeType() == Node::DOCUMENT_NODE || - n->nodeType() == Node::DOCUMENT_FRAGMENT_NODE || - n->nodeType() == Node::ATTRIBUTE_NODE || - n->nodeType() == Node::ENTITY_NODE || - n->nodeType() == Node::NOTATION_NODE ) - exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET; - -} - -RangeImpl *RangeImpl::cloneRange(int &exceptioncode) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - return new RangeImpl(m_ownerDocument,m_startContainer,m_startOffset,m_endContainer,m_endOffset); -} - -void RangeImpl::setStartAfter( NodeImpl *refNode, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if (!refNode) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - if (refNode->getDocument() != m_ownerDocument) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return; - } - - checkNodeBA( refNode, exceptioncode ); - if (exceptioncode) - return; - - setStart( refNode->parentNode(), refNode->nodeIndex()+1, exceptioncode ); -} - -void RangeImpl::setEndBefore( NodeImpl *refNode, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if (!refNode) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - if (refNode->getDocument() != m_ownerDocument) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return; - } - - checkNodeBA( refNode, exceptioncode ); - if (exceptioncode) - return; - - setEnd( refNode->parentNode(), refNode->nodeIndex(), exceptioncode ); -} - -void RangeImpl::setEndAfter( NodeImpl *refNode, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if (!refNode) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - if (refNode->getDocument() != m_ownerDocument) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return; - } - - checkNodeBA( refNode, exceptioncode ); - if (exceptioncode) - return; - - setEnd( refNode->parentNode(), refNode->nodeIndex()+1, exceptioncode ); - -} - -void RangeImpl::selectNode( NodeImpl *refNode, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if (!refNode) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - // INVALID_NODE_TYPE_ERR: Raised if an ancestor of refNode is an Entity, Notation or - // DocumentType node or if refNode is a Document, DocumentFragment, Attr, Entity, or Notation - // node. - NodeImpl *anc; - for (anc = refNode->parentNode(); anc; anc = anc->parentNode()) { - if (anc->nodeType() == Node::ENTITY_NODE || - anc->nodeType() == Node::NOTATION_NODE || - anc->nodeType() == Node::DOCUMENT_TYPE_NODE) { - - exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET; - return; - } - } - - if (refNode->nodeType() == Node::DOCUMENT_NODE || - refNode->nodeType() == Node::DOCUMENT_FRAGMENT_NODE || - refNode->nodeType() == Node::ATTRIBUTE_NODE || - refNode->nodeType() == Node::ENTITY_NODE || - refNode->nodeType() == Node::NOTATION_NODE) { - - exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET; - return; - } - - setStartBefore( refNode, exceptioncode ); - if (exceptioncode) - return; - setEndAfter( refNode, exceptioncode ); -} - -void RangeImpl::selectNodeContents( NodeImpl *refNode, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if (!refNode) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - // INVALID_NODE_TYPE_ERR: Raised if refNode or an ancestor of refNode is an Entity, Notation - // or DocumentType node. - NodeImpl *n; - for (n = refNode; n; n = n->parentNode()) { - if (n->nodeType() == Node::ENTITY_NODE || - n->nodeType() == Node::NOTATION_NODE || - n->nodeType() == Node::DOCUMENT_TYPE_NODE) { - - exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET; - return; - } - } - - setStartContainer(refNode); - m_startOffset = 0; - setEndContainer(refNode); - m_endOffset = refNode->childNodeCount(); -} - -void RangeImpl::surroundContents( NodeImpl *newParent, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if( !newParent ) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - // INVALID_NODE_TYPE_ERR: Raised if node is an Attr, Entity, DocumentType, Notation, - // Document, or DocumentFragment node. - if( newParent->nodeType() == Node::ATTRIBUTE_NODE || - newParent->nodeType() == Node::ENTITY_NODE || - newParent->nodeType() == Node::NOTATION_NODE || - newParent->nodeType() == Node::DOCUMENT_TYPE_NODE || - newParent->nodeType() == Node::DOCUMENT_NODE || - newParent->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) { - exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET; - return; - } - - // NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of either boundary-point of - // the Range is read-only. - if (readOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - NodeImpl *n = m_startContainer; - while (n && !n->isReadOnly()) - n = n->parentNode(); - if (n) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - n = m_endContainer; - while (n && !n->isReadOnly()) - n = n->parentNode(); - if (n) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - // WRONG_DOCUMENT_ERR: Raised if newParent and the container of the start of the Range were - // not created from the same document. - if (newParent->getDocument() != m_startContainer->getDocument()) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return; - } - - // HIERARCHY_REQUEST_ERR: Raised if the container of the start of the Range is of a type that - // does not allow children of the type of newParent or if newParent is an ancestor of the container - // or if node would end up with a child node of a type not allowed by the type of node. - if (!m_startContainer->childTypeAllowed(newParent->nodeType())) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - - for (n = m_startContainer; n; n = n->parentNode()) { - if (n == newParent) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - } - - // ### check if node would end up with a child node of a type not allowed by the type of node - - // BAD_BOUNDARYPOINTS_ERR: Raised if the Range partially selects a non-text node. - if (m_startContainer->nodeType() != Node::TEXT_NODE && - m_startContainer->nodeType() != Node::COMMENT_NODE && - m_startContainer->nodeType() != Node::CDATA_SECTION_NODE && - m_startContainer->nodeType() != Node::PROCESSING_INSTRUCTION_NODE) { - - if (m_startOffset > 0 && m_startOffset < m_startContainer->childNodeCount()) { - exceptioncode = RangeException::BAD_BOUNDARYPOINTS_ERR + RangeException::_EXCEPTION_OFFSET; - return; - } - } - - if (m_endContainer->nodeType() != Node::TEXT_NODE && - m_endContainer->nodeType() != Node::COMMENT_NODE && - m_endContainer->nodeType() != Node::CDATA_SECTION_NODE && - m_endContainer->nodeType() != Node::PROCESSING_INSTRUCTION_NODE) { - - if (m_endOffset > 0 && m_endOffset < m_endContainer->childNodeCount()) { - exceptioncode = RangeException::BAD_BOUNDARYPOINTS_ERR + RangeException::_EXCEPTION_OFFSET; - return; - } - } - - while (newParent->firstChild()) { - newParent->removeChild(newParent->firstChild(),exceptioncode); - if (exceptioncode) - return; - } - DocumentFragmentImpl *fragment = extractContents(exceptioncode); - if (exceptioncode) - return; - insertNode( newParent, exceptioncode ); - if (exceptioncode) - return; - newParent->appendChild( fragment, exceptioncode ); - if (exceptioncode) - return; - selectNode( newParent, exceptioncode ); -} - -void RangeImpl::setStartBefore( NodeImpl *refNode, int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return; - } - - if (!refNode) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - if (refNode->getDocument() != m_ownerDocument) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return; - } - - checkNodeBA( refNode, exceptioncode ); - if (exceptioncode) - return; - - setStart( refNode->parentNode(), refNode->nodeIndex(), exceptioncode ); -} - -void RangeImpl::setStartContainer(NodeImpl *_startContainer) -{ - if (m_startContainer == _startContainer) - return; - - if (m_startContainer) - m_startContainer->deref(); - m_startContainer = _startContainer; - if (m_startContainer) - m_startContainer->ref(); -} - -void RangeImpl::setEndContainer(NodeImpl *_endContainer) -{ - if (m_endContainer == _endContainer) - return; - - if (m_endContainer) - m_endContainer->deref(); - m_endContainer = _endContainer; - if (m_endContainer) - m_endContainer->ref(); -} - -void RangeImpl::checkDeleteExtract(int &exceptioncode) { - - NodeImpl *start; - if (m_startContainer->nodeType() != Node::TEXT_NODE && - m_startContainer->nodeType() != Node::CDATA_SECTION_NODE && - m_startContainer->nodeType() != Node::COMMENT_NODE && - m_startContainer->nodeType() != Node::PROCESSING_INSTRUCTION_NODE) { - - start = m_startContainer->childNode(m_startOffset); - if (!start) { - if (m_startContainer->lastChild()) - start = m_startContainer->lastChild()->traverseNextNode(); - else - start = m_startContainer->traverseNextNode(); - } - } - else - start = m_startContainer; - - NodeImpl *end; - if (m_endContainer->nodeType() != Node::TEXT_NODE && - m_endContainer->nodeType() != Node::CDATA_SECTION_NODE && - m_endContainer->nodeType() != Node::COMMENT_NODE && - m_endContainer->nodeType() != Node::PROCESSING_INSTRUCTION_NODE) { - - end = m_endContainer->childNode(m_endOffset); - if (!end) { - if (m_endContainer->lastChild()) - end = m_endContainer->lastChild()->traverseNextNode(); - else - end = m_endContainer->traverseNextNode(); - } - } - else - end = m_endContainer; - - NodeImpl *n; - for (n = start; n != end; n = n->traverseNextNode()) { - if (n->isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - if (n->nodeType() == Node::DOCUMENT_TYPE_NODE) { // ### is this for only directly under the DF, or anywhere? - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - } - - if (containedByReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } -} - - -bool RangeImpl::containedByReadOnly() { - NodeImpl *n; - for (n = m_startContainer; n; n = n->parentNode()) { - if (n->isReadOnly()) - return true; - } - for (n = m_endContainer; n; n = n->parentNode()) { - if (n->isReadOnly()) - return true; - } - return false; -} - - - - - - - - diff --git a/khtml/xml/dom2_rangeimpl.h b/khtml/xml/dom2_rangeimpl.h deleted file mode 100644 index 35d532f23..000000000 --- a/khtml/xml/dom2_rangeimpl.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) - * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) - * (C) 2001 Peter Kelly (pmk@post.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _DOM2_RangeImpl_h_ -#define _DOM2_RangeImpl_h_ - -#include "dom/dom2_range.h" -#include "misc/shared.h" - -namespace DOM { - -class RangeImpl : public khtml::Shared<RangeImpl> -{ - friend class DocumentImpl; -public: - RangeImpl(DocumentImpl *_ownerDocument); - RangeImpl(DocumentImpl *_ownerDocument, - NodeImpl *_startContainer, long _startOffset, - NodeImpl *_endContainer, long _endOffset); - - ~RangeImpl(); - - NodeImpl *startContainer(int &exceptioncode) const; - long startOffset(int &exceptioncode) const; - NodeImpl *endContainer(int &exceptioncode) const; - long endOffset(int &exceptioncode) const; - bool collapsed(int &exceptioncode) const; - - NodeImpl *commonAncestorContainer(int &exceptioncode); - static NodeImpl *commonAncestorContainer(NodeImpl *containerA, NodeImpl *containerB); - void setStart ( NodeImpl *refNode, long offset, int &exceptioncode ); - void setEnd ( NodeImpl *refNode, long offset, int &exceptioncode ); - void collapse ( bool toStart, int &exceptioncode ); - short compareBoundaryPoints ( Range::CompareHow how, RangeImpl *sourceRange, int &exceptioncode ); - static short compareBoundaryPoints ( NodeImpl *containerA, long offsetA, NodeImpl *containerB, long offsetB ); - bool boundaryPointsValid ( ); - void deleteContents ( int &exceptioncode ); - DocumentFragmentImpl *extractContents ( int &exceptioncode ); - DocumentFragmentImpl *cloneContents ( int &exceptioncode ); - void insertNode( NodeImpl *newNode, int &exceptioncode ); - DOMString toString ( int &exceptioncode ); - /** Converts the selection to HTML. The returned string will have matching - * tags, and all td, tr, etc tags will be inside a table tag. CSS is not - * used at this stage - This needs to be fixed. - * - * This is guaranteed to produce an xml valid snippet, no matter how crappy the input - * html page is. It will have html and body tags. - * - * Any urls in images or links will be expanded to full urls <em>with passwords stripped</em> - * for security reasons. - * - * Note: Originally this function didn't have the exceptioncode argument. I added it - * since all the other functions do. If this is correct, please remove this comment. - * - * @param exceptioncode This will be set if m_detached is true. - * @return A string with html tags for this range. - * - * @since 3.4 - */ - DOMString toHTML ( int &exceptioncode ); - - DocumentFragment createContextualFragment ( const DOMString &html, int &exceptioncode ); - - void detach ( int &exceptioncode ); - bool isDetached() const; - RangeImpl *cloneRange(int &exceptioncode); - - void setStartAfter( NodeImpl *refNode, int &exceptioncode ); - void setEndBefore( NodeImpl *refNode, int &exceptioncode ); - void setEndAfter( NodeImpl *refNode, int &exceptioncode ); - void selectNode( NodeImpl *refNode, int &exceptioncode ); - void selectNodeContents( NodeImpl *refNode, int &exceptioncode ); - void surroundContents( NodeImpl *newParent, int &exceptioncode ); - void setStartBefore( NodeImpl *refNode, int &exceptioncode ); - - enum ActionType { - DELETE_CONTENTS, - EXTRACT_CONTENTS, - CLONE_CONTENTS - }; - DocumentFragmentImpl *processContents ( ActionType action, int &exceptioncode ); - - bool readOnly() { return false; } - -protected: - DocumentImpl *m_ownerDocument; - NodeImpl *m_startContainer; - unsigned long m_startOffset; - NodeImpl *m_endContainer; - unsigned long m_endOffset; - bool m_detached; - -private: - void checkNodeWOffset( NodeImpl *n, int offset, int &exceptioncode) const; - void checkNodeBA( NodeImpl *n, int &exceptioncode ) const; - void setStartContainer(NodeImpl *_startContainer); - void setEndContainer(NodeImpl *_endContainer); - void checkDeleteExtract(int &exceptioncode); - bool containedByReadOnly(); -}; - -} // namespace - -#endif - diff --git a/khtml/xml/dom2_traversalimpl.cpp b/khtml/xml/dom2_traversalimpl.cpp deleted file mode 100644 index 2abdadead..000000000 --- a/khtml/xml/dom2_traversalimpl.cpp +++ /dev/null @@ -1,667 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) - * (C) 2001 Peter Kelly (pmk@post.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "dom/dom_exception.h" -#include "xml/dom_docimpl.h" - -using namespace DOM; - -NodeIteratorImpl::NodeIteratorImpl(NodeImpl *_root, unsigned long _whatToShow, - NodeFilter _filter, bool _entityReferenceExpansion) -{ - m_root = _root; - m_whatToShow = _whatToShow; - m_filter = _filter; - m_expandEntityReferences = _entityReferenceExpansion; - - m_referenceNode = _root; - m_inFront = false; - - m_doc = m_root->getDocument(); - m_doc->attachNodeIterator(this); - m_doc->ref(); - - m_detached = false; -} - -NodeIteratorImpl::~NodeIteratorImpl() -{ - m_doc->detachNodeIterator(this); - m_doc->deref(); -} - -NodeImpl *NodeIteratorImpl::root() -{ - return m_root; -} - -unsigned long NodeIteratorImpl::whatToShow() -{ - return m_whatToShow; -} - -NodeFilter NodeIteratorImpl::filter() -{ - return m_filter; -} - -bool NodeIteratorImpl::expandEntityReferences() -{ - return m_expandEntityReferences; -} - -NodeImpl *NodeIteratorImpl::nextNode( int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - if (!m_referenceNode) { - m_inFront = true; - return 0; - } - - if (!m_inFront) { - m_inFront = true; - if (isAccepted(m_referenceNode) == NodeFilter::FILTER_ACCEPT) - return m_referenceNode; - } - - NodeImpl *_tempCurrent = getNextNode(m_referenceNode); - while( _tempCurrent ) { - m_referenceNode = _tempCurrent; - if(isAccepted(_tempCurrent) == NodeFilter::FILTER_ACCEPT) - return m_referenceNode; - _tempCurrent = getNextNode(_tempCurrent); - } - - return 0; -} - -NodeImpl *NodeIteratorImpl::getNextNode(NodeImpl *n) -{ - /* 1. my first child - * 2. my next sibling - * 3. my parents sibling, or their parents sibling (loop) - * 4. not found - */ - - if( !n ) - return 0; - - if( n->hasChildNodes() ) - return n->firstChild(); - - if( m_root == n) - return 0; - - if( n->nextSibling() ) - return n->nextSibling(); - - NodeImpl *parent = n->parentNode(); - while( parent ) - { - if( m_root == parent ) - return 0; - - n = parent->nextSibling(); - if( n ) - return n; - - parent = parent->parentNode(); - } - return 0; -} - -NodeImpl *NodeIteratorImpl::previousNode( int &exceptioncode ) -{ - if (m_detached) { - exceptioncode = DOMException::INVALID_STATE_ERR; - return 0; - } - - if (!m_referenceNode) { - m_inFront = false; - return 0; - } - - if (m_inFront) { - m_inFront = false; - if (isAccepted(m_referenceNode) == NodeFilter::FILTER_ACCEPT) - return m_referenceNode; - } - - NodeImpl *_tempCurrent = getPreviousNode(m_referenceNode); - while( _tempCurrent ) { - m_referenceNode = _tempCurrent; - if(isAccepted(_tempCurrent) == NodeFilter::FILTER_ACCEPT) - return m_referenceNode; - _tempCurrent = getPreviousNode(_tempCurrent); - } - - return 0; -} - -NodeImpl *NodeIteratorImpl::getPreviousNode(NodeImpl *n) -{ -/* 1. my previous sibling.lastchild - * 2. my previous sibling - * 3. my parent - */ - NodeImpl *_tempCurrent; - - if( !n || m_root == n ) - return 0; - - _tempCurrent = n->previousSibling(); - if( _tempCurrent ) - { - if( _tempCurrent->lastChild() ) - { - while( _tempCurrent->lastChild() ) - _tempCurrent = _tempCurrent->lastChild(); - return _tempCurrent; - } - else - return _tempCurrent; - } - - return n->parentNode(); - -} - -void NodeIteratorImpl::detach(int &/*exceptioncode*/) -{ - m_doc->detachNodeIterator(this); - m_detached = true; -} - - -void NodeIteratorImpl::notifyBeforeNodeRemoval(NodeImpl *removed) -{ - // make sure the deleted node is with the root (but not the root itself) - if (removed == m_root) - return; - - NodeImpl *maybeRoot = removed->parentNode(); - while (maybeRoot && maybeRoot != m_root) - maybeRoot = maybeRoot->parentNode(); - if (!maybeRoot) - return; - - // did I get deleted, or one of my parents? - NodeImpl *_tempDeleted = m_referenceNode; - while( _tempDeleted && _tempDeleted != removed) - _tempDeleted = _tempDeleted->parentNode(); - - if( !_tempDeleted ) // someone that didn't consern me got deleted - return; - - if( !m_inFront) - { - NodeImpl *_next = getNextNode(_tempDeleted); - if( _next ) - m_referenceNode = _next; - else - { - // deleted node was at end of list - m_inFront = true; - m_referenceNode = getPreviousNode(_tempDeleted); - } - } - else { - NodeImpl *_prev = getPreviousNode(_tempDeleted); - if ( _prev ) - m_referenceNode = _prev; - else - { - // deleted node was at start of list - m_inFront = false; - m_referenceNode = getNextNode(_tempDeleted); - } - } - -} - -short NodeIteratorImpl::isAccepted(NodeImpl *n) -{ - // if XML is implemented we have to check expandEntityRerefences in this function - if( ( ( 1 << ( n->nodeType()-1 ) ) & m_whatToShow) != 0 ) - { - if(!m_filter.isNull()) - return m_filter.acceptNode(n); - else - return NodeFilter::FILTER_ACCEPT; - } - return NodeFilter::FILTER_SKIP; -} - -// -------------------------------------------------------------- - - -NodeFilterImpl::NodeFilterImpl() -{ - m_customNodeFilter = 0; -} - -NodeFilterImpl::~NodeFilterImpl() -{ - if (m_customNodeFilter) - m_customNodeFilter->deref(); -} - -short NodeFilterImpl::acceptNode(const Node &n) -{ - if (m_customNodeFilter) - return m_customNodeFilter->acceptNode(n); - else - return NodeFilter::FILTER_ACCEPT; -} - -void NodeFilterImpl::setCustomNodeFilter(CustomNodeFilter *custom) -{ - m_customNodeFilter = custom; - if (m_customNodeFilter) - m_customNodeFilter->ref(); -} - -CustomNodeFilter *NodeFilterImpl::customNodeFilter() -{ - return m_customNodeFilter; -} - -// -------------------------------------------------------------- - -TreeWalkerImpl::TreeWalkerImpl(NodeImpl *n, long _whatToShow, NodeFilterImpl *f, - bool entityReferenceExpansion) -{ - m_currentNode = n; - m_rootNode = n; - m_whatToShow = _whatToShow; - m_filter = f; - if ( m_filter ) - m_filter->ref(); - m_expandEntityReferences = entityReferenceExpansion; - m_doc = m_rootNode->getDocument(); - m_doc->ref(); -} - -TreeWalkerImpl::~TreeWalkerImpl() -{ - m_doc->deref(); - if ( m_filter ) - m_filter->deref(); -} - -NodeImpl *TreeWalkerImpl::getRoot() const -{ - return m_rootNode; -} - -unsigned long TreeWalkerImpl::getWhatToShow() const -{ - return m_whatToShow; -} - -NodeFilterImpl *TreeWalkerImpl::getFilter() const -{ - return m_filter; -} - -bool TreeWalkerImpl::getExpandEntityReferences() const -{ - return m_expandEntityReferences; -} - -NodeImpl *TreeWalkerImpl::getCurrentNode() const -{ - return m_currentNode; -} - -void TreeWalkerImpl::setWhatToShow(long _whatToShow) -{ - // do some testing wether this is an accepted value - m_whatToShow = _whatToShow; -} - -void TreeWalkerImpl::setFilter(NodeFilterImpl *_filter) -{ - m_filter->deref(); - m_filter = _filter; - if ( m_filter ) - m_filter->ref(); -} - -void TreeWalkerImpl::setExpandEntityReferences(bool value) -{ - m_expandEntityReferences = value; -} - -void TreeWalkerImpl::setCurrentNode( NodeImpl *n ) -{ - if ( n ) - { - //m_rootNode = n; - m_currentNode = n; - } -// else -// throw( DOMException::NOT_SUPPORTED_ERR ); -} - -NodeImpl *TreeWalkerImpl::parentNode( ) -{ - NodeImpl *n = getParentNode( m_currentNode ); - if ( n ) - m_currentNode = n; - return n; -} - - -NodeImpl *TreeWalkerImpl::firstChild( ) -{ - NodeImpl *n = getFirstChild( m_currentNode ); - if ( n ) - m_currentNode = n; - return n; -} - - -NodeImpl *TreeWalkerImpl::lastChild( ) -{ - NodeImpl *n = getLastChild(m_currentNode); - if( n ) - m_currentNode = n; - return n; -} - -NodeImpl *TreeWalkerImpl::previousSibling( ) -{ - NodeImpl *n = getPreviousSibling( m_currentNode ); - if( n ) - m_currentNode = n; - return n; -} - -NodeImpl *TreeWalkerImpl::nextSibling( ) -{ - NodeImpl *n = getNextSibling( m_currentNode ); - if( n ) - m_currentNode = n; - return n; -} - -NodeImpl *TreeWalkerImpl::previousNode( ) -{ -/* 1. my previous sibling.lastchild - * 2. my previous sibling - * 3. my parent - */ - - NodeImpl *n = getPreviousSibling( m_currentNode ); - if( !n ) - { - n = getParentNode( m_currentNode ); - if( n ) //parent - { - m_currentNode = n; - return m_currentNode; - } - else // parent failed.. no previous node - return 0; - } - - NodeImpl *child = getLastChild( n ); - if( child ) // previous siblings last child - { - m_currentNode = child; - return m_currentNode; - } - else // previous sibling - { - m_currentNode = n; - return m_currentNode; - } - return 0; // should never get here! -} - -NodeImpl *TreeWalkerImpl::nextNode( ) -{ -/* 1. my first child - * 2. my next sibling - * 3. my parents sibling, or their parents sibling (loop) - * 4. not found - */ - - NodeImpl *n = getFirstChild( m_currentNode ); - if( n ) // my first child - { - m_currentNode = n; - return n; - } - - n = getNextSibling( m_currentNode ); // my next sibling - if( n ) - { - m_currentNode = n; - return m_currentNode; - } - NodeImpl *parent = getParentNode( m_currentNode ); - while( parent ) // parents sibling - { - n = getNextSibling( parent ); - if( n ) - { - m_currentNode = n; - return m_currentNode; - } - else - parent = getParentNode( parent ); - } - return 0; -} - -short TreeWalkerImpl::isAccepted(NodeImpl *n) -{ - // if XML is implemented we have to check expandEntityRerefences in this function - if( ( ( 1 << ( n->nodeType()-1 ) ) & m_whatToShow) != 0 ) - { - if(m_filter) - return m_filter->acceptNode(n); - else - return NodeFilter::FILTER_ACCEPT; - } - return NodeFilter::FILTER_SKIP; -} - -NodeImpl *TreeWalkerImpl::getParentNode(NodeImpl *n) -{ - short _result = NodeFilter::FILTER_ACCEPT; - - if( n == m_rootNode /*|| !n*/ ) - return 0; - - NodeImpl *_tempCurrent = n->parentNode(); - - if( !_tempCurrent ) - return 0; - - _result = isAccepted( _tempCurrent ); - if ( _result == NodeFilter::FILTER_ACCEPT ) - return _tempCurrent; // match found - - return getParentNode( _tempCurrent ); -} - -NodeImpl *TreeWalkerImpl::getFirstChild(NodeImpl *n) -{ - short _result; - - if( !n || !n->firstChild() ) - return 0; - n = n->firstChild(); - - _result = isAccepted( n ); - - switch( _result ) - { - case NodeFilter::FILTER_ACCEPT: - return n; - break; - case NodeFilter::FILTER_SKIP: - if( n->hasChildNodes() ) - return getFirstChild( n ); - else - return getNextSibling( n ); - break; - - case NodeFilter::FILTER_REJECT: - return getNextSibling( n ); - break; - } - return 0; // should never get here! -} - -NodeImpl *TreeWalkerImpl::getLastChild(NodeImpl *n) -{ - short _result; - - if( !n || !n->lastChild() ) - return 0; - n = n->lastChild(); - _result = isAccepted( n ); - - switch( _result ) - { - case NodeFilter::FILTER_ACCEPT: - return n; - break; - - case NodeFilter::FILTER_SKIP: - if( n->hasChildNodes() ) - return getLastChild( n ); - else - return getPreviousSibling( n ); - break; - - case NodeFilter::FILTER_REJECT: - return getPreviousSibling( n ); - break; - } - return 0; -} - -NodeImpl *TreeWalkerImpl::getPreviousSibling(NodeImpl *n) -{ - short _result; - NodeImpl *_tempCurrent; - - if( !n ) - return 0; - //first the cases if we have a previousSibling - _tempCurrent = n->previousSibling(); - if( _tempCurrent ) - { - _result = isAccepted( _tempCurrent ); - switch ( _result ) - { - case NodeFilter::FILTER_ACCEPT: - return _tempCurrent; - break; - - case NodeFilter::FILTER_SKIP: - { - NodeImpl *nskip = getLastChild( _tempCurrent ); - if( nskip ) - return nskip; - return getPreviousSibling( _tempCurrent ); - break; - } - - case NodeFilter::FILTER_REJECT: - return getPreviousSibling( _tempCurrent ); - break; - } - } - // now the case if we don't have previous sibling - else - { - _tempCurrent = n->parentNode(); - if( !_tempCurrent || _tempCurrent == m_rootNode) - return 0; - _result = isAccepted( _tempCurrent ); - if ( _result == NodeFilter::FILTER_SKIP ) - return getPreviousSibling( _tempCurrent ); - - return 0; - - } - return 0; // should never get here! -} - -NodeImpl *TreeWalkerImpl::getNextSibling(NodeImpl *n) -{ - NodeImpl *_tempCurrent = 0; - short _result; - - if( !n ) - return 0; - - _tempCurrent = n->nextSibling(); - if( _tempCurrent ) - { - _result = isAccepted( _tempCurrent ); - switch ( _result ) - { - case NodeFilter::FILTER_ACCEPT: - return _tempCurrent; - break; - - case NodeFilter::FILTER_SKIP: - { - NodeImpl *nskip = getFirstChild( _tempCurrent ); - if( nskip ) - return nskip; - return getNextSibling( _tempCurrent ); - break; - } - - case NodeFilter::FILTER_REJECT: - return getNextSibling( _tempCurrent ); - break; - } - } - else - { - _tempCurrent = n->parentNode(); - if( !_tempCurrent || _tempCurrent == m_rootNode) - return 0; - _result = isAccepted( _tempCurrent ); - if( _result == NodeFilter::FILTER_SKIP ) - return getNextSibling( _tempCurrent ); - - return 0; - } - return 0; -} - diff --git a/khtml/xml/dom2_traversalimpl.h b/khtml/xml/dom2_traversalimpl.h deleted file mode 100644 index 3c5ea1dac..000000000 --- a/khtml/xml/dom2_traversalimpl.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) - * (C) 2001 Peter Kelly (pmk@post.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _DOM2_TraversalImpl_h_ -#define _DOM2_TraversalImpl_h_ - -#include "dom/dom_node.h" -#include "dom/dom_misc.h" -#include "misc/shared.h" -#include "dom/dom2_traversal.h" - -namespace DOM { - -class NodeImpl; -class DocumentImpl; - -class NodeIteratorImpl : public khtml::Shared<NodeIteratorImpl> -{ -public: - NodeIteratorImpl(NodeImpl *_root, unsigned long _whatToShow, NodeFilter _filter, bool _entityReferenceExpansion); - ~NodeIteratorImpl(); - - - NodeImpl *root(); - unsigned long whatToShow(); - NodeFilter filter(); - bool expandEntityReferences(); - - NodeImpl *nextNode(int &exceptioncode); - NodeImpl *previousNode(int &exceptioncode); - void detach(int &exceptioncode); - - - /** - * This function has to be called if you delete a node from the - * document tree and you want the Iterator to react if there - * are any changes concerning it. - */ - void notifyBeforeNodeRemoval(NodeImpl *removed); - - short isAccepted(NodeImpl *n); - NodeImpl *getNextNode(NodeImpl *n); - NodeImpl *getPreviousNode(NodeImpl *n); -protected: - NodeImpl *m_root; - long m_whatToShow; - NodeFilter m_filter; - bool m_expandEntityReferences; - - bool m_inFront; - NodeImpl *m_referenceNode; - bool m_detached; - DocumentImpl *m_doc; -}; - -class NodeFilterImpl : public khtml::Shared<NodeFilterImpl> -{ -public: - NodeFilterImpl(); - ~NodeFilterImpl(); - - short acceptNode(const Node &n); - - void setCustomNodeFilter(CustomNodeFilter *custom); - CustomNodeFilter *customNodeFilter(); -protected: - CustomNodeFilter *m_customNodeFilter; - -}; - -class TreeWalkerImpl : public khtml::Shared<TreeWalkerImpl> -{ -public: - TreeWalkerImpl(); - TreeWalkerImpl(const TreeWalkerImpl &other); - TreeWalkerImpl(NodeImpl *n, NodeFilter f); - TreeWalkerImpl(NodeImpl *n, long _whatToShow, NodeFilterImpl *f, - bool entityReferenceExpansion); - TreeWalkerImpl & operator = (const TreeWalkerImpl &other); - - - ~TreeWalkerImpl(); - - NodeImpl *getRoot() const; - - unsigned long getWhatToShow() const; - - NodeFilterImpl *getFilter() const; - - bool getExpandEntityReferences() const; - - NodeImpl *getCurrentNode() const; - - void setCurrentNode( NodeImpl *_currentNode); - - NodeImpl *parentNode(); - - NodeImpl *firstChild(); - - NodeImpl *lastChild (); - - NodeImpl *previousSibling (); - - NodeImpl *nextSibling(); - - NodeImpl *previousNode(); - - NodeImpl *nextNode(); - - - /** - * Sets which node types are to be presented via the TreeWalker - */ - void setWhatToShow(long _whatToShow); - void setFilter(NodeFilterImpl *_filter); - void setExpandEntityReferences(bool value); - - NodeImpl *getParentNode(NodeImpl *n); - NodeImpl *getFirstChild(NodeImpl *n); - NodeImpl *getLastChild(NodeImpl *n); - NodeImpl *getPreviousSibling(NodeImpl *n); - NodeImpl *getNextSibling(NodeImpl *n); - - short isAccepted(NodeImpl *n); - -protected: - /** - * This attribute determines which node types are presented via - * the TreeWalker. - * - */ - long m_whatToShow; - - /** - * The filter used to screen nodes. - * - */ - NodeFilterImpl *m_filter; - - /** - * The value of this flag determines whether entity reference - * nodes are expanded. To produce a view of the document that has - * entity references expanded and does not expose the entity - * reference node itself, use the whatToShow flags to hide the - * entity reference node and set expandEntityReferences to true - * when creating the iterator. To produce a view of the document - * that has entity reference nodes but no entity expansion, use - * the whatToShow flags to show the entity reference node and set - * expandEntityReferences to true. - * - * This is not implemented (always true) - */ - bool m_expandEntityReferences; - - /** - * The current node. - * - * The value must not be null. Attempting to set it to null will - * raise a NOT_SUPPORTED_ERR exception. When setting a node, the - * whatToShow flags and any Filter associated with the TreeWalker - * are not checked. The currentNode may be set to any Node of any - * type. - * - */ - NodeImpl *m_currentNode; - - NodeImpl *m_rootNode; - DocumentImpl *m_doc; -}; - - -} // namespace - -#endif - diff --git a/khtml/xml/dom2_viewsimpl.cpp b/khtml/xml/dom2_viewsimpl.cpp deleted file mode 100644 index 2195a9db1..000000000 --- a/khtml/xml/dom2_viewsimpl.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * (C) 2001 Peter Kelly (pmk@post.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "dom2_viewsimpl.h" -#include "dom_elementimpl.h" -#include "dom_docimpl.h" -#include "css/css_renderstyledeclarationimpl.h" -#include "css/cssproperties.h" -#include "css/css_stylesheetimpl.h" - -using namespace khtml; -using namespace DOM; - -AbstractViewImpl::AbstractViewImpl(DocumentImpl *_document) -{ - m_document = _document; -} - -AbstractViewImpl::~AbstractViewImpl() -{ -} - -CSSStyleDeclarationImpl *AbstractViewImpl::getComputedStyle(ElementImpl* elt, DOMStringImpl* /*pseudoElt*/) -{ - if (!elt) - return 0; - - CSSStyleDeclarationImpl* style = new RenderStyleDeclarationImpl( elt ); - return style; -} - diff --git a/khtml/xml/dom2_viewsimpl.h b/khtml/xml/dom2_viewsimpl.h deleted file mode 100644 index caff63e11..000000000 --- a/khtml/xml/dom2_viewsimpl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * (C) 2001 Peter Kelly (pmk@post.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _DOM_ViewsImpl_h_ -#define _DOM_ViewsImpl_h_ - -#include "dom/dom_misc.h" -#include "css/css_valueimpl.h" -#include "misc/shared.h" - -namespace DOM { - -class DocumentImpl; -class CSSStyleDeclarationImpl; -class ElementImpl; -class DOMStringImpl; - -// Introduced in DOM Level 2: -class AbstractViewImpl : public khtml::Shared<AbstractViewImpl> -{ -public: - AbstractViewImpl(DocumentImpl *_document); - ~AbstractViewImpl(); - DocumentImpl *document() const { return m_document; } - CSSStyleDeclarationImpl *getComputedStyle(ElementImpl *elt, DOMStringImpl *pseudoElt); -protected: - DocumentImpl *m_document; -}; - -} //namespace -#endif diff --git a/khtml/xml/dom_docimpl.cpp b/khtml/xml/dom_docimpl.cpp deleted file mode 100644 index ff206a1cc..000000000 --- a/khtml/xml/dom_docimpl.cpp +++ /dev/null @@ -1,2892 +0,0 @@ -/** - * 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) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * (C) 2002-2006 Apple Computer, Inc. - * (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "dom/dom_exception.h" - -#include "xml/dom_textimpl.h" -#include "xml/dom_xmlimpl.h" -#include "xml/dom2_rangeimpl.h" -#include "xml/dom2_eventsimpl.h" -#include "xml/xml_tokenizer.h" -#include "html/htmltokenizer.h" -#include "xml/dom_restyler.h" - -#include "css/csshelper.h" -#include "css/cssstyleselector.h" -#include "css/css_stylesheetimpl.h" -#include "misc/htmlhashes.h" -#include "misc/helper.h" -#include "misc/seed.h" -#include "misc/loader.h" -#include "ecma/kjs_proxy.h" -#include "ecma/kjs_binding.h" - -#include <tqptrstack.h> -#include <tqpaintdevicemetrics.h> -#include <kdebug.h> -#include <klocale.h> -#include <kstaticdeleter.h> - -#include "rendering/counter_tree.h" -#include "rendering/render_canvas.h" -#include "rendering/render_replaced.h" -#include "rendering/render_arena.h" -#include "rendering/render_layer.h" -#include "rendering/render_frames.h" -#include "rendering/render_image.h" - -#include "khtmlview.h" -#include "khtml_part.h" - -#include <kglobalsettings.h> -#include <kstringhandler.h> -#include <krfcdate.h> -#include "khtml_settings.h" -#include "khtmlpart_p.h" - -#include "html/html_baseimpl.h" -#include "html/html_blockimpl.h" -#include "html/html_documentimpl.h" -#include "html/html_formimpl.h" -#include "html/html_headimpl.h" -#include "html/html_imageimpl.h" -#include "html/html_listimpl.h" -#include "html/html_miscimpl.h" -#include "html/html_tableimpl.h" -#include "html/html_objectimpl.h" - -#include <kapplication.h> -#include <kio/job.h> - -#include <stdlib.h> -#include "dom_docimpl.h" - -using namespace DOM; -using namespace khtml; - -// ------------------------------------------------------------------------ - -DOMImplementationImpl *DOMImplementationImpl::m_instance = 0; - -DOMImplementationImpl::DOMImplementationImpl() -{ -} - -DOMImplementationImpl::~DOMImplementationImpl() -{ -} - -bool DOMImplementationImpl::hasFeature ( const DOMString &feature, const DOMString &version ) -{ - // ### update when we (fully) support the relevant features - TQString lower = feature.string().lower(); - if ((lower == "html" || lower == "xml") && - (version.isEmpty() || version == "1.0" || version == "2.0" || version == "null")) - return true; - - // ## Do we support Core Level 3 ? - if ((lower == "core" ) && - (version.isEmpty() || version == "2.0" || version == "null")) - return true; - - if ((lower == "events" || lower == "uievents" || - lower == "mouseevents" || lower == "mutationevents" || - lower == "htmlevents" || lower == "textevents" ) && - (version.isEmpty() || version == "2.0" || version == "3.0" || version == "null")) - return true; - return false; -} - -DocumentTypeImpl *DOMImplementationImpl::createDocumentType( const DOMString &qualifiedName, const DOMString &publicId, - const DOMString &systemId, int &exceptioncode ) -{ - // Not mentioned in spec: throw NAMESPACE_ERR if no qualifiedName supplied - if (qualifiedName.isNull()) { - exceptioncode = DOMException::NAMESPACE_ERR; - return 0; - } - - // INVALID_CHARACTER_ERR: Raised if the specified qualified name contains an illegal character. - if (!Element::khtmlValidQualifiedName(qualifiedName)) { - exceptioncode = DOMException::INVALID_CHARACTER_ERR; - return 0; - } - - // NAMESPACE_ERR: Raised if the qualifiedName is malformed. - // Added special case for the empty string, which seems to be a common pre-DOM2 misuse - if (!qualifiedName.isEmpty() && Element::khtmlMalformedQualifiedName(qualifiedName)) { - exceptioncode = DOMException::NAMESPACE_ERR; - return 0; - } - - return new DocumentTypeImpl(this,0,qualifiedName,publicId,systemId); -} - -DOMImplementationImpl* DOMImplementationImpl::getInterface(const DOMString& /*feature*/) const -{ - // ### - return 0; -} - -DocumentImpl *DOMImplementationImpl::createDocument( const DOMString &namespaceURI, const DOMString &qualifiedName, - const DocumentType &doctype, int &exceptioncode ) -{ - exceptioncode = 0; - - if (!checkQualifiedName(qualifiedName, namespaceURI, 0, true/*nameCanBeNull*/, - true /*nameCanBeEmpty, see #61650*/, &exceptioncode) ) - return 0; - - DocumentTypeImpl *dtype = static_cast<DocumentTypeImpl*>(doctype.handle()); - // WRONG_DOCUMENT_ERR: Raised if doctype has already been used with a different document or was - // created from a different implementation. - if (dtype && (dtype->getDocument() || dtype->implementation() != this)) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return 0; - } - - // ### this is completely broken.. without a view it will not work (Dirk) - DocumentImpl *doc = new DocumentImpl(this, 0); - - // now get the interesting parts of the doctype - // ### create new one if not there (currently always there) - if (doc->doctype() && dtype) - doc->doctype()->copyFrom(*dtype); - - // the document must be created empty if all parameters are null - // (or empty for qName/nsURI as a tolerance) - see DOM 3 Core. - if (dtype || !qualifiedName.isEmpty() || !namespaceURI.isEmpty()) { - ElementImpl *element = doc->createElementNS(namespaceURI,qualifiedName); - doc->appendChild(element,exceptioncode); - if (exceptioncode) { - delete element; - delete doc; - return 0; - } - } - return doc; -} - -CSSStyleSheetImpl *DOMImplementationImpl::createCSSStyleSheet(DOMStringImpl* /*title*/, DOMStringImpl *media, - int &/*exceptioncode*/) -{ - // ### TODO : title should be set, and media could have wrong syntax, in which case we should - // generate an exception. - CSSStyleSheetImpl *parent = 0L; - CSSStyleSheetImpl *sheet = new CSSStyleSheetImpl(parent, DOMString()); - sheet->setMedia(new MediaListImpl(sheet, media)); - return sheet; -} - -DocumentImpl *DOMImplementationImpl::createDocument( KHTMLView *v ) -{ - return new DocumentImpl(this, v); -} - -HTMLDocumentImpl *DOMImplementationImpl::createHTMLDocument( KHTMLView *v ) -{ - return new HTMLDocumentImpl(this, v); -} - -DOMImplementationImpl *DOMImplementationImpl::instance() -{ - if (!m_instance) { - m_instance = new DOMImplementationImpl(); - m_instance->ref(); - } - - return m_instance; -} - -// ------------------------------------------------------------------------ - - -ElementMappingCache::ElementMappingCache():m_dict(257) -{ - m_dict.setAutoDelete(true); -} - -void ElementMappingCache::add(const TQString& id, ElementImpl* nd) -{ - if (id.isEmpty()) return; - - ItemInfo* info = m_dict.find(id); - if (info) - { - info->ref++; - info->nd = 0; //Now ambigous - } - else - { - ItemInfo* info = new ItemInfo(); - info->ref = 1; - info->nd = nd; - m_dict.insert(id, info); - } -} - -void ElementMappingCache::set(const TQString& id, ElementImpl* nd) -{ - if (id.isEmpty()) return; - - ItemInfo* info = m_dict.find(id); - info->nd = nd; -} - -void ElementMappingCache::remove(const TQString& id, ElementImpl* nd) -{ - if (id.isEmpty()) return; - - ItemInfo* info = m_dict.find(id); - info->ref--; - if (info->ref == 0) - { - m_dict.take(id); - delete info; - } - else - { - if (info->nd == nd) - info->nd = 0; - } -} - -bool ElementMappingCache::contains(const TQString& id) -{ - if (id.isEmpty()) return false; - return m_dict.find(id); -} - -ElementMappingCache::ItemInfo* ElementMappingCache::get(const TQString& id) -{ - if (id.isEmpty()) return 0; - return m_dict.find(id); -} - -static KStaticDeleter< TQPtrList<DocumentImpl> > s_changedDocumentsDeleter; -TQPtrList<DocumentImpl> * DocumentImpl::changedDocuments; - -// KHTMLView might be 0 -DocumentImpl::DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v) - : NodeBaseImpl( 0 ), m_domtree_version(0), m_counterDict(257), - m_imageLoadEventTimer(0) -{ - m_document.resetSkippingRef(this); //Make getDocument return us.. - m_selfOnlyRefCount = 0; - - m_paintDeviceMetrics = 0; - m_paintDevice = 0; - m_decoderMibEnum = 0; - m_textColor = Qt::black; - - m_view = v; - m_renderArena.reset(); - - KHTMLFactory::ref(); - - if ( v ) { - m_docLoader = new DocLoader(v->part(), this ); - setPaintDevice( TQT_TQPAINTDEVICE(m_view) ); - } - else - m_docLoader = new DocLoader( 0, this ); - - visuallyOrdered = false; - m_bParsing = false; - m_docChanged = false; - m_elemSheet = 0; - m_tokenizer = 0; - - // ### this should be created during parsing a <!DOCTYPE> - // not during construction. Not sure who added that and why (Dirk) - m_doctype = new DocumentTypeImpl(_implementation, getDocument(), - DOMString() /* qualifiedName */, - DOMString() /* publicId */, - DOMString() /* systemId */); - m_doctype->ref(); - - m_implementation = _implementation; - m_implementation->ref(); - pMode = Strict; - hMode = XHtml; - m_textColor = "#000000"; - m_attrMap = new IdNameMapping(ATTR_LAST_ATTR+1); - m_elementMap = new IdNameMapping(ID_LAST_TAG+1); - m_namespaceMap = new IdNameMapping(1); - TQString xhtml(XHTML_NAMESPACE); - m_namespaceMap->names.insert(emptyNamespace, new DOMStringImpl("")); - m_namespaceMap->names.insert(xhtmlNamespace, new DOMStringImpl(xhtml.unicode(), xhtml.length())); - m_namespaceMap->names[emptyNamespace]->ref(); - m_namespaceMap->names[xhtmlNamespace]->ref(); - m_namespaceMap->count+=2; - m_focusNode = 0; - m_hoverNode = 0; - m_activeNode = 0; - m_defaultView = new AbstractViewImpl(this); - m_defaultView->ref(); - m_listenerTypes = 0; - m_styleSheets = new StyleSheetListImpl; - m_styleSheets->ref(); - m_addedStyleSheets = 0; - m_inDocument = true; - m_styleSelectorDirty = false; - m_styleSelector = 0; - m_counterDict.setAutoDelete(true); - - m_inStyleRecalc = false; - m_pendingStylesheets = 0; - m_ignorePendingStylesheets = false; - m_async = true; - m_hadLoadError = false; - m_docLoading = false; - m_inSyncLoad = false; - m_loadingXMLDoc = 0; - m_cssTarget = 0; - m_dynamicDomRestyler = new khtml::DynamicDomRestyler(); -} - -void DocumentImpl::removedLastRef() -{ - if (m_selfOnlyRefCount) { - /* In this case, the only references to us are from children, - so we have a cycle. We'll try to break it by disconnecting the - children from us; this sucks/is wrong, but it's pretty much - the best we can do without tracing. - - Of course, if dumping the children causes the refcount from them to - drop to 0 we can get killed right here, so better hold - a temporary reference, too - */ - DocPtr<DocumentImpl> guard(this); - - // we must make sure not to be retaining any of our children through - // these extra pointers or we will create a reference cycle - if (m_doctype) { - m_doctype->deref(); - m_doctype = 0; - } - - if (m_cssTarget) { - m_cssTarget->deref(); - m_cssTarget = 0; - } - - if (m_focusNode) { - m_focusNode->deref(); - m_focusNode = 0; - } - - if (m_hoverNode) { - m_hoverNode->deref(); - m_hoverNode = 0; - } - - if (m_activeNode) { - m_activeNode->deref(); - m_activeNode = 0; - } - - removeChildren(); - - delete m_tokenizer; - m_tokenizer = 0; - } else { - delete this; - } -} - -DocumentImpl::~DocumentImpl() -{ - //Important: if you need to remove stuff here, - //you may also have to fix removedLastRef() above - M.O. - assert( !m_render ); - - TQIntDictIterator<NodeListImpl::Cache> it(m_nodeListCache); - for (; it.current(); ++it) - it.current()->deref(); - - if (m_loadingXMLDoc) - m_loadingXMLDoc->deref(this); - if (changedDocuments && m_docChanged) - changedDocuments->remove(this); - delete m_tokenizer; - m_document.resetSkippingRef(0); - delete m_styleSelector; - delete m_docLoader; - if (m_elemSheet ) m_elemSheet->deref(); - if (m_doctype) - m_doctype->deref(); - m_implementation->deref(); - delete m_paintDeviceMetrics; - delete m_elementMap; - delete m_attrMap; - delete m_namespaceMap; - delete m_dynamicDomRestyler; - m_defaultView->deref(); - m_styleSheets->deref(); - if (m_addedStyleSheets) - m_addedStyleSheets->deref(); - if (m_cssTarget) - m_cssTarget->deref(); - if (m_focusNode) - m_focusNode->deref(); - if ( m_hoverNode ) - m_hoverNode->deref(); - if (m_activeNode) - m_activeNode->deref(); - - m_renderArena.reset(); - - KHTMLFactory::deref(); -} - - -DocumentTypeImpl *DocumentImpl::doctype() const -{ - return m_doctype; -} - -DOMImplementationImpl *DocumentImpl::implementation() const -{ - return m_implementation; -} - -ElementImpl *DocumentImpl::documentElement() const -{ - NodeImpl *n = firstChild(); - while (n && n->nodeType() != Node::ELEMENT_NODE) - n = n->nextSibling(); - return static_cast<ElementImpl*>(n); -} - -ElementImpl *DocumentImpl::createElement( const DOMString &name, int* pExceptioncode ) -{ - Id id = getId( NodeImpl::ElementId, name.implementation(), - false /* allocate */, false /*HTMLDocumentImpl::createElement looked for HTML elements already*/, - pExceptioncode); - if ( pExceptioncode && *pExceptioncode ) - return 0; - - XMLElementImpl* e = new XMLElementImpl( getDocument(), id ); - e->setHTMLCompat( htmlMode() != XHtml ); // Not a real HTML element, but inside an html-compat doc all tags are uppercase. - return e; -} - -AttrImpl *DocumentImpl::createAttribute( const DOMString &tagName, int* pExceptioncode ) -{ - Id id = getId( NodeImpl::AttributeId, tagName.implementation(), - false /* allocate */, isHTMLDocument(), pExceptioncode); - if ( pExceptioncode && *pExceptioncode ) - return 0; - AttrImpl* attr = new AttrImpl( 0, getDocument(), id, DOMString("").implementation()); - attr->setHTMLCompat( htmlMode() != XHtml ); - return attr; -} - -DocumentFragmentImpl *DocumentImpl::createDocumentFragment( ) -{ - return new DocumentFragmentImpl( docPtr() ); -} - -CommentImpl *DocumentImpl::createComment ( DOMStringImpl* data ) -{ - return new CommentImpl( docPtr(), data ); -} - -CDATASectionImpl *DocumentImpl::createCDATASection ( DOMStringImpl* data ) -{ - return new CDATASectionImpl( docPtr(), data ); -} - -ProcessingInstructionImpl *DocumentImpl::createProcessingInstruction ( const DOMString &target, DOMStringImpl* data ) -{ - return new ProcessingInstructionImpl( docPtr(),target,data); -} - -EntityReferenceImpl *DocumentImpl::createEntityReference ( const DOMString &name ) -{ - return new EntityReferenceImpl(docPtr(), name.implementation()); -} - -NodeImpl *DocumentImpl::importNode(NodeImpl *importedNode, bool deep, int &exceptioncode) -{ - NodeImpl *result = 0; - - // Not mentioned in spec: throw NOT_FOUND_ERR if evt is null - if (!importedNode) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return 0; - } - - if(importedNode->nodeType() == Node::ELEMENT_NODE) - { - // Why not use cloneNode? - ElementImpl *otherElem = static_cast<ElementImpl*>(importedNode); - NamedAttrMapImpl *otherMap = static_cast<ElementImpl *>(importedNode)->attributes(true); - - ElementImpl *tempElementImpl; - if (!importedNode->localName().isNull()) - tempElementImpl = createElementNS(otherElem->namespaceURI(),otherElem->nodeName()); - else - tempElementImpl = createElement(otherElem->nodeName()); - result = tempElementImpl; - - - if(otherMap) { - for(unsigned long i = 0; i < otherMap->length(); i++) - { - AttrImpl *otherAttr = otherMap->attrAt(i)->createAttr(otherElem,otherElem->docPtr()); - - if (!otherAttr->localName().isNull()) { - // attr was created via createElementNS() - tempElementImpl->setAttributeNS(otherAttr->namespaceURI(), - otherAttr->name(), - otherAttr->nodeValue(), - exceptioncode); - } - else { - // attr was created via createElement() - tempElementImpl->setAttribute(otherAttr->id(), - otherAttr->nodeValue(), - otherAttr->name(), - exceptioncode); - } - - if(exceptioncode != 0) - break; // ### properly cleanup here - } - } - } - else if(importedNode->nodeType() == Node::TEXT_NODE) - { - result = createTextNode(static_cast<TextImpl*>(importedNode)->string()); - deep = false; - } - else if(importedNode->nodeType() == Node::CDATA_SECTION_NODE) - { - result = createCDATASection(static_cast<CDATASectionImpl*>(importedNode)->string()); - deep = false; - } - else if(importedNode->nodeType() == Node::ENTITY_REFERENCE_NODE) - result = createEntityReference(importedNode->nodeName()); - else if(importedNode->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) - { - result = createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue().implementation()); - deep = false; - } - else if(importedNode->nodeType() == Node::COMMENT_NODE) - { - result = createComment(static_cast<CommentImpl*>(importedNode)->string()); - deep = false; - } - else if (importedNode->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) - result = createDocumentFragment(); - else - exceptioncode = DOMException::NOT_SUPPORTED_ERR; - - //### FIXME: This should handle Attributes, and a few other things - - if(deep && result) - { - for(Node n = importedNode->firstChild(); !n.isNull(); n = n.nextSibling()) - result->appendChild(importNode(n.handle(), true, exceptioncode), exceptioncode); - } - - return result; -} - -ElementImpl *DocumentImpl::createElementNS( const DOMString &_namespaceURI, const DOMString &_qualifiedName, int* pExceptioncode ) -{ - ElementImpl *e = 0; - int colonPos = -2; - // check NAMESPACE_ERR/INVALID_CHARACTER_ERR - if (pExceptioncode && !checkQualifiedName(_qualifiedName, _namespaceURI, &colonPos, - false/*nameCanBeNull*/, false/*nameCanBeEmpty*/, - pExceptioncode)) - return 0; - DOMString prefix, localName; - splitPrefixLocalName(_qualifiedName.implementation(), prefix, localName, colonPos); - - if ((isHTMLDocument() && _namespaceURI.isNull()) || - (strcasecmp(_namespaceURI, XHTML_NAMESPACE) == 0 && localName == localName.lower())) { - e = createHTMLElement(localName); - if (e) { - int _exceptioncode = 0; - if (!prefix.isNull()) - e->setPrefix(prefix, _exceptioncode); - if ( _exceptioncode ) { - if ( pExceptioncode ) *pExceptioncode = _exceptioncode; - delete e; - return 0; - } - e->setHTMLCompat( _namespaceURI.isNull() && htmlMode() != XHtml ); - } - } - if (!e) { - Id id = getId(NodeImpl::ElementId, _namespaceURI.implementation(), prefix.implementation(), - localName.implementation(), false, false /*HTML already looked up*/); - e = new XMLElementImpl( getDocument(), id, prefix.implementation() ); - } - - return e; -} - -AttrImpl *DocumentImpl::createAttributeNS( const DOMString &_namespaceURI, - const DOMString &_qualifiedName, int* pExceptioncode) -{ - int colonPos = -2; - // check NAMESPACE_ERR/INVALID_CHARACTER_ERR - if (pExceptioncode && !checkQualifiedName(_qualifiedName, _namespaceURI, &colonPos, - false/*nameCanBeNull*/, false/*nameCanBeEmpty*/, - pExceptioncode)) - return 0; - DOMString prefix, localName; - splitPrefixLocalName(_qualifiedName.implementation(), prefix, localName, colonPos); - Id id = getId(NodeImpl::AttributeId, _namespaceURI.implementation(), prefix.implementation(), - localName.implementation(), false, true /*lookupHTML*/); - AttrImpl* attr = new AttrImpl(0, getDocument(), id, DOMString("").implementation(), - prefix.implementation()); - attr->setHTMLCompat( _namespaceURI.isNull() && htmlMode() != XHtml ); - return attr; -} - -ElementImpl *DocumentImpl::getElementById( const DOMString &elementId ) const -{ - TQString stringKey = elementId.string(); - - ElementMappingCache::ItemInfo* info = m_getElementByIdCache.get(stringKey); - - if (!info) - return 0; - - //See if cache has an unambiguous answer. - if (info->nd) - return info->nd; - - //Now we actually have to walk. - TQPtrStack<NodeImpl> nodeStack; - NodeImpl *current = _first; - - while(1) - { - if(!current) - { - if(nodeStack.isEmpty()) break; - current = nodeStack.pop(); - current = current->nextSibling(); - } - else - { - if(current->isElementNode()) - { - ElementImpl *e = static_cast<ElementImpl *>(current); - if(e->getAttribute(ATTR_ID) == elementId) { - info->nd = e; - return e; - } - } - - NodeImpl *child = current->firstChild(); - if(child) - { - nodeStack.push(current); - current = child; - } - else - { - current = current->nextSibling(); - } - } - } - - assert(0); //If there is no item with such an ID, we should never get here - - //kdDebug() << "WARNING: *DocumentImpl::getElementById not found " << elementId.string() << endl; - - return 0; -} - -void DocumentImpl::setTitle(const DOMString& _title) -{ - if (_title == m_title && !m_title.isNull()) return; - - m_title = _title; - - TQString titleStr = m_title.string(); - for (unsigned int i = 0; i < titleStr.length(); ++i) - if (titleStr[i] < ' ') - titleStr[i] = ' '; - titleStr = titleStr.simplifyWhiteSpace(); - titleStr.compose(); - if ( view() && !view()->part()->parentPart() ) { - if (titleStr.isNull() || titleStr.isEmpty()) { - // empty title... set window caption as the URL - KURL url = m_url; - url.setRef(TQString::null); - url.setQuery(TQString::null); - titleStr = url.prettyURL(); - } - - emit view()->part()->setWindowCaption( KStringHandler::csqueeze( titleStr, 128 ) ); - } -} - -DOMString DocumentImpl::nodeName() const -{ - return "#document"; -} - -unsigned short DocumentImpl::nodeType() const -{ - return Node::DOCUMENT_NODE; -} - -DOMStringImpl* DocumentImpl::textContent() const -{ - return 0; -} - -void DocumentImpl::setTextContent( const DOMString&, int& ) -{} - -ElementImpl *DocumentImpl::createHTMLElement( const DOMString &name ) -{ - uint id = khtml::getTagID( name.string().lower().latin1(), name.string().length() ); -// id = makeId(xhtmlNamespace, id); - - ElementImpl *n = 0; - switch(id) - { - case ID_HTML: - n = new HTMLHtmlElementImpl(docPtr()); - break; - case ID_HEAD: - n = new HTMLHeadElementImpl(docPtr()); - break; - case ID_BODY: - n = new HTMLBodyElementImpl(docPtr()); - break; - -// head elements - case ID_BASE: - n = new HTMLBaseElementImpl(docPtr()); - break; - case ID_LINK: - n = new HTMLLinkElementImpl(docPtr()); - break; - case ID_META: - n = new HTMLMetaElementImpl(docPtr()); - break; - case ID_STYLE: - n = new HTMLStyleElementImpl(docPtr()); - break; - case ID_TITLE: - n = new HTMLTitleElementImpl(docPtr()); - break; - -// frames - case ID_FRAME: - n = new HTMLFrameElementImpl(docPtr()); - break; - case ID_FRAMESET: - n = new HTMLFrameSetElementImpl(docPtr()); - break; - case ID_IFRAME: - n = new HTMLIFrameElementImpl(docPtr()); - break; - -// form elements -// ### FIXME: we need a way to set form dependency after we have made the form elements - case ID_FORM: - n = new HTMLFormElementImpl(docPtr(), false); - break; - case ID_BUTTON: - n = new HTMLButtonElementImpl(docPtr()); - break; - case ID_FIELDSET: - n = new HTMLFieldSetElementImpl(docPtr()); - break; - case ID_INPUT: - n = new HTMLInputElementImpl(docPtr()); - break; - case ID_ISINDEX: - n = new HTMLIsIndexElementImpl(docPtr()); - break; - case ID_LABEL: - n = new HTMLLabelElementImpl(docPtr()); - break; - case ID_LEGEND: - n = new HTMLLegendElementImpl(docPtr()); - break; - case ID_OPTGROUP: - n = new HTMLOptGroupElementImpl(docPtr()); - break; - case ID_OPTION: - n = new HTMLOptionElementImpl(docPtr()); - break; - case ID_SELECT: - n = new HTMLSelectElementImpl(docPtr()); - break; - case ID_TEXTAREA: - n = new HTMLTextAreaElementImpl(docPtr()); - break; - -// lists - case ID_DL: - n = new HTMLDListElementImpl(docPtr()); - break; - case ID_DD: - n = new HTMLGenericElementImpl(docPtr(), id); - break; - case ID_DT: - n = new HTMLGenericElementImpl(docPtr(), id); - break; - case ID_UL: - n = new HTMLUListElementImpl(docPtr()); - break; - case ID_OL: - n = new HTMLOListElementImpl(docPtr()); - break; - case ID_DIR: - n = new HTMLDirectoryElementImpl(docPtr()); - break; - case ID_MENU: - n = new HTMLMenuElementImpl(docPtr()); - break; - case ID_LI: - n = new HTMLLIElementImpl(docPtr()); - break; - -// formatting elements (block) - case ID_DIV: - case ID_P: - n = new HTMLDivElementImpl( docPtr(), id ); - break; - case ID_BLOCKQUOTE: - case ID_H1: - case ID_H2: - case ID_H3: - case ID_H4: - case ID_H5: - case ID_H6: - n = new HTMLGenericElementImpl(docPtr(), id); - break; - case ID_HR: - n = new HTMLHRElementImpl(docPtr()); - break; - case ID_PLAINTEXT: - case ID_XMP: - case ID_PRE: - n = new HTMLPreElementImpl(docPtr(), id); - break; - -// font stuff - case ID_BASEFONT: - n = new HTMLBaseFontElementImpl(docPtr()); - break; - case ID_FONT: - n = new HTMLFontElementImpl(docPtr()); - break; - -// ins/del - case ID_DEL: - case ID_INS: - n = new HTMLGenericElementImpl(docPtr(), id); - break; - -// anchor - case ID_A: - n = new HTMLAnchorElementImpl(docPtr()); - break; - -// images - case ID_IMG: - n = new HTMLImageElementImpl(docPtr()); - break; - case ID_MAP: - n = new HTMLMapElementImpl(docPtr()); - /*n = map;*/ - break; - case ID_AREA: - n = new HTMLAreaElementImpl(docPtr()); - break; - -// objects, applets and scripts - case ID_APPLET: - n = new HTMLAppletElementImpl(docPtr()); - break; - case ID_OBJECT: - n = new HTMLObjectElementImpl(docPtr()); - break; - case ID_EMBED: - n = new HTMLEmbedElementImpl(docPtr()); - break; - case ID_PARAM: - n = new HTMLParamElementImpl(docPtr()); - break; - case ID_SCRIPT: - n = new HTMLScriptElementImpl(docPtr()); - break; - -// tables - case ID_TABLE: - n = new HTMLTableElementImpl(docPtr()); - break; - case ID_CAPTION: - n = new HTMLTableCaptionElementImpl(docPtr()); - break; - case ID_COLGROUP: - case ID_COL: - n = new HTMLTableColElementImpl(docPtr(), id); - break; - case ID_TR: - n = new HTMLTableRowElementImpl(docPtr()); - break; - case ID_TD: - case ID_TH: - n = new HTMLTableCellElementImpl(docPtr(), id); - break; - case ID_THEAD: - case ID_TBODY: - case ID_TFOOT: - n = new HTMLTableSectionElementImpl(docPtr(), id, false); - break; - -// inline elements - case ID_BR: - n = new HTMLBRElementImpl(docPtr()); - break; - case ID_Q: - n = new HTMLGenericElementImpl(docPtr(), id); - break; - -// elements with no special representation in the DOM - -// block: - case ID_ADDRESS: - case ID_CENTER: - n = new HTMLGenericElementImpl(docPtr(), id); - break; -// inline - // %fontstyle - case ID_TT: - case ID_U: - case ID_B: - case ID_I: - case ID_S: - case ID_STRIKE: - case ID_BIG: - case ID_SMALL: - - // %phrase - case ID_EM: - case ID_STRONG: - case ID_DFN: - case ID_CODE: - case ID_SAMP: - case ID_KBD: - case ID_VAR: - case ID_CITE: - case ID_ABBR: - case ID_ACRONYM: - - // %special - case ID_SUB: - case ID_SUP: - case ID_SPAN: - case ID_NOBR: - case ID_WBR: - case ID_BDO: - case ID_NOFRAMES: - n = new HTMLGenericElementImpl(docPtr(), id); - break; - - case ID_MARQUEE: - n = new HTMLMarqueeElementImpl(docPtr()); - break; -// text - case ID_TEXT: - kdDebug( 6020 ) << "Use document->createTextNode()" << endl; - break; - - default: - break; - } - return n; -} - -TQString DocumentImpl::nextState() -{ - TQString state; - if (!m_state.isEmpty()) - { - state = m_state.first(); - m_state.remove(m_state.begin()); - } - return state; -} - -TQStringList DocumentImpl::docState() -{ - TQStringList s; - for (TQPtrListIterator<NodeImpl> it(m_maintainsState); it.current(); ++it) - s.append(it.current()->state()); - - return s; -} - -bool DocumentImpl::unsubmittedFormChanges() -{ - for (TQPtrListIterator<NodeImpl> it(m_maintainsState); it.current(); ++it) - if (it.current()->state().right(1)=="M") - return true; - - return false; -} - -RangeImpl *DocumentImpl::createRange() -{ - return new RangeImpl( docPtr() ); -} - -NodeIteratorImpl *DocumentImpl::createNodeIterator(NodeImpl *root, unsigned long whatToShow, - NodeFilter &filter, bool entityReferenceExpansion, - int &exceptioncode) -{ - if (!root) { - exceptioncode = DOMException::NOT_SUPPORTED_ERR; - return 0; - } - - return new NodeIteratorImpl(root,whatToShow,filter,entityReferenceExpansion); -} - -TreeWalkerImpl *DocumentImpl::createTreeWalker(NodeImpl *root, unsigned long whatToShow, NodeFilterImpl *filter, - bool entityReferenceExpansion, int &exceptioncode) -{ - if (!root) { - exceptioncode = DOMException::NOT_SUPPORTED_ERR; - return 0; - } - - return new TreeWalkerImpl( root, whatToShow, filter, entityReferenceExpansion ); -} - -void DocumentImpl::setDocumentChanged(bool b) -{ - if (!changedDocuments) - changedDocuments = s_changedDocumentsDeleter.setObject( changedDocuments, new TQPtrList<DocumentImpl>() ); - - if (b && !m_docChanged) - changedDocuments->append(this); - else if (!b && m_docChanged) - changedDocuments->remove(this); - m_docChanged = b; -} - -void DocumentImpl::recalcStyle( StyleChange change ) -{ -// tqDebug("recalcStyle(%p)", this); -// TQTime qt; -// qt.start(); - if (m_inStyleRecalc) - return; // Guard against re-entrancy. -dwh - - m_inStyleRecalc = true; - - if( !m_render ) goto bail_out; - - if ( change == Force ) { - RenderStyle* oldStyle = m_render->style(); - if ( oldStyle ) oldStyle->ref(); - RenderStyle* _style = new RenderStyle(); - _style->setDisplay(BLOCK); - _style->setVisuallyOrdered( visuallyOrdered ); - // ### make the font stuff _really_ work!!!! - - khtml::FontDef fontDef; - TQFont f = TDEGlobalSettings::generalFont(); - fontDef.family = f.family(); - fontDef.italic = f.italic(); - fontDef.weight = f.weight(); - if (m_view) { - const KHTMLSettings *settings = m_view->part()->settings(); - TQString stdfont = settings->stdFontName(); - if ( !stdfont.isEmpty() ) - fontDef.family = stdfont; - - fontDef.size = m_styleSelector->fontSizes()[3]; - } - - //kdDebug() << "DocumentImpl::attach: setting to charset " << settings->charset() << endl; - _style->setFontDef(fontDef); - _style->htmlFont().update( paintDeviceMetrics() ); - if ( inCompatMode() ) - _style->setHtmlHacks(true); // enable html specific rendering tricks - - StyleChange ch = diff( _style, oldStyle ); - if(m_render && ch != NoChange) - m_render->setStyle(_style); - else - delete _style; - if ( change != Force ) - change = ch; - - if (oldStyle) - oldStyle->deref(); - } - - NodeImpl *n; - for (n = _first; n; n = n->nextSibling()) - if ( change>= Inherit || n->hasChangedChild() || n->changed() ) - n->recalcStyle( change ); - //kdDebug( 6020 ) << "TIME: recalcStyle() dt=" << qt.elapsed() << endl; - - if (changed() && m_view) - m_view->layout(); - -bail_out: - setChanged( false ); - setHasChangedChild( false ); - setDocumentChanged( false ); - - m_inStyleRecalc = false; -} - -void DocumentImpl::updateRendering() -{ - if (!hasChangedChild()) return; - -// TQTime time; -// time.start(); -// kdDebug() << "UPDATERENDERING: "<<endl; - - StyleChange change = NoChange; -#if 0 - if ( m_styleSelectorDirty ) { - recalcStyleSelector(); - change = Force; - } -#endif - recalcStyle( change ); - -// kdDebug() << "UPDATERENDERING time used="<<time.elapsed()<<endl; -} - -void DocumentImpl::updateDocumentsRendering() -{ - if (!changedDocuments) - return; - - while ( !changedDocuments->isEmpty() ) { - changedDocuments->first(); - DocumentImpl* it = changedDocuments->take(); - if (it->isDocumentChanged()) - it->updateRendering(); - } -} - -void DocumentImpl::updateLayout() -{ - bool oldIgnore = m_ignorePendingStylesheets; - - if (!haveStylesheetsLoaded()) { - m_ignorePendingStylesheets = true; - updateStyleSelector(); - } - - updateRendering(); - - // Only do a layout if changes have occurred that make it necessary. - if (m_view && renderer() && renderer()->needsLayout()) - m_view->layout(); - - m_ignorePendingStylesheets = oldIgnore; -} - -void DocumentImpl::attach() -{ - assert(!attached()); - - if ( m_view ) - setPaintDevice( TQT_TQPAINTDEVICE(m_view) ); - - if (!m_renderArena) - m_renderArena.reset(new RenderArena()); - - // Create the rendering tree - assert(!m_styleSelector); - m_styleSelector = new CSSStyleSelector( this, m_usersheet, m_styleSheets, m_url, - !inCompatMode() ); - m_render = new (m_renderArena.get()) RenderCanvas(this, m_view); - m_styleSelector->computeFontSizes(paintDeviceMetrics(), m_view ? m_view->part()->zoomFactor() : 100); - recalcStyle( Force ); - - RenderObject* render = m_render; - m_render = 0; - - NodeBaseImpl::attach(); - m_render = render; -} - -void DocumentImpl::detach() -{ - RenderObject* render = m_render; - - // indicate destruction mode, i.e. attached() but m_render == 0 - m_render = 0; - - delete m_tokenizer; - m_tokenizer = 0; - - // Empty out these lists as a performance optimization - m_imageLoadEventDispatchSoonList.clear(); - m_imageLoadEventDispatchingList.clear(); - NodeBaseImpl::detach(); - - if ( render ) - render->detach(); - - m_view = 0; - - m_renderArena.reset(); -} - -void DocumentImpl::setVisuallyOrdered() -{ - visuallyOrdered = true; - if (m_render) - m_render->style()->setVisuallyOrdered(true); -} - -void DocumentImpl::setSelection(NodeImpl* s, int sp, NodeImpl* e, int ep) -{ - if ( m_render ) - static_cast<RenderCanvas*>(m_render)->setSelection(s->renderer(),sp,e->renderer(),ep); -} - -void DocumentImpl::clearSelection() -{ - if ( m_render ) - static_cast<RenderCanvas*>(m_render)->clearSelection(); -} - -khtml::Tokenizer *DocumentImpl::createTokenizer() -{ - return new khtml::XMLTokenizer(docPtr(),m_view); -} - -void DocumentImpl::setPaintDevice( TQPaintDevice *dev ) -{ - if (m_paintDevice != dev) { - m_paintDevice = dev; - delete m_paintDeviceMetrics; - m_paintDeviceMetrics = new TQPaintDeviceMetrics( dev ); - } -} - -void DocumentImpl::open( bool clearEventListeners ) -{ - if (parsing()) return; - - if (m_tokenizer) - close(); - - delete m_tokenizer; - m_tokenizer = 0; - - KHTMLView* view = m_view; - bool was_attached = attached(); - if ( was_attached ) - detach(); - - removeChildren(); - delete m_styleSelector; - m_styleSelector = 0; - m_view = view; - if ( was_attached ) - attach(); - - if (clearEventListeners) - m_windowEventListeners.clear(); - - m_tokenizer = createTokenizer(); - m_decoderMibEnum = 0; - connect(m_tokenizer,TQT_SIGNAL(finishedParsing()),this,TQT_SIGNAL(finishedParsing())); - m_tokenizer->begin(); -} - -HTMLElementImpl* DocumentImpl::body() -{ - NodeImpl *de = documentElement(); - if (!de) - return 0; - - // try to prefer a FRAMESET element over BODY - NodeImpl* body = 0; - for (NodeImpl* i = de->firstChild(); i; i = i->nextSibling()) { - if (i->id() == ID_FRAMESET) - return static_cast<HTMLElementImpl*>(i); - - if (i->id() == ID_BODY) - body = i; - } - return static_cast<HTMLElementImpl *>(body); -} - -void DocumentImpl::close( ) -{ - if (parsing() || !m_tokenizer) return; - - if ( m_render ) - m_render->close(); - - // on an explicit document.close(), the tokenizer might still be waiting on scripts, - // and in that case we don't want to destroy it because that will prevent the - // scripts from getting processed. - if (m_tokenizer && !m_tokenizer->isWaitingForScripts() && !m_tokenizer->isExecutingScript()) { - delete m_tokenizer; - m_tokenizer = 0; - } - - if (m_view) - m_view->part()->checkEmitLoadEvent(); -} - -void DocumentImpl::write( const DOMString &text ) -{ - write(text.string()); -} - -void DocumentImpl::write( const TQString &text ) -{ - if (!m_tokenizer) { - open(); - if (m_view) - m_view->part()->resetFromScript(); - m_tokenizer->setAutoClose(); - write(TQString::fromLatin1("<html>")); - } - m_tokenizer->write(text, false); -} - -void DocumentImpl::writeln( const DOMString &text ) -{ - write(text); - write(DOMString("\n")); -} - -void DocumentImpl::finishParsing ( ) -{ - if(m_tokenizer) - m_tokenizer->finish(); -} - -void DocumentImpl::setUserStyleSheet( const TQString& sheet ) -{ - if ( m_usersheet != sheet ) { - m_usersheet = sheet; - updateStyleSelector(); - } -} - -CSSStyleSheetImpl* DocumentImpl::elementSheet() -{ - if (!m_elemSheet) { - m_elemSheet = new CSSStyleSheetImpl(this, baseURL().url() ); - m_elemSheet->ref(); - } - return m_elemSheet; -} - -void DocumentImpl::determineParseMode( const TQString &/*str*/ ) -{ - // For XML documents, use strict parse mode - pMode = Strict; - hMode = XHtml; - kdDebug(6020) << " using strict parseMode" << endl; -} - -NodeImpl *DocumentImpl::nextFocusNode(NodeImpl *fromNode) -{ - unsigned short fromTabIndex; - - if (!fromNode) { - // No starting node supplied; begin with the top of the document - NodeImpl *n; - - int lowestTabIndex = 65535; - for (n = this; n != 0; n = n->traverseNextNode()) { - if (n->isTabFocusable()) { - if ((n->tabIndex() > 0) && (n->tabIndex() < lowestTabIndex)) - lowestTabIndex = n->tabIndex(); - } - } - - if (lowestTabIndex == 65535) - lowestTabIndex = 0; - - // Go to the first node in the document that has the desired tab index - for (n = this; n != 0; n = n->traverseNextNode()) { - if (n->isTabFocusable() && (n->tabIndex() == lowestTabIndex)) - return n; - } - - return 0; - } - else { - fromTabIndex = fromNode->tabIndex(); - } - - if (fromTabIndex == 0) { - // Just need to find the next selectable node after fromNode (in document order) that doesn't have a tab index - NodeImpl *n = fromNode->traverseNextNode(); - while (n && !(n->isTabFocusable() && n->tabIndex() == 0)) - n = n->traverseNextNode(); - return n; - } - else { - // Find the lowest tab index out of all the nodes except fromNode, that is greater than or equal to fromNode's - // tab index. For nodes with the same tab index as fromNode, we are only interested in those that come after - // fromNode in document order. - // If we don't find a suitable tab index, the next focus node will be one with a tab index of 0. - unsigned short lowestSuitableTabIndex = 65535; - NodeImpl *n; - - bool reachedFromNode = false; - for (n = this; n != 0; n = n->traverseNextNode()) { - if (n->isTabFocusable() && - ((reachedFromNode && (n->tabIndex() >= fromTabIndex)) || - (!reachedFromNode && (n->tabIndex() > fromTabIndex))) && - (n->tabIndex() < lowestSuitableTabIndex) && - (n != fromNode)) { - - // We found a selectable node with a tab index at least as high as fromNode's. Keep searching though, - // as there may be another node which has a lower tab index but is still suitable for use. - lowestSuitableTabIndex = n->tabIndex(); - } - - if (n == fromNode) - reachedFromNode = true; - } - - if (lowestSuitableTabIndex == 65535) { - // No next node with a tab index -> just take first node with tab index of 0 - NodeImpl *n = this; - while (n && !(n->isTabFocusable() && n->tabIndex() == 0)) - n = n->traverseNextNode(); - return n; - } - - // Search forwards from fromNode - for (n = fromNode->traverseNextNode(); n != 0; n = n->traverseNextNode()) { - if (n->isTabFocusable() && (n->tabIndex() == lowestSuitableTabIndex)) - return n; - } - - // The next node isn't after fromNode, start from the beginning of the document - for (n = this; n != fromNode; n = n->traverseNextNode()) { - if (n->isTabFocusable() && (n->tabIndex() == lowestSuitableTabIndex)) - return n; - } - - assert(false); // should never get here - return 0; - } -} - -NodeImpl *DocumentImpl::previousFocusNode(NodeImpl *fromNode) -{ - NodeImpl *lastNode = this; - while (lastNode->lastChild()) - lastNode = lastNode->lastChild(); - - if (!fromNode) { - // No starting node supplied; begin with the very last node in the document - NodeImpl *n; - - int highestTabIndex = 0; - for (n = lastNode; n != 0; n = n->traversePreviousNode()) { - if (n->isTabFocusable()) { - if (n->tabIndex() == 0) - return n; - else if (n->tabIndex() > highestTabIndex) - highestTabIndex = n->tabIndex(); - } - } - - // No node with a tab index of 0; just go to the last node with the highest tab index - for (n = lastNode; n != 0; n = n->traversePreviousNode()) { - if (n->isTabFocusable() && (n->tabIndex() == highestTabIndex)) - return n; - } - - return 0; - } - else { - unsigned short fromTabIndex = fromNode->tabIndex(); - - if (fromTabIndex == 0) { - // Find the previous selectable node before fromNode (in document order) that doesn't have a tab index - NodeImpl *n = fromNode->traversePreviousNode(); - while (n && !(n->isTabFocusable() && n->tabIndex() == 0)) - n = n->traversePreviousNode(); - if (n) - return n; - - // No previous nodes with a 0 tab index, go to the last node in the document that has the highest tab index - int highestTabIndex = 0; - for (n = this; n != 0; n = n->traverseNextNode()) { - if (n->isTabFocusable() && (n->tabIndex() > highestTabIndex)) - highestTabIndex = n->tabIndex(); - } - - if (highestTabIndex == 0) - return 0; - - for (n = lastNode; n != 0; n = n->traversePreviousNode()) { - if (n->isTabFocusable() && (n->tabIndex() == highestTabIndex)) - return n; - } - - assert(false); // should never get here - return 0; - } - else { - // Find the lowest tab index out of all the nodes except fromNode, that is less than or equal to fromNode's - // tab index. For nodes with the same tab index as fromNode, we are only interested in those before - // fromNode. - // If we don't find a suitable tab index, then there will be no previous focus node. - unsigned short highestSuitableTabIndex = 0; - NodeImpl *n; - - bool reachedFromNode = false; - for (n = this; n != 0; n = n->traverseNextNode()) { - if (n->isTabFocusable() && - ((!reachedFromNode && (n->tabIndex() <= fromTabIndex)) || - (reachedFromNode && (n->tabIndex() < fromTabIndex))) && - (n->tabIndex() > highestSuitableTabIndex) && - (n != fromNode)) { - - // We found a selectable node with a tab index no higher than fromNode's. Keep searching though, as - // there may be another node which has a higher tab index but is still suitable for use. - highestSuitableTabIndex = n->tabIndex(); - } - - if (n == fromNode) - reachedFromNode = true; - } - - if (highestSuitableTabIndex == 0) { - // No previous node with a tab index. Since the order specified by HTML is nodes with tab index > 0 - // first, this means that there is no previous node. - return 0; - } - - // Search backwards from fromNode - for (n = fromNode->traversePreviousNode(); n != 0; n = n->traversePreviousNode()) { - if (n->isTabFocusable() && (n->tabIndex() == highestSuitableTabIndex)) - return n; - } - // The previous node isn't before fromNode, start from the end of the document - for (n = lastNode; n != fromNode; n = n->traversePreviousNode()) { - if (n->isTabFocusable() && (n->tabIndex() == highestSuitableTabIndex)) - return n; - } - - assert(false); // should never get here - return 0; - } - } -} - -ElementImpl* DocumentImpl::findAccessKeyElement(TQChar c) -{ - c = c.upper(); - for( NodeImpl* n = this; - n != NULL; - n = n->traverseNextNode()) { - if( n->isElementNode()) { - ElementImpl* en = static_cast< ElementImpl* >( n ); - DOMString s = en->getAttribute( ATTR_ACCESSKEY ); - if( s.length() == 1 - && s[ 0 ].upper() == c ) - return en; - } - } - return NULL; -} - -int DocumentImpl::nodeAbsIndex(NodeImpl *node) -{ - assert(node->getDocument() == this); - - int absIndex = 0; - for (NodeImpl *n = node; n && n != this; n = n->traversePreviousNode()) - absIndex++; - return absIndex; -} - -NodeImpl *DocumentImpl::nodeWithAbsIndex(int absIndex) -{ - NodeImpl *n = this; - for (int i = 0; n && (i < absIndex); i++) { - n = n->traverseNextNode(); - } - return n; -} - -void DocumentImpl::processHttpEquiv(const DOMString &equiv, const DOMString &content) -{ - assert(!equiv.isNull() && !content.isNull()); - - KHTMLView *v = getDocument()->view(); - - if(strcasecmp(equiv, "refresh") == 0 && v && v->part()->metaRefreshEnabled()) - { - // get delay and url - TQString str = content.string().stripWhiteSpace(); - int pos = str.find(TQRegExp("[;,]")); - if ( pos == -1 ) - pos = str.find(TQRegExp("[ \t]")); - - bool ok = false; - int delay = kMax( 0, content.implementation()->toInt(&ok) ); - if ( !ok && str.length() && str[0] == '.' ) - ok = true; - - if (pos == -1) // There can be no url (David) - { - if(ok) - v->part()->scheduleRedirection(delay, v->part()->url().url() ); - } else { - pos++; - while(pos < (int)str.length() && str[pos].isSpace()) pos++; - str = str.mid(pos); - if(str.find("url", 0, false ) == 0) str = str.mid(3); - str = str.stripWhiteSpace(); - if ( str.length() && str[0] == '=' ) str = str.mid( 1 ).stripWhiteSpace(); - while(str.length() && - (str[str.length()-1] == ';' || str[str.length()-1] == ',')) - str.setLength(str.length()-1); - str = parseURL( DOMString(str) ).string(); - TQString newURL = getDocument()->completeURL( str ); - if ( ok ) - v->part()->scheduleRedirection(delay, getDocument()->completeURL( str ), delay < 2 || newURL == URL().url()); - } - } - else if(strcasecmp(equiv, "expires") == 0) - { - bool relative = false; - TQString str = content.string().stripWhiteSpace(); - time_t expire_date = KRFCDate::parseDate(str); - if (!expire_date) - { - expire_date = str.toULong(); - relative = true; - } - if (!expire_date) - expire_date = 1; // expire now - if (m_docLoader) - m_docLoader->setExpireDate(expire_date, relative); - } - else if(v && (strcasecmp(equiv, "pragma") == 0 || strcasecmp(equiv, "cache-control") == 0)) - { - TQString str = content.string().lower().stripWhiteSpace(); - KURL url = v->part()->url(); - if ((str == "no-cache") && url.protocol().startsWith("http")) - { - TDEIO::http_update_cache(url, true, 0); - } - } - else if( (strcasecmp(equiv, "set-cookie") == 0)) - { - // ### make setCookie work on XML documents too; e.g. in case of <html:meta .....> - HTMLDocumentImpl *d = static_cast<HTMLDocumentImpl *>(this); - d->setCookie(content); - } - else if (strcasecmp(equiv, "default-style") == 0) { - // HTML 4.0 14.3.2 - // http://www.hixie.ch/tests/evil/css/import/main/preferred.html - m_preferredStylesheetSet = content; - updateStyleSelector(); - } - else if (strcasecmp(equiv, "content-language") == 0) { - m_contentLanguage = content.string(); - } -} - -bool DocumentImpl::prepareMouseEvent( bool readonly, int _x, int _y, MouseEvent *ev ) -{ - if ( m_render ) { - assert(m_render->isCanvas()); - RenderObject::NodeInfo renderInfo(readonly, ev->type == MousePress); - bool isInside = m_render->layer()->nodeAtPoint(renderInfo, _x, _y); - ev->innerNode = renderInfo.innerNode(); - ev->innerNonSharedNode = renderInfo.innerNonSharedNode(); - - if (renderInfo.URLElement()) { - assert(renderInfo.URLElement()->isElementNode()); - //tqDebug("urlnode: %s (%d)", getTagName(renderInfo.URLElement()->id()).string().latin1(), renderInfo.URLElement()->id()); - - ElementImpl* e = static_cast<ElementImpl*>(renderInfo.URLElement()); - DOMString href = khtml::parseURL(e->getAttribute(ATTR_HREF)); - DOMString target = e->getAttribute(ATTR_TARGET); - - if (!target.isNull() && !href.isNull()) { - ev->target = target; - ev->url = href; - } - else - ev->url = href; - } - - if (!readonly) - updateRendering(); - - return isInside; - } - - - return false; -} - - -// DOM Section 1.1.1 -bool DocumentImpl::childTypeAllowed( unsigned short type ) -{ - switch (type) { - case Node::ATTRIBUTE_NODE: - case Node::CDATA_SECTION_NODE: - case Node::DOCUMENT_FRAGMENT_NODE: - case Node::DOCUMENT_NODE: - case Node::ENTITY_NODE: - case Node::ENTITY_REFERENCE_NODE: - case Node::NOTATION_NODE: - case Node::TEXT_NODE: -// case Node::XPATH_NAMESPACE_NODE: - return false; - case Node::COMMENT_NODE: - case Node::PROCESSING_INSTRUCTION_NODE: - return true; - case Node::DOCUMENT_TYPE_NODE: - case Node::ELEMENT_NODE: - // Documents may contain no more than one of each of these. - // (One Element and one DocumentType.) - for (NodeImpl* c = firstChild(); c; c = c->nextSibling()) - if (c->nodeType() == type) - return false; - return true; - } - return false; -} - -NodeImpl *DocumentImpl::cloneNode ( bool /*deep*/ ) -{ - // Spec says cloning Document nodes is "implementation dependent" - // so we do not support it... - return 0; -} - - -typedef const char* (*NameLookupFunction)(unsigned short id); -typedef int (*IdLookupFunction)(const char *tagStr, int len); - -NodeImpl::Id DocumentImpl::getId( NodeImpl::IdType _type, DOMStringImpl* _nsURI, DOMStringImpl *_prefix, - DOMStringImpl *_name, bool readonly, bool /*lookupHTML*/, int *pExceptioncode) -{ - /*kdDebug() << "DocumentImpl::getId( type: " << _type << ", uri: " << DOMString(_nsURI).string() - << ", prefix: " << DOMString(_prefix).string() << ", name: " << DOMString(_name).string() - << ", readonly: " << readonly - << ", lookupHTML: " << lookupHTML - << ", exceptions: " << (pExceptioncode ? "yes" : "no") - << " )" << endl;*/ - - if(!_name) return 0; - IdNameMapping *map; - IdLookupFunction lookup; - - switch (_type) { - case NodeImpl::ElementId: - map = m_elementMap; - lookup = getTagID; - break; - case NodeImpl::AttributeId: - map = m_attrMap; - lookup = getAttrID; - break; - case NodeImpl::NamespaceId: - if( strcasecmp(_name, XHTML_NAMESPACE) == 0) - return xhtmlNamespace; - if( _name->l == 0) - return emptyNamespace; - // defaultNamespace handled by "if (!_name) return 0" - map = m_namespaceMap; - lookup = 0; - break; - default: - return 0; - } - // Names and attributes with "" - if (_name->l == 0) return 0; - - NodeImpl::Id id, nsid = 0; - TQConstString n(_name->s, _name->l); - bool cs = true; // case sensitive - if (_type != NodeImpl::NamespaceId) { - if (_nsURI) - nsid = getId( NodeImpl::NamespaceId, 0, 0, _nsURI, false, false, 0 ) << 16; - - // Each document maintains a mapping of tag name -> id for every tag name encountered - // in the document. - cs = (htmlMode() == XHtml) || (_nsURI && _type != NodeImpl::AttributeId); - - // First see if it's a HTML element name - // xhtml is lower case - case sensitive, easy to implement - if ( cs && (id = lookup(n.string().ascii(), _name->l)) ) { - map->addAlias(_prefix, _name, cs, id); - return nsid + id; - } - // compatibility: upper case - case insensitive - if ( !cs && (id = lookup(n.string().lower().ascii(), _name->l )) ) { - map->addAlias(_prefix, _name, cs, id); - return nsid + id; - } - } - - // Look in the names array for the name - // compatibility mode has to lookup upper case - TQString name = cs ? n.string() : n.string().upper(); - - if (!_nsURI) { - id = (NodeImpl::Id)(long) map->ids.find( name ); - if (!id && _type != NodeImpl::NamespaceId) { - id = (NodeImpl::Id)(long) map->ids.find( "aliases: " + name ); - } - } else { - id = (NodeImpl::Id)(long) map->ids.find( name ); - if (!readonly && id && _prefix && _prefix->l) { - // we were called in registration mode... check if the alias exists - TQConstString px( _prefix->s, _prefix->l ); - TQString qn("aliases: " + (cs ? px.string() : px.string().upper()) + ":" + name); - if (!map->ids.find( qn )) { - map->ids.insert( qn, (void*)id ); - } - } - } - - if (id) return nsid + id; - - // unknown - if (readonly) return 0; - - if ( pExceptioncode && _type != NodeImpl::NamespaceId && !Element::khtmlValidQualifiedName(_name)) { - *pExceptioncode = DOMException::INVALID_CHARACTER_ERR; - return 0; - } - - // Name not found, so let's add it - NodeImpl::Id cid = map->count++ + map->idStart; - map->names.insert( cid, _name ); - _name->ref(); - - map->ids.insert( name, (void*)cid ); - - // and register an alias if needed for DOM1 methods compatibility - map->addAlias(_prefix, _name, cs, cid); - - return nsid + cid; - } - -NodeImpl::Id DocumentImpl::getId( NodeImpl::IdType _type, DOMStringImpl *_nodeName, bool readonly, bool lookupHTML, int *pExceptioncode) -{ - return getId(_type, 0, 0, _nodeName, readonly, lookupHTML, pExceptioncode); -} - -DOMString DocumentImpl::getName( NodeImpl::IdType _type, NodeImpl::Id _id ) const -{ - IdNameMapping *map; - NameLookupFunction lookup; - bool hasNS = (namespacePart(_id) != defaultNamespace); - switch (_type) { - case NodeImpl::ElementId: - map = m_elementMap; - lookup = getTagName; - break; - case NodeImpl::AttributeId: - map = m_attrMap; - lookup = getAttrName; - break; - case NodeImpl::NamespaceId: - if( _id == xhtmlNamespace ) - return XHTML_NAMESPACE; - else - if( _id == emptyNamespace ) - return DOMString(""); - else - if ( _id == defaultNamespace ) - return DOMString(); - map = m_namespaceMap; - lookup = 0; - break; - default: - return DOMString();; - } - _id = localNamePart(_id) ; - if (_id >= map->idStart) { - return map->names[_id]; - } - else if (lookup) { - // ### put them in a cache - if (hasNS) - return DOMString(lookup(_id)).lower(); - else - return lookup(_id); - } else - return DOMString(); -} - -// This method is called whenever a top-level stylesheet has finished loading. -void DocumentImpl::styleSheetLoaded() -{ - // Make sure we knew this sheet was pending, and that our count isn't out of sync. - assert(m_pendingStylesheets > 0); - - m_pendingStylesheets--; - updateStyleSelector(); -} - -DOMString DocumentImpl::selectedStylesheetSet() const -{ - if (!view()) return DOMString(); - - return view()->part()->d->m_sheetUsed; -} - -void DocumentImpl::setSelectedStylesheetSet(const DOMString& s) -{ - // this code is evil - if (view() && view()->part()->d->m_sheetUsed != s.string()) { - view()->part()->d->m_sheetUsed = s.string(); - updateStyleSelector(); - } -} - -void DocumentImpl::addStyleSheet(StyleSheetImpl *sheet, int *exceptioncode) -{ - int excode = 0; - - if (!m_addedStyleSheets) { - m_addedStyleSheets = new StyleSheetListImpl; - m_addedStyleSheets->ref(); - } - - m_addedStyleSheets->add(sheet); - if (sheet->isCSSStyleSheet()) updateStyleSelector(); - - if (exceptioncode) *exceptioncode = excode; -} - -void DocumentImpl::removeStyleSheet(StyleSheetImpl *sheet, int *exceptioncode) -{ - int excode = 0; - bool removed = false; - bool is_css = sheet->isCSSStyleSheet(); - - if (m_addedStyleSheets) { - bool in_main_list = !sheet->hasOneRef(); - removed = m_addedStyleSheets->styleSheets.removeRef(sheet); - sheet->deref(); - - if (m_addedStyleSheets->styleSheets.count() == 0) { - bool reset = m_addedStyleSheets->hasOneRef(); - m_addedStyleSheets->deref(); - if (reset) m_addedStyleSheets = 0; - } - - // remove from main list, too - if (in_main_list) m_styleSheets->remove(sheet); - } - - if (removed) { - if (is_css) updateStyleSelector(); - } else - excode = DOMException::NOT_FOUND_ERR; - - if (exceptioncode) *exceptioncode = excode; -} - -void DocumentImpl::updateStyleSelector(bool shallow) -{ -// kdDebug() << "PENDING " << m_pendingStylesheets << endl; - - // Don't bother updating, since we haven't loaded all our style info yet. - if (m_pendingStylesheets > 0) - return; - - if (shallow) - rebuildStyleSelector(); - else - recalcStyleSelector(); - recalcStyle(Force); -#if 0 - - m_styleSelectorDirty = true; -#endif - if ( renderer() ) - renderer()->setNeedsLayoutAndMinMaxRecalc(); -} - -void DocumentImpl::recalcStyleSelector() -{ - if ( !m_render || !attached() ) return; - - assert(m_pendingStylesheets==0); - - TQPtrList<StyleSheetImpl> oldStyleSheets = m_styleSheets->styleSheets; - m_styleSheets->styleSheets.clear(); - TQString sheetUsed = view() ? view()->part()->d->m_sheetUsed.replace("&&", "&") : TQString(); - bool autoselect = sheetUsed.isEmpty(); - if (autoselect && !m_preferredStylesheetSet.isEmpty()) - sheetUsed = m_preferredStylesheetSet.string(); - NodeImpl *n; - for (int i=0 ; i<2 ; i++) { - m_availableSheets.clear(); - m_availableSheets << i18n("Basic Page Style"); - bool canResetSheet = false; - - for (n = this; n; n = n->traverseNextNode()) { - StyleSheetImpl *sheet = 0; - - if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) - { - // Processing instruction (XML documents only) - ProcessingInstructionImpl* pi = static_cast<ProcessingInstructionImpl*>(n); - sheet = pi->sheet(); - if (!sheet && !pi->localHref().isEmpty()) - { - // Processing instruction with reference to an element in this document - e.g. - // <?xml-stylesheet href="#mystyle">, with the element - // <foo id="mystyle">heading { color: red; }</foo> at some location in - // the document - ElementImpl* elem = getElementById(pi->localHref()); - if (elem) { - DOMString sheetText(""); - NodeImpl *c; - for (c = elem->firstChild(); c; c = c->nextSibling()) { - if (c->nodeType() == Node::TEXT_NODE || c->nodeType() == Node::CDATA_SECTION_NODE) - sheetText += c->nodeValue(); - } - - CSSStyleSheetImpl *cssSheet = new CSSStyleSheetImpl(this); - cssSheet->parseString(sheetText); - pi->setStyleSheet(cssSheet); - sheet = cssSheet; - } - } - - } - else if (n->isHTMLElement() && ( n->id() == ID_LINK || n->id() == ID_STYLE) ) { - TQString title; - if ( n->id() == ID_LINK ) { - HTMLLinkElementImpl* l = static_cast<HTMLLinkElementImpl*>(n); - if (l->isCSSStyleSheet()) { - sheet = l->sheet(); - - if (sheet || l->isLoading() || l->isAlternate() ) - title = l->getAttribute(ATTR_TITLE).string(); - - if ((autoselect || title != sheetUsed) && l->isDisabled()) { - sheet = 0; - } else if (!title.isEmpty() && !l->isAlternate() && sheetUsed.isEmpty()) { - sheetUsed = title; - l->setDisabled(false); - } - } - } - else { - // <STYLE> element - HTMLStyleElementImpl* s = static_cast<HTMLStyleElementImpl*>(n); - if (!s->isLoading()) { - sheet = s->sheet(); - if (sheet) title = s->getAttribute(ATTR_TITLE).string(); - } - if (!title.isEmpty() && sheetUsed.isEmpty()) - sheetUsed = title; - } - - if ( !title.isEmpty() ) { - if ( title != sheetUsed ) - sheet = 0; // don't use it - - title = title.replace('&', "&&"); - - if ( !m_availableSheets.contains( title ) ) - m_availableSheets.append( title ); - } - } - else if (n->isHTMLElement() && n->id() == ID_BODY) { - // <BODY> element (doesn't contain styles as such but vlink="..." and friends - // are treated as style declarations) - sheet = static_cast<HTMLBodyElementImpl*>(n)->sheet(); - } - - if (sheet) { - sheet->ref(); - m_styleSheets->styleSheets.append(sheet); - } - - // For HTML documents, stylesheets are not allowed within/after the <BODY> tag. So we - // can stop searching here. - if (isHTMLDocument() && n->id() == ID_BODY) { - canResetSheet = !canResetSheet; - break; - } - } - - // we're done if we don't select an alternative sheet - // or we found the sheet we selected - if (sheetUsed.isEmpty() || - (!canResetSheet && tokenizer()) || - m_availableSheets.contains(sheetUsed)) { - break; - } - - // the alternative sheet we used doesn't exist anymore - // so try from scratch again - if (view()) - view()->part()->d->m_sheetUsed = TQString::null; - if (!m_preferredStylesheetSet.isEmpty() && !(sheetUsed == m_preferredStylesheetSet)) - sheetUsed = m_preferredStylesheetSet.string(); - else - sheetUsed = TQString::null; - autoselect = true; - } - - // Include programmatically added style sheets - if (m_addedStyleSheets) { - TQPtrListIterator<StyleSheetImpl> it = m_addedStyleSheets->styleSheets; - for (; *it; ++it) { - if ((*it)->isCSSStyleSheet() && !(*it)->disabled()) - m_styleSheets->add(*it); - } - } - - // De-reference all the stylesheets in the old list - TQPtrListIterator<StyleSheetImpl> it(oldStyleSheets); - for (; it.current(); ++it) - it.current()->deref(); - - rebuildStyleSelector(); -} - -void DocumentImpl::rebuildStyleSelector() -{ - // Create a new style selector - delete m_styleSelector; - TQString usersheet = m_usersheet; - if ( m_view && m_view->mediaType() == "print" ) - usersheet += m_printSheet; - m_styleSelector = new CSSStyleSelector( this, usersheet, m_styleSheets, m_url, - !inCompatMode() ); - - m_styleSelectorDirty = false; -} - -void DocumentImpl::setHoverNode(NodeImpl *newHoverNode) -{ - NodeImpl* oldHoverNode = m_hoverNode; - if (newHoverNode ) newHoverNode->ref(); - m_hoverNode = newHoverNode; - if ( oldHoverNode ) oldHoverNode->deref(); -} - -void DocumentImpl::setActiveNode(NodeImpl* newActiveNode) -{ - NodeImpl* oldActiveNode = m_activeNode; - if (newActiveNode ) newActiveNode->ref(); - m_activeNode = newActiveNode; - if ( oldActiveNode ) oldActiveNode->deref(); -} - -void DocumentImpl::setFocusNode(NodeImpl *newFocusNode) -{ - // don't process focus changes while detaching - if( !m_render ) return; - - // We do want to blur if a widget is being detached, - // but we don't want to emit events since that - // triggers updateLayout() and may recurse detach() - bool widgetDetach = m_focusNode && m_focusNode != this && - m_focusNode->renderer() && !m_focusNode->renderer()->parent(); - - // Make sure newFocusNode is actually in this document - if (newFocusNode && (newFocusNode->getDocument() != this)) - return; - - if (m_focusNode != newFocusNode) { - NodeImpl *oldFocusNode = m_focusNode; - // Set focus on the new node - m_focusNode = newFocusNode; - // Remove focus from the existing focus node (if any) - if (oldFocusNode) { - if (oldFocusNode->active()) - oldFocusNode->setActive(false); - - oldFocusNode->setFocus(false); - - if (!widgetDetach) { - oldFocusNode->dispatchHTMLEvent(EventImpl::BLUR_EVENT,false,false); - oldFocusNode->dispatchUIEvent(EventImpl::DOMFOCUSOUT_EVENT); - } - if ((oldFocusNode == this) && oldFocusNode->hasOneRef()) { - oldFocusNode->deref(); // deletes this - return; - } - else { - oldFocusNode->deref(); - } - } - - if (m_focusNode) { - m_focusNode->ref(); - m_focusNode->dispatchHTMLEvent(EventImpl::FOCUS_EVENT,false,false); - if (m_focusNode != newFocusNode) return; - m_focusNode->dispatchUIEvent(EventImpl::DOMFOCUSIN_EVENT); - if (m_focusNode != newFocusNode) return; - m_focusNode->setFocus(); - if (m_focusNode != newFocusNode) return; - - // eww, I suck. set the qt focus correctly - // ### find a better place in the code for this - if (view()) { - if (!m_focusNode->renderer() || !m_focusNode->renderer()->isWidget()) - view()->setFocus(); - else if (static_cast<RenderWidget*>(m_focusNode->renderer())->widget()) - { - if (view()->isVisible()) - static_cast<RenderWidget*>(m_focusNode->renderer())->widget()->setFocus(); - } - } - } else { - //We're blurring. Better clear the Qt focus/give it to the view... - if (view()) - view()->setFocus(); - } - - if (!widgetDetach) - updateRendering(); - } -} - -void DocumentImpl::setCSSTarget(NodeImpl* n) -{ - if (n == m_cssTarget) - return; - - if (m_cssTarget) { - m_cssTarget->setChanged(); - m_cssTarget->deref(); - } - m_cssTarget = n; - if (n) { - n->setChanged(); - n->ref(); - } -} - -void DocumentImpl::attachNodeIterator(NodeIteratorImpl *ni) -{ - m_nodeIterators.append(ni); -} - -void DocumentImpl::detachNodeIterator(NodeIteratorImpl *ni) -{ - m_nodeIterators.remove(ni); -} - -void DocumentImpl::notifyBeforeNodeRemoval(NodeImpl *n) -{ - TQPtrListIterator<NodeIteratorImpl> it(m_nodeIterators); - for (; it.current(); ++it) - it.current()->notifyBeforeNodeRemoval(n); -} - -bool DocumentImpl::isURLAllowed(const TQString& url) const -{ - KHTMLPart *thisPart = part(); - - KURL newURL(completeURL(url)); - newURL.setRef(TQString::null); - - if (KHTMLFactory::defaultHTMLSettings()->isAdFiltered( newURL.url() )) - return false; - - // Prohibit non-file URLs if we are asked to. - if (!thisPart || thisPart->onlyLocalReferences() && newURL.protocol() != "file" && newURL.protocol() != "data") - return false; - - // do we allow this suburl ? - if ( !kapp || (newURL.protocol() != "javascript" && !kapp->authorizeURLAction("redirect", thisPart->url(), newURL)) ) - return false; - - // We allow one level of self-reference because some sites depend on that. - // But we don't allow more than one. - bool foundSelfReference = false; - for (KHTMLPart *part = thisPart; part; part = part->parentPart()) { - KURL partURL = part->url(); - partURL.setRef(TQString::null); - if (partURL == newURL) { - if (foundSelfReference) - return false; - foundSelfReference = true; - } - } - - return true; -} - -void DocumentImpl::setDesignMode(bool b) -{ - if (part()) - part()->setEditable(b); -} - -bool DocumentImpl::designMode() const -{ - return part() ? part()->isEditable() : false; -} - -EventImpl *DocumentImpl::createEvent(const DOMString &eventType, int &exceptioncode) -{ - if (eventType == "UIEvents" || eventType == "UIEvent") - return new UIEventImpl(); - else if (eventType == "MouseEvents" || eventType == "MouseEvent") - return new MouseEventImpl(); - else if (eventType == "TextEvent") - return new TextEventImpl(); - else if (eventType == "KeyboardEvent") - return new KeyboardEventImpl(); - else if (eventType == "MutationEvents" || eventType == "MutationEvent") - return new MutationEventImpl(); - else if (eventType == "HTMLEvents" || eventType == "Events" || - eventType == "HTMLEvent" || eventType == "Event") - return new EventImpl(); - else { - exceptioncode = DOMException::NOT_SUPPORTED_ERR; - return 0; - } -} - -CSSStyleDeclarationImpl *DocumentImpl::getOverrideStyle(ElementImpl* /*elt*/, DOMStringImpl* /*pseudoElt*/) -{ - return 0; // ### -} - -void DocumentImpl::abort() -{ - if (m_inSyncLoad) { - m_inSyncLoad = false; - kapp->exit_loop(); - } - - if (m_loadingXMLDoc) - m_loadingXMLDoc->deref(this); - m_loadingXMLDoc = 0; -} - -void DocumentImpl::load(const DOMString &uri) -{ - if (m_inSyncLoad) { - m_inSyncLoad = false; - kapp->exit_loop(); - } - - m_hadLoadError = false; - if (m_loadingXMLDoc) - m_loadingXMLDoc->deref(this); - - // Use the document loader to retrieve the XML file. We use CachedCSSStyleSheet because - // this is an easy way to retrieve an arbitrary text file... it is not specific to - // stylesheets. - - // ### Note: By loading the XML document this way we do not get the proper decoding - // of the data retrieved from the server based on the character set, as happens with - // HTML files. Need to look into a way of using the decoder in CachedCSSStyleSheet. - m_docLoading = true; - m_loadingXMLDoc = m_docLoader->requestStyleSheet(uri.string(),TQString(),"text/xml"); - - if (!m_loadingXMLDoc) { - m_docLoading = false; - return; - } - - m_loadingXMLDoc->ref(this); - - if (!m_async && m_docLoading) { - m_inSyncLoad = true; - kapp->enter_loop(); - } -} - -void DocumentImpl::loadXML(const DOMString &source) -{ - open(false); - write(source); - finishParsing(); - close(); - dispatchHTMLEvent(EventImpl::LOAD_EVENT,false,false); -} - -void DocumentImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset) -{ - if (!m_hadLoadError) { - m_url = url.string(); - loadXML(sheet); - } - - m_docLoading = false; - if (m_inSyncLoad) { - m_inSyncLoad = false; - kapp->exit_loop(); - } - - assert(m_loadingXMLDoc != 0); - m_loadingXMLDoc->deref(this); - m_loadingXMLDoc = 0; -} - -void DocumentImpl::error(int err, const TQString &text) -{ - m_docLoading = false; - if (m_inSyncLoad) { - m_inSyncLoad = false; - kapp->exit_loop(); - } - - m_hadLoadError = true; - - int exceptioncode = 0; - EventImpl *evt = new EventImpl(EventImpl::ERROR_EVENT,false,false); - if (err != 0) - evt->setMessage(TDEIO::buildErrorString(err,text)); - else - evt->setMessage(text); - evt->ref(); - dispatchEvent(evt,exceptioncode,true); - evt->deref(); - - assert(m_loadingXMLDoc != 0); - m_loadingXMLDoc->deref(this); - m_loadingXMLDoc = 0; -} - -void DocumentImpl::defaultEventHandler(EventImpl *evt) -{ - // if any html event listeners are registered on the window, then dispatch them here - if (!m_windowEventListeners.listeners || evt->propagationStopped()) - return; - - TQValueList<RegisteredEventListener>::iterator it; - - //Grab a copy in case of clear - TQValueList<RegisteredEventListener> listeners = *m_windowEventListeners.listeners; - Event ev(evt); - for (it = listeners.begin(); it != listeners.end(); ++it) { - //Check to make sure it didn't get removed. KDE4: use Java-style iterators - if (!m_windowEventListeners.stillContainsListener(*it)) - continue; - - if ((*it).id == evt->id()) { - // currentTarget must be 0 in khtml for kjs_events to set "this" correctly. - // (this is how we identify events dispatched to the window, like window.onmousedown) - // ## currentTarget is unimplemented in IE, and is "window" in Mozilla (how? not a DOM node) - evt->setCurrentTarget(0); - (*it).listener->handleEvent(ev); - } - } -} - -void DocumentImpl::setHTMLWindowEventListener(int id, EventListener *listener) -{ - m_windowEventListeners.setHTMLEventListener(id, listener); -} - -EventListener *DocumentImpl::getHTMLWindowEventListener(int id) -{ - return m_windowEventListeners.getHTMLEventListener(id); -} - -void DocumentImpl::addWindowEventListener(int id, EventListener *listener, const bool useCapture) -{ - m_windowEventListeners.addEventListener(id, listener, useCapture); -} - -void DocumentImpl::removeWindowEventListener(int id, EventListener *listener, bool useCapture) -{ - m_windowEventListeners.removeEventListener(id, listener, useCapture); -} - -bool DocumentImpl::hasWindowEventListener(int id) -{ - return m_windowEventListeners.hasEventListener(id); -} - -EventListener *DocumentImpl::createHTMLEventListener(const TQString& code, const TQString& name, NodeImpl* node) -{ - return part() ? part()->createHTMLEventListener(code, name, node) : 0; -} - -void DocumentImpl::dispatchImageLoadEventSoon(HTMLImageElementImpl *image) -{ - m_imageLoadEventDispatchSoonList.append(image); - if (!m_imageLoadEventTimer) { - m_imageLoadEventTimer = startTimer(0); - } -} - -void DocumentImpl::removeImage(HTMLImageElementImpl *image) -{ - // Remove instances of this image from both lists. - // Use loops because we allow multiple instances to get into the lists. - while (m_imageLoadEventDispatchSoonList.removeRef(image)) { } - while (m_imageLoadEventDispatchingList.removeRef(image)) { } - if (m_imageLoadEventDispatchSoonList.isEmpty() && m_imageLoadEventTimer) { - killTimer(m_imageLoadEventTimer); - m_imageLoadEventTimer = 0; - } -} - -void DocumentImpl::dispatchImageLoadEventsNow() -{ - // need to avoid re-entering this function; if new dispatches are - // scheduled before the parent finishes processing the list, they - // will set a timer and eventually be processed - if (!m_imageLoadEventDispatchingList.isEmpty()) { - return; - } - - if (m_imageLoadEventTimer) { - killTimer(m_imageLoadEventTimer); - m_imageLoadEventTimer = 0; - } - - m_imageLoadEventDispatchingList = m_imageLoadEventDispatchSoonList; - m_imageLoadEventDispatchSoonList.clear(); - for (TQPtrListIterator<HTMLImageElementImpl> it(m_imageLoadEventDispatchingList); it.current(); ) { - HTMLImageElementImpl* image = it.current(); - // Must advance iterator *before* dispatching call. - // Otherwise, it might be advanced automatically if dispatching the call had a side effect - // of destroying the current HTMLImageElementImpl, and then we would advance past the *next* - // item, missing one altogether. - ++it; - image->dispatchLoadEvent(); - } - m_imageLoadEventDispatchingList.clear(); -} - -void DocumentImpl::timerEvent(TQTimerEvent *) -{ - dispatchImageLoadEventsNow(); -} - -void DocumentImpl::setDecoderCodec(const TQTextCodec *codec) -{ - m_decoderMibEnum = codec->mibEnum(); -} - -ElementImpl *DocumentImpl::ownerElement() const -{ - KHTMLPart *childPart = part(); - if (!childPart) - return 0; - ChildFrame *childFrame = childPart->d->m_frame; - if (!childFrame) - return 0; - RenderPart *renderPart = childFrame->m_frame; - if (!renderPart) - return 0; - return static_cast<ElementImpl *>(renderPart->element()); -} - -DOMString DocumentImpl::domain() const -{ - if ( m_domain.isEmpty() ) // not set yet (we set it on demand to save time and space) - m_domain = URL().host(); // Initially set to the host - return m_domain; -} - -void DocumentImpl::setDomain(const DOMString &newDomain) -{ - if ( m_domain.isEmpty() ) // not set yet (we set it on demand to save time and space) - m_domain = URL().host().lower(); // Initially set to the host - - if ( m_domain.isEmpty() /*&& part() && part()->openedByJS()*/ ) - m_domain = newDomain.lower(); - - // Both NS and IE specify that changing the domain is only allowed when - // the new domain is a suffix of the old domain. - int oldLength = m_domain.length(); - int newLength = newDomain.length(); - if ( newLength < oldLength ) // e.g. newDomain=kde.org (7) and m_domain=www.kde.org (11) - { - DOMString test = m_domain.copy(); - DOMString reference = newDomain.lower(); - if ( test[oldLength - newLength - 1] == '.' ) // Check that it's a subdomain, not e.g. "de.org" - { - test.remove( 0, oldLength - newLength ); // now test is "kde.org" from m_domain - if ( test == reference ) // and we check that it's the same thing as newDomain - m_domain = reference; - } - } -} - -DOMString DocumentImpl::toString() const -{ - DOMString result; - - for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) { - result += child->toString(); - } - - return result; -} - - -KHTMLPart* DOM::DocumentImpl::part() const -{ - // ### TODO: make this independent from a KHTMLView one day. - return view() ? view()->part() : 0; -} - -NodeListImpl::Cache* DOM::DocumentImpl::acquireCachedNodeListInfo( - NodeListImpl::CacheFactory* factory, NodeImpl* base, int type) -{ - //### might want to flush the dict when the version number - //changes - NodeListImpl::CacheKey key(base, type); - - //Check to see if we have this sort of item cached. - NodeListImpl::Cache* cached = - (type == NodeListImpl::UNCACHEABLE) ? 0 : m_nodeListCache.find(key.hash()); - - if (cached) { - if (cached->key == key) { - cached->ref(); //Add the nodelist's reference - return cached; - } else { - //Conflict. Drop our reference to the old item. - cached->deref(); - } - } - - //Nothing to reuse, make a new item. - NodeListImpl::Cache* newInfo = factory(); - newInfo->key = key; - newInfo->clear(this); - newInfo->ref(); //Add the nodelist's reference - - if (type != NodeListImpl::UNCACHEABLE) { - newInfo->ref(); //Add the cache's reference - m_nodeListCache.replace(key.hash(), newInfo); - } - - return newInfo; -} - -void DOM::DocumentImpl::releaseCachedNodeListInfo(NodeListImpl::Cache* entry) -{ - entry->deref(); -} - -// ---------------------------------------------------------------------------- - -DocumentFragmentImpl::DocumentFragmentImpl(DocumentImpl *doc) : NodeBaseImpl(doc) -{ -} - -DocumentFragmentImpl::DocumentFragmentImpl(const DocumentFragmentImpl &other) - : NodeBaseImpl(other) -{ -} - -DOMString DocumentFragmentImpl::nodeName() const -{ - return "#document-fragment"; -} - -unsigned short DocumentFragmentImpl::nodeType() const -{ - return Node::DOCUMENT_FRAGMENT_NODE; -} - -// DOM Section 1.1.1 -bool DocumentFragmentImpl::childTypeAllowed( unsigned short type ) -{ - switch (type) { - case Node::ELEMENT_NODE: - case Node::PROCESSING_INSTRUCTION_NODE: - case Node::COMMENT_NODE: - case Node::TEXT_NODE: - case Node::CDATA_SECTION_NODE: - case Node::ENTITY_REFERENCE_NODE: - return true; - break; - default: - return false; - } -} - -DOMString DocumentFragmentImpl::toString() const -{ - DOMString result; - - for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) { - result += child->toString(); - } - - return result; -} - -NodeImpl *DocumentFragmentImpl::cloneNode ( bool deep ) -{ - DocumentFragmentImpl *clone = new DocumentFragmentImpl( docPtr() ); - if (deep) - cloneChildNodes(clone); - return clone; -} - - -// ---------------------------------------------------------------------------- - -DocumentTypeImpl::DocumentTypeImpl(DOMImplementationImpl *implementation, DocumentImpl *doc, - const DOMString &qualifiedName, const DOMString &publicId, - const DOMString &systemId) - : NodeImpl(doc), m_implementation(implementation), - m_qualifiedName(qualifiedName), m_publicId(publicId), m_systemId(systemId) -{ - m_implementation->ref(); - - m_entities = 0; - m_notations = 0; - - // if doc is 0, it is not attached to a document and / or - // therefore does not provide entities or notations. (DOM Level 3) -} - -DocumentTypeImpl::~DocumentTypeImpl() -{ - m_implementation->deref(); - if (m_entities) - m_entities->deref(); - if (m_notations) - m_notations->deref(); -} - -void DocumentTypeImpl::copyFrom(const DocumentTypeImpl& other) -{ - m_qualifiedName = other.m_qualifiedName; - m_publicId = other.m_publicId; - m_systemId = other.m_systemId; - m_subset = other.m_subset; -} - -DOMString DocumentTypeImpl::toString() const -{ - DOMString result = "<!DOCTYPE"; - result += m_qualifiedName; - if (!m_publicId.isEmpty()) { - result += " PUBLIC \""; - result += m_publicId; - result += "\" \""; - result += m_systemId; - result += "\""; - } else if (!m_systemId.isEmpty()) { - result += " SYSTEM \""; - result += m_systemId; - result += "\""; - } - - if (!m_subset.isEmpty()) { - result += " ["; - result += m_subset; - result += "]"; - } - - result += ">"; - - return result; -} - -DOMString DocumentTypeImpl::nodeName() const -{ - return name(); -} - -unsigned short DocumentTypeImpl::nodeType() const -{ - return Node::DOCUMENT_TYPE_NODE; -} - -// DOM Section 1.1.1 -bool DocumentTypeImpl::childTypeAllowed( unsigned short /*type*/ ) -{ - return false; -} - -NodeImpl *DocumentTypeImpl::cloneNode ( bool /*deep*/ ) -{ - // Spec says cloning Document nodes is "implementation dependent" - // so we do not support it... - return 0; -} - -DOMStringImpl* DocumentTypeImpl::textContent() const -{ - return 0; -} - -void DocumentTypeImpl::setTextContent( const DOMString&, int& ) -{} - -NamedNodeMapImpl * DocumentTypeImpl::entities() const -{ - if ( !m_entities ) { - m_entities = new GenericRONamedNodeMapImpl( docPtr() ); - m_entities->ref(); - } - return m_entities; -} - -NamedNodeMapImpl * DocumentTypeImpl::notations() const -{ - if ( !m_notations ) { - m_notations = new GenericRONamedNodeMapImpl( docPtr() ); - m_notations->ref(); - } - return m_notations; -} - -#include "dom_docimpl.moc" diff --git a/khtml/xml/dom_docimpl.h b/khtml/xml/dom_docimpl.h deleted file mode 100644 index 5e50c09a4..000000000 --- a/khtml/xml/dom_docimpl.h +++ /dev/null @@ -1,763 +0,0 @@ -/* - * 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) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * (C) 2002-2003 Apple Computer, Inc. - * (C) 2006 Allan Sandfeld Jensen(kde@carewolf.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _DOM_DocumentImpl_h_ -#define _DOM_DocumentImpl_h_ - -#include "xml/dom_elementimpl.h" -#include "xml/dom_textimpl.h" -#include "xml/dom2_traversalimpl.h" -#include "misc/shared.h" -#include "misc/loader.h" -#include "misc/seed.h" - -#include <tqstringlist.h> -#include <tqptrlist.h> -#include <tqobject.h> -#include <tqintcache.h> -#include <tqintdict.h> -#include <tqdict.h> -#include <tqmap.h> - -#include <kurl.h> - -class TQPaintDevice; -class TQTextCodec; -class TQPaintDeviceMetrics; -class KHTMLView; - -namespace khtml { - class Tokenizer; - class CSSStyleSelector; - class DocLoader; - class CSSStyleSelectorList; - class RenderArena; - class RenderObject; - class CounterNode; - class CachedObject; - class CachedCSSStyleSheet; - class DynamicDomRestyler; -} - -namespace DOM { - - class AbstractViewImpl; - class AttrImpl; - class CDATASectionImpl; - class CSSStyleSheetImpl; - class CommentImpl; - class DocumentFragmentImpl; - class DocumentImpl; - class DocumentType; - class DocumentTypeImpl; - class ElementImpl; - class EntityReferenceImpl; - class EventImpl; - class EventListener; - class GenericRONamedNodeMapImpl; - class HTMLDocumentImpl; - class HTMLElementImpl; - class HTMLImageElementImpl; - class NodeFilter; - class NodeFilterImpl; - class NodeIteratorImpl; - class NodeListImpl; - class ProcessingInstructionImpl; - class RangeImpl; - class RegisteredEventListener; - class StyleSheetImpl; - class StyleSheetListImpl; - class TextImpl; - class TreeWalkerImpl; - -class DOMImplementationImpl : public khtml::Shared<DOMImplementationImpl> -{ -public: - DOMImplementationImpl(); - ~DOMImplementationImpl(); - - // DOM methods & attributes for DOMImplementation - bool hasFeature ( const DOMString &feature, const DOMString &version ); - DocumentTypeImpl *createDocumentType( const DOMString &qualifiedName, const DOMString &publicId, - const DOMString &systemId, int &exceptioncode ); - DocumentImpl *createDocument( const DOMString &namespaceURI, const DOMString &qualifiedName, - const DocumentType &doctype, int &exceptioncode ); - - DOMImplementationImpl* getInterface(const DOMString& feature) const; - - // From the DOMImplementationCSS interface - CSSStyleSheetImpl *createCSSStyleSheet(DOMStringImpl *title, DOMStringImpl *media, int &exceptioncode); - - // From the HTMLDOMImplementation interface - HTMLDocumentImpl* createHTMLDocument( const DOMString& title); - - // Other methods (not part of DOM) - DocumentImpl *createDocument( KHTMLView *v = 0 ); - HTMLDocumentImpl *createHTMLDocument( KHTMLView *v = 0 ); - - // Returns the static instance of this class - only one instance of this class should - // ever be present, and is used as a factory method for creating DocumentImpl objects - static DOMImplementationImpl *instance(); - -protected: - static DOMImplementationImpl *m_instance; -}; - -/** - * @internal A cache of element name (or id) to pointer - * ### KDE4, QHash: better to store values here - */ -class ElementMappingCache -{ -public: - /** - For each name, we hold a reference count, and a - pointer. If the item is in the table, which implies - reference count is > 1, the name is a valid key. - If the pointer is non-null, it points to the appropriate - mapping - */ - struct ItemInfo - { - int ref; - ElementImpl* nd; - }; - - ElementMappingCache(); - - /** - Add a pointer as just one of candidates, not neccesserily the proper one - */ - void add(const TQString& id, ElementImpl* nd); - - /** - Set the pointer as the definite mapping; it must have already been added - */ - void set(const TQString& id, ElementImpl* nd); - - /** - Remove the item; it must have already been added. - */ - void remove(const TQString& id, ElementImpl* nd); - - /** - Returns true if the item exists - */ - bool contains(const TQString& id); - - /** - Returns the information for the given ID - */ - ItemInfo* get(const TQString& id); -private: - TQDict<ItemInfo> m_dict; -}; - - -/** - * @internal - */ -class DocumentImpl : public TQObject, private khtml::CachedObjectClient, public NodeBaseImpl -{ - Q_OBJECT -public: - DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v); - ~DocumentImpl(); - - // DOM methods & attributes for Document - - DocumentTypeImpl *doctype() const; - - DOMImplementationImpl *implementation() const; - ElementImpl *documentElement() const; - virtual ElementImpl *createElement ( const DOMString &tagName, int* pExceptioncode = 0 ); - virtual AttrImpl *createAttribute( const DOMString &tagName, int* pExceptioncode = 0 ); - DocumentFragmentImpl *createDocumentFragment (); - TextImpl *createTextNode ( DOMStringImpl* data ) { return new TextImpl( docPtr(), data); } - TextImpl *createTextNode ( const TQString& data ) - { return createTextNode(new DOMStringImpl(data.unicode(), data.length())); } - CommentImpl *createComment ( DOMStringImpl* data ); - CDATASectionImpl *createCDATASection ( DOMStringImpl* data ); - ProcessingInstructionImpl *createProcessingInstruction ( const DOMString &target, DOMStringImpl* data ); - EntityReferenceImpl *createEntityReference ( const DOMString &name ); - NodeImpl *importNode( NodeImpl *importedNode, bool deep, int &exceptioncode ); - virtual ElementImpl *createElementNS ( const DOMString &_namespaceURI, const DOMString &_qualifiedName, - int* pExceptioncode = 0 ); - virtual AttrImpl *createAttributeNS( const DOMString &_namespaceURI, const DOMString &_qualifiedName, - int* pExceptioncode = 0 ); - ElementImpl *getElementById ( const DOMString &elementId ) const; - - // Actually part of HTMLDocument, but used for giving XML documents a window title as well - DOMString title() const { return m_title; } - void setTitle(const DOMString& _title); - - // DOM methods overridden from parent classes - - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - - virtual DOMStringImpl* textContent() const; - virtual void setTextContent( const DOMString &text, int& exceptioncode ); - - // Other methods (not part of DOM) - virtual bool isDocumentNode() const { return true; } - virtual bool isHTMLDocument() const { return false; } - - virtual ElementImpl *createHTMLElement ( const DOMString &tagName ); - - khtml::CSSStyleSelector *styleSelector() { return m_styleSelector; } - - /** - * Updates the pending sheet count and then calls updateStyleSelector. - */ - void styleSheetLoaded(); - - /** - * This method returns true if all top-level stylesheets have loaded (including - * any \@imports that they may be loading). - */ - bool haveStylesheetsLoaded() { return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets; } - - /** - * Increments the number of pending sheets. The \<link\> elements - * invoke this to add themselves to the loading list. - */ - void addPendingSheet() { m_pendingStylesheets++; } - - /** - * Returns true if the document has pending stylesheets - * loading. - */ - bool hasPendingSheets() const { return m_pendingStylesheets; } - - /** - * Called when one or more stylesheets in the document may have been added, removed or changed. - * - * Creates a new style selector and assign it to this document. This is done by iterating through all nodes in - * document (or those before \<BODY\> in a HTML document), searching for stylesheets. Stylesheets can be contained in - * \<LINK\>, \<STYLE\> or \<BODY\> elements, as well as processing instructions (XML documents only). A list is - * constructed from these which is used to create the a new style selector which collates all of the stylesheets - * found and is used to calculate the derived styles for all rendering objects. - * - * @param shallow If the stylesheet list for the document is unchanged, with only added or removed rules - * in existing sheets, then set this argument to true for efficiency. - */ - void updateStyleSelector(bool shallow=false); - - void recalcStyleSelector(); - void rebuildStyleSelector(); - - TQString nextState(); - - // Query all registered elements for their state - TQStringList docState(); - bool unsubmittedFormChanges(); - void registerMaintainsState(NodeImpl* e) { m_maintainsState.append(e); } - void deregisterMaintainsState(NodeImpl* e) { m_maintainsState.removeRef(e); } - - // Set the state the document should restore to - void setRestoreState( const TQStringList &s) { m_state = s; } - - KHTMLView *view() const { return m_view; } - KHTMLPart* part() const; - - RangeImpl *createRange(); - - NodeIteratorImpl *createNodeIterator(NodeImpl *root, unsigned long whatToShow, - NodeFilter &filter, bool entityReferenceExpansion, int &exceptioncode); - - TreeWalkerImpl *createTreeWalker(NodeImpl *root, unsigned long whatToShow, NodeFilterImpl *filter, - bool entityReferenceExpansion, int &exceptioncode); - - virtual void recalcStyle( StyleChange = NoChange ); - static TQPtrList<DocumentImpl> * changedDocuments; - virtual void updateRendering(); - void updateLayout(); - static void updateDocumentsRendering(); - khtml::DocLoader *docLoader() { return m_docLoader; } - - virtual void attach(); - virtual void detach(); - - khtml::RenderArena* renderArena() { return m_renderArena.get(); } - - // to get visually ordered hebrew and arabic pages right - void setVisuallyOrdered(); - // to get URL decoding right - void setDecoderCodec(const TQTextCodec *codec); - - void setSelection(NodeImpl* s, int sp, NodeImpl* e, int ep); - void clearSelection(); - - void open ( bool clearEventListeners = true ); - virtual void close ( ); - void write ( const DOMString &text ); - void write ( const TQString &text ); - void writeln ( const DOMString &text ); - void finishParsing ( ); - - KURL URL() const { return m_url; } - void setURL(const TQString& url) { m_url = url; } - - KURL baseURL() const { return m_baseURL.isEmpty() ? m_url : m_baseURL; } - void setBaseURL(const KURL& baseURL) { m_baseURL = baseURL; } - - TQString baseTarget() const { return m_baseTarget; } - void setBaseTarget(const TQString& baseTarget) { m_baseTarget = baseTarget; } - - TQString completeURL(const TQString& url) const { return KURL(baseURL(),url,m_decoderMibEnum).url(); }; - DOMString canonURL(const DOMString& url) const { return url.isEmpty() ? url : completeURL(url.string()); } - - void setUserStyleSheet(const TQString& sheet); - TQString userStyleSheet() const { return m_usersheet; } - void setPrintStyleSheet(const TQString& sheet) { m_printSheet = sheet; } - TQString printStyleSheet() const { return m_printSheet; } - - CSSStyleSheetImpl* elementSheet(); - virtual khtml::Tokenizer *createTokenizer(); - khtml::Tokenizer *tokenizer() { return m_tokenizer; } - - TQPaintDeviceMetrics *paintDeviceMetrics() { return m_paintDeviceMetrics; } - TQPaintDevice *paintDevice() const { return m_paintDevice; } - void setPaintDevice( TQPaintDevice *dev ); - - enum HTMLMode { - Html3 = 0, - Html4 = 1, - XHtml = 2 - }; - - enum ParseMode { - Unknown, - Compat, - Transitional, - Strict - }; - virtual void determineParseMode( const TQString &str ); - void setParseMode( ParseMode m ) { pMode = m; } - ParseMode parseMode() const { return pMode; } - - bool inCompatMode() const { return pMode == Compat; } - bool inTransitionalMode() const { return pMode == Transitional; } - bool inStrictMode() const { return pMode == Strict; } - - //void setHTMLMode( HTMLMode m ) { hMode = m; } - HTMLMode htmlMode() const { return hMode; } - - void setParsing(bool b) { m_bParsing = b; } - bool parsing() const { return m_bParsing; } - - void setTextColor( TQColor color ) { m_textColor = color; } - TQColor textColor() const { return m_textColor; } - - void setDesignMode(bool b); - bool designMode() const; - - // internal - bool prepareMouseEvent( bool readonly, int x, int y, MouseEvent *ev ); - - virtual bool childTypeAllowed( unsigned short nodeType ); - virtual NodeImpl *cloneNode ( bool deep ); - - NodeImpl::Id getId( NodeImpl::IdType _type, DOMStringImpl* _nsURI, DOMStringImpl *_localName, - DOMStringImpl *_prefix, bool readonly, bool lookupHTML, int *pExceptioncode = 0); - NodeImpl::Id getId( NodeImpl::IdType _type, DOMStringImpl *_nodeName, bool readonly, bool lookupHTML, - int *pExceptioncode = 0); - DOMString getName( NodeImpl::IdType _type, NodeImpl::Id _id ) const; - - StyleSheetListImpl* styleSheets() { return m_styleSheets; }; - - DOMString preferredStylesheetSet() const { return m_preferredStylesheetSet; } - DOMString selectedStylesheetSet() const; - void setSelectedStylesheetSet(const DOMString&); - void setPreferredStylesheetSet(const DOMString& s) { m_preferredStylesheetSet = s; } - - void addStyleSheet(StyleSheetImpl *, int *exceptioncode = 0); - void removeStyleSheet(StyleSheetImpl *, int *exceptioncode = 0); - - TQStringList availableStyleSheets() const { return m_availableSheets; } - - NodeImpl* hoverNode() const { return m_hoverNode; } - void setHoverNode(NodeImpl *newHoverNode); - NodeImpl *focusNode() const { return m_focusNode; } - void setFocusNode(NodeImpl *newFocusNode); - NodeImpl* activeNode() const { return m_activeNode; } - void setActiveNode(NodeImpl *newActiveNode); - - // Updates for :target (CSS3 selector). - void setCSSTarget(NodeImpl* n); - NodeImpl* getCSSTarget() { return m_cssTarget; } - - bool isDocumentChanged() { return m_docChanged; } - virtual void setDocumentChanged(bool = true); - void attachNodeIterator(NodeIteratorImpl *ni); - void detachNodeIterator(NodeIteratorImpl *ni); - void notifyBeforeNodeRemoval(NodeImpl *n); - AbstractViewImpl *defaultView() const { return m_defaultView; } - EventImpl *createEvent(const DOMString &eventType, int &exceptioncode); - - // keep track of what types of event listeners are registered, so we don't - // dispatch events unnecessarily - enum ListenerType { - DOMSUBTREEMODIFIED_LISTENER = 0x01, - DOMNODEINSERTED_LISTENER = 0x02, - DOMNODEREMOVED_LISTENER = 0x04, - DOMNODEREMOVEDFROMDOCUMENT_LISTENER = 0x08, - DOMNODEINSERTEDINTODOCUMENT_LISTENER = 0x10, - DOMATTRMODIFIED_LISTENER = 0x20, - DOMCHARACTERDATAMODIFIED_LISTENER = 0x40 - }; - - bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); } - void addListenerType(ListenerType listenerType) { m_listenerTypes = m_listenerTypes | listenerType; } - - CSSStyleDeclarationImpl *getOverrideStyle(ElementImpl *elt, DOMStringImpl *pseudoElt); - - bool async() const { return m_async; } - void setAsync(bool b) { m_async = b; } - void abort(); - void load(const DOMString &uri); - void loadXML(const DOMString &source); - // from cachedObjectClient - void setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset); - void error(int err, const TQString &text); - - typedef TQMap<TQString, ProcessingInstructionImpl*> LocalStyleRefs; - LocalStyleRefs* localStyleRefs() { return &m_localStyleRefs; } - - virtual void defaultEventHandler(EventImpl *evt); - virtual void setHTMLWindowEventListener(int id, EventListener *listener); - EventListener *getHTMLWindowEventListener(int id); - EventListener *createHTMLEventListener(const TQString& code, const TQString& name, NodeImpl* node); - - void addWindowEventListener(int id, EventListener *listener, const bool useCapture); - void removeWindowEventListener(int id, EventListener *listener, bool useCapture); - bool hasWindowEventListener(int id); - - EventListener *createHTMLEventListener(TQString code); - - /** - * Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode. - * The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes - * first (from lowest to highest), and then elements without tab indexes (in document order). - * - * @param fromNode The node from which to start searching. The node after this will be focused. May be null. - * - * @return The focus node that comes after fromNode - * - * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1 - */ - NodeImpl *nextFocusNode(NodeImpl *fromNode); - - /** - * Searches through the document, starting from fromNode, for the previous selectable element (that comes _before_) - * fromNode. The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab - * indexes first (from lowest to highest), and then elements without tab indexes (in document order). - * - * @param fromNode The node from which to start searching. The node before this will be focused. May be null. - * - * @return The focus node that comes before fromNode - * - * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1 - */ - NodeImpl *previousFocusNode(NodeImpl *fromNode); - - ElementImpl* findAccessKeyElement(TQChar c); - - int nodeAbsIndex(NodeImpl *node); - NodeImpl *nodeWithAbsIndex(int absIndex); - - /** - * Handles a HTTP header equivalent set by a meta tag using <meta http-equiv="..." content="...">. This is called - * when a meta tag is encountered during document parsing, and also when a script dynamically changes or adds a meta - * tag. This enables scripts to use meta tags to perform refreshes and set expiry dates in addition to them being - * specified in a HTML file. - * - * @param equiv The http header name (value of the meta tag's "equiv" attribute) - * @param content The header value (value of the meta tag's "content" attribute) - */ - void processHttpEquiv(const DOMString &equiv, const DOMString &content); - - void dispatchImageLoadEventSoon(HTMLImageElementImpl *); - void dispatchImageLoadEventsNow(); - void removeImage(HTMLImageElementImpl *); - virtual void timerEvent(TQTimerEvent *); - - // Returns the owning element in the parent document. - // Returns 0 if this is the top level document. - ElementImpl *ownerElement() const; - - DOMString domain() const; - void setDomain( const DOMString &newDomain ); // not part of the DOM - - bool isURLAllowed(const TQString& url) const; - - HTMLElementImpl* body(); - - DOMString toString() const; - - void incDOMTreeVersion() { ++m_domtree_version; } - unsigned int domTreeVersion() const { return m_domtree_version; } - - TQDict<khtml::CounterNode>* counters(const khtml::RenderObject* o) { return m_counterDict[(void*)o]; } - void setCounters(const khtml::RenderObject* o, TQDict<khtml::CounterNode> *dict) { m_counterDict.insert((void*)o, dict);} - void removeCounters(const khtml::RenderObject* o) { m_counterDict.remove((void*)o); } - - - ElementMappingCache& underDocNamedCache() { - return m_underDocNamedCache; - } - - NodeListImpl::Cache* acquireCachedNodeListInfo(NodeListImpl::CacheFactory* fact, - NodeImpl* base, int type); - void releaseCachedNodeListInfo(NodeListImpl::Cache* cache); - - ElementMappingCache& getElementByIdCache() const { - return m_getElementByIdCache; - } - - TQString contentLanguage() const { return m_contentLanguage; } - void setContentLanguage(const TQString& cl) { m_contentLanguage = cl; } - - khtml::DynamicDomRestyler& dynamicDomRestyler() { return *m_dynamicDomRestyler; } - const khtml::DynamicDomRestyler& dynamicDomRestyler() const { return *m_dynamicDomRestyler; } - -signals: - void finishedParsing(); - -protected: - khtml::CSSStyleSelector *m_styleSelector; - KHTMLView *m_view; - TQStringList m_state; - - khtml::DocLoader *m_docLoader; - khtml::Tokenizer *m_tokenizer; - KURL m_url; - KURL m_baseURL; - TQString m_baseTarget; - - DocumentTypeImpl *m_doctype; - DOMImplementationImpl *m_implementation; - - TQString m_usersheet; - TQString m_printSheet; - TQStringList m_availableSheets; - - TQString m_contentLanguage; - - // Track the number of currently loading top-level stylesheets. Sheets - // loaded using the @import directive are not included in this count. - // We use this count of pending sheets to detect when we can begin attaching - // elements. - int m_pendingStylesheets; - bool m_ignorePendingStylesheets; - - CSSStyleSheetImpl *m_elemSheet; - - TQPaintDevice *m_paintDevice; - TQPaintDeviceMetrics *m_paintDeviceMetrics; - ParseMode pMode; - HTMLMode hMode; - - TQColor m_textColor; - NodeImpl *m_hoverNode; - NodeImpl *m_focusNode; - NodeImpl *m_activeNode; - NodeImpl *m_cssTarget; - - unsigned int m_domtree_version; - - struct IdNameMapping { - IdNameMapping(unsigned short _start) - : idStart(_start), count(0) {} - ~IdNameMapping() { - TQIntDictIterator<DOM::DOMStringImpl> it(names); - for (; it.current() ; ++it) - it.current()->deref(); - } - unsigned short idStart; - unsigned short count; - TQIntDict<DOM::DOMStringImpl> names; - TQDict<void> ids; - - void expandIfNeeded() { - if (ids.size() <= ids.count() && ids.size() != khtml_MaxSeed) - ids.resize( khtml::nextSeed(ids.count()) ); - if (names.size() <= names.count() && names.size() != khtml_MaxSeed) - names.resize( khtml::nextSeed(names.count()) ); - } - - void addAlias(DOMStringImpl* _prefix, DOMStringImpl* _name, bool cs, NodeImpl::Id id) { - if(_prefix && _prefix->l) { - TQConstString n(_name->s, _name->l); - TQConstString px( _prefix->s, _prefix->l ); - TQString name = cs ? n.string() : n.string().upper(); - TQString qn("aliases: " + (cs ? px.string() : px.string().upper()) + ":" + name); - if (!ids.find( qn )) { - ids.insert( qn, (void*)id ); - } - } - expandIfNeeded(); - } - - }; - - IdNameMapping *m_attrMap; - IdNameMapping *m_elementMap; - IdNameMapping *m_namespaceMap; - - TQPtrList<NodeIteratorImpl> m_nodeIterators; - AbstractViewImpl *m_defaultView; - - unsigned short m_listenerTypes; - StyleSheetListImpl* m_styleSheets; - StyleSheetListImpl *m_addedStyleSheets; // programmatically added style sheets - LocalStyleRefs m_localStyleRefs; // references to inlined style elements - RegisteredListenerList m_windowEventListeners; - TQPtrList<NodeImpl> m_maintainsState; - - // ### evaluate for placement in RenderStyle - TQPtrDict<TQDict<khtml::CounterNode> > m_counterDict; - - khtml::DynamicDomRestyler *m_dynamicDomRestyler; - - bool visuallyOrdered; - bool m_bParsing; - bool m_docChanged; - bool m_styleSelectorDirty; - bool m_inStyleRecalc; - bool m_async; - bool m_hadLoadError; - bool m_docLoading; - bool m_inSyncLoad; - - DOMString m_title; - DOMString m_preferredStylesheetSet; - khtml::CachedCSSStyleSheet *m_loadingXMLDoc; - - int m_decoderMibEnum; - - //Forms, images, etc., must be quickly accessible via document.name. - ElementMappingCache m_underDocNamedCache; - - //Cache for nodelists and collections. - TQIntDict<NodeListImpl::Cache> m_nodeListCache; - - TQPtrList<HTMLImageElementImpl> m_imageLoadEventDispatchSoonList; - TQPtrList<HTMLImageElementImpl> m_imageLoadEventDispatchingList; - int m_imageLoadEventTimer; - - //Cache for getElementById - mutable ElementMappingCache m_getElementByIdCache; - - khtml::SharedPtr<khtml::RenderArena> m_renderArena; -private: - mutable DOMString m_domain; - int m_selfOnlyRefCount; -public: - // Nodes belonging to this document hold "self-only" references - - // these are enough to keep the document from being destroyed, but - // not enough to keep it from removing its children. This allows a - // node that outlives its document to still have a valid document - // pointer without introducing reference cycles - - void selfOnlyRef() { ++m_selfOnlyRefCount; } - void selfOnlyDeref() { - --m_selfOnlyRefCount; - if (!m_selfOnlyRefCount && !refCount()) - delete this; - } - - // This is called when our last outside reference dies - virtual void removedLastRef(); -}; - -class DocumentFragmentImpl : public NodeBaseImpl -{ -public: - DocumentFragmentImpl(DocumentImpl *doc); - DocumentFragmentImpl(const DocumentFragmentImpl &other); - - // DOM methods overridden from parent classes - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual NodeImpl *cloneNode ( bool deep ); - - // Other methods (not part of DOM) - virtual bool childTypeAllowed( unsigned short type ); - - virtual DOMString toString() const; -}; - - -class DocumentTypeImpl : public NodeImpl -{ -public: - DocumentTypeImpl(DOMImplementationImpl *_implementation, DocumentImpl *doc, - const DOMString &qualifiedName, const DOMString &publicId, - const DOMString &systemId); - ~DocumentTypeImpl(); - - // DOM methods & attributes for DocumentType - NamedNodeMapImpl *entities() const; - NamedNodeMapImpl *notations() const; - - DOMString name() const { return m_qualifiedName; } - DOMString publicId() const { return m_publicId; } - DOMString systemId() const { return m_systemId; } - DOMString internalSubset() const { return m_subset; } - - // DOM methods overridden from parent classes - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual bool childTypeAllowed( unsigned short type ); - virtual NodeImpl *cloneNode ( bool deep ); - - virtual DOMStringImpl* textContent() const; - virtual void setTextContent( const DOMString &text, int& exceptioncode ); - - // Other methods (not part of DOM) - void setName(const DOMString& n) { m_qualifiedName = n; } - void setPublicId(const DOMString& publicId) { m_publicId = publicId; } - void setSystemId(const DOMString& systemId) { m_systemId = systemId; } - DOMImplementationImpl *implementation() const { return m_implementation; } - void copyFrom(const DocumentTypeImpl&); - - virtual DOMString toString() const; - -protected: - DOMImplementationImpl *m_implementation; - mutable NamedNodeMapImpl* m_entities; - mutable NamedNodeMapImpl* m_notations; - - DOMString m_qualifiedName; - DOMString m_publicId; - DOMString m_systemId; - DOMString m_subset; -}; - -} //namespace -#endif diff --git a/khtml/xml/dom_elementimpl.cpp b/khtml/xml/dom_elementimpl.cpp deleted file mode 100644 index 875c5f2e4..000000000 --- a/khtml/xml/dom_elementimpl.cpp +++ /dev/null @@ -1,1301 +0,0 @@ -/** - * 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) - * (C) 2001 Peter Kelly (pmk@post.com) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -//#define EVENT_DEBUG -#include "dom/dom_exception.h" -#include "dom/dom_node.h" -#include "dom/html_image.h" -#include "xml/dom_textimpl.h" -#include "xml/dom_docimpl.h" -#include "xml/dom2_eventsimpl.h" -#include "xml/dom_elementimpl.h" -#include "xml/dom_restyler.h" - -#include "html/dtd.h" -#include "html/htmlparser.h" -#include "html/html_imageimpl.h" - -#include "rendering/render_canvas.h" -#include "misc/htmlhashes.h" -#include "css/css_valueimpl.h" -#include "css/css_stylesheetimpl.h" -#include "css/cssstyleselector.h" -#include "css/cssvalues.h" -#include "css/cssproperties.h" -#include "xml/dom_xmlimpl.h" - -#include <tqtextstream.h> -#include <kdebug.h> -#include <stdlib.h> - -// ### support default attributes -// ### dispatch mutation events -// ### check for INVALID_CHARACTER_ERR where appropriate - -using namespace DOM; -using namespace khtml; - -AttrImpl::AttrImpl(ElementImpl* element, DocumentImpl* docPtr, NodeImpl::Id attrId, - DOMStringImpl *value, DOMStringImpl *prefix) - : NodeBaseImpl(docPtr), - m_element(element), - m_attrId(attrId) -{ - m_value = value; - m_value->ref(); - - m_prefix = prefix; - if (m_prefix) - m_prefix->ref(); - m_specified = true; // we don't yet support default attributes -} - -AttrImpl::~AttrImpl() -{ - m_value->deref(); - if (m_prefix) - m_prefix->deref(); -} - -DOMString AttrImpl::nodeName() const -{ - return name(); -} - -unsigned short AttrImpl::nodeType() const -{ - return Node::ATTRIBUTE_NODE; -} - -DOMString AttrImpl::prefix() const -{ - return m_prefix; -} - -void AttrImpl::setPrefix(const DOMString &_prefix, int &exceptioncode ) -{ - checkSetPrefix(_prefix, exceptioncode); - if (exceptioncode) - return; - - if (m_prefix == _prefix.implementation()) - return; - - if (m_prefix) - m_prefix->deref(); - m_prefix = _prefix.implementation(); - if (m_prefix) - m_prefix->ref(); -} - -DOMString AttrImpl::namespaceURI() const -{ - if (m_htmlCompat) - return DOMString(); - return getDocument()->getName(NamespaceId, m_attrId >> 16); -} - -DOMString AttrImpl::localName() const -{ - if (m_htmlCompat) - return DOMString(); - return getDocument()->getName(AttributeId, m_attrId); -} - -DOMString AttrImpl::nodeValue() const -{ - return m_value; -} - -DOMString AttrImpl::name() const -{ - DOMString n = getDocument()->getName(AttributeId, m_attrId); - - // compat mode always return attribute names in lowercase. - // that's not formally in the specification, but common - // practice - a w3c erratum to DOM L2 is pending. - if (m_htmlCompat) - n = n.lower(); - - if (m_prefix && m_prefix->l) - return DOMString(m_prefix) + ":" + n; - - return n; -} - -void AttrImpl::setValue( const DOMString &v, int &exceptioncode ) -{ - exceptioncode = 0; - - // ### according to the DOM docs, we should create an unparsed Text child - // node here - // do not interprete entities in the string, its literal! - - // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly - if (isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - // ### what to do on 0 ? - if (v.isNull()) { - exceptioncode = DOMException::DOMSTRING_SIZE_ERR; - return; - } - - if (m_value == v.implementation()) - return; - - if (m_element && m_attrId == ATTR_ID) - m_element->updateId(m_value, v.implementation()); - - m_value->deref(); - m_value = v.implementation(); - m_value->ref(); - - if (m_element) { - m_element->parseAttribute(m_attrId,m_value); - m_element->attributeChanged(m_attrId); - } -} - -void AttrImpl::setNodeValue( const DOMString &v, int &exceptioncode ) -{ - exceptioncode = 0; - // NO_MODIFICATION_ALLOWED_ERR: taken care of by setValue() - setValue(v, exceptioncode); -} - -NodeImpl *AttrImpl::cloneNode ( bool /*deep*/) -{ - AttrImpl* attr = new AttrImpl(0, docPtr(), m_attrId, m_value, m_prefix); - attr->setHTMLCompat(m_htmlCompat); - return attr; -} - -// DOM Section 1.1.1 -bool AttrImpl::childAllowed( NodeImpl *newChild ) -{ - if(!newChild) - return false; - - return childTypeAllowed(newChild->nodeType()); -} - -bool AttrImpl::childTypeAllowed( unsigned short type ) -{ - switch (type) { - case Node::TEXT_NODE: - case Node::ENTITY_REFERENCE_NODE: - return true; - break; - default: - return false; - } -} - -DOMString AttrImpl::toString() const -{ - DOMString result; - - result += nodeName(); - - // FIXME: substitute entities for any instances of " or ' -- - // maybe easier to just use text value and ignore existing - // entity refs? - - if ( firstChild() ) { - result += "=\""; - - for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) { - result += child->toString(); - } - - result += "\""; - } else if ( !nodeValue().isEmpty() ){ - //remove the else once the AttributeImpl changes are merged - result += "=\""; - result += nodeValue(); - result += "\""; - } - - return result; -} - -void AttrImpl::setElement(ElementImpl *element) -{ - m_element = element; -} - -// Strictly speaking, these two methods should not be needed, but -// we can't fully deal with the mess that are DOM attributes right.. -DOMStringImpl* AttrImpl::textContent() const -{ - if (m_value) - return new DOMStringImpl(m_value->s, m_value->l); - else - return 0; -} - -void AttrImpl::setTextContent( const DOMString &text, int& exceptioncode ) -{ - setValue(text, exceptioncode); -} - -// ------------------------------------------------------------------------- - -void AttributeImpl::setValue(DOMStringImpl *value, ElementImpl *element) -{ - assert(value); - if (m_attrId) { - if (m_data.value == value) - return; - - if (element && m_attrId == ATTR_ID) - element->updateId(m_data.value, value); - - m_data.value->deref(); - m_data.value = value; - m_data.value->ref(); - - if (element) { - element->parseAttribute(this); - element->attributeChanged(m_attrId); - } - } - else { - int exceptioncode = 0; - m_data.attr->setValue(value,exceptioncode); - // AttrImpl::setValue() calls parseAttribute() - } -} - -AttrImpl *AttributeImpl::createAttr(ElementImpl *element, DocumentImpl *docPtr) -{ - if (m_attrId) { - AttrImpl *attr = new AttrImpl(element,docPtr,m_attrId,m_data.value); - if (!attr) return 0; - attr->setHTMLCompat( docPtr->htmlMode() != DocumentImpl::XHtml ); - m_data.value->deref(); - m_data.attr = attr; - m_data.attr->ref(); - m_attrId = 0; /* "has implementation" flag */ - } - - return m_data.attr; -} - -void AttributeImpl::free() -{ - if (m_attrId) { - m_data.value->deref(); - } - else { - m_data.attr->setElement(0); - m_data.attr->deref(); - } -} - -// ------------------------------------------------------------------------- - -ElementImpl::ElementImpl(DocumentImpl *doc) - : NodeBaseImpl(doc) -{ - namedAttrMap = 0; - m_styleDecls = 0; - m_prefix = 0; -} - -ElementImpl::~ElementImpl() -{ - if(namedAttrMap) { - namedAttrMap->detachFromElement(); - namedAttrMap->deref(); - } - - if (m_styleDecls) { - m_styleDecls->setNode(0); - m_styleDecls->setParent(0); - m_styleDecls->deref(); - } - - if (m_prefix) - m_prefix->deref(); -} - -unsigned short ElementImpl::nodeType() const -{ - return Node::ELEMENT_NODE; -} - -DOMStringImpl* ElementImpl::getAttributeImpl( NodeImpl::Id id, bool nsAware, DOMStringImpl* qName) const -{ - if (!namedAttrMap) - return 0; - - DOMStringImpl *value = namedAttrMap->getValue(id, nsAware, qName); - if (value) - return value; - - // then search in default attr in case it is not yet set - NamedAttrMapImpl* dm = defaultMap(); - value = dm ? dm->getValue(id, nsAware, qName) : 0; - if (value) - return value; - - return 0; -} - -DOMString ElementImpl::getAttribute( NodeImpl::Id id, bool nsAware, const DOMString& qName) const -{ - return DOMString(getAttributeImpl(id, nsAware, qName.implementation())); -} - -void ElementImpl::setAttribute(NodeImpl::Id id, const DOMString &value, const DOMString& qName, int &exceptioncode) -{ - // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly - if (isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - attributes()->setValue(id, value.implementation(), (qName.isEmpty() ? 0: qName.implementation())); -} - -void ElementImpl::setAttributeNS( const DOMString &namespaceURI, const DOMString &qualifiedName, - const DOMString &value, int &exceptioncode ) -{ - // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly - if (isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - int colonPos; - if (!DOM::checkQualifiedName(qualifiedName, namespaceURI, &colonPos, - false/*nameCanBeNull*/, false/*nameCanBeEmpty*/, - &exceptioncode)) - return; - DOMString prefix, localName; - splitPrefixLocalName(qualifiedName.implementation(), prefix, localName, colonPos); - NodeImpl::Id id = getDocument()->getId(AttributeId, namespaceURI.implementation(), - prefix.implementation(), localName.implementation(), false, true /*lookupHTML*/); - attributes()->setValue(id, value.implementation(), 0, prefix.implementation(), - true /*nsAware*/, !namespaceURI.isNull() /*hasNS*/); -} - -void ElementImpl::setAttribute(NodeImpl::Id id, const DOMString &value) -{ - int exceptioncode = 0; - setAttribute(id,value,DOMString(),exceptioncode); -} - -void ElementImpl::setAttributeMap( NamedAttrMapImpl* list ) -{ - // If setting the whole map changes the id attribute, we need to - // call updateId. - DOMStringImpl *oldId = namedAttrMap ? namedAttrMap->getValue(ATTR_ID) : 0; - DOMStringImpl *newId = list ? list->getValue(ATTR_ID) : 0; - - if (oldId || newId) { - updateId(oldId, newId); - } - - if (namedAttrMap) { - namedAttrMap->detachFromElement(); - namedAttrMap->deref(); - } - - namedAttrMap = list; - - if (namedAttrMap) { - namedAttrMap->ref(); - assert(namedAttrMap->m_element == 0); - namedAttrMap->setElement(this); - unsigned long len = namedAttrMap->length(); - for (unsigned long i = 0; i < len; i++) { - parseAttribute(&namedAttrMap->m_attrs[i]); - attributeChanged(namedAttrMap->m_attrs[i].id()); - } - } -} - -NodeImpl *ElementImpl::cloneNode(bool deep) -{ - ElementImpl *clone; - if ( !localName().isNull() ) - clone = getDocument()->createElementNS( namespaceURI(), nodeName() ); - else - clone = getDocument()->createElement( nodeName() ); - if (!clone) return 0; - finishCloneNode( clone, deep ); - return clone; -} - -void ElementImpl::finishCloneNode( ElementImpl* clone, bool deep ) -{ - // clone attributes - if (namedAttrMap) - clone->attributes()->copyAttributes(namedAttrMap); - - // clone individual style rules - if (m_styleDecls) - *(clone->styleRules()) = *m_styleDecls; - - if (deep) - cloneChildNodes(clone); -} - -DOMString ElementImpl::nodeName() const -{ - return tagName(); -} - -DOMString ElementImpl::namespaceURI() const -{ - if (m_htmlCompat) - return DOMString(); - return getDocument()->getName(NamespaceId, id() >> 16); -} - -DOMString ElementImpl::prefix() const -{ - return m_prefix; -} - -void ElementImpl::setPrefix( const DOMString &_prefix, int &exceptioncode ) -{ - checkSetPrefix(_prefix, exceptioncode); - if (exceptioncode) - return; - - if (m_prefix == _prefix.implementation()) - return; - - if (m_prefix) - m_prefix->deref(); - m_prefix = _prefix.implementation(); - if (m_prefix) - m_prefix->ref(); -} - -void ElementImpl::createAttributeMap() const -{ - namedAttrMap = new NamedAttrMapImpl(const_cast<ElementImpl*>(this)); - namedAttrMap->ref(); -} - -NamedAttrMapImpl* ElementImpl::defaultMap() const -{ - return 0; -} - -RenderStyle *ElementImpl::styleForRenderer(RenderObject * /*parentRenderer*/) -{ - return getDocument()->styleSelector()->styleForElement(this); -} - -RenderObject *ElementImpl::createRenderer(RenderArena *arena, RenderStyle *style) -{ - if (getDocument()->documentElement() == this && style->display() == NONE) { - // Ignore display: none on root elements. Force a display of block in that case. - RenderBlock* result = new (arena) RenderBlock(this); - if (result) result->setStyle(style); - return result; - } - return RenderObject::createObject(this, style); -} - -void ElementImpl::attach() -{ - assert(!attached()); - assert(!m_render); - assert(parentNode()); - -#if SPEED_DEBUG < 1 - createRendererIfNeeded(); -#endif - - NodeBaseImpl::attach(); -} - -void ElementImpl::close() -{ - NodeImpl::close(); - - // Trigger all the addChild changes as one large dynamic appendChildren change - if (attached()) - backwardsStructureChanged(); -} - -void ElementImpl::detach() -{ - getDocument()->dynamicDomRestyler().resetDependencies(this); - - NodeBaseImpl::detach(); -} - -void ElementImpl::structureChanged() -{ - NodeBaseImpl::structureChanged(); - - if (!getDocument()->renderer()) - return; // the document is about to be destroyed - - getDocument()->dynamicDomRestyler().restyleDepedent(this, StructuralDependency); - // In theory BackwardsStructurualDependencies are indifferent to prepend, - // but it's too rare to optimize. - getDocument()->dynamicDomRestyler().restyleDepedent(this, BackwardsStructuralDependency); -} - -void ElementImpl::backwardsStructureChanged() -{ - NodeBaseImpl::backwardsStructureChanged(); - - if (!getDocument()->renderer()) - return; // the document is about to be destroyed - - // Most selectors are not affected by append. Fire the few that are. - getDocument()->dynamicDomRestyler().restyleDepedent(this, BackwardsStructuralDependency); -} - -void ElementImpl::attributeChanged(NodeImpl::Id id) -{ - if (!getDocument()->renderer()) - return; // the document is about to be destroyed - -#if 0 // one-one dependencies for attributes disabled - getDocument()->dynamicDomRestyler().restyleDepedent(this, AttributeDependency); -#endif - if (getDocument()->dynamicDomRestyler().checkDependency(id, PersonalDependency)) - setChanged(true); - if (getDocument()->dynamicDomRestyler().checkDependency(id, AncestorDependency)) - setChangedAscendentAttribute(true); - if (getDocument()->dynamicDomRestyler().checkDependency(id, PredecessorDependency) && parent()) - // Any element that dependt on a predecessors attribute, also depend structurally on parent - parent()->structureChanged(); -} - -void ElementImpl::recalcStyle( StyleChange change ) -{ - // ### should go away and be done in renderobject - RenderStyle* _style = m_render ? m_render->style() : 0; - bool hasParentRenderer = parent() ? parent()->attached() : false; - -#if 0 - const char* debug; - switch(change) { - case NoChange: debug = "NoChange"; - break; - case NoInherit: debug= "NoInherit"; - break; - case Inherit: debug = "Inherit"; - break; - case Force: debug = "Force"; - break; - } - tqDebug("recalcStyle(%d: %s, changed: %d)[%p: %s]", change, debug, changed(), this, tagName().string().latin1()); -#endif - if ( hasParentRenderer && (change >= Inherit || changed()) ) { - RenderStyle *newStyle = getDocument()->styleSelector()->styleForElement(this); - newStyle->ref(); - StyleChange ch = diff( _style, newStyle ); - if (ch == Detach) { - if (attached()) detach(); - // ### Suboptimal. Style gets calculated again. - attach(); - // attach recalulates the style for all children. No need to do it twice. - setChanged( false ); - setHasChangedChild( false ); - newStyle->deref(); - return; - } - else if (ch != NoChange) { - if( m_render && newStyle ) { - m_render->setStyle(newStyle); - } - } - newStyle->deref(); - - if ( change != Force) - change = ch; - } - // If a changed attribute has ancestor dependencies, restyle all children - if (changedAscendentAttribute()) { - change = Force; - setChangedAscendentAttribute(false); - } - - NodeImpl *n; - for (n = _first; n; n = n->nextSibling()) { - if ( change >= Inherit || n->isTextNode() || - n->hasChangedChild() || n->changed() ) { - //tqDebug(" (%p) calling recalcStyle on child %p/%s, change=%d", this, n, n->isElementNode() ? ((ElementImpl *)n)->tagName().string().latin1() : n->isTextNode() ? "text" : "unknown", change ); - n->recalcStyle( change ); - } - } - - setChanged( false ); - setHasChangedChild( false ); -} - -bool ElementImpl::isFocusable() const -{ - // Only make editable elements selectable if its parent element - // is not editable. FIXME: this is not 100% right as non-editable elements - // within editable elements are focusable too. - return contentEditable() && !(parentNode() && parentNode()->contentEditable()); -} - -// DOM Section 1.1.1 -bool ElementImpl::childAllowed( NodeImpl *newChild ) -{ - if (!childTypeAllowed(newChild->nodeType())) - return false; - - // ### check xml element allowedness according to DTD - - // If either this node or the other node is an XML element node, allow regardless (we don't do DTD checks for XML - // yet) - if (isXMLElementNode() || newChild->isXMLElementNode()) - return true; - else - return checkChild(id(), newChild->id(), !getDocument()->inCompatMode()); -} - -bool ElementImpl::childTypeAllowed( unsigned short type ) -{ - switch (type) { - case Node::ELEMENT_NODE: - case Node::TEXT_NODE: - case Node::COMMENT_NODE: - case Node::PROCESSING_INSTRUCTION_NODE: - case Node::CDATA_SECTION_NODE: - case Node::ENTITY_REFERENCE_NODE: - return true; - break; - default: - return false; - } -} - -void ElementImpl::scrollIntoView(bool /*alignToTop*/) -{ - // ### - kdWarning() << "non-standard scrollIntoView() not implemented" << endl; -} - -void ElementImpl::createDecl( ) -{ - m_styleDecls = new CSSStyleDeclarationImpl(0); - m_styleDecls->ref(); - m_styleDecls->setParent(getDocument()->elementSheet()); - m_styleDecls->setNode(this); - m_styleDecls->setStrictParsing( !getDocument()->inCompatMode() ); -} - -void ElementImpl::dispatchAttrRemovalEvent(NodeImpl::Id /*id*/, DOMStringImpl * /*value*/) -{ - // ### enable this stuff again - if (!getDocument()->hasListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER)) - return; - //int exceptioncode = 0; - //dispatchEvent(new MutationEventImpl(EventImpl::DOMATTRMODIFIED_EVENT,true,false,attr,attr->value(), - //attr->value(), getDocument()->attrName(attr->id()),MutationEvent::REMOVAL),exceptioncode); -} - -void ElementImpl::dispatchAttrAdditionEvent(NodeImpl::Id /*id*/, DOMStringImpl * /*value*/) -{ - // ### enable this stuff again - if (!getDocument()->hasListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER)) - return; - //int exceptioncode = 0; - //dispatchEvent(new MutationEventImpl(EventImpl::DOMATTRMODIFIED_EVENT,true,false,attr,attr->value(), - //attr->value(),getDocument()->attrName(attr->id()),MutationEvent::ADDITION),exceptioncode); -} - -void ElementImpl::updateId(DOMStringImpl* oldId, DOMStringImpl* newId) -{ - if (!inDocument()) - return; - - if (oldId && oldId->l) - removeId(DOMString(oldId).string()); - - if (newId && newId->l) - addId(DOMString(newId).string()); -} - -void ElementImpl::removeId(const TQString& id) -{ - getDocument()->getElementByIdCache().remove(id, this); -} - -void ElementImpl::addId(const TQString& id) -{ - getDocument()->getElementByIdCache().add(id, this); -} - -void ElementImpl::insertedIntoDocument() -{ - // need to do superclass processing first so inDocument() is true - // by the time we reach updateId - NodeBaseImpl::insertedIntoDocument(); - - if (hasID()) { - DOMString id = getAttribute(ATTR_ID); - updateId(0, id.implementation()); - } -} - -void ElementImpl::removedFromDocument() -{ - if (hasID()) { - DOMString id = getAttribute(ATTR_ID); - updateId(id.implementation(), 0); - } - - NodeBaseImpl::removedFromDocument(); -} - -DOMString ElementImpl::openTagStartToString(bool expandurls) const -{ - DOMString result = DOMString("<") + tagName(); - - NamedAttrMapImpl *attrMap = attributes(true); - - if (attrMap) { - unsigned long numAttrs = attrMap->length(); - for (unsigned long i = 0; i < numAttrs; i++) { - result += " "; - - AttributeImpl *attribute = attrMap->attrAt(i); - AttrImpl *attr = attribute->attr(); - - if (attr) { - result += attr->toString(); - } else { - result += getDocument()->getName( NodeImpl::AttributeId, attribute->id()); - if (!attribute->value().isNull()) { - result += "=\""; - // FIXME: substitute entities for any instances of " or ' - // Expand out all urls, i.e. the src and href attributes - if(expandurls && ( attribute->id() == ATTR_SRC || attribute->id() == ATTR_HREF)) - if(getDocument()) { - //We need to sanitize the urls - strip out the passwords. - //FIXME: are src= and href= the only places that might have a password and need to be sanitized? - KURL safeURL(getDocument()->completeURL(attribute->value().string())); - safeURL.setPass(TQString::null); - result += safeURL.htmlURL(); - } - else { - kdWarning() << "getDocument() returned false"; - result += attribute->value(); - } - else - result += attribute->value(); - result += "\""; - } - } - } - } - - return result; -} -DOMString ElementImpl::selectionToString(NodeImpl *selectionStart, NodeImpl *selectionEnd, int startOffset, int endOffset, bool &found) const -{ - DOMString result = openTagStartToString(); - - if (hasChildNodes()) { - result += ">"; - - for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) { - result += child->selectionToString(selectionStart, selectionEnd, startOffset, endOffset, found); // this might set found to true - if(child == selectionEnd) - found = true; - if(found) break; - } - - result += "</"; - result += tagName(); - result += ">"; - } else { - result += " />"; - } - - return result; -} - -DOMString ElementImpl::toString() const -{ - TQString result = openTagStartToString().string(); //Accumulate in TQString, since DOMString can't append well. - - if (hasChildNodes()) { - result += ">"; - - for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) { - DOMString kid = child->toString(); - result += TQConstString(kid.unicode(), kid.length()).string(); - } - - result += "</"; - result += tagName().string(); - result += ">"; - } else if (result.length() == 1) { - // ensure we dont get results like < /> can happen when serialize document - result = ""; - } else { - result += " />"; - } - - return result; -} - -bool ElementImpl::contentEditable() const { -#if 0 - DOM::CSSPrimitiveValueImpl *val = static_cast<DOM::CSSPrimitiveValueImpl *> - (const_cast<ElementImpl *>(this)->styleRules() - ->getPropertyCSSValue(CSS_PROP__KONQ_USER_INPUT)); -// kdDebug() << "val" << val << endl; - return val ? val->getIdent() == CSS_VAL_ENABLED : false; -#endif - return NodeImpl::contentEditable(); -} - -void ElementImpl::setContentEditable(bool enabled) { - // FIXME: the approach is flawed, better use an enum instead of bool - int value; - if (enabled) - value = CSS_VAL_ENABLED; - else { - // Intelligently use "none" or "disabled", depending on the type of - // element - // FIXME: intelligence not impl'd yet - value = CSS_VAL_NONE; - - // FIXME: reset caret if it is in this node or a child - }/*end if*/ - // FIXME: use addCSSProperty when I get permission to move it here -// kdDebug(6000) << "CSS_PROP__KHTML_USER_INPUT: "<< value << endl; - styleRules()->setProperty(CSS_PROP__KHTML_USER_INPUT, value, false, true); - setChanged(); - -} - -// ------------------------------------------------------------------------- - -XMLElementImpl::XMLElementImpl(DocumentImpl *doc, NodeImpl::Id id) - : ElementImpl(doc) -{ - // Called from createElement(). In this case localName, prefix, and namespaceURI all need to be null. - m_id = id; -} - -XMLElementImpl::XMLElementImpl(DocumentImpl *doc, NodeImpl::Id id, DOMStringImpl *_prefix) - : ElementImpl(doc) -{ - // Called from createElementNS() - m_id = id; - - m_prefix = _prefix; - if (m_prefix) - m_prefix->ref(); -} - -XMLElementImpl::~XMLElementImpl() -{ -} - -DOMString XMLElementImpl::localName() const -{ - if ( m_htmlCompat ) - return DOMString(); // was created with non-namespace-aware createElement() - return getDocument()->getName(ElementId, m_id); -} - -DOMString XMLElementImpl::tagName() const -{ - DOMString tn = getDocument()->getName(ElementId, id()); - if (m_htmlCompat) - tn = tn.upper(); - - if (m_prefix) - return DOMString(m_prefix) + ":" + tn; - - return tn; -} - -NodeImpl *XMLElementImpl::cloneNode ( bool deep ) -{ - XMLElementImpl *clone = new XMLElementImpl(docPtr(), id(), m_prefix); - finishCloneNode( clone, deep ); - return clone; -} - -// ------------------------------------------------------------------------- - -NamedAttrMapImpl::NamedAttrMapImpl(ElementImpl *element) - : m_element(element), - m_attrs(0), - m_attrCount(0) -{ -} - -NamedAttrMapImpl::~NamedAttrMapImpl() -{ - for (unsigned long i = 0; i < m_attrCount; i++) - m_attrs[i].free(); - free(m_attrs); -} - -NodeImpl *NamedAttrMapImpl::getNamedItem ( NodeImpl::Id id, bool nsAware, DOMStringImpl* qName ) const -{ - if (!m_element) - return 0; - unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; - id = (id & mask); - - for (unsigned long i = 0; i < m_attrCount; i++) { - if ((m_attrs[i].id() & mask) == id) { - // if we are called with a qualified name, filter out NS-aware elements with non-matching name. - if (qName && (namespacePart(m_attrs[i].id()) != defaultNamespace) && - strcasecmp(m_attrs[i].name(), DOMString(qName))) - continue; - return m_attrs[i].createAttr(m_element,m_element->docPtr()); - } - } - - return 0; -} - -Node NamedAttrMapImpl::removeNamedItem ( NodeImpl::Id id, bool nsAware, DOMStringImpl* qName, int &exceptioncode ) -{ - if (!m_element) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return 0; - } - - // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly - if (isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return 0; - } - unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; - id = (id & mask); - - for (unsigned long i = 0; i < m_attrCount; i++) { - if ((m_attrs[i].id() & mask) == id) { - // if we are called with a qualified name, filter out NS-aware elements with non-matching name. - if (qName && (namespacePart(m_attrs[i].id()) != defaultNamespace) && - strcasecmp(m_attrs[i].name(), DOMString(qName))) - continue; - id = m_attrs[i].id(); - if (id == ATTR_ID) - m_element->updateId(m_attrs[i].val(), 0); - Node removed(m_attrs[i].createAttr(m_element,m_element->docPtr())); - m_attrs[i].free(); - memmove(m_attrs+i,m_attrs+i+1,(m_attrCount-i-1)*sizeof(AttributeImpl)); - m_attrCount--; - m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); - m_element->parseAttribute(id,0); - m_element->attributeChanged(id); - return removed; - } - } - - // NOT_FOUND_ERR: Raised if there is no node with the specified namespaceURI - // and localName in this map. - exceptioncode = DOMException::NOT_FOUND_ERR; - return 0; -} - -Node NamedAttrMapImpl::setNamedItem ( NodeImpl* arg, bool nsAware, DOMStringImpl* qName, int &exceptioncode ) -{ - if (!m_element) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return 0; - } - - // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. - if (isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return 0; - } - - // WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map. - if (arg->getDocument() != m_element->getDocument()) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return 0; - } - - // HIERARCHY_REQUEST_ERR: Raised if an attempt is made to add a node doesn't belong in this NamedNodeMap - if (!arg->isAttributeNode()) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return 0; - } - AttrImpl *attr = static_cast<AttrImpl*>(arg); - - // INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object. - // The DOM user must explicitly clone Attr nodes to re-use them in other elements. - if (attr->ownerElement() && attr->ownerElement() != m_element) { - exceptioncode = DOMException::INUSE_ATTRIBUTE_ERR; - return 0; - } - - if (attr->ownerElement() == m_element) { - // Already have this attribute. - // DOMTS core-1 test "hc_elementreplaceattributewithself" says we should return it. - return attr; - } - unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; - NodeImpl::Id id = (attr->id() & mask); - - for (unsigned long i = 0; i < m_attrCount; i++) { - if ((m_attrs[i].id() & mask) == id) { - // if we are called with a qualified name, filter out NS-aware elements with non-matching name. - if (qName && (namespacePart(m_attrs[i].id()) != defaultNamespace) && - strcasecmp(m_attrs[i].name(), DOMString(qName))) - continue; - // Attribute exists; replace it - if (id == ATTR_ID) - m_element->updateId(m_attrs[i].val(), attr->val()); - - Node replaced = m_attrs[i].createAttr(m_element,m_element->docPtr()); - m_attrs[i].free(); - m_attrs[i].m_attrId = 0; /* "has implementation" flag */ - m_attrs[i].m_data.attr = attr; - m_attrs[i].m_data.attr->ref(); - attr->setElement(m_element); - m_element->parseAttribute(&m_attrs[i]); - m_element->attributeChanged(m_attrs[i].id()); - // ### dispatch mutation events - return replaced; - } - } - - // No existing attribute; add to list - m_attrCount++; - m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); - m_attrs[m_attrCount-1].m_attrId = 0; /* "has implementation" flag */ - m_attrs[m_attrCount-1].m_data.attr = attr; - m_attrs[m_attrCount-1].m_data.attr->ref(); - attr->setElement(m_element); - if (id == ATTR_ID) - m_element->updateId(0, attr->val()); - m_element->parseAttribute(&m_attrs[m_attrCount-1]); - m_element->attributeChanged(m_attrs[m_attrCount-1].id()); - // ### dispatch mutation events - - return 0; -} - -NodeImpl *NamedAttrMapImpl::item ( unsigned long index ) const -{ - if (!m_element) - return 0; - - if (index >= m_attrCount) - return 0; - else - return m_attrs[index].createAttr(m_element,m_element->docPtr()); -} - -unsigned long NamedAttrMapImpl::length( ) const -{ - if (!m_element) - return 0; - - return m_attrCount; -} - -NodeImpl::Id NamedAttrMapImpl::idAt(unsigned long index) const -{ - assert(index <= m_attrCount); - return m_attrs[index].id(); -} - -DOMStringImpl *NamedAttrMapImpl::valueAt(unsigned long index) const -{ - assert(index <= m_attrCount); - return m_attrs[index].val(); -} - -DOMStringImpl *NamedAttrMapImpl::getValue(NodeImpl::Id id, bool nsAware, DOMStringImpl* qName) const -{ - unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; - id = (id & mask); - for (unsigned long i = 0; i < m_attrCount; i++) - if ((m_attrs[i].id() & mask) == id) { - // if we are called with a qualified name, filter out NS-aware elements with non-matching name. - if (qName && (namespacePart(m_attrs[i].id()) != defaultNamespace) && - strcasecmp(m_attrs[i].name(), qName)) - continue; - return m_attrs[i].val(); - } - return 0; -} - -void NamedAttrMapImpl::setValue(NodeImpl::Id id, DOMStringImpl *value, DOMStringImpl* qName, - DOMStringImpl *prefix, bool nsAware, bool hasNS) -{ - assert( !(qName && nsAware) ); - if (!id) return; - // Passing in a null value here causes the attribute to be removed. This is a khtml extension - // (the spec does not specify what to do in this situation). - int exceptioncode = 0; - if (!value) { - removeNamedItem(id, nsAware, qName, exceptioncode); - return; - } - unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; - NodeImpl::Id mid = (id & mask); - - // Check for an existing attribute. - for (unsigned long i = 0; i < m_attrCount; i++) { - if ((m_attrs[i].id() & mask) == mid) { - // if we are called with a qualified name, filter out NS-aware elements with non-matching name. - if (qName && (namespacePart(m_attrs[i].id()) != defaultNamespace) && - strcasecmp(m_attrs[i].name(), DOMString(qName))) - continue; - if (prefix) - m_attrs[i].attr()->setPrefix(prefix,exceptioncode); - m_attrs[i].setValue(value,m_element); - // ### dispatch mutation events - return; - } - } - - // No existing matching attribute; add a new one - m_attrCount++; - m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); - if (!nsAware) { - // Called from setAttribute()... we only have a name - m_attrs[m_attrCount-1].m_attrId = id; - m_attrs[m_attrCount-1].m_data.value = value; - m_attrs[m_attrCount-1].m_data.value->ref(); - } - else { - // Called from setAttributeNS()... need to create a full AttrImpl here - if(!m_element) - return; - m_attrs[m_attrCount-1].m_data.attr = new AttrImpl(m_element,m_element->docPtr(), - id, - value, - prefix); - m_attrs[m_attrCount-1].m_attrId = 0; /* "has implementation" flag */ - m_attrs[m_attrCount-1].m_data.attr->ref(); - m_attrs[m_attrCount-1].m_data.attr->setHTMLCompat( !hasNS && - m_element->getDocument()->htmlMode() != DocumentImpl::XHtml ); - } - if (m_element) { - if (id == ATTR_ID) - m_element->updateId(0, value); - m_element->parseAttribute(&m_attrs[m_attrCount-1]); - m_element->attributeChanged(m_attrs[m_attrCount-1].id()); - } - // ### dispatch mutation events -} - -Attr NamedAttrMapImpl::removeAttr(AttrImpl *attr) -{ - for (unsigned long i = 0; i < m_attrCount; i++) { - if (m_attrs[i].attr() == attr) { - NodeImpl::Id id = m_attrs[i].id(); - if (id == ATTR_ID) - m_element->updateId(attr->val(), 0); - Node removed(m_attrs[i].createAttr(m_element,m_element->docPtr())); - m_attrs[i].free(); - memmove(m_attrs+i,m_attrs+i+1,(m_attrCount-i-1)*sizeof(AttributeImpl)); - m_attrCount--; - m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); - m_element->parseAttribute(id,0); - m_element->attributeChanged(id); - // ### dispatch mutation events - return removed; - } - } - - return 0; -} - -NodeImpl::Id NamedAttrMapImpl::mapId(DOMStringImpl* namespaceURI, - DOMStringImpl* localName, bool readonly) -{ - if (!m_element) - return 0; - - return m_element->getDocument()->getId(NodeImpl::AttributeId, namespaceURI, 0, localName, readonly, - true /*lookupHTML*/); -} - -void NamedAttrMapImpl::copyAttributes(NamedAttrMapImpl *other) -{ - assert(m_element); - unsigned long i; - for (i = 0; i < m_attrCount; i++) { - if (m_attrs[i].id() == ATTR_ID) - m_element->updateId(m_attrs[i].val(), 0); - m_attrs[i].free(); - } - m_attrCount = other->m_attrCount; - m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); - for (i = 0; i < m_attrCount; i++) { - m_attrs[i].m_attrId = other->m_attrs[i].m_attrId; - if (m_attrs[i].m_attrId) { - m_attrs[i].m_data.value = other->m_attrs[i].m_data.value; - m_attrs[i].m_data.value->ref(); - } - else { - m_attrs[i].m_data.attr = static_cast<AttrImpl*>(other->m_attrs[i].m_data.attr->cloneNode(true)); - m_attrs[i].m_data.attr->ref(); - m_attrs[i].m_data.attr->setElement(m_element); - } - if (m_attrs[i].id() == ATTR_ID) - m_element->updateId(0, m_attrs[i].val()); - m_element->parseAttribute(&m_attrs[i]); - m_element->attributeChanged(m_attrs[i].id()); - } -} - -void NamedAttrMapImpl::setElement(ElementImpl *element) -{ - assert(!m_element); - m_element = element; - - for (unsigned long i = 0; i < m_attrCount; i++) - if (m_attrs[i].attr()) - m_attrs[i].attr()->setElement(element); -} - -void NamedAttrMapImpl::detachFromElement() -{ - // This makes the map invalid; nothing can really be done with it now since it's not - // associated with an element. But we have to keep it around in memory in case there - // are still references to it. - m_element = 0; - for (unsigned long i = 0; i < m_attrCount; i++) - m_attrs[i].free(); - free(m_attrs); - m_attrs = 0; - m_attrCount = 0; -} diff --git a/khtml/xml/dom_elementimpl.h b/khtml/xml/dom_elementimpl.h deleted file mode 100644 index ee1be3e4a..000000000 --- a/khtml/xml/dom_elementimpl.h +++ /dev/null @@ -1,392 +0,0 @@ -/* - * 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) - * (C) 2001 Peter Kelly (pmk@post.com) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * (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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef _DOM_ELEMENTImpl_h_ -#define _DOM_ELEMENTImpl_h_ - -#include "dom_nodeimpl.h" -#include "dom/dom_exception.h" -#include "dom/dom_element.h" -#include "xml/dom_stringimpl.h" -#include "misc/shared.h" - -namespace khtml { - class CSSStyleSelector; -} - -namespace DOM { - -class ElementImpl; -class DocumentImpl; -class NamedAttrMapImpl; - -// Attr can have Text and EntityReference children -// therefore it has to be a fullblown Node. The plan -// is to dynamically allocate a textchild and store the -// resulting nodevalue in the AttributeImpl upon -// destruction. however, this is not yet implemented. -class AttrImpl : public NodeBaseImpl -{ - friend class ElementImpl; - friend class NamedAttrMapImpl; - -public: - AttrImpl(ElementImpl* element, DocumentImpl* docPtr, NodeImpl::Id attrId, - DOMStringImpl *value, DOMStringImpl *prefix = 0); - ~AttrImpl(); - -private: - AttrImpl(const AttrImpl &other); - AttrImpl &operator = (const AttrImpl &other); -public: - - // DOM methods & attributes for Attr - bool specified() const { return m_specified; } - ElementImpl* ownerElement() const { return m_element; } - void setOwnerElement( ElementImpl* impl ) { m_element = impl; } - DOMString name() const; - - //DOMString value() const; - void setValue( const DOMString &v, int &exceptioncode ); - - // DOM methods overridden from parent classes - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual DOMString prefix() const; - virtual void setPrefix(const DOMString &_prefix, int &exceptioncode ); - virtual DOMString namespaceURI() const; - virtual DOMString localName() const; - - virtual DOMString nodeValue() const; - virtual void setNodeValue( const DOMString &, int &exceptioncode ); - virtual NodeImpl *cloneNode ( bool deep ); - - virtual DOMStringImpl* textContent() const; - virtual void setTextContent( const DOMString &text, int& exceptioncode ); - - - // Other methods (not part of DOM) - virtual bool isAttributeNode() const { return true; } - virtual bool childAllowed( NodeImpl *newChild ); - virtual bool childTypeAllowed( unsigned short type ); - virtual NodeImpl::Id id() const { return m_attrId; } - - virtual DOMString toString() const; - - void setElement(ElementImpl *element); - DOMStringImpl *val() { return m_value; } - -protected: - ElementImpl *m_element; - NodeImpl::Id m_attrId; - DOMStringImpl *m_value; - DOMStringImpl *m_prefix; - DOMStringImpl *m_localName; -}; - -// Mini version of AttrImpl internal to NamedAttrMapImpl. -// Stores either the id and value of an attribute -// (in the case of m_attrId != 0), or a pointer to an AttrImpl (if m_attrId == 0) -// The latter case only happens when the Attr node is requested by some DOM -// code or is an XML attribute. -// In most cases the id and value is all we need to store, which is more -// memory efficient. -struct AttributeImpl -{ - NodeImpl::Id id() const { return m_attrId ? m_attrId : m_data.attr->id(); } - DOMStringImpl *val() const { return m_attrId ? m_data.value : m_data.attr->val(); } - DOMString value() const { return val(); } - AttrImpl *attr() const { return m_attrId ? 0 : m_data.attr; } - DOMString namespaceURI() { return m_attrId ? DOMString() : m_data.attr->namespaceURI(); } - DOMString prefix() { return m_attrId ? DOMString() : m_data.attr->prefix(); } - DOMString localName() { return m_attrId ? DOMString() : m_data.attr->localName(); } - DOMString name() { return m_attrId ? DOMString() : m_data.attr->name(); } - - void setValue(DOMStringImpl *value, ElementImpl *element); - AttrImpl *createAttr(ElementImpl *element, DocumentImpl *docPtr); - void free(); - - NodeImpl::Id m_attrId; - union { - DOMStringImpl *value; - AttrImpl *attr; - } m_data; -}; - -class ElementImpl : public NodeBaseImpl -{ - friend class DocumentImpl; - friend class NamedAttrMapImpl; - friend class AttrImpl; - friend class NodeImpl; - friend class khtml::CSSStyleSelector; -public: - ElementImpl(DocumentImpl *doc); - ~ElementImpl(); - - DOMString getAttribute( NodeImpl::Id id, bool nsAware = 0, const DOMString& qName = DOMString() ) const; - DOMStringImpl* getAttributeImpl( NodeImpl::Id id, bool nsAware = 0, DOMStringImpl* qName = 0 ) const; - void setAttribute( NodeImpl::Id id, const DOMString &value, const DOMString &qName, - int &exceptioncode ); - void setAttributeNS( const DOMString &namespaceURI, const DOMString &qualifiedName, - const DOMString& value, int &exceptioncode ); - virtual DOMString prefix() const; - void setPrefix(const DOMString &_prefix, int &exceptioncode ); - virtual DOMString namespaceURI() const; - - // DOM methods overridden from parent classes - virtual DOMString tagName() const = 0; - virtual unsigned short nodeType() const; - virtual NodeImpl *cloneNode ( bool deep ); - virtual DOMString nodeName() const; - virtual NodeImpl::Id id() const = 0; - virtual bool isElementNode() const { return true; } - virtual void insertedIntoDocument(); - virtual void removedFromDocument(); - - // convenience methods which ignore exceptions - void setAttribute (NodeImpl::Id id, const DOMString &value); - - NamedAttrMapImpl* attributes(bool readonly = false) const - { - if (!readonly && !namedAttrMap) createAttributeMap(); - return namedAttrMap; - } - - //This is always called, whenever an attribute changed - virtual void parseAttribute(AttributeImpl *) {} - void parseAttribute(NodeImpl::Id attrId, DOMStringImpl *value) { - AttributeImpl aimpl; - aimpl.m_attrId = attrId; - aimpl.m_data.value = value; - parseAttribute(&aimpl); - } - - // not part of the DOM - void setAttributeMap ( NamedAttrMapImpl* list ); - - // State of the element. - virtual TQString state() { return TQString::null; } - - virtual void attach(); - virtual void close(); - virtual void detach(); - virtual void structureChanged(); - virtual void backwardsStructureChanged(); - virtual void attributeChanged(NodeImpl::Id attrId); - - virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent); - virtual khtml::RenderObject *createRenderer(khtml::RenderArena *, khtml::RenderStyle *); - virtual void recalcStyle( StyleChange = NoChange ); - - virtual void mouseEventHandler( MouseEvent* /*ev*/, bool /*inside*/ ) {} - virtual bool isFocusable() const; - virtual bool childAllowed( NodeImpl *newChild ); - virtual bool childTypeAllowed( unsigned short type ); - - DOM::CSSStyleDeclarationImpl *styleRules() { - if (!m_styleDecls) createDecl(); - return m_styleDecls; - } - - void dispatchAttrRemovalEvent(NodeImpl::Id id, DOMStringImpl *value); - void dispatchAttrAdditionEvent(NodeImpl::Id id, DOMStringImpl *value); - - virtual DOMString toString() const; - virtual DOMString selectionToString(NodeImpl *selectionStart, NodeImpl *selectionEnd, int startOffset, int endOffset, bool &found) const; - - virtual bool contentEditable() const; - void setContentEditable(bool enabled); - - void scrollIntoView(bool alignToTop); - - /** Returns the opening tag and properties. - * Examples: '<b', '<img alt="hello" src="image.png" - * - * For security reasons, passwords are stripped out of all src= and - * href= tags if expandurls is turned on. - * - * @param expandurls If this is set then in the above example, it would give - * src="http://website.com/image.png". Note that the password - * is stripped out of the url. - * - * DOM::RangeImpl uses this which is why it is public. - */ - DOMString openTagStartToString(bool expandurls = false) const; - - void updateId(DOMStringImpl* oldId, DOMStringImpl* newId); - //Called when mapping from id to this node in document should be removed - virtual void removeId(const TQString& id); - //Called when mapping from id to this node in document should be added - virtual void addId (const TQString& id); - -protected: - void createAttributeMap() const; - void createDecl(); - void finishCloneNode( ElementImpl *clone, bool deep ); - -private: - // map of default attributes. derived element classes are responsible - // for setting this according to the corresponding element description - // in the DTD - virtual NamedAttrMapImpl* defaultMap() const; - -protected: // member variables - mutable NamedAttrMapImpl *namedAttrMap; - - DOM::CSSStyleDeclarationImpl *m_styleDecls; - DOMStringImpl *m_prefix; -}; - - -class XMLElementImpl : public ElementImpl -{ - -public: - XMLElementImpl(DocumentImpl *doc, NodeImpl::Id id); - XMLElementImpl(DocumentImpl *doc, NodeImpl::Id id, DOMStringImpl *_qualifiedName); - ~XMLElementImpl(); - - // DOM methods overridden from parent classes - virtual DOMString tagName() const; - virtual DOMString localName() const; - virtual NodeImpl *cloneNode ( bool deep ); - - // Other methods (not part of DOM) - virtual bool isXMLElementNode() const { return true; } - virtual Id id() const { return m_id; } - -protected: - Id m_id; -}; - -// the map of attributes of an element -class NamedAttrMapImpl : public NamedNodeMapImpl -{ - friend class ElementImpl; -public: - NamedAttrMapImpl(ElementImpl *element); - virtual ~NamedAttrMapImpl(); - - // DOM methods & attributes for NamedNodeMap - virtual NodeImpl *getNamedItem ( NodeImpl::Id id, bool nsAware = false, DOMStringImpl* qName = 0 ) const; - virtual Node removeNamedItem ( NodeImpl::Id id, bool nsAware, DOMStringImpl* qName, int &exceptioncode ); - virtual Node setNamedItem ( NodeImpl* arg, bool nsAware, DOMStringImpl* qName, int &exceptioncode ); - - virtual NodeImpl *item ( unsigned long index ) const; - virtual unsigned long length( ) const; - - // Other methods (not part of DOM) - virtual bool isReadOnly() { return false; } - - AttributeImpl *attrAt(unsigned long index) const { return &m_attrs[index]; } - // ### replace idAt and getValueAt with attrAt - NodeImpl::Id idAt(unsigned long index) const; - DOMStringImpl *valueAt(unsigned long index) const; - DOMStringImpl *getValue(NodeImpl::Id id, bool nsAware = false, DOMStringImpl* qName = 0) const; - void setValue(NodeImpl::Id id, DOMStringImpl *value, DOMStringImpl* qName = 0, - DOMStringImpl *prefix = 0, bool nsAware = false, bool hasNS = false); - Attr removeAttr(AttrImpl *attr); - NodeImpl::Id mapId(DOMStringImpl* namespaceURI, DOMStringImpl* localName, bool readonly); - void copyAttributes(NamedAttrMapImpl *other); - void setElement(ElementImpl *element); - void detachFromElement(); - -protected: - ElementImpl *m_element; - AttributeImpl *m_attrs; - unsigned long m_attrCount; -}; - -// ------------ inline DOM helper functions --------------- - -inline bool checkQualifiedName(const DOMString &qualifiedName, const DOMString &namespaceURI, int *colonPos, - bool nameCanBeNull, bool nameCanBeEmpty, int *pExceptioncode) -{ - - // Not mentioned in spec: throw NAMESPACE_ERR if no qualifiedName supplied - if (!nameCanBeNull && qualifiedName.isNull()) { - if (pExceptioncode) - *pExceptioncode = DOMException::NAMESPACE_ERR; - return false; - } - - // INVALID_CHARACTER_ERR: Raised if the specified qualified name contains an illegal character. - if (!qualifiedName.isNull() && !Element::khtmlValidQualifiedName(qualifiedName) - && ( !qualifiedName.isEmpty() || !nameCanBeEmpty ) ) { - if (pExceptioncode) - *pExceptioncode = DOMException::INVALID_CHARACTER_ERR; - return false; - } - - // NAMESPACE_ERR: - // - Raised if the qualifiedName is malformed, - // - if the qualifiedName has a prefix and the namespaceURI is null, or - // - if the qualifiedName is null and the namespaceURI is different from null - // - if the qualifiedName has a prefix that is "xml" and the namespaceURI is different - // from "http://www.w3.org/XML/1998/namespace" [Namespaces]. - int colonpos = -1; - uint i; - DOMStringImpl *qname = qualifiedName.implementation(); - for (i = 0 ; i < qname->l ; i++) { - if ((*qname)[i] == ':') { - colonpos = i; - break; - } - } - - if (!qualifiedName.isNull() && Element::khtmlMalformedQualifiedName(qualifiedName) || - (colonpos >= 0 && namespaceURI.isNull()) || - (qualifiedName.isNull() && !namespaceURI.isNull()) || - (colonpos == 3 && qualifiedName[0] == 'x' && qualifiedName[1] == 'm' && qualifiedName[2] == 'l' && - namespaceURI != "http://www.w3.org/XML/1998/namespace")) { - if (pExceptioncode) - *pExceptioncode = DOMException::NAMESPACE_ERR; - return false; - } - if(colonPos) - *colonPos = colonpos; - return true; -} - -inline void splitPrefixLocalName(DOMStringImpl *qualifiedName, DOMString &prefix, DOMString &localName, int colonPos = -2) -{ - if (colonPos == -2) - for (uint i = 0 ; i < qualifiedName->l ; ++i) - if (qualifiedName->s[i] == ':') { - colonPos = i; - break; - } - if (colonPos >= 0) { - prefix = qualifiedName->copy(); - localName = prefix.split(colonPos+1); - prefix.implementation()->truncate(colonPos); - } else - localName = qualifiedName->copy(); -} - -} //namespace - -#endif diff --git a/khtml/xml/dom_nodeimpl.cpp b/khtml/xml/dom_nodeimpl.cpp deleted file mode 100644 index 5febe695e..000000000 --- a/khtml/xml/dom_nodeimpl.cpp +++ /dev/null @@ -1,2068 +0,0 @@ -/* - * 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) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * (C) 2003-2006 Apple Computer, Inc. - * (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "dom/dom_exception.h" -#include "misc/htmlattrs.h" -#include "misc/htmltags.h" -#include "xml/dom_elementimpl.h" -#include "xml/dom_textimpl.h" -#include "xml/dom2_eventsimpl.h" -#include "xml/dom_docimpl.h" -#include "xml/dom_nodeimpl.h" -#include "xml/dom_restyler.h" - -#include <kglobal.h> -#include <kdebug.h> - -#include "rendering/render_text.h" -#include "rendering/render_flow.h" -#include "rendering/render_line.h" - -#include "ecma/kjs_proxy.h" -#include "khtmlview.h" -#include "khtml_part.h" -#include "dom_nodeimpl.h" - -// from khtml_caret_p.h -namespace khtml { -void /*KDE_NO_EXPORT*/ mapDOMPosToRenderPos(DOM::NodeImpl *node, long offset, - khtml::RenderObject *&r, long &r_ofs, bool &outside, bool &outsideEnd); -} - -using namespace DOM; -using namespace khtml; - -NodeImpl::NodeImpl(DocumentImpl *doc) - : m_document(doc), - m_previous(0), - m_next(0), - m_render(0), - m_tabIndex( 0 ), - m_hasId( false ), - m_attached(false), - m_closed(false), - m_changed( false ), - m_hasChangedChild( false ), - m_changedAscendentAttribute( false ), - m_inDocument( false ), - m_hasAnchor( false ), - m_specified( false ), - m_hovered( false ), - m_focused( false ), - m_active( false ), - m_implicit( false ), - m_htmlCompat( false ), - m_hasClassList( false ), - m_hasClass( false ) -{ -} - -NodeImpl::~NodeImpl() -{ - if (m_render) - detach(); - if (m_previous) - m_previous->setNextSibling(0); - if (m_next) - m_next->setPreviousSibling(0); -} - -DOMString NodeImpl::nodeValue() const -{ - return DOMString(); -} - -void NodeImpl::setNodeValue( const DOMString &/*_nodeValue*/, int &/*exceptioncode*/ ) -{ - // by default nodeValue is null, so setting it has no effect - // don't throw NO_MODIFICATION_ALLOWED_ERR from here, DOMTS-Core-Level1's hc_nodevalue03 - // (createEntityReference().setNodeValue())) says it would be wrong. - // This must be done by subclasses instead. -} - -DOMString NodeImpl::nodeName() const -{ - return DOMString(); -} - -unsigned short NodeImpl::nodeType() const -{ - return 0; -} - -NodeListImpl *NodeImpl::childNodes() -{ - return new ChildNodeListImpl(this); -} - -NodeImpl *NodeImpl::firstChild() const -{ - return 0; -} - -NodeImpl *NodeImpl::lastChild() const -{ - return 0; -} - -NodeImpl *NodeImpl::insertBefore( NodeImpl *, NodeImpl *, int &exceptioncode ) -{ - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return 0; -} - -void NodeImpl::replaceChild( NodeImpl *, NodeImpl *, int &exceptioncode ) -{ - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; -} - -void NodeImpl::removeChild( NodeImpl *, int &exceptioncode ) -{ - exceptioncode = DOMException::NOT_FOUND_ERR; -} - -NodeImpl *NodeImpl::appendChild( NodeImpl *, int &exceptioncode ) -{ - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return 0; -} - -bool NodeImpl::hasChildNodes( ) const -{ - return false; -} - -void NodeImpl::normalize () -{ - // ### normalize attributes? (when we store attributes using child nodes) - int exceptioncode = 0; - NodeImpl *child = firstChild(); - - // Recursively go through the subtree beneath us, normalizing all nodes. In the case - // where there are two adjacent text nodes, they are merged together - while (child) { - NodeImpl *nextChild = child->nextSibling(); - - if (nextChild && child->nodeType() == Node::TEXT_NODE && nextChild->nodeType() == Node::TEXT_NODE) { - // Current child and the next one are both text nodes... merge them - TextImpl *currentText = static_cast<TextImpl*>(child); - TextImpl *nextText = static_cast<TextImpl*>(nextChild); - - currentText->appendData(nextText->data(),exceptioncode); - if (exceptioncode) - return; - - removeChild(nextChild,exceptioncode); - if (exceptioncode) - return; - } - else { - child->normalize(); - child = nextChild; - } - } -} - -DOMString NodeImpl::prefix() const -{ - // For nodes other than elements and attributes, the prefix is always null - return DOMString(); -} - -DOMString NodeImpl::namespaceURI() const -{ - return DOMString(); -} - -void NodeImpl::setPrefix(const DOMString &/*_prefix*/, int &exceptioncode ) -{ - // The spec says that for nodes other than elements and attributes, prefix is always null. - // It does not say what to do when the user tries to set the prefix on another type of - // node, however mozilla throws a NAMESPACE_ERR exception - exceptioncode = DOMException::NAMESPACE_ERR; -} - -DOMString NodeImpl::localName() const -{ - return DOMString(); -} - -void NodeImpl::setFirstChild(NodeImpl *) -{ -} - -void NodeImpl::setLastChild(NodeImpl *) -{ -} - -NodeImpl *NodeImpl::addChild(NodeImpl *) -{ - return 0; -} - -void NodeImpl::getCaret(int offset, bool override, int &_x, int &_y, int &width, int &height) -{ - if (m_render) { - RenderObject *r; - long r_ofs; - bool outside, outsideEnd; -#if 0 -kdDebug(6200) << "getCaret: node " << this << " " << nodeName().string() << " offset: " << offset << endl; -#endif - mapDOMPosToRenderPos(this, offset, r, r_ofs, outside, outsideEnd); -#if 0 -kdDebug(6200) << "getCaret: r " << r << " " << (r?r->renderName():TQString::null) << " r_ofs: " << r_ofs << " outside " << outside << " outsideEnd " << outsideEnd << endl; -#endif - if (r) { - r->caretPos(r_ofs, override*RenderObject::CFOverride - + outside*RenderObject::CFOutside - + outsideEnd*RenderObject::CFOutsideEnd, _x, _y, width, height); - } else - _x = _y = height = -1, width = 1; - } else _x = _y = height = -1, width = 1; -} - -TQRect NodeImpl::getRect() const -{ - int _x, _y; - if(m_render && m_render->absolutePosition(_x, _y)) - return TQRect( _x + m_render->inlineXPos(), _y + m_render->inlineYPos(), - m_render->width(), m_render->height() + renderer()->borderTopExtra() + renderer()->borderBottomExtra() ); - - return TQRect(); -} - -void NodeImpl::setChanged(bool b) -{ - if (b && !attached()) // changed compared to what? - return; - - m_changed = b; - if ( b ) { - NodeImpl *p = parentNode(); - while ( p ) { - p->setHasChangedChild( true ); - p = p->parentNode(); - } - getDocument()->setDocumentChanged(); - } -} - -bool NodeImpl::isInline() const -{ - if (m_render) return m_render->style()->display() == khtml::INLINE; - return !isElementNode(); -} - - -unsigned long NodeImpl::nodeIndex() const -{ - NodeImpl *_tempNode = previousSibling(); - unsigned long count=0; - for( count=0; _tempNode; count++ ) - _tempNode = _tempNode->previousSibling(); - return count; -} - -void NodeImpl::addEventListener(int id, EventListener *listener, const bool useCapture) -{ - switch (id) { - case EventImpl::DOMSUBTREEMODIFIED_EVENT: - getDocument()->addListenerType(DocumentImpl::DOMSUBTREEMODIFIED_LISTENER); - break; - case EventImpl::DOMNODEINSERTED_EVENT: - getDocument()->addListenerType(DocumentImpl::DOMNODEINSERTED_LISTENER); - break; - case EventImpl::DOMNODEREMOVED_EVENT: - getDocument()->addListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER); - break; - case EventImpl::DOMNODEREMOVEDFROMDOCUMENT_EVENT: - getDocument()->addListenerType(DocumentImpl::DOMNODEREMOVEDFROMDOCUMENT_LISTENER); - break; - case EventImpl::DOMNODEINSERTEDINTODOCUMENT_EVENT: - getDocument()->addListenerType(DocumentImpl::DOMNODEINSERTEDINTODOCUMENT_LISTENER); - break; - case EventImpl::DOMATTRMODIFIED_EVENT: - getDocument()->addListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER); - break; - case EventImpl::DOMCHARACTERDATAMODIFIED_EVENT: - getDocument()->addListenerType(DocumentImpl::DOMCHARACTERDATAMODIFIED_LISTENER); - break; - default: - break; - } - - m_regdListeners.addEventListener(id, listener, useCapture); -} - -void NodeImpl::removeEventListener(int id, EventListener *listener, bool useCapture) -{ - m_regdListeners.removeEventListener(id, listener, useCapture); -} - -void NodeImpl::setHTMLEventListener(int id, EventListener *listener) -{ - m_regdListeners.setHTMLEventListener(id, listener); -} - -EventListener *NodeImpl::getHTMLEventListener(int id) -{ - return m_regdListeners.getHTMLEventListener(id); -} - -void NodeImpl::dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent) -{ - evt->setTarget(this); - - // Since event handling code could cause this object to be deleted, grab a reference to the view now - KHTMLView *view = getDocument()->view(); - - dispatchGenericEvent( evt, exceptioncode ); - - // If tempEvent is true, this means that the DOM implementation will not be storing a reference to the event, i.e. - // there is no way to retrieve it from javascript if a script does not already have a reference to it in a variable. - // So there is no need for the interpreter to keep the event in its cache - if (tempEvent && view && view->part() && view->part()->jScript()) - view->part()->jScript()->finishedWithEvent(evt); -} - -void NodeImpl::dispatchGenericEvent( EventImpl *evt, int &/*exceptioncode */) -{ - // ### check that type specified - - // work out what nodes to send event to - TQPtrList<NodeImpl> nodeChain; - NodeImpl *n; - for (n = this; n; n = n->parentNode()) { - n->ref(); - nodeChain.prepend(n); - } - - // trigger any capturing event handlers on our way down - evt->setEventPhase(Event::CAPTURING_PHASE); - TQPtrListIterator<NodeImpl> it(nodeChain); - for (; it.current() && it.current() != this && !evt->propagationStopped(); ++it) { - evt->setCurrentTarget(it.current()); - it.current()->handleLocalEvents(evt,true); - } - - // dispatch to the actual target node - it.toLast(); - NodeImpl* propagationSentinel = 0; - if (!evt->propagationStopped()) { - evt->setEventPhase(Event::AT_TARGET); - evt->setCurrentTarget(it.current()); - it.current()->handleLocalEvents(evt, true); - if (!evt->propagationStopped()) - it.current()->handleLocalEvents(evt,false); - else - propagationSentinel = it.current(); - } - --it; - - if (evt->bubbles()) { - evt->setEventPhase(Event::BUBBLING_PHASE); - for (; it.current() && !evt->propagationStopped(); --it) { - if (evt->propagationStopped()) propagationSentinel = it.current(); - evt->setCurrentTarget(it.current()); - it.current()->handleLocalEvents(evt,false); - } - - // now we call all default event handlers (this is not part of DOM - it is internal to khtml) - evt->setCurrentTarget(0); - evt->setEventPhase(0); // I guess this is correct, the spec does not seem to say - for (it.toLast(); it.current() && it.current() != propagationSentinel && - !evt->defaultPrevented() && !evt->defaultHandled(); --it) - it.current()->defaultEventHandler(evt); - - if (evt->id() == EventImpl::CLICK_EVENT && !evt->defaultPrevented() && - static_cast<MouseEventImpl*>( evt )->button() == 0) // LMB click - dispatchUIEvent(EventImpl::DOMACTIVATE_EVENT, static_cast<UIEventImpl*>(evt)->detail()); - } - - // copy this over into a local variable, as the following deref() calls might cause this to be deleted. - DocumentImpl *doc = m_document.get(); - doc->ref(); - - // deref all nodes in chain - it.toFirst(); - for (; it.current(); ++it) - it.current()->deref(); // this may delete us - - DocumentImpl::updateDocumentsRendering(); - doc->deref(); -} - -bool NodeImpl::dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg) -{ - int exceptioncode = 0; - EventImpl* const evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg); - evt->ref(); - dispatchEvent(evt,exceptioncode,true); - bool ret = !evt->defaultPrevented(); - evt->deref(); - return ret; -} - -void NodeImpl::dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg) -{ - int exceptioncode = 0; - EventImpl* const evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg); - evt->setTarget( 0 ); - evt->ref(); - DocumentImpl *doc = getDocument(); - doc->ref(); - dispatchGenericEvent( evt, exceptioncode ); - if (!evt->defaultPrevented() && doc) - doc->defaultEventHandler(evt); - - if (_id == EventImpl::LOAD_EVENT && !evt->propagationStopped() && doc) { - // For onload events, send them to the enclosing frame only. - // This is a DOM extension and is independent of bubbling/capturing rules of - // the DOM. You send the event only to the enclosing frame. It does not - // bubble through the parent document. - DOM::ElementImpl* elt = doc->ownerElement(); - if (elt && (elt->getDocument()->domain().isNull() || - elt->getDocument()->domain() == doc->domain())) { - // We also do a security check, since we don't want to allow the enclosing - // iframe to see loads of child documents in other domains. - evt->setCurrentTarget(elt); - - // Capturing first. - elt->handleLocalEvents(evt,true); - - // Bubbling second. - if (!evt->propagationStopped()) - elt->handleLocalEvents(evt,false); - } - } - - doc->deref(); - evt->deref(); -} - -void NodeImpl::dispatchMouseEvent(TQMouseEvent *_mouse, int overrideId, int overrideDetail) -{ - bool cancelable = true; - int detail = overrideDetail; // defaults to 0 - EventImpl::EventId evtId = EventImpl::UNKNOWN_EVENT; - if (overrideId) { - evtId = static_cast<EventImpl::EventId>(overrideId); - } - else { - switch (_mouse->type()) { - case TQEvent::MouseButtonPress: - evtId = EventImpl::MOUSEDOWN_EVENT; - break; - case TQEvent::MouseButtonRelease: - evtId = EventImpl::MOUSEUP_EVENT; - break; - case TQEvent::MouseButtonDblClick: - evtId = EventImpl::CLICK_EVENT; - detail = 1; // ### support for multiple double clicks - break; - case TQEvent::MouseMove: - evtId = EventImpl::MOUSEMOVE_EVENT; - cancelable = false; - break; - default: - break; - } - } - if (evtId == EventImpl::UNKNOWN_EVENT) - return; // shouldn't happen - - - int exceptioncode = 0; - int pageX = _mouse->x(); - int pageY = _mouse->y(); - int clientX = pageX; - int clientY = pageY; - if ( getDocument()->view() ) - getDocument()->view()->viewportToContents( clientX, clientY, pageX, pageY ); - - int screenX = _mouse->globalX(); - int screenY = _mouse->globalY(); - - int button = -1; - switch (_mouse->button()) { - case Qt::LeftButton: - button = 0; - break; - case Qt::MidButton: - button = 1; - break; - case Qt::RightButton: - button = 2; - break; - default: - break; - } - bool ctrlKey = (_mouse->state() & TQt::ControlButton); - bool altKey = (_mouse->state() & TQt::AltButton); - bool shiftKey = (_mouse->state() & TQt::ShiftButton); - bool metaKey = false; // ### qt support? - - EventImpl* const evt = new MouseEventImpl(evtId,true,cancelable,getDocument()->defaultView(), - detail,screenX,screenY,clientX,clientY,pageX,pageY,ctrlKey,altKey,shiftKey,metaKey, - button,0); - evt->ref(); - dispatchEvent(evt,exceptioncode,true); - evt->deref(); -} - -void NodeImpl::dispatchUIEvent(int _id, int detail) -{ - assert (!( (_id != EventImpl::DOMFOCUSIN_EVENT && - _id != EventImpl::DOMFOCUSOUT_EVENT && - _id != EventImpl::DOMACTIVATE_EVENT))); - - bool cancelable = false; - if (_id == EventImpl::DOMACTIVATE_EVENT) - cancelable = true; - - int exceptioncode = 0; - UIEventImpl* const evt = new UIEventImpl(static_cast<EventImpl::EventId>(_id),true, - cancelable,getDocument()->defaultView(),detail); - evt->ref(); - dispatchEvent(evt,exceptioncode,true); - evt->deref(); -} - -void NodeImpl::dispatchSubtreeModifiedEvent() -{ - childrenChanged(); - getDocument()->incDOMTreeVersion(); - if (!getDocument()->hasListenerType(DocumentImpl::DOMSUBTREEMODIFIED_LISTENER)) - return; - int exceptioncode = 0; - MutationEventImpl* const evt = new MutationEventImpl(EventImpl::DOMSUBTREEMODIFIED_EVENT,true, - false,0,DOMString(),DOMString(),DOMString(),0); - evt->ref(); - dispatchEvent(evt,exceptioncode,true); - evt->deref(); -} - -bool NodeImpl::dispatchKeyEvent(TQKeyEvent *key, bool keypress) -{ - int exceptioncode = 0; - //kdDebug(6010) << "DOM::NodeImpl: dispatching keyboard event" << endl; - EventImpl* keyEventImpl; - if (keypress) - keyEventImpl = new TextEventImpl(key, getDocument()->defaultView()); - else - keyEventImpl = new KeyboardEventImpl(key, getDocument()->defaultView()); - keyEventImpl->ref(); - dispatchEvent(keyEventImpl,exceptioncode,true); - bool r = keyEventImpl->defaultHandled() || keyEventImpl->defaultPrevented(); - keyEventImpl->deref(); - return r; -} - -void NodeImpl::handleLocalEvents(EventImpl *evt, bool useCapture) -{ - if (!m_regdListeners.listeners) - return; - - Event ev = evt; - // removeEventListener (e.g. called from a JS event listener) might - // invalidate the item after the current iterator (which "it" is pointing to). - // So we make a copy of the list. - TQValueList<RegisteredEventListener> listeners = *m_regdListeners.listeners; - TQValueList<RegisteredEventListener>::iterator it; - for (it = listeners.begin(); it != listeners.end(); ++it) { - //Check whether this got removed...KDE4: use Java-style iterators - if (!m_regdListeners.stillContainsListener(*it)) - continue; - - RegisteredEventListener& current = (*it); - if (current.id == evt->id() && current.useCapture == useCapture) - current.listener->handleEvent(ev); - - // ECMA legacy hack - if (current.useCapture == useCapture && evt->id() == EventImpl::CLICK_EVENT) { - MouseEventImpl* me = static_cast<MouseEventImpl*>(evt); - if (me->button() == 0) { - // To find whether to call onclick or ondblclick, we can't - // * use me->detail(), it's 2 when clicking twice w/o moving, even very slowly - // * use me->qEvent(), it's not available when using initMouseEvent/dispatchEvent - // So we currently store a bool in MouseEventImpl. If anyone needs to trigger - // dblclicks from the DOM API, we'll need a timer here (well in the doc). - if ( ( !me->isDoubleClick() && current.id == EventImpl::KHTML_ECMA_CLICK_EVENT) || - ( me->isDoubleClick() && current.id == EventImpl::KHTML_ECMA_DBLCLICK_EVENT) ) - current.listener->handleEvent(ev); - } - } - } -} - -void NodeImpl::defaultEventHandler(EventImpl *) -{ -} - -unsigned long NodeImpl::childNodeCount() -{ - return 0; -} - -NodeImpl *NodeImpl::childNode(unsigned long /*index*/) -{ - return 0; -} - -NodeImpl *NodeImpl::traverseNextNode(NodeImpl *stayWithin) const -{ - if (firstChild() || stayWithin == this) - return firstChild(); - else if (nextSibling()) - return nextSibling(); - else { - const NodeImpl *n = this; - while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin)) - n = n->parentNode(); - if (n) - return n->nextSibling(); - } - return 0; -} - -NodeImpl *NodeImpl::traversePreviousNode() const -{ - if (previousSibling()) { - NodeImpl *n = previousSibling(); - while (n->lastChild()) - n = n->lastChild(); - return n; - } - else if (parentNode()) { - return parentNode(); - } - else { - return 0; - } -} - -void NodeImpl::checkSetPrefix(const DOMString &_prefix, int &exceptioncode) -{ - // Perform error checking as required by spec for setting Node.prefix. Used by - // ElementImpl::setPrefix() and AttrImpl::setPrefix() - - // INVALID_CHARACTER_ERR: Raised if the specified prefix contains an illegal character. - if (!Element::khtmlValidPrefix(_prefix)) { - exceptioncode = DOMException::INVALID_CHARACTER_ERR; - return; - } - - // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. - if (isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - // NAMESPACE_ERR: - Raised if the specified prefix is malformed - // - if the namespaceURI of this node is null, - // - if the specified prefix is "xml" and the namespaceURI of this node is different from - // "http://www.w3.org/XML/1998/namespace", - // - if this node is an attribute and the specified prefix is "xmlns" and - // the namespaceURI of this node is different from "http://www.w3.org/2000/xmlns/", - // - or if this node is an attribute and the qualifiedName of this node is "xmlns" [Namespaces]. - if (Element::khtmlMalformedPrefix(_prefix) || (namespacePart(id()) == defaultNamespace && id() > ID_LAST_TAG) || - (_prefix == "xml" && namespaceURI() != "http://www.w3.org/XML/1998/namespace")) { - exceptioncode = DOMException::NAMESPACE_ERR; - return; - } -} - -void NodeImpl::checkAddChild(NodeImpl *newChild, int &exceptioncode) -{ - // Perform error checking as required by spec for adding a new child. Used by - // appendChild(), replaceChild() and insertBefore() - - // Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null - if (!newChild) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly - if (isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - // WRONG_DOCUMENT_ERR: Raised if newChild was created from a different document than the one that - // created this node. - // We assume that if newChild is a DocumentFragment, all children are created from the same document - // as the fragment itself (otherwise they could not have been added as children) - if (newChild->getDocument() != getDocument()) { - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return; - } - - // HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not allow children of the type of the - // newChild node, or if the node to append is one of this node's ancestors. - - // check for ancestor/same node - if (isAncestor(newChild)) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - - // check node allowed - if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) { - // newChild is a DocumentFragment... check all its children instead of newChild itself - NodeImpl *child; - for (child = newChild->firstChild(); child; child = child->nextSibling()) { - if (!childTypeAllowed(child->nodeType())) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - } - } - else { - // newChild is not a DocumentFragment... check if it's allowed directly - if(!childTypeAllowed(newChild->nodeType())) { - exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; - return; - } - } -} - -bool NodeImpl::isAncestor( NodeImpl *other ) -{ - // Return true if other is the same as this node or an ancestor of it, otherwise false - NodeImpl *n; - for (n = this; n; n = n->parentNode()) { - if (n == other) - return true; - } - return false; -} - -bool NodeImpl::childAllowed( NodeImpl *newChild ) -{ - return childTypeAllowed(newChild->nodeType()); -} - -NodeImpl::StyleChange NodeImpl::diff( khtml::RenderStyle *s1, khtml::RenderStyle *s2 ) -{ - // This method won't work when a style contains noninherited properties with "inherit" value. - StyleChange ch = NoInherit; - - EDisplay display1 = s1 ? s1->display() : NONE; - EDisplay display2 = s2 ? s2->display() : NONE; - EPosition position1 = s1 ? s1->position() : STATIC; - EPosition position2 = s2 ? s2->position() : STATIC; - - if (display1 != display2 || position1 != position2) - ch = Detach; - else if ( !s1 || !s2 ) - ch = Inherit; - else if ( *s1 == *s2 ) - ch = NoChange; - else if (s1->useNormalContent() != s2->useNormalContent()) - ch = Detach; // when we add generated content all children must be detached - else if ( s1->inheritedNotEqual( s2 ) ) - ch = Inherit; - - // Because the first-letter implementation is so f..ked up, the easiest way - // to update first-letter is to remove the entire node and readd it. - if (ch < Detach && pseudoDiff(s1, s2, khtml::RenderStyle::FIRST_LETTER)) - ch = Detach; - // If the other pseudoStyles have changed, we want to return NoInherit - if (ch == NoChange && pseudoDiff(s1, s2, khtml::RenderStyle::BEFORE)) - ch = NoInherit; - if (ch == NoChange && pseudoDiff(s1, s2, khtml::RenderStyle::AFTER)) - ch = NoInherit; - if (ch == NoChange && pseudoDiff(s1, s2, khtml::RenderStyle::MARKER)) - ch = NoInherit; - if (ch == NoChange && pseudoDiff(s1, s2, khtml::RenderStyle::SELECTION)) - ch = NoInherit; - if (ch == NoChange && pseudoDiff(s1, s2, khtml::RenderStyle::FIRST_LINE)) - ch = NoInherit; - - return ch; -} - -bool NodeImpl::pseudoDiff( khtml::RenderStyle *s1, khtml::RenderStyle *s2, unsigned int pid) -{ - khtml::RenderStyle *ps1 = s1 ? s1->getPseudoStyle((khtml::RenderStyle::PseudoId)pid) : 0; - khtml::RenderStyle *ps2 = s2 ? s2->getPseudoStyle((khtml::RenderStyle::PseudoId)pid) : 0; - - if (ps1 == ps2) - return false; - else - if (ps1 && ps2) { - if (*ps1 == *ps2) - return false; - else - return true; - } - else - return true; -} - -void NodeImpl::close() -{ - if (m_render) m_render->close(); - m_closed = true; -} - -void NodeImpl::attach() -{ - assert(!attached()); - assert(!m_render || (m_render->style() && m_render->parent())); - if (m_render) // set states to match node - { - if (closed()) m_render->close(); - if (hovered()) m_render->setMouseInside(); - } - getDocument()->incDOMTreeVersion(); - m_attached = true; -} - -void NodeImpl::detach() -{ -// assert(m_attached); - - if ( m_render ) - m_render->detach(); - - m_render = 0; - getDocument()->incDOMTreeVersion(); - m_attached = false; -} - -bool NodeImpl::maintainsState() -{ - return false; -} - -TQString NodeImpl::state() -{ - return TQString::null; -} - -void NodeImpl::restoreState(const TQString &/*state*/) -{ -} - -void NodeImpl::insertedIntoDocument() -{ - setInDocument(true); -} - -void NodeImpl::removedFromDocument() -{ - setInDocument(false); -} - -void NodeImpl::childrenChanged() -{ - if (parentNode()) - parentNode()->childrenChanged(); -} - -bool NodeImpl::isReadOnly() -{ - // Entity & Entity Reference nodes and their descendants are read-only - NodeImpl *n = this; - while (n) { - if (n->nodeType() == Node::ENTITY_NODE || - n->nodeType() == Node::ENTITY_REFERENCE_NODE) - return true; - n = n->parentNode(); - } - return false; -} - -RenderObject * NodeImpl::previousRenderer() -{ - for (NodeImpl *n = previousSibling(); n; n = n->previousSibling()) { - if (n->renderer()) - return n->renderer(); - } - return 0; -} - -RenderObject * NodeImpl::nextRenderer() -{ - for (NodeImpl *n = nextSibling(); n; n = n->nextSibling()) { - if (n->renderer()) - return n->renderer(); - } - return 0; -} - -void NodeImpl::createRendererIfNeeded() -{ -#ifdef APPLE_CHANGES - if (!getDocument()->shouldCreateRenderers()) - return; -#endif - - assert(!m_render); - - NodeImpl *parent = parentNode(); - assert(parent); - - RenderObject *parentRenderer = parent->renderer(); - if (parentRenderer && parentRenderer->childAllowed()) { - RenderStyle *style = styleForRenderer(parentRenderer); - style->ref(); - if (rendererIsNeeded(style)) { - m_render = createRenderer(getDocument()->renderArena(), style); - m_render->setStyle(style); - parentRenderer->addChild(m_render, nextRenderer()); - } - style->deref(); - } -} - -RenderStyle *NodeImpl::styleForRenderer(RenderObject *parent) -{ - return parent->style(); -} - -bool NodeImpl::rendererIsNeeded(RenderStyle *style) -{ - return (getDocument()->documentElement() == this) || (style->display() != NONE); -} - -RenderObject *NodeImpl::createRenderer(RenderArena* /*arena*/, RenderStyle* /*style*/) -{ - assert(false); - return 0; -} - -bool NodeImpl::contentEditable() const -{ - RenderObject *r = renderer(); - if (!r || !r->style()) return false; - return r->style()->userInput() == UI_ENABLED; -} - -long NodeImpl::minOffset() const -{ - // Arrgh! You'd think *every* offset starts at zero, but loo, - // therefore we need this method - return renderer() ? renderer()->minOffset() : 0; -} - -long NodeImpl::maxOffset() const -{ - return const_cast<NodeImpl *>(this)->childNodeCount(); -// return renderer() ? renderer()->maxOffset() : 1; -} - -DOMStringImpl* NodeImpl::textContent() const -{ - TQString out; - for (NodeImpl *child = firstChild(); child != 0; child = child->nextSibling()) { - short type = child->nodeType(); - if (type != Node::COMMENT_NODE && type != Node::PROCESSING_INSTRUCTION_NODE) { - DOMStringImpl* kidText = child->textContent(); - if (kidText) - out += TQConstString(kidText->s, kidText->l).string(); - delete kidText; - } - } - return new DOMStringImpl(out.unicode(), out.length()); -} - -//------------------------------------------------------------------------- - -NodeBaseImpl::~NodeBaseImpl() -{ - //kdDebug( 6020 ) << "NodeBaseImpl destructor" << endl; - // we have to tell all children, that the parent has died... - NodeImpl *n; - NodeImpl *next; - - for( n = _first; n != 0; n = next ) { - next = n->nextSibling(); - n->setPreviousSibling(0); - n->setNextSibling(0); - n->setParent(0); - if ( !n->refCount() ) - delete n; - } -} - - -NodeImpl *NodeBaseImpl::firstChild() const -{ - return _first; -} - -NodeImpl *NodeBaseImpl::lastChild() const -{ - return _last; -} - -NodeImpl *NodeBaseImpl::insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode ) -{ - exceptioncode = 0; - - // insertBefore(...,null) is equivalent to appendChild() - if(!refChild) - return appendChild(newChild, exceptioncode); - - // Make sure adding the new child is ok - checkAddChild(newChild, exceptioncode); - if (exceptioncode) - return 0; - - // NOT_FOUND_ERR: Raised if refChild is not a child of this node - if (refChild->parentNode() != this) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return 0; - } - - bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE; - - // If newChild is a DocumentFragment with no children.... there's nothing to do. - // Just return the document fragment - if (isFragment && !newChild->firstChild()) - return newChild; - - // Now actually add the child(ren) - NodeImpl *nextChild; - NodeImpl *child = isFragment ? newChild->firstChild() : newChild; - - NodeImpl *prev = refChild->previousSibling(); - if ( prev == newChild || refChild == newChild ) // nothing to do - return newChild; - - while (child) { - nextChild = isFragment ? child->nextSibling() : 0; - - // If child is already present in the tree, first remove it - NodeImpl *newParent = child->parentNode(); - - //...guard it in case we need to move it.. - SharedPtr<NodeImpl> guard(child); - - if(newParent) - newParent->removeChild( child, exceptioncode ); - if ( exceptioncode ) - return 0; - - // Add child in the correct position - if (prev) - prev->setNextSibling(child); - else - _first = child; - refChild->setPreviousSibling(child); - child->setParent(this); - child->setPreviousSibling(prev); - child->setNextSibling(refChild); - - // Add child to the rendering tree - // ### should we detach() it first if it's already attached? - if (attached() && !child->attached()) - child->attach(); - - // Dispatch the mutation events - dispatchChildInsertedEvents(child,exceptioncode); - - prev = child; - child = nextChild; - } - - structureChanged(); - - // ### set style in case it's attached - dispatchSubtreeModifiedEvent(); - return newChild; -} - -void NodeBaseImpl::replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode ) -{ - exceptioncode = 0; - - if ( oldChild == newChild ) // nothing to do - return; - - // Make sure adding the new child is ok - checkAddChild(newChild, exceptioncode); - if (exceptioncode) - return; - - // NOT_FOUND_ERR: Raised if oldChild is not a child of this node. - if (!oldChild || oldChild->parentNode() != this) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE; - NodeImpl *nextChild; - NodeImpl *child = isFragment ? newChild->firstChild() : newChild; - - - // Remove the old child - NodeImpl *prev = oldChild->previousSibling(); - NodeImpl *next = oldChild->nextSibling(); - - removeChild(oldChild, exceptioncode); - if (exceptioncode) - return; - - // Add the new child(ren) - while (child) { - nextChild = isFragment ? child->nextSibling() : 0; - - // If child is already present in the tree, first remove it - NodeImpl *newParent = child->parentNode(); - if ( child == next ) - next = child->nextSibling(); - if ( child == prev ) - prev = child->previousSibling(); - //...guard it in case we need to move it.. - SharedPtr<NodeImpl> guard(child); - if(newParent) - newParent->removeChild( child, exceptioncode ); - if (exceptioncode) - return; - - // Add child in the correct position - if (prev) prev->setNextSibling(child); - if (next) next->setPreviousSibling(child); - if(!prev) _first = child; - if(!next) _last = child; - child->setParent(this); - child->setPreviousSibling(prev); - child->setNextSibling(next); - - // Add child to the rendering tree - // ### should we detach() it first if it's already attached? - if (attached() && !child->attached()) - child->attach(); - - // Dispatch the mutation events - dispatchChildInsertedEvents(child,exceptioncode); - - prev = child; - child = nextChild; - } - - structureChanged(); - - // ### set style in case it's attached - dispatchSubtreeModifiedEvent(); - return; -} - -void NodeBaseImpl::removeChild ( NodeImpl *oldChild, int &exceptioncode ) -{ - exceptioncode = 0; - - // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. - if (isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - // NOT_FOUND_ERR: Raised if oldChild is not a child of this node. - if (!oldChild || oldChild->parentNode() != this) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return; - } - - dispatchChildRemovalEvents(oldChild,exceptioncode); - if (exceptioncode) - return; - - SharedPtr<NodeImpl> memManage(oldChild); //Make sure to free if needed - - // Remove from rendering tree - if (oldChild->attached()) - oldChild->detach(); - - // Remove the child - NodeImpl *prev, *next; - prev = oldChild->previousSibling(); - next = oldChild->nextSibling(); - - if(next) next->setPreviousSibling(prev); - if(prev) prev->setNextSibling(next); - if(_first == oldChild) _first = next; - if(_last == oldChild) _last = prev; - - oldChild->setPreviousSibling(0); - oldChild->setNextSibling(0); - oldChild->setParent(0); - - structureChanged(); - - // Dispatch post-removal mutation events - dispatchSubtreeModifiedEvent(); - - NodeImpl *p = this; - while (p->parentNode()) - p = p->parentNode(); - if (p->nodeType() == Node::DOCUMENT_NODE) { - for (NodeImpl *c = oldChild; c; c = c->traverseNextNode(oldChild)) - c->removedFromDocument(); - } -} - -void NodeBaseImpl::removeChildren() -{ - bool inDoc = inDocument(); - NodeImpl *n, *next; - for( n = _first, _first = 0; n; n = next ) - { - next = n->nextSibling(); - if (n->attached()) - n->detach(); - n->setPreviousSibling(0); - n->setNextSibling(0); - n->setParent(0); - - if ( inDoc ) - for ( NodeImpl* c = n; c; c = c->traverseNextNode( n ) ) - c->removedFromDocument(); - - if( !n->refCount() ) - delete n; - } - _last = 0; -} - - -NodeImpl *NodeBaseImpl::appendChild ( NodeImpl *newChild, int &exceptioncode ) -{ - exceptioncode = 0; - - // Make sure adding the new child is ok - checkAddChild(newChild, exceptioncode); - if (exceptioncode) - return 0; - - if ( newChild == _last ) // nothing to do - return newChild; - - bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE; - - // If newChild is a DocumentFragment with no children.... there's nothing to do. - // Just return the document fragment - if (isFragment && !newChild->firstChild()) - return newChild; - - // Now actually add the child(ren) - NodeImpl *nextChild; - NodeImpl *child = isFragment ? newChild->firstChild() : newChild; - - while (child) { - nextChild = isFragment ? child->nextSibling() : 0; - - // If child is already present in the tree, first remove it - NodeImpl *oldParent = child->parentNode(); - SharedPtr<NodeImpl> guard(child); //Guard in case we move it - if(oldParent) { - oldParent->removeChild( child, exceptioncode ); - if (exceptioncode) - return 0; - } - - // Append child to the end of the list - child->setParent(this); - - if(_last) - { - child->setPreviousSibling(_last); - _last->setNextSibling(child); - _last = child; - } - else - { - _first = _last = child; - } - - // Add child to the rendering tree - // ### should we detach() it first if it's already attached? - if (attached() && !child->attached()) - child->attach(); - - // Dispatch the mutation events - dispatchChildInsertedEvents(child,exceptioncode); - - child = nextChild; - } - - backwardsStructureChanged(); - - // ### set style in case it's attached - dispatchSubtreeModifiedEvent(); - return newChild; -} - -bool NodeBaseImpl::hasChildNodes ( ) const -{ - return _first != 0; -} - -// not part of the DOM -void NodeBaseImpl::setFirstChild(NodeImpl *child) -{ - _first = child; -} - -void NodeBaseImpl::setLastChild(NodeImpl *child) -{ - _last = child; -} - -// check for same source document: -bool NodeBaseImpl::checkSameDocument( NodeImpl *newChild, int &exceptioncode ) -{ - exceptioncode = 0; - DocumentImpl *ownerDocThis = getDocument(); - DocumentImpl *ownerDocNew = newChild->getDocument(); - if(ownerDocThis != ownerDocNew) { - kdDebug(6010)<< "not same document, newChild = " << newChild << "document = " << getDocument() << endl; - exceptioncode = DOMException::WRONG_DOCUMENT_ERR; - return true; - } - return false; -} - -// check for being child: -bool NodeBaseImpl::checkIsChild( NodeImpl *oldChild, int &exceptioncode ) -{ - if(!oldChild || oldChild->parentNode() != this) { - exceptioncode = DOMException::NOT_FOUND_ERR; - return true; - } - return false; -} - -NodeImpl *NodeBaseImpl::addChild(NodeImpl *newChild) -{ - // do not add applyChanges here! This function is only used during parsing - - // short check for consistency with DTD - if(getDocument()->isHTMLDocument() && !childAllowed(newChild)) - { - //kdDebug( 6020 ) << "AddChild failed! id=" << id() << ", child->id=" << newChild->id() << endl; - return 0; - } - - // just add it... - newChild->setParent(this); - - if(_last) - { - newChild->setPreviousSibling(_last); - _last->setNextSibling(newChild); - _last = newChild; - } - else - { - _first = _last = newChild; - } - - if (inDocument()) - newChild->insertedIntoDocument(); - childrenChanged(); - - if(newChild->nodeType() == Node::ELEMENT_NODE) - return newChild; - return this; -} - -void NodeBaseImpl::attach() -{ - NodeImpl *child = _first; - while(child != 0) - { - child->attach(); - child = child->nextSibling(); - } - NodeImpl::attach(); -} - -void NodeBaseImpl::detach() -{ - NodeImpl *child = _first; - while(child != 0) - { - NodeImpl* prev = child; - child = child->nextSibling(); - prev->detach(); - } - NodeImpl::detach(); -} - -void NodeBaseImpl::cloneChildNodes(NodeImpl *clone) -{ - int exceptioncode = 0; - NodeImpl *n; - for(n = firstChild(); n && !exceptioncode; n = n->nextSibling()) - { - clone->appendChild(n->cloneNode(true),exceptioncode); - } -} - -// I don't like this way of implementing the method, but I didn't find any -// other way. Lars -bool NodeBaseImpl::getUpperLeftCorner(int &xPos, int &yPos) const -{ - if (!m_render) - return false; - RenderObject *o = m_render; - xPos = yPos = 0; - if ( !o->isInline() || o->isReplaced() ) { - o->absolutePosition( xPos, yPos ); - return true; - } - - // find the next text/image child, to get a position - while(o) { - if(o->firstChild()) - o = o->firstChild(); - else if(o->nextSibling()) - o = o->nextSibling(); - else { - RenderObject *next = 0; - while(!next) { - o = o->parent(); - if(!o) return false; - next = o->nextSibling(); - } - o = next; - } - if((o->isText() && !o->isBR()) || o->isReplaced()) { - o->container()->absolutePosition( xPos, yPos ); - if (o->isText()) { - xPos += o->inlineXPos(); - yPos += o->inlineYPos(); - } else { - xPos += o->xPos(); - yPos += o->yPos(); - } - return true; - } - } - return true; -} - -bool NodeBaseImpl::getLowerRightCorner(int &xPos, int &yPos) const -{ - if (!m_render) - return false; - - RenderObject *o = m_render; - xPos = yPos = 0; - if (!o->isInline() || o->isReplaced()) - { - o->absolutePosition( xPos, yPos ); - xPos += o->width(); - yPos += o->height() + o->borderTopExtra() + o->borderBottomExtra(); - return true; - } - // find the last text/image child, to get a position - while(o) { - if(o->lastChild()) - o = o->lastChild(); - else if(o->previousSibling()) - o = o->previousSibling(); - else { - RenderObject *prev = 0; - while(!prev) { - o = o->parent(); - if(!o) return false; - prev = o->previousSibling(); - } - o = prev; - } - if((o->isText() && !o->isBR()) || o->isReplaced()) { - o->container()->absolutePosition(xPos, yPos); - if (o->isText()) { - xPos += o->inlineXPos() + o->width(); - yPos += o->inlineYPos() + o->height(); - } else { - xPos += o->xPos() + o->width(); - yPos += o->yPos() + o->height(); - } - return true; - } - } - return true; -} - -void NodeBaseImpl::setFocus(bool received) -{ - if (m_focused == received) return; - - NodeImpl::setFocus(received); - - // note that we need to recalc the style - setChanged(); // *:focus is a default style, so we just assume personal dependency - if (isElementNode()) { - getDocument()->dynamicDomRestyler().restyleDepedent(static_cast<ElementImpl*>(this), OtherStateDependency); - } -} - -void NodeBaseImpl::setActive(bool down) -{ - if (down == active()) return; - - NodeImpl::setActive(down); - - // note that we need to recalc the style - if (isElementNode()) - getDocument()->dynamicDomRestyler().restyleDepedent(static_cast<ElementImpl*>(this), ActiveDependency); -} - -void NodeBaseImpl::setHovered(bool hover) -{ - if (hover == hovered()) return; - - NodeImpl::setHovered(hover); - - // note that we need to recalc the style - if (isElementNode()) - getDocument()->dynamicDomRestyler().restyleDepedent(static_cast<ElementImpl*>(this), HoverDependency); -} - -unsigned long NodeBaseImpl::childNodeCount() -{ - unsigned long count = 0; - NodeImpl *n; - for (n = firstChild(); n; n = n->nextSibling()) - count++; - return count; -} - -NodeImpl *NodeBaseImpl::childNode(unsigned long index) -{ - unsigned long i; - NodeImpl *n = firstChild(); - for (i = 0; n && i < index; i++) - n = n->nextSibling(); - return n; -} - -void NodeBaseImpl::dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode ) -{ - if (getDocument()->hasListenerType(DocumentImpl::DOMNODEINSERTED_LISTENER)) { - MutationEventImpl* const evt = new MutationEventImpl(EventImpl::DOMNODEINSERTED_EVENT,true,false,this,DOMString(),DOMString(),DOMString(),0); - evt->ref(); - child->dispatchEvent(evt,exceptioncode,true); - evt->deref(); - if (exceptioncode) - return; - } - - // dispatch the DOMNodeInsertedIntoDocument event to all descendants - bool hasInsertedListeners = getDocument()->hasListenerType(DocumentImpl::DOMNODEINSERTEDINTODOCUMENT_LISTENER); - NodeImpl *p = this; - while (p->parentNode()) - p = p->parentNode(); - if (p->nodeType() == Node::DOCUMENT_NODE) { - for (NodeImpl *c = child; c; c = c->traverseNextNode(child)) { - c->insertedIntoDocument(); - - if (hasInsertedListeners) { - MutationEventImpl* const evt = new MutationEventImpl(EventImpl::DOMNODEINSERTEDINTODOCUMENT_EVENT,false,false,0,DOMString(),DOMString(),DOMString(),0); - evt->ref(); - c->dispatchEvent(evt,exceptioncode,true); - evt->deref(); - if (exceptioncode) - return; - } - } - } -} - -void NodeBaseImpl::dispatchChildRemovalEvents( NodeImpl *child, int &exceptioncode ) -{ - // Dispatch pre-removal mutation events - getDocument()->notifyBeforeNodeRemoval(child); // ### use events instead - if (getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER)) { - MutationEventImpl* const evt = new MutationEventImpl(EventImpl::DOMNODEREMOVED_EVENT,true,false,this,DOMString(),DOMString(),DOMString(),0); - evt->ref(); - child->dispatchEvent(evt,exceptioncode,true); - evt->deref(); - if (exceptioncode) - return; - } - - bool hasRemovalListeners = getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVEDFROMDOCUMENT_LISTENER); - - // dispatch the DOMNodeRemovedFromDocument event to all descendants - NodeImpl *p = this; - while (p->parentNode()) - p = p->parentNode(); - if (p->nodeType() == Node::DOCUMENT_NODE) { - for (NodeImpl *c = child; c; c = c->traverseNextNode(child)) { - if (hasRemovalListeners) { - MutationEventImpl* const evt = new MutationEventImpl(EventImpl::DOMNODEREMOVEDFROMDOCUMENT_EVENT,false,false,0,DOMString(),DOMString(),DOMString(),0); - evt->ref(); - c->dispatchEvent(evt,exceptioncode,true); - evt->deref(); - if (exceptioncode) - return; - } - } - } -} - -void NodeBaseImpl::setTextContent( const DOMString &text, int& exceptioncode ) -{ - // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. - if (isReadOnly()) { - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return; - } - - removeChildren(); - - if ( !text.isEmpty() && !text.isNull() ) { - TextImpl *t = new TextImpl( docPtr(), text.implementation() ); - appendChild( t, exceptioncode ); - } -} - -// --------------------------------------------------------------------------- -NodeImpl *NodeListImpl::item( unsigned long index ) const -{ - unsigned long requestIndex = index; - - m_cache->updateNodeListInfo(m_refNode->getDocument()); - - NodeImpl* n; - bool usedCache = false; - if (m_cache->current.node) { - //Compute distance from the requested index to the cache node - long cacheDist = QABS(long(index) - long(m_cache->position)); - - if (cacheDist < (long)index) { //Closer to the cached position - usedCache = true; - if (index >= m_cache->position) { //Go ahead - unsigned long relIndex = index - m_cache->position; - n = recursiveItem(m_refNode, m_cache->current.node, relIndex); - } else { //Go backwards - unsigned long relIndex = m_cache->position - index; - n = recursiveItemBack(m_refNode, m_cache->current.node, relIndex); - } - } - } - - if (!usedCache) - n = recursiveItem(m_refNode, m_refNode->firstChild(), index); - - //We always update the cache state, to make starting iteration - //where it was left off easy. - m_cache->current.node = n; - m_cache->position = requestIndex; - return n; -} - -unsigned long NodeListImpl::length() const -{ - m_cache->updateNodeListInfo(m_refNode->getDocument()); - if (!m_cache->hasLength) { - m_cache->length = calcLength( m_refNode ); - m_cache->hasLength = true; - } - return m_cache->length; -} - -unsigned long NodeListImpl::calcLength(NodeImpl *start) const -{ - unsigned long len = 0; - for(NodeImpl *n = start->firstChild(); n != 0; n = n->nextSibling()) { - bool recurse = true; - if (nodeMatches(n, recurse)) - len++; - if (recurse) - len+= NodeListImpl::calcLength(n); - } - - return len; -} - -NodeListImpl::NodeListImpl( NodeImpl *n, int type, CacheFactory* factory ) -{ - m_refNode = n; - m_refNode->ref(); - - m_cache = m_refNode->getDocument()->acquireCachedNodeListInfo( - factory ? factory : Cache::make, - n, type ); -} - -NodeListImpl::~NodeListImpl() -{ - m_refNode->getDocument()->releaseCachedNodeListInfo(m_cache); - m_refNode->deref(); -} - - -/** - Next item in the pre-order walk of tree from node, but not going outside - absStart -*/ -static NodeImpl* helperNext(NodeImpl* node, NodeImpl* absStart) -{ - //Walk up until we wind a sibling to go to. - while (!node->nextSibling() && node != absStart) - node = node->parentNode(); - - if (node != absStart) - return node->nextSibling(); - else - return 0; -} - -NodeImpl *NodeListImpl::recursiveItem ( NodeImpl* absStart, NodeImpl *start, unsigned long &offset ) const -{ - for(NodeImpl *n = start; n != 0; n = helperNext(n, absStart)) { - bool recurse = true; - if (nodeMatches(n, recurse)) - if (!offset--) - return n; - - NodeImpl *depthSearch = recurse ? recursiveItem(n, n->firstChild(), offset) : 0; - if (depthSearch) - return depthSearch; - } - - return 0; // no matching node in this subtree -} - - -NodeImpl *NodeListImpl::recursiveItemBack ( NodeImpl* absStart, NodeImpl *start, unsigned long &offset ) const -{ - //### it might be cleaner/faster to split nodeMatches and recursion - //filtering. - bool dummy = true; - NodeImpl* n = start; - - do { - bool recurse = true; - - //Check whether the current node matches. - if (nodeMatches(n, dummy)) - if (!offset--) - return n; - - if (n->previousSibling()) { - //Move to the last node of this whole subtree that we should recurse into - n = n->previousSibling(); - recurse = true; - - while (n->lastChild()) { - (void)nodeMatches(n, recurse); - if (!recurse) - break; //Don't go there - n = n->lastChild(); - } - } else { - //We're done with this whole subtree, so move up - n = n->parentNode(); - } - } - while (n && n != absStart); - - return 0; -} - - -NodeListImpl::Cache::~Cache() -{} - -void NodeListImpl::Cache::clear(DocumentImpl* doc) -{ - hasLength = false; - current.node = 0; - version = doc->domTreeVersion(); -} - -void NodeListImpl::Cache::updateNodeListInfo(DocumentImpl* doc) -{ - //If version doesn't match, clear - if (doc->domTreeVersion() != version) - clear(doc); -} - -ChildNodeListImpl::ChildNodeListImpl( NodeImpl *n ): NodeListImpl(n, CHILD_NODES) -{} - -bool ChildNodeListImpl::nodeMatches( NodeImpl* /*testNode*/, bool& doRecurse ) const -{ - doRecurse = false; - return true; -} - -TagNodeListImpl::TagNodeListImpl( NodeImpl *n, NodeImpl::Id id ) - : NodeListImpl(n, UNCACHEABLE), - m_id(id), - m_namespaceAware(false) -{ - // An id of 0 here means "*" (match all nodes) - m_matchAllNames = (id == 0); - m_matchAllNamespaces = false; -} - -TagNodeListImpl::TagNodeListImpl( NodeImpl *n, const DOMString &namespaceURI, const DOMString &localName ) - : NodeListImpl(n, UNCACHEABLE), - m_id(0), - m_namespaceURI(namespaceURI), - m_localName(localName), - m_namespaceAware(true) -{ - m_matchAllNames = (localName == "*"); - m_matchAllNamespaces = (namespaceURI == "*"); -} - - -bool TagNodeListImpl::nodeMatches( NodeImpl *testNode, bool& /*doRecurse*/ ) const -{ - if ( testNode->nodeType() != Node::ELEMENT_NODE ) return false; - if (m_namespaceAware) - return (m_matchAllNamespaces || testNode->namespaceURI() == m_namespaceURI) && - (m_matchAllNames || testNode->localName() == m_localName); - else { - NodeImpl::Id testId = testNode->id(); - //we have to strip the namespaces if we compare in a namespace unaware fashion - if ( !m_namespaceAware ) testId = localNamePart(testId); - return (m_id == 0 || m_id == testId); - } -} - -NameNodeListImpl::NameNodeListImpl(NodeImpl *n, const DOMString &t ) - : NodeListImpl(n, UNCACHEABLE), - nodeName(t) -{} - -bool NameNodeListImpl::nodeMatches( NodeImpl *testNode, bool& /*doRecurse*/ ) const -{ - if ( testNode->nodeType() != Node::ELEMENT_NODE ) return false; - return static_cast<ElementImpl *>(testNode)->getAttribute(ATTR_NAME) == nodeName; -} - -// --------------------------------------------------------------------------- - -NamedNodeMapImpl::NamedNodeMapImpl() -{ -} - -NamedNodeMapImpl::~NamedNodeMapImpl() -{ -} - -// ---------------------------------------------------------------------------- - -GenericRONamedNodeMapImpl::GenericRONamedNodeMapImpl(DocumentImpl* doc) - : NamedNodeMapImpl() -{ - m_doc = doc; - m_contents = new TQPtrList<NodeImpl>; -} - -GenericRONamedNodeMapImpl::~GenericRONamedNodeMapImpl() -{ - while (!m_contents->isEmpty()) - m_contents->take(0)->deref(); - - delete m_contents; -} - -NodeImpl *GenericRONamedNodeMapImpl::getNamedItem ( NodeImpl::Id id, bool /*nsAware*/, DOMStringImpl* /*qName*/ ) const -{ - // ## do we need namespace support in this class? - TQPtrListIterator<NodeImpl> it(*m_contents); - for (; it.current(); ++it) - if (it.current()->id() == id) - return it.current(); - return 0; -} - -Node GenericRONamedNodeMapImpl::setNamedItem ( NodeImpl* /*arg*/, bool /*nsAware*/, DOMStringImpl* /*qName*/, int &exceptioncode ) -{ - // can't modify this list through standard DOM functions - // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return 0; -} - -Node GenericRONamedNodeMapImpl::removeNamedItem ( NodeImpl::Id /*id*/, bool /*nsAware*/, DOMStringImpl* /*qName*/, int &exceptioncode ) -{ - // can't modify this list through standard DOM functions - // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly - exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; - return 0; -} - -NodeImpl *GenericRONamedNodeMapImpl::item ( unsigned long index ) const -{ - if (index >= m_contents->count()) - return 0; - - return m_contents->at(index); -} - -unsigned long GenericRONamedNodeMapImpl::length( ) const -{ - return m_contents->count(); -} - -void GenericRONamedNodeMapImpl::addNode(NodeImpl *n) -{ - // The spec says that in the case of duplicates we only keep the first one - if (getNamedItem(n->id(), false, 0)) - return; - - n->ref(); - m_contents->append(n); -} - -NodeImpl::Id GenericRONamedNodeMapImpl::mapId(DOMStringImpl* namespaceURI, - DOMStringImpl* localName, bool readonly) -{ - if (!m_doc) - return 0; - - return m_doc->getId(NodeImpl::ElementId, - namespaceURI, 0, localName, readonly, - false /*don't lookupHTML*/); -} - -// ----------------------------------------------------------------------------- - -void RegisteredListenerList::addEventListener(int id, EventListener *listener, const bool useCapture) -{ - RegisteredEventListener rl(static_cast<EventImpl::EventId>(id),listener,useCapture); - if (!listeners) - listeners = new TQValueList<RegisteredEventListener>; - - // if this id/listener/useCapture combination is already registered, do nothing. - // the DOM2 spec says that "duplicate instances are discarded", and this keeps - // the listener order intact. - TQValueList<RegisteredEventListener>::iterator it; - for (it = listeners->begin(); it != listeners->end(); ++it) - if (*it == rl) - return; - - listeners->append(rl); -} - -void RegisteredListenerList::removeEventListener(int id, EventListener *listener, bool useCapture) -{ - if (!listeners) // nothing to remove - return; - - RegisteredEventListener rl(static_cast<EventImpl::EventId>(id),listener,useCapture); - - TQValueList<RegisteredEventListener>::iterator it; - for (it = listeners->begin(); it != listeners->end(); ++it) - if (*it == rl) { - listeners->remove(it); - return; - } -} - -bool RegisteredListenerList::isHTMLEventListener(EventListener* listener) -{ - return (listener->eventListenerType() == "_khtml_HTMLEventListener"); -} - -void RegisteredListenerList::setHTMLEventListener(int id, EventListener *listener) -{ - if (!listeners) - listeners = new TQValueList<RegisteredEventListener>; - - TQValueList<RegisteredEventListener>::iterator it; - if (!listener) { - for (it = listeners->begin(); it != listeners->end(); ++it) { - if ((*it).id == id && isHTMLEventListener((*it).listener)) { - listeners->remove(it); - break; - } - } - return; - } - - // if this event already has a registered handler, insert the new one in - // place of the old one, to preserve the order. - RegisteredEventListener rl(static_cast<EventImpl::EventId>(id),listener,false); - - int i; - for (i = 0, it = listeners->begin(); it != listeners->end(); ++it, ++i) - if ((*it).id == id && isHTMLEventListener((*it).listener)) { - listeners->insert(it, rl); - listeners->remove(it); - return; - } - - listeners->append(rl); -} - -EventListener *RegisteredListenerList::getHTMLEventListener(int id) -{ - if (!listeners) - return 0; - - TQValueList<RegisteredEventListener>::iterator it; - for (it = listeners->begin(); it != listeners->end(); ++it) - if ((*it).id == id && isHTMLEventListener((*it).listener)) { - return (*it).listener; - } - return 0; -} - -bool RegisteredListenerList::hasEventListener(int id) -{ - if (!listeners) - return false; - - TQValueList<RegisteredEventListener>::iterator it; - for (it = listeners->begin(); it != listeners->end(); ++it) - if ((*it).id == id) - return true; - - return false; -} - -void RegisteredListenerList::clear() -{ - delete listeners; - listeners = 0; -} - -bool RegisteredListenerList::stillContainsListener(const RegisteredEventListener& listener) -{ - if (!listeners) - return false; - return listeners->find(listener) != listeners->end(); -} - -RegisteredListenerList::~RegisteredListenerList() { - delete listeners; listeners = 0; -} diff --git a/khtml/xml/dom_nodeimpl.h b/khtml/xml/dom_nodeimpl.h deleted file mode 100644 index 275452d69..000000000 --- a/khtml/xml/dom_nodeimpl.h +++ /dev/null @@ -1,736 +0,0 @@ -/* - * 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) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * (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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef _DOM_NodeImpl_h_ -#define _DOM_NodeImpl_h_ - -#include "dom/dom_misc.h" -#include "dom/dom_string.h" -#include "dom/dom_node.h" -#include "misc/helper.h" -#include "misc/shared.h" - -// The namespace used for XHTML elements -#define XHTML_NAMESPACE "http://www.w3.org/1999/xhtml" - -class TQPainter; -template <class type> class TQPtrList; -template <class type> class TQValueList; -class KHTMLView; -class TQRect; -class TQMouseEvent; -class TQKeyEvent; -class TQTextStream; - -namespace khtml { - class RenderStyle; - class RenderObject; - class RenderArena; -} - -namespace DOM { - -class NodeListImpl; -class NamedNodeMapImpl; -class DocumentImpl; -class CSSStyleDeclarationImpl; -class RegisteredEventListener; -class EventImpl; - -struct RegisteredListenerList { - RegisteredListenerList() : listeners(0) - {} - - ~RegisteredListenerList(); - - void addEventListener(int id, EventListener *listener, const bool useCapture); - void removeEventListener(int id, EventListener *listener, bool useCapture); - - void setHTMLEventListener(int id, EventListener *listener); - EventListener *getHTMLEventListener(int id); - - bool hasEventListener(int id); - void clear(); - - //### KDE4: should disappear - bool stillContainsListener(const RegisteredEventListener& listener); - - TQValueList<RegisteredEventListener>* listeners;//The actual listener list - may be 0 -private: - bool isHTMLEventListener(EventListener* listener); -}; - - -// this class implements nodes, which can have a parent but no children: -#define NodeImpl_IdNSMask 0xffff0000 -#define NodeImpl_IdLocalMask 0x0000ffff - -const TQ_UINT16 defaultNamespace = 0; -const TQ_UINT16 xhtmlNamespace = 1; -const TQ_UINT16 emptyNamespace = 2; -const TQ_UINT16 anyNamespace = 0xffff; -const TQ_UINT16 anyLocalName = 0xffff; - -inline TQ_UINT16 localNamePart(TQ_UINT32 id) { return id & NodeImpl_IdLocalMask; } -inline TQ_UINT16 namespacePart(TQ_UINT32 id) { return (((unsigned int)id) & NodeImpl_IdNSMask) >> 16; } -inline TQ_UINT32 makeId(TQ_UINT16 n, TQ_UINT16 l) { return (n << 16) | l; } - -const TQ_UINT32 anyQName = makeId(anyNamespace, anyLocalName); - -class NodeImpl : public khtml::TreeShared<NodeImpl> -{ - friend class DocumentImpl; -public: - NodeImpl(DocumentImpl *doc); - virtual ~NodeImpl(); - - // DOM methods & attributes for Node - virtual DOMString nodeName() const; - virtual DOMString nodeValue() const; - virtual void setNodeValue( const DOMString &_nodeValue, int &exceptioncode ); - virtual unsigned short nodeType() const; - NodeImpl *parentNode() const { return m_parent; } - NodeImpl *previousSibling() const { return m_previous; } - NodeImpl *nextSibling() const { return m_next; } - virtual NodeListImpl *childNodes(); - virtual NodeImpl *firstChild() const; - virtual NodeImpl *lastChild() const; - // insertBefore, replaceChild and appendChild also close newChild - // unlike the speed optimized addChild (which is used by the parser) - virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode ); - - /* These two methods may delete the old node, so make sure to reference it if you need it */ - virtual void replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode ); - virtual void removeChild ( NodeImpl *oldChild, int &exceptioncode ); - virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode ); - virtual bool hasChildNodes ( ) const; - virtual NodeImpl *cloneNode ( bool deep ) = 0; - virtual DOMString localName() const; - virtual DOMString prefix() const; - virtual DOMString namespaceURI() const; - virtual void setPrefix(const DOMString &_prefix, int &exceptioncode ); - void normalize (); - - // Other methods (not part of DOM) - virtual bool isElementNode() const { return false; } - virtual bool isHTMLElement() const { return false; } - virtual bool isAttributeNode() const { return false; } - virtual bool isTextNode() const { return false; } - virtual bool isDocumentNode() const { return false; } - virtual bool isXMLElementNode() const { return false; } - virtual bool isGenericFormElement() const { return false; } - virtual bool containsOnlyWhitespace() const { return false; } - virtual bool contentEditable() const; - - // helper functions not being part of the DOM - // Attention: they assume that the caller did the consistency checking! - void setPreviousSibling(NodeImpl *previous) { m_previous = previous; } - void setNextSibling(NodeImpl *next) { m_next = next; } - - virtual void setFirstChild(NodeImpl *child); - virtual void setLastChild(NodeImpl *child); - - // used by the parser. Doesn't do as many error checkings as - // appendChild(), and returns the node into which will be parsed next. - virtual NodeImpl *addChild(NodeImpl *newChild); - - typedef TQ_UINT32 Id; - // id() is used to easily and exactly identify a node. It - // is optimized for quick comparison and low memory consumption. - // its value depends on the owner document of the node and is - // categorized in the following way: - // 1..ID_LAST_TAG: the node inherits HTMLElementImpl and is - // part of the HTML namespace. - // The HTML namespace is either the global - // one (no namespace) or the XHTML namespace - // depending on the owner document's doctype - // ID_LAST_TAG+1..0xffff: non-HTML elements in the global namespace - // others non-HTML elements in a namespace. - // the upper 16 bit identify the namespace - // the lower 16 bit identify the local part of the - // qualified element name. - virtual Id id() const { return 0; } - - // These are the DOM 3 Core answer to innerText/setInnerText, and are used - // quite a bit since Mozilla doesn't do innerText. They do, however, behave slightly - // differently. The default implementation is for ELEMENT_NODE, ATTRIBUTE_NODE, - // ENTITY_NODE, ENTITY_REFERENCE_NODE, DOCUMENT_FRAGMENT_NODE. - virtual DOMStringImpl* textContent() const; - virtual void setTextContent( const DOMString &text, int& exceptioncode ) = 0; - - enum IdType { - AttributeId, - ElementId, - NamespaceId - }; - - enum MouseEventType { - MousePress, - MouseRelease, - MouseClick, - MouseDblClick, - MouseMove - }; - - struct MouseEvent - { - MouseEvent( int _button, MouseEventType _type, - const DOMString &_url = DOMString(), const DOMString& _target = DOMString(), - NodeImpl *_innerNode = 0, NodeImpl *_innerNonSharedNode = 0) - { - button = _button; type = _type; - url = _url; target = _target; - innerNode = _innerNode; - innerNonSharedNode = _innerNonSharedNode; - } - - int button; - MouseEventType type; - DOMString url; // url under mouse or empty - DOMString target; - Node innerNode; - Node innerNonSharedNode; - }; - - // for LINK and STYLE - virtual void sheetLoaded() {} - - bool hasID() const { return m_hasId; } - bool hasClass() const { return m_hasClass; } - bool active() const { return m_active; } - bool focused() const { return m_focused; } - bool hovered() const { return m_hovered; } - bool attached() const { return m_attached; } - bool closed() const { return m_closed; } - bool changed() const { return m_changed; } - bool hasChangedChild() const { return m_hasChangedChild; } - bool hasAnchor() const { return m_hasAnchor; } - bool inDocument() const { return m_inDocument; } - bool implicitNode() const { return m_implicit; } - bool htmlCompat() const { return m_htmlCompat; } - void setHasID(bool b=true) { m_hasId = b; } - void setHasClass(bool b=true) { m_hasClass = b; } - void setHasChangedChild( bool b = true ) { m_hasChangedChild = b; } - void setInDocument(bool b=true) { m_inDocument = b; } - void setHTMLCompat(bool b) { m_htmlCompat = b; } - virtual void setFocus(bool b=true) { m_focused = b; } - virtual void setActive(bool b=true) { m_active = b; } - virtual void setHovered(bool b=true) { m_hovered = b; } - virtual void setChanged(bool b=true); - - // for descending restyle when ID or CLASS changes - bool changedAscendentAttribute() const { return m_changedAscendentAttribute; } - void setChangedAscendentAttribute(bool b) { m_changedAscendentAttribute = b; } - - // for style selection performance: whether the element matches several CSS Classes - bool hasClassList() const { return m_hasClassList; } - void setHasClassList(bool b) { m_hasClassList = b; } - - unsigned short tabIndex() const { return m_tabIndex; } - void setTabIndex(unsigned short _tabIndex) { m_tabIndex = _tabIndex; } - - virtual bool isFocusable() const { return false; } - virtual bool isMouseFocusable() const { return isFocusable(); } - virtual bool isTabFocusable() const { return isFocusable(); } - - virtual bool isInline() const; - - virtual void getCaret(int offset, bool override, int &_x, int &_y, int &width, int &height); - virtual TQRect getRect() const; - - enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force }; - virtual void recalcStyle( StyleChange = NoChange ) {} - static StyleChange diff( khtml::RenderStyle *s1, khtml::RenderStyle *s2 ); - static bool pseudoDiff( khtml::RenderStyle *s1, khtml::RenderStyle *s2, unsigned int pid); - - unsigned long nodeIndex() const; - // Returns the document that this node is associated with. This is guaranteed to always be non-null, as opposed to - // DOM's ownerDocument() which is null for Document nodes (and sometimes DocumentType nodes). - DocumentImpl* getDocument() const { return m_document.get(); } - - void addEventListener(int id, EventListener *listener, const bool useCapture); - void removeEventListener(int id, EventListener *listener, bool useCapture); - void setHTMLEventListener(int id, EventListener *listener); - EventListener *getHTMLEventListener(int id); - - void dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent = false); - void dispatchGenericEvent( EventImpl *evt, int &exceptioncode); - // return true if event not prevented - bool dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg); - void dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg); - void dispatchMouseEvent(TQMouseEvent *e, int overrideId = 0, int overrideDetail = 0); - void dispatchUIEvent(int _id, int detail = 0); - void dispatchSubtreeModifiedEvent(); - // return true if defaultPrevented (i.e. event should be swallowed) - // this matches the logic in KHTMLView. - bool dispatchKeyEvent(TQKeyEvent *key, bool keypress); - - void handleLocalEvents(EventImpl *evt, bool useCapture); - - /** - * Perform the default action for an event e.g. submitting a form - */ - virtual void defaultEventHandler(EventImpl *evt); - - virtual bool isReadOnly(); - virtual bool childTypeAllowed( unsigned short /*type*/ ) { return false; } - virtual unsigned long childNodeCount(); - virtual NodeImpl *childNode(unsigned long index); - - /** - * Does a pre-order traversal of the tree to find the node next node after this one. This uses the same order that - * the tags appear in the source file. - * - * @param stayWithin If not null, the traversal will stop once the specified node is reached. This can be used to - * restrict traversal to a particular sub-tree. - * - * @return The next node, in document order - * - * see traversePreviousNode() - */ - NodeImpl *traverseNextNode(NodeImpl *stayWithin = 0) const; - - /** - * Does a reverse pre-order traversal to find the node that comes before the current one in document order - * - * see traverseNextNode() - */ - NodeImpl *traversePreviousNode() const; - - DocumentImpl *docPtr() const { return m_document.get(); } - - khtml::RenderObject *renderer() const { return m_render; } - khtml::RenderObject *nextRenderer(); - khtml::RenderObject *previousRenderer(); - void setRenderer(khtml::RenderObject* renderer) { m_render = renderer; } - - void checkSetPrefix(const DOMString &_prefix, int &exceptioncode); - void checkAddChild(NodeImpl *newChild, int &exceptioncode); - bool isAncestor( NodeImpl *other ); - virtual bool childAllowed( NodeImpl *newChild ); - - /** - * Returns the minimum caret offset that is allowed for this node. - * - * This default implementation always returns 0. Textual child nodes - * may return other values. - */ - virtual long minOffset() const; - /** - * Returns the maximum caret offset that is allowed for this node. - * - * This default implementation always returns the node count. - * Textual child nodes return the character count instead. - */ - virtual long maxOffset() const; - - // ----------------------------------------------------------------------------- - // Integration with rendering tree - - /** - * Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an - * appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This - * makes the node visible in the KHTMLView. - */ - virtual void attach(); - - /** - * Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove - * the node's rendering object from the rendering tree and delete it. - */ - virtual void detach(); - - /** - * Notifies the node that no more children will be added during parsing. - * After a node has been closed all changes must go through the DOM interface. - */ - virtual void close(); - - virtual void structureChanged() {}; - virtual void backwardsStructureChanged() {}; - - void createRendererIfNeeded(); - virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent); - virtual bool rendererIsNeeded(khtml::RenderStyle *); - virtual khtml::RenderObject *createRenderer(khtml::RenderArena *, khtml::RenderStyle *); - - // ----------------------------------------------------------------------------- - // Methods for maintaining the state of the element between history navigation - - /** - * Indicates whether or not this type of node maintains its state. If so, the state of the node will be stored when - * the user goes to a different page using the state() method, and restored using the restoreState() method if the - * user returns (e.g. using the back button). This is used to ensure that user-changeable elements such as form - * controls maintain their contents when the user returns to a previous page in the history. - */ - virtual bool maintainsState(); - - /** - * Returns the state of this node represented as a string. This string will be passed to restoreState() if the user - * returns to the page. - * - * @return State information about the node represented as a string - */ - virtual TQString state(); - - /** - * Sets the state of the element based on a string previosuly returned by state(). This is used to initialize form - * controls with their old values when the user returns to the page in their history. - * - * @param state A string representation of the node's previously-stored state - */ - virtual void restoreState(const TQString &state); - - // ----------------------------------------------------------------------------- - // Notification of document stucture changes - - /** - * Notifies the node that it has been inserted into the document. This is called during document parsing, and also - * when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only - * happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of - * the node. The call happens _after_ the node has been added to the tree. - * - * This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event - * dispatching. - */ - virtual void insertedIntoDocument(); - - /** - * Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor - * node. - * - * This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event - * dispatching, and is called _after_ the node is removed from the tree. - */ - virtual void removedFromDocument(); - - /** - * Notifies the node that its list of children have changed (either by adding or removing child nodes), or a child - * node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value. - */ - virtual void childrenChanged(); - - virtual DOMString toString() const = 0; - /** - * Sometimes we need to get the string between two points on the DOM graph. Use this function to do this. - * For example, when the user copies some selected text to the clipboard as html. - * @param selectionStart Where to start the selection. If selectionStart != this, it is assumed we are after the start point - * @param selectionEnd Where to end the selection. If selectionEnd != this, it is assumed we are before the end point (unless found is true) - * @param startOffset Number of characters into the text in selectionStart that the start of the selection is. - * @param endOffset Number of characters into the text in selectionEnd that the end of the selection is. - * @param found When this is set to true, don't print anymore but closing tags. - * @return An html formatted string for this node and its children between the selectionStart and selectionEnd. - */ - virtual DOMString selectionToString(NodeImpl * selectionStart, - NodeImpl * selectionEnd, - int startOffset, - int endOffset, - bool &found) const - { Q_UNUSED(selectionStart); - Q_UNUSED(selectionEnd); - Q_UNUSED(startOffset); - Q_UNUSED(endOffset); - Q_UNUSED(found); - return toString(); - } - -private: // members - khtml::DocPtr<DocumentImpl> m_document; - NodeImpl *m_previous; - NodeImpl *m_next; -protected: - khtml::RenderObject *m_render; - RegisteredListenerList m_regdListeners; - - unsigned short m_tabIndex : 15; - bool m_hasTabIndex : 1; - - bool m_hasId : 1; - bool m_attached : 1; - bool m_closed : 1; - bool m_changed : 1; - bool m_hasChangedChild : 1; - bool m_changedAscendentAttribute : 1; - bool m_inDocument : 1; - bool m_hasAnchor : 1; - bool m_specified : 1; // used in AttrImpl. Accessor functions there - - bool m_hovered : 1; - bool m_focused : 1; - bool m_active : 1; - bool m_implicit : 1; // implicitely generated by the parser - bool m_htmlCompat : 1; // true if element was created in HTML compat mode - bool m_hasClassList : 1; - bool m_hasClass : 1; // true if element has a class property, as relevant to CSS -}; - -// this is the full Node Implementation with parents and children. -class NodeBaseImpl : public NodeImpl -{ -public: - NodeBaseImpl(DocumentImpl *doc) - : NodeImpl(doc), _first(0), _last(0) {} - virtual ~NodeBaseImpl(); - - // DOM methods overridden from parent classes - virtual NodeImpl *firstChild() const; - virtual NodeImpl *lastChild() const; - virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode ); - virtual void replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode ); - virtual void removeChild ( NodeImpl *oldChild, int &exceptioncode ); - virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode ); - virtual bool hasChildNodes ( ) const; - - virtual void setTextContent( const DOMString &text, int& exceptioncode ); - - // Other methods (not part of DOM) - void removeChildren(); - void cloneChildNodes(NodeImpl *clone); - - virtual void setFirstChild(NodeImpl *child); - virtual void setLastChild(NodeImpl *child); - virtual NodeImpl *addChild(NodeImpl *newChild); - virtual void attach(); - virtual void detach(); - - - bool getUpperLeftCorner(int &xPos, int &yPos) const; - bool getLowerRightCorner(int &xPos, int &yPos) const; - - virtual void setFocus(bool=true); - virtual void setActive(bool=true); - virtual void setHovered(bool=true); - virtual unsigned long childNodeCount(); - virtual NodeImpl *childNode(unsigned long index); - -protected: - NodeImpl *_first; - NodeImpl *_last; - - // helper functions for inserting children: - - // ### this should vanish. do it in dom/ ! - // check for same source document: - bool checkSameDocument( NodeImpl *newchild, int &exceptioncode ); - // check for being child: - bool checkIsChild( NodeImpl *oldchild, int &exceptioncode ); - // ### - - // find out if a node is allowed to be our child - void dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode ); - void dispatchChildRemovalEvents( NodeImpl *child, int &exceptioncode ); -}; - -// -------------------------------------------------------------------------- -class Node; -class NodeImpl; - -class NodeListImpl : public khtml::Shared<NodeListImpl> -{ -public: - //Type of the item stored in the cache. - enum Type { - UNCACHEABLE, //Too complex to be cached like this - CHILD_NODES, - LAST_NODE_LIST = CHILD_NODES - }; - - struct CacheKey - { - NodeImpl* baseNode; - int type; - - CacheKey(): type(UNCACHEABLE) {} - - CacheKey(NodeImpl* _baseNode, int _type): - baseNode(_baseNode), type(_type) - {} - - int hash() const - { - return int(reinterpret_cast<unsigned long>(baseNode) >> 2) ^ - (unsigned(type) << 26); - } - - bool operator==(const CacheKey& other) const - { - return baseNode == other.baseNode && - type == other.type; - } - }; - - struct Cache: public khtml::Shared<Cache> - { - static Cache* make() { return new Cache; } - - CacheKey key;//### We must store this in here due to TQCache in Qt3 sucking - - unsigned int version; - union - { - NodeImpl* node; - unsigned int index; - } current; - unsigned int position; - unsigned int length; - bool hasLength; - - void updateNodeListInfo(DocumentImpl* doc); - - virtual void clear(DocumentImpl* doc); - virtual ~Cache(); - }; - - typedef Cache* CacheFactory(); - - NodeListImpl(NodeImpl* node, int type, CacheFactory* factory = 0); - virtual ~NodeListImpl(); - - // DOM methods & attributes for NodeList - virtual unsigned long length() const; - virtual NodeImpl *item ( unsigned long index ) const; - - // Other methods (not part of DOM) - -protected: - virtual unsigned long calcLength(NodeImpl *start) const; - // helper functions for searching all ElementImpls in a tree - - NodeImpl *recursiveItem ( NodeImpl* absStart, NodeImpl *start, unsigned long &offset ) const; - NodeImpl *recursiveItemBack( NodeImpl* absStart, NodeImpl *start, unsigned long &offset ) const; - - // Override this to determine what nodes to return. Set doRecurse to - // false if the children of this node do not need to be entered. - virtual bool nodeMatches( NodeImpl *testNode, bool& doRecurse ) const = 0; - - NodeImpl* m_refNode; - mutable Cache* m_cache; -}; - -class ChildNodeListImpl : public NodeListImpl -{ -public: - - ChildNodeListImpl( NodeImpl *n); - -protected: - virtual bool nodeMatches( NodeImpl *testNode, bool& doRecurse ) const; -}; - - -/** - * NodeList which lists all Nodes in a document with a given tag name - */ -class TagNodeListImpl : public NodeListImpl -{ -public: - TagNodeListImpl( NodeImpl *n, NodeImpl::Id id ); - TagNodeListImpl( NodeImpl *n, const DOMString &namespaceURI, const DOMString &localName ); - - // Other methods (not part of DOM) - -protected: - virtual bool nodeMatches( NodeImpl *testNode, bool& doRecurse ) const; - NodeImpl::Id m_id; - DOMString m_namespaceURI; - DOMString m_localName; - - bool m_matchAllNames; - bool m_matchAllNamespaces; - bool m_namespaceAware; -}; - - -/** - * NodeList which lists all Nodes in a Element with a given "name=" tag - */ -class NameNodeListImpl : public NodeListImpl -{ -public: - NameNodeListImpl( NodeImpl *doc, const DOMString &t ); - - // Other methods (not part of DOM) - -protected: - virtual bool nodeMatches( NodeImpl *testNode, bool& doRecurse ) const; - - DOMString nodeName; -}; - -// Generic NamedNodeMap interface -// Other classes implement this for more specific situations e.g. attributes -// of an element -class NamedNodeMapImpl : public khtml::Shared<NamedNodeMapImpl> -{ -public: - NamedNodeMapImpl(); - virtual ~NamedNodeMapImpl(); - - // DOM methods & attributes for NamedNodeMap - virtual NodeImpl *getNamedItem ( NodeImpl::Id id, bool nsAware = false, DOMStringImpl* qName = 0 ) const = 0; - virtual Node removeNamedItem ( NodeImpl::Id id, bool nsAware, DOMStringImpl* qName, int &exceptioncode ) = 0; - virtual Node setNamedItem ( NodeImpl* arg, bool nsAware, DOMStringImpl* qName, int &exceptioncode ) = 0; - - virtual NodeImpl *item ( unsigned long index ) const = 0; - virtual unsigned long length( ) const = 0; - - // Other methods (not part of DOM) - virtual NodeImpl::Id mapId(DOMStringImpl* namespaceURI, - DOMStringImpl* localName, bool readonly) = 0; - virtual bool isReadOnly() { return false; } -}; - -// Generic read-only NamedNodeMap implementation -// Used for e.g. entities and notations in DocumentType. -// You can add nodes using addNode -class GenericRONamedNodeMapImpl : public NamedNodeMapImpl -{ -public: - GenericRONamedNodeMapImpl(DocumentImpl* doc); - virtual ~GenericRONamedNodeMapImpl(); - - // DOM methods & attributes for NamedNodeMap - - virtual NodeImpl *getNamedItem ( NodeImpl::Id id, bool nsAware = false, DOMStringImpl* qName = 0 ) const; - virtual Node removeNamedItem ( NodeImpl::Id id, bool nsAware, DOMStringImpl* qName, int &exceptioncode ); - virtual Node setNamedItem ( NodeImpl* arg, bool nsAware, DOMStringImpl* qName, int &exceptioncode ); - - virtual NodeImpl *item ( unsigned long index ) const; - virtual unsigned long length( ) const; - - // Other methods (not part of DOM) - virtual NodeImpl::Id mapId(DOMStringImpl* namespaceURI, - DOMStringImpl* localName, bool readonly); - - virtual bool isReadOnly() { return true; } - - void addNode(NodeImpl *n); - -protected: - DocumentImpl* m_doc; - TQPtrList<NodeImpl> *m_contents; -}; - -} //namespace -#endif diff --git a/khtml/xml/dom_restyler.cpp b/khtml/xml/dom_restyler.cpp deleted file mode 100644 index 0050c4a03..000000000 --- a/khtml/xml/dom_restyler.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "dom_restyler.h" -#include "dom_elementimpl.h" - -namespace khtml { - -DynamicDomRestyler::DynamicDomRestyler() -{ -} - -void DynamicDomRestyler::addDependency(ElementImpl* subject, ElementImpl* dependency, StructuralDependencyType type) -{ - assert(type < LastStructuralDependency); - - dependency_map[type].append(dependency, subject); - reverse_map.append(subject,dependency); -} - -void DynamicDomRestyler::removeDependency(ElementImpl* subject, ElementImpl* dependency, StructuralDependencyType type) -{ - dependency_map[type].remove(dependency, subject); - // don't remove from reverse_map as there might be other depencies to the same element -} - -void DynamicDomRestyler::removeDependencies(ElementImpl* subject, StructuralDependencyType type) -{ - KMultiMap<ElementImpl>::List* my_dependencies = reverse_map.find(subject); - - if (!my_dependencies) return; - - for (my_dependencies->first(); my_dependencies->current() ; my_dependencies->next()) - { - ElementImpl* e = my_dependencies->current(); - dependency_map[type].remove(e,subject); - } - - // don't remove from reverse_map as there might be other depencies to the same elements -} - -void DynamicDomRestyler::resetDependencies(ElementImpl* subject) -{ - KMultiMap<ElementImpl>::List* my_dependencies = reverse_map.find(subject); - - if (!my_dependencies) return; - - for (my_dependencies->first(); my_dependencies->current() ; my_dependencies->next()) - { - ElementImpl* e = my_dependencies->current(); - for (int type = 0; type < LastStructuralDependency; type++) { - dependency_map[type].remove(e,subject); - } - } - - reverse_map.remove(subject); -} - -void DynamicDomRestyler::restyleDepedent(ElementImpl* dependency, StructuralDependencyType type) -{ - assert(type < LastStructuralDependency); - KMultiMap<ElementImpl>::List* dep = dependency_map[type].find(dependency); - - if (!dep) return; - - // take copy as the restyle will change the list - KMultiMap<ElementImpl>::List dependent(*dep); - - for (dependent.first(); dependent.current() ; dependent.next()) - { -// kdDebug() << "Restyling dependent" << endl; - dependent.current()->setChanged(true); - } -} - -void DynamicDomRestyler::dumpStats() const -{ -/* - kdDebug() << "Keys in structural dependencies: " << dependency_map[StructuralDependency].size() << endl; - kdDebug() << "Keys in attribute dependencies: " << dependency_map[AttributeDependency].size() << endl; - - kdDebug() << "Keys in reverse map: " << reverse_map.size() << endl; - */ -} - -void DynamicDomRestyler::addDependency(uint attrID, AttributeDependencyType type) -{ - assert(type < LastAttributeDependency); - - unsigned int hash = (attrID * 257) % 512; - attribute_map[type][hash] = true; -} - -bool DynamicDomRestyler::checkDependency(uint attrID, AttributeDependencyType type) -{ - assert(type < LastAttributeDependency); - - unsigned int hash = (attrID * 257) % 512; - // ### gives false positives, but that's okay. - return attribute_map[type][hash]; -} - -} // namespace diff --git a/khtml/xml/dom_restyler.h b/khtml/xml/dom_restyler.h deleted file mode 100644 index eb8d795d5..000000000 --- a/khtml/xml/dom_restyler.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _DOM_restyler_h_ -#define _DOM_restyler_h_ - -#include "misc/multimap.h" -#include <bitset> - -namespace DOM { - class ElementImpl; -} - -// Restyle dependency tracker for dynamic DOM - -namespace khtml { - -using DOM::ElementImpl; - -// These types are different types of dependencies, and serves to identify which element should be -// restyled when a change of that kind triggers on the element -enum StructuralDependencyType { - // Style relies on the children of the element (unaffected by append & close) - StructuralDependency = 0, - // Style relies on the last children of the element (affected by append & close) - BackwardsStructuralDependency = 1, - // Style relies on the element having hover - HoverDependency = 2, - // Style relies on the element being active - ActiveDependency = 3, - // Style relies on another state of element (focus, disabled, checked, etc.) - // (focus is special cased though since elements always depend on their own focus) - OtherStateDependency = 4, - LastStructuralDependency -}; - -// Attribute dependencies are much coarser than structural, for memory reasons rather than performance -// This tracks global depencies of various kinds. -// The groups are separated into where possible depending elements might be: -enum AttributeDependencyType { - // Style of the changed element depend on this attribute - PersonalDependency = 0, - // Style of the elements children depend on this attribute - AncestorDependency = 1, - // Style of the elements later siblings or their children depend on this attribute - PredecessorDependency = 2, - LastAttributeDependency -}; - - -/** - * @internal - */ -class DynamicDomRestyler { -public: - DynamicDomRestyler(); - - // Structural dependencies are tracked from element to subject - void addDependency(ElementImpl* subject, ElementImpl* dependency, StructuralDependencyType type); - void resetDependencies(ElementImpl* subject); - void removeDependency(ElementImpl* subject, ElementImpl* dependency, StructuralDependencyType type); - void removeDependencies(ElementImpl* subject, StructuralDependencyType type); - void restyleDepedent(ElementImpl* dependency, StructuralDependencyType type); - - // Attribute dependencies are traced on attribute alone - void addDependency(uint attrID, AttributeDependencyType type); - bool checkDependency(uint attrID, AttributeDependencyType type); - - void dumpStats() const; -private: - // Map of dependencies. - KMultiMap<ElementImpl> dependency_map[LastStructuralDependency]; - // Map of reverse dependencies. For fast reset - KMultiMap<ElementImpl> reverse_map; - - // Map of the various attribute dependencies - std::bitset<512> attribute_map[LastAttributeDependency]; -}; - -} - -#endif - diff --git a/khtml/xml/dom_stringimpl.cpp b/khtml/xml/dom_stringimpl.cpp deleted file mode 100644 index 79bddf5d9..000000000 --- a/khtml/xml/dom_stringimpl.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2001-2003 Dirk Mueller ( mueller@kde.org ) - * (C) 2002 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "dom_stringimpl.h" - -#include <kdebug.h> - -#include <string.h> -#include <tqstringlist.h> - -using namespace DOM; -using namespace khtml; - - -DOMStringImpl::DOMStringImpl(const char *str) -{ - if(str && *str) - { - l = strlen(str); - s = QT_ALLOC_QCHAR_VEC( l ); - int i = l; - TQChar* ptr = s; - while( i-- ) - *ptr++ = *str++; - } - else - { - s = QT_ALLOC_QCHAR_VEC( 1 ); // crash protection - s[0] = 0x0; // == TQChar::null; - l = 0; - } -} - -// FIXME: should be a cached flag maybe. -bool DOMStringImpl::containsOnlyWhitespace() const -{ - if (!s) - return true; - - for (uint i = 0; i < l; i++) { - TQChar c = s[i]; - if (c.unicode() <= 0x7F) { - if (c.unicode() > ' ') - return false; - } else { - if (c.direction() != TQChar::DirWS) - return false; - } - } - return true; -} - - -void DOMStringImpl::append(DOMStringImpl *str) -{ - if(str && str->l != 0) - { - int newlen = l+str->l; - TQChar *c = QT_ALLOC_QCHAR_VEC(newlen); - memcpy(c, s, l*sizeof(TQChar)); - memcpy(c+l, str->s, str->l*sizeof(TQChar)); - if(s) QT_DELETE_QCHAR_VEC(s); - s = c; - l = newlen; - } -} - -void DOMStringImpl::insert(DOMStringImpl *str, unsigned int pos) -{ - if(pos > l) - { - append(str); - return; - } - if(str && str->l != 0) - { - int newlen = l+str->l; - TQChar *c = QT_ALLOC_QCHAR_VEC(newlen); - memcpy(c, s, pos*sizeof(TQChar)); - memcpy(c+pos, str->s, str->l*sizeof(TQChar)); - memcpy(c+pos+str->l, s+pos, (l-pos)*sizeof(TQChar)); - if(s) QT_DELETE_QCHAR_VEC(s); - s = c; - l = newlen; - } -} - -void DOMStringImpl::truncate(int len) -{ - if(len > (int)l) return; - - int nl = len < 1 ? 1 : len; - TQChar *c = QT_ALLOC_QCHAR_VEC(nl); - memcpy(c, s, nl*sizeof(TQChar)); - if(s) QT_DELETE_QCHAR_VEC(s); - s = c; - l = len; -} - -void DOMStringImpl::remove(unsigned int pos, int len) -{ - if(pos >= l ) return; - if(pos+len > l) - len = l - pos; - - uint newLen = l-len; - TQChar *c = QT_ALLOC_QCHAR_VEC(newLen); - memcpy(c, s, pos*sizeof(TQChar)); - memcpy(c+pos, s+pos+len, (l-len-pos)*sizeof(TQChar)); - if(s) QT_DELETE_QCHAR_VEC(s); - s = c; - l = newLen; -} - -DOMStringImpl *DOMStringImpl::split(unsigned int pos) -{ - if( pos >=l ) return new DOMStringImpl(); - - uint newLen = l-pos; - DOMStringImpl *str = new DOMStringImpl(s + pos, newLen); - truncate(pos); - return str; -} - -DOMStringImpl *DOMStringImpl::substring(unsigned int pos, unsigned int len) -{ - if( pos >=l ) return new DOMStringImpl(); - if(pos+len > l) - len = l - pos; - - return new DOMStringImpl(s + pos, len); -} - -// Collapses white-space according to CSS 2.1 rules -DOMStringImpl *DOMStringImpl::collapseWhiteSpace(bool preserveLF, bool preserveWS) -{ - if (preserveLF && preserveWS) return this; - - // Notice we are likely allocating more space than needed (worst case) - TQChar *n = QT_ALLOC_QCHAR_VEC(l); - - unsigned int pos = 0; - bool collapsing = false; // collapsing white-space - bool collapsingLF = false; // collapsing around linefeed - bool changedLF = false; - for(unsigned int i=0; i<l; i++) { - TQChar ch = s[i]; - - // We act on \r as we would on \n because CSS uses it to indicate new-line - if (ch == '\r') ch = '\n'; - else - // ### The XML parser lets \t through, for now treat them as spaces - if (ch == '\t') ch = ' '; - - if (!preserveLF && ch == '\n') { - // ### Not strictly correct according to CSS3 text-module. - // - In ideographic languages linefeed should be ignored - // - and in Thai and Khmer it should be treated as a zero-width space - ch = ' '; // Treat as space - changedLF = true; - } - - if (collapsing) { - if (ch == ' ') - continue; - if (ch == '\n') { - collapsingLF = true; - continue; - } - - n[pos++] = (collapsingLF) ? '\n' : ' '; - collapsing = false; - collapsingLF = false; - } - else - if (!preserveWS && ch == ' ') { - collapsing = true; - continue; - } - else - if (!preserveWS && ch == '\n') { - collapsing = true; - collapsingLF = true; - continue; - } - - n[pos++] = ch; - } - if (collapsing) - n[pos++] = ((collapsingLF) ? '\n' : ' '); - - if (pos == l && !changedLF) { - QT_DELETE_QCHAR_VEC(n); - return this; - } - else { - DOMStringImpl* out = new DOMStringImpl(); - out->s = n; - out->l = pos; - - return out; - } -} - -static Length parseLength(const TQChar *s, unsigned int l) -{ - if (l == 0) { - return Length(1, Relative); - } - - unsigned i = 0; - while (i < l && s[i].isSpace()) - ++i; - if (i < l && (s[i] == '+' || s[i] == '-')) - ++i; - while (i < l && s[i].isDigit()) - ++i; - - bool ok; - int r = TQConstString(s, i).string().toInt(&ok); - - /* Skip over any remaining digits, we are not that accurate (5.5% => 5%) */ - while (i < l && (s[i].isDigit() || s[i] == '.')) - ++i; - - /* IE Quirk: Skip any whitespace (20 % => 20%) */ - while (i < l && s[i].isSpace()) - ++i; - - if (ok) { - if (i == l) { - return Length(r, Fixed); - } else { - const TQChar* next = s+i; - - if (*next == '%') - return Length(r, Percent); - - if (*next == '*') - return Length(r, Relative); - } - return Length(r, Fixed); - } else { - if (i < l) { - const TQChar* next = s+i; - - if (*next == '*') - return Length(1, Relative); - - if (*next == '%') - return Length(1, Relative); - } - } - return Length(0, Relative); -} - -khtml::Length* DOMStringImpl::toCoordsArray(int& len) const -{ - TQString str(s, l); - for(unsigned int i=0; i < l; i++) { - TQChar cc = s[i]; - if (cc > TQChar('9') || (cc < TQChar('0') && cc != '-' && cc != '*' && cc != '.')) - str[i] = ' '; - } - str = str.simplifyWhiteSpace(); - - len = str.contains(' ') + 1; - khtml::Length* r = new khtml::Length[len]; - - int i = 0; - int pos = 0; - int pos2; - - while((pos2 = str.find(' ', pos)) != -1) { - r[i++] = parseLength((TQChar *) str.unicode()+pos, pos2-pos); - pos = pos2+1; - } - r[i] = parseLength((TQChar *) str.unicode()+pos, str.length()-pos); - - return r; -} - -khtml::Length* DOMStringImpl::toLengthArray(int& len) const -{ - TQString str(s, l); - str = str.simplifyWhiteSpace(); - - len = str.contains(',') + 1; - - // If we have no commas, we have no array. - if( len == 1 ) - return 0L; - - khtml::Length* r = new khtml::Length[len]; - - int i = 0; - int pos = 0; - int pos2; - - while((pos2 = str.find(',', pos)) != -1) { - r[i++] = parseLength((TQChar *) str.unicode()+pos, pos2-pos); - pos = pos2+1; - } - - /* IE Quirk: If the last comma is the last char skip it and reduce len by one */ - if (str.length()-pos > 0) - r[i] = parseLength((TQChar *) str.unicode()+pos, str.length()-pos); - else - len--; - - return r; -} - -bool DOMStringImpl::isLower() const -{ - unsigned int i; - for (i = 0; i < l; i++) - if (s[i].lower() != s[i]) - return false; - return true; -} - -DOMStringImpl *DOMStringImpl::lower() const -{ - DOMStringImpl *c = new DOMStringImpl; - if(!l) return c; - - c->s = QT_ALLOC_QCHAR_VEC(l); - c->l = l; - - for (unsigned int i = 0; i < l; i++) - c->s[i] = s[i].lower(); - - return c; -} - -DOMStringImpl *DOMStringImpl::upper() const -{ - DOMStringImpl *c = new DOMStringImpl; - if(!l) return c; - - c->s = QT_ALLOC_QCHAR_VEC(l); - c->l = l; - - for (unsigned int i = 0; i < l; i++) - c->s[i] = s[i].upper(); - - return c; -} - -DOMStringImpl *DOMStringImpl::capitalize(bool noFirstCap) const -{ - bool canCapitalize= !noFirstCap; - DOMStringImpl *c = new DOMStringImpl; - if(!l) return c; - - c->s = QT_ALLOC_QCHAR_VEC(l); - c->l = l; - - for (unsigned int i=0; i<l; i++) - { - if (s[i].isLetterOrNumber() && canCapitalize) - { - c->s[i]=s[i].upper(); - canCapitalize=false; - } - else - { - c->s[i]=s[i]; - if (s[i].isSpace()) - canCapitalize=true; - } - } - - return c; -} - -TQString DOMStringImpl::string() const -{ - return TQString(s, l); -} - -int DOMStringImpl::toInt(bool* ok) const -{ - // match \s*[+-]?\d* - unsigned i = 0; - while (i < l && s[i].isSpace()) - ++i; - if (i < l && (s[i] == '+' || s[i] == '-')) - ++i; - while (i < l && s[i].isDigit()) - ++i; - - return TQConstString(s, i).string().toInt(ok); -} - -static const unsigned short amp[] = {'&', 'a', 'm', 'p', ';'}; -static const unsigned short lt[] = {'&', 'l', 't', ';'}; -static const unsigned short gt[] = {'&', 'g', 't', ';'}; - -DOMStringImpl *DOMStringImpl::escapeHTML() -{ - unsigned outL = 0; - for (unsigned int i = 0; i < l; ++i ) { - if ( s[i] == '&' ) - outL += 5; //& - else if (s[i] == '<' || s[i] == '>') - outL += 4; //>/< - else - ++outL; - } - if (outL == l) - return this; - - - DOMStringImpl* toRet = new DOMStringImpl(); - toRet->s = QT_ALLOC_QCHAR_VEC(outL); - toRet->l = outL; - - unsigned outP = 0; - for (unsigned int i = 0; i < l; ++i ) { - if ( s[i] == '&' ) { - memcpy(&toRet->s[outP], amp, sizeof(amp)); - outP += 5; - } else if (s[i] == '<') { - memcpy(&toRet->s[outP], lt, sizeof(lt)); - outP += 4; - } else if (s[i] == '>') { - memcpy(&toRet->s[outP], gt, sizeof(gt)); - outP += 4; - } else { - toRet->s[outP] = s[i]; - ++outP; - } - } - return toRet; -} - diff --git a/khtml/xml/dom_stringimpl.h b/khtml/xml/dom_stringimpl.h deleted file mode 100644 index cd7128967..000000000 --- a/khtml/xml/dom_stringimpl.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2003 Dirk Mueller (mueller@kde.org) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef _DOM_DOMStringImpl_h_ -#define _DOM_DOMStringImpl_h_ - -#include <tqstring.h> - -#include "dom/dom_misc.h" -#include "misc/khtmllayout.h" -#include "misc/shared.h" - -#define QT_ALLOC_QCHAR_VEC( N ) (TQChar*) new char[ sizeof(TQChar)*( N ) ] -#define QT_DELETE_QCHAR_VEC( P ) delete[] ((char*)( P )) - -namespace DOM { - -class DOMStringImpl : public khtml::Shared<DOMStringImpl> -{ -private: - DOMStringImpl(const DOMStringImpl&); - DOMStringImpl& operator=(const DOMStringImpl&); -protected: - DOMStringImpl() { s = 0, l = 0; } -public: - DOMStringImpl(const TQChar *str, unsigned int len) { - bool havestr = str && len; - s = QT_ALLOC_QCHAR_VEC( havestr ? len : 1 ); - if(str && len) { - memcpy( s, str, len * sizeof(TQChar) ); - l = len; - } else { - // crash protection - s[0] = 0x0; - l = 0; - } - } - - explicit DOMStringImpl(const char *str); - explicit DOMStringImpl(const TQChar &ch) { - s = QT_ALLOC_QCHAR_VEC( 1 ); - s[0] = ch; - l = 1; - } - ~DOMStringImpl() { - if(s) QT_DELETE_QCHAR_VEC(s); - } - - void append(DOMStringImpl *str); - void insert(DOMStringImpl *str, unsigned int pos); - void truncate(int len); - void remove(unsigned int pos, int len=1); - DOMStringImpl *split(unsigned int pos); - DOMStringImpl *copy() const { - return new DOMStringImpl(s,l); - }; - - - DOMStringImpl *substring(unsigned int pos, unsigned int len); - DOMStringImpl *collapseWhiteSpace(bool preserveLF, bool preserveWS); - - const TQChar &operator [] (int pos) { return s[pos]; } - bool containsOnlyWhitespace() const; - - // ignores trailing garbage, unlike QString - int toInt(bool* ok = 0) const; - - khtml::Length* toLengthArray(int& len) const; - khtml::Length* toCoordsArray(int& len) const; - bool isLower() const; - DOMStringImpl *lower() const; - DOMStringImpl *upper() const; - DOMStringImpl *capitalize(bool noFirstCap=false) const; - DOMStringImpl *escapeHTML(); - - TQChar *unicode() const { return s; } - uint length() const { return l; } - TQString string() const; - - unsigned int l; - TQChar *s; -}; - -} -#endif diff --git a/khtml/xml/dom_textimpl.cpp b/khtml/xml/dom_textimpl.cpp deleted file mode 100644 index 86317293d..000000000 --- a/khtml/xml/dom_textimpl.cpp +++ /dev/null @@ -1,522 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 2001-2003 Dirk Mueller (mueller@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2002-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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, 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 "rendering/render_flow.h" - -#include <kdebug.h> - -using namespace DOM; -using namespace khtml; - -static DOMString escapeHTML( const DOMString& in ) -{ - return in.implementation()->escapeHTML(); -} - -CharacterDataImpl::CharacterDataImpl(DocumentImpl *doc, DOMStringImpl* _text) - : NodeImpl(doc) -{ - str = _text ? _text : new DOMStringImpl(0, 0); - str->ref(); -} - -CharacterDataImpl::~CharacterDataImpl() -{ - if(str) str->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(); -} - -unsigned long CharacterDataImpl::length() const -{ - return str->l; -} - -DOMString CharacterDataImpl::substringData( 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 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))->setText(str); - setChanged(true); - - 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))->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(); -} - -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(); -} - -DOMString CharacterDataImpl::nodeValue() const -{ - return str; -} - -bool CharacterDataImpl::containsOnlyWhitespace() const -{ - return str->containsOnlyWhitespace(); -} - -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; - 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::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::minOffset() const -{ - RenderText *r = static_cast<RenderText *>(renderer()); - if (!r || !r->isText()) return 0; - - // take :first-letter into consideration -#ifdef __GNUC__ -#warning FIXME -#endif -#if 0 - if (r->forcedMinOffset()) { - RenderFlow *firstLetter = static_cast<RenderFlow *>(r->previousSibling()); - if (firstLetter && firstLetter->isFlow() && firstLetter->isFirstLetter()) { - RenderText *letterText = static_cast<RenderText *>(firstLetter->firstChild()); - return letterText->minOffset(); - } - } -#endif - - return r->minOffset(); -} - -long CharacterDataImpl::maxOffset() const -{ - RenderText *r = static_cast<RenderText *>(renderer()); - if (!r || !r->isText()) return (long)length(); - return r->maxOffset(); -} - -DOMStringImpl* CharacterDataImpl::textContent() const -{ - return new DOMStringImpl(str->s, str->l); -} - -void CharacterDataImpl::setTextContent( const DOMString &str, int& exceptioncode ) -{ - setData(str, exceptioncode); -} - -// --------------------------------------------------------------------------- - -DOMString CommentImpl::nodeName() const -{ - return "#comment"; -} - -unsigned short CommentImpl::nodeType() const -{ - return Node::COMMENT_NODE; -} - -NodeImpl *CommentImpl::cloneNode(bool /*deep*/) -{ - return getDocument()->createComment( str ); -} - -NodeImpl::Id CommentImpl::id() const -{ - return ID_COMMENT; -} - -// DOM Section 1.1.1 -bool CommentImpl::childTypeAllowed( unsigned short /*type*/ ) -{ - return false; -} - -DOMString CommentImpl::toString() const -{ - // FIXME: substitute entity references as needed! - return DOMString("<!--") + escapeHTML( nodeValue() ) + "-->"; -} - -// --------------------------------------------------------------------------- - -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; -} - -DOMString TextImpl::nodeName() const -{ - return "#text"; -} - -unsigned short TextImpl::nodeType() const -{ - return Node::TEXT_NODE; -} - -NodeImpl *TextImpl::cloneNode(bool /*deep*/) -{ - return getDocument()->createTextNode(str); -} - -bool TextImpl::rendererIsNeeded(RenderStyle *style) -{ - if (!CharacterDataImpl::rendererIsNeeded(style)) { - return false; - } - bool onlyWS = containsOnlyWhitespace(); - if (!onlyWS) { - return true; - } - - RenderObject *par = parentNode()->renderer(); - - if (par->isTable() || par->isTableRow() || par->isTableSection()) { - return false; - } - - if (style->preserveWS() || style->preserveLF()) { - return true; - } - - RenderObject *prev = previousRenderer(); - if (par->isInlineFlow()) { - // <span><div/> <div/></span> - if (prev && !prev->isInline()) { - return false; - } - } else { - if (par->isRenderBlock() && !par->childrenInline() && (!prev || !prev->isInline())) { - return false; - } - - RenderObject *first = par->firstChild(); - while (first && first->isFloatingOrPositioned()) - first = first->nextSibling(); - RenderObject *next = nextRenderer(); - if (!first || next == first) { - // Whitespace at the start of a block just goes away. Don't even - // make a render object for this text. - return false; - } - } - - return true; -} - -RenderObject *TextImpl::createRenderer(RenderArena *arena, RenderStyle *style) -{ - return new (arena) RenderText(this, str); -} - -void TextImpl::attach() -{ - createRendererIfNeeded(); - CharacterDataImpl::attach(); -} - -NodeImpl::Id TextImpl::id() const -{ - return ID_TEXT; -} - -void TextImpl::recalcStyle( StyleChange change ) -{ -// tqDebug("textImpl::recalcStyle"); - // Create renderer if now needed - if ( changed() && !m_render) { - createRendererIfNeeded(); - } - if (change != NoChange && parentNode()) { -// tqDebug("DomText::recalcStyle"); - if(m_render) - m_render->setStyle(parentNode()->renderer()->style()); - } - if ( changed() && m_render && m_render->isText() ) - static_cast<RenderText*>(m_render)->setText(str); - setChanged( false ); -} - -// DOM Section 1.1.1 -bool TextImpl::childTypeAllowed( unsigned short /*type*/ ) -{ - return false; -} - -TextImpl *TextImpl::createNew(DOMStringImpl *_str) -{ - return new TextImpl(docPtr(),_str); -} - -DOMStringImpl* TextImpl::renderString() const -{ - if (renderer()) - return static_cast<RenderText*>(renderer())->string(); - else - return string(); -} - -DOMString TextImpl::toString() const -{ - // FIXME: substitute entity references as needed! - return escapeHTML( nodeValue() ); -} - -DOMString TextImpl::toString(long long startOffset, long long endOffset) const -{ - // FIXME: substitute entity references as needed! - - DOMString str = nodeValue(); - if(endOffset >=0 || startOffset >0) - str = str.copy(); //we are going to modify this, so make a copy. I hope I'm doing this right. - if(endOffset >= 0) - str.truncate(endOffset); - if(startOffset > 0) //note the order of these 2 'if' statements so that it works right when n==m_startContainer==m_endContainer - str.remove(0, startOffset); - return escapeHTML( str ); -} - -// --------------------------------------------------------------------------- - -DOMString CDATASectionImpl::nodeName() const -{ - return "#cdata-section"; -} - -unsigned short CDATASectionImpl::nodeType() const -{ - return Node::CDATA_SECTION_NODE; -} - -NodeImpl *CDATASectionImpl::cloneNode(bool /*deep*/) -{ - return getDocument()->createCDATASection(str); -} - -// DOM Section 1.1.1 -bool CDATASectionImpl::childTypeAllowed( unsigned short /*type*/ ) -{ - return false; -} - -TextImpl *CDATASectionImpl::createNew(DOMStringImpl *_str) -{ - return new CDATASectionImpl(docPtr(),_str); -} - -DOMString CDATASectionImpl::toString() const -{ - // FIXME: substitute entity references as needed! - return DOMString("<![CDATA[") + nodeValue() + "]]>"; -} - - - diff --git a/khtml/xml/dom_textimpl.h b/khtml/xml/dom_textimpl.h deleted file mode 100644 index 07e4909f6..000000000 --- a/khtml/xml/dom_textimpl.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 2001-2003 Dirk Mueller (mueller@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef _DOM_CharacterDataImpl_h_ -#define _DOM_CharacterDataImpl_h_ - -#include "xml/dom_nodeimpl.h" -#include "dom/dom_string.h" - -namespace DOM { - - class DocumentImpl; - class CharacterData; - class Text; - -class CharacterDataImpl : public NodeImpl -{ -public: - CharacterDataImpl(DocumentImpl *doc, DOMStringImpl* _text); - CharacterDataImpl(DocumentImpl *doc) - : NodeImpl(doc), str(0) {} - - virtual ~CharacterDataImpl(); - - // DOM methods & attributes for CharacterData - - virtual void setData( const DOMString &_data, int &exceptioncode ); - virtual unsigned long length ( ) const; - virtual DOMString substringData ( const unsigned long offset, const unsigned long count, int &exceptioncode ); - virtual void appendData ( const DOMString &arg, int &exceptioncode ); - virtual void insertData ( const unsigned long offset, const DOMString &arg, int &exceptioncode ); - virtual void deleteData ( const unsigned long offset, const unsigned long count, int &exceptioncode ); - virtual void replaceData ( const unsigned long offset, const unsigned long count, const DOMString &arg, int &exceptioncode ); - - virtual bool containsOnlyWhitespace() const; - - // DOM methods overridden from parent classes - - virtual DOMString nodeValue() const; - virtual void setNodeValue( const DOMString &_nodeValue, int &exceptioncode ); - - virtual DOMStringImpl* textContent() const; - virtual void setTextContent( const DOMString &text, int& exceptioncode ); - - // Other methods (not part of DOM) - - DOMStringImpl *string() const { return str; } - DOMString data() const { return str; } - - virtual void checkCharDataOperation( const unsigned long offset, int &exceptioncode ); - - virtual long minOffset() const; - virtual long maxOffset() const; - -protected: - // note: since DOMStrings are shared, str should always be copied when making - // a change or returning a string - DOMStringImpl *str; - - void dispatchModifiedEvent(DOMStringImpl *prevValue); -}; - -// ---------------------------------------------------------------------------- - -class CommentImpl : public CharacterDataImpl -{ -public: - CommentImpl(DocumentImpl *doc, DOMStringImpl* _text) - : CharacterDataImpl(doc, _text) {} - CommentImpl(DocumentImpl *doc) - : CharacterDataImpl(doc) {} - // DOM methods overridden from parent classes - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual NodeImpl *cloneNode(bool deep); - - // Other methods (not part of DOM) - - virtual Id id() const; - virtual bool childTypeAllowed( unsigned short type ); - - virtual DOMString toString() const; -}; - -// ---------------------------------------------------------------------------- - -class TextImpl : public CharacterDataImpl -{ -public: - TextImpl(DocumentImpl *impl, DOMStringImpl* _text) - : CharacterDataImpl(impl, _text) {} - TextImpl(DocumentImpl *impl) - : CharacterDataImpl(impl) {} - - // DOM methods & attributes for CharacterData - - TextImpl *splitText ( const unsigned long offset, int &exceptioncode ); - - // DOM methods overridden from parent classes - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual NodeImpl *cloneNode(bool deep); - - // Other methods (not part of DOM) - - virtual bool isTextNode() const { return true; } - virtual Id id() const; - virtual void attach(); - virtual bool rendererIsNeeded(khtml::RenderStyle *); - virtual khtml::RenderObject *createRenderer(khtml::RenderArena *, khtml::RenderStyle *); - virtual void recalcStyle( StyleChange = NoChange ); - virtual bool childTypeAllowed( unsigned short type ); - - DOMStringImpl *renderString() const; - - virtual DOMString toString() const; - /** Return the text for the node, with < replaced with < and so on. - * @param startOffset The number of characters counted from the left, zero indexed, counting "<" as one character, to start from. Use -1 to start from 0. - * @param endOffset The number of characters counted from the left, zero indexed, counting "<" as one character, to end on. Use -1 to end at the end of the string. - * @return An html escaped version of the substring. - */ - DOMString toString(long long startOffset, long long endOffset) const; -protected: - virtual TextImpl *createNew(DOMStringImpl *_str); -}; - -// ---------------------------------------------------------------------------- - -class CDATASectionImpl : public TextImpl -{ -public: - CDATASectionImpl(DocumentImpl *impl, DOMStringImpl* _text) - : TextImpl(impl, _text) {} - CDATASectionImpl(DocumentImpl *impl) - : TextImpl(impl) {} - - // DOM methods overridden from parent classes - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual NodeImpl *cloneNode(bool deep); - - // Other methods (not part of DOM) - - virtual bool childTypeAllowed( unsigned short type ); - - virtual DOMString toString() const; - -protected: - virtual TextImpl *createNew(DOMStringImpl *_str); -}; - - - -} //namespace -#endif diff --git a/khtml/xml/dom_xmlimpl.cpp b/khtml/xml/dom_xmlimpl.cpp deleted file mode 100644 index 121ad436a..000000000 --- a/khtml/xml/dom_xmlimpl.cpp +++ /dev/null @@ -1,498 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2000 Peter Kelly (pmk@post.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "dom/dom_exception.h" - -#include "xml/dom_xmlimpl.h" -#include "xml/dom_docimpl.h" -#include "xml/dom_stringimpl.h" -#include "css/css_stylesheetimpl.h" -#include "misc/loader.h" - -using namespace DOM; - -EntityImpl::EntityImpl(DocumentImpl *doc) : NodeBaseImpl(doc) -{ - m_publicId = 0; - m_systemId = 0; - m_notationName = 0; - m_name = 0; -} - -EntityImpl::EntityImpl(DocumentImpl *doc, DOMString _name) : NodeBaseImpl(doc) -{ - m_publicId = 0; - m_systemId = 0; - m_notationName = 0; - m_name = _name.implementation(); - if (m_name) - m_name->ref(); -} - -EntityImpl::EntityImpl(DocumentImpl *doc, DOMString _publicId, DOMString _systemId, DOMString _notationName) : NodeBaseImpl(doc) -{ - m_publicId = _publicId.implementation(); - if (m_publicId) - m_publicId->ref(); - m_systemId = _systemId.implementation(); - if (m_systemId) - m_systemId->ref(); - m_notationName = _notationName.implementation(); - if (m_notationName) - m_notationName->ref(); - m_name = 0; -} - - -EntityImpl::~EntityImpl() -{ - if (m_publicId) - m_publicId->deref(); - if (m_systemId) - m_systemId->deref(); - if (m_notationName) - m_notationName->deref(); - if (m_name) - m_name->deref(); -} - -DOMString EntityImpl::publicId() const -{ - return m_publicId; -} - -DOMString EntityImpl::systemId() const -{ - return m_systemId; -} - -DOMString EntityImpl::notationName() const -{ - return m_notationName; -} - -DOMString EntityImpl::nodeName() const -{ - return m_name; -} - -unsigned short EntityImpl::nodeType() const -{ - return Node::ENTITY_NODE; -} - -NodeImpl *EntityImpl::cloneNode ( bool /*deep*/) -{ - // Spec says cloning Document nodes is "implementation dependent" - // so we do not support it... - return 0; -} - -// DOM Section 1.1.1 -bool EntityImpl::childTypeAllowed( unsigned short type ) -{ - switch (type) { - case Node::ELEMENT_NODE: - case Node::PROCESSING_INSTRUCTION_NODE: - case Node::COMMENT_NODE: - case Node::TEXT_NODE: - case Node::CDATA_SECTION_NODE: - case Node::ENTITY_REFERENCE_NODE: - return true; - break; - default: - return false; - } -} - -DOMString EntityImpl::toString() const -{ - DOMString result = "<!ENTITY' "; - - if (m_name && m_name->l != 0) { - result += " "; - result += m_name; - } - - if (m_publicId && m_publicId->l != 0) { - result += " PUBLIC \""; - result += m_publicId; - result += "\" \""; - result += m_systemId; - result += "\""; - } else if (m_systemId && m_systemId->l != 0) { - result += " SYSTEM \""; - result += m_systemId; - result += "\""; - } - - if (m_notationName && m_notationName->l != 0) { - result += " NDATA "; - result += m_notationName; - } - - result += ">"; - - return result; -} - -// ------------------------------------------------------------------------- - -EntityReferenceImpl::EntityReferenceImpl(DocumentImpl *doc) : NodeBaseImpl(doc) -{ - m_entityName = 0; -} - -EntityReferenceImpl::EntityReferenceImpl(DocumentImpl *doc, DOMStringImpl *_entityName) : NodeBaseImpl(doc) -{ - m_entityName = _entityName; - if (m_entityName) - m_entityName->ref(); -} - -EntityReferenceImpl::~EntityReferenceImpl() -{ - if (m_entityName) - m_entityName->deref(); -} - -DOMString EntityReferenceImpl::nodeName() const -{ - return m_entityName; -} - -unsigned short EntityReferenceImpl::nodeType() const -{ - return Node::ENTITY_REFERENCE_NODE; -} - -NodeImpl *EntityReferenceImpl::cloneNode ( bool deep ) -{ - EntityReferenceImpl *clone = new EntityReferenceImpl(docPtr(),m_entityName); - // ### make sure children are readonly - // ### since we are a reference, should we clone children anyway (even if not deep?) - if (deep) - cloneChildNodes(clone); - return clone; -} - -// DOM Section 1.1.1 -bool EntityReferenceImpl::childTypeAllowed( unsigned short type ) -{ - switch (type) { - case Node::ELEMENT_NODE: - case Node::PROCESSING_INSTRUCTION_NODE: - case Node::COMMENT_NODE: - case Node::TEXT_NODE: - case Node::CDATA_SECTION_NODE: - case Node::ENTITY_REFERENCE_NODE: - return true; - break; - default: - return false; - } -} - -DOMString EntityReferenceImpl::toString() const -{ - DOMString result = "&"; - result += m_entityName; - result += ";"; - - return result; -} - -// ------------------------------------------------------------------------- - -NotationImpl::NotationImpl(DocumentImpl *doc) : NodeBaseImpl(doc) -{ - m_publicId = 0; - m_systemId = 0; - m_name = 0; -} - -NotationImpl::NotationImpl(DocumentImpl *doc, DOMString _name, DOMString _publicId, DOMString _systemId) : NodeBaseImpl(doc) -{ - m_name = _name.implementation(); - if (m_name) - m_name->ref(); - m_publicId = _publicId.implementation(); - if (m_publicId) - m_publicId->ref(); - m_systemId = _systemId.implementation(); - if (m_systemId) - m_systemId->ref(); -} - -NotationImpl::~NotationImpl() -{ - if (m_name) - m_name->deref(); - if (m_publicId) - m_publicId->deref(); - if (m_systemId) - m_systemId->deref(); -} - -DOMString NotationImpl::publicId() const -{ - return m_publicId; -} - -DOMString NotationImpl::systemId() const -{ - return m_systemId; -} - -DOMString NotationImpl::nodeName() const -{ - return m_name; -} - -unsigned short NotationImpl::nodeType() const -{ - return Node::NOTATION_NODE; -} - -NodeImpl *NotationImpl::cloneNode ( bool /*deep*/) -{ - // Spec says cloning Document nodes is "implementation dependent" - // so we do not support it... - return 0; -} - -// DOM Section 1.1.1 -bool NotationImpl::childTypeAllowed( unsigned short /*type*/ ) -{ - return false; -} - -// ------------------------------------------------------------------------- - -// ### need a way of updating these properly whenever child nodes of the processing instruction -// change or are added/removed - -ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImpl *doc) : NodeBaseImpl(doc) -{ - m_target = 0; - m_data = 0; - m_localHref = 0; - m_sheet = 0; - m_cachedSheet = 0; -} - -ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImpl *doc, DOMString _target, DOMString _data) : NodeBaseImpl(doc) -{ - m_target = _target.implementation(); - if (m_target) - m_target->ref(); - m_data = _data.implementation(); - if (m_data) - m_data->ref(); - m_sheet = 0; - m_cachedSheet = 0; - m_localHref = 0; -} - -ProcessingInstructionImpl::~ProcessingInstructionImpl() -{ - if (m_target) - m_target->deref(); - if (m_data) - m_data->deref(); - if (m_cachedSheet) - m_cachedSheet->deref(this); - if (m_sheet) - m_sheet->deref(); -} - -DOMString ProcessingInstructionImpl::target() const -{ - return m_target; -} - -void ProcessingInstructionImpl::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 (m_data) - m_data->deref(); - m_data = _data.implementation(); - if (m_data) - m_data->ref(); -} - -DOMString ProcessingInstructionImpl::nodeName() const -{ - return m_target; -} - -unsigned short ProcessingInstructionImpl::nodeType() const -{ - return Node::PROCESSING_INSTRUCTION_NODE; -} - -DOMString ProcessingInstructionImpl::nodeValue() const -{ - return m_data; -} - -void ProcessingInstructionImpl::setNodeValue( const DOMString &_nodeValue, int &exceptioncode ) -{ - // NO_MODIFICATION_ALLOWED_ERR: taken care of by setData() - setData(_nodeValue, exceptioncode); -} - -NodeImpl *ProcessingInstructionImpl::cloneNode ( bool /*deep*/) -{ - // ### copy m_localHref - return new ProcessingInstructionImpl(docPtr(),m_target,m_data); -} - -DOMString ProcessingInstructionImpl::localHref() const -{ - return m_localHref; -} - -// DOM Section 1.1.1 -bool ProcessingInstructionImpl::childTypeAllowed( unsigned short /*type*/ ) -{ - return false; -} - -void ProcessingInstructionImpl::checkStyleSheet() -{ - if (m_target && DOMString(m_target) == "xml-stylesheet") { - // see http://www.w3.org/TR/xml-stylesheet/ - // ### check that this occurs only in the prolog - // ### support stylesheet included in a fragment of this (or another) document - // ### make sure this gets called when adding from javascript - XMLAttributeReader attrReader(DOMString(m_data).string()); - bool attrsOk; - TQXmlAttributes attrs = attrReader.readAttrs(attrsOk); - if (!attrsOk) - return; - if (attrs.value("type") != "text/css" && !attrs.value("type").isEmpty()) - return; - - DOMString href = attrs.value("href"); - - if (href.length()>1) - { - if (href[0]=='#') - { - if (m_localHref) - m_localHref->deref(); - m_localHref=href.implementation()->split(1); - if (m_localHref) - m_localHref->ref(); - } - else - { - // ### some validation on the URL? - // ### FIXME charset - if (m_cachedSheet) m_cachedSheet->deref(this); - m_cachedSheet = getDocument()->docLoader()->requestStyleSheet(getDocument()->completeURL(href.string()), TQString::null); - if (m_cachedSheet) { - getDocument()->addPendingSheet(); //before ref, because during the ref it might load! - m_cachedSheet->ref( this ); - } - } - - } - } -} - -StyleSheetImpl *ProcessingInstructionImpl::sheet() const -{ - return m_sheet; -} - -void ProcessingInstructionImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset) -{ - if (m_sheet) - m_sheet->deref(); - m_sheet = new CSSStyleSheetImpl(getDocument(), url); - m_sheet->ref(); - m_sheet->setCharset(charset); - m_sheet->parseString(sheet); - if (m_cachedSheet) - m_cachedSheet->deref(this); - m_cachedSheet = 0; - - getDocument()->styleSheetLoaded(); -} - -void ProcessingInstructionImpl::setStyleSheet(CSSStyleSheetImpl* sheet) -{ - if (m_sheet) - m_sheet->deref(); - m_sheet = sheet; - if (m_sheet) - m_sheet->ref(); -} - -DOMString ProcessingInstructionImpl::toString() const -{ - DOMString result = "<?"; - result += m_target; - result += " "; - result += m_data; - result += ">"; - return result; -} - -// ------------------------------------------------------------------------- - -XMLAttributeReader::XMLAttributeReader(const TQString& _attrString) -{ - m_attrString = _attrString; -} - -XMLAttributeReader::~XMLAttributeReader() -{ -} - -TQXmlAttributes XMLAttributeReader::readAttrs(bool &ok) -{ - // parse xml file - TQXmlInputSource source; - source.setData("<?xml version=\"1.0\"?><attrs "+m_attrString+" />"); - TQXmlSimpleReader reader; - reader.setContentHandler( this ); - ok = reader.parse( source ); - return attrs; -} - -bool XMLAttributeReader::startElement(const TQString& /*namespaceURI*/, const TQString& localName, - const TQString& /*qName*/, const TQXmlAttributes& atts) -{ - if (localName == "attrs") { - attrs = atts; - return true; - } - else - return false; // we shouldn't have any other elements -} diff --git a/khtml/xml/dom_xmlimpl.h b/khtml/xml/dom_xmlimpl.h deleted file mode 100644 index d88dc041f..000000000 --- a/khtml/xml/dom_xmlimpl.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2000 Peter Kelly (pmk@post.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _DOM_XmlImpl_h_ -#define _DOM_XmlImpl_h_ - -#include "xml/dom_nodeimpl.h" -#include "misc/loader_client.h" - -#include <tqxml.h> - -namespace khtml { -class CachedCSSStyleSheet; -} - -namespace DOM { - -class DocumentImpl; -class CSSStyleSheetImpl; -class StyleSheetImpl; -class DOMString; - -class EntityImpl : public NodeBaseImpl -{ -public: - EntityImpl(DocumentImpl *doc); - EntityImpl(DocumentImpl *doc, DOMString _name); - EntityImpl(DocumentImpl *doc, DOMString _publicId, DOMString _systemId, DOMString _notationName); - virtual ~EntityImpl(); - - // DOM methods & attributes for Entity - - virtual DOMString publicId() const; - virtual DOMString systemId() const; - virtual DOMString notationName() const; - - // DOM methods overridden from parent classes - - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual NodeImpl *cloneNode ( bool deep ); - - // Other methods (not part of DOM) - - virtual bool childTypeAllowed( unsigned short type ); - - virtual DOMString toString() const; - -protected: - DOMStringImpl *m_publicId; - DOMStringImpl *m_systemId; - DOMStringImpl *m_notationName; - DOMStringImpl *m_name; -}; - - -class EntityReferenceImpl : public NodeBaseImpl -{ -public: - EntityReferenceImpl(DocumentImpl *doc); - EntityReferenceImpl(DocumentImpl *doc, DOMStringImpl *_entityName); - virtual ~EntityReferenceImpl(); - - // DOM methods overridden from parent classes - - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual NodeImpl *cloneNode ( bool deep ); - - // Other methods (not part of DOM) - - virtual bool childTypeAllowed( unsigned short type ); - - virtual DOMString toString() const; -protected: - DOMStringImpl *m_entityName; -}; - -class NotationImpl : public NodeBaseImpl -{ -public: - NotationImpl(DocumentImpl *doc); - NotationImpl(DocumentImpl *doc, DOMString _name, DOMString _publicId, DOMString _systemId); - virtual ~NotationImpl(); - - // DOM methods & attributes for Notation - - virtual DOMString publicId() const; - virtual DOMString systemId() const; - - // DOM methods overridden from parent classes - - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual NodeImpl *cloneNode ( bool deep ); - - // Other methods (not part of DOM) - - virtual bool childTypeAllowed( unsigned short type ); -protected: - DOMStringImpl *m_name; - DOMStringImpl *m_publicId; - DOMStringImpl *m_systemId; -}; - - -class ProcessingInstructionImpl : public NodeBaseImpl, private khtml::CachedObjectClient -{ -public: - ProcessingInstructionImpl(DocumentImpl *doc); - ProcessingInstructionImpl(DocumentImpl *doc, DOMString _target, DOMString _data); - virtual ~ProcessingInstructionImpl(); - - // DOM methods & attributes for Notation - - virtual DOMString target() const; - DOMString data() const { return m_data; } - virtual void setData( const DOMString &_data, int &exceptioncode ); - - // DOM methods overridden from parent classes - - virtual DOMString nodeName() const; - virtual unsigned short nodeType() const; - virtual DOMString nodeValue() const; - virtual void setNodeValue( const DOMString &_nodeValue, int &exceptioncode ); - virtual NodeImpl *cloneNode ( bool deep ); - - // Other methods (not part of DOM) - - virtual DOMString localHref() const; - virtual bool childTypeAllowed( unsigned short type ); - StyleSheetImpl *sheet() const; - void checkStyleSheet(); - virtual void setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset); - virtual void setStyleSheet(CSSStyleSheetImpl* sheet); - - virtual DOMString toString() const; - -protected: - DOMStringImpl *m_target; - DOMStringImpl *m_data; - DOMStringImpl *m_localHref; - khtml::CachedCSSStyleSheet *m_cachedSheet; - CSSStyleSheetImpl *m_sheet; -}; - -class XMLAttributeReader : public TQXmlDefaultHandler -{ -public: - XMLAttributeReader(const TQString& _attrString); - virtual ~XMLAttributeReader(); - TQXmlAttributes readAttrs(bool &ok); - bool startElement(const TQString& namespaceURI, const TQString& localName, const TQString& qName, const TQXmlAttributes& atts); - -protected: - TQXmlAttributes attrs; - TQString m_attrString; -}; - -} //namespace - -#endif diff --git a/khtml/xml/xml_tokenizer.cpp b/khtml/xml/xml_tokenizer.cpp deleted file mode 100644 index 7c043815a..000000000 --- a/khtml/xml/xml_tokenizer.cpp +++ /dev/null @@ -1,609 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2000 Peter Kelly (pmk@post.com) - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - - -#include "xml_tokenizer.h" -#include "xml/dom_docimpl.h" -#include "xml/dom_textimpl.h" -#include "xml/dom_xmlimpl.h" -#include "html/html_tableimpl.h" -#include "html/html_headimpl.h" -#include "rendering/render_object.h" -#include "misc/htmltags.h" -#include "misc/htmlattrs.h" -#include "misc/loader.h" - -#include "khtmlview.h" -#include "khtml_part.h" -#include <tqvariant.h> -#include <kdebug.h> -#include <klocale.h> - -using namespace DOM; -using namespace khtml; - -XMLIncrementalSource::XMLIncrementalSource() - : TQXmlInputSource(), m_pos( 0 ), m_unicode( 0 ), - m_finished( false ) -{ -} - -void XMLIncrementalSource::fetchData() -{ - //just a dummy to overwrite default behavior -} - -TQChar XMLIncrementalSource::next() -{ - if ( m_finished ) - return TQXmlInputSource::EndOfDocument; - else if ( m_data.length() <= m_pos ) - return TQXmlInputSource::EndOfData; - else - return m_unicode[m_pos++]; -} - -void XMLIncrementalSource::setData( const TQString& str ) -{ - m_data = str; - m_unicode = m_data.unicode(); - m_pos = 0; - if ( !str.isEmpty() ) - m_finished = false; -} -void XMLIncrementalSource::setData( const TQByteArray& data ) -{ - setData( fromRawData( data, true ) ); -} - -void XMLIncrementalSource::appendXML( const TQString& str ) -{ - m_data += str; - m_unicode = m_data.unicode(); -} - -TQString XMLIncrementalSource::data() -{ - return m_data; -} - -void XMLIncrementalSource::setFinished( bool finished ) -{ - m_finished = finished; -} - -XMLHandler::XMLHandler(DocumentImpl *_doc, KHTMLView *_view) - : errorLine(0) -{ - m_doc = _doc; - m_view = _view; - pushNode( _doc ); -} - -XMLHandler::~XMLHandler() -{ -} - -void XMLHandler::pushNode( NodeImpl *node ) -{ - m_nodes.push( node ); -} - -NodeImpl *XMLHandler::popNode() -{ - return m_nodes.pop(); -} - -NodeImpl *XMLHandler::currentNode() const -{ - return m_nodes.current(); -} - -TQString XMLHandler::errorProtocol() -{ - return errorProt; -} - - -bool XMLHandler::startDocument() -{ - // at the beginning of parsing: do some initialization - errorProt = ""; - state = StateInit; - - return true; -} - -bool XMLHandler::startPrefixMapping(const TQString& prefix, const TQString& uri) -{ - namespaceInfo[prefix].push(uri); - return true; -} - -bool XMLHandler::endPrefixMapping(const TQString& prefix) -{ - TQValueStack<TQString>& stack = namespaceInfo[prefix]; - stack.pop(); - if (stack.isEmpty()) - namespaceInfo.remove(prefix); - return true; -} - -void XMLHandler::fixUpNSURI(TQString& uri, const TQString& qname) -{ - /* QXml does not resolve the namespaces of attributes in the same - tag that preceed the xmlns declaration. This fixes up that case */ - if (uri.isEmpty() && qname.find(':') != -1) { - TQXmlNamespaceSupport ns; - TQString localName, prefix; - ns.splitName(qname, prefix, localName); - if (namespaceInfo.contains(prefix)) { - uri = namespaceInfo[prefix].top(); - } - } -} - -bool XMLHandler::startElement( const TQString& namespaceURI, const TQString& /*localName*/, - const TQString& qName, const TQXmlAttributes& atts ) -{ - if (currentNode()->nodeType() == Node::TEXT_NODE) - exitText(); - - DOMString nsURI; - if (!namespaceURI.isNull()) - nsURI = DOMString(namespaceURI); - else - // No namespace declared, default to the no namespace - nsURI = DOMString(""); - ElementImpl *newElement = m_doc->createElementNS(nsURI,qName); - if (!newElement) - return false; - int i; - for (i = 0; i < atts.length(); i++) { - int exceptioncode = 0; - TQString uriString = atts.uri(i); - TQString qnString = atts.qName(i); - fixUpNSURI(uriString, qnString); - DOMString uri(uriString); - DOMString qn(qnString); - DOMString val(atts.value(i)); - newElement->setAttributeNS(uri, qn, val, exceptioncode); - if (exceptioncode) // exception setting attributes - return false; - } - - if (newElement->id() == ID_SCRIPT || newElement->id() == makeId(xhtmlNamespace, ID_SCRIPT)) - static_cast<HTMLScriptElementImpl *>(newElement)->setCreatedByParser(true); - - //this is tricky. in general the node doesn't have to attach to the one it's in. as far - //as standards go this is wrong, but there's literally thousands of documents where - //we see <p><ul>...</ul></p>. the following code is there for those cases. - //when we can't attach to the currently holding us node we try to attach to its parent - bool attached = false; - for ( NodeImpl *current = currentNode(); current; current = current->parent() ) { - attached = current->addChild( newElement ); - if ( attached ) - break; - } - if (attached) { - if (m_view && !newElement->attached() && !m_doc->hasPendingSheets()) - newElement->attach(); - pushNode( newElement ); - return true; - } - else { - delete newElement; - return false; - } - - // ### DOM spec states: "if there is no markup inside an element's content, the text is contained in a - // single object implementing the Text interface that is the only child of the element."... do we - // need to ensure that empty elements always have an empty text child? -} - - -bool XMLHandler::endElement( const TQString& /*namespaceURI*/, const TQString& /*localName*/, const TQString& /*qName*/ ) -{ - if (currentNode()->nodeType() == Node::TEXT_NODE) - exitText(); - - NodeImpl *node = popNode(); - if ( node ) { - node->close(); - while ( currentNode() && currentNode()->implicitNode() ) //for the implicit HTMLTableSectionElementImpl - popNode()->close(); - } else - return false; - - return true; -} - - -bool XMLHandler::startCDATA() -{ - if (currentNode()->nodeType() == Node::TEXT_NODE) - exitText(); - - NodeImpl *newNode = m_doc->createCDATASection(new DOMStringImpl("")); - if (currentNode()->addChild(newNode)) { - if (m_view && !newNode->attached() && !m_doc->hasPendingSheets()) - newNode->attach(); - pushNode( newNode ); - return true; - } - else { - delete newNode; - return false; - } - -} - -bool XMLHandler::endCDATA() -{ - popNode(); - Q_ASSERT( currentNode() ); - return currentNode(); -} - -bool XMLHandler::characters( const TQString& ch ) -{ - if (currentNode()->nodeType() == Node::TEXT_NODE || - currentNode()->nodeType() == Node::CDATA_SECTION_NODE || - enterText()) { - int exceptioncode = 0; - static_cast<TextImpl*>(currentNode())->appendData(ch,exceptioncode); - if (exceptioncode) - return false; - return true; - } - else { - // Don't worry about white-space violating DTD - if (ch.stripWhiteSpace().isEmpty()) return true; - - return false; - } - -} - -bool XMLHandler::comment(const TQString & ch) -{ - if (currentNode()->nodeType() == Node::TEXT_NODE) - exitText(); - // ### handle exceptions - currentNode()->addChild(m_doc->createComment(new DOMStringImpl(ch.unicode(), ch.length()))); - return true; -} - -bool XMLHandler::processingInstruction(const TQString &target, const TQString &data) -{ - if (currentNode()->nodeType() == Node::TEXT_NODE) - exitText(); - // ### handle exceptions - ProcessingInstructionImpl *pi = - m_doc->createProcessingInstruction(target, new DOMStringImpl(data.unicode(), data.length())); - currentNode()->addChild(pi); - pi->checkStyleSheet(); - return true; -} - - -TQString XMLHandler::errorString() -{ - // ### Make better error-messages - return i18n("the document is not in the correct file format"); -} - - -bool XMLHandler::fatalError( const TQXmlParseException& exception ) -{ - errorProt += i18n( "fatal parsing error: %1 in line %2, column %3" ) - .arg( exception.message() ) - .arg( exception.lineNumber() ) - .arg( exception.columnNumber() ); - - errorLine = exception.lineNumber(); - errorCol = exception.columnNumber(); - - return false; -} - -bool XMLHandler::enterText() -{ - NodeImpl *newNode = m_doc->createTextNode(""); - if (currentNode()->addChild(newNode)) { - pushNode( newNode ); - return true; - } - else { - delete newNode; - return false; - } -} - -void XMLHandler::exitText() -{ - if ( m_view && !currentNode()->attached() && !m_doc->hasPendingSheets() ) - currentNode()->attach(); - popNode(); -} - -bool XMLHandler::attributeDecl(const TQString &/*eName*/, const TQString &/*aName*/, const TQString &/*type*/, - const TQString &/*valueDefault*/, const TQString &/*value*/) -{ - // qt's xml parser (as of 2.2.3) does not currently give us values for type, valueDefault and - // value. When it does, we can store these somewhere and have default attributes on elements - return true; -} - -bool XMLHandler::externalEntityDecl(const TQString &/*name*/, const TQString &/*publicId*/, const TQString &/*systemId*/) -{ - // ### insert these too - is there anything special we have to do here? - return true; -} - -bool XMLHandler::internalEntityDecl(const TQString &name, const TQString &value) -{ - EntityImpl *e = new EntityImpl(m_doc,name); - // ### further parse entities inside the value and add them as separate nodes (or entityreferences)? - e->addChild(m_doc->createTextNode(new DOMStringImpl(value.unicode(), value.length()))); - if (m_doc->doctype()) - static_cast<GenericRONamedNodeMapImpl*>(m_doc->doctype()->entities())->addNode(e); - return true; -} - -bool XMLHandler::notationDecl(const TQString &/*name*/, const TQString &/*publicId*/, const TQString &/*systemId*/) -{ -// ### FIXME -// if (m_doc->document()->doctype()) { -// NotationImpl *n = new NotationImpl(m_doc,name,publicId,systemId); -// static_cast<GenericRONamedNodeMapImpl*>(m_doc->document()->doctype()->notations())->addNode(n); -// } - return true; -} - -bool XMLHandler::unparsedEntityDecl(const TQString &/*name*/, const TQString &/*publicId*/, - const TQString &/*systemId*/, const TQString &/*notationName*/) -{ - // ### - return true; -} - - -//------------------------------------------------------------------------------ - -XMLTokenizer::XMLTokenizer(DOM::DocumentImpl *_doc, KHTMLView *_view) - : m_handler(_doc,_view) -{ - m_doc = _doc; - m_view = _view; - m_scriptsIt = 0; - m_cachedScript = 0; - m_noErrors = true; - m_reader.setContentHandler( &m_handler ); - m_reader.setLexicalHandler( &m_handler ); - m_reader.setErrorHandler( &m_handler ); - m_reader.setDeclHandler( &m_handler ); - m_reader.setDTDHandler( &m_handler ); - m_reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); -} - -XMLTokenizer::~XMLTokenizer() -{ - if (m_scriptsIt) - delete m_scriptsIt; - if (m_cachedScript) - m_cachedScript->deref(this); -} - - -void XMLTokenizer::begin() -{ - // parse xml file - m_reader.parse( &m_source, true ); -} - -void XMLTokenizer::write( const TokenizerString &str, bool appendData ) -{ - if ( !m_noErrors && appendData ) - return; - if ( appendData ) { - m_source.appendXML( str.toString() ); - - } else { - m_source.setData( str.toString() ); - } - m_noErrors = m_reader.parseContinue(); -} - -void XMLTokenizer::end() -{ - m_source.setFinished( true ); - //if ( m_noErrors ) - //m_noErrors = m_reader.parseContinue(); - emit finishedParsing(); -} - -void XMLTokenizer::finish() -{ - m_source.setFinished( true ); - if (!m_noErrors) { - // An error occurred during parsing of the code. Display an error page to the user (the DOM - // tree is created manually and includes an excerpt from the code where the error is located) - - // ### for multiple error messages, display the code for each (can this happen?) - - // Clear the document - int exceptioncode = 0; - while (m_doc->hasChildNodes()) - static_cast<NodeImpl*>(m_doc)->removeChild(m_doc->firstChild(),exceptioncode); - - TQString line, errorLocPtr; - if ( m_handler.errorLine ) { - TQString xmlCode = m_source.data(); - TQTextIStream stream(&xmlCode); - for (unsigned long lineno = 0; lineno < m_handler.errorLine-1; lineno++) - stream.readLine(); - line = stream.readLine(); - - for (unsigned long colno = 0; colno < m_handler.errorCol-1; colno++) - errorLocPtr += " "; - errorLocPtr += "^"; - } - - // Create elements for display - DocumentImpl *doc = m_doc; - NodeImpl *html = doc->createElementNS(XHTML_NAMESPACE,"html"); - NodeImpl *body = doc->createElementNS(XHTML_NAMESPACE,"body"); - NodeImpl *h1 = doc->createElementNS(XHTML_NAMESPACE,"h1"); - NodeImpl *headingText = doc->createTextNode(i18n("XML parsing error")); - NodeImpl *errorText = doc->createTextNode(m_handler.errorProtocol()); - NodeImpl *hr = 0; - NodeImpl *pre = 0; - NodeImpl *lineText = 0; - NodeImpl *errorLocText = 0; - if ( !line.isNull() ) { - hr = doc->createElementNS(XHTML_NAMESPACE,"hr"); - pre = doc->createElementNS(XHTML_NAMESPACE,"pre"); - lineText = doc->createTextNode(line+"\n"); - errorLocText = doc->createTextNode(errorLocPtr); - } - - // Construct DOM tree. We ignore exceptions as we assume they will not be thrown here (due to the - // fact we are using a known tag set) - doc->appendChild(html,exceptioncode); - html->appendChild(body,exceptioncode); - if ( body ) - body->appendChild(h1,exceptioncode); - h1->appendChild(headingText,exceptioncode); - body->appendChild(errorText,exceptioncode); - body->appendChild(hr,exceptioncode); - body->appendChild(pre,exceptioncode); - if ( pre ) { - pre->appendChild(lineText,exceptioncode); - pre->appendChild(errorLocText,exceptioncode); - } - - // Close the renderers so that they update their display correctly - // ### this should not be necessary, but requires changes in the rendering code... - h1->close(); - if ( pre ) pre->close(); - body->close(); - - m_doc->recalcStyle( NodeImpl::Inherit ); - m_doc->updateRendering(); - - end(); - } - else { - // Parsing was successful. Now locate all html <script> tags in the document and execute them - // one by one - addScripts(m_doc); - m_scriptsIt = new TQPtrListIterator<HTMLScriptElementImpl>(m_scripts); - executeScripts(); - } - -} - -void XMLTokenizer::addScripts(NodeImpl *n) -{ - // Recursively go through the entire document tree, looking for html <script> tags. For each of these - // that is found, add it to the m_scripts list from which they will be executed - - if (n->id() == ID_SCRIPT || n->id() == makeId(xhtmlNamespace, ID_SCRIPT)) { - m_scripts.append(static_cast<HTMLScriptElementImpl*>(n)); - } - - NodeImpl *child; - for (child = n->firstChild(); child; child = child->nextSibling()) - addScripts(child); -} - -void XMLTokenizer::executeScripts() -{ - // Iterate through all of the html <script> tags in the document. For those that have a src attribute, - // start loading the script and return (executeScripts() will be called again once the script is loaded - // and continue where it left off). For scripts that don't have a src attribute, execute the code - // inside the tag - while (m_scriptsIt->current()) { - DOMString scriptSrc = m_scriptsIt->current()->getAttribute(ATTR_SRC); - TQString charset = m_scriptsIt->current()->getAttribute(ATTR_CHARSET).string(); - - if (!scriptSrc.isEmpty()) { - // we have a src attribute - m_cachedScript = m_doc->docLoader()->requestScript(scriptSrc, charset); - ++(*m_scriptsIt); - if (m_cachedScript) { - m_cachedScript->ref(this); // will call executeScripts() again if already cached - return; - } - } - else { - // no src attribute - execute from contents of tag - TQString scriptCode = ""; - NodeImpl *child; - for (child = m_scriptsIt->current()->firstChild(); child; child = child->nextSibling()) { - if ( ( child->nodeType() == Node::TEXT_NODE || child->nodeType() == Node::CDATA_SECTION_NODE) && - static_cast<TextImpl*>(child)->string() ) - scriptCode += TQConstString(static_cast<TextImpl*>(child)->string()->s, - static_cast<TextImpl*>(child)->string()->l).string(); - } - // the script cannot do document.write until we support incremental parsing - // ### handle the case where the script deletes the node or redirects to - // another page, etc. (also in notifyFinished()) - // ### the script may add another script node after this one which should be executed - if (m_view) { - m_view->part()->executeScript(DOM::Node(), scriptCode); - } - ++(*m_scriptsIt); - } - } - - // All scripts have finished executing, so calculate the style for the document and close - // the last element - m_doc->updateStyleSelector(); - - // We are now finished parsing - end(); -} - -void XMLTokenizer::notifyFinished(CachedObject *finishedObj) -{ - // This is called when a script has finished loading that was requested from executeScripts(). We execute - // the script, and then call executeScripts() again to continue iterating through the list of scripts in - // the document - if (finishedObj == m_cachedScript) { - DOMString scriptSource = m_cachedScript->script(); - m_cachedScript->deref(this); - m_cachedScript = 0; - if (m_view) - m_view->part()->executeScript(DOM::Node(), scriptSource.string()); - executeScripts(); - } -} - -bool XMLTokenizer::isWaitingForScripts() const -{ - return m_cachedScript != 0; -} - -#include "xml_tokenizer.moc" - diff --git a/khtml/xml/xml_tokenizer.h b/khtml/xml/xml_tokenizer.h deleted file mode 100644 index 355c41b74..000000000 --- a/khtml/xml/xml_tokenizer.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2000 Peter Kelly (pmk@post.com) - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _XML_Tokenizer_h_ -#define _XML_Tokenizer_h_ - -#include <tqxml.h> -#include <tqptrlist.h> -#include <tqptrstack.h> -#include <tqvaluestack.h> -#include <tqobject.h> -#include "misc/loader_client.h" -#include "misc/stringit.h" - -class KHTMLView; - -namespace khtml { - class CachedObject; - class CachedScript; -} - -namespace DOM { - class DocumentImpl; - class NodeImpl; - class HTMLScriptElementImpl; - class DocumentImpl; - class HTMLScriptElementImpl; -} - -namespace khtml { - -class XMLHandler : public TQXmlDefaultHandler -{ -public: - XMLHandler(DOM::DocumentImpl *_doc, KHTMLView *_view); - virtual ~XMLHandler(); - - // return the error protocol if parsing failed - TQString errorProtocol(); - - // overloaded handler functions - bool startDocument(); - bool startElement(const TQString& namespaceURI, const TQString& localName, const TQString& qName, const TQXmlAttributes& atts); - bool endElement(const TQString& namespaceURI, const TQString& localName, const TQString& qName); - bool startCDATA(); - bool endCDATA(); - bool characters(const TQString& ch); - bool comment(const TQString & ch); - bool processingInstruction(const TQString &target, const TQString &data); - - // namespace handling, to workaround problem in QXML where some attributes - // do not get the namespace resolved properly - bool startPrefixMapping(const TQString& prefix, const TQString& uri); - bool endPrefixMapping(const TQString& prefix); - void fixUpNSURI(TQString& uri, const TQString& qname); - TQMap<TQString, TQValueStack<TQString> > namespaceInfo; - - - // from QXmlDeclHandler - bool attributeDecl(const TQString &eName, const TQString &aName, const TQString &type, const TQString &valueDefault, const TQString &value); - bool externalEntityDecl(const TQString &name, const TQString &publicId, const TQString &systemId); - bool internalEntityDecl(const TQString &name, const TQString &value); - - // from QXmlDTDHandler - bool notationDecl(const TQString &name, const TQString &publicId, const TQString &systemId); - bool unparsedEntityDecl(const TQString &name, const TQString &publicId, const TQString &systemId, const TQString ¬ationName); - - bool enterText(); - void exitText(); - - TQString errorString(); - - bool fatalError( const TQXmlParseException& exception ); - - unsigned long errorLine; - unsigned long errorCol; - -private: - void pushNode( DOM::NodeImpl *node ); - DOM::NodeImpl *popNode(); - DOM::NodeImpl *currentNode() const; -private: - TQString errorProt; - DOM::DocumentImpl *m_doc; - KHTMLView *m_view; - TQPtrStack<DOM::NodeImpl> m_nodes; - DOM::NodeImpl *m_rootNode; - - enum State { - StateInit, - StateDocument, - StateQuote, - StateLine, - StateHeading, - StateP - }; - State state; -}; - -class Tokenizer : public TQObject -{ - Q_OBJECT -public: - virtual void begin() = 0; - // script output must be prepended, while new data - // received during executing a script must be appended, hence the - // extra bool to be able to distinguish between both cases. document.write() - // always uses false, while khtmlpart uses true - virtual void write( const TokenizerString &str, bool appendData) = 0; - virtual void end() = 0; - virtual void finish() = 0; - virtual void setOnHold(bool /*_onHold*/) {} - virtual bool isWaitingForScripts() const = 0; - virtual bool isExecutingScript() const = 0; - virtual void abort() {} - virtual void setAutoClose(bool b=true) = 0; - -signals: - void finishedParsing(); - -}; - -class XMLIncrementalSource : public TQXmlInputSource -{ -public: - XMLIncrementalSource(); - virtual void fetchData(); - virtual TQChar next(); - virtual void setData( const TQString& str ); - virtual void setData( const TQByteArray& data ); - virtual TQString data(); - - void appendXML( const TQString& str ); - void setFinished( bool ); - -private: - TQString m_data; - uint m_pos; - const TQChar *m_unicode; - bool m_finished; -}; - -class XMLTokenizer : public Tokenizer, public khtml::CachedObjectClient -{ -public: - XMLTokenizer(DOM::DocumentImpl *, KHTMLView * = 0); - virtual ~XMLTokenizer(); - virtual void begin(); - virtual void write( const TokenizerString &str, bool ); - virtual void end(); - virtual void finish(); - virtual void setAutoClose(bool b=true) { tqWarning("XMLTokenizer::setAutoClose: stub."); (void)b; } - - // from CachedObjectClient - void notifyFinished(khtml::CachedObject *finishedObj); - - virtual bool isWaitingForScripts() const; - virtual bool isExecutingScript() const { return false; } - -protected: - DOM::DocumentImpl *m_doc; - KHTMLView *m_view; - - void executeScripts(); - void addScripts(DOM::NodeImpl *n); - - TQPtrList<DOM::HTMLScriptElementImpl> m_scripts; - TQPtrListIterator<DOM::HTMLScriptElementImpl> *m_scriptsIt; - khtml::CachedScript *m_cachedScript; - - XMLHandler m_handler; - TQXmlSimpleReader m_reader; - XMLIncrementalSource m_source; - bool m_noErrors; -}; - -} // end namespace - -#endif |