Skip to content

Commit

Permalink
Closes #22. Add interface for User to select (force) Renderer.
Browse files Browse the repository at this point in the history
See #47. Start implementing SpacePen support.
  • Loading branch information
Glavin001 committed Aug 11, 2014
1 parent 0b9f7f3 commit 9b4f722
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 21 deletions.
44 changes: 44 additions & 0 deletions lib/options-view.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{View} = require 'atom'

module.exports =
class OptionsView extends View
@content: ->
@div =>
@div
class: 'overlay from-top'
=>
@div class: "tool-panel panel-bottom", =>
@div class: "inset-panel", =>
@div class: "panel-heading", =>
@div class: 'btn-toolbar pull-right', =>
@button
class: 'btn'
click: 'close'
'Close'
@span 'Preview Options'
@div
class: "panel-body padded"
=>
@div "HAWT BODYYYY"
@button
class: 'btn btn-primary inline-block-tight'
click: 'selectRenderer'
'Select Renderer'


initialize: (@previewView) ->

attach: =>
@previewView.editorContents.append @
@previewView.hideMessage()
toggle: =>
if @hasParent()
@detach()
else
@attach()
close: (event, element) =>
@detach()

selectRenderer: =>
console.log 'Select Renderer!'
@previewView.selectRenderer()
97 changes: 84 additions & 13 deletions lib/preview-view.coffee
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{$, $$$} = require 'atom'
{$, $$, $$$} = require 'atom'
path = require 'path'
_ = require 'underscore-plus'
renderers = require './renderer'
PreviewMessageView = require './preview-message-view.coffee'
PreviewMessageView = require './preview-message-view'
OptionsView = require './options-view'
SelectRendererView = require './select-renderer-view.coffee'
analyticsWriteKey = "bp0dj6lufc"
pkg = require "../package"
version = pkg.version
Expand All @@ -19,6 +21,10 @@ class PreviewView extends ReactEditorView
params = params ? params || {}
super(params)

lastEditor: null
lastRendererName: null # TODO: implement the tracking of this
matchedRenderersCache: {}

constructor: () ->
# Create TextBuffer
buffer = new TextBuffer
Expand All @@ -31,9 +37,21 @@ class PreviewView extends ReactEditorView
# Empty to start
editor.setText ''

# Get EditorContents element
@editorContents = $('.editor-contents', @element)
# Attach the MessageView
@messageView = new PreviewMessageView()
@showLoading()
# Attach the OptionsView
@optionsView = new OptionsView(@)
# Create SelectRendererView
@selectRendererView = new SelectRendererView(@)
# Create container for Previewing Rendered HTML
@htmlPreviewContainer = $$ ->
@div =>
@div "THIS IS A TEST"
@.append @htmlPreviewContainer
@htmlPreviewContainer.hide() # hide by default

# Setup Observers
# Update on Tab Change
Expand Down Expand Up @@ -69,6 +87,10 @@ class PreviewView extends ReactEditorView
'pane-container:active-pane-item-changed', @handleTabChanges

getTitle: ->
# if @lastRendererName?
# "#{@lastRendererName} Preview"
# else
# "Preview"
if @getEditor()?
"#{@getEditor().getTitle()} preview"
else
Expand Down Expand Up @@ -107,13 +129,23 @@ class PreviewView extends ReactEditorView
# Trigger update
@changeHandler()

renderPreview: () ->
renderPreview: =>
@renderPreviewWithRenderer "Default"

