@kudoai/chatgpt.js 3.3.5 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +28 -21
  2. package/chatgpt.js +129 -78
  3. package/dist/chatgpt.min.js +3 -3
  4. package/docs/README.md +28 -21
  5. package/docs/USERGUIDE.md +3 -3
  6. package/package.json +18 -11
  7. package/starters/chrome/docs/README.md +10 -8
  8. package/starters/chrome/extension/components/icons.js +32 -0
  9. package/starters/chrome/extension/components/modals.js +121 -0
  10. package/starters/chrome/extension/content.js +121 -47
  11. package/starters/chrome/extension/icons/faded/icon128.png +0 -0
  12. package/starters/chrome/extension/icons/faded/icon16.png +0 -0
  13. package/starters/chrome/extension/icons/faded/icon32.png +0 -0
  14. package/starters/chrome/extension/icons/faded/icon64.png +0 -0
  15. package/starters/chrome/extension/lib/chatgpt.js +129 -78
  16. package/starters/chrome/extension/lib/dom.js +28 -0
  17. package/starters/chrome/extension/lib/settings.js +30 -0
  18. package/starters/chrome/extension/manifest.json +25 -22
  19. package/starters/chrome/extension/popup/controller.js +138 -0
  20. package/starters/chrome/extension/popup/index.html +7 -44
  21. package/starters/chrome/extension/popup/style.css +15 -6
  22. package/starters/chrome/extension/service-worker.js +38 -0
  23. package/starters/greasemonkey/chatgpt.js-greasemonkey-starter.user.js +12 -12
  24. package/starters/greasemonkey/docs/README.md +2 -0
  25. package/starters/chrome/extension/background.js +0 -14
  26. package/starters/chrome/extension/lib/settings-utils.js +0 -24
  27. package/starters/chrome/extension/popup/popup.js +0 -92
  28. package/starters/chrome/media/images/icons/refresh/icon16.png +0 -0
  29. package/starters/chrome/media/images/icons/refresh/icon50.png +0 -0
  30. /package/starters/chrome/{media/images → images}/icons/question-mark/icon16.png +0 -0
  31. /package/starters/chrome/{media/images → images}/icons/question-mark/icon512.png +0 -0
  32. /package/starters/chrome/{media/images → images}/screenshots/chatgpt-extension-in-list.png +0 -0
  33. /package/starters/chrome/{media/images → images}/screenshots/developer-mode-toggle.png +0 -0
  34. /package/starters/chrome/{media/images → images}/screenshots/developer-mode-toggle.psd +0 -0
  35. /package/starters/chrome/{media/images → images}/screenshots/extension-loaded.png +0 -0
  36. /package/starters/chrome/{media/images → images}/screenshots/load-unpacked-button.png +0 -0
  37. /package/starters/chrome/{media/images → images}/screenshots/reload-extension-button.png +0 -0
  38. /package/starters/chrome/{media/images → images}/screenshots/reload-page-button.png +0 -0
  39. /package/starters/chrome/{media/images → images}/screenshots/select-extension-folder.png +0 -0
@@ -0,0 +1,138 @@
1
+ (async () => {
2
+
3
+ // Import JS resources
4
+ for (const resource of ['components/icons.js', 'lib/dom.js', 'lib/settings.js'])
5
+ await import(chrome.runtime.getURL(resource))
6
+
7
+ // Init ENV context
8
+ const env = { site: /([^.]+)\.[^.]+$/.exec(new URL((await chrome.tabs.query(
9
+ { active: true, currentWindow: true }))[0].url).hostname)?.[1] }
10
+
11
+ // Import APP data
12
+ const { app } = await chrome.storage.sync.get('app')
13
+ icons.dependencies.import({ app }) // for src's using app.urls.assetHost
14
+
15
+ // Define FUNCTIONS
16
+
17
+ async function sendMsgToActiveTab(action, options) {
18
+ const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true })
19
+ return await chrome.tabs.sendMessage(activeTab.id, { action: action, options: { ...options }})
20
+ }
21
+
22
+ function notify(msg, pos = 'bottom-right') { sendMsgToActiveTab('notify', { msg, pos }) }
23
+
24
+ const sync = {
25
+ fade() {
26
+
27
+ // Update toolbar icon
28
+ const iconDimensions = [16, 32, 64, 128], iconPaths = {}
29
+ iconDimensions.forEach(dimension => iconPaths[dimension] = `../icons/${
30
+ config.extensionDisabled ? 'faded/' : '' }icon${dimension}.png` )
31
+ chrome.action.setIcon({ path: iconPaths })
32
+
33
+ // Update menu contents
34
+ document.querySelectorAll('div.logo, div.menu-title, div.menu')
35
+ .forEach(elem => {
36
+ elem.classList.remove(masterToggle.checked ? 'disabled' : 'enabled')
37
+ elem.classList.add(masterToggle.checked ? 'enabled' : 'disabled')
38
+ })
39
+ },
40
+
41
+ configToUI(options) { return sendMsgToActiveTab('syncConfigToUI', options) }
42
+ }
43
+
44
+ // Run MAIN routine
45
+
46
+ // Init MASTER TOGGLE
47
+ const masterToggle = document.querySelector('input')
48
+ await settings.load('extensionDisabled')
49
+ masterToggle.checked = !config.extensionDisabled ; sync.fade()
50
+ masterToggle.onchange = () => {
51
+ settings.save('extensionDisabled', !config.extensionDisabled)
52
+ Object.keys(sync).forEach(key => sync[key]()) // sync fade + storage to UI
53
+ notify(`${chrome.runtime.getManifest().name} ${ this.checked ? 'ON' : 'OFF' }`)
54
+ }
55
+
56
+ // Create CHILD menu entries on chatgpt.com
57
+ if (env.site == 'chatgpt') {
58
+ await settings.load(settings.availKeys)
59
+
60
+ // Create/insert child section
61
+ const togglesDiv = dom.create.elem('div', { class: 'menu' })
62
+ document.querySelector('.menu-header').insertAdjacentElement('afterend', togglesDiv)
63
+
64
+ // Create/insert child entries
65
+ Object.keys(settings.controls).forEach(key => {
66
+
67
+ // Init elems
68
+ const menuItemDiv = dom.create.elem('div', { class: 'menu-item menu-area' }),
69
+ menuLabel = dom.create.elem('label', { class: 'menu-icon' }),
70
+ menuLabelSpan = document.createElement('span')
71
+ let menuInput, menuSlider
72
+ menuLabelSpan.textContent = settings.controls[key].label
73
+ if (settings.controls[key].type == 'toggle') {
74
+ menuInput = dom.create.elem('input', { type: 'checkbox' })
75
+ menuInput.checked = /disabled|hidden/i.test(key) ^ config[key]
76
+ menuSlider = dom.create.elem('span', { class: 'slider' })
77
+ menuLabel.append(menuInput, menuSlider)
78
+ menuLabel.classList.add('toggle-switch')
79
+ } else if (settings.controls[key].type == 'prompt') {
80
+ menuLabel.innerText = settings.controls[key].symbol
81
+ menuLabel.classList.add('menu-prompt')
82
+ }
83
+
84
+ // Assemble/append elems
85
+ menuItemDiv.append(menuLabel, menuLabelSpan)
86
+ togglesDiv.append(menuItemDiv)
87
+
88
+ // Add listeners
89
+ if (settings.controls[key].type == 'toggle') {
90
+ menuItemDiv.onclick = () => menuInput.click()
91
+ menuInput.onclick = menuSlider.onclick = event => // prevent double toggle
92
+ event.stopImmediatePropagation()
93
+ menuInput.onchange = () => {
94
+ settings.save(key, !config[key]) ; sync.configToUI({ updatedKey: key })
95
+ notify(`${settings.controls[key].label} ${ /disabled|hidden/i.test(key) != config[key] ? 'ON' : 'OFF' }`)
96
+ }
97
+ } else if (settings.controls[key].type == 'prompt') {
98
+ // custom logic for each prompt based on key name
99
+ }
100
+ })
101
+
102
+ sync.fade() // in case master toggle off
103
+ }
104
+
105
+ // Create/append FOOTER container
106
+ const footer = document.createElement('footer')
107
+ document.body.append(footer)
108
+
109
+ // Create/append CHATGPT.JS footer logo
110
+ const cjsDiv = dom.create.elem('div', { class: 'chatgpt-js' })
111
+ const cjsLogo = dom.create.elem('img', {
112
+ title: 'Powered by chatgpt.js',
113
+ src: `${app.urls.cjsMediaHost}/images/badges/powered-by-chatgpt.js-faded.png?a439ab6` })
114
+ cjsLogo.onmouseover = cjsLogo.onmouseout = event => cjsLogo.src = `${
115
+ app.urls.cjsMediaHost}/images/badges/powered-by-chatgpt.js${ event.type == 'mouseover' ? '' : '-faded' }.png?a439ab6`
116
+ cjsLogo.onclick = () => chrome.tabs.create({ url: app.urls.chatgptJS })
117
+ cjsDiv.append(cjsLogo) ; footer.append(cjsDiv)
118
+
119
+ // Create/append ABOUT footer button
120
+ const aboutSpan = dom.create.elem('span', {
121
+ title: 'About ChatGPT Extension',
122
+ class: 'menu-icon menu-area', style: 'right:30px ; padding-top: 2px' })
123
+ const aboutIcon = icons.create({ name: 'questionMark', width: 15, height: 13, style: 'margin-bottom: 0.04rem' })
124
+ aboutSpan.onclick = () => { chrome.runtime.sendMessage({ action: 'showAbout' }) ; close() }
125
+ aboutSpan.append(aboutIcon) ; footer.append(aboutSpan)
126
+
127
+ // Create/append RELATED EXTENSIONS footer button
128
+ const moreExtensionsSpan = dom.create.elem('span', {
129
+ title: 'More AI Extensions',
130
+ class: 'menu-icon menu-area', style: 'right:2px ; padding-top: 2px' })
131
+ const moreExtensionsIcon = icons.create({ name: 'plus', size: 16 })
132
+ moreExtensionsSpan.onclick = () => { chrome.tabs.create({ url: app.urls.relatedExtensions }) ; close() }
133
+ moreExtensionsSpan.append(moreExtensionsIcon) ; footer.append(moreExtensionsSpan)
134
+
135
+ // Hide loading spinner
136
+ document.querySelectorAll('[class^="loading"]').forEach(elem => elem.style.display = 'none')
137
+
138
+ })()
@@ -1,9 +1,13 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
- <link href="/popup/style.css" rel="stylesheet">
4
+ <link href="style.css" rel="stylesheet">
5
+ <meta charset="UTF-8">
5
6
  </head>
