Skip to content

Commit

Permalink
Added unwrapTags option to paste extension
Browse files Browse the repository at this point in the history
  • Loading branch information
paradite committed Aug 13, 2016
1 parent 1ae7fd4 commit 3befae3
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 9 deletions.
6 changes: 6 additions & 0 deletions OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@ List of element attributes to remove during paste when __cleanPastedHTML__ is `t

List of element tag names to remove during paste when __cleanPastedHTML__ is `true` or when calling `cleanPaste(text)` or `pasteHTML(html,options)` helper methods.

***
#### `unwrapTags`
**Default:** `[]`

List of element tag names to unwrap (remove the element tag but retain its child elements) during paste when __cleanPastedHTML__ is `true` or when calling `cleanPaste(text)` or `pasteHTML(html,options)` helper methods.

### Disabling Paste Handling

To disable MediumEditor manipulating pasted content, set the both the `forcePlainText` and `cleanPastedHTML` options to `false`:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ var editor = new MediumEditor('.editable', {
* __cleanReplacements__: custom pairs (2 element arrays) of RegExp and replacement text to use during paste when __forcePlainText__ or __cleanPastedHTML__ are `true` OR when calling `cleanPaste(text)` helper method. These replacements are executed _after_ builtin replacements. Default: `[]`
* __cleanAttrs__: list of element attributes to remove during paste when __cleanPastedHTML__ is `true` or when calling `cleanPaste(text)` or `pasteHTML(html,options)` helper methods. Default: `['class', 'style', 'dir']`
* __cleanTags__: list of element tag names to remove during paste when __cleanPastedHTML__ is `true` or when calling `cleanPaste(text)` or `pasteHTML(html,options)` helper methods. Default: `['meta']`
* __unwrapTags__: list of element tag names to unwrap (remove the element tag but retain its child elements) during paste when __cleanPastedHTML__ is `true` or when calling `cleanPaste(text)` or `pasteHTML(html,options)` helper methods. Default: `[]`

### KeyboardCommands Options

Expand Down
19 changes: 16 additions & 3 deletions spec/paste.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -716,21 +716,34 @@ describe('Pasting content', function () {
expect(editor.elements[0].innerHTML).toBe('<div><i>test</i></div>');
});

it('should accept a list of tags to unwrap', function () {
var editor = this.newMediumEditor('.editor');
selectElementContents(this.el.firstChild);
editor.pasteHTML(
'<div><i>test</i><sub><b>test</b></sub><sup>test</sup></div>',
{ unwrapTags: ['sub', 'sup'] }
);
expect(editor.elements[0].innerHTML).toBe('<div><i>test</i><b>test</b>test</div>');
});

it('should respect custom clean up options passed during instantiation', function () {
var editor = this.newMediumEditor('.editor', {
paste: {
cleanAttrs: ['style', 'dir'],
cleanTags: ['meta', 'b']
cleanTags: ['meta', 'b'],
unwrapTags: ['sub', 'sup']
}
});
selectElementContents(this.el.firstChild);
editor.pasteHTML(
'<table class="medium-editor-table" dir="ltr" style="border: 1px solid red;"><tbody><tr><td>test</td></tr></tbody></table>' +
'<div><i>test</i><meta name="description" content="test" /><b>test</b></div>'
'<div><i>test</i><meta name="description" content="test" /><b>test</b></div>' +
'<div><i>test</i><sub><b>test</b></sub><sup>test</sup></div>'
);
expect(editor.elements[0].innerHTML).toBe(
'<table class="medium-editor-table"><tbody><tr><td>test</td></tr></tbody></table>' +
'<div><i>test</i></div>'
'<div><i>test</i></div>' +
'<div><i>test</i>test</div>'
);
});
});
Expand Down
11 changes: 10 additions & 1 deletion src/js/extensions/paste.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@
*/
cleanTags: ['meta'],

/* unwrapTags: [Array]
* list of element tag names to unwrap (remove the element tag but retain its child elements)
* during paste when __cleanPastedHTML__ is `true` or when
* calling `cleanPaste(text)` or `pasteHTML(html, options)` helper methods.
*/
unwrapTags: [],

init: function () {
MediumEditor.Extension.prototype.init.apply(this, arguments);

Expand Down Expand Up @@ -422,7 +429,8 @@
pasteHTML: function (html, options) {
options = MediumEditor.util.defaults({}, options, {
cleanAttrs: this.cleanAttrs,
cleanTags: this.cleanTags
cleanTags: this.cleanTags,
unwrapTags: this.unwrapTags
});

var elList, workEl, i, fragmentBody, pasteBlock = this.document.createDocumentFragment();
Expand All @@ -444,6 +452,7 @@

MediumEditor.util.cleanupAttrs(workEl, options.cleanAttrs);
MediumEditor.util.cleanupTags(workEl, options.cleanTags);
MediumEditor.util.unwrapTags(workEl, options.unwrapTags);
}

MediumEditor.util.insertHTMLCommand(this.document, fragmentBody.innerHTML.replace(/&nbsp;/g, ' '));
Expand Down
14 changes: 9 additions & 5 deletions src/js/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -1024,11 +1024,15 @@
},

cleanupTags: function (el, tags) {
tags.forEach(function (tag) {
if (el.nodeName.toLowerCase() === tag) {
el.parentNode.removeChild(el);
}
});
if (tags.indexOf(el.nodeName.toLowerCase()) !== -1) {
el.parentNode.removeChild(el);
}
},

unwrapTags: function (el, tags) {
if (tags.indexOf(el.nodeName.toLowerCase()) !== -1) {
MediumEditor.util.unwrap(el, document);
}
},

// get the closest parent
Expand Down

0 comments on commit 3befae3

Please sign in to comment.