] var ancestors = listAncestor(point.node, func.eq(root)); if (!ancestors.length) { return null; } else if (ancestors.length === 1) { return splitNode(point, options); } return ancestors.reduce(function (node, parent) { if (node === point.node) { node = splitNode(point, options); } return splitNode({ node: parent, offset: node ? position(node) : nodeLength(parent) }, options); }); } /** * split point * * @param {Point} point * @param {Boolean} isInline * @return {Object} */ function splitPoint(point, isInline) { // find splitRoot, container // - inline: splitRoot is a child of paragraph // - block: splitRoot is a child of bodyContainer var pred = isInline ? isPara : isBodyContainer; var ancestors = listAncestor(point.node, pred); var topAncestor = lists.last(ancestors) || point.node; var splitRoot, container; if (pred(topAncestor)) { splitRoot = ancestors[ancestors.length - 2]; container = topAncestor; } else { splitRoot = topAncestor; container = splitRoot.parentNode; } // if splitRoot is exists, split with splitTree var pivot = splitRoot && splitTree(splitRoot, point, { isSkipPaddingBlankHTML: isInline, isNotSplitEdgePoint: isInline }); // if container is point.node, find pivot with point.offset if (!pivot && container === point.node) { pivot = point.node.childNodes[point.offset]; } return { rightNode: pivot, container: container }; } function create(nodeName) { return document.createElement(nodeName); } function createText(text) { return document.createTextNode(text); } /** * @method remove * * remove node, (isRemoveChild: remove child or not) * * @param {Node} node * @param {Boolean} isRemoveChild */ function remove(node, isRemoveChild) { if (!node || !node.parentNode) { return; } if (node.removeNode) { return node.removeNode(isRemoveChild); } var parent = node.parentNode; if (!isRemoveChild) { var nodes = []; for (var i = 0, len = node.childNodes.length; i < len; i++) { nodes.push(node.childNodes[i]); } for (var i = 0, len = nodes.length; i < len; i++) { parent.insertBefore(nodes[i], node); } } parent.removeChild(node); } /** * @method removeWhile * * @param {Node} node * @param {Function} pred */ function removeWhile(node, pred) { while (node) { if (isEditable(node) || !pred(node)) { break; } var parent = node.parentNode; remove(node); node = parent; } } /** * @method replace * * replace node with provided nodeName * * @param {Node} node * @param {String} nodeName * @return {Node} - new node */ function replace(node, nodeName) { if (node.nodeName.toUpperCase() === nodeName.toUpperCase()) { return node; } var newNode = create(nodeName); if (node.style.cssText) { newNode.style.cssText = node.style.cssText; } appendChildNodes(newNode, lists.from(node.childNodes)); insertAfter(newNode, node); remove(node); return newNode; } var isTextarea = makePredByNodeName('TEXTAREA'); /** * @param {jQuery} $node * @param {Boolean} [stripLinebreaks] - default: false */ function value($node, stripLinebreaks) { var val = isTextarea($node[0]) ? $node.val() : $node.html(); if (stripLinebreaks) { return val.replace(/[\n\r]/g, ''); } return val; } /** * @method html * * get the HTML contents of node * * @param {jQuery} $node * @param {Boolean} [isNewlineOnBlock] */ function html($node, isNewlineOnBlock) { var markup = value($node); if (isNewlineOnBlock) { var regexTag = /<(\/?)(\b(?!!)[^>\s]*)(.*?)(\s*\/?>)/g; markup = markup.replace(regexTag, function (match, endSlash, name) { name = name.toUpperCase(); var isEndOfInlineContainer = /^DIV|^TD|^TH|^P|^LI|^H[1-7]/.test(name) && !!endSlash; var isBlockNode = /^BLOCKQUOTE|^TABLE|^TBODY|^TR|^HR|^UL|^OL/.test(name); return match + ((isEndOfInlineContainer || isBlockNode) ? '\n' : ''); }); markup = $$1.trim(markup); } return markup; } function posFromPlaceholder(placeholder) { var $placeholder = $$1(placeholder); var pos = $placeholder.offset(); var height = $placeholder.outerHeight(true); // include margin return { left: pos.left, top: pos.top + height }; } function attachEvents($node, events) { Object.keys(events).forEach(function (key) { $node.on(key, events[key]); }); } function detachEvents($node, events) { Object.keys(events).forEach(function (key) { $node.off(key, events[key]); }); } /** * @method isCustomStyleTag * * assert if a node contains a "note-styletag" class, * which implies that's a custom-made style tag node * * @param {Node} an HTML DOM node */ function isCustomStyleTag(node) { return node && !isText(node) && lists.contains(node.classList, 'note-styletag'); } var dom = { /** @property {String} NBSP_CHAR */ NBSP_CHAR: NBSP_CHAR, /** @property {String} ZERO_WIDTH_NBSP_CHAR */ ZERO_WIDTH_NBSP_CHAR: ZERO_WIDTH_NBSP_CHAR, /** @property {String} blank */ blank: blankHTML, /** @property {String} emptyPara */ emptyPara: "
" + blankHTML + "
text
|text|
', 'Summernote 0.8.10 · ', 'Project · ', 'Issues', '