parlement 0.5 → 0.6
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/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
|
+
*/
|