fanmingyou3_wd

添加wdRouter模块,

添加wdJsBridge,wdWebComponent模块
Showing 75 changed files with 1779 additions and 44 deletions
... ... @@ -47,6 +47,18 @@
]
},
{
"name": "wdConstant",
"srcPath": "./wdConstant",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
},
{
"name": "wdKit",
"srcPath": "./wdKit",
"targets": [
... ... @@ -83,8 +95,8 @@
]
},
{
"name": "wdConstant",
"srcPath": "./wdConstant",
"name": "wdNetwork",
"srcPath": "./wdNetwork",
"targets": [
{
"name": "default",
... ... @@ -95,8 +107,24 @@
]
},
{
"name": "wdNetwork",
"srcPath": "./wdNetwork",
"name": "wdRouter",
"srcPath": "./wdRouter",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
},
{
"name": "wdJsBridge",
"srcPath": "./wdJsBridge"
},
{
"name": "wdWebComponent",
"srcPath": "./wdWebComponent",
"targets": [
{
"name": "default",
... ...
... ... @@ -10,7 +10,9 @@
"wdComponent": "file:../wdComponent",
"wdConstant": "file:../wdConstant",
"wdKit": "file:../wdKit",
"wdWebComponent": "file:../wdWebComponent",
"wdBean": "file:../wdBean",
"wdRouter": "file:../wdRouter",
"wdNetwork": "file:../wdNetwork"
}
}
... ...
... ... @@ -3,10 +3,12 @@ import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
import { registerRouter } from 'wdRouter';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
registerRouter();
}
onDestroy(): void {
... ...
import router from '@ohos.router';
import { Action } from 'wdBean';
import { Logger } from 'wdKit';
import { WdWebComponent } from 'wdWebComponent';
const TAG = 'DefaultWebPage';
@Entry
@Component
struct DefaultWebPage {
private url?: string;
@State reload: number = 0;
aboutToAppear() {
let action: Action = router.getParams() as Action
if (action) {
this.url = action.params?.url
}
}
onPageShow() {
Logger.info(TAG, `DefaultWebPage# onPageShow:::refresh`);
this.reload = ++this.reload
}
onPageHide() {
this.reload = 0
}
build() {
Column() {
WdWebComponent({
webUrl: this.url,
backVisibility: true,
reload: this.reload
})
}
}
}
... ...
{
"src": [
"pages/Index"
"pages/Index",
"pages/web/DefaultWebPage"
]
}
... ...
... ... @@ -26,6 +26,10 @@ export { ItemDTO } from './src/main/ets/bean/ItemDTO';
export { ItemBean } from './src/main/ets/bean/ItemBean';
// component
export { Action } from './src/main/ets/bean/programme/Action'
export { Params } from './src/main/ets/bean/programme/Params'
export { LabelBean } from './src/main/ets/bean/component/extra/LabelBean';
export { LabelDTO } from './src/main/ets/bean/component/extra/LabelDTO';
... ...
import { Params } from './Params';
// 事件对象
export interface Action {
type: string;
name?: string; // 行为的名称,目前值与type相同,暂不启用
// params?: Params; // 参数集合
params?: Params; // 参数集合
}
\ No newline at end of file
... ...
import { ExtraDTO } from '../component/extra/ExtraDTO';
export interface Params {
pageID: string;
contentID?: string;
path?: string;
url?: string;
extra?: ExtraDTO; // 跳转时额外需要带的参数:map<String,String> 即仅有一层的json
detailPageType?:number; // 详情页类型
}
... ...
... ... @@ -9,6 +9,7 @@
"dependencies": {
"wdConstant": "file:../wdConstant",
"wdKit": "file:../wdKit",
"wdBean": "file:../wdBean"
"wdBean": "file:../wdBean",
"wdRouter": "file:../wdRouter"
}
}
... ...
import { ContentDTO, ScreenType } from 'wdBean';
import { CommonConstants } from 'wdConstant';
import { Action, ContentDTO, Params, ScreenType } from 'wdBean';
import { CommonConstants, ConfigConstants } from 'wdConstant';
import { Logger } from 'wdKit';
import { CompUtils } from '../utils/CompUtils';
import { WDRouterRule } from 'wdRouter';
const TAG: string = 'CardView';
... ... @@ -70,6 +71,13 @@ export struct CarouselLayout01CardView {
.hoverEffect(HoverEffect.Scale)
.onClick((event: ClickEvent) => {
Logger.info(TAG, `BannerComponent onClick event index: ${this.index}`);
let taskAction: Action = {
type: 'JUMP_H5_BY_WEB_VIEW',
params: {
url: ConfigConstants.DETAIL_URL
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
})
}
}
... ... @@ -143,6 +151,13 @@ export struct SingleColumn01CardView {
.hoverEffect(HoverEffect.Scale)
.onClick((event: ClickEvent) => {
Logger.info(TAG, `SingleColumn01CardView onClick event index: ${this.index}`);
let taskAction: Action = {
type: 'JUMP_H5_BY_WEB_VIEW',
params: {
url: ConfigConstants.DETAIL_URL
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
})
}
}
... ... @@ -258,6 +273,13 @@ export struct SingleColumn02CardView {
.hoverEffect(HoverEffect.Scale)
.onClick((event: ClickEvent) => {
Logger.info(TAG, `SingleColumn02CardView onClick event index: ${this.index}`);
let taskAction: Action = {
type: 'JUMP_H5_BY_WEB_VIEW',
params: {
url: ConfigConstants.DETAIL_URL
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
})
}
}
... ... @@ -356,6 +378,13 @@ export struct MasonryLayout01CardView {
.hoverEffect(HoverEffect.Scale)
.onClick((event: ClickEvent) => {
Logger.info(TAG, `MasonryLayout01CardView onClick event index: ${this.index}`);
let taskAction: Action = {
type: 'JUMP_H5_BY_WEB_VIEW',
params: {
url: ConfigConstants.DETAIL_URL
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
})
}
}
\ No newline at end of file
... ...
import { ContentDTO } from 'wdBean';
import { CommonConstants } from 'wdConstant';
import { Action, ContentDTO, Params } from 'wdBean';
import { CommonConstants, ConfigConstants } from 'wdConstant';
import { Logger } from 'wdKit';
import { WDRouterRule } from 'wdRouter';
const TAG = 'GridLayout01Component';
... ... @@ -13,7 +15,7 @@ const TAG = 'GridLayout01Component';
export struct GridLayout01Component {
@StorageLink('currentBreakpoint') currentBreakpoint: string = 'xs';
@State dataList?: ContentDTO[] = undefined
@State adapterBeanList?:ContentDTO[] = []
@State adapterBeanList?: ContentDTO[] = []
aboutToAppear() {
this.buildAdapterBeanList(this.currentBreakpoint)
... ... @@ -74,8 +76,8 @@ export struct GridLayout01Component {
}
@Builder
buildItemTopImgBottomTxt01(item: ContentDTO, index: number){
Column(){
buildItemTopImgBottomTxt01(item: ContentDTO, index: number) {
Column() {
Image(item.hImageUrl)
.width('100%')
.aspectRatio(16 / 9)
... ... @@ -95,7 +97,15 @@ export struct GridLayout01Component {
.backgroundColor(Color.White)
.hoverEffect(HoverEffect.Scale)
.alignItems(HorizontalAlign.Start)
.onClick((event: ClickEvent) => {
Logger.info(TAG, `buildItemTopImgBottomTxt01 onClick event index: ${index}`);
let taskAction: Action = {
type: 'JUMP_H5_BY_WEB_VIEW',
params: {
url: ConfigConstants.DETAIL_URL
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
})
}
}
\ No newline at end of file
... ...
import { ContentDTO } from 'wdBean';
import { Action, ContentDTO, Params } from 'wdBean';
import { ConfigConstants } from 'wdConstant';
import { Logger } from 'wdKit';
import { WDRouterRule } from 'wdRouter';
const TAG = 'SingleRow03Component';
... ... @@ -16,7 +19,7 @@ export struct SingleRow03Component {
List( {space: 2.5}){
ForEach(this.dataList, (item : ContentDTO, index?: number) =>{
ListItem(){
this.contentItem(item)
this.contentItem(item, index)
}
} , (item: ContentDTO) => JSON.stringify(item))
... ... @@ -29,7 +32,7 @@ export struct SingleRow03Component {
}
@Builder
contentItem(item: ContentDTO){
contentItem(item: ContentDTO, index?: number){
Column(){
RelativeContainer() {
Image(item.coverUrl)
... ... @@ -97,7 +100,15 @@ export struct SingleRow03Component {
.height($r('app.float.single_row_03_item_height'))
.backgroundColor(Color.White)
.alignItems(HorizontalAlign.Start)
.onClick((event: ClickEvent) => {
Logger.info(TAG, `contentItem onClick event index: ${index}`);
let taskAction: Action = {
type: 'JUMP_H5_BY_WEB_VIEW',
params: {
url: ConfigConstants.DETAIL_URL
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
})
}
}
\ No newline at end of file
... ...
... ... @@ -7,13 +7,11 @@ export class ConfigConstants {
*
*/
static readonly appId: string = "";
/**
* 终端id/terminalId
*
*/
static readonly terminalId: string = "android";
/**
* 36_渠道编码(sappType)
*
... ... @@ -22,34 +20,27 @@ export class ConfigConstants {
static readonly appType: string = "3"; // 手机客户端App(安卓)
static readonly clientType: string = "";
/**
* SourceID
*
*/
static readonly sourceId: string = "";
/**
* 产品渠道应用对照关系:
*/
static readonly appCode: string = "";
/**
* 基线代码和客户端应用版本号规范
*/
static readonly ptvCode: string = "";
/**
* 省份code/province(02->上海)
*/
static readonly province: string = "02";
/**
* 正在播放的节目ID
*/
static playingContentId?: string = null
static playingContentId?: string = undefined
/**
* 设备Id/deviceId
* 设备Id或者能标识请求端的唯一标识
... ... @@ -59,12 +50,10 @@ export class ConfigConstants {
* base url VOD
*/
static readonly BASE_URL_VOD: string = "";
/**
* base url Live
*/
static readonly BASE_URL_LIVE: string = "";
/**
* 获取用户信息的服务器
*/
... ... @@ -77,4 +66,8 @@ export class ConfigConstants {
* 电视台(直播)列表路径
*/
static readonly LIVE_TV_PATH: string = "/live/v2/tv-data";
/**
* 临时的详情URL
*/
static readonly DETAIL_URL = "https://pd-people-uat.pdnews.cn/h/contentTop/110?hiddenTopNavigation=true"
}
\ No newline at end of file
... ...
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test
\ No newline at end of file
... ...
export { BridgeWebViewControl } from './src/main/ets/core/BridgeWebViewControl'
export { BridgeHandler } from './src/main/ets/core/BridgeHandler'
export { Callback } from './src/main/ets/core/BridgeHandler'
export { BridgeUtil } from './src/main/ets/utils/BridgeUtil'
... ...
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default"
}
]
}
\ No newline at end of file
... ...
import { harTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}
... ...
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope
\ No newline at end of file
... ...
{
"license": "Apache-2.0",
"devDependencies": {},
"author": "",
"name": "wdjsbridge",
"description": "Please describe the basic information.",
"main": "Index.ets",
"version": "1.0.0",
"dependencies": {}
}
... ...
// 事件对象,同wdBean的Action
export interface Action {
type: string;
// params?: Params; // 参数集合
}
\ No newline at end of file
... ...
import { StringUtils } from '../utils/StringUtils';
/**
* 消息Message
*/
export class CallBackMessage {
callbackId: string = ""; //callbackId
responseId: string = ""; //responseId
responseData: string = ""; //responseData
data?: string; //data of message
handlerName: string = ""; //name of handler
/**
* TODO 待验证
* @returns
*/
toJson(): string {
let cloneObject:object = JSON.parse(JSON.stringify(this))
return StringUtils.escapeDoubleQuotes(JSON.stringify(cloneObject))
}
/**
* TODO 待验证
* @param jsonStr
* @returns
*/
toList(jsonStr: string): Array<CallBackMessage> {
return JSON.parse(jsonStr)
}
}
\ No newline at end of file
... ...
import { Action } from './Action';
/**
* 消息Message
*/
export class Message {
callbackId: string = ""; //callbackId
responseId: string = ""; //responseId
responseData: string = ""; //responseData
data?: Action; //data of message
handlerName: string = ""; //name of handler
/**
* TODO 待验证
* @returns
*/
toJson(): string {
let jsonString: string = JSON.stringify(this)
return jsonString
}
/**
* TODO 待验证
* @param jsonStr
* @returns
*/
toList(jsonStr: string): Array<Message> {
return JSON.parse(jsonStr)
}
}
\ No newline at end of file
... ...
import { Action } from '../bean/Action'
/**
* 注册回调接口
*/
export type Callback = (data: string) => void
export interface BridgeHandler {
handle: (data: Action, f: Callback) => void
}
export class DefaultBridgeHandler implements BridgeHandler {
handle(data: Action, f: Callback) {
//1,2.3
f("DefaultHandler response data")
}
}
\ No newline at end of file
... ...
import webview from '@ohos.web.webview';
import HashMap from '@ohos.util.HashMap';
import { BridgeHandler, DefaultBridgeHandler, Callback } from './BridgeHandler';
import { BridgeUtil } from '../utils/BridgeUtil';
import { Message } from '../bean/Message';
import { CallBackMessage } from '../bean/CallBackMessage';
import { StringUtils } from '../utils/StringUtils';
const TAG = 'BridgeWebViewControl';
export class BridgeWebViewControl extends webview.WebviewController {
/**
*
*/
private responseCallbacks: HashMap<string, Callback> = new HashMap<string, Callback>()
/**
*
*/
private messageHandlers: HashMap<string, BridgeHandler> = new HashMap()
/**
* 页面加载前,不能处理消息
*/
private uniqueId = 0;
registerHandler(handlerName: string, handler: BridgeHandler) {
if (handler != null) {
this.messageHandlers.set(handlerName, handler)
}
}
unregisterHandler(handlerName: string) {
if (handlerName != null) {
this.messageHandlers.remove(handlerName);
}
}
/**
* @param url
* @param returnCallback
*/
loadUrlCustom(url: string, returnCallback: Callback) {
this.loadUrl(url)
this.responseCallbacks.set(BridgeUtil.parseFunctionName(url), returnCallback);
}
/**
* 刷新消息
*/
flushMessageQueue() {
this.loadUrlCustom(BridgeUtil.JS_FETCH_QUEUE_FROM_JAVA, (data: string) => {
let list: Array<Message> = JSON.parse(data)
if (list == null || list.length == 0) {
return
}
list.forEach(value => {
let responseId: string = value.responseId
// 是否是response CallBackFunction,收到消息,
if (StringUtils.isNotEmpty(responseId)) {
let call: Callback = this.responseCallbacks.get(responseId)
let responseData: string = value.responseData;
if (StringUtils.isEmpty(responseData) || call === undefined) {
return
}
call(responseData)
this.responseCallbacks.remove(responseId)
} else {
let responseFunction: Callback;
let callbackId: string = value.callbackId
if (StringUtils.isNotEmpty(callbackId)) {
responseFunction = (data: string) => {
let msg: CallBackMessage = new CallBackMessage()
msg.responseId = callbackId
msg.responseData = data
this.queueMessage(msg)
}
} else {
responseFunction = (data: string) => {
//TODO 更换log输出方式
// Logger.info(TAG, `default response:: ${data}`);
}
}
let handle: BridgeHandler
if (StringUtils.isNotEmpty(value.handlerName)) {
handle = this.messageHandlers.get(value.handlerName)
} else {
handle = new DefaultBridgeHandler()
}
if (handle != undefined && value.data != undefined) {
handle.handle(value.data, responseFunction)
}
}
})
})
}
private queueMessage(msg: CallBackMessage) {
// //TODO
this.dispatchMessage(msg);
// }
}
/**
* 消息分发,最终执行js方法
* @param msg
*/
private dispatchMessage(msg: CallBackMessage) {
let messageJson: string = msg.toJson()
// messageJson = messageJson.replace("%7B", encodeURIComponent("%7B"));
// messageJson = messageJson.replace("%7D", encodeURIComponent("%7D"));
// messageJson = messageJson.replace("%22", encodeURIComponent("%22"));
let javascriptCommand: string = StringUtils.formatStringForJS(BridgeUtil.JS_HANDLE_MESSAGE_FROM_JAVA, messageJson);
this.runJavaScript(javascriptCommand)
}
/**
* native 主动调用JSBridge方法
* @param msg
*/
callHandle(handlerName: string, data: string, callBack: Callback) {
this.doSend(handlerName, data, callBack)
}
private doSend(handlerName: string, data: string, callBack: Callback) {
let msg: CallBackMessage = new CallBackMessage()
if (StringUtils.isNotEmpty(data)) {
// msg.data = data
}
if (StringUtils.isNotEmpty(handlerName)) {
msg.handlerName = handlerName
}
if (callBack != undefined) {
let callbackId: string = StringUtils.formatStringForJS(BridgeUtil.CALLBACK_ID_FORMAT, ++this.uniqueId + (BridgeUtil.UNDERLINE_STR + new Date().getTime()));
this.responseCallbacks.set(callbackId, callBack)
msg.callbackId = callbackId
}
this.queueMessage(msg);
}
handlerReturnData(url: string) {
let functionName: string = BridgeUtil.getFunctionFromReturnUrl(url);
let callback = this.responseCallbacks.get(functionName);
let data: string = BridgeUtil.getDataFromReturnUrl(url);
if (callback != undefined) {
callback(data)
this.responseCallbacks.remove(functionName)
}
}
//TODO
clean() {
this.responseCallbacks.clear()
this.messageHandlers.clear()
this.uniqueId = 0
}
}
... ...
import webview from '@ohos.web.webview';
import { ResourceManager } from './ResourceManager';
export class BridgeUtil {
static readonly YY_OVERRIDE_SCHEMA = "yy://";
static readonly YY_RETURN_DATA = BridgeUtil.YY_OVERRIDE_SCHEMA + "return/";
static readonly YY_FETCH_QUEUE = BridgeUtil.YY_RETURN_DATA + "_fetchQueue/";
static readonly EMPTY_STR = "";
static readonly UNDERLINE_STR = "_";
static readonly SPLIT_MARK = "/";
static readonly CALLBACK_ID_FORMAT = "JAVA_CB_%s";
static readonly JS_HANDLE_MESSAGE_FROM_JAVA = "javascript:WebViewJavascriptBridge._handleMessageFromNative('%s');";
static readonly JS_FETCH_QUEUE_FROM_JAVA = "javascript:WebViewJavascriptBridge._fetchQueue();";
static readonly JAVASCRIPT_STR = "javascript:";
// 例子 javascript:WebViewJavascriptBridge._fetchQueue(); --> _fetchQueue
static parseFunctionName(jsUrl: string): string {
return jsUrl.replace("javascript:WebViewJavascriptBridge.", "").replace("();", "");
}
static getDataFromReturnUrl(url: string): string {
if (url.startsWith(BridgeUtil.YY_FETCH_QUEUE)) {
// return = [{"responseId":"JAVA_CB_2_3957","responseData":"Javascript Says Right back aka!"}]
return url.replace(BridgeUtil.YY_FETCH_QUEUE, BridgeUtil.EMPTY_STR);
}
// temp = _fetchQueue/[{"responseId":"JAVA_CB_2_3957","responseData":"Javascript Says Right back aka!"}]
let temp = url.replace(BridgeUtil.YY_RETURN_DATA, BridgeUtil.EMPTY_STR);
let functionAndData = temp.split(BridgeUtil.SPLIT_MARK);
if (functionAndData.length < 2) {
return ""
}
let result = ""
functionAndData.forEach((value) => {
result = result + value
});
return result
}
/**
* TODO
*/
static releaseWebView() {
}
// 获取到传递信息的方法
// url = yy://return/_fetchQueue/[{"responseId":"JAVA_CB_1_360","responseData":"Javascript Says Right back aka!"}]
static getFunctionFromReturnUrl(url: string): string {
let temp = url.replace(BridgeUtil.YY_RETURN_DATA, BridgeUtil.EMPTY_STR);
let functionAndData = temp.split(BridgeUtil.SPLIT_MARK);
if (functionAndData.length >= 1) {
// functionAndData[0] = _fetchQueue
return functionAndData[0];
}
return ""
}
/**
* 这里只是加载lib包中assets中的 WebViewJavascriptBridge.js
* @param controller
* @param path 路径
*/
static webViewLoadLocalJs(context: Context, controller: webview.WebviewController) {
ResourceManager.getResourcesText(context, "WebViewJavascriptBridge.js").then((str) => {
//执行js注入
controller.runJavaScriptExt('javascript:' + str).then((msg) => {
console.log("Js注入结果:" + msg.getString());
})
})
}
}
\ No newline at end of file
... ...
import buffer from '@ohos.buffer';
export class ResourceManager {
/**
* 获取资源字符串内容
* @param context
* @param filename
* @returns
*/
static getResourcesText(context: Context, filename: string): Promise<string> {
return new Promise<string>((success, error) => {
context.resourceManager.getRawFileContent(filename).then((content: Uint8Array) => {
if (!content) {
error("file is empty");
return
}
let result = buffer.from(content).toString("utf8");
if (result) {
success(result);
} else {
error("parse resources file result is empty");
}
}).catch((err: Error) => {
error(err);
})
})
}
}
\ No newline at end of file
... ...
/**
* StringUtils class.
*/
export class StringUtils {
/**
* Check obj is not empty.
*
* @param {object} obj
* @return {boolean} true(not empty)
*/
static isNotEmpty(obj: any): boolean {
// return (obj && obj !== '');
// 或
return (obj !== undefined && obj !== null && obj !== '');
}
static isEmpty(...params: any): boolean {
if (params.length === 0) {
return true;
}
for (const param of params) {
if (!param) { // param === undefined || param === null || param === '';
return true;
}
}
return false;
}
static formatStringForJS(template: string, ...args: any[]): string {
let formattedString = template;
for (const arg of args) {
formattedString = formattedString.replace(/%s/, arg.toString());
}
return formattedString;
}
static escapeDoubleQuotes(obj:any): any {
if (typeof obj === 'string') {
return obj.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
} else if (typeof obj === 'object') {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
obj[key] = StringUtils.escapeDoubleQuotes(obj[key]);
}
}
}
return obj;
}
}
// export default new StringUtils();
... ...
{
"module": {
"name": "wdJsBridge",
"type": "har",
"description": "$string:shared_desc",
"deviceTypes": [
"phone",
"tablet",
"2in1"
]
}
}
\ No newline at end of file
... ...
{
"color": [
{
"name": "white",
"value": "#FFFFFF"
}
]
}
\ No newline at end of file
... ...
{
"string": [
{
"name": "shared_desc",
"value": "description"
}
]
}
\ No newline at end of file
... ...
//notation: js file can only use this kind of comments
//since comments will cause error when use in webview.loadurl,
//comments will be remove by java use regexp
(function() {
if (window.WebViewJavascriptBridge) {
return;
}
var messagingIframe;
var bizMessagingIframe;
var sendMessageQueue = [];
var receiveMessageQueue = [];
var messageHandlers = {};
var CUSTOM_PROTOCOL_SCHEME = 'yy';
var QUEUE_HAS_MESSAGE = '__QUEUE_MESSAGE__/';
var responseCallbacks = {};
var uniqueId = 1;
// 创建消息index队列iframe
function _createQueueReadyIframe(doc) {
messagingIframe = doc.createElement('iframe');
messagingIframe.style.display = 'none';
doc.documentElement.appendChild(messagingIframe);
}
//创建消息体队列iframe
function _createQueueReadyIframe4biz(doc) {
bizMessagingIframe = doc.createElement('iframe');
bizMessagingIframe.style.display = 'none';
doc.documentElement.appendChild(bizMessagingIframe);
}
//set default messageHandler 初始化默认的消息线程
function init(messageHandler) {
if (WebViewJavascriptBridge._messageHandler) {
throw new Error('WebViewJavascriptBridge.init called twice');
}
WebViewJavascriptBridge._messageHandler = messageHandler;
var receivedMessages = receiveMessageQueue;
receiveMessageQueue = null;
for (var i = 0; i < receivedMessages.length; i++) {
_dispatchMessageFromNative(receivedMessages[i]);
}
}
// 发送
function send(data, responseCallback) {
_doSend({
data: data
}, responseCallback);
}
// 注册线程 往数组里面添加值
function registerHandler(handlerName, handler) {
messageHandlers[handlerName] = handler;
}
// 调用线程
function callHandler(handlerName, data, responseCallback) {
_doSend({
handlerName: handlerName,
data: data
}, responseCallback);
}
//sendMessage add message, 触发native处理 sendMessage
function _doSend(message, responseCallback) {
if (responseCallback) {
var callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime();
responseCallbacks[callbackId] = responseCallback;
message.callbackId = callbackId;
}
sendMessageQueue.push(message);
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE;
}
// 提供给native调用,该函数作用:获取sendMessageQueue返回给native,由于android不能直接获取返回的内容,所以使用url shouldOverrideUrlLoading 的方式返回内容
function _fetchQueue() {
var messageQueueString = JSON.stringify(sendMessageQueue);
sendMessageQueue = [];
//android can't read directly the return data, so we can reload iframe src to communicate with java
if (messageQueueString !== '[]') {
bizMessagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://return/_fetchQueue/' + encodeURIComponent(messageQueueString);
}
}
//提供给native使用,
function _dispatchMessageFromNative(messageJSON) {
setTimeout(function() {
var message = JSON.parse(messageJSON);
var responseCallback;
//java call finished, now need to call js callback function
if (message.responseId) {
responseCallback = responseCallbacks[message.responseId];
if (!responseCallback) {
return;
}
responseCallback(message.responseData);
delete responseCallbacks[message.responseId];
} else {
//直接发送
if (message.callbackId) {
var callbackResponseId = message.callbackId;
responseCallback = function(responseData) {
_doSend({
responseId: callbackResponseId,
responseData: responseData
});
};
}
var handler = WebViewJavascriptBridge._messageHandler;
if (message.handlerName) {
handler = messageHandlers[message.handlerName];
}
//查找指定handler
try {
handler(message.data, responseCallback);
} catch (exception) {
if (typeof console != 'undefined') {
console.log("WebViewJavascriptBridge: WARNING: javascript handler threw.", message, exception);
}
}
}
});
}
//提供给native调用,receiveMessageQueue 在会在页面加载完后赋值为null,所以
function _handleMessageFromNative(messageJSON) {
//console.log(messageJSON);
if (receiveMessageQueue) {
receiveMessageQueue.push(messageJSON);
}
_dispatchMessageFromNative(messageJSON);
}
var WebViewJavascriptBridge = window.WebViewJavascriptBridge = {
init: init,
send: send,
registerHandler: registerHandler,
callHandler: callHandler,
_fetchQueue: _fetchQueue,
_handleMessageFromNative: _handleMessageFromNative
};
var doc = document;
_createQueueReadyIframe(doc);
_createQueueReadyIframe4biz(doc);
var readyEvent = doc.createEvent('Events');
readyEvent.initEvent('WebViewJavascriptBridgeReady');
readyEvent.bridge = WebViewJavascriptBridge;
doc.dispatchEvent(readyEvent);
})();
... ...
//notation: js file can only use this kind of comments
//since comments will cause error when use in webview.loadurl,
//comments will be remove by java use regexp
(function() {
if (window.WebViewJavascriptBridge) {
return;
}
var messagingIframe;
var bizMessagingIframe;
var sendMessageQueue = [];
var receiveMessageQueue = [];
var messageHandlers = {};
var CUSTOM_PROTOCOL_SCHEME = 'yy';
var QUEUE_HAS_MESSAGE = '__QUEUE_MESSAGE__/';
var responseCallbacks = {};
var uniqueId = 1;
// 创建消息index队列iframe
function _createQueueReadyIframe(doc) {
messagingIframe = doc.createElement('iframe');
messagingIframe.style.display = 'none';
doc.documentElement.appendChild(messagingIframe);
}
//创建消息体队列iframe
function _createQueueReadyIframe4biz(doc) {
bizMessagingIframe = doc.createElement('iframe');
bizMessagingIframe.style.display = 'none';
doc.documentElement.appendChild(bizMessagingIframe);
}
//set default messageHandler 初始化默认的消息线程
function init(messageHandler) {
if (WebViewJavascriptBridge._messageHandler) {
throw new Error('WebViewJavascriptBridge.init called twice');
}
WebViewJavascriptBridge._messageHandler = messageHandler;
var receivedMessages = receiveMessageQueue;
receiveMessageQueue = null;
for (var i = 0; i < receivedMessages.length; i++) {
_dispatchMessageFromNative(receivedMessages[i]);
}
}
// 发送
function send(data, responseCallback) {
_doSend({
data: data
}, responseCallback);
}
// 注册线程 往数组里面添加值
function registerHandler(handlerName, handler) {
messageHandlers[handlerName] = handler;
}
// 调用线程
function callHandler(handlerName, data, responseCallback) {
_doSend({
handlerName: handlerName,
data: data
}, responseCallback);
}
//sendMessage add message, 触发native处理 sendMessage
function _doSend(message, responseCallback) {
if (responseCallback) {
var callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime();
responseCallbacks[callbackId] = responseCallback;
message.callbackId = callbackId;
}
sendMessageQueue.push(message);
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE;
}
// 提供给native调用,该函数作用:获取sendMessageQueue返回给native,由于android不能直接获取返回的内容,所以使用url shouldOverrideUrlLoading 的方式返回内容
function _fetchQueue() {
var messageQueueString = JSON.stringify(sendMessageQueue);
sendMessageQueue = [];
//android can't read directly the return data, so we can reload iframe src to communicate with java
if (messageQueueString !== '[]') {
bizMessagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://return/_fetchQueue/' + encodeURIComponent(messageQueueString);
}
}
//提供给native使用,
function _dispatchMessageFromNative(messageJSON) {
setTimeout(function() {
var message = JSON.parse(messageJSON);
var responseCallback;
//java call finished, now need to call js callback function
if (message.responseId) {
responseCallback = responseCallbacks[message.responseId];
if (!responseCallback) {
return;
}
responseCallback(message.responseData);
delete responseCallbacks[message.responseId];
} else {
//直接发送
if (message.callbackId) {
var callbackResponseId = message.callbackId;
responseCallback = function(responseData) {
_doSend({
responseId: callbackResponseId,
responseData: responseData
});
};
}
var handler = WebViewJavascriptBridge._messageHandler;
if (message.handlerName) {
handler = messageHandlers[message.handlerName];
}
//查找指定handler
try {
handler(message.data, responseCallback);
} catch (exception) {
if (typeof console != 'undefined') {
console.log("WebViewJavascriptBridge: WARNING: javascript handler threw.", message, exception);
}
}
}
});
}
//提供给native调用,receiveMessageQueue 在会在页面加载完后赋值为null,所以
function _handleMessageFromNative(messageJSON) {
//console.log(messageJSON);
if (receiveMessageQueue) {
receiveMessageQueue.push(messageJSON);
}
_dispatchMessageFromNative(messageJSON);
}
var WebViewJavascriptBridge = window.WebViewJavascriptBridge = {
init: init,
send: send,
registerHandler: registerHandler,
callHandler: callHandler,
_fetchQueue: _fetchQueue,
_handleMessageFromNative: _handleMessageFromNative
};
var doc = document;
_createQueueReadyIframe(doc);
_createQueueReadyIframe4biz(doc);
var readyEvent = doc.createEvent('Events');
readyEvent.initEvent('WebViewJavascriptBridgeReady');
readyEvent.bridge = WebViewJavascriptBridge;
doc.dispatchEvent(readyEvent);
})();
... ...
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}
\ No newline at end of file
... ...
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest',() => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}
\ No newline at end of file
... ...
... ... @@ -13,3 +13,5 @@ export { BasicDataSource } from './src/main/ets/utils/BasicDataSource';
export { LazyDataSource } from './src/main/ets/utils/LazyDataSource'
export { BreakpointSystem, BreakPointType } from './src/main/ets/utils/BreakPointSystem';
export { ToastUtils } from './src/main/ets/utils/ToastUtils';
... ...
import common from '@ohos.app.ability.common';
import bundleManager from '@ohos.bundle.bundleManager';
import common from '@ohos.app.ability.common';
import { Logger } from './Logger';
const TAG: string = 'AppUtils';
... ... @@ -34,6 +35,7 @@ export class AppUtils {
let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT)
return bundleInfo?.versionName
} catch (e) {
Logger.warn(TAG, 'get app version error:' + e?.message);
}
return "";
}
... ... @@ -43,13 +45,13 @@ export class AppUtils {
* @returns 应用版本编码
*/
static getAppVersionCode(): string {
return "2600010700"
// try {
// let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT)
// return bundleInfo?.versionCode
// } catch (e) {
// Logger.warn(TAG, 'get app version error:' + e?.message);
// }
// return 0;
try {
let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT)
return bundleInfo?.versionCode + ""
} catch (e) {
Logger.warn(TAG, 'get app version error:' + e?.message);
}
return '';
}
}
... ...
import prompt from '@ohos.promptAction'
export class ToastUtils {
private static longToastTime: number = 3000
private static shortToastTime: number = 1000
static showToast(message: ResourceStr, duration: number) {
prompt.showToast({ message: message, duration: duration })
}
static shortToast(message: ResourceStr) {
ToastUtils.showToast(message, ToastUtils.shortToastTime)
}
static longToast(message: ResourceStr) {
ToastUtils.showToast(message, ToastUtils.longToastTime)
}
}
// export default new ToastUtils()
\ No newline at end of file
... ...
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test
\ No newline at end of file
... ...
... ... @@ -7,7 +7,7 @@
"main": "Index.ets",
"version": "1.0.0",
"dependencies": {
"@ohos/axios": "^2.1.1",
"wdKit": "file:../wdKit"
"wdKit": "file:../wdKit",
"@ohos/axios": "^2.1.1"
}
}
... ...
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test
\ No newline at end of file
... ...
export { WDRouterRule } from './src/main/ets/router/WDRouterRule'
export { WDRouterPage } from './src/main/ets/router/WDRouterPage'
export { registerRouter } from './src/main/ets/router/Action2Page'
\ No newline at end of file
... ...
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default"
}
]
}
\ No newline at end of file
... ...
import { hspTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: hspTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}
... ...
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope
\ No newline at end of file
... ...
{
"license": "Apache-2.0",
"devDependencies": {},
"author": "",
"name": "wdrouter",
"description": "Please describe the basic information.",
"main": "Index.ets",
"version": "1.0.0",
"dependencies": {
"wdKit": "file:../wdKit",
"wdBean": "file:../wdBean"
}
}
... ...
import { WDRouterPage } from './WDRouterPage'
import { Action } from 'wdBean'
import ArrayList from '@ohos.util.ArrayList';
interface HandleObject {
handle: (action: Action) => (WDRouterPage | undefined)
priority: number
}
export class Action2Page {
private static handles: Record<string, ArrayList<HandleObject>> = {};
static register(actionType: string, handle: (action: Action) => (WDRouterPage | undefined), priority: number = 0) {
let handles = Action2Page.handles[actionType] ?? new ArrayList();
let obj: HandleObject = {
handle: handle,
priority: priority
};
handles.add(obj);
handles.sort((f, s) => {
return f.priority - s.priority;
})
Action2Page.handles[actionType] = handles;
}
static get(action?: Action): WDRouterPage | undefined {
if (!action || !action.type) {
return undefined;
}
let handles = Action2Page.handles[action.type];
if (!handles) {
return undefined;
}
let page: WDRouterPage | undefined
for (let i = 0; i < handles.length; i++) {
let tmp = (handles[i] as HandleObject).handle(action);
if (tmp) {
page = tmp;
break
}
}
return page
}
}
export function registerRouter() {
// Action2Page.register("USER_LOGIN", (action: Action) => {
// return WDRouterPage.webLoginPage
// })
// Action2Page.register("JUMP_DETAIL_PAGE", (action) => {
// if (action.params?.pageID == "296ff8a4b07d457cb15b6f9e5f433cc0") {
// return WDRouterPage.tvLivePage
// }
// if (action.params?.detailPageType == 7 || action.params?.detailPageType == 8) {
// return WDRouterPage.shortVideoDetail
// }
// return WDRouterPage.playDetail
// })
Action2Page.register("JUMP_H5_BY_WEB_VIEW", (action) => {
return WDRouterPage.defaultWebPage
})
// Action2Page.register("JUMP_INNER_NEW_PAGE", (action) => {
// if (action.params?.pageID == "WORLDCUP_DETAIL") {
// return WDRouterPage.livependantpage
// }
// return undefined
// })
}
\ No newline at end of file
... ...
import bundleManager from '@ohos.bundle.bundleManager'
export class WDRouterPage {
private moduleName: string
private pagePath: string
constructor(moduleName: string, pagePath: string) {
this.moduleName = moduleName
this.pagePath = pagePath
}
url() {
let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT)
return `@bundle:${bundleInfo.name}/${this.moduleName}/${this.pagePath}`
}
// 主页
static index = new WDRouterPage("entry", "ets/pages/Index");
// 关于页面
// static aboutPage = new WDRouterPage("entry", "ets/pages/about/AboutPage");
// web默认页面
static defaultWebPage = new WDRouterPage("entry", "ets/pages/web/DefaultWebPage");
}
... ...
import router from '@ohos.router'
import { Action } from 'wdBean'
import { ToastUtils } from 'wdKit'
import { Action2Page } from './Action2Page'
import { WDRouterPage } from './WDRouterPage'
export class WDRouterRule {
static jumpWithAction(action?: Action) {
if (!action || !action.type) {
ToastUtils.showToast("跳转参数异常", 1000);
return
}
let page = Action2Page.get(action);
WDRouterRule.jumpWithPage(page, action)
}
private static jumpWithPage(page?: WDRouterPage, params?: object) {
if (page) {
if (params) {
// router.pushUrl({ url: 'pages/routerpage2', , params: params })
router.pushUrl({ url: page.url(), params: params })
} else {
router.pushUrl({ url: page.url() })
}
} else {
ToastUtils.showToast("功能开发中", 1000);
}
}
}
\ No newline at end of file
... ...
{
"module": {
"name": "wdRouter",
"type": "shared",
"description": "$string:shared_desc",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true
}
}
\ No newline at end of file
... ...
{
"color": [
{
"name": "white",
"value": "#FFFFFF"
}
]
}
\ No newline at end of file
... ...
{
"string": [
{
"name": "shared_desc",
"value": "description"
}
]
}
\ No newline at end of file
... ...
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}
\ No newline at end of file
... ...
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest',() => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}
\ No newline at end of file
... ...
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test
\ No newline at end of file
... ...
export { WdWebComponent } from './src/main/ets/pages/WdWebComponent'
\ No newline at end of file
... ...
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default"
}
]
}
\ No newline at end of file
... ...
import { hspTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: hspTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}
... ...
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope
\ No newline at end of file
... ...
{
"license": "Apache-2.0",
"devDependencies": {},
"author": "",
"name": "wdwebcomponent",
"description": "Please describe the basic information.",
"main": "Index.ets",
"version": "1.0.0",
"dependencies": {
"wdConstant": "file:../wdConstant",
"wdKit": "file:../wdKit",
"wdJsBridge": "file:../wdJsBridge",
"wdBean": "file:../wdBean",
"wdRouter": "file:../wdRouter"
}
}
... ...
import { Action } from 'wdBean';
import { Callback } from 'wdJsBridge';
import { Logger, StringUtils, } from 'wdKit';
// import { AccountManagerUtils, ILoginService, Logger, ServiceManager, StringUtils, UserBean, UserInfo } from 'wdKit';
import { WDRouterPage, WDRouterRule } from 'wdRouter';
// import { wdMenc } from 'wdMenc';
/**
* h5调用native代码
* @param data
* @param call
*/
export function performJSCallNative(data: Action, call: Callback) {
// if (data.name == "GET_PROMOTION_SIGN") {
// wdMenc.getActivitySign(data.params?.intfId, (sign) => {
// if (sign) {
// call(JSON.stringify(sign));
// } else {
// call("")
// }
// })
// return
// }
//TODO 数据校验
switch (data.type) {
//获取用户信息
case "GET_USER_INFO":
//测试环境
// call(JSON.stringify(getTestUserBean()))
// let isLogin = AccountManagerUtils.isLoginSync()
// Logger.info("WebComponent", `GET_USER_INFO#:::refresh==` + isLogin);
//
// if (isLogin) {
// const loginService = ServiceManager.getService(ILoginService.name) as ILoginService.Service
// let userBean: UserBean = loginService.getUserBean()
// // userBean.userInfo = JSON.stringify(loginService.getUserInfo())
// call(JSON.stringify(userBean))
// } else {
// call("fail")
// }
break;
case "JUMP_DETAIL_PAGE":
WDRouterRule.jumpWithAction(data)
break;
case "JUMP_INNER_NEW_PAGE":
WDRouterRule.jumpWithAction(data)
break
case "GET_DEVICE_DATA":
break
//用户登陆
case "USER_LOGIN":
WDRouterRule.jumpWithAction(data)
//支付完成回调
case "REGISTER_H5_WEBVIEW_CREATE_ORDER_RESULT":
break
//打开H5页面
case "JUMP_H5_BY_WEB_VIEW":
WDRouterRule.jumpWithAction(data)
break
case "USER_LOGOUT":
// const loginService = ServiceManager.getService(ILoginService.name) as ILoginService.Service
// loginService.logout()
break
default:
call("this is def value")
}
}
// /**
// *
// * @returns 模拟测试环境的user信息
// */
// function getTestUserBean(): UserBean {
// const loginService = ServiceManager.getService(ILoginService.name) as ILoginService.Service
// //正是环境
// let userBean: UserBean = loginService.getUserBean()
// userBean.userId = "930855275"
// userBean.userToken = "nlps6FADECE38F5AAD2116F2"
// // userBean.clientId = "f1bf515c-4006-4606-a752-2b4cdd9343d0"
// // userBean.carrierCode = "CM"
// userBean.mobile = "NTTrcDO4ADN1cTM5MTM"
// userBean.uname = '139****0887'
// userBean.picture = "http://36.155.98.104:23380/publish/voms2/uic_service/picture/userImage/543/626/5181.jpg"
// // userBean.ssotoken = "STnid0000011700463753943SKPUlfNxEDJsrauGjCwUldiDfrd0mUuM"
// // userBean.clientProvinceCode = "210"
// // userBean.clientCityId = "0210"
// // userBean.sign = "617DAC548595B7C9EBB13043735F1BE0"
// // userBean.blurMobile = "177****9217"
// let userinfo: UserInfo = ({
// userId: "930855275",
// userNum: "NzDrsyN4gDM0UzNxkzMxYDO",
// mobile: "NTTrcDO4ADN1cTM5MTM",
// areaId: "210",
// cityId: "0210",
// carrierCode: "CM",
// passId: "602201990200225921",
// userToken: "nlps6FADECE38F5AAD2116F2",
// expiredOn: "1705647754000",
// blurMobile: "139****0887",
// encrypted: true
// })
// // userBean.userInfo = JSON.stringify(userinfo);
// return userBean
// }
//
// /**
// *
// * @returns 用户信息
// */
// function getUserBean(): UserBean {
// const loginService = ServiceManager.getService(ILoginService.name) as ILoginService.Service
// //正是环境
// let userBean: UserBean = loginService.getUserBean()
// userBean.userId = "1437725487"
// userBean.userToken = "nlps08468E117C554CA08A43"
// // userBean.clientId = "27fb3129-5a54-45bc-8af1-7dc8f1155501"
// // userBean.carrierCode = "CT"
// userBean.mobile = "OTTrcTMykTO4ATM3cTM"
// userBean.uname = '小可爱啊'
// userBean.picture = "http://img.cmvideo.cn:8080/publish/voms2/uic_service/picture/userImage/1437/725/487/20211224174128beax.png"
// // userBean.ssotoken = "STnid0000011700461738301N5rjsHdbvyzMpyzwvHrFRJsj7oNT1Juf"
// // userBean.clientProvinceCode = "100"
// // userBean.clientCityId = "0100"
// // userBean.sign = "4ABFB8442EE914B57CCD9F1DE587D96D"
// // userBean.blurMobile = "177****9217"
// let userinfo: UserInfo = ({
// userId: "1437725487",
// userNum: "MzDrsyNxITO5gDMxczNxYDO",
// mobile: "OTTrcTMykTO4ATM3cTM",
// areaId: "100",
// cityId: "0100",
// carrierCode: "CT",
// passId: "467464726359024540",
// userToken: "nlps08468E117C554CA08A43",
// expiredOn: "1705645738000",
// blurMobile: "177****9217",
// encrypted: true
// })
// // userBean.userInfo = JSON.stringify(userinfo);
// return userBean
// }
... ...
import router from '@ohos.router';
import { Action } from 'wdBean';
import { ConfigConstants } from 'wdConstant';
import { Logger } from 'wdKit';
import { BridgeHandler, BridgeUtil, BridgeWebViewControl, Callback } from 'wdJsBridge';
import { performJSCallNative } from './JsBridgeBiz';
import { setDefaultNativeWebSettings } from './WebComponentUtil';
const TAG = 'WdWebComponent';
@Component
export struct WdWebComponent {
private webviewControl: BridgeWebViewControl = new BridgeWebViewControl()
//TODO 默认网页
webUrl: string = ConfigConstants.DETAIL_URL
/**
* 对外暴露webview的回调,能力
*/
onPageBegin: (url?: string) => void = () => {
}
onPageEnd: (url?: string) => void = () => {
}
onLoadIntercept: (url?: string) => boolean = () => {
return false
}
onHttpErrorReceive: (url?: string) => boolean = () => {
return false
}
@Prop @Watch('onReloadStateChanged') reload: number = 0
/**
* 默认【CallNative】逻辑处理
*/
private defaultPerformJSCallNative: (data: Action, f: Callback) => void = (data: Action, f: Callback) => {
performJSCallNative(data, f)
}
/**
* jsBridge的处理
*/
handleInfo: [string, BridgeHandler][] = []
backVisibility: boolean = false
defaultRegisterHandler(): void {
this.webviewControl.registerHandler("CallNative", {
handle: (data: Action, f: Callback) => {
this.defaultPerformJSCallNative(data, f)
}
});
}
build() {
Column() {
Row() {
Image($r("app.media.ic_back"))
.width(44)
.padding(13)
.aspectRatio(1)
.onClick(() => {
router.back();
})
}.backgroundColor(Color.Black)
.width('100%')
.height(44)
.visibility(this.backVisibility ? Visibility.Visible : Visibility.None)
Web({ src: this.webUrl, controller: this.webviewControl })
.domStorageAccess(true)
.databaseAccess(true)
.javaScriptAccess(true)
.onHttpErrorReceive((event) => {
//TODO 页面加载不成功的时候处理
Logger.info(TAG, 'onHttpErrorReceive event.request.getRequestUrl:' + event?.request.getRequestUrl());
Logger.info(TAG, 'onHttpErrorReceive event.response.getResponseCode:' + event?.response.getResponseCode());
})
.onPageEnd((event) => {
this.onPageEnd(event?.url)
})
.onPageBegin((event) => {
setDefaultNativeWebSettings(this.webviewControl, this.webUrl).then(()=>{
this.handleInfo && this.handleInfo.length > 1 ? this.handleInfo.forEach(value => {
this.webviewControl.registerHandler(value[0], value[1])
}) : this.defaultRegisterHandler()
setTimeout(()=>{
BridgeUtil.webViewLoadLocalJs(getContext(this), this.webviewControl)
},500)
})
this.onPageBegin(event?.url)
})
.onLoadIntercept((event) => {
let url: string = event.data.getRequestUrl().toString()
url = url.replace("%(?![0-9a-fA-F]{2})", "%25")
.replace("\\+", "%2B");
url = decodeURIComponent(url)
if (url.startsWith(BridgeUtil.YY_RETURN_DATA)) {
this.webviewControl.handlerReturnData(url)
return true
}
if (url.startsWith(BridgeUtil.YY_OVERRIDE_SCHEMA)) {
this.webviewControl.flushMessageQueue()
return true
}
return this.onLoadIntercept(event.data.getRequestUrl().toString())
})
}
}
onReloadStateChanged() {
Logger.info(TAG, `onReloadStateChanged:::refresh, this.reload: ${this.reload}`);
if (this.reload > 0) {
this.webviewControl.refresh()
}
}
}
... ...
import bundleManager from '@ohos.bundle.bundleManager';
import web_webview from '@ohos.web.webview';
import HashMap from '@ohos.util.HashMap';
import { StringUtils, AppUtils } from 'wdKit';
/**
* 用于底层webview基础设置:ua,cookie等
*/
export function setDefaultNativeWebSettings(control: WebviewController, url: string): Promise<void> {
//设置UA
let customUA = control.getCustomUserAgent();
return new Promise((resolve) => {
let versionName = AppUtils.getAppVersionName();
let versionCode = AppUtils.getAppVersionCode();
//TODO 设置cookie有问题
if(customUA.indexOf('miguvideo')===-1){
let temp = customUA + " Migu/miguvideo/" + versionName + "(" + versionCode + ")"
control.setCustomUserAgent(temp)
}else{
control.setCustomUserAgent(customUA)
}
//设置Cookie
try{
syncCookies(url, getBaseCookie())
web_webview.WebCookieManager.setCookie(url, "AppVersion=" + versionCode)
}catch(e){
}
resolve();
});
}
function setCookie(url: string, value: string) {
if (StringUtils.isEmpty(value) || StringUtils.isEmpty(url) || !value.includes("=")) {
return
}
web_webview.WebCookieManager.setCookie(url, value)
}
function getBaseCookie(): HashMap<string, string> {
let cookies: HashMap<string, string> = new HashMap<string, string>()
cookies.set("SupportAPI", "H5_CALL_NATIVE_HTTP_REQUEST")
cookies.set("PlatForm", "harmony")
return cookies
}
function syncCookies(url: string, map: HashMap<String, String>) {
if (map == undefined && StringUtils.isEmpty(url)) {
return
}
map.forEach((value, key) => {
setCookie(url, `${key}=${value}`)
})
}
\ No newline at end of file
... ...
{
"module": {
"name": "wdWebComponent",
"type": "shared",
"description": "$string:shared_desc",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true
}
}
\ No newline at end of file
... ...
{
"color": [
{
"name": "white",
"value": "#FFFFFF"
}
]
}
\ No newline at end of file
... ...
{
"string": [
{
"name": "shared_desc",
"value": "description"
}
]
}
\ No newline at end of file
... ...
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}
\ No newline at end of file
... ...
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest',() => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}
\ No newline at end of file
... ...