~doctormo/+junk/ethsketch

« back to all changes in this revision

Viewing changes to static/svg/extensions/ext-etherpad.js

  • Committer: Martin Owens (DoctorMO)
  • Date: 2011-12-07 17:06:57 UTC
  • Revision ID: doctormo@gmail.com-20111207170657-5sb7a0u10g6utuje
Make the write portion work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 
10
10
var svgns = "http://www.w3.org/2000/svg"
11
11
 
 
12
 
12
13
var currentDocument = '';
13
14
var documentIds = new Array;
14
15
var tostr = function(e) { return (new XMLSerializer()).serializeToString(e); }
107
108
        alert("Problem loadinding image from pad! (not started)");
108
109
        return;
109
110
      }
110
 
      svgCanvas.setSvgString(atxt.text);
111
 
      svgEditor.updateCanvas();
 
111
      self.call('reset', [ atxt.text ] )
112
112
    },
113
113
    applyChangesToBase: function(cs, optAuthor, apoolJsonObj)
114
114
    {
116
116
      var changes    = Changeset.opIterator(unpacked.ops);
117
117
      var characters = Changeset.stringIterator(unpacked.charBank);
118
118
 
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
122
122
 
123
123
      while (changes.hasNext()) {
124
124
        var op = changes.next();
125
125
        switch (op.opcode) {
126
126
        case '+':
 
127
          // chars - Number of charicters to add
 
128
          // lines - Number of lines to add
127
129
          text = characters.take(op.chars);
128
130
          if(text) {
129
 
              self.call('addition', [ text, line, count, offset, op.lines ]);
 
131
              self.call('addition', [ text, offset, line, inset, op.lines ]);
130
132
          } else {
131
133
              alert("No text: "+text+" from "+unpacked.charBank);
132
134
          }
133
 
          // chars - Number of charicters to add
134
 
          // lines - Number of lines to add
135
135
          break;
136
136
        case '-':
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 ]);
140
140
          break;
141
141
        case '=':
142
142
          // This very may well happen multiple times.
143
143
          if(op.lines > 0) {
144
 
            count = op.chars
145
 
            line = op.lines
 
144
            offset = op.chars;
 
145
            line = op.lines;
146
146
          } else {
147
 
            offset = op.chars
 
147
            inset = op.chars;
148
148
          }
149
149
          break;
150
150
        }
239
239
          alert(tostr(root));
240
240
      }
241
241
    },
 
242
    parseFragment: function(text) {
 
243
      var mydom = new DOMParser();
 
244
      try {
 
245
        // The name space is VITALLY import to making sure this works right.
 
246
        var doc = mydom.parseFromString('<svg xmlns="http://www.w3.org/2000/svg">' +
 
247
          text+"</svg>", "text/xml");
 
248
        return doc.documentElement.childNodes;
 
249
      } catch(e) {
 
250
        alert("Couldn't parse incoming xml: "+text+", error: "+e);
 
251
      }
 
252
    },
242
253
    syncElement: function(source, target) {
243
254
      // Remove any removed attributes
244
255
      $.each(target.attributes, function(i, attr) {
253
264
        }
254
265
      });
255
266
    },
256
 
    hashAttributes: function(element) {
257
 
      result = {};
258
 
      $.each(element.attributes, function(i, attr) {
259
 
        if(attr && attr.value) {
260
 
          result[attr.nodeName] = attr.nodeValue;
261
 
        }
262
 
      });
263
 
      return result;
264
 
    },
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();
269
 
      try {
270
 
        var newdoc = mydom.parseFromString("<outer>"+text+"</outer>", "text/xml");
271
 
      } catch(e) {
272
 
        alert("Couldn't parse incoming xml: "+text+", error: "+e);
273
 
      }
274
 
      if(newdoc) {
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'));
280
 
             if(p) {
281
 
               self.syncElement(e, p);
282
 
             } else {
283
 
               //shape = svgdoc.createElementNS(svgns, data.element);
284
 
               var shape = S.addSvgElementFromJson( {
285
 
                 "element": e.tagName,
286
 
                 "attr": self.hashAttributes(e),
287
 
               });
288
 
               for(var j = 0; j < e.childNodes.length; ++j) {
289
 
                 n = e.childNodes.item(j);
290
 
                 shape.appendChild(n.cloneNode(true));
291
 
               }
292
 
             }
293
 
           }
294
 
         }
295
 
      }*/
296
 
    },
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);
304
 
      //}
305
 
      //for(e in elementsInText(total)) {
306
 
      //  removeElement(e);
307
 
      //}
 
267
    insertAfter: function(target, sibling) {
 
268
      if (sibling.nextSibling) {
 
269
        sibling.parentNode.insertBefore(target, sibling.nextSibling);
 
270
      } else {
 
271
        sibling.parentNode.appendChild(target);
 
272
      }
 
273
    },
 
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();
 
279
    },
 
280
    updateElement: function(id, element) {
 
281
      // Update an element with a new
 
282
      self.syncElement(element, S.getElem(id));
 
283
    },
 
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;
 
290
 
 
291
        var id = element.getAttribute('id');
 
292
        var existing = S.getElem(id);
 
293
        if(existing) {
 
294
          self.updateElement(element, existing);
 
295
        } else {
 
296
          if(sibling) {
 
297
            // parent is really sibling
 
298
            self.insertAfter(element, sop);
 
299
            sop = element;
 
300
          } else {
 
301
            sop.appendChild(element);
 
302
          }
 
303
        }
 
304
      }
 
305
    },
 
306
    removeElement: function(id) {
 
307
      // Remove an element from the canvas.
 
308
      var element = S.getElem(id);
 
309
      if(element) {    
 
310
        element.parentNode.removeChild(element);
 
311
      /*} else {
 
312
        alert("Removal error, can't find: "+id);*/
 
313
      }
 
314
    },
 
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);
 
319
      
 
320
      if(text.indexOf('<') != -1 && text.indexOf('>') != -1) {
 
321
        var foundEnd = 0;
 
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);
 
327
          foundEnd = 1;
 
328
        }
 
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);
 
334
        } else { // Parent
 
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);
 
338
        }
 
339
      }
 
340
    },
 
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);
 
347
 
 
348
      currentDocument = currentDocument.substr(0, coffset) +
 
349
                        currentDocument.substr(coffset + length);
 
350
 
 
351
      if(text.indexOf('<') != -1 && text.indexOf('>') != -1) {
 
352
        // Removed elements
 
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'));
 
358
           }
 
359
        }
 
360
      } else {
 
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);
 
367
           }
 
368
        }
 
369
      }
308
370
    }
309
371
  };
 
372
  padeditor.bind('reset', self.setDocument);
310
373
  padeditor.bind('addition', self.addition);
311
374
  padeditor.bind('removal', self.removal);
312
 
 
 
375
 
313
376
  return self;
314
377
});
315
378