Skip to content

Instantly share code, notes, and snippets.

@luccabb
Created April 15, 2024 07:52
Show Gist options
  • Save luccabb/31d6ba45766ab385770dc8e392716dbc to your computer and use it in GitHub Desktop.
Save luccabb/31d6ba45766ab385770dc8e392716dbc to your computer and use it in GitHub Desktop.
(() => {
"use strict";
var t = {
79: (t, e) => {
const n = ["#docs-editor-container"],
o = ["#docs-editor", ...n],
r = ["iframe.docs-texteventtarget-iframe", ".docs-texteventtarget-iframe"],
i = [".kix-page", ".docs-page"],
s = [".kix-lineview", ".kix-paragraphrenderer"],
c = [".kix-lineview-text-block"],
a = [".kix-wordhtmlgenerator-word-node"],
l = [".kix-selection-overlay"],
u = [".kix-cursor"],
d = [".docs-text-ui-cursor-blink"],
f = [".kix-cursor-caret"];
function h(t, e = document) {
if (null == e) throw new Error("Passed root element does not exists");
let n = null;
for (const o of t)
if (n = e.querySelector(o), n) break;
return n
}
function p(t, e = document) {
if (null == e) throw new Error("Passed root element does not exists");
let n = null;
for (const o of t)
if (n = e.querySelectorAll(o), n.length > 0) break;
return n ? Array.from(n) : []
}
function m() {
return h(o)
}
function y(t, e) {
const n = document.createElement("span");
n.textContent = t, n.style.cssText = e, n.style.whiteSpace = "pre", n.style.position = "absolute", n.style.top = "-100px", document.body.appendChild(n);
const o = n.getBoundingClientRect();
return n.remove(), o
}
function g() {
const t = h(r);
return function(t) {
return "iframe" === t.nodeName.toLowerCase()
}(t) ? t.contentDocument : t
}
function w() {
const t = m();
return p(i, t)
}
function v() {
const t = w();
let e = [];
for (const n of t) {
const t = p(s, n);
e = [...e, ...t]
}
return e
}
function x() {
const t = v(),
e = [];
for (const n of t) {
const t = h(c, n);
e.push(t)
}
return e
}
function K(t) {
return function(t) {
return t.replace(/\u00A0/g, "")
}(t = t.replace(/\u200C/g, ""))
}
function E() {
const t = x(),
e = [];
for (const n of t) {
let t = n.textContent;
t = K(t), t = b(t), e.push(t)
}
return e
}
function b(t) {
return t.trim()
}
function A() {
const t = v(),
e = [];
for (const n of t) {
const t = p(a, n);
e.push(t)
}
return e
}
function C() {
const t = v(),
e = [];
for (const n of t) {
const t = h(l, n);
e.push(t)
}
return e
}
function P(t, e, n, o) {
let r = n.left,
i = !1,
s = 0,
c = t.length;
for (let n = 0; n !== t.length; n++) {
if (o.left <= r && r < o.right) i || (s = n, i = !0);
else if (i) {
c = n;
break
}
r += y(t[n], e)
.width
}
return i ? {
start: s,
end: c
} : null
}
function L() {
const t = m();
return h(u, t)
}
function k() {
const t = m();
return h(d, t)
}
function S() {
const t = L();
return t ? h(f, t) : null
}
function R() {
const t = S();
if (!t) return null;
const e = A();
if (!e.length) return null;
const n = t.getBoundingClientRect(),
o = {
element: null,
wordElement: null,
lineIndex: null,
positionIndexRelativeToWord: null
};
let r = !1;
for (let c = 0; c !== e.length; c++) {
const a = e[c];
for (let e = 0; e !== a.length; e++) {
const l = a[e],
u = l.getBoundingClientRect();
if (s = u, (i = n)
.left <= s.right && i.right >= s.left && i.top <= s.bottom && i.bottom >= s.top) {
o.element = t, o.wordElement = l, o.lineIndex = c, o.positionIndexRelativeToWord = D(u, n, l.textContent, l.style.cssText), r = !0;
break
}
}
if (r) break
}
var i, s;
return o
}
function D(t, e, n, o) {
let r = t.left - e.width,
i = 0;
for (const t of n) {
const n = y(t, o);
if (0 !== n.width) {
if (r += n.width, r >= e.left) break;
i += 1
}
}
return i
}
function I(t, e, n) {
let o, r, i;
n ? (o = t => t <= 0, r = t => t - 1, i = t => t + 1) : (o = t => t >= e.length, r = t => t + 1, i = t => t - 1);
let s = t,
c = e[s];
if (n && T(c) && !o(s) && (s = r(s), c = e[s], T(c))) return t;
for (; !T(c) && !o(s);) s = r(s), c = e[s];
return n && !o(s) && (s = i(s)), s
}
function T(t) {
return null == t || !((e = t)
.match(/[\w]/) || e.toLowerCase() !== e.toUpperCase());
var e
}
function M(t, e, n, o, r, i) {
return null == o && (o = "Key" + n.toUpperCase()), null == r && (r = n.codePointAt(0)), new KeyboardEvent(t, {
repeat: !1,
isComposing: !1,
bubbles: !0,
cancelable: !0,
ctrlKey: !1,
shiftKey: !1,
altKey: !1,
metaKey: !1,
target: e,
currentTarget: e,
key: n,
code: o,
keyCode: r,
charCode: r,
which: r,
...i
})
}
function N(t, e, n = null, o = null, r = {}) {
const i = M("keypress", t, e, n, o, r);
t.dispatchEvent(i)
}
function B(t, e, n = null, o = null, r = {}) {
const i = M("keydown", t, e, n, o, r);
t.dispatchEvent(i)
}
function _(t, {
ctrlKey: e = !1,
shiftKey: n = !1
} = {}) {
e || n ? B(g(), t, null, null, {
ctrlKey: e,
shiftKey: n
}) : N(g(), t)
}
function O({
ctrlKey: t = !1
} = {}) {
B(g(), "Backspace", "Backspace", 8, {
ctrlKey: t
})
}
function H({
ctrlKey: t = !1,
shiftKey: e = !1
} = {}) {
B(g(), "End", "End", 35, {
ctrlKey: t,
shiftKey: e
})
}
function W({
ctrlKey: t = !1,
shiftKey: e = !1
} = {}) {
B(g(), "Home", "Home", 36, {
ctrlKey: t,
shiftKey: e
})
}
function F({
ctrlKey: t = !1,
shiftKey: e = !1
} = {}) {
B(g(), "ArrowLeft", "ArrowLeft", 37, {
ctrlKey: t,
shiftKey: e
})
}
function U({
ctrlKey: t = !1,
shiftKey: e = !1
} = {}) {
B(g(), "ArrowUp", "ArrowUp", 38, {
ctrlKey: t,
shiftKey: e
})
}
function q({
ctrlKey: t = !1,
shiftKey: e = !1
} = {}) {
B(g(), "ArrowRight", "ArrowRight", 39, {
ctrlKey: t,
shiftKey: e
})
}
function j({
ctrlKey: t = !1,
shiftKey: e = !1
} = {}) {
B(g(), "ArrowDown", "ArrowDown", 40, {
ctrlKey: t,
shiftKey: e
})
}
function z({
ctrlKey: t = !1
} = {}) {
B(g(), "Delete", "Delete", 46, {
ctrlKey: t
})
}
function V() {
_("z", {
ctrlKey: !0
})
}
var $ = Object.freeze({
__proto__: null,
Character: _,
Backspace: O,
Tab: function() {
B(g(), "Tab", "Tab", 9)
},
Enter: function() {
B(g(), "Enter", "Enter", 13)
},
Space: function() {
N(g(), " ", "Space", 32)
},
End: H,
Home: W,
ArrowLeft: F,
ArrowUp: U,
ArrowRight: q,
ArrowDown: j,
Delete: z,
Undo: V,
Redo: function() {
_("y", {
ctrlKey: !0
})
},
PrintDialog: function() {
_("p", {
ctrlKey: !0
})
},
Bold: function() {
_("b", {
ctrlKey: !0
})
},
Italic: function() {
_("i", {
ctrlKey: !0
})
},
Underline: function() {
_("u", {
ctrlKey: !0
})
}
});
function G() {
return C()
.some((t => !!t))
}
function J() {
return !!k()
}
function Q() {
if (J()) return !1;
const t = G();
return _("?"), t ? V() : O(), !0
}
var X = Object.freeze({
__proto__: null,
PrevCharacter: function() {
F()
},
NextCharacter: function() {
q()
},
PrevLine: function() {
U()
},
NextLine: function() {
j()
},
PrevWord: function() {
F({
ctrlKey: !0
})
},
NextWord: function() {
q({
ctrlKey: !0
})
},
PrevParagraph: function() {
U({
ctrlKey: !0
})
},
NextParagraph: function() {
j({
ctrlKey: !0
})
},
LineStart: function() {
Q(), W()
},
LineEnd: function() {
Q(), H()
},
DocumentStart: function() {
W({
ctrlKey: !0
})
},
DocumentEnd: function() {
H({
ctrlKey: !0
})
}
}),
Y = Object.freeze({
__proto__: null,
PrevWord: function() {
O({
ctrlKey: !0
})
},
NextWord: function() {
z({
ctrlKey: !0
})
},
Selection: function() {
return !!G() && (z(), !0)
}
}),
Z = Object.freeze({
__proto__: null,
All: function() {
_("a", {
ctrlKey: !0
})
},
PrevCharacter: function() {
F({
shiftKey: !0
})
},
NextCharacter: function() {
q({
shiftKey: !0
})
},
PrevWord: function() {
F({
shiftKey: !0,
ctrlKey: !0
})
},
NextWord: function() {
q({
shiftKey: !0,
ctrlKey: !0
})
},
PrevLine: function() {
Q(), U({
shiftKey: !0
})
},
NextLine: function() {
Q(), j({
shiftKey: !0
})
},
PrevParagraph: function() {
U({
shiftKey: !0,
ctrlKey: !0
})
},
NextParagraph: function() {
j({
shiftKey: !0,
ctrlKey: !0
})
},
TextBetweenCursorAndLineStart: function() {
Q(), W({
shiftKey: !0
})
},
TextBetweenCursorAndLineEnd: function() {
Q(), H({
shiftKey: !0
})
},
TextBetweenCursorAndDocumentStart: function() {
W({
shiftKey: !0,
ctrlKey: !0
})
},
TextBetweenCursorAndDocumentEnd: function() {
H({
shiftKey: !0,
ctrlKey: !0
})
}
});
const tt = {},
et = function(t) {
const e = [];
for (let n of t) {
n.startsWith(".") || (n = n.slice(n.indexOf("."))), n = n.slice(1);
const t = n.split(".");
for (const n of t) n && e.push(n)
}
return e
}(l);
function nt(t) {
let e = !1;
for (const n of t) {
for (const t of n.addedNodes) {
const n = Array.from(t.classList || []);
e = e || et.some((t => n.includes(t)))
}
for (const t of n.removedNodes) {
const n = Array.from(t.classList || []);
e = e || et.some((t => n.includes(t)))
}
}
e && function(t) {
const e = tt[t];
if (e)
for (const n of e) try {
n({
type: t
})
} catch (t) {
console.error(t)
}
}("selectionchange")
}! function(t) {
const e = () => {
t()
};
"loading" === document.readyState ? document.addEventListener("DOMContentLoaded", e) : e()
}((function() {
const t = h(n);
if (null == t) throw new Error("Unable to observe missing docsEditorContainer");
new MutationObserver(nt)
.observe(t, {
subtree: !0,
childList: !0,
attributes: !1,
characterData: !1
})
})), e.pressOn = $, e.typeText = function(t) {
! function(t) {
for (const e of t) _(e)
}(t)
}
},
774: (t, e, n) => {
t.exports = n(79)
}
},
e = {};
function n(o) {
var r = e[o];
if (void 0 !== r) return r.exports;
var i = e[o] = {
exports: {}
};
return t[o](i, i.exports, n), i.exports
}(() => {
const t = async t => new Promise((e => {
chrome.storage.sync.get("excludeList", (n => {
let o = n.excludeList || [];
e(o.includes(t))
}))
})), e = t => {
try {
return new URL(t)
?.host ?? ""
} catch (t) {
return console.log("Something went wrong", t), ""
}
};
var o = n(774);
(() => {
const n = e(window.location.href);
chrome.runtime.onMessage.addListener(((t, e, o) => ("getHostByTabId" === t && o({
host: n
}), !0))), window.addEventListener("load", (async function() {
await t(n) ? window.dispatchEvent(new CustomEvent("unloadScript")) : window.dispatchEvent(new CustomEvent("loadScript"))
})), chrome.storage.onChanged.addListener(((t, e) => {
"sync" === e && t.excludeList && (t.excludeList.newValue.includes(n) ? window.dispatchEvent(new CustomEvent("unloadScript")) : window.dispatchEvent(new CustomEvent("loadScript")))
}))
})();
const r = new class {
constructor(t, e = 5) {
this.textContainer = document.querySelector(".docs-texteventtarget-iframe")
.contentDocument.activeElement, this.gEditor = document.querySelector("#docs-editor"), this.pattern = t, this.deleteSpeed = e, this.handleKeyDown = this.handleKeyDown.bind(this)
}
activate() {
this.textContainer.addEventListener("keydown", this.handleKeyDown)
}
deactivate() {
this.textContainer.removeEventListener("keydown", this.handleKeyDown)
}
async handleKeyDown(t) {
if (this.initAuthOnPatternTyped(t), "Enter" === t.key) {
const e = document.querySelector("#kix-current-user-cursor-caret")
.getBoundingClientRect(),
n = Math.floor(e.right),
r = Math.floor(e.top),
i = this.getRect(n, r),
{
patternFound: s,
prompt: c
} = this.extractPrompt(i, n, r, this.pattern);
if (s) {
t.preventDefault(), t.stopPropagation(), console.log(c), this.initFetchingResponseFromApi(c);
let e = c.length + this.pattern.length;
for (; e > 0;) o.pressOn.Backspace({
ctrlKey: !1
}), e--, await new Promise((t => setTimeout(t, this.deleteSpeed)));
await this.getResponseFromBgAndInsert(t.target)
}
}
}
initAuthOnPatternTyped(t) {
this.pattern.startsWith(this.typedPattern + t.key) ? (this.typedPattern += t.key, this.typedPattern === this.pattern && (console.log("********Pattern detected!**********"), this.initAuthenticationProcess(), this.typedPattern = "")) : this.typedPattern = ""
}
async initAuthenticationProcess() {
return console.log("1. Init Authentication Process"), new Promise(((t, e) => {
this.port = chrome.runtime.connect({
name: "contentScript"
}), this.authenticationInProgress = !0, this.port.postMessage({
msg: "initAuthentication"
}), this.port.onMessage.addListener((e => {
"authenticated" === e.msg && !0 === e.status && (console.log("2. Authenticated"), this.authenticated = !0, t(!0))
}))
}))
}
async initFetchingResponseFromApi(t) {
this.authenticated || (this.authenticationInProgress ? (console.log("Authentication in progress. Waiting for a maximum of 10 secs..."), await new Promise(((t, e) => {
let n = 0;
const o = setInterval((() => {
n += 1e3, this.authenticated ? (clearInterval(o), t()) : n >= 1e4 && (clearInterval(o), e(new Error("Authentication timeout")))
}), 1e3)
}))) : (console.log("Start a new authentication"), this.authenticated = await this.initAuthenticationProcess())), console.log("3. Init fetching response"), this.port.postMessage({
msg: "fetchResponse",
prompt: t
}), this.authenticated = !1, this.authenticationInProgress = !1
}
async getResponseFromBgAndInsert(t) {
console.log("hereee");
console.log("o", o);
console.log("open gdocs and type '>> write about x' then press enter or return; observe 'test text' gets written");
(0, o.typeText)("test text")
// this.port.postMessage({
// msg: "startStreaming"
// }), this.isLoading(!0), this.lockMouse(!0), this.messageListener = async t => {
// console.log("hereee");
// "streamData" === t.msg ? (0, o.typeText)(t.data) : "streamEnd" === t.msg && (this.isLoading(!1), this.lockMouse(!1), this.port.onMessage.removeListener(this.messageListener))
// }, this.port.onMessage.addListener(this.messageListener)
}
getRect(t, e) {
if (!this.styleElement) {
this.styleElement = document.createElement("style"), this.styleElement.id = "enable-pointer-events-on-rect", this.styleElement.textContent = [".kix-canvas-tile-content{pointer-events:none!important;}", "#kix-current-user-cursor-caret{pointer-events:none!important;}", ".kix-canvas-tile-content svg>g>rect{pointer-events:all!important; stroke-width:7px !important;}"].join("\n");
const t = document.head || document.documentElement;
null !== t && t.appendChild(this.styleElement)
}
this.styleElement.disabled = !1;
const n = document.elementFromPoint(t, e);
return this.styleElement.disabled = !0, n
}
getCaretIndex(t, e, n) {
const o = t.getAttribute("aria-label"),
r = document.createTextNode(o),
i = this.createTextOverlay(t, o, r);
if (!o || !i || !r) return null;
let s = document.createRange(),
c = 0,
a = r.nodeValue.length;
for (; a - c > 1;) {
const t = Math.floor((c + a) / 2);
s.setStart(r, t), s.setEnd(r, a);
const o = s.getClientRects();
this.isPointInAnyRect(e, n, o) ? c = t : e > s.getClientRects()[0].right ? c = a : a = t
}
const l = c;
return i.remove(), l
}
extractPrompt(t, e, n, o, r = !0) {
let i = t,
s = "",
c = !1;
for (; i && "rect" === i.tagName;) {
const t = i.getAttribute("aria-label"),
a = t.indexOf(o);
if (a >= 0) {
if (r) {
const r = this.getCaretIndex(i, e, n);
s = t.substring(a + o.length, r)
} else s = t.substring(a + o.length) + " " + s;
c = !0;
break
}
if (r) {
const o = this.getCaretIndex(i, e, n);
s = t.substring(0, o) + s, r = !1
} else s = t + " " + s;
i = i.previousElementSibling
}
if (!c) {
const i = t.parentNode.previousElementSibling;
if (i && "g" === i.tagName) {
const t = this.extractPrompt(i.lastElementChild, e, n, o, r);
t.prompt && (s = t.prompt + (s ? "\n" + s : ""), c = t.patternFound)
}
}
return {
patternFound: c,
prompt: s
}
}
isLoading(t) {
if (t) {
console.log("Added loading effect");
const t = document.querySelector("#ChromeExtAiAnytime") || document.head.appendChild(document.createElement("style"));
t.id = "ChromeExtAiAnytime", t.textContent = "*{cursor:progress !important;}"
} else {
console.log("Removed loading effect");
const t = document.querySelector("#ChromeExtAiAnytime");
t && t.remove()
}
}
mouseHandler(t) {
t.preventDefault(), t.stopPropagation()
}
lockMouse(t) {
t ? (this.gEditor.addEventListener("mousemove", this.mouseHandler, {
capture: !0
}), this.gEditor.addEventListener("mousedown", this.mouseHandler, {
capture: !0
}), this.gEditor.addEventListener("mouseup", this.mouseHandler, {
capture: !0
}), this.gEditor.addEventListener("click", this.mouseHandler, {
capture: !0
}), console.log("mouse locked")) : (this.gEditor.removeEventListener("mousemove", this.mouseHandler, {
capture: !0
}), this.gEditor.removeEventListener("mousedown", this.mouseHandler, {
capture: !0
}), this.gEditor.removeEventListener("mouseup", this.mouseHandler, {
capture: !0
}), this.gEditor.removeEventListener("click", this.mouseHandler, {
capture: !0
}), console.log("mouse unlocked"))
}
createTextOverlay(t, e, n) {
if (!t || "rect" !== t.tagName) return {};
const o = document.createElementNS("http://www.w3.org/2000/svg", "text"),
r = t.getAttribute("transform") || "",
i = t.getAttribute("data-font-css") || "";
o.setAttribute("x", t.getAttribute("x")), o.setAttribute("y", t.getAttribute("y")), o.appendChild(n), o.style.setProperty("all", "initial", "important"), o.style.setProperty("transform", r, "important"), o.style.setProperty("font", i, "important"), o.style.setProperty("text-anchor", "start", "important"), t.parentNode.appendChild(o);
const s = t.getBoundingClientRect(),
c = o.getBoundingClientRect(),
a = .5 * (s.top - c.top + (s.bottom - c.bottom));
return o.style.setProperty("transform", `translate(0px,${a}px) ${r}`, "important"), o
}
isPointInAnyRect(t, e, n) {
for (const o of n)
if (t >= Math.floor(o.left) && t <= Math.floor(o.right) && e >= Math.floor(o.top) && e <= Math.floor(o.bottom)) return !0;
return !1
}
}(">>", 5);
window.addEventListener("loadScript", (() => {
r.activate()
})), window.addEventListener("unloadScript", (() => {
r.deactivate()
}))
})()
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment