From 3e0a9ff2c708891a15a681e5af549caf0b18ff60 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 26 Oct 2021 12:06:36 -0400 Subject: when document is in lightbox view and a link is followed to its sidebar, we no longer reopen the document in its context. fixed selecting annotations on web/pdf. don't change document height when shown in a linkPreview. webBox fixes for pages with scripts. fixed range bounds when clicking on web text several fixes to web pages on server and client. client webbox allows clicks on divs with onclick instead of doing selection also hacky fix so that google search url doesn't keep expanding by removing 'q=' regions also added prevent/allow script menu item server grabs all html and hides id="google.." which are ads. also rewrites hrefs starting with http to route through corsProxy also removes target=_blank tags to prevent pages from opening outside of dash. also cleaned up routes and comments also when not logged in, references to anything in dash domain route to /home --- src/client/views/nodes/WebBox.tsx | 77 +++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 16 deletions(-) (limited to 'src/client/views/nodes/WebBox.tsx') diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 37d716993..9956cc36b 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -58,8 +58,10 @@ export class WebBox extends ViewBoxAnnotatableComponent(); private _searchRef = React.createRef(); private _searchString = ""; + @observable private _webUrl = ""; // url of the src parameter of the embedded iframe but not necessarily the rendered page - eg, when following a link, the rendered page changes but we don't wan the src parameter to also change as that would cause an unnecessary re-render. + @observable private _hackHide = false; // apparently changing the value of the 'sandbox' prop doesn't necessarily apply it to the active iframe. so thisforces the ifrmae to be rebuilt when allowScripts is toggled @observable private _searching: boolean = false; - @observable _showSidebar = false; + @observable private _showSidebar = false; @observable private _scrollTimer: any; @observable private _overlayAnnoInfo: Opt; @observable private _marqueeing: number[] | undefined; @@ -79,6 +81,7 @@ export class WebBox extends ViewBoxAnnotatableComponent this._webUrl = this._url); // setting the weburl will change the src parameter of the embedded iframe and force a navigation to it. } @action @@ -239,7 +242,7 @@ export class WebBox extends ViewBoxAnnotatableComponent this._marqueeing = undefined), 100); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it. } else { this._iframeClick = this._iframe ?? undefined; @@ -269,9 +272,24 @@ export class WebBox extends ViewBoxAnnotatableComponent { const iframe = this._iframe; - this._iframe?.contentDocument?.addEventListener("pointerup", this.iframeUp); + let requrlraw = decodeURIComponent(iframe?.contentWindow?.location.href.replace(Utils.prepend("") + "/corsProxy/", "") ?? this._url.toString()); + if (requrlraw !== this._url.toString()) { + if (requrlraw.match(/q=.*&/)?.length && this._url.toString().match(/q=.*&/)?.length) { + const matches = requrlraw.match(/[^a-zA-z]q=[^&]*/g); + const newsearch = matches?.lastElement()!; + if (matches) { + requrlraw = requrlraw.substring(0, requrlraw.indexOf(newsearch)); + for (let i = 1; i < Array.from(matches)?.length; i++) { + requrlraw = requrlraw.replace(matches[i], ""); + } + } + requrlraw = requrlraw.replace(/q=[^&]*/, newsearch.substring(1)).replace("search&", "search?").replace("?gbv=1", ""); + } + this.submitURL(requrlraw, undefined, true); + } if (iframe?.contentDocument) { - iframe?.contentDocument.addEventListener("pointerdown", this.iframeDown); + iframe.contentDocument.addEventListener("pointerup", this.iframeUp); + iframe.contentDocument.addEventListener("pointerdown", this.iframeDown); this._scrollHeight = Math.max(this.scrollHeight, iframe?.contentDocument.body.scrollHeight); setTimeout(action(() => this._scrollHeight = Math.max(this.scrollHeight, iframe?.contentDocument?.body.scrollHeight || 0)), 5000); const initialScroll = this._initialScroll; @@ -281,13 +299,15 @@ export class WebBox extends ViewBoxAnnotatableComponent { + iframe.contentDocument.addEventListener("click", undoBatch(action((e: MouseEvent) => { let href = ""; - for (let ele = e.target; ele; ele = ele.parentElement) { + for (let ele = e.target as any; ele; ele = ele.parentElement) { href = (typeof (ele.href) === "string" ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || href; } - if (href && this.webField?.origin) { - this.submitURL(href.replace(Utils.prepend(""), this.webField?.origin)); + const origin = this.webField?.origin; + if (href && origin) { + e.stopPropagation(); + setTimeout(() => this.submitURL(href.replace(Utils.prepend(""), origin))); if (this._outerRef.current) { this._outerRef.current.scrollTop = NumCast(this.layoutDoc._scrollTop); this._outerRef.current.scrollLeft = 0; @@ -338,8 +358,15 @@ export class WebBox extends ViewBoxAnnotatableComponent([...history, this._url]); this.dataDoc[this.fieldKey] = new WebField(new URL(future.pop()!)); + if (this._webUrl === this._url) { + this._webUrl = curUrl; + setTimeout(action(() => this._webUrl = this._url)); + } else { + this._webUrl = this._url; + } return true; } return false; @@ -350,10 +377,16 @@ export class WebBox extends ViewBoxAnnotatableComponent([this._url]); else this.dataDoc[this.fieldKey + "-future"] = new List([...future, this._url]); this.dataDoc[this.fieldKey] = new WebField(new URL(history.pop()!)); - console.log(this._urlHash); + if (this._webUrl === this._url) { + this._webUrl = curUrl; + setTimeout(action(() => this._webUrl = this._url)); + } else { + this._webUrl = this._url; + } return true; } return false; @@ -362,9 +395,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { return Math.abs(s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0)); } - @action - submitURL = (newUrl?: string, preview?: boolean) => { + submitURL = (newUrl?: string, preview?: boolean, dontUpdateIframe?: boolean) => { if (!newUrl) return; if (!newUrl.startsWith("http")) newUrl = "http://" + newUrl; try { @@ -376,7 +408,10 @@ export class WebBox extends ViewBoxAnnotatableComponent this.layoutDoc.useCors = !this.layoutDoc.useCors, icon: "snowflake" }); + funcs.push({ + description: (this.layoutDoc.allowScripts ? "Prevent" : "Allow") + " Scripts", event: () => { + this.layoutDoc.allowScripts = !this.layoutDoc.allowScripts; + if (this._iframe) { + runInAction(() => this._hackHide = true); + setTimeout(action(() => this._hackHide = false)); + } + }, icon: "snowflake" + }); funcs.push({ description: (!this.layoutDoc.forceReflow ? "Force" : "Prevent") + " Reflow", event: () => { const nw = !this.layoutDoc.forceReflow ? undefined : Doc.NativeWidth(this.layoutDoc) - this.sidebarWidth() / (this.props.scaling?.() || 1); @@ -468,18 +512,19 @@ export class WebBox extends ViewBoxAnnotatableComponent; } else if (field instanceof WebField) { - const url = this.layoutDoc.useCors ? Utils.CorsProxy(this._url) : this._url; + const url = this.layoutDoc.useCors ? Utils.CorsProxy(this._webUrl) : this._webUrl; view =