<commit_before>/*
* @Author: huhuaquan
* @Date:   2016-04-20 10:18:53
* @Last Modified by:   HectorHu
* @Last Modified time: 2016-04-25 21:27:33
*/
$(function() {
	var winResult = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]],
		userPlayer,
		computerPlayer,
		panel = [[0,0,0], [0,0,0], [0,0,0]],
		running = false,
		computerWin = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]],
		userWin = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]],
		firstPos = 4,
		computerVal = 1,
		userVal = -1,
		panelSize = 3,
		computerFirst;

	var Tictactoe = function() {};

	function getPosition(className) {
		return className.split(' ')[1].split('-')[1];
	}

	function oneWin() {
		for(var i = 0; i < winResult.length; i++) {
			var tmpCount = 0;
			for(var j = 0; j < winResult[i].length; j++) {
				var pos = winResult[i][j];
				if(parseInt(panel[getX(pos)][getY(pos)]) == computerVal) {
					++tmpCount;
				}
			}
			if(tmpCount === panelSize) {
				return true;
			}
		}

		return false;
	}

	function tied() {
		var dropCount = 0;
		for(var i = 0; i < panelSize; i++) {
			for(var j = 0; j < panelSize; j++) {
				if(parseInt(panel[i][j]) !== 0) {
					++dropCount;
				}
			}
		}

		return dropCount === 9;
	}

	function updatePanel(pos, val) {
		var x = getX(pos),
			y = getY(pos),
			player = (val == computerVal) ? computerPlayer : userPlayer;
		panel[x][y] = val;
		$(".grid-" + pos).html(player);
		updatePossibleWin(pos, val);
		if(oneWin()) {
			var winner = (val == computerVal) ? "Computer" : "You";
			if(confirm("Winner : " + winner + ".再来一局?")) {
				return window.location.reload();
			}
		} else if(tied()) {
			if(confirm("平局.再来一局?")) {
				return location.reload();
			}
		}
	}

	function updatePossibleWin(pos, val) {
		if(val == -1) {
			$.each(computerWin, function(index, subArr) {
				if($.inArray(parseInt(pos), subArr) !== -1) {
					computerWin[index] = undefined;
				}
			});
			computerWin = computerWin.filter(function(item) {
				return item !== undefined;
			});
		} else {
			$.each(userWin, function(index, subArr) {
				if($.inArray(parseInt(pos), subArr) !== -1) {
					userWin[index] = undefined;
				}
			});
			userWin = userWin.filter(function(item) {
				return item !== undefined;
			});
		}
	}

	function canAttack() {
		//是否可以攻击
		for(var i = 0; i < computerWin.length; i++) {
			if(computerOneEmpty(computerWin[i])) {
				return true;
			}
		}

		return false;
	}

	function userOneEmpty(winArr) {
		var emptyCount = 0;
		for(var i = 0; i < winArr.length; i++) {
			var pos = winArr[i];
			if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
				++emptyCount;
			}
		}
		return (emptyCount === 1);
	}

	function needDefend() {
		//是否需要防护
		for(var i = 0; i < userWin.length; i++) {
			if(userOneEmpty(userWin[i])) {
				return true;
			}
		}

		return false;
	}

	function findDefendPos() {
		for(var i = 0; i < userWin.length; i++) {
			if(userOneEmpty(userWin[i])) {
				for(var j = 0; j < userWin[i].length; j++) {
					var pos = userWin[i][j];
					if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
						return pos;
					}
				}
			}
		}
	}

	function computerOneEmpty(winArr) {
		var emptyCount = 0;
		for(var i = 0; i < winArr.length; i++) {
			var pos = winArr[i];
			if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
				++emptyCount;
			}
		}
		return (emptyCount === 1);
	}

	function findAttackPos() {
		var emptyCount = 0;
		for(var i = 0; i < computerWin.length; i++) {
			if(computerOneEmpty(computerWin[i])) {
				for(var j = 0; j < computerWin[i].length; j++) {
					var pos = computerWin[i][j];
					if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
						return pos;
					}
				}
			}
		}
	}

	function firstStep() {
		//第一步
		return !running;
	}

	function getY(pos) {
		return pos % panelSize;
	}

	function getX(pos) {
		return Math.floor(pos / panelSize);
	}

	function hasEmpty(winArr) {
		var emptyCount = 0;
		for(var i = 0; i < winArr.length; i++) {
			var pos = winArr[i];
			if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
				++emptyCount;
			}
		}
		return (emptyCount > 0);
	}

	function findEmptyPos() {
		var emptyCount = 0;
		for(var i = 0; i < computerWin.length; i++) {
			if(hasEmpty(computerWin[i])) {
				for(var j = 0; j < computerWin[i].length; j++) {
					var pos = computerWin[i][j];
					if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
						return pos;
					}
				}
			}
		}

		for(var i = 0; i < panelSize; i++) {
			for(var j = 0; j < panelSize; j++) {
				if(panel[i][j] == 0) {
					return i * 3 + j;
				}
			}
		}
	}

	function setPlayer(btn) {
		userPlayer = btn.html();
		computerPlayer = userPlayer === 'X' ? 'O' : 'X';
		$(".choose-player").css('display', 'none');
		$(".choose-first").css('display', 'block');
	}

	function special() {
		if(panel[0][0] == panel[2][2] && panel[0][0] == userVal
			|| panel[0][2] == panel[2][0] && panel[0][2] == userVal) {
			return true;
		} else {
			return false;
		}
	}

	function findSpecialPos() {
		if(parseInt(panel[0][1]) == 0) {
			return 1;
		} else {
			return 7;
		}
	}

	Tictactoe.prototype = {
		init: function() {
			var self = this;
			$(".xobtn").click(function() {
				setPlayer($(this));
	        });
	        $(".firstbtn").click(function() {
	        	computerFirst = ($(this).attr('id') == 'computer');
	        	$(".bg").css('display', 'none');
	        	$(".choose-panel").css('display', 'none');
	        	if(computerFirst === true) {
	        		self.play();
	        	} else {
	        		running = true;
	        	}
	        });
	        $(".grid").click(function() {
				$(this).html(userPlayer);
				updatePanel(parseInt(getPosition($(this).attr('class'))), userVal);
				self.play();
			});
		},
		play: function() {
			if(canAttack()) {
				console.log("attack");
				var attackPos = findAttackPos();
				updatePanel(attackPos, computerVal);
			} else if(needDefend()) {
				console.log("defend");
				var defendPos = findDefendPos();
				updatePanel(defendPos, computerVal);
			} else if(firstStep()) {
				console.log("first");
	            updatePanel(firstPos, computerVal);
	            running = true;
			} else {
				console.log("other");
				if(panel[1][1] == 0) {
					updatePanel(firstPos, computerVal);
					return;
				}
				if(special()) {
					console.log('special');
					var pos = findSpecialPos();
					updatePanel(pos, computerVal);
					return;
				}
				var random = Math.floor(Math.random() * 2);
				if(panel[0][0] == 0 && panel[2][2] == 0) {
					var pos = (random == 0) ? 0 : 8;
					updatePanel(pos, computerVal);
				} else if(panel[0][2] == 0 && panel[2][0] == 0) {
					var pos = (random == 0) ? 2: 6;
					updatePanel(pos, computerVal);
				} else {
					var otherPos = findEmptyPos();
					updatePanel(otherPos, computerVal);
				}
			}
		}
	};

	var ttt = new Tictactoe();
	ttt.init();
});<commit_msg>fix bug#1<commit_after>/*
* @Author: huhuaquan
* @Date:   2016-04-20 10:18:53
* @Last Modified by:   huhuaquan
* @Last Modified time: 2016-05-03 15:30:05
*/
$(function() {
	var winResult = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]],
		userPlayer,
		computerPlayer,
		panel = [[0,0,0], [0,0,0], [0,0,0]],
		running = false,
		computerWin = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]],
		userWin = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]],
		firstPos = 4,
		computerVal = 1,
		userVal = -1,
		panelSize = 3,
		computerFirst,
		end = false;

	var Tictactoe = function() {};

	function getPosition(className) {
		return className.split(' ')[1].split('-')[1];
	}

	function oneWin(val) {
		for(var i = 0; i < winResult.length; i++) {
			var tmpCount = 0;
			for(var j = 0; j < winResult[i].length; j++) {
				var pos = winResult[i][j];
				if(parseInt(panel[getX(pos)][getY(pos)]) == val) {
					++tmpCount;
				}
			}
			if(tmpCount === panelSize) {
				return true;
			}
		}

		return false;
	}

	function tied() {
		var dropCount = 0;
		for(var i = 0; i < panelSize; i++) {
			for(var j = 0; j < panelSize; j++) {
				if(parseInt(panel[i][j]) !== 0) {
					++dropCount;
				}
			}
		}

		return dropCount === 9;
	}

	function updatePanel(pos, val) {
		var x = getX(pos),
			y = getY(pos),
			player = (val == computerVal) ? computerPlayer : userPlayer;
		panel[x][y] = val;
		$(".grid-" + pos).html(player);
		updatePossibleWin(pos, val);
		if(oneWin(val)) {
			end = true;
			var winner = (val == computerVal) ? "Computer" : "You";
			if(confirm("Winner : " + winner + ".再来一局?")) {
				return window.location.reload();
			}
		} else if(tied()) {
			end = true;
			if(confirm("平局.再来一局?")) {
				return location.reload();
			}
		}
	}

	function updatePossibleWin(pos, val) {
		if(val == -1) {
			$.each(computerWin, function(index, subArr) {
				if($.inArray(parseInt(pos), subArr) !== -1) {
					computerWin[index] = undefined;
				}
			});
			computerWin = computerWin.filter(function(item) {
				return item !== undefined;
			});
		} else {
			$.each(userWin, function(index, subArr) {
				if($.inArray(parseInt(pos), subArr) !== -1) {
					userWin[index] = undefined;
				}
			});
			userWin = userWin.filter(function(item) {
				return item !== undefined;
			});
		}
	}

	function canAttack() {
		//是否可以攻击
		for(var i = 0; i < computerWin.length; i++) {
			if(computerOneEmpty(computerWin[i])) {
				return true;
			}
		}

		return false;
	}

	function userOneEmpty(winArr) {
		var emptyCount = 0;
		for(var i = 0; i < winArr.length; i++) {
			var pos = winArr[i];
			if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
				++emptyCount;
			}
		}
		return (emptyCount === 1);
	}

	function needDefend() {
		//是否需要防护
		for(var i = 0; i < userWin.length; i++) {
			if(userOneEmpty(userWin[i])) {
				return true;
			}
		}

		return false;
	}

	function findDefendPos() {
		for(var i = 0; i < userWin.length; i++) {
			if(userOneEmpty(userWin[i])) {
				for(var j = 0; j < userWin[i].length; j++) {
					var pos = userWin[i][j];
					if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
						return pos;
					}
				}
			}
		}
	}

	function computerOneEmpty(winArr) {
		var emptyCount = 0;
		for(var i = 0; i < winArr.length; i++) {
			var pos = winArr[i];
			if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
				++emptyCount;
			}
		}
		return (emptyCount === 1);
	}

	function findAttackPos() {
		var emptyCount = 0;
		for(var i = 0; i < computerWin.length; i++) {
			if(computerOneEmpty(computerWin[i])) {
				for(var j = 0; j < computerWin[i].length; j++) {
					var pos = computerWin[i][j];
					if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
						return pos;
					}
				}
			}
		}
	}

	function firstStep() {
		//第一步
		return !running;
	}

	function getY(pos) {
		return pos % panelSize;
	}

	function getX(pos) {
		return Math.floor(pos / panelSize);
	}

	function hasEmpty(winArr) {
		var emptyCount = 0;
		for(var i = 0; i < winArr.length; i++) {
			var pos = winArr[i];
			if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
				++emptyCount;
			}
		}
		return (emptyCount > 0);
	}

	function findEmptyPos() {
		var emptyCount = 0;
		for(var i = 0; i < computerWin.length; i++) {
			if(hasEmpty(computerWin[i])) {
				for(var j = 0; j < computerWin[i].length; j++) {
					var pos = computerWin[i][j];
					if(parseInt(panel[getX(pos)][getY(pos)]) === 0) {
						return pos;
					}
				}
			}
		}

		for(var i = 0; i < panelSize; i++) {
			for(var j = 0; j < panelSize; j++) {
				if(panel[i][j] == 0) {
					return i * 3 + j;
				}
			}
		}
	}

	function setPlayer(btn) {
		userPlayer = btn.html();
		computerPlayer = userPlayer === 'X' ? 'O' : 'X';
		$(".choose-player").css('display', 'none');
		$(".choose-first").css('display', 'block');
	}

	function special() {
		if(panel[0][0] == panel[2][2] && panel[0][0] == userVal
			|| panel[0][2] == panel[2][0] && panel[0][2] == userVal) {
			return true;
		} else {
			return false;
		}
	}

	function findSpecialPos() {
		if(parseInt(panel[0][1]) == 0) {
			return 1;
		} else {
			return 7;
		}
	}

	Tictactoe.prototype = {
		init: function() {
			var self = this;
			$(".xobtn").click(function() {
				setPlayer($(this));
	        });
	        $(".firstbtn").click(function() {
	        	computerFirst = ($(this).attr('id') == 'computer');
	        	$(".bg").css('display', 'none');
	        	$(".choose-panel").css('display', 'none');
	        	if(computerFirst === true) {
	        		self.play();
	        	} else {
	        		running = true;
	        	}
	        });
	        $(".grid").click(function() {
				$(this).html(userPlayer);
				updatePanel(parseInt(getPosition($(this).attr('class'))), userVal);
				if(end === false)
					self.play();
			});
		},
		play: function() {
			if(canAttack()) {
				console.log("attack");
				var attackPos = findAttackPos();
				updatePanel(attackPos, computerVal);
			} else if(needDefend()) {
				console.log("defend");
				var defendPos = findDefendPos();
				updatePanel(defendPos, computerVal);
			} else if(firstStep()) {
				console.log("first");
	            updatePanel(firstPos, computerVal);
	            running = true;
			} else {
				console.log("other");
				if(panel[1][1] == 0) {
					updatePanel(firstPos, computerVal);
					return;
				}
				if(special()) {
					console.log('special');
					var pos = findSpecialPos();
					updatePanel(pos, computerVal);
					return;
				}
				var random = Math.floor(Math.random() * 2);
				if(panel[0][0] == 0 && panel[2][2] == 0) {
					var pos = (random == 0) ? 0 : 8;
					updatePanel(pos, computerVal);
				} else if(panel[0][2] == 0 && panel[2][0] == 0) {
					var pos = (random == 0) ? 2: 6;
					updatePanel(pos, computerVal);
				} else {
					var otherPos = findEmptyPos();
					updatePanel(otherPos, computerVal);
				}
			}
		}
	};

	var ttt = new Tictactoe();
	ttt.init();
});<|endoftext|>


