@@ -2,8 +2,9 @@ import config from './config'
22import * as string from './util/string'
33import * as nodeType from './node-type'
44import * as quotes from './quotes'
5+ import { isPlainTextBlock } from './block'
56
6- let allowedElements , requiredAttributes , transformElements , blockLevelElements , replaceQuotes
7+ let allowedElements , allowedPlainTextElements , requiredAttributes , transformElements , blockLevelElements , replaceQuotes
78let splitIntoBlocks , blacklistedElements
89const whitespaceOnly = / ^ \s * $ /
910const blockPlaceholder = '<!-- BLOCK -->'
@@ -13,6 +14,7 @@ updateConfig(config)
1314export function updateConfig ( conf ) {
1415 const rules = conf . pastedHtmlRules
1516 allowedElements = rules . allowedElements || { }
17+ allowedPlainTextElements = rules . allowedPlainTextElements || { }
1618 requiredAttributes = rules . requiredAttributes || { }
1719 transformElements = rules . transformElements || { }
1820 blacklistedElements = rules . blacklistedElements || [ ]
@@ -25,9 +27,9 @@ export function updateConfig (conf) {
2527 rules . splitIntoBlocks . forEach ( ( name ) => { splitIntoBlocks [ name ] = true } )
2628}
2729
28- export function paste ( element , cursor , clipboardContent ) {
29- const document = element . ownerDocument
30- element . setAttribute ( config . pastingAttribute , true )
30+ export function paste ( block , cursor , clipboardContent ) {
31+ const document = block . ownerDocument
32+ block . setAttribute ( config . pastingAttribute , true )
3133
3234 if ( cursor . isSelection ) {
3335 cursor = cursor . deleteExactSurroundingTags ( )
@@ -39,9 +41,10 @@ export function paste (element, cursor, clipboardContent) {
3941 const pasteHolder = document . createElement ( 'div' )
4042 pasteHolder . innerHTML = clipboardContent
4143
42- const blocks = parseContent ( pasteHolder )
44+ const isPlainText = isPlainTextBlock ( block )
45+ const blocks = parseContent ( pasteHolder , { plainText : isPlainText } )
4346
44- element . removeAttribute ( config . pastingAttribute )
47+ block . removeAttribute ( config . pastingAttribute )
4548 return { blocks, cursor}
4649}
4750
@@ -55,30 +58,35 @@ export function paste (element, cursor, clipboardContent) {
5558 * @param {DOM node } A container where the pasted content is located.
5659 * @returns {Array of Strings } An array of cleaned innerHTML like strings.
5760 */
58- export function parseContent ( element ) {
61+ export function parseContent ( element , { plainText = false } = { } ) {
62+ const options = {
63+ allowedElements : plainText ? allowedPlainTextElements : allowedElements ,
64+ keepInternalRelativeLinks : plainText ? false : keepInternalRelativeLinks
65+ }
66+
5967 // Filter pasted content
60- return filterHtmlElements ( element )
68+ return filterHtmlElements ( element , options )
6169 // Handle Blocks
6270 . split ( blockPlaceholder )
6371 . map ( ( entry ) => string . trim ( cleanWhitespace ( replaceAllQuotes ( entry ) ) ) )
6472 . filter ( ( entry ) => ! whitespaceOnly . test ( entry ) )
6573}
6674
67- export function filterHtmlElements ( elem ) {
75+ function filterHtmlElements ( elem , options ) {
6876 return Array . from ( elem . childNodes ) . reduce ( ( content , child ) => {
6977 if ( blacklistedElements . indexOf ( child . nodeName . toLowerCase ( ) ) !== - 1 ) {
7078 return ''
7179 }
7280
7381 // Keep internal relative links relative (on paste).
74- if ( keepInternalRelativeLinks && child . nodeName === 'A' && child . href ) {
82+ if ( options . keepInternalRelativeLinks && child . nodeName === 'A' && child . href ) {
7583 const stripInternalHost = child . getAttribute ( 'href' ) . replace ( window . location . origin , '' )
7684 child . setAttribute ( 'href' , stripInternalHost )
7785 }
7886
7987 if ( child . nodeType === nodeType . elementNode ) {
80- const childContent = filterHtmlElements ( child )
81- return content + conditionalNodeWrap ( child , childContent )
88+ const childContent = filterHtmlElements ( child , options )
89+ return content + conditionalNodeWrap ( child , childContent , options )
8290 }
8391
8492 // Escape HTML characters <, > and &
@@ -87,11 +95,11 @@ export function filterHtmlElements (elem) {
8795 } , '' )
8896}
8997
90- export function conditionalNodeWrap ( child , content ) {
98+ function conditionalNodeWrap ( child , content , options ) {
9199 let nodeName = child . nodeName . toLowerCase ( )
92100 nodeName = transformNodeName ( nodeName )
93101
94- if ( shouldKeepNode ( nodeName , child ) ) {
102+ if ( shouldKeepNode ( nodeName , child , options ) ) {
95103 const attributes = filterAttributes ( nodeName , child )
96104
97105 if ( nodeName === 'br' ) return `<${ nodeName + attributes } >`
@@ -115,7 +123,7 @@ export function conditionalNodeWrap (child, content) {
115123}
116124
117125// returns string of concatenated attributes e.g. 'target="_blank" rel="nofollow" href="/test.com"'
118- export function filterAttributes ( nodeName , node ) {
126+ function filterAttributes ( nodeName , node ) {
119127 return Array . from ( node . attributes ) . reduce ( ( attributes , { name, value} ) => {
120128 if ( allowedElements [ nodeName ] [ name ] && value ) {
121129 return `${ attributes } ${ name } ="${ value } "`
@@ -124,22 +132,22 @@ export function filterAttributes (nodeName, node) {
124132 } , '' )
125133}
126134
127- export function transformNodeName ( nodeName ) {
135+ function transformNodeName ( nodeName ) {
128136 return transformElements [ nodeName ] || nodeName
129137}
130138
131- export function hasRequiredAttributes ( nodeName , node ) {
139+ function hasRequiredAttributes ( nodeName , node ) {
132140 const requiredAttrs = requiredAttributes [ nodeName ]
133141 if ( ! requiredAttrs ) return true
134142
135143 return ! requiredAttrs . some ( ( name ) => ! node . getAttribute ( name ) )
136144}
137145
138- export function shouldKeepNode ( nodeName , node ) {
139- return allowedElements [ nodeName ] && hasRequiredAttributes ( nodeName , node )
146+ function shouldKeepNode ( nodeName , node , options ) {
147+ return options . allowedElements [ nodeName ] && hasRequiredAttributes ( nodeName , node )
140148}
141149
142- export function cleanWhitespace ( str ) {
150+ function cleanWhitespace ( str ) {
143151 return str
144152 . replace ( / \n / g, ' ' )
145153 . replace ( / { 2 , } / g, ' ' )
@@ -149,7 +157,7 @@ export function cleanWhitespace (str) {
149157 ) )
150158}
151159
152- export function replaceAllQuotes ( str ) {
160+ function replaceAllQuotes ( str ) {
153161 if ( replaceQuotes . quotes || replaceQuotes . singleQuotes || replaceQuotes . apostrophe ) {
154162 return quotes . replaceAllQuotes ( str , replaceQuotes )
155163 }
0 commit comments