Skip to content

Commit

Permalink
Merge pull request #127 from JunoLab/sp/newrsults
Browse files Browse the repository at this point in the history
Inline result overhaul
  • Loading branch information
pfitzseb authored May 25, 2017
2 parents 60b61ad + c354ee2 commit b7ad0f4
Show file tree
Hide file tree
Showing 10 changed files with 579 additions and 237 deletions.
7 changes: 7 additions & 0 deletions keymaps/ink.cson
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@
'ink-console':
'shift-space': 'unset!'

'.platform-win32 .ink, .platform-linux .ink':
'ctrl-c': 'native!'

'.platform-darwin .ink':
'cmd-c': 'native!'

'atom-text-editor:not([mini])':
'escape': 'inline:clear-current'
'alt-t': 'inline-results:toggle'

'.platform-darwin atom-text-editor:not([mini])':
'cmd-i cmd-c': 'inline-results:clear-all'
Expand Down
2 changes: 1 addition & 1 deletion lib/console/view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class ConsoleElement extends HTMLElement
@isLoading = l

# Scrolling
scrollDown: -> throttle (=> delay (=> @lastElement().scrollIntoView()), 20), 130, {leading: false}
scrollDown: -> throttle (=> delay (=> @lastElement()?.scrollIntoView()), 20), 130, {leading: false}

lock: (f) ->
if @isVisible @lastElement()
Expand Down
152 changes: 152 additions & 0 deletions lib/editor/result-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
'use babel'
import {CompositeDisposable} from 'atom'
let views = require('../util/views')
let {span, div} = views.tags

export default class ResultView {
constructor (model, opts = {}) {
this.model = model
this.disposables = new CompositeDisposable()
this.completeView(opts)

this.model.onDidRemove(() => this.destroy())
this.model.onDidUpdate(() => this.modelUpdated = true)
this.model.onDidInvalidate(() => this.view.classList.add('invalid'))
this.model.onDidValidate(() => this.view.classList.remove('invalid'))
this.model.onDidAttach(() => this.overlayElement = this.complete.parentElement)

this.lastEdWidth = -1

return this
}

getView () {
return this.model.type == 'inline' ? this.complete : this.view
}

getContent () {
return this.view
}

getRawContent () {
return this.rawContent
}

completeView (opts) {
this.complete = document.createElement('div')
this.complete.classList.add('ink-result-container')
if (!opts.noTB && opts.type === 'inline') {
this.toolbarView = this.toolbar(opts.buttons, opts.customButtons)
this.complete.appendChild(this.toolbarView)
}

this.complete.appendChild(this.content(opts))

this.disposables.add(atom.config.observe('editor.lineHeight', (h) => {
this.complete.style.top = -h + 'em'
this.complete.style.minHeight = h + 'em'
}))
}

content (opts) {
let {content, fade, loading, type} = opts
this.view = document.createElement('div')
this.view.setAttribute('tabindex', '-1')
this.view.classList.add('ink', 'result', opts.scope)
if (type === 'inline') {
this.view.classList.add('inline')
} else if (type === 'block') {
this.view.classList.add('under')
}

this.view.addEventListener('mousewheel', (e) => {
if ((this.view.offsetHeight < this.view.scrollHeight ||
this.view.offsetWidth < this.view.scrollWidth) &&
((e.deltaY > 0 && this.view.scrollHeight - this.view.scrollTop > this.view.clientHeight) ||
(e.deltaY < 0 && this.view.scrollTop > 0) ||
(e.deltaX > 0 && this.view.scrollWidth - this.view.scrollLeft > this.view.clientWidth) ||
(e.deltaX < 0 && this.view.scrollLeft > 0))) {
e.stopPropagation()
}
})

this.view.addEventListener('click', () => {
if (this.overlayElement === null) return
this.overlayElement.parentNode.appendChild(this.overlayElement)
})

this.disposables.add(atom.commands.add(this.view, {'inline-results:clear': () => this.remove()}))

if (fade) this.fadeIn()
if (content != null) this.setContent(content, opts)
if (loading) this.setContent(views.render(span('loading icon icon-gear')), opts)

return this.view
}

fadeIn () {
this.view.classList.add('ink-hide')
setTimeout(() => this.view.classList.remove('ink-hide'), 20)
}

setContent (view, {error = false, loading = false}) {
this.rawContent = [view, {error, loading}]
while (this.view.firstChild != null) {
this.view.removeChild(this.view.firstChild)
}
error ? this.view.classList.add('error') : this.view.classList.remove('error')
loading ? this.view.classList.add('loading') : this.view.classList.remove('loading')
this.view.appendChild(view)

// HACK: don't display toolbar for "small" results
if (this.model.type === 'inline' && this.toolbarView && view.innerHTML.length < 100 ) {
this.toolbarView.classList.add('hide')
} else {
this.toolbarView.classList.remove('hide')
}
}

toolbar (buttons, customButtons) {
let tb = views.render(div('btn-group'))
let addButtons = (buttons) => {
for (let b of buttons(this.model)) {
let v = document.createElement('button')
v.classList.add('btn', b.icon)
v.addEventListener('click', b.onclick)
tb.appendChild(v)
}
}
if (customButtons) addButtons(customButtons)
addButtons(buttons)
return views.render(div('ink-result-toolbar', tb))
}

// only read from the DOM
decideUpdateWidth (edRect) {
this.isVisible = false
this.left = 0
this.newEdWidth = false
if (this.overlayElement) {
let rect = this.view.getBoundingClientRect()
this.isVisible = rect.top < edRect.bottom && rect.bottom > edRect.top
this.left = parseInt(this.getView().parentElement.style.left)
this.newEdWidth = edRect.width !== this.lastEdWidth
}
}

// only write to the DOM
updateWidth (edRect) {
if ((this.isVisible && this.newEdWidth) || this.modelUpdated) {
let w = edRect.width + edRect.left - 40 - this.left
if (w < 100) w = 100
this.getView().style.maxWidth = w + 'px'
this.lastEdWidth = edRect.width
this.modelUpdated = false
}
}

destroy () {
this.view.classList.add('ink-hide')
this.disposables.dispose()
}
}
203 changes: 0 additions & 203 deletions lib/editor/result.coffee

This file was deleted.

Loading

0 comments on commit b7ad0f4

Please sign in to comment.