@dolphinweex/dof-weex-vue-precompiler
Version:
a precompiler for weex-vue-render.
162 lines (144 loc) • 4.73 kB
JavaScript
const identifyTag = require('./identifier')
const components = require('./components')
const hooks = require('./hooks')
const util = require('./util')
const defaults = require('./config')
const camelCase = require('camelcase');
const arrayMergeOpts = [
'weexRegisteredComponents',
'weexBuiltInComponents',
'aliweexComponents'
]
const mergeStrats = {
px2rem: function (thisConfig, config) {
const { px2rem } = config
const { px2rem: thisPx2rem } = thisConfig
if (px2rem) {
for (k in px2rem) {
if (k === 'rootValue') {
// ignore rootValue. Always use 750. Why? We use meta[name=weex-viewport] and
// meta.setViewport API to set design viewport width, and they would be broken if
// we use other rootValue here.
continue
}
else if (px2rem.hasOwnProperty(k)) {
thisPx2rem[k] = px2rem[k]
}
}
}
return thisPx2rem
}
}
function mergeConfig(thisConfig, config) {
if (config) {
const {
weexRegisteredComponents,
weexBuiltInComponents,
aliweex,
aliweexComponents,
processHooks
} = config
// merge all fields except arrays.
for (const k in config) {
if (arrayMergeOpts.indexOf(k) <= -1) {
thisConfig[k] = mergeStrats[k] ? mergeStrats[k](thisConfig, config) : config[k]
}
}
// merge array fields.
arrayMergeOpts.forEach(function (optName) {
const vals = config[optName]
if (util.isArray(vals)) {
thisConfig[optName] = util.mergeStringArray(
thisConfig[optName],
vals
)
}
})
}
// At last, set the preservedTags.
thisConfig.preservedTags = thisConfig.weexRegisteredComponents
.concat(thisConfig.weexBuiltInComponents)
if (config && config.aliweex) {
thisConfig.preservedTags = thisConfig.preservedTags.concat(
thisConfig.aliweexComponents
)
}
}
class Precompiler {
/**
* config:
* - preservedTags: the preserved weex components tag list. The default
* value is: ['a','container','div','image','img','text','input',
* 'switch','list','scroller','waterfall','slider','indicator',
* 'loading-indicator','loading','refresh','textarea','video','web'].
* If you have other components as plugins installed in weex, you
* should add them to this lists, add pass the whole list to this.
* - autoprefixer: options for autoprefixer. default is { browsers:
* ['> 0.1%', 'ios >= 8', 'not ie < 12'] }.
* - px2rem: options for postcss-plugin-px2rem. default is: { rootValue: 75 }
* @param {*} config
*/
constructor (config) {
this.config = defaults
mergeConfig(this.config, config)
}
isSamelayerComponent(tag, sameLayerComponents) {
tag = camelCase(tag);
if (tag && sameLayerComponents.length > 0) {
return sameLayerComponents.find(comp=>comp.componentName.toUpperCase() == tag.toUpperCase())
}
return false
}
precompile (el, { sameLayerComponents = [] }) {
const attrsMap = el.attrsMap ? el.attrsMap : (el.attrsMap = {})
const attrsList = el.attrsList ? el.attrsList : (el.attrsList = [])
const attrs = el.attrs ? el.attrs : (el.attrs = [])
const staticClass = (el.staticClass || '').replace(/"/g, '')
const args = [el, attrsMap, attrsList, attrs, staticClass]
const tag = identifyTag(el)
const {
weexBuiltInComponents,
weexRegisteredComponents,
aliweex,
aliweexComponents
} = this.config
if (weexBuiltInComponents.indexOf(el._origTag || el.tag) > -1) {
el._weexBuiltIn = true
}
else if (
weexRegisteredComponents.indexOf(el.tag) > -1
|| aliweex && aliweexComponents.indexOf(el.tag) > -1
) {
el._weexRegistered = true
}
// add by wuhl55 添加判断是否是同层渲染组件
else if (this.isSamelayerComponent(el.tag, sameLayerComponents)) {
el._sameLayerComponent = true
el._userRegistered = true
}
else{
el._userRegistered = true
}
// use component processors to process components' special attrs.
const processor = components[tag]
if (processor) {
processor.apply(this, args)
}
// process hooks.
if (this.config.processHooks) {
var processHooks = this.config.processHooks
for (let index = 0; index < processHooks.length; index++) {
const k = processHooks[index];
hooks[k].apply(this, args)
}
} else {
for (const k in hooks) {
hooks[k].apply(this, args)
}
}
}
}
module.exports = function getPrecompiler(config) {
const precompiler = new Precompiler(config)
return precompiler.precompile.bind(precompiler)
}