From db34b52b66311a72f986a0406acdb935369d264f Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 1 Jul 2019 12:38:51 -0400
Subject: added some context menu undo's

---
 src/client/views/TemplateMenu.tsx | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'src/client/views/TemplateMenu.tsx')

diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index a9bc4d3d2..a53c8749a 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -6,6 +6,7 @@ import './DocumentDecorations.scss';
 import { DocumentView } from "./nodes/DocumentView";
 import { Template } from "./Templates";
 import React = require("react");
+import { undoBatch } from "../util/UndoManager";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -39,6 +40,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
         super(props);
     }
 
+    @undoBatch
     @action
     toggleTemplate = (event: React.ChangeEvent<HTMLInputElement>, template: Template): void => {
         if (event.target.checked) {
-- 
cgit v1.2.3-70-g09d2


From ab2b2317e601b9e440f9c48b4639c143d5187949 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Mon, 1 Jul 2019 19:29:15 -0400
Subject: added tooltips and improved acm scraping

---
 src/client/views/DocumentDecorations.tsx |  2 +-
 src/client/views/GlobalKeyHandler.ts     |  2 +-
 src/client/views/MainView.tsx            |  6 ++--
 src/client/views/TemplateMenu.tsx        |  2 +-
 src/scraping/acm/index.js                | 56 +++++++++++++++++++++++++-------
 src/scraping/acm/results.txt             | 34 +++++++++++--------
 6 files changed, 71 insertions(+), 31 deletions(-)

(limited to 'src/client/views/TemplateMenu.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 61e9d209a..e1eff5cdc 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -692,7 +692,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 {this._edtingTitle ?
                     <input ref={this.keyinput} className="title" type="text" name="dynbox" value={this._title} onBlur={this.titleBlur} onChange={this.titleChanged} onKeyPress={this.titleEntered} /> :
                     <div className="title" onPointerDown={this.onTitleDown} ><span>{`${this.selectionTitle}`}</span></div>}
-                <div className="documentDecorations-closeButton" onPointerDown={this.onCloseDown}>X</div>
+                <div className="documentDecorations-closeButton" title="Close Document" onPointerDown={this.onCloseDown}>X</div>
                 <div id="documentDecorations-topLeftResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
                 <div id="documentDecorations-topResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
                 <div id="documentDecorations-topRightResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index e467d7c61..4c72bd683 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -13,7 +13,7 @@ type KeyControlInfo = {
 };
 
 export default class KeyManager {
-    public static Handler: KeyManager = new KeyManager();
+    public static Instance: KeyManager = new KeyManager();
     private router = new Map<string, KeyHandler>();
 
     constructor() {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index fb88c284f..a9d75d8cc 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -64,8 +64,8 @@ export class MainView extends React.Component {
     }
 
     componentWillMount() {
-        window.removeEventListener("keydown", KeyManager.Handler.handle);
-        window.addEventListener("keydown", KeyManager.Handler.handle);
+        window.removeEventListener("keydown", KeyManager.Instance.handle);
+        window.addEventListener("keydown", KeyManager.Instance.handle);
 
         window.removeEventListener("pointerdown", this.pointerDown);
         window.addEventListener("pointerdown", this.pointerDown);
@@ -78,7 +78,7 @@ export class MainView extends React.Component {
     pointerUp = (e: PointerEvent) => this.isPointerDown = false;
 
     componentWillUnMount() {
-        window.removeEventListener("keydown", KeyManager.Handler.handle);
+        window.removeEventListener("keydown", KeyManager.Instance.handle);
         window.removeEventListener("pointerdown", this.pointerDown);
         window.removeEventListener("pointerup", this.pointerUp);
     }
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index a9bc4d3d2..a1d59484a 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -79,7 +79,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
 
         return (
             <div className="templating-menu" >
-                <div className="templating-button" onClick={() => this.toggleTemplateActivity()}>+</div>
+                <div title="Template Options" className="templating-button" onClick={() => this.toggleTemplateActivity()}>+</div>
                 <ul id="template-list" style={{ display: this._hidden ? "none" : "block" }}>
                     {templateMenu}
                 </ul>
diff --git a/src/scraping/acm/index.js b/src/scraping/acm/index.js
index ff4b099e7..ad0f844ba 100644
--- a/src/scraping/acm/index.js
+++ b/src/scraping/acm/index.js
@@ -10,6 +10,17 @@ const {
 const driver_pause = 500; // milliseconds
 const sample_line_char_max = 100; // characters
 const target_browser = 'chrome';
+const tab_map = {
+    abstract: "11",
+    authors: "14",
+    references: "15",
+    cited_by: "16",
+    index_terms: "17",
+    publication: "18",
+    reviews: "19",
+    comments: "20",
+    table_of_contents: "21"
+};
 
 // GENERAL UTILITY FUNCTIONS
 
@@ -32,14 +43,18 @@ function log_snippet(result, quotes = true) {
             snippet = quotes ? `"${snippet}"` : snippet;
             break;
         case "object":
-            snippet = result.map(res => {
-                switch (typeof res) {
-                    case "string":
-                        return res.substring(0, sample_line_char_max / result.length);
-                    case "object":
-                        return res[Object.keys(res)[0]];
-                }
-            }).join(', ');
+            if (Array.isArray(result)) {
+                snippet = result.map(res => {
+                    switch (typeof res) {
+                        case "string":
+                            return res.substring(0, sample_line_char_max / result.length);
+                        case "object":
+                            return res[Object.keys(res)[0]];
+                    }
+                }).join(', ');
+            } else {
+                snippet = result[Object.keys(result)[0]];
+            }
     }
     console.log(snippet);
     return result;
@@ -57,6 +72,10 @@ async function click_on(ref) {
     await driver.sleep(driver_pause);
 }
 
+async function click_on_acm_tab(target) {
+    await click_on(`//*[@id="tab-10${tab_map[target]}-btnInnerEl"]/span`);
+}
+
 async function locate(ref, multiple = false) {
     let locator = ref.startsWith("//") ? By.xpath(ref) : By.id(ref);
     return await multiple ? driver.findElements(locator) : driver.findElement(locator);
@@ -84,8 +103,6 @@ async function logged_assign(key, value) {
 // TEXT SCRAPING
 
 async function read_authors() {
-    await click_on('//*[@id="tab-1014-btnInnerEl"]/span');
-
     let authors = await text_of('//*[@id="tabpanel-1009-body"]');
     let sanitize = line => line.length > 0 && !(line.startsWith("No contact information") || line.startsWith("View colleagues of") || line.startsWith("Bibliometrics:"));
     let author_lines = authors.split("\n").map(line => line.trim()).filter(sanitize);
@@ -106,6 +123,17 @@ async function read_authors() {
     return all_authors;
 }
 
+async function read_publication() {
+    let publciation_elements = (await text_of("source-body")).split("\n");
+    let publication_module = {};
+    for (let element of publciation_elements) {
+        if (element.startsWith("Title")) {
+            publication_module.title = element.substring(6);
+        }
+    }
+    return publication_module;
+}
+
 // JSON / DASH CONVERSION AND EXPORT
 
 function parse_authors(metadata) {
@@ -134,7 +162,7 @@ function write_results() {
     results.forEach(res => output += (JSON.stringify(res, null, 4) + "\n"));
 
     writeFile("./results.txt", output, function errorHandler(exception) {
-        console.log(exception || "scraped references successfully written as JSON to ./results.txt\n");
+        console.log(exception || "scraped references successfully written as JSON to ./results.txt");
     });
 }
 
@@ -157,12 +185,18 @@ async function scrape_targets(error, data) {
             let id = references[i];
             let url = `https://dl.acm.org/citation.cfm?id=${id}`;
             console.log(`\nscraping ${i + 1}/${quota} (${id})`);
+
             await navigate_to(url);
 
             logged_assign("url", url);
             logged_assign("title", await text_of('//*[@id="divmain"]/div/h1'));
             logged_assign("abstract", (await text_of_all("abstract-body")).join(" "));
+
+            await click_on_acm_tab("authors");
             logged_assign("authors", (await read_authors()).map(parse_authors));
+
+            await click_on_acm_tab("publication");
+            logged_assign("publication", await read_publication());
         } catch (e) {
             console.log(e);
             await driver.quit();
diff --git a/src/scraping/acm/results.txt b/src/scraping/acm/results.txt
index fffa7ff51..ba66d61a7 100644
--- a/src/scraping/acm/results.txt
+++ b/src/scraping/acm/results.txt
@@ -10,10 +10,10 @@
             "publication_count": 1,
             "citation_count": 179,
             "available_for_download": 1,
-            "downloads_6_weeks": 130,
-            "downloads_12_months": 1004,
-            "downloads_cumulative": 9792,
-            "average_downloads_per_article": 9792,
+            "downloads_6_weeks": 123,
+            "downloads_12_months": 922,
+            "downloads_cumulative": 9793,
+            "average_downloads_per_article": 9793,
             "average_citations_per_article": 179
         },
         {
@@ -23,10 +23,10 @@
             "publication_count": 5,
             "citation_count": 196,
             "available_for_download": 1,
-            "downloads_6_weeks": 130,
-            "downloads_12_months": 1004,
-            "downloads_cumulative": 9792,
-            "average_downloads_per_article": 9792,
+            "downloads_6_weeks": 123,
+            "downloads_12_months": 922,
+            "downloads_cumulative": 9793,
+            "average_downloads_per_article": 9793,
             "average_citations_per_article": 39.2
         },
         {
@@ -36,13 +36,16 @@
             "publication_count": 2,
             "citation_count": 188,
             "available_for_download": 2,
-            "downloads_6_weeks": 130,
-            "downloads_12_months": 1009,
-            "downloads_cumulative": 10023,
-            "average_downloads_per_article": 5011.5,
+            "downloads_6_weeks": 123,
+            "downloads_12_months": 927,
+            "downloads_cumulative": 10024,
+            "average_downloads_per_article": 5012,
             "average_citations_per_article": 94
         }
-    ]
+    ],
+    "publication": {
+        "title": "Journal of the ACM (JACM) JACM Homepage table of contents archive"
+    }
 }
 {
     "url": "https://dl.acm.org/citation.cfm?id=2412979",
@@ -62,5 +65,8 @@
             "average_downloads_per_article": 0,
             "average_citations_per_article": 0
         }
-    ]
+    ],
+    "publication": {
+        "title": "IEEE Transactions on Software Engineering table of contents archive"
+    }
 }
-- 
cgit v1.2.3-70-g09d2


From 16822d88f981e7a86729d942a92b6ad8590680e4 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 1 Jul 2019 22:32:44 -0400
Subject: fixed title template view issue

---
 src/client/views/TemplateMenu.tsx                      | 8 ++++++++
 src/client/views/Templates.tsx                         | 4 ++--
 src/client/views/collections/CollectionDockingView.tsx | 2 +-
 src/client/views/nodes/DocumentView.tsx                | 5 +++++
 4 files changed, 16 insertions(+), 3 deletions(-)

(limited to 'src/client/views/TemplateMenu.tsx')

diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index d63f45e5a..1b32f0ddd 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -64,6 +64,13 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
         }
     }
 
+    @undoBatch
+    @action
+    clearTemplates = (event: React.MouseEvent) => {
+        this.props.docs.map(d => d.clearTemplates());
+        Array.from(this.props.templates.keys()).map(t => this.props.templates.set(t, false));
+    }
+
     @action
     componentWillReceiveProps(nextProps: TemplateMenuProps) {
         // this._templates = nextProps.templates;
@@ -84,6 +91,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
                 <div title="Template Options" className="templating-button" onClick={() => this.toggleTemplateActivity()}>+</div>
                 <ul id="template-list" style={{ display: this._hidden ? "none" : "block" }}>
                     {templateMenu}
+                    <button style={{ display: this._hidden ? "none" : "block" }} onClick={this.clearTemplates}>Clear</button>
                 </ul>
             </div>
         );
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index 5bb8d454a..4843a70a6 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -50,7 +50,7 @@ export namespace Templates {
     export const Title = new Template("Title", TemplatePosition.InnerTop,
         `<div>
             <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; z-index: 100">
-                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.DataDoc.title}</span>
+                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
             </div>
             <div style="height:calc(100% - 25px);">
                 <div style="width:100%;overflow:auto">{layout}</div>
@@ -58,7 +58,7 @@ export namespace Templates {
         </div>` );
 
     export const Header = new Template("Header", TemplatePosition.InnerTop,
-        `< div style = "display:flex; flex-direction:column; height:100%;" >
+        `<div style = "display:flex; flex-direction:column; height:100%;" >
             <div style="width:100%; background-color: rgba(0, 0, 0, .4); color: white; ">
                 <FormattedTextBox {...props} height={"min-content"} color={"white"} fieldKey={"header"} />
             </div>
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index ad5472a4a..8724216f5 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -269,7 +269,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         var cur = this._containerRef.current;
 
         // bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed
-        this._goldenLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height);
+        this._goldenLayout && this._goldenLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height);
     }
 
     @action
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 687c7f73d..3673cb0e2 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -473,6 +473,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
         this.templates = this.templates;
     }
+    @action
+    clearTemplates = () => {
+        this.templates.length = 0;
+        this.templates = this.templates;
+    }
 
     @undoBatch
     @action
-- 
cgit v1.2.3-70-g09d2

