Skip to content

Commit 610246a

Browse files
authoredOct 1, 2016
Merge pull request #1347 from JoelParke/master
fix(DOM, textAngular.com.html, taExecCommand.lists.spec) Corrects iss…
2 parents 7e14a36 + 9f70441 commit 610246a

File tree

3 files changed

+343
-17
lines changed

3 files changed

+343
-17
lines changed
 

‎src/DOM.js

+174-14
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,151 @@ angular.module('textAngular.DOM', ['textAngular.factories'])
1212
listElement.remove();
1313
taSelection.setSelectionToElementEnd($target[0]);
1414
};
15+
var listElementToSelfTag = function(list, listElement, selfTag, bDefault, defaultWrap){
16+
var $target, i;
17+
// if all selected then we should remove the list
18+
// grab all li elements
19+
var priorElement;
20+
var nextElement;
21+
var children = list.find('li');
22+
var foundIndex;
23+
for (i = 0; i<children.length; i++) {
24+
if (children[i].outerHTML === listElement[0].outerHTML) {
25+
// found it...
26+
foundIndex = i;
27+
if (i>0) {
28+
priorElement = children[i-1];
29+
}
30+
if (i+1<children.length) {
31+
nextElement = children[i+1];
32+
}
33+
break;
34+
}
35+
}
36+
//console.log('listElementToSelfTag', list, listElement, selfTag, bDefault, priorElement, nextElement);
37+
// un-list the listElement
38+
var html = '';
39+
if (bDefault) {
40+
html += '<' + defaultWrap + '>' + listElement[0].innerHTML + '</' + defaultWrap + '>';
41+
} else {
42+
html += '<' + taBrowserTag(selfTag) + '>';
43+
html += '<li>' + listElement[0].innerHTML + '</li>';
44+
html += '</' + taBrowserTag(selfTag) + '>';
45+
}
46+
$target = angular.element(html);
47+
//console.log('$target', $target[0]);
48+
if (!priorElement) {
49+
// this is the first the list, so we just remove it...
50+
listElement.remove();
51+
list.after(angular.element(list[0].outerHTML));
52+
list.after($target);
53+
list.remove();
54+
taSelection.setSelectionToElementEnd($target[0]);
55+
return;
56+
} else if (!nextElement) {
57+
// this is the last in the list, so we just remove it..
58+
listElement.remove();
59+
list.after($target);
60+
taSelection.setSelectionToElementEnd($target[0]);
61+
} else {
62+
var p = list.parent();
63+
// okay it was some where in the middle... so we need to break apart the list...
64+
var html1 = '';
65+
var listTag = list[0].nodeName.toLowerCase();
66+
html1 += '<' + listTag + '>';
67+
for(i = 0; i < foundIndex; i++){
68+
html1 += '<li>' + children[i].innerHTML + '</li>';
69+
}
70+
html1 += '</' + listTag + '>';
71+
var html2 = '';
72+
html2 += '<' + listTag + '>';
73+
for(i = foundIndex+1; i < children.length; i++){
74+
html2 += '<li>' + children[i].innerHTML + '</li>';
75+
}
76+
html2 += '</' + listTag + '>';
77+
//console.log(html1, $target[0], html2);
78+
list.after(angular.element(html2));
79+
list.after($target);
80+
list.after(angular.element(html1));
81+
list.remove();
82+
//console.log('parent ******XXX*****', p[0]);
83+
taSelection.setSelectionToElementEnd($target[0]);
84+
}
85+
};
86+
var listElementsToSelfTag = function(list, listElements, selfTag, bDefault, defaultWrap){
87+
var $target, i, j, p;
88+
// grab all li elements
89+
var priorElement;
90+
var afterElement;
91+
//console.log('list:', list, 'listElements:', listElements, 'selfTag:', selfTag, 'bDefault:', bDefault);
92+
var children = list.find('li');
93+
var foundIndexes = [];
94+
for (i = 0; i<children.length; i++) {
95+
for (j = 0; j<listElements.length; j++) {
96+
if (children[i].isEqualNode(listElements[j])) {
97+
// found it...
98+
foundIndexes[j] = i;
99+
}
100+
}
101+
}
102+
if (foundIndexes[0] > 0) {
103+
priorElement = children[foundIndexes[0] - 1];
104+
}
105+
if (foundIndexes[listElements.length-1] + 1 < children.length) {
106+
afterElement = children[foundIndexes[listElements.length-1] + 1];
107+
}
108+
//console.log('listElementsToSelfTag', list, listElements, selfTag, bDefault, !priorElement, !afterElement, foundIndexes[listElements.length-1], children.length);
109+
// un-list the listElements
110+
var html = '';
111+
if (bDefault) {
112+
for (j = 0; j < listElements.length; j++) {
113+
html += '<' + defaultWrap + '>' + listElements[j].innerHTML + '</' + defaultWrap + '>';
114+
listElements[j].remove();
115+
}
116+
} else {
117+
html += '<' + taBrowserTag(selfTag) + '>';
118+
for (j = 0; j < listElements.length; j++) {
119+
html += listElements[j].outerHTML;
120+
listElements[j].remove();
121+
}
122+
html += '</' + taBrowserTag(selfTag) + '>';
123+
}
124+
$target = angular.element(html);
125+
if (!priorElement) {
126+
// this is the first the list, so we just remove it...
127+
list.after(angular.element(list[0].outerHTML));
128+
list.after($target);
129+
list.remove();
130+
taSelection.setSelectionToElementEnd($target[0]);
131+
return;
132+
} else if (!afterElement) {
133+
// this is the last in the list, so we just remove it..
134+
list.after($target);
135+
taSelection.setSelectionToElementEnd($target[0]);
136+
return;
137+
} else {
138+
// okay it was some where in the middle... so we need to break apart the list...
139+
var html1 = '';
140+
var listTag = list[0].nodeName.toLowerCase();
141+
html1 += '<' + listTag + '>';
142+
for(i = 0; i < foundIndexes[0]; i++){
143+
html1 += '<li>' + children[i].innerHTML + '</li>';
144+
}
145+
html1 += '</' + listTag + '>';
146+
var html2 = '';
147+
html2 += '<' + listTag + '>';
148+
for(i = foundIndexes[listElements.length-1]+1; i < children.length; i++){
149+
html2 += '<li>' + children[i].innerHTML + '</li>';
150+
}
151+
html2 += '</' + listTag + '>';
152+
list.after(angular.element(html2));
153+
list.after($target);
154+
list.after(angular.element(html1));
155+
list.remove();
156+
//console.log('parent ******YYY*****', list.parent()[0]);
157+
taSelection.setSelectionToElementEnd($target[0]);
158+
}
159+
};
15160
var selectLi = function(liElement){
16161
if(/(<br(|\/)>)$/i.test(liElement.innerHTML.trim())) taSelection.setSelectionBeforeElement(angular.element(liElement).find("br")[0]);
17162
else taSelection.setSelectionToElementEnd(liElement);
@@ -167,14 +312,24 @@ angular.module('textAngular.DOM', ['textAngular.factories'])
167312
}catch(e){}
168313
//console.log('************** selectedElement:', selectedElement);
169314
var $selected = angular.element(selectedElement);
170-
//if(selectedElement !== undefined && selectedElement.tagName !== undefined){
171315
var tagName = selectedElement.tagName.toLowerCase();
172316
if(command.toLowerCase() === 'insertorderedlist' || command.toLowerCase() === 'insertunorderedlist'){
173317
var selfTag = taBrowserTag((command.toLowerCase() === 'insertorderedlist')? 'ol' : 'ul');
318+
var selectedElements = taSelection.getOnlySelectedElements();
319+
//console.log('PPPPPPPPPPPPP', tagName, selfTag, selectedElements, tagName.match(BLOCKELEMENTS), $selected.hasClass('ta-bind'), $selected.parent()[0].tagName);
320+
if (selectedElements.length>1 && (tagName === 'ol' || tagName === 'ul' )) {
321+
return listElementsToSelfTag($selected, selectedElements, selfTag, selfTag===tagName, taDefaultWrap);
322+
}
174323
if(tagName === selfTag){
175324
// if all selected then we should remove the list
176325
// grab all li elements and convert to taDefaultWrap tags
177-
return listToDefault($selected, taDefaultWrap);
326+
//console.log('tagName===selfTag');
327+
if ($selected[0].childNodes.length !== selectedElements.length && selectedElements.length===1) {
328+
$selected = angular.element(selectedElements[0]);
329+
return listElementToSelfTag($selected.parent(), $selected, selfTag, true, taDefaultWrap);
330+
} else {
331+
return listToDefault($selected, taDefaultWrap);
332+
}
178333
}else if(tagName === 'li' &&
179334
$selected.parent()[0].tagName.toLowerCase() === selfTag &&
180335
$selected.parent().children().length === 1){
@@ -188,7 +343,15 @@ angular.module('textAngular.DOM', ['textAngular.factories'])
188343
}else if(tagName.match(BLOCKELEMENTS) && !$selected.hasClass('ta-bind')){
189344
// if it's one of those block elements we have to change the contents
190345
// if it's a ol/ul we are changing from one to the other
346+
if (selectedElements.length) {
347+
if ($selected[0].childNodes.length !== selectedElements.length && selectedElements.length===1) {
348+
//console.log('&&&&&&&&&&&&&&& --------- &&&&&&&&&&&&&&&&', selectedElements[0], $selected[0].childNodes);
349+
$selected = angular.element(selectedElements[0]);
350+
return listElementToSelfTag($selected.parent(), $selected, selfTag, selfTag===tagName, taDefaultWrap);
351+
}
352+
}
191353
if(tagName === 'ol' || tagName === 'ul'){
354+
// now if this is a set of selected elements... behave diferently
192355
return listToList($selected, selfTag);
193356
}else{
194357
var childBlockElements = false;
@@ -204,8 +367,9 @@ angular.module('textAngular.DOM', ['textAngular.factories'])
204367
}
205368
}
206369
}else if(tagName.match(BLOCKELEMENTS)){
207-
// if we get here then all the contents of the ta-bind are selected
370+
// if we get here then the contents of the ta-bind are selected
208371
_nodes = taSelection.getOnlySelectedElements();
372+
//console.log('_nodes', _nodes, tagName);
209373
if(_nodes.length === 0){
210374
// here is if there is only text in ta-bind ie <div ta-bind>test content</div>
211375
$target = angular.element('<' + selfTag + '><li>' + selectedElement.innerHTML + '</li></' + selfTag + '>');
@@ -237,6 +401,7 @@ angular.module('textAngular.DOM', ['textAngular.factories'])
237401
$nodes.unshift($n);
238402
}
239403
}
404+
//console.log('$nodes', $nodes);
240405
$target = angular.element('<' + selfTag + '>' + html + '</' + selfTag + '>');
241406
$nodes.pop().replaceWith($target);
242407
angular.forEach($nodes, function($node){ $node.remove(); });
@@ -473,15 +638,10 @@ function($document, taDOM, $log){
473638
if (container.nodeName.toLowerCase() === 'div' &&
474639
/^taTextElement/.test(container.id)) {
475640
//console.log('*********taTextElement************');
476-
//for (var i=0; i<container.childNodes.length; i++) {
477-
// console.log(i, container.childNodes[i]);
478-
//}
479-
//console.log('getSelection start: end:', selection.start.offset, selection.end.offset);
480641
//console.log('commonAncestorContainer:', container);
481-
// fix this to be the <textNode>
482-
selection.end.element = selection.start.element = selection.container = container.childNodes[selection.start.offset];
483-
selection.start.offset = selection.end.offset = 0;
484-
selection.collapsed=true;
642+
selection.start.element = container.childNodes[selection.start.offset];
643+
selection.end.element = container.childNodes[selection.end.offset];
644+
selection.container = container;
485645
} else {
486646
if (container.parentNode === selection.start.element ||
487647
container.parentNode === selection.end.element) {
@@ -708,11 +868,11 @@ function($document, taDOM, $log){
708868
return undefined;
709869
}
710870
},
711-
setSelection: function(el, start, end){
871+
setSelection: function(elStart, elEnd, start, end){
712872
var range = rangy.createRange();
713873

714-
range.setStart(el, start);
715-
range.setEnd(el, end);
874+
range.setStart(elStart, start);
875+
range.setEnd(elEnd, end);
716876

717877
rangy.getSelection().setSingleRange(range);
718878
},

‎src/demo/textAngular.com.html

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:400,300">
2020
<link rel="stylesheet" href="http://textangular.com/dist/textAngular.css" type="text/css">
2121
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js" type="text/javascript"></script>
22-
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js'></script>
2322
<style>
2423
textarea.ta-bind {
2524
width: 100%;

0 commit comments

Comments
 (0)