📄 htmlediting_impl.h
字号:
/*
* Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __htmleditingimpl_h__
#define __htmleditingimpl_h__
#include "htmlediting.h"
#include "dom_position.h"
#include "dom_selection.h"
#include "dom_string.h"
#include "dom2_range.h"
#include "qvaluelist.h"
#include "shared.h"
namespace DOM {
class AtomicString;
class CSSProperty;
class CSSStyleDeclarationImpl;
class DocumentImpl;
class DOMString;
class ElementImpl;
class HTMLElementImpl;
class NodeImpl;
class NodeListImpl;
class Position;
class Range;
class Selection;
class TextImpl;
class TreeWalkerImpl;
};
namespace khtml {
//------------------------------------------------------------------------------------------
// EditCommandImpl
class EditCommandImpl : public SharedCommandImpl
{
public:
EditCommandImpl(DOM::DocumentImpl *);
virtual ~EditCommandImpl();
virtual int commandID() const;
bool isCompositeStep() const { return parent().notNull(); }
EditCommand parent() const;
void setParent(const EditCommand &);
enum ECommandState { NotApplied, Applied };
void apply();
void unapply();
void reapply();
virtual void doApply() = 0;
virtual void doUnapply() = 0;
virtual void doReapply(); // calls doApply()
virtual DOM::DocumentImpl * const document() const { return m_document; }
DOM::Selection startingSelection() const { return m_startingSelection; }
DOM::Selection endingSelection() const { return m_endingSelection; }
ECommandState state() const { return m_state; }
void setState(ECommandState state) { m_state = state; }
void setStartingSelection(const DOM::Selection &s);
void setEndingSelection(const DOM::Selection &s);
private:
DOM::DocumentImpl *m_document;
ECommandState m_state;
DOM::Selection m_startingSelection;
DOM::Selection m_endingSelection;
EditCommand m_parent;
};
//------------------------------------------------------------------------------------------
// CompositeEditCommandImpl
class CompositeEditCommandImpl : public EditCommandImpl
{
public:
CompositeEditCommandImpl(DOM::DocumentImpl *);
virtual ~CompositeEditCommandImpl();
virtual int commandID() const;
virtual void doApply() = 0;
virtual void doUnapply();
virtual void doReapply();
protected:
//
// sugary-sweet convenience functions to help create and apply edit commands in composite commands
//
void appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild);
void applyCommandToComposite(EditCommand &);
void deleteCollapsibleWhitespace();
void deleteCollapsibleWhitespace(const DOM::Selection &selection);
void deleteKeyPressed();
void deleteSelection();
void deleteSelection(const DOM::Selection &selection);
void deleteText(DOM::TextImpl *node, long offset, long count);
void inputText(const DOM::DOMString &text);
void insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
void insertNodeAt(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild, long offset);
void insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
void insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text);
void joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2);
void removeCSSProperty(DOM::CSSStyleDeclarationImpl *, int property);
void removeNodeAttribute(DOM::ElementImpl *, int attribute);
void removeNode(DOM::NodeImpl *removeChild);
void removeNodeAndPrune(DOM::NodeImpl *pruneNode, DOM::NodeImpl *stopNode=0);
void removeNodePreservingChildren(DOM::NodeImpl *node);
void replaceText(DOM::TextImpl *node, long offset, long count, const DOM::DOMString &replacementText);
void setNodeAttribute(DOM::ElementImpl *, int attribute, const DOM::DOMString &);
void splitTextNode(DOM::TextImpl *text, long offset);
DOM::ElementImpl *createTypingStyleElement() const;
QValueList<EditCommand> m_cmds;
};
//==========================================================================================
// Concrete commands
//------------------------------------------------------------------------------------------
// AppendNodeCommandImpl
class AppendNodeCommandImpl : public EditCommandImpl
{
public:
AppendNodeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *parentNode, DOM::NodeImpl *appendChild);
virtual ~AppendNodeCommandImpl();
virtual int commandID() const;
virtual void doApply();
virtual void doUnapply();
DOM::NodeImpl *parentNode() const { return m_parentNode; }
DOM::NodeImpl *appendChild() const { return m_appendChild; }
private:
DOM::NodeImpl *m_parentNode;
DOM::NodeImpl *m_appendChild;
};
//------------------------------------------------------------------------------------------
// ApplyStyleCommandImpl
class ApplyStyleCommandImpl : public CompositeEditCommandImpl
{
public:
ApplyStyleCommandImpl(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *style);
virtual ~ApplyStyleCommandImpl();
virtual int commandID() const;
virtual void doApply();
DOM::CSSStyleDeclarationImpl *style() const { return m_style; }
struct StyleChange {
StyleChange() : applyBold(false), applyItalic(false) {}
DOM::DOMString cssStyle;
bool applyBold:1;
bool applyItalic:1;
};
private:
// style-removal helpers
bool isHTMLStyleNode(DOM::HTMLElementImpl *);
void removeHTMLStyleNode(DOM::HTMLElementImpl *);
void removeCSSStyle(DOM::HTMLElementImpl *);
void removeStyle(const DOM::Position &start, const DOM::Position &end);
bool nodeFullySelected(const DOM::NodeImpl *node) const;
// style-application helpers
bool currentlyHasStyle(const DOM::Position &, const DOM::CSSProperty *) const;
StyleChange computeStyleChange(const DOM::Position &, DOM::CSSStyleDeclarationImpl *);
bool splitTextAtStartIfNeeded(const DOM::Position &start, const DOM::Position &end);
DOM::NodeImpl *splitTextAtEndIfNeeded(const DOM::Position &start, const DOM::Position &end);
void surroundNodeRangeWithElement(DOM::NodeImpl *start, DOM::NodeImpl *end, DOM::ElementImpl *element);
DOM::Position positionInsertionPoint(DOM::Position);
void applyStyleIfNeeded(DOM::NodeImpl *start, DOM::NodeImpl *end);
DOM::CSSStyleDeclarationImpl *m_style;
};
//------------------------------------------------------------------------------------------
// DeleteCollapsibleWhitespaceCommandImpl
class DeleteCollapsibleWhitespaceCommandImpl : public CompositeEditCommandImpl
{
public:
DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl *document);
DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl *document, const DOM::Selection &selection);
virtual ~DeleteCollapsibleWhitespaceCommandImpl();
virtual int commandID() const;
virtual void doApply();
private:
DOM::Position deleteWhitespace(const DOM::Position &pos);
unsigned long m_charactersDeleted;
DOM::Selection m_selectionToCollapse;
bool m_hasSelectionToCollapse;
};
//------------------------------------------------------------------------------------------
// DeleteSelectionCommandImpl
class DeleteSelectionCommandImpl : public CompositeEditCommandImpl
{
public:
DeleteSelectionCommandImpl(DOM::DocumentImpl *document);
DeleteSelectionCommandImpl(DOM::DocumentImpl *document, const DOM::Selection &selection);
virtual ~DeleteSelectionCommandImpl();
virtual int commandID() const;
virtual void doApply();
private:
void deleteDownstreamWS(const DOM::Position &start);
bool containsOnlyWhitespace(const DOM::Position &start, const DOM::Position &end);
void joinTextNodesWithSameStyle();
DOM::Selection m_selectionToDelete;
bool m_hasSelectionToDelete;
};
//------------------------------------------------------------------------------------------
// DeleteTextCommandImpl
class DeleteTextCommandImpl : public EditCommandImpl
{
public:
DeleteTextCommandImpl(DOM::DocumentImpl *document, DOM::TextImpl *node, long offset, long count);
virtual ~DeleteTextCommandImpl();
virtual int commandID() const;
virtual void doApply();
virtual void doUnapply();
DOM::TextImpl *node() const { return m_node; }
long offset() const { return m_offset; }
long count() const { return m_count; }
private:
DOM::TextImpl *m_node;
long m_offset;
long m_count;
DOM::DOMString m_text;
};
//------------------------------------------------------------------------------------------
// InputNewlineCommandImpl
class InputNewlineCommandImpl : public CompositeEditCommandImpl
{
public:
InputNewlineCommandImpl(DOM::DocumentImpl *document);
virtual ~InputNewlineCommandImpl();
virtual int commandID() const;
virtual void doApply();
private:
void insertNodeAfterPosition(DOM::NodeImpl *node, const DOM::Position &pos);
void insertNodeBeforePosition(DOM::NodeImpl *node, const DOM::Position &pos);
};
//------------------------------------------------------------------------------------------
// InputTextCommandImpl
class InputTextCommandImpl : public CompositeEditCommandImpl
{
public:
InputTextCommandImpl(DOM::DocumentImpl *document);
virtual ~InputTextCommandImpl();
virtual int commandID() const;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -