<

{{title}}

{{file.summary.functions.pct}}%

Functions
{{file.summary.functions.covered}}/{{file.summary.functions.total}}

{{file.summary.branches.pct}}%

Branches
{{file.summary.branches.covered}}/{{file.summary.branches.total}}

{{file.summary.lines.pct}}%

Lines
{{file.summary.lines.covered}}/{{file.summary.lines.total}}
          
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                
import promptAction from '@ohos.promptAction'; 
import window from '@ohos.window'; 
import common from '@ohos.app.ability.common'; 
import { ComponentContent } from '@ohos.arkui.node'; 
 
/** 弹窗交互结果。 */ 
interface DialogResult { 
  index: number; 
} 
 
/** `prompt` 弹窗参数。 */ 
class PromptDialogParams { 
  public message: string = ''; 
  public defaultValue: string = ''; 
  public inputValue: string = ''; 
  public onConfirm: (value: string) => void = (_v: string): void => {}; 
  public onCancel: () => void = (): void => {}; 
 
  constructor( 
    message: string, 
    defaultValue: string, 
    onConfirm: (value: string) => void, 
    onCancel: () => void 
  ) { 
    this.message = message; 
    this.defaultValue = defaultValue; 
    this.inputValue = defaultValue; 
    this.onConfirm = onConfirm; 
    this.onCancel = onCancel; 
  } 
} 
 
@Builder 
function buildPromptDialog(params: PromptDialogParams): void { 
  Column() { 
    Text('提示') 
      .fontSize(18) 
      .fontWeight(FontWeight.Bold) 
      .fontColor('#000000') 
      .width('100%') 
      .textAlign(TextAlign.Start) 
      .margin({ bottom: 12 }); 
 
    Text(params.message) 
      .fontSize(14) 
      .fontColor('#333333') 
      .width('100%') 
      .textAlign(TextAlign.Start) 
      .margin({ bottom: 12 }); 
 
    TextInput({ text: params.defaultValue, placeholder: '请输入' }) 
      .width('100%') 
      .height(40) 
      .fontSize(14) 
      .fontColor('#222222') 
      .placeholderColor('#999999') 
      .caretColor('#1989FA') 
      .backgroundColor('#F5F5F5') 
      .borderRadius(6) 
      .padding({ left: 12, right: 12 }) 
      .margin({ bottom: 16 }) 
      .onChange((value: string): void => { 
        params.inputValue = value; 
      }); 
 
    Row() { 
      Button('取消') 
        .type(ButtonType.Normal) 
        .backgroundColor(Color.Transparent) 
        .fontColor('#999999') 
        .layoutWeight(1) 
        .height(44) 
        .onClick((): void => { 
          params.onCancel(); 
        }); 
 
      Divider() 
        .vertical(true) 
        .height(20) 
        .color('#E5E5E5'); 
 
      Button('确定') 
        .type(ButtonType.Normal) 
        .backgroundColor(Color.Transparent) 
        .fontColor('#000000') 
        .fontWeight(FontWeight.Medium) 
        .layoutWeight(1) 
        .height(44) 
        .onClick((): void => { 
          params.onConfirm(params.inputValue); 
        }); 
    } 
    .width('100%') 
    .alignItems(VerticalAlign.Center); 
  } 
  .padding({ top: 20, left: 20, right: 20, bottom: 4 }) 
  .backgroundColor('#FFFFFF') 
  .borderRadius(14) 
  .width('80%'); 
} 
 
/** 
 * 处理 WebView 中 JS `alert` / `confirm` / `prompt` 弹窗。 
 */ 
export class JsDialogHandler { 
  /** 弹出 alert 对话框。 */ 
  public static async showAlert(context: common.UIAbilityContext, url: string, message: string): Promise<boolean> { 
    const safeMsg: string = message ?? ''; 
    try { 
      const uc: UIContext | null = await JsDialogHandler.getUIContext(context); 
      if (uc !== null) { 
        await uc.getPromptAction().showDialog({ 
          title: '提示', 
          message: safeMsg, 
          buttons: [{ text: '确定', color: '#1989FA' }] 
        }); 
      } else { 
        await promptAction.showDialog({ 
          title: '提示', 
          message: safeMsg, 
          buttons: [{ text: '确定', color: '#1989FA' }] 
        }); 
      } 
      return true; 
    } catch (_e) { 
      return false; 
    } 
  } 
 
  /** 弹出 confirm 对话框。 */ 
  public static async showConfirm(context: common.UIAbilityContext, url: string, message: string): Promise<boolean> { 
    const safeMsg: string = message ?? ''; 
    try { 
      const uc: UIContext | null = await JsDialogHandler.getUIContext(context); 
      let result: DialogResult; 
      if (uc !== null) { 
        result = await uc.getPromptAction().showDialog({ 
          title: '提示', 
          message: safeMsg, 
          buttons: [ 
            { text: '取消', color: '#999999' }, 
            { text: '确定', color: '#1989FA' } 
          ] 
        }) as DialogResult; 
      } else { 
        result = await promptAction.showDialog({ 
          title: '提示', 
          message: safeMsg, 
          buttons: [ 
            { text: '取消', color: '#999999' }, 
            { text: '确定', color: '#1989FA' } 
          ] 
        }) as DialogResult; 
      } 
      return result.index === 1; 
    } catch (_e) { 
      return false; 
    } 
  } 
 
  /** 弹出 prompt 对话框(含文本输入)。 */ 
  public static async showPrompt( 
    context: common.UIAbilityContext, 
    url: string, 
    message: string, 
    defaultValue: string 
  ): Promise<string | null> { 
    const safeMsg: string = message ?? ''; 
    const safeDefault: string = defaultValue ?? ''; 
 
    let uiCtx: UIContext | null = await JsDialogHandler.getUIContext(context); 
    if (uiCtx === null) { 
      return JsDialogHandler.showPromptFallback(safeMsg, safeDefault); 
    } 
 
    return new Promise<string | null>((resolve: (v: string | null) => void): void => { 
      const finalUiCtx: UIContext = uiCtx as UIContext; 
      let contentNode: ComponentContent<PromptDialogParams> | null = null; 
 
      const closeAndResolve = (value: string | null): void => { 
        try { 
          if (contentNode !== null) { 
            finalUiCtx.getPromptAction().closeCustomDialog(contentNode); 
          } 
        } catch (_e) { 
          // ignore 
        } 
        resolve(value); 
      }; 
 
      const params: PromptDialogParams = new PromptDialogParams( 
        safeMsg, 
        safeDefault, 
        (value: string): void => { closeAndResolve(value); }, 
        (): void => { closeAndResolve(null); } 
      ); 
 
      try { 
        contentNode = new ComponentContent<PromptDialogParams>( 
          finalUiCtx, 
          wrapBuilder<[PromptDialogParams]>(buildPromptDialog), 
          params 
        ); 
        finalUiCtx.getPromptAction().openCustomDialog(contentNode, { 
          alignment: DialogAlignment.Center, 
          autoCancel: false, 
          maskColor: '#80000000' 
        }).catch((_e: Object): void => { resolve(null); }); 
      } catch (_e) { 
        resolve(null); 
      } 
    }); 
  } 
 
  /** prompt 对话框的简化实现(不含自定义输入控件)。 */ 
  private static async showPromptFallback(message: string, defaultValue: string): Promise<string | null> { 
    const composedMessage: string = message 
      + (defaultValue.length > 0 ? ('\n\n默认值: ' + defaultValue) : ''); 
    try { 
      const result = await promptAction.showDialog({ 
        title: '提示', 
        message: composedMessage, 
        buttons: [ 
          { text: '取消', color: '#999999' }, 
          { text: '确定', color: '#1989FA' } 
        ] 
      }) as DialogResult; 
      return result.index === 1 ? defaultValue : null; 
    } catch (_e) { 
      return null; 
    } 
  } 
 
  /** 获取当前窗口的 UIContext。 */ 
  private static async getUIContext(context: common.UIAbilityContext): Promise<UIContext | null> { 
    try { 
      const win: window.Window = await window.getLastWindow(context); 
      return win.getUIContext(); 
    } catch (_e) { 
      return null; 
    } 
  } 
 
  private constructor() {} 
} 

              
Code coverage generated by bjc at {{date}}