Index: trunk/extensions/VisualEditor/tests/es/index.html |
— | — | @@ -31,8 +31,6 @@ |
32 | 32 | |
33 | 33 | <!-- Models --> |
34 | 34 | <script src="../../modules/es/models/es.DocumentModel.js"></script> |
35 | | - <script src="../../modules/es/models/es.HistoryModel.js"></script> |
36 | | - <script src="../../modules/es/models/es.HistoryStateModel.js"></script> |
37 | 35 | <script src="../../modules/es/models/es.ListItemModel.js"></script> |
38 | 36 | <script src="../../modules/es/models/es.ListModel.js"></script> |
39 | 37 | <script src="../../modules/es/models/es.ParagraphModel.js"></script> |
Index: trunk/extensions/VisualEditor/demo/index.html |
— | — | @@ -82,8 +82,6 @@ |
83 | 83 | <!-- Models --> |
84 | 84 | <script src="../modules/es/models/es.SurfaceModel.js"></script> |
85 | 85 | <script src="../modules/es/models/es.DocumentModel.js"></script> |
86 | | - <script src="../modules/es/models/es.HistoryModel.js"></script> |
87 | | - <script src="../modules/es/models/es.HistoryStateModel.js"></script> |
88 | 86 | <script src="../modules/es/models/es.ParagraphModel.js"></script> |
89 | 87 | <script src="../modules/es/models/es.PreModel.js"></script> |
90 | 88 | <script src="../modules/es/models/es.ListModel.js"></script> |
Index: trunk/extensions/VisualEditor/modules/es/models/es.HistoryModel.js |
— | — | @@ -1,190 +0,0 @@ |
2 | | -/** |
3 | | - * Creates an es.HistoryModel object. |
4 | | - * |
5 | | - * @class |
6 | | - * @constructor |
7 | | - * @extends {es.EventEmitter} |
8 | | - * @param {es.DocumentModel} doc Document being tracked and modified |
9 | | - */ |
10 | | -es.HistoryModel = function( doc ) { |
11 | | - // Inheritance |
12 | | - es.EventEmitter.call( this ); |
13 | | - |
14 | | - // Properties |
15 | | - this.doc = doc; |
16 | | - this.currentState = new es.HistoryStateModel(); |
17 | | - this.currentStateIndex = 0; |
18 | | - this.states = [this.currentState]; |
19 | | - this.currentStateDiff = 0; |
20 | | - |
21 | | - // Configuration |
22 | | - this.maxStateDiff = 24; |
23 | | -}; |
24 | | - |
25 | | -/* Methods */ |
26 | | - |
27 | | -/** |
28 | | - * Gets the index of the current state. |
29 | | - * |
30 | | - * |
31 | | - */ |
32 | | -es.HistoryModel.prototype.getCurrentStateIndex = function() { |
33 | | - return this.currentStateIndex; |
34 | | -}; |
35 | | - |
36 | | -/** |
37 | | - * Gets the index of the current state. |
38 | | - * |
39 | | - * |
40 | | - */ |
41 | | -es.HistoryModel.prototype.getCurrentStateSelection = function() { |
42 | | - return this.currentState.getSelection(); |
43 | | -}; |
44 | | - |
45 | | -/** |
46 | | - * Gets the number of states available. |
47 | | - * |
48 | | - * @method |
49 | | - */ |
50 | | -es.HistoryModel.prototype.getStateCount = function() { |
51 | | - return this.states.length; |
52 | | -}; |
53 | | - |
54 | | -/** |
55 | | - * Gets a copy of the list of states. |
56 | | - * |
57 | | - * @method |
58 | | - * @param {Boolean} deep Whether to make a deep copy (can be slow) |
59 | | - * @returns {Array[]} List of states, each a list of transactions |
60 | | - */ |
61 | | -es.HistoryModel.prototype.getStates = function( deep ) { |
62 | | - return deep ? es.copyArray( this.states ) : this.states.slice( 0 ); |
63 | | -}; |
64 | | - |
65 | | -/** |
66 | | - * Gets a copy of the list of transactions, which are not yet part of a state. |
67 | | - * |
68 | | - * @method |
69 | | - * @param {Boolean} deep Whether to make a deep copy (can be slow) |
70 | | - * @returns {es.TransactionModel[]} List of transactions |
71 | | - */ |
72 | | -es.HistoryModel.prototype.getTransactions = function( deep ) { |
73 | | - return deep ? es.copyArray( this.transactions ) : this.transactions.slice( 0 ); |
74 | | -}; |
75 | | - |
76 | | -/** |
77 | | - * Commits a transaction. |
78 | | - * |
79 | | - * Unless the accumulate option is used a state will be automatically pushed before committing |
80 | | - * if the transaction is of a different type as the previous one in the transaction buffer, or if |
81 | | - * the transaction would produce a content length difference beyond the configured maximum. |
82 | | - * |
83 | | - * @method |
84 | | - * @param {es.TransactionModel} transaction Transaction to commit |
85 | | - * @param {es.Range} [selection] Selection to use after the transaction has been applied |
86 | | - * @param {Boolean} [accumulate] Prevent automatic state pushing |
87 | | - */ |
88 | | -es.HistoryModel.prototype.commit = function( transaction, selection, accumulate ) { |
89 | | - var transactionDiff = Math.abs( transaction.getLengthDiff() ); |
90 | | - // Unless we should intentionally accumulate transactions or this is the first one for this |
91 | | - // state, automatically push state |
92 | | - var transactionCount = this.currentState.getTransactionCount(); |
93 | | - if ( !accumulate && transactionCount ) { |
94 | | - if ( |
95 | | - // If the transactions are of a different type |
96 | | - this.currentState.getTransactions()[transactionCount - 1].type !== transaction.type || |
97 | | - // This transaction would make the state longer than the maximum length |
98 | | - this.currentStateDiff + transactionDiff > this.maxStateDiff |
99 | | - ) { |
100 | | - this.pushState(); |
101 | | - } |
102 | | - } |
103 | | - this.currentState.pushTransaction( transaction ); |
104 | | - this.currentStateDiff += transactionDiff; |
105 | | - // Apply transaction to the document |
106 | | - this.doc.commit( transaction ); |
107 | | - // Emit a do event with the transaction that was just committed |
108 | | - this.emit( 'do', transaction ); |
109 | | -}; |
110 | | - |
111 | | -/** |
112 | | - * Moves transactions in the buffer into a new state. |
113 | | - * |
114 | | - * @method |
115 | | - */ |
116 | | -es.HistoryModel.prototype.pushState = function() { |
117 | | - // If any transactions have been pushed since the last state push |
118 | | - if ( this.currentState.getTransactionCount() ) { |
119 | | - // If the current state is not the most recently added state |
120 | | - if ( this.currentStateIndex < this.states.length - 1 ) { |
121 | | - // Forget about states newer than the current one |
122 | | - this.states.splice( |
123 | | - this.currentStateIndex, this.states.length - this.currentStateIndex |
124 | | - ); |
125 | | - } |
126 | | - // Create a new current state |
127 | | - this.currentState = new es.HistoryStateModel(); |
128 | | - // Add the new current state to the stack |
129 | | - this.states.push( this.currentState ); |
130 | | - // Reset the state diff counter |
131 | | - this.currentStateDiff = 0; |
132 | | - // Move the current state index to the end (should be equivilant of ++) |
133 | | - this.currentStateIndex = this.states.length - 1; |
134 | | - } |
135 | | - // Emit the completed |
136 | | - this.emit( 'pushState', this.states[this.states.length - 1] ); |
137 | | -}; |
138 | | - |
139 | | -/** |
140 | | - * |
141 | | - * |
142 | | - * @method |
143 | | - */ |
144 | | -es.HistoryModel.prototype.undo = function( steps ) { |
145 | | - if ( steps === undefined ) { |
146 | | - steps = 1; |
147 | | - } |
148 | | - // Stop undo just before the first state |
149 | | - var previousStateIndex = this.currentStateIndex; |
150 | | - this.currentStateIndex = Math.max( -1, this.currentStateIndex - steps ); |
151 | | - if ( previousStateIndex > this.currentStateIndex ) { |
152 | | - for ( var i = previousStateIndex; i > this.currentStateIndex; i-- ) { |
153 | | - // Apply transaction to the document |
154 | | - var transactions = this.states[i].getTransactions(); |
155 | | - for ( var j = transactions.length - 1; j >= 0; j-- ) { |
156 | | - this.doc.rollback( transactions[j] ); |
157 | | - } |
158 | | - // Emit an undo event with the state to be rolled back |
159 | | - this.emit( 'undo', this.states[i] ); |
160 | | - } |
161 | | - } |
162 | | -}; |
163 | | - |
164 | | -/** |
165 | | - * |
166 | | - * |
167 | | - * @method |
168 | | - */ |
169 | | -es.HistoryModel.prototype.redo = function( steps ) { |
170 | | - if ( steps === undefined ) { |
171 | | - steps = 1; |
172 | | - } |
173 | | - // Stop redo at the last state |
174 | | - var previousStateIndex = this.currentStateIndex; |
175 | | - this.currentStateIndex = Math.min( this.states.length - 1, this.currentStateIndex + steps ); |
176 | | - if ( previousStateIndex < this.currentStateIndex ) { |
177 | | - for ( var i = previousStateIndex + 1; i >= this.currentStateIndex; i++ ) { |
178 | | - // Apply transaction to the document |
179 | | - var transactions = this.states[i].getTransactions(); |
180 | | - for ( var j = 0; j < transactions.length; j++ ) { |
181 | | - this.doc.commit( transactions[j] ); |
182 | | - } |
183 | | - // Emit an undo event with the state to be rolled back |
184 | | - this.emit( 'redo', this.states[i] ); |
185 | | - } |
186 | | - } |
187 | | -}; |
188 | | - |
189 | | -/* Inheritance */ |
190 | | - |
191 | | -es.extendClass( es.HistoryModel, es.EventEmitter ); |
Index: trunk/extensions/VisualEditor/modules/es/models/es.HistoryStateModel.js |
— | — | @@ -1,31 +0,0 @@ |
2 | | -/** |
3 | | - * Creates an es.HistoryStateModel object. |
4 | | - * |
5 | | - * @class |
6 | | - * @constructor |
7 | | - */ |
8 | | -es.HistoryStateModel = function() { |
9 | | - this.transactions = []; |
10 | | - this.selection = null; |
11 | | -}; |
12 | | - |
13 | | -/* Methods */ |
14 | | - |
15 | | -es.HistoryStateModel.prototype.getSelection = function() { |
16 | | - return this.selection; |
17 | | -}; |
18 | | - |
19 | | -es.HistoryStateModel.prototype.getTransactions = function() { |
20 | | - return this.transactions; |
21 | | -}; |
22 | | - |
23 | | -es.HistoryStateModel.prototype.getTransactionCount = function() { |
24 | | - return this.transactions.length; |
25 | | -}; |
26 | | - |
27 | | -es.HistoryStateModel.prototype.pushTransaction = function( transaction, selection ) { |
28 | | - this.transactions.push( transaction ); |
29 | | - if ( selection !== undefined ) { |
30 | | - this.selection = selection.clone(); |
31 | | - } |
32 | | -}; |
Index: trunk/extensions/VisualEditor/modules/es/models/es.SurfaceModel.js |
— | — | @@ -3,14 +3,207 @@ |
4 | 4 | * |
5 | 5 | * @class |
6 | 6 | * @constructor |
| 7 | + * @extends {es.EventEmitter} |
7 | 8 | * @param {es.DocumentModel} doc Document model to create surface for |
8 | 9 | */ |
9 | 10 | es.SurfaceModel = function( doc ) { |
| 11 | + // Inheritance |
| 12 | + es.EventEmitter.call( this ); |
| 13 | + |
| 14 | + // Properties |
10 | 15 | this.doc = doc; |
| 16 | + this.selection = new es.Range(); |
| 17 | + this.states = [[]]; |
| 18 | + this.initializeState( this.states.length - 1 ); |
| 19 | + |
| 20 | + // Configuration |
| 21 | + this.distanceLimit = 24; |
| 22 | + this.lengthDifferenceLimit = 24; |
11 | 23 | }; |
12 | 24 | |
13 | 25 | /* Methods */ |
14 | 26 | |
| 27 | +es.SurfaceModel.prototype.initializeState = function( stateIndex ) { |
| 28 | + if ( this.states[stateIndex] === undefined ) { |
| 29 | + throw 'Invalid state index error. State index our of range: ' + stateIndex; |
| 30 | + } |
| 31 | + this.currentStateIndex = stateIndex; |
| 32 | + this.currentState = this.states[stateIndex]; |
| 33 | + this.currentStateDistance = 0; |
| 34 | + this.currentStateLengthDifference = 0; |
| 35 | +}; |
| 36 | + |
| 37 | +/** |
| 38 | + * Gets the document model of the surface. |
| 39 | + * |
| 40 | + * @method |
| 41 | + * @returns {es.DocumentModel} Document model of the surface |
| 42 | + */ |
15 | 43 | es.SurfaceModel.prototype.getDocument = function() { |
16 | 44 | return this.doc; |
17 | 45 | }; |
| 46 | + |
| 47 | +/** |
| 48 | + * Gets the selection for the current state. |
| 49 | + * |
| 50 | + * @method |
| 51 | + * @returns {es.Range} Current state's selection |
| 52 | + */ |
| 53 | +es.SurfaceModel.prototype.getSelection = function() { |
| 54 | + return this.selection; |
| 55 | +}; |
| 56 | + |
| 57 | +/** |
| 58 | + * Changes the selection. |
| 59 | + * |
| 60 | + * If changing the selection at a high frequency (such as while dragging) use the combine argument |
| 61 | + * to avoid them being split up into multiple states. |
| 62 | + * |
| 63 | + * @method |
| 64 | + * @param {es.Range} selection |
| 65 | + * @param {Boolean} combine Whether to prevent this transaction from causing a state push |
| 66 | + */ |
| 67 | +es.SurfaceModel.prototype.select = function( selection, combine ) { |
| 68 | + if ( !combine && this.shouldPushState( selection ) ) { |
| 69 | + this.pushState(); |
| 70 | + } |
| 71 | + var lastAction = this.states[this.states.length - 1]; |
| 72 | + if ( lastAction instanceof es.Range ) { |
| 73 | + this.currentStateDistance += Math.abs( |
| 74 | + selection.from - this.states[this.states.length - 1].from |
| 75 | + ); |
| 76 | + } |
| 77 | + this.selection = selection; |
| 78 | + this.currentState.push( selection ); |
| 79 | + this.emit( 'select', selection ); |
| 80 | +}; |
| 81 | + |
| 82 | +/** |
| 83 | + * Applies a series of transactions to the content data. |
| 84 | + * |
| 85 | + * If committing multiple transactions which are the result of a single user action and need to be |
| 86 | + * part of a single state, use the combine argument for all but the last one to avoid them being |
| 87 | + * split up into multple states. |
| 88 | + * |
| 89 | + * @method |
| 90 | + * @param {es.TransactionModel} transactions Tranasction to apply to the document |
| 91 | + * @param {Boolean} combine Whether to prevent this transaction from causing a state push |
| 92 | + */ |
| 93 | +es.SurfaceModel.prototype.transact = function( transaction, combine ) { |
| 94 | + if ( !combine && this.shouldPushState( transaction ) ) { |
| 95 | + this.pushState(); |
| 96 | + } |
| 97 | + this.currentStateLengthDifference += transaction.getLengthDifference(); |
| 98 | + this.doc.commit( transaction ); |
| 99 | + this.currentState.push( transaction ); |
| 100 | + this.emit( 'transact', transaction ); |
| 101 | +}; |
| 102 | + |
| 103 | +/** |
| 104 | + * Reverses one or more selections and transactions. |
| 105 | + * |
| 106 | + * @method |
| 107 | + * @param {Integer} steps Number of steps to reverse |
| 108 | + * @param {Boolean} soft Whether to consider selection states as steps |
| 109 | + */ |
| 110 | +es.SurfaceModel.prototype.undo = function( steps, soft ) { |
| 111 | + // TODO: Implement me! |
| 112 | + this.emit( 'undo'/*, transaction/selection*/ ); |
| 113 | +}; |
| 114 | + |
| 115 | +/** |
| 116 | + * Repeats one or more selections and transactions. |
| 117 | + * |
| 118 | + * @method |
| 119 | + * @param {Integer} steps Number of steps to repeat |
| 120 | + * @param {Boolean} soft Whether to consider selection states as steps |
| 121 | + */ |
| 122 | +es.SurfaceModel.prototype.redo = function( steps, soft ) { |
| 123 | + // TODO: Implement me! |
| 124 | + this.emit( 'redo'/*, transaction/selection*/ ); |
| 125 | +}; |
| 126 | + |
| 127 | +/** |
| 128 | + * Checks if it's an appropriate time to push the state. |
| 129 | + * |
| 130 | + * @method |
| 131 | + * @returns {Boolean} Whether the state should be pushed |
| 132 | + */ |
| 133 | +es.SurfaceModel.prototype.shouldPushState = function( nextAction ) { |
| 134 | + // Never push a new state if the current one is empty |
| 135 | + if ( !this.currentState.length ) { |
| 136 | + return false; |
| 137 | + } |
| 138 | + var lastAction = this.currentState[this.currentState.length - 1], |
| 139 | + nextDirection, |
| 140 | + lastDirection; |
| 141 | + if ( |
| 142 | + // Check that types match |
| 143 | + nextAction instanceof es.Range && lastAction instanceof es.Range |
| 144 | + ) { |
| 145 | + if ( |
| 146 | + // 2 or more select actions in a row are required to detect a direction |
| 147 | + this.states.length >= 2 && this.states[this.states.length - 2] instanceof es.Range |
| 148 | + ) { |
| 149 | + // Check we haven't changed directions |
| 150 | + lastDirection = this.states[this.states.length - 2].from - lastAction.from; |
| 151 | + nextDirection = lastAction.from - nextAction.from; |
| 152 | + if ( |
| 153 | + // Both movements are in the same direction |
| 154 | + ( lastDirection < 0 && nextDirection < 0 ) || |
| 155 | + ( lastDirection > 0 && nextDirection > 0 ) |
| 156 | + ) { |
| 157 | + // Check we are still within the distance threshold |
| 158 | + if ( |
| 159 | + Math.abs( nextAction.from - lastAction.from ) + this.currentStateDistance < |
| 160 | + this.distanceLimit |
| 161 | + ) { |
| 162 | + return false; |
| 163 | + } |
| 164 | + } |
| 165 | + } |
| 166 | + } else if ( |
| 167 | + // Check that types match |
| 168 | + nextAction instanceof es.TransactionModel && lastAction instanceof es.TransactionModel |
| 169 | + ) { |
| 170 | + // Check if we've changed directions (insert vs remove) |
| 171 | + lastLengthDifference = lastAction.getLengthDifference(); |
| 172 | + nextLengthDifference = nextAction.getLengthDifference(); |
| 173 | + if ( |
| 174 | + // Both movements are in the same direction |
| 175 | + ( lastLengthDifference < 0 && nextLengthDifference < 0 ) || |
| 176 | + ( lastLengthDifference > 0 && nextLengthDifference > 0 ) |
| 177 | + ) { |
| 178 | + // Check we are still within the length difference threshold |
| 179 | + if ( |
| 180 | + nextLengthDifference + this.currentStateLengthDifference < |
| 181 | + this.lengthDifferenceLimit |
| 182 | + ) { |
| 183 | + return false; |
| 184 | + } |
| 185 | + } |
| 186 | + } |
| 187 | + return true; |
| 188 | +}; |
| 189 | + |
| 190 | +/** |
| 191 | + * Removes any undone states and pushes a new state to the stack. |
| 192 | + * |
| 193 | + * @method |
| 194 | + */ |
| 195 | +es.SurfaceModel.prototype.pushState = function() { |
| 196 | + // Automatically drop undone states - we are now moving in a new direction |
| 197 | + if ( this.states[this.states.length - 1] !== this.currentState ) { |
| 198 | + for ( var i = this.states.length - 1; i > this.currentStateIndex; i-- ) { |
| 199 | + this.emit( 'popState', this.states.pop() ); |
| 200 | + } |
| 201 | + } |
| 202 | + // Push a new state to the stack |
| 203 | + this.states.push( [] ); |
| 204 | + this.initializeState( this.states.length - 1 ); |
| 205 | + this.emit( 'pushState' ); |
| 206 | +}; |
| 207 | + |
| 208 | +/* Inheritance */ |
| 209 | + |
| 210 | +es.extendClass( es.SurfaceModel, es.EventEmitter ); |
Index: trunk/extensions/VisualEditor/modules/es/views/es.SurfaceView.js |
— | — | @@ -173,7 +173,7 @@ |
174 | 174 | } else if ( e.originalEvent.detail === 2 ) { // double click |
175 | 175 | this.mouse.selectingMode = 2; // used in mouseMove handler |
176 | 176 | |
177 | | - var wordRange = this.documentView.getModel().getWordBoundaries( offset ); |
| 177 | + var wordRange = this.model.getDocument().getWordBoundaries( offset ); |
178 | 178 | if( wordRange ) { |
179 | 179 | this.selection = wordRange; |
180 | 180 | this.mouse.selectedRange = this.selection.clone(); |
— | — | @@ -185,11 +185,11 @@ |
186 | 186 | var node = this.documentView.getNodeFromOffset( offset ), |
187 | 187 | nodeOffset = this.documentView.getOffsetFromNode( node, false ); |
188 | 188 | |
189 | | - this.selection.from = this.documentView.getModel().getRelativeContentOffset( |
| 189 | + this.selection.from = this.model.getDocument().getRelativeContentOffset( |
190 | 190 | nodeOffset, |
191 | 191 | 1 |
192 | 192 | ); |
193 | | - this.selection.to = this.documentView.getModel().getRelativeContentOffset( |
| 193 | + this.selection.to = this.model.getDocument().getRelativeContentOffset( |
194 | 194 | nodeOffset + node.getElementLength(), |
195 | 195 | -1 |
196 | 196 | ); |
— | — | @@ -220,7 +220,7 @@ |
221 | 221 | if ( this.mouse.selectingMode === 1 ) { // selection of chars |
222 | 222 | this.selection.to = offset; |
223 | 223 | } else if ( this.mouse.selectingMode === 2 ) { // selection of words |
224 | | - var wordRange = this.documentView.getModel().getWordBoundaries( offset ); |
| 224 | + var wordRange = this.model.getDocument().getWordBoundaries( offset ); |
225 | 225 | if ( wordRange ) { |
226 | 226 | if ( wordRange.to <= this.mouse.selectedRange.from ) { |
227 | 227 | this.selection.from = wordRange.from; |
— | — | @@ -238,14 +238,14 @@ |
239 | 239 | this.documentView.getNodeFromOffset( offset ) |
240 | 240 | ); |
241 | 241 | if ( nodeRange.to <= this.mouse.selectedRange.from ) { |
242 | | - this.selection.from = this.documentView.getModel().getRelativeContentOffset( |
| 242 | + this.selection.from = this.model.getDocument().getRelativeContentOffset( |
243 | 243 | nodeRange.from, |
244 | 244 | 1 |
245 | 245 | ); |
246 | 246 | this.selection.to = this.mouse.selectedRange.to; |
247 | 247 | } else { |
248 | 248 | this.selection.from = this.mouse.selectedRange.from; |
249 | | - this.selection.to = this.documentView.getModel().getRelativeContentOffset( |
| 249 | + this.selection.to = this.model.getDocument().getRelativeContentOffset( |
250 | 250 | nodeRange.to, |
251 | 251 | -1 |
252 | 252 | ); |
— | — | @@ -408,12 +408,12 @@ |
409 | 409 | if ( this.selection.from === this.selection.to ) { |
410 | 410 | if ( backspace ) { |
411 | 411 | sourceOffset = this.selection.to; |
412 | | - targetOffset = this.documentView.getModel().getRelativeContentOffset( |
| 412 | + targetOffset = this.model.getDocument().getRelativeContentOffset( |
413 | 413 | sourceOffset, |
414 | 414 | -1 |
415 | 415 | ); |
416 | 416 | } else { |
417 | | - sourceOffset = this.documentView.getModel().getRelativeContentOffset( |
| 417 | + sourceOffset = this.model.getDocument().getRelativeContentOffset( |
418 | 418 | this.selection.to, |
419 | 419 | 1 |
420 | 420 | ); |
— | — | @@ -427,22 +427,22 @@ |
428 | 428 | sourceSplitableNode = es.DocumentViewNode.getSplitableNode( sourceNode ); |
429 | 429 | targetSplitableNode = es.DocumentViewNode.getSplitableNode( targetNode ); |
430 | 430 | } |
431 | | - |
| 431 | + |
432 | 432 | this.selection.from = this.selection.to = targetOffset; |
433 | 433 | this.showCursor(); |
434 | | - |
| 434 | + |
435 | 435 | if ( sourceNode === targetNode || |
436 | 436 | ( typeof sourceSplitableNode !== 'undefined' && |
437 | 437 | sourceSplitableNode.getParent() === targetSplitableNode.getParent() ) ) { |
438 | | - tx = this.documentView.getModel().prepareRemoval( |
| 438 | + tx = this.model.getDocument().prepareRemoval( |
439 | 439 | new es.Range( targetOffset, sourceOffset ) |
440 | 440 | ); |
441 | | - this.documentView.getModel().commit( tx ); |
| 441 | + this.model.transact( tx ); |
442 | 442 | } else { |
443 | | - tx = this.documentView.getModel().prepareInsertion( |
| 443 | + tx = this.model.getDocument().prepareInsertion( |
444 | 444 | targetOffset, sourceNode.model.getContent() |
445 | 445 | ); |
446 | | - this.documentView.getModel().commit( tx ); |
| 446 | + this.model.transact( tx ); |
447 | 447 | |
448 | 448 | var nodeToDelete = sourceNode; |
449 | 449 | es.DocumentNode.traverseUpstream( nodeToDelete, function( node ) { |
— | — | @@ -455,13 +455,13 @@ |
456 | 456 | var range = new es.Range(); |
457 | 457 | range.from = this.documentView.getOffsetFromNode( nodeToDelete, false ); |
458 | 458 | range.to = range.from + nodeToDelete.getElementLength(); |
459 | | - tx = this.documentView.getModel().prepareRemoval( range ); |
460 | | - this.documentView.getModel().commit( tx ); |
| 459 | + tx = this.model.getDocument().prepareRemoval( range ); |
| 460 | + this.model.transact( tx ); |
461 | 461 | } |
462 | 462 | } else { |
463 | 463 | // selection removal |
464 | | - tx = this.documentView.getModel().prepareRemoval( this.selection ); |
465 | | - this.documentView.getModel().commit( tx ); |
| 464 | + tx = this.model.getDocument().prepareRemoval( this.selection ); |
| 465 | + this.model.transact( tx ); |
466 | 466 | this.documentView.clearSelection(); |
467 | 467 | this.selection.from = this.selection.to = this.selection.start; |
468 | 468 | this.showCursor(); |
— | — | @@ -483,7 +483,7 @@ |
484 | 484 | nodeOffset + node.getElementLength(), |
485 | 485 | [ { 'type': 'paragraph' }, { 'type': '/paragraph' } ] |
486 | 486 | ); |
487 | | - this.documentView.getModel().commit( tx ); |
| 487 | + this.model.transact( tx ); |
488 | 488 | this.selection.from = this.selection.to = nodeOffset + node.getElementLength() + 1; |
489 | 489 | this.showCursor(); |
490 | 490 | } else { |
— | — | @@ -510,9 +510,9 @@ |
511 | 511 | splitable = es.DocumentView.splitRules[ elementType ].self; |
512 | 512 | } ); |
513 | 513 | var tx = this.documentView.model.prepareInsertion( this.selection.to, stack ); |
514 | | - this.documentView.getModel().commit( tx ); |
| 514 | + this.model.transact( tx ); |
515 | 515 | this.selection.from = this.selection.to = |
516 | | - this.documentView.getModel().getRelativeContentOffset( this.selection.to, 1 ); |
| 516 | + this.model.getDocument().getRelativeContentOffset( this.selection.to, 1 ); |
517 | 517 | this.showCursor(); |
518 | 518 | } |
519 | 519 | }; |
— | — | @@ -523,14 +523,14 @@ |
524 | 524 | if ( val.length > 0 ) { |
525 | 525 | var tx; |
526 | 526 | if ( this.selection.from != this.selection.to ) { |
527 | | - tx = this.documentView.getModel().prepareRemoval( this.selection ); |
528 | | - this.documentView.getModel().commit( tx ); |
| 527 | + tx = this.model.getDocument().prepareRemoval( this.selection ); |
| 528 | + this.model.transact( tx ); |
529 | 529 | this.documentView.clearSelection(); |
530 | 530 | this.selection.from = this.selection.to = |
531 | 531 | Math.min( this.selection.from, this.selection.to ); |
532 | 532 | } |
533 | | - tx = this.documentView.getModel().prepareInsertion( this.selection.from, val.split('') ); |
534 | | - this.documentView.getModel().commit( tx ); |
| 533 | + tx = this.model.getDocument().prepareInsertion( this.selection.from, val.split('') ); |
| 534 | + this.model.transact( tx ); |
535 | 535 | this.selection.from += val.length; |
536 | 536 | this.selection.to += val.length; |
537 | 537 | this.showCursor(); |
— | — | @@ -560,12 +560,12 @@ |
561 | 561 | } else { |
562 | 562 | offset = direction === 'left' ? this.selection.start : this.selection.end; |
563 | 563 | } |
564 | | - to = this.documentView.getModel().getRelativeContentOffset( |
| 564 | + to = this.model.getDocument().getRelativeContentOffset( |
565 | 565 | offset, |
566 | 566 | direction === 'left' ? -1 : 1 |
567 | 567 | ); |
568 | 568 | if ( unit === 'word' ) { |
569 | | - var wordRange = this.documentView.getModel().getWordBoundaries( |
| 569 | + var wordRange = this.model.getDocument().getWordBoundaries( |
570 | 570 | direction === 'left' ? to : offset |
571 | 571 | ); |
572 | 572 | if ( wordRange ) { |
— | — | @@ -575,7 +575,7 @@ |
576 | 576 | break; |
577 | 577 | case 'line': |
578 | 578 | offset = this.cursor.initialBias ? |
579 | | - this.documentView.getModel().getRelativeContentOffset( |
| 579 | + this.model.getDocument().getRelativeContentOffset( |
580 | 580 | this.selection.to, |
581 | 581 | -1) : |
582 | 582 | this.selection.to; |
— | — | @@ -589,7 +589,7 @@ |
590 | 590 | switch ( unit ) { |
591 | 591 | case 'unit': |
592 | 592 | var toNode = null; |
593 | | - this.documentView.getModel().traverseLeafNodes( |
| 593 | + this.model.getDocument().traverseLeafNodes( |
594 | 594 | function( node ) { |
595 | 595 | if ( toNode === null) { |
596 | 596 | toNode = node; |
— | — | @@ -601,7 +601,7 @@ |
602 | 602 | this.documentView.getNodeFromOffset( this.selection.to, false ).getModel(), |
603 | 603 | direction === 'up' ? true : false |
604 | 604 | ); |
605 | | - to = this.documentView.getModel().getOffsetFromNode( toNode, false ) + 1; |
| 605 | + to = this.model.getDocument().getOffsetFromNode( toNode, false ) + 1; |
606 | 606 | break; |
607 | 607 | case 'char': |
608 | 608 | /* |