<commit_before>    {
        id: 0,
        name: 'Atlantic Ocean Road, Norway',
        infoUrl: 'http://www.wikiwand.com/en/Atlantic_Ocean_Road',
        images: [
            {
                infoUrl: 'https://www.flickr.com/photos/kjelljoran/7667690396',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/0.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/yetdark/5956055552',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/1.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/karaian/3279172727',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/2.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/accidentdesigns/7728797602',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/3.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/kjelljoran/7667698842',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/4.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/yetdark/5956137390',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/5.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/kjelljoran/7667703714',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/6.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/kjelljoran/7667712140',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/7.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/rawmeyn/6266189106',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/8.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/rawmeyn/6266190948',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/9.jpg'
            }
        ]
    }
<commit_msg>#20 Fix image set info link<commit_after>    {
        id: 0,
        name: 'Atlantic Ocean Road, Norway',
        infoUrl: 'http://en.wikipedia.org/wiki/Atlantic_Ocean_Road',
        images: [
            {
                infoUrl: 'https://www.flickr.com/photos/kjelljoran/7667690396',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/0.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/yetdark/5956055552',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/1.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/karaian/3279172727',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/2.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/accidentdesigns/7728797602',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/3.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/kjelljoran/7667698842',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/4.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/yetdark/5956137390',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/5.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/kjelljoran/7667703714',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/6.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/kjelljoran/7667712140',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/7.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/rawmeyn/6266189106',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/8.jpg'
            },
            {
                infoUrl: 'https://www.flickr.com/photos/rawmeyn/6266190948',
                imageUrl: 'http://tabtrekker.parseapp.com/images/atlantic_ocean_road/9.jpg'
            }
        ]
    }
<|endoftext|>


<commit_before>/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
*

*       The System Object is static; all of its functions and properties are used directly from the object.
*

* @toc {System} System Event
* @featureID blackberry.system.event
* @BB50+
* @RIPPLE
* @namespace The System Event object allows you to get access to events triggered by system events on the BlackBerry device.
*/
blackberry.system.event = { };

/**
* Constant representing the back button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_BACK = 0;

/**
* Constant representing the menu button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_MENU = 1;

/**
* Constant representing the first convenience button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_CONVENIENCE_1 = 2;

/**
* Constant representing the second convenience button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_CONVENIENCE_2 = 3;

/**
* Constant representing the call button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_STARTCALL = 4;

/**
* Constant representing the end call button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_ENDCALL = 5;

/**
* Constant representing the volume down button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_VOLUMEDOWN = 6;

/**
* Constant representing the volume up button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_VOLUMEUP = 7;

/**
* @name blackberry.system.event.onHardwareKey
* @description Assigns a listener for the click of one of the hardware buttons on the device.
* @param {Number} key Hardware key to listen for.  A list of constants allowed for these keys is shown above.
* @callback {function} onSystemEvent Function to be called when the key is clicked - this function takes no parameters and no return value is required.  If you attempt to subscribe more than one callback function to a particular key, only the newest callback will be used when the key is pressed.  To remove the callback simply call the onHardwareKey with null as the callback parameter.
* @BB50+
* @function
* @example
* <script type="text/javascript">
*   function trapForBackKey() {
*     blackberry.system.event.onHardwareKey(blackberry.system.event.KEY_BACK, handleBack);
*   }
*
*   function handleBack() {
*     alert("handle back button");
*   }
* </script>
*/
blackberry.system.event.onHardwareKey = function(key,onSystemEvent) { };

/**
* @name blackberry.system.event.onCoverageChange
* @description Assigns a listener for when the coverage status changes.
* @callback {function} onSystemEvent Function to be called when coverage changes.  Only one function can be assigned to this event. To unregister the callback, call the onCoverageChange method and pass in null for the callback parameter.
* @BB50+
* @RIPPLE
* @function
*/
blackberry.system.event.onCoverageChange = function(onSystemEvent) { };

/**
 * @function
 * @description Assigns a listener for when the battery level changes.
 * Battery level is a percentage value. This API is currently designed where it will immediately announce the initial battery level, then it will announce any percentage change afterwards
 * @callback {function} onBatteryLevelChange Function to be called when the battery level changes. The level is passed as its only argument.
 * @callback {Number} onBatteryLevelChange.level battery level of the device ranging from 0 to 100
 * @PB10+
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *  function onBatteryLevelChange(level) { //This is just the callback function to be able to access the battery level. If you want it to alert you at a different interval, you just change this specific callback function to alert you at a different interval.
 *    alert("Battery Level: " + level);
 *  }
 *
 *  function notifyOnBatteryLevelChange(batteryLevelChangeCb) {
 *    blackberry.system.event.deviceBatteryLevelChange(batteryLevelChangeCb);
 *  }
 *
 *  notifyOnBatteryLevelChange(onBatteryLevelChange);
 * </script>
 */
blackberry.system.event.deviceBatteryLevelChange =  function(onBatteryLevelChange){};

/**
 * @function
 * @description Assigns a listener for when the battery state changes. When called, this API will immediately return the current battery state (whether it is charging or unplugged etc.) and will return the value when it reaches a new battery state.
 *

 * States are defined as the following:
 *
UNKNOWN		= 0;
 *
FULL		= 1;
 *
CHARGING 	= 2;
 *
UNPLUGGED	= 3;
 * @callback {function} onBatteryStateChange Function to be called when the battery charge state changes. The new state is passed as its only argument.
 * @callback {Number} onBatteryStateChange.state battery state of the device
 * @PB10+
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *  function foo(state) { //This is just the callback function to be able to access the battery state when there is a change.
 *    alert("Battery state: " + state);
 *  }
 *
 *  function notifyStateChange(someCallBackFunction) {
 *    blackberry.system.event.deviceBatteryStateChange(someCallBackFunction);
 *  }
 *
 *  notifyStateChange(foo);
 * </script>
  */
blackberry.system.event.deviceBatteryStateChange = function(onBatteryStateChange){};
<commit_msg>changed function name<commit_after>/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
*

*       The System Object is static; all of its functions and properties are used directly from the object.
*

* @toc {System} System Event
* @featureID blackberry.system.event
* @BB50+
* @RIPPLE
* @namespace The System Event object allows you to get access to events triggered by system events on the BlackBerry device.
*/
blackberry.system.event = { };

/**
* Constant representing the back button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_BACK = 0;

/**
* Constant representing the menu button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_MENU = 1;

/**
* Constant representing the first convenience button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_CONVENIENCE_1 = 2;

/**
* Constant representing the second convenience button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_CONVENIENCE_2 = 3;

/**
* Constant representing the call button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_STARTCALL = 4;

/**
* Constant representing the end call button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_ENDCALL = 5;

/**
* Constant representing the volume down button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_VOLUMEDOWN = 6;

/**
* Constant representing the volume up button.
* @type Number
* @constant
* @BB50+
* @RIPPLE
*/
blackberry.system.event.KEY_VOLUMEUP = 7;

/**
* @name blackberry.system.event.onHardwareKey
* @description Assigns a listener for the click of one of the hardware buttons on the device.
* @param {Number} key Hardware key to listen for.  A list of constants allowed for these keys is shown above.
* @callback {function} onSystemEvent Function to be called when the key is clicked - this function takes no parameters and no return value is required.  If you attempt to subscribe more than one callback function to a particular key, only the newest callback will be used when the key is pressed.  To remove the callback simply call the onHardwareKey with null as the callback parameter.
* @BB50+
* @function
* @example
* <script type="text/javascript">
*   function trapForBackKey() {
*     blackberry.system.event.onHardwareKey(blackberry.system.event.KEY_BACK, handleBack);
*   }
*
*   function handleBack() {
*     alert("handle back button");
*   }
* </script>
*/
blackberry.system.event.onHardwareKey = function(key,onSystemEvent) { };

/**
* @name blackberry.system.event.onCoverageChange
* @description Assigns a listener for when the coverage status changes.
* @callback {function} onSystemEvent Function to be called when coverage changes.  Only one function can be assigned to this event. To unregister the callback, call the onCoverageChange method and pass in null for the callback parameter.
* @BB50+
* @RIPPLE
* @function
*/
blackberry.system.event.onCoverageChange = function(onSystemEvent) { };

/**
 * @function
 * @description Assigns a listener for when the battery level changes.
 * Battery level is a percentage value. This API is currently designed where it will immediately announce the initial battery level, then it will announce any percentage change afterwards
 * @callback {function} onBatteryLevelChange Function to be called when the battery level changes. The level is passed as its only argument.
 * @callback {Number} onBatteryLevelChange.level battery level of the device ranging from 0 to 100
 * @PB10+
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *  function foobar(level) { //This is just the callback function to be able to access the battery level. If you want it to alert you at a different interval, you just change this specific callback function to alert you at a different interval.
 *    alert("Battery Level: " + level);
 *  }
 *
 *  function notifyOnBatteryLevelChange(callBackFunction) {
 *    blackberry.system.event.deviceBatteryLevelChange(callBackFunction);
 *  }
 *
 *  notifyOnBatteryLevelChange(foobar);
 * </script>
 */
blackberry.system.event.deviceBatteryLevelChange =  function(onBatteryLevelChange){};

/**
 * @function
 * @description Assigns a listener for when the battery state changes. When called, this API will immediately return the current battery state (whether it is charging or unplugged etc.) and will return the value when it reaches a new battery state.
 *

 * States are defined as the following:
 *
UNKNOWN		= 0;
 *
FULL		= 1;
 *
CHARGING 	= 2;
 *
UNPLUGGED	= 3;
 * @callback {function} onBatteryStateChange Function to be called when the battery charge state changes. The new state is passed as its only argument.
 * @callback {Number} onBatteryStateChange.state battery state of the device
 * @PB10+
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *  function foo(state) { //This is just the callback function to be able to access the battery state when there is a change.
 *    alert("Battery state: " + state);
 *  }
 *
 *  function notifyStateChange(callBackFunction) {
 *    blackberry.system.event.deviceBatteryStateChange(callBackFunction);
 *  }
 *
 *  notifyStateChange(foo);
 * </script>
  */
blackberry.system.event.deviceBatteryStateChange = function(onBatteryStateChange){};
<|endoftext|>


<commit_before>Travis.Build = Travis.Record.extend(Travis.Helpers.Urls, Travis.Helpers.Common, {
  repositoryId:   SC.Record.attr(Number, { key: 'repository_id' }),
  parentId:       SC.Record.attr(Number, { key: 'parent_id' }),
  config:         SC.Record.attr(Object),
  state:          SC.Record.attr(String),
  number:         SC.Record.attr(Number),
  commit:         SC.Record.attr(String),
  branch:         SC.Record.attr(String),
  message:        SC.Record.attr(String),
  result:         SC.Record.attr(Number, { key: 'status' }), // status is reserved by SC
  startedAt:      SC.Record.attr(String, { key: 'started_at' }), // use DateTime?
  finishedAt:     SC.Record.attr(String, { key: 'finished_at' }),
  committedAt:    SC.Record.attr(String, { key: 'committed_at' }),
  committerName:  SC.Record.attr(String, { key: 'committer_name' }),
  committerEmail: SC.Record.attr(String, { key: 'committer_email' }),
  authorName:     SC.Record.attr(String, { key: 'author_name' }),
  authorEmail:    SC.Record.attr(String, { key: 'author_email' }),
  compareUrl:     SC.Record.attr(String, { key: 'compare_url' }),
  log:            SC.Record.attr(String, { defaultValue: '' }),

  matrix: SC.Record.toMany('Travis.Build', { nested: true }), // TODO should be Travis.Test!

  parent: function() {
    //console.log('updating parent on build ' + this.get('id'));
    return this.get('parentId') ? Travis.Build.find(this.get('parentId')) : null;
  }.property('parentId', 'status').cacheable(),

  repository: function() {
    //console.log('updating repository on build ' + this.get('id'));
    return Travis.Repository.find(this.get('repositoryId'));
  }.property('repositoryId', 'status').cacheable(),

  build: function() {
    return this.get('matrix').objectAt(0);
  }.property('build', 'status').cacheable(),

  update: function(attrs) {
    if('status' in attrs) attrs.result = attrs.status
    if('matrix' in attrs) attrs.matrix = this._joinMatrixAttributes(attrs.matrix);
    this._super(attrs);
  },

  appendLog: function(log) {
    this.set('log', this.get('log') + log);
  },

  updateTimes: function() {
    this.notifyPropertyChange('startedAt');
    this.notifyPropertyChange('finishedAt');
  },

  isMatrix: function() {
    //console.log('updating isMatrix on build ' + this.get('id'));
    return this.getPath('matrix.length') > 1;
  }.property('matrix.status').cacheable(),

  color: function() {
    //console.log('updating color on build ' + this.get('id'));
    return this.colorForStatus(this.get('result'));
  }.property('status', 'result').cacheable(),

  duration: function() {
    //console.log('updating duration on build ' + this.get('id'));
    return this.durationFrom(this.get('startedAt'), this.get('finishedAt'));
  }.property('startedAt', 'finishedAt').cacheable(),

  configKeys: function() {
    return $.map($.keys($.only(this.get('config'), 'rvm', 'gemfile', 'env', 'otp_release')), function(key) { return $.camelize(key) });
  }.property('config').cacheable(),

  configValues: function() {
    return $.values($.only(this.get('config'), 'rvm', 'gemfile', 'env', 'otp_release'));
  }.property('config').cacheable(),

  // see https://github.com/sproutcore/sproutcore20/issues/160
  configKeyObjects: function() {
    //console.log('updating configKeyObjects on build ' + this.get('id'));
    return $.map(this.get('configKeys'), function(key) { return SC.Object.create({ key: key }) });
  }.property('config').cacheable(),

  configValueObjects: function() {
    //console.log('updating configValueObjects on build ' + this.get('id'));
    return $.map(this.get('configValues'), function(value) { return SC.Object.create({ value: value }) });
  }.property('config').cacheable(),

  // TODO the following display logic all seems to belong to a controller or helper module

  formattedCommit: function() {
    return (this.get('commit') || '').substr(0, 7) + (this.get('branch') ? ' (%@)'.fmt(this.get('branch')) : '');
  }.property('commit', 'branch').cacheable(),

  formattedDuration: function() {
    return this.readableTime(this.get('duration'));
  }.property('status', 'duration').cacheable(),

  formattedFinishedAt: function() {
    return this.timeAgoInWords(this.get('finishedAt')) || '-';
  }.property('status', 'finishedAt').cacheable(),

  formattedConfig: function() {
    if(this.get('isMatrix')) return;
    var config = $.only(this.get('config'), 'rvm', 'gemfile', 'env');
    var values = $.map(config, function(value, key) { return '%@: %@'.fmt($.camelize(key), value.join ? value.join(', ') : value); });
    return values.length == 0 ? '-' : values.join(', ');
  }.property('config').cacheable(),

  formattedLog: function() {
    var log = this.get('parentId') ? this.get('log') : this.getPath('matrix.firstObject.log');
    return log ? Travis.Log.filter(log) : '';
  }.property('matrix', 'log').cacheable(),

  formattedCompareUrl: function() {
    var parts = (this.get('compare_url') || '').split('/');
    return parts[parts.length - 1];
  }.property('compareUrl').cacheable(),

  // need to join given attributes with existing attributes because SC.Record.toMany
  // does not seem to allow partial updates, i.e. would remove existing attributes?
  _joinMatrixAttributes: function(attrs) {
    var _this = this;
    return $.each(attrs, function(ix, build) {
      if(build.status) build.result = build.status;
      attrs[ix] = $.extend(_this.get('matrix').objectAt(ix).get('attributes') || {}, build);
    });
  }
});

