| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2012 Google Inc. All rights reserved. | 3 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 */ | 28 */ |
| 29 | 29 |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "core/page/DOMSelection.h" | 32 #include "core/page/DOMSelection.h" |
| 33 | 33 |
| 34 #include "bindings/v8/ExceptionMessages.h" | |
| 35 #include "bindings/v8/ExceptionState.h" | 34 #include "bindings/v8/ExceptionState.h" |
| 36 #include "bindings/v8/ExceptionStatePlaceholder.h" | 35 #include "bindings/v8/ExceptionStatePlaceholder.h" |
| 37 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
| 38 #include "core/dom/ExceptionCode.h" | 37 #include "core/dom/ExceptionCode.h" |
| 39 #include "core/dom/Node.h" | 38 #include "core/dom/Node.h" |
| 40 #include "core/dom/Range.h" | 39 #include "core/dom/Range.h" |
| 41 #include "core/dom/TreeScope.h" | 40 #include "core/dom/TreeScope.h" |
| 42 #include "core/editing/FrameSelection.h" | 41 #include "core/editing/FrameSelection.h" |
| 43 #include "core/editing/TextIterator.h" | 42 #include "core/editing/TextIterator.h" |
| 44 #include "core/editing/htmlediting.h" | 43 #include "core/editing/htmlediting.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 return 0; | 192 return 0; |
| 194 return m_frame->selection().isNone() ? 0 : 1; | 193 return m_frame->selection().isNone() ? 0 : 1; |
| 195 } | 194 } |
| 196 | 195 |
| 197 void DOMSelection::collapse(Node* node, int offset, ExceptionState& exceptionSta
te) | 196 void DOMSelection::collapse(Node* node, int offset, ExceptionState& exceptionSta
te) |
| 198 { | 197 { |
| 199 if (!m_frame) | 198 if (!m_frame) |
| 200 return; | 199 return; |
| 201 | 200 |
| 202 if (offset < 0) { | 201 if (offset < 0) { |
| 203 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::fail
edToExecute("collapse", "Selection", String::number(offset) + " is not a valid o
ffset.")); | 202 exceptionState.throwDOMException(IndexSizeError, String::number(offset)
+ " is not a valid offset."); |
| 204 return; | 203 return; |
| 205 } | 204 } |
| 206 | 205 |
| 207 if (!isValidForPosition(node)) | 206 if (!isValidForPosition(node)) |
| 208 return; | 207 return; |
| 209 | 208 |
| 210 // FIXME: Eliminate legacy editing positions | 209 // FIXME: Eliminate legacy editing positions |
| 211 m_frame->selection().moveTo(VisiblePosition(createLegacyEditingPosition(node
, offset), DOWNSTREAM)); | 210 m_frame->selection().moveTo(VisiblePosition(createLegacyEditingPosition(node
, offset), DOWNSTREAM)); |
| 212 } | 211 } |
| 213 | 212 |
| 214 void DOMSelection::collapseToEnd(ExceptionState& exceptionState) | 213 void DOMSelection::collapseToEnd(ExceptionState& exceptionState) |
| 215 { | 214 { |
| 216 if (!m_frame) | 215 if (!m_frame) |
| 217 return; | 216 return; |
| 218 | 217 |
| 219 const VisibleSelection& selection = m_frame->selection().selection(); | 218 const VisibleSelection& selection = m_frame->selection().selection(); |
| 220 | 219 |
| 221 if (selection.isNone()) { | 220 if (selection.isNone()) { |
| 222 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("collapseToEnd", "Selection", "there is no selection.")); | 221 exceptionState.throwDOMException(InvalidStateError, "there is no selecti
on."); |
| 223 return; | 222 return; |
| 224 } | 223 } |
| 225 | 224 |
| 226 m_frame->selection().moveTo(VisiblePosition(selection.end(), DOWNSTREAM)); | 225 m_frame->selection().moveTo(VisiblePosition(selection.end(), DOWNSTREAM)); |
| 227 } | 226 } |
| 228 | 227 |
| 229 void DOMSelection::collapseToStart(ExceptionState& exceptionState) | 228 void DOMSelection::collapseToStart(ExceptionState& exceptionState) |
| 230 { | 229 { |
| 231 if (!m_frame) | 230 if (!m_frame) |
| 232 return; | 231 return; |
| 233 | 232 |
| 234 const VisibleSelection& selection = m_frame->selection().selection(); | 233 const VisibleSelection& selection = m_frame->selection().selection(); |
| 235 | 234 |
| 236 if (selection.isNone()) { | 235 if (selection.isNone()) { |
| 237 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("collapseToStart", "Selection", "there is no selection.")); | 236 exceptionState.throwDOMException(InvalidStateError, "there is no selecti
on."); |
| 238 return; | 237 return; |
| 239 } | 238 } |
| 240 | 239 |
| 241 m_frame->selection().moveTo(VisiblePosition(selection.start(), DOWNSTREAM)); | 240 m_frame->selection().moveTo(VisiblePosition(selection.start(), DOWNSTREAM)); |
| 242 } | 241 } |
| 243 | 242 |
| 244 void DOMSelection::empty() | 243 void DOMSelection::empty() |
| 245 { | 244 { |
| 246 if (!m_frame) | 245 if (!m_frame) |
| 247 return; | 246 return; |
| 248 m_frame->selection().clear(); | 247 m_frame->selection().clear(); |
| 249 } | 248 } |
| 250 | 249 |
| 251 void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extent
Node, int extentOffset, ExceptionState& exceptionState) | 250 void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extent
Node, int extentOffset, ExceptionState& exceptionState) |
| 252 { | 251 { |
| 253 if (!m_frame) | 252 if (!m_frame) |
| 254 return; | 253 return; |
| 255 | 254 |
| 256 if (baseOffset < 0) { | 255 if (baseOffset < 0) { |
| 257 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::fail
edToExecute("setBaseAndExtent", "Selection", String::number(baseOffset) + " is n
ot a valid base offset.")); | 256 exceptionState.throwDOMException(IndexSizeError, String::number(baseOffs
et) + " is not a valid base offset."); |
| 258 return; | 257 return; |
| 259 } | 258 } |
| 260 | 259 |
| 261 if (extentOffset < 0) { | 260 if (extentOffset < 0) { |
| 262 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::fail
edToExecute("setBaseAndExtent", "Selection", String::number(extentOffset) + " is
not a valid extent offset.")); | 261 exceptionState.throwDOMException(IndexSizeError, String::number(extentOf
fset) + " is not a valid extent offset."); |
| 263 return; | 262 return; |
| 264 } | 263 } |
| 265 | 264 |
| 266 if (!isValidForPosition(baseNode) || !isValidForPosition(extentNode)) | 265 if (!isValidForPosition(baseNode) || !isValidForPosition(extentNode)) |
| 267 return; | 266 return; |
| 268 | 267 |
| 269 // FIXME: Eliminate legacy editing positions | 268 // FIXME: Eliminate legacy editing positions |
| 270 VisiblePosition visibleBase = VisiblePosition(createLegacyEditingPosition(ba
seNode, baseOffset), DOWNSTREAM); | 269 VisiblePosition visibleBase = VisiblePosition(createLegacyEditingPosition(ba
seNode, baseOffset), DOWNSTREAM); |
| 271 VisiblePosition visibleExtent = VisiblePosition(createLegacyEditingPosition(
extentNode, extentOffset), DOWNSTREAM); | 270 VisiblePosition visibleExtent = VisiblePosition(createLegacyEditingPosition(
extentNode, extentOffset), DOWNSTREAM); |
| 272 | 271 |
| 273 m_frame->selection().moveTo(visibleBase, visibleExtent); | 272 m_frame->selection().moveTo(visibleBase, visibleExtent); |
| 274 } | 273 } |
| 275 | 274 |
| 276 void DOMSelection::setPosition(Node* node, int offset, ExceptionState& exception
State) | 275 void DOMSelection::setPosition(Node* node, int offset, ExceptionState& exception
State) |
| 277 { | 276 { |
| 278 if (!m_frame) | 277 if (!m_frame) |
| 279 return; | 278 return; |
| 280 if (offset < 0) { | 279 if (offset < 0) { |
| 281 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::fail
edToExecute("setPosition", "Selection", String::number(offset) + " is not a vali
d offset.")); | 280 exceptionState.throwDOMException(IndexSizeError, String::number(offset)
+ " is not a valid offset."); |
| 282 return; | 281 return; |
| 283 } | 282 } |
| 284 | 283 |
| 285 if (!isValidForPosition(node)) | 284 if (!isValidForPosition(node)) |
| 286 return; | 285 return; |
| 287 | 286 |
| 288 // FIXME: Eliminate legacy editing positions | 287 // FIXME: Eliminate legacy editing positions |
| 289 m_frame->selection().moveTo(VisiblePosition(createLegacyEditingPosition(node
, offset), DOWNSTREAM)); | 288 m_frame->selection().moveTo(VisiblePosition(createLegacyEditingPosition(node
, offset), DOWNSTREAM)); |
| 290 } | 289 } |
| 291 | 290 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 | 337 |
| 339 m_frame->selection().modify(alter, direction, granularity); | 338 m_frame->selection().modify(alter, direction, granularity); |
| 340 } | 339 } |
| 341 | 340 |
| 342 void DOMSelection::extend(Node* node, int offset, ExceptionState& exceptionState
) | 341 void DOMSelection::extend(Node* node, int offset, ExceptionState& exceptionState
) |
| 343 { | 342 { |
| 344 if (!m_frame) | 343 if (!m_frame) |
| 345 return; | 344 return; |
| 346 | 345 |
| 347 if (!node) { | 346 if (!node) { |
| 348 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::f
ailedToExecute("extend", "Selection", "The node provided is invalid.")); | 347 exceptionState.throwDOMException(TypeMismatchError, "The node provided i
s invalid."); |
| 349 return; | 348 return; |
| 350 } | 349 } |
| 351 | 350 |
| 352 if (offset < 0) { | 351 if (offset < 0) { |
| 353 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::fail
edToExecute("extend", "Selection", String::number(offset) + " is not a valid off
set.")); | 352 exceptionState.throwDOMException(IndexSizeError, String::number(offset)
+ " is not a valid offset."); |
| 354 return; | 353 return; |
| 355 } | 354 } |
| 356 if (offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node-
>childNodeCount())) { | 355 if (offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node-
>childNodeCount())) { |
| 357 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::fail
edToExecute("extend", "Selection", String::number(offset) + " is larger than the
given node's length.")); | 356 exceptionState.throwDOMException(IndexSizeError, String::number(offset)
+ " is larger than the given node's length."); |
| 358 return; | 357 return; |
| 359 } | 358 } |
| 360 | 359 |
| 361 if (!isValidForPosition(node)) | 360 if (!isValidForPosition(node)) |
| 362 return; | 361 return; |
| 363 | 362 |
| 364 // FIXME: Eliminate legacy editing positions | 363 // FIXME: Eliminate legacy editing positions |
| 365 m_frame->selection().setExtent(VisiblePosition(createLegacyEditingPosition(n
ode, offset), DOWNSTREAM)); | 364 m_frame->selection().setExtent(VisiblePosition(createLegacyEditingPosition(n
ode, offset), DOWNSTREAM)); |
| 366 } | 365 } |
| 367 | 366 |
| 368 PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionState& exceptionS
tate) | 367 PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionState& exceptionS
tate) |
| 369 { | 368 { |
| 370 if (!m_frame) | 369 if (!m_frame) |
| 371 return 0; | 370 return 0; |
| 372 | 371 |
| 373 if (index < 0 || index >= rangeCount()) { | 372 if (index < 0 || index >= rangeCount()) { |
| 374 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::fail
edToExecute("getRangeAt", "Selection", String::number(index) + " is not a valid
index.")); | 373 exceptionState.throwDOMException(IndexSizeError, String::number(index) +
" is not a valid index."); |
| 375 return 0; | 374 return 0; |
| 376 } | 375 } |
| 377 | 376 |
| 378 // If you're hitting this, you've added broken multi-range selection support | 377 // If you're hitting this, you've added broken multi-range selection support |
| 379 ASSERT(rangeCount() == 1); | 378 ASSERT(rangeCount() == 1); |
| 380 | 379 |
| 381 if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) { | 380 if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) { |
| 382 ContainerNode* container = shadowAncestor->parentNodeGuaranteedHostFree(
); | 381 ContainerNode* container = shadowAncestor->parentNodeGuaranteedHostFree(
); |
| 383 int offset = shadowAncestor->nodeIndex(); | 382 int offset = shadowAncestor->nodeIndex(); |
| 384 return Range::create(shadowAncestor->document(), container, offset, cont
ainer, offset); | 383 return Range::create(shadowAncestor->document(), container, offset, cont
ainer, offset); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 | 543 |
| 545 bool DOMSelection::isValidForPosition(Node* node) const | 544 bool DOMSelection::isValidForPosition(Node* node) const |
| 546 { | 545 { |
| 547 ASSERT(m_frame); | 546 ASSERT(m_frame); |
| 548 if (!node) | 547 if (!node) |
| 549 return true; | 548 return true; |
| 550 return node->document() == m_frame->document(); | 549 return node->document() == m_frame->document(); |
| 551 } | 550 } |
| 552 | 551 |
| 553 } // namespace WebCore | 552 } // namespace WebCore |
| OLD | NEW |