Index: trunk/extensions/VisualEditor/modules/es/tools/es.ListButtonTool.js |
— | — | @@ -19,74 +19,161 @@ |
20 | 20 | /* Methods */ |
21 | 21 | |
22 | 22 | es.ListButtonTool.prototype.onClick = function() { |
23 | | - var stacks = [], |
24 | | - stack = [], |
25 | | - i, |
26 | | - j, |
27 | | - data; |
| 23 | + if ( !this.$.hasClass( 'es-toolbarButtonTool-down' ) ) { |
28 | 24 | |
29 | | - // |
30 | | - // Step 1 |
31 | | - // |
| 25 | + var surface = this.toolbar.surfaceView, |
| 26 | + stack = [], |
| 27 | + stacks = [], |
| 28 | + listItems = [], |
| 29 | + parent, |
| 30 | + styles, |
| 31 | + insertAt, |
| 32 | + removeLength, |
| 33 | + data, |
| 34 | + tx, |
| 35 | + i, |
| 36 | + j; |
32 | 37 | |
33 | | - for( i = 0; i < this.nodes.length; i++ ) { |
34 | | - if ( this.nodes[i].getParent().getElementType() === 'listItem' ) { |
35 | | - if( stack.length > 0 ) { |
36 | | - stacks.push ( stack ); |
37 | | - stack = []; |
38 | | - } |
39 | | - } else { |
40 | | - if( stack.length > 0 ) { |
41 | | - if ( this.nodes[i].getParent() === stack[stack.length - 1].getParent() ) { |
| 38 | + for( i = 0; i < this.nodes.length; i++ ) { |
| 39 | + parent = this.nodes[i].getParent(); |
| 40 | + if ( parent.getElementType() === 'listItem' ) { |
| 41 | + if ( stack.length > 0 ) { |
| 42 | + stacks.push( stack ); |
| 43 | + stack = []; |
| 44 | + } |
| 45 | + listItems.push( parent ); |
| 46 | + } else { |
| 47 | + if( stack.length > 0 ) { |
| 48 | + if ( parent === stack[stack.length - 1].getParent() ) { |
| 49 | + stack.push( this.nodes[i] ); |
| 50 | + } else { |
| 51 | + stacks.push( stack ); |
| 52 | + stack = [this.nodes[i]]; |
| 53 | + } |
| 54 | + } else { |
42 | 55 | stack.push( this.nodes[i] ); |
43 | | - } else { |
44 | | - stacks.push ( stack ); |
45 | | - stack = [this.nodes[i]]; |
46 | 56 | } |
47 | | - } else { |
48 | | - stack.push( this.nodes[i] ); |
49 | 57 | } |
50 | 58 | } |
51 | | - } |
52 | | - if( stack.length > 0 ) { |
53 | | - stacks.push ( stack ); |
54 | | - } |
| 59 | + if( stack.length > 0 ) { |
| 60 | + stacks.push( stack ); |
| 61 | + } |
55 | 62 | |
56 | | - // |
57 | | - // Step 2 |
58 | | - // |
59 | | - |
60 | | - var insertAt, |
61 | | - removeLength, |
62 | | - tx; |
| 63 | + for( i = 0; i < listItems.length; i++ ) { |
| 64 | + styles = listItems[i].getElementAttribute( 'styles' ); |
| 65 | + if ( styles[styles.length - 1] !== this.name ) { |
| 66 | + styles.splice( styles.length - 1, 1, this.name ); |
| 67 | + tx = surface.model.getDocument().prepareElementAttributeChange( |
| 68 | + surface.documentView.model.getOffsetFromNode( listItems[i], false ), |
| 69 | + 'set', |
| 70 | + 'styles', |
| 71 | + styles |
| 72 | + ); |
| 73 | + surface.model.transact( tx ); |
| 74 | + } |
| 75 | + } |
63 | 76 | |
64 | | - for( i = 0; i < stacks.length; i++ ) { |
65 | | - removeLength = 0; |
66 | | - insertAt = this.toolbar.surfaceView.documentView.model.getOffsetFromNode( |
67 | | - stacks[i][0], false |
68 | | - ); |
69 | | - data = [ { 'type': 'list' } ]; |
70 | | - for( j = 0; j < stacks[i].length; j++ ) { |
71 | | - removeLength += stacks[i][j].getElementLength(); |
72 | | - data = data |
73 | | - .concat( [ { 'type': 'listItem', 'attributes' : { 'styles': [ this.name ] } } ] ) |
74 | | - .concat( stacks[i][j].getElementData() ) |
75 | | - .concat( [ { 'type': '/listItem' } ] ); |
| 77 | + for( i = 0; i < stacks.length; i++ ) { |
| 78 | + removeLength = 0; |
| 79 | + insertAt = surface.documentView.model.getOffsetFromNode( stacks[i][0], false ); |
| 80 | + data = [ { 'type': 'list' } ]; |
| 81 | + for( j = 0; j < stacks[i].length; j++ ) { |
| 82 | + removeLength += stacks[i][j].getElementLength(); |
| 83 | + data = data |
| 84 | + .concat( [ { |
| 85 | + 'type': 'listItem', |
| 86 | + 'attributes' : { 'styles': [ this.name ] } |
| 87 | + } ] ) |
| 88 | + .concat( stacks[i][j].getElementData() ) |
| 89 | + .concat( [ { 'type': '/listItem' } ] ); |
| 90 | + } |
| 91 | + data = data.concat( [ { 'type': '/list' } ] ); |
| 92 | + |
| 93 | + tx = surface.model.getDocument().prepareInsertion( insertAt, data ); |
| 94 | + surface.model.transact( tx ); |
| 95 | + |
| 96 | + tx = surface.model.getDocument().prepareRemoval( |
| 97 | + new es.Range( insertAt + data.length, insertAt + removeLength + data.length ) |
| 98 | + ); |
| 99 | + surface.model.transact( tx ); |
76 | 100 | } |
77 | | - data = data.concat( [ { 'type': '/list' } ] ); |
78 | 101 | |
79 | | - tx = this.toolbar.surfaceView.model.getDocument().prepareInsertion( |
80 | | - insertAt, |
81 | | - data |
82 | | - ); |
83 | | - this.toolbar.surfaceView.model.transact( tx ); |
| 102 | + } else { |
| 103 | +/* |
| 104 | + // unlist |
| 105 | + // |
| 106 | + // Step 1 |
| 107 | + // |
| 108 | + |
| 109 | + var listItems = [], |
| 110 | + listItem, |
| 111 | + i, |
| 112 | + j; |
| 113 | + |
| 114 | + for( i = 0; i < this.nodes.length; i++ ) { |
| 115 | + listItem = this.nodes[i].getParent(); |
| 116 | + if ( listItems.length > 0 ) { |
| 117 | + if (listItem != listItems[listItems.length - 1]) { |
| 118 | + listItems.push( listItem ); |
| 119 | + } |
| 120 | + } else { |
| 121 | + listItems.push( listItem ); |
| 122 | + } |
| 123 | + } |
| 124 | + |
| 125 | + var stacks = []; |
| 126 | + var stack = { first: false, last: false, nodes: [], offset: -1, length: 0 }; |
| 127 | + for( i = 0; i < listItems.length; i++ ) { |
| 128 | + if( stack.nodes.length > 0 ) { |
| 129 | + if ( stack.nodes[stack.nodes.length - 1].getParent() != listItems[i].getParent() ) { |
| 130 | + stacks.push(stack); |
| 131 | + stack = { first: false, last: false, nodes: [], offset: -1, length: 0 }; |
| 132 | + } |
| 133 | + } |
| 134 | + |
| 135 | + if ( listItems[i].getParent().indexOf( listItems[i] ) === 0 ) { |
| 136 | + stack.first = true; |
| 137 | + } |
| 138 | + if ( listItems[i].getParent().indexOf( listItems[i] ) === listItems[i].getParent().children.length - 1 ) { |
| 139 | + stack.last = true; |
| 140 | + } |
| 141 | + if( stack.nodes.length === 0 ){ |
| 142 | + stack.offset = this.toolbar.surfaceView.documentView.model.getOffsetFromNode(listItems[i], false); |
| 143 | + } |
| 144 | + stack.length += listItems[i].getElementLength(); |
| 145 | + stack.nodes.push( listItems[i] ); |
| 146 | + |
| 147 | + } |
| 148 | + if( stack.nodes.length > 0 ) { |
| 149 | + stacks.push(stack); |
| 150 | + } |
84 | 151 | |
85 | | - tx = this.toolbar.surfaceView.model.getDocument().prepareRemoval( |
86 | | - new es.Range( insertAt+data.length, insertAt+removeLength+data.length) |
87 | | - ); |
88 | | - this.toolbar.surfaceView.model.transact( tx ); |
| 152 | + // |
| 153 | + // Step 2 |
| 154 | + // |
| 155 | + var data; |
| 156 | + |
| 157 | + for( i = 0; i < stacks.length; i++ ) { |
| 158 | + stack = stacks[i]; |
| 159 | + if( stack.first === false && stack.last === false ) { |
89 | 160 | |
90 | | - |
| 161 | + |
| 162 | + tx = this.toolbar.surfaceView.model.getDocument().prepareRemoval( |
| 163 | + new es.Range( stack.offset, stack.offset+stack.length ) |
| 164 | + ); |
| 165 | + this.toolbar.surfaceView.model.transact( tx ); |
| 166 | + |
| 167 | + data = [ { 'type': '/list' }, { 'type': 'list' } ]; |
| 168 | + tx = this.toolbar.surfaceView.model.getDocument().prepareInsertion( |
| 169 | + stack.offset, |
| 170 | + data |
| 171 | + ); |
| 172 | + console.log(tx); |
| 173 | + this.toolbar.surfaceView.model.transact( tx ); |
| 174 | + |
| 175 | + } |
| 176 | + } |
| 177 | +*/ |
91 | 178 | } |
92 | 179 | }; |
93 | 180 | |