Skip to content

Commit 48a604f

Browse files
authored
refactor: huaweicloud logic (#192)
* refactor: huaweicloud logic * refactor: ua first
1 parent aee8248 commit 48a604f

5 files changed

Lines changed: 239 additions & 79 deletions

File tree

apps/extension/src/background.js

Lines changed: 121 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ async function handleMessage(request, sender) {
180180
} else if (request.platform === 'alipayopen' && request.userInfo) {
181181
await chrome.storage.local.set({ alipayopen_user: request.userInfo })
182182
console.log('[COSE] 支付宝用户信息已缓存:', request.userInfo.username)
183+
} else if (request.platform === 'huaweicloud' && request.userInfo) {
184+
await chrome.storage.local.set({ huaweicloud_user: request.userInfo })
185+
console.log('[COSE] 华为云用户信息已缓存:', request.userInfo.username)
183186
}
184187
return { success: true }
185188
default:
@@ -1771,13 +1774,10 @@ async function syncToPlatform(platformId, content) {
17711774
const switchResult = await chrome.scripting.executeScript({
17721775
target: { tabId: tab.id },
17731776
func: () => {
1774-
// 检查当前是否已经是 Markdown 编辑器
17751777
if (window.tinymceModal?.currentEditorType === 'markdown') {
17761778
console.log('[COSE] 华为云已经是 Markdown 编辑器')
17771779
return { alreadyMarkdown: true }
17781780
}
1779-
1780-
// 查找 "Markdown格式编辑" 标签并点击
17811781
const allElements = document.querySelectorAll('*')
17821782
for (const el of allElements) {
17831783
if (el.textContent === 'Markdown格式编辑' && el.children.length === 0) {
@@ -1793,14 +1793,10 @@ async function syncToPlatform(platformId, content) {
17931793

17941794
// 如果点击了切换按钮,需要等待确认对话框并点击确定
17951795
if (switchResult[0]?.result?.clicked) {
1796-
// 等待确认对话框出现
17971796
await new Promise(resolve => setTimeout(resolve, 500))
1798-
1799-
// 点击确认对话框的"确定"按钮
18001797
await chrome.scripting.executeScript({
18011798
target: { tabId: tab.id },
18021799
func: () => {
1803-
// 查找确认对话框中的"确定"按钮
18041800
const allElements = document.querySelectorAll('*')
18051801
for (const el of allElements) {
18061802
if (el.textContent === '确定' && el.children.length === 0) {
@@ -1813,16 +1809,14 @@ async function syncToPlatform(platformId, content) {
18131809
},
18141810
world: 'MAIN',
18151811
})
1816-
18171812
// 等待编辑器切换完成
18181813
await new Promise(resolve => setTimeout(resolve, 3000))
18191814
}
18201815

1821-
// 填充标题和内容
1822-
const fillResult = await chrome.scripting.executeScript({
1816+
// 填充标题
1817+
await chrome.scripting.executeScript({
18231818
target: { tabId: tab.id },
1824-
func: (title, markdown) => {
1825-
// 填充标题
1819+
func: (title) => {
18261820
const titleInput = document.querySelector('input[placeholder*="标题"]')
18271821
if (titleInput && title) {
18281822
titleInput.focus()
@@ -1831,18 +1825,125 @@ async function syncToPlatform(platformId, content) {
18311825
titleInput.dispatchEvent(new Event('change', { bubbles: true }))
18321826
console.log('[COSE] 华为云开发者博客标题填充成功')
18331827
}
1828+
},
1829+
args: [content.title],
1830+
world: 'MAIN',
1831+
})
1832+
1833+
// 等待 Markdown 编辑器 iframe 完全就绪,然后填充内容
1834+
// 使用 MutationObserver 监听 iframe 出现,message 事件监听内容确认
1835+
const fillResult = await chrome.scripting.executeScript({
1836+
target: { tabId: tab.id },
1837+
func: async (markdown) => {
1838+
// 工具函数:使用 MutationObserver 等待 iframe 元素出现并加载
1839+
const waitForEditorReady = (timeout = 15000) => {
1840+
return new Promise((resolve) => {
1841+
const check = () => {
1842+
const editor = window.tinymceModal?.currentEditor
1843+
if (editor && typeof editor.setContent === 'function') {
1844+
const iframe = document.getElementById(editor.editor_id)
1845+
if (iframe && iframe.contentWindow) {
1846+
return { editor, iframe }
1847+
}
1848+
}
1849+
return null
1850+
}
1851+
1852+
// 先立即检查一次
1853+
const immediate = check()
1854+
if (immediate) return resolve(immediate)
1855+
1856+
// 使用 MutationObserver 监听 DOM 变化(iframe 插入)
1857+
let resolved = false
1858+
const observer = new MutationObserver(() => {
1859+
if (resolved) return
1860+
const result = check()
1861+
if (result) {
1862+
resolved = true
1863+
observer.disconnect()
1864+
resolve(result)
1865+
}
1866+
})
1867+
observer.observe(document.body, { childList: true, subtree: true })
1868+
1869+
// 超时兜底
1870+
setTimeout(() => {
1871+
if (!resolved) {
1872+
resolved = true
1873+
observer.disconnect()
1874+
resolve(null)
1875+
}
1876+
}, timeout)
1877+
})
1878+
}
1879+
1880+
// 工具函数:使用 message 事件监听 setContent 确认(setMdDataSucc)
1881+
const setContentWithConfirm = (editor, iframe, content, timeout = 3000) => {
1882+
return new Promise((resolve) => {
1883+
let resolved = false
1884+
1885+
const onMessage = (event) => {
1886+
try {
1887+
const data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data
1888+
if (data.mdEventAction === 'setMdDataSucc' || data.mdEventAction === 'mdContent') {
1889+
if (!resolved) {
1890+
resolved = true
1891+
window.removeEventListener('message', onMessage)
1892+
resolve({ confirmed: true })
1893+
}
1894+
}
1895+
} catch (e) { /* 忽略非 JSON 消息 */ }
1896+
}
1897+
1898+
window.addEventListener('message', onMessage)
1899+
editor.setContent(content)
1900+
1901+
// 超时兜底
1902+
setTimeout(() => {
1903+
if (!resolved) {
1904+
resolved = true
1905+
window.removeEventListener('message', onMessage)
1906+
resolve({ confirmed: false })
1907+
}
1908+
}, timeout)
1909+
})
1910+
}
18341911

1835-
// 使用 tinymceModal.currentEditor.setContent() 填充 Markdown 内容
1836-
const editor = window.tinymceModal?.currentEditor
1837-
if (editor && typeof editor.setContent === 'function') {
1838-
editor.setContent(markdown)
1839-
console.log('[COSE] 华为云开发者博客内容填充成功,长度:', markdown.length)
1840-
return { success: true, method: 'tinymceModal', length: markdown.length }
1912+
// 1. 等待编辑器和 iframe 就绪
1913+
console.log('[COSE] 华为云:等待 Markdown 编辑器 iframe 就绪...')
1914+
const ready = await waitForEditorReady()
1915+
if (!ready) {
1916+
console.log('[COSE] 华为云:编辑器等待超时')
1917+
return { success: false, error: '编辑器 iframe 等待超时' }
18411918
}
1919+
console.log('[COSE] 华为云:编辑器 iframe 已就绪')
18421920

1843-
return { success: false, error: 'tinymceModal.currentEditor not found' }
1921+
// 2. 带重试的内容填充,通过 message 事件确认
1922+
const maxRetries = 6
1923+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
1924+
console.log(`[COSE] 华为云内容填充尝试 ${attempt}/${maxRetries}`)
1925+
1926+
const result = await setContentWithConfirm(ready.editor, ready.iframe, markdown)
1927+
if (result.confirmed) {
1928+
console.log(`[COSE] 华为云内容填充成功(第${attempt}次),已收到 iframe 确认`)
1929+
return { success: true, method: 'message-confirm', attempt, length: markdown.length }
1930+
}
1931+
1932+
console.log(`[COSE] 华为云:未收到 iframe 确认,等待后重试...`)
1933+
// iframe 内部应用可能还在初始化,等待后重试
1934+
await new Promise(r => setTimeout(r, 2000))
1935+
}
1936+
1937+
// 3. 所有重试失败,直接 postMessage 作为最后手段
1938+
console.log('[COSE] 重试耗尽,尝试直接 postMessage')
1939+
ready.iframe.contentWindow.postMessage(JSON.stringify({
1940+
mdEditorEventAction: 'setMdEditorContent',
1941+
data: encodeURIComponent(markdown)
1942+
}), '*')
1943+
await new Promise(r => setTimeout(r, 1000))
1944+
return { success: true, method: 'direct-postMessage', length: markdown.length }
18441945
},
1845-
args: [content.title, markdownContent],
1946+
args: [markdownContent],
18461947
world: 'MAIN',
18471948
})
18481949

apps/extension/src/content.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,46 @@ console.log('[COSE Content Script] Hostname:', window.location.hostname)
88
; (function () {
99
'use strict'
1010

11+
// 华为云开发者博客页面:自动获取并缓存用户信息
12+
if (window.location.hostname.includes('huaweicloud.com')) {
13+
console.log('[COSE] 检测到华为云页面')
14+
15+
setTimeout(async () => {
16+
try {
17+
const response = await fetch('https://devdata.huaweicloud.com/rest/developer/fwdu/rest/developer/user/hdcommunityservice/v1/member/get-personal-info', {
18+
method: 'GET',
19+
credentials: 'include',
20+
headers: { 'Accept': 'application/json' },
21+
})
22+
if (!response.ok) return
23+
24+
const data = await response.json()
25+
if (data && data.memName) {
26+
const userInfo = {
27+
loggedIn: true,
28+
username: data.memAlias || data.memName || '',
29+
avatar: data.memPhoto || '',
30+
cachedAt: Date.now(),
31+
}
32+
33+
if (typeof chrome !== 'undefined' && chrome.runtime) {
34+
chrome.runtime.sendMessage({
35+
type: 'CACHE_USER_INFO',
36+
platform: 'huaweicloud',
37+
userInfo,
38+
}).then(() => {
39+
console.log('[COSE] 华为云用户信息已缓存:', userInfo.username)
40+
}).catch(e => {
41+
console.log('[COSE] 缓存失败:', e.message)
42+
})
43+
}
44+
}
45+
} catch (e) {
46+
console.log('[COSE] 华为云用户信息缓存失败:', e.message)
47+
}
48+
}, 3000) // 华为云 SSO 登录需要几秒延迟
49+
}
50+
1151
// 小红书页面:自动获取并缓存用户信息
1252
if (window.location.hostname.includes('xiaohongshu.com')) {
1353
console.log('[COSE] 检测到小红书页面')
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// 华为云开发者博客平台配置
2+
const HuaweiCloudPlatform = {
3+
id: 'huaweicloud',
4+
name: 'HuaweiCloud',
5+
icon: 'https://www.huaweicloud.com/favicon.ico',
6+
url: 'https://bbs.huaweicloud.com/blogs/article',
7+
publishUrl: 'https://bbs.huaweicloud.com/blogs/article',
8+
title: '华为云开发者博客',
9+
type: 'huaweicloud',
10+
}
11+
12+
export { HuaweiCloudPlatform }

packages/core/src/platforms/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { SohuPlatform } from './sohu.js'
2323
import { BilibiliPlatform } from './bilibili.js'
2424
import { WeiboPlatform } from './weibo.js'
2525
import { AliyunPlatform } from './aliyun.js'
26+
import { HuaweiCloudPlatform } from './huaweicloud.js'
2627
import { HuaweiDevPlatform } from './huaweidev.js'
2728
import { TwitterPlatform } from './twitter.js'
2829
import { QianfanPlatform } from './qianfan.js'
@@ -55,6 +56,7 @@ const PLATFORMS = [
5556
BilibiliPlatform,
5657
WeiboPlatform,
5758
AliyunPlatform,
59+
HuaweiCloudPlatform,
5860
HuaweiDevPlatform,
5961
TwitterPlatform,
6062
QianfanPlatform,
@@ -88,6 +90,7 @@ function getPlatformFiller(hostname) {
8890
if (hostname.includes('member.bilibili.com')) return 'bilibili'
8991
if (hostname.includes('card.weibo.com')) return 'weibo'
9092
if (hostname.includes('developer.aliyun.com')) return 'aliyun'
93+
if (hostname.includes('bbs.huaweicloud.com')) return 'huaweicloud'
9194
if (hostname.includes('developer.huawei.com')) return 'huaweidev'
9295
if (hostname.includes('x.com') || hostname.includes('twitter.com')) return 'twitter'
9396
if (hostname.includes('qianfan.cloud.baidu.com')) return 'qianfan'

0 commit comments

Comments
 (0)