Skip to content

Commit

Permalink
feat: template simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
lwyj123 committed Sep 26, 2018
1 parent 22a533b commit 44c3c49
Show file tree
Hide file tree
Showing 18 changed files with 661 additions and 5 deletions.
17 changes: 16 additions & 1 deletion packages/xgplayer-music/browser/index.js

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion packages/xgplayer-music/dist/index.js

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion packages/xgplayer-music/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@
"postcss-cssnext": "^3.1.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"webpack": "^4.11.0"
"webpack": "^4.11.0",
"yuefu-template-compiler": "^1.1.3"
},
"peerDependency": {
"xgplayer": "^0.1.0"
},
"devDependencies": {
"babel-preset-es2015": "^6.24.1",
"url-loader": "^1.1.1",
"webpack-cli": "^3.0.2"
}
}
4 changes: 3 additions & 1 deletion packages/xgplayer-music/src/music.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Player from 'xgplayer'
import Lyric from './lyric'
import Template from './template'
import Analyze from './analyze'
import Xhr from './xhr'
let mode
Expand Down Expand Up @@ -277,5 +278,6 @@ class Music extends Player {
export default Music
export {
Lyric,
Analyze
Analyze,
Template
}
101 changes: 101 additions & 0 deletions packages/xgplayer-music/src/template/ASTCompiler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
function Compile (el, templateDescriptor, model, options) {
this.model = model
this.$vm = Object.assign({}, model.data, model.methods, options.inject)
this.$el = document.querySelector(el)
if (this.$el) {
this.$fragment = this.node2Fragment()
this.init(templateDescriptor)
this.$el.appendChild(this.$fragment)
}
}

function createElement (tag, data, childrens = []) {
const dom = document.createElement(tag)

const attrs = (data && data.attrs) ? data.attrs : {}
Object.keys(attrs).forEach((attr) => {
dom.setAttribute(attr, data.attrs[attr])
})

if (data && (data.class || data.staticClass)) {
dom.setAttribute('class', ((data.class ? data.class : ' ') + ' ' + (data.staticClass ? data.staticClass : ' ')).trim())
}

childrens && childrens.forEach((child) => {
dom.appendChild(child)
})
return dom
}

Compile.prototype = {
node2Fragment: function () {
var fragment = document.createDocumentFragment()

return fragment
},

init: function (templateDescriptor) {
this.$vm.ast = templateDescriptor.ast
this.$vm.render = new Function(templateDescriptor.render)
this.$vm._c = createElement
this.$vm._e = document.createComment.bind(document, '')
// this.$vm._v = document.createTextNode;
this.$vm._v = document.createTextNode.bind(document)
this.$vm._s = (str) => {
return `${str.toString()}`
}
let res = this.$vm.render()
this.$fragment.appendChild(res)
this.compileElement(this.$fragment, [this.$vm.ast])
this.model.mounted.call(this.$vm)
},

compileElement: function (el, ast) {
var childNodes = el.childNodes;
[].slice.call(childNodes).forEach((node, index) => {
if (this.isElementNode(node) || this.isTextNode(node)) {
this.compile(node, ast[index])
}

if (node.childNodes && node.childNodes.length) {
this.compileElement(node, ast[index].children)
}
})
},

compile: function (node, ast) {
if (ast.events) {
const self = this
Object.keys(ast.events).forEach((event) => {
if (event === 'click') {
const exp = ast.events[event].value
const fn = self.$vm[exp]
node.addEventListener('click', fn.bind(self.$vm), false)
}
if (event === 'mousedown') {
const exp = ast.events[event].value
const fn = self.$vm[exp]
node.addEventListener('mousedown', fn.bind(self.$vm), false)
}
})
}
},

isDirective: function (attr) {
return attr.indexOf('v-') === 0
},

isEventDirective: function (dir) {
return dir.indexOf('on') === 0
},

isElementNode: function (node) {
return node.nodeType === 1
},

isTextNode: function (node) {
return node.nodeType === 3
}
}

export default Compile
48 changes: 48 additions & 0 deletions packages/xgplayer-music/src/template/Template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { compile } from 'yuefu-template-compiler'
import ASTCompiler from './ASTCompiler'
import Player from 'xgplayer'

import { insertCss } from './utils'

class Template {
constructor (element, component, player, model, options) {
this.player = player
this.options = options
this.template = component.template
this.model = component.model
this.style = component.style
this.element = element
}
render () {
console.log('[template]render:')
if (!this.template) {
throw new Error('未设置template')
}
const compiled = compile(this.template, this.options)

console.log('[template]compiled:', compiled)

const astCompiler = new ASTCompiler(this.element, compiled, this.model, {
inject: {
$player: this.player, // 注入$player对象
$util: Player.util // 注入$util对象
}
})
// const mvvm = new MVVM({
// el: this.element,
// data: this.model.data,
// mounted: this.model.mounted,
// methods: this.model.methods,
// templateDescriptor: compiled
// })

// 插入template的css
// TODO: 考虑会影响其他样式,考虑加入scoped
const style = insertCss(this.style)
console.log('[template]css injected:', compiled)
}
}
Template.DEFAULTS = {}
// Module.name = 'undefinedModule'

export default Template
13 changes: 13 additions & 0 deletions packages/xgplayer-music/src/template/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Player from 'xgplayer'
import Template from './Template'
import learningTemplate from '../templateExamples/learning'

const templatePlugin = function (player) {
// TODO: 模版可配置化
// TODO: 异步加载模版
// TODO: 组件化机制
const template = new Template('#wrapper', learningTemplate, this)
template.render()
}

Player.install('template', templatePlugin)
55 changes: 55 additions & 0 deletions packages/xgplayer-music/src/template/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
var containers = [] // will store container HTMLElement references
var styleElements = [] // will store {prepend: HTMLElement, append: HTMLElement}

var usage = 'insert-css: You need to provide a CSS string. Usage: insertCss(cssString[, options]).'

export function insertCss (css, options) {
options = options || {}

if (css === undefined) {
throw new Error(usage)
}

var position = options.prepend === true ? 'prepend' : 'append'
var container = options.container !== undefined ? options.container : document.querySelector('head')
var containerId = containers.indexOf(container)

// first time we see this container, create the necessary entries
if (containerId === -1) {
containerId = containers.push(container) - 1
styleElements[containerId] = {}
}

// try to get the correponding container + position styleElement, create it otherwise
var styleElement

if (styleElements[containerId] !== undefined && styleElements[containerId][position] !== undefined) {
styleElement = styleElements[containerId][position]
} else {
styleElement = styleElements[containerId][position] = createStyleElement()

if (position === 'prepend') {
container.insertBefore(styleElement, container.childNodes[0])
} else {
container.appendChild(styleElement)
}
}

// strip potential UTF-8 BOM if css was read from a file
if (css.charCodeAt(0) === 0xFEFF) { css = css.substr(1, css.length) }

// actually add the stylesheet
if (styleElement.styleSheet) {
styleElement.styleSheet.cssText += css
} else {
styleElement.textContent += css
}

return styleElement
}

function createStyleElement () {
var styleElement = document.createElement('style')
styleElement.setAttribute('type', 'text/css')
return styleElement
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 44c3c49

Please sign in to comment.