Skip to content

Commit

Permalink
Connect tooltips, text insertion
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrl committed Dec 6, 2023
1 parent 4da9919 commit bb164a8
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 26 deletions.
38 changes: 28 additions & 10 deletions src/components/FillSelector.svelte
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
<script lang="ts">
import type {PersonalInfo, Talk} from "../storage";
import {getTalkName, publicKeysOnly} from '../tools/helpers.js'
import {getTalkName, publicKeysOnly, simulateInput} from '../tools/helpers'
import type {FocusableTarget} from '../tools/helpers'
import Button from "./ui/Button.svelte";
import Accordion from "./ui/Accordion.svelte";
import type {Writable} from "svelte/store";
export let activeTalk: Talk;
export let personalInfo: PersonalInfo;
export let activeInput: Writable<FocusableTarget>
let inputRef: FocusableTarget
let unusedTalkFields: string[] = Object.keys(activeTalk).filter(publicKeysOnly)
let usedTalkFields: string[] = []
let unusedPersonalFields: string[] = Object.keys(personalInfo)
let usedPersonalFields: string[] = []
activeInput.subscribe((value) => {
inputRef = value
});
const onClick = (key: string, personal = false) => {
const dataSource = personal ? personalInfo : activeTalk
simulateInput(inputRef, dataSource[key])
if (!personal) {
unusedTalkFields = [...unusedTalkFields.filter((field) => field !== key)]
usedTalkFields = [...usedTalkFields, key]
Expand All @@ -25,6 +36,11 @@
}
}
const onClickUsed = (key: string, personal = false) => {
const dataSource = personal ? personalInfo : activeTalk
simulateInput(inputRef, dataSource[key])
}
</script>

<section class="container">
Expand All @@ -38,15 +54,17 @@
<Button label={unusedField} on:click={() => onClick(unusedField)} />
{/each}
<hr/>
<Accordion label="Show used">
{#each usedPersonalFields as usedField}
<Button label={usedField} />
{/each}
<hr/>
{#each usedTalkFields as usedField}
<Button label={usedField} />
{/each}
</Accordion>
{#if usedPersonalFields.length > 0 || usedTalkFields.length > 0}
<Accordion label="Show used">
{#each usedPersonalFields as usedField}
<Button label={usedField} on:click={() => onClickUsed(usedField, true)} />
{/each}
<hr/>
{#each usedTalkFields as usedField}
<Button label={usedField} on:click={() => onClickUsed(usedField)} />
{/each}
</Accordion>
{/if}

</section>

Expand Down
3 changes: 3 additions & 0 deletions src/components/ui/TalkView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
.talk {
display: flex;
flex-direction: column;
box-shadow: 0px 3px 17px 0px #0000002b;
padding: 0.3rem;
border-radius: 3px;
}
.talk p {
white-space: pre-line;
Expand Down
60 changes: 45 additions & 15 deletions src/content/index.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,66 @@
import FillSelector from "../components/FillSelector.svelte";
import type {PersonalInfo, Talk} from "../storage";
import { createPopper } from '@popperjs/core';
import { writable } from 'svelte/store';

// Content scripts
// https://developer.chrome.com/docs/extensions/mv3/content_scripts/

// Some global styles on the page
import "./styles.css";
import {isElementVisible} from "../tools/helpers";

const createTooltip = () => {
const tooltip = document.createElement('div')
const container = document.createElement('div')
const target = document.createElement('div')
tooltip.id = 'sfp-tooltip'
tooltip.innerHTML = `<div class="sfp-tooltip-arrow" data-popper-arrow></div>`
tooltip.append(container)
document.body.prepend(tooltip)
tooltip.append(target)
document.body.append(tooltip)
return { tooltip, target }
}

return container
const drawTooltip = (target: Element, content: HTMLElement) => {
createPopper(target, content, {
placement: 'left',
modifiers: [
{
name: 'offset',
options: {
offset: [0, 10],
},
},
],
});
}

const init = async () => {
await chrome.runtime.sendMessage({ requestTalk: 'please' });
chrome.runtime.onMessage.addListener(
async function(request: { targetTalk: Talk, personalInfo: PersonalInfo }, sender, sendResponse) {
const { targetTalk, personalInfo } = request
console.log('Initiating submission process with the following data: ', { targetTalk, personalInfo })
const onStart = async (request: { targetTalk: Talk, personalInfo: PersonalInfo }) => {
const { targetTalk, personalInfo } = request
console.log('Initiating submission process with the following data: ', { targetTalk, personalInfo })

// @TODO: apply more sophisticated form detection method
const formInputs = document.querySelectorAll('input, textarea')
const visibleInputs = Array.from(formInputs).filter(isElementVisible)

const activeInput = writable(visibleInputs[0])

const { target, tooltip } = createTooltip()
new FillSelector({ target, props: { activeTalk: targetTalk, personalInfo, activeInput } })

const target = createTooltip()
new FillSelector({ target, props: { activeTalk: targetTalk, personalInfo } })

// @TODO this is where we inject popper
}
);
drawTooltip(visibleInputs[0], tooltip)

visibleInputs.forEach(input => {
input.addEventListener('focus', () => {
activeInput.set(input)
drawTooltip(input, tooltip)
})
})
}

const init = async () => {
await chrome.runtime.sendMessage({ requestTalk: 'please' });
chrome.runtime.onMessage.addListener(onStart);
}

console.log('I have arrived!')
Expand Down
19 changes: 18 additions & 1 deletion src/tools/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
import type {Talk} from "../storage";

export type FocusableTarget = HTMLTextAreaElement | HTMLInputElement

export const HIDDEN_KEYS = ['id', '__revision'];

export const getTalkName = (talk: Talk) => {
return talk.title || talk.Title || talk.id;
}

export const publicKeysOnly = (key: string) => !HIDDEN_KEYS.includes(key);
export const publicKeysOnly = (key: string) => !HIDDEN_KEYS.includes(key);

export const isElementVisible = (el: Element) => {
const style = window.getComputedStyle(el);
return !((style.display === 'none') || (style.visibility === 'hidden'))
}

export const simulateInput = (element: FocusableTarget, text: string) => {
element.focus()
element.select()
try {
document.execCommand("insertText", false, text)
} catch (e) {
console.error("is document.execCommand already disabled in your browser? Tough luck.", e);
}
}

0 comments on commit bb164a8

Please sign in to comment.