blob: ba11ed50108034a7284bcad03e59f03c323bda11 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {
getHeadStyleMap,
getComponentStyle,
extractComponentStyle
} from '../core'
import {
normalizeStyle,
camelizeKeys,
extend
} from '../utils'
/**
* get a beforeCreate hook, which has a mark to identify the hook function itself.
*/
function getIdentifiedBeforeCreate () {
const disposed = {} // disposed components. Already scanned.
function beforeCreate () {
/**
* get static class style map from document's styleSheets.
* Weex.on will create a Vue instance. In this case we'll ignore it, since
* it's not sure whether the scoped style has already attached to head or not.
*/
const tagName = this.$options && this.$options._componentTag
/**
* For vue-loader ^11.3.x, there's no injectStyle function. The styleSheet
* is already injected into the head. Just scan it.
*/
// async component.
if ((this.$vnode && this.$vnode.data && this.$vnode.data.tag === 'component')
|| (this === this.$root && this.$options && !this._firstScanned)) {
this._firstScanned = true
extend(weex._styleMap, getHeadStyleMap())
}
/**
* For vue-loader ^12.0, the injectStyle function is hooked. We should scan
* style map after the injectStyle hook called.
*/
if (((this === this.$root && this.$options)
|| (tagName
&& !weex._components[tagName]
&& !disposed[tagName]))
&& !this._secondScanned) {
disposed[tagName] = 1
this._secondScanned = true
const hooks = this.$options.beforeCreate
const len = hooks.length
let thisHookIdx = 0 // index of this hook in the hooks array.
for (; thisHookIdx < len; thisHookIdx++) {
if (hooks[thisHookIdx]._styleMixin) { break }
}
if (thisHookIdx !== len - 1) {
const func = hooks[len - 1]
hooks[len - 1] = function () {
// call the original injectStyle hook.
func.call(this)
// scan the new appended styleSheet.
extend(weex._styleMap, getHeadStyleMap())
hooks[len - 1] = func
}
}
}
}
beforeCreate._styleMixin = true
return beforeCreate
}
export default {
beforeCreate: getIdentifiedBeforeCreate(),
methods: {
$processStyle (style) {
window._style_processing_added = true
if (!style) {
return
}
return normalizeStyle(camelizeKeys(style))
},
_extractComponentStyle () {
return extractComponentStyle(this)
},
/**
* get style from class, staticClass, style and staticStyle.
* merge styles priority: high -> low
* 1. data.style (bound style).
* 2. data.staticStyle (inline styles).
* 3. data.class style (bound class names).
* 4. data.staticClass style (scoped styles or static classes).
*/
_getComponentStyle (data) {
return getComponentStyle(this)
},
_getParentRect () {
const parentElm = this.$options._parentElm
return parentElm && parentElm.getBoundingClientRect()
}
}
}