Files: 43af34efb145e2705ff168ae3e6f3cc6832314ac / editor-view.js
3711 bytesRaw
1 | const h = require('hyperscript') |
2 | const ho = require('hyperobj') |
3 | const observable = require('observable') |
4 | |
5 | const Menubar = require('./renderers/menubar') |
6 | const JsonEditor = require('./json-editor') |
7 | |
8 | let renderMenu = ho( |
9 | Menubar(), |
10 | Menubar().renderItem |
11 | ) |
12 | |
13 | module.exports = function(parent, ssb, config) { |
14 | config = config || {} |
15 | let customRender = config.editor && config.editor.render || function () {} |
16 | |
17 | let renderPreviewEditor = ho( |
18 | function(value) { |
19 | if (typeof value === 'undefined') return h('span.undefined', '[undefined]') |
20 | if (value === null) return h('span.null', '[null]') |
21 | }, |
22 | customRender(ssb), |
23 | ...require('./default-renderers')(config) |
24 | ) |
25 | |
26 | let toolbar, container, jsonContainer, previewContainer |
27 | parent.appendChild(toolbar = h('.toolbar')) |
28 | // NOTE: these nested containers need to be of class .editor-container |
29 | // to make resizing of code-mirror work properly when the browser window |
30 | // is resized. |
31 | parent.appendChild(container = h('.editor-container')) |
32 | container.appendChild(jsonContainer = h('.editor-container.cm-wrapper')) |
33 | container.appendChild(previewContainer = h('.editor-container.preview-wrapper')) |
34 | |
35 | let menubar = renderMenu({ |
36 | type: 'menubar', |
37 | right: [{ |
38 | key: 'preview', |
39 | value: { label: 'Preview' } |
40 | }, { |
41 | key: 'json', |
42 | value: { label: 'Json'} |
43 | }], |
44 | }) |
45 | toolbar.appendChild(menubar) |
46 | menubar.activate('json') |
47 | |
48 | let change = observable() |
49 | |
50 | let currMessageId = null |
51 | const editor = JsonEditor({ |
52 | container: jsonContainer, |
53 | blobs: ssb.blobs |
54 | }) |
55 | |
56 | editor.on('changes', (e)=>change(e) ) |
57 | |
58 | let previewEditor |
59 | function showPreviewEditor(value, key) { |
60 | removePreviewEditor() |
61 | if (config.sbot.cms.kiosk) return |
62 | // only render preview if our value is parsable JSON |
63 | let msg |
64 | try { |
65 | msg = JSON.parse(value) |
66 | } catch(e) { |
67 | console.error('parsing failed', value) |
68 | return |
69 | } |
70 | previewEditor = renderPreviewEditor(msg, [key]) |
71 | if (previewEditor) { |
72 | previewContainer.appendChild(previewEditor) |
73 | } |
74 | } |
75 | |
76 | function removePreviewEditor() { |
77 | if (previewEditor) { |
78 | previewEditor.parentElement.removeChild(previewEditor) |
79 | previewEditor = null |
80 | } |
81 | } |
82 | |
83 | menubar.activeItem( (item)=>{ |
84 | let key = item.getAttribute('data-key') |
85 | if (key === 'json') { |
86 | jsonContainer.style.display = 'block' |
87 | editor.show() |
88 | } else { |
89 | editor.hide() |
90 | jsonContainer.style.display = 'none' |
91 | } |
92 | |
93 | removePreviewEditor() |
94 | if (key === 'preview') { |
95 | let value = editor.getValue() |
96 | showPreviewEditor(value, currMessageId) |
97 | } |
98 | }) |
99 | |
100 | return { |
101 | change, |
102 | clean: editor.clean, |
103 | setValue: (value, key) => { |
104 | currMessageId = key |
105 | if (value && previewEditor) { |
106 | showPreviewEditor(value, key) |
107 | } |
108 | let cursor = editor.getCursor() |
109 | editor.setValue(value) |
110 | editor.setSelection(cursor, cursor) |
111 | }, |
112 | getValue: editor.getValue.bind(editor), |
113 | clearHistory: editor.clearHistory.bind(editor), |
114 | renderPreviewEditor, |
115 | adjustSize: ()=>editor.show() |
116 | } |
117 | } |
118 | |
119 | module.exports.css = ()=> ` |
120 | .editor-container { |
121 | flex: 1 0; |
122 | position: relative; |
123 | overflow: hidden; |
124 | display: flex; |
125 | flex-direction: column; |
126 | } |
127 | .editor-container.cm-wrapper { |
128 | flex: 1 0 100%; |
129 | } |
130 | .editor-container.preview-wrapper { |
131 | background: #eee; |
132 | overflow: scroll; |
133 | display: block; |
134 | } |
135 | .editor-container>.toolbar { |
136 | display: flex; |
137 | align-items: flex-end; |
138 | flex-direction: row; |
139 | } |
140 | .editor-container>.toolbar>.menubar { |
141 | flex: 1 1 auto; |
142 | background: unset; |
143 | } |
144 | .editor-container>.toolbar>.menubar>.right>.menu-item.active { |
145 | background: #fff; |
146 | color: #888; |
147 | } |
148 | ` |
149 |
Built with git-ssb-web