Fully end to end encrypted anonymous chat program. Server only stores public key lookup for users and the encrypted messages. No credentials are transfered to the server, but kept in local browser storage. This allows 100% safe chatting. https://safechat.ch
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
4.4 KiB

/*!
* Stylus - Unit
* Copyright (c) Automattic <developer.wordpress.com>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node')
, nodes = require('./');
/**
* Unit conversion table.
*/
var FACTOR_TABLE = {
'mm': {val: 1, label: 'mm'},
'cm': {val: 10, label: 'mm'},
'in': {val: 25.4, label: 'mm'},
'pt': {val: 25.4/72, label: 'mm'},
'ms': {val: 1, label: 'ms'},
's': {val: 1000, label: 'ms'},
'Hz': {val: 1, label: 'Hz'},
'kHz': {val: 1000, label: 'Hz'}
};
/**
* Initialize a new `Unit` with the given `val` and unit `type`
* such as "px", "pt", "in", etc.
*
* @param {String} val
* @param {String} type
* @api public
*/
var Unit = module.exports = function Unit(val, type){
Node.call(this);
this.val = val;
this.type = type;
};
/**
* Inherit from `Node.prototype`.
*/
Unit.prototype.__proto__ = Node.prototype;
/**
* Return Boolean based on the unit value.
*
* @return {Boolean}
* @api public
*/
Unit.prototype.toBoolean = function(){
return nodes.Boolean(this.type
? true
: this.val);
};
/**
* Return unit string.
*
* @return {String}
* @api public
*/
Unit.prototype.toString = function(){
return this.val + (this.type || '');
};
/**
* Return a clone of this node.
*
* @return {Node}
* @api public
*/
Unit.prototype.clone = function(){
var clone = new Unit(this.val, this.type);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
/**
* Return a JSON representation of this node.
*
* @return {Object}
* @api public
*/
Unit.prototype.toJSON = function(){
return {
__type: 'Unit',
val: this.val,
type: this.type,
lineno: this.lineno,
column: this.column,
filename: this.filename
};
};
/**
* Operate on `right` with the given `op`.
*
* @param {String} op
* @param {Node} right
* @return {Node}
* @api public
*/
Unit.prototype.operate = function(op, right){
var type = this.type || right.first.type;
// swap color
if ('rgba' == right.nodeName || 'hsla' == right.nodeName) {
return right.operate(op, this);
}
// operate
if (this.shouldCoerce(op)) {
right = right.first;
// percentages
if ('%' != this.type && ('-' == op || '+' == op) && '%' == right.type) {
right = new Unit(this.val * (right.val / 100), '%');
} else {
right = this.coerce(right);
}
switch (op) {
case '-':
return new Unit(this.val - right.val, type);
case '+':
// keyframes interpolation
type = type || (right.type == '%' && right.type);
return new Unit(this.val + right.val, type);
case '/':
return new Unit(this.val / right.val, type);
case '*':
return new Unit(this.val * right.val, type);
case '%':
return new Unit(this.val % right.val, type);
case '**':
return new Unit(Math.pow(this.val, right.val), type);
case '..':
case '...':
var start = this.val
, end = right.val
, expr = new nodes.Expression
, inclusive = '..' == op;
if (start < end) {
do {
expr.push(new nodes.Unit(start));
} while (inclusive ? ++start <= end : ++start < end);
} else {
do {
expr.push(new nodes.Unit(start));
} while (inclusive ? --start >= end : --start > end);
}
return expr;
}
}
return Node.prototype.operate.call(this, op, right);
};
/**
* Coerce `other` unit to the same type as `this` unit.
*
* Supports:
*
* mm -> cm | in
* cm -> mm | in
* in -> mm | cm
*
* ms -> s
* s -> ms
*
* Hz -> kHz
* kHz -> Hz
*
* @param {Unit} other
* @return {Unit}
* @api public
*/
Unit.prototype.coerce = function(other){
if ('unit' == other.nodeName) {
var a = this
, b = other
, factorA = FACTOR_TABLE[a.type]
, factorB = FACTOR_TABLE[b.type];
if (factorA && factorB && (factorA.label == factorB.label)) {
var bVal = b.val * (factorB.val / factorA.val);
return new nodes.Unit(bVal, a.type);
} else {
return new nodes.Unit(b.val, a.type);
}
} else if ('string' == other.nodeName) {
// keyframes interpolation
if ('%' == other.val) return new nodes.Unit(0, '%');
var val = parseFloat(other.val);
if (isNaN(val)) Node.prototype.coerce.call(this, other);
return new nodes.Unit(val);
} else {
return Node.prototype.coerce.call(this, other);
}
};