From 480ed16d8a5d45081acb249b0b9af305b528da15 Mon Sep 17 00:00:00 2001
From: Xiao Gui <xgui3783@gmail.com>
Date: Fri, 5 Aug 2022 11:44:08 +0200
Subject: [PATCH] feat: hide ext href in strict local mode

---
 deploy/app.js                                 |  8 +++----
 deploy/util/reconfigPrecomputedServer.js      | 14 -----------
 deploy_env.md                                 |  2 +-
 .../datasets/dataset/dataset.component.ts     |  5 ++--
 .../datasets/dataset/dataset.template.html    |  2 +-
 .../sapiViews/core/datasets/module.ts         |  4 +++-
 .../sapiViews/core/parcellation/module.ts     |  2 ++
 .../parcellation.smartChip.template.html      |  1 +
 .../sapiViews/core/region/module.ts           |  2 ++
 .../region/rich/region.rich.template.html     |  1 +
 .../sapiViews/features/receptors/module.ts    | 15 ------------
 src/index.html                                |  2 ++
 src/strictLocal/index.ts                      |  2 ++
 src/strictLocal/module.ts                     | 23 +++++++++++++++++++
 src/strictLocal/strictLocal.directive.ts      | 22 ++++++++++++++++++
 .../strictLocalCmp.component.ts               | 13 +++++++++++
 src/ui/help/about/about.template.html         |  4 ++--
 src/ui/help/module.ts                         |  4 +++-
 18 files changed, 85 insertions(+), 41 deletions(-)
 delete mode 100644 deploy/util/reconfigPrecomputedServer.js
 create mode 100644 src/strictLocal/index.ts
 create mode 100644 src/strictLocal/module.ts
 create mode 100644 src/strictLocal/strictLocal.directive.ts
 create mode 100644 src/strictLocal/strictLocalCmp/strictLocalCmp.component.ts

diff --git a/deploy/app.js b/deploy/app.js
index 7b48f151d..f4b33a1c3 100644
--- a/deploy/app.js
+++ b/deploy/app.js
@@ -7,7 +7,7 @@ const crypto = require('crypto')
 const cookieParser = require('cookie-parser')
 const bkwdMdl = require('./bkwdCompat')()
 
-const LOCAL_CDN_FLAG = !!process.env.PRECOMPUTED_SERVER
+const LOCAL_CDN_FLAG = !!process.env.LOCAL_CDN
 
 if (process.env.NODE_ENV !== 'production') {
   app.use(require('cors')())
@@ -126,7 +126,8 @@ if (LOCAL_CDN_FLAG) {
   const LOCAL_CDN = process.env.LOCAL_CDN
   const CDN_ARRAY = [
     'https://stackpath.bootstrapcdn.com',
-    'https://use.fontawesome.com'
+    'https://use.fontawesome.com',
+    'https://unpkg.com'
   ]
 
   let indexFile
@@ -214,8 +215,7 @@ app.get('/ready', async (req, res) => {
  * only use compression for production
  * this allows locally built aot to be served without errors
  */
-const { compressionMiddleware, setAlwaysOff } = require('nomiseco')
-if (LOCAL_CDN_FLAG) setAlwaysOff(true)
+const { compressionMiddleware } = require('nomiseco')
 
 app.use(compressionMiddleware, express.static(PUBLIC_PATH))
 
diff --git a/deploy/util/reconfigPrecomputedServer.js b/deploy/util/reconfigPrecomputedServer.js
deleted file mode 100644
index 98a1932ba..000000000
--- a/deploy/util/reconfigPrecomputedServer.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * n.b. trailing slash is required
- * e.g. http://localhost:10080/
- */
-const PRECOMPUTED_SERVER = process.env.PRECOMPUTED_SERVER
-
-const reconfigureFlag = !!PRECOMPUTED_SERVER
-
-exports.reconfigureFlag = reconfigureFlag
-
-exports.reconfigureUrl = (str) => {
-  if (!reconfigureFlag) return str
-  return str.replace(/https?:\/\/.*?\//g, PRECOMPUTED_SERVER)
-}
\ No newline at end of file
diff --git a/deploy_env.md b/deploy_env.md
index bb17c783c..c470a1ef4 100644
--- a/deploy_env.md
+++ b/deploy_env.md
@@ -8,7 +8,7 @@
 | `HOST_PATHNAME` | pathname to listen on, restrictions: leading slash, no trailing slash | `''` | `/viewer` |
 | `SESSIONSECRET` | session secret for cookie session |
 | `NODE_ENV` | determines where the built viewer will be served from | | `production` |
-| `PRECOMPUTED_SERVER` | redirect data uri to another server. Useful for offline demos | | `http://localhost:8080/precomputed/` |
+| ~~`PRECOMPUTED_SERVER`~~ _deprecated_, use `LOCAL_CDN` instead. | redirect data uri to another server. Useful for offline demos | | `http://localhost:8080/precomputed/` |
 | `LOCAL_CDN` | rewrite cdns to local server. useful for offlnie demo | | `http://localhost:7080/` |
 | `PLUGIN_URLS` | semi colon separated urls to be returned when user queries plugins | `''`
 | `STAGING_PLUGIN_URLS` | semi colon separated urls to be returned when user queries plugins | `''`
diff --git a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.component.ts b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.component.ts
index 88614d619..22813095a 100644
--- a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.component.ts
+++ b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input, OnChanges, SimpleChanges } from "@angular/core";
+import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from "@angular/core";
 import { SapiDatasetModel } from "src/atlasComponents/sapi";
 import { CONST } from "common/constants"
 
@@ -9,7 +9,8 @@ const RESTRICTED_ACCESS_ID = "https://nexus.humanbrainproject.org/v0/data/minds/
   templateUrl: './dataset.template.html',
   styleUrls: [
     `./dataset.style.css`
-  ]
+  ],
+  changeDetection: ChangeDetectionStrategy.OnPush
 })
 
 export class DatasetView implements OnChanges{
diff --git a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html
index f9c37f990..a04996afb 100644
--- a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html
+++ b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html
@@ -33,7 +33,7 @@
 
     <mat-divider class="sxplr-pl-1" [vertical]="true"></mat-divider>
 
-    <a mat-icon-button *ngFor="let url of dataset.urls" [href]="url.doi | parseDoi" target="_blank">
+    <a mat-icon-button sxplr-hide-when-local *ngFor="let url of dataset.urls" [href]="url.doi | parseDoi" target="_blank">
       <i class="fas fa-external-link-alt"></i>
     </a>
   </mat-card-subtitle>
diff --git a/src/atlasComponents/sapiViews/core/datasets/module.ts b/src/atlasComponents/sapiViews/core/datasets/module.ts
index b295da6bc..d7b43955b 100644
--- a/src/atlasComponents/sapiViews/core/datasets/module.ts
+++ b/src/atlasComponents/sapiViews/core/datasets/module.ts
@@ -2,6 +2,7 @@ import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
 import { MarkdownModule } from "src/components/markdown";
 import { AngularMaterialModule } from "src/sharedModules";
+import { StrictLocalModule } from "src/strictLocal";
 import { SapiViewsUtilModule } from "../../util/module";
 import { DatasetView } from "./dataset/dataset.component";
 
@@ -10,7 +11,8 @@ import { DatasetView } from "./dataset/dataset.component";
     CommonModule,
     AngularMaterialModule,
     MarkdownModule,
-    SapiViewsUtilModule
+    SapiViewsUtilModule,
+    StrictLocalModule,
   ],
   declarations: [
     DatasetView,
diff --git a/src/atlasComponents/sapiViews/core/parcellation/module.ts b/src/atlasComponents/sapiViews/core/parcellation/module.ts
index 91133d0c1..1fe2e70c0 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/module.ts
+++ b/src/atlasComponents/sapiViews/core/parcellation/module.ts
@@ -4,6 +4,7 @@ import { Store } from "@ngrx/store";
 import { ComponentsModule } from "src/components";
 import { AngularMaterialModule } from "src/sharedModules";
 import { atlasAppearance } from "src/state";
+import { StrictLocalModule } from "src/strictLocal";
 import { DialogModule } from "src/ui/dialogInfo/module";
 import { UtilModule } from "src/util";
 import { SapiViewsUtilModule } from "../../util";
@@ -25,6 +26,7 @@ import { SapiViewsCoreParcellationParcellationTile } from "./tile/parcellation.t
     UtilModule,
     SapiViewsUtilModule,
     DialogModule,
+    StrictLocalModule
   ],
   declarations: [
     SapiViewsCoreParcellationParcellationTile,
diff --git a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
index 05899973a..4dac11789 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
+++ b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
@@ -121,6 +121,7 @@
   <mat-dialog-actions align="start">
     <a *ngFor="let url of parc | parcellationDoiPipe"
       [href]="url"
+      sxplr-hide-when-local
       target="_blank"
       mat-raised-button
       color="primary">
diff --git a/src/atlasComponents/sapiViews/core/region/module.ts b/src/atlasComponents/sapiViews/core/region/module.ts
index 6c30611aa..60fd2425c 100644
--- a/src/atlasComponents/sapiViews/core/region/module.ts
+++ b/src/atlasComponents/sapiViews/core/region/module.ts
@@ -3,6 +3,7 @@ import { NgModule } from "@angular/core";
 import { MarkdownModule } from "src/components/markdown";
 import { SpinnerModule } from "src/components/spinner";
 import { AngularMaterialModule } from "src/sharedModules";
+import { StrictLocalModule } from "src/strictLocal";
 import { SapiViewsFeaturesModule } from "../../features";
 import { SapiViewsUtilModule } from "../../util/module";
 import { SapiViewsCoreRegionRegionChip } from "./region/chip/region.chip.component";
@@ -19,6 +20,7 @@ import { SapiViewsCoreRegionRegionRich } from "./region/rich/region.rich.compone
     SapiViewsFeaturesModule,
     SpinnerModule,
     MarkdownModule,
+    StrictLocalModule,
   ],
   declarations: [
     SapiViewsCoreRegionRegionListItem,
diff --git a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html
index d4a9a79d1..2d03c2042 100644
--- a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html
+++ b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html
@@ -42,6 +42,7 @@
         <!-- explore doi -->
         <a *ngFor="let doi of dois"
           [href]="doi | parseDoi"
+          sxplr-hide-when-local
           [matTooltip]="ARIA_LABELS.EXPLORE_DATASET_IN_KG"
           target="_blank"
           mat-icon-button>
diff --git a/src/atlasComponents/sapiViews/features/receptors/module.ts b/src/atlasComponents/sapiViews/features/receptors/module.ts
index d5bd04dc6..34f29d7f0 100644
--- a/src/atlasComponents/sapiViews/features/receptors/module.ts
+++ b/src/atlasComponents/sapiViews/features/receptors/module.ts
@@ -32,21 +32,6 @@ import { Profile } from "./profile/profile.component"
     Profile,
     Entry,
   ],
-  providers: [{
-    provide: APP_INITIALIZER,
-    multi: true,
-    useFactory: (appendScriptFn: (url: string) => Promise<any>) => {
-
-      const libraries = [
-        'https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js',
-        'https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.1.2/es5/tex-svg.js'
-      ]
-      return () => Promise.all(libraries.map(appendScriptFn))
-    },
-    deps: [
-      APPEND_SCRIPT_TOKEN
-    ]
-  }],
   schemas: [
     CUSTOM_ELEMENTS_SCHEMA,
   ]
diff --git a/src/index.html b/src/index.html
index 56e924d2b..3a8561057 100644
--- a/src/index.html
+++ b/src/index.html
@@ -16,6 +16,8 @@
   <script src="https://unpkg.com/three-surfer@0.0.11/dist/bundle.js" defer></script>
   <script type="module" src="https://unpkg.com/ng-layer-tune@0.0.6/dist/ng-layer-tune/ng-layer-tune.esm.js"></script>
   <script type="module" src="https://unpkg.com/hbp-connectivity-component@0.6.2/dist/connectivity-component/connectivity-component.js" ></script>
+  <script defer src="https://unpkg.com/mathjax@3.1.2/es5/tex-svg.js"></script>
+  <script defer src="https://unpkg.com/d3@6.2.0/dist/d3.min.js"></script>
   <title>Siibra Explorer</title>
 </head>
 <body>
diff --git a/src/strictLocal/index.ts b/src/strictLocal/index.ts
new file mode 100644
index 000000000..df38eaa22
--- /dev/null
+++ b/src/strictLocal/index.ts
@@ -0,0 +1,2 @@
+export { StrictLocalModule } from "./module"
+export { HideWhenLocal } from "./strictLocal.directive"
\ No newline at end of file
diff --git a/src/strictLocal/module.ts b/src/strictLocal/module.ts
new file mode 100644
index 000000000..62db4e8d8
--- /dev/null
+++ b/src/strictLocal/module.ts
@@ -0,0 +1,23 @@
+import { CommonModule } from "@angular/common";
+import { NgModule } from "@angular/core";
+import { MatButtonModule } from "@angular/material/button";
+import { MatTooltipModule } from "@angular/material/tooltip";
+import { HideWhenLocal } from "./strictLocal.directive";
+import { StrictLocalInfo } from "./strictLocalCmp/strictLocalCmp.component";
+
+@NgModule({
+  declarations: [
+    HideWhenLocal,
+    StrictLocalInfo,
+  ],
+  imports: [
+    CommonModule,
+    MatTooltipModule,
+    MatButtonModule,
+  ],
+  exports: [
+    HideWhenLocal,
+  ]
+})
+
+export class StrictLocalModule{}
diff --git a/src/strictLocal/strictLocal.directive.ts b/src/strictLocal/strictLocal.directive.ts
new file mode 100644
index 000000000..b5f0c83ad
--- /dev/null
+++ b/src/strictLocal/strictLocal.directive.ts
@@ -0,0 +1,22 @@
+import { ComponentFactoryResolver, Directive, HostBinding, ViewContainerRef } from "@angular/core";
+import { environment } from "src/environments/environment"
+import { StrictLocalInfo } from "./strictLocalCmp/strictLocalCmp.component";
+
+@Directive({
+  selector: '[sxplr-hide-when-local]',
+  exportAs: 'hideWhenLocal'
+})
+
+export class HideWhenLocal {
+  @HostBinding('style.display')
+  hideWhenLocal = environment.STRICT_LOCAL ? 'none!important' : null
+  constructor(
+    private vc: ViewContainerRef,
+    private cfr: ComponentFactoryResolver,
+  ){
+    if (environment.STRICT_LOCAL) {
+      const cf = this.cfr.resolveComponentFactory(StrictLocalInfo)
+      this.vc.createComponent(cf)
+    }
+  }
+}
diff --git a/src/strictLocal/strictLocalCmp/strictLocalCmp.component.ts b/src/strictLocal/strictLocalCmp/strictLocalCmp.component.ts
new file mode 100644
index 000000000..e75b84c2b
--- /dev/null
+++ b/src/strictLocal/strictLocalCmp/strictLocalCmp.component.ts
@@ -0,0 +1,13 @@
+import { Component } from "@angular/core";
+
+@Component({
+  selector: `strict-local-info`,
+  template: `
+  <button mat-icon-button [matTooltip]="tooltip" tabindex="-1">
+    <i class="fas fa-unlink"></i>
+  </button>`,
+})
+
+export class StrictLocalInfo{
+  tooltip = "External links are hidden in strict local mode."
+}
diff --git a/src/ui/help/about/about.template.html b/src/ui/help/about/about.template.html
index 9a9169afd..380dbf4d2 100644
--- a/src/ui/help/about/about.template.html
+++ b/src/ui/help/about/about.template.html
@@ -1,7 +1,7 @@
 <div class="container-fluid">
   <div class="row mt-4 mb-4">
 
-    <a [href]="userDoc" target="_blank">
+    <a sxplr-hide-when-local [href]="userDoc" target="_blank">
       <button mat-raised-button color="primary">
         <i class="fas fa-book-open"></i>
         <span>
@@ -10,7 +10,7 @@
       </button>
     </a>
 
-    <a [href]="repoUrl" target="_blank">
+    <a sxplr-hide-when-local [href]="repoUrl" target="_blank">
       <button mat-flat-button>
         <i class="fab fa-github"></i>
         <span>
diff --git a/src/ui/help/module.ts b/src/ui/help/module.ts
index b99786401..5dded0948 100644
--- a/src/ui/help/module.ts
+++ b/src/ui/help/module.ts
@@ -7,6 +7,7 @@ import { AboutCmp } from './about/about.component'
 import { HelpOnePager } from "./helpOnePager/helpOnePager.component";
 import {QuickTourModule} from "src/ui/quickTour/module";
 import { HowToCite } from "./howToCite/howToCite.component";
+import { StrictLocalModule } from "src/strictLocal";
 
 @NgModule({
   imports: [
@@ -14,7 +15,8 @@ import { HowToCite } from "./howToCite/howToCite.component";
     AngularMaterialModule,
     ComponentsModule,
     UtilModule,
-    QuickTourModule
+    QuickTourModule,
+    StrictLocalModule,
   ],
   declarations: [
     AboutCmp,
-- 
GitLab