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