cartilage 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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