<commit_before>// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a  attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('next', ['ionic', 'next.services', 'next.filters', 'ngCordova.plugins.geolocation'])

.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleLightContent();
    }
  });
})

.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
  $stateProvider
  .state('detail', {
    url: '/station-detail',
    controller: 'DetailCtrl',
    templateUrl: 'templates/station-detail.html'
  })
  .state('overview', {
    url: '/station-overview',
    controller: 'OverviewCtrl',
    templateUrl: 'templates/stations-overview.html'
  });

   $urlRouterProvider.otherwise("/station-overview");

    $ionicConfigProvider.backButton.previousTitleText(false).text('');

})

.controller('OverviewCtrl', function($scope, $location, $ionicPlatform, $ionicLoading, $cordovaGeolocation, $ionicViewSwitcher, $timeout, ApiService, StationService) {
    $scope.stations = [];

    var lat;
    var lng;
    $ionicLoading.hide();

    $ionicPlatform.ready(function() {
        $cordovaGeolocation.getCurrentPosition()
            .then(function (position) {
              lat  = position.coords.latitude;
              lng = position.coords.longitude;

              // Oslo: 59.932624, 10.734738
              // Ytterby: 57.863906199999995 11.9110967

              console.log("Coordinates from cordova geolocation",lat,lng);

              if ((lng+"").substr(0,4)==="11.9"){
                lat = 59.932624;
                lng = 10.734738;
                console.log("But since you are in Ytterby we'll use",lat,lng,"instead! :)");
              }

              var preferredStation = ApiService.getPreferredStation(lat, lng);
              if (preferredStation) {
                $ionicViewSwitcher.nextTransition('none');
                StationService.setStation(preferredStation);
                $location.path('/station-detail');
              }
              getStationsFromApi(lat, lng, 15);

            }, function(err) {
              console.log("Error getting current position! :(",err);
            });
    });

    $scope.goToStation = function(station) {
        if (station && lat && lng) {
          ApiService.preferStation(station, lat, lng);
        }
        StationService.setStation(station);
        $location.path('/station-detail');
    };

    function getStationsFromApi(lat, lng, count) {
        ApiService.getStationList(lat, lng, count, function(err, stations) {
          $timeout(function() {
              $scope.stations = stations;
              $scope.$apply();
          })
      });
    }

    $scope.refresh = function() {
        $cordovaGeolocation.getCurrentPosition()
            .then(function (position) {
              lat  = position.coords.latitude;
              lng = position.coords.longitude;
              getStationsFromApi(lat, lng, 15);
        })
        $scope.$broadcast('scroll.refreshComplete');
    };

    $scope.reset = function(station) {
        ApiService.unpreferStation(station, lat, lng);
        getStationsFromApi(lat, lng, 15);
    };

})

.controller('DetailCtrl', function($scope, $ionicSlideBoxDelegate, $ionicPlatform, $ionicLoading, $cordovaGeolocation, $timeout, ApiService, StationService) {

    $ionicLoading.show({
      template: 'Laster inn avganger...
<ion-spinner icon="spiral" class="spinner-positive"></ion-spinner>
'
    });

    if (StationService.getStation() != null) {
        $scope.selectedStation = StationService.getStation();
        getLinesFromApi($scope.selectedStation.ID);
    }

    function getLinesFromApi(id) {
        ApiService.getDeparturesForStation(id, (function(err, lines) {
            console.log(err);
            console.log(lines);
            $timeout(function() {
                $scope.lines = lines;
                $scope.$apply();
                $ionicLoading.hide();
            });
        }));
    }

    $scope.activeIndex = 0;
    $scope.slideChanged = function(index) {
        $scope.selectedStation = $scope.stations[index];
        $scope.activeIndex = index;
    };

    $scope.refresh = function() {
        getLinesFromApi($scope.selectedStation.ID);
        $scope.$broadcast('scroll.refreshComplete');
    };

    $scope.findImg = function(line) {
        if (line.LineRef < 20) return "./img/trikk.png";
        else return "./img/buss.png";
    }

})

<commit_msg>add functions to show bus and tram icons<commit_after>// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a  attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('next', ['ionic', 'next.services', 'next.filters', 'ngCordova.plugins.geolocation'])

.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleLightContent();
    }
  });
})

.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
  $stateProvider
  .state('detail', {
    url: '/station-detail',
    controller: 'DetailCtrl',
    templateUrl: 'templates/station-detail.html'
  })
  .state('overview', {
    url: '/station-overview',
    controller: 'OverviewCtrl',
    templateUrl: 'templates/stations-overview.html'
  });

   $urlRouterProvider.otherwise("/station-overview");

    $ionicConfigProvider.backButton.previousTitleText(false).text('');

})

.controller('OverviewCtrl', function($scope, $location, $ionicPlatform, $ionicLoading, $cordovaGeolocation, $ionicViewSwitcher, $timeout, ApiService, StationService) {
    $scope.stations = [];

    var lat;
    var lng;

    $ionicPlatform.ready(function() {
        $cordovaGeolocation.getCurrentPosition()
            .then(function (position) {
              lat  = position.coords.latitude;
              lng = position.coords.longitude;

              // Oslo: 59.932624, 10.734738
              // Ytterby: 57.863906199999995 11.9110967

              console.log("Coordinates from cordova geolocation",lat,lng);

              if ((lng+"").substr(0,4)==="11.9"){
                lat = 59.932624;
                lng = 10.734738;
                console.log("But since you are in Ytterby we'll use",lat,lng,"instead! :)");
              }

              var preferredStation = ApiService.getPreferredStation(lat, lng);
              if (preferredStation) {
                $ionicViewSwitcher.nextTransition('none');
                StationService.setStation(preferredStation);
                $location.path('/station-detail');
              }
              getStationsFromApi(lat, lng, 15);

            }, function(err) {
              console.log("Error getting current position! :(",err);
            });
    });

    $scope.goToStation = function(station) {
        if (station && lat && lng) {
          ApiService.preferStation(station, lat, lng);
        }
        StationService.setStation(station);
        $location.path('/station-detail');
    };

    function getStationsFromApi(lat, lng, count) {
        ApiService.getStationList(lat, lng, count, function(err, stations) {
          $timeout(function() {
              $scope.stations = stations;
              $scope.$apply();
          })
      });
    }

    $scope.servedByTram = function(station) {
        for (var i = 0; i < station.Lines.length; i++) {
            if (station.Lines[i].LineID < 20) {
                return true;
            }
        }

        return false;
      }

    $scope.servedByBus = function(station) {
        for (var i = 0; i < station.Lines.length; i++) {
            if (station.Lines[i].LineID > 20 && station.Lines[i].LineID < 100) {
                return true;
            }
        }

        return false;
      }

    $scope.refresh = function() {
        $cordovaGeolocation.getCurrentPosition()
            .then(function (position) {
              lat  = position.coords.latitude;
              lng = position.coords.longitude;
              getStationsFromApi(lat, lng, 15);
        })
        $scope.$broadcast('scroll.refreshComplete');
    };

    $scope.reset = function(station) {
        ApiService.unpreferStation(station, lat, lng);
        getStationsFromApi(lat, lng, 15);
    };

})

.controller('DetailCtrl', function($scope, $ionicSlideBoxDelegate, $ionicPlatform, $ionicLoading, $cordovaGeolocation, $timeout, ApiService, StationService) {

    $ionicLoading.show({
      template: 'Laster inn avganger...
<ion-spinner icon="spiral" class="spinner-positive"></ion-spinner>
'
    });

    if (StationService.getStation() != null) {
        $scope.selectedStation = StationService.getStation();
        getLinesFromApi($scope.selectedStation.ID);
    }

    function getLinesFromApi(id) {
        ApiService.getDeparturesForStation(id, (function(err, lines) {
            $timeout(function() {
                $scope.lines = lines;
                $scope.$apply();
                $ionicLoading.hide();
            });
        }));
    }

    $scope.activeIndex = 0;
    $scope.slideChanged = function(index) {
        $scope.selectedStation = $scope.stations[index];
        $scope.activeIndex = index;
    };

    $scope.refresh = function() {
        getLinesFromApi($scope.selectedStation.ID);
        $scope.$broadcast('scroll.refreshComplete');
    };

})

<|endoftext|>


<commit_before>// Function to validate the E-Mail input in the DonationForm

function validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
}

var userInput = [];
var DonationForm = document.getElementById("donationForm");

//Event Listeners for Submit Button

DonationForm.addEventListener("submit", validateDonationForm);

// Function to validate the Name input in the DonationForm

function validateDonationForm(e) {
    e.preventDefault();
    console.log(e);
    for (var i = 0; i < e.target.length; i++) {
      var el = e.target[i];
      var InputValue = el.value;
      var InputID = el.id;
      var ElP = el.nextElementSibling;
      var checkEmail = false;
        if (InputID != "SubmitButton" && InputID !=  "DonationAmount" &&  InputID != "DonationPreference") { //don't include the button
          userInput.push(InputValue);
          console.log(InputValue);
          if (InputValue == null || InputValue == ""){ //checks if something is written in box
            ElP.setAttribute('style', 'visibility:visible');
          } else {
            ElP.setAttribute('style', 'visibility:hidden')
            checkEmail = true;
          }
          if (checkEmail && InputID == 'DonationEmail') { //checks if something is a valid email
            var validEmail = validateEmail(InputValue);
              if (validEmail) { //checks if input is true or false (and email is valid)
                ElP.setAttribute('style', 'visibility:hidden');
              } else {
                ElP.setAttribute('style', 'visibility:visible');
              }

          }
      }
    }
  }

    console.log(userInput);

    //  var userName = document.forms["DonationForm"]["fname"].value;
    //  if (userName == null || userName == "") {
    //      nameAlert.setAttribute('style', 'visibility:visible');
    //  } else {
    //    userInput.nameInput = userName;
    //    saveStorage('UserInputName', userInput.nameInput);
    //  }
    //  console.log(userInput);
//}

// Function to validate the Location input in the DonationForm

function validateDonationFormLocation(e) {
    e.preventDefault();
    var userLocation = document.forms["DonationForm"]["flocation"].value;
    if (userLocation == null || userLocation == "") {
        locationAlert.setAttribute('style', 'visibility:visible');
    } else {
      userInput.locationInput = userLocation;
      saveStorage('UserInputLocation', userInput.locationInput);
    }
    console.log(userInput);
}

//Local Storage

function saveStorage(key, UserData) {
  var temp = JSON.stringify(UserData);
  localStorage.setItem(key, temp);
}

function getStorage(key){
  var temp = localStorage.getItem(key);
  return JSON.parse(temp);
}
<commit_msg>started working on local storage. Wrote new function<commit_after>// Function to validate the E-Mail input in the DonationForm

function validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
}

var userInput = [];
var DonationForm = document.getElementById("donationForm");

//Local Storage

function saveStorage(key, UserData) {
  var temp = JSON.stringify(UserData);
  localStorage.setItem(key, temp);
}

function getStorage(key){
  var temp = localStorage.getItem(key);
  return JSON.parse(temp);
}

var DonationFormStorage = getStorage('DonationsForm');

//Event Listeners for Submit Button

DonationForm.addEventListener("submit", validateDonationForm);
DonationForm.addEventListener("keyup", storeFormValues);

// Function to validate the Name input in the DonationForm

function validateDonationForm(e) {
    e.preventDefault();
    for (var i = 0; i < e.target.length; i++) {
      var el = e.target[i];
      var InputValue = el.value;
      var InputID = el.id;
      var ElP = el.nextElementSibling;
      var checkEmail = false;
        if (InputID != "SubmitButton" && InputID !=  "DonationAmount" &&  InputID != "DonationPreference") { //don't include the button
          userInput.push(InputValue);
          console.log(InputValue);
          if (InputValue == null || InputValue == ""){ //checks if something is written in box
            ElP.setAttribute('style', 'visibility:visible');
          } else {
            ElP.setAttribute('style', 'visibility:hidden')
            checkEmail = true;
          }
          if (checkEmail && InputID == 'DonationEmail') { //checks if something is a valid email
            var validEmail = validateEmail(InputValue);
              if (validEmail) { //checks if input is true or false (and email is valid)
                ElP.setAttribute('style', 'visibility:hidden');
              } else {
                ElP.setAttribute('style', 'visibility:visible');
              }
          }
      }
    }
  }

//Local Storage

function storeFormValues (e) {
  console.log(e);
  var elForm = e.target.form;
  var localStorageArray = [];
  for (var i = 0; i < elForm.length; i++) {
    var el = elForm[i];
    var InputValue = el.value;
    var InputID = el.id;
    if (InputID != "SubmitButton" && InputID !=  "DonationAmount" &&  InputID != "DonationPreference"){
      localStorageArray.push(InputValue);
    }
  }
  saveStorage('DonationsForm', localStorageArray);
}
<|endoftext|>


<commit_before>var path = require('path');
var _ = require('lodash');
var Q = require('q');
var crypto = require('crypto');

var types = require('../types');
var errors = require('../errors');

function genSha() {
    var shasum = crypto.createHash('sha1');
    shasum.update(_.uniqueId('sha'));
    return shasum.digest('hex');
}

function Driver(options) {
    this.options = _.defaults(options || {}, {
        files: {}
    });
    if (!this.options.files || _.size(this.options.files) == 0) throw "Need at least one file";

    this.branches = {
        master: {
            name: "master",
            commits: [],
            files: {}
        }
    };

    _.each(this.options.files, function(content, filepath) {
        this.create(filepath, content, {
            message: "Initial commit",
            ref: "master"
        });
    }, this);
}

Driver.prototype.mapBranch = function (branch) {
    return {
        name: branch.name,
        commit: _.last(branch.commits).sha
    };
};

Driver.prototype.mapFile = function(ref, file) {
    return {
        path: file.path,
        name: path.basename(file.path),
        size: file.content.length,
        content: file.content,
        type: this.isDirectory(ref, file.path)? types.DIRECTORY : types.FILE
    };
};

// Check if a path is a directory
Driver.prototype.isDirectory = function(ref, p) {
    return !!_.find(this.branches[ref].files, function(file, filepath) {
        return (filepath != p && filepath.indexOf(p) === 0);
    });
};

// Get infos for a file
Driver.prototype.stat = function(p, opts) {
    if (!this.branches[opts.ref]) throw errors.refNotFound(opts.ref);

    return this.mapFile(opts.ref, this.branches[opts.ref].files[p]);
};

// List files in a directory
Driver.prototype.readdir = function(p, opts) {
    if (!this.branches[opts.ref]) throw errors.refNotFound(opts.ref);
    if (!this.isDirectory(opts.ref, p)) throw errors.notDirectory(p);

    return _.chain(this.branches[opts.ref].files)
        .filter(function(file) {
            return(
                file.path != p &&
                file.path.indexOf(p) === 0 &&
                _.compact(file.path.slice(p.length).split('/')).length == 1
            );
        })
        .map(function(file) {
            return [
                path.basename(file.path),
                this.mapFile(opts.ref, file)
            ];
        }, this)
        .object()
        .value();
};

// Push a commit
Driver.prototype.pushCommit = function(ref, msg, files) {
    var commit = {
        message: msg,
        sha: genSha(),
        files: files
    };

    this.branches[ref].commits.push(commit);
};

// Write a file
Driver.prototype._write = function(checkExists, p, content, opts) {
    if (!this.branches[opts.ref]) throw errors.refNotFound(opts.ref);
    if (checkExists && !this.branches[opts.ref].files[p]) throw errors.fileNotFound(p);

    this.pushCommit(opts.ref, opts.message, _.object([[p, content]]));
    this.branches[opts.ref].files[p] = {
        path: p,
        content: content
    };

    return this.mapFile(opts.ref, this.branches[opts.ref].files[p]);

};
Driver.prototype.write = _.partial(Driver.prototype._write, true)
Driver.prototype.create = _.partial(Driver.prototype._write, false)

// Delete a file
Driver.prototype.unlink = function(p, opts) {
    if (!this.branches[opts.ref]) throw errors.refNotFound(opts.ref);

    this.pushCommit(opts.ref, opts.message, _.object([[p, null]]));
    delete this.branches[opts.ref].files[p];
};

// List branches
Driver.prototype.listBranches = function(p, opts) {
    return _.map(this.branches, this.mapBranch, this);
};

// Create a branch
Driver.prototype.createBranch = function(name, from) {
    if (this.branches[name]) throw "Branch '"+name+"' already exists";
    if (!this.branches[from]) throw "Branch '"+from+"' doesn't exist";

    this.branches[name] = _.cloneDeep(this.branches[from]);
    this.branches[name].name = name;
    return this.mapBranch(this.branches[name]);
};

// Remove a branch
Driver.prototype.removeBranch = function(name) {
    if (!this.branches[name]) throw "Branch '"+name+"' doesn't exist";
    delete this.branches[name];
};

// Merge branches
Driver.prototype.mergeBranches = function(from, to, opts) {
    var that = this;

};

Driver.id = "memory";
module.exports = Driver;
<commit_msg>Fix directories listing in memory driver<commit_after>var path = require('path');
var _ = require('lodash');
var Q = require('q');
var crypto = require('crypto');

var types = require('../types');
var errors = require('../errors');

function genSha() {
    var shasum = crypto.createHash('sha1');
    shasum.update(_.uniqueId('sha'));
    return shasum.digest('hex');
}

function Driver(options) {
    this.options = _.defaults(options || {}, {
        files: {}
    });
    if (!this.options.files || _.size(this.options.files) == 0) throw "Need at least one file";

    this.branches = {
        master: {
            name: "master",
            commits: [],
            files: {}
        }
    };

    _.each(this.options.files, function(content, filepath) {
        this.create(filepath, content, {
            message: "Initial commit",
            ref: "master"
        });
    }, this);
}

Driver.prototype.mapBranch = function (branch) {
    return {
        name: branch.name,
        commit: _.last(branch.commits).sha
    };
};

Driver.prototype.mapFile = function(ref, file) {
    return {
        path: file.path,
        name: path.basename(file.path),
        size: file.content.length,
        content: file.content,
        type: this.isDirectory(ref, file.path)? types.DIRECTORY : types.FILE
    };
};

// Check if a path is a directory
Driver.prototype.isDirectory = function(ref, p) {
    if (!p) return true;
    return !!_.find(this.branches[ref].files, function(file, filepath) {
        return (filepath != p && filepath.indexOf(p+'/') === 0);
    });
};

// Get infos for a file
Driver.prototype.stat = function(p, opts) {
    if (!this.branches[opts.ref]) throw errors.refNotFound(opts.ref);

    return this.mapFile(opts.ref, this.branches[opts.ref].files[p]);
};

// List files in a directory
Driver.prototype.readdir = function(p, opts) {
    if (!this.branches[opts.ref]) throw errors.refNotFound(opts.ref);
    if (!this.isDirectory(opts.ref, p)) throw errors.notDirectory(p);

    var prepended = p;
    if (p) prepended = p + '/';

    return _.chain(this.branches[opts.ref].files)
        .filter(function(file) {
            return(
                file.path != p &&
                file.path.indexOf(prepended) === 0 &&
                _.compact(file.path.slice(prepended.length).split('/')).length == 1
            );
        })
        .map(function(file) {
            return [
                path.basename(file.path),
                this.mapFile(opts.ref, file)
            ];
        }, this)
        .object()
        .value();
};

// Push a commit
Driver.prototype.pushCommit = function(ref, msg, files) {
    var commit = {
        message: msg,
        sha: genSha(),
        files: files
    };

    this.branches[ref].commits.push(commit);
};

// Write a file
Driver.prototype._write = function(checkExists, p, content, opts) {
    if (!this.branches[opts.ref]) throw errors.refNotFound(opts.ref);
    if (checkExists && !this.branches[opts.ref].files[p]) throw errors.fileNotFound(p);

    this.pushCommit(opts.ref, opts.message, _.object([[p, content]]));
    this.branches[opts.ref].files[p] = {
        path: p,
        content: content
    };

    return this.mapFile(opts.ref, this.branches[opts.ref].files[p]);

};
Driver.prototype.write = _.partial(Driver.prototype._write, true)
Driver.prototype.create = _.partial(Driver.prototype._write, false)

// Delete a file
Driver.prototype.unlink = function(p, opts) {
    if (!this.branches[opts.ref]) throw errors.refNotFound(opts.ref);

    this.pushCommit(opts.ref, opts.message, _.object([[p, null]]));
    delete this.branches[opts.ref].files[p];
};

// List branches
Driver.prototype.listBranches = function(p, opts) {
    return _.map(this.branches, this.mapBranch, this);
};

// Create a branch
Driver.prototype.createBranch = function(name, from) {
    if (this.branches[name]) throw "Branch '"+name+"' already exists";
    if (!this.branches[from]) throw "Branch '"+from+"' doesn't exist";

    this.branches[name] = _.cloneDeep(this.branches[from]);
    this.branches[name].name = name;
    return this.mapBranch(this.branches[name]);
};

// Remove a branch
Driver.prototype.removeBranch = function(name) {
    if (!this.branches[name]) throw "Branch '"+name+"' doesn't exist";
    delete this.branches[name];
};

// Merge branches
Driver.prototype.mergeBranches = function(from, to, opts) {
    var that = this;

};

Driver.id = "memory";
module.exports = Driver;
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

/**
 * This hook makes sure projects using [cordova-plugin-firebase](https://github.com/arnesson/cordova-plugin-firebase)
 * will build properly and have the required key files copied to the proper destinations when the app is build on Ionic Cloud using the package command.
 * Credits: https://github.com/arnesson.
 */
var fse = require('fs-extra');
var config = fse.readFileSync('config.xml').toString();
var name = getValue(config, 'name');

var IOS_DIR = 'platforms/ios';
var ANDROID_DIR = 'platforms/android';

var PLATFORM = {
    IOS: {
        dest: [
            IOS_DIR + name + '/Resources/GoogleService-Info.plist',
            IOS_DIR + name + '/Resources/Resources/GoogleService-Info.plist'
        ],
        src: [
            'GoogleService-Info.plist',
            IOS_DIR + '/www/GoogleService-Info.plist',
            'www/GoogleService-Info.plist'
        ]
    },
    ANDROID: {
        dest: [
            ANDROID_DIR + '/google-services.json'
        ],
        src: [
            'google-services.json',
            ANDROID_DIR + '/assets/www/google-services.json',
            'www/google-services.json'
        ],
        stringsXml: ANDROID_DIR + '/res/values/strings.xml'
    }
};

// Copy key files to their platform specific folders
if (directoryExists(IOS_DIR)) {
    copyKey(PLATFORM.IOS);
} else if (directoryExists(ANDROID_DIR)) {
    copyKey(PLATFORM.ANDROID, updateStringsXml)
}

function updateStringsXml(contents) {
    var json = JSON.parse(contents);
    var strings = fse.readFileSync(PLATFORM.ANDROID.stringsXml).toString();

    // strip non-default value
    strings = strings.replace(new RegExp('<string name="google_app_id">([^\@<]+?)</string>', 'i'), '');

    // strip non-default value
    strings = strings.replace(new RegExp('<string name="google_api_key">([^\@<]+?)</string>', 'i'), '');

    // strip empty lines
    strings = strings.replace(new RegExp('(\r\n|\n|\r)[ \t]*(\r\n|\n|\r)', 'gm'), '$1');

    // replace the default value
    strings = strings.replace(new RegExp('<string name="google_app_id">([^<]+?)</string>', 'i'), '<string name="google_app_id">' + json.client[0].client_info.mobilesdk_app_id + '</string>');

    // replace the default value
    strings = strings.replace(new RegExp('<string name="google_api_key">([^<]+?)</string>', 'i'), '<string name="google_api_key">' + json.client[0].api_key[0].current_key + '</string>');

    fse.writeFileSync(PLATFORM.ANDROID.stringsXml, strings);
}

function copyKey(platform, callback) {
    for (var i = 0; i < platform.src.length; i++) {
        var file = platform.src[i];
        if (fileExists(file)) {
            try {
                var contents = fse.readFileSync(file).toString();

                try {
                    platform.dest.forEach(function (destinationPath) {
                        var folder = destinationPath.substring(0, destinationPath.lastIndexOf('/'));
                        fse.ensureDirSync(folder);
                        fse.writeFileSync(destinationPath, contents);
                    });
                } catch (e) {
                    // skip
                }

                callback && callback(contents);
            } catch (err) {
                console.log(err)
            }

            break;
        }
    }
}

function getValue(config, name) {
    var value = config.match(new RegExp('<' + name + '>(.*?)</' + name + '>', 'i'));
    if (value && value[1]) {
        return value[1]
    } else {
        return null
    }
}

function fileExists(path) {
    try {
        return fse.statSync(path).isFile();
    } catch (e) {
        return false;
    }
}

function directoryExists(path) {
    try {
        return fse.statSync(path).isDirectory();
    } catch (e) {
        return false;
    }
}<commit_msg>fix ios GoogleService-Info.plist path<commit_after>#!/usr/bin/env node
'use strict';

/**
 * This hook makes sure projects using [cordova-plugin-firebase](https://github.com/arnesson/cordova-plugin-firebase)
 * will build properly and have the required key files copied to the proper destinations when the app is build on Ionic Cloud using the package command.
 * Credits: https://github.com/arnesson.
 */
var fse = require('fs-extra');
var config = fse.readFileSync('config.xml').toString();
var name = getValue(config, 'name');

var IOS_DIR = 'platforms/ios';
var ANDROID_DIR = 'platforms/android';

var PLATFORM = {
    IOS: {
        dest: [
            IOS_DIR + '/' + name + '/Resources/GoogleService-Info.plist',
            IOS_DIR + '/' + name + '/Resources/Resources/GoogleService-Info.plist'
        ],
        src: [
            'GoogleService-Info.plist',
            IOS_DIR + '/www/GoogleService-Info.plist',
            'www/GoogleService-Info.plist'
        ]
    },
    ANDROID: {
        dest: [
            ANDROID_DIR + '/google-services.json'
        ],
        src: [
            'google-services.json',
            ANDROID_DIR + '/assets/www/google-services.json',
            'www/google-services.json'
        ],
        stringsXml: ANDROID_DIR + '/res/values/strings.xml'
    }
};

// Copy key files to their platform specific folders
if (directoryExists(IOS_DIR)) {
    copyKey(PLATFORM.IOS);
} else if (directoryExists(ANDROID_DIR)) {
    copyKey(PLATFORM.ANDROID, updateStringsXml)
}

function updateStringsXml(contents) {
    var json = JSON.parse(contents);
    var strings = fse.readFileSync(PLATFORM.ANDROID.stringsXml).toString();

    // strip non-default value
    strings = strings.replace(new RegExp('<string name="google_app_id">([^\@<]+?)</string>', 'i'), '');

    // strip non-default value
    strings = strings.replace(new RegExp('<string name="google_api_key">([^\@<]+?)</string>', 'i'), '');

    // strip empty lines
    strings = strings.replace(new RegExp('(\r\n|\n|\r)[ \t]*(\r\n|\n|\r)', 'gm'), '$1');

    // replace the default value
    strings = strings.replace(new RegExp('<string name="google_app_id">([^<]+?)</string>', 'i'), '<string name="google_app_id">' + json.client[0].client_info.mobilesdk_app_id + '</string>');

    // replace the default value
    strings = strings.replace(new RegExp('<string name="google_api_key">([^<]+?)</string>', 'i'), '<string name="google_api_key">' + json.client[0].api_key[0].current_key + '</string>');

    fse.writeFileSync(PLATFORM.ANDROID.stringsXml, strings);
}

function copyKey(platform, callback) {
    for (var i = 0; i < platform.src.length; i++) {
        var file = platform.src[i];
        if (fileExists(file)) {
            try {
                var contents = fse.readFileSync(file).toString();

                try {
                    platform.dest.forEach(function (destinationPath) {
                        var folder = destinationPath.substring(0, destinationPath.lastIndexOf('/'));
                        fse.ensureDirSync(folder);
                        fse.writeFileSync(destinationPath, contents);
                    });
                } catch (e) {
                    // skip
                }

                callback && callback(contents);
            } catch (err) {
                console.log(err)
            }

            break;
        }
    }
}

function getValue(config, name) {
    var value = config.match(new RegExp('<' + name + '>(.*?)</' + name + '>', 'i'));
    if (value && value[1]) {
        return value[1]
    } else {
        return null
    }
}

function fileExists(path) {
    try {
        return fse.statSync(path).isFile();
    } catch (e) {
        return false;
    }
}

function directoryExists(path) {
    try {
        return fse.statSync(path).isDirectory();
    } catch (e) {
        return false;
    }
}
<|endoftext|>


<commit_before>/**
 * @class Utils provides a number of utility functions which are handy
 *        around the app.
 *
 * @property {Boolean} debugMode This boolean can be changed from true to
 *           false for production mode to speed up the app.
 *
 * @constructs
 */
var Utils = Utils || {};

Utils.debugMode = true;

//Utils.couchUrl = "https://ilanguage.iriscouch.com/default";
Utils.couchUrl = "http://localhost:5984/default";
/**
 * The address of the TouchDB-Android database on the Android.
 */
Utils.touchUrl = "http://localhost:8888/db";

/**
 * The address of the PouchDB database on the browser.
 */
Utils.pouchUrl = "idb://db";

//Utils.activityFeedCouchUrl = "https://ilanguage.iriscouch.com/activity_feed";
Utils.activityFeedCouchUrl = "http://localhost:5984/activity_feed";
/**
 * The address of the TouchDB-Android database on the Android.
 * @Deprecated now using pouchUrl for all
 */
//Utils.activityFeedTouchUrl = "http://localhost:8888/activity_feed_db";

/**
 * The address of the PouchDB database on the browser.
 * @Deprecated now using pouchUrl for all
 */
//Utils.activityFeedPouchUrl = "idb://activity_feed_db";

/**
 * The url of the authentication server.
 */

//Utils.authUrl = "https://ifield.fieldlinguist.com";//"https://localhost:3001";
Utils.authUrl = "https://localhost:3001";
/**
 * The parameters of the default couch server.
 */
Utils.defaultCouchConnection = function() {
  return {
//    protocol : "https://",
//    domain : "ilanguage.iriscouch.com",
//    port : "443",
//    pouchname : "default"
//  };
    protocol : "http://",
    domain : "localhost",
    port : "5984",
    pouchname : "default"
  };
};
/**
 * A message for users if they need help which brings them to our contact us form
 */
Utils.contactUs = "Contact Us";

/**
 * Console logs out, if not on Internet Explorer. Only logs out if
 * debugMode is true.
 */
Utils.debug = function(message, secondmessage) {
	if(navigator.appName == 'Microsoft Internet Explorer') {
		return;
	}
	if(this.debugMode) {
		console.log(message);
		if(secondmessage){
	    console.log(secondmessage);
		}
	}
};

/**
 * Simple Pub/sub plugin to create a decoupled javascript app
 * http://answers.oreilly.com/topic/2190-two-examples-of-the-observer-pattern-in-javascript/
 *
 * How to use it:
var hub = {};
makePublisher(hub);

hub.subscribe(
  "probeCommand",
  function(arg) {
    debug("Receiving command " + arg);
  }, self);

hub.publish(
    "probeResponse",
"Command not valid.")

var right = document.getElementById("rightSideReading");
hub.unsubscribe('probeResponse', null, center);
hub.subscribe('probeResponse', function(arg) {
  debug("Putting probe's response in the right input field.");
  var cleanedMessage = arg.replace(/[^0-9]/g, "");
  debug("Cleaned message: " + arg + " to: " + cleanedMessage);
  right.value = cleanedMessage;
}, right);

hub.subscribe('changeLogo',function(arg){
  debug("Putting the logo from the user. This is the path: "+ arg);
  img.setAttribute("src",storage.getItem("userLogo"));
},img);
 *
 */

Utils.publisher = {
  subscribers : {
    any : []
  },
  subscribe : function(type, fn, context) {
    type = type || 'any';
    fn = typeof fn === "function" ? fn : context[fn];

    if (typeof this.subscribers[type] === "undefined") {
      this.subscribers[type] = [];
    }
    this.subscribers[type].push({
      fn : fn,
      context : context || this
    });
  },
  unsubscribe : function(type, fn, context) {
    this.visitSubscribers('unsubscribe', type, fn, context);
  },
  publish : function(type, publication) {
    this.visitSubscribers('publish', type, publication);
  },
  visitSubscribers : function(action, type, arg, context) {
    var pubtype = type || 'any', subscribers = this.subscribers[pubtype], i, max = subscribers ? subscribers.length
        : 0;

    for (i = 0; i < max; i += 1) {
      if (action === 'publish') {
        subscribers[i].fn.call(subscribers[i].context, arg);
      } else {
        if (subscribers[i].context === context) {
          subscribers.splice(i, 1);
          Utils.debug("Removed subscribers");

        } else {
          Utils.debug("Not removing subscriber" + i);

        }
      }
    }
  }
};
Utils.makePublisher = function(o) {
  var i;
  for (i in Utils.publisher) {
    if (Utils.publisher.hasOwnProperty(i)
        && typeof Utils.publisher[i] === "function") {
      o[i] = Utils.publisher[i];
    }
  }
  o.subscribers = {
    any : []
  };
};

/**
 * http://www.w3schools.com/js/js_cookies.asp
 * name of the cookie, the value of the cookie, and the number of days until the cookie expires.
 *
 * @param c_name
 * @param value
 * @param exdays
 */
Utils.setCookie = function(c_name, value, exdays){
  var exdate = new Date();
  exdate.setDate(exdate.getDate() + exdays);
  var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString());
  document.cookie = c_name + "=" + c_value;
};
Utils.getCookie = function(c_name){
  var i, x, y, ARRcookies = document.cookie.split(";");
  for (i = 0; i < ARRcookies.length; i++){
    x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
    y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
    x = x.replace(/^\s+|\s+$/g,"");
    if (x == c_name){
      return unescape(y);
    }
  }
};

/**
 * Detects whether we are running offline on an Android app.
 *
 * Note: to Android app developers, append this to your user agent string to
 * take advantage of the offline functionality of this app.
 *
 * @returns {Boolean} true if using offline Android
 */
Utils.androidApp = function() {
	return navigator.userAgent.indexOf("OfflineAndroidApp") > -1;
};

/**
 * Detects whether we are running offline in chrome extension.
 *
 * @returns {Boolean} true if using a Chrome Extension
 */
Utils.chromeApp = function() {
	return window.location.href.indexOf("chrome-extension") > -1;
};

/**
 * If not running offline on an android or in a chrome extension,
 * assume we are online.
 *
 * @returns {Boolean} true if not on offline Android or on a Chrome
 *          Extension
 */
Utils.onlineOnly = function() {
	return !this.androidApp() && !this.chromeApp();
};

Utils.hasClass = function(ele, cls) {
	return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
};

Utils.addClass = function(ele, cls) {
	if(!this.hasClass(ele, cls))
		ele.className += " " + cls;
};

Utils.removeClass = function(ele, cls) {
	if(this.hasClass(ele, cls)) {
		var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)', 'g');
		ele.className = ele.className.replace(reg, ' ');
	}
};
Utils.getVersion = function(callback) {
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('GET', 'manifest.json');
  xmlhttp.onload = function (e) {
      var manifest = JSON.parse(xmlhttp.responseText);
      callback(manifest.version);
  };
  xmlhttp.send(null);
};

<commit_msg>turning debug mode off so that the app is faster.<commit_after>/**
 * @class Utils provides a number of utility functions which are handy
 *        around the app.
 *
 * @property {Boolean} debugMode This boolean can be changed from true to
 *           false for production mode to speed up the app.
 *
 * @constructs
 */
var Utils = Utils || {};

Utils.debugMode = false;

//Utils.couchUrl = "https://ilanguage.iriscouch.com/default";
Utils.couchUrl = "http://localhost:5984/default";
/**
 * The address of the TouchDB-Android database on the Android.
 */
Utils.touchUrl = "http://localhost:8888/db";

/**
 * The address of the PouchDB database on the browser.
 */
Utils.pouchUrl = "idb://db";

//Utils.activityFeedCouchUrl = "https://ilanguage.iriscouch.com/activity_feed";
Utils.activityFeedCouchUrl = "http://localhost:5984/activity_feed";
/**
 * The address of the TouchDB-Android database on the Android.
 * @Deprecated now using pouchUrl for all
 */
//Utils.activityFeedTouchUrl = "http://localhost:8888/activity_feed_db";

/**
 * The address of the PouchDB database on the browser.
 * @Deprecated now using pouchUrl for all
 */
//Utils.activityFeedPouchUrl = "idb://activity_feed_db";

/**
 * The url of the authentication server.
 */

//Utils.authUrl = "https://ifield.fieldlinguist.com";//"https://localhost:3001";
Utils.authUrl = "https://localhost:3001";
/**
 * The parameters of the default couch server.
 */
Utils.defaultCouchConnection = function() {
  return {
//    protocol : "https://",
//    domain : "ilanguage.iriscouch.com",
//    port : "443",
//    pouchname : "default"
//  };
    protocol : "http://",
    domain : "localhost",
    port : "5984",
    pouchname : "default"
  };
};
/**
 * A message for users if they need help which brings them to our contact us form
 */
Utils.contactUs = "Contact Us";

/**
 * Console logs out, if not on Internet Explorer. Only logs out if
 * debugMode is true.
 */
Utils.debug = function(message, secondmessage) {
	if(navigator.appName == 'Microsoft Internet Explorer') {
		return;
	}
	if(this.debugMode) {
		console.log(message);
		if(secondmessage){
	    console.log(secondmessage);
		}
	}
};

/**
 * Simple Pub/sub plugin to create a decoupled javascript app
 * http://answers.oreilly.com/topic/2190-two-examples-of-the-observer-pattern-in-javascript/
 *
 * How to use it:
var hub = {};
makePublisher(hub);

hub.subscribe(
  "probeCommand",
  function(arg) {
    debug("Receiving command " + arg);
  }, self);

hub.publish(
    "probeResponse",
"Command not valid.")

var right = document.getElementById("rightSideReading");
hub.unsubscribe('probeResponse', null, center);
hub.subscribe('probeResponse', function(arg) {
  debug("Putting probe's response in the right input field.");
  var cleanedMessage = arg.replace(/[^0-9]/g, "");
  debug("Cleaned message: " + arg + " to: " + cleanedMessage);
  right.value = cleanedMessage;
}, right);

hub.subscribe('changeLogo',function(arg){
  debug("Putting the logo from the user. This is the path: "+ arg);
  img.setAttribute("src",storage.getItem("userLogo"));
},img);
 *
 */

Utils.publisher = {
  subscribers : {
    any : []
  },
  subscribe : function(type, fn, context) {
    type = type || 'any';
    fn = typeof fn === "function" ? fn : context[fn];

    if (typeof this.subscribers[type] === "undefined") {
      this.subscribers[type] = [];
    }
    this.subscribers[type].push({
      fn : fn,
      context : context || this
    });
  },
  unsubscribe : function(type, fn, context) {
    this.visitSubscribers('unsubscribe', type, fn, context);
  },
  publish : function(type, publication) {
    this.visitSubscribers('publish', type, publication);
  },
  visitSubscribers : function(action, type, arg, context) {
    var pubtype = type || 'any', subscribers = this.subscribers[pubtype], i, max = subscribers ? subscribers.length
        : 0;

    for (i = 0; i < max; i += 1) {
      if (action === 'publish') {
        subscribers[i].fn.call(subscribers[i].context, arg);
      } else {
        if (subscribers[i].context === context) {
          subscribers.splice(i, 1);
          Utils.debug("Removed subscribers");

        } else {
          Utils.debug("Not removing subscriber" + i);

        }
      }
    }
  }
};
Utils.makePublisher = function(o) {
  var i;
  for (i in Utils.publisher) {
    if (Utils.publisher.hasOwnProperty(i)
        && typeof Utils.publisher[i] === "function") {
      o[i] = Utils.publisher[i];
    }
  }
  o.subscribers = {
    any : []
  };
};

/**
 * http://www.w3schools.com/js/js_cookies.asp
 * name of the cookie, the value of the cookie, and the number of days until the cookie expires.
 *
 * @param c_name
 * @param value
 * @param exdays
 */
Utils.setCookie = function(c_name, value, exdays){
  var exdate = new Date();
  exdate.setDate(exdate.getDate() + exdays);
  var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString());
  document.cookie = c_name + "=" + c_value;
};
Utils.getCookie = function(c_name){
  var i, x, y, ARRcookies = document.cookie.split(";");
  for (i = 0; i < ARRcookies.length; i++){
    x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
    y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
    x = x.replace(/^\s+|\s+$/g,"");
    if (x == c_name){
      return unescape(y);
    }
  }
};

/**
 * Detects whether we are running offline on an Android app.
 *
 * Note: to Android app developers, append this to your user agent string to
 * take advantage of the offline functionality of this app.
 *
 * @returns {Boolean} true if using offline Android
 */
Utils.androidApp = function() {
	return navigator.userAgent.indexOf("OfflineAndroidApp") > -1;
};

/**
 * Detects whether we are running offline in chrome extension.
 *
 * @returns {Boolean} true if using a Chrome Extension
 */
Utils.chromeApp = function() {
	return window.location.href.indexOf("chrome-extension") > -1;
};

/**
 * If not running offline on an android or in a chrome extension,
 * assume we are online.
 *
 * @returns {Boolean} true if not on offline Android or on a Chrome
 *          Extension
 */
Utils.onlineOnly = function() {
	return !this.androidApp() && !this.chromeApp();
};

Utils.hasClass = function(ele, cls) {
	return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
};

Utils.addClass = function(ele, cls) {
	if(!this.hasClass(ele, cls))
		ele.className += " " + cls;
};

Utils.removeClass = function(ele, cls) {
	if(this.hasClass(ele, cls)) {
		var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)', 'g');
		ele.className = ele.className.replace(reg, ' ');
	}
};
Utils.getVersion = function(callback) {
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('GET', 'manifest.json');
  xmlhttp.onload = function (e) {
      var manifest = JSON.parse(xmlhttp.responseText);
      callback(manifest.version);
  };
  xmlhttp.send(null);
};

<|endoftext|>


<commit_before>const Mixer = require('beam-client-node');
const ws = require('ws');

let userInfo;

const client = new Mixer.Client(new Mixer.DefaultRequestRunner());

// With OAuth we don't need to log in. The OAuth Provider will attach
// the required information to all of our requests after this call.
client.use(new Mixer.OAuthProvider(client, {
    tokens: {
        access: 'Click here to get your Token!',
        expires: Date.now() + (365 * 24 * 60 * 60 * 1000)
    },
}));

// Gets the user that the Access Token we provided above belongs to.
client.request('GET', 'users/current')
.then(response => {
    userInfo = response.body;
    return new Mixer.ChatService(client).join(response.body.channel.id);
})
.then(response => {
    const body = response.body;
    return createChatSocket(userInfo.id, userInfo.channel.id, body.endpoints, body.authkey);
})
.catch(error => {
    console.error('Something went wrong.');
    console.error(error);
});

/**
 * Creates a Mixer chat socket and sets up listeners to various chat events.
 * @param {number} userId The user to authenticate as
 * @param {number} channelId The channel id to join
 * @param {string[]} endpoints An array of endpoints to connect to
 * @param {string} authkey An authentication key to connect with
 * @returns {Promise.<>}
 */
function createChatSocket (userId, channelId, endpoints, authkey) {
    // Chat connection
    const socket = new Mixer.Socket(ws, endpoints).boot();

    // Greet a joined user
    socket.on('UserJoin', data => {
        socket.call('msg', [`Hi ${data.username}! I'm pingbot! Write !ping and I will pong back!`]);
    });

    // React to our !pong command
    socket.on('ChatMessage', data => {
        if (data.message.message[0].data.toLowerCase().startsWith('!ping')) {
            socket.call('msg', [`@${data.user_name} PONG!`]);
            console.log(`Ponged ${data.user_name}`);
        }
    });

    // Handle errors
    socket.on('error', error => {
        console.error('Socket error');
        console.error(error);
    });

    return socket.auth(channelId, userId, authkey)
    .then(() => {
        console.log('Login successful');
        return socket.call('msg', ['Hi! I\'m pingbot! Write !ping and I will pong back!']);
    });
}
<commit_msg>chore(rename): adjust example for rename<commit_after>const Mixer = require('@mixer/client-node');
const ws = require('ws');

let userInfo;

const client = new Mixer.Client(new Mixer.DefaultRequestRunner());

// With OAuth we don't need to log in. The OAuth Provider will attach
// the required information to all of our requests after this call.
client.use(new Mixer.OAuthProvider(client, {
    tokens: {
        access: 'Click here to get your Token!',
        expires: Date.now() + (365 * 24 * 60 * 60 * 1000)
    },
}));

// Gets the user that the Access Token we provided above belongs to.
client.request('GET', 'users/current')
.then(response => {
    userInfo = response.body;
    return new Mixer.ChatService(client).join(response.body.channel.id);
})
.then(response => {
    const body = response.body;
    return createChatSocket(userInfo.id, userInfo.channel.id, body.endpoints, body.authkey);
})
.catch(error => {
    console.error('Something went wrong.');
    console.error(error);
});

/**
 * Creates a Mixer chat socket and sets up listeners to various chat events.
 * @param {number} userId The user to authenticate as
 * @param {number} channelId The channel id to join
 * @param {string[]} endpoints An array of endpoints to connect to
 * @param {string} authkey An authentication key to connect with
 * @returns {Promise.<>}
 */
function createChatSocket (userId, channelId, endpoints, authkey) {
    // Chat connection
    const socket = new Mixer.Socket(ws, endpoints).boot();

    // Greet a joined user
    socket.on('UserJoin', data => {
        socket.call('msg', [`Hi ${data.username}! I'm pingbot! Write !ping and I will pong back!`]);
    });

    // React to our !pong command
    socket.on('ChatMessage', data => {
        if (data.message.message[0].data.toLowerCase().startsWith('!ping')) {
            socket.call('msg', [`@${data.user_name} PONG!`]);
            console.log(`Ponged ${data.user_name}`);
        }
    });

    // Handle errors
    socket.on('error', error => {
        console.error('Socket error');
        console.error(error);
    });

    return socket.auth(channelId, userId, authkey)
    .then(() => {
        console.log('Login successful');
        return socket.call('msg', ['Hi! I\'m pingbot! Write !ping and I will pong back!']);
    });
}
<|endoftext|>


<commit_before>/**
 * OpenFB is a micro-library that lets you integrate your JavaScript application with Facebook.
 * OpenFB works for both BROWSER-BASED apps and CORDOVA/PHONEGAP apps.
 * This library has no dependency: You don't need (and shouldn't use) the Facebook SDK with this library. Whe running in
 * Cordova, you also don't need the Facebook Cordova plugin. There is also no dependency on jQuery.
 * OpenFB allows you to login to Facebook and execute any Facebook Graph API request.
 * @author Christophe Coenraets @ccoenraets
 * @version 0.5
 */
var openFB = (function () {

    var loginURL = 'https://www.facebook.com/dialog/oauth',

        logoutURL = 'https://www.facebook.com/logout.php',

    // By default we store fbtoken in sessionStorage. This can be overridden in init()
        tokenStore = window.sessionStorage,

    // The Facebook App Id. Required. Set using init().
        fbAppId,

        context = window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/")),

        baseURL = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '') + context,

    // Default OAuth redirect URL. Can be overriden in init()
        oauthRedirectURL = baseURL + '/oauthcallback.html',

    // Default Cordova OAuth redirect URL. Can be overriden in init()
        cordovaOAuthRedirectURL = "https://www.facebook.com/connect/login_success.html",

    // Default Logout redirect URL. Can be overriden in init()
        logoutRedirectURL = baseURL + '/logoutcallback.html',

    // Because the OAuth login spans multiple processes, we need to keep the login callback function as a variable
    // inside the module instead of keeping it local within the login function.
        loginCallback,

    // Indicates if the app is running inside Cordova
        runningInCordova,

    // Used in the exit event handler to identify if the login has already been processed elsewhere (in the oauthCallback function)
        loginProcessed;

    // MAKE SURE YOU INCLUDE <script src="cordova.js"></script> IN YOUR index.html, OTHERWISE runningInCordova will always by false.
    // You don't need to (and should not) add the actual cordova.js file to your file system: it will be added automatically
    // by the Cordova build process
    document.addEventListener("deviceready", function () {
        runningInCordova = true;
    }, false);

    /**
     * Initialize the OpenFB module. You must use this function and initialize the module with an appId before you can
     * use any other function.
     * @param params - init paramters
     *  appId: (Required) The id of the Facebook app,
     *  tokenStore: (optional) The store used to save the Facebook token. If not provided, we use sessionStorage.
     *  loginURL: (optional) The OAuth login URL. Defaults to https://www.facebook.com/dialog/oauth.
     *  logoutURL: (optional) The logout URL. Defaults to https://www.facebook.com/logout.php.
     *  oauthRedirectURL: (optional) The OAuth redirect URL. Defaults to [baseURL]/oauthcallback.html.
     *  cordovaOAuthRedirectURL: (optional) The OAuth redirect URL. Defaults to https://www.facebook.com/connect/login_success.html.
     *  logoutRedirectURL: (optional) The logout redirect URL. Defaults to [baseURL]/logoutcallback.html.
     *  accessToken: (optional) An already authenticated access token.
     */
    function init(params) {

        if (params.appId) {
            fbAppId = params.appId;
        } else {
            throw 'appId parameter not set in init()';
        }

        if (params.tokenStore) {
            tokenStore = params.tokenStore;
        }

        if (params.accessToken) {
            tokenStore.fbAccessToken = params.accessToken;
        }

        loginURL = params.loginURL || loginURL;
        logoutURL = params.logoutURL || logoutURL;
        oauthRedirectURL = params.oauthRedirectURL || oauthRedirectURL;
        cordovaOAuthRedirectURL = params.cordovaOAuthRedirectURL || cordovaOAuthRedirectURL;
        logoutRedirectURL = params.logoutRedirectURL || logoutRedirectURL;

    }

    /**
     * Checks if the user has logged in with openFB and currently has a session api token.
     * @param callback the function that receives the loginstatus
     */
    function getLoginStatus(callback) {
        var token = tokenStore.fbAccessToken,
            loginStatus = {};
        if (token) {
            loginStatus.status = 'connected';
            loginStatus.authResponse = {accessToken: token};
        } else {
            loginStatus.status = 'unknown';
        }
        if (callback) callback(loginStatus);
    }

    /**
     * Login to Facebook using OAuth. If running in a Browser, the OAuth workflow happens in a a popup window.
     * If running in Cordova container, it happens using the In-App Browser. Don't forget to install the In-App Browser
     * plugin in your Cordova project: cordova plugins add org.apache.cordova.inappbrowser.
     *
     * @param callback - Callback function to invoke when the login process succeeds
     * @param options - options.scope: The set of Facebook permissions requested
     * @returns {*}
     */
    function login(callback, options) {

        var loginWindow,
            startTime,
            scope = '',
            redirectURL = runningInCordova ? cordovaOAuthRedirectURL : oauthRedirectURL;

        if (!fbAppId) {
            return callback({status: 'unknown', error: 'Facebook App Id not set.'});
        }

        // Inappbrowser load start handler: Used when running in Cordova only
        function loginWindow_loadStartHandler(event) {
            var url = event.url;
            if (url.indexOf("access_token=") > 0 || url.indexOf("error=") > 0) {
                // When we get the access token fast, the login window (inappbrowser) is still opening with animation
                // in the Cordova app, and trying to close it while it's animating generates an exception. Wait a little...
                var timeout = 600 - (new Date().getTime() - startTime);
                setTimeout(function () {
                    loginWindow.close();
                }, timeout > 0 ? timeout : 0);
                oauthCallback(url);
            }
        }

        // Inappbrowser exit handler: Used when running in Cordova only
        function loginWindow_exitHandler() {
            console.log('exit and remove listeners');
            // Handle the situation where the user closes the login window manually before completing the login process
            if (loginCallback && !loginProcessed) loginCallback({status: 'user_cancelled'});
            loginWindow.removeEventListener('loadstop', loginWindow_loadStopHandler);
            loginWindow.removeEventListener('exit', loginWindow_exitHandler);
            loginWindow = null;
            console.log('done removing listeners');
        }

        if (options && options.scope) {
            scope = options.scope;
        }

        loginCallback = callback;
        loginProcessed = false;

        startTime = new Date().getTime();
        loginWindow = window.open(loginURL + '?client_id=' + fbAppId + '&redirect_uri=' + redirectURL +
            '&response_type=token&scope=' + scope, '_blank', 'location=no,clearcache=yes');

        // If the app is running in Cordova, listen to URL changes in the InAppBrowser until we get a URL with an access_token or an error
        if (runningInCordova) {
            loginWindow.addEventListener('loadstart', loginWindow_loadStartHandler);
            loginWindow.addEventListener('exit', loginWindow_exitHandler);
        }
        // Note: if the app is running in the browser the loginWindow dialog will call back by invoking the
        // oauthCallback() function. See oauthcallback.html for details.

    }

    /**
     * Called either by oauthcallback.html (when the app is running the browser) or by the loginWindow loadstart event
     * handler defined in the login() function (when the app is running in the Cordova/PhoneGap container).
     * @param url - The oautchRedictURL called by Facebook with the access_token in the querystring at the ned of the
     * OAuth workflow.
     */
    function oauthCallback(url) {
        // Parse the OAuth data received from Facebook
        var queryString,
            obj;

        loginProcessed = true;
        if (url.indexOf("access_token=") > 0) {
            queryString = url.substr(url.indexOf('#') + 1);
            obj = parseQueryString(queryString);
            tokenStore.fbAccessToken = obj['access_token'];
            if (loginCallback) loginCallback({status: 'connected', authResponse: {accessToken: obj['access_token']}});
        } else if (url.indexOf("error=") > 0) {
            queryString = url.substring(url.indexOf('?') + 1, url.indexOf('#'));
            obj = parseQueryString(queryString);
            if (loginCallback) loginCallback({status: 'not_authorized', error: obj.error});
        } else {
            if (loginCallback) loginCallback({status: 'not_authorized'});
        }
    }

    /**
     * Logout from Facebook, and remove the token.
     * IMPORTANT: For the Facebook logout to work, the logoutRedirectURL must be on the domain specified in "Site URL" in your Facebook App Settings
     *
     */
    function logout(callback) {
        var logoutWindow,
            token = tokenStore.fbAccessToken;

        /* Remove token. Will fail silently if does not exist */
        tokenStore.removeItem('fbtoken');

        if (token) {
            logoutWindow = window.open(logoutURL + '?access_token=' + token + '&next=' + logoutRedirectURL, '_blank', 'location=no,clearcache=yes');
            if (runningInCordova) {
                setTimeout(function() {
                    logoutWindow.close();
                }, 700);
            }
        }

        if (callback) {
            callback();
        }

    }

    /**
     * Lets you make any Facebook Graph API request.
     * @param obj - Request configuration object. Can include:
     *  method:  HTTP method: GET, POST, etc. Optional - Default is 'GET'
     *  path:    path in the Facebook graph: /me, /me.friends, etc. - Required
     *  params:  queryString parameters as a map - Optional
     *  success: callback function when operation succeeds - Optional
     *  error:   callback function when operation fails - Optional
     */
    function api(obj) {

        var method = obj.method || 'GET',
            params = obj.params || {},
            xhr = new XMLHttpRequest(),
            url;

        params['access_token'] = tokenStore.fbAccessToken;

        url = 'https://graph.facebook.com' + obj.path + '?' + toQueryString(params);

        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    if (obj.success) obj.success(JSON.parse(xhr.responseText));
                } else {
                    var error = xhr.responseText ? JSON.parse(xhr.responseText).error : {message: 'An error has occurred'};
                    if (obj.error) obj.error(error);
                }
            }
        };

        xhr.open(method, url, true);
        xhr.send();
    }

    /**
     * Helper function to de-authorize the app
     * @param success
     * @param error
     * @returns {*}
     */
    function revokePermissions(success, error) {
        return api({method: 'DELETE',
            path: '/me/permissions',
            success: function () {
                success();
            },
            error: error});
    }

    function parseQueryString(queryString) {
        var qs = decodeURIComponent(queryString),
            obj = {},
            params = qs.split('&');
        params.forEach(function (param) {
            var splitter = param.split('=');
            obj[splitter[0]] = splitter[1];
        });
        return obj;
    }

    function toQueryString(obj) {
        var parts = [];
        for (var i in obj) {
            if (obj.hasOwnProperty(i)) {
                parts.push(encodeURIComponent(i) + "=" + encodeURIComponent(obj[i]));
            }
        }
        return parts.join("&");
    }

    // The public API
    return {
        init: init,
        login: login,
        logout: logout,
        revokePermissions: revokePermissions,
        api: api,
        oauthCallback: oauthCallback,
        getLoginStatus: getLoginStatus
    }

}());
<commit_msg>Update openfb.js<commit_after>/**
 * OpenFB is a micro-library that lets you integrate your JavaScript application with Facebook.
 * OpenFB works for both BROWSER-BASED apps and CORDOVA/PHONEGAP apps.
 * This library has no dependency: You don't need (and shouldn't use) the Facebook SDK with this library. Whe running in
 * Cordova, you also don't need the Facebook Cordova plugin. There is also no dependency on jQuery.
 * OpenFB allows you to login to Facebook and execute any Facebook Graph API request.
 * @author Christophe Coenraets @ccoenraets
 * @version 0.5
 */
