diff options
| author | Misko Hevery | 2010-01-23 15:54:58 -0800 | 
|---|---|---|
| committer | Misko Hevery | 2010-01-23 15:54:58 -0800 | 
| commit | 4460328bc1173f5d97fb4ff54edc041968486fce (patch) | |
| tree | 40e18a175f7f1ae104aa56347fe5038526374ed8 /src | |
| parent | e41ee88ef85986dcd0fea23fefcc57d89cee5c0b (diff) | |
| download | angular.js-4460328bc1173f5d97fb4ff54edc041968486fce.tar.bz2 | |
lots of cleanup to get it ready for OS
Diffstat (limited to 'src')
| -rw-r--r-- | src/Angular.js | 328 | ||||
| -rw-r--r-- | src/Binder.js | 19 | ||||
| -rw-r--r-- | src/JSON.js | 18 | ||||
| -rw-r--r-- | src/Users.js | 4 | ||||
| -rw-r--r-- | src/Widgets.js | 11 | 
5 files changed, 163 insertions, 217 deletions
diff --git a/src/Angular.js b/src/Angular.js index 3dc72ff7..51fca458 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -134,16 +134,6 @@ function bind(_this, _function) {    };  } -function shiftBind(_this, _function) { -  return function() { -    var args = [ this ]; -    for ( var i = 0; i < arguments.length; i++) { -      args.push(arguments[i]); -    } -    return _function.apply(_this, args); -  }; -} -  function outerHTML(node) {    var temp = document.createElement('div');    temp.appendChild(node); @@ -177,159 +167,9 @@ function merge(src, dst) {  }  // //////////////////////////// -// Angular +// UrlWatcher  // //////////////////////////// -function Angular(document, head, config) { -  this.document = jQuery(document); -  this.head = jQuery(head); -  this.config = config; -  this.location = window.location; -} - -Angular.prototype = { -  load: function() { -    this.configureLogging(); -    log("Server: " + this.config.server); -    this.configureJQueryPlugins(); -    this.computeConfiguration(); -    this.bindHtml(); -  }, -   -  configureJQueryPlugins: function() { -    log('Angular.configureJQueryPlugins()'); -    jQuery['fn']['scope'] = function() { -      var element = this; -      while (element && element.get(0)) { -        var scope = element.data("scope"); -        if (scope) -          return scope; -        element = element.parent(); -      } -      return null; -    }; -    jQuery['fn']['controller'] = function() { -      return this.data('controller') || NullController.instance; -    }; -  }, -   -  uid: function() { -    return "" + new Date().getTime(); -  }, -   -  computeConfiguration: function() { -    var config = this.config; -    if (!config.database) { -      var match = config.server.match(/https?:\/\/([\w]*)/); -      config.database = match ? match[1] : "$MEMORY"; -    } -  }, -   -  bindHtml: function() { -    log('Angular.bindHtml()'); -    var watcher = this.watcher = new UrlWatcher(this.location); -    var document = this.document; -    var widgetFactory = new WidgetFactory(this.config.server, this.config.database); -    var binder = new Binder(document[0], widgetFactory, watcher, this.config); -    widgetFactory.onChangeListener = shiftBind(binder, binder.updateModel); -    var controlBar = new ControlBar(document.find('body'), this.config.server); -    var onUpdate = function(){binder.updateView();}; -    var server = this.config.database=="$MEMORY" ? -        new FrameServer(this.window) : -        new Server(this.config.server, jQuery.getScript); -    server = new VisualServer(server, new Status(jQuery(document.body)), onUpdate); -    var users = new Users(server, controlBar); -    var databasePath = '/data/' + this.config.database; -    var post = function(request, callback){ -      server.request("POST", databasePath, request, callback); -    }; -    var datastore = new DataStore(post, users, binder.anchor); -    binder.updateListeners.push(function(){datastore.flush();}); -    var scope = new Scope( { -      '$anchor' : binder.anchor, -      '$binder' : binder, -      '$config' : this.config, -      '$console' : window.console, -      '$datastore' : datastore, -      '$save' : function(callback) { -        datastore.saveScope(scope.state, callback, binder.anchor); -      }, -      '$window' : window, -      '$uid' : this.uid, -      '$users' : users -    }, "ROOT"); -   -    document.data('scope', scope); -    log('$binder.entity()'); -    binder.entity(scope); -   -    log('$binder.compile()'); -    binder.compile(); -   -    log('ControlBar.bind()'); -    controlBar.bind(); -   -    log('$users.fetchCurrentUser()'); -    function fetchCurrentUser() { -      users.fetchCurrentUser(function(u) { -        if (!u && document.find("[ng-auth=eager]").length) { -          users.login(); -        } -      }); -    } -    fetchCurrentUser(); -   -    log('PopUp.bind()'); -    new PopUp(document).bind(); -   -    log('$binder.parseAnchor()'); -    binder.parseAnchor(); -     -    document.find("body").show(); -    log('ready()'); -  }, -   -  visualPost: function(delegate) { -    var status = new Status(jQuery(document.body)); -    return function(request, delegateCallback) { -      status.beginRequest(request); -      var callback = function() { -        status.endRequest(); -        try { -          delegateCallback.apply(this, arguments); -        } catch (e) { -          alert(toJson(e)); -        } -      }; -      delegate(request, callback); -    }; -  }, -   -  configureLogging: function() { -    var url = window.location.href + '#'; -    url = url.split('#')[1]; -    var config = { -      debug : null -    }; -    var configs = url.split('&'); -    for ( var i = 0; i < configs.length; i++) { -      var part = (configs[i] + '=').split('='); -      config[part[0]] = part[1]; -    } -    if (config.debug == 'console') { -      consoleNode = document.createElement("div"); -      consoleNode.id = 'ng-console'; -      document.getElementsByTagName('body')[0].appendChild(consoleNode); -      log = function() { -        consoleLog('ng-console-info', arguments); -      }; -      console.error = function() { -        consoleLog('ng-console-error', arguments); -      }; -    } -  } -}; -  function UrlWatcher(location) {    this.location = location;    this.delay = 25; @@ -343,6 +183,9 @@ function UrlWatcher(location) {  }  UrlWatcher.prototype = { +  listen: function(fn){ +    this.listener = fn; +  },    watch: function() {      var self = this;      var pull = function() { @@ -369,48 +212,149 @@ UrlWatcher.prototype = {        self.setTimeout(pull, self.delay);      };      pull(); +    return this;    }, -  setUrl: function(url) { -    //TODO: conditionaly? -    var existingURL = window.location.href; +  set: function(url) { +    var existingURL = this.location.href;      if (!existingURL.match(/#/))        existingURL += '#';      if (existingURL != url) -      window.location.href = url; +      this.location.href = url;      this.existingURL = url;    }, -  getUrl: function() { +  get: function() {      return window.location.href;    }  }; -   -angular['compile'] = function(root, config) { -  config = config || {}; -  var defaults = { -    'server': "", -    'addUrlChangeListener': noop -  }; -  //todo: don't start watcher -  var angular = new Angular(root, jQuery("head"), _(defaults).extend(config)); -  //todo: don't load stylesheet by default -  // loader.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css'); -  // loader.loadCss('/stylesheets/css'); -  angular.load(); -  var scope = jQuery(root).scope(); -  //TODO: cleanup -  return { -    'updateView':function(){return scope.updateView();}, -    'set':function(){return scope.set.apply(scope, arguments);}, -    'get':function(){return scope.get.apply(scope, arguments);}, -    'init':function(){scope.get('$binder.executeInit')(); scope.updateView();}, -    'watchUrl':function(){ -      var binder = scope.get('$binder'); -      var watcher = angular.watcher; -      watcher.listener = bind(binder, binder.onUrlChange, watcher); -      watcher.onUpdate = function(){alert("update");}; -      watcher.watch(); + +///////////////////////////////////////////////// +function configureJQueryPlugins() { +  log('Angular.configureJQueryPlugins()'); +  var fn = jQuery['fn']; +  fn['scope'] = function() { +    var element = this; +    while (element && element.get(0)) { +      var scope = element.data("scope"); +      if (scope) +        return scope; +      element = element.parent();      } +    return null; +  }; +  fn['controller'] = function() { +    return this.data('controller') || NullController.instance;    }; +} + +function configureLogging(config) { +  if (config.debug == 'console' && !consoleNode) { +    consoleNode = document.createElement("div"); +    consoleNode.id = 'ng-console'; +    document.getElementsByTagName('body')[0].appendChild(consoleNode); +    log = function() { +      consoleLog('ng-console-info', arguments); +    }; +    console.error = function() { +      consoleLog('ng-console-error', arguments); +    }; +  } +} + +function exposeMethods(obj, methods){ +  var bound = {}; +  foreach(methods, function(fn, name){ +    bound[name] = _(fn).bind(obj); +  }); +  return bound; +} + +function wireAngular(element, config) { +  var widgetFactory = new WidgetFactory(config['server'], config['database']); +  var binder = new Binder(element[0], widgetFactory, config['location'], config); +  var controlBar = new ControlBar(element.find('body'), config.server); +  var onUpdate = function(){binder.updateView();}; +  var server = config.database=="$MEMORY" ? +      new FrameServer(this.window) : +      new Server(config.server, jQuery.getScript); +  server = new VisualServer(server, new Status(jQuery(element.body)), onUpdate); +  var users = new Users(server, controlBar); +  var databasePath = '/data/' + config.database; +  var post = function(request, callback){ +    server.request("POST", databasePath, request, callback); +  }; +  var datastore = new DataStore(post, users, binder.anchor); +  binder.updateListeners.push(function(){datastore.flush();}); +  var scope = new Scope({ +    '$anchor'    : binder.anchor, +    '$updateView': _(binder.updateView).bind(binder), +    '$config'    : config, +    '$console'   : window.console, +    '$datastore' : exposeMethods(datastore, { +      'load':                    datastore.load, +      'loadMany':                datastore.loadMany, +      'loadOrCreate':            datastore.loadOrCreate, +      'loadAll':                 datastore.loadAll, +      'save':                    datastore.save, +      'remove':                  datastore.remove, +      'flush':                   datastore.flush, +      'query':                   datastore.query, +      'entity':                  datastore.entity, +      'entities':                datastore.entities, +      'documentCountsByUser':    datastore.documentCountsByUser, +      'userDocumentIdsByEntity': datastore.userDocumentIdsByEntity, +      'join':                    datastore.join +    }), +    '$save' : function(callback) { +      datastore.saveScope(scope.state, callback, binder.anchor); +    }, +    '$window' : window, +    '$uid' : function() { +      return "" + new Date().getTime(); +    }, +    '$users' : users +  }, "ROOT"); + +  element.data('scope', scope); +  binder.entity(scope); +  binder.compile(); +  controlBar.bind(); +   +  //TODO: remove this code +  new PopUp(element).bind(); +   +  var self = _(exposeMethods(scope, { +    'updateView': scope.updateView, +    'set':        scope.set, +    'get':        scope.get, +    'eval':       scope.eval +  })).extend({ +    'init':function(){ +        config['location']['listen'](_(binder.onUrlChange).bind(binder)); +        binder.parseAnchor(); +        binder.executeInit();  +        scope.updateView();  +        return self; +      }, +    'element':element[0], +    'config':config +  }); +  return self; +} + +angular['startUrlWatcher'] = function(){  +  return new UrlWatcher(window['location']).watch(); +}; + +angular['compile'] = function(element, config) { +  config = _({ +      'server': "", +      'location': {'get':noop, 'set':noop, 'listen':noop} +    }).extend(config||{}); + +  configureLogging(config); +  configureJQueryPlugins(); +   +  return wireAngular(jQuery(element), config);  };
\ No newline at end of file diff --git a/src/Binder.js b/src/Binder.js index b687fb77..3fc45a20 100644 --- a/src/Binder.js +++ b/src/Binder.js @@ -1,6 +1,6 @@ -function Binder(doc, widgetFactory, urlWatcher, config) { +function Binder(doc, widgetFactory, location, config) {    this.doc = doc; -  this.urlWatcher = urlWatcher; +  this.location = location;    this.anchor = {};    this.widgetFactory = widgetFactory;    this.config = config || {}; @@ -48,9 +48,8 @@ Binder.prototype = {      return params;    }, -  parseAnchor: function(url) { -    var self = this; -    url = url || this.urlWatcher.getUrl(); +  parseAnchor: function() { +    var self = this, url = this.location.get() || "";      var anchorIndex = url.indexOf('#');      if (anchorIndex < 0) return; @@ -65,13 +64,13 @@ Binder.prototype = {      });    }, -  onUrlChange: function (url) { -    this.parseAnchor(url); +  onUrlChange: function() { +    this.parseAnchor();      this.updateView();    },    updateAnchor: function() { -    var url = this.urlWatcher.getUrl(); +    var url = this.location.get();      var anchorIndex = url.indexOf('#');      if (anchorIndex > -1)        url = url.substring(0, anchorIndex); @@ -88,7 +87,7 @@ Binder.prototype = {          sep = '&';        }      } -    this.urlWatcher.setUrl(url); +    this.location.set(url);      return url;    }, @@ -154,7 +153,7 @@ Binder.prototype = {          jNode.addClass("ng-exception");          jNode.attr('ng-error', toJson(e, true));        } -      scope.eval('$binder.updateView()'); +      scope.get('$updateView')();        return false;      });    }, diff --git a/src/JSON.js b/src/JSON.js index 0c842865..98dfddd2 100644 --- a/src/JSON.js +++ b/src/JSON.js @@ -2,7 +2,7 @@ array = [].constructor;  function toJson(obj, pretty){    var buf = []; -  toJsonArray(buf, obj, pretty ? "\n  " : null); +  toJsonArray(buf, obj, pretty ? "\n  " : null, _([]));    return buf.join('');  }; @@ -25,7 +25,14 @@ function fromJson(json) {  angular['toJson'] = toJson;  angular['fromJson'] = fromJson; -function toJsonArray(buf, obj, pretty){ +function toJsonArray(buf, obj, pretty, stack){ +  if (typeof obj == "object") { +    if (stack.include(obj)) { +      buf.push("RECURSION"); +      return; +    } +    stack.push(obj); +  }    var type = typeof obj;    if (obj === null) {      buf.push("null"); @@ -52,7 +59,7 @@ function toJsonArray(buf, obj, pretty){          if (typeof item == 'function' || typeof item == 'undefined') {            buf.push("null");          } else { -          toJsonArray(buf, item, pretty); +          toJsonArray(buf, item, pretty, stack);          }          sep = true;        } @@ -82,7 +89,7 @@ function toJsonArray(buf, obj, pretty){              }              buf.push(angular['String']['quote'](key));              buf.push(":"); -            toJsonArray(buf, value, childPretty); +            toJsonArray(buf, value, childPretty, stack);              comma = true;            }          } catch (e) { @@ -91,4 +98,7 @@ function toJsonArray(buf, obj, pretty){        buf.push("}");      }    } +  if (typeof obj == "object") { +    stack.pop(); +  }  }; diff --git a/src/Users.js b/src/Users.js index 47da4f73..79ed3129 100644 --- a/src/Users.js +++ b/src/Users.js @@ -7,7 +7,7 @@ Users.prototype = {    'fetchCurrentUser':function(callback) {      var self = this;      this.server.request("GET", "/account.json", {}, function(code, response){ -      self.current = response.user; +      self['current'] = response['user'];        callback(response.user);      });    }, @@ -15,7 +15,7 @@ Users.prototype = {    'logout': function(callback) {      var self = this;      this.controlBar.logout(function(){ -      delete self.current; +      delete self['current'];        (callback||noop)();      });    }, diff --git a/src/Widgets.js b/src/Widgets.js index f93f2476..a012adf3 100644 --- a/src/Widgets.js +++ b/src/Widgets.js @@ -9,7 +9,6 @@ function WidgetFactory(serverUrl, database) {        alert("ERROR: swfobject not loaded!");      };    } -  this.onChangeListener = function(){};  };  WidgetFactory.prototype = { @@ -43,12 +42,12 @@ WidgetFactory.prototype = {        throw 'Unknown type: ' + type;      }      input.data('controller', controller); -    var binder = scope.get('$binder'); +    var updateView = scope.get('$updateView');      var action = function() {        if (controller.updateModel(scope)) {          var action = jQuery(controller.view).attr('ng-action') || "";          if (scope.evalWidget(controller, action)) { -          binder.updateView(scope); +          updateView(scope);          }        }        return bubbleEvent; @@ -74,12 +73,6 @@ WidgetFactory.prototype = {      var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);      jQuery(swfNode).data('controller', cntl);      return cntl; -  }, -   -  createTextWidget: function(textInput) { -    var controller = new TextController(textInput); -    controller.onChange(this.onChangeListener); -    return controller;    }  };  /////////////////////  | 
