blob: bec967f846f72f544c7a601800fa3439b6aa3216 [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.
*/
// @flow
import { extend } from '../utils/func'
/**
* viewport priority:
*
* 1. meta weex-viewport (developer custom)
* 2. setViewport(config) := config.width (private code) @deprecated
* 3. process.env.VIEWPORT_WIDTH (buid time)
*
*/
let isInited = false
const DEFAULT_VIEWPORT_WIDTH = 750
/**
* get viewport width from weex-viewport meta.
*/
const envViewportWidth = parseInt(process.env.VIEWPORT_WIDTH)
let width: number = !isNaN(envViewportWidth) && envViewportWidth > 0
? envViewportWidth
: DEFAULT_VIEWPORT_WIDTH
let wxViewportMeta = document.querySelector('meta[name="weex-viewport"]')
const metaWidth = wxViewportMeta && parseInt(wxViewportMeta.getAttribute('content'))
if (metaWidth && !isNaN(metaWidth) && metaWidth > 0) {
width = metaWidth
}
let dpr: number = 0
let screenWidth: number = 0
let screenHeight: number = 0
const info: {
dpr: number,
scale: number,
rem: number,
deviceWidth: number,
deviceHeight: number
} = {
dpr,
scale: 0,
rem: 0,
deviceWidth: 0,
deviceHeight: 0
}
/**
* set root font-size for rem units. If already been set, just skip this.
*/
function setRootFont (width: number): void {
const doc = window.document
const rem = width / 10
if (!doc.documentElement) { return }
const rootFontSize = doc.documentElement.style.fontSize
if (!rootFontSize) {
doc.documentElement.style.fontSize = rem + 'px'
info.rem = rem
}
}
function setMetaViewport (width: number): void {
if (!wxViewportMeta) {
wxViewportMeta = document.createElement('meta')
wxViewportMeta.setAttribute('name', 'weex-viewport')
}
else {
const metaWidth = parseInt(wxViewportMeta.getAttribute('content'))
if (metaWidth === width) {
return
}
}
wxViewportMeta.setAttribute('content', width + '')
}
/**
* export viewport info.
*/
export function init (viewportWidth: number = width): ?{
dpr: number,
scale: number,
rem: number,
deviceWidth: number,
deviceHeight: number
} {
if (!isInited) {
isInited = true
const doc = window.document
if (!doc) {
console.error('[vue-render] window.document is undfined.')
return
}
if (!doc.documentElement) {
console.error('[vue-render] document.documentElement is undfined.')
return
}
dpr = info.dpr = window.devicePixelRatio
screenWidth = doc.documentElement.clientWidth
screenHeight = doc.documentElement.clientHeight
const resetDeviceHeight = function () {
screenHeight = doc.documentElement.clientHeight
const env = window.weex && window.weex.config.env
info.deviceHeight = env.deviceHeight = screenHeight * dpr
}
// set root font for rem.
setRootFont(screenWidth)
setMetaViewport(viewportWidth)
window.addEventListener('resize', resetDeviceHeight)
/**
* why not to use window.screen.width to get screenWidth ? Because in some
* old webkit browser on android system it get the device pixel width, which
* is the screenWidth multiply by the device pixel ratio.
* e.g. ip6 -> get 375 for virtual screen width.
*/
const scale = screenWidth / viewportWidth
/**
* 1. if set initial/maximum/mimimum-scale some how the page will have a bounce
* effect when user drag the page towards horizontal axis.
* 2. Due to compatibility reasons, not to use viewport meta anymore. Just bring
* a parameter scale into the style value processing.
*/
// const contents = [
// `width=${viewportWidth}`,
// `initial-scale=${scale}`,
// `maximum-scale=${scale}`,
// `minimum-scale=${scale}`,
// `user-scalable=no`
// ]
// let meta = doc.querySelector('meta[name="viewport"]')
// if (!meta) {
// meta = doc.createElement('meta')
// meta.setAttribute('name', 'viewport')
// document.querySelector('head').appendChild(meta)
// }
// meta.setAttribute('content', contents.join(','))
extend(info, {
scale,
deviceWidth: screenWidth * dpr,
deviceHeight: screenHeight * dpr
})
}
return info
}
/**
* reset viewport width and scale.
* @return new scale.
*/
export function resetViewport (viewportWidth: number): number {
setMetaViewport(viewportWidth)
const newScale = screenWidth / viewportWidth
info.scale = newScale
return newScale
}
export function getViewportInfo (): {
dpr: number,
scale: number,
rem: number,
deviceWidth: number,
deviceHeight: number
} {
return info
}