middleman-wizard-template 1.0.0.pre.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (21) hide show
  1. data/.gitignore +4 -4
  2. data/lib/middleman-wizard-template/template.rb +1 -0
  3. data/lib/middleman-wizard-template/template/README.tt +25 -0
  4. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/closurebuilder.py +256 -0
  5. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/depstree.py +189 -0
  6. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/depstree.pyc +0 -0
  7. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/depstree_test.py +127 -0
  8. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/depswriter.py +202 -0
  9. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/jscompiler.py +71 -0
  10. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/jscompiler.pyc +0 -0
  11. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/source.py +114 -0
  12. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/source.pyc +0 -0
  13. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/source_test.py +121 -0
  14. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/treescan.py +78 -0
  15. data/lib/middleman-wizard-template/template/closure/library/closure/bin/build/treescan.pyc +0 -0
  16. data/lib/middleman-wizard-template/template/config.tt +66 -0
  17. data/lib/middleman-wizard-template/template/shared/Gemfile.tt +2 -1
  18. data/lib/middleman-wizard-template/template/source/javascripts/app.js +3 -5
  19. data/lib/middleman-wizard-template/version.rb +1 -1
  20. metadata +21 -6
  21. data/lib/middleman-wizard-template/template/source/javascripts/_lib/asset_loader.js +0 -492
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env python
2
+ #
3
+ # Copyright 2010 The Closure Library Authors. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS-IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+
18
+ """Unit test for source."""
19
+
20
+ __author__ = 'nnaze@google.com (Nathan Naze)'
21
+
22
+
23
+ import unittest
24
+
25
+ import source
26
+
27
+
28
+ class SourceTestCase(unittest.TestCase):
29
+ """Unit test for source. Tests the parser on a known source input."""
30
+
31
+ def testSourceScan(self):
32
+ test_source = source.Source(_TEST_SOURCE)
33
+
34
+ self.assertEqual(set(['foo', 'foo.test']),
35
+ test_source.provides)
36
+ self.assertEqual(set(['goog.dom', 'goog.events.EventType']),
37
+ test_source.requires)
38
+
39
+ def testSourceScanBase(self):
40
+ test_source = source.Source(_TEST_BASE_SOURCE)
41
+
42
+ self.assertEqual(set(['goog']),
43
+ test_source.provides)
44
+ self.assertEqual(test_source.requires, set())
45
+
46
+ def testSourceScanBadBase(self):
47
+
48
+ def MakeSource():
49
+ source.Source(_TEST_BAD_BASE_SOURCE)
50
+
51
+ self.assertRaises(Exception, MakeSource)
52
+
53
+ def testStripComments(self):
54
+ self.assertEquals(
55
+ '\nvar foo = function() {}',
56
+ source.Source._StripComments((
57
+ '/* This is\n'
58
+ ' a comment split\n'
59
+ ' over multiple lines\n'
60
+ '*/\n'
61
+ 'var foo = function() {}')))
62
+
63
+ def testGoogStatementsInComments(self):
64
+ test_source = source.Source(_TEST_COMMENT_SOURCE)
65
+
66
+ self.assertEqual(set(['foo']),
67
+ test_source.provides)
68
+ self.assertEqual(set(['goog.events.EventType']),
69
+ test_source.requires)
70
+
71
+
72
+ _TEST_SOURCE = """// Fake copyright notice
73
+
74
+ /** Very important comment. */
75
+
76
+ goog.provide('foo');
77
+ goog.provide('foo.test');
78
+
79
+ goog.require('goog.dom');
80
+ goog.require('goog.events.EventType');
81
+
82
+ function foo() {
83
+ // Set bar to seventeen to increase performance.
84
+ this.bar = 17;
85
+ }
86
+ """
87
+
88
+ _TEST_COMMENT_SOURCE = """// Fake copyright notice
89
+
90
+ goog.provide('foo');
91
+
92
+ /*
93
+ goog.provide('foo.test');
94
+ */
95
+
96
+ /*
97
+ goog.require('goog.dom');
98
+ */
99
+
100
+ // goog.require('goog.dom');
101
+
102
+ goog.require('goog.events.EventType');
103
+
104
+ function bar() {
105
+ this.baz = 55;
106
+ }
107
+ """
108
+
109
+ _TEST_BASE_SOURCE = """
110
+ var goog = goog || {}; // Identifies this file as the Closure base.
111
+ """
112
+
113
+ _TEST_BAD_BASE_SOURCE = """
114
+ goog.provide('goog');
115
+
116
+ var goog = goog || {}; // Identifies this file as the Closure base.
117
+ """
118
+
119
+
120
+ if __name__ == '__main__':
121
+ unittest.main()
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env python
2
+ #
3
+ # Copyright 2010 The Closure Library Authors. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS-IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+
18
+ """Shared utility functions for scanning directory trees."""
19
+
20
+ import os
21
+ import re
22
+
23
+
24
+ __author__ = 'nnaze@google.com (Nathan Naze)'
25
+
26
+
27
+ # Matches a .js file path.
28
+ _JS_FILE_REGEX = re.compile(r'^.+\.js$')
29
+
30
+
31
+ def ScanTreeForJsFiles(root):
32
+ """Scans a directory tree for JavaScript files.
33
+
34
+ Args:
35
+ root: str, Path to a root directory.
36
+
37
+ Returns:
38
+ An iterable of paths to JS files, relative to cwd.
39
+ """
40
+ return ScanTree(root, path_filter=_JS_FILE_REGEX)
41
+
42
+
43
+ def ScanTree(root, path_filter=None, ignore_hidden=True):
44
+ """Scans a directory tree for files.
45
+
46
+ Args:
47
+ root: str, Path to a root directory.
48
+ path_filter: A regular expression filter. If set, only paths matching
49
+ the path_filter are returned.
50
+ ignore_hidden: If True, do not follow or return hidden directories or files
51
+ (those starting with a '.' character).
52
+
53
+ Yields:
54
+ A string path to files, relative to cwd.
55
+ """
56
+
57
+ def OnError(os_error):
58
+ raise os_error
59
+
60
+ for dirpath, dirnames, filenames in os.walk(root, onerror=OnError):
61
+ # os.walk allows us to modify dirnames to prevent decent into particular
62
+ # directories. Avoid hidden directories.
63
+ for dirname in dirnames:
64
+ if ignore_hidden and dirname.startswith('.'):
65
+ dirnames.remove(dirname)
66
+
67
+ for filename in filenames:
68
+
69
+ # nothing that starts with '.'
70
+ if ignore_hidden and filename.startswith('.'):
71
+ continue
72
+
73
+ fullpath = os.path.join(dirpath, filename)
74
+
75
+ if path_filter and not path_filter.match(fullpath):
76
+ continue
77
+
78
+ yield os.path.normpath(fullpath)
@@ -0,0 +1,66 @@
1
+ use Rack::Static, :urls => ["/closure"]
2
+
3
+ set :haml, :attr_wrapper => '"'
4
+
5
+ ready do
6
+ ::Sprockets.unregister_postprocessor 'application/javascript', ::Sprockets::SafetyColons
7
+ end
8
+
9
+ # Preview Server
10
+ configure :development do
11
+ activate :relative_assets
12
+ end
13
+
14
+ # Closure Compiler Testing
15
+ configure :build do
16
+ after_build do |builder|
17
+ builder.say "Linting"
18
+ system %Q{gjslint -r source/javascripts/ --exclude_files="source/javascripts/modernizr.js"}
19
+
20
+ # Create Goro-ready css file
21
+ orig_css = File.read("build/stylesheets/site.css")
22
+ orig_css.gsub!(%Q{@charset "UTF-8";}, "")
23
+ builder.create_file "build/stylesheets/site.css" do
24
+ orig_css
25
+ end
26
+ end
27
+
28
+ # Goro deploy
29
+ if ENV['GORO']
30
+ set :layout, false
31
+ # set :http_prefix, "../../"
32
+
33
+ compass_config do |compass|
34
+ compass.line_comments = false
35
+ end
36
+
37
+ after_build do |builder|
38
+ builder.say "Optimizing Images (may take a while)"
39
+ image_optim = ImageOptim.new(:pngout => false)
40
+ image_optim.optimize_images!(Dir['build/images/**/*.*']) do |unoptimized, optimized|
41
+ puts unoptimized
42
+ end
43
+ end
44
+ else
45
+ activate :relative_assets
46
+
47
+ compass_config do |compass|
48
+ compass.line_comments = false
49
+ end
50
+
51
+ after_build do |builder|
52
+ builder.say "Compiling to a single file"
53
+ builder.create_file "build/javascripts/app.min.js" do
54
+ `closure/library/closure/bin/build/closurebuilder.py --root=closure/library/ --root=build/javascripts/ --namespace="site_name" --output_mode=compiled --compiler_flags="--debug=true" --compiler_jar=closure/compiler/compiler.jar --compiler_flags="--compilation_level=ADVANCED_OPTIMIZATIONS"`
55
+ end
56
+
57
+ orig_file = File.read("build/index.html")
58
+
59
+ # Remove goog.base
60
+ orig_file.gsub!(%Q{<script src="/closure/library/closure/goog/base.js"></script>}, "")
61
+ builder.create_file "build/index.html" do
62
+ orig_file
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,3 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem "middleman", "~> <%= Middleman::VERSION %>"
3
+ gem "middleman", "~> <%= Middleman::VERSION %>"
4
+ gem "image_optim"
@@ -1,20 +1,18 @@
1
1
  //= require "_lib/util"
