Skip to content

Commit

Permalink
Backspace works nice. Fixed Backspace in beginning of a *styled* line…
Browse files Browse the repository at this point in the history
… does not affect the line positioning #567

Issue: #567
  • Loading branch information
xdan committed Dec 13, 2020
1 parent bd57900 commit e82e271
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 75 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ console.log(item.options); // {some: false}
#### :bug: Bug Fix

* [#568 Reset in size change not rescaling image](https://github.com/xdan/jodit/issues/568)
* [#567 Backspace in beginning of a *styled* line does not affect the line positioning](https://github.com/xdan/jodit/issues/567)
* [#550 Table cell elements are always left-aligned](https://github.com/xdan/jodit/issues/550)
* [#543 editor.destruct throws error](https://github.com/xdan/jodit/issues/543)
* [#540 How i can get Iframe without parent element <jodit>...</jodit>](https://github.com/xdan/jodit/issues/540)
Expand Down
98 changes: 71 additions & 27 deletions src/plugins/keyboard/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export class Delete extends Plugin {
if (!isVoid(removed) && removed !== INVISIBLE_SPACE) {
charRemoved = true;

Dom.after(sibling, fakeNode);
call(backspace ? Dom.after : Dom.before, sibling, fakeNode);

if (block) {
while (this.checkRemoveChar(fakeNode, backspace, false)) {}
Expand Down Expand Up @@ -531,10 +531,10 @@ export class Delete extends Plugin {

call(!backspace ? Dom.append : Dom.prepend, second, fakeNode);

this.checkJoinNeighbors(fakeNode, backspace);
Dom.moveContent(prev, next, !backspace);
Dom.safeRemove(prev);

call(backspace ? Dom.append : Dom.prepend, target, fakeNode);

call(backspace ? setCursorBefore : setCursorAfter, fakeNode);

return true;
Expand Down Expand Up @@ -600,41 +600,85 @@ export class Delete extends Plugin {
}

if (Dom.isElement(mainClosestBox)) {
let sibling = findNotEmptySibling(
const sibling = findNotEmptySibling(
mainClosestBox,
backspace
) as Nullable<Element>;

// Process UL/LI/OL cases
const siblingIsList = Dom.isTag(sibling, ['ol', 'ul']);
const boxIsList = Dom.isTag(mainClosestBox, ['ol', 'ul']);
const elementChild = (elm: Element, side: boolean) =>
side ? elm.firstElementChild : elm.lastElementChild;

if (boxIsList) {
sibling = jodit.createInside.element(jodit.o.enterBlock);
Dom.before(mainClosestBox, sibling);
mainClosestBox = elementChild(mainClosestBox, backspace);
} else if (sibling && siblingIsList && !boxIsList) {
sibling = elementChild(mainClosestBox, !backspace);
if (
sibling &&
(this.checkMoveListContent(
mainClosestBox,
sibling,
backspace
) ||
this.moveContentAndRemoveEmpty(
mainClosestBox,
sibling,
backspace
))
) {
jodit.s.setCursorBefore(fakeNode);
return true;
}
}
}

// Move content and remove empty nodes
if (mainClosestBox && Dom.isElement(sibling)) {
Dom.moveContent(mainClosestBox, sibling, !backspace);
private checkMoveListContent(
mainClosestBox: Element,
sibling: Element,
backspace: boolean
): boolean {
const { jodit } = this;

let remove: Nullable<Node> = mainClosestBox;
// Process UL/LI/OL cases
const siblingIsList = Dom.isTag(sibling, ['ol', 'ul']);
const boxIsList = Dom.isTag(mainClosestBox, ['ol', 'ul']);
const elementChild = (elm: Element, side: boolean) =>
side ? elm.firstElementChild : elm.lastElementChild;

while (remove && remove !== this.root && Dom.isEmpty(remove)) {
const parent: Nullable<Node> = remove.parentElement;
Dom.safeRemove(remove);
remove = parent;
}
if (boxIsList) {
sibling = jodit.createInside.element(jodit.o.enterBlock);
Dom.before(mainClosestBox, sibling);

jodit.s.setCursorBefore(fakeNode);
return true;
return this.moveContentAndRemoveEmpty(
elementChild(mainClosestBox, backspace),
sibling,
backspace
);
}

if (sibling && siblingIsList && !boxIsList) {
return this.moveContentAndRemoveEmpty(
mainClosestBox,
elementChild(sibling, !backspace),
backspace
);
}

return false;
}
private moveContentAndRemoveEmpty(
mainClosestBox: Nullable<Node>,
sibling: Nullable<Node>,
backspace: boolean
): boolean {
// Move content and remove empty nodes
if (mainClosestBox && Dom.isElement(sibling)) {
Dom.moveContent(mainClosestBox, sibling, !backspace);

let remove: Nullable<Node> = mainClosestBox;

while (remove && remove !== this.root && Dom.isEmpty(remove)) {
const parent: Nullable<Node> = remove.parentElement;
Dom.safeRemove(remove);
remove = parent;
}

return true;
}

return false;
}

checkJoinNeighbors2(fakeNode: Node, backspace: boolean): true | void {
Expand Down
67 changes: 24 additions & 43 deletions test/tests/acceptance/deleteBackSpaceTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -892,8 +892,8 @@ describe('Backspace/Delete key', function () {
expect(editor.value).equals('<p>Test a Test</p>');
});

describe('With styles', function () {
it('Should connect both elements in one element', function () {
describe('inline elements', function () {
it('Should move cursor inside first element', function () {
editor.value = '<div><span style="color: rgb(0, 0, 255);">This is</span></div>\n' +
'<div><span style="color: rgb(0, 0, 255);">my line</span></div>';

Expand All @@ -902,37 +902,35 @@ describe('Backspace/Delete key', function () {

simulateEvent('keydown', Jodit.KEY_BACKSPACE, editor.editor);

expect(sortAttributes(editor.value)).equals('<div><span style="color:#0000FF">This ismy line</span></div>');
expect(sortAttributes(editor.value)).equals('<div><span style="color:#0000FF">This is</span><span style="color:#0000FF">my line</span></div>\n');

editor.s.insertHTML(' a ');
expect(sortAttributes(editor.value)).equals('<div><span style="color:#0000FF">This is a my line</span></div>');
expect(sortAttributes(editor.value)).equals('<div><span style="color:#0000FF">This is</span><span style="color:#0000FF"> a my line</span></div>\n');
});
});

describe('Several elements', function () {
it('Should connect both elements in one element and move all children in previous element', function () {
editor.value = '<div><span>This is</span></div>\n' +
'<div><span>my line</span><strong>test</strong></div>';
'<div><span>|my line</span><strong>test</strong></div>';

range.setStart(editor.editor.querySelectorAll('span')[1].firstChild, 0);
editor.s.selectRange(range);
setCursorToChar(editor);

simulateEvent('keydown', Jodit.KEY_BACKSPACE, editor.editor);

expect(sortAttributes(editor.value)).equals('<div><span>This ismy line</span><strong>test</strong></div>');
expect(sortAttributes(editor.value)).equals('<div><span>This is</span><span>my line</span><strong>test</strong></div>\n');
});

describe('Different elements', function () {
it('Should move content', function () {
editor.value = '<div><span>This is</span></div>\n' +
'<div><strong>my line</strong><strong>test</strong></div>';
'<div><strong>|my line</strong><strong>test</strong></div>';

range.setStart(editor.editor.querySelectorAll('span')[1].firstChild, 0);
editor.s.selectRange(range);
setCursorToChar(editor);

simulateEvent('keydown', Jodit.KEY_BACKSPACE, editor.editor);

expect(sortAttributes(editor.value)).equals('<div><span>This ismy line</span><strong>test</strong></div>');
expect(sortAttributes(editor.value)).equals('<div><span>This is</span><strong>my line</strong><strong>test</strong></div>\n');
});
});
});
Expand Down Expand Up @@ -1008,11 +1006,11 @@ describe('Backspace/Delete key', function () {
);

expect(sortAttributes(editor.value)).equals(
'<p>TestTest</p>'
'<p>TestTest</p> \n '
);

editor.s.insertHTML(' a ');
expect(editor.value).equals('<p>Test a Test</p>');
expect(editor.value).equals('<p>Test a Test</p> \n ');
});
});
});
Expand All @@ -1037,15 +1035,11 @@ describe('Backspace/Delete key', function () {
describe('In the middle of two UL elements', function () {
describe('Backspace', function () {
describe('In first LI of second UL', function () {
it('Should connect both UL in one element', function () {
it('Should move content of this LI and put it inside new P', function () {
editor.value =
'<ul><li>Test</li></ul><ul><li>Some text</li></ul>';
'<ul><li>Test</li></ul><ul><li>|Some text</li></ul>';

range.setStart(
editor.editor.lastChild.firstChild.firstChild,
0
);
editor.s.selectRange(range);
setCursorToChar(editor);

simulateEvent(
'keydown',
Expand All @@ -1054,36 +1048,26 @@ describe('Backspace/Delete key', function () {
);

expect(sortAttributes(editor.value)).equals(
'<ul><li>Test</li><li>Some text</li></ul>'
'<ul><li>Test</li></ul><p>Some text</p>'
);

editor.s.insertNode(editor.createInside.text(' a '));

expect(sortAttributes(editor.value)).equals(
'<ul><li>Test</li><li> a Some text</li></ul>'
'<ul><li>Test</li></ul><p> a Some text</p>'
);
});
});

describe('In the P element', function () {
it('Should connect both UL in one element', function () {
editor.value =
'<ul><li>Test</li><li> </li><li>Some text</li></ul>';

const range = editor.s.createRange();

range.setStart(editor.editor.firstChild.childNodes[1], 0);
range.collapse(true);
'<ul><li>Test</li></ul><p>|<br></p><ul><li>Some text</li></ul>';

editor.s.selectRange(range);

simulateEvent('keydown', Jodit.KEY_ENTER, editor.editor);

expect(sortAttributes(editor.value)).equals(
'<ul><li>Test</li></ul><p><br></p><ul><li>Some text</li></ul>'
);
setCursorToChar(editor);

editor.s.focus();

simulateEvent(
'keydown',
Jodit.KEY_BACKSPACE,
Expand All @@ -1107,23 +1091,20 @@ describe('Backspace/Delete key', function () {
describe('In last LI of first UL', function () {
it('Should connect both UL in one element', function () {
editor.value =
'<ul><li>Test</li></ul><ul><li>Some text</li></ul>';
'<ul><li>Test|</li></ul><ul><li>Some text</li></ul>';

range.setStartAfter(
editor.editor.firstChild.firstChild.firstChild
);
editor.s.selectRange(range);
setCursorToChar(editor);

simulateEvent('keydown', Jodit.KEY_DELETE, editor.editor);

expect(sortAttributes(editor.value)).equals(
'<ul><li>Test</li><li>Some text</li></ul>'
'<p>Test</p><ul><li>Some text</li></ul>'
);

editor.s.insertNode(editor.createInside.text(' a '));

expect(sortAttributes(editor.value)).equals(
'<ul><li>Test a </li><li>Some text</li></ul>'
'<p>Test a </p><ul><li>Some text</li></ul>'
);
});
});
Expand Down
2 changes: 1 addition & 1 deletion test/tests/acceptance/toolbarTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ describe('Toolbar', function () {

const pencil = getButton('link', popup);
expect(pencil).is.not.null;
debugger

simulateEvent('click', pencil);
const subpopup = getOpenedPopup(editor);

Expand Down
4 changes: 1 addition & 3 deletions test/tests/units/helpersTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ describe('Test helpers', function () {
).is.true;
});
});

describe('getClassName', function () {
const getClassName = Jodit.modules.Helpers.getClassName;

Expand All @@ -672,9 +673,6 @@ describe('Test helpers', function () {
expect(
getClassName(Jodit.modules.ToolbarButton.prototype)
).equals('ToolbarButton');
expect(getClassName(Jodit.modules.Component.prototype)).equals(
'Component'
);
});
});
});
Expand Down
2 changes: 1 addition & 1 deletion test/tests/units/popupTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ describe('Test popup', function() {

const openPopup = function(getBound, content, strategy) {
const editor = getJodit();
debugger

const popup = new Jodit.modules.Popup(editor);

if (strategy) {
Expand Down

0 comments on commit e82e271

Please sign in to comment.