116
116
var changes = Changeset.opIterator(unpacked.ops);
117
117
var characters = Changeset.stringIterator(unpacked.charBank);
119
var count = null; // Number of chars from start
120
var line = null; // Number of lines from start
121
var offset = null; // Number of chars from line
119
var offset = null; // Number of chars from doc start to line start
120
var line = null; // Number of lines from doc start
121
var inset = null; // Number of chars from line start
123
123
while (changes.hasNext()) {
124
124
var op = changes.next();
125
125
switch (op.opcode) {
127
// chars - Number of charicters to add
128
// lines - Number of lines to add
127
129
text = characters.take(op.chars);
129
self.call('addition', [ text, line, count, offset, op.lines ]);
131
self.call('addition', [ text, offset, line, inset, op.lines ]);
131
133
alert("No text: "+text+" from "+unpacked.charBank);
133
// chars - Number of charicters to add
134
// lines - Number of lines to add
137
self.call('removal', [ op.chars, line, count, offset, op.lines ]);
138
137
// chars - Number of charicters to remove
139
138
// lines - Number of lines to remove
139
self.call('removal', [ op.chars, offset, line, inset, op.lines ]);
142
142
// This very may well happen multiple times.
143
143
if(op.lines > 0) {
256
hashAttributes: function(element) {
258
$.each(element.attributes, function(i, attr) {
259
if(attr && attr.value) {
260
result[attr.nodeName] = attr.nodeValue;
265
addition: function(text, line, count, offset, nolines) {
266
// Adding arbitary text, we replace that which is effected.
267
//(partial, total) = getAffectedLines(text, line, count, offset);
268
/*var mydom = new DOMParser();
270
var newdoc = mydom.parseFromString("<outer>"+text+"</outer>", "text/xml");
272
alert("Couldn't parse incoming xml: "+text+", error: "+e);
275
var nodes = newdoc.documentElement.childNodes;
276
for (var i = 0; i < nodes.length; ++i) {
277
var e = nodes.item(i);
278
if(e.nodeType == 1) {
279
p = S.getElem(e.getAttribute('id'));
281
self.syncElement(e, p);
283
//shape = svgdoc.createElementNS(svgns, data.element);
284
var shape = S.addSvgElementFromJson( {
285
"element": e.tagName,
286
"attr": self.hashAttributes(e),
288
for(var j = 0; j < e.childNodes.length; ++j) {
289
n = e.childNodes.item(j);
290
shape.appendChild(n.cloneNode(true));
297
removal: function(length, line, count, offset, nolines) {
298
//var current = svgCanvas.getSvgString();
299
// This will not work in all cases, because the lines in the local cache
300
// Will break when we have a problem between the local and global strings.
301
//(partial, total) = getAffectedLines(length, line, count, offset);
302
//for(e in elementsInText(partial)) {
303
// syncElement(e.id, e);
305
//for(e in elementsInText(total)) {
267
insertAfter: function(target, sibling) {
268
if (sibling.nextSibling) {
269
sibling.parentNode.insertBefore(target, sibling.nextSibling);
271
sibling.parentNode.appendChild(target);
274
setDocument: function(text) {
275
// Set the document in total (used for resync and for first starting.
276
currentDocument = text;
277
svgCanvas.setSvgString(text);
278
svgEditor.updateCanvas();
280
updateElement: function(id, element) {
281
// Update an element with a new
282
self.syncElement(element, S.getElem(id));
284
addElements: function(elements, parentId, sibling) {
285
// Add a list of elements to the canvas
286
var sop = S.getElem(parentId);
287
for(var i = 0; i < elements.length; ++i) {
288
var element = elements.item(i);
289
if(element.nodeType != 1) continue;
291
var id = element.getAttribute('id');
292
var existing = S.getElem(id);
294
self.updateElement(element, existing);
297
// parent is really sibling
298
self.insertAfter(element, sop);
301
sop.appendChild(element);
306
removeElement: function(id) {
307
// Remove an element from the canvas.
308
var element = S.getElem(id);
310
element.parentNode.removeChild(element);
312
alert("Removal error, can't find: "+id);*/
315
addition: function(text, offset, line, inset, nolines) {
316
var coffset = offset + inset;
317
var start = currentDocument.substr(0, coffset);
318
currentDocument = start + text + currentDocument.substr(coffset);
320
if(text.indexOf('<') != -1 && text.indexOf('>') != -1) {
322
// First we want to get the parent or sibling
323
var tagStart = start.lastIndexOf('<');
324
if(start.charAt(tagStart + 1) == '/') {
325
// We've found the end tag instead
326
tagStart = start.lastIndexOf('<', tagStart - 1);
329
var tagEnd = start.lastIndexOf('>');
330
var tag = start.substr(tagStart, tagEnd - tagStart + 1);
331
if(tag.charAt(tag.length-2) == '/' || foundEnd) { // Sibling
332
var sid = self.parseFragment(tag)[0].getAttribute('id');
333
self.addElements(self.parseFragment(text), sid, 1);
335
tag = tag.substr(0, tag.length - 2) + '/>';
336
var pid = self.parseFragment(tag)[0].getAttribute('id');
337
self.addElements(self.parseFragment(text), pid, 0);
341
removal: function(length, offset, line, inset, nolines) {
342
var coffset = offset + inset;
343
// We might want to change this is look for > or <, but for now, lines is ok.
344
var nextcrt = currentDocument.indexOf("\n", coffset + length -1);
345
var linesEffected = currentDocument.substr(offset, nextcrt - offset);
346
var text = currentDocument.substr(coffset, length);
348
currentDocument = currentDocument.substr(0, coffset) +
349
currentDocument.substr(coffset + length);
351
if(text.indexOf('<') != -1 && text.indexOf('>') != -1) {
353
var nodes = self.parseFragment(text);
354
for(var i = 0; i < nodes.length; ++i) {
355
var e = nodes.item(i);
356
if(e.nodeType == 1) {
357
self.removeElement(e.getAttribute('id'));
361
// Changed text or attribute?
362
var nodes = self.parseFragment(linesEffected);
363
for(var i = 0; i < nodes.length; ++i) {
364
var e = nodes.item(i);
365
if(e.nodeType == 1) {
366
self.updateElement(e.getAttribute('id'), e);
372
padeditor.bind('reset', self.setDocument);
310
373
padeditor.bind('addition', self.addition);
311
374
padeditor.bind('removal', self.removal);