Travis.Build.reopenClass({
  resource: 'builds',

  byRepositoryId: function(id, parameters) {
    return this.all({ url: '/repositories/%@/builds.json?parent_id='.fmt(id), repositoryId: id, parentId: null, orderBy: 'number DESC' })
  },
});
<commit_msg>tweak caching properties<commit_after>Travis.Build = Travis.Record.extend(Travis.Helpers.Urls, Travis.Helpers.Common, {
  repositoryId:   SC.Record.attr(Number, { key: 'repository_id' }),
  parentId:       SC.Record.attr(Number, { key: 'parent_id' }),
  config:         SC.Record.attr(Object),
  state:          SC.Record.attr(String),
  number:         SC.Record.attr(Number),
  commit:         SC.Record.attr(String),
  branch:         SC.Record.attr(String),
  message:        SC.Record.attr(String),
  result:         SC.Record.attr(Number, { key: 'status' }), // status is reserved by SC
  startedAt:      SC.Record.attr(String, { key: 'started_at' }), // use DateTime?
  finishedAt:     SC.Record.attr(String, { key: 'finished_at' }),
  committedAt:    SC.Record.attr(String, { key: 'committed_at' }),
  committerName:  SC.Record.attr(String, { key: 'committer_name' }),
  committerEmail: SC.Record.attr(String, { key: 'committer_email' }),
  authorName:     SC.Record.attr(String, { key: 'author_name' }),
  authorEmail:    SC.Record.attr(String, { key: 'author_email' }),
  compareUrl:     SC.Record.attr(String, { key: 'compare_url' }),
  log:            SC.Record.attr(String, { defaultValue: '' }),

  matrix: SC.Record.toMany('Travis.Build', { nested: true }), // TODO should be Travis.Test!

  parent: function() {
    //console.log('updating parent on build ' + this.get('id'));
    return this.get('parentId') ? Travis.Build.find(this.get('parentId')) : null;
  }.property('parentId', 'status').cacheable(),

  repository: function() {
    //console.log('updating repository on build ' + this.get('id'));
    return Travis.Repository.find(this.get('repositoryId'));
  }.property('repositoryId', 'status').cacheable(),

  build: function() {
    return this.get('matrix').objectAt(0);
  }.property('build', 'status').cacheable(),

  update: function(attrs) {
    if('status' in attrs) attrs.result = attrs.status
    if('matrix' in attrs) attrs.matrix = this._joinMatrixAttributes(attrs.matrix);
    this._super(attrs);
  },

  appendLog: function(log) {
    this.set('log', this.get('log') + log);
  },

  updateTimes: function() {
    this.notifyPropertyChange('startedAt');
    this.notifyPropertyChange('finishedAt');
  },

  isMatrix: function() {
    //console.log('updating isMatrix on build ' + this.get('id'));
    return this.getPath('matrix.length') > 1;
  }.property('matrix.status').cacheable(),

  color: function() {
    //console.log('updating color on build ' + this.get('id'));
    return this.colorForStatus(this.get('result'));
  }.property('status', 'result').cacheable(),

  duration: function() {
    //console.log('updating duration on build ' + this.get('id'));
    return this.durationFrom(this.get('startedAt'), this.get('finishedAt'));
  }.property('startedAt', 'finishedAt').cacheable(),

  configKeys: function() {
    return $.map($.keys($.only(this.get('config'), 'rvm', 'gemfile', 'env', 'otp_release')), function(key) { return $.camelize(key) });
  }.property('config').cacheable(),

  configValues: function() {
    return $.values($.only(this.get('config'), 'rvm', 'gemfile', 'env', 'otp_release'));
  }.property('config').cacheable(),

  // see https://github.com/sproutcore/sproutcore20/issues/160
  configKeyObjects: function() {
    //console.log('updating configKeyObjects on build ' + this.get('id'));
    return $.map(this.get('configKeys'), function(key) { return SC.Object.create({ key: key }) });
  }.property('config').cacheable(),

  configValueObjects: function() {
    //console.log('updating configValueObjects on build ' + this.get('id'));
    return $.map(this.get('configValues'), function(value) { return SC.Object.create({ value: value }) });
  }.property('config').cacheable(),

  // TODO the following display logic all seems to belong to a controller or helper module

  formattedCommit: function() {
    return (this.get('commit') || '').substr(0, 7) + (this.get('branch') ? ' (%@)'.fmt(this.get('branch')) : '');
  }.property('commit', 'branch').cacheable(),

  formattedDuration: function() {
    return this.readableTime(this.get('duration'));
  }.property('status', 'duration').cacheable(),

  formattedFinishedAt: function() {
    return this.timeAgoInWords(this.get('finishedAt')) || '-';
  }.property('status', 'finishedAt').cacheable(),

  formattedConfig: function() {
    if(this.get('isMatrix')) return;
    var config = $.only(this.get('config'), 'rvm', 'gemfile', 'env');
    var values = $.map(config, function(value, key) { return '%@: %@'.fmt($.camelize(key), value.join ? value.join(', ') : value); });
    return values.length == 0 ? '-' : values.join(', ');
  }.property('config').cacheable(),

  formattedLog: function() {
    var log = this.get('parentId') ? this.get('log') : this.getPath('matrix.firstObject.log');
    return log ? Travis.Log.filter(log) : '';
  }.property('parentId', 'log', 'matrix.firstObject.log').cacheable(),

  formattedCompareUrl: function() {
    var parts = (this.get('compare_url') || '').split('/');
    return parts[parts.length - 1];
  }.property('compareUrl').cacheable(),

  // need to join given attributes with existing attributes because SC.Record.toMany
  // does not seem to allow partial updates, i.e. would remove existing attributes?
  _joinMatrixAttributes: function(attrs) {
    var _this = this;
    return $.each(attrs, function(ix, build) {
      if(build.status) build.result = build.status;
      attrs[ix] = $.extend(_this.get('matrix').objectAt(ix).get('attributes') || {}, build);
    });
  }
});

Travis.Build.reopenClass({
  resource: 'builds',

  byRepositoryId: function(id, parameters) {
    return this.all({ url: '/repositories/%@/builds.json?parent_id='.fmt(id), repositoryId: id, parentId: null, orderBy: 'number DESC' })
  },
});
<|endoftext|>


