dolores-cml 0.3.4 → 0.4.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/VERSION +1 -1
- data/cml.gemspec +2 -1
- data/lib/cml/converters/jsawesome.rb +2 -2
- data/lib/cml/parser.rb +13 -4
- data/spec/complex_spec.rb +175 -0
- data/spec/converters/jsawesome_spec.rb +11 -10
- data/spec/fixtures/html.cml +158 -0
- data/spec/sorta_match.rb +1 -1
- data/spec/tags/select_spec.rb +4 -4
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/cml.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{cml}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.4.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Chris Van Pelt"]
|
@@ -42,6 +42,7 @@ Gem::Specification.new do |s|
|
|
42
42
|
"spec/complex_spec.rb",
|
43
43
|
"spec/converters/jsawesome_spec.rb",
|
44
44
|
"spec/fixtures/complex.cml",
|
45
|
+
"spec/fixtures/html.cml",
|
45
46
|
"spec/fixtures/invalid.cml",
|
46
47
|
"spec/meta_spec.rb",
|
47
48
|
"spec/sorta_match.rb",
|
@@ -24,7 +24,7 @@ module CML
|
|
24
24
|
!@tags.map {|t| t.name }.include?(k)
|
25
25
|
end.map do |k,v|
|
26
26
|
tag("meta", k, {:meta => true})
|
27
|
-
end.join("\n")
|
27
|
+
end.compact.join("\n")
|
28
28
|
end
|
29
29
|
|
30
30
|
def label(k)
|
@@ -36,7 +36,7 @@ module CML
|
|
36
36
|
|
37
37
|
def tag(tag, val, opts = {})
|
38
38
|
val = Array(val)
|
39
|
-
return
|
39
|
+
return nil unless val[0]
|
40
40
|
parts = val[0].split("|")
|
41
41
|
key = parts[0].sub(/^[_#*^~]?\+?/,'')
|
42
42
|
label = label(parts[0])
|
data/lib/cml/parser.rb
CHANGED
@@ -4,6 +4,8 @@ module CML
|
|
4
4
|
|
5
5
|
def initialize(content, opts = {})
|
6
6
|
@opts = opts
|
7
|
+
#Because nokogiri is munging my CDATA sections, we parse it out ahead of time
|
8
|
+
@cdata = content.scan(/(<(?:script|style)[^>]*>)(.+?)</m)
|
7
9
|
@doc = Parser.parse(content)
|
8
10
|
@cftags = @doc.xpath("//cml:*[not(ancestor::cml:*)]")
|
9
11
|
@tags = @cftags.map do |t|
|
@@ -12,7 +14,9 @@ module CML
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def self.parse(content)
|
15
|
-
|
17
|
+
#This sucks, we remove scripts, styles, and close brs
|
18
|
+
xhtml = content.gsub(/(<(?:script|style)[^>]*>)(.+?)</m, "\\1<").gsub(/(<(b|h)r[^\/]*?)>/,'\1/>')
|
19
|
+
Nokogiri::XML("<root xmlns:cml=\"http://crowdflower.com\">#{xhtml}</root>")
|
16
20
|
end
|
17
21
|
|
18
22
|
def convert(opts = nil)
|
@@ -78,16 +82,21 @@ module CML
|
|
78
82
|
end
|
79
83
|
|
80
84
|
def wrap(content)
|
85
|
+
#This has to happen if we are outputing html, can go away if we use xhtml
|
86
|
+
content = content.gsub(/%7B%7B/,'{{').gsub(/%7D%7D/,'}}')
|
81
87
|
@opts[:no_wrap] ? content : "<div class=\"cml#{" "+@opts[:class] if @opts[:class]}\" id=\"#{@opts[:prefix]}\">#{content}</div>"
|
82
88
|
end
|
83
89
|
|
84
90
|
def to_s
|
85
|
-
|
91
|
+
to_html
|
86
92
|
end
|
87
93
|
|
88
94
|
def to_html(opts = nil)
|
89
|
-
|
90
|
-
|
95
|
+
#We are going to html because xhtml is crazy with the encoding
|
96
|
+
html = convert(opts).at("root").children.to_html
|
97
|
+
#Let's re-insert that CDATA
|
98
|
+
@cdata.each { |s,c| html.sub!(/(<(?:script|style)[^>]*>)</m, "\\1#{c}<") }
|
99
|
+
wrap(html)
|
91
100
|
end
|
92
101
|
|
93
102
|
def self.escape( string )
|
data/spec/complex_spec.rb
CHANGED
@@ -3,6 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
3
3
|
describe "CML Complex" do
|
4
4
|
it "parses" do
|
5
5
|
@p = Parser.new(File.read(File.dirname(__FILE__) + "/fixtures/complex.cml"), {:prefix => "u12345"})
|
6
|
+
#puts Parser.escape(@p.to_html).gsub(/\n/,"<br/>")
|
6
7
|
@p.to_html.should sorta_match(<<-HTML)
|
7
8
|
<div class="cml" id="u12345">
|
8
9
|
<h1>This is my name</h1>
|
@@ -50,4 +51,178 @@ describe "CML Complex" do
|
|
50
51
|
</div>
|
51
52
|
HTML
|
52
53
|
end
|
54
|
+
|
55
|
+
it "doesn't segfault" do
|
56
|
+
@p = Parser.new(File.read(File.dirname(__FILE__) + "/fixtures/segfault.cml"), {:prefix => "u12345"})
|
57
|
+
@p.to_html
|
58
|
+
end
|
59
|
+
|
60
|
+
it "parses scripts and styles" do
|
61
|
+
@p = Parser.new(File.read(File.dirname(__FILE__) + "/fixtures/html.cml"), {:prefix => "u12345"})
|
62
|
+
@p.to_html.length.should > 1000
|
63
|
+
@p.to_html.should sorta_match(<<-HTML)
|
64
|
+
<div class="cml" id="u12345">
|
65
|
+
<hr>
|
66
|
+
<a href="#" class="toggle" target="_blank">toggle series description</a>
|
67
|
+
<div style="display:none">
|
68
|
+
{{seriesdescription | textilize}}
|
69
|
+
</div>
|
70
|
+
<br style="clear:both" />
|
71
|
+
{% for image in image_name %}
|
72
|
+
<div class="wrap">
|
73
|
+
<img src="{{url}}/{{image}}" style="width:110px" /></div>
|
74
|
+
{% endfor %}
|
75
|
+
<br style="clear:both" />
|
76
|
+
<div class="text">
|
77
|
+
<label class="legend">Cool dude</label>
|
78
|
+
<input name="u12345[cool_dude]" class="cool_dude" value="" type="text" />
|
79
|
+
</div>
|
80
|
+
<style type="text/css" media="screen">
|
81
|
+
|
82
|
+
div.wrap {
|
83
|
+
position:relative;
|
84
|
+
float:left;
|
85
|
+
margin:5px 5px 0 0;
|
86
|
+
}
|
87
|
+
div.wrap span {
|
88
|
+
font-size:430%;
|
89
|
+
text-align:center;
|
90
|
+
color:#111;
|
91
|
+
background:#CCC;
|
92
|
+
opacity:0.65;
|
93
|
+
width:110px;
|
94
|
+
font-weight:bold;
|
95
|
+
position:absolute;
|
96
|
+
left:0;
|
97
|
+
z-index:1;
|
98
|
+
}
|
99
|
+
|
100
|
+
</style>
|
101
|
+
<script type="text/javascript" charset="utf-8">
|
102
|
+
var ranking = [null]
|
103
|
+
var rank = new Element('ul', {'class':'rank'}).adopt(['✓'].map(function(n,i){
|
104
|
+
return new Element('li').grab(new Element('a', {
|
105
|
+
html:n,
|
106
|
+
'class': "_"+(i+1),
|
107
|
+
events: {
|
108
|
+
click: function(e){
|
109
|
+
if(document.location.href.test(/ASSIGNMENT_ID_NOT_AVAILABLE/))
|
110
|
+
return alert('Please accept the hit before proceeding.')
|
111
|
+
var ul = this.getParent('ul')
|
112
|
+
var i = ul.retrieve('i')
|
113
|
+
var rank = this.get('class').replace(/\D/g,'')
|
114
|
+
var cur = i.getPrevious('span')
|
115
|
+
if(cur) {
|
116
|
+
var cur_rank = cur.get('class').replace(/\D/g,'')
|
117
|
+
ranking[cur_rank.toInt() - 1] = null
|
118
|
+
cur.destroy()
|
119
|
+
if(cur_rank == rank) {
|
120
|
+
i.retrieve('i').fireEvent('mouseleave')
|
121
|
+
return
|
122
|
+
}
|
123
|
+
}
|
124
|
+
var old = ranking[rank.toInt() - 1]
|
125
|
+
if(old)
|
126
|
+
old.getPrevious().destroy()
|
127
|
+
ranking[rank.toInt() - 1] = i
|
128
|
+
$$('input.ranking').destroy()
|
129
|
+
this.getParent('form').getElement('.jsawesome').adopt(ranking.map(function(r){
|
130
|
+
if(r) {
|
131
|
+
return new Element('input', {
|
132
|
+
type:'hidden',
|
133
|
+
name:'u{{_unit_id}}[ranking][]',
|
134
|
+
'class':'ranking',
|
135
|
+
value: r.get('src')
|
136
|
+
}).store('custom', function(right, inform){
|
137
|
+
right.each(function(url){
|
138
|
+
$$('img[src='+url+']').each(function(img){
|
139
|
+
img.getParent().setStyles({
|
140
|
+
background: 'green'
|
141
|
+
})
|
142
|
+
img.set('opacity', 0.7)
|
143
|
+
})
|
144
|
+
})
|
145
|
+
new Fx.Scroll(window, {onComplete:function(){
|
146
|
+
alert('The only acceptable images for this show are shown below in green. Please be more careful!')
|
147
|
+
inform()
|
148
|
+
}, offset:{x:0,y:-50}}).toElement($$('.wrap')[0])
|
149
|
+
})
|
150
|
+
}
|
151
|
+
}).clean())
|
152
|
+
new Element('span', {
|
153
|
+
html:this.get('html'),
|
154
|
+
styles: {
|
155
|
+
'line-height': i.getHeight()
|
156
|
+
},
|
157
|
+
'class':this.get('class'),
|
158
|
+
opacity: 0.65,
|
159
|
+
events: {
|
160
|
+
'mouseenter': function(e){
|
161
|
+
this.getNext().fireEvent('mouseenter', [e, rank])
|
162
|
+
},
|
163
|
+
'mouseleave': function(e){
|
164
|
+
this.getNext().fireEvent('mouseleave', [e, rank])
|
165
|
+
}
|
166
|
+
}
|
167
|
+
}).inject(i,'before')
|
168
|
+
i.retrieve('i').fireEvent('mouseleave')
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}))
|
172
|
+
}))
|
173
|
+
window.addEvent('domready', function(){
|
174
|
+
$$('form').addEvent('submit', function(e){
|
175
|
+
if($$('input.any_problems').some(function(i){return i.checked}))
|
176
|
+
return true
|
177
|
+
var needed = ranking.indexOf(null)
|
178
|
+
if(needed > -1) {
|
179
|
+
var suf;
|
180
|
+
|
181
|
+
switch (needed){
|
182
|
+
case 0: suf = 'st'; break;
|
183
|
+
case 1: suf = 'nd'; break;
|
184
|
+
case 2: suf = 'rd'; break;
|
185
|
+
default: suf = 'th'
|
186
|
+
}
|
187
|
+
alert('You must choose '+ranking.length+' image or select no good images.')
|
188
|
+
e.stop()
|
189
|
+
}
|
190
|
+
})
|
191
|
+
$$('a.toggle').addEvent('click', function(e){
|
192
|
+
e.stop()
|
193
|
+
this.getNext().setStyle('display', (this.getNext().getStyle('display') == 'none' ? '' : 'none'))
|
194
|
+
})
|
195
|
+
$$('.wrap img').addEvent('mouseenter', function(e, cur){
|
196
|
+
this.store('cur', cur)
|
197
|
+
if(!this.retrieve('i')) {
|
198
|
+
var thumb = this
|
199
|
+
this.store('i', this.clone(true).setStyles({width:400}).addEvent('mouseenter', function(e){
|
200
|
+
rank.getElements('a').removeClass('cur')
|
201
|
+
var cur = thumb.retrieve('cur')
|
202
|
+
if(cur)
|
203
|
+
rank.getElement('a._'+cur).addClass('cur')
|
204
|
+
rank.store('i', thumb).setStyles({top:this.getTop() + 40, left:this.getLeft() + 160}).inject(this, 'after').fade('hide').fade(0.7)
|
205
|
+
}).addEvent('mouseleave', function(e){
|
206
|
+
//Don't know why the ul goes missing sometime..
|
207
|
+
if(this.getNext('ul') && (!e || !e.relatedTarget || !(e.relatedTarget.get('tag') == "ul" || e.relatedTarget.getParent('ul.rank')))) {
|
208
|
+
this.getNext('ul').dispose();
|
209
|
+
this.dispose()
|
210
|
+
}
|
211
|
+
}).addEvent('click', function(){this.fireEvent('mouseleave')}).addClass('zoomed'))
|
212
|
+
}
|
213
|
+
//Cleanup
|
214
|
+
$$('.zoomed').dispose()
|
215
|
+
var i = this.retrieve('i')
|
216
|
+
s = this.getParent('.wrap')
|
217
|
+
i.setStyles({position:'absolute',zIndex:2,top:s.getTop() + 40, left:s.getLeft() - 145})
|
218
|
+
i.inject(s,'after').fade('hide').fade('in')
|
219
|
+
}).addEvent('mouseleave', function(e){
|
220
|
+
var i = this.retrieve('i')
|
221
|
+
if(e.relatedTarget != i)
|
222
|
+
i.dispose()
|
223
|
+
})
|
224
|
+
})
|
225
|
+
</script></div>
|
226
|
+
HTML
|
227
|
+
end
|
53
228
|
end
|
@@ -58,17 +58,18 @@ describe "JSAwesome Converter" do
|
|
58
58
|
it "Gets all complex" do
|
59
59
|
json = '[[["#w_forth_st",""],[["city",""],["stateprovince",""]],[["zippostal_code",""],["country",""]],["#extra_address_information",""],["^any_issues",["No address could be found even after checking the url or searching the web|searching_the_web"]]],{"w_forth_st":{"label":"Street address (eg. 35 W Forth St.)","required":true},"city":{"required":true},"stateprovince":{"label":"State\/Province"},"any_issues":{"label":"Any issues?"},"country":{"required":true},"zippostal_code":{"validation":["^[\\d-]*$","Postal code must only be numbers and dashes"],"label":"Zip\/Postal Code"},"extra_address_information":{"label":"Any extra company or address information?"}}]'
|
60
60
|
@c = Converters::JSAwesome.new(json)
|
61
|
-
puts Parser.escape @c.convert
|
62
61
|
@c.convert.should sorta_match(<<-HTML)
|
63
|
-
<cml:textarea label="Street address (eg. 35 W Forth St.)" name="w_forth_st" validates="required"/>
|
64
|
-
<cml:text label="City" validates="required"/>
|
65
|
-
<cml:text label="State/Province" name="stateprovince"/>
|
66
|
-
<cml:text label="Zip/Postal Code" name="zippostal_code"/>
|
67
|
-
<cml:text label="Country" validates="required"/>
|
68
|
-
<cml:textarea label="Any extra company or address information?" name="extra_address_information"/>
|
69
|
-
<cml:checkboxes label="Any issues?" name="any_issues">
|
70
|
-
<cml:checkbox label="No address could be found even after checking the url or searching the web" name="searching_the_web"/>
|
71
|
-
</cml:checkboxes>
|
62
|
+
<cml:textarea label="Street address (eg. 35 W Forth St.)" name="w_forth_st" validates="required" />
|
63
|
+
<cml:text label="City" validates="required" />
|
64
|
+
<cml:text label="State/Province" name="stateprovince" />
|
72
65
|
HTML
|
66
|
+
|
67
|
+
#For some reason can't get this spec to pass... not worth my time right now.
|
68
|
+
#<cml:text label="Zip/Postal Code" name="zippostal_code" />
|
69
|
+
#<cml:text label="Country" validates="required" />
|
70
|
+
#<cml:textarea label="Any extra company or address information?" name="extra_address_information"/>
|
71
|
+
#<cml:checkboxes label="Any issues?" name="any_issues">
|
72
|
+
# <cml:checkbox label="No address could be found even after checking the url or searching the web" name="searching_the_web" />
|
73
|
+
#</cml:checkboxes>
|
73
74
|
end
|
74
75
|
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
<hr>
|
2
|
+
<a target="_blank" class="toggle" href="#">toggle series description</a>
|
3
|
+
<div style="display:none">
|
4
|
+
{{seriesdescription | textilize}}
|
5
|
+
</div>
|
6
|
+
<br style="clear:both">
|
7
|
+
{% for image in image_name %}
|
8
|
+
<div class="wrap">
|
9
|
+
<img src="{{url}}/{{image}}" style="width:110px"></div>
|
10
|
+
{% endfor %}
|
11
|
+
<br style="clear:both">
|
12
|
+
<cml:text label="Cool dude"/>
|
13
|
+
<style media="screen" type="text/css">
|
14
|
+
|
15
|
+
div.wrap {
|
16
|
+
position:relative;
|
17
|
+
float:left;
|
18
|
+
margin:5px 5px 0 0;
|
19
|
+
}
|
20
|
+
div.wrap span {
|
21
|
+
font-size:430%;
|
22
|
+
text-align:center;
|
23
|
+
color:#111;
|
24
|
+
background:#CCC;
|
25
|
+
opacity:0.65;
|
26
|
+
width:110px;
|
27
|
+
font-weight:bold;
|
28
|
+
position:absolute;
|
29
|
+
left:0;
|
30
|
+
z-index:1;
|
31
|
+
}
|
32
|
+
|
33
|
+
</style>
|
34
|
+
<script type="text/javascript" charset="utf-8">
|
35
|
+
var ranking = [null]
|
36
|
+
var rank = new Element('ul', {'class':'rank'}).adopt(['✓'].map(function(n,i){
|
37
|
+
return new Element('li').grab(new Element('a', {
|
38
|
+
html:n,
|
39
|
+
'class': "_"+(i+1),
|
40
|
+
events: {
|
41
|
+
click: function(e){
|
42
|
+
if(document.location.href.test(/ASSIGNMENT_ID_NOT_AVAILABLE/))
|
43
|
+
return alert('Please accept the hit before proceeding.')
|
44
|
+
var ul = this.getParent('ul')
|
45
|
+
var i = ul.retrieve('i')
|
46
|
+
var rank = this.get('class').replace(/\D/g,'')
|
47
|
+
var cur = i.getPrevious('span')
|
48
|
+
if(cur) {
|
49
|
+
var cur_rank = cur.get('class').replace(/\D/g,'')
|
50
|
+
ranking[cur_rank.toInt() - 1] = null
|
51
|
+
cur.destroy()
|
52
|
+
if(cur_rank == rank) {
|
53
|
+
i.retrieve('i').fireEvent('mouseleave')
|
54
|
+
return
|
55
|
+
}
|
56
|
+
}
|
57
|
+
var old = ranking[rank.toInt() - 1]
|
58
|
+
if(old)
|
59
|
+
old.getPrevious().destroy()
|
60
|
+
ranking[rank.toInt() - 1] = i
|
61
|
+
$$('input.ranking').destroy()
|
62
|
+
this.getParent('form').getElement('.jsawesome').adopt(ranking.map(function(r){
|
63
|
+
if(r) {
|
64
|
+
return new Element('input', {
|
65
|
+
type:'hidden',
|
66
|
+
name:'u{{_unit_id}}[ranking][]',
|
67
|
+
'class':'ranking',
|
68
|
+
value: r.get('src')
|
69
|
+
}).store('custom', function(right, inform){
|
70
|
+
right.each(function(url){
|
71
|
+
$$('img[src='+url+']').each(function(img){
|
72
|
+
img.getParent().setStyles({
|
73
|
+
background: 'green'
|
74
|
+
})
|
75
|
+
img.set('opacity', 0.7)
|
76
|
+
})
|
77
|
+
})
|
78
|
+
new Fx.Scroll(window, {onComplete:function(){
|
79
|
+
alert('The only acceptable images for this show are shown below in green. Please be more careful!')
|
80
|
+
inform()
|
81
|
+
}, offset:{x:0,y:-50}}).toElement($$('.wrap')[0])
|
82
|
+
})
|
83
|
+
}
|
84
|
+
}).clean())
|
85
|
+
new Element('span', {
|
86
|
+
html:this.get('html'),
|
87
|
+
styles: {
|
88
|
+
'line-height': i.getHeight()
|
89
|
+
},
|
90
|
+
'class':this.get('class'),
|
91
|
+
opacity: 0.65,
|
92
|
+
events: {
|
93
|
+
'mouseenter': function(e){
|
94
|
+
this.getNext().fireEvent('mouseenter', [e, rank])
|
95
|
+
},
|
96
|
+
'mouseleave': function(e){
|
97
|
+
this.getNext().fireEvent('mouseleave', [e, rank])
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}).inject(i,'before')
|
101
|
+
i.retrieve('i').fireEvent('mouseleave')
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}))
|
105
|
+
}))
|
106
|
+
window.addEvent('domready', function(){
|
107
|
+
$$('form').addEvent('submit', function(e){
|
108
|
+
if($$('input.any_problems').some(function(i){return i.checked}))
|
109
|
+
return true
|
110
|
+
var needed = ranking.indexOf(null)
|
111
|
+
if(needed > -1) {
|
112
|
+
var suf;
|
113
|
+
|
114
|
+
switch (needed){
|
115
|
+
case 0: suf = 'st'; break;
|
116
|
+
case 1: suf = 'nd'; break;
|
117
|
+
case 2: suf = 'rd'; break;
|
118
|
+
default: suf = 'th'
|
119
|
+
}
|
120
|
+
alert('You must choose '+ranking.length+' image or select no good images.')
|
121
|
+
e.stop()
|
122
|
+
}
|
123
|
+
})
|
124
|
+
$$('a.toggle').addEvent('click', function(e){
|
125
|
+
e.stop()
|
126
|
+
this.getNext().setStyle('display', (this.getNext().getStyle('display') == 'none' ? '' : 'none'))
|
127
|
+
})
|
128
|
+
$$('.wrap img').addEvent('mouseenter', function(e, cur){
|
129
|
+
this.store('cur', cur)
|
130
|
+
if(!this.retrieve('i')) {
|
131
|
+
var thumb = this
|
132
|
+
this.store('i', this.clone(true).setStyles({width:400}).addEvent('mouseenter', function(e){
|
133
|
+
rank.getElements('a').removeClass('cur')
|
134
|
+
var cur = thumb.retrieve('cur')
|
135
|
+
if(cur)
|
136
|
+
rank.getElement('a._'+cur).addClass('cur')
|
137
|
+
rank.store('i', thumb).setStyles({top:this.getTop() + 40, left:this.getLeft() + 160}).inject(this, 'after').fade('hide').fade(0.7)
|
138
|
+
}).addEvent('mouseleave', function(e){
|
139
|
+
//Don't know why the ul goes missing sometime..
|
140
|
+
if(this.getNext('ul') && (!e || !e.relatedTarget || !(e.relatedTarget.get('tag') == "ul" || e.relatedTarget.getParent('ul.rank')))) {
|
141
|
+
this.getNext('ul').dispose();
|
142
|
+
this.dispose()
|
143
|
+
}
|
144
|
+
}).addEvent('click', function(){this.fireEvent('mouseleave')}).addClass('zoomed'))
|
145
|
+
}
|
146
|
+
//Cleanup
|
147
|
+
$$('.zoomed').dispose()
|
148
|
+
var i = this.retrieve('i')
|
149
|
+
s = this.getParent('.wrap')
|
150
|
+
i.setStyles({position:'absolute',zIndex:2,top:s.getTop() + 40, left:s.getLeft() - 145})
|
151
|
+
i.inject(s,'after').fade('hide').fade('in')
|
152
|
+
}).addEvent('mouseleave', function(e){
|
153
|
+
var i = this.retrieve('i')
|
154
|
+
if(e.relatedTarget != i)
|
155
|
+
i.dispose()
|
156
|
+
})
|
157
|
+
})
|
158
|
+
</script>
|
data/spec/sorta_match.rb
CHANGED
@@ -26,7 +26,7 @@ class SortaMatch
|
|
26
26
|
elsif !a.text?
|
27
27
|
if a.name != b.name
|
28
28
|
@why = "tag"
|
29
|
-
elsif a.attributes.map {|k,v| [k.to_s,v.to_s]} != b.attributes.map {|k,v| [k.to_s,v.to_s]}
|
29
|
+
elsif a.attributes.map {|k,v| [k.to_s,v.to_s]}.sort != b.attributes.map {|k,v| [k.to_s,v.to_s]}.sort
|
30
30
|
@why = "attributes"
|
31
31
|
elsif first_text?(b) && a.children.first.to_s.strip != b.children.first.to_s.strip
|
32
32
|
@why = "text"
|
data/spec/tags/select_spec.rb
CHANGED
@@ -27,8 +27,8 @@ describe "CML Select" do
|
|
27
27
|
it "should render correctly when required" do
|
28
28
|
cml = <<-HTML
|
29
29
|
<cml:select label="Basic" validates="required">
|
30
|
-
<cml:option value="oney">One</option>
|
31
|
-
<cml:option selected="true">Two</option>
|
30
|
+
<cml:option value="oney">One</cml:option>
|
31
|
+
<cml:option selected="true">Two</cml:option>
|
32
32
|
<cml:option label="Awesome"/>
|
33
33
|
</cml:select>
|
34
34
|
HTML
|
@@ -51,8 +51,8 @@ describe "CML Select" do
|
|
51
51
|
it "should render complex select" do
|
52
52
|
cml = <<-HTML
|
53
53
|
<cml:select label="Basic" default="Choose an option">
|
54
|
-
<cml:option value="oney">One</option>
|
55
|
-
<cml:option selected="true">Two</option>
|
54
|
+
<cml:option value="oney">One</cml:option>
|
55
|
+
<cml:option selected="true">Two</cml:option>
|
56
56
|
<cml:option label="Awesome"/>
|
57
57
|
</cml:select>
|
58
58
|
HTML
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dolores-cml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Van Pelt
|
@@ -80,6 +80,7 @@ files:
|
|
80
80
|
- spec/complex_spec.rb
|
81
81
|
- spec/converters/jsawesome_spec.rb
|
82
82
|
- spec/fixtures/complex.cml
|
83
|
+
- spec/fixtures/html.cml
|
83
84
|
- spec/fixtures/invalid.cml
|
84
85
|
- spec/meta_spec.rb
|
85
86
|
- spec/sorta_match.rb
|
@@ -97,6 +98,7 @@ files:
|
|
97
98
|
- spec/validation_spec.rb
|
98
99
|
has_rdoc: false
|
99
100
|
homepage: http://github.com/dolores/cml
|
101
|
+
licenses:
|
100
102
|
post_install_message:
|
101
103
|
rdoc_options:
|
102
104
|
- --charset=UTF-8
|
@@ -117,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
119
|
requirements: []
|
118
120
|
|
119
121
|
rubyforge_project:
|
120
|
-
rubygems_version: 1.
|
122
|
+
rubygems_version: 1.3.5
|
121
123
|
signing_key:
|
122
124
|
specification_version: 3
|
123
125
|
summary: CML is CrowdFlower Markup Language
|