Skip to content

Instantly share code, notes, and snippets.

@ccheney
Created December 8, 2015 20:21
Show Gist options
  • Save ccheney/e6b218f0ad70545b25cf to your computer and use it in GitHub Desktop.
Save ccheney/e6b218f0ad70545b25cf to your computer and use it in GitHub Desktop.
/**
* A bind polyfill for browsers that don't support the bind method.
*/
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () {
}, fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
/**
* Generates a hash string from the string being passed in. In this case it is a function that is casted as string value.
*
* @param str
* @returns {String}
*/
var hashCode = function (str) {
str = String(str);
// http://erlycoder.com/49/javascript-hash-functions-to-convert-string-into-integer-hash-
var character;
var hash = null;
var strLength = str.length;
if (strLength == 0)
return hash;
for (var i = 0; i < strLength; i++) {
character = str.charCodeAt(i);
hash = ((hash << 5) - hash) + character;
hash = hash & hash; // Convert to 32bit integer
}
return String(Math.abs(hash));
};
var add = EventTarget.prototype.addEventListener;
(<any>EventTarget).prototype.addEventListener = function(type, fn, scope, capture) {
//debugger;
if (typeof scope === 'boolean' || scope == null) {
this.f = add;
this.f(type, fn, scope);
} else {
this._scope = scope;
this._scope._handlerMap = this._scope._handlerMap || {};
this._handler = this._scope._handlerMap[hashCode(fn)] = fn.bind(this._scope);
this.f = add;
this.f(type, this._handler, capture);
}
};
var remove = EventTarget.prototype.removeEventListener;
(<any>EventTarget).prototype.removeEventListener = function(type, fn, scope, capture) {
if (typeof scope === 'boolean' || scope == null) {
this.f = remove;
this.f(type, fn, scope);
} else {
this._scope = scope;
this._scope._handlerMap = this._scope._handlerMap || {};
this._handler = this._scope._handlerMap[hashCode(fn)];
this.f = remove;
this.f(type, this._handler, capture);
this._scope._handlerMap[hashCode(fn)] = null;
}
};
//var dispatch = EventTarget.prototype.dispatchEvent;
//(<any>EventTarget).prototype.dispatchEvent = function(evt) {
// console.log("evt", evt, this);
// this.f = dispatch;
// return this.f(evt);
//};
//TODO: Clean up.
var _startX = 0; // mouse starting positions
var _startY = 0;
var _endX = 0;
var _endY = 0;
var _offsetX = 0; // current element offset
var _offsetY = 0;
/**
* A utility to visually show logs.
*
* @class VisualDebugger
* @extends DOMElement
* @constructor
**/
class VisualDebugger {
/**
* A reference to the VisualDebugger most outer element.
*
* @property _container
* @type {HTMLElement}
* @private
*/
private static _container:any = null;
/**
* A boolean value to determine if the VisualDebugger is enabled or disabled.
*
* @property _isEnabled
* @type {boolean}
* @private static
*/
private static _isEnabled:boolean = false;
constructor() {
}
/**
* Logs the text into in the Visual Debugger.
*
* @method log
* @public
* @static
* @example
* VisualDebugger.log('test log');
*
* vd.log('test log');
*/
public static log(...value:any[]):void {
this.enable();
const text:any = value;
const item = document.createElement('li');
item.appendChild(document.createTextNode(text));
this._container.appendChild(item);
}
/**
* Enables the Visual Debugger.
*
* @method enable
* @public
* @static
* @example
* VisualDebugger.enable();
*
* vd.enable();
*/
public static enable():void {
if (this._isEnabled === true) { return; }
let xy = window.localStorage.getItem("xy");
if (xy) {
xy = xy.split(',');
} else {
xy = [5,5]; // Default
window.localStorage.setItem("xy", "5,5");
}
this._container = document.createElement('ul');
this._container.style.width = '300px';
this._container.style.height = '100px';
this._container.style.left = xy[0] + 'px';
this._container.style.top = xy[1] + 'px';
this._container.style.background = 'grey';
this._container.style.color = 'wheat';
this._container.style.position = 'absolute';
this._container.style.opacity = '0.95';
this._container.style.zIndex = '999999';
this._container.style.fontSize = '14px';
this._container.style.padding = '5px 10px';
document.body.appendChild(this._container);
(<any>this._container).addEventListener('mousedown', this._mouseDownHandler, this, false);
(<any>window).addEventListener('mouseup', this._mouseUpHandler, this, false);
this._isEnabled = true;
}
public static _mouseDownHandler(event) {
//console.log("_mouseDownHandler", event, this);
_startX = event.clientX;
_startY = event.clientY;
_offsetX = parseInt(event.target.style.left, 10);
_offsetY = parseInt(event.target.style.top, 10);
(<any>window).addEventListener('mousemove', this._mouseMoveHandler, this, false);
}
public static _mouseMoveHandler(event){
//console.log("_mouseMoveHandler", event, this);
this._container.style.left = (_offsetX + event.clientX - _startX) + 'px';
this._container.style.top = (_offsetY + event.clientY - _startY) + 'px';
}​
public static _mouseUpHandler(event) {
_endX = parseInt(this._container.style.left);
_endY = parseInt(this._container.style.top);
window.localStorage.setItem("xy", _endX + ',' + _endY);
(<any>window).removeEventListener('mousemove', this._mouseMoveHandler, this, false);
}
/**
* Disables the Visual Debugger.
*
* @method clear
* @public
* @static
* VisualDebugger.disable();
*
* vd.disable();
*/
public static disable():void {
if (this._isEnabled === false) { return; }
(<any>this._container).removeEventListener('mousedown', this._mouseDownHandler, this, false);
(<any>window).removeEventListener('mouseup', this._mouseUpHandler, this, false);
document.body.removeChild(this._container);
this._container = null;
this._isEnabled = false;
}
/**
* Clears the log in the Visual Debugger.
*
* @method clear
* @public
* @static
* VisualDebugger.clear();
*
* vd.clear();
*/
public static clear():void {
this._container.innerHTML = '';
}
/**
* Shows the Visual Debugger.
*
* @method show
* @public
* @static
* VisualDebugger.show();
*
* vd.show();
*/
public static show():void {
this._container.style.display = 'block';
}
/**
* Hides the Visual Debugger.
*
* @method hide
* @public
* @static
* VisualDebugger.hide();
*
* vd.hide();
*/
public static hide():void {
this._container.style.display = 'none';
}
}
window['VisualDebugger'] = VisualDebugger;
window['vd'] = VisualDebugger;
export = VisualDebugger;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment