@@ -86,20 +86,71 @@ const formatOneListResult = options => (entity, idx, A) => {
8686 prefix.appendChild(prettyType)*/
8787
8888 /** 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 ) => {
9090 const cell = document . createElement ( 'span' ) ,
9191 inner = document . createElement ( 'span' )
9292 cell . className = className
9393 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+ }
9599 cell . appendChild ( inner )
96100 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+
97148 return cell
98149 }
99150
100151 // add any attributes that should appear *before* the name column
101152 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 ) )
103154 }
104155
105156 // now add the clickable name
@@ -117,7 +168,7 @@ const formatOneListResult = options => (entity, idx, A) => {
117168 entityName . appendChild ( entityNameGroup )
118169
119170 // name of the entity
120- let name = entity . name
171+ let name = entity . prettyName || entity . name
121172
122173 // click handler for the list result
123174 if ( typeof name === 'string' ) {
@@ -144,7 +195,7 @@ const formatOneListResult = options => (entity, idx, A) => {
144195 // case-specific cells
145196 //
146197 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 ) )
148199
149200 } else if ( entity . type === 'actions' ) {
150201 // action-specific cells
@@ -281,6 +332,8 @@ const printResults = (block, nextBlock, resultDom, echo=true, execOptions, parse
281332 if ( echo ) {
282333 ui . showCustom ( response , execOptions )
283334 ui . ok ( resultDom . parentNode )
335+ } else if ( execOptions && execOptions . replSilence ) {
336+ ui . showCustom ( response , execOptions )
284337 }
285338
286339 } else if ( response . type === 'activations' ) {
@@ -345,7 +398,7 @@ self.init = (prefs={}) => {
345398 }
346399
347400 // focus the current prompt no matter where the user clicks
348- document . body . onclick = evt => {
401+ document . querySelector ( '#main-repl' ) . onclick = evt => {
349402 if ( ! window . getSelection ( ) . toString ( ) ) {
350403 // if there is no selected text, then focus
351404 // 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) => {
607660 debug ( 'exec' , commandUntrimmed )
608661
609662 const echo = ! execOptions || execOptions . echo !== false
610- const nested = execOptions && execOptions . noHistory
663+ const nested = execOptions && execOptions . noHistory && ! execOptions . replSilence
611664 if ( nested ) execOptions . nested = nested
612665
613666 const block = execOptions && execOptions . block || ui . getCurrentBlock ( ) ,
0 commit comments