@kudoai/chatgpt.js 3.3.4 → 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.
- package/README.md +35 -22
- package/chatgpt.js +130 -79
- package/dist/chatgpt.min.js +3 -3
- package/docs/README.md +35 -22
- package/docs/SECURITY.md +6 -1
- package/docs/USERGUIDE.md +4 -4
- package/package.json +18 -11
- package/starters/chrome/docs/README.md +13 -9
- package/starters/chrome/extension/components/icons.js +32 -0
- package/starters/chrome/extension/components/modals.js +121 -0
- package/starters/chrome/extension/content.js +121 -47
- package/starters/chrome/extension/icons/faded/icon128.png +0 -0
- package/starters/chrome/extension/icons/faded/icon16.png +0 -0
- package/starters/chrome/extension/icons/faded/icon32.png +0 -0
- package/starters/chrome/extension/icons/faded/icon64.png +0 -0
- package/starters/chrome/extension/lib/chatgpt.js +130 -79
- package/starters/chrome/extension/lib/dom.js +28 -0
- package/starters/chrome/extension/lib/settings.js +30 -0
- package/starters/chrome/extension/manifest.json +25 -22
- package/starters/chrome/extension/popup/controller.js +138 -0
- package/starters/chrome/extension/popup/index.html +7 -44
- package/starters/chrome/extension/popup/style.css +15 -6
- package/starters/chrome/extension/service-worker.js +38 -0
- package/starters/docs/README.md +9 -2
- package/starters/greasemonkey/chatgpt.js-greasemonkey-starter.user.js +12 -12
- package/starters/greasemonkey/docs/README.md +2 -0
- package/starters/chrome/extension/background.js +0 -14
- package/starters/chrome/extension/lib/settings-utils.js +0 -24
- package/starters/chrome/extension/popup/popup.js +0 -92
- package/starters/chrome/media/images/icons/refresh/icon16.png +0 -0
- package/starters/chrome/media/images/icons/refresh/icon50.png +0 -0
- /package/starters/chrome/{media/images → images}/icons/question-mark/icon16.png +0 -0
- /package/starters/chrome/{media/images → images}/icons/question-mark/icon512.png +0 -0
- /package/starters/chrome/{media/images → images}/screenshots/chatgpt-extension-in-list.png +0 -0
- /package/starters/chrome/{media/images → images}/screenshots/developer-mode-toggle.png +0 -0
- /package/starters/chrome/{media/images → images}/screenshots/developer-mode-toggle.psd +0 -0
- /package/starters/chrome/{media/images → images}/screenshots/extension-loaded.png +0 -0
- /package/starters/chrome/{media/images → images}/screenshots/load-unpacked-button.png +0 -0
- /package/starters/chrome/{media/images → images}/screenshots/reload-extension-button.png +0 -0
- /package/starters/chrome/{media/images → images}/screenshots/reload-page-button.png +0 -0
- /package/starters/chrome/{media/images → images}/screenshots/select-extension-folder.png +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<a id="top"></a>
|
|
2
|
+
|
|
1
3
|
<div align="center">
|
|
2
4
|
<h6>
|
|
3
5
|
<picture>
|
|
@@ -26,7 +28,7 @@
|
|
|
26
28
|
|
|
27
29
|
<br>
|
|
28
30
|
|
|
29
|
-
<img src="../
|
|
31
|
+
<img src="../images/screenshots/extension-loaded.png">
|
|
30
32
|
|
|
31
33
|
## ⚡ Installation
|
|
32
34
|
|
|
@@ -37,36 +39,38 @@
|
|
|
37
39
|
3. Visit `chrome://extensions` in Chrome (or any Chromium browser)
|
|
38
40
|
|
|
39
41
|
4. Ensure **Develper mode** toggle is activated<br>
|
|
40
|
-

|
|
41
43
|
|
|
42
44
|
5. Click **Load unpacked**<br><br>
|
|
43
|
-
<img src="../
|
|
45
|
+
<img src="../images/screenshots/load-unpacked-button.png">
|
|
44
46
|
<br>
|
|
45
47
|
|
|
46
48
|
6. In pop-up window, select the **extension** folder > click **Select Folder**<br><br><br>
|
|
47
|
-
<img src="../
|
|
49
|
+
<img src="../images/screenshots/select-extension-folder.png"><br><br>
|
|
48
50
|
|
|
49
51
|
That's it! **ChatGPT Extension** will now appear in extension list:
|
|
50
52
|
|
|
51
53
|
<br>
|
|
52
54
|
|
|
53
|
-
<img src="../
|
|
55
|
+
<img src="../images/screenshots/chatgpt-extension-in-list.png">
|
|
54
56
|
|
|
55
57
|
<p><br>
|
|
56
58
|
|
|
57
|
-
**💡 TIP:** _To reflect changes from source code, click **Reload** on extension tile + reload any Chrome tabs
|
|
59
|
+
**💡 TIP:** _To reflect changes from source code, click **Reload** on extension tile + reload any Chrome tabs content scripts are running on:_
|
|
58
60
|
|
|
59
61
|
<div align="center">
|
|
60
62
|
|
|
61
63
|
<br>
|
|
62
64
|
|
|
63
|
-
<img src="../
|
|
64
|
-
<img src="../
|
|
65
|
+
<img src="../images/screenshots/reload-extension-button.png">
|
|
66
|
+
<img src="../images/screenshots/reload-page-button.png">
|
|
65
67
|
|
|
66
68
|
<p><br>
|
|
67
69
|
|
|
68
70
|
</div>
|
|
69
71
|
|
|
72
|
+
_For advanced Chrome API methods, see: https://developer.chrome.com/docs/extensions/reference/api_
|
|
73
|
+
|
|
70
74
|
## 🤖 Made with chatgpt.js
|
|
71
75
|
|
|
72
76
|
These are some of the extensions featured by Google that use chatgpt.js:
|
|
@@ -90,4 +94,4 @@ These are some of the extensions featured by Google that use chatgpt.js:
|
|
|
90
94
|
|
|
91
95
|
#
|
|
92
96
|
|
|
93
|
-
<a href="https://github.com/KudoAI/chatgpt.js-chrome-starter/issues">Get Help</a> / <a href="#">Back to top ↑</a>
|
|
97
|
+
<a href="https://github.com/KudoAI/chatgpt.js-chrome-starter/issues">Get Help</a> / <a href="#top">Back to top ↑</a>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Requires lib/dom.js
|
|
2
|
+
|
|
3
|
+
window.icons = {
|
|
4
|
+
|
|
5
|
+
dependencies: {
|
|
6
|
+
import(dependencies) { // { app }
|
|
7
|
+
for (const name in dependencies) this[name] = dependencies[name] }
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
create({ name, size = 16, width, height, ...additionalAttrs }) {
|
|
11
|
+
const iconData = icons[name],
|
|
12
|
+
iconAttrs = { width: width || size, height: height || size, ...additionalAttrs }
|
|
13
|
+
if (iconData.type == 'svg') {
|
|
14
|
+
const svg = dom.create.svgElem('svg', { viewBox: iconData.viewBox, ...iconAttrs })
|
|
15
|
+
iconData.elems.forEach(([tag, attrs]) => svg.append(dom.create.svgElem(tag, attrs)))
|
|
16
|
+
return svg
|
|
17
|
+
} else // img w/ src
|
|
18
|
+
return dom.create.elem('img', { src: iconData.src, ...iconAttrs })
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
plus: {
|
|
22
|
+
type: 'svg', viewBox: '0 0 1024 1024',
|
|
23
|
+
elems: [
|
|
24
|
+
[ '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' }]
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
questionMark: {
|
|
29
|
+
type: 'png',
|
|
30
|
+
get src() { return `${icons.dependencies.app.urls.assetHost}@b5551ac/images/icons/question-mark/icon16.png` }
|
|
31
|
+
}
|
|
32
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Requires lib/chatgpt.js + lib/dom.js
|
|
2
|
+
|
|
3
|
+
window.modals = {
|
|
4
|
+
stack: [], // of types of undismissed modals
|
|
5
|
+
|
|
6
|
+
dependencies: {
|
|
7
|
+
import(dependencies) { // { app, siteAlert }
|
|
8
|
+
for (const name in dependencies) this[name] = dependencies[name] }
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
open(modalType) {
|
|
12
|
+
this.stack.unshift(modalType) // add to stack
|
|
13
|
+
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
|
|
17
|
+
this.observeRemoval(modal, modalType) // to maintain stack for proper nav
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
observeRemoval(modal, modalType) { // to maintain stack for proper nav
|
|
21
|
+
const modalBG = modal.parentNode
|
|
22
|
+
new MutationObserver(([mutation], obs) => {
|
|
23
|
+
mutation.removedNodes.forEach(removedNode => { if (removedNode == modalBG) {
|
|
24
|
+
if (this.stack[0] == modalType) { // new modal not launched, implement nav back logic
|
|
25
|
+
this.stack.shift() // remove this modal type from stack
|
|
26
|
+
const prevModalType = this.stack[0]
|
|
27
|
+
if (prevModalType) { // open it
|
|
28
|
+
this.stack.shift() // remove type from stack since re-added on open
|
|
29
|
+
this.open(prevModalType)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
obs.disconnect()
|
|
33
|
+
}})
|
|
34
|
+
}).observe(modalBG.parentNode, { childList: true, subtree: true })
|
|
35
|
+
},
|
|
36
|
+
|
|
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
|
+
about() {
|
|
67
|
+
|
|
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
|
+
// 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
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
// 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'
|
|
99
|
+
|
|
100
|
+
// Hack buttons
|
|
101
|
+
aboutModal.querySelector('.modal-buttons').style.justifyContent = 'center'
|
|
102
|
+
aboutModal.querySelectorAll('button').forEach(btn => {
|
|
103
|
+
btn.style.cssText = 'cursor: pointer !important ; height: 43px'
|
|
104
|
+
|
|
105
|
+
// Prepend emoji
|
|
106
|
+
if (/support/i.test(btn.textContent))
|
|
107
|
+
btn.textContent = '🧠 ' + btn.textContent
|
|
108
|
+
else if (/rate/i.test(btn.textContent))
|
|
109
|
+
btn.textContent = '⭐ ' + btn.textContent
|
|
110
|
+
else if (/extensions/i.test(btn.textContent))
|
|
111
|
+
btn.textContent = '🧠 ' + btn.textContent
|
|
112
|
+
|
|
113
|
+
// Hide Dismiss button
|
|
114
|
+
else btn.style.display = 'none'
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
return aboutModal
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
safeWinOpen(url) { open(url, '_blank', 'noopener') } // to prevent backdoor vulnerabilities
|
|
121
|
+
};
|
|
@@ -1,62 +1,136 @@
|
|
|
1
1
|
// NOTE: This script relies on the powerful chatgpt.js library @ https://chatgpt.js.org
|
|
2
2
|
// © 2023–2024 KudoAI & contributors under the MIT license
|
|
3
|
-
// Source: https://github.com/KudoAI/chatgpt.js
|
|
4
|
-
// Latest minified release: https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js/chatgpt.min.js
|
|
5
3
|
|
|
6
4
|
(async () => {
|
|
7
5
|
|
|
8
|
-
// Import
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// Add Chrome action msg listener
|
|
13
|
-
chrome.runtime.onMessage.addListener((request) => {
|
|
14
|
-
if (request.action === 'notify') notify(request.msg, request.position);
|
|
15
|
-
else if (request.action === 'alert') alert(request.title, request.msg, request.btns);
|
|
16
|
-
else if (typeof window[request.action] === 'function') {
|
|
17
|
-
const args = Array.isArray(request.args) ? request.args // preserve array if supplied
|
|
18
|
-
: request.args !== undefined ? [request.args] : []; // convert to array if single or no arg
|
|
19
|
-
window[request.action](...args); // call expression functions
|
|
20
|
-
}
|
|
21
|
-
return true;
|
|
22
|
-
});
|
|
6
|
+
// Import JS resources
|
|
7
|
+
for (const resource of ['components/modals.js', 'lib/chatgpt.js', 'lib/dom.js', 'lib/settings.js'])
|
|
8
|
+
await import(chrome.runtime.getURL(resource))
|
|
23
9
|
|
|
24
|
-
|
|
25
|
-
chatgpt.
|
|
26
|
-
settings.load('skipAlert').then(() => {
|
|
27
|
-
if (!config.skipAlert) {
|
|
28
|
-
chatgpt.alert('≫ ChatGPT extension loaded! 🚀', // title
|
|
29
|
-
'Success! Press Ctrl+Shift+J to view all chatgpt.js methods.', // msg
|
|
30
|
-
function getHelp() { // button
|
|
31
|
-
window.open(config.ghRepoURL + '/issues', '_blank', 'noopener'); },
|
|
32
|
-
function dontShowAgain() { // checkbox
|
|
33
|
-
settings.save('skipAlert', !config.skipAlert); }
|
|
34
|
-
);}});
|
|
10
|
+
// Init ENV context
|
|
11
|
+
const env = { browser: { isMobile: chatgpt.browser.isMobile() }}
|
|
35
12
|
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
//
|
|
13
|
+
// Import APP data
|
|
14
|
+
const { app } = await chrome.storage.sync.get('app')
|
|
15
|
+
modals.dependencies.import({ app, siteAlert })
|
|
16
|
+
|
|
17
|
+
// Add CHROME MSG listener
|
|
18
|
+
chrome.runtime.onMessage.addListener(req => { // from service-worker.js + popup/index.html
|
|
19
|
+
if (req.action == 'notify')
|
|
20
|
+
notify(...['msg', 'pos', 'notifDuration', 'shadow'].map(arg => req.options[arg]))
|
|
21
|
+
else if (req.action == 'alert')
|
|
22
|
+
siteAlert(...['title', 'msg', 'btns', 'checkbox', 'width'].map(arg => req.options[arg]))
|
|
23
|
+
else if (req.action == 'showAbout') chatgpt.isLoaded().then(() => { modals.open('about') })
|
|
24
|
+
else if (req.action == 'syncConfigToUI') syncConfigToUI(req.options)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// Init SETTINGS
|
|
28
|
+
await settings.load(Object.keys(settings.controls), 'skipAlert')
|
|
42
29
|
|
|
43
30
|
// Define FEEDBACK functions
|
|
44
31
|
|
|
45
|
-
function notify(msg,
|
|
46
|
-
chatgpt.notify(`${ config.appSymbol } ${ msg }`, position, notifDuration,
|
|
47
|
-
shadow || chatgpt.isDarkMode() ? '' : 'shadow' ); }
|
|
32
|
+
function notify(msg, pos = '', notifDuration = '', shadow = '') {
|
|
48
33
|
|
|
49
|
-
|
|
50
|
-
|
|
34
|
+
// Strip state word to append colored one later
|
|
35
|
+
const foundState = ['ON', 'OFF'].find(word => msg.includes(word))
|
|
36
|
+
if (foundState) msg = msg.replace(foundState, '')
|
|
37
|
+
|
|
38
|
+
// Show notification
|
|
39
|
+
siteAlert(`${app.symbol} ${msg}`, pos, notifDuration,
|
|
40
|
+
shadow || chatgpt.isDarkMode() ? '' : 'shadow' )
|
|
41
|
+
const notif = document.querySelector('.chatgpt-notif:last-child')
|
|
42
|
+
|
|
43
|
+
// Append styled state word
|
|
44
|
+
if (foundState) {
|
|
45
|
+
const styledStateSpan = document.createElement('span')
|
|
46
|
+
styledStateSpan.style.cssText = `color: ${
|
|
47
|
+
foundState == 'OFF' ? '#ef4848 ; text-shadow: rgba(255, 169, 225, 0.44) 2px 1px 5px'
|
|
48
|
+
: '#5cef48 ; text-shadow: rgba(255, 250, 169, 0.38) 2px 1px 5px' }`
|
|
49
|
+
styledStateSpan.append(foundState) ; notif.append(styledStateSpan)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
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
|
+
}
|
|
51
57
|
|
|
52
58
|
// Define SYNC function
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
settings.load('extensionDisabled'
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
async function syncConfigToUI(options) { // eslint-disable-line
|
|
61
|
+
await settings.load('extensionDisabled', Object.keys(settings.controls)) // load from Chrome storage to content.js config
|
|
62
|
+
if (config.extensionDisabled) {
|
|
63
|
+
// Remove all hacks
|
|
64
|
+
} else {
|
|
65
|
+
// Add/remove hacks to reflect each potentially updated setting per settings.controls in lib/settings.mjs
|
|
66
|
+
// e.g. if you created toolbar popup toggle to hide ChatGPT footer using hiddenFooter key...
|
|
67
|
+
// ...here you would use options?.updatedKey == 'hiddenFooter' && config.hiddenFooter...
|
|
68
|
+
// ...to conditionally append/remove hidden footer style...
|
|
69
|
+
// ...(initial style creation + append if config.hiddenFooter would go in main routine)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Run MAIN routine
|
|
74
|
+
|
|
75
|
+
chatgpt.printAllFunctions() // to console
|
|
76
|
+
|
|
77
|
+
// CHILL a bit if your hacks depend on delayed DOM content
|
|
78
|
+
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
|
|
105
|
+
|
|
106
|
+
// Add STARS styles for modals
|
|
107
|
+
['black', 'white'].forEach(color => document.head.append(
|
|
108
|
+
dom.create.elem('link', { rel: 'stylesheet',
|
|
109
|
+
href: `https://assets.aiwebextensions.com/styles/css/${color}-rising-stars.min.css?v=542104c`
|
|
110
|
+
})))
|
|
111
|
+
|
|
112
|
+
if (config.extensionDisabled) return
|
|
113
|
+
|
|
114
|
+
if (!config.skipAlert) // alert to extension load
|
|
115
|
+
chatgpt.alert('≫ ChatGPT extension loaded! 🚀', // title
|
|
116
|
+
'Success! Press Ctrl+Shift+J to view all chatgpt.js methods.', // msg
|
|
117
|
+
function getHelp() { // button
|
|
118
|
+
chrome.tabs.create({ url: `${app.urls.gitHub}/issues` }) },
|
|
119
|
+
function dontShowAgain() { // checkbox
|
|
120
|
+
settings.save('skipAlert', !config.skipAlert) }
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
// Your code here...
|
|
124
|
+
// Your code here...
|
|
125
|
+
// Your code here...
|
|
126
|
+
// Your code here...
|
|
127
|
+
// Your code here...
|
|
128
|
+
// Your code here...
|
|
129
|
+
// Your code here...
|
|
130
|
+
// Your code here...
|
|
131
|
+
// Your code here...
|
|
132
|
+
// Your code here...
|
|
133
|
+
// Your code here...
|
|
134
|
+
// Your code here...
|
|
61
135
|
|
|
62
|
-
})()
|
|
136
|
+
})()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|