You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							370 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							370 lines
						
					
					
						
							11 KiB
						
					
					
				| (function () { | |
| var textpattern = (function () { | |
|   'use strict'; | |
| 
 | |
|   var Cell = function (initial) { | |
|     var value = initial; | |
|     var get = function () { | |
|       return value; | |
|     }; | |
|     var set = function (v) { | |
|       value = v; | |
|     }; | |
|     var clone = function () { | |
|       return Cell(get()); | |
|     }; | |
|     return { | |
|       get: get, | |
|       set: set, | |
|       clone: clone | |
|     }; | |
|   }; | |
| 
 | |
|   var PluginManager = tinymce.util.Tools.resolve('tinymce.PluginManager'); | |
| 
 | |
|   var get = function (patternsState) { | |
|     var setPatterns = function (newPatterns) { | |
|       patternsState.set(newPatterns); | |
|     }; | |
|     var getPatterns = function () { | |
|       return patternsState.get(); | |
|     }; | |
|     return { | |
|       setPatterns: setPatterns, | |
|       getPatterns: getPatterns | |
|     }; | |
|   }; | |
|   var $_7212mvq3jd09eyro = { get: get }; | |
| 
 | |
|   var defaultPatterns = [ | |
|     { | |
|       start: '*', | |
|       end: '*', | |
|       format: 'italic' | |
|     }, | |
|     { | |
|       start: '**', | |
|       end: '**', | |
|       format: 'bold' | |
|     }, | |
|     { | |
|       start: '***', | |
|       end: '***', | |
|       format: [ | |
|         'bold', | |
|         'italic' | |
|       ] | |
|     }, | |
|     { | |
|       start: '#', | |
|       format: 'h1' | |
|     }, | |
|     { | |
|       start: '##', | |
|       format: 'h2' | |
|     }, | |
|     { | |
|       start: '###', | |
|       format: 'h3' | |
|     }, | |
|     { | |
|       start: '####', | |
|       format: 'h4' | |
|     }, | |
|     { | |
|       start: '#####', | |
|       format: 'h5' | |
|     }, | |
|     { | |
|       start: '######', | |
|       format: 'h6' | |
|     }, | |
|     { | |
|       start: '1. ', | |
|       cmd: 'InsertOrderedList' | |
|     }, | |
|     { | |
|       start: '* ', | |
|       cmd: 'InsertUnorderedList' | |
|     }, | |
|     { | |
|       start: '- ', | |
|       cmd: 'InsertUnorderedList' | |
|     } | |
|   ]; | |
|   var getPatterns = function (editorSettings) { | |
|     return editorSettings.textpattern_patterns !== undefined ? editorSettings.textpattern_patterns : defaultPatterns; | |
|   }; | |
|   var $_cuxek9q4jd09eyrp = { getPatterns: getPatterns }; | |
| 
 | |
|   var Delay = tinymce.util.Tools.resolve('tinymce.util.Delay'); | |
| 
 | |
|   var VK = tinymce.util.Tools.resolve('tinymce.util.VK'); | |
| 
 | |
|   var TreeWalker = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker'); | |
| 
 | |
|   var Tools = tinymce.util.Tools.resolve('tinymce.util.Tools'); | |
| 
 | |
|   var sortPatterns = function (patterns) { | |
|     return patterns.sort(function (a, b) { | |
|       if (a.start.length > b.start.length) { | |
|         return -1; | |
|       } | |
|       if (a.start.length < b.start.length) { | |
|         return 1; | |
|       } | |
|       return 0; | |
|     }); | |
|   }; | |
|   var findPattern = function (patterns, text) { | |
|     for (var i = 0; i < patterns.length; i++) { | |
|       if (text.indexOf(patterns[i].start) !== 0) { | |
|         continue; | |
|       } | |
|       if (patterns[i].end && text.lastIndexOf(patterns[i].end) !== text.length - patterns[i].end.length) { | |
|         continue; | |
|       } | |
|       return patterns[i]; | |
|     } | |
|   }; | |
|   var isMatchingPattern = function (pattern, text, offset, delta) { | |
|     var textEnd = text.substr(offset - pattern.end.length - delta, pattern.end.length); | |
|     return textEnd === pattern.end; | |
|   }; | |
|   var hasContent = function (offset, delta, pattern) { | |
|     return offset - delta - pattern.end.length - pattern.start.length > 0; | |
|   }; | |
|   var findEndPattern = function (patterns, text, offset, delta) { | |
|     var pattern, i; | |
|     var sortedPatterns = sortPatterns(patterns); | |
|     for (i = 0; i < sortedPatterns.length; i++) { | |
|       pattern = sortedPatterns[i]; | |
|       if (pattern.end !== undefined && isMatchingPattern(pattern, text, offset, delta) && hasContent(offset, delta, pattern)) { | |
|         return pattern; | |
|       } | |
|     } | |
|   }; | |
|   var $_g9hn94qcjd09eyrz = { | |
|     findPattern: findPattern, | |
|     findEndPattern: findEndPattern | |
|   }; | |
| 
 | |
|   var splitContainer = function (container, pattern, endOffset, startOffset, space) { | |
|     container = startOffset > 0 ? container.splitText(startOffset) : container; | |
|     container.splitText(endOffset - startOffset + pattern.end.length); | |
|     container.deleteData(0, pattern.start.length); | |
|     container.deleteData(container.data.length - pattern.end.length, pattern.end.length); | |
|     return container; | |
|   }; | |
|   var patternFromRng = function (patterns, rng, space) { | |
|     if (rng.collapsed === false) { | |
|       return; | |
|     } | |
|     var container = rng.startContainer; | |
|     var text = container.data; | |
|     var delta = space === true ? 1 : 0; | |
|     if (container.nodeType !== 3) { | |
|       return; | |
|     } | |
|     var endPattern = $_g9hn94qcjd09eyrz.findEndPattern(patterns, text, rng.startOffset, delta); | |
|     if (endPattern === undefined) { | |
|       return; | |
|     } | |
|     var endOffset = text.lastIndexOf(endPattern.end, rng.startOffset - delta); | |
|     var startOffset = text.lastIndexOf(endPattern.start, endOffset - endPattern.end.length); | |
|     endOffset = text.indexOf(endPattern.end, startOffset + endPattern.start.length); | |
|     if (startOffset === -1) { | |
|       return; | |
|     } | |
|     var patternRng = document.createRange(); | |
|     patternRng.setStart(container, startOffset); | |
|     patternRng.setEnd(container, endOffset + endPattern.end.length); | |
|     var startPattern = $_g9hn94qcjd09eyrz.findPattern(patterns, patternRng.toString()); | |
|     if (endPattern === undefined || startPattern !== endPattern || container.data.length <= endPattern.start.length + endPattern.end.length) { | |
|       return; | |
|     } | |
|     return { | |
|       pattern: endPattern, | |
|       startOffset: startOffset, | |
|       endOffset: endOffset | |
|     }; | |
|   }; | |
|   var splitAndApply = function (editor, container, found, space) { | |
|     var formatArray = Tools.isArray(found.pattern.format) ? found.pattern.format : [found.pattern.format]; | |
|     var validFormats = Tools.grep(formatArray, function (formatName) { | |
|       var format = editor.formatter.get(formatName); | |
|       return format && format[0].inline; | |
|     }); | |
|     if (validFormats.length !== 0) { | |
|       editor.undoManager.transact(function () { | |
|         container = splitContainer(container, found.pattern, found.endOffset, found.startOffset, space); | |
|         formatArray.forEach(function (format) { | |
|           editor.formatter.apply(format, {}, container); | |
|         }); | |
|       }); | |
|       return container; | |
|     } | |
|   }; | |
|   var doApplyInlineFormat = function (editor, patterns, space) { | |
|     var rng = editor.selection.getRng(true); | |
|     var foundPattern = patternFromRng(patterns, rng, space); | |
|     if (foundPattern) { | |
|       return splitAndApply(editor, rng.startContainer, foundPattern, space); | |
|     } | |
|   }; | |
|   var applyInlineFormatSpace = function (editor, patterns) { | |
|     return doApplyInlineFormat(editor, patterns, true); | |
|   }; | |
|   var applyInlineFormatEnter = function (editor, patterns) { | |
|     return doApplyInlineFormat(editor, patterns, false); | |
|   }; | |
|   var applyBlockFormat = function (editor, patterns) { | |
|     var selection, dom, container, firstTextNode, node, format, textBlockElm, pattern, walker, rng, offset; | |
|     selection = editor.selection; | |
|     dom = editor.dom; | |
|     if (!selection.isCollapsed()) { | |
|       return; | |
|     } | |
|     textBlockElm = dom.getParent(selection.getStart(), 'p'); | |
|     if (textBlockElm) { | |
|       walker = new TreeWalker(textBlockElm, textBlockElm); | |
|       while (node = walker.next()) { | |
|         if (node.nodeType === 3) { | |
|           firstTextNode = node; | |
|           break; | |
|         } | |
|       } | |
|       if (firstTextNode) { | |
|         pattern = $_g9hn94qcjd09eyrz.findPattern(patterns, firstTextNode.data); | |
|         if (!pattern) { | |
|           return; | |
|         } | |
|         rng = selection.getRng(true); | |
|         container = rng.startContainer; | |
|         offset = rng.startOffset; | |
|         if (firstTextNode === container) { | |
|           offset = Math.max(0, offset - pattern.start.length); | |
|         } | |
|         if (Tools.trim(firstTextNode.data).length === pattern.start.length) { | |
|           return; | |
|         } | |
|         if (pattern.format) { | |
|           format = editor.formatter.get(pattern.format); | |
|           if (format && format[0].block) { | |
|             firstTextNode.deleteData(0, pattern.start.length); | |
|             editor.formatter.apply(pattern.format, {}, firstTextNode); | |
|             rng.setStart(container, offset); | |
|             rng.collapse(true); | |
|             selection.setRng(rng); | |
|           } | |
|         } | |
|         if (pattern.cmd) { | |
|           editor.undoManager.transact(function () { | |
|             firstTextNode.deleteData(0, pattern.start.length); | |
|             editor.execCommand(pattern.cmd); | |
|           }); | |
|         } | |
|       } | |
|     } | |
|   }; | |
|   var $_4u8b1bq9jd09eyrv = { | |
|     patternFromRng: patternFromRng, | |
|     applyInlineFormatSpace: applyInlineFormatSpace, | |
|     applyInlineFormatEnter: applyInlineFormatEnter, | |
|     applyBlockFormat: applyBlockFormat | |
|   }; | |
| 
 | |
|   function handleEnter(editor, patterns) { | |
|     var wrappedTextNode, rng; | |
|     wrappedTextNode = $_4u8b1bq9jd09eyrv.applyInlineFormatEnter(editor, patterns); | |
|     if (wrappedTextNode) { | |
|       rng = editor.dom.createRng(); | |
|       rng.setStart(wrappedTextNode, wrappedTextNode.data.length); | |
|       rng.setEnd(wrappedTextNode, wrappedTextNode.data.length); | |
|       editor.selection.setRng(rng); | |
|     } | |
|     $_4u8b1bq9jd09eyrv.applyBlockFormat(editor, patterns); | |
|   } | |
|   function handleInlineKey(editor, patterns) { | |
|     var wrappedTextNode, lastChar, lastCharNode, rng, dom; | |
|     wrappedTextNode = $_4u8b1bq9jd09eyrv.applyInlineFormatSpace(editor, patterns); | |
|     if (wrappedTextNode) { | |
|       dom = editor.dom; | |
|       lastChar = wrappedTextNode.data.slice(-1); | |
|       if (/[\u00a0 ]/.test(lastChar)) { | |
|         wrappedTextNode.deleteData(wrappedTextNode.data.length - 1, 1); | |
|         lastCharNode = dom.doc.createTextNode(lastChar); | |
|         dom.insertAfter(lastCharNode, wrappedTextNode.parentNode); | |
|         rng = dom.createRng(); | |
|         rng.setStart(lastCharNode, 1); | |
|         rng.setEnd(lastCharNode, 1); | |
|         editor.selection.setRng(rng); | |
|       } | |
|     } | |
|   } | |
|   var checkKeyEvent = function (codes, event, predicate) { | |
|     for (var i = 0; i < codes.length; i++) { | |
|       if (predicate(codes[i], event)) { | |
|         return true; | |
|       } | |
|     } | |
|   }; | |
|   var checkKeyCode = function (codes, event) { | |
|     return checkKeyEvent(codes, event, function (code, event) { | |
|       return code === event.keyCode && VK.modifierPressed(event) === false; | |
|     }); | |
|   }; | |
|   var checkCharCode = function (chars, event) { | |
|     return checkKeyEvent(chars, event, function (chr, event) { | |
|       return chr.charCodeAt(0) === event.charCode; | |
|     }); | |
|   }; | |
|   var $_101d6xq8jd09eyrs = { | |
|     handleEnter: handleEnter, | |
|     handleInlineKey: handleInlineKey, | |
|     checkCharCode: checkCharCode, | |
|     checkKeyCode: checkKeyCode | |
|   }; | |
| 
 | |
|   var setup = function (editor, patternsState) { | |
|     var charCodes = [ | |
|       ',', | |
|       '.', | |
|       ';', | |
|       ':', | |
|       '!', | |
|       '?' | |
|     ]; | |
|     var keyCodes = [32]; | |
|     editor.on('keydown', function (e) { | |
|       if (e.keyCode === 13 && !VK.modifierPressed(e)) { | |
|         $_101d6xq8jd09eyrs.handleEnter(editor, patternsState.get()); | |
|       } | |
|     }, true); | |
|     editor.on('keyup', function (e) { | |
|       if ($_101d6xq8jd09eyrs.checkKeyCode(keyCodes, e)) { | |
|         $_101d6xq8jd09eyrs.handleInlineKey(editor, patternsState.get()); | |
|       } | |
|     }); | |
|     editor.on('keypress', function (e) { | |
|       if ($_101d6xq8jd09eyrs.checkCharCode(charCodes, e)) { | |
|         Delay.setEditorTimeout(editor, function () { | |
|           $_101d6xq8jd09eyrs.handleInlineKey(editor, patternsState.get()); | |
|         }); | |
|       } | |
|     }); | |
|   }; | |
|   var $_159oeuq5jd09eyrq = { setup: setup }; | |
| 
 | |
|   PluginManager.add('textpattern', function (editor) { | |
|     var patternsState = Cell($_cuxek9q4jd09eyrp.getPatterns(editor.settings)); | |
|     $_159oeuq5jd09eyrq.setup(editor, patternsState); | |
|     return $_7212mvq3jd09eyro.get(patternsState); | |
|   }); | |
|   function Plugin () { | |
|   } | |
| 
 | |
|   return Plugin; | |
| 
 | |
| }()); | |
| })()
 |