Weibo关键词涂抹白字

在 weibo把指定关键词渲染为白色;附带轮询确保生效

// ==UserScript==
// @name         Weibo关键词涂抹白字
// @namespace    local.weibo.kwwhite
// @version      1.1.1.2
// @description  在 weibo把指定关键词渲染为白色;附带轮询确保生效
// @author       you
// @match        *://*.weibo.cn/*
// @match        *://weibo.cn/*
// @match        *://weibo.com/*
// @match        *://s.weibo.com/*
// @match        *://rebang.today/*
// @match        *://tophub.today/*
// @match        *://www.xiaohongshu.com/*
// @match        *://www.zaobao.com.sg/*
// @match        *://wp.m.163.com/*
// @run-at       document-end
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
  'use strict';

  /** ① 在这里添加/删除你的关键词 **/

  const KEYWORDS = [
      "#","@",
      "日本","中国","乌克兰","以色列","巴勒斯坦","加沙","北京","上海","广东","深圳","广州","南京","杭州","新疆","柬埔寨", "首尔","釜山","重庆",
      "网红","警方","官方","法院","警车",
      "居然","还有","谁懂", "离谱!",
      "快递","外卖","麦当劳","肯德基","淘宝","美团","京东","腾讯","胖东来","于东来","支付宝", "贾国龙","微信","段奥娟","TFBOYS","金子涵","舒淇","王耀庆","胡先煦","李宛妲","郑恺","白百何", "监控","胡锡进",
"王玉雯","彭昱畅","张子枫","何炅","彭于晏","骨相","沈梦瑶","张晋","张萌","卓沅","乔妍","朱延浩","徐艺洋", "华晨宇","张继科","张召忠","奇瑞","瑞虎","微博","魏建军","苏炳添","邵雨琪", "李庚希","陈数",
      "官宣","通报","美学","建议","如何","看待","知道","终于","为啥","回应","怎么","评论","评价","是不是","偷偷","啥样",
      "体制内","原生家庭","王安宇","沈月","田栩宁","严浩翔","孙怡","董子健","韩庚","卢靖姗","文章","马伊琍","胡兵","瞿颖","谢霆锋","金晨","黄圣依","檀健次","蔡徐坤","王一博","肖战","王俊凯","王源","易烊千玺",
      "贾玲","黄磊","脱口秀","黄子韬","沈腾","赵丽颖","迪丽热巴","热巴","周杰伦","赵露思","邓超","鹿晗","陈赫","王鹤棣","虞书欣","白鹿","小米","华为","鞠婧炜","五月天", "邪修","李现","演唱会","出轨","女主","租房","王心凌","妈咪","级别","宋茜","宋浩然","金钟国","张杰","朱桢","马龙","樊振东","魏哲鸣","女孩","花光","积蓄","瞒着家人","老婆","老公","洗碗","宋亚轩","广电总局","偷拍","柳冈旻","李相沅","余适","鸿蒙","澎湃","周安信","贺鑫隆","陈添祥","毛不易","李艺彤","曹颖","王珞丹","李晟","祝绪丹","叶童","宋妍霏","李梦","许珑瀚","常华森", "刘宇宁","陈泽","佟丽娅","陈思诚","贾冰","蓝盈莹","张海宇","张天阳","沈涛","龚俊林","徐志胜","秦昊","颜人中","高瀚宇","田嘉瑞", "陈小春","张馨予","于适","蔚来","刘嘉玲", "杨采钰","柯洁","井胧","袁咏仪","李维刚", "苏有朋","陈岚","张雅琪","宋佳","孙红雷","那英","罗予彤", "容祖儿","成龙","吴世勋","林小宅", "谁","给","和","金宇彬","林峯",
"曝",
"梁朝伟","任豪","李佳航","印小天","宗馥莉", "薛飞","郑钦文","李承铉","朴敏英","阿娇","赵昭仪","陈伟霆", "探店","Gucci","王暖暖","鹿哈","女友", "男友","花少","收视率","张予曦","何超莲",
"窦骁","金智秀","河南","嘉宾","王嘉尔", "杨超越","孙一宁","蔡文静","黑龙江","宋威龙",
"中医","中药",
      "雷军","卢伟冰","罗永浩","余承东","陈乔恩","岳云鹏","郭德纲","王楚钦","孙颖莎","张艺兴","时代少年团","iPhone","黄晓明","angelababy","张天爱","吴彦祖","王力宏","韩安冉","李乃文",
      "王冕","服务员","临时工","后续","向佐","向太","张家辉","周星驰","马柏全","张晚意","陈紫函","戴向宇","幽门螺旋杆菌","葛夕","白敬亭","辛芷蕾","黄灿灿","李荣浩","杨丞琳","高圆圆",
      "赵又廷","关晓彤","刘涛","李沁","薛之谦","李一桐","淘宝","美团","马思纯","于正","王晶","王菲","窦靖童","周冬雨","杨蓉","章若楠","台风","航母","唐嫣","白百何","丁真","李沛恩", "王曼昱","黄渤","任敏","张雨绮","周柏豪","陈哲远","刘宇","李昀锐","李昊","热依扎","柏成训","吴慷仁","黄景瑜","张智霖","陆毅","鲍蕾","张泽禹","陈汉典","黄冠亨","黄子弘凡","袁一琦","许杨玉琢","唐国强","丁程鑫","沙溢","杨迪","邵子恒","金靖","金九粒","宋小宝","邵兵","汪东城","杜淳","胡军","钟楚曦","侯明昊","卢昱晓","李鸿其","王紫璇","丁程鑫", "周政杰", "边伯贤",
      "李沉舟","苏新皓","闵玧其","贺峻霖","王敬轩","全智贤","丞磊","展轩","赵今麦","梓渝","岳雨婷","张峻豪","麦当劳","肯德基","娜扎","齐思钧","孙菲菲","汪苏泷","姚安娜","labubu",
      "荣梓杉","谢娜","刘芮麟","井柏然","孟佳","理想汽车","肖明明","梁靖崑","娃哈哈","韩国","洪尧","李兰迪","薛佳凝","邱淑贞","张元英","李雪琴","王一通","曾舜晞","郭俊辰","汤唯",
      "魏大勋","南派三叔","谭维维","杨紫","爱奇艺","黄正音","李川","张新成","丁禹兮","苏醒","张远","刘芸","郑钧","直播","打赏","沈佳润","谭松韵","梅婷","GAI","新剧","妻子","牵手",
      "泽连斯基","白宇","张碧晨","张栋梁","周传雄","蔡国庆","周深","黎姿","王楚然","张若昀","唐艺昕","吴京","谢楠","惠英红","生图","儿子","刘耀文","于洋","范丞丞","范冰冰","李冰冰",
      "前夫","前妻","男子","女子","男神","女神","田力","全女","xxn","xdm","女生","律师","中介","丁克","婉拒","谢谢","张嘉益","穆祉丞","刘宇宁","郭采洁","张一山","白百何",
      "孙菲菲","澳门","香港","台湾","张雪峰","高德","周鸿祎","东风日产","比亚迪","智己","董璇","张维伊","东风汽车","长安","零跑汽车",
      "刘亦菲","安徽","刘萧旭","胡歌","田曦薇","周也","刘浩存","杨幂","孟子义","陈都灵","任嘉伦","成毅","邓为","龚俊","张凌赫","邢菲","宋轶","王影璐","许凯","杨洋","欧豪","陈飞宇","王星越","金世佳","宋祖儿",
      "沈羽洁","鞠婧祎","张柏芝","刘诗诗","张婧仪","蒋欣","祝绪丹","刘令姿","陈昊宇","生日","内娱","俊辰","刘德华","郭富城", "吴艳妮","林雨薇", "姜李韵喆","朱雨玲","朱梓予","范玮琪","林志炫",
"金海心","张帅","田震","闫妮","解晓东", "朱一龙","林依轮","陈丽君","陈楚生","福禄寿", "孙宇晨","加密货币","区块链","王健林","万达", "李晨","短剧","奔跑吧","敖瑞鹏","跑男",
"恋综","朱志鑫","哈妮克孜","毕雯珺","泡泡玛特", "杜海涛","王霏霏","男主","女主","阚清子",
"柯爱林","易梦玲","徐冬冬","王赫野","吉克隽逸", "闷声","干","大事","杨博文","魔丸",
"气血足","求婚","结婚","离婚","夏思齐", 
      "古天乐","小沈阳","王青","冯建宇","刘思远","李秀满","朱珠","蓝战非","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何",
"白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何","白百何"];
    const CASE_INSENSITIVE = true;

  /** ③ 轮询间隔(毫秒)。为兼容 /pub 的局部刷新,建议保留 **/
  const POLL_MS = 1000;

  // --- 正则 --- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 59.16 69.57'>     <g transform='translate(-110.73,-61.49)'>         <path d='m 130.15,99.28 c 2.9,-1.3 4.93,-4.22 4.94,-7.6 0,-4.61 -3.74,-8.35 -8.35,-8.35 -4.61,0 -8.35,3.74 -8.35,8.35 0,4.6 3.74,8.34 8.35,8.34 0.72,0 1.41,-0.1 2.08,-0.27 0.41,-0.18 0.85,-0.33 1.32,-0.46 z m -7.55,-6.13 c 0,-2.3 1.87,-4.17 4.18,-4.17 0.58,0 1.15,0.12 1.65,0.34 -0.11,0.31 -0.18,0.65 -0.18,1.0 0,1.53 1.19,2.79 2.7,2.91 -0.04,2.26 -1.89,4.09 -4.17,4.09 -2.3,0 -4.18,-1.87 -4.18,-4.17' style='fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 146.01,83.31 c -4.61,0 -8.35,3.74 -8.35,8.35 0,3.35 1.97,6.23 4.82,7.56 0.55,0.14 1.08,0.32 1.56,0.54 0.63,0.15 1.28,0.24 1.96,0.24 4.6,0 8.34,-3.74 8.35,-8.35 0,-4.61 -3.74,-8.35 -8.35,-8.35 z m 0.04,14.01 c -2.3,0 -4.17,-1.87 -4.17,-4.17 0,-2.3 1.87,-4.17 4.17,-4.17 0.51,0 1.01,0.09 1.46,0.26 -0.13,0.33 -0.21,0.7 -0.21,1.08 0,1.61 1.3,2.92 2.92,2.92 -0.05,2.26 -1.9,4.08 -4.17,4.08' style='fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 144.48,101.56 c -0.88,-0.89 -2.66,-1.31 -4.61,-1.49 0.0,-0.06 0.02,-0.13 0.02,-0.2 0,-0.14 -0.02,-0.28 -0.05,-0.41 -0.06,-0.24 -0.18,-0.46 -0.33,-0.65 -0.31,-0.37 -0.77,-0.62 -1.3,-0.62 -0.48,0 -0.92,0.2 -1.23,0.53 -0.16,0.17 -0.28,0.38 -0.36,0.61 -0.05,0.17 -0.09,0.35 -0.09,0.54 0,0.02 0.0,0.04 0.0,0.06 -0.03,0 -0.07,-7.94e-4 -0.11,-7.94e-4 -0.05,0 -0.11,0 -0.18,0 0.0,-0.02 0.0,-0.04 0.0,-0.06 0,-0.19 -0.03,-0.37 -0.09,-0.54 -0.07,-0.23 -0.2,-0.44 -0.36,-0.61 -0.31,-0.33 -0.74,-0.53 -1.23,-0.53 -0.53,0 -1.0,0.25 -1.32,0.63 -0.15,0.19 -0.26,0.41 -0.32,0.65 -0.03,0.13 -0.05,0.26 -0.05,0.4 0,0.07 0.01,0.14 0.02,0.21 -1.76,0.17 -3.61,0.58 -4.53,1.49 -0.29,0.28 -0.48,0.62 -0.55,1.02 -0.02,0.1 -0.03,0.22 -0.03,0.33 0,3.35 3.73,5.89 8.68,5.89 4.78,0 8.68,-2.64 8.68,-5.89 0,-0.11 -0.02,-0.22 -0.03,-0.33 -0.06,-0.39 -0.25,-0.73 -0.53,-1.02 z m -7.01,-1.7 c 0,-0.21 0.09,-0.4 0.24,-0.53 0.12,-0.11 0.28,-0.18 0.47,-0.18 0.2,0 0.38,0.08 0.51,0.22 0.12,0.12 0.2,0.3 0.2,0.49 0,0.04 -0.01,0.08 -0.02,0.13 -0.06,0.33 -0.34,0.58 -0.69,0.58 -0.36,0 -0.66,-0.28 -0.7,-0.64 -0.0,-0.02 -0.01,-0.05 -0.01,-0.07 z m -3.68,0 c 0,-0.19 0.07,-0.36 0.19,-0.49 0.13,-0.13 0.31,-0.22 0.52,-0.22 0.18,0 0.34,0.07 0.47,0.18 0.14,0.13 0.24,0.31 0.24,0.53 0,0.02 -0.01,0.04 -0.01,0.07 -0.03,0.35 -0.33,0.64 -0.7,0.64 -0.35,0 -0.63,-0.25 -0.69,-0.58 -0.0,-0.04 -0.02,-0.08 -0.02,-0.13 z m -0.16,6.82 c -0.93,0 -1.7,-0.76 -1.7,-1.7 h 0.49 0.49 c 0,0.39 0.32,0.72 0.72,0.72 0.39,0 0.72,-0.32 0.72,-0.72 h 0.49 0.49 c 0,0.93 -0.76,1.7 -1.7,1.7' style='fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 115.82,89.87 c -1.14,-0.47 -2.52,-0.26 -3.29,0.5 -0.36,0.36 -0.7,0.99 -0.3,1.93 0.45,1.07 1.22,2.33 2.01,3.29 0.99,1.2 1.64,1.49 1.87,1.47 0.13,-0.01 0.27,-0.27 0.37,-0.67 l 0.02,0.0 c -0.44,-1.11 -0.69,-2.32 -0.69,-3.6 v -2.93' style='fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 160.15,90.37 c -0.75,-0.75 -2.09,-0.96 -3.23,-0.52 v 2.95 c 0,1.29 -0.25,2.52 -0.71,3.65 0.09,0.36 0.22,0.6 0.35,0.61 0.23,0.01 0.88,-0.27 1.87,-1.47 0.78,-0.95 1.56,-2.21 2.01,-3.29 0.39,-0.94 0.05,-1.57 -0.3,-1.93' style='fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 130.96,93.23 c -1.51,-0.11 -2.7,-1.37 -2.7,-2.91 0,-0.35 0.06,-0.69 0.18,-1.0 -0.5,-0.22 -1.06,-0.34 -1.65,-0.34 -2.3,0 -4.18,1.87 -4.18,4.17 0,2.3 1.87,4.17 4.18,4.17 2.28,0 4.13,-1.82 4.17,-4.09' style='fill:#282a2b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 146.05,97.32 c 2.27,0 4.12,-1.81 4.17,-4.08 -1.61,-0.0 -2.92,-1.31 -2.92,-2.92 0,-0.38 0.07,-0.75 0.21,-1.08 -0.45,-0.17 -0.95,-0.26 -1.46,-0.26 -2.3,0 -4.17,1.87 -4.17,4.17 0,2.3 1.87,4.17 4.17,4.17' style='fill:#282a2b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 146.29,102.92 c 0,-0.11 -0.0,-0.22 -0.01,-0.33 h 0.86 c 3.46,0 6.5,-1.81 8.23,-4.53 0.03,-0.05 0.07,-0.1 0.1,-0.16 0.3,0.33 0.66,0.46 0.96,0.48 0.04,0.0 0.08,0.0 0.13,0.0 0.83,0 1.79,-0.65 2.86,-1.95 0.86,-1.04 1.71,-2.43 2.21,-3.61 0.52,-1.24 0.31,-2.46 -0.58,-3.37 -1.01,-1.01 -2.65,-1.38 -4.15,-0.97 V 86.44 71.27 c 1e-5,-5.4 -4.37,-9.78 -9.78,-9.78 h -21.53 c -5.4,0 -9.78,4.37 -9.78,9.78 v 15.21 2.0 c -1.52,-0.42 -3.19,-0.07 -4.21,0.95 -0.89,0.9 -1.11,2.12 -0.58,3.37 0.5,1.18 1.34,2.56 2.21,3.61 1.07,1.29 2.03,1.95 2.86,1.95 0.04,0 0.08,-0.0 0.13,-0.0 0.31,-0.02 0.68,-0.15 1.0,-0.52 0.03,0.05 0.06,0.1 0.1,0.15 1.73,2.74 4.77,4.58 8.26,4.58 h 0.86 c -0.01,0.11 -0.01,0.22 -0.01,0.33 0,4.06 4.26,7.12 9.92,7.12 5.46,0 9.91,-3.19 9.91,-7.12 z m 13.86,-12.55 c 0.36,0.36 0.7,0.99 0.3,1.93 -0.45,1.07 -1.22,2.33 -2.01,3.29 -0.99,1.2 -1.64,1.49 -1.87,1.47 -0.12,-0.01 -0.26,-0.25 -0.35,-0.61 0.45,-1.12 0.71,-2.35 0.71,-3.65 v -2.95 c 1.13,-0.43 2.47,-0.22 3.23,0.52 z m -14.14,-7.05 c 4.61,0 8.35,3.74 8.35,8.35 -0.01,4.61 -3.75,8.35 -8.35,8.35 -0.67,0 -1.33,-0.08 -1.96,-0.24 -0.47,-0.22 -1.0,-0.4 -1.56,-0.54 -2.84,-1.33 -4.82,-4.21 -4.82,-7.56 0,-4.61 3.74,-8.35 8.35,-8.35 z m -29.52,13.09 c -0.09,0.39 -0.23,0.65 -0.37,0.67 -0.23,0.01 -0.88,-0.27 -1.87,-1.47 -0.78,-0.95 -1.56,-2.21 -2.01,-3.29 -0.39,-0.94 -0.05,-1.57 0.3,-1.93 0.76,-0.76 2.14,-0.97 3.29,-0.5 v 2.93 c 0,1.27 0.25,2.48 0.69,3.6 z m 1.9,-4.72 c 0,-4.61 3.74,-8.35 8.35,-8.35 4.61,0 8.35,3.74 8.35,8.35 -0.0,3.38 -2.03,6.3 -4.94,7.6 -0.46,0.12 -0.91,0.27 -1.32,0.46 -0.66,0.17 -1.36,0.27 -2.08,0.27 -4.61,0 -8.35,-3.74 -8.35,-8.34 z m 9.29,11.24 c 0,-0.11 0.01,-0.22 0.03,-0.33 0.07,-0.39 0.26,-0.73 0.55,-1.02 0.91,-0.9 2.76,-1.31 4.53,-1.49 -0.0,-0.06 -0.02,-0.13 -0.02,-0.21 0,-0.14 0.02,-0.27 0.05,-0.4 0.06,-0.24 0.17,-0.46 0.32,-0.65 0.31,-0.38 0.78,-0.63 1.32,-0.63 0.48,0 0.92,0.2 1.23,0.53 0.16,0.17 0.28,0.38 0.36,0.61 0.05,0.17 0.09,0.35 0.09,0.54 0,0.02 -0.0,0.04 -0.0,0.06 0.06,0 0.12,0 0.18,0 0.03,0 0.07,7.94e-4 0.11,7.94e-4 -0.0,-0.02 -0.0,-0.04 -0.0,-0.06 0,-0.19 0.03,-0.37 0.09,-0.54 0.07,-0.23 0.2,-0.44 0.36,-0.61 0.31,-0.32 0.74,-0.53 1.23,-0.53 0.52,0 0.99,0.24 1.3,0.62 0.15,0.19 0.27,0.41 0.33,0.65 0.03,0.13 0.05,0.27 0.05,0.41 0,0.07 -0.01,0.13 -0.02,0.2 1.94,0.18 3.73,0.59 4.61,1.49 0.28,0.28 0.46,0.62 0.53,1.02 0.01,0.11 0.03,0.21 0.03,0.33 0,3.24 -3.89,5.89 -8.68,5.89 -4.95,0 -8.68,-2.53 -8.68,-5.89' style='fill:#282a2b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 134.49,100.58 c 0.37,0 0.66,-0.28 0.7,-0.64 0.0,-0.02 0.01,-0.04 0.01,-0.07 0,-0.21 -0.09,-0.4 -0.24,-0.53 -0.12,-0.11 -0.29,-0.18 -0.47,-0.18 -0.2,0 -0.38,0.08 -0.52,0.22 -0.12,0.12 -0.19,0.3 -0.19,0.49 0,0.04 0.01,0.08 0.02,0.13 0.06,0.33 0.34,0.58 0.69,0.58' style='fill:#282a2b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 138.18,100.58 c 0.35,0 0.62,-0.25 0.69,-0.58 0.0,-0.04 0.02,-0.08 0.02,-0.13 0,-0.19 -0.07,-0.36 -0.2,-0.49 -0.13,-0.13 -0.31,-0.22 -0.51,-0.22 -0.18,0 -0.34,0.07 -0.47,0.18 -0.15,0.13 -0.24,0.31 -0.24,0.53 0,0.02 0.01,0.05 0.01,0.07 0.04,0.35 0.33,0.64 0.7,0.64' style='fill:#282a2b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 134.33,104.97 c -3.4e-4,0.39 -0.32,0.72 -0.72,0.72 -0.39,0 -0.72,-0.32 -0.72,-0.72 h -0.49 -0.49 c 0,0.93 0.76,1.7 1.7,1.7 0.93,0 1.7,-0.76 1.7,-1.7 h -0.49 -0.49' style='fill:#282a2b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />         <path d='m 165.85,106.2 -0.22,-0.22 c -4.1,-4.1 -10.78,-4.1 -14.88,0 -1.78,1.78 -2.77,4.16 -2.77,6.68 0,2.52 0.98,4.9 2.77,6.68 l 0.08,0.08 c 1.66,1.66 3.85,2.5 6.04,2.5 2.19,-2.7e-4 4.37,-0.83 6.04,-2.5 2.45,-2.45 2.45,-6.44 0,-8.9 -0.57,-0.57 -1.5,-0.57 -2.08,0 -0.57,0.57 -0.57,1.5 0,2.08 1.3,1.3 1.3,3.42 0,4.73 -2.18,2.18 -5.73,2.18 -7.92,0 l -0.08,-0.08 c -1.22,-1.22 -1.9,-2.86 -1.9,-4.6 0,-1.73 0.67,-3.37 1.9,-4.6 2.95,-2.95 7.76,-2.95 10.71,0 l 0.22,0.22 c 4.23,4.23 4.23,11.13 0,15.37 -2.87,2.86 -6.68,4.45 -10.74,4.45 h -4.03 c 0.06,-0.28 0.11,-0.59 0.11,-0.94 0,-4.96 -7.31,-7.35 -7.23,-10.18 0.19,-6.94 -9.38,-7.21 -9.58,-0.27 -0.19,6.97 -1.11,14.35 6.29,14.35 0.64,0 1.26,-0.0 1.86,-0.0 0.03,0.0 0.07,0.01 0.11,0.01 h 12.46 c 4.84,0 9.4,-1.88 12.82,-5.31 5.38,-5.38 5.38,-14.15 0,-19.54' style='fill:#282a2b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.03' />     </g> </svg>
  const regex = buildRegex(KEYWORDS, CASE_INSENSITIVE);
  if (!regex) return;

  // 初次执行 + 轮询
  runOnce();
  setInterval(runOnce, POLL_MS);

  function runOnce() {
    // 老页尽量少过滤,直接全页扫;但跳过常见不可见容器
    highlightIn(document.body);
  }

  function buildRegex(words, ci) {
    const parts = (words || []).filter(Boolean).map(escapeRegExp);
    if (!parts.length) return null;
    return new RegExp("(" + parts.join("|") + ")", ci ? "gi" : "g");
  }
  function escapeRegExp(s) {
    return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  }

  // 核心:扫描文本节点,把命中片段用 <span style="color:#fff !important" data-kw-hit> 包裹
  function highlightIn(root) {
    if (!root || !regex) return;

    const ign = node => {
      if (node.nodeType !== 1) return false;
      const tag = node.tagName;
      // 最小化忽略清单:脚本/样式/内嵌对象
      return tag === "SCRIPT" || tag === "STYLE" || tag === "IFRAME" || tag === "OBJECT" || tag === "NOSCRIPT";
    };
    if (ign(root)) return;

    const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
    const nodes = [];
    let n;
    while ((n = walker.nextNode())) nodes.push(n);

    for (const textNode of nodes) {
      const parent = textNode.parentNode;
      if (!parent) continue;
      // 如果父节点已经是我们包裹过的片段,跳过
      if (parent.nodeType === 1 && parent.hasAttribute && parent.hasAttribute("data-kw-hit")) continue;

      const text = textNode.nodeValue;
      if (!text || !regex.test(text)) continue;
      regex.lastIndex = 0;

      const frag = document.createDocumentFragment();
      let last = 0;
      text.replace(regex, (m, _g1, idx) => {
        // 前段原样
        if (idx > last) frag.appendChild(document.createTextNode(text.slice(last, idx)));
        // 命中片段 -> 白字
        const span = document.createElement("span");
        span.setAttribute("style", "color:#fff !important;");
        span.setAttribute("data-kw-hit", "1");
        span.textContent = m;
        frag.appendChild(span);
        last = idx + m.length;
        return m;
      });
      // 末尾残余
      if (last < text.length) frag.appendChild(document.createTextNode(text.slice(last)));

      parent.replaceChild(frag, textNode);
    }
  }
})();