]> git.r.bdr.sh - rbdr/dotfiles/blame - atom/packages/ex-mode/node_modules/space-pen/README.md
Adds atom
[rbdr/dotfiles] / atom / packages / ex-mode / node_modules / space-pen / README.md
CommitLineData
24c7594d
BB
1# SpacePen [![Build Status](https://travis-ci.org/atom/space-pen.svg?branch=master)](https://travis-ci.org/atom/space-pen)
2
3**Version 5.x of SpacePen is intended to be included as a direct dependency of 1.0-compatible Atom packages. If you're looking for SpacePen 3.x, used in [Atom Core](https://github.com/atom/atom), check out the [3.x branch](https://github.com/atom/space-pen/tree/3.x).**
4
5## Write markup on the final frontier
6
7SpacePen is a powerful but minimalistic client-side view framework for
8CoffeeScript. It combines the "view" and "controller" into a single jQuery
9object, whose markup is expressed with an embedded DSL similar to Markaby for
10Ruby.
11
12## Changes In Version 4
13
14This version of SpacePen depends on HTML 5 custom elements to support lifecycle
15hooks that previously depended on all DOM manipulation being performed via
16jQuery. The `afterAttach` and `beforeRemove` hooks have been replaced with
17`attached` and `detached` and their semantics have been altered.
18
19If you need to use SpacePen in an environment that doesn't support custom
20elements, consider using the previous major version or switching frameworks.
21
22## Basics
23
24View objects extend from the View class and have a @content class method where
25you express their HTML contents with an embedded markup DSL:
26
27```coffeescript
28class Spacecraft extends View
29 @content: ->
30 @div =>
31 @h1 "Spacecraft"
32 @ol =>
33 @li "Apollo"
34 @li "Soyuz"
35 @li "Space Shuttle"
36```
37
38Views descend from jQuery's prototype, so when you construct one you can call
39jQuery methods on it just as you would a DOM fragment created with `$(...)`.
40
41```coffeescript
42view = new Spacecraft
43view.find('ol').append('<li>Star Destroyer</li>')
44
45view.on 'click', 'li', ->
46 alert "They clicked on #{$(this).text()}"
47```
48
49But SpacePen views are more powerful than normal jQuery fragments because they
50let you define custom methods:
51
52```coffeescript
53class Spacecraft extends View
54 @content: -> ...
55
56 addSpacecraft: (name) ->
57 @find('ol').append "<li>#{name}</li>"
58
59
60view = new Spacecraft
61view.addSpacecraft "Enterprise"
62```
63
64You can also pass arguments on construction, which get passed to both the
65`@content` method and the view's constructor.
66
67```coffeescript
68class Spacecraft extends View
69 @content: (params) ->
70 @div =>
71 @h1 params.title
72 @ol =>
73 @li name for name in params.spacecraft
74
75view = new Spacecraft(title: "Space Weapons", spacecraft: ["TIE Fighter", "Death Star", "Warbird"])
76```
77
78Methods from the jQuery prototype can be gracefully overridden using `super`:
79
80```coffeescript
81class Spacecraft extends View
82 @content: -> ...
83
84 hide: ->
85 console.log "Hiding Spacecraft List"
86 super()
87```
88
89If you override the View class's constructor, ensure you call `super`.
90Alternatively, you can define an `initialize` method, which the constructor will
91call for you automatically with the constructor's arguments.
92
93```coffeescript
94class Spacecraft extends View
95 @content: -> ...
96
97 initialize: (params) ->
98 @title = params.title
99```
100
101## Outlets and Events
102
103SpacePen will automatically create named reference for any element with an
104`outlet` attribute. For example, if the `ol` element has an attribute
105`outlet=list`, the view object will have a `list` entry pointing to a jQuery
106wrapper for the `ol` element.
107
108```coffeescript
109class Spacecraft extends View
110 @content: ->
111 @div =>
112 @h1 "Spacecraft"
113 @ol outlet: "list", =>
114 @li "Apollo"
115 @li "Soyuz"
116 @li "Space Shuttle"
117
118 addSpacecraft: (name) ->
119 @list.append("<li>#{name}</li>")
120```
121
122Elements can also have event name attributes whose value references a custom
123method. For example, if a `button` element has an attribute
124`click=launchSpacecraft`, then SpacePen will invoke the `launchSpacecraft`
125method on the button's parent view when it is clicked:
126
127```coffeescript
128class Spacecraft extends View
129 @content: ->
130 @div =>
131 @h1 "Spacecraft"
132 @ol =>
133 @li click: 'launchSpacecraft', "Saturn V"
134
135 launchSpacecraft: (event, element) ->
136 console.log "Preparing #{element.name} for launch!"
137```
138## Markup DSL Details
139
140### Tag Methods (`@div`, `@h1`, etc.)
141
142As you've seen so far, the markup DSL is pretty straightforward. From the
143`@content` class method or any method it calls, just invoke instance methods
144named for the HTML tags you want to generate. There are 3 types of arguments you
145can pass to a tag method:
146
147* *Strings*: The string will be HTML-escaped and used as the text contents of the generated tag.
148
149* *Hashes*: The key-value pairs will be used as the attributes of the generated tag.
150
151* *Functions* (bound with `=>`): The function will be invoked in-between the open and closing tag to produce the HTML element's contents.
152
153If you need to emit a non-standard tag, you can use the `@tag(name, args...)`
154method to name the tag with a string:
155
156```coffeescript
157@tag 'bubble', type: "speech", => ...
158```
159
160### Text Methods
161
162* `@text(string)`: Emits the HTML-escaped string as text wherever it is called.
163
164* `@raw(string)`: Passes the given string through unescaped. Use this when you need to emit markup directly that was generated beforehand.
165
166## Subviews
167
168Subviews are a great way to make your view code more modular. The
169`@subview(name, view)` method takes a name and another view object. The view
170object will be inserted at the location of the call, and a reference with the
171given name will be wired to it from the parent view. A `parentView` reference
172will be created on the subview pointing at the parent.
173
174```coffeescript
175class Spacecraft extends View
176 @content: (params) ->
177 @div =>
178 @subview 'launchController', new LaunchController(countdown: params.countdown)
179 @h1 "Spacecraft"
180 ...
181```
182
183## Freeform Markup Generation
184
185You don't need a View class to use the SpacePen markup DSL. Call `View.render`
186with an unbound function (`->`, not `=>`) that calls tag methods, and it will
187return a document fragment for ad-hoc use. This method is also assigned to the
188`$$` global variable for convenience.
189
190```coffeescript
191view.list.append $$ ->
192 @li =>
193 @text "Starship"
194 @em "Enterprise"
195```
196
197## jQuery extensions
198
199### $.fn.view
200You can retrieve the view object for any DOM element by calling `view()` on it.
201This usually shouldn't be necessary, as most DOM manipulation will take place
202within the view itself using outlet references, but is occasionally helpful.
203
204```coffeescript
205view = new Spacecraft
206$('body').append(view)
207
208# assuming no other li elements on the DOM, for example purposes,
209# the following expression should be true
210$('li').view() == view
211```
212
213### Attached/Detached Hooks
214The `initialize` method is always called when the view is still a detached DOM
215fragment, before it is appended to the DOM. This is usually okay, but
216occasionally you'll have some initialization logic that depends on the view
217actually being on the DOM. For example, you may depend on applying a CSS rule
218before measuring an element's height.
219
220For these situations, use the `attached` hook. It will be called whenever your
221element is actually attached to the DOM. Past versions of SpacePen would also
222call this hook when your element was attached to another detached node, but that
223behavior is no longer supported.
224
225To be notified when your element is detached from the DOM, implement the
226`detached` hook.
227
228```coffeescript
229class Spacecraft extends View
230 @content: -> ...
231
232 attached: ->
233 console.log "With CSS applied, my height is", @height()
234
235 detached: ->
236 console.log "I have been detached."
237```
238
239## Hacking on SpacePen
240
241```sh
242git clone https://github.com/atom/space-pen.git
243cd space-pen
244npm install
245npm start
246```
247
248* Open http://localhost:1337 to run the specs
249* Open http://localhost:1337/benchmark to run the benchmarks
250* Open http://localhost:1337/examples to browse the examples