├── .gitignore ├── src ├── nuomi │ ├── vue3 │ │ ├── style.scss │ │ ├── template.html │ │ ├── Observer.js │ │ └── index.js │ ├── contextMenu │ │ ├── template.html │ │ ├── style.scss │ │ ├── index.js │ │ ├── ContextMenu.scss │ │ └── ContextMenu.js │ ├── player │ │ ├── font │ │ │ ├── iconfont.eot │ │ │ ├── iconfont.ttf │ │ │ ├── iconfont.woff │ │ │ ├── demo_fontclass.html │ │ │ ├── demo_unicode.html │ │ │ ├── demo_symbol.html │ │ │ └── iconfont.svg │ │ ├── fonts │ │ │ ├── icomoon.eot │ │ │ ├── icomoon.ttf │ │ │ ├── icomoon.woff │ │ │ └── icomoon.svg │ │ ├── index.js │ │ ├── iconfont.css │ │ ├── template.html │ │ └── font.css │ ├── vue4 │ │ ├── template.html │ │ ├── style.scss │ │ ├── index.js │ │ ├── Vue.js │ │ └── Observer.js │ ├── vue1 │ │ ├── template.html │ │ ├── Observer.js │ │ ├── style.scss │ │ └── index.js │ ├── vue2 │ │ ├── template.html │ │ ├── style.scss │ │ ├── Observer.js │ │ └── index.js │ ├── loading │ │ ├── template.html │ │ ├── index.js │ │ └── style.scss │ ├── vue5 │ │ ├── style.scss │ │ ├── template.html │ │ ├── Publisher.js │ │ ├── index.js │ │ ├── Vue.js │ │ ├── Watcher.js │ │ └── Observer.js │ ├── collapse │ │ ├── index.js │ │ ├── style.scss │ │ └── template.html │ ├── hoverEffect │ │ ├── index.js │ │ ├── template.html │ │ └── style.scss │ ├── vue │ │ ├── Publisher.js │ │ ├── Observer.js │ │ ├── Watcher.js │ │ └── Vue.js │ ├── markdown │ │ ├── index.js │ │ ├── template.html │ │ ├── Markdown.js │ │ ├── style.scss │ │ ├── LNote.js │ │ └── GMD.js │ ├── slider │ │ ├── index.js │ │ ├── template.html │ │ └── style.scss │ └── phantomjs │ │ ├── task.js │ │ └── tmall.baidu.json ├── business │ └── snake │ │ ├── template.html │ │ ├── style.scss │ │ └── index.js ├── echarts │ └── threejs1 │ │ ├── style.scss │ │ ├── template.html │ │ └── index.js ├── style │ ├── var.scss │ ├── entries.scss │ └── index.scss ├── createEntries.js ├── taskList.json └── Router.js ├── .babelrc ├── static ├── 28246.jpg ├── avatar.png ├── cover.jpg ├── iconfont.eot ├── iconfont.ttf ├── iconfont.woff ├── anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg └── iconfont.svg ├── docs ├── static │ ├── 28246.jpg │ ├── avatar.png │ ├── cover.jpg │ ├── iconfont.eot │ ├── iconfont.ttf │ ├── iconfont.woff │ ├── anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg │ ├── 4596fc0d.anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg │ ├── icomoon.svg │ └── iconfont.svg ├── style.css.map ├── 1070c58cc710edcca465a8465b35ae2a.woff ├── 68ad099a8cf8387adb3b91569383877d.ttf ├── 814ee47a7bfa61193af15d0ceea56807.ttf ├── 8ed19a6deb6943cd7e3efb25aa040bbb.woff ├── bd86b39250df5f0d2bb3db45bae6775e.eot ├── f0122547efbcc6600c978835e2f8c808.eot ├── f254c503c3061d5d899714710f52b80e.jpg ├── commons.js ├── index.html ├── 13.index.js ├── 10.index.js ├── 11.index.js ├── 12.index.js ├── 8.index.js ├── 7.index.js ├── 4.index.js ├── 3.index.js ├── 9.index.js ├── 6.index.js └── 5.index.js ├── deploy.sh ├── package.json ├── index.html ├── webpack.config.js └── npm-debug.log /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /src/nuomi/vue3/style.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/nuomi/contextMenu/template.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0"], 3 | "comments": false 4 | } -------------------------------------------------------------------------------- /static/28246.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/static/28246.jpg -------------------------------------------------------------------------------- /static/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/static/avatar.png -------------------------------------------------------------------------------- /static/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/static/cover.jpg -------------------------------------------------------------------------------- /static/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/static/iconfont.eot -------------------------------------------------------------------------------- /static/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/static/iconfont.ttf -------------------------------------------------------------------------------- /docs/static/28246.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/static/28246.jpg -------------------------------------------------------------------------------- /docs/static/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/static/avatar.png -------------------------------------------------------------------------------- /docs/static/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/static/cover.jpg -------------------------------------------------------------------------------- /static/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/static/iconfont.woff -------------------------------------------------------------------------------- /docs/static/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/static/iconfont.eot -------------------------------------------------------------------------------- /docs/static/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/static/iconfont.ttf -------------------------------------------------------------------------------- /src/business/snake/template.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
-------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | npm run build 4 | git add . 5 | git status 6 | git commit -m "$1" 7 | git push -------------------------------------------------------------------------------- /docs/static/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/static/iconfont.woff -------------------------------------------------------------------------------- /docs/style.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":[],"names":[],"mappings":"","file":"style.css","sourceRoot":""} -------------------------------------------------------------------------------- /src/nuomi/player/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/src/nuomi/player/font/iconfont.eot -------------------------------------------------------------------------------- /src/nuomi/player/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/src/nuomi/player/font/iconfont.ttf -------------------------------------------------------------------------------- /src/nuomi/player/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/src/nuomi/player/fonts/icomoon.eot -------------------------------------------------------------------------------- /src/nuomi/player/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/src/nuomi/player/fonts/icomoon.ttf -------------------------------------------------------------------------------- /src/nuomi/player/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/src/nuomi/player/font/iconfont.woff -------------------------------------------------------------------------------- /src/nuomi/player/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/src/nuomi/player/fonts/icomoon.woff -------------------------------------------------------------------------------- /docs/1070c58cc710edcca465a8465b35ae2a.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/1070c58cc710edcca465a8465b35ae2a.woff -------------------------------------------------------------------------------- /docs/68ad099a8cf8387adb3b91569383877d.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/68ad099a8cf8387adb3b91569383877d.ttf -------------------------------------------------------------------------------- /docs/814ee47a7bfa61193af15d0ceea56807.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/814ee47a7bfa61193af15d0ceea56807.ttf -------------------------------------------------------------------------------- /docs/8ed19a6deb6943cd7e3efb25aa040bbb.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/8ed19a6deb6943cd7e3efb25aa040bbb.woff -------------------------------------------------------------------------------- /docs/bd86b39250df5f0d2bb3db45bae6775e.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/bd86b39250df5f0d2bb3db45bae6775e.eot -------------------------------------------------------------------------------- /docs/f0122547efbcc6600c978835e2f8c808.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/f0122547efbcc6600c978835e2f8c808.eot -------------------------------------------------------------------------------- /docs/f254c503c3061d5d899714710f52b80e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/f254c503c3061d5d899714710f52b80e.jpg -------------------------------------------------------------------------------- /src/business/snake/style.scss: -------------------------------------------------------------------------------- 1 | .snake { 2 | position: absolute; 3 | left: 50%; 4 | top: 50%; 5 | transform: translate(-50%, -50%); 6 | } -------------------------------------------------------------------------------- /src/echarts/threejs1/style.scss: -------------------------------------------------------------------------------- 1 | #mainCanvas { 2 | position: absolute; 3 | left: 50%; 4 | top: 50%; 5 | transform: translate(-50%, -50%); 6 | } -------------------------------------------------------------------------------- /src/nuomi/vue4/template.html: -------------------------------------------------------------------------------- 1 |
2 |
Name: {{ user.name }}
3 |
Age: {{ user.age }}
4 |
-------------------------------------------------------------------------------- /src/echarts/threejs1/template.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/nuomi/vue1/template.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
-------------------------------------------------------------------------------- /src/nuomi/vue2/template.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
-------------------------------------------------------------------------------- /src/nuomi/vue3/template.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
-------------------------------------------------------------------------------- /src/nuomi/loading/template.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 |
7 | 8 |
-------------------------------------------------------------------------------- /src/nuomi/vue4/style.scss: -------------------------------------------------------------------------------- 1 | #vue-content { 2 | text-align: center; 3 | font-size: .3rem; 4 | position: absolute; 5 | width: 100%; 6 | top: 50%; 7 | transform: translateY(-50%); 8 | } -------------------------------------------------------------------------------- /src/nuomi/vue5/style.scss: -------------------------------------------------------------------------------- 1 | #vue-content { 2 | text-align: center; 3 | font-size: .3rem; 4 | position: absolute; 5 | width: 100%; 6 | top: 50%; 7 | transform: translateY(-50%); 8 | } -------------------------------------------------------------------------------- /static/anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/static/anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg -------------------------------------------------------------------------------- /docs/static/anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/static/anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg -------------------------------------------------------------------------------- /src/nuomi/vue5/template.html: -------------------------------------------------------------------------------- 1 |
2 |
Name: {{ user.name }}
3 |
Age: {{ user.age }}
4 |
Clicked: {{ click }} times
5 | 6 | 7 |
-------------------------------------------------------------------------------- /docs/static/4596fc0d.anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongpeione/ife2017/HEAD/docs/static/4596fc0d.anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg -------------------------------------------------------------------------------- /src/nuomi/loading/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g } from '../../gtool'; 3 | import './style.scss'; 4 | 5 | export function create (parent, option = []) { 6 | parent = typeof parent === 'string' ? g.$(parent) : parent; 7 | 8 | parent.innerHTML = template; 9 | } -------------------------------------------------------------------------------- /src/nuomi/collapse/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g } from '../../gtool'; 3 | import './style.scss'; 4 | 5 | export function create (parent, option = []) { 6 | parent = typeof parent === 'string' ? g.$(parent) : parent; 7 | 8 | parent.innerHTML = template; 9 | 10 | 11 | } -------------------------------------------------------------------------------- /src/nuomi/hoverEffect/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g } from '../../gtool'; 3 | import './style.scss'; 4 | 5 | export function create (parent, option = []) { 6 | parent = typeof parent === 'string' ? g.$(parent) : parent; 7 | 8 | parent.innerHTML = template; 9 | 10 | 11 | } -------------------------------------------------------------------------------- /src/nuomi/vue/Publisher.js: -------------------------------------------------------------------------------- 1 | export default class Publisher { 2 | constructor () { 3 | this.subscribers = []; 4 | } 5 | 6 | add (sub) { 7 | this.subscribers.push(sub); 8 | } 9 | 10 | update (path) { 11 | this.subscribers.forEach(sub => { 12 | sub.update(path); 13 | }); 14 | } 15 | } -------------------------------------------------------------------------------- /src/nuomi/vue5/Publisher.js: -------------------------------------------------------------------------------- 1 | export default class Publisher { 2 | constructor () { 3 | this.watchers = []; 4 | } 5 | 6 | add (watcher) { 7 | this.watchers.push(watcher); 8 | } 9 | 10 | update () { 11 | this.watchers.forEach(watcher => { 12 | watcher.update(); 13 | }); 14 | } 15 | } -------------------------------------------------------------------------------- /src/nuomi/player/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g } from '../../gtool'; 3 | import './style.scss'; 4 | import Player from './Player'; 5 | 6 | export function create (parent, option = []) { 7 | parent = typeof parent === 'string' ? g.$(parent) : parent; 8 | 9 | parent.innerHTML = template; 10 | 11 | new Player(parent, true); 12 | } -------------------------------------------------------------------------------- /src/nuomi/markdown/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g } from '../../gtool'; 3 | import './style.scss'; 4 | import Markdown from './Markdown'; 5 | 6 | export function create (parent, option = []) { 7 | parent = typeof parent === 'string' ? g.$(parent) : parent; 8 | 9 | parent.innerHTML = template; 10 | 11 | new Markdown('.markdown .editor', '.markdown .out'); 12 | } -------------------------------------------------------------------------------- /src/business/snake/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g } from '../../gtool'; 3 | import './style.scss'; 4 | import Snake from './Snake'; 5 | 6 | export function create (parent, option = []) { 7 | parent = typeof parent === 'string' ? g.$(parent) : parent; 8 | 9 | parent.innerHTML = template; 10 | 11 | new Snake('.snake-wrap', { 12 | color: { 13 | bg: '#232', 14 | snake: '#985' 15 | } 16 | }); 17 | } -------------------------------------------------------------------------------- /src/nuomi/contextMenu/style.scss: -------------------------------------------------------------------------------- 1 | .contentMenu { 2 | width: 100%; 3 | height: 200px; 4 | background: #eee; 5 | border-radius: 3px; 6 | position: absolute; 7 | top: 50%; 8 | margin: -100px 0 0 0; 9 | // transform: translate(-50%, -50%); 10 | 11 | &::before { 12 | content: '这里是右键菜单区域'; 13 | font-size: 20px; 14 | color: #999; 15 | position: absolute; 16 | left: 50%; 17 | top: 50%; 18 | transform: translate(-50%, -50%); 19 | } 20 | } -------------------------------------------------------------------------------- /src/nuomi/hoverEffect/template.html: -------------------------------------------------------------------------------- 1 |
2 | hover effect 3 |
4 |
5 |
6 |
7 |

El Psy Congroo

8 | Enter 9 |
10 |
11 |
12 |
13 |
-------------------------------------------------------------------------------- /src/nuomi/vue4/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g, CONST } from '../../gtool'; 3 | import './style.scss'; 4 | import Observer from './Observer'; 5 | import Vue from './Vue'; 6 | 7 | export function create (parent, option = []) { 8 | parent = typeof parent === 'string' ? g.$(parent) : parent; 9 | 10 | parent.innerHTML = template; 11 | 12 | let app = new Vue({ 13 | el: '#vue-content', 14 | data: { 15 | user: { 16 | name: 'youngwind', 17 | age: 25 18 | } 19 | } 20 | }); 21 | 22 | console.log(app); 23 | 24 | } -------------------------------------------------------------------------------- /src/nuomi/slider/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g } from '../../gtool'; 3 | import './style.scss'; 4 | 5 | export function create (parent, option = []) { 6 | parent = typeof parent === 'string' ? g.$(parent) : parent; 7 | 8 | parent.innerHTML = template; 9 | 10 | let angle = 0; 11 | const sliderCover = g.$('.slider-cover'); 12 | g.$('.previous').addEventListener('click', () => { 13 | g.css(sliderCover, `transform: rotateY(${angle += 60}deg)`); 14 | }); 15 | g.$('.next').addEventListener('click', () => { 16 | g.css(sliderCover, `transform: rotateY(${angle -= 60}deg)`); 17 | }); 18 | } -------------------------------------------------------------------------------- /src/nuomi/slider/template.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 |
15 | 16 |
-------------------------------------------------------------------------------- /src/style/var.scss: -------------------------------------------------------------------------------- 1 | $gap-big: .4rem; 2 | $gap-middle: .2rem; 3 | $gap-normal: .15rem; 4 | $gap-small: .1rem; 5 | $gap-tiny: .06rem; 6 | 7 | $border: 0.01rem; 8 | 9 | // Color 10 | $green: #54DD70; 11 | $green-light: #64e47e; 12 | $green-dark: #40b958; 13 | 14 | $blue: #38AFF6; 15 | $blue-light: #59bbf5; 16 | $blue-dark: #299ade; 17 | 18 | $yellow: #FFCD49; 19 | $red: #F1584D; 20 | 21 | $dark: #3D4448; 22 | $dark-light: #535C60; 23 | $gray: #747E86; 24 | $gray-light: #ABB5BC; 25 | $light: #E5E9EC; 26 | $white: #fff; 27 | 28 | $white20: rgba(255, 255, 255, .2); 29 | $white50: rgba(255, 255, 255, .5); 30 | $white80: rgba(255, 255, 255, .8); 31 | 32 | $black20: rgba(0, 0, 0, .2); 33 | $black50: rgba(0, 0, 0, .5); 34 | $black80: rgba(0, 0, 0, .8); -------------------------------------------------------------------------------- /src/nuomi/vue1/Observer.js: -------------------------------------------------------------------------------- 1 | export default class Observer { 2 | constructor (obj) { 3 | this.obj = obj; 4 | this.data = {}; 5 | 6 | this.walk(obj); 7 | } 8 | 9 | walk (obj) { 10 | Object.keys(obj).forEach(key => { 11 | Object.defineProperty(this.data, key, { 12 | enumerable: true, 13 | configurable: false, 14 | get: () => { 15 | console.log(`你访问了 ${key}`); 16 | return this.obj[key]; 17 | }, 18 | set: (newVal) => { 19 | console.log(`你设置了 ${key},新的值为 ${newVal}`); 20 | this.obj[key] = newVal; 21 | }, 22 | }); 23 | }) 24 | } 25 | } -------------------------------------------------------------------------------- /src/nuomi/vue5/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g, CONST } from '../../gtool'; 3 | import './style.scss'; 4 | import Observer from './Observer'; 5 | import Vue from './Vue'; 6 | 7 | export function create (parent, option = []) { 8 | parent = typeof parent === 'string' ? g.$(parent) : parent; 9 | 10 | parent.innerHTML = template; 11 | 12 | let app = new Vue({ 13 | el: '#vue-content', 14 | data: { 15 | user: { 16 | name: 'Geeku', 17 | age: 24 18 | }, 19 | click: 0 20 | } 21 | }); 22 | 23 | window.app = app; 24 | 25 | g.$('#clickme').addEventListener('click', e => { 26 | app.data.click += 1; 27 | }); 28 | 29 | } -------------------------------------------------------------------------------- /src/nuomi/vue1/style.scss: -------------------------------------------------------------------------------- 1 | .console { 2 | 3 | position: absolute; 4 | left: 50%; 5 | top: 50%; 6 | transform: translate(-50%, -50%); 7 | overflow: hidden; 8 | background: #eee; 9 | border-radius: 3px; 10 | width: 60%; 11 | max-height: 60%; 12 | overflow: auto; 13 | 14 | div { 15 | padding: 5px 8px; 16 | background: #223348; 17 | border-bottom: 1px solid #404446; 18 | color: #fff; 19 | 20 | span { 21 | color: rgba(255,255,255,.4); 22 | margin-right: 5px; 23 | } 24 | 25 | &.command { 26 | color: #8fb0bb; 27 | } 28 | } 29 | input { 30 | border: none; 31 | width: 100%; 32 | background: #404446; 33 | padding: 5px 10px; 34 | outline: none; 35 | color: #eee; 36 | } 37 | } -------------------------------------------------------------------------------- /src/nuomi/slider/style.scss: -------------------------------------------------------------------------------- 1 | .slider { 2 | position: absolute; 3 | width: 100%; 4 | height: 100%; 5 | padding: 1rem 6 | } 7 | .slider-wrap { 8 | perspective: 10rem; 9 | width: 100%; 10 | height: 100%; 11 | position: relative; 12 | display: flex; 13 | justify-content: center; 14 | align-items: center; 15 | .slider-cover { 16 | transform-style: preserve-3d; 17 | display: flex; 18 | justify-content: center; 19 | align-items: center; 20 | flex: 1; 21 | transition: transform .2s ease-in-out; 22 | } 23 | 24 | img { 25 | position: absolute; 26 | // opacity: .9; 27 | } 28 | 29 | @for $i from 0 through 5 { 30 | img:nth-child(#{$i + 1}) { 31 | transform: rotateY(60deg * $i) translate3d(0, 0, 2.8rem) scale(.8); 32 | } 33 | } 34 | 35 | button { 36 | background: #0d47a1; 37 | } 38 | } -------------------------------------------------------------------------------- /src/nuomi/markdown/template.html: -------------------------------------------------------------------------------- 1 |
2 | 50 | 51 |
52 |
53 |
54 |
55 |
56 |
57 | 58 |
-------------------------------------------------------------------------------- /src/nuomi/player/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('./font/iconfont.eot?t=1488617243886'); /* IE9*/ 3 | src: url('./font/iconfont.eot?t=1488617243886#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('./font/iconfont.woff?t=1488617243886') format('woff'), /* chrome, firefox */ 5 | url('./font/iconfont.ttf?t=1488617243886') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ 6 | url('./font/iconfont.svg?t=1488617243886#iconfont') format('svg'); /* iOS 4.1- */ 7 | } 8 | 9 | [class*=icon] { 10 | font-family:"iconfont" !important; 11 | font-size:16px; 12 | font-style:normal; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | } 16 | 17 | .icon-close:before { content: "\e641"; } 18 | 19 | .icon-unlike:before { content: "\e643"; } 20 | 21 | .icon-delete:before { content: "\e645"; } 22 | 23 | .icon-volume:before { content: "\e64c"; } 24 | 25 | .icon-list:before { content: "\e655"; } 26 | 27 | .icon-next:before { content: "\e65f"; } 28 | 29 | .icon-previous:before { content: "\e660"; } 30 | 31 | .icon-like:before { content: "\e684"; } 32 | 33 | -------------------------------------------------------------------------------- /src/createEntries.js: -------------------------------------------------------------------------------- 1 | import { g } from './gtool'; 2 | 3 | import taskList from './taskList.json'; 4 | 5 | const entries = taskList; 6 | 7 | export default function createEntries (parent) { 8 | parent = typeof parent === 'string' ? g.$(parent) : parent; 9 | 10 | const entriesList = []; 11 | entries.forEach(topLevel => { 12 | 13 | const topLevelList = []; 14 | const ul = new g.vdom('ul'); 15 | const title = new g.vdom('li', {}, [ topLevel.title ]); 16 | 17 | topLevel.tasks.forEach(task => { 18 | 19 | const taskList = new g.vdom('li', { 20 | class: task.completed ? 'completed' : '' 21 | }, [ task.title ]); 22 | 23 | taskList.addEvent('click', e => { 24 | location.hash = '!/' + task.name; 25 | // Handler[task.name](e); 26 | }); 27 | 28 | topLevelList.push(taskList); 29 | }); 30 | 31 | ul.addChildren(topLevelList); 32 | entriesList.push(title, ul); 33 | }) 34 | 35 | const ul = new g.vdom('ul', {}, entriesList); 36 | parent.appendChild(ul.render()); 37 | } -------------------------------------------------------------------------------- /src/nuomi/contextMenu/index.js: -------------------------------------------------------------------------------- 1 | import { g } from '../../gtool'; 2 | import template from './template.html'; 3 | import ContextMenu from './ContextMenu'; 4 | import './style.scss'; 5 | 6 | export function create (parent, option = []) { 7 | parent = typeof parent === 'string' ? g.$(parent) : parent; 8 | 9 | // console.log(html); 10 | parent.innerHTML = template; 11 | 12 | const container = g.$('.contentMenu', parent); 13 | new ContextMenu(container, defaultOption); 14 | } 15 | 16 | const defaultOption = { 17 | class: 'context-menu', 18 | items: [ 19 | { 20 | type: 'link', 21 | title: '百度', 22 | content: 'https://www.baidu.com', 23 | target: '_blank' 24 | }, 25 | { 26 | type: 'separator', 27 | }, 28 | { 29 | type: 'function', 30 | title: 'Alert', 31 | content: () => alert(1) 32 | }, 33 | { 34 | type: 'link', 35 | title: 'Disabled', 36 | disabled: true 37 | }, 38 | { 39 | type: 'text', 40 | title: 'Plain Text', 41 | class: 'plain' 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /src/nuomi/contextMenu/ContextMenu.scss: -------------------------------------------------------------------------------- 1 | .g-contextMenu { 2 | background: #fff; 3 | display: none; 4 | border-radius: 3px; 5 | margin: 0; 6 | padding: 5px 0; 7 | list-style: none; 8 | min-width: 200px; 9 | position: fixed; 10 | border: 1px solid #ccc; 11 | box-shadow: 1px 1px 2px rgba(0,0,0,0.2); 12 | 13 | &.show { 14 | display: inline-block; 15 | } 16 | &.hide { 17 | display: none; 18 | } 19 | 20 | li { 21 | padding: 5px 10px; 22 | color: #333; 23 | 24 | &:hover { 25 | background: #eee; 26 | } 27 | } 28 | 29 | li.separator { 30 | border-bottom: 1px solid #eee; 31 | padding: 0; 32 | margin: 5px 0; 33 | &:hover { 34 | background: transparent; 35 | } 36 | } 37 | 38 | li.disabled { 39 | color: #999; 40 | cursor: not-allowed; 41 | &:hover { 42 | background: transparent; 43 | } 44 | 45 | a { 46 | color: #999; 47 | cursor: not-allowed 48 | } 49 | } 50 | 51 | a { 52 | color: #333; 53 | text-decoration: none; 54 | display: block; 55 | } 56 | } -------------------------------------------------------------------------------- /src/nuomi/player/template.html: -------------------------------------------------------------------------------- 1 |
2 | 35 | 36 | 37 |
-------------------------------------------------------------------------------- /src/nuomi/collapse/style.scss: -------------------------------------------------------------------------------- 1 | .collapse { 2 | position: absolute; 3 | left: 50%; 4 | top: 50%; 5 | transform: translate(-50%, -50%); 6 | // overflow: hidden; 7 | // background: #eee; 8 | // border-radius: 3px; 9 | width: 60%; 10 | 11 | section { 12 | margin: .1rem .1rem; 13 | background: #fff; 14 | border: 1px solid #eee; 15 | border-radius: .03rem; 16 | } 17 | .content { 18 | // height: 0; 19 | // display: none; 20 | padding: 0; 21 | max-height: 0; 22 | overflow: hidden; 23 | transition: max-height .2s cubic-bezier(0, 1, 1, 1); 24 | // transition-delay: .2s; 25 | // box-sizing: border-box; 26 | } 27 | .cover { 28 | padding: .1rem .15rem; 29 | } 30 | label { 31 | display: block; 32 | background: #eee; 33 | padding: .1rem .15rem; 34 | font-size: .16rem; 35 | cursor: pointer; 36 | } 37 | input[type=radio] { 38 | display: none; 39 | 40 | &:checked { 41 | & + .content { 42 | // padding: .1rem .15rem; 43 | max-height: 300px; 44 | transition: max-height .2s cubic-bezier(1, 1, 1, 1); 45 | // display: block; 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /docs/commons.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var n=window.webpackJsonp;window.webpackJsonp=function(t,i,u){for(var c,a,f,l=0,s=[];l { 18 | console.log(`你访问了 ${key}`); 19 | return val; 20 | }, 21 | set: (newVal) => { 22 | 23 | if (typeof newVal === 'object') { 24 | this.walk(newVal); 25 | } 26 | console.log(`你设置了 ${key},新的值为 ${newVal}`); 27 | 28 | // console.log('watchers', this.watchers[key]); 29 | if (this.watchers[key]) { 30 | this.watchers[key](newVal); 31 | } 32 | val = newVal; 33 | }, 34 | }); 35 | } 36 | 37 | walk (data) { 38 | // console.log(data); 39 | if (!data || typeof data !== 'object') { 40 | return; 41 | } 42 | 43 | Object.keys(data).forEach(key => { 44 | this.observe(data, key, data[key]); 45 | }); 46 | } 47 | 48 | $watch (prop, callback = () => {}) { 49 | this.watchers[prop] = callback; 50 | } 51 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ife2017", 3 | "version": "1.0.0", 4 | "main": "webpack.config.js", 5 | "devDependencies": {}, 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base", 9 | "build": "NODE_ENV='production' webpack -p --progress --colors" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "description": "", 14 | "dependencies": { 15 | "autoprefixer": "^6.6.1", 16 | "babel-core": "^6.21.0", 17 | "babel-eslint": "^7.1.1", 18 | "babel-loader": "^6.2.10", 19 | "babel-polyfill": "^6.20.0", 20 | "babel-preset-es2015": "^6.18.0", 21 | "babel-preset-stage-0": "^6.16.0", 22 | "babel-preset-stage-2": "^6.18.0", 23 | "copy-webpack-plugin": "^4.0.1", 24 | "css-loader": "^0.26.1", 25 | "eslint": "^3.12.2", 26 | "eslint-loader": "^1.6.1", 27 | "eslint-plugin-babel": "^4.0.0", 28 | "extract-text-webpack-plugin": "^2.0.0-beta", 29 | "file-loader": "^0.9.0", 30 | "gmd-markdown-parser": "^0.0.2", 31 | "html-loader": "^0.4.4", 32 | "html-webpack-plugin": "^2.26.0", 33 | "node-sass": "^4.1.1", 34 | "planktos": "^0.3.0", 35 | "postcss-loader": "^1.2.1", 36 | "postcss-scss": "^0.4.0", 37 | "precss": "^1.4.0", 38 | "sass-loader": "^4.1.1", 39 | "style-loader": "^0.13.1", 40 | "webpack": "^1.14.0", 41 | "webpack-dev-server": "^1.16.2" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/nuomi/vue5/Vue.js: -------------------------------------------------------------------------------- 1 | import { g, CONST } from '../../gtool'; 2 | import Observer from './Observer'; 3 | import Watcher from './Watcher'; 4 | import Publisher from './Publisher'; 5 | 6 | const NODE_TYPE = { 7 | element: 1, 8 | text: 3, 9 | comment: 8 10 | }; 11 | 12 | const moustache = /({{(.*?)}})/g; 13 | export default class Vue { 14 | constructor (option) { 15 | this.data = option.data; 16 | this.el = (typeof option.el === 'string') ? g.$(option.el) : option.el; 17 | 18 | this.publisher = new Publisher(); 19 | 20 | this.observer = new Observer(this.data, this.publisher); 21 | 22 | this.parseHTML(this.el); 23 | } 24 | 25 | parseHTML (html) { 26 | 27 | const fragment = document.createDocumentFragment(); 28 | let node; 29 | while (node = html.firstChild) { 30 | 31 | let content = ''; 32 | if (node.nodeType === NODE_TYPE.element) { 33 | content = node.innerText; 34 | } 35 | if (node.nodeType === NODE_TYPE.text) { 36 | content = node.nodeValue; 37 | } 38 | 39 | const match = moustache.test(content); 40 | if (match) { 41 | new Watcher(this.data, node, this.publisher); 42 | } 43 | 44 | fragment.appendChild(node); 45 | } 46 | 47 | this.el.appendChild(fragment); 48 | } 49 | 50 | $watch (name, callback) { 51 | this.observer.$watch(name, callback); 52 | } 53 | } -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Document

Geeku & IFE2017

-------------------------------------------------------------------------------- /src/nuomi/player/font.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src: url('fonts/icomoon.eot?59m82g'); 4 | src: url('fonts/icomoon.eot?59m82g#iefix') format('embedded-opentype'), 5 | url('fonts/icomoon.ttf?59m82g') format('truetype'), 6 | url('fonts/icomoon.woff?59m82g') format('woff'), 7 | url('fonts/icomoon.svg?59m82g#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], [class*=" icon-"] { 13 | /* use !important to prevent issues with browser extensions that change fonts */ 14 | font-family: 'icomoon' !important; 15 | speak: none; 16 | font-style: normal; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | 22 | /* Better Font Rendering =========== */ 23 | -webkit-font-smoothing: antialiased; 24 | -moz-osx-font-smoothing: grayscale; 25 | } 26 | 27 | .icon-pc:before { 28 | content: "\e956"; 29 | } 30 | .icon-delete:before { 31 | content: "\e9ac"; 32 | } 33 | .icon-list:before { 34 | content: "\e9ba"; 35 | } 36 | .icon-lyric:before { 37 | content: "\e9bd"; 38 | } 39 | .icon-link:before { 40 | content: "\e9cb"; 41 | } 42 | .icon-like:before { 43 | content: "\e9da"; 44 | } 45 | .icon-play:before { 46 | content: "\ea1c"; 47 | } 48 | .icon-pause:before { 49 | content: "\ea1d"; 50 | } 51 | .icon-backward:before { 52 | content: "\ea1f"; 53 | } 54 | .icon-forward:before { 55 | content: "\ea20"; 56 | } 57 | .icon-volume:before { 58 | content: "\ea27"; 59 | } 60 | .icon-volume-mute:before { 61 | content: "\ea2a"; 62 | } 63 | .icon-loop:before { 64 | content: "\ea2d"; 65 | } 66 | .icon-shuffle:before { 67 | content: "\ea30"; 68 | } 69 | .icon-share:before { 70 | content: "\1f32b"; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 |
34 |
35 | 36 | 37 | 38 |

Geeku & IFE2017

39 | 40 |
41 | 42 |
43 | 44 |
45 |
46 |
47 | 48 | 49 |
50 | 51 |
52 |
53 | 54 | 55 |
56 | 57 | 58 | 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /docs/13.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([13,15],{121:function(e,n,t){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function o(e){if(Array.isArray(e)){for(var n=0,t=Array(e.length);n1&&void 0!==arguments[1]?arguments[1]:[];e="string"==typeof e?u.g.$(e):e,e.innerHTML=l.default,c(i)}function i(){var e=window.THREE,n=new e.WebGLRenderer({canvas:u.g.$("#mainCanvas"),antialias:!0});n.setClearColor(13421772),n.shadowMapEnabled=!0;var t=window.scene=new e.Scene,a=new THREE.PerspectiveCamera(30,4/3,1,1e3);a.position.set(60,70,60),t.add(a),a.lookAt(new e.Vector3(-50,0,-50));var o=new e.MeshLambertMaterial({color:13421772}),r=new e.PlaneGeometry(260,260),i=new e.Mesh(r,new e.MeshLambertMaterial({color:4473924}));t.add(i),i.rotation.x=80,i.position.set(-50,5,-50),i.receiveShadow=!0;var c=new e.Mesh(new e.CubeGeometry(40,20,20),o);t.add(c),c.position.set(-10,30,0),c.castShadow=!0;var d=s();d.forEach(function(e){t.add(e)});var l=new THREE.PointLight(16777215);l.position.set(100,100,50),t.add(l),l.castShadow=!0;var p=new THREE.DirectionalLight(16777215,.6);p.position.set(0,100,200),t.add(p),p.castShadow=!0,n.render(t,a)}function s(){for(var e=new THREE.MeshLambertMaterial({color:13421772}),n=new THREE.TorusGeometry(5,2,20,20),t=[],a=[[0,20,10],[-20,20,10],[0,20,-10],[-20,20,-10]],r=0;r<4;r++){var i,s=new THREE.Mesh(n,e);(i=s.position).set.apply(i,o(a[r])),s.castShadow=!0,t.push(s)}return t}function c(e){var n=document.createElement("script");n.src="//cdn.bootcss.com/three.js/r83/three.min.js",n.async=!0,n.addEventListener("load",function(){e()}),document.body.appendChild(n)}Object.defineProperty(n,"__esModule",{value:!0}),n.create=r;var d=t(373),l=a(d),u=t(59);t(355)},342:function(e,n,t){n=e.exports=t(318)(),n.push([e.i,"#mainCanvas{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}",""])},355:function(e,n,t){var a=t(342);"string"==typeof a&&(a=[[e.i,a,""]]);t(319)(a,{});a.locals&&(e.exports=a.locals)},373:function(e,n){e.exports=" "}}); 2 | //# sourceMappingURL=13.index.js.map -------------------------------------------------------------------------------- /docs/10.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([10,15],{128:function(t,e,r){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function s(t){arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];t="string"==typeof t?n.g.$(t):t,t.innerHTML=l.default;var e=0,r=n.g.$(".slider-cover");n.g.$(".previous").addEventListener("click",function(){n.g.css(r,"transform: rotateY("+(e+=60)+"deg)")}),n.g.$(".next").addEventListener("click",function(){n.g.css(r,"transform: rotateY("+(e-=60)+"deg)")})}Object.defineProperty(e,"__esModule",{value:!0}),e.create=s;var a=r(380),l=i(a),n=r(59);r(363)},350:function(t,e,r){e=t.exports=r(318)(),e.push([t.i,".slider{position:absolute;width:100%;height:100%;padding:1rem}.slider-wrap{perspective:10rem;width:100%;height:100%;position:relative}.slider-wrap,.slider-wrap .slider-cover{display:flex;justify-content:center;align-items:center}.slider-wrap .slider-cover{transform-style:preserve-3d;flex:1;transition:transform .2s ease-in-out}.slider-wrap img{position:absolute}.slider-wrap img:first-child{transform:rotateY(0deg) translateZ(2.8rem) scale(.8)}.slider-wrap img:nth-child(2){transform:rotateY(60deg) translateZ(2.8rem) scale(.8)}.slider-wrap img:nth-child(3){transform:rotateY(120deg) translateZ(2.8rem) scale(.8)}.slider-wrap img:nth-child(4){transform:rotateY(180deg) translateZ(2.8rem) scale(.8)}.slider-wrap img:nth-child(5){transform:rotateY(240deg) translateZ(2.8rem) scale(.8)}.slider-wrap img:nth-child(6){transform:rotateY(300deg) translateZ(2.8rem) scale(.8)}.slider-wrap button{background:#0d47a1}",""])},363:function(t,e,r){var i=r(350);"string"==typeof i&&(i=[[t.i,i,""]]);r(319)(i,{});i.locals&&(t.exports=i.locals)},380:function(t,e){t.exports='
'}}); 2 | //# sourceMappingURL=10.index.js.map -------------------------------------------------------------------------------- /src/nuomi/phantomjs/task.js: -------------------------------------------------------------------------------- 1 | const webpage = require('webpage'); 2 | const page = webpage.create(); 3 | const system = require('system'); 4 | const keyword = encodeURIComponent(system.args[1]); 5 | const urlTemplate = 'https://www.baidu.com/s?wd='; 6 | 7 | // console.log('keycode:' , keyword); 8 | 9 | // page.onConsoleMessage = function (msg) { 10 | // console.log(msg); 11 | // }; 12 | 13 | // console.log('page'); 14 | 15 | const startTime = new Date(); 16 | page.onError = function(err) { 17 | // console.log(err); 18 | }; 19 | phantom.onError = function(err) { 20 | // console.log(err); 21 | }; 22 | try { 23 | const retData = { 24 | code: -1, 25 | msg: 'Failed', 26 | keyword: decodeURIComponent(keyword), 27 | time: 0, 28 | dataList: [] 29 | } 30 | page.open(urlTemplate + keyword, function (status) { 31 | if (status !== 'success') { 32 | throw new Error('Failed'); 33 | } 34 | // console.log('page'); 35 | const content = page.evaluate(function() { 36 | const items = $('.result.c-container, .result-op.c-container').map(function(_, item) { 37 | return { 38 | title: $(item).find('h3 a:first-child').text() || '', 39 | info: $(item).find('p,.op_kefu_table').text().trim().replace(/[\s]/g, '') || '', 40 | link: $(item).find('h3 a:first-child').attr('href') || '', 41 | pic: $(item).find('img').attr('src') || '' 42 | } 43 | }); 44 | 45 | return items.toArray(); 46 | }); 47 | 48 | retData.code = 1; 49 | retData.msg = "successful"; 50 | retData.time = (new Date()) - startTime; 51 | retData.dataList = content; 52 | 53 | console.log(JSON.stringify(retData, null, ' ')); 54 | 55 | // console.log(content); 56 | 57 | phantom.exit(); 58 | }); 59 | } catch (err) { 60 | console.log(err); 61 | phantom.exit(); 62 | // retData.msg = JSON.stringify(err, null, ' '); 63 | // retData.time = (new Date()) - startTime; 64 | 65 | // console.log(JSON.stringify(retData, null, ' ')); 66 | } 67 | // phantom.exit(); -------------------------------------------------------------------------------- /src/nuomi/vue4/Vue.js: -------------------------------------------------------------------------------- 1 | import { g, CONST } from '../../gtool'; 2 | import Observer from './Observer'; 3 | 4 | const NODE_TYPE = { 5 | element: 1, 6 | text: 3, 7 | comment: 8 8 | }; 9 | 10 | export default class Vue { 11 | constructor (option) { 12 | this.data = option.data; 13 | this.el = (typeof option.el === 'string') ? g.$(option.el) : option.el; 14 | 15 | this.moustache = /({{(.*?)}})/g; 16 | 17 | new Observer(this.data); 18 | 19 | this.parseHTML(this.el); 20 | } 21 | 22 | render (node) { 23 | if (node.nodeType === NODE_TYPE.element) { 24 | 25 | node.innerText = this.replaceContent(node.innerText); 26 | } 27 | if (node.nodeType === NODE_TYPE.text) { 28 | 29 | node.nodeValue = this.replaceContent(node.nodeValue); 30 | } 31 | } 32 | 33 | replaceContent (target) { 34 | const mathes = target.match(this.moustache); 35 | 36 | if (mathes && mathes.length) { 37 | 38 | let result = target; 39 | mathes.forEach(matchItem => { 40 | 41 | matchItem.match(this.moustache); 42 | 43 | const orignialText = (RegExp.$1).trim(); 44 | const variable = (RegExp.$2).trim(); 45 | const replacedText = this.stringToData(variable); 46 | 47 | result = result.replace(orignialText, replacedText); 48 | }); 49 | return result; 50 | } 51 | } 52 | 53 | parseHTML (html) { 54 | 55 | const fragment = document.createDocumentFragment(); 56 | let node; 57 | while (node = html.firstChild) { 58 | this.render(node); 59 | fragment.appendChild(node); 60 | } 61 | 62 | this.el.appendChild(fragment); 63 | } 64 | 65 | stringToData (string) { 66 | try { 67 | const arr = string.trim().split('.'); 68 | if (arr.length === 1) { 69 | return this.data[arr[0]]; 70 | } 71 | return arr.reduce((x, y) => { 72 | return this.data[x][y]; 73 | }); 74 | } catch (e) { 75 | return ''; 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /docs/11.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([11,15],{125:function(e,r,t){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function a(e){arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];e="string"==typeof e?d.g.$(e):e,e.innerHTML=o.default}Object.defineProperty(r,"__esModule",{value:!0}),r.create=a;var i=t(377),o=n(i),d=t(59);t(360)},347:function(e,r,t){r=e.exports=t(318)(),r.push([e.i,'.loadings{width:100%;height:100%;background:#23272d}.loadings .loading-wrap{position:absolute;width:1rem;height:1rem;left:50%;top:50%;transform:translate(-50%,-50%);overflow:hidden}.loadings .outside{width:0;height:0;border:.5rem solid #54dd70;border-bottom-color:transparent;border-radius:50%;position:absolute;top:0;left:0;animation:outRotate .8s infinite linear;will-change:transform}.loadings .outside:before{content:"";position:absolute;width:.94rem;height:.94rem;background:#23272d}.loadings .inside,.loadings .outside:before{left:50%;top:50%;transform:translate(-50%,-50%);border-radius:50%}.loadings .inside{width:.5rem;height:.5rem;position:relative;color:#a9eeb7;overflow:hidden;animation:underChangeBG 1.6s infinite steps(1);will-change:transform}.loadings .inside:before{content:"";position:absolute;background-image:linear-gradient(90deg,transparent 50%,currentColor 0);width:100%;height:100%;animation:rotate .8s infinite linear,changeBG 1.6s infinite steps(1);will-change:transform}@keyframes rotate{0%{transform:rotate(1turn)}to{transform:rotate(0deg)}}@keyframes outRotate{0%{transform:rotate(315deg)}to{transform:rotate(-45deg)}}@keyframes changeBG{0%{background-image:linear-gradient(90deg,transparent 50%,currentColor 0)}25%{background-image:linear-gradient(90deg,#54dd70 50%,transparent 0)}50%{background-image:linear-gradient(90deg,transparent 50%,#54dd70 0)}75%{background-image:linear-gradient(90deg,currentColor 50%,transparent 0)}to{background-image:linear-gradient(90deg,transparent 50%,currentColor 0)}}@keyframes underChangeBG{0%{background-image:linear-gradient(90deg,currentColor 50%,#54dd70 0)}50%{background-image:linear-gradient(90deg,#54dd70 50%,currentColor 0)}}',""])},360:function(e,r,t){var n=t(347);"string"==typeof n&&(n=[[e.i,n,""]]);t(319)(n,{});n.locals&&(e.exports=n.locals)},377:function(e,r){e.exports="
"}}); 2 | //# sourceMappingURL=11.index.js.map -------------------------------------------------------------------------------- /src/nuomi/vue5/Watcher.js: -------------------------------------------------------------------------------- 1 | const moustache = /({{(.*?)}})/g; 2 | 3 | const NODE_TYPE = { 4 | element: 1, 5 | text: 3, 6 | comment: 8 7 | }; 8 | 9 | export default class Watcher { 10 | constructor (data, node, publisher) { 11 | this.node = node; 12 | this.name = []; 13 | this.oldVal = {}; 14 | this.data = data; 15 | this.publisher = publisher; 16 | this.nodeType = node.nodeType; 17 | 18 | this.publisher.add(this); 19 | 20 | this.init(); 21 | } 22 | 23 | init () { 24 | let content = ''; 25 | if (this.nodeType === NODE_TYPE.element) { 26 | content = this.node.innerText; 27 | } 28 | if (this.nodeType === NODE_TYPE.text) { 29 | content = this.node.nodeValue; 30 | } 31 | const mathes = content.match(moustache); 32 | if (mathes && mathes.length) { 33 | mathes.forEach(matchItem => { 34 | 35 | const orignialText = (RegExp.$1).trim(); 36 | const name = (RegExp.$2).trim(); 37 | 38 | this.oldVal[name] = orignialText; 39 | 40 | this.name.push(name); 41 | }); 42 | } 43 | 44 | this.update(); 45 | } 46 | 47 | update () { 48 | this.render(); 49 | } 50 | 51 | render () { 52 | if (this.nodeType === NODE_TYPE.element) { 53 | this.node.innerText = this.replaceContent(this.node.innerText); 54 | } 55 | if (this.nodeType === NODE_TYPE.text) { 56 | this.node.nodeValue = this.replaceContent(this.node.nodeValue); 57 | } 58 | } 59 | 60 | replaceContent (original) { 61 | this.name.forEach(name => { 62 | const curVal = this.getData(name); 63 | original = original.replace(this.oldVal[name], curVal); 64 | 65 | this.oldVal[name] = curVal; 66 | }); 67 | return original; 68 | } 69 | 70 | getData (string) { 71 | try { 72 | const arr = string.trim().split('.'); 73 | if (arr.length === 1) { 74 | return this.data[arr[0]]; 75 | } 76 | return arr.reduce((x, y) => { 77 | return this.data[x][y]; 78 | }); 79 | } catch (e) { 80 | return ''; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/nuomi/vue3/Observer.js: -------------------------------------------------------------------------------- 1 | class ObEventHandler { 2 | constructor () { 3 | this.changeMethods = {}; 4 | } 5 | 6 | onChange (name, callback = () => {}) { 7 | this.changeMethods[name] = callback; 8 | } 9 | 10 | callChangeMethods (name, newVal = '') { 11 | name in this.changeMethods && this.changeMethods[name](newVal); 12 | } 13 | 14 | bubbling (path, newVal) { 15 | 16 | const pathArray = path.slice(0, path.length - 1).split('.'); 17 | const length = pathArray.length; 18 | 19 | // Call same path name's function,eg '['a.b.c.d']()' 20 | this.callChangeMethods(path, newVal); 21 | 22 | if (length) { 23 | 24 | // Call each path name's function, eg '['a'](), ['b']() ...' 25 | pathArray.forEach(pathName => { 26 | this.callChangeMethods(pathName, newVal); 27 | }); 28 | 29 | // Call parent path name's function,, eg '['a.b.c'](), ['a.b']() ...' 30 | for (let i = pathArray.length - 1; i >= 2 ; i--) { 31 | const pathSlice = pathArray.slice(0, i); 32 | this.callChangeMethods(pathSlice.join('.'), newVal); 33 | } 34 | } 35 | } 36 | } 37 | 38 | export default class Observer { 39 | 40 | constructor (data) { 41 | this.originalData = this.data = data; 42 | 43 | this.handler = new ObEventHandler(); 44 | 45 | this.observe(this.originalData); 46 | } 47 | 48 | observe (data) { 49 | this.checkData(data); 50 | } 51 | 52 | checkData (data, path = '') { 53 | if (typeof data === 'object') { 54 | Object.keys(data).forEach(key => { 55 | this.initProperty(data, key, data[key], path); 56 | }); 57 | } 58 | } 59 | 60 | initProperty (data, key, val, path) { 61 | 62 | path += key + '.'; 63 | 64 | this.checkData(val, path); 65 | 66 | Object.defineProperty(data, key, { 67 | enumerable: true, 68 | configurable: false, 69 | get: () => { 70 | return val; 71 | }, 72 | set: newVal => { 73 | this.checkData(newVal, parent); 74 | this.handler.bubbling(path, newVal); 75 | val = newVal; 76 | } 77 | }); 78 | } 79 | 80 | $watch (name, callback = () => {}) { 81 | this.handler.onChange(name, callback); 82 | } 83 | } -------------------------------------------------------------------------------- /src/nuomi/vue4/Observer.js: -------------------------------------------------------------------------------- 1 | class ObEventHandler { 2 | constructor () { 3 | this.changeMethods = {}; 4 | } 5 | 6 | onChange (name, callback = () => {}) { 7 | this.changeMethods[name] = callback; 8 | } 9 | 10 | callChangeMethods (name, newVal = '') { 11 | name in this.changeMethods && this.changeMethods[name](newVal); 12 | } 13 | 14 | bubbling (path, newVal) { 15 | 16 | const pathArray = path.slice(0, path.length - 1).split('.'); 17 | const length = pathArray.length; 18 | 19 | // Call same path name's function,eg '['a.b.c.d']()' 20 | this.callChangeMethods(path, newVal); 21 | 22 | if (length) { 23 | 24 | // Call each path name's function, eg '['a'](), ['b']() ...' 25 | pathArray.forEach(pathName => { 26 | this.callChangeMethods(pathName, newVal); 27 | }); 28 | 29 | // Call parent path name's function,, eg '['a.b.c'](), ['a.b']() ...' 30 | for (let i = pathArray.length - 1; i >= 2 ; i--) { 31 | const pathSlice = pathArray.slice(0, i); 32 | this.callChangeMethods(pathSlice.join('.'), newVal); 33 | } 34 | } 35 | } 36 | } 37 | 38 | export default class Observer { 39 | 40 | constructor (data) { 41 | this.originalData = this.data = data; 42 | 43 | this.handler = new ObEventHandler(); 44 | 45 | this.observe(this.originalData); 46 | } 47 | 48 | observe (data) { 49 | this.checkData(data); 50 | } 51 | 52 | checkData (data, path = '') { 53 | if (typeof data === 'object') { 54 | Object.keys(data).forEach(key => { 55 | this.initProperty(data, key, data[key], path); 56 | }); 57 | } 58 | } 59 | 60 | initProperty (data, key, val, path) { 61 | 62 | path += key + '.'; 63 | 64 | this.checkData(val, path); 65 | 66 | Object.defineProperty(data, key, { 67 | enumerable: true, 68 | configurable: false, 69 | get: () => { 70 | return val; 71 | }, 72 | set: newVal => { 73 | this.checkData(newVal, parent); 74 | this.handler.bubbling(path, newVal); 75 | val = newVal; 76 | } 77 | }); 78 | } 79 | 80 | $watch (name, callback = () => {}) { 81 | this.handler.onChange(name, callback); 82 | } 83 | } -------------------------------------------------------------------------------- /src/nuomi/vue1/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g, CONST } from '../../gtool'; 3 | import '../vue2/style.scss'; 4 | import Observer from './Observer'; 5 | 6 | export function create (parent, option = []) { 7 | parent = typeof parent === 'string' ? g.$(parent) : parent; 8 | 9 | parent.innerHTML = template; 10 | 11 | const oldConsole = console.log; 12 | const outputList = []; 13 | console.log = (output, isCommand = false) => { 14 | if (isCommand) { 15 | outputList.push(`
> ${output}
`); 16 | } else { 17 | outputList.push(`
< ${output}
`); 18 | } 19 | }; 20 | 21 | console.log(`let app1 = new Observer({ 22 | name: 'youngwind', 23 | age: 25 24 | });`, true); 25 | let app1 = new Observer({ 26 | name: 'youngwind', 27 | age: 25 28 | }); 29 | // console.log 30 | console.log('app1.data.name', true); 31 | app1.data.name // 你访问了 name 32 | console.log('app1.data.age = 100;', true); 33 | app1.data.age = 100; // 你设置了 age,新的值为100 34 | 35 | playCommand(outputList); 36 | 37 | console.log = (output, isCommand = false) => { 38 | if (isCommand) { 39 | addList(`
> ${output}
`); 40 | } else { 41 | addList(`
< ${output}
`); 42 | } 43 | }; 44 | const input = g.$('.console input'); 45 | input.addEventListener('keyup', e => { 46 | if (e.keyCode === CONST.KEY_CODE.ENTER) { 47 | 48 | const command = input.value; 49 | console.log(command, true); 50 | 51 | if (/app1\.data\.(\w+)+?\s?=?('.*?')?/.test(command)) { 52 | eval(command); 53 | } else { 54 | console.log("[warning] Command illegal"); 55 | } 56 | 57 | input.value = ''; 58 | } 59 | }); 60 | 61 | // console.log = oldConsole; 62 | } 63 | 64 | async function playCommand (outputList) { 65 | // console.log(outputList); 66 | for(let i = 0; i < outputList.length; i++) { 67 | await new Promise((r, j) => { setTimeout(() => { r() } , 200); }); 68 | await addList(outputList[i]); 69 | } 70 | } 71 | 72 | function addList (output) { 73 | const outputEle = g.$('.console .output'); 74 | outputEle.innerHTML += output; 75 | outputEle.scrollTop = outputEle.scrollHeight; 76 | } -------------------------------------------------------------------------------- /src/nuomi/collapse/template.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 | 7 |
8 | 9 |
10 |
11 | 这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, 12 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. 13 | Sapiente placeat, nam consequatur dolorum。 14 |
15 |
16 |
17 |
18 |
19 | 20 |
21 | 22 |
23 |
24 | 这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, 25 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. 26 | Sapiente placeat, nam consequatur dolorum。 27 | 这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, 28 | cum nihil voluptate, 29 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. 30 | Sapiente placeat, nam consequatur dolorum。 31 | 这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, 32 | cum nihil voluptate, 33 | odio explicabo o 34 | odio explicabo omnis, eveniet autem voluptas maiores culpa iure nesciunt quo quod magnam adipisci! 35 |
36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 | 这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, 46 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. 47 | Sapiente placeat, nam consequatur dolorum。 48 | 这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, 49 | cum nihil voluptate, 50 | odio explicabo omnis, eveniet autem voluptas maiores culpa iure nesciunt quo quod magnam adipisci! 51 |
52 |
53 |
54 |
55 | 56 |
-------------------------------------------------------------------------------- /docs/12.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([12,15],{122:function(e,i,o){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function t(e){arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];e="string"==typeof e?s.g.$(e):e,e.innerHTML=c.default}Object.defineProperty(i,"__esModule",{value:!0}),i.create=t;var l=o(374),c=a(l),s=o(59);o(356)},343:function(e,i,o){i=e.exports=o(318)(),i.push([e.i,".collapse{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:60%}.collapse section{margin:.1rem;background:#fff;border:1px solid #eee;border-radius:.03rem}.collapse .content{padding:0;max-height:0;overflow:hidden;transition:max-height .2s cubic-bezier(0,1,1,1)}.collapse .cover,.collapse label{padding:.1rem .15rem}.collapse label{display:block;background:#eee;font-size:.16rem;cursor:pointer}.collapse input[type=radio]{display:none}.collapse input[type=radio]:checked+.content{max-height:300px;transition:max-height .2s cubic-bezier(1,1,1,1)}",""])},356:function(e,i,o){var a=o(343);"string"==typeof a&&(a=[[e.i,a,""]]);o(319)(a,{});a.locals&&(e.exports=a.locals)},374:function(e,i){e.exports="
这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente placeat, nam consequatur dolorum。
这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente placeat, nam consequatur dolorum。 这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, cum nihil voluptate, Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente placeat, nam consequatur dolorum。 这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, cum nihil voluptate, odio explicabo o odio explicabo omnis, eveniet autem voluptas maiores culpa iure nesciunt quo quod magnam adipisci!
这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente placeat, nam consequatur dolorum。 这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容, cum nihil voluptate, odio explicabo omnis, eveniet autem voluptas maiores culpa iure nesciunt quo quod magnam adipisci!
"}}); 2 | //# sourceMappingURL=12.index.js.map -------------------------------------------------------------------------------- /src/nuomi/markdown/Markdown.js: -------------------------------------------------------------------------------- 1 | import { g } from '../../gtool'; 2 | import GMD from 'gmd-markdown-parser'; 3 | import LNote from './LNote'; 4 | 5 | const defaultVal = `# h1\n 6 | 7 | ## h2 8 | 9 | ### h3 10 | 11 | #### h4 12 | 13 | ##### h5 14 | 15 | ###### h6 16 | 17 | --- 18 | 19 | Code: \`code\`, em: *em*, strong: **strong**, strike through: ~~through~~ 20 | 21 | --- 22 | 23 | [Link](https://google.com) 24 | 25 | ![img](https://ww4.sinaimg.cn/large/006tNc79gy1fdk3zs7r9nj308c08cdi7.jpg) 26 | 27 | > Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis veniam recusandae maiores aperiam? Vero amet iste aliquam, architecto sapiente ipsum provident, adipisci molestiae. Incidunt natus, tempora ratione atque praesentium 28 | > assumenda! 29 | 30 | --- 31 | 32 | pre: 33 | 34 | \`\`\`javascript 35 | alert(1) 36 | \`\`\` 37 | 38 | --- 39 | 40 | - unordered list1 41 | - list1 42 | - list1 43 | - list1 44 | 45 | 1. ordered list 46 | 2. ordered list 47 | 3. ordered list 48 | 4. ordered list`; 49 | 50 | export default class MarkDown { 51 | 52 | constructor (editor, output) { 53 | 54 | this.editor = typeof editor === 'string' ? g.$(editor) : editor; 55 | this.output = typeof output === 'string' ? g.$(output) : output; 56 | 57 | this.gmd = new GMD(); 58 | this.lnote = new LNote(this.editor, newVal => { 59 | this.update(newVal); 60 | }, defaultVal); 61 | 62 | this.init(); 63 | } 64 | 65 | init () { 66 | 67 | // this.textarea = new g.vdom('textarea', { 68 | // class: 'g-MarkDown' 69 | // }, [ this.parent.innerHTML.replace(/>/g, '>') ]).render(); 70 | 71 | // this.textarea.addEventListener('keyup', e => { 72 | // this.update(); 73 | // }) 74 | 75 | // this.parent.innerHTML = ''; 76 | // this.parent.appendChild(this.textarea); 77 | 78 | // this.update(); 79 | // this.data.setAttribute('contenteditable', true); 80 | 81 | // this.mutation = new MutationObserver(function(mutations) { 82 | // mutations.forEach(function(mutation) { 83 | // console.log(mutation, mutation.type); 84 | // }); 85 | // }); 86 | // this.mutation.observe(this.data, { 87 | // // attributes: true, 88 | // childList: true, 89 | // characterData: true, 90 | // subtree: true 91 | // }); 92 | } 93 | 94 | update (newVal) { 95 | this.output.innerHTML = this.gmd.parse(newVal); 96 | } 97 | } -------------------------------------------------------------------------------- /src/nuomi/vue5/Observer.js: -------------------------------------------------------------------------------- 1 | class ObEventHandler { 2 | constructor () { 3 | this.changeMethods = {}; 4 | } 5 | 6 | onChange (name, callback = () => {}) { 7 | this.changeMethods[name] = callback; 8 | } 9 | 10 | callChangeMethods (name, newVal = '') { 11 | name in this.changeMethods && this.changeMethods[name](newVal); 12 | } 13 | 14 | bubbling (path, newVal) { 15 | 16 | const pathArray = path.slice(0, path.length - 1).split('.'); 17 | const length = pathArray.length; 18 | 19 | // Call same path name's function,eg '['a.b.c.d']()' 20 | this.callChangeMethods(path, newVal); 21 | 22 | if (length) { 23 | 24 | // Call each path name's function, eg '['a'](), ['b']() ...' 25 | pathArray.forEach(pathName => { 26 | this.callChangeMethods(pathName, newVal); 27 | }); 28 | 29 | // Call parent path name's function,, eg '['a.b.c'](), ['a.b']() ...' 30 | for (let i = pathArray.length - 1; i >= 2 ; i--) { 31 | const pathSlice = pathArray.slice(0, i); 32 | this.callChangeMethods(pathSlice.join('.'), newVal); 33 | } 34 | } 35 | } 36 | } 37 | 38 | export default class Observer { 39 | 40 | constructor (data, publisher) { 41 | this.originalData = this.data = data; 42 | this.publisher = publisher; 43 | 44 | this.handler = new ObEventHandler(); 45 | 46 | this.observe(this.originalData); 47 | } 48 | 49 | observe (data) { 50 | this.checkData(data); 51 | } 52 | 53 | checkData (data, path = '') { 54 | if (typeof data === 'object') { 55 | Object.keys(data).forEach(key => { 56 | this.initProperty(data, key, data[key], path); 57 | }); 58 | } 59 | } 60 | 61 | initProperty (data, key, val, path) { 62 | 63 | path += key + '.'; 64 | 65 | this.checkData(val, path); 66 | 67 | Object.defineProperty(data, key, { 68 | enumerable: true, 69 | configurable: false, 70 | get: () => { 71 | return val; 72 | }, 73 | set: newVal => { 74 | this.checkData(newVal, parent); 75 | this.handler.bubbling(path, newVal); 76 | 77 | val = newVal; 78 | 79 | this.publisher.update(); 80 | } 81 | }); 82 | } 83 | 84 | $watch (name, callback = () => {}) { 85 | this.handler.onChange(name, callback); 86 | } 87 | } -------------------------------------------------------------------------------- /src/nuomi/vue3/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g, CONST } from '../../gtool'; 3 | import '../vue2/style.scss'; 4 | import Observer from './Observer'; 5 | 6 | export function create (parent, option = []) { 7 | parent = typeof parent === 'string' ? g.$(parent) : parent; 8 | 9 | parent.innerHTML = template; 10 | 11 | const oldConsole = console.log; 12 | const outputList = []; 13 | console.log = (output, isCommand = false) => { 14 | if (isCommand) { 15 | outputList.push(`
> ${output}
`); 16 | } else { 17 | outputList.push(`
< ${output}
`); 18 | } 19 | }; 20 | 21 | console.log(`let app1 = new Observer({ 22 | name: { 23 | firstName: 'shaofeng', 24 | lastName: 'liang' 25 | }, 26 | age: 25 27 | });`, true); 28 | let app1 = new Observer({ 29 | name: { 30 | firstName: 'shaofeng', 31 | lastName: 'liang' 32 | }, 33 | age: 25 34 | }); 35 | 36 | console.log(`app1.$watch('name', function (newName) { 37 | console.log('我的姓名发生了变化,可能是姓氏变了,也可能是名字变了。') 38 | });`, true); 39 | app1.$watch('name', function (newName) { 40 | console.log('我的姓名发生了变化,可能是姓氏变了,也可能是名字变了。新值为:' + newName); 41 | }); 42 | 43 | console.log(`app1.data.name.firstName = 'hahaha';`, true); 44 | app1.data.name.firstName = 'hahaha'; 45 | 46 | console.log(`app1.data.name.lastName = 'blablabla';`, true); 47 | app1.data.name.lastName = 'blablabla'; 48 | 49 | playCommand(outputList); 50 | 51 | console.log = (output, isCommand = false) => { 52 | if (isCommand) { 53 | addList(`
> ${output}
`); 54 | } else { 55 | addList(`
< ${output}
`); 56 | } 57 | }; 58 | const input = g.$('.console input'); 59 | input.addEventListener('keyup', e => { 60 | if (e.keyCode === CONST.KEY_CODE.ENTER) { 61 | 62 | const command = input.value; 63 | console.log(command, true); 64 | 65 | if (/app1\.data\.(\w+)+?\s?=?('.*?')?/.test(command)) { 66 | eval(command); 67 | } else { 68 | console.log("[warning] Command illegal"); 69 | } 70 | 71 | input.value = ''; 72 | } 73 | }); 74 | } 75 | 76 | async function playCommand (outputList) { 77 | // console.log(outputList); 78 | for(let i = 0; i < outputList.length; i++) { 79 | await new Promise((r, j) => { setTimeout(() => { r() } , 200); }); 80 | await addList(outputList[i]); 81 | } 82 | } 83 | 84 | function addList (output) { 85 | const outputEle = g.$('.console .output'); 86 | outputEle.innerHTML += output; 87 | outputEle.scrollTop = outputEle.scrollHeight; 88 | } -------------------------------------------------------------------------------- /src/nuomi/vue/Observer.js: -------------------------------------------------------------------------------- 1 | class ObEventHandler { 2 | constructor () { 3 | this.changeMethods = {}; 4 | } 5 | 6 | onChange (name, callback = () => {}) { 7 | this.changeMethods[name] = callback; 8 | } 9 | 10 | callChangeMethods (name, newVal = '') { 11 | name in this.changeMethods && this.changeMethods[name](newVal); 12 | } 13 | 14 | bubbling (path, newVal) { 15 | 16 | const pathArray = path.slice(0, path.length - 1).split('.'); 17 | const length = pathArray.length; 18 | 19 | // Call same path name's function,eg '['a.b.c.d']()' 20 | this.callChangeMethods(path, newVal); 21 | 22 | if (length) { 23 | 24 | // Call each path name's function, eg '['a'](), ['b']() ...' 25 | pathArray.forEach(pathName => { 26 | this.callChangeMethods(pathName, newVal); 27 | }); 28 | 29 | // Call parent path name's function,, eg '['a.b.c'](), ['a.b']() ...' 30 | for (let i = pathArray.length - 1; i >= 2 ; i--) { 31 | const pathSlice = pathArray.slice(0, i); 32 | this.callChangeMethods(pathSlice.join('.'), newVal); 33 | } 34 | } 35 | } 36 | } 37 | 38 | export default class Observer { 39 | 40 | constructor (data, publisher) { 41 | this.originalData = this.data = data; 42 | this.publisher = publisher; 43 | 44 | this.handler = new ObEventHandler(); 45 | 46 | this.observe(this.originalData); 47 | } 48 | 49 | observe (data) { 50 | this.checkData(data); 51 | } 52 | 53 | checkData (data, path = '') { 54 | if (typeof data === 'object') { 55 | Object.keys(data).forEach(key => { 56 | this.initProperty(data, key, data[key], path); 57 | }); 58 | } 59 | } 60 | 61 | initProperty (data, key, val, path) { 62 | 63 | path += key + '.'; 64 | 65 | this.checkData(val, path); 66 | 67 | // if this property is an computed one then do nothing 68 | const property = Object.getOwnPropertyDescriptor(data, key); 69 | if (property.configurable === false) { 70 | return; 71 | } 72 | 73 | Object.defineProperty(data, key, { 74 | enumerable: true, 75 | configurable: false, 76 | get: () => { 77 | return val; 78 | }, 79 | set: newVal => { 80 | 81 | if (newVal === val) { 82 | return; 83 | } 84 | 85 | val = newVal; 86 | 87 | this.checkData(newVal, parent); 88 | this.handler.bubbling(path, newVal); 89 | 90 | this.publisher.update(path); 91 | } 92 | }); 93 | } 94 | 95 | $watch (name, callback = () => {}) { 96 | this.handler.onChange(name, callback); 97 | } 98 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const autoprefixer = require('autoprefixer'); 4 | const precss = require('precss'); 5 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 6 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 7 | const copy = require('copy-webpack-plugin'); 8 | 9 | const srcDir = path.resolve(__dirname, './src'); 10 | const distDir = path.resolve(__dirname, './docs'); 11 | const staticDir = path.resolve(__dirname, './static'); 12 | 13 | const commonsPlugin = new webpack.optimize.CommonsChunkPlugin({ 14 | name: 'commons', 15 | filename: 'commons.js' 16 | }); 17 | const hotReplacement = new webpack.HotModuleReplacementPlugin(); 18 | const extract = new ExtractTextPlugin('style.css'); 19 | const htmlPlugin = new HtmlWebpackPlugin({ 20 | title: 'Geeku', 21 | template: path.resolve(__dirname, './index.html'), 22 | inject: 'body', 23 | hash: true, 24 | minify: { 25 | collapseWhitespace: true 26 | } 27 | }); 28 | const postcss = new webpack.LoaderOptionsPlugin({ 29 | options: { 30 | postcss: function () { 31 | return [ 32 | autoprefixer({ 33 | remove: false, 34 | browsers: ['ie >= 9', '> 1% in CN'], 35 | }), 36 | precss 37 | ]; 38 | }, 39 | } 40 | }); 41 | const copyStatic = new copy([ 42 | { 43 | from: './static', 44 | to: './static' 45 | } 46 | ]); 47 | 48 | module.exports = { 49 | entry: { 50 | 'src': srcDir, 51 | }, 52 | output: { 53 | path: distDir, 54 | // publicPath: 'static', 55 | filename: 'index.js', 56 | }, 57 | module: { 58 | loaders: [ 59 | { 60 | test: /template\.html$/, 61 | use: ['html-loader?root=./static/'] 62 | }, 63 | { 64 | test: /\.woff$|\.ttf$|\.eot$|\.wav$|\.mp3$/, 65 | use: ['file-loader'] 66 | }, 67 | { 68 | test: /\.jpe?g$|\.gif$|\.png$|\.svg$/, 69 | use: ['file-loader?limit=8192&name=static/[name].[ext]'] 70 | }, 71 | { 72 | test: /\.js$/, 73 | loaders: ['babel-loader?presets[]=es2015,presets[]=stage-0&cacheDirectory'], 74 | exclude: /node_modules/ 75 | }, 76 | { 77 | test: /\.css$|\.scss$/, 78 | use: ExtractTextPlugin.extract({ 79 | fallback: "style-loader", 80 | use: ["css-loader?minimize", 'sass-loader'] 81 | }) 82 | } 83 | ] 84 | }, 85 | plugins: [ commonsPlugin, extract, htmlPlugin, postcss, copyStatic, new webpack.DefinePlugin({ 86 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') 87 | }) ], 88 | // watch: true, 89 | 90 | devServer: { 91 | historyApiFallback: true, 92 | hot: false, 93 | inline: true, 94 | progress: true, 95 | port: 2333 96 | }, 97 | devtool: '#source-map', 98 | } -------------------------------------------------------------------------------- /src/nuomi/vue2/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g, CONST } from '../../gtool'; 3 | import './style.scss'; 4 | import Observer from './Observer'; 5 | 6 | export function create (parent, option = []) { 7 | parent = typeof parent === 'string' ? g.$(parent) : parent; 8 | 9 | parent.innerHTML = template; 10 | 11 | const oldConsole = console.log; 12 | const outputList = []; 13 | console.log = (output, isCommand = false) => { 14 | if (isCommand) { 15 | outputList.push(`
> ${output}
`); 16 | } else { 17 | outputList.push(`
< ${output}
`); 18 | } 19 | }; 20 | 21 | console.log(`let app1 = new Observer({ 22 | name: 'youngwind', 23 | age: 25, 24 | cellphone: { 25 | '1': 'iPhone 7', 26 | '2': 'Pixel XL' 27 | } 28 | });`, true); 29 | let app1 = new Observer({ 30 | name: 'youngwind', 31 | age: 25, 32 | cellphone: { 33 | '1': 'iPhone 7', 34 | '2': 'Pixel XL' 35 | } 36 | }); 37 | 38 | console.log(`app1.$watch('name', newVal => { 39 | console.log('[Watcher] ' + newVal); 40 | });`, true); 41 | app1.$watch('name', newVal => { 42 | console.log('[Watcher] ' + newVal); 43 | }); 44 | 45 | console.log(`app1.data.cellphone = { 46 | '1': 'iPhone 7 plus', 47 | '2': 'Pixel XL' 48 | }`, true); 49 | app1.data.cellphone = { 50 | '1': 'iPhone 7 plus', 51 | '2': 'Pixel XL' 52 | } 53 | 54 | console.log('app1.data.age = 100;', true); 55 | app1.data.age = 100; // 你设置了 age,新的值为100 56 | 57 | console.log('app1.data.name', true); 58 | app1.data.name = "Hai Su"; 59 | 60 | playCommand(outputList); 61 | 62 | console.log = (output, isCommand = false) => { 63 | if (isCommand) { 64 | addList(`
> ${output}
`); 65 | } else { 66 | addList(`
< ${output}
`); 67 | } 68 | }; 69 | const input = g.$('.console input'); 70 | input.addEventListener('keyup', e => { 71 | if (e.keyCode === CONST.KEY_CODE.ENTER) { 72 | 73 | const command = input.value; 74 | console.log(command, true); 75 | 76 | if (/app1\.data\.(\w+)+?\s?=?('.*?')?/.test(command)) { 77 | eval(command); 78 | } else { 79 | console.log("[warning] Command illegal"); 80 | } 81 | 82 | input.value = ''; 83 | } 84 | }); 85 | 86 | // console.log = oldConsole; 87 | } 88 | 89 | async function playCommand (outputList) { 90 | // console.log(outputList); 91 | for(let i = 0; i < outputList.length; i++) { 92 | await new Promise((r, j) => { setTimeout(() => { r() } , 200); }); 93 | await addList(outputList[i]); 94 | } 95 | } 96 | 97 | function addList (output) { 98 | const outputEle = g.$('.console .output'); 99 | outputEle.innerHTML += output; 100 | outputEle.scrollTop = outputEle.scrollHeight; 101 | } -------------------------------------------------------------------------------- /src/echarts/threejs1/index.js: -------------------------------------------------------------------------------- 1 | import template from './template.html'; 2 | import { g } from '../../gtool'; 3 | import './style.scss'; 4 | 5 | export function create (parent, option = []) { 6 | parent = typeof parent === 'string' ? g.$(parent) : parent; 7 | 8 | parent.innerHTML = template; 9 | loadLibraries(buildACar); 10 | } 11 | 12 | function buildACar () { 13 | 14 | const three = window.THREE; 15 | const renderer = new three.WebGLRenderer({ 16 | canvas: g.$('#mainCanvas'), 17 | antialias:true, 18 | }); 19 | 20 | renderer.setClearColor(0xcccccc); 21 | renderer.shadowMapEnabled = true; 22 | 23 | const scene = window.scene = new three.Scene(); 24 | const camera = new THREE.PerspectiveCamera(30, 4 / 3, 1, 1000); 25 | // const camera = new three.OrthographicCamera(-100, 100, -80, 80, 1, 100); 26 | camera.position.set(60, 70, 60); 27 | scene.add(camera); 28 | camera.lookAt(new three.Vector3(-50, 0, -50)); 29 | 30 | const material = new three.MeshLambertMaterial({ 31 | color: 0xcccccc, 32 | }) 33 | 34 | const plane = new three.PlaneGeometry(260, 260); 35 | const planeMesh = new three.Mesh(plane, new three.MeshLambertMaterial({ 36 | color: 0x444444, 37 | })); 38 | scene.add(planeMesh); 39 | 40 | planeMesh.rotation.x = 80; 41 | planeMesh.position.set(-50, 5, -50); 42 | 43 | planeMesh.receiveShadow = true; 44 | 45 | const cube = new three.Mesh( 46 | new three.CubeGeometry(40, 20, 20), 47 | material 48 | ); 49 | scene.add(cube); 50 | cube.position.set(-10, 30, 0); 51 | cube.castShadow = true; 52 | 53 | const torusList = torusGenerator(); 54 | 55 | torusList.forEach(torus => { 56 | scene.add(torus); 57 | }); 58 | 59 | var light = new THREE.PointLight(0xffffff); 60 | light.position.set(100, 100, 50); 61 | scene.add(light); 62 | light.castShadow = true; 63 | 64 | var light2 = new THREE.DirectionalLight(0xffffff, .6); 65 | light2.position.set(0, 100, 200); 66 | scene.add(light2); 67 | light2.castShadow = true; 68 | 69 | 70 | renderer.render(scene, camera); 71 | } 72 | 73 | function torusGenerator () { 74 | const material = new THREE.MeshLambertMaterial({ 75 | color: 0xcccccc, 76 | }); 77 | const torusShape = new THREE.TorusGeometry(5, 2, 20, 20); 78 | const torusList = []; 79 | const torusPositions = [ 80 | [0, 20, 10], 81 | [-20, 20, 10], 82 | [0, 20, -10], 83 | [-20, 20, -10] 84 | ]; 85 | for (let i = 0; i < 4; i++) { 86 | const torus = new THREE.Mesh( 87 | torusShape, 88 | material 89 | ); 90 | torus.position.set(...torusPositions[i]); 91 | torus.castShadow = true; 92 | torusList.push(torus); 93 | } 94 | 95 | return torusList; 96 | } 97 | 98 | function loadLibraries (afterLoaded) { 99 | const script = document.createElement("script"); 100 | 101 | script.src = "//cdn.bootcss.com/three.js/r83/three.min.js"; 102 | script.async = true; 103 | script.addEventListener('load', () => { 104 | afterLoaded(); 105 | }); 106 | 107 | document.body.appendChild(script); 108 | } -------------------------------------------------------------------------------- /src/nuomi/phantomjs/tmall.baidu.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 1, 3 | "msg": "successful", 4 | "keyword": "天猫", 5 | "time": 1854, 6 | "dataList": [ 7 | { 8 | "info": "由于该网站的robots.txt文件存在限制指令(限制搜索引擎抓取),系统无法提供该页面的内容描述-了解详情", 9 | "link": "http://www.baidu.com/link?url=3y9eTv_0EmHTJhnU6wVd-AhgXAemFlUpAQQyv9sldga", 10 | "pic": "", 11 | "title": "天猫tmall.com--上天猫,就够了" 12 | }, 13 | { 14 | "info": "“天猫”(英文:Tmall,亦称淘宝商城、天猫商城)原名淘宝商城,是一个综合性购物网站。2012年1月11日上午,淘宝商城正式宣布更名为“天猫”。2012年3月29日天猫发布全新Logo形象。2012年11月11日,天猫借光棍节大赚一笔,宣称13小时卖100...历史发展网站规模特有优势特色店铺商城规则更多>>baike.baidu.com/-", 15 | "link": "http://www.baidu.com/link?url=BRUg10VtnXuQmJL-L4SziDy0tSZFXefkCXgRiiskYGOodEPE8RfANZvwdixZb6nJ-a3HVCzrv3MVRizBbzG_URRPs0E9RZlF3gL7BdlDyg7", 16 | "pic": "https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3112243937,4200092487&fm=58", 17 | "title": "天猫_百度百科" 18 | }, 19 | { 20 | "info": "欢迎来到天猫吧参与讨论关注用户:131万人累计发贴:367万天猫活动喵课堂客服mm在线没事聊聊天", 21 | "link": "http://www.baidu.com/link?url=dOJTHR0sOg9lacE2DjTL2J1KffNzAJImPXC1swv0ijXqSFv2-gSy73OyAyHIovwA9p1-yCndEQuwgnae2FbCfa", 22 | "pic": "https://ss1.baidu.com/70cFfyinKgQFm2e88IuM_a/forum/pic/item/20a2b33533fa828b5baaa7dffa1f4134960a5a99.jpg", 23 | "title": "天猫吧_百度贴吧" 24 | }, 25 | { 26 | "info": "", 27 | "link": "http://www.baidu.com/link?url=5lpevpetLP6b-8E79V63jE7WfqDUwi9nTb7KEGGLpFoPI55O2P5RMB90PbgE08xm88F9rI7olGBKy1lTxdFCccKsHqqFir4uLo1q0OpRs5BOx8Iwal_lxeqOeaPGc7fj", 28 | "pic": "https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=3981893779,2930187418&fm=82&s=40967C920810E28812F5C9DF0300D032&w=121&h=81&img.JPEG", 29 | "title": "天猫的最新相关信息" 30 | }, 31 | { 32 | "info": "", 33 | "link": "http://www.baidu.com/link?url=ctH-Nmejyryntb3nPF-BmpFdLBMkgAvVo88_QNkl9ZStT2ooR9ki430LQFY6G0KLcLEnPQCSMOEJnCTo_rIinjo8tXMRr227B1i6YJpKhhu", 34 | "pic": "https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=3136958136,4004736188&fm=58", 35 | "title": "天猫的新浪微博" 36 | }, 37 | { 38 | "info": "服务热线400-860-8608查看更多电话>>", 39 | "link": "http://www.baidu.com/link?url=_Q1a-pQ-7AByUn_YA9n0lsYe8Sh0OILq_0jC7vNWwGyvBrvtBvHOyvlr7cK0DZe-MPtmCcQ7txVyNo9Dcpt7_ZMYRkWvicq74vVYcXedcM1XJRfKUcAz370PVhRvIZjz", 40 | "pic": "", 41 | "title": "天猫客服电话" 42 | }, 43 | { 44 | "info": "由于该网站的robots.txt文件存在限制指令(限制搜索引擎抓取),系统无法提供该页面的内容描述-了解详情", 45 | "link": "http://www.baidu.com/link?url=uFA2d-lEp_7xCNdkTCgSBkvBjeN-lqIwuVMCxLBWeIq", 46 | "pic": "", 47 | "title": "天猫家装-上天猫,就够了" 48 | }, 49 | { 50 | "info": "由于该网站的robots.txt文件存在限制指令(限制搜索引擎抓取),系统无法提供该页面的内容描述-了解详情", 51 | "link": "http://www.baidu.com/link?url=SzKDnEvxrMN1jCsRuQbRyASdM87hb4vRjwxYOBNPTmK", 52 | "pic": "", 53 | "title": "天猫精选-上天猫,就够了" 54 | }, 55 | { 56 | "info": "由于该网站的robots.txt文件存在限制指令(限制搜索引擎抓取),系统无法提供该页面的内容描述-了解详情", 57 | "link": "http://www.baidu.com/link?url=f4FJFkCEn9b1PM9iCVWuztd73G4-ncePZjCMyLF1XiqlQ8ulLdqP2_jiEBIRTqPf", 58 | "pic": "", 59 | "title": "天猫通用下载页-上天猫,就够了" 60 | } 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /src/nuomi/loading/style.scss: -------------------------------------------------------------------------------- 1 | $main-color: #54dd70; 2 | $second-color: lighten($main-color, 20%); 3 | $speed: .8s; 4 | $background: #23272d; 5 | 6 | .loadings { 7 | 8 | width: 100%; 9 | height: 100%; 10 | background: $background; 11 | 12 | .loading-wrap { 13 | position: absolute; 14 | width: 1rem; 15 | height: 1rem; 16 | left: 50%; 17 | top: 50%; 18 | transform: translate(-50%, -50%); 19 | overflow: hidden; 20 | } 21 | .outside { 22 | width: 0; 23 | height: 0; 24 | border: .5rem solid $main-color; 25 | border-bottom-color: transparent; 26 | border-radius: 50%; 27 | position: absolute; 28 | top: 0; 29 | left: 0; 30 | 31 | animation: outRotate $speed infinite linear; 32 | will-change: transform; 33 | 34 | &::before { 35 | content: ''; 36 | position: absolute; 37 | left: 50%; 38 | top: 50%; 39 | transform: translate(-50%, -50%); 40 | width: .94rem; 41 | height: .94rem; 42 | background: $background; 43 | border-radius: 50%; 44 | } 45 | } 46 | 47 | .inside { 48 | width: .5rem; 49 | height: .5rem; 50 | position: relative; 51 | left: 50%; 52 | top: 50%; 53 | transform: translate(-50%, -50%); 54 | color: $second-color; 55 | border-radius: 50%; 56 | overflow: hidden; 57 | animation: underChangeBG $speed * 2 infinite steps(1, end); 58 | 59 | will-change: transform; 60 | 61 | &::before { 62 | content: ''; 63 | position: absolute; 64 | background-image: linear-gradient(to right, transparent 50%, currentColor 0); 65 | width: 100%; 66 | height: 100%; 67 | animation: rotate $speed infinite linear, 68 | changeBG $speed * 2 infinite steps(1, end); 69 | 70 | will-change: transform; 71 | } 72 | } 73 | } 74 | 75 | @keyframes rotate { 76 | from { 77 | transform: rotate(360deg); 78 | } 79 | to { 80 | transform: rotate(0deg); 81 | } 82 | } 83 | 84 | @keyframes outRotate { 85 | from { 86 | transform: rotate(315deg); 87 | } 88 | to { 89 | transform: rotate(-45deg); 90 | } 91 | } 92 | 93 | @keyframes changeBG { 94 | 0% { 95 | background-image: linear-gradient(to right, transparent 50%, currentColor 0); 96 | } 97 | 25% { 98 | background-image: linear-gradient(to right, $main-color 50%, transparent 0); 99 | } 100 | 50% { 101 | background-image: linear-gradient(to right, transparent 50%, $main-color 0); 102 | } 103 | 75% { 104 | background-image: linear-gradient(to right, currentColor 50%, transparent 0); 105 | } 106 | 100% { 107 | background-image: linear-gradient(to right, transparent 50%, currentColor 0); 108 | } 109 | } 110 | 111 | @keyframes underChangeBG { 112 | 0% { 113 | background-image: linear-gradient(to right, currentColor 50%, $main-color 0); 114 | } 115 | 50% { 116 | background-image: linear-gradient(to right, $main-color 50%, currentColor 0); 117 | } 118 | } -------------------------------------------------------------------------------- /npm-debug.log: -------------------------------------------------------------------------------- 1 | 0 info it worked if it ends with ok 2 | 1 verbose cli [ '/Users/geeku/.nvm/versions/node/v7.0.0/bin/node', 3 | 1 verbose cli '/Users/geeku/.nvm/versions/node/v7.0.0/bin/npm', 4 | 1 verbose cli 'run', 5 | 1 verbose cli 'build' ] 6 | 2 info using npm@3.10.8 7 | 3 info using node@v7.0.0 8 | 4 verbose run-script [ 'prebuild', 'build', 'postbuild' ] 9 | 5 info lifecycle ife2017@1.0.0~prebuild: ife2017@1.0.0 10 | 6 silly lifecycle ife2017@1.0.0~prebuild: no script for prebuild, continuing 11 | 7 info lifecycle ife2017@1.0.0~build: ife2017@1.0.0 12 | 8 verbose lifecycle ife2017@1.0.0~build: unsafe-perm in lifecycle true 13 | 9 verbose lifecycle ife2017@1.0.0~build: PATH: /Users/geeku/.nvm/versions/node/v7.0.0/lib/node_modules/npm/bin/node-gyp-bin:/Users/geeku/Projects/Frontend/IFE2017/node_modules/.bin:/Users/geeku/.yarn/bin:/usr/local/opt/php70/bin:/Users/geeku/.nvm/versions/node/v7.0.0/bin:/usr/local/bin:/Users/geeku/.yarn/bin:/usr/local/opt/php70/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/go/bin:/opt/ImageMagick/bin 14 | 10 verbose lifecycle ife2017@1.0.0~build: CWD: /Users/geeku/Projects/Frontend/IFE2017 15 | 11 silly lifecycle ife2017@1.0.0~build: Args: [ '-c', 16 | 11 silly lifecycle 'NODE_ENV=\'production\' webpack -p --progress --colors' ] 17 | 12 silly lifecycle ife2017@1.0.0~build: Returned: code: 2 signal: null 18 | 13 info lifecycle ife2017@1.0.0~build: Failed to exec build script 19 | 14 verbose stack Error: ife2017@1.0.0 build: `NODE_ENV='production' webpack -p --progress --colors` 20 | 14 verbose stack Exit status 2 21 | 14 verbose stack at EventEmitter. (/Users/geeku/.nvm/versions/node/v7.0.0/lib/node_modules/npm/lib/utils/lifecycle.js:255:16) 22 | 14 verbose stack at emitTwo (events.js:106:13) 23 | 14 verbose stack at EventEmitter.emit (events.js:191:7) 24 | 14 verbose stack at ChildProcess. (/Users/geeku/.nvm/versions/node/v7.0.0/lib/node_modules/npm/lib/utils/spawn.js:40:14) 25 | 14 verbose stack at emitTwo (events.js:106:13) 26 | 14 verbose stack at ChildProcess.emit (events.js:191:7) 27 | 14 verbose stack at maybeClose (internal/child_process.js:877:16) 28 | 14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5) 29 | 15 verbose pkgid ife2017@1.0.0 30 | 16 verbose cwd /Users/geeku/Projects/Frontend/IFE2017 31 | 17 error Darwin 16.4.0 32 | 18 error argv "/Users/geeku/.nvm/versions/node/v7.0.0/bin/node" "/Users/geeku/.nvm/versions/node/v7.0.0/bin/npm" "run" "build" 33 | 19 error node v7.0.0 34 | 20 error npm v3.10.8 35 | 21 error code ELIFECYCLE 36 | 22 error ife2017@1.0.0 build: `NODE_ENV='production' webpack -p --progress --colors` 37 | 22 error Exit status 2 38 | 23 error Failed at the ife2017@1.0.0 build script 'NODE_ENV='production' webpack -p --progress --colors'. 39 | 23 error Make sure you have the latest version of node.js and npm installed. 40 | 23 error If you do, this is most likely a problem with the ife2017 package, 41 | 23 error not with npm itself. 42 | 23 error Tell the author that this fails on your system: 43 | 23 error NODE_ENV='production' webpack -p --progress --colors 44 | 23 error You can get information on how to open an issue for this project with: 45 | 23 error npm bugs ife2017 46 | 23 error Or if that isn't available, you can get their info via: 47 | 23 error npm owner ls ife2017 48 | 23 error There is likely additional logging output above. 49 | 24 verbose exit [ 1, true ] 50 | -------------------------------------------------------------------------------- /docs/8.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([8,15],{124:function(t,e,o){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function n(t){arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];t="string"==typeof t?f.g.$(t):t,t.innerHTML=i.default}Object.defineProperty(e,"__esModule",{value:!0}),e.create=n;var a=o(376),i=r(a),f=o(59);o(359)},346:function(t,e,o){e=t.exports=o(318)(),e.push([t.i,'.hoverEffect{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);overflow:hidden}.hoverEffect img{width:600px;height:auto;display:block;transition:filter .1s ease-in-out}.hoverEffect figcaption{position:absolute;left:0;top:0;width:100%;height:100%}.hoverEffect .content{height:100%;width:100%;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);border:50px solid rgba(0,0,0,.2);background-clip:padding-box;transition:opacity .2s ease-in-out;opacity:0;background:rgba(4,28,47,.8)}.hoverEffect .content:after,.hoverEffect .content:before{content:"";position:absolute;left:0;height:2px;width:100%;transform:scaleX(0);background:#fff;transition:transform .4s ease-in-out;transition-delay:.1s;will-change:transform}.hoverEffect .content:before{top:0}.hoverEffect .content:after{bottom:0}.hoverEffect .content:hover:after,.hoverEffect .content:hover:before{transform:scaleX(1)}.hoverEffect .content:hover header:after,.hoverEffect .content:hover header:before{transform:scaleY(1)}.hoverEffect .cover{display:table-cell;vertical-align:middle}.hoverEffect header{text-align:center;transition:transform .2s ease-in-out;transform:translate3d(0,-10%,0);color:#fff;position:static;height:100%;top:0;position:absolute;width:100%;display:table}.hoverEffect header:after,.hoverEffect header:before{content:"";position:absolute;top:0;width:2px;height:100%;transform:scaleY(0);background:#fff;transition:transform .4s ease-in-out;transition-delay:.1s}.hoverEffect header:before{left:0}.hoverEffect header:after{right:0}.hoverEffect h1{margin:10px;background-image:linear-gradient(-90deg,#1c80ff,#cf35f7 26%,#ffa33a 50%,#37f656 77%,#1c80ff);background-position:0 0;background-size:200% 100%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;color:transparent;position:relative;animation:textColor 5s infinite linear;font-weight:800;font-size:.4rem}.hoverEffect h1:after{background:none;content:attr(data-text);left:50%;width:100%;transform:translateX(-50%);position:absolute;text-shadow:1px 1px 2px rgba(0,0,0,.5);top:0;z-index:-1}@keyframes textColor{0%{background-position:0 0}to{background-position:-200% 0}}.hoverEffect a{color:#fff;text-decoration:none;font-size:.3rem;background-image:linear-gradient(-90deg,#1c80ff,#cf35f7 26%,#ffa33a 50%,#37f656 77%,#1c80ff);background-position:0 0;background-size:200% 100%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;color:transparent;animation:textColor 1s infinite linear;opacity:.6}.hoverEffect:hover img{will-change:filter;filter:blur(10px)}.hoverEffect:hover .content{will-change:opacity;opacity:1}.hoverEffect:hover header{transform:translateZ(0)}',""])},359:function(t,e,o){var r=o(346);"string"==typeof r&&(r=[[t.i,r,""]]);o(319)(r,{});r.locals&&(t.exports=r.locals)},369:function(t,e,o){t.exports=o.p+"static/anime_boys_nitroplus_steins_gate_shiina_mayuri_makise_desktop_1280x960_hd-wallpaper-693120.jpg"},376:function(t,e,o){t.exports="

El Psy Congroo

Enter
'}}); 2 | //# sourceMappingURL=8.index.js.map -------------------------------------------------------------------------------- /src/nuomi/markdown/style.scss: -------------------------------------------------------------------------------- 1 | $gray: #000; 2 | 3 | .markdown { 4 | height: 100%; 5 | overflow: auto; 6 | display: flex; 7 | 8 | .content { 9 | flex: 1; 10 | 11 | textarea { 12 | width: 100%; 13 | height: 100%; 14 | max-width: 100%; 15 | max-height: 100%; 16 | border: none; 17 | background: #2a2f31; 18 | color: #eee; 19 | padding: .1rem; 20 | outline: none; 21 | } 22 | } 23 | 24 | .cover { 25 | flex: 1; 26 | height: 100%; 27 | overflow: auto; 28 | } 29 | 30 | .out { 31 | min-height: 100%; 32 | overflow: auto; 33 | padding: .2rem .3rem; 34 | font-size: .12rem; 35 | // background: #fbf5e5; 36 | // display: none; 37 | 38 | a { 39 | color: #1d71c0; 40 | text-decoration: underline; 41 | } 42 | h1, h2, h3, h4, h5, h6 { 43 | margin: .1rem 0; 44 | } 45 | blockquote { 46 | border-left: 5px solid #f0f5f7; 47 | padding: 0 .3rem; 48 | color: #666; 49 | margin: .4rem 0; 50 | font-size: .14rem; 51 | overflow: hidden; 52 | } 53 | ol { 54 | margin: .2rem; 55 | } 56 | ul { 57 | margin: .2rem 0; 58 | list-style: none; 59 | } 60 | ul li::before { 61 | content: '•'; 62 | color: #1d71c0; 63 | margin-right: .1rem; 64 | } 65 | ul li.task-list-item::before { 66 | content: ''; 67 | } 68 | code { 69 | background: #f0f5f7; 70 | padding: .02rem .08rem; 71 | border-radius: 3px 72 | } 73 | pre { 74 | // border: 2px dashed #aaa; 75 | padding: .2rem; 76 | margin: .2rem 0; 77 | background: #f0f5f7; 78 | overflow-x: auto; 79 | border-radius: 3px; 80 | line-height: 1.5; 81 | } 82 | hr { 83 | border: none; 84 | border-top: .02rem solid #f0f5f7; 85 | } 86 | } 87 | 88 | .editor { 89 | display: flex; 90 | flex: 1; 91 | min-height: 100%; 92 | 93 | p { 94 | margin: 0; 95 | font-size: .14rem; 96 | white-space: nowrap; 97 | height: .14rem * 1.5; 98 | letter-spacing: .01rem; 99 | } 100 | } 101 | 102 | .line-nums { 103 | min-width: .4rem; 104 | background: #30363a; 105 | padding: .15rem .05rem; 106 | text-align: right; 107 | color: #6f8b9c; 108 | border-right: 1px dashed #535e63; 109 | } 110 | .textarea { 111 | flex: 1; 112 | background: #30363a; 113 | outline: none; 114 | padding: .15rem; 115 | color: #ddd; 116 | 117 | } 118 | } 119 | 120 | @media print { 121 | body, 122 | html { 123 | height: auto!important; 124 | overflow: auto!important; 125 | } 126 | .entries, 127 | .markdown .cover:first-child, 128 | .github, 129 | #disqus 130 | { 131 | display: none!important; 132 | } 133 | .container { 134 | width: 100%; 135 | } 136 | .out { 137 | display: block !important; 138 | width: 100%; 139 | padding: 0!important; 140 | } 141 | } -------------------------------------------------------------------------------- /src/style/entries.scss: -------------------------------------------------------------------------------- 1 | @import './var.scss'; 2 | 3 | .entries { 4 | background: $dark; 5 | /* Rectangle: */ 6 | // background-image: linear-gradient(0deg, #54DD70 0%, #3D4448 100%); 7 | width: 260px; 8 | height: 100%; 9 | float: left; 10 | // text-align: center; 11 | // border-right: 3px solid $light; 12 | // box-shadow: 2px 0 3px rgba(0,0,0,.2); 13 | overflow: hidden; 14 | 15 | header { 16 | padding: .2rem .15rem; 17 | margin: 0; 18 | background: $green; 19 | text-align: center; 20 | // border-radius: .03rem; 21 | overflow: hidden; 22 | color: $white80; 23 | display: flex; 24 | justify-content: center; 25 | align-items: center; 26 | 27 | img { 28 | width: .5rem; 29 | height: auto; 30 | display: inline-block; 31 | // display: none; 32 | vertical-align: bottom; 33 | margin-right: .1rem; 34 | filter: drop-shadow(2px 2px rgba(0,0,0,.2)); 35 | // margin-top: -80px; 36 | // float: left; 37 | } 38 | h1 { 39 | display: block; 40 | font-size: .18rem; 41 | margin: 0; 42 | color: #fff; 43 | text-shadow: 1px 1px 0 rgba(0,0,0,.2), 2px 2px 0 rgba(0,0,0,.2),; 44 | 45 | // margin-top: .1rem; 46 | // margin-top: .1rem; 47 | // line-height: 60px; 48 | // color: #fff; 49 | // background: $dark; 50 | // span { 51 | // color: $green; 52 | // } 53 | } 54 | } 55 | 56 | ul { 57 | list-style: none; 58 | padding: 0; 59 | margin: 0; 60 | 61 | li { 62 | padding: .1rem .2rem; 63 | cursor: pointer; 64 | text-align: left; 65 | white-space: nowrap; 66 | overflow: hidden; 67 | text-overflow: ellipsis; 68 | 69 | &:hover { 70 | background: $dark-light; 71 | } 72 | 73 | &.current { 74 | border-left: .03rem solid $green; 75 | color: $green; 76 | } 77 | 78 | &::before { 79 | content: ''; 80 | width: .08rem; 81 | height: .08rem; 82 | background: $yellow; 83 | border-radius: 50%; 84 | margin-right: .1rem; 85 | display: inline-block; 86 | vertical-align: middle; 87 | } 88 | 89 | &.completed { 90 | &::before { 91 | background: $green; 92 | } 93 | } 94 | } 95 | } 96 | 97 | nav { 98 | color: #fff; 99 | padding: 0; 100 | max-height: calc(100% - 100px); 101 | overflow-y: auto; 102 | // margin-top: -1rem; 103 | // min-height: 100%; 104 | 105 | > ul { 106 | 107 | > li { 108 | font-weight: 600; 109 | font-size: .12rem; 110 | // padding: .1rem .2rem; 111 | color: $gray-light; 112 | border-bottom: 1px solid $dark-light; 113 | margin-top: .1rem; 114 | 115 | &:hover { 116 | background: $dark; 117 | } 118 | 119 | &::before { 120 | display: none; 121 | } 122 | } 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /src/nuomi/player/font/demo_fontclass.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | IconFont 7 | 8 | 9 | 10 | 11 |
12 |

IconFont 图标

13 |
    14 | 15 |
  • 16 | 17 |
    错误
    18 |
    .icon-cuowu
    19 |
  • 20 | 21 |
  • 22 | 23 |
    聚收藏
    24 |
    .icon-jushoucang
    25 |
  • 26 | 27 |
  • 28 | 29 |
    垃圾箱
    30 |
    .icon-lajixiang
    31 |
  • 32 | 33 |
  • 34 | 35 |
    声音
    36 |
    .icon-shengyin
    37 |
  • 38 | 39 |
  • 40 | 41 |
    我的订单
    42 |
    .icon-wodedingdan
    43 |
  • 44 | 45 |
  • 46 | 47 |
    向右箭头
    48 |
    .icon-xiangyoujiantou
    49 |
  • 50 | 51 |
  • 52 | 53 |
    向左箭头
    54 |
    .icon-xiangzuojiantou
    55 |
  • 56 | 57 |
  • 58 | 59 |
    聚收藏gift
    60 |
    .icon-jushoucanggift
    61 |
  • 62 | 63 |
64 | 65 |

font-class引用

66 |
67 | 68 |

font-class是unicode使用方式的一种变种,主要是解决unicode书写不直观,语意不明确的问题。

69 |

与unicode使用方式相比,具有如下特点:

70 |
    71 |
  • 兼容性良好,支持ie8+,及所有现代浏览器。
  • 72 |
  • 相比于unicode语意明确,书写更直观。可以很容易分辨这个icon是什么。
  • 73 |
  • 因为使用class来定义图标,所以当要替换图标时,只需要修改class里面的unicode引用。
  • 74 |
  • 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
  • 75 |
76 |

使用步骤如下:

77 |

第一步:引入项目下面生成的fontclass代码:

78 | 79 | 80 |
<link rel="stylesheet" type="text/css" href="./iconfont.css">
81 |

第二步:挑选相应图标并获取类名,应用于页面:

82 |
<i class="iconfont icon-xxx"></i>
83 |
84 |

"iconfont"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。

85 |
86 |
87 | 88 | 89 | -------------------------------------------------------------------------------- /docs/7.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([7,15],{129:function(module,exports,__webpack_require__){"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _asyncToGenerator(e){return function(){var n=e.apply(this,arguments);return new Promise(function(e,t){function o(a,r){try{var i=n[a](r),u=i.value}catch(e){return void t(e)}return i.done?void e(u):Promise.resolve(u).then(function(e){o("next",e)},function(e){o("throw",e)})}return o("next")})}}function create(parent){var option=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];parent="string"==typeof parent?_gtool.g.$(parent):parent,parent.innerHTML=_template2.default;var oldConsole=console.log,outputList=[];console.log=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];n?outputList.push('
> '+e+"
"):outputList.push("
< "+e+"
")},console.log("let app1 = new Observer({\n name: 'youngwind',\n age: 25\n });",!0);var app1=new _Observer2.default({name:"youngwind",age:25});console.log("app1.data.name",!0),app1.data.name,console.log("app1.data.age = 100;",!0),app1.data.age=100,playCommand(outputList),console.log=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];addList(n?'
> '+e+"
":"
< "+e+"
")};var input=_gtool.g.$(".console input");input.addEventListener("keyup",function(e){if(e.keyCode===_gtool.CONST.KEY_CODE.ENTER){var command=input.value;console.log(command,!0),/app1\.data\.(\w+)+?\s?=?('.*?')?/.test(command)?eval(command):console.log("[warning] Command illegal"),input.value=""}})}function addList(e){var n=_gtool.g.$(".console .output");n.innerHTML+=e,n.scrollTop=n.scrollHeight}Object.defineProperty(exports,"__esModule",{value:!0});var playCommand=function(){var e=_asyncToGenerator(regeneratorRuntime.mark(function e(n){var t;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:t=0;case 1:if(!(t
'}}); 2 | //# sourceMappingURL=7.index.js.map -------------------------------------------------------------------------------- /src/nuomi/vue/Watcher.js: -------------------------------------------------------------------------------- 1 | const moustache = /({{(.*?)}})/g; 2 | const NODE_TYPE = { 3 | element: 1, 4 | text: 3, 5 | comment: 8 6 | }; 7 | 8 | export default class Watcher { 9 | 10 | static TYPE = { 11 | TEXT: 'text', 12 | NODE: 'node', 13 | BIND: 'bind' 14 | }; 15 | // node, type, original, context, attr 16 | constructor (options) { 17 | 18 | this.node = options.node || this.error('Node is required'); 19 | this.context = options.context || this.error('Context is required'); 20 | this.data = this.context.data; 21 | this.publisher = this.context.publisher; 22 | 23 | this.type = options.type || Watcher.TYPE.NODE; 24 | 25 | if (this.type === Watcher.TYPE.BIND) { 26 | this.attrName = options.attrName || this.error('Attribute Name is missing'); 27 | this.name = options.name || this.error('Attribute Value is missing') 28 | } 29 | 30 | this.curVal = []; 31 | 32 | this.init(); 33 | 34 | this.publisher.add(this); 35 | } 36 | 37 | error (msg) { 38 | throw new Error(msg); 39 | } 40 | 41 | init () { 42 | 43 | if (this.type === Watcher.TYPE.NODE || this.type === Watcher.TYPE.TEXT) { 44 | 45 | this.name = []; 46 | this.originalText = this.type === Watcher.TYPE.NODE ? 47 | this.node.innerText : 48 | this.node.nodeValue; 49 | 50 | const nameList = this.originalText.match(moustache); 51 | 52 | if (nameList && nameList.length) { 53 | 54 | nameList.forEach(name => { 55 | 56 | name.match(moustache); 57 | 58 | const orignialText = (RegExp.$1).trim(); 59 | const nameValue = (RegExp.$2).trim(); 60 | 61 | this.curVal[nameValue] = orignialText; 62 | 63 | this.name.push(nameValue); 64 | }); 65 | } 66 | } 67 | 68 | this.update('init'); 69 | } 70 | 71 | update (path) { 72 | if ( 73 | (path && this.name.indexOf(path.slice(0,-1)) >= 0) || 74 | path === 'init' 75 | ) { 76 | this.render(); 77 | } 78 | } 79 | 80 | render () { 81 | // const newVal = this.replaceContent(this.originalText); 82 | 83 | // if (newVal === this.originalText) { 84 | // return; 85 | // } 86 | 87 | switch (this.type) { 88 | case Watcher.TYPE.TEXT: 89 | this.node.nodeValue = this.replaceContent(this.originalText); 90 | break; 91 | case Watcher.TYPE.NODE: 92 | this.node.innerText = this.replaceContent(this.originalText); 93 | break; 94 | case Watcher.TYPE.BIND: 95 | // console.log(this.attrName); 96 | this.node.removeAttribute(this.attrName); 97 | this.node.setAttribute(this.attrName.replace('g-', ''), this.getData(this.name)); 98 | } 99 | } 100 | 101 | replaceContent (original) { 102 | 103 | let retVal = original; 104 | this.name.forEach(name => { 105 | 106 | const curVal = this.getData(name); 107 | this.originalText = retVal = retVal.replace(this.curVal[name], curVal); 108 | 109 | this.curVal[name] = curVal; 110 | 111 | // console.log(name, curVal); 112 | }); 113 | 114 | // console.log(original); 115 | return retVal; 116 | } 117 | 118 | getData (string) { 119 | try { 120 | const arr = string.trim().split('.'); 121 | if (arr.length === 1) { 122 | return this.data[arr[0]]; 123 | } 124 | return arr.reduce((x, y) => { 125 | return this.data[x][y]; 126 | }); 127 | } catch (e) { 128 | return ''; 129 | } 130 | } 131 | } -------------------------------------------------------------------------------- /src/taskList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "糯米学院", 4 | "tasks": [ 5 | { 6 | "title": "自定义网页右键菜单", 7 | "name": "contextMenu", 8 | "completed": true, 9 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/contextMenu" 10 | }, 11 | { 12 | "title": "网页抓取分析服务系列之一(基础分析)", 13 | "name": "phantomjs1", 14 | "completed": true, 15 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/phantomjs" 16 | }, 17 | { 18 | "title": "有趣的鼠标悬浮模糊效果", 19 | "name": "hoverEffect", 20 | "completed": true, 21 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/hoverEffect" 22 | }, 23 | { 24 | "title": "动态数据绑定(一)", 25 | "name": "vue1", 26 | "completed": true, 27 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/vue1" 28 | }, 29 | { 30 | "title": "动态数据绑定(二)", 31 | "name": "vue2", 32 | "completed": true, 33 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/vue2" 34 | }, 35 | { 36 | "title": "动态数据绑定(三)", 37 | "name": "vue3", 38 | "completed": true, 39 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/vue3" 40 | }, 41 | { 42 | "title": "动态数据绑定(四)", 43 | "name": "vue4", 44 | "completed": true, 45 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/vue4" 46 | }, 47 | { 48 | "title": "动态数据绑定(五)", 49 | "name": "vue5", 50 | "completed": true, 51 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/vue5" 52 | }, 53 | { 54 | "title": "使用CSS实现折叠面板", 55 | "name": "collapse", 56 | "completed": true, 57 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/collapse" 58 | }, 59 | { 60 | "title": "CSS3饼状loading效果", 61 | "name": "loading", 62 | "completed": true, 63 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/loading" 64 | }, 65 | { 66 | "title": "CSS3实现3D 轮播图", 67 | "name": "slider", 68 | "completed": true, 69 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/slider" 70 | }, 71 | { 72 | "title": "仿豆瓣音乐播放器", 73 | "name": "player", 74 | "completed": false, 75 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/player" 76 | }, 77 | { 78 | "title": "正则表达式之简易markdown文件解析器", 79 | "name": "markdown", 80 | "completed": true, 81 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/nuomi/markdown" 82 | } 83 | ] 84 | }, 85 | { 86 | "title": "ECharts & WebVR学院", 87 | "tasks": [ 88 | { 89 | "title": "WebGL No.1 - Three.js 入门", 90 | "name": "threejs1", 91 | "completed": true, 92 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/echarts/threejs1" 93 | } 94 | ] 95 | }, 96 | { 97 | "title": "商业平台学院", 98 | "tasks": [ 99 | { 100 | "title": "贪吃蛇", 101 | "name": "snake", 102 | "completed": false, 103 | "github": "https://github.com/gongpeione/ife2017/tree/master/src/echarts/snake" 104 | } 105 | ] 106 | } 107 | ] -------------------------------------------------------------------------------- /docs/4.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([4,15],{132:function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function o(e){arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];e="string"==typeof e?u.g.$(e):e,e.innerHTML=r.default;var t=new s.default({el:"#vue-content",data:{user:{name:"youngwind",age:25}}});console.log(t)}Object.defineProperty(t,"__esModule",{value:!0}),t.create=o;var i=n(384),r=a(i),u=n(59);n(364);var c=n(322),l=(a(c),n(337)),s=a(l)},322:function(e,t,n){"use strict";function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:function(){};this.changeMethods[e]=t}},{key:"callChangeMethods",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";e in this.changeMethods&&this.changeMethods[e](t)}},{key:"bubbling",value:function(e,t){var n=this,a=e.slice(0,e.length-1).split("."),o=a.length;if(this.callChangeMethods(e,t),o){a.forEach(function(e){n.callChangeMethods(e,t)});for(var i=a.length-1;i>=2;i--){var r=a.slice(0,i);this.callChangeMethods(r.join("."),t)}}}}]),e}(),u=function(){function e(t){a(this,e),this.originalData=this.data=t,this.handler=new r,this.observe(this.originalData)}return i(e,[{key:"observe",value:function(e){this.checkData(e)}},{key:"checkData",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";"object"===("undefined"==typeof e?"undefined":o(e))&&Object.keys(e).forEach(function(a){t.initProperty(e,a,e[a],n)})}},{key:"initProperty",value:function(e,t,n,a){var o=this;a+=t+".",this.checkData(n,a),Object.defineProperty(e,t,{enumerable:!0,configurable:!1,get:function(){return n},set:function(e){o.checkData(e,parent),o.handler.bubbling(a,e),n=e}})}},{key:"$watch",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};this.handler.onChange(e,t)}}]),e}();t.default=u},337:function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n
Name: {{ user.name }}
Age: {{ user.age }}
"}}); 2 | //# sourceMappingURL=4.index.js.map -------------------------------------------------------------------------------- /src/nuomi/vue/Vue.js: -------------------------------------------------------------------------------- 1 | import Observer from './Observer'; 2 | import Watcher from './Watcher'; 3 | import Publisher from './Publisher'; 4 | 5 | const NODE_TYPE = { 6 | element: 1, 7 | text: 3, 8 | comment: 8 9 | }; 10 | 11 | const moustache = /({{(.*?)}})/; 12 | const directive = /g-(.*?)/; 13 | 14 | export default class Vue { 15 | constructor (option) { 16 | 17 | this.data = option.data; 18 | this.el = (typeof option.el === 'string') ? document.querySelector(option.el) : option.el; 19 | 20 | this.publisher = new Publisher(); 21 | 22 | // add computed property 23 | this.computedList = option.computed; 24 | this.computed(); 25 | 26 | this.observer = new Observer(this.data, this.publisher); 27 | 28 | this.events = option.events; 29 | this.watchList = option.watch; 30 | 31 | this.parseHTML(this.el); 32 | this.addEvents(this.el); 33 | this.watch(); 34 | } 35 | 36 | computed () { 37 | const _this = this; 38 | Object.keys(this.computedList).forEach(key => { 39 | Object.defineProperty(this.data, key, { 40 | enumerable: true, 41 | configurable: false, 42 | get () { 43 | return _this.computedList[key].apply(_this); 44 | } 45 | }); 46 | }); 47 | } 48 | 49 | watch () { 50 | Object.keys(this.watchList).forEach(name => { 51 | this.$watch(name, this.watchList[name]) 52 | }); 53 | } 54 | 55 | addEvents (root) { 56 | Object.keys(this.events).forEach(event => { 57 | Object.keys(this.events[event]).forEach(el => { 58 | root.querySelectorAll(el).forEach(each => { 59 | each.addEventListener(event, this.events[event][el].bind(this)); 60 | }); 61 | }); 62 | }); 63 | } 64 | 65 | parseHTML (html) { 66 | 67 | const fragment = document.createDocumentFragment(); 68 | const childrenLength = html.children.length; 69 | 70 | let child = null; 71 | while (child = html.firstChild) { 72 | fragment.appendChild(child); 73 | this.parseNode(child); 74 | } 75 | 76 | this.el.appendChild(fragment); 77 | } 78 | 79 | parseNode (node) { 80 | 81 | let content = ''; 82 | 83 | // console.log(node); 84 | if (node.nodeType === NODE_TYPE.element) { 85 | 86 | Array.from(node.attributes).forEach(attr => { 87 | const name = attr.name; 88 | const value = attr.nodeValue; 89 | if (directive.test(name)) { 90 | 91 | if (RegExp.$1 === 'for') { 92 | 93 | 94 | 95 | } else { 96 | new Watcher({ 97 | node: node, 98 | type: Watcher.TYPE.BIND, 99 | name: value, 100 | context: this, 101 | attrName: name 102 | }); 103 | } 104 | 105 | } 106 | }); 107 | 108 | const children = Array.from(node.children); 109 | if (children.length) { 110 | children.forEach(child => { 111 | this.parseNode(child); 112 | }); 113 | } else { 114 | content = node.innerText; 115 | 116 | if (moustache.test(content)) { 117 | new Watcher({ 118 | node: node, 119 | type: Watcher.TYPE.NODE, 120 | context: this 121 | }); 122 | } 123 | } 124 | } 125 | if (node.nodeType === NODE_TYPE.text) { 126 | content = node.nodeValue; 127 | 128 | if (moustache.test(content)) { 129 | new Watcher({ 130 | node: node, 131 | type: Watcher.TYPE.TEXT, 132 | context: this 133 | }); 134 | } 135 | } 136 | } 137 | 138 | $watch (name, callback) { 139 | this.observer.$watch(name, callback.bind(this)); 140 | } 141 | } -------------------------------------------------------------------------------- /src/nuomi/markdown/LNote.js: -------------------------------------------------------------------------------- 1 | export default class LNote { 2 | 3 | constructor (parent, callback, defaultVal = 'Edit here') { 4 | this.parent = typeof parent === 'string' ? document.querySelector(parent) : parent; 5 | this.section = { 6 | lineNums: null, 7 | textarea: null 8 | }; 9 | this.callback = callback; 10 | 11 | this.lineCounter = 0; 12 | this.defaultVal = defaultVal; 13 | 14 | this.init(); 15 | } 16 | 17 | init () { 18 | 19 | const lines = this.section.lineNums = document.createElement('div'); 20 | const textarea = this.section.textarea = document.createElement('div'); 21 | 22 | lines.classList.add('line-nums'); 23 | textarea.classList.add('textarea'); 24 | textarea.setAttribute('contenteditable', true); 25 | 26 | this.parent.appendChild(lines); 27 | this.parent.appendChild(textarea); 28 | 29 | this.mutation = new MutationObserver((mutations) => { 30 | 31 | const newContent = this.getContent(); 32 | 33 | this.callback(newContent.text); 34 | this.updateNums(newContent.nums); 35 | this.saveContent(newContent.html); 36 | }); 37 | 38 | this.mutation.observe(textarea, { 39 | // attributes: true, 40 | childList: true, 41 | characterData: true, 42 | subtree: true 43 | }); 44 | 45 | textarea.addEventListener('keydown', e => { 46 | if (this.lineCounter > 1) { 47 | return; 48 | } 49 | if (textarea.innerText.length === 1 && e.keyCode === 8) { 50 | e.preventDefault(); 51 | } 52 | }); 53 | 54 | const defaultVal = this.loadContent(); 55 | if (defaultVal) { 56 | this.setContent(defaultVal, true); 57 | } else { 58 | this.setContent(this.defaultVal); 59 | } 60 | 61 | this.callback(defaultVal); 62 | } 63 | 64 | updateNums (newCounter) { 65 | 66 | if (newCounter === this.lineCounter) { 67 | return; 68 | } 69 | 70 | // Add new lines 71 | if (newCounter > this.lineCounter) { 72 | const fragment = document.createDocumentFragment(); 73 | 74 | for (let i = this.lineCounter; i < newCounter; i++, this.lineCounter++) { 75 | fragment.appendChild(this.newNum(i + 1)); 76 | } 77 | 78 | this.section.lineNums.appendChild(fragment); 79 | } 80 | 81 | // Remove lines 82 | if (newCounter < this.lineCounter) { 83 | 84 | const rmAmount = this.lineCounter - newCounter; 85 | 86 | if (rmAmount < 50) { 87 | for (let i = 0; i < rmAmount; i++, this.lineCounter--) { 88 | this.section.lineNums.lastChild.remove(); 89 | } 90 | return; 91 | } 92 | 93 | this.section.lineNums.innerHTML = ''; 94 | const fragment = document.createDocumentFragment(); 95 | 96 | for (let i = 1; i <= newCounter; i++, this.lineCounter++) { 97 | fragment.appendChild(this.newNum(i)); 98 | } 99 | this.section.lineNums.appendChild(fragment); 100 | } 101 | } 102 | 103 | newNum (index) { 104 | 105 | const num = document.createElement('p'); 106 | 107 | num.classList.add('line-num'); 108 | num.dataset.index = index; 109 | num.innerText = index; 110 | 111 | return num; 112 | } 113 | 114 | getContent () { 115 | const lines = Array.from(this.section.textarea.querySelectorAll('p')); 116 | const text = lines.reduce((str, line2) => str + line2.innerText + '\n', ''); 117 | 118 | return { 119 | nums: lines.length, 120 | text: text, 121 | html: this.section.textarea.innerHTML 122 | } 123 | } 124 | 125 | saveContent (content) { 126 | localStorage.setItem('GMD_content', content); 127 | } 128 | 129 | setContent (content, isHTML) { 130 | if (isHTML) { 131 | this.section.textarea.innerHTML = content; 132 | } else { 133 | this.section.textarea.innerHTML = content.split('\n').map(line => `

${line}

`).join(''); 134 | } 135 | 136 | } 137 | 138 | loadContent () { 139 | return localStorage.getItem('GMD_content') || false; 140 | } 141 | } -------------------------------------------------------------------------------- /src/nuomi/contextMenu/ContextMenu.js: -------------------------------------------------------------------------------- 1 | import { g } from '../../gtool'; 2 | import './ContextMenu.scss'; 3 | 4 | // TODO submenu 5 | export default class ContextMenu { 6 | constructor (parent, options = {}) { 7 | this.parent = typeof parent === 'string' ? g.$(parent) : parent; 8 | this.options = options; 9 | this.isHidden = true; 10 | this.type = [ 11 | 'separator', 12 | 'link', 13 | 'function', 14 | 'text', 15 | ]; 16 | 17 | this.menu = this.render(); 18 | this.parent.appendChild(this.menu); 19 | 20 | this.parent.addEventListener('contextmenu', e => { 21 | this.show(); 22 | const position = this._getXY(e); 23 | this.setPosition(position.x, position.y); 24 | 25 | e.preventDefault(); 26 | return false; 27 | }); 28 | document.addEventListener('click', e => { 29 | // console.log(this); 30 | if (e.target !== this.menu) { 31 | this.hide(); 32 | } 33 | }); 34 | document.addEventListener('contextmenu', e => { 35 | // console.log(e); 36 | if (e.target !== this.menu && e.target !== this.parent) { 37 | this.hide(); 38 | } 39 | }); 40 | } 41 | 42 | render () { 43 | const menuList = []; 44 | this.options.items.forEach(item => { 45 | 46 | if (this.type.indexOf(item.type) < 0) { 47 | return; 48 | } 49 | switch (item.type) { 50 | case 'separator': menuList.push(this.separator(item)); break; 51 | case 'link': menuList.push(this.link(item)); break; 52 | case 'function': menuList.push(this.function(item)); break; 53 | case 'text': menuList.push(this.text(item)); break; 54 | 55 | default: return; 56 | } 57 | 58 | }); 59 | 60 | const className = 'g-contextMenu ' + (this.options.class || ''); 61 | return new g.vdom('ul', { class: className }, menuList).render(); 62 | } 63 | 64 | separator (option) { 65 | return new g.vdom('li', { class: 'separator' }); 66 | } 67 | 68 | link (option) { 69 | 70 | const a = new g.vdom('a', { 71 | 72 | href: option.content || '', 73 | target: option.target ? option.target : '_blank', 74 | 75 | }, [ option.title ]); 76 | 77 | const list = new g.vdom('li', { class: 'link' + (option.disabled ? ' disabled' : '') }, [ a ]); 78 | if (option.disabled) { 79 | list.addEvent('click', e => { 80 | e.preventDefault(); 81 | return false; 82 | }) 83 | } 84 | 85 | return list; 86 | } 87 | 88 | function (option) { 89 | const btn = new g.vdom('li', { 90 | class: 'function' + (option.disabled ? ' disabled' : '') 91 | }, [ option.title ]); 92 | 93 | if (!option.disabled) { 94 | btn.addEvent('click', (e) => { 95 | option.content(e); 96 | }); 97 | } 98 | 99 | return btn; 100 | } 101 | 102 | text (option) { 103 | return new g.vdom('li', { 104 | class: 'text' + (option.disabled ? ' disabled' : '') 105 | }, [ option.title ]); 106 | } 107 | 108 | show () { 109 | g.class(this.menu, 'hide', true); 110 | g.class(this.menu, 'show'); 111 | } 112 | 113 | hide () { 114 | g.class(this.menu, 'show', true); 115 | g.class(this.menu, 'hide'); 116 | } 117 | 118 | setPosition (x, y) { 119 | g.css(this.menu, `left:${x}px; top:${y}px`); 120 | } 121 | 122 | _getXY (e) { 123 | // console.log(e); 124 | const toTop = document.documentElement.scrollTop || document.body.scrollTop; 125 | const toLeft = document.documentElement.scrollLeft || document.body.scrollLeft; 126 | const bodyWidth = g.width(document.body); 127 | const bodyHeight = g.height(document.body); 128 | const menuWidth = g.width(this.menu); 129 | const menuHeight = g.height(this.menu); 130 | 131 | let x = e.clientX + toLeft; 132 | let y = e.clientY + toTop; 133 | if (bodyWidth - x < menuWidth) { 134 | x -= menuWidth; 135 | } 136 | if (bodyHeight - y < menuHeight) { 137 | y -= menuHeight; 138 | } 139 | return {x, y}; 140 | // return {x: e.clientX + toLeft, y: e.clientY + toTop}; 141 | } 142 | } -------------------------------------------------------------------------------- /docs/3.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([3,15],{123:function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}function i(e){arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];e="string"==typeof e?r.g.$(e):e,e.innerHTML=s.default;var t=r.g.$(".contentMenu",e);new c.default(t,u)}Object.defineProperty(t,"__esModule",{value:!0}),t.create=i;var r=n(59),a=n(375),s=o(a),l=n(326),c=o(l);n(358);var u={class:"context-menu",items:[{type:"link",title:"百度",content:"https://www.baidu.com",target:"_blank"},{type:"separator"},{type:"function",title:"Alert",content:function(){return alert(1)}},{type:"link",title:"Disabled",disabled:!0},{type:"text",title:"Plain Text",class:"plain"}]}},326:function(e,t,n){"use strict";function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{};o(this,e),this.parent="string"==typeof t?r.g.$(t):t,this.options=i,this.isHidden=!0,this.type=["separator","link","function","text"],this.menu=this.render(),this.parent.appendChild(this.menu),this.parent.addEventListener("contextmenu",function(e){n.show();var t=n._getXY(e);return n.setPosition(t.x,t.y),e.preventDefault(),!1}),document.addEventListener("click",function(e){e.target!==n.menu&&n.hide()}),document.addEventListener("contextmenu",function(e){e.target!==n.menu&&e.target!==n.parent&&n.hide()})}return i(e,[{key:"render",value:function(){var e=this,t=[];this.options.items.forEach(function(n){if(!(e.type.indexOf(n.type)<0))switch(n.type){case"separator":t.push(e.separator(n));break;case"link":t.push(e.link(n));break;case"function":t.push(e.function(n));break;case"text":t.push(e.text(n));break;default:return}});var n="g-contextMenu "+(this.options.class||"");return new r.g.vdom("ul",{class:n},t).render()}},{key:"separator",value:function(e){return new r.g.vdom("li",{class:"separator"})}},{key:"link",value:function(e){var t=new r.g.vdom("a",{href:e.content||"",target:e.target?e.target:"_blank"},[e.title]),n=new r.g.vdom("li",{class:"link"+(e.disabled?" disabled":"")},[t]);return e.disabled&&n.addEvent("click",function(e){return e.preventDefault(),!1}),n}},{key:"function",value:function(e){var t=new r.g.vdom("li",{class:"function"+(e.disabled?" disabled":"")},[e.title]);return e.disabled||t.addEvent("click",function(t){e.content(t)}),t}},{key:"text",value:function(e){return new r.g.vdom("li",{class:"text"+(e.disabled?" disabled":"")},[e.title])}},{key:"show",value:function(){r.g.class(this.menu,"hide",!0),r.g.class(this.menu,"show")}},{key:"hide",value:function(){r.g.class(this.menu,"show",!0),r.g.class(this.menu,"hide")}},{key:"setPosition",value:function(e,t){r.g.css(this.menu,"left:"+e+"px; top:"+t+"px")}},{key:"_getXY",value:function(e){var t=document.documentElement.scrollTop||document.body.scrollTop,n=document.documentElement.scrollLeft||document.body.scrollLeft,o=r.g.width(document.body),i=r.g.height(document.body),a=r.g.width(this.menu),s=r.g.height(this.menu),l=e.clientX+n,c=e.clientY+t;return o-l"}}); 2 | //# sourceMappingURL=3.index.js.map -------------------------------------------------------------------------------- /docs/9.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([9,15],{120:function(t,i,n){"use strict";function e(t){return t&&t.__esModule?t:{default:t}}function s(t){arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];t="string"==typeof t?h.g.$(t):t,t.innerHTML=a.default,new d.default(".snake-wrap",{color:{bg:"#232",snake:"#985"}})}Object.defineProperty(i,"__esModule",{value:!0}),i.create=s;var o=n(372),a=e(o),h=n(59);n(354);var r=n(325),d=e(r)},325:function(t,i,n){"use strict";function e(t,i){if(!(t instanceof i))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0});var s=function(){function t(t,i){for(var n=0;n=0){if(console.log(this.direction,i,d[i]),this.direction===i||this.direction===d[i])return;this.direction=i}}},{key:"randomFood",value:function(){var t=Math.random()*(this.map[0].length-1),i=Math.random()*(this.map.length-1),n=[Math.round(t),Math.round(i)];console.log(n),this.snakeAtPosition(n)?this.randomFood():this.foodPosition=n}},{key:"end",value:function(){this.isPlaying=!1}},{key:"mapRender",value:function(){for(var t=0;t1&&void 0!==arguments[1]&&arguments[1],n=void 0,e=JSON.stringify(t),s=Object.assign([],this.snakeBody);return i?(s.splice(this.snakeHeadAnchor,1),n=JSON.stringify(s)):n=JSON.stringify(s),n.indexOf(e)>=0}},{key:"snakeHeadAtPosition",value:function(t){var i=JSON.stringify(this.snakeBody[this.snakeHeadAnchor]),n=JSON.stringify(t);return 0===i.indexOf(n)}},{key:"foodAtPosition",value:function(t){var i=JSON.stringify(this.foodPosition),n=JSON.stringify(t);return 0===i.indexOf(n)}},{key:"snakeMove",value:function(){var t=this.snakeHeadAnchor,i=this.snakeBody.length,n=Object.assign([],this.snakeBody[t]);switch(this.direction){case r.right:this.snakeBody[t][0]++;break;case r.left:this.snakeBody[t][0]--;break;case r.up:this.snakeBody[t][1]--;break;case r.down:this.snakeBody[t][1]++}if(this.snakeBody[t][0]>this.map[0].length-1||this.snakeBody[t][0]<0||this.snakeBody[t][1]>this.map.length-1||this.snakeBody[t][1]<0||this.snakeAtPosition(this.snakeBody[t],!0))return console.log("end"),void this.end();for(var e=1;e
"}}); 2 | //# sourceMappingURL=9.index.js.map -------------------------------------------------------------------------------- /src/nuomi/hoverEffect/style.scss: -------------------------------------------------------------------------------- 1 | .hoverEffect { 2 | position: absolute; 3 | left: 50%; 4 | top: 50%; 5 | transform: translate(-50%, -50%); 6 | overflow: hidden; 7 | 8 | 9 | img { 10 | width: 600px; 11 | height: auto; 12 | display: block; 13 | transition: filter .1s ease-in-out; 14 | } 15 | 16 | figcaption { 17 | // background: rgba(0,0,0,.5); 18 | position: absolute; 19 | left: 0; 20 | top: 0; 21 | width: 100%; 22 | height: 100%; 23 | } 24 | 25 | .content { 26 | height: 100%; 27 | width: 100%; 28 | position: absolute; 29 | left: 50%; 30 | top: 50%; 31 | transform: translate(-50%,-50%); 32 | border: 50px solid rgba(0,0,0,.2); 33 | background-clip: padding-box; 34 | transition: opacity .2s ease-in-out; 35 | opacity: 0; 36 | background: rgba(4, 28, 47, 0.8); 37 | 38 | &::before, 39 | &::after { 40 | content: ''; 41 | position: absolute; 42 | left: 0; 43 | height: 2px; 44 | width: 100%; 45 | transform: scaleX(0); 46 | background: #fff; 47 | transition: transform .4s ease-in-out; 48 | transition-delay: .1s; 49 | will-change: transform; 50 | } 51 | &::before { 52 | top: 0; 53 | } 54 | &::after { 55 | bottom: 0; 56 | } 57 | 58 | &:hover::before, 59 | &:hover::after { 60 | transform: scaleX(1); 61 | } 62 | 63 | &:hover header { 64 | &::before, 65 | &::after { 66 | transform: scaleY(1); 67 | } 68 | } 69 | 70 | } 71 | .cover { 72 | display: table-cell; 73 | vertical-align: middle; 74 | } 75 | header { 76 | text-align: center; 77 | transition: transform .2s ease-in-out; 78 | // margin-top: 10%; 79 | transform: translate3d(0, -10%, 0); 80 | color: #fff; 81 | position: static; 82 | height: 100%; 83 | top: 0; 84 | position: absolute; 85 | width: 100%; 86 | display: table; 87 | 88 | &::before, 89 | &::after { 90 | content: ''; 91 | position: absolute; 92 | top: 0; 93 | width: 2px; 94 | height: 100%; 95 | transform: scaleY(0); 96 | background: #fff; 97 | transition: transform .4s ease-in-out; 98 | transition-delay: .1s; 99 | } 100 | &::before { 101 | left: 0; 102 | } 103 | &::after { 104 | right: 0; 105 | } 106 | } 107 | h1 { 108 | margin: 10px; 109 | background-image: linear-gradient(-90deg, #1C80FF 0%, #CF35F7 26%, #FFA33A 50%, #37F656 77%, #1C80FF 100%); 110 | background-position: 0 0; 111 | background-size: 200% 100%; 112 | -webkit-background-clip: text; 113 | -webkit-text-fill-color: transparent; 114 | color: transparent; 115 | // text-shadow: 1px 1px 2px rgba(0,0,0,.5); 116 | position: relative; 117 | animation: textColor 5s infinite linear; 118 | font-weight: 800; 119 | font-size: .4rem; 120 | 121 | &::after { 122 | background: none; 123 | content: attr(data-text); 124 | left: 50%; 125 | width: 100%; 126 | transform: translateX(-50%); 127 | position: absolute; 128 | text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); 129 | top: 0; 130 | z-index: -1; 131 | } 132 | } 133 | @keyframes textColor { 134 | from { 135 | background-position: 0 0; 136 | } 137 | to { 138 | background-position: -200% 0; 139 | } 140 | } 141 | a { 142 | color: #fff; 143 | text-decoration: none; 144 | font-size: .3rem; 145 | background-image: linear-gradient(-90deg, #1C80FF 0%, #CF35F7 26%, #FFA33A 50%, #37F656 77%, #1C80FF 100%); 146 | background-position: 0 0; 147 | background-size: 200% 100%; 148 | -webkit-background-clip: text; 149 | -webkit-text-fill-color: transparent; 150 | color: transparent; 151 | animation: textColor 1s infinite linear; 152 | opacity: .6; 153 | } 154 | &:hover { 155 | img { 156 | will-change: filter; 157 | filter: blur(10px); 158 | } 159 | .content { 160 | will-change: opacity; 161 | opacity: 1; 162 | } 163 | header { 164 | transform: translate3d(0, 0, 0); 165 | } 166 | } 167 | } -------------------------------------------------------------------------------- /docs/6.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([6,15],{130:function(module,exports,__webpack_require__){"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _asyncToGenerator(e){return function(){var n=e.apply(this,arguments);return new Promise(function(e,o){function t(a,r){try{var i=n[a](r),l=i.value}catch(e){return void o(e)}return i.done?void e(l):Promise.resolve(l).then(function(e){t("next",e)},function(e){t("throw",e)})}return t("next")})}}function create(parent){var option=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];parent="string"==typeof parent?_gtool.g.$(parent):parent,parent.innerHTML=_template2.default;var oldConsole=console.log,outputList=[];console.log=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];n?outputList.push('
> '+e+"
"):outputList.push("
< "+e+"
")},console.log("let app1 = new Observer({\n name: 'youngwind',\n age: 25,\n cellphone: {\n '1': 'iPhone 7',\n '2': 'Pixel XL'\n }\n });",!0);var app1=new _Observer2.default({name:"youngwind",age:25,cellphone:{1:"iPhone 7",2:"Pixel XL"}});console.log("app1.$watch('name', newVal => {\n console.log('[Watcher] ' + newVal);\n });",!0),app1.$watch("name",function(e){console.log("[Watcher] "+e)}),console.log("app1.data.cellphone = {\n '1': 'iPhone 7 plus',\n '2': 'Pixel XL'\n }",!0),app1.data.cellphone={1:"iPhone 7 plus",2:"Pixel XL"},console.log("app1.data.age = 100;",!0),app1.data.age=100,console.log("app1.data.name",!0),app1.data.name="Hai Su",playCommand(outputList),console.log=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];addList(n?'
> '+e+"
":"
< "+e+"
")};var input=_gtool.g.$(".console input");input.addEventListener("keyup",function(e){if(e.keyCode===_gtool.CONST.KEY_CODE.ENTER){var command=input.value;console.log(command,!0),/app1\.data\.(\w+)+?\s?=?('.*?')?/.test(command)?eval(command):console.log("[warning] Command illegal"),input.value=""}})}function addList(e){var n=_gtool.g.$(".console .output");n.innerHTML+=e,n.scrollTop=n.scrollHeight}Object.defineProperty(exports,"__esModule",{value:!0});var playCommand=function(){var e=_asyncToGenerator(regeneratorRuntime.mark(function e(n){var o;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:o=0;case 1:if(!(o1&&void 0!==arguments[1]?arguments[1]:function(){};this.watchers[e]=n}}]),e}();n.default=i},382:function(e,n){e.exports='
'}}); 2 | //# sourceMappingURL=6.index.js.map -------------------------------------------------------------------------------- /src/style/index.scss: -------------------------------------------------------------------------------- 1 | @import './normalize.css'; 2 | @import './entries.scss'; 3 | @import './var.scss'; 4 | 5 | $fontSize: .4rem; 6 | 7 | * { 8 | box-sizing: border-box; 9 | } 10 | body, 11 | html { 12 | height: 100%; 13 | overflow: hidden; 14 | } 15 | html { 16 | font-size: 100px; 17 | } 18 | body { 19 | font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; 20 | font-size: .14rem; 21 | font-weight: 300; 22 | line-height: 1.5; 23 | color: $dark; 24 | } 25 | h1, h2, h3, h4, h5, h6 { 26 | font-weight: 400; 27 | } 28 | h1, 29 | .h1 { 30 | font-size: $fontSize; 31 | } 32 | h2, 33 | .h2 { 34 | font-size: $fontSize - .05; 35 | } 36 | h3, 37 | .h3 { 38 | font-size: $fontSize - .1; 39 | } 40 | h4, 41 | .h4 { 42 | font-size: $fontSize - .15; 43 | } 44 | h5, 45 | .h5 { 46 | font-size: $fontSize - .2; 47 | } 48 | h6, 49 | .h6 { 50 | font-size: $fontSize - .25; 51 | } 52 | p, 53 | .p { 54 | font-size: .16rem; 55 | margin-bottom: .16rem; 56 | } 57 | 58 | .container { 59 | display: flex; 60 | width: calc(100% - 260px); 61 | height: 100%; 62 | float: left; 63 | position: relative; 64 | overflow: hidden; 65 | justify-content: center; 66 | align-items: center; 67 | } 68 | 69 | .github { 70 | position: absolute; 71 | right: 0; 72 | top: 0; 73 | transform: scale(1.8); 74 | transform-origin: right top; 75 | } 76 | 77 | .nopage { 78 | width: 80%; 79 | height: 40%; 80 | border-radius: .03rem; 81 | background: #eee; 82 | position: absolute; 83 | left: 50%; 84 | top: 50%; 85 | transform: translate(-50%, -50%); 86 | &::before { 87 | content: '本题无展示页,请点击右上方 Github 图标查看源代码。'; 88 | color: #999; 89 | position: absolute; 90 | width: 100%; 91 | top: 50%; 92 | text-align: center; 93 | transform: translateY(-50%); 94 | font-size: .2rem; 95 | } 96 | } 97 | 98 | .loading { 99 | width: .2rem; 100 | height: .2rem; 101 | // position: fixed; 102 | right: .1rem; 103 | bottom: .1rem; 104 | // display: none; 105 | &:before { 106 | content: ''; 107 | position: absolute; 108 | width: .2rem; 109 | height: .2rem; 110 | background-color: $green; 111 | left: calc(50% - .1rem); 112 | top: calc(50% - .1rem); 113 | animation: loading 1s cubic-bezier(0.59, 0.02, 0.3, 1) infinite; 114 | z-index: -1; 115 | } 116 | &.hide { 117 | display: none; 118 | } 119 | &.show { 120 | display: block; 121 | } 122 | } 123 | @keyframes loading { 124 | 0% { 125 | border-radius: 0; 126 | background-color: #ccc; 127 | transform: rotate(0deg); 128 | } 129 | 50% { 130 | border-radius: 50%; 131 | background-color: #4eba56; 132 | transform: rotate(180deg); 133 | } 134 | 100% { 135 | border-radius: 1%; 136 | background-color: #ccc; 137 | transform: rotate(359deg); 138 | } 139 | } 140 | 141 | button { 142 | border: none; 143 | background: $green; 144 | padding: .05rem .1rem; 145 | border-radius: .03rem; 146 | color: $white; 147 | font-size: .16rem; 148 | outline: none; 149 | } 150 | 151 | #disqus { 152 | right: .2rem; 153 | position: fixed; 154 | bottom: .2rem; 155 | width: 60%; 156 | z-index: 99; 157 | transform: translateY(320px); 158 | text-align: right; 159 | transition: transform .2s ease-in-out; 160 | 161 | input { 162 | display: none; 163 | } 164 | label { 165 | display: inline-block; 166 | overflow: hidden; 167 | height: .3rem; 168 | width: .3rem; 169 | cursor: pointer; 170 | 171 | &::before { 172 | content: ''; 173 | position: absolute; 174 | right: 0; 175 | height: .2rem; 176 | width: .25rem; 177 | border-radius: 50%; 178 | background: #3d4448; 179 | } 180 | 181 | &::after { 182 | content: ""; 183 | position: absolute; 184 | right: .15rem; 185 | top: .08rem; 186 | width: 0; 187 | border: .12rem solid transparent; 188 | border-left-color: #3d4448; 189 | background: transparent; 190 | transform: rotate(140deg) scaleY(.4); 191 | } 192 | } 193 | } 194 | #comment_close { 195 | display: none; 196 | 197 | &:checked ~ #disqus { 198 | transform: translateY(0); 199 | } 200 | } 201 | #disqus_thread { 202 | background: #fff; 203 | padding: .2rem; 204 | height: 3rem; 205 | overflow-y: auto; 206 | border: 1px solid #eee; 207 | background: #f9f9f9; 208 | // box-shadow: 1px 1px 3px rgba(0,0,0,.2),-1px -1px 2px rgba(0,0,0,.2); 209 | border-radius: .03rem; 210 | } 211 | 212 | .page404 { 213 | font-size: .5rem; 214 | text-align: center; 215 | position: absolute; 216 | width: 100%; 217 | top: 50%; 218 | transform: translateY(-50%); 219 | } -------------------------------------------------------------------------------- /src/nuomi/player/font/demo_unicode.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | IconFont 7 | 8 | 9 | 29 | 30 | 31 |
32 |

IconFont 图标

33 |
    34 | 35 |
  • 36 | 37 |
    错误
    38 |
    &#xe641;
    39 |
  • 40 | 41 |
  • 42 | 43 |
    聚收藏
    44 |
    &#xe643;
    45 |
  • 46 | 47 |
  • 48 | 49 |
    垃圾箱
    50 |
    &#xe645;
    51 |
  • 52 | 53 |
  • 54 | 55 |
    声音
    56 |
    &#xe64c;
    57 |
  • 58 | 59 |
  • 60 | 61 |
    我的订单
    62 |
    &#xe655;
    63 |
  • 64 | 65 |
  • 66 | 67 |
    向右箭头
    68 |
    &#xe65f;
    69 |
  • 70 | 71 |
  • 72 | 73 |
    向左箭头
    74 |
    &#xe660;
    75 |
  • 76 | 77 |
  • 78 | 79 |
    聚收藏gift
    80 |
    &#xe684;
    81 |
  • 82 | 83 |
84 |

unicode引用

85 |
86 | 87 |

unicode是字体在网页端最原始的应用方式,特点是:

88 |
    89 |
  • 兼容性最好,支持ie6+,及所有现代浏览器。
  • 90 |
  • 支持按字体的方式去动态调整图标大小,颜色等等。
  • 91 |
  • 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
  • 92 |
93 |
94 |

注意:新版iconfont支持多色图标,这些多色图标在unicode模式下将不能使用,如果有需求建议使用symbol的引用方式

95 |
96 |

unicode使用步骤如下:

97 |

第一步:拷贝项目下面生成的font-face

98 |
@font-face {
 99 |   font-family: 'iconfont';
100 |   src: url('iconfont.eot');
101 |   src: url('iconfont.eot?#iefix') format('embedded-opentype'),
102 |   url('iconfont.woff') format('woff'),
103 |   url('iconfont.ttf') format('truetype'),
104 |   url('iconfont.svg#iconfont') format('svg');
105 | }
106 | 
107 |

第二步:定义使用iconfont的样式

108 |
.iconfont{
109 |   font-family:"iconfont" !important;
110 |   font-size:16px;font-style:normal;
111 |   -webkit-font-smoothing: antialiased;
112 |   -webkit-text-stroke-width: 0.2px;
113 |   -moz-osx-font-smoothing: grayscale;
114 | }
115 | 
116 |

第三步:挑选相应图标并获取字体编码,应用于页面

117 |
<i class="iconfont">&#x33;</i>
118 | 119 |
120 |

"iconfont"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。

121 |
122 |
123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /src/Router.js: -------------------------------------------------------------------------------- 1 | 2 | // TODO dynamic parame 3 | export default class Router { 4 | 5 | constructor (routes = []) { 6 | 7 | this._hash = ''; 8 | this.from = { 9 | path: '', 10 | fullPath: location.href 11 | }; 12 | this.to = { 13 | path: '', 14 | fullPath: location.href 15 | }; 16 | this.history = []; 17 | this.historyAnchor = -1; 18 | 19 | this.beforeEachFuncs = []; 20 | this.afterEachFuncs = []; 21 | 22 | this.origin = location.protocol + '//' + location.host + location.pathname; 23 | 24 | this.routes = routes; 25 | 26 | this.defaultPath = '/'; 27 | this.page404 = () => {}; 28 | 29 | this.routes.forEach(route => { 30 | if (route.default) { 31 | this.defaultPath = route.path; 32 | } 33 | if (route.path === '*') { 34 | this.page404 = route.handler; 35 | } 36 | }); 37 | } 38 | 39 | start () { 40 | window.addEventListener("hashchange", () => { 41 | this.hashName = location.hash.replace('#!', ''); 42 | console.log(this.hashName); 43 | }); 44 | this.firstPage(); 45 | } 46 | 47 | firstPage () { 48 | if (location.hash !== '') { 49 | this.hashName = location.hash.replace('#!', ''); 50 | } else { 51 | location.hash = '!' + this.defaultPath; 52 | } 53 | } 54 | 55 | get hashName () { 56 | return this._hash; 57 | } 58 | 59 | set hashName(newVal) { 60 | 61 | this.from.path = this.hashName; 62 | this.from.fullPath = `${this.origin}#!${this.hashName}`; 63 | 64 | this._hash = newVal; 65 | 66 | this.to.path = this.hashName; 67 | this.to.fullPath = `${this.origin}#!${this.hashName}`; 68 | 69 | this.history.push(this.hashName); 70 | this.historyAnchor += 1; 71 | 72 | this.hashChange ({ from: this.from, to: this.to }); 73 | } 74 | 75 | hashChange (parame) { 76 | 77 | if (this.routes.length) { 78 | 79 | let from = parame.from; 80 | let to = parame.to; 81 | const lastIndex = this.beforeEachFuncs.length - 1; 82 | const routesLastIndex = this.routes.length - 1; 83 | 84 | for (let i = 0; i < routesLastIndex; i++) { 85 | const route = this.routes[i]; 86 | 87 | if (this.hashName === route.path) { 88 | // Excute beforeEach functions 89 | if (this.beforeEachFuncs.length) { 90 | // beforeEach functions chain 91 | let index = 0; 92 | const next = () => { 93 | // console.log(index); 94 | if (index < lastIndex) { 95 | this.beforeEachFuncs[++index](from, to, next); 96 | } else { 97 | route.handler({ from, to }); 98 | } 99 | } 100 | this.beforeEachFuncs[0](from, to, next); 101 | 102 | } else { 103 | route.handler({ from, to }); 104 | } 105 | 106 | if (this.afterEachFuncs.length) { 107 | for (let j = 0; j < this.afterEachFuncs.length; j++) { 108 | this.afterEachFuncs[j](); 109 | } 110 | } 111 | 112 | return; 113 | } 114 | } 115 | 116 | // 404 page 117 | if (this.beforeEachFuncs.length) { 118 | // beforeEach functions chain 119 | let index = 0; 120 | const next = () => { 121 | // console.log(index); 122 | if (index < lastIndex) { 123 | this.beforeEachFuncs[++index](from, to, next, '404'); 124 | } else { 125 | this.page404({ from, to }); 126 | } 127 | } 128 | this.beforeEachFuncs[0](from, to, next, '404'); 129 | 130 | } else { 131 | this.page404({ from, to }); 132 | } 133 | } 134 | } 135 | 136 | beforeEach (func) { 137 | this.beforeEachFuncs.push(func); 138 | func(this.from, this.to, () => {}); 139 | 140 | return this; 141 | } 142 | 143 | afterEach (func) { 144 | this.afterEachFuncs.push(func); 145 | func(this.from, this.to); 146 | 147 | return this; 148 | } 149 | 150 | back () { 151 | if (this.history.length < 2) { 152 | return; 153 | } 154 | this.hashName = this.history[this.historyAnchor - 1]; 155 | } 156 | 157 | go (cout) { 158 | if (cout > 0 && (this.history.length - 1 - this.historyAnchor) >= cout) { 159 | this.hashName = this.history[this.historyAnchor - cout]; 160 | } 161 | 162 | if (cout < 0 && this.historyAnchor >= Math.abs(cout)) { 163 | this.hashName = this.history[this.historyAnchor + cout]; 164 | } 165 | } 166 | } -------------------------------------------------------------------------------- /src/nuomi/player/font/demo_symbol.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | IconFont 7 | 8 | 9 | 10 | 24 | 25 | 26 |
27 |

IconFont 图标

28 |
    29 | 30 |
  • 31 | 34 |
    错误
    35 |
    #icon-cuowu
    36 |
  • 37 | 38 |
  • 39 | 42 |
    聚收藏
    43 |
    #icon-jushoucang
    44 |
  • 45 | 46 |
  • 47 | 50 |
    垃圾箱
    51 |
    #icon-lajixiang
    52 |
  • 53 | 54 |
  • 55 | 58 |
    声音
    59 |
    #icon-shengyin
    60 |
  • 61 | 62 |
  • 63 | 66 |
    我的订单
    67 |
    #icon-wodedingdan
    68 |
  • 69 | 70 |
  • 71 | 74 |
    向右箭头
    75 |
    #icon-xiangyoujiantou
    76 |
  • 77 | 78 |
  • 79 | 82 |
    向左箭头
    83 |
    #icon-xiangzuojiantou
    84 |
  • 85 | 86 |
  • 87 | 90 |
    聚收藏gift
    91 |
    #icon-jushoucanggift
    92 |
  • 93 | 94 |
95 | 96 | 97 |

symbol引用

98 |
99 | 100 |

这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 101 | 这种用法其实是做了一个svg的集合,与另外两种相比具有如下特点:

102 |
    103 |
  • 支持多色图标了,不再受单色限制。
  • 104 |
  • 通过一些技巧,支持像字体那样,通过font-size,color来调整样式。
  • 105 |
  • 兼容性较差,支持 ie9+,及现代浏览器。
  • 106 |
  • 浏览器渲染svg的性能一般,还不如png。
  • 107 |
108 |

使用步骤如下:

109 |

第一步:引入项目下面生成的symbol代码:

110 |
<script src="./iconfont.js"></script>
111 |

第二步:加入通用css代码(引入一次就行):

112 |
<style type="text/css">
113 | .icon {
114 |    width: 1em; height: 1em;
115 |    vertical-align: -0.15em;
116 |    fill: currentColor;
117 |    overflow: hidden;
118 | }
119 | </style>
120 |

第三步:挑选相应图标并获取类名,应用于页面:

121 |
<svg class="icon" aria-hidden="true">
122 |   <use xlink:href="#icon-xxx"></use>
123 | </svg>
124 |         
125 |
126 | 127 | 128 | -------------------------------------------------------------------------------- /docs/5.index.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([5,15],{131:function(module,exports,__webpack_require__){"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _asyncToGenerator(e){return function(){var n=e.apply(this,arguments);return new Promise(function(e,t){function o(a,r){try{var i=n[a](r),l=i.value}catch(e){return void t(e)}return i.done?void e(l):Promise.resolve(l).then(function(e){o("next",e)},function(e){o("throw",e)})}return o("next")})}}function create(parent){var option=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];parent="string"==typeof parent?_gtool.g.$(parent):parent,parent.innerHTML=_template2.default;var oldConsole=console.log,outputList=[];console.log=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];n?outputList.push('
> '+e+"
"):outputList.push("
< "+e+"
")},console.log("let app1 = new Observer({\n name: {\n firstName: 'shaofeng',\n lastName: 'liang'\n },\n age: 25\n });",!0);var app1=new _Observer2.default({name:{firstName:"shaofeng",lastName:"liang"},age:25});console.log("app1.$watch('name', function (newName) {\n console.log('我的姓名发生了变化,可能是姓氏变了,也可能是名字变了。')\n });",!0),app1.$watch("name",function(e){console.log("我的姓名发生了变化,可能是姓氏变了,也可能是名字变了。新值为:"+e)}),console.log("app1.data.name.firstName = 'hahaha';",!0),app1.data.name.firstName="hahaha",console.log("app1.data.name.lastName = 'blablabla';",!0),app1.data.name.lastName="blablabla",playCommand(outputList),console.log=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];addList(n?'
> '+e+"
":"
< "+e+"
")};var input=_gtool.g.$(".console input");input.addEventListener("keyup",function(e){if(e.keyCode===_gtool.CONST.KEY_CODE.ENTER){var command=input.value;console.log(command,!0),/app1\.data\.(\w+)+?\s?=?('.*?')?/.test(command)?eval(command):console.log("[warning] Command illegal"),input.value=""}})}function addList(e){var n=_gtool.g.$(".console .output");n.innerHTML+=e,n.scrollTop=n.scrollHeight}Object.defineProperty(exports,"__esModule",{value:!0});var playCommand=function(){var e=_asyncToGenerator(regeneratorRuntime.mark(function e(n){var t;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:t=0;case 1:if(!(t1&&void 0!==arguments[1]?arguments[1]:function(){};this.changeMethods[e]=n}},{key:"callChangeMethods",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";e in this.changeMethods&&this.changeMethods[e](n)}},{key:"bubbling",value:function(e,n){var t=this,o=e.slice(0,e.length-1).split("."),a=o.length;if(this.callChangeMethods(e,n),a){o.forEach(function(e){t.callChangeMethods(e,n)});for(var r=o.length-1;r>=2;r--){var i=o.slice(0,r);this.callChangeMethods(i.join("."),n)}}}}]),e}(),l=function(){function e(n){o(this,e),this.originalData=this.data=n,this.handler=new i,this.observe(this.originalData)}return r(e,[{key:"observe",value:function(e){this.checkData(e)}},{key:"checkData",value:function(e){var n=this,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";"object"===("undefined"==typeof e?"undefined":a(e))&&Object.keys(e).forEach(function(o){n.initProperty(e,o,e[o],t)})}},{key:"initProperty",value:function(e,n,t,o){var a=this;o+=n+".",this.checkData(t,o),Object.defineProperty(e,n,{enumerable:!0,configurable:!1,get:function(){return t},set:function(e){a.checkData(e,parent),a.handler.bubbling(o,e),t=e}})}},{key:"$watch",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};this.handler.onChange(e,n)}}]),e}();n.default=l},383:function(e,n){e.exports='
'}}); 2 | //# sourceMappingURL=5.index.js.map -------------------------------------------------------------------------------- /src/nuomi/markdown/GMD.js: -------------------------------------------------------------------------------- 1 | export default class GMD { 2 | constructor () { 3 | this.diffLines = []; 4 | this.init(); 5 | } 6 | 7 | init () { 8 | this.markPattern = { 9 | separator: { 10 | regex: /^[\-=\*]{3,}/, 11 | template: '
', 12 | singleLine: true, 13 | lineStart: true, 14 | }, 15 | emphasis: { 16 | regex: /[\*_]([^\*_]+?)[\*_](?!\*)/, 17 | template: '$1', 18 | singleLine: false 19 | }, 20 | strongEm: { 21 | regex: /[\*_]{2}(.*?)[\*_]{2}/, 22 | template: '$1', 23 | singleLine: false 24 | }, 25 | strikeThrough: { 26 | regex: /~{2}(.*?)~{2}/, 27 | template: '$1', 28 | singleLine: false 29 | }, 30 | ul: { 31 | regex: /^[\*\-\+]\s([^\n]+)/, 32 | template: '
    $1
', 33 | singleLine: false, 34 | lineStart: true 35 | }, 36 | ol: { 37 | regex: /^\d+\.\s([^\n]+)/, 38 | template: '
    $1
', 39 | singleLine: false, 40 | lineStart: true 41 | }, 42 | link: { 43 | regex: /(?:[^!]|^)\[([^\]]+?)\]\(([^\)]+?)\)/, 44 | template: '$1', 45 | singleLine: false 46 | }, 47 | img: { 48 | regex: /!\[([^\]]*?)\]\(([^\)]+?)\)/, 49 | template: '$1', 50 | singleLine: false 51 | }, 52 | blockquote: { 53 | regex: /^\>\s([^\n]+)/, 54 | template: '
$1
', 55 | singleLine: false, 56 | lineStart: true 57 | }, 58 | code: { 59 | regex: /`([^`\n]+)`/, 60 | template: '$1', 61 | singleLine: false 62 | }, 63 | pre: { 64 | regex: /```(\w+)([^`]+?)```/, 65 | template: '
$2
', 66 | singleLine: false 67 | }, 68 | } 69 | 70 | // Add h1-h6 regex 71 | for (let i = 1; i <= 6; i++) { 72 | const reg = '^\s*?' + '#'.repeat(i) + '\\s([^\\n]+)'; 73 | this.markPattern['h' + i] = { 74 | regex: new RegExp(reg), 75 | template: `$1`, 76 | singleLine: false, 77 | lineStart: true 78 | }; 79 | } 80 | 81 | console.log(this.markPattern); 82 | } 83 | 84 | update () { 85 | return this.parse(this.textarea.value); 86 | } 87 | 88 | parse (val) { 89 | const lines = val.split(/\n{2,}/); 90 | 91 | const linesParsed = lines.map(line => { 92 | return this.parseLine(line); 93 | }); 94 | 95 | const result = linesParsed.join('\n'); 96 | 97 | return result; 98 | } 99 | 100 | parseLine (line) { 101 | 102 | let isBlockEle = false; 103 | let isQuote = false; 104 | 105 | for (let key in this.markPattern) { 106 | 107 | const pattern = this.markPattern[key]; 108 | 109 | if (!pattern.regex.test(line)) { 110 | continue; 111 | } 112 | 113 | if (pattern.singleLine) { 114 | line = line.replace(pattern.regex, pattern.template); 115 | return line; 116 | } 117 | 118 | if (pattern.lineStart) { 119 | 120 | if (['blockquote', 'ol', 'ul'].indexOf(key) >= 0) { 121 | const list = []; 122 | // const matches = line.match(new RegExp(pattern.regex, 'g')); 123 | const matches = line.split('\n'); 124 | 125 | matches.forEach(match => { 126 | 127 | if (key === 'blockquote') { 128 | const filtered = match.replace(/>\s/, ''); 129 | list.push(this.parseLine(filtered)); 130 | } else { 131 | const filtered = match.replace(/[\*\-\+]\s|\d+\.\s/, ''); 132 | list.push(`
  • ${filtered}
  • `); 133 | } 134 | }); 135 | 136 | // console.log(list.join('\n'), pattern.template, key); 137 | 138 | line = pattern.template.replace('$1', list.join('')); 139 | 140 | continue; 141 | } 142 | 143 | const filtered = pattern.template.replace('{data}', RegExp.$1); 144 | 145 | // line = line.replace(RegExp.$_, filtered); 146 | line = line.replace(new RegExp(pattern.regex), pattern.template); 147 | 148 | isBlockEle = true; 149 | 150 | continue; 151 | // line = line.replace(match[0], newContent); 152 | } 153 | 154 | line = line.replace(new RegExp(pattern.regex, 'g'), pattern.template); 155 | } 156 | 157 | if (!isBlockEle) { 158 | return `

    ${line}

    `; 159 | } else { 160 | return line; 161 | } 162 | } 163 | 164 | diff () { 165 | 166 | } 167 | 168 | } -------------------------------------------------------------------------------- /docs/static/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/nuomi/player/fonts/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /static/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Created by FontForge 20120731 at Sat Mar 4 16:47:23 2017 6 | By admin 7 | 8 | 9 | 10 | 24 | 26 | 28 | 30 | 32 | 34 | 38 | 40 | 44 | 48 | 52 | 56 | 58 | 60 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /docs/static/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Created by FontForge 20120731 at Sat Mar 4 16:47:23 2017 6 | By admin 7 | 8 | 9 | 10 | 24 | 26 | 28 | 30 | 32 | 34 | 38 | 40 | 44 | 48 | 52 | 56 | 58 | 60 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/nuomi/player/font/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Created by FontForge 20120731 at Sat Mar 4 16:47:23 2017 6 | By admin 7 | 8 | 9 | 10 | 24 | 26 | 28 | 30 | 32 | 34 | 38 | 40 | 44 | 48 | 52 | 56 | 58 | 60 | 63 | 64 | 65 | --------------------------------------------------------------------------------