├── Chromium ├── js │ ├── faq.js │ └── worker.js ├── icons │ ├── dh │ │ └── t.png │ ├── drag.webp │ ├── err512.png │ ├── hyl_512.png │ ├── logo128.png │ ├── logo16.png │ ├── logo256.png │ ├── logo32.png │ ├── logo64.png │ ├── paste.webp │ ├── yyl_512.png │ ├── RightClick.webp │ └── fileicon │ │ ├── ae.png │ │ ├── ai.png │ │ ├── ar.png │ │ ├── asp.png │ │ ├── bat.png │ │ ├── c.png │ │ ├── css.png │ │ ├── dll.png │ │ ├── exe.png │ │ ├── js.png │ │ ├── php.png │ │ ├── ppt.png │ │ ├── pr.png │ │ ├── ps.png │ │ ├── py.png │ │ ├── sys.png │ │ ├── txt.png │ │ ├── zip.png │ │ ├── WORD.png │ │ ├── excel.png │ │ ├── file.png │ │ ├── html.png │ │ ├── java.png │ │ ├── json.png │ │ ├── link.png │ │ ├── music.png │ │ ├── video.png │ │ ├── images.png │ │ └── unknown.png ├── vendor │ ├── bootstrap │ │ └── fonts │ │ │ ├── bootstrap-icons.woff │ │ │ └── bootstrap-icons.woff2 │ ├── content_scripts │ │ ├── css │ │ │ ├── master_process.css │ │ │ ├── content_scripts.css │ │ │ ├── FullDomPermissions.css │ │ │ └── notification.css │ │ └── js │ │ │ ├── notification.js │ │ │ ├── Sticker.js │ │ │ ├── FullDomPermissions.js │ │ │ └── AutoInsertFun.js │ ├── UploadLog │ │ ├── imagesloaded.pkgd.min.js │ │ └── jquery.twbsPagination.min.js │ ├── dropzone │ │ └── css │ │ │ └── dropzone.css │ ├── confetti │ │ └── confetti.js │ └── IndexedDB │ │ └── db.js ├── _locales │ └── language.js ├── manifest.json ├── popup.html ├── css │ ├── UploadLog.css │ ├── popup.css │ ├── public.css │ └── options.css ├── UploadLog.html └── FAQ.html ├── Privacy.md ├── 自建表情包数据参考.json ├── README.md ├── 自动插入支持.md └── 版本更新.md /Chromium/js/faq.js: -------------------------------------------------------------------------------- 1 | $('.row').hide().slideDown('slow'); //动画 2 | -------------------------------------------------------------------------------- /Chromium/icons/dh/t.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/dh/t.png -------------------------------------------------------------------------------- /Chromium/icons/drag.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/drag.webp -------------------------------------------------------------------------------- /Chromium/icons/err512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/err512.png -------------------------------------------------------------------------------- /Chromium/icons/hyl_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/hyl_512.png -------------------------------------------------------------------------------- /Chromium/icons/logo128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/logo128.png -------------------------------------------------------------------------------- /Chromium/icons/logo16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/logo16.png -------------------------------------------------------------------------------- /Chromium/icons/logo256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/logo256.png -------------------------------------------------------------------------------- /Chromium/icons/logo32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/logo32.png -------------------------------------------------------------------------------- /Chromium/icons/logo64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/logo64.png -------------------------------------------------------------------------------- /Chromium/icons/paste.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/paste.webp -------------------------------------------------------------------------------- /Chromium/icons/yyl_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/yyl_512.png -------------------------------------------------------------------------------- /Chromium/icons/RightClick.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/RightClick.webp -------------------------------------------------------------------------------- /Chromium/icons/fileicon/ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/ae.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/ai.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/ar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/ar.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/asp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/asp.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/bat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/bat.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/c.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/css.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/css.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/dll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/dll.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/exe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/exe.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/js.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/php.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/php.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/ppt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/ppt.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/pr.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/ps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/ps.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/py.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/py.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/sys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/sys.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/txt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/txt.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/zip.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/WORD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/WORD.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/excel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/excel.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/file.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/html.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/java.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/java.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/json.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/link.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/music.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/music.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/video.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/images.png -------------------------------------------------------------------------------- /Chromium/icons/fileicon/unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/icons/fileicon/unknown.png -------------------------------------------------------------------------------- /Chromium/vendor/bootstrap/fonts/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/vendor/bootstrap/fonts/bootstrap-icons.woff -------------------------------------------------------------------------------- /Chromium/vendor/bootstrap/fonts/bootstrap-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZenEcho/PLExtension-Customized/HEAD/Chromium/vendor/bootstrap/fonts/bootstrap-icons.woff2 -------------------------------------------------------------------------------- /Privacy.md: -------------------------------------------------------------------------------- 1 | # Privacy Policy 2 | 3 | ## Personal or Sensitive User Data 4 | 5 | 目前,我们不会收集任何用户信息。 6 | 7 | :-) 8 | 9 | ## Use of Permissions 10 | 11 | 12 | | 权限 | 用途说明 | 13 | | ------------- | ----------------------------------------------- | 14 | | storage | 用于存储配置信息,例如使用的图床 | 15 | | contextMenus | 用于右键菜单上传,在页面上右键选项对图片进行上传 | 16 | | notifications | 用于通知状态,如右键上传/拖拽上传的完成或失败 | 17 | 18 | ### 我们保证存储的任何信息,不会被上传,不会被共享 -------------------------------------------------------------------------------- /Chromium/_locales/language.js: -------------------------------------------------------------------------------- 1 | // $(document).ready(function () { 2 | // $("[data-i18n]").each(function () { 3 | // $(this).html(chrome.i18n.getMessage($(this).attr("data-i18n"))); 4 | // }); 5 | // }) 6 | 7 | $(document).ready(function () { 8 | $("[data-i18n]").each(function () { 9 | var i18nKey = $(this).attr("data-i18n"); 10 | var i18nMessage = ""; 11 | var i18nKeys = i18nKey.split('+').map(key => key.trim()); 12 | 13 | i18nKeys.forEach(function (key) { 14 | i18nMessage += chrome.i18n.getMessage(key); 15 | }); 16 | 17 | $(this).html(i18nMessage); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /Chromium/vendor/content_scripts/css/master_process.css: -------------------------------------------------------------------------------- 1 | .insertContentIntoEditorPrompt { 2 | min-width: 2em; 3 | height: 1em; 4 | line-height: 1em; 5 | color: #fff; 6 | padding: 5px 10px; 7 | font-weight: bold; 8 | cursor: pointer; 9 | transition: all 0.3s ease; 10 | position: relative; 11 | display: inline-block; 12 | outline: none; 13 | overflow: hidden; 14 | border-radius: 5px; 15 | border: none; 16 | background-color: #3a86ff 17 | } 18 | .insertContentIntoEditorPrompt:hover { 19 | border-radius: 5px; 20 | padding-right: 24px; 21 | padding-left:8px; 22 | } 23 | .insertContentIntoEditorPrompt:hover:after { 24 | opacity: 1; 25 | right: 10px; 26 | } 27 | .insertContentIntoEditorPrompt:after { 28 | content: "\00BB"; 29 | position: absolute; 30 | opacity: 0; 31 | font-size: 1em; 32 | line-height: 1em; 33 | padding: 5px 0; 34 | top: 0; 35 | right: -20px; 36 | transition: 0.4s; 37 | } -------------------------------------------------------------------------------- /Chromium/js/worker.js: -------------------------------------------------------------------------------- 1 | self.addEventListener('message', function (e) { 2 | let item_imgUrl = e.data; 3 | let xhr = new XMLHttpRequest(); 4 | xhr.open('GET', item_imgUrl, true); 5 | xhr.responseType = 'text'; 6 | 7 | xhr.onprogress = function (event) { 8 | if (event.lengthComputable) { 9 | var percentComplete = Math.floor((event.loaded / event.total) * 100); 10 | self.postMessage({ status: 'loading', progress: percentComplete }); 11 | } else { 12 | self.postMessage({ status: 'loading', loaded: event.loaded }); 13 | } 14 | }; 15 | 16 | xhr.onload = function () { 17 | if (xhr.status === 200) { 18 | self.postMessage({ status: 'loaded', responseText: xhr.response }); 19 | } else { 20 | self.postMessage({ status: 'error', errorMsg: '加载失败: ' + xhr.status }); 21 | } 22 | }; 23 | xhr.onerror = function () { 24 | self.postMessage({ status: 'error', errorMsg: '网络错误或请求被阻止' }); 25 | }; 26 | 27 | xhr.send(); 28 | }); 29 | -------------------------------------------------------------------------------- /自建表情包数据参考.json: -------------------------------------------------------------------------------- 1 | { 2 | "sticker": [ 3 | { 4 | "StickerTitle": "贴吧表情", 5 | "StickerDescribe": "贴吧的表情", 6 | "StickerAuthor": "盘络收藏", 7 | "StickerData": [ 8 | { 9 | "StickerName": "呵呵", 10 | "StickerURL": "https://cdn-us.imgs.moe/2023/08/21/64e2d2c41d1c6.webp" 11 | }, 12 | { 13 | "StickerName": "哈哈", 14 | "StickerURL": "https://cdn-us.imgs.moe/2023/08/21/64e2d2c42b210.webp" 15 | }, 16 | { 17 | "StickerName": "捂嘴坏笑", 18 | "StickerURL": "https://cdn-us.imgs.moe/2023/08/21/64e2d2c450b24.webp" 19 | }, 20 | { 21 | "StickerName": "吐舌头", 22 | "StickerURL": "https://cdn-us.imgs.moe/2023/08/21/64e2d2c43705d.webp" 23 | } 24 | ] 25 | }, 26 | { 27 | "StickerTitle": "bili小黄豆", 28 | "StickerDescribe": "哔哩哔哩的小黄豆", 29 | "StickerAuthor": "盘络收藏", 30 | "StickerData": [ 31 | { 32 | "StickerName": "0", 33 | "StickerURL": "https://cdn-us.imgs.moe/Sticker/bili/0.webp" 34 | }, 35 | { 36 | "StickerName": "1", 37 | "StickerURL": "https://cdn-us.imgs.moe/Sticker/bili/1.webp" 38 | }, 39 | { 40 | "StickerName": "2", 41 | "StickerURL": "https://cdn-us.imgs.moe/Sticker/bili/2.webp" 42 | } 43 | ] 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /Chromium/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "__MSG_app_name__", 3 | "version": "1.1.0", 4 | "manifest_version": 3, 5 | "description": "__MSG_app_description__", 6 | "homepage_url": "https://fileup.dev/", 7 | "default_locale": "en", 8 | "icons": { 9 | "16": "icons/logo16.png", 10 | "32": "icons/logo32.png", 11 | "64": "icons/logo64.png", 12 | "128": "icons/logo128.png" 13 | }, 14 | "options_page": "options.html", 15 | "background": { 16 | "service_worker": "background.js", 17 | "type": "module" 18 | }, 19 | "content_scripts": [ 20 | { 21 | "matches": [ 22 | "" 23 | ], 24 | "js": [ 25 | "vendor/IndexedDB/db.js", 26 | "vendor/content_scripts/js/notification.js", 27 | "vendor/confetti/confetti.js", 28 | "js/public.js", 29 | "vendor/content_scripts/js/content_scripts.js", 30 | "js/uploader.js", 31 | "vendor/content_scripts/js/AutoInsertFun.js", 32 | "vendor/content_scripts/js/Sticker.js" 33 | ], 34 | "css": [ 35 | "vendor/content_scripts/css/content_scripts.css", 36 | "vendor/content_scripts/css/notification.css" 37 | ] 38 | } 39 | ], 40 | "web_accessible_resources": [ 41 | { 42 | "resources": [ 43 | "popup.html", 44 | "icons/*.png", 45 | "vendor/content_scripts/js/FullDomPermissions.js", 46 | "vendor/content_scripts/css/FullDomPermissions.css" 47 | ], 48 | "matches": [ 49 | "" 50 | ] 51 | } 52 | ], 53 | "action": { 54 | "default_title": "__MSG_app_name__", 55 | "default_icon": "icons/logo128.png", 56 | "default_popup": "" 57 | }, 58 | "permissions": [ 59 | "storage", 60 | "contextMenus", 61 | "notifications", 62 | "cookies" 63 | ], 64 | "host_permissions": [ 65 | "" 66 | ] 67 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | logo 3 | logo 4 |

5 | 6 | # 盘络上传扩展兰空定制 7 | 8 | ------------- 9 | ## 怎么定制自己图床? 10 | 11 | 1.下载本仓库代码,将其解压到本地。 12 | 13 | 2.打开`_locales`文件夹里的`messages.json` (en和zh对应中文英文) 14 | 15 | 3.Ctrl+H打开查找功能,在`message.json`中找到`浏览器扩展定制`字段,将其值改为你想要的文字。 16 | 17 | 4.修改完后压缩为zip,并分享引导用户安装即可。 18 | 19 | ------------- 20 | 21 | ## 功能演示 22 | 23 | - **粘贴上传** 24 | 25 | "粘贴上传"便捷的文件上传功能,支持直接粘贴图片数据、图片链接或本地文件到上传框,实现快速上传。省去了繁琐的选择步骤,只需简单复制并粘贴,即可将文件上传。 26 | ![粘贴上传.gif](https://cdn-us.imgs.moe/2023/07/04/64a414475a4ec.gif) 27 | 28 | - **拖拽上传** 29 | 30 | "拖拽上传"是便捷的文件上传方式。只需将文件从本地拖动到指定区域即可完成上传,还可以快速拖拽多个文件或频繁上传文件,提高工作效率,为用户带来便利和舒适的上传体验。 31 | ![拖拽上传.gif](https://cdn-us.imgs.moe/2023/07/04/64a4145276e67.gif) 32 | 33 | - **右键上传** 34 | 35 | "右键上传"是浏览器右键菜单中的便捷文件上传方式。用户只需在网页上对着图片右键点击,选择上传选项,即可完成文件上传。用户可以在浏览网页的同时,快速上传图片。 36 | ![右键上传.gif](https://cdn-us.imgs.moe/2023/07/04/64a414574dba6.gif) 37 | 38 | - **表情贴纸** 39 | 鼠标在盘络按钮上停留1秒钟即可打开表情贴纸,点击表情即可使用,表情插入调用自动插入功能。支持站点参考(自动插入支持.md) 40 | ![表情包.gif](https://cdn-us.imgs.moe/2023/08/22/64e4239e8629a.gif) 41 | 42 | - **自动插入** 43 | ![GitHub测试.gif](https://cdn-us.imgs.moe/2023/06/06/647f3b9b0fb88.gif) 44 | ![ty测试.gif](https://cdn-us.imgs.moe/2023/06/06/647f3b9b590e1.gif) 45 | ![wp测试.gif](https://cdn-us.imgs.moe/2023/06/06/647f3b9bc6a46.gif) 46 | #### [更多详细](https://github.com/ZenEcho/PLExtension/blob/master/%E8%87%AA%E5%8A%A8%E6%8F%92%E5%85%A5%E6%94%AF%E6%8C%81.md) 47 | 48 | ------------- 49 | 50 | ## 自定义表情贴纸 51 | 52 | **盘络提供的表情不合你胃口?你可以在配置信息底部,可以填写你自定义的表情贴纸数据,[数据参考](https://github.com/ZenEcho/PLExtension/blob/master/%E8%87%AA%E5%BB%BA%E8%A1%A8%E6%83%85%E5%8C%85%E6%95%B0%E6%8D%AE%E5%8F%82%E8%80%83.json)** 53 | 54 | ## 问题反馈 55 | [插件反馈](https://github.com/ZenEcho/PLExtension/issues) 56 | ------------- 57 | 58 | ## 效果图: 59 | ![上传记录.png](https://cdn-us.imgs.moe/2023/06/06/647f22c071273.png) 60 | ![上传页面.png](https://cdn-us.imgs.moe/2023/06/06/647f22c08ea2a.png) 61 | ![配置信息.png](https://cdn-us.imgs.moe/2023/06/06/647f22c096444.png) 62 | ------------- 63 | 64 | ## 开发: 65 | 66 | V1.1.4后增加了Chromium,Gecko内核识别 67 | 68 | 这样开发功能时只需要开发一个内核,完成功能后将代码复制到另一个内核即可。 69 | 70 | 但是manifest.json文件两个内核并不能合并,需要单独修改它。 71 | 72 | ### 扩展识别 73 | 74 | 考虑到js页面注入不同浏览器扩展会造成冲突,所以添加了识别功能 75 | 当扩展开发者发现功能冲突与盘络上传冲突时,可以使用: 76 | 77 | `window.postMessage({ type: 'Extension', data: "" }, "*");` 78 | 79 | 喊话扩展,然后使用: 80 | 81 | `window.addEventListener('message', function (event) {if (event.data.type === 'ExtensionResponse') {console.log(event.data.data);}});` 82 | 83 | 接收判断有没有安装盘络上传,并做出规避; 84 | 85 | 86 | -------------------------------------------------------------------------------- /自动插入支持.md: -------------------------------------------------------------------------------- 1 | **以下内容仅为经过开发者测试的,不排除未经测试也可以使用的情况** 2 | | / | 回复楼主 | 回复楼层 | 发帖 | 3 | | ---------------------- | ---------------- | ---------------- | ---------------- | 4 | | **程序** | 5 | | Discuz程序论坛 | 支持 | 支持 | 支持 | 6 | | Xiuno程序论坛 | 支持 | 支持 | 支持 | 7 | | phpbb程序论坛 | 支持 | 支持 | 支持 | 8 | | mybb程序论坛 | 支持(高级回复) | 支持(高级回复) | 支持 | 9 | | SMF程序论坛 | 支持 | 支持 | 支持 | 10 | | SForum论坛程序 | 支持(高级回复) | 支持(高级回复) | 支持 | 11 | | typecho博客 | 无 | 无 | 支持(文章) | 12 | | WordPress博客(6.2以上) | 无 | 无 | 支持 | 13 | | Halo建站(2.6以上) | 无 | 无 | 支持(默认编辑器) | 14 | | emlog博客 | 无 | 无 | 支持 | 15 | | zblog博客 | 无 | 无 | 支持 | 16 | | **编辑器** | 17 | | CodeMirror5/6 | 理论支持 | 理论支持 | 理论支持 | 18 | | TinyMCE | 理论支持 | 理论支持 | 理论支持 | 19 | | wangEditor | 理论支持 | 理论支持 | 理论支持 | 20 | | ckEditor4/5 | 理论支持 | 理论支持 | 理论支持 | 21 | | 古腾堡 | 理论支持 | 理论支持 | 理论支持 | 22 | | UEditor | 理论支持 | 理论支持 | 理论支持 | 23 | | editor.md | 理论支持 | 理论支持 | 理论支持 | 24 | | **站点** | 25 | | GitHub | 无 | 无 | 支持(在线编辑) | 26 | | 稀土掘金 | 不支持 | 不支持 | 支持 | 27 | | v2ex | 半支持(图片转换) | 半支持(图片转换) | 支持 | 28 | | liyuans | 支持 | 支持 | 支持 | 29 | | nodeseek | 支持 | 支持 | 支持 | 30 | | hostevaluate | 不支持 | 支持 | 支持 | 31 | | hostloc | 支持 | 支持 | 支持 | 32 | | 52破解 | 支持 | 支持 | 支持 | 33 | | 52辅助 | 支持 | 支持 | 支持 | 34 | | mcbbs | 支持 | 支持 | 支持 | 35 | | 藏宝湾 | 支持 | 支持 | 支持 | 36 | | 大佬论坛 | 支持(高级回复) | 不支持 | 支持 | 37 | | 西柚主机论坛 | 支持 | 支持 | 支持 | 38 | | lowendtalk | 支持 | 支持 | 支持 | -------------------------------------------------------------------------------- /Chromium/vendor/content_scripts/css/content_scripts.css: -------------------------------------------------------------------------------- 1 | #uploadArea { 2 | position: fixed; 3 | box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06); 4 | user-select: none; 5 | } 6 | 7 | #PL_JS_Alerts { 8 | position: fixed; 9 | bottom: 16px; 10 | right: 16px; 11 | } 12 | 13 | .PL_JS_Alert { 14 | border-radius: 0.5rem; 15 | text-align: center; 16 | background-color: #fff; 17 | border: 1px solid #ccc; 18 | margin: 1rem; 19 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); 20 | } 21 | 22 | .PL_JS_Title { 23 | color: white; 24 | background-color: #03A9F4; 25 | padding: .5rem; 26 | border-radius: 0.5rem 0.5rem 0rem 0rem; 27 | text-align: left; 28 | font-weight: bold; 29 | font-size: 1rem; 30 | } 31 | 32 | .PL_JS_Content { 33 | font-size: 1rem; 34 | padding-top: 1rem; 35 | padding-left: 1.5rem; 36 | padding-bottom: 1rem; 37 | padding-right: 1.5rem; 38 | border-bottom: 1px solid #eee; 39 | } 40 | 41 | .PL_JS_Countdown { 42 | text-align: right; 43 | font-size: 0.5rem; 44 | } 45 | 46 | #PNG_upload_prompt { 47 | font-size: 16px; 48 | position: fixed; 49 | top: 20%; 50 | left: 50%; 51 | color: white; 52 | transform: translate(-50%, -50%); 53 | background-color: #2196f3; 54 | border: 1px solid #eee; 55 | padding: 16px; 56 | text-align: center; 57 | } 58 | 59 | .PL-iframe { 60 | position: fixed; 61 | width: 780px !important; 62 | height: 100% !important; 63 | bottom: 0; 64 | border: none; 65 | transition: left right 0.4s ease; 66 | box-shadow: rgb(0 0 0 / 30%) 0px 0px 10px, rgba(0, 0, 0, 0.06) 0px 2px 4px; 67 | } 68 | 69 | .Functional_animation span { 70 | font-size: 2em; 71 | } 72 | 73 | .Functional_animation { 74 | top: 60%; 75 | position: absolute; 76 | bottom: 0; 77 | z-index: 9998; 78 | transition: left 3s ease; 79 | width: 200px; 80 | } 81 | 82 | .animation_finger { 83 | width: 155px; 84 | height: 200px; 85 | } 86 | 87 | .Functional_animation.active { 88 | right: 0%; 89 | } 90 | 91 | 92 | .PL-IframeBox { 93 | position: fixed; 94 | top: 0; 95 | left: 0; 96 | width: 100%; 97 | height: 100%; 98 | background-color: rgb(0 0 0 / 4%); 99 | } 100 | 101 | @keyframes box-shadow-Blink { 102 | 0% { 103 | box-shadow: rgb(0 0 0 / 30%) 0px 0px 10px, rgba(0, 0, 0, 0.06) 0px 2px 4px; 104 | } 105 | 106 | 50% { 107 | box-shadow: #3a86ff 0px 0px 10px, #3a86ff 0px 2px 4px; 108 | /* 闪烁的颜色 */ 109 | } 110 | 111 | 100% { 112 | box-shadow: rgb(0 0 0 / 30%) 0px 0px 10px, rgba(0, 0, 0, 0.06) 0px 2px 4px; 113 | } 114 | } 115 | 116 | /* 定义闪烁类 */ 117 | .box-shadow-Blink { 118 | animation: box-shadow-Blink 1s infinite; 119 | } 120 | 121 | .btn { 122 | color: #353535; 123 | background-color: #f2f2f2; 124 | border-color: #bfbfbf; 125 | } 126 | 127 | .btn-mini { 128 | padding: 1px 5px; 129 | font-size: 12px; 130 | line-height: 1.5; 131 | border-radius: 4px; 132 | } 133 | 134 | .btn-primary { 135 | color: #fff; 136 | background-color: #3280fc; 137 | border-color: #1970fc; 138 | } -------------------------------------------------------------------------------- /Chromium/vendor/content_scripts/css/FullDomPermissions.css: -------------------------------------------------------------------------------- 1 | .insertContentIntoEditorPrompt { 2 | text-align: center !important; 3 | font-size: 14px !important; 4 | max-width: 100px !important; 5 | color: #fff !important; 6 | padding: 5px 10px !important; 7 | font-weight: bold !important; 8 | cursor: pointer !important; 9 | transition: all 0.3s ease !important; 10 | position: relative !important; 11 | display: inline-block !important; 12 | outline: none !important; 13 | overflow: hidden !important; 14 | border-radius: 5px !important; 15 | border: none !important; 16 | background-color: #3a86ff !important; 17 | } 18 | 19 | .insertContentIntoEditorPrompt:hover { 20 | padding-right: 14px !important; 21 | padding-left: 12px !important; 22 | } 23 | 24 | .insertContentIntoEditorPrompt:hover:after { 25 | opacity: 1; 26 | right: 4px; 27 | } 28 | 29 | .insertContentIntoEditorPrompt:after { 30 | content: "\00BB"; 31 | position: absolute; 32 | opacity: 0; 33 | font-size: 14px; 34 | /* line-height: 14px; */ 35 | padding: 5px 0; 36 | top: 0; 37 | right: -20px; 38 | transition: 0.4s; 39 | } 40 | 41 | .PL-EmoticonBox { 42 | font-size: 14px; 43 | user-select: none; 44 | border-radius: 14px; 45 | width: 0px; 46 | height: 200px; 47 | background-color: #dddddd26; 48 | position: absolute; 49 | padding: 0; 50 | box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2); 51 | z-index: 1000; 52 | max-height: 200px; 53 | display: none; 54 | transition: width .5s ease; 55 | } 56 | 57 | .StickerBox { 58 | display: flex; 59 | flex-direction: column; 60 | } 61 | 62 | .StickerBoxRemove { 63 | position: absolute; 64 | width: 2em; 65 | line-height: 2em; 66 | top: -1em; 67 | right: -1em; 68 | border-radius: 50%; 69 | color: white; 70 | background-color: #F44336; 71 | text-align: center; 72 | } 73 | 74 | .StickerBoxLeft { 75 | display: none; 76 | position: absolute; 77 | left: -120px; 78 | top: 40px; 79 | width: 120px; 80 | height: 150px; 81 | background: #eee; 82 | border-radius: 14px 0px 0 14px; 83 | box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2); 84 | flex-direction: column; 85 | align-items: center; 86 | justify-content: center; 87 | 88 | } 89 | 90 | .StickerBoxLeftBut { 91 | position: absolute; 92 | top: 40px; 93 | left: 0px; 94 | font-size: 14px; 95 | line-height: 14px; 96 | text-align: center; 97 | } 98 | 99 | .StickerBoxright { 100 | display: flex; 101 | position: absolute; 102 | right: -155px; 103 | top: 40px; 104 | width: 150px; 105 | height: 160px; 106 | align-items: center; 107 | } 108 | 109 | .StickerBoxright img { 110 | max-height: 160px; 111 | } 112 | 113 | img { 114 | box-shadow: none !important; 115 | border: none !important; 116 | } 117 | 118 | .StickerBoxRemove:hover { 119 | background-color: #cf372c; 120 | 121 | } 122 | 123 | .StickerHead { 124 | height: 40px; 125 | } 126 | 127 | .StickerBoxhead { 128 | border-radius: 14px 14px 0 0; 129 | background-color: #0f62fe; 130 | color: white; 131 | display: flex; 132 | overflow-x: hidden; 133 | white-space: nowrap; 134 | padding: 0em 16px; 135 | /* 添加滚动条以处理溢出内容 */ 136 | } 137 | 138 | .StickerBoxhead:active { 139 | cursor: grabbing; 140 | /* 设置鼠标样式为“抓取中” */ 141 | } 142 | 143 | .StickerBoxheadtem { 144 | user-select: none; 145 | font-size: 16px; 146 | padding: 3px 16px !important; 147 | margin: 5px 0px !important; 148 | border-radius: 16px; 149 | text-align: center; 150 | } 151 | 152 | .StickerBoxheadtem:hover { 153 | background: #3a86ff; 154 | } 155 | 156 | .StickerBoxContent { 157 | height: 156px; 158 | display: flex; 159 | flex-wrap: wrap; 160 | margin-top: 4px; 161 | padding: 0 4px; 162 | justify-content: center; 163 | align-items: center; 164 | overflow: auto; 165 | } 166 | 167 | .StickerBoxContentitem { 168 | user-select: none; 169 | margin: 5px 170 | } 171 | 172 | .StickerBoxContentitem:hover { 173 | transform: scale3d(1.1, 1.1, 1.1); 174 | } 175 | 176 | .StickerBoxContentitem img { 177 | width: 54px; 178 | } 179 | 180 | .StickerAuthor { 181 | width: 100%; 182 | text-align: center; 183 | } 184 | 185 | .PL-v2exImgMark::before { 186 | position: absolute; 187 | bottom: 0px; 188 | right: 0; 189 | content: "❤️"; 190 | font-size: 12px; 191 | line-height: 12px; 192 | color: red; 193 | } 194 | 195 | .PL-ImgMark { 196 | width: 100%; 197 | } 198 | 199 | .PL-ImgMark::before { 200 | position: absolute; 201 | top: 0px; 202 | left: 0px; 203 | content: "❤️"; 204 | font-size: 12px; 205 | line-height: 12px; 206 | color: red; 207 | } 208 | 209 | .position-relative { 210 | position: relative; 211 | } -------------------------------------------------------------------------------- /Chromium/vendor/UploadLog/imagesloaded.pkgd.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * imagesLoaded PACKAGED v5.0.0 3 | * JavaScript is all like "You images are done yet or what?" 4 | * MIT License 5 | */ 6 | !function(t,e){"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,(function(){function t(){}let e=t.prototype;return e.on=function(t,e){if(!t||!e)return this;let i=this._events=this._events||{},s=i[t]=i[t]||[];return s.includes(e)||s.push(e),this},e.once=function(t,e){if(!t||!e)return this;this.on(t,e);let i=this._onceEvents=this._onceEvents||{};return(i[t]=i[t]||{})[e]=!0,this},e.off=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;let s=i.indexOf(e);return-1!=s&&i.splice(s,1),this},e.emitEvent=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;i=i.slice(0),e=e||[];let s=this._onceEvents&&this._onceEvents[t];for(let n of i){s&&s[n]&&(this.off(t,n),delete s[n]),n.apply(this,e)}return this},e.allOff=function(){return delete this._events,delete this._onceEvents,this},t})), 7 | /*! 8 | * imagesLoaded v5.0.0 9 | * JavaScript is all like "You images are done yet or what?" 10 | * MIT License 11 | */ 12 | function(t,e){"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}("undefined"!=typeof window?window:this,(function(t,e){let i=t.jQuery,s=t.console;function n(t,e,o){if(!(this instanceof n))return new n(t,e,o);let r=t;var h;("string"==typeof t&&(r=document.querySelectorAll(t)),r)?(this.elements=(h=r,Array.isArray(h)?h:"object"==typeof h&&"number"==typeof h.length?[...h]:[h]),this.options={},"function"==typeof e?o=e:Object.assign(this.options,e),o&&this.on("always",o),this.getImages(),i&&(this.jqDeferred=new i.Deferred),setTimeout(this.check.bind(this))):s.error(`Bad element for imagesLoaded ${r||t}`)}n.prototype=Object.create(e.prototype),n.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)};const o=[1,9,11];n.prototype.addElementImages=function(t){"IMG"===t.nodeName&&this.addImage(t),!0===this.options.background&&this.addElementBackgroundImages(t);let{nodeType:e}=t;if(!e||!o.includes(e))return;let i=t.querySelectorAll("img");for(let t of i)this.addImage(t);if("string"==typeof this.options.background){let e=t.querySelectorAll(this.options.background);for(let t of e)this.addElementBackgroundImages(t)}};const r=/url\((['"])?(.*?)\1\)/gi;function h(t){this.img=t}function d(t,e){this.url=t,this.element=e,this.img=new Image}return n.prototype.addElementBackgroundImages=function(t){let e=getComputedStyle(t);if(!e)return;let i=r.exec(e.backgroundImage);for(;null!==i;){let s=i&&i[2];s&&this.addBackground(s,t),i=r.exec(e.backgroundImage)}},n.prototype.addImage=function(t){let e=new h(t);this.images.push(e)},n.prototype.addBackground=function(t,e){let i=new d(t,e);this.images.push(i)},n.prototype.check=function(){if(this.progressedCount=0,this.hasAnyBroken=!1,!this.images.length)return void this.complete();let t=(t,e,i)=>{setTimeout((()=>{this.progress(t,e,i)}))};this.images.forEach((function(e){e.once("progress",t),e.check()}))},n.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount===this.images.length&&this.complete(),this.options.debug&&s&&s.log(`progress: ${i}`,t,e)},n.prototype.complete=function(){let t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){let t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},h.prototype=Object.create(e.prototype),h.prototype.check=function(){this.getIsImageComplete()?this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.img.crossOrigin&&(this.proxyImage.crossOrigin=this.img.crossOrigin),this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.proxyImage.src=this.img.currentSrc||this.img.src)},h.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},h.prototype.confirm=function(t,e){this.isLoaded=t;let{parentNode:i}=this.img,s="PICTURE"===i.nodeName?i:this.img;this.emitEvent("progress",[this,s,e])},h.prototype.handleEvent=function(t){let e="on"+t.type;this[e]&&this[e](t)},h.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},h.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},h.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype=Object.create(h.prototype),d.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url,this.getIsImageComplete()&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},d.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},n.makeJQueryPlugin=function(e){(e=e||t.jQuery)&&(i=e,i.fn.imagesLoaded=function(t,e){return new n(this,t,e).jqDeferred.promise(i(this))})},n.makeJQueryPlugin(),n})); 13 | -------------------------------------------------------------------------------- /Chromium/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 上传程序 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 51 |
52 |

53 |

54 | 55 |
56 |
58 |
59 |
60 | 97 | 98 | 107 |
108 |
109 | 110 | 111 | -------------------------------------------------------------------------------- /Chromium/vendor/content_scripts/css/notification.css: -------------------------------------------------------------------------------- 1 | .notification-container { 2 | padding: 14px 18px; 3 | max-width: 80%; 4 | position: fixed; 5 | right: 0; 6 | bottom: 0; 7 | display: flex; 8 | flex-direction: column; 9 | align-items: flex-end; 10 | 11 | .notification { 12 | min-width: 200px; 13 | background-color: #fff; 14 | border: 1px solid #ccc; 15 | border-radius: 4px; 16 | padding: 10px; 17 | margin: 10px 0; 18 | max-width: 100%; 19 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); 20 | display: flex; 21 | flex-direction: column; 22 | position: relative; 23 | transition: transform 0.5s; 24 | 25 | & button { 26 | padding: 0; 27 | margin: 0; 28 | user-select: none; 29 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); 30 | } 31 | 32 | .progress-bar { 33 | color: white; 34 | font-size: 8px; 35 | line-height: 8px; 36 | text-align: end; 37 | height: 8px; 38 | position: absolute; 39 | bottom: 0; 40 | left: 0; 41 | width: 100%; 42 | animation: PLprogress 5s linear; 43 | border-radius: 2px; 44 | } 45 | } 46 | } 47 | 48 | .notification-title { 49 | display: flex; 50 | align-items: center; 51 | font-weight: bold; 52 | user-select: none; 53 | 54 | .icon { 55 | margin: 0px 4px 0px 0px !important; 56 | width: 32px !important; 57 | height: 32px !important; 58 | 59 | & svg { 60 | background: none !important; 61 | margin: 0 !important; 62 | padding: 0 !important; 63 | } 64 | } 65 | 66 | .title { 67 | margin: 0 !important; 68 | font-size: 18px !important; 69 | } 70 | } 71 | 72 | .notification-content { 73 | font-size: 14px; 74 | margin: 10px 0; 75 | } 76 | 77 | .notification .close { 78 | border-radius: 50% !important; 79 | width: 24px !important; 80 | height: 24px !important; 81 | border: none !important; 82 | position: absolute !important; 83 | right: -8px !important; 84 | top: -8px !important; 85 | font-size: 16px !important; 86 | opacity: 1 !important; 87 | } 88 | 89 | .notification .reduce { 90 | border: none !important; 91 | width: 16px !important; 92 | height: 100% !important; 93 | position: absolute !important; 94 | top: 0 !important; 95 | left: -14px !important; 96 | font-size: 16px !important; 97 | opacity: 1 !important; 98 | } 99 | 100 | .notification .reduce:hover { 101 | transform: none !important; 102 | } 103 | 104 | .notification .reduceActive { 105 | width: 100px; 106 | overflow: hidden; 107 | white-space: nowrap; 108 | text-overflow: ellipsis; 109 | } 110 | 111 | .notification button:hover { 112 | transform: scale3d(1.1, 1.1, 1.1) !important; 113 | } 114 | 115 | .notification button:disabled { 116 | opacity: 0.65; 117 | transform: none !important; 118 | } 119 | 120 | .notification hr { 121 | border: none; 122 | padding: 0; 123 | margin: 5px 0; 124 | border-bottom-width: 2px; 125 | border-bottom-style: solid; 126 | } 127 | 128 | .notification.info { 129 | background-color: #eee; 130 | border-color: #dddddd; 131 | color: #444; 132 | 133 | & hr { 134 | border-bottom-color: #aaa; 135 | } 136 | 137 | & button { 138 | background: #444; 139 | color: white; 140 | } 141 | 142 | & button:hover { 143 | background: #333; 144 | } 145 | 146 | .progress-bar { 147 | background-color: #aaa; 148 | } 149 | } 150 | 151 | .notification.success { 152 | background-color: #d4edda; 153 | border-color: #c3e6cb; 154 | color: #155724; 155 | 156 | & hr { 157 | border-bottom-color: #4CAF50; 158 | 159 | } 160 | 161 | & button { 162 | background: #33CC00; 163 | color: white; 164 | } 165 | 166 | & button:hover { 167 | background: #009900; 168 | } 169 | 170 | & button:disabled { 171 | background: #33CC00; 172 | } 173 | 174 | .progress-bar { 175 | background-color: #33cc00; 176 | } 177 | 178 | } 179 | 180 | .notification.warning { 181 | background-color: #fff3cd; 182 | border-color: #ffeeba; 183 | color: #856404; 184 | 185 | & hr { 186 | border-bottom-color: #FFC107; 187 | } 188 | 189 | & button { 190 | background: #ff9900; 191 | color: white; 192 | } 193 | 194 | & button:hover { 195 | background: #ff6600; 196 | } 197 | 198 | & button:disabled { 199 | background: #ff9900; 200 | } 201 | 202 | .progress-bar { 203 | background-color: #ff9900; 204 | } 205 | } 206 | 207 | .notification.error { 208 | background-color: #f8d7da; 209 | border-color: #f5c6cb; 210 | color: #721c24; 211 | 212 | & hr { 213 | border-bottom-color: #FF5722; 214 | } 215 | 216 | & button { 217 | background: #FF3333; 218 | color: white; 219 | } 220 | 221 | & button:hover { 222 | background: #dc3545; 223 | } 224 | 225 | & button:disabled { 226 | background: #FF3333; 227 | } 228 | 229 | .progress-bar { 230 | background-color: #f44336; 231 | } 232 | } 233 | 234 | @keyframes PLprogress { 235 | 0% { 236 | width: 100%; 237 | } 238 | 239 | 100% { 240 | width: 0; 241 | } 242 | } -------------------------------------------------------------------------------- /Chromium/vendor/UploadLog/jquery.twbsPagination.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Bootstrap Pagination v1.4.2 3 | * https://github.com/josecebe/twbs-pagination 4 | * 5 | * Copyright 2014-2018, Eugene Simakin 6 | * Released under Apache-2.0 license 7 | * http://apache.org/licenses/LICENSE-2.0.html 8 | */ 9 | 10 | !function(o,e,t,s){"use strict";var i=o.fn.twbsPagination,r=function(t,s){if(this.$element=o(t),this.options=o.extend({},o.fn.twbsPagination.defaults,s),this.options.startPage<1||this.options.startPage>this.options.totalPages)throw new Error("Start page option is incorrect");if(this.options.totalPages=parseInt(this.options.totalPages),isNaN(this.options.totalPages))throw new Error("Total pages option is not correct!");if(this.options.visiblePages=parseInt(this.options.visiblePages),isNaN(this.options.visiblePages))throw new Error("Visible pages option is not correct!");if(this.options.beforePageClick instanceof Function&&this.$element.first().on("beforePage",this.options.beforePageClick),this.options.onPageClick instanceof Function&&this.$element.first().on("page",this.options.onPageClick),this.options.hideOnlyOnePage&&1==this.options.totalPages)return this.options.initiateStartPageClick&&this.$element.trigger("page",1),this;if(this.options.href&&(this.options.startPage=this.getPageFromQueryString(),this.options.startPage||(this.options.startPage=1)),"UL"===("function"==typeof this.$element.prop?this.$element.prop("tagName"):this.$element.attr("tagName")))this.$listContainer=this.$element;else{var e=this.$element,i=o([]);e.each(function(t){var s=o("
    ");o(this).append(s),i.push(s[0])}),this.$listContainer=i,this.$element=i}return this.$listContainer.addClass(this.options.paginationClass),this.options.initiateStartPageClick?this.show(this.options.startPage):(this.currentPage=this.options.startPage,this.render(this.getPages(this.options.startPage)),this.setupEvents()),this};r.prototype={constructor:r,destroy:function(){return this.$element.empty(),this.$element.removeData("twbs-pagination"),this.$element.off("page"),this},show:function(t){if(t<1||t>this.options.totalPages)throw new Error("Page is incorrect.");this.currentPage=t,this.$element.trigger("beforePage",t);var s=this.getPages(t);return this.render(s),this.setupEvents(),this.$element.trigger("page",t),s},enable:function(){this.show(this.currentPage)},disable:function(){var t=this;this.$listContainer.off("click").on("click","li",function(t){t.preventDefault()}),this.$listContainer.children().each(function(){o(this).hasClass(t.options.activeClass)||o(this).addClass(t.options.disabledClass)})},buildListItems:function(t){var s=[];if(this.options.first&&s.push(this.buildItem("first",1)),this.options.prev){var e=1"),i=o(""),a=this.options[t]?this.makeText(this.options[t],s):s;return e.addClass(this.options[t+"Class"]),e.data("page",s),e.data("page-type",t),e.append(i.attr("href",this.makeHref(s)).addClass(this.options.anchorClass).html(a)),e},getPages:function(t){var s=[],e=Math.floor(this.options.visiblePages/2),i=t-e+1-this.options.visiblePages%2,a=t+e,n=this.options.visiblePages;n>this.options.totalPages&&(n=this.options.totalPages),i<=0&&(i=1,a=n),a>this.options.totalPages&&(i=this.options.totalPages-n+1,a=this.options.totalPages);for(var o=i;o<=a;)s.push(o),o++;return{currentPage:t,numeric:s}},render:function(s){var e=this;this.$listContainer.children().remove();var t=this.buildListItems(s);o.each(t,function(t,s){e.$listContainer.append(s)}),this.$listContainer.children().each(function(){var t=o(this);switch(t.data("page-type")){case"page":t.data("page")===s.currentPage&&t.addClass(e.options.activeClass);break;case"first":t.toggleClass(e.options.disabledClass,1===s.currentPage);break;case"last":t.toggleClass(e.options.disabledClass,s.currentPage===e.options.totalPages);break;case"prev":t.toggleClass(e.options.disabledClass,!e.options.loop&&1===s.currentPage);break;case"next":t.toggleClass(e.options.disabledClass,!e.options.loop&&s.currentPage===e.options.totalPages)}})},setupEvents:function(){var e=this;this.$listContainer.off("click").on("click","li",function(t){var s=o(this);if(s.hasClass(e.options.disabledClass)||s.hasClass(e.options.activeClass))return!1;!e.options.href&&t.preventDefault(),e.show(parseInt(s.data("page")))})},changeTotalPages:function(t,s){return this.options.totalPages=t,this.show(s)},makeHref:function(t){return this.options.href?this.generateQueryString(t):"#"},makeText:function(t,s){return t.replace(this.options.pageVariable,s).replace(this.options.totalPagesVariable,this.options.totalPages)},getPageFromQueryString:function(t){var s=this.getSearchString(t),e=new RegExp(this.options.pageVariable+"(=([^&#]*)|&|#|$)").exec(s);return e&&e[2]?(e=decodeURIComponent(e[2]),e=parseInt(e),isNaN(e)?null:e):null},generateQueryString:function(t,s){var e=this.getSearchString(s),i=new RegExp(this.options.pageVariable+"=*[^&#]*");return e?"?"+e.replace(i,this.options.pageVariable+"="+t):""},getSearchString:function(t){var s=t||e.location.search;return""===s?null:(0===s.indexOf("?")&&(s=s.substr(1)),s)},getCurrentPage:function(){return this.currentPage},getTotalPages:function(){return this.options.totalPages}},o.fn.twbsPagination=function(t){var s,e=Array.prototype.slice.call(arguments,1),i=o(this),a=i.data("twbs-pagination"),n="object"==typeof t?t:{};return a||i.data("twbs-pagination",a=new r(this,n)),"string"==typeof t&&(s=a[t].apply(a,e)),void 0===s?i:s},o.fn.twbsPagination.defaults={totalPages:1,startPage:1,visiblePages:5,initiateStartPageClick:!0,hideOnlyOnePage:!1,href:!1,pageVariable:"{{page}}",totalPagesVariable:"{{total_pages}}",page:null,first:"First",prev:"Previous",next:"Next",last:"Last",loop:!1,beforePageClick:null,onPageClick:null,paginationClass:"pagination",nextClass:"page-item next",prevClass:"page-item prev",lastClass:"page-item last",firstClass:"page-item first",pageClass:"page-item",activeClass:"active",disabledClass:"disabled",anchorClass:"page-link"},o.fn.twbsPagination.Constructor=r,o.fn.twbsPagination.noConflict=function(){return o.fn.twbsPagination=i,this},o.fn.twbsPagination.version="1.4.2"}(window.jQuery,window,document); -------------------------------------------------------------------------------- /版本更新.md: -------------------------------------------------------------------------------- 1 | ### 1.1.7更新: 2 | 3 | 1.新增自动插入管理,用于管理自动插入的域名与插入类型。 4 | 5 | 2.新增兰空图床,简单图床 Chevereto图床的token页面可以一键配置扩展。 6 | 7 | 3.新增上传记录图片插入到编辑框功能,与上传成功时的自动插入公用方法。 8 | 9 | 4.优化上传记录本地数据效果,删除图片自动计算剩余页数并替补。 10 | 11 | 5.优化自动插入逻辑,域名与插入类型绑定,下次插入自动调取该类型方法。 12 | 13 | 6.优化导入配置,当导入的配置只有一个时默认启动它 14 | 15 | 7.优化程序选中与启用配置的区分,(启用程序名称前有个⚪点) 16 | 17 | 8.优化上传记录中的排序状态显示 18 | 19 | 9.修复Telegra.ph在编辑框粘贴/页面拖拽/右键上传时自定义访问域名无效的问题 20 | 21 | 10.修复表情贴纸会被遮挡的问题。 22 | 23 | 11.修复chevereto上传失败的bug。 24 | 25 | 12.配置记录与上传记录和表情贴纸改用indexed DB存储,更新完毕后打开配置页数据将自动迁移到indexed DB。 26 | 27 | ————————————— 28 | 29 | ### 1.1.6.2更新: 30 | 31 | 1.新增加功能按钮开关状态 32 | 33 | 2.修复右键上传/拖拽上传文件名固定为png的问题,更改为获取url后缀如果没有后缀默认png。 34 | 35 | 3.修复GitHub注入页粘贴/拖拽上传失败的问题。 36 | 37 | 4.解除递归上传限制,恢复同步上传(github除外)。 38 | 39 | 5.优化自定义上传,更多更全的配置 40 | 41 | 6.优化配置存储逻辑 42 | 43 | 7.修改错误英文/完善未完成的语言支持 44 | 45 | 注意:本版本出现破坏性修改,无法继承上一个版本的配置,更新后将使用默认设置。如无法使用,请尝试重新开关扩展! 46 | 47 | ————————————— 48 | 49 | ### 1.1.6.1更新: 50 | 51 | 1.新增配置分享功能 52 | 53 | 2.新增配置导入功能(配置追加/配置替换) 54 | 55 | 3.新增配置记录,记录拖拽排序功能 56 | 57 | 4.页面注入代码优化,实现了侧边栏更换图床时免刷新右键/拖拽/粘贴上传 58 | 59 | 5.修复自定义上传的记录url错误问题 60 | 61 | 6.修复关闭拖拽上传,上传状态不显示问题 62 | 63 | 7.修复对象存储右键上传/拖拽上传的bug问题 64 | 65 | ————————————— 66 | 67 | ### 1.1.6更新: 68 | 69 | 1.新增页面的侧边栏拖拽移动,长按侧边栏可以拖拽移到更改位置 70 | 71 | 2.新增侧边栏打开后自动聚焦,可以直接粘贴内容,无需点一次页面再粘贴 72 | 73 | 4.新增加58图床,免登录 74 | 75 | 5.新增加百度图床,百度cookie登录 76 | 77 | 6.新增加freebuf图床,免登录 78 | 79 | 7.新增加今日头条图床,免登录 80 | 81 | 8.新增加图片代理功能,当图片上传完成或者复制的时候向链接插入代理服务器 82 | 83 | 9.新增加编辑框粘贴功能,开启后在编辑框粘贴本地资源可以对资源进行上传 84 | 85 | 10.修复GitHub本地上传记录出错的问题 86 | 87 | 11.修复oss,s3,GitHub没有上传中的状态的问题 88 | 89 | 12.修复配置页面侧边栏选项的重置按钮会多次触发的问题 90 | 91 | 13.修复上传记录打开目录路径错误的问题 92 | 93 | 14.连接转换图片优化 94 | 95 | 15.wp博客经典编辑器的自动插入支持 96 | 97 | ————————————— 98 | 99 | ### 1.1.5.2更新: 100 | 101 | 1.链接转图片优化,不在依据图片后缀转换,改成是链接就转换,然后依据onerror事件,当图片不正确时删除元素。 102 | 103 | 2.新增配置记录,可以在多图床之间自由切换 104 | 105 | 3.配置页面ui优化 106 | 107 | 4.上传记录ul优化,主要解决文字溢出问题 108 | 109 | 5.贴纸优化,减少每次网络请求次数改用懒加载技术,从全部加载改成每次显示20张 110 | 111 | ————————————— 112 | 113 | ### 1.1.5.1更新: 114 | 115 | 1.mybb论坛程序适配 116 | 117 | 2.SMF论坛程序适配 118 | 119 | 3.SForum论坛程序适配 120 | 121 | 4.CodeMirror6编辑器适配 122 | 123 | 5.v2ex社区图片优化,后缀为【.png,.jpg,.jpeg,.gif,.bmp,.webp,.ico】的链接自动转换为图片,并在图片右下角显示❤表示经过转换 124 | 125 | 6.nodeseek社区图片优化,后缀为【.png,.jpg,.jpeg,.gif,.bmp,.webp,.ico】的链接自动转换为图片,并在图片左上角显示❤表示经过转换 126 | 127 | 7.Discuz社区图片优化,后缀为【.png,.jpg,.jpeg,.gif,.bmp,.webp,.ico】的链接自动转换为图片,并在图片左上角显示❤表示经过转换 128 | 129 | 8.Discuz论坛贴纸插入逻辑优化 130 | 131 | 9.页面盘络按钮逻辑优化,能够更精准的识别站点是否支持自动插入 132 | 133 | 10.贴纸使用体验优化,用户点开的贴纸包得到保存,切换页面也不会丢失。 134 | 135 | #修复: 136 | 137 | 1.修复GitHub自动插入问题 138 | 139 | ————————————— 140 | 141 | ### 1.1.5更新: 142 | 143 | #修复: 144 | 145 | 1.版本迭代 146 | 147 | #已知问题 148 | 149 | 待发现 150 | 151 | ————————————— 152 | ### 1.1.4.3更新: 153 | 154 | #修复: 155 | 156 | 1.修复贴纸标题错误问题 157 | 158 | 2.优化贴纸数据请求方式,提高使用体验 159 | 160 | #已知问题 161 | 162 | 待发现 163 | 164 | ————————————— 165 | 166 | ### 1.1.4.2更新: 167 | 168 | 1.新增自动复制,允许上传完成后自动将url复制到剪切板。默认关闭 169 | 170 | 2.新增页面上传状态条 171 | 172 | 3.新增表情贴纸功能,鼠标移到页面上的盘络按钮1秒后显示,调用自动插入功能写入。支持站点参考(自动插入支持.md) 173 | 174 | 4.新增phpbb程序,lowendtalk论坛的自动插入支持 175 | 176 | #修复: 177 | 178 | 1.修复侧边栏在某些站点显示错误问题 179 | 180 | 2.修复右键/拖拽 自定义上传返回参数错误问题 181 | 182 | #已知问题 183 | 184 | 待发现 185 | 186 | ————————————— 187 | 188 | ### 1.1.4.1更新: 189 | 190 | #修复: 191 | 192 | 1.提示信息错误修复 193 | 194 | 2.修复上传页面删除文件切页数据还在的问题 195 | 196 | 3.修复discuz自动插入部分不含discuz字符主题无法插入图片问题。 197 | 198 | #已知问题 199 | 200 | 待发现 201 | 202 | ————————————— 203 | 204 | ### 1.1.4更新: 205 | 206 | 1.上传记录新增判断非图片文件无法打开预览功能 207 | 208 | 2.新增复制多个数据时,数据换行 209 | 210 | 3.新增加上传页面图片预览动画效果 211 | 212 | 4.新增图片Loading,删除图片Loading效果 213 | 214 | #修复: 215 | 216 | 1.修复演示模式粘贴上传的元素错位导致无法点击问题 217 | 218 | 2.页面注入代码逻辑优化 219 | 220 | 3.上传模式的模块化,更易于上传适配 221 | 222 | #已知问题 223 | 224 | 待发现 225 | 226 | ————————————— 227 | 228 | ### 1.1.3.1更新: 229 | 230 | 1.tg新增自定义域名 231 | 232 | #修复: 233 | 234 | 1.修复tg上传返回路径错误问题 235 | 236 | #已知问题 237 | 238 | 待发现 239 | 240 | ————————————— 241 | 242 | ### 1.1.3更新: 243 | 244 | 1.新增选择按钮. 245 | 246 | 2.新增文件浏览模式,在上传页面点击图片时会打开浏览模式. 247 | 248 | 3.新增路径输入框,在上传页面可以输入路径进入指定文件夹或点击文件夹进入. 249 | 250 | 4.新增时间排序,可以选择:时间最先排序,时间最后排序. 251 | 252 | 5.新增大小排序,可以选择:最大排序,最小排序. 253 | 254 | 6.新增imgdd图床. 255 | 256 | #修复: 257 | 258 | 1.暂无 259 | 260 | #已知问题 261 | 262 | 待发现 263 | 264 | ————————————— 265 | 266 | ### 1.1.2更新: 267 | 268 | #修复: 269 | 270 | 1.修复简单图床上传无法返回url问题 271 | 272 | 2.修复上传记录页面删除失败问题 273 | 274 | 3.异步上传更改为递归上传,防止记录存储失败! 275 | 276 | #已知问题 277 | 278 | 待发现 279 | 280 | ————————————— 281 | 282 | ### 1.1.1更新: 283 | 284 | 1.新增加TG图床适配 285 | 286 | #修复: 287 | 288 | 1.修复GitHub跨域请求bug 289 | 290 | 2.修复imgurl上传错误问题 291 | 292 | 3.修复自定义上传不能返回数据的bug 293 | 294 | 4.修复上传记录页面错误数据到账页面无响应的bug 295 | 296 | 4.优化Chevereto可能会出现错误的bug 297 | 298 | #已知问题 299 | 300 | 待发现 301 | 302 | ————————————— 303 | 304 | ### 1.1.0更新: 305 | 306 | 一.新增GitHub上传 307 | 308 | 二.新增Firefox浏览器支持 309 | 310 | 三.支持Halo默认编辑器自动插入 311 | 312 | 四.Chevereto图床新增加相册ID选项 313 | 314 | 五.Chevereto图床新增加nsfw选项 315 | 316 | 六.Chevereto图床新增加删除时间选项 317 | 318 | 七.兰空图床新增加隐私选择 319 | 320 | 八.兰空图床新增加相册选择 321 | 322 | 九.新增全局上传支持在线url解析上传 323 | 324 | 十.新增版本查看按钮(点击查询GitHub上的最新版本) 325 | 326 | 十一.移除了手势上传功能 327 | 328 | #修复: 329 | 330 | 1.已修复:对象存储上传速度过快导致本地记录失败(解决中) 331 | 332 | 2.已修复:古腾堡或其他编辑器上传过快,信息插入重复问题 333 | 334 | #已知问题 335 | 336 | 待发现 337 | 338 | ————————————— 339 | 340 | ### 1.0.9.1更新: 341 | 342 | 一.新增自动插入功能(默认开启) 343 | 344 | 二.新增页面插入提示,当页面有"😍盘络"按钮时表示该页面受支持的,"😭盘络"时表示页面受支持但是无法插入.如果没有按钮表示不受支持或按钮初始化失败,具体支持详细查看(https://fileup.dev/#page2/3) 345 | 346 | 三.修复bug 347 | 348 | #已知BUG: 349 | 350 | 对象存储上传速度过快导致本地记录失败(解决中) 351 | 352 | 手势上传与全局上传会被鼠标手势插件影响(待解决) 353 | 354 | ————————————— 355 | 356 | ### 1.0.9更新: 357 | 358 | 一.新增腾讯云对象存储(COS)功能(本地直传,不经服务器) 359 | 360 | 二.新增阿里云对象存储(OSS)功能(本地直传,不经服务器) 361 | 362 | 三.新增AWS S3对象存储(S3)并支持S3接口兼容(本地直传,不经服务器) 363 | 364 | 四.上传记录页面重构,支持对象存储的字符串读取如html,javascript,python,cpp,txt等字符串文本读取,支持MP3,MP4流媒体展示,压缩包,office等文件的识别! 365 | 366 | 五.腾讯云,阿里云,S3对象存储支持一键设置CORS,其中腾讯云,阿里云支持访问权限设置. 367 | 368 | 六.优化画圈手势上传逻辑 369 | 370 | 七.新增对象存储均支持手势和全局以及右键上传! 371 | 372 | 八.修复已知BUG(真的修复了,但是我又忘了具体是哪个) 373 | 374 | #已知BUG: 375 | 376 | 对象存储上传速度过快导致本地记录失败 377 | 378 | 手势上传与全局上传会被鼠标手势插件影响 379 | 380 | ————————————— 381 | ### 1.0.8.1更新: 382 | 383 | 新增侧边栏设置功能 384 | 385 | 优化页面侧边栏效果 386 | 387 | 美化程序UI 388 | 389 | 修复已知bug 390 | 391 | ————————————— 392 | 393 | ### 1.0.8更新: 394 | 395 | 新增画圈手势上传功能 396 | 397 | 新增全局本地上传功能 398 | 399 | 新增右键上传开关 400 | 401 | 新增全选,选中复制,选中删除等功能 402 | 403 | 修复上传页面的多重执行造成的性能bug 404 | 405 | 优化上传逻辑,减少重复性代码,响应号召减少碳排放 406 | 407 | 优化程序UI,包含上传页面,配置页面,常见问题 408 | 409 | ————————————— 410 | 411 | ### 1.0.7更新: 412 | 413 | 新增自定义上传配置信息 414 | 415 | 新增windows通知提示 416 | 417 | 修复上传页删除图片时链接框出错的问题 418 | 419 | 修复配置页面样式不统一的问题 420 | 421 | ————————————— 422 | 423 | ### 1.0.6更新: 424 | 425 | 新增新的UI交互 426 | 427 | 新增上传日志可以读取图床相册功能 428 | 429 | 优化上传成功后的UI,点击图片时对应的URL常亮 430 | 431 | 优化Hellohao图床程序,从邮箱密码改成Token 432 | 433 | 允许读取服务器相册的图床:兰空,SM,Hellohao 434 | 435 | ————————————— 436 | 437 | ### 1.0.5更新: 438 | 439 | 更换了主题 440 | 441 | 修复了BUG 442 | 443 | ————————————— 444 | 445 | ### 1.0.4更新: 446 | 447 | 新增右键上传到图床功能 448 | 449 | 新增图片上传记录功能 450 | 451 | 还修复了乱七八糟的问题 452 | 453 | ————————————— 454 | 455 | ### 1.0.3更新: 456 | 457 | 优化上传逻辑 458 | 459 | 修复FAQ页面图片异常 460 | -------------------------------------------------------------------------------- /Chromium/vendor/dropzone/css/dropzone.css: -------------------------------------------------------------------------------- 1 | @keyframes passing-through { 2 | 0% { 3 | opacity: 0; 4 | transform: translateY(40px) 5 | } 6 | 7 | 30%, 8 | 70% { 9 | opacity: 1; 10 | transform: translateY(0px) 11 | } 12 | 13 | 100% { 14 | opacity: 0; 15 | transform: translateY(-40px) 16 | } 17 | } 18 | 19 | @keyframes slide-in { 20 | 0% { 21 | opacity: 0; 22 | transform: translateY(40px) 23 | } 24 | 25 | 30% { 26 | opacity: 1; 27 | transform: translateY(0px) 28 | } 29 | } 30 | 31 | @keyframes pulse { 32 | 0% { 33 | transform: scale(1) 34 | } 35 | 36 | 10% { 37 | transform: scale(1.1) 38 | } 39 | 40 | 20% { 41 | transform: scale(1) 42 | } 43 | } 44 | 45 | .dropzone, 46 | .dropzone * { 47 | box-sizing: border-box 48 | } 49 | 50 | .dropzone { 51 | min-height: 100px; 52 | border: 1px solid rgba(0, 0, 0, .8); 53 | border-radius: 5px; 54 | padding: 20px 20px 55 | } 56 | 57 | .dropzone.dz-clickable { 58 | cursor: pointer 59 | } 60 | 61 | .dropzone.dz-clickable * { 62 | cursor: default 63 | } 64 | 65 | .dropzone.dz-clickable .dz-message, 66 | .dropzone.dz-clickable .dz-message * { 67 | cursor: pointer 68 | } 69 | 70 | .dropzone.dz-started .dz-message { 71 | display: none 72 | } 73 | 74 | .dropzone.dz-drag-hover { 75 | border-style: solid 76 | } 77 | 78 | .dropzone.dz-drag-hover .dz-message { 79 | opacity: .5 80 | } 81 | 82 | .dropzone .dz-message { 83 | text-align: center; 84 | width: 100%; 85 | position: absolute; 86 | left: 50%; 87 | top: 50%; 88 | transform: translate(-50%, -50%); 89 | } 90 | 91 | .dropzone .dz-message .dz-button { 92 | background: none; 93 | color: inherit; 94 | border: none; 95 | padding: 0; 96 | font: inherit; 97 | cursor: pointer; 98 | outline: inherit 99 | } 100 | 101 | .dropzone .dz-preview { 102 | position: relative; 103 | display: inline-block; 104 | vertical-align: top; 105 | margin: 16px; 106 | min-height: 100px 107 | } 108 | 109 | .dropzone .dz-preview:hover { 110 | z-index: 1000 111 | } 112 | 113 | .dropzone .dz-preview:hover .dz-details { 114 | opacity: 1 115 | } 116 | 117 | .dropzone .dz-preview.dz-file-preview .dz-image { 118 | border-radius: 20px; 119 | background: #999; 120 | background: linear-gradient(to bottom, #eee, #ddd) 121 | } 122 | 123 | .dropzone .dz-preview.dz-file-preview .dz-details { 124 | opacity: 1 125 | } 126 | 127 | .dropzone .dz-preview.dz-image-preview { 128 | background: #fff 129 | } 130 | 131 | .dropzone .dz-preview.dz-image-preview .dz-details { 132 | transition: opacity .2s linear 133 | } 134 | 135 | .dropzone .dz-preview .dz-remove { 136 | margin-top: 1rem; 137 | font-size: 14px; 138 | text-align: center; 139 | display: block; 140 | cursor: pointer; 141 | border: none 142 | } 143 | 144 | .dropzone .dz-preview .dz-remove:hover { 145 | text-decoration: underline 146 | } 147 | 148 | .dropzone .dz-preview:hover .dz-details { 149 | opacity: 1 150 | } 151 | 152 | .dropzone .dz-preview .dz-details { 153 | z-index: 20; 154 | position: absolute; 155 | top: 0; 156 | left: 0; 157 | opacity: 0; 158 | font-size: 13px; 159 | min-width: 100%; 160 | max-width: 100%; 161 | padding: 2em 1em; 162 | text-align: center; 163 | color: rgba(0, 0, 0, .9); 164 | line-height: 150% 165 | } 166 | 167 | .dropzone .dz-preview .dz-details .dz-size { 168 | margin-bottom: 1em; 169 | font-size: 16px 170 | } 171 | 172 | .dropzone .dz-preview .dz-details .dz-filename { 173 | white-space: nowrap 174 | } 175 | 176 | .dropzone .dz-preview .dz-details .dz-filename:hover span { 177 | border: 1px solid rgba(200, 200, 200, .8); 178 | background-color: rgba(255, 255, 255, .8) 179 | } 180 | 181 | .dropzone .dz-preview .dz-details .dz-filename:not(:hover) { 182 | overflow: hidden; 183 | text-overflow: ellipsis 184 | } 185 | 186 | .dropzone .dz-preview .dz-details .dz-filename:not(:hover) span { 187 | border: 1px solid transparent 188 | } 189 | 190 | .dropzone .dz-preview .dz-details .dz-filename span, 191 | .dropzone .dz-preview .dz-details .dz-size span { 192 | background-color: rgba(255, 255, 255, .4); 193 | padding: 0 .4em; 194 | border-radius: 3px 195 | } 196 | 197 | .dropzone .dz-preview:hover .dz-image img { 198 | transform: scale(1.05, 1.05); 199 | filter: blur(8px) 200 | } 201 | 202 | .dropzone .dz-preview .dz-image { 203 | border-radius: 20px; 204 | overflow: hidden; 205 | width: 120px; 206 | height: 120px; 207 | position: relative; 208 | display: block; 209 | z-index: 10 210 | } 211 | 212 | .dropzone .dz-preview .dz-image img { 213 | display: block 214 | } 215 | 216 | .dropzone .dz-preview.dz-success .dz-success-mark { 217 | animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1) 218 | } 219 | 220 | .dropzone .dz-preview.dz-error .dz-error-mark { 221 | opacity: 1; 222 | animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1) 223 | } 224 | 225 | .dropzone .dz-preview .dz-success-mark, 226 | .dropzone .dz-preview .dz-error-mark { 227 | pointer-events: none; 228 | opacity: 0; 229 | z-index: 500; 230 | position: absolute; 231 | display: block; 232 | top: 50%; 233 | left: 50%; 234 | margin-left: -16px; 235 | margin-top: -32px; 236 | background: rgba(0, 0, 0, .8); 237 | width: 32px; 238 | text-align: center; 239 | border-radius: 50%; 240 | } 241 | 242 | .dropzone .dz-preview .dz-success-mark svg, 243 | .dropzone .dz-preview .dz-error-mark svg { 244 | display: block; 245 | width: 54px; 246 | height: 54px; 247 | fill: #fff 248 | } 249 | 250 | .dropzone .dz-preview.dz-processing .dz-progress { 251 | opacity: 1; 252 | transition: all .2s linear 253 | } 254 | 255 | .dropzone .dz-preview.dz-complete .dz-progress { 256 | opacity: 0; 257 | transition: opacity .4s ease-in 258 | } 259 | 260 | .dropzone .dz-preview:not(.dz-processing) .dz-progress { 261 | animation: pulse 6s ease infinite 262 | } 263 | 264 | .dropzone .dz-preview .dz-progress { 265 | opacity: 1; 266 | z-index: 1000; 267 | pointer-events: none; 268 | position: absolute; 269 | height: 20px; 270 | top: 50%; 271 | margin-top: -10px; 272 | left: 15%; 273 | right: 15%; 274 | border: 3px solid rgba(0, 0, 0, .8); 275 | background: rgba(0, 0, 0, .8); 276 | border-radius: 10px; 277 | overflow: hidden 278 | } 279 | 280 | .dropzone .dz-preview .dz-progress .dz-upload { 281 | background: #fff; 282 | display: block; 283 | position: relative; 284 | height: 100%; 285 | width: 0; 286 | transition: width 300ms ease-in-out; 287 | border-radius: 17px 288 | } 289 | 290 | .dropzone .dz-preview.dz-error .dz-error-message { 291 | display: block 292 | } 293 | 294 | .dropzone .dz-preview.dz-error:hover .dz-error-message { 295 | opacity: 1; 296 | pointer-events: auto 297 | } 298 | 299 | .dropzone .dz-preview .dz-error-message { 300 | pointer-events: none; 301 | z-index: 1000; 302 | position: absolute; 303 | display: block; 304 | display: none; 305 | opacity: 0; 306 | transition: opacity .3s ease; 307 | border-radius: 8px; 308 | font-size: 13px; 309 | top: 130px; 310 | left: -10px; 311 | width: 140px; 312 | background: #b10606; 313 | padding: .5em 1em; 314 | color: #fff 315 | } 316 | 317 | .dropzone .dz-preview .dz-error-message:after { 318 | content: ""; 319 | position: absolute; 320 | top: -6px; 321 | left: 64px; 322 | width: 0; 323 | height: 0; 324 | border-left: 6px solid transparent; 325 | border-right: 6px solid transparent; 326 | border-bottom: 6px solid #b10606 327 | } -------------------------------------------------------------------------------- /Chromium/css/UploadLog.css: -------------------------------------------------------------------------------- 1 | body { 2 | min-width: 720px 3 | } 4 | 5 | .item { 6 | width: 360px; 7 | min-height: 104px; 8 | margin: 5px; 9 | } 10 | 11 | .item .FileMedia { 12 | width: 100%; 13 | min-height: 104px; 14 | object-fit: cover 15 | } 16 | 17 | .item #textarea { 18 | padding: 0; 19 | margin: 0; 20 | width: 100%; 21 | border: none 22 | } 23 | 24 | .item #textarea:focus { 25 | outline: none; 26 | border: none 27 | } 28 | 29 | .delete { 30 | user-select: none; 31 | width: 2rem; 32 | line-height: 2rem; 33 | color: red; 34 | text-align: center; 35 | display: block; 36 | position: absolute; 37 | top: 0; 38 | right: 0; 39 | z-index: 999 40 | } 41 | 42 | .delete:hover { 43 | color: white; 44 | background-color: red 45 | } 46 | 47 | .delete-loading { 48 | position: absolute; 49 | top: 45%; 50 | left: 49%; 51 | display: inline-block; 52 | width: 0; 53 | height: 0; 54 | border-left: 10px solid transparent; 55 | border-right: 10px solid transparent; 56 | border-bottom: 10px solid #4183d7; 57 | border-top: 10px solid #f5ab35; 58 | animation: delete-loading-animation 1.2s ease-in-out infinite alternate 59 | } 60 | 61 | @keyframes delete-loading-animation { 62 | from { 63 | transform: rotate(0deg) 64 | } 65 | 66 | to { 67 | transform: rotate(720deg) 68 | } 69 | } 70 | 71 | .head .selected:after { 72 | content: ""; 73 | width: 12px; 74 | height: 12px; 75 | border-radius: 50%; 76 | position: absolute; 77 | left: 5px; 78 | top: 50%; 79 | animation: pulse 1.5s infinite; 80 | background: #198754; 81 | } 82 | 83 | .head .selectedA { 84 | background: #4433ff; 85 | color: white; 86 | } 87 | 88 | @keyframes pulse { 89 | 0% { 90 | transform: translateY(-50%) scale3d(1.2, 1.2, 1.2); 91 | } 92 | 93 | 94 | 50% { 95 | transform: translateY(-50%) scale3d(1, 1, 1); 96 | } 97 | 98 | 100% { 99 | transform: translateY(-50%) scale3d(1.2, 1.2, 1.2); 100 | } 101 | } 102 | 103 | .copy { 104 | user-select: none; 105 | width: 2rem; 106 | line-height: 2rem; 107 | color: black; 108 | text-align: center; 109 | display: block; 110 | position: absolute; 111 | top: 0; 112 | right: 32px; 113 | z-index: 999 114 | } 115 | 116 | .copy:hover { 117 | background-color: #0d6efd; 118 | color: white 119 | } 120 | 121 | .plus { 122 | user-select: none; 123 | width: 2rem; 124 | line-height: 2rem; 125 | color: black; 126 | text-align: center; 127 | display: block; 128 | position: absolute; 129 | top: 0; 130 | right: 64px; 131 | z-index: 999; 132 | font-size: 24px; 133 | } 134 | 135 | .plus:hover { 136 | background-color: #0d6efd; 137 | color: white 138 | } 139 | 140 | .Image_Width_And_Height { 141 | user-select: none; 142 | font-size: 1rem; 143 | padding-left: .5rem; 144 | padding-right: .5rem; 145 | line-height: 2rem; 146 | text-align: center; 147 | display: block; 148 | color: white; 149 | background-color: #0000002d; 150 | position: absolute; 151 | top: 0 152 | } 153 | 154 | .urlDate { 155 | text-align: center; 156 | display: block; 157 | margin-bottom: 10px; 158 | margin-left: 5px; 159 | margin-right: 5px 160 | } 161 | 162 | .logurl { 163 | font-size: 1rem; 164 | white-space: nowrap; 165 | overflow: hidden; 166 | text-align: center; 167 | text-overflow: ellipsis; 168 | display: block; 169 | list-style: none; 170 | padding: 0; 171 | margin: 0; 172 | position: absolute; 173 | bottom: 0; 174 | background-color: #0000002d; 175 | width: 100%; 176 | color: white 177 | } 178 | 179 | .gigante { 180 | border: #03a9f4 2px solid 181 | } 182 | 183 | .Selected_But { 184 | margin: 0px 5px 0 5px 185 | } 186 | 187 | .head { 188 | display: flex; 189 | justify-content: flex-end; 190 | padding: 1rem 0px 191 | } 192 | 193 | #container { 194 | min-height: 150px; 195 | margin-top: calc(var(--bs-gutter-x) * .5) 196 | } 197 | 198 | .foot { 199 | position: sticky; 200 | bottom: 0; 201 | background: #fff 202 | } 203 | 204 | nav { 205 | margin-top: 1rem; 206 | padding-top: 1rem; 207 | border-top: 1px solid #eee 208 | } 209 | 210 | #Bottom_button { 211 | padding-bottom: 1rem 212 | } 213 | 214 | .overlay { 215 | position: fixed; 216 | top: 0; 217 | left: 0; 218 | width: 100vw; 219 | height: 100vh; 220 | background-color: rgba(0, 0, 0, 0.8); 221 | display: flex; 222 | justify-content: center; 223 | align-items: center; 224 | z-index: 9991 225 | } 226 | 227 | .overlay img, 228 | video, 229 | textarea { 230 | width: 90%; 231 | height: 90%; 232 | object-fit: contain; 233 | transition: transform .5s ease-in-out 234 | } 235 | 236 | .overlay img { 237 | position: absolute 238 | } 239 | 240 | .overlay video { 241 | position: absolute 242 | } 243 | 244 | .close-button { 245 | user-select: none; 246 | position: absolute; 247 | top: 0; 248 | right: 0em; 249 | background-color: #999; 250 | width: 2em; 251 | color: #fff; 252 | font-size: 2em; 253 | cursor: pointer; 254 | z-index: 9992; 255 | text-align: center; 256 | border-radius: 0px 0px 0px 1em 257 | } 258 | 259 | .close-button:hover { 260 | background-color: #8f8f8f 261 | } 262 | 263 | .zoomdiv { 264 | position: absolute; 265 | bottom: 5px; 266 | display: flex 267 | } 268 | 269 | .zoom-button { 270 | width: 30px; 271 | height: 30px; 272 | background-color: #fff; 273 | border: 1px solid #ccc; 274 | border-radius: 50%; 275 | display: flex; 276 | justify-content: center; 277 | align-items: center; 278 | font-weight: bold; 279 | cursor: pointer; 280 | margin: 5px; 281 | user-select: none; 282 | z-index: 9992 283 | } 284 | 285 | .zoom-button:hover { 286 | background-color: #eee 287 | } 288 | 289 | .zoom-in { 290 | font-size: 20px 291 | } 292 | 293 | .zoom-out { 294 | font-size: 26px 295 | } 296 | 297 | #Select_mode {} 298 | 299 | #Copy_Selected { 300 | min-width: 110px 301 | } 302 | 303 | .Copy_Selected button { 304 | font-weight: bold; 305 | border: 2px solid #4433ff; 306 | color: #4433ff 307 | } 308 | 309 | .Copy_Selected button:hover { 310 | color: #fff; 311 | border: 2px solid #4433ff; 312 | background-color: #4433ff 313 | } 314 | 315 | .Copy_Selected button:nth-child(2) { 316 | border-left: 1px 317 | } 318 | 319 | @media screen and (max-width:1280px) { 320 | .container-md.border-bottom.head { 321 | display: block; 322 | columns: 3 323 | } 324 | 325 | .container-md.border-bottom.head div, 326 | .container-md.border-bottom.head .Selected_But button { 327 | width: 100% 328 | } 329 | 330 | #dropdown-button { 331 | width: auto 332 | } 333 | 334 | .container-md.border-bottom.head div { 335 | margin-bottom: 10px 336 | } 337 | 338 | .container-md.border-bottom.head .Selected_But button#Copy_Selected { 339 | width: auto 340 | } 341 | } 342 | 343 | @media screen and (max-width:900px) { 344 | .container-md.border-bottom.head { 345 | display: block; 346 | columns: 2 347 | } 348 | } -------------------------------------------------------------------------------- /Chromium/vendor/confetti/confetti.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Minified by jsDelivr using Terser v5.15.1. 3 | * Original file: /npm/canvas-confetti@1.6.0/dist/confetti.browser.js 4 | * 5 | * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files 6 | */ 7 | !function(t,e){!function t(e,n,a,i){var o=!!(e.Worker&&e.Blob&&e.Promise&&e.OffscreenCanvas&&e.OffscreenCanvasRenderingContext2D&&e.HTMLCanvasElement&&e.HTMLCanvasElement.prototype.transferControlToOffscreen&&e.URL&&e.URL.createObjectURL);function r(){}function l(t){var a=n.exports.Promise,i=void 0!==a?a:e.Promise;return"function"==typeof i?new i(t):(t(r,r),null)}var c,s,u,h,f,d,m,g,b,v=(u=Math.floor(1e3/60),h={},f=0,"function"==typeof requestAnimationFrame&&"function"==typeof cancelAnimationFrame?(c=function(t){var e=Math.random();return h[e]=requestAnimationFrame((function n(a){f===a||f+u-1 2 | 3 | 4 | 5 | 6 | 7 | 8 | 上传记录 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 46 |
    47 |
    48 |
    49 |
    50 |
    51 | 53 |
    54 |
    55 | 58 |
    59 |
    60 | 63 |
    64 |
    65 | 68 |
    69 | 70 |
    71 | 73 | 75 | 82 |
    83 | 84 |
    85 | 88 |
    89 | 90 |
    91 |
    92 | 97 |
    98 | 102 | 108 |
    109 |
    110 | 114 | 120 |
    121 |
    122 | 123 |
    124 | 125 |
    126 |
    127 | 128 |
    129 | 139 |
    140 | 142 | 144 |
    145 |
    146 | 147 | 148 | 149 | 150 | 151 |
    152 |
    153 |
    154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /Chromium/vendor/IndexedDB/db.js: -------------------------------------------------------------------------------- 1 | class IndexedDBHelper { 2 | // 构造函数 3 | constructor(storeName, dbName) { 4 | this.dbName = dbName || "PLExtension"; // 默认数据库名 5 | this.storeName = storeName; // 对象存储名 6 | this.db = null; // 数据库实例 7 | this.sortedByIndex = 0; // 新增变量 8 | } 9 | 10 | // 打开数据库 11 | open(version = 1) { 12 | return new Promise((resolve, reject) => { 13 | // 打开或创建数据库 14 | const request = indexedDB.open(this.dbName, version); 15 | // 数据库升级时的回调 16 | request.onupgradeneeded = event => { 17 | this.db = event.target.result; 18 | 19 | if (!this.db.objectStoreNames.contains('BedConfigStore')) { 20 | const Store = this.db.createObjectStore('BedConfigStore', { keyPath: "id" }); 21 | Store.createIndex("index", "index", { unique: false }); 22 | } 23 | if (!this.db.objectStoreNames.contains('Uploads')) { 24 | const Store = this.db.createObjectStore('Uploads', { keyPath: "key" }); 25 | Store.createIndex("index", "index", { unique: false }); 26 | } 27 | 28 | if (!this.db.objectStoreNames.contains('Sticker')) { 29 | const Store = this.db.createObjectStore('Sticker', { keyPath: 'id', autoIncrement: true }); 30 | Store.createIndex("index", "index", { unique: false }); 31 | } 32 | }; 33 | 34 | // 打开成功的回调 35 | request.onsuccess = async event => { 36 | this.db = event.target.result; 37 | // 初始化 currentSortOrder 的值 38 | try { 39 | this.getMaxIndex().then(index => { 40 | this.sortedByIndex = index; 41 | }); 42 | resolve(); 43 | } catch (error) { 44 | reject(error); 45 | } 46 | }; 47 | // 打开失败的回调 48 | request.onerror = event => { 49 | console.error("IndexedDB error:", event.target.errorCode); 50 | reject(event.target.errorCode); 51 | }; 52 | }); 53 | } 54 | getMaxIndex() { 55 | return new Promise((resolve, reject) => { 56 | const transaction = this.db.transaction([this.storeName], "readonly"); 57 | const store = transaction.objectStore(this.storeName); 58 | 59 | const index = store.index("index"); 60 | const request = index.openCursor(null, "prev"); 61 | 62 | request.onsuccess = event => { 63 | const cursor = event.target.result; 64 | if (cursor) { 65 | return resolve(cursor.value.index + 1); 66 | } else { 67 | resolve(0); 68 | } 69 | }; 70 | 71 | request.onerror = () => reject(request.error); 72 | }); 73 | } 74 | // 关闭数据库 75 | close() { 76 | if (this.db) { 77 | this.db.close(); 78 | this.db = null; 79 | } 80 | } 81 | 82 | add(data, batchSize = 1000) { 83 | return this._batchOperation(data, batchSize, 'add'); 84 | } 85 | 86 | put(data, batchSize = 1000) { 87 | return this._batchOperation(data, batchSize, 'put'); 88 | } 89 | 90 | _batchOperation(data, batchSize, operation) { 91 | return new Promise(async (resolve, reject) => { 92 | if (!Array.isArray(data)) { 93 | data = [data]; 94 | } 95 | for (let i = 0; i < data.length; i += batchSize) { 96 | 97 | const batch = data.slice(i, i + batchSize); 98 | try { 99 | await this._processBatch(batch, operation); 100 | } catch (error) { 101 | reject(error); 102 | return; 103 | } 104 | } 105 | 106 | resolve(); 107 | }); 108 | } 109 | _processBatch(batch, operation, Index) { 110 | return new Promise((resolve, reject) => { 111 | const transaction = this.db.transaction([this.storeName], "readwrite"); 112 | const store = transaction.objectStore(this.storeName); 113 | let count = 0; 114 | 115 | batch.forEach((item, index) => { 116 | let request; 117 | if (item.index === undefined) { 118 | item.index = this.sortedByIndex++; 119 | } 120 | if (operation === 'put') { 121 | request = store.put(item); 122 | } else if (operation === 'add') { 123 | request = store.add(item); 124 | } else { 125 | reject(new Error("Invalid operation")); 126 | return; 127 | } 128 | 129 | request.onsuccess = () => { 130 | count++; 131 | if (count === batch.length) { 132 | resolve(); 133 | } 134 | }; 135 | request.onerror = () => reject(request.error); 136 | }); 137 | }); 138 | } 139 | 140 | 141 | // 根据键获取数据 142 | get(key) { 143 | return new Promise((resolve, reject) => { 144 | const transaction = this.db.transaction([this.storeName]); 145 | const store = transaction.objectStore(this.storeName); 146 | 147 | let request; 148 | if (key === undefined) { 149 | // 如果没有提供键值,获取所有数据 150 | request = store.getAll(); 151 | } else { 152 | // 如果提供了键值,获取指定键的数据 153 | request = store.get(key); 154 | } 155 | 156 | request.onsuccess = () => resolve(request.result); 157 | request.onerror = () => reject(request.error); 158 | }); 159 | } 160 | // 获取所有数据 161 | getAll() { 162 | return new Promise((resolve, reject) => { 163 | const transaction = this.db.transaction([this.storeName], "readonly"); 164 | const store = transaction.objectStore(this.storeName); 165 | const request = store.getAll(); // 获取所有数据 166 | 167 | request.onsuccess = () => resolve(request.result); 168 | request.onerror = () => reject(request.error); 169 | }); 170 | } 171 | // 获取所有数据并按照 index 字段排序 172 | getSortedByIndex() { 173 | return new Promise((resolve, reject) => { 174 | const transaction = this.db.transaction([this.storeName], "readonly"); 175 | const store = transaction.objectStore(this.storeName); 176 | const index = store.index("index"); // 使用创建的索引 177 | const request = index.getAll(); // 获取根据索引排序的所有数据 178 | request.onsuccess = () => resolve(request.result); 179 | request.onerror = () => reject(request.error); 180 | }); 181 | } 182 | 183 | // 根据键删除数据 184 | delete(keys) { 185 | return new Promise((resolve, reject) => { 186 | const transaction = this.db.transaction([this.storeName], "readwrite"); 187 | const store = transaction.objectStore(this.storeName); 188 | 189 | // 检查 keys 是否为数组 190 | if (Array.isArray(keys)) { 191 | let count = 0; 192 | keys.forEach(key => { 193 | const request = store.delete(key); 194 | 195 | request.onsuccess = () => { 196 | count++; 197 | // 当所有键都被删除时,解决 promise 198 | if (count === keys.length) { 199 | resolve(); 200 | } 201 | }; 202 | 203 | request.onerror = () => reject(request.error); 204 | }); 205 | } else { 206 | // keys 不是数组,处理单个键 207 | let request; 208 | if (keys === undefined) { 209 | // 没有指定键,删除所有数据 210 | request = store.clear(); 211 | } else { 212 | // 根据指定键删除数据 213 | request = store.delete(keys); 214 | } 215 | 216 | request.onsuccess = () => resolve(); 217 | request.onerror = () => reject(request.error); 218 | } 219 | }); 220 | } 221 | 222 | // 清空所有数据 223 | clear() { 224 | return new Promise((resolve, reject) => { 225 | const transaction = this.db.transaction([this.storeName], "readwrite"); 226 | const store = transaction.objectStore(this.storeName); 227 | const request = store.clear(); // 清空对象存储中的所有数据 228 | this.sortedByIndex = 0 229 | request.onsuccess = () => resolve(); 230 | request.onerror = () => reject(request.error); 231 | }); 232 | } 233 | } 234 | 235 | 236 | function dbHelper(storeName) { 237 | return new Promise((resolve, reject) => { 238 | const db = new IndexedDBHelper(storeName); 239 | db.open().then(() => { 240 | resolve({ db }); 241 | }).catch(error => { 242 | reject({ "error": error, "message": "数据库好像出了点问题" }); 243 | }); 244 | }); 245 | } 246 | -------------------------------------------------------------------------------- /Chromium/css/popup.css: -------------------------------------------------------------------------------- 1 | #overlay { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | width: 100%; 6 | height: 100%; 7 | background-color: rgba(0, 0, 0, 0.5); 8 | z-index: 9999; 9 | display: flex; 10 | justify-content: center; 11 | align-items: center 12 | } 13 | 14 | #overlay p { 15 | margin: 0; 16 | padding: 0 17 | } 18 | 19 | #introBox { 20 | background: #6cbbfc; 21 | color: white; 22 | padding: 20px; 23 | text-align: center; 24 | border-radius: 8px; 25 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3) 26 | } 27 | 28 | .Functional_animation { 29 | opacity: 0; 30 | position: fixed; 31 | left: 0; 32 | bottom: 0; 33 | z-index: 9998; 34 | transition: left 1s ease, transform 1s ease 35 | } 36 | 37 | .animation_finger { 38 | width: 155px; 39 | height: 200px; 40 | background-image: url(../icons/dh/t.png) 41 | } 42 | 43 | .Functional_animation.active { 44 | opacity: 1; 45 | transform: translate(-50%, -50%); 46 | left: 50% 47 | } 48 | 49 | #overlay #introBox button { 50 | padding: 10px 20px; 51 | font-size: 16px; 52 | border: none; 53 | border-radius: 4px; 54 | background-color: #007bff; 55 | color: #fff; 56 | cursor: pointer; 57 | margin-right: 10px 58 | } 59 | 60 | #overlay #introBox button:hover { 61 | background-color: #0056b3 62 | } 63 | 64 | .Demo-container { 65 | position: relative; 66 | display: flex; 67 | justify-content: center; 68 | align-items: center; 69 | flex-wrap: wrap; 70 | z-index: 1 71 | } 72 | 73 | .Demo-container .card { 74 | position: relative; 75 | width: 200px; 76 | height: 350px; 77 | margin: 10px; 78 | border-radius: 15px; 79 | background: rgba(255, 255, 255, 0.2); 80 | overflow: hidden; 81 | display: flex; 82 | justify-content: center; 83 | align-items: center; 84 | backdrop-filter: blur(5px) 85 | } 86 | 87 | .Demo-container .card:hover { 88 | background: rgba(255, 255, 255, 0.3) 89 | } 90 | 91 | .Demo-container .card .content { 92 | padding: 20px; 93 | text-align: center; 94 | transform: translateY(100px); 95 | opacity: 0; 96 | transition: 0.5s 97 | } 98 | 99 | .Demo-container .card:hover .content { 100 | transform: translateY(0px); 101 | opacity: 1 102 | } 103 | 104 | .Demo-container .card h2 { 105 | position: absolute; 106 | width: 150px; 107 | height: 150px; 108 | font-size: 8em; 109 | color: rgba(255, 255, 255, 0); 110 | pointer-events: none 111 | } 112 | 113 | .Demo-container .card:nth-child(1) h2 { 114 | background: url(../icons/paste.webp); 115 | background-size: cover 116 | } 117 | 118 | .Demo-container .card:nth-child(2) h2 { 119 | background: url(../icons/drag.webp); 120 | background-size: cover 121 | } 122 | 123 | .Demo-container .card:nth-child(3) h2 { 124 | background: url(../icons/RightClick.webp); 125 | background-size: cover 126 | } 127 | 128 | .Demo-container .card:hover h2 { 129 | color: rgba(255, 255, 255, 0); 130 | background: none 131 | } 132 | 133 | .Demo-container .card .content h3 { 134 | font-size: 1.8em; 135 | color: #fff; 136 | z-index: 1; 137 | margin-bottom: .5em 138 | } 139 | 140 | .Demo-container .card .content p { 141 | font-size: 1em; 142 | color: #fff; 143 | font-weight: 300; 144 | margin: 0 145 | } 146 | 147 | .Demo-container .card .content a { 148 | position: relative; 149 | display: inline-block; 150 | padding: 8px 20px; 151 | margin-top: 15px; 152 | background: #fff; 153 | color: #000; 154 | border-radius: 20px; 155 | text-decoration: none; 156 | font-weight: 500; 157 | box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2) 158 | } 159 | 160 | .popup-Select { 161 | user-select: none; 162 | padding: .6rem; 163 | text-align: center; 164 | border-radius: .6rem .6rem 0px 0px 165 | } 166 | 167 | .popup-Select:hover { 168 | background-color: #eee 169 | } 170 | 171 | .LinksBox { 172 | display: none 173 | } 174 | 175 | textarea:focus { 176 | outline: none; 177 | border: #03a9f4 1px solid 178 | } 179 | 180 | .dropzone { 181 | min-height: 284px; 182 | border: none; 183 | transition: min-height 1s ease-in-out 184 | } 185 | 186 | .dz-button { 187 | transition: margin-top 1s ease-in-out 188 | } 189 | 190 | .p_urls { 191 | word-break: break-word 192 | } 193 | 194 | @media screen and (min-height:680px) { 195 | .dropzone { 196 | min-height: 420px 197 | } 198 | } 199 | 200 | @media screen and (min-height:780px) { 201 | .dropzone { 202 | min-height: 520px 203 | } 204 | } 205 | 206 | @media screen and (min-height:880px) { 207 | .dropzone { 208 | min-height: 620px 209 | } 210 | } 211 | 212 | @media screen and (min-height:1080px) { 213 | .dropzone { 214 | min-height: 820px 215 | } 216 | } 217 | 218 | @media screen and (max-width:780px) { 219 | #ButtonBox { 220 | display: flex; 221 | width: 100%; 222 | justify-content: space-around; 223 | } 224 | .urlButton{ 225 | width: 100%; 226 | } 227 | .selector_p_urls { 228 | width: 2.5rem 229 | } 230 | 231 | .copy { 232 | width: 2.5rem 233 | } 234 | } 235 | 236 | @media screen and (min-width:768px) { 237 | #ButtonBox { 238 | width: 9rem; 239 | border-right: 1px solid #eee; 240 | position: sticky; 241 | height: 100%; 242 | top: 90px; 243 | display: block; 244 | } 245 | } 246 | 247 | .dropzone .icon { 248 | width: 10rem; 249 | height: 10rem; 250 | -webkit-user-drag: none 251 | } 252 | 253 | .dropzone .dz-preview { 254 | margin: .5rem 255 | } 256 | 257 | .dropzone .dz-preview .dz-image { 258 | width: 200px; 259 | height: 200px 260 | } 261 | 262 | .dropzone .dz-preview .dz-image img { 263 | width: 100%; 264 | height: 100% 265 | } 266 | 267 | .dz-remove { 268 | text-decoration: none; 269 | color: #000 270 | } 271 | 272 | fieldset { 273 | margin-top: 20px; 274 | border: .2rem rgba(0, 0, 0, 0.3) solid 275 | } 276 | 277 | .urlButton { 278 | overflow: hidden; 279 | user-select: none; 280 | padding: .6rem 281 | } 282 | 283 | .urlButton:hover { 284 | background-color: #eee 285 | } 286 | 287 | .Check { 288 | border-bottom: .1rem #03a9f4 solid 289 | } 290 | 291 | .textFrame { 292 | padding: 0rem .5rem; 293 | } 294 | 295 | .int_urls { 296 | width: 100%; 297 | min-height: 100px; 298 | border-radius: 5px 299 | } 300 | 301 | .p_urls { 302 | font-size: 1rem; 303 | padding: .5rem .8rem; 304 | border-radius: 5px 0px 0px 5px; 305 | margin: 0px; 306 | background-color: #eee 307 | } 308 | 309 | .p_urls:hover { 310 | box-shadow: 0 -0.2em 1em var(--bs-danger), 0 0.2em 1em var(--bs-primary) 311 | } 312 | 313 | .IMGpreview { 314 | box-shadow: 0 -0.2em 1em var(--bs-red), 0 0.2em 1em var(--bs-indigo) 315 | } 316 | 317 | .delete { 318 | user-select: none; 319 | font-size: 1rem; 320 | font-weight: bold; 321 | width: 2rem; 322 | line-height: 2rem; 323 | color: #2196f3; 324 | text-align: center; 325 | display: block; 326 | background-color: #eee; 327 | position: absolute; 328 | top: 4px; 329 | right: 4px 330 | } 331 | 332 | .delete:hover { 333 | color: white; 334 | background-color: red 335 | } 336 | 337 | .copy { 338 | user-select: none; 339 | width: 3rem; 340 | display: flex; 341 | align-items: center; 342 | justify-content: center; 343 | background-color: #2196f3; 344 | color: white 345 | } 346 | 347 | .copy:hover { 348 | background-color: #03a9f4 349 | } 350 | 351 | .selector_p_urls { 352 | user-select: none; 353 | width: 3rem; 354 | display: flex; 355 | align-items: center; 356 | justify-content: center; 357 | background-color: #eee; 358 | border-radius: 0px 5px 5px 0px 359 | } 360 | 361 | .selector_p_urls:hover { 362 | background-color: #e4e4e4 363 | } 364 | 365 | .selector_p_urls_Click { 366 | background-color: #e0e0e0 367 | } 368 | 369 | .dz-remove { 370 | font-size: 1rem 371 | } 372 | 373 | .Upload_Return_Box { 374 | display: flex; 375 | margin: .5rem 0px 376 | } -------------------------------------------------------------------------------- /Chromium/css/public.css: -------------------------------------------------------------------------------- 1 | body{padding:0px;margin:0px;min-width:500px} 2 | .container-md{transition:max-width 1s ease-in-out} 3 | #header{z-index:9990;background-color:#0f62fe;position:sticky;top:0} 4 | #header .nav .nav-item a{color:#eee} 5 | #header .nav .nav-item a:hover{transform: scale3d(1.1, 1.1, 1.1);color:white} 6 | .title-a{text-shadow:2px 2px #03a9f4;text-decoration:none} 7 | h1{text-align:center;background:-webkit-linear-gradient(135deg,#0eaf6d,#ff6ac6 25%,#147b96 50%,#e6d205 55%,#2cc4e0 60%,#8b2ce0 80%,#ff6384 95%,#08dfb4);-webkit-text-fill-color:transparent;-webkit-background-clip:text;-webkit-background-size:200% 100%;-webkit-animation:flowCss 12s infinite linear} 8 | @-webkit-keyframes flowCss{0%{background-position:0 0} 9 | 100%{background-position:-400% 0} 10 | }h1:hover{-webkit-animation:flowCss 4s infinite linear} 11 | .box-shadow{box-shadow:0 1px 6px rgba(0,0,0,0.1),0 2px 4px rgba(0,0,0,0.06)} 12 | .em1{padding:1em;margin:1em} 13 | #alert{z-index:999;width:100%;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:transparent;color:black;font-size:1rem;text-align:center} 14 | .alert_title{width:100%;text-align:center;line-height:2rem;background-color:#03a9f4} 15 | .alert_title_p{font-size:1.5rem;margin:0;padding:0;width:100%;vertical-align:middle;color:white;user-select:none} 16 | .alert_title_button{width:2rem;float:right;margin-top:-2rem;border:none;background-color:#ff5722;height:2rem;color:white} 17 | .alert_title_button:hover{background-color:#ff9800} 18 | .alert_content{font-size:1rem;width:100%;height:100%;overflow:hidden;vertical-align:middle;background-color:white;user-select:none} 19 | #alertBG{z-index:998;margin:0;padding:0;position:absolute;top:0%;width:999%;height:999%;background:rgb(0 0 0 / 50%)} 20 | .Animation_button{border:none;cursor:pointer;position:relative} 21 | .Animation_button_span{display:block} 22 | .Animation_button::before,.Animation_button::after{content:"";width:0;height:2px;position:absolute;transition:all .2s linear;background:-webkit-linear-gradient(180deg,#00CCFF,#0099FF 50%,#00CCFF)} 23 | .Animation_button_span::before,.Animation_button_span::after{content:"";width:2px;height:0;position:absolute;transition:all .2s linear;background:-webkit-linear-gradient(180deg,#00CCFF,#0099FF 50%,#00CCFF)} 24 | .Animation_button:hover::before,.Animation_button:hover::after{width:100%} 25 | .Animation_button:hover .Animation_button_span::before,.Animation_button:hover .Animation_button_span::after{height:100%} 26 | .Animation_button1::before,.Animation_button1::after{transition-delay:.2s} 27 | .Animation_button1 .Animation_button_span::before,.Animation_button1 .Animation_button_span::after{transition-delay:0s} 28 | .Animation_button1::before{right:0;top:0} 29 | .Animation_button1::after{left:0;bottom:0} 30 | .Animation_button1 .Animation_button_span::before{left:0;top:0} 31 | .Animation_button1 .Animation_button_span::after{right:0;bottom:0} 32 | .Animation_button1:hover::before,.Animation_button1:hover::after{transition-delay:0s} 33 | .Animation_button1:hover .Animation_button_span::before,.Animation_button1:hover .Animation_button_span::after{transition-delay:.2s} 34 | .Animation_button2::before,.Animation_button2::after{transition-delay:0s} 35 | .Animation_button2 .Animation_button_span::before,.Animation_button2 .Animation_button_span::after{transition-delay:.2s} 36 | .Animation_button2::before{right:0;top:0} 37 | .Animation_button2::after{left:0;bottom:0} 38 | .Animation_button2 .Animation_button_span::before{left:0;top:0} 39 | .Animation_button2 .Animation_button_span::after{right:0;bottom:0} 40 | .Animation_button2:hover::before,.Animation_button2:hover::after{transition-delay:.2s} 41 | .Animation_button2:hover .Animation_button_span::before,.Animation_button2:hover .Animation_button_span::after{transition-delay:0s} 42 | .Animation_button3::after{left:0;bottom:0;transition-delay:.6s} 43 | .Animation_button3 .Animation_button_span::after{transition-delay:.4s;right:0;bottom:0} 44 | .Animation_button3::before{right:0;top:0;transition-delay:.2s} 45 | .Animation_button3 .Animation_button_span::before{transition-delay:0s;left:0;top:0} 46 | .Animation_button3:hover::after{transition-delay:0s} 47 | .Animation_button3:hover .Animation_button_span::after{transition-delay:.2s} 48 | .Animation_button3:hover::before{transition-delay:.4s} 49 | .Animation_button3:hover .Animation_button_span::before{transition-delay:.6s} 50 | .Animation_button4::after{right:0;bottom:0;transition-duration:.4s} 51 | .Animation_button4 .Animation_button_span::after{right:0;bottom:0;transition-duration:.4s} 52 | .Animation_button4::before{left:0;top:0;transition-duration:.4s} 53 | .Animation_button4 .Animation_button_span::before{left:0;top:0;transition-duration:.4s} 54 | .Animation_button5::after{left:0;bottom:0;transition-duration:.4s} 55 | .Animation_button5 .Animation_button_span::after{right:0;top:0;transition-duration:.4s} 56 | .Animation_button5::before{right:0;top:0;transition-duration:.4s} 57 | .Animation_button5 .Animation_button_span::before{left:0;bottom:0;transition-duration:.4s} 58 | .Animation_button6::before{left:50%;top:0;transition-duration:.4s} 59 | .Animation_button6::after{left:50%;bottom:0;transition-duration:.4s} 60 | .Animation_button6 .Animation_button_span::before{left:0;top:50%;transition-duration:.4s} 61 | .Animation_button6 .Animation_button_span::after{right:0;top:50%;transition-duration:.4s} 62 | .Animation_button6:hover::before,.Animation_button6:hover::after{left:0} 63 | .Animation_button6:hover .Animation_button_span::before,.Animation_button6:hover .Animation_button_span::after{top:0} 64 | .options-loading{width:30px;height:30px;animation:animationContainer 1s ease infinite} 65 | .loading{width:30px;height:30px;animation:animationContainer 1s ease infinite} 66 | .UploadLog-loading{width:30px;height:30px;position:absolute;top:42%;left:46%;animation:animationContainer 1s ease infinite} 67 | .loading-shape{width:10px;height:10px;border-radius:50%;position:absolute} 68 | .loading-shape-1{background-color:#1875e5;left:0;animation:animationloading-shape1 0.5s ease infinite alternate} 69 | .loading-shape-2{background-color:#c5523f;right:0;animation:animationloading-shape2 0.5s ease infinite alternate} 70 | .loading-shape-3{background-color:#499255;bottom:0;animation:animationloading-shape3 0.5s ease infinite alternate} 71 | .loading-shape-4{background-color:#f2b736;right:0;bottom:0;animation:animationloading-shape4 0.5s ease infinite alternate} 72 | .overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:rgba(0,0,0,0.8);display:flex;justify-content:center;align-items:center;z-index:9991} 73 | @keyframes animationContainer{0%{transform:rotate(0)} 74 | 100%{transform:rotate(360deg)} 75 | }@keyframes animationloading-shape1{0%{transform:translate(0,0)} 76 | 100%{transform:translate(20px,20px)} 77 | }@keyframes animationloading-shape2{0%{transform:translate(0,0)} 78 | 100%{transform:translate(-20px,20px)} 79 | }@keyframes animationloading-shape3{0%{transform:translate(0,0)} 80 | 100%{transform:translate(20px,-20px)} 81 | }@keyframes animationloading-shape4{0%{transform:translate(0,0)} 82 | 100%{transform:translate(-20px,-20px)} 83 | }.css-button-rounded--black{height:40px;color:#fff;padding:5px 10px;font-weight:bold;cursor:pointer;transition:all 0.3s ease;position:relative;display:inline-block;outline:none;border-radius:5px;border:2px solid #212529;background:#212529} 84 | .css-button-rounded--black:hover{background:#fff;color:#212529} 85 | .css-button-rounded--red{height:40px;color:#fff;padding:5px 10px;font-weight:bold;cursor:pointer;transition:all 0.3s ease;position:relative;display:inline-block;outline:none;border-radius:5px;border:2px solid #d90429;background:#d90429} 86 | .css-button-rounded--red:hover{background:#fff;color:#d90429} 87 | .css-button-rounded--sky{height:40px;color:#fff;padding:5px 10px;font-weight:bold;cursor:pointer;transition:all 0.3s ease;position:relative;display:inline-block;outline:none;border-radius:5px;border:2px solid #4433ff;background:#4433ff} 88 | .css-button-rounded--sky:hover{background:#fff;color:#4433ff} 89 | .css-button-rounded--blue{height:40px;color:#fff;padding:5px 10px;font-weight:bold;cursor:pointer;transition:all 0.3s ease;position:relative;display:inline-block;outline:none;border-radius:5px;border:2px solid #2c0b8e;background:#2c0b8e} 90 | .css-button-rounded--blue:hover{background:#fff;color:#2c0b8e} 91 | .css-button-arrow--sky{height:40px;color:#fff;padding:5px 30px;font-weight:bold;cursor:pointer;transition:all 0.3s ease;position:relative;display:inline-block;outline:none;overflow:hidden;border-radius:5px;border:none;background-color:#4433ff} 92 | .css-button-arrow--sky:hover{border-radius:5px} 93 | .css-button-arrow--sky:hover:after{opacity:1;right:10px} 94 | .css-button-arrow--sky:after{content:"\00BB";position:absolute;opacity:0;font-size:20px;line-height:40px;top:0;right:-20px;transition:0.4s} 95 | #options_exe .css-button-shadow--sky{height:40px;color:#fff;padding:5px 10px;font-weight:bold;cursor:pointer;transition:all 0.3s ease;position:relative;display:inline-block;outline:none;border-radius:5px;border:none;background-color:#3a86ff;box-shadow:0 3px 1px -2px #ccc,0 2px 2px 0 #ccc,0 1px 5px 0 #ccc} 96 | #options_exe .css-button-shadow--sky:active{box-shadow:0 4px 2px -3px #ccc,0 4px 5px 1px #ccc,0 2px 7px 1px #ccc} -------------------------------------------------------------------------------- /Chromium/css/options.css: -------------------------------------------------------------------------------- 1 | body { 2 | min-width: 720px 3 | } 4 | 5 | code { 6 | white-space: nowrap 7 | } 8 | 9 | .modal-dialog { 10 | position: sticky !important; 11 | top: 20% 12 | } 13 | 14 | .container-fluid { 15 | margin-top: 20PX; 16 | display: flex; 17 | flex-direction: column; 18 | align-items: center; 19 | padding: 20px; 20 | border-bottom: 1px solid #eee 21 | } 22 | 23 | .main { 24 | display: flex; 25 | justify-content: center 26 | } 27 | 28 | .main .main-left { 29 | border-radius: 20px; 30 | position: relative; 31 | margin: 10px; 32 | min-width: 650px; 33 | width: 60vw; 34 | height: 100%; 35 | } 36 | 37 | .main .main-right { 38 | display: block; 39 | margin: 10px; 40 | max-width: 450px; 41 | } 42 | 43 | .Config-Bottom-Boxs { 44 | border-radius: 20px; 45 | padding: 10px; 46 | margin: 14px 0 47 | } 48 | 49 | .Config-Bottom-Boxs div { 50 | position: relative; 51 | } 52 | 53 | .main-right .Config-Bottom-Boxs:nth-child(1) { 54 | column-count: 2; 55 | text-align: center 56 | } 57 | 58 | .main-right .Config-Bottom-Boxs:nth-child(1) div, 59 | .main-right .Config-Bottom-Boxs:nth-child(1) button { 60 | width: 100% 61 | } 62 | 63 | .main-right .Config-Bottom-Boxs:nth-child(1) { 64 | margin-top: 0 65 | } 66 | 67 | .Config-Bottom-Boxs .Config-Bottom-Box { 68 | padding: 4px 0 69 | } 70 | 71 | #options_exe { 72 | margin-top: 1rem; 73 | margin-bottom: 1.5rem; 74 | text-align: center; 75 | position: sticky; 76 | top: 80px 77 | } 78 | 79 | #options_exe button { 80 | background: none; 81 | width: 100%; 82 | padding: .5rem 0rem .5rem 0rem 83 | } 84 | 85 | #options_exe button.active { 86 | color: white; 87 | background: #2e1bff 88 | } 89 | 90 | #options_exe button span.selected:after { 91 | content: ""; 92 | width: 12px; 93 | height: 12px; 94 | border-radius: 50%; 95 | position: absolute; 96 | left: 5px; 97 | top: 50%; 98 | animation: pulse 1.5s infinite; 99 | background: #2e1bff; 100 | } 101 | 102 | .BedConfigShow { 103 | position: absolute; 104 | font-size: 24px; 105 | right: 10px; 106 | top: 0px 107 | } 108 | 109 | .BedConfigShow:hover { 110 | color: #2e1bff 111 | } 112 | 113 | .Config-Box { 114 | display: flex 115 | } 116 | 117 | .Config-Box-Log-haed { 118 | text-align: center; 119 | background-color: #03a9f4; 120 | border-radius: 16px 16px 0 0; 121 | padding: 8px; 122 | user-select: none 123 | } 124 | 125 | .Config-Box-Log-haed-del { 126 | position: absolute; 127 | right: 8px; 128 | color: white 129 | } 130 | 131 | .Config-Box-Log-haed-del:hover { 132 | color: #2e1bff 133 | } 134 | 135 | .Config-Box-Log-content .moving { 136 | background: transparent; 137 | color: transparent; 138 | animation: border-Blink 1s infinite; 139 | 140 | } 141 | 142 | @keyframes border-Blink { 143 | 0% { 144 | border: 1px dashed #ccc; 145 | } 146 | 147 | 50% { 148 | border: 1px dashed #3a86ff; 149 | } 150 | 151 | 100% { 152 | border: 1px dashed #ccc; 153 | } 154 | } 155 | 156 | .Config-Box-Log-item { 157 | background-color: white; 158 | padding: 5px; 159 | display: flex; 160 | justify-content: space-between 161 | } 162 | 163 | .BedConfigName { 164 | width: 100%; 165 | user-select: none 166 | } 167 | 168 | .Config-Box-Log-item:hover .BedConfigName span { 169 | color: #6c757d 170 | } 171 | 172 | .Config-Box-Log-item .button { 173 | margin: 0 4px; 174 | user-select: none; 175 | color: #2e1bff; 176 | border: none; 177 | background: none; 178 | padding: 0; 179 | } 180 | 181 | .Config-Box-Log-item .button:hover { 182 | color: red 183 | } 184 | 185 | .Config-Box .Config-Box-Left { 186 | width: 160px; 187 | border-right: #eee 1px solid 188 | } 189 | 190 | .Config-Box-Right { 191 | margin-top: .5rem 192 | } 193 | 194 | .Config-Box-Right:nth-child(2) { 195 | padding: 0 5px 196 | } 197 | 198 | .Config-Box-Right-header { 199 | padding: .5rem 0; 200 | display: flex 201 | } 202 | 203 | .Config-Box-Right-header div { 204 | margin: 0 5px 205 | } 206 | 207 | .Config-Box-Right-header div:nth-child(1) { 208 | margin-left: 0 209 | } 210 | 211 | @media screen and (min-width:2000px) { 212 | .main .main-left { 213 | width: 1000px 214 | } 215 | } 216 | 217 | @media screen and (max-width:1000px) { 218 | .main { 219 | flex-direction: column 220 | } 221 | 222 | .main .main-left { 223 | width: auto 224 | } 225 | 226 | .main .main-right { 227 | padding: 0 10px; 228 | margin: 20px 0px; 229 | min-width: 100% !important; 230 | } 231 | } 232 | 233 | @media screen and (max-width:960px) { 234 | .Config-Box .Config-Box-Left { 235 | width: 140px 236 | } 237 | } 238 | 239 | .options-form { 240 | padding: 0 8px; 241 | } 242 | 243 | .form-group { 244 | width: 100%; 245 | margin-bottom: 20px 246 | } 247 | 248 | .form-group label { 249 | font-size: 18px; 250 | font-weight: bolder 251 | } 252 | 253 | .form-group p { 254 | margin: .5rem 0rem; 255 | font-size: 12px; 256 | color: #6d6d6d; 257 | display: inline-block 258 | } 259 | 260 | label { 261 | user-select: none; 262 | } 263 | 264 | .required-marker { 265 | font-size: 12px; 266 | color: red; 267 | /* 设置星号的颜色 */ 268 | margin: 4px; 269 | /* 设置星号与输入框之间的间距 */ 270 | } 271 | 272 | .form-group input { 273 | width: 100%; 274 | border-radius: 5px 275 | } 276 | 277 | .form-group input:focus { 278 | outline: none; 279 | border: #03a9f4 1px solid 280 | } 281 | 282 | .form-text { 283 | margin-bottom: 10px 284 | } 285 | 286 | .options_Open_with { 287 | margin-top: 1rem; 288 | border: none; 289 | background-color: #03a9f4; 290 | color: white; 291 | padding: .4rem 292 | } 293 | 294 | .options_Open_with:hover { 295 | background-color: #2196f3 296 | } 297 | 298 | .switch { 299 | top: .7rem; 300 | position: relative; 301 | display: inline-block; 302 | width: 60px; 303 | height: 34px 304 | } 305 | 306 | .switch input { 307 | display: none 308 | } 309 | 310 | .slider { 311 | position: absolute; 312 | cursor: pointer; 313 | top: 0; 314 | left: 0; 315 | right: 0; 316 | bottom: 0; 317 | background-color: #ccc; 318 | -webkit-transition: .4s; 319 | transition: .4s 320 | } 321 | 322 | .slider:before { 323 | position: absolute; 324 | content: ""; 325 | height: 26px; 326 | width: 26px; 327 | left: 4px; 328 | bottom: 4px; 329 | background-color: white; 330 | -webkit-transition: .4s; 331 | transition: .4s 332 | } 333 | 334 | input:checked+.slider { 335 | background-color: #2196F3 336 | } 337 | 338 | input:focus+.slider { 339 | box-shadow: 0 0 1px #2196F3 340 | } 341 | 342 | input:checked+.slider:before { 343 | -webkit-transform: translateX(26px); 344 | -ms-transform: translateX(26px); 345 | transform: translateX(26px) 346 | } 347 | 348 | .slider.round { 349 | border-radius: 34px 350 | } 351 | 352 | .slider.round:before { 353 | border-radius: 50% 354 | } 355 | 356 | .ImgurPostModeDiv { 357 | margin: 1rem; 358 | user-select: none 359 | } 360 | 361 | #PNGmodal-body { 362 | width: 100%; 363 | height: 350px; 364 | padding: 0; 365 | margin: 0; 366 | display: flex; 367 | user-select: none 368 | } 369 | 370 | #edit_uploadArea { 371 | height: 64px; 372 | width: 10px; 373 | cursor: move; 374 | position: absolute 375 | } 376 | 377 | .css-button-rounded--sky { 378 | height: 40px; 379 | color: #fff; 380 | padding: 5px 10px; 381 | font-weight: bold; 382 | cursor: pointer; 383 | transition: all 0.3s ease; 384 | position: relative; 385 | display: inline-block; 386 | outline: none; 387 | border-radius: 5px; 388 | border: 2px solid #4433ff; 389 | background: #4433ff 390 | } 391 | 392 | .css-button-rounded--sky:hover { 393 | background: #fff; 394 | color: #4433ff 395 | } 396 | 397 | .css-button-sliding-bottom { 398 | min-width: 130px; 399 | height: 40px; 400 | color: #fff; 401 | padding: 5px 10px; 402 | font-weight: bold; 403 | cursor: pointer; 404 | transition: all 0.3s ease; 405 | position: relative; 406 | display: inline-block; 407 | outline: none; 408 | border-radius: 5px; 409 | z-index: 0; 410 | background: #fff; 411 | overflow: hidden; 412 | border: none; 413 | color: #4433ff 414 | } 415 | 416 | .css-button-sliding-bottom:hover { 417 | color: #fff 418 | } 419 | 420 | .css-button-sliding-bottom:hover:after { 421 | height: 100% 422 | } 423 | 424 | .css-button-sliding-bottom:after { 425 | content: ""; 426 | position: absolute; 427 | z-index: -1; 428 | transition: all 0.3s ease; 429 | left: 0; 430 | top: 0; 431 | height: 0; 432 | width: 100%; 433 | background: #4433ff 434 | } 435 | 436 | .css-button-sliding-top { 437 | min-width: 130px; 438 | height: 40px; 439 | color: #fff; 440 | padding: 5px 10px; 441 | font-weight: bold; 442 | cursor: pointer; 443 | transition: all 0.3s ease; 444 | position: relative; 445 | display: inline-block; 446 | outline: none; 447 | border-radius: 5px; 448 | z-index: 0; 449 | background: #fff; 450 | overflow: hidden; 451 | border: none; 452 | color: #4433ff 453 | } 454 | 455 | .css-button-sliding-top:hover { 456 | color: #fff 457 | } 458 | 459 | .css-button-sliding-top:hover:after { 460 | height: 100% 461 | } 462 | 463 | .css-button-sliding-top:after { 464 | content: ""; 465 | position: absolute; 466 | z-index: -1; 467 | transition: all 0.3s ease; 468 | left: 0; 469 | bottom: 0; 470 | height: 0; 471 | width: 100%; 472 | background: #4433ff 473 | } 474 | 475 | .css-button-sliding-right { 476 | min-width: 130px; 477 | height: 40px; 478 | color: #fff; 479 | padding: 5px 10px; 480 | font-weight: bold; 481 | cursor: pointer; 482 | transition: all 0.3s ease; 483 | position: relative; 484 | display: inline-block; 485 | outline: none; 486 | border-radius: 5px; 487 | z-index: 0; 488 | background: #fff; 489 | overflow: hidden; 490 | border: none; 491 | color: #4433ff 492 | } 493 | 494 | .css-button-sliding-right:hover { 495 | color: #fff 496 | } 497 | 498 | .css-button-sliding-right:hover:after { 499 | width: 100% 500 | } 501 | 502 | .css-button-sliding-right:after { 503 | content: ""; 504 | position: absolute; 505 | z-index: -1; 506 | transition: all 0.3s ease; 507 | left: 0; 508 | top: 0; 509 | width: 0; 510 | height: 100%; 511 | background: #4433ff 512 | } 513 | 514 | .css-button-sliding-left { 515 | min-width: 130px; 516 | height: 40px; 517 | color: #fff; 518 | padding: 5px 10px; 519 | font-weight: bold; 520 | cursor: pointer; 521 | transition: all 0.3s ease; 522 | position: relative; 523 | display: inline-block; 524 | outline: none; 525 | border-radius: 5px; 526 | z-index: 0; 527 | background: #fff; 528 | overflow: hidden; 529 | border: none; 530 | color: #4433ff 531 | } 532 | 533 | .css-button-sliding-left:hover { 534 | color: #fff 535 | } 536 | 537 | .css-button-sliding-left:hover:after { 538 | width: 100% 539 | } 540 | 541 | .css-button-sliding-left:after { 542 | content: ""; 543 | position: absolute; 544 | z-index: -1; 545 | transition: all 0.3s ease; 546 | right: 0; 547 | top: 0; 548 | width: 0; 549 | height: 100%; 550 | background: #4433ff 551 | } 552 | 553 | #carouselExampleCaptions, 554 | #carouselExampleCaptions img { 555 | width: 100%; 556 | 557 | } 558 | 559 | .on:after, 560 | .off:after { 561 | content: ""; 562 | width: 12px; 563 | height: 12px; 564 | border-radius: 50%; 565 | position: absolute; 566 | left: 8px; 567 | top: 50%; 568 | animation: pulse 1.5s infinite; 569 | } 570 | 571 | .on:after { 572 | background: green; 573 | } 574 | 575 | .off:after { 576 | background: red; 577 | } 578 | 579 | /* 定义动画 */ 580 | @keyframes pulse { 581 | 0% { 582 | transform: translateY(-50%) scale3d(1.2, 1.2, 1.2); 583 | } 584 | 585 | 586 | 50% { 587 | transform: translateY(-50%) scale3d(1, 1, 1); 588 | } 589 | 590 | 100% { 591 | transform: translateY(-50%) scale3d(1.2, 1.2, 1.2); 592 | } 593 | } 594 | 595 | #insertionModal { 596 | .modal-body { 597 | max-height: 450px; 598 | overflow: auto; 599 | } 600 | 601 | & td:nth-child(1) { 602 | width: 50%; 603 | } 604 | 605 | & td:nth-child(2) { 606 | width: 30%; 607 | } 608 | 609 | & td:nth-child(3) { 610 | width: 20%; 611 | } 612 | 613 | & input { 614 | width: 100%; 615 | outline-style: none; 616 | border: 1px solid #ccc; 617 | border-radius: 3px; 618 | } 619 | 620 | & input:focus { 621 | border: 1px solid #03a9f4; 622 | outline: 0; 623 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); 624 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6) 625 | } 626 | 627 | & select { 628 | outline-style: none; 629 | border: 1px solid #ccc; 630 | border-radius: 3px; 631 | } 632 | 633 | & select:focus { 634 | border: 1px solid #03a9f4; 635 | outline: 0; 636 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); 637 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6) 638 | } 639 | } -------------------------------------------------------------------------------- /Chromium/vendor/content_scripts/js/notification.js: -------------------------------------------------------------------------------- 1 | const storageAPI = typeof browser !== 'undefined' && browser.storage ? browser.storage : typeof chrome !== 'undefined' && chrome.storage ? chrome.storage : null; 2 | const maxNotifications = 8; // 最大允许的通知数量 3 | const notifications = []; 4 | /** 5 | * 6 | * @param {object} config 7 | * @returns 8 | * 创建通知函数 9 | */ 10 | function PLNotification(config) { 11 | const defaultConfig = { 12 | type: 'info', // 默认类型为信息通知 13 | title: chrome.i18n.getMessage("app_name") + ':', // 默认标题为通知 14 | content: 'No Data', // 默认内容为空 15 | duration: 10, // 默认持续时间为10秒 16 | style: "",// content的行内样式 17 | overwrite: true, // 默认重复内容覆盖 18 | saved: false, //存储通知,刷新页面也会通知 19 | button: [], //按钮组 20 | }; 21 | // 合并配置项 22 | config = { ...defaultConfig, ...config }; 23 | config.type = config.type === "信息" ? "info" : config.type === "成功" ? "success" : config.type === "失败" ? "error" : config.type === "警告" ? "warning" : config.type; 24 | if (notifications.length >= maxNotifications) { 25 | // 如果通知数量达到最大值,删除最早的通知 26 | const oldestNotification = notifications.shift(); 27 | closeNotification(oldestNotification, config); 28 | } 29 | 30 | let container = document.getElementById('notification-container'); 31 | if (!container) { 32 | container = document.createElement('div'); 33 | container.id = "notification-container" 34 | container.className = "notification-container" 35 | document.body.appendChild(container); 36 | } 37 | const successIcon = `` 38 | const warningIcon = `` 39 | const errorIcon = `` 40 | const infoIcon = `` 41 | const Icon = config.type === "success" ? successIcon : config.type === "warning" ? warningIcon : config.type === "error" ? errorIcon : infoIcon; 42 | const existingNotification = notifications.find(item => item.content === config.content); 43 | if (existingNotification && config.overwrite == true) { 44 | existingNotification.element.className = `notification ${config.type}`; 45 | existingNotification.element.querySelector(".icon").innerHTML = Icon; 46 | existingNotification.element.querySelector(".title").innerHTML = config.title; 47 | updateCountdown(config, existingNotification.element); 48 | updateNotificationInStorage(config, () => { 49 | console.log('通知已更新'); 50 | }); 51 | return; 52 | } 53 | // 如果没有重复的就执行以下 54 | 55 | // 构建通知 56 | const notification = document.createElement('div'); 57 | const maxZIndex = Math.pow(2, 31) - 1; // 设置 z-index 58 | container.style.zIndex = maxZIndex.toString(); 59 | notification.className = `notification ${config.type}`; 60 | notification.innerHTML = ` 61 |
    62 | ${Icon} 63 | ${config.title} 64 |
    65 |
    66 |
    ${config.content}
    `; 67 | 68 | // 通知的各种方法按钮 例如关闭 缩小 69 | const closeButton = document.createElement('button'); 70 | closeButton.innerHTML = 'X'; 71 | closeButton.className = "close" 72 | 73 | const reduceButton = document.createElement('button'); 74 | reduceButton.innerHTML = '>'; 75 | reduceButton.className = "reduce" 76 | 77 | 78 | notification.appendChild(closeButton); 79 | notification.appendChild(reduceButton) 80 | 81 | closeButton.addEventListener('click', () => { 82 | closeNotification(notification, config); 83 | }); 84 | reduceButton.addEventListener('click', () => { 85 | reduceNotification(notification); 86 | }); 87 | // 创建按钮容器 88 | let buttonsContainer; 89 | if (config.button) { 90 | buttonsContainer = document.createElement(config.button.label || 'div'); 91 | if (config.button.class) buttonsContainer.className = config.button.class; 92 | if (config.button.style) buttonsContainer.style = config.button.style; 93 | 94 | // 创建并添加按钮 95 | let buttons = config.button.but || config.button; 96 | if (Array.isArray(buttons)) { 97 | buttons.forEach(btnConfig => { 98 | const button = document.createElement('button'); 99 | button.textContent = btnConfig.text || "我是一个按钮"; 100 | if (btnConfig.class) button.className = btnConfig.class; 101 | if (btnConfig.style) button.style = btnConfig.style; 102 | 103 | const close = () => closeNotification(notification, config); 104 | if (typeof btnConfig.init === 'function') { 105 | btnConfig.init.call(button, close); 106 | } 107 | buttonsContainer.appendChild(button); 108 | }); 109 | } 110 | } 111 | 112 | if (buttonsContainer) { 113 | notification.appendChild(buttonsContainer); 114 | } 115 | 116 | 117 | updateCountdown(config, notification) 118 | notifications.push({ 119 | type: config.type, 120 | content: config.content, 121 | duration: config.duration, 122 | element: notification 123 | }); 124 | if (config.saved) { 125 | saveNotificationToStorage(config); 126 | } 127 | container.appendChild(notification); 128 | } 129 | // 更新倒计时 130 | let handleMouseEnter; 131 | let handleMouseLeave; 132 | let handleVisibilityChange; 133 | /** 134 | * 135 | * @param {object} config 136 | * @param {element} notification 137 | * @returns 138 | * 通知元素的时间相关 139 | */ 140 | function updateCountdown(config, notification) { 141 | if (config.duration < 1) { return; } 142 | let timer; // 用于存储倒计时计时器 143 | let progressBar = document.createElement('div'); 144 | progressBar.className = "progress-bar"; 145 | notification.appendChild(progressBar); // 插入进度条 146 | progressBar.style.animation = `PLprogress ${config.duration}s linear`; 147 | 148 | let remainingTime = config.duration; 149 | const updateRemainingTime = () => { 150 | progressBar.textContent = `${remainingTime}`; 151 | }; 152 | timer = setInterval(() => { 153 | remainingTime--; 154 | updateRemainingTime(); 155 | }, 1000); 156 | function handleAnimationEnd() { 157 | progressBar.removeEventListener('animationend', handleAnimationEnd); 158 | progressBar.remove(); 159 | closeNotification(notification, config); 160 | } 161 | handleVisibilityChange = () => { 162 | if (document.hidden) { 163 | // 页面不可见,停止倒计时和动画 164 | clearInterval(timer); 165 | progressBar.style.animationPlayState = 'paused'; 166 | } else { 167 | // 页面重新可见,恢复倒计时和动画 168 | timer = setInterval(() => { 169 | remainingTime--; 170 | updateRemainingTime(); 171 | }, 1000); 172 | progressBar.style.animationPlayState = 'running'; 173 | } 174 | }; 175 | handleMouseEnter = () => { 176 | // 鼠标悬停时停止倒计时和动画 177 | clearInterval(timer); 178 | progressBar.style.animationPlayState = 'paused'; 179 | }; 180 | handleMouseLeave = () => { 181 | // 鼠标离开时恢复倒计时和动画 182 | timer = setInterval(() => { 183 | remainingTime--; 184 | updateRemainingTime(); 185 | }, 1000); 186 | 187 | progressBar.style.animationPlayState = 'running'; 188 | }; 189 | progressBar.addEventListener('animationend', handleAnimationEnd); //动画化结束 190 | document.addEventListener('visibilitychange', handleVisibilityChange); //窗口可见 191 | notification.addEventListener('mouseenter', handleMouseEnter); 192 | notification.addEventListener('mouseleave', handleMouseLeave); 193 | } 194 | /** 195 | * @param {element} notification 196 | * @param {object} config 197 | * 关闭通知元素 198 | */ 199 | function closeNotification(notification, config) { 200 | removeNotificationFromStorage(config); 201 | notification.style.transform = 'translateX(100%)'; 202 | setTimeout(() => { 203 | notification.remove(); 204 | const index = notifications.findIndex(item => item.content === config.content); 205 | if (index !== -1) { 206 | notifications.splice(index, 1); 207 | } 208 | notification.removeEventListener('mouseenter', handleMouseEnter); 209 | notification.removeEventListener('mouseleave', handleMouseLeave); 210 | document.removeEventListener('visibilitychange', handleVisibilityChange); 211 | }, 300); 212 | } 213 | function reduceNotification(notification) { 214 | notification.style.minWidth === '100px' ? notification.style.minWidth = '200px' : notification.style.minWidth = '100px'; 215 | notification.querySelector('.reduce').textContent === ">" ? notification.querySelector('.reduce').textContent = "<" : notification.querySelector('.reduce').textContent = ">"; 216 | let children = notification.querySelectorAll('*'); 217 | // 遍历每个子元素并添加类 218 | children.forEach(child => { 219 | child.classList.toggle('reduceActive'); 220 | }); 221 | 222 | } 223 | 224 | /** 225 | * @param {*} callback 226 | * 从浏览器的 storage 获取保存的通知 227 | */ 228 | function getSavedNotifications(callback) { 229 | if (!storageAPI) { return console.error('存储API不受支持'); } 230 | storageAPI.local.get({ 'PLSavedNotifications': [] }, (data) => { 231 | const savedNotifications = data.PLSavedNotifications || []; 232 | callback(savedNotifications); 233 | }); 234 | } 235 | /** 236 | * @param {object} config 237 | * 保存通知到浏览器的 storage 238 | */ 239 | function saveNotificationToStorage(config) { 240 | if (!storageAPI) { return console.error('存储API不受支持'); } 241 | delete config.saved 242 | getSavedNotifications((savedNotifications) => { 243 | savedNotifications.push(config); 244 | if (savedNotifications.length > maxNotifications) { 245 | savedNotifications.shift(); 246 | } 247 | storageAPI.local.set({ 'PLSavedNotifications': savedNotifications }); 248 | }); 249 | } 250 | /** 251 | * 252 | * @param {object} config 253 | * 从浏览器的 storage 移除通知 254 | */ 255 | function removeNotificationFromStorage(config) { 256 | if (!storageAPI) { return console.error('存储API不受支持'); } 257 | getSavedNotifications((savedNotifications) => { 258 | const updatedNotifications = savedNotifications.filter( 259 | (item) => item.content !== config.content 260 | ); 261 | storageAPI.local.set({ 'PLSavedNotifications': updatedNotifications }); 262 | }); 263 | } 264 | /** 265 | * 266 | * @param {object} updatedNotification 267 | * @param {*} callback 268 | * 更新浏览器的 storage 中的通知 269 | */ 270 | function updateNotificationInStorage(updatedNotification, callback) { 271 | if (!storageAPI) { return console.error('存储API不受支持'); } 272 | getSavedNotifications((savedNotifications) => { 273 | const updatedNotifications = savedNotifications.map((notification) => { 274 | if (notification.content === updatedNotification.content) { 275 | return updatedNotification; 276 | } 277 | return notification; 278 | }); 279 | 280 | storageAPI.local.set({ 'PLSavedNotifications': updatedNotifications }, () => { 281 | if (typeof callback === 'function') { 282 | callback(); 283 | } 284 | }); 285 | }); 286 | } 287 | // 在页面加载时检索并显示已保存的通知 288 | (function () { 289 | getSavedNotifications((savedNotifications) => { 290 | for (const notification of savedNotifications) { 291 | PLNotification(notification); 292 | } 293 | }); 294 | })(); 295 | 296 | chrome.runtime.onMessage.addListener(function (request) { 297 | // chrome.runtime.sendMessage({ 298 | // PLNotification: { 299 | // type: 'info', // 默认类型为信息通知 300 | // title: '盘络上传:', // 默认标题为通知 301 | // content: 'No Data', // 默认内容为空 302 | // duration: 10, // 默认持续时间为10秒 303 | // saved: false, //存储通知,刷新页面也会通知 304 | // } 305 | // }); 306 | if (request.PLNotificationJS) { 307 | PLNotification(request.PLNotificationJS) 308 | } 309 | }); 310 | 311 | window.addEventListener('message', function (event) { 312 | // window.postMessage({ type: 'PLNotification', data: {} }, "*"); 313 | if (event.data.type === 'PLNotification') { 314 | const data = typeof event.data.data === "object" ? event.data.data : JSON.parse(event.data.data); 315 | PLNotification(data) 316 | } 317 | }); -------------------------------------------------------------------------------- /Chromium/vendor/content_scripts/js/Sticker.js: -------------------------------------------------------------------------------- 1 | let StickerOptional; 2 | function EmoticonBox() { 3 | let EmoticonBox = document.createElement('div'); 4 | const maxZIndex = Math.pow(2, 31) - 1; //设置index 5 | EmoticonBox.style.zIndex = maxZIndex.toString() - 1; 6 | EmoticonBox.className = 'PL-EmoticonBox'; 7 | EmoticonBox.style.display = "none" 8 | if (!document.getElementsByClassName("PL-EmoticonBox").length) { 9 | EmoticonBox.innerHTML = ` 10 |
    11 |
    12 |
    13 |
    14 |
    15 |
    16 |
    17 |
    18 | X 19 | 👈 20 |
    21 |

    焦点插入

    22 | 29 |
    30 |
    31 | 32 |
    33 |
    34 | ` 35 | document.body.appendChild(EmoticonBox); 36 | 37 | chrome.storage.local.get(['StickerOptional'], function (result) { 38 | document.getElementById("StickerOptional").checked = result.StickerOptional 39 | StickerOptional = result.StickerOptional 40 | }); 41 | document.getElementById("StickerOptional").addEventListener('click', function (event) { 42 | const isChecked = event.target.checked; 43 | if (isChecked) { 44 | chrome.storage.local.set({ 'StickerOptional': 1 }); 45 | 46 | } else { 47 | // 存储为0 48 | chrome.storage.local.set({ 'StickerOptional': 0 }); 49 | } 50 | StickerOptional = isChecked 51 | }); 52 | 53 | chrome.storage.local.get(['StickerCodeSelect'], function (result) { 54 | const selectedValue = result.StickerCodeSelect; 55 | const StickerCodeSelect = document.getElementById("StickerCodeSelect"); 56 | if (selectedValue) { 57 | StickerCodeSelect.value = selectedValue; 58 | } 59 | }); 60 | document.getElementById("StickerCodeSelect").addEventListener('change', function (event) { 61 | const selectedValue = this.value 62 | chrome.storage.local.set({ "StickerCodeSelect": selectedValue }); 63 | }); 64 | let StickerBoxLeftBut = 0 65 | document.querySelector(".StickerBoxLeftBut").addEventListener('click', function (event) { 66 | if (StickerBoxLeftBut == 0) { 67 | this.innerText = '👉' 68 | document.querySelector(".StickerBoxLeft").style.display = 'flex'; 69 | StickerBoxLeftBut = 1 70 | } else { 71 | this.innerText = '👈' 72 | document.querySelector(".StickerBoxLeft").style.display = 'none'; 73 | StickerBoxLeftBut = 0 74 | } 75 | 76 | }); 77 | 78 | // 添加拖动逻辑 79 | let isDragging = false; 80 | let offsetX, offsetY; 81 | 82 | document.querySelector(".StickerBoxContent").addEventListener('mousedown', startDrag); 83 | document.addEventListener('mousemove', drag); 84 | document.addEventListener('mouseup', stopDrag); 85 | 86 | function startDrag(event) { 87 | if (event.target.tagName.toLowerCase() === 'img') { 88 | return; // 如果拖动的是 元素,不进行拖动处理 89 | } 90 | isDragging = true; 91 | offsetX = event.clientX - EmoticonBox.offsetLeft; 92 | offsetY = event.clientY - EmoticonBox.offsetTop; 93 | } 94 | 95 | function drag(event) { 96 | if (isDragging) { 97 | const x = event.clientX - offsetX; 98 | const y = event.clientY - offsetY; 99 | EmoticonBox.style.left = x + 'px'; 100 | EmoticonBox.style.top = y + 'px'; 101 | } 102 | } 103 | 104 | function stopDrag() { 105 | isDragging = false; 106 | } 107 | 108 | 109 | 110 | function makeHorizontalDraggable(element) { 111 | let isDragging = false; 112 | let startPosX = 0; 113 | let startScrollLeft = 0; 114 | 115 | element.addEventListener('mousedown', (e) => { 116 | isDragging = true; 117 | startPosX = e.clientX; 118 | startScrollLeft = element.scrollLeft; 119 | element.style.cursor = 'grabbing'; 120 | e.preventDefault(); // 防止选中文字 121 | }); 122 | 123 | document.addEventListener('mousemove', (e) => { 124 | if (!isDragging) return; 125 | 126 | const deltaX = e.clientX - startPosX; 127 | element.scrollLeft = startScrollLeft - deltaX; 128 | }); 129 | 130 | document.addEventListener('mouseup', () => { 131 | isDragging = false; 132 | element.style.cursor = 'grab'; 133 | }); 134 | } 135 | makeHorizontalDraggable(document.querySelector('.StickerBoxhead')); 136 | } 137 | } 138 | EmoticonBox() 139 | function mainLogic(insertContentPrompt) { 140 | const emoticonBox = document.querySelector('.PL-EmoticonBox'); 141 | let timerShow; 142 | let timerHide; 143 | let getStickerStatus = false; 144 | let isShow = false; 145 | insertContentPrompt.addEventListener('mouseenter', () => { 146 | clearTimeout(timerHide); // 鼠标进入时清除隐藏的定时器 147 | if (isShow) return; //防止重复触发 148 | timerShow = setTimeout(() => { 149 | showEmoticonBox(); 150 | }, 800); 151 | }); 152 | insertContentPrompt.addEventListener('mouseleave', () => { 153 | clearTimeout(timerShow); // 鼠标离开时清除显示的定时器 154 | timerHide = setTimeout(() => { 155 | hideEmoticonBox(); 156 | }, 1000); // 一秒后隐藏 157 | }); 158 | 159 | emoticonBox.addEventListener('mouseenter', () => { 160 | clearTimeout(timerHide); // 鼠标进入 emoticonBox 时清除隐藏的定时器 161 | }); 162 | 163 | emoticonBox.addEventListener('mouseleave', () => { 164 | timerHide = setTimeout(() => { 165 | hideEmoticonBox(); 166 | }, 2000); // 一秒后隐藏 167 | }); 168 | 169 | function showEmoticonBox() { 170 | isShow = true; 171 | clearTimeout(timerHide); 172 | const promptRect = insertContentPrompt.getBoundingClientRect(); 173 | const scrollY = window.scrollY || window.pageYOffset; //滚动条位置 174 | const scrollX = window.scrollX || window.pageXOffset; //滚动条位置 175 | 176 | const emoticonBoxWidth = 420 //贴纸盒子的宽度 177 | const emoticonBoxHeight = 200 //贴纸盒子的高度 178 | 179 | const viewportWidth = window.innerWidth;// 获取视口的可见宽 180 | const viewportHeight = window.innerHeight;// 获取视口的可见高度 181 | 182 | const spaceBelow = (scrollY + viewportHeight) - (scrollY + promptRect.bottom) 183 | 184 | const LeftRightPositions = scrollX + promptRect.left 185 | if (LeftRightPositions >= emoticonBoxWidth) { 186 | emoticonBox.style.left = `${promptRect.right - emoticonBoxWidth + 12}px`; 187 | 188 | } else { 189 | emoticonBox.style.left = `${promptRect.left}px`; 190 | } 191 | 192 | if (spaceBelow >= emoticonBoxHeight) { 193 | // 下方空间足够,显示在下方 194 | emoticonBox.style.top = `${promptRect.bottom + scrollY + 10}px`; 195 | } else { 196 | emoticonBox.style.top = `${promptRect.top + scrollY - emoticonBoxHeight - 10}px`; 197 | } 198 | emoticonBox.style.display = 'block'; 199 | 200 | dbHelper("Sticker").then(function (result) { 201 | const { db } = result; 202 | db.getAll().then(Sticker => { 203 | chrome.storage.local.get(["StickerHeadSelected"], function (result) { 204 | emoticonBox.style.width = "420px"; 205 | let StickerDATA = Sticker || [] 206 | let StickerHeadSelected = result.StickerHeadSelected || 0 207 | if (getStickerStatus == true) { 208 | getSticker(1, db) 209 | return; 210 | } 211 | if (StickerDATA.length == 0) { 212 | //首次加载贴纸 213 | getSticker(0, db) 214 | } else { 215 | //存储里的贴纸 216 | DataRendering(StickerDATA, StickerHeadSelected, db) 217 | } 218 | }) 219 | }) 220 | 221 | }); 222 | } 223 | 224 | // 隐藏贴纸框 225 | function hideEmoticonBox() { 226 | isShow = false; 227 | emoticonBox.style.width = "0px"; 228 | setTimeout(() => { 229 | emoticonBox.style.display = 'none'; 230 | }, 500) 231 | } 232 | document.querySelector(".StickerBox .StickerBoxRemove").addEventListener('click', function (event) { 233 | hideEmoticonBox() 234 | }) 235 | 236 | // 获取网络贴纸 237 | function getSticker(IsGet, db) { 238 | chrome.storage.local.get(["StickerURL"], function (result) { 239 | fetch('https://cors-anywhere.pnglog.com/' + result.StickerURL) 240 | .then(response => { 241 | return response.json(); // 解析JSON数据 242 | }) 243 | .then(data => { 244 | if (data.sticker) { 245 | data.sticker.forEach((item, index) => { 246 | if (item.id === undefined) { 247 | item.id = index; 248 | } 249 | if (item.index === undefined) { 250 | item.index = item.id || index; 251 | } 252 | }); 253 | db.put(data.sticker).catch(error => { 254 | console.log(error); 255 | }); 256 | if (IsGet == 1) { 257 | return; 258 | } 259 | DataRendering(data.sticker, 0) 260 | } 261 | }) 262 | .catch(error => { 263 | console.error(error); 264 | }); 265 | }) 266 | } 267 | 268 | // 贴纸渲染 269 | function DataRendering(data, StickerHeadSelected) { 270 | const StickerBoxhead = document.querySelector('.StickerBoxhead'); // 获取贴纸标题元素 271 | const StickerBoxContent = document.querySelector('.StickerBoxContent'); // 获取贴纸内容元素 272 | StickerBoxContent.innerHTML = ''; 273 | let currentPage = 1; 274 | const itemsPerPage = 20; 275 | let Selected = StickerHeadSelected 276 | function updateSelectedStatus(selectedIndex) { 277 | const selectedItems = document.querySelectorAll('.StickerBoxheadtem'); 278 | selectedItems.forEach((item, index) => { 279 | item.style.color = index === selectedIndex ? "red" : "#fff"; 280 | }); 281 | } 282 | 283 | data.forEach(function (sticker, index) { 284 | const StickerBoxheadtem = document.createElement('div'); 285 | StickerBoxheadtem.className = 'StickerBoxheadtem'; 286 | StickerBoxheadtem.textContent = sticker.StickerTitle; 287 | StickerBoxheadtem.title = sticker.StickerAuthor; 288 | StickerBoxhead.appendChild(StickerBoxheadtem); 289 | StickerBoxheadtem.addEventListener('click', function (event) { 290 | StickerBoxContent.innerHTML = ''; 291 | currentPage = 1; 292 | Selected = index 293 | updateSelectedStatus(index); 294 | StickerDataItem(index); 295 | chrome.storage.local.set({ 'StickerHeadSelected': index }) 296 | }) 297 | }) 298 | function StickerDataItem(index) { 299 | if (data[index].StickerData.length == 0) { 300 | StickerBoxContent.innerHTML = '数据为空'; 301 | return; 302 | } 303 | const startIndex = (currentPage - 1) * itemsPerPage; 304 | const endIndex = startIndex + itemsPerPage; 305 | 306 | const EmotionPreview = document.getElementById('PL-EmotionPreview') 307 | const stickersToDisplay = data[index].StickerData.slice(startIndex, endIndex); 308 | 309 | // 贴纸遍历 310 | stickersToDisplay.forEach((sticker, stickerIndex) => { 311 | const StickerBoxContentitem = document.createElement('div'); 312 | StickerBoxContentitem.className = 'StickerBoxContentitem'; 313 | const img = document.createElement('img'); 314 | img.src = sticker.StickerURL; 315 | img.alt = sticker.StickerName; 316 | img.title = sticker.StickerName; 317 | img.loading = "lazy"; 318 | img.addEventListener('click', function (event) { 319 | if (StickerOptional == 1) { 320 | chrome.storage.local.get(['StickerCodeSelect'], function (result) { 321 | const selectedValue = result.StickerCodeSelect; 322 | let url; 323 | switch (selectedValue) { 324 | case 'URL': 325 | url = sticker.StickerURL 326 | break; 327 | case 'HTML': 328 | url = '' 329 | break; 330 | case 'BBCode': 331 | url = '[img]' + sticker.StickerURL + '[/img]' 332 | break; 333 | case 'Markdown': 334 | url = '![' + sticker.StickerName + '](' + sticker.StickerURL + ')' 335 | break; 336 | case 'MD with link': 337 | url = '[![' + sticker.StickerName + '](' + sticker.StickerURL + ')](' + sticker.StickerURL + ')' 338 | break; 339 | } 340 | AutoInsertFun(url, true); 341 | return; 342 | }); 343 | } 344 | AutoInsertFun(sticker.StickerURL, false) 345 | }) 346 | img.addEventListener('mouseover', function () { 347 | EmotionPreview.style.display = "block" 348 | EmotionPreview.src = this.src; 349 | }); 350 | img.addEventListener('mouseleave', function () { 351 | EmotionPreview.style.display = "none" 352 | }); 353 | StickerBoxContentitem.appendChild(img); 354 | StickerBoxContent.appendChild(StickerBoxContentitem); 355 | if (stickerIndex === stickersToDisplay.length - 1) { 356 | img.parentNode.classList.add('lastSticker'); 357 | } 358 | }); 359 | 360 | 361 | // 视口懒加载 362 | function handleIntersection(entries, observer) { 363 | let foundLastSticker = false; 364 | entries.forEach(entry => { 365 | if (entry.isIntersecting) { 366 | try { 367 | document.querySelector('.lastSticker').classList.remove('lastSticker'); 368 | currentPage++; 369 | StickerDataItem(Selected); 370 | foundLastSticker = true; 371 | } catch (error) { 372 | return; 373 | } 374 | } 375 | }); 376 | // 如果没有找到 .lastSticker 元素,取消监听 377 | if (foundLastSticker) { 378 | observer.disconnect(); 379 | } 380 | } 381 | const observer = new IntersectionObserver(handleIntersection); 382 | setTimeout(() => { 383 | const elementsWithLastStickerClass = document.querySelectorAll('.lastSticker'); 384 | elementsWithLastStickerClass.forEach(element => { 385 | observer.observe(element); 386 | }); 387 | }, 500); 388 | 389 | } 390 | updateSelectedStatus(Selected); 391 | StickerDataItem(Selected); 392 | getStickerStatus = true 393 | } 394 | } 395 | 396 | -------------------------------------------------------------------------------- /Chromium/vendor/content_scripts/js/FullDomPermissions.js: -------------------------------------------------------------------------------- 1 | // 拥有完整dom权限 2 | window.addEventListener('message', function (event) { 3 | console.log("postMessage监听: ", event.data); 4 | if (event.data.type === 'CodeMirror5') { 5 | let editorElement = document.querySelector(".CodeMirror"); 6 | if (editorElement) { 7 | const content = editorElement.CodeMirror.getValue(); 8 | const newContent = content + event.data.data; 9 | editorElement.CodeMirror.setValue(newContent); 10 | } 11 | } 12 | if (event.data.type === 'Gutenberg') { 13 | try { 14 | let Gutenberg = wp.data.dispatch('core/block-editor'); 15 | if (Gutenberg) { 16 | const imageBlock = wp.blocks.createBlock('core/image', { url: event.data.data }); 17 | Gutenberg.insertBlock(imageBlock); 18 | } 19 | } catch (err) { 20 | } 21 | 22 | } 23 | if (event.data.type === 'TinyMCE') { 24 | try { 25 | let TinyMCEs = tinymce.activeEditor; 26 | if (TinyMCEs) { 27 | tinymce.activeEditor.execCommand('mceInsertContent', false, event.data.data); 28 | } 29 | } catch (error) { 30 | } 31 | } 32 | if (event.data.type === 'wangeditor') { 33 | try { 34 | let wangeditor_Element = editor.getEditableContainer() 35 | if (wangeditor_Element) { 36 | editor.dangerouslyInsertHtml(event.data.data) 37 | } 38 | } catch (error) { 39 | } 40 | 41 | } 42 | if (event.data.type === 'ckeditor') { 43 | try { 44 | let ckeditor_Element = Object.values(CKEDITOR.instances)[0]; 45 | if (ckeditor_Element) { 46 | ckeditor_Element.insertHtml(event.data.data); 47 | } 48 | return; 49 | } catch (error) { 50 | } 51 | try { 52 | let ckeditor_Element = editor; 53 | if (ckeditor_Element) { 54 | const content = ckeditor_Element.getData(); 55 | ckeditor_Element.setData(content + event.data.data); 56 | } 57 | return; 58 | } catch (error) { 59 | } 60 | } 61 | if (event.data.type === 'ckeditor4') { 62 | try { 63 | let ckeditor_Element = Object.values(CKEDITOR.instances)[0]; 64 | if (ckeditor_Element) { 65 | ckeditor_Element.insertHtml(event.data.data); 66 | } 67 | } catch (error) { 68 | } 69 | 70 | } 71 | if (event.data.type === 'ckeditor5') { 72 | try { 73 | let ckeditor_Element = editor; 74 | if (ckeditor_Element) { 75 | const content = ckeditor_Element.getData(); 76 | ckeditor_Element.setData(content + event.data.data); 77 | } 78 | } catch (error) { 79 | } 80 | 81 | } 82 | if (event.data.type === 'ueditor') { 83 | try { 84 | let ueditor_Element = UE.getEditor("editor_content"); 85 | if (ueditor_Element) { 86 | ueditor_Element.execCommand('insertimage', { 87 | src: event.data.data, 88 | }); 89 | } 90 | } catch (error) { 91 | } 92 | 93 | } 94 | if (event.data.type === 'phpbbForum') { 95 | try { 96 | let phpbbForum = phpbb; 97 | if (phpbbForum) { 98 | let phpbbEditor = document.getElementById("message") 99 | phpbbEditor.value += event.data.data; 100 | event.source.postMessage({ type: 'phpbbForumResponse', data: true }, event.origin); 101 | } 102 | } catch (error) { 103 | event.source.postMessage({ type: 'phpbbForumResponse', data: false }, event.origin); 104 | } 105 | 106 | } 107 | //自动复制 108 | if (event.data.type === 'AutoCopy') { 109 | let value = event.data.data; 110 | // 使用 Clipboard API 复制文本内容到剪贴板 111 | navigator.clipboard.writeText(value) 112 | .then(() => { 113 | console.log("已复制到剪贴板:" + value); 114 | }) 115 | .catch(error => { 116 | console.error("复制到剪贴板失败:" + error); 117 | }); 118 | } 119 | //刷新 120 | if (event.data.type === 'pageRefresh') { 121 | window.location.reload(); 122 | } 123 | }); 124 | function detectEncoding() { 125 | const charsetMeta = document.querySelector('meta[charset]'); 126 | if (charsetMeta) { 127 | return charsetMeta.getAttribute('charset').toLowerCase(); 128 | } 129 | return 'unknown'; 130 | } 131 | 132 | function insertImageDiv(element, link, CssName) { 133 | const imgDiv = document.createElement('div'); 134 | const imgElement = document.createElement('img'); 135 | imgElement.src = link; 136 | if (CssName) { 137 | imgElement.className = CssName; 138 | } 139 | imgElement.loading = "lazy"; 140 | 141 | imgDiv.appendChild(imgElement); 142 | element.appendChild(imgDiv); 143 | imgElement.onload = function () { 144 | imgDiv.className = `position-relative PL-ImgMark`; 145 | imgElement.alt = "扩展转换"; 146 | imgElement.title = link; 147 | 148 | if (!CssName) { 149 | // 如果图片宽度大于父元素宽度,将图片宽度设置为100% 150 | if (imgElement.width > element.clientWidth) { 151 | imgElement.style.width = "100%"; 152 | } 153 | } 154 | 155 | }; 156 | imgElement.onerror = function () { 157 | imgDiv.remove() 158 | }; 159 | } 160 | 161 | function FullDomAutoInsert() { 162 | let item = document.createElement('div'); 163 | item.className = "insertContentIntoEditorPrompt" 164 | item.innerText = "😍扩展" 165 | item.addEventListener('click', function () { 166 | window.postMessage({ type: 'insertContentIntoEditorPrompt_Click', data: true }, '*'); 167 | }); 168 | const supportedImageFormats = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp', '.ico']; 169 | const detectedEncoding = detectEncoding(); 170 | if (detectedEncoding !== 'utf-8') { 171 | // 不是utf-8 172 | item.innerText = "PL-Upload" 173 | } 174 | 175 | let success = false; 176 | let pageText = document.body.innerText; 177 | let currentURL = window.location.href; 178 | //Discuz 179 | if (pageText.toLowerCase().includes("discuz") || pageText.toLowerCase().includes("论坛") == true) { 180 | let DiscuzReply = document.getElementById("fastpostmessage") 181 | let Discuz_ReplyAdvanced = document.getElementById("e_textarea") 182 | if (DiscuzReply) { 183 | let fastpostsubmit = document.getElementById("fastpostsubmit") 184 | fastpostsubmit.parentNode.appendChild(item) 185 | success = "Discuz" 186 | } 187 | if (Discuz_ReplyAdvanced) { 188 | Discuz_ReplyAdvanced.parentNode.parentNode.appendChild(item) 189 | success = "Discuz" 190 | } 191 | // url转图片 192 | const topicContentElements = Array.from(document.querySelectorAll('.t_f')); 193 | ContentElements(topicContentElements); 194 | function ContentElements(ContentElements) { 195 | if (ContentElements.length < 1) { 196 | return; 197 | } 198 | for (const replyContent of ContentElements) { 199 | const clonedParagraph = replyContent.cloneNode(true); 200 | const imgElements = Array.from(clonedParagraph.querySelectorAll('img')); 201 | for (const imgElement of imgElements) { 202 | imgElement.remove(); 203 | } 204 | 205 | const text = clonedParagraph.textContent; 206 | const imageLinks = text.match(/https?:\/\/[^\s]+/g) || []; 207 | // 去除屁股的html标签 208 | const cleanedImageLinks = imageLinks.map(link => link.replace(/<\/?[^>]+(>|$)/g, '')); 209 | cleanedImageLinks.forEach(link => { 210 | insertImageDiv(replyContent, link); 211 | }); 212 | } 213 | } 214 | 215 | 216 | } 217 | //v2exReply 218 | if (currentURL.toLowerCase().includes("v2ex.com")) { 219 | if (success != false) { 220 | return success; 221 | } 222 | let topic_content = document.getElementById("topic_content") 223 | if (pageText.toLowerCase().includes("主题创建指南")) { 224 | if (topic_content) { 225 | topic_content.parentNode.appendChild(item) 226 | success = true 227 | } 228 | } 229 | let reply_content = document.getElementById("reply_content") 230 | if (reply_content) { 231 | reply_content.parentNode.appendChild(item) 232 | item.title = "v2ex提示:非imgur图床,未安装用户无法预览" 233 | success = true 234 | } 235 | // url转图片 236 | const topicContentElements = Array.from(document.querySelectorAll('.topic_content')); 237 | ContentElements(topicContentElements) 238 | const replyContentElements = Array.from(document.querySelectorAll('.reply_content')); 239 | ContentElements(replyContentElements) 240 | function ContentElements(ContentElements) { 241 | if (ContentElements.length < 1) { 242 | return 243 | } 244 | for (const replyContent of ContentElements) { 245 | const anchorElements = Array.from(replyContent.querySelectorAll('a')); 246 | for (const anchorElement of anchorElements) { 247 | const imgElements = Array.from(anchorElement.querySelectorAll('img')); 248 | if (imgElements.length === 0) { 249 | const href = anchorElement.getAttribute('href'); 250 | insertImageDiv(anchorElement, href, "embedded_image"); 251 | } 252 | } 253 | } 254 | } 255 | 256 | } 257 | //nodeseek 258 | if (currentURL.toLowerCase().includes("nodeseek.com")) { 259 | if (success != false) { 260 | return success; 261 | } 262 | let nodeseek = document.getElementById("markdown-input") 263 | if (nodeseek) { 264 | nodeseek.parentNode.parentNode.appendChild(item) 265 | success = "nodeseek" 266 | } 267 | 268 | const topicContentElements = Array.from(document.querySelectorAll('.post-content')); 269 | ContentElements(topicContentElements); 270 | function ContentElements(ContentElements) { 271 | if (ContentElements.length < 1) { 272 | return; 273 | } 274 | for (const replyContent of ContentElements) { 275 | const anchorElements = Array.from(replyContent.querySelectorAll('p')); 276 | for (const anchorElement of anchorElements) { 277 | const clonedParagraph = anchorElement.cloneNode(true); 278 | const imgElements = Array.from(clonedParagraph.querySelectorAll('img')); 279 | for (const imgElement of imgElements) { 280 | imgElement.remove(); 281 | } 282 | const text = clonedParagraph.textContent; 283 | const imageLinks = text.match(/https?:\/\/[^\s]+/g) || []; 284 | // 去除屁股的html标签 285 | const cleanedImageLinks = imageLinks.map(link => link.replace(/<\/?[^>]+(>|$)/g, '')); 286 | cleanedImageLinks.forEach(link => { 287 | insertImageDiv(anchorElement, link); 288 | }); 289 | } 290 | } 291 | } 292 | 293 | 294 | } 295 | //Xiuno 296 | if (pageText.toLowerCase().includes("xiuno")) { 297 | if (success != false) { 298 | return success; 299 | } 300 | if (pageText.toLowerCase().includes("粗体") || pageText.toLowerCase().includes("回帖")) { 301 | let Xiuno = document.getElementById("message") 302 | if (Xiuno) { 303 | Xiuno.parentNode.parentNode.appendChild(item) 304 | success = "Xiuno" 305 | } 306 | } 307 | if (pageText.toLowerCase().includes("回复") || pageText.toLowerCase().includes("楼主")) { 308 | item.innerText = "😭扩展" 309 | } 310 | } 311 | //hostevaluate 312 | if (currentURL.toLowerCase().includes("hostevaluate.com")) { 313 | if (success != false) { 314 | return success; 315 | } 316 | let new_topic = document.getElementById("new_topic") 317 | if (new_topic) { 318 | new_topic.parentNode.appendChild(item) 319 | success = "hostevaluate" 320 | } 321 | } 322 | //typecho 323 | if (pageText.toLowerCase().includes("typecho")) { 324 | if (success != false) { 325 | return success; 326 | } 327 | let Typecho = document.getElementById("btn-submit") 328 | if (Typecho) { 329 | Typecho.parentNode.appendChild(item) 330 | success = "typecho" 331 | } 332 | } 333 | //lowendtalk 334 | if (currentURL.toLowerCase().includes("lowendtalk.com")) { 335 | if (success != false) { 336 | return success; 337 | } 338 | let lowendtalkEditor = document.getElementById("Form_Body") 339 | if (lowendtalkEditor) { 340 | lowendtalkEditor.parentNode.appendChild(item) 341 | success = "lowendtalk" 342 | } 343 | } 344 | //CodeMirror Editor 345 | let editorElement = document.querySelector(".CodeMirror"); 346 | if (editorElement) { 347 | if (success != false) { 348 | return success; 349 | } 350 | editorElement.parentNode.appendChild(item) 351 | success = "CodeMirror" 352 | } 353 | //Gutenberg Editor 354 | let Gutenberg = document.getElementById("wpbody-content") 355 | if (Gutenberg) { 356 | if (success != false) { 357 | return success; 358 | } 359 | let wpfooter = document.getElementsByClassName("interface-interface-skeleton__footer") 360 | if (wpfooter.length) { 361 | wpfooter[wpfooter.length - 1].appendChild(item) 362 | success = "Gutenberg" 363 | } 364 | 365 | } 366 | //halo 367 | let HaloEditorElement = document.getElementsByClassName("halo-rich-text-editor") 368 | if (HaloEditorElement.length) { 369 | if (success != false) { 370 | return success; 371 | } 372 | let HaloEditorHeader = HaloEditorElement[0].querySelector('.editor-header'); 373 | HaloEditorHeader.appendChild(item) 374 | success = "halo" 375 | } 376 | let CodeMirror6 = document.querySelector(".cm-editor"); 377 | if (CodeMirror6) { 378 | if (success != false) { 379 | return success; 380 | } 381 | CodeMirror6.parentNode.appendChild(item) 382 | success = "CodeMirror6" 383 | } 384 | //tinymce 385 | try { 386 | if (success != false) { 387 | return success; 388 | } 389 | let TinyMCE_Elements = tinymce.activeEditor 390 | if (TinyMCE_Elements) { 391 | let container = TinyMCE_Elements.getContainer(); 392 | container.appendChild(item) 393 | success = "tinymce"; 394 | } 395 | } catch (error) { 396 | } 397 | //wangeditor 398 | try { 399 | if (success != false) { 400 | return success; 401 | } 402 | let wangeditor_Elements = editor.getEditableContainer() 403 | if (wangeditor_Elements) { 404 | wangeditor_Elements.appendChild(item) 405 | success = "wangeditor"; 406 | } 407 | } catch (error) { 408 | 409 | } 410 | //ckeditor 4 411 | try { 412 | if (success != false) { 413 | return success; 414 | } 415 | let ckeditor_Elements = Object.values(CKEDITOR.instances)[0]; 416 | let ckeditor_Element_Node = ckeditor_Elements.container.$ 417 | if (ckeditor_Element_Node) { 418 | ckeditor_Element_Node.appendChild(item) 419 | success = "ckeditor4"; 420 | } 421 | } catch (error) { 422 | } 423 | //ueditor 424 | try { 425 | if (success != false) { 426 | return success; 427 | } 428 | let ueditor_Elements = UE.getEditor("editor_content"); 429 | let ueditor_Elements_Node = ueditor_Elements.container 430 | if (ueditor_Elements_Node) { 431 | ueditor_Elements_Node.appendChild(item) 432 | success = "ueditor"; 433 | } 434 | } catch (error) { 435 | 436 | } 437 | // phpbb 438 | try { 439 | if (success != false) { 440 | return success; 441 | } 442 | let phpbbForum = phpbb; 443 | if (phpbbForum) { 444 | let phpbbEditor = document.getElementById("message").parentElement 445 | phpbbEditor.appendChild(item) 446 | success = "phpbb"; 447 | } 448 | } catch (error) { 449 | } 450 | 451 | let iframe = document.querySelector('iframe'); 452 | if (iframe) { 453 | if (success != false) { 454 | return success; 455 | } 456 | try { 457 | let iframeDocument = iframe.contentDocument || iframe.contentWindow.document; 458 | let editableElement = iframeDocument.querySelector('[contenteditable="true"]'); 459 | 460 | if (editableElement) { 461 | iframe.parentNode.appendChild(item) 462 | success = "iframe"; 463 | } 464 | } catch (error) { 465 | console.error(error) 466 | } 467 | } 468 | return success; 469 | } 470 | setTimeout(() => { 471 | let AutoInsert = FullDomAutoInsert() 472 | if (AutoInsert != false) { 473 | window.postMessage({ type: 'insertContentIntoEditorState', data: true }, '*'); 474 | } 475 | }, 800); 476 | 477 | -------------------------------------------------------------------------------- /Chromium/FAQ.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 常见问题 9 | 10 | 11 | 12 | 13 | 14 | 15 | 26 | 27 | 28 | 29 | 52 | 53 |
    54 | 55 | 56 |

    使用Ctrl+F快速搜索

    57 |

    请使用开发者工具(F12)查看错误代码

    58 |
    59 | 99 | 100 |
    101 |
    102 |
    103 |

    错误代码:服务器返回 0 代码

    104 |

    一般情况下这个错误表示上传服务器域名错误,会出现在域名是兰空图床程序,而用户选择了简单图床程序的时候出现错误。

    105 |
    106 |
    107 |

    错误代码:Unauthenticated或者[object Object]

    108 |

    这个表示身份验证错误,请检查Token值或者UID值

    109 |
    110 |
    111 |

    Uncaught SyntaxError: Unexpected token '←', "←br /→←b→"... is not valid JSON

    112 |

    简单图床的身份验证错误,请检查Token值

    113 |
    114 |
    115 |

    ....CORS policy: Response to preflight request doesn't pass access control check: 116 | No 117 | 'Access-Control-Allow-Origin' header is present on the requested resource.

    118 |

    表示服务器未启用跨域(CORS)处理解决办法

    119 |

    1.如果是用户请联系服务商管理员

    120 |

    2.如果是服务商管理员请查看对应的图床程序api手册,或者联系图床程序作者进行协作处理

    121 |

    3.*使用cors代理上传。部署自己的cors代理https://github.com/Rob--W/cors-anywhere,或者使用临时代理:https://cors-anywhere.herokuapp.com/

    124 |

    4.*关闭浏览器的跨域(CORS)处理:在浏览器快捷键的启动路径后面插入(请注意空格)" --disable-web-security --user-data-dir=F:\edge\data"F:\edge\data为用户配置数据路径,可以自定义。 126 |

    127 |

    128 |
    129 |
    130 |

    为什么右键上传/粘贴上传的图片本地记录找不到,或者上传失败?

    131 |

    如果是右键上传,可能就是单纯的失败了,原因很多,建议多试一下或者在扩展里重新开关一下插件。

    132 |

    如果是粘贴的网络资源,也没见上传成功提示说明该图片资源类型不是image类型。所以没有上传,程序上是可以转换的但是没做因为如果使用转换将可以上传很多不是图片的文件。

    133 |
    134 |
    135 |

    画圆手势拖动上传默认模式和增强模式有什么区别?(功能已丢弃)

    136 |

    默认模式:这个模式会在打开网页的时候检测页面的图片(img标签)元素并绑定手势动作,对于后来加载的网页则没有效果。

    137 |

    增强模式:非常暴力的检测页面所有节点的刷新动态,如果页面刷新数据过于庞大如百度图片页面,会绑定出海量的图片元素。所有效果也是最好的,就没有失效的情况!

    138 |

    更具体的区别可以在页面按F12打开控制台查看执行次数

    139 |
    140 |
    141 |

    为什么画圆识别成功了,还需要拖拽到框框里才能上传这么麻烦?(功能已丢弃)

    142 |

    因为会触发bug如果拖拽过快就会被秒识别成功,直接跳过手势步骤所以才加了这个规则

    143 |

    144 |
    145 |
    146 |

    本地文件全局上传默认模式和增强模式有什么区别?

    147 |

    不建议与画圆手势拖动上传同时开启,除非你能分辨他们的区别

    148 |

    默认模式:只支持本地文件拖拽到右下角的图标进行上传,或者拖拽到提示框中取消上传

    149 |

    增强模式:允许拖拽到浏览器页面的任意位置进行上传,除了页面内的上传框,或者拖拽到提示框中取消上传

    150 |
    151 |
    152 |

    S3支持都支持那些商家?

    153 |

    理论支持所有S3兼容的对象存储

    154 |
    155 |
    156 |

    对象存储是否支持普通文件上传?

    157 |

    是的目前对象存储已实现文件上传,最大每次5G

    158 |
    159 |
    160 |

    自动插入现在支持网站?

    161 | 162 | 163 |

    目前支持(经测试的)

    164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 |
    /回复楼主回复楼层发帖
    程序
    Discuz程序论坛3.4支持支持支持
    Xiuno程序论坛支持支持支持
    typecho博客支持(文章)
    WordPress博客(6.2以上)支持(古腾堡)
    编辑器
    CodeMirror理论支持理论支持理论支持
    TinyMCE 5/6理论支持理论支持理论支持
    wangEditor理论支持理论支持理论支持
    ckEditor4/5理论支持理论支持理论支持
    古腾堡理论支持理论支持理论支持
    站点
    GitHub支持(在线编辑)
    v2ex不支持不支持支持
    liyuans支持支持支持
    nodeseek支持支持支持
    hostevaluate不支持支持支持
    hostloc支持支持支持
    52破解支持支持支持
    52辅助支持支持支持
    mcbbs支持支持支持
    藏宝湾支持支持支持
    大佬论坛支持(高级回复)不支持支持
    316 | 317 |
    318 |
    319 |

    简单图床Token获取

    320 |

    321 |
    322 |
    323 |

    imgurl图床Token、UID获取

    324 |

    325 |
    326 |
    327 |

    imgur图床Client-ID获取

    328 |

    点击注册Client-ID

    330 |

    331 |

    按照实际情况填写

    332 |
    333 |
    334 |

    GitHub的Token获取

    335 |

    点击跳转创建

    336 |

    337 |

    选择经典token

    338 |

    339 |

    设置名称,选择过期时间和权限

    340 |

    341 |

    还有一个权限,选完创建即可!

    342 |
    343 |
    344 |

    AWS S3 对接

    345 |
    1.创建对象存储:
    346 |

    点击跳转创建

    347 |

    348 |

    创建的时候注意上述圈出内容即可

    349 |

    350 |

    这是创建完成后的样子,记住桶名称和区域

    351 |
    2.创建密钥:
    352 |

    353 |

    注意请妥善保存密钥

    354 |
    3.最后的填写:
    355 |

    356 |
    357 |
    358 |

    S3兼容——R2对接

    359 |
    1.创建桶:
    360 |

    361 |

    记得开启Cloudflare R2 的公开访问权限

    362 |
    2.获取密钥
    363 |

    R2主页点击,管理R2 api令牌进行创建

    364 |

    365 |

    选择编辑权限,因为需要修改和删除

    366 |

    367 |
    最后填写:
    368 |

    369 |
    370 |
    371 |

    S3兼容——七牛对接

    372 |

    待编写

    373 |
    374 |
    375 |

    画圈手势上传使用方法

    376 |

    377 |
    378 |
    379 |

    全局上传使用方法

    380 |

    381 | 382 |
    383 | 384 |
    385 |
    386 |
    387 |
    388 | 389 | 390 | 391 | 392 | -------------------------------------------------------------------------------- /Chromium/vendor/content_scripts/js/AutoInsertFun.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 编辑器的初始识别和状态 3 | */ 4 | function insertContentIntoEditorState() { 5 | function FullDomPermissionsCSS(file) { 6 | let link = document.createElement('link'); 7 | link.href = chrome.runtime.getURL(file); 8 | link.rel = 'stylesheet'; 9 | (document.head || document.documentElement).appendChild(link); 10 | } 11 | FullDomPermissionsCSS('vendor/content_scripts/css/FullDomPermissions.css'); 12 | function FullDomPermissionsJs(file) { 13 | let script = document.createElement('script'); 14 | script.src = chrome.runtime.getURL(file); 15 | script.onload = function () { 16 | this.remove(); 17 | }; 18 | (document.head || document.documentElement).appendChild(script); 19 | } 20 | FullDomPermissionsJs('vendor/content_scripts/js/FullDomPermissions.js'); 21 | 22 | } 23 | window.addEventListener('message', function (event) { 24 | if (event.data.type === 'insertContentIntoEditorState') { 25 | mainLogic(document.querySelector(".insertContentIntoEditorPrompt")); 26 | chrome.storage.local.get(["FuncDomain"], function (result) { 27 | if (result.FuncDomain.EditPasteUpload == "on") { 28 | handlePasteEventOnFocus() 29 | } 30 | }) 31 | } 32 | }) 33 | chrome.runtime.onMessage.addListener(function (request) { 34 | if (request.AutoInsertFun) { 35 | AutoInsertFun(request.AutoInsertFun,false) 36 | } 37 | }); 38 | 39 | function transformUpUrl(AutoInsert_message_content, ImageProxy) { 40 | let UpUrl = AutoInsert_message_content; 41 | switch (ImageProxy) { 42 | case "1": 43 | let index = parseInt(Math.random() * 3); 44 | UpUrl = `https://i` + index + `.wp.com/` + UpUrl.replace(/^https:\/\//, '') 45 | break; 46 | case "2": 47 | UpUrl = `https://images.weserv.nl/?url=` + UpUrl 48 | break; 49 | case "3": 50 | UpUrl = `https://imageproxy.pimg.tw/resize?url=` + UpUrl 51 | break; 52 | case "4": 53 | UpUrl = `https://pic1.xuehuaimg.com/proxy/` + UpUrl 54 | break; 55 | case "5": 56 | UpUrl = `https://cors.zme.ink/` + UpUrl 57 | break; 58 | } 59 | return UpUrl; 60 | } 61 | 62 | function insertIntoFocusEditor(UpUrl) { 63 | // 将图片插入到当前焦点的编辑器中 64 | //焦点插入 65 | const selection = window.getSelection(); 66 | if (selection.rangeCount > 0) { 67 | const range = selection.getRangeAt(0); 68 | const commonAncestor = range.commonAncestorContainer; 69 | if (commonAncestor.nodeType === Node.ELEMENT_NODE) { 70 | const inputElements = commonAncestor.querySelectorAll('input'); 71 | const textareaElements = commonAncestor.querySelectorAll('textarea'); 72 | const contentEditableElements = commonAncestor.querySelectorAll('[contenteditable="true"]'); 73 | if (inputElements.length > 0) { 74 | // 方法1: 处理input元素 75 | document.execCommand('insertText', false, UpUrl); 76 | 77 | } else if (textareaElements.length > 0) { 78 | // 方法2: 处理textarea元素 79 | document.execCommand('insertText', false, UpUrl); 80 | 81 | } else if (contentEditableElements.length > 0) { 82 | // 方法3: 处理具有contenteditable属性的元素 83 | const imgElement = document.createElement('img'); 84 | imgElement.src = UpUrl; // 替换成你的图片URL 85 | imgElement.alt = '图片'; 86 | contentEditableElements[0].appendChild(imgElement); 87 | 88 | } 89 | } else if (commonAncestor.nodeType === Node.TEXT_NODE && commonAncestor.parentElement && commonAncestor.parentElement.hasAttribute('contenteditable')) { 90 | // commonAncestor.textContent += UpUrl 91 | document.execCommand('insertText', false, UpUrl); 92 | } 93 | } 94 | 95 | } 96 | 97 | function determineEditorType(excludedTypes = []) { 98 | let currentURL = window.location.href; 99 | let webScripts = document.querySelectorAll('script'); 100 | 101 | function isExcluded(type) { 102 | return excludedTypes.includes(type); 103 | } 104 | 105 | if (!isExcluded("discuz") && (document.body.innerText.toLowerCase().includes("discuz") || document.documentElement.innerHTML.toLowerCase().indexOf('discuz') !== -1)) { 106 | return "discuz"; 107 | } 108 | if (!isExcluded("v2ex") && currentURL.includes("v2ex.com")) { 109 | return "v2ex"; 110 | } 111 | if (!isExcluded("nodeseek") && currentURL.includes("nodeseek.com")) { 112 | return "nodeseek"; 113 | } 114 | if (!isExcluded("hostevaluate") && currentURL.includes("hostevaluate.com")) { 115 | return "hostevaluate"; 116 | } 117 | if (!isExcluded("lowendtalk") && currentURL.includes("lowendtalk.com")) { 118 | return "lowendtalk"; 119 | } 120 | if (!isExcluded("typecho") && document.body.innerText.toLowerCase().includes("typecho")) { 121 | return "typecho"; 122 | } 123 | let phpbbForum = document.getElementById("phpbb"); 124 | if (!isExcluded("phpbb") && phpbbForum) { 125 | return "phpbb"; 126 | } 127 | let CodeMirror = document.querySelector(".CodeMirror"); 128 | if (!isExcluded("codeMirror_5") && CodeMirror) { 129 | return "codeMirror_5"; 130 | } 131 | let CodeMirror6 = document.querySelector(".cm-content"); 132 | if (!isExcluded("codeMirror_6") && CodeMirror6) { 133 | return "codeMirror_6"; 134 | } 135 | let Gutenberg = document.getElementById("wpbody-content"); 136 | if (!isExcluded("gutenberg") && Gutenberg) { 137 | return "gutenberg"; 138 | } 139 | 140 | for (let i = 0; i < webScripts.length; i++) { 141 | let src = webScripts[i].getAttribute('src'); 142 | if (src) { 143 | if (!isExcluded("tinymce_5or6") && src.includes('tinymce')) { 144 | return "tinymce_5or6"; 145 | } 146 | if (!isExcluded("wangeditor") && src.includes('wangeditor')) { 147 | return "wangeditor"; 148 | } 149 | if (!isExcluded("ckeditor_4") && src.includes('ckeditor4')) { 150 | return "ckeditor_4"; 151 | } 152 | if (!isExcluded("ckeditor_5") && src.includes('ckeditor5')) { 153 | return "ckeditor_5"; 154 | } 155 | if (!isExcluded("ckeditor_4or5") && src.includes('ckeditor')) { 156 | return "ckeditor_4or5"; 157 | } 158 | if (!isExcluded("halo") && src.includes('halo')) { 159 | return "halo"; 160 | } 161 | if (!isExcluded("ueditor") && src.includes('ueditor')) { 162 | return "ueditor"; 163 | } 164 | } 165 | } 166 | 167 | if (!isExcluded("iframe")) { 168 | let iframe = document.querySelector('iframe'); 169 | if (iframe) { 170 | return "iframe"; 171 | } 172 | } 173 | 174 | return null; // 如果没有匹配的编辑器类型 175 | } 176 | 177 | function insertIntoSpecificEditor(editorType, UpUrl) { 178 | const editorHandlers = { 179 | 'discuz': (UpUrl) => handleDiscuz(UpUrl), 180 | 'v2ex': (UpUrl) => handleV2exReply(UpUrl), 181 | 'nodeseek': (UpUrl) => handleCodeMirror5(UpUrl), 182 | 'hostevaluate': (UpUrl) => handleHostEvaluate(UpUrl), 183 | 'lowendtalk': (UpUrl) => handleLowEndTalk(UpUrl), 184 | 'typecho': (UpUrl) => handleTypecho(UpUrl), 185 | 'phpbb': (UpUrl) => handlePHPBB(UpUrl), 186 | 'codeMirror_5': (UpUrl) => handleCodeMirror5(UpUrl), 187 | 'codeMirror_6': (UpUrl) => handleCodeMirror6(UpUrl), 188 | 'gutenberg': (UpUrl) => handleGutenberg(UpUrl), 189 | 'tinymce_5or6': (UpUrl) => handleTinyMCE_5or6(UpUrl), 190 | 'wangeditor': (UpUrl) => handleWangeditor(UpUrl), 191 | 'ckeditor_4': (UpUrl) => handleCKEditor4(UpUrl), 192 | 'ckeditor_5': (UpUrl) => handleCKEditor5(UpUrl), 193 | 'ckeditor_4or5': (UpUrl) => handleCKEditor(UpUrl), 194 | 'halo': (UpUrl) => handleHalo(UpUrl), 195 | 'ueditor': (UpUrl) => handleUeditor(UpUrl), 196 | 'iframe': (UpUrl) => handleIframe(UpUrl), 197 | 198 | }; 199 | let handler = editorHandlers[editorType]; 200 | if (handler) { 201 | return handler(UpUrl); 202 | } else { 203 | return false; 204 | } 205 | } 206 | 207 | let excludedEditorTypes = []; 208 | function AutoInsertFun(AutoInsert_message_content, FocusInsert) { 209 | chrome.storage.local.get(["FuncDomain"], function (result) { 210 | if (result.FuncDomain.AutoInsert != "on") { return; } 211 | let ImageProxy = result.FuncDomain.ImageProxy || 0 212 | 213 | let UpUrl = transformUpUrl(AutoInsert_message_content, ImageProxy); 214 | 215 | // 表情的聚焦插入 216 | if (FocusInsert) { 217 | insertIntoFocusEditor(UpUrl); 218 | return; 219 | } 220 | 221 | // 然后处理特定编辑器 222 | attemptInsertion(UpUrl); 223 | 224 | }) 225 | } 226 | function getDomainFromURL() { 227 | return window.location.hostname; 228 | } 229 | function getStoredInsertionEditorTypes(callback) { 230 | chrome.storage.local.get(['InsertionEditorType'], function (result) { 231 | callback(result.InsertionEditorType ? result.InsertionEditorType : {}); 232 | }); 233 | } 234 | 235 | // 保存域名和对应的editorType到本地数据库 236 | function saveEditorTypeForDomain(editorType) { 237 | let currentDomain = getDomainFromURL() 238 | getStoredInsertionEditorTypes(function (storedEditorTypes) { 239 | storedEditorTypes[currentDomain] = editorType; 240 | chrome.storage.local.set({ 'InsertionEditorType': storedEditorTypes }); 241 | }); 242 | } 243 | 244 | // 尝试从本地数据库获取当前域名的editorType 245 | function getEditorTypeForCurrentDomain(callback) { 246 | let currentDomain = getDomainFromURL(); 247 | getStoredInsertionEditorTypes(function (storedEditorTypes) { 248 | callback(storedEditorTypes[currentDomain]); 249 | }); 250 | } 251 | 252 | function attemptInsertion(UpUrl) { 253 | getEditorTypeForCurrentDomain(function (savedEditorType) { 254 | if (savedEditorType) { 255 | let success = insertIntoSpecificEditor(savedEditorType, UpUrl); 256 | if (!success) { 257 | if (confirm("发现了错误的插入类型,是否修正?")) { 258 | excludedEditorTypes.push(savedEditorType); 259 | let editorType = determineEditorType(excludedEditorTypes); 260 | if (editorType) { 261 | let success = insertIntoSpecificEditor(editorType, UpUrl); 262 | if (!success) { 263 | excludedEditorTypes.push(editorType); 264 | attemptInsertion(UpUrl); 265 | } else { 266 | saveEditorTypeForDomain(editorType); 267 | } 268 | } 269 | 270 | } 271 | } 272 | return; 273 | } 274 | let editorType = determineEditorType(excludedEditorTypes); 275 | if (editorType) { 276 | let success = insertIntoSpecificEditor(editorType, UpUrl); 277 | if (!success) { 278 | // 如果插入失败,将该编辑器类型添加到排除列表中 279 | excludedEditorTypes.push(editorType); 280 | PLNotification({ 281 | type: "warning", 282 | content: "发现错误插入类型:" + editorType + "
    错误URL:" + window.location.href, 283 | }); 284 | attemptInsertion(UpUrl); 285 | } else { 286 | saveEditorTypeForDomain(editorType); 287 | } 288 | } else { 289 | PLNotification({ 290 | type: "error", 291 | content: "找不到合适的编辑器类型,或者所有类型都失败了" + "
    失效地址:" + window.location.href + "
    如果需要适配请上报该错误!", 292 | }); 293 | } 294 | }) 295 | 296 | 297 | } 298 | function handleDiscuz(UpUrl) { 299 | let Discuz = document.getElementById("fastpostmessage") 300 | let Discuz_Interactive_reply = document.getElementById("postmessage") 301 | let Discuz_Advanced = document.getElementById("e_textarea") 302 | if (Discuz_Interactive_reply) { 303 | //回复楼层 304 | Discuz_Interactive_reply.value += '[img]' + UpUrl + '[/img]' 305 | return true; 306 | } else if (Discuz) { 307 | //回复楼主 308 | Discuz.value += '[img]' + UpUrl + '[/img]' 309 | return true; 310 | } 311 | if (Discuz_Advanced) { 312 | //高级回复 313 | let Discuz_Advanced_iframe 314 | try { 315 | Discuz_Advanced_iframe = Discuz_Advanced.parentNode.querySelector("iframe") 316 | if (Discuz_Advanced_iframe) { 317 | let bodyElement = Discuz_Advanced_iframe.contentDocument.body 318 | let img = document.createElement('img') 319 | img.src = UpUrl 320 | bodyElement.appendChild(img) 321 | return true; 322 | } 323 | else { 324 | Discuz_Advanced.value += '[img]' + UpUrl + '[/img]' 325 | return true; 326 | } 327 | } catch (error) { 328 | } 329 | } 330 | return false; 331 | } 332 | 333 | function handleV2exReply(UpUrl) { 334 | let reply_content_Advanced = document.getElementById("topic_content") 335 | if (reply_content_Advanced && reply_content_Advanced.type != "hidden") { 336 | reply_content_Advanced.value += '![' + "图片" + '](' + UpUrl + ')' 337 | let inputEvent = new Event('input', { bubbles: true }); 338 | reply_content_Advanced.dispatchEvent(inputEvent); 339 | return true; 340 | } 341 | if (document.body.innerText.toLowerCase().includes("请尽量让自己的回复能够对别人有帮助")) { 342 | let reply_content = document.getElementById("reply_content") 343 | if (reply_content) { 344 | reply_content.value += UpUrl 345 | let inputEvent = new Event('input', { bubbles: true }); 346 | reply_content.dispatchEvent(inputEvent); 347 | return true; 348 | } 349 | } 350 | return false; 351 | } 352 | 353 | function handleNodeSeek(UpUrl) { 354 | let nodeseek = document.getElementById("markdown-input") 355 | if (nodeseek) { 356 | nodeseek.value += '![' + "图片" + '](' + UpUrl + ')' 357 | let inputEvent = new Event('input', { bubbles: true }); 358 | nodeseek.dispatchEvent(inputEvent); 359 | return true; 360 | } 361 | return false; 362 | } 363 | 364 | function handleHostEvaluate(UpUrl) { 365 | let hostevaluate = document.getElementsByClassName("write-container") 366 | if (hostevaluate.length) { 367 | let write = hostevaluate[hostevaluate.length - 1].querySelector(".write") 368 | write.value += '![' + "图片" + '](' + UpUrl + ')' 369 | let inputEvent = new Event('input', { bubbles: true }); 370 | write.dispatchEvent(inputEvent); 371 | return true; 372 | } 373 | return false; 374 | } 375 | 376 | function handleLowEndTalk(UpUrl) { 377 | let lowendtalkEditor = document.getElementById("Form_Body") 378 | if (lowendtalkEditor) { 379 | lowendtalkEditor.value += '![' + "图片" + '](' + UpUrl + ')'; 380 | return true; 381 | } 382 | return false; 383 | } 384 | function handleTypecho(UpUrl) { 385 | let text = document.getElementById("text") 386 | if (text) { 387 | text.value += '![' + "图片" + '](' + UpUrl + ')' 388 | let inputEvent = new Event('input', { bubbles: true }); 389 | text.dispatchEvent(inputEvent); 390 | return true; 391 | } 392 | return false; 393 | } 394 | function handlePHPBB(UpUrl) { 395 | let phpbbForum = document.getElementById("phpbb") 396 | if (phpbbForum) { 397 | window.postMessage({ type: 'phpbbForum', data: '[img]' + UpUrl + '[/img]' }, '*'); 398 | return true; 399 | } 400 | return false; 401 | } 402 | function handleCodeMirror5(UpUrl) { 403 | let CodeMirror = document.querySelector(".CodeMirror"); 404 | if (CodeMirror) { 405 | window.postMessage({ type: 'CodeMirror5', data: '![' + "描述" + '](' + UpUrl + ')' }, '*'); 406 | return true; 407 | } 408 | return false; 409 | } 410 | function handleCodeMirror6(UpUrl) { 411 | let CodeMirror6 = document.querySelector(".cm-content"); 412 | if (CodeMirror6) { 413 | let item = document.createElement('div'); 414 | item.className = "cm-line" 415 | item.dir = "auto" 416 | item.innerText = '![' + "描述" + '](' + UpUrl + ')' 417 | CodeMirror6.appendChild(item) 418 | return true; 419 | } 420 | return false; 421 | } 422 | function handleGutenberg(UpUrl) { 423 | if (window.location.href.toLowerCase().includes("post-new.php")) { 424 | window.postMessage({ type: 'Gutenberg', data: UpUrl }, '*'); 425 | return true; 426 | } 427 | return false; 428 | } 429 | function handleTinyMCE_5or6(UpUrl) { 430 | window.postMessage({ type: 'TinyMCE', data: `` }, '*'); 431 | return true; 432 | } 433 | function handleWangeditor(UpUrl) { 434 | window.postMessage({ type: 'wangeditor', data: `` }, '*'); 435 | return true; 436 | } 437 | function handleCKEditor4(UpUrl) { 438 | window.postMessage({ type: 'ckeditor4', data: `` }, '*'); 439 | return true; 440 | } 441 | function handleCKEditor5(UpUrl) { 442 | window.postMessage({ type: 'ckeditor5', data: `` }, '*'); 443 | return true; 444 | } 445 | function handleCKEditor(UpUrl) { 446 | window.postMessage({ type: 'ckeditor', data: `` }, '*'); 447 | return true; 448 | } 449 | function handleHalo(UpUrl) { 450 | let HaloEditor_Element = document.querySelector('.ProseMirror'); 451 | if (HaloEditor_Element) { 452 | HaloEditor_Element.focus(); 453 | document.execCommand('insertImage', false, UpUrl); 454 | return true; 455 | } 456 | return false; 457 | } 458 | function handleUeditor(UpUrl) { 459 | window.postMessage({ type: 'ueditor', data: UpUrl }, '*'); 460 | return true; 461 | } 462 | function handleIframe(UpUrl) { 463 | let iframe = document.querySelector('iframe'); 464 | if (iframe) { 465 | let iframeStyles = window.getComputedStyle(iframe); 466 | if (iframeStyles.display === 'none') { 467 | let textarea = document.querySelector('textarea') 468 | let textareaStyles = window.getComputedStyle(textarea); 469 | if (textareaStyles.display != 'none') { 470 | textarea.value += '[img]' + UpUrl + '[/img]'; 471 | return true; 472 | } 473 | } 474 | 475 | let iframeDocument = iframe.contentDocument || iframe.contentWindow.document; 476 | let editableElement = iframeDocument.querySelector('[contenteditable="true"]'); 477 | if (editableElement) { 478 | // 创建图片元素并设置属性 479 | let imgElement = document.createElement('img'); 480 | imgElement.src = UpUrl; 481 | imgElement.alt = '图片'; 482 | // 插入图片元素 483 | editableElement.appendChild(imgElement); 484 | return true; 485 | } 486 | return false; 487 | } 488 | return false; 489 | } 490 | 491 | 492 | 493 | //编辑框粘贴 494 | function handlePasteEventOnFocus() { 495 | function pasteHandler(e) { 496 | const focusedElement = document.activeElement; 497 | if (!focusedElement) { 498 | return; 499 | } 500 | // 检查focusedElement是否不是可输入的元素 501 | if ( 502 | !(focusedElement instanceof HTMLInputElement) && 503 | !(focusedElement instanceof HTMLTextAreaElement) && 504 | !focusedElement.isContentEditable 505 | ) { 506 | console.log("Input", focusedElement instanceof HTMLInputElement); 507 | console.log("TextArea", focusedElement instanceof HTMLTextAreaElement); 508 | console.log("contentEditable", focusedElement.isContentEditable); 509 | return; 510 | } 511 | 512 | const copyFileItems = e.clipboardData.items; 513 | const filesToSend = []; 514 | 515 | for (let i = 0; i < copyFileItems.length; i++) { 516 | const copyFileItem = copyFileItems[i]; 517 | if (copyFileItem.kind == "file") { 518 | if (copyFileItem.type.indexOf("image") != -1) { 519 | const file = copyFileItem.getAsFile(); 520 | filesToSend.push(file); 521 | } 522 | } 523 | } 524 | if (filesToSend.length > 0) { 525 | content_scripts_CheckUploadModel(filesToSend, false, true) 526 | } 527 | } 528 | document.addEventListener("paste", pasteHandler); 529 | } 530 | --------------------------------------------------------------------------------