aboutsummaryrefslogtreecommitdiff
path: root/app/src/web
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/web')
-rw-r--r--app/src/web/scss/core/_core_text.scss2
-rw-r--r--app/src/web/ts/click_a.ts93
-rw-r--r--app/src/web/ts/context_a.ts33
3 files changed, 93 insertions, 35 deletions
diff --git a/app/src/web/scss/core/_core_text.scss b/app/src/web/scss/core/_core_text.scss
index 63622610..2142ef73 100644
--- a/app/src/web/scss/core/_core_text.scss
+++ b/app/src/web/scss/core/_core_text.scss
@@ -19,7 +19,7 @@ textarea:not([style*="color: rgb"]), ._24pi, ._4en9, ._1kb, ._5p7j, ._2klz, ._57
div.sharerSelector, .footer, ._4pv_, ._1dbp, ._3kad, ._20zc, ._2i5v, ._2i5w,
a, ._5fpq, ._4gux, ._3bg5 ._52x1, ._3bg5 ._52x2, ._6dsj ._3gin, ._hdn._hdn,
.mentions-input:not([style*="color: rgb"]), .mentions-placeholder:not([style*="color: rgb"]),
-.largeStatusBox .placeHolder, .fcw, ._2rgt, ._67i4 ._5hu6 ._59tt,
+.largeStatusBox .placeHolder, .fcw, ._2rgt, ._67i4 ._5hu6 ._59tt, ._2bu3, ._2bu4,
._5-7t, .fcl, ._4qas, .thread-title, .title, ._46pa, ._336p, ._1rrd, ._2om4,
._3m1m, ._2om2, ._5n_e, .appListExplanation, ._5yt8, ._8he, ._2luw, ._5rgs,
h1, h2, h3, h4, h5, h6 {
diff --git a/app/src/web/ts/click_a.ts b/app/src/web/ts/click_a.ts
index 5023610e..8d1d545b 100644
--- a/app/src/web/ts/click_a.ts
+++ b/app/src/web/ts/click_a.ts
@@ -1,34 +1,81 @@
(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.
+ * 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
+ }
+
+ /**
+ * Attempts to find a url entry at most [depth] away
+ * A url is found if the element has tag 'A', and the url isn't blank
+ */
+ function _parentUrl(el: HTMLElement, depth: number): string | null {
+ const element = _parentEl(el, depth, (el) => el.tagName === 'A');
+ if (!element) {
+ return null;
+ }
+ const url = element.getAttribute('href');
+ if (!url || url === '#') {
+ return null;
+ }
+ return url
+ }
+
+ /**
+ * Given event and target, return true if handled and false otherwise.
+ */
+ type EventHandler = (e: Event, target: HTMLElement) => Boolean
+
+ const _frostGeneral: EventHandler = (e, target) => {
+ // Notifications are two layers under
+ const url = _parentUrl(target, 2);
+ return Frost.loadUrl(url);
+ };
+
+ 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);
+ };
+
+ const handlers: EventHandler[] = [_frostLaunchpadClick, _frostGeneral];
+
const _frostAClick = (e: Event) => {
- // check for valid target
+ if (prevented) {
+ console.log("Click intercept prevented");
+ return
+ }
+ /*
+ * Commonality; check for valid target
+ */
const target = e.target || e.currentTarget || e.srcElement;
- if (!(target instanceof Element)) {
+ if (!(target instanceof HTMLElement)) {
console.log("No element found");
return
}
- let element: Element = target;
- // Notifications are two layers under
- for (let i = 0; i < 2; i++) {
- if (element.tagName !== 'A') {
- element = <Element>element.parentElement;
- }
- }
- if (element.tagName === 'A') {
- if (!prevented) {
- const url = element.getAttribute('href');
- if (!url || url === '#') {
- return
- }
- console.log(`Click intercept ${url}`);
- // If Frost is injected, check if loading the url through an overlay works
- if (Frost.loadUrl(url)) {
- e.stopPropagation();
- e.preventDefault();
- }
- } else {
- console.log("Click intercept prevented")
+ for (const h of handlers) {
+ if (h(e, target)) {
+ e.stopPropagation();
+ e.preventDefault();
+ return
}
}
};
diff --git a/app/src/web/ts/context_a.ts b/app/src/web/ts/context_a.ts
index 5eec7611..b9549f3f 100644
--- a/app/src/web/ts/context_a.ts
+++ b/app/src/web/ts/context_a.ts
@@ -7,6 +7,25 @@
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
@@ -55,16 +74,8 @@
* Opens image activity for posts with just one image
*/
const _frostImage: EventHandler = (e, target) => {
- let element: Element = target;
- // Notifications are two layers under
- for (let i = 0; i < 2; i++) {
- if (element.tagName !== 'A') {
- element = <Element>element.parentElement;
- } else {
- break
- }
- }
- if (element.tagName !== 'A') {
+ const element = _parentEl(target, 2, (el) => el.tagName === 'A');
+ if (!element) {
return false;
}
const url = element.getAttribute('href');
@@ -92,7 +103,7 @@
return true;
};
- const handlers = [_frostImage, _frostCopyComment, _frostCopyPost];
+ const handlers: EventHandler[] = [_frostImage, _frostCopyComment, _frostCopyPost];
const _frostAContext = (e: Event) => {
Frost.longClick(true);