| /* |
| * 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 |
| } |