<commit_before>define([
    'jquery'
], function($) {
    'use strict';

    // ==============
    // = IE helpers =
    // ==============
    $.fn.disableSelection = function() {
        return this.each(function() {
            // this.onselectstart = function() { return false; };
            this.unselectable = "on";
            $(this).addClass('disableSelection');
        });
    };
    $.fn.iefocus = function() {
        if($.browser.ltie10) {
            this.each(function() {
                $(this).on('mousedown', function(e) {
                    window.setTimeout(_.bind(function() {
                        this.focus();
                    }, this), 1);
                    this.focus();
                    // e.stopPropagation();
                });
                if($.browser.ltie8) {
                    this.hideFocus = true;
                    $(this).bind('focus', function(e) { $(e.target).addClass('focus'); });
                    $(this).bind('blur', function(e) { $(e.target).removeClass('focus'); });
                }
            });
        }
        return this;
    };

    // =====================
    // = Browser detection =
    // =====================
    /* Put back $.browser which was dropped in jQuery 1.9 */
    $.uaMatch = function( ua ) {
     ua = ua.toLowerCase();

     var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
         /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
         /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
         /(msie) ([\w.]+)/.exec( ua ) ||
         ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
         [];

     return {
         browser: match[ 1 ] || "",
         version: match[ 2 ] || "0"
     };
    };

    // Don't clobber any existing $.browser in case it's different
    if ( !$.browser ) {
        var matched = $.uaMatch( navigator.userAgent );
        var browser = {};

        if ( matched.browser ) {
            browser[ matched.browser ] = true;
            browser.version = matched.version;
        }

        // Chrome is Webkit, but Webkit is also Safari.
        if ( browser.chrome ) {
            browser.webkit = true;
        } else if ( browser.webkit ) {
            browser.safari = true;
        }

        $.browser = browser;
    }
    $.browser.ltie8 = $.browser.msie && parseInt($.browser.version, 10) < 8;
    $.browser.ltie9 = $.browser.msie && parseInt($.browser.version, 10) < 9;
    $.browser.ltie10 = $.browser.msie && parseInt($.browser.version, 10) < 10;

    /* Normalize mouse wheel through a hand-crafted "wheel" event */
    (function () {
        var oldEvents = ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
            allEvents =  ['wheel'].concat(oldEvents),
            hasWheel = "onwheel" in document.createElement("div"),
            bindEvents = hasWheel ? ['wheel'] : oldEvents;

        function handler(e) {
            var orgEv = e || window.event;
            e = $.event.fix(orgEv);
            e.type = "wheel";
            e.deltaMode = orgEv.type == "MozMousePixelScroll" ? 0 : 1;

            if(hasWheel) { // Moz
                e.deltaX = orgEv.deltaX;
                e.deltaY = orgEv.deltaY;
                // Speed up if not inertial scroll
                var s = e.deltaX+''+e.deltaY;
                if(s.indexOf('.') !== -1) {
                    e.deltaX *= 10;
                    e.deltaY *= 10;
                }
            }
            else {
                e.deltaY = - 1/4 * orgEv.wheelDelta; // IE + webkit
                e.deltaX = orgEv.wheelDeltaX ? - 1/40 * orgEv.wheelDeltaX : 0; // webkit
            }
            return ($.event.dispatch || $.event.handle).call(this, e);
        }

        if($.event.fixHooks)
            for(var i=0, name; name = allEvents[i]; i++)
                $.event.fixHooks[name] = $.event.mouseHooks;

        $.event.special.wheel = {
            setup: function() {
                if(this.addEventListener)
                    for(var i=0,name; name=bindEvents[i]; i++)
                        this.addEventListener(name, handler, false);
                else
                    this.onmousewheel = handler;
            },
            teardown: function() {
                if(this.addEventListener)
                    for(var i=0,name; name=bindEvents[i]; i++)
                        this.addEventListener(name, handler, false);
                else
                    this.onmousewheel = handler;
            }
        };

    })();

    $.fn.getPreText = function (trim) {
        var ce = this.clone();
        if($.browser.webkit || $.browser.chrome)
            ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
        else if($.browser.msie)
            ce.find("p").replaceWith(function() { return "\n" + this.innerHTML; });
        else {
            ce.find("br").replaceWith("\n");
        }

        if(trim) {
            var lines = ce.text().split('\n');
            lines = _.compact(_.map(lines, function(line) {
                return $.trim(line);
            }));
            return lines.join('\n');
        }
        else
            return ce.text();

    };

    $.fn.getOffsetPadding = function() {
        var el = this[0],
            x = 0,
            y = 0;
        do {
            el = $(el);
            x += el.outerWidth(true) - el.width();
            y += el.outerHeight(true) - el.height();
        }
        while(el = el[0].offsetParent);
        return {x: x, y: y};
    };

    $.fn.reverse = [].reverse;

    $.fn.contains = function(childEl) {
        return $(childEl).containedBy(this);
    };
    $.fn.screen = function() {
        var pos = this.offset(),
            body = this[0].ownerDocument.body,
            top = pos.top - body.scrollTop,
            left = pos.left - body.scrollLeft;
        return {left: left, top: top};
    };
    $.fn.ieunselectable = function() {
        this.each(function() {
            if($.browser.ltie10)
                $(this).find('*').each(function() { this.unselectable = "on"; });
        });
        return this;
    };
    $.fn.blink = function(callback) {
        this.each(function() {
            var count = 0,
                el = this;
            $(el).toggleClass('selected');
            var timer = window.setInterval(function() {
                $(el).toggleClass('selected', (count+1) % 2 === 0);
                count++;
                if(count == 3) {
                    window.clearInterval(timer);
                    $(el).toggleClass('selected', true)
                    callback();
                }
            }, 60);
        });
    };
    $.fn.selectAll = function() {
        this.each(function() {
            var sel, range;
            if (window.getSelection && document.createRange) {
                sel = window.getSelection();
                range = document.createRange();
                range.selectNodeContents(this);
                sel.removeAllRanges();
                sel.addRange(range);
            } else if (document.body.createTextRange) {
                range = document.body.createTextRange();
                range.moveToElementText(this);
                range.select();
            }
        });
    };
    $.fn.moveCursorToEnd = function(el) {
        this.each(function() {
            var range;
            if(document.selection) {
                range = document.body.createTextRange();
                range.moveToElementText(this);
                range.collapse(false);
                range.select();
            }
            else {
                range = document.createRange();
                range.selectNodeContents(this);
                range.collapse(false); // collapse to end
                var sel = window.getSelection();
                sel.removeAllRanges();
                sel.addRange(range);
            }
        });
        return this;
    };

    $.fn.insertAt = function(index, element) {
        var lastIndex = this.children().size();
        if(index < 0) {
            index = Math.max(0, lastIndex + 1 + index);
        }
        this.append(element);
        if(index < lastIndex) {
            this.children().eq(index).before(this.children().last());
        }
        return this;
    };

    $.fn.make = function(className) {
        this.each(function() {
            $(this).parent().children('.'+className).removeClass(className);
            $(this).addClass(className);
        });
        return this;
    };

    $.fn.containedBy = function(parent) {
        parent = $(parent)[0];
        var isContainedBy = false;

        this.parents().each(function(i, par) {
            if(par === parent) {
                isContainedBy = true;
                return false; // break
            }
        });
        return isContainedBy;
    };

    var get_center = function(width, height) {
        var winHeight = $(window).height();
        var winWidth = $(window).width();
        var top = ((winHeight - height) / 2) + $(window).scrollTop();
        var left = ((winWidth - width) / 2) + $(window).scrollLeft();
        return [left, top];
    };
    $.fn.center = function(args) {
        args = $.extend({
            // defaults
            top: null  // center horizontally, manually specify top
        }, args || {});

        this.each(function() {
            var self = $(this),
                coords = get_center(self.outerWidth(), self.outerHeight()),
                left = coords[0], top = coords[1];

            if(args.top !== null) {
                top = args.top;
            }
            self.css({top: top, left: left});
       });
    };

    $.fn.getAllAttributes = function() {
        var el = this[0];
        var attributes = {};
        if($.browser.ltie9) {
            // Todo: Temp, stupid ie
            var attrs = el.attributes,
                names = ['name', 'factory', 'class', 'style', 'value', 'disabled'];
            for(var i=0; i<names.length; i++) {
                if(attrs[names[i]])
                    attributes[names[i]] = attrs[names[i]].nodeValue;
            }
        } else {
            // w3c NamedNodeMap
            $.each(el.attributes, function(index, attr) {
                attributes[attr.name] = attr.value;
            });
        }
        return attributes;
    };
    $.fn.attrs = function(attrs) {
        if(arguments.length === 0) {
            return $(this).getAllAttributes();
        }
        $.each(attrs || {}, function(key, val) {
            $(this).attr(key, val);
        }, this);
        return this;
    };

    $.fn.focusWithoutScrolling = function(){
        var x = window.scrollX,
            y = window.scrollY;
        this.focus();
        window.scrollTo(x, y);
    };

    $.fn.scrollMeOnly = function() {
        this.on('wheel', function(e) {
            e.preventDefault();
            e.currentTarget.scrollTop += e.deltaY;
        });
        return this;
    };

    $.fn.scrollIntoView = function(alignWithTop, scrollable) {
        var el = scrollable || this.offsetParent,
            item = this[0],
            scrollTop = el.scrollTop;
        if(!item)
            return;

        if(alignWithTop) {
            if(item.offsetTop < scrollTop)
                el.scrollTop = item.offsetTop;
        }
        else {
            var height = $(this).outerHeight();
            if(item.offsetTop + height > el.clientHeight + scrollTop)
                el.scrollTop = item.offsetTop - el.clientHeight + height;
        }
    };

    $.fn.box = function() {
        return {
            left: $(this).offset().left,
            top: $(this).offset().top,
            width: $(this).outerWidth(),
            height: $(this).outerHeight()
        };
    };

    $.fn.fadeOutFast = function(options) {
        options = options || {};
        this.each(function(i, el) {
            var method = options.detach ? 'detach':'remove';
            if($.browser.ltie9)
                $(el)[method]();
            else
                $(el).fadeOut('fast', function() {
                    $(el)[method]().css({opacity: 1, display: 'block'});
                });
        });
    };

    function tabChainTabKeyDown(e) {
        if(e.altKey || e.ctrlKey || e.metaKey)
            return;
        var set = $(e.currentTarget).find('*:tabable'),
            index = set.index(e.target),
            next = set[index + (e.shiftKey ? -1 : 1)];
        (next || set[e.shiftKey ? set.length-1 : 0]).focus();
        e.preventDefault();
    }

    $.fn.tabChain = function(options) {
        this.each(function() {
            $(this).on('keydown', null, 'tab', tabChainTabKeyDown);
        });
    };

    $.fn.reverse = [].reverse;

    // ==============================
    // = jQuery selector extensions =
    // ==============================
    // From jQuery UI 1.9.1
    function visible( element ) {
        return $.expr.filters.visible( element ) &&
            !$( element ).parents().andSelf().filter(function() {
                return $.css( this, "visibility" ) === "hidden";
            }).length;
    }
    function focusable( element, isTabIndexNotNaN ) {
        var map, mapName, img,
            nodeName = element.nodeName.toLowerCase();
        if ( "area" === nodeName ) {
            map = element.parentNode;
            mapName = map.name;
            if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
                return false;
            }
            img = $( "img[usemap=#" + mapName + "]" )[0];
            return !!img && visible( img );
        }
        return ( /input|select|textarea|button|object/.test( nodeName ) ?
            !element.disabled :
            "a" === nodeName ?
                element.href || isTabIndexNotNaN :
                isTabIndexNotNaN) &&
            // the element and all of its ancestors must be visible
            visible( element );
    }

    // Mark a function for use in filtering
    var markFunction = function(fn) {
        fn.sizzleFilter = true;
        return fn;
    };
    $.extend($.expr[':'], {
        selectable: function(el) {
            // visible and not disabled
            return $(el).is(':visible') && !$(el).is('.disabled');
        },
        floating: function(el) {
            // absolute or fixed positioned
            var pos = el.style.position.toLowerCase();
            var pos2 = $(el).css('position');
            return  pos2 == 'absolute' || pos2 == 'fixed';
        },
        containsre: markFunction(function(text, context, xml) {
            return function(el) {
                var re = text.replace(/^\/+|\/+$/, '').split('/'); // strip slashes, then split
                return new RegExp(re[0], re[1]).test($(el).text());
            };
        }),
        tabable: function(el) {
            return el.tabIndex !== -1 && $(el).closest('.disabled').length === 0;
        },
        inviewport: function(el) {
            var scrollTop = $(window).scrollTop(),
                elTop = $(el).offset().top,
                height = $(window).height();

            return (elTop > scrollTop) && (elTop < scrollTop+height);
        },
        inside: markFunction(function(selector, context, xml) {
            return function(el) {
                return $(el).closest(selector).length;
            };
        }),
        focusable: function(el) {
            return focusable(el, !isNaN($.attr(el, "tabindex")));
        },
        scrollable: function(el) {
            var $el = $(el),
                scroll = {'scroll': true, 'auto': true},
                of = $el.css('overflow') in scroll,
                ofX = $el.css('overflow-x') in scroll,
                ofY = $el.css('overflow-y') in scroll;

            // HTML can scroll with overflow:visible
            if(el.tagName == 'HTML') {
                of = $el.css('overflow') != 'hidden';
                ofX = $el.css('overflow-x') != 'hidden';
                ofY = $el.css('overflow-y') != 'hidden';
            }
            if(!of && !ofX && !ofY)
                return false;
            return (el.clientHeight < el.scrollHeight && (of || ofY)) || (el.clientWidth < el.scrollWidth && (of || ofX));
        }
    });

});

<commit_msg>$.fn.scrollIntoView should use el.parentNode if no container has been given.<commit_after>define([
    'jquery'
], function($) {
    'use strict';

    // ==============
    // = IE helpers =
    // ==============
    $.fn.disableSelection = function() {
        return this.each(function() {
            // this.onselectstart = function() { return false; };
            this.unselectable = "on";
            $(this).addClass('disableSelection');
        });
    };
    $.fn.iefocus = function() {
        if($.browser.ltie10) {
            this.each(function() {
                $(this).on('mousedown', function(e) {
                    window.setTimeout(_.bind(function() {
                        this.focus();
                    }, this), 1);
                    this.focus();
                    // e.stopPropagation();
                });
                if($.browser.ltie8) {
                    this.hideFocus = true;
                    $(this).bind('focus', function(e) { $(e.target).addClass('focus'); });
                    $(this).bind('blur', function(e) { $(e.target).removeClass('focus'); });
                }
            });
        }
        return this;
    };

    // =====================
    // = Browser detection =
    // =====================
    /* Put back $.browser which was dropped in jQuery 1.9 */
    $.uaMatch = function( ua ) {
     ua = ua.toLowerCase();

     var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
         /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
         /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
         /(msie) ([\w.]+)/.exec( ua ) ||
         ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
         [];

     return {
         browser: match[ 1 ] || "",
         version: match[ 2 ] || "0"
     };
    };

    // Don't clobber any existing $.browser in case it's different
    if ( !$.browser ) {
        var matched = $.uaMatch( navigator.userAgent );
        var browser = {};

        if ( matched.browser ) {
            browser[ matched.browser ] = true;
            browser.version = matched.version;
        }

        // Chrome is Webkit, but Webkit is also Safari.
        if ( browser.chrome ) {
            browser.webkit = true;
        } else if ( browser.webkit ) {
            browser.safari = true;
        }

        $.browser = browser;
    }
    $.browser.ltie8 = $.browser.msie && parseInt($.browser.version, 10) < 8;
    $.browser.ltie9 = $.browser.msie && parseInt($.browser.version, 10) < 9;
    $.browser.ltie10 = $.browser.msie && parseInt($.browser.version, 10) < 10;

    /* Normalize mouse wheel through a hand-crafted "wheel" event */
    (function () {
        var oldEvents = ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
            allEvents =  ['wheel'].concat(oldEvents),
            hasWheel = "onwheel" in document.createElement("div"),
            bindEvents = hasWheel ? ['wheel'] : oldEvents;

        function handler(e) {
            var orgEv = e || window.event;
            e = $.event.fix(orgEv);
            e.type = "wheel";
            e.deltaMode = orgEv.type == "MozMousePixelScroll" ? 0 : 1;

            if(hasWheel) { // Moz
                e.deltaX = orgEv.deltaX;
                e.deltaY = orgEv.deltaY;
                // Speed up if not inertial scroll
                var s = e.deltaX+''+e.deltaY;
                if(s.indexOf('.') !== -1) {
                    e.deltaX *= 10;
                    e.deltaY *= 10;
                }
            }
            else {
                e.deltaY = - 1/4 * orgEv.wheelDelta; // IE + webkit
                e.deltaX = orgEv.wheelDeltaX ? - 1/40 * orgEv.wheelDeltaX : 0; // webkit
            }
            return ($.event.dispatch || $.event.handle).call(this, e);
        }

        if($.event.fixHooks)
            for(var i=0, name; name = allEvents[i]; i++)
                $.event.fixHooks[name] = $.event.mouseHooks;

        $.event.special.wheel = {
            setup: function() {
                if(this.addEventListener)
                    for(var i=0,name; name=bindEvents[i]; i++)
                        this.addEventListener(name, handler, false);
                else
                    this.onmousewheel = handler;
            },
            teardown: function() {
                if(this.addEventListener)
                    for(var i=0,name; name=bindEvents[i]; i++)
                        this.addEventListener(name, handler, false);
                else
                    this.onmousewheel = handler;
            }
        };

    })();

    $.fn.getPreText = function (trim) {
        var ce = this.clone();
        if($.browser.webkit || $.browser.chrome)
            ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
        else if($.browser.msie)
            ce.find("p").replaceWith(function() { return "\n" + this.innerHTML; });
        else {
            ce.find("br").replaceWith("\n");
        }

        if(trim) {
            var lines = ce.text().split('\n');
            lines = _.compact(_.map(lines, function(line) {
                return $.trim(line);
            }));
            return lines.join('\n');
        }
        else
            return ce.text();

    };

    $.fn.getOffsetPadding = function() {
        var el = this[0],
            x = 0,
            y = 0;
        do {
            el = $(el);
            x += el.outerWidth(true) - el.width();
            y += el.outerHeight(true) - el.height();
        }
        while(el = el[0].offsetParent);
        return {x: x, y: y};
    };

    $.fn.reverse = [].reverse;

    $.fn.contains = function(childEl) {
        return $(childEl).containedBy(this);
    };
    $.fn.screen = function() {
        var pos = this.offset(),
            body = this[0].ownerDocument.body,
            top = pos.top - body.scrollTop,
            left = pos.left - body.scrollLeft;
        return {left: left, top: top};
    };
    $.fn.ieunselectable = function() {
        this.each(function() {
            if($.browser.ltie10)
                $(this).find('*').each(function() { this.unselectable = "on"; });
        });
        return this;
    };
    $.fn.blink = function(callback) {
        this.each(function() {
            var count = 0,
                el = this;
            $(el).toggleClass('selected');
            var timer = window.setInterval(function() {
                $(el).toggleClass('selected', (count+1) % 2 === 0);
                count++;
                if(count == 3) {
                    window.clearInterval(timer);
                    $(el).toggleClass('selected', true)
                    callback();
                }
            }, 60);
        });
    };
    $.fn.selectAll = function() {
        this.each(function() {
            var sel, range;
            if (window.getSelection && document.createRange) {
                sel = window.getSelection();
                range = document.createRange();
                range.selectNodeContents(this);
                sel.removeAllRanges();
                sel.addRange(range);
            } else if (document.body.createTextRange) {
                range = document.body.createTextRange();
                range.moveToElementText(this);
                range.select();
            }
        });
    };
    $.fn.moveCursorToEnd = function(el) {
        this.each(function() {
            var range;
            if(document.selection) {
                range = document.body.createTextRange();
                range.moveToElementText(this);
                range.collapse(false);
                range.select();
            }
            else {
                range = document.createRange();
                range.selectNodeContents(this);
                range.collapse(false); // collapse to end
                var sel = window.getSelection();
                sel.removeAllRanges();
                sel.addRange(range);
            }
        });
        return this;
    };

    $.fn.insertAt = function(index, element) {
        var lastIndex = this.children().size();
        if(index < 0) {
            index = Math.max(0, lastIndex + 1 + index);
        }
        this.append(element);
        if(index < lastIndex) {
            this.children().eq(index).before(this.children().last());
        }
        return this;
    };

    $.fn.make = function(className) {
        this.each(function() {
            $(this).parent().children('.'+className).removeClass(className);
            $(this).addClass(className);
        });
        return this;
    };

    $.fn.containedBy = function(parent) {
        parent = $(parent)[0];
        var isContainedBy = false;

        this.parents().each(function(i, par) {
            if(par === parent) {
                isContainedBy = true;
                return false; // break
            }
        });
        return isContainedBy;
    };

    var get_center = function(width, height) {
        var winHeight = $(window).height();
        var winWidth = $(window).width();
        var top = ((winHeight - height) / 2) + $(window).scrollTop();
        var left = ((winWidth - width) / 2) + $(window).scrollLeft();
        return [left, top];
    };
    $.fn.center = function(args) {
        args = $.extend({
            // defaults
            top: null  // center horizontally, manually specify top
        }, args || {});

        this.each(function() {
            var self = $(this),
                coords = get_center(self.outerWidth(), self.outerHeight()),
                left = coords[0], top = coords[1];

            if(args.top !== null) {
                top = args.top;
            }
            self.css({top: top, left: left});
       });
    };

    $.fn.getAllAttributes = function() {
        var el = this[0];
        var attributes = {};
        if($.browser.ltie9) {
            // Todo: Temp, stupid ie
            var attrs = el.attributes,
                names = ['name', 'factory', 'class', 'style', 'value', 'disabled'];
            for(var i=0; i<names.length; i++) {
                if(attrs[names[i]])
                    attributes[names[i]] = attrs[names[i]].nodeValue;
            }
        } else {
            // w3c NamedNodeMap
            $.each(el.attributes, function(index, attr) {
                attributes[attr.name] = attr.value;
            });
        }
        return attributes;
    };
    $.fn.attrs = function(attrs) {
        if(arguments.length === 0) {
            return $(this).getAllAttributes();
        }
        $.each(attrs || {}, function(key, val) {
            $(this).attr(key, val);
        }, this);
        return this;
    };

    $.fn.focusWithoutScrolling = function(){
        var x = window.scrollX,
            y = window.scrollY;
        this.focus();
        window.scrollTo(x, y);
    };

    $.fn.scrollMeOnly = function() {
        this.on('wheel', function(e) {
            e.preventDefault();
            e.currentTarget.scrollTop += e.deltaY;
        });
        return this;
    };

    $.fn.scrollIntoView = function(alignWithTop, scrollable) {
        var el = scrollable || this[0].parentNode;
            item = this[0],
            scrollTop = el.scrollTop;
        if(!item)
            return;

        if(alignWithTop) {
            if(item.offsetTop < scrollTop)
                el.scrollTop = item.offsetTop;
        }
        else {
            var height = $(this).outerHeight();
            if(item.offsetTop + height > el.clientHeight + scrollTop)
                el.scrollTop = item.offsetTop - el.clientHeight + height;
        }
    };

    $.fn.box = function() {
        return {
            left: $(this).offset().left,
            top: $(this).offset().top,
            width: $(this).outerWidth(),
            height: $(this).outerHeight()
        };
    };

    $.fn.fadeOutFast = function(options) {
        options = options || {};
        this.each(function(i, el) {
            var method = options.detach ? 'detach':'remove';
            if($.browser.ltie9)
                $(el)[method]();
            else
                $(el).fadeOut('fast', function() {
                    $(el)[method]().css({opacity: 1, display: 'block'});
                });
        });
    };

    function tabChainTabKeyDown(e) {
        if(e.altKey || e.ctrlKey || e.metaKey)
            return;
        var set = $(e.currentTarget).find('*:tabable'),
            index = set.index(e.target),
            next = set[index + (e.shiftKey ? -1 : 1)];
        (next || set[e.shiftKey ? set.length-1 : 0]).focus();
        e.preventDefault();
    }

    $.fn.tabChain = function(options) {
        this.each(function() {
            $(this).on('keydown', null, 'tab', tabChainTabKeyDown);
        });
    };

    $.fn.reverse = [].reverse;

    // ==============================
    // = jQuery selector extensions =
    // ==============================
    // From jQuery UI 1.9.1
    function visible( element ) {
        return $.expr.filters.visible( element ) &&
            !$( element ).parents().andSelf().filter(function() {
                return $.css( this, "visibility" ) === "hidden";
            }).length;
    }
    function focusable( element, isTabIndexNotNaN ) {
        var map, mapName, img,
            nodeName = element.nodeName.toLowerCase();
        if ( "area" === nodeName ) {
            map = element.parentNode;
            mapName = map.name;
            if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
                return false;
            }
            img = $( "img[usemap=#" + mapName + "]" )[0];
            return !!img && visible( img );
        }
        return ( /input|select|textarea|button|object/.test( nodeName ) ?
            !element.disabled :
            "a" === nodeName ?
                element.href || isTabIndexNotNaN :
                isTabIndexNotNaN) &&
            // the element and all of its ancestors must be visible
            visible( element );
    }

    // Mark a function for use in filtering
    var markFunction = function(fn) {
        fn.sizzleFilter = true;
        return fn;
    };
    $.extend($.expr[':'], {
        selectable: function(el) {
            // visible and not disabled
            return $(el).is(':visible') && !$(el).is('.disabled');
        },
        floating: function(el) {
            // absolute or fixed positioned
            var pos = el.style.position.toLowerCase();
            var pos2 = $(el).css('position');
            return  pos2 == 'absolute' || pos2 == 'fixed';
        },
        containsre: markFunction(function(text, context, xml) {
            return function(el) {
                var re = text.replace(/^\/+|\/+$/, '').split('/'); // strip slashes, then split
                return new RegExp(re[0], re[1]).test($(el).text());
            };
        }),
        tabable: function(el) {
            return el.tabIndex !== -1 && $(el).closest('.disabled').length === 0;
        },
        inviewport: function(el) {
            var scrollTop = $(window).scrollTop(),
                elTop = $(el).offset().top,
                height = $(window).height();

            return (elTop > scrollTop) && (elTop < scrollTop+height);
        },
        inside: markFunction(function(selector, context, xml) {
            return function(el) {
                return $(el).closest(selector).length;
            };
        }),
        focusable: function(el) {
            return focusable(el, !isNaN($.attr(el, "tabindex")));
        },
        scrollable: function(el) {
            var $el = $(el),
                scroll = {'scroll': true, 'auto': true},
                of = $el.css('overflow') in scroll,
                ofX = $el.css('overflow-x') in scroll,
                ofY = $el.css('overflow-y') in scroll;

            // HTML can scroll with overflow:visible
            if(el.tagName == 'HTML') {
                of = $el.css('overflow') != 'hidden';
                ofX = $el.css('overflow-x') != 'hidden';
                ofY = $el.css('overflow-y') != 'hidden';
            }
            if(!of && !ofX && !ofY)
                return false;
            return (el.clientHeight < el.scrollHeight && (of || ofY)) || (el.clientWidth < el.scrollWidth && (of || ofX));
        }
    });

});

