提交 247b5d60 编写于 作者: Q qiang

Merge branch 'dev' into alpha

......@@ -55,6 +55,7 @@ const media = [
'compressImage',
'getRecorderManager',
'getBackgroundAudioManager',
'createAudioContext',
'createInnerAudioContext',
'chooseVideo',
'saveVideoToPhotosAlbum',
......@@ -206,8 +207,8 @@ const third = [
'setPageMeta',
'onNativeEventReceive',
'sendNativeEvent',
'preloadPage',
'unPreloadPage',
'preloadPage',
'unPreloadPage',
'loadSubPackage'
]
......
......@@ -111,8 +111,8 @@ function isNVuePage (page, root = '') {
}
function isValidPage (page, root = '') {
if (typeof page === 'string') { // 不合法的配置
console.warn(`${page} 配置错误, 已被忽略, 查看文档: https://uniapp.dcloud.io/collocation/pages?id=pages`)
if (typeof page === 'string' || !page.path) { // 不合法的配置
console.warn('pages.json 页面配置错误, 已被忽略, 查看文档: https://uniapp.dcloud.io/collocation/pages?id=pages')
return false
}
let pagePath = page.path
......
......@@ -12,6 +12,12 @@ wx.createComponent({
`
}
function generateCssCode (ownerName) {
return `
@import './${ownerName}.wxss'
`
}
function hasOwn (obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key)
}
......@@ -61,7 +67,7 @@ module.exports = {
}
parentNode.attr.generic[slotName] = true
// 生成 scopedSlots 文件,包括 json,js,wxml,还需要更新 owner 的 usingComponents
// 生成 scopedSlots 文件,包括 json,js,wxml,wxss,还需要更新 owner 的 usingComponents
if (!state.files) {
state.files = {}
}
......@@ -100,6 +106,11 @@ module.exports = {
const jsContent = generateJsCode(genCode(t.objectExpression(objectProperties), true))
state.files[jsFile] = jsContent
const cssFile = resourcePath.replace(ownerName + extname, componentName + '.wxss')
const cssContent = generateCssCode(ownerName)
state.files[cssFile] = cssContent
if (!state.generic) {
state.generic = []
}
......@@ -108,4 +119,4 @@ module.exports = {
return ''
}
}
}
......@@ -25,7 +25,7 @@ const postcssLoader = {
options: {
sourceMap: false,
parser: require('postcss-comment'),
plugins: [
plugins: [
require('postcss-import')({
resolve (id, basedir, importOptions) {
if (id.startsWith('~@/')) {
......@@ -77,12 +77,13 @@ if (sassLoaderVersion < 8) {
sassLoader.options.outputStyle = 'expanded'
sassLoader.options.indentedSyntax = true
} else {
scssLoader.options.prependData = sassData
const name = sassLoaderVersion >= 9 ? 'additionalData' : 'prependData'
scssLoader.options[name] = sassData
scssLoader.options.sassOptions = {
outputStyle: 'expanded'
}
sassLoader.options.prependData = sassData
sassLoader.options[name] = sassData
sassLoader.options.sassOptions = {
outputStyle: 'expanded',
indentedSyntax: true
......
const {
normalizePath,
isInHBuilderX
} = require('@dcloudio/uni-cli-shared/lib/util');
} = require('@dcloudio/uni-cli-shared/lib/util')
const plp = require('@dcloudio/webpack-uni-pages-loader/package.json')
class ErrorReport {
static get instance() {
class ErrorReport {
static get instance () {
if (this._instance == null) {
this._instance = new ErrorReport();
this._instance = new ErrorReport()
}
return this._instance;
return this._instance
}
constructor () {
this._instance = null
this._os = null
this._https = null
this._crypto = null
this._cacheList = []
this._UNI_INPUT_DIR_REG = new RegExp(normalizePath(process.env.UNI_INPUT_DIR), 'g')
this._UNI_CLI_CONTEXT_REG = new RegExp(normalizePath(process.env.UNI_CLI_CONTEXT), 'g')
}
constructor() {
this._instance = null;
this._https = null;
this._crypto = null;
this._cacheList = [];
this._UNI_INPUT_DIR_REG = new RegExp(normalizePath(process.env.UNI_INPUT_DIR), 'g');
this._UNI_CLI_CONTEXT_REG = new RegExp(normalizePath(process.env.UNI_CLI_CONTEXT), 'g');
get os () {
if (this._os == null) {
this._os = require('os')
}
return this._os
}
get https() {
get https () {
if (this._https == null) {
this._https = require('https');
this._https = require('https')
}
return this._https;
return this._https
}
report(type, err) {
report (type, err) {
if (!this._shouldReport(err)) {
return;
return
}
err = normalizePath(err)
err = err.replace(this._UNI_INPUT_DIR_REG, 'UNI_INPUT_DIR')
err = err.replace(this._UNI_CLI_CONTEXT_REG, 'UNI_CLI_CONTEXT')
const data = JSON.stringify({
const data = JSON.stringify({
di: this._getMD5(this._getMac()),
np: process.platform,
nv: process.version,
cp: process.env.UNI_PLATFORM,
cp: process.env.UNI_PLATFORM,
cv: plp['uni-app'].compilerVersion,
hx: isInHBuilderX ? 1 : 0,
et: type,
em: err
});
})
var hash = this._getMD5(data);
var hash = this._getMD5(data)
if (this._cacheList.includes(hash)) {
return;
return
}
this._cacheList.push(hash);
this._cacheList.push(hash)
setTimeout(() => {
this._doReport(data);
}, 10);
this._doReport(data)
}, 10)
}
_doReport(data) {
_doReport (data) {
const req = this.https.request({
hostname: this.HOST,
port: 443,
......@@ -69,12 +79,12 @@ class ErrorReport {
'Content-Type': 'application/json',
'Content-Length': data.length
}
});
req.write(data);
req.end();
})
req.write(data)
req.end()
}
_shouldReport(err = '') {
_shouldReport (err = '') {
try {
const errMsg = err.toString()
......@@ -94,25 +104,44 @@ class ErrorReport {
return false
}
_getMD5(str) {
return this.crypto.createHash('md5').update(str).digest('hex');
_getMD5 (str) {
return this.crypto.createHash('md5').update(str).digest('hex')
}
_getMac () {
let mac
const network = this.os.networkInterfaces()
for (const key in network) {
const array = network[key]
for (let i = 0; i < array.length; i++) {
const item = array[i]
if (!item.family || (item.mac && item.mac === '00:00:00:00:00:00')) {
continue
}
if (item.family === 'IPv4' || item.family === 'IPv6') {
mac = item.mac
break
}
}
}
return mac
}
get crypto() {
get crypto () {
if (this._crypto == null) {
this._crypto = require('crypto');
this._crypto = require('crypto')
}
return this._crypto;
return this._crypto
}
}
Object.assign(ErrorReport.prototype, {
HOST: '96f0e031-f37a-48ef-84c7-2023f6360c0a.bspapp.com',
PATH: '/http/uni-app-compiler',
EXCLUDE_ERROR_LIST: ['uni-app-compiler']
});
EXCLUDE_ERROR_LIST: ['uni-app-compiler', 'Error: ENOENT: no such file or directory']
})
function report(type, err) {
ErrorReport.instance.report(type, err);
function report (type, err) {
ErrorReport.instance.report(type, err)
}
global.__error_reporting__ = report
......
......@@ -85,8 +85,9 @@ module.exports = function initOptions (options) {
if (sassLoaderVersion < 8) {
options.css.loaderOptions.sass.data = sassData
} else {
options.css.loaderOptions.sass.prependData = sassData
} else {
const name = sassLoaderVersion >= 9 ? 'additionalData' : 'prependData'
options.css.loaderOptions.sass[name] = sassData
}
const userPostcssConfigPath = path.resolve(process.env.UNI_INPUT_DIR, 'postcss.config.js')
......
......@@ -187,6 +187,68 @@ global['__wxVueOptions'] = {
}
)
assertCodegenOptions(
`const options = {
name: 'test'
}
export default options`,
{
name: '"test"',
inheritAttrs: null,
props: null
}
)
assertCodegenOptions(
`let options
options = {
name: 'test'
}
export default options`,
{
name: '"test"',
inheritAttrs: null,
props: null
}
)
assertCodegenOptions(
`const options = Vue.extend({
name: 'test'
})
export default options`,
{
name: '"test"',
inheritAttrs: null,
props: null
}
)
assertCodegenOptions(
`let options
options = Vue.extend({
name: 'test'
})
export default options`,
{
name: '"test"',
inheritAttrs: null,
props: null
}
)
assertCodegenOptions(
`const options = {
name: 'test'
}
export default Vue.extend(options)`,
{
name: '"test"',
inheritAttrs: null,
props: null
}
)
assertCodegenOptions(
`export default {
props: ['id', 'test']
......
......@@ -60,6 +60,41 @@ function handleComponentsObjectExpression (componentsObjExpr, path, state, prepe
state.components = prepend ? components.concat(state.components) : components
}
function handleIdentifier ({ name }, path, state) {
// 仅做有限查找
for (let i = path.container.length; i > 0; i--) {
const node = path.container[i - 1]
let declarations = []
if (t.isExpressionStatement(node)) {
declarations = [node]
} else if (t.isVariableDeclaration(node)) {
declarations = node.declarations
}
for (let i = declarations.length; i > 0; i--) {
let declaration = declarations[i - 1]
let identifier
if (t.isVariableDeclarator(declaration)) {
identifier = declaration.id
declaration = declaration.init
} else if (t.isExpressionStatement(declaration)) {
identifier = declaration.expression.left
declaration = declaration.expression.right
}
if (identifier.name === name) {
if (t.isCallExpression(declaration) &&
t.isMemberExpression(declaration.callee) &&
declaration.arguments.length === 1) {
declaration = declaration.arguments[0]
}
if (t.isObjectExpression(declaration)) {
handleObjectExpression(declaration, path, state)
}
return
}
}
}
}
module.exports = function (ast, state = {
type: 'Component',
components: [],
......@@ -96,12 +131,19 @@ module.exports = function (ast, state = {
const declaration = path.node.declaration
if (t.isObjectExpression(declaration)) { // export default {components:{}}
handleObjectExpression(declaration, path, state)
} else if (t.isIdentifier(declaration)) {
handleIdentifier(declaration, path, state)
} else if (t.isCallExpression(declaration) &&
t.isMemberExpression(declaration.callee) &&
declaration.arguments.length === 1) { // export default Vue.extend({components:{}})
if (declaration.callee.object.name === 'Vue' && declaration.callee.property.name ===
'extend') {
handleObjectExpression(declaration.arguments[0], path, state)
const argument = declaration.arguments[0]
if (t.isObjectExpression(argument)) {
handleObjectExpression(argument, path, state)
} else if (t.isIdentifier(argument)) {
handleIdentifier(argument, path, state)
}
}
} else if (t.isClassDeclaration(declaration) &&
declaration.decorators &&
......
......@@ -64,6 +64,7 @@ module.exports = function generateComponent (compilation) {
const concatenatedModules = modules.filter(module => module.modules)
const uniModuleId = modules.find(module => module.resource && normalizePath(module.resource) === uniPath).id
const wxssImports = {}
Object.keys(assets).forEach(name => {
if (components.has(name.replace('.js', ''))) {
......@@ -81,7 +82,7 @@ module.exports = function generateComponent (compilation) {
let resource = normalizePath(path.resolve(process.env.UNI_INPUT_DIR, '..', modulePath))
const altResource = normalizePath(path.resolve(process.env.UNI_INPUT_DIR, modulePath))
if (
if (
/^win/.test(process.platform) &&
modulePath.includes('@dcloudio') &&
(
......@@ -125,6 +126,24 @@ module.exports = function generateComponent (compilation) {
assets[name].source = newSource
}
}
if (name.endsWith('.wxss')) {
// 移除部分含有错误引用的 wxss 文件
const origSource = assets[name].source().trim()
const result = origSource.match(/^@import ["'](.+?)["']$/)
if (result) {
const wxssPath = path.join(path.dirname(name), result[1])
if (Object.keys(assets).includes(wxssPath)) {
wxssImports[wxssPath] = wxssImports[wxssPath] || []
wxssImports[wxssPath].push(name)
} else {
if (wxssImports[name]) {
wxssImports[name].forEach(name => delete assets[name])
delete wxssImports[name]
}
delete assets[name]
}
}
}
})
}
if (process.env.UNI_FEATURE_OBSOLETE !== 'false') {
......@@ -158,4 +177,4 @@ function removeUnusedComponent (name) {
fs.renameSync(path.join(process.env.UNI_OUTPUT_DIR, name + '.json'), path.join(process.env.UNI_OUTPUT_DIR, name +
'.bak.json'))
} catch (e) {}
}
}
......@@ -40,7 +40,9 @@ function processArgs (methodName, fromArgs, argsOption = {}, returnValue = {}, k
toArgs[keyOption.name ? keyOption.name : key] = keyOption.value
}
} else if (CALLBACKS.indexOf(key) !== -1) {
toArgs[key] = processCallback(methodName, fromArgs[key], returnValue)
if (isFn(fromArgs[key])) {
toArgs[key] = processCallback(methodName, fromArgs[key], returnValue)
}
} else {
if (!keepFromArgs) {
toArgs[key] = fromArgs[key]
......
import {
onMethod,
invokeMethod
} from '../../platform'
const eventNames = [
'canplay',
'play',
'pause',
'stop',
'ended',
'timeUpdate',
'error',
'waiting',
'seeking',
'seeked'
]
function operateAudioPlayer (audioId, pageId, type, data) {
UniServiceJSBridge.publishHandler(pageId + '-audio-' + audioId, {
audioId,
type,
data
}, pageId)
}
const props = [
{
name: 'src',
cache: true
},
{
name: 'startTime',
default: 0,
cache: true
},
{
name: 'autoplay',
default: false,
cache: true
},
{
name: 'loop',
default: false,
cache: true
},
{
name: 'obeyMuteSwitch',
default: true,
readonly: true,
cache: true
},
{
name: 'duration',
readonly: true
},
{
name: 'currentTime',
readonly: true
},
{
name: 'paused',
readonly: true
},
{
name: 'buffered',
readonly: true
},
{
name: 'volume'
class AudioContext {
constructor (id, pageId) {
this.id = id
this.pageId = pageId
}
]
class InnerAudioContext {
constructor (id) {
this.id = id
this._callbacks = {}
this._options = {}
eventNames.forEach(name => {
this._callbacks[name.toLowerCase()] = []
})
props.forEach(item => {
const name = item.name
const data = {
get () {
const result = item.cache ? this._options : invokeMethod('getAudioState', {
audioId: this.id
})
const value = name in result ? result[name] : item.default
return typeof value === 'number' && name !== 'volume' ? value / 1e3 : value
}
}
if (!item.readonly) {
data.set = function (value) {
this._options[name] = value
invokeMethod('setAudioState', Object.assign({}, this._options, {
audioId: this.id
}))
}
}
Object.defineProperty(this, name, data)
setSrc (src) {
operateAudioPlayer(this.id, this.pageId, 'setSrc', {
src
})
}
}
play () {
this._operate('play')
}
operateAudioPlayer(this.id, this.pageId, 'play')
}
pause () {
this._operate('pause')
}
stop () {
this._operate('stop')
}
operateAudioPlayer(this.id, this.pageId, 'pause')
}
seek (position) {
this._operate('seek', {
currentTime: position * 1e3
operateAudioPlayer(this.id, this.pageId, 'seek', {
position
})
}
destroy () {
clearInterval(this.__timing)
invokeMethod('destroyAudioInstance', {
audioId: this.id
})
delete innerAudioContexts[this.id]
}
_operate (type, options) {
invokeMethod('operateAudio', Object.assign({}, options, {
audioId: this.id,
operationType: type
}))
}
}
eventNames.forEach(item => {
const name = item[0].toUpperCase() + item.substr(1)
item = item.toLowerCase()
InnerAudioContext.prototype[`on${name}`] = function (callback) {
this._callbacks[item].push(callback)
export function createAudioContext (id, context) {
if (context) {
return new AudioContext(id, context.$page.id)
}
InnerAudioContext.prototype[`off${name}`] = function (callback) {
const callbacks = this._callbacks[item]
const index = callbacks.indexOf(callback)
if (index >= 0) {
callbacks.splice(index, 1)
}
const app = getApp()
if (app.$route && app.$route.params.__id__) {
return new AudioContext(id, app.$route.params.__id__)
} else {
UniServiceJSBridge.emit('onError', 'createAudioContext:fail')
}
})
function emit (audio, state, errMsg, errCode) {
audio._callbacks[state].forEach(callback => {
if (typeof callback === 'function') {
callback(state === 'error' ? {
errMsg,
errCode
} : {})
}
})
}
onMethod('onAudioStateChange', ({
state,
audioId,
errMsg,
errCode
}) => {
const audio = innerAudioContexts[audioId]
if (audio) {
emit(audio, state, errMsg, errCode)
if (state === 'play') {
const oldCurrentTime = audio.currentTime
audio.__timing = setInterval(() => {
const currentTime = audio.currentTime
if (currentTime !== oldCurrentTime) {
emit(audio, 'timeupdate')
}
}, 200)
} else if (state === 'pause' || state === 'stop' || state === 'error') {
clearInterval(audio.__timing)
}
}
})
const innerAudioContexts = Object.create(null)
export function createInnerAudioContext () {
const {
audioId
} = invokeMethod('createAudioInstance')
const innerAudioContext = new InnerAudioContext(audioId)
innerAudioContexts[audioId] = innerAudioContext
return innerAudioContext
}
import {
onMethod,
invokeMethod
} from '../../platform'
const eventNames = [
'canplay',
'play',
'pause',
'stop',
'ended',
'timeUpdate',
'error',
'waiting',
'seeking',
'seeked'
]
const props = [
{
name: 'src',
cache: true
},
{
name: 'startTime',
default: 0,
cache: true
},
{
name: 'autoplay',
default: false,
cache: true
},
{
name: 'loop',
default: false,
cache: true
},
{
name: 'obeyMuteSwitch',
default: true,
readonly: true,
cache: true
},
{
name: 'duration',
readonly: true
},
{
name: 'currentTime',
readonly: true
},
{
name: 'paused',
readonly: true
},
{
name: 'buffered',
readonly: true
},
{
name: 'volume'
}
]
class InnerAudioContext {
constructor (id) {
this.id = id
this._callbacks = {}
this._options = {}
eventNames.forEach(name => {
this._callbacks[name.toLowerCase()] = []
})
props.forEach(item => {
const name = item.name
const data = {
get () {
const result = item.cache ? this._options : invokeMethod('getAudioState', {
audioId: this.id
})
const value = name in result ? result[name] : item.default
return typeof value === 'number' && name !== 'volume' ? value / 1e3 : value
}
}
if (!item.readonly) {
data.set = function (value) {
this._options[name] = value
invokeMethod('setAudioState', Object.assign({}, this._options, {
audioId: this.id
}))
}
}
Object.defineProperty(this, name, data)
})
}
play () {
this._operate('play')
}
pause () {
this._operate('pause')
}
stop () {
this._operate('stop')
}
seek (position) {
this._operate('seek', {
currentTime: position * 1e3
})
}
destroy () {
clearInterval(this.__timing)
invokeMethod('destroyAudioInstance', {
audioId: this.id
})
delete innerAudioContexts[this.id]
}
_operate (type, options) {
invokeMethod('operateAudio', Object.assign({}, options, {
audioId: this.id,
operationType: type
}))
}
}
eventNames.forEach(item => {
const name = item[0].toUpperCase() + item.substr(1)
item = item.toLowerCase()
InnerAudioContext.prototype[`on${name}`] = function (callback) {
this._callbacks[item].push(callback)
}
InnerAudioContext.prototype[`off${name}`] = function (callback) {
const callbacks = this._callbacks[item]
const index = callbacks.indexOf(callback)
if (index >= 0) {
callbacks.splice(index, 1)
}
}
})
function emit (audio, state, errMsg, errCode) {
audio._callbacks[state].forEach(callback => {
if (typeof callback === 'function') {
callback(state === 'error' ? {
errMsg,
errCode
} : {})
}
})
}
onMethod('onAudioStateChange', ({
state,
audioId,
errMsg,
errCode
}) => {
const audio = innerAudioContexts[audioId]
if (audio) {
emit(audio, state, errMsg, errCode)
if (state === 'play') {
const oldCurrentTime = audio.currentTime
audio.__timing = setInterval(() => {
const currentTime = audio.currentTime
if (currentTime !== oldCurrentTime) {
emit(audio, 'timeupdate')
}
}, 200)
} else if (state === 'pause' || state === 'stop' || state === 'error') {
clearInterval(audio.__timing)
}
}
})
const innerAudioContexts = Object.create(null)
export function createInnerAudioContext () {
const {
audioId
} = invokeMethod('createAudioInstance')
const innerAudioContext = new InnerAudioContext(audioId)
innerAudioContexts[audioId] = innerAudioContext
return innerAudioContext
}
export * from './base/event-bus'
export * from './context/audio'
export * from './context/inner-audio'
export * from './context/background-audio'
export * from './context/canvas'
export * from './context/operate-map-player'
......
function operateAudioPlayer (audioId, pageId, type, data) {
UniServiceJSBridge.publishHandler(pageId + '-audio-' + audioId, {
audioId,
type,
data
}, pageId)
}
class AudioContext {
constructor (id, pageId) {
this.id = id
this.pageId = pageId
}
setSrc (src) {
operateAudioPlayer(this.id, this.pageId, 'setSrc', {
src
})
}
play () {
operateAudioPlayer(this.id, this.pageId, 'play')
}
pause () {
operateAudioPlayer(this.id, this.pageId, 'pause')
}
stop () {
operateAudioPlayer(this.id, this.pageId, 'stop')
}
seek (position) {
operateAudioPlayer(this.id, this.pageId, 'seek', {
position
})
}
}
export function createAudioContext (id, context) {
if (context) {
return new AudioContext(id, context.$page.id)
}
const app = getApp()
if (app.$route && app.$route.params.__id__) {
return new AudioContext(id, app.$route.params.__id__)
} else {
UniServiceJSBridge.emit('onError', 'createAudioContext:fail')
}
}
<template>
<uni-ad
v-bind="attrs"
v-on="$listeners"
>
<div
ref="container"
class="uni-ad-container"
/>
</uni-ad>
</template>
<script>
import {
subscriber
} from 'uni-mixins'
class AdConfig {
static get instance () {
if (this._instance == null) {
this._instance = new AdConfig()
this._instance._init()
}
return this._instance
}
constructor () {
this._instance = null
this._adConfig = null
this._isLoading = false
this._lastError = null
this._callbacks = []
}
get (adpid, callback) {
if (this._adConfig != null) {
callback(this._adConfig.adpids[adpid])
return
}
this._callbacks.push({ adpid: adpid, callback: callback })
this._loadAdConfig()
}
_init () {
var config = this._getConfig()
if (config != null && config.last) {
var td = Math.abs(Date.now() - config.last)
if (td < this.CACHE_TIME) {
this._adConfig = config.data
}
}
}
_loadAdConfig (adpid, callback) {
if (this._isLoading === true) {
return
}
this._isLoading = true
uni.request({
url: this.URL,
timeout: 3000,
method: 'GET',
data: {
appid: '__UNI__ADD1C32'
},
dataType: 'json',
success: (res) => {
const rd = res.data
if (rd.ret === 0) {
const data = rd.data
this._adConfig = data
this._setConfig(data)
this._callbacks.forEach((i) => {
i.callback(data.adpids[i.adpid])
})
}
},
complete: (c) => {
this._isLoading = false
}
})
}
_getConfig () {
if (!navigator.cookieEnabled || !window.localStorage) {
return null
}
var data = localStorage.getItem(this.KEY)
return data ? JSON.parse(data) : null
}
_setConfig (data) {
if (!navigator.cookieEnabled || !window.localStorage) {
return null
}
localStorage.setItem(this.KEY, JSON.stringify({
last: Date.now(),
data: data
}))
}
}
Object.assign(AdConfig.prototype, {
URL: '//stream.dcloud.net.cn/dcloud/H5Config',
KEY: 'UNI_APP_AD',
CACHE_TIME: 1000 * 60 * 10
})
const adProvider = {
hx: 'hx',
ky: 'ky'
}
const CHECK_RENDER_DELAY = 1000
const CHECK_RENDER_RETRY = 3
export default {
name: 'Ad',
mixins: [subscriber],
props: {
adpid: {
type: [Number, String],
default: ''
}
},
data () {
return {
hidden: false
}
},
watch: {
hidden (val) {
},
adpid (val) {
if (val) {
this._loadData(val)
}
}
},
mounted () {
this._pl = []
this._pd = {}
this._pi = 0
this._loadData()
this._checkTimer = null
this._checkTimerCount = 0
},
beforeDestroy () {
this.$refs.container.innerHTML = ''
},
methods: {
_loadData (adpid) {
AdConfig.instance.get(adpid || this.adpid, (data) => {
this._pd = data
this._pl = data.psp.split(',')
this._renderAd()
})
},
_renderAd () {
if (this._pi > this._pl.length - 1) {
return
}
var ap = this._pl[this._pi]
var data = this._pd[ap]
switch (ap) {
case adProvider.hx:
this._renderHX(data)
break
case adProvider.ky:
this._renderKY(data)
break
}
},
_renderHX (data) {
var ad = document.createElement('script')
ad.src = data.src || data.url
var adView = document.createElement('div')
adView.setAttribute('id', this._randomId())
adView.appendChild(ad)
this.$refs.container.innerHTML = ''
this.$refs.container.append(adView)
// this._startCheckTimer()
},
_renderKY (data) {
var ad = document.createElement('script')
ad.src = data.src || data.url
this.$refs.container.innerHTML = ''
this.$refs.container.append(ad)
// this._startCheckTimer()
},
_renderNext () {
if (this._pi >= this._pl.length - 1) {
return
}
this._pi++
this._renderAd()
},
_checkRender () {
var hasContent = this.$refs.container.querySelector('a') || this.$refs.container.querySelector('iframe')
return hasContent
},
_startCheckTimer () {
this._clearCheckTimer()
this._checkTimer = setInterval(() => {
if (this._checkRender()) {
this._clearCheckTimer()
return
}
this._checkTimerCount++
if (this._checkTimerCount >= CHECK_RENDER_RETRY) {
this._clearCheckTimer()
this._renderNext()
}
}, CHECK_RENDER_DELAY)
},
_clearCheckTimer () {
this._checkTimerCount = 0
if (this._checkTimer != null) {
window.clearInterval(this._checkTimer)
}
},
_randomId () {
return 'ad' + Date.now() + '' + parseInt(Math.random() * 1000)
}
}
}
</script>
<style>
uni-ad {
display: block;
overflow: hidden;
}
uni-ad[hidden] {
display: none;
}
uni-ad .uni-ad-container {
min-height: 1px;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册