var openFB = (function () {

    var loginURL = 'https://www.facebook.com/dialog/oauth',

        logoutURL = 'https://www.facebook.com/logout.php',

    // By default we store fbtoken in sessionStorage. This can be overridden in init()
        tokenStore = window.sessionStorage,

    // The Facebook App Id. Required. Set using init().
        fbAppId,

        context = window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/")),

        baseURL = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '') + context,

    // Default OAuth redirect URL. Can be overriden in init()
        oauthRedirectURL = baseURL + '/oauthcallback.html',

    // Default Cordova OAuth redirect URL. Can be overriden in init()
        cordovaOAuthRedirectURL = "https://www.facebook.com/connect/login_success.html",

    // Default Logout redirect URL. Can be overriden in init()
        logoutRedirectURL = baseURL + '/logoutcallback.html',

    // Because the OAuth login spans multiple processes, we need to keep the login callback function as a variable
    // inside the module instead of keeping it local within the login function.
        loginCallback,

    // Indicates if the app is running inside Cordova
        runningInCordova,

    // Used in the exit event handler to identify if the login has already been processed elsewhere (in the oauthCallback function)
        loginProcessed;

    // MAKE SURE YOU INCLUDE <script src="cordova.js"></script> IN YOUR index.html, OTHERWISE runningInCordova will always by false.
    // You don't need to (and should not) add the actual cordova.js file to your file system: it will be added automatically
    // by the Cordova build process
    document.addEventListener("deviceready", function () {
        runningInCordova = true;
    }, false);

    /**
     * Initialize the OpenFB module. You must use this function and initialize the module with an appId before you can
     * use any other function.
     * @param params - init paramters
     *  appId: (Required) The id of the Facebook app,
     *  tokenStore: (optional) The store used to save the Facebook token. If not provided, we use sessionStorage.
     *  loginURL: (optional) The OAuth login URL. Defaults to https://www.facebook.com/dialog/oauth.
     *  logoutURL: (optional) The logout URL. Defaults to https://www.facebook.com/logout.php.
     *  oauthRedirectURL: (optional) The OAuth redirect URL. Defaults to [baseURL]/oauthcallback.html.
     *  cordovaOAuthRedirectURL: (optional) The OAuth redirect URL. Defaults to https://www.facebook.com/connect/login_success.html.
     *  logoutRedirectURL: (optional) The logout redirect URL. Defaults to [baseURL]/logoutcallback.html.
     *  accessToken: (optional) An already authenticated access token.
     */
    function init(params) {

        if (params.appId) {
            fbAppId = params.appId;
        } else {
            throw 'appId parameter not set in init()';
        }

        if (params.tokenStore) {
            tokenStore = params.tokenStore;
        }

        if (params.accessToken) {
            tokenStore.fbAccessToken = params.accessToken;
        }

        loginURL = params.loginURL || loginURL;
        logoutURL = params.logoutURL || logoutURL;
        oauthRedirectURL = params.oauthRedirectURL || oauthRedirectURL;
        cordovaOAuthRedirectURL = params.cordovaOAuthRedirectURL || cordovaOAuthRedirectURL;
        logoutRedirectURL = params.logoutRedirectURL || logoutRedirectURL;

    }

    /**
     * Checks if the user has logged in with openFB and currently has a session api token.
     * @param callback the function that receives the loginstatus
     */
    function getLoginStatus(callback) {
        var token = tokenStore.fbAccessToken,
            loginStatus = {};
        if (token) {
            loginStatus.status = 'connected';
            loginStatus.authResponse = {accessToken: token};
        } else {
            loginStatus.status = 'unknown';
        }
        if (callback) callback(loginStatus);
    }

    /**
     * Login to Facebook using OAuth. If running in a Browser, the OAuth workflow happens in a a popup window.
     * If running in Cordova container, it happens using the In-App Browser. Don't forget to install the In-App Browser
     * plugin in your Cordova project: cordova plugins add org.apache.cordova.inappbrowser.
     *
     * @param callback - Callback function to invoke when the login process succeeds
     * @param options - options.scope: The set of Facebook permissions requested
     * @returns {*}
     */
    function login(callback, options) {

        var loginWindow,
            startTime,
            scope = '',
            redirectURL = runningInCordova ? cordovaOAuthRedirectURL : oauthRedirectURL;

        if (!fbAppId) {
            return callback({status: 'unknown', error: 'Facebook App Id not set.'});
        }

        // Inappbrowser load start handler: Used when running in Cordova only
        function loginWindow_loadStartHandler(event) {
            var url = event.url;
            if (url.indexOf("access_token=") > 0 || url.indexOf("error=") > 0) {
                // When we get the access token fast, the login window (inappbrowser) is still opening with animation
                // in the Cordova app, and trying to close it while it's animating generates an exception. Wait a little...
                var timeout = 600 - (new Date().getTime() - startTime);
                setTimeout(function () {
                    loginWindow.close();
                }, timeout > 0 ? timeout : 0);
                oauthCallback(url);
            }
        }

        // Inappbrowser exit handler: Used when running in Cordova only
        function loginWindow_exitHandler() {
            console.log('exit and remove listeners');
            // Handle the situation where the user closes the login window manually before completing the login process
            if (loginCallback && !loginProcessed) loginCallback({status: 'user_cancelled'});
            loginWindow.removeEventListener('loadstop', loginWindow_loadStopHandler);
            loginWindow.removeEventListener('exit', loginWindow_exitHandler);
            loginWindow = null;
            console.log('done removing listeners');
        }

        if (options && options.scope) {
            scope = options.scope;
        }

        loginCallback = callback;
        loginProcessed = false;

        startTime = new Date().getTime();
        loginWindow = window.open(loginURL + '?client_id=' + fbAppId + '&redirect_uri=' + redirectURL +
            '&response_type=token&scope=' + scope, '_blank', 'location=no,clearcache=yes');

        // If the app is running in Cordova, listen to URL changes in the InAppBrowser until we get a URL with an access_token or an error
        if (runningInCordova) {
            loginWindow.addEventListener('loadstart', loginWindow_loadStartHandler);
            loginWindow.addEventListener('exit', loginWindow_exitHandler);
        }
        // Note: if the app is running in the browser the loginWindow dialog will call back by invoking the
        // oauthCallback() function. See oauthcallback.html for details.

    }

    /**
     * Called either by oauthcallback.html (when the app is running the browser) or by the loginWindow loadstart event
     * handler defined in the login() function (when the app is running in the Cordova/PhoneGap container).
     * @param url - The oautchRedictURL called by Facebook with the access_token in the querystring at the ned of the
     * OAuth workflow.
     */
    function oauthCallback(url) {
        // Parse the OAuth data received from Facebook
        var queryString,
            obj;

        loginProcessed = true;
        if (url.indexOf("access_token=") > 0) {
            queryString = url.substr(url.indexOf('#') + 1);
            obj = parseQueryString(queryString);
            tokenStore.fbAccessToken = obj['access_token'];
            if (loginCallback) loginCallback({status: 'connected', authResponse: {accessToken: obj['access_token']}});
        } else if (url.indexOf("error=") > 0) {
            queryString = url.substring(url.indexOf('?') + 1, url.indexOf('#'));
            obj = parseQueryString(queryString);
            if (loginCallback) loginCallback({status: 'not_authorized', error: obj.error});
        } else {
            if (loginCallback) loginCallback({status: 'not_authorized'});
        }
    }

    /**
     * Logout from Facebook, and remove the token.
     * IMPORTANT: For the Facebook logout to work, the logoutRedirectURL must be on the domain specified in "Site URL" in your Facebook App Settings
     *
     */
    function logout(callback) {
        var logoutWindow,
            token = tokenStore.fbAccessToken;

        /* Remove token. Will fail silently if does not exist */
        tokenStore.removeItem('fbtoken');

        if (token) {
            logoutWindow = window.open(logoutURL + '?access_token=' + token + '&next=' + logoutRedirectURL, '_blank', 'location=no,clearcache=yes');
            if (runningInCordova) {
                setTimeout(function() {
                    logoutWindow.close();
                }, 1);
            }
        }

        if (callback) {
            callback();
        }

    }

    /**
     * Lets you make any Facebook Graph API request.
     * @param obj - Request configuration object. Can include:
     *  method:  HTTP method: GET, POST, etc. Optional - Default is 'GET'
     *  path:    path in the Facebook graph: /me, /me.friends, etc. - Required
     *  params:  queryString parameters as a map - Optional
     *  success: callback function when operation succeeds - Optional
     *  error:   callback function when operation fails - Optional
     */
    function api(obj) {

        var method = obj.method || 'GET',
            params = obj.params || {},
            xhr = new XMLHttpRequest(),
            url;

        params['access_token'] = tokenStore.fbAccessToken;

        url = 'https://graph.facebook.com' + obj.path + '?' + toQueryString(params);

        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    if (obj.success) obj.success(JSON.parse(xhr.responseText));
                } else {
                    var error = xhr.responseText ? JSON.parse(xhr.responseText).error : {message: 'An error has occurred'};
                    if (obj.error) obj.error(error);
                }
            }
        };

        xhr.open(method, url, true);
        xhr.send();
    }

    /**
     * Helper function to de-authorize the app
     * @param success
     * @param error
     * @returns {*}
     */
    function revokePermissions(success, error) {
        return api({method: 'DELETE',
            path: '/me/permissions',
            success: function () {
                success();
            },
            error: error});
    }

    function parseQueryString(queryString) {
        var qs = decodeURIComponent(queryString),
            obj = {},
            params = qs.split('&');
        params.forEach(function (param) {
            var splitter = param.split('=');
            obj[splitter[0]] = splitter[1];
        });
        return obj;
    }

    function toQueryString(obj) {
        var parts = [];
        for (var i in obj) {
            if (obj.hasOwnProperty(i)) {
                parts.push(encodeURIComponent(i) + "=" + encodeURIComponent(obj[i]));
            }
        }
        return parts.join("&");
    }

    // The public API
    return {
        init: init,
        login: login,
        logout: logout,
        revokePermissions: revokePermissions,
        api: api,
        oauthCallback: oauthCallback,
        getLoginStatus: getLoginStatus
    }

}());
<|endoftext|>


<commit_before>(function(window,$){
/**
 * resizeable-x
 * @param Jquery element
 * @returns {jquery-resizeablex_L1.Resizablex}
 * @author xilei
 */
//resize handle html
var handleTpl = '

';

var resizeHandles = {
        n:function(resize){
            var resizeh = resize.h+resize.t-resize.y;
            if(resizeh<resize.options.minh){
                return ;
            }
            resize.h = resizeh;
            resize.t = resize.y;
            resize.top();
            resize.height();
        },
        e:function(resize){
            resize.w = resize.x - resize.l;
            resize.width();
        },
        s:function(resize){
            resize.h = resize.y - resize.t;
            resize.height();
        },
        w:function(resize){
            var resizew = resize.w+resize.l-resize.x;
            if(resizew < resize.options.minw){
                return ;
            }
            resize.w = resizew;
            resize.l = resize.x;
            resize.left();
            resize.width();
        },
        se:function(resize){
            this.s(resize);this.e(resize);
        },
        sw:function(resize){
            this.s(resize);this.w(resize);
        },
        ne:function(resize){
            this.n(resize);this.e(resize);
        },
        nw:function(resize){
            this.n(resize);this.w(resize);
        }
};

var _current = null;

var defaultOptions = {
    minh:10,
    minw:10,
    dragable:true
};

var Resizablex = function(element,options){
         var _pos = element.position();
         this.dom = element;
         this.w = this.dom.width();
         this.h = this.dom.height();
         this.l = _pos.left;
         this.t = _pos.top;
         this.x = 0;
         this.y = 0;
         this.options = $.extend({},defaultOptions,options);
         this.direction = null;
         this.dragoffset = null;
         this.controls = {};
         this.init();
     };

    Resizablex.prototype = {

        init:function(){
            for(var direction in resizeHandles){
                this.controls[direction] = $(handleTpl.replace('{d}',direction));
                this.dom.append(this.controls[direction]);
                this.controls[direction]
                        .bind('mousedown',{direction:direction},$.proxy(this,'_mousedown'));
            }
            if(this.options.dragable){
                this.dom.bind('mousedown',$.proxy(this,'_dragmousedown'));
            }
        },

        _mousedown:function(e){
            if(e.button===2)return false;
            e.stopPropagation();
            this.direction = e.data.direction;
            _current = this;
            return true;
        },

        width:function(value){
            if(value){
               this.w = value;
            }
            this.w = this.w < this.options.minw ? this.options.minw :this.w ;
            this.dom.width(this.w);
            return this;
        },
        height:function(value){
            if(value){
               this.h = value;
            }
            this.h = this.h < this.options.minh ? this.options.minh :this.h ;
            this.dom.height(this.h);
            return this;
        },

        left:function(value){
            if(value){
               this.l = value;
            }
            this.dom.css('left',this.l);
        },

        top:function(value){
            if(value){
               this.t = value;
            }
            this.dom.css('top',this.t);
        },

        limit:function(w,h){
            this.options.minw = w>0 ? w : 0;
            this.options.minh = h>0 ? h : 0;
        },

        //@todo disabled some direction  resize
        disabled:function(){

        },

        //@todo enabled some direction  resize
        enabled:function(){

        },

        _dragmousedown:function(e){
            if(e.button===2)return false;

            e.stopPropagation();
            this.dragoffset = {
                x:e.clientX-this.l,
                y:e.clientY-this.t
            };
            _current = this;
        },

        _dragmousemove:function(e){
            this.l = e.clientX-this.dragoffset.x;
            this.t = e.clientY-this.dragoffset.y;
            this.dom.css({'left':this.l,'top':this.t});
        }
};
//less callback
$(window.document).bind('mousemove',function(e){
    if(!_current){
        return true;
    }
    e.preventDefault();
    e.stopPropagation();
    if(_current.direction){
        _current.x = e.clientX;
        _current.y = e.clientY;
        resizeHandles[_current.direction](_current);
    }else if(_current.dragoffset){
        _current._dragmousemove(e);
    }
}).bind('mouseup',function(e){
    if(!_current){
        return true;
    }
    e.stopPropagation();
    _current.direction = null;
    _current.dragoffset = null;
    _current = null;
});

$.fn.resizeablex = function(options){
    var resizes = [];
    $.each(this,function(){
       resizes.push(new Resizablex($(this),options));
    });
    return resizes;
};

})(window,jQuery);

<commit_msg>add RaxManager & raxevents<commit_after>(function(window,$){
/**
 * resizeable-x
 *
 * events
 *       raxdragstart
 *       raxdragmove
 *       raxdragend
 *       raxmove
 *       raxstart
 *       raxend
 *
 *
 * @param Jquery element
 * @returns {jquery-resizeablex_L1.Resizablex}
 * @author xilei
 */
//resize handle html
var handleTpl = '

';

var resizeHandles = {
        n:function(resize){
            var resizeh = resize.h+resize.t-resize.y;
            if(resizeh<resize.options.minh){
                return ;
            }
            resize.h = resizeh;
            resize.t = resize.y;
            resize.top();
            resize.height();
        },
        e:function(resize){
            resize.w = resize.x - resize.l;
            resize.width();
        },
        s:function(resize){
            resize.h = resize.y - resize.t;
            resize.height();
        },
        w:function(resize){
            var resizew = resize.w+resize.l-resize.x;
            if(resizew < resize.options.minw){
                return ;
            }
            resize.w = resizew;
            resize.l = resize.x;
            resize.left();
            resize.width();
        },
        se:function(resize){
            this.s(resize);this.e(resize);
        },
        sw:function(resize){
            this.s(resize);this.w(resize);
        },
        ne:function(resize){
            this.n(resize);this.e(resize);
        },
        nw:function(resize){
            this.n(resize);this.w(resize);
        }
};

var _current = null;

var defaultOptions = {
    minh:10,
    minw:10,
    dragable:true
};

/**
 * resizeable manager
 * @type type
 */
var RaxMananer = {
    _items:{},

    guid:0,

    create:function(element,options){
        var id = element.attr('id') || 'rax_'+this.guid++ ;
        this._items[id] = new Resizablex(element,options);
        return this._items[id];
    },

    get:function(id){
        return this._items[id];
    },

    call:function(fn,params){
        var checked = false,id=null;
        for(id in this._items){
            if(!checked && $.type(this._items[id][fn]) != 'function'){
                break;
                checked = true;
            }
            this._items[id][fn](params);
        }
    }
};

var Resizablex = function(element,options){
         var _pos = element.position();
         this.dom = element;
         this.w = this.dom.width();
         this.h = this.dom.height();
         this.l = _pos.left;
         this.t = _pos.top;
         this.x = 0;
         this.y = 0;
         this.options = $.extend({},defaultOptions,options);
         this.direction = null;
         this.dragoffset = null;
         this.controls = {};
         this.init();
     };

    Resizablex.prototype = {

        init:function(){
            for(var direction in resizeHandles){
                this.controls[direction] = $(handleTpl.replace('{d}',direction));
                this.dom.append(this.controls[direction]);
                this.controls[direction]
                        .bind('mousedown',{direction:direction},$.proxy(this,'_mousedown'));
            }
            if(this.options.dragable){
                this.dom.bind('mousedown',$.proxy(this,'_dragmousedown'));
            }
        },

        _mousedown:function(e){
            if(this.dom.hasClass('raxstart')){
                return true;
            }
            if(e.button===2)return false;
            e.stopPropagation();
            this.direction = e.data.direction;
            _current = this;
            this.dom.triggerHandler($.Event('raxstart',{rax:this}));
            return true;
        },

        width:function(value){
            if(value){
               this.w = value;
            }
            this.w = this.w < this.options.minw ? this.options.minw :this.w ;
            this.dom.width(this.w);
            return this;
        },
        height:function(value){
            if(value){
               this.h = value;
            }
            this.h = this.h < this.options.minh ? this.options.minh :this.h ;
            this.dom.height(this.h);
            return this;
        },

        left:function(value){
            if(value){
               this.l = value;
            }
            this.dom.css('left',this.l);
        },

        top:function(value){
            if(value){
               this.t = value;
            }
            this.dom.css('top',this.t);
        },

        limit:function(w,h){
            this.options.minw = w>0 ? w : 0;
            this.options.minh = h>0 ? h : 0;
        },

        //@todo disabled some direction  resize
        disable:function(){
            this.dom.addClass('rax-disable');
        },

        //@todo enabled some direction  resize
        enable:function(){
            this.dom.removeClass('rax-disable');
        },

        dragdisable:function(){
            this.dom.addClass('rax-drag-disable');
        },

        dragenable:function(){
           this.dom.removeClass('rax-drag-disable');
        },

        _dragmousedown:function(e){
            if(this.dom.hasClass('rax-drag-disable')){
                return true;
            }
            if(e.button===2)return false;

            e.stopPropagation();
            this.dragoffset = {
                x:e.clientX-this.l,
                y:e.clientY-this.t
            };
            _current = this;
            this.dom.triggerHandler($.Event('raxdragstart',{rax:this}));
        },

        _dragmousemove:function(e){
            this.l = e.clientX-this.dragoffset.x;
            this.t = e.clientY-this.dragoffset.y;
            this.dom.css({'left':this.l,'top':this.t});
        }
};
//less callback
$(window.document).bind('mousemove',function(e){
    if(!_current){
        return true;
    }
    e.preventDefault();
    e.stopPropagation();
    if(_current.direction){
        _current.x = e.clientX;
        _current.y = e.clientY;
        resizeHandles[_current.direction](_current);
        _current.dom.triggerHandler($.Event('raxmove',{rax:_current}));
    }else if(_current.dragoffset){
        _current._dragmousemove(e);
        _current.dom.triggerHandler($.Event('raxdragmove',{rax:_current}));
    }
}).bind('mouseup',function(e){
    if(!_current){
        return true;
    }
    e.stopPropagation();
    if(_current.direction){
        _current.dom.triggerHandler($.Event('raxend',{rax:_current}));
        _current.direction = null;
    }else if(_current.dragoffset){
        _current.dom.triggerHandler($.Event('raxdragend',{rax:_current}));
         _current.dragoffset = null;
    }
    _current = null;
});

/**
 * options object see defaultOptions
 *         string disable|enable|dragdisable|dragenable
 * @returns jquery instance
 */
$.fn.resizeablex = function(options){
    if($.type(options) == 'string' && $.inArray(options,['disable','enable','dragenable','dragdisable'])!=-1){
        RaxMananer.call(options);
    }else{
        this.each(function(){
          RaxMananer.create($(this),options);
        });
    }
    return this;
};

})(window,jQuery);

<|endoftext|>