# AIFF Capacitor WebView 插件

一个功能强大的 Capacitor 插件，用于在移动应用和 Web 应用中打开 WebView 窗口，特别优化了与 AIFF (Aile Frontend Framework) 的集成。

[![CI](https://github.com/zhucl1006/capacitor-aiff/actions/workflows/ci.yml/badge.svg)](https://github.com/zhucl1006/capacitor-aiff/actions/workflows/ci.yml)
[![npm version](https://badge.fury.io/js/aile-capacitor-aiff.svg)](https://badge.fury.io/js/aile-capacitor-aiff)

## 特性

- 🚀 **跨平台支持**: 支持 iOS、Android 和 Web 平台
- 🔗 **AIFF 框架集成**: 专为 Aile Frontend Framework 优化
- 📱 **原生体验**: 在移动设备上提供原生 WebView 体验
- 🎨 **可定制化**: 支持多种主题、工具栏类型和样式
- 🔒 **安全通信**: 安全的 JavaScript 消息传递机制
- 🧪 **完整测试**: 包含单元测试、集成测试和 E2E 测试
- 📖 **详细文档**: 完整的 API 文档和示例代码

## 安装

```bash
npm install aile-capacitor-aiff
```

### iOS 平台

```bash
npx cap sync ios
```

### Android 平台

```bash
npx cap sync android
```

## 快速开始

### 基本用法

```typescript
import { AiffWebView } from 'aile-capacitor-aiff';

// 打开 WebView
await AiffWebView.openWebView({
  url: 'https://example.com',
  title: '示例页面',
  toolbarType: 'navigation'
});

// 关闭 WebView
await AiffWebView.closeWebView();
```

### AIFF 框架集成

```typescript
// 打开包含 AIFF 框架的页面
await AiffWebView.openWebView({
  url: 'https://your-aiff-app.com',
  title: 'AIFF 应用',
  toolbarType: 'activity'
});

// 监听来自 AIFF 框架的消息
AiffWebView.addListener('messageFromWebview', (data) => {
  console.log('收到 AIFF 消息:', data);
});

// 向 AIFF 框架发送消息
await AiffWebView.postMessage({
  detail: {
    type: 'aiff-event',
    data: { action: 'update-data' }
  }
});
```

## API 参考

### openWebView(options)

打开一个新的 WebView 窗口。

**参数：**

```typescript
interface WebViewOptions {
  url: string;                    // 要打开的 URL
  title?: string;                 // 页面标题
  toolbarType?: ToolBarType;      // 工具栏类型
  showReloadButton?: boolean;     // 显示刷新按钮
  headers?: Record<string, string>; // 自定义请求头
  toolbarColor?: string;          // 工具栏颜色
  theme?: 'light' | 'dark' | 'auto'; // 主题
  closeModal?: boolean;           // 点击外部关闭
}
```

**示例：**

```typescript
// 基础用法
await AiffWebView.openWebView({ url: 'https://example.com' });

// 完整配置
await AiffWebView.openWebView({
  url: 'https://api.example.com/dashboard',
  title: '管理面板',
  toolbarType: 'navigation',
  showReloadButton: true,
  headers: {
    'Authorization': 'Bearer your-token-here',
    'X-API-Key': 'your-api-key'
  },
  toolbarColor: '#007bff',
  theme: 'dark',
  closeModal: true
});
```

### closeWebView()

关闭当前打开的 WebView。

```typescript
await AiffWebView.closeWebView();
```

### executeScript(options)

在 WebView 中执行 JavaScript 代码。

```typescript
await AiffWebView.executeScript({
  code: 'document.body.style.backgroundColor = "lightblue";'
});
```

### postMessage(options)

向 WebView 发送消息。

```typescript
await AiffWebView.postMessage({
  detail: {
    type: 'notification',
    data: { message: 'Hello from native app!' }
  }
});
```

### setUrl(options)

更改当前 WebView 的 URL。

```typescript
await AiffWebView.setUrl({ url: 'https://new-url.com' });
```

### reload()

重新加载当前页面。

```typescript
await AiffWebView.reload();
```

### addListener(eventName, callback)

添加事件监听器。

```typescript
// 监听页面加载完成
AiffWebView.addListener('pageLoaded', (data) => {
  console.log('页面加载完成:', data);
});

// 监听 URL 变化
AiffWebView.addListener('urlChangeEvent', (data) => {
  console.log('URL 变化:', data.url);
});

// 监听来自 WebView 的消息
AiffWebView.addListener('messageFromWebview', (data) => {
  console.log('收到消息:', data);
});

// 监听关闭事件
AiffWebView.addListener('closeEvent', () => {
  console.log('WebView 已关闭');
});
```

## AIFF 框架集成

### JavaScript 注入

插件会自动在 WebView 中注入以下对象，供 AIFF 框架使用：

#### window.mobileApp

```javascript
// 在 AIFF 应用中使用
window.mobileApp.postMessage(JSON.stringify({
  type: 'user-action',
  data: { action: 'login', userId: 123 }
}));

// 监听原生消息
window.mobileApp.onMessage = function(message) {
  const data = JSON.parse(message);
  console.log('收到原生消息:', data);
};
```

#### postMessageToJS

```javascript
// 向原生应用发送消息
postMessageToJS({
  type: 'aiff-event',
  data: { 
    action: 'update-title',
    title: '新标题'
  }
});
```

### 消息格式

#### 从 WebView 到原生应用

```javascript
window.mobileApp.postMessage(JSON.stringify({
  type: 'event-type',
  data: {
    // 事件数据
  }
}));
```

#### 从原生应用到 WebView

```javascript
// 使用 postMessage
await AiffWebView.postMessage({
  detail: {
    type: 'native-event',
    data: { /* 数据 */ }
  }
});

// 使用 executeScript
await AiffWebView.executeScript({
  code: `
    if (window.aiffApp) {
      window.aiffApp.handleNativeMessage(${JSON.stringify(data)});
    }
  `
});
```

## 配置选项

### ToolBarType

```typescript
enum ToolBarType {
  DEFAULT = 'default',      // 默认工具栏
  NAVIGATION = 'navigation', // 导航工具栏（前进、后退、刷新）
  ACTIVITY = 'activity',    // 活动工具栏（标题、关闭按钮）
  BLANK = 'blank'          // 无工具栏
}
```

### 主题选项

- `light`: 浅色主题
- `dark`: 深色主题  
- `auto`: 自动跟随系统主题

## 平台特定说明

### iOS

- 使用 WKWebView 实现
- 支持 iOS 11.0+
- 需要在 Info.plist 中配置相关权限

### Android

- 使用 WebView 实现
- 支持 Android API 21+
- 需要在 AndroidManifest.xml 中配置相关权限

### Web

- 使用 iframe 模拟 WebView 行为
- 支持所有现代浏览器
- 提供与原生平台一致的 API

## 示例应用

查看 `example/` 目录获取完整的示例应用代码。

### React 示例

```typescript
import React, { useEffect } from 'react';
import { AiffWebView } from 'aile-capacitor-aiff';

const WebViewExample: React.FC = () => {
  const openDashboard = async () => {
    await AiffWebView.openWebView({
      url: 'https://dashboard.example.com',
      title: '管理面板',
      toolbarType: 'navigation'
    });
  };

  useEffect(() => {
    // 监听来自 AIFF 框架的消息
    const listener = AiffWebView.addListener('messageFromWebview', (data) => {
      if (data.type === 'login-success') {
        console.log('用户登录成功:', data.user);
      }
    });

    return () => {
      listener.remove();
    };
  }, []);

  return (
    <div>
      <button onClick={openDashboard}>打开管理面板</button>
    </div>
  );
};
```

### Vue 示例

```vue
<template>
  <div>
    <button @click="openWebView">打开 WebView</button>
    <div v-if="messages.length">
      <h3>收到的消息:</h3>
      <ul>
        <li v-for="msg in messages" :key="msg.id">{{ msg.text }}</li>
      </ul>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { AiffWebView } from 'aile-capacitor-aiff';

const messages = ref([]);
let listener: any = null;

const openWebView = async () => {
  await AiffWebView.openWebView({
    url: 'https://your-aiff-app.com',
    title: 'AIFF 应用'
  });
};

onMounted(() => {
  listener = AiffWebView.addListener('messageFromWebview', (data) => {
    messages.value.push({
      id: Date.now(),
      text: JSON.stringify(data)
    });
  });
});

onUnmounted(() => {
  if (listener) {
    listener.remove();
  }
});
</script>
```

## 开发

### 环境要求

- Node.js 16+
- npm 或 yarn
- Capacitor 6+

### 本地开发

```bash
# 克隆项目
git clone https://github.com/your-org/aile-capacitor-aiff.git
cd aile-capacitor-aiff

# 安装依赖
npm install

# 运行测试
npm run test
npm run test:e2e

# 构建项目
npm run build
```

### 测试

```bash
# 运行所有测试
npm test

# 运行单元测试
npm run test:unit

# 运行集成测试
npm run test:integration

# 运行 E2E 测试
npm run test:e2e

# 运行特定平台测试
npm run test:ios
npm run test:android
npm run test:web
```

## 贡献

欢迎提交 Issue 和 Pull Request！

### 开发流程

1. Fork 项目
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
3. 提交更改 (`git commit -m 'Add amazing feature'`)
4. 推送到分支 (`git push origin feature/amazing-feature`)
5. 创建 Pull Request

## 许可证

MIT License - 查看 [LICENSE](LICENSE) 文件了解详情。

## 支持

- 📧 邮箱: leo.zhu@chainsea.ai
- 💬 讨论区: [GitHub Discussions](https://github.com/your-org/aile-capacitor-aiff/discussions)
- 🐛 Bug 报告: [GitHub Issues](https://github.com/your-org/aile-capacitor-aiff/issues)

## 更新日志

查看 [CHANGELOG.md](CHANGELOG.md) 了解版本更新详情。