maxilo-vue
Version:
maxilo web framework.
1,473 lines (1,266 loc) • 310 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object') module.exports = factory();else if (typeof define === 'function' && define.amd) define([], factory);else if (typeof exports === 'object') exports["Mock"] = factory();else root["Mock"] = factory();
})(this, function () {
return (
/******/
function (modules) {
// webpackBootstrap
/******/
// The module cache
/******/
var installedModules = {};
/******/
// The require function
/******/
function __webpack_require__(moduleId) {
/******/
// Check if module is in cache
/******/
if (installedModules[moduleId])
/******/
return installedModules[moduleId].exports;
/******/
// Create a new module (and put it into the cache)
/******/
var module = installedModules[moduleId] = {
/******/
exports: {},
/******/
id: moduleId,
/******/
loaded: false
/******/
};
/******/
// Execute the module function
/******/
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
// Flag the module as loaded
/******/
module.loaded = true;
/******/
// Return the exports of the module
/******/
return module.exports;
/******/
}
/******/
// expose the modules object (__webpack_modules__)
/******/
__webpack_require__.m = modules;
/******/
// expose the module cache
/******/
__webpack_require__.c = installedModules;
/******/
// __webpack_public_path__
/******/
__webpack_require__.p = "";
/******/
// Load entry module and return exports
/******/
return __webpack_require__(0);
/******/
}(
/************************************************************************/
/******/
[
/* 0 */
/***/
function (module, exports, __webpack_require__) {
/* global require, module, window */
var Handler = __webpack_require__(1);
var Util = __webpack_require__(3);
var Random = __webpack_require__(5);
var RE = __webpack_require__(20);
var toJSONSchema = __webpack_require__(23);
var valid = __webpack_require__(25);
var XHR;
if (typeof window !== 'undefined') XHR = __webpack_require__(27);
/*!
Mock - 模拟请求 & 模拟数据
https://github.com/nuysoft/Mock
墨智 mozhi.gyy@taobao.com nuysoft@gmail.com
*/
var Mock = {
Handler: Handler,
Random: Random,
Util: Util,
XHR: XHR,
RE: RE,
toJSONSchema: toJSONSchema,
valid: valid,
heredoc: Util.heredoc,
setup: function (settings) {
return XHR.setup(settings);
},
_mocked: {}
};
Mock.version = '1.0.1-beta3'; // 避免循环依赖
if (XHR) XHR.Mock = Mock;
/*
* Mock.mock( template )
* Mock.mock( function() )
* Mock.mock( rurl, template )
* Mock.mock( rurl, function(options) )
* Mock.mock( rurl, rtype, template )
* Mock.mock( rurl, rtype, function(options) )
根据数据模板生成模拟数据。
*/
Mock.mock = function (
rurl,
rtype,
template,
title = false,
check = null) {
// Mock.mock(template)
if (arguments.length === 1) {
return Handler.gen(rurl);
} // Mock.mock(rurl, template)
if (arguments.length === 2) {
template = rtype;
rtype = undefined;
} // 拦截 XHR
if (XHR) window.XMLHttpRequest = XHR;
Mock._mocked[rurl + (rtype || '')] = {
rurl: rurl,
rtype: rtype,
template: template,
title,
check
};
return Mock;
};
module.exports = Mock;
/***/
},
/* 1 */
/***/
function (module, exports, __webpack_require__) {
/*
## Handler
处理数据模板。
* Handler.gen( template, name?, context? )
入口方法。
* Data Template Definition, DTD
处理数据模板定义。
* Handler.array( options )
* Handler.object( options )
* Handler.number( options )
* Handler.boolean( options )
* Handler.string( options )
* Handler.function( options )
* Handler.regexp( options )
处理路径(相对和绝对)。
* Handler.getValueByKeyPath( key, options )
* Data Placeholder Definition, DPD
处理数据占位符定义
* Handler.placeholder( placeholder, context, templateContext, options )
*/
var Constant = __webpack_require__(2);
var Util = __webpack_require__(3);
var Parser = __webpack_require__(4);
var Random = __webpack_require__(5);
var RE = __webpack_require__(20);
var Handler = {
extend: Util.extend
/*
template 属性值(即数据模板)
name 属性名
context 数据上下文,生成后的数据
templateContext 模板上下文,
Handle.gen(template, name, options)
context
currentContext, templateCurrentContext,
path, templatePath
root, templateRoot
*/
};
Handler.gen = function (template, name, context) {
/* jshint -W041 */
name = name == undefined ? '' : name + '';
context = context || {};
context = {
// 当前访问路径,只有属性名,不包括生成规则
path: context.path || [Constant.GUID],
templatePath: context.templatePath || [Constant.GUID++],
// 最终属性值的上下文
currentContext: context.currentContext,
// 属性值模板的上下文
templateCurrentContext: context.templateCurrentContext || template,
// 最终值的根
root: context.root || context.currentContext,
// 模板的根
templateRoot: context.templateRoot || context.templateCurrentContext || template // console.log('path:', context.path.join('.'), template)
};
var rule = Parser.parse(name);
var type = Util.type(template);
var data;
if (Handler[type]) {
data = Handler[type]({
// 属性值类型
type: type,
// 属性值模板
template: template,
// 属性名 + 生成规则
name: name,
// 属性名
parsedName: name ? name.replace(Constant.RE_KEY, '$1') : name,
// 解析后的生成规则
rule: rule,
// 相关上下文
context: context
});
if (!context.root) context.root = data;
return data;
}
return template;
};
Handler.extend({
array: function (options) {
var result = [],
i,
ii; // 'name|1': []
// 'name|count': []
// 'name|min-max': []
if (options.template.length === 0) return result; // 'arr': [{ 'email': '@EMAIL' }, { 'email': '@EMAIL' }]
if (!options.rule.parameters) {
for (i = 0; i < options.template.length; i++) {
options.context.path.push(i);
options.context.templatePath.push(i);
result.push(Handler.gen(options.template[i], i, {
path: options.context.path,
templatePath: options.context.templatePath,
currentContext: result,
templateCurrentContext: options.template,
root: options.context.root || result,
templateRoot: options.context.templateRoot || options.template
}));
options.context.path.pop();
options.context.templatePath.pop();
}
} else {
// 'method|1': ['GET', 'POST', 'HEAD', 'DELETE']
if (options.rule.min === 1 && options.rule.max === undefined) {
// fix #17
options.context.path.push(options.name);
options.context.templatePath.push(options.name);
result = Random.pick(Handler.gen(options.template, undefined, {
path: options.context.path,
templatePath: options.context.templatePath,
currentContext: result,
templateCurrentContext: options.template,
root: options.context.root || result,
templateRoot: options.context.templateRoot || options.template
}));
options.context.path.pop();
options.context.templatePath.pop();
} else {
// 'data|+1': [{}, {}]
if (options.rule.parameters[2]) {
options.template.__order_index = options.template.__order_index || 0;
options.context.path.push(options.name);
options.context.templatePath.push(options.name);
result = Handler.gen(options.template, undefined, {
path: options.context.path,
templatePath: options.context.templatePath,
currentContext: result,
templateCurrentContext: options.template,
root: options.context.root || result,
templateRoot: options.context.templateRoot || options.template
})[options.template.__order_index % options.template.length];
options.template.__order_index += +options.rule.parameters[2];
options.context.path.pop();
options.context.templatePath.pop();
} else {
// 'data|1-10': [{}]
for (i = 0; i < options.rule.count; i++) {
// 'data|1-10': [{}, {}]
for (ii = 0; ii < options.template.length; ii++) {
options.context.path.push(result.length);
options.context.templatePath.push(ii);
result.push(Handler.gen(options.template[ii], result.length, {
path: options.context.path,
templatePath: options.context.templatePath,
currentContext: result,
templateCurrentContext: options.template,
root: options.context.root || result,
templateRoot: options.context.templateRoot || options.template
}));
options.context.path.pop();
options.context.templatePath.pop();
}
}
}
}
}
return result;
},
object: function (options) {
var result = {},
keys,
fnKeys,
key,
parsedKey,
inc,
i; // 'obj|min-max': {}
/* jshint -W041 */
if (options.rule.min != undefined) {
keys = Util.keys(options.template);
keys = Random.shuffle(keys);
keys = keys.slice(0, options.rule.count);
for (i = 0; i < keys.length; i++) {
key = keys[i];
parsedKey = key.replace(Constant.RE_KEY, '$1');
options.context.path.push(parsedKey);
options.context.templatePath.push(key);
result[parsedKey] = Handler.gen(options.template[key], key, {
path: options.context.path,
templatePath: options.context.templatePath,
currentContext: result,
templateCurrentContext: options.template,
root: options.context.root || result,
templateRoot: options.context.templateRoot || options.template
});
options.context.path.pop();
options.context.templatePath.pop();
}
} else {
// 'obj': {}
keys = [];
fnKeys = []; // #25 改变了非函数属性的顺序,查找起来不方便
for (key in options.template) {
(typeof options.template[key] === 'function' ? fnKeys : keys).push(key);
}
keys = keys.concat(fnKeys);
/*
会改变非函数属性的顺序
keys = Util.keys(options.template)
keys.sort(function(a, b) {
var afn = typeof options.template[a] === 'function'
var bfn = typeof options.template[b] === 'function'
if (afn === bfn) return 0
if (afn && !bfn) return 1
if (!afn && bfn) return -1
})
*/
for (i = 0; i < keys.length; i++) {
key = keys[i];
parsedKey = key.replace(Constant.RE_KEY, '$1');
options.context.path.push(parsedKey);
options.context.templatePath.push(key);
result[parsedKey] = Handler.gen(options.template[key], key, {
path: options.context.path,
templatePath: options.context.templatePath,
currentContext: result,
templateCurrentContext: options.template,
root: options.context.root || result,
templateRoot: options.context.templateRoot || options.template
});
options.context.path.pop();
options.context.templatePath.pop(); // 'id|+1': 1
inc = key.match(Constant.RE_KEY);
if (inc && inc[2] && Util.type(options.template[key]) === 'number') {
options.template[key] += parseInt(inc[2], 10);
}
}
}
return result;
},
number: function (options) {
var result, parts;
if (options.rule.decimal) {
// float
options.template += '';
parts = options.template.split('.'); // 'float1|.1-10': 10,
// 'float2|1-100.1-10': 1,
// 'float3|999.1-10': 1,
// 'float4|.3-10': 123.123,
parts[0] = options.rule.range ? options.rule.count : parts[0];
parts[1] = (parts[1] || '').slice(0, options.rule.dcount);
while (parts[1].length < options.rule.dcount) {
parts[1] += // 最后一位不能为 0:如果最后一位为 0,会被 JS 引擎忽略掉。
parts[1].length < options.rule.dcount - 1 ? Random.character('number') : Random.character('123456789');
}
result = parseFloat(parts.join('.'), 10);
} else {
// integer
// 'grade1|1-100': 1,
result = options.rule.range && !options.rule.parameters[2] ? options.rule.count : options.template;
}
return result;
},
boolean: function (options) {
var result; // 'prop|multiple': false, 当前值是相反值的概率倍数
// 'prop|probability-probability': false, 当前值与相反值的概率
result = options.rule.parameters ? Random.bool(options.rule.min, options.rule.max, options.template) : options.template;
return result;
},
string: function (options) {
var result = '',
i,
placeholders,
ph,
phed;
if (options.template.length) {
// 'foo': '★',
/* jshint -W041 */
if (options.rule.count == undefined) {
result += options.template;
} // 'star|1-5': '★',
for (i = 0; i < options.rule.count; i++) {
result += options.template;
} // 'email|1-10': '@EMAIL, ',
placeholders = result.match(Constant.RE_PLACEHOLDER) || []; // A-Z_0-9 > \w_
for (i = 0; i < placeholders.length; i++) {
ph = placeholders[i]; // 遇到转义斜杠,不需要解析占位符
if (/^\\/.test(ph)) {
placeholders.splice(i--, 1);
continue;
}
phed = Handler.placeholder(ph, options.context.currentContext, options.context.templateCurrentContext, options); // 只有一个占位符,并且没有其他字符
if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) {
//
result = phed;
break;
if (Util.isNumeric(phed)) {
result = parseFloat(phed, 10);
break;
}
if (/^(true|false)$/.test(phed)) {
result = phed === 'true' ? true : phed === 'false' ? false : phed; // 已经是布尔值
break;
}
}
result = result.replace(ph, phed);
}
} else {
// 'ASCII|1-10': '',
// 'ASCII': '',
result = options.rule.range ? Random.string(options.rule.count) : options.template;
}
return result;
},
'function': function (options) {
// ( context, options )
return options.template.call(options.context.currentContext, options);
},
'regexp': function (options) {
var source = ''; // 'name': /regexp/,
/* jshint -W041 */
if (options.rule.count == undefined) {
source += options.template.source; // regexp.source
} // 'name|1-5': /regexp/,
for (var i = 0; i < options.rule.count; i++) {
source += options.template.source;
}
return RE.Handler.gen(RE.Parser.parse(source));
}
});
Handler.extend({
_all: function () {
var re = {};
for (var key in Random) re[key.toLowerCase()] = key;
return re;
},
// 处理占位符,转换为最终值
placeholder: function (placeholder, obj, templateContext, options) {
// console.log(options.context.path)
// 1 key, 2 params
Constant.RE_PLACEHOLDER.exec('');
var parts = Constant.RE_PLACEHOLDER.exec(placeholder),
key = parts && parts[1],
lkey = key && key.toLowerCase(),
okey = this._all()[lkey],
params = parts && parts[2] || '';
var pathParts = this.splitPathToArray(key); // 解析占位符的参数
try {
// 1. 尝试保持参数的类型
/*
#24 [Window Firefox 30.0 引用 占位符 抛错](https://github.com/nuysoft/Mock/issues/24)
[BX9056: 各浏览器下 window.eval 方法的执行上下文存在差异](http://www.w3help.org/zh-cn/causes/BX9056)
应该属于 Window Firefox 30.0 的 BUG
*/
/* jshint -W061 */
params = eval('(function(){ return [].splice.call(arguments, 0 ) })(' + params + ')');
} catch (error) {
// 2. 如果失败,只能解析为字符串
// console.error(error)
// if (error instanceof ReferenceError) params = parts[2].split(/,\s*/);
// else throw error
params = parts[2].split(/,\s*/);
} // 占位符优先引用数据模板中的属性
if (obj && key in obj) return obj[key]; // @index @key
// if (Constant.RE_INDEX.test(key)) return +options.name
// if (Constant.RE_KEY.test(key)) return options.name
// 绝对路径 or 相对路径
if (key.charAt(0) === '/' || pathParts.length > 1) return this.getValueByKeyPath(key, options); // 递归引用数据模板中的属性
if (templateContext && typeof templateContext === 'object' && key in templateContext && placeholder !== templateContext[key] // fix #15 避免自己依赖自己
) {
// 先计算被引用的属性值
templateContext[key] = Handler.gen(templateContext[key], key, {
currentContext: obj,
templateCurrentContext: templateContext
});
return templateContext[key];
} // 如果未找到,则原样返回
if (!(key in Random) && !(lkey in Random) && !(okey in Random)) return placeholder; // 递归解析参数中的占位符
for (var i = 0; i < params.length; i++) {
Constant.RE_PLACEHOLDER.exec('');
if (Constant.RE_PLACEHOLDER.test(params[i])) {
params[i] = Handler.placeholder(params[i], obj, templateContext, options);
}
}
var handle = Random[key] || Random[lkey] || Random[okey];
switch (Util.type(handle)) {
case 'array':
// 自动从数组中取一个,例如 @areas
return Random.pick(handle);
case 'function':
// 执行占位符方法(大多数情况)
handle.options = options;
var re = handle.apply(Random, params);
if (re === undefined) re = ''; // 因为是在字符串中,所以默认为空字符串。
delete handle.options;
return re;
}
},
getValueByKeyPath: function (key, options) {
var originalKey = key;
var keyPathParts = this.splitPathToArray(key);
var absolutePathParts = []; // 绝对路径
if (key.charAt(0) === '/') {
absolutePathParts = [options.context.path[0]].concat(this.normalizePath(keyPathParts));
} else {
// 相对路径
if (keyPathParts.length > 1) {
absolutePathParts = options.context.path.slice(0);
absolutePathParts.pop();
absolutePathParts = this.normalizePath(absolutePathParts.concat(keyPathParts));
}
}
key = keyPathParts[keyPathParts.length - 1];
var currentContext = options.context.root;
var templateCurrentContext = options.context.templateRoot;
for (var i = 1; i < absolutePathParts.length - 1; i++) {
currentContext = currentContext[absolutePathParts[i]];
templateCurrentContext = templateCurrentContext[absolutePathParts[i]];
} // 引用的值已经计算好
if (currentContext && key in currentContext) return currentContext[key]; // 尚未计算,递归引用数据模板中的属性
if (templateCurrentContext && typeof templateCurrentContext === 'object' && key in templateCurrentContext && originalKey !== templateCurrentContext[key] // fix #15 避免自己依赖自己
) {
// 先计算被引用的属性值
templateCurrentContext[key] = Handler.gen(templateCurrentContext[key], key, {
currentContext: currentContext,
templateCurrentContext: templateCurrentContext
});
return templateCurrentContext[key];
}
},
// https://github.com/kissyteam/kissy/blob/master/src/path/src/path.js
normalizePath: function (pathParts) {
var newPathParts = [];
for (var i = 0; i < pathParts.length; i++) {
switch (pathParts[i]) {
case '..':
newPathParts.pop();
break;
case '.':
break;
default:
newPathParts.push(pathParts[i]);
}
}
return newPathParts;
},
splitPathToArray: function (path) {
var parts = path.split(/\/+/);
if (!parts[parts.length - 1]) parts = parts.slice(0, -1);
if (!parts[0]) parts = parts.slice(1);
return parts;
}
});
module.exports = Handler;
/***/
},
/* 2 */
/***/
function (module, exports) {
/*
## Constant
常量集合。
*/
/*
RE_KEY
'name|min-max': value
'name|count': value
'name|min-max.dmin-dmax': value
'name|min-max.dcount': value
'name|count.dmin-dmax': value
'name|count.dcount': value
'name|+step': value
1 name, 2 step, 3 range [ min, max ], 4 drange [ dmin, dmax ]
RE_PLACEHOLDER
placeholder(*)
[正则查看工具](http://www.regexper.com/)
#26 生成规则 支持 负数,例如 number|-100-100
*/
module.exports = {
GUID: 1,
RE_KEY: /(.+)\|(?:\+(\d+)|([\+\-]?\d+-?[\+\-]?\d*)?(?:\.(\d+-?\d*))?)/,
RE_RANGE: /([\+\-]?\d+)-?([\+\-]?\d+)?/,
RE_PLACEHOLDER: /\\*@([^@#%&()\?\s]+)(?:\((.*?)\))?/g // /\\*@([^@#%&()\?\s\/\.]+)(?:\((.*?)\))?/g
// RE_INDEX: /^index$/,
// RE_KEY: /^key$/
/***/
};
},
/* 3 */
/***/
function (module, exports) {
/*
## Utilities
*/
var Util = {};
Util.extend = function extend() {
var target = arguments[0] || {},
i = 1,
length = arguments.length,
options,
name,
src,
copy,
clone;
if (length === 1) {
target = this;
i = 0;
}
for (; i < length; i++) {
options = arguments[i];
if (!options) continue;
for (name in options) {
src = target[name];
copy = options[name];
if (target === copy) continue;
if (copy === undefined) continue;
if (Util.isArray(copy) || Util.isObject(copy)) {
if (Util.isArray(copy)) clone = src && Util.isArray(src) ? src : [];
if (Util.isObject(copy)) clone = src && Util.isObject(src) ? src : {};
target[name] = Util.extend(clone, copy);
} else {
target[name] = copy;
}
}
}
return target;
};
Util.each = function each(obj, iterator, context) {
var i, key;
if (this.type(obj) === 'number') {
for (i = 0; i < obj; i++) {
iterator(i, i);
}
} else if (obj.length === +obj.length) {
for (i = 0; i < obj.length; i++) {
if (iterator.call(context, obj[i], i, obj) === false) break;
}
} else {
for (key in obj) {
if (iterator.call(context, obj[key], key, obj) === false) break;
}
}
};
Util.type = function type(obj) {
return obj === null || obj === undefined ? String(obj) : Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1].toLowerCase();
};
Util.each('String Object Array RegExp Function'.split(' '), function (value) {
Util['is' + value] = function (obj) {
return Util.type(obj) === value.toLowerCase();
};
});
Util.isObjectOrArray = function (value) {
return Util.isObject(value) || Util.isArray(value);
};
Util.isNumeric = function (value) {
return !isNaN(parseFloat(value)) && isFinite(value);
};
Util.keys = function (obj) {
var keys = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) keys.push(key);
}
return keys;
};
Util.values = function (obj) {
var values = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) values.push(obj[key]);
}
return values;
};
/*
### Mock.heredoc(fn)
* Mock.heredoc(fn)
以直观、安全的方式书写(多行)HTML 模板。
**使用示例**如下所示:
var tpl = Mock.heredoc(function() {
/*!
{{email}}{{age}}
<!-- Mock {
email: '@EMAIL',
age: '@INT(1,100)'
} -->
*\/
})
**相关阅读**
* [Creating multiline strings in JavaScript](http://stackoverflow.com/questions/805107/creating-multiline-strings-in-javascript)、
*/
Util.heredoc = function heredoc(fn) {
// 1. 移除起始的 function(){ /*!
// 2. 移除末尾的 */ }
// 3. 移除起始和末尾的空格
return fn.toString().replace(/^[^\/]+\/\*!?/, '').replace(/\*\/[^\/]+$/, '').replace(/^[\s\xA0]+/, '').replace(/[\s\xA0]+$/, ''); // .trim()
};
Util.noop = function () {};
module.exports = Util;
/***/
},
/* 4 */
/***/
function (module, exports, __webpack_require__) {
/*
## Parser
解析数据模板(属性名部分)。
* Parser.parse( name )
```json
{
parameters: [ name, inc, range, decimal ],
rnage: [ min , max ],
min: min,
max: max,
count : count,
decimal: decimal,
dmin: dmin,
dmax: dmax,
dcount: dcount
}
```
*/
var Constant = __webpack_require__(2);
var Random = __webpack_require__(5);
/* jshint -W041 */
module.exports = {
parse: function (name) {
name = name == undefined ? '' : name + '';
var parameters = (name || '').match(Constant.RE_KEY);
var range = parameters && parameters[3] && parameters[3].match(Constant.RE_RANGE);
var min = range && range[1] && parseInt(range[1], 10); // || 1
var max = range && range[2] && parseInt(range[2], 10); // || 1
// repeat || min-max || 1
// var count = range ? !range[2] && parseInt(range[1], 10) || Random.integer(min, max) : 1
var count = range ? !range[2] ? parseInt(range[1], 10) : Random.integer(min, max) : undefined;
var decimal = parameters && parameters[4] && parameters[4].match(Constant.RE_RANGE);
var dmin = decimal && decimal[1] && parseInt(decimal[1], 10); // || 0,
var dmax = decimal && decimal[2] && parseInt(decimal[2], 10); // || 0,
// int || dmin-dmax || 0
var dcount = decimal ? !decimal[2] && parseInt(decimal[1], 10) || Random.integer(dmin, dmax) : undefined;
var result = {
// 1 name, 2 inc, 3 range, 4 decimal
parameters: parameters,
// 1 min, 2 max
range: range,
min: min,
max: max,
// min-max
count: count,
// 是否有 decimal
decimal: decimal,
dmin: dmin,
dmax: dmax,
// dmin-dimax
dcount: dcount
};
for (var r in result) {
if (result[r] != undefined) return result;
}
return {};
}
/***/
};
},
/* 5 */
/***/
function (module, exports, __webpack_require__) {
/*
## Mock.Random
工具类,用于生成各种随机数据。
*/
var Util = __webpack_require__(3);
var Random = {
extend: Util.extend
};
Random.extend(__webpack_require__(6));
Random.extend(__webpack_require__(7));
Random.extend(__webpack_require__(8));
Random.extend(__webpack_require__(10));
Random.extend(__webpack_require__(13));
Random.extend(__webpack_require__(15));
Random.extend(__webpack_require__(16));
Random.extend(__webpack_require__(17));
Random.extend(__webpack_require__(14));
Random.extend(__webpack_require__(19));
module.exports = Random;
/***/
},
/* 6 */
/***/
function (module, exports) {
/*
## Basics
*/
module.exports = {
// 返回一个随机的布尔值。
boolean: function (min, max, cur) {
if (cur !== undefined) {
min = typeof min !== 'undefined' && !isNaN(min) ? parseInt(min, 10) : 1;
max = typeof max !== 'undefined' && !isNaN(max) ? parseInt(max, 10) : 1;
return Math.random() > 1.0 / (min + max) * min ? !cur : cur;
}
return Math.random() >= 0.5;
},
bool: function (min, max, cur) {
return this.boolean(min, max, cur);
},
// 返回一个随机的自然数(大于等于 0 的整数)。
natural: function (min, max) {
min = typeof min !== 'undefined' ? parseInt(min, 10) : 0;
max = typeof max !== 'undefined' ? parseInt(max, 10) : 9007199254740992; // 2^53
return Math.round(Math.random() * (max - min)) + min;
},
// 返回一个随机的整数。
integer: function (min, max) {
min = typeof min !== 'undefined' ? parseInt(min, 10) : -9007199254740992;
max = typeof max !== 'undefined' ? parseInt(max, 10) : 9007199254740992; // 2^53
return Math.round(Math.random() * (max - min)) + min;
},
int: function (min, max) {
return this.integer(min, max);
},
// 返回一个随机的浮点数。
float: function (min, max, dmin, dmax) {
dmin = dmin === undefined ? 0 : dmin;
dmin = Math.max(Math.min(dmin, 17), 0);
dmax = dmax === undefined ? 17 : dmax;
dmax = Math.max(Math.min(dmax, 17), 0);
var ret = this.integer(min, max) + '.';
for (var i = 0, dcount = this.natural(dmin, dmax); i < dcount; i++) {
ret += // 最后一位不能为 0:如果最后一位为 0,会被 JS 引擎忽略掉。
i < dcount - 1 ? this.character('number') : this.character('123456789');
}
return parseFloat(ret, 10);
},
// 返回一个随机字符。
character: function (pool) {
var pools = {
lower: 'abcdefghijklmnopqrstuvwxyz',
upper: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
number: '0123456789',
symbol: '!@#$%^&*()[]'
};
pools.alpha = pools.lower + pools.upper;
pools['undefined'] = pools.lower + pools.upper + pools.number + pools.symbol;
pool = pools[('' + pool).toLowerCase()] || pool;
return pool.charAt(this.natural(0, pool.length - 1));
},
char: function (pool) {
return this.character(pool);
},
// 返回一个随机字符串。
string: function (pool, min, max) {
var len;
switch (arguments.length) {
case 0:
// ()
len = this.natural(3, 7);
break;
case 1:
// ( length )
len = pool;
pool = undefined;
break;
case 2:
// ( pool, length )
if (typeof arguments[0] === 'string') {
len = min;
} else {
// ( min, max )
len = this.natural(pool, min);
pool = undefined;
}
break;
case 3:
len = this.natural(min, max);
break;
}
var text = '';
for (var i = 0; i < len; i++) {
text += this.character(pool);
}
return text;
},
str: function ()
/*pool, min, max*/
{
return this.string.apply(this, arguments);
},
// 返回一个整型数组。
range: function (start, stop, step) {
// range( stop )
if (arguments.length <= 1) {
stop = start || 0;
start = 0;
} // range( start, stop )
step = arguments[2] || 1;
start = +start;
stop = +stop;
step = +step;
var len = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(len);
while (idx < len) {
range[idx++] = start;
start += step;
}
return range;
}
/***/
};
},
/* 7 */
/***/
function (module, exports) {
/*
## Date
*/
var patternLetters = {
yyyy: 'getFullYear',
yy: function (date) {
return ('' + date.getFullYear()).slice(2);
},
y: 'yy',
MM: function (date) {
var m = date.getMonth() + 1;
return m < 10 ? '0' + m : m;
},
M: function (date) {
return date.getMonth() + 1;
},
dd: function (date) {
var d = date.getDate();
return d < 10 ? '0' + d : d;
},
d: 'getDate',
HH: function (date) {
var h = date.getHours();
return h < 10 ? '0' + h : h;
},
H: 'getHours',
hh: function (date) {
var h = date.getHours() % 12;
return h < 10 ? '0' + h : h;
},
h: function (date) {
return date.getHours() % 12;
},
mm: function (date) {
var m = date.getMinutes();
return m < 10 ? '0' + m : m;
},
m: 'getMinutes',
ss: function (date) {
var s = date.getSeconds();
return s < 10 ? '0' + s : s;
},
s: 'getSeconds',
SS: function (date) {
var ms = date.getMilliseconds();
return ms < 10 && '00' + ms || ms < 100 && '0' + ms || ms;
},
S: 'getMilliseconds',
A: function (date) {
return date.getHours() < 12 ? 'AM' : 'PM';
},
a: function (date) {
return date.getHours() < 12 ? 'am' : 'pm';
},
T: 'getTime'
};
module.exports = {
// 日期占位符集合。
_patternLetters: patternLetters,
// 日期占位符正则。
_rformat: new RegExp(function () {
var re = [];
for (var i in patternLetters) re.push(i);
return '(' + re.join('|') + ')';
}(), 'g'),
// 格式化日期。
_formatDate: function (date, format) {
return format.replace(this._rformat, function creatNewSubString($0, flag) {
return typeof patternLetters[flag] === 'function' ? patternLetters[flag](date) : patternLetters[flag] in patternLetters ? creatNewSubString($0, patternLetters[flag]) : date[patternLetters[flag]]();
});
},
// 生成一个随机的 Date 对象。
_randomDate: function (min, max) {
// min, max
min = min === undefined ? new Date(0) : min;
max = max === undefined ? new Date() : max;
return new Date(Math.random() * (max.getTime() - min.getTime()));
},
// 返回一个随机的日期字符串。
date: function (format) {
format = format || 'yyyy-MM-dd';
return this._formatDate(this._randomDate(), format);
},
// 返回一个随机的时间字符串。
time: function (format) {
format = format || 'HH:mm:ss';
return this._formatDate(this._randomDate(), format);
},
// 返回一个随机的日期和时间字符串。
datetime: function (format) {
format = format || 'yyyy-MM-dd HH:mm:ss';
return this._formatDate(this._randomDate(), format);
},
// 返回当前的日期和时间字符串。
now: function (unit, format) {
// now(unit) now(format)
if (arguments.length === 1) {
// now(format)
if (!/year|month|day|hour|minute|second|week/.test(unit)) {
format = unit;
unit = '';
}
}
unit = (unit || '').toLowerCase();
format = format || 'yyyy-MM-dd HH:mm:ss';
var date = new Date();
/* jshint -W086 */
// 参考自 http://momentjs.cn/docs/#/manipulating/start-of/
switch (unit) {
case 'year':
date.setMonth(0);
case 'month':
date.setDate(1);
case 'week':
case 'day':
date.setHours(0);
case 'hour':
date.setMinutes(0);
case 'minute':
date.setSeconds(0);
case 'second':
date.setMilliseconds(0);
}
switch (unit) {
case 'week':
date.setDate(date.getDate() - date.getDay());
}
return this._formatDate(date, format);
}
/***/
};
},
/* 8 */
/***/
function (module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */
(function (module) {
/* global document */
/*
## Image
*/
module.exports = {
// 常见的广告宽高
_adSize: ['300x250', '250x250', '240x400', '336x280', '180x150', '720x300', '468x60', '234x60', '88x31', '120x90', '120x60', '120x240', '125x125', '728x90', '160x600', '120x600', '300x600'],
// 常见的屏幕宽高
_screenSize: ['320x200', '320x240', '640x480', '800x480', '800x480', '1024x600', '1024x768', '1280x800', '1440x900', '1920x1200', '2560x1600'],
// 常见的视频宽高
_videoSize: ['720x480', '768x576', '1280x720', '1920x1080'],
/*
生成一个随机的图片地址。
替代图片源
http://fpoimg.com/
参考自
http://rensanning.iteye.com/blog/1933310
http://code.tutsplus.com/articles/the-top-8-placeholders-for-web-designers--net-19485
*/
image: function (size, background, foreground, format, text) {
// Random.image( size, background, foreground, text )
if (arguments.length === 4) {
text = format;
format = undefined;
} // Random.image( size, background, text )
if (arguments.length === 3) {
text = foreground;
foreground = undefined;
} // Random.image()
if (!size) size = this.pick(this._adSize);
if (background && ~background.indexOf('#')) background = background.slice(1);
if (foreground && ~foreground.indexOf('#')) foreground = foreground.slice(1); // http://dummyimage.com/600x400/cc00cc/470047.png&text=hello
return 'http://dummyimage.com/' + size + (background ? '/' + background : '') + (foreground ? '/' + foreground : '') + (format ? '.' + format : '') + (text ? '&text=' + text : '');
},
img: function () {
return this.image.apply(this, arguments);
},
/*
BrandColors
http://brandcolors.net/
A collection of major brand color codes curated by Galen Gidman.
大牌公司的颜色集合
// 获取品牌和颜色
$('h2').each(function(index, item){
item = $(item)
console.log('\'' + item.text() + '\'', ':', '\'' + item.next().text() + '\'', ',')
})
*/
_brandColors: {
'4ormat': '#fb0a2a',
'500px': '#02adea',
'About.me (blue)': '#00405d',
'About.me (yellow)': '#ffcc33',
'Addvocate': '#ff6138',
'Adobe': '#ff0000',
'Aim': '#fcd20b',
'Amazon': '#e47911',
'Android': '#a4c639',
'Angie\'s List': '#7fbb00',
'AOL': '#0060a3',
'Atlassian': '#003366',
'Behance': '#053eff',
'Big Cartel': '#97b538',
'bitly': '#ee6123',
'Blogger': '#fc4f08',
'Boeing': '#0039a6',
'Booking.com': '#003580',
'Carbonmade': '#613854',
'Cheddar': '#ff7243',
'Code School': '#3d4944',
'Delicious': '#205cc0',
'Dell': '#3287c1',
'Designmoo': '#e54a4f',
'Deviantart': '#4e6252',
'Designer News': '#2d72da',
'Devour': '#fd0001',
'DEWALT': '#febd17',
'Disqus (blue)': '#59a3fc',
'Disqus (orange)': '#db7132',
'Dribbble': '#ea4c89',
'Dropbox': '#3d9ae8',
'Drupal': '#0c76ab',
'Dunked': '#2a323a',
'eBay': '#89c507',
'Ember': '#f05e1b',
'Engadget': '#00bdf6',
'Envato': '#528036',
'Etsy': '#eb6d20',
'Evernote': '#5ba525',
'Fab.com': '#dd0017',
'Facebook': '#3b5998',
'Firefox': '#e66000',
'Flickr (blue)': '#0063dc',
'Flickr (pink)': '#ff0084',
'Forrst': '#5b9a68',
'Foursquare': '#25a0ca',
'Garmin': '#007cc3',
'GetGlue': '#2d75a2',
'Gimmebar': '#f70078',
'GitHub': '#171515',
'Google Blue': '#0140ca',
'Google Green': '#16a61e',
'Google Red': '#dd1812',
'Google Yellow': '#fcca03',
'Google+': '#dd4b39',
'Grooveshark': '#f77f00',
'Groupon': '#82b548',
'Hacker News': '#ff6600',
'HelloWallet': '#0085ca',
'Heroku (light)': '#c7c5e6',
'Heroku (dark)': '#6567a5',
'HootSuite': '#003366',
'Houzz': '#73ba37',
'HTML5': '#ec6231',
'IKEA': '#ffcc33',
'IMDb': '#f3ce13',
'Instagram': '#3f729b',
'Intel': '#0071c5',
'Intuit': '#365ebf',
'Kickstarter': '#76cc1e',
'kippt': '#e03500',
'Kodery': '#00af81',
'LastFM': '#c3000d',
'LinkedIn': '#0e76a8',
'Livestream': '#cf0005',
'Lumo': '#576396',
'Mixpanel': '#a086d3',
'Meetup': '#e51937',
'Nokia': '#183693',
'NVIDIA': '#76b900',
'Opera': '#cc0f16',
'Path': '#e41f11',
'PayPal (dark)': '#1e477a',
'PayPal (light)': '#3b7bbf',
'Pinboard': '#0000e6',
'Pinterest': '#c8232c',
'PlayStation': '#665cbe',
'Pocket': '#ee4056',
'Prezi': '#318bff',
'Pusha': '#0f71b4',
'Quora': '#a82400',
'QUOTE.fm': '#66ceff',
'Rdio': '#008fd5',
'Readability': '#9c0000',
'Red Hat': '#cc0000',
'Resource': '#7eb400',
'Rockpack': '#0ba6ab',
'Roon': '#62b0d9',
'RSS': '#ee802f',
'Salesforce': '#1798c1',
'Samsung': '#0c4da2',
'Shopify': '#96bf48',
'Skype': '#00aff0',
'Snagajob': '#f47a20',
'Softonic': '#008ace',
'SoundCloud': '#ff7700',
'Space Box': '#f86960',
'Spotify': '#81b71a',
'Sprint': '#fee100',
'Squarespace': '#121212',
'StackOverflow': '#ef8236',
'Staples': '#cc0000',
'Status Chart': '#d7584f',
'Stripe': '#008cdd',
'StudyBlue': '#00afe1',
'StumbleUpon': '#f74425',
'T-Mobile': '#ea0a8e',
'Technorati': '#40a800',
'The Next Web': '#ef4423',
'Treehouse': '#5cb868',
'Trulia': '#5eab1f',
'Tumblr': '#34526f',
'Twitch.tv': '#6441a5',
'Twitter': '#00acee',
'TYPO3': '#ff8700',
'Ubuntu': '#dd4814',
'Ustream': '#3388ff',
'Verizon': '#ef1d1d',
'Vimeo': '#86c9ef',
'Vine': '#00a478',
'Virb': '#06afd8',
'Virgin Media': '#cc0000',
'Wooga': '#5b009c',
'WordPress (blue)': '#21759b',
'WordPress (orange)': '#d54e21',
'WordPress (grey)': '#464646',
'Wunderl