https://www.latepost.com/。 用油猴写了个脚本好了。问题来源是晚点文章页加载了自己的 web-highlighter 和 select-share.js。它会抢先拆分选中的正文 DOM,导致五彩拿到失效的选区。
新脚本只禁用晚点自身的选区分享高亮实例,不修改五彩。之后高亮、批注、账号同步仍全部由五彩原生功能完成。
// ==UserScript==
// @name 晚点 LatePost × 五彩兼容修复
// @namespace https://www.latepost.com/
// @version 1.0.0
// @description 禁用晚点文章页自带的选区高亮实例,避免它抢先改写 DOM,让五彩原生高亮、批注和账号云同步正常工作。
// @author Codex
// @match https://www.latepost.com/news/dj_detail*
// @match https://latepost.com/news/dj_detail*
// @run-at document-start
// @grant unsafeWindow
// @inject-into page
// ==/UserScript==
(function () {
'use strict';
const pageWindow = typeof unsafeWindow === 'object' ? unsafeWindow : window;
let nativeHighlighter = null;
let restored = false;
/**
晚点的 select-share.js 只需要这些方法来启动它自己的选区工具。
返回空实现后,它不会监听选区、拆分文本节点或插入 highlight-wrap,
因而不会破坏五彩稍后读取的 Selection / Range。
*/
function DisabledLatePostHighlighter() {}
DisabledLatePostHighlighter.event = {
CLICK: 'click',
HOVER: 'hover',
HOVER_OUT: 'hover_out',
CREATE: 'create',
REMOVE: 'remove',
};
DisabledLatePostHighlighter.prototype.on = function () { return this; };
DisabledLatePostHighlighter.prototype.run = function () { return this; };
DisabledLatePostHighlighter.prototype.remove = function () { return this; };
DisabledLatePostHighlighter.prototype.removeAll = function () { return this; };
DisabledLatePostHighlighter.prototype.getDoms = function () { return []; };
function restoreNativeExport() {
if (restored || !nativeHighlighter) return;
restored = true;
// select-share.js 已经持有禁用实例后,恢复原始全局导出,尽量不影响
// 晚点将来可能添加的、与选区分享无关的其他代码。
Object.defineProperty(pageWindow, 'Highlighter', {
configurable: true,
enumerable: true,
writable: true,
value: nativeHighlighter,
});
console.info('[LatePost × WuCai] 已隔离晚点选区高亮,五彩可接管原始选区。');
}
try {
// web-highlighter.min.js 使用 window.Highlighter = Constructor 导出。
// 在它赋值时保留真正的构造器,但只让紧随其后的 select-share.js
// 看到空实现。整个处理发生在 document-start,不修改五彩扩展。
Object.defineProperty(pageWindow, 'Highlighter', {
configurable: true,
enumerable: true,
get() {
return nativeHighlighter ? DisabledLatePostHighlighter : undefined;
},
set(value) {
nativeHighlighter = value;
if (value && value.event) {
DisabledLatePostHighlighter.event = value.event;
}
},
});
// 晚点当前把 web-highlighter 与 select-share 作为相邻同步脚本加载。
// DOMContentLoaded 时,后者已完成初始化,可以安全恢复全局导出。
document.addEventListener('DOMContentLoaded', restoreNativeExport, { once: true });
pageWindow.addEventListener('load', restoreNativeExport, { once: true });
// 防止页面以后改成异步脚本,留一个短暂的兼容窗口。
pageWindow.setTimeout(restoreNativeExport, 3000);
} catch (error) {
console.warn('[LatePost × WuCai] 页面兼容修复未能启动:', error);
}
})();