Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-24760

Copy and Paste problems with list and macro selections.

XMLWordPrintable

      Summary

      • Copy and pasting lists / sections with only partial selections does not behave in a reasonable manner.

      To fix:

      • Confirm desired behaviour is what we want
      • Need to make sure we have good automated test cases for these selection and copy-paste scenarios
      • Fix the underlying issues

      Copy and paste of original comments

      History from CAC

      Shannon GreyWalker

      "EPIC" BUG

      The conversation thread that culminated in this specific comment up above has shed light on what I think is a "super pattern" that collectively describes various specific bugs that users have been reporting with the cut/copy/paste/dragMove behavior of the 4.x editor. The most concise way to describe this "epic" bug is as follows:

      4.x editor does not consistently preserve and reproduce the semantic/visual structure (order and nesting) of a diverse set of selected elements when cutting/copying > pasting, or when drag-moving, into a new location

      Note that I'm stressing the semantic and visual structure of the selection, because the new editor makes it truly impossible to understand how the start and end points of the selection correspond to the specific start and end tags of the underlying selection in the XML storage format of the page. Therefore, all your users can rely on is what they see in the rendered/styled text within the editor. And what they see is always clearly representative of a semantic structure that has a specific order and nesting of semantic elements.

      I would very much like to see a single JIRA issue number assigned to this overarching "epic" bug so that I can track a single JIRA ticket instead of multiple more granular JIRA tickets. Why? Because IMO this is one more "showstopper" issue that will prevent my company from migrating from 3.5.x to 4.x. Now that I've been banging specifically on copy/cut/paste/dragMove mechanics and seeing how truly dysfunctional the overall behavior currently is even in 4.1.5, I cannot give a green light internally to migration until the meta-issue I describe above is fully resolved in the most typical use cases. Now that I understand that these problems are essentially all bugs and not "behavior as designed, which can be managed correctly through some common conceptual workarounds", I cannot force this confusing behavior on my user base.

      It's worth noting that in the old wiki syntax, what you select is always 100% obvious, and is exactly what you paste, and the resulting behavior is always 100% predictable. So this is an entirely new problem introduced with the 4.x environment. Remember, moving things around in and between pages is at least 50% or more of what your heads-down users spend their time doing in the editor. Writing is mostly revision.

      I strongly recommend that once you get this "epic" bug resolved, you create several functional tests based on several test pages that you always faithfully run during regression for every single point release of Confluence, and you do not release if any of those functional tests fail. Why, again because cut/copy/paste/dragMove is at least 50% of what your users spend every hour in Confluence actually doing. Your code for cut/copy/paste/dragMove needs to be 100% reliable and predictable based upon what your users can actually see and infer in the rendered WYSIsortaWYG text in the editor. It was 100% reliable before in wiki syntax mode, so it needs to be the same in 4.x or we have a net loss and lots of confused and pissed-off users.

      Here are two specific and common functional tests I can think of off the top of my head. Both of these also serve to illustrate the meta pattern I describe above for this "epic" bug:

      Functional Test 1 - Cut and paste within an ordered list
      Test object
          1. This is originally step 1
             a. This is originally step 1.a
             b. This is originally step 1.b
          2. This is originally step 2
             a. This is originally step 2.a
             b. This is originally step 2.b
             c. This is originally step 2.c
          3. This is originally step 3
             a. This is originally step 3.a
             b. This is originally step 3.b
             c. This is originally step 3.c
          4. This is originally step 4
      
      Sub Test 1.1 - Select from start of semantic parent, paste before start of another semantic parent
      1. Select from the first character of the text within parent Step 3 through:
        1. The last character of the text within child Step 3.b.
        2. The last character of the text within child Step 3.b, and then press Shift + rightArrow one time to extend the selection highlight to the right margin of the editor frame.
        3. Also select the entire scope of Step 3 > 3.a > 3.b by placing the selection point immediately before the first character of the text within parent Step 3, then using Shift + downArrow three times to extend the selection highlight to the right margin of the editor frame for Step 3.b.
        4. The middle of the text within child Step 3.b (end just before the word "originally").
      2. Cut the selection.
      3. Place the selection point immediately before the first character of the text within Step 2.
      4. Paste the cut selection.

      Selection types 1.a, 1.b, and 1.c should all yield the same expected semantic result when pasted, as follows:

          1. This is originally step 1
             a. This is originally step 1.a
             b. This is originally step 1.b
          2. This is originally step 3
             a. This is originally step 3.a
             b. This is originally step 3.b
          3. This is originally step 2
             a. This is originally step 2.a
             b. This is originally step 2.b
             c. This is originally step 2.c
             d. This is originally step 3.c
          4. This is originally step 4
      

      Selection type 1.d should yield the following expected semantic result when pasted:

          1. This is originally step 1
             a. This is originally step 1.a
             b. This is originally step 1.b
          2. This is originally step 3
             a. This is originally step 3.a
             b. This is originally step 3.b
             c. This is
          3. This is originally step 2
             a. This is originally step 2.a
             b. This is originally step 2.b
             c. This is originally step 2.c
             d. originally step 3.c
          4. This is originally step 4
      
      Sub Test 1.2 - Select from middle of semantic parent, paste before start of another semantic parent
      1. Select from the middle of the text within parent Step 3 (start just before the word "originally") through:
        1. The last character of the text within child Step 3.b.
        2. The last character of the text within child Step 3.b, and then press Shift + rightArrow one time to extend the selection highlight to the right margin of the editor frame.
        3. Also select the entire scope of Step 3 > 3.a > 3.b by placing the selection point immediately before the first character of the text within parent Step 3, then using Shift + downArrow three times to extend the selection highlight to the right margin of the editor frame for Step 3.b.
        4. The middle of the text within child Step 3.b (end just before the word "originally").
      2. Cut the selection.
      3. Place the selection point immediately before the first character of the text within Step 2.
      4. Paste the cut selection.

      Selection types 1.a, 1.b, and 1.c should all yield the same expected semantic result when pasted, as follows:

          1. This is originally step 1
              a. This is originally step 1.a
              b. This is originally step 1.b
          2. originally step 3
              a. This is originally step 3.a
              b. This is originally step 3.b
          3. This is originally step 2
              a. This is originally step 2.a
              b. This is originally step 2.b
              c. This is originally step 2.c
          4. This is
              a. This is originally step 3.c
          5. This is originally step 4
      

      Selection type 1.d should yield the following expected semantic result when pasted:

          1. This is originally step 1
              a. This is originally step 1.a
              b. This is originally step 1.b
          2. originally step 3
              a. This is originally step 3.a
              b. This is originally step 3.b
              c. This is
          3. This is originally step 2
              a. This is originally step 2.a
              b. This is originally step 2.b
              c. This is originally step 2.c
          4. This is
              a. originally step 3.c
          5. This is originally step 4
      
      Sub Test 1.3 - Select from start of semantic parent, paste in middle of another semantic parent
      1. Select from the first character of the text within parent Step 3 through:
        1. The last character of the text within child Step 3.b.
        2. The last character of the text within child Step 3.b, and then press Shift + rightArrow one time to extend the selection highlight to the right margin of the editor frame.
        3. Also select the entire scope of Step 3 > 3.a > 3.b by placing the selection point immediately before the first character of the text within parent Step 3, then using Shift + downArrow three times to extend the selection highlight to the right margin of the editor frame for Step 3.b.
        4. The middle of the text within child Step 3.b (end just before the word "originally").
      2. Cut the selection.
      3. Place the selection point in the middle of the text within Step 2 (just before the word "originally").
      4. Paste the cut selection.

      Selection types 1.a, 1.b, and 1.c should all yield the same expected semantic result when pasted, as follows:

          1. This is originally step 1
              a. This is originally step 1.a
              b. This is originally step 1.b
          2. This is 
          3. This is originally step 3
              a. This is originally step 3.a
              b. This is originally step 3.b
          4. originally step 2
              a. This is originally step 2.a
              b. This is originally step 2.b
              c. This is originally step 2.c
              d. This is originally step 3.c
          5. This is originally step 4
      

      Selection type 1.d should yield the following expected semantic result when pasted:

          1. This is originally step 1
              a. This is originally step 1.a
              b. This is originally step 1.b
          2. This is
          3. This is originally step 3
              a. This is originally step 3.a
              b. This is originally step 3.b
              c. This is
          4. originally step 2
              a. This is originally step 2.a
              b. This is originally step 2.b
              c. This is originally step 2.c
              d. originally step 3.c
          5. This is originally step 4
      
      Sub Test 1.4 - Select from middle of semantic parent, paste in middle of another semantic parent
      1. Select from the middle of the text within parent Step 3 (start just before the word "originally") through:
        1. The last character of the text within child Step 3.b.
        2. The last character of the text within child Step 3.b, and then press Shift + rightArrow one time to extend the selection highlight to the right margin of the editor frame.
        3. Also select the entire scope of Step 3 > 3.a > 3.b by placing the selection point immediately before the first character of the text within parent Step 3, then using Shift + downArrow three times to extend the selection highlight to the right margin of the editor frame for Step 3.b.
        4. The middle of the text within child Step 3.b (end just before the word "originally").
      2. Cut the selection.
      3. Place the selection point in the middle of the text within Step 2 (just before the word "originally").
      4. Paste the cut selection.

      Selection types 1.a, 1.b, and 1.c should all yield the same expected semantic result when pasted, as follows:

          1. This is originally step 1
              a. This is originally step 1.a
              b. This is originally step 1.b
          2. This is 
          3. originally step 3
              a. This is originally step 3.a
              b. This is originally step 3.b
          4. originally step 2
              a. This is originally step 2.a
              b. This is originally step 2.b
              c. This is originally step 2.c
          5. This is
              a. This is originally step 3.c
          6. This is originally step 4
      

      Selection type 1.d should yield the following expected semantic result when pasted:

          1. This is originally step 1
              a. This is originally step 1.a
              b. This is originally step 1.b
          2. This is
          3. originally step 3
              a. This is originally step 3.a
              b. This is originally step 3.b
              c. This is
          4. originally step 2
              a. This is originally step 2.a
              b. This is originally step 2.b
              c. This is originally step 2.c
          5. This is
              a. originally step 3.c
          6. This is originally step 4
      
      Functional Test 2 - Cut and paste within a mixed set of nested macros, sections, and paragraphs
      Test object

      This is hard to simulate in JIRA, so see


      Section 1

      lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah

      • blah blah
      • blah blah
      • blah blah

      lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah

      Section 2

      lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah

      lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah

      <warning macro>
      lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah

      • blah blah
      • blah blah
        <warning macro>

      lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah

      • blah blah
      • blah blah

      lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah

      Section 3

      lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah lorem ipsum blah blah


      Sub Tests

      Okay I'm not going to make another long vertical wall of specific tests and expected results here, because hopefully you see how the same testing pattern enumerated for the ordered list test object would be applied to this new test object comprising a semantic mixed content model for common combinations of paragraph and list block elements plus some nested macro objects (each of which contains a mixture of typical paragraph and list block elements.

      The basic idea is to apply the same four tests here to this new test object, ideally within Section 2 because it contains the most complex mixture of semantic objects.

      • Sub Test 2.1 - Select from start of one semantic parent, paste before start of another semantic parent. For example, what would you intuitively expect to happen if you selected the entire panel macro in Section 2 and then pasted the selection with your insertion point immediately before the first character of the first bullet in the bullet list of Section 1. Yeah, you see where I'm going here, right? Do you get this intuitively expected result right now? Nope.
      • Sub Test 2.2 - Select from start of one semantic parent, paste in middle of another semantic parent. I won't bore you with examples. I hope you get it by now.
      • Sub Test 2.3 - Select from middle of one semantic parent, paste before start of another semantic parent. Yada yada.
      • Sub Test 2.4 - Select from middle of one semantic parent, paste in middle of another semantic parent. Yada yada.

      The bottom line with all these functional test objects and the four typical semantic cut/copy/paste/dragMove sub tests to perform on each one boils down to one intuitively expected UX pattern:

      • Structurally speaking, the clipped/pasted result of a selection should be the exact same whether the selection's end-point is at the end of a visible text line in the editor or the end-point is at the right margin. Yes, under the covers this subtle distinction makes for a different range in the tinyMCE's information it gets from the browser, but for a user looking at the screen, there is no distinction; it's the same exact thing. Your code should reflect this user perception and should not reflect the actual technical distinction under the covers in the DOM.
      • The complete visual and semantic structure of the clipped selection should be preserved and reproduced exactly the same in the new, pasted context, AND
      • The visual and semantic structure into which you pasted the clipped selection should "split" around the inserted paste and that split structure should be maintained with the same exact structure in both halves of the split.
      • When you have to make a decision between acting upon what's really selected (or where the insertion point is) based on the underlying DOM of the selection range reported by the browser versus what the user sees visually in the editor and thinks of as being "the semantic objects I've selected", you should always decide in favor of what the user visually and conceptually sees with their own eyes.
      • Good luck with this. I'm sure it can be done. The question is: how soon? And what JIRA issue number do I track to watch for completion of this?

      Paul Curren

      Hi Shannon. I apologise for the delay in responding to this comment. I've been in contact with our bug-fixing team to go through the issues you have described here. We will get one or more issues raised soon, as appropriate and let you know the numbers for tracking purposes.

      Thanks.


      Shannon Greywalker

      Thanks Paul. I know it was a lot to chew on and spec out. No worries; thanks for the update.

              fhe@atlassian.com Franklin He (Inactive)
              ffe0c07824fd Shannon Greywalker
              Votes:
              15 Vote for this issue
              Watchers:
              23 Start watching this issue

                Created:
                Updated:
                Resolved: