~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/webkit/WebCore/page/DOMSelection.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
 
2
 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
3
3
 *
4
4
 * Redistribution and use in source and binary forms, with or without
5
5
 * modification, are permitted provided that the following conditions
32
32
 
33
33
#include "ExceptionCode.h"
34
34
#include "Frame.h"
35
 
#include "htmlediting.h"
36
35
#include "Node.h"
37
36
#include "PlatformString.h"
38
37
#include "Range.h"
39
38
#include "SelectionController.h"
40
39
#include "TextIterator.h"
 
40
#include "htmlediting.h"
41
41
 
42
42
namespace WebCore {
43
43
 
 
44
static Node* selectionShadowAncestor(Frame* frame)
 
45
{
 
46
    Node* node = frame->selection()->selection().base().anchorNode();
 
47
    if (!node)
 
48
        return 0;
 
49
    Node* shadowAncestor = node->shadowAncestorNode();
 
50
    if (shadowAncestor == node)
 
51
        return 0;
 
52
    return shadowAncestor;
 
53
}
 
54
 
44
55
DOMSelection::DOMSelection(Frame* frame)
45
56
    : m_frame(frame)
46
57
{
56
67
    m_frame = 0;
57
68
}
58
69
 
 
70
const VisibleSelection& DOMSelection::visibleSelection() const
 
71
{
 
72
    ASSERT(m_frame);
 
73
    return m_frame->selection()->selection();
 
74
}
 
75
 
 
76
static Position anchorPosition(const VisibleSelection& selection)
 
77
{
 
78
    Position anchor = selection.isBaseFirst() ? selection.start() : selection.end();
 
79
    return rangeCompliantEquivalent(anchor);
 
80
}
 
81
 
 
82
static Position focusPosition(const VisibleSelection& selection)
 
83
{
 
84
    Position focus = selection.isBaseFirst() ? selection.end() : selection.start();
 
85
    return rangeCompliantEquivalent(focus);
 
86
}
 
87
 
 
88
static Position basePosition(const VisibleSelection& selection)
 
89
{
 
90
    return rangeCompliantEquivalent(selection.base());
 
91
}
 
92
 
 
93
static Position extentPosition(const VisibleSelection& selection)
 
94
{
 
95
    return rangeCompliantEquivalent(selection.extent());
 
96
}
 
97
 
59
98
Node* DOMSelection::anchorNode() const
60
99
{
61
100
    if (!m_frame)
62
101
        return 0;
63
 
 
64
 
    const Selection& selection = m_frame->selection()->selection();
65
 
    Position anchor = selection.isBaseFirst() ? selection.start() : selection.end();
66
 
    anchor = rangeCompliantEquivalent(anchor);
67
 
    return anchor.node();
 
102
    if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
 
103
        return shadowAncestor->parentNode();
 
104
    return anchorPosition(visibleSelection()).node();
 
105
}
 
106
 
 
107
int DOMSelection::anchorOffset() const
 
108
{
 
109
    if (!m_frame)
 
110
        return 0;
 
111
    if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
 
112
        return shadowAncestor->nodeIndex();
 
113
    return anchorPosition(visibleSelection()).deprecatedEditingOffset();
 
114
}
 
115
 
 
116
Node* DOMSelection::focusNode() const
 
117
{
 
118
    if (!m_frame)
 
119
        return 0;
 
120
    if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
 
121
        return shadowAncestor->parentNode();
 
122
    return focusPosition(visibleSelection()).node();
 
123
}
 
124
 
 
125
int DOMSelection::focusOffset() const
 
126
{
 
127
    if (!m_frame)
 
128
        return 0;
 
129
    if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
 
130
        return shadowAncestor->nodeIndex();
 
131
    return focusPosition(visibleSelection()).deprecatedEditingOffset();
68
132
}
69
133
 
70
134
Node* DOMSelection::baseNode() const
71
135
{
72
136
    if (!m_frame)
73
137
        return 0;
74
 
    return rangeCompliantEquivalent(m_frame->selection()->selection().base()).node();
75
 
}
76
 
 
77
 
int DOMSelection::anchorOffset() const
78
 
{
79
 
    if (!m_frame)
80
 
        return 0;
81
 
 
82
 
    const Selection& selection = m_frame->selection()->selection();
83
 
    Position anchor = selection.isBaseFirst() ? selection.start() : selection.end();
84
 
    anchor = rangeCompliantEquivalent(anchor);
85
 
    return anchor.offset();
 
138
    if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
 
139
        return shadowAncestor->parentNode();
 
140
    return basePosition(visibleSelection()).node();
86
141
}
87
142
 
88
143
int DOMSelection::baseOffset() const
89
144
{
90
145
    if (!m_frame)
91
146
        return 0;
92
 
    return rangeCompliantEquivalent(m_frame->selection()->selection().base()).offset();
93
 
}
94
 
 
95
 
Node* DOMSelection::focusNode() const
96
 
{
97
 
    if (!m_frame)
98
 
        return 0;
99
 
 
100
 
    const Selection& selection = m_frame->selection()->selection();
101
 
    Position focus = selection.isBaseFirst() ? selection.end() : selection.start();
102
 
    focus = rangeCompliantEquivalent(focus);
103
 
    return focus.node();
 
147
    if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
 
148
        return shadowAncestor->nodeIndex();
 
149
    return basePosition(visibleSelection()).deprecatedEditingOffset();
104
150
}
105
151
 
106
152
Node* DOMSelection::extentNode() const
107
153
{
108
154
    if (!m_frame)
109
155
        return 0;
110
 
    return rangeCompliantEquivalent(m_frame->selection()->selection().extent()).node();
111
 
}
112
 
 
113
 
int DOMSelection::focusOffset() const
114
 
{
115
 
    if (!m_frame)
116
 
        return 0;
117
 
 
118
 
    const Selection& selection = m_frame->selection()->selection();
119
 
    Position focus = selection.isBaseFirst() ? selection.end() : selection.start();
120
 
    focus = rangeCompliantEquivalent(focus);
121
 
    return focus.offset();
 
156
    if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
 
157
        return shadowAncestor->parentNode();
 
158
    return extentPosition(visibleSelection()).node();
122
159
}
123
160
 
124
161
int DOMSelection::extentOffset() const
125
162
{
126
163
    if (!m_frame)
127
164
        return 0;
128
 
    return rangeCompliantEquivalent(m_frame->selection()->selection().extent()).offset();
 
165
    if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
 
166
        return shadowAncestor->nodeIndex();
 
167
    return extentPosition(visibleSelection()).deprecatedEditingOffset();
129
168
}
130
169
 
131
170
bool DOMSelection::isCollapsed() const
132
171
{
133
 
    if (!m_frame)
134
 
        return false;
 
172
    if (!m_frame || selectionShadowAncestor(m_frame))
 
173
        return true;
135
174
    return !m_frame->selection()->isRange();
136
175
}
137
176
 
142
181
 
143
182
    SelectionController* selection = m_frame->selection();
144
183
 
 
184
    // This is a WebKit DOM extension, incompatible with an IE extension
 
185
    // IE has this same attribute, but returns "none", "text" and "control"
 
186
    // http://msdn.microsoft.com/en-us/library/ms534692(VS.85).aspx
145
187
    if (selection->isNone())
146
188
        return "None";
147
189
    if (selection->isCaret())
173
215
    if (!m_frame)
174
216
        return;
175
217
 
176
 
    const Selection& selection = m_frame->selection()->selection();
 
218
    const VisibleSelection& selection = m_frame->selection()->selection();
177
219
    m_frame->selection()->moveTo(VisiblePosition(selection.end(), DOWNSTREAM));
178
220
}
179
221
 
182
224
    if (!m_frame)
183
225
        return;
184
226
 
185
 
    const Selection& selection = m_frame->selection()->selection();
 
227
    const VisibleSelection& selection = m_frame->selection()->selection();
186
228
    m_frame->selection()->moveTo(VisiblePosition(selection.start(), DOWNSTREAM));
187
229
}
188
230
 
190
232
{
191
233
    if (!m_frame)
192
234
        return;
193
 
    m_frame->selection()->moveTo(VisiblePosition());
 
235
    m_frame->selection()->clear();
194
236
}
195
237
 
196
238
void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extentNode, int extentOffset, ExceptionCode& ec)
204
246
    }
205
247
    VisiblePosition visibleBase = VisiblePosition(baseNode, baseOffset, DOWNSTREAM);
206
248
    VisiblePosition visibleExtent = VisiblePosition(extentNode, extentOffset, DOWNSTREAM);
207
 
    
 
249
 
208
250
    m_frame->selection()->moveTo(visibleBase, visibleExtent);
209
251
}
210
252
 
229
271
        alter = SelectionController::EXTEND;
230
272
    else if (equalIgnoringCase(alterString, "move"))
231
273
        alter = SelectionController::MOVE;
232
 
    else 
 
274
    else
233
275
        return;
234
 
    
 
276
 
235
277
    SelectionController::EDirection direction;
236
278
    if (equalIgnoringCase(directionString, "forward"))
237
279
        direction = SelectionController::FORWARD;
243
285
        direction = SelectionController::RIGHT;
244
286
    else
245
287
        return;
246
 
        
 
288
 
247
289
    TextGranularity granularity;
248
290
    if (equalIgnoringCase(granularityString, "character"))
249
291
        granularity = CharacterGranularity;
298
340
        return 0;
299
341
    }
300
342
 
301
 
    const Selection& selection = m_frame->selection()->selection();
302
 
    return selection.toRange();
 
343
    // If you're hitting this, you've added broken multi-range selection support
 
344
    ASSERT(rangeCount() == 1);
 
345
 
 
346
    if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) {
 
347
        Node* container = shadowAncestor->parentNode();
 
348
        int offset = shadowAncestor->nodeIndex();
 
349
        return Range::create(shadowAncestor->document(), container, offset, container, offset);
 
350
    }
 
351
 
 
352
    const VisibleSelection& selection = m_frame->selection()->selection();
 
353
    return selection.firstRange();
303
354
}
304
355
 
305
356
void DOMSelection::removeAllRanges()
317
368
        return;
318
369
 
319
370
    SelectionController* selection = m_frame->selection();
320
 
    
 
371
 
321
372
    if (selection->isNone()) {
322
 
        selection->setSelection(Selection(r));
 
373
        selection->setSelection(VisibleSelection(r));
323
374
        return;
324
375
    }
325
376
 
326
 
    RefPtr<Range> range = selection->selection().toRange();
 
377
    RefPtr<Range> range = selection->selection().toNormalizedRange();
327
378
    ExceptionCode ec = 0;
328
379
    if (r->compareBoundaryPoints(Range::START_TO_START, range.get(), ec) == -1) {
329
380
        // We don't support discontiguous selection. We don't do anything if r and range don't intersect.
330
381
        if (r->compareBoundaryPoints(Range::START_TO_END, range.get(), ec) > -1) {
331
382
            if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), ec) == -1)
332
383
                // The original range and r intersect.
333
 
                selection->setSelection(Selection(r->startPosition(), range->endPosition(), DOWNSTREAM));
 
384
                selection->setSelection(VisibleSelection(r->startPosition(), range->endPosition(), DOWNSTREAM));
334
385
            else
335
386
                // r contains the original range.
336
 
                selection->setSelection(Selection(r));
 
387
                selection->setSelection(VisibleSelection(r));
337
388
        }
338
389
    } else {
339
390
        // We don't support discontiguous selection. We don't do anything if r and range don't intersect.
340
391
        if (r->compareBoundaryPoints(Range::END_TO_START, range.get(), ec) < 1) {
341
392
            if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), ec) == -1)
342
393
                // The original range contains r.
343
 
                selection->setSelection(Selection(range.get()));
 
394
                selection->setSelection(VisibleSelection(range.get()));
344
395
            else
345
396
                // The original range and r intersect.
346
 
                selection->setSelection(Selection(range->startPosition(), r->endPosition(), DOWNSTREAM));
 
397
                selection->setSelection(VisibleSelection(range->startPosition(), r->endPosition(), DOWNSTREAM));
347
398
        }
348
399
    }
349
400
}
361
412
    if (isCollapsed())
362
413
        selection->modify(SelectionController::EXTEND, SelectionController::BACKWARD, CharacterGranularity);
363
414
 
364
 
    RefPtr<Range> selectedRange = selection->selection().toRange();
 
415
    RefPtr<Range> selectedRange = selection->selection().toNormalizedRange();
365
416
 
366
417
    ExceptionCode ec = 0;
367
418
    selectedRange->deleteContents(ec);
368
419
    ASSERT(!ec);
369
 
    
 
420
 
370
421
    setBaseAndExtent(selectedRange->startContainer(ec), selectedRange->startOffset(ec), selectedRange->startContainer(ec), selectedRange->startOffset(ec), ec);
371
422
    ASSERT(!ec);
372
423
}
383
434
 
384
435
    Node* parentNode = n->parentNode();
385
436
    unsigned nodeIndex = n->nodeIndex();
386
 
    RefPtr<Range> selectedRange = selection->selection().toRange();
 
437
    RefPtr<Range> selectedRange = selection->selection().toNormalizedRange();
387
438
 
388
439
    if (!parentNode)
389
440
        return false;
418
469
    if (!m_frame)
419
470
        return String();
420
471
 
421
 
    return plainText(m_frame->selection()->selection().toRange().get());
 
472
    return plainText(m_frame->selection()->selection().toNormalizedRange().get());
422
473
}
423
474
 
424
475
} // namespace WebCore