Skip to content

Commit

Permalink
DOM: Restore horizontal edge traversal implementation (#8461)
Browse files Browse the repository at this point in the history
* Add a failing test for removing an empty first line.

* DOM: Restore horizontal edge traversal implementation

Co-Authored-By: iseulde
  • Loading branch information
aduth authored Aug 7, 2018
1 parent c1ddfb2 commit 41ff1f2
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 9 deletions.
57 changes: 48 additions & 9 deletions packages/dom/src/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,54 @@ export function isHorizontalEdge( container, isReverse ) {
range.collapse( ! isSelectionForward( selection ) );
}

const { endContainer, endOffset } = range;
range.selectNodeContents( container );
range.setEnd( endContainer, endOffset );

// Check if the caret position is at the expected start/end position based
// on the value of `isReverse`. If so, consider the horizontal edge to be
// reached.
const caretOffset = range.toString().length;
return caretOffset === ( isReverse ? 0 : container.textContent.length );
let node = range.startContainer;

let extentOffset;
if ( isReverse ) {
// When in reverse, range node should be first.
extentOffset = 0;
} else if ( node.nodeValue ) {
// Otherwise, vary by node type. A text node has no children. Its range
// offset reflects its position in nodeValue.
//
// "If the startContainer is a Node of type Text, Comment, or
// CDATASection, then the offset is the number of characters from the
// start of the startContainer to the boundary point of the Range."
//
// See: https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
// See: https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue
extentOffset = node.nodeValue.length;
} else {
// "For other Node types, the startOffset is the number of child nodes
// between the start of the startContainer and the boundary point of
// the Range."
//
// See: https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
extentOffset = node.childNodes.length;
}

// Offset of range should be at expected extent.
const position = isReverse ? 'start' : 'end';
const offset = range[ `${ position }Offset` ];
if ( offset !== extentOffset ) {
return false;
}

// If confirmed to be at extent, traverse up through DOM, verifying that
// the node is at first or last child for reverse or forward respectively.
// Continue until container is reached.
const order = isReverse ? 'first' : 'last';
while ( node !== container ) {
const parentNode = node.parentNode;
if ( parentNode[ `${ order }Child` ] !== node ) {
return false;
}

node = parentNode;
}

// If reached, range is assumed to be at edge.
return true;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions test/e2e/specs/__snapshots__/splitting-merging.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`splitting and merging blocks Should delete an empty first line 1`] = `
"<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->"
`;

exports[`splitting and merging blocks Should merge into inline boundary position 1`] = `
"<!-- wp:paragraph -->
<p>Bar</p>
Expand Down
17 changes: 17 additions & 0 deletions test/e2e/specs/splitting-merging.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,21 @@ describe( 'splitting and merging blocks', () => {

expect( await getEditedPostContent() ).toMatchSnapshot();
} );

it( 'Should delete an empty first line', async () => {
// Regression Test: When a paragraph block has line break, and the first
// line has no text, pressing backspace at the start of the second line
// should remove the first.
//
// See: https://github.com/WordPress/gutenberg/issues/8388
await insertBlock( 'Paragraph' );
await page.keyboard.down( 'Shift' );
await page.keyboard.press( 'Enter' );
await page.keyboard.up( 'Shift' );

// Delete the soft line break.
await page.keyboard.press( 'Backspace' );

expect( await getEditedPostContent() ).toMatchSnapshot();
} );
} );

0 comments on commit 41ff1f2

Please sign in to comment.