@@ -86,20 +86,71 @@ const formatOneListResult = options => (entity, idx, A) => {
86
86
prefix.appendChild(prettyType)*/
87
87
88
88
/** add a cell to the current row of the list view we] are generating. "entityName" is the current row */
89
- const addCell = ( className , value , innerClassName = '' , parent = entityName ) => {
89
+ const addCell = ( className , value , innerClassName = '' , parent = entityName , onclick , watch ) => {
90
90
const cell = document . createElement ( 'span' ) ,
91
91
inner = document . createElement ( 'span' )
92
92
cell . className = className
93
93
inner . className = innerClassName
94
- inner . appendChild ( value . nodeName ? value : document . createTextNode ( value . toString ( ) ) )
94
+ if ( value ) {
95
+ inner . appendChild ( value . nodeName ? value : document . createTextNode ( value . toString ( ) ) )
96
+ } else {
97
+ console . error ( 'Invalid cell model, no value field' )
98
+ }
95
99
cell . appendChild ( inner )
96
100
parent . appendChild ( cell )
101
+
102
+ if ( onclick ) {
103
+ cell . classList . add ( 'clickable' )
104
+ cell . onclick = onclick
105
+ }
106
+
107
+ if ( watch ) {
108
+ const spinner = document . createElement ( 'i' )
109
+ spinner . className = 'fas fa-spinner fa-pulse small-left-pad deemphasize'
110
+ cell . appendChild ( spinner )
111
+
112
+ const interval = setInterval ( ( ) => {
113
+ try {
114
+ Promise . resolve ( watch ( ) )
115
+ . then ( ( { value, done= false , css } ) => {
116
+
117
+ // update the styling
118
+ if ( css ) {
119
+ inner . className = css
120
+ }
121
+
122
+ // update the text
123
+ if ( value ) {
124
+ inner . innerText = ''
125
+ inner . appendChild ( value . nodeName ? value : document . createTextNode ( value . toString ( ) ) )
126
+ }
127
+
128
+ // are we done polling for updates?
129
+ if ( ! value || done ) {
130
+ clearInterval ( interval )
131
+
132
+ const toRemove = cell . querySelector ( '.fa-spinner' )
133
+ cell . removeChild ( toRemove )
134
+ }
135
+ } )
136
+
137
+ } catch ( err ) {
138
+ console . error ( 'Error watching value' , err )
139
+ clearInterval ( interval )
140
+
141
+ const toRemove = cell . querySelector ( '.fa-spinner' )
142
+ cell . removeChild ( toRemove )
143
+ }
144
+
145
+ } , 2000 )
146
+ }
147
+
97
148
return cell
98
149
}
99
150
100
151
// add any attributes that should appear *before* the name column
101
152
if ( entity . beforeAttributes ) {
102
- entity . beforeAttributes . forEach ( ( { value, css= '' , outerCSS= '' } ) => addCell ( outerCSS , value , css ) )
153
+ entity . beforeAttributes . forEach ( ( { value, css= '' , outerCSS= '' , onclick } ) => addCell ( outerCSS , value , css , undefined , onclick ) )
103
154
}
104
155
105
156
// now add the clickable name
@@ -117,7 +168,7 @@ const formatOneListResult = options => (entity, idx, A) => {
117
168
entityName . appendChild ( entityNameGroup )
118
169
119
170
// name of the entity
120
- let name = entity . name
171
+ let name = entity . prettyName || entity . name
121
172
122
173
// click handler for the list result
123
174
if ( typeof name === 'string' ) {
@@ -144,7 +195,7 @@ const formatOneListResult = options => (entity, idx, A) => {
144
195
// case-specific cells
145
196
//
146
197
if ( entity . attributes ) {
147
- entity . attributes . forEach ( ( { value, css= '' , outerCSS= '' } ) => addCell ( outerCSS , value , css ) )
198
+ entity . attributes . forEach ( ( { value, css= '' , outerCSS= '' , watch , onclick } ) => addCell ( outerCSS , value , css , undefined , onclick , watch ) )
148
199
149
200
} else if ( entity . type === 'actions' ) {
150
201
// action-specific cells
@@ -281,6 +332,8 @@ const printResults = (block, nextBlock, resultDom, echo=true, execOptions, parse
281
332
if ( echo ) {
282
333
ui . showCustom ( response , execOptions )
283
334
ui . ok ( resultDom . parentNode )
335
+ } else if ( execOptions && execOptions . replSilence ) {
336
+ ui . showCustom ( response , execOptions )
284
337
}
285
338
286
339
} else if ( response . type === 'activations' ) {
@@ -345,7 +398,7 @@ self.init = (prefs={}) => {
345
398
}
346
399
347
400
// focus the current prompt no matter where the user clicks
348
- document . body . onclick = evt => {
401
+ document . querySelector ( '#main-repl' ) . onclick = evt => {
349
402
if ( ! window . getSelection ( ) . toString ( ) ) {
350
403
// if there is no selected text, then focus
351
404
// this works, because the HTML (? or chrome?) section model behavior is to clear the selection upon click
@@ -607,7 +660,7 @@ self.exec = (commandUntrimmed, execOptions) => {
607
660
debug ( 'exec' , commandUntrimmed )
608
661
609
662
const echo = ! execOptions || execOptions . echo !== false
610
- const nested = execOptions && execOptions . noHistory
663
+ const nested = execOptions && execOptions . noHistory && ! execOptions . replSilence
611
664
if ( nested ) execOptions . nested = nested
612
665
613
666
const block = execOptions && execOptions . block || ui . getCurrentBlock ( ) ,
0 commit comments