<commit_before>//WARNING: no log() function usage before init.js

exports.core.os = navigator.platform
exports.core.device = 0
exports.core.vendor = ""

exports.trace = { key: false, focus: false }

exports.core.keyCodes = {
	13: 'Select',
	27: 'Back',
	37: 'Left',
	32: 'Space',
	33: 'PageUp',
	34: 'PageDown',
	38: 'Up',
	39: 'Right',
	40: 'Down',
	48: '0',
	49: '1',
	50: '2',
	51: '3',
	52: '4',
	53: '5',
	54: '6',
	55: '7',
	56: '8',
	57: '9',
	112: 'Red',
	113: 'Green',
	114: 'Yellow',
	115: 'Blue'
}

var copyArguments = function(args, src, prefix) {
	var copy = Array.prototype.slice.call(args, src)
	if (prefix !== undefined)
		copy.unshift(prefix)
	return copy
}

exports.core.copyArguments = copyArguments

/* ${init.js} */

if (log === null)
	log = console.log.bind(console)

/** @const */
/** @param {string} text @param {...} args */
_globals.qsTr = function(text, args) { return _globals._context.qsTr.apply(qml._context, arguments) }

var _checkDevice = function(target, info) {
	if (navigator.userAgent.indexOf(target) < 0)
		return

	log("[QML] " + target)
	exports.core.vendor = info.vendor
	exports.core.device = info.device
	exports.core.os = info.os
	log("loaded")
}

if (!exports.core.vendor) {
	_checkDevice('Blackberry', { 'vendor': 'blackberry', 'device': 2, 'os': 'blackberry' })
	_checkDevice('Android', { 'vendor': 'google', 'device': 2, 'os': 'android' })
	_checkDevice('iPhone', { 'vendor': 'apple', 'device': 2, 'os': 'iOS' })
	_checkDevice('iPad', { 'vendor': 'apple', 'device': 2, 'os': 'iOS' })
	_checkDevice('iPod', { 'vendor': 'apple', 'device': 2, 'os': 'iOS' })
}

var colorTable = {
	'maroon':	'800000',
	'red':		'ff0000',
	'orange':	'ffA500',
	'yellow':	'ffff00',
	'olive':	'808000',
	'purple':	'800080',
	'fuchsia':	'ff00ff',
	'white':	'ffffff',
	'lime':		'00ff00',
	'green':	'008000',
	'navy':		'000080',
	'blue':		'0000ff',
	'aqua':		'00ffff',
	'teal':		'008080',
	'black':	'000000',
	'silver':	'c0c0c0',
	'gray':		'080808',
	'transparent': '0000'
}

var safeCallImpl = function(callback, args, onError) {
	try { return callback.apply(null, args) } catch(ex) { onError(ex) }
}

exports.core.safeCall = function(args, onError) {
	return function(callback) { return safeCallImpl(callback, args, onError) }
}

/**
 * @constructor
 */
exports.core.CoreObject = function() { }
exports.core.CoreObject.prototype.constructor = exports.core.CoreObject

/** @constructor */
exports.core.Color = function(value) {
	if (Array.isArray(value)) {
		this.r = value[0]
		this.g = value[1]
		this.b = value[2]
		this.a = value[3] !== undefined? value[3]: 255
		return
	}
	if (typeof value !== 'string')
	{
		this.r = this.b = this.a = 255
		this.g = 0
		log("invalid color specification: " + value)
		return
	}
	var triplet
	if (value.substring(0, 4) == "rgba") {
		var b = value.indexOf('('), e = value.lastIndexOf(')')
		value = value.substring(b + 1, e).split(',')
		this.r = parseInt(value[0], 10)
		this.g = parseInt(value[1], 10)
		this.b = parseInt(value[2], 10)
		this.a = Math.floor(parseFloat(value[3]) * 255)
		return
	}
	else {
		var h = value.charAt(0);
		if (h != '#')
			triplet = colorTable[value];
		else
			triplet = value.substring(1)
	}
	if (!triplet) {
		this.r = 255
		this.g = 0
		this.b = 255
		log("invalid color specification: " + value)
		return
	}

	var len = triplet.length;
	if (len == 3 || len == 4) {
		var r = parseInt(triplet.charAt(0), 16)
		var g = parseInt(triplet.charAt(1), 16)
		var b = parseInt(triplet.charAt(2), 16)
		var a = (len == 4)? parseInt(triplet.charAt(3), 16): 15
		this.r = (r << 4) | r;
		this.g = (g << 4) | g;
		this.b = (b << 4) | b;
		this.a = (a << 4) | a;
	} else if (len == 6 || len == 8) {
		this.r = parseInt(triplet.substring(0, 2), 16)
		this.g = parseInt(triplet.substring(2, 4), 16)
		this.b = parseInt(triplet.substring(4, 6), 16)
		this.a = (len == 8)? parseInt(triplet.substring(6, 8), 16): 255
	} else
		throw new Error("invalid color specification: " + value)
}
exports.core.Color.prototype.constructor = exports.core.Color
/** @const */
var Color = exports.core.Color

exports.core.Color.prototype.rgba = function() {
	return "rgba(" + this.r + "," + this.g + "," + this.b + "," + (this.a / 255) + ")";
}

exports.core.normalizeColor = function(spec) {
	return (new Color(spec)).rgba()
}

exports.core.mixColor = function(specA, specB, r) {
	var a = new Color(specA)
	var b = new Color(specB)
	var mix = function(a, b, r) { return Math.floor((b - a) * r + a) }
	return [mix(a.r, b.r, r), mix(a.g, b.g, r), mix(a.b, b.b, r), mix(a.a, b.a, r)]
}

exports.core.ModelUpdate = function() {
	this._updates = []
}
exports.core.ModelUpdate.prototype.constructor = exports.core.ModelUpdate

exports.core.ModelUpdate.prototype.reset = function(model) {
	var updates = []
	var n = model.count
	for(var i = 0; i < n; ++i)
		updates.push(model.get(i))
	this._updates = updates
}

exports.core.ModelUpdate.prototype.insert = function(model, begin, end) {

}

exports.core.ModelUpdate.prototype.update = function(model, begin, end) {

}

exports.core.ModelUpdate.prototype.remove = function(model, begin, end) {

}

exports.core.ModelUpdate.prototype.apply = function(view) {
}

/** @constructor */
exports.core.DelayedAction = function(context, action) {
	this.context = context
	this.action = function() {
		this._scheduled = false
		action()
	}.bind(this)
}

exports.core.DelayedAction.prototype.schedule = function() {
	if (!this._scheduled) {
		this._scheduled = true
		this.context.scheduleAction(this.action)
	}
}

var Modernizr = window.Modernizr
var requestAnimationFrame = Modernizr.prefixed('requestAnimationFrame', window)	|| function(callback) { return setTimeout(callback, 0) }
var cancelAnimationFrame = Modernizr.prefixed('cancelAnimationFrame', window)	|| function(id) { return clearTimeout(id) }

exports.addProperty = function(proto, type, name, defaultValue) {
	var convert
	switch(type) {
		case 'enum':
		case 'int':		convert = function(value) { return parseInt(value, 0) }; break
		case 'bool':	convert = function(value) { return value? true: false }; break
		case 'real':	convert = function(value) { return parseFloat(value) }; break
		case 'string':	convert = function(value) { return String(value) }; break
		default:		convert = function(value) { return value }; break
	}

	if (defaultValue !== undefined) {
		defaultValue = convert(defaultValue)
	} else {
		switch(type) {
			case 'enum': //fixme: add default value here
			case 'int':		defaultValue = 0; break
			case 'bool':	defaultValue = false; break
			case 'real':	defaultValue = 0.0; break
			case 'string':	defaultValue = ""; break
			case 'array':	defaultValue = []; break
			default:
				defaultValue = (type[0].toUpperCase() == type[0])? null: undefined
		}
	}

	var storageName = '__property_' + name
	var forwardName = '__forward_' + name

	Object.defineProperty(proto, name, {
		get: function() {
			var p = this[storageName]
			return p !== undefined?
				p.interpolatedValue !== undefined? p.interpolatedValue: p.value:
				defaultValue
		},

		set: function(newValue) {
			newValue = convert(newValue)
			var p = this[storageName]
			if (p === undefined) { //no storage
				if (newValue === defaultValue) //value == defaultValue, no storage allocation
					return

				p = this[storageName] = { value : defaultValue }
			}
			var animation = this.getAnimation(name)
			if (animation && p.value !== newValue) {
				if (p.frameRequest)
					cancelAnimationFrame(p.frameRequest)

				var now = new Date()
				p.started = now.getTime() + now.getMilliseconds() / 1000.0

				var src = p.interpolatedValue !== undefined? p.interpolatedValue: p.value
				var dst = newValue

				var self = this

				var complete = function() {
					cancelAnimationFrame(p.frameRequest)
					p.frameRequest = undefined
					animation.complete = function() { }
					animation.running = false
					p.interpolatedValue = undefined
					p.started = undefined
					self._update(name, dst, src)
				}

				var duration = animation.duration

				var nextFrame = function() {
					var date = new Date()
					var now = date.getTime() + date.getMilliseconds() / 1000.0
					var t = 1.0 * (now - p.started) / duration
					if (t >= 1) {
						complete()
					} else {
						p.interpolatedValue = convert(animation.interpolate(dst, src, t))
						self._update(name, p.interpolatedValue, src)
						p.frameRequest = requestAnimationFrame(nextFrame)
					}
				}

				p.frameRequest = requestAnimationFrame(nextFrame)

				animation.running = true
				animation.complete = complete
			}
			var oldValue = p.value
			if (oldValue !== newValue) {
				var forwardTarget = this[forwardName]
				if (forwardTarget !== undefined) {
					if (oldValue !== null && (oldValue instanceof Object)) {
						//forward property update for mixins
						var forwardedOldValue = oldValue[forwardTarget]
						if (newValue !== forwardedOldValue) {
							oldValue[forwardTarget] = newValue
							this._update(name, newValue, forwardedOldValue)
						}
						return
					} else if (newValue instanceof Object) {
						//first assignment of mixin
						this.connectOnChanged(newValue, forwardTarget, function(v, ov) { this._update(name, v, ov) }.bind(this))
					}
				}
				p.value = newValue
				if ((!animation || !animation.running) && newValue == defaultValue)
					delete this[storageName]
				if (!animation)
					this._update(name, newValue, oldValue)
			}
		},
		enumerable: true
	})
}

exports.addAliasProperty = function(self, name, getObject, srcProperty) {
	var target = getObject()
	self.connectOnChanged(target, srcProperty, function(value) { self._update(name, value) })

	Object.defineProperty(self, name, {
		get: function() { return target[srcProperty] },
		set: function(value) { target[srcProperty] = value },
		enumerable: true
	})
}

exports.core.createSignalForwarder = function(object, name) {
	return (function() { object.emit.apply(object, copyArguments(arguments, 0, name)) })
}

/** @constructor */
exports.core.EventBinder = function(target) {
	this.target = target
	this.callbacks = {}
	this.enabled = false
}

exports.core.EventBinder.prototype.on = function(event, callback) {
	if (event in this.callbacks)
		throw new Error('double adding of event (' + event + ')')
	this.callbacks[event] = callback
	if (this.enabled)
		this.target.on(event, callback)
}

exports.core.EventBinder.prototype.constructor = exports.core.EventBinder

exports.core.EventBinder.prototype.enable = function(value) {
	if (value != this.enabled) {
		var target = this.target
		this.enabled = value
		if (value) {
			for(var event in this.callbacks)
				target.on(event, this.callbacks[event])
		} else {
			for(var event in this.callbacks)
				target.removeListener(event, this.callbacks[event])
		}
	}
}
<commit_msg>accumulate all model updates<commit_after>//WARNING: no log() function usage before init.js

exports.core.os = navigator.platform
exports.core.device = 0
exports.core.vendor = ""

exports.trace = { key: false, focus: false }

exports.core.keyCodes = {
	13: 'Select',
	27: 'Back',
	37: 'Left',
	32: 'Space',
	33: 'PageUp',
	34: 'PageDown',
	38: 'Up',
	39: 'Right',
	40: 'Down',
	48: '0',
	49: '1',
	50: '2',
	51: '3',
	52: '4',
	53: '5',
	54: '6',
	55: '7',
	56: '8',
	57: '9',
	112: 'Red',
	113: 'Green',
	114: 'Yellow',
	115: 'Blue'
}

var copyArguments = function(args, src, prefix) {
	var copy = Array.prototype.slice.call(args, src)
	if (prefix !== undefined)
		copy.unshift(prefix)
	return copy
}

exports.core.copyArguments = copyArguments

/* ${init.js} */

if (log === null)
	log = console.log.bind(console)

/** @const */
/** @param {string} text @param {...} args */
_globals.qsTr = function(text, args) { return _globals._context.qsTr.apply(qml._context, arguments) }

var _checkDevice = function(target, info) {
	if (navigator.userAgent.indexOf(target) < 0)
		return

	log("[QML] " + target)
	exports.core.vendor = info.vendor
	exports.core.device = info.device
	exports.core.os = info.os
	log("loaded")
}

if (!exports.core.vendor) {
	_checkDevice('Blackberry', { 'vendor': 'blackberry', 'device': 2, 'os': 'blackberry' })
	_checkDevice('Android', { 'vendor': 'google', 'device': 2, 'os': 'android' })
	_checkDevice('iPhone', { 'vendor': 'apple', 'device': 2, 'os': 'iOS' })
	_checkDevice('iPad', { 'vendor': 'apple', 'device': 2, 'os': 'iOS' })
	_checkDevice('iPod', { 'vendor': 'apple', 'device': 2, 'os': 'iOS' })
}

var colorTable = {
	'maroon':	'800000',
	'red':		'ff0000',
	'orange':	'ffA500',
	'yellow':	'ffff00',
	'olive':	'808000',
	'purple':	'800080',
	'fuchsia':	'ff00ff',
	'white':	'ffffff',
	'lime':		'00ff00',
	'green':	'008000',
	'navy':		'000080',
	'blue':		'0000ff',
	'aqua':		'00ffff',
	'teal':		'008080',
	'black':	'000000',
	'silver':	'c0c0c0',
	'gray':		'080808',
	'transparent': '0000'
}

var safeCallImpl = function(callback, args, onError) {
	try { return callback.apply(null, args) } catch(ex) { onError(ex) }
}

exports.core.safeCall = function(args, onError) {
	return function(callback) { return safeCallImpl(callback, args, onError) }
}

/**
 * @constructor
 */
exports.core.CoreObject = function() { }
exports.core.CoreObject.prototype.constructor = exports.core.CoreObject

/** @constructor */
exports.core.Color = function(value) {
	if (Array.isArray(value)) {
		this.r = value[0]
		this.g = value[1]
		this.b = value[2]
		this.a = value[3] !== undefined? value[3]: 255
		return
	}
	if (typeof value !== 'string')
	{
		this.r = this.b = this.a = 255
		this.g = 0
		log("invalid color specification: " + value)
		return
	}
	var triplet
	if (value.substring(0, 4) == "rgba") {
		var b = value.indexOf('('), e = value.lastIndexOf(')')
		value = value.substring(b + 1, e).split(',')
		this.r = parseInt(value[0], 10)
		this.g = parseInt(value[1], 10)
		this.b = parseInt(value[2], 10)
		this.a = Math.floor(parseFloat(value[3]) * 255)
		return
	}
	else {
		var h = value.charAt(0);
		if (h != '#')
			triplet = colorTable[value];
		else
			triplet = value.substring(1)
	}
	if (!triplet) {
		this.r = 255
		this.g = 0
		this.b = 255
		log("invalid color specification: " + value)
		return
	}

	var len = triplet.length;
	if (len == 3 || len == 4) {
		var r = parseInt(triplet.charAt(0), 16)
		var g = parseInt(triplet.charAt(1), 16)
		var b = parseInt(triplet.charAt(2), 16)
		var a = (len == 4)? parseInt(triplet.charAt(3), 16): 15
		this.r = (r << 4) | r;
		this.g = (g << 4) | g;
		this.b = (b << 4) | b;
		this.a = (a << 4) | a;
	} else if (len == 6 || len == 8) {
		this.r = parseInt(triplet.substring(0, 2), 16)
		this.g = parseInt(triplet.substring(2, 4), 16)
		this.b = parseInt(triplet.substring(4, 6), 16)
		this.a = (len == 8)? parseInt(triplet.substring(6, 8), 16): 255
	} else
		throw new Error("invalid color specification: " + value)
}
exports.core.Color.prototype.constructor = exports.core.Color
/** @const */
var Color = exports.core.Color

exports.core.Color.prototype.rgba = function() {
	return "rgba(" + this.r + "," + this.g + "," + this.b + "," + (this.a / 255) + ")";
}

exports.core.normalizeColor = function(spec) {
	return (new Color(spec)).rgba()
}

exports.core.mixColor = function(specA, specB, r) {
	var a = new Color(specA)
	var b = new Color(specB)
	var mix = function(a, b, r) { return Math.floor((b - a) * r + a) }
	return [mix(a.r, b.r, r), mix(a.g, b.g, r), mix(a.b, b.b, r), mix(a.a, b.a, r)]
}

exports.core.ModelUpdate = function() {
	this._updates = []
	this._updateIndex = 0
	this.count = 0
}

exports.core.ModelUpdate.prototype.constructor = exports.core.ModelUpdate

exports.core.ModelUpdate.prototype.reset = function(model) {
	this._updates = []
	this._updateIndex = 0
	this.count = model.count
}

exports.core.ModelUpdate.prototype._addRange = function(begin, end) {
	for(var i = begin; i < end; ++i) {
		this._updates[i] = true
	}
}

exports.core.ModelUpdate.prototype._setUpdateIndex = function(begin) {
	var n = this._updates.length
	this._updates.slice(begin, n - begin) //remove tail of sparse update array
	this._updateIndex = begin
}

exports.core.ModelUpdate.prototype.insert = function(model, begin, end) {
	var d = end - begin
	if (d === 0)
		return

	this._setUpdateIndex(begin)
	this.count += d
	if (this.count != model.count)
		throw new Error('unbalanced insert ' + this.count + ' + [' + begin + '-' + end + '], model reported ' + model.count)
}

exports.core.ModelUpdate.prototype.update = function(model, begin, end) {
	if (begin >= end || begin >= this._updateIndex)
		return

	if (end >= this._updateIndex) {
		this._setUpdateIndex(begin)
		return
	}

	this._addRange(begin, end)
}

exports.core.ModelUpdate.prototype.remove = function(model, begin, end) {
	var d = end - begin
	if (d === 0)
		return

	this._setUpdateIndex(begin)
	this.count -= d
	if (this.count != model.count)
		throw new Error('unbalanced remove ' + this.count + ' + [' + begin + '-' + end + '], model reported ' + model.count)
}

exports.core.ModelUpdate.prototype.apply = function(view) {
	var model = view.model
	this._updates.forEach(function(value, idx) { view._updateDelegate(idx) })
	var d = this.count - view._items.length

	if (d > 0) {
		while(d--) {
			view._items.push(null)
		}
	} else if (d < 0) {
		view._items.splice(this.count, -d)
	}

	for(var i = this._updateIndex; i < this.count; ++i)
		view._updateDelegate(i)
	this._updateIndex = this.count
	this._updates = []
}

/** @constructor */
exports.core.DelayedAction = function(context, action) {
	this.context = context
	this.action = function() {
		this._scheduled = false
		action()
	}.bind(this)
}

exports.core.DelayedAction.prototype.schedule = function() {
	if (!this._scheduled) {
		this._scheduled = true
		this.context.scheduleAction(this.action)
	}
}

var Modernizr = window.Modernizr
var requestAnimationFrame = Modernizr.prefixed('requestAnimationFrame', window)	|| function(callback) { return setTimeout(callback, 0) }
var cancelAnimationFrame = Modernizr.prefixed('cancelAnimationFrame', window)	|| function(id) { return clearTimeout(id) }

exports.addProperty = function(proto, type, name, defaultValue) {
	var convert
	switch(type) {
		case 'enum':
		case 'int':		convert = function(value) { return parseInt(value, 0) }; break
		case 'bool':	convert = function(value) { return value? true: false }; break
		case 'real':	convert = function(value) { return parseFloat(value) }; break
		case 'string':	convert = function(value) { return String(value) }; break
		default:		convert = function(value) { return value }; break
	}

	if (defaultValue !== undefined) {
		defaultValue = convert(defaultValue)
	} else {
		switch(type) {
			case 'enum': //fixme: add default value here
			case 'int':		defaultValue = 0; break
			case 'bool':	defaultValue = false; break
			case 'real':	defaultValue = 0.0; break
			case 'string':	defaultValue = ""; break
			case 'array':	defaultValue = []; break
			default:
				defaultValue = (type[0].toUpperCase() == type[0])? null: undefined
		}
	}

	var storageName = '__property_' + name
	var forwardName = '__forward_' + name

	Object.defineProperty(proto, name, {
		get: function() {
			var p = this[storageName]
			return p !== undefined?
				p.interpolatedValue !== undefined? p.interpolatedValue: p.value:
				defaultValue
		},

		set: function(newValue) {
			newValue = convert(newValue)
			var p = this[storageName]
			if (p === undefined) { //no storage
				if (newValue === defaultValue) //value == defaultValue, no storage allocation
					return

				p = this[storageName] = { value : defaultValue }
			}
			var animation = this.getAnimation(name)
			if (animation && p.value !== newValue) {
				if (p.frameRequest)
					cancelAnimationFrame(p.frameRequest)

				var now = new Date()
				p.started = now.getTime() + now.getMilliseconds() / 1000.0

				var src = p.interpolatedValue !== undefined? p.interpolatedValue: p.value
				var dst = newValue

				var self = this

				var complete = function() {
					cancelAnimationFrame(p.frameRequest)
					p.frameRequest = undefined
					animation.complete = function() { }
					animation.running = false
					p.interpolatedValue = undefined
					p.started = undefined
					self._update(name, dst, src)
				}

				var duration = animation.duration

				var nextFrame = function() {
					var date = new Date()
					var now = date.getTime() + date.getMilliseconds() / 1000.0
					var t = 1.0 * (now - p.started) / duration
					if (t >= 1) {
						complete()
					} else {
						p.interpolatedValue = convert(animation.interpolate(dst, src, t))
						self._update(name, p.interpolatedValue, src)
						p.frameRequest = requestAnimationFrame(nextFrame)
					}
				}

				p.frameRequest = requestAnimationFrame(nextFrame)

				animation.running = true
				animation.complete = complete
			}
			var oldValue = p.value
			if (oldValue !== newValue) {
				var forwardTarget = this[forwardName]
				if (forwardTarget !== undefined) {
					if (oldValue !== null && (oldValue instanceof Object)) {
						//forward property update for mixins
						var forwardedOldValue = oldValue[forwardTarget]
						if (newValue !== forwardedOldValue) {
							oldValue[forwardTarget] = newValue
							this._update(name, newValue, forwardedOldValue)
						}
						return
					} else if (newValue instanceof Object) {
						//first assignment of mixin
						this.connectOnChanged(newValue, forwardTarget, function(v, ov) { this._update(name, v, ov) }.bind(this))
					}
				}
				p.value = newValue
				if ((!animation || !animation.running) && newValue == defaultValue)
					delete this[storageName]
				if (!animation)
					this._update(name, newValue, oldValue)
			}
		},
		enumerable: true
	})
}

exports.addAliasProperty = function(self, name, getObject, srcProperty) {
	var target = getObject()
	self.connectOnChanged(target, srcProperty, function(value) { self._update(name, value) })

	Object.defineProperty(self, name, {
		get: function() { return target[srcProperty] },
		set: function(value) { target[srcProperty] = value },
		enumerable: true
	})
}

exports.core.createSignalForwarder = function(object, name) {
	return (function() { object.emit.apply(object, copyArguments(arguments, 0, name)) })
}

/** @constructor */
exports.core.EventBinder = function(target) {
	this.target = target
	this.callbacks = {}
	this.enabled = false
}

exports.core.EventBinder.prototype.on = function(event, callback) {
	if (event in this.callbacks)
		throw new Error('double adding of event (' + event + ')')
	this.callbacks[event] = callback
	if (this.enabled)
		this.target.on(event, callback)
}

exports.core.EventBinder.prototype.constructor = exports.core.EventBinder

exports.core.EventBinder.prototype.enable = function(value) {
	if (value != this.enabled) {
		var target = this.target
		this.enabled = value
		if (value) {
			for(var event in this.callbacks)
				target.on(event, this.callbacks[event])
		} else {
			for(var event in this.callbacks)
				target.removeListener(event, this.callbacks[event])
		}
	}
}
<|endoftext|>


<commit_before>/* qml.core javascript code */

if (!_globals.core)
	_globals.core = {}

_globals.core.Object = function(parent) {
	this.parent = parent;
	this._local = {}
	this._changedHandlers = {}
	this._animations = {}
}

_globals.core.Object.prototype._update = function(name, value) {
	if (name in this._changedHandlers) {
		var handlers = this._changedHandlers[name];
		handlers.forEach(function(callback) { callback(value); });
	}
}

_globals.core.Object.prototype._setId = function (name) {
	var p = this;
	while(p) {
		p._local[name] = this;
		p = p.parent;
	}
}

_globals.core.Object.prototype.onChanged = function (name, callback) {
	if (name in this._changedHandlers)
		this._changedHandlers[name].push(callback);
	else
		this._changedHandlers[name] = [callback];
}

_globals.core.Object.prototype.get = function (name) {
	if (name in this._local)
		return this._local[name];
	if (this.hasOwnProperty(name))
		return this[name];
	console.log(name, this);
	throw ("invalid property requested: '" + name + "' in context of " + this);
}

_globals.core.Object.prototype.setAnimation = function (name, animation) {
	this._animations[name] = animation;
}

_globals.core.Object.prototype.getAnimation = function (name, animation) {
	return this._animations[name] || null;
}

function setup(context) {
	_globals.core.Item.prototype.children = []

	_globals.core.Item.prototype.toScreen = function() {
		var item = this;
		var x = 0, y = 0;
		while(item) {
			x += item.x;
			y += item.y;
			item = item.parent;
		}
		return [x, y, x + this.width, y + this.height];
	}

	_globals.core.Border.prototype._update = function(name, value) {
		switch(name) {
			case 'width': this.parent.element.css({'border-width': value, 'margin-left': -value, 'margin-top': -value}); break;
			case 'color': this.parent.element.css('border-color', value); break;
		}
		_globals.core.Object.prototype._update.apply(this, arguments);
	}

	_globals.core.Item.prototype._update = function(name, value) {
		switch(name) {
			case 'width': 	this.element.css('width', value); this.right.value = this.x + value; break;
			case 'height':	this.element.css('height', value); this.bottom.value = this.y + value; break;
			case 'x':		this.element.css('left', value); this.left.value = value; this.right.value = value + this.width; break;
			case 'y':		this.element.css('top', value); this.top.value = value; this.bottom.value = value + this.height; break;
			case 'z':		this.element.css('z-index', value); break;
			case 'radius':	this.element.css('border-radius', value); break;
		}
		_globals.core.Object.prototype._update.apply(this, arguments);
	}

	_globals.core.AnchorLine.prototype.toScreen = function() {
		return this.parent.parent.toScreen()[this.boxIndex] + this.value;
	}

	_globals.core.Anchors.prototype._update = function(name, line) {
		var self = this.parent;
		var target = line.parent;
		var anchors = this;
		var lm = anchors.leftMargin || anchors.margins;
		var rm = anchors.rightMargin || anchors.margins;
		var tm = anchors.topMargin || anchors.margins;
		var bm = anchors.bottomMargin || anchors.margins;

		var update_left = function() {
			var parent_box = self.parent.toScreen();
			//console.log(target_box, parent_box);
			self.x = line.toScreen() + lm - parent_box[0];
			if (anchors.right) {
				var right_target_box = anchors.right.parent.toScreen();
				self.width = (right_target_box[2] - parent_box[0]) - self.x - rm ;
			}
		};

		var update_right = function() {
			var parent_box = self.parent.toScreen();
			//console.log(target_box, parent_box);
			if (anchors.left) {
				var left_target_box = anchors.left.parent.toScreen();
				self.width = line.toScreen() - left_target_box[0] - lm - rm;
			}
			self.x = (line.toScreen() - parent_box[0] - self.width) + lm;
		};

		var update_top = function() {
			var parent_box = self.parent.toScreen();
			//console.log(target_box, parent_box);
			self.y = line.toScreen() + tm - parent_box[1];
			if (anchors.bottom) {
				var bottom_target_box = anchors.bottom.parent.toScreen();
				self.height = (bottom_target_box[3] - parent_box[1]) - self.y - bm;
			}
		};

		var update_bottom = function() {
			var parent_box = self.parent.toScreen();
			//console.log(target_box, parent_box);
			if (anchors.top) {
				var top_target_box = anchors.top.parent.toScreen();
				self.height = line.toScreen() - top_target_box[1] - tm - bm;
			}
			self.y = (line.toScreen() - parent_box[1] - self.height) + tm;
		};

		switch(name) {
			case 'left':
				update_left();
				target.left.onChanged('value', update_left);
				break;

			case 'right':
				update_right();
				target.right.onChanged('value', update_right);
				break;

			case 'top':
				update_top();
				target.top.onChanged('value', update_top);
				break;

			case 'bottom':
				update_bottom();
				target.bottom.onChanged('value', update_bottom);
				break;
		}
		_globals.core.Object.prototype._update.apply(this, arguments);
	}

	_globals.core.Font.prototype._update = function(name, value) {
		switch(name) {
			case 'pointSize': this.parent.element.css('font-size', value + "pt"); break;
			case 'pixelSize': this.parent.element.css('font-size', value + "px"); break;
			case 'italic': this.parent.element.css('font-style', value? 'italic': 'normal'); break;
		}
		_globals.core.Object.prototype._update.apply(this, arguments);
	}

	_globals.core.Text.prototype._update = function(name, value) {
		switch(name) {
			case 'text': this.element.text(value); break;
		}
		_globals.core.Item.prototype._update.apply(this, arguments);
	}

	_globals.core.Rectangle.prototype._update = function(name, value) {
		switch(name) {
			case 'color': this.element.css('background-color', value); break;
		}
		_globals.core.Item.prototype._update.apply(this, arguments);
	}
}

exports.Context = function() {
	_globals.core.Object.apply(this, null);

	var w = $(window).width();
	var h = $(window).height();
	console.log("window size: " + w + "x" + h);

	var body = $('body');
	var div = $("

");
	body.append(div);
	$('head').append($(""
	));

	exports.addProperty(this, 'int', 'x');
	exports.addProperty(this, 'int', 'y');
	exports.addProperty(this, 'int', 'width');
	exports.addProperty(this, 'int', 'height');

	this.element = div
	this.element.css({width: w, height: h});
	this.width = w;
	this.height = h;

	console.log("context created");
	setup(this);
}

exports.Context.prototype = Object.create(_globals.core.Object.prototype);
exports.Context.prototype.constructor = exports.Context;

exports.Context.prototype.toScreen = function() {
	return [0, 0, this.width, this.height];
}

exports.Context.prototype.start = function(name) {
	var proto;
	if (typeof name == 'string') {
		console.log('creating component...', name);
		var path = name.split('.');
		proto = _globals;
		for (var i = 0; i < path.length; ++i)
			proto = proto[path[i]]
	}
	else
		proto = name;
	var instance = Object.create(proto.prototype);
	proto.apply(instance, [this]);
	return instance;
}

exports.addProperty = function(self, type, name) {
	var value;
	var timer;
	switch(type) {
		case 'int':			value = 0; break;
		case 'bool':		value = false; break;
		case 'real':		value = 0.0; break;
		default: if (type[0].toUpperCase() == type[0]) value = null; break;
	}
	Object.defineProperty(self, name, {
		get: function() {
			return value;
		},
		set: function(newValue) {
			var animation = self.getAnimation(name)
			if (animation) {
				var duration = animation.duration;
				var date = new Date();
				var started = date.getTime() + date.getMilliseconds() / 1000.0;
				timer = setInterval(function() {
					var date = new Date();
					var now = date.getTime() + date.getMilliseconds() / 1000.0;
					var t = 1.0 * (now - started) / duration;
					if (t >= 1)
						t = 1;
					console.log(t);
					self._update(name, t * (newValue - oldValue) + oldValue, oldValue);
				});

				setTimeout(function() {
					clearInterval(timer);
					self._update(name, newValue, oldValue);
				}, duration);
			}
			oldValue = value;
			if (oldValue != newValue) {
				value = newValue;
				if (!animation)
					self._update(name, newValue, oldValue);
			}
		},
		enumerable: true
	});
}

exports._bootstrap = function(self, name) {
	switch(name) {
		case 'core.Item':
			if (self.element)
				throw "double ctor call";
			self.element = $('
');
			self.parent.element.append(self.element);
			break;
	}
}
<commit_msg>put old/new value into different variables (dst, src) in scope<commit_after>/* qml.core javascript code */

if (!_globals.core)
	_globals.core = {}

_globals.core.Object = function(parent) {
	this.parent = parent;
	this._local = {}
	this._changedHandlers = {}
	this._animations = {}
}

_globals.core.Object.prototype._update = function(name, value) {
	if (name in this._changedHandlers) {
		var handlers = this._changedHandlers[name];
		handlers.forEach(function(callback) { callback(value); });
	}
}

_globals.core.Object.prototype._setId = function (name) {
	var p = this;
	while(p) {
		p._local[name] = this;
		p = p.parent;
	}
}

_globals.core.Object.prototype.onChanged = function (name, callback) {
	if (name in this._changedHandlers)
		this._changedHandlers[name].push(callback);
	else
		this._changedHandlers[name] = [callback];
}

_globals.core.Object.prototype.get = function (name) {
	if (name in this._local)
		return this._local[name];
	if (this.hasOwnProperty(name))
		return this[name];
	console.log(name, this);
	throw ("invalid property requested: '" + name + "' in context of " + this);
}

_globals.core.Object.prototype.setAnimation = function (name, animation) {
	this._animations[name] = animation;
}

_globals.core.Object.prototype.getAnimation = function (name, animation) {
	return this._animations[name] || null;
}

function setup(context) {
	_globals.core.Item.prototype.children = []

	_globals.core.Item.prototype.toScreen = function() {
		var item = this;
		var x = 0, y = 0;
		while(item) {
			x += item.x;
			y += item.y;
			item = item.parent;
		}
		return [x, y, x + this.width, y + this.height];
	}

	_globals.core.Border.prototype._update = function(name, value) {
		switch(name) {
			case 'width': this.parent.element.css({'border-width': value, 'margin-left': -value, 'margin-top': -value}); break;
			case 'color': this.parent.element.css('border-color', value); break;
		}
		_globals.core.Object.prototype._update.apply(this, arguments);
	}

	_globals.core.Item.prototype._update = function(name, value) {
		switch(name) {
			case 'width': 	this.element.css('width', value); this.right.value = this.x + value; break;
			case 'height':	this.element.css('height', value); this.bottom.value = this.y + value; break;
			case 'x':		this.element.css('left', value); this.left.value = value; this.right.value = value + this.width; break;
			case 'y':		this.element.css('top', value); this.top.value = value; this.bottom.value = value + this.height; break;
			case 'z':		this.element.css('z-index', value); break;
			case 'radius':	this.element.css('border-radius', value); break;
		}
		_globals.core.Object.prototype._update.apply(this, arguments);
	}

	_globals.core.AnchorLine.prototype.toScreen = function() {
		return this.parent.parent.toScreen()[this.boxIndex] + this.value;
	}

	_globals.core.Anchors.prototype._update = function(name, line) {
		var self = this.parent;
		var target = line.parent;
		var anchors = this;
		var lm = anchors.leftMargin || anchors.margins;
		var rm = anchors.rightMargin || anchors.margins;
		var tm = anchors.topMargin || anchors.margins;
		var bm = anchors.bottomMargin || anchors.margins;

		var update_left = function() {
			var parent_box = self.parent.toScreen();
			//console.log(target_box, parent_box);
			self.x = line.toScreen() + lm - parent_box[0];
			if (anchors.right) {
				var right_target_box = anchors.right.parent.toScreen();
				self.width = (right_target_box[2] - parent_box[0]) - self.x - rm ;
			}
		};

		var update_right = function() {
			var parent_box = self.parent.toScreen();
			//console.log(target_box, parent_box);
			if (anchors.left) {
				var left_target_box = anchors.left.parent.toScreen();
				self.width = line.toScreen() - left_target_box[0] - lm - rm;
			}
			self.x = (line.toScreen() - parent_box[0] - self.width) + lm;
		};

		var update_top = function() {
			var parent_box = self.parent.toScreen();
			//console.log(target_box, parent_box);
			self.y = line.toScreen() + tm - parent_box[1];
			if (anchors.bottom) {
				var bottom_target_box = anchors.bottom.parent.toScreen();
				self.height = (bottom_target_box[3] - parent_box[1]) - self.y - bm;
			}
		};

		var update_bottom = function() {
			var parent_box = self.parent.toScreen();
			//console.log(target_box, parent_box);
			if (anchors.top) {
				var top_target_box = anchors.top.parent.toScreen();
				self.height = line.toScreen() - top_target_box[1] - tm - bm;
			}
			self.y = (line.toScreen() - parent_box[1] - self.height) + tm;
		};

		switch(name) {
			case 'left':
				update_left();
				target.left.onChanged('value', update_left);
				break;

			case 'right':
				update_right();
				target.right.onChanged('value', update_right);
				break;

			case 'top':
				update_top();
				target.top.onChanged('value', update_top);
				break;

			case 'bottom':
				update_bottom();
				target.bottom.onChanged('value', update_bottom);
				break;
		}
		_globals.core.Object.prototype._update.apply(this, arguments);
	}

	_globals.core.Font.prototype._update = function(name, value) {
		switch(name) {
			case 'pointSize': this.parent.element.css('font-size', value + "pt"); break;
			case 'pixelSize': this.parent.element.css('font-size', value + "px"); break;
			case 'italic': this.parent.element.css('font-style', value? 'italic': 'normal'); break;
		}
		_globals.core.Object.prototype._update.apply(this, arguments);
	}

	_globals.core.Text.prototype._update = function(name, value) {
		switch(name) {
			case 'text': this.element.text(value); break;
		}
		_globals.core.Item.prototype._update.apply(this, arguments);
	}

	_globals.core.Rectangle.prototype._update = function(name, value) {
		switch(name) {
			case 'color': this.element.css('background-color', value); break;
		}
		_globals.core.Item.prototype._update.apply(this, arguments);
	}
}

exports.Context = function() {
	_globals.core.Object.apply(this, null);

	var w = $(window).width();
	var h = $(window).height();
	console.log("window size: " + w + "x" + h);

	var body = $('body');
	var div = $("

");
	body.append(div);
	$('head').append($(""
	));

	exports.addProperty(this, 'int', 'x');
	exports.addProperty(this, 'int', 'y');
	exports.addProperty(this, 'int', 'width');
	exports.addProperty(this, 'int', 'height');

	this.element = div
	this.element.css({width: w, height: h});
	this.width = w;
	this.height = h;

	console.log("context created");
	setup(this);
}

exports.Context.prototype = Object.create(_globals.core.Object.prototype);
exports.Context.prototype.constructor = exports.Context;

exports.Context.prototype.toScreen = function() {
	return [0, 0, this.width, this.height];
}

exports.Context.prototype.start = function(name) {
	var proto;
	if (typeof name == 'string') {
		console.log('creating component...', name);
		var path = name.split('.');
		proto = _globals;
		for (var i = 0; i < path.length; ++i)
			proto = proto[path[i]]
	}
	else
		proto = name;
	var instance = Object.create(proto.prototype);
	proto.apply(instance, [this]);
	return instance;
}

exports.addProperty = function(self, type, name) {
	var value;
	var timer;
	switch(type) {
		case 'int':			value = 0; break;
		case 'bool':		value = false; break;
		case 'real':		value = 0.0; break;
		default: if (type[0].toUpperCase() == type[0]) value = null; break;
	}
	Object.defineProperty(self, name, {
		get: function() {
			return value;
		},
		set: function(newValue) {
			var animation = self.getAnimation(name)
			if (animation && value != newValue) {
				var duration = animation.duration;
				var date = new Date();
				var started = date.getTime() + date.getMilliseconds() / 1000.0;
				var src = value;
				var dst = newValue;
				timer = setInterval(function() {
					var date = new Date();
					var now = date.getTime() + date.getMilliseconds() / 1000.0;
					var t = 1.0 * (now - started) / duration;
					if (t >= 1)
						t = 1;
					self._update(name, t * (dst - src) + src, src);
				});

				setTimeout(function() {
					clearInterval(timer);
					self._update(name, dst, src);
				}, duration);
			}
			oldValue = value;
			if (oldValue != newValue) {
				value = newValue;
				if (!animation)
					self._update(name, newValue, oldValue);
			}
		},
		enumerable: true
	});
}

exports._bootstrap = function(self, name) {
	switch(name) {
		case 'core.Item':
			if (self.element)
				throw "double ctor call";
			self.element = $('
');
			self.parent.element.append(self.element);
			break;
	}
}
<|endoftext|>


<commit_before>'use strict'

import ansiHTML from 'ansi-html'
import serialize from 'serialize-javascript'
import { getContext, setAnsiColors, encodeHtml } from './utils'
const debug = require('debug')('nuxt:render')
// force blue color
debug.color = 4
setAnsiColors(ansiHTML)

export async function render (req, res) {
  if (!this.renderer && !this.dev) {
    console.error('> No build files found, please run `nuxt build` before launching `nuxt start`') // eslint-disable-line no-console
    process.exit(1)
  }
  /* istanbul ignore if */
  if (!this.renderer || !this.appTemplate) {
    return new Promise((resolve) => {
      setTimeout(() => {
        debug('Waiting for renderer to be ready')
        resolve(this.render(req, res))
      }, 1000)
    })
  }
  const context = getContext(req, res)
  res.statusCode = 200
  try {
    if (this.dev) {
      // Call webpack middleware only in development
      await this.webpackDevMiddleware(req, res)
      await this.webpackHotMiddleware(req, res)
    }
    if (!this.dev && this.options.performance.gzip) {
      await this.gzipMiddleware(req, res)
    }
    // If base in req.url, remove it for the middleware and vue-router
    if (this.options.router.base !== '/' && req.url.indexOf(this.options.router.base) === 0) {
      // Compatibility with base url for dev server
      req.url = req.url.replace(this.options.router.base, '/')
    }
    // Serve static/ files
    await this.serveStatic(req, res)
    // Serve .nuxt/dist/ files (only for production)
    if (!this.dev && req.url.indexOf(this.options.build.publicPath) === 0) {
      const url = req.url
      req.url = req.url.replace(this.options.build.publicPath, '/')
      await this.serveStaticNuxt(req, res)
      /* istanbul ignore next */
      req.url = url
    }
    if (this.dev && req.url.indexOf(this.options.build.publicPath) === 0 && req.url.includes('.hot-update.json')) {
      res.statusCode = 404
      return res.end()
    }
    const { html, error, redirected } = await this.renderRoute(req.url, context)
    if (redirected) {
      return html
    }
    if (error) {
      res.statusCode = context.nuxt.error.statusCode || 500
    }
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    res.setHeader('Content-Length', Buffer.byteLength(html))
    res.end(html, 'utf8')
    return html
  } catch (err) {
    if (context.redirected) {
      console.error(err) // eslint-disable-line no-console
      return err
    }
    const html = this.errorTemplate({
      error: err,
      stack: ansiHTML(encodeHtml(err.stack))
    })
    res.statusCode = 500
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    res.setHeader('Content-Length', Buffer.byteLength(html))
    res.end(html, 'utf8')
    return err
  }
}

export async function renderRoute (url, context = {}) {
  debug(`Rendering url ${url}`)
  // Add url and isSever to the context
  context.url = url
  context.isServer = true
  // Call renderToString from the bundleRenderer and generate the HTML (will update the context as well)
  let APP = await this.renderToString(context)
  if (!context.nuxt.serverRendered) {
    APP = '

'
  }
  const m = context.meta.inject()
  let HEAD = m.meta.text() + m.title.text() + m.link.text() + m.style.text() + m.script.text() + m.noscript.text()
  if (this._routerBaseSpecified) {
    HEAD += `<base href="${this.options.router.base}">`
  }
  if (this.options.performance.prefetch) {
    HEAD += context.renderResourceHints()
  }
  HEAD += context.renderStyles()
  APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })}</script>`
  APP += context.renderScripts()
  const html = this.appTemplate({
    HTML_ATTRS: 'data-n-head-ssr ' + m.htmlAttrs.text(),
    BODY_ATTRS: m.bodyAttrs.text(),
    HEAD,
    APP
  })
  return {
    html,
    error: context.nuxt.error,
    redirected: context.redirected
  }
}

// Function used to do dom checking via jsdom
let jsdom = null
export function renderAndGetWindow (url, opts = {}) {
  /* istanbul ignore if */
  if (!jsdom) {
    try {
      // https://github.com/tmpvar/jsdom/blob/master/lib/old-api.md
      jsdom = require('jsdom/lib/old-api')
    } catch (e) {
      console.error('Fail when calling nuxt.renderAndGetWindow(url)') // eslint-disable-line no-console
      console.error('jsdom module is not installed') // eslint-disable-line no-console
      console.error('Please install jsdom with: npm install --save-dev jsdom') // eslint-disable-line no-console
      process.exit(1)
    }
  }
  let virtualConsole = jsdom.createVirtualConsole().sendTo(console)
  // let virtualConsole = new jsdom.VirtualConsole().sendTo(console)
  if (opts.virtualConsole === false) {
    virtualConsole = undefined
  }
  url = url || 'http://localhost:3000'
  return new Promise((resolve, reject) => {
    jsdom.env({
      url: url,
      features: {
        FetchExternalResources: ['script', 'link'],
        ProcessExternalResources: ['script']
      },
      virtualConsole,
      done (err, window) {
        if (err) return reject(err)
        // Mock window.scrollTo
        window.scrollTo = function () {}
        // If Nuxt could not be loaded (error from the server-side)
        if (!window.__NUXT__) {
          let error = new Error('Could not load the nuxt app')
          error.body = window.document.getElementsByTagName('body')[0].innerHTML
          return reject(error)
        }
        // Used by nuxt.js to say when the components are loaded and the app ready
        window.onNuxtReady(() => {
          resolve(window)
        })
      }
    })
  })
}
<commit_msg>disable console log<commit_after>'use strict'

import ansiHTML from 'ansi-html'
import serialize from 'serialize-javascript'
import { getContext, setAnsiColors, encodeHtml } from './utils'
const debug = require('debug')('nuxt:render')
// force blue color
debug.color = 4
setAnsiColors(ansiHTML)

export async function render (req, res) {
  if (!this.renderer && !this.dev) {
    console.error('> No build files found, please run `nuxt build` before launching `nuxt start`') // eslint-disable-line no-console
    process.exit(1)
  }
  /* istanbul ignore if */
  if (!this.renderer || !this.appTemplate) {
    return new Promise((resolve) => {
      setTimeout(() => {
        // debug('Waiting for renderer to be ready')
        resolve(this.render(req, res))
      }, 1000)
    })
  }
  const context = getContext(req, res)
  res.statusCode = 200
  try {
    if (this.dev) {
      // Call webpack middleware only in development
      await this.webpackDevMiddleware(req, res)
      await this.webpackHotMiddleware(req, res)
    }
    if (!this.dev && this.options.performance.gzip) {
      await this.gzipMiddleware(req, res)
    }
    // If base in req.url, remove it for the middleware and vue-router
    if (this.options.router.base !== '/' && req.url.indexOf(this.options.router.base) === 0) {
      // Compatibility with base url for dev server
      req.url = req.url.replace(this.options.router.base, '/')
    }
    // Serve static/ files
    await this.serveStatic(req, res)
    // Serve .nuxt/dist/ files (only for production)
    if (!this.dev && req.url.indexOf(this.options.build.publicPath) === 0) {
      const url = req.url
      req.url = req.url.replace(this.options.build.publicPath, '/')
      await this.serveStaticNuxt(req, res)
      /* istanbul ignore next */
      req.url = url
    }
    if (this.dev && req.url.indexOf(this.options.build.publicPath) === 0 && req.url.includes('.hot-update.json')) {
      res.statusCode = 404
      return res.end()
    }
    const { html, error, redirected } = await this.renderRoute(req.url, context)
    if (redirected) {
      return html
    }
    if (error) {
      res.statusCode = context.nuxt.error.statusCode || 500
    }
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    res.setHeader('Content-Length', Buffer.byteLength(html))
    res.end(html, 'utf8')
    return html
  } catch (err) {
    if (context.redirected) {
      console.error(err) // eslint-disable-line no-console
      return err
    }
    const html = this.errorTemplate({
      error: err,
      stack: ansiHTML(encodeHtml(err.stack))
    })
    res.statusCode = 500
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    res.setHeader('Content-Length', Buffer.byteLength(html))
    res.end(html, 'utf8')
    return err
  }
}

export async function renderRoute (url, context = {}) {
  debug(`Rendering url ${url}`)
  // Add url and isSever to the context
  context.url = url
  context.isServer = true
  // Call renderToString from the bundleRenderer and generate the HTML (will update the context as well)
  let APP = await this.renderToString(context)
  if (!context.nuxt.serverRendered) {
    APP = '

'
  }
  const m = context.meta.inject()
  let HEAD = m.meta.text() + m.title.text() + m.link.text() + m.style.text() + m.script.text() + m.noscript.text()
  if (this._routerBaseSpecified) {
    HEAD += `<base href="${this.options.router.base}">`
  }
  if (this.options.performance.prefetch) {
    HEAD += context.renderResourceHints()
  }
  HEAD += context.renderStyles()
  APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })}</script>`
  APP += context.renderScripts()
  const html = this.appTemplate({
    HTML_ATTRS: 'data-n-head-ssr ' + m.htmlAttrs.text(),
    BODY_ATTRS: m.bodyAttrs.text(),
    HEAD,
    APP
  })
  return {
    html,
    error: context.nuxt.error,
    redirected: context.redirected
  }
}

// Function used to do dom checking via jsdom
let jsdom = null
export function renderAndGetWindow (url, opts = {}) {
  /* istanbul ignore if */
  if (!jsdom) {
    try {
      // https://github.com/tmpvar/jsdom/blob/master/lib/old-api.md
      jsdom = require('jsdom/lib/old-api')
    } catch (e) {
      console.error('Fail when calling nuxt.renderAndGetWindow(url)') // eslint-disable-line no-console
      console.error('jsdom module is not installed') // eslint-disable-line no-console
      console.error('Please install jsdom with: npm install --save-dev jsdom') // eslint-disable-line no-console
      process.exit(1)
    }
  }
  let virtualConsole = jsdom.createVirtualConsole().sendTo(console)
  // let virtualConsole = new jsdom.VirtualConsole().sendTo(console)
  if (opts.virtualConsole === false) {
    virtualConsole = undefined
  }
  url = url || 'http://localhost:3000'
  return new Promise((resolve, reject) => {
    jsdom.env({
      url: url,
      features: {
        FetchExternalResources: ['script', 'link'],
        ProcessExternalResources: ['script']
      },
      virtualConsole,
      done (err, window) {
        if (err) return reject(err)
        // Mock window.scrollTo
        window.scrollTo = function () {}
        // If Nuxt could not be loaded (error from the server-side)
        if (!window.__NUXT__) {
          let error = new Error('Could not load the nuxt app')
          error.body = window.document.getElementsByTagName('body')[0].innerHTML
          return reject(error)
        }
        // Used by nuxt.js to say when the components are loaded and the app ready
        window.onNuxtReady(() => {
          resolve(window)
        })
      }
    })
  })
}
<|endoftext|>


<commit_before>var net = require('net'),
    http = require('http'),
    sys = require("sys"),
    microseconds = require("./deps/node-microseconds/lib/node-microseconds"),
    EventEmitter = require('events').EventEmitter,
    mongo = require('./deps/node-mongodb-native/lib/mongodb'),
    host = process.env['MONGO_NODE_DRIVER_HOST'] != null ?
      process.env['MONGO_NODE_DRIVER_HOST'] : 'localhost',
    port = process.env['MONGO_NODE_DRIVER_PORT'] != null ?
      process.env['MONGO_NODE_DRIVER_PORT'] : mongo.Connection.DEFAULT_PORT,
    LINE_SIZE = 120,
    db = new mongo.Db('node-mongo-queue', new mongo.Server(host, port, {}), {}),
    messages = [],
    waiters = [],
    emitter = new EventEmitter(),
    host = 'ec2-174-129-57-251.compute-1.amazonaws.com'; //'127.0.0.1',
    push_port = 8081,
    pull_port = 8082,
    alive_port = 8083;

sys.puts("Connecting to " + host + ":" + port);

db.open(function(err,db) {
  var collection = db.collection('node-queue', function(err, collection) {
    collection.find(function(err, cursor) {
      cursor.each(function(err, item) {
        if(item != null) {
          messages.push(item);
          sys.puts('Added message with id ' + item._id + ' to queue.');
        }
      });
    });
    net.createServer(function(stream) {}).listen(alive_port, host);
    var push = net.createServer(function(stream) {
      var message = '';
      // stream.setEncoding('utf8');
      // stream.on('connect', function(){ });
      stream.on('data', function(data) { message += data; });
      stream.on('end', function() {
        // insert message into database
        var ts = microseconds.milliseconds();
        collection.insert({message:message, timestamp: ts},function(err, docs) {
          if (err) {
            sys.puts(sys.inspect(err));
          } else {
            for (var i=0; i<docs.length; i++) {
              messages.push(docs[i]);
              sys.puts('Enqueued message ' + docs[i]._id + ' at timestamp ' + docs[i].timestamp);
            }
            emitter.emit('message');
          }
        });
      });
    });
    push.listen(push_port, host);
    var pull = net.createServer(function(stream) {
      stream.on('connect', function(){
        if (messages.length) {
          message = messages.shift();
          collection.remove({_id: message._id}, function(err, collection) {});
          stream.write(message.message);
          stream.end();
          sys.puts('Dequeued message ' + message._id + ' at timestamp ' + message.timestamp);
        } else {
          waiters.push(stream);
        }
      });
      // stream.on('data', function(){});
      // stream.on('end', function(){});
    });
    pull.listen(pull_port, host);

    emitter.on('message', function(){
      if (messages.length && waiters.length) {
        stream = waiters.shift();
        message = messages.shift();
        collection.remove({_id: message._id}, function(err, collection) {});
        stream.write(message.message);
        stream.end();
        sys.puts('Dequeued message ' + message._id + ' at timestamp ' + message.timestamp);
      }
    });
  });
});

/*
http.createServer(function(request,response){
  response.writeHead(200, {
    'Content-type':'text/plain'
  });
  response.end('Hello World\n');
}).listen(8124);
console.log('Server running at http://localhost:8124/');

var net = require('net');
var server = net.createServer(function(stream) {
  stream.setEncoding('utf8');
  stream.on('connect', function(){
    stream.write('hello\r\n');
  });
  stream.on('data', function(data) {
    stream.write(data);
  });
  stream.on('end', function() {
    stream.write('goodbye\r\n');
  });
});
server.listen(8125,'localhost');
*/<commit_msg>adding web server to queue<commit_after>var net = require('net'),
    http = require('http'),
    sys = require("sys"),
    url = require('url'),
    microseconds = require("./deps/node-microseconds/lib/node-microseconds"),
    EventEmitter = require('events').EventEmitter,
    mongo = require('./deps/node-mongodb-native/lib/mongodb'),
    host = process.env['MONGO_NODE_DRIVER_HOST'] != null ?
      process.env['MONGO_NODE_DRIVER_HOST'] : 'localhost',
    port = process.env['MONGO_NODE_DRIVER_PORT'] != null ?
      process.env['MONGO_NODE_DRIVER_PORT'] : mongo.Connection.DEFAULT_PORT,
    LINE_SIZE = 120,
    db = new mongo.Db('node-mongo-queue', new mongo.Server(host, port, {}), {}),
    messages = [],
    waiters = [],
    emitter = new EventEmitter(),
    host = 'localhost',
    web_port = 8080,
    push_port = 8081,
    pull_port = 8082,
    alive_port = 8083;

sys.puts("Connecting to " + host + ":" + port);

db.open(function(err,db) {
  var collection = db.collection('node-queue', function(err, collection) {
    collection.find(function(err, cursor) {
      cursor.each(function(err, item) {
        if(item != null) {
          messages.push(item);
          sys.puts('Added message with id ' + item._id + ' to queue.');
        }
      });
    });
    net.createServer(function(stream) {}).listen(alive_port, host);
    var push = net.createServer(function(stream) {
      var message = '';
      // stream.setEncoding('utf8');
      // stream.on('connect', function(){ });
      stream.on('data', function(data) { message += data; });
      stream.on('end', function() {
        // insert message into database
        var ts = microseconds.milliseconds();
        collection.insert({message:message, timestamp: ts},function(err, docs) {
          if (err) {
            sys.puts(sys.inspect(err));
          } else {
            for (var i=0; i<docs.length; i++) {
              messages.push(docs[i]);
              sys.puts('Enqueued message ' + docs[i]._id + ' at timestamp ' + docs[i].timestamp);
            }
            emitter.emit('message');
          }
        });
      });
    });
    push.listen(push_port, host);
    var pull = net.createServer(function(stream) {
      stream.on('connect', function(){
        if (messages.length) {
          message = messages.shift();
          collection.remove({_id: message._id}, function(err, collection) {});
          stream.end('{"success":true,message:'+message+'}');
          sys.puts('Dequeued message ' + message._id + ' at timestamp ' + message.timestamp);
        } else {
          waiters.push(stream);
        }
      });
      // stream.on('data', function(){});
      // stream.on('end', function(){});
    });
    pull.listen(pull_port, host);

    var web = http.createServer(function(request,response){
      var parsed = url.parse(request.url, true),
          output = {
            success: false,
            message: 'Unknown error'
          },
          message;
      response.writeHead(200, {
        'Content-type':'text/json'
      });
      switch(parsed.pathname) {
        case '/push':
          if (parsed['query'] && parsed.query['message']) {
            sys.puts('got message via http: '+parsed.query.message);
            var ts = microseconds.milliseconds();
            collection.insert({message:parsed.query.message, timestamp: ts},function(err, docs) {
              if (err) {
                sys.puts(sys.inspect(err));
                output.success = false;
                output.message = "failed to insert message.";
                output.detail = err;
                response.end(sys.inspect(output));
              } else {
                for (var i=0; i<docs.length; i++) {
                  messages.push(docs[i]);
                  sys.puts('Enqueued message ' + docs[i].id + ' at timestamp ' + docs[i].timestamp);
                }
                emitter.emit('message');
                output.success = true;
                output.message = "message enqueueued";
                output.id = ''+docs[0]._id;
                response.end(sys.inspect(output));
              }
            });
          } else {
            output.message = 'push requires message parameter';
            response.end(sys.inspect(output));
          }
          break;
        case '/pull':
          if (messages.length) {
            message = messages.shift();
            collection.remove({_id: message._id}, function(err, collection) {});
            output.success = true;
            output.message = message;
            response.end(sys.inspect(output));
            sys.puts('Dequeued message ' + message._id + ' at timestamp ' + message.timestamp);
          } else {
            waiters.push(response);
          }
          break;
        case '/list':
          output.success = true;
          output.message = messages;
          response.end(sys.inspect(output));
          break;
        default:
          output.message = "Invalid request path "+request.pathname+", should be /push or /pull";
          response.end(sys.inspect(output));
      }
    }).listen(web_port);
    console.log('Web Server running on port ' + web_port);

    emitter.on('message', function(){
      var output = {
        success: true,
        message: ''
      };
      if (messages.length && waiters.length) {
        stream = waiters.shift();
        message = messages.shift();
        collection.remove({_id: message._id}, function(err, collection) {});
        output.message = message;
        stream.end(sys.inspect(output));
        sys.puts('Dequeued message ' + message._id + ' at timestamp ' + message.timestamp);
      }
    });
  });
});

<|endoftext|>


<commit_before>var Client = require("rester-client").Client,
    Parser = require("rester-client").Parser;

var eol = "\r\n",
    responseEditor;

function getSelectionOrText(editor) {
    var selection = editor.getSelectedText().trim();
    if (selection.length > 0) {
        return selection;
    }
    return editor.getText();
}

function displayResponse(response) {
    if (responseEditor) {
        try {
            if (!responseEditor.isEmpty()) {
                responseEditor.selectAll();
                responseEditor.delete();
            }
            writeResponse(response, responseEditor, function () {
                responseEditor.setCursorBufferPosition([0, 0]);
            });
        } catch (e) {
             responseEditor = null;
             displayResponse(response);
        }
    } else {
        atom.workspace.open(undefined, {
            split: "right"
        }).then(function (editor) {
            responseEditor = editor;
            writeResponse(response, responseEditor, function () {
                responseEditor.setCursorBufferPosition([0, 0]);
            });
        });
    }
}

function writeResponse(response, editor, callback) {
    var i, u;

    // Status line
    editor.insertText([
        "HTTP/" + response.httpVersion,
        response.statusCode,
        response.statusMessage
    ].join(" ") + eol);

    // Headers
    for (i = 0, u = response.rawHeaders.length; i < u; ++i) {
        editor.insertText(response.rawHeaders[i]);
        editor.insertText(i % 2 === 0 ? ": " : eol);
    }
    editor.insertText(eol);

    // Body
    response.setEncoding(editor.getEncoding());
    response.on("data",  function (chunk) {
        editor.insertText(chunk);
    });
    response.on("end", function () {
        callback();
    });
}

// -----------------------------------------------------------------------------

module.exports = {
    activate: function() {
        atom.commands.add("atom-workspace", "rester:request", this.request);
    },
    request: function() {
        var parser = new Parser(),
            editor = atom.workspace.getActiveTextEditor(),
            text = getSelectionOrText(editor);
        parser.parse(text, function (error, options, body) {
            var client = new Client();
            client.on("response", function (response, willRedirect) {
                if (!willRedirect) {
                    displayResponse(response);
                }
            });
            client.request(options, body);
        });
    }
};
<commit_msg>Show error alert on failed request.<commit_after>var Client = require("rester-client").Client,
    Parser = require("rester-client").Parser;

var eol = "\r\n",
    responseEditor;

function getSelectionOrText(editor) {
    var selection = editor.getSelectedText().trim();
    if (selection.length > 0) {
        return selection;
    }
    return editor.getText();
}

function displayResponse(response) {
    if (responseEditor) {
        try {
            if (!responseEditor.isEmpty()) {
                responseEditor.selectAll();
                responseEditor.delete();
            }
            writeResponse(response, responseEditor, function () {
                responseEditor.setCursorBufferPosition([0, 0]);
            });
        } catch (e) {
             responseEditor = null;
             displayResponse(response);
        }
    } else {
        atom.workspace.open(undefined, {
            split: "right"
        }).then(function (editor) {
            responseEditor = editor;
            writeResponse(response, responseEditor, function () {
                responseEditor.setCursorBufferPosition([0, 0]);
            });
        });
    }
}

function makeRequest() {
    var parser = new Parser(),
        editor = atom.workspace.getActiveTextEditor(),
        text = getSelectionOrText(editor);
    parser.parse(text, function (error, options, body) {
        var client = new Client();
        client.on("response", function (response, willRedirect) {
            if (!willRedirect) {
                displayResponse(response);
            }
        });
        client.on("error", function (message) {
            atom.notifications.addError("Error making request", {detail: message});
        });
        client.request(options, body);
    });
}

function writeResponse(response, editor, callback) {
    var i, u;

    // Status line
    editor.insertText([
        "HTTP/" + response.httpVersion,
        response.statusCode,
        response.statusMessage
    ].join(" ") + eol);

    // Headers
    for (i = 0, u = response.rawHeaders.length; i < u; ++i) {
        editor.insertText(response.rawHeaders[i]);
        editor.insertText(i % 2 === 0 ? ": " : eol);
    }
    editor.insertText(eol);

    // Body
    response.setEncoding(editor.getEncoding());
    response.on("data",  function (chunk) {
        editor.insertText(chunk);
    });
    response.on("end", function () {
        callback();
    });
}

// -----------------------------------------------------------------------------

module.exports = {
    activate: function() {
        atom.commands.add("atom-workspace", "rester:request", makeRequest);
    }
};
<|endoftext|>


<commit_before>(function() {
  var DefaultParser, RetinaControl, StaticParser, activate_element, add_parser, clear_parsers, ignore_element, parsers, remove_parser, retina, root, scan, set_manual_mode, set_parser, _active_controls, _active_elements, _current_zoom_level, _get_zoom_level, _ignore_list, _is_manual_mode, _schedule_scan;
  var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __indexOf = Array.prototype.indexOf || function(item) {
    for (var i = 0, l = this.length; i < l; i++) {
      if (__hasProp.call(this, i) && this[i] === item) return i;
    }
    return -1;
  };
  root = this;
  _current_zoom_level = 1;
  _is_manual_mode = false;
  _ignore_list = [];
  _active_elements = [];
  _active_controls = [];
  parsers = [];
  DefaultParser = (function() {
    function DefaultParser() {}
    DefaultParser.prototype._pattern = /([\.\-_][0-9])?@(1x)?\.[a-z]+$/i;
    DefaultParser.prototype.isValidFilename = function(filename) {
      return !!filename.match(this._pattern);
    };
    DefaultParser.prototype.zoomLevelsForFilename = function(filename) {
      var i, match, max, _results;
      match = filename.match(this._pattern);
      max = match[1] ? parseInt(match[1].slice(1), 10) : 2;
      _results = [];
      for (i = 1; 1 <= max ? i <= max : i >= max; 1 <= max ? i++ : i--) {
        _results.push(Math.pow(2, i - 1));
      }
      return _results;
    };
    DefaultParser.prototype.filenameForZoom = function(baseFilename, zoom) {
      var match;
      if (zoom === 1) {
        return baseFilename;
      } else {
        match = baseFilename.match(/(.+)@(.*?)\.([a-z]+)$/i);
        return match[1] + "@" + zoom + "x." + match[3];
      }
    };
    return DefaultParser;
  })();
  StaticParser = (function() {
    function StaticParser(conf) {
      this.conf = conf != null ? conf : [];
    }
    StaticParser.prototype._confForFilename = function(filename) {
      var conf, _i, _len, _ref;
      _ref = this.conf;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        conf = _ref[_i];
        if (typeof conf === "string") conf = [conf];
        if (filename.match(new RegExp("" + conf[0] + "$"))) return conf;
      }
      return null;
    };
    StaticParser.prototype.isValidFilename = function(filename) {
      return !!this._confForFilename(filename);
    };
    StaticParser.prototype.zoomLevelsForFilename = function(filename) {
      var conf, i, max, _results;
      conf = this._confForFilename(filename);
      max = conf.length > 1 ? typeof conf[1] === "number" ? conf[1] : conf.length : 2;
      _results = [];
      for (i = 1; 1 <= max ? i <= max : i >= max; 1 <= max ? i++ : i--) {
        _results.push(Math.pow(2, i - 1));
      }
      return _results;
    };
    StaticParser.prototype.filenameForZoom = function(baseFilename, zoom) {
      var conf, filename, parts, zoom_sfx;
      conf = this._confForFilename(baseFilename);
      filename = conf[0];
      if (conf.length === 1 || conf.length > 1 && typeof conf[1] === "number") {
        if (zoom === 1) {
          return baseFilename;
        } else {
          parts = baseFilename.match(/(.+?)(@)?([0-9]+x)?\.([a-z]+$)/i);
          zoom_sfx = zoom === 1 ? "" : "@" + zoom + "x";
          return "" + parts[1] + zoom_sfx + "." + parts[4];
        }
      } else {
        return conf[zoom - 1];
      }
    };
    return StaticParser;
  })();
  RetinaControl = (function() {
    function RetinaControl(element, parser, is_image, url) {
      var init_size;
      this.element = element;
      this.parser = parser;
      this.is_image = is_image;
      this.url = url;
      this.complete = 0;
      this.width = 0;
      this.height = 0;
      this.zoom = 1;
      this.setImagePath(this.url);
      init_size = __bind(function(width, height) {
        this.width = width;
        this.height = height;
        return this.setZoom(_current_zoom_level);
      }, this);
      if (this.is_image && this.element.complete) {
        init_size(this.element.naturalWidth, this.element.naturalHeight);
      } else {
        this.cachePath(this.url, init_size);
      }
    }
    RetinaControl.prototype.setZoom = function(zoom) {
      var bgwidth, l, level, levels, match, path, _i, _len;
      if (this.is_image) {
        zoom *= this.element.offsetWidth / this.width;
      } else {
        bgwidth = root.getComputedStyle(this.element, null)['background-size'].split(" ")[0];
        if (match = bgwidth.match(/(.+)(px|%)$/)) {
          if (match[2] === "px") {
            zoom *= (parseFloat(match[1])) / this.width;
          } else {
            zoom *= (parseFloat(match[1])) / 100 * this.element.offsetWidth / this.width;
          }
        }
      }
      levels = this.parser.zoomLevelsForFilename(this.url);
      level = levels.slice(-1)[0];
      for (_i = 0, _len = levels.length; _i < _len; _i++) {
        l = levels[_i];
        if (l >= zoom && l < level) level = l;
      }
      if (level === this.zoom) return;
      path = this.parser.filenameForZoom(this.url, level);
      this.cachePath(path, __bind(function() {
        var _base, _base2, _base3;
        if (this.is_image) {
          if (!((this.element.getAttribute("width")) || (this.element.getAttribute("height")))) {
            (_base = this.element.style)['width'] || (_base['width'] = "" + this.width + "px");
            (_base2 = this.element.style)['height'] || (_base2['height'] = "" + this.height + "px");
          }
        } else {
          (_base3 = this.element.style)['backgroundSize'] || (_base3['backgroundSize'] = "" + this.width + "px " + this.height + "px");
        }
        return this.setImagePath(path);
      }, this));
      return this.zoom = level;
    };
    RetinaControl.prototype.release = function() {
      return this.setZoom(1);
    };
    RetinaControl.prototype.setImagePath = function(url) {
      var tmp_bgsize;
      if (this.is_image) {
        return this.element.src = url;
      } else {
        tmp_bgsize = root.getComputedStyle(this.element, null)['background-size'];
        this.element.style['backgroundImage'] = "url(" + url + ")";
        if (tmp_bgsize !== "auto auto" && !root.navigator.userAgent.match(/Chrome/)) {
          return this.element.style['backgroundSize'] = tmp_bgsize;
        }
      }
    };
    RetinaControl.prototype.cachePath = function(url, callback) {
      var img, _ref;
      if ((_ref = this.cached) == null) this.cached = {};
      if (url in this.cached) return callback(this.cached[url]);
      img = new Image;
      img.addEventListener("load", __bind(function() {
        this.cached[url] = [img.naturalWidth, img.naturalHeight];
        return callback.apply(null, this.cached[url]);
      }, this));
      return img.src = url;
    };
    return RetinaControl;
  })();
  _get_zoom_level = function() {
    var screenWidth, userAgent, _ref, _ref2;
    userAgent = (_ref = root.navigator) != null ? _ref.userAgent : void 0;
    if (root.window && userAgent.match(/Webkit/i)) {
      return (userAgent.match(/Mobile/i) ? (screenWidth = (_ref2 = root.orientation) === 0 || _ref2 === 180 ? root.screen.width : root.screen.height, root.devicePixelRatio ? screenWidth *= root.devicePixelRatio : void 0) : root.document.width) / root.window.innerWidth;
    } else {
      return 1;
    }
  };
  add_parser = function(parser) {
    var func, _i, _len, _ref;
    _ref = "isValidFilename zoomLevelsForFilename filenameForZoom".split(" ");
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      func = _ref[_i];
      if (typeof parser[func] !== "function") {
        throw "Invalid parser object. No method " + func + " found.";
      }
    }
    return parsers.push(parser);
  };
  remove_parser = function(parser) {
    var index;
    if (__indexOf.call(parsers, parser) >= 0) {
      index = parsers.indexOf(parser);
      return parsers.splice(index, 1);
    }
  };
  clear_parsers = function() {
    while (parsers.length) {
      remove_parser(parsers[0]);
    }
  };
  set_parser = function(parser) {
    if (parsers.length !== 1 || parsers[0] !== parser) {
      clear_parsers();
      return add_parser(parser);
    }
  };
  _schedule_scan = (function() {
    var next;
    next = 0;
    return function(delay) {
      if (delay == null) delay = 4000;
      if (next) root.clearTimeout(next);
      if (delay >= 0 && !_is_manual_mode) {
        return next = root.setTimeout(scan, delay);
      }
    };
  })();
  scan = (function() {
    var walker;
    walker = null;
    return function(reset) {
      var count, element;
      if (reset == null) reset = true;
      if (walker == null) {
        walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
          acceptNode: function(node) {
            if (node.tagName === "IMG" && node.getAttribute("src") || root.getComputedStyle(node)['background-image'] !== "none") {
              return NodeFilter.FILTER_ACCEPT;
            } else {
              return NodeFilter.FILTER_SKIP;
            }
          }
        }, false);
      }
      if (reset) walker.currentNode = document.body;
      count = 0;
      while (element = walker.nextNode()) {
        if (__indexOf.call(_ignore_list, element) >= 0) continue;
        if (__indexOf.call(_active_elements, element) < 0) {
          activate_element(element);
        }
        if (++count > 50) {
          return setTimeout((function() {
            return scan(false);
          }), 50);
        }
      }
      return _schedule_scan();
    };
  })();
  set_manual_mode = function(manual) {
    if (manual == null) manual = true;
    _is_manual_mode = !!manual;
    return _schedule_scan();
  };
  activate_element = function(element, url) {
    var control, is_image, parser, _i, _len;
    if (url == null) url = "";
    if (__indexOf.call(_active_elements, element) >= 0) return;
    if (__indexOf.call(_ignore_list, element) >= 0) {
      _ignore_list.splice(ignore_list.indexOf(element), 1);
    }
    is_image = element instanceof root.HTMLImageElement;
    url || (url = is_image ? element.src : root.getComputedStyle(element)['background-image'].match(/url\((.+)\)/)[1]);
    for (_i = 0, _len = parsers.length; _i < _len; _i++) {
      parser = parsers[_i];
      if (parser.isValidFilename(url)) {
        control = new RetinaControl(element, parser, is_image, url);
        _active_controls.push(control);
        _active_elements.push(element);
        return true;
      }
    }
    return false;
  };
  ignore_element = function(element) {
    var index;
    if (__indexOf.call(_active_elements, element) >= 0) {
      index = _active_elements.indexOf(element);
      _active_elements.splice(index, 1);
      _active_controls.splice(index, 1);
    }
    return _ignore_list.push(element);
  };
  retina = {
    allParsers: function() {
      return parsers.slice();
    },
    addParser: add_parser,
    removeParser: remove_parser,
    clearParsers: clear_parsers,
    setParser: set_parser,
    scan: scan,
    setManualMode: set_manual_mode,
    activateElement: activate_element,
    ignoreElement: ignore_element,
    DefaultParser: DefaultParser,
    StaticParser: StaticParser
  };
  if (!(typeof RELEASE_MODE !== "undefined" && RELEASE_MODE !== null)) {
    retina._get_zoom_level = _get_zoom_level;
  }
  retina.addParser(new DefaultParser);
  root.addEventListener("load", function() {
    scan();
    return setInterval(function() {
      var control, zoom, _i, _len;
      zoom = _get_zoom_level();
      if (zoom !== _current_zoom_level) {
        _current_zoom_level = zoom;
        for (_i = 0, _len = _active_controls.length; _i < _len; _i++) {
          control = _active_controls[_i];
          control.setZoom(zoom);
        }
        return _schedule_scan(1);
      }
    }, 1000);
  });
  if ((typeof module !== "undefined" && module !== null ? module.exports : void 0) != null) {
    module.exports = retina;
  } else {
    this.retina = retina;
  }
}).call(this);
<commit_msg>New Javascript version<commit_after>(function() {
  var DefaultParser, RetinaControl, StaticParser, activate_element, add_parser, clear_parsers, ignore_element, parsers, remove_parser, retina, root, scan, set_manual_mode, set_parser, _active_controls, _active_elements, _current_zoom_level, _get_zoom_level, _ignore_list, _is_manual_mode, _schedule_scan;
  var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __indexOf = Array.prototype.indexOf || function(item) {
    for (var i = 0, l = this.length; i < l; i++) {
      if (this[i] === item) return i;
    }
    return -1;
  };
  root = this;
  _current_zoom_level = 1;
  _is_manual_mode = false;
  _ignore_list = [];
  _active_elements = [];
  _active_controls = [];
  parsers = [];
  DefaultParser = (function() {
    function DefaultParser() {}
    DefaultParser.prototype._pattern = /([\.\-_][0-9])?@(1x)?\.[a-z]+$/i;
    DefaultParser.prototype.isValidFilename = function(filename) {
      return !!filename.match(this._pattern);
    };
    DefaultParser.prototype.zoomLevelsForFilename = function(filename) {
      var i, match, max, _results;
      match = filename.match(this._pattern);
      max = match[1] ? parseInt(match[1].slice(1), 10) : 2;
      _results = [];
      for (i = 1; 1 <= max ? i <= max : i >= max; 1 <= max ? i++ : i--) {
        _results.push(Math.pow(2, i - 1));
      }
      return _results;
    };
    DefaultParser.prototype.filenameForZoom = function(baseFilename, zoom) {
      var match;
      if (zoom === 1) {
        return baseFilename;
      } else {
        match = baseFilename.match(/(.+)@(.*?)\.([a-z]+)$/i);
        return match[1] + "@" + zoom + "x." + match[3];
      }
    };
    return DefaultParser;
  })();
  StaticParser = (function() {
    function StaticParser(conf) {
      this.conf = conf != null ? conf : [];
    }
    StaticParser.prototype._confForFilename = function(filename) {
      var conf, _i, _len, _ref;
      _ref = this.conf;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        conf = _ref[_i];
        if (typeof conf === "string") {
          conf = [conf];
        }
        if (filename.match(new RegExp("" + conf[0] + "$"))) {
          return conf;
        }
      }
      return null;
    };
    StaticParser.prototype.isValidFilename = function(filename) {
      return !!this._confForFilename(filename);
    };
    StaticParser.prototype.zoomLevelsForFilename = function(filename) {
      var conf, i, max, _results;
      conf = this._confForFilename(filename);
      max = conf.length > 1 ? typeof conf[1] === "number" ? conf[1] : conf.length : 2;
      _results = [];
      for (i = 1; 1 <= max ? i <= max : i >= max; 1 <= max ? i++ : i--) {
        _results.push(Math.pow(2, i - 1));
      }
      return _results;
    };
    StaticParser.prototype.filenameForZoom = function(baseFilename, zoom) {
      var conf, filename, parts, zoom_sfx;
      conf = this._confForFilename(baseFilename);
      filename = conf[0];
      if (conf.length === 1 || conf.length > 1 && typeof conf[1] === "number") {
        if (zoom === 1) {
          return baseFilename;
        } else {
          parts = baseFilename.match(/(.+?)(@)?([0-9]+x)?\.([a-z]+$)/i);
          zoom_sfx = zoom === 1 ? "" : "@" + zoom + "x";
          return "" + parts[1] + zoom_sfx + "." + parts[4];
        }
      } else {
        return conf[zoom - 1];
      }
    };
    return StaticParser;
  })();
  RetinaControl = (function() {
    function RetinaControl(element, parser, is_image, url) {
      var init_size;
      this.element = element;
      this.parser = parser;
      this.is_image = is_image;
      this.url = url;
      this.complete = 0;
      this.width = 0;
      this.height = 0;
      this.zoom = 1;
      this.setImagePath(this.url);
      init_size = __bind(function(width, height) {
        this.width = width;
        this.height = height;
        return this.setZoom(_current_zoom_level);
      }, this);
      if (this.is_image && this.element.complete) {
        init_size(this.element.naturalWidth, this.element.naturalHeight);
      } else {
        this.cachePath(this.url, init_size);
      }
    }
    RetinaControl.prototype.setZoom = function(zoom) {
      var bgwidth, l, level, levels, match, path, _i, _len;
      if (this.is_image) {
        zoom *= this.element.offsetWidth / this.width;
      } else {
        bgwidth = root.getComputedStyle(this.element, null)['background-size'].split(" ")[0];
        if (match = bgwidth.match(/(.+)(px|%)$/)) {
          if (match[2] === "px") {
            zoom *= (parseFloat(match[1])) / this.width;
          } else {
            zoom *= (parseFloat(match[1])) / 100 * this.element.offsetWidth / this.width;
          }
        }
      }
      levels = this.parser.zoomLevelsForFilename(this.url);
      level = levels.slice(-1)[0];
      for (_i = 0, _len = levels.length; _i < _len; _i++) {
        l = levels[_i];
        if (l >= zoom && l < level) {
          level = l;
        }
      }
      if (level === this.zoom) {
        return;
      }
      path = this.parser.filenameForZoom(this.url, level);
      this.cachePath(path, __bind(function() {
        var _base, _base2, _base3;
        if (this.is_image) {
          if (!((this.element.getAttribute("width")) || (this.element.getAttribute("height")))) {
            (_base = this.element.style)['width'] || (_base['width'] = "" + this.width + "px");
            (_base2 = this.element.style)['height'] || (_base2['height'] = "" + this.height + "px");
          }
        } else {
          (_base3 = this.element.style)['backgroundSize'] || (_base3['backgroundSize'] = "" + this.width + "px " + this.height + "px");
        }
        return this.setImagePath(path);
      }, this));
      return this.zoom = level;
    };
    RetinaControl.prototype.release = function() {
      return this.setZoom(1);
    };
    RetinaControl.prototype.setImagePath = function(url) {
      var tmp_bgsize;
      if (this.is_image) {
        return this.element.src = url;
      } else {
        tmp_bgsize = root.getComputedStyle(this.element, null)['background-size'];
        this.element.style['backgroundImage'] = "url(" + url + ")";
        if (tmp_bgsize !== "auto auto" && !root.navigator.userAgent.match(/Chrome/)) {
          return this.element.style['backgroundSize'] = tmp_bgsize;
        }
      }
    };
    RetinaControl.prototype.cachePath = function(url, callback) {
      var img, _ref;
      if ((_ref = this.cached) == null) {
        this.cached = {};
      }
      if (url in this.cached) {
        return callback(this.cached[url]);
      }
      img = new Image;
      img.addEventListener("load", __bind(function() {
        this.cached[url] = [img.naturalWidth, img.naturalHeight];
        return callback.apply(null, this.cached[url]);
      }, this));
      return img.src = url;
    };
    return RetinaControl;
  })();
  _get_zoom_level = function() {
    var screenWidth, userAgent, _ref, _ref2;
    userAgent = (_ref = root.navigator) != null ? _ref.userAgent : void 0;
    if (root.window && userAgent.match(/Webkit/i)) {
      return (userAgent.match(/Mobile/i) ? (screenWidth = (_ref2 = root.orientation) === 0 || _ref2 === 180 ? root.screen.width : root.screen.height, root.devicePixelRatio ? screenWidth *= root.devicePixelRatio : void 0) : root.document.width) / root.window.innerWidth;
    } else {
      return 1;
    }
  };
  add_parser = function(parser) {
    var func, _i, _len, _ref;
    _ref = "isValidFilename zoomLevelsForFilename filenameForZoom".split(" ");
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      func = _ref[_i];
      if (typeof parser[func] !== "function") {
        throw "Invalid parser object. No method " + func + " found.";
      }
    }
    return parsers.push(parser);
  };
  remove_parser = function(parser) {
    var index;
    if (__indexOf.call(parsers, parser) >= 0) {
      index = parsers.indexOf(parser);
      return parsers.splice(index, 1);
    }
  };
  clear_parsers = function() {
    while (parsers.length) {
      remove_parser(parsers[0]);
    }
  };
  set_parser = function(parser) {
    if (parsers.length !== 1 || parsers[0] !== parser) {
      clear_parsers();
      return add_parser(parser);
    }
  };
  _schedule_scan = (function() {
    var next;
    next = 0;
    return function(delay) {
      if (delay == null) {
        delay = 4000;
      }
      if (next) {
        root.clearTimeout(next);
      }
      if (delay >= 0 && !_is_manual_mode) {
        return next = root.setTimeout(scan, delay);
      }
    };
  })();
  scan = (function() {
    var walker;
    walker = null;
    return function(reset) {
      var count, element;
      if (reset == null) {
        reset = true;
      }
      if (walker == null) {
        walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
          acceptNode: function(node) {
            if (node.tagName === "IMG" && node.getAttribute("src") || root.getComputedStyle(node)['background-image'] !== "none") {
              return NodeFilter.FILTER_ACCEPT;
            } else {
              return NodeFilter.FILTER_SKIP;
            }
          }
        }, false);
      }
      if (reset) {
        walker.currentNode = document.body;
      }
      count = 0;
      while (element = walker.nextNode()) {
        if (__indexOf.call(_ignore_list, element) >= 0) {
          continue;
        }
        if (__indexOf.call(_active_elements, element) < 0) {
          activate_element(element);
        }
        if (++count > 50) {
          return setTimeout((function() {
            return scan(false);
          }), 50);
        }
      }
      return _schedule_scan();
    };
  })();
  set_manual_mode = function(manual) {
    if (manual == null) {
      manual = true;
    }
    _is_manual_mode = !!manual;
    return _schedule_scan();
  };
  activate_element = function(element, url) {
    var control, is_image, parser, _i, _len;
    if (url == null) {
      url = "";
    }
    if (__indexOf.call(_active_elements, element) >= 0) {
      return;
    }
    if (__indexOf.call(_ignore_list, element) >= 0) {
      _ignore_list.splice(ignore_list.indexOf(element), 1);
    }
    is_image = element instanceof root.HTMLImageElement;
    url || (url = is_image ? element.src : root.getComputedStyle(element)['background-image'].match(/url\((.+)\)/)[1]);
    for (_i = 0, _len = parsers.length; _i < _len; _i++) {
      parser = parsers[_i];
      if (parser.isValidFilename(url)) {
        control = new RetinaControl(element, parser, is_image, url);
        _active_controls.push(control);
        _active_elements.push(element);
        return true;
      }
    }
    return false;
  };
  ignore_element = function(element) {
    var index;
    if (__indexOf.call(_active_elements, element) >= 0) {
      index = _active_elements.indexOf(element);
      _active_elements.splice(index, 1);
      _active_controls.splice(index, 1);
    }
    return _ignore_list.push(element);
  };
  retina = {
    allParsers: function() {
      return parsers.slice();
    },
    addParser: add_parser,
    removeParser: remove_parser,
    clearParsers: clear_parsers,
    setParser: set_parser,
    scan: scan,
    setManualMode: set_manual_mode,
    activateElement: activate_element,
    ignoreElement: ignore_element,
    DefaultParser: DefaultParser,
    StaticParser: StaticParser
  };
  if (!(typeof RELEASE_MODE !== "undefined" && RELEASE_MODE !== null)) {
    retina._get_zoom_level = _get_zoom_level;
  }
  retina.addParser(new DefaultParser);
  root.addEventListener("load", function() {
    scan();
    return setInterval(function() {
      var control, zoom, _i, _len;
      zoom = _get_zoom_level();
      if (zoom !== _current_zoom_level) {
        _current_zoom_level = zoom;
        for (_i = 0, _len = _active_controls.length; _i < _len; _i++) {
          control = _active_controls[_i];
          control.setZoom(zoom);
        }
        return _schedule_scan(1);
      }
    }, 1000);
  });
  if ((typeof module !== "undefined" && module !== null ? module.exports : void 0) != null) {
    module.exports = retina;
  } else {
    this.retina = retina;
  }
}).call(this);
<|endoftext|>