<commit_before>var customer = module.exports = {};
var Joi = require('joi');
var Org = require('../agents/org');
var User = require('../models/user');
var Customer = require('../agents/customer');
var P = require('bluebird');
var utils = require('../lib/utils');
var validate = require('validate-npm-package-name');
var invalidUserName = require('npm-user-validate').username;

var _ = require('lodash');

customer.getBillingInfo = function(request, reply) {

  var opts = {
    title: 'Billing',
    updated: ('updated' in request.query),
    canceled: ('canceled' in request.query),
    stripePublicKey: process.env.STRIPE_PUBLIC_KEY
  };

  // Display a message to unpaid collaborators about the
  // package they could be accessing if they paid for it
  if (request.query.package) {
    opts.package = request.query.package;
  }

  var stripeDataErrorHandler = function(err) {
    if (err.statusCode === 404) {
      return null;
    } else {
      throw err;
    }
  };

  var stripeDataPromise = request.customer.getStripeData()
    .catch(stripeDataErrorHandler);

  var getByIdPromise = request.customer.getById(request.loggedInUser.email)
    .catch(stripeDataErrorHandler);

  var customerStripeData = P.join(stripeDataPromise, getByIdPromise, function(stripeCustomer, licenseApiCustomer) {
    if (stripeCustomer && licenseApiCustomer) {
      stripeCustomer.customer_id = licenseApiCustomer.stripe_customer_id;
    }

    return {
      customer: stripeCustomer
    };
  });

  var customerSubscriptions = request.customer.getSubscriptions()
    .catch(function(err) {
      request.logger.error('unable to get subscriptions for ' + request.loggedInUser.name);
      request.logger.error(err);
      return [];
    }).then(function(subs) {

    var privateModules = [],
      orgs = [];

    subs.forEach(function(sub) {
      sub.cost = (sub.amount / 100) * sub.quantity;
      if (sub.privateModules) {
        privateModules.push(sub);
      } else {
        orgs.push(sub);
      }
    });

    opts.totalCost = subs.map(function(sub) {
      return sub.cost;
    }).reduce(function(prev, curr) {
      return prev + curr;
    }, 0);

    return {
      privateModules: privateModules,
      orgs: orgs
    };
  });

  var onSuccess = function(opts) {
    return reply.view('user/billing', opts);
  };

  var onError = function(err) {
    request.logger.error(err);
    return reply.view('errors/internal', err).code(500);
  };

  P.join(customerStripeData, customerSubscriptions, function(customer, subscriptions) {
    var addopts = [customer, subscriptions];

    addopts.forEach(function(e) {
      _.extend(opts, e);
    });

    return opts;
  })
    .then(onSuccess, onError);
};

customer.updateBillingInfo = function(request, reply, callback) {
  var sendToHubspot = request.server.methods.npme.sendData;

  var coupon = request.payload.coupon;

  var billingInfo = {
    name: request.loggedInUser.name,
    email: request.loggedInUser.email,
    card: request.payload.stripeToken,
  };

  if (coupon) {
    billingInfo.coupon = coupon.toLowerCase();
  }

  request.customer.updateBilling(billingInfo, function(err) {
    var opts = {};

    if (err) {
      opts.errors = [];
      opts.errors.push(new Error(err));
      return reply.view('user/billing', opts);
    }

    var data = {
      hs_context: {
        pageName: "customer-billing-update",
        ipAddress: utils.getUserIP(request)
      },
      email: billingInfo.email
    };

    sendToHubspot(process.env.HUBSPOT_FORM_PRIVATE_NPM_SIGNUP, data, function(er) {
      if (er) {
        request.logger.error('unable to send billing email to HubSpot');
        request.logger.error(er);
      }

      if (callback) {
        return callback(er);
      }

      return reply.redirect('/settings/billing?updated=1');
    });
  });

};

customer.deleteBillingInfo = function(request, reply) {

  request.customer.del(function(err, customer) {
    if (err) {
      request.logger.error("unable to delete billing info for " + customer);
      request.logger.error(err);
      return reply.view('errors/internal').code(500);
    }
    return reply.redirect('/settings/billing?canceled=1');
  });
};

var plans = {
  private_modules: 'npm-paid-individual-user-7',
  orgs: 'npm-paid-org-7'
};

var subscriptionSchema = {
  planType: Joi.string().valid(Object.keys(plans)).required(),
  stripeToken: Joi.string(),
  coupon: Joi.string().optional().allow(''),
  "human-name": Joi.string().optional().allow(''),
  orgScope: Joi.string().when('planType', {
    is: 'orgs',
    then: Joi.required()
  }),
  "new-user": Joi.string().optional(),
  "paid-org-type": Joi.string().optional(),
  "card-number": Joi.string().optional(),
  "card-cvc": Joi.string().optional(),
  "card-exp-month": Joi.string().optional(),
  "card-exp-year": Joi.string().optional()
};

customer.subscribe = function(request, reply) {
  var loggedInUser = request.loggedInUser.name;

  Joi.validate(request.payload, subscriptionSchema, function(err, planData) {
    if (err) {
      var notices;

      if (planData.planType === 'orgs') {
        notices = err.details.map(function(e) {
          return e.message;
        });

        return reply.view('org/create', {
          stripePublicKey: process.env.STRIPE_PUBLIC_KEY,
          notices: notices
        });
      } else {
        notices = err.details.map(function(e) {
          return P.reject(e.message);
        });

        return request.saveNotifications(notices).then(function(token) {
          return reply.redirect('/settings/billing' + (token ? '?notice=' + token : ''));
        }).catch(function(err) {
          request.logger.error(err);
        });
      }

    }

    var planType = planData.planType;
    var planInfo = {
      plan: plans[planType]
    };

    if (request.loggedInUser.customer) {
      return subscribe();
    } else {
      return customer.updateBillingInfo(request, reply, subscribe);
    }

    function subscribe() {
      if (planType === 'orgs') {
        return subscribeToOrg();
      } else {
        return request.customer.createSubscription(planInfo, function(err, subscriptions) {
          if (err) {
            request.logger.error("unable to update subscription to " + planInfo.plan);
            request.logger.error(err);
          }

          if (typeof subscriptions === 'string') {
            request.logger.info("created subscription: ", planInfo);
          }

          User.new(request).dropCache(request.loggedInUser.name, function(err) {
            if (err) {
              request.logger.error(err);
              return reply.view('errors/internal', err);
            }
            return reply.redirect('/settings/billing?updated=1');
          });

        });
      }
    }

    function subscribeToOrg() {

      var newUser = planData['new-user'];

      if (newUser && invalidUserName(newUser)) {
        var err = new Error("User name must be valid");
        request.logger.error(err);
        return request.saveNotifications([
          P.reject(err.message)
        ]).then(function(token) {
          var url = '/org/transfer-user-name';
          var param = token ? "?notice=" + token : "";
          param = param + "&orgScope=" + request.query.orgScope;
          url = url + param;
          return reply.redirect(url);
        }).catch(function(err) {
          request.logger.error(err);
        });
      }

      // check if the org name works as a package name
      var valid = validate('@' + planData.orgScope + '/foo');

      if (!valid.errors) {
        // now check if the org name works on its own
        valid = validate(planData.orgScope);
      }

      if (valid.errors) {
        return reply.view('org/create', {
          stripePublicKey: process.env.STRIPE_PUBLIC_KEY,
          notices: valid.errors
        });
      }

      Org(loggedInUser)
        .get(planData.orgScope).then(function() {
        var err = new Error("Org already exists");
        err.isUserError = true;
        throw err;
      }).catch(function(err) {
        if (err.statusCode !== 404) {
          throw err;
        }

        // org doesn't yet exist, transfer user then create org
        var start = newUser ? User.new(request).toOrg(loggedInUser, newUser) : P.resolve(null);

        return start.then(function(newUserData) {
          var setSession = P.promisify(request.server.methods.user.setSession(request));
          var delSession = P.promisify(request.server.methods.user.delSession(request));
          loggedInUser = newUserData ? newUser : loggedInUser;

          if (newUserData) {
            return delSession(request.loggedInUser)
              .then(function() {
                request.logger.info("setting session to: " + loggedInUser);
                return setSession({
                  name: loggedInUser
                });
              })
          } else {
            return Org(loggedInUser)
              .create({
                scope: planData.orgScope,
                humanName: planData["human-name"]
              });
          }
        }).then(function() {
          planInfo.npm_org = planData.orgScope;
          return Customer(loggedInUser).createSubscription(planInfo)
            .tap(function(subscription) {
              if (typeof subscription === 'string') {
                request.logger.info("created subscription: ", planInfo);
              }
              return new P(function(accept, reject) {
                User.new(request).dropCache(loggedInUser, function(err) {
                  if (err) {
                    request.logger.error(err);
                    return reject(err);
                  }
                  return accept();
                });
              });
            }).then(function(subscription) {
            return Customer(loggedInUser).extendSponsorship(subscription.license_id, loggedInUser);
          }).then(function(extendedSponsorship) {
            return Customer(loggedInUser).acceptSponsorship(extendedSponsorship.verification_key);
          }).then(function() {
            return reply.redirect('/org/' + planData.orgScope);
          });
        })
          .catch(function(err) {
            request.logger.error(err);
            throw err;
          });
      }).catch(function(err) {
        request.logger.error(err);

        if (err.isUserError) {
          return reply.view('org/create', {
            stripePublicKey: process.env.STRIPE_PUBLIC_KEY,
            notices: [err]
          });
        } else if (err.statusCode === 409 && err.message) {
          return reply.view('org/create', {
            stripePublicKey: process.env.STRIPE_PUBLIC_KEY,
            inUseError: true,
            orgScope: planData.orgScope,
            humanName: planData["human-name"],
            notices: [err]
          });
        } else {
          return reply.view('errors/internal', err).code(500);
        }
      });
    }
  });
};
<commit_msg>Refactor isUserError out for code + what<commit_after>var customer = module.exports = {};
var Joi = require('joi');
var Org = require('../agents/org');
var User = require('../models/user');
var Customer = require('../agents/customer');
var P = require('bluebird');
var utils = require('../lib/utils');
var validate = require('validate-npm-package-name');
var invalidUserName = require('npm-user-validate').username;

var _ = require('lodash');

customer.getBillingInfo = function(request, reply) {

  var opts = {
    title: 'Billing',
    updated: ('updated' in request.query),
    canceled: ('canceled' in request.query),
    stripePublicKey: process.env.STRIPE_PUBLIC_KEY
  };

  // Display a message to unpaid collaborators about the
  // package they could be accessing if they paid for it
  if (request.query.package) {
    opts.package = request.query.package;
  }

  var stripeDataErrorHandler = function(err) {
    if (err.statusCode === 404) {
      return null;
    } else {
      throw err;
    }
  };

  var stripeDataPromise = request.customer.getStripeData()
    .catch(stripeDataErrorHandler);

  var getByIdPromise = request.customer.getById(request.loggedInUser.email)
    .catch(stripeDataErrorHandler);

  var customerStripeData = P.join(stripeDataPromise, getByIdPromise, function(stripeCustomer, licenseApiCustomer) {
    if (stripeCustomer && licenseApiCustomer) {
      stripeCustomer.customer_id = licenseApiCustomer.stripe_customer_id;
    }

    return {
      customer: stripeCustomer
    };
  });

  var customerSubscriptions = request.customer.getSubscriptions()
    .catch(function(err) {
      request.logger.error('unable to get subscriptions for ' + request.loggedInUser.name);
      request.logger.error(err);
      return [];
    }).then(function(subs) {

    var privateModules = [],
      orgs = [];

    subs.forEach(function(sub) {
      sub.cost = (sub.amount / 100) * sub.quantity;
      if (sub.privateModules) {
        privateModules.push(sub);
      } else {
        orgs.push(sub);
      }
    });

    opts.totalCost = subs.map(function(sub) {
      return sub.cost;
    }).reduce(function(prev, curr) {
      return prev + curr;
    }, 0);

    return {
      privateModules: privateModules,
      orgs: orgs
    };
  });

  var onSuccess = function(opts) {
    return reply.view('user/billing', opts);
  };

  var onError = function(err) {
    request.logger.error(err);
    return reply.view('errors/internal', err).code(500);
  };

  P.join(customerStripeData, customerSubscriptions, function(customer, subscriptions) {
    var addopts = [customer, subscriptions];

    addopts.forEach(function(e) {
      _.extend(opts, e);
    });

    return opts;
  })
    .then(onSuccess, onError);
};

customer.updateBillingInfo = function(request, reply, callback) {
  var sendToHubspot = request.server.methods.npme.sendData;

  var coupon = request.payload.coupon;

  var billingInfo = {
    name: request.loggedInUser.name,
    email: request.loggedInUser.email,
    card: request.payload.stripeToken,
  };

  if (coupon) {
    billingInfo.coupon = coupon.toLowerCase();
  }

  request.customer.updateBilling(billingInfo, function(err) {
    var opts = {};

    if (err) {
      opts.errors = [];
      opts.errors.push(new Error(err));
      return reply.view('user/billing', opts);
    }

    var data = {
      hs_context: {
        pageName: "customer-billing-update",
        ipAddress: utils.getUserIP(request)
      },
      email: billingInfo.email
    };

    sendToHubspot(process.env.HUBSPOT_FORM_PRIVATE_NPM_SIGNUP, data, function(er) {
      if (er) {
        request.logger.error('unable to send billing email to HubSpot');
        request.logger.error(er);
      }

      if (callback) {
        return callback(er);
      }

      return reply.redirect('/settings/billing?updated=1');
    });
  });

};

customer.deleteBillingInfo = function(request, reply) {

  request.customer.del(function(err, customer) {
    if (err) {
      request.logger.error("unable to delete billing info for " + customer);
      request.logger.error(err);
      return reply.view('errors/internal').code(500);
    }
    return reply.redirect('/settings/billing?canceled=1');
  });
};

var plans = {
  private_modules: 'npm-paid-individual-user-7',
  orgs: 'npm-paid-org-7'
};

var subscriptionSchema = {
  planType: Joi.string().valid(Object.keys(plans)).required(),
  stripeToken: Joi.string(),
  coupon: Joi.string().optional().allow(''),
  "human-name": Joi.string().optional().allow(''),
  orgScope: Joi.string().when('planType', {
    is: 'orgs',
    then: Joi.required()
  }),
  "new-user": Joi.string().optional(),
  "paid-org-type": Joi.string().optional(),
  "card-number": Joi.string().optional(),
  "card-cvc": Joi.string().optional(),
  "card-exp-month": Joi.string().optional(),
  "card-exp-year": Joi.string().optional()
};

customer.subscribe = function(request, reply) {
  var loggedInUser = request.loggedInUser.name;

  Joi.validate(request.payload, subscriptionSchema, function(err, planData) {
    if (err) {
      var notices;

      if (planData.planType === 'orgs') {
        notices = err.details.map(function(e) {
          return e.message;
        });

        return reply.view('org/create', {
          stripePublicKey: process.env.STRIPE_PUBLIC_KEY,
          notices: notices
        });
      } else {
        notices = err.details.map(function(e) {
          return P.reject(e.message);
        });

        return request.saveNotifications(notices).then(function(token) {
          return reply.redirect('/settings/billing' + (token ? '?notice=' + token : ''));
        }).catch(function(err) {
          request.logger.error(err);
        });
      }

    }

    var planType = planData.planType;
    var planInfo = {
      plan: plans[planType]
    };

    if (request.loggedInUser.customer) {
      return subscribe();
    } else {
      return customer.updateBillingInfo(request, reply, subscribe);
    }

    function subscribe() {
      if (planType === 'orgs') {
        return subscribeToOrg();
      } else {
        return request.customer.createSubscription(planInfo, function(err, subscriptions) {
          if (err) {
            request.logger.error("unable to update subscription to " + planInfo.plan);
            request.logger.error(err);
          }

          if (typeof subscriptions === 'string') {
            request.logger.info("created subscription: ", planInfo);
          }

          User.new(request).dropCache(request.loggedInUser.name, function(err) {
            if (err) {
              request.logger.error(err);
              return reply.view('errors/internal', err);
            }
            return reply.redirect('/settings/billing?updated=1');
          });

        });
      }
    }

    function subscribeToOrg() {

      var newUser = planData['new-user'];

      if (newUser && invalidUserName(newUser)) {
        var err = new Error("User name must be valid");
        request.logger.error(err);
        return request.saveNotifications([
          P.reject(err.message)
        ]).then(function(token) {
          var url = '/org/transfer-user-name';
          var param = token ? "?notice=" + token : "";
          param = param + "&orgScope=" + request.query.orgScope;
          url = url + param;
          return reply.redirect(url);
        }).catch(function(err) {
          request.logger.error(err);
        });
      }

      // check if the org name works as a package name
      var valid = validate('@' + planData.orgScope + '/foo');

      if (!valid.errors) {
        // now check if the org name works on its own
        valid = validate(planData.orgScope);
      }

      if (valid.errors) {
        return reply.view('org/create', {
          stripePublicKey: process.env.STRIPE_PUBLIC_KEY,
          notices: valid.errors
        });
      }

      Org(loggedInUser)
        .get(planData.orgScope)
        .then(function() {
          throw Object.assign(new Error("Org already exists"), {
            code: 'EEXIST',
            statusCode: 409,
            what: 'org'
          });
        }).catch(function(err) {
        if (err.statusCode !== 404) {
          throw err;
        }

        // org doesn't yet exist, transfer user then create org
        var start = newUser ? User.new(request).toOrg(loggedInUser, newUser) : P.resolve(null);

        return start.then(function(newUserData) {
          var setSession = P.promisify(request.server.methods.user.setSession(request));
          var delSession = P.promisify(request.server.methods.user.delSession(request));
          loggedInUser = newUserData ? newUser : loggedInUser;

          if (newUserData) {
            return delSession(request.loggedInUser)
              .then(function() {
                request.logger.info("setting session to: " + loggedInUser);
                return setSession({
                  name: loggedInUser
                });
              })
          } else {
            return Org(loggedInUser)
              .create({
                scope: planData.orgScope,
                humanName: planData["human-name"]
              });
          }
        }).then(function() {
          planInfo.npm_org = planData.orgScope;
          return Customer(loggedInUser).createSubscription(planInfo)
            .tap(function(subscription) {
              if (typeof subscription === 'string') {
                request.logger.info("created subscription: ", planInfo);
              }
              return new P(function(accept, reject) {
                User.new(request).dropCache(loggedInUser, function(err) {
                  if (err) {
                    request.logger.error(err);
                    return reject(err);
                  }
                  return accept();
                });
              });
            }).then(function(subscription) {
            return Customer(loggedInUser).extendSponsorship(subscription.license_id, loggedInUser);
          }).then(function(extendedSponsorship) {
            return Customer(loggedInUser).acceptSponsorship(extendedSponsorship.verification_key);
          }).then(function() {
            return reply.redirect('/org/' + planData.orgScope);
          });
        })
          .catch(function(err) {
            request.logger.error(err);
            throw err;
          });
      }).catch(function(err) {
        request.logger.error(err);

        if (err.code === 'EEXIST' && err.what === 'org') {
          return reply.view('org/create', {
            stripePublicKey: process.env.STRIPE_PUBLIC_KEY,
            notices: [err]
          });
        } else if (err.statusCode === 409 && err.message) {
          return reply.view('org/create', {
            stripePublicKey: process.env.STRIPE_PUBLIC_KEY,
            inUseError: true,
            orgScope: planData.orgScope,
            humanName: planData["human-name"],
            notices: [err]
          });
        } else {
          return reply.view('errors/internal', err).code(500);
        }
      });
    }
  });
};
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */

suite('Built-in Element instanceof', function() {

  test('Built-in Elements are instanceof HTMLElement', function() {
    'use strict';

    // All tags implementing the HTMLElement interface, according to:
    // https://html.spec.whatwg.org/multipage/indices.html#element-interfaces
    // Commented out tags do not have their own class, but are concrete
    // instances of HTMLElement, which makes it impossible to patch their
    // prototype chain to make instanceof work.
    var elements = [
      'a',
      // 'abbr',
      // 'address',
      'area',
      // 'article',
      // 'aside',
      'audio',
      // 'b',
      'base',
      // 'bdi',
      // 'bdo',
      'blockquote',
      'body',
      'br',
      'button',
      'canvas',
      'caption',
      // 'cite',
      // 'code',
      'col',
      'colgroup',
      'menuitem',
      'data',
      'datalist',
      // 'dd',
      'del',
      'details',
      // 'dfn',
      'dialog',
      'div',
      'dl',
      // 'dt',
      // 'em',
      'embed',
      'fieldset',
      // 'figcaption',
      // 'figure',
      // 'footer',
      'form',
      'h1',
      'h2',
      'h3',
      'h4',
      'h5',
      'h6',
      'head',
      // 'header',
      // 'hgroup',
      'hr',
      'html',
      // 'i',
      'iframe',
      'img',
      'input',
      'ins',
      // 'kbd',
      'keygen',
      'label',
      'legend',
      'li',
      'link',
      // 'main',
      'map',
      // 'mark',
      'menu',
      'meta',
      'meter',
      // 'nav',
      // 'noscript',
      'object',
      'ol',
      'optgroup',
      'option',
      'output',
      'p',
      'param',
      'picture',
      'pre',
      'progress',
      'q',
      // 'rp',
      // 'rt',
      // 'ruby',
      // 's',
      // 'samp',
      'script',
      // 'section',
      'select',
      'slot',
      // 'small',
      'source',
      'span',
      // 'strong',
      'style',
      // 'sub',
      // 'summary',
      // 'sup',
      'table',
      'tbody',
      'td',
      'template',
      'textarea',
      'tfoot',
      'th',
      'thead',
      'time',
      'title',
      'tr',
      'track',
      // 'u',
      'ul',
      // 'var',
      'video',
      // 'wbr',
    ];

    console.log("HTMLElement", HTMLElement);

    var d = document.createElement('abbr');
    console.log(d);
    console.log(d.__proto__);
    console.log(d instanceof HTMLElement);

    for (var i = 0; i < elements.length; i++) {
      var tag = elements[i];
      var e = document.createElement(tag);
      assert.isTrue(e instanceof HTMLElement, tag + ' not instanceof HTMLElement');
    }

  });

});
<commit_msg>Skip some instanceof tests on Safari 9<commit_after>/**
 * @license
 * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */

suite('Built-in Element instanceof', function() {

  test('Built-in Elements are instanceof HTMLElement', function() {
    'use strict';

    // All tags implementing the HTMLElement interface, according to:
    // https://html.spec.whatwg.org/multipage/indices.html#element-interfaces
    // Commented out tags do not have their own class, but are concrete
    // instances of HTMLElement, which makes it impossible to patch their
    // prototype chain to make instanceof work.
    var elements = [
      'a',
      // 'abbr',
      // 'address',
      'area',
      // 'article',
      // 'aside',
      'audio',
      // 'b',
      'base',
      // 'bdi',
      // 'bdo',
      'blockquote',
      'body',
      'br',
      'button',
      'canvas',
      'caption',
      // 'cite',
      // 'code',
      'col',
      'colgroup',
      'menuitem',
      'data',
      'datalist',
      // 'dd',
      'del',
      // 'details', // doesn't work on Safari 9
      // 'dfn',
      'dialog',
      'div',
      'dl',
      // 'dt',
      // 'em',
      'embed',
      'fieldset',
      // 'figcaption',
      // 'figure',
      // 'footer',
      'form',
      'h1',
      'h2',
      'h3',
      'h4',
      'h5',
      'h6',
      'head',
      // 'header',
      // 'hgroup',
      'hr',
      'html',
      // 'i',
      'iframe',
      'img',
      'input',
      'ins',
      // 'kbd',
      'keygen',
      'label',
      'legend',
      'li',
      'link',
      // 'main',
      'map',
      // 'mark',
      'menu',
      'meta',
      'meter',
      // 'nav',
      // 'noscript',
      'object',
      'ol',
      'optgroup',
      'option',
      'output',
      'p',
      'param',
      'picture',
      'pre',
      'progress',
      'q',
      // 'rp',
      // 'rt',
      // 'ruby',
      // 's',
      // 'samp',
      'script',
      // 'section',
      'select',
      'slot',
      // 'small',
      'source',
      'span',
      // 'strong',
      'style',
      // 'sub',
      // 'summary',
      // 'sup',
      'table',
      'tbody',
      'td',
      'template',
      'textarea',
      'tfoot',
      'th',
      'thead',
      // 'time', // doesn't work on Safari 9
      'title',
      'tr',
      'track',
      // 'u',
      'ul',
      // 'var',
      'video',
      // 'wbr',
    ];

    for (var i = 0; i < elements.length; i++) {
      var tag = elements[i];
      var e = document.createElement(tag);
      assert.isTrue(e instanceof HTMLElement, tag + ' not instanceof HTMLElement');
    }

  });

});
<|endoftext|>


<commit_before>/**
 * Blueprint API Configuration
 *
 * These settings are for the global configuration of blueprint routes
 * and request options (which impact the behavior of blueprint actions)
 *
 * You may also override any of these settings on a per-controller basis
 * by defining a '_config' key in your controller definition, and assigning it
 * a configuration object with overrides for the settings in this file
 */

export default {
  blueprints: {
    /**
     * When enabled, GET, POST, PUT and DELETE routes will be generated for everyone of a controller's actions
     * @type {Boolean}
     */
    actions: true,

    /**
     * When enabled, `index` action will be default action
     * @type {Boolean}
     */
    index: true,

    /**
     * REST blueprints are the automatically generated routes Sails uses to expose a conventional REST API
     * on top of a controller's `find`, `findOne`, `create`, `update`, and `destroy` actions
     * @type {Boolean}
     */
    rest: true,

    /**
     * Shortcut routes are simple helpers to provide access to a controller's CRUD methods from your browser's URL bar
     * @type {Boolean}
     */
    shortcuts: false,

    /**
     * An optional mount path for all blueprint routes on a controller, including `rest`, `actions`, and `shortcuts`
     * @type {String}
     */
    prefix: '/v1',

    /**
     * An optional mount path for all blueprint routes on a controller, including only `rest`
     * @type {String}
     */
    restPrefix: '',

    /**
     * Whether to pluralize controller names in blueprint routes
     * @type {Boolean}
     */
    pluralize: true,

    /**
     * Whether the blueprint controllers should populate model fetches with data
     * from other models which are linked by associations
     * @type {Boolean}
     */
    populate: false,

    /**
     * Whether to run Model.watch() in the find and findOne blueprint actions
     * @type {Boolean}
     */
    autoWatch: false,

    /**
     * The default number of records to show in the response from a "find" action
     * @type {Number}
     */
    defaultLimit: 20
  }
}
<commit_msg>add rest api<commit_after>/**
 * Blueprint API Configuration
 * (sails.config.blueprints)
 *
 * These settings are for the global configuration of blueprint routes and
 * request options (which impact the behavior of blueprint actions).
 *
 * You may also override any of these settings on a per-controller basis
 * by defining a '_config' key in your controller defintion, and assigning it
 * a configuration object with overrides for the settings in this file.
 * A lot of the configuration options below affect so-called "CRUD methods",
 * or your controllers' `find`, `create`, `update`, and `destroy` actions.
 *
 * It's important to realize that, even if you haven't defined these yourself, as long as
 * a model exists with the same name as the controller, Sails will respond with built-in CRUD
 * logic in the form of a JSON API, including support for sort, pagination, and filtering.
 *
 * For more information on the blueprint API, check out:
 * http://sailsjs.org/#!/documentation/reference/blueprint-api
 *
 * For more information on the settings in this file, see:
 * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.blueprints.html
 *
 */

module.exports.blueprints = {

  /***************************************************************************
  *                                                                          *
  * Action routes speed up the backend development workflow by               *
  * eliminating the need to manually bind routes. When enabled, GET, POST,   *
  * PUT, and DELETE routes will be generated for every one of a controller's *
  * actions.                                                                 *
  *                                                                          *
  * If an `index` action exists, additional naked routes will be created for *
  * it. Finally, all `actions` blueprints support an optional path           *
  * parameter, `id`, for convenience.                                        *
  *                                                                          *
  * `actions` are enabled by default, and can be OK for production--         *
  * however, if you'd like to continue to use controller/action autorouting  *
  * in a production deployment, you must take great care not to              *
  * inadvertently expose unsafe/unintentional controller logic to GET        *
  * requests.                                                                *
  *                                                                          *
  ***************************************************************************/

  actions: false,

  /***************************************************************************
   *                                                                          *
   * RESTful routes (`sails.config.blueprints.rest`)                          *
   *                                                                          *
   * REST blueprints are the automatically generated routes Sails uses to     *
   * expose a conventional REST API on top of a controller's `find`,          *
   * `create`, `update`, and `destroy` actions.                               *
   *                                                                          *
   * For example, a BoatController with `rest` enabled generates the          *
   * following routes:                                                        *
   * :::::::::::::::::::::::::::::::::::::::::::::::::::::::                  *
   *  GET /boat -> BoatController.find                                        *
   *  GET /boat/:id -> BoatController.findOne                                 *
   *  POST /boat -> BoatController.create                                     *
   *  PUT /boat/:id -> BoatController.update                                  *
   *  DELETE /boat/:id -> BoatController.destroy                              *
   *                                                                          *
   * `rest` blueprint routes are enabled by default, and are suitable for use *
   * in a production scenario, as long you take standard security precautions *
   * (combine w/ policies, etc.)                                              *
   *                                                                          *
   ***************************************************************************/
  rest: false,

  /***************************************************************************
   *                                                                          *
   * Shortcut routes are simple helpers to provide access to a                *
   * controller's CRUD methods from your browser's URL bar. When enabled,     *
   * GET, POST, PUT, and DELETE routes will be generated for the              *
   * controller's`find`, `create`, `update`, and `destroy` actions.           *
   *                                                                          *
   * `shortcuts` are enabled by default, but should be disabled in            *
   * production.                                                              *
   *                                                                          *
   ***************************************************************************/

  shortcuts: true,

  /***************************************************************************
   *                                                                          *
   * An optional mount path for all blueprint routes on a controller,         *
   * including `rest`, `actions`, and `shortcuts`. This allows you to take    *
   * advantage of blueprint routing, even if you need to namespace your API   *
   * methods.                                                                 *
   *                                                                          *
   * (NOTE: This only applies to blueprint autoroutes, not manual routes from *
   * `sails.config.routes`)                                                   *
   *                                                                          *
   ***************************************************************************/

  prefix: '/api/v1',

  /***************************************************************************
   *                                                                          *
   * An optional mount path for all REST blueprint routes on a controller.    *
   * And it do not include `actions` and `shortcuts` routes.                  *
   * This allows you to take advantage of REST blueprint routing,             *
   * even if you need to namespace your RESTful API methods                   *
   *                                                                          *
   ***************************************************************************/

  // restPrefix: '',

  /***************************************************************************
   *                                                                          *
   * Whether to pluralize controller names in blueprint routes.               *
   *                                                                          *
   * (NOTE: This only applies to blueprint autoroutes, not manual routes from *
   * `sails.config.routes`)                                                   *
   *                                                                          *
   * For example, REST blueprints for `FooController` with `pluralize`        *
   * enabled:                                                                 *
   * GET /foos/:id?                                                           *
   * POST /foos                                                               *
   * PUT /foos/:id?                                                           *
   * DELETE /foos/:id?                                                        *
   *                                                                          *
   ***************************************************************************/

  // pluralize: false,

  /***************************************************************************
   *                                                                          *
   * Whether the blueprint controllers should populate model fetches with     *
   * data from other models which are linked by associations                  *
   *                                                                          *
   * If you have a lot of data in one-to-many associations, leaving this on   *
   * may result in very heavy api calls                                       *
   *                                                                          *
   ***************************************************************************/

  populate: false,

  /****************************************************************************
   *                                                                           *
   * Whether to run Model.watch() in the find and findOne blueprint actions.   *
   * Can be overridden on a per-model basis.                                   *
   *                                                                           *
   ****************************************************************************/

  // autoWatch: true,

  /****************************************************************************
   *                                                                           *
   * The default number of records to show in the response from a "find"       *
   * action. Doubles as the default size of populated arrays if populate is    *
   * true.                                                                     *
   *                                                                           *
   ****************************************************************************/

  defaultLimit: 30

};
<|endoftext|>


<commit_before>//= require knockout.min
//= require knockout-mapping
//= require knockout-onenter
//= require ko/binding-url-path-param
//= require jquery.waypoints.min
function ProjectAuth(data) {
    "use strict";
    var self = this;
    self.jobCreate = ko.observable(false);
    self.admin = ko.observable(false);
    self.mapping = {};
    if (data) {
        ko.mapping.fromJS(data, self.mapping, self);
    }
}
function ProjectReadme(data) {
    "use strict";
    var self = this;
    self.readmeHTML = ko.observable(null);
    self.motdHTML = ko.observable(null);

    self.mapping = {};
    if (data) {
        ko.mapping.fromJS(data, self.mapping, self);
    }
}
function Project(data) {
    var self = this;
    self.name = ko.observable(data.name);
    self.execCount = ko.observable(data.execCount || 0);
    self.userCount = ko.observable(data.userCount || 0);
    self.description = ko.observable(data.description);
    self.auth = ko.observable(new ProjectAuth());
    self.readme = ko.observable(new ProjectReadme());
    self.loaded = ko.observable(false);
    self.mapping = {
        auth: {
            create: function (options) {
                "use strict";
                return new ProjectAuth(options.data);
            }
        },
        readme: {
            create: function (options) {
                "use strict";
                return new ProjectReadme(options.data);
            }
        }
    };
    if (data) {
        ko.mapping.fromJS(data, self.mapping, self);
    }
}
function HomeData(data) {
    var self = this;
    self.baseUrl = data.baseUrl;
    self.summaryUrl = data.summaryUrl;
    self.projectNamesUrl = data.projectNamesUrl;
    self.loaded = ko.observable(false);
    self.jobCount = ko.observable(0);
    self.execCount = ko.observable(0);
    self.projectNames = ko.observableArray(data.projectNames || []);
    self.projectNamesTotal = ko.observable(data.projectNamesTotal || 0);
    self.loadedProjectNames = ko.observable(false);
    self.projects = ko.observableArray([]);
    self.projects.extend({rateLimit: 500});

    self.recentUsers = ko.observableArray([]);
    self.recentProjects = ko.observableArray([]);
    self.frameworkNodeName = ko.observable(null);
    self.doRefresh = ko.observable(false);
    self.doPaging = ko.observable(false);
    self.pagingMax = ko.observable(20);
    self.pagingRepeatMax = ko.observable(20);
    self.pagingDelay = ko.observable(2000);
    self.pagingOffset = ko.observable(0);
    self.refreshDelay = ko.observable(30000);
    self.search=ko.observable(null);

    //batch of project data to load
    self.batchList=ko.observableArray([]);
    self.batchList.extend({ rateLimit: 500 });
    self.batches=ko.observableArray([]);

    self.recentUsersCount = ko.pureComputed(function () {
        return self.recentUsers().length;
    });
    self.recentProjectsCount = ko.pureComputed(function () {
        return self.recentProjects().length;
    });
    self.searchedProjects=ko.pureComputed(function(){
        "use strict";
        var search=self.search();
        var names=self.projectNames();
        if(null==search){
            return names;
        }
        return ko.utils.arrayFilter(names,function(val,ndx){
            return val.search(search)>=0;
        });
    });
    self.projectCount = ko.pureComputed(function () {
        return self.projectNames().length;
    });
    self.projectsByName = ko.pureComputed(function () {
        var obj = {};
        ko.utils.arrayForEach(self.projects(), function (elem, ndx) {
            obj[ko.unwrap(elem.name)] = elem;
        });
        return obj;
    });
    self.searchProjectsByName = ko.pureComputed(function () {
        var obj = {};
        ko.utils.arrayForEach(self.searchedProjects(), function (elem, ndx) {
            obj[ko.unwrap(elem.name)] = elem;
        });
        return obj;
    });
    self.projectInSearch=function(name){
        "use strict";
        return !self.search() || self.searchProjectsByName()[name]!=null;
    };
    self.prototypeProject=new Project({});
    self.projectForName = function (name) {
        var projectsByName = self.projectsByName()[name];
        if(null==projectsByName){
            return self.prototypeProject;
        }
        return projectsByName;
    };
    self.mapping = {
        'projects': {
            key: function (data) {
                return ko.utils.unwrapObservable(data.name);
            },
            create: function (data) {
                "use strict";
                return new Project(options.data);
            },
            update: function (options) {
                var updateArray = [];
                var found = options.parent.projectForName(options.data.name);
                if (found) {
                    return ko.mapping.fromJS(options.data, {}, found);
                } else {
                    return ko.mapping.fromJS(options.data, {}, {});
                }
            }
        }
    };
    self.loadSummary = function () {
        return jQuery.ajax({
            type: 'GET',
            contentType: 'json',
            headers: {'x-rundeck-ajax': 'true'},
            url: _genUrl(self.summaryUrl, {}),
            success: function (data, status, jqxhr) {

                ko.mapping.fromJS(data, self.mapping, self);
                self.loaded(true);

                if (self.doRefresh()) {
                    setTimeout(self.loadSummary, self.refreshDelay());
                }
            }
        });
    };
    self.loadProjects = function (projs) {
        for (var i = 0; i < projs.length; i++) {
            var newproj = projs[i];
            var found = self.projectForName(newproj.name);
            if (found && found.name()==newproj.name) {
                ko.mapping.fromJS(newproj, null, found);
                found.loaded(true);
            } else {
                self.projects.push(
                    new Project(jQuery.extend(newproj, {loaded: true}))
                );
            }
        }
    };
    self.load = function (refresh) {
        var params = {};//refresh?{refresh:true}:{};
        if (self.doPaging()) {
            jQuery.extend(params, {
                offset: self.pagingOffset(),
                max: self.pagingMax()
            });
            self.pagingMax(self.pagingRepeatMax());
        }
        return jQuery.ajax({
            type: 'GET',
            contentType: 'json',
            headers: {'x-rundeck-ajax': 'true'},
            url: _genUrl(self.baseUrl, params),
            success: function (data, status, jqxhr) {
                if (data.projects) {
                    self.loadProjects(data.projects);
                }
                // ko.mapping.fromJS(data, self.mapping, self);
                if (self.doPaging() && data.nextoffset) {
                    self.pagingOffset(data.nextoffset);
                    if (self.pagingOffset() === -1) {
                        self.pagingOffset(0);
                    } else {
                        setTimeout(self.load.curry(true), self.pagingDelay());
                        return;
                    }
                }
            }
        });
    };
    self.pullBatch=function(){
        "use strict";
        //pull up to max number of items from batchList
        var items=self.batchList.splice(0,self.pagingMax());
        if(items.length>0) {
            self.batches.push(items);
        }
    };
    self.batchList.subscribe(function(newValue){
        "use strict";
        if(newValue.length>0){
            setTimeout(self.pullBatch,100);
        }
    });
    self.batches.subscribe(function(newValue){
        if(!self.batchLoading && newValue.length>0){
            self.batchLoading=true;
            setTimeout(self.loadBatch,100);
        }
    });
    self.clearBatchLoad=function(){
        "use strict";

        self.batchList([]);
        self.batches([]);
    };
    self.search.subscribe(self.clearBatchLoad);
    self.batchLoading=false;
    self.loadBatch = function () {
        self.batchLoading=true;
        var projects=self.batches.shift();
        if(null==projects || projects.length<1){
            self.batchLoading=false;
            return;
        }
        var params = {projects:projects.join(',')};//refresh?{refresh:true}:{};
        return jQuery.ajax({
            type: 'GET',
            contentType: 'json',
            headers: {'x-rundeck-ajax': 'true'},
            url: _genUrl(self.baseUrl, params),
            success: function (data, status, jqxhr) {
                if (data.projects) {
                    self.loadProjects(data.projects);
                }
                //...
                if(self.batches().length>0){
                    self.loadBatch();
                }else{
                    self.batchLoading=false;
                }
            }
        });
    };

    /**
     * bound via the ko/binding-waypoints knockout binding
     * example:
     * <span data-bind="waypoints: $root.waypointHandler" >
     */
    self.waypointHandler=function(){
        "use strict";
        var projectName = jQuery(this.element).data('project');
        if(!self.projectForName(projectName).loaded()) {
            self.batchList.push(projectName);
        }

        this.destroy();
    };
    //initial setup
    self.beginLoad = function () {
        self.loadSummary().then(function () {
            "use strict";
            // setTimeout(self.load,200);
        });
    };
    self.loadProjectNames = function () {
        return jQuery.ajax({
            type: 'GET',
            contentType: 'json',
            headers: {'x-rundeck-ajax': 'true'},
            url: _genUrl(self.projectNamesUrl, {}),
            success: function (data, status, jqxhr) {
                self.projectNames(data.projectNames);
                self.projectNamesTotal(data.projectNames.length);
                self.loadedProjectNames(true);
                self.beginLoad();
            }
        });
    };
    self.init = function () {
        self.beginLoad();
        if (self.projectCount() != self.projectNamesTotal()) {
            setTimeout(self.loadProjectNames, 200);
        }
    };
}
function initWaypoints(homedata,reset){
    "use strict";
    if(reset){
        Waypoint.destroyAll();
    }

    jQuery('.list-group-item.project_list_item[data-project]').waypoint(homedata.waypointHandler, {offset:'100%'});
}

/**
 * START page init
 */
var homedata;
function init() {
    // ko.options.deferUpdates = true;
    var pageparams = loadJsonData('homeDataPagingParams') || {};
    var projectNamesData = loadJsonData('projectNamesData');
    if (projectNamesData.projectNames == null) {
        projectNamesData.projectNames = [];
    }
    homedata = new HomeData({
        baseUrl: appLinks.menuHomeAjax,
        summaryUrl: appLinks.menuHomeSummaryAjax,
        projectNamesUrl: appLinks.menuProjectNamesAjax,
        projectNames: projectNamesData.projectNames.sort(),
        projectNamesTotal: projectNamesData.projectNamesTotal || 0,

    });
    homedata.loadedProjectNames(projectNamesData.projectNames.length > 0 && projectNamesData.projectNames.length == projectNamesData.projectNamesTotal);
    ko.applyBindings(homedata);

    homedata.pagingMax(pageparams.pagingInitialMax || 15);
    homedata.pagingRepeatMax(pageparams.pagingRepeatMax || 50);
    homedata.doRefresh(pageparams.summaryRefresh != null ? pageparams.summaryRefresh : true);
    homedata.refreshDelay(pageparams.refreshDelay || 30000);
    homedata.doPaging(pageparams.doPaging != null ? pageparams.doPaging : true);
    homedata.pagingDelay(pageparams.pagingDelay || 2000);
    homedata.searchedProjects.subscribe(function(val){
        "use strict";
        //when search results change, refresh waypoints
        ko.tasks.schedule(initWaypoints.curry(homedata,true));
    });
    if(homedata.loadedProjectNames()){
        //load waypoints manually
        initWaypoints(homedata);
    }
    homedata.loaded.subscribe(Waypoint.refreshAll);
    homedata.projects.subscribe(Waypoint.refreshAll);
    homedata.init();
}
jQuery(init);
<commit_msg>include message template binding<commit_after>//= require knockout.min
//= require knockout-mapping
//= require knockout-onenter
//= require ko/binding-url-path-param
//= require ko/binding-message-template
//= require jquery.waypoints.min
function ProjectAuth(data) {
    "use strict";
    var self = this;
    self.jobCreate = ko.observable(false);
    self.admin = ko.observable(false);
    self.mapping = {};
    if (data) {
        ko.mapping.fromJS(data, self.mapping, self);
    }
}
function ProjectReadme(data) {
    "use strict";
    var self = this;
    self.readmeHTML = ko.observable(null);
    self.motdHTML = ko.observable(null);

    self.mapping = {};
    if (data) {
        ko.mapping.fromJS(data, self.mapping, self);
    }
}
function Project(data) {
    var self = this;
    self.name = ko.observable(data.name);
    self.execCount = ko.observable(data.execCount || 0);
    self.userCount = ko.observable(data.userCount || 0);
    self.description = ko.observable(data.description);
    self.auth = ko.observable(new ProjectAuth());
    self.readme = ko.observable(new ProjectReadme());
    self.loaded = ko.observable(false);
    self.mapping = {
        auth: {
            create: function (options) {
                "use strict";
                return new ProjectAuth(options.data);
            }
        },
        readme: {
            create: function (options) {
                "use strict";
                return new ProjectReadme(options.data);
            }
        }
    };
    if (data) {
        ko.mapping.fromJS(data, self.mapping, self);
    }
}
function HomeData(data) {
    var self = this;
    self.baseUrl = data.baseUrl;
    self.summaryUrl = data.summaryUrl;
    self.projectNamesUrl = data.projectNamesUrl;
    self.loaded = ko.observable(false);
    self.jobCount = ko.observable(0);
    self.execCount = ko.observable(0);
    self.projectNames = ko.observableArray(data.projectNames || []);
    self.projectNamesTotal = ko.observable(data.projectNamesTotal || 0);
    self.loadedProjectNames = ko.observable(false);
    self.projects = ko.observableArray([]);
    self.projects.extend({rateLimit: 500});

    self.recentUsers = ko.observableArray([]);
    self.recentProjects = ko.observableArray([]);
    self.frameworkNodeName = ko.observable(null);
    self.doRefresh = ko.observable(false);
    self.doPaging = ko.observable(false);
    self.pagingMax = ko.observable(20);
    self.pagingRepeatMax = ko.observable(20);
    self.pagingDelay = ko.observable(2000);
    self.pagingOffset = ko.observable(0);
    self.refreshDelay = ko.observable(30000);
    self.search=ko.observable(null);

    //batch of project data to load
    self.batchList=ko.observableArray([]);
    self.batchList.extend({ rateLimit: 500 });
    self.batches=ko.observableArray([]);

    self.recentUsersCount = ko.pureComputed(function () {
        return self.recentUsers().length;
    });
    self.recentProjectsCount = ko.pureComputed(function () {
        return self.recentProjects().length;
    });
    self.searchedProjects=ko.pureComputed(function(){
        "use strict";
        var search=self.search();
        var names=self.projectNames();
        if(null==search){
            return names;
        }
        return ko.utils.arrayFilter(names,function(val,ndx){
            return val.search(search)>=0;
        });
    });
    self.projectCount = ko.pureComputed(function () {
        return self.projectNames().length;
    });
    self.projectsByName = ko.pureComputed(function () {
        var obj = {};
        ko.utils.arrayForEach(self.projects(), function (elem, ndx) {
            obj[ko.unwrap(elem.name)] = elem;
        });
        return obj;
    });
    self.searchProjectsByName = ko.pureComputed(function () {
        var obj = {};
        ko.utils.arrayForEach(self.searchedProjects(), function (elem, ndx) {
            obj[ko.unwrap(elem.name)] = elem;
        });
        return obj;
    });
    self.projectInSearch=function(name){
        "use strict";
        return !self.search() || self.searchProjectsByName()[name]!=null;
    };
    self.prototypeProject=new Project({});
    self.projectForName = function (name) {
        var projectsByName = self.projectsByName()[name];
        if(null==projectsByName){
            return self.prototypeProject;
        }
        return projectsByName;
    };
    self.mapping = {
        'projects': {
            key: function (data) {
                return ko.utils.unwrapObservable(data.name);
            },
            create: function (data) {
                "use strict";
                return new Project(options.data);
            },
            update: function (options) {
                var updateArray = [];
                var found = options.parent.projectForName(options.data.name);
                if (found) {
                    return ko.mapping.fromJS(options.data, {}, found);
                } else {
                    return ko.mapping.fromJS(options.data, {}, {});
                }
            }
        }
    };
    self.loadSummary = function () {
        return jQuery.ajax({
            type: 'GET',
            contentType: 'json',
            headers: {'x-rundeck-ajax': 'true'},
            url: _genUrl(self.summaryUrl, {}),
            success: function (data, status, jqxhr) {

                ko.mapping.fromJS(data, self.mapping, self);
                self.loaded(true);

                if (self.doRefresh()) {
                    setTimeout(self.loadSummary, self.refreshDelay());
                }
            }
        });
    };
    self.loadProjects = function (projs) {
        for (var i = 0; i < projs.length; i++) {
            var newproj = projs[i];
            var found = self.projectForName(newproj.name);
            if (found && found.name()==newproj.name) {
                ko.mapping.fromJS(newproj, null, found);
                found.loaded(true);
            } else {
                self.projects.push(
                    new Project(jQuery.extend(newproj, {loaded: true}))
                );
            }
        }
    };
    self.load = function (refresh) {
        var params = {};//refresh?{refresh:true}:{};
        if (self.doPaging()) {
            jQuery.extend(params, {
                offset: self.pagingOffset(),
                max: self.pagingMax()
            });
            self.pagingMax(self.pagingRepeatMax());
        }
        return jQuery.ajax({
            type: 'GET',
            contentType: 'json',
            headers: {'x-rundeck-ajax': 'true'},
            url: _genUrl(self.baseUrl, params),
            success: function (data, status, jqxhr) {
                if (data.projects) {
                    self.loadProjects(data.projects);
                }
                // ko.mapping.fromJS(data, self.mapping, self);
                if (self.doPaging() && data.nextoffset) {
                    self.pagingOffset(data.nextoffset);
                    if (self.pagingOffset() === -1) {
                        self.pagingOffset(0);
                    } else {
                        setTimeout(self.load.curry(true), self.pagingDelay());
                        return;
                    }
                }
            }
        });
    };
    self.pullBatch=function(){
        "use strict";
        //pull up to max number of items from batchList
        var items=self.batchList.splice(0,self.pagingMax());
        if(items.length>0) {
            self.batches.push(items);
        }
    };
    self.batchList.subscribe(function(newValue){
        "use strict";
        if(newValue.length>0){
            setTimeout(self.pullBatch,100);
        }
    });
    self.batches.subscribe(function(newValue){
        if(!self.batchLoading && newValue.length>0){
            self.batchLoading=true;
            setTimeout(self.loadBatch,100);
        }
    });
    self.clearBatchLoad=function(){
        "use strict";

        self.batchList([]);
        self.batches([]);
    };
    self.search.subscribe(self.clearBatchLoad);
    self.batchLoading=false;
    self.loadBatch = function () {
        self.batchLoading=true;
        var projects=self.batches.shift();
        if(null==projects || projects.length<1){
            self.batchLoading=false;
            return;
        }
        var params = {projects:projects.join(',')};//refresh?{refresh:true}:{};
        return jQuery.ajax({
            type: 'GET',
            contentType: 'json',
            headers: {'x-rundeck-ajax': 'true'},
            url: _genUrl(self.baseUrl, params),
            success: function (data, status, jqxhr) {
                if (data.projects) {
                    self.loadProjects(data.projects);
                }
                //...
                if(self.batches().length>0){
                    self.loadBatch();
                }else{
                    self.batchLoading=false;
                }
            }
        });
    };

    /**
     * bound via the ko/binding-waypoints knockout binding
     * example:
     * <span data-bind="waypoints: $root.waypointHandler" >
     */
    self.waypointHandler=function(){
        "use strict";
        var projectName = jQuery(this.element).data('project');
        if(!self.projectForName(projectName).loaded()) {
            self.batchList.push(projectName);
        }

        this.destroy();
    };
    //initial setup
    self.beginLoad = function () {
        self.loadSummary().then(function () {
            "use strict";
            // setTimeout(self.load,200);
        });
    };
    self.loadProjectNames = function () {
        return jQuery.ajax({
            type: 'GET',
            contentType: 'json',
            headers: {'x-rundeck-ajax': 'true'},
            url: _genUrl(self.projectNamesUrl, {}),
            success: function (data, status, jqxhr) {
                self.projectNames(data.projectNames);
                self.projectNamesTotal(data.projectNames.length);
                self.loadedProjectNames(true);
                self.beginLoad();
            }
        });
    };
    self.init = function () {
        self.beginLoad();
        if (self.projectCount() != self.projectNamesTotal()) {
            setTimeout(self.loadProjectNames, 200);
        }
    };
}
function initWaypoints(homedata,reset){
    "use strict";
    if(reset){
        Waypoint.destroyAll();
    }

    jQuery('.list-group-item.project_list_item[data-project]').waypoint(homedata.waypointHandler, {offset:'100%'});
}

/**
 * START page init
 */
var homedata;
function init() {
    // ko.options.deferUpdates = true;
    var pageparams = loadJsonData('homeDataPagingParams') || {};
    var projectNamesData = loadJsonData('projectNamesData');
    if (projectNamesData.projectNames == null) {
        projectNamesData.projectNames = [];
    }
    homedata = new HomeData({
        baseUrl: appLinks.menuHomeAjax,
        summaryUrl: appLinks.menuHomeSummaryAjax,
        projectNamesUrl: appLinks.menuProjectNamesAjax,
        projectNames: projectNamesData.projectNames.sort(),
        projectNamesTotal: projectNamesData.projectNamesTotal || 0,

    });
    homedata.loadedProjectNames(projectNamesData.projectNames.length > 0 && projectNamesData.projectNames.length == projectNamesData.projectNamesTotal);
    ko.applyBindings(homedata);

    homedata.pagingMax(pageparams.pagingInitialMax || 15);
    homedata.pagingRepeatMax(pageparams.pagingRepeatMax || 50);
    homedata.doRefresh(pageparams.summaryRefresh != null ? pageparams.summaryRefresh : true);
    homedata.refreshDelay(pageparams.refreshDelay || 30000);
    homedata.doPaging(pageparams.doPaging != null ? pageparams.doPaging : true);
    homedata.pagingDelay(pageparams.pagingDelay || 2000);
    homedata.searchedProjects.subscribe(function(val){
        "use strict";
        //when search results change, refresh waypoints
        ko.tasks.schedule(initWaypoints.curry(homedata,true));
    });
    if(homedata.loadedProjectNames()){
        //load waypoints manually
        initWaypoints(homedata);
    }
    homedata.loaded.subscribe(Waypoint.refreshAll);
    homedata.projects.subscribe(Waypoint.refreshAll);
    homedata.init();
}
jQuery(init);
<|endoftext|>


<commit_before>var resurrect={

  contextUrl:null,

// // // // // // // // // // // // // // // // // // // // // // // // // // //

  onLoad:function() {
    window.removeEventListener('load', resurrect.onLoad, false);
    document.getElementById('contentAreaContextMenu')
        .addEventListener('popupshowing', resurrect.toggleContextItems, false);
    addEventListener('DOMContentLoaded', resurrect.contentDomLoad, false);
  },

  toggleContextItems:function(event) {
    resurrect.contextUrl = gContextMenu.linkURL;

    var onDocument=!(
        gContextMenu.isContentSelected || gContextMenu.onTextInput ||
        gContextMenu.onLink || gContextMenu.onImage);

    document.getElementById('resurrect-page-context')
        .setAttribute('hidden', !onDocument);
    document.getElementById('resurrect-link-context')
        .setAttribute('hidden', !gContextMenu.onLink);
  },

  contentDomLoad:function(event) {
    var contentDoc=event.target;

    if (contentDoc.documentURI.indexOf('about:neterror') != 0) return;

    // Inject our content...
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'chrome://resurrect/content/netError.xhtml', true);
    xhr.onload = function() {
      var fieldset = xhr.responseXML.getElementById('resurrect');
      var xhtml = new XMLSerializer().serializeToString(fieldset);
      var container = contentDoc.getElementById('errorPageContainer');
      container.innerHTML += xhtml;

      // ...plus the CSS.
      var link = contentDoc.createElement('link');
      link.setAttribute('rel', 'stylesheet');
      link.setAttribute('href', 'chrome://resurrect/skin/netError.css');
      link.setAttribute('type', 'text/css');
      link.setAttribute('media', 'all');
      contentDoc.getElementsByTagName('head')[0].appendChild(link);

      // Add the className that enables it, only when appropriate.
      contentDoc.location.href =
          'javascript:if ("nssBadCert" != getErrorCode()) {'
          + 'document.body.className += " resurrect";'
          + '}; void(0)';

      // Add event listener.
      contentDoc.getElementById('resurrect').addEventListener(
          'click', resurrect.clickedHtml, false);
      contentDoc.getElementById('resurrect').addEventListener(
          'keypress', resurrect.clickedHtml, false);
    };
    xhr.send(null);
  },

  disableButtons:function(doc) {
    var bs=doc.getElementById('resurrect')
        .getElementsByTagName('xul:button');
    for (var i=0, b=null; b=bs[i]; i++) {
      b.setAttribute('disabled', 'true');
    }
  },

// // // // // // // // // // // // // // // // // // // // // // // // // // //

  page:function(event) {
    var doc=getBrowser().contentWindow.document;
    resurrect.showDialog(doc.location.href);
  },

  link:function(event) {
    resurrect.showDialog(resurrect.contextUrl);
  },

// // // // // // // // // // // // // // // // // // // // // // // // // // //

  loadTarget:function() {
    var pref=Components.classes['@mozilla.org/preferences-service;1']
        .getService(Components.interfaces.nsIPrefBranch);
    var target=pref.getCharPref('extensions.resurrect.target');

    document.getElementById('targetGroup').selectedItem=
        document.getElementById(target);
  },

  saveTarget:function(el) {
    var target=document.getElementById('targetGroup').selectedItem.id;

    var pref=Components.classes['@mozilla.org/preferences-service;1']
        .getService(Components.interfaces.nsIPrefBranch);
    pref.setCharPref('extensions.resurrect.target', target);
  },

// // // // // // // // // // // // // // // // // // // // // // // // // // //

  showDialog:function(url) {
    window.openDialog(
        'chrome://resurrect/content/resurrect-select-mirror.xul',
        '_blank',
        'modal,centerscreen,resizable=no,chrome,dependent',
        getBrowser().contentWindow.document, url);
  },

  clickedHtml:function(event) {
    if ('true'==event.target.getAttribute('disabled')) {
      return;
    }
    if ('keypress' == event.type) {
      if (event.target.parentNode.id != 'resurrect') return;
      if (event.charCode != 32 && event.keyCode != 13) return;
    }

    return resurrect.clickHandler(
        event,
        event.target.ownerDocument,
        event.target.ownerDocument.location.href);
  },

  clickedXul:function(event) {
    resurrect.saveTarget(event.target);

    return resurrect.clickHandler(
        event,
        window.arguments[0],
        window.arguments[1]);
  },

  clickHandler:function(event, contentDoc, rawUrl) {
    resurrect.disableButtons(event.target.ownerDocument);

    // Run the actual code.  After timeout for UI repaint.
    setTimeout(
        resurrect.selectMirror, 1,
        event.target.getAttribute('value'),
        event.target.ownerDocument,
        contentDoc, rawUrl);
  },

  selectMirror:function(mirror, ownerDoc, contentDoc, rawUrl) {
    var gotoUrl=null;
    var encUrl=encodeURIComponent(rawUrl);

    switch (mirror) {
    case 'google':
      gotoUrl='http://www.google.com/search?q=cache:'+encUrl;
      break;
    case 'googletext':
      gotoUrl='http://www.google.com/search?strip=1&q=cache:'+encUrl;
      break;
    case 'archive':
      var dateStr = (new Date()).toISOString().replace(/-|T|:|\..*/g, '');
      gotoUrl='http://wayback.archive.org/web/'+dateStr+'/'+rawUrl;
      break;
    case 'archiveis':
      gotoUrl='https://archive.is/'+rawUrl;
      break;
    case 'webcitation':
      gotoUrl='http://webcitation.org/query.php?url='+encUrl;
      break;
    default:
      return false;
      break;
    }

    if (gotoUrl) {
      if (ownerDoc.getElementById('targetTab').getAttribute('selected')) {
        window.opener.openUILinkIn(gotoUrl, 'tab');
      } else if (ownerDoc.getElementById('targetWin').getAttribute('selected')) {
        // the setTimeout keeps focus from returning to the opener
        setTimeout(function(){
          window.opener.openNewWindowWith(gotoUrl, null, null);
        }, 10);
      } else {
        contentDoc.location.assign(gotoUrl);
      }

      if ('chrome://resurrect/content/resurrect-select-mirror.xul'==window.document.location) {
        // setTimeout avoids errors because the window is gone
        setTimeout(window.close, 0);
      }
    }
  }
};
<commit_msg>use https for google and archive.org<commit_after>var resurrect={

  contextUrl:null,

// // // // // // // // // // // // // // // // // // // // // // // // // // //

  onLoad:function() {
    window.removeEventListener('load', resurrect.onLoad, false);
    document.getElementById('contentAreaContextMenu')
        .addEventListener('popupshowing', resurrect.toggleContextItems, false);
    addEventListener('DOMContentLoaded', resurrect.contentDomLoad, false);
  },

  toggleContextItems:function(event) {
    resurrect.contextUrl = gContextMenu.linkURL;

    var onDocument=!(
        gContextMenu.isContentSelected || gContextMenu.onTextInput ||
        gContextMenu.onLink || gContextMenu.onImage);

    document.getElementById('resurrect-page-context')
        .setAttribute('hidden', !onDocument);
    document.getElementById('resurrect-link-context')
        .setAttribute('hidden', !gContextMenu.onLink);
  },

  contentDomLoad:function(event) {
    var contentDoc=event.target;

    if (contentDoc.documentURI.indexOf('about:neterror') != 0) return;

    // Inject our content...
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'chrome://resurrect/content/netError.xhtml', true);
    xhr.onload = function() {
      var fieldset = xhr.responseXML.getElementById('resurrect');
      var xhtml = new XMLSerializer().serializeToString(fieldset);
      var container = contentDoc.getElementById('errorPageContainer');
      container.innerHTML += xhtml;

      // ...plus the CSS.
      var link = contentDoc.createElement('link');
      link.setAttribute('rel', 'stylesheet');
      link.setAttribute('href', 'chrome://resurrect/skin/netError.css');
      link.setAttribute('type', 'text/css');
      link.setAttribute('media', 'all');
      contentDoc.getElementsByTagName('head')[0].appendChild(link);

      // Add the className that enables it, only when appropriate.
      contentDoc.location.href =
          'javascript:if ("nssBadCert" != getErrorCode()) {'
          + 'document.body.className += " resurrect";'
          + '}; void(0)';

      // Add event listener.
      contentDoc.getElementById('resurrect').addEventListener(
          'click', resurrect.clickedHtml, false);
      contentDoc.getElementById('resurrect').addEventListener(
          'keypress', resurrect.clickedHtml, false);
    };
    xhr.send(null);
  },

  disableButtons:function(doc) {
    var bs=doc.getElementById('resurrect')
        .getElementsByTagName('xul:button');
    for (var i=0, b=null; b=bs[i]; i++) {
      b.setAttribute('disabled', 'true');
    }
  },

// // // // // // // // // // // // // // // // // // // // // // // // // // //

  page:function(event) {
    var doc=getBrowser().contentWindow.document;
    resurrect.showDialog(doc.location.href);
  },

  link:function(event) {
    resurrect.showDialog(resurrect.contextUrl);
  },

// // // // // // // // // // // // // // // // // // // // // // // // // // //

  loadTarget:function() {
    var pref=Components.classes['@mozilla.org/preferences-service;1']
        .getService(Components.interfaces.nsIPrefBranch);
    var target=pref.getCharPref('extensions.resurrect.target');

    document.getElementById('targetGroup').selectedItem=
        document.getElementById(target);
  },

  saveTarget:function(el) {
    var target=document.getElementById('targetGroup').selectedItem.id;

    var pref=Components.classes['@mozilla.org/preferences-service;1']
        .getService(Components.interfaces.nsIPrefBranch);
    pref.setCharPref('extensions.resurrect.target', target);
  },

// // // // // // // // // // // // // // // // // // // // // // // // // // //

  showDialog:function(url) {
    window.openDialog(
        'chrome://resurrect/content/resurrect-select-mirror.xul',
        '_blank',
        'modal,centerscreen,resizable=no,chrome,dependent',
        getBrowser().contentWindow.document, url);
  },

  clickedHtml:function(event) {
    if ('true'==event.target.getAttribute('disabled')) {
      return;
    }
    if ('keypress' == event.type) {
      if (event.target.parentNode.id != 'resurrect') return;
      if (event.charCode != 32 && event.keyCode != 13) return;
    }

    return resurrect.clickHandler(
        event,
        event.target.ownerDocument,
        event.target.ownerDocument.location.href);
  },

  clickedXul:function(event) {
    resurrect.saveTarget(event.target);

    return resurrect.clickHandler(
        event,
        window.arguments[0],
        window.arguments[1]);
  },

  clickHandler:function(event, contentDoc, rawUrl) {
    resurrect.disableButtons(event.target.ownerDocument);

    // Run the actual code.  After timeout for UI repaint.
    setTimeout(
        resurrect.selectMirror, 1,
        event.target.getAttribute('value'),
        event.target.ownerDocument,
        contentDoc, rawUrl);
  },

  selectMirror:function(mirror, ownerDoc, contentDoc, rawUrl) {
    var gotoUrl=null;
    var encUrl=encodeURIComponent(rawUrl);

    switch (mirror) {
    case 'google':
      gotoUrl='https://www.google.com/search?q=cache:'+encUrl;
      break;
    case 'googletext':
      gotoUrl='https://www.google.com/search?strip=1&q=cache:'+encUrl;
      break;
    case 'archive':
      var dateStr = (new Date()).toISOString().replace(/-|T|:|\..*/g, '');
      gotoUrl='https://wayback.archive.org/web/'+dateStr+'/'+rawUrl;
      break;
    case 'archiveis':
      gotoUrl='https://archive.is/'+rawUrl;
      break;
    case 'webcitation':
      gotoUrl='http://webcitation.org/query.php?url='+encUrl;
      break;
    default:
      return false;
      break;
    }

    if (gotoUrl) {
      if (ownerDoc.getElementById('targetTab').getAttribute('selected')) {
        window.opener.openUILinkIn(gotoUrl, 'tab');
      } else if (ownerDoc.getElementById('targetWin').getAttribute('selected')) {
        // the setTimeout keeps focus from returning to the opener
        setTimeout(function(){
          window.opener.openNewWindowWith(gotoUrl, null, null);
        }, 10);
      } else {
        contentDoc.location.assign(gotoUrl);
      }

      if ('chrome://resurrect/content/resurrect-select-mirror.xul'==window.document.location) {
        // setTimeout avoids errors because the window is gone
        setTimeout(window.close, 0);
      }
    }
  }
};
<|endoftext|>


<commit_before>//Audio files contained in this sample are copyright  2009 by Palm, Inc

function AudioPlayerAssistant() {
	/* this is the creator function for your scene assistant object. It will be passed all the
	   additional parameters (after the scene name) that were passed to pushScene. The reference
	   to the scene controller (this.controller) has not be established yet, so any initialization
	   that needs the scene controller should be done in the setup function below. */
}

AudioPlayerAssistant.prototype.setup = function() {
	/* this function is for setup tasks that have to happen when the scene is first created */

	/* use Luna.View.render to render view templates and add them to the scene, if needed. */

	/* setup widgets here */

	/* add event handlers to listen to events from widgets */
	myassistant = this;
	this.buttonModel1 = {
		buttonLabel : 'Open audio app',
		buttonClass : '',
		disable : false
	}
	this.buttonAtt1 = {
		type : Mojo.Widget.activityButton
	}
	this.buttonModel3 = {
		buttonLabel : 'Launch audio app',
		buttonClass : '',
		disable : false
	}
	this.buttonAtt3 = {
		type : Mojo.Widget.activityButton
	}
	myassistant = this;
	this.buttonModel2 = {
		buttonLabel : 'Audio Object',
		buttonClass : '',
		disable : false
	}
	this.buttonAtt2 = {
	}
	this.controller.setupWidget('LaunchAudioButton',this.buttonAtt1,this.buttonModel1)
	this.controller.setupWidget('EmbeddedButton',this.buttonAtt3,this.buttonModel3)
	this.controller.setupWidget('audioObjectButton',this.buttonAtt2,this.buttonModel2)
	this.controller.listen('LaunchAudioButton',Mojo.Event.tap, this.handleButtonPressed.bind(this));
	this.controller.listen('EmbeddedButton',Mojo.Event.tap, this.handleButton3Pressed.bind(this));
	this.controller.listen('audioObjectButton',Mojo.Event.tap, this.handleButton2Pressed.bind(this));
}

AudioPlayerAssistant.prototype.handleButtonPressed = function(event) {

	this.controller.serviceRequest(	'palm://com.palm.applicationManager',
	{
		method: 'open',
		parameters: {
			target : "/media/internal/ringtones/Flurry.mp3"
		},
		onSuccess: function(status){
            $('area-to-update').update(Object.toJSON(status));
        },
        onFailure: function(status){
        	$('area-to-update').update(Object.toJSON(status));
        },
		onComplete: function(){
			this.getButton = myassistant.controller.get('LaunchAudioButton');
			this.getButton.mojo.deactivate();
		}
	});
}
AudioPlayerAssistant.prototype.handleButton3Pressed = function(event) {
	this.controller.serviceRequest('palm://com.palm.applicationManager', {
		method:'launch',
		parameters: {
			id : 'com.palm.app.streamingmusicplayer',
			params: {
				target : '/media/internal/ringtones/Guitar.mp3'
			}
		},
		onSuccess: function(status){
            $('area-to-update').update(Object.toJSON(status));
        },
        onFailure: function(status){
        	$('area-to-update').update(Object.toJSON(status));
        },
		onComplete: function(){
			this.getButton = myassistant.controller.get('EmbeddedButton');
			this.getButton.mojo.deactivate();
		}
	});
}
AudioPlayerAssistant.prototype.handleButton2Pressed = function(event) {
	this.controller.stageController.pushScene('audioObject');
}
AudioPlayerAssistant.prototype.activate = function(event) {
	/* put in event handlers here that should only be in effect when this scene is active. For
	   example, key handlers that are observing the document */
}

AudioPlayerAssistant.prototype.deactivate = function(event) {
	/* remove any event handlers you added in activate and do any other cleanup that should happen before
	   this scene is popped or another scene is pushed on top */
	  //this.getButton = myassistant.controller.get('OpenSceneButton');
	//		this.getButton.mojo.deactivate();
}

AudioPlayerAssistant.prototype.cleanup = function(event) {
	/* this function should do any cleanup needed before the scene is destroyed as
	   a result of being popped off the scene stack */
	this.controller.stopListening('LaunchAudioButton',Mojo.Event.tap, this.handleButtonPressed.bind(this));
	this.controller.stopListening('EmbeddedButton',Mojo.Event.tap, this.handleButton3Pressed.bind(this));
}
<commit_msg>Uploaded blank last time<commit_after>//Audio files contained in this sample are copyright  2009 by Palm, Inc
function AudioPlayerAssistant() {
	/* this is the creator function for your scene assistant object. It will be passed all the
	   additional parameters (after the scene name) that were passed to pushScene. The reference
	   to the scene controller (this.controller) has not be established yet, so any initialization
	   that needs the scene controller should be done in the setup function below. */
}

AudioPlayerAssistant.prototype.setup = function() {
	/* this function is for setup tasks that have to happen when the scene is first created */

	/* use Luna.View.render to render view templates and add them to the scene, if needed. */

	/* setup widgets here */

	/* add event handlers to listen to events from widgets */
	myassistant = this;
	this.buttonModel1 = {
		buttonLabel : 'Open audio app',
		buttonClass : '',
		disable : false
	}
	this.buttonAtt1 = {
		type : Mojo.Widget.activityButton
	}
	this.buttonModel3 = {
		buttonLabel : 'Launch audio app',
		buttonClass : '',
		disable : false
	}
	this.buttonAtt3 = {
		type : Mojo.Widget.activityButton
	}
	myassistant = this;
	this.buttonModel2 = {
		buttonLabel : 'Audio Object',
		buttonClass : '',
		disable : false
	}
	this.buttonAtt2 = {
	}
	this.controller.setupWidget('LaunchAudioButton',this.buttonAtt1,this.buttonModel1)
	this.controller.setupWidget('EmbeddedButton',this.buttonAtt3,this.buttonModel3)
	this.controller.setupWidget('audioObjectButton',this.buttonAtt2,this.buttonModel2)
	this.controller.listen('LaunchAudioButton',Mojo.Event.tap, this.handleButtonPressed.bind(this));
	this.controller.listen('EmbeddedButton',Mojo.Event.tap, this.handleButton3Pressed.bind(this));
	this.controller.listen('audioObjectButton',Mojo.Event.tap, this.handleButton2Pressed.bind(this));
}

AudioPlayerAssistant.prototype.handleButtonPressed = function(event) {

	this.controller.serviceRequest(	'palm://com.palm.applicationManager',
	{
		method: 'open',
		parameters: {
			target : "/media/internal/ringtones/Flurry.mp3"
		},
		onSuccess: function(status){
            $('area-to-update').update(Object.toJSON(status));
        },
        onFailure: function(status){
        	$('area-to-update').update(Object.toJSON(status));
        },
		onComplete: function(){
			this.getButton = myassistant.controller.get('LaunchAudioButton');
			this.getButton.mojo.deactivate();
		}
	});
}
AudioPlayerAssistant.prototype.handleButton3Pressed = function(event) {
	this.controller.serviceRequest('palm://com.palm.applicationManager', {
		method:'launch',
		parameters: {
			id : 'com.palm.app.streamingmusicplayer',
			params: {
				target : '/media/internal/ringtones/Guitar.mp3'
			}
		},
		onSuccess: function(status){
            $('area-to-update').update(Object.toJSON(status));
        },
        onFailure: function(status){
        	$('area-to-update').update(Object.toJSON(status));
        },
		onComplete: function(){
			this.getButton = myassistant.controller.get('EmbeddedButton');
			this.getButton.mojo.deactivate();
		}
	});
}
AudioPlayerAssistant.prototype.handleButton2Pressed = function(event) {
	this.controller.stageController.pushScene('audioObject');
}
AudioPlayerAssistant.prototype.activate = function(event) {
	/* put in event handlers here that should only be in effect when this scene is active. For
	   example, key handlers that are observing the document */
}

AudioPlayerAssistant.prototype.deactivate = function(event) {
	/* remove any event handlers you added in activate and do any other cleanup that should happen before
	   this scene is popped or another scene is pushed on top */
	  //this.getButton = myassistant.controller.get('OpenSceneButton');
	//		this.getButton.mojo.deactivate();
}

AudioPlayerAssistant.prototype.cleanup = function(event) {
	/* this function should do any cleanup needed before the scene is destroyed as
	   a result of being popped off the scene stack */
	this.controller.stopListening('LaunchAudioButton',Mojo.Event.tap, this.handleButtonPressed.bind(this));
	this.controller.stopListening('EmbeddedButton',Mojo.Event.tap, this.handleButton3Pressed.bind(this));
}
<|endoftext|>