parlement 0.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +26 -0
- data/README +2 -1
- data/app/controllers/account_controller.rb +27 -18
- data/app/controllers/application.rb +1 -3
- data/app/controllers/elt_controller.rb +92 -42
- data/app/helpers/elt_helper.rb +7 -18
- data/app/models/elt.rb +76 -22
- data/app/models/mail.rb +13 -10
- data/app/models/mail_notify.rb +11 -27
- data/app/models/person.rb +1 -1
- data/app/views/account/_login.rhtml +14 -9
- data/app/views/account/_show.rhtml +23 -9
- data/app/views/elt/_choice.rhtml +32 -0
- data/app/views/elt/_elt.rhtml +90 -78
- data/app/views/elt/_list.rhtml +83 -50
- data/app/views/elt/_listByDate.rhtml +60 -0
- data/app/views/elt/_listByVote.rhtml +71 -0
- data/app/views/elt/choices.rhtml +29 -0
- data/app/views/elt/new.rhtml +11 -26
- data/app/views/elt/rss.rxml +14 -12
- data/app/views/elt/show.rhtml +23 -29
- data/app/views/elt/vote_rss.rxml +40 -0
- data/app/views/layouts/top.rhtml +5 -13
- data/config/environment.rb +3 -1
- data/config/routes.rb +4 -0
- data/db/development_structure.sql +5 -2
- data/db/migrate/002_nested_set.rb +22 -0
- data/db/migrate/003_elt_children_count.rb +12 -0
- data/public/images/ParlementLogo.png +0 -0
- data/public/images/indicator.gif +0 -0
- data/public/javascripts/behaviour.js +254 -0
- data/public/javascripts/mybehaviour.js +96 -0
- data/public/javascripts/slider.js +188 -163
- data/test/fixtures/elts.yml +19 -0
- data/test/fixtures/mail/mail_ruby +4 -0
- data/test/fixtures/mail/mail_rubyChild +1 -1
- data/test/fixtures/mail/mail_rubyChild2 +1 -1
- data/test/functional/account_controller_test.rb +24 -0
- data/test/functional/elt_controller_test.rb +64 -4
- data/test/unit/elt_test.rb +28 -4
- data/test/unit/mail_notify_test.rb +7 -5
- data/test/unit/mail_test.rb +1 -1
- data/vendor/plugins/google_analytics/README +19 -0
- data/vendor/plugins/google_analytics/Rakefile +22 -0
- data/vendor/plugins/google_analytics/init.rb +3 -0
- data/vendor/plugins/google_analytics/lib/rubaidh/google_analytics.rb +70 -0
- data/vendor/plugins/google_analytics/test/google_analytics_test.rb +8 -0
- data/vendor/plugins/output_compression/README +4 -0
- data/vendor/plugins/output_compression/Rakefile +22 -0
- data/vendor/plugins/output_compression/init.rb +2 -0
- data/vendor/plugins/output_compression/lib/output_compression.rb +66 -0
- data/vendor/plugins/output_compression/tasks/output_compression_tasks.rake +4 -0
- data/vendor/plugins/output_compression/test/output_compression_test.rb +8 -0
- metadata +32 -4
- data/public/images/smile.svg +0 -257
- data/public/javascripts/borders.js +0 -687
data/app/views/elt/new.rhtml
CHANGED
@@ -4,24 +4,15 @@
|
|
4
4
|
|
5
5
|
<%= error_messages_for 'elt' %>
|
6
6
|
|
7
|
-
<!--
|
8
|
-
<span id="author_<%= @elt.parent_id %>">
|
9
|
-
<%= render :partial => 'account/show',
|
10
|
-
:locals => { :divId => 'author_'+@elt.parent_id } %>
|
11
|
-
</span>
|
12
|
-
-->
|
13
|
-
|
14
7
|
<%= form_remote_tag(
|
15
8
|
:update => 'eltSubs_'+@elt.parent_id,
|
16
|
-
:url => { :action => 'create' },
|
9
|
+
:url => { :action => 'create', :id => @elt.parent },
|
17
10
|
:position => 'bottom',
|
18
|
-
:
|
19
|
-
:
|
20
|
-
Element.show('eltSubsClose_#{@elt.parent_id
|
21
|
-
:loaded => visual_effect(:BlindDown, 'elt_'+@elt.id.to_s)) %>
|
11
|
+
:before => visual_effect(:BlindUp, 'eltNew_'+@elt.parent_id),
|
12
|
+
:loading => "Element.show('eltSubs_#{@elt.parent_id}');
|
13
|
+
Element.show('eltSubsClose_#{@elt.parent_id}')") %>
|
22
14
|
|
23
|
-
|
24
|
-
<%= hidden_field 'elt', 'parent_id' %></p>
|
15
|
+
<%= hidden_field 'elt', 'parent_id' %>
|
25
16
|
|
26
17
|
<h2>
|
27
18
|
<%= text_field 'elt', 'subject' %>
|
@@ -35,18 +26,14 @@
|
|
35
26
|
' } %>
|
36
27
|
</h2>
|
37
28
|
|
38
|
-
<div style="display:none">
|
39
|
-
<label for="elt_position">Position:</label>
|
40
|
-
<%= text_field 'elt', 'position', 'size' => 1, 'align' => 'right' %>
|
41
|
-
</div>
|
42
|
-
|
43
29
|
<%= text_area 'elt', 'body' %>
|
44
30
|
|
45
31
|
<div class="eltNewButtons">
|
46
32
|
<%= submit_to_remote('Preview', 'Preview',
|
47
|
-
|
48
|
-
|
49
|
-
|
33
|
+
:update => "eltNewPreview_"+@elt.parent_id,
|
34
|
+
:url => { :action => "create", :id => @elt.parent, :submit => "preview" },
|
35
|
+
:loading => visual_effect(:BlindDown, 'eltNewPreview_'+@elt.parent_id)) %>
|
36
|
+
|
50
37
|
<%= submit_tag 'Propose!' %>
|
51
38
|
|
52
39
|
<%= render :partial => '/help',
|
@@ -94,9 +81,7 @@
|
|
94
81
|
<a href="http://hobix.com/textile/quick.html">Textile Reference</a>
|
95
82
|
' } %>
|
96
83
|
</div>
|
97
|
-
|
98
|
-
<span class="eltNew" id="eltNewPreview_<%= @elt.parent_id %>"/>
|
99
|
-
|
100
|
-
<!--[eoform:elt]-->
|
101
84
|
<%= end_form_tag %>
|
102
85
|
|
86
|
+
<span class="elt" id="eltNewPreview_<%= @elt.parent_id %>"/>
|
87
|
+
|
data/app/views/elt/rss.rxml
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
|
2
2
|
xml.channel do
|
3
|
-
xml.title
|
4
|
-
xml.link
|
5
|
-
xml.description @elt.subject
|
6
|
-
xml.language "en"
|
7
|
-
xml.language "fr"
|
3
|
+
xml.title @elt.subject
|
4
|
+
xml.link url_for(:only_path => false, :action => 'show', :id => @elt)
|
5
|
+
xml.description @elt.subject
|
8
6
|
|
9
|
-
|
7
|
+
Elt.find(:all,
|
8
|
+
:conditions => "lft > #{@elt.lft} AND rgt < #{@elt.rgt}",
|
9
|
+
:order => 'created_on DESC',
|
10
|
+
:limit => PAGE_ELT_LENGTH).each do |item|
|
10
11
|
xml.item do
|
11
|
-
xml.title
|
12
|
+
xml.title item.subject
|
12
13
|
#xml.category(@elt.subject)
|
13
|
-
xml.pubDate
|
14
|
+
xml.pubDate item.created_on
|
14
15
|
|
15
16
|
if url_for(:only_path => false).match(/http:\/\/echarp.dyndns.org/) and @elt.id == 'blog'
|
16
17
|
xml.link(url_for(:only_path => false, :controller => 'perso',
|
@@ -18,14 +19,15 @@ xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
|
|
18
19
|
xml.comments(url_for(:only_path => false, :controller => 'perso',
|
19
20
|
:action => 'blog', :id => item.id+'.html'))
|
20
21
|
else
|
21
|
-
xml.link(url_for(:only_path => false, :action => 'show', :id => item
|
22
|
-
xml.comments(url_for(:only_path => false, :action => 'show', :id => item
|
22
|
+
xml.link(url_for(:only_path => false, :action => 'show', :id => item))
|
23
|
+
xml.comments(url_for(:only_path => false, :action => 'show', :id => item))
|
23
24
|
end
|
24
25
|
|
25
|
-
xml.tag!("dc:creator", item.person.name) if item.person
|
26
|
+
xml.tag!("dc:creator", item.person.name) if item.person
|
26
27
|
|
27
|
-
xml.description
|
28
|
+
xml.description "<p>"+format(item.body)+"</p>"
|
28
29
|
end
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
33
|
+
|
data/app/views/elt/show.rhtml
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
<h3 class="boxTitle">Electoral list</h3>
|
3
3
|
<div class="box">
|
4
4
|
All voters:
|
5
|
-
<span class="result" style="float: none">
|
5
|
+
<span class="result selected" style="float: none">
|
6
6
|
<%= Choice.count :select => 'person_id', :distinct => true %>
|
7
7
|
</span>
|
8
8
|
</div>
|
@@ -10,36 +10,27 @@
|
|
10
10
|
<h3 class="boxTitle">Identity</h3>
|
11
11
|
<div class="box">
|
12
12
|
<div id="author_<%= @elt.id %>">
|
13
|
-
<%= render :partial => 'account/show',
|
14
|
-
:locals => { :divId => 'author_'+@elt.id } %>
|
13
|
+
<%= render :partial => 'account/show', :locals => { :divId => 'author_'+@elt.id } %>
|
15
14
|
</div>
|
16
15
|
</div>
|
17
16
|
|
18
|
-
<% if @elt.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
<div class="box">
|
23
|
-
<ul>
|
24
|
-
<% for elt in @elt.children.reverse[0...PAGE_ELT_LENGTH] %>
|
25
|
-
<li class="boxLine" title="<%= elt.created_on.strftime('%d/%m') %>">
|
26
|
-
<span class="result"><%= sprintf("%+d", elt.result) %></span>
|
27
|
-
<%= link_to elt.subject, :id => elt %>
|
28
|
-
</li>
|
29
|
-
<% end %>
|
30
|
-
</ul>
|
17
|
+
<% if @elt.elts_count > 0 %><h3 class="boxTitle">Highest posts</h3><% end %>
|
18
|
+
<div class="box listByVote">
|
19
|
+
<%= render :partial => '/elt/listByVote' %>
|
20
|
+
</div>
|
31
21
|
|
32
|
-
|
33
|
-
|
22
|
+
<% if @elt.elts_count > 0 %><h3 class="boxTitle">Latest posts</h3><% end %>
|
23
|
+
<div class="box listByDate">
|
24
|
+
<%= render :partial => '/elt/listByDate' %>
|
34
25
|
</div>
|
35
26
|
|
36
27
|
<h3 class="boxTitle">Subscribe</h3>
|
37
28
|
<div class="box">
|
38
29
|
<div id="subscription">
|
39
30
|
<%= link_to_remote(((@session[:person] and @elt.subscribers.include?(@session[:person])) ? 'Unsubscribe!' : 'Subscribe!'),
|
40
|
-
|
41
|
-
|
42
|
-
|
31
|
+
:update => 'subscription',
|
32
|
+
:url => { :controller => 'subscriber', :action => 'subscribe', :id => @elt },
|
33
|
+
:loaded => visual_effect(:BlindDown, 'subscription')) %>
|
43
34
|
</div>
|
44
35
|
|
45
36
|
<div class="boxLine">
|
@@ -47,7 +38,12 @@
|
|
47
38
|
<%= link_to(i.name, :controller => 'person', :action => 'show', :id => i) %>
|
48
39
|
<% end %>
|
49
40
|
</div>
|
50
|
-
|
41
|
+
|
42
|
+
<div class="boxLineR">
|
43
|
+
<% @elt.parent.all_recipients.each do |i| %>
|
44
|
+
<%= link_to(i.name, :controller => 'person', :action => 'show', :id => i) %>
|
45
|
+
<% end %>
|
46
|
+
</div>
|
51
47
|
</div>
|
52
48
|
</div>
|
53
49
|
|
@@ -55,14 +51,12 @@
|
|
55
51
|
<div class="<%= key %>"><%= value %></div>
|
56
52
|
<% end %>
|
57
53
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
</h3>
|
63
|
-
<% end %>
|
54
|
+
<h3 class="parent">
|
55
|
+
<%= link_to textilize_without_paragraph(@elt.parent.subject), :id => @elt.parent \
|
56
|
+
if @elt.parent %>
|
57
|
+
</h3>
|
64
58
|
|
65
|
-
<ul>
|
59
|
+
<ul class="top">
|
66
60
|
<%= render :partial => 'elt', :layout => 'top',
|
67
61
|
:locals => { :elt => @elt, :eltTop => true } %>
|
68
62
|
</ul>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
|
2
|
+
xml.channel do
|
3
|
+
xml.title @elt.subject
|
4
|
+
xml.link url_for(:only_path => false, :action => 'show', :id => @elt)
|
5
|
+
xml.description @elt.subject
|
6
|
+
|
7
|
+
Elt.find(:all,
|
8
|
+
:select => 'SUM(value), elts.id, parent_id, elts.created_on, parent_id,' \
|
9
|
+
+'elts_count, position, elts.person_id, subject, body, lft, rgt',
|
10
|
+
:conditions => "lft > #{@elt.lft} AND rgt < #{@elt.rgt}",
|
11
|
+
:order => 'SUM(value) IS NULL, SUM(value) DESC, created_on DESC',
|
12
|
+
:group => 'elts.id, parent_id, elts.created_on, parent_id, elts_count,' \
|
13
|
+
+'position, elts.person_id, subject, body, lft, rgt',
|
14
|
+
:limit => PAGE_ELT_LENGTH,
|
15
|
+
:joins => "LEFT JOIN choices ON elt_id = elts.id").each do |item|
|
16
|
+
|
17
|
+
xml.item do
|
18
|
+
xml.title item.subject
|
19
|
+
#xml.category(@elt.subject)
|
20
|
+
xml.vote item.result
|
21
|
+
xml.pubDate item.created_on
|
22
|
+
|
23
|
+
if url_for(:only_path => false).match(/http:\/\/echarp.dyndns.org/) and @elt.id == 'blog'
|
24
|
+
xml.link(url_for(:only_path => false, :controller => 'perso',
|
25
|
+
:action => 'blog', :id => item.id+'.html'))
|
26
|
+
xml.comments(url_for(:only_path => false, :controller => 'perso',
|
27
|
+
:action => 'blog', :id => item.id+'.html'))
|
28
|
+
else
|
29
|
+
xml.link(url_for(:only_path => false, :action => 'show', :id => item))
|
30
|
+
xml.comments(url_for(:only_path => false, :action => 'show', :id => item))
|
31
|
+
end
|
32
|
+
|
33
|
+
xml.tag!("dc:creator", item.person.name) if item.person
|
34
|
+
|
35
|
+
xml.description "<p>"+format(item.body)+"</p>"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
data/app/views/layouts/top.rhtml
CHANGED
@@ -7,9 +7,9 @@
|
|
7
7
|
<%= stylesheet_link_tag 'default.css' %>
|
8
8
|
<%= javascript_include_tag "/javascripts/prototype" %>
|
9
9
|
<%= javascript_include_tag "/javascripts/scriptaculous" %>
|
10
|
-
|
11
|
-
<%= javascript_include_tag "/javascripts/
|
12
|
-
|
10
|
+
|
11
|
+
<%= javascript_include_tag "/javascripts/behaviour" %>
|
12
|
+
<%= javascript_include_tag "/javascripts/mybehaviour" %>
|
13
13
|
|
14
14
|
<!-- compliance patch for microsoft browsers -->
|
15
15
|
<!--[if lt IE 7]>
|
@@ -17,7 +17,6 @@
|
|
17
17
|
<%= javascript_include_tag "/javascripts/ie7.js" %>
|
18
18
|
<![endif]-->
|
19
19
|
|
20
|
-
|
21
20
|
<link rel="shortcut icon" href="/images/world.png" type="image/png"/>
|
22
21
|
|
23
22
|
<meta name="ROBOTS" content="ALL"/>
|
@@ -34,10 +33,10 @@
|
|
34
33
|
<body>
|
35
34
|
<div class="links">
|
36
35
|
<a class="title" href="http://leparlement.org">Parlement</a>
|
37
|
-
<
|
36
|
+
<span class="signets">
|
38
37
|
<a href="http://rubyforge.org/projects/parlement">forge</a>
|
39
38
|
<a href="http://www.gnu.org/licenses/gpl.html">GPL</a>
|
40
|
-
</
|
39
|
+
</span>
|
41
40
|
</div>
|
42
41
|
|
43
42
|
<%= @content_for_layout %>
|
@@ -52,13 +51,6 @@
|
|
52
51
|
<img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict"/>
|
53
52
|
</a>
|
54
53
|
</p>
|
55
|
-
|
56
|
-
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
57
|
-
</script>
|
58
|
-
<script type="text/javascript">
|
59
|
-
_uacct = "UA-317241-1";
|
60
|
-
urchinTracker();
|
61
|
-
</script>
|
62
54
|
</body>
|
63
55
|
</html>
|
64
56
|
|
data/config/environment.rb
CHANGED
@@ -64,7 +64,7 @@ require 'rails_file_column'
|
|
64
64
|
require 'jcode'
|
65
65
|
$KCODE = 'u'
|
66
66
|
|
67
|
-
PARLEMENT_VERSION='0.
|
67
|
+
PARLEMENT_VERSION='0.6'
|
68
68
|
|
69
69
|
# How many elements are displayed at once
|
70
70
|
PAGE_ELT_LENGTH = 10
|
@@ -101,3 +101,5 @@ module LoginEngine
|
|
101
101
|
end
|
102
102
|
Engines.start :login
|
103
103
|
|
104
|
+
Rubaidh::GoogleAnalytics.tracker_id = 'UA-317241-1'
|
105
|
+
|
data/config/routes.rb
CHANGED
@@ -12,16 +12,20 @@ ActionController::Routing::Routes.draw do |map|
|
|
12
12
|
|
13
13
|
map.connect '', :controller => 'elt', :action => 'show', :id => 'parlement'
|
14
14
|
map.connect 'index.rss', :controller => 'elt', :action => 'rss', :id => 'parlement'
|
15
|
+
map.connect 'vote.rss', :controller => 'elt', :action => 'vote_rss', :id => 'parlement'
|
15
16
|
|
16
17
|
map.connect ':id', :controller => 'elt', :action => 'rss', :requirements => { :id => /.*\.rss/ }
|
17
18
|
map.connect ':id', :controller => 'elt', :action => 'show'
|
18
19
|
map.connect ':id/index.rss', :controller => 'elt', :action => 'rss'
|
20
|
+
map.connect ':id/vote.rss', :controller => 'elt', :action => 'vote_rss'
|
19
21
|
map.connect ':id//index.rss', :controller => 'elt', :action => 'rss'
|
22
|
+
map.connect ':id//vote.rss', :controller => 'elt', :action => 'vote_rss'
|
20
23
|
|
21
24
|
map.connect 'perso/:id', :controller => 'elt', :action => 'show'
|
22
25
|
map.connect 'perso/:id/index.rss', :controller => 'elt', :action => 'rss'
|
23
26
|
map.connect 'perso/blog/:id', :controller => 'elt'
|
24
27
|
map.connect 'perso/blog/:id/index.rss', :controller => 'elt', :action => 'rss'
|
28
|
+
map.connect 'perso/blog/:id/vote.rss', :controller => 'elt', :action => 'vote_rss'
|
25
29
|
|
26
30
|
# Allow downloading Web Service WSDL as a file with an extension
|
27
31
|
# instead of a file named 'wsdl'
|
@@ -70,7 +70,10 @@ CREATE TABLE elts (
|
|
70
70
|
created_on timestamp with time zone DEFAULT now() NOT NULL,
|
71
71
|
person_id text,
|
72
72
|
subject text,
|
73
|
-
body text
|
73
|
+
body text,
|
74
|
+
lft integer,
|
75
|
+
rgt integer,
|
76
|
+
elts_count integer DEFAULT 0
|
74
77
|
);
|
75
78
|
|
76
79
|
|
@@ -357,4 +360,4 @@ ALTER TABLE ONLY usersold
|
|
357
360
|
-- PostgreSQL database dump complete
|
358
361
|
--
|
359
362
|
|
360
|
-
INSERT INTO schema_info (version) VALUES (
|
363
|
+
INSERT INTO schema_info (version) VALUES (3)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class NestedSet < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def NestedSet.nested_set_construction(e)
|
4
|
+
e.children.each { |c|
|
5
|
+
e.add_child c
|
6
|
+
nested_set_construction c
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.up
|
11
|
+
add_column :elts, :lft, :integer
|
12
|
+
add_column :elts, :rgt, :integer
|
13
|
+
|
14
|
+
e = Elt.find 'ROOT'
|
15
|
+
NestedSet.nested_set_construction e
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
remove_column :elts, :lft
|
20
|
+
remove_column :elts, :rgt
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class EltChildrenCount < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :elts, :elts_count, :integer, :default => 0
|
4
|
+
execute 'UPDATE elts SET elts_count = (SELECT COUNT(*) FROM elts e2 WHERE e2.parent_id = elts.id)'
|
5
|
+
add_index "elts", ["lft"], :name => "elts_lft_key", :unique => true
|
6
|
+
add_index "elts", ["parent_id"], :name => "elts_parent_key"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
remove_column :elts, :elts_count
|
11
|
+
end
|
12
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,254 @@
|
|
1
|
+
/*
|
2
|
+
Behaviour v1.1 by Ben Nolan, June 2005. Based largely on the work
|
3
|
+
of Simon Willison (see comments by Simon below).
|
4
|
+
|
5
|
+
Description:
|
6
|
+
|
7
|
+
Uses css selectors to apply javascript behaviours to enable
|
8
|
+
unobtrusive javascript in html documents.
|
9
|
+
|
10
|
+
Usage:
|
11
|
+
|
12
|
+
var myrules = {
|
13
|
+
'b.someclass' : function(element){
|
14
|
+
element.onclick = function(){
|
15
|
+
alert(this.innerHTML);
|
16
|
+
}
|
17
|
+
},
|
18
|
+
'#someid u' : function(element){
|
19
|
+
element.onmouseover = function(){
|
20
|
+
this.innerHTML = "BLAH!";
|
21
|
+
}
|
22
|
+
}
|
23
|
+
};
|
24
|
+
|
25
|
+
Behaviour.register(myrules);
|
26
|
+
|
27
|
+
// Call Behaviour.apply() to re-apply the rules (if you
|
28
|
+
// update the dom, etc).
|
29
|
+
|
30
|
+
License:
|
31
|
+
|
32
|
+
This file is entirely BSD licensed.
|
33
|
+
|
34
|
+
More information:
|
35
|
+
|
36
|
+
http:/ipcord.co.nz/behaviour/
|
37
|
+
|
38
|
+
*/
|
39
|
+
|
40
|
+
var Behaviour = {
|
41
|
+
list : new Array,
|
42
|
+
|
43
|
+
register : function(sheet){
|
44
|
+
Behaviour.list.push(sheet);
|
45
|
+
},
|
46
|
+
|
47
|
+
start : function(){
|
48
|
+
Behaviour.addLoadEvent(function(){
|
49
|
+
Behaviour.apply();
|
50
|
+
});
|
51
|
+
},
|
52
|
+
|
53
|
+
apply : function(){
|
54
|
+
for (h=0;sheet=Behaviour.list[h];h++){
|
55
|
+
for (selector in sheet){
|
56
|
+
list = document.getElementsBySelector(selector);
|
57
|
+
|
58
|
+
if (!list){
|
59
|
+
continue;
|
60
|
+
}
|
61
|
+
|
62
|
+
for (i=0;element=list[i];i++){
|
63
|
+
sheet[selector](element);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
},
|
68
|
+
|
69
|
+
addLoadEvent : function(func){
|
70
|
+
var oldonload = window.onload;
|
71
|
+
|
72
|
+
if (typeof window.onload != 'function') {
|
73
|
+
window.onload = func;
|
74
|
+
} else {
|
75
|
+
window.onload = function() {
|
76
|
+
oldonload();
|
77
|
+
func();
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
Behaviour.start();
|
84
|
+
|
85
|
+
/*
|
86
|
+
The following code is Copyright (C) Simon Willison 2004.
|
87
|
+
|
88
|
+
document.getElementsBySelector(selector)
|
89
|
+
- returns an array of element objects from the current document
|
90
|
+
matching the CSS selector. Selectors can contain element names,
|
91
|
+
class names and ids and can be nested. For example:
|
92
|
+
|
93
|
+
elements = document.getElementsBySelect('div#main p a.external')
|
94
|
+
|
95
|
+
Will return an array of all 'a' elements with 'external' in their
|
96
|
+
class attribute that are contained inside 'p' elements that are
|
97
|
+
contained inside the 'div' element which has id="main"
|
98
|
+
|
99
|
+
New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
|
100
|
+
See http://www.w3.org/TR/css3-selectors/#attribute-selectors
|
101
|
+
|
102
|
+
Version 0.4 - Simon Willison, March 25th 2003
|
103
|
+
-- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
|
104
|
+
-- Opera 7 fails
|
105
|
+
*/
|
106
|
+
|
107
|
+
function getAllChildren(e) {
|
108
|
+
// Returns all children of element. Workaround required for IE5/Windows. Ugh.
|
109
|
+
return e.all ? e.all : e.getElementsByTagName('*');
|
110
|
+
}
|
111
|
+
|
112
|
+
document.getElementsBySelector = function(selector) {
|
113
|
+
// Attempt to fail gracefully in lesser browsers
|
114
|
+
if (!document.getElementsByTagName) {
|
115
|
+
return new Array();
|
116
|
+
}
|
117
|
+
// Split selector in to tokens
|
118
|
+
var tokens = selector.split(' ');
|
119
|
+
var currentContext = new Array(document);
|
120
|
+
for (var i = 0; i < tokens.length; i++) {
|
121
|
+
token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
|
122
|
+
if (token.indexOf('#') > -1) {
|
123
|
+
// Token is an ID selector
|
124
|
+
var bits = token.split('#');
|
125
|
+
var tagName = bits[0];
|
126
|
+
var id = bits[1];
|
127
|
+
var element = document.getElementById(id);
|
128
|
+
if (tagName && element.nodeName.toLowerCase() != tagName) {
|
129
|
+
// tag with that ID not found, return false
|
130
|
+
return new Array();
|
131
|
+
}
|
132
|
+
// Set currentContext to contain just this element
|
133
|
+
currentContext = new Array(element);
|
134
|
+
continue; // Skip to next token
|
135
|
+
}
|
136
|
+
if (token.indexOf('.') > -1) {
|
137
|
+
// Token contains a class selector
|
138
|
+
var bits = token.split('.');
|
139
|
+
var tagName = bits[0];
|
140
|
+
var className = bits[1];
|
141
|
+
if (!tagName) {
|
142
|
+
tagName = '*';
|
143
|
+
}
|
144
|
+
// Get elements matching tag, filter them for class selector
|
145
|
+
var found = new Array;
|
146
|
+
var foundCount = 0;
|
147
|
+
for (var h = 0; h < currentContext.length; h++) {
|
148
|
+
var elements;
|
149
|
+
if (tagName == '*') {
|
150
|
+
elements = getAllChildren(currentContext[h]);
|
151
|
+
} else {
|
152
|
+
elements = currentContext[h].getElementsByTagName(tagName);
|
153
|
+
}
|
154
|
+
for (var j = 0; j < elements.length; j++) {
|
155
|
+
found[foundCount++] = elements[j];
|
156
|
+
}
|
157
|
+
}
|
158
|
+
currentContext = new Array;
|
159
|
+
var currentContextIndex = 0;
|
160
|
+
for (var k = 0; k < found.length; k++) {
|
161
|
+
if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
|
162
|
+
currentContext[currentContextIndex++] = found[k];
|
163
|
+
}
|
164
|
+
}
|
165
|
+
continue; // Skip to next token
|
166
|
+
}
|
167
|
+
// Code to deal with attribute selectors
|
168
|
+
if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
|
169
|
+
var tagName = RegExp.$1;
|
170
|
+
var attrName = RegExp.$2;
|
171
|
+
var attrOperator = RegExp.$3;
|
172
|
+
var attrValue = RegExp.$4;
|
173
|
+
if (!tagName) {
|
174
|
+
tagName = '*';
|
175
|
+
}
|
176
|
+
// Grab all of the tagName elements within current context
|
177
|
+
var found = new Array;
|
178
|
+
var foundCount = 0;
|
179
|
+
for (var h = 0; h < currentContext.length; h++) {
|
180
|
+
var elements;
|
181
|
+
if (tagName == '*') {
|
182
|
+
elements = getAllChildren(currentContext[h]);
|
183
|
+
} else {
|
184
|
+
elements = currentContext[h].getElementsByTagName(tagName);
|
185
|
+
}
|
186
|
+
for (var j = 0; j < elements.length; j++) {
|
187
|
+
found[foundCount++] = elements[j];
|
188
|
+
}
|
189
|
+
}
|
190
|
+
currentContext = new Array;
|
191
|
+
var currentContextIndex = 0;
|
192
|
+
var checkFunction; // This function will be used to filter the elements
|
193
|
+
switch (attrOperator) {
|
194
|
+
case '=': // Equality
|
195
|
+
checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
|
196
|
+
break;
|
197
|
+
case '~': // Match one of space seperated words
|
198
|
+
checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
|
199
|
+
break;
|
200
|
+
case '|': // Match start with value followed by optional hyphen
|
201
|
+
checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
|
202
|
+
break;
|
203
|
+
case '^': // Match starts with value
|
204
|
+
checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
|
205
|
+
break;
|
206
|
+
case '$': // Match ends with value - fails with "Warning" in Opera 7
|
207
|
+
checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
|
208
|
+
break;
|
209
|
+
case '*': // Match ends with value
|
210
|
+
checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
|
211
|
+
break;
|
212
|
+
default :
|
213
|
+
// Just test for existence of attribute
|
214
|
+
checkFunction = function(e) { return e.getAttribute(attrName); };
|
215
|
+
}
|
216
|
+
currentContext = new Array;
|
217
|
+
var currentContextIndex = 0;
|
218
|
+
for (var k = 0; k < found.length; k++) {
|
219
|
+
if (checkFunction(found[k])) {
|
220
|
+
currentContext[currentContextIndex++] = found[k];
|
221
|
+
}
|
222
|
+
}
|
223
|
+
// alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
|
224
|
+
continue; // Skip to next token
|
225
|
+
}
|
226
|
+
|
227
|
+
if (!currentContext[0]){
|
228
|
+
return;
|
229
|
+
}
|
230
|
+
|
231
|
+
// If we get here, token is JUST an element (not a class or ID selector)
|
232
|
+
tagName = token;
|
233
|
+
var found = new Array;
|
234
|
+
var foundCount = 0;
|
235
|
+
for (var h = 0; h < currentContext.length; h++) {
|
236
|
+
var elements = currentContext[h].getElementsByTagName(tagName);
|
237
|
+
for (var j = 0; j < elements.length; j++) {
|
238
|
+
found[foundCount++] = elements[j];
|
239
|
+
}
|
240
|
+
}
|
241
|
+
currentContext = found;
|
242
|
+
}
|
243
|
+
return currentContext;
|
244
|
+
}
|
245
|
+
|
246
|
+
/* That revolting regular expression explained
|
247
|
+
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
|
248
|
+
\---/ \---/\-------------/ \-------/
|
249
|
+
| | | |
|
250
|
+
| | | The value
|
251
|
+
| | ~,|,^,$,* or =
|
252
|
+
| Attribute
|
253
|
+
Tag
|
254
|
+
*/
|