Opened 10 years ago

Last modified 10 years ago

#11861 closed Bug

[Blink/Webkit] Span elements created while joining adjacent elements — at Version 5

Reported by: Olek Nowodziński Owned by: Olek Nowodziński
Priority: Normal Milestone: CKEditor 4.4.1
Component: General Version: 3.0
Keywords: Webkit Blink Cc: joel.peltonen@…

Description (last modified by Olek Nowodziński)

It's a follow-up of #9998, which covers a single case.


Example 1

  1. Set data
    <p>foo</p>
    <p>^bar</p>
    
  2. Backspace.
  3. <p>foo<span style="line-height:1.6">bar</span></p>
  4. Expected:
    <p>foo^bar</p>
    

Example 2

  1. Set data
    <h1>foo</h1>
    <p>^bar</p>
    
  2. Backspace.
  3. <h1>foo<span style="font-size:13px; line-height:1.6">bar</span></h1>
  4. Expected:
    <h1>foo^bar</h1>
    

Algorithm for collapsed selection

  1. Let's consider sample HTML and selection
    <div><p><em>x</em></p></div>
    <blockquote><p><strong>^y</strong></p></blockquote>
    
  1. BACKSPACE or DEL is pressed. We expect the contents of <blockquote><p>...</p></blockquote> to be merged with contents of <div><p>...</p></div>.
  1. Custom listener in editable listens on DEL and BACKSPACE. The listener is of lowest possible priority to not to interfere with existing code, which is supposed to deal with lists, non–editables, etc.
  1. Retrieve range from selection.
  1. Abort if range is not collapsed (then enter a different branch of the algorithm).
  1. Get elementPath out of the range (range.startPath()).
  1. Create walker, starting in path.block (<p><strong></p>). Starting from path.block solves the problem of bogus BR. In case of BACKSPACE, walker is supposed to walk back; in case of DEL – forward.
  1. walker determines if current case (DOM+selection) should be handled by the custom listener. It traverses DOM tree in search for blocks (when entering elements) and checks if current selection is anchored at the block boundary (when leaving elements).
  1. Abort, if no previous (BACKSPACE) or next (DEL) block is found or reached boundary of editable. Also abort if current selection is not at the block boundary.
  1. If previous (BACKSPACE – <div><p></div>) or next (DEL – none) block is found, a new range is created and moved to the closest editable position, according to the direction (back or forward with range.moveToClosestEditablePosition()<p><em>^</p> for BACKSPACE). This trick let us move from <div><p></div> up to <p><em></p> without hard, vertical traversing.
  1. Create new elementPath for the range once moved to the closest editable position. The block of this elementPath is our target place for elements to be moved.
  1. Create intrusive bookmarks (<strong>||y</strong>).
  1. Move all children from the block found in 6. to the one found in 10 (BACKSPACE: <strong>y</strong> joins <em>x</em>).
  1. Use element.mergeSiblings to clean up mess, which could emerge if, i.e.instead of <em>x</em> there was <strong>x</strong> so <strong>x</strong><strong>y</strong> is merged <strong>xy</strong>.
  1. Remove block found in 6.
  1. If block found in 6. (<p><was strong></p>) was the only meaningful element in DOM branch, cut it off.
  1. Restore bookmark saved in 11.
    <div><p><em>x</em><strong>^y</strong></p></div>
    

Change History (5)

comment:1 Changed 10 years ago by Olek Nowodziński

Description: modified (diff)

comment:2 Changed 10 years ago by Olek Nowodziński

Owner: set to Olek Nowodziński
Status: newassigned

comment:3 Changed 10 years ago by Piotrek Koszuliński

cc

comment:4 Changed 10 years ago by Olek Nowodziński

Keywords: Webkit Blink added
Summary: [Webkit] Span elements created while joining adjacent elements[Blink/Webkit] Span elements created while joining adjacent elements

comment:5 Changed 10 years ago by Olek Nowodziński

Description: modified (diff)
Note: See TracTickets for help on using tickets.
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy