@kudoai/chatgpt.js 3.4.0 → 3.5.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.
package/docs/README.md CHANGED
@@ -47,7 +47,7 @@
47
47
 
48
48
  [![](https://img.shields.io/github/stars/KudoAI/chatgpt.js?label=Stars&color=af68ff&logo=github&logoColor=white&labelColor=464646&style=for-the-badge)](https://github.com/KudoAI/chatgpt.js/stargazers)
49
49
  [![](https://img.shields.io/badge/License-MIT-green.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge)](https://github.com/KudoAI/chatgpt.js/blob/main/LICENSE.md)
50
- [![](https://img.shields.io/github/size/KudoAI/chatgpt.js/dist/chatgpt.min.js?branch=v3.4.0&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge)](https://github.com/KudoAI/chatgpt.js/tree/v3.4.0/dist/chatgpt.min.js)
50
+ [![](https://img.shields.io/github/size/KudoAI/chatgpt.js/dist/chatgpt.min.js?branch=v3.5.0&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge)](https://github.com/KudoAI/chatgpt.js/tree/v3.5.0/dist/chatgpt.min.js)
51
51
  [![](https://img.shields.io/codefactor/grade/github/kudoai/chatgpt.js?label=Code+Quality&logo=codefactor&logoColor=white&labelColor=464646&color=1acc6c&style=for-the-badge)](https://www.codefactor.io/repository/github/kudoai/chatgpt.js)
52
52
  [![](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dkudoai_chatgpt.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold)](https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=kudoai_chatgpt.js)
53
53
  [![](https://img.shields.io/badge/Mentioned_in-Awesome-cca8c4?logo=awesomelists&logoColor=white&labelColor=464646&style=for-the-badge)](https://github.com/sindresorhus/awesome-chatgpt#javascript)
@@ -86,7 +86,7 @@
86
86
 
87
87
  ```js
88
88
  (async () => {
89
- await import('https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.4.0/dist/chatgpt.min.js');
89
+ await import('https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.5.0/dist/chatgpt.min.js');
90
90
  // Your code here...
91
91
  })();
92
92
  ```
@@ -95,7 +95,7 @@
95
95
 
96
96
  ```js
97
97
  var xhr = new XMLHttpRequest();
98
- xhr.open('GET', 'https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.4.0/dist/chatgpt.min.js');
98
+ xhr.open('GET', 'https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.5.0/dist/chatgpt.min.js');
99
99
  xhr.onload = function () {
100
100
  if (xhr.status === 200) {
101
101
  var chatgptJS = document.createElement('script');
@@ -118,7 +118,7 @@ function yourCode() {
118
118
 
119
119
  ```js
120
120
  ...
121
- // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.4.0/dist/chatgpt.min.js
121
+ // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.5.0/dist/chatgpt.min.js
122
122
  // ==/UserScript==
123
123
 
124
124
  // Your code here...
@@ -188,7 +188,7 @@ chatgpt.get('reply', 'last');
188
188
 
189
189
  Each call equally fetches the last response. If you think it works, it probably will... so just type it!
190
190
 
191
- If it didn't, check out the extended [userguide](https://github.com/KudoAI/chatgpt.js/blob/v3.4.0/docs/USERGUIDE.md), or simply submit an [issue](https://github.com/KudoAI/chatgpt.js/issues) or [PR](https://github.com/KudoAI/chatgpt.js/pulls) and it will be integrated, ezpz!
191
+ If it didn't, check out the extended [userguide](https://github.com/KudoAI/chatgpt.js/blob/v3.5.0/docs/USERGUIDE.md), or simply submit an [issue](https://github.com/KudoAI/chatgpt.js/issues) or [PR](https://github.com/KudoAI/chatgpt.js/pulls) and it will be integrated, ezpz!
192
192
 
193
193
  <img height=8px width="100%" src="https://media.chatgptjs.org/images/separators/gradient-aqua.png?78210a7">
194
194
 
@@ -336,6 +336,7 @@ This library exists thanks to code, translations, issues & ideas from the follow
336
336
  [![](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/75193555?first-contrib=2024.10.28-fix-nepali-typo&h=47&w=47&mask=circle&maxage=7d "@samir-byte")](https://github.com/samir-byte)
337
337
  [![](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54546340?first-contrib=2024.10.28-fix-nepali-grammar&h=47&w=47&mask=circle&maxage=7d "@ghimirebibek")](https://github.com/ghimirebibek)
338
338
  [![](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/82641474?first-contrib=2024.10.30-improve-hindi-readme&h=47&w=47&mask=circle&maxage=7d "@JanumalaAkhilendra")](https://github.com/JanumalaAkhilendra)
339
+ [![](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/130197125?first-contrib=2024.12.1-new-chat-selector-outdated-report&h=47&w=47&mask=circle&maxage=7d "@AliasUruz")](https://github.com/AliasUruz)
339
340
  [![](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/29110&h=47&w=47&mask=circle&maxage=7d "Dependabot")](https://github.com/dependabot)
340
341
  <a href="https://chatgpt.com"><picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://images.weserv.nl/?url=https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@main/media/images/icons/platforms/chatgpt/black-on-white/icon189.png?h=46&w=46&mask=circle&maxage=7d"><img src="https://images.weserv.nl/?url=https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@main/media/images/icons/platforms/chatgpt/white-on-black/icon189.png?h=46&w=46&mask=circle&maxage=7d" title="ChatGPT"></picture></a>
341
342
  <a href="https://poe.com"><picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://images.weserv.nl/?url=https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@main/media/images/icons/platforms/poe/w-purple-blue-stripes/black-on-white/icon175.png?h=46&w=46&mask=circle&maxage=7d"><img src="https://images.weserv.nl/?url=https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@main/media/images/icons/platforms/poe/w-purple-blue-stripes/white-on-black/icon175.png?h=46&w=46&mask=circle&maxage=7d" title="Poe"></picture></a>
@@ -367,7 +368,7 @@ This library exists thanks to code, translations, issues & ideas from the follow
367
368
  <div align="center">
368
369
 
369
370
  **[Releases](https://github.com/KudoAI/chatgpt.js/releases)** /
370
- [Userguide](https://github.com/KudoAI/chatgpt.js/blob/v3.4.0/docs/USERGUIDE.md) /
371
+ [Userguide](https://github.com/KudoAI/chatgpt.js/blob/v3.5.0/docs/USERGUIDE.md) /
371
372
  [Discuss](https://github.com/KudoAI/chatgpt.js/discussions) /
372
373
  [Back to top ↑](#top)
373
374
 
package/docs/SECURITY.md CHANGED
@@ -25,6 +25,4 @@
25
25
 
26
26
  # Security Policy
27
27
 
28
- If you find a vulnerability, please open a [draft security advisory](https://github.com/KudoAI/chatgpt.js/security/advisories/new).
29
-
30
- Pull requests are also welcome, but for safety reasons, send an email to <security@kudoai.com> and wait for a response before making it public.
28
+ If you find a vulnerability, please follow the reporting instructions @ https://tidelift.com/security
package/docs/USERGUIDE.md CHANGED
@@ -159,7 +159,7 @@
159
159
 
160
160
  ```js
161
161
  (async () => {
162
- await import('https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.4.0/dist/chatgpt.min.js');
162
+ await import('https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.5.0/dist/chatgpt.min.js');
163
163
  // Your code here...
164
164
  })();
165
165
  ```
@@ -168,7 +168,7 @@
168
168
 
169
169
  ```js
170
170
  var xhr = new XMLHttpRequest();
171
- xhr.open('GET', 'https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.4.0/dist/chatgpt.min.js');
171
+ xhr.open('GET', 'https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.5.0/dist/chatgpt.min.js');
172
172
  xhr.onload = function () {
173
173
  if (xhr.status === 200) {
174
174
  var chatgptJS = document.createElement('script');
@@ -190,7 +190,7 @@ function yourCode() {
190
190
 
191
191
  ```js
192
192
  ...
193
- // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.4.0/dist/chatgpt.min.js
193
+ // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.5.0/dist/chatgpt.min.js
194
194
  // ==/UserScript==
195
195
 
196
196
  // Your code here...
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kudoai/chatgpt.js",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "Client-side JavaScript library for ChatGPT",
5
5
  "author": {
6
6
  "name": "KudoAI & contributors",
@@ -1,10 +1,9 @@
1
1
  // Requires lib/dom.js
2
2
 
3
3
  window.icons = {
4
-
5
- dependencies: {
6
- import(dependencies) { // { app }
7
- for (const name in dependencies) this[name] = dependencies[name] }
4
+ imports: {
5
+ import(deps) { // { app }
6
+ for (const depName in deps) this[depName] = deps[depName] }
8
7
  },
9
8
 
10
9
  create({ name, size = 16, width, height, ...additionalAttrs }) {
@@ -27,6 +26,6 @@ window.icons = {
27
26
 
28
27
  questionMark: {
29
28
  type: 'png',
30
- get src() { return `${icons.dependencies.app.urls.assetHost}@b5551ac/images/icons/question-mark/icon16.png` }
29
+ get src() { return `${icons.imports.app.urls.assetHost}@b5551ac/images/icons/question-mark/icon16.png` }
31
30
  }
32
31
  };
@@ -2,27 +2,83 @@
2
2
 
3
3
  window.modals = {
4
4
  stack: [], // of types of undismissed modals
5
+ get class() { return `${this.imports.app.cssPrefix}-modal` },
5
6
 
6
- dependencies: {
7
- import(dependencies) { // { app, siteAlert }
8
- for (const name in dependencies) this[name] = dependencies[name] }
7
+ imports: {
8
+ import(deps) { // { app, env }
9
+ for (const depName in deps) this[depName] = deps[depName] }
10
+ },
11
+
12
+ alert(title = '', msg = '', btns = '', checkbox = '', width = '') { // generic one from chatgpt.alert()
13
+ const alertID = chatgpt.alert(title, msg, btns, checkbox, width),
14
+ alert = document.getElementById(alertID).firstChild
15
+ this.init(alert) // add classes + starry bg
16
+ return alert
9
17
  },
10
18
 
11
19
  open(modalType) {
12
- this.stack.unshift(modalType) // add to stack
13
20
  const modal = this[modalType]() // show modal
14
- modal.classList.add('chatgpt-infinity-modal')
15
- modal.onmousedown = this.dragHandlers.mousedown
16
- dom.fillStarryBG(modal) // fill BG w/ rising stars
21
+ this.stack.unshift(modalType) // add to stack
22
+ this.init(alert) // add classes + starry bg
17
23
  this.observeRemoval(modal, modalType) // to maintain stack for proper nav
18
24
  },
19
25
 
26
+ init(modal) {
27
+ if (!this.styles) this.stylize() // to init/append stylesheet
28
+ modal.classList.add(this.class) ; modal.parentNode.classList.add(`${this.class}-bg`) // add classes
29
+ dom.fillStarryBG(modal) // add starry bg
30
+ },
31
+
32
+ stylize() {
33
+ if (!this.styles) {
34
+ this.styles = dom.create.elem('style') ; this.styles.id = `${this.class}-styles`
35
+ document.head.append(this.styles)
36
+ }
37
+ this.styles.innerText = (
38
+ `.${this.class} {` // modals
39
+ + 'font-family: -apple-system, system-ui, BlinkMacSystemFont, Segoe UI, Roboto,'
40
+ + 'Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif ;'
41
+ + 'padding: 20px 25px 24px 25px !important ; font-size: 20px ;'
42
+ + `color: ${ this.imports.env.ui.scheme == 'dark' ? 'white' : 'black' } !important ;`
43
+ + `background-image: linear-gradient(180deg, ${
44
+ this.imports.env.ui.scheme == 'dark' ? '#99a8a6 -200px, black 200px'
45
+ : '#b6ebff -296px, white 171px' }) }`
46
+ + `.${this.class} [class*=modal-close-btn] {`
47
+ + 'position: absolute !important ; float: right ; top: 14px !important ; right: 16px !important ;'
48
+ + 'cursor: pointer ; width: 33px ; height: 33px ; border-radius: 20px }'
49
+ + `.${this.class} [class*=modal-close-btn] svg { height: 10px }`
50
+ + `.${this.class} [class*=modal-close-btn] path {`
51
+ + `${ this.imports.env.ui.scheme == 'dark' ? 'stroke: white ; fill: white'
52
+ : 'stroke: #9f9f9f ; fill: #9f9f9f' }}`
53
+ + ( this.imports.env.ui.scheme == 'dark' ? // invert dark mode hover paths
54
+ `.${this.class} [class*=modal-close-btn]:hover path { stroke: black ; fill: black }` : '' )
55
+ + `.${this.class} [class*=modal-close-btn]:hover { background-color: #f2f2f2 }` // hover underlay
56
+ + `.${this.class} [class*=modal-close-btn] svg { margin: 11.5px }` // center SVG for hover underlay
57
+ + `.${this.class} a {`
58
+ + `color: #${ this.imports.env.ui.scheme == 'dark' ? '00cfff' : '1e9ebb' } !important }`
59
+ + `.${this.class} h2 { font-weight: bold }`
60
+ + `.${this.class} button {`
61
+ + 'font-size: 14px ; text-transform: uppercase ;' // shrink/uppercase labels
62
+ + 'border-radius: 0 !important ;' // square borders
63
+ + 'transition: transform 0.1s ease-in-out, box-shadow 0.1s ease-in-out ;' // smoothen hover fx
64
+ + 'cursor: pointer !important ;' // add finger cursor
65
+ + `border: 1px solid ${ this.imports.env.ui.scheme == 'dark' ? 'white' : 'black' } !important ;`
66
+ + 'padding: 8px !important ; min-width: 102px }' // resize
67
+ + `.${this.class} button:hover {` // add zoom, re-scheme
68
+ + 'transform: scale(1.055) ; color: black !important ;'
69
+ + `background-color: #${ this.imports.env.ui.scheme == 'dark' ? '00cfff' : '9cdaff' } !important }`
70
+ + ( !this.imports.env.browser.isMobile ?
71
+ `.${this.class} .modal-buttons { margin-left: -13px !important }` : '' )
72
+ + `.about-em { color: ${ this.imports.env.ui.scheme == 'dark' ? 'white' : 'green' } !important }`
73
+ )
74
+ },
75
+
20
76
  observeRemoval(modal, modalType) { // to maintain stack for proper nav
21
77
  const modalBG = modal.parentNode
22
78
  new MutationObserver(([mutation], obs) => {
23
79
  mutation.removedNodes.forEach(removedNode => { if (removedNode == modalBG) {
24
80
  if (this.stack[0] == modalType) { // new modal not launched, implement nav back logic
25
- this.stack.shift() // remove this modal type from stack
81
+ this.stack.shift() // remove this modal type from stack 1st
26
82
  const prevModalType = this.stack[0]
27
83
  if (prevModalType) { // open it
28
84
  this.stack.shift() // remove type from stack since re-added on open
@@ -34,73 +90,44 @@ window.modals = {
34
90
  }).observe(modalBG.parentNode, { childList: true, subtree: true })
35
91
  },
36
92
 
37
- dragHandlers: {
38
- mousedown(event) { // find modal, attach listeners, init XY offsets
39
- if (event.button != 0) return // prevent non-left-click drag
40
- if (getComputedStyle(event.target).cursor == 'pointer') return // prevent drag on interactive elems
41
- modals.dragHandlers.draggableElem = event.currentTarget
42
- modals.dragHandlers.draggableElem.style.cursor = 'grabbing'
43
- event.preventDefault(); // prevent sub-elems like icons being draggable
44
- ['mousemove', 'mouseup'].forEach(event => document.addEventListener(event, modals.dragHandlers[event]))
45
- const draggableElemRect = modals.dragHandlers.draggableElem.getBoundingClientRect()
46
- modals.dragHandlers.offsetX = event.clientX - draggableElemRect.left +21
47
- modals.dragHandlers.offsetY = event.clientY - draggableElemRect.top +12
48
- },
49
-
50
- mousemove(event) { // drag modal
51
- if (modals.dragHandlers.draggableElem) {
52
- const newX = event.clientX - modals.dragHandlers.offsetX,
53
- newY = event.clientY - modals.dragHandlers.offsetY
54
- Object.assign(modals.dragHandlers.draggableElem.style, { left: `${newX}px`, top: `${newY}px` })
55
- }
56
- },
57
-
58
- mouseup() { // remove listeners, reset modals.dragHandlers.draggableElem
59
- modals.dragHandlers.draggableElem.style.cursor = 'inherit';
60
- ['mousemove', 'mouseup'].forEach(event =>
61
- document.removeEventListener(event, modals.dragHandlers[event]))
62
- modals.dragHandlers.draggableElem = null
63
- }
64
- },
65
-
66
93
  about() {
67
94
 
68
- // Init styles
69
- const headingStyle = 'font-size: 1.15rem',
70
- pStyle = 'position: relative ; left: 3px',
71
- pBrStyle = 'position: relative ; left: 4px ',
72
- aStyle = 'color: ' + ( chatgpt.isDarkMode() ? '#c67afb' : '#8325c4' ) // purple
73
-
74
- // Init buttons
75
- const modalBtns = [
76
- function getSupport(){ modals.safeWinOpen(`${modals.dependencies.app.urls.gitHub}/issues`) },
77
- function rateUs() { modals.safeWinOpen(`${modals.dependencies.app.urls.gitHub}/discussions`) },
78
- function moreAiExtensions(){ modals.safeWinOpen(modals.dependencies.app.urls.relatedExtensions) }
79
- ]
80
-
81
95
  // Show modal
82
- const aboutModal = this.dependencies.siteAlert(
83
- `${this.dependencies.app.symbol} ${chrome.runtime.getManifest().name}`, // title
84
- `<span style="${headingStyle}"><b>🏷️ <i>Version</i></b>: </span>`
85
- + `<span style="${pStyle}">${this.dependencies.app.version}</span>\n`
86
- + `<span style="${headingStyle}"><b>⚡ <i>Powered by</i></b>: </span>`
87
- + `<span style="${pStyle}">`
88
- + `<a style="${aStyle}" href="${this.dependencies.app.urls.chatgptJS}" target="_blank"`
89
- + ' rel="noopener">chatgpt.js</a></span>\n'
90
- + `<span style="${headingStyle}"><b>📜 <i>Open source code</i></b>:</span>\n`
91
- + `<span style="${pBrStyle}"><a href="${this.dependencies.app.urls.gitHub}" target="_blank"`
92
- + ` rel="nopener">${this.dependencies.app.urls.gitHub}</a></span>`,
93
- modalBtns, '', 451
96
+ const aboutModal = this.alert(
97
+ `${this.imports.app.symbol} ${chrome.runtime.getManifest().name}`, // title
98
+ '🧠 Author: ' // msg
99
+ + `<a href="${this.imports.app.author.url}">${this.imports.app.author.name}</a> `
100
+ + `& <a href="${this.imports.app.urls.contributors}">contributors</a>\n`
101
+ + `🏷️ Version: <span class="about-em">${this.imports.app.version}</span>\n`
102
+ + '📜 Open source code: '
103
+ + `<a href="${this.imports.app.urls.gitHub}" target="_blank" rel="nopener">`
104
+ + this.imports.app.urls.gitHub + '</a>\n'
105
+ + '⚡ Powered by: '
106
+ + `<a href="${this.imports.app.urls.chatgptJS}" target="_blank" rel="noopener">chatgpt.js</a>`,
107
+ [ function getSupport(){}, function rateUs(){}, function moreAiExtensions(){} ], // button labels
108
+ '', 656 // modal width
94
109
  )
95
110
 
96
111
  // Format text
97
- aboutModal.querySelector('h2').style.cssText = 'text-align: center ; font-size: 37px ; padding: 9px'
98
- aboutModal.querySelector('p').style.cssText = 'text-align: center'
112
+ aboutModal.querySelector('h2').style.cssText = (
113
+ 'text-align: center ; font-size: 51px ; line-height: 46px ; padding: 15px 0' )
114
+ aboutModal.querySelector('p').style.cssText = (
115
+ 'text-align: center ; overflow-wrap: anywhere ;'
116
+ + `margin: ${ this.imports.env.browser.isPortrait ? '6px 0 -16px' : '3px 0 0' }` )
99
117
 
100
118
  // Hack buttons
101
119
  aboutModal.querySelector('.modal-buttons').style.justifyContent = 'center'
102
120
  aboutModal.querySelectorAll('button').forEach(btn => {
103
- btn.style.cssText = 'cursor: pointer !important ; height: 43px'
121
+ btn.style.cssText = 'height: 55px ; min-width: 136px ; text-align: center'
122
+
123
+ // Replace buttons w/ clones that don't dismiss modal
124
+ const btnClone = btn.cloneNode(true)
125
+ btn.parentNode.replaceChild(btnClone, btn) ; btn = btnClone
126
+ btn.onclick = () => this.safeWinOpen(
127
+ btn.textContent == 'Get Support' ? `${modals.imports.app.urls.gitHub}/issues`
128
+ : btn.textContent == 'Rate Us' ? `${modals.imports.app.urls.gitHub}/discussions`
129
+ : modals.imports.app.urls.relatedExtensions
130
+ )
104
131
 
105
132
  // Prepend emoji
106
133
  if (/support/i.test(btn.textContent))
@@ -8,18 +8,22 @@
8
8
  await import(chrome.runtime.getURL(resource))
9
9
 
10
10
  // Init ENV context
11
- const env = { browser: { isMobile: chatgpt.browser.isMobile() }}
11
+ const env = { browser: { isMobile: chatgpt.browser.isMobile() }, ui: { scheme: getScheme() }}
12
+ env.browser.isPortrait = env.browser.isMobile && (window.innerWidth < window.innerHeight)
12
13
 
13
14
  // Import APP data
14
15
  const { app } = await chrome.storage.sync.get('app')
15
- modals.dependencies.import({ app, siteAlert })
16
+
17
+ // Export DEPENDENCIES to imported resources
18
+ dom.imports.import({ env }) // for env.ui.scheme
19
+ modals.imports.import({ app, env }) // for app data + env.ui.scheme
16
20
 
17
21
  // Add CHROME MSG listener
18
22
  chrome.runtime.onMessage.addListener(req => { // from service-worker.js + popup/index.html
19
23
  if (req.action == 'notify')
20
24
  notify(...['msg', 'pos', 'notifDuration', 'shadow'].map(arg => req.options[arg]))
21
25
  else if (req.action == 'alert')
22
- siteAlert(...['title', 'msg', 'btns', 'checkbox', 'width'].map(arg => req.options[arg]))
26
+ modals.alert(...['title', 'msg', 'btns', 'checkbox', 'width'].map(arg => req.options[arg]))
23
27
  else if (req.action == 'showAbout') chatgpt.isLoaded().then(() => { modals.open('about') })
24
28
  else if (req.action == 'syncConfigToUI') syncConfigToUI(req.options)
25
29
  })
@@ -27,7 +31,7 @@
27
31
  // Init SETTINGS
28
32
  await settings.load(Object.keys(settings.controls), 'skipAlert')
29
33
 
30
- // Define FEEDBACK functions
34
+ // Define FUNCTIONS
31
35
 
32
36
  function notify(msg, pos = '', notifDuration = '', shadow = '') {
33
37
 
@@ -36,13 +40,12 @@
36
40
  if (foundState) msg = msg.replace(foundState, '')
37
41
 
38
42
  // Show notification
39
- siteAlert(`${app.symbol} ${msg}`, pos, notifDuration,
40
- shadow || chatgpt.isDarkMode() ? '' : 'shadow' )
43
+ chatgpt.notify(`${app.symbol} ${msg}`, pos, notifDuration, shadow || env.ui.scheme == 'dark' ? '' : 'shadow')
41
44
  const notif = document.querySelector('.chatgpt-notif:last-child')
42
45
 
43
46
  // Append styled state word
44
47
  if (foundState) {
45
- const styledStateSpan = document.createElement('span')
48
+ const styledStateSpan = dom.create.elem('span')
46
49
  styledStateSpan.style.cssText = `color: ${
47
50
  foundState == 'OFF' ? '#ef4848 ; text-shadow: rgba(255, 169, 225, 0.44) 2px 1px 5px'
48
51
  : '#5cef48 ; text-shadow: rgba(255, 250, 169, 0.38) 2px 1px 5px' }`
@@ -50,13 +53,6 @@
50
53
  }
51
54
  }
52
55
 
53
- function siteAlert(title = '', msg = '', btns = '', checkbox = '', width = '') {
54
- const alertID = chatgpt.alert(title, msg, btns, checkbox, width)
55
- return document.getElementById(alertID).firstChild
56
- }
57
-
58
- // Define SYNC function
59
-
60
56
  async function syncConfigToUI(options) { // eslint-disable-line
61
57
  await settings.load('extensionDisabled', Object.keys(settings.controls)) // load from Chrome storage to content.js config
62
58
  if (config.extensionDisabled) {
@@ -70,49 +66,30 @@
70
66
  }
71
67
  }
72
68
 
69
+ function getScheme() {
70
+ return document.documentElement.className
71
+ || (window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ? 'dark' : 'light')
72
+ }
73
+
73
74
  // Run MAIN routine
74
75
 
75
76
  chatgpt.printAllFunctions() // to console
76
77
 
77
78
  // CHILL a bit if your hacks depend on delayed DOM content
78
79
  await chatgpt.isLoaded()
79
- await new Promise(resolve => setTimeout(resolve, 500)) // sleep .5s
80
-
81
- // Add/update TWEAKS style
82
- const tweaksStyleUpdated = 1732627011377 // timestamp of last edit for this file's tweaksStyle
83
- let tweaksStyle = document.getElementById('tweaks-style') // try to select existing style (from your other extensions)
84
- if (!tweaksStyle || parseInt(tweaksStyle.getAttribute('last-updated')) < tweaksStyleUpdated) {
85
- if (!tweaksStyle) { // outright missing, create/id/attr/append it first
86
- tweaksStyle = dom.create.elem('style', {
87
- id: 'tweaks-style', 'last-updated': tweaksStyleUpdated.toString() })
88
- document.head.append(tweaksStyle)
89
- }
90
- tweaksStyle.innerText = (
91
- '[class$="-modal"] { z-index: 13456 ; position: absolute }' // to be click-draggable
92
- + ( chatgpt.isDarkMode() ? '.chatgpt-modal > div { border: 1px solid white }' : '' )
93
- + '.chatgpt-modal button {'
94
- + 'font-size: 0.77rem ; text-transform: uppercase ;' // shrink/uppercase labels
95
- + 'border-radius: 0 !important ;' // square borders
96
- + 'transition: transform 0.1s ease-in-out, box-shadow 0.1s ease-in-out ;' // smoothen hover fx
97
- + 'cursor: pointer !important ;' // add finger cursor
98
- + 'padding: 5px !important ; min-width: 102px }' // resize
99
- + '.chatgpt-modal button:hover {' // add zoom, re-scheme
100
- + 'transform: scale(1.055) ; color: black !important ;'
101
- + `background-color: #${ chatgpt.isDarkMode() ? '00cfff' : '9cdaff' } !important }`
102
- + ( !env.browser.isMobile ? '.modal-buttons { margin-left: -13px !important }' : '' )
103
- )
104
- }; // eslint-disable-line
80
+ await new Promise(resolve => setTimeout(resolve, 500)); // sleep .5s
105
81
 
106
82
  // Add STARS styles for modals
107
83
  ['black', 'white'].forEach(color => document.head.append(
108
84
  dom.create.elem('link', { rel: 'stylesheet',
109
- href: `https://assets.aiwebextensions.com/styles/css/${color}-rising-stars.min.css?v=542104c`
85
+ href: `https://assets.aiwebextensions.com/styles/rising-stars/dist/${
86
+ color}.min.css?v=0cde30f9ae3ce99ae998141f6e7a36de9b0cc2e7`
110
87
  })))
111
88
 
112
89
  if (config.extensionDisabled) return
113
90
 
114
91
  if (!config.skipAlert) // alert to extension load
115
- chatgpt.alert('≫ ChatGPT extension loaded! 🚀', // title
92
+ modals.alert('≫ ChatGPT extension loaded! 🚀', // title
116
93
  'Success! Press Ctrl+Shift+J to view all chatgpt.js methods.', // msg
117
94
  function getHelp() { // button
118
95
  chrome.tabs.create({ url: `${app.urls.gitHub}/issues` }) },
@@ -120,6 +97,16 @@
120
97
  settings.save('skipAlert', !config.skipAlert) }
121
98
  )
122
99
 
100
+ // Monitor SCHEME PREF CHANGES to update modal colors + env.ui.scheme for your use
101
+ new MutationObserver(handleSchemePrefChange).observe( // for site scheme pref changes
102
+ document.documentElement, { attributes: true, attributeFilter: ['class'] })
103
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener( // for browser/system scheme pref changes
104
+ 'change', () => requestAnimationFrame(handleSchemePrefChange))
105
+ function handleSchemePrefChange() {
106
+ const displayedScheme = getScheme()
107
+ if (env.ui.scheme != displayedScheme) { env.ui.scheme = displayedScheme ; modals.stylize() }
108
+ }
109
+
123
110
  // Your code here...
124
111
  // Your code here...
125
112
  // Your code here...