1 wysihtml5.commands.insertList = (function(wysihtml5) {
3 var isNode = function(node, name) {
4 if (node && node.nodeName) {
5 if (typeof name === 'string') {
8 for (var n = name.length; n--;) {
9 if (node.nodeName === name[n]) {
17 var findListEl = function(node, nodeName, composer) {
24 var parentLi = wysihtml5.dom.getParentElement(node, { nodeName: "LI" }),
25 otherNodeName = (nodeName === "UL") ? "OL" : "UL";
27 if (isNode(node, nodeName)) {
29 } else if (isNode(node, otherNodeName)) {
34 } else if (parentLi) {
35 if (isNode(parentLi.parentNode, nodeName)) {
36 ret.el = parentLi.parentNode;
37 } else if (isNode(parentLi.parentNode, otherNodeName)) {
39 el : parentLi.parentNode,
46 // do not count list elements outside of composer
47 if (ret.el && !composer.element.contains(ret.el)) {
54 var handleSameTypeList = function(el, nodeName, composer) {
55 var otherNodeName = (nodeName === "UL") ? "OL" : "UL",
56 otherLists, innerLists;
58 // <ul><li>foo</li><li>bar</li></ul>
61 composer.selection.executeAndRestore(function() {
62 var otherLists = getListsInSelection(otherNodeName, composer);
63 if (otherLists.length) {
64 for (var l = otherLists.length; l--;) {
65 wysihtml5.dom.renameElement(otherLists[l], nodeName.toLowerCase());
68 innerLists = getListsInSelection(['OL', 'UL'], composer);
69 for (var i = innerLists.length; i--;) {
70 wysihtml5.dom.resolveList(innerLists[i], composer.config.useLineBreaks);
72 wysihtml5.dom.resolveList(el, composer.config.useLineBreaks);
77 var handleOtherTypeList = function(el, nodeName, composer) {
78 var otherNodeName = (nodeName === "UL") ? "OL" : "UL";
79 // Turn an ordered list into an unordered list
80 // <ol><li>foo</li><li>bar</li></ol>
82 // <ul><li>foo</li><li>bar</li></ul>
83 // Also rename other lists in selection
84 composer.selection.executeAndRestore(function() {
85 var renameLists = [el].concat(getListsInSelection(otherNodeName, composer));
87 // All selection inner lists get renamed too
88 for (var l = renameLists.length; l--;) {
89 wysihtml5.dom.renameElement(renameLists[l], nodeName.toLowerCase());
94 var getListsInSelection = function(nodeName, composer) {
95 var ranges = composer.selection.getOwnRanges(),
98 for (var r = ranges.length; r--;) {
99 renameLists = renameLists.concat(ranges[r].getNodes([1], function(node) {
100 return isNode(node, nodeName);
107 var createListFallback = function(nodeName, composer) {
108 // Fallback for Create list
109 composer.selection.executeAndRestoreRangy(function() {
110 var tempClassName = "_wysihtml5-temp-" + new Date().getTime(),
111 tempElement = composer.selection.deblockAndSurround({
113 "className": tempClassName
117 // This space causes new lists to never break on enter
118 var INVISIBLE_SPACE_REG_EXP = /\uFEFF/g;
119 tempElement.innerHTML = tempElement.innerHTML.replace(wysihtml5.INVISIBLE_SPACE_REG_EXP, "");
122 isEmpty = wysihtml5.lang.array(["", "<br>", wysihtml5.INVISIBLE_SPACE]).contains(tempElement.innerHTML);
123 list = wysihtml5.dom.convertToList(tempElement, nodeName.toLowerCase(), composer.parent.config.uneditableContainerClassname);
125 composer.selection.selectNode(list.querySelector("li"), true);
132 exec: function(composer, command, nodeName) {
133 var doc = composer.doc,
134 cmd = (nodeName === "OL") ? "insertOrderedList" : "insertUnorderedList",
135 selectedNode = composer.selection.getSelectedNode(),
136 list = findListEl(selectedNode, nodeName, composer);
139 if (composer.commands.support(cmd)) {
140 doc.execCommand(cmd, false, null);
142 createListFallback(nodeName, composer);
144 } else if (list.other) {
145 handleOtherTypeList(list.el, nodeName, composer);
147 handleSameTypeList(list.el, nodeName, composer);
151 state: function(composer, command, nodeName) {
152 var selectedNode = composer.selection.getSelectedNode(),
153 list = findListEl(selectedNode, nodeName, composer);
155 return (list.el && !list.other) ? list.el : false;