<|endoftext|>


<commit_before>//= require ./mousetrap.js
"use strict";

(function() {
  var $btn, $elem;
  var buildLocalizationForm, getLocalizationPath, getLocalizationDetails,
    replaceWithForm, submitForm, removeLitForm;

  buildLocalizationForm = function(e){
    var $this = $(this);
    var meta = $('meta[name="lit-url-base"]');

    if(meta.length > 0)
      getLocalizationPath($this, meta);
    else
      console.error('cannot find lit base url');

    e.stopPropagation();
    return false;
  };

  getLocalizationPath = function(elem, metaElem) {
    $.getJSON(metaElem.attr('value'),
      { locale: elem.data('locale'),
        key: elem.data('key') },
      function(data){
        getLocalizationDetails(elem, data.path);
      }
    );
  };

  getLocalizationDetails = function(elem, path){
    $.getJSON(path, {},
      function(data){
        replaceWithForm(elem, data.value, path);
      }
    );
  };

  replaceWithForm = function(elem, value, update_path){
    removeLitForm();
    var $this = $(elem);
    $this.attr('contenteditable', true);
    if(value)
      $this.html(value);
    $this.focus();
    $this.on('blur', function(){
      submitForm($this, $this.html(), update_path);
      removeLitForm();
    });
  };

  submitForm = function(elem, val, update_path){
    $.ajax({
      type: 'PATCH',
      dataType: 'json',
      url: update_path,
      data: { 'localization[translated_value]': val },
      success: function(data){
        elem.html( data.html );
        elem.attr('contentEditable', false);
        console.log('saved ' + elem.data('key'));
      },
      error: function(){
        console.error('cannot save ' + elem.data('key'));
        alert('cannot save ' + elem.data('key'));
      }
    });
  };

  removeLitForm = function(){
    $('#litForm').remove();
  };

  $(document).ready(function(){
    $('
').appendTo('body');
    $btn = $('#lit_button_wrapper').text('Enable / disable lit highlight');
    $btn.on('click', function(){
      removeLitForm();
      if($btn.hasClass('lit-highlight-enabled')){
        $('.lit-key-generic').removeClass('lit-key-highlight').off('click.form');
        $btn.removeClass('lit-highlight-enabled');
        $('.lit-key-generic').each(function(_, elem){
          $elem = $(elem);
          $elem.attr('title', $elem.data('old-title') || '');
        });
      }else{
        $('.lit-key-generic').addClass('lit-key-highlight').on('click.form', buildLocalizationForm);
        $btn.addClass('lit-highlight-enabled');
        $('.lit-key-generic').each(function(_, elem){
          $elem = $(elem);
          $elem.data('old-title', $elem.attr('title'));
          $elem.attr('title', $elem.data('key'));
        });
      }
    });
    $('.lit-translations-info .lit-open-button').click(function(){
      $('.lit-translations-info').toggleClass('collapsed expanded');
    });
    $('.lit-translations-info .lit-close-button').click(function(){
      $('.lit-translations-info').toggleClass('collapsed expanded');
    });
  });

}).call(this);

<commit_msg>Use lit namespace for jQuery<commit_after>//= require ./mousetrap.js
"use strict";

(function() {
  var $btn, $elem;
  var buildLocalizationForm, getLocalizationPath, getLocalizationDetails,
    replaceWithForm, submitForm, removeLitForm;

  buildLocalizationForm = function(e){
    var $this = $(this);
    var meta = $('meta[name="lit-url-base"]');

    if(meta.length > 0)
      getLocalizationPath($this, meta);
    else
      console.error('cannot find lit base url');

    e.stopPropagation();
    return false;
  };

  getLocalizationPath = function(elem, metaElem) {
    $.getJSON(metaElem.attr('value'),
      { locale: elem.data('locale'),
        key: elem.data('key') },
      function(data){
        getLocalizationDetails(elem, data.path);
      }
    );
  };

  getLocalizationDetails = function(elem, path){
    $.getJSON(path, {},
      function(data){
        replaceWithForm(elem, data.value, path);
      }
    );
  };

  replaceWithForm = function(elem, value, update_path){
    removeLitForm();
    var $this = $(elem);
    $this.attr('contenteditable', true);
    if(value)
      $this.html(value);
    $this.focus();
    $this.on('blur', function(){
      submitForm($this, $this.html(), update_path);
      removeLitForm();
    });
  };

  submitForm = function(elem, val, update_path){
    $.ajax({
      type: 'PATCH',
      dataType: 'json',
      url: update_path,
      data: { 'localization[translated_value]': val },
      success: function(data){
        elem.html( data.html );
        elem.attr('contentEditable', false);
        console.log('saved ' + elem.data('key'));
      },
      error: function(){
        console.error('cannot save ' + elem.data('key'));
        alert('cannot save ' + elem.data('key'));
      }
    });
  };

  removeLitForm = function(){
    $('#litForm').remove();
  };

  $(document).ready(function(){
    $('
').appendTo('body');
    $btn = $('#lit_button_wrapper').text('Enable / disable lit highlight');
    $btn.on('click', function(){
      removeLitForm();
      if($btn.hasClass('lit-highlight-enabled')){
        $('.lit-key-generic').removeClass('lit-key-highlight').off('click.lit');
        $btn.removeClass('lit-highlight-enabled');
        $('.lit-key-generic').each(function(_, elem){
          $elem = $(elem);
          $elem.attr('title', $elem.data('old-title') || '');
        });
      }else{
        $('.lit-key-generic').addClass('lit-key-highlight').on('click.lit', buildLocalizationForm);
        $btn.addClass('lit-highlight-enabled');
        $('.lit-key-generic').each(function(_, elem){
          $elem = $(elem);
          $elem.data('old-title', $elem.attr('title'));
          $elem.attr('title', $elem.data('key'));
        });
      }
    });
    $('.lit-translations-info .lit-open-button').click(function(){
      $('.lit-translations-info').toggleClass('collapsed expanded');
    });
    $('.lit-translations-info .lit-close-button').click(function(){
      $('.lit-translations-info').toggleClass('collapsed expanded');
    });
  });

}).call(this);

<|endoftext|>


<commit_before>// ------------------------------------ UI tools -----------------------------------------
var Ui = {
  // return true if the dialog of grid with "name" is open, unless return false
  isOpen: function() {
    return ($(".ui-dialog:visible").size() > 0);
  },

  // check if the grid is being edited
  isEditing: function() {
    var editing = false;
    $.each(gridManager.grids, function(){
      if(this.isEditing()) editing = true;
    });
    return editing;
  },

  // Resize grid
  resizeGrid: function(grid) {
    grid.resizeCanvas();
    grid.autosizeColumns();
    grid.filterPanel.generateFilters();
    $(window).resize(function() {
      grid.resizeCanvas();
      grid.autosizeColumns();
      grid.filterPanel.generateFilters();
    });
  },

  // Check if filter panel is open
  filterPanelOpen: function() {
    return ($('.slick-headerrow-columns:visible').size() > 0 && $( document.activeElement ).parent().attr('class') === 'slick-headerrow-columns');
  },

  // Check if can add or delete records
  addOrDeleteLocked: function() {
    return this.isEditing() || this.isOpen() || this.filterPanelOpen();
  },

  // Select grid names
  selectGridNames: function() {
    var gridContainers = $(".grid_container"), gridName;
    return $.map( gridContainers, function(container){
      gridName = $.trim($(container).attr("id").split("grid_")[1]);
      if (gridName) {
        return gridName;
      }
    });
  },

  // Refresh create form when continue create new record
  refreshCreateForm: function(grid) {
    var name = grid.name;
    $.get(grid.path + '/wulin_master_new_form', function(data){
      newFormDom = $(data);
      $('#' + name + '_form:visible form').replaceWith(newFormDom.find('form'));
      setTimeout(function(){ Ui.setupForm(name, false); }, 350)
    });
  },

  // Reset form
  resetForm: function(name) {
    $(':input','#new_' + name).not(':button, :submit, :reset, :hidden').not('[readonly]').val('').removeAttr('checked').removeAttr('selected');
    // For chosen
    $('ul.chzn-choices li.search-choice').remove();
  },

  // Create and open dialog
  openDialog: function(grid,options) {
    var scope, width, height, name;
    name = grid.name;

    $.get(grid.path + '/wulin_master_new_form', function(data){
      $('body').append(data);

      scope = $( '#' + name + '_form');

      if (options) {
        width = options.form_dialog_width || 600;
        height = options.form_dialog_height || (scope.outerHeight() + 40);
      } else {
        width = 600;
        height = (scope.outerHeight() + 40);
      }

      scope.dialog({
        height: height,
        width: width,
        show: "blind",
        modal: true,
        create: function(event, ui) {
          Ui.setupForm(name, false);
  			},
        close: function(event, ui) {
          scope.dialog('destroy');
          scope.remove();
        }
      });
    });
  },

  setupForm: function(name, monitor) {
    var  remotePath;
    $('#' + name + '_form .chzn-select:not([data-remote-path])').chosen();
    $('#' + name + '_form input[data-date]').datepicker({ dateFormat: 'yy-mm-dd' });
    $('#' + name + '_form input[data-datetime]').datetimepicker({
      onlyTime: false,
      dateFormat: "yy-mm-dd",
      timeFormat: 'hh:mm'
    });
    $('#' + name + '_form input[data-time]').timepicker({});

    if ($('#' + name + '_form #remote_paths').val()) {
      // Fetch options of select box by ajax
      remotePath = $('#' + name + '_form #remote_paths').val().split(',');
      window._jsonData = window._jsonData || {};
      $.each(remotePath, function(i,path){
        if ($.isEmptyObject(path)) return

        var first_input, target = $("select[data-remote-path='" + path + "']"),
        textAttr = target.attr('data-text-attr');
        target.empty();
        if ($.isEmptyObject(window._jsonData[path])) {
          $.getJSON(path, function(itemdata){
            window._jsonData[path] = itemdata;
            $.each(itemdata, function(index, value) {
              target.append("<option value='" + value.id + "'>" + value[textAttr] + "</option>");
            });
            Ui.setupChosen(path, monitor);
          });
        } else {
          $.each(window._jsonData[path], function(index, value) {
            target.append("<option value='" + value.id + "'>" + value[textAttr] + "</option>");
          });
          Ui.setupChosen(path, monitor);
        }
      });
    }

    first_input = $( '#' + name + '_form input:text' ).first();
    if ($.isEmptyObject(first_input.attr('data-date'))) {
      first_input.focus();
    }
  },

  setupChosen: function(path, monitor) {
    setTimeout(function(){
      var afterSetupChosen = $("select[data-remote-path='" + path + "']").data('afterSetupChosen');
      if (monitor) {
        $("select[data-remote-path='" + path + "']").chosen().change(function(){
          $('input.target_flag:checkbox[data-target="' + $(this).attr('data-target') + '"]').attr('checked', 'checked');
        });
      } else {
        $("select[data-remote-path='" + path + "']").chosen();
      }

      if( afterSetupChosen ) {
        afterSetupChosen();
      }
    }, 100);
  },

  // Close dialog
  closeDialog: function(name) {
    var $form = $( '#' + name + '_form' );

    // setTimeout(function(){
    //   Ui.highlightCreatedRows(name);
    // }, 300);
    window._focused = {};

    $form.dialog("destroy");
    $form.remove();
  },

  // Highlight the created rows after close the dialog
  // highlightCreatedRows: function(name) {
  //   var grid = gridManager.getGrid(name),
  //   createdRows = [];
  //   console.log(grid.operatedIds);
  //   $.each(grid.operatedIds, function(){
  //     if (grid.getRowByRecordId(this) && grid.getRowByRecordId(this).row) {
  //       createdRows.push(grid.getRowByRecordId(this).row);
  //     }
  //   });
  //   $.each(createdRows, function(){
  //     $(this).effect( 'highlight', {}, 5000 );
  //   });
  // },

  // Flash the notification
  flashNotice: function(ids, action) {
    var recordSize = $.isArray(ids) ? ids.length : ids.split(',').length,
    recordUnit = recordSize > 1 ? 'records' : 'record',
    actionDesc = action === 'delete' ? 'has been deleted!' : 'has been created!';

    if (recordSize > 0) {
      $('.notice_flash').remove();
      $('#indicators').before('
' + recordSize + ' ' + recordUnit + ' ' + actionDesc + '
');
      $('.notice_flash').fadeOut(7000);
    }
  },

  // Find the selected grid
  findCurrentGrid: function() {
    var currentGrid = null;
    currentGridContainer = $( document.activeElement ).parents('.grid_container');
    if (currentGridContainer.size() == 0) {
      return null;
    }
    gridName = currentGridContainer.attr('id').split('grid_')[1];

    if (gridManager.grids.length == 1) {
      currentGrid = gridManager.grids[0]
    } else {
      if (currentGridContainer.size() == 1) {
        currentGrid = gridManager.getGrid(gridName);
      } else {
        $.each(gridManager.grids, function(){
          if(this.getSelectedRows().length > 0) currentGrid = this;
        });
      }
    }
    return currentGrid;
  },

	formatData: function(grid, arrayData) {
	  var data = {}, columns;
    columns = grid.loader.getColumns();
	  $.each(columns, function(index, column){
	    data[column['id']] = arrayData[index];
	  })
	  return data;
	}

};
<commit_msg>BUG #10367 - Framework: belongs_to drop-down should have a 'Select an option..' blank value when there's is no presence validation associated<commit_after>// ------------------------------------ UI tools -----------------------------------------
var Ui = {
  // return true if the dialog of grid with "name" is open, unless return false
  isOpen: function() {
    return ($(".ui-dialog:visible").size() > 0);
  },

  // check if the grid is being edited
  isEditing: function() {
    var editing = false;
    $.each(gridManager.grids, function(){
      if(this.isEditing()) editing = true;
    });
    return editing;
  },

  // Resize grid
  resizeGrid: function(grid) {
    grid.resizeCanvas();
    grid.autosizeColumns();
    grid.filterPanel.generateFilters();
    $(window).resize(function() {
      grid.resizeCanvas();
      grid.autosizeColumns();
      grid.filterPanel.generateFilters();
    });
  },

  // Check if filter panel is open
  filterPanelOpen: function() {
    return ($('.slick-headerrow-columns:visible').size() > 0 && $( document.activeElement ).parent().attr('class') === 'slick-headerrow-columns');
  },

  // Check if can add or delete records
  addOrDeleteLocked: function() {
    return this.isEditing() || this.isOpen() || this.filterPanelOpen();
  },

  // Select grid names
  selectGridNames: function() {
    var gridContainers = $(".grid_container"), gridName;
    return $.map( gridContainers, function(container){
      gridName = $.trim($(container).attr("id").split("grid_")[1]);
      if (gridName) {
        return gridName;
      }
    });
  },

  // Refresh create form when continue create new record
  refreshCreateForm: function(grid) {
    var name = grid.name;
    $.get(grid.path + '/wulin_master_new_form', function(data){
      newFormDom = $(data);
      $('#' + name + '_form:visible form').replaceWith(newFormDom.find('form'));
      setTimeout(function(){ Ui.setupForm(name, false); }, 350)
    });
  },

  // Reset form
  resetForm: function(name) {
    $(':input','#new_' + name).not(':button, :submit, :reset, :hidden').not('[readonly]').val('').removeAttr('checked').removeAttr('selected');
    // For chosen
    $('ul.chzn-choices li.search-choice').remove();
  },

  // Create and open dialog
  openDialog: function(grid,options) {
    var scope, width, height, name;
    name = grid.name;

    $.get(grid.path + '/wulin_master_new_form', function(data){
      $('body').append(data);

      scope = $( '#' + name + '_form');

      if (options) {
        width = options.form_dialog_width || 600;
        height = options.form_dialog_height || (scope.outerHeight() + 40);
      } else {
        width = 600;
        height = (scope.outerHeight() + 40);
      }

      scope.dialog({
        height: height,
        width: width,
        show: "blind",
        modal: true,
        create: function(event, ui) {
          Ui.setupForm(name, false);
  			},
        close: function(event, ui) {
          scope.dialog('destroy');
          scope.remove();
        }
      });
    });
  },

  setupForm: function(name, monitor) {
    var  remotePath;
    $('#' + name + '_form .chzn-select:not([data-remote-path])').chosen();
    $('#' + name + '_form input[data-date]').datepicker({ dateFormat: 'yy-mm-dd' });
    $('#' + name + '_form input[data-datetime]').datetimepicker({
      onlyTime: false,
      dateFormat: "yy-mm-dd",
      timeFormat: 'hh:mm'
    });
    $('#' + name + '_form input[data-time]').timepicker({});

    if ($('#' + name + '_form #remote_paths').val()) {
      // Fetch options of select box by ajax
      remotePath = $('#' + name + '_form #remote_paths').val().split(',');
      window._jsonData = window._jsonData || {};
      $.each(remotePath, function(i,path){
        if ($.isEmptyObject(path)) return

        var first_input, target = $("select[data-remote-path='" + path + "']"),
        textAttr = target.attr('data-text-attr');
        // target.empty();
        $('option[value!=""]', target).remove();
        if ($.isEmptyObject(window._jsonData[path])) {
          $.getJSON(path, function(itemdata){
            window._jsonData[path] = itemdata;
            $.each(itemdata, function(index, value) {
              target.append("<option value='" + value.id + "'>" + value[textAttr] + "</option>");
            });
            Ui.setupChosen(path, monitor);
          });
        } else {
          $.each(window._jsonData[path], function(index, value) {
            target.append("<option value='" + value.id + "'>" + value[textAttr] + "</option>");
          });
          Ui.setupChosen(path, monitor);
        }
      });
    }

    first_input = $( '#' + name + '_form input:text' ).first();
    if ($.isEmptyObject(first_input.attr('data-date'))) {
      first_input.focus();
    }
  },

  setupChosen: function(path, monitor) {
    setTimeout(function(){
      var afterSetupChosen = $("select[data-remote-path='" + path + "']").data('afterSetupChosen');
      if (monitor) {
        $("select[data-remote-path='" + path + "']").chosen().change(function(){
          $('input.target_flag:checkbox[data-target="' + $(this).attr('data-target') + '"]').attr('checked', 'checked');
        });
      } else {
        $("select[data-remote-path='" + path + "']").chosen();
      }

      if( afterSetupChosen ) {
        afterSetupChosen();
      }
    }, 100);
  },

  // Close dialog
  closeDialog: function(name) {
    var $form = $( '#' + name + '_form' );

    // setTimeout(function(){
    //   Ui.highlightCreatedRows(name);
    // }, 300);
    window._focused = {};

    $form.dialog("destroy");
    $form.remove();
  },

  // Highlight the created rows after close the dialog
  // highlightCreatedRows: function(name) {
  //   var grid = gridManager.getGrid(name),
  //   createdRows = [];
  //   console.log(grid.operatedIds);
  //   $.each(grid.operatedIds, function(){
  //     if (grid.getRowByRecordId(this) && grid.getRowByRecordId(this).row) {
  //       createdRows.push(grid.getRowByRecordId(this).row);
  //     }
  //   });
  //   $.each(createdRows, function(){
  //     $(this).effect( 'highlight', {}, 5000 );
  //   });
  // },

  // Flash the notification
  flashNotice: function(ids, action) {
    var recordSize = $.isArray(ids) ? ids.length : ids.split(',').length,
    recordUnit = recordSize > 1 ? 'records' : 'record',
    actionDesc = action === 'delete' ? 'has been deleted!' : 'has been created!';

    if (recordSize > 0) {
      $('.notice_flash').remove();
      $('#indicators').before('
' + recordSize + ' ' + recordUnit + ' ' + actionDesc + '
');
      $('.notice_flash').fadeOut(7000);
    }
  },

  // Find the selected grid
  findCurrentGrid: function() {
    var currentGrid = null;
    currentGridContainer = $( document.activeElement ).parents('.grid_container');
    if (currentGridContainer.size() == 0) {
      return null;
    }
    gridName = currentGridContainer.attr('id').split('grid_')[1];

    if (gridManager.grids.length == 1) {
      currentGrid = gridManager.grids[0]
    } else {
      if (currentGridContainer.size() == 1) {
        currentGrid = gridManager.getGrid(gridName);
      } else {
        $.each(gridManager.grids, function(){
          if(this.getSelectedRows().length > 0) currentGrid = this;
        });
      }
    }
    return currentGrid;
  },

	formatData: function(grid, arrayData) {
	  var data = {}, columns;
    columns = grid.loader.getColumns();
	  $.each(columns, function(index, column){
	    data[column['id']] = arrayData[index];
	  })
	  return data;
	}

};
<|endoftext|>