modjs-architecture 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,9 +2,279 @@
2
2
 
3
3
  ##About
4
4
 
5
- Mod.js is a Javascript framework built specifically for the [ArchitectureJS](https://github.com/daytonn/architecture-js "ArchitectureJS") engine although it can be used as a stand-alone framework.
5
+ Mod.js is a small Javascript framework for building large javascript applications. The goal of Mod.js is to provide a solid foundation from which to build your javascript application. Combined with the ArchitectureJS build tool, modjs-architecture is a cohesive javascript development workflow.
6
6
 
7
- ###contributing to architecture.js
7
+ ##Installation
8
+ It's easiest to install modjs-architecture through rubygems like this:
9
+
10
+ gem install modjs-architecture
11
+
12
+ You can also include it in your project's Gemfile
13
+
14
+ gem 'modjs-architecture'
15
+
16
+ ## Getting Started
17
+ To create your modjs application, use the architect command using the modjs blueprint:
18
+
19
+ architect create myapp example -b modjs
20
+
21
+ This will create the myapp application in the example folder (creating the folder if it does not exist) with the modjs scaffolding. Now your ready to build your application.
22
+
23
+ ## The Application object
24
+ Mod.js creates an application object which acts as a namespace for your entire application. This global variable will encapsulate most of the code in your web application and act as the central hub of your modules.
25
+
26
+ The application object really couldn't be much simpler. It has one method and one property. The name property is just a string that identifys the object. It's only method is add_module, which creates a new module, adds that module as a property, and returns a reference to the new module. This method's only purpose is to attach a new module to the global namespace.
27
+
28
+ ```js
29
+ myapp.add_module('dashboard'); // creates myapp.dashboard module
30
+ ```
31
+
32
+ ## Modules
33
+ Modules are the heart of a modjs application. They're not exactly controllers and they're not exactly classes but they share a lot of the same responsibilities as you'd expect from these classical constructs. Modules are based on the typical browser-based workflow. Wait for the DOM, when it's ready attach events, setup plugins, and ajax the shit out of it, etc.
34
+
35
+ Mod.js modules encapsulate this common pattern and create a coherent way to design and create javascript solutions. Modules are only slightly more sophisticated than the application object itself. A modules two main method's are init and init_when_ready.
36
+
37
+ Calling init_when_ready will wait for the dom to be loaded and then call the init method. By default, the init method does nothing. You will provide the code for the init method. The init method should follow the composed method pattern, a simple list of functions to call when the dom is ready. An example of a typical module looks something like this:
38
+
39
+ ```js
40
+ (function(app) {
41
+ var m = app.add_module('dashboard');
42
+
43
+ m.init = function() {
44
+ setup_tabbed_navigation();
45
+ open_external_links_in_new_tab();
46
+ };
47
+
48
+ m.init_when_ready();
49
+
50
+ // Private methods
51
+
52
+ function setup_tabbed_navigation() {
53
+ $('#navigation').tabs();
54
+ }
55
+
56
+ function open_external_links_in_new_tab() {
57
+ var links = $('a');
58
+ var re_local = new RegExp(location.hostname);
59
+ var external_links = links.filter(function(i, link) {
60
+ if (is_defined($(link).attr('href'))) {
61
+ if (href.match(/^https?\:\/\//) && !re_local.test(href)) {
62
+ return true;
63
+ }
64
+ }
65
+ });
66
+ external_links.attr('target', '_blank');
67
+ }
68
+ })(myapp);
69
+ ```
70
+
71
+ This probably looks similar to the code you write currently, Mod.js simply makes it formal. Let's take a tour through this module.
72
+
73
+ Notice that the entire module is wrapped in a closure. This creates a private scope specific to this module. Public methods and properties can be created by attaching them to the module, private properties and methods are simply defined inside the closure, with no connection to the global scope. Also notice that the application object is passed into the closure and aliased as `app`. This means if application name changes or you wish to copy this module into another application, you only need to change the name in one place. It also has the added advantage of being short when referencing the namespace.
74
+
75
+ Next is the module instantiation: `var m = app.add_module('dashboard')`. This line adds a new Mod.js module to the application and returns a reference to that module to be stored as `m`. This serves multiple purposes. For one, it provides a concrete reference to the current module, you won't have to juggle the `this` variable throughout the code. It also serves to attach public methods and properties to the module's scope.
76
+
77
+ Next, see the `init` method declaration. This is where to put all the code which runs when the DOM is ready to be manipulated. Notice that the `setup_tabbed_navigation` method and the `open_external_links_in_new_tab` method are both defined as private methods inside the closure. By using this pattern, only the `dashboard` module has access to these methods. If you wanted to make these methods publicly accessible, simply add the methods to the module namespace. The previous module re-written with public methods would look like this:
78
+
79
+ ```js
80
+ (function(app) {
81
+ var m = app.add_module('dashboard');
82
+
83
+ m.init = function() {
84
+ m.setup_tabbed_navigation();
85
+ m.open_external_links_in_new_tab();
86
+ };
87
+
88
+ m.setup_tabbed_navigation = function() {
89
+ $('#navigation').tabs();
90
+ };
91
+
92
+ m.open_external_links_in_new_tab = function() {
93
+ var links = $('a');
94
+ var re_local = new RegExp(location.hostname);
95
+ var external_links = links.filter(function(i, link) {
96
+ if (is_defined($(link).attr('href'))) {
97
+ if (href.match(/^https?\:\/\//) && !re_local.test(href)) {
98
+ return true;
99
+ }
100
+ }
101
+ });
102
+ external_links.attr('target', '_blank');
103
+ }
104
+
105
+ m.init_when_ready();
106
+ })(myapp);
107
+ ```
108
+
109
+ This makes these methods available publicly through the application namespace. For example, to call `open_external_links_in_new_tab` from another module, do the following:
110
+
111
+ ```js
112
+ (function(app){
113
+ var m = app.add_module('some_other_module');
114
+
115
+ m.init = function() {
116
+ app.dashboard.open_external_links_in_new_tab();
117
+ }
118
+
119
+ m.init_when_ready();
120
+ })(myapp);
121
+ ```
122
+
123
+ You should avoid modules having knowledge of other modules, but it can be handy when solving certain kinds of problems. Most of the time you won't need too many publicly available methods so keeping them hidden to the global scope is a great idea.
124
+
125
+ ## ArchitectureJS and the Sprockets engine
126
+
127
+ Other than establishing a namespace and providing this simple module API, Mod.js does little else to influence how you write your application. Part of what makes Mod.js such a pleasure to work with is the ArchitectureJS build system and the Sprockets engine.
128
+
129
+ Sprockets is a javascript concatenation engine, written in ruby (which eventually became the Rails asset pipeline). Sprockets allows you to concatenate scripts together using special comments called directives. These directives tell Sprockets to search for the file in the project's load path an include it in the compiled source. To learn more about Sprockets directives please view the [Sprockets documentation](http://daytonn.github.com/architecture-js/sprockets.html) on the ArchitectureJS website.
130
+
131
+ ArchitectureJS is a build system for javascript that is similar to the [compass](https://github.com/chriseppstein/compass) css preprocessor. Using Sprockets directives, ArchitectureJS will compile your application scripts into the build directory with all of their dependencies included.
132
+
133
+ To learn more about using ArchitectureJS visit [https://github.com/daytonn/architecture-js](https://github.com/daytonn/architecture-js)
134
+
135
+ ## Requiring support files
136
+ The modules and application directories contain the main scripts of your application, you may be wondering what all the other folders are used for. Using the Sprockets `//= require` directive, you can include scripts from these other directories into the modules or application file. This let's us divide code into logical pieces on the filesystem. Let's look at an example of using the require directive in the `dashboard` module used earlier:
137
+
138
+ ```js
139
+ //= require "../plugins/foo"
140
+
141
+ (function(app) {
142
+ var m = app.add_module('dashboard');
143
+
144
+ ...
145
+ })(myapp);
146
+ ```
147
+
148
+ This module assumes that a `foo.js` file exists inside the `plugins` directory. This line will find that file and include it in the dashboard.js file that is compiled into the application directory. Notice that the file is referenced from the application folder so the `require` line needs the `../` prepended to the path. Also notice that you do not need to add the `.js` because Sprockets only compiles javascript files. In this way you can manage all the dependencies of a given module without including another script tag in your application.
149
+
150
+ The `plugins`, `lib`, and `spec` directories are just arbitrary folders for various script assets (although some of them contain resources you may want/need). Feel free to add your own folders to organize your scripts in whatever way you feel comfortable. BE SURE NOT TO REMOVE OR RENAME THE `lib` folder because it contains a copy of the mod.js library that get's compiled into the application file. The `elements` and `models` directories have special meaning to the modjs framework.
151
+
152
+ ## Elements
153
+
154
+ In this day and age of javascript programming, it seems everyone starts with a DOM polyfill like jQuery or Prototype. Using these frameworks, it's become practice to cache the DOM selections so the element can be referenced many times without querying the DOM again. In practice this means that the code tends to be littered with statements querying the DOM for specific elements to be acted on. At best they are all defined in one place. At worst they are strewn about the code making it easy for teams to duplicate effort and create inefficient code. Either way it can end up creating a lot of noise in scripts and can become hard to manage. Mod.js solves this problem by using `//= require` to separate the DOM selections from the module file that uses those elements to define behavior. This keeps the module file clean and only concerned with behavior. Let's take a look at how this might look in practice, again using the `dashboard` module example:
155
+
156
+ ```js
157
+ (function(app) {
158
+ var m = app.add_module('dashboard');
159
+
160
+ //= require "../elements/dashboard.elements"
161
+
162
+ m.init = function() {
163
+ setup_tabbed_navigation();
164
+ open_external_links_in_new_tab();
165
+ };
166
+
167
+ ...
168
+ })(myapp);
169
+ ```
170
+
171
+ We `require` the /elements/dashboard.elements.js _inside_ the module closure. This is necessary to use the `m` variable that is only available inside the closure. Let's take a look at the dashboard.elements file and how it interacts with it's module:
172
+
173
+ ```js
174
+ m.elements({
175
+ navigation: $('#navigation'),
176
+ links: $('a')
177
+ });
178
+ ```
179
+
180
+ The elements method is defined by `Mod.Module` and simply let's you create an object hash of named selectors. To set an element property of a module simply provide an object with a key (name of the element property) and a cached selector (in this case a jQuery object). To retrieve the cached selector simply call `elements` and pass it the name of the element you wish to retrieve. To access the cached navigation element:
181
+
182
+ ```js
183
+ m.elements('navigation'); // $('#navigation')
184
+ ```
185
+
186
+ Now to update the dashboard.module file to use the new cahced selectors:
187
+
188
+ ```js
189
+ (function(app) {
190
+ var m = app.add_module('dashboard');
191
+
192
+ m.init = function() {
193
+ setup_tabbed_navigation();
194
+ open_external_links_in_new_tab();
195
+ };
196
+
197
+ m.init_when_ready();
198
+
199
+ // Private methods
200
+
201
+ function setup_tabbed_navigation() {
202
+ m.navigation.tabs();
203
+ }
204
+
205
+ function open_external_links_in_new_tab() {
206
+ var re_local = new RegExp(location.hostname);
207
+ var external_links = m.elements('links').filter(function(i, link) {
208
+ if (is_defined($(link).attr('href'))) {
209
+ if (href.match(/^https?\:\/\//) && !re_local.test(href)) {
210
+ return true;
211
+ }
212
+ }
213
+ });
214
+ external_links.attr('target', '_blank');
215
+ }
216
+ })(myapp);
217
+ ```
218
+
219
+ Notice in `setup_tabbed_navigation`, `$('#navigation')` became `m.elements('navigation')` and in `open_external_links_in_new_tab`, `$('a')` became `m.elements('links')`. Before you start thinking that this is overkill consider what this allows us to do. If you decide to swap out jQuery for another framework like Prototype, there's one place to change all the selections for all modules. Even if you don't ever change frameworks, this elements method can be extended to provide extra functionality not provided by the framework. This wrapper technique helps us stay agile by abstracting the method of selection from the practice.
220
+
221
+ ## Models
222
+
223
+ Models in Mod.js are simply json structures that are owned by the module. Each module has a data attribute that is basically a key-value store of basic properties shared throughout the module. The idea behind this is similar to the elements abstraction. Many times we use several object literals to define configuration or other miscellaneous tasks. Models formalize these otherwise autonomous pieces of data. Here's how a using models in Mod.js works:
224
+
225
+ ```js
226
+ (function(app) {
227
+ var m = app.add_module('dashboard');
228
+
229
+ //= require "../elements/dashboard.elements"
230
+ //= require "../models/dashboard.model"
231
+
232
+ m.init = function() {
233
+ setup_tabbed_navigation();
234
+ open_external_links_in_new_tab();
235
+ };
236
+
237
+ ...
238
+ })(myapp);
239
+ ```
240
+
241
+ Now that the model is included in our module we can use the `dashboard.model.js` file to attach data to our module. Using the simple example of a plugin configuration object, we'll add configuration data to the `tabs` plugin being used by `setup_tabbed_navigation`:
242
+
243
+ ```js
244
+ m.set_data('tab_config', {
245
+ selectedTab: 2,
246
+ transition: 'fade'
247
+ });
248
+ ```
249
+
250
+ This is a made up example of a configuration object used on the fictional `tabs` plugin used in `setup_tabbed_navigation`. Now that the data is defined in the model, we can access it in the module like so:
251
+
252
+ ```js
253
+ ...
254
+ function setup_tabbed_navigation() {
255
+ m.navigation.tabs(m.data.tab_config);
256
+ }
257
+ ...
258
+ ```
259
+
260
+ This way we can reuse the `m.data.tab_config` in the module without having to redefine the object literal each time we use the plugin. We can even use jQuery's extend method to modify parts of the config while keeping the defaults. Using the previous example, we can easily use the `tab_config` data to setup another instance of the tab plugin with slightly different configuration:
261
+
262
+ ```js
263
+ ...
264
+ function setup_tabbed_navigation() {
265
+ m.navigation.tabs(m.data.tab_config);
266
+ m.some_other_tabs($.extend({ selectedTab: 1 }, m.data.tab_config));
267
+ }
268
+ ...
269
+ ```
270
+
271
+ This way we can reuse as much as possible and are only definig the difference between the default and the custom plugin instantiation.
272
+
273
+ ## Conclusion
274
+
275
+ That's pretty much Mod.js in a nutshell. It focuses on providing a solid base for modern javscript web development. The simple abstraction adhere's to best practices and let's you focus on building features and not managing a mess of scripts and scopes. Happy scripting ;)
276
+
277
+ ###contributing to modjs-architecture
8
278
 
9
279
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
10
280
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
data/Rakefile CHANGED
@@ -68,4 +68,12 @@ task :travis do
68
68
  end
69
69
  end
70
70
 
71
+ namespace :docs do
72
+ task :build do
73
+ src_dir = File.expand_path('lib/modjs-architecture')
74
+ puts %x{docco #{src_dir}/core/*.js #{src_dir}/extensions/*.js #{src_dir}/helpers/*.js}
75
+ puts "Docco docs built successfully!"
76
+ end
77
+ end
78
+
71
79
  task :default => 'travis'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.5
1
+ 0.4.0
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html> <html> <head> <title>application.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="application.html"> application.js </a> <a class="source" href="dom.html"> dom.js </a> <a class="source" href="module.html"> module.js </a> <a class="source" href="events.html"> events.js </a> <a class="source" href="existence.html"> existence.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> application.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <h2>Mod.Application</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>The application object serves as a basic namespace for your application
2
+ with a convenience method for attaching modules.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">Mod</span><span class="p">.</span><span class="nx">Application</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>Constructing an application requires a name.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">Application</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
3
+ <span class="k">if</span> <span class="p">(</span><span class="nx">is_undefined</span><span class="p">(</span><span class="nx">name</span><span class="p">))</span> <span class="p">{</span>
4
+ <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;new Mod.Application(name): name is undefined&quot;</span><span class="p">);</span>
5
+ <span class="p">}</span>
6
+
7
+ <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span>
8
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <h3>add_module</h3>
9
+
10
+ <p>A factory method to attach modules to the application object.
11
+ This method makes sure to avaoid naming collisions</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">Application</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">add_module</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
12
+ <span class="k">if</span> <span class="p">(</span><span class="nx">is_undefined</span><span class="p">(</span><span class="nx">name</span><span class="p">))</span> <span class="p">{</span>
13
+ <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;Mod.Application.add_module(name): name is undefined&quot;</span><span class="p">);</span>
14
+ <span class="p">}</span>
15
+
16
+ <span class="k">if</span> <span class="p">(</span><span class="nx">is_defined</span><span class="p">(</span><span class="k">this</span><span class="p">[</span><span class="nx">name</span><span class="p">]))</span> <span class="p">{</span>
17
+ <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;Mod.Application.add_module(&#39;&quot;</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot;&#39;): &#39;&quot;</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot;&#39; already declared&quot;</span><span class="p">);</span>
18
+ <span class="p">}</span>
19
+
20
+ <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
21
+ <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;Mod.Application.add_module(&#39;&quot;</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot;&#39;): a module cannot have the same name as the application. It&#39;s bad idea. Do you really want to write &quot;</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot;.&quot;</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot;? It&#39;s confusing.&#39;&quot;</span><span class="p">);</span>
22
+ <span class="p">}</span>
23
+
24
+ <span class="k">return</span> <span class="k">this</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Mod</span><span class="p">.</span><span class="nx">Module</span><span class="p">(</span><span class="nx">name</span><span class="p">);</span>
25
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Return the application object as a reference</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">Application</span><span class="p">;</span>
26
+ <span class="p">})();</span>
27
+
28
+ </pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
data/docs/docco.css ADDED
@@ -0,0 +1,186 @@
1
+ /*--------------------- Layout and Typography ----------------------------*/
2
+ body {
3
+ font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
4
+ font-size: 15px;
5
+ line-height: 22px;
6
+ color: #252519;
7
+ margin: 0; padding: 0;
8
+ }
9
+ a {
10
+ color: #261a3b;
11
+ }
12
+ a:visited {
13
+ color: #261a3b;
14
+ }
15
+ p {
16
+ margin: 0 0 15px 0;
17
+ }
18
+ h1, h2, h3, h4, h5, h6 {
19
+ margin: 0px 0 15px 0;
20
+ }
21
+ h1 {
22
+ margin-top: 40px;
23
+ }
24
+ #container {
25
+ position: relative;
26
+ }
27
+ #background {
28
+ position: fixed;
29
+ top: 0; left: 525px; right: 0; bottom: 0;
30
+ background: #f5f5ff;
31
+ border-left: 1px solid #e5e5ee;
32
+ z-index: -1;
33
+ }
34
+ #jump_to, #jump_page {
35
+ background: white;
36
+ -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
37
+ -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
38
+ font: 10px Arial;
39
+ text-transform: uppercase;
40
+ cursor: pointer;
41
+ text-align: right;
42
+ }
43
+ #jump_to, #jump_wrapper {
44
+ position: fixed;
45
+ right: 0; top: 0;
46
+ padding: 5px 10px;
47
+ }
48
+ #jump_wrapper {
49
+ padding: 0;
50
+ display: none;
51
+ }
52
+ #jump_to:hover #jump_wrapper {
53
+ display: block;
54
+ }
55
+ #jump_page {
56
+ padding: 5px 0 3px;
57
+ margin: 0 0 25px 25px;
58
+ }
59
+ #jump_page .source {
60
+ display: block;
61
+ padding: 5px 10px;
62
+ text-decoration: none;
63
+ border-top: 1px solid #eee;
64
+ }
65
+ #jump_page .source:hover {
66
+ background: #f5f5ff;
67
+ }
68
+ #jump_page .source:first-child {
69
+ }
70
+ table td {
71
+ border: 0;
72
+ outline: 0;
73
+ }
74
+ td.docs, th.docs {
75
+ max-width: 450px;
76
+ min-width: 450px;
77
+ min-height: 5px;
78
+ padding: 10px 25px 1px 50px;
79
+ overflow-x: hidden;
80
+ vertical-align: top;
81
+ text-align: left;
82
+ }
83
+ .docs pre {
84
+ margin: 15px 0 15px;
85
+ padding-left: 15px;
86
+ }
87
+ .docs p tt, .docs p code {
88
+ background: #f8f8ff;
89
+ border: 1px solid #dedede;
90
+ font-size: 12px;
91
+ padding: 0 0.2em;
92
+ }
93
+ .pilwrap {
94
+ position: relative;
95
+ }
96
+ .pilcrow {
97
+ font: 12px Arial;
98
+ text-decoration: none;
99
+ color: #454545;
100
+ position: absolute;
101
+ top: 3px; left: -20px;
102
+ padding: 1px 2px;
103
+ opacity: 0;
104
+ -webkit-transition: opacity 0.2s linear;
105
+ }
106
+ td.docs:hover .pilcrow {
107
+ opacity: 1;
108
+ }
109
+ td.code, th.code {
110
+ padding: 14px 15px 16px 25px;
111
+ width: 100%;
112
+ vertical-align: top;
113
+ background: #f5f5ff;
114
+ border-left: 1px solid #e5e5ee;
115
+ }
116
+ pre, tt, code {
117
+ font-size: 12px; line-height: 18px;
118
+ font-family: Monaco, Consolas, "Lucida Console", monospace;
119
+ margin: 0; padding: 0;
120
+ }
121
+
122
+
123
+ /*---------------------- Syntax Highlighting -----------------------------*/
124
+ td.linenos { background-color: #f0f0f0; padding-right: 10px; }
125
+ span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
126
+ body .hll { background-color: #ffffcc }
127
+ body .c { color: #408080; font-style: italic } /* Comment */
128
+ body .err { border: 1px solid #FF0000 } /* Error */
129
+ body .k { color: #954121 } /* Keyword */
130
+ body .o { color: #666666 } /* Operator */
131
+ body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
132
+ body .cp { color: #BC7A00 } /* Comment.Preproc */
133
+ body .c1 { color: #408080; font-style: italic } /* Comment.Single */
134
+ body .cs { color: #408080; font-style: italic } /* Comment.Special */
135
+ body .gd { color: #A00000 } /* Generic.Deleted */
136
+ body .ge { font-style: italic } /* Generic.Emph */
137
+ body .gr { color: #FF0000 } /* Generic.Error */
138
+ body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
139
+ body .gi { color: #00A000 } /* Generic.Inserted */
140
+ body .go { color: #808080 } /* Generic.Output */
141
+ body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
142
+ body .gs { font-weight: bold } /* Generic.Strong */
143
+ body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
144
+ body .gt { color: #0040D0 } /* Generic.Traceback */
145
+ body .kc { color: #954121 } /* Keyword.Constant */
146
+ body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
147
+ body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
148
+ body .kp { color: #954121 } /* Keyword.Pseudo */
149
+ body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
150
+ body .kt { color: #B00040 } /* Keyword.Type */
151
+ body .m { color: #666666 } /* Literal.Number */
152
+ body .s { color: #219161 } /* Literal.String */
153
+ body .na { color: #7D9029 } /* Name.Attribute */
154
+ body .nb { color: #954121 } /* Name.Builtin */
155
+ body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
156
+ body .no { color: #880000 } /* Name.Constant */
157
+ body .nd { color: #AA22FF } /* Name.Decorator */
158
+ body .ni { color: #999999; font-weight: bold } /* Name.Entity */
159
+ body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
160
+ body .nf { color: #0000FF } /* Name.Function */
161
+ body .nl { color: #A0A000 } /* Name.Label */
162
+ body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
163
+ body .nt { color: #954121; font-weight: bold } /* Name.Tag */
164
+ body .nv { color: #19469D } /* Name.Variable */
165
+ body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
166
+ body .w { color: #bbbbbb } /* Text.Whitespace */
167
+ body .mf { color: #666666 } /* Literal.Number.Float */
168
+ body .mh { color: #666666 } /* Literal.Number.Hex */
169
+ body .mi { color: #666666 } /* Literal.Number.Integer */
170
+ body .mo { color: #666666 } /* Literal.Number.Oct */
171
+ body .sb { color: #219161 } /* Literal.String.Backtick */
172
+ body .sc { color: #219161 } /* Literal.String.Char */
173
+ body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
174
+ body .s2 { color: #219161 } /* Literal.String.Double */
175
+ body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
176
+ body .sh { color: #219161 } /* Literal.String.Heredoc */
177
+ body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
178
+ body .sx { color: #954121 } /* Literal.String.Other */
179
+ body .sr { color: #BB6688 } /* Literal.String.Regex */
180
+ body .s1 { color: #219161 } /* Literal.String.Single */
181
+ body .ss { color: #19469D } /* Literal.String.Symbol */
182
+ body .bp { color: #954121 } /* Name.Builtin.Pseudo */
183
+ body .vc { color: #19469D } /* Name.Variable.Class */
184
+ body .vg { color: #19469D } /* Name.Variable.Global */
185
+ body .vi { color: #19469D } /* Name.Variable.Instance */
186
+ body .il { color: #666666 } /* Literal.Number.Integer.Long */