Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added unwrapTags option to paste extension #1177

Merged
merged 2 commits into from
Aug 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var editor = new MediumEditor('.editor', {
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->


- [Core Options](#core-options)
- [`activeButtonClass`](#activebuttonclass)
- [`buttonLabels`](#buttonlabels)
Expand All @@ -32,17 +33,20 @@ var editor = new MediumEditor('.editor', {
- [`diffTop`](#difftop)
- [`firstButtonClass`](#firstbuttonclass)
- [`lastButtonClass`](#lastbuttonclass)
- [`relativeContainer`](#relativecontainer)
- [`standardizeSelectionStart`](#standardizeselectionstart)
- [`static`](#static)
- ['static' Toolbar Options](#static-toolbar-options)
- [`align`](#align)
- [`sticky`](#sticky)
- [`stickyTopOffset`](#stickytopoffset)
- [`updateOnEmptySelection`](#updateonemptyselection)
- [Disabling Toolbar](#disabling-toolbar)
- [Anchor Preview options](#anchor-preview-options)
- [`hideDelay`](#hidedelay)
- [`previewValueSelector`](#previewvalueselector)
- [`showOnEmptyLinks`](#showonemptylinks)
- [`showWhenToolbarIsVisible`](#showwhentoolbarisvisible)
- [Disabling Anchor Preview](#disabling-anchor-preview)
- [Placeholder Options](#placeholder-options)
- [`text`](#text)
Expand All @@ -61,6 +65,7 @@ var editor = new MediumEditor('.editor', {
- [`cleanReplacements`](#cleanreplacements)
- [`cleanAttrs`](#cleanattrs)
- [`cleanTags`](#cleantags)
- [`unwrapTags`](#unwraptags)
- [Disabling Paste Handling](#disabling-paste-handling)
- [KeyboardCommands Options](#keyboardcommands-options)
- [`commands`](#commands)
Expand Down Expand Up @@ -521,6 +526,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