3 |
4 |
5 |
6 |
7 |
8 |
63 |
64 |
67 |
--------------------------------------------------------------------------------
/src/views/Loading.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
17 |
18 |
78 |
--------------------------------------------------------------------------------
/src/components/MediaItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
64 |
65 |
85 |
--------------------------------------------------------------------------------
/src/util.js:
--------------------------------------------------------------------------------
1 | import sha1 from 'sha1'
2 | import fetchJsonp from 'fetch-jsonp'
3 |
4 | const Util = {
5 | url: 'http://cs.nankebuluo.com/',
6 | //url: 'http://agent.nankebuluo.com/',
7 | cdnUrl: 'http://cdn.nankebuluo.com',
8 | imageUrl: 'http://cdn.nankebuluo.com/static/image',
9 | mediaUrl: 'http://cdn.nankebuluo.com/static/media',
10 | appid: 'wx8eec0e3d43f5362b',
11 | makeSignature(timestamp, nonce) {
12 | const token = 'swan'
13 |
14 | let arr = [token, timestamp, nonce].sort((a, b) => (a + '') > (b + '') ? 1 : -1)
15 | //alert(arr)
16 | return sha1(arr.join(''))
17 | },
18 |
19 | getParam(name){
20 | var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
21 | var r = window.location.search.substr(1).match(reg);
22 | if (r != null) return unescape(r[2]);
23 | return null;
24 | },
25 |
26 | fetchJsonp(url, data, options){
27 | const timestamp = (+new Date() + '').slice(0, 10)
28 | const nonce = parseInt(Math.random() * 100) + ''
29 | const signature = this.makeSignature(timestamp, nonce)
30 |
31 | const _data = {...data, timestamp, nonce, signature}
32 |
33 | let _url = url
34 | let tem = []
35 | for (let x in _data) {
36 | tem.push(x + '=' + _data[x])
37 | }
38 | _url += '?' + tem.join('&')
39 |
40 | return fetchJsonp(_url, options)
41 | },
42 |
43 | login(func){
44 | const redirectUri = this.url + 'htdocs/index.html'
45 | const code = this.getParam('code')
46 | if (code) {
47 | const data = {
48 | code
49 | }
50 | fun.getJSON(this.url + 'Login.php?callback=?', data, json => {
51 | func(json);
52 | if (json.ret == 0) {
53 | } else {
54 | location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + this.appid + '&redirect_uri=' + encodeURIComponent(redirectUri) + '&response_type=code&scope=snsapi_userinfo&state=STAT'
55 | }
56 | })
57 | } else {
58 | location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + this.appid + '&redirect_uri=' + encodeURIComponent(redirectUri) + '&response_type=code&scope=snsapi_base&state=STAT'
59 | }
60 | }
61 | }
62 |
63 | export default Util
64 |
--------------------------------------------------------------------------------
/src/components/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
35 |
36 |
78 |
--------------------------------------------------------------------------------
/test/unit/karma.conf.js:
--------------------------------------------------------------------------------
1 | // This is a karma config file. For more details see
2 | // http://karma-runner.github.io/0.13/config/configuration-file.html
3 | // we are also using it with karma-webpack
4 | // https://github.com/webpack/karma-webpack
5 |
6 | var path = require('path')
7 | var merge = require('webpack-merge')
8 | var baseConfig = require('../../build/webpack.base.conf')
9 | var utils = require('../../build/utils')
10 | var webpack = require('webpack')
11 | var projectRoot = path.resolve(__dirname, '../../')
12 |
13 | var webpackConfig = merge(baseConfig, {
14 | // use inline sourcemap for karma-sourcemap-loader
15 | module: {
16 | loaders: utils.styleLoaders()
17 | },
18 | devtool: '#inline-source-map',
19 | vue: {
20 | loaders: {
21 | js: 'isparta'
22 | }
23 | },
24 | plugins: [
25 | new webpack.DefinePlugin({
26 | 'process.env': require('../../config/test.env')
27 | })
28 | ]
29 | })
30 |
31 | // no need for app entry during tests
32 | delete webpackConfig.entry
33 |
34 | // make sure isparta loader is applied before eslint
35 | webpackConfig.module.preLoaders = webpackConfig.module.preLoaders || []
36 | webpackConfig.module.preLoaders.unshift({
37 | test: /\.js$/,
38 | loader: 'isparta',
39 | include: path.resolve(projectRoot, 'src')
40 | })
41 |
42 | // only apply babel for test files when using isparta
43 | webpackConfig.module.loaders.some(function (loader, i) {
44 | if (loader.loader === 'babel') {
45 | loader.include = path.resolve(projectRoot, 'test/unit')
46 | return true
47 | }
48 | })
49 |
50 | module.exports = function (config) {
51 | config.set({
52 | // to run in additional browsers:
53 | // 1. install corresponding karma launcher
54 | // http://karma-runner.github.io/0.13/config/browsers.html
55 | // 2. add it to the `browsers` array below.
56 | browsers: ['PhantomJS'],
57 | frameworks: ['mocha', 'sinon-chai'],
58 | reporters: ['spec', 'coverage'],
59 | files: ['./index.js'],
60 | preprocessors: {
61 | './index.js': ['webpack', 'sourcemap']
62 | },
63 | webpack: webpackConfig,
64 | webpackMiddleware: {
65 | noInfo: true
66 | },
67 | coverageReporter: {
68 | dir: './coverage',
69 | reporters: [
70 | { type: 'lcov', subdir: '.' },
71 | { type: 'text-summary' }
72 | ]
73 | }
74 | })
75 | }
76 |
--------------------------------------------------------------------------------
/src/assets/js/zepto/fx_methods.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | ;(function($, undefined){
6 | var document = window.document, docElem = document.documentElement,
7 | origShow = $.fn.show, origHide = $.fn.hide, origToggle = $.fn.toggle
8 |
9 | function anim(el, speed, opacity, scale, callback) {
10 | if (typeof speed == 'function' && !callback) callback = speed, speed = undefined
11 | var props = { opacity: opacity }
12 | if (scale) {
13 | props.scale = scale
14 | el.css($.fx.cssPrefix + 'transform-origin', '0 0')
15 | }
16 | return el.animate(props, speed, null, callback)
17 | }
18 |
19 | function hide(el, speed, scale, callback) {
20 | return anim(el, speed, 0, scale, function(){
21 | origHide.call($(this))
22 | callback && callback.call(this)
23 | })
24 | }
25 |
26 | $.fn.show = function(speed, callback) {
27 | origShow.call(this)
28 | if (speed === undefined) speed = 0
29 | else this.css('opacity', 0)
30 | return anim(this, speed, 1, '1,1', callback)
31 | }
32 |
33 | $.fn.hide = function(speed, callback) {
34 | if (speed === undefined) return origHide.call(this)
35 | else return hide(this, speed, '0,0', callback)
36 | }
37 |
38 | $.fn.toggle = function(speed, callback) {
39 | if (speed === undefined || typeof speed == 'boolean')
40 | return origToggle.call(this, speed)
41 | else return this.each(function(){
42 | var el = $(this)
43 | el[el.css('display') == 'none' ? 'show' : 'hide'](speed, callback)
44 | })
45 | }
46 |
47 | $.fn.fadeTo = function(speed, opacity, callback) {
48 | return anim(this, speed, opacity, null, callback)
49 | }
50 |
51 | $.fn.fadeIn = function(speed, callback) {
52 | var target = this.css('opacity')
53 | if (target > 0) this.css('opacity', 0)
54 | else target = 1
55 | return origShow.call(this).fadeTo(speed, target, callback)
56 | }
57 |
58 | $.fn.fadeOut = function(speed, callback) {
59 | return hide(this, speed, null, callback)
60 | }
61 |
62 | $.fn.fadeToggle = function(speed, callback) {
63 | return this.each(function(){
64 | var el = $(this)
65 | el[
66 | (el.css('opacity') == 0 || el.css('display') == 'none') ? 'fadeIn' : 'fadeOut'
67 | ](speed, callback)
68 | })
69 | }
70 |
71 | })(Zepto)
72 |
--------------------------------------------------------------------------------
/src/views/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
23 |
24 |
48 |
49 |
91 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 | import Router from 'vue-router'
4 | import VueTouch from 'vue-touch'
5 |
6 | import 'whatwg-fetch'
7 | import 'babel-polyfill'
8 |
9 | import Util from './util'
10 | //import 'moment'
11 |
12 | //import './assets/js/qq-wechat-emotion-parser'
13 | //import Home from './views/Home'
14 | //import Tasks from './views/ChatRoom'
15 | import List from './views/List'
16 | import Chat from './views/Chat'
17 | //import Media from './views/Media'
18 | //import User from './views/User'
19 | //import MediaManger from './views/MediaManger'
20 | // import AlertDoc from './views/AlertDoc'
21 | //import DraggableHeader from './components/DraggableHeader'
22 | //import Loading from './views/Loading'
23 | // import Login from './views/Login'
24 | /* eslint-disable no-new */
25 | // new Vue({
26 | // el: 'body',
27 | // components: { App }
28 | // })
29 | VueTouch.config.swipe = {
30 | direction: 'horizontal'
31 | };
32 |
33 | Vue.use(Router)
34 | Vue.use(VueTouch)
35 |
36 | var router = new Router()
37 | Vue.config.debug = true;
38 |
39 | router.map({
40 | '/': {
41 | component: List
42 | },
43 | //'/home': {
44 | // component: Home
45 | //},
46 | //'/tasks': {
47 | // component: Tasks
48 | //},
49 | '/list': {
50 | component: List
51 | },
52 | '/chat/:openid': {
53 | name: 'chat',
54 | component: Chat
55 | },
56 | //'/mediamanger':{
57 | // component: MediaManger
58 | //},
59 | //'/media/:mediaid/:mediatype': {
60 | // name: 'media',
61 | // component: Media
62 | //},
63 | //'/DraggableHeader' : {
64 | // component: DraggableHeader
65 | //},
66 | //'/user' : {
67 | // component: User
68 | //}
69 | // },
70 | // '/login' : {
71 | // component: Login
72 | // }
73 | })
74 |
75 | router.beforeEach(({to, from, next}) => {
76 | let toPath = to.path
77 | let fromPath = from.path
78 | console.log('to: ' + toPath + ' from: ' + fromPath);
79 | if (toPath.replace(/[^/]/g, '').length > 1 || toPath === '/mediamanger') {
80 | router.app.isIndex = false
81 | }
82 | else {
83 | let depath = toPath === '/'
84 | router.app.isIndex = depath ? 0 : 1
85 | }
86 |
87 | next()
88 | })
89 |
90 | router.afterEach(function ({to}) {
91 | console.log(`success to: ${to.path}`)
92 | })
93 |
94 | //Util.login(function (json) {
95 | // if (json.ret == 0) {
96 | // router.start(App, '#app')
97 | // } else {
98 | // console.log('not login')
99 | // }
100 | //})
101 | router.start(App, '#app')
102 |
--------------------------------------------------------------------------------
/src/components/ListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
![]()
8 |
{{istip}}
9 |
10 |
11 |
{{{ '[' + uid + '] ' + qqWechatEmotionParser(nickname) }}}
12 |
{{{ qqWechatEmotionParser(message) }}}
13 |
{{ moment(this.time*1000).format('MM.DD HH:mm') }}
14 |
15 |
16 |
17 |
18 |
75 |
112 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-chat",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "jocelyn",
6 | "private": true,
7 | "scripts": {
8 | "dev": "node build/dev-server.js",
9 | "build": "node build/build.js",
10 | "unit": "karma start test/unit/karma.conf.js --single-run",
11 | "e2e": "node test/e2e/runner.js",
12 | "test": "npm run unit && npm run e2e",
13 | "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"
14 | },
15 | "dependencies": {
16 | "babel-polyfill": "^6.13.0",
17 | "babel-runtime": "^6.0.0",
18 | "express": "^4.14.0",
19 | "fetch-ie8": "^1.4.3",
20 | "fetch-jsonp": "^1.0.1",
21 | "normalize.css": "^4.2.0",
22 | "vue": "^1.0.21",
23 | "vue-loadmore": "^0.2.4",
24 | "vue-router": "^0.7.13",
25 | "vue-touch": "^1.1.0",
26 | "whatwg-fetch": "^1.0.0"
27 | },
28 | "devDependencies": {
29 | "babel-core": "^6.0.0",
30 | "babel-loader": "^6.0.0",
31 | "babel-plugin-transform-runtime": "^6.0.0",
32 | "babel-preset-es2015": "^6.0.0",
33 | "babel-preset-stage-2": "^6.0.0",
34 | "chai": "^3.5.0",
35 | "chromedriver": "^2.21.2",
36 | "connect-history-api-fallback": "^1.1.0",
37 | "cross-spawn": "^2.1.5",
38 | "css-loader": "^0.23.0",
39 | "eslint": "^2.10.2",
40 | "eslint-config-standard": "^5.1.0",
41 | "eslint-friendly-formatter": "^2.0.5",
42 | "eslint-loader": "^1.3.0",
43 | "eslint-plugin-html": "^1.3.0",
44 | "eslint-plugin-promise": "^1.0.8",
45 | "eslint-plugin-standard": "^1.3.2",
46 | "eventsource-polyfill": "^0.9.6",
47 | "exports-loader": "^0.6.3",
48 | "express": "^4.13.3",
49 | "extract-text-webpack-plugin": "^1.0.1",
50 | "file-loader": "^0.8.4",
51 | "function-bind": "^1.0.2",
52 | "html-webpack-plugin": "^2.8.1",
53 | "http-proxy-middleware": "^0.12.0",
54 | "imports-loader": "^0.6.5",
55 | "inject-loader": "^2.0.1",
56 | "isparta-loader": "^2.0.0",
57 | "json-loader": "^0.5.4",
58 | "karma": "^0.13.15",
59 | "karma-coverage": "^0.5.5",
60 | "karma-mocha": "^0.2.2",
61 | "karma-phantomjs-launcher": "^1.0.0",
62 | "karma-sinon-chai": "^1.2.0",
63 | "karma-sourcemap-loader": "^0.3.7",
64 | "karma-spec-reporter": "0.0.24",
65 | "karma-webpack": "^1.7.0",
66 | "lolex": "^1.4.0",
67 | "mocha": "^2.4.5",
68 | "nightwatch": "^0.8.18",
69 | "ora": "^0.2.0",
70 | "phantomjs-prebuilt": "^2.1.3",
71 | "selenium-server": "2.53.0",
72 | "shelljs": "^0.6.0",
73 | "sinon": "^1.17.3",
74 | "sinon-chai": "^2.8.0",
75 | "url-loader": "^0.5.7",
76 | "vue-hot-reload-api": "^1.2.0",
77 | "vue-html-loader": "^1.0.0",
78 | "vue-loader": "^8.3.0",
79 | "vue-style-loader": "^1.0.0",
80 | "webpack": "^1.12.2",
81 | "webpack-dev-middleware": "^1.4.0",
82 | "webpack-hot-middleware": "^2.6.0",
83 | "webpack-merge": "^0.8.3"
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/assets/js/zepto/data.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | // The following code is heavily inspired by jQuery's $.fn.data()
6 |
7 | ;(function($){
8 | var data = {}, dataAttr = $.fn.data, camelize = $.camelCase,
9 | exp = $.expando = 'Zepto' + (+new Date()), emptyArray = []
10 |
11 | // Get value from node:
12 | // 1. first try key as given,
13 | // 2. then try camelized key,
14 | // 3. fall back to reading "data-*" attribute.
15 | function getData(node, name) {
16 | var id = node[exp], store = id && data[id]
17 | if (name === undefined) return store || setData(node)
18 | else {
19 | if (store) {
20 | if (name in store) return store[name]
21 | var camelName = camelize(name)
22 | if (camelName in store) return store[camelName]
23 | }
24 | return dataAttr.call($(node), name)
25 | }
26 | }
27 |
28 | // Store value under camelized key on node
29 | function setData(node, name, value) {
30 | var id = node[exp] || (node[exp] = ++$.uuid),
31 | store = data[id] || (data[id] = attributeData(node))
32 | if (name !== undefined) store[camelize(name)] = value
33 | return store
34 | }
35 |
36 | // Read all "data-*" attributes from a node
37 | function attributeData(node) {
38 | var store = {}
39 | $.each(node.attributes || emptyArray, function(i, attr){
40 | if (attr.name.indexOf('data-') == 0)
41 | store[camelize(attr.name.replace('data-', ''))] =
42 | $.zepto.deserializeValue(attr.value)
43 | })
44 | return store
45 | }
46 |
47 | $.fn.data = function(name, value) {
48 | return value === undefined ?
49 | // set multiple values via object
50 | $.isPlainObject(name) ?
51 | this.each(function(i, node){
52 | $.each(name, function(key, value){ setData(node, key, value) })
53 | }) :
54 | // get value from first element
55 | (0 in this ? getData(this[0], name) : undefined) :
56 | // set value on all elements
57 | this.each(function(){ setData(this, name, value) })
58 | }
59 |
60 | $.data = function(elem, name, value) {
61 | return $(elem).data(name, value)
62 | }
63 |
64 | $.hasData = function(elem) {
65 | var id = elem[exp], store = id && data[id]
66 | return store ? !$.isEmptyObject(store) : false
67 | }
68 |
69 | $.fn.removeData = function(names) {
70 | if (typeof names == 'string') names = names.split(/\s+/)
71 | return this.each(function(){
72 | var id = this[exp], store = id && data[id]
73 | if (store) $.each(names || store, function(key){
74 | delete store[names ? camelize(this) : key]
75 | })
76 | })
77 | }
78 |
79 | // Generate extended `remove` and `empty` functions
80 | ;['remove', 'empty'].forEach(function(methodName){
81 | var origFn = $.fn[methodName]
82 | $.fn[methodName] = function() {
83 | var elements = this.find('*')
84 | if (methodName === 'remove') elements = elements.add(this)
85 | elements.removeData()
86 | return origFn.call(this)
87 | }
88 | })
89 | })(Zepto)
90 |
--------------------------------------------------------------------------------
/src/assets/js/zepto/selector.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | ;(function($){
6 | var zepto = $.zepto, oldQsa = zepto.qsa, oldMatches = zepto.matches
7 |
8 | function visible(elem){
9 | elem = $(elem)
10 | return !!(elem.width() || elem.height()) && elem.css("display") !== "none"
11 | }
12 |
13 | // Implements a subset from:
14 | // http://api.jquery.com/category/selectors/jquery-selector-extensions/
15 | //
16 | // Each filter function receives the current index, all nodes in the
17 | // considered set, and a value if there were parentheses. The value
18 | // of `this` is the node currently being considered. The function returns the
19 | // resulting node(s), null, or undefined.
20 | //
21 | // Complex selectors are not supported:
22 | // li:has(label:contains("foo")) + li:has(label:contains("bar"))
23 | // ul.inner:first > li
24 | var filters = $.expr[':'] = {
25 | visible: function(){ if (visible(this)) return this },
26 | hidden: function(){ if (!visible(this)) return this },
27 | selected: function(){ if (this.selected) return this },
28 | checked: function(){ if (this.checked) return this },
29 | parent: function(){ return this.parentNode },
30 | first: function(idx){ if (idx === 0) return this },
31 | last: function(idx, nodes){ if (idx === nodes.length - 1) return this },
32 | eq: function(idx, _, value){ if (idx === value) return this },
33 | contains: function(idx, _, text){ if ($(this).text().indexOf(text) > -1) return this },
34 | has: function(idx, _, sel){ if (zepto.qsa(this, sel).length) return this }
35 | }
36 |
37 | var filterRe = new RegExp('(.*):(\\w+)(?:\\(([^)]+)\\))?$\\s*'),
38 | childRe = /^\s*>/,
39 | classTag = 'Zepto' + (+new Date())
40 |
41 | function process(sel, fn) {
42 | // quote the hash in `a[href^=#]` expression
43 | sel = sel.replace(/=#\]/g, '="#"]')
44 | var filter, arg, match = filterRe.exec(sel)
45 | if (match && match[2] in filters) {
46 | filter = filters[match[2]], arg = match[3]
47 | sel = match[1]
48 | if (arg) {
49 | var num = Number(arg)
50 | if (isNaN(num)) arg = arg.replace(/^["']|["']$/g, '')
51 | else arg = num
52 | }
53 | }
54 | return fn(sel, filter, arg)
55 | }
56 |
57 | zepto.qsa = function(node, selector) {
58 | return process(selector, function(sel, filter, arg){
59 | try {
60 | var taggedParent
61 | if (!sel && filter) sel = '*'
62 | else if (childRe.test(sel))
63 | // support "> *" child queries by tagging the parent node with a
64 | // unique class and prepending that classname onto the selector
65 | taggedParent = $(node).addClass(classTag), sel = '.'+classTag+' '+sel
66 |
67 | var nodes = oldQsa(node, sel)
68 | } catch(e) {
69 | console.error('error performing selector: %o', selector)
70 | throw e
71 | } finally {
72 | if (taggedParent) taggedParent.removeClass(classTag)
73 | }
74 | return !filter ? nodes :
75 | zepto.uniq($.map(nodes, function(n, i){ return filter.call(n, i, nodes, arg) }))
76 | })
77 | }
78 |
79 | zepto.matches = function(node, selector){
80 | return process(selector, function(sel, filter, arg){
81 | return (!sel || oldMatches(node, sel)) &&
82 | (!filter || filter.call(node, null, arg) === node)
83 | })
84 | }
85 | })(Zepto)
86 |
--------------------------------------------------------------------------------
/src/components/Slider.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
92 |
93 |
160 |
--------------------------------------------------------------------------------
/src/assets/js/common.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/bootstrap 6e0e0a4bd70a9133a00f"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gFAAwE,mPAAmP;AAC3T;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA","file":"common.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n \t\twhile(callbacks.length)\n \t\t\tcallbacks.shift().call(null, __webpack_require__);\n \t\tif(moreModules[0]) {\n \t\t\tinstalledModules[0] = 0;\n \t\t\treturn __webpack_require__(0);\n \t\t}\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// \"0\" means \"already loaded\"\n \t// Array means \"loading\", array contains callbacks\n \tvar installedChunks = {\n \t\t9:0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n \t\t// \"0\" is the signal for \"already loaded\"\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn callback.call(null, __webpack_require__);\n\n \t\t// an array means \"currently loading\".\n \t\tif(installedChunks[chunkId] !== undefined) {\n \t\t\tinstalledChunks[chunkId].push(callback);\n \t\t} else {\n \t\t\t// start chunk loading\n \t\t\tinstalledChunks[chunkId] = [callback];\n \t\t\tvar head = document.getElementsByTagName('head')[0];\n \t\t\tvar script = document.createElement('script');\n \t\t\tscript.type = 'text/javascript';\n \t\t\tscript.charset = 'utf-8';\n \t\t\tscript.async = true;\n\n \t\t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".build.js?\" + {\"0\":\"b6ff1d52d65888b11b0d\",\"1\":\"3291d0d99fbddf12dbb8\",\"2\":\"34da392290c0ce34f3c9\",\"3\":\"92babfeac2e38a70e686\",\"4\":\"b24151215d1762d7bad8\",\"5\":\"082a831074b8501b437e\",\"6\":\"f72c281efb37dc2354ec\",\"7\":\"a90b46366ec70cc62096\",\"8\":\"e388421d8ea3638e6764\"}[chunkId] + \"\";\n \t\t\thead.appendChild(script);\n \t\t}\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/dist/\";\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 6e0e0a4bd70a9133a00f\n **/"],"sourceRoot":""}
--------------------------------------------------------------------------------
/src/assets/js/zepto/detect.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | ;(function($){
6 | function detect(ua, platform){
7 | var os = this.os = {}, browser = this.browser = {},
8 | webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/),
9 | android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
10 | osx = !!ua.match(/\(Macintosh\; Intel /),
11 | ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
12 | ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
13 | iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
14 | webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
15 | win = /Win\d{2}|Windows/.test(platform),
16 | wp = ua.match(/Windows Phone ([\d.]+)/),
17 | touchpad = webos && ua.match(/TouchPad/),
18 | kindle = ua.match(/Kindle\/([\d.]+)/),
19 | silk = ua.match(/Silk\/([\d._]+)/),
20 | blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/),
21 | bb10 = ua.match(/(BB10).*Version\/([\d.]+)/),
22 | rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/),
23 | playbook = ua.match(/PlayBook/),
24 | chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/),
25 | firefox = ua.match(/Firefox\/([\d.]+)/),
26 | firefoxos = ua.match(/\((?:Mobile|Tablet); rv:([\d.]+)\).*Firefox\/[\d.]+/),
27 | ie = ua.match(/MSIE\s([\d.]+)/) || ua.match(/Trident\/[\d](?=[^\?]+).*rv:([0-9.].)/),
28 | webview = !chrome && ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),
29 | safari = webview || ua.match(/Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/)
30 |
31 | // Todo: clean this up with a better OS/browser seperation:
32 | // - discern (more) between multiple browsers on android
33 | // - decide if kindle fire in silk mode is android or not
34 | // - Firefox on Android doesn't specify the Android version
35 | // - possibly devide in os, device and browser hashes
36 |
37 | if (browser.webkit = !!webkit) browser.version = webkit[1]
38 |
39 | if (android) os.android = true, os.version = android[2]
40 | if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.')
41 | if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.')
42 | if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null
43 | if (wp) os.wp = true, os.version = wp[1]
44 | if (webos) os.webos = true, os.version = webos[2]
45 | if (touchpad) os.touchpad = true
46 | if (blackberry) os.blackberry = true, os.version = blackberry[2]
47 | if (bb10) os.bb10 = true, os.version = bb10[2]
48 | if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2]
49 | if (playbook) browser.playbook = true
50 | if (kindle) os.kindle = true, os.version = kindle[1]
51 | if (silk) browser.silk = true, browser.version = silk[1]
52 | if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true
53 | if (chrome) browser.chrome = true, browser.version = chrome[1]
54 | if (firefox) browser.firefox = true, browser.version = firefox[1]
55 | if (firefoxos) os.firefoxos = true, os.version = firefoxos[1]
56 | if (ie) browser.ie = true, browser.version = ie[1]
57 | if (safari && (osx || os.ios || win)) {
58 | browser.safari = true
59 | if (!os.ios) browser.version = safari[1]
60 | }
61 | if (webview) browser.webview = true
62 |
63 | os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
64 | (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)))
65 | os.phone = !!(!os.tablet && !os.ipod && (android || iphone || webos || blackberry || bb10 ||
66 | (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
67 | (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))))
68 | }
69 |
70 | detect.call($, navigator.userAgent, navigator.platform)
71 | // make available to unit tests
72 | $.__detect = detect
73 |
74 | })(Zepto)
75 |
--------------------------------------------------------------------------------
/src/views/MediaManger.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
9 |
10 |
23 |
24 |
25 |
26 |
65 |
66 |
153 |
--------------------------------------------------------------------------------
/src/components/DraggableHeader.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
83 |
84 |
130 |
--------------------------------------------------------------------------------
/src/views/Media.vue:
--------------------------------------------------------------------------------
1 |
2 |
25 |
26 |
27 |
28 |
95 |
96 |
158 |
159 |
--------------------------------------------------------------------------------
/src/assets/js/zepto/deferred.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 | //
5 | // Some code (c) 2005, 2013 jQuery Foundation, Inc. and other contributors
6 |
7 | ;(function($){
8 | var slice = Array.prototype.slice
9 |
10 | function Deferred(func) {
11 | var tuples = [
12 | // action, add listener, listener list, final state
13 | [ "resolve", "done", $.Callbacks({once:1, memory:1}), "resolved" ],
14 | [ "reject", "fail", $.Callbacks({once:1, memory:1}), "rejected" ],
15 | [ "notify", "progress", $.Callbacks({memory:1}) ]
16 | ],
17 | state = "pending",
18 | promise = {
19 | state: function() {
20 | return state
21 | },
22 | always: function() {
23 | deferred.done(arguments).fail(arguments)
24 | return this
25 | },
26 | then: function(/* fnDone [, fnFailed [, fnProgress]] */) {
27 | var fns = arguments
28 | return Deferred(function(defer){
29 | $.each(tuples, function(i, tuple){
30 | var fn = $.isFunction(fns[i]) && fns[i]
31 | deferred[tuple[1]](function(){
32 | var returned = fn && fn.apply(this, arguments)
33 | if (returned && $.isFunction(returned.promise)) {
34 | returned.promise()
35 | .done(defer.resolve)
36 | .fail(defer.reject)
37 | .progress(defer.notify)
38 | } else {
39 | var context = this === promise ? defer.promise() : this,
40 | values = fn ? [returned] : arguments
41 | defer[tuple[0] + "With"](context, values)
42 | }
43 | })
44 | })
45 | fns = null
46 | }).promise()
47 | },
48 |
49 | promise: function(obj) {
50 | return obj != null ? $.extend( obj, promise ) : promise
51 | }
52 | },
53 | deferred = {}
54 |
55 | $.each(tuples, function(i, tuple){
56 | var list = tuple[2],
57 | stateString = tuple[3]
58 |
59 | promise[tuple[1]] = list.add
60 |
61 | if (stateString) {
62 | list.add(function(){
63 | state = stateString
64 | }, tuples[i^1][2].disable, tuples[2][2].lock)
65 | }
66 |
67 | deferred[tuple[0]] = function(){
68 | deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments)
69 | return this
70 | }
71 | deferred[tuple[0] + "With"] = list.fireWith
72 | })
73 |
74 | promise.promise(deferred)
75 | if (func) func.call(deferred, deferred)
76 | return deferred
77 | }
78 |
79 | $.when = function(sub) {
80 | var resolveValues = slice.call(arguments),
81 | len = resolveValues.length,
82 | i = 0,
83 | remain = len !== 1 || (sub && $.isFunction(sub.promise)) ? len : 0,
84 | deferred = remain === 1 ? sub : Deferred(),
85 | progressValues, progressContexts, resolveContexts,
86 | updateFn = function(i, ctx, val){
87 | return function(value){
88 | ctx[i] = this
89 | val[i] = arguments.length > 1 ? slice.call(arguments) : value
90 | if (val === progressValues) {
91 | deferred.notifyWith(ctx, val)
92 | } else if (!(--remain)) {
93 | deferred.resolveWith(ctx, val)
94 | }
95 | }
96 | }
97 |
98 | if (len > 1) {
99 | progressValues = new Array(len)
100 | progressContexts = new Array(len)
101 | resolveContexts = new Array(len)
102 | for ( ; i < len; ++i ) {
103 | if (resolveValues[i] && $.isFunction(resolveValues[i].promise)) {
104 | resolveValues[i].promise()
105 | .done(updateFn(i, resolveContexts, resolveValues))
106 | .fail(deferred.reject)
107 | .progress(updateFn(i, progressContexts, progressValues))
108 | } else {
109 | --remain
110 | }
111 | }
112 | }
113 | if (!remain) deferred.resolveWith(resolveContexts, resolveValues)
114 | return deferred.promise()
115 | }
116 |
117 | $.Deferred = Deferred
118 | })(Zepto)
119 |
--------------------------------------------------------------------------------
/src/components/VideoItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
31 |
32 |
33 |
123 |
124 |
172 |
--------------------------------------------------------------------------------
/src/assets/js/zepto/callbacks.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | ;(function($){
6 | // Create a collection of callbacks to be fired in a sequence, with configurable behaviour
7 | // Option flags:
8 | // - once: Callbacks fired at most one time.
9 | // - memory: Remember the most recent context and arguments
10 | // - stopOnFalse: Cease iterating over callback list
11 | // - unique: Permit adding at most one instance of the same callback
12 | $.Callbacks = function(options) {
13 | options = $.extend({}, options)
14 |
15 | var memory, // Last fire value (for non-forgettable lists)
16 | fired, // Flag to know if list was already fired
17 | firing, // Flag to know if list is currently firing
18 | firingStart, // First callback to fire (used internally by add and fireWith)
19 | firingLength, // End of the loop when firing
20 | firingIndex, // Index of currently firing callback (modified by remove if needed)
21 | list = [], // Actual callback list
22 | stack = !options.once && [], // Stack of fire calls for repeatable lists
23 | fire = function(data) {
24 | memory = options.memory && data
25 | fired = true
26 | firingIndex = firingStart || 0
27 | firingStart = 0
28 | firingLength = list.length
29 | firing = true
30 | for ( ; list && firingIndex < firingLength ; ++firingIndex ) {
31 | if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {
32 | memory = false
33 | break
34 | }
35 | }
36 | firing = false
37 | if (list) {
38 | if (stack) stack.length && fire(stack.shift())
39 | else if (memory) list.length = 0
40 | else Callbacks.disable()
41 | }
42 | },
43 |
44 | Callbacks = {
45 | add: function() {
46 | if (list) {
47 | var start = list.length,
48 | add = function(args) {
49 | $.each(args, function(_, arg){
50 | if (typeof arg === "function") {
51 | if (!options.unique || !Callbacks.has(arg)) list.push(arg)
52 | }
53 | else if (arg && arg.length && typeof arg !== 'string') add(arg)
54 | })
55 | }
56 | add(arguments)
57 | if (firing) firingLength = list.length
58 | else if (memory) {
59 | firingStart = start
60 | fire(memory)
61 | }
62 | }
63 | return this
64 | },
65 | remove: function() {
66 | if (list) {
67 | $.each(arguments, function(_, arg){
68 | var index
69 | while ((index = $.inArray(arg, list, index)) > -1) {
70 | list.splice(index, 1)
71 | // Handle firing indexes
72 | if (firing) {
73 | if (index <= firingLength) --firingLength
74 | if (index <= firingIndex) --firingIndex
75 | }
76 | }
77 | })
78 | }
79 | return this
80 | },
81 | has: function(fn) {
82 | return !!(list && (fn ? $.inArray(fn, list) > -1 : list.length))
83 | },
84 | empty: function() {
85 | firingLength = list.length = 0
86 | return this
87 | },
88 | disable: function() {
89 | list = stack = memory = undefined
90 | return this
91 | },
92 | disabled: function() {
93 | return !list
94 | },
95 | lock: function() {
96 | stack = undefined
97 | if (!memory) Callbacks.disable()
98 | return this
99 | },
100 | locked: function() {
101 | return !stack
102 | },
103 | fireWith: function(context, args) {
104 | if (list && (!fired || stack)) {
105 | args = args || []
106 | args = [context, args.slice ? args.slice() : args]
107 | if (firing) stack.push(args)
108 | else fire(args)
109 | }
110 | return this
111 | },
112 | fire: function() {
113 | return Callbacks.fireWith(this, arguments)
114 | },
115 | fired: function() {
116 | return !!fired
117 | }
118 | }
119 |
120 | return Callbacks
121 | }
122 | })(Zepto)
123 |
--------------------------------------------------------------------------------
/src/components/InputBox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
20 |
21 |
22 |
92 |
93 |
201 |
--------------------------------------------------------------------------------
/src/assets/js/zepto/fx.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | ;(function($, undefined){
6 | var prefix = '', eventPrefix,
7 | vendors = { Webkit: 'webkit', Moz: '', O: 'o' },
8 | testEl = document.createElement('div'),
9 | supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,
10 | transform,
11 | transitionProperty, transitionDuration, transitionTiming, transitionDelay,
12 | animationName, animationDuration, animationTiming, animationDelay,
13 | cssReset = {}
14 |
15 | function dasherize(str) { return str.replace(/([A-Z])/g, '-$1').toLowerCase() }
16 | function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : name.toLowerCase() }
17 |
18 | if (testEl.style.transform === undefined) $.each(vendors, function(vendor, event){
19 | if (testEl.style[vendor + 'TransitionProperty'] !== undefined) {
20 | prefix = '-' + vendor.toLowerCase() + '-'
21 | eventPrefix = event
22 | return false
23 | }
24 | })
25 |
26 | transform = prefix + 'transform'
27 | cssReset[transitionProperty = prefix + 'transition-property'] =
28 | cssReset[transitionDuration = prefix + 'transition-duration'] =
29 | cssReset[transitionDelay = prefix + 'transition-delay'] =
30 | cssReset[transitionTiming = prefix + 'transition-timing-function'] =
31 | cssReset[animationName = prefix + 'animation-name'] =
32 | cssReset[animationDuration = prefix + 'animation-duration'] =
33 | cssReset[animationDelay = prefix + 'animation-delay'] =
34 | cssReset[animationTiming = prefix + 'animation-timing-function'] = ''
35 |
36 | $.fx = {
37 | off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined),
38 | speeds: { _default: 400, fast: 200, slow: 600 },
39 | cssPrefix: prefix,
40 | transitionEnd: normalizeEvent('TransitionEnd'),
41 | animationEnd: normalizeEvent('AnimationEnd')
42 | }
43 |
44 | $.fn.animate = function(properties, duration, ease, callback, delay){
45 | if ($.isFunction(duration))
46 | callback = duration, ease = undefined, duration = undefined
47 | if ($.isFunction(ease))
48 | callback = ease, ease = undefined
49 | if ($.isPlainObject(duration))
50 | ease = duration.easing, callback = duration.complete, delay = duration.delay, duration = duration.duration
51 | if (duration) duration = (typeof duration == 'number' ? duration :
52 | ($.fx.speeds[duration] || $.fx.speeds._default)) / 1000
53 | if (delay) delay = parseFloat(delay) / 1000
54 | return this.anim(properties, duration, ease, callback, delay)
55 | }
56 |
57 | $.fn.anim = function(properties, duration, ease, callback, delay){
58 | var key, cssValues = {}, cssProperties, transforms = '',
59 | that = this, wrappedCallback, endEvent = $.fx.transitionEnd,
60 | fired = false
61 |
62 | if (duration === undefined) duration = $.fx.speeds._default / 1000
63 | if (delay === undefined) delay = 0
64 | if ($.fx.off) duration = 0
65 |
66 | if (typeof properties == 'string') {
67 | // keyframe animation
68 | cssValues[animationName] = properties
69 | cssValues[animationDuration] = duration + 's'
70 | cssValues[animationDelay] = delay + 's'
71 | cssValues[animationTiming] = (ease || 'linear')
72 | endEvent = $.fx.animationEnd
73 | } else {
74 | cssProperties = []
75 | // CSS transitions
76 | for (key in properties)
77 | if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') '
78 | else cssValues[key] = properties[key], cssProperties.push(dasherize(key))
79 |
80 | if (transforms) cssValues[transform] = transforms, cssProperties.push(transform)
81 | if (duration > 0 && typeof properties === 'object') {
82 | cssValues[transitionProperty] = cssProperties.join(', ')
83 | cssValues[transitionDuration] = duration + 's'
84 | cssValues[transitionDelay] = delay + 's'
85 | cssValues[transitionTiming] = (ease || 'linear')
86 | }
87 | }
88 |
89 | wrappedCallback = function(event){
90 | if (typeof event !== 'undefined') {
91 | if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below"
92 | $(event.target).unbind(endEvent, wrappedCallback)
93 | } else
94 | $(this).unbind(endEvent, wrappedCallback) // triggered by setTimeout
95 |
96 | fired = true
97 | $(this).css(cssReset)
98 | callback && callback.call(this)
99 | }
100 | if (duration > 0){
101 | this.bind(endEvent, wrappedCallback)
102 | // transitionEnd is not always firing on older Android phones
103 | // so make sure it gets fired
104 | setTimeout(function(){
105 | if (fired) return
106 | wrappedCallback.call(that)
107 | }, ((duration + delay) * 1000) + 25)
108 | }
109 |
110 | // trigger page reflow so new elements can animate
111 | this.size() && this.get(0).clientLeft
112 |
113 | this.css(cssValues)
114 |
115 | if (duration <= 0) setTimeout(function() {
116 | that.each(function(){ wrappedCallback.call(this) })
117 | }, 0)
118 |
119 | return this
120 | }
121 |
122 | testEl = null
123 | })(Zepto)
124 |
--------------------------------------------------------------------------------
/src/assets/js/touch.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | ;(function($){
6 | var touch = {},
7 | touchTimeout, tapTimeout, swipeTimeout, longTapTimeout,
8 | longTapDelay = 750,
9 | gesture
10 |
11 | function swipeDirection(x1, x2, y1, y2) {
12 | return Math.abs(x1 - x2) >=
13 | Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
14 | }
15 |
16 | function longTap() {
17 | longTapTimeout = null
18 | if (touch.last) {
19 | touch.el.trigger('longTap')
20 | touch = {}
21 | }
22 | }
23 |
24 | function cancelLongTap() {
25 | if (longTapTimeout) clearTimeout(longTapTimeout)
26 | longTapTimeout = null
27 | }
28 |
29 | function cancelAll() {
30 | if (touchTimeout) clearTimeout(touchTimeout)
31 | if (tapTimeout) clearTimeout(tapTimeout)
32 | if (swipeTimeout) clearTimeout(swipeTimeout)
33 | if (longTapTimeout) clearTimeout(longTapTimeout)
34 | touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
35 | touch = {}
36 | }
37 |
38 | function isPrimaryTouch(event){
39 | return (event.pointerType == 'touch' ||
40 | event.pointerType == event.MSPOINTER_TYPE_TOUCH)
41 | && event.isPrimary
42 | }
43 |
44 | function isPointerEventType(e, type){
45 | return (e.type == 'pointer'+type ||
46 | e.type.toLowerCase() == 'mspointer'+type)
47 | }
48 |
49 | $(document).ready(function(){
50 | var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType
51 |
52 | if ('MSGesture' in window) {
53 | gesture = new MSGesture()
54 | gesture.target = document.body
55 | }
56 |
57 | $(document)
58 | .bind('MSGestureEnd', function(e){
59 | var swipeDirectionFromVelocity =
60 | e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null
61 | if (swipeDirectionFromVelocity) {
62 | touch.el.trigger('swipe')
63 | touch.el.trigger('swipe'+ swipeDirectionFromVelocity)
64 | }
65 | })
66 | .on('touchstart MSPointerDown pointerdown', function(e){
67 | if((_isPointerType = isPointerEventType(e, 'down')) &&
68 | !isPrimaryTouch(e)) return
69 | firstTouch = _isPointerType ? e : e.touches[0]
70 | if (e.touches && e.touches.length === 1 && touch.x2) {
71 | // Clear out touch movement data if we have it sticking around
72 | // This can occur if touchcancel doesn't fire due to preventDefault, etc.
73 | touch.x2 = undefined
74 | touch.y2 = undefined
75 | }
76 | now = Date.now()
77 | delta = now - (touch.last || now)
78 | touch.el = $('tagName' in firstTouch.target ?
79 | firstTouch.target : firstTouch.target.parentNode)
80 | touchTimeout && clearTimeout(touchTimeout)
81 | touch.x1 = firstTouch.pageX
82 | touch.y1 = firstTouch.pageY
83 | if (delta > 0 && delta <= 250) touch.isDoubleTap = true
84 | touch.last = now
85 | longTapTimeout = setTimeout(longTap, longTapDelay)
86 | // adds the current touch contact for IE gesture recognition
87 | if (gesture && _isPointerType) gesture.addPointer(e.pointerId)
88 | })
89 | .on('touchmove MSPointerMove pointermove', function(e){
90 | if((_isPointerType = isPointerEventType(e, 'move')) &&
91 | !isPrimaryTouch(e)) return
92 | firstTouch = _isPointerType ? e : e.touches[0]
93 | cancelLongTap()
94 | touch.x2 = firstTouch.pageX
95 | touch.y2 = firstTouch.pageY
96 |
97 | deltaX += Math.abs(touch.x1 - touch.x2)
98 | deltaY += Math.abs(touch.y1 - touch.y2)
99 | })
100 | .on('touchend MSPointerUp pointerup', function(e){
101 | if((_isPointerType = isPointerEventType(e, 'up')) &&
102 | !isPrimaryTouch(e)) return
103 | cancelLongTap()
104 |
105 | // swipe
106 | if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
107 | (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))
108 |
109 | swipeTimeout = setTimeout(function() {
110 | if (touch.el){
111 | touch.el.trigger('swipe')
112 | touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
113 | }
114 | touch = {}
115 | }, 0)
116 |
117 | // normal tap
118 | else if ('last' in touch)
119 | // don't fire tap when delta position changed by more than 30 pixels,
120 | // for instance when moving to a point and back to origin
121 | if (deltaX < 30 && deltaY < 30) {
122 | // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
123 | // ('tap' fires before 'scroll')
124 | tapTimeout = setTimeout(function() {
125 |
126 | // trigger universal 'tap' with the option to cancelTouch()
127 | // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
128 | var event = $.Event('tap')
129 | event.cancelTouch = cancelAll
130 | // [by paper] fix -> "TypeError: 'undefined' is not an object (evaluating 'touch.el.trigger'), when double tap
131 | if (touch.el) touch.el.trigger(event)
132 |
133 | // trigger double tap immediately
134 | if (touch.isDoubleTap) {
135 | if (touch.el) touch.el.trigger('doubleTap')
136 | touch = {}
137 | }
138 |
139 | // trigger single tap after 250ms of inactivity
140 | else {
141 | touchTimeout = setTimeout(function(){
142 | touchTimeout = null
143 | if (touch.el) touch.el.trigger('singleTap')
144 | touch = {}
145 | }, 250)
146 | }
147 | }, 0)
148 | } else {
149 | touch = {}
150 | }
151 | deltaX = deltaY = 0
152 |
153 | })
154 | // when the browser window loses focus,
155 | // for example when a modal dialog is shown,
156 | // cancel all ongoing events
157 | .on('touchcancel MSPointerCancel pointercancel', cancelAll)
158 |
159 | // scrolling the window indicates intention of the user
160 | // to scroll, not tap or swipe, so cancel all ongoing events
161 | $(window).on('scroll', cancelAll)
162 | })
163 |
164 | ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown',
165 | 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){
166 | $.fn[eventName] = function(callback){ return this.on(eventName, callback) }
167 | })
168 | })(Zepto)
169 |
--------------------------------------------------------------------------------
/src/assets/js/zepto/touch.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | ;(function($){
6 | var touch = {},
7 | touchTimeout, tapTimeout, swipeTimeout, longTapTimeout,
8 | longTapDelay = 750,
9 | gesture
10 |
11 | function swipeDirection(x1, x2, y1, y2) {
12 | return Math.abs(x1 - x2) >=
13 | Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
14 | }
15 |
16 | function longTap() {
17 | longTapTimeout = null
18 | if (touch.last) {
19 | touch.el.trigger('longTap')
20 | touch = {}
21 | }
22 | }
23 |
24 | function cancelLongTap() {
25 | if (longTapTimeout) clearTimeout(longTapTimeout)
26 | longTapTimeout = null
27 | }
28 |
29 | function cancelAll() {
30 | if (touchTimeout) clearTimeout(touchTimeout)
31 | if (tapTimeout) clearTimeout(tapTimeout)
32 | if (swipeTimeout) clearTimeout(swipeTimeout)
33 | if (longTapTimeout) clearTimeout(longTapTimeout)
34 | touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
35 | touch = {}
36 | }
37 |
38 | function isPrimaryTouch(event){
39 | return (event.pointerType == 'touch' ||
40 | event.pointerType == event.MSPOINTER_TYPE_TOUCH)
41 | && event.isPrimary
42 | }
43 |
44 | function isPointerEventType(e, type){
45 | return (e.type == 'pointer'+type ||
46 | e.type.toLowerCase() == 'mspointer'+type)
47 | }
48 |
49 | $(document).ready(function(){
50 | var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType
51 |
52 | if ('MSGesture' in window) {
53 | gesture = new MSGesture()
54 | gesture.target = document.body
55 | }
56 |
57 | $(document)
58 | .bind('MSGestureEnd', function(e){
59 | var swipeDirectionFromVelocity =
60 | e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null
61 | if (swipeDirectionFromVelocity) {
62 | touch.el.trigger('swipe')
63 | touch.el.trigger('swipe'+ swipeDirectionFromVelocity)
64 | }
65 | })
66 | .on('touchstart MSPointerDown pointerdown', function(e){
67 | if((_isPointerType = isPointerEventType(e, 'down')) &&
68 | !isPrimaryTouch(e)) return
69 | firstTouch = _isPointerType ? e : e.touches[0]
70 | if (e.touches && e.touches.length === 1 && touch.x2) {
71 | // Clear out touch movement data if we have it sticking around
72 | // This can occur if touchcancel doesn't fire due to preventDefault, etc.
73 | touch.x2 = undefined
74 | touch.y2 = undefined
75 | }
76 | now = Date.now()
77 | delta = now - (touch.last || now)
78 | touch.el = $('tagName' in firstTouch.target ?
79 | firstTouch.target : firstTouch.target.parentNode)
80 | touchTimeout && clearTimeout(touchTimeout)
81 | touch.x1 = firstTouch.pageX
82 | touch.y1 = firstTouch.pageY
83 | if (delta > 0 && delta <= 250) touch.isDoubleTap = true
84 | touch.last = now
85 | longTapTimeout = setTimeout(longTap, longTapDelay)
86 | // adds the current touch contact for IE gesture recognition
87 | if (gesture && _isPointerType) gesture.addPointer(e.pointerId)
88 | })
89 | .on('touchmove MSPointerMove pointermove', function(e){
90 | if((_isPointerType = isPointerEventType(e, 'move')) &&
91 | !isPrimaryTouch(e)) return
92 | firstTouch = _isPointerType ? e : e.touches[0]
93 | cancelLongTap()
94 | touch.x2 = firstTouch.pageX
95 | touch.y2 = firstTouch.pageY
96 |
97 | deltaX += Math.abs(touch.x1 - touch.x2)
98 | deltaY += Math.abs(touch.y1 - touch.y2)
99 | })
100 | .on('touchend MSPointerUp pointerup', function(e){
101 | if((_isPointerType = isPointerEventType(e, 'up')) &&
102 | !isPrimaryTouch(e)) return
103 | cancelLongTap()
104 |
105 | // swipe
106 | if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
107 | (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))
108 |
109 | swipeTimeout = setTimeout(function() {
110 | if (touch.el){
111 | touch.el.trigger('swipe')
112 | touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
113 | }
114 | touch = {}
115 | }, 0)
116 |
117 | // normal tap
118 | else if ('last' in touch)
119 | // don't fire tap when delta position changed by more than 30 pixels,
120 | // for instance when moving to a point and back to origin
121 | if (deltaX < 30 && deltaY < 30) {
122 | // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
123 | // ('tap' fires before 'scroll')
124 | tapTimeout = setTimeout(function() {
125 |
126 | // trigger universal 'tap' with the option to cancelTouch()
127 | // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
128 | var event = $.Event('tap')
129 | event.cancelTouch = cancelAll
130 | // [by paper] fix -> "TypeError: 'undefined' is not an object (evaluating 'touch.el.trigger'), when double tap
131 | if (touch.el) touch.el.trigger(event)
132 |
133 | // trigger double tap immediately
134 | if (touch.isDoubleTap) {
135 | if (touch.el) touch.el.trigger('doubleTap')
136 | touch = {}
137 | }
138 |
139 | // trigger single tap after 250ms of inactivity
140 | else {
141 | touchTimeout = setTimeout(function(){
142 | touchTimeout = null
143 | if (touch.el) touch.el.trigger('singleTap')
144 | touch = {}
145 | }, 250)
146 | }
147 | }, 0)
148 | } else {
149 | touch = {}
150 | }
151 | deltaX = deltaY = 0
152 |
153 | })
154 | // when the browser window loses focus,
155 | // for example when a modal dialog is shown,
156 | // cancel all ongoing events
157 | .on('touchcancel MSPointerCancel pointercancel', cancelAll)
158 |
159 | // scrolling the window indicates intention of the user
160 | // to scroll, not tap or swipe, so cancel all ongoing events
161 | $(window).on('scroll', cancelAll)
162 | })
163 |
164 | ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown',
165 | 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){
166 | $.fn[eventName] = function(callback){ return this.on(eventName, callback) }
167 | })
168 | })(Zepto)
169 |
--------------------------------------------------------------------------------
/src/views/List.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
28 |
140 |
141 |
282 |
--------------------------------------------------------------------------------
/src/assets/css/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /**
4 | * 1. Change the default font family in all browsers (opinionated).
5 | * 2. Correct the line height in all browsers.
6 | * 3. Prevent adjustments of font size after orientation changes in IE and iOS.
7 | */
8 |
9 | /* Document
10 | ========================================================================== */
11 |
12 | html {
13 | font-family: sans-serif; /* 1 */
14 | line-height: 1.15; /* 2 */
15 | -ms-text-size-adjust: 100%; /* 3 */
16 | -webkit-text-size-adjust: 100%; /* 3 */
17 | }
18 |
19 | /* Sections
20 | ========================================================================== */
21 |
22 | /**
23 | * Remove the margin in all browsers (opinionated).
24 | */
25 |
26 | body {
27 | margin: 0;
28 | }
29 |
30 | /**
31 | * Add the correct display in IE 9-.
32 | */
33 |
34 | article,
35 | aside,
36 | footer,
37 | header,
38 | nav,
39 | section {
40 | display: block;
41 | }
42 |
43 | /**
44 | * Correct the font size and margin on `h1` elements within `section` and
45 | * `article` contexts in Chrome, Firefox, and Safari.
46 | */
47 |
48 | h1 {
49 | font-size: 2em;
50 | margin: 0.67em 0;
51 | }
52 |
53 | /* Grouping content
54 | ========================================================================== */
55 |
56 | /**
57 | * Add the correct display in IE 9-.
58 | * 1. Add the correct display in IE.
59 | */
60 |
61 | figcaption,
62 | figure,
63 | main { /* 1 */
64 | display: block;
65 | }
66 |
67 | /**
68 | * Add the correct margin in IE 8.
69 | */
70 |
71 | figure {
72 | margin: 1em 40px;
73 | }
74 |
75 | /**
76 | * 1. Add the correct box sizing in Firefox.
77 | * 2. Show the overflow in Edge and IE.
78 | */
79 |
80 | hr {
81 | box-sizing: content-box; /* 1 */
82 | height: 0; /* 1 */
83 | overflow: visible; /* 2 */
84 | }
85 |
86 | /**
87 | * 1. Correct the inheritance and scaling of font size in all browsers.
88 | * 2. Correct the odd `em` font sizing in all browsers.
89 | */
90 |
91 | pre {
92 | font-family: monospace, monospace; /* 1 */
93 | font-size: 1em; /* 2 */
94 | }
95 |
96 | /* Text-level semantics
97 | ========================================================================== */
98 |
99 | /**
100 | * 1. Remove the gray background on active links in IE 10.
101 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
102 | */
103 |
104 | a {
105 | background-color: transparent; /* 1 */
106 | -webkit-text-decoration-skip: objects; /* 2 */
107 | }
108 |
109 | /**
110 | * Remove the outline on focused links when they are also active or hovered
111 | * in all browsers (opinionated).
112 | */
113 |
114 | a:active,
115 | a:hover {
116 | outline-width: 0;
117 | }
118 |
119 | /**
120 | * 1. Remove the bottom border in Firefox 39-.
121 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
122 | */
123 |
124 | abbr[title] {
125 | border-bottom: none; /* 1 */
126 | text-decoration: underline; /* 2 */
127 | text-decoration: underline dotted; /* 2 */
128 | }
129 |
130 | /**
131 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
132 | */
133 |
134 | b,
135 | strong {
136 | font-weight: inherit;
137 | }
138 |
139 | /**
140 | * Add the correct font weight in Chrome, Edge, and Safari.
141 | */
142 |
143 | b,
144 | strong {
145 | font-weight: bolder;
146 | }
147 |
148 | /**
149 | * 1. Correct the inheritance and scaling of font size in all browsers.
150 | * 2. Correct the odd `em` font sizing in all browsers.
151 | */
152 |
153 | code,
154 | kbd,
155 | samp {
156 | font-family: monospace, monospace; /* 1 */
157 | font-size: 1em; /* 2 */
158 | }
159 |
160 | /**
161 | * Add the correct font style in Android 4.3-.
162 | */
163 |
164 | dfn {
165 | font-style: italic;
166 | }
167 |
168 | /**
169 | * Add the correct background and color in IE 9-.
170 | */
171 |
172 | mark {
173 | background-color: #ff0;
174 | color: #000;
175 | }
176 |
177 | /**
178 | * Add the correct font size in all browsers.
179 | */
180 |
181 | small {
182 | font-size: 80%;
183 | }
184 |
185 | /**
186 | * Prevent `sub` and `sup` elements from affecting the line height in
187 | * all browsers.
188 | */
189 |
190 | sub,
191 | sup {
192 | font-size: 75%;
193 | line-height: 0;
194 | position: relative;
195 | vertical-align: baseline;
196 | }
197 |
198 | sub {
199 | bottom: -0.25em;
200 | }
201 |
202 | sup {
203 | top: -0.5em;
204 | }
205 |
206 | /* Embedded content
207 | ========================================================================== */
208 |
209 | /**
210 | * Add the correct display in IE 9-.
211 | */
212 |
213 | audio,
214 | video {
215 | display: inline-block;
216 | }
217 |
218 | /**
219 | * Add the correct display in iOS 4-7.
220 | */
221 |
222 | audio:not([controls]) {
223 | display: none;
224 | height: 0;
225 | }
226 |
227 | /**
228 | * Remove the border on images inside links in IE 10-.
229 | */
230 |
231 | img {
232 | border-style: none;
233 | }
234 |
235 | /**
236 | * Hide the overflow in IE.
237 | */
238 |
239 | svg:not(:root) {
240 | overflow: hidden;
241 | }
242 |
243 | /* Forms
244 | ========================================================================== */
245 |
246 | /**
247 | * 1. Change font properties to `inherit` in all browsers (opinionated).
248 | * 2. Remove the margin in Firefox and Safari.
249 | */
250 |
251 | button,
252 | input,
253 | optgroup,
254 | select,
255 | textarea {
256 | font: inherit; /* 1 */
257 | margin: 0; /* 2 */
258 | }
259 |
260 | /**
261 | * Restore the font weight unset by the previous rule.
262 | */
263 |
264 | optgroup {
265 | font-weight: bold;
266 | }
267 |
268 | /**
269 | * Show the overflow in IE.
270 | * 1. Show the overflow in Edge.
271 | */
272 |
273 | button,
274 | input { /* 1 */
275 | overflow: visible;
276 | }
277 |
278 | /**
279 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
280 | * 1. Remove the inheritance of text transform in Firefox.
281 | */
282 |
283 | button,
284 | select { /* 1 */
285 | text-transform: none;
286 | }
287 |
288 | /**
289 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
290 | * controls in Android 4.
291 | * 2. Correct the inability to style clickable types in iOS and Safari.
292 | */
293 |
294 | button,
295 | html [type="button"], /* 1 */
296 | [type="reset"],
297 | [type="submit"] {
298 | -webkit-appearance: button; /* 2 */
299 | }
300 |
301 | /**
302 | * Remove the inner border and padding in Firefox.
303 | */
304 |
305 | button::-moz-focus-inner,
306 | [type="button"]::-moz-focus-inner,
307 | [type="reset"]::-moz-focus-inner,
308 | [type="submit"]::-moz-focus-inner {
309 | border-style: none;
310 | padding: 0;
311 | }
312 |
313 | /**
314 | * Restore the focus styles unset by the previous rule.
315 | */
316 |
317 | button:-moz-focusring,
318 | [type="button"]:-moz-focusring,
319 | [type="reset"]:-moz-focusring,
320 | [type="submit"]:-moz-focusring {
321 | outline: 1px dotted ButtonText;
322 | }
323 |
324 | /**
325 | * Change the border, margin, and padding in all browsers (opinionated).
326 | */
327 |
328 | fieldset {
329 | border: 1px solid #c0c0c0;
330 | margin: 0 2px;
331 | padding: 0.35em 0.625em 0.75em;
332 | }
333 |
334 | /**
335 | * 1. Correct the text wrapping in Edge and IE.
336 | * 2. Correct the color inheritance from `fieldset` elements in IE.
337 | * 3. Remove the padding so developers are not caught out when they zero out
338 | * `fieldset` elements in all browsers.
339 | */
340 |
341 | legend {
342 | box-sizing: border-box; /* 1 */
343 | color: inherit; /* 2 */
344 | display: table; /* 1 */
345 | max-width: 100%; /* 1 */
346 | padding: 0; /* 3 */
347 | white-space: normal; /* 1 */
348 | }
349 |
350 | /**
351 | * 1. Add the correct display in IE 9-.
352 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
353 | */
354 |
355 | progress {
356 | display: inline-block; /* 1 */
357 | vertical-align: baseline; /* 2 */
358 | }
359 |
360 | /**
361 | * Remove the default vertical scrollbar in IE.
362 | */
363 |
364 | textarea {
365 | overflow: auto;
366 | }
367 |
368 | /**
369 | * 1. Add the correct box sizing in IE 10-.
370 | * 2. Remove the padding in IE 10-.
371 | */
372 |
373 | [type="checkbox"],
374 | [type="radio"] {
375 | box-sizing: border-box; /* 1 */
376 | padding: 0; /* 2 */
377 | }
378 |
379 | /**
380 | * Correct the cursor style of increment and decrement buttons in Chrome.
381 | */
382 |
383 | [type="number"]::-webkit-inner-spin-button,
384 | [type="number"]::-webkit-outer-spin-button {
385 | height: auto;
386 | }
387 |
388 | /**
389 | * 1. Correct the odd appearance in Chrome and Safari.
390 | * 2. Correct the outline style in Safari.
391 | */
392 |
393 | [type="search"] {
394 | -webkit-appearance: textfield; /* 1 */
395 | outline-offset: -2px; /* 2 */
396 | }
397 |
398 | /**
399 | * Remove the inner padding and cancel buttons in Chrome and Safari on OS X.
400 | */
401 |
402 | [type="search"]::-webkit-search-cancel-button,
403 | [type="search"]::-webkit-search-decoration {
404 | -webkit-appearance: none;
405 | }
406 |
407 | /**
408 | * 1. Correct the inability to style clickable types in iOS and Safari.
409 | * 2. Change font properties to `inherit` in Safari.
410 | */
411 |
412 | ::-webkit-file-upload-button {
413 | -webkit-appearance: button; /* 1 */
414 | font: inherit; /* 2 */
415 | }
416 |
417 | /* Interactive
418 | ========================================================================== */
419 |
420 | /*
421 | * Add the correct display in IE 9-.
422 | * 1. Add the correct display in Edge, IE, and Firefox.
423 | */
424 |
425 | details, /* 1 */
426 | menu {
427 | display: block;
428 | }
429 |
430 | /*
431 | * Add the correct display in all browsers.
432 | */
433 |
434 | summary {
435 | display: list-item;
436 | }
437 |
438 | /* Scripting
439 | ========================================================================== */
440 |
441 | /**
442 | * Add the correct display in IE 9-.
443 | */
444 |
445 | canvas {
446 | display: inline-block;
447 | }
448 |
449 | /**
450 | * Add the correct display in IE.
451 | */
452 |
453 | template {
454 | display: none;
455 | }
456 |
457 | /* Hidden
458 | ========================================================================== */
459 |
460 | /**
461 | * Add the correct display in IE 10-.
462 | */
463 |
464 | [hidden] {
465 | display: none;
466 | }
--------------------------------------------------------------------------------
/src/assets/js/zepto/event.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | ;(function($){
6 | var _zid = 1, undefined,
7 | slice = Array.prototype.slice,
8 | isFunction = $.isFunction,
9 | isString = function(obj){ return typeof obj == 'string' },
10 | handlers = {},
11 | specialEvents={},
12 | focusinSupported = 'onfocusin' in window,
13 | focus = { focus: 'focusin', blur: 'focusout' },
14 | hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }
15 |
16 | specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
17 |
18 | function zid(element) {
19 | return element._zid || (element._zid = _zid++)
20 | }
21 | function findHandlers(element, event, fn, selector) {
22 | event = parse(event)
23 | if (event.ns) var matcher = matcherFor(event.ns)
24 | return (handlers[zid(element)] || []).filter(function(handler) {
25 | return handler
26 | && (!event.e || handler.e == event.e)
27 | && (!event.ns || matcher.test(handler.ns))
28 | && (!fn || zid(handler.fn) === zid(fn))
29 | && (!selector || handler.sel == selector)
30 | })
31 | }
32 | function parse(event) {
33 | var parts = ('' + event).split('.')
34 | return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
35 | }
36 | function matcherFor(ns) {
37 | return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')
38 | }
39 |
40 | function eventCapture(handler, captureSetting) {
41 | return handler.del &&
42 | (!focusinSupported && (handler.e in focus)) ||
43 | !!captureSetting
44 | }
45 |
46 | function realEvent(type) {
47 | return hover[type] || (focusinSupported && focus[type]) || type
48 | }
49 |
50 | function add(element, events, fn, data, selector, delegator, capture){
51 | var id = zid(element), set = (handlers[id] || (handlers[id] = []))
52 | events.split(/\s/).forEach(function(event){
53 | if (event == 'ready') return $(document).ready(fn)
54 | var handler = parse(event)
55 | handler.fn = fn
56 | handler.sel = selector
57 | // emulate mouseenter, mouseleave
58 | if (handler.e in hover) fn = function(e){
59 | var related = e.relatedTarget
60 | if (!related || (related !== this && !$.contains(this, related)))
61 | return handler.fn.apply(this, arguments)
62 | }
63 | handler.del = delegator
64 | var callback = delegator || fn
65 | handler.proxy = function(e){
66 | e = compatible(e)
67 | if (e.isImmediatePropagationStopped()) return
68 | e.data = data
69 | var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))
70 | if (result === false) e.preventDefault(), e.stopPropagation()
71 | return result
72 | }
73 | handler.i = set.length
74 | set.push(handler)
75 | if ('addEventListener' in element)
76 | element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
77 | })
78 | }
79 | function remove(element, events, fn, selector, capture){
80 | var id = zid(element)
81 | ;(events || '').split(/\s/).forEach(function(event){
82 | findHandlers(element, event, fn, selector).forEach(function(handler){
83 | delete handlers[id][handler.i]
84 | if ('removeEventListener' in element)
85 | element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
86 | })
87 | })
88 | }
89 |
90 | $.event = { add: add, remove: remove }
91 |
92 | $.proxy = function(fn, context) {
93 | var args = (2 in arguments) && slice.call(arguments, 2)
94 | if (isFunction(fn)) {
95 | var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) }
96 | proxyFn._zid = zid(fn)
97 | return proxyFn
98 | } else if (isString(context)) {
99 | if (args) {
100 | args.unshift(fn[context], fn)
101 | return $.proxy.apply(null, args)
102 | } else {
103 | return $.proxy(fn[context], fn)
104 | }
105 | } else {
106 | throw new TypeError("expected function")
107 | }
108 | }
109 |
110 | $.fn.bind = function(event, data, callback){
111 | return this.on(event, data, callback)
112 | }
113 | $.fn.unbind = function(event, callback){
114 | return this.off(event, callback)
115 | }
116 | $.fn.one = function(event, selector, data, callback){
117 | return this.on(event, selector, data, callback, 1)
118 | }
119 |
120 | var returnTrue = function(){return true},
121 | returnFalse = function(){return false},
122 | ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,
123 | eventMethods = {
124 | preventDefault: 'isDefaultPrevented',
125 | stopImmediatePropagation: 'isImmediatePropagationStopped',
126 | stopPropagation: 'isPropagationStopped'
127 | }
128 |
129 | function compatible(event, source) {
130 | if (source || !event.isDefaultPrevented) {
131 | source || (source = event)
132 |
133 | $.each(eventMethods, function(name, predicate) {
134 | var sourceMethod = source[name]
135 | event[name] = function(){
136 | this[predicate] = returnTrue
137 | return sourceMethod && sourceMethod.apply(source, arguments)
138 | }
139 | event[predicate] = returnFalse
140 | })
141 |
142 | event.timeStamp || (event.timeStamp = Date.now())
143 |
144 | if (source.defaultPrevented !== undefined ? source.defaultPrevented :
145 | 'returnValue' in source ? source.returnValue === false :
146 | source.getPreventDefault && source.getPreventDefault())
147 | event.isDefaultPrevented = returnTrue
148 | }
149 | return event
150 | }
151 |
152 | function createProxy(event) {
153 | var key, proxy = { originalEvent: event }
154 | for (key in event)
155 | if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
156 |
157 | return compatible(proxy, event)
158 | }
159 |
160 | $.fn.delegate = function(selector, event, callback){
161 | return this.on(event, selector, callback)
162 | }
163 | $.fn.undelegate = function(selector, event, callback){
164 | return this.off(event, selector, callback)
165 | }
166 |
167 | $.fn.live = function(event, callback){
168 | $(document.body).delegate(this.selector, event, callback)
169 | return this
170 | }
171 | $.fn.die = function(event, callback){
172 | $(document.body).undelegate(this.selector, event, callback)
173 | return this
174 | }
175 |
176 | $.fn.on = function(event, selector, data, callback, one){
177 | var autoRemove, delegator, $this = this
178 | if (event && !isString(event)) {
179 | $.each(event, function(type, fn){
180 | $this.on(type, selector, data, fn, one)
181 | })
182 | return $this
183 | }
184 |
185 | if (!isString(selector) && !isFunction(callback) && callback !== false)
186 | callback = data, data = selector, selector = undefined
187 | if (callback === undefined || data === false)
188 | callback = data, data = undefined
189 |
190 | if (callback === false) callback = returnFalse
191 |
192 | return $this.each(function(_, element){
193 | if (one) autoRemove = function(e){
194 | remove(element, e.type, callback)
195 | return callback.apply(this, arguments)
196 | }
197 |
198 | if (selector) delegator = function(e){
199 | var evt, match = $(e.target).closest(selector, element).get(0)
200 | if (match && match !== element) {
201 | evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
202 | return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))
203 | }
204 | }
205 |
206 | add(element, event, callback, data, selector, delegator || autoRemove)
207 | })
208 | }
209 | $.fn.off = function(event, selector, callback){
210 | var $this = this
211 | if (event && !isString(event)) {
212 | $.each(event, function(type, fn){
213 | $this.off(type, selector, fn)
214 | })
215 | return $this
216 | }
217 |
218 | if (!isString(selector) && !isFunction(callback) && callback !== false)
219 | callback = selector, selector = undefined
220 |
221 | if (callback === false) callback = returnFalse
222 |
223 | return $this.each(function(){
224 | remove(this, event, callback, selector)
225 | })
226 | }
227 |
228 | $.fn.trigger = function(event, args){
229 | event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event)
230 | event._args = args
231 | return this.each(function(){
232 | // handle focus(), blur() by calling them directly
233 | if (event.type in focus && typeof this[event.type] == "function") this[event.type]()
234 | // items in the collection might not be DOM elements
235 | else if ('dispatchEvent' in this) this.dispatchEvent(event)
236 | else $(this).triggerHandler(event, args)
237 | })
238 | }
239 |
240 | // triggers event handlers on current element just as if an event occurred,
241 | // doesn't trigger an actual event, doesn't bubble
242 | $.fn.triggerHandler = function(event, args){
243 | var e, result
244 | this.each(function(i, element){
245 | e = createProxy(isString(event) ? $.Event(event) : event)
246 | e._args = args
247 | e.target = element
248 | $.each(findHandlers(element, event.type || event), function(i, handler){
249 | result = handler.proxy(e)
250 | if (e.isImmediatePropagationStopped()) return false
251 | })
252 | })
253 | return result
254 | }
255 |
256 | // shortcut methods for `.bind(event, fn)` for each event type
257 | ;('focusin focusout focus blur load resize scroll unload click dblclick '+
258 | 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+
259 | 'change select keydown keypress keyup error').split(' ').forEach(function(event) {
260 | $.fn[event] = function(callback) {
261 | return (0 in arguments) ?
262 | this.bind(event, callback) :
263 | this.trigger(event)
264 | }
265 | })
266 |
267 | $.Event = function(type, props) {
268 | if (!isString(type)) props = type, type = props.type
269 | var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
270 | if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
271 | event.initEvent(type, bubbles, true)
272 | return compatible(event)
273 | }
274 |
275 | })(Zepto)
276 |
--------------------------------------------------------------------------------
/static/js/qq-wechat-emotion-parser.js:
--------------------------------------------------------------------------------
1 |
2 | !function(){window._qqWechatEmotionParser = {};
3 | window.qqWechatEmotionParser = function() {};
4 | }();
5 |
6 | !function(){window._qqWechatEmotionParser.emotion_map={"/::)":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/0.gif","/::~":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/1.gif","/::B":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/2.gif","/::|":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/3.gif","/:8-)":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/4.gif","/::<":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/5.gif","/::$":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/6.gif","/::X":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/7.gif","/::Z":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/8.gif","/::'(":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/9.gif","/::-|":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/10.gif","/::@":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/11.gif","/::P":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/12.gif","/::D":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/13.gif","/::O":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/14.gif","/::(":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/15.gif","/::+":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/16.gif","/:--b":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/17.gif","/::Q":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/18.gif","/::T":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/19.gif","/:,@P":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/20.gif","/:,@-D":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/21.gif","/::d":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/22.gif","/:,@o":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/23.gif","/::g":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/24.gif","/:|-)":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/25.gif","/::!":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/26.gif","/::L":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/27.gif","/::>":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/28.gif","/::,@":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/29.gif","/:,@f":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/30.gif","/::-S":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/31.gif","/:?":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/32.gif","/:,@x":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/33.gif","/:,@@":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/34.gif","/::8":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/35.gif","/:,@!":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/36.gif","/:!!!":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/37.gif","/:xx":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/38.gif","/:bye":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/39.gif","/:wipe":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/40.gif","/:dig":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/41.gif","/:handclap":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/42.gif","/:&-(":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/43.gif","/:B-)":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/44.gif","/:<@":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/45.gif","/:@>":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/46.gif","/::-O":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/47.gif","/:>-|":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/48.gif","/:P-(":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/49.gif","/::'|":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/50.gif","/:X-)":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/51.gif","/::*":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/52.gif","/:@x":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/53.gif","/:8*":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/54.gif","/:pd":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/55.gif","/:
":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/56.gif","/:beer":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/57.gif","/:basketb":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/58.gif","/:oo":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/59.gif","/:coffee":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/60.gif","/:eat":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/61.gif","/:pig":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/62.gif","/:rose":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/63.gif","/:fade":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/64.gif","/:showlove":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/65.gif","/:heart":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/66.gif","/:break":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/67.gif","/:cake":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/68.gif","/:li":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/69.gif","/:bome":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/70.gif","/:kn":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/71.gif","/:footb":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/72.gif","/:ladybug":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/73.gif","/:shit":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/74.gif","/:moon":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/75.gif","/:sun":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/76.gif","/:gift":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/77.gif","/:hug":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/78.gif","/:strong":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/79.gif","/:weak":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/80.gif","/:share":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/81.gif","/:v":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/82.gif","/:@)":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/83.gif","/:jj":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/84.gif","/:@@":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/85.gif","/:bad":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/86.gif","/:lvu":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/87.gif","/:no":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/88.gif","/:ok":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/89.gif","/:love":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/90.gif","/:":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/91.gif","/:jump":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/92.gif","/:shake":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/93.gif","/:":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/94.gif","/:circle":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/95.gif","/:kotow":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/96.gif","/:turn":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/97.gif","/:skip":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/98.gif","/:oY":"https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/99.gif"};}();
7 |
8 | !function(){function Trie(){
9 | this.words = 0;
10 | this.empty = 1;
11 | this.index = 0;
12 | this.children = {};
13 | }
14 |
15 | Trie.prototype = {
16 | insert: function(str, pos, idx){
17 | if(str.length === 0) {
18 | return;
19 | }
20 | var T = this;
21 | var k;
22 | var child;
23 |
24 | if(pos === undefined) {
25 | pos = 0;
26 | }
27 | if(pos === str.length) {
28 | T.index = idx;
29 | return;
30 | }
31 | k = str[pos];
32 | if(T.children[k] === undefined){
33 | T.children[k] = new Trie();
34 | T.empty = 0;
35 | T.children[k].words = this.words + 1;
36 | }
37 | child = T.children[k];
38 | child.insert(str, pos + 1, idx);
39 | },
40 |
41 | build: function(arr){
42 | var len = arr.length;
43 | for(var i = 0; i < len; i++){
44 | this.insert(arr[i], 0, i);
45 | }
46 | },
47 |
48 | searchOne: function(str, pos){
49 | if(pos === undefined){
50 | pos = 0;
51 | }
52 | var result = {};
53 | if(str.length === 0) return result;
54 | var T = this;
55 | var child;
56 | var k;
57 | result.arr = [];
58 | k = str[pos];
59 | child = T.children[k];
60 | if(child !== undefined && pos < str.length){
61 | return child.searchOne(str, pos + 1);
62 | }
63 | if(child === undefined && T.empty === 0) return result;
64 | if(T.empty == 1){
65 | result.arr[0] = pos - T.words;
66 | result.arr[1] = T.index;
67 | result.words = T.words;
68 | return result;
69 | }
70 | return result;
71 | },
72 |
73 | search: function(str){
74 | if(this.empty == 1) return [];
75 | var len = str.length;
76 | var searchResult = [];
77 | var tmp;
78 | for(var i = 0; i < len - 1; i++){
79 | tmp = this.searchOne(str, i);
80 | if(typeof tmp.arr !== 'undefined' && tmp.arr.length > 0){
81 | searchResult.push(tmp.arr);
82 | i = i + tmp.words - 1;
83 | }
84 | }
85 | return searchResult;
86 | }
87 | };
88 |
89 | if(typeof module !== 'undefined'){
90 | module.exports = Trie;
91 | }
92 | else if(typeof window !== 'undefined'){
93 | window._qqWechatEmotionParser.Trie = Trie;
94 | }
95 |
96 | }();
97 |
98 | !function(){var emotion_map, trie, emotion_list, Trie;
99 |
100 | if(typeof module !== 'undefined'){
101 | emotion_map = require('./emotions.json');
102 | Trie = require('./trie');
103 | build();
104 | module.exports = qqWechatEmotionParser;
105 | }
106 | else if(window !== 'undefined'){
107 | emotion_map = window._qqWechatEmotionParser.emotion_map;
108 | Trie = window._qqWechatEmotionParser.Trie;
109 | build();
110 | window.qqWechatEmotionParser = qqWechatEmotionParser;
111 | }
112 | else return;
113 |
114 | function build(){
115 | emotion_list = keys(emotion_map);
116 | trie = new Trie();
117 | trie.build(emotion_list);
118 | }
119 |
120 | function qqWechatEmotionParser(str) {
121 | var indices = trie.search(str);
122 | indices.reverse().map(function(idx) {
123 | var pos = idx[0],
124 | emotion = emotion_list[idx[1]],
125 | img = '
';
126 | str = splice(str, pos, emotion.length, img);
127 | });
128 | return str;
129 | }
130 |
131 | function splice(str, index, count, add) {
132 | return str.slice(0, index) + add + str.slice(index + count);
133 | }
134 |
135 | function keys(map){
136 | var list = [];
137 | for (var k in map) {
138 | if (map.hasOwnProperty(k)) list.push(k);
139 | }
140 | return list;
141 | }
142 | }();
143 |
--------------------------------------------------------------------------------
/src/components/MessageItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 | {{moment(createtime * 1000).format('MM.DD HH:mm')}}
6 |
7 |
47 |
89 |
90 |
91 |
92 |
196 |
197 |
419 |
--------------------------------------------------------------------------------
/src/assets/js/zepto/ajax.js:
--------------------------------------------------------------------------------
1 | // Zepto.js
2 | // (c) 2010-2016 Thomas Fuchs
3 | // Zepto.js may be freely distributed under the MIT license.
4 |
5 | ;(function($){
6 | var jsonpID = +new Date(),
7 | document = window.document,
8 | key,
9 | name,
10 | rscript = /
347 |
348 |
481 |
--------------------------------------------------------------------------------