luca 0.9.2 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rvmrc +1 -1
- data/CHANGELOG +46 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/Guardfile +1 -1
- data/README.md +64 -27
- data/ROADMAP +17 -2
- data/Rakefile +49 -1
- data/app.rb +38 -2
- data/assets/javascripts/luca-ui-base.coffee +1 -20
- data/assets/javascripts/luca-ui-full.js +3 -0
- data/assets/javascripts/luca-ui.coffee +0 -5
- data/assets/javascripts/sandbox/application.coffee +24 -18
- data/assets/javascripts/sandbox/router.coffee +16 -6
- data/assets/javascripts/sandbox/templates/builder/component_list.luca +1 -0
- data/assets/javascripts/sandbox/templates/builder.luca +2 -0
- data/assets/javascripts/sandbox/templates/main.luca +4 -3
- data/assets/javascripts/sandbox/templates/sandbox/docs_index.luca +1 -0
- data/assets/javascripts/sandbox/templates/sandbox/navigation.luca +6 -1
- data/assets/javascripts/sandbox/templates/sandbox/readme.luca +30 -0
- data/assets/javascripts/sandbox/views/builder/builder_canvas.coffee +3 -0
- data/assets/javascripts/sandbox/views/builder/builder_editor.coffee +6 -0
- data/assets/javascripts/sandbox/views/builder/component_list.coffee +38 -0
- data/assets/javascripts/sandbox/views/builder/project_browser.coffee +14 -0
- data/assets/javascripts/sandbox/views/builder.coffee +133 -0
- data/assets/javascripts/sandbox/views/docs_controller.coffee +7 -0
- data/assets/javascripts/sandbox/views/inspector/instance_filter.coffee +18 -0
- data/assets/javascripts/sandbox/{collections/sample.coffee → views/inspector/instance_list.coffee} +0 -0
- data/assets/javascripts/sandbox/views/inspector.coffee +11 -0
- data/assets/javascripts/sandbox.coffee +2 -0
- data/assets/stylesheets/luca-ui-full.css +3 -0
- data/assets/stylesheets/sandbox/builder.scss +79 -0
- data/assets/stylesheets/sandbox/sandbox.scss +2 -1
- data/docs/application.md +41 -0
- data/docs/collection.md +79 -0
- data/docs/collection_manager.md +76 -0
- data/docs/container_philosophy.md +122 -0
- data/docs/event_binding_helpers.md +164 -0
- data/docs/method_caching_and_computed_properties.md +77 -0
- data/docs/view.md +119 -0
- data/lib/luca/rails/version.rb +1 -1
- data/lib/luca/template.rb +9 -9
- data/site/assets/bootstrap.min.js +7 -0
- data/site/assets/luca-ui-bootstrap.css +19 -1
- data/site/assets/luca-ui-development-tools.css +10 -0
- data/site/assets/luca-ui-development-tools.min.js +15 -0
- data/site/assets/luca-ui-full.min.js +8 -0
- data/site/assets/luca-ui.min.js +4 -0
- data/site/assets/sandbox.css +52 -4
- data/site/assets/sandbox.js +368 -30
- data/site/docs/application.html +41 -0
- data/site/docs/caching.html +43 -0
- data/site/docs/collection.html +75 -0
- data/site/docs/collection_manager.html +71 -0
- data/site/docs/containers.html +118 -0
- data/site/docs/events.html +153 -0
- data/site/docs/view.html +128 -0
- data/site/img/glyphicons-halflings-white.png +0 -0
- data/site/img/glyphicons-halflings.png +0 -0
- data/site/source-map.js +1 -0
- data/spec/core/view_spec.coffee +5 -17
- data/spec/managers/collection_manager_spec.coffee +4 -7
- data/src/components/application.coffee +202 -77
- data/src/components/base_toolbar.coffee +1 -1
- data/src/components/collection_view.coffee +38 -10
- data/src/components/controller.coffee +24 -1
- data/src/components/fields/checkbox_field.coffee +9 -12
- data/src/components/fields/label_field.coffee +14 -0
- data/src/components/fields/select_field.coffee +2 -2
- data/src/components/fields/text_field.coffee +12 -7
- data/src/components/fields/type_ahead_field.coffee +1 -0
- data/src/components/form_view.coffee +44 -25
- data/src/components/page_controller.coffee +2 -0
- data/src/containers/card_view.coffee +4 -1
- data/src/containers/column_view.coffee +2 -1
- data/src/containers/modal_view.coffee +6 -2
- data/src/containers/page_view.coffee +2 -0
- data/src/containers/panel_toolbar.coffee +0 -5
- data/src/containers/viewport.coffee +28 -10
- data/src/core/collection.coffee +7 -1
- data/src/core/container.coffee +57 -30
- data/src/core/core.coffee +0 -186
- data/src/core/field.coffee +11 -3
- data/src/core/model.coffee +31 -16
- data/src/core/panel.coffee +6 -46
- data/src/core/registry.coffee +19 -2
- data/src/core/script_loader.coffee +32 -0
- data/src/core/view.coffee +112 -139
- data/src/define.coffee +110 -0
- data/src/framework.coffee +8 -2
- data/src/luca.coffee +22 -0
- data/src/managers/collection_manager.coffee +65 -31
- data/src/modules/load_mask.coffee +47 -0
- data/src/plugins/development_tool_helpers.coffee +21 -0
- data/src/plugins/events.coffee +54 -0
- data/src/stylesheets/components/viewport.scss +15 -0
- data/src/stylesheets/containers/container.scss +1 -4
- data/src/stylesheets/tools/component_tester.scss +18 -0
- data/src/templates/fields/select_field.luca +6 -5
- data/src/templates/fields/text_field.luca +10 -9
- data/src/tools/application_inspector.coffee +2 -0
- data/src/tools/coffee_script_editor.coffee +28 -6
- data/src/tools/collections/components.coffee +59 -0
- data/src/tools/collections/instances.coffee +15 -0
- data/src/tools/component_tester.coffee +12 -22
- data/src/tools/console.coffee +22 -4
- data/src/tools/models/components.coffee +16 -54
- data/src/tools/models/instance.coffee +2 -0
- data/src/{core/util.coffee → util.coffee} +10 -1
- data/vendor/assets/javascripts/luca-ui-base.js +132 -137
- data/vendor/assets/javascripts/luca-ui-development-tools.js +191 -219
- data/vendor/assets/javascripts/luca-ui-development-tools.min.js +2 -2
- data/vendor/assets/javascripts/luca-ui-full.js +4680 -0
- data/vendor/assets/javascripts/luca-ui-full.min.js +8 -0
- data/vendor/assets/javascripts/luca-ui-spec.js +291 -225
- data/vendor/assets/javascripts/luca-ui.js +1001 -724
- data/vendor/assets/javascripts/luca-ui.min.js +4 -4
- data/vendor/assets/stylesheets/luca-ui-bootstrap.css +19 -1
- data/vendor/assets/stylesheets/luca-ui-development-tools.css +10 -0
- data/vendor/assets/stylesheets/luca-ui-full.css +1334 -0
- data/vendor/assets/stylesheets/luca-ui-spec.css +19 -1
- data/vendor/assets/stylesheets/luca-ui.css +19 -1
- data/views/index.erb +2 -5
- metadata +58 -9
- data/lib/sprockets/luca_template.rb +0 -49
- data/src/tools/class_browser.coffee +0 -39
- data/src/tools/components/class_browser_detail.coffee +0 -10
- data/src/tools/components/class_browser_list.coffee +0 -74
@@ -0,0 +1,164 @@
|
|
1
|
+
## Event Binding Syntactic Sugar
|
2
|
+
|
3
|
+
`Luca.Events` provides you with some additional event binding sugar.
|
4
|
+
|
5
|
+
**once**
|
6
|
+
|
7
|
+
`once` is how you would run one function in response to an event, but only once.
|
8
|
+
|
9
|
+
```coffeescript
|
10
|
+
view = new Luca.View()
|
11
|
+
|
12
|
+
view.once "event:gets:triggered", ()->
|
13
|
+
alert('sup baby')
|
14
|
+
|
15
|
+
view.trigger("event:gets:triggered")
|
16
|
+
```
|
17
|
+
|
18
|
+
**defer until**
|
19
|
+
|
20
|
+
`defer` is similar to `once`, but with syntax I like a little better:
|
21
|
+
|
22
|
+
```coffeescript
|
23
|
+
_.def("MyView").extends("Luca.View").with
|
24
|
+
initialize: ()->
|
25
|
+
@defer(@setup).until("event:gets:triggered")
|
26
|
+
```
|
27
|
+
|
28
|
+
If you want to defer a callback until an event gets triggered on some other object:
|
29
|
+
|
30
|
+
```coffeescript
|
31
|
+
|
32
|
+
_.def("MyView").extends("Luca.View").with
|
33
|
+
|
34
|
+
initialize:()->
|
35
|
+
@defer(@setup).until(@someObject,"triggers:an:event")
|
36
|
+
|
37
|
+
setup: ()->
|
38
|
+
|
39
|
+
```
|
40
|
+
|
41
|
+
## Component Bindings
|
42
|
+
|
43
|
+
Luca provides a number of configuration API for its components
|
44
|
+
which facilitate the binding of a component's methods to events that
|
45
|
+
occur on instances of the CollectionManager and Application objects.
|
46
|
+
|
47
|
+
For Luca.core.Container classes there is also a component events
|
48
|
+
binding API that allows you to declare in your container which events
|
49
|
+
to listen for on that container's components
|
50
|
+
|
51
|
+
## Auto Context Binding For Event Handlers
|
52
|
+
|
53
|
+
By setting the @bindAllEvents property to true on your prototype definitions,
|
54
|
+
all event handler methods on your view will automatically be bound to the context
|
55
|
+
of the view.
|
56
|
+
|
57
|
+
```coffeescript
|
58
|
+
_.def('MyApp.views.AutoBoundView').extends('Luca.View').with
|
59
|
+
|
60
|
+
bindAllEvents: true
|
61
|
+
|
62
|
+
events:
|
63
|
+
"click a.btn" : "clickHandler"
|
64
|
+
"click a.btn.btn-danger" : "dangerHandler"
|
65
|
+
|
66
|
+
initialize:()->
|
67
|
+
# You no longer need to do this
|
68
|
+
# if you want to have these handlers run
|
69
|
+
# in the context of this view
|
70
|
+
_.bindAll @, "clickHandler", "dangerHandler"
|
71
|
+
|
72
|
+
```
|
73
|
+
|
74
|
+
## Collection Manager Event Binding
|
75
|
+
|
76
|
+
Luca Applications which use the Luca.CollectionManager have the benefit of
|
77
|
+
a declarative event binding syntax which allows you bind to events on collections
|
78
|
+
by their name. This saves you from having to create a reference to the collection
|
79
|
+
in some method, and setup a callback binding. By simply providing a @collectionEvents
|
80
|
+
configuration property on your views, you can eliminate a lot of boilerplate in your components.
|
81
|
+
|
82
|
+
The format of the @collectionEvents hash is a key which is made up of the collection's name and the event
|
83
|
+
separated by a space, and either a function or a name of a method on your view.
|
84
|
+
|
85
|
+
```coffeescript
|
86
|
+
SamplesCollection = Backbone.Collection.extend
|
87
|
+
name: "samples"
|
88
|
+
url: "/api/v1/samples"
|
89
|
+
|
90
|
+
_.def("MyView").extends("Luca.View").with
|
91
|
+
# NOTE: you may omit this property and
|
92
|
+
# it will use Luca.CollectionManager.get() to
|
93
|
+
# get the main instance.
|
94
|
+
collectionManager: "main"
|
95
|
+
|
96
|
+
collectionEvents:
|
97
|
+
"samples reset" : "samplesResetHandler"
|
98
|
+
|
99
|
+
samplesResetHandler: (collection)->
|
100
|
+
if collection.length > 1
|
101
|
+
@doSomething()
|
102
|
+
```
|
103
|
+
## Application Event Binding
|
104
|
+
|
105
|
+
Similar to the CollectionManager event binding API, there is a similar API for binding to the global application
|
106
|
+
object. Most applications will have a single application instance, that is either available on the global object
|
107
|
+
or through a call to `Luca.getApplication()`.
|
108
|
+
|
109
|
+
It is in the Application instance that global state tracking should occur. Should your views want to respond to changes
|
110
|
+
in global application state, you can provide an @applicationEvents configuration property. The format is a key value
|
111
|
+
pair, where the key represents the event being triggered by the application, and the value is a name of a method on
|
112
|
+
your view or an anonymous function.
|
113
|
+
|
114
|
+
```coffeescript
|
115
|
+
App = new Luca.Application
|
116
|
+
name: "main"
|
117
|
+
|
118
|
+
defaultState:
|
119
|
+
currentMode: "solid"
|
120
|
+
|
121
|
+
_.def("AppBoundView").extends("Luca.View").with
|
122
|
+
# NOTE: you may omit this and it will use Luca.getApplication()
|
123
|
+
app: "main"
|
124
|
+
|
125
|
+
applicationEvents:
|
126
|
+
"change:currentMode" : "modeChangeHandler"
|
127
|
+
|
128
|
+
modeChangeHandler: ()->
|
129
|
+
@doSomething()
|
130
|
+
```
|
131
|
+
|
132
|
+
## Luca.core.Container Component Events
|
133
|
+
|
134
|
+
Containers are special views whose only purpose is to render multiple components in a specified configuration, and handle
|
135
|
+
all of the communication between the components. This is what allows Luca components to be extremely re-usable, because they
|
136
|
+
never know about views that exist outside of them.
|
137
|
+
|
138
|
+
By providing a @componentEvents configuration property on your container, you can bind to events on the components in your container
|
139
|
+
and relay information about them to other members of the container. The format is a key value pair where the key is a string which
|
140
|
+
contains the name of the component and the event it triggers, separated by a space. The value is a name of a method on your view or an anonymous function.
|
141
|
+
|
142
|
+
```coffeescript
|
143
|
+
# ctype = component_one
|
144
|
+
_.def("ComponentOne").extends("Luca.View").with
|
145
|
+
name:"one"
|
146
|
+
eventHandler: ()->
|
147
|
+
@trigger "custom:event"
|
148
|
+
|
149
|
+
# ctype = component_two
|
150
|
+
_.def("ComponentTwo").extends("ComponentOne").with
|
151
|
+
name:"two"
|
152
|
+
eventHandler: ()->
|
153
|
+
@trigger "some:other:event"
|
154
|
+
|
155
|
+
_.def("MyContainer").extends("Luca.core.Container").with
|
156
|
+
components:["component_two","component_one"]
|
157
|
+
componentEvents:
|
158
|
+
"one custom:event" : "customEventHandler"
|
159
|
+
|
160
|
+
# when component named one fires an event
|
161
|
+
# we can handle it here, pass it to two, whatever
|
162
|
+
customEventHandler: ()->
|
163
|
+
Luca('two').eventHandler()
|
164
|
+
```
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# Method Caching and Computed Properties on Luca Collection and Model
|
2
|
+
|
3
|
+
The concept of computed properties ( on the model ) or cached methods ( on the collection )
|
4
|
+
optimizes for cases where you call a method that performs calculations or some other operations
|
5
|
+
whose value is dependent on the model and its underlying attributes.
|
6
|
+
|
7
|
+
## Cached Methods on Luca.Collection
|
8
|
+
|
9
|
+
Luca provides a configuration API for Luca.Collection where you specify the method whose value
|
10
|
+
you wish to cache, and the change events which get bubbled up from the models that would change
|
11
|
+
the value, in essence expiring the cache. In addition to change events, standard events on the
|
12
|
+
collection for when a model is added or removed will expire the cached value.
|
13
|
+
|
14
|
+
```coffeescript
|
15
|
+
_.def("MyCollection").extends("Luca.Collection").with
|
16
|
+
name:"my_collection"
|
17
|
+
|
18
|
+
cachedMethods:[
|
19
|
+
"expensiveMethod:attributeOne,attributeTwo",
|
20
|
+
"anotherExpensiveMethod"
|
21
|
+
]
|
22
|
+
|
23
|
+
expensiveMethod: ()->
|
24
|
+
@map (model)-> model.get('attributeOne') + model.getAttribute('two')
|
25
|
+
|
26
|
+
anotherExpensiveMethod: ()->
|
27
|
+
@map (model)-> model.value()
|
28
|
+
```
|
29
|
+
|
30
|
+
In the example above, the `expensiveMethod` is dependent on the `attributeOne` and `attributeTwo` attributes
|
31
|
+
on each of the models in the collection, therefor if any of these values change, the cache needs to be expired and new value recalculated.
|
32
|
+
|
33
|
+
The `anotherExpensiveMethod` call is not dependent on any specific values, so will only expire any time a new model
|
34
|
+
is added or removed, or the collection is reset.
|
35
|
+
|
36
|
+
|
37
|
+
Example:
|
38
|
+
|
39
|
+
```coffeescript
|
40
|
+
_.def("Users").extends("Luca.Collection").with
|
41
|
+
name: 'users'
|
42
|
+
|
43
|
+
cachedMethods: [
|
44
|
+
"averageAge:age"
|
45
|
+
]
|
46
|
+
|
47
|
+
averageAge: ()->
|
48
|
+
sum = @reduce (acc, user) ->
|
49
|
+
acc + user.get('age')
|
50
|
+
, 0
|
51
|
+
Math.floor(sum / @size)
|
52
|
+
```
|
53
|
+
An `averageAge` will be cached and recalculated only when either
|
54
|
+
membership of the collection will change or `age` attribute on either member
|
55
|
+
|
56
|
+
## Computed Properties on Luca.Model
|
57
|
+
|
58
|
+
```coffeescript
|
59
|
+
_.def("MyModel").extends("Luca.Model").with
|
60
|
+
computed:
|
61
|
+
"expensive" : ["dependencyOne","dependencyTwo"]
|
62
|
+
|
63
|
+
expensive: ()->
|
64
|
+
@get("dependencyOne") + @get("dependencyTwo")
|
65
|
+
```
|
66
|
+
|
67
|
+
In the example above, `expensive` method will be converted to the `expensive` property which is be computed/updated on initialization and every time any of its dependent properties will change. That `expensive` property will act as any other attribute on the model (responds to `get` operations, can be available in `toJSON()` etc).
|
68
|
+
|
69
|
+
Example:
|
70
|
+
|
71
|
+
```coffeescript
|
72
|
+
_.def("User").extends("Luca.Model").with
|
73
|
+
computed:
|
74
|
+
"fullName": ["firstName","lastName"]
|
75
|
+
fullName: ()->
|
76
|
+
@get("firstName") + @get("lastName")
|
77
|
+
```
|
data/docs/view.md
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# Luca.View
|
2
|
+
|
3
|
+
The `Luca.View` class is the base class for Luca components. A number of patterns and optimizations that are helpful in your view classes have been extracted into the base class.
|
4
|
+
|
5
|
+
## Hooks
|
6
|
+
|
7
|
+
In Backbone, views trigger events, and we can bind to them as normally, and that this is good. Often we are binding our view's methods to events that get triggered. In Luca, hooks are events you can declare on your component definition which will be automatically called if events get triggered with names which match the pattern. This saves you the work of having to set up event binding logic manually.
|
8
|
+
|
9
|
+
For example:
|
10
|
+
|
11
|
+
```coffeescript
|
12
|
+
_.def("Luca.View").extends("Backbone.View").with
|
13
|
+
hooks:[
|
14
|
+
"after:initialize" # => will call the @afterInitialize method if it exists
|
15
|
+
"before:render" # => @beforeRender
|
16
|
+
"after:render" # => @afterRender
|
17
|
+
"first:activation" # => @firstActivation
|
18
|
+
"activation" # => @activation
|
19
|
+
"deactivation" # => @deactivation
|
20
|
+
]
|
21
|
+
```
|
22
|
+
|
23
|
+
**Note on extending hook methods**
|
24
|
+
|
25
|
+
If you want to maintain the functionality of the component you are extending from, you will have to remember to call the prototype method like such:
|
26
|
+
|
27
|
+
```coffeescript
|
28
|
+
_.def("MyView").extends("Luca.View").with
|
29
|
+
beforeRender: ()->
|
30
|
+
@_super("beforeRender", @, arguments)
|
31
|
+
|
32
|
+
# or, if you prefer
|
33
|
+
Luca.View::beforeRender?.apply(@, arguments)
|
34
|
+
```
|
35
|
+
|
36
|
+
## The @render() method
|
37
|
+
|
38
|
+
The default implementation of @render() simply appends the view's `@$el` to the DOM element represented by the `$(@container)` property on the view.
|
39
|
+
|
40
|
+
Whatever method you choose to implement for your `@render()` call should behave similar to how the Backbone.View::render() expects, in that it should return an instance of the view.
|
41
|
+
|
42
|
+
Additionally, the call to `@render()` will trigger `before:render` and `after:render` as which, on a Luca.View is configured as a hook. So any `@beforeRender()` and `@afterRender()` method will get called as well, if they exist.
|
43
|
+
|
44
|
+
## Before Render
|
45
|
+
|
46
|
+
Since in Luca, the actual render method just attaches the view to its container, setup related methods for building your view's content are best put in the `beforeRender()` method. In addition to this, there are other options available for filling the content of the view, like `@bodyTemplate`.
|
47
|
+
|
48
|
+
## Luca.template helper
|
49
|
+
|
50
|
+
`Luca.template()` is a util function which allows you reference your client side template system. It accepts a name of a template ( which, if not found, it will attempt to match one for you ) and an object of interpolations to pass to the template function
|
51
|
+
|
52
|
+
`Luca.available_templates()` is a util function, useful for debugging, to see which templates are available to you.
|
53
|
+
|
54
|
+
## Configuration Options
|
55
|
+
|
56
|
+
- `@additionalClassNames` - an array of CSS classes to apply to the view's `@$el`. This is helpful for inheritance of views.
|
57
|
+
|
58
|
+
- `@name` - Setting a name property on your view, will allow you to reference the instance of that view later.
|
59
|
+
|
60
|
+
```coffeescript
|
61
|
+
view = new Luca.View(name:"my_view")
|
62
|
+
|
63
|
+
Luca("my_view") is view # => true
|
64
|
+
|
65
|
+
```
|
66
|
+
|
67
|
+
- `@wrapperClass` - automatically wraps the view with a div with this as the CSS class.
|
68
|
+
|
69
|
+
- `@bodyTemplate` - will apply the content of the template to your view
|
70
|
+
|
71
|
+
- `@bindAllEvents` - true or false automatically bind all event handler methods to the context of your view's instance
|
72
|
+
|
73
|
+
- `@applicationEvents` - configuration similar to the DOM `@events` configuration on Backbone.View. Used to bind to events triggered by the `Luca.Application.get()` object. You can customize which application you use by setting `@app` to either reference the app, or to the name of a given application.
|
74
|
+
|
75
|
+
- `@collectionEvents` - configuration similar to the DOM `@events` configuration on Backbone.View. Used to bind to events triggered by the `Luca.CollectionManager.get()` object.
|
76
|
+
|
77
|
+
## Luca.View::$bodyEl()
|
78
|
+
|
79
|
+
In your `Luca.View` definitions, If you set the `@bodyTemplate` property to one of the available templates, then on `initialize` the view will set the HTML of its DOM element to the contents of the template.
|
80
|
+
|
81
|
+
This is useful in cases where there is a fair amount of structural, or otherwise static DOM content in your view, and one of the standard `Luca.core.Container` components is not suited for what you want to do. The `Luca.components.Panel` view is basically just a `Luca.View` which has additional DOM containers for footers and headers. It accomplishes this through the use of the `@bodyClassName` and `@bodyTagName` properties.
|
82
|
+
|
83
|
+
`@bodyClassName` and `@bodyTagName` work the same way the `@className` and `@tagName` properties work on standard Backbone views. They are used to create a DOM element via `Backbone.View.prototype.make(@bodyTagName,class:@bodyClassName,id:@bodyId`
|
84
|
+
|
85
|
+
If you use `view.$bodyEl()` instead of the standard `view.$el()` that ships with Backbone, all of the standard DOM manipulation methods available will be scoped to the CSS selector that corresponds to the actual body element of your view.
|
86
|
+
|
87
|
+
## Deferrable Rendering
|
88
|
+
|
89
|
+
The jury is still out as to whether or not deferrable rendering is a useful pattern, or whether it is too complex. The use case it was trying to optimize is for views which can only be rendered in response to an event being fired on another object. Such as `Backbone.Collection::fetch`.
|
90
|
+
|
91
|
+
If this is what you are doing, then this feature is for you.
|
92
|
+
|
93
|
+
The options available for views which use the `@deferrable` property are as follows:
|
94
|
+
|
95
|
+
- `@deferrable` - if you set a reference to an object, such as a collection, on the @deferrable property, then the call to `view.render()` will actually just set up an event binding to the `reset` event of your collection, and it will automatically call `fetch` for you on that collection.
|
96
|
+
|
97
|
+
If you set `@deferrable` to true then the view will expect a `@collection` property.
|
98
|
+
|
99
|
+
- `@deferrable_method` - a call to `@render()` on a `@deferrable` view will automatically call this method on the `@deferrable` object.
|
100
|
+
|
101
|
+
- `@deferrable_trigger` - if you use the deferrable system , by default, it will automatically call the `@deferrable_method` on your `@deferrable` object when you call `@render()`. However, if you want to defer this method being fired even later, just set the `@deferrable_trigger` property to whatever trigger your view will listen for.
|
102
|
+
|
103
|
+
A useful example would be for views which get rendered hidden, and activated if and only if the user does a specific action. ( For example, a TabView activating a secondary tab ). If that action triggers an event, and you want to delay the render process if and only if that event is triggered.
|
104
|
+
|
105
|
+
## Helpers
|
106
|
+
|
107
|
+
- `view.$template` calls `view.$.html()` on your view, with whatever is returned from the template. Delegates to `Luca.template(templateName, customizationHash)`
|
108
|
+
|
109
|
+
- `view.$wrap` the same as `view.$el.wrap()` -- accepts a CSS class name string, or a DOM element
|
110
|
+
|
111
|
+
- `view.$append` the same as `view.$el.append()`
|
112
|
+
|
113
|
+
- `view.$container` - references `$( view.container )`. Note: the @container property is set on a view when it belongs to the `@components` property of a `Luca.core.Container` instance. It is just a standard CSS selector.
|
114
|
+
|
115
|
+
- `view.registerEvent()` manipulates your `@events` configuration on your Backbone.View and then calls `@delegateEvents` to make sure they are live.
|
116
|
+
|
117
|
+
## Backbone Component Helpers
|
118
|
+
|
119
|
+
Views which have properties on them referencing other views, models, or collections, can access those objects by calling `view.models()` or `view.views()` or `view.collections()`. This is mainly useful for introspection, debugging, or what not.
|
data/lib/luca/rails/version.rb
CHANGED
data/lib/luca/template.rb
CHANGED
@@ -2,7 +2,11 @@ require 'tilt'
|
|
2
2
|
|
3
3
|
module Luca
|
4
4
|
class Template < Tilt::Template
|
5
|
-
|
5
|
+
|
6
|
+
def self.namespace
|
7
|
+
'JST'
|
8
|
+
end
|
9
|
+
|
6
10
|
def self.default_mime_type
|
7
11
|
'application/javascript'
|
8
12
|
end
|
@@ -20,7 +24,6 @@ module Luca
|
|
20
24
|
def prepare
|
21
25
|
options = @options.merge(:filename => eval_file, :line => line, :escape_attrs => false)
|
22
26
|
@engine = ::Haml::Engine.new(data, options)
|
23
|
-
self.namespace = "window.JST"
|
24
27
|
end
|
25
28
|
|
26
29
|
def evaluate(scope, locals, &block)
|
@@ -28,15 +31,12 @@ module Luca
|
|
28
31
|
code = EJS.compile(compiled)
|
29
32
|
tmpl = scope.logical_path
|
30
33
|
|
31
|
-
|
34
|
+
namespace = self.class.namespace
|
32
35
|
|
36
|
+
tmpl.gsub! /^.*\/templates\//, ''
|
37
|
+
|
33
38
|
<<-JST
|
34
|
-
|
35
|
-
(function() {
|
36
|
-
#{namespace} || (#{namespace} = {});
|
37
|
-
#{namespace}[#{ tmpl.inspect }] = #{indent(code)};
|
38
|
-
}).call(this);
|
39
|
-
|
39
|
+
(function() {#{namespace} || (#{namespace} = {}); #{namespace}[#{ tmpl.inspect }] = #{indent(code)}; }).call(this);
|
40
40
|
JST
|
41
41
|
end
|
42
42
|
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/**
|
2
|
+
* Bootstrap.js by @fat & @mdo
|
3
|
+
* plugins: bootstrap-transition.js, bootstrap-modal.js, bootstrap-dropdown.js, bootstrap-tooltip.js, bootstrap-popover.js, bootstrap-alert.js, bootstrap-button.js, bootstrap-collapse.js, bootstrap-typeahead.js
|
4
|
+
* Copyright 2012 Twitter, Inc.
|
5
|
+
* http://www.apache.org/licenses/LICENSE-2.0.txt
|
6
|
+
*/
|
7
|
+
!function(a){a(function(){a.support.transition=function(){var a=function(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",msTransition:"MSTransitionEnd",transition:"transitionend"},c;for(c in b)if(a.style[c]!==undefined)return b[c]}();return a&&{end:a}}()})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('<div class="modal-backdrop '+d+'" />').appendTo(document.body),this.options.backdrop!="static"&&this.$backdrop.click(a.proxy(this.hide,this)),e&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),e?this.$backdrop.one(a.support.transition.end,b):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,a.proxy(f,this)):f.call(this)):b&&b()}function f(){this.$backdrop.remove(),this.$backdrop=null}function g(){var b=this;this.isShown&&this.options.keyboard?a(document).on("keyup.dismiss.modal",function(a){a.which==27&&b.hide()}):this.isShown||a(document).off("keyup.dismiss.modal")}var b=function(b,c){this.options=c,this.$element=a(b).delegate('[data-dismiss="modal"]',"click.dismiss.modal",a.proxy(this.hide,this))};b.prototype={constructor:b,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var b=this,c=a.Event("show");this.$element.trigger(c);if(this.isShown||c.isDefaultPrevented())return;a("body").addClass("modal-open"),this.isShown=!0,g.call(this),e.call(this,function(){var c=a.support.transition&&b.$element.hasClass("fade");b.$element.parent().length||b.$element.appendTo(document.body),b.$element.show(),c&&b.$element[0].offsetWidth,b.$element.addClass("in"),c?b.$element.one(a.support.transition.end,function(){b.$element.trigger("shown")}):b.$element.trigger("shown")})},hide:function(b){b&&b.preventDefault();var e=this;b=a.Event("hide"),this.$element.trigger(b);if(!this.isShown||b.isDefaultPrevented())return;this.isShown=!1,a("body").removeClass("modal-open"),g.call(this),this.$element.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?c.call(this):d.call(this)}},a.fn.modal=function(c){return this.each(function(){var d=a(this),e=d.data("modal"),f=a.extend({},a.fn.modal.defaults,d.data(),typeof c=="object"&&c);e||d.data("modal",e=new b(this,f)),typeof c=="string"?e[c]():f.show&&e.show()})},a.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},a.fn.modal.Constructor=b,a(function(){a("body").on("click.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("modal")?"toggle":a.extend({},e.data(),c.data());b.preventDefault(),e.modal(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e,f,g;if(c.is(".disabled, :disabled"))return;return f=c.attr("data-target"),f||(f=c.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,"")),e=a(f),e.length||(e=c.parent()),g=e.hasClass("open"),d(),g||e.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown",".dropdown form",function(a){a.stopPropagation()}).on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){var b=function(a,b){this.init("tooltip",a,b)};b.prototype={constructor:b,init:function(b,c,d){var e,f;this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.enabled=!0,this.options.trigger!="manual"&&(e=this.options.trigger=="hover"?"mouseenter":"focus",f=this.options.trigger=="hover"?"mouseleave":"blur",this.$element.on(e,this.options.selector,a.proxy(this.enter,this)),this.$element.on(f,this.options.selector,a.proxy(this.leave,this))),this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(b){return b=a.extend({},a.fn[this.type].defaults,b,this.$element.data()),b.delay&&typeof b.delay=="number"&&(b.delay={show:b.delay,hide:b.delay}),b},enter:function(b){var c=a(b.currentTarget)[this.type](this._options).data(this.type);if(!c.options.delay||!c.options.delay.show)return c.show();clearTimeout(this.timeout),c.hoverState="in",this.timeout=setTimeout(function(){c.hoverState=="in"&&c.show()},c.options.delay.show)},leave:function(b){var c=a(b.currentTarget)[this.type](this._options).data(this.type);if(!c.options.delay||!c.options.delay.hide)return c.hide();clearTimeout(this.timeout),c.hoverState="out",this.timeout=setTimeout(function(){c.hoverState=="out"&&c.hide()},c.options.delay.hide)},show:function(){var a,b,c,d,e,f,g;if(this.hasContent()&&this.enabled){a=this.tip(),this.setContent(),this.options.animation&&a.addClass("fade"),f=typeof this.options.placement=="function"?this.options.placement.call(this,a[0],this.$element[0]):this.options.placement,b=/in/.test(f),a.remove().css({top:0,left:0,display:"block"}).appendTo(b?this.$element:document.body),c=this.getPosition(b),d=a[0].offsetWidth,e=a[0].offsetHeight;switch(b?f.split(" ")[1]:f){case"bottom":g={top:c.top+c.height,left:c.left+c.width/2-d/2};break;case"top":g={top:c.top-e,left:c.left+c.width/2-d/2};break;case"left":g={top:c.top+c.height/2-e/2,left:c.left-d};break;case"right":g={top:c.top+c.height/2-e/2,left:c.left+c.width}}a.css(g).addClass(f).addClass("in")}},isHTML:function(a){return typeof a!="string"||a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3||/^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(a)},setContent:function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.isHTML(b)?"html":"text"](b),a.removeClass("fade in top bottom left right")},hide:function(){function d(){var b=setTimeout(function(){c.off(a.support.transition.end).remove()},500);c.one(a.support.transition.end,function(){clearTimeout(b),c.remove()})}var b=this,c=this.tip();c.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d():c.remove()},fixTitle:function(){var a=this.$element;(a.attr("title")||typeof a.attr("data-original-title")!="string")&&a.attr("data-original-title",a.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(b){return a.extend({},b?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||(typeof c.title=="function"?c.title.call(b[0]):c.title),a},tip:function(){return this.$tip=this.$tip||a(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(){this[this.tip().hasClass("in")?"hide":"show"]()}},a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("tooltip"),f=typeof c=="object"&&c;e||d.data("tooltip",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.tooltip.Constructor=b,a.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover",title:"",delay:0}}(window.jQuery),!function(a){var b=function(a,b){this.init("popover",a,b)};b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype,{constructor:b,setContent:function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.isHTML(b)?"html":"text"](b),a.find(".popover-content > *")[this.isHTML(c)?"html":"text"](c),a.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var a,b=this.$element,c=this.options;return a=b.attr("data-content")||(typeof c.content=="function"?c.content.call(b[0]):c.content),a},tip:function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip}}),a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("popover"),f=typeof c=="object"&&c;e||d.data("popover",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.defaults=a.extend({},a.fn.tooltip.defaults,{placement:"right",content:"",template:'<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'})}(window.jQuery),!function(a){var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function f(){e.trigger("closed").remove()}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger(b=a.Event("close"));if(b.isDefaultPrevented())return;e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(function(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle")})})}(window.jQuery),!function(a){var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b,c,d,e;if(this.transitioning)return;b=this.dimension(),c=a.camelCase(["scroll",b].join("-")),d=this.$parent&&this.$parent.find("> .accordion-group > .in");if(d&&d.length){e=d.data("collapse");if(e&&e.transitioning)return;d.collapse("hide"),e||d.data("collapse",null)}this.$element[b](0),this.transition("addClass",a.Event("show"),"shown"),this.$element[b](this.$element[0][c])},hide:function(){var b;if(this.transitioning)return;b=this.dimension(),this.reset(this.$element[b]()),this.transition("removeClass",a.Event("hide"),"hidden"),this.$element[b](0)},reset:function(a){var b=this.dimension();return this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element[a!==null?"addClass":"removeClass"]("collapse"),this},transition:function(b,c,d){var e=this,f=function(){c.type=="show"&&e.reset(),e.transitioning=0,e.$element.trigger(d)};this.$element.trigger(c);if(c.isDefaultPrevented())return;this.transitioning=1,this.$element[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.typeahead.defaults,c),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.$menu=a(this.options.menu).appendTo("body"),this.source=this.options.source,this.shown=!1,this.listen()};b.prototype={constructor:b,select:function(){var a=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(a)).change(),this.hide()},updater:function(a){return a},show:function(){var b=a.extend({},this.$element.offset(),{height:this.$element[0].offsetHeight});return this.$menu.css({top:b.top+b.height,left:b.left}),this.$menu.show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(b){var c=this,d,e;return this.query=this.$element.val(),this.query?(d=a.grep(this.source,function(a){return c.matcher(a)}),d=this.sorter(d),d.length?this.render(d.slice(0,this.options.items)).show():this.shown?this.hide():this):this.shown?this.hide():this},matcher:function(a){return~a.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(a){var b=[],c=[],d=[],e;while(e=a.shift())e.toLowerCase().indexOf(this.query.toLowerCase())?~e.indexOf(this.query)?c.push(e):d.push(e):b.push(e);return b.concat(c,d)},highlighter:function(a){var b=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return a.replace(new RegExp("("+b+")","ig"),function(a,b){return"<strong>"+b+"</strong>"})},render:function(b){var c=this;return b=a(b).map(function(b,d){return b=a(c.options.item).attr("data-value",d),b.find("a").html(c.highlighter(d)),b[0]}),b.first().addClass("active"),this.$menu.html(b),this},next:function(b){var c=this.$menu.find(".active").removeClass("active"),d=c.next();d.length||(d=a(this.$menu.find("li")[0])),d.addClass("active")},prev:function(a){var b=this.$menu.find(".active").removeClass("active"),c=b.prev();c.length||(c=this.$menu.find("li").last()),c.addClass("active")},listen:function(){this.$element.on("blur",a.proxy(this.blur,this)).on("keypress",a.proxy(this.keypress,this)).on("keyup",a.proxy(this.keyup,this)),(a.browser.webkit||a.browser.msie)&&this.$element.on("keydown",a.proxy(this.keypress,this)),this.$menu.on("click",a.proxy(this.click,this)).on("mouseenter","li",a.proxy(this.mouseenter,this))},keyup:function(a){switch(a.keyCode){case 40:case 38:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}a.stopPropagation(),a.preventDefault()},keypress:function(a){if(!this.shown)return;switch(a.keyCode){case 9:case 13:case 27:a.preventDefault();break;case 38:if(a.type!="keydown")break;a.preventDefault(),this.prev();break;case 40:if(a.type!="keydown")break;a.preventDefault(),this.next()}a.stopPropagation()},blur:function(a){var b=this;setTimeout(function(){b.hide()},150)},click:function(a){a.stopPropagation(),a.preventDefault(),this.select()},mouseenter:function(b){this.$menu.find(".active").removeClass("active"),a(b.currentTarget).addClass("active")}},a.fn.typeahead=function(c){return this.each(function(){var d=a(this),e=d.data("typeahead"),f=typeof c=="object"&&c;e||d.data("typeahead",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>'},a.fn.typeahead.Constructor=b,a(function(){a("body").on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(b){var c=a(this);if(c.data("typeahead"))return;b.preventDefault(),c.typeahead(c.data())})})}(window.jQuery)
|
@@ -847,8 +847,16 @@ button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-ap
|
|
847
847
|
.with-mask .load-mask .progress {
|
848
848
|
margin: 50px auto;
|
849
849
|
width: 50%; }
|
850
|
+
html.luca-ui-fullscreen, body.luca-ui-fullscreen {
|
851
|
+
height: 100%; }
|
852
|
+
|
853
|
+
.luca-ui-fullscreen .fluid-viewport-wrapper {
|
854
|
+
padding-top: 40px; }
|
855
|
+
.luca-ui-fullscreen .luca-ui-viewport, .luca-ui-fullscreen .fullscreen-container {
|
856
|
+
min-height: 100%;
|
857
|
+
height: auto !important;
|
858
|
+
height: 100%; }
|
850
859
|
.toolbar-container {
|
851
|
-
overflow: hidden;
|
852
860
|
clear: both; }
|
853
861
|
|
854
862
|
.toolbar-container.top {
|
@@ -1286,6 +1294,16 @@ ul.typeahead.dropdown-menu {
|
|
1286
1294
|
.font-large .CodeMirror {
|
1287
1295
|
font-size: 18px;
|
1288
1296
|
line-height: 1.7; }
|
1297
|
+
|
1298
|
+
#component_tester #editor_container .toolbar-container.bottom {
|
1299
|
+
margin: 0px; }
|
1300
|
+
#component_tester #editor_container .toolbar-container.bottom .luca-ui-toolbar {
|
1301
|
+
margin: 0px;
|
1302
|
+
padding: 0px; }
|
1303
|
+
#component_tester [data-luca-owner="component_detail"] {
|
1304
|
+
max-height: 600px;
|
1305
|
+
overflow: scroll;
|
1306
|
+
min-height: 400px; }
|
1289
1307
|
.luca-ui-console .CodeMirror {
|
1290
1308
|
font-family: "Monaco";
|
1291
1309
|
font-size: 14px;
|
@@ -196,6 +196,16 @@ ul.typeahead.dropdown-menu {
|
|
196
196
|
.font-large .CodeMirror {
|
197
197
|
font-size: 18px;
|
198
198
|
line-height: 1.7; }
|
199
|
+
|
200
|
+
#component_tester #editor_container .toolbar-container.bottom {
|
201
|
+
margin: 0px; }
|
202
|
+
#component_tester #editor_container .toolbar-container.bottom .luca-ui-toolbar {
|
203
|
+
margin: 0px;
|
204
|
+
padding: 0px; }
|
205
|
+
#component_tester [data-luca-owner="component_detail"] {
|
206
|
+
max-height: 600px;
|
207
|
+
overflow: scroll;
|
208
|
+
min-height: 400px; }
|
199
209
|
.luca-ui-console .CodeMirror {
|
200
210
|
font-family: "Monaco";
|
201
211
|
font-size: 14px;
|