shuriken 0.1.0
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.
- data/README.md +36 -0
- data/Rakefile +20 -0
- data/coffeescripts/shuriken/mixins/callbacks.coffee +23 -0
- data/coffeescripts/shuriken/mixins.coffee +41 -0
- data/coffeescripts/shuriken.coffee +127 -0
- data/lib/shuriken.rb +11 -0
- data/shuriken.gemspec +44 -0
- data/wip-coffeescripts/test.coffee +36 -0
- metadata +69 -0
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Shuriken #
|
2
|
+
## Pointy javascript namespace helpers and stuff ##
|
3
|
+
|
4
|
+
Shuriken is a lightweight toolset for Javascript, written in coffeescript
|
5
|
+
that provides a lightweight implementation of namespaces and a few other things
|
6
|
+
(e.g. mixins) that I've found have simplified structured javascript development.
|
7
|
+
|
8
|
+
Using it is as simple as including the shuriken.js in your app and writing your code:
|
9
|
+
|
10
|
+
// declare BHM as a root namespace.
|
11
|
+
var BHM = Shuriken.as('BHM');
|
12
|
+
|
13
|
+
// Should print out true.
|
14
|
+
console.log(BHM instanceof Shuriken.Namespace);
|
15
|
+
|
16
|
+
BHM.withNS('Something', function(ns) {
|
17
|
+
|
18
|
+
ns.hello = true;
|
19
|
+
|
20
|
+
ns.sayHello = function() {
|
21
|
+
if(ns.hello) console.log("Hello there!");
|
22
|
+
};
|
23
|
+
|
24
|
+
ns.setup = function() {
|
25
|
+
ns.sayHello();
|
26
|
+
};
|
27
|
+
|
28
|
+
});
|
29
|
+
|
30
|
+
// On document load, unless BHM.autosetup is false,
|
31
|
+
// BHM.Something.setup() will be automatically called.
|
32
|
+
// Also,
|
33
|
+
BHM.Something.sayHello();
|
34
|
+
// will say hello manually. I'm sure you get the picture by now.
|
35
|
+
|
36
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
require 'lib/shuriken'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = "shuriken"
|
10
|
+
gem.summary = %Q{Simple Namespace support for JS + Other niceties, packaged as a Barista framework}
|
11
|
+
gem.description = %Q{Simple Namespace support for JS + Other niceties, packaged as a Barista framework}
|
12
|
+
gem.email = "sutto@sutto.net"
|
13
|
+
gem.homepage = "http://github.com/Sutto/shuriken"
|
14
|
+
gem.version = Shuriken::VERSION
|
15
|
+
gem.authors = ["Darcy Laycock"]
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Shuriken.defineExtension (baseNS) ->
|
2
|
+
baseNS.defineMixin 'Callbacks', (mixin) ->
|
3
|
+
|
4
|
+
mixin.callbacks: {}
|
5
|
+
|
6
|
+
mixin.defineCallback: (key) ->
|
7
|
+
@["on$key"]: (callback) -> @hasCallback key, callback
|
8
|
+
@["invoke$key"]: (args...) -> @invokeCallbacks key, args...
|
9
|
+
true
|
10
|
+
|
11
|
+
mixin.hasCallback: (name, callback) ->
|
12
|
+
callbacks: mixin.callbacks[name]?= []
|
13
|
+
callbacks.push callback
|
14
|
+
true
|
15
|
+
|
16
|
+
mixin.callbacksFor: (name) ->
|
17
|
+
existing: mixin.callbacks[name]
|
18
|
+
if existing? then existing else []
|
19
|
+
|
20
|
+
mixin.invokeCallbacks: (name, args...) ->
|
21
|
+
for callback in mixin.callbacksFor(name)
|
22
|
+
return false if callback(args...) is false
|
23
|
+
true
|
@@ -0,0 +1,41 @@
|
|
1
|
+
Shuriken.defineExtension (baseNS) ->
|
2
|
+
baseNS.withNS 'Mixins', (ns) ->
|
3
|
+
|
4
|
+
root: @getRootNS()
|
5
|
+
ns.mixins: {}
|
6
|
+
root.mixins: {}
|
7
|
+
|
8
|
+
root.withBase (base) ->
|
9
|
+
base.mixin: (mixins) -> ns.mixin @, mixins
|
10
|
+
|
11
|
+
defineMixin: (key, mixin) ->
|
12
|
+
@mixins[key]: mixin
|
13
|
+
|
14
|
+
root.defineMixin: defineMixin
|
15
|
+
ns.define: defineMixin
|
16
|
+
|
17
|
+
ns.lookupMixin: (mixin) ->
|
18
|
+
switch typeof mixin
|
19
|
+
when "string"
|
20
|
+
if ns.mixins[mixin]?
|
21
|
+
ns.mixins[mixin]
|
22
|
+
else if root.mixins[mixin]?
|
23
|
+
root.mixins[mixin]
|
24
|
+
else
|
25
|
+
{} # unknown mixin, return a blank object.
|
26
|
+
else
|
27
|
+
mixin
|
28
|
+
|
29
|
+
ns.invokeMixin: (scope, mixin) ->
|
30
|
+
switch typeof mixin
|
31
|
+
when "string"
|
32
|
+
ns.invokeMixin scope, ns.lookupMixin(mixin)
|
33
|
+
when "function"
|
34
|
+
mixin.call scope, scope
|
35
|
+
when "object"
|
36
|
+
$.extend scope, mixin
|
37
|
+
|
38
|
+
ns.mixin: (scope, mixins) ->
|
39
|
+
mixins: [mixins] unless $.isArray mixins
|
40
|
+
ns.invokeMixin scope, ns.lookupMixin(mixin) for mixin in mixins
|
41
|
+
true
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# First off, add our dataAttr extensions.
|
2
|
+
if jQuery?
|
3
|
+
(($) ->
|
4
|
+
stringToDataKey: (key) -> "data-$key".replace /_/g, '-'
|
5
|
+
$.fn.dataAttr: (key, value) -> @attr stringToDataKey(key), value
|
6
|
+
$.fn.removeDataAttr: (key) -> @removeAttr stringToDataKey(key)
|
7
|
+
$.fn.hasDataAttr: (key) -> @is "[${stringToDataKey(key)}]"
|
8
|
+
$.getMeta: (key) -> $("meta[name='$key']").attr "content"
|
9
|
+
)(jQuery)
|
10
|
+
|
11
|
+
|
12
|
+
Shuriken: {
|
13
|
+
Base: {}
|
14
|
+
Util: {}
|
15
|
+
jsPathPrefix: "/javascripts/"
|
16
|
+
jsPathSuffix: ""
|
17
|
+
namespaces: {},
|
18
|
+
extensions: []
|
19
|
+
}
|
20
|
+
|
21
|
+
Shuriken.Util.underscoreize: (s) ->
|
22
|
+
s.replace(/\./g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/-/g, '_').toLowerCase()
|
23
|
+
|
24
|
+
Shuriken.Util.scopedClosure: (closure, scope) ->
|
25
|
+
closure.call scope, scope if $.isFunction closure
|
26
|
+
|
27
|
+
|
28
|
+
# Base is the prototype for all namespaces.
|
29
|
+
base: Shuriken.Base
|
30
|
+
|
31
|
+
base.hasChildNamespace: (child) ->
|
32
|
+
@children.push child
|
33
|
+
|
34
|
+
base.toNSName: (children...) ->
|
35
|
+
parts: children
|
36
|
+
current: @
|
37
|
+
while current.parent?
|
38
|
+
parts.unshift parts
|
39
|
+
current: current.parent
|
40
|
+
parts.join "."
|
41
|
+
|
42
|
+
base.getNS: (namespace) ->
|
43
|
+
parts: key.split "."
|
44
|
+
currentNS: @
|
45
|
+
for name in parts
|
46
|
+
return unless currentNS[name]?
|
47
|
+
currentNS = currentNS[name]
|
48
|
+
currentNS
|
49
|
+
|
50
|
+
base.getRootNS: ->
|
51
|
+
current: @
|
52
|
+
current: current.parent while current.parent?
|
53
|
+
current
|
54
|
+
|
55
|
+
base.hasNS: (namespace) ->
|
56
|
+
@getNS(namespace)?
|
57
|
+
|
58
|
+
base.withNS: (key, initializer) ->
|
59
|
+
parts: key.split "."
|
60
|
+
currentNS: @
|
61
|
+
for name in parts
|
62
|
+
currentNS[name] = makeNS(name, currentNS, @baseNS) if not currentNS[name]?
|
63
|
+
currentNS: currentNS[name]
|
64
|
+
hadSetup: $.isFunction currentNS.setup
|
65
|
+
Shuriken.Util.scopedClosure initializer, currentNS
|
66
|
+
currentNS.setupVia currentNS.setup if not hadSetup and $.isFunction currentNS.setup
|
67
|
+
currentNS
|
68
|
+
|
69
|
+
base.withBase: (closure) ->
|
70
|
+
Shuriken.Util.scopedClosure closure, @baseNS
|
71
|
+
|
72
|
+
base.isRoot: ->
|
73
|
+
not @parent?
|
74
|
+
|
75
|
+
base.log: (args...) ->
|
76
|
+
console.log "[${@toNSName()}]", args...
|
77
|
+
|
78
|
+
base.debug: (args...) ->
|
79
|
+
console.log "[Debug - ${@toNSName()}]", args...
|
80
|
+
|
81
|
+
base.setupVia: (f) ->
|
82
|
+
$(document).ready => Shuriken.Util.scopedClosure(f, @) if @autosetup?
|
83
|
+
|
84
|
+
base.require: (key, callback) ->
|
85
|
+
ns: @getNS key
|
86
|
+
if ns?
|
87
|
+
Shuriken.Util.scopedClosure callback, ns
|
88
|
+
else
|
89
|
+
path: Shuriken.Util.underscoreize "${@toNSName()}.$key"
|
90
|
+
url: "${Shuriken.jsPathPrefix}${path}.js${Shuriken.jsPathSuffix}"
|
91
|
+
script: $ "<script />", {type: "text/javascript", src: url}
|
92
|
+
script.load -> Shuriken.Util.scopedClosure callback, @getNS(key)
|
93
|
+
script.appendTo $ "head"
|
94
|
+
|
95
|
+
base.autosetup: true
|
96
|
+
|
97
|
+
# Used as a part of the prototype chain.
|
98
|
+
Shuriken.Namespace: ->
|
99
|
+
Shuriken.Namespace.prototype = Shuriken.Base;
|
100
|
+
|
101
|
+
makeNS: (name, parent, sharedPrototype) ->
|
102
|
+
sharedPrototype?= new Shuriken.Namespace()
|
103
|
+
namespace: ->
|
104
|
+
@name: name
|
105
|
+
@parent: parent
|
106
|
+
@baseNS: sharedPrototype
|
107
|
+
@children: []
|
108
|
+
parent.hasChildNamespace(@) if parent?
|
109
|
+
@
|
110
|
+
namespace.prototype: sharedPrototype
|
111
|
+
new namespace name, parent
|
112
|
+
|
113
|
+
Shuriken.defineExtension: (closure) ->
|
114
|
+
for namespace in Shuriken.namespaces
|
115
|
+
console.log namespace
|
116
|
+
Shuriken.Util.scopedClosure closure, namespace
|
117
|
+
Shuriken.extensions.push closure
|
118
|
+
|
119
|
+
Shuriken.as: (name) ->
|
120
|
+
ns: makeNS name
|
121
|
+
Shuriken.namespaces[name]: ns
|
122
|
+
Shuriken.root[name]: ns
|
123
|
+
Shuriken.Util.scopedClosure extension, ns for extension in Shuriken.extensions
|
124
|
+
ns
|
125
|
+
|
126
|
+
Shuriken.root: @
|
127
|
+
@['Shuriken'] = Shuriken
|
data/lib/shuriken.rb
ADDED
data/shuriken.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{shuriken}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Darcy Laycock"]
|
12
|
+
s.date = %q{2010-05-03}
|
13
|
+
s.description = %q{Simple Namespace support for JS + Other niceties, packaged as a Barista framework}
|
14
|
+
s.email = %q{sutto@sutto.net}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"README.md",
|
20
|
+
"Rakefile",
|
21
|
+
"coffeescripts/shuriken.coffee",
|
22
|
+
"coffeescripts/shuriken/mixins.coffee",
|
23
|
+
"coffeescripts/shuriken/mixins/callbacks.coffee",
|
24
|
+
"lib/shuriken.rb",
|
25
|
+
"shuriken.gemspec",
|
26
|
+
"wip-coffeescripts/test.coffee"
|
27
|
+
]
|
28
|
+
s.homepage = %q{http://github.com/Sutto/shuriken}
|
29
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
30
|
+
s.require_paths = ["lib"]
|
31
|
+
s.rubygems_version = %q{1.3.6}
|
32
|
+
s.summary = %q{Simple Namespace support for JS + Other niceties, packaged as a Barista framework}
|
33
|
+
|
34
|
+
if s.respond_to? :specification_version then
|
35
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
36
|
+
s.specification_version = 3
|
37
|
+
|
38
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
39
|
+
else
|
40
|
+
end
|
41
|
+
else
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Shuriken.Test = {}
|
2
|
+
|
3
|
+
((test) ->
|
4
|
+
|
5
|
+
class test.Context
|
6
|
+
|
7
|
+
constructor: (name) ->
|
8
|
+
@name: name
|
9
|
+
@blocks: {}
|
10
|
+
|
11
|
+
blocksFor: (name) ->
|
12
|
+
@blocks[name]?= []
|
13
|
+
|
14
|
+
invokeBlocksFor: (name) ->
|
15
|
+
block() for block in @blocksFor name
|
16
|
+
|
17
|
+
run: ->
|
18
|
+
@invokeBlocksFor "beforeAll"
|
19
|
+
for test in blocksFor "tests"
|
20
|
+
@invokeBlocksFor "setup"
|
21
|
+
test.run()
|
22
|
+
@invokeBlocksFor "teardown"
|
23
|
+
@invokeBlocksFor "afterAll"
|
24
|
+
|
25
|
+
class test.Test
|
26
|
+
|
27
|
+
constructor: (name, body) ->
|
28
|
+
@name: name
|
29
|
+
@body: body
|
30
|
+
|
31
|
+
run: ->
|
32
|
+
@body()
|
33
|
+
"Passed"
|
34
|
+
|
35
|
+
|
36
|
+
)(Shuriken.Test)
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shuriken
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Darcy Laycock
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-03 00:00:00 +08:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Simple Namespace support for JS + Other niceties, packaged as a Barista framework
|
22
|
+
email: sutto@sutto.net
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README.md
|
29
|
+
files:
|
30
|
+
- README.md
|
31
|
+
- Rakefile
|
32
|
+
- coffeescripts/shuriken.coffee
|
33
|
+
- coffeescripts/shuriken/mixins.coffee
|
34
|
+
- coffeescripts/shuriken/mixins/callbacks.coffee
|
35
|
+
- lib/shuriken.rb
|
36
|
+
- shuriken.gemspec
|
37
|
+
- wip-coffeescripts/test.coffee
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/Sutto/shuriken
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.3.6
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: Simple Namespace support for JS + Other niceties, packaged as a Barista framework
|
68
|
+
test_files: []
|
69
|
+
|