Bug 1253989 Part 5 - Remove touch caret and selection carets naming. r=mtseng
authorTing-Yu Lin <tlin@mozilla.com>
Tue, 08 Mar 2016 22:45:47 +0800
changeset 287426 ba096724ac7ce2bed4741b3b68668e924552db61
parent 287425 c0fdb08d2254c5c75e7173233f4d2decabf23738
child 287427 c575320f1d603d726cabb777d522e12b647018d8
push id30068
push usercbook@mozilla.com
push dateWed, 09 Mar 2016 10:46:58 +0000
treeherdermozilla-central@af7c0cb0798f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmtseng
bugs1253989
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1253989 Part 5 - Remove touch caret and selection carets naming. r=mtseng - To avoid confusion, call the blinking cursor (nsCaret) "cursor" so that AccessibleCaret can be called caret for short. - Add second_caret_location() as a helper function, and use it in selection mode tests. MozReview-Commit-ID: IKN6KuR92HE
layout/base/tests/marionette/test_accessiblecaret_cursor_mode.py
layout/base/tests/marionette/test_accessiblecaret_selection_mode.py
testing/marionette/client/marionette_driver/selection.py
--- a/layout/base/tests/marionette/test_accessiblecaret_cursor_mode.py
+++ b/layout/base/tests/marionette/test_accessiblecaret_cursor_mode.py
@@ -46,82 +46,82 @@ class AccessibleCaretCursorModeTestCase(
     def test_move_cursor_to_the_right_by_one_character(self, el_id):
         self.open_test_html()
         el = self.marionette.find_element(By.ID, el_id)
         sel = SelectionManager(el)
         content_to_add = '!'
         target_content = sel.content
         target_content = target_content[:1] + content_to_add + target_content[1:]
 
-        # Get touch caret (x, y) at position 1 and 2.
+        # Get first caret (x, y) at position 1 and 2.
         el.tap()
-        sel.move_caret_to_front()
-        caret0_x, caret0_y = sel.caret_location()
-        touch_caret0_x, touch_caret0_y = sel.touch_caret_location()
-        sel.move_caret_by_offset(1)
-        touch_caret1_x, touch_caret1_y = sel.touch_caret_location()
+        sel.move_cursor_to_front()
+        cursor0_x, cursor0_y = sel.cursor_location()
+        first_caret0_x, first_caret0_y = sel.first_caret_location()
+        sel.move_cursor_by_offset(1)
+        first_caret1_x, first_caret1_y = sel.first_caret_location()
 
-        # Tap the front of the input to make touch caret appear.
-        el.tap(caret0_x, caret0_y)
+        # Tap the front of the input to make first caret appear.
+        el.tap(cursor0_x, cursor0_y)
 
-        # Move touch caret
-        self.actions.flick(el, touch_caret0_x, touch_caret0_y,
-                           touch_caret1_x, touch_caret1_y).perform()
+        # Move first caret.
+        self.actions.flick(el, first_caret0_x, first_caret0_y,
+                           first_caret1_x, first_caret1_y).perform()
 
         self.actions.key_down(content_to_add).key_up(content_to_add).perform()
         self.assertEqual(target_content, sel.content)
 
     @parameterized(_input_id, el_id=_input_id)
     @parameterized(_textarea_id, el_id=_textarea_id)
     @parameterized(_contenteditable_id, el_id=_contenteditable_id)
     def test_move_cursor_to_end_by_dragging_caret_to_bottom_right_corner(self, el_id):
         self.open_test_html()
         el = self.marionette.find_element(By.ID, el_id)
         sel = SelectionManager(el)
         content_to_add = '!'
         target_content = sel.content + content_to_add
 
-        # Tap the front of the input to make touch caret appear.
+        # Tap the front of the input to make first caret appear.
         el.tap()
-        sel.move_caret_to_front()
-        el.tap(*sel.caret_location())
+        sel.move_cursor_to_front()
+        el.tap(*sel.cursor_location())
 
-        # Move touch caret to the bottom-right corner of the element.
-        src_x, src_y = sel.touch_caret_location()
+        # Move first caret to the bottom-right corner of the element.
+        src_x, src_y = sel.first_caret_location()
         dest_x, dest_y = el.size['width'], el.size['height']
         self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform()
 
         self.actions.key_down(content_to_add).key_up(content_to_add).perform()
         self.assertEqual(target_content, sel.content)
 
     @parameterized(_input_id, el_id=_input_id)
     @parameterized(_textarea_id, el_id=_textarea_id)
     @parameterized(_contenteditable_id, el_id=_contenteditable_id)
     def test_move_cursor_to_front_by_dragging_caret_to_front(self, el_id):
         self.open_test_html()
         el = self.marionette.find_element(By.ID, el_id)
         sel = SelectionManager(el)
         content_to_add = '!'
         target_content = content_to_add + sel.content
 
-        # Get touch caret location at the front.
+        # Get first caret location at the front.
         el.tap()
-        sel.move_caret_to_front()
-        dest_x, dest_y = sel.touch_caret_location()
+        sel.move_cursor_to_front()
+        dest_x, dest_y = sel.first_caret_location()
 
-        # Tap to make touch caret appear. Note: it's strange that when the caret
+        # Tap to make first caret appear. Note: it's strange that when the caret
         # is at the end, the rect of the caret in <textarea> cannot be obtained.
         # A bug perhaps.
         el.tap()
-        sel.move_caret_to_end()
-        sel.move_caret_by_offset(1, backward=True)
-        el.tap(*sel.caret_location())
-        src_x, src_y = sel.touch_caret_location()
+        sel.move_cursor_to_end()
+        sel.move_cursor_by_offset(1, backward=True)
+        el.tap(*sel.cursor_location())
+        src_x, src_y = sel.first_caret_location()
 
-        # Move touch caret to the front of the input box.
+        # Move first caret to the front of the input box.
         self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform()
 
         self.actions.key_down(content_to_add).key_up(content_to_add).perform()
         self.assertEqual(target_content, sel.content)
 
     @parameterized(_input_id, el_id=_input_id)
     @parameterized(_textarea_id, el_id=_textarea_id)
     @parameterized(_contenteditable_id, el_id=_contenteditable_id)
@@ -134,51 +134,51 @@ class AccessibleCaretCursorModeTestCase(
 
         # Set caret timeout to be 1 second.
         timeout = 1
         self.marionette.set_pref(self.caret_timeout_ms_pref, timeout * 1000)
 
         # Set a 3x timeout margin to prevent intermittent test failures.
         timeout *= 3
 
-        # Tap to make touch caret appear. Note: it's strange that when the caret
+        # Tap to make first caret appear. Note: it's strange that when the caret
         # is at the end, the rect of the caret in <textarea> cannot be obtained.
         # A bug perhaps.
         el.tap()
-        sel.move_caret_to_end()
-        sel.move_caret_by_offset(1, backward=True)
-        el.tap(*sel.caret_location())
+        sel.move_cursor_to_end()
+        sel.move_cursor_by_offset(1, backward=True)
+        el.tap(*sel.cursor_location())
 
-        # Wait until touch caret disappears, then pretend to move it to the
+        # Wait until first caret disappears, then pretend to move it to the
         # top-left corner of the input box.
-        src_x, src_y = sel.touch_caret_location()
+        src_x, src_y = sel.first_caret_location()
         dest_x, dest_y = 0, 0
         self.actions.wait(timeout).flick(el, src_x, src_y, dest_x, dest_y).perform()
 
         self.actions.key_down(content_to_add).key_up(content_to_add).perform()
         self.assertNotEqual(non_target_content, sel.content)
 
     def test_caret_not_appear_when_typing_in_scrollable_content(self):
         self.open_test_html()
         el = self.marionette.find_element(By.ID, self._input_id)
         sel = SelectionManager(el)
         content_to_add = '!'
         target_content = sel.content + string.ascii_letters + content_to_add
 
         el.tap()
-        sel.move_caret_to_end()
+        sel.move_cursor_to_end()
 
         # Insert a long string to the end of the <input>, which triggers
         # ScrollPositionChanged event.
         el.send_keys(string.ascii_letters)
 
         # The caret should not be visible. If it does appear wrongly due to the
         # ScrollPositionChanged event, we can drag it to the front of the
         # <input> to change the cursor position.
-        src_x, src_y = sel.touch_caret_location()
+        src_x, src_y = sel.first_caret_location()
         dest_x, dest_y = 0, 0
         self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform()
 
         # The content should be inserted at the end of the <input>.
         el.send_keys(content_to_add)
 
         self.assertEqual(target_content, sel.content)
 
@@ -187,16 +187,16 @@ class AccessibleCaretCursorModeTestCase(
         el = self.marionette.find_element(By.ID, self._input_id)
         sel = SelectionManager(el)
         content_to_add = '!'
         non_target_content = sel.content + content_to_add
 
         # Goal: the cursor position does not being changed after dragging the
         # caret down on the Y-axis.
         el.tap()
-        sel.move_caret_to_front()
-        el.tap(*sel.caret_location())
-        x, y = sel.touch_caret_location()
+        sel.move_cursor_to_front()
+        el.tap(*sel.cursor_location())
+        x, y = sel.first_caret_location()
 
         # Drag the caret down by 50px, and insert '!'.
         self.actions.flick(el, x, y, x, y + 50).perform()
         self.actions.key_down(content_to_add).key_up(content_to_add).perform()
         self.assertNotEqual(non_target_content, sel.content)
--- a/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py
+++ b/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py
@@ -91,19 +91,19 @@ class AccessibleCaretSelectionModeTestCa
         target element el.
 
         '''
         sel = SelectionManager(el)
         offset = self.word_offset(sel.content, ordinal)
 
         # Move the blinking cursor to the word.
         el.tap()
-        sel.move_caret_to_front()
-        sel.move_caret_by_offset(offset)
-        x, y = sel.caret_location()
+        sel.move_cursor_to_front()
+        sel.move_cursor_by_offset(offset)
+        x, y = sel.cursor_location()
 
         return x, y
 
     def rect_relative_to_window(self, el):
         '''Get element's bounding rectangle.
 
         This function is similar to el.rect, but the coordinate is relative to
         the top left corner of the window instead of the document.
@@ -183,26 +183,26 @@ class AccessibleCaretSelectionModeTestCa
         sel = SelectionManager(el)
         original_content = sel.content
         words = original_content.split()
         self.assertTrue(len(words) >= 1, 'Expect at least one word in the content.')
 
         # Goal: Select all text after the first word.
         target_content = original_content[len(words[0]):]
 
-        # Get the location of the selection carets at the end of the content for
-        # later use.
+        # Get the location of the carets at the end of the content for later
+        # use.
         el.tap()
         sel.select_all()
-        (_, _), (end_caret_x, end_caret_y) = sel.selection_carets_location()
+        end_caret_x, end_caret_y = sel.second_caret_location()
 
         self.long_press_on_word(el, 0)
 
         # Drag the second caret to the end of the content.
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
         self.actions.flick(el, caret2_x, caret2_y, end_caret_x, end_caret_y).perform()
 
         # Drag the first caret to the previous position of the second caret.
         self.actions.flick(el, caret1_x, caret1_y, caret2_x, caret2_y).perform()
 
         self.assertEqual(target_content, sel.selected_content)
 
     @parameterized(_input_id, el_id=_input_id)
@@ -224,39 +224,39 @@ class AccessibleCaretSelectionModeTestCa
         self._test_minimum_select_one_character(el)
 
     def _test_minimum_select_one_character(self, el, x=None, y=None):
         sel = SelectionManager(el)
         original_content = sel.content
         words = original_content.split()
         self.assertTrue(len(words) >= 1, 'Expect at least one word in the content.')
 
-        # Get the location of the selection carets at the end of the content for
-        # later use.
+        # Get the location of the carets at the end of the content for later
+        # use.
         sel.select_all()
-        (_, _), (end_caret_x, end_caret_y) = sel.selection_carets_location()
+        end_caret_x, end_caret_y = sel.second_caret_location()
         el.tap()
 
         # Goal: Select the first character.
         target_content = original_content[0]
 
         if x and y:
             # If we got x and y from the arguments, use it as a hint of the
             # location of the first word
             pass
         else:
             x, y = self.word_location(el, 0)
         self.long_press_on_location(el, x, y)
 
         # Drag the second caret to the end of the content.
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
         self.actions.flick(el, caret2_x, caret2_y, end_caret_x, end_caret_y).perform()
 
         # Drag the second caret to the position of the first caret.
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
         self.actions.flick(el, caret2_x, caret2_y, caret1_x, caret1_y).perform()
 
         self.assertEqual(target_content, sel.selected_content)
 
     @parameterized(_input_id + '_to_' + _textarea_id,
                    el1_id=_input_id, el2_id=_textarea_id)
     @parameterized(_input_id + '_to_' + _contenteditable_id,
                    el1_id=_input_id, el2_id=_contenteditable_id)
@@ -338,24 +338,24 @@ class AccessibleCaretSelectionModeTestCa
         self.assertTrue(len(words) >= 1, 'Expect at least one word in the content.')
 
         # Goal: Select the first word.
         self.long_press_on_word(el, 0)
         target_content = sel.selected_content
 
         # Drag the first caret to the position of the second caret to trigger
         # carets overlapping.
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
         self.actions.flick(el, caret1_x, caret1_y, caret2_x, caret2_y).perform()
 
         # We make two hit tests targeting the left edge of the left tilted caret
         # and the right edge of the right tilted caret. If either of the hits is
         # missed, selection would be collapsed and both carets should not be
         # draggable.
-        (caret3_x, caret3_y), (caret4_x, caret4_y) = sel.selection_carets_location()
+        (caret3_x, caret3_y), (caret4_x, caret4_y) = sel.carets_location()
 
         # The following values are from ua.css and all.js
         caret_width = float(self.marionette.get_pref('layout.accessiblecaret.width'))
         caret_margin_left = float(self.marionette.get_pref('layout.accessiblecaret.margin-left'))
         tilt_right_margin_left = 0.41 * caret_width
         tilt_left_margin_left = -0.39 * caret_width
 
         left_caret_left_edge_x = caret3_x + caret_margin_left + tilt_left_margin_left
@@ -366,72 +366,75 @@ class AccessibleCaretSelectionModeTestCa
         el.tap(right_caret_right_edge_x - 2, caret4_y)
 
         # Drag the first caret back to the initial selection, the first word.
         self.actions.flick(el, caret3_x, caret3_y, caret1_x, caret1_y).perform()
 
         self.assertEqual(target_content, sel.selected_content)
 
     def test_drag_caret_over_non_selectable_field(self):
-        '''Testing drag caret over non selectable field.
-        So that the selected content should exclude non selectable field and
-        end selection caret should appear in last range's position.'''
+        '''Test dragging the caret over a non-selectable field.
+
+        The selected content should exclude non-selectable elements and the
+        second caret should appear in last range's position.
+
+        '''
         self.open_test_html_multirange()
         body = self.marionette.find_element(By.ID, 'bd')
         sel3 = self.marionette.find_element(By.ID, 'sel3')
         sel4 = self.marionette.find_element(By.ID, 'sel4')
         sel6 = self.marionette.find_element(By.ID, 'sel6')
 
         # Select target element and get target caret location
         self.long_press_on_word(sel4, 3)
         sel = SelectionManager(body)
-        (_, _), (end_caret_x, end_caret_y) = sel.selection_carets_location()
+        end_caret_x, end_caret_y = sel.second_caret_location()
 
         self.long_press_on_word(sel6, 0)
-        (_, _), (end_caret2_x, end_caret2_y) = sel.selection_carets_location()
+        end_caret2_x, end_caret2_y = sel.second_caret_location()
 
         # Select start element
         self.long_press_on_word(sel3, 3)
 
         # Drag end caret to target location
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
         self.actions.flick(body, caret2_x, caret2_y, end_caret_x, end_caret_y, 1).perform()
         self.assertEqual(self.to_unix_line_ending(sel.selected_content.strip()),
                          'this 3\nuser can select this')
 
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
         self.actions.flick(body, caret2_x, caret2_y, end_caret2_x, end_caret2_y, 1).perform()
         self.assertEqual(self.to_unix_line_ending(sel.selected_content.strip()),
                          'this 3\nuser can select this 4\nuser can select this 5\nuser')
 
         # Drag first caret to target location
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
         self.actions.flick(body, caret1_x, caret1_y, end_caret_x, end_caret_y, 1).perform()
         self.assertEqual(self.to_unix_line_ending(sel.selected_content.strip()),
                          '4\nuser can select this 5\nuser')
 
     def test_drag_caret_to_beginning_of_a_line(self):
         '''Bug 1094056
         Test caret visibility when caret is dragged to beginning of a line
         '''
         self.open_test_html_multirange()
         body = self.marionette.find_element(By.ID, 'bd')
         sel1 = self.marionette.find_element(By.ID, 'sel1')
         sel2 = self.marionette.find_element(By.ID, 'sel2')
 
         # Select the first word in the second line
         self.long_press_on_word(sel2, 0)
         sel = SelectionManager(body)
-        (start_caret_x, start_caret_y), (end_caret_x, end_caret_y) = sel.selection_carets_location()
+        (start_caret_x, start_caret_y), (end_caret_x, end_caret_y) = sel.carets_location()
 
         # Select target word in the first line
         self.long_press_on_word(sel1, 2)
 
         # Drag end caret to the beginning of the second line
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
         self.actions.flick(body, caret2_x, caret2_y, start_caret_x, start_caret_y).perform()
 
         # Drag end caret back to the target word
         self.actions.flick(body, start_caret_x, start_caret_y, caret2_x, caret2_y).perform()
 
         self.assertEqual(self.to_unix_line_ending(sel.selected_content), 'select')
 
     @skip_if_not_rotatable
@@ -444,19 +447,19 @@ class AccessibleCaretSelectionModeTestCa
 
         body = self.marionette.find_element(By.ID, 'bd')
         longtext = self.marionette.find_element(By.ID, 'longtext')
 
         # Select word in portrait mode, then change to landscape mode
         self.marionette.set_orientation('portrait')
         self.long_press_on_word(longtext, 12)
         sel = SelectionManager(body)
-        (p_start_caret_x, p_start_caret_y), (p_end_caret_x, p_end_caret_y) = sel.selection_carets_location()
+        (p_start_caret_x, p_start_caret_y), (p_end_caret_x, p_end_caret_y) = sel.carets_location()
         self.marionette.set_orientation('landscape')
-        (l_start_caret_x, l_start_caret_y), (l_end_caret_x, l_end_caret_y) = sel.selection_carets_location()
+        (l_start_caret_x, l_start_caret_y), (l_end_caret_x, l_end_caret_y) = sel.carets_location()
 
         # Drag end caret to the start caret to change the selected content
         self.actions.flick(body, l_end_caret_x, l_end_caret_y,
                            l_start_caret_x, l_start_caret_y).perform()
 
         # Change orientation back to portrait mode to prevent affecting
         # other tests
         self.marionette.set_orientation('portrait')
@@ -534,34 +537,34 @@ class AccessibleCaretSelectionModeTestCa
         self.assertEqual(words[1], sel.selected_content)
 
         self.long_press_on_location(el, word0_x, word0_y)
         self.assertEqual(words[0], sel.selected_content)
 
         # If the second carets is visible, it can be dragged to the position of
         # the first caret. After that, selection will contain only the first
         # character.
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
         self.actions.flick(el, caret2_x, caret2_y, caret1_x, caret1_y).perform()
         self.assertEqual(words[0][0], sel.selected_content)
 
     def test_carets_do_not_jump_when_dragging_to_editable_content_boundary(self):
         self.open_test_html()
         el = self.marionette.find_element(By.ID, self._input_id)
         sel = SelectionManager(el)
         original_content = sel.content
         words = original_content.split()
         self.assertTrue(len(words) >= 3, 'Expect at least three words in the content.')
 
         # Goal: the selection does not being changed after dragging the caret
         # on the Y-axis only.
         target_content = words[1]
 
         self.long_press_on_word(el, 1)
-        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
+        (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
 
         # Drag the first caret up by 50px.
         self.actions.flick(el, caret1_x, caret1_y, caret1_x, caret1_y - 50).perform()
         self.assertEqual(target_content, sel.selected_content)
 
         # Drag the first caret down by 50px.
         self.actions.flick(el, caret2_x, caret2_y, caret2_x, caret2_y + 50).perform()
         self.assertEqual(target_content, sel.selected_content)
--- a/testing/marionette/client/marionette_driver/selection.py
+++ b/testing/marionette/client/marionette_driver/selection.py
@@ -2,16 +2,19 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 class SelectionManager(object):
     '''Interface for manipulating the selection and carets of the element.
 
+    We call the blinking cursor (nsCaret) as cursor, and call AccessibleCaret as
+    caret for short.
+
     Simple usage example:
 
     ::
 
         element = marionette.find_element('id', 'input')
         sel = SelectionManager(element)
         sel.move_caret_to_front()
 
@@ -36,45 +39,45 @@ class SelectionManager(object):
         '''
         if self._input_or_textarea():
             # We must unwrap sel so that DOMRect could be returned to Python
             # side.
             return '''var sel = arguments[0].editor.selection;'''
         else:
             return '''var sel = window.getSelection();'''
 
-    def move_caret_by_offset(self, offset, backward=False):
-        '''Move caret in the element by character offset.
+    def move_cursor_by_offset(self, offset, backward=False):
+        '''Move cursor in the element by character offset.
 
-        :param offset: Move the caret to the direction by offset characters.
+        :param offset: Move the cursor to the direction by offset characters.
         :param backward: Optional, True to move backward; Default to False to
          move forward.
 
         '''
         cmd = self.js_selection_cmd() + '''
               for (let i = 0; i < %d; ++i) {
                   sel.modify("move", "%s", "character");
               }
               ''' % (offset, 'backward' if backward else 'forward')
 
         self.element.marionette.execute_script(
             cmd, script_args=[self.element], sandbox='system')
 
-    def move_caret_to_front(self):
-        '''Move caret in the element to the front of the content.'''
+    def move_cursor_to_front(self):
+        '''Move cursor in the element to the front of the content.'''
         if self._input_or_textarea():
             cmd = '''arguments[0].setSelectionRange(0, 0);'''
         else:
             cmd = '''var sel = window.getSelection();
                   sel.collapse(arguments[0].firstChild, 0);'''
 
         self.element.marionette.execute_script(cmd, script_args=[self.element])
 
-    def move_caret_to_end(self):
-        '''Move caret in the element to the end of the content.'''
+    def move_cursor_to_end(self):
+        '''Move cursor in the element to the end of the content.'''
         if self._input_or_textarea():
             cmd = '''var len = arguments[0].value.length;
                   arguments[0].setSelectionRange(len, len);'''
         else:
             cmd = '''var sel = window.getSelection();
                   sel.collapse(arguments[0].lastChild, arguments[0].lastChild.length);'''
 
         self.element.marionette.execute_script(cmd, script_args=[self.element])
@@ -148,43 +151,52 @@ class SelectionManager(object):
         Return a tuple containing two pairs of (x, y) coordinates of the start
         and end of the selection. The coordinates are relative to the top
         left-hand corner of the element. Both ltr and rtl direction are
         considered.
 
         '''
         return self._selection_location_helper('center')
 
-    def selection_carets_location(self):
-        '''Return a pair of the two selection carets' location.
+    def carets_location(self):
+        '''Return a pair of the two carets' location.
 
         Return a tuple containing two pairs of (x, y) coordinates of the two
-        selection carets' tip. The coordinates are relative to the top left-hand
-        corner of the element. Both ltr and rtl direction are considered.
+        carets' tip. The coordinates are relative to the top left-hand corner of
+        the element. Both ltr and rtl direction are considered.
 
         '''
         return self._selection_location_helper('caret')
 
-    def caret_location(self):
-        '''Return caret's center location within the element.
+    def cursor_location(self):
+        '''Return the blanking cursor's center location within the element.
 
-        Return (x, y) coordinates of the caret's center relative to the top
+        Return (x, y) coordinates of the cursor's center relative to the top
         left-hand corner of the element.
 
         '''
         return self._selection_location_helper('center')[0]
 
-    def touch_caret_location(self):
-        '''Return touch caret's location (based on current caret location).
+    def first_caret_location(self):
+        '''Return the first caret's location.
 
-        Return (x, y) coordinates of the touch caret's tip relative to the top
+        Return (x, y) coordinates of the first caret's tip relative to the top
         left-hand corner of the element.
 
         '''
-        return self._selection_location_helper('caret')[0]
+        return self.carets_location()[0]
+
+    def second_caret_location(self):
+        '''Return the second caret's location.
+
+        Return (x, y) coordinates of the second caret's tip relative to the top
+        left-hand corner of the element.
+
+        '''
+        return self.carets_location()[1]
 
     def select_all(self):
         '''Select all the content in the element.'''
         if self._input_or_textarea():
             cmd = '''var len = arguments[0].value.length;
                   arguments[0].focus();
                   arguments[0].setSelectionRange(0, len);'''
         else: