ChatGPT Shortcut Anywhere

ChatGPT Shortcut 扩展的增强版,任意网站都能打开 AiShort 侧边栏

  1. // ==UserScript==
  2. // @name ChatGPT Shortcut Anywhere
  3. // @name:zh-CN ChatGPT Shortcut Anywhere
  4. // @name:ja どこでもChatGPTショートカット
  5. // @name:pt Atalho ChatGPT Em Qualquer Lugar
  6. // @namespace https://www.aishort.top/
  7. // @version 1.0.0
  8. // @description Toggle AiShort sidebar on the page
  9. // @author BensonLi
  10. // @description:zh-CN ChatGPT Shortcut 扩展的增强版,任意网站都能打开 AiShort 侧边栏
  11. // @description:ja ChatGPT Shortcut 拡張の強化版、任意のウェブサイトで AiShort サイドバーを開くことができます
  12. // @description:pt Versão aprimorada da extensão ChatGPT Shortcut, abre a barra lateral AiShort em qualquer site
  13. // @match https://chatgpt.com/*
  14. // @match https://chat.deepseek.com/*
  15. // @match https://gemini.google.com/*
  16. // @match https://claude.ai/*
  17. // @match https://yiyan.baidu.com/*
  18. // @match https://*.siliconflow.cn/*
  19. // @match https://tongyi.aliyun.com/*
  20. // @match https://kimi.moonshot.cn/*
  21. // @match https://www.doubao.com/*
  22. // @match https://chatglm.cn/*
  23. // @match https://xinghuo.xfyun.cn/*
  24. // @match https://ying.baichuan-ai.com/*
  25. // @match https://yuanbao.tencent.com/*
  26. // @match https://groq.com/*
  27. // @match https://*.groq.com/*
  28. // @match https://openrouter.ai/*
  29. // @match https://metaso.cn/*
  30. // @match https://302.ai/*
  31. // @match https://chat.scnet.cn/*
  32. // @match https://www.perplexity.ai/*
  33. // @match https://grok.com/*
  34. // @match https://character.ai/*
  35. // @match https://pi.ai/*
  36. // @match https://janitorai.com/*
  37. // @match https://www.tiangong.cn/*
  38. // @exclude *://www.aishort.top/*
  39. // @icon https://www.aishort.top/img/logo.svg
  40. // @grant none
  41. // @license MIT
  42. // ==/UserScript==
  43.  
  44. // You can directly set your preferred language by editing this variable.
  45. // For example, replace 'null' with 'zh' for Chinese, 'en' for English, 'ja' for Japanese, etc.
  46. // Supported language codes include: 'en', 'zh', 'ja', 'ko', 'es', 'fr', 'de', 'it', 'ru', 'pt', 'hi', 'ar', and 'bn'.
  47. // If set to 'null', the script will automatically use the browser's default language.
  48. const userSelectedLanguage = null; // Example: const userSelectedLanguage = 'zh';
  49. // Array of available languages
  50. const AVAILABLE_LANGUAGES = ['en', 'zh', 'ja', 'ko', 'es', 'fr', 'de', 'it', 'ru', 'pt', 'hi', 'ar', 'bn'];
  51.  
  52. const hostsRequiringPopup = ['chatgpt.com', 'claude.ai', 'gemini.google.com', 'groq.com', 'openrouter.ai','tongyi.aliyun.com'];
  53. const hostname = window.location.hostname;
  54.  
  55. // Function to get the user-selected language or the browser's default language
  56. function getLanguage() {
  57. if (AVAILABLE_LANGUAGES.includes(userSelectedLanguage)) {
  58. return userSelectedLanguage;
  59. }
  60. const browserLanguage = navigator.language.split('-')[0];
  61. return AVAILABLE_LANGUAGES.includes(browserLanguage) ? browserLanguage : 'en';
  62. }
  63.  
  64. // 获取iframe URL
  65. function getIframeUrl() {
  66. const userLanguage = getLanguage();
  67. return userLanguage === 'zh' ? 'https://www.aishort.top/' : `https://www.aishort.top/${userLanguage}/`;
  68. }
  69. function createToggleIcon() {
  70. const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  71. svg.setAttribute('viewBox', '0 0 1024 1024');
  72. svg.setAttribute('width', '35');
  73. svg.setAttribute('height', '35');
  74.  
  75. const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  76. path1.setAttribute('d', 'M85.333333 490.666667A64 64 0 0 0 149.333333 554.666667h725.333334a64 64 0 0 0 0-128h-725.333334A64 64 0 0 0 85.333333 490.666667z');
  77. path1.setAttribute('fill', '#5cac7c');
  78.  
  79. const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  80. path2.setAttribute('d', 'M405.333333 853.333333a64 64 0 0 1 0-128h469.333334a64 64 0 0 1 0 128h-469.333334z m256-597.333333a64 64 0 0 1 0-128h213.333334a64 64 0 0 1 0 128h-213.333334z');
  81. path2.setAttribute('fill', '#5cac7c');
  82. path2.setAttribute('opacity', '0.5');
  83.  
  84. svg.appendChild(path1);
  85. svg.appendChild(path2);
  86.  
  87. svg.style.position = 'fixed';
  88. svg.style.bottom = '300px';
  89. svg.style.right = '15px';
  90. svg.style.zIndex = '1000';
  91. svg.style.cursor = 'pointer';
  92.  
  93. return svg;
  94. }
  95. // 创建侧边栏按钮及逻辑
  96. function createSidebar() {
  97. const iframeUrl = getIframeUrl();
  98. const toggleIcon = createToggleIcon();
  99. document.body.appendChild(toggleIcon);
  100.  
  101. if (hostsRequiringPopup.includes(hostname)) {
  102. let popupWindow = null;
  103. toggleIcon.addEventListener('click', function() {
  104. if (popupWindow && !popupWindow.closed) {
  105. popupWindow.close();
  106. popupWindow = null;
  107. } else {
  108. // 如果窗口未打开或已关闭,打开新窗口
  109. popupWindow = window.open(iframeUrl, '_blank', 'width=500,height=700');
  110. }
  111. });
  112. } else {
  113. const iframe = document.createElement('iframe');
  114. iframe.id = 'ai-shortcut-sidebar';
  115. iframe.style.cssText = `
  116. width: 400px;
  117. height: 100%;
  118. position: fixed;
  119. right: -400px;
  120. top: 0;
  121. z-index: 999;
  122. border: none;
  123. transition: right 0.3s ease;
  124. box-shadow: -2px 0 5px rgba(0,0,0,0.2);
  125. background: white;
  126. `;
  127. iframe.src = iframeUrl;
  128. iframe.allow = "clipboard-write";
  129. iframe.sandbox = 'allow-same-origin allow-scripts allow-popups allow-forms allow-downloads';
  130. document.body.appendChild(iframe);
  131. toggleIcon.addEventListener('click', function() {
  132. // 切换iframe显示
  133. iframe.style.right = (iframe.style.right === '0px') ? '-400px' : '0px';
  134. });
  135. }
  136. }
  137.  
  138. // 检查是否已经存在相同的iframe(包括扩展的)
  139. function checkForExistingIframe() {
  140. setTimeout(() => {
  141. const iframes = Array.from(document.getElementsByTagName('iframe'));
  142. const existingIframe = iframes.some(iframe => {
  143. try {
  144. const iframeSrc = new URL(iframe.src);
  145. return iframeSrc.hostname === 'www.aishort.top' ||
  146. iframe.id === 'unique-iframe-id' ||
  147. iframe.id === 'ai-shortcut-sidebar';
  148. } catch (e) {
  149. return false;
  150. }
  151. });
  152.  
  153. if (!existingIframe) {
  154. createSidebar();
  155. }
  156. }, 500);
  157. }
  158.  
  159. (function() {
  160. 'use strict';
  161. window.onload = () => checkForExistingIframe();
  162. })();