changeset 46:ab2dc8736d88

fix paste html and cleanup
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 30 Aug 2022 14:33:27 -0600
parents bc1bce78276d
children 16b61f228546
files src/formats/bbcode.js src/formats/xhtml.js src/plugins/alternative-lists.js src/sceditor.js src/themes/default.css
diffstat 5 files changed, 77 insertions(+), 312 deletions(-) [+]
line wrap: on
line diff
--- a/src/formats/bbcode.js	Tue Aug 30 02:03:50 2022 -0600
+++ b/src/formats/bbcode.js	Tue Aug 30 14:33:27 2022 -0600
@@ -454,15 +454,9 @@
 				li: null
 			},
 			isInline: false,
-			closedBy: ['/ul', '/ol', '/list', '*', 'li'],
 			format: '[li]{0}[/li]',
 			html: '<li>{0}</li>'
 		},
-		'*': {
-			isInline: false,
-			closedBy: ['/ul', '/ol', '/list', '*', 'li'],
-			html: '<li>{0}</li>'
-		},
 		// END_COMMAND
 
 		// START_COMMAND: Table
@@ -1243,17 +1237,6 @@
 					} else {
 						output.push(token);
 					}
-				},
-				/**
-				 * Checks if this tag closes the current tag
-				 * @param  {string} name
-				 * @return {Void}
-				 */
-				closesCurrentTag = function (name) {
-					return currentTag() &&
-						(bbcode = bbcodeHandlers[currentTag().name]) &&
-						bbcode.closedBy &&
-						bbcode.closedBy.indexOf(name) > -1;
 				};
 
 			while ((token = toks.shift())) {
@@ -1284,12 +1267,6 @@
 
 				switch (token.type) {
 					case TOKEN_OPEN:
-						// Check it this closes a parent,
-						// e.g. for lists [*]one [*]two
-						if (closesCurrentTag(token.name)) {
-							openTags.pop();
-						}
-
 						addTag(token);
 						bbcode = bbcodeHandlers[token.name];
 
@@ -1298,9 +1275,7 @@
 						// list of open tags. If has the closedBy property then
 						// it is closed by other tags so include everything as
 						// it's children until one of those tags is reached.
-						if (bbcode &&
-							(bbcode.closedBy ||
-								hasTag(token.name, TOKEN_CLOSE, toks))) {
+						if (bbcode && hasTag(token.name, TOKEN_CLOSE, toks)) {
 							openTags.push(token);
 						} else {
 							token.type = TOKEN_CONTENT;
@@ -1308,14 +1283,6 @@
 						break;
 
 					case TOKEN_CLOSE:
-						// check if this closes the current tag,
-						// e.g. [/list] would close an open [*]
-						if (currentTag() && token.name !== currentTag().name &&
-							closesCurrentTag('/' + token.name)) {
-
-							openTags.pop();
-						}
-
 						// If this is closing the currently open tag just pop
 						// the close tag off the open tags array
 						if (currentTag() && token.name === currentTag().name) {
@@ -1379,33 +1346,6 @@
 						break;
 
 					case TOKEN_NEWLINE:
-						// handle things like
-						//     [*]list\nitem\n[*]list1
-						// where it should come out as
-						//     [*]list\nitem[/*]\n[*]list1[/*]
-						// instead of
-						//     [*]list\nitem\n[/*][*]list1[/*]
-						if (currentTag() && next && closesCurrentTag(
-							(next.type === TOKEN_CLOSE ? '/' : '') +
-							next.name
-						)) {
-							// skip if the next tag is the closing tag for
-							// the option tag, i.e. [/*]
-							if (!(next.type === TOKEN_CLOSE &&
-								next.name === currentTag().name)) {
-								bbcode = bbcodeHandlers[currentTag().name];
-
-								if (bbcode && bbcode.breakAfter) {
-									openTags.pop();
-								} else if (bbcode &&
-									bbcode.isInline === false &&
-									base.opts.breakAfterBlock &&
-									bbcode.breakAfter !== false) {
-									openTags.pop();
-								}
-							}
-						}
-
 						addTag(token);
 						break;
 
@@ -1913,14 +1853,11 @@
 						ret += convertToBBCode(token.children);
 					}
 
-					// add closing tag if not self closing
-					if (!bbcode.excludeClosing) {
-						if (breakEnd) {
-							ret += '\n';
-						}
+					if (breakEnd) {
+						ret += '\n';
+					}
 
-						ret += '[/' + token.name + ']';
-					}
+					ret += '[/' + token.name + ']';
 
 					if (breakAfter) {
 						ret += '\n';
@@ -2440,11 +2377,13 @@
 		 *
 		 * @param {string} source
 		 */
-		function toHtml(source) {
+		function toHtml(source, asFragment) {
 			let parser = newBBCodeParser(base.editor);
 			let html = parser.toHTML(
 				base.opts.bbcodeTrim ? source.trim() : source
 			);
+			if( asFragment )
+				html = removeFirstLastDiv(html);
 			return html;
 		}
 
@@ -2458,60 +2397,57 @@
 		 * @return {string}
 		 * @private
 		 */
-		function toSource(asFragment) {
-			return function(html, context, parent) {
-				context = context || document;
+		function toSource(html, context, parent, asFragment) {
+			context = context || document;
 
-				var	bbcode, elements;
-				var containerParent = context.createElement('div');
-				var container = context.createElement('div');
-				var parser = newBBCodeParser(base.editor);
+			var	bbcode, elements;
+			var containerParent = context.createElement('div');
+			var container = context.createElement('div');
+			var parser = newBBCodeParser(base.editor);
 
-				container.innerHTML = html;
-				css(containerParent, 'visibility', 'hidden');
-				containerParent.appendChild(container);
-				context.body.appendChild(containerParent);
+			container.innerHTML = html;
+			css(containerParent, 'visibility', 'hidden');
+			containerParent.appendChild(container);
+			context.body.appendChild(containerParent);
 
-				if (asFragment) {
-					// Add text before and after so removeWhiteSpace doesn't remove
-					// leading and trailing whitespace
-					containerParent.insertBefore(
-						context.createTextNode('#'),
-						containerParent.firstChild
-					);
-					containerParent.appendChild(context.createTextNode('#'));
-				}
+			if (asFragment) {
+				// Add text before and after so removeWhiteSpace doesn't remove
+				// leading and trailing whitespace
+				containerParent.insertBefore(
+					context.createTextNode('#'),
+					containerParent.firstChild
+				);
+				containerParent.appendChild(context.createTextNode('#'));
+			}
 
-				// Match parents white-space handling
-				if (parent) {
-					css(container, 'whiteSpace', css(parent, 'whiteSpace'));
-				}
+			// Match parents white-space handling
+			if (parent) {
+				css(container, 'whiteSpace', css(parent, 'whiteSpace'));
+			}
 
-				// Remove all nodes with sceditor-ignore class
-				elements = container.getElementsByClassName('sceditor-ignore');
-				while (elements.length) {
-					elements[0].parentNode.removeChild(elements[0]);
-				}
-
-				dom.removeWhiteSpace(containerParent);
+			// Remove all nodes with sceditor-ignore class
+			elements = container.getElementsByClassName('sceditor-ignore');
+			while (elements.length) {
+				elements[0].parentNode.removeChild(elements[0]);
+			}
 
-				bbcode = elementToBbcode(container);
+			dom.removeWhiteSpace(containerParent);
 
-				context.body.removeChild(containerParent);
+			bbcode = elementToBbcode(container);
 
-				bbcode = parser.toBBCode(bbcode, true);
+			context.body.removeChild(containerParent);
 
-				if (base.opts.bbcodeTrim) {
-					bbcode = bbcode.trim();
-				}
+			bbcode = parser.toBBCode(bbcode, true);
 
-				return bbcode;
-			};
+			if (base.opts.bbcodeTrim) {
+				bbcode = bbcode.trim();
+			}
+
+			return bbcode;
 		}
 
 		base.toHtml = toHtml;
-		base.toSource = toSource(false);
-		base.fragmentToSource = toSource(true);
+		base.toSource = toSource;
 
 		return base;
 	};
--- a/src/formats/xhtml.js	Tue Aug 30 02:03:50 2022 -0600
+++ b/src/formats/xhtml.js	Tue Aug 30 14:33:27 2022 -0600
@@ -538,34 +538,30 @@
 		 * @return {string}
 		 * @memberOf jQuery.sceditor.plugins.xhtml.prototype
 		 */
-		function toSource(isFragment) {
-			return function(html, context) {
-				var xhtml,
-					container = context.createElement('div');
-				container.innerHTML = html;
+		function toSource(html, context, parent, asFragment) {
+			var xhtml,
+				container = context.createElement('div');
+			container.innerHTML = html;
 
-				css(container, 'visibility', 'hidden');
-				context.body.appendChild(container);
+			css(container, 'visibility', 'hidden');
+			context.body.appendChild(container);
 
-				convertTags(container);
-				removeTags(container);
-				removeAttribs(container);
+			convertTags(container);
+			removeTags(container);
+			removeAttribs(container);
 
-				if (!isFragment) {
-					wrapInlines(container);
-				}
+			if (!asFragment) {
+				wrapInlines(container);
+			}
 
-				xhtml = (new sceditor.XHTMLSerializer()).serialize(container, true);
+			xhtml = (new sceditor.XHTMLSerializer()).serialize(container, true);
 
-				context.body.removeChild(container);
+			context.body.removeChild(container);
 
-				return xhtml;
-			};
+			return xhtml;
 		}
 
-		base.toSource = toSource(false);
-
-		base.fragmentToSource = toSource(true);;
+		base.toSource = toSource;
 
 		/**
 		 * Runs all converters for the specified tagName
--- a/src/plugins/alternative-lists.js	Tue Aug 30 02:03:50 2022 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-/**
- * SCEditor Inline-Code Plugin for BBCode format
- * http://www.sceditor.com/
- *
- * Copyright (C) 2011-2013, Sam Clarke (samclarke.com)
- *
- * SCEditor is licensed under the MIT license:
- *	http://www.opensource.org/licenses/mit-license.php
- *
- * @fileoverview SCEditor alternative lists plugin
- * This plugin implements phpBB style of the lists:
- * [list]
- * [*]item
- * [*]item
- * [/list]
- * @author Alex Betis
- */
-
-(function (sceditor) {
-	'use strict';
-
-	var utils = sceditor.utils;
-
-	function isFunction(fn) {
-		return typeof fn === 'function';
-	}
-
-	sceditor.plugins['alternative-lists'] = function () {
-		var base = {};
-
-		/**
-		 * Private functions
-		 * @private
-		 */
-		var bulletHandler;
-		var orderedHandler;
-
-		base.init = function (editor) {
-			var opts = editor.opts;
-
-			// Enable for BBCode only
-			if (opts.format && opts.format !== 'bbcode') {
-				return;
-			}
-
-			// Override only txtExec implementation
-			editor.commands.orderedlist.txtExec = orderedHandler;
-			editor.commands.bulletlist.txtExec = bulletHandler;
-
-			// Override current implementation
-			sceditor.formats.bbcode.set('list', {
-				breakStart: true,
-				isInline: false,
-				skipLastLineBreak: true,
-				html: function (token, attrs, content) {
-					var listType = 'disc';
-					var toHtml = null;
-
-					if (attrs.defaultattr) {
-						listType = attrs.defaultattr;
-					}
-
-					if (listType === '1') {
-						// This listType belongs to orderedList (OL)
-						toHtml = sceditor.formats.bbcode.get('ol').html;
-					} else {
-						// unknown listType, use default bullet list behavior
-						toHtml = sceditor.formats.bbcode.get('ul').html;
-					}
-
-					if (isFunction(toHtml)) {
-						return toHtml(token, attrs, content);
-					} else {
-						token.attrs['0'] = content;
-						return sceditor.formats.bbcode.formatBBCodeString(
-							toHtml, token.attrs);
-					}
-				}
-			});
-
-			sceditor.formats.bbcode.set('ul', {
-				tags: {
-					ul: null
-				},
-				breakStart: true,
-				isInline: false,
-				skipLastLineBreak: true,
-				format: '[list]{0}[/list]',
-				html: '<ul>{0}</ul>'
-			});
-
-			sceditor.formats.bbcode.set('ol', {
-				tags: {
-					ol: null
-				},
-				breakStart: true,
-				isInline: false,
-				skipLastLineBreak: true,
-				format: '[list=1]{0}[/list]',
-				html: '<ol>{0}</ol>'
-			});
-
-			sceditor.formats.bbcode.set('li', {
-				tags: {
-					li: null
-				},
-				isInline: false,
-				closedBy: ['/ul', '/ol', '/list', '*', 'li'],
-				format: '[*]{0}',
-				html: '<li>{0}</li>'
-			});
-
-			sceditor.formats.bbcode.set('*', {
-				isInline: false,
-				excludeClosing: true,
-				closedBy: ['/ul', '/ol', '/list', '*', 'li'],
-				html: '<li>{0}</li>'
-			});
-		};
-
-		function insertListTag(editor, listType, selected) {
-			let content = '';
-
-			utils.each(selected.split(/\r?\n/), function (_, item) {
-				content += (content ? '\n' : '') +
-					'[*]' + item;
-			});
-
-			if (listType === '') {
-				editor.insertText('[list]\n' + content + '\n[/list]');
-			} else {
-				editor.insertText('[list=' + listType + ']\n' + content +
-				'\n[/list]');
-			}
-		};
-
-		/**
-		 * Function for the txtExec and exec properties
-		 *
-		 * @param  {node} caller
-		 * @private
-		 */
-		orderedHandler = function (editor, caller, selected) {
-			insertListTag(editor, '1', selected);
-		};
-
-		bulletHandler = function (editor, caller, selected) {
-			insertListTag(editor, '', selected);
-		};
-
-		return base;
-	};
-})(sceditor);
--- a/src/sceditor.js	Tue Aug 30 02:03:50 2022 -0600
+++ b/src/sceditor.js	Tue Aug 30 14:33:27 2022 -0600
@@ -2595,7 +2595,7 @@
 					perLine = Math.sqrt(Object.keys(emoticons).length);
 
 					onEvent1(content, 'click', 'img', function (target, e) {
-						editor.insert(targetToHtml(target), null, false);
+						editor.insert(targetToHtml(target));
 						editor.closeDropDown(true);
 
 						e.preventDefault();
@@ -4763,7 +4763,7 @@
 					}
 
 					let shortcut = command.shortcut;
-					let icon = command.icon || '';
+					let icon = command.icon || '&nbsp;'+commandName+'&nbsp;';
 					let button = '<button>' + icon + '</button>';
 					button = parseHTML(button).firstChild;
 					button._sceTxtMode = !!command.txtExec;
@@ -5590,21 +5590,26 @@
 				pasteArea.innerHTML = entities(data.text || '');
 			}
 
-			var paste = {
+			let paste = {
 				val: pasteArea.innerHTML
 			};
 
-			if ('fragmentToSource' in format) {
+			if ('toSource' in format) {
 				paste.val = format
-					.fragmentToSource(paste.val, wysiwygDocument, currentNode);
+					.toSource(paste.val, wysiwygDocument, currentNode, true);
 			}
 
 			pluginManager.call('paste', paste);
 			trigger(editorContainer, 'paste', paste);
 
+			if ('toHtml' in format) {
+				paste.val = format
+					.toHtml(paste.val, currentNode, true);
+			}
+
 			pluginManager.call('pasteHtml', paste);
 
-			var parent = rangeHelper.getFirstBlockParent();
+			let parent = rangeHelper.getFirstBlockParent();
 			base.wysiwygEditorInsertHtml(paste.val, null, true);
 			merge(parent);
 		};
@@ -5897,15 +5902,13 @@
 		 *
 		 * @param {string} start
 		 * @param {string} [end=null]
-		 * @param {boolean} [filter=true]
-		 * @param {boolean} [allowMixed=false]
 		 * @since 1.4.3
 		 * @function
 		 * @name insert^2
 		 */
 		// eslint-disable-next-line max-params
 		base.insert = function (
-			start, end, filter, allowMixed
+			start, end
 		) {
 			if (base.inSourceMode()) {
 				base.sourceEditorInsertText(start, end);
@@ -5914,23 +5917,10 @@
 
 			// Add the selection between start and end
 			if (end) {
-				var	html = rangeHelper.selectedHtml();
-
-				if (filter !== false && 'fragmentToSource' in format) {
-					html = format
-						.fragmentToSource(html, wysiwygDocument, currentNode);
-				}
-
+				let	html = rangeHelper.selectedHtml();
 				start += html + end;
 			}
 
-			// Convert any escaped HTML back into HTML if mixed is allowed
-			if (filter !== false && allowMixed === true) {
-				start = start.replace(/&lt;/g, '<')
-					.replace(/&gt;/g, '>')
-					.replace(/&amp;/g, '&');
-			}
-
 			base.wysiwygEditorInsertHtml(start);
 		};
 
--- a/src/themes/default.css	Tue Aug 30 02:03:50 2022 -0600
+++ b/src/themes/default.css	Tue Aug 30 14:33:27 2022 -0600
@@ -28,8 +28,6 @@
 .sceditor-container *,
 .sceditor-container *:before,
 .sceditor-container *:after {
-	-webkit-box-sizing: content-box;
-	-moz-box-sizing: content-box;
 	box-sizing: content-box;
 }
 .sceditor-container,
@@ -148,8 +146,6 @@
 div.sceditor-dropdown *,
 div.sceditor-dropdown *:before,
 div.sceditor-dropdown *:after {
-	-webkit-box-sizing: border-box;
-	-moz-box-sizing: border-box;
 	box-sizing: border-box;
 }
 div.sceditor-dropdown a,
@@ -273,7 +269,7 @@
 	background-clip: padding-box;
 }
 div.sceditor-group {
-	display: inline-block;
+	display: inline-flex;
 	background: #ddd;
 	margin: 1px 5px 1px 0;
 	padding: 1px;
@@ -287,7 +283,7 @@
 	border: 0;
 	background: transparent;
 	cursor: pointer;
-	width: 26px;
+	min-width: 26px;
 	height: 26px;
 	border-radius: 3px;
 	display: inline-flex;