v1.0
只读模式 group, 分享 评论更多问题 博客标签总是存在一个
This commit is contained in:
199
public/tinymce/classes/EnterKey.js
Normal file → Executable file
199
public/tinymce/classes/EnterKey.js
Normal file → Executable file
@ -13,16 +13,18 @@
|
||||
*/
|
||||
define("tinymce/EnterKey", [
|
||||
"tinymce/dom/TreeWalker",
|
||||
"tinymce/dom/RangeUtils",
|
||||
"tinymce/Env"
|
||||
], function(TreeWalker, Env) {
|
||||
], function(TreeWalker, RangeUtils, Env) {
|
||||
var isIE = Env.ie && Env.ie < 11;
|
||||
|
||||
return function(editor) {
|
||||
var dom = editor.dom, selection = editor.selection, settings = editor.settings;
|
||||
var undoManager = editor.undoManager, schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements();
|
||||
var undoManager = editor.undoManager, schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements(),
|
||||
moveCaretBeforeOnEnterElementsMap = schema.getMoveCaretBeforeOnEnterElements();
|
||||
|
||||
function handleEnterKey(evt) {
|
||||
var rng = selection.getRng(true), tmpRng, editableRoot, container, offset, parentBlock, documentMode, shiftKey,
|
||||
var rng, tmpRng, editableRoot, container, offset, parentBlock, documentMode, shiftKey,
|
||||
newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer;
|
||||
|
||||
// Returns true if the block can be split into two blocks or not
|
||||
@ -51,6 +53,10 @@ define("tinymce/EnterKey", [
|
||||
function trimInlineElementsOnLeftSideOfBlock(block) {
|
||||
var node = block, firstChilds = [], i;
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find inner most first child ex: <p><i><b>*</b></i></p>
|
||||
while ((node = node.firstChild)) {
|
||||
if (dom.isBlock(node)) {
|
||||
@ -80,7 +86,6 @@ define("tinymce/EnterKey", [
|
||||
// pure whitespace text node or before an image
|
||||
function moveToCaretPosition(root) {
|
||||
var walker, node, rng, lastNode = root, tempElm;
|
||||
|
||||
function firstNonWhiteSpaceNodeSibling(node) {
|
||||
while (node) {
|
||||
if (node.nodeType == 1 || (node.nodeType == 3 && node.data && /[\r\n\s]/.test(node.data))) {
|
||||
@ -91,16 +96,36 @@ define("tinymce/EnterKey", [
|
||||
}
|
||||
}
|
||||
|
||||
if (root.nodeName == 'LI') {
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Old IE versions doesn't properly render blocks with br elements in them
|
||||
// For example <p><br></p> wont be rendered correctly in a contentEditable area
|
||||
// until you remove the br producing <p></p>
|
||||
if (Env.ie && Env.ie < 9 && parentBlock && parentBlock.firstChild) {
|
||||
if (parentBlock.firstChild == parentBlock.lastChild && parentBlock.firstChild.tagName == 'BR') {
|
||||
dom.remove(parentBlock.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
if (/^(LI|DT|DD)$/.test(root.nodeName)) {
|
||||
var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
|
||||
|
||||
if (firstChild && /^(UL|OL)$/.test(firstChild.nodeName)) {
|
||||
if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {
|
||||
root.insertBefore(dom.doc.createTextNode('\u00a0'), root.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
rng = dom.createRng();
|
||||
|
||||
// Normalize whitespace to remove empty text nodes. Fix for: #6904
|
||||
// Gecko will be able to place the caret in empty text nodes but it won't render propery
|
||||
// Older IE versions will sometimes crash so for now ignore all IE versions
|
||||
if (!Env.ie) {
|
||||
root.normalize();
|
||||
}
|
||||
|
||||
if (root.hasChildNodes()) {
|
||||
walker = new TreeWalker(root, root);
|
||||
|
||||
@ -111,7 +136,7 @@ define("tinymce/EnterKey", [
|
||||
break;
|
||||
}
|
||||
|
||||
if (nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
|
||||
if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) {
|
||||
rng.setStartBefore(node);
|
||||
rng.setEndBefore(node);
|
||||
break;
|
||||
@ -164,7 +189,7 @@ define("tinymce/EnterKey", [
|
||||
// Creates a new block element by cloning the current one or creating a new one if the name is specified
|
||||
// This function will also copy any text formatting from the parent block and add it to the new one
|
||||
function createNewBlock(name) {
|
||||
var node = container, block, clonedNode, caretNode;
|
||||
var node = container, block, clonedNode, caretNode, textInlineElements = schema.getTextInlineElements();
|
||||
|
||||
if (name || parentBlockName == "TABLE") {
|
||||
block = dom.create(name || newBlockName);
|
||||
@ -178,7 +203,7 @@ define("tinymce/EnterKey", [
|
||||
// Clone any parent styles
|
||||
if (settings.keep_styles !== false) {
|
||||
do {
|
||||
if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(node.nodeName)) {
|
||||
if (textInlineElements[node.nodeName]) {
|
||||
// Never clone a caret containers
|
||||
if (node.id == '_mce_caret') {
|
||||
continue;
|
||||
@ -339,7 +364,7 @@ define("tinymce/EnterKey", [
|
||||
function getContainerBlock() {
|
||||
var containerBlockParent = containerBlock.parentNode;
|
||||
|
||||
if (containerBlockParent.nodeName == 'LI') {
|
||||
if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) {
|
||||
return containerBlockParent;
|
||||
}
|
||||
|
||||
@ -399,56 +424,9 @@ define("tinymce/EnterKey", [
|
||||
undoManager.add();
|
||||
}
|
||||
|
||||
// Walks the parent block to the right and look for BR elements
|
||||
function hasRightSideContent() {
|
||||
var walker = new TreeWalker(container, parentBlock), node;
|
||||
|
||||
while ((node = walker.next())) {
|
||||
if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inserts a BR element if the forced_root_block option is set to false or empty string
|
||||
function insertBr() {
|
||||
var brElm, extraBr, marker;
|
||||
|
||||
if (container && container.nodeType == 3 && offset >= container.nodeValue.length) {
|
||||
// Insert extra BR element at the end block elements
|
||||
if (!isIE && !hasRightSideContent()) {
|
||||
brElm = dom.create('br');
|
||||
rng.insertNode(brElm);
|
||||
rng.setStartAfter(brElm);
|
||||
rng.setEndAfter(brElm);
|
||||
extraBr = true;
|
||||
}
|
||||
}
|
||||
|
||||
brElm = dom.create('br');
|
||||
rng.insertNode(brElm);
|
||||
|
||||
// Rendering modes below IE8 doesn't display BR elements in PRE unless we have a \n before it
|
||||
if (isIE && parentBlockName == 'PRE' && (!documentMode || documentMode < 8)) {
|
||||
brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm);
|
||||
}
|
||||
|
||||
// Insert temp marker and scroll to that
|
||||
marker = dom.create('span', {}, ' ');
|
||||
brElm.parentNode.insertBefore(marker, brElm);
|
||||
selection.scrollIntoView(marker);
|
||||
dom.remove(marker);
|
||||
|
||||
if (!extraBr) {
|
||||
rng.setStartAfter(brElm);
|
||||
rng.setEndAfter(brElm);
|
||||
} else {
|
||||
rng.setStartBefore(brElm);
|
||||
rng.setEndBefore(brElm);
|
||||
}
|
||||
|
||||
selection.setRng(rng);
|
||||
undoManager.add();
|
||||
editor.execCommand("InsertLineBreak", false, evt);
|
||||
}
|
||||
|
||||
// Trims any linebreaks at the beginning of node user for example when pressing enter in a PRE element
|
||||
@ -495,59 +473,65 @@ define("tinymce/EnterKey", [
|
||||
}
|
||||
}
|
||||
|
||||
// Delete any selected contents
|
||||
if (!rng.collapsed) {
|
||||
editor.execCommand('Delete');
|
||||
return;
|
||||
}
|
||||
rng = selection.getRng(true);
|
||||
|
||||
// Event is blocked by some other handler for example the lists plugin
|
||||
if (evt.isDefaultPrevented()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup range items and newBlockName
|
||||
container = rng.startContainer;
|
||||
|
||||
// life ace, 在ace editor下回车给ace来控制
|
||||
var $container = $(container);
|
||||
var aceEditorAndPre = LeaAce.isInAce($container);
|
||||
if(aceEditorAndPre) {
|
||||
// alert(2);
|
||||
// 跳出aceEditor
|
||||
if(evt.shiftKey) {
|
||||
// alert(33);
|
||||
// var id = $container.attr('id');
|
||||
var aceEditor = aceEditorAndPre[0];
|
||||
aceEditor.blur();
|
||||
var pre = aceEditorAndPre[1];
|
||||
// 必须要延迟
|
||||
setTimeout(function() {
|
||||
aceEditor.blur();
|
||||
// log('blur...')
|
||||
var newBlock = $("<p><br /></p>");
|
||||
pre.after(newBlock);
|
||||
// log(newBlock.get(0));
|
||||
rng.setStart(newBlock.get(0), 0);
|
||||
rng.setEnd(newBlock.get(0), 0);
|
||||
// 没用
|
||||
rng.selectNode(newBlock.get(0));
|
||||
selection.setRng(rng);
|
||||
// 再延迟
|
||||
setTimeout(function() {
|
||||
selection.setRng(rng);
|
||||
}, 10);
|
||||
|
||||
// TODO ... 这里
|
||||
// log("why");
|
||||
// log(rng);
|
||||
// log(selection.getRng());
|
||||
}, 10);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// Delete any selected contents
|
||||
if (!rng.collapsed) {
|
||||
editor.execCommand('Delete');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Setup range items and newBlockName
|
||||
new RangeUtils(dom).normalize(rng);
|
||||
container = rng.startContainer;
|
||||
|
||||
// life ace, 在ace editor下回车给ace来控制
|
||||
if(window.LeaAce && LeaAce.isInAce && window.$) {
|
||||
var $container = $(container);
|
||||
var aceEditorAndPre = LeaAce.isInAce($container);
|
||||
if(aceEditorAndPre) {
|
||||
// alert(2);
|
||||
// 跳出aceEditor
|
||||
if(evt.shiftKey) {
|
||||
// alert(33);
|
||||
// var id = $container.attr('id');
|
||||
var aceEditor = aceEditorAndPre[0];
|
||||
aceEditor.blur();
|
||||
var pre = aceEditorAndPre[1];
|
||||
// 必须要延迟
|
||||
setTimeout(function() {
|
||||
aceEditor.blur();
|
||||
// log('blur...')
|
||||
var newBlock = $("<p><br /></p>");
|
||||
pre.after(newBlock);
|
||||
// log(newBlock.get(0));
|
||||
rng.setStart(newBlock.get(0), 0);
|
||||
rng.setEnd(newBlock.get(0), 0);
|
||||
// 没用
|
||||
rng.selectNode(newBlock.get(0));
|
||||
selection.setRng(rng);
|
||||
// 再延迟
|
||||
setTimeout(function() {
|
||||
selection.setRng(rng);
|
||||
}, 10);
|
||||
|
||||
// TODO ... 这里
|
||||
// log("why");
|
||||
// log(rng);
|
||||
// log(selection.getRng());
|
||||
}, 10);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
offset = rng.startOffset;
|
||||
newBlockName = (settings.force_p_newlines ? 'p' : '') || settings.forced_root_block;
|
||||
newBlockName = newBlockName ? newBlockName.toUpperCase() : '';
|
||||
@ -557,6 +541,7 @@ define("tinymce/EnterKey", [
|
||||
// Resolve node index
|
||||
if (container.nodeType == 1 && container.hasChildNodes()) {
|
||||
isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
|
||||
|
||||
container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
|
||||
if (isAfterLastNodeInContainer && container.nodeType == 3) {
|
||||
offset = container.nodeValue.length;
|
||||
@ -605,8 +590,8 @@ define("tinymce/EnterKey", [
|
||||
parentBlockName = containerBlockName;
|
||||
}
|
||||
|
||||
// Handle enter in LI
|
||||
if (parentBlockName == 'LI') {
|
||||
// Handle enter in list item
|
||||
if (/^(LI|DT|DD)$/.test(parentBlockName)) {
|
||||
if (!newBlockName && shiftKey) {
|
||||
insertBr();
|
||||
return;
|
||||
@ -680,7 +665,7 @@ define("tinymce/EnterKey", [
|
||||
dom.setAttrib(newBlock, 'id', ''); // Remove ID since it needs to be document unique
|
||||
|
||||
// Allow custom handling of new blocks
|
||||
editor.fire('NewBlock', { newBlock: newBlock });
|
||||
editor.fire('NewBlock', {newBlock: newBlock});
|
||||
|
||||
undoManager.add();
|
||||
}
|
||||
|
Reference in New Issue
Block a user