goat 0.1.6 → 0.2.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/lib/goat.rb +276 -77
- data/lib/goat/goat.js +64 -4
- data/lib/goat/notifications.rb +1 -1
- metadata +4 -4
data/lib/goat.rb
CHANGED
@@ -6,7 +6,7 @@ require 'thin'
|
|
6
6
|
require 'term/ansicolor'
|
7
7
|
require 'tilt'
|
8
8
|
|
9
|
-
%w{logger notifications extn html}.each do |file|
|
9
|
+
%w{logger notifications extn html static autobind}.each do |file|
|
10
10
|
require File.join(File.dirname(__FILE__), 'goat', file)
|
11
11
|
end
|
12
12
|
|
@@ -50,6 +50,29 @@ class Object
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
module Kernel
|
54
|
+
# from http://redcorundum.blogspot.com/2006/05/kernelqualifiedconstget.html
|
55
|
+
def fetch_class(str)
|
56
|
+
path = str.to_s.split('::')
|
57
|
+
from_root = path[0].empty?
|
58
|
+
if from_root
|
59
|
+
from_root = []
|
60
|
+
path = path[1..-1]
|
61
|
+
else
|
62
|
+
start_ns = ((Class === self)||(Module === self)) ? self : self.class
|
63
|
+
from_root = start_ns.to_s.split('::')
|
64
|
+
end
|
65
|
+
until from_root.empty?
|
66
|
+
begin
|
67
|
+
return (from_root+path).inject(Object) { |ns,name| ns.const_get(name) }
|
68
|
+
rescue NameError
|
69
|
+
from_root.delete_at(-1)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
path.inject(Object) { |ns,name| ns.const_get(name) }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
53
76
|
class Set
|
54
77
|
def glimpse(n=100)
|
55
78
|
"#<Set: #{self.map{|x| x.glimpse(n)}.join(', ')}>"
|
@@ -101,11 +124,11 @@ module Goat
|
|
101
124
|
end
|
102
125
|
|
103
126
|
def self.load_all(dir_fragment)
|
104
|
-
dir = File.join(
|
127
|
+
dir = File.join(Goat.setting!(:root), dir_fragment)
|
105
128
|
if File.directory?(dir)
|
106
129
|
Dir.entries(dir).select{|f| f =~ /\.rb$/}.each {|f| require(File.join(dir, f))}
|
107
130
|
end
|
108
|
-
end
|
131
|
+
end
|
109
132
|
|
110
133
|
@settings = {}
|
111
134
|
def self.setting(opt)
|
@@ -135,6 +158,10 @@ module Goat
|
|
135
158
|
Goat.extend_mongo if Goat.setting(:mongo)
|
136
159
|
Goat.extend_sinatra if Goat.setting(:sinatra)
|
137
160
|
|
161
|
+
if p = Goat.setting(:press)
|
162
|
+
Goat::Static.press = p
|
163
|
+
end
|
164
|
+
|
138
165
|
if Goat.setting(:debug)
|
139
166
|
if defined?(Thin)
|
140
167
|
Thin::Logging.debug = true
|
@@ -147,7 +174,7 @@ module Goat
|
|
147
174
|
end
|
148
175
|
|
149
176
|
def self.rack_builder(app)
|
150
|
-
Rack::Builder.new do
|
177
|
+
Rack::Builder.new do
|
151
178
|
if cookies = Goat.setting(:cookies)
|
152
179
|
use Rack::Session::Cookie, cookies
|
153
180
|
end
|
@@ -156,9 +183,12 @@ module Goat
|
|
156
183
|
use Rack::Static, :urls => static.fetch(:urls), :root => static.fetch(:root)
|
157
184
|
end
|
158
185
|
|
159
|
-
use Rack::CommonLogger
|
160
186
|
use Rack::Flash if defined?(Rack::Flash) # TODO hack
|
161
187
|
|
188
|
+
if Goat.setting(:reload_files)
|
189
|
+
use Rack::Reloader
|
190
|
+
end
|
191
|
+
|
162
192
|
run app
|
163
193
|
end
|
164
194
|
end
|
@@ -347,14 +377,62 @@ module Goat
|
|
347
377
|
end
|
348
378
|
end
|
349
379
|
|
350
|
-
module
|
380
|
+
module HTMLHelpers
|
381
|
+
include Rack::Utils
|
382
|
+
alias_method :h, :escape_html
|
383
|
+
alias_method :e, :escape # for URIs
|
384
|
+
|
385
|
+
def jsesc(x); x.gsub('\\', '\\\\\\').gsub('"', '\"'); end
|
386
|
+
end
|
387
|
+
|
388
|
+
module FlashHelper
|
389
|
+
def flash
|
390
|
+
request.env['x-rack.flash']
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
class ERBRunner
|
395
|
+
include HTMLHelpers
|
396
|
+
include FlashHelper
|
397
|
+
|
398
|
+
def initialize(req, resp, params)
|
399
|
+
@request = req
|
400
|
+
@response = resp
|
401
|
+
@params = params
|
402
|
+
end
|
403
|
+
|
404
|
+
attr_reader :request, :response, :params
|
405
|
+
attr_accessor :delegate
|
406
|
+
|
407
|
+
def take_delegate_ivars
|
408
|
+
@delegate.instance_variables.each do |ivar|
|
409
|
+
unless self.instance_variables.include?(ivar)
|
410
|
+
self.instance_variable_set(ivar, @delegate.instance_variable_get(ivar))
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
def method_missing(meth, *args)
|
416
|
+
if @delegate
|
417
|
+
@delegate.send(meth, *args)
|
418
|
+
else
|
419
|
+
super
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
351
423
|
def erb(name, opts={}, &blk)
|
424
|
+
take_delegate_ivars if @delegate
|
425
|
+
|
352
426
|
opts = {
|
353
427
|
:partial => false,
|
354
428
|
:layout => true,
|
355
|
-
:locals =>
|
429
|
+
:locals => {}
|
356
430
|
}.merge(opts)
|
357
431
|
|
432
|
+
if self.kind_of?(Page)
|
433
|
+
opts[:locals][:page] ||= self
|
434
|
+
end
|
435
|
+
|
358
436
|
partial = opts[:partial]
|
359
437
|
use_layout = opts[:layout]
|
360
438
|
locals = opts[:locals]
|
@@ -392,8 +470,8 @@ module Goat
|
|
392
470
|
def partial_erb(name, opts={})
|
393
471
|
erb(name, {:partial => true}.merge(opts))
|
394
472
|
end
|
395
|
-
end
|
396
|
-
|
473
|
+
end
|
474
|
+
|
397
475
|
module AppHelpers
|
398
476
|
def halt
|
399
477
|
raise Halt.new(response)
|
@@ -413,13 +491,7 @@ module Goat
|
|
413
491
|
c.processed_html
|
414
492
|
end
|
415
493
|
end
|
416
|
-
|
417
|
-
module FlashHelper
|
418
|
-
def flash
|
419
|
-
request.env['x-rack.flash']
|
420
|
-
end
|
421
|
-
end
|
422
|
-
|
494
|
+
|
423
495
|
class IndifferentHash < Hash
|
424
496
|
def self.from_hash(hash)
|
425
497
|
ih = self.new
|
@@ -442,14 +514,6 @@ module Goat
|
|
442
514
|
end
|
443
515
|
end
|
444
516
|
|
445
|
-
module HTMLHelpers
|
446
|
-
include Rack::Utils
|
447
|
-
alias_method :h, :escape_html
|
448
|
-
alias_method :e, :escape # for URIs
|
449
|
-
|
450
|
-
def jsesc(x); x.gsub('\\', '\\\\\\').gsub('"', '\"'); end
|
451
|
-
end
|
452
|
-
|
453
517
|
class App
|
454
518
|
class << self
|
455
519
|
|
@@ -458,7 +522,7 @@ module Goat
|
|
458
522
|
@@not_found_handler = nil
|
459
523
|
@@active_pages = {}
|
460
524
|
@@active_page_queue = Queue.new
|
461
|
-
@@before_handlers = []
|
525
|
+
@@before_handlers = []
|
462
526
|
|
463
527
|
def active_pages; @@active_pages; end
|
464
528
|
def active_page_queue; @@active_page_queue; end
|
@@ -587,6 +651,24 @@ module Goat
|
|
587
651
|
end
|
588
652
|
end
|
589
653
|
|
654
|
+
def handle_rpc(app)
|
655
|
+
req = app.request
|
656
|
+
|
657
|
+
c = req['_component']
|
658
|
+
id = req['_id']
|
659
|
+
rpc = req['_rpc']
|
660
|
+
|
661
|
+
if comp = Goat.rpc_handlers[c]
|
662
|
+
if comp[rpc]
|
663
|
+
resp = app.respond_with_hook("rpc_#{rpc}", req.params)
|
664
|
+
resp[2] = resp[2].to_json
|
665
|
+
return resp
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
[500, {}, {'success' => false}.to_json]
|
670
|
+
end
|
671
|
+
|
590
672
|
def error(&blk)
|
591
673
|
@@error_handler = blk
|
592
674
|
end
|
@@ -600,7 +682,7 @@ module Goat
|
|
600
682
|
def not_found_handler; @@not_found_handler; end
|
601
683
|
|
602
684
|
end # end class << self
|
603
|
-
|
685
|
+
|
604
686
|
def self.call(env)
|
605
687
|
# TODO better place to put this?
|
606
688
|
NotificationCenter.init # will do nothing if not enabled
|
@@ -610,12 +692,10 @@ module Goat
|
|
610
692
|
self.req_handler.handle_request(env)
|
611
693
|
end
|
612
694
|
|
613
|
-
include ERBHelper
|
614
|
-
include FlashHelper
|
615
695
|
include AppHelpers
|
616
696
|
|
617
|
-
def self.bind(hook)
|
618
|
-
mname = String.random
|
697
|
+
def self.bind(hook, name=nil)
|
698
|
+
mname = name || String.random
|
619
699
|
|
620
700
|
lambda do |app, *args|
|
621
701
|
kls = app.class
|
@@ -647,9 +727,16 @@ module Goat
|
|
647
727
|
response.finish
|
648
728
|
end
|
649
729
|
|
730
|
+
def erb(name, opts={}, &blk)
|
731
|
+
e = ERBRunner.new(@req, @response, @params)
|
732
|
+
e.delegate = self
|
733
|
+
e.erb(name, {:locals => {:page => nil}}.merge(opts), &blk)
|
734
|
+
end
|
735
|
+
|
650
736
|
map :path => '/channel', :metal => true, :hook => lambda {|app| handle_channel(app.request)}
|
651
737
|
map :path => '/post', :metal => true, :hook => lambda {|app| handle_post(app.request) }
|
652
738
|
map :path => '/dispatch', :metal => true, :hook => lambda {|app| handle_dispatch(app.request) }
|
739
|
+
map :path => '/rpc', :method => :post, :metal => true, :hook => lambda {|app| handle_rpc(app)}
|
653
740
|
end
|
654
741
|
|
655
742
|
class Channel
|
@@ -666,6 +753,8 @@ module Goat
|
|
666
753
|
@emchannel.push(msg)
|
667
754
|
end
|
668
755
|
end
|
756
|
+
|
757
|
+
def self.rpc_handlers; @rpc_handlers ||= {}; end
|
669
758
|
|
670
759
|
class Page
|
671
760
|
attr_reader :canvas, :request, :id, :canvas, :layout, :params, :channel
|
@@ -676,14 +765,12 @@ module Goat
|
|
676
765
|
def self.enable_live_updates; @live_updates = true; end
|
677
766
|
def self.live_updates_enabled?; @live_updates != false; end
|
678
767
|
|
679
|
-
include ERBHelper
|
680
|
-
include HTMLHelpers
|
681
768
|
include FlashHelper
|
682
769
|
|
683
|
-
alias_method :old_erb, :erb
|
684
|
-
|
685
770
|
def erb(name, opts={}, &blk)
|
686
|
-
|
771
|
+
e = ERBRunner.new(@request, @response, @params)
|
772
|
+
e.delegate = self
|
773
|
+
e.erb(name, {:partial => false}.merge(opts), &blk)
|
687
774
|
end
|
688
775
|
|
689
776
|
def self.handle_request(app)
|
@@ -740,31 +827,89 @@ module Goat
|
|
740
827
|
components.each(&:mark_alive!)
|
741
828
|
end
|
742
829
|
|
830
|
+
class CanvasDistiller
|
831
|
+
def initialize(canvas)
|
832
|
+
@canvas = canvas
|
833
|
+
end
|
834
|
+
|
835
|
+
def all_component_classes
|
836
|
+
comp_classes = Set.new
|
837
|
+
@canvas.all_components.map(&:class).uniq.map do |cls|
|
838
|
+
c = cls
|
839
|
+
|
840
|
+
while c
|
841
|
+
if c == Object
|
842
|
+
raise "Error traversing class hierarchy to find necessary JS"
|
843
|
+
end
|
844
|
+
|
845
|
+
comp_classes << c
|
846
|
+
|
847
|
+
if c == Component
|
848
|
+
break
|
849
|
+
else
|
850
|
+
c = c.superclass
|
851
|
+
end
|
852
|
+
end
|
853
|
+
end
|
854
|
+
|
855
|
+
comp_classes
|
856
|
+
end
|
857
|
+
|
858
|
+
def script
|
859
|
+
cs = all_component_classes.to_a.reject do |cls|
|
860
|
+
Goat.setting(:press) && Goat::Static.pressed?(cls)
|
861
|
+
end
|
862
|
+
|
863
|
+
i = 0
|
864
|
+
# invariant: left of i has no superclasses to right
|
865
|
+
while i < cs.size
|
866
|
+
c = cs[i]
|
867
|
+
if cs[(i+1)..-1].any?{|sup| c.kind_of?(sup)}
|
868
|
+
cs.delete(c)
|
869
|
+
cs << c
|
870
|
+
else
|
871
|
+
i += 1
|
872
|
+
end
|
873
|
+
end
|
874
|
+
|
875
|
+
[
|
876
|
+
cs.map(&:__script),
|
877
|
+
@canvas.all_components.select{|c| c.class.wired?}.map(&:wire_script),
|
878
|
+
@canvas.all_components.map(&:__script)
|
879
|
+
].flatten.compact.join(';')
|
880
|
+
end
|
881
|
+
|
882
|
+
def style
|
883
|
+
@canvas.all_components.map(&:class).uniq.select(&:__css).map(&:scoped_css).join
|
884
|
+
end
|
885
|
+
end
|
886
|
+
|
743
887
|
def html
|
744
888
|
layout = self.layout
|
745
889
|
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
body = @canvas.body.map do |item|
|
890
|
+
distiller = CanvasDistiller.new(@canvas)
|
891
|
+
html = nil
|
892
|
+
|
893
|
+
if @canvas.erb
|
894
|
+
html = self.erb(@canvas.erb, :layout => false)
|
895
|
+
elsif !@canvas.body.empty?
|
896
|
+
html = (@canvas.body.map do |item|
|
754
897
|
if item.kind_of?(Component)
|
755
|
-
"<style>#{item.processed_css}</style>" +
|
756
898
|
item.processed_html
|
757
899
|
elsif item.kind_of?(String)
|
758
900
|
item
|
759
901
|
else
|
760
902
|
raise "Unknown body item: #{item.inspect}"
|
761
903
|
end
|
762
|
-
end
|
763
|
-
|
764
|
-
render_to_layout(body.join, layout)
|
904
|
+
end).join
|
765
905
|
else
|
766
906
|
raise "You can define an erb or append to the body, but not both"
|
767
907
|
end
|
908
|
+
|
909
|
+
@canvas.style << distiller.style
|
910
|
+
@canvas.script << distiller.script
|
911
|
+
|
912
|
+
render_to_layout(html, layout)
|
768
913
|
end
|
769
914
|
|
770
915
|
def render_component(c)
|
@@ -789,19 +934,21 @@ module Goat
|
|
789
934
|
end
|
790
935
|
|
791
936
|
class PageCanvas
|
792
|
-
attr_accessor :body, :title, :components, :erb
|
937
|
+
attr_accessor :body, :title, :components, :erb, :script, :style
|
793
938
|
|
794
939
|
def initialize
|
795
940
|
@body = []
|
796
941
|
@components = []
|
942
|
+
@script = []
|
943
|
+
@style = []
|
797
944
|
end
|
798
945
|
|
799
|
-
def
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
946
|
+
def flattened_style; @style.join; end
|
947
|
+
def flattened_script; @script.join; end
|
948
|
+
|
949
|
+
def all_components
|
950
|
+
cs = body.empty? ? @components : @body.select{|c| c.kind_of?(Component)}
|
951
|
+
cs.map(&:all_components).flatten
|
805
952
|
end
|
806
953
|
end
|
807
954
|
|
@@ -809,9 +956,8 @@ module Goat
|
|
809
956
|
attr_reader :id, :handlers, :page, :params
|
810
957
|
|
811
958
|
include HTMLHelpers # sure just shit it in with everything else
|
812
|
-
include ERBHelper
|
813
959
|
|
814
|
-
def initialize(page)
|
960
|
+
def initialize(page)
|
815
961
|
@id = String.random(10, :alpha => true)
|
816
962
|
@page = page
|
817
963
|
@callbacks = {}
|
@@ -819,6 +965,14 @@ module Goat
|
|
819
965
|
@dead = false
|
820
966
|
end
|
821
967
|
|
968
|
+
def erb(*args, &blk)
|
969
|
+
ERBRunner.new(@page.request, nil, @params).erb(*args, &blk)
|
970
|
+
end
|
971
|
+
|
972
|
+
def partial_erb(*args, &blk)
|
973
|
+
ERBRunner.new(@page.request, nil, @params).partial_erb(*args, &blk)
|
974
|
+
end
|
975
|
+
|
822
976
|
def halt; @page.halt; end
|
823
977
|
|
824
978
|
def channel; @page.channel; end
|
@@ -871,35 +1025,72 @@ module Goat
|
|
871
1025
|
c = @callbacks[k].call
|
872
1026
|
c[:target].send(c[:method], *c[:args])
|
873
1027
|
end
|
874
|
-
|
875
|
-
def
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
1028
|
+
|
1029
|
+
def self.script(script); @script = AutoBind.process(script); end
|
1030
|
+
def script(script); @script = AutoBind.process(script); end
|
1031
|
+
def self.__script; @script; end
|
1032
|
+
def __script; @script; end
|
1033
|
+
|
1034
|
+
def wire_script
|
1035
|
+
"Goat.wireComponent('#{id}', #{clientside_instance})"
|
881
1036
|
end
|
882
|
-
|
1037
|
+
|
1038
|
+
def self.css(css); @css = css; end
|
1039
|
+
def css(css); @css = css; end
|
1040
|
+
def self.__css; @css; end
|
1041
|
+
def __css; @css; end
|
1042
|
+
|
1043
|
+
def self.clientside(js)
|
1044
|
+
script(js)
|
1045
|
+
@wired = true
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
def self.wired?; @wired; end
|
1049
|
+
|
1050
|
+
def clientside_args; []; end
|
1051
|
+
|
1052
|
+
def clientside_instance
|
1053
|
+
args = [id, *clientside_args].to_json[1..-2]
|
1054
|
+
"new #{self.class.name}('#{self.class.name}', #{args})"
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
def self.rpc(name, &blk)
|
1058
|
+
Goat.rpc_handlers[self.name.to_s] ||= {}
|
1059
|
+
Goat.rpc_handlers[self.name.to_s][name.to_s] = true
|
1060
|
+
|
1061
|
+
App.send(:define_method, "rpc_#{name}", blk)
|
1062
|
+
end
|
1063
|
+
|
883
1064
|
def component(body)
|
884
|
-
[:div, {:id => id},
|
885
|
-
[:script, js],
|
886
|
-
body
|
887
|
-
]
|
1065
|
+
[:div, {:id => id, :class => self.class.name}, body]
|
888
1066
|
end
|
889
1067
|
|
890
1068
|
def html; make_me; end
|
891
|
-
def css; ''; end
|
892
1069
|
|
893
1070
|
def processed_html
|
894
|
-
HTMLBuilder.new(self, component(self.html)).html
|
1071
|
+
HTMLBuilder.new(self, component(self.html)).html + \
|
1072
|
+
(__css ? "<style>#{scoped_css}</style>" : '')
|
895
1073
|
end
|
896
|
-
|
897
|
-
def
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
1074
|
+
|
1075
|
+
def self.scope_css(css, prefix, dot_or_hash)
|
1076
|
+
# #%foo, .%bar, etc
|
1077
|
+
rep = css.gsub(/(.)%(\w+)([\ \t\{])/) do |str|
|
1078
|
+
p = $1
|
1079
|
+
m = $2
|
1080
|
+
ws = $3
|
1081
|
+
"#{p}#{prefix}_#{m}#{ws}"
|
902
1082
|
end
|
1083
|
+
rep.gsub(/(^|\W)%([\W\{])/) do |str|
|
1084
|
+
"#{$1}#{dot_or_hash}#{prefix}#{$2}"
|
1085
|
+
end
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
def self.scoped_css
|
1089
|
+
scope_css(self.__css, self.name, '.')
|
1090
|
+
end
|
1091
|
+
|
1092
|
+
def scoped_css
|
1093
|
+
self.class.scope_css(self.__css, @id, '#')
|
903
1094
|
end
|
904
1095
|
|
905
1096
|
def model_changed(item, notif)
|
@@ -916,9 +1107,17 @@ module Goat
|
|
916
1107
|
# end
|
917
1108
|
end
|
918
1109
|
|
1110
|
+
def children; []; end
|
1111
|
+
|
919
1112
|
def all_components
|
920
|
-
[self]
|
1113
|
+
[self] + self.children
|
1114
|
+
end
|
1115
|
+
|
1116
|
+
def to_html(builder, comp)
|
1117
|
+
processed_html # for html.rb
|
921
1118
|
end
|
1119
|
+
|
1120
|
+
script File.read(File.join(File.dirname(__FILE__), 'goat/js/component.js'))
|
922
1121
|
end
|
923
1122
|
|
924
1123
|
class Model
|
data/lib/goat/goat.js
CHANGED
@@ -92,7 +92,7 @@ $.extend(Goat, {
|
|
92
92
|
},
|
93
93
|
|
94
94
|
reopenChannel: function() {
|
95
|
-
console.
|
95
|
+
console.log("reopenChannel()");
|
96
96
|
var fails = this.channelOpenFails;
|
97
97
|
setTimeout(function() { Goat.openChannel(); }, (fails > 20) ? 20000 : (fails * 500));
|
98
98
|
this.channelOpenFails++;
|
@@ -160,13 +160,73 @@ $.extend(Goat, {
|
|
160
160
|
|
161
161
|
return false;
|
162
162
|
},
|
163
|
-
|
164
|
-
|
165
|
-
this.components[id] =
|
163
|
+
|
164
|
+
wireComponent: function(id, obj) {
|
165
|
+
this.components[id] = obj;
|
166
166
|
}
|
167
167
|
});
|
168
168
|
|
169
|
+
(function(){
|
170
|
+
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
171
|
+
// The base Class implementation (does nothing)
|
172
|
+
this.Class = function(){};
|
173
|
+
|
174
|
+
// Create a new Class that inherits from this class
|
175
|
+
Class.extend = function(prop) {
|
176
|
+
var _super = this.prototype;
|
177
|
+
|
178
|
+
// Instantiate a base class (but only create the instance,
|
179
|
+
// don't run the init constructor)
|
180
|
+
initializing = true;
|
181
|
+
var prototype = new this();
|
182
|
+
initializing = false;
|
183
|
+
|
184
|
+
// Copy the properties over onto the new prototype
|
185
|
+
for (var name in prop) {
|
186
|
+
// Check if we're overwriting an existing function
|
187
|
+
prototype[name] = typeof prop[name] == "function" &&
|
188
|
+
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
|
189
|
+
(function(name, fn){
|
190
|
+
return function() {
|
191
|
+
var tmp = this._super;
|
192
|
+
|
193
|
+
// Add a new ._super() method that is the same method
|
194
|
+
// but on the super-class
|
195
|
+
this._super = _super[name];
|
196
|
+
|
197
|
+
// The method only need to be bound temporarily, so we
|
198
|
+
// remove it when we're done executing
|
199
|
+
var ret = fn.apply(this, arguments);
|
200
|
+
this._super = tmp;
|
201
|
+
|
202
|
+
return ret;
|
203
|
+
};
|
204
|
+
})(name, prop[name]) :
|
205
|
+
prop[name];
|
206
|
+
}
|
207
|
+
|
208
|
+
// The dummy class constructor
|
209
|
+
function Class() {
|
210
|
+
// All construction is actually done in the init method
|
211
|
+
if ( !initializing && this.init )
|
212
|
+
this.init.apply(this, arguments);
|
213
|
+
}
|
214
|
+
|
215
|
+
// Populate our constructed prototype object
|
216
|
+
Class.prototype = prototype;
|
217
|
+
|
218
|
+
// Enforce the constructor to be what we expect
|
219
|
+
Class.constructor = Class;
|
220
|
+
|
221
|
+
// And make this class extendable
|
222
|
+
Class.extend = arguments.callee;
|
223
|
+
|
224
|
+
return Class;
|
225
|
+
};
|
226
|
+
})();
|
227
|
+
|
169
228
|
$(document).ready(function() {
|
229
|
+
$.each(Goat.components, function(_, c) { c.onLoad(); });
|
170
230
|
setTimeout(function() { if(Goat.page_id) Goat.openChannel(); }, 1);
|
171
231
|
});
|
172
232
|
|
data/lib/goat/notifications.rb
CHANGED
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Patrick Collison
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-09-
|
18
|
+
date: 2010-09-20 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|