6
7
  <body>
8
+ <div class="loading-bg">
9
+ <span class="loading-spinner"></span>
10
+ </div>
7
11
  <div class="menu-header">
8
12
  <div class="logo">
9
13
  <img width=26 src="https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@f0cdfc9/starters/chrome/extension/icons/icon32.png">
@@ -16,47 +20,6 @@
16
20
  </label>
17
21
  </div>
18
22
  </div>
19
- <!-- Sub-menu items
20
- <div class="menu">
21
- <div class="menu-item menu-area">
22
- <label class="toggle-switch menu-icon">
23
- <input type="checkbox">
24
- <span class="slider"></span>
25
- </label>
26
- <span >Toggle Label 1</span>
27
- </div>
28
- <div class="menu-item menu-area">
29
- <label class="toggle-switch menu-icon">
30
- <input type="checkbox">
31
- <span class="slider"></span>
32
- </label>
33
- <span >Toggle Label 2</span>
34
- </div>
35
- <div class="menu-item menu-area">
36
- <label class="toggle-switch menu-icon">
37
- <input type="checkbox">
38
- <span class="slider"></span>
39
- </label>
40
- <span >Toggle Label 3</span>
41
- </div>
42
- </div>
43
- -->
44
- <footer>
45
- <div class="chatgpt-js"><a title="Powered by chatgpt.js" href="https://chatgpt.js.org" target="_blank" rel="noopener"><img src="https://media.chatgptjs.org/images/badges/powered-by-chatgpt.js-faded.png?main"></a></div>
46
- <span title="Check for Updates" class="menu-icon menu-area" style="right:58px ; padding-top: 7px" >
47
- <img width=15 height=15 src="https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@258bec1/starters/chrome/media/images/icons/refresh/icon16.png" style="margin-top: 0.04rem">
48
- </span>
49
- <span title="Support" class="menu-icon menu-area" style="right:30px ; padding-top: 9px " >
50
- <a title="Support" href="https://github.com/KudoAI/chatgpt.js-chrome-starter/issues" target="_blank" rel="noopener">
51
- <img width=15 height=13 src="https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@258bec1/starters/chrome/media/images/icons/question-mark/icon16.png" style="margin-bottom: 0.04rem">
52
- </a>
53
- </span>
54
- <span title="More ChatGPT add-ons" class="menu-icon menu-area" style="right:2px ; padding-top: 7px " >
55
- <a title="More ChatGPT add-ons" href="https://github.com/adamlui/chatgpt-userscripts" target="_blank" rel="noopener">
56
- <svg width=16 height=16 viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M899.901 600.38H600.728v299.173c0 74.383-179.503 74.383-179.503 0V600.38H122.051c-74.384 0-74.384-179.503 0-179.503h299.173V121.703c0-74.384 179.503-74.384 179.503 0v299.174H899.9c74.385 0 74.385 179.503.001 179.503z"/></svg>
57
- </a>
58
- </span>
59
- </footer>
60
- <script src="popup.js"></script>
23
+ <script src="controller.js"></script>
61
24
  </body>
62
25
  </html>
@@ -1,6 +1,6 @@
1
1
  /* General size */
2
- html { height: fit-content }
3
- body { width: max-content ; height: 85px !important ; margin: 0 }
2
+ html { height: fit-content ; min-height: 50px }
3
+ body { width: max-content ; margin: 0 ; overflow: clip }
4
4
 
5
5
  /* General font */
6
6
  body, button, input, select, textarea {
@@ -10,11 +10,20 @@ body, button, input, select, textarea {
10
10
  a { color: #999 ; text-decoration: none }
11
11
  a:focus, a:hover { text-decoration: underline ; color: inherit }
12
12
 
13
+ /* Loading elems */
14
+ .loading-bg { background-color: white ; width: 100% ; height: 100% ; position: absolute ; z-index: 1111; }
15
+ .loading-spinner {
16
+ border: 8px solid #f3f3f3 ; border-top: 8px solid #3498db ; border-radius: 50% ;
17
+ width: 15vh ; height: 15vh ; animation: spin 1s linear infinite ;
18
+ position: absolute ; top: calc(50% - 7.5vh - 8px) ; left: calc(50% - 7.5vh)
19
+ }
20
+ @keyframes spin { 0% { transform: rotate(0deg) } 100% { transform: rotate(360deg) }}
21
+
13
22
  /* Header */
14
23
  .menu-header {
15
24
  border-bottom: solid 1px lightgrey ; padding: 5px 5px 5px 0; margin: 0 ;
16
25
  display: flex; background: white ; align-items: center }
17
- .logo { margin: 4px 10px 4px 12px }
26
+ .logo { margin: 4px 8px 4px 12px ; position: relative ; top: 3px }
18
27
  .menu-title { font-size: 0.85rem ; font-weight: 600 ; padding-right: 3px }
19
28
  .menu-icons > .toggle-switch { transform: scale(1.1) } /* make master toggle bigger */
20
29
  .main-toggle { margin-left: auto ; display: flex }
@@ -46,9 +55,9 @@ a:focus, a:hover { text-decoration: underline ; color: inherit }
46
55
  .toggle-switch input[type="checkbox"]:checked + .slider::before { transform: translateX(9px) } /* move knob right when toggled */
47
56
 
48
57
  /* Footer */
49
- footer { font-size: 12px ; text-align: center ; color: #999 ; background: #f5f5f5 ; height: 40px ; padding-top: 3px }
50
- footer > .menu-icon { position: absolute ; bottom: 4px ; opacity: 0.7 }
51
- .chatgpt-js { position: absolute ; bottom: 0.65rem ; left: 0.7rem }
58
+ footer { font-size: 12px ; text-align: center ; color: #999 ; background: #f5f5f5 ; height: 40px ; line-height: 40px }
59
+ footer > .menu-icon { position: absolute ; bottom: -10px ; opacity: 0.7 }
60
+ .chatgpt-js { position: absolute ; bottom: -.25rem ; left: 0.7rem ; cursor: pointer }
52
61
 
53
62
  /* Master toggle effects */
54
63
  .disabled { opacity: 0.3 ; pointer-events: none }
@@ -0,0 +1,38 @@
1
+ // Init APP data
2
+ const app = {
3
+ symbol: '🤖', version: chrome.runtime.getManifest().version,
4
+ urls: {
5
+ assetHost: 'https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js-chrome-starter',
6
+ cjsMediaHost: 'https://media.chatgptjs.org',
7
+ gitHub: 'https://github.com/KudoAI/chatgpt.js-chrome-starter',
8
+ relatedExtensions: 'https://aiwebextensions.com',
9
+ support: 'https://github.com/KudoAI/chatgpt.js-chrome-starter/issues'
10
+ }
11
+ }
12
+ chrome.storage.sync.set({ app }) // save to Chrome storage
13
+
14
+ // Launch ChatGPT on install
15
+ chrome.runtime.onInstalled.addListener(details => {
16
+ if (details.reason == 'install')
17
+ chrome.tabs.create({ url: 'https://chatgpt.com/' })
18
+ })
19
+
20
+ // Sync settings to activated tabs
21
+ chrome.tabs.onActivated.addListener(activeInfo =>
22
+ chrome.tabs.sendMessage(activeInfo.tabId, { action: 'syncConfigToUI' }))
23
+
24
+ // Show ABOUT modal on ChatGPT when toolbar button clicked
25
+ chrome.runtime.onMessage.addListener(async req => {
26
+ if (req.action == 'showAbout') {
27
+ const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true })
28
+ const chatgptTab = new URL(activeTab.url).hostname == 'chatgpt.com' ? activeTab
29
+ : await chrome.tabs.create({ url: 'https://chatgpt.com/' })
30
+ if (activeTab != chatgptTab) await new Promise(resolve => // after new tab loads
31
+ chrome.tabs.onUpdated.addListener(async function statusListener(tabId, info) {
32
+ if (tabId == chatgptTab.id && info.status == 'complete') {
33
+ chrome.tabs.onUpdated.removeListener(statusListener)
34
+ setTimeout(resolve, 2500)
35
+ }}))
36
+ chrome.tabs.sendMessage(chatgptTab.id, { action: 'showAbout' })
37
+ }
38
+ })
@@ -3,13 +3,13 @@
3
3
  // @description A Greasemonkey template to start using chatgpt.js like a boss
4
4
  // @author chatgpt.js
5
5
  // @namespace https://chatgpt.js.org
6
- // @version 2024.10.11
6
+ // @version 2024.12.20
7
7
  // @license MIT
8
+ // @icon https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@3.4.0/starters/greasemonkey/media/images/icons/robot/icon48.png
9
+ // @icon64 https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@3.4.0/starters/greasemonkey/media/images/icons/robot/icon64.png
8
10
  // @match *://chatgpt.com/*
9
11
  // @match *://chat.openai.com/*
10
- // @icon https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@3.3.5/starters/greasemonkey/media/images/icons/robot/icon48.png
11
- // @icon64 https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@3.3.5/starters/greasemonkey/media/images/icons/robot/icon64.png
12
- // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.3.5/dist/chatgpt.min.js
12
+ // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.4.0/dist/chatgpt.min.js
13
13
  // @grant GM_getValue
14
14
  // @grant GM_setValue
15
15
  // @noframes
@@ -22,22 +22,22 @@
22
22
  (async () => {
23
23
 
24
24
  // Init config
25
- const config = { prefix: 'chatgptScript' }; loadSetting('skipAlert');
25
+ const config = { prefix: 'chatgptScript' } ; loadSetting('skipAlert')
26
26
 
27
27
  // Print chatgpt.js methods
28
- await chatgpt.isLoaded(); chatgpt.printAllFunctions(); // to console
28
+ await chatgpt.isLoaded() ; chatgpt.printAllFunctions() // to console
29
29
 
30
30
  // Show alert
31
- if (!config.skipAlert) {
31
+ if (!config.skipAlert)
32
32
  chatgpt.alert('≫ ChatGPT script loaded! 🚀', // title
33
33
  'Success! Press Ctrl+Shift+' // msg
34
34
  + ( navigator.userAgent.indexOf('Firefox') > -1 ? 'K' : 'J' )
35
35
  + ' to view all chatgpt.js functions.',
36
36
  function getHelp() { // button
37
- window.open('https://github.kudoai.com/chatgpt.js-greasemonkey-starter/issues', '_blank', 'noopener'); },
37
+ window.open('https://github.kudoai.com/chatgpt.js-greasemonkey-starter/issues', '_blank', 'noopener') },
38
38
  function dontShowAgain() { // checkbox
39
- saveSetting('skipAlert', !config.skipAlert); });
40
- }
39
+ saveSetting('skipAlert', !config.skipAlert) }
40
+ )
41
41
 
42
42
  // Your code here...
43
43
  // Your code here...
@@ -47,7 +47,7 @@
47
47
  // Your code here...
48
48
 
49
49
  // Define HELPER functions
50
- function loadSetting(...keys) { keys.forEach(key => { config[key] = GM_getValue(config.prefix + '_' + key, false); });}
51
- function saveSetting(key, value) { GM_setValue(config.prefix + '_' + key, value); config[key] = value; }
50
+ function loadSetting(...keys) { keys.forEach(key => config[key] = GM_getValue(config.prefix + '_' + key, false)) }
51
+ function saveSetting(key, value) { GM_setValue(config.prefix + '_' + key, value) ; config[key] = value }
52
52
 
53
53
  })();
@@ -5,3 +5,5 @@
5
5
  <br>
6
6
 
7
7
  <img src="../media/images/screenshots/chatgpt-userscript-on.png">
8
+
9
+ _For advanced Greasemonkey API methods, see: https://wiki.greasespot.net/Greasemonkey_Manual:API_
@@ -1,14 +0,0 @@
1
- const allowedHosts = ['chatgpt.com', 'chat.openai.com'];
2
-
3
- // Add install/update actions
4
- chrome.runtime.onInstalled.addListener((details) => {
5
- chrome.storage.local.set({ 'chatgptJS_extensionDisabled': false }); // auto-enable
6
- if (details.reason == 'install') chrome.tabs.create({ url: 'https://chatgpt.com/' }); // open ChatGPT
7
- });
8
-
9
- // Sync extension state/settings when ChatGPT tab active
10
- chrome.tabs.onActivated.addListener((activeInfo) => {
11
- chrome.tabs.get(activeInfo.tabId, (tab) => {
12
- if (allowedHosts.includes(new URL(tab.url).hostname)) {
13
- chrome.tabs.sendMessage(tab.id, { action: 'syncExtension' });
14
- }});});
@@ -1,24 +0,0 @@
1
- const config = {
2
- prefix: 'chatgptJS', appSymbol: '🤖', appName: 'ChatGPT Extension',
3
- ghRepoURL: 'https://github.kudoai.com/chatgpt.js-chrome-starter' };
4
-
5
- const settings = {
6
-
7
- load: function() {
8
- const keys = ( // original array if array, else new array from multiple args
9
- Array.isArray(arguments[0]) ? arguments[0] : Array.from(arguments));
10
- return Promise.all(keys.map((key) => { // resolve promise when all keys load
11
- return new Promise((resolve) => { // resolve promise when single key value loads
12
- chrome.storage.local.get(config.prefix + '_' + key, (result) => { // load from Chrome
13
- config[key] = result[config.prefix + '_' + key] || false; resolve();
14
- });});}));},
15
-
16
- save: function(key, value) {
17
- const obj = {} ; obj[config.prefix + '_' + key] = value;
18
- chrome.storage.local.set(obj); // save to Chrome
19
- config[key] = value; // save to memory
20
- }
21
-
22
- };
23
-
24
- export { config, settings };
@@ -1,92 +0,0 @@
1
- (async () => {
2
-
3
- // Import settings-utils.js
4
- const { config, settings } = await import(chrome.runtime.getURL('lib/settings-utils.js'));
5
-
6
- // Initialize popup toggles
7
- settings.load('extensionDisabled')
8
- .then(function() { // restore extension/toggle states
9
- masterToggle.checked = !config.extensionDisabled;
10
- updateGreyness();
11
- });
12
-
13
- // Add main toggle click-listener
14
- const toggles = document.querySelectorAll('input'),
15
- masterToggle = toggles[0];
16
- masterToggle.addEventListener('change', function() {
17
- settings.save('extensionDisabled', !this.checked);
18
- syncExtension() ; updateGreyness();
19
- notify(config.appName + ( this.checked ? ' ON' : ' OFF' ));
20
- });
21
-
22
- // Add update-check span click-listener
23
- const updateSpan = document.querySelector('span[title*="update" i]');
24
- updateSpan.addEventListener('click', () => {
25
- window.close(); // popup
26
- chrome.runtime.requestUpdateCheck((status, details) => {
27
- alertToUpdate(status === 'update_available' ? details.version : '');
28
- });});
29
-
30
- // Add Support span click-listener
31
- const supportLink = document.querySelector('a[title*="support" i]'),
32
- supportSpan = supportLink.parentNode;
33
- supportSpan.addEventListener('click', (event) => {
34
- if (event.target == supportSpan) supportLink.click(); // to avoid double-toggle
35
- });
36
-
37
- // Add More Add-ons span click-listener
38
- const moreAddOnsLink = document.querySelector('a[title*="more" i]'),
39
- moreAddOnsSpan = moreAddOnsLink.parentNode;
40
- moreAddOnsSpan.addEventListener('click', (event) => {
41
- if (event.target == moreAddOnsSpan) moreAddOnsLink.click(); // to avoid double-toggle
42
- });
43
-
44
- // Add Powered by chatgpt.js hover-listener
45
- const chatGPTjsHostPath = 'https://media.chatgptjs.org/images/badges/',
46
- chatGPTjsImg = document.querySelector('.chatgpt-js img');
47
- chatGPTjsImg.addEventListener('mouseover', () => {
48
- chatGPTjsImg.src = chatGPTjsHostPath + 'powered-by-chatgpt.js.png'; });
49
- chatGPTjsImg.addEventListener('mouseout', () => {
50
- chatGPTjsImg.src = chatGPTjsHostPath + 'powered-by-chatgpt.js-faded.png'; });
51
-
52
- // Define FEEDBACK functions
53
-
54
- function notify(msg, position) {
55
- chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
56
- chrome.tabs.sendMessage(tabs[0].id, {
57
- action: 'notify', msg: msg, position: position || 'bottom-right' });
58
- });}
59
-
60
- function alertToUpdate(version) {
61
- chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
62
- chrome.tabs.sendMessage(tabs[0].id, {
63
- action: 'alertToUpdate', args: version });
64
- });}
65
-
66
- // Define SYNC functions
67
-
68
- function syncExtension() {
69
- chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
70
- chrome.tabs.sendMessage(tabs[0].id, { action: 'syncExtension' });
71
- });}
72
-
73
- function updateGreyness() {
74
-
75
- // Updated toolbar icon
76
- const iconDimensions = [16, 32, 64, 128], iconPaths = {};
77
- iconDimensions.forEach((dimension) => {
78
- iconPaths[dimension] = '../icons/'
79
- + (config.extensionDisabled ? 'faded/' : '')
80
- + 'icon' + dimension + '.png';
81
- });
82
- chrome.action.setIcon({ path: iconPaths });
83
-
84
- // Update menu contents
85
- document.querySelectorAll('div.logo, div.menu-title, div.menu')
86
- .forEach((elem) => {
87
- elem.classList.remove(masterToggle.checked ? 'disabled' : 'enabled');
88
- elem.classList.add(masterToggle.checked ? 'enabled' : 'disabled');
89
- });
90
- }
91
-
92
- })();