Skip to content

Commit

Permalink
Fix first/last pasted BBCode blocks being removed (#927)
Browse files Browse the repository at this point in the history
When pasting in BBCode format, the first and last blocks were sometimes
being removed, such as:

[center]test[/center][center]test[/center][center]test[/center]

This also caused extra newlines to sometimes be added when pasting.
  • Loading branch information
samclarke authored Mar 1, 2023
1 parent 8172419 commit c368667
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 57 deletions.
64 changes: 8 additions & 56 deletions src/formats/bbcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -854,57 +854,6 @@
});
}

/**
* Removes the first and last divs from the HTML.
*
* This is needed for pasting
* @param {string} html
* @return {string}
* @private
*/
function removeFirstLastDiv(html) {
var node, next, removeDiv,
output = document.createElement('div');

removeDiv = function (node, isFirst) {
// Don't remove divs that have styling
if (dom.hasStyling(node)) {
return;
}

if ((node.childNodes.length !== 1 ||
!is(node.firstChild, 'br'))) {
while ((next = node.firstChild)) {
output.insertBefore(next, node);
}
}

if (isFirst) {
var lastChild = output.lastChild;

if (node !== lastChild && is(lastChild, 'div') &&
node.nextSibling === lastChild) {
output.insertBefore(document.createElement('br'), node);
}
}

output.removeChild(node);
};

css(output, 'display', 'none');
output.innerHTML = html.replace(/<\/div>\n/g, '</div>');

if ((node = output.firstChild) && is(node, 'div')) {
removeDiv(node, true);
}

if ((node = output.lastChild) && is(node, 'div')) {
removeDiv(node);
}

return output.innerHTML;
}

function isFunction(fn) {
return typeof fn === 'function';
}
Expand Down Expand Up @@ -1794,6 +1743,10 @@
return convertToHTML(base.parse(str, preserveNewLines), true);
};

base.toHTMLFragment = function (str, preserveNewLines) {
return convertToHTML(base.parse(str, preserveNewLines), false);
};

/**
* @private
*/
Expand Down Expand Up @@ -2542,12 +2495,11 @@
*/
function toHtml(asFragment, source, legacyAsFragment) {
var parser = new BBCodeParser(base.opts.parserOptions);
var html = parser.toHTML(
base.opts.bbcodeTrim ? source.trim() : source
);
var toHTML = (asFragment || legacyAsFragment) ?
parser.toHTMLFragment :
parser.toHTML;

return (asFragment || legacyAsFragment) ?
removeFirstLastDiv(html) : html;
return toHTML(base.opts.bbcodeTrim ? source.trim() : source);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/lib/SCEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,8 @@ export default function SCEditor(original, userOptions) {
// into a paragraph
dom.fixNesting(wysiwygBody);

wrapInlines(wysiwygBody, wysiwygDocument);

// Scroll the editor after the end of the selection
marker = dom.find(wysiwygBody, '#sceditor-end-marker')[0];
dom.show(marker);
Expand Down
51 changes: 50 additions & 1 deletion tests/unit/formats/bbcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,56 @@ QUnit.test('From BBCode method as fragment', function (assert) {
assert.htmlEqual(
this.mockEditor.fromBBCode('[b]test[/b]', true),
'<strong>test</strong>',
'As fragment'
'Should not wrap fragments in blocks'
);

assert.htmlEqual(
this.mockEditor.fromBBCode(
'line1[b]test[/b][center]line2[/center]line3[b]test[/b]',
true
),
'line1<strong>test</strong>' +
'<div align="center">line2<br /></div>' +
'line3<strong>test</strong>',
'Should not wrap inlines with a block in between'
);

assert.htmlEqual(
this.mockEditor.fromBBCode(
'\n\n',
true
),
'<br /><br />',
'Should preserve newlines'
);

assert.htmlEqual(
this.mockEditor.fromBBCode(
'[none]test[/none]',
true
),
'[none]test[/none]',
'Should not alter nonexistent BBCodes'
);

assert.htmlEqual(
this.mockEditor.fromBBCode(
'[center]line1[/center][center]line2[/center][center]line3[/center]',
true
),
'<div align="center">line1<br /></div>' +
'<div align="center">line2<br /></div>' +
'<div align="center">line3<br /></div>',
'Should keep all styled blocks created by a BBCode'
);

assert.htmlEqual(
this.mockEditor.fromBBCode(
'\nline2\n',
true
),
'<br />line2<br />',
'Should not wrap newlines'
);
});

Expand Down

0 comments on commit c368667

Please sign in to comment.