cartilage 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.markdown +57 -0
  3. data/Rakefile +84 -0
  4. data/app/assets/images/cartilage/patterns/background.dark.png +0 -0
  5. data/app/assets/images/cartilage/patterns/background.dark.psd +0 -0
  6. data/app/assets/images/cartilage/patterns/background.light.png +0 -0
  7. data/app/assets/images/cartilage/patterns/background.light.psd +0 -0
  8. data/app/assets/images/cartilage/patterns/background.medium.png +0 -0
  9. data/app/assets/images/cartilage/patterns/background.medium.psd +0 -0
  10. data/app/assets/images/cartilage/patterns/background.png +0 -0
  11. data/app/assets/images/cartilage/patterns/background.psd +0 -0
  12. data/app/assets/javascripts/cartilage/application.js.coffee +45 -0
  13. data/app/assets/javascripts/cartilage/collections/segments.js.coffee +4 -0
  14. data/app/assets/javascripts/cartilage/core.js.coffee +8 -0
  15. data/app/assets/javascripts/cartilage/models/model.js.coffee +2 -0
  16. data/app/assets/javascripts/cartilage/models/segment.js.coffee +2 -0
  17. data/app/assets/javascripts/cartilage/views/bar_segment_view.js.coffee +58 -0
  18. data/app/assets/javascripts/cartilage/views/bar_view.js.coffee +85 -0
  19. data/app/assets/javascripts/cartilage/views/content_view.js.coffee +16 -0
  20. data/app/assets/javascripts/cartilage/views/image_view.js.coffee +76 -0
  21. data/app/assets/javascripts/cartilage/views/list_view.js.coffee +515 -0
  22. data/app/assets/javascripts/cartilage/views/list_view_item.js.coffee +85 -0
  23. data/app/assets/javascripts/cartilage/views/loading_indicator_view.js.coffee +147 -0
  24. data/app/assets/javascripts/cartilage/views/matrix_view.js.coffee +253 -0
  25. data/app/assets/javascripts/cartilage/views/matrix_view_item.js.coffee +5 -0
  26. data/app/assets/javascripts/cartilage/views/modal_view.js.coffee +26 -0
  27. data/app/assets/javascripts/cartilage/views/popover_view.js.coffee +212 -0
  28. data/app/assets/javascripts/cartilage/views/source_list_view.js.coffee +69 -0
  29. data/app/assets/javascripts/cartilage/views/source_list_view_item.js.coffee +5 -0
  30. data/app/assets/javascripts/cartilage/views/split_view.js.coffee +175 -0
  31. data/app/assets/javascripts/cartilage/views/usage_bar_view.js.coffee +5 -0
  32. data/app/assets/javascripts/cartilage/views/view.js.coffee +232 -0
  33. data/app/assets/javascripts/cartilage.js.coffee +18 -0
  34. data/app/assets/javascripts/extensions/console.js.coffee +9 -0
  35. data/app/assets/javascripts/extensions/constructor_name.js.coffee +10 -0
  36. data/app/assets/javascripts/extensions/properties.js.coffee +45 -0
  37. data/app/assets/javascripts/extensions/underscore.js.coffee +71 -0
  38. data/app/assets/stylesheets/cartilage/core.css.scss +432 -0
  39. data/app/assets/stylesheets/cartilage/mixins.css.scss +19 -0
  40. data/app/assets/stylesheets/cartilage/responsive.css.scss +192 -0
  41. data/app/assets/stylesheets/cartilage/variables.css.scss +113 -0
  42. data/app/assets/stylesheets/cartilage/views/list_view.css.scss +41 -0
  43. data/app/assets/stylesheets/cartilage/views/list_view_item.css.scss +47 -0
  44. data/app/assets/stylesheets/cartilage/views/loading_indicator_view.css.scss +50 -0
  45. data/app/assets/stylesheets/cartilage/views/matrix_view.css.scss +87 -0
  46. data/app/assets/stylesheets/cartilage/views/popover_view.css.scss +124 -0
  47. data/app/assets/stylesheets/cartilage/views/segmented_view.css.scss +98 -0
  48. data/app/assets/stylesheets/cartilage/views/source_list_view.css.scss +65 -0
  49. data/app/assets/stylesheets/cartilage/views/split_view.css.scss +80 -0
  50. data/app/assets/stylesheets/cartilage/views/usage_bar_view.css.scss +101 -0
  51. data/app/assets/stylesheets/cartilage/views/view.css.scss +13 -0
  52. data/app/assets/stylesheets/cartilage.css.scss +5 -0
  53. data/lib/cartilage/engine.rb +14 -0
  54. data/lib/cartilage/version.rb +3 -0
  55. data/lib/cartilage.rb +5 -0
  56. data/lib/tasks/cartilage_tasks.rake +4 -0
  57. data/test/cartilage_test.rb +7 -0
  58. data/test/dummy/Rakefile +7 -0
  59. data/test/dummy/app/assets/javascripts/application.js +9 -0
  60. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  61. data/test/dummy/app/controllers/application_controller.rb +3 -0
  62. data/test/dummy/app/helpers/application_helper.rb +2 -0
  63. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  64. data/test/dummy/config/application.rb +45 -0
  65. data/test/dummy/config/boot.rb +10 -0
  66. data/test/dummy/config/database.yml +25 -0
  67. data/test/dummy/config/environment.rb +5 -0
  68. data/test/dummy/config/environments/development.rb +30 -0
  69. data/test/dummy/config/environments/production.rb +60 -0
  70. data/test/dummy/config/environments/test.rb +42 -0
  71. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  72. data/test/dummy/config/initializers/inflections.rb +10 -0
  73. data/test/dummy/config/initializers/mime_types.rb +5 -0
  74. data/test/dummy/config/initializers/secret_token.rb +7 -0
  75. data/test/dummy/config/initializers/session_store.rb +8 -0
  76. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  77. data/test/dummy/config/locales/en.yml +5 -0
  78. data/test/dummy/config/routes.rb +58 -0
  79. data/test/dummy/config.ru +4 -0
  80. data/test/dummy/db/readme +6 -0
  81. data/test/dummy/public/404.html +26 -0
  82. data/test/dummy/public/422.html +26 -0
  83. data/test/dummy/public/500.html +26 -0
  84. data/test/dummy/public/favicon.ico +0 -0
  85. data/test/dummy/script/rails +6 -0
  86. data/test/framework/cartilage/application_test.js.coffee +14 -0
  87. data/test/framework/cartilage/views/bar_segment_view_test.js.coffee +5 -0
  88. data/test/framework/cartilage/views/bar_view_test.js.coffee +30 -0
  89. data/test/framework/cartilage/views/image_view_test.js.coffee +27 -0
  90. data/test/framework/cartilage/views/list_view_item_test.js.coffee +17 -0
  91. data/test/framework/cartilage/views/list_view_test.js.coffee +190 -0
  92. data/test/framework/cartilage/views/loading_indicator_view_test.js.coffee +5 -0
  93. data/test/framework/cartilage/views/matrix_view_item_test.js.coffee +5 -0
  94. data/test/framework/cartilage/views/matrix_view_test.js.coffee +5 -0
  95. data/test/framework/cartilage/views/popover_view_test.js.coffee +5 -0
  96. data/test/framework/cartilage/views/source_list_view_item_test.js.coffee +5 -0
  97. data/test/framework/cartilage/views/source_list_view_test.js.coffee +5 -0
  98. data/test/framework/cartilage/views/split_view_test.js.coffee +5 -0
  99. data/test/framework/cartilage/views/usage_bar_view_test.js.coffee +5 -0
  100. data/test/framework/cartilage/views/view_test.js.coffee +85 -0
  101. data/test/framework/extensions/properties_test.js.coffee +82 -0
  102. data/test/framework/extensions/underscore_test.js.coffee +73 -0
  103. data/test/framework/index.html +72 -0
  104. data/test/framework/vendor/backbone.js +1431 -0
  105. data/test/framework/vendor/coffee-script.js +8 -0
  106. data/test/framework/vendor/jquery.js +9440 -0
  107. data/test/framework/vendor/phantomjs-runner.js +196 -0
  108. data/test/framework/vendor/qunit.css +235 -0
  109. data/test/framework/vendor/qunit.js +1977 -0
  110. data/test/framework/vendor/run-qunit.js +81 -0
  111. data/test/framework/vendor/sinon-1.5.0.js +4142 -0
  112. data/test/framework/vendor/sinon-qunit-1.0.0.js +62 -0
  113. data/test/framework/vendor/underscore.js +1059 -0
  114. data/test/test_helper.rb +10 -0
  115. metadata +373 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2010-2012 ActiveProspect, Inc
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,57 @@
1
+ # Cartilage for Backbone.js
2
+
3
+ [![Build Status](https://secure.travis-ci.org/Cartilage/cartilage.png)](http://travis-ci.org/Cartilage/cartilage)
4
+
5
+ Cartilage is a standardized set of layouts and user interface elements that
6
+ are bundled as a Rails Engine. It is build on top of Backbone.js (for
7
+ interactivity) and Bootstrap (for visual styling).
8
+
9
+ ## Example
10
+
11
+ An example project is available at http://github.com/Cartilage/cartilage-example which
12
+ is available as a demo here http://example.cartilagejs.org/
13
+ ## Requirements
14
+
15
+ * Ruby on Rails 3.2+
16
+ * Asset Pipeline
17
+ * jQuery
18
+
19
+ ## Usage
20
+
21
+ Include the Cartilage library in your project by adding the following to your
22
+ Gemfile:
23
+
24
+ gem 'cartilage', :git => 'git@github.com:Cartilage/cartilage.git'
25
+
26
+ Cartilage depends on Twitter Bootstrap and we prefer the bootstrap-sass gem
27
+ for this, so also add this line while you're at it:
28
+
29
+ gem 'bootstrap-sass'
30
+
31
+ Be sure to perform a `bundle install` to bring these new dependencies into
32
+ your project.
33
+
34
+ ### Including Cartilage in the Asset Pipeline
35
+
36
+ You will also need to edit your manifest files (i.e. application.css and
37
+ application.js) to include Cartilage:
38
+
39
+ //= require cartilage
40
+
41
+
42
+ ### Working With Windows
43
+
44
+ If you need to work with IE on Windows it is recommend that you continue development
45
+ on Mac or *nix environment. If you're using Pow, run "rake pow:prepare" which will
46
+ create a "public" symlink to the test directory. Once the cartilage repo is linked
47
+ it'll automatically pick up the public folder and start serving the static files there.
48
+ With Pow, you'll be able to use xip.io to access the tests from browsers through a VM
49
+ or beyond your own computer.
50
+
51
+ Alternatively, if you're not using Pow you can also simply call 'rackup' from the repo
52
+ root which will start the default server and point directly to the test directory.
53
+
54
+ ## License
55
+
56
+ Cartilage is licensed under the terms of the MIT license (see MIT-LICENSE for
57
+ more details).
data/Rakefile ADDED
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env rake
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+ begin
9
+ require 'rdoc/task'
10
+ rescue LoadError
11
+ require 'rdoc/rdoc'
12
+ require 'rake/rdoctask'
13
+ RDoc::Task = Rake::RDocTask
14
+ end
15
+
16
+ RDoc::Task.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'Cartilage'
19
+ rdoc.options << '--line-numbers'
20
+ rdoc.rdoc_files.include('README.rdoc')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
23
+
24
+ Bundler::GemHelper.install_tasks
25
+
26
+ require 'rake/testtask'
27
+
28
+ desc "Run tests for both engine and framework"
29
+ task :test => [ "test:framework" ] do
30
+ # ...
31
+ end
32
+
33
+ namespace :pow do
34
+ task :prepare do
35
+ File.symlink("test/framework", "public")
36
+ end
37
+ end
38
+
39
+ namespace :test do
40
+ desc "Run tests for framework"
41
+ task :framework => [ :compile ] do
42
+ `which phantomjs`
43
+ if $?.success?
44
+ system "phantomjs --debug=no --local-to-remote-url-access=yes #{File.dirname(__FILE__)}/test/framework/vendor/run-qunit.js #{File.dirname(__FILE__)}/test/framework/index.html"
45
+ else
46
+ raise "PhantomJS is not installed. On Mac OS X please make sure you have the latest homebrew and try 'brew install phantomjs'"
47
+ end
48
+ end
49
+
50
+ task :browser => [ :compile ] do
51
+ system "open #{File.dirname(__FILE__)}/test/framework/index.html"
52
+ end
53
+
54
+ namespace :browser do
55
+ # Having trouble running this in Chrome due to cross-origin issues due to file://?
56
+ # Quit Chrome and let open start it up with the -allow-file-access-from-files flag
57
+ # which should make things work again. FF and Safari work fine with the default 'open'.
58
+ task :chrome => [ :compile ] do
59
+ system "open -a \"Google Chrome.app\" --args -allow-file-access-from-files #{File.dirname(__FILE__)}/test/framework/index.html"
60
+ end
61
+ end
62
+ end
63
+
64
+ # task :default => :test
65
+
66
+ desc "Compiles the framework into standalone JavaScript and CSS files"
67
+ task :compile do
68
+ require 'sprockets'
69
+ require 'uglifier'
70
+
71
+ environment = Sprockets::Environment.new(File.dirname(__FILE__))
72
+ environment.append_path 'app/assets/javascripts'
73
+ environment.append_path 'app/assets/stylesheets'
74
+ environment.append_path 'vendor/assets/javascripts'
75
+ environment.append_path 'vendor/assets/stylesheets'
76
+
77
+ cartilage_js = environment.find_asset('cartilage.js.coffee').to_s
78
+ compressed_js = Uglifier.compile(cartilage_js, :mangle => false)
79
+ File.open("#{File.dirname(__FILE__)}/test/framework/cartilage.js", 'w') { |f| f.write(compressed_js) }
80
+
81
+ # cartilage_css = environment.find_asset('cartilage.css.scss').to_s
82
+ # compressed_css = Uglifier.compile(cartilage_css)
83
+ # File.open('cartilage.css', 'w') { |f| f.write(compressed_js) }
84
+ end
@@ -0,0 +1,45 @@
1
+
2
+ class window.Cartilage.Application
3
+
4
+ @Collections: {}
5
+ @Models: {}
6
+ @Routers: {}
7
+ @Views: {}
8
+
9
+ @sharedInstance: null
10
+ @contentView: null
11
+
12
+ @launch: ->
13
+ @sharedInstance = new @
14
+ @sharedInstance.initialize()
15
+ @hijackLinks()
16
+
17
+ @show: (view) ->
18
+ @contentView = new Cartilage.Views.ContentView unless @contentView?
19
+ @contentView.show(view)
20
+
21
+ @hijackLinks: ->
22
+ if Backbone.history and Backbone.history._hasPushState
23
+ $(document).delegate "a", "click", (event) ->
24
+ href = $(this).attr("href")
25
+ protocol = this.protocol + "//"
26
+
27
+ # Ignore anchors without hrefs.
28
+ return unless href
29
+
30
+ # Ensure that the link element does not define data-passthrough="true",
31
+ # which denotes that the link should be passed through to the backend
32
+ # application.
33
+ return if $(this).attr("data-passthrough") is "true"
34
+
35
+ # Ensure the protocol is not part of URL, meaning its relative.
36
+ return if href.match(/\:\/\//)
37
+
38
+ # Stop the event bubbling to ensure the link will not cause a page
39
+ # refresh.
40
+ event.preventDefault()
41
+
42
+ # Note by using Backbone.history.navigate, router events will not be
43
+ # triggered. If this is a problem, change this to navigate on your
44
+ # router.
45
+ Backbone.history.navigate(href, true)
@@ -0,0 +1,4 @@
1
+
2
+ class window.Cartilage.Collections.Segments extends Backbone.Collection
3
+
4
+ model: Cartilage.Models.Segment
@@ -0,0 +1,8 @@
1
+
2
+ window.Cartilage =
3
+
4
+ Version: 2.0
5
+
6
+ Collections: []
7
+ Models: []
8
+ Views: []
@@ -0,0 +1,2 @@
1
+
2
+ class window.Cartilage.Model extends Backbone.Model
@@ -0,0 +1,2 @@
1
+
2
+ class window.Cartilage.Models.Segment extends Cartilage.Model
@@ -0,0 +1,58 @@
1
+ #
2
+ # Bar Segment View
3
+ #
4
+
5
+ class window.Cartilage.Views.BarSegmentView extends Cartilage.View
6
+
7
+ # View Configuration -------------------------------------------------------
8
+
9
+ tagName: "li"
10
+
11
+ # Properties ---------------------------------------------------------------
12
+
13
+ #
14
+ # The BarView instance that this segment belongs to.
15
+ #
16
+ @property "barView", access: READONLY
17
+
18
+ #
19
+ # The background color of the segment.
20
+ #
21
+ @property "color", default: "#eeeeee"
22
+
23
+ #
24
+ # The fill width specified as a float from 0 to 1 that represents the
25
+ # percentage of the segment to occupy.
26
+ #
27
+ @property "fillWidth", default: 0
28
+
29
+ #
30
+ # The width specified as a float from 0 to 1 that represents the percentage
31
+ # of the barView to occupy.
32
+ #
33
+ @property "width", default: 0
34
+
35
+ # Internal Properties ------------------------------------------------------
36
+
37
+ # --------------------------------------------------------------------------
38
+
39
+ initialize: (options = {}) ->
40
+
41
+ # Initialize the View
42
+ super(options)
43
+
44
+ # Initialize the Bar Element
45
+ @_barElement = ($ "<div />").addClass("bar")
46
+ ($ @_barElement).css
47
+ width: (@fillWidth * 100) + "%"
48
+ backgroundColor: @color
49
+
50
+ prepare: ->
51
+
52
+ # Prepare the View
53
+ super()
54
+
55
+ ($ @el).html @_barElement
56
+ ($ @_barElement).css { display: "block" } if @fillWidth > 0
57
+
58
+ ($ @el).css { width: (@width * 100) + "%" }
@@ -0,0 +1,85 @@
1
+ #
2
+ # Bar View
3
+ #
4
+
5
+ class window.Cartilage.Views.BarView extends Cartilage.View
6
+
7
+ # View Configuration -------------------------------------------------------
8
+
9
+ tagName: "ul"
10
+
11
+ # Properties ---------------------------------------------------------------
12
+
13
+ #
14
+ # The segments of the bar view.
15
+ #
16
+ @property "segments", default: new Cartilage.Collections.Segments
17
+
18
+ #
19
+ # The value of the bar view.
20
+ #
21
+ @property "value", default: 0
22
+
23
+ #
24
+ # The default colors for the segments that comprise the bar view.
25
+ #
26
+ @property "colors", default: [ '#6ba2d4', '#a765a2', '#f69062', '#8ccc64', '#c26bb4', '#e9d243' ]
27
+
28
+ # Internal Properties ------------------------------------------------------
29
+
30
+ _cumulativeWidth: 0
31
+
32
+ # --------------------------------------------------------------------------
33
+
34
+ prepare: ->
35
+
36
+ # Prepare the View
37
+ super()
38
+
39
+ # Create segment views for each segment of the bar view.
40
+ _.each @segments.models, (segment, index) =>
41
+ segmentWidth = @_percentageWidthForSegmentAtIndex(index)
42
+ barWidth = @_percentageWidthForBarInSegmentAtIndex(index)
43
+ segmentView = new Cartilage.Views.BarSegmentView {
44
+ barView: @,
45
+ model: segment,
46
+ width: segmentWidth,
47
+ fillWidth: barWidth,
48
+ color: @colors[index]
49
+ }
50
+ @addSubview segmentView
51
+
52
+ # TODO Move this to BarSegmentView
53
+ _percentageWidthForSegmentAtIndex: (index) =>
54
+ segment = @segments.models[index]
55
+ segmentWidth = segment.get("maximum") - @segments.models[index - 1]?.get("maximum") || segment.get("maximum")
56
+ totalWidth = _.last(@segments.models).get("maximum")
57
+ computedWidth = segmentWidth / totalWidth
58
+
59
+ computedWidth = 0.02 unless computedWidth > 0.02
60
+ computedWidth = 1.0 - @_cumulativeWidth unless @segments.models[index + 1]?
61
+
62
+ @_cumulativeWidth += computedWidth
63
+
64
+ # console.log "Segment: ", segment, "Width: ", segmentWidth, "Computed Width: ", computedWidth, "Total Width: ", totalWidth, "Cumulative Width: ", @_cumulativeWidth
65
+
66
+ computedWidth
67
+
68
+ # TODO Move this to BarSegmentView
69
+ _percentageWidthForBarInSegmentAtIndex: (index) ->
70
+ segment = @segments.models[index]
71
+ maximumSoFar = @segments.models[index - 1]?.get("maximum") || 0
72
+ segmentWidth = segment.get("maximum") - maximumSoFar
73
+ fooWidth = @value - maximumSoFar
74
+ barWidth = 0
75
+
76
+ return 0 if fooWidth <= 0
77
+
78
+ if @value > segment.get("maximum")
79
+ barWidth = 1.0
80
+ else
81
+ barWidth = fooWidth / segmentWidth
82
+
83
+ # console.log "Bar for Segment: ", segment, "Width: ", segmentWidth, "Bar Width: ", barWidth, "Value: ", @value, "Foo Width: ", fooWidth
84
+
85
+ barWidth
@@ -0,0 +1,16 @@
1
+ class window.Cartilage.Views.ContentView extends Cartilage.View
2
+
3
+ el: "#content"
4
+
5
+ initialize: (options = {}) ->
6
+ @currentView = null
7
+ super(options)
8
+
9
+ show: (view) ->
10
+ if @currentView
11
+ @currentView.cleanup() if @currentView.cleanup
12
+ else if @currentView
13
+ console.warn "This view does not implement a cleanup method. Please extend all of your views from Cartilage.View to ensure compatibility."
14
+
15
+ @currentView = view
16
+ @addSubview @currentView
@@ -0,0 +1,76 @@
1
+ #
2
+ # Image View
3
+ #
4
+ # Wraps an HTML <img/> element and observes for load and error events,
5
+ # dispatching those events to callbacks defined on a subclass or methods on
6
+ # the delegate.
7
+ #
8
+ # Events
9
+ # ------
10
+ #
11
+ # * "loaded"
12
+ # * "error"
13
+ # * "cleared"
14
+ #
15
+
16
+ class window.Cartilage.Views.ImageView extends Cartilage.View
17
+
18
+ # Properties ---------------------------------------------------------------
19
+
20
+ #
21
+ # The URL to the image.
22
+ #
23
+ @property "imageAddress", set: (url) ->
24
+ @__imageAddress = url
25
+ @__imageElement = ($ "<img />").attr('src', @imageAddress)
26
+
27
+ # Bind to Events manually because event delegation will not work for
28
+ # image load and error events...
29
+ ($ @__imageElement).load @handleLoadEvent
30
+ ($ @__imageElement).error @handleErrorEvent
31
+
32
+ #
33
+ # Denotes whether or not the image has finished loading.
34
+ #
35
+ @property "isLoaded", access: READONLY, default: no
36
+
37
+ #
38
+ # Denotes whether or not an error occurred while loading.
39
+ #
40
+ @property "isError", access: READONLY, default: no
41
+
42
+ #
43
+ # The image element that this view manages.
44
+ #
45
+ @property "imageElement", access: READONLY
46
+
47
+ # --------------------------------------------------------------------------
48
+
49
+ render: ->
50
+ super()
51
+ ($ @el).html @_imageElement
52
+
53
+ @
54
+
55
+ cleanup: ->
56
+ @clear { silent: true }
57
+ super()
58
+
59
+ clear: (options = {}) ->
60
+ @_isLoaded = false
61
+ @_imageAddress = null
62
+ ($ @_imageElement).off().hide().attr("src", null)
63
+ @trigger "cleared" unless options.silent
64
+
65
+ # Event Handlers -----------------------------------------------------------
66
+
67
+ handleLoadEvent: (event) =>
68
+ @_isLoaded = true
69
+ @_isError = false
70
+ @imageElement.fadeIn() unless @imageElement.is ":visible"
71
+ @trigger "load", event
72
+
73
+ handleErrorEvent: (event) =>
74
+ @clear()
75
+ @_isError = true
76
+ @trigger "error", event