joosy 0.1.0.RC3 → 0.1.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -2
- data/Gemfile +2 -13
- data/Gemfile.lock +62 -80
- data/Guardfile +15 -21
- data/MIT-LICENSE +2 -2
- data/README.rdoc +3 -0
- data/app/helpers/joosy/sprockets_helper.rb +11 -23
- data/joosy.gemspec +3 -3
- data/lib/joosy/forms.rb +12 -2
- data/lib/joosy/rails/engine.rb +1 -9
- data/lib/joosy/rails/version.rb +2 -2
- data/lib/joosy-rails.rb +5 -0
- data/lib/rails/generators/joosy/application_generator.rb +3 -13
- data/lib/rails/generators/joosy/joosy_base.rb +2 -2
- data/lib/rails/generators/joosy/layout_generator.rb +1 -8
- data/lib/rails/generators/joosy/page_generator.rb +6 -21
- data/lib/rails/generators/joosy/preloader_generator.rb +7 -14
- data/lib/rails/generators/joosy/templates/app/layouts/application.js.coffee +0 -1
- data/lib/rails/generators/joosy/templates/app/layouts/template.js.coffee +1 -1
- data/lib/rails/generators/joosy/templates/app/pages/application.js.coffee +1 -1
- data/lib/rails/generators/joosy/templates/app/pages/template.js.coffee +3 -3
- data/lib/rails/generators/joosy/templates/app/routes.js.coffee +1 -7
- data/lib/rails/generators/joosy/templates/app/widgets/template.js.coffee +2 -2
- data/lib/rails/generators/joosy/templates/app.js.coffee +0 -3
- data/lib/rails/generators/joosy/templates/app_preloader.js.coffee.erb +12 -9
- data/lib/rails/generators/joosy/templates/preload.html.erb +6 -5
- data/lib/rails/generators/joosy/templates/preload.html.haml +5 -3
- data/lib/rails/generators/joosy/templates/preload.html.slim +21 -0
- data/lib/rails/generators/joosy/widget_generator.rb +1 -8
- data/spec/javascripts/helpers/spec_helper.js.coffee +0 -20
- data/spec/javascripts/joosy/core/modules/container_spec.js.coffee +27 -24
- data/spec/javascripts/joosy/core/modules/events_spec.js.coffee +18 -42
- data/spec/javascripts/joosy/core/modules/filters_spec.js.coffee +27 -27
- data/spec/javascripts/joosy/core/modules/log_spec.js.coffee +3 -3
- data/spec/javascripts/joosy/core/modules/module_spec.js.coffee +15 -6
- data/spec/javascripts/joosy/core/modules/time_manager_spec.js.coffee +7 -12
- data/spec/javascripts/joosy/core/modules/widget_manager_spec.js.coffee +17 -31
- data/tmp/javascripts/.gitignore +1 -0
- data/tmp/spec/javascripts/helpers/.gitignore +1 -0
- data/vendor/assets/javascripts/base64.js +135 -0
- data/vendor/assets/javascripts/joosy/core/application.js.coffee +26 -0
- data/vendor/assets/javascripts/joosy/core/form.js.coffee +87 -0
- data/vendor/assets/javascripts/joosy/core/joosy.js.coffee +62 -0
- data/vendor/assets/javascripts/joosy/core/layout.js.coffee +38 -0
- data/vendor/assets/javascripts/joosy/core/modules/container.js.coffee +51 -0
- data/vendor/assets/javascripts/joosy/core/modules/events.js.coffee +17 -0
- data/vendor/assets/javascripts/joosy/core/modules/filters.js.coffee +39 -0
- data/vendor/assets/javascripts/joosy/core/modules/log.js.coffee +12 -0
- data/vendor/assets/javascripts/joosy/core/modules/module.js.coffee +28 -0
- data/vendor/assets/javascripts/joosy/core/modules/time_manager.js.coffee +23 -0
- data/vendor/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +45 -0
- data/vendor/assets/javascripts/joosy/core/page.js.coffee +136 -0
- data/vendor/assets/javascripts/joosy/core/resource/rest.js.coffee +69 -0
- data/vendor/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +42 -0
- data/vendor/assets/javascripts/joosy/core/router.js.coffee +75 -0
- data/vendor/assets/javascripts/joosy/core/widget.js.coffee +35 -0
- data/vendor/assets/javascripts/joosy/preloader/development.js.coffee +27 -0
- data/vendor/assets/javascripts/joosy/preloader/production.js.coffee +84 -0
- data/{app → vendor}/assets/javascripts/joosy.js.coffee +0 -0
- data/vendor/assets/javascripts/jquery.form.js +963 -978
- data/vendor/assets/javascripts/sugar.js +1 -1
- metadata +48 -77
- data/.codoopts +0 -5
- data/README.md +0 -95
- data/app/assets/javascripts/joosy/core/application.js.coffee +0 -50
- data/app/assets/javascripts/joosy/core/form.js.coffee +0 -304
- data/app/assets/javascripts/joosy/core/helpers/view.js.coffee +0 -30
- data/app/assets/javascripts/joosy/core/joosy.js.coffee +0 -129
- data/app/assets/javascripts/joosy/core/layout.js.coffee +0 -162
- data/app/assets/javascripts/joosy/core/modules/container.js.coffee +0 -104
- data/app/assets/javascripts/joosy/core/modules/events.js.coffee +0 -123
- data/app/assets/javascripts/joosy/core/modules/filters.js.coffee +0 -67
- data/app/assets/javascripts/joosy/core/modules/log.js.coffee +0 -36
- data/app/assets/javascripts/joosy/core/modules/module.js.coffee +0 -105
- data/app/assets/javascripts/joosy/core/modules/renderer.js.coffee +0 -195
- data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +0 -46
- data/app/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +0 -84
- data/app/assets/javascripts/joosy/core/page.js.coffee +0 -375
- data/app/assets/javascripts/joosy/core/preloader.js.coffee +0 -13
- data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +0 -174
- data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +0 -254
- data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +0 -197
- data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +0 -125
- data/app/assets/javascripts/joosy/core/router.js.coffee +0 -163
- data/app/assets/javascripts/joosy/core/templaters/rails_jst.js.coffee +0 -36
- data/app/assets/javascripts/joosy/core/widget.js.coffee +0 -80
- data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +0 -169
- data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +0 -56
- data/lib/joosy.rb +0 -9
- data/lib/rails/generators/joosy/resource_generator.rb +0 -29
- data/lib/rails/generators/joosy/templates/app/helpers/application.js.coffee +0 -4
- data/lib/rails/generators/joosy/templates/app/pages/welcome/index.js.coffee +0 -22
- data/lib/rails/generators/joosy/templates/app/resources/template.js.coffee +0 -2
- data/lib/rails/generators/joosy/templates/app/templates/layouts/application.jst.hamlc +0 -2
- data/lib/rails/generators/joosy/templates/app/templates/pages/welcome/index.jst.hamlc +0 -7
- data/spec/javascripts/joosy/core/application_spec.js.coffee +0 -40
- data/spec/javascripts/joosy/core/form_spec.js.coffee +0 -184
- data/spec/javascripts/joosy/core/joosy_spec.js.coffee +0 -72
- data/spec/javascripts/joosy/core/layout_spec.js.coffee +0 -50
- data/spec/javascripts/joosy/core/modules/renderer_spec.js.coffee +0 -185
- data/spec/javascripts/joosy/core/page_spec.js.coffee +0 -178
- data/spec/javascripts/joosy/core/resource/collection_spec.js.coffee +0 -84
- data/spec/javascripts/joosy/core/resource/generic_spec.js.coffee +0 -118
- data/spec/javascripts/joosy/core/resource/rest_collection_spec.js.coffee +0 -58
- data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +0 -129
- data/spec/javascripts/joosy/core/router_spec.js.coffee +0 -123
- data/spec/javascripts/joosy/core/templaters/rails_jst_spec.js.coffee +0 -25
- data/spec/javascripts/joosy/core/widget_spec.js.coffee +0 -40
- data/spec/javascripts/joosy/preloaders/caching_spec.js.coffee +0 -36
- data/spec/javascripts/joosy/preloaders/inline_spec.js.coffee +0 -16
- data/spec/javascripts/support/assets/coolface.jpg +0 -0
- data/spec/javascripts/support/assets/okay.jpg +0 -0
- data/spec/javascripts/support/assets/test.js +0 -1
- data/spec/javascripts/support/sinon-ie-1.3.1.js +0 -82
- data/vendor/assets/javascripts/metamorph.js +0 -409
@@ -1,163 +0,0 @@
|
|
1
|
-
#= require joosy/core/joosy
|
2
|
-
|
3
|
-
#
|
4
|
-
# Router. Reacts on a hash change event and loads proper pages
|
5
|
-
#
|
6
|
-
# Example:
|
7
|
-
# Joosy.Router.map
|
8
|
-
# 404 : (path) -> alert "Page '#{path}' was not found :("
|
9
|
-
# '/' : Welcome.IndexPage
|
10
|
-
# '/resources' :
|
11
|
-
# '/' : Resource.IndexPage
|
12
|
-
# '/:id' : Resource.ShowPage
|
13
|
-
# '/:id/edit' : Resource.EditPage
|
14
|
-
# '/new' : Resource.EditPage
|
15
|
-
#
|
16
|
-
# @module
|
17
|
-
#
|
18
|
-
Joosy.Router =
|
19
|
-
#
|
20
|
-
# The Object containing route parts in keys and pages/lambdas in values
|
21
|
-
#
|
22
|
-
rawRoutes: Object.extended()
|
23
|
-
|
24
|
-
#
|
25
|
-
# Flattern routes mapped to regexps (to check if current route is what we
|
26
|
-
# need) and actual executors
|
27
|
-
#
|
28
|
-
routes: Object.extended()
|
29
|
-
|
30
|
-
#
|
31
|
-
# Clears the routes
|
32
|
-
#
|
33
|
-
reset: ->
|
34
|
-
@rawRoutes = Object.extended()
|
35
|
-
@routes = Object.extended()
|
36
|
-
|
37
|
-
#
|
38
|
-
# Registers the set of raw routes
|
39
|
-
# This method will only store routes and will not make them act immediately
|
40
|
-
# Routes get registered only once at system initialization during #__setupRoutes call
|
41
|
-
#
|
42
|
-
# @param [Object] routes Set of routes in inner format (see class description)
|
43
|
-
#
|
44
|
-
map: (routes) ->
|
45
|
-
Joosy.Module.merge @rawRoutes, routes
|
46
|
-
|
47
|
-
#
|
48
|
-
# Changes current hash with shebang (#!) and therefore triggers new route loading
|
49
|
-
# to be loaded
|
50
|
-
#
|
51
|
-
# @param [String] to Route to navigate to
|
52
|
-
#
|
53
|
-
navigate: (to) ->
|
54
|
-
location.hash = '!' + to
|
55
|
-
|
56
|
-
#
|
57
|
-
# Inits the routing system and loads the current route
|
58
|
-
# Binds the window hashchange event and therefore should only be called once
|
59
|
-
# during system startup
|
60
|
-
#
|
61
|
-
__setupRoutes: ->
|
62
|
-
@__prepareRoutes @rawRoutes
|
63
|
-
@__respondRoute location.hash
|
64
|
-
$(window).hashchange =>
|
65
|
-
@__respondRoute location.hash
|
66
|
-
|
67
|
-
#
|
68
|
-
# Compiles routes to map object
|
69
|
-
# Object will contain regexp string as key and lambda/Page to load as value
|
70
|
-
#
|
71
|
-
# @param [Object] routes Raw routes to prepare
|
72
|
-
# @param [String] namespace Inner cursor for recursion
|
73
|
-
#
|
74
|
-
__prepareRoutes: (routes, namespace='') ->
|
75
|
-
if !namespace && routes[404]
|
76
|
-
@wildcardAction = routes[404]
|
77
|
-
delete routes[404]
|
78
|
-
|
79
|
-
Object.each routes, (path, response) =>
|
80
|
-
path = (namespace + path).replace /\/{2,}/, '/'
|
81
|
-
if response && (Object.isFunction(response) || response.prototype?)
|
82
|
-
Joosy.Module.merge @routes, @__prepareRoute(path, response)
|
83
|
-
else
|
84
|
-
@__prepareRoutes response, path
|
85
|
-
|
86
|
-
#
|
87
|
-
# Compiles one single route
|
88
|
-
#
|
89
|
-
# @param [String] path Full path from raw route
|
90
|
-
# @param [Joosy.Page] response Page that should be loaded at this route
|
91
|
-
# @param [Function] response Lambda to call at this route
|
92
|
-
#
|
93
|
-
__prepareRoute: (path, response) ->
|
94
|
-
matchPath = path.replace(/\/:([^\/]+)/g, '/([^/]+)').replace(/^\/?/, '^/?').replace(/\/?$/, '/?$')
|
95
|
-
result = Object.extended()
|
96
|
-
|
97
|
-
result[matchPath] =
|
98
|
-
capture: (path.match(/\/:[^\/]+/g) || []).map (str) ->
|
99
|
-
str.substr 2
|
100
|
-
action: response
|
101
|
-
result
|
102
|
-
|
103
|
-
#
|
104
|
-
# Searches the corresponding route through compiled routes
|
105
|
-
#
|
106
|
-
# @param [String] hash Hash value to search route for
|
107
|
-
#
|
108
|
-
__respondRoute: (hash) ->
|
109
|
-
Joosy.Modules.Log.debug "Router> Answering '#{hash}'"
|
110
|
-
fullPath = hash.replace /^#!?/, ''
|
111
|
-
@currentPath = fullPath
|
112
|
-
found = false
|
113
|
-
queryArray = fullPath.split '&'
|
114
|
-
path = queryArray.shift()
|
115
|
-
urlParams = @__paramsFromQueryArray queryArray
|
116
|
-
|
117
|
-
for regex, route of @routes when @routes.hasOwnProperty regex
|
118
|
-
if vals = path.match new RegExp(regex)
|
119
|
-
params = @__paramsFromRouteMatch(vals, route).merge urlParams
|
120
|
-
|
121
|
-
if Joosy.Module.hasAncestor route.action, Joosy.Page
|
122
|
-
Joosy.Application.setCurrentPage route.action, params
|
123
|
-
else
|
124
|
-
route.action.call this, params
|
125
|
-
|
126
|
-
found = true
|
127
|
-
break
|
128
|
-
|
129
|
-
if !found && @wildcardAction?
|
130
|
-
@wildcardAction path, urlParams
|
131
|
-
|
132
|
-
#
|
133
|
-
# Collects params from route placeholders (/foo/:placeholder)
|
134
|
-
#
|
135
|
-
# @param [Array] vals Array of value gathered by regexp
|
136
|
-
# @param [Object] route Compiled route
|
137
|
-
# @returns [Object] Hash of params
|
138
|
-
#
|
139
|
-
__paramsFromRouteMatch: (vals, route) ->
|
140
|
-
params = Object.extended()
|
141
|
-
|
142
|
-
vals.shift()
|
143
|
-
for param in route.capture
|
144
|
-
params[param] = vals.shift()
|
145
|
-
|
146
|
-
params
|
147
|
-
|
148
|
-
#
|
149
|
-
# Collects params from query routes (/foo/&a=b)
|
150
|
-
#
|
151
|
-
# @param [Array] queryArray Array of query string split by '&' sign
|
152
|
-
# @returns [Object] Hash of params
|
153
|
-
#
|
154
|
-
__paramsFromQueryArray: (queryArray) ->
|
155
|
-
params = Object.extended()
|
156
|
-
|
157
|
-
if queryArray
|
158
|
-
$.each queryArray, ->
|
159
|
-
unless @isBlank()
|
160
|
-
pair = @split '='
|
161
|
-
params[pair[0]] = pair[1]
|
162
|
-
|
163
|
-
params
|
@@ -1,36 +0,0 @@
|
|
1
|
-
#= require joosy/core/joosy
|
2
|
-
|
3
|
-
#
|
4
|
-
# Rails JST template precompilation binding
|
5
|
-
#
|
6
|
-
class Joosy.Templaters.RailsJST
|
7
|
-
constructor: (@applicationName) ->
|
8
|
-
|
9
|
-
#
|
10
|
-
# Gets template lambda by its full name
|
11
|
-
#
|
12
|
-
# @param [String] name Template name 'foo/bar'
|
13
|
-
#
|
14
|
-
buildView: (name) ->
|
15
|
-
template = JST[location = "#{@applicationName}/templates/#{name}"]
|
16
|
-
|
17
|
-
unless template
|
18
|
-
throw new Error "Template '#{name}' not found. Checked at: #{location}"
|
19
|
-
|
20
|
-
template
|
21
|
-
|
22
|
-
#
|
23
|
-
# Gets full name of template by several params
|
24
|
-
#
|
25
|
-
# @param [String] section Section of templates like pages/layouts/...
|
26
|
-
# @param [String] template Internal template path
|
27
|
-
# @param [String] entity Entity to lookup template path by its namespace
|
28
|
-
#
|
29
|
-
resolveTemplate: (section, template, entity) ->
|
30
|
-
if template.startsWith '/'
|
31
|
-
return template.substr 1
|
32
|
-
|
33
|
-
path = entity.constructor?.__namespace__?.map('underscore') || []
|
34
|
-
path.unshift section
|
35
|
-
|
36
|
-
"#{path.join '/'}/#{template}"
|
@@ -1,80 +0,0 @@
|
|
1
|
-
#= require joosy/core/joosy
|
2
|
-
#= require joosy/core/modules/module
|
3
|
-
#= require joosy/core/modules/log
|
4
|
-
#= require joosy/core/modules/events
|
5
|
-
#= require joosy/core/modules/container
|
6
|
-
#= require joosy/core/modules/renderer
|
7
|
-
#= require joosy/core/modules/filters
|
8
|
-
|
9
|
-
#
|
10
|
-
# Base class for all of your Joosy Layouts.
|
11
|
-
#
|
12
|
-
# @todo Add link to the 5th chapter of guides here.
|
13
|
-
#
|
14
|
-
# @example Sample widget
|
15
|
-
# class @FooWidget extends Joosy.Widget
|
16
|
-
# @view 'foo'
|
17
|
-
#
|
18
|
-
class Joosy.Widget extends Joosy.Module
|
19
|
-
@include Joosy.Modules.Log
|
20
|
-
@include Joosy.Modules.Events
|
21
|
-
@include Joosy.Modules.Container
|
22
|
-
@include Joosy.Modules.Renderer
|
23
|
-
@include Joosy.Modules.Filters
|
24
|
-
@include Joosy.Modules.TimeManager
|
25
|
-
|
26
|
-
#
|
27
|
-
# By default widget will not render on load
|
28
|
-
#
|
29
|
-
__renderer: false
|
30
|
-
|
31
|
-
#
|
32
|
-
# Initial data that will be passed to view on load
|
33
|
-
# False (and not {}) by default to have a chance to check if data was loaded
|
34
|
-
#
|
35
|
-
data: false
|
36
|
-
|
37
|
-
#
|
38
|
-
# Proxy to Joosy.Router#navigate
|
39
|
-
#
|
40
|
-
navigate: (args...) ->
|
41
|
-
Joosy.Router.navigate args...
|
42
|
-
|
43
|
-
#
|
44
|
-
# This is required by {Joosy.Modules.Renderer}
|
45
|
-
# Sets the base template dir to app_name/templates/widgets
|
46
|
-
#
|
47
|
-
__renderSection: ->
|
48
|
-
'widgets'
|
49
|
-
|
50
|
-
#
|
51
|
-
# Widget bootstrap proccess
|
52
|
-
#
|
53
|
-
# * Rendering (if required)
|
54
|
-
# * {Joosy.Modules.Container#refreshElements}
|
55
|
-
# * {Joosy.Modules.Container#__delegateEvents}
|
56
|
-
# * {Joosy.Modules.Filters#__runAfterLoads}
|
57
|
-
#
|
58
|
-
# @param [Joosy.Page, Joosy.Layout] Page or Layout to attach to
|
59
|
-
# @param [jQuery] container Container to attach to
|
60
|
-
#
|
61
|
-
__load: (@parent, @container) ->
|
62
|
-
if @__renderer
|
63
|
-
@container.html @__renderer(@data || {})
|
64
|
-
@refreshElements()
|
65
|
-
@__delegateEvents()
|
66
|
-
@__runAfterLoads()
|
67
|
-
|
68
|
-
this
|
69
|
-
|
70
|
-
#
|
71
|
-
# Layout destruction proccess.
|
72
|
-
#
|
73
|
-
# * {Joosy.Modules.TimeManager#__clearTime}
|
74
|
-
# * {Joosy.Modules.Renderer#__removeMetamorphs}
|
75
|
-
# * {Joosy.Modules.Filters#__runAfterUnloads}
|
76
|
-
#
|
77
|
-
__unload: ->
|
78
|
-
@__clearTime()
|
79
|
-
@__removeMetamorphs()
|
80
|
-
@__runAfterUnloads()
|
@@ -1,169 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Preloader for libraries with localStorage cache
|
3
|
-
#
|
4
|
-
# @note The `start` callback will only be called if loading required.
|
5
|
-
# While working with cache, `complete` is the only callback that will be triggered.
|
6
|
-
#
|
7
|
-
# @example Basic usage
|
8
|
-
# libraries = [['/test1.js', 100], ['/test2.js', 500]] #100, 500 - size in bytes
|
9
|
-
#
|
10
|
-
# CachingPreloader.load libraries,
|
11
|
-
# start: -> console.log 'preloading started'
|
12
|
-
# progress: (percent) -> console.log "#{percent}% loaded"
|
13
|
-
# complete: -> console.log 'preloading finished'
|
14
|
-
#
|
15
|
-
# @module
|
16
|
-
#
|
17
|
-
@CachingPreloader =
|
18
|
-
#
|
19
|
-
# If set to true, localStorage cache will be avoided
|
20
|
-
#
|
21
|
-
force: false
|
22
|
-
|
23
|
-
#
|
24
|
-
# Prefix for localStorage keys
|
25
|
-
#
|
26
|
-
prefix: "cache:"
|
27
|
-
|
28
|
-
#
|
29
|
-
# Number of libraries have been loaded (increases after lib was loaded)
|
30
|
-
#
|
31
|
-
counter: 0
|
32
|
-
|
33
|
-
#
|
34
|
-
# Loads (or takes from cache) set of libraries using xhr and caches them in localStorage
|
35
|
-
# See class description for example of usage
|
36
|
-
#
|
37
|
-
# @param [Array] 2-levels array of libraries URLs i.e. [['/test1.js', 10],['/test2.js', 20]]
|
38
|
-
# Second param of inner level is a size of script in bytes. Can be undefined.
|
39
|
-
# @param [Hash] Available options:
|
40
|
-
# * start: `() -> null` to call before load starts
|
41
|
-
# * progress: `(int percents) -> null` to call each 100ms of load in progress
|
42
|
-
# * complete: `() -> null` to call after load completes
|
43
|
-
#
|
44
|
-
load: (libraries, options={}) ->
|
45
|
-
@[key] = val for key, val of options
|
46
|
-
@libraries = libraries.slice()
|
47
|
-
|
48
|
-
for lib, i in @libraries
|
49
|
-
@libraries[i] = @prefix+lib[0]
|
50
|
-
|
51
|
-
if !@force && @check()
|
52
|
-
@restore()
|
53
|
-
else
|
54
|
-
@start?.call window
|
55
|
-
@clean()
|
56
|
-
@download libraries
|
57
|
-
|
58
|
-
#
|
59
|
-
# Checks if we can load libraries or have to download them over
|
60
|
-
#
|
61
|
-
check: ->
|
62
|
-
flag = true
|
63
|
-
for name, i in @libraries
|
64
|
-
flag &&= window.localStorage.getItem(name)?
|
65
|
-
flag
|
66
|
-
|
67
|
-
#
|
68
|
-
# Escapes non-printable terminal chars before storing to localStorage to prevent IE bug
|
69
|
-
#
|
70
|
-
# @param [String] String, that will be prepared for localStorage
|
71
|
-
#
|
72
|
-
escapeStr: (str) ->
|
73
|
-
str.replace(new RegExp("\u0001", 'g'), "\\u0001").replace(new RegExp("\u000B", 'g'), "\\u000B")
|
74
|
-
|
75
|
-
#
|
76
|
-
# Gets sources of scripts from localStorage and evals them
|
77
|
-
#
|
78
|
-
restore: ->
|
79
|
-
for name, i in @libraries
|
80
|
-
window.evalGlobaly window.localStorage.getItem name
|
81
|
-
@complete?.call window, true
|
82
|
-
|
83
|
-
#
|
84
|
-
# Loads set of libraries using xhr and caches them in localStorage
|
85
|
-
#
|
86
|
-
# @param [Array] 2-levels array of libraries URLs i.e. [['/test1.js', 100],['/test2.js', 500]]
|
87
|
-
# Second param of inner level is a size of script in bytes. Can be undefined.
|
88
|
-
#
|
89
|
-
download: (libraries) ->
|
90
|
-
if libraries.length > 0
|
91
|
-
@counter += 1
|
92
|
-
|
93
|
-
lib = libraries.shift()
|
94
|
-
url = lib[0]
|
95
|
-
size = lib[1]
|
96
|
-
|
97
|
-
@ajax url, size, (xhr) =>
|
98
|
-
code = xhr.responseText
|
99
|
-
if window.navigator.appName == "Microsoft Internet Explorer"
|
100
|
-
code = @escapeStr code
|
101
|
-
window.localStorage.setItem @prefix+url, code
|
102
|
-
window.evalGlobaly xhr.responseText
|
103
|
-
@download libraries
|
104
|
-
else
|
105
|
-
@complete?.call window
|
106
|
-
|
107
|
-
#
|
108
|
-
# Runs XHR request to get single script body
|
109
|
-
# Binds poller to call @progress each 100ms if possible (not IE *doh*)
|
110
|
-
#
|
111
|
-
# @param [String] URL to download from
|
112
|
-
# @param [Float] Expected size of download (to calculate percents)
|
113
|
-
# Size can not be taken from headers since we are supposed to get gziped content
|
114
|
-
# @param [Function] `(xhr) -> null` to call after script was loaded
|
115
|
-
#
|
116
|
-
ajax: (url, size, callback) ->
|
117
|
-
if window.XMLHttpRequest
|
118
|
-
x = new XMLHttpRequest
|
119
|
-
else
|
120
|
-
x = new ActiveXObject 'Microsoft.XMLHTTP'
|
121
|
-
|
122
|
-
x.open 'GET', url, 1
|
123
|
-
|
124
|
-
x.onreadystatechange = () =>
|
125
|
-
if x.readyState > 3
|
126
|
-
clearInterval @interval
|
127
|
-
callback? x
|
128
|
-
|
129
|
-
if @progress
|
130
|
-
poller = =>
|
131
|
-
try
|
132
|
-
@progress.call window, Math.round((x.responseText.length / size) * (@counter / @libraries.length) * 100)
|
133
|
-
catch e
|
134
|
-
# ... IE?
|
135
|
-
|
136
|
-
@interval = setInterval poller, 100
|
137
|
-
|
138
|
-
x.send()
|
139
|
-
|
140
|
-
#
|
141
|
-
# Searches through localStorage for outdated entries with our prefix and removes them
|
142
|
-
#
|
143
|
-
clean: ->
|
144
|
-
i = 0
|
145
|
-
|
146
|
-
find = (arr, obj) ->
|
147
|
-
(return i if obj == x) for x in arr
|
148
|
-
return -1
|
149
|
-
|
150
|
-
while i < window.localStorage.length && key = window.localStorage.key(i)
|
151
|
-
if key.indexOf(@prefix) == 0 && find(@libraries, key) < 0
|
152
|
-
window.localStorage.removeItem key
|
153
|
-
else
|
154
|
-
i += 1
|
155
|
-
|
156
|
-
#
|
157
|
-
# Evals source at a global scope
|
158
|
-
# Don't touch it! It should be window's property, or FF3.6 will execute scripts on preloader context.
|
159
|
-
#
|
160
|
-
# @param [String] JS source to execute
|
161
|
-
#
|
162
|
-
window.evalGlobaly = (src) ->
|
163
|
-
return if src.length == 0
|
164
|
-
if window.execScript
|
165
|
-
window.execScript src
|
166
|
-
else
|
167
|
-
window.eval src
|
168
|
-
|
169
|
-
@Preloader = @CachingPreloader
|
@@ -1,56 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Preloader for libraries using `script src` without any caching magic
|
3
|
-
#
|
4
|
-
# @example Basic usage
|
5
|
-
# libraries = [['/test1.js'], ['/test2.js']]
|
6
|
-
#
|
7
|
-
# InlinePreloader.load libraries,
|
8
|
-
# start: -> console.log 'preloading started'
|
9
|
-
# complete: -> console.log 'preloading finished'
|
10
|
-
#
|
11
|
-
# @module
|
12
|
-
#
|
13
|
-
@InlinePreloader =
|
14
|
-
#
|
15
|
-
# Loads set of libraries by adding `script src` to DOM head
|
16
|
-
# See class description for example of usage
|
17
|
-
#
|
18
|
-
# @param [Array] 2-levels array of libraries URLs i.e. [['/test1.js'],['/test2.js']]
|
19
|
-
# @param [Hash] Available options:
|
20
|
-
# * start: `() -> null` to call before load starts:
|
21
|
-
# * complete: `() -> null` to call after load completes
|
22
|
-
#
|
23
|
-
load: (libraries, options) ->
|
24
|
-
@[key] = val for key, val of options
|
25
|
-
@start?()
|
26
|
-
|
27
|
-
if libraries.length > 0
|
28
|
-
@receive libraries.shift()[0], => @load(libraries)
|
29
|
-
else
|
30
|
-
@complete?()
|
31
|
-
|
32
|
-
#
|
33
|
-
# Loads one script by adding `script src` to DOM head
|
34
|
-
#
|
35
|
-
# @param [String] url to load script from
|
36
|
-
# @param [Function] `() -> null` to call after script was loaded and executed
|
37
|
-
#
|
38
|
-
receive: (url, callback) ->
|
39
|
-
head = document.getElementsByTagName("head")[0]
|
40
|
-
script = document.createElement "script"
|
41
|
-
script.src = url
|
42
|
-
|
43
|
-
done = false
|
44
|
-
|
45
|
-
proceed = ->
|
46
|
-
if !done && (!@readyState? || @readyState == "loaded" || @readyState == "complete")
|
47
|
-
done = true
|
48
|
-
callback?()
|
49
|
-
script.onload = script.onreadystatechange = null
|
50
|
-
|
51
|
-
script.onload = script.onreadystatechange = proceed
|
52
|
-
|
53
|
-
head.appendChild script
|
54
|
-
return undefined
|
55
|
-
|
56
|
-
@Preloader = @InlinePreloader
|
data/lib/joosy.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'rails/generators/joosy/joosy_base'
|
2
|
-
|
3
|
-
module Joosy
|
4
|
-
module Generators
|
5
|
-
class ResourceGenerator < ::Rails::Generators::JoosyBase
|
6
|
-
source_root File.join(File.dirname(__FILE__), 'templates')
|
7
|
-
|
8
|
-
def create_files
|
9
|
-
super
|
10
|
-
|
11
|
-
empty_directory "#{app_path}/resources"
|
12
|
-
template "app/resources/template.js.coffee", "#{app_path}/resources/#{file_name}.js.coffee"
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
def app_path
|
18
|
-
unless class_path.size == 1
|
19
|
-
puts <<HELP
|
20
|
-
Usage: rails generate joosy:resource joosy_app_name/resource_name
|
21
|
-
Tip: resource_name is better to be singular
|
22
|
-
HELP
|
23
|
-
exit 1
|
24
|
-
end
|
25
|
-
class_path[0]
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
Joosy.namespace 'Welcome', ->
|
2
|
-
|
3
|
-
class @IndexPage extends ApplicationPage
|
4
|
-
@layout ApplicationLayout
|
5
|
-
@view 'index'
|
6
|
-
|
7
|
-
@afterLoad ->
|
8
|
-
@startHeartbeat()
|
9
|
-
@content.css
|
10
|
-
'padding-top': "#{$(window).height() / 2 - 160}px"
|
11
|
-
|
12
|
-
elements:
|
13
|
-
content: '#content'
|
14
|
-
joosy: '.joosy'
|
15
|
-
|
16
|
-
events:
|
17
|
-
'mouseover $joosy': -> clearInterval @heartbeat
|
18
|
-
'mouseout $joosy': 'startHeartbeat'
|
19
|
-
|
20
|
-
startHeartbeat: ->
|
21
|
-
@heartbeat = @setInterval 1500, =>
|
22
|
-
@joosy.animate({opacity: 0.8}, 300).animate({opacity: 1}, 300)
|
@@ -1,7 +0,0 @@
|
|
1
|
-
#wrapper
|
2
|
-
#content
|
3
|
-
%h1 Welcome aboard
|
4
|
-
%h2{:style => 'margin-bottom: 30px'} You’re still riding Ruby on Rails.
|
5
|
-
.joosy{:style => 'background: #F71; border-radius: 10px; width: 250px; display: inline-block'}
|
6
|
-
%div{:style => 'color: #FFF; padding: 10px;'}
|
7
|
-
But it's so joosy this time!
|
@@ -1,40 +0,0 @@
|
|
1
|
-
describe "Joosy.Application", ->
|
2
|
-
|
3
|
-
beforeEach ->
|
4
|
-
sinon.stub(Joosy.Router, "__setupRoutes")
|
5
|
-
@seedGround()
|
6
|
-
|
7
|
-
afterEach ->
|
8
|
-
Joosy.Router.__setupRoutes.restore()
|
9
|
-
|
10
|
-
it "should initialize", ->
|
11
|
-
Joosy.Application.initialize 'app', '#application'
|
12
|
-
expect(Joosy.Application.page).toBeUndefined()
|
13
|
-
expect(Joosy.Application.selector).toEqual '#application'
|
14
|
-
expect(Joosy.Application.sandboxSelector).toMatch /#[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}/
|
15
|
-
expect($(Joosy.Application.sandboxSelector).length).toEqual 1
|
16
|
-
expect(Joosy.Router.__setupRoutes.callCount).toEqual 1
|
17
|
-
expect(Joosy.Application.name).toEqual 'app'
|
18
|
-
|
19
|
-
it "should set container", ->
|
20
|
-
expect(Joosy.Application.content()).toEqual $('#application')
|
21
|
-
|
22
|
-
it "should properly initialize and save pages", ->
|
23
|
-
spy = sinon.spy()
|
24
|
-
class Page1
|
25
|
-
constructor: spy
|
26
|
-
class Page2
|
27
|
-
constructor: spy
|
28
|
-
|
29
|
-
Joosy.Application.setCurrentPage(Page1, {foo: 'bar'})
|
30
|
-
|
31
|
-
expect(Joosy.Application.page instanceof Page1).toBeTruthy()
|
32
|
-
expect(spy.callCount).toEqual 1
|
33
|
-
expect(spy.args[0]).toEqual [{foo: 'bar'}, undefined]
|
34
|
-
|
35
|
-
Joosy.Application.setCurrentPage(Page2, {bar: 'baz'})
|
36
|
-
|
37
|
-
expect(Joosy.Application.page instanceof Page2).toBeTruthy()
|
38
|
-
expect(spy.callCount).toEqual 2
|
39
|
-
expect(spy.args[1][0]).toEqual {bar: 'baz'}
|
40
|
-
expect(spy.args[1][1] instanceof Page1).toBeTruthy()
|