Skip to content

Commit

Permalink
Moved tooltip methods/routines/div to lib/tooltip.js ↞ [auto-sync from
Browse files Browse the repository at this point in the history
  • Loading branch information
kudo-sync-bot committed Feb 9, 2025
1 parent 8bc2b38 commit 1a9398c
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 108 deletions.
18 changes: 9 additions & 9 deletions chromium/extension/components/buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ window.buttons = {
},

imports: {
import(deps) { // { app, chatbar, env, sites, toggle, tooltipDiv, tweaksStyle }
import(deps) { // { app, chatbar, env, sites, toggle, tooltip, tweaksStyle }
for (const depName in deps) this[depName] = deps[depName] }
},

Expand Down Expand Up @@ -76,7 +76,7 @@ window.buttons = {

validBtnTypes.forEach(async (btnType, idx) => {
const btn = this[btnType] = dom.create.elem('div')
btn.id = `${btnType}-btn` // for toggle.tooltip()
btn.id = `${btnType}-btn` // for tooltip.toggle()
btn.className = this.class // for update.style.tweaks()
Object.assign(btn.style, {
position: this.imports.env.hasTallChatbar ? 'absolute' : 'relative', cursor: 'pointer',
Expand All @@ -95,20 +95,20 @@ window.buttons = {
}

// Add hover/click listeners
btn.onmouseover = btn.onmouseout = this.imports.toggle.tooltip
btn.onmouseover = btn.onmouseout = this.imports.tooltip.toggle
btn.onclick = () => {
if (btnType == 'newChat') {
document.querySelector(this.imports.sites[this.imports.env.site].selectors.btns.newChat)?.click()
this.imports.tooltipDiv.style.opacity = 0
this.imports.tooltip.div.style.opacity = 0
} else { // toggle mode
this.imports.toggle.mode(btnType)
if (btnType == 'fullWindow' // disable right btn tooltips on Perplexity homepage to avoid v-flicker
&& this.imports.env.site == 'perplexity' && location.pathname == '/') {
this.imports.tooltipDiv.style.opacity = 0;
this.imports.tooltip.div.style.opacity = 0;
['fullWindow', 'fullScreen'].forEach(btnType => {
const btn = this[btnType]
btn.onmouseover = btn.onmouseout = null
setTimeout(() => btn.onmouseover = btn.onmouseout = this.imports.toggle.tooltip, 300)
setTimeout(() => btn.onmouseover = btn.onmouseout = this.imports.tooltip.toggle, 300)
})
}
}
Expand All @@ -134,7 +134,7 @@ window.buttons = {
&& !(type == 'wideScreen' && chatgpt.canvasIsOpen()))
},

visible() { // used in update.tooltip() + chatbar.tweak() for horizontal math
visible() { // used in tooltip.update() + chatbar.tweak() for horizontal math
return this.valid().filter(type => !(type == 'newChat' && config.ncbDisabled)) }
},

Expand Down Expand Up @@ -163,14 +163,14 @@ window.buttons = {
this.state.hasFadedIn = true // ...so disable fade-in on subsequent .insert()s till .remove()
}
})
parentToInsertInto.insertBefore(this.imports.tooltipDiv, elemToInsertBefore) // add tooltips
parentToInsertInto.insertBefore(this.imports.tooltip.div, elemToInsertBefore) // add tooltips
setTimeout(() => this.imports.chatbar.tweak(), 1) ; this.update.color()
this.state.status = 'inserted'
},

remove() {
if (!this.imports.chatbar.get() || !document.getElementById('fullScreen-btn')) return
this.types.forEach(type => this[type]?.remove()) ; this.imports.tooltipDiv?.remove()
this.types.forEach(type => this[type]?.remove()) ; this.imports.tooltip.div?.remove()
this.state.status = 'missing' // ensure next .insert() doesn't return early
this.state.hasFadedIn = false // ensure next .insert() fades in buttons
},
Expand Down
52 changes: 52 additions & 0 deletions chromium/extension/components/tooltip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Requires dom.js + env.site + sites

window.tooltip = {

imports: {
import(deps) { // { site: env.site, sites }
for (const depName in deps) this[depName] = deps[depName] }
},

createDiv() { this.div = dom.create.elem('div', { class: 'cwm-tooltip' }) },

toggle(event) {
tooltip.update(event.currentTarget.id.replace(/-btn$/, ''))
tooltip.div.style.opacity = event.type == 'mouseover' ? 1 : 0
},

stylize() {
if (this.styles) return
this.styles = dom.create.style(`.cwm-tooltip {
background-color: rgba(0,0,0,0.71) ; padding: 5px 6px ; border-radius: 6px ; border: 1px solid #d9d9e3 ;
font-size: 0.85rem ; color: white ; white-space: nowrap ; /* text style */
--shadow: 4px 6px 16px 0 rgb(0 0 0 / 38%) ;
box-shadow: var(--shadow) ; -webkit-box-shadow: var(--shadow) ; -moz-box-shadow: var(--shadow) ;
position: absolute ; bottom: 58px ; opacity: 0 ; z-index: 9999 ; /* visibility */
transition: opacity 0.1s ; -webkit-transition: opacity 0.1s ; -moz-transition: opacity 0.1s ;
-ms-transition: opacity 0.1s ; -o-transition: opacity 0.1s ;
user-select: none ; webkit-user-select: none ; -moz-user-select: none ; -ms-user-select: none }`
)
document.head.append(this.styles)
},

async update(btnType) { // text & position
const site = this.imports.site, visibleBtnTypes = buttons.getTypes.visible()
const ctrAddend = (await buttons.getRightBtn()).getBoundingClientRect().width
+ ( site == 'perplexity' ? ( chatbar.is.tall() ? -1 : 8 )
: site == 'poe' ? 28 : 7 )
const spreadFactor = site == 'perplexity' ? 27.5 : site == 'poe' ? 28 : 31
const iniRoffset = spreadFactor * ( visibleBtnTypes.indexOf(btnType) +1 ) + ctrAddend
+ ( site == 'chatgpt' && chatbar.is.tall() ? -2 : 4 )
this.div.innerText = chrome.i18n.getMessage(`tooltip_${btnType}${
!/full|wide/i.test(btnType) ? '' : (config[btnType] ? 'OFF' : 'ON')}`)
this.div.style.right = `${ iniRoffset - this.div.getBoundingClientRect().width /2 }px` // x-pos
this.div.style.bottom = ( // y-pos
site == 'perplexity' ? (
location.pathname != '/' ? '64px' // not homepage
: document.querySelector( // logged-in homepage
this.imports.sites.perplexity.selectors.btns.settings) ? 'revert-layer'
: '50vh' // logged-out homepage
) : site == 'poe' ? '50px' : '59px'
)
}
};
51 changes: 7 additions & 44 deletions chromium/extension/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// Import JS resources
for (const resource of [
'lib/chatbar.js', 'lib/chatgpt.js', 'lib/dom.js', 'lib/settings.js',
'components/buttons.js', 'components/modals.js'
'components/buttons.js', 'components/modals.js', 'components/tooltip.js'
]) await import(chrome.runtime.getURL(resource))

// Init ENV context
Expand All @@ -26,6 +26,7 @@
dom.imports.import({ env }) // for env.ui.scheme
modals.imports.import({ app, env }) // for app data + env.ui.scheme
settings.imports.import({ env }) // to load/save active tab's settings using env.site
tooltip.imports.import({ site: env.site, sites }) // for tooltip.update() position logic

// Init SETTINGS
const firstRunKey = `${env.site}_isFirstRun`
Expand Down Expand Up @@ -113,18 +114,11 @@
err => console.error(app.symbol + ' » Failed to exit fullscreen', err))
}
}
},

tooltip(event) {
update.tooltip(event.currentTarget.id.replace(/-btn$/, ''))
tooltipDiv.style.opacity = event.type == 'mouseover' ? 1 : 0
}
}

// Export dependencies to BUTTONS
const tooltipDiv = dom.create.elem('div', { class: 'cwm-tooltip' }),
tweaksStyle = dom.create.style()
buttons.imports.import({ app, chatbar, env, sites, toggle, tooltipDiv, tweaksStyle })
const tweaksStyle = dom.create.style()
buttons.imports.import({ app, chatbar, env, sites, toggle, tooltip, tweaksStyle })

const update = {

Expand Down Expand Up @@ -182,26 +176,6 @@
+ '[class^=Message] { max-width: 100% !important }' ) // widen speech bubbles
: '' )
}
},

async tooltip(btnType) { // text & position
const visibleBtnTypes = buttons.getTypes.visible()
const ctrAddend = (await buttons.getRightBtn()).getBoundingClientRect().width
+ ( env.site == 'perplexity' ? ( chatbar.is.tall() ? -1 : 8 )
: env.site == 'poe' ? 28 : 7 )
const spreadFactor = env.site == 'perplexity' ? 27.5 : env.site == 'poe' ? 28 : 31
const iniRoffset = spreadFactor * ( visibleBtnTypes.indexOf(btnType) +1 ) + ctrAddend
+ ( env.site == 'chatgpt' && chatbar.is.tall() ? -2 : 4 )
tooltipDiv.innerText = chrome.i18n.getMessage(`tooltip_${btnType}${
!/full|wide/i.test(btnType) ? '' : (config[btnType] ? 'OFF' : 'ON')}`)
tooltipDiv.style.right = `${ iniRoffset - tooltipDiv.getBoundingClientRect().width /2 }px` // x-pos
tooltipDiv.style.bottom = ( // y-pos
env.site == 'perplexity' ? (
location.pathname != '/' ? '64px' // not homepage
: document.querySelector(sites.perplexity.selectors.btns.settings) ? 'revert-layer' // logged-in homepage
: '50vh' // logged-out homepage
) : env.site == 'poe' ? '50px' : '59px'
)
}
}

Expand Down Expand Up @@ -253,7 +227,7 @@
const state = ( mode == 'wideScreen' ? !!document.getElementById('wideScreen-mode')
: mode == 'fullWindow' ? isFullWin()
: chatgpt.isFullScreen() )
settings.save(mode, state) ; buttons.update.svg(mode) ; update.tooltip(mode)
settings.save(mode, state) ; buttons.update.svg(mode) ; tooltip.update(mode)
if (!config.extensionDisabled) { // tweak UI
if (mode == 'fullWindow') sync.fullerWin()
if (env.site == 'chatgpt') setTimeout(() => chatbar.tweak(), // update inner width
Expand Down Expand Up @@ -300,18 +274,6 @@
config.fullWindow = isFullWin() // ...so match it
else await settings.load('fullWindow') // otherwise load CWM's saved state

// Stylize TOOLTIP div
document.head.append(dom.create.style('.cwm-tooltip {'
+ 'background-color: rgba(0,0,0,0.71) ; padding: 5px 6px ; border-radius: 6px ; border: 1px solid #d9d9e3 ;'
+ 'font-size: 0.85rem ; color: white ; white-space: nowrap ;' // text style
+ `--shadow: 4px 6px 16px 0 rgb(0 0 0 / 38%) ;
box-shadow: var(--shadow) ; -webkit-box-shadow: var(--shadow) ; -moz-box-shadow: var(--shadow) ;`
+ 'position: absolute ; bottom: 58px ; opacity: 0 ; z-index: 9999 ;' // visibility
+ 'transition: opacity 0.1s ; -webkit-transition: opacity 0.1s ; -moz-transition: opacity 0.1s ;'
+ '-ms-transition: opacity 0.1s ; -o-transition: opacity 0.1s ;'
+ 'user-select: none ; webkit-user-select: none ; -moz-user-select: none ; -ms-user-select: none }'
))

// Apply general style TWEAKS
const tcbStyle = ( // heighten chatbox
env.site == 'chatgpt' ? `div[class*=prose]:has(${sites.chatgpt.selectors.input})`
Expand Down Expand Up @@ -345,7 +307,8 @@
const chatbarStyle = dom.create.style()
update.style.chatbar() ; document.head.append(chatbarStyle)

// Insert BUTTONS
// Insert BUTTONS/TOOLTIPS
tooltip.createDiv() ; tooltip.stylize()
if (!config.extensionDisabled) {
buttons.insert()

Expand Down
2 changes: 1 addition & 1 deletion chromium/extension/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"web_accessible_resources": [{
"matches": [ "<all_urls>" ],
"resources": [
"components/buttons.js", "components/modals.js",
"components/buttons.js", "components/modals.js", "components/tooltip.js",
"lib/chatbar.js", "lib/chatgpt.js", "lib/dom.js", "lib/settings.js"
]
}],
Expand Down
18 changes: 9 additions & 9 deletions firefox/extension/components/buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ window.buttons = {
},

imports: {
import(deps) { // { app, chatbar, env, sites, toggle, tooltipDiv, tweaksStyle }
import(deps) { // { app, chatbar, env, sites, toggle, tooltip, tweaksStyle }
for (const depName in deps) this[depName] = deps[depName] }
},

Expand Down Expand Up @@ -76,7 +76,7 @@ window.buttons = {

validBtnTypes.forEach(async (btnType, idx) => {
const btn = this[btnType] = dom.create.elem('div')
btn.id = `${btnType}-btn` // for toggle.tooltip()
btn.id = `${btnType}-btn` // for tooltip.toggle()
btn.className = this.class // for update.style.tweaks()
Object.assign(btn.style, {
position: this.imports.env.hasTallChatbar ? 'absolute' : 'relative', cursor: 'pointer',
Expand All @@ -95,20 +95,20 @@ window.buttons = {
}

// Add hover/click listeners
btn.onmouseover = btn.onmouseout = this.imports.toggle.tooltip
btn.onmouseover = btn.onmouseout = this.imports.tooltip.toggle
btn.onclick = () => {
if (btnType == 'newChat') {
document.querySelector(this.imports.sites[this.imports.env.site].selectors.btns.newChat)?.click()
this.imports.tooltipDiv.style.opacity = 0
this.imports.tooltip.div.style.opacity = 0
} else { // toggle mode
this.imports.toggle.mode(btnType)
if (btnType == 'fullWindow' // disable right btn tooltips on Perplexity homepage to avoid v-flicker
&& this.imports.env.site == 'perplexity' && location.pathname == '/') {
this.imports.tooltipDiv.style.opacity = 0;
this.imports.tooltip.div.style.opacity = 0;
['fullWindow', 'fullScreen'].forEach(btnType => {
const btn = this[btnType]
btn.onmouseover = btn.onmouseout = null
setTimeout(() => btn.onmouseover = btn.onmouseout = this.imports.toggle.tooltip, 300)
setTimeout(() => btn.onmouseover = btn.onmouseout = this.imports.tooltip.toggle, 300)
})
}
}
Expand All @@ -134,7 +134,7 @@ window.buttons = {
&& !(type == 'wideScreen' && chatgpt.canvasIsOpen()))
},

visible() { // used in update.tooltip() + chatbar.tweak() for horizontal math
visible() { // used in tooltip.update() + chatbar.tweak() for horizontal math
return this.valid().filter(type => !(type == 'newChat' && config.ncbDisabled)) }
},

Expand Down Expand Up @@ -163,14 +163,14 @@ window.buttons = {
this.state.hasFadedIn = true // ...so disable fade-in on subsequent .insert()s till .remove()
}
})
parentToInsertInto.insertBefore(this.imports.tooltipDiv, elemToInsertBefore) // add tooltips
parentToInsertInto.insertBefore(this.imports.tooltip.div, elemToInsertBefore) // add tooltips
setTimeout(() => this.imports.chatbar.tweak(), 1) ; this.update.color()
this.state.status = 'inserted'
},

remove() {
if (!this.imports.chatbar.get() || !document.getElementById('fullScreen-btn')) return
this.types.forEach(type => this[type]?.remove()) ; this.imports.tooltipDiv?.remove()
this.types.forEach(type => this[type]?.remove()) ; this.imports.tooltip.div?.remove()
this.state.status = 'missing' // ensure next .insert() doesn't return early
this.state.hasFadedIn = false // ensure next .insert() fades in buttons
},
Expand Down
52 changes: 52 additions & 0 deletions firefox/extension/components/tooltip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Requires dom.js + env.site + sites

window.tooltip = {

imports: {
import(deps) { // { site: env.site, sites }
for (const depName in deps) this[depName] = deps[depName] }
},

createDiv() { this.div = dom.create.elem('div', { class: 'cwm-tooltip' }) },

toggle(event) {
tooltip.update(event.currentTarget.id.replace(/-btn$/, ''))
tooltip.div.style.opacity = event.type == 'mouseover' ? 1 : 0
},

stylize() {
if (this.styles) return
this.styles = dom.create.style(`.cwm-tooltip {
background-color: rgba(0,0,0,0.71) ; padding: 5px 6px ; border-radius: 6px ; border: 1px solid #d9d9e3 ;
font-size: 0.85rem ; color: white ; white-space: nowrap ; /* text style */
--shadow: 4px 6px 16px 0 rgb(0 0 0 / 38%) ;
box-shadow: var(--shadow) ; -webkit-box-shadow: var(--shadow) ; -moz-box-shadow: var(--shadow) ;
position: absolute ; bottom: 58px ; opacity: 0 ; z-index: 9999 ; /* visibility */
transition: opacity 0.1s ; -webkit-transition: opacity 0.1s ; -moz-transition: opacity 0.1s ;
-ms-transition: opacity 0.1s ; -o-transition: opacity 0.1s ;
user-select: none ; webkit-user-select: none ; -moz-user-select: none ; -ms-user-select: none }`
)
document.head.append(this.styles)
},

async update(btnType) { // text & position
const site = this.imports.site, visibleBtnTypes = buttons.getTypes.visible()
const ctrAddend = (await buttons.getRightBtn()).getBoundingClientRect().width
+ ( site == 'perplexity' ? ( chatbar.is.tall() ? -1 : 8 )
: site == 'poe' ? 28 : 7 )
const spreadFactor = site == 'perplexity' ? 27.5 : site == 'poe' ? 28 : 31
const iniRoffset = spreadFactor * ( visibleBtnTypes.indexOf(btnType) +1 ) + ctrAddend
+ ( site == 'chatgpt' && chatbar.is.tall() ? -2 : 4 )
this.div.innerText = chrome.i18n.getMessage(`tooltip_${btnType}${
!/full|wide/i.test(btnType) ? '' : (config[btnType] ? 'OFF' : 'ON')}`)
this.div.style.right = `${ iniRoffset - this.div.getBoundingClientRect().width /2 }px` // x-pos
this.div.style.bottom = ( // y-pos
site == 'perplexity' ? (
location.pathname != '/' ? '64px' // not homepage
: document.querySelector( // logged-in homepage
this.imports.sites.perplexity.selectors.btns.settings) ? 'revert-layer'
: '50vh' // logged-out homepage
) : site == 'poe' ? '50px' : '59px'
)
}
};
Loading

0 comments on commit 1a9398c

Please sign in to comment.