xugenyuan

ref |> 更新最新的H5模板

Signed-off-by: xugenyuan <xugenyuan@wondertek.com.cn>
... ... @@ -199,7 +199,7 @@
<div class="head-link-block" v-if="hasHeadLink" @click="moreInformationClick">
<img v-if="darkMode === 'light'" src="./image/headLinkIcon.svg" alt="">
<img v-if="darkMode === 'dark'" src="./image/dark/headLinkIcon.svg" alt="">
<span class="head-link-block-str" v-html="details.newLinkObject.newsTitle"></span>
<span class="head-link-block-str" v-html="details.newLinkObject ? details.newLinkObject.newsTitle : ''"></span>
</div>
<!-- 导读 -->
<div class="new-intro-box droidSerif" v-if="details.newIntroduction">
... ... @@ -219,7 +219,7 @@
<div class="cdescrip_text" v-if="details.rmhDesc" @click="skipCustomerNumberPage">{{details.rmhDesc}}</div>
</div>
<!-- @click.stop阻止事件冒泡 -->
<template v-if="!isOwer && showButton">
<template v-if="!isOwer">
<div class="clook-btn clook" @click.stop="clookBtn" v-if="clookStatusSee || showClook">
<template v-if="clookBtnActive">
<img class="clook-loading anticon-spin" src="./image/loading_clock.svg" alt="">
... ... @@ -276,14 +276,8 @@
<div class="aft anmite-vote" v-if="voteState.status == 1 || !details.endTimePoint">
<div class="jdat" v-if="optionList.length">
<div class="pkjd-box" v-if="optionList[0].votesBf != 0 || optionList[1].votesBf != 0">
<span
class="s s1"
:style="optionList.length ? optionList[0].oneStyleAfter : undefined"
></span>
<spsn
class="s s2"
:style="optionList.length ? optionList[1].twoStyleAfter : undefined"
></spsn>
<span class="s s1" :style="optionList.length ? optionList[0].oneStyleAfter : undefined"></span>
<spsn class="s s2" :style="optionList.length ? optionList[1].twoStyleAfter : undefined"></spsn>
</div>
<span
v-if="optionList[0].votesBf === 0 && optionList[1].votesBf === 0"
... ... @@ -427,7 +421,7 @@
</div>
<!-- 分享 -->
<!-- <div class="share" v-if="shareOpen" :style="{ marginTop: actieInfo.show ? '0.64rem' : undefined }">
<div class="share" v-if="shareOpen" :style="{ marginTop: actieInfo.show ? '0.64rem' : undefined }">
<div
v-if="details.shareInfo.sharePosterOpen == 1"
class="sharePoster share-wrapper share-box"
... ... @@ -506,7 +500,7 @@
<span>微博</span>
</div>
</div>
</div> -->
</div>
<div class="reload-page" v-if="baseNode == 'dev'" @click="mockAppClearData">模拟app复用重新加载</div>
</div>
... ... @@ -533,6 +527,7 @@
<div id="hidden"></div>
<div id="hiddenArticle"></div>
<!-- Plugin 的 JS 文件 -->
<script src="./js/plugin/error-stack-parser.min.js"></script>
<script src="./js/plugin/jquery.min.js"></script>
<script src="./js/plugin/vue3.min.js"></script>
<script src="./js/plugin/day.min.js"></script>
... ...
... ... @@ -18,7 +18,7 @@ function useAudio(audioState, details) {
play: [],
pause: [],
error: [],
ended: [],
ended: []
}
const start = () => {
... ... @@ -69,7 +69,6 @@ function useAudio(audioState, details) {
audioEvent.error.push(errorFun)
audioEvent.ended.push(endedFun)
const playFun = function () {
if (item_audio) {
audioPlayNum.value += 1
... ... @@ -150,32 +149,39 @@ function useAudio(audioState, details) {
audioStylePlay.style.display = 'block'
}
if (audioEvent.duration.length) {
if (audioEvent.duration && audioEvent.duration.length) {
item_audio.removeEventListener('durationchange', audioEvent.duration[key])
}
if (audioEvent.time.length) {
if (audioEvent.time && audioEvent.time.length) {
item_audio.removeEventListener('timeupdate', audioEvent.time[key])
}
if (audioEvent.ended.length) {
if (audioEvent.ended && audioEvent.ended.length) {
item_audio.removeEventListener('ended', audioEvent.ended[key])
}
if (audioEvent.error.length) {
if (audioEvent.error && audioEvent.error.length) {
item_audio.removeEventListener('error', audioEvent.error[key])
}
if (audioEvent.play.length) {
if (audioEvent.play && audioEvent.play.length) {
audioStylePlay.removeEventListener('click', audioEvent.play[key])
}
if (audioEvent.pause.length) {
if (audioEvent.pause && audioEvent.pause.length) {
audioStylePause.removeEventListener('click', audioEvent.pause[key])
}
})
audioEvent = {}
audioEvent = {
duration: [],
time: [],
play: [],
pause: [],
error: [],
ended: []
}
}
return {
... ...
... ... @@ -189,7 +189,6 @@ function useEditorContent(details, netstutas, audioState, loadlmageOnlyWifiSwitc
str = str.replace(/<VIDEO(.*?)poster="(.*?)"(.*?)>/g, '<VIDEO$1poster="" data-poster="$2"$3>')
str = str.replace(/<p>\s*<\/p>/g, '')
str = str.replace(/[\u200B-\u200D\uFEFF]/g, '')
str = str.replace(/‘/g, '\'')
str = htmlDecode(str)
// 这一步去除元素与元素之间的空格
str = str.replace(/>\s+</g, '><')
... ... @@ -220,6 +219,10 @@ function useEditorContent(details, netstutas, audioState, loadlmageOnlyWifiSwitc
jqHtml('#newsContent', { type: 'set', str })
const realHtml = jqHtml('#newsContent', { type: 'get' })
jqHtml('#newsContent', { type: 'set', str: '' })
mainProcessProgress['8'] = {
status:'success',
message: '准备调用:handleArticleStr方法'
}
domUtil.handleArticleStr(realHtml, (type, option) => {
if (type === 1) {
addPreview()
... ... @@ -235,13 +238,23 @@ function useEditorContent(details, netstutas, audioState, loadlmageOnlyWifiSwitc
}, details.value, netstutas.value, loadlmageOnlyWifiSwitch.value)
clearEmptyPel()
// errorBlock(
// './image/content_fail.svg',
// '获取内容失败,请重试',
// true
// )
changeContentHtmlHeight({ type: 'done-before' })
// setTimeout(() => {
// if (document.querySelector('.error-block').style.display !== 'block') {
// mainProcessProgress['9'] = {
// status:'success',
// message: '页面开始展示,去除骨架屏'
// }
// appBlock(true)
// mobileApp(true)
// startShowArticle = true
// }
// }, 4000)
if (document.querySelector('.error-block').style.display !== 'block') {
mainProcessProgress['9'] = {
status:'success',
message: '页面开始展示,去除骨架屏'
}
appBlock(true)
mobileApp(true)
startShowArticle = true
... ... @@ -306,8 +319,6 @@ function useEditorContent(details, netstutas, audioState, loadlmageOnlyWifiSwitc
const inner = dataInfo && (typeof dataInfo === 'undefined'
? 'undefined'
: typeof dataInfo === 'object' && dataInfo.jumpType && dataInfo.jumpType == 'internal')
console.log(inner)
console.log(dataInfo)
if (inner && url) {
jumpAppInnerFun(dataInfo, url)
} else if (url) {
... ...
... ... @@ -20,7 +20,7 @@ function useImage(details, netstutas, loadlmageOnlyWifiSwitch) {
imageLoadedLen.value += 1
}
if (hasPreview) {
if (hasPreview && record.parentNode) {
record.parentNode.setAttribute('status', 'success')
record.parentNode.classList.remove('error')
record.parentNode.classList.remove('minHeight')
... ... @@ -43,7 +43,7 @@ function useImage(details, netstutas, loadlmageOnlyWifiSwitch) {
}
if (hasPreview) {
if (hasPreview && record.parentNode) {
record.parentNode.setAttribute('status', 'error')
record.parentNode.classList.remove('success')
record.parentNode.classList.remove('loading')
... ... @@ -82,7 +82,7 @@ function useImage(details, netstutas, loadlmageOnlyWifiSwitch) {
imageLoadedLen.value += 1
}
if (hasPreview) {
if (hasPreview && record.parentNode) {
record.parentNode.setAttribute('status', 'error')
record.parentNode.classList.remove('success')
record.parentNode.classList.remove('loading')
... ...
... ... @@ -61,8 +61,10 @@ function useVideo() {
const isGiveWidth = !!height
videoItem.setAttribute('data-height', `${styleHeight}px`)
videoItem.style.height = `${styleHeight}px`
if (videoItem) {
videoItem.setAttribute('data-height', `${styleHeight}px`)
videoItem.style.height = `${styleHeight}px`
}
videoItem.parentNode.style.width = `100%`
videoItem.parentNode.style.height = `${styleHeight}px`
... ... @@ -87,8 +89,10 @@ function useVideo() {
if (isGiveWidth) return
const newHeight = !!playerWdith && !!playerHieght ? Number(width) * Number(playerHieght) / Number(
playerWdith) : 300
videoItem.setAttribute('data-height', `${newHeight}px`)
videoItem.style.height = `${newHeight}px`
if (videoItem) {
videoItem.setAttribute('data-height', `${newHeight}px`)
videoItem.style.height = `${newHeight}px`
}
videoItem.parentNode.style.width = `100%`
videoItem.parentNode.style.height = `${newHeight}px`
callback(newHeight)
... ...
dayjs.extend(dayjs_plugin_localizedFormat)
dayjs.extend(dayjs_plugin_relativeTime)
const { onMounted, onUnmounted, toRefs, nextTick, watchEffect, toRef } = Vue
const { toRefs, nextTick, toRef } = Vue
function compareTimeArray(obj1, obj2, key, sort) {
const val1 = obj1[key]
... ... @@ -50,7 +50,6 @@ const app = Vue.createApp({
const isRmh = ref(null)
const isNewspaper = ref(null)
const browseStr = ref('')
const showButton = ref(false)
const state = reactive({
clientHeight: 0,
... ... @@ -217,8 +216,8 @@ const app = Vue.createApp({
// document.documentElement.setAttribute('data-size', state.appFontSize)
state.environment = window.config.VUE_BASE_HEADER.environment
// channelId.value = 2038
state.relId = 500004384175
state.contentId = 30037827178
// state.relId = 500005771692
state.contentId = 30037846595
contentId = state.contentId
clearInterval(time.value)
setTimeout(() => {
... ... @@ -235,16 +234,13 @@ const app = Vue.createApp({
}
document.querySelector('.error-block').style.display = 'none'
setRemUnit()
/*config数据是由H5预埋,App加载完成后 app主动传递的方法名请求数据 */
/* config数据是由H5预埋,App加载完成后 app主动传递的方法名请求数据 */
const config = window.config.VUE_CONTENT_CONFIG
try {
const data =
typeof config === 'object' ? config : JSON.parse(config)
if (data.dataJson) {
const dataJson =
typeof data.dataJson === 'object'
? data.dataJson
: JSON.parse(data.dataJson)
const dataJson = handleAppData(config)
if (dataJson) {
state.sourcePage = dataJson.sourcePage
clearInterval(time.value)
// console.log(`详情接口完成:${dayjs().format('HH:mm:ss:SSS')} - ${dayjs()
... ... @@ -269,7 +265,6 @@ const app = Vue.createApp({
//通用设备imei
state.deviceId = state.appHeader.device_id
state.userId = state.appHeader.userId
logInfo(state.userId)
// App服务协议
state.agreementURL = state.appHeader.agreementURL
//0:无网 1:Wi-Fi 2:2G 3:3G 4:4G 5:5G
... ... @@ -278,7 +273,6 @@ const app = Vue.createApp({
state.environment = state.appHeader.environment
})
} catch (e) {
}
try {
... ... @@ -286,7 +280,6 @@ const app = Vue.createApp({
} catch (e) {}
try {
// console.log('详情初始数据', data)
if (data.dataExt) {
hasAppLoginExtra = true
... ... @@ -317,12 +310,11 @@ const app = Vue.createApp({
}
// 处理详情
let initialRes = dataJson.responseMap
initialRes =
typeof initialRes === 'object'
? initialRes
: JSON.parse(initialRes)
initData(initialRes, dataJson.contentId)
mainProcessProgress['3'] = {
status:'success',
message: '准备调用:initData方法'
}
initData(handleAppDetails(dataJson.responseMap), dataJson.contentId)
} else {
errorResponse()
errorBlock(
... ... @@ -331,6 +323,13 @@ const app = Vue.createApp({
true
)
}
} else {
errorResponse()
errorBlock(
'./image/no_net.svg',
'网络出小差了,请检查网络后重试',
true
)
}
} catch (e) { }
}
... ... @@ -339,7 +338,16 @@ const app = Vue.createApp({
if (window.config.VUE_BASE_NODE === 'dev') {
if (devApp || window.config.devApp) {
const details = res.data ? res.data.length > 0 ? res.data[0] : {} : {}
mainProcessProgress['1'] = {
status:'success',
message: 'App给到的数据',
appData: res
}
hasDetails = true
mainProcessProgress['4'] = {
status:'success',
message: '准备调用:handleArticle方法'
}
handleArticle(details)
return
... ... @@ -347,9 +355,9 @@ const app = Vue.createApp({
const response = await axiosRequest({
url: '/content/zh/c/content/detail',
methot: 'post',
methot: 'get',
appStatus: false,
isMock: true,
// isMock: true,
// weakNetwork: true,
// mockTimeOut: 10,
//环境
... ... @@ -357,14 +365,9 @@ const app = Vue.createApp({
//接口前缀
prefix: '/api/rmrb-bff-display-zh',
//给接口传的数据
data: {
contents: [
{
//内容id
contentId: id,
relId: state.relId
}
]
params: {
contentId: id,
relId: state.relId
},
//请求头信息
headers: state.appHeader
... ... @@ -375,7 +378,16 @@ const app = Vue.createApp({
if (response.success) {
if (response.data) {
const details = response.data.length > 0 ? response.data[0] : {}
mainProcessProgress['1'] = {
status:'success',
message: 'App给到的数据',
appData: response
}
hasDetails = true
mainProcessProgress['4'] = {
status:'success',
message: '准备调用:handleArticle方法'
}
handleArticle(details)
} else {
errorResponse()
... ... @@ -399,6 +411,10 @@ const app = Vue.createApp({
hasDetails = true
// 获取用户登录状态
if (hasAppLoginExtra) {
mainProcessProgress['4'] = {
status:'success',
message: '准备调用:handleArticle方法'
}
handleArticle(details)
} else {
// const nowDate = dayjs()
... ... @@ -413,6 +429,10 @@ const app = Vue.createApp({
state.creatorID = loginStatusResponse && loginStatusResponse.creatorID
state.isLogined =
loginStatusResponse && loginStatusResponse.isLogined
mainProcessProgress['4'] = {
status:'success',
message: '准备调用:handleArticle方法'
}
handleArticle(details)
})
} catch (e) { }
... ... @@ -453,8 +473,16 @@ const app = Vue.createApp({
state.details = deepCopy(details)
state.originDataSource = deepCopy(details)
if (window.config.VUE_BASE_NODE === 'dev') {
mainProcessProgress['5'] = {
status:'success',
message: '准备调用:initApp方法'
}
initApp(details)
} else {
mainProcessProgress['5'] = {
status:'success',
message: '准备调用:initApp方法'
}
initApp(details)
try {
// H5传递数据至App
... ... @@ -531,6 +559,10 @@ const app = Vue.createApp({
if (pageError) {
changeAppError()
}
mainProcessProgress['7'] = {
status:'success',
message: '准备调用:initEditorStr方法'
}
initEditorStr(isNewspaper.value)
})
}
... ... @@ -642,13 +674,11 @@ const app = Vue.createApp({
if (state.isLogined == 1) {
// 已登录
if (window.config.VUE_BASE_NODE === 'dev') {
showButton.value = true
showClook.value = true
} else {
clookStatus(true) // 查"关注"状态 , 更新按钮上的文字
}
} else {
showButton.value = true
showClook.value = true
}
}
... ... @@ -674,6 +704,10 @@ const app = Vue.createApp({
if (actieInfo.title) { actieInfo.show = true }
}
mainProcessProgress['6'] = {
status:'success',
message: '准备调用:getOthersStatus回调方法'
}
if (callBack) callBack()
}
... ... @@ -1052,13 +1086,11 @@ const app = Vue.createApp({
headers: state.appHeader,
showError: false
})
showButton.value = true
if (response.success) {
clookStatusSee.value = response.data[0].status == '1' ? false : true // '1' 是已关注 '0'是未关注
}
} else {
if (state.creatorID == state.details.rmhId) {
showButton.value = true
isOwer.value = true
clookStatusSee.value = false
nextTick(() => {
... ... @@ -1093,7 +1125,6 @@ const app = Vue.createApp({
const code = statusResponseMap.code
const data = statusResponseMap.data
if ([ 200, '0' ].includes(code)) {
showButton.value = true
if (data) {
if (data[0].status == '1') {
state.initClockStatus = !initStatus
... ... @@ -1356,24 +1387,7 @@ const app = Vue.createApp({
data: [
{
voteInfo: shallowMergeObj(state.originDataSource.voteInfo, {
options: [
{
backColor: '#486FFF',
index: 1,
optionId: 8537,
summary: 2,
totalVotes: 1,
wordColor: '#FFFFFF'
},
{
backColor: '#486FFF',
index: 2,
optionId: 8538,
summary: 1,
totalVotes: 0,
wordColor: '#FFFFFF'
}
]
options: voteOtions.value
})
}
]
... ... @@ -1407,16 +1421,14 @@ const app = Vue.createApp({
sendNative(
'jsCall_callAppService',
{
method: 'post',
method: 'get',
url: '/api/rmrb-bff-display-zh/content/zh/c/content/detail',
parameters: {
contents: shallowMergeObj({
contentId: eq
}, reLInfo)
contentId: eq,
...reLInfo
}
},
(res) => {
logInfo('res', res)
try {
const refResponse =
typeof res === 'object' ? res : JSON.parse(res)
... ... @@ -1456,6 +1468,7 @@ const app = Vue.createApp({
const voteStatus = async (vId, index, callBack) => {
if (window.config.VUE_BASE_NODE === 'dev') {
voteInit.value = true
state.voteState.optionId = voteOtions.value[0].optionId
state.voteState.status = 1 // 决定是投票前0 还是 投票后1
nextTick(() => handleVoteList())
if (state.details.voteInfo.style === 1) {
... ... @@ -1493,10 +1506,12 @@ const app = Vue.createApp({
if ([ 200, '0' ].includes(code) && data) {
if (Object.keys(data).length > 0) {
try {
voteInit.value = true
state.voteState.status = data.status // 决定是投票前0 还是 投票后1
state.voteState.optionId = data.optionId // 返回的是 被投票项的 optionId ,没投就是 ''
nextTick(() => handleVoteList())
} catch (e) {}
} catch (e) {
}
if (state.details.voteInfo.style === 1) {
// 展示对 √
if (index) {
... ... @@ -1914,6 +1929,7 @@ const app = Vue.createApp({
document.querySelector('.skeleton-loading').classList.add('active')
appBlock(false)
mainProcessProgress = {}
time.value = ''
deviceType.value = judgTerminal() === 1 ? 'ad' : 'ios'
statrTime.value = dayjs()
... ... @@ -1928,7 +1944,6 @@ const app = Vue.createApp({
isNewspaper.value = false
voteInit.value = false
showClook.value = false
showButton.value = false
optionList.value = []
subjectList.value = []
channelList.value = []
... ... @@ -2054,7 +2069,6 @@ const app = Vue.createApp({
optionList,
showClook,
clookStatusSee,
showButton,
timeLine,
shareOpen,
hasReadCount,
... ... @@ -2092,5 +2106,6 @@ const app = Vue.createApp({
app.mount('#app')
app.config.errorHandler = (err) => {
h5ErrorPage(err.toString())
const ev = handleJsError('vue-errorHandler', err, err.message)
h5ErrorPage(ev, err)
}
... ...
!function(e,t){"use strict";"function"==typeof define&&define.amd?define("stackframe",[],t):"object"==typeof exports?module.exports=t():e.StackFrame=t()}(this,function(){"use strict";function e(e){return e.charAt(0).toUpperCase()+e.substring(1)}function t(e){return function(){return this[e]}}var r=["isConstructor","isEval","isNative","isToplevel"],n=["columnNumber","lineNumber"],i=["fileName","functionName","source"],a=r.concat(n,i,["args"],["evalOrigin"]);function o(t){if(t)for(var r=0;r<a.length;r++)void 0!==t[a[r]]&&this["set"+e(a[r])](t[a[r]])}o.prototype={getArgs:function(){return this.args},setArgs:function(e){if("[object Array]"!==Object.prototype.toString.call(e))throw new TypeError("Args must be an Array");this.args=e},getEvalOrigin:function(){return this.evalOrigin},setEvalOrigin:function(e){if(e instanceof o)this.evalOrigin=e;else{if(!(e instanceof Object))throw new TypeError("Eval Origin must be an Object or StackFrame");this.evalOrigin=new o(e)}},toString:function(){var e=this.getFileName()||"",t=this.getLineNumber()||"",r=this.getColumnNumber()||"",n=this.getFunctionName()||"";return this.getIsEval()?e?"[eval] ("+e+":"+t+":"+r+")":"[eval]:"+t+":"+r:n?n+" ("+e+":"+t+":"+r+")":e+":"+t+":"+r}},o.fromString=function(e){var t=e.indexOf("("),r=e.lastIndexOf(")"),n=e.substring(0,t),i=e.substring(t+1,r).split(","),a=e.substring(r+1);if(0===a.indexOf("@"))var s=/@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(a,""),c=s[1],u=s[2],f=s[3];return new o({functionName:n,args:i||void 0,fileName:c,lineNumber:u||void 0,columnNumber:f||void 0})};for(var s=0;s<r.length;s++)o.prototype["get"+e(r[s])]=t(r[s]),o.prototype["set"+e(r[s])]=function(e){return function(t){this[e]=Boolean(t)}}(r[s]);for(var c=0;c<n.length;c++)o.prototype["get"+e(n[c])]=t(n[c]),o.prototype["set"+e(n[c])]=function(e){return function(t){if(r=t,isNaN(parseFloat(r))||!isFinite(r))throw new TypeError(e+" must be a Number");var r;this[e]=Number(t)}}(n[c]);for(var u=0;u<i.length;u++)o.prototype["get"+e(i[u])]=t(i[u]),o.prototype["set"+e(i[u])]=function(e){return function(t){this[e]=String(t)}}(i[u]);return o}),function(e,t){"use strict";"function"==typeof define&&define.amd?define("error-stack-parser",["stackframe"],t):"object"==typeof exports?module.exports=t(require("stackframe")):e.ErrorStackParser=t(e.StackFrame)}(this,function(e){"use strict";var t=/(^|@)\S+:\d+/,r=/^\s*at .*(\S+:\d+|\(native\))/m,n=/^(eval@)?(\[native code])?$/;return{parse:function(e){if(void 0!==e.stacktrace||void 0!==e["opera#sourceloc"])return this.parseOpera(e);if(e.stack&&e.stack.match(r))return this.parseV8OrIE(e);if(e.stack)return this.parseFFOrSafari(e);throw new Error("Cannot parse given Error object")},extractLocation:function(e){if(-1===e.indexOf(":"))return[e];var t=/(.+?)(?::(\d+))?(?::(\d+))?$/.exec(e.replace(/[()]/g,""));return[t[1],t[2]||void 0,t[3]||void 0]},parseV8OrIE:function(t){return t.stack.split("\n").filter(function(e){return!!e.match(r)},this).map(function(t){t.indexOf("(eval ")>-1&&(t=t.replace(/eval code/g,"eval").replace(/(\(eval at [^()]*)|(,.*$)/g,""));var r=t.replace(/^\s+/,"").replace(/\(eval code/g,"(").replace(/^.*?\s+/,""),n=r.match(/ (\(.+\)$)/);r=n?r.replace(n[0],""):r;var i=this.extractLocation(n?n[1]:r),a=n&&r||void 0,o=["eval","<anonymous>"].indexOf(i[0])>-1?void 0:i[0];return new e({functionName:a,fileName:o,lineNumber:i[1],columnNumber:i[2],source:t})},this)},parseFFOrSafari:function(t){return t.stack.split("\n").filter(function(e){return!e.match(n)},this).map(function(t){if(t.indexOf(" > eval")>-1&&(t=t.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,":$1")),-1===t.indexOf("@")&&-1===t.indexOf(":"))return new e({functionName:t});var r=/((.*".+"[^@]*)?[^@]*)(?:@)/,n=t.match(r),i=n&&n[1]?n[1]:void 0,a=this.extractLocation(t.replace(r,""));return new e({functionName:i,fileName:a[0],lineNumber:a[1],columnNumber:a[2],source:t})},this)},parseOpera:function(e){return!e.stacktrace||e.message.indexOf("\n")>-1&&e.message.split("\n").length>e.stacktrace.split("\n").length?this.parseOpera9(e):e.stack?this.parseOpera11(e):this.parseOpera10(e)},parseOpera9:function(t){for(var r=/Line (\d+).*script (?:in )?(\S+)/i,n=t.message.split("\n"),i=[],a=2,o=n.length;a<o;a+=2){var s=r.exec(n[a]);s&&i.push(new e({fileName:s[2],lineNumber:s[1],source:n[a]}))}return i},parseOpera10:function(t){for(var r=/Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i,n=t.stacktrace.split("\n"),i=[],a=0,o=n.length;a<o;a+=2){var s=r.exec(n[a]);s&&i.push(new e({functionName:s[3]||void 0,fileName:s[2],lineNumber:s[1],source:n[a]}))}return i},parseOpera11:function(r){return r.stack.split("\n").filter(function(e){return!!e.match(t)&&!e.match(/^Error created at/)},this).map(function(t){var r,n=t.split("@"),i=this.extractLocation(n.pop()),a=n.shift()||"",o=a.replace(/<anonymous function(: (\w+))?>/,"$2").replace(/\([^)]*\)/g,"")||void 0;a.match(/\(([^)]*)\)/)&&(r=a.replace(/^[^(]+\(([^)]*)\)$/,"$1"));var s=void 0===r||"[arguments not available]"===r?void 0:r.split(",");return new e({functionName:o,args:s,fileName:i[0],lineNumber:i[1],columnNumber:i[2],source:t})},this)}}});
//# sourceMappingURL=error-stack-parser.min.js.map
... ...
... ... @@ -15,7 +15,7 @@ function playerVideo(player, events) {
const top = player.container.parentNode.offsetTop
const left = player.container.parentNode.getBoundingClientRect().left
const videoLandscape = width > height ? '1' : (width < height ? '2' : '')
const videoUrl = player.options.record.url
const videoUrl = player.options ? player.options.record ? player.options.record.url : '' : ''
if (window.config.VUE_BASE_NODE === 'dev') {
console.log('视频播放', width, height, left, top, videoLandscape)
... ...
... ... @@ -31,7 +31,7 @@ class videoEnPlayer extends Emitter {
initOhtersPlayer() {
const domId = this.container.getAttribute('id')
const url = this.options.record.url
const url = this.options ? this.options.record ? this.options.record.url : '' : ''
const isDark = document.querySelector('html').getAttribute('dark-mode') === 'true'
this.originPoster = this.options.record.poster
this.previewPoster = this.options.record.poster
... ...
... ... @@ -157,7 +157,9 @@ class DomUtil {
// 处理所有表格属性
for (let i = 0; i < tableAllDom.length; i++) {
tableAllDom[i].setAttribute('width', '')
if (tableAllDom[i]) {
tableAllDom[i].setAttribute('width', '')
}
}
// 处理图片点亮
... ... @@ -833,7 +835,7 @@ class DomUtil {
const isInline = style && style.display ? style.display.indexOf('inline') > -1 : false
if (!classList.includes('not-preview-image') && name !== 'people' && !isInline) {
effectImage.push(imageDom[i])
} else {
} else if (imageDom[i]) {
imageDom[i].setAttribute('status', 'loading')
}
} else {
... ... @@ -959,8 +961,10 @@ class DomUtil {
let height = 0
const videoEl = videoDomList[i]
const videoElId = `origin-video-${i}`
videoEl.setAttribute('id', videoElId)
videoEl.setAttribute('class', 'en-origin-video')
if (videoEl) {
videoEl.setAttribute('id', videoElId)
videoEl.setAttribute('class', 'en-origin-video')
}
const src = videoDomList[i].getAttribute('src')
if (!src) break
if (videoEl && videoEl.style.display === 'none') break
... ... @@ -1034,7 +1038,9 @@ class DomUtil {
const aEl = document.querySelectorAll('#newsContent a')
for (let i = 0; i < aEl.length; i++) {
const url = aEl[i].getAttribute('href')
aEl[i].setAttribute('data-href', url || '')
if (aEl[i]) {
aEl[i].setAttribute('data-href', url || '')
}
aEl[i].removeAttribute('href')
aEl[i].style.textDecoration = 'underline'
}
... ...
function h5ErrorPage(message) {
const ERROR_ID = []
function h5ErrorPage(message, error) {
if (error && !getIsReportId(error)) return
pageErrorTypePoint({ errorMessage: message })
errorBlock(
'./image/content_fail.svg',
... ... @@ -6,13 +10,49 @@ function h5ErrorPage(message) {
)
}
function getErrorId(val) {
return window.btoa(decodeURIComponent(encodeURIComponent(val)))
}
function getIsReportId(error) {
const id = getErrorId(error?.message || error?.fileName)
const even = item => item === id
if (ERROR_ID.some(even)) {
console.warn(`Duplicate error, not reported, ${error?.message}`)
return false
} else {
ERROR_ID.push(id)
return true
}
}
function handleJsError(type, ev, message) {
let stackFrame = ErrorStackParser.parse(ev)[0]
// 错误文件、行号、列号、源文件、堆栈等等
let { source } = stackFrame
const stack = `${type}: ` + message + ` ${trim(source)}`
return stack
}
window.onerror = function (message, source, lineno, colno, error) {
h5ErrorPage(message)
console.log(111)
const ev = handleJsError('window-onerror', error, error.message)
h5ErrorPage(ev, error)
}
window.addEventListener('error', function (error) {
const ev = handleJsError('addEventListener-error', error.error, error.message)
h5ErrorPage(ev, error)
})
window.addEventListener('unhandledrejection', function (e) {
e.preventDefault()
h5ErrorPage(e.reason.stack)
const ev = handleJsError('unhandledrejection-error', e.reason, e.reason.message)
h5ErrorPage(ev, e.reason)
// 唯一id判断
// const error = e.reason.stack
// const errorSource = extractParenthesesContent(error || '')
// const first = error ? error.split('\n')[0] : error
// h5ErrorPage(first + ` (${errorSource.map(el => `"${el}"`).join('、')})`)
return true
})
... ...
... ... @@ -21,6 +21,8 @@ const userAgent = navigator.userAgent
// 页面加载模式
var darkMode = 'light'
// var darkMode = 'dark'
// 页面主进程进度
var mainProcessProgress = {}
/**
* @Author gx12358
... ...
... ... @@ -266,6 +266,81 @@ function setHtmlBaseOptions(appData) {
}
}
/**
* @Author gx12358
* @DateTime 2024/9/23
* @lastTime 2024/9/23
* @description 处理客户端给到的数据
*/
function handleAppData(appData) {
const data =
typeof appData === 'object' ? appData : JSON.parse(appData)
if (data.dataJson) {
const dataJson =
typeof data.dataJson === 'object'
? data.dataJson
: JSON.parse(data.dataJson)
return dataJson
}
return null
}
/**
* @Author gx12358
* @DateTime 2024/9/23
* @lastTime 2024/9/23
* @description 拿到详情接口数据
*/
function handleAppDetails(responseMap) {
let initialRes = responseMap
initialRes =
typeof initialRes === 'object'
? initialRes
: JSON.parse(initialRes)
return initialRes
}
/**
* @Author gx12358
* @DateTime 2024/9/23
* @lastTime 2024/9/23
* @description appData - init
*/
function detailsChange(appData, responseCallback) {
// const data =
// typeof appData === 'object' ? appData : JSON.parse(appData)
const dataJson = handleAppData(appData)
// try {
// sendNative(
// 'jsCall_h5TrackingEvent',
// {
// eventId: 'h5_article_page_browse',
// parameters: {
// appData: JSON.stringify(data)
// }
// }
// )
// } catch (e) {}
mainProcessProgress = {}
mainProcessProgress['1'] = {
status:'success',
message: 'App给到的数据',
appData: JSON.stringify(handleAppDetails(dataJson))
}
window.config.VUE_CONTENT_CONFIG = appData
setHtmlBaseOptions(appData)
if (document.querySelector('#detail-change')) {
mainProcessProgress['2'] = {
status:'success',
message: '准备调用:requestApp方法'
}
document.querySelector('#detail-change').click()
}
if (responseCallback) responseCallback(appData)
}
/* 该方法由H5预埋,App加载完成后 app主动传递数据用。 */
document.addEventListener('DOMContentLoaded', function () {
if (window.config.VUE_BASE_NODE === 'dev') {
... ... @@ -325,23 +400,13 @@ document.addEventListener('DOMContentLoaded', function () {
if (judgTerminal() === 1) {
connectWebViewJavascriptBridge(function (bridge) {
bridge.registerHandler('jsCall_receiveAppData', function (appData, responseCallback) {
window.config.VUE_CONTENT_CONFIG = appData
setHtmlBaseOptions(appData)
if (document.querySelector('#detail-change')) {
document.querySelector('#detail-change').click()
}
if (responseCallback) responseCallback(appData)
detailsChange(appData, responseCallback)
})
})
} else {
setupWebViewJavascriptBridge(function (bridge) {
bridge.registerHandler('jsCall_receiveAppData', function (appData, responseCallback) {
window.config.VUE_CONTENT_CONFIG = appData
setHtmlBaseOptions(appData)
if (document.querySelector('#detail-change')) {
document.querySelector('#detail-change').click()
}
if (responseCallback) responseCallback(appData)
detailsChange(appData, responseCallback)
})
})
}
... ...
... ... @@ -1019,8 +1019,16 @@ function pageErrorTypePoint({
newsId,
errorMessage
}) {
logInfo('contentId', newsId || contentId)
logInfo('error', errorMessage)
const parameters = {
newsId: newsId || contentId,
errorMessage,
userAgent,
date: dayjs().format('YYYY-MM-DD HH:mm:ss'),
mainProcessProgress: JSON.stringify(mainProcessProgress)
}
logInfo(Object.assign(parameters, {
mainProcessProgress
}))
try {
sendNative('jsCall_currentPageOperate', {
operateType: '50'
... ... @@ -1032,10 +1040,7 @@ function pageErrorTypePoint({
'jsCall_h5TrackingEvent',
{
eventId: 'h5_article_page_error',
parameters: {
newsId: newsId || contentId,
errorMessage
}
parameters
}
)
} catch (e) {}
... ... @@ -1381,7 +1386,7 @@ function jumpAppInnerFun(record, url) {
if (window.config.VUE_BASE_NODE === 'dev') {
axiosRequest({
url: '/content/zh/c/content/detail',
methot: 'post',
methot: 'get',
appStatus: false,
// isMock: true,
// weakNetwork: true,
... ... @@ -1391,14 +1396,11 @@ function jumpAppInnerFun(record, url) {
//接口前缀
prefix: '/api/rmrb-bff-display-zh',
//给接口传的数据
data: {
contents: [
{
//内容id
contentId: record.contentId,
relId: record.relId
}
]
params: {
//内容id
contentId: record.contentId,
relId: record.relId,
relType: record.relType,
},
//请求头信息
headers: shallowMerge({
... ... @@ -1425,16 +1427,13 @@ function jumpAppInnerFun(record, url) {
sendNative(
'jsCall_callAppService',
{
method: 'post',
method: 'get',
url: '/api/rmrb-bff-display-zh/content/zh/c/content/detail',
parameters: {
contents: [
{
//内容id
contentId: record.contentId,
relId: record.relId
}
]
parameters: {
//内容id
contentId: record.contentId,
relId: record.relId,
relType: record.relType,
}
},
(res) => {
... ...