From 5e4571bfc17a00a88a480f208bfd87a2ddfa0201 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Thu, 11 Jun 2020 19:29:06 -0500 Subject: [PATCH 1/5] decaffeinate views --- lib/ui/views.coffee | 137 --------------------------------- lib/ui/views.js | 183 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 137 deletions(-) delete mode 100644 lib/ui/views.coffee create mode 100644 lib/ui/views.js diff --git a/lib/ui/views.coffee b/lib/ui/views.coffee deleted file mode 100644 index dc278d92..00000000 --- a/lib/ui/views.coffee +++ /dev/null @@ -1,137 +0,0 @@ -Highlighter = require './highlighter' - -{client} = require '../connection' -{once} = require '../misc' - -getlazy = client.import 'getlazy' - -module.exports = views = - dom: ({tag, attrs, contents}, opts) -> - view = document.createElement tag - for k, v of attrs - if v instanceof Array then v = v.join ' ' - view.setAttribute k, v - if contents? - if contents.constructor isnt Array - contents = [contents] - for child in contents - view.appendChild @render child, opts - view - - html: ({content, block = false}) -> - view = @render if block then @tags.div() else @tags.span() - view.innerHTML = content - view = if view.children.length == 1 then view.children[0] else view - - tree: ({head, children, expand}, opts) -> - @ink.tree.treeView(@render(head, opts), - children.map((x)=>@render(@tags.div([x]), opts)), - expand: expand) - - lazy: ({head, id}, opts) -> - conn = client.conn - if opts.registerLazy? - opts.registerLazy id - else - console.warn 'Unregistered lazy view' - view = @ink.tree.treeView @render(head, opts), [], - onToggle: once => - return unless client.conn == conn - getlazy(id).then (children) => - body = view.querySelector ':scope > .body' - children.map((x) => @render(@tags.div([x]), opts)).forEach (x) => - body.appendChild(@ink.ansiToHTML(x)) - - subtree: ({label, child}, opts) -> - @render (if child.type == "tree" - type: "tree" - head: @tags.span [label, child.head] - children: child.children - # children: child.children.map((x) => @tags.span "gutted", x) - else - @tags.span "gutted", [label, child]), opts - - copy: ({view, text}, opts) -> - view = @render view, opts - atom.commands.add view, - 'core:copy': (e) -> - atom.clipboard.write text - e.stopPropagation() - view - - link: ({file, line, contents}) -> - view = @render @tags.a {href: '#'}, contents - # TODO: maybe need to dispose of the tooltip onclick and readd them, but - # that doesn't seem to be necessary - if @ink.Opener.isUntitled(file) - tt = atom.tooltips.add view, title: -> 'untitled' - else - tt = atom.tooltips.add view, title: -> file - view.onclick = (e) => - @ink.Opener.open(file, line, { - pending: atom.config.get('core.allowPendingPaneItems') - }) - e.stopPropagation() - view.addEventListener 'DOMNodeRemovedFromDocument', => - tt.dispose() - view - - number: ({value, full}) -> - rounded = value.toPrecision(3) - rounded += '…' unless rounded.toString().length >= full.length - view = @render @tags.span 'syntax--constant syntax--numeric', rounded - isfull = false - view.onclick = (e) -> - view.innerText = if !isfull then full else rounded - isfull = !isfull - e.stopPropagation() - view - - code: ({text, attrs, scope}) -> - grammar = atom.grammars.grammarForScopeName("source.julia") - block = attrs?.block || false - highlighted = Highlighter.highlight(text, grammar, {scopePrefix: 'syntax--', block}) - @render {type: 'html', block, content: highlighted} - - latex: ({attrs, text}) -> - block = attrs?.block || false - latex = @ink.KaTeX.texify(text, block) - @render {type: 'html', block, content: latex} - - views: - dom: (a...) -> views.dom a... - html: (a...) -> views.html a... - tree: (a...) -> views.tree a... - lazy: (a...) -> views.lazy a... - subtree: (a...) -> views.subtree a... - link: (a...) -> views.link a... - copy: (a...) -> views.copy a... - number: (a...) -> views.number a... - code: (a...) -> views.code a... - latex: (a...) -> views.latex a... - - render: (data, opts = {}) -> - if @views.hasOwnProperty(data.type) - r = @views[data.type](data, opts) - @ink.ansiToHTML(r) - r - else if data?.constructor is String - new Text data - else - @render "julia-client: can't render #{data?.type}" - - tag: (tag, attrs, contents) -> - if attrs?.constructor is String - attrs = class: attrs - if attrs?.constructor isnt Object - [contents, attrs] = [attrs, undefined] - type: 'dom' - tag: tag - attrs: attrs - contents: contents - - tags: {} - -['div', 'span', 'a', 'strong', 'table', 'tr', 'td', 'webview'].forEach (tag) -> - views.tags[tag] = (attrs, contents) -> - views.tag tag, attrs, contents diff --git a/lib/ui/views.js b/lib/ui/views.js new file mode 100644 index 00000000..4246b2ed --- /dev/null +++ b/lib/ui/views.js @@ -0,0 +1,183 @@ +'use babel' +import * as Highlighter from './highlighter'; +import client from '../connection/client'; +import { once } from '../misc'; + +const getlazy = client.import('getlazy'); + +let views; +export default views = { + dom({tag, attrs, contents}, opts) { + const view = document.createElement(tag); + for (let k in attrs) { + let v = attrs[k]; + if (v instanceof Array) { v = v.join(' '); } + view.setAttribute(k, v); + } + if (contents != null) { + if (contents.constructor !== Array) { + contents = [contents]; + } + for (let child of contents) { + view.appendChild(this.render(child, opts)); + } + } + return view; + }, + + html(...args) { + const obj = args[0], + { + content + } = obj, + val = obj.block, + block = val != null ? val : false; + let view = this.render(block ? this.tags.div() : this.tags.span()); + view.innerHTML = content; + return view = view.children.length === 1 ? view.children[0] : view; + }, + + tree({head, children, expand}, opts) { + this.ink.tree.treeView(this.render(head, opts), + children.map(x=> this.render(this.tags.div([x]), opts)), + {expand}); + }, + + lazy({head, id}, opts) { + const conn = client.conn; + if (opts.registerLazy != null) { + opts.registerLazy(id); + } else { + console.warn('Unregistered lazy view'); + } + let view; + return view = this.ink.tree.treeView(this.render(head, opts), [], { + onToggle: once(() => { + if (client.conn !== conn) { return; } + getlazy(id).then(children => { + const body = view.querySelector(':scope > .body'); + children.map(x => this.render(this.tags.div([x]), opts)).forEach(x => { + body.appendChild(this.ink.ansiToHTML(x)); + }); + }); + }) + } + ); + }, + + subtree({label, child}, opts) { + return this.render((child.type === "tree" ?{ + type: "tree", + head: this.tags.span([label, child.head]), + children: child.children + } + // children: child.children.map((x) => @tags.span "gutted", x) + : + this.tags.span("gutted", [label, child])), opts); + }, + + copy({view, text}, opts) { + view = this.render(view, opts); + atom.commands.add(view, { + 'core:copy'(e) { + atom.clipboard.write(text); + e.stopPropagation(); + } + } + ); + return view; + }, + + link({file, line, contents}) { + const view = this.render(this.tags.a({href: '#'}, contents)); + // TODO: maybe need to dispose of the tooltip onclick and readd them, but + // that doesn't seem to be necessary + let tt; + if (this.ink.Opener.isUntitled(file)) { + tt = atom.tooltips.add(view, {title() { return 'untitled'; }}); + } else { + tt = atom.tooltips.add(view, {title() { return file; }}); + } + view.onclick = e => { + this.ink.Opener.open(file, line, { + pending: atom.config.get('core.allowPendingPaneItems') + }); + e.stopPropagation(); + }; + view.addEventListener('DOMNodeRemovedFromDocument', () => { + tt.dispose(); + }); + return view; + }, + + number({value, full}) { + let rounded = value.toPrecision(3); + if (rounded.toString().length < full.length) { rounded += '…'; } + const view = this.render(this.tags.span('syntax--constant syntax--numeric', rounded)); + let isfull = false; + view.onclick = function(e) { + view.innerText = !isfull ? full : rounded; + isfull = !isfull; + e.stopPropagation(); + }; + return view; + }, + + code({text, attrs, scope}) { + const grammar = atom.grammars.grammarForScopeName("source.julia"); + const block = (attrs != null ? attrs.block : undefined) || false; // attrs?.block || false + const highlighted = Highlighter.highlight(text, grammar, {scopePrefix: 'syntax--', block}); + return this.render({type: 'html', block, content: highlighted}); + }, + + latex({attrs, text}) { + const block = (attrs != null ? attrs.block : undefined) || false; // attrs?.block || false + const latex = this.ink.KaTeX.texify(text, block); + return this.render({type: 'html', block, content: latex}); + }, + + views: { + // TODO Remove unnecessary use of Array.from + dom(...a) { return views.dom(...Array.from(a || [])); }, + html(...a) { return views.html(...Array.from(a || [])); }, + tree(...a) { return views.tree(...Array.from(a || [])); }, + lazy(...a) { return views.lazy(...Array.from(a || [])); }, + subtree(...a) { return views.subtree(...Array.from(a || [])); }, + link(...a) { return views.link(...Array.from(a || [])); }, + copy(...a) { return views.copy(...Array.from(a || [])); }, + number(...a) { return views.number(...Array.from(a || [])); }, + code(...a) { return views.code(...Array.from(a || [])); }, + latex(...a) { return views.latex(...Array.from(a || [])); } + }, + + render(data, opts = {}) { + if (this.views.hasOwnProperty(data.type)) { + const r = this.views[data.type](data, opts); + this.ink.ansiToHTML(r); + return r; + } else if ((data != null ? data.constructor : undefined) === String) { // data?.constructor === String + return new Text(data); + } else { + return this.render(`julia-client: can't render ${(data != null ? data.type : undefined)}`); // data?.type + } + }, + + tag(tag, attrs, contents) { + if ((attrs != null ? attrs.constructor : undefined) === String) { // attrs?.constructor === String + attrs = {class: attrs}; + } + if ((attrs != null ? attrs.constructor : undefined) !== Object) { // attrs?.constructor !== Object + [contents, attrs] = [attrs, undefined]; + } + return { + type: 'dom', + tag, + attrs, + contents + }; + }, + + tags: {} +}; + +['div', 'span', 'a', 'strong', 'table', 'tr', 'td', 'webview'].forEach(tag => views.tags[tag] = (attrs, contents) => views.tag(tag, attrs, contents)); From f4f30de4fd5ca465d35f449b45f304acceaaa525 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Thu, 11 Jun 2020 23:44:39 -0500 Subject: [PATCH 2/5] remove array.from --- lib/ui/views.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/ui/views.js b/lib/ui/views.js index 4246b2ed..5261966d 100644 --- a/lib/ui/views.js +++ b/lib/ui/views.js @@ -138,16 +138,16 @@ export default views = { views: { // TODO Remove unnecessary use of Array.from - dom(...a) { return views.dom(...Array.from(a || [])); }, - html(...a) { return views.html(...Array.from(a || [])); }, - tree(...a) { return views.tree(...Array.from(a || [])); }, - lazy(...a) { return views.lazy(...Array.from(a || [])); }, - subtree(...a) { return views.subtree(...Array.from(a || [])); }, - link(...a) { return views.link(...Array.from(a || [])); }, - copy(...a) { return views.copy(...Array.from(a || [])); }, - number(...a) { return views.number(...Array.from(a || [])); }, - code(...a) { return views.code(...Array.from(a || [])); }, - latex(...a) { return views.latex(...Array.from(a || [])); } + dom(...a) { return views.dom(...a); }, + html(...a) { return views.html(...a); }, + tree(...a) { return views.tree(...a); }, + lazy(...a) { return views.lazy(...a); }, + subtree(...a) { return views.subtree(...a); }, + link(...a) { return views.link(...a); }, + copy(...a) { return views.copy(...a); }, + number(...a) { return views.number(...a); }, + code(...a) { return views.code(...a); }, + latex(...a) { return views.latex(...a); } }, render(data, opts = {}) { From 5c4a98ddd3079ccfa88c6ffc136784129b4a362e Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Thu, 11 Jun 2020 19:49:20 -0500 Subject: [PATCH 3/5] named export views in ui already fixed in the other PR --- lib/ui/docs.js | 2 +- lib/ui/views.js | 120 ++++++++++++++++++++++++------------------------ 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/lib/ui/docs.js b/lib/ui/docs.js index 3f936872..59565492 100644 --- a/lib/ui/docs.js +++ b/lib/ui/docs.js @@ -2,7 +2,7 @@ import { CompositeDisposable } from 'atom' import { client } from '../connection' -const views = require('./views') +import * as views from './views' import goto from '../runtime/goto' const { diff --git a/lib/ui/views.js b/lib/ui/views.js index 5261966d..a2351b42 100644 --- a/lib/ui/views.js +++ b/lib/ui/views.js @@ -5,9 +5,8 @@ import { once } from '../misc'; const getlazy = client.import('getlazy'); -let views; -export default views = { - dom({tag, attrs, contents}, opts) { + +export function dom({tag, attrs, contents}, opts) { const view = document.createElement(tag); for (let k in attrs) { let v = attrs[k]; @@ -19,31 +18,31 @@ export default views = { contents = [contents]; } for (let child of contents) { - view.appendChild(this.render(child, opts)); + view.appendChild(render(child, opts)); } } return view; - }, +} - html(...args) { +export function html(...args) { const obj = args[0], { content } = obj, val = obj.block, block = val != null ? val : false; - let view = this.render(block ? this.tags.div() : this.tags.span()); + let view = render(block ? tags.div() : tags.span()); view.innerHTML = content; return view = view.children.length === 1 ? view.children[0] : view; - }, +} - tree({head, children, expand}, opts) { - this.ink.tree.treeView(this.render(head, opts), - children.map(x=> this.render(this.tags.div([x]), opts)), +export function tree({head, children, expand}, opts) { + this.ink.tree.treeView(render(head, opts), + children.map(x=> render(tags.div([x]), opts)), {expand}); - }, +} - lazy({head, id}, opts) { +export function lazy({head, id}, opts) { const conn = client.conn; if (opts.registerLazy != null) { opts.registerLazy(id); @@ -51,33 +50,33 @@ export default views = { console.warn('Unregistered lazy view'); } let view; - return view = this.ink.tree.treeView(this.render(head, opts), [], { + return view = this.ink.tree.treeView(render(head, opts), [], { onToggle: once(() => { if (client.conn !== conn) { return; } getlazy(id).then(children => { const body = view.querySelector(':scope > .body'); - children.map(x => this.render(this.tags.div([x]), opts)).forEach(x => { + children.map(x => render(tags.div([x]), opts)).forEach(x => { body.appendChild(this.ink.ansiToHTML(x)); }); }); }) } ); - }, +} - subtree({label, child}, opts) { - return this.render((child.type === "tree" ?{ +export function subtree({label, child}, opts) { + return render((child.type === "tree" ?{ type: "tree", - head: this.tags.span([label, child.head]), + head: tags.span([label, child.head]), children: child.children } // children: child.children.map((x) => @tags.span "gutted", x) : - this.tags.span("gutted", [label, child])), opts); - }, + tags.span("gutted", [label, child])), opts); +} - copy({view, text}, opts) { - view = this.render(view, opts); +export function copy({view, text}, opts) { + view = render(view, opts); atom.commands.add(view, { 'core:copy'(e) { atom.clipboard.write(text); @@ -86,10 +85,10 @@ export default views = { } ); return view; - }, +} - link({file, line, contents}) { - const view = this.render(this.tags.a({href: '#'}, contents)); +export function link({file, line, contents}) { + const view = render(tags.a({href: '#'}, contents)); // TODO: maybe need to dispose of the tooltip onclick and readd them, but // that doesn't seem to be necessary let tt; @@ -108,12 +107,12 @@ export default views = { tt.dispose(); }); return view; - }, +} - number({value, full}) { +export function number({value, full}) { let rounded = value.toPrecision(3); if (rounded.toString().length < full.length) { rounded += '…'; } - const view = this.render(this.tags.span('syntax--constant syntax--numeric', rounded)); + const view = render(tags.span('syntax--constant syntax--numeric', rounded)); let isfull = false; view.onclick = function(e) { view.innerText = !isfull ? full : rounded; @@ -121,48 +120,48 @@ export default views = { e.stopPropagation(); }; return view; - }, +} - code({text, attrs, scope}) { +export function code({text, attrs, scope}) { const grammar = atom.grammars.grammarForScopeName("source.julia"); const block = (attrs != null ? attrs.block : undefined) || false; // attrs?.block || false const highlighted = Highlighter.highlight(text, grammar, {scopePrefix: 'syntax--', block}); - return this.render({type: 'html', block, content: highlighted}); - }, + return render({type: 'html', block, content: highlighted}); +} - latex({attrs, text}) { +export function latex({attrs, text}) { const block = (attrs != null ? attrs.block : undefined) || false; // attrs?.block || false const latex = this.ink.KaTeX.texify(text, block); - return this.render({type: 'html', block, content: latex}); - }, + return render({type: 'html', block, content: latex}); +} - views: { +export const views = { // TODO Remove unnecessary use of Array.from - dom(...a) { return views.dom(...a); }, - html(...a) { return views.html(...a); }, - tree(...a) { return views.tree(...a); }, - lazy(...a) { return views.lazy(...a); }, - subtree(...a) { return views.subtree(...a); }, - link(...a) { return views.link(...a); }, - copy(...a) { return views.copy(...a); }, - number(...a) { return views.number(...a); }, - code(...a) { return views.code(...a); }, - latex(...a) { return views.latex(...a); } - }, - - render(data, opts = {}) { - if (this.views.hasOwnProperty(data.type)) { - const r = this.views[data.type](data, opts); + dom(...a) { return dom(...a); }, + html(...a) { return html(...a); }, + tree(...a) { return tree(...a); }, + lazy(...a) { return lazy(...a); }, + subtree(...a) { return subtree(...a); }, + link(...a) { return link(...a); }, + copy(...a) { return copy(...a); }, + number(...a) { return number(...a); }, + code(...a) { return code(...a); }, + latex(...a) { return latex(...a); } +} + +export function render(data, opts = {}) { + if (views.hasOwnProperty(data.type)) { + const r = views[data.type](data, opts); this.ink.ansiToHTML(r); return r; } else if ((data != null ? data.constructor : undefined) === String) { // data?.constructor === String return new Text(data); } else { - return this.render(`julia-client: can't render ${(data != null ? data.type : undefined)}`); // data?.type + return render(`julia-client: can't render ${(data != null ? data.type : undefined)}`); // data?.type } - }, +} - tag(tag, attrs, contents) { +export function tag(tag, attrs, contents) { if ((attrs != null ? attrs.constructor : undefined) === String) { // attrs?.constructor === String attrs = {class: attrs}; } @@ -175,9 +174,10 @@ export default views = { attrs, contents }; - }, - - tags: {} -}; +} -['div', 'span', 'a', 'strong', 'table', 'tr', 'td', 'webview'].forEach(tag => views.tags[tag] = (attrs, contents) => views.tag(tag, attrs, contents)); +export let tags = {} +const tags_arr = ['div', 'span', 'a', 'strong', 'table', 'tr', 'td', 'webview'] +for (let _tag of tags_arr) { + tags[_tag] = (attrs, contents) => tag(_tag, attrs, contents) +} From ccfaa7120c1975b66b65b0f74d10519bbbd6767b Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Thu, 11 Jun 2020 20:01:05 -0500 Subject: [PATCH 4/5] views.activate --- lib/ui.coffee | 2 +- lib/ui/views.js | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/ui.coffee b/lib/ui.coffee index caf613e8..27b3ebea 100644 --- a/lib/ui.coffee +++ b/lib/ui.coffee @@ -31,7 +31,7 @@ module.exports = @subs.dispose() consumeInk: (@ink) -> - @views.ink = @ink + @views.activate(@ink) @selector.activate(@ink) @docpane.activate(@ink) @progress.activate(@ink) diff --git a/lib/ui/views.js b/lib/ui/views.js index a2351b42..3268ee7b 100644 --- a/lib/ui/views.js +++ b/lib/ui/views.js @@ -5,6 +5,10 @@ import { once } from '../misc'; const getlazy = client.import('getlazy'); +let ink; +export function activate (ink_in) { + ink = ink_in +} export function dom({tag, attrs, contents}, opts) { const view = document.createElement(tag); @@ -37,7 +41,7 @@ export function html(...args) { } export function tree({head, children, expand}, opts) { - this.ink.tree.treeView(render(head, opts), + ink.tree.treeView(render(head, opts), children.map(x=> render(tags.div([x]), opts)), {expand}); } @@ -50,13 +54,13 @@ export function lazy({head, id}, opts) { console.warn('Unregistered lazy view'); } let view; - return view = this.ink.tree.treeView(render(head, opts), [], { + return view = ink.tree.treeView(render(head, opts), [], { onToggle: once(() => { if (client.conn !== conn) { return; } getlazy(id).then(children => { const body = view.querySelector(':scope > .body'); children.map(x => render(tags.div([x]), opts)).forEach(x => { - body.appendChild(this.ink.ansiToHTML(x)); + body.appendChild(ink.ansiToHTML(x)); }); }); }) @@ -92,13 +96,13 @@ export function link({file, line, contents}) { // TODO: maybe need to dispose of the tooltip onclick and readd them, but // that doesn't seem to be necessary let tt; - if (this.ink.Opener.isUntitled(file)) { + if (ink.Opener.isUntitled(file)) { tt = atom.tooltips.add(view, {title() { return 'untitled'; }}); } else { tt = atom.tooltips.add(view, {title() { return file; }}); } view.onclick = e => { - this.ink.Opener.open(file, line, { + ink.Opener.open(file, line, { pending: atom.config.get('core.allowPendingPaneItems') }); e.stopPropagation(); @@ -131,7 +135,7 @@ export function code({text, attrs, scope}) { export function latex({attrs, text}) { const block = (attrs != null ? attrs.block : undefined) || false; // attrs?.block || false - const latex = this.ink.KaTeX.texify(text, block); + const latex = ink.KaTeX.texify(text, block); return render({type: 'html', block, content: latex}); } @@ -152,7 +156,7 @@ export const views = { export function render(data, opts = {}) { if (views.hasOwnProperty(data.type)) { const r = views[data.type](data, opts); - this.ink.ansiToHTML(r); + ink.ansiToHTML(r); return r; } else if ((data != null ? data.constructor : undefined) === String) { // data?.constructor === String return new Text(data); From 0f3ffacd4a81fda4fb41aeca85cbb9e0299bcfcc Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Thu, 11 Jun 2020 23:51:08 -0500 Subject: [PATCH 5/5] TODO ...a --- lib/ui/views.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/views.js b/lib/ui/views.js index 3268ee7b..9261c237 100644 --- a/lib/ui/views.js +++ b/lib/ui/views.js @@ -140,7 +140,7 @@ export function latex({attrs, text}) { } export const views = { - // TODO Remove unnecessary use of Array.from + // TODO do we need ...a dom(...a) { return dom(...a); }, html(...a) { return html(...a); }, tree(...a) { return tree(...a); },