提交 4d054896 编写于 作者: Q qiang

Merge branch 'dev' into alpha

......@@ -52,8 +52,10 @@ const media = [
'chooseFile',
'previewImage',
'getImageInfo',
'getVideoInfo',
'saveImageToPhotosAlbum',
'compressImage',
'compressVideo',
'getRecorderManager',
'getBackgroundAudioManager',
'createAudioContext',
......
......@@ -58,8 +58,10 @@
"uni.chooseFile": true,
"uni.previewImage": true,
"uni.getImageInfo": true,
"uni.getVideoInfo": true,
"uni.saveImageToPhotosAlbum": true,
"uni.compressImage": true,
"uni.compressVideo": true,
"uni.getRecorderManager": true,
"uni.getBackgroundAudioManager": true,
"uni.createInnerAudioContext": true,
......
......@@ -739,8 +739,8 @@ describe('mp:compiler-extra', () => {
)
assertCodegen(
'<view v-if="test1(key)&&test2(key)">{{getValue(key)}}</view>',
'<block wx:if="{{$root.m0&&$root.m1}}"><view>{{$root.m2}}</view></block>',
'with(this){var m0=test1(key);var m1=test2(key);var m2=m0&&m1?getValue(key):null;$mp.data=Object.assign({},{$root:{m0:m0,m1:m1,m2:m2}})}'
'<block wx:if="{{$root.m0}}"><view>{{$root.m1}}</view></block>',
'with(this){var m0=test1(key)&&test2(key);var m1=m0?getValue(key):null;$mp.data=Object.assign({},{$root:{m0:m0,m1:m1}})}'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view v-if="item">{{getValue(item)}}</view></view>',
......
......@@ -15,7 +15,7 @@ const {
getTagName
} = require('../../h5')
const {
const {
hasOwn,
hyphenate,
traverseFilter,
......@@ -149,41 +149,41 @@ module.exports = {
const methodName = callee.name
switch (methodName) {
case METHOD_CREATE_ELEMENT:
{
const tagNode = path.node.arguments[0]
if (t.isStringLiteral(tagNode)) {
// 需要把标签增加到 class 样式中
const tagName = getTagName(tagNode.value)
if (tagName !== tagNode.value) {
addStaticClass(path, '_' + tagNode.value)
}
tagNode.value = getComponentName(hyphenate(tagName))
// 组件增加 vueId
if (this.options.platform.isComponent(tagNode.value)) {
addVueId(path, this)
}
// 查找全局组件
checkUsingGlobalComponents(
tagNode.value,
this.options.globalUsingComponents,
this
)
}
if (this.options.scopeId) {
addStaticClass(path, this.options.scopeId)
}
const dataPath = path.get('arguments.1')
dataPath && dataPath.isObjectExpression() && traverseData(dataPath, this, tagNode.value)
{
const tagNode = path.node.arguments[0]
if (t.isStringLiteral(tagNode)) {
// 需要把标签增加到 class 样式中
const tagName = getTagName(tagNode.value)
if (tagName !== tagNode.value) {
addStaticClass(path, '_' + tagNode.value)
}
tagNode.value = getComponentName(hyphenate(tagName))
// 组件增加 vueId
if (this.options.platform.isComponent(tagNode.value)) {
addVueId(path, this)
}
// 查找全局组件
checkUsingGlobalComponents(
tagNode.value,
this.options.globalUsingComponents,
this
)
}
if (this.options.scopeId) {
addStaticClass(path, this.options.scopeId)
}
const dataPath = path.get('arguments.1')
dataPath && dataPath.isObjectExpression() && traverseData(dataPath, this, tagNode.value)
}
break
case METHOD_TO_STRING:
{
const stringNodes = path.node.arguments[0]
stringNodes.$toString = true
path.replaceWith(stringNodes)
{
const stringNodes = path.node.arguments[0]
stringNodes.$toString = true
path.replaceWith(stringNodes)
}
break
case METHOD_RENDER_LIST:
......@@ -202,7 +202,11 @@ module.exports = {
// event
return path.skip()
}
path = path.findParent((path) => path.isLogicalExpression()) || path
path.skip()
if (path.findParent((path) => path.shouldSkip)) {
return
}
path.replaceWith(
getMemberExpr(
path,
......@@ -265,4 +269,4 @@ module.exports = {
path.replaceWith(root)
}
}
}
......@@ -28,7 +28,8 @@ module.exports = (api, options) => {
'--minimize': 'Tell webpack to minimize the bundle using the TerserPlugin.',
'--auto-host': 'specify automator host',
'--auto-port': 'specify automator port',
'--subpackage': 'specify subpackage'
'--subpackage': 'specify subpackage',
'--plugin': 'specify plugin'
}
}, async (args) => {
for (const key in defaults) {
......@@ -42,6 +43,10 @@ module.exports = (api, options) => {
process.env.UNI_SUBPACKGE = args.subpackage
}
if (args.plugin && platforms.includes(process.env.UNI_PLATFORM)) {
process.env.UNI_MP_PLUGIN = args.plugin
}
require('./util').initAutomator(args)
args.entry = args.entry || args._[0]
......@@ -190,4 +195,4 @@ async function build (args, api, options) {
module.exports.defaultModes = {
'uni-build': process.env.NODE_ENV
}
}
......@@ -197,7 +197,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
if (!isAppView) { // app-plus view不需要copy
plugins.push(new CopyWebpackPlugin(getCopyWebpackPluginOptions(manifestPlatformOptions, vueOptions)))
}
if (!process.env.UNI_SUBPACKGE) {
if (!process.env.UNI_SUBPACKGE || !process.env.UNI_MP_PLUGIN) {
try {
const automatorJson = require.resolve('@dcloudio/uni-automator/dist/automator.json')
plugins.push(new CopyWebpackPlugin([{
......
......@@ -38,6 +38,8 @@ function getProvides () {
if (process.env.UNI_USING_COMPONENTS) {
if (process.env.UNI_SUBPACKGE) {
provides.createApp = [uniPath, 'createSubpackageApp']
} else if (process.env.UNI_MP_PLUGIN) {
provides.createApp = [uniPath, 'createPlugin']
} else {
provides.createApp = [uniPath, 'createApp']
}
......@@ -126,11 +128,11 @@ class PreprocessAssetsPlugin {
function initSubpackageConfig (webpackConfig, vueOptions) {
if (process.env.UNI_OUTPUT_DEFAULT_DIR === process.env.UNI_OUTPUT_DIR) { // 未自定义output
process.env.UNI_OUTPUT_DIR = path.resolve(process.env.UNI_OUTPUT_DIR, process.env.UNI_SUBPACKGE)
process.env.UNI_OUTPUT_DIR = path.resolve(process.env.UNI_OUTPUT_DIR, (process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN))
}
vueOptions.outputDir = process.env.UNI_OUTPUT_DIR
webpackConfig.output.path(process.env.UNI_OUTPUT_DIR)
webpackConfig.output.jsonpFunction('webpackJsonp_' + process.env.UNI_SUBPACKGE)
webpackConfig.output.jsonpFunction('webpackJsonp_' + (process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN))
}
module.exports = {
......@@ -162,7 +164,7 @@ module.exports = {
new webpack.ProvidePlugin(getProvides())
]
if (process.env.UNI_SUBPACKGE && process.env.UNI_SUBPACKGE !== 'main') {
if ((process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN) && process.env.UNI_SUBPACKGE !== 'main') {
plugins.push(new PreprocessAssetsPlugin())
}
......@@ -272,7 +274,7 @@ module.exports = {
}))
}
if (process.env.UNI_SUBPACKGE) {
if (process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN) {
initSubpackageConfig(webpackConfig, vueOptions)
}
......
......@@ -184,7 +184,7 @@ module.exports = function generateJson (compilation) {
delete jsonObj.navigationBarShadow
}
if (process.env.UNI_SUBPACKGE && jsonObj.usingComponents) {
if ((process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN) && jsonObj.usingComponents) {
jsonObj.usingComponents = normalizeUsingComponents(name, jsonObj.usingComponents)
}
const source = JSON.stringify(jsonObj, null, 2)
......
......@@ -110,7 +110,6 @@ export const canvasToTempFilePath = {
quality: {
type: Number,
validator (value, params) {
value = Math.floor(value)
params.quality = value > 0 && value < 1 ? value : 1
}
}
......
......@@ -10,6 +10,10 @@ export const chooseVideo = {
params.sourceType = sourceType.length ? sourceType : SOURCE_TYPES
}
},
compressed: {
type: Boolean,
default: true
},
maxDuration: {
type: Number,
default: 60
......
import getRealPath from 'uni-platform/helpers/get-real-path'
export const compressVideo = {
src: {
type: String,
required: true,
validator (src, params) {
params.src = getRealPath(src)
}
},
quality: {
type: String
},
bitrate: {
type: Number
},
fps: {
type: Number
},
resolution: {
type: Number
}
}
import getRealPath from 'uni-platform/helpers/get-real-path'
export const getVideoInfo = {
src: {
type: String,
required: true,
validator (src, params) {
params.src = getRealPath(src)
}
}
}
......@@ -26,8 +26,9 @@ import {
import createApp from './wrapper/create-app'
import createPage from './wrapper/create-page'
import createComponent from './wrapper/create-component'
import createComponent from './wrapper/create-component'
import createSubpackageApp from './wrapper/create-subpackage-app'
import createPlugin from './wrapper/create-plugin'
todos.forEach(todoApi => {
protocols[todoApi] = false
......@@ -115,13 +116,15 @@ if (__PLATFORM__ === 'app-plus') {
__GLOBAL__.createApp = createApp
__GLOBAL__.createPage = createPage
__GLOBAL__.createComponent = createComponent
__GLOBAL__.createSubpackageApp = createSubpackageApp
__GLOBAL__.createSubpackageApp = createSubpackageApp
__GLOBAL__.createPlugin = createPlugin
export {
createApp,
createPage,
createComponent,
createSubpackageApp
createComponent,
createSubpackageApp,
createPlugin
}
export default uni
export default uni
import 'uni-platform/runtime/index'
import {
isFn
} from 'uni-shared'
import parseApp from 'uni-platform/runtime/wrapper/app-parser'
export default function createPlugin (vm) {
const appOptions = parseApp(vm)
if (isFn(appOptions.onShow) && __GLOBAL__.onAppShow) {
__GLOBAL__.onAppShow((...args) => {
appOptions.onShow.apply(vm, args)
})
}
if (isFn(appOptions.onHide) && __GLOBAL__.onAppHide) {
__GLOBAL__.onAppHide((...args) => {
appOptions.onHide.apply(vm, args)
})
}
if (isFn(appOptions.onLaunch)) {
const args = __GLOBAL__.getLaunchOptionsSync && __GLOBAL__.getLaunchOptionsSync()
appOptions.onLaunch.call(vm, args)
}
return vm
}
......@@ -876,7 +876,7 @@ export function canvasToTempFilePath ({
destHeight,
canvasId,
fileType,
qualit
quality
}, callbackId) {
var pageId = getCurrentPageId()
if (!pageId) {
......@@ -897,7 +897,7 @@ export function canvasToTempFilePath ({
destWidth,
destHeight,
fileType,
qualit,
quality,
dirname,
callbackId: cId
})
......
......@@ -363,7 +363,7 @@ export default {
destHeight,
hidpi = true,
dataType,
qualit = 1,
quality = 1,
type = 'png',
callbackId
}) {
......@@ -399,7 +399,7 @@ export default {
try {
let compressed
if (dataType === 'base64') {
data = newCanvas.toDataURL(`image/${type}`, qualit)
data = newCanvas.toDataURL(`image/${type}`, quality)
} else {
const imgData = context.getImageData(0, 0, destWidth, destHeight)
if (__PLATFORM__ === 'app-plus') {
......@@ -480,7 +480,7 @@ export default {
destWidth,
destHeight,
fileType,
qualit,
quality,
dirname,
callbackId
}) {
......@@ -494,7 +494,7 @@ export default {
hidpi: false,
dataType: 'base64',
type: fileType,
qualit
quality
})
if (!res.data || !res.data.length) {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
......
......@@ -2,13 +2,13 @@
<uni-checkbox
:disabled="disabled"
v-on="$listeners"
@click="_onClick"
@click="_onClick"
>
<div class="uni-checkbox-wrapper">
<div
:class="[checkboxChecked ? 'uni-checkbox-input-checked' : '']"
:class="{ 'uni-checkbox-input-checked' : checkboxChecked, 'uni-checkbox-input-disabled' : disabled }"
:style="{color:color}"
class="uni-checkbox-input"
class="uni-checkbox-input"
/>
<slot />
</div>
......
......@@ -155,6 +155,7 @@ export default {
}
}
}
window.dispatchEvent(new CustomEvent('updateview'))
},
_resetSize () {
this.$el.style.width = this.originalStyle.width
......
......@@ -98,12 +98,9 @@ export default {
},
data () {
return {
composing: false,
valid: true,
wrapperHeight: 0,
cachedValue: '',
// Safari 14 以上修正禁用状态颜色
fixColor: String(navigator.vendor).indexOf('Apple') === 0 && CSS.supports('image-orientation:from-image')
cachedValue: ''
}
},
computed: {
......@@ -212,21 +209,6 @@ export default {
value: this.valueSync
}, force)
},
_onFocus ($event) {
this.$trigger('focus', $event, {
value: $event.target.value
})
},
_onBlur ($event) {
// iOS 输入法 compositionend 事件可能晚于 blur
if (this.composing) {
this.composing = false
this._onInput($event, true)
}
this.$trigger('blur', $event, {
value: $event.target.value
})
},
_onComposition ($event) {
if ($event.type === 'compositionstart') {
this.composing = true
......
......@@ -260,6 +260,7 @@ export default {
.uni-picker-view-group {
height: 100%;
overflow: hidden;
}
.uni-picker-view-mask {
......@@ -273,6 +274,7 @@ export default {
left: 0;
width: 100%;
z-index: 3;
pointer-events: none;
}
.uni-picker-view-mask {
......
<template>
<uni-rich-text v-on="$listeners">
<div />
<div ref="content">
<v-uni-resize-sensor
ref="sensor"
@resize="_updateView()"
/>
</div>
</uni-rich-text>
</template>
<script>
......@@ -27,14 +32,22 @@ export default {
},
methods: {
_renderNodes (nodes) {
if (typeof nodes === 'string') {
if (!this._isMounted) {
return
}
if (typeof nodes === 'string') {
nodes = parseHtml(nodes)
}
const nodeList = parseNodes(nodes, document.createDocumentFragment())
this.$el.firstChild.innerHTML = ''
this.$el.firstChild.appendChild(nodeList)
nodeList.appendChild(this.$refs.sensor.$el)
const content = this.$refs.content
content.innerHTML = ''
content.appendChild(nodeList)
},
_updateView () {
window.dispatchEvent(new CustomEvent('updateview'))
}
}
}
</script>
<style></style>
<style></style>
......@@ -100,18 +100,6 @@ export default {
type: [Boolean, String],
default: false
},
cursor: {
type: [Number, String],
default: -1
},
selectionStart: {
type: [Number, String],
default: -1
},
selectionEnd: {
type: [Number, String],
default: -1
},
confirmType: {
type: String,
default: ''
......@@ -120,14 +108,10 @@ export default {
data () {
return {
valueComposition: '',
composing: false,
focusSync: this.focus,
height: 0,
focusChangeSource: '',
// iOS 13 以下版本需要修正边距
fixMargin: String(navigator.platform).indexOf('iP') === 0 && String(navigator.vendor).indexOf('Apple') === 0 && window.matchMedia(DARK_TEST_STRING).media !== DARK_TEST_STRING,
// Safari 14 以上修正禁用状态颜色
fixColor: String(navigator.vendor).indexOf('Apple') === 0 && CSS.supports('image-orientation:from-image')
fixMargin: String(navigator.platform).indexOf('iP') === 0 && String(navigator.vendor).indexOf('Apple') === 0 && window.matchMedia(DARK_TEST_STRING).media !== DARK_TEST_STRING
}
},
computed: {
......@@ -135,18 +119,6 @@ export default {
var maxlength = Number(this.maxlength)
return isNaN(maxlength) ? 140 : maxlength
},
cursorNumber () {
var cursor = Number(this.cursor)
return isNaN(cursor) ? -1 : cursor
},
selectionStartNumber () {
var selectionStart = Number(this.selectionStart)
return isNaN(selectionStart) ? -1 : selectionStart
},
selectionEndNumber () {
var selectionEnd = Number(this.selectionEnd)
return isNaN(selectionEnd) ? -1 : selectionEnd
},
valueCompute () {
return (this.composing ? this.valueComposition : this.valueSync).split('\n')
},
......@@ -160,20 +132,6 @@ export default {
this.focusChangeSource = 'focus'
}
},
focusSync (val) {
this.$emit('update:focus', val)
this._checkSelection()
this._checkCursor()
},
cursorNumber () {
this._checkCursor()
},
selectionStartNumber () {
this._checkSelection()
},
selectionEndNumber () {
this._checkSelection()
},
height (height) {
let lineHeight = parseFloat(getComputedStyle(this.$el).lineHeight)
if (isNaN(lineHeight)) {
......@@ -228,35 +186,6 @@ export default {
this.$refs.textarea.blur()
}
},
_onFocus: function ($event) {
this.focusSync = true
this.$trigger('focus', $event, {
value: this.valueSync
})
},
_checkSelection () {
if (this.focusSync && (!this.focusChangeSource) && this.selectionStartNumber > -1 && this.selectionEndNumber > -1) {
this.$refs.textarea.selectionStart = this.selectionStartNumber
this.$refs.textarea.selectionEnd = this.selectionEndNumber
}
},
_checkCursor () {
if (this.focusSync && (this.focusChangeSource === 'focus' || ((!this.focusChangeSource) && this.selectionStartNumber < 0 && this.selectionEndNumber < 0)) && this.cursorNumber > -1) {
this.$refs.textarea.selectionEnd = this.$refs.textarea.selectionStart = this.cursorNumber
}
},
_onBlur: function ($event) {
// iOS 输入法 compositionend 事件可能晚于 blur
if (this.composing) {
this.composing = false
this._onInput($event, true)
}
this.focusSync = false
this.$trigger('blur', $event, {
value: this.valueSync,
cursor: this.$refs.textarea.selectionEnd
})
},
_onCompositionstart ($event) {
this.composing = true
},
......@@ -317,6 +246,7 @@ uni-textarea {
line-height: normal;
white-space: pre-wrap;
word-break: break-all;
box-sizing: content-box !important;
}
uni-textarea[hidden] {
display: none;
......
......@@ -49,11 +49,27 @@ export default {
focus: {
type: [Boolean, String],
default: false
},
cursor: {
type: [Number, String],
default: -1
},
selectionStart: {
type: [Number, String],
default: -1
},
selectionEnd: {
type: [Number, String],
default: -1
}
},
data () {
return {
valueSync: this._getValueString(this.value)
composing: false,
valueSync: this._getValueString(this.value),
focusSync: this.focus,
// Safari 14 以上修正禁用状态颜色
fixColor: String(navigator.vendor).indexOf('Apple') === 0 && CSS.supports('image-orientation:from-image')
}
},
watch: {
......@@ -63,11 +79,35 @@ export default {
} else {
this._blur()
}
},
focusSync (val) {
this.$emit('update:focus', val)
},
cursorNumber () {
this._checkCursor()
},
selectionStartNumber () {
this._checkSelection()
},
selectionEndNumber () {
this._checkSelection()
}
},
computed: {
needFocus () {
return this.autoFocus || this.focus
},
cursorNumber () {
var cursor = Number(this.cursor)
return isNaN(cursor) ? -1 : cursor
},
selectionStartNumber () {
var selectionStart = Number(this.selectionStart)
return isNaN(selectionStart) ? -1 : selectionStart
},
selectionEndNumber () {
var selectionEnd = Number(this.selectionEnd)
return isNaN(selectionEnd) ? -1 : selectionEnd
}
},
created () {
......@@ -133,6 +173,38 @@ export default {
_blur () {
const field = this._field
field && field.blur()
},
_onFocus ($event) {
this.focusSync = true
this.$trigger('focus', $event, {
value: this.valueSync
})
// 从 watch:focusSync 中移出到这里。在watcher中如果focus初始值为ture,则不会执行以下逻辑
this._checkSelection()
this._checkCursor()
},
_onBlur ($event) {
// iOS 输入法 compositionend 事件可能晚于 blur
if (this.composing) {
this.composing = false
this._onInput($event, true)
}
this.focusSync = false
this.$trigger('blur', $event, {
value: this.valueSync,
cursor: $event.target.selectionEnd
})
},
_checkSelection () {
if (this.focusSync && this.selectionStartNumber > -1 && this.selectionEndNumber > -1) {
this._field.selectionStart = this.selectionStartNumber
this._field.selectionEnd = this.selectionEndNumber
}
},
_checkCursor () {
if (this.focusSync && this.selectionStartNumber < 0 && this.selectionEndNumber < 0 && this.cursorNumber > -1) {
this._field.selectionEnd = this._field.selectionStart = this.cursorNumber
}
}
}
}
......@@ -30,7 +30,9 @@ export * from './media/audio'
export * from './media/choose-image'
export * from './media/choose-video'
export * from './media/compress-image'
export * from './media/compress-video'
export * from './media/get-image-info'
export * from './media/get-video-info'
export * from './media/preview-image'
export * from './media/recorder'
export * from './media/save-image-to-photos-album'
......
......@@ -7,7 +7,8 @@ import {
} from '../../bridge'
import {
warpPlusErrorCallback
warpPlusErrorCallback,
getFileName
} from '../util'
import {
......@@ -16,26 +17,45 @@ import {
export function chooseVideo ({
sourceType,
compressed,
maxDuration,
camera
} = {}, callbackId) {
const errorCallback = warpPlusErrorCallback(callbackId, 'chooseVideo', 'cancel')
function successCallback (tempFilePath = '') {
plus.io.getVideoInfo({
filePath: tempFilePath,
success (videoInfo) {
const result = {
errMsg: 'chooseVideo:ok',
tempFilePath: tempFilePath
}
result.size = videoInfo.size
result.duration = videoInfo.duration
result.width = videoInfo.width
result.height = videoInfo.height
invoke(callbackId, result)
},
errorCallback
const dst = `${TEMP_PATH}/compressed/${Date.now()}_${getFileName(tempFilePath)}`
const compressVideo = compressed ? plus.zip.compressVideo : function (_, callback) {
callback({ tempFilePath })
}
if (compressed) {
plus.nativeUI.showWaiting()
}
compressVideo({
src: tempFilePath,
dst
}, ({ tempFilePath }) => {
if (compressed) {
plus.nativeUI.closeWaiting()
}
plus.io.getVideoInfo({
filePath: tempFilePath,
success (videoInfo) {
const result = {
errMsg: 'chooseVideo:ok',
tempFilePath: tempFilePath
}
result.size = videoInfo.size
result.duration = videoInfo.duration
result.width = videoInfo.width
result.height = videoInfo.height
invoke(callbackId, result)
},
errorCallback
})
}, error => {
plus.nativeUI.closeWaiting()
errorCallback(error)
})
}
......
import {
TEMP_PATH
} from '../constants'
import {
warpPlusSuccessCallback,
warpPlusErrorCallback,
getFileName
} from '../util'
export function compressVideo (options, callbackId) {
const dst = `${TEMP_PATH}/compressed/${Date.now()}_${getFileName(options.src)}`
const successCallback = warpPlusSuccessCallback(callbackId, 'compressVideo')
const errorCallback = warpPlusErrorCallback(callbackId, 'compressVideo')
plus.zip.compressVideo(Object.assign({}, options, {
dst
}), successCallback, errorCallback)
}
import {
warpPlusMethod
} from '../util'
export const getVideoInfo = warpPlusMethod('io', 'getVideoInfo', options => {
options.filePath = options.src
return options
}, data => {
return {
duration: data.duration,
fps: data.fps || 30,
height: data.height,
width: data.width,
size: data.size
}
})
......@@ -208,7 +208,7 @@ export function warpPlusErrorCallback (callbackId, name, errMsg) {
}
}
export function warpPlusMethod (module, name, before) {
export function warpPlusMethod (module, name, before, after) {
return function (options, callbackId) {
if (typeof before === 'function') {
options = before(options)
......@@ -217,6 +217,9 @@ export function warpPlusMethod (module, name, before) {
success (data = {}) {
delete data.code
delete data.message
if (typeof after === 'function') {
data = after(data)
}
invoke(callbackId, Object.assign({}, data, {
errMsg: `${name}:ok`
}))
......
<template>
<uni-video v-on="$listeners">
<div
ref="container"
class="uni-video-container"
<div
ref="container"
class="uni-video-container"
/>
<div class="uni-video-slot">
<slot />
......@@ -56,6 +56,7 @@ const attrs = [
'pageGesture',
'enableProgressGesture',
'showPlayBtn',
'enablePlayGesture',
'showCenterPlayBtn',
'showLoading',
'codec',
......@@ -145,6 +146,10 @@ export default {
type: [Boolean, String],
default: true
},
enablePlayGesture: {
type: [Boolean, String],
default: true
},
showCenterPlayBtn: {
type: [Boolean, String],
default: true
......
......@@ -9,17 +9,17 @@
@regionchange="_regionchange"
>
<div class="map-location" />
<div
class="map-move"
@click="_moveToLocation"
<div
class="map-move"
@click="_moveToLocation"
>
<i>&#xec32;</i>
</div>
</v-uni-map>
<div class="nav">
<div
class="nav-btn back"
@click="_back"
<div
class="nav-btn back"
@click="_back"
>
<i class="uni-btn-icon">&#xe650;</i>
</div>
......@@ -51,14 +51,14 @@
取消
</div>
</div>
<v-uni-scroll-view
scroll-y
class="list"
@scrolltolower="_scrolltolower"
<v-uni-scroll-view
scroll-y
class="list"
@scrolltolower="_scrolltolower"
>
<div
v-if="loading"
class="list-loading"
<div
v-if="loading"
class="list-loading"
>
<i class="uni-loading" />
</div>
......@@ -77,7 +77,7 @@
{{ item.name }}
</div>
<div class="list-item-detail">
{{ item.distance ? item.distance + "米 | " : "" }}{{ item.address }}
{{ item.distance | distance }}{{ item.address }}
</div>
</div>
</v-uni-scroll-view>
......@@ -95,6 +95,17 @@ const key = __uniConfig.qqMapKey
export default {
name: 'SystemChooseLocation',
filters: {
distance (distance) {
if (distance > 100) {
return `${distance > 1000 ? (distance / 1000).toFixed(1) + 'k' : distance.toFixed(0)}m | `
} else if (distance > 0) {
return '100m内 | '
} else {
return ''
}
}
},
data () {
return {
latitude: 0,
......@@ -105,12 +116,16 @@ export default {
list: [],
keyword: '',
searching: false,
loading: true
loading: true,
adcode: ''
}
},
computed: {
selected () {
return this.list[this.selectedIndex]
},
boundary () {
return this.adcode ? `region(${this.adcode},1,${this.latitude},${this.longitude})` : `nearby(${this.latitude},${this.longitude},5000)`
}
},
created () {
......@@ -173,7 +188,7 @@ export default {
},
_getList () {
this.loading = true
const url = this.searching ? `https://apis.map.qq.com/ws/place/v1/search?output=jsonp&key=${key}&boundary=nearby(${this.latitude},${this.longitude},1000)&keyword=${this.keyword}&page_size=${this.pageSize}&page_index=${this.pageIndex}` : `https://apis.map.qq.com/ws/geocoder/v1/?output=jsonp&key=${key}&location=${this.latitude},${this.longitude}&get_poi=1&poi_options=page_size=${this.pageSize};page_index=${this.pageIndex}`
const url = this.searching ? `https://apis.map.qq.com/ws/place/v1/search?output=jsonp&key=${key}&boundary=${this.boundary}&keyword=${this.keyword}&page_size=${this.pageSize}&page_index=${this.pageIndex}` : `https://apis.map.qq.com/ws/geocoder/v1/?output=jsonp&key=${key}&location=${this.latitude},${this.longitude}&get_poi=1&poi_options=page_size=${this.pageSize};page_index=${this.pageIndex}`
// TODO 列表加载失败提示
getJSONP(url, {
callback: 'callback'
......@@ -181,8 +196,12 @@ export default {
this.loading = false
if (this.searching && 'data' in res && res.data.length) {
this._pushData(res.data)
} else if ('result' in res && res.result.pois) {
this._pushData(res.result.pois)
} else if ('result' in res) {
const result = res.result
this.adcode = result.ad_info ? result.ad_info.adcode : ''
if (result.pois) {
this._pushData(result.pois)
}
}
}, () => {
this.loading = false
......@@ -234,10 +253,10 @@ export default {
.uni-system-choose-location .map {
position: absolute;
top: -40px;
top: 0;
left: 0;
width: 100%;
height: 380px;
height: 300px;
}
.uni-system-choose-location .map-location {
......
......@@ -9,9 +9,10 @@ const files = {}
/**
* 从url读取File
* @param {string} url
* @param {boolean} local
* @param {Promise}
*/
export function urlToFile (url) {
export function urlToFile (url, local) {
var file = files[url]
if (file) {
return Promise.resolve(file)
......@@ -19,6 +20,9 @@ export function urlToFile (url) {
if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(url)) {
return Promise.resolve(base64ToFile(url))
}
if (local) {
return Promise.reject(new Error('not find'))
}
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
......
......@@ -88,7 +88,7 @@ class InnerAudioContext {
})
// 和audio对象同名同效果的事件
var eventNames = ['canplay', 'play', 'pause', 'ended', 'timeUpdate', 'error', 'waiting', 'seeking', 'seeked']
var stopEventNames = ['pause', 'seeking', 'seeked', 'timeUpdate']
var stopEventNames = ['canplay', 'pause', 'seeking', 'seeked', 'timeUpdate']
eventNames.forEach(eventName => {
audio.addEventListener(eventName.toLowerCase(), () => {
// stop事件过滤
......
import {
urlToFile
} from 'uni-platform/helpers/file'
export function getVideoInfo ({
src
}, callbackId) {
const {
invokeCallbackHandler: invoke
} = UniServiceJSBridge
urlToFile(src, true).then(file => {
return file
}).catch(() => {
return {}
}).then(file => {
const result = file.size ? {
size: file.size,
errMsg: 'getVideoInfo:ok'
} : {
errMsg: 'getVideoInfo:fail'
}
const video = document.createElement('video')
if (video.onloadedmetadata !== undefined) {
// 部分浏览器(如微信内置浏览器)未播放无法触发loadedmetadata事件
const handle = setTimeout(() => {
video.onloadedmetadata = null
video.onerror = null
invoke(callbackId, result)
}, src.startsWith('data:') || src.startsWith('blob:') ? 300 : 3000)
// 尝试获取视频的宽高信息
video.onloadedmetadata = function () {
clearTimeout(handle)
video.onerror = null
invoke(callbackId, Object.assign(result, {
size: file.size,
duration: video.duration || 0,
width: video.videoWidth || 0,
height: video.videoHeight || 0,
errMsg: 'getVideoInfo:ok'
}))
}
video.onerror = function () {
clearTimeout(handle)
video.onloadedmetadata = null
invoke(callbackId, result)
}
video.src = src
} else {
invoke(callbackId, result)
}
})
}
......@@ -93,9 +93,9 @@ class SocketTask {
}
try {
ws.close(...arrgs)
this._callback(options, 'sendSocketMessage:ok')
this._callback(options, 'closeSocket:ok')
} catch (error) {
this._callback(options, `sendSocketMessage:fail ${error}`)
this._callback(options, `closeSocket:fail ${error}`)
}
}
......
......@@ -14,7 +14,7 @@ const customize = cached((str) => {
function initTriggerEvent (mpInstance) {
if (__PLATFORM__ === 'mp-weixin' || __PLATFORM__ === 'app-plus') {
if (!wx.canIUse('nextTick')) {
if (!wx.canIUse || !wx.canIUse('nextTick')) {
return
}
}
......@@ -49,4 +49,4 @@ if (!MPPage.__$wrappered) {
initHook('created', options)
return MPComponent(options)
}
}
}
......@@ -69,7 +69,7 @@ export default function parseBaseApp (vm, {
delete this.$options.mpType
delete this.$options.mpInstance
if (this.mpType === 'page') { // hack vue-i18n
if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n
const app = getApp()
if (app.$vm && app.$vm.$i18n) {
this._i18n = app.$vm.$i18n
......@@ -88,7 +88,7 @@ export default function parseBaseApp (vm, {
return
}
if (__PLATFORM__ === 'mp-weixin' || __PLATFORM__ === 'mp-qq') {
if (!wx.canIUse('nextTick')) { // 事实 上2.2.3 即可,简单使用 2.3.0 的 nextTick 判断
if (wx.canIUse && !wx.canIUse('nextTick')) { // 事实 上2.2.3 即可,简单使用 2.3.0 的 nextTick 判断
console.error('当前微信基础库版本过低,请将 微信开发者工具-详情-项目设置-调试基础库版本 更换为`2.3.0`以上')
}
}
......@@ -123,4 +123,4 @@ export default function parseBaseApp (vm, {
initHooks(appOptions, hooks)
return appOptions
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册