server/php/basic/public_html/static/lib/backbone/backbone.js
author durandn
Thu, 21 Apr 2016 15:18:19 +0200
changeset 605 13d355fd09bf
parent 498 08d121184a38
permissions -rw-r--r--
updated uri to allow optional trailing slash on single resource URIs (django automatic redirects don't carry over the Authorization header that can sometimes be needed, for instance with OAuth)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
     1
//     Backbone.js 1.2.3
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
     3
//     (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
//     Backbone may be freely distributed under the MIT license.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
//     For all details and documentation:
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
//     http://backbonejs.org
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
     8
(function(factory) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
     9
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    10
  // Establish the root object, `window` (`self`) in the browser, or `global` on the server.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    11
  // We use `self` instead of `window` for `WebWorker` support.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    12
  var root = (typeof self == 'object' && self.self == self && self) ||
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    13
            (typeof global == 'object' && global.global == global && global);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
  // Set up Backbone appropriately for the environment. Start with AMD.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
  if (typeof define === 'function' && define.amd) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
    define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
      // Export global even in AMD case in case this script is loaded with
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
      // others that may still expect a global Backbone.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
      root.Backbone = factory(root, exports, _, $);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
  // Next for Node.js or CommonJS. jQuery may not be needed as a module.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
  } else if (typeof exports !== 'undefined') {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    25
    var _ = require('underscore'), $;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    26
    try { $ = require('jquery'); } catch(e) {}
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    27
    factory(root, exports, _, $);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
  // Finally, as a browser global.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
  } else {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
    root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
  }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    34
}(function(root, Backbone, _, $) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
  // Initial Setup
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
  // -------------
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
  // Save the previous value of the `Backbone` variable, so that it can be
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
  // restored later on, if `noConflict` is used.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
  var previousBackbone = root.Backbone;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    43
  // Create a local reference to a common array method we'll want to use later.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    44
  var slice = Array.prototype.slice;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
  // Current version of the library. Keep in sync with `package.json`.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    47
  Backbone.VERSION = '1.2.3';
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
  // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
  // the `$` variable.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
  Backbone.$ = $;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
  // to its previous owner. Returns a reference to this Backbone object.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
  Backbone.noConflict = function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
    root.Backbone = previousBackbone;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
    return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
  // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
  // set a `X-Http-Method-Override` header.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
  Backbone.emulateHTTP = false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
  // Turn on `emulateJSON` to support legacy servers that can't deal with direct
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    66
  // `application/json` requests ... this will encode the body as
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
  // `application/x-www-form-urlencoded` instead and will send the model in a
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
  // form param named `model`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
  Backbone.emulateJSON = false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    71
  // Proxy Backbone class methods to Underscore functions, wrapping the model's
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    72
  // `attributes` object or collection's `models` array behind the scenes.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    73
  //
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    74
  // collection.filter(function(model) { return model.get('age') > 10 });
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    75
  // collection.each(this.addView);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    76
  //
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    77
  // `Function#apply` can be slow so we use the method's arg count, if we know it.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    78
  var addMethod = function(length, method, attribute) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    79
    switch (length) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    80
      case 1: return function() {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    81
        return _[method](this[attribute]);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    82
      };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    83
      case 2: return function(value) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    84
        return _[method](this[attribute], value);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    85
      };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    86
      case 3: return function(iteratee, context) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    87
        return _[method](this[attribute], cb(iteratee, this), context);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    88
      };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    89
      case 4: return function(iteratee, defaultVal, context) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    90
        return _[method](this[attribute], cb(iteratee, this), defaultVal, context);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    91
      };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    92
      default: return function() {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    93
        var args = slice.call(arguments);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    94
        args.unshift(this[attribute]);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    95
        return _[method].apply(_, args);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    96
      };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    97
    }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    98
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
    99
  var addUnderscoreMethods = function(Class, methods, attribute) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   100
    _.each(methods, function(length, method) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   101
      if (_[method]) Class.prototype[method] = addMethod(length, method, attribute);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   102
    });
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   103
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   104
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   105
  // Support `collection.sortBy('attr')` and `collection.findWhere({id: 1})`.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   106
  var cb = function(iteratee, instance) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   107
    if (_.isFunction(iteratee)) return iteratee;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   108
    if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   109
    if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   110
    return iteratee;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   111
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   112
  var modelMatcher = function(attrs) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   113
    var matcher = _.matches(attrs);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   114
    return function(model) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   115
      return matcher(model.attributes);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   116
    };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   117
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   118
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
  // Backbone.Events
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
  // ---------------
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
  // A module that can be mixed in to *any object* in order to provide it with
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   123
  // a custom event channel. You may bind a callback to an event with `on` or
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   124
  // remove with `off`; `trigger`-ing an event fires all callbacks in
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
  // succession.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
  //
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
  //     var object = {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
  //     _.extend(object, Backbone.Events);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
  //     object.on('expand', function(){ alert('expanded'); });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
  //     object.trigger('expand');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
  //
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   132
  var Events = Backbone.Events = {};
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
  // Regular expression used to split event strings.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
  var eventSplitter = /\s+/;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   137
  // Iterates over the standard `event, callback` (as well as the fancy multiple
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   138
  // space-separated events `"change blur", callback` and jQuery-style event
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   139
  // maps `{event: callback}`).
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   140
  var eventsApi = function(iteratee, events, name, callback, opts) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   141
    var i = 0, names;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   142
    if (name && typeof name === 'object') {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   143
      // Handle event maps.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   144
      if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   145
      for (names = _.keys(name); i < names.length ; i++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   146
        events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   147
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   148
    } else if (name && eventSplitter.test(name)) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   149
      // Handle space separated event names by delegating them individually.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   150
      for (names = name.split(eventSplitter); i < names.length; i++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   151
        events = iteratee(events, names[i], callback, opts);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   152
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   153
    } else {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   154
      // Finally, standard events.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   155
      events = iteratee(events, name, callback, opts);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   156
    }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   157
    return events;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   158
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   159
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   160
  // Bind an event to a `callback` function. Passing `"all"` will bind
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   161
  // the callback to all events fired.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   162
  Events.on = function(name, callback, context) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   163
    return internalOn(this, name, callback, context);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   164
  };
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   166
  // Guard the `listening` argument from the public API.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   167
  var internalOn = function(obj, name, callback, context, listening) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   168
    obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   169
        context: context,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   170
        ctx: obj,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   171
        listening: listening
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   172
    });
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   173
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   174
    if (listening) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   175
      var listeners = obj._listeners || (obj._listeners = {});
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   176
      listeners[listening.id] = listening;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   177
    }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   178
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   179
    return obj;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   180
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   181
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   182
  // Inversion-of-control versions of `on`. Tell *this* object to listen to
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   183
  // an event in another object... keeping track of what it's listening to
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   184
  // for easier unbinding later.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   185
  Events.listenTo =  function(obj, name, callback) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   186
    if (!obj) return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   187
    var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   188
    var listeningTo = this._listeningTo || (this._listeningTo = {});
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   189
    var listening = listeningTo[id];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   190
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   191
    // This object is not listening to any other events on `obj` yet.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   192
    // Setup the necessary references to track the listening callbacks.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   193
    if (!listening) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   194
      var thisId = this._listenId || (this._listenId = _.uniqueId('l'));
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   195
      listening = listeningTo[id] = {obj: obj, objId: id, id: thisId, listeningTo: listeningTo, count: 0};
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   198
    // Bind callbacks on obj, and keep track of them on listening.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   199
    internalOn(obj, name, callback, this, listening);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   200
    return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   201
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   202
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   203
  // The reducing API that adds a callback to the `events` object.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   204
  var onApi = function(events, name, callback, options) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   205
    if (callback) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   206
      var handlers = events[name] || (events[name] = []);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   207
      var context = options.context, ctx = options.ctx, listening = options.listening;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   208
      if (listening) listening.count++;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   209
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   210
      handlers.push({ callback: callback, context: context, ctx: context || ctx, listening: listening });
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   211
    }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   212
    return events;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   213
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   214
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   215
  // Remove one or many callbacks. If `context` is null, removes all
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   216
  // callbacks with that function. If `callback` is null, removes all
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   217
  // callbacks for the event. If `name` is null, removes all bound
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   218
  // callbacks for all events.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   219
  Events.off =  function(name, callback, context) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   220
    if (!this._events) return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   221
    this._events = eventsApi(offApi, this._events, name, callback, {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   222
        context: context,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   223
        listeners: this._listeners
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   224
    });
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   225
    return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   226
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   227
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   228
  // Tell this object to stop listening to either specific events ... or
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   229
  // to every object it's currently listening to.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   230
  Events.stopListening =  function(obj, name, callback) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   231
    var listeningTo = this._listeningTo;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   232
    if (!listeningTo) return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   233
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   234
    var ids = obj ? [obj._listenId] : _.keys(listeningTo);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   235
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   236
    for (var i = 0; i < ids.length; i++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   237
      var listening = listeningTo[ids[i]];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   238
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   239
      // If listening doesn't exist, this object is not currently
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   240
      // listening to obj. Break out early.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   241
      if (!listening) break;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   242
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   243
      listening.obj.off(name, callback, this);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   244
    }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   245
    if (_.isEmpty(listeningTo)) this._listeningTo = void 0;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   246
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   247
    return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   248
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   249
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   250
  // The reducing API that removes a callback from the `events` object.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   251
  var offApi = function(events, name, callback, options) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   252
    if (!events) return;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   253
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   254
    var i = 0, listening;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   255
    var context = options.context, listeners = options.listeners;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   256
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   257
    // Delete all events listeners and "drop" events.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   258
    if (!name && !callback && !context) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   259
      var ids = _.keys(listeners);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   260
      for (; i < ids.length; i++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   261
        listening = listeners[ids[i]];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   262
        delete listeners[listening.id];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   263
        delete listening.listeningTo[listening.objId];
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   264
      }
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   265
      return;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   266
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   267
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   268
    var names = name ? [name] : _.keys(events);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   269
    for (; i < names.length; i++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   270
      name = names[i];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   271
      var handlers = events[name];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   272
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   273
      // Bail out if there are no events stored.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   274
      if (!handlers) break;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   275
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   276
      // Replace events if there are any remaining.  Otherwise, clean up.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   277
      var remaining = [];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   278
      for (var j = 0; j < handlers.length; j++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   279
        var handler = handlers[j];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   280
        if (
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   281
          callback && callback !== handler.callback &&
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   282
            callback !== handler.callback._callback ||
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   283
              context && context !== handler.context
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   284
        ) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   285
          remaining.push(handler);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   286
        } else {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   287
          listening = handler.listening;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   288
          if (listening && --listening.count === 0) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   289
            delete listeners[listening.id];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   290
            delete listening.listeningTo[listening.objId];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   291
          }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   292
        }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   293
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   294
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   295
      // Update tail event if the list has any events.  Otherwise, clean up.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   296
      if (remaining.length) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   297
        events[name] = remaining;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   298
      } else {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   299
        delete events[name];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   300
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   301
    }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   302
    if (_.size(events)) return events;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   303
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   304
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   305
  // Bind an event to only be triggered a single time. After the first time
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   306
  // the callback is invoked, its listener will be removed. If multiple events
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   307
  // are passed in using the space-separated syntax, the handler will fire
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   308
  // once for each event, not once for a combination of all events.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   309
  Events.once =  function(name, callback, context) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   310
    // Map the event into a `{event: once}` object.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   311
    var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   312
    return this.on(events, void 0, context);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   313
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   314
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   315
  // Inversion-of-control versions of `once`.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   316
  Events.listenToOnce =  function(obj, name, callback) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   317
    // Map the event into a `{event: once}` object.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   318
    var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   319
    return this.listenTo(obj, events);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   320
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   321
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   322
  // Reduces the event callbacks into a map of `{event: onceWrapper}`.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   323
  // `offer` unbinds the `onceWrapper` after it has been called.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   324
  var onceMap = function(map, name, callback, offer) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   325
    if (callback) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   326
      var once = map[name] = _.once(function() {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   327
        offer(name, once);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   328
        callback.apply(this, arguments);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   329
      });
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   330
      once._callback = callback;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   331
    }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   332
    return map;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   333
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   334
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   335
  // Trigger one or many events, firing all bound callbacks. Callbacks are
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   336
  // passed the same arguments as `trigger` is, apart from the event name
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   337
  // (unless you're listening on `"all"`, which will cause your callback to
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   338
  // receive the true name of the event as the first argument).
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   339
  Events.trigger =  function(name) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   340
    if (!this._events) return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   341
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   342
    var length = Math.max(0, arguments.length - 1);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   343
    var args = Array(length);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   344
    for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   345
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   346
    eventsApi(triggerApi, this._events, name, void 0, args);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   347
    return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   348
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   349
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   350
  // Handles triggering the appropriate event callbacks.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   351
  var triggerApi = function(objEvents, name, cb, args) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   352
    if (objEvents) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   353
      var events = objEvents[name];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   354
      var allEvents = objEvents.all;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   355
      if (events && allEvents) allEvents = allEvents.slice();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   356
      if (events) triggerEvents(events, args);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   357
      if (allEvents) triggerEvents(allEvents, [name].concat(args));
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   358
    }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   359
    return objEvents;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   360
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   361
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   362
  // A difficult-to-believe, but optimized internal dispatch function for
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   363
  // triggering events. Tries to keep the usual cases speedy (most internal
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   364
  // Backbone events have 3 arguments).
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   365
  var triggerEvents = function(events, args) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   366
    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   367
    switch (args.length) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   368
      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   369
      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   370
      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   371
      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   372
      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   373
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   374
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   375
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   376
  // Aliases for backwards compatibility.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   377
  Events.bind   = Events.on;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   378
  Events.unbind = Events.off;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   379
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   380
  // Allow the `Backbone` object to serve as a global event bus, for folks who
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   381
  // want global "pubsub" in a convenient place.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   382
  _.extend(Backbone, Events);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   383
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   384
  // Backbone.Model
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   385
  // --------------
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   386
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   387
  // Backbone **Models** are the basic data object in the framework --
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   388
  // frequently representing a row in a table in a database on your server.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   389
  // A discrete chunk of data and a bunch of useful, related methods for
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   390
  // performing computations and transformations on that data.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   391
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   392
  // Create a new model with the specified attributes. A client id (`cid`)
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   393
  // is automatically generated and assigned for you.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   394
  var Model = Backbone.Model = function(attributes, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   395
    var attrs = attributes || {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   396
    options || (options = {});
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   397
    this.cid = _.uniqueId(this.cidPrefix);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   398
    this.attributes = {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   399
    if (options.collection) this.collection = options.collection;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   400
    if (options.parse) attrs = this.parse(attrs, options) || {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   401
    attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   402
    this.set(attrs, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   403
    this.changed = {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   404
    this.initialize.apply(this, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   405
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   406
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   407
  // Attach all inheritable methods to the Model prototype.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   408
  _.extend(Model.prototype, Events, {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   409
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   410
    // A hash of attributes whose current and previous value differ.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   411
    changed: null,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   412
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   413
    // The value returned during the last failed validation.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   414
    validationError: null,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   415
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   416
    // The default name for the JSON `id` attribute is `"id"`. MongoDB and
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   417
    // CouchDB users may want to set this to `"_id"`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   418
    idAttribute: 'id',
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   419
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   420
    // The prefix is used to create the client id which is used to identify models locally.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   421
    // You may want to override this if you're experiencing name clashes with model ids.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   422
    cidPrefix: 'c',
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   423
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   424
    // Initialize is an empty function by default. Override it with your own
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   425
    // initialization logic.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   426
    initialize: function(){},
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   427
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   428
    // Return a copy of the model's `attributes` object.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   429
    toJSON: function(options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   430
      return _.clone(this.attributes);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   431
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   432
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   433
    // Proxy `Backbone.sync` by default -- but override this if you need
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   434
    // custom syncing semantics for *this* particular model.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   435
    sync: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   436
      return Backbone.sync.apply(this, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   437
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   438
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   439
    // Get the value of an attribute.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   440
    get: function(attr) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   441
      return this.attributes[attr];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   442
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   443
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   444
    // Get the HTML-escaped value of an attribute.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   445
    escape: function(attr) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   446
      return _.escape(this.get(attr));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   447
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   448
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   449
    // Returns `true` if the attribute contains a value that is not null
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   450
    // or undefined.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   451
    has: function(attr) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   452
      return this.get(attr) != null;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   453
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   454
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   455
    // Special-cased proxy to underscore's `_.matches` method.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   456
    matches: function(attrs) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   457
      return !!_.iteratee(attrs, this)(this.attributes);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   458
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   459
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   460
    // Set a hash of model attributes on the object, firing `"change"`. This is
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   461
    // the core primitive operation of a model, updating the data and notifying
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   462
    // anyone who needs to know about the change in state. The heart of the beast.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   463
    set: function(key, val, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   464
      if (key == null) return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   465
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   466
      // Handle both `"key", value` and `{key: value}` -style arguments.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   467
      var attrs;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   468
      if (typeof key === 'object') {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   469
        attrs = key;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   470
        options = val;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   471
      } else {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   472
        (attrs = {})[key] = val;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   473
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   474
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   475
      options || (options = {});
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   476
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   477
      // Run validation.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   478
      if (!this._validate(attrs, options)) return false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   479
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   480
      // Extract attributes and options.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   481
      var unset      = options.unset;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   482
      var silent     = options.silent;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   483
      var changes    = [];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   484
      var changing   = this._changing;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   485
      this._changing = true;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   486
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   487
      if (!changing) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   488
        this._previousAttributes = _.clone(this.attributes);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   489
        this.changed = {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   490
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   491
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   492
      var current = this.attributes;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   493
      var changed = this.changed;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   494
      var prev    = this._previousAttributes;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   495
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   496
      // For each `set` attribute, update or delete the current value.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   497
      for (var attr in attrs) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   498
        val = attrs[attr];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   499
        if (!_.isEqual(current[attr], val)) changes.push(attr);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   500
        if (!_.isEqual(prev[attr], val)) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   501
          changed[attr] = val;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   502
        } else {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   503
          delete changed[attr];
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   504
        }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   505
        unset ? delete current[attr] : current[attr] = val;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   506
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   507
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   508
      // Update the `id`.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   509
      this.id = this.get(this.idAttribute);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   510
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   511
      // Trigger all relevant attribute changes.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   512
      if (!silent) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   513
        if (changes.length) this._pending = options;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   514
        for (var i = 0; i < changes.length; i++) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   515
          this.trigger('change:' + changes[i], this, current[changes[i]], options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   516
        }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   517
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   518
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   519
      // You might be wondering why there's a `while` loop here. Changes can
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   520
      // be recursively nested within `"change"` events.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   521
      if (changing) return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   522
      if (!silent) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   523
        while (this._pending) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   524
          options = this._pending;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   525
          this._pending = false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   526
          this.trigger('change', this, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   527
        }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   528
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   529
      this._pending = false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   530
      this._changing = false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   531
      return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   532
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   533
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   534
    // Remove an attribute from the model, firing `"change"`. `unset` is a noop
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   535
    // if the attribute doesn't exist.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   536
    unset: function(attr, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   537
      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   538
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   539
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   540
    // Clear all attributes on the model, firing `"change"`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   541
    clear: function(options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   542
      var attrs = {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   543
      for (var key in this.attributes) attrs[key] = void 0;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   544
      return this.set(attrs, _.extend({}, options, {unset: true}));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   545
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   546
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   547
    // Determine if the model has changed since the last `"change"` event.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   548
    // If you specify an attribute name, determine if that attribute has changed.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   549
    hasChanged: function(attr) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   550
      if (attr == null) return !_.isEmpty(this.changed);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   551
      return _.has(this.changed, attr);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   552
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   553
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   554
    // Return an object containing all the attributes that have changed, or
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   555
    // false if there are no changed attributes. Useful for determining what
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   556
    // parts of a view need to be updated and/or what attributes need to be
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   557
    // persisted to the server. Unset attributes will be set to undefined.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   558
    // You can also pass an attributes object to diff against the model,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   559
    // determining if there *would be* a change.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   560
    changedAttributes: function(diff) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   561
      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   562
      var old = this._changing ? this._previousAttributes : this.attributes;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   563
      var changed = {};
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   564
      for (var attr in diff) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   565
        var val = diff[attr];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   566
        if (_.isEqual(old[attr], val)) continue;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   567
        changed[attr] = val;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   568
      }
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   569
      return _.size(changed) ? changed : false;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   570
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   571
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   572
    // Get the previous value of an attribute, recorded at the time the last
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   573
    // `"change"` event was fired.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   574
    previous: function(attr) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   575
      if (attr == null || !this._previousAttributes) return null;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   576
      return this._previousAttributes[attr];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   577
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   578
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   579
    // Get all of the attributes of the model at the time of the previous
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   580
    // `"change"` event.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   581
    previousAttributes: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   582
      return _.clone(this._previousAttributes);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   583
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   584
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   585
    // Fetch the model from the server, merging the response with the model's
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   586
    // local attributes. Any changed attributes will trigger a "change" event.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   587
    fetch: function(options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   588
      options = _.extend({parse: true}, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   589
      var model = this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   590
      var success = options.success;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   591
      options.success = function(resp) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   592
        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   593
        if (!model.set(serverAttrs, options)) return false;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   594
        if (success) success.call(options.context, model, resp, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   595
        model.trigger('sync', model, resp, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   596
      };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   597
      wrapError(this, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   598
      return this.sync('read', this, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   599
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   600
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   601
    // Set a hash of model attributes, and sync the model to the server.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   602
    // If the server returns an attributes hash that differs, the model's
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   603
    // state will be `set` again.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   604
    save: function(key, val, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   605
      // Handle both `"key", value` and `{key: value}` -style arguments.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   606
      var attrs;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   607
      if (key == null || typeof key === 'object') {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   608
        attrs = key;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   609
        options = val;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   610
      } else {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   611
        (attrs = {})[key] = val;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   612
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   613
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   614
      options = _.extend({validate: true, parse: true}, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   615
      var wait = options.wait;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   616
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   617
      // If we're not waiting and attributes exist, save acts as
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   618
      // `set(attr).save(null, opts)` with validation. Otherwise, check if
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   619
      // the model will be valid when the attributes, if any, are set.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   620
      if (attrs && !wait) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   621
        if (!this.set(attrs, options)) return false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   622
      } else {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   623
        if (!this._validate(attrs, options)) return false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   624
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   625
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   626
      // After a successful server-side save, the client is (optionally)
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   627
      // updated with the server-side state.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   628
      var model = this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   629
      var success = options.success;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   630
      var attributes = this.attributes;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   631
      options.success = function(resp) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   632
        // Ensure attributes are restored during synchronous saves.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   633
        model.attributes = attributes;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   634
        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   635
        if (wait) serverAttrs = _.extend({}, attrs, serverAttrs);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   636
        if (serverAttrs && !model.set(serverAttrs, options)) return false;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   637
        if (success) success.call(options.context, model, resp, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   638
        model.trigger('sync', model, resp, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   639
      };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   640
      wrapError(this, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   641
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   642
      // Set temporary attributes if `{wait: true}` to properly find new ids.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   643
      if (attrs && wait) this.attributes = _.extend({}, attributes, attrs);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   644
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   645
      var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   646
      if (method === 'patch' && !options.attrs) options.attrs = attrs;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   647
      var xhr = this.sync(method, this, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   648
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   649
      // Restore attributes.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   650
      this.attributes = attributes;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   651
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   652
      return xhr;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   653
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   654
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   655
    // Destroy this model on the server if it was already persisted.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   656
    // Optimistically removes the model from its collection, if it has one.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   657
    // If `wait: true` is passed, waits for the server to respond before removal.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   658
    destroy: function(options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   659
      options = options ? _.clone(options) : {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   660
      var model = this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   661
      var success = options.success;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   662
      var wait = options.wait;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   663
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   664
      var destroy = function() {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   665
        model.stopListening();
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   666
        model.trigger('destroy', model, model.collection, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   667
      };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   668
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   669
      options.success = function(resp) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   670
        if (wait) destroy();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   671
        if (success) success.call(options.context, model, resp, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   672
        if (!model.isNew()) model.trigger('sync', model, resp, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   673
      };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   674
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   675
      var xhr = false;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   676
      if (this.isNew()) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   677
        _.defer(options.success);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   678
      } else {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   679
        wrapError(this, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   680
        xhr = this.sync('delete', this, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   681
      }
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   682
      if (!wait) destroy();
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   683
      return xhr;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   684
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   685
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   686
    // Default URL for the model's representation on the server -- if you're
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   687
    // using Backbone's restful methods, override this to change the endpoint
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   688
    // that will be called.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   689
    url: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   690
      var base =
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   691
        _.result(this, 'urlRoot') ||
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   692
        _.result(this.collection, 'url') ||
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   693
        urlError();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   694
      if (this.isNew()) return base;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   695
      var id = this.get(this.idAttribute);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   696
      return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   697
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   698
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   699
    // **parse** converts a response into the hash of attributes to be `set` on
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   700
    // the model. The default implementation is just to pass the response along.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   701
    parse: function(resp, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   702
      return resp;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   703
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   704
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   705
    // Create a new model with identical attributes to this one.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   706
    clone: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   707
      return new this.constructor(this.attributes);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   708
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   709
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   710
    // A model is new if it has never been saved to the server, and lacks an id.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   711
    isNew: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   712
      return !this.has(this.idAttribute);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   713
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   714
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   715
    // Check if the model is currently in a valid state.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   716
    isValid: function(options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   717
      return this._validate({}, _.defaults({validate: true}, options));
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   718
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   719
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   720
    // Run validation against the next complete set of model attributes,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   721
    // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   722
    _validate: function(attrs, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   723
      if (!options.validate || !this.validate) return true;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   724
      attrs = _.extend({}, this.attributes, attrs);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   725
      var error = this.validationError = this.validate(attrs, options) || null;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   726
      if (!error) return true;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   727
      this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   728
      return false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   729
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   730
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   731
  });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   732
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   733
  // Underscore methods that we want to implement on the Model, mapped to the
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   734
  // number of arguments they take.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   735
  var modelMethods = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   736
      omit: 0, chain: 1, isEmpty: 1 };
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   737
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   738
  // Mix in each Underscore method as a proxy to `Model#attributes`.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   739
  addUnderscoreMethods(Model, modelMethods, 'attributes');
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   740
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   741
  // Backbone.Collection
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   742
  // -------------------
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   743
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   744
  // If models tend to represent a single row of data, a Backbone Collection is
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   745
  // more analogous to a table full of data ... or a small slice or page of that
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   746
  // table, or a collection of rows that belong together for a particular reason
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   747
  // -- all of the messages in this particular folder, all of the documents
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   748
  // belonging to this particular author, and so on. Collections maintain
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   749
  // indexes of their models, both in order, and for lookup by `id`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   750
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   751
  // Create a new **Collection**, perhaps to contain a specific type of `model`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   752
  // If a `comparator` is specified, the Collection will maintain
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   753
  // its models in sort order, as they're added and removed.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   754
  var Collection = Backbone.Collection = function(models, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   755
    options || (options = {});
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   756
    if (options.model) this.model = options.model;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   757
    if (options.comparator !== void 0) this.comparator = options.comparator;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   758
    this._reset();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   759
    this.initialize.apply(this, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   760
    if (models) this.reset(models, _.extend({silent: true}, options));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   761
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   762
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   763
  // Default options for `Collection#set`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   764
  var setOptions = {add: true, remove: true, merge: true};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   765
  var addOptions = {add: true, remove: false};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   766
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   767
  // Splices `insert` into `array` at index `at`.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   768
  var splice = function(array, insert, at) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   769
    at = Math.min(Math.max(at, 0), array.length);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   770
    var tail = Array(array.length - at);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   771
    var length = insert.length;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   772
    for (var i = 0; i < tail.length; i++) tail[i] = array[i + at];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   773
    for (i = 0; i < length; i++) array[i + at] = insert[i];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   774
    for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   775
  };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   776
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   777
  // Define the Collection's inheritable methods.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   778
  _.extend(Collection.prototype, Events, {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   779
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   780
    // The default model for a collection is just a **Backbone.Model**.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   781
    // This should be overridden in most cases.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   782
    model: Model,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   783
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   784
    // Initialize is an empty function by default. Override it with your own
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   785
    // initialization logic.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   786
    initialize: function(){},
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   787
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   788
    // The JSON representation of a Collection is an array of the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   789
    // models' attributes.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   790
    toJSON: function(options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   791
      return this.map(function(model) { return model.toJSON(options); });
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   792
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   793
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   794
    // Proxy `Backbone.sync` by default.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   795
    sync: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   796
      return Backbone.sync.apply(this, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   797
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   798
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   799
    // Add a model, or list of models to the set. `models` may be Backbone
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   800
    // Models or raw JavaScript objects to be converted to Models, or any
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   801
    // combination of the two.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   802
    add: function(models, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   803
      return this.set(models, _.extend({merge: false}, options, addOptions));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   804
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   805
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   806
    // Remove a model, or a list of models from the set.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   807
    remove: function(models, options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   808
      options = _.extend({}, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   809
      var singular = !_.isArray(models);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   810
      models = singular ? [models] : _.clone(models);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   811
      var removed = this._removeModels(models, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   812
      if (!options.silent && removed) this.trigger('update', this, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   813
      return singular ? removed[0] : removed;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   814
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   815
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   816
    // Update a collection by `set`-ing a new list of models, adding new ones,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   817
    // removing models that are no longer present, and merging models that
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   818
    // already exist in the collection, as necessary. Similar to **Model#set**,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   819
    // the core operation for updating the data contained by the collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   820
    set: function(models, options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   821
      if (models == null) return;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   822
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   823
      options = _.defaults({}, options, setOptions);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   824
      if (options.parse && !this._isModel(models)) models = this.parse(models, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   825
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   826
      var singular = !_.isArray(models);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   827
      models = singular ? [models] : models.slice();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   828
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   829
      var at = options.at;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   830
      if (at != null) at = +at;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   831
      if (at < 0) at += this.length + 1;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   832
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   833
      var set = [];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   834
      var toAdd = [];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   835
      var toRemove = [];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   836
      var modelMap = {};
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   837
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   838
      var add = options.add;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   839
      var merge = options.merge;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   840
      var remove = options.remove;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   841
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   842
      var sort = false;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   843
      var sortable = this.comparator && (at == null) && options.sort !== false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   844
      var sortAttr = _.isString(this.comparator) ? this.comparator : null;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   845
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   846
      // Turn bare objects into model references, and prevent invalid models
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   847
      // from being added.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   848
      var model;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   849
      for (var i = 0; i < models.length; i++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   850
        model = models[i];
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   851
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   852
        // If a duplicate is found, prevent it from being added and
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   853
        // optionally merge it into the existing model.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   854
        var existing = this.get(model);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   855
        if (existing) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   856
          if (merge && model !== existing) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   857
            var attrs = this._isModel(model) ? model.attributes : model;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   858
            if (options.parse) attrs = existing.parse(attrs, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   859
            existing.set(attrs, options);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   860
            if (sortable && !sort) sort = existing.hasChanged(sortAttr);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   861
          }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   862
          if (!modelMap[existing.cid]) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   863
            modelMap[existing.cid] = true;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   864
            set.push(existing);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   865
          }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   866
          models[i] = existing;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   867
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   868
        // If this is a new, valid model, push it to the `toAdd` list.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   869
        } else if (add) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   870
          model = models[i] = this._prepareModel(model, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   871
          if (model) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   872
            toAdd.push(model);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   873
            this._addReference(model, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   874
            modelMap[model.cid] = true;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   875
            set.push(model);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   876
          }
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   877
        }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   878
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   879
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   880
      // Remove stale models.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   881
      if (remove) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   882
        for (i = 0; i < this.length; i++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   883
          model = this.models[i];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   884
          if (!modelMap[model.cid]) toRemove.push(model);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   885
        }
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   886
        if (toRemove.length) this._removeModels(toRemove, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   887
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   888
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   889
      // See if sorting is needed, update `length` and splice in new models.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   890
      var orderChanged = false;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   891
      var replace = !sortable && add && remove;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   892
      if (set.length && replace) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   893
        orderChanged = this.length != set.length || _.some(this.models, function(model, index) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   894
          return model !== set[index];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   895
        });
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   896
        this.models.length = 0;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   897
        splice(this.models, set, 0);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   898
        this.length = this.models.length;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   899
      } else if (toAdd.length) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   900
        if (sortable) sort = true;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   901
        splice(this.models, toAdd, at == null ? this.length : at);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   902
        this.length = this.models.length;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   903
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   904
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   905
      // Silently sort the collection if appropriate.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   906
      if (sort) this.sort({silent: true});
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   907
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   908
      // Unless silenced, it's time to fire all appropriate add/sort events.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   909
      if (!options.silent) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   910
        for (i = 0; i < toAdd.length; i++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   911
          if (at != null) options.index = at + i;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   912
          model = toAdd[i];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   913
          model.trigger('add', model, this, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   914
        }
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   915
        if (sort || orderChanged) this.trigger('sort', this, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   916
        if (toAdd.length || toRemove.length) this.trigger('update', this, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   917
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   918
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   919
      // Return the added (or merged) model (or models).
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   920
      return singular ? models[0] : models;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   921
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   922
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   923
    // When you have more items than you want to add or remove individually,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   924
    // you can reset the entire set with a new list of models, without firing
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   925
    // any granular `add` or `remove` events. Fires `reset` when finished.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   926
    // Useful for bulk operations and optimizations.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   927
    reset: function(models, options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   928
      options = options ? _.clone(options) : {};
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   929
      for (var i = 0; i < this.models.length; i++) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   930
        this._removeReference(this.models[i], options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   931
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   932
      options.previousModels = this.models;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   933
      this._reset();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   934
      models = this.add(models, _.extend({silent: true}, options));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   935
      if (!options.silent) this.trigger('reset', this, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   936
      return models;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   937
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   938
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   939
    // Add a model to the end of the collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   940
    push: function(model, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   941
      return this.add(model, _.extend({at: this.length}, options));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   942
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   943
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   944
    // Remove a model from the end of the collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   945
    pop: function(options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   946
      var model = this.at(this.length - 1);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   947
      return this.remove(model, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   948
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   949
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   950
    // Add a model to the beginning of the collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   951
    unshift: function(model, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   952
      return this.add(model, _.extend({at: 0}, options));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   953
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   954
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   955
    // Remove a model from the beginning of the collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   956
    shift: function(options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   957
      var model = this.at(0);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   958
      return this.remove(model, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   959
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   960
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   961
    // Slice out a sub-array of models from the collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   962
    slice: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   963
      return slice.apply(this.models, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   964
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   965
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   966
    // Get a model from the set by id.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   967
    get: function(obj) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   968
      if (obj == null) return void 0;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   969
      var id = this.modelId(this._isModel(obj) ? obj.attributes : obj);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   970
      return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   971
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   972
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   973
    // Get the model at the given index.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   974
    at: function(index) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   975
      if (index < 0) index += this.length;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   976
      return this.models[index];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   977
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   978
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   979
    // Return models with matching attributes. Useful for simple cases of
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   980
    // `filter`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   981
    where: function(attrs, first) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   982
      return this[first ? 'find' : 'filter'](attrs);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   983
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   984
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   985
    // Return the first model with matching attributes. Useful for simple cases
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   986
    // of `find`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   987
    findWhere: function(attrs) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   988
      return this.where(attrs, true);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   989
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   990
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   991
    // Force the collection to re-sort itself. You don't need to call this under
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   992
    // normal circumstances, as the set will maintain sort order as each item
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   993
    // is added.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   994
    sort: function(options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   995
      var comparator = this.comparator;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   996
      if (!comparator) throw new Error('Cannot sort a set without a comparator');
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   997
      options || (options = {});
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
   998
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
   999
      var length = comparator.length;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1000
      if (_.isFunction(comparator)) comparator = _.bind(comparator, this);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1001
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1002
      // Run sort based on type of `comparator`.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1003
      if (length === 1 || _.isString(comparator)) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1004
        this.models = this.sortBy(comparator);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1005
      } else {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1006
        this.models.sort(comparator);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1007
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1008
      if (!options.silent) this.trigger('sort', this, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1009
      return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1010
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1011
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1012
    // Pluck an attribute from each model in the collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1013
    pluck: function(attr) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1014
      return _.invoke(this.models, 'get', attr);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1015
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1016
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1017
    // Fetch the default set of models for this collection, resetting the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1018
    // collection when they arrive. If `reset: true` is passed, the response
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1019
    // data will be passed through the `reset` method instead of `set`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1020
    fetch: function(options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1021
      options = _.extend({parse: true}, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1022
      var success = options.success;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1023
      var collection = this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1024
      options.success = function(resp) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1025
        var method = options.reset ? 'reset' : 'set';
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1026
        collection[method](resp, options);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1027
        if (success) success.call(options.context, collection, resp, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1028
        collection.trigger('sync', collection, resp, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1029
      };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1030
      wrapError(this, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1031
      return this.sync('read', this, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1032
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1033
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1034
    // Create a new instance of a model in this collection. Add the model to the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1035
    // collection immediately, unless `wait: true` is passed, in which case we
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1036
    // wait for the server to agree.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1037
    create: function(model, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1038
      options = options ? _.clone(options) : {};
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1039
      var wait = options.wait;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1040
      model = this._prepareModel(model, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1041
      if (!model) return false;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1042
      if (!wait) this.add(model, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1043
      var collection = this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1044
      var success = options.success;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1045
      options.success = function(model, resp, callbackOpts) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1046
        if (wait) collection.add(model, callbackOpts);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1047
        if (success) success.call(callbackOpts.context, model, resp, callbackOpts);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1048
      };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1049
      model.save(null, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1050
      return model;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1051
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1052
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1053
    // **parse** converts a response into a list of models to be added to the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1054
    // collection. The default implementation is just to pass it through.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1055
    parse: function(resp, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1056
      return resp;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1057
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1058
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1059
    // Create a new collection with an identical list of models as this one.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1060
    clone: function() {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1061
      return new this.constructor(this.models, {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1062
        model: this.model,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1063
        comparator: this.comparator
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1064
      });
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1065
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1066
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1067
    // Define how to uniquely identify models in the collection.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1068
    modelId: function (attrs) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1069
      return attrs[this.model.prototype.idAttribute || 'id'];
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1070
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1071
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1072
    // Private method to reset all internal state. Called when the collection
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1073
    // is first initialized or reset.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1074
    _reset: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1075
      this.length = 0;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1076
      this.models = [];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1077
      this._byId  = {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1078
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1079
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1080
    // Prepare a hash of attributes (or other model) to be added to this
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1081
    // collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1082
    _prepareModel: function(attrs, options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1083
      if (this._isModel(attrs)) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1084
        if (!attrs.collection) attrs.collection = this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1085
        return attrs;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1086
      }
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1087
      options = options ? _.clone(options) : {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1088
      options.collection = this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1089
      var model = new this.model(attrs, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1090
      if (!model.validationError) return model;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1091
      this.trigger('invalid', this, model.validationError, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1092
      return false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1093
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1094
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1095
    // Internal method called by both remove and set.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1096
    _removeModels: function(models, options) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1097
      var removed = [];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1098
      for (var i = 0; i < models.length; i++) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1099
        var model = this.get(models[i]);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1100
        if (!model) continue;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1101
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1102
        var index = this.indexOf(model);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1103
        this.models.splice(index, 1);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1104
        this.length--;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1105
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1106
        if (!options.silent) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1107
          options.index = index;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1108
          model.trigger('remove', model, this, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1109
        }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1110
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1111
        removed.push(model);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1112
        this._removeReference(model, options);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1113
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1114
      return removed.length ? removed : false;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1115
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1116
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1117
    // Method for checking whether an object should be considered a model for
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1118
    // the purposes of adding to the collection.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1119
    _isModel: function (model) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1120
      return model instanceof Model;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1121
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1122
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1123
    // Internal method to create a model's ties to a collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1124
    _addReference: function(model, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1125
      this._byId[model.cid] = model;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1126
      var id = this.modelId(model.attributes);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1127
      if (id != null) this._byId[id] = model;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1128
      model.on('all', this._onModelEvent, this);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1129
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1130
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1131
    // Internal method to sever a model's ties to a collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1132
    _removeReference: function(model, options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1133
      delete this._byId[model.cid];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1134
      var id = this.modelId(model.attributes);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1135
      if (id != null) delete this._byId[id];
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1136
      if (this === model.collection) delete model.collection;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1137
      model.off('all', this._onModelEvent, this);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1138
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1139
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1140
    // Internal method called every time a model in the set fires an event.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1141
    // Sets need to update their indexes when models change ids. All other
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1142
    // events simply proxy through. "add" and "remove" events that originate
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1143
    // in other collections are ignored.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1144
    _onModelEvent: function(event, model, collection, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1145
      if ((event === 'add' || event === 'remove') && collection !== this) return;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1146
      if (event === 'destroy') this.remove(model, options);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1147
      if (event === 'change') {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1148
        var prevId = this.modelId(model.previousAttributes());
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1149
        var id = this.modelId(model.attributes);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1150
        if (prevId !== id) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1151
          if (prevId != null) delete this._byId[prevId];
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1152
          if (id != null) this._byId[id] = model;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1153
        }
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1154
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1155
      this.trigger.apply(this, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1156
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1157
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1158
  });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1159
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1160
  // Underscore methods that we want to implement on the Collection.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1161
  // 90% of the core usefulness of Backbone Collections is actually implemented
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1162
  // right here:
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1163
  var collectionMethods = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 4,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1164
      foldl: 4, inject: 4, reduceRight: 4, foldr: 4, find: 3, detect: 3, filter: 3,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1165
      select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1166
      contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1167
      head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1168
      without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1169
      isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1170
      sortBy: 3, indexBy: 3};
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1171
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1172
  // Mix in each Underscore method as a proxy to `Collection#models`.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1173
  addUnderscoreMethods(Collection, collectionMethods, 'models');
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1174
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1175
  // Backbone.View
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1176
  // -------------
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1177
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1178
  // Backbone Views are almost more convention than they are actual code. A View
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1179
  // is simply a JavaScript object that represents a logical chunk of UI in the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1180
  // DOM. This might be a single item, an entire list, a sidebar or panel, or
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1181
  // even the surrounding frame which wraps your whole app. Defining a chunk of
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1182
  // UI as a **View** allows you to define your DOM events declaratively, without
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1183
  // having to worry about render order ... and makes it easy for the view to
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1184
  // react to specific changes in the state of your models.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1185
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1186
  // Creating a Backbone.View creates its initial element outside of the DOM,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1187
  // if an existing element is not provided...
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1188
  var View = Backbone.View = function(options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1189
    this.cid = _.uniqueId('view');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1190
    _.extend(this, _.pick(options, viewOptions));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1191
    this._ensureElement();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1192
    this.initialize.apply(this, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1193
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1194
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1195
  // Cached regex to split keys for `delegate`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1196
  var delegateEventSplitter = /^(\S+)\s*(.*)$/;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1197
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1198
  // List of view options to be set as properties.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1199
  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1200
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1201
  // Set up all inheritable **Backbone.View** properties and methods.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1202
  _.extend(View.prototype, Events, {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1203
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1204
    // The default `tagName` of a View's element is `"div"`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1205
    tagName: 'div',
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1206
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1207
    // jQuery delegate for element lookup, scoped to DOM elements within the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1208
    // current view. This should be preferred to global lookups where possible.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1209
    $: function(selector) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1210
      return this.$el.find(selector);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1211
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1212
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1213
    // Initialize is an empty function by default. Override it with your own
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1214
    // initialization logic.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1215
    initialize: function(){},
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1216
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1217
    // **render** is the core function that your view should override, in order
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1218
    // to populate its element (`this.el`), with the appropriate HTML. The
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1219
    // convention is for **render** to always return `this`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1220
    render: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1221
      return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1222
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1223
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1224
    // Remove this view by taking the element out of the DOM, and removing any
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1225
    // applicable Backbone.Events listeners.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1226
    remove: function() {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1227
      this._removeElement();
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1228
      this.stopListening();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1229
      return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1230
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1231
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1232
    // Remove this view's element from the document and all event listeners
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1233
    // attached to it. Exposed for subclasses using an alternative DOM
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1234
    // manipulation API.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1235
    _removeElement: function() {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1236
      this.$el.remove();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1237
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1238
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1239
    // Change the view's element (`this.el` property) and re-delegate the
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1240
    // view's events on the new element.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1241
    setElement: function(element) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1242
      this.undelegateEvents();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1243
      this._setElement(element);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1244
      this.delegateEvents();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1245
      return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1246
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1247
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1248
    // Creates the `this.el` and `this.$el` references for this view using the
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1249
    // given `el`. `el` can be a CSS selector or an HTML string, a jQuery
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1250
    // context or an element. Subclasses can override this to utilize an
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1251
    // alternative DOM manipulation API and are only required to set the
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1252
    // `this.el` property.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1253
    _setElement: function(el) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1254
      this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1255
      this.el = this.$el[0];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1256
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1257
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1258
    // Set callbacks, where `this.events` is a hash of
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1259
    //
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1260
    // *{"event selector": "callback"}*
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1261
    //
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1262
    //     {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1263
    //       'mousedown .title':  'edit',
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1264
    //       'click .button':     'save',
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1265
    //       'click .open':       function(e) { ... }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1266
    //     }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1267
    //
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1268
    // pairs. Callbacks will be bound to the view, with `this` set properly.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1269
    // Uses event delegation for efficiency.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1270
    // Omitting the selector binds the event to `this.el`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1271
    delegateEvents: function(events) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1272
      events || (events = _.result(this, 'events'));
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1273
      if (!events) return this;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1274
      this.undelegateEvents();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1275
      for (var key in events) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1276
        var method = events[key];
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1277
        if (!_.isFunction(method)) method = this[method];
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1278
        if (!method) continue;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1279
        var match = key.match(delegateEventSplitter);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1280
        this.delegate(match[1], match[2], _.bind(method, this));
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1281
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1282
      return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1283
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1284
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1285
    // Add a single event listener to the view's element (or a child element
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1286
    // using `selector`). This only works for delegate-able events: not `focus`,
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1287
    // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1288
    delegate: function(eventName, selector, listener) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1289
      this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1290
      return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1291
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1292
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1293
    // Clears all callbacks previously bound to the view by `delegateEvents`.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1294
    // You usually don't need to use this, but may wish to if you have multiple
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1295
    // Backbone views attached to the same DOM element.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1296
    undelegateEvents: function() {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1297
      if (this.$el) this.$el.off('.delegateEvents' + this.cid);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1298
      return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1299
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1300
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1301
    // A finer-grained `undelegateEvents` for removing a single delegated event.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1302
    // `selector` and `listener` are both optional.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1303
    undelegate: function(eventName, selector, listener) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1304
      this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1305
      return this;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1306
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1307
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1308
    // Produces a DOM element to be assigned to your view. Exposed for
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1309
    // subclasses using an alternative DOM manipulation API.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1310
    _createElement: function(tagName) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1311
      return document.createElement(tagName);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1312
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1313
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1314
    // Ensure that the View has a DOM element to render into.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1315
    // If `this.el` is a string, pass it through `$()`, take the first
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1316
    // matching element, and re-assign it to `el`. Otherwise, create
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1317
    // an element from the `id`, `className` and `tagName` properties.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1318
    _ensureElement: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1319
      if (!this.el) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1320
        var attrs = _.extend({}, _.result(this, 'attributes'));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1321
        if (this.id) attrs.id = _.result(this, 'id');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1322
        if (this.className) attrs['class'] = _.result(this, 'className');
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1323
        this.setElement(this._createElement(_.result(this, 'tagName')));
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1324
        this._setAttributes(attrs);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1325
      } else {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1326
        this.setElement(_.result(this, 'el'));
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1327
      }
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1328
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1329
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1330
    // Set attributes from a hash on this view's element.  Exposed for
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1331
    // subclasses using an alternative DOM manipulation API.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1332
    _setAttributes: function(attributes) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1333
      this.$el.attr(attributes);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1334
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1335
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1336
  });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1337
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1338
  // Backbone.sync
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1339
  // -------------
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1340
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1341
  // Override this function to change the manner in which Backbone persists
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1342
  // models to the server. You will be passed the type of request, and the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1343
  // model in question. By default, makes a RESTful Ajax request
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1344
  // to the model's `url()`. Some possible customizations could be:
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1345
  //
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1346
  // * Use `setTimeout` to batch rapid-fire updates into a single request.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1347
  // * Send up the models as XML instead of JSON.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1348
  // * Persist models via WebSockets instead of Ajax.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1349
  //
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1350
  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1351
  // as `POST`, with a `_method` parameter containing the true HTTP method,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1352
  // as well as all requests with the body as `application/x-www-form-urlencoded`
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1353
  // instead of `application/json` with the model in a param named `model`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1354
  // Useful when interfacing with server-side languages like **PHP** that make
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1355
  // it difficult to read the body of `PUT` requests.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1356
  Backbone.sync = function(method, model, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1357
    var type = methodMap[method];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1358
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1359
    // Default options, unless specified.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1360
    _.defaults(options || (options = {}), {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1361
      emulateHTTP: Backbone.emulateHTTP,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1362
      emulateJSON: Backbone.emulateJSON
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1363
    });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1364
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1365
    // Default JSON-request options.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1366
    var params = {type: type, dataType: 'json'};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1367
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1368
    // Ensure that we have a URL.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1369
    if (!options.url) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1370
      params.url = _.result(model, 'url') || urlError();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1371
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1372
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1373
    // Ensure that we have the appropriate request data.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1374
    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1375
      params.contentType = 'application/json';
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1376
      params.data = JSON.stringify(options.attrs || model.toJSON(options));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1377
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1378
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1379
    // For older servers, emulate JSON by encoding the request into an HTML-form.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1380
    if (options.emulateJSON) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1381
      params.contentType = 'application/x-www-form-urlencoded';
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1382
      params.data = params.data ? {model: params.data} : {};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1383
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1384
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1385
    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1386
    // And an `X-HTTP-Method-Override` header.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1387
    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1388
      params.type = 'POST';
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1389
      if (options.emulateJSON) params.data._method = type;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1390
      var beforeSend = options.beforeSend;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1391
      options.beforeSend = function(xhr) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1392
        xhr.setRequestHeader('X-HTTP-Method-Override', type);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1393
        if (beforeSend) return beforeSend.apply(this, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1394
      };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1395
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1396
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1397
    // Don't process data on a non-GET request.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1398
    if (params.type !== 'GET' && !options.emulateJSON) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1399
      params.processData = false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1400
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1401
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1402
    // Pass along `textStatus` and `errorThrown` from jQuery.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1403
    var error = options.error;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1404
    options.error = function(xhr, textStatus, errorThrown) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1405
      options.textStatus = textStatus;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1406
      options.errorThrown = errorThrown;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1407
      if (error) error.call(options.context, xhr, textStatus, errorThrown);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1408
    };
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1409
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1410
    // Make the request, allowing the user to override any Ajax options.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1411
    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1412
    model.trigger('request', model, xhr, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1413
    return xhr;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1414
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1415
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1416
  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1417
  var methodMap = {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1418
    'create': 'POST',
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1419
    'update': 'PUT',
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1420
    'patch':  'PATCH',
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1421
    'delete': 'DELETE',
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1422
    'read':   'GET'
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1423
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1424
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1425
  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1426
  // Override this if you'd like to use a different library.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1427
  Backbone.ajax = function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1428
    return Backbone.$.ajax.apply(Backbone.$, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1429
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1430
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1431
  // Backbone.Router
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1432
  // ---------------
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1433
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1434
  // Routers map faux-URLs to actions, and fire events when routes are
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1435
  // matched. Creating a new one sets its `routes` hash, if not set statically.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1436
  var Router = Backbone.Router = function(options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1437
    options || (options = {});
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1438
    if (options.routes) this.routes = options.routes;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1439
    this._bindRoutes();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1440
    this.initialize.apply(this, arguments);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1441
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1443
  // Cached regular expressions for matching named param parts and splatted
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1444
  // parts of route strings.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1445
  var optionalParam = /\((.*?)\)/g;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1446
  var namedParam    = /(\(\?)?:\w+/g;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1447
  var splatParam    = /\*\w+/g;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1448
  var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1449
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1450
  // Set up all inheritable **Backbone.Router** properties and methods.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1451
  _.extend(Router.prototype, Events, {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1452
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1453
    // Initialize is an empty function by default. Override it with your own
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1454
    // initialization logic.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1455
    initialize: function(){},
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1456
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1457
    // Manually bind a single named route to a callback. For example:
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1458
    //
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1459
    //     this.route('search/:query/p:num', 'search', function(query, num) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1460
    //       ...
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1461
    //     });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1462
    //
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1463
    route: function(route, name, callback) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1464
      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1465
      if (_.isFunction(name)) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1466
        callback = name;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1467
        name = '';
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1468
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1469
      if (!callback) callback = this[name];
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1470
      var router = this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1471
      Backbone.history.route(route, function(fragment) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1472
        var args = router._extractParameters(route, fragment);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1473
        if (router.execute(callback, args, name) !== false) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1474
          router.trigger.apply(router, ['route:' + name].concat(args));
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1475
          router.trigger('route', name, args);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1476
          Backbone.history.trigger('route', router, name, args);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1477
        }
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1478
      });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1479
      return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1480
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1481
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1482
    // Execute a route handler with the provided parameters.  This is an
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1483
    // excellent place to do pre-route setup or post-route cleanup.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1484
    execute: function(callback, args, name) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1485
      if (callback) callback.apply(this, args);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1486
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1487
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1488
    // Simple proxy to `Backbone.history` to save a fragment into the history.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1489
    navigate: function(fragment, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1490
      Backbone.history.navigate(fragment, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1491
      return this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1492
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1493
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1494
    // Bind all defined routes to `Backbone.history`. We have to reverse the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1495
    // order of the routes here to support behavior where the most general
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1496
    // routes can be defined at the bottom of the route map.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1497
    _bindRoutes: function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1498
      if (!this.routes) return;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1499
      this.routes = _.result(this, 'routes');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1500
      var route, routes = _.keys(this.routes);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1501
      while ((route = routes.pop()) != null) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1502
        this.route(route, this.routes[route]);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1503
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1504
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1505
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1506
    // Convert a route string into a regular expression, suitable for matching
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1507
    // against the current location hash.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1508
    _routeToRegExp: function(route) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1509
      route = route.replace(escapeRegExp, '\\$&')
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1510
                   .replace(optionalParam, '(?:$1)?')
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1511
                   .replace(namedParam, function(match, optional) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1512
                     return optional ? match : '([^/?]+)';
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1513
                   })
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1514
                   .replace(splatParam, '([^?]*?)');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1515
      return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1516
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1517
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1518
    // Given a route, and a URL fragment that it matches, return the array of
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1519
    // extracted decoded parameters. Empty or unmatched parameters will be
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1520
    // treated as `null` to normalize cross-browser behavior.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1521
    _extractParameters: function(route, fragment) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1522
      var params = route.exec(fragment).slice(1);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1523
      return _.map(params, function(param, i) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1524
        // Don't decode the search params.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1525
        if (i === params.length - 1) return param || null;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1526
        return param ? decodeURIComponent(param) : null;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1527
      });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1528
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1529
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1530
  });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1531
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1532
  // Backbone.History
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1533
  // ----------------
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1534
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1535
  // Handles cross-browser history management, based on either
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1536
  // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1537
  // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1538
  // and URL fragments. If the browser supports neither (old IE, natch),
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1539
  // falls back to polling.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1540
  var History = Backbone.History = function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1541
    this.handlers = [];
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1542
    this.checkUrl = _.bind(this.checkUrl, this);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1543
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1544
    // Ensure that `History` can be used outside of the browser.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1545
    if (typeof window !== 'undefined') {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1546
      this.location = window.location;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1547
      this.history = window.history;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1548
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1549
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1550
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1551
  // Cached regex for stripping a leading hash/slash and trailing space.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1552
  var routeStripper = /^[#\/]|\s+$/g;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1553
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1554
  // Cached regex for stripping leading and trailing slashes.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1555
  var rootStripper = /^\/+|\/+$/g;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1556
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1557
  // Cached regex for stripping urls of hash.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1558
  var pathStripper = /#.*$/;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1559
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1560
  // Has the history handling already been started?
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1561
  History.started = false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1562
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1563
  // Set up all inheritable **Backbone.History** properties and methods.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1564
  _.extend(History.prototype, Events, {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1565
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1566
    // The default interval to poll for hash changes, if necessary, is
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1567
    // twenty times a second.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1568
    interval: 50,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1569
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1570
    // Are we at the app root?
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1571
    atRoot: function() {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1572
      var path = this.location.pathname.replace(/[^\/]$/, '$&/');
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1573
      return path === this.root && !this.getSearch();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1574
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1575
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1576
    // Does the pathname match the root?
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1577
    matchRoot: function() {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1578
      var path = this.decodeFragment(this.location.pathname);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1579
      var root = path.slice(0, this.root.length - 1) + '/';
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1580
      return root === this.root;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1581
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1582
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1583
    // Unicode characters in `location.pathname` are percent encoded so they're
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1584
    // decoded for comparison. `%25` should not be decoded since it may be part
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1585
    // of an encoded parameter.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1586
    decodeFragment: function(fragment) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1587
      return decodeURI(fragment.replace(/%25/g, '%2525'));
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1588
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1589
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1590
    // In IE6, the hash fragment and search params are incorrect if the
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1591
    // fragment contains `?`.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1592
    getSearch: function() {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1593
      var match = this.location.href.replace(/#.*/, '').match(/\?.+/);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1594
      return match ? match[0] : '';
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1595
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1596
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1597
    // Gets the true hash value. Cannot use location.hash directly due to bug
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1598
    // in Firefox where location.hash will always be decoded.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1599
    getHash: function(window) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1600
      var match = (window || this).location.href.match(/#(.*)$/);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1601
      return match ? match[1] : '';
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1602
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1603
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1604
    // Get the pathname and search params, without the root.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1605
    getPath: function() {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1606
      var path = this.decodeFragment(
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1607
        this.location.pathname + this.getSearch()
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1608
      ).slice(this.root.length - 1);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1609
      return path.charAt(0) === '/' ? path.slice(1) : path;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1610
    },
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1611
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1612
    // Get the cross-browser normalized URL fragment from the path or hash.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1613
    getFragment: function(fragment) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1614
      if (fragment == null) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1615
        if (this._usePushState || !this._wantsHashChange) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1616
          fragment = this.getPath();
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1617
        } else {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1618
          fragment = this.getHash();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1619
        }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1620
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1621
      return fragment.replace(routeStripper, '');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1622
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1623
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1624
    // Start the hash change handling, returning `true` if the current URL matches
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1625
    // an existing route, and `false` otherwise.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1626
    start: function(options) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1627
      if (History.started) throw new Error('Backbone.history has already been started');
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1628
      History.started = true;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1629
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1630
      // Figure out the initial configuration. Do we need an iframe?
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1631
      // Is pushState desired ... is it available?
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1632
      this.options          = _.extend({root: '/'}, this.options, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1633
      this.root             = this.options.root;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1634
      this._wantsHashChange = this.options.hashChange !== false;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1635
      this._hasHashChange   = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1636
      this._useHashChange   = this._wantsHashChange && this._hasHashChange;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1637
      this._wantsPushState  = !!this.options.pushState;
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1638
      this._hasPushState    = !!(this.history && this.history.pushState);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1639
      this._usePushState    = this._wantsPushState && this._hasPushState;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1640
      this.fragment         = this.getFragment();
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1641
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1642
      // Normalize root to always include a leading and trailing slash.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1643
      this.root = ('/' + this.root + '/').replace(rootStripper, '/');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1644
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1645
      // Transition from hashChange to pushState or vice versa if both are
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1646
      // requested.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1647
      if (this._wantsHashChange && this._wantsPushState) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1648
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1649
        // If we've started off with a route from a `pushState`-enabled
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1650
        // browser, but we're currently in a browser that doesn't support it...
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1651
        if (!this._hasPushState && !this.atRoot()) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1652
          var root = this.root.slice(0, -1) || '/';
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1653
          this.location.replace(root + '#' + this.getPath());
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1654
          // Return immediately as browser will do redirect to new url
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1655
          return true;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1656
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1657
        // Or if we've started out with a hash-based route, but we're currently
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1658
        // in a browser where it could be `pushState`-based instead...
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1659
        } else if (this._hasPushState && this.atRoot()) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1660
          this.navigate(this.getHash(), {replace: true});
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1661
        }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1662
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1663
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1664
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1665
      // Proxy an iframe to handle location events if the browser doesn't
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1666
      // support the `hashchange` event, HTML5 history, or the user wants
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1667
      // `hashChange` but not `pushState`.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1668
      if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1669
        this.iframe = document.createElement('iframe');
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1670
        this.iframe.src = 'javascript:0';
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1671
        this.iframe.style.display = 'none';
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1672
        this.iframe.tabIndex = -1;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1673
        var body = document.body;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1674
        // Using `appendChild` will throw on IE < 9 if the document is not ready.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1675
        var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1676
        iWindow.document.open();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1677
        iWindow.document.close();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1678
        iWindow.location.hash = '#' + this.fragment;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1679
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1680
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1681
      // Add a cross-platform `addEventListener` shim for older browsers.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1682
      var addEventListener = window.addEventListener || function (eventName, listener) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1683
        return attachEvent('on' + eventName, listener);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1684
      };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1685
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1686
      // Depending on whether we're using pushState or hashes, and whether
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1687
      // 'onhashchange' is supported, determine how we check the URL state.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1688
      if (this._usePushState) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1689
        addEventListener('popstate', this.checkUrl, false);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1690
      } else if (this._useHashChange && !this.iframe) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1691
        addEventListener('hashchange', this.checkUrl, false);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1692
      } else if (this._wantsHashChange) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1693
        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1694
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1695
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1696
      if (!this.options.silent) return this.loadUrl();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1697
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1698
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1699
    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1700
    // but possibly useful for unit testing Routers.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1701
    stop: function() {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1702
      // Add a cross-platform `removeEventListener` shim for older browsers.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1703
      var removeEventListener = window.removeEventListener || function (eventName, listener) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1704
        return detachEvent('on' + eventName, listener);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1705
      };
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1706
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1707
      // Remove window listeners.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1708
      if (this._usePushState) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1709
        removeEventListener('popstate', this.checkUrl, false);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1710
      } else if (this._useHashChange && !this.iframe) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1711
        removeEventListener('hashchange', this.checkUrl, false);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1712
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1713
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1714
      // Clean up the iframe if necessary.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1715
      if (this.iframe) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1716
        document.body.removeChild(this.iframe);
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1717
        this.iframe = null;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1718
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1719
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1720
      // Some environments will throw when clearing an undefined interval.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1721
      if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1722
      History.started = false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1723
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1724
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1725
    // Add a route to be tested when the fragment changes. Routes added later
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1726
    // may override previous routes.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1727
    route: function(route, callback) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1728
      this.handlers.unshift({route: route, callback: callback});
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1729
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1730
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1731
    // Checks the current URL to see if it has changed, and if it has,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1732
    // calls `loadUrl`, normalizing across the hidden iframe.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1733
    checkUrl: function(e) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1734
      var current = this.getFragment();
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1735
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1736
      // If the user pressed the back button, the iframe's hash will have
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1737
      // changed and we should use that for comparison.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1738
      if (current === this.fragment && this.iframe) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1739
        current = this.getHash(this.iframe.contentWindow);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1740
      }
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1741
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1742
      if (current === this.fragment) return false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1743
      if (this.iframe) this.navigate(current);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1744
      this.loadUrl();
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1745
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1746
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1747
    // Attempt to load the current URL fragment. If a route succeeds with a
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1748
    // match, returns `true`. If no defined routes matches the fragment,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1749
    // returns `false`.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1750
    loadUrl: function(fragment) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1751
      // If the root doesn't match, no routes can match either.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1752
      if (!this.matchRoot()) return false;
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1753
      fragment = this.fragment = this.getFragment(fragment);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1754
      return _.some(this.handlers, function(handler) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1755
        if (handler.route.test(fragment)) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1756
          handler.callback(fragment);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1757
          return true;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1758
        }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1759
      });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1760
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1761
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1762
    // Save a fragment into the hash history, or replace the URL state if the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1763
    // 'replace' option is passed. You are responsible for properly URL-encoding
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1764
    // the fragment in advance.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1765
    //
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1766
    // The options object can contain `trigger: true` if you wish to have the
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1767
    // route callback be fired (not usually desirable), or `replace: true`, if
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1768
    // you wish to modify the current URL without adding an entry to the history.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1769
    navigate: function(fragment, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1770
      if (!History.started) return false;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1771
      if (!options || options === true) options = {trigger: !!options};
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1772
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1773
      // Normalize the fragment.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1774
      fragment = this.getFragment(fragment || '');
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1775
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1776
      // Don't include a trailing slash on the root.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1777
      var root = this.root;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1778
      if (fragment === '' || fragment.charAt(0) === '?') {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1779
        root = root.slice(0, -1) || '/';
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1780
      }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1781
      var url = root + fragment;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1782
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1783
      // Strip the hash and decode for matching.
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1784
      fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1785
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1786
      if (this.fragment === fragment) return;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1787
      this.fragment = fragment;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1788
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1789
      // If pushState is available, we use it to set the fragment as a real URL.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1790
      if (this._usePushState) {
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1791
        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1792
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1793
      // If hash changes haven't been explicitly disabled, update the hash
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1794
      // fragment to store history.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1795
      } else if (this._wantsHashChange) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1796
        this._updateHash(this.location, fragment, options.replace);
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1797
        if (this.iframe && (fragment !== this.getHash(this.iframe.contentWindow))) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1798
          var iWindow = this.iframe.contentWindow;
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1799
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1800
          // Opening and closing the iframe tricks IE7 and earlier to push a
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1801
          // history entry on hash-tag change.  When replace is true, we don't
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1802
          // want this.
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1803
          if (!options.replace) {
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1804
            iWindow.document.open();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1805
            iWindow.document.close();
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1806
          }
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1807
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1808
          this._updateHash(iWindow.location, fragment, options.replace);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1809
        }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1810
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1811
      // If you've told us that you explicitly don't want fallback hashchange-
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1812
      // based history, then `navigate` becomes a page refresh.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1813
      } else {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1814
        return this.location.assign(url);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1815
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1816
      if (options.trigger) return this.loadUrl(fragment);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1817
    },
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1818
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1819
    // Update the hash location, either replacing the current entry, or adding
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1820
    // a new one to the browser history.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1821
    _updateHash: function(location, fragment, replace) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1822
      if (replace) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1823
        var href = location.href.replace(/(javascript:|#).*$/, '');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1824
        location.replace(href + '#' + fragment);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1825
      } else {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1826
        // Some browsers require that `hash` contains a leading #.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1827
        location.hash = '#' + fragment;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1828
      }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1829
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1830
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1831
  });
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1832
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1833
  // Create the default Backbone.history.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1834
  Backbone.history = new History;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1835
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1836
  // Helpers
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1837
  // -------
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1838
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1839
  // Helper function to correctly set up the prototype chain for subclasses.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1840
  // Similar to `goog.inherits`, but uses a hash of prototype properties and
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1841
  // class properties to be extended.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1842
  var extend = function(protoProps, staticProps) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1843
    var parent = this;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1844
    var child;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1845
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1846
    // The constructor function for the new subclass is either defined by you
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1847
    // (the "constructor" property in your `extend` definition), or defaulted
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1848
    // by us to simply call the parent constructor.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1849
    if (protoProps && _.has(protoProps, 'constructor')) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1850
      child = protoProps.constructor;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1851
    } else {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1852
      child = function(){ return parent.apply(this, arguments); };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1853
    }
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1854
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1855
    // Add static properties to the constructor function, if supplied.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1856
    _.extend(child, parent, staticProps);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1857
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1858
    // Set the prototype chain to inherit from `parent`, without calling
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1859
    // `parent` constructor function.
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1860
    var Surrogate = function(){ this.constructor = child; };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1861
    Surrogate.prototype = parent.prototype;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1862
    child.prototype = new Surrogate;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1863
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1864
    // Add prototype properties (instance properties) to the subclass,
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1865
    // if supplied.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1866
    if (protoProps) _.extend(child.prototype, protoProps);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1867
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1868
    // Set a convenience property in case the parent's prototype is needed
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1869
    // later.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1870
    child.__super__ = parent.prototype;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1871
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1872
    return child;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1873
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1874
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1875
  // Set up inheritance for the model, collection, router, view and history.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1876
  Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1877
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1878
  // Throw an error when a URL is needed, and none is supplied.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1879
  var urlError = function() {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1880
    throw new Error('A "url" property or function must be specified');
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1881
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1882
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1883
  // Wrap an optional error callback with a fallback error event.
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1884
  var wrapError = function(model, options) {
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1885
    var error = options.error;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1886
    options.error = function(resp) {
498
08d121184a38 upgrade libs
ymh <ymh.work@gmail.com>
parents: 442
diff changeset
  1887
      if (error) error.call(options.context, model, resp, options);
442
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1888
      model.trigger('error', model, resp, options);
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1889
    };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1890
  };
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1891
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1892
  return Backbone;
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1893
adb907bba956 add server php example
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1894
}));