Skip to content

Commit 2a34167

Browse files
committed
Update build
1 parent 7b5af29 commit 2a34167

File tree

3 files changed

+89
-44
lines changed

3 files changed

+89
-44
lines changed

Changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
# v0.4.1
22

3+
#### Features
4+
35
- Filter pasted content [#84](https://github.com/upfrontIO/editable.js/pull/84)
46

7+
#### Bugfixes
8+
9+
- Remove content.normalizeSpaces() [#82](https://github.com/upfrontIO/editable.js/issues/82)
10+
511

612
# v0.4.0
713

editable.js

Lines changed: 81 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3486,15 +3486,16 @@ var config = {
34863486
italicTag: '<em>',
34873487

34883488
// Rules that are applied when filtering pasted content
3489-
pastedHtmlFilter: {
3489+
pastedHtmlRules: {
34903490

34913491
// Elements and their attributes to keep in pasted text
34923492
allowedElements: {
34933493
'a': {
34943494
'href': true
34953495
},
34963496
'strong': {},
3497-
'em': {}
3497+
'em': {},
3498+
'br': {}
34983499
},
34993500

35003501
// Elements that have required attributes.
@@ -3509,8 +3510,15 @@ var config = {
35093510
transformElements: {
35103511
'b': 'strong',
35113512
'i': 'em'
3512-
}
3513+
},
3514+
3515+
// A list of elements which should be split into paragraphs.
3516+
splitIntoBlocks: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'blockquote'],
3517+
3518+
// A list of HTML block level elements.
3519+
blockLevelElements: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'p', 'pre', 'hr', 'blockquote', 'article', 'figure', 'header', 'footer', 'ul', 'ol', 'li', 'section', 'table', 'video']
35133520
}
3521+
35143522
};
35153523

35163524

@@ -3657,8 +3665,7 @@ Editable.prototype.enable = function($elem, normalize) {
36573665

36583666
if (normalize) {
36593667
$elem.each(function(index, el) {
3660-
content.normalizeTags(el);
3661-
content.normalizeSpaces(el);
3668+
content.tidyHtml(el);
36623669
});
36633670
}
36643671

@@ -3908,13 +3915,26 @@ var block = (function() {
39083915

39093916
var clipboard = (function() {
39103917
var allowedElements, requiredAttributes, transformElements;
3918+
var blockLevelElements, splitIntoBlocks;
39113919
var whitespaceOnly = /^\s*$/;
3920+
var blockPlaceholder = '<!-- BLOCK -->';
39123921

39133922
var updateConfig = function (config) {
3914-
var filter = config.pastedHtmlFilter;
3915-
allowedElements = filter.allowedElements || {};
3916-
requiredAttributes = filter.requiredAttributes || {};
3917-
transformElements = filter.transformElements || {};
3923+
var i, name, rules = config.pastedHtmlRules;
3924+
allowedElements = rules.allowedElements || {};
3925+
requiredAttributes = rules.requiredAttributes || {};
3926+
transformElements = rules.transformElements || {};
3927+
3928+
blockLevelElements = {};
3929+
for (i = 0; i < rules.blockLevelElements.length; i++) {
3930+
name = rules.blockLevelElements[i];
3931+
blockLevelElements[name] = true;
3932+
}
3933+
splitIntoBlocks = {};
3934+
for (i = 0; i < rules.splitIntoBlocks.length; i++) {
3935+
name = rules.splitIntoBlocks[i];
3936+
splitIntoBlocks[name] = true;
3937+
}
39183938
};
39193939

39203940
updateConfig(config);
@@ -3957,7 +3977,6 @@ var clipboard = (function() {
39573977
getContenteditableContainer: function(document) {
39583978
var pasteHolder = $('<div>')
39593979
.attr('contenteditable', true)
3960-
.addClass('filteredPaste_pasteIntoArea_xxx')
39613980
.css({
39623981
position: 'fixed',
39633982
left: '5px',
@@ -3980,7 +3999,19 @@ var clipboard = (function() {
39803999
// Filter pasted content
39814000
var pastedString = this.filterHtmlElements(element);
39824001

4002+
// Handle Blocks
4003+
var blocks = pastedString.split(blockPlaceholder);
4004+
blocks = blocks.filter(function(entry) {
4005+
return !whitespaceOnly.test(entry);
4006+
});
4007+
pastedString = blocks.join('<br><br>');
4008+
4009+
// Clean Whitesapce
4010+
// todo: make configurable
4011+
pastedString = this.cleanWhitespace(pastedString);
4012+
39834013
// Trim pasted Text
4014+
// todo: make configurable
39844015
if (pastedString) {
39854016
pastedString = string.trim(pastedString);
39864017
}
@@ -4010,11 +4041,25 @@ var clipboard = (function() {
40104041
var nodeName = child.nodeName.toLowerCase();
40114042
nodeName = this.transformNodeName(nodeName);
40124043

4013-
if ( this.shouldKeepNode(nodeName, child) && !whitespaceOnly.test(content) ){
4044+
if ( this.shouldKeepNode(nodeName, child) ) {
40144045
var attributes = this.filterAttributes(nodeName, child);
4015-
return '<'+ nodeName + attributes +'>'+ content +'</'+ nodeName +'>';
4046+
if (nodeName === 'br') {
4047+
return '<'+ nodeName + attributes +'>';
4048+
} else if ( !whitespaceOnly.test(content) ) {
4049+
return '<'+ nodeName + attributes +'>'+ content +'</'+ nodeName +'>';
4050+
} else {
4051+
return content;
4052+
}
40164053
} else {
4017-
return content;
4054+
if (splitIntoBlocks[nodeName]) {
4055+
return blockPlaceholder + content + blockPlaceholder;
4056+
} else if (blockLevelElements[nodeName]) {
4057+
// prevent missing whitespace between text when block-level
4058+
// elements are removed.
4059+
return content + ' ';
4060+
} else {
4061+
return content;
4062+
}
40184063
}
40194064
},
40204065

@@ -4056,6 +4101,17 @@ var clipboard = (function() {
40564101

40574102
shouldKeepNode: function(nodeName, node) {
40584103
return allowedElements[nodeName] && this.hasRequiredAttributes(nodeName, node);
4104+
},
4105+
4106+
cleanWhitespace: function(str) {
4107+
var cleanedStr = str.replace(/(.)(\u00A0)/g, function(match, group1, group2, offset, string) {
4108+
if ( /[\u0020]/.test(group1) ) {
4109+
return group1 + '\u00A0';
4110+
} else {
4111+
return group1 + ' ';
4112+
}
4113+
});
4114+
return cleanedStr;
40594115
}
40604116

40614117
};
@@ -4074,6 +4130,15 @@ var content = (function() {
40744130
var zeroWidthNonBreakingSpace = /\uFEFF/g;
40754131

40764132
return {
4133+
4134+
/**
4135+
* Clean up the Html.
4136+
*/
4137+
tidyHtml: function(element) {
4138+
this.normalizeTags(element);
4139+
},
4140+
4141+
40774142
/**
40784143
* Remove empty tags and merge consecutive tags (they must have the same
40794144
* attributes).
@@ -4228,27 +4293,6 @@ var content = (function() {
42284293
}
42294294
},
42304295

4231-
/**
4232-
* Convert the first and last space to a non breaking space charcter to
4233-
* prevent visual collapse by some browser.
4234-
*
4235-
* @method normalizeSpaces
4236-
* @param {HTMLElement} element The element to process.
4237-
*/
4238-
normalizeSpaces: function(element) {
4239-
var nonBreakingSpace = '\u00A0';
4240-
4241-
if (!element) return;
4242-
4243-
if (element.nodeType === nodeType.textNode) {
4244-
element.nodeValue = element.nodeValue.replace(/^(\s)/, nonBreakingSpace).replace(/(\s)$/, nonBreakingSpace);
4245-
}
4246-
else {
4247-
this.normalizeSpaces(element.firstChild);
4248-
this.normalizeSpaces(element.lastChild);
4249-
}
4250-
},
4251-
42524296
/**
42534297
* Get all tags that start or end inside the range
42544298
*/
@@ -4860,10 +4904,8 @@ var createDefaultBehavior = function(editable) {
48604904
}
48614905
element.appendChild(after);
48624906

4863-
content.normalizeTags(newNode);
4864-
content.normalizeSpaces(newNode);
4865-
content.normalizeTags(element);
4866-
content.normalizeSpaces(element);
4907+
content.tidyHtml(newNode);
4908+
content.tidyHtml(element);
48674909
element.focus();
48684910
},
48694911

@@ -4894,8 +4936,7 @@ var createDefaultBehavior = function(editable) {
48944936
merger.parentNode.removeChild(merger);
48954937

48964938
cursor.save();
4897-
content.normalizeTags(container);
4898-
content.normalizeSpaces(container);
4939+
content.tidyHtml(container);
48994940
cursor.restore();
49004941
cursor.setVisibleSelection();
49014942
},
@@ -5189,8 +5230,6 @@ Dispatcher.prototype.setupElementEvents = function() {
51895230
}).on('paste.editable', _this.editableSelector, function(event) {
51905231
log('Paste');
51915232
_this.notify('clipboard', this, 'paste', _this.selectionWatcher.getFreshSelection());
5192-
// todo: this might be a bug since there is a timeout in the paste logic
5193-
// consider moving the paste code in here an not in the default behaviour
51945233
_this.triggerChangeEvent(this);
51955234
}).on('input.editable', _this.editableSelector, function(event) {
51965235
log('Input');

0 commit comments

Comments
 (0)