<commit_before>/***
 * A standalone touch library for mobile devices.
 * @author rainyjune <rainyjune@live.cn>
 */

/* global define, Zepto */
((function(){

  function TouchObject(domElement) {
    this.element = domElement;
    // Put all TouchEvent objects fired in the touchstart event into this array.
    var touchStartTouchList = [];

    var elementListeners= [];

    this.__defineGetter__("touchStartTouchList", function() {
      return touchStartTouchList;
    });
    this.__defineGetter__("elementListeners", function() {
      return elementListeners;
    });

    var isTapLength,
        tapLengthTimeout;

    this.horizontalOffset = 20,
    this.verticalOffset = 30;

    this.isDebug = true;

    this.bindEvents();
  }

  TouchObject.prototype.bindEvents = function() {
    var element = this.element;

    var mouseStartHandlerBind = mousestartHandler.bind(this);
    var mousemoveHandlerBind = mousemoveHandler.bind(this);
    var mouseEndHandlerBind = mouseEndHandler.bind(this);

    element.addEventListener("mousedown", mouseStartHandlerBind, false);
    element.addEventListener("mousemove", mousemoveHandlerBind, false);
    element.addEventListener("mouseup", mouseEndHandlerBind, false);
    element.addEventListener("mouseleave", mouseEndHandlerBind, false);

    this.elementListeners.push({
      "eventName": "mousedown",
      "callback": mouseStartHandlerBind
    });
    this.elementListeners.push({
      "eventName": "mousemove",
      "callback": mousemoveHandlerBind
    });
    this.elementListeners.push({
      "eventName": "mouseup",
      "callback": mouseEndHandlerBind
    });
    this.elementListeners.push({
      "eventName": "mouseleave",
      "callback": mouseEndHandlerBind
    });

    function mousestartHandler(event) {
      this.touchStartTouchList.push({
        "identifier": 0,
        "pageX": event.pageX,
        "pageY": event.pageY,
        "clientX": event.clientX,
        "clientY": event.clientY,
        "screenX": event.screenX,
        "screenY": event.screenY
      });
      this.trigger("swipeStart", event);
    }

    function mousemoveHandler(event) {
      // The 'touch' event not started.
      if (this.touchStartTouchList.length === 0) {
        return false;
      }
      var firstTouchStartEvent = this.touchStartTouchList[0];
      var nowPageX = event.pageX;
      var nowPageY = event.pageY;
      var movedPageX = nowPageX - firstTouchStartEvent.pageX;
      var movedPageY = nowPageY - firstTouchStartEvent.pageY;
      var eventObj = {
        pageX: event.pageX,
        pageY: event.pageY,
        clientX: event.clientX,
        clientY: event.clientY,
        screenX: event.screenX,
        screenY: event.screenY,
        detail: {'movedPageX': movedPageX, 'movedPageY': movedPageY}
      };
      this.trigger("swipeProgress", eventObj);
    }

    function mouseEndHandler(event) {
      var firstTouchStartEvent = this.touchStartTouchList[0];
      if (!firstTouchStartEvent) {
        return false;
      }
      this.touchStartTouchList.length = 0;

      var touchX = firstTouchStartEvent.clientX,
          nowX = event.clientX,
          touchY = firstTouchStartEvent.clientY,
          nowY = event.clientY;

      var movX = Math.abs(touchX - nowX);
      var movY = Math.abs(touchY - nowY);

      if (movX > this.horizontalOffset || movY > this.verticalOffset) {
        this.trigger("swipe", event);
        var direction = swipeDirection(touchX, nowX, touchY, nowY);
        this.trigger("swipe" + direction, event);
      } else {
        this.trigger("swipeCancel", event);
      }
    }

  };

  TouchObject.prototype.addEventListener = function(eventName, callback) {
    EventsObject.on(eventName, callback);
  }

  TouchObject.prototype.trigger = function(eventName, customData) {
    EventsObject.trigger(eventName, customData);
  }

  TouchObject.prototype.dispose = function() {
    for (var i = 0; i < this.elementListeners.length; i ++) {
      var currentListener = this.elementListeners[i];
      this.element.removeEventListener(currentListener["eventName"], currentListener["callback"]);
    }
    this.elementListeners.length = 0;
  };

  function swipeDirection(x1, x2, y1, y2) {
    return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down');
  }

  var EventsObject = (function(){
    // Events on and off
    var Events = [];

    function on(event, callback) {
        if (!Events[event]) {
            Events[event] = [];
        }
        Events[event].push(callback);
        return callback;
    }

    function off(event, callback) {
        if (!Events[event]) {
            return ;
        }
        if (callback) {
            var index = Events[event].indexOf(callback);
            if (index !== -1) {
                Events[event].splice(index, 1);
            }
        } else {
            Events[event] = [];
        }
    }

    function trigger (event) {
        if (!Events[event]) {
            return ;
        }
        var args = Array.prototype.slice.call(arguments, 1);
        var callbackArray = Events[event];
        for (var i = callbackArray.length - 1; i >= 0; i--) {
            callbackArray[i].apply(callbackArray[i], args);
        }
    }
    return {
      "on": on,
      "off": off,
      "trigger": trigger
    }
  })();

  if (typeof define === "function" && (define.amd || define.cmd)) {
    define(function(){
      return TouchObject;
    });
  } else {
    window.TouchObject = TouchObject;
  }

})());<commit_msg>Update touch.js: Add PointerEvent support(to be continued)<commit_after>/***
 * A standalone touch library for mobile devices.
 * @author rainyjune <rainyjune@live.cn>
 */

/* global define, Zepto */
((function(){

  function TouchObject(domElement) {
    this.element = domElement;
    // Put all TouchEvent objects fired in the touchstart event into this array.
    var touchStartTouchList = [];

    var elementListeners= [];

    this.__defineGetter__("touchStartTouchList", function() {
      return touchStartTouchList;
    });
    this.__defineGetter__("elementListeners", function() {
      return elementListeners;
    });

    var isTapLength,
        tapLengthTimeout;

    this.horizontalOffset = 20,
    this.verticalOffset = 30;

    this.isDebug = true;

    this.bindEvents();
  }

  TouchObject.prototype.bindMouseEvents = function() {
    var element = this.element;

    var mouseStartHandlerBind = mousestartHandler.bind(this);
    var mousemoveHandlerBind = mousemoveHandler.bind(this);
    var mouseEndHandlerBind = mouseEndHandler.bind(this);

    element.addEventListener("mousedown", mouseStartHandlerBind, false);
    element.addEventListener("mousemove", mousemoveHandlerBind, false);
    element.addEventListener("mouseup", mouseEndHandlerBind, false);
    element.addEventListener("mouseleave", mouseEndHandlerBind, false);

    this.elementListeners.push({
      "eventName": "mousedown",
      "callback": mouseStartHandlerBind
    });
    this.elementListeners.push({
      "eventName": "mousemove",
      "callback": mousemoveHandlerBind
    });
    this.elementListeners.push({
      "eventName": "mouseup",
      "callback": mouseEndHandlerBind
    });
    this.elementListeners.push({
      "eventName": "mouseleave",
      "callback": mouseEndHandlerBind
    });

    function mousestartHandler(event) {
      var touchCopy = this.copyTouch(event);
      this.touchStartTouchList.push(touchCopy);
      this.trigger("swipeStart", event);
    }

    function mousemoveHandler(event) {
      // The 'touch' event not started.
      if (this.touchStartTouchList.length === 0) {
        return false;
      }
      var firstTouchStartEvent = this.touchStartTouchList[0];
      var nowPageX = event.pageX;
      var nowPageY = event.pageY;
      var movedPageX = nowPageX - firstTouchStartEvent.pageX;
      var movedPageY = nowPageY - firstTouchStartEvent.pageY;
      var eventObj = {
        pageX: event.pageX,
        pageY: event.pageY,
        clientX: event.clientX,
        clientY: event.clientY,
        screenX: event.screenX,
        screenY: event.screenY,
        detail: {'movedPageX': movedPageX, 'movedPageY': movedPageY}
      };
      this.trigger("swipeProgress", eventObj);
    }

    function mouseEndHandler(event) {
      var firstTouchStartEvent = this.touchStartTouchList[0];
      if (!firstTouchStartEvent) {
        return false;
      }
      this.touchStartTouchList.length = 0;

      var touchX = firstTouchStartEvent.clientX,
          nowX = event.clientX,
          touchY = firstTouchStartEvent.clientY,
          nowY = event.clientY;

      var movX = Math.abs(touchX - nowX);
      var movY = Math.abs(touchY - nowY);

      if (movX > this.horizontalOffset || movY > this.verticalOffset) {
        this.trigger("swipe", event);
        var direction = swipeDirection(touchX, nowX, touchY, nowY);
        this.trigger("swipe" + direction, event);
      } else {
        this.trigger("swipeCancel", event);
      }
    }

  };

  TouchObject.prototype.bindPointerEvents = function() {
    var pointerDownName = window.PointerEvent ? "pointerdown" : "MSPointerDown",
        pointerMoveName = window.PointerEvent ? "pointermove" : "MSPointerMove",
        pointerUpName = window.PointerEvent ? "pointerup" : "MSPointerUp",
        pointerCancelName = window.PointerEvent ? "pointercancel" : "MSPointerCancel";

    var pointerDownBind = pointerDown.bind(this),
        pointerMoveBind = pointerMove.bind(this),
        pointerUpBind = pointerUp.bind(this),
        pointerCancelBind = pointerCancel.bind(this);

    var element = this.element,
        elementListeners = this.elementListeners;

    element.addEventListener(pointerDownName, pointerDownBind, false);
    element.addEventListener(pointerMoveName, pointerMoveBind, false);
    element.addEventListener(pointerUpName, pointerUpBind, false);
    element.addEventListener(pointerCancelName, pointerCancelBind, false);

    elementListeners.push({ "eventName": pointerDownName, "callback":  pointerDownBind });
    elementListeners.push({ "eventName": pointerMoveName, "callback": pointerMoveBind });
    elementListeners.push({ "eventName": pointerUpName, "callback": pointerUpBind });
    elementListeners.push({ "eventName": pointerCancelName, "callback": pointerCancelBind });

    function pointerDown(event) {
      var touchCopy = this.copyTouch(event);
      this.touchStartTouchList.push(touchCopy);
      this.trigger("swipeStart", event);
    }

    function pointerMove(event) {

    }

    function pointerUp(event) {

    }

    function pointerCancel(event) {

    }

  };

  TouchObject.prototype.copyTouch = function(touch) {
    return {
      "identifier": touch.identifier || touch.pointerId || 0,
      "pageX": touch.pageX,
      "pageY": touch.pageY,
      "clientX": touch.clientX,
      "clientY": touch.clientY,
      "screenX": touch.screenX,
      "screenY": touch.screenY
    };
  };

  TouchObject.prototype.bindEvents = function() {
    if (window.PointerEvent || window.navigator.msPointerEnabled) {
      this.bindPointerEvents();
    } else if (('ontouchstart' in document.documentElement) || ('ontouchstart' in window)){
      this.bindTouchEvents();
    } else {
      this.bindMouseEvents();
    }
  };

  TouchObject.prototype.addEventListener = function(eventName, callback) {
    EventsObject.on(eventName, callback);
  }

  TouchObject.prototype.trigger = function(eventName, customData) {
    EventsObject.trigger(eventName, customData);
  }

  TouchObject.prototype.dispose = function() {
    for (var i = 0; i < this.elementListeners.length; i ++) {
      var currentListener = this.elementListeners[i];
      this.element.removeEventListener(currentListener["eventName"], currentListener["callback"]);
    }
    this.elementListeners.length = 0;
  };

  function swipeDirection(x1, x2, y1, y2) {
    return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down');
  }

  var EventsObject = (function(){
    // Events on and off
    var Events = [];

    function on(event, callback) {
        if (!Events[event]) {
            Events[event] = [];
        }
        Events[event].push(callback);
        return callback;
    }

    function off(event, callback) {
        if (!Events[event]) {
            return ;
        }
        if (callback) {
            var index = Events[event].indexOf(callback);
            if (index !== -1) {
                Events[event].splice(index, 1);
            }
        } else {
            Events[event] = [];
        }
    }

    function trigger (event) {
        if (!Events[event]) {
            return ;
        }
        var args = Array.prototype.slice.call(arguments, 1);
        var callbackArray = Events[event];
        for (var i = callbackArray.length - 1; i >= 0; i--) {
            callbackArray[i].apply(callbackArray[i], args);
        }
    }
    return {
      "on": on,
      "off": off,
      "trigger": trigger
    }
  })();

  if (typeof define === "function" && (define.amd || define.cmd)) {
    define(function(){
      return TouchObject;
    });
  } else {
    window.TouchObject = TouchObject;
  }

})());<|endoftext|>


<commit_before>
var tracing = require('tracing');
var chain = require('stack-chain');

// Contains the call site objects of all the prevouse ticks leading
// up to this one
var callSitesForPreviuseTicks = null;

// add currentTrace to the callSite array
chain.extend.attach(function (error, frames) {
  frames = frames.slice(0);
  frames.push.apply(frames, callSitesForPreviuseTicks);
  return frames;
});

// Setup an async listener with the handlers listed below
tracing.addAsyncListener({
  'create': asyncFunctionInitialized,
  'before': asyncCallbackBefore,
  'error': asyncCallbackError,
  'after': asyncCallbackAfter
});

function asyncFunctionInitialized() {
  // Capture the callSites for this tick
  // .slice(2) removes first this file and then process.runAsyncQueue from the
  // callSites array. Both of those only exists because of this module.
  var trace = chain.callSite().slice(2);

  // Add all the callSites from previuse ticks
  trace.push.apply(trace, callSitesForPreviuseTicks);

  // `trace` now contains callSites from this ticks and all the ticks leading
  // up to this event in time
  return trace;
}

function asyncCallbackBefore(context, trace) {
  // restore previuseTicks for this specific async action, thereby allowing it
  // to become a part of a error `stack` string
  callSitesForPreviuseTicks = trace;
}

function asyncCallbackError(trace, error) {
  // Ensure that the error `stack` string is constructed before the
  // previuseTicks is cleared.
  // The construction logic is defined in
  //  - https://github.com/v8/v8/blob/master/src/messages.js -> captureStackTrace
  // and in the stack-chain module invoked earlier in this file
  error.stack;

  // clear previuseTicks
  callSitesForPreviuseTicks = null;
}

function asyncCallbackAfter(context, trace) {
  // clear previuseTicks. This allows for other async actions to get there
  // very own trace stack and helps in preventing a trace stack to get attach
  // to an error `stack` string, in the unknown case where asyncCallbackBefore
  // wasn't invoked. (This is an unseen event since trace v1.0.0)
  callSitesForPreviuseTicks = null;
}
<commit_msg>[optimize] cut trace array to Error.stackTraceLimit<commit_after>
var tracing = require('tracing');
var chain = require('stack-chain');

// Contains the call site objects of all the prevouse ticks leading
// up to this one
var callSitesForPreviuseTicks = null;

// add currentTrace to the callSite array
chain.extend.attach(function (error, frames) {
  frames = frames.slice(0);
  frames.push.apply(frames, callSitesForPreviuseTicks);
  return frames;
});

// Setup an async listener with the handlers listed below
tracing.addAsyncListener({
  'create': asyncFunctionInitialized,
  'before': asyncCallbackBefore,
  'error': asyncCallbackError,
  'after': asyncCallbackAfter
});

function asyncFunctionInitialized() {
  // Capture the callSites for this tick
  // .slice(2) removes first this file and then process.runAsyncQueue from the
  // callSites array. Both of those only exists because of this module.
  var trace = chain.callSite().slice(2);

  // Add all the callSites from previuse ticks
  trace.push.apply(trace, callSitesForPreviuseTicks);

  // Cut the trace so it don't contain callSites there won't be shown anyway
  // because of Error.stackTraceLimit
  trace.splice(Error.stackTraceLimit);

  // `trace` now contains callSites from this ticks and all the ticks leading
  // up to this event in time
  return trace;
}

function asyncCallbackBefore(context, trace) {
  // restore previuseTicks for this specific async action, thereby allowing it
  // to become a part of a error `stack` string
  callSitesForPreviuseTicks = trace;
}

function asyncCallbackError(trace, error) {
  // Ensure that the error `stack` string is constructed before the
  // `callSitesForPreviuseTicks` is cleared.
  // The construction logic is defined in
  //  - https://github.com/v8/v8/blob/master/src/messages.js -> captureStackTrace
  // and in the stack-chain module invoked earlier in this file
  error.stack;

  // clear previuseTicks
  callSitesForPreviuseTicks = null;
}

function asyncCallbackAfter(context, trace) {
  // clear `callSitesForPreviuseTicks`. This allows for other async actions
  // to get there very own trace stack and helps in preventing a trace stack to
  // get attach to an error `stack` string, in the unknown case where
  // asyncCallbackBefore wasn't invoked.
  // (This is an unseen event since trace v1.0.0)
  callSitesForPreviuseTicks = null;
}
<|endoftext|>


<commit_before>
var chain = require('stack-chain');

// Contains the call site objects of all the prevouse ticks leading
// up to this one
var callSitesForPreviuseTicks = null;

// add currentTrace to the callSite array
chain.extend.attach(function (error, frames) {
  frames = frames.slice(0);
  frames.push.apply(frames, callSitesForPreviuseTicks);
  return frames;
});

// filter out call sites from this file
chain.filter.attach(function (error, frames) {
  return frames.filter(function (callSite) {
    return (callSite.getFileName() !== module.filename);
  });
});

// Setup an async listener with the handlers listed below
process.addAsyncListener({
  'create': asyncFunctionInitialized,
  'before': asyncCallbackBefore,
  'error': asyncCallbackError,
  'after': asyncCallbackAfter
});

function asyncFunctionInitialized() {
  // Capture the callSites for this tick
  var err = new Error();
  var trace = err.callSite.slice(0);

  // Add all the callSites from previuse ticks
  trace.push.apply(trace, callSitesForPreviuseTicks);

  // `trace` now contains callSites from this ticks and all the ticks leading
  // up to this event in time
  return trace;
}

function asyncCallbackBefore(context, trace) {
  // restore previuseTicks for this specific async action, thereby allowing it
  // to become a part of a error `stack` string
  callSitesForPreviuseTicks = trace;
}

function asyncCallbackError(trace, error) {
  // Ensure that the error `stack` string is constructed before the
  // previuseTicks is cleared.
  // The construction logic is defined in
  //  - https://github.com/v8/v8/blob/master/src/messages.js -> captureStackTrace
  // and in the stack-chain module invoked earlier in this file
  error.stack;

  // clear previuseTicks
  callSitesForPreviuseTicks = null;
}

function asyncCallbackAfter(context, trace) {
  // clear previuseTicks. This allows for other async actions to get there
  // very own trace stack and helps in preventing a trace stack to get attach
  // to an error `stack` string, in the unknown case where asyncCallbackBefore
  // wasn't invoked. (This is an unseen event since trace v1.0.0)
  callSitesForPreviuseTicks = null;
}
<commit_msg>[fix] ignore process.runAsyncQueue and simplify filter logic<commit_after>
var chain = require('stack-chain');

// Contains the call site objects of all the prevouse ticks leading
// up to this one
var callSitesForPreviuseTicks = null;

// add currentTrace to the callSite array
chain.extend.attach(function (error, frames) {
  frames = frames.slice(0);
  frames.push.apply(frames, callSitesForPreviuseTicks);
  return frames;
});

// Setup an async listener with the handlers listed below
process.addAsyncListener({
  'create': asyncFunctionInitialized,
  'before': asyncCallbackBefore,
  'error': asyncCallbackError,
  'after': asyncCallbackAfter
});

function asyncFunctionInitialized() {
  // Capture the callSites for this tick
  var err = new Error();
  // .slice(2) removes first this file and then process.runAsyncQueue from the
  // callSites array. Both of those only exists because of this module.
  var trace = err.callSite.slice(2);

  // Add all the callSites from previuse ticks
  trace.push.apply(trace, callSitesForPreviuseTicks);

  // `trace` now contains callSites from this ticks and all the ticks leading
  // up to this event in time
  return trace;
}

function asyncCallbackBefore(context, trace) {
  // restore previuseTicks for this specific async action, thereby allowing it
  // to become a part of a error `stack` string
  callSitesForPreviuseTicks = trace;
}

function asyncCallbackError(trace, error) {
  // Ensure that the error `stack` string is constructed before the
  // previuseTicks is cleared.
  // The construction logic is defined in
  //  - https://github.com/v8/v8/blob/master/src/messages.js -> captureStackTrace
  // and in the stack-chain module invoked earlier in this file
  error.stack;

  // clear previuseTicks
  callSitesForPreviuseTicks = null;
}

function asyncCallbackAfter(context, trace) {
  // clear previuseTicks. This allows for other async actions to get there
  // very own trace stack and helps in preventing a trace stack to get attach
  // to an error `stack` string, in the unknown case where asyncCallbackBefore
  // wasn't invoked. (This is an unseen event since trace v1.0.0)
  callSitesForPreviuseTicks = null;
}
<|endoftext|>


<commit_before>/*
* icons.js
* Credits: Lord Haji, panpawn
*/
'use strict';

let icons = {};
const fs = require('fs');

function load() {
	fs.readFile('config/icons.json', 'utf8', function (err, file) {
		if (err) return;
		icons = JSON.parse(file);
	});
}
load();

function updateIcons() {
	fs.writeFileSync('config/icons.json', JSON.stringify(icons));

	let newCss = '/* ICONS START */\n';

	for (let name in icons) {
		newCss += generateCSS(name, icons[name]);
	}
	newCss += '/* ICONS END */\n';

	let file = fs.readFileSync('config/custom.css', 'utf8').split('\n');
	if (~file.indexOf('/* ICONS START */')) file.splice(file.indexOf('/* ICONS START */'), (file.indexOf('/* ICONS END */') - file.indexOf('/* ICONS START */')) + 1);
	fs.writeFileSync('config/custom.css', file.join('\n') + newCss);
	SG.reloadCSS();
}

function generateCSS(name, icon) {
	let css = '';
	let rooms = [];
	name = toId(name);
	Rooms.rooms.forEach((curRoom, id) => {
		if (curRoom.id === 'global' || curRoom.type !== 'chat' || curRoom.isPersonal) return;
		if (!isNaN(Number(id.charAt(0)))) return;
		rooms.push('#' + id + '-userlist-user-' + name);
	});
	css = rooms.join(', ');
	css += '{\nbackground: url("' + icon + '") no-repeat right\n}\n';
	return css;
}

exports.commands = {
	uli: 'icon',
	userlisticon: 'icon',
	customicon: 'icon',
	icon: {
		set: function (target, room, user) {
			if (!this.can('roomowner')) return false;
			target = target.split(',');
			for (let u in target) target[u] = target[u].trim();
			if (target.length !== 2) return this.parse('/help icon');
			if (toId(target[0]).length > 19) return this.errorReply("Usernames are not this long...");
			if (icons[toId(target[0])]) return this.errorReply("This user already has a custom userlist icon.  Do /icon delete [user] and then set their new icon.");
			this.sendReply("|raw|You have given " + SG.nameColor(target[0], true) + " an icon.");
			Rooms('upperstaff').add('|raw|' + SG.nameColor((target[0])) + ' has received an icon from ' + SG.nameColor(user.name), true).update();
			this.privateModCommand("|raw|(" + target[0] + " has recieved icon:  from " + user.name + ".)");
			if (Users(target[0]) && Users(target[0]).connected) Users(target[0]).popup("|html|" + SG.nameColor(user.name, true) + " has set your userlist icon to:
Refresh, If you don't see it.");
			icons[toId(target[0])] = target[1];
			updateIcons();
		},
		remove: 'delete',
		delete: function (target, room, user) {
			if (!this.can('roomowner')) return false;
			target = toId(target);
			if (!icons[toId(target)]) return this.errorReply('/icon - ' + target + ' does not have an icon.');
			delete icons[toId(target)];
			updateIcons();
			this.sendReply("You removed " + target + "'s icon.");
			Rooms('upperstaff').add('|raw|' + SG.nameColor(user.name, true) + " removed " + target + "'s icon.").update();
			this.privateModCommand("(" + target + "'s icon was removed by " + user.name + ".)");
			if (Users(target) && Users(target).connected) Users(target).popup("|html|" + SG.nameColor(user.name, true) + " has removed your userlist icon.");
		},
	},
	iconhelp: [
		"Commands Include:",
		"/icon set [user], [image url] - Gives [user] an icon of [image url]",
		"/icon delete [user] - Deletes a user's icon",
	],
};
<commit_msg>Update icons.js<commit_after>/*
* icons.js
* Credits: Lord Haji, panpawn
*/
'use strict';

let icons = {};
const fs = require('fs');

function load() {
	fs.readFile('config/icons.json', 'utf8', function (err, file) {
		if (err) return;
		icons = JSON.parse(file);
	});
}
load();

function updateIcons() {
	fs.writeFileSync('config/icons.json', JSON.stringify(icons));

	let newCss = '/* ICONS START */\n';

	for (let name in icons) {
		newCss += generateCSS(name, icons[name]);
	}
	newCss += '/* ICONS END */\n';

	let file = fs.readFileSync('config/custom.css', 'utf8').split('\n');
	if (~file.indexOf('/* ICONS START */')) file.splice(file.indexOf('/* ICONS START */'), (file.indexOf('/* ICONS END */') - file.indexOf('/* ICONS START */')) + 1);
	fs.writeFileSync('config/custom.css', file.join('\n') + newCss);
	SG.reloadCSS();
}

function generateCSS(name, icon) {
	let css = '';
	let rooms = [];
	name = toId(name);
	Rooms.rooms.forEach((curRoom, id) => {
		if (curRoom.id === 'global' || curRoom.type !== 'chat' || curRoom.isPersonal) return;
		if (!isNaN(Number(id.charAt(0)))) return;
		rooms.push('#' + id + '-userlist-user-' + name);
	});
	css = rooms.join(', ');
	css += '{\nbackground: url("' + icon + '") no-repeat right\n}\n';
	return css;
}

exports.commands = {
	uli: 'icon',
	userlisticon: 'icon',
	customicon: 'icon',
	icon: {
		set: function (target, room, user) {
			if (!this.can('roomowner')) return false;
			target = target.split(',');
			for (let u in target) target[u] = target[u].trim();
			if (target.length !== 2) return this.parse('/help icon');
			if (toId(target[0]).length > 19) return this.errorReply("Usernames are not this long...");
			if (icons[toId(target[0])]) return this.errorReply("This user already has a custom userlist icon.  Do /icon delete [user] and then set their new icon.");
			this.sendReply("|raw|You have given " + SG.nameColor(target[0], true) + " an icon.");
			Monitor.adminLog(target[0] + " has received an icon from " + user.name + ".");
			this.privateModCommand("|raw|(" + target[0] + " has recieved icon:  from " + user.name + ".)");
			if (Users(target[0]) && Users(target[0]).connected) Users(target[0]).popup("|html|" + SG.nameColor(user.name, true) + " has set your userlist icon to:
Refresh, If you don't see it.");
			icons[toId(target[0])] = target[1];
			updateIcons();
		},
		remove: 'delete',
		delete: function (target, room, user) {
			if (!this.can('roomowner')) return false;
			target = toId(target);
			if (!icons[toId(target)]) return this.errorReply('/icon - ' + target + ' does not have an icon.');
			delete icons[toId(target)];
			updateIcons();
			this.sendReply("You removed " + target + "'s icon.");
			Monitor.adminLog(user.name + " removed " + target + "'s icon.");
			this.privateModCommand("(" + target + "'s icon was removed by " + user.name + ".)");
			if (Users(target) && Users(target).connected) Users(target).popup("|html|" + SG.nameColor(user.name, true) + " has removed your userlist icon.");
		},
	},
	iconhelp: [
		"Commands Include:",
		"/icon set [user], [image url] - Gives [user] an icon of [image url]",
		"/icon delete [user] - Deletes a user's icon",
	],
};
<|endoftext|>


<commit_before>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

/* eslint-env jasmine */

var path = require('path');
var rewire = require('rewire');
var util = require('../src/cordova/util');
var cordova_config = require('../src/cordova/config');
var prepare = rewire('../src/cordova/prepare');
var restore = require('../src/cordova/restore-util');
var platforms = require('../src/platforms/platforms');
var HooksRunner = require('../src/hooks/HooksRunner');
var Q = require('q');
var PlatformJson = require('cordova-common').PlatformJson;

var project_dir = '/some/path';

describe('cordova/prepare', function () {
    var platform_api_prepare_mock;
    beforeEach(function () {
        platform_api_prepare_mock = jasmine.createSpy('prepare').and.returnValue(Q());
        spyOn(platforms, 'getPlatformApi').and.callFake(function (platform, rootDir) {
            return {
                prepare: platform_api_prepare_mock,
                getPlatformInfo: jasmine.createSpy('getPlatformInfo').and.returnValue({
                    locations: {
                        www: path.join(project_dir, 'platforms', platform, 'www')
                    }
                })
            };
        });
        spyOn(PlatformJson, 'load');
    });

    describe('main method', function () {
        beforeEach(function () {
            spyOn(util, 'cdProjectRoot').and.returnValue(project_dir);
            spyOn(util, 'preProcessOptions').and.returnValue({
                platforms: []
            });
            spyOn(cordova_config, 'read').and.returnValue({});
            spyOn(HooksRunner.prototype, 'fire').and.returnValue(Q());
            spyOn(restore, 'installPlatformsFromConfigXML').and.returnValue(Q());
            spyOn(restore, 'installPluginsFromConfigXML').and.returnValue(Q());
        });
        describe('failure', function () {
            it('should invoke util.preProcessOptions as preflight task checker, which, if fails, should trigger promise rejection');
            it('should not fire any hooks if preProcessOptions throws');
        });

        describe('success', function () {
            it('should fire the before_prepare hook and provide platform and path information as arguments');
            it('should invoke restore module\'s installPlatformsFromConfigXML method');
            it('should retrieve PlatformApi instances for each platform provided');
            it('should invoke restore module\'s installPluginsFromConfigXML method');
            it('should invoke preparePlatforms method, providing the appropriate platforms');
            it('should fire the after_prepare hook and provide platform and path information as arguments');
        });
    });

    describe('preparePlatforms helper method', function () {
        var cfg_parser_mock = function () {};
        var cfg_parser_revert_mock;
        var platform_munger_mock = function () {};
        var platform_munger_revert_mock;
        var platform_munger_save_mock;
        beforeEach(function () {
            cfg_parser_mock.prototype = jasmine.createSpyObj('config parser prototype mock', []);
            cfg_parser_revert_mock = prepare.__set__('ConfigParser', cfg_parser_mock);
            platform_munger_save_mock = jasmine.createSpy('platform munger save mock');
            platform_munger_mock.protytpe = jasmine.createSpyObj('platform munger prototype mock', ['add_config_changes']);
            platform_munger_mock.prototype.add_config_changes.and.returnValue({
                save_all: platform_munger_save_mock
            });
            platform_munger_revert_mock = prepare.__set__('PlatformMunger', platform_munger_mock);
            spyOn(util, 'projectConfig').and.returnValue(project_dir);
            spyOn(util, 'projectWww').and.returnValue(path.join(project_dir, 'www'));
            spyOn(prepare, 'restoreMissingPluginsForPlatform').and.returnValue(Q());
        });
        afterEach(function () {
            cfg_parser_revert_mock();
            platform_munger_revert_mock();
        });
        it('should call restoreMissingPluginsForPlatform');
        it('should retrieve the platform API via getPlatformApi per platform provided, and invoke the prepare method from that API');
        it('should fire a pre_package hook for the windows platform when the platform API is not an instance of PlatformApiPoly');
        // TODO: xit'ed the one below as dynamic requires make it difficult to spy on
        // Can we refactor the relevant code to make it testable?
        xit('should invoke browserify if the browserify option is provided');
        it('should handle config changes by invoking add_config_changes and save_all');
    });

    describe('restoreMissingPluginsForPlatform helper method', function () {
        var is_plugin_installed_mock;
        beforeEach(function () {
            is_plugin_installed_mock = jasmine.createSpy('is plugin installed mock');
            // mock platform json value below
            PlatformJson.load.and.returnValue({
                isPluginInstalled: is_plugin_installed_mock,
                root: {
                    installed_plugins: [],
                    dependent_plugins: []
                }
            });
        });
        it('should resolve quickly if there is no difference between "old" and "new" platform.json');
        it('should leverage platform API to remove and add any missing plugins identified');
    });
});
<commit_msg>CB-12361: added unit tests for prepare.spec.js<commit_after>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

/* eslint-env jasmine */

var path = require('path');
var rewire = require('rewire');
var util = require('../src/cordova/util');
var cordova_config = require('../src/cordova/config');
var prepare = rewire('../src/cordova/prepare');
var restore = require('../src/cordova/restore-util');
var platforms = require('../src/platforms/platforms');
var HooksRunner = require('../src/hooks/HooksRunner');
var Q = require('q');
var PlatformJson = require('cordova-common').PlatformJson;

var project_dir = '/some/path';

describe('cordova/prepare', function () {
    var platform_api_prepare_mock;
    beforeEach(function () {
        platform_api_prepare_mock = jasmine.createSpy('prepare').and.returnValue(Q());
        spyOn(platforms, 'getPlatformApi').and.callFake(function (platform, rootDir) {
            return {
                prepare: platform_api_prepare_mock,
                getPlatformInfo: jasmine.createSpy('getPlatformInfo').and.returnValue({
                    locations: {
                        www: path.join(project_dir, 'platforms', platform, 'www')
                    }
                })
            };
        });
        spyOn(PlatformJson, 'load');
    });

    describe('main method', function () {
        beforeEach(function () {
            spyOn(cordova_config, 'read').and.returnValue({});
            spyOn(HooksRunner.prototype, 'fire').and.returnValue(Q());
            spyOn(restore, 'installPlatformsFromConfigXML').and.returnValue(Q());
            spyOn(restore, 'installPluginsFromConfigXML').and.returnValue(Q());
            spyOn(util, 'isCordova').and.returnValue(true);
            spyOn(prepare, 'preparePlatforms').and.returnValue(Q);
        });
        describe('failure', function () {
            it('should invoke util.preProcessOptions as preflight task checker, which, if fails, should trigger promise rejection and only fire the before_prepare hook', function(done) {
                spyOn(util, 'cdProjectRoot').and.returnValue(project_dir);
                spyOn(util, 'preProcessOptions').and.throwError();
                prepare({}).fail(function(err) {
                    expect(err).toBeDefined();
                    expect(HooksRunner.prototype.fire.calls.count()).toBe(1);
                    expect(HooksRunner.prototype.fire.calls.argsFor(0)[0]).toEqual('before_prepare');
                    done();
                });
            });
            it('should invoke util.cdProjectRoot as a preflight task checker, which, if fails, should trigger a promise rejection and fire no hooks', function(done) {
                spyOn(util, 'cdProjectRoot').and.throwError();
                prepare({}).fail(function(err) {
                    expect(err).toBeDefined();
                    expect(HooksRunner.prototype.fire.calls.any()).toBe(false);
                    done();
                });
            });
        });

        describe('success', function () {
            beforeEach(function () {
                spyOn(util, 'cdProjectRoot').and.returnValue(project_dir);
                spyOn(util, 'preProcessOptions').and.callFake(function(options) {
                    let platforms = options.platforms || []
                    return {'platforms':platforms}
                });
            });
            it('should fire the before_prepare hook and provide platform and path information as arguments', function(done) {
                prepare({}).then(function() {
                    expect(HooksRunner.prototype.fire.calls.argsFor(0)[0]).toEqual('before_prepare');
                    done();
                })
            });
            it('should invoke restore module\'s installPlatformsFromConfigXML method', function(done) {
                prepare({}).then(function() {
                    expect(restore.installPlatformsFromConfigXML).toHaveBeenCalled();
                    done();
                }).fail(function(err){
                    console.log(err);
                    expect(err).toBeUndefined();
                    done();
                });
            });
            it('should retrieve PlatformApi instances for each platform provided', function(done) {
                prepare({'platforms':['android', 'ios']}).then(function() {
                    expect(platforms.getPlatformApi.calls.count()).toBe(4);
                    expect(platforms.getPlatformApi.calls.argsFor(0)[0]).toBe('android');
                    expect(platforms.getPlatformApi.calls.argsFor(0)[1]).toBe('/some/path/platforms/android');
                    expect(platforms.getPlatformApi.calls.argsFor(1)[0]).toBe('ios');
                    expect(platforms.getPlatformApi.calls.argsFor(1)[1]).toBe('/some/path/platforms/ios');
                    expect(platforms.getPlatformApi.calls.argsFor(2)[0]).toBe('android');
                    expect(platforms.getPlatformApi.calls.argsFor(3)[0]).toBe('ios');

                    done();
                }).fail(function(err){
                    console.log(err);
                    expect(err).toBeUndefined();
                    done();
                });
            });
            it('should invoke restore module\'s installPluginsFromConfigXML method', function(done) {
                prepare({platforms:[]}).then(function() {
                    //expect(true).toHaveBeenCalled();
                    done();
                });
            });
            it('should invoke preparePlatforms method, providing the appropriate platforms');
            it('should fire the after_prepare hook and provide platform and path information as arguments', function(done) {
                prepare({}).then(function() {
                    expect(HooksRunner.prototype.fire.calls.argsFor(1)[0]).toEqual('after_prepare');
                    expect(HooksRunner.prototype.fire.calls.argsFor(1)[1]).toEqual({ 'platforms': [], 'paths': [], 'searchpath': undefined });
                    done();
                });
            });
        });
    });

    describe('preparePlatforms helper method', function () {
        var cfg_parser_mock = function () {};
        var cfg_parser_revert_mock;
        var platform_munger_mock = function () {};
        var platform_munger_revert_mock;
        var platform_munger_save_mock;
        beforeEach(function () {
            cfg_parser_mock.prototype = jasmine.createSpyObj('config parser prototype mock', []);
            cfg_parser_revert_mock = prepare.__set__('ConfigParser', cfg_parser_mock);
            platform_munger_save_mock = jasmine.createSpy('platform munger save mock');
            platform_munger_mock.protytpe = jasmine.createSpyObj('platform munger prototype mock', ['add_config_changes']);
            platform_munger_mock.prototype.add_config_changes.and.returnValue({
                save_all: platform_munger_save_mock
            });
            platform_munger_revert_mock = prepare.__set__('PlatformMunger', platform_munger_mock);
            spyOn(util, 'projectConfig').and.returnValue(project_dir);
            spyOn(util, 'projectWww').and.returnValue(path.join(project_dir, 'www'));
            spyOn(prepare, 'restoreMissingPluginsForPlatform').and.returnValue(Q());
        });
        afterEach(function () {
            cfg_parser_revert_mock();
            platform_munger_revert_mock();
        });
        it('should call restoreMissingPluginsForPlatform');
        it('should retrieve the platform API via getPlatformApi per platform provided, and invoke the prepare method from that API');
        it('should fire a pre_package hook for the windows platform when the platform API is not an instance of PlatformApiPoly');
        // TODO: xit'ed the one below as dynamic requires make it difficult to spy on
        // Can we refactor the relevant code to make it testable?
        xit('should invoke browserify if the browserify option is provided');
        it('should handle config changes by invoking add_config_changes and save_all');
    });

    describe('restoreMissingPluginsForPlatform helper method', function () {
        var is_plugin_installed_mock;
        beforeEach(function () {
            is_plugin_installed_mock = jasmine.createSpy('is plugin installed mock');
            // mock platform json value below
            PlatformJson.load.and.returnValue({
                isPluginInstalled: is_plugin_installed_mock,
                root: {
                    installed_plugins: [],
                    dependent_plugins: []
                }
            });
        });
        it('should resolve quickly if there is no difference between "old" and "new" platform.json');
        it('should leverage platform API to remove and add any missing plugins identified');
    });
});
<|endoftext|>


<commit_before>import { Session } from 'meteor/session';
import { Template } from 'meteor/templating';
import { $ } from 'meteor/jquery';

import '/imports/ui/components/regions/selection/region-selection.js';

import './region-splash.html';

Template.regionsSplash.onRendered(function regionsSplashOnRendered() {
	this.$('#regionsSplash').modal('show');
});

Template.regionsSplash.events({
	'hidden.bs.modal #regionsSplash'() {
		const regionId = Session.get('region') || 'all';
		try {
			localStorage.setItem("region", regionId); // to survive page reload
		} catch (e) {
			console.error(e);
		}

		Session.set('showRegionSplash', false);
	},

	'click .js-region-search'(event, instance) {
		instance.$(event.currentTarget).select();
	},

	'click #confirmRegion'(event, instance) {
		instance.$('#regionsSplash').modal('hide');
	},

	'click #loginForRegion'(event, instance) {
		$('#accountTasks').modal('show');
		instance.$('#regionsSplash').modal('hide');
	}
});
<commit_msg>close region splash when clicking on region closes #1069<commit_after>import { Session } from 'meteor/session';
import { Template } from 'meteor/templating';
import { $ } from 'meteor/jquery';

import '/imports/ui/components/regions/selection/region-selection.js';

import './region-splash.html';

Template.regionsSplash.onRendered(function regionsSplashOnRendered() {
	this.$('#regionsSplash').modal('show');
});

Template.regionsSplash.events({
	'hidden.bs.modal #regionsSplash'() {
		const regionId = Session.get('region') || 'all';
		try {
			localStorage.setItem("region", regionId); // to survive page reload
		} catch (e) {
			console.error(e);
		}

		Session.set('showRegionSplash', false);
	},

	'click .js-region-link'(event, instance) {
		instance.$('#regionsSplash').modal('hide');
	},

	'click .js-region-search'(event, instance) {
		instance.$(event.currentTarget).select();
	},

	'click #confirmRegion'(event, instance) {
		instance.$('#regionsSplash').modal('hide');
	},

	'click #loginForRegion'(event, instance) {
		$('#accountTasks').modal('show');
		instance.$('#regionsSplash').modal('hide');
	}
});
<|endoftext|>


<commit_before>/* eslint-disable prefer-const */
/* eslint-disable no-var */
/* eslint-disable vars-on-top */
/* eslint-disable no-unused-vars */
/* eslint-disable func-names */
/* eslint-disable camelcase */
/* eslint-disable no-undef */
/* eslint-disable no-new-func */
/* eslint-disable strict */

/**
 * @fileoverview
 * @enhanceable
 * @public
 */
// GENERATED CODE -- DO NOT EDIT!

const jspb = require('google-protobuf');

const goog = jspb;
const global = Function('return this')();

goog.exportSymbol('proto.helloworld.HelloReply', null, global);
goog.exportSymbol('proto.helloworld.HelloRequest', null, global);

/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.helloworld.HelloRequest = function (opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.helloworld.HelloRequest, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  proto.helloworld.HelloRequest.displayName = 'proto.helloworld.HelloRequest';
}

if (jspb.Message.GENERATE_TO_OBJECT) {
  /**
   * Creates an object representation of this proto suitable for use in Soy templates.
   * Field names that are reserved in JavaScript and will be renamed to pb_name.
   * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
   * For the list of reserved names please see:
   *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
   * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
   *     for transitional soy proto support: http://goto/soy-param-migration
   * @return {!Object}
   */
  proto.helloworld.HelloRequest.prototype.toObject = function (
    opt_includeInstance,
  ) {
    return proto.helloworld.HelloRequest.toObject(opt_includeInstance, this);
  };

  /**
   * Static version of the {@see toObject} method.
   * @param {boolean|undefined} includeInstance Whether to include the JSPB
   *     instance for transitional soy proto support:
   *     http://goto/soy-param-migration
   * @param {!proto.helloworld.HelloRequest} msg The msg instance to transform.
   * @return {!Object}
   */
  proto.helloworld.HelloRequest.toObject = function (includeInstance, msg) {
    let f;

    const obj = {
      name: msg.getName(),
    };

    if (includeInstance) {
      obj.$jspbMessageInstance = msg;
    }
    return obj;
  };
}

/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.helloworld.HelloRequest}
 */
proto.helloworld.HelloRequest.deserializeBinary = function (bytes) {
  const reader = new jspb.BinaryReader(bytes);
  const msg = new proto.helloworld.HelloRequest();
  return proto.helloworld.HelloRequest.deserializeBinaryFromReader(msg, reader);
};

/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.helloworld.HelloRequest} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.helloworld.HelloRequest}
 */
proto.helloworld.HelloRequest.deserializeBinaryFromReader = function (
  msg,
  reader,
) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    const field = reader.getFieldNumber();
    switch (field) {
      case 1:
        var value = /** @type {string} */ (reader.readString());
        msg.setName(value);
        break;
      default:
        reader.skipField();
        break;
    }
  }
  return msg;
};

/**
 * Class method variant: serializes the given message to binary data
 * (in protobuf wire format), writing to the given BinaryWriter.
 * @param {!proto.helloworld.HelloRequest} message
 * @param {!jspb.BinaryWriter} writer
 */
proto.helloworld.HelloRequest.serializeBinaryToWriter = function (
  message,
  writer,
) {
  message.serializeBinaryToWriter(writer);
};

/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.helloworld.HelloRequest.prototype.serializeBinary = function () {
  const writer = new jspb.BinaryWriter();
  this.serializeBinaryToWriter(writer);
  return writer.getResultBuffer();
};

/**
 * Serializes the message to binary data (in protobuf wire format),
 * writing to the given BinaryWriter.
 * @param {!jspb.BinaryWriter} writer
 */
proto.helloworld.HelloRequest.prototype.serializeBinaryToWriter = function (
  writer,
) {
  let f;
  f = this.getName();
  if (f.length > 0) {
    writer.writeString(1, f);
  }
};

/**
 * Creates a deep clone of this proto. No data is shared with the original.
 * @return {!proto.helloworld.HelloRequest} The clone.
 */
proto.helloworld.HelloRequest.prototype.cloneMessage = function () {
  return /** @type {!proto.helloworld.HelloRequest} */ (jspb.Message.cloneMessage(
    this,
  ));
};

/**
 * optional string name = 1;
 * @return {string}
 */
proto.helloworld.HelloRequest.prototype.getName = function () {
  return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, ''));
};

/** @param {string} value  */
proto.helloworld.HelloRequest.prototype.setName = function (value) {
  jspb.Message.setField(this, 1, value);
};

/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.helloworld.HelloReply = function (opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.helloworld.HelloReply, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  proto.helloworld.HelloReply.displayName = 'proto.helloworld.HelloReply';
}

if (jspb.Message.GENERATE_TO_OBJECT) {
  /**
   * Creates an object representation of this proto suitable for use in Soy templates.
   * Field names that are reserved in JavaScript and will be renamed to pb_name.
   * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
   * For the list of reserved names please see:
   *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
   * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
   *     for transitional soy proto support: http://goto/soy-param-migration
   * @return {!Object}
   */
  proto.helloworld.HelloReply.prototype.toObject = function (
    opt_includeInstance,
  ) {
    return proto.helloworld.HelloReply.toObject(opt_includeInstance, this);
  };

  /**
   * Static version of the {@see toObject} method.
   * @param {boolean|undefined} includeInstance Whether to include the JSPB
   *     instance for transitional soy proto support:
   *     http://goto/soy-param-migration
   * @param {!proto.helloworld.HelloReply} msg The msg instance to transform.
   * @return {!Object}
   */
  proto.helloworld.HelloReply.toObject = function (includeInstance, msg) {
    let f;

    const obj = {
      message: msg.getMessage(),
    };

    if (includeInstance) {
      obj.$jspbMessageInstance = msg;
    }
    return obj;
  };
}

/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.helloworld.HelloReply}
 */
proto.helloworld.HelloReply.deserializeBinary = function (bytes) {
  const reader = new jspb.BinaryReader(bytes);
  const msg = new proto.helloworld.HelloReply();
  return proto.helloworld.HelloReply.deserializeBinaryFromReader(msg, reader);
};

/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.helloworld.HelloReply} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.helloworld.HelloReply}
 */
proto.helloworld.HelloReply.deserializeBinaryFromReader = function (
  msg,
  reader,
) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    const field = reader.getFieldNumber();
    switch (field) {
      case 1:
        var value = /** @type {string} */ (reader.readString());
        msg.setMessage(value);
        break;
      default:
        reader.skipField();
        break;
    }
  }
  return msg;
};

/**
 * Class method variant: serializes the given message to binary data
 * (in protobuf wire format), writing to the given BinaryWriter.
 * @param {!proto.helloworld.HelloReply} message
 * @param {!jspb.BinaryWriter} writer
 */
proto.helloworld.HelloReply.serializeBinaryToWriter = function (
  message,
  writer,
) {
  message.serializeBinaryToWriter(writer);
};

/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.helloworld.HelloReply.prototype.serializeBinary = function () {
  const writer = new jspb.BinaryWriter();
  this.serializeBinaryToWriter(writer);
  return writer.getResultBuffer();
};

/**
 * Serializes the message to binary data (in protobuf wire format),
 * writing to the given BinaryWriter.
 * @param {!jspb.BinaryWriter} writer
 */
proto.helloworld.HelloReply.prototype.serializeBinaryToWriter = function (
  writer,
) {
  let f;
  f = this.getMessage();
  if (f.length > 0) {
    writer.writeString(1, f);
  }
};

/**
 * Creates a deep clone of this proto. No data is shared with the original.
 * @return {!proto.helloworld.HelloReply} The clone.
 */
proto.helloworld.HelloReply.prototype.cloneMessage = function () {
  return /** @type {!proto.helloworld.HelloReply} */ (jspb.Message.cloneMessage(
    this,
  ));
};

/**
 * optional string message = 1;
 * @return {string}
 */
proto.helloworld.HelloReply.prototype.getMessage = function () {
  return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, ''));
};

/** @param {string} value  */
proto.helloworld.HelloReply.prototype.setMessage = function (value) {
  jspb.Message.setField(this, 1, value);
};

goog.object.extend(exports, proto.helloworld);
<commit_msg>chore: remove double blank lines (#1185)<commit_after>/* eslint-disable prefer-const */
/* eslint-disable no-var */
/* eslint-disable vars-on-top */
/* eslint-disable no-unused-vars */
/* eslint-disable func-names */
/* eslint-disable camelcase */
/* eslint-disable no-undef */
/* eslint-disable no-new-func */
/* eslint-disable strict */

/**
 * @fileoverview
 * @enhanceable
 * @public
 */
// GENERATED CODE -- DO NOT EDIT!

const jspb = require('google-protobuf');

const goog = jspb;
const global = Function('return this')();

goog.exportSymbol('proto.helloworld.HelloReply', null, global);
goog.exportSymbol('proto.helloworld.HelloRequest', null, global);

/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.helloworld.HelloRequest = function (opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.helloworld.HelloRequest, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  proto.helloworld.HelloRequest.displayName = 'proto.helloworld.HelloRequest';
}

if (jspb.Message.GENERATE_TO_OBJECT) {
  /**
   * Creates an object representation of this proto suitable for use in Soy templates.
   * Field names that are reserved in JavaScript and will be renamed to pb_name.
   * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
   * For the list of reserved names please see:
   *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
   * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
   *     for transitional soy proto support: http://goto/soy-param-migration
   * @return {!Object}
   */
  proto.helloworld.HelloRequest.prototype.toObject = function (
    opt_includeInstance,
  ) {
    return proto.helloworld.HelloRequest.toObject(opt_includeInstance, this);
  };

  /**
   * Static version of the {@see toObject} method.
   * @param {boolean|undefined} includeInstance Whether to include the JSPB
   *     instance for transitional soy proto support:
   *     http://goto/soy-param-migration
   * @param {!proto.helloworld.HelloRequest} msg The msg instance to transform.
   * @return {!Object}
   */
  proto.helloworld.HelloRequest.toObject = function (includeInstance, msg) {
    let f;

    const obj = {
      name: msg.getName(),
    };

    if (includeInstance) {
      obj.$jspbMessageInstance = msg;
    }
    return obj;
  };
}

/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.helloworld.HelloRequest}
 */
proto.helloworld.HelloRequest.deserializeBinary = function (bytes) {
  const reader = new jspb.BinaryReader(bytes);
  const msg = new proto.helloworld.HelloRequest();
  return proto.helloworld.HelloRequest.deserializeBinaryFromReader(msg, reader);
};

/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.helloworld.HelloRequest} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.helloworld.HelloRequest}
 */
proto.helloworld.HelloRequest.deserializeBinaryFromReader = function (
  msg,
  reader,
) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    const field = reader.getFieldNumber();
    switch (field) {
      case 1:
        var value = /** @type {string} */ (reader.readString());
        msg.setName(value);
        break;
      default:
        reader.skipField();
        break;
    }
  }
  return msg;
};

/**
 * Class method variant: serializes the given message to binary data
 * (in protobuf wire format), writing to the given BinaryWriter.
 * @param {!proto.helloworld.HelloRequest} message
 * @param {!jspb.BinaryWriter} writer
 */
proto.helloworld.HelloRequest.serializeBinaryToWriter = function (
  message,
  writer,
) {
  message.serializeBinaryToWriter(writer);
};

/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.helloworld.HelloRequest.prototype.serializeBinary = function () {
  const writer = new jspb.BinaryWriter();
  this.serializeBinaryToWriter(writer);
  return writer.getResultBuffer();
};

/**
 * Serializes the message to binary data (in protobuf wire format),
 * writing to the given BinaryWriter.
 * @param {!jspb.BinaryWriter} writer
 */
proto.helloworld.HelloRequest.prototype.serializeBinaryToWriter = function (
  writer,
) {
  let f;
  f = this.getName();
  if (f.length > 0) {
    writer.writeString(1, f);
  }
};

/**
 * Creates a deep clone of this proto. No data is shared with the original.
 * @return {!proto.helloworld.HelloRequest} The clone.
 */
proto.helloworld.HelloRequest.prototype.cloneMessage = function () {
  return /** @type {!proto.helloworld.HelloRequest} */ (jspb.Message.cloneMessage(
    this,
  ));
};

/**
 * optional string name = 1;
 * @return {string}
 */
proto.helloworld.HelloRequest.prototype.getName = function () {
  return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, ''));
};

/** @param {string} value  */
proto.helloworld.HelloRequest.prototype.setName = function (value) {
  jspb.Message.setField(this, 1, value);
};

/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.helloworld.HelloReply = function (opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.helloworld.HelloReply, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  proto.helloworld.HelloReply.displayName = 'proto.helloworld.HelloReply';
}

if (jspb.Message.GENERATE_TO_OBJECT) {
  /**
   * Creates an object representation of this proto suitable for use in Soy templates.
   * Field names that are reserved in JavaScript and will be renamed to pb_name.
   * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
   * For the list of reserved names please see:
   *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
   * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
   *     for transitional soy proto support: http://goto/soy-param-migration
   * @return {!Object}
   */
  proto.helloworld.HelloReply.prototype.toObject = function (
    opt_includeInstance,
  ) {
    return proto.helloworld.HelloReply.toObject(opt_includeInstance, this);
  };

  /**
   * Static version of the {@see toObject} method.
   * @param {boolean|undefined} includeInstance Whether to include the JSPB
   *     instance for transitional soy proto support:
   *     http://goto/soy-param-migration
   * @param {!proto.helloworld.HelloReply} msg The msg instance to transform.
   * @return {!Object}
   */
  proto.helloworld.HelloReply.toObject = function (includeInstance, msg) {
    let f;

    const obj = {
      message: msg.getMessage(),
    };

    if (includeInstance) {
      obj.$jspbMessageInstance = msg;
    }
    return obj;
  };
}

/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.helloworld.HelloReply}
 */
proto.helloworld.HelloReply.deserializeBinary = function (bytes) {
  const reader = new jspb.BinaryReader(bytes);
  const msg = new proto.helloworld.HelloReply();
  return proto.helloworld.HelloReply.deserializeBinaryFromReader(msg, reader);
};

/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.helloworld.HelloReply} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.helloworld.HelloReply}
 */
proto.helloworld.HelloReply.deserializeBinaryFromReader = function (
  msg,
  reader,
) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    const field = reader.getFieldNumber();
    switch (field) {
      case 1:
        var value = /** @type {string} */ (reader.readString());
        msg.setMessage(value);
        break;
      default:
        reader.skipField();
        break;
    }
  }
  return msg;
};

/**
 * Class method variant: serializes the given message to binary data
 * (in protobuf wire format), writing to the given BinaryWriter.
 * @param {!proto.helloworld.HelloReply} message
 * @param {!jspb.BinaryWriter} writer
 */
proto.helloworld.HelloReply.serializeBinaryToWriter = function (
  message,
  writer,
) {
  message.serializeBinaryToWriter(writer);
};

/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.helloworld.HelloReply.prototype.serializeBinary = function () {
  const writer = new jspb.BinaryWriter();
  this.serializeBinaryToWriter(writer);
  return writer.getResultBuffer();
};

/**
 * Serializes the message to binary data (in protobuf wire format),
 * writing to the given BinaryWriter.
 * @param {!jspb.BinaryWriter} writer
 */
proto.helloworld.HelloReply.prototype.serializeBinaryToWriter = function (
  writer,
) {
  let f;
  f = this.getMessage();
  if (f.length > 0) {
    writer.writeString(1, f);
  }
};

/**
 * Creates a deep clone of this proto. No data is shared with the original.
 * @return {!proto.helloworld.HelloReply} The clone.
 */
proto.helloworld.HelloReply.prototype.cloneMessage = function () {
  return /** @type {!proto.helloworld.HelloReply} */ (jspb.Message.cloneMessage(
    this,
  ));
};

/**
 * optional string message = 1;
 * @return {string}
 */
proto.helloworld.HelloReply.prototype.getMessage = function () {
  return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, ''));
};

/** @param {string} value  */
proto.helloworld.HelloReply.prototype.setMessage = function (value) {
  jspb.Message.setField(this, 1, value);
};

goog.object.extend(exports, proto.helloworld);
<|endoftext|>


<commit_before>'use strict';

/**
 * This post-processing step iterates the newly indexed assets in the
 * ElasticSearch index and sets their in_artifact_rotation_series and updates
 * their is_searchable value, so only the front-facing rotational image is
 * reachable when searching.
 */

var Q = require('q');
var _ = require('lodash');
var es = require('../../lib/services/elasticsearch');
var config = require('../../lib/config');

// TODO: Consider taking the 'Rotationsbilleder' category name from a
// configuration file.
const ROTATIONAL_IMAGES_RELATION_UUID = '9ed0887f-40e8-4091-a91c-de356c869251';

module.exports = function(state) {
  var activity = 'Post-processing to derive rotational series';
  console.log('\n=== ' + activity + ' ===');

  // Let's take the queries one by one.
  return state.queries.reduce(function(state, query) {
    return state.then(function(state) {
      // First searching the elasticsearch index for assets that has been
      // indexed in this run and has master assets, gathering these master
      // assets ids as they may be main/frontal asset of a rotational series,
      // which turns the particular asset to be a part of a rotational series.
      var additionalAssetIds = [];

      return es.scrollSearch({
        'query': {
          'bool': {
            'must': [{
              'ids': {
                'values': query.indexedAssetIds
              }
            }, {
              'match': {
                'related_master_assets.relation':
                  ROTATIONAL_IMAGES_RELATION_UUID
              }
            }]
          }
        }
      }, function(hit) {
        // Determine whether or not this asset has a relation to a master
        // asset which is a main front facing image.
        var catalogAlias = hit._source.catalog;
        var masterAssets = hit._source.related_master_assets;
        masterAssets.forEach(function(masterAsset) {
          additionalAssetIds.push(catalogAlias + '-' + masterAsset.id);
        });
      }).then(function() {
        // Search for all assets that has been indexed in this run and which is
        // either in the rotational image category or has a master asset that
        // might be in the rotational image category.
        return es.scrollSearch({
          'query': {
            'bool': {
              'must': [{
                'ids': {
                  'values': _.union(query.indexedAssetIds, additionalAssetIds)
                }
              }, {
                'match': {
                  'categories.name':
                    config.cip.rotationCategoryName
                }
              }]
            }
          }
        }, function(hit) {
          // Update the master asset so it's in_artifact_rotation_series is true
          // and the artifact_rotation_series_rank is 0.
          var actions = [
            {update: {_id: hit._id}},
            {
              doc: {
                'in_artifact_rotation_series': true,
                'artifact_rotation_series_rank': 0
              }
            }
          ];
          // Update all the sub-assets so their in_artifact_rotation_series is
          // true, their artifact_rotation_series_rank reflects their order in
          // the master assets related sub assets and their is_searchable is
          // false.
          var subAssets = hit._source.related_sub_assets || [];
          subAssets.filter(function(subAsset) {
            return subAsset.relation === ROTATIONAL_IMAGES_RELATION_UUID;
          }).forEach(function(subAsset, subAssetIndex) {
            var subAssetId = hit._source.catalog + '-' + subAsset.id;
            actions.push({update: {_id: subAssetId}});
            actions.push({
              doc: {
                'in_artifact_rotation_series': true,
                'artifact_rotation_series_rank': subAssetIndex + 1,
                'is_searchable': false
              }
            });
          });

          console.log('Updating a rotational master asset (' +
                      hit._id + ') and it´s',
                      subAssets.length,
                      'sub-assets.');
          return es.bulk({
            index: state.index,
            type: 'asset',
            body: actions
          });
        });
      }).then(() => {
        return state;
      });
    });
  }, new Q(state));
};
<commit_msg>Only run in rotation series post processing when the correct config is there<commit_after>'use strict';

/**
 * This post-processing step iterates the newly indexed assets in the
 * ElasticSearch index and sets their in_artifact_rotation_series and updates
 * their is_searchable value, so only the front-facing rotational image is
 * reachable when searching.
 */

var Q = require('q');
var _ = require('lodash');
var es = require('../../lib/services/elasticsearch');
var config = require('../../lib/config');

// TODO: Consider taking the 'Rotationsbilleder' category name from a
// configuration file.
const ROTATIONAL_IMAGES_RELATION_UUID = '9ed0887f-40e8-4091-a91c-de356c869251';

module.exports = function(state) {
  var activity = 'Post-processing to derive rotational series';
  console.log('\n=== ' + activity + ' ===');

  // This should only run when a rotational category name is set.
  if(!config.cip.rotationCategoryName) {
    console.log('Skipping this, as the rotationCategoryName is not provided.');
    return state;
  }

  // Let's take the queries one by one.
  return state.queries.reduce(function(state, query) {
    return state.then(function(state) {
      // First searching the elasticsearch index for assets that has been
      // indexed in this run and has master assets, gathering these master
      // assets ids as they may be main/frontal asset of a rotational series,
      // which turns the particular asset to be a part of a rotational series.
      var additionalAssetIds = [];

      return es.scrollSearch({
        'query': {
          'bool': {
            'must': [{
              'ids': {
                'values': query.indexedAssetIds
              }
            }, {
              'match': {
                'related_master_assets.relation':
                  ROTATIONAL_IMAGES_RELATION_UUID
              }
            }]
          }
        }
      }, function(hit) {
        // Determine whether or not this asset has a relation to a master
        // asset which is a main front facing image.
        var catalogAlias = hit._source.catalog;
        var masterAssets = hit._source.related_master_assets;
        masterAssets.forEach(function(masterAsset) {
          additionalAssetIds.push(catalogAlias + '-' + masterAsset.id);
        });
      }).then(function() {
        // Search for all assets that has been indexed in this run and which is
        // either in the rotational image category or has a master asset that
        // might be in the rotational image category.
        return es.scrollSearch({
          'query': {
            'bool': {
              'must': [{
                'ids': {
                  'values': _.union(query.indexedAssetIds, additionalAssetIds)
                }
              }, {
                'match': {
                  'categories.name':
                    config.cip.rotationCategoryName
                }
              }]
            }
          }
        }, function(hit) {
          // Update the master asset so it's in_artifact_rotation_series is true
          // and the artifact_rotation_series_rank is 0.
          var actions = [
            {update: {_id: hit._id}},
            {
              doc: {
                'in_artifact_rotation_series': true,
                'artifact_rotation_series_rank': 0
              }
            }
          ];
          // Update all the sub-assets so their in_artifact_rotation_series is
          // true, their artifact_rotation_series_rank reflects their order in
          // the master assets related sub assets and their is_searchable is
          // false.
          var subAssets = hit._source.related_sub_assets || [];
          subAssets.filter(function(subAsset) {
            return subAsset.relation === ROTATIONAL_IMAGES_RELATION_UUID;
          }).forEach(function(subAsset, subAssetIndex) {
            var subAssetId = hit._source.catalog + '-' + subAsset.id;
            actions.push({update: {_id: subAssetId}});
            actions.push({
              doc: {
                'in_artifact_rotation_series': true,
                'artifact_rotation_series_rank': subAssetIndex + 1,
                'is_searchable': false
              }
            });
          });

          console.log('Updating a rotational master asset (' +
                      hit._id + ') and it´s',
                      subAssets.length,
                      'sub-assets.');
          return es.bulk({
            index: state.index,
            type: 'asset',
            body: actions
          });
        });
      }).then(() => {
        return state;
      });
    });
  }, new Q(state));
};
<|endoftext|>


<commit_before>dojo.provide("dojox.form.BusyButton");

dojo.require("dijit.form.Button");

dojo.requireLocalization("dijit", "loading");

dojo.declare("dojox.form.BusyButton",
	[dijit.form.Button],
	{

	isBusy: false,
	busyLabel: "", // text while button is busy
	timeout: null, // timeout, should be controlled by xhr call
	useIcon: true, // use a busy icon

	postMixInProperties: function(){
		this.inherited(arguments);
		if(!this.busyLabel){
			this.busyLabel = dojo.i18n.getLocalization("dijit", "loading", this.lang).loadingState;
		}
	},

	postCreate: function(){
		// summary:
		//	stores initial label and timeout for reference
		this._label = this.containerNode.innerHTML;
		this._initTimeout = this.timeout;

		// for initial busy buttons
		if(this.isBusy){
			this.makeBusy();
		}
	},

	makeBusy: function(){
		// summary:
		//	sets state from idle to busy
		this.isBusy = true;
		this.setAttribute("disabled", true);

		this.setLabel(this.busyLabel, this.timeout);
	},

	cancel: function(){
		// summary:
		//	if no timeout is set or for other reason the user can put the button back
		//  to being idle
		this.setAttribute("disabled", false);
		this.isBusy = false;
		this.setLabel(this._label);
		if(this._timeout){	clearTimeout(this._timeout); }
		this.timeout = this._initTimeout;
	},

	resetTimeout: function(/*Int*/ timeout){
		// summary:
		//	to reset existing timeout and setting a new timeout
		if(this._timeout){
			clearTimeout(this._timeout);
		}

		// new timeout
		if(timeout){
			this._timeout = setTimeout(dojo.hitch(this, function(){
				this.cancel();
			}), timeout);
		}
	},

	setLabel: function(/*String*/ content, /*Int*/ timeout){
		// summary:
		//	setting a label and optional timeout of the labels state

		// this.inherited(arguments); FIXME: throws an Unknown runtime error

		// Begin IE hack
		// summary: reset the label (text) of the button; takes an HTML string
		this.label = content;
		// remove children
		while (this.containerNode.firstChild){
			this.containerNode.removeChild(this.containerNode.firstChild);
		}
		this.containerNode.appendChild(document.createTextNode(this.label));

		this._layoutHack();
		if(this.showLabel == false && !(dojo.attr(this.domNode, "title"))){
			this.titleNode.title=dojo.trim(this.containerNode.innerText || this.containerNode.textContent || '');
		}
		// End IE hack

		// setting timeout
		if(timeout){
			this.resetTimeout(timeout);
		}else{
			this.timeout = null;
		}

		// create optional busy image
		if(this.useIcon && this.isBusy){
			var node = new Image();
			node.src = this._blankGif;
			dojo.attr(node, "id", this.id+"_icon");
			dojo.addClass(node, "dojoxBusyButtonIcon");
			this.containerNode.appendChild(node);
		}
	},

	_clicked: function(e){
		// summary:
		//	on button click the button state gets changed

		// only do something if button is not busy
		if(!this.isBusy){
			this.makeBusy();
		}
	}
});<commit_msg>Refs #7347 - resetting the timeout with 0 or undefined will clear it immediately<commit_after>dojo.provide("dojox.form.BusyButton");

dojo.require("dijit.form.Button");

dojo.requireLocalization("dijit", "loading");

dojo.declare("dojox.form.BusyButton",
	[dijit.form.Button],
	{

	isBusy: false,
	busyLabel: "", // text while button is busy
	timeout: null, // timeout, should be controlled by xhr call
	useIcon: true, // use a busy icon

	postMixInProperties: function(){
		this.inherited(arguments);
		if(!this.busyLabel){
			this.busyLabel = dojo.i18n.getLocalization("dijit", "loading", this.lang).loadingState;
		}
	},

	postCreate: function(){
		// summary:
		//	stores initial label and timeout for reference
		this._label = this.containerNode.innerHTML;
		this._initTimeout = this.timeout;

		// for initial busy buttons
		if(this.isBusy){
			this.makeBusy();
		}
	},

	makeBusy: function(){
		// summary:
		//	sets state from idle to busy
		this.isBusy = true;
		this.setAttribute("disabled", true);

		this.setLabel(this.busyLabel, this.timeout);
	},

	cancel: function(){
		// summary:
		//	if no timeout is set or for other reason the user can put the button back
		//  to being idle
		this.setAttribute("disabled", false);
		this.isBusy = false;
		this.setLabel(this._label);
		if(this._timeout){	clearTimeout(this._timeout); }
		this.timeout = this._initTimeout;
	},

	resetTimeout: function(/*Int*/ timeout){
		// summary:
		//	to reset existing timeout and setting a new timeout
		if(this._timeout){
			clearTimeout(this._timeout);
		}

		// new timeout
		if(timeout){
			this._timeout = setTimeout(dojo.hitch(this, function(){
				this.cancel();
			}), timeout);
		}else if(timeout == undefined || timeout === 0){
			this.cancel();
		}
	},

	setLabel: function(/*String*/ content, /*Int*/ timeout){
		// summary:
		//	setting a label and optional timeout of the labels state

		// this.inherited(arguments); FIXME: throws an Unknown runtime error

		// Begin IE hack
		// summary: reset the label (text) of the button; takes an HTML string
		this.label = content;
		// remove children
		while (this.containerNode.firstChild){
			this.containerNode.removeChild(this.containerNode.firstChild);
		}
		this.containerNode.appendChild(document.createTextNode(this.label));

		this._layoutHack();
		if(this.showLabel == false && !(dojo.attr(this.domNode, "title"))){
			this.titleNode.title=dojo.trim(this.containerNode.innerText || this.containerNode.textContent || '');
		}
		// End IE hack

		// setting timeout
		if(timeout){
			this.resetTimeout(timeout);
		}else{
			this.timeout = null;
		}

		// create optional busy image
		if(this.useIcon && this.isBusy){
			var node = new Image();
			node.src = this._blankGif;
			dojo.attr(node, "id", this.id+"_icon");
			dojo.addClass(node, "dojoxBusyButtonIcon");
			this.containerNode.appendChild(node);
		}
	},

	_clicked: function(e){
		// summary:
		//	on button click the button state gets changed

		// only do something if button is not busy
		if(!this.isBusy){
			this.makeBusy();
		}
	}
});<|endoftext|>


<commit_before>describe("j$.pp", function () {
  it("should wrap strings in single quotes", function() {
    expect(j$.pp("some string")).toEqual("'some string'");
    expect(j$.pp("som' string")).toEqual("'som' string'");
  });

  it("should stringify primitives properly", function() {
    expect(j$.pp(true)).toEqual("true");
    expect(j$.pp(false)).toEqual("false");
    expect(j$.pp(null)).toEqual("null");
    expect(j$.pp(jasmine.undefined)).toEqual("undefined");
    expect(j$.pp(3)).toEqual("3");
    expect(j$.pp(-3.14)).toEqual("-3.14");
  });

  it("should stringify arrays properly", function() {
    expect(j$.pp([1, 2])).toEqual("[ 1, 2 ]");
    expect(j$.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', {  }, undefined, null ]");
  });

  it("should indicate circular array references", function() {
    var array1 = [1, 2];
    var array2 = [array1];
    array1.push(array2);
    expect(j$.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
  });

  it("should stringify objects properly", function() {
    expect(j$.pp({foo: 'bar'})).toEqual("{ foo : 'bar' }");
    expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo : 'bar', baz : 3, nullValue : null, undefinedValue : undefined }");
    expect(j$.pp({foo: function () {
    }, bar: [1, 2, 3]})).toEqual("{ foo : Function, bar : [ 1, 2, 3 ] }");
  });

  it("should not include inherited properties when stringifying an object", function() {
    var SomeClass = function() {};
    SomeClass.prototype.foo = "inherited foo";
    var instance = new SomeClass();
    instance.bar = "my own bar";
    expect(j$.pp(instance)).toEqual("{ bar : 'my own bar' }");
  });

  it("should not recurse objects and arrays more deeply than j$.MAX_PRETTY_PRINT_DEPTH", function() {
    var originalMaxDepth = j$.MAX_PRETTY_PRINT_DEPTH;
    var nestedObject = { level1: { level2: { level3: { level4: "leaf" } } } };
    var nestedArray  = [1, [2, [3, [4, "leaf"]]]];

    try {
      j$.MAX_PRETTY_PRINT_DEPTH = 2;
      expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : Object } }");
      expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");

      j$.MAX_PRETTY_PRINT_DEPTH = 3;
      expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : Object } } }");
      expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");

      j$.MAX_PRETTY_PRINT_DEPTH = 4;
      expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : { level4 : 'leaf' } } } }");
      expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
    } finally {
      j$.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
    }
  });

  it("should stringify RegExp objects properly", function() {
    expect(j$.pp(/x|y|z/)).toEqual("/x|y|z/");
  });

  it("should indicate circular object references", function() {
    var sampleValue = {foo: 'hello'};
    sampleValue.nested = sampleValue;
    expect(j$.pp(sampleValue)).toEqual("{ foo : 'hello', nested : <circular reference: Object> }");
  });

  it("should indicate getters on objects as such", function() {
    var sampleValue = {id: 1};
    if (sampleValue.__defineGetter__) {
      //not supported in IE!
      sampleValue.__defineGetter__('calculatedValue', function() {
        throw new Error("don't call me!");
      });
    }
    if (sampleValue.__defineGetter__) {
      expect(j$.pp(sampleValue)).toEqual("{ id : 1, calculatedValue : <getter> }");
    }
    else {
      expect(j$.pp(sampleValue)).toEqual("{ id : 1 }");
    }
  });

  it('should not do HTML escaping of strings', function() {
    expect(j$.pp('some html string &', false)).toEqual('\'some html string &\'');
  });

  it("should abbreviate the global (usually window) object", function() {
    expect(j$.pp(jasmine.getGlobal())).toEqual("<global>");
  });

  it("should stringify Date objects properly", function() {
    var now = new Date();
    expect(j$.pp(now)).toEqual("Date(" + now.toString() + ")");
  });

  it("should stringify spy objects properly", function() {
    var TestObject = {
          someFunction: function() {}
        },
        env = new j$.Env();

    env.spyOn(TestObject, 'someFunction');
    expect(j$.pp(TestObject.someFunction)).toEqual("spy on someFunction");

    expect(j$.pp(j$.createSpy("something"))).toEqual("spy on something");
  });

  it("should stringify objects that implement jasmineToString", function () {
    var obj = {
      jasmineToString: function () { return "strung"; }
    };

    expect(j$.pp(obj)).toEqual("strung");
  });

  it("should handle objects with null prototype", function() {
    var obj = Object.create(null);
    obj.foo = 'bar';

    expect(j$.pp(obj)).toEqual("{ foo : 'bar' }");
  });
});

<commit_msg>Run Object.create(null) spec on all browsers not IE 8<commit_after>describe("j$.pp", function () {
  it("should wrap strings in single quotes", function() {
    expect(j$.pp("some string")).toEqual("'some string'");
    expect(j$.pp("som' string")).toEqual("'som' string'");
  });

  it("should stringify primitives properly", function() {
    expect(j$.pp(true)).toEqual("true");
    expect(j$.pp(false)).toEqual("false");
    expect(j$.pp(null)).toEqual("null");
    expect(j$.pp(jasmine.undefined)).toEqual("undefined");
    expect(j$.pp(3)).toEqual("3");
    expect(j$.pp(-3.14)).toEqual("-3.14");
  });

  it("should stringify arrays properly", function() {
    expect(j$.pp([1, 2])).toEqual("[ 1, 2 ]");
    expect(j$.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', {  }, undefined, null ]");
  });

  it("should indicate circular array references", function() {
    var array1 = [1, 2];
    var array2 = [array1];
    array1.push(array2);
    expect(j$.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
  });

  it("should stringify objects properly", function() {
    expect(j$.pp({foo: 'bar'})).toEqual("{ foo : 'bar' }");
    expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo : 'bar', baz : 3, nullValue : null, undefinedValue : undefined }");
    expect(j$.pp({foo: function () {
    }, bar: [1, 2, 3]})).toEqual("{ foo : Function, bar : [ 1, 2, 3 ] }");
  });

  it("should not include inherited properties when stringifying an object", function() {
    var SomeClass = function() {};
    SomeClass.prototype.foo = "inherited foo";
    var instance = new SomeClass();
    instance.bar = "my own bar";
    expect(j$.pp(instance)).toEqual("{ bar : 'my own bar' }");
  });

  it("should not recurse objects and arrays more deeply than j$.MAX_PRETTY_PRINT_DEPTH", function() {
    var originalMaxDepth = j$.MAX_PRETTY_PRINT_DEPTH;
    var nestedObject = { level1: { level2: { level3: { level4: "leaf" } } } };
    var nestedArray  = [1, [2, [3, [4, "leaf"]]]];

    try {
      j$.MAX_PRETTY_PRINT_DEPTH = 2;
      expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : Object } }");
      expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");

      j$.MAX_PRETTY_PRINT_DEPTH = 3;
      expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : Object } } }");
      expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");

      j$.MAX_PRETTY_PRINT_DEPTH = 4;
      expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : { level4 : 'leaf' } } } }");
      expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
    } finally {
      j$.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
    }
  });

  it("should stringify RegExp objects properly", function() {
    expect(j$.pp(/x|y|z/)).toEqual("/x|y|z/");
  });

  it("should indicate circular object references", function() {
    var sampleValue = {foo: 'hello'};
    sampleValue.nested = sampleValue;
    expect(j$.pp(sampleValue)).toEqual("{ foo : 'hello', nested : <circular reference: Object> }");
  });

  it("should indicate getters on objects as such", function() {
    var sampleValue = {id: 1};
    if (sampleValue.__defineGetter__) {
      //not supported in IE!
      sampleValue.__defineGetter__('calculatedValue', function() {
        throw new Error("don't call me!");
      });
    }
    if (sampleValue.__defineGetter__) {
      expect(j$.pp(sampleValue)).toEqual("{ id : 1, calculatedValue : <getter> }");
    }
    else {
      expect(j$.pp(sampleValue)).toEqual("{ id : 1 }");
    }
  });

  it('should not do HTML escaping of strings', function() {
    expect(j$.pp('some html string &', false)).toEqual('\'some html string &\'');
  });

  it("should abbreviate the global (usually window) object", function() {
    expect(j$.pp(jasmine.getGlobal())).toEqual("<global>");
  });

  it("should stringify Date objects properly", function() {
    var now = new Date();
    expect(j$.pp(now)).toEqual("Date(" + now.toString() + ")");
  });

  it("should stringify spy objects properly", function() {
    var TestObject = {
          someFunction: function() {}
        },
        env = new j$.Env();

    env.spyOn(TestObject, 'someFunction');
    expect(j$.pp(TestObject.someFunction)).toEqual("spy on someFunction");

    expect(j$.pp(j$.createSpy("something"))).toEqual("spy on something");
  });

  it("should stringify objects that implement jasmineToString", function () {
    var obj = {
      jasmineToString: function () { return "strung"; }
    };

    expect(j$.pp(obj)).toEqual("strung");
  });

  it("should handle objects with null prototype", function() {
    if (jasmine.getEnv().ieVersion < 9) { return; }

    var obj = Object.create(null);
    obj.foo = 'bar';

    expect(j$.pp(obj)).toEqual("{ foo : 'bar' }");
  });
});

<|endoftext|>