aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-06-08 01:17:24 -0400
committerbobzel <zzzman@gmail.com>2022-06-08 01:17:24 -0400
commitf8840672a7bcb3f337d8e50098f374a1b2d441ce (patch)
treeae91a89fb8711c0fa216402c58c4acc130c65028 /src
parent3bf78af650a17db0a836118cb49159fd94cb8de2 (diff)
added ability to make thumbnails of dashboards. started to cleanup dockingView/goldenlayout undo event handling. cleaned up tab doc list in docking view. made titles editable again in treeview. fixed overlay view to work with image docs etc by setting top/left in css
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts6
-rw-r--r--src/client/goldenLayout.js2
-rw-r--r--src/client/util/CurrentUserUtils.ts26
-rw-r--r--src/client/views/DocumentButtonBar.tsx53
-rw-r--r--src/client/views/MainView.tsx12
-rw-r--r--src/client/views/OverlayView.scss2
-rw-r--r--src/client/views/OverlayView.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx21
-rw-r--r--src/client/views/collections/TabDocView.tsx28
-rw-r--r--src/client/views/collections/TreeView.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx45
-rw-r--r--src/client/views/nodes/WebBoxRenderer.js4
-rw-r--r--src/client/views/topbar/TopBar.tsx6
13 files changed, 108 insertions, 103 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 817478b2f..acc1e341a 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -671,9 +671,9 @@ export namespace Docs {
return viewDoc;
}
- export function ImageDocument(url: string, options: DocumentOptions = {}) {
- const imgField = new ImageField(url);
- return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: basename(url), ...options });
+ export function ImageDocument(url: string|ImageField, options: DocumentOptions = {}) {
+ const imgField = url instanceof ImageField ? url : new ImageField(url);
+ return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: basename(imgField.url.href), ...options });
}
export function PresDocument(options: DocumentOptions = {}) {
diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js
index 82b10608d..4735f216f 100644
--- a/src/client/goldenLayout.js
+++ b/src/client/goldenLayout.js
@@ -1431,7 +1431,7 @@
this.root.callDownwards('_$init');
if (config.maximisedItemId === '__glMaximised') {
- this.root.getItemsById(config.maximisedItemId)[0].toggleMaximise();
+ this.root.getItemsById(config.maximisedItemId)[0]?.toggleMaximise();
}
},
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 51bfdbbd2..885679b64 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -8,7 +8,7 @@ import { PrefetchProxy } from "../../fields/Proxy";
import { RichTextField } from "../../fields/RichTextField";
import { ComputedField, ScriptField } from "../../fields/ScriptField";
import { BoolCast, Cast, DateCast, NumCast, PromiseValue, StrCast } from "../../fields/Types";
-import { nullAudio } from "../../fields/URLField";
+import { ImageField, nullAudio } from "../../fields/URLField";
import { SharingPermissions } from "../../fields/util";
import { Utils } from "../../Utils";
import { DocServer } from "../DocServer";
@@ -22,11 +22,10 @@ import { TreeView } from "../views/collections/TreeView";
import { Colors } from "../views/global/globalEnums";
import { MainView } from "../views/MainView";
import { ButtonType, NumButtonType } from "../views/nodes/button/FontIconBox";
-import { LabelBox } from "../views/nodes/LabelBox";
import { CollectionFreeFormDocumentView } from "../views/nodes/CollectionFreeFormDocumentView";
import { OverlayView } from "../views/OverlayView";
import { DocumentManager } from "./DocumentManager";
-import { DragManager, dropActionType } from "./DragManager";
+import { DragManager } from "./DragManager";
import { makeTemplate, MakeTemplate } from "./DropConverter";
import { HistoryUtil } from "./History";
import { LinkManager } from "./LinkManager";
@@ -1185,9 +1184,24 @@ export class CurrentUserUtils {
}
public static async snapshotDashboard(userDoc: Doc) {
- const copy = await CollectionDockingView.Copy(CurrentUserUtils.ActiveDashboard);
- Doc.AddDocToList(Cast(userDoc.myDashboards, Doc, null), "data", copy);
- CurrentUserUtils.openDashboard(userDoc, copy);
+ const docView = CollectionDockingView.Instance.props.DocumentView?.();
+ const content = docView?.ContentDiv;
+ if (docView && content) {
+ const _width = Number(getComputedStyle(content).width.replace("px",""));
+ const _height = Number(getComputedStyle(content).height.replace("px",""));
+ CollectionFreeFormView.UpdateIcon(
+ docView.layoutDoc[Id] + "-icon" + (new Date()).getTime(),
+ content,
+ _width, _height,
+ _width, _height, 0,
+ (iconFile, _nativeWidth, _nativeHeight) => {
+ const img = Docs.Create.ImageDocument(new ImageField(iconFile), { title: docView.rootDoc.title+"-icon", _width, _height, _nativeWidth, _nativeHeight});
+ const proto = Cast(img.proto, Doc, null)!;
+ proto["data-nativeWidth"] = _width;
+ proto["data-nativeHeight"] = _height;
+ docView.dataDoc.thumb = img;
+ });
+ }
}
public static createNewDashboard = async (userDoc: Doc, id?: string) => {
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index c0645f0ab..103734b9b 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -213,34 +213,31 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
@undoBatch
@action
pinWithView = (targetDoc: Doc) => {
- if (targetDoc) {
- TabDocView.PinDoc(targetDoc);
- setTimeout(() => {
- const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1];
- const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetDoc.type as any) || targetDoc._viewType === CollectionViewType.Stacking;
- const pannable: boolean = ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG);
- if (scrollable) {
- const scroll = targetDoc._scrollTop;
- activeDoc.presPinView = true;
- activeDoc.presPinViewScroll = scroll;
- } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
- activeDoc.presPinView = true;
- activeDoc.presStartTime = targetDoc._currentTimecode;
- activeDoc.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1;
- } else if (pannable) {
- const x = targetDoc._panX;
- const y = targetDoc._panY;
- const scale = targetDoc._viewScale;
- activeDoc.presPinView = true;
- activeDoc.presPinViewX = x;
- activeDoc.presPinViewY = y;
- activeDoc.presPinViewScale = scale;
- } else if (targetDoc.type === DocumentType.COMPARISON) {
- const width = targetDoc._clipWidth;
- activeDoc.presPinClipWidth = width;
- activeDoc.presPinView = true;
- }
- });
+ const activeDoc = targetDoc && TabDocView.PinDoc(targetDoc);
+ if (activeDoc) {
+ const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetDoc.type as any) || targetDoc._viewType === CollectionViewType.Stacking;
+ const pannable: boolean = ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG);
+ if (scrollable) {
+ const scroll = targetDoc._scrollTop;
+ activeDoc.presPinView = true;
+ activeDoc.presPinViewScroll = scroll;
+ } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
+ activeDoc.presPinView = true;
+ activeDoc.presStartTime = targetDoc._currentTimecode;
+ activeDoc.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1;
+ } else if (pannable) {
+ const x = targetDoc._panX;
+ const y = targetDoc._panY;
+ const scale = targetDoc._viewScale;
+ activeDoc.presPinView = true;
+ activeDoc.presPinViewX = x;
+ activeDoc.presPinViewY = y;
+ activeDoc.presPinViewScale = scale;
+ } else if (targetDoc.type === DocumentType.COMPARISON) {
+ const width = targetDoc._clipWidth;
+ activeDoc.presPinClipWidth = width;
+ activeDoc.presPinView = true;
+ }
}
}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index cdf85c905..a30db66e4 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -226,17 +226,7 @@ export class MainView extends React.Component {
if (received && !this.userDoc) {
reaction(() => CurrentUserUtils.GuestTarget, target => target && CurrentUserUtils.createNewDashboard(Doc.UserDoc()), { fireImmediately: true });
} else {
- if (received && CurrentUserUtils._urlState.sharing) {
- reaction(() => CollectionDockingView.Instance && CollectionDockingView.Instance.initialized,
- initialized => initialized && received && DocServer.GetRefField(received).then(docField => {
- if (docField instanceof Doc && docField._viewType !== CollectionViewType.Docking) {
- CollectionDockingView.AddSplit(docField, "right");
- }
- }),
- );
- }
- const activeDash = PromiseValue(this.userDoc.activeDashboard);
- activeDash.then(dash => {
+ PromiseValue(this.userDoc.activeDashboard).then(dash => {
if (dash instanceof Doc) CurrentUserUtils.openDashboard(this.userDoc, dash);
else CurrentUserUtils.createNewDashboard(this.userDoc);
});
diff --git a/src/client/views/OverlayView.scss b/src/client/views/OverlayView.scss
index 555f4298d..f22e68ff5 100644
--- a/src/client/views/OverlayView.scss
+++ b/src/client/views/OverlayView.scss
@@ -46,4 +46,6 @@
.overlayView-doc {
z-index: 9002; //so that it appears above chroma
position: absolute;
+ top: 0;
+ left: 0;
} \ No newline at end of file
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index c3c103b50..f5e686473 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -200,7 +200,7 @@ export class OverlayView extends React.Component {
ScreenToLocalTransform={this.docScreenToLocalXf(d)}
renderDepth={1}
isDocumentActive={returnTrue}
- isContentActive={retu}
+ isContentActive={returnTrue}
whenChildContentsActiveChanged={emptyFunction}
focus={DocUtils.DefaultFocus}
styleProvider={DefaultStyleProvider}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index de2106e4a..5af72b7d1 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -26,6 +26,7 @@ import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView";
import { CollectionViewType } from './CollectionView';
import { TabDocView } from './TabDocView';
import React = require("react");
+import { SelectionManager } from '../../util/SelectionManager';
const _global = (window /* browser */ || global /* node */) as any;
@observer
@@ -50,9 +51,8 @@ export class CollectionDockingView extends CollectionSubView() {
public _flush: UndoManager.Batch | undefined;
private _ignoreStateChange = "";
public tabMap: Set<any> = new Set();
- public get initialized() { return this._goldenLayout !== null; }
public get HasFullScreen() { return this._goldenLayout._maximisedItem !== null; }
- @observable private _goldenLayout: any = null;
+ private _goldenLayout: any = null;
constructor(props: SubCollectionViewProps) {
super(props);
@@ -118,6 +118,7 @@ export class CollectionDockingView extends CollectionSubView() {
@undoBatch
public static OpenFullScreen(doc: Doc) {
+ SelectionManager.DeselectAll();
const instance = CollectionDockingView.Instance;
if (doc._viewType === CollectionViewType.Docking && doc.layoutKey === "layout") {
return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
@@ -271,7 +272,7 @@ export class CollectionDockingView extends CollectionSubView() {
return true;
}
- async setupGoldenLayout() {
+ setupGoldenLayout = async () => {
const config = StrCast(this.props.Document.dockingConfig);
if (config) {
const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g);
@@ -291,7 +292,7 @@ export class CollectionDockingView extends CollectionSubView() {
}
this.tabMap.clear();
this._goldenLayout?.destroy();
- runInAction(() => this._goldenLayout = new GoldenLayout(JSON.parse(config)));
+ this._goldenLayout = new GoldenLayout(JSON.parse(config));
this._goldenLayout.on('tabCreated', this.tabCreated);
this._goldenLayout.on('tabDestroyed', this.tabDestroyed);
this._goldenLayout.on('stackCreated', this.stackCreated);
@@ -322,7 +323,7 @@ export class CollectionDockingView extends CollectionSubView() {
}
this._ignoreStateChange = "";
});
- setTimeout(() => this.setupGoldenLayout(), 0);
+ setTimeout(this.setupGoldenLayout);
//window.addEventListener('resize', this.onResize); // bcz: would rather add this event to the parent node, but resize events only come from Window
}
}
@@ -413,19 +414,25 @@ export class CollectionDockingView extends CollectionSubView() {
const docs = !docids ? [] : docids.map(id => DocServer.GetCachedRefField(id)).filter(f => f).map(f => f as Doc);
const changesMade = this.props.Document.dockcingConfig !== json;
if (changesMade && !this._flush) {
- this.props.Document.dockingConfig = json;
- this.props.Document.data = new List<Doc>(docs);
+ UndoManager.RunInBatch(() => {
+ this.props.Document.dockingConfig = json;
+ this.props.Document.data = new List<Doc>(docs);
+ }, "state changed");
}
return changesMade;
}
tabDestroyed = (tab: any) => {
+ const dview = CollectionDockingView.Instance.props.Document;
+ const fieldKey = CollectionDockingView.Instance.props.fieldKey;
+ Doc.RemoveDocFromList(dview, fieldKey, tab.DashDoc);
this.tabMap.delete(tab);
tab._disposers && Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
tab.reactComponents?.forEach((ele: any) => ReactDOM.unmountComponentAtNode(ele));
this.stateChanged();
}
tabCreated = (tab: any) => {
+ this.tabMap.add(tab);
tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content)
}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 0141724ea..75a8207dd 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -82,7 +82,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
const iconWrap = document.createElement("div");
const closeWrap = document.createElement("div");
-
titleEle.size = StrCast(doc.title).length + 3;
titleEle.value = doc.title;
titleEle.onkeydown = (e: KeyboardEvent) => {
@@ -185,14 +184,13 @@ export class TabDocView extends React.Component<TabDocViewProps> {
UndoManager.RunInBatch(() => tab.contentItem.remove(), "delete tab");
});
}
- CollectionDockingView.Instance.tabMap.add(tab);
}
/**
* Adds a document to the presentation view
**/
@action
- public static async PinDoc(doc: Doc, pinProps?: PinProps) {
+ public static PinDoc(doc: Doc, pinProps?: PinProps) {
//add this new doc to props.Document
// all docs will be added to the ActivePresentation as stored on CurrentUserUtils
@@ -246,19 +244,14 @@ export class TabDocView extends React.Component<TabDocViewProps> {
pinDoc.presMovement = PresMovement.None;
}
if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
- const dview = CollectionDockingView.Instance.props.Document;
- const fieldKey = CollectionDockingView.Instance.props.fieldKey;
- const tabdocs = await DocListCastAsync(dview[fieldKey]);
- runInAction(() => {
- if (!pinProps?.hidePresBox && !tabdocs?.includes(curPres)) {
- tabdocs?.push(curPres); // bcz: Argh! this is annoying. if multiple documents are pinned, this will get called multiple times before the presentation view is drawn. Thus it won't be in the tabdocs list and it will get created multple times. so need to explicilty add the presbox to the list of open tabs
- CollectionDockingView.AddSplit(curPres, "right");
- }
- PresBox.Instance?._selectedArray.clear();
- pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array
- DocumentManager.Instance.jumpToDocument(doc, false, undefined, []);
- batch.end();
- });
+ if (!Array.from(CollectionDockingView.Instance.tabMap).map(d => d.DashDoc).includes(curPres)) {
+ CollectionDockingView.AddSplit(curPres, "right");
+ setTimeout(() => DocumentManager.Instance.jumpToDocument(doc, false, undefined, []), 100); // keeps the pinned doc in view since the sidebar shifts things
+ }
+ PresBox.Instance?._selectedArray.clear();
+ pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array
+ setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
+ return pinDoc;
}
}
@@ -282,7 +275,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
componentWillUnmount() {
this._tabReaction?.();
this._view && DocumentManager.Instance.RemoveView(this._view);
- this.tab && CollectionDockingView.Instance.tabMap.delete(this.tab);
this.props.glContainer.layoutManager.off("activeContentItemChanged", this.onActiveContentItemChanged);
}
@@ -430,9 +422,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}} ref={ref => {
if (this._mainCont = ref) {
if (this._lastTab) {
- console.log("DUP tab")
this._view && DocumentManager.Instance.RemoveView(this._view);
- CollectionDockingView.Instance.tabMap.delete(this._lastTab);
}
this._lastTab = this.tab;
(this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document);
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index befd2020c..09f05f69a 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -609,10 +609,8 @@ export class TreeView extends React.Component<TreeViewProps> {
return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label }));
}
- // TODO: currently doc focus works, but can't seem to edit title
- // onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
onChildClick = () => {
- return this.props.onChildClick?.() ?? (ScriptField.MakeFunction(`DocFocusOrOpen(self)`)! || this._editTitleScript?.());
+ return this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!);
}
onChildDoubleClick = () => (!this.props.treeView.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 77cf0fc84..5f927a2a9 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1489,7 +1489,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}));
}
- replaceCanvases = (oldDiv: HTMLElement, newDiv: HTMLElement) => {
+ static replaceCanvases(oldDiv: HTMLElement, newDiv: HTMLElement) {
if (oldDiv.childNodes && newDiv) {
for (let i = 0; i < oldDiv.childNodes.length; i++) {
this.replaceCanvases(oldDiv.childNodes[i] as HTMLElement, newDiv.childNodes[i] as HTMLElement);
@@ -1508,32 +1508,39 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
}
- updateIcon = () => {
- const docViewContent = this.props.docViewPath().lastElement().ContentDiv!;
+ updateIcon = () => CollectionFreeFormView.UpdateIcon(
+ this.layoutDoc[Id] + "-icon" + (new Date()).getTime(),
+ this.props.docViewPath().lastElement().ContentDiv!,
+ this.layoutDoc[WidthSym](), this.layoutDoc[HeightSym](),
+ this.props.PanelWidth(), this.props.PanelHeight(), 0,
+ (iconFile, nativeWidth, nativeHeight) => {
+ this.dataDoc.icon = new ImageField(iconFile);
+ this.dataDoc["icon-nativeWidth"] = nativeWidth;
+ this.dataDoc["icon-nativeHeight"] = nativeHeight;
+ });
+
+ public static UpdateIcon(filename:string, docViewContent:HTMLElement, width: number, height: number,
+ panelWidth:number, panelHeight: number, scrollTop:number, cb:(iconFile:string, nativeWidth:number, nativeHeight:number) => any) {
const newDiv = docViewContent.cloneNode(true) as HTMLDivElement;
- newDiv.style.width = (this.layoutDoc[WidthSym]()).toString();
- newDiv.style.height = (this.layoutDoc[HeightSym]()).toString();
+ newDiv.style.width = width.toString();
+ newDiv.style.height = height.toString();
this.replaceCanvases(docViewContent, newDiv);
- const htmlString = this._mainCont && new XMLSerializer().serializeToString(newDiv);
- const nativeWidth = this.layoutDoc[WidthSym]();
- const nativeHeight = this.layoutDoc[HeightSym]();
-
+ const htmlString = new XMLSerializer().serializeToString(newDiv);
+ const nativeWidth = width;
+ const nativeHeight = height;
CreateImage(
- "",
+ Utils.prepend(""),
document.styleSheets,
htmlString,
nativeWidth,
- nativeWidth * this.props.PanelHeight() / this.props.PanelWidth(),
- NumCast(this.layoutDoc._scrollTop)
+ nativeWidth * panelHeight / panelWidth,
+ scrollTop
).then
((data_url: any) => {
- VideoBox.convertDataUri(data_url, this.layoutDoc[Id] + "-icon" + (new Date()).getTime(), true, this.layoutDoc[Id] + "-icon").then(
- returnedfilename => setTimeout(action(() => {
-
- this.dataDoc.icon = new ImageField(returnedfilename);
- this.dataDoc["icon-nativeWidth"] = nativeWidth;
- this.dataDoc["icon-nativeHeight"] = nativeHeight;
- }), 500));
+ VideoBox.convertDataUri(data_url, filename).then(
+ returnedfilename => setTimeout(() => {
+ cb(returnedfilename as string, nativeWidth, nativeHeight);
+ }, 500));
})
.catch(function (error: any) {
console.error('oops, something went wrong!', error);
diff --git a/src/client/views/nodes/WebBoxRenderer.js b/src/client/views/nodes/WebBoxRenderer.js
index d9524dd6e..f3f1bcf5c 100644
--- a/src/client/views/nodes/WebBoxRenderer.js
+++ b/src/client/views/nodes/WebBoxRenderer.js
@@ -214,8 +214,8 @@ var ForeignHtmlRenderer = function (styleSheets) {
.replace(/noscript/g, "div").replace(/<div class="mediaset"><\/div>/g, "") // when scripting isn't available (ie, rendering web pages here), <noscript> tags should become <div>'s. But for Brown CS, there's a layout problem if you leave the empty <mediaset> tag
.replace(/<link[^>]*>/g, "") // don't need to keep any linked style sheets because we've already processed all style sheets above
.replace(/srcset="([^ "]*)[^"]*"/g, "src=\"$1\""); // instead of converting each item in the srcset to a data url, just convert the first one and use that
- let urlsFoundInHtml = getImageUrlsFromFromHtml(contentHtml);
- const fetchedResources = await getMultipleResourcesAsBase64(webUrl, urlsFoundInHtml);
+ let urlsFoundInHtml = getImageUrlsFromFromHtml(contentHtml).filter(url => !url.startsWith("data:"));
+ const fetchedResources = webUrl ? await getMultipleResourcesAsBase64(webUrl, urlsFoundInHtml) : [];
for (let i = 0; i < fetchedResources.length; i++) {
const r = fetchedResources[i];
if (r.resourceUrl) {
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index be248ab92..e486bcb52 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -48,7 +48,7 @@ export class TopBar extends React.Component {
await CurrentUserUtils.createNewDashboard(Doc.UserDoc());
batch.end();
}}>
- {"New"}<FontAwesomeIcon icon="plus" />
+ New<FontAwesomeIcon icon="plus" />
</div>
</Tooltip>
<Tooltip title={<div className="dash-tooltip">Work on a copy of the dashboard layout</div>} placement="bottom">
@@ -57,12 +57,12 @@ export class TopBar extends React.Component {
await CurrentUserUtils.snapshotDashboard(Doc.UserDoc());
batch.end();
}}>
- {"Snapshot"}<FontAwesomeIcon icon="camera" />
+ Snapshot<FontAwesomeIcon icon="camera" />
</div>
</Tooltip>
<Tooltip title={<div className="dash-tooltip">Browsing mode for directly navigating to documents</div>} placement="bottom">
<div className="topbar-icon" style={{ background: MainView.Instance._exploreMode ? Colors.LIGHT_BLUE : undefined }} onClick={action(() => MainView.Instance._exploreMode = !MainView.Instance._exploreMode)}>
- {"Explore"}<FontAwesomeIcon icon="map" />
+ Explore<FontAwesomeIcon icon="map" />
</div>
</Tooltip>
</div>