From f13b2d2998e03c91f71c84dd553e662deea67e97 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Tue, 20 Jun 2023 22:00:37 -0700 Subject: [PATCH] Remove gecko extension and add back old scripts --- .../webview/injection/FrostJsInjectors.kt | 4 +- .../webview/injection/assets/JsAssets.kt | 2 +- .../src/web/assets/frostcore/manifest.json | 48 ------ app-compose/src/web/package.json | 4 +- .../src/web/ts/auto_resize_textarea.ts | 43 ++++++ app-compose/src/web/ts/background/cookies.ts | 44 ------ app-compose/src/web/ts/click_a.ts | 18 +-- app-compose/src/web/ts/click_debugger.ts | 15 ++ app-compose/src/web/ts/context_a.ts | 145 ++++++++++++++++++ app-compose/src/web/ts/document_watcher.ts | 27 ++++ app-compose/src/web/ts/frost.ts | 21 --- app-compose/src/web/ts/header_badges.ts | 7 + .../src/web/ts/horizontal_scrolling.ts | 61 ++++++++ app-compose/src/web/ts/media.ts | 47 ++++++ app-compose/src/web/ts/notif_msg.ts | 25 +++ app-compose/src/web/ts/scroll_stop.ts | 25 +++ app-compose/src/web/ts/textarea_listener.ts | 31 ++++ app-compose/src/web/tsconfig.json | 2 +- app-compose/src/web/typings/browser.d.ts | 7 - app-compose/src/web/typings/frost.d.ts | 40 +++-- 20 files changed, 471 insertions(+), 145 deletions(-) delete mode 100644 app-compose/src/web/assets/frostcore/manifest.json create mode 100644 app-compose/src/web/ts/auto_resize_textarea.ts delete mode 100644 app-compose/src/web/ts/background/cookies.ts create mode 100644 app-compose/src/web/ts/click_debugger.ts create mode 100644 app-compose/src/web/ts/context_a.ts create mode 100644 app-compose/src/web/ts/document_watcher.ts delete mode 100644 app-compose/src/web/ts/frost.ts create mode 100644 app-compose/src/web/ts/header_badges.ts create mode 100644 app-compose/src/web/ts/horizontal_scrolling.ts create mode 100644 app-compose/src/web/ts/media.ts create mode 100644 app-compose/src/web/ts/notif_msg.ts create mode 100644 app-compose/src/web/ts/scroll_stop.ts create mode 100644 app-compose/src/web/ts/textarea_listener.ts delete mode 100644 app-compose/src/web/typings/browser.d.ts diff --git a/app-compose/src/main/kotlin/com/pitchedapps/frost/webview/injection/FrostJsInjectors.kt b/app-compose/src/main/kotlin/com/pitchedapps/frost/webview/injection/FrostJsInjectors.kt index 77cb6c59e..0af5774b8 100644 --- a/app-compose/src/main/kotlin/com/pitchedapps/frost/webview/injection/FrostJsInjectors.kt +++ b/app-compose/src/main/kotlin/com/pitchedapps/frost/webview/injection/FrostJsInjectors.kt @@ -42,11 +42,11 @@ internal constructor( theme.inject(view) } - fun getTheme(): JsInjector { + private fun getTheme(): JsInjector { return try { val content = context.assets - .open("frostcore/css/facebook/themes/material_glass.css") + .open("frost/css/facebook/themes/material_glass.css") .bufferedReader() .use(BufferedReader::readText) JsBuilder().css(content).build() diff --git a/app-compose/src/main/kotlin/com/pitchedapps/frost/webview/injection/assets/JsAssets.kt b/app-compose/src/main/kotlin/com/pitchedapps/frost/webview/injection/assets/JsAssets.kt index 1515e4ab8..a911bbbcc 100644 --- a/app-compose/src/main/kotlin/com/pitchedapps/frost/webview/injection/assets/JsAssets.kt +++ b/app-compose/src/main/kotlin/com/pitchedapps/frost/webview/injection/assets/JsAssets.kt @@ -50,7 +50,7 @@ enum class JsAssets(private val singleLoad: Boolean = true) : JsInjector { private fun injectorBlocking(context: Context): JsInjector { return try { val content = - context.assets.open("frostcore/js/$file").bufferedReader().use(BufferedReader::readText) + context.assets.open("frost/js/$file").bufferedReader().use(BufferedReader::readText) JsBuilder().js(content).run { if (singleLoad) single(name) else this }.build() } catch (e: FileNotFoundException) { logger.atWarning().withCause(e).log("JsAssets file not found") diff --git a/app-compose/src/web/assets/frostcore/manifest.json b/app-compose/src/web/assets/frostcore/manifest.json deleted file mode 100644 index 0f5bd27aa..000000000 --- a/app-compose/src/web/assets/frostcore/manifest.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "manifest_version": 2, - "name": "frostcore", - "version": "1.0.0", - "description": "Core web extension for Frost", - "browser_specific_settings": { - "gecko": { - "id": "frost_gecko_core@pitchedapps" - } - }, - "background": { - "scripts": [ - "js/background/cookies.js" - ] - }, - "content_scripts": [ - { - "matches": [ - "" - ], - "js": [ - "js/frost.js" - ] - }, - { - "matches": [ - "*://*.facebook.com/*" - ], - "js": [ - "js/click_a.js" - ] - } - ], - "permissions": [ - "", - "activeTab", - "contextMenus", - "contextualIdentities", - "cookies", - "history", - "management", - "tabs", - "nativeMessaging", - "nativeMessagingFromContent", - "geckoViewAddons", - "webRequest" - ] -} \ No newline at end of file diff --git a/app-compose/src/web/package.json b/app-compose/src/web/package.json index 73ac90cfc..46f29bbc9 100644 --- a/app-compose/src/web/package.json +++ b/app-compose/src/web/package.json @@ -1,7 +1,7 @@ { "scripts": { - "compile": "tsc -p tsconfig.json && sass --no-source-map --style compressed --update scss:assets/frostcore/css", - "scss-watch": "sass --no-source-map --style compressed --update scss:assets/frostcore/css --watch" + "compile": "tsc -p tsconfig.json && sass --no-source-map --style compressed --update scss:assets/frost/css", + "scss-watch": "sass --no-source-map --style compressed --update scss:assets/frost/css --watch" }, "license": "MPL-2.0", "repository": { diff --git a/app-compose/src/web/ts/auto_resize_textarea.ts b/app-compose/src/web/ts/auto_resize_textarea.ts new file mode 100644 index 000000000..c71a75a1e --- /dev/null +++ b/app-compose/src/web/ts/auto_resize_textarea.ts @@ -0,0 +1,43 @@ +// Credits to https://codepen.io/tomhodgins/pen/KgazaE +(function () { + const classTag = 'frostAutoExpand'; + const textareas = >document.querySelectorAll(`textarea:not(.${classTag})`); + + const dataAttribute = 'data-frost-minHeight'; + + const _frostAutoExpand = (el: HTMLElement) => { + if (!el.hasAttribute(dataAttribute)) { + el.setAttribute(dataAttribute, el.offsetHeight.toString()); + } + // If no height is defined, have min bound to current height; + // otherwise we will allow for height decreases in case user deletes text + const minHeight = parseInt(el.getAttribute(dataAttribute) ?? '0'); + + // Save scroll position prior to height update + // See https://stackoverflow.com/a/18262927/4407321 + const scrollLeft = window.pageXOffset || + (document.documentElement || document.body.parentNode || document.body).scrollLeft; + const scrollTop = window.pageYOffset || + (document.documentElement || document.body.parentNode || document.body).scrollTop; + + el.style.height = 'inherit'; + el.style.height = `${Math.max(el.scrollHeight, minHeight)}px`; + + // Go to original scroll position + window.scrollTo(scrollLeft, scrollTop); + }; + function _frostExpandAll() { + textareas.forEach(_frostAutoExpand); + } + textareas.forEach(el => { + el.classList.add(classTag) + const __frostAutoExpand = () => { + _frostAutoExpand(el) + }; + el.addEventListener('paste', __frostAutoExpand) + el.addEventListener('input', __frostAutoExpand) + el.addEventListener('keyup', __frostAutoExpand) + }); + window.addEventListener('load', _frostExpandAll) + window.addEventListener('resize', _frostExpandAll) +}).call(undefined); diff --git a/app-compose/src/web/ts/background/cookies.ts b/app-compose/src/web/ts/background/cookies.ts deleted file mode 100644 index 5e1ee8b95..000000000 --- a/app-compose/src/web/ts/background/cookies.ts +++ /dev/null @@ -1,44 +0,0 @@ -async function updateCookies(changeInfo: browser.cookies._OnChangedChangeInfo) { - - const application = "frostBackgroundChannel" - - browser.runtime.sendNativeMessage(application, changeInfo) -} - -async function readCookies() { - const application = "frostBackgroundChannel" - - browser.runtime.sendNativeMessage(application, 'start cookie fetch') - - // Testing with domains or urls didn't work - const cookies = await browser.cookies.getAll({}); - - const cookies2 = await browser.cookies.getAll({ storeId: "firefox-container-frost-context-1" }) - - const cookieStores = await browser.cookies.getAllCookieStores(); - - browser.runtime.sendNativeMessage(application, { name: "cookies", data: cookies.length, stores: cookieStores.map((s) => s.id), data2: cookies2.length, data3: cookies.filter(s => s.storeId != 'firefox-default').length }) -} - -async function handleMessage(request: any, sender: browser.runtime.MessageSender, sendResponse: (response?: any) => void) { - browser.runtime.sendNativeMessage("frostBackgroundChannel", 'pre send') - - await new Promise(resolve => setTimeout(resolve, 1000)); - - browser.runtime.sendNativeMessage("frostBackgroundChannel", 'post send') - - sendResponse({ received: request, asdf: "asdf" }) -} - -// Reading cookies with storeId might not be fully supported on Android -// https://stackoverflow.com/q/76505000/4407321 -// Using manifest 3 stopped getAll from working -// Reading now always shows storeId as firefox-default -// Setting a cookie with a custom container does not seem to work - -// browser.cookies.onChanged.addListener(updateCookies); -// browser.tabs.onActivated.addListener(readCookies); -// browser.runtime.onStartup.addListener(readCookies); - -// browser.runtime.onMessage.addListener(handleMessage); - diff --git a/app-compose/src/web/ts/click_a.ts b/app-compose/src/web/ts/click_a.ts index ddf4e84c8..8a7cc48c6 100644 --- a/app-compose/src/web/ts/click_a.ts +++ b/app-compose/src/web/ts/click_a.ts @@ -1,7 +1,6 @@ -(async function () { +(function () { let prevented = false; - /** * Go up at most [depth] times, to retrieve a parent matching the provided predicate * If one is found, it is returned immediately. @@ -40,29 +39,29 @@ /** * Given event and target, return true if handled and false otherwise. */ - type EventHandler = (e: Event, target: HTMLElement) => Promise + type EventHandler = (e: Event, target: HTMLElement) => Boolean - const _frostGeneral: EventHandler = async (e, target) => { + const _frostGeneral: EventHandler = (e, target) => { // We now disable clicks for the main notification page if (document.getElementById("notifications_list")) { return false } const url = _parentUrl(target, 2); - return frost.loadUrl(url); + return Frost.loadUrl(url); }; - const _frostLaunchpadClick: EventHandler = async (e, target) => { + const _frostLaunchpadClick: EventHandler = (e, target) => { if (!_parentEl(target, 6, (el) => el.id === 'launchpad')) { return false } console.log('Clicked launchpad'); const url = _parentUrl(target, 5); - return frost.loadUrl(url); + return Frost.loadUrl(url); }; const handlers: EventHandler[] = [_frostLaunchpadClick, _frostGeneral]; - const _frostAClick = async (e: Event) => { + const _frostAClick = (e: Event) => { if (prevented) { console.log("Click intercept prevented"); return @@ -75,9 +74,8 @@ console.log("No element found"); return } - // TODO cannot use await here; copy logic over here for (const h of handlers) { - if (await h(e, target)) { + if (h(e, target)) { e.stopPropagation(); e.preventDefault(); return diff --git a/app-compose/src/web/ts/click_debugger.ts b/app-compose/src/web/ts/click_debugger.ts new file mode 100644 index 000000000..088271fa8 --- /dev/null +++ b/app-compose/src/web/ts/click_debugger.ts @@ -0,0 +1,15 @@ +// For desktop only + +(function () { + const _frostAContext = (e: Event) => { + // Commonality; check for valid target + const element = e.target || e.currentTarget || e.srcElement; + if (!(element instanceof Element)) { + console.log("No element found"); + return + } + console.log(`Clicked element ${element.tagName} ${element.className}`); + }; + + document.addEventListener('contextmenu', _frostAContext, true); +}).call(undefined); diff --git a/app-compose/src/web/ts/context_a.ts b/app-compose/src/web/ts/context_a.ts new file mode 100644 index 000000000..ad81279e6 --- /dev/null +++ b/app-compose/src/web/ts/context_a.ts @@ -0,0 +1,145 @@ +/** + * Context menu for links + * Largely mimics click_a.js + */ + +(function () { + let longClick = false; + + /** + * Go up at most [depth] times, to retrieve a parent matching the provided predicate + * If one is found, it is returned immediately. + * Otherwise, null is returned. + */ + function _parentEl(el: HTMLElement, depth: number, predicate: (el: HTMLElement) => boolean): HTMLElement | null { + for (let i = 0; i < depth + 1; i++) { + if (predicate(el)) { + return el + } + const parent = el.parentElement; + if (!parent) { + return null + } + el = parent + } + return null + } + + /** + * Given event and target, return true if handled and false otherwise. + */ + type EventHandler = (e: Event, target: HTMLElement) => Boolean + + const _frostCopyComment: EventHandler = (e, target) => { + if (!target.hasAttribute('data-commentid')) { + return false; + } + const text = target.innerText; + console.log(`Copy comment ${text}`); + Frost.contextMenu(null, text); + return true; + }; + + /** + * Posts should click a tag, with two parents up being div.story_body_container + */ + const _frostCopyPost: EventHandler = (e, target) => { + if (target.tagName !== 'A') { + return false; + } + const parent1 = target.parentElement; + if (!parent1 || parent1.tagName !== 'DIV') { + return false; + } + const parent2 = parent1.parentElement; + if (!parent2 || !parent2.classList.contains('story_body_container')) { + return false; + } + const url = target.getAttribute('href'); + const text = parent1.innerText; + console.log(`Copy post ${url} ${text}`); + Frost.contextMenu(url, text); + return true; + }; + + const _getImageStyleUrl = (el: Element): string | null => { + // Emojis and special characters may be images from a span + const img = el.querySelector("[style*=\"background-image: url(\"]:not(span)"); + if (!img) { + return null + } + return (window.getComputedStyle(img, null).backgroundImage).trim().slice(4, -1); + }; + + /** + * Opens image activity for posts with just one image + */ + const _frostImage: EventHandler = (e, target) => { + const element = _parentEl(target, 2, (el) => el.tagName === 'A'); + if (!element) { + return false; + } + const url = element.getAttribute('href'); + if (!url || url === '#') { + return false; + } + const text = (element.parentElement).innerText; + // Check if image item exists, first in children and then in parent + const imageUrl = _getImageStyleUrl(element) || _getImageStyleUrl(element.parentElement); + if (imageUrl) { + console.log(`Context image: ${imageUrl}`); + Frost.loadImage(imageUrl, text); + return true; + } + // Check if true img exists + const img = element.querySelector("img[src*=scontent]"); + if (img instanceof HTMLMediaElement) { + const imgUrl = img.src; + console.log(`Context img: ${imgUrl}`); + Frost.loadImage(imgUrl, text); + return true; + } + console.log(`Context content ${url} ${text}`); + Frost.contextMenu(url, text); + return true; + }; + + const handlers: EventHandler[] = [_frostImage, _frostCopyComment, _frostCopyPost]; + + const _frostAContext = (e: Event) => { + Frost.longClick(true); + longClick = true; + + /** + * Don't handle context events while scrolling + */ + if (Frost.isScrolling()) { + console.log("Skip from scrolling"); + return; + } + + /* + * Commonality; check for valid target + */ + const target = e.target || e.currentTarget || e.srcElement; + if (!(target instanceof HTMLElement)) { + console.log("No element found"); + return + } + for (const h of handlers) { + if (h(e, target)) { + e.stopPropagation(); + e.preventDefault(); + return + } + } + }; + + document.addEventListener('contextmenu', _frostAContext, true); + document.addEventListener('touchend', () => { + if (longClick) { + Frost.longClick(false); + longClick = false + } + }, true); +}).call(undefined); diff --git a/app-compose/src/web/ts/document_watcher.ts b/app-compose/src/web/ts/document_watcher.ts new file mode 100644 index 000000000..e671149c6 --- /dev/null +++ b/app-compose/src/web/ts/document_watcher.ts @@ -0,0 +1,27 @@ +// Emit key once half the viewport is covered +(function () { + const isReady = () => { + return document.body.scrollHeight > innerHeight + 100 + }; + + if (isReady()) { + console.log('Already ready'); + Frost.isReady(); + return + } + + console.log('Injected document watcher'); + + const observer = new MutationObserver(() => { + if (isReady()) { + observer.disconnect(); + Frost.isReady(); + console.log(`Documented surpassed height in ${performance.now()}`); + } + }); + + observer.observe(document, { + childList: true, + subtree: true + }) +}).call(undefined); diff --git a/app-compose/src/web/ts/frost.ts b/app-compose/src/web/ts/frost.ts deleted file mode 100644 index abf194f70..000000000 --- a/app-compose/src/web/ts/frost.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Mobile browsers don't support modules, so I'm creating a shared variable. - * - * No idea if this is good practice. - */ -const frost = (function () { - const application = "frostChannel" - - async function sendMessage(message: ExtensionModel): Promise { - return browser.runtime.sendNativeMessage(application, message) - } - - async function loadUrl(url: string | null): Promise { - if (url == null) return false - return sendMessage({ type: "url-click", url: url }) - } - - return { - sendMessage, loadUrl - } -}).call(undefined); \ No newline at end of file diff --git a/app-compose/src/web/ts/header_badges.ts b/app-compose/src/web/ts/header_badges.ts new file mode 100644 index 000000000..3f7588591 --- /dev/null +++ b/app-compose/src/web/ts/header_badges.ts @@ -0,0 +1,7 @@ +// Fetches the header contents if it exists +(function() { + const header = document.getElementById('header'); + if (header) { + Frost.handleHeader(header.outerHTML); + } +}).call(undefined); diff --git a/app-compose/src/web/ts/horizontal_scrolling.ts b/app-compose/src/web/ts/horizontal_scrolling.ts new file mode 100644 index 000000000..b104725eb --- /dev/null +++ b/app-compose/src/web/ts/horizontal_scrolling.ts @@ -0,0 +1,61 @@ +(function () { + + /** + * Go up at most [depth] times, to retrieve a parent matching the provided predicate + * If one is found, it is returned immediately. + * Otherwise, null is returned. + */ + function _parentEl(el: HTMLElement, depth: number, predicate: (el: HTMLElement) => boolean): HTMLElement | null { + for (let i = 0; i < depth + 1; i++) { + if (predicate(el)) { + return el + } + const parent = el.parentElement; + if (!parent) { + return null + } + el = parent + } + return null + } + + /** + * Check if element can scroll horizontally. + * We primarily rely on the overflow-x field. + * For performance reasons, we will check scrollWidth first to see if scrolling is a possibility + */ + function _canScrollHorizontally(el: HTMLElement): boolean { + /* + * Sometimes the offsetWidth is off by < 10px. We use the multiplier + * since the trays are typically more than 2 times greater + */ + if (el.scrollWidth > el.offsetWidth * 1.2) { + return true + } + const styles = window.getComputedStyle(el); + /* + * Works well in testing, but on mobile it just shows 'visible' + */ + return styles.overflowX === 'scroll'; + } + + const _frostCheckHorizontalScrolling = (e: Event) => { + const target = e.target || e.currentTarget || e.srcElement; + if (!(target instanceof HTMLElement)) { + return + } + const scrollable = _parentEl(target, 5, _canScrollHorizontally) !== null; + if (scrollable) { + console.log('Pause horizontal scrolling'); + Frost.allowHorizontalScrolling(false); + } + }; + + const _frostResetHorizontalScrolling = (e: Event) => { + Frost.allowHorizontalScrolling(true) + }; + + document.addEventListener('touchstart', _frostCheckHorizontalScrolling, true); + document.addEventListener('touchend', _frostResetHorizontalScrolling, true); +}).call(undefined); + diff --git a/app-compose/src/web/ts/media.ts b/app-compose/src/web/ts/media.ts new file mode 100644 index 000000000..5b9b1a54b --- /dev/null +++ b/app-compose/src/web/ts/media.ts @@ -0,0 +1,47 @@ +// Handles media events +(function () { + const _frostMediaClick = (e: Event) => { + const target = e.target || e.srcElement; + if (!(target instanceof HTMLElement)) { + return + } + let element: HTMLElement = target; + const dataset = element.dataset; + if (!dataset || !dataset.sigil || dataset.sigil.toLowerCase().indexOf('inlinevideo') == -1) { + return + } + let i = 0; + while (!element.hasAttribute('data-store')) { + if (++i > 2) { + return + } + element = element.parentNode; + } + const store = element.dataset.store; + if (!store) { + return + } + + let dataStore; + + try { + dataStore = JSON.parse(store) + } catch (e) { + return + } + + const url = dataStore.src; + + // !startsWith; see https://stackoverflow.com/a/36876507/4407321 + if (!url || url.lastIndexOf('http', 0) !== 0) { + return + } + + console.log(`Inline video ${url}`); + if (Frost.loadVideo(url, dataStore.animatedGifVideo || false)) { + e.stopPropagation() + } + }; + + document.addEventListener('click', _frostMediaClick, true); +}).call(undefined); diff --git a/app-compose/src/web/ts/notif_msg.ts b/app-compose/src/web/ts/notif_msg.ts new file mode 100644 index 000000000..b7ce7a191 --- /dev/null +++ b/app-compose/src/web/ts/notif_msg.ts @@ -0,0 +1,25 @@ +// Binds callback to an invisible webview to take in the search events +(function () { + let finished = false; + const x = new MutationObserver(() => { + const _f_thread = document.querySelector('#threadlist_rows'); + if (!_f_thread) { + return + } + console.log(`Found message threads ${_f_thread.outerHTML}`); + Frost.handleHtml(_f_thread.outerHTML); + finished = true; + x.disconnect(); + }); + x.observe(document, { + childList: true, + subtree: true + }); + setTimeout(() => { + if (!finished) { + finished = true; + console.log('Message thread timeout cancellation'); + Frost.handleHtml("") + } + }, 20000); +}).call(undefined); diff --git a/app-compose/src/web/ts/scroll_stop.ts b/app-compose/src/web/ts/scroll_stop.ts new file mode 100644 index 000000000..1ec6d30bc --- /dev/null +++ b/app-compose/src/web/ts/scroll_stop.ts @@ -0,0 +1,25 @@ +// Listen when scrolling events stop +(function () { + let scrollTimeout: number | undefined = undefined; + let scrolling: boolean = false; + + window.addEventListener('scroll', function (event) { + + if (!scrolling) { + Frost.setScrolling(true); + scrolling = true; + } + + window.clearTimeout(scrollTimeout); + + scrollTimeout = setTimeout(function () { + if (scrolling) { + Frost.setScrolling(false); + scrolling = false; + } + }, 600); + // For our specific use case, we want to release other features pretty far after scrolling stops + // For general scrolling use cases, the delta can be much smaller + // My assumption for context menus is that the long press is 500ms + }, false); +}).call(undefined); \ No newline at end of file diff --git a/app-compose/src/web/ts/textarea_listener.ts b/app-compose/src/web/ts/textarea_listener.ts new file mode 100644 index 000000000..062f5bf67 --- /dev/null +++ b/app-compose/src/web/ts/textarea_listener.ts @@ -0,0 +1,31 @@ +/* + * focus listener for textareas + * since swipe to refresh is quite sensitive, we will disable it + * when we detect a user typing + * note that this extends passed having a keyboard opened, + * as a user may still be reviewing his/her post + * swiping should automatically be reset on refresh + */ +(function () { + const _frostFocus = (e: Event) => { + const element = e.target || e.srcElement; + if (!(element instanceof Element)) { + return + } + console.log(`FrostJSI focus, ${element.tagName}`); + if (element.tagName === 'TEXTAREA') { + Frost.disableSwipeRefresh(true); + } + }; + + const _frostBlur = (e: Event) => { + const element = e.target || e.srcElement; + if (!(element instanceof Element)) { + return + } + console.log(`FrostJSI blur, ${element.tagName}`); + Frost.disableSwipeRefresh(false); + }; + document.addEventListener("focus", _frostFocus, true); + document.addEventListener("blur", _frostBlur, true); +}).call(undefined); diff --git a/app-compose/src/web/tsconfig.json b/app-compose/src/web/tsconfig.json index 64032f84f..2bf985f60 100644 --- a/app-compose/src/web/tsconfig.json +++ b/app-compose/src/web/tsconfig.json @@ -16,7 +16,7 @@ "allowUnreachableCode": true, "allowUnusedLabels": true, "removeComments": true, - "outDir": "assets/frostcore/js" + "outDir": "assets/frost/js" }, "include": [ "ts", diff --git a/app-compose/src/web/typings/browser.d.ts b/app-compose/src/web/typings/browser.d.ts deleted file mode 100644 index f631123a4..000000000 --- a/app-compose/src/web/typings/browser.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare namespace browser.runtime { - interface Port { - postMessage: (message: string) => void; - postMessage: (message: ExtensionModel) => void; - } - function sendNativeMessage(application: string, message: ExtensionModel): Promise; -} \ No newline at end of file diff --git a/app-compose/src/web/typings/frost.d.ts b/app-compose/src/web/typings/frost.d.ts index 1c4538517..9f77ce9e1 100644 --- a/app-compose/src/web/typings/frost.d.ts +++ b/app-compose/src/web/typings/frost.d.ts @@ -1,11 +1,33 @@ -type TestModel = { - type: 'test-model' - message: string +declare interface FrostJSI { + loadUrl(url: string | null): boolean + + loadVideo(url: string | null, isGif: boolean): boolean + + reloadBaseUrl(animate: boolean) + + contextMenu(url: string | null, text: string | null) + + longClick(start: boolean) + + disableSwipeRefresh(disable: boolean) + + loadLogin() + + loadImage(imageUrl: string, text: string | null) + + emit(flag: number) + + isReady() + + handleHtml(html: string | null) + + handleHeader(html: string | null) + + allowHorizontalScrolling(enable: boolean) + + setScrolling(scrolling: boolean) + + isScrolling(): boolean } -type UrlClickModel = { - type: 'url-click' - url: string -} - -type ExtensionModel = TestModel | UrlClickModel +declare var Frost: FrostJSI;