luca 0.9.89 → 0.9.91

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. data/CHANGELOG +11 -1
  2. data/Gemfile +5 -2
  3. data/Gemfile.lock +84 -56
  4. data/Rakefile +10 -2
  5. data/app/assets/javascripts/luca/components/application.coffee +82 -89
  6. data/app/assets/javascripts/luca/components/collection_view.coffee +9 -5
  7. data/app/assets/javascripts/luca/components/controller.coffee +72 -11
  8. data/app/assets/javascripts/luca/components/fields/base.coffee +61 -8
  9. data/app/assets/javascripts/luca/components/fields/button_field.coffee +53 -7
  10. data/app/assets/javascripts/luca/components/fields/checkbox_array.coffee +12 -7
  11. data/app/assets/javascripts/luca/components/fields/text_field.coffee +1 -1
  12. data/app/assets/javascripts/luca/components/form_view.coffee +2 -2
  13. data/app/assets/javascripts/luca/components/grid_layout_view.coffee +0 -1
  14. data/app/assets/javascripts/luca/components/page.coffee +1 -0
  15. data/app/assets/javascripts/luca/components/table_view.coffee +2 -2
  16. data/app/assets/javascripts/luca/concerns/dom_helpers.coffee +2 -2
  17. data/app/assets/javascripts/luca/containers/card_view.coffee +84 -54
  18. data/app/assets/javascripts/luca/containers/container.coffee +126 -46
  19. data/app/assets/javascripts/luca/containers/modal_view.coffee +9 -9
  20. data/app/assets/javascripts/luca/containers/page_controller.coffee +25 -0
  21. data/app/assets/javascripts/luca/containers/panel_toolbar.coffee +1 -1
  22. data/app/assets/javascripts/luca/containers/viewport.coffee +2 -5
  23. data/app/assets/javascripts/luca/core/collection.coffee +18 -4
  24. data/app/assets/javascripts/luca/core/model.coffee +1 -1
  25. data/app/assets/javascripts/luca/core/panel.coffee +1 -1
  26. data/app/assets/javascripts/luca/core/view.coffee +26 -7
  27. data/app/assets/javascripts/luca/development/code_sync_manager.coffee +51 -4
  28. data/app/assets/javascripts/luca/development/console.coffee +1 -1
  29. data/app/assets/javascripts/luca/framework.coffee +1 -1
  30. data/app/assets/javascripts/luca/index.coffee +1 -0
  31. data/app/assets/javascripts/luca/util/luca.coffee +2 -1
  32. data/app/assets/stylesheets/luca/components/viewport.scss +0 -4
  33. data/bin/luca +14 -0
  34. data/docs/framework.json +1 -1
  35. data/docs/luca-framework-documentation.js +1 -0
  36. data/lib/luca/cli/generate.rb +37 -0
  37. data/lib/luca/cli/server.rb +20 -0
  38. data/lib/luca/cli/sync.rb +40 -0
  39. data/lib/luca/cli/watch.rb +16 -0
  40. data/lib/luca/cli.rb +68 -0
  41. data/lib/luca/collection/endpoint.rb +1 -0
  42. data/lib/luca/component_definition.rb +23 -5
  43. data/lib/luca/luca_application.rb +18 -7
  44. data/lib/luca/rails/version.rb +1 -1
  45. data/lib/luca/server.rb +7 -0
  46. data/lib/luca/stylesheet.rb +2 -3
  47. data/lib/luca/version.rb +3 -0
  48. data/lib/luca/watcher.rb +72 -0
  49. data/lib/luca.rb +8 -1
  50. data/luca.gemspec +14 -7
  51. data/site/.bundle/config +2 -0
  52. data/site/.gitignore +5 -0
  53. data/site/.rvmrc +1 -0
  54. data/site/CHANGELOG.md +41 -0
  55. data/site/DOCS.md +41 -0
  56. data/site/Gemfile +8 -0
  57. data/site/Gemfile.lock +134 -0
  58. data/site/LICENSE.md +19 -0
  59. data/site/config.rb +84 -0
  60. data/site/helpers/site_helpers.rb +20 -0
  61. data/site/html5bp-docs/README.md +38 -0
  62. data/site/html5bp-docs/contribute.md +104 -0
  63. data/site/html5bp-docs/crossdomain.md +21 -0
  64. data/site/html5bp-docs/css.md +135 -0
  65. data/site/html5bp-docs/extend.md +507 -0
  66. data/site/html5bp-docs/faq.md +77 -0
  67. data/site/html5bp-docs/htaccess.md +323 -0
  68. data/site/html5bp-docs/html.md +170 -0
  69. data/site/html5bp-docs/js.md +31 -0
  70. data/site/html5bp-docs/misc.md +25 -0
  71. data/site/html5bp-docs/usage.md +109 -0
  72. data/site/readme.md +47 -0
  73. data/site/source/.htaccess +540 -0
  74. data/site/source/404.html +157 -0
  75. data/site/source/app/assets/javascripts/dependencies.js.coffee +6 -0
  76. data/site/source/app/assets/javascripts/docs/application.coffee +64 -0
  77. data/site/source/app/assets/javascripts/docs/collections/docs_documentation.coffee +17 -0
  78. data/site/source/app/assets/javascripts/docs/collections/github_repositories.coffee +7 -0
  79. data/site/source/app/assets/javascripts/docs/collections/index.coffee +1 -0
  80. data/site/source/app/assets/javascripts/docs/collections/luca_documentation.coffee +17 -0
  81. data/site/source/app/assets/javascripts/docs/collections/public_gists.coffee +4 -0
  82. data/site/source/app/assets/javascripts/docs/config.coffee +5 -0
  83. data/site/source/app/assets/javascripts/docs/index.coffee +12 -0
  84. data/site/source/app/assets/javascripts/docs/lib/router.coffee +3 -0
  85. data/site/source/app/assets/javascripts/docs/lib/util.coffee +0 -0
  86. data/site/source/app/assets/javascripts/docs/models/component.coffee +99 -0
  87. data/site/source/app/assets/javascripts/docs/models/github_repository.coffee +3 -0
  88. data/site/source/app/assets/javascripts/docs/models/index.coffee +1 -0
  89. data/site/source/app/assets/javascripts/docs/templates/component_documentation.jst.ejs +55 -0
  90. data/site/source/app/assets/javascripts/docs/templates/examples_browser/overview.jst.ejs +4 -0
  91. data/site/source/app/assets/javascripts/docs/templates/examples_browser/selector.jst.ejs +11 -0
  92. data/site/source/app/assets/javascripts/docs/templates/github_repository.jst.ejs +4 -0
  93. data/site/source/app/assets/javascripts/docs/templates/layouts/main.jst.ejs +4 -0
  94. data/site/source/app/assets/javascripts/docs/templates/left_navigation.jst.ejs +5 -0
  95. data/site/source/app/assets/javascripts/docs/templates/pages/getting_started.jst.ejs +78 -0
  96. data/site/source/app/assets/javascripts/docs/templates/pages/home.jst.ejs +57 -0
  97. data/site/source/app/assets/javascripts/docs/views/components/code_editor/index.coffee +0 -0
  98. data/site/source/app/assets/javascripts/docs/views/components/code_editor.coffee +45 -0
  99. data/site/source/app/assets/javascripts/docs/views/components/component_documentation.coffee +72 -0
  100. data/site/source/app/assets/javascripts/docs/views/index.coffee +3 -0
  101. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/details.coffee +37 -0
  102. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/list.coffee +31 -0
  103. data/site/source/app/assets/javascripts/docs/views/pages/browse_source.coffee +46 -0
  104. data/site/source/app/assets/javascripts/docs/views/pages/component_editor.coffee +10 -0
  105. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/docs.coffee +12 -0
  106. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/source.coffee +13 -0
  107. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser.coffee +102 -0
  108. data/site/source/app/assets/javascripts/docs/views/pages/home.coffee +10 -0
  109. data/site/source/app/assets/javascripts/docs/views/views/api_browser/index.coffee +43 -0
  110. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/grid_layout_view_example.coffee +14 -0
  111. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/table_view_example.coffee +39 -0
  112. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/basic_example.coffee +38 -0
  113. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/complex_layout.coffee +110 -0
  114. data/site/source/app/assets/javascripts/docs/views/views/top_navigation.coffee +6 -0
  115. data/site/source/app/assets/javascripts/docs-docs.js +1 -0
  116. data/site/source/app/assets/javascripts/luca-docs.js +1 -0
  117. data/site/source/app/assets/javascripts/luca-framework-documentation.js +1 -0
  118. data/site/source/app/assets/javascripts/site.js.coffee +4 -0
  119. data/site/source/app/assets/javascripts/vendor/codemirror.js +4786 -0
  120. data/site/source/app/assets/javascripts/vendor/coffeescript.js +346 -0
  121. data/site/source/app/assets/javascripts/vendor/css.js +465 -0
  122. data/site/source/app/assets/javascripts/vendor/htmlmixed.js +84 -0
  123. data/site/source/app/assets/javascripts/vendor/javascript.js +422 -0
  124. data/site/source/app/assets/javascripts/vendor/js-beautify.js +1353 -0
  125. data/site/source/app/assets/javascripts/vendor/modernizr-2.6.1.min.js +4 -0
  126. data/site/source/app/assets/javascripts/vendor/vim.js +2511 -0
  127. data/site/source/app/assets/stylesheets/docs/api-browser.css.scss +5 -0
  128. data/site/source/app/assets/stylesheets/docs/application.css.scss +35 -0
  129. data/site/source/app/assets/stylesheets/docs/browse-source.css.scss +5 -0
  130. data/site/source/app/assets/stylesheets/docs/scrollable-table.css.scss +5 -0
  131. data/site/source/app/assets/stylesheets/site.css.scss +2 -0
  132. data/site/source/app/assets/stylesheets/vendor/codemirror.css +240 -0
  133. data/site/source/app/assets/stylesheets/vendor/prettify-tomorrow-night-bright.css +160 -0
  134. data/site/source/app/assets/stylesheets/vendor/twilight.css +26 -0
  135. data/site/source/crossdomain.xml +15 -0
  136. data/site/source/documentation.html.haml +1 -0
  137. data/site/source/favicon_base.png +0 -0
  138. data/site/source/humans.txt +15 -0
  139. data/site/source/images/background.png +0 -0
  140. data/site/source/images/middleman.png +0 -0
  141. data/site/source/index.html.haml +1 -0
  142. data/site/source/layouts/layout.haml +55 -0
  143. data/site/source/readme.md +63 -0
  144. data/site/source/robots.txt +3 -0
  145. data/spec/javascripts/components/collection_view_spec.coffee +1 -1
  146. data/spec/javascripts/containers/card_view_spec.coffee +58 -5
  147. data/spec/javascripts/core/collection_spec.coffee +1 -1
  148. data/spec/javascripts/core/view_spec.coffee +2 -2
  149. data/vendor/assets/javascripts/backbone-min.js +37 -33
  150. data/vendor/assets/javascripts/backbone-query.min.js +1 -1
  151. data/vendor/assets/javascripts/jquery.js +5 -4
  152. data/vendor/assets/javascripts/luca-dependencies.min.js +8 -6
  153. data/vendor/assets/javascripts/luca-development.min.js +1 -1
  154. data/vendor/assets/javascripts/luca.full.min.js +12 -10
  155. data/vendor/assets/javascripts/luca.min.js +5 -5
  156. data/vendor/assets/javascripts/underscore-min.js +1 -5
  157. data/vendor/assets/javascripts/underscore-string.min.js +1 -1
  158. data/vendor/assets/stylesheets/luca-components.css +0 -2
  159. data/vendor/assets/stylesheets/luca-development.css +1 -1
  160. metadata +215 -39
  161. data/app/assets/javascripts/luca/components/page_controller.coffee +0 -3
  162. data/app/assets/javascripts/luca/core/collection_view.coffee +0 -150
  163. data/site/assets/bootstrap.min.js +0 -7
  164. data/site/assets/dependencies.js +0 -94
  165. data/site/assets/glyphicons-halflings-white.png +0 -0
  166. data/site/assets/glyphicons-halflings.png +0 -0
  167. data/site/assets/luca-ui-bootstrap.css +0 -1331
  168. data/site/assets/luca-ui-bootstrap.js +0 -9
  169. data/site/assets/luca-ui-development-tools.css +0 -234
  170. data/site/assets/luca-ui-development-tools.js +0 -18561
  171. data/site/assets/luca-ui-development-tools.min.js +0 -15
  172. data/site/assets/luca-ui-full.min.js +0 -8
  173. data/site/assets/luca-ui.min.js +0 -4
  174. data/site/assets/sandbox.css +0 -62
  175. data/site/assets/sandbox.js +0 -469
  176. data/site/docs/application.html +0 -41
  177. data/site/docs/caching.html +0 -43
  178. data/site/docs/collection.html +0 -75
  179. data/site/docs/collection_manager.html +0 -71
  180. data/site/docs/containers.html +0 -118
  181. data/site/docs/events.html +0 -153
  182. data/site/docs/view.html +0 -128
  183. data/site/img/glyphicons-halflings-white.png +0 -0
  184. data/site/img/glyphicons-halflings.png +0 -0
  185. data/site/index.html +0 -20
  186. data/site/source-map.js +0 -1
data/site/source-map.js DELETED
@@ -1 +0,0 @@
1
- [{"className":"Luca.Application","file":"src/components/application.coffee","source":"# Luca.Application \n#\n# The Application class is the global state tracking mechanism\n# for your single page application, as well as the entry point.\n#\n# By default it contains a main controller which is a Luca.components.Controller instance. \n#\n# In a typical Luca application, the router will use the applications @navigate_to() method to switch\n# from page to page on the main controller, or any other controllers nested inside of it.\n#\n# You would control flow when the controller fires activation events on the nested view components inside of it.\n#\n# Decoupling application control flow from the URL Fragment from Backbone.History and preventing\n# your components from directly caring about the URL Fragment, allows you to build applications as\n# isolated components which can run separately or nested inside of other applications. \n\nstartHistory = ()-> Backbone.history.start()\n\n_.def('Luca.Application').extends('Luca.containers.Viewport').with\n name: \"MyApp\"\n\n # The Application uses a Backbone.Model as a state machine, which\n # allows you to get / set attributes, persist them somewhere, and\n # most importantly to bind to change events of certain attributes.\n #\n # the @defaultState property will be the default attributes\n defaultState: {}\n\n # if autoBoot is set to true, the application will \n # attempt to boot on document ready.\n autoBoot: false\n\n # automatically starts the @router if it exists, \n # once the components for the application have \n # been created. Pass the event name you want to\n # listen for on this component before you start history\n autoStartHistory: \"before:render\"\n\n # we will create a collection manager singleton\n # by default unless otherwise specified. \n useCollectionManager: true\n\n # to pass options to the collection manager, set the @collectionManager\n # hash which will get passed once the collection manager is created\n collectionManager: {}\n\n # by default we will use the standard collection manager which ships with\n # Luca. If you would like to use your own extension of the collection manager\n # just pass a reference to the class you would like to use. \n collectionManagerClass: \"Luca.CollectionManager\"\n\n # Luca plugin apps are apps which mount onto existing\n # luca apps, and will not have the behavior of a main\n # app which acts as a singleton\n plugin: false\n\n # by default, the application will use a controller\n # component, which is a card view container which shows\n # one view at a time. this is useful for having an application\n # with several 'pages' so to speak\n useController: true\n\n # Key Handler\n # \n # One responsibility of the application, since it is a viewport which monopolizes the entire screen\n # is to relay keypress events from the document, to whatever views are interested in responding to them.\n #\n # This functionality is disabled by default.\n useKeyHandler: false\n\n # You can configure key events by specifying them by their name, as it exists in Luca.keyMap. For example:\n #\n # keyEvents\n # keyup: keyUpHandler\n # enter: enterHandler\n # meta:\n # up: metaUpHandler\n # control:\n # forwardslash: controlSlashHandler\n # keyup: controlUpHandler\n # control_meta:\n # keydown: metaControlKeyDownHandler\n #\n keyEvents: {} \n\n # applications have one component, the controller.\n # any components defined on the application class directly\n # will get wrapped by the main controller unless you\n # set useController = false\n components:[\n ctype: 'template'\n name: 'welcome'\n template: 'sample/welcome'\n templateContainer: \"Luca.templates\"\n ]\n\n initialize: (@options={})->\n app = @\n appName = @name\n alreadyRunning = Luca.getApplication?()\n\n Luca.Application.instances ||= {}\n Luca.Application.instances[ appName ] = app\n \n Luca.containers.Viewport::initialize.apply @, arguments\n\n @state = new Luca.Model( @defaultState )\n\n # The Controller is the piece of the application that handles showing\n # and hiding 'pages' of the app. The Application has a navigate_to\n # method which delegates to the controller, and allows you to navigate\n # to a given page, or component, by its name. The controller integrates\n # with the state machine of the application\n @setupMainController()\n\n # The Collection Manager is responsible \n @setupCollectionManager()\n\n # we will render when all of the various components\n # which handle our data dependencies determine that\n # we are ready\n @defer(()-> app.render()).until(@, \"ready\")\n\n # Set up the Backbone Router\n @setupRouter()\n\n # the keyHandler allows us to specify\n # keyEvents on our application with an API very similar\n # to the DOM events API for Backbone.View\n #\n # Example:\n #\n # keyEvents:\n # meta:\n # forwardslash: \"altSlashHandler\"\n console.log \"The useKeyRouter property is being deprecated. switch to useKeyHandler instead\"\n \n @setupKeyHandler() if (@useKeyHandler is true or @useKeyRouter is true) and @keyEvents?\n\n # if the application is a plugin designed to modify the behavior\n # of another app, then don't claim ownership. otherwise the most common\n # use-case is that there will be one application instance\n unless @plugin is true or alreadyRunning\n Luca.getApplication = (name)=> \n return app unless name?\n Luca.Application.instances[ name ] \n\n if @autoBoot\n if Luca.util.resolve(@name)\n throw \"Attempting to override window.#{ @name } when it already exists\"\n\n $ ->\n window[ appName ] = app \n app.boot()\n\n # @activeView() returns a reference to the instance of the view\n # which is currently monopolizing the viewport.\n #\n # this will be whicever component is active on the controllers\n # nested within the main controller, if there are any, or the view\n # itself which is active on the main controller. \n activeView: ()->\n if active = @activeSubSection()\n @view( active )\n else\n @view( @activeSection() )\n\n # Returns the name of the active component on the main controller \n activeSection: ()->\n @get(\"active_section\")\n\n # Returns the name of the active component on the nested controllers\n # on the main controller, if there is one. These get set on the\n # state machine in response to card switch events on the controller component\n activeSubSection: ()->\n @get(\"active_sub_section\")\n\n activePages: ()->\n @$('.luca-ui-controller').map (index,element)=> $(element).data('active-section')\n\n # boot should trigger the ready event, which will call the initial call\n # to render() your application, which will have a cascading effect on every\n # subcomponent in the view, recursively rendering everything which is set\n # to automatically render (i.e. any non-deferrable components ).\n #\n # you should use boot to fire up any dependent collections, manager, any\n # sort of data processing, whatever your application requires to run outside\n # of the views\n boot: ()->\n @trigger \"ready\"\n\n # delegate to the collection manager's get or create function.\n # use App.collection() to create or access existing collections\n collection: ()->\n @collectionManager.getOrCreate.apply(@collectionManager, arguments)\n\n get: (attribute)->\n @state.get(attribute)\n\n set: (attribute, value, options)->\n @state.set.apply(@state, arguments)\n\n view: (name)->\n Luca.cache(name)\n\n #### Navigation Hooks\n #\n # delegate to the main controller so that we can switch the active section\n navigate_to: (component_name, callback)->\n @getMainController().navigate_to(component_name, callback)\n\n getMainController: ()->\n return @components[0] if @useController is true\n Luca.cache('main_controller')\n\n # \n keyHandler: (e)->\n return unless e and @keyEvents\n\n isInputEvent = $(e.target).is('input') || $(e.target).is('textarea')\n\n return if isInputEvent\n\n keyname = Luca.keyMap[ e.keyCode ]\n\n return unless keyname\n\n meta = e?.metaKey is true\n control = e?.ctrlKey is true\n\n source = @keyEvents\n source = if meta then @keyEvents.meta else source\n source = if control then @keyEvents.control else source\n source = if meta and control then @keyEvents.meta_control else source\n\n if keyEvent = source?[keyname]\n if @[keyEvent]?\n @[keyEvent]?.call(@)\n else\n @trigger(keyEvent)\n\n setupControllerBindings: ()->\n # any time the main controller card switches we should track\n # the active card on the global state chart\n @getMainController()?.bind \"after:card:switch\", (previous,current)=>\n @state.set(active_section:current.name)\n\n # any time the card switches on one of the sub controllers\n # then we should track the active sub section on the global state chart\n @getMainController()?.each (component)=>\n if component.ctype.match(/controller$/)\n component.bind \"after:card:switch\", (previous,current)=>\n @state.set(active_sub_section:current.name) \n\n setupMainController: ()->\n if @useController is true\n definedComponents = @components || []\n\n @components = [\n ctype: 'controller'\n name: \"main_controller\"\n components: definedComponents\n ]\n\n @defer( @setupControllerBindings, false ).until(\"after:components\")\n\n setupCollectionManager: ()->\n if @useCollectionManager is true\n @collectionManagerClass = Luca.util.resolve( @collectionManagerClass ) if _.isString( @collectionManagerClass )\n\n collectionManagerOptions = @collectionManagerOptions\n\n if _.isObject(@collectionManager) and not _.isFunction( @collectionManager?.get )\n collectionManagerOptions = @collectionManager\n @collectionManager = undefined\n\n if _.isString(@collectionManager)\n collectionManagerOptions = \n name: @collectionManager\n\n @collectionManager = Luca.CollectionManager.get?( collectionManagerOptions.name )\n\n unless _.isFunction(@collectionManager?.get)\n @collectionManager = new @collectionManagerClass( collectionManagerOptions ) \n\n setupRouter: ()->\n app = @\n\n if _.isString( @router )\n routerClass = Luca.util.resolve(@router)\n @router = new routerClass({app})\n\n # if this application has a router associated with it\n # then we need to start backbone history on a certain event.\n # you can control which by setting the @startHistoryOn property\n if @router and @autoStartHistory\n @autoStartHistory = \"before:render\" if @autoStartHistory is true\n @defer(startHistory, false).until(@, @autoStartHistory) \n\n setupKeyHandler: ()->\n return unless @keyEvents\n\n @keyEvents.control_meta ||= {}\n\n # allow for both meta_control, control_meta for the combo\n _.extend(@keyEvents.control_meta, @keyEvents.meta_control) if @keyEvents.meta_control\n\n handler = _.bind(@keyHandler, @)\n\n $( document ).keydown( handler )\n\n"},{"className":"Luca.components.Toolbar","file":"src/components/base_toolbar.coffee","source":"_.def('Luca.components.Toolbar').extends('Luca.core.Container').with\n\n className: 'luca-ui-toolbar'\n\n position: 'bottom'\n\n initialize: (@options={})->\n Luca.core.Container::initialize.apply @, arguments\n\n prepareComponents: ()->\n _( @components ).each (component)=>\n component.container = @$el\n\n render: ()->\n $(@container).append(@el)"},{"className":"Luca.components.CollectionLoaderView","file":"src/components/collection_loader_view.coffee","source":"# Collection Loader View is a simple modal view\n# You can provide your own template for the collection loader modal\n# if you want to. Default implementation uses twitter bootstrap modal and\n# progress bar (http://twitter.github.com/bootstrap/). You template\n# should contain `progress`, `bar` and `message` classes\n_.def('Luca.components.CollectionLoaderView').extends('Luca.components.Template').with\n\n className: 'luca-ui-collection-loader-view'\n\n template: \"components/collection_loader_view\"\n\n initialize: (@options={})->\n Luca.components.Template::initialize.apply @,arguments\n\n @container ||= $('body')\n @manager ||= Luca.CollectionManager.get()\n\n @setupBindings()\n\n modalContainer: ()->\n $(\"#progress-modal\", @el)\n\n setupBindings: ()->\n @manager.bind \"collection_loaded\", (name)=>\n loaded = @manager.loadedCollectionsCount()\n total = @manager.totalCollectionsCount()\n progress = parseInt((loaded / total) * 100)\n collectionName = _.string.titleize( _.string.humanize( name ) )\n\n @modalContainer().find('.progress .bar').attr(\"style\", \"width: #{progress}%;\")\n @modalContainer().find('.message').html(\"Loaded #{ collectionName }...\")\n\n @manager.bind \"all_collections_loaded\", ()=>\n @modalContainer().find('.message').html(\"All done!\")\n _.delay ()=>\n @modalContainer().modal('hide')\n , 400"},{"className":"Luca.components.CollectionView","file":"src/components/collection_view.coffee","source":"make = Luca.View::make\n\n_.def(\"Luca.components.CollectionView\").extends(\"Luca.components.Panel\").with\n tagName: \"div\"\n\n className: \"luca-ui-collection-view\"\n\n bodyClassName: \"collection-ui-panel\"\n\n # A collection view can pass a model through to a template\n itemTemplate: undefined\n\n # A collection view can pass a model through a function which should return a string\n itemRenderer: undefined\n\n itemTagName: 'li'\n\n itemClassName: 'collection-item'\n\n initialize: (@options={})->\n _.extend(@, @options)\n\n _.bindAll @, \"refresh\"\n\n unless @collection? or @options.collection\n throw \"Collection Views must specify a collection\"\n\n unless @itemTemplate? || @itemRenderer? || @itemProperty?\n throw \"Collection Views must specify an item template or item renderer function\"\n\n Luca.components.Panel::initialize.apply(@, arguments)\n\n if _.isString(@collection) and Luca.CollectionManager.get()\n @collection = Luca.CollectionManager.get().get(@collection)\n\n if Luca.isBackboneCollection(@collection)\n @collection.bind \"reset\", @refresh\n @collection.bind \"add\", @refresh\n @collection.bind \"remove\", @refresh\n\n attributesForItem: (item)->\n _.extend {}, class: @itemClassName, \"data-index\": item.index\n\n contentForItem: (item={})->\n if @itemTemplate? and templateFn = Luca.template(@itemTemplate)\n content = templateFn.call(@, item)\n\n if @itemRenderer? and _.isFunction( @itemRenderer )\n content = @itemRenderer.call(@, item, item.model, item.index)\n\n if @itemProperty\n content = item.model.get(@itemProperty) || item.model[ @itemProperty ]\n content = content() if _.isFunction(content)\n\n content\n\n makeItem: (model, index)->\n item = if @prepareItem? then @prepareItem.call(@, model, index) else (model:model, index: index)\n\n make(@itemTagName, @attributesForItem(item), @contentForItem(item))\n\n getModels: ()->\n if @collection?.query and (@filter || @filterOptions)\n @collection.query(@filter, @filterOptions)\n else\n @collection.models\n\n refresh: ()->\n panel = @\n\n @$bodyEl().empty()\n\n _( @getModels() ).each (model, index)->\n panel.$append( panel.makeItem(model, index) )\n\n registerEvent: (domEvent, selector, handler)->\n if !handler? and _.isFunction(selector)\n handler = selector\n selector = undefined\n\n eventTrigger = _([domEvent,\"#{ @itemTagName }.#{ @itemClassName }\", selector]).compact().join(\" \")\n Luca.View::registerEvent(eventTrigger,handler)\n\n render: ()->\n @refresh()\n @$attach() if @$el.parent().length > 0 and @container?"},{"className":"Luca.components.Controller","file":"src/components/controller.coffee","source":"_.def('Luca.components.Controller').extends('Luca.containers.CardView').with\n\n additionalClassNames:['luca-ui-controller']\n\n activeAttribute: \"active-section\"\n\n initialize: (@options)->\n Luca.containers.CardView::initialize.apply @, arguments\n\n @defaultCard ||= @components[0]?.name\n\n throw \"Controllers must specify a defaultCard property and/or the first component must have a name\" unless @defaultCard\n\n @state = new Backbone.Model \n active_section: @defaultCard\n\n each: (fn)->\n _( @components ).each (component)=>\n fn.apply @, [component]\n\n activeSection: ()->\n @get(\"activeSection\")\n\n controllers:(deep=false)->\n @select 'ctype', 'controller', deep\n\n availableSections: ()->\n base = {}\n base[ @name ] = @sectionNames()\n\n _( @controllers() ).reduce (memo,controller)=>\n memo[ controller.name ] = controller.sectionNames() \n memo\n , base \n\n sectionNames: (deep=false)->\n @pluck('name')\n\n default: (callback)->\n @navigate_to(@defaultCard, callback)\n\n # switch the active card of this controller\n # optionally passing an onActivation callback\n # will fire this callback in the context of\n # the currently active card\n navigate_to: (section, callback)->\n section ||= @defaultCard\n\n # activate is a method on Luca.containers.CardView which\n # selects a component and makes it visible, hiding any\n # other component which may be monopolizing the view at that time.\n\n # after activation it triggers a after:card:switch event\n # and if it is the first time that view is being activated,\n # it triggers a first:activation event which gets relayed to all\n # child components in that view\n @activate section, false, (activator, previous,current)=>\n @state.set(active_section: current.name )\n if _.isFunction( callback )\n callback.apply(current)\n\n # return the section we are navigating to\n @find(section)\n"},{"className":"Luca.fields.ButtonField","file":"src/components/fields/button_field.coffee","source":"_.def('Luca.fields.ButtonField').extends('Luca.core.Field').with\n\n readOnly: true\n\n events:\n \"click input\" : \"click_handler\"\n\n hooks:[\n \"button:click\"\n ]\n\n className: 'luca-ui-field luca-ui-button-field'\n\n template: 'fields/button_field'\n\n click_handler: (e)->\n me = my = $( e.currentTarget )\n @trigger \"button:click\"\n\n initialize: (@options={})->\n _.extend @options\n _.bindAll @, \"click_handler\"\n\n Luca.core.Field::initialize.apply @, arguments\n\n @template = \"fields/button_field_link\" if @icon_class?.length\n\n afterInitialize: ()->\n @input_id ||= _.uniqueId('button')\n @input_name ||= @name ||= @input_id\n @input_value ||= @label ||= @text\n @input_type ||= \"button\"\n @input_class ||= @class\n @icon_class ||= \"\"\n @icon_class = \"icon-#{ @icon_class }\" if @icon_class.length and !@icon_class.match(/^icon-/)\n @icon_class += \" icon-white\" if @white\n\n setValue: ()-> true"},{"className":"Luca.fields.CheckboxArray","file":"src/components/fields/checkbox_array.coffee","source":"make = Luca.View::make\n\n_.def('Luca.fields.CheckboxArray').extends('Luca.core.Field').with\n version: 2\n\n template: \"fields/checkbox_array\"\n\n className: \"luca-ui-checkbox-array\"\n\n events:\n \"click input\" : \"clickHandler\"\n\n selectedItems: []\n\n initialize: (@options={})->\n _.extend @, @options\n _.extend @, Luca.modules.Deferrable\n _.bindAll @, \"renderCheckboxes\", \"clickHandler\", \"checkSelected\"\n\n Luca.core.Field::initialize.apply @, arguments\n\n @input_id ||= _.uniqueId('field')\n @input_name ||= @name\n @label ||= @name\n @valueField ||= \"id\"\n @displayField ||= \"name\"\n\n afterInitialize: (@options={})->\n try\n @configure_collection()\n catch e\n console.log \"Error Configuring Collection\", @, e.message\n\n cbArray = @\n\n if @collection.length > 0\n @renderCheckboxes()\n else\n @defer(\"renderCheckboxes\").until(@collection,\"reset\")\n\n clickHandler: (event)->\n checkbox = $(event.target)\n\n if checkbox.prop('checked')\n @selectedItems.push( checkbox.val() )\n else\n if _( @selectedItems ).include( checkbox.val() )\n @selectedItems = _( @selectedItems ).without( checkbox.val() )\n\n controls: ()->\n @$('.controls')\n\n renderCheckboxes: ()->\n @controls().empty()\n @selectedItems = []\n\n @collection.each (model)=>\n value = model.get(@valueField)\n label = model.get(@displayField)\n input_id = _.uniqueId(\"#{ @cid }_checkbox\")\n\n inputElement = make(\"input\",type:\"checkbox\",class:\"array-checkbox\",name:@input_name,value:value,id: input_id)\n element = make(\"label\", {for:input_id}, inputElement)\n\n $( element ).append(\" #{ label }\")\n @controls().append( element )\n\n @trigger(\"checkboxes:rendered\", @checkboxesRendered = true)\n @\n\n uncheckAll: ()->\n @allFields().prop('checked', false)\n\n allFields: ()->\n @controls().find(\"input[type='checkbox']\")\n\n checkSelected: (items)->\n @selectedItems = items if items?\n\n @uncheckAll()\n\n for value in @selectedItems\n checkbox = @controls().find(\"input[value='#{ value }']\")\n checkbox.prop('checked', true)\n\n @selectedItems\n\n getValue: ()->\n @$(field).val() for field in @allFields() when @$(field).prop('checked')\n\n setValue: (items)->\n @selectedItems = items\n\n if @checkboxesRendered is true\n @checkSelected(items)\n else\n cbArray = @\n @defer ()->\n cbArray.checkSelected(items)\n .until(\"checkboxes:rendered\")\n\n getValues: ()->\n @getValue()\n\n setValues: (items)->\n @setValue(items)"},{"className":"Luca.fields.CheckboxField","file":"src/components/fields/checkbox_field.coffee","source":"_.def('Luca.fields.CheckboxField').extends('Luca.core.Field').with\n\n events:\n \"change input\" : \"change_handler\"\n\n change_handler: (e)->\n me = my = $(e.currentTarget)\n\n @trigger \"on:change\", @, e\n\n if me.checked is true\n @trigger \"checked\"\n else\n @trigger \"unchecked\"\n\n className: 'luca-ui-checkbox-field luca-ui-field'\n\n template: 'fields/checkbox_field'\n\n hooks: [\"checked\",\"unchecked\"]\n\n send_blanks: true\n\n initialize: (@options={})->\n _.extend @, @options\n _.bindAll @, \"change_handler\"\n\n Luca.core.Field::initialize.apply @, arguments\n\n afterInitialize: ()->\n @input_id ||= _.uniqueId('field')\n @input_name ||= @name\n @input_value ||= 1\n @label ||= @name\n\n setValue: (checked)->\n @input.attr('checked', checked)\n\n getValue:()->\n @input.attr('checked') is true"},{"className":"Luca.fields.FileUploadField","file":"src/components/fields/file_upload_field.coffee","source":"_.def('Luca.fields.FileUploadField').extends('Luca.core.Field').with\n\n template: 'fields/file_upload_field'\n\n initialize: (@options={})->\n Luca.core.Field::initialize.apply @, arguments\n\n afterInitialize: ()->\n @input_id ||= _.uniqueId('field')\n @input_name ||= @name\n @label ||= @name\n @helperText ||= \"\"\n"},{"className":"Luca.fields.HiddenField","file":"src/components/fields/hidden_field.coffee","source":"_.def('Luca.fields.HiddenField').extends('Luca.core.Field').with\n\n template: 'fields/hidden_field'\n\n initialize: (@options={})->\n Luca.core.Field::initialize.apply @, arguments\n\n afterInitialize: ()->\n @input_id ||= _.uniqueId('field')\n @input_name ||= @name\n @input_value ||= @value\n @label ||= @name"},{"className":"Luca.fields.SelectField","file":"src/components/fields/select_field.coffee","source":"_.def('Luca.fields.SelectField').extends('Luca.core.Field').with\n\n events:\n \"change select\" : \"change_handler\"\n\n hooks:[\n \"after:select\"\n ]\n\n className: 'luca-ui-select-field luca-ui-field'\n\n template: \"fields/select_field\"\n\n includeBlank: true\n\n blankValue: ''\n\n blankText: 'Select One'\n\n initialize: (@options={})->\n _.extend @, @options\n _.extend @, Luca.modules.Deferrable\n _.bindAll @, \"change_handler\", \"populateOptions\", \"beforeFetch\"\n\n Luca.core.Field::initialize.apply @, arguments\n\n @input_id ||= _.uniqueId('field')\n @input_name ||= @name\n @label ||= @name\n @retainValue = true if _.isUndefined @retainValue\n\n afterInitialize: ()->\n if @collection?.data\n @valueField ||= \"id\"\n @displayField ||= \"name\"\n @parseData()\n\n try\n @configure_collection()\n catch e\n console.log \"Error Configuring Collection\", @, e.message\n\n @collection.bind \"before:fetch\", @beforeFetch\n @collection.bind \"reset\", @populateOptions\n\n # if the select field is configured with a data property\n # then parse that data into the proper format. either\n # an array of objects with the valueField and displayField\n # properties, or an array of arrays with [valueField, displayField]\n parseData: ()->\n @collection.data = _( @collection.data ).map (record)=>\n return record if not _.isArray( record )\n hash = {}\n hash[ @valueField ] = record[0]\n hash[ @displayField ] = record[1]\n\n hash\n\n\n afterRender: ()->\n @input = $('select', @el)\n\n if @collection?.models?.length > 0\n @populateOptions()\n else\n @collection.trigger(\"reset\")\n\n setValue: (value)->\n @currentValue = value\n Luca.core.Field::setValue.apply @, arguments\n\n beforeFetch: ()->\n @resetOptions()\n\n change_handler: (e)->\n @trigger \"on:change\", @, e\n\n resetOptions: ()->\n @input.html('')\n\n if @includeBlank\n @input.append(\"<option value='#{ @blankValue }'>#{ @blankText }</option>\")\n\n\n populateOptions: ()->\n @resetOptions()\n\n if @collection?.each?\n @collection.each (model) =>\n value = model.get( @valueField )\n display = model.get( @displayField )\n selected = \"selected\" if @selected and value is @selected\n option = \"<option #{ selected } value='#{ value }'>#{ display }</option>\"\n @input.append( option )\n\n @trigger \"after:populate:options\", @\n @setValue( @currentValue )"},{"className":"Luca.fields.TextAreaField","file":"src/components/fields/text_area_field.coffee","source":"_.def('Luca.fields.TextAreaField').extends('Luca.core.Field').with\n\n events:\n \"keydown input\" : \"keydown_handler\"\n \"blur input\" : \"blur_handler\"\n \"focus input\" : \"focus_handler\"\n\n template: 'fields/text_area_field'\n\n height: \"200px\"\n width: \"90%\"\n\n initialize: (@options={})->\n _.bindAll @, \"keydown_handler\"\n\n Luca.core.Field::initialize.apply @, arguments\n\n @input_id ||= _.uniqueId('field')\n @input_name ||= @name\n @label ||= @name\n @input_class ||= @class\n @inputStyles ||= \"height:#{ @height };width:#{ @width }\"\n\n setValue: (value)->\n $( @field() ).val(value)\n\n getValue: ()->\n $( @field() ).val()\n\n field: ()->\n @input = $(\"textarea##{ @input_id }\", @el)\n\n keydown_handler: (e)->\n me = my = $( e.currentTarget )\n\n blur_handler: (e)->\n me = my = $( e.currentTarget )\n\n focus_handler: (e)->\n me = my = $( e.currentTarget )"},{"className":"Luca.fields.TextField","file":"src/components/fields/text_field.coffee","source":"change_handler = (e)-> @trigger \"on:change\", @, e\n\n_.def('Luca.fields.TextField').extends('Luca.core.Field').with\n events:\n \"blur input\" : \"blur_handler\"\n \"focus input\" : \"focus_handler\"\n \"change input\" : \"change_handler\"\n\n template: 'fields/text_field'\n\n autoBindEventHandlers: true\n\n send_blanks: true\n\n initialize: (@options={})->\n Luca.core.Field::initialize.apply @, arguments\n\n @input_id ||= _.uniqueId('field')\n @input_name ||= @name\n @label ||= @name\n @input_class ||= @class\n\n if @prepend\n @$el.addClass('input-prepend')\n @addOn = @prepend\n\n if @append\n @$el.addClass('input-append')\n @addOn = @append\n\n @registerEvent(\"keydown input\",\"keydown_handler\") if @enableKeyEvents\n\n blur_handler: (e)->\n me = my = $( e.currentTarget )\n\n focus_handler: (e)->\n me = my = $( e.currentTarget )\n\n change_handler: change_handler\n keydown_handler: _.throttle ((e)-> change_handler.apply @, arguments), 300\n"},{"className":"Luca.fields.TypeAheadField","file":"src/components/fields/type_ahead_field.coffee","source":"_.def('Luca.fields.TypeAheadField').extends('Luca.fields.TextField').with\n className: 'luca-ui-field'\n\n getSource: ()->\n @source || []\n\n matcher: (item)->\n # IMPLEMENT\n # return true where item matches @query\n true\n\n beforeRender: ()->\n @_super(\"beforeRender\", @, arguments)\n @$('input').attr('data-provide','typeahead')\n\n afterRender: ()->\n @_super(\"afterRender\", @, arguments)\n\n @$('input').typeahead\n matcher: @matcher\n source: @getSource()"},{"className":"Luca.components.FormButtonToolbar","file":"src/components/form_button_toolbar.coffee","source":"_.def('Luca.components.FormButtonToolbar').extends('Luca.components.Toolbar').with\n\n className: 'luca-ui-form-toolbar form-actions'\n\n position: 'bottom'\n\n includeReset: false\n\n render: ()->\n $(@container).append(@el)\n\n initialize: (@options={})->\n Luca.components.Toolbar.prototype.initialize.apply @, arguments\n\n @components = [\n ctype: 'button_field'\n label: 'Submit'\n class: 'btn submit-button'\n ]\n\n if @includeReset\n @components.push\n ctype: 'button_field'\n label: 'Reset'\n class: 'btn reset-button'\n"},{"className":"Luca.components.FormView","file":"src/components/form_view.coffee","source":"defaultToolbar =\n buttons:[\n icon:\"remove-sign\"\n label: \"Reset\"\n eventId: \"click:reset\"\n className:\"reset-button\"\n align: 'right'\n ,\n icon:\"ok-sign\"\n white: true\n label: \"Save Changes\"\n eventId: \"click:submit\"\n color: \"success\"\n className: 'submit-button'\n align: 'right'\n ]\n\n_.def(\"Luca.components.FormView\").extends('Luca.core.Container').with\n\n tagName: 'form'\n\n className: 'luca-ui-form-view'\n\n hooks:[\n \"before:submit\"\n \"before:reset\"\n \"before:load\"\n \"before:load:new\"\n \"before:load:existing\"\n \"after:submit\"\n \"after:reset\"\n \"after:load\"\n \"after:load:new\"\n \"after:load:existing\"\n \"after:submit:success\"\n \"after:submit:fatal_error\"\n \"after:submit:error\"\n ]\n\n events:\n \"click .submit-button\" : \"submitHandler\"\n \"click .reset-button\" : \"resetHandler\"\n\n toolbar: true\n\n legend: \"\"\n\n bodyClassName: \"form-view-body\"\n\n initialize: (@options={})->\n @loadMask = Luca.enableBootstrap unless @loadMask?\n\n Luca.core.Container::initialize.apply @, arguments\n\n _.bindAll @, \"submitHandler\", \"resetHandler\", \"renderToolbars\", \"applyLoadMask\"\n\n @state ||= new Backbone.Model\n\n @setupHooks( @hooks )\n\n @applyStyleClasses()\n\n if @toolbar isnt false and (not @topToolbar and not @bottomToolbar)\n @topToolbar = @getDefaultToolbar() if @toolbar is \"both\" or @toolbar is \"top\"\n @bottomToolbar = @getDefaultToolbar() unless @toolbar is \"top\"\n\n getDefaultToolbar: ()->\n defaultToolbar\n\n applyStyleClasses: ()->\n if Luca.enableBootstrap\n @applyBootstrapStyleClasses()\n\n @$el.addClass( \"label-align-#{ @labelAlign }\") if @labelAlign\n @$el.addClass( @fieldLayoutClass ) if @fieldLayoutClass\n\n applyBootstrapStyleClasses: ()->\n @inlineForm = true if @labelAlign is \"left\"\n\n @$el.addClass('well') if @well\n @$el.addClass('form-search') if @searchForm\n @$el.addClass('form-horizontal') if @horizontalForm\n @$el.addClass('form-inline') if @inlineForm\n\n resetHandler: (e)->\n me = my = $( e?.target )\n @trigger \"before:reset\", @\n @reset()\n @trigger \"after:reset\", @\n\n submitHandler: (e)->\n me = my = $( e?.target )\n @trigger \"before:submit\", @\n @trigger \"enable:loadmask\", @ if @loadMask is true\n @submit() if @hasModel()\n\n afterComponents: ()->\n Luca.core.Container::afterComponents?.apply(@, arguments)\n\n @eachField (field)=>\n field.getForm = ()=> @\n field.getModel = ()=> @currentModel()\n\n eachField: (iterator)->\n _( @getFields() ).map( iterator )\n\n getField: (name)->\n _( @getFields('name', name) ).first()\n\n getFields: (attr,value)->\n # do a deep search of all of the nested components\n # to find the fields\n fields = @select(\"isField\", true, true)\n\n return fields unless attr and value\n # if an optional attribute and value pair is passed\n # then you can limit the array of fields even further\n _(fields).select (field)->\n property = field[ attr ]\n property? and value is (if _.isFunction(property) then property() else property)\n\n fields\n\n loadModel: (@current_model)->\n form = @\n fields = @getFields()\n\n @trigger \"before:load\", @, @current_model\n\n if @current_model\n @current_model.beforeFormLoad?.apply(@current_model, @)\n\n event = \"before:load:#{ (if @current_model.isNew() then \"new\" else \"existing\")}\"\n @trigger event, @, @current_model\n\n @setValues(@current_model)\n\n @trigger \"after:load\", @, @current_model\n\n if @current_model\n @trigger \"after:load:#{ (if @current_model.isNew() then \"new\" else \"existing\")}\", @, @current_model\n\n reset: ()->\n @loadModel( @current_model ) if @current_model?\n\n clear: ()->\n @current_model = if @defaultModel? then @defaultModel() else undefined\n\n _( @getFields() ).each (field)=>\n try\n field.setValue('')\n catch e\n console.log \"Error Clearing\", @, field\n\n # set the values on the form\n # without syncing\n setValues: (source, options={})->\n source ||= @currentModel()\n fields = @getFields()\n\n _( fields ).each (field) =>\n field_name = field.input_name || field.name\n\n if value = source[field_name]\n if _.isFunction(value)\n value = value.apply(@)\n\n if !value and Luca.isBackboneModel(source)\n value = source.get(field_name)\n\n field?.setValue( value ) unless field.readOnly is true\n\n @syncFormWithModel() unless options.silent? is true\n\n getValues: (options={})->\n options.reject_blank = true unless options.reject_blank?\n options.skip_buttons = true unless options.skip_buttons?\n\n _( @getFields() ).inject (memo,field)->\n value = field.getValue()\n key = field.input_name || field.name\n\n skip = false\n\n # don't include the values of buttons in our values hash\n skip = true if options.skip_buttons and field.ctype is \"button_field\"\n\n # if the value is blank and we are passed reject_blank in the options\n # then we should not include this field in our hash. however, if the\n # field is setup to send blanks, then we will send this value anyway\n if _.string.isBlank( value )\n skip = true if options.reject_blank and !field.send_blanks\n skip = true if field.input_name is \"id\"\n\n memo[ key ] = value unless skip is true\n\n memo\n , {}\n\n submit_success_handler: (model, response, xhr)->\n @trigger \"after:submit\", @, model, response\n @trigger \"disable:loadmask\", @ if @loadMask is true\n\n if response and response?.success is true\n @trigger \"after:submit:success\", @, model, response\n else\n @trigger \"after:submit:error\", @, model, response\n\n submit_fatal_error_handler: (model, response, xhr)->\n @trigger \"after:submit\", @, model, response\n @trigger \"after:submit:fatal_error\", @, model, response\n\n submit: (save=true, saveOptions={})->\n _.bindAll @, \"submit_success_handler\", \"submit_fatal_error_handler\"\n\n saveOptions.success ||= @submit_success_handler\n saveOptions.error ||= @submit_fatal_error_handler\n\n @syncFormWithModel()\n return unless save\n @current_model.save( @current_model.toJSON(), saveOptions )\n\n hasModel: ()->\n @current_model?\n\n currentModel: (options={})->\n if options is true or options?.refresh is true\n @syncFormWithModel()\n\n @current_model\n\n syncFormWithModel: ()->\n @current_model?.set( @getValues() )\n\n setLegend: (@legend)->\n $('fieldset legend', @el).first().html(@legend)\n\n flash: (message)->\n if @$('.toolbar-container.top').length > 0\n @$('.toolbar-container.top').after(message)\n else\n @$bodyEl().prepend(message)\n\n successFlashDelay: 1500\n\n successMessage: (message)->\n @$('.alert.alert-success').remove()\n @flash Luca.template(\"components/form_alert\", className:\"alert alert-success\", message: message)\n _.delay ()=>\n @$('.alert.alert-success').fadeOut()\n , @successFlashDelay || 0\n\n errorMessage: (message)->\n @$('.alert.alert-error').remove()\n @flash Luca.template(\"components/form_alert\", className:\"alert alert-error\", message: message)\n\n"},{"className":"Luca.components.GridView","file":"src/components/grid_view.coffee","source":"_.def('Luca.components.GridView').extend('Luca.components.Panel').with\n\n bodyTemplate: \"components/grid_view\"\n\n autoBindEventHandlers: true\n\n events:\n \"dblclick table tbody tr\" : \"double_click_handler\"\n \"click table tbody tr\": \"click_handler\"\n\n className: 'luca-ui-g-view'\n\n rowClass: \"luca-ui-g-row\"\n\n wrapperClass: \"luca-ui-g-view-wrapper\"\n\n # add whatever additional container classes you want\n # to be applied to the wrapper here\n additionalWrapperClasses: []\n\n # add additional style declarations to the wrapper if you like\n # these will be added by jquery.css and accept the same syntax\n wrapperStyles: {}\n\n scrollable: true\n\n emptyText: 'No Results To display.'\n\n # available options are striped, condensed, bordered\n # or any combination of these, split up by space\n tableStyle: 'striped'\n\n # we have to specify height to make the scrollable table portion work\n defaultHeight: 285\n\n # unless we specify the width ourselves\n # the width of the grid will automatically be set to the width of the container\n # and if it can't be determined, then it will be set to the default\n defaultWidth: 756\n\n # the grid should never outgrow its container\n maxWidth: undefined\n\n # hooks is configuration sugar\n # the before:grid:render trigger\n # will automatically fire the\n # beforeGridRender function\n hooks:[\n \"before:grid:render\"\n \"before:render:header\"\n \"before:render:row\"\n \"after:grid:render\"\n \"row:double:click\"\n \"row:click\"\n \"after:collection:load\"\n ]\n\n initialize: (@options={})->\n _.extend @, @options\n _.extend @, Luca.modules.Deferrable\n\n @loadMask = Luca.enableBootstrap unless @loadMask?\n @loadMaskEl ||= \".luca-ui-g-view-body\" if @loadMask is true\n\n Luca.components.Panel::initialize.apply(@, arguments)\n\n @configure_collection(true)\n\n @collection.bind \"before:fetch\", ()=>\n @trigger \"enable:loadmask\" if @loadMask is true\n\n @collection.bind \"reset\", (collection) =>\n @refresh()\n @trigger \"disable:loadmask\" if @loadMask is true\n @trigger \"after:collection:load\", collection\n\n # if a model changes, then we will update the row's contents\n # by rerendering that row's cells\n @collection.bind \"change\", (model)=>\n return unless @rendered is true\n\n try\n rowEl = @getRowEl( model.id || model.get('id') || model.cid )\n cells = @render_row(model, @collection.indexOf(model), cellsOnly: true )\n $( rowEl ).html( cells.join(\" \") )\n catch error\n console.log \"Error in change handler for GridView.collection\", error, @, model\n\n beforeRender: ()->\n Luca.components.Panel::beforeRender?.apply(@, arguments)\n\n @trigger \"before:grid:render\", @\n\n @table = @$ 'table.luca-ui-g-view'\n @header = @$ \"thead\"\n @body = @$ \"tbody\"\n @footer = @$ \"tfoot\"\n @wrapper = @$ \".#{ @wrapperClass }\"\n\n @applyCssClasses()\n\n @setDimensions() if @scrollable\n\n @renderHeader()\n\n @emptyMessage()\n\n $(@container).append @$el\n\n afterRender: ()->\n Luca.components.Panel::afterRender?.apply(@, arguments)\n\n @rendered = true\n @refresh()\n @trigger \"after:grid:render\", @\n\n applyCssClasses: ()->\n @$el.addClass 'scrollable-g-view' if @scrollable\n\n _( @additionalWrapperClasses ).each (containerClass)=>\n @wrapper?.addClass( containerClass )\n\n if Luca.enableBootstrap\n @table.addClass('table')\n\n _( @tableStyle?.split(\" \") ).each (style)=>\n @table.addClass(\"table-#{ style }\")\n\n setDimensions: (offset)->\n @height ||= @defaultHeight\n\n @$('.luca-ui-g-view-body').height( @height )\n @$('tbody.scrollable').height( @height - 23 )\n\n @container_width = do => $(@container).width()\n\n @width ||= if @container_width > 0 then @container_width else @defaultWidth\n\n # don't let the grid outgrow its maxWidth\n @width = _([@width, (@maxWidth || @width)]).max()\n\n @$('.luca-ui-g-view-body').width @width\n @$('.luca-ui-g-view-body table').width @width\n\n @setDefaultColumnWidths()\n\n resize: (newWidth)->\n difference = newWidth - @width\n @width = newWidth\n\n @$('.luca-ui-g-view-body').width( @width )\n @$('.luca-ui-g-view-body table').width( @width )\n\n if @columns.length > 0\n distribution = difference / @columns.length\n\n _(@columns).each (col,index)=>\n column = $(\".column-#{ index }\", @el )\n column.width( col.width = col.width + distribution )\n\n padLastColumn: ()->\n configured_column_widths = _(@columns).inject (sum, column)->\n sum = (column.width) + sum\n , 0\n\n unused_width = @width - configured_column_widths\n\n if unused_width > 0\n @lastColumn().width += unused_width\n\n setDefaultColumnWidths: ()->\n default_column_width = if @columns.length > 0 then @width / @columns.length else 200\n\n _( @columns ).each (column)->\n parseInt(column.width ||= default_column_width)\n\n @padLastColumn()\n\n lastColumn: ()->\n @columns[ @columns.length - 1 ]\n\n\n\n emptyMessage: (text=\"\")->\n text ||= @emptyText\n @body.html('')\n @body.append Luca.templates[\"components/grid_view_empty_text\"](colspan:@columns.length,text:text)\n\n refresh: ()->\n @body.html('')\n @collection.each (model,index)=>\n @render_row.apply(@, [model,index])\n\n if @collection.models.length == 0\n @emptyMessage()\n\n ifLoaded: (fn, scope)->\n scope ||= @\n fn ||= ()-> true\n\n @collection.ifLoaded(fn,scope)\n\n applyFilter: (values, options={auto:true,refresh:true})->\n @collection.applyFilter(values, options)\n\n renderHeader: ()->\n @trigger \"before:render:header\"\n\n headers = _(@columns).map (column,column_index) =>\n # temporary hack for scrollable grid dimensions.\n style = if column.width then \"width:#{ column.width }px;\" else \"\"\n\n \"<th style='#{ style }' class='column-#{ column_index }'>#{ column.header}</th>\"\n\n @header.append(\"<tr>#{ headers }</tr>\")\n\n getRowEl: (id)->\n @$ \"[data-record-id=#{ id }]\", 'table'\n\n render_row: (row,row_index, options={})->\n rowClass = @rowClass\n\n model_id = if row?.get and row?.attributes then row.get('id') else ''\n\n @trigger \"before:render:row\", row, row_index\n\n cells = _( @columns ).map (column,col_index) =>\n value = @cell_renderer(row, column, col_index)\n style = if column.width then \"width:#{ column.width }px;\" else \"\"\n\n display = if _.isUndefined(value) then \"\" else value\n\n \"<td style='#{ style }' class='column-#{ col_index }'>#{ display }</td>\"\n\n return cells if options.cellsOnly\n\n altClass = ''\n if @alternateRowClasses\n altClass = if row_index % 2 is 0 then \"even\" else \"odd\"\n\n content = \"<tr data-record-id='#{ model_id }' data-row-index='#{ row_index }' class='#{ rowClass } #{ altClass }' id='row-#{ row_index }'>#{ cells }</tr>\"\n\n return content if options.contentOnly is true\n\n @body?.append(content)\n\n cell_renderer: (row, column, columnIndex )->\n if _.isFunction column.renderer\n return column.renderer.apply @, [row,column,columnIndex]\n else if column.data.match(/\\w+\\.\\w+/)\n source = row.attributes || row\n return Luca.util.nestedValue( column.data, source )\n else\n return row.get?( column.data ) || row[ column.data ]\n\n double_click_handler: (e)->\n me = my = $( e.currentTarget )\n rowIndex = my.data('row-index')\n record = @collection.at( rowIndex )\n @trigger \"row:double:click\", @, record, rowIndex\n\n click_handler: (e)->\n me = my = $( e.currentTarget )\n rowIndex = my.data('row-index')\n record = @collection.at( rowIndex )\n @trigger \"row:click\", @, record, rowIndex\n\n $(\".#{ @rowClass }\", @body ).removeClass('selected-row')\n me.addClass('selected-row')"},{"className":"Luca.components.LoadMask","file":"src/components/load_mask.coffee","source":"_.def(\"Luca.components.LoadMask\").extends(\"Luca.View\").with\n className: \"luca-ui-load-mask\"\n bodyTemplate:\"components/load_mask\""},{"className":"Luca.components.NavBar","file":"src/components/nav_bar.coffee","source":"_.def(\"Luca.components.NavBar\").extends(\"Luca.View\").with\n fixed: true\n position: 'top'\n className: 'navbar'\n brand: \"Luca.js\"\n bodyTemplate: 'nav_bar'\n bodyClassName: 'luca-ui-navbar-body'\n\n beforeRender: ()->\n @$el.addClass \"navbar-fixed-#{ @position }\" if @fixed\n\n if @brand?\n @content().append(\"<a class='brand' href='#'>#{ @brand }</a>\")\n\n if @template\n @content().append Luca.template(@template, @)\n\n render: ()->\n @\n\n content: ()->\n @$('.container').eq(0)\n"},{"className":"Luca.components.RecordManager","file":"src/components/record_manager.coffee","source":"# The RecordManager is a high level component which incorporates\n# a filterable grid, and an editor form responsible for editing\n# the records in that grid.\n#\n# it provides convenience methods for accesing those components.\n#\n# this represents a clean pattern for having multiple components\n# which work together. inter-component communication should be handled\n# by parent containers, and not individual components, which should\n# usually not be aware of other components.\n_.def('Luca.components.RecordManager').extends('Luca.containers.CardView').with\n events:\n \"click .record-manager-grid .edit-link\" : \"edit_handler\"\n \"click .record-manager-filter .filter-button\" : \"filter_handler\"\n \"click .record-manager-filter .reset-button\" : \"reset_filter_handler\"\n \"click .add-button\" : \"add_handler\"\n \"click .refresh-button\" : \"filter_handler\"\n \"click .back-to-search-button\" : \"back_to_search_handler\"\n\n record_manager: true\n\n initialize: (@options={})->\n Luca.containers.CardView::initialize.apply @, arguments\n\n throw \"Record Managers must specify a name\" unless @name\n\n _.bindAll @, \"add_handler\", \"edit_handler\", \"filter_handler\", \"reset_filter_handler\"\n\n _.extend @components[0][0], @filterConfig if @filterConfig\n _.extend @components[0][1], @gridConfig if @gridConfig\n _.extend @components[1][0], @editorConfig if @editorConfig\n\n @bind \"after:card:switch\", () =>\n @trigger(\"activation:search\", @) if @activeCard is 0\n @trigger(\"activation:editor\", @) if @activeCard is 1\n\n components:[\n ctype: 'split_view',\n relayFirstActivation: true\n components:[\n ctype: 'form_view'\n ,\n ctype: 'grid_view'\n ]\n ,\n ctype: 'form_view'\n ]\n\n getSearch: (activate=false, reset=true)->\n @activate(0) if activate is true\n @getEditor().clear() if reset is true\n\n _.first(@components)\n\n getFilter: ()->\n _.first @getSearch().components\n\n getGrid: ()->\n _.last @getSearch().components\n\n getCollection: ()->\n @getGrid().collection\n\n getEditor: (activate=false,reset=false)->\n if activate is true\n @activate 1, (activator,previous,current)=>\n current.reset()\n\n _.last(@components)\n\n beforeRender: ()->\n @$el.addClass(\"#{ @resource }-manager\")\n Luca.containers.CardView::beforeRender?.apply @, arguments\n\n @$el.addClass(\"#{ @resource } record-manager\")\n @$el.data('resource', @resource)\n\n $(@getGrid().el).addClass(\"#{ @resource } record-manager-grid\")\n $(@getFilter().el).addClass(\"#{ @resource } record-manager-filter\")\n $(@getEditor().el).addClass(\"#{ @resource } record-manager-editor\")\n\n # This is an example of a best practice from ExtJS\n # that we incorporate in Luca, which is that container\n # components are responsible for component communication.\n #\n # child components should not be aware of other components\n # in the layout. Their parents should be responsible for\n # controlling how they interact. listening to events on one,\n # changing state, inducing effects in the others\n afterRender: ()->\n Luca.containers.CardView::afterRender?.apply @, arguments\n\n manager = @\n grid = @getGrid()\n filter = @getFilter()\n editor = @getEditor()\n collection = @getCollection()\n\n # when a row is double clicked on the grid\n # then we edit that row\n grid.bind \"row:double:click\", (grid,model,index)->\n manager.getEditor(true)\n editor.loadModel( model )\n\n editor.bind \"before:submit\", ()=>\n $('.form-view-flash-container', @el).html('')\n $('.form-view-body', @el).spin(\"large\")\n\n editor.bind \"after:submit\", ()=>\n $('.form-view-body', @el).spin(false)\n\n editor.bind \"after:submit:fatal_error\", ()=>\n $('.form-view-flash-container', @el ).append \"<li class='error'>There was an internal server error saving this record. Please contact developers@benchprep.com to report this error.</li>\"\n $('.form-view-body', @el).spin(false)\n\n editor.bind \"after:submit:error\", (form, model, response)=>\n _( response.errors ).each (error)=>\n $('.form-view-flash-container', @el ).append \"<li class='error'>#{ error }</li>\"\n\n editor.bind \"after:submit:success\", (form, model, response)=>\n $('.form-view-flash-container', @el).append \"<li class='success'>Successfully Saved Record</li>\"\n\n model.set( response.result )\n form.loadModel( model )\n\n grid.refresh()\n\n _.delay ()=>\n $('.form-view-flash-container li.success', @el).fadeOut(1000)\n $('.form-view-flash-container', @el).html('')\n , 4000\n\n filter.eachComponent (component)=>\n try\n component.bind \"on:change\", @filter_handler\n catch e\n undefined\n\n firstActivation: ()->\n @getGrid().trigger \"first:activation\", @, @getGrid()\n @getFilter().trigger \"first:activation\", @, @getGrid()\n\n reload: ()->\n manager = @\n\n grid = @getGrid()\n filter = @getFilter()\n editor = @getEditor()\n\n # refresh the select fields in the filter\n filter.clear()\n\n grid.applyFilter()\n\n manageRecord: (record_id)->\n model = @getCollection().get(record_id)\n return @loadModel(model) if model\n\n console.log \"Could Not Find Model, building and fetching\"\n\n model = @buildModel()\n model.set({id:record_id},{silent:true})\n\n model.fetch\n success: (model,response)=>\n @loadModel(model)\n\n loadModel: (@current_model)->\n @getEditor(true).loadModel( @current_model )\n @trigger \"model:loaded\", @current_model\n\n currentModel: ()->\n @getEditor(false).currentModel()\n\n buildModel: ()->\n editor = @getEditor(false)\n collection = @getCollection()\n\n collection.add([{}], silent:true, at: 0)\n\n model = collection.at(0)\n\n createModel: ()->\n @loadModel(@buildModel())\n\n ##### DOM Event Handlers\n reset_filter_handler: (e)->\n @getFilter().clear()\n @getGrid().applyFilter( @getFilter().getValues() )\n\n filter_handler: (e)->\n @getGrid().applyFilter( @getFilter().getValues() )\n\n edit_handler: (e)->\n me = my = $( e.currentTarget )\n record_id = my.parents('tr').data('record-id')\n\n if record_id\n model = @getGrid().collection.get( record_id )\n\n model ||= @getGrid().collection.at( row_index )\n\n\n add_handler: (e)->\n me = my = $( e.currentTarget )\n resource = my.parents('.record-manager').eq(0).data('resource')\n\n destroy_handler: (e)->\n #destroy handler\n\n back_to_search_handler: ()->\n # search handler"},{"className":"Luca.Router","file":"src/components/router.coffee","source":"_.def(\"Luca.Router\").extends(\"Backbone.Router\").with\n routes:\n \"\" : \"default\"\n\n initialize: (@options)->\n _.extend @, @options\n\n @routeHandlers = _( @routes ).values()\n\n # when a route handler is fired, the route:route_name event is triggered by the router\n # unfortunately this doesn't apply to calls to @navigate() so we override Backbone.Router.navigate\n # and trigger an event separately.\n _( @routeHandlers ).each (route_id) =>\n @bind \"route:#{ route_id }\", ()=>\n @trigger.apply @, [\"change:navigation\", route_id ].concat( _( arguments ).flatten() )\n\n #### Router Functions\n\n # Intercept calls to Backbone.Router.navigate so that we can at least\n # build a path from the route, even if we don't trigger the route handler\n navigate: (route, triggerRoute=false)->\n Backbone.Router.prototype.navigate.apply @, arguments\n @buildPathFrom( Backbone.history.getFragment() )\n\n # given a url fragment, construct an argument chain similar to what would be\n # emitted from a normal route:#{ name } event that gets triggered\n # when a route is actually fired. This is used to trap route changes that happen\n # through calls to @navigate()\n buildPathFrom: (matchedRoute)->\n _(@routes).each (route_id, route)=>\n regex = @_routeToRegExp(route)\n if regex.test(matchedRoute)\n args = @_extractParameters(regex, matchedRoute)\n @trigger.apply @, [\"change:navigation\", route_id].concat( args )\n"},{"className":"Luca.components.Template","file":"src/components/template.coffee","source":"_.def('Luca.components.Template').extends('Luca.View').with\n initialize: (@options={})->\n console.log \"The Use of Luca.components.Template directly is being DEPRECATED\"\n\n Luca.View::initialize.apply @, arguments\n"},{"className":"Luca.components.ToolbarDialog","file":"src/components/toolbar_dialog.coffee","source":"_.def(\"Luca.components.ToolbarDialog\").extends(\"Luca.View\").with\n className:\"luca-ui-toolbar-dialog span well\"\n\n styles:\n \"position\" : \"absolute\"\n \"z-Index\" : \"3000\"\n \"float\" : \"left\"\n\n initialize: (@options={})->\n @_super(\"initialize\", @, arguments)\n\n createWrapper: ()->\n @make \"div\",\n class: \"component-picker span4 well\"\n style:\n \"position: absolute; z-index:12000\"\n\n show: ()->\n @$el.parent().show()\n\n hide: ()->\n @$el.parent().hide()\n\n toggle: ()->\n @$el.parent().toggle()\n"},{"className":"Luca.containers.CardView","file":"src/containers/card_view.coffee","source":"_.def(\"Luca.containers.CardView\").extends(\"Luca.core.Container\").with\n componentType: 'card_view'\n\n className: 'luca-ui-card-view-wrapper'\n\n activeCard: 0\n\n components: []\n\n hooks:[\n 'before:card:switch',\n 'after:card:switch'\n ]\n\n componentClass: 'luca-ui-card'\n appendContainers: true\n\n initialize: (@options)->\n Luca.core.Container::initialize.apply @,arguments\n @setupHooks(@hooks)\n\n prepareComponents: ()->\n Luca.core.Container::prepareComponents?.apply(@, arguments)\n\n _( @components ).each (component,index)=>\n if index is @activeCard\n $( component.container ).show()\n else\n $( component.container ).hide()\n\n activeComponentElement: ()->\n @componentElements().eq( @activeCard )\n\n activeComponent: ()->\n @getComponent( @activeCard )\n\n customizeContainerEl: (containerEl, panel, panelIndex)->\n containerEl.style += if panelIndex is @activeCard then \"display:block;\" else \"display:none;\"\n\n containerEl\n\n cycle: ()->\n nextIndex = if @activeCard < @components.length - 1 then @activeCard + 1 else 0\n @activate( nextIndex )\n\n find: (name)->\n @findComponentByName(name,true)\n\n firstActivation: ()->\n @activeComponent().trigger \"first:activation\", @, @activeComponent()\n\n activate: (index, silent=false, callback)->\n if _.isFunction(silent)\n silent = false\n callback = silent\n\n return if index is @activeCard\n\n previous = @activeComponent()\n current = @getComponent(index)\n\n if !current\n index = @indexOf(index)\n current = @getComponent( index )\n\n unless current\n return\n\n unless silent\n @trigger \"before:card:switch\", previous, current\n previous?.trigger?.apply(previous,[\"before:deactivation\", @, previous, current])\n current?.trigger?.apply(previous,[\"before:activation\", @, previous, current])\n\n _.defer ()=>\n @$el.data( @activeAttribute || \"active-card\", current.name)\n\n @componentElements().hide()\n\n unless current.previously_activated\n current.trigger \"first:activation\"\n current.previously_activated = true\n\n @activeCard = index\n @activeComponentElement().show()\n\n unless silent\n @trigger \"after:card:switch\", previous, current\n previous.trigger?.apply(previous, [\"deactivation\", @, previous, current])\n current.trigger?.apply(current, [\"activation\", @, previous, current])\n\n\n if _.isFunction(callback)\n callback.apply @, [@,previous,current]"},{"className":"Luca.containers.ColumnView","file":"src/containers/column_view.coffee","source":"_.def('Luca.containers.ColumnView').extends('Luca.core.Container').with\n componentType: 'column_view'\n\n className: 'luca-ui-column-view'\n\n components: []\n\n initialize: (@options={})->\n Luca.core.Container::initialize.apply @, arguments\n @setColumnWidths()\n\n componentClass: 'luca-ui-column'\n\n containerTemplate: \"containers/basic\"\n\n appendContainers: true\n\n autoColumnWidths: ()->\n widths = []\n\n _( @components.length ).times ()=>\n widths.push( parseInt( 100 / @components.length ) )\n\n widths\n\n setColumnWidths: ()->\n @columnWidths = if @layout?\n _( @layout.split('/') ).map((v)-> parseInt(v) )\n else\n @autoColumnWidths()\n\n @columnWidths = _( @columnWidths ).map (val)-> \"#{ val }%\"\n\n beforeLayout: ()->\n @debug \"column_view before layout\"\n\n _(@columnWidths).each (width,index) =>\n @components[index].float = \"left\"\n @components[index].width = width\n\n Luca.core.Container::beforeLayout?.apply @, arguments"},{"className":"Luca.ModalView","file":"src/containers/modal_view.coffee","source":"_.def(\"Luca.ModalView\").extends(\"Luca.View\").with\n\n closeOnEscape: true\n\n showOnInitialize: false\n\n backdrop: false\n\n container: ()->\n $('body')\n\n toggle: ()->\n @$el.modal('toggle')\n\n show: ()->\n @$el.modal('show')\n\n hide: ()->\n @$el.modal('hide')\n\n render: ()->\n @$el.addClass 'modal'\n @$el.addClass 'fade' if @fade is true\n\n $('body').append( @$el )\n\n @$el.modal\n backdrop: @backdrop is true\n keyboard: @closeOnEscape is true\n show: @showOnInitialize is true\n\n_.def(\"Luca.containers.ModalView\").extends(\"Luca.ModalView\").with()"},{"className":"Luca.containers.ModalView","file":"src/containers/modal_view.coffee","source":"_.def(\"Luca.ModalView\").extends(\"Luca.View\").with\n\n closeOnEscape: true\n\n showOnInitialize: false\n\n backdrop: false\n\n container: ()->\n $('body')\n\n toggle: ()->\n @$el.modal('toggle')\n\n show: ()->\n @$el.modal('show')\n\n hide: ()->\n @$el.modal('hide')\n\n render: ()->\n @$el.addClass 'modal'\n @$el.addClass 'fade' if @fade is true\n\n $('body').append( @$el )\n\n @$el.modal\n backdrop: @backdrop is true\n keyboard: @closeOnEscape is true\n show: @showOnInitialize is true\n\n_.def(\"Luca.containers.ModalView\").extends(\"Luca.ModalView\").with()"},{"className":"Luca.containers.PanelToolbar","file":"src/containers/panel_toolbar.coffee","source":"\n# button config accepts the following paramters:\n#\n# label what should the button say\n# eventId what event should the button trigger\n# dropdown an array of arrays: [eventId, label]\n# group an array of button configs\n# wrapper a css class, in addition to btn-group\n# icon which icon do you want to use on this button?\n# white true or false: is it a white colored text?\n# color options are primary, info, success, warning, danger, inverse\n\nmake = Backbone.View::make\n\nbuildButton = (config, wrap=true)->\n if config.ctype?\n config.className ||= \"\"\n config.className += 'toolbar-component'\n\n object = Luca(config).render()\n if Luca.isBackboneView(object)\n console.log \"Adding toolbar component\", object\n return object.el\n\n if config.spacer\n return make \"div\", class: \"spacer #{ config.spacer }\"\n\n if config.text\n return make \"div\", {class: \"toolbar-text\"}, config.text\n\n wrapper = 'btn-group'\n wrapper += \" #{ config.wrapper }\" if config.wrapper?\n wrapper += \" align-#{ config.align }\" if config.align?\n\n # if we're passed a group, then we need to just\n # wrap the contents of the buttons property in that group\n # skipping the btn-group wrapping that takes place for\n # individual buttons\n if config.group? and config.buttons?\n buttons = prepareButtons( config.buttons, false )\n return make \"div\", class: wrapper, buttons\n\n # if it is a normal button, and not a button group\n else\n label = config.label ||= \"\"\n\n config.eventId ||= _.string.dasherize( config.label.toLowerCase() )\n\n if config.icon\n label = \" \" if _.string.isBlank( label )\n white = \"icon-white\" if config.white\n label = \"<i class='#{ white || \"\" } icon-#{ config.icon }' /> #{ label }\"\n\n buttonAttributes =\n class: _.compact([\"btn\",config.classes,config.className]).join(\" \")\n \"data-eventId\" : config.eventId\n title: config.title || config.description\n\n buttonAttributes[\"class\"] += \" btn-#{ config.color }\" if config.color?\n\n if config.dropdown\n label = \"#{ label } <span class='caret'></span>\"\n buttonAttributes[\"class\"] += \" dropdown-toggle\"\n buttonAttributes[\"data-toggle\"] = \"dropdown\"\n\n dropdownItems = _(config.dropdown).map (dropdownItem)=>\n link = make \"a\", {}, dropdownItem[1]\n make \"li\", {\"data-eventId\": dropdownItem[0]}, link\n\n dropdownEl = make \"ul\", {class:\"dropdown-menu\"}, dropdownItems\n\n buttonEl = make \"a\", buttonAttributes, label\n\n # needs to be wrapped for proper rendering, but not\n # if it already is part of a group\n autoWrapClass = \"btn-group\"\n autoWrapClass += \" align-#{ config.align }\" if config.align?\n\n if wrap is true\n return make \"div\", {class: autoWrapClass}, [buttonEl,dropdownEl]\n else\n # for buttons which are already part f a group\n buttonEl\n\nprepareButtons = (buttons, wrap=true)->\n _( buttons ).map (button)->\n buildButton(button, wrap)\n\n\n#### Panel Toolbar Component\n#\n# The Panel Toolbar is a collection of buttons and / or dropdowns\n# which are automatically created by BasicPanel classes, or can be\n# added to any other view component.\n_.def(\"Luca.containers.PanelToolbar\").extends(\"Luca.View\").with\n\n className: \"luca-ui-toolbar btn-toolbar\"\n\n # @buttons is an array of button config objects\n\n\n buttons:[]\n\n well: true\n\n orientation: 'top'\n\n autoBindEventHandlers: true\n\n events:\n \"click a.btn, click .dropdown-menu li\" : \"clickHandler\"\n\n #autoBindEventHandlers: true\n\n # The Toolbar behaves by triggering events on the components which they\n # belong to. Combined with Luca.View::setupHooks it is a clean way\n # to organize actions\n clickHandler: (e)->\n me = my = $( e.target )\n\n if me.is('i')\n me = my = $( e.target ).parent()\n\n eventId = my.data('eventid')\n\n return unless eventId?\n\n hook = Luca.util.hook( eventId )\n\n source = @parent || @\n if _.isFunction( source[hook] )\n source[ hook ].call(@, me, e)\n else\n source.trigger(eventId, me, e)\n\n beforeRender:()->\n @_super(\"beforeRender\", @, arguments)\n\n if @well is true\n @$el.addClass 'well'\n\n @$el.addClass \"toolbar-#{ @orientation }\"\n\n @applyStyles( @styles ) if @styles?\n\n render: ()->\n @$el.empty()\n\n elements = prepareButtons(@buttons)\n _( elements ).each (element)=>\n @$el.append( element )\n"},{"className":"Luca.containers.PanelView","file":"src/containers/panel_view.coffee","source":"_.def('Luca.containers.PanelView').extends('Luca.core.Container').with\n className: 'luca-ui-panel'\n\n initialize: (@options={})->\n Luca.core.Container::initialize.apply @, arguments\n\n afterLayout: ()->\n if @template\n contents = ( Luca.templates || JST )[ @template ]( @ )\n @$el.html(contents)\n\n render: ()->\n $(@container).append @$el\n\n afterRender: ()->\n Luca.core.Container::afterRender?.apply @, arguments\n if @css\n _( @css ).each (value,property)=>\n @$el.css(property,value)\n\n\n\n\n"},{"className":"Luca.containers.SplitView","file":"src/containers/split_view.coffee","source":"_.def('Luca.containers.SplitView').extends('Luca.core.Container').with\n componentType: 'split_view'\n\n containerTemplate: 'containers/basic'\n\n className: 'luca-ui-split-view'\n\n componentClass: 'luca-ui-panel'"},{"className":"Luca.containers.TabView","file":"src/containers/tab_view.coffee","source":"_.def('Luca.containers.TabView').extends('Luca.containers.CardView').with\n\n hooks:[\n \"before:select\"\n \"after:select\"\n ]\n\n componentType: 'tab_view'\n\n className: 'luca-ui-tab-view tabbable'\n\n tab_position: 'top'\n\n tabVerticalOffset: '50px'\n\n navClass: \"nav-tabs\"\n\n bodyTemplate: \"containers/tab_view\"\n bodyEl: \"div.tab-content\"\n\n initialize: (@options={})->\n @navClass = \"nav-list\"if @navStyle is \"list\"\n\n Luca.containers.CardView::initialize.apply @, arguments\n\n _.bindAll @, \"select\", \"highlightSelectedTab\"\n\n @setupHooks( @hooks )\n\n @bind \"after:card:switch\", @highlightSelectedTab\n\n activeTabSelector: ()->\n @tabSelectors().eq( @activeCard || @activeTab || @activeItem )\n\n beforeLayout: ()->\n @$el.addClass(\"tabs-#{ @tab_position }\")\n @activeTabSelector().addClass 'active'\n\n @createTabSelectors()\n\n Luca.containers.CardView::beforeLayout?.apply @, arguments\n\n afterRender: ()->\n Luca.containers.CardView::afterRender?.apply @, arguments\n @registerEvent(\"click ##{ @cid }-tabs-selector li a\", \"select\")\n\n if Luca.enableBootstrap and (@tab_position is \"left\" or @tab_position is \"right\")\n @tabContainerWrapper().addClass(\"span2\")\n @tabContentWrapper().addClass(\"span9\")\n\n\n createTabSelectors: ()->\n tabView = @\n @each (component,index)->\n icon = \"<i class='icon-#{ component.tabIcon }\" if component.tabIcon\n link = \"<a href='#'>#{ icon || ''} #{ component.title }</a>\"\n selector = tabView.make(\"li\",{class:\"tab-selector\",\"data-target\":index}, link)\n tabView.tabContainer().append(selector)\n\n if component.navHeading? and not tabView.navHeadings?[ component.navHeading ]\n $( selector ).before( tabView.make('li',{class:\"nav-header\"}, component.navHeading))\n tabView.navHeadings ||= {}\n tabView.navHeadings[ component.navHeading ] = true\n\n highlightSelectedTab: ()->\n @tabSelectors().removeClass('active')\n @activeTabSelector().addClass('active')\n\n select: (e)->\n e.preventDefault()\n\n me = my = $( e.target )\n\n @trigger \"before:select\", @\n @activate my.parent().data('target')\n @trigger \"after:select\", @\n\n componentElements: ()->\n @$(\">.tab-content >.#{ @componentClass }\")\n\n tabContentWrapper: ()->\n $(\"##{ @cid }-tab-view-content\")\n\n tabContainerWrapper: ()->\n $(\"##{ @cid }-tabs-selector\")\n\n tabContainer: ()->\n @$(\"ul.#{ @navClass }\", @tabContainerWrapper() )\n\n tabSelectors: ()->\n @$( 'li.tab-selector', @tabContainer() )"},{"className":"Luca.containers.Viewport","file":"src/containers/viewport.coffee","source":"_.def('Luca.containers.Viewport').extend('Luca.containers.CardView').with\n\n activeItem: 0\n\n additionalClassNames: 'luca-ui-viewport'\n\n fullscreen: true\n\n fluid: false\n\n wrapperClass: 'row'\n\n initialize: (@options={})->\n _.extend @, @options\n\n if Luca.enableBootstrap is true\n @wrapperClass = \"row-fluid fluid-viewport-wrapper\" if @fluid is true\n\n Luca.core.Container::initialize.apply(@, arguments)\n\n $('html,body').addClass('luca-ui-fullscreen') if @fullscreen\n\n beforeRender: ()->\n Luca.containers.CardView::beforeRender?.apply(@, arguments)\n\n #if Luca.enableBootstrap and @topNav and @fullscreen\n # $('body').css('padding','40px')\n\n @renderTopNavigation() if @topNav?\n @renderBottomNavigation() if @bottomNav?\n\n afterRender: ()->\n Luca.containers.CardView::after?.apply(@, arguments)\n\n if Luca.enableBootstrap is true and @containerClassName\n @$el.children().wrap('<div class=\"#{ containerClassName }\" />')\n\n renderTopNavigation: ()->\n return unless @topNav?\n\n if _.isString( @topNav )\n @topNav = Luca.util.lazyComponent(@topNav)\n\n if _.isObject( @topNav )\n @topNav.ctype ||= @topNav.type || \"nav_bar\"\n unless Luca.isBackboneView(@topNav)\n @topNav = Luca.util.lazyComponent( @topNav )\n\n @topNav.app = @\n\n $('body').prepend( @topNav.render().el )\n\n renderBottomNavigation: ()->\n # IMPLEMENT\n\n"},{"className":"Luca.Collection","file":"src/core/collection.coffee","source":"source = 'Backbone.Collection'\nsource = 'Backbone.QueryCollection' if Backbone.QueryCollection?\n\n_.def(\"Luca.Collection\").extends( source ).with\n # cachedMethods refers to a list of methods on the collection\n # whose value gets cached once it is ran. the collection then\n # binds to change, add, remove, and reset events and then expires\n # the cached value once these events are fired.\n\n # cachedMethods expects an array of strings representing the method name\n # or objects containing @method and @resetEvents properties. by default\n # @resetEvents are 'add','remove',reset' and 'change'.\n cachedMethods: []\n\n # if filtering a collection should handle via a call to a REST API\n # and return the filtered results that way, then leave this true\n remoteFilter: false\n\n initialize: (models=[], @options)->\n _.extend @, @options\n @setupMethodCaching()\n @_reset()\n\n # By specifying a @cache_key property or method, you can instruct\n # Luca.Collection instances where to pull an array of model attributes\n # usually done with the bootstrap functionality provided.\n\n # DEPRECATION NOTICE\n if @cached\n console.log 'The @cached property of Luca.Collection is being deprecated. Please change to cache_key'\n\n if @cache_key ||= @cached\n @bootstrap_cache_key = if _.isFunction( @cache_key ) then @cache_key() else @cache_key\n\n if @registerAs or @registerWith\n console.log \"This configuration API is deprecated. use @name and @manager properties instead\"\n\n # support the older configuration API\n @name ||= @registerAs\n @manager ||= @registerWith\n\n @manager = if _.isFunction(@manager) then @manager() else @manager\n\n # if they specify a\n if @name and not @manager\n @manager = Luca.CollectionManager.get()\n\n # If we are going to be registering this collection with the CollectionManager\n # class, then we need to specify a key to register ourselves under. @registerAs can be\n # as simple as something as \"books\", or if you are using collections which need\n # to be scoped with some sort of unique id, as say some sort of belongsTo relationship\n # then you can specify @registerAs as a method()\n if @manager\n @name ||= @cache_key()\n @name = if _.isFunction( @name ) then @name() else @name\n\n unless @private or @anonymous\n @bind \"after:initialize\", ()=>\n @register( @manager, @name, @)\n\n # by passing useLocalStorage = true to your collection definition\n # you will bypass the RESTful persistence layer and just persist everything\n # locally in localStorage\n if @useLocalStorage is true and window.localStorage?\n table = @bootstrap_cache_key || @name\n throw \"Must specify either a cached or registerAs property to use localStorage\"\n @localStorage = new Luca.LocalStore( table )\n\n # Populating a collection with local data\n #\n # by specifying a @data property which is an array\n # then you can set the collection to be a @memoryCollection\n # which never interacts with a persistence layer at all.\n #\n # this is mainly used by the Luca.fields.SelectField class for\n # generating simple select fields with static data\n if _.isArray(@data) and @data.length > 0\n @memoryCollection = true\n\n @__wrapUrl() unless @useNormalUrl is true\n\n Backbone.Collection::initialize.apply @, [models, @options]\n\n if models\n @reset models, silent: true, parse: options?.parse\n\n @trigger \"after:initialize\"\n\n # Luca.Collections will append a query string to the URL\n # and will automatically do this for you without you having\n # to write a special url handler. If you want to use a normal\n # url without this feature, just set @useNormalUrl = true\n __wrapUrl: ()->\n if _.isFunction(@url)\n @url = _.wrap @url, (fn)=>\n val = fn.apply @\n parts = val.split('?')\n\n existing_params = _.last(parts) if parts.length > 1\n\n queryString = @queryString()\n\n if existing_params and val.match(existing_params)\n queryString = queryString.replace( existing_params, '')\n\n new_val = \"#{ val }?#{ queryString }\"\n new_val = new_val.replace(/\\?$/,'') if new_val.match(/\\?$/)\n\n new_val\n else\n url = @url\n params = @queryString()\n\n @url = _([url,params]).compact().join(\"?\")\n\n queryString: ()->\n parts = _( @base_params ||= Luca.Collection.baseParams() ).inject (memo, value, key)=>\n str = \"#{ key }=#{ value }\"\n memo.push(str)\n memo\n , []\n\n _.uniq(parts).join(\"&\")\n\n resetFilter: ()->\n @base_params = _( Luca.Collection.baseParams() ).clone()\n @\n\n applyFilter: (filter={}, options={})->\n if options.remote? is true or @remoteFilter is true\n @applyParams(filter)\n @fetch _.extend(options,refresh:true)\n else\n @reset @query filter\n\n # You can apply params to a collection, so that any upcoming requests\n # made to the REST API are made with the key values specified\n applyParams: (params)->\n @base_params = _( Luca.Collection.baseParams() ).clone()\n _.extend @base_params, params\n\n @\n\n # If this collection is to be registered with some global collection\n # tracker such as new Luca.CollectionManager() then we will register\n # ourselves automatically\n #\n # To automatically register a collection with the registry, instantiate\n # it with the registerWith property, which can either be a reference to\n # the manager itself, or a string in case the manager isn't available\n # at compile time\n register: (collectionManager=Luca.CollectionManager.get(), key=\"\", collection)->\n throw \"Can not register with a collection manager without a key\" unless key.length >= 1\n throw \"Can not register with a collection manager without a valid collection manager\" unless collectionManager?\n\n # by passing a string instead of a reference to an object, we can look up\n # that object only when necessary. this prevents us from having to create\n # the manager instance before we can define our collections\n if _.isString( collectionManager )\n collectionManager = Luca.util.nestedValue( collectionManager, (window || global) )\n\n throw \"Could not register with collection manager\" unless collectionManager\n\n if _.isFunction( collectionManager.add )\n return collectionManager.add(key, collection)\n\n if _.isObject( collectionManager )\n collectionManager[ key ] = collection\n\n # A Luca.Collection will load models from the in memory model store\n # returned from Luca.Collection.cache, where the key returned from\n # the @cache_keyattribute or method matches the key of the model cache\n loadFromBootstrap: ()->\n return unless @bootstrap_cache_key\n @reset @cached_models()\n @trigger \"bootstrapped\", @\n\n # an alias for loadFromBootstrap which is a bit more descriptive\n bootstrap: ()->\n @loadFromBootstrap()\n\n # cached_models is a reference to the Luca.Collection.cache object\n # key'd on whatever this collection's bootstrap_cache_key is set to be\n # via the @cache_key() interface\n cached_models: ()->\n Luca.Collection.cache( @bootstrap_cache_key )\n\n # Luca.Collection overrides the default Backbone.Collection.fetch method\n # and triggers an event \"before:fetch\" which gives you additional control\n # over the process\n #\n # in addition, it loads models directly from the bootstrap cache instead\n # of going directly to the API\n fetch: (options={})->\n @trigger \"before:fetch\", @\n\n return @reset(@data) if @memoryCollection is true\n\n # fetch will try to pull from the bootstrap if it is setup to do so\n # you can actually make the roundtrip to the server anyway if you pass\n # refresh = true in the options hash\n return @bootstrap() if @cached_models().length and not options.refresh\n\n url = if _.isFunction(@url) then @url() else @url\n\n return true unless ((url and url.length > 1) or @localStorage)\n\n @fetching = true\n\n try\n Backbone.Collection.prototype.fetch.apply @, arguments\n catch e\n console.log \"Error in Collection.fetch\", e\n\n throw e\n\n # onceLoaded is equivalent to binding to the\n # reset trigger with a function wrapped in _.once\n # so that it only gets run...ahem...once.\n #\n # that being said, if the collection already has models\n # it won't even bother fetching it it will just run\n # as if reset was already triggered\n onceLoaded: (fn, options={autoFetch:true})->\n if @length > 0 and not @fetching\n fn.apply @, [@]\n return\n\n wrapped = ()=> fn.apply @,[@]\n\n @bind \"reset\", ()->\n wrapped()\n @unbind \"reset\", @\n\n unless @fetching or not options.autoFetch\n @fetch()\n\n # ifLoaded is equivalent to binding to the reset trigger with\n # a function, if the collection already has models it will just\n # run automatically. similar to onceLoaded except the binding\n # stays in place\n ifLoaded: (fn, options={scope:@,autoFetch:true})->\n scope = options.scope || @\n\n if @length > 0 and not @fetching\n fn.apply scope, [@]\n\n @bind \"reset\", (collection)=> fn.call(scope,collection)\n\n unless @fetching is true or !options.autoFetch or @length > 0\n @fetch()\n\n # parse is very close to the stock Backbone.Collection parse, which\n # just returns the response. However, it also triggers a callback\n # after:response, and automatically parses responses which contain\n # a JSON root like you would see in rails, if you specify the @root\n # property.\n #\n # it will also update the Luca.Collection.cache with the models from\n # the response, so that any subsequent calls to fetch() on a bootstrapped\n # collection, will have updated models from the server. Really only\n # useful if you call fetch(refresh:true) manually on any bootstrapped\n # collection\n parse: (response)->\n @fetching = false\n @trigger \"after:response\", response\n models = if @root? then response[ @root ] else response\n\n if @bootstrap_cache_key\n Luca.Collection.cache( @bootstrap_cache_key, models)\n\n models\n\n # Method Caching\n #\n # Method Caching is a way of saving the output of a method on your collection.\n # And then expiring that value if any changes are detected to the models in\n # the collection\n restoreMethodCache: ()->\n for name, config of @_methodCache\n if config.original?\n config.args = undefined\n @[ name ] = config.original\n\n clearMethodCache: (method)->\n @_methodCache[method].value = undefined\n\n clearAllMethodsCache: ()->\n for name, config of @_methodCache\n @clearMethodCache(name)\n\n setupMethodCaching: ()->\n collection = @\n membershipEvents = [\"reset\",\"add\",\"remove\"]\n cache = @_methodCache = {}\n\n _( @cachedMethods ).each (method)->\n # store a reference to the unwrapped version of the method\n # and a placeholder for the cached value\n cache[ method ] =\n name: method\n original: collection[method]\n value: undefined\n\n # wrap the collection method with a basic memoize operation\n collection[ method ] = ()->\n cache[method].value ||= cache[method].original.apply collection, arguments\n\n # bind to events on the collection, which once triggered, will\n # invalidate the cached value. causing us to have to restore it\n for membershipEvent in membershipEvents\n collection.bind membershipEvent, ()->\n collection.clearAllMethodsCache()\n\n dependencies = method.split(':')[1]\n\n if dependencies\n for dependency in dependencies.split(\",\")\n collection.bind \"change:#{dependency}\", ()->\n collection.clearMethodCache(method: method)\n\n # make sure the querying interface from backbone.query is present\n # in the case backbone-query isn't loaded. without it, it will\n # just return the models\n query: (filter={},options={})->\n if Backbone.QueryCollection?\n return Backbone.QueryCollection::query.apply(@, arguments)\n else\n @models\n\n# Global Collection Observer\n_.extend Luca.Collection.prototype,\n trigger: ()->\n if Luca.enableGlobalObserver\n Luca.CollectionObserver ||= new Luca.Observer(type:\"collection\")\n Luca.CollectionObserver.relay(@, arguments)\n\n Backbone.View.prototype.trigger.apply @, arguments\n\n# Always include these parameters in every request to your REST API.\n#\n# either specify a function which returns a hash, or just a normal hash\nLuca.Collection.baseParams = (obj)->\n return Luca.Collection._baseParams = obj if obj\n\n if _.isFunction( Luca.Collection._baseParams )\n return Luca.Collection._baseParams()\n\n if _.isObject( Luca.Collection._baseParams )\n Luca.Collection._baseParams\n\n# In order to make our Backbone Apps super fast it is a good practice\n# to pre-populate your collections by what is referred to as bootstrapping\n#\n# Luca.Collections make it easier for you to do this cleanly and automatically\n#\n# by specifying a @cache_keyproperty or method in your collection definition\n# Luca.Collections will automatically look in this space to find models\n# and avoid a roundtrip to your API unless explicitly told to.\nLuca.Collection._bootstrapped_models = {}\n\n# In order to do this, just load an object whose keys\nLuca.Collection.bootstrap = (obj)->\n _.extend Luca.Collection._bootstrapped_models, obj\n\n# Lookup cached() or bootstrappable models. This is used by the\n# augmented version of Backbone.Collection.fetch() in order to avoid\n# roundtrips to the API\nLuca.Collection.cache = (key, models)->\n return Luca.Collection._bootstrapped_models[ key ] = models if models\n Luca.Collection._bootstrapped_models[ key ] || []\n"},{"className":"Luca.core.Container","file":"src/core/container.coffee","source":"# The Component Container\n#\n# The Component Container is a nestable component\n# which are responsible for handling communication between multiple\n# nested views.\n#\n# One: Layout\n#\n# a container is responsible for laying out the nested views\n# and rendering them in a special DOM element\ndoLayout = ()->\n @trigger \"before:layout\", @\n @prepareLayout()\n @trigger \"after:layout\", @\n\n# and displaying those elements in a way that is\n# optimal for the desired user experience of that view\n# ( i.e seeing only one of them at a time, seeing them side by side )\napplyDOMConfig = (panel, panelIndex)->\n style_declarations = []\n\n style_declarations.push \"height: #{ (if _.isNumber(panel.height) then panel.height + 'px' else panel.height ) }\" if panel.height?\n style_declarations.push \"width: #{ (if _.isNumber(panel.width) then panel.width + 'px' else panel.width ) }\" if panel.width?\n style_declarations.push \"float: #{ panel.float }\" if panel.float\n\n config =\n class: panel?.classes || @componentClass\n id: \"#{ @cid }-#{ panelIndex }\"\n style: style_declarations.join(';')\n \"data-luca-owner\" : @name || @cid\n\n if @customizeContainerEl?\n config = @customizeContainerEl( config, panel, panelIndex )\n\n config\n\n# Two: Component Creation\n#\n# A container is responsible for creating and storing references to the nested\n# views that are required for its functioning.\ndoComponents = ()->\n\n @trigger \"before:components\", @, @components\n @prepareComponents()\n @createComponents()\n @trigger \"before:render:components\", @, @components\n @renderComponents()\n @trigger \"after:components\", @, @components\n\n\n# Containers are central to Luca. They are what make it easy to structure\n# your application in a logical way and to specify much of the behavior of\n# complex / composite views at define time using JSON syntax combined with\n# the meta data contained in the Luca component registry.\n_.def('Luca.core.Container').extends('Luca.components.Panel').with\n\n className: 'luca-ui-container'\n\n componentTag: 'div'\n componentClass: 'luca-ui-panel'\n\n isContainer: true\n\n hooks:[\n \"before:components\"\n \"before:render:components\"\n \"before:layout\"\n \"after:components\"\n \"after:layout\"\n \"first:activation\"\n ]\n\n rendered: false\n\n components: []\n\n initialize: (@options={})->\n _.extend @, @options\n\n @setupHooks [\n \"before:components\"\n \"before:render:components\"\n \"before:layout\"\n \"after:components\"\n \"after:layout\"\n \"first:activation\"\n ]\n\n Luca.View::initialize.apply @, arguments\n\n # Rendering Pipeline\n #\n # A container has nested components. these components\n # are automatically rendered inside their own DOM element\n # and then CSS configuration is generally applied to these\n # DOM elements. Each component is assigned to this DOM\n # element by specifying a @container property on the component.\n #\n # Each component is instantiated by looking up its @ctype propery\n # in the Luca Component Registry. Then the components are rendered\n # by having their @render() method called on them.\n #\n # Any class which extends Luca.View will have its defined render method\n # wrapped in a method which triggers \"before:render\", and \"after:render\"\n # before and after the defined render method.\n #\n # so you can expect the following, for any container or nested container\n #\n # DOM Element Manipulation:\n #\n # beforeRender()\n # beforeLayout()\n # prepareLayout()\n # afterLayout()\n #\n # Luca / Backbone Component Manipulation\n #\n # beforeComponents()\n # prepareComponents()\n # createComponents()\n # beforeRenderComponents()\n # renderComponents() ->\n # calls render() on each component, starting this whole cycle\n #\n # afterComponents()\n #\n # DOM Injection\n #\n # render()\n # afterRender()\n #\n # For Components which are originally hidden\n # ( card view, tab view, etc )\n #\n # firstActivation()\n #\n beforeRender: ()->\n doLayout.call(@)\n doComponents.call(@)\n Luca.components.Panel::beforeRender?.apply(@, arguments)\n\n # Components which inherit from Luca.core.Container can implement\n # their own versions of this method, if they need to apply any sort\n # of additional styling / configuration for the DOM elements that\n # are created to wrap each container.\n customizeContainerEl: (containerEl, panel, panelIndex)->\n containerEl\n\n prepareLayout: ()->\n container = @\n @componentContainers = _( @components ).map (component, index)->\n applyDOMConfig.call(container, component, index)\n\n # prepare components is where each component gets assigned\n # a container to be rendered into. if @appendContainers is\n # set to true, then the view will automatically $append()\n # elements created via Backbone.View::make() to the body element of the view\n prepareComponents: ()->\n # accept components as an array of strings representing\n # the luca component type\n for component in @components when _.isString(component)\n component = (type: component)\n\n _( @components ).each (component, index)=>\n container = @componentContainers?[index]\n\n # support a variety of the bad naming conventions\n container.class = container.class || container.className || container.classes\n\n if @appendContainers\n panel = @make(@componentTag, container, '')\n @$append( panel )\n\n unless component.container?\n component.container = \"##{ container.id }\" if @appendContainers\n component.container ||= @$bodyEl()\n\n # create components is responsible for turning the JSON syntax of the\n # container's definition into live objects against a given Luca Component\n # type.\n #\n # In addition to this, a container builds an index of the components\n # which belong to it, so that they can easily be looked up by name\n createComponents: ()->\n return if @componentsCreated is true\n\n map = @componentIndex =\n name_index: {}\n cid_index: {}\n\n @components = _( @components ).map (object, index)=>\n\n # you can include normal backbone views as components\n # you will want to make sure your render method handles\n # adding the views @$el to the appropriate @container.\n\n # you can also just pass a string representing the component_type\n component = if Luca.isBackboneView( object )\n object\n else\n object.type ||= object.ctype\n\n if !object.type?\n if object.components?\n object.type = object.ctype = 'container'\n else\n object.type = object.ctype = Luca.defaultComponentType\n\n Luca.util.lazyComponent( object )\n\n # if we're using base backbone views, then they don't extend themselves\n # with their passed options, so this is a workaround to get them to\n # pick up the container config property\n if !component.container and component.options.container\n component.container = component.options.container\n\n if map and component.cid?\n map.cid_index[ component.cid ] = index\n\n if map and component.name?\n map.name_index[ component.name ] = index\n\n component\n\n @componentsCreated = true\n\n @registerComponentEvents() unless _.isEmpty(@componentEvents)\n\n map\n\n # Trigger the Rendering Pipeline process on all of the nested\n # components\n renderComponents: (@debugMode=\"\")->\n @debug \"container render components\"\n _(@components).each (component)=>\n component.getParent = ()=> @\n $( component.container ).append $(component.el)\n\n try\n component.render()\n catch e\n console.log \"Error Rendering Component #{ component.name || component.cid }\", component\n\n if _.isObject(e)\n console.log e.message\n console.log e.stack\n\n throw e unless Luca.silenceRenderErrors? is true\n\n #### Container Activation\n #\n # When a container is first activated is a good time to perform\n # operations which are not needed unless that component becomes\n # visible. This first activation event should be relayed to all\n # of the nested components. Components which hide / display\n # other components, such as a CardView or TabContainer\n # will trigger first:activation on the components as they become\n # displayed.\n firstActivation: ()->\n activator = @\n @each (component, index)->\n # apply the first:activation trigger on the component, in the context of the component\n # passing as arguments the component itself, and the component doing the activation\n unless component?.previously_activated is true\n component?.trigger?.call component, \"first:activation\", component, activator\n component.previously_activated = true\n\n #### Underscore Methods For Working with Components\n pluck: (attribute)-> \n _( @components ).pluck attribute\n\n invoke: (method)->\n _( @components ).invoke method\n\n select: (attribute, value, deep=false)->\n components = _( @components ).map (component)->\n matches = []\n test = component[ attribute ]\n\n matches.push( component ) if test is value\n\n # recursively traverse our components\n matches.push component.select?(attribute, value, true) if deep is true\n\n _.compact matches\n\n _.flatten( components )\n\n # event binding sugar for nested components\n #\n # you can define events like:\n\n # _.def(\"MyContainer\").extends(\"Luca.View\").with\n # componentEvents:\n # \"component_name before:load\" : \"mySpecialHandler\"\n #\n componentEvents: {}\n\n registerComponentEvents: ()->\n for listener, handler of @componentEvents\n [componentName,trigger] = listener.split(' ')\n component = @findComponentByName(componentName)\n component?.bind trigger, @[handler]\n\n findComponentByName: (name, deep=false)->\n @findComponent(name, \"name_index\", deep)\n\n findComponentById: (id, deep=false)->\n @findComponent(id, \"cid_index\", deep)\n\n findComponent: (needle, haystack=\"name\", deep=false)->\n @createComponents() unless @componentsCreated is true\n\n\n position = @componentIndex?[ haystack ][ needle ]\n component = @components?[ position ]\n\n return component if component\n\n if deep is true\n sub_container = _( @components ).detect (component)-> component?.findComponent?(needle, haystack, true)\n sub_container?.findComponent?(needle, haystack, true)\n\n each: (fn)->\n @eachComponent(fn, false)\n\n # run a function for each component in this container\n # and any nested containers in those components, recursively\n # pass false as the second argument to skip the deep recursion\n eachComponent: (fn, deep=true)->\n _( @components ).each (component, index)=>\n fn.call component, component, index\n component?.eachComponent?.apply component, [fn,deep] if deep\n\n indexOf: (name)->\n names = _( @components ).pluck('name')\n _( names ).indexOf(name)\n\n activeComponent: ()->\n return @ unless @activeItem\n return @components[ @activeItem ]\n\n componentElements: ()->\n $(\">.#{ @componentClass }\", @el)\n\n getComponent: (needle)->\n @components[ needle ]\n\n rootComponent: ()->\n !@getParent?\n\n getRootComponent: ()->\n if @rootComponent() then @ else @getParent().getRootComponent()"},{"className":"MyContainer","file":"src/core/container.coffee","source":"# The Component Container\n#\n# The Component Container is a nestable component\n# which are responsible for handling communication between multiple\n# nested views.\n#\n# One: Layout\n#\n# a container is responsible for laying out the nested views\n# and rendering them in a special DOM element\ndoLayout = ()->\n @trigger \"before:layout\", @\n @prepareLayout()\n @trigger \"after:layout\", @\n\n# and displaying those elements in a way that is\n# optimal for the desired user experience of that view\n# ( i.e seeing only one of them at a time, seeing them side by side )\napplyDOMConfig = (panel, panelIndex)->\n style_declarations = []\n\n style_declarations.push \"height: #{ (if _.isNumber(panel.height) then panel.height + 'px' else panel.height ) }\" if panel.height?\n style_declarations.push \"width: #{ (if _.isNumber(panel.width) then panel.width + 'px' else panel.width ) }\" if panel.width?\n style_declarations.push \"float: #{ panel.float }\" if panel.float\n\n config =\n class: panel?.classes || @componentClass\n id: \"#{ @cid }-#{ panelIndex }\"\n style: style_declarations.join(';')\n \"data-luca-owner\" : @name || @cid\n\n if @customizeContainerEl?\n config = @customizeContainerEl( config, panel, panelIndex )\n\n config\n\n# Two: Component Creation\n#\n# A container is responsible for creating and storing references to the nested\n# views that are required for its functioning.\ndoComponents = ()->\n\n @trigger \"before:components\", @, @components\n @prepareComponents()\n @createComponents()\n @trigger \"before:render:components\", @, @components\n @renderComponents()\n @trigger \"after:components\", @, @components\n\n\n# Containers are central to Luca. They are what make it easy to structure\n# your application in a logical way and to specify much of the behavior of\n# complex / composite views at define time using JSON syntax combined with\n# the meta data contained in the Luca component registry.\n_.def('Luca.core.Container').extends('Luca.components.Panel').with\n\n className: 'luca-ui-container'\n\n componentTag: 'div'\n componentClass: 'luca-ui-panel'\n\n isContainer: true\n\n hooks:[\n \"before:components\"\n \"before:render:components\"\n \"before:layout\"\n \"after:components\"\n \"after:layout\"\n \"first:activation\"\n ]\n\n rendered: false\n\n components: []\n\n initialize: (@options={})->\n _.extend @, @options\n\n @setupHooks [\n \"before:components\"\n \"before:render:components\"\n \"before:layout\"\n \"after:components\"\n \"after:layout\"\n \"first:activation\"\n ]\n\n Luca.View::initialize.apply @, arguments\n\n # Rendering Pipeline\n #\n # A container has nested components. these components\n # are automatically rendered inside their own DOM element\n # and then CSS configuration is generally applied to these\n # DOM elements. Each component is assigned to this DOM\n # element by specifying a @container property on the component.\n #\n # Each component is instantiated by looking up its @ctype propery\n # in the Luca Component Registry. Then the components are rendered\n # by having their @render() method called on them.\n #\n # Any class which extends Luca.View will have its defined render method\n # wrapped in a method which triggers \"before:render\", and \"after:render\"\n # before and after the defined render method.\n #\n # so you can expect the following, for any container or nested container\n #\n # DOM Element Manipulation:\n #\n # beforeRender()\n # beforeLayout()\n # prepareLayout()\n # afterLayout()\n #\n # Luca / Backbone Component Manipulation\n #\n # beforeComponents()\n # prepareComponents()\n # createComponents()\n # beforeRenderComponents()\n # renderComponents() ->\n # calls render() on each component, starting this whole cycle\n #\n # afterComponents()\n #\n # DOM Injection\n #\n # render()\n # afterRender()\n #\n # For Components which are originally hidden\n # ( card view, tab view, etc )\n #\n # firstActivation()\n #\n beforeRender: ()->\n doLayout.call(@)\n doComponents.call(@)\n Luca.components.Panel::beforeRender?.apply(@, arguments)\n\n # Components which inherit from Luca.core.Container can implement\n # their own versions of this method, if they need to apply any sort\n # of additional styling / configuration for the DOM elements that\n # are created to wrap each container.\n customizeContainerEl: (containerEl, panel, panelIndex)->\n containerEl\n\n prepareLayout: ()->\n container = @\n @componentContainers = _( @components ).map (component, index)->\n applyDOMConfig.call(container, component, index)\n\n # prepare components is where each component gets assigned\n # a container to be rendered into. if @appendContainers is\n # set to true, then the view will automatically $append()\n # elements created via Backbone.View::make() to the body element of the view\n prepareComponents: ()->\n # accept components as an array of strings representing\n # the luca component type\n for component in @components when _.isString(component)\n component = (type: component)\n\n _( @components ).each (component, index)=>\n container = @componentContainers?[index]\n\n # support a variety of the bad naming conventions\n container.class = container.class || container.className || container.classes\n\n if @appendContainers\n panel = @make(@componentTag, container, '')\n @$append( panel )\n\n unless component.container?\n component.container = \"##{ container.id }\" if @appendContainers\n component.container ||= @$bodyEl()\n\n # create components is responsible for turning the JSON syntax of the\n # container's definition into live objects against a given Luca Component\n # type.\n #\n # In addition to this, a container builds an index of the components\n # which belong to it, so that they can easily be looked up by name\n createComponents: ()->\n return if @componentsCreated is true\n\n map = @componentIndex =\n name_index: {}\n cid_index: {}\n\n @components = _( @components ).map (object, index)=>\n\n # you can include normal backbone views as components\n # you will want to make sure your render method handles\n # adding the views @$el to the appropriate @container.\n\n # you can also just pass a string representing the component_type\n component = if Luca.isBackboneView( object )\n object\n else\n object.type ||= object.ctype\n\n if !object.type?\n if object.components?\n object.type = object.ctype = 'container'\n else\n object.type = object.ctype = Luca.defaultComponentType\n\n Luca.util.lazyComponent( object )\n\n # if we're using base backbone views, then they don't extend themselves\n # with their passed options, so this is a workaround to get them to\n # pick up the container config property\n if !component.container and component.options.container\n component.container = component.options.container\n\n if map and component.cid?\n map.cid_index[ component.cid ] = index\n\n if map and component.name?\n map.name_index[ component.name ] = index\n\n component\n\n @componentsCreated = true\n\n @registerComponentEvents() unless _.isEmpty(@componentEvents)\n\n map\n\n # Trigger the Rendering Pipeline process on all of the nested\n # components\n renderComponents: (@debugMode=\"\")->\n @debug \"container render components\"\n _(@components).each (component)=>\n component.getParent = ()=> @\n $( component.container ).append $(component.el)\n\n try\n component.render()\n catch e\n console.log \"Error Rendering Component #{ component.name || component.cid }\", component\n\n if _.isObject(e)\n console.log e.message\n console.log e.stack\n\n throw e unless Luca.silenceRenderErrors? is true\n\n #### Container Activation\n #\n # When a container is first activated is a good time to perform\n # operations which are not needed unless that component becomes\n # visible. This first activation event should be relayed to all\n # of the nested components. Components which hide / display\n # other components, such as a CardView or TabContainer\n # will trigger first:activation on the components as they become\n # displayed.\n firstActivation: ()->\n activator = @\n @each (component, index)->\n # apply the first:activation trigger on the component, in the context of the component\n # passing as arguments the component itself, and the component doing the activation\n unless component?.previously_activated is true\n component?.trigger?.call component, \"first:activation\", component, activator\n component.previously_activated = true\n\n #### Underscore Methods For Working with Components\n pluck: (attribute)-> \n _( @components ).pluck attribute\n\n invoke: (method)->\n _( @components ).invoke method\n\n select: (attribute, value, deep=false)->\n components = _( @components ).map (component)->\n matches = []\n test = component[ attribute ]\n\n matches.push( component ) if test is value\n\n # recursively traverse our components\n matches.push component.select?(attribute, value, true) if deep is true\n\n _.compact matches\n\n _.flatten( components )\n\n # event binding sugar for nested components\n #\n # you can define events like:\n\n # _.def(\"MyContainer\").extends(\"Luca.View\").with\n # componentEvents:\n # \"component_name before:load\" : \"mySpecialHandler\"\n #\n componentEvents: {}\n\n registerComponentEvents: ()->\n for listener, handler of @componentEvents\n [componentName,trigger] = listener.split(' ')\n component = @findComponentByName(componentName)\n component?.bind trigger, @[handler]\n\n findComponentByName: (name, deep=false)->\n @findComponent(name, \"name_index\", deep)\n\n findComponentById: (id, deep=false)->\n @findComponent(id, \"cid_index\", deep)\n\n findComponent: (needle, haystack=\"name\", deep=false)->\n @createComponents() unless @componentsCreated is true\n\n\n position = @componentIndex?[ haystack ][ needle ]\n component = @components?[ position ]\n\n return component if component\n\n if deep is true\n sub_container = _( @components ).detect (component)-> component?.findComponent?(needle, haystack, true)\n sub_container?.findComponent?(needle, haystack, true)\n\n each: (fn)->\n @eachComponent(fn, false)\n\n # run a function for each component in this container\n # and any nested containers in those components, recursively\n # pass false as the second argument to skip the deep recursion\n eachComponent: (fn, deep=true)->\n _( @components ).each (component, index)=>\n fn.call component, component, index\n component?.eachComponent?.apply component, [fn,deep] if deep\n\n indexOf: (name)->\n names = _( @components ).pluck('name')\n _( names ).indexOf(name)\n\n activeComponent: ()->\n return @ unless @activeItem\n return @components[ @activeItem ]\n\n componentElements: ()->\n $(\">.#{ @componentClass }\", @el)\n\n getComponent: (needle)->\n @components[ needle ]\n\n rootComponent: ()->\n !@getParent?\n\n getRootComponent: ()->\n if @rootComponent() then @ else @getParent().getRootComponent()"},{"className":"Luca.View","file":"src/core/view.coffee","source":"_.def(\"Luca.View\").extends(\"Backbone.View\").with\n\n additionalClassNames:[]\n\n debug: ()->\n return unless @debugMode or window.LucaDebugMode?\n console.log [(@name || @cid),message] for message in arguments\n\n trigger: ()->\n if Luca.enableGlobalObserver\n if Luca.developmentMode is true or @observeEvents is true\n Luca.ViewObserver ||= new Luca.Observer(type:\"view\")\n Luca.ViewObserver.relay @, arguments\n\n Backbone.View.prototype.trigger.apply @, arguments\n\n hooks:[\n \"after:initialize\"\n \"before:render\"\n \"after:render\"\n \"first:activation\"\n \"activation\"\n \"deactivation\"\n ]\n\n initialize: (@options={})->\n\n _.extend @, @options\n\n @cid = _.uniqueId(@name) if @name?\n\n if template = @bodyTemplate\n @$el.empty()\n Luca.View::$html.call(@, Luca.template(template, @) )\n\n Luca.cache( @cid, @ )\n\n unique = _( Luca.View.prototype.hooks.concat( @hooks ) ).uniq()\n\n @setupHooks( unique )\n\n if @autoBindEventHandlers is true\n @bindAllEventHandlers()\n\n if @additionalClassNames\n @additionalClassNames = @additionalClassNames.split(\" \") if _.isString(@additionalClassNames)\n @$el.addClass( additional ) for additional in @additionalClassNames\n\n @$wrap(@wrapperClass) if @wrapperClass?\n\n @trigger \"after:initialize\", @\n\n @registerCollectionEvents()\n\n @delegateEvents()\n\n #### JQuery / DOM Selector Helpers\n $wrap: (wrapper)->\n if _.isString(wrapper) and not wrapper.match(/[<>]/)\n wrapper = @make(\"div\",class:wrapper)\n\n @$el.wrap( wrapper )\n\n $template: (template, variables={})->\n @$el.html( Luca.template(template,variables) )\n\n $html: (content)->\n @$el.html( content )\n\n $append: (content)->\n @$el.append( content )\n\n #### Containers\n #\n # Luca is heavily reliant on the concept of Container views. Views which\n # contain other views and handle inter-component communication between the\n # component views. The default render() operation consists of building the\n # view's content, and then attaching that view to its container.\n #\n # 99% of the time this would happen automatically\n $attach: ()->\n @$container().append( @el )\n\n $container: ()->\n $(@container)\n\n #### Hooks or Auto Event Binding\n #\n # views which inherit from Luca.View can define hooks\n # or events which can be emitted from them. Automatically,\n # any functions on the view which are named according to the\n # convention will automatically get run.\n #\n # by default, all Luca.View classes come with the following:\n #\n # before:render : beforeRender()\n # after:render : afterRender()\n # after:initialize : afterInitialize()\n # first:activation : firstActivation()\n setupHooks: (set)->\n set ||= @hooks\n\n _(set).each (eventId)=>\n fn = Luca.util.hook( eventId )\n\n callback = ()=>\n @[fn]?.apply @, arguments\n\n callback = _.once(callback) if eventId?.match(/once:/)\n\n @bind eventId, callback\n\n\n #### Luca.Collection and Luca.CollectionManager integration\n\n # under the hood, this will find your collection manager using\n # Luca.CollectionManager.get, which is a function that returns\n # the first instance of the CollectionManager class ever created.\n #\n # if you want to use more than one collection manager, over ride this\n # function in your views with your own logic\n getCollectionManager: ()->\n @collectionManager || Luca.CollectionManager.get?()\n\n ##### Collection Events\n #\n # By defining a hash of collectionEvents in the form of\n #\n # \"books add\" : \"onBookAdd\"\n #\n # the Luca.View will bind to the collection found in the\n # collectionManager with that key, and bind to that event.\n # a property of @booksCollection will be created on the view,\n # and the \"add\" event will trigger \"onBookAdd\"\n #\n # you may also specify a function directly. this\n #\n registerCollectionEvents: ()->\n manager = @getCollectionManager()\n\n _( @collectionEvents ).each (handler, signature)=>\n [key,event] = signature.split(\" \")\n\n collection = @[\"#{ key }Collection\"] = manager.getOrCreate( key )\n\n if !collection\n throw \"Could not find collection specified by #{ key }\"\n\n if _.isString(handler)\n handler = @[handler]\n\n unless _.isFunction(handler)\n throw \"invalid collectionEvents configuration\"\n\n try\n collection.bind(event, handler)\n catch e\n console.log \"Error Binding To Collection in registerCollectionEvents\", @\n throw e\n\n registerEvent: (selector, handler)->\n @events ||= {}\n @events[ selector ] = handler\n @delegateEvents()\n\n bindAllEventHandlers: ()->\n _( @events ).each (handler,event)=>\n if _.isString(handler)\n _.bindAll @, handler\n\n definitionClass: ()->\n Luca.util.resolve(@displayName, window)?.prototype\n\n # refreshCode happens whenever the Luca.Framework extension\n # system is run after there are running instances of a given component\n\n # in the context of views, what this means is that each eventHandler which\n # is bound to a specific object via _.bind or _.bindAll, or autoBindEventHandlers\n # is refreshed with the prototype method of the component that it inherits from,\n # and then delegateEvents is called to refresh any of the updated event handlers\n\n # in addition to this, all properties of the instance of a given view which are\n # also backbone views will have the same process run against them\n refreshCode: ()->\n view = @\n\n _( @eventHandlerProperties() ).each (prop)->\n view[ prop ] = view.definitionClass()[prop]\n\n if @autoBindEventHandlers is true\n @bindAllEventHandlers()\n\n @delegateEvents()\n\n eventHandlerProperties: ()->\n handlerIds = _( @events ).values()\n _( handlerIds ).select (v)->\n _.isString(v)\n\n eventHandlerFunctions: ()->\n handlerIds = _( @events ).values()\n _( handlerIds ).map (handlerId)=>\n if _.isFunction(handlerId) then handlerId else @[handlerId]\n\n collections: ()-> Luca.util.selectProperties( Luca.isBackboneCollection, @ )\n models: ()-> Luca.util.selectProperties( Luca.isBackboneModel, @ )\n views: ()-> Luca.util.selectProperties( Luca.isBackboneView, @ )\n\n\noriginalExtend = Backbone.View.extend\n\ncustomizeRender = (definition)->\n #### Rendering\n #\n # Our base view class wraps the defined render() method\n # of the views which inherit from it, and does things like\n # trigger the before and after render events automatically.\n # In addition, if the view has a deferrable property on it\n # then it will make sure that the render method doesn't get called\n # until.\n\n _base = definition.render\n\n _base ||= Luca.View::$attach\n\n\n definition.render = ()->\n view = @\n # if a view has a deferrable property set\n\n if @deferrable\n target = @deferrable_target\n\n unless Luca.isBackboneCollection(@deferrable)\n @deferrable = @collection\n\n target ||= @deferrable\n trigger = if @deferrable_event then @deferrable_event else \"reset\"\n\n deferred = ()->\n _base.call(view)\n view.trigger(\"after:render\", view)\n\n view.defer(deferred).until(target, trigger)\n\n view.trigger \"before:render\", @\n\n autoTrigger = @deferrable_trigger || @deferUntil\n\n if !autoTrigger?\n target[ (@deferrable_method||\"fetch\") ].call(target)\n else\n fn = _.once ()=> @deferrable[ (@deferrable_method||\"fetch\") ]?()\n (@deferrable_target || @ ).bind(@deferrable_trigger, fn)\n\n return @\n\n else\n @trigger \"before:render\", @\n _base.apply(@, arguments)\n @trigger \"after:render\", @\n\n return @\n\n definition\n\n# By overriding Backbone.View.extend we are able to intercept\n# some method definitions and add special behavior around them\n# mostly related to render()\nLuca.View.extend = (definition)->\n definition = customizeRender( definition )\n originalExtend.call(@, definition)\n\n"},{"className":"MyView","file":"src/core/core.coffee","source":"# Component Definition Helpers\n#\n#\n# We have customized the core Backbone.extend process to use a slightly\n# different syntax, which allows us to intercept the component definition at\n# various points, and maintain information about classes being defined, and\n# the relationships between inherited classes, etc.\n\n# _.def, or Luca.define returns a chainable object which allows you to define\n# your components with a readable syntax. For example:\n\n# _.def(\"Luca.View\").extends(\"Backbone.View\").with the_good:\"shit\"\n# _.def(\"MyView\").extends(\"Luca.View\").with the_custom:\"shit\"\n\nLuca.define = (componentName)->\n new DefineProxy(componentName)\n\nLuca.component = Luca.define\n\n# The define proxy chain sets up a call to Luca.extend, which is a wrapper around Luca and Backbone component class' extend function.\nclass DefineProxy\n constructor:(componentName)->\n @namespace = Luca.util.namespace()\n @componentId = @componentName = componentName\n\n if componentName.match(/\\./)\n @namespaced = true\n parts = componentName.split('.')\n @componentId = parts.pop()\n @namespace = parts.join('.')\n\n # automatically add the namespace to the namespace registry\n Luca.registry.addNamespace( parts.join('.') )\n\n # allow for specifying the namespace\n in: (@namespace)-> @\n\n # allow for multiple ways of saying the same thing for readability purposes\n from: (@superClassName)-> @\n extends: (@superClassName)-> @\n extend: (@superClassName)-> @\n\n # an alias for with, or a readability helper in multi-line definitions\n enhance: (properties)->\n return @with(properties) if properties?\n @\n\n # which properties, methods, etc will you be extending the base class with?\n with: (properties)->\n at = if @namespaced\n Luca.util.resolve(@namespace, (window || global))\n else\n (window||global)\n\n # automatically create the namespace\n if @namespaced and not at?\n eval(\"(window||global).#{ @namespace } = {}\")\n at = Luca.util.resolve(@namespace,(window || global))\n\n at[@componentId] = Luca.extend(@superClassName,@componentName, properties)\n\n if Luca.autoRegister is true \n componentType = \"view\" if Luca.isViewPrototype( at[@componentId] )\n\n if Luca.isCollectionPrototype( at[@componentId] )\n Luca.Collection.namespaces ||= []\n Luca.Collection.namespaces.push( @namespace )\n componentType = \"collection\" \n\n componentType = \"model\" if Luca.isModelPrototype( at[@componentId] )\n\n # automatically register this with the component registry\n Luca.register( _.string.underscored(@componentId), @componentName, componentType)\n\n at[@componentId]\n\n# The last method of the DefineProxy chain is always going to result in\n# a call to Luca.extend. Luca.extend wraps the call to Luca.View.extend,\n# or Backbone.Collection.extend, and accepts the names of the extending,\n# and extended classes as strings. This allows us to maintain information\n# and references to the classes and their prototypes, mainly for the purposes\n# of introspection and development tools\nLuca.extend = (superClassName, childName, properties={})->\n superClass = Luca.util.resolve( superClassName, (window || global) )\n\n unless _.isFunction(superClass?.extend)\n throw \"#{ superClassName } is not a valid component to extend from\"\n\n properties.displayName = childName\n\n properties._superClass = ()->\n superClass.displayName ||= superClassName\n superClass\n\n properties._super = (method, context, args)->\n @_superClass().prototype[method]?.apply(context, args)\n\n superClass.extend(properties)\n\n_.mixin\n def: Luca.define\n\n\n# Luca.Events\n#\n# These helpers will get mixed into Luca.Collection, Luca.View, and Luca.Model.\n#\n# They allow for syntactic sugar like:\n#\n# view.defer(\"someMethodOnTheView\").until(\"collection\",\"fetch\")\n#\n# or\n#\n# view.defer( myCallback ).until(\"triggered:event\")\nclass DeferredBindingProxy\n constructor: (@object, operation, wrapWithUnderscore=true)->\n if _.isFunction(operation)\n fn = operation\n\n else if _.isString(operation) and _.isFunction(@object[operation])\n fn = @object[operation]\n\n unless _.isFunction(fn)\n throw \"Must pass a function or a string representing one\"\n\n if wrapWithUnderscore is true\n @fn = ()=>\n _.defer(fn)\n else\n @fn = fn\n\n @\n\n # until accepts an object to bind to, and a trigger to bind with\n # if you just pass a trigger, the object getting bound to\n # will implicitly be @object\n until: (watch, trigger)->\n if watch? and not trigger?\n trigger = watch\n watch = @object\n\n watch.once(trigger, @fn)\n\n @object\n\nLuca.Events =\n defer: (operation, wrapWithUnderscore=true)->\n new DeferredBindingProxy(@, operation, wrapWithUnderscore)\n\n once: (trigger, callback, context)->\n context ||= @\n\n onceFn = ()->\n callback.apply(context, arguments)\n @unbind(trigger, onceFn)\n\n @bind trigger, onceFn\n\nclass Luca.ScriptLoader\n @loaded: {}\n\n constructor: (options={})->\n _.extend(@, Backbone.Events, Luca.Events)\n @autoStart = options.autoStart is true\n @scripts = options.scripts\n\n ready = ()-> @trigger(\"ready\")\n\n @ready = _.after( @scripts.length, ready)\n\n _.bindAll @, \"load\", \"ready\"\n\n @defer(\"load\").until(@, \"start\")\n\n if @autoStart is true\n @trigger(\"start\")\n\n @bind \"ready\", @onReady\n\n applyPrefix: (script)->\n script\n\n onReady: ()->\n console.log \"All dependencies loaded\"\n\n start: ()->\n @trigger(\"start\")\n\n load: ()->\n Luca.util.loadScript( @applyPrefix(script), @ready ) for script in @scripts\n\n"},{"className":"Luca.core.Field","file":"src/core/field.coffee","source":"_.def('Luca.core.Field').extends('Luca.View').with\n\n className: 'luca-ui-text-field luca-ui-field'\n\n isField: true\n\n template: 'fields/text_field'\n\n labelAlign: 'top'\n\n hooks:[\n \"before:validation\",\n \"after:validation\",\n \"on:change\"\n ]\n\n # see: http://twitter.github.com/bootstrap/base-css.html\n statuses: [\n \"warning\"\n \"error\"\n \"success\"\n ]\n\n initialize: (@options={})->\n _.extend @, @options\n\n @input_id ||= _.uniqueId('field')\n @input_name ||= @name\n @input_class ||= \"\"\n @helperText ||= \"\"\n @label ||= \"*#{ @label }\" if @required and not @label?.match(/^\\*/)\n @inputStyles ||= \"\"\n\n @disable() if @disabled\n\n @updateState( @state )\n @placeHolder ||= \"\"\n\n Luca.View::initialize.apply(@, arguments)\n\n beforeRender: ()->\n if Luca.enableBootstrap\n @$el.addClass('control-group')\n\n @$el.addClass('required') if @required\n\n @$el.html Luca.templates[ @template ]( @ )\n @input = $('input', @el)\n\n change_handler: (e)->\n @trigger \"on:change\", @, e\n\n disable: ()->\n $(\"input\",@el).attr('disabled', true)\n\n enable: ()->\n $(\"input\", @el).attr('disabled', false)\n\n getValue: ()->\n @input.attr('value')\n\n render: ()->\n $( @container ).append( @$el )\n\n setValue: (value)->\n @input.attr('value', value)\n\n updateState: (state)->\n _( @statuses ).each (cls)=>\n @$el.removeClass(cls)\n @$el.addClass(state)"},{"className":"Luca.Model","file":"src/core/model.coffee","source":"# Luca.Model\n#\n# Luca.Model is an extenstion of Backbone.Model which provides\n# few useful patterns:\n#\n# - computed properties support\n_.def('Luca.Model').extends('Backbone.Model').with\n initialize: ()->\n Backbone.Model::initialize @, arguments\n\n return if _.isUndefined(@computed)\n\n @_computed = {}\n\n for attr, dependencies of @computed\n @on \"change:#{attr}\", ()=>\n @_computed[attr] = @[attr].call @\n\n _(dependencies).each (dep)=>\n @on \"change:#{dep}\", ()=>\n @trigger \"change:#{attr}\"\n @trigger \"change:#{attr}\" if @has(dep)\n\n get: (attr)->\n if @computed?.hasOwnProperty(attr)\n @_computed[attr]\n else\n Backbone.Model::get.call @, attr\n"},{"className":"Luca.components.Panel","file":"src/core/panel.coffee","source":"# This is a helper for creating the DOM element that go along with\n# a given component, if it is configured to use one via the topToolbar\n# and bottomToolbar properties\nattachToolbar = (config={}, targetEl)->\n config.orientation ||= \"top\"\n config.ctype ||= @toolbarType || \"panel_toolbar\"\n\n id = \"#{ @cid }-tbc-#{ config.orientation }\"\n\n toolbar = Luca.util.lazyComponent( config )\n\n container = @make \"div\",\n class:\"toolbar-container #{ config.orientation }\",\n id: id\n ,\n toolbar.render().el\n\n hasBody = @bodyClassName or @bodyTagName\n\n # there will be a body panel inside of the views $el\n # so just place the toolbar before, or after the body\n action = switch config.orientation\n when \"top\", \"left\"\n if hasBody then \"before\" else \"prepend\"\n when \"bottom\", \"right\"\n if hasBody then \"after\" else \"append\"\n\n (targetEl || @$bodyEl() )[action]( container )\n\n# A Panel is a basic Luca.View but with Toolbar extensions\n#\n# In general other components should inherit from the panel class.\n\n_.def(\"Luca.components.Panel\").extends(\"Luca.View\").with\n\n topToolbar: undefined\n\n bottomToolbar: undefined\n\n # Load Mask will apply a transparent overlay over the form\n # upon submission, with a moving progress bar which will be\n # hidden upon successful response\n loadMask: false\n loadMaskTemplate: [\"components/load_mask\"]\n loadMaskTimeout: 3000\n\n initialize: (@options={})->\n Luca.View::initialize.apply(@, arguments)\n\n _.bindAll @, \"applyLoadMask\", \"disableLoadMask\"\n\n if @loadMask is true\n @defer ()=>\n @$el.addClass('with-mask')\n\n if @$('.load-mask').length is 0\n @loadMaskTarget().prepend Luca.template(@loadMaskTemplate, @)\n @$('.load-mask').hide()\n .until(\"after:render\")\n\n @on \"enable:loadmask\", @applyLoadMask\n @on \"disable:loadmask\", @applyLoadMask\n\n loadMaskTarget: ()->\n if @loadMaskEl? then @$(@loadMaskEl) else @$bodyEl()\n\n disableLoadMask: ()->\n @$('.load-mask .bar').css(\"width\",\"100%\")\n @$('.load-mask').hide()\n clearInterval(@loadMaskInterval)\n\n enableLoadMask: ()->\n @$('.load-mask').show().find('.bar').css(\"width\",\"0%\")\n maxWidth = @$('.load-mask .progress').width()\n if maxWidth < 20 and (maxWidth = @$el.width()) < 20\n maxWidth = @$el.parent().width()\n\n @loadMaskInterval = setInterval ()=>\n currentWidth = @$('.load-mask .bar').width()\n newWidth = currentWidth + 12\n @$('.load-mask .bar').css('width', newWidth)\n , 200\n\n return unless @loadMaskTimeout?\n\n _.delay ()=>\n @disableLoadMask()\n , @loadMaskTimeout\n\n applyLoadMask: ()->\n if @$('.load-mask').is(\":visible\")\n @disableLoadMask()\n else\n @enableLoadMask()\n\n applyStyles: (styles={},body=false)->\n\n target = if body then @$bodyEl() else @$el\n\n for setting, value of styles\n target.css(setting,value)\n\n @\n\n beforeRender: ()->\n Luca.View::beforeRender?.apply(@, arguments)\n @applyStyles( @styles ) if @styles?\n @applyStyles( @bodyStyles, true ) if @bodyStyles?\n @renderToolbars?()\n\n $bodyEl: ()->\n element = @bodyTagName || \"div\"\n className = @bodyClassName || \"view-body\"\n\n @bodyEl ||= \"#{ element }.#{ className }\"\n\n bodyEl = @$(@bodyEl)\n\n return bodyEl if bodyEl.length > 0\n\n # if we've been configured to have one, and it doesn't exist\n # then we should append it to ourselves\n if bodyEl.length is 0 and (@bodyClassName? || @bodyTagName?)\n newElement = @make(element,class:className,\"data-auto-appended\":true)\n $(@el).append( newElement )\n return @$(@bodyEl)\n\n\n $(@el)\n\n $wrap: (wrapper)->\n if _.isString(wrapper) and not wrapper.match(/[<>]/)\n wrapper = @make(\"div\",class:wrapper)\n\n @$el.wrap( wrapper )\n\n $template: (template, variables={})->\n @$html( Luca.template(template,variables) )\n\n $html: (content)->\n @$bodyEl().html( content )\n\n $append: (content)->\n @$bodyEl().append(content)\n\n # Luca containers can have toolbars,\n # these will get injected before or after the bodyEl, or at the top\n # or bottom of the $el\n renderToolbars: ()->\n _( [\"top\",\"left\",\"right\",\"bottom\"] ).each (orientation)=>\n if config = @[\"#{ orientation }Toolbar\"]\n @renderToolbar( orientation, config)\n\n renderToolbar: (orientation=\"top\", config={})->\n config.parent = @\n config.orientation = orientation\n\n attachToolbar.call(@, config, config.targetEl )"},{"className":"App.collections.MyCollection","file":"src/samples/definition.coffee","source":"# Component Definition\n\n# In Luca, we define components like such:\n\n_.def(\"App.collections.MyCollection\").extends(\"Luca.Collection\").with\n cache_key: \"my_collection\"\n storageEngine: \"localStorage\"\n\n_.def(\"App.views.MyView\").extends(\"Luca.core.Container\").with\n name: \"default_name_of_the_view\"\n components:[\n ctype: \"form_view\"\n ,\n ctype: \"grid_view\"\n collection: \"my_collection\"\n ]\n initialize: (@options)->\n @_super(\"initialize\", @, arguments)\n @customMethod()\n\n# This achieves a few things:\n#\n# 0. More pleasant to read\n#\n# 1. All instances of App.views.MyView have a displayName property set\n# so we know upon inspection which class they inherit from\n#\n# 2. All instances of App.views.MyView know that they extend Luca.components.FormView,\n# which allows us to use @_super() when overriding important framework methods, and\n# saves us from having to type Luca.core.Container.prototype.initialize.apply(@, arguments)\n# every time, on every method that it is needed\n#\n# 3. App.views.MyView gets assigned a ctype: \"my_view\" so that we can use a declarative\n# JSON syntax for building complex components made up of smaller views, models, collections\n# simply by referencing their 'ctype'. This allows Luca.Containers to create the nested components\n# for you\n#\n# 4. Luca.registry knows about all of the components defined against it, as well as all instances of\n# the components, so with our in browser development tool we can modify the prototype of a view and\n# automatically refresh all running instances of the comoponent with updated code\n#\n# 5. We don't actually have to create App.views.MyView right away, we could develop an intermediate layer\n# which stores the name of the defined view, who it extends from, and what customizations are being made to it\n# in some temporary buffer, and build our own dependency management layer which handles loading dependencies on demand\n\n# Problem\n#\n# What is the best way to integrate a solution like requirejs, airdrop, stitch, or similar\n# with the above style of component definition?"},{"className":"App.views.MyView","file":"src/samples/definition.coffee","source":"# Component Definition\n\n# In Luca, we define components like such:\n\n_.def(\"App.collections.MyCollection\").extends(\"Luca.Collection\").with\n cache_key: \"my_collection\"\n storageEngine: \"localStorage\"\n\n_.def(\"App.views.MyView\").extends(\"Luca.core.Container\").with\n name: \"default_name_of_the_view\"\n components:[\n ctype: \"form_view\"\n ,\n ctype: \"grid_view\"\n collection: \"my_collection\"\n ]\n initialize: (@options)->\n @_super(\"initialize\", @, arguments)\n @customMethod()\n\n# This achieves a few things:\n#\n# 0. More pleasant to read\n#\n# 1. All instances of App.views.MyView have a displayName property set\n# so we know upon inspection which class they inherit from\n#\n# 2. All instances of App.views.MyView know that they extend Luca.components.FormView,\n# which allows us to use @_super() when overriding important framework methods, and\n# saves us from having to type Luca.core.Container.prototype.initialize.apply(@, arguments)\n# every time, on every method that it is needed\n#\n# 3. App.views.MyView gets assigned a ctype: \"my_view\" so that we can use a declarative\n# JSON syntax for building complex components made up of smaller views, models, collections\n# simply by referencing their 'ctype'. This allows Luca.Containers to create the nested components\n# for you\n#\n# 4. Luca.registry knows about all of the components defined against it, as well as all instances of\n# the components, so with our in browser development tool we can modify the prototype of a view and\n# automatically refresh all running instances of the comoponent with updated code\n#\n# 5. We don't actually have to create App.views.MyView right away, we could develop an intermediate layer\n# which stores the name of the defined view, who it extends from, and what customizations are being made to it\n# in some temporary buffer, and build our own dependency management layer which handles loading dependencies on demand\n\n# Problem\n#\n# What is the best way to integrate a solution like requirejs, airdrop, stitch, or similar\n# with the above style of component definition?"},{"className":"Luca.tools.CodeEditor","file":"src/tools/code_editor.coffee","source":"BuffersModel = Luca.Model.extend\n defaults:\n _current: \"default\"\n _namespace: \"default\"\n _compiled: []\n\n initialize: (@attributes={})->\n Luca.Model::initialize.apply(@, arguments)\n @fetch(silent:true)\n\n requireCompilation: ()->\n @get(\"_compiled\")\n\n bufferKeys: ()->\n return @bufferNames if @bufferNames?\n\n for key, value of @attributes when !key.match(/_/)\n key\n\n namespacedBuffer: (key)->\n \"#{ @get('_namespace') }:#{ key }\"\n\n bufferValues: ()->\n _( @attributes ).pick( @bufferKeys() )\n\n fetch: (options={})->\n options.silent ||= true\n\n _( @bufferKeys() ).each (key)=>\n value = localStorage?.getItem( @namespacedBuffer(key) )\n @set(key, value, silent: options.silent is true) if value?\n\n @\n\n persist: ()->\n _( @bufferKeys() ).each (key)=>\n value = @get(key)\n localStorage?.setItem( @namespacedBuffer(key), value)\n\n @\n\n currentContent: ()->\n current = @get(\"_current\")\n @get(current)\n\ncompilers =\n coffeescript: (code)->\n CoffeeScript.compile code, bare: true\n default: (code)->\n code\n\n_.def(\"Luca.tools.CodeEditor\").extends(\"Luca.components.Panel\").with\n name: \"code_editor\"\n\n id: \"editor_container\"\n\n autoBindEventHandlers: true\n\n bodyClassName: \"codemirror-wrapper\"\n\n defaultValue: ''\n\n compilationEnabled: false\n\n bufferNamespace: \"luca:code\"\n\n namespace: (set, options={})->\n if set?\n @bufferNamespace = set\n @buffers?.set(\"_namespace\", set, silent: (options.silent is true) )\n\n @bufferNamespace\n\n initialize: (@options)->\n @_super(\"initialize\", @, arguments)\n\n _.bindAll @, \"onCompiledCodeChange\", \"onBufferChange\", \"onEditorChange\", \"stripTabs\"\n\n @mode ||= \"coffeescript\"\n @theme ||= \"monokai\"\n @keyMap ||= \"vim\"\n @lineWrapping ||= true\n\n @compiler = compilers[@mode] || compilers.default\n\n @setupBuffers()\n\n setWrap: (@lineWrapping)->\n @editor.setOption(\"lineWrapping\", @lineWrapping)\n\n setMode: (@mode)->\n @editor.setOption(\"mode\", @mode)\n @\n\n setKeyMap: (@keyMap)->\n @editor.setOption(\"keyMap\", @keyMap)\n @\n\n setTheme: (@theme)->\n @editor.setOption(\"theme\",@theme)\n @\n\n setupBuffers: ()->\n attributes = _.extend(@currentBuffers || {},_compiled:@compiledBuffers,_namespace:@namespace())\n @buffers = new BuffersModel(attributes)\n\n editor = @\n\n _( @buffers.bufferKeys() ).each (key)=>\n @buffers.bind \"change:#{ key }\", ()=>\n @onBufferChange.apply(@, arguments)\n\n _( @buffers.requireCompilation() ).each (key)=>\n @buffers.bind \"change:compiled_#{ key }\", @onCompiledCodeChange\n\n # handle switching of the buffers. when the editor\n # is told to switch buffers, we will get the current content\n # in that buffer, and update the code mirror instance\n @buffers.bind \"change:_current\", (model,value)=>\n editor.trigger \"buffer:change\"\n editor.editor.setValue( @buffers.currentContent() || \"\" )\n\n @monitorChanges = true\n\n currentBuffer: ()->\n @buffers.get(\"_current\")\n\n loadBuffer: (bufferName, autoSave=true)->\n @saveBuffer() if autoSave\n @buffers.set(\"_current\", bufferName)\n\n saveBuffer: ()->\n localStorage.setItem( @buffers.namespacedBuffer( @currentBuffer() ), @editor.getValue())\n @buffers.set( @currentBuffer(), @editor.getValue() )\n\n getBuffer: (buffer, compiled=false)->\n buffer ||= @currentBuffer()\n code = @buffers.get( buffer )\n\n return code unless compiled is true\n\n compiledCode = @buffers.get(\"compiled_#{ buffer }\")\n\n if _.string.isBlank(compiledCode)\n compiledCode = @compileCode(code, buffer)\n\n return compiledCode\n\n editorOptions: ()->\n mode: @mode\n theme: @theme\n keyMap: @keyMap\n lineNumbers: true\n gutter: true\n autofocus: true\n onChange: @onEditorChange\n onKeyEvent: @stripTabs\n passDelay: 50\n autoClearEmptyLines: true\n smartIndent: false\n tabSize: 2\n electricChars: false\n\n\n beforeRender: ()->\n Luca.components.Panel::beforeRender?.apply(@, arguments)\n\n styles =\n \"min-height\": @minHeight\n background:'#272822'\n color:'#f8f8f2'\n\n @$bodyEl().css(styles)\n\n @$html \"<textarea></textarea>\"\n\n afterRender: ()->\n _.defer ()=>\n @editor = window.CodeMirror.fromTextArea( @$('textarea')[0], @editorOptions())\n @restore()\n @enableTabStripping = true\n\n save: ()->\n @saveBuffer()\n\n restore: ()->\n @editor.setValue(\"\")\n @editor.refresh()\n\n replaceTabWithSpace: ()->\n\n stripTabs: (editor, keyEvent)->\n if keyEvent?.keyCode is 9\n coords = @editor.cursorCoords()\n cleansed = @getValue().replace(/\\t/g,' ')\n @setValue(cleansed)\n @editor.setCursor( coords )\n\n false\n\n onEditorChange: ()->\n if @monitorChanges\n @save()\n\n onBufferChange: (model, newValue, changes)->\n previous = model.previousAttributes()\n\n _( @buffers.bufferKeys() ).each (key)=>\n if previous[key] isnt @buffers.get(key)\n\n if _( @buffers.requireCompilation() ).include(key)\n result = @compileCode( @buffers.get(key), key )\n if result.success is true\n @buffers.persist(key)\n @buffers.set(\"compiled_#{ key }\", result.compiled, silent: true)\n else\n @trigger \"code:change:#{ key }\", @buffers.get(key)\n @buffers.persist(key)\n\n @buffers.change()\n\n onCompiledCodeChange: (model, newValue, changes)->\n changedBuffers = _( model.changedAttributes() ).keys()\n @trigger \"code:change\", changedBuffers\n for changed in changedBuffers\n @trigger \"code:change:#{ changed }\", changed\n\n compileCode: (code, buffer)->\n buffer ||= @currentBuffer()\n code ||= @getBuffer(buffer, false)\n\n compiled = \"\"\n\n result =\n success: true\n compiled: \"\"\n\n try\n compiled = @compiler.call(@, code)\n @trigger \"compile:success\", code, compiled\n result.compiled = compiled\n catch error\n @trigger \"compile:error\", error, code\n result.success = false\n result.compiled = @buffers.get(\"compiled_#{ buffer }\")\n\n result\n\n getCompiledCode: (buffer)->\n buffer = @getBuffer(buffer)\n _.string.strip( @compileCode(buffer) )\n\n getValue: ()->\n @editor.getValue()\n\n setValue: (value)->\n value = value.replace(/\\t/g, ' ')\n @editor.setValue( value )"},{"className":"Luca.tools.CoffeeEditor","file":"src/tools/coffee_script_editor.coffee","source":"_.def(\"Luca.tools.CoffeeEditor\").extends(\"Luca.tools.CodeMirrorField\").with\n name : \"coffeescript_editor\"\n\n autoCompile: true\n\n compileOptions:\n bare: true\n\n hooks:[\n \"editor:change\"\n ]\n\n initialize: (@options)->\n Luca.tools.CodeMirrorField::initialize.apply(@, arguments)\n\n _.bindAll(@, \"editorChange\", \"toggleSource\")\n\n editor = @\n\n @state = new Luca.Model\n currentMode: \"coffeescript\"\n coffeescript:\"\"\n javascript:\"\"\n\n @state.bind \"change:coffeescript\", (model)->\n editor.trigger(\"change:coffeescript\")\n code = model.get(\"coffeescript\")\n\n editor.compile code, (compiled)->\n model.set('javascript',compiled)\n\n @state.bind \"change:javascript\", (model)->\n editor.onJavascriptChange?.call(editor, model.get('javascript') )\n\n @state.bind \"change:currentMode\", (model)->\n if model.get('currentMode') is \"javascript\"\n editor.setValue model.get('javascript')\n else \n editor.setValue model.get('coffeescript')\n\n compile: (code, callback)->\n response = {}\n code ||= @getValue()\n\n try\n compiled = CoffeeScript.compile(code, @compileOptions)\n callback?.call(@, compiled)\n response =\n success: true\n compiled: compiled\n catch error\n @trigger(\"compile:error\", error, code)\n\n response =\n success: false\n compiled: ''\n message: error.message\n\n toggleMode: ()->\n if @currentMode() is \"coffeescript\"\n @state.set('currentMode', 'javascript')\n else if @currentMode() is \"javascript\"\n @state.set('currentMode', 'coffeescript')\n\n currentMode: ()->\n @state.get(\"currentMode\")\n\n getCoffeescript: ()->\n @state.get(\"coffeescript\")\n \n getJavascript: (recompile=false)->\n js = @state.get(\"javascript\")\n\n if recompile is true or js?.length is 0\n results = @compile( @getCoffeescript() ) \n js = results?.compiled\n\n js\n\n editorChange: ()->\n if @autoCompile is true\n @state.set( @currentMode(), @getValue() )\n"},{"className":"Luca.tools.CollectionInspector","file":"src/tools/collection_inspector.coffee","source":"_.def(\"Luca.tools.CollectionInspector\").extends(\"Luca.View\").with\n name: \"collection_inspector\"\n\n className: \"collection-inspector\"\n"},{"className":"Luca.collections.Components","file":"src/tools/collections/components.coffee","source":"_.def('Luca.collections.Components').extends('Luca.Collection').with\n\n cachedMethods: [\n \"namespaces\"\n \"classes\"\n \"roots\"\n \"views\"\n \"collections\"\n \"models\"\n ]\n\n cache_key: \"luca_components\"\n\n name: \"components\"\n\n initialize: ()->\n @model = Luca.models.Component\n Luca.Collection::initialize.apply(@, arguments)\n \n url: ()->\n \"/source-map.js\"\n\n collections: ()->\n @select (component)-> Luca.isCollectionPrototype( component.definition() )\n\n modelClasses: ()->\n @select (component)-> Luca.isModelPrototype( component.definition() )\n\n views: ()->\n @select (component)-> Luca.isViewPrototype( component.definition() )\n\n classes: ()->\n _.uniq( @pluck \"className\" )\n\n roots: ()->\n _.uniq( @invoke(\"root\") )\n\n namespaces: ()->\n _.uniq( @invoke(\"namespace\") )\n\n asTree: ()->\n classes = @classes()\n namespaces = @namespaces()\n roots = @roots()\n\n tree = _( roots ).inject (memo,root)->\n memo[ root ] ||= {}\n regexp = new RegExp(\"^#{ root }\")\n memo[root] = _( namespaces ).select (namespace)->\n regexp.exec(namespace) and _( namespaces ).include(namespace) and namespace.split('.').length is 2\n memo\n , {}\n\n _( tree ).inject (memo, namespaces, root)->\n memo[root] = {}\n _( namespaces ).each (namespace)->\n memo[root][namespace] = {}\n memo\n , {}"},{"className":"MyComponent","file":"src/tools/component_tester.coffee","source":"# TODO\n#\n# Developed this component for use with the component tester.\n#\n# The editor which compiles coffeescript code should be extracted into a separate component\n# and all of the buffers / specifics etc should be moved into a more specific component for\n# this purpose\n\ndefaults = {}\n\ndefaults.setup = \"\"\"\n# the setup tab contains code which is run every time\n# prior to the 'implementation' run\n\"\"\"\n\ndefaults.component = \"\"\"\n# the component tab is where you handle the definition of the component\n# that you are trying to test. it will render its output into the\n# output panel of the code tester\n#\n# example definition:\n#\n# _.def('MyComponent').extends('Luca.View').with\n# bodyTemplate: 'sample/welcome'\n\"\"\"\n\ndefaults.teardown = \"\"\"\n# the teardown tab is where you undo / cleanup any of the operations\n# from setup / implementation\n\"\"\"\n\ndefaults.implementation = \"\"\"\n# the implementation tab is where you specify options for your component.\n#\n# NOTE: the component tester uses whatever is returned from evalulating\n# the code in this tab. if it responds to render(), it will append\n# render().el to the output panel. if it is an object, then we will attempt\n# to create an instance of the component you defined with the object as\n\"\"\"\n\ndefaults.style = \"\"\"\n/*\n * customize the styles that effect this component\n * note, all styles here will be scoped to only effect\n * the output panel :)\n*/\n\"\"\"\n\ndefaults.html = \"\"\n\nbufferNames = [\"setup\",\"implementation\",\"component\",\"style\",\"html\"]\ncompiledBuffers = [\"setup\",\"implementation\",\"component\"]\n\nComponentPicker = Luca.fields.TypeAheadField.extend\n name: \"component_picker\"\n\n label: \"Choose a component to edit\"\n\n initialize: ()->\n @collection = new Luca.collections.Components()\n @collection.fetch()\n\n @_super(\"initialize\", @, arguments)\n\n getSource: ()->\n @collection.classes()\n\n change_handler: ()->\n componentDefinition = @getValue()\n\n component = @collection.find (model)->\n model.get(\"className\") is componentDefinition\n\n component.fetch success: (model, response)=>\n if response?.source.length > 0\n @trigger \"component:fetched\", response.source, response.className\n\n @hide()\n\n createWrapper: ()->\n @make \"div\",\n class: \"component-picker span4 well\"\n style:\n \"position: absolute; z-index:12000\"\n\n show: ()->\n @$el.parent().show()\n\n hide: ()->\n @$el.parent().hide()\n\n toggle: ()->\n @$el.parent().toggle()\n\n\n\n_.def(\"Luca.tools.ComponentTester\").extends(\"Luca.core.Container\").with\n id: \"component_tester\"\n name: \"component_tester\"\n\n autoEvaluateCode: true\n\n currentSize: 1\n\n sizes:[\n icon: \"resize-full\"\n value: ()-> $(window).height() * 0.3\n ,\n icon: \"resize-small\"\n value: ()-> $(window).height() * 0.6\n ]\n \n components:[\n ctype: 'card_view'\n name: \"component_detail\"\n activeCard: 0\n components:[\n ctype: 'panel'\n name: \"component_tester_output\"\n bodyTemplate: \"component_tester/help\"\n ]\n ,\n ctype: \"code_editor\"\n name: \"ctester_edit\"\n className: 'font-large fixed-height'\n minHeight:'350px'\n\n currentBuffers: defaults\n\n compiledBuffers:[\"component\",\"setup\",\"implementation\"]\n\n topToolbar:\n buttons:[\n icon: \"resize-full\"\n align: \"right\"\n description: \"change the size of the component tester editor\"\n eventId: \"toggle:size\"\n ,\n icon: \"pause\"\n align: \"right\"\n description: \"Toggle auto-evaluation of test script on code change\"\n eventId: \"click:autoeval\"\n ,\n icon: \"plus\"\n description: \"add a new component to test\"\n eventId: \"click:add\"\n ,\n icon: \"folder-open\"\n description: \"open an existing component's definition\"\n eventId: \"click:open\"\n ]\n\n bottomToolbar:\n buttons:[\n group: true\n wrapper: \"span4\"\n buttons:[\n label: \"View Javascript\"\n description: \"Switch between compiled JS and Coffeescript\"\n eventId: \"toggle:mode\"\n ]\n ,\n group: true\n wrapper: \"span6 offset4\"\n buttons:[\n label: \"Component\"\n eventId: \"edit:component\"\n description: \"Edit the component itself\"\n ,\n label: \"Setup\"\n eventId: \"edit:setup\"\n description: \"Edit the setup for your component test\"\n ,\n label: \"Implementation\"\n eventId: \"edit:implementation\"\n description: \"Implement your component\"\n ,\n label: \"Markup\",\n eventId: \"edit:markup\"\n description: \"Edit the HTML produced by the component\"\n ,\n label: \"CSS\"\n eventId: \"edit:style\"\n description: \"Edit CSS\"\n ]\n ,\n group: true\n align: \"right\"\n buttons:[\n icon:\"question-sign\"\n align: \"right\"\n eventId: \"click:help\"\n description: \"Help\"\n ,\n icon: \"cog\"\n align: 'right'\n eventId: \"click:settings\"\n description : \"component tester settings\"\n ,\n icon: \"eye-close\"\n align: \"right\"\n eventId: \"click:hide\"\n description: \"hide the tester controls\"\n ,\n icon: \"heart\"\n eventId: \"click:console\"\n description: \"Coffeescript Console\"\n align: \"right\"\n ]\n ]\n ]\n\n debugMode: true\n\n componentEvents:\n \"ctester_edit click:autoeval\" : \"toggleAutoeval\"\n \"ctester_edit click:refresh\" : \"refreshCode\"\n \"ctester_edit click:hide\" : \"toggleControls\"\n \"ctester_edit click:settings\" : \"toggleSettings\"\n \"ctester_edit click:add\" : \"addComponent\"\n \"ctester_edit click:open\" : \"openComponent\"\n \"ctester_edit click:help\" : \"showHelp\"\n \"ctester_edit click:console\" : \"toggleConsole\"\n \"ctester_edit eval:error\" : \"onError\"\n \"ctester_edit eval:success\" : \"onSuccess\"\n \"ctester_edit edit:setup\" : \"editSetup\"\n \"ctester_edit edit:teardown\" : \"editTeardown\"\n \"ctester_edit edit:component\" : \"editComponent\"\n \"ctester_edit edit:style\" : \"editStyle\"\n \"ctester_edit edit:markup\" : \"editMarkup\"\n \"ctester_edit edit:implementation\" : \"editImplementation\"\n \"ctester_edit toggle:keymap\" : \"toggleKeymap\"\n \"ctester_edit toggle:mode\" : \"toggleMode\"\n \"ctester_edit code:change:html\" : \"onMarkupChange\"\n \"ctester_edit code:change:style\" : \"onStyleChange\"\n \"ctester_edit toggle:size\" : \"toggleSize\"\n\n\n initialize: ()->\n Luca.core.Container::initialize.apply(@, arguments)\n\n for key, value of @componentEvents\n @[ value ] = _.bind(@[value], @)\n\n @defer(\"editComponent\").until(\"after:render\")\n\n afterRender: ()->\n changeHandler = _.idleMedium ()=>\n if @autoEvaluateCode is true\n @applyTestRun()\n , 500\n\n @getEditor().bind \"code:change\", changeHandler\n\n getEditor: ()->\n Luca(\"ctester_edit\")\n\n getDetail: ()->\n Luca(\"component_detail\")\n\n getOutput: ()->\n @getDetail().findComponentByName(\"component_tester_output\")\n\n onError: (error, bufferId)->\n console.log \"Error in #{ bufferId }\", error, error.message, error.stack\n\n onSuccess: (result, bufferId)->\n if bufferId is \"component\"\n @componentDefinition = result\n\n if bufferId is \"implementation\"\n if Luca.isBackboneView(result)\n object = result\n else if _.isObject(result) and result.ctype?\n object = Luca(result)\n else if _.isObject(result) and _.isFunction(@componentDefinition)\n object = ( new @componentDefinition(result) )\n\n if Luca.isBackboneView(object)\n @getOutput().$html( object.render().el )\n\n applyTestRun: ()->\n @getOutput().$html('')\n\n for bufferId, code of @getTestRun()\n @evaluateCode(code, bufferId)\n\n toggleConsole: (button)->\n @developmentConsole = Luca \"coffeescript-console\", ()-> new Luca.tools.DevelopmentConsole(name:\"coffeescript-console\")\n\n unless @consoleContainerAppended\n container = @make(\"div\",{id:\"devtools-console-wrapper\",class:\"devtools-console-container modal\",style:\"width:900px;height:650px;\"}, @developmentConsole.el)\n $('body').append( container )\n @consoleContainerAppended = true\n @developmentConsole.render()\n\n $('#devtools-console-wrapper').modal(backdrop:false,show:true)\n\n toggleAutoeval: (button)->\n @autoEvaluateCode = !(@autoEvaluateCode is true)\n\n if not @started and @autoEvaluateCode is true\n @started = true\n @applyTestRun()\n\n iconHolder = button.children('i').eq(0)\n buttonClass = if @autoEvaluateCode then \"icon-pause\" else \"icon-play\"\n iconHolder.removeClass()\n iconHolder.addClass(buttonClass)\n\n @\n\n showEditor: (options)->\n @getEditor().$('.toolbar-container.top').toggle(options)\n @getEditor().$('.codemirror-wrapper').toggle(options)\n @trigger \"controls:toggled\"\n\n toggleKeymap: (button)->\n newMode = if @getEditor().keyMap is \"vim\" then \"basic\" else \"vim\"\n @getEditor().setKeyMap(newMode)\n button.html( _.string.capitalize(newMode) )\n\n toggleMode: (button)->\n newMode = if @getEditor().mode is \"coffeescript\" then \"javascript\" else \"coffeescript\"\n @getEditor().setMode(newMode)\n button.html _.string.capitalize((if newMode is \"coffeescript\" then \"View Javascript\" else \"View Coffeescript\"))\n @editBuffer @currentBufferName, (newMode is \"javascript\")\n\n\n\n\n toggleSize: (button)->\n index = @currentSize++ % @sizes.length\n newSize = @sizes[ index ].value()\n newIcon = @sizes[ index ].icon\n\n if button?\n iconHolder = button.children('i').eq(0)\n iconHolder.removeClass().addClass(\"icon-#{ newIcon }\")\n\n @$('.codemirror-wrapper').css('height', \"#{ parseInt(newSize) }px\")\n @getEditor().refresh()\n\n toggleControls: (button)->\n @bind \"controls:toggled\", ()=>\n iconHolder = button.children('i').eq(0)\n iconHolder.removeClass()\n\n buttonClass = if @getEditor().$('.toolbar-container.top').is(\":visible\") then \"icon-eye-close\" else \"icon-eye-open\"\n iconHolder.addClass(buttonClass)\n\n @showEditor()\n\n @\n\n toggleSettings: ()->\n @\n\n setValue: (value, buffer=\"component\")->\n compiled = @getEditor().editor.getOption('mode') is \"javascript\"\n @editBuffer(buffer, compiled, false).getEditor().setValue( value )\n\n editBuffer: (@currentBufferName, compiled=false, autoSave=true)->\n @showEditor(true)\n @highlight(@currentBufferName)\n\n buffer = if compiled then \"compiled_#{ @currentBufferName }\" else @currentBufferName\n @getEditor().loadBuffer(buffer,autoSave)\n @\n\n editMarkup: ()->\n @getEditor().setMode('htmlmixed')\n @getEditor().setWrap(true)\n @editBuffer(\"html\").setValue(@getOutput().$html(), 'html')\n\n editStyle: ()->\n @getEditor().setMode('css')\n @editBuffer(\"style\")\n\n editComponent: ()->\n @getEditor().setMode('coffeescript')\n @editBuffer(\"component\")\n\n editTeardown: ()->\n @getEditor().setMode('coffeescript')\n @editBuffer(\"teardown\")\n\n editSetup: ()->\n @getEditor().setMode('coffeescript')\n @editBuffer(\"setup\")\n\n editImplementation: ()->\n @getEditor().setMode('coffeescript')\n @editBuffer(\"implementation\")\n\n getTestRun: ()->\n editor = @getEditor()\n\n testRun = {}\n\n for buffer in [\"component\",\"setup\",\"implementation\"]\n testRun[buffer] = editor.getBuffer(buffer, true)\n\n testRun\n\n getContext: ()->\n Luca.util.resolve(@context||=\"window\")\n\n evaluateCode: (code, bufferId, compile=false)->\n code ||= @getEditor().getValue()\n compiled = if compile is true then @getEditor().compileCode(code) else code\n\n evaluator = ()-> eval( compiled )\n\n try\n result = evaluator.call( @getContext() )\n @onSuccess(result, bufferId, code)\n catch error\n @onError( error, bufferId, code)\n\n onMarkupChange: ()->\n if @autoEvaluateCode is true\n @getOutput().$html @getEditor().getValue()\n\n onStyleChange: ()->\n if @autoEvaluateCode is true\n $('#component-tester-stylesheet').remove()\n\n style = @getEditor()?.getValue()\n\n if style\n styleTag = @make \"style\", type:\"text/css\", id: \"component-tester-stylesheet\"\n $('head').append( styleTag )\n $(styleTag).append(style)\n\n showHelp: ()->\n @getOutput().$html( Luca.template(\"component_tester/help\",@) )\n\n addComponent: (button)->\n\n openComponent: (button)->\n @componentPicker ||= new ComponentPicker()\n\n @componentPicker.bind \"component:fetched\", (source, component)=>\n @setEditorNamespace(component).setValue( source, \"component\")\n\n if !@getEditor().$('.component-picker').length > 0\n @getEditor().$('.codemirror-wrapper').before(@componentPicker.createWrapper())\n @getEditor().$('.component-picker').html( @componentPicker.render().el )\n @componentPicker.show()\n return\n\n @componentPicker.toggle()\n\n highlight: (section)->\n @$(\"a.btn[data-eventid='edit:#{ section }']\").siblings().css('font-weight','normal')\n @$(\"a.btn[data-eventid='edit:#{ section }']\").css('font-weight','bold')\n\n setEditorNamespace: (namespace)->\n @getEditor().namespace( namespace )\n @getEditor().buffers.fetch()\n @"},{"className":"Luca.tools.ComponentTester","file":"src/tools/component_tester.coffee","source":"# TODO\n#\n# Developed this component for use with the component tester.\n#\n# The editor which compiles coffeescript code should be extracted into a separate component\n# and all of the buffers / specifics etc should be moved into a more specific component for\n# this purpose\n\ndefaults = {}\n\ndefaults.setup = \"\"\"\n# the setup tab contains code which is run every time\n# prior to the 'implementation' run\n\"\"\"\n\ndefaults.component = \"\"\"\n# the component tab is where you handle the definition of the component\n# that you are trying to test. it will render its output into the\n# output panel of the code tester\n#\n# example definition:\n#\n# _.def('MyComponent').extends('Luca.View').with\n# bodyTemplate: 'sample/welcome'\n\"\"\"\n\ndefaults.teardown = \"\"\"\n# the teardown tab is where you undo / cleanup any of the operations\n# from setup / implementation\n\"\"\"\n\ndefaults.implementation = \"\"\"\n# the implementation tab is where you specify options for your component.\n#\n# NOTE: the component tester uses whatever is returned from evalulating\n# the code in this tab. if it responds to render(), it will append\n# render().el to the output panel. if it is an object, then we will attempt\n# to create an instance of the component you defined with the object as\n\"\"\"\n\ndefaults.style = \"\"\"\n/*\n * customize the styles that effect this component\n * note, all styles here will be scoped to only effect\n * the output panel :)\n*/\n\"\"\"\n\ndefaults.html = \"\"\n\nbufferNames = [\"setup\",\"implementation\",\"component\",\"style\",\"html\"]\ncompiledBuffers = [\"setup\",\"implementation\",\"component\"]\n\nComponentPicker = Luca.fields.TypeAheadField.extend\n name: \"component_picker\"\n\n label: \"Choose a component to edit\"\n\n initialize: ()->\n @collection = new Luca.collections.Components()\n @collection.fetch()\n\n @_super(\"initialize\", @, arguments)\n\n getSource: ()->\n @collection.classes()\n\n change_handler: ()->\n componentDefinition = @getValue()\n\n component = @collection.find (model)->\n model.get(\"className\") is componentDefinition\n\n component.fetch success: (model, response)=>\n if response?.source.length > 0\n @trigger \"component:fetched\", response.source, response.className\n\n @hide()\n\n createWrapper: ()->\n @make \"div\",\n class: \"component-picker span4 well\"\n style:\n \"position: absolute; z-index:12000\"\n\n show: ()->\n @$el.parent().show()\n\n hide: ()->\n @$el.parent().hide()\n\n toggle: ()->\n @$el.parent().toggle()\n\n\n\n_.def(\"Luca.tools.ComponentTester\").extends(\"Luca.core.Container\").with\n id: \"component_tester\"\n name: \"component_tester\"\n\n autoEvaluateCode: true\n\n currentSize: 1\n\n sizes:[\n icon: \"resize-full\"\n value: ()-> $(window).height() * 0.3\n ,\n icon: \"resize-small\"\n value: ()-> $(window).height() * 0.6\n ]\n \n components:[\n ctype: 'card_view'\n name: \"component_detail\"\n activeCard: 0\n components:[\n ctype: 'panel'\n name: \"component_tester_output\"\n bodyTemplate: \"component_tester/help\"\n ]\n ,\n ctype: \"code_editor\"\n name: \"ctester_edit\"\n className: 'font-large fixed-height'\n minHeight:'350px'\n\n currentBuffers: defaults\n\n compiledBuffers:[\"component\",\"setup\",\"implementation\"]\n\n topToolbar:\n buttons:[\n icon: \"resize-full\"\n align: \"right\"\n description: \"change the size of the component tester editor\"\n eventId: \"toggle:size\"\n ,\n icon: \"pause\"\n align: \"right\"\n description: \"Toggle auto-evaluation of test script on code change\"\n eventId: \"click:autoeval\"\n ,\n icon: \"plus\"\n description: \"add a new component to test\"\n eventId: \"click:add\"\n ,\n icon: \"folder-open\"\n description: \"open an existing component's definition\"\n eventId: \"click:open\"\n ]\n\n bottomToolbar:\n buttons:[\n group: true\n wrapper: \"span4\"\n buttons:[\n label: \"View Javascript\"\n description: \"Switch between compiled JS and Coffeescript\"\n eventId: \"toggle:mode\"\n ]\n ,\n group: true\n wrapper: \"span6 offset4\"\n buttons:[\n label: \"Component\"\n eventId: \"edit:component\"\n description: \"Edit the component itself\"\n ,\n label: \"Setup\"\n eventId: \"edit:setup\"\n description: \"Edit the setup for your component test\"\n ,\n label: \"Implementation\"\n eventId: \"edit:implementation\"\n description: \"Implement your component\"\n ,\n label: \"Markup\",\n eventId: \"edit:markup\"\n description: \"Edit the HTML produced by the component\"\n ,\n label: \"CSS\"\n eventId: \"edit:style\"\n description: \"Edit CSS\"\n ]\n ,\n group: true\n align: \"right\"\n buttons:[\n icon:\"question-sign\"\n align: \"right\"\n eventId: \"click:help\"\n description: \"Help\"\n ,\n icon: \"cog\"\n align: 'right'\n eventId: \"click:settings\"\n description : \"component tester settings\"\n ,\n icon: \"eye-close\"\n align: \"right\"\n eventId: \"click:hide\"\n description: \"hide the tester controls\"\n ,\n icon: \"heart\"\n eventId: \"click:console\"\n description: \"Coffeescript Console\"\n align: \"right\"\n ]\n ]\n ]\n\n debugMode: true\n\n componentEvents:\n \"ctester_edit click:autoeval\" : \"toggleAutoeval\"\n \"ctester_edit click:refresh\" : \"refreshCode\"\n \"ctester_edit click:hide\" : \"toggleControls\"\n \"ctester_edit click:settings\" : \"toggleSettings\"\n \"ctester_edit click:add\" : \"addComponent\"\n \"ctester_edit click:open\" : \"openComponent\"\n \"ctester_edit click:help\" : \"showHelp\"\n \"ctester_edit click:console\" : \"toggleConsole\"\n \"ctester_edit eval:error\" : \"onError\"\n \"ctester_edit eval:success\" : \"onSuccess\"\n \"ctester_edit edit:setup\" : \"editSetup\"\n \"ctester_edit edit:teardown\" : \"editTeardown\"\n \"ctester_edit edit:component\" : \"editComponent\"\n \"ctester_edit edit:style\" : \"editStyle\"\n \"ctester_edit edit:markup\" : \"editMarkup\"\n \"ctester_edit edit:implementation\" : \"editImplementation\"\n \"ctester_edit toggle:keymap\" : \"toggleKeymap\"\n \"ctester_edit toggle:mode\" : \"toggleMode\"\n \"ctester_edit code:change:html\" : \"onMarkupChange\"\n \"ctester_edit code:change:style\" : \"onStyleChange\"\n \"ctester_edit toggle:size\" : \"toggleSize\"\n\n\n initialize: ()->\n Luca.core.Container::initialize.apply(@, arguments)\n\n for key, value of @componentEvents\n @[ value ] = _.bind(@[value], @)\n\n @defer(\"editComponent\").until(\"after:render\")\n\n afterRender: ()->\n changeHandler = _.idleMedium ()=>\n if @autoEvaluateCode is true\n @applyTestRun()\n , 500\n\n @getEditor().bind \"code:change\", changeHandler\n\n getEditor: ()->\n Luca(\"ctester_edit\")\n\n getDetail: ()->\n Luca(\"component_detail\")\n\n getOutput: ()->\n @getDetail().findComponentByName(\"component_tester_output\")\n\n onError: (error, bufferId)->\n console.log \"Error in #{ bufferId }\", error, error.message, error.stack\n\n onSuccess: (result, bufferId)->\n if bufferId is \"component\"\n @componentDefinition = result\n\n if bufferId is \"implementation\"\n if Luca.isBackboneView(result)\n object = result\n else if _.isObject(result) and result.ctype?\n object = Luca(result)\n else if _.isObject(result) and _.isFunction(@componentDefinition)\n object = ( new @componentDefinition(result) )\n\n if Luca.isBackboneView(object)\n @getOutput().$html( object.render().el )\n\n applyTestRun: ()->\n @getOutput().$html('')\n\n for bufferId, code of @getTestRun()\n @evaluateCode(code, bufferId)\n\n toggleConsole: (button)->\n @developmentConsole = Luca \"coffeescript-console\", ()-> new Luca.tools.DevelopmentConsole(name:\"coffeescript-console\")\n\n unless @consoleContainerAppended\n container = @make(\"div\",{id:\"devtools-console-wrapper\",class:\"devtools-console-container modal\",style:\"width:900px;height:650px;\"}, @developmentConsole.el)\n $('body').append( container )\n @consoleContainerAppended = true\n @developmentConsole.render()\n\n $('#devtools-console-wrapper').modal(backdrop:false,show:true)\n\n toggleAutoeval: (button)->\n @autoEvaluateCode = !(@autoEvaluateCode is true)\n\n if not @started and @autoEvaluateCode is true\n @started = true\n @applyTestRun()\n\n iconHolder = button.children('i').eq(0)\n buttonClass = if @autoEvaluateCode then \"icon-pause\" else \"icon-play\"\n iconHolder.removeClass()\n iconHolder.addClass(buttonClass)\n\n @\n\n showEditor: (options)->\n @getEditor().$('.toolbar-container.top').toggle(options)\n @getEditor().$('.codemirror-wrapper').toggle(options)\n @trigger \"controls:toggled\"\n\n toggleKeymap: (button)->\n newMode = if @getEditor().keyMap is \"vim\" then \"basic\" else \"vim\"\n @getEditor().setKeyMap(newMode)\n button.html( _.string.capitalize(newMode) )\n\n toggleMode: (button)->\n newMode = if @getEditor().mode is \"coffeescript\" then \"javascript\" else \"coffeescript\"\n @getEditor().setMode(newMode)\n button.html _.string.capitalize((if newMode is \"coffeescript\" then \"View Javascript\" else \"View Coffeescript\"))\n @editBuffer @currentBufferName, (newMode is \"javascript\")\n\n\n\n\n toggleSize: (button)->\n index = @currentSize++ % @sizes.length\n newSize = @sizes[ index ].value()\n newIcon = @sizes[ index ].icon\n\n if button?\n iconHolder = button.children('i').eq(0)\n iconHolder.removeClass().addClass(\"icon-#{ newIcon }\")\n\n @$('.codemirror-wrapper').css('height', \"#{ parseInt(newSize) }px\")\n @getEditor().refresh()\n\n toggleControls: (button)->\n @bind \"controls:toggled\", ()=>\n iconHolder = button.children('i').eq(0)\n iconHolder.removeClass()\n\n buttonClass = if @getEditor().$('.toolbar-container.top').is(\":visible\") then \"icon-eye-close\" else \"icon-eye-open\"\n iconHolder.addClass(buttonClass)\n\n @showEditor()\n\n @\n\n toggleSettings: ()->\n @\n\n setValue: (value, buffer=\"component\")->\n compiled = @getEditor().editor.getOption('mode') is \"javascript\"\n @editBuffer(buffer, compiled, false).getEditor().setValue( value )\n\n editBuffer: (@currentBufferName, compiled=false, autoSave=true)->\n @showEditor(true)\n @highlight(@currentBufferName)\n\n buffer = if compiled then \"compiled_#{ @currentBufferName }\" else @currentBufferName\n @getEditor().loadBuffer(buffer,autoSave)\n @\n\n editMarkup: ()->\n @getEditor().setMode('htmlmixed')\n @getEditor().setWrap(true)\n @editBuffer(\"html\").setValue(@getOutput().$html(), 'html')\n\n editStyle: ()->\n @getEditor().setMode('css')\n @editBuffer(\"style\")\n\n editComponent: ()->\n @getEditor().setMode('coffeescript')\n @editBuffer(\"component\")\n\n editTeardown: ()->\n @getEditor().setMode('coffeescript')\n @editBuffer(\"teardown\")\n\n editSetup: ()->\n @getEditor().setMode('coffeescript')\n @editBuffer(\"setup\")\n\n editImplementation: ()->\n @getEditor().setMode('coffeescript')\n @editBuffer(\"implementation\")\n\n getTestRun: ()->\n editor = @getEditor()\n\n testRun = {}\n\n for buffer in [\"component\",\"setup\",\"implementation\"]\n testRun[buffer] = editor.getBuffer(buffer, true)\n\n testRun\n\n getContext: ()->\n Luca.util.resolve(@context||=\"window\")\n\n evaluateCode: (code, bufferId, compile=false)->\n code ||= @getEditor().getValue()\n compiled = if compile is true then @getEditor().compileCode(code) else code\n\n evaluator = ()-> eval( compiled )\n\n try\n result = evaluator.call( @getContext() )\n @onSuccess(result, bufferId, code)\n catch error\n @onError( error, bufferId, code)\n\n onMarkupChange: ()->\n if @autoEvaluateCode is true\n @getOutput().$html @getEditor().getValue()\n\n onStyleChange: ()->\n if @autoEvaluateCode is true\n $('#component-tester-stylesheet').remove()\n\n style = @getEditor()?.getValue()\n\n if style\n styleTag = @make \"style\", type:\"text/css\", id: \"component-tester-stylesheet\"\n $('head').append( styleTag )\n $(styleTag).append(style)\n\n showHelp: ()->\n @getOutput().$html( Luca.template(\"component_tester/help\",@) )\n\n addComponent: (button)->\n\n openComponent: (button)->\n @componentPicker ||= new ComponentPicker()\n\n @componentPicker.bind \"component:fetched\", (source, component)=>\n @setEditorNamespace(component).setValue( source, \"component\")\n\n if !@getEditor().$('.component-picker').length > 0\n @getEditor().$('.codemirror-wrapper').before(@componentPicker.createWrapper())\n @getEditor().$('.component-picker').html( @componentPicker.render().el )\n @componentPicker.show()\n return\n\n @componentPicker.toggle()\n\n highlight: (section)->\n @$(\"a.btn[data-eventid='edit:#{ section }']\").siblings().css('font-weight','normal')\n @$(\"a.btn[data-eventid='edit:#{ section }']\").css('font-weight','bold')\n\n setEditorNamespace: (namespace)->\n @getEditor().namespace( namespace )\n @getEditor().buffers.fetch()\n @"},{"className":"Luca.models.Component","file":"src/tools/models/components.coffee","source":"_.def(\"Luca.models.Component\").extends(\"Luca.Model\").with\n root: ()->\n @get(\"className\").split('.')[0]\n\n className: ()->\n @get(\"className\")\n\n instances: ()->\n Luca.registry.findInstancesByClassName @className()\n\n definitionPrototype: ()->\n @definition()?.prototype \n\n parentClasses: ()->\n Luca.parentClasses( @className() ) \n\n definition: ()->\n Luca.util.resolve @className()\n\n namespace: ()->\n return \"\" unless @get(\"className\")?\n\n parts = @get(\"className\").split('.')\n parts.pop()\n parts.join \".\"\n"},{"className":"Sandbox.Application","file":"assets/javascripts/sandbox/application.coffee","source":"_.def('Sandbox.Application').extends('Luca.Application').with\n\n autoBoot: true\n\n name: 'SandboxApp'\n\n router: \"Sandbox.Router\"\n\n el: '#viewport'\n\n fluid: true\n\n topNav:'top_navigation'\n\n useKeyHandler: true\n\n keyEvents:\n meta:\n forwardslash: \"developmentConsole\"\n\n collectionManager:\n initialCollections: [\"components\"]\n\n components:[\n ctype: 'controller'\n name: 'pages'\n components:[\n name: \"main\"\n className:\"marketing-content\"\n bodyTemplate: 'main'\n ,\n name: \"intro\"\n className:\"marketing-content\"\n bodyTemplate: \"readme\"\n ,\n name: \"build\"\n ctype: \"builder\"\n ]\n ]\n\n developmentConsole: ()->\n @developmentConsole = Luca \"coffeescript-console\", ()->\n new Luca.tools.DevelopmentConsole(name:\"coffeescript-console\")\n\n unless @consoleContainerAppended\n container = @make(\"div\",{id:\"devtools-console-wrapper\",class:\"devtools-console-container modal\",style:\"width:1000px\"}, @developmentConsole.el)\n $('body').append( container )\n @consoleContainerAppended = true\n @developmentConsole.render()\n\n $('#devtools-console-wrapper').modal(backdrop:false,show:true)\n\n$ -> \n new Sandbox.Application()"},{"className":"Sandbox.views.BuilderCanvas","file":"assets/javascripts/sandbox/views/builder/builder_canvas.coffee","source":"_.def(\"Sandbox.views.BuilderCanvas\").extends(\"Luca.View\").with\n name: \"builder_canvas\"\n bodyTemplate: \"builder\""},{"className":"Sandbox.views.BuilderEditor","file":"assets/javascripts/sandbox/views/builder/builder_editor.coffee","source":"_.def(\"Sandbox.views.BuilderEditor\").extends(\"Luca.tools.CoffeeEditor\").with\n name: \"builder_editor\"\n\n bottomToolbar:\n buttons:[\n eventId:\"toggle:source\"\n label:\"mode: coffeescript\"\n ]\n\n toggleSource:()->\n @_super(\"toggleMode\", @, arguments)\n @updateToggleSourceButton()\n\n updateToggleSourceButton: ()->\n @$('[data-eventid=\"toggle:source\"]').html(\"mode: #{ @currentMode() }\")\n"},{"className":"Sandbox.views.ComponentList","file":"assets/javascripts/sandbox/views/builder/component_list.coffee","source":"_.def(\"Sandbox.views.ComponentList\").extends(\"Luca.components.CollectionView\").with\n name: \"component_list\"\n id: \"component_list\"\n className:\"span3\"\n collection:\"components\"\n itemTagName:\"div\"\n itemRenderer: (item, model, index)->\n Luca.util.make(\"a\",{\"data-index\":index}, model.className() )\n\n autoBindEventHandlers: true\n\n events:\n \"click div.collection-item a\" : \"clickHandler\"\n\n clickHandler: (e)->\n e.preventDefault()\n me = my = $( e.target )\n component = @collection.at( my.data('index') )\n @trigger \"selected\", component"},{"className":"Sandbox.views.Builder","file":"assets/javascripts/sandbox/views/builder.coffee","source":"_.def(\"Sandbox.views.Builder\").extends(\"Luca.core.Container\").with\n name: \"builder\"\n id: \"builder\"\n components:[\n ctype: \"builder_canvas\"\n className: \"builder-canvas\"\n ,\n ctype: \"container\"\n name:\"editor_container\"\n bodyClassName:\"row-fluid\" \n\n topToolbar:\n buttons:[\n align:\"left\"\n label:\"View\"\n dropdown:[\n [\"toggle:all\",\"All\"]\n [\"toggle:collections\",\"Collections\"]\n [\"toggle:models\",\"Models\"]\n [\"toggle:views\",\"Views\"],\n ]\n ]\n\n componentEvents:\n \"component_list selected\" : \"onComponentSelection\"\n\n components:[\n ctype:\"component_list\"\n name: \"component_list\"\n className:\"span3\"\n beforeRender: ()->\n @collection.fetch()\n ,\n ctype: \"builder_editor\" \n className:\"span9 builder-editor-container\"\n styles:\n \"margin-left\":\"0px\"\n \"width\":\"76%\"\n ]\n\n onComponentSelection: (component)->\n Luca(\"builder_editor\").setValue( component.get('source') )\n Luca(\"builder_editor\").state.set('currentMode','coffeescript')\n Luca(\"builder_editor\").updateToggleSourceButton()\n ]\n\n\n initialize: (@options={})->\n Luca.core.Container::initialize.apply(@, arguments)\n\n @state = new Backbone.Model\n canvasLayout: \"horizontal-split\" \n\n @state.bind \"change:canvasLayout\", ()=>\n @$el.removeClass().addClass @state.get(\"canvasLayout\")\n\n canvas: ()-> Luca(\"builder_canvas\")\n editor: ()-> Luca(\"builder_editor\")\n componentList: ()-> Luca(\"component_list\")\n\n fitToScreen: ()->\n viewportHeight = $(window).height()\n half = viewportHeight * 0.5\n toolbarHeight = 0\n toolbarHeight += @$('.toolbar-container.top').height() * @$('.toolbar-container.top').length\n\n @canvas().$el.height( half - toolbarHeight - 40 )\n\n @componentList().$el.height( half )\n @editor().$el.height( half )\n @editor().setHeight( half - 50 )\n\n activation: ()->\n @fitToScreen()\n\n deactivation: ()->\n\n beforeRender: ()->\n Luca.core.Container::beforeRender?.apply(@, arguments)\n @$el.removeClass().addClass @state.get(\"canvasLayout\")\n\n"},{"className":"Sandbox.views.TopNavigation","file":"assets/javascripts/sandbox/views/top_navigation.coffee","source":"_.def(\"Sandbox.views.TopNavigation\").extends(\"Luca.components.NavBar\").with\n brand: \"Luca\"\n name: \"top_navigation\"\n template: \"sandbox/navigation\""}]