WebCore:
[WebKit-https.git] / WebCore / editing / Editor.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "Editor.h"
28
29 #include "Frame.h"
30 #include "Range.h"
31 #include "Sound.h"
32 #include "EditorClient.h"
33
34 namespace WebCore {
35
36 // implement as platform-specific
37 Pasteboard generalPasteboard()
38 {
39     return 0;
40 }
41
42 bool Editor::canCopy()
43 { return false; }
44
45 bool Editor::canCut()
46 { return false; }
47
48 bool Editor::canDelete()
49 { return false; }
50
51 bool Editor::canDeleteRange(Range* range)
52 {
53     ExceptionCode ec = 0;
54     Node *startContainer = range->startContainer(ec);
55     Node *endContainer = range->endContainer(ec);
56     if (!startContainer || !endContainer)
57         return false;
58     
59     if (!startContainer->isContentEditable() || !endContainer->isContentEditable())
60         return false;
61     
62     if (range->collapsed(ec)) {
63         VisiblePosition start(startContainer, range->startOffset(ec), DOWNSTREAM);
64         VisiblePosition previous = start.previous();
65         // FIXME: We sometimes allow deletions at the start of editable roots, like when the caret is in an empty list item.
66         if (previous.isNull() || previous.deepEquivalent().node()->rootEditableElement() != startContainer->rootEditableElement())
67             return false;
68     }
69     return true;
70 }
71
72 bool Editor::canPaste()
73 { return false; }
74
75 bool Editor::canSmartCopyOrDelete()
76 { return false; }
77
78 void Editor::deleteSelection()
79 {}
80
81 void Editor::deleteSelectionWithSmartDelete(bool enabled)
82 {}
83
84 bool Editor::isSelectionRichlyEditable()
85 { return false; }
86
87 void Editor::pasteAsPlainTextWithPasteboard(Pasteboard pasteboard)
88 {}
89
90 void Editor::pasteWithPasteboard(Pasteboard pasteboard, bool allowPlainText)
91 {}
92
93 Range* Editor::selectedRange()
94 { return NULL; }
95
96 bool Editor::shouldDeleteRange(Range* range)
97 {
98     ExceptionCode ec;
99     if (!range || range->collapsed(ec))
100         return false;
101     
102     if (!canDeleteRange(range))
103         return false;
104
105     return m_client->shouldDeleteRange(range);
106  }
107
108 bool Editor::tryDHTMLCopy()
109 {
110     bool handled = false;
111     return handled;
112 }
113
114 bool Editor::tryDHTMLCut()
115 {
116     bool handled = false;
117     return handled;
118 }
119
120 bool Editor::tryDHTMLPaste()
121 {
122     bool handled = false;
123     return handled;
124 }
125
126 void Editor::writeSelectionToPasteboard(Pasteboard pasteboard)
127 {}
128
129 // =============================================================================
130 //
131 // public editing commands
132 //
133 // =============================================================================
134
135 Editor::Editor(Frame* frame, EditorClient* client)
136     : m_frame(frame)
137     , m_client(client)
138
139     m_client->ref();
140 }
141
142 Editor::~Editor()
143 {
144     m_client->deref();
145 }
146
147 void Editor::cut()
148 {
149     if (tryDHTMLCut())
150         return; // DHTML did the whole operation
151     if (!canCut()) {
152         systemBeep();
153         return;
154     }
155     
156     if (shouldDeleteRange(selectedRange())) {
157         writeSelectionToPasteboard(generalPasteboard());
158         deleteSelectionWithSmartDelete(canSmartCopyOrDelete());
159     }
160 }
161
162 void Editor::copy()
163 {
164
165     if (tryDHTMLCopy())
166         return; // DHTML did the whole operation
167     if (!canCopy()) {
168         systemBeep();
169         return;
170     }
171     writeSelectionToPasteboard(generalPasteboard());
172 }
173
174 void Editor::paste()
175 {
176     if (tryDHTMLPaste())
177         return;     // DHTML did the whole operation
178     if (!canPaste())
179         return;
180     if (isSelectionRichlyEditable())
181         pasteWithPasteboard(generalPasteboard(), true);
182     else
183         pasteAsPlainTextWithPasteboard(generalPasteboard());
184 }
185
186 void Editor::performDelete()
187 {
188     if (!canDelete()) {
189         systemBeep();
190         return;
191     }
192     deleteSelection();
193 }
194
195 } // namespace WebCore