Commits

Udi Bauman committed 0d65eea

Initial parsing of source into Backbone models

Comments (0)

Files changed (5)

                     <div id="diagram_widget" style="width: 675px; height: 360px;"></div>
                 </div>
                 <div class="tab-pane fade" id="source">
-                    <textarea id="source_input" rows="20" style="width: 675px; height: 341px;"></textarea>
+                    <div>
+                        <textarea id="source_input" rows="20" style="width: 675px; height: 341px;"></textarea>
+                        <p class="muted" style="float: right;">
+                            For example:<br/><br/>
+                            Class1 : BaseClass1<br/>
+                            +method1<br/>
+                            +method2<br/>
+                            -method3<br/>
+                            <br/>
+                            Class2 : BaseClass2<br/>
+                            +method1<br/>
+                            +method2<br/>
+                            -method3<br/>
+                        </p>
+                    </div>
                 </div>
             </div>
 
     <script src="js/jquery.min.js"></script>
     <script src="js/underscore.js"></script>
     <script src="js/backbone.js"></script>
+    <script src="js/backbone.dualstorage.js"></script>
     <script src="js/bootstrap-transition.js"></script>
     <script src="js/bootstrap-alert.js"></script>
     <script src="js/bootstrap-modal.js"></script>
     <script src="js/bootstrap-typeahead.js"></script>
     <script src="js/model-models.js"></script>
     <script src="js/model-widgets.js"></script>
+    <script src="js/model-controllers.js"></script>
 
   </body>
 </html>

js/backbone.dualstorage.js

+(function() {
+  'use strict';
+  var S4, dualsync, getUrl, guid, localsync, methodMap, onlineSync, urlError;
+
+  S4 = function() {
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  };
+
+  guid = function() {
+    return S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4();
+  };
+
+  window.Store = (function() {
+
+    Store.prototype.sep = '';
+
+    function Store(name) {
+      var store;
+      this.name = name;
+      store = localStorage.getItem(this.name);
+      this.records = (store && store.split(',')) || [];
+    }
+
+    Store.prototype.save = function() {
+      return localStorage.setItem(this.name, this.records.join(','));
+    };
+
+    Store.prototype.create = function(model) {
+      console.log('creating', model, 'in', this.name);
+      if (!_.isObject(model)) return model;
+      if (model.attributes != null) model = model.attributes;
+      if (!model.id) model.id = guid();
+      localStorage.setItem(this.name + this.sep + model.id, JSON.stringify(model));
+      this.records.push(model.id.toString());
+      this.save();
+      return model;
+    };
+
+    Store.prototype.update = function(model) {
+      console.log('updating', model, 'in', this.name);
+      localStorage.setItem(this.name + this.sep + model.id, JSON.stringify(model));
+      if (!_.include(this.records, model.id.toString())) {
+        this.records.push(model.id.toString());
+      }
+      this.save();
+      return model;
+    };
+
+    Store.prototype.find = function(model) {
+      console.log('finding', model, 'in', this.name);
+      return JSON.parse(localStorage.getItem(this.name + this.sep + model.id));
+    };
+
+    Store.prototype.findAll = function() {
+      var id, _i, _len, _ref, _results;
+      console.log('findAlling');
+      _ref = this.records;
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        id = _ref[_i];
+        _results.push(JSON.parse(localStorage.getItem(this.name + this.sep + id)));
+      }
+      return _results;
+    };
+
+    Store.prototype.destroy = function(model) {
+      console.log('trying to destroy', model, 'in', this.name);
+      localStorage.removeItem(this.name + this.sep + model.id);
+      this.records = _.reject(this.records, function(record_id) {
+        return record_id === model.id.toString();
+      });
+      this.save();
+      return model;
+    };
+
+    return Store;
+
+  })();
+
+  localsync = function(method, model, options, error) {
+    var resp, store;
+    if (typeof options === 'function') {
+      options = {
+        success: options,
+        error: error
+      };
+    }
+    store = model.localStorage || model.collection.localStorage;
+    resp = (function() {
+      switch (method) {
+        case 'read':
+          if (model.id) {
+            return store.find(model);
+          } else {
+            return store.findAll();
+          }
+          break;
+        case 'create':
+          return store.create(model);
+        case 'update':
+          return store.update(model);
+        case 'delete':
+          return store.destroy(model);
+      }
+    })();
+    if (resp) {
+      return options.success(resp);
+    } else {
+      return options.error('Record not found');
+    }
+  };
+
+  getUrl = function(object) {
+    if (!(object && object.url)) return null;
+    if (_.isFunction(object.url)) {
+      return object.url();
+    } else {
+      return object.url;
+    }
+  };
+
+  urlError = function() {
+    throw new Error('A "url" property or function must be specified');
+  };
+
+  methodMap = {
+    'create': 'POST',
+    'update': 'PUT',
+    'delete': 'DELETE',
+    'read': 'GET'
+  };
+
+  onlineSync = Backbone.sync;
+
+  dualsync = function(method, model, options) {
+    var response, store, success;
+    console.log('dualsync', method, model, options);
+    store = new Store(getUrl(model));
+    switch (method) {
+      case 'read':
+        if (store) {
+          response = model.id ? store.find(model) : store.findAll();
+          if (!_.isEmpty(response)) {
+            console.log('getting local', response, 'from', store);
+            options.success(response);
+            return;
+          }
+          success = options.success;
+          options.success = function(resp, status, xhr) {
+            var i, _i, _len;
+            console.log('got remote', resp, 'putting into', store);
+            if (_.isArray(resp)) {
+              for (_i = 0, _len = resp.length; _i < _len; _i++) {
+                i = resp[_i];
+                console.log('trying to store', i);
+                store.create(i);
+              }
+            } else {
+              store.create(resp);
+            }
+            return success(resp);
+          };
+        }
+        if (!model.local) return onlineSync(method, model, options);
+        break;
+      case 'create':
+        if (!model.local && options.remote !== false) {
+          onlineSync(method, model, options);
+        }
+        return store.create(model);
+      case 'update':
+        if (!model.local && options.remote !== false) {
+          onlineSync(method, model, options);
+        }
+        return store.update(model);
+      case 'delete':
+        if (!model.local && options.remote !== false) {
+          onlineSync(method, model, options);
+        }
+        return store.destroy(model);
+    }
+  };
+
+  Backbone.sync = dualsync;
+
+}).call(this);

js/model-controllers.js

+/**
+ * User: udibauman
+ * Date: 2/3/12
+ * Time: 8:08 AM
+ */
+
+
+var SourceParser = {
+
+    parse: function() {
+        var previous_source = "",
+            current_class = "",
+            current_super_classes = [];
+
+        var members_map = {
+            "+": [],
+            "-": []
+        };
+
+        var add_class = function() {
+            var cls = new Class({
+                "name": current_class,
+                "super_classes": _.clone(current_super_classes),
+                "public_methods": _.clone(members_map["+"]),
+                "private_methods": _.clone(members_map["-"])
+            });
+            var existing_class = current_diagram.find(function(c) { return c.get('name') == cls.name});
+            if (existing_class) {
+                existing_class.set(cls);
+            }
+            else {
+                current_diagram.add(cls);
+            }
+            current_class = "";
+            current_super_classes = [];
+            members_map["+"] = [];
+            members_map["-"] = [];
+        };
+
+        return function() {
+            var source = $("#source_input").val();
+            if (source != previous_source) {
+                previous_source = source;
+                var lines = source.split("\n");
+                _.each(lines, function(line) {
+                    if (line.trim().length == 0) return;
+                    var first_char = line.charAt(0);
+                    if (members_map[first_char]) {
+                        members_map[first_char].push(line.substr(1));
+                    }
+                    else {
+                        if (current_class != "") {
+                            add_class();
+                        }
+                        if (line.indexOf(":") >= 0) {
+                            var parts = line.split(":");
+                            current_class = parts[0].trim();
+                            current_super_classes = parts[1].trim().split(",");
+                        }
+                        else {
+                            current_class = line;
+                        }
+                    }
+                });
+                add_class();
+            }
+        }
+    }
+
+
+};
+
+
+$(function () {
+    var parse = SourceParser.parse(),
+        first_time = true;
+    $('a[data-toggle="tab"]').on('shown', function (e) {
+        if (first_time) {
+            first_time = false;
+            if (current_diagram.source != "") {
+                $("#source_input").val(current_diagram.source);
+            }
+        }
+        parse();
+    })
+});

js/model-models.js

 
 
 var Diagram = Backbone.Collection.extend({
-    model: Class
-});
+    model: Class,
+    source: ""
+});
+
+
+var current_diagram = new Diagram();

js/model-widgets.js

 
 
 
-$(function () {
-    $('a[data-toggle="tab"]').on('shown', function (e) {
-
-
-    })
-});
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.