2
- //= require "_lib/asset_loader"
3
2
  //= require "_lib/raf"
4
3
  //= require "_lib/Transform"
5
4
  //= require "_lib/Tween"
6
- //= require "_lib/router"
7
5
 
8
6
  goog.provide('site_name');
9
- goog.require('goog.History');
7
+ // goog.require('goog.History');
10
8
  goog.require('goog.dom');
11
9
  goog.require('goog.dom.classes');
12
10
  goog.require('goog.dom.dataset');
13
11
  goog.require('goog.dom.query');
14
12
  goog.require('goog.events');
15
- goog.require('goog.net.XhrIo');
13
+ // goog.require('goog.net.XhrIo');
16
14
  goog.require('goog.style');
17
- goog.require('goog.userAgent');
15
+ // goog.require('goog.userAgent');
18
16
 
19
17
  /**
20
18
  * Initialize the app.
@@ -1,5 +1,5 @@
1
1
  module Middleman
2
2
  module WizardTemplate
3
- VERSION = "1.0.0.pre.1"
3
+ VERSION = "1.0.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: middleman-wizard-template
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre.1
5
- prerelease: 6
4
+ version: 1.0.1
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Thomas Reynolds
@@ -41,11 +41,24 @@ files:
41
41
  - Rakefile
42
42
  - lib/middleman-wizard-template.rb
43
43
  - lib/middleman-wizard-template/template.rb
44
+ - lib/middleman-wizard-template/template/README.tt
44
45
  - lib/middleman-wizard-template/template/closure/compiler/COPYING
45
46
  - lib/middleman-wizard-template/template/closure/compiler/README
46
47
  - lib/middleman-wizard-template/template/closure/compiler/compiler.jar
47
48
  - lib/middleman-wizard-template/template/closure/library/all_tests.html
48
49
  - lib/middleman-wizard-template/template/closure/library/alltests.js
50
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/closurebuilder.py
51
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/depstree.py
52
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/depstree.pyc
53
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/depstree_test.py
54
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/depswriter.py
55
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/jscompiler.py
56
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/jscompiler.pyc
57
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/source.py
58
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/source.pyc
59
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/source_test.py
60
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/treescan.py
61
+ - lib/middleman-wizard-template/template/closure/library/closure/bin/build/treescan.pyc
49
62
  - lib/middleman-wizard-template/template/closure/library/closure/bin/calcdeps.py
50
63
  - lib/middleman-wizard-template/template/closure/library/closure/bin/scopify.py
51
64
  - lib/middleman-wizard-template/template/closure/library/closure/css/inlay/g-base.css
@@ -1763,7 +1776,6 @@ files:
1763
1776
  - lib/middleman-wizard-template/template/source/index.html.erb
1764
1777
  - lib/middleman-wizard-template/template/source/javascripts/_lib/Transform.js
1765
1778
  - lib/middleman-wizard-template/template/source/javascripts/_lib/Tween.js
1766
- - lib/middleman-wizard-template/template/source/javascripts/_lib/asset_loader.js
1767
1779
  - lib/middleman-wizard-template/template/source/javascripts/_lib/raf.js
1768
1780
  - lib/middleman-wizard-template/template/source/javascripts/_lib/router.js
1769
1781
  - lib/middleman-wizard-template/template/source/javascripts/_lib/util.js
@@ -1788,13 +1800,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
1788
1800
  version: '0'
1789
1801
  segments:
1790
1802
  - 0
1791
- hash: -4398009891192626344
1803
+ hash: 282265817994922857
1792
1804
  required_rubygems_version: !ruby/object:Gem::Requirement
1793
1805
  none: false
1794
1806
  requirements:
1795
- - - ! '>'
1807
+ - - ! '>='
1796
1808
  - !ruby/object:Gem::Version
1797
- version: 1.3.1
1809
+ version: '0'
1810
+ segments:
1811
+ - 0
1812
+ hash: 282265817994922857
1798
1813
  requirements: []
1799
1814
  rubyforge_project: middleman-wizard-template
1800
1815
  rubygems_version: 1.8.23
@@ -1,492 +0,0 @@
1
- /**
2
- * Loads resources while providing progress updates.
3
- * @constructor
4
- * @param {Object} settings Config vars.
5
- */
6
- ww.Loader = function Loader(settings) {
7
-
8
- // merge settings with defaults
9
- settings = settings || {};
10
-
11
- // how frequently we poll resources for progress
12
- if (settings.statusInterval == null) {
13
- settings.statusInterval = 5000; // every 5 seconds by default
14
- }
15
-
16
- // delay before logging since last progress change
17
- if (settings.loggingDelay == null) {
18
- settings.loggingDelay = 20 * 1000; // log stragglers after 20 secs
19
- }
20
-
21
- // stop waiting if no progress has been made in the moving time window
22
- if (settings.noProgressTimeout == null) {
23
- settings.noProgressTimeout = Infinity; // do not stop waiting by default
24
- }
25
-
26
- var entries = [],
27
- // holds resources to be loaded with their status
28
- progressListeners = [],
29
- timeStarted, progressChanged = +new Date();
30
-
31
- /**
32
- * The status of a resource
33
- * @enum {number}
34
- */
35
- var ResourceState = {
36
- QUEUED: 0,
37
- WAITING: 1,
38
- LOADED: 2,
39
- ERROR: 3,
40
- TIMEOUT: 4
41
- };
42
-
43
- // places non-array values into an array.
44
- var ensureArray = function(val) {
45
- if (val == null) {
46
- return [];
47
- }
48
-
49
- if (Array.isArray(val)) {
50
- return val;
51
- }
52
-
53
- return [val];
54
- };
55
-
56
- // add an entry to the list of resources to be loaded
57
- this.add = function(resource) {
58
-
59
- // ensure tags are in an object
60
- resource.tags = new ww.LoaderTags(resource.tags);
61
-
62
- // ensure priority is set
63
- if (resource.priority == null) {
64
- resource.priority = Infinity;
65
- }
66
-
67
- entries.push({
68
- resource: resource,
69
- status: ResourceState.QUEUED
70
- });
71
- };
72
-
73
- this.addProgressListener = function(callback, tags) {
74
- progressListeners.push({
75
- callback: callback,
76
- tags: new ww.LoaderTags(tags)
77
- });
78
- };
79
-
80
- this.addCompletionListener = function(callback, tags) {
81
- progressListeners.push({
82
- tags: new ww.LoaderTags(tags),
83
- callback: function(e) {
84
- if (e.completedCount === e.totalCount) {
85
- callback();
86
- }
87
- }
88
- });
89
- };
90
-
91
- // creates a comparison function for resources
92
- var getResourceSort = function(orderedTags) {
93
-
94
- // helper to get the top tag's order for a resource
95
- orderedTags = ensureArray(orderedTags);
96
- var getTagOrder = function(entry) {
97
- var resource = entry.resource,
98
- bestIndex = Infinity;
99
- for (var i = 0; i < resource.tags.length; i++) {
100
- for (var j = 0; j < Math.min(orderedTags.length, bestIndex); j++) {
101
- if (resource.tags[i] == orderedTags[j] && j < bestIndex) {
102
- bestIndex = j;
103
- if (bestIndex === 0) break;
104
- }
105
- if (bestIndex === 0) break;
106
- }
107
- }
108
- return bestIndex;
109
- };
110
- return function(a, b) {
111
- // check tag order first
112
- var aOrder = getTagOrder(a),
113
- bOrder = getTagOrder(b);
114
- if (aOrder < bOrder) return -1;
115
- if (aOrder > bOrder) return 1;
116
-
117
- // now check priority
118
- if (a.priority < b.priority) return -1;
119
- if (a.priority > b.priority) return 1;
120
- return 0;
121
- }
122
- };
123
-
124
- this.start = function(orderedTags) {
125
- timeStarted = +new Date;
126
-
127
- // first order the resources
128
- var compareResources = getResourceSort(orderedTags);
129
- entries.sort(compareResources);
130
-
131
- // trigger requests for each resource
132
- for (var i = 0, len = entries.length; i < len; i++) {
133
- var entry = entries[i];
134
- entry.status = ResourceState.WAITING;
135
- entry.resource.start(this);
136
- }
137
-
138
- // do an initial status check soon since items may be loaded from the cache
139
- setTimeout(statusCheck, 100);
140
- };
141
-
142
- var statusCheck = function() {
143
- var checkAgain = false,
144
- noProgressTime = (+new Date()) - progressChanged,
145
- timedOut = (noProgressTime >= settings.noProgressTimeout),
146
- shouldLog = (noProgressTime >= settings.loggingDelay);
147
-
148
- for (var i = 0, len = entries.length; i < len; i++) {
149
- var entry = entries[i];
150
- if (entry.status !== ResourceState.WAITING) {
151
- continue;
152
- }
153
-
154
- // see if the resource has loaded
155
- if (entry.resource.checkStatus) {
156
- entry.resource.checkStatus();
157
- }
158
-
159
- // if still waiting, mark as timed out or make sure we check again
160
- if (entry.status === ResourceState.WAITING) {
161
- if (timedOut) {
162
- entry.resource.onTimeout();
163
- } else {
164
- checkAgain = true;
165
- }
166
- }
167
- }
168
-
169
- // log any resources that are still pending
170
- if (shouldLog && checkAgain) {
171
- log();
172
- }
173
-
174
- if (checkAgain) {
175
- setTimeout(statusCheck, settings.statusInterval);
176
- }
177
- };
178
-
179
- this.isBusy = function() {
180
- for (var i = 0, len = entries.length; i < len; i++) {
181
- if ((entries[i].status === ResourceState.QUEUED) ||
182
- (entries[i].status === ResourceState.WAITING)) {
183
- return true;
184
- }
185
- }
186
- return false;
187
- };
188
-
189
- var onProgress = function(resource, statusType) {
190
- // find the entry for the resource
191
- var entry = null;
192
- for (var i = 0, len = entries.length; i < len; i++) {
193
- if (entries[i].resource === resource) {
194
- entry = entries[i];
195
- break;
196
- }
197
- }
198
-
199
- // we have already updated the status of the resource
200
- if (entry == null || entry.status !== ResourceState.WAITING) {
201
- return;
202
- }
203
- entry.status = statusType;
204
- progressChanged = +new Date();
205
-
206
- var numResourceTags = resource.tags.length;
207
-
208
- // fire callbacks for interested listeners
209
- var numListeners = progressListeners.length;
210
- for (var i = 0; i < numListeners; i++) {
211
- var listener = progressListeners[i],
212
- shouldCall;
213
-
214
- if (listener.tags.length === 0) {
215
- // no tags specified so always tell the listener
216
- shouldCall = true;
217
- } else {
218
- // listener only wants to hear about certain tags
219
- shouldCall = resource.tags.contains(listener.tags);
220
- }
221
-
222
- if (shouldCall) {
223
- sendProgress(entry, listener);
224
- }
225
- }
226
- };
227
-
228
- this.onLoad = function(resource) {
229
- onProgress(resource, ResourceState.LOADED);
230
- };
231
- this.onError = function(resource) {
232
- onProgress(resource, ResourceState.ERROR);
233
- };
234
- this.onTimeout = function(resource) {
235
- onProgress(resource, ResourceState.TIMEOUT);
236
- };
237
-
238
- // sends a progress report to a listener
239
- var sendProgress = function(updatedEntry, listener) {
240
- // find stats for all the resources the caller is interested in
241
- var completed = 0,
242
- total = 0;
243
- for (var i = 0, len = entries.length; i < len; i++) {
244
- var entry = entries[i],
245
- includeResource = false;
246
-
247
- if (listener.tags.length === 0) {
248
- // no tags specified so always tell the listener
249
- includeResource = true;
250
- } else {
251
- includeResource = entry.resource.tags.contains(listener.tags);
252
- }
253
-
254
- if (includeResource) {
255
- total++;
256
- if ((entry.status === ResourceState.LOADED) ||
257
- (entry.status === ResourceState.ERROR) ||
258
- (entry.status === ResourceState.TIMEOUT)) {
259
- completed++;
260
- }
261
- }
262
- }
263
-
264
- listener.callback({
265
- // info about the resource that changed
266
- resource: updatedEntry.resource,
267
-
268
- // should we expose StatusType instead?
269
- loaded: (updatedEntry.status === ResourceState.LOADED),
270
- error: (updatedEntry.status === ResourceState.ERROR),
271
- timeout: (updatedEntry.status === ResourceState.TIMEOUT),
272
-
273
- // updated stats for all resources
274
- completedCount: completed,
275
- totalCount: total
276
- });
277
- };
278
-
279
- // prints the status of each resource to the console
280
- var log = this.log = function(showAll) {
281
- if (!window.console) {
282
- return;
283
- }
284
-
285
- var elapsedSeconds = Math.round((+new Date() - timeStarted) / 1000);
286
- window.console.log('ww.Loader elapsed: ' + elapsedSeconds + ' sec');
287
-
288
- for (var i = 0, len = entries.length; i < len; i++) {
289
- var entry = entries[i];
290
- if (!showAll && entry.status !== ResourceState.WAITING) {
291
- continue;
292
- }
293
-
294
- var message = 'ww.Loader: #' + i + ' ' + entry.resource.getName();
295
- switch (entry.status) {
296
- case ResourceState.QUEUED:
297
- message += ' (Not Started)';
298
- break;
299
- case ResourceState.WAITING:
300
- message += ' (Waiting)';
301
- break;
302
- case ResourceState.LOADED:
303
- message += ' (Loaded)';
304
- break;
305
- case ResourceState.ERROR:
306
- message += ' (Error)';
307
- break;
308
- case ResourceState.TIMEOUT:
309
- message += ' (Timeout)';
310
- break;
311
- }
312
-
313
- if (entry.resource.tags.length > 0) {
314
- message += ' Tags: [' + entry.resource.tags.join(',') + ']';
315
- }
316
-
317
- window.console.log(message);
318
- }
319
- };
320
- };
321
-
322
- goog.exportSymbol('ww.Loader', ww.Loader);
323
-
324
- // Tag object to handle tag intersection; once created not meant to be changed
325
- // Performance rationale: http://jsperf.com/lists-indexof-vs-in-operator/3
326
- /**
327
- * Tags.
328
- * @constructor
329
- * @param {Object} values Tag values.
330
- */
331
- ww.LoaderTags = function LoaderTags(values) {
332
-
333
- this.array = [];
334
- this.object = {};
335
- this.value = null; // single value
336
- this.length = 0;
337
-
338
- if (values !== null && values !== undefined) {
339
- if (Array.isArray(values)) {
340
- this.array = values;
341
- } else if (typeof values === 'object') {
342
- for (var key in values) {
343
- this.array.push(key);
344
- }
345
- } else {
346
- this.array.push(values);
347
- this.value = values;
348
- }
349
-
350
- this.length = this.array.length;
351
-
352
- // convert array values to object with truthy values, used by contains
353
- // function below
354
- for (var i = 0; i < this.length; i++) {
355
- this.object[this.array[i]] = true;
356
- }
357
- }
358
-
359
- // compare this object with another; return true if they share at least
360
- // one value
361
- this.contains = function(other) {
362
- if (this.length === 0 || other.length === 0) {
363
- return false;
364
- } else if (this.length === 1 && this.value !== null) {
365
- if (other.length === 1) {
366
- return this.value === other.value;
367
- } else {
368
- return other.object.hasOwnProperty(this.value);
369
- }
370
- } else if (other.length < this.length) {
371
- return other.contains(this); // better to loop through the smaller object
372
- } else {
373
- for (var key in this.object) {
374
- if (other.object[key]) {
375
- return true;
376
- }
377
- }
378
- return false;
379
- }
380
- };
381
- };
382
-
383
- // shims to ensure we have newer Array utility methods
384
- if (!Array.isArray) {
385
- /**
386
- * Polyfill for isArray
387
- * @param {Array} arg The array.
388
- * @return {Boolean} Whether it is an array.
389
- */
390
- Array.isArray = function(arg) {
391
- return Object.prototype.toString.call(arg) == '[object Array]';
392
- };
393
- }
394
-
395
- goog.exportSymbol('ww.LoaderTags', ww.LoaderTags);
396
-
397
- /**
398
- * Loader plugin to load images.
399
- * @constructor
400
- * @param {String} url Url of the Swiffy.
401
- * @param {Array} tags Array of tag names.
402
- * @param {Number} priority Load order.
403
- */
404
- ww.LoaderImage = function LoaderImage(url, tags, priority) {
405
- var self = this,
406
- loader = null;
407
-
408
- this.img = new Image();
409
- this.tags = tags;
410
- this.priority = priority;
411
-
412
- var onReadyStateChange = function() {
413
- if (self.img.readyState == 'complete') {
414
- removeEventHandlers();
415
- loader.onLoad(self);
416
- }
417
- };
418
-
419
- var onLoad = function() {
420
- removeEventHandlers();
421
- loader.onLoad(self);
422
- };
423
-
424
- var onError = function() {
425
- removeEventHandlers();
426
- loader.onError(self);
427
- };
428
-
429
- var removeEventHandlers = function() {
430
- self.unbind('load', onLoad);
431
- self.unbind('readystatechange', onReadyStateChange);
432
- self.unbind('error', onError);
433
- };
434
-
435
- this.start = function(pxloader) {
436
- // we need the loader ref so we can notify upon completion
437
- loader = pxloader;
438
-
439
- // NOTE: Must add event listeners before the src is set. We
440
- // also need to use the readystatechange because sometimes
441
- // load doesn't fire when an image is in the cache.
442
- self.bind('load', onLoad);
443
- self.bind('readystatechange', onReadyStateChange);
444
- self.bind('error', onError);
445
-
446
- self.img.src = url;
447
- };
448
-
449
- // called by ww.Loader to check status of image (fallback in case
450
- // the event listeners are not triggered).
451
- this.checkStatus = function() {
452
- if (self.img.complete) {
453
- removeEventHandlers();
454
- loader.onLoad(self);
455
- }
456
- };
457
-
458
- // called by ww.Loader when it is no longer waiting
459
- this.onTimeout = function() {
460
- removeEventHandlers();
461
- if (self.img.complete) {
462
- loader.onLoad(self);
463
- } else {
464
- loader.onTimeout(self);
465
- }
466
- };
467
-
468
- // returns a name for the resource that can be used in logging
469
- this.getName = function() {
470
- return url;
471
- };
472
-
473
- // cross-browser event binding
474
- this.bind = function(eventName, eventHandler) {
475
- if (self.img.addEventListener) {
476
- self.img.addEventListener(eventName, eventHandler, false);
477
- } else if (self.img.attachEvent) {
478
- self.img.attachEvent('on' + eventName, eventHandler);
479
- }
480
- };
481
-
482
- // cross-browser event un-binding
483
- this.unbind = function(eventName, eventHandler) {
484
- if (self.img.removeEventListener) {
485
- self.img.removeEventListener(eventName, eventHandler, false);
486
- } else if (self.img.detachEvent) {
487
- self.img.detachEvent('on' + eventName, eventHandler);
488
- }
489
- };
490
- };
491
-
492
- goog.exportSymbol('ww.LoaderImage', ww.LoaderImage);