renderPreviewWithRenderer: (rendererName) =>
# Update Title
@trigger 'title-changed'
# Start preview processing
cEditor = atom.workspace.getActiveEditor()
editor = @getEditor()
if cEditor? and cEditor isnt editor
if cEditor? and cEditor isnt editor and \
cEditor instanceof Editor
# console.log "Remember last editor"
@lastEditor = cEditor
else
# console.log "Revert to last editor", @lastEditor
cEditor = @lastEditor
if cEditor?
# Source Code text
text = cEditor.getText()
# console.log(text)
Expand All @@ -123,22 +155,47 @@ class PreviewView extends ReactEditorView
@trigger 'title-changed'
# Create Callback
callback = (error, result) =>
@hideMessage()
if error?
return @showError error
outLang = renderer.lang()
grammar = atom.syntax.selectGrammar("source.#{outLang}", result)
editor.setGrammar grammar
editor.setText result
@redraw()
@hideMessage()
# Check if result is a string and therefore source code
if typeof result is "string"
outLang = renderer.lang()
grammar = atom.syntax.selectGrammar("source.#{outLang}", result)
editor.setGrammar grammar
editor.setText result
@redraw()
@hideViewPreview()
# Check if result is a Space-pen View (jQuery)
else if result instanceof $
# Is SpacePen View
@renderViewForPreview(result)
else
# Unknown result type
@hideViewPreview() # Show Editor by default
return @showError new Error("Unsupported result type.")

# Start preview processing
try
grammar = cEditor.getGrammar().name
filePath = cEditor.getPath()
# console.log grammar,filePath
extension = path.extname(filePath)
# console.log extension
renderer = renderers.findRenderer grammar, extension
# Get the renderer
renderer = null
if rendererName is "Default"
# Get the cached renderer for this file
renderer = @matchedRenderersCache[filePath]
# Check if cached renderer was found
if not renderer?
# Find renderer
renderer = renderers.findRenderer grammar, extension
else
# Get the Renderer by name
renderer = renderers.grammars[rendererName]
# Save matched renderer
@matchedRenderersCache[filePath] = renderer
# console.log renderer
if not text?
# Track
Expand Down Expand Up @@ -196,6 +253,12 @@ class PreviewView extends ReactEditorView
}
return @showError e

toggleOptions: ->
@optionsView.toggle()

selectRenderer: ->
@selectRendererView.attach()

showError: (result) ->
failureMessage = result?.message
@showMessage()
Expand Down Expand Up @@ -232,9 +295,17 @@ class PreviewView extends ReactEditorView

showMessage: ->
if not @messageView.hasParent()
editorContents = $('.editor-contents', @element)
editorContents.append @messageView
#@editorContents.append @messageView
@.append @messageView

hideMessage: ->
if @messageView.hasParent()
@messageView.detach()

renderViewForPreview: (view) =>
@editorContents.hide()
@htmlPreviewContainer.show()
@htmlPreviewContainer.html view
hideViewPreview: =>
@htmlPreviewContainer.hide()
@editorContents.show()
18 changes: 15 additions & 3 deletions lib/preview.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ module.exports =
activate: (state) ->
# console.log 'activate(state)'
# console.log state

atom.workspaceView.command 'preview:toggle', =>
@toggle()
atom.workspaceView.command 'preview:toggle-options', =>
@toggleOptions()
atom.workspaceView.command 'preview:select-renderer', =>
@selectRenderer()

atom.workspace.registerOpener (uriToOpen) ->
atom.workspace.registerOpener (uriToOpen) =>
try
{protocol, host, pathname} = url.parse(uriToOpen)
catch error
Expand All @@ -33,7 +37,7 @@ module.exports =
catch error
return
# Create and show preview!
new PreviewView()
@previewView = new PreviewView()

# Deserialize state
@toggle if state.isOpen
Expand Down Expand Up @@ -77,3 +81,11 @@ module.exports =
if previewView instanceof PreviewView
previewView.renderPreview()
previousActivePane.activate()

toggleOptions: ->
if @previewView?
@previewView.toggleOptions()

selectRenderer: ->
if @previewView?
@previewView.selectRenderer()
62 changes: 59 additions & 3 deletions lib/renderer.coffee
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{$} = require 'atom'
path = require 'path'
temp = require("temp").track()
fs = require 'fs'
{allowUnsafeEval, allowUnsafeNewFunction} = require 'loophole'
_ = require 'underscore-plus'
# Speed up repetitive requiring renderers
rCache = {}

module.exports =
findByGrammar: (grammar) ->
Expand Down Expand Up @@ -62,13 +67,13 @@ module.exports =
resourcePath = atom.themes.resourcePath;
# Atom UI Variables is under `./static/variables/`
atomVariablesPath = path.resolve resourcePath, 'static', 'variables'
parser = new(less.Parser)({
parser = new(less.Parser) ({
paths: [ # Specify search paths for @import directives
'.',
atomVariablesPath
],
filename: filepath # Specify a filename, for better error messages
})
} )
parser.parse(text, (e, tree) ->
# console.log e, tree
if e?
Expand All @@ -77,7 +82,7 @@ module.exports =
output = tree.toCSS({
# Do Not Minify CSS output
compress: false
})
} )
cb null, output
)
lang: -> 'css'
Expand Down Expand Up @@ -149,3 +154,54 @@ module.exports =
cb null, jsContent
exts: /^.*\.(em)$/
lang: -> 'js'
'SpacePen':
render: (text, filepath, cb) ->
try
console.log "File Path:", filepath
extension = path.extname(filepath)
temp.open {suffix: extension}, (err, info) ->
if err?
return cb(err, null)
fs.write info.fd, text or "", (err) ->
if err?
return cb(err, null)
fs.close info.fd, (err) ->
if err?
return cb(err, null)
# Get the View class module
console.log info.path
# Patch the NODE_PATH
cd = path.dirname(filepath)
nodePath = process.env.NODE_PATH
deli = ":"
newNodePath = "#{nodePath}#{deli}#{cd}"
console.log newNodePath
process.env.NODE_PATH = newNodePath
module.paths.push cd
console.log module.paths
mFilename = module.filename
module.filename = cd
require('module').Module._initPaths();
View = null
try
View = require(info.path) # Get the View module
catch e
# Revert NODE_PATH
process.env.NODE_PATH = nodePath
module.filename = mFilename
require('module').Module._initPaths();
return cb(e, null)
# Revert NODE_PATH
process.env.NODE_PATH = nodePath
module.filename = mFilename
require('module').Module._initPaths();
view = new View() # Create new View
# Check if it is an instance of a Space-pen View
if view instanceof $
# Is Space-pen view
cb(null, view)
else
cb(new Error("Is not a SpacePen View"), null)
catch e
return cb(e, null)
exts: /^.*\.(coffee|js)$/
29 changes: 29 additions & 0 deletions lib/select-renderer-view.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{SelectListView} = require 'atom'
renderers = require './renderer'

module.exports =
class SelectRendererView extends SelectListView
initialize: (@previewView)->
super
@addClass('overlay from-top')
grammars = Object.keys renderers.grammars
@setItems(grammars)
@focusFilterEditor()

viewForItem: (item) ->
"<li>#{item}</li>"

confirmed: (item) ->
console.log("#{item} was selected")
@previewView.renderPreviewWithRenderer item
# Close
@detach()

attach: =>
@previewView.editorContents.append @
@previewView.hideMessage()
toggle: =>
if @hasParent()
@detach()
else
@attach()
4 changes: 3 additions & 1 deletion menus/app.cson
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
'submenu': [
'label': 'Preview'
'submenu': [
{ 'label': 'Toggle Preview', 'command': 'preview:toggle' }
{ 'label': 'Toggle Preview Tab', 'command': 'preview:toggle' }
{ 'label': 'Toggle Options', 'command': 'preview:toggle-options' }
{ 'label': 'Select Renderer', 'command': 'preview:select-renderer' }
]
]
}
Expand Down
3 changes: 3 additions & 0 deletions menus/context.cson
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
'context-menu':
'.workspace .editor:not(.mini)':
'Toggle Preview': 'preview:toggle'
'.workspace .editor:not(.mini).preview-container':
'Toggle Preview Options': 'preview:toggle-options'
'Select Preview Renderer': 'preview:select-renderer'
Loading

0 comments on commit 9b4f722

Please sign in to comment.