hobo 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +330 -0
- data/Manifest +12 -4
- data/Rakefile +4 -6
- data/dryml_generators/rapid/cards.dryml.erb +5 -1
- data/dryml_generators/rapid/forms.dryml.erb +8 -10
- data/dryml_generators/rapid/pages.dryml.erb +65 -36
- data/hobo.gemspec +28 -15
- data/lib/active_record/association_collection.rb +3 -22
- data/lib/hobo.rb +25 -258
- data/lib/hobo/accessible_associations.rb +131 -0
- data/lib/hobo/authentication_support.rb +15 -9
- data/lib/hobo/composite_model.rb +1 -1
- data/lib/hobo/controller.rb +7 -8
- data/lib/hobo/dryml.rb +9 -10
- data/lib/hobo/dryml/dryml_builder.rb +7 -1
- data/lib/hobo/dryml/dryml_doc.rb +161 -0
- data/lib/hobo/dryml/dryml_generator.rb +18 -9
- data/lib/hobo/dryml/part_context.rb +76 -42
- data/lib/hobo/dryml/tag_parameters.rb +1 -0
- data/lib/hobo/dryml/taglib.rb +2 -1
- data/lib/hobo/dryml/template.rb +39 -29
- data/lib/hobo/dryml/template_environment.rb +79 -37
- data/lib/hobo/dryml/template_handler.rb +66 -21
- data/lib/hobo/guest.rb +2 -10
- data/lib/hobo/hobo_helper.rb +125 -53
- data/lib/hobo/include_in_save.rb +0 -1
- data/lib/hobo/lifecycles.rb +54 -24
- data/lib/hobo/lifecycles/actions.rb +95 -31
- data/lib/hobo/lifecycles/creator.rb +18 -23
- data/lib/hobo/lifecycles/lifecycle.rb +86 -62
- data/lib/hobo/lifecycles/state.rb +1 -2
- data/lib/hobo/lifecycles/transition.rb +22 -28
- data/lib/hobo/model.rb +64 -176
- data/lib/hobo/model_controller.rb +67 -54
- data/lib/hobo/model_router.rb +5 -2
- data/lib/hobo/permissions.rb +397 -0
- data/lib/hobo/permissions/associations.rb +167 -0
- data/lib/hobo/scopes.rb +15 -38
- data/lib/hobo/scopes/association_proxy_extensions.rb +15 -5
- data/lib/hobo/scopes/automatic_scopes.rb +43 -18
- data/lib/hobo/scopes/named_scope_extensions.rb +2 -2
- data/lib/hobo/user.rb +10 -4
- data/lib/hobo/user_controller.rb +6 -5
- data/lib/hobo/view_hints.rb +58 -0
- data/rails_generators/hobo/hobo_generator.rb +7 -3
- data/rails_generators/hobo/templates/guest.rb +1 -13
- data/rails_generators/hobo_front_controller/hobo_front_controller_generator.rb +1 -1
- data/rails_generators/hobo_model/hobo_model_generator.rb +4 -2
- data/rails_generators/hobo_model/templates/hints.rb +4 -0
- data/rails_generators/hobo_model/templates/model.rb +8 -8
- data/rails_generators/hobo_model_controller/hobo_model_controller_generator.rb +10 -0
- data/rails_generators/hobo_model_controller/templates/controller.rb +1 -1
- data/rails_generators/hobo_rapid/templates/hobo-rapid.js +91 -56
- data/rails_generators/hobo_rapid/templates/lowpro.js +15 -15
- data/rails_generators/hobo_rapid/templates/reset.css +36 -3
- data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/clean.css +13 -17
- data/rails_generators/hobo_user_controller/templates/controller.rb +1 -1
- data/rails_generators/hobo_user_model/templates/model.rb +18 -16
- data/taglibs/core.dryml +60 -18
- data/taglibs/rapid.dryml +8 -401
- data/taglibs/rapid_core.dryml +586 -0
- data/taglibs/rapid_document_tags.dryml +28 -10
- data/taglibs/rapid_editing.dryml +92 -55
- data/taglibs/rapid_forms.dryml +406 -87
- data/taglibs/rapid_generics.dryml +1 -1
- data/taglibs/rapid_navigation.dryml +2 -1
- data/taglibs/rapid_pages.dryml +7 -16
- data/taglibs/rapid_plus.dryml +39 -14
- data/taglibs/rapid_support.dryml +1 -1
- data/taglibs/rapid_user_pages.dryml +14 -4
- data/tasks/{generate_tag_reference.rb → generate_tag_reference.rake} +49 -18
- data/tasks/hobo_tasks.rake +16 -0
- data/test/permissions/models/models.rb +134 -0
- data/test/permissions/models/schema.rb +55 -0
- data/test/permissions/models/test.sqlite3 +0 -0
- data/test/permissions/test_permissions.rb +436 -0
- metadata +27 -14
- data/lib/hobo/mass_assignment.rb +0 -64
- data/rails_generators/hobo/templates/patch_routing.rb +0 -30
- data/uninstall.rb +0 -1
@@ -0,0 +1,58 @@
|
|
1
|
+
module Hobo
|
2
|
+
|
3
|
+
class ViewHints
|
4
|
+
|
5
|
+
def self.enable
|
6
|
+
ActiveSupport::Dependencies.load_paths |= ["#{RAILS_ROOT}/app/viewhints"]
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.setter(name, default=nil, &block)
|
10
|
+
metaclass.send :define_method, name do |*args|
|
11
|
+
if args.empty?
|
12
|
+
instance_variable_get("@#{name}") || (default.is_a?(Proc) ? instance_eval(&default) : default)
|
13
|
+
else
|
14
|
+
arg = if block
|
15
|
+
block[*args]
|
16
|
+
else
|
17
|
+
args.first
|
18
|
+
end
|
19
|
+
instance_variable_set("@#{name}", arg)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
setter :model_name, proc { name.sub(/Hints$/, "") }
|
25
|
+
|
26
|
+
setter :field_names, {}
|
27
|
+
|
28
|
+
setter :field_help, {}
|
29
|
+
|
30
|
+
setter :children, proc { model.dependent_collections.sort_by(&:to_s) } do |*args|
|
31
|
+
args
|
32
|
+
end
|
33
|
+
|
34
|
+
# Accessors
|
35
|
+
|
36
|
+
class << self
|
37
|
+
|
38
|
+
def model
|
39
|
+
model_name.constantize
|
40
|
+
end
|
41
|
+
|
42
|
+
def field_name(field)
|
43
|
+
field_names.fetch(field.to_sym, field.to_s.titleize)
|
44
|
+
end
|
45
|
+
|
46
|
+
def primary_children
|
47
|
+
children.first
|
48
|
+
end
|
49
|
+
|
50
|
+
def secondary_children
|
51
|
+
children.rest
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -16,13 +16,17 @@ class HoboGenerator < Rails::Generator::Base
|
|
16
16
|
record do |m|
|
17
17
|
m.directory File.join("app/views/taglibs")
|
18
18
|
m.directory File.join("app/views/taglibs/themes")
|
19
|
-
m.directory File.join("public/hobothemes")
|
20
19
|
m.template "application.dryml", File.join("app/views/taglibs/application.dryml")
|
20
|
+
m.directory File.join("public/hobothemes")
|
21
|
+
|
22
|
+
m.directory File.join("app/models")
|
21
23
|
m.file "guest.rb", File.join("app/models/guest.rb")
|
22
|
-
|
24
|
+
|
25
|
+
m.directory File.join("public/stylesheets")
|
23
26
|
m.file "application.css", File.join("public/stylesheets/application.css")
|
27
|
+
m.file "dryml-support.js", File.join("public/javascripts/dryml-support.js")
|
28
|
+
|
24
29
|
m.file "initializer.rb", File.join("config/initializers/hobo.rb")
|
25
|
-
m.file "patch_routing.rb", File.join("config/initializers/patch_routing.rb")
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
@@ -47,7 +47,7 @@ class HoboFrontControllerGenerator < Rails::Generator::NamedBase
|
|
47
47
|
name = full_class_path
|
48
48
|
|
49
49
|
route = (" map.site_search 'search', :controller => '#{name}', :action => 'search'\n" +
|
50
|
-
" map.
|
50
|
+
" map.root :controller => '#{name}', :action => 'index'")
|
51
51
|
|
52
52
|
route_src = File.read(routes_path)
|
53
53
|
return if route_src.include?(route)
|
@@ -9,10 +9,12 @@ class HoboModelGenerator < Rails::Generator::NamedBase
|
|
9
9
|
m.directory File.join('app/models', class_path)
|
10
10
|
m.directory File.join('test/unit', class_path)
|
11
11
|
m.directory File.join('test/fixtures', class_path)
|
12
|
+
m.directory File.join("app/viewhints")
|
12
13
|
|
13
14
|
# Model class, unit test, and fixtures.
|
14
|
-
m.template 'model.rb', File.join('app/models',
|
15
|
-
m.template '
|
15
|
+
m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
16
|
+
m.template 'hints.rb', File.join('app/viewhints', class_path, "#{file_name}_hints.rb")
|
17
|
+
m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
|
16
18
|
m.template 'fixtures.yml', File.join('test/fixtures', class_path, "#{table_name}.yml")
|
17
19
|
end
|
18
20
|
end
|
@@ -10,21 +10,21 @@ class <%= class_name %> < ActiveRecord::Base
|
|
10
10
|
end
|
11
11
|
|
12
12
|
|
13
|
-
# ---
|
13
|
+
# --- Permissions --- #
|
14
14
|
|
15
|
-
def
|
16
|
-
|
15
|
+
def create_permitted?
|
16
|
+
acting_user.administrator?
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
|
19
|
+
def update_permitted?
|
20
|
+
acting_user.administrator?
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
|
23
|
+
def destroy_permitted?
|
24
|
+
acting_user.administrator?
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
27
|
+
def view_permitted?(field)
|
28
28
|
true
|
29
29
|
end
|
30
30
|
|
@@ -4,11 +4,20 @@ class HoboModelControllerGenerator < Rails::Generator::NamedBase
|
|
4
4
|
args[0] = args[0].pluralize
|
5
5
|
super(args, options)
|
6
6
|
end
|
7
|
+
|
8
|
+
attr_reader :subsite
|
7
9
|
|
8
10
|
def manifest
|
9
11
|
record do |m|
|
10
12
|
# Check for class naming collisions.
|
11
13
|
m.class_collisions class_path, "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper"
|
14
|
+
|
15
|
+
if class_path.length == 1 and
|
16
|
+
subsite = class_path.first and
|
17
|
+
File.exist?(File.join('app/controllers', class_path, "#{subsite}_site_controller.rb"))
|
18
|
+
|
19
|
+
@subsite = subsite.camelize
|
20
|
+
end
|
12
21
|
|
13
22
|
# Controller, helper, views, and test directories.
|
14
23
|
m.directory File.join('app/controllers', class_path)
|
@@ -33,4 +42,5 @@ class HoboModelControllerGenerator < Rails::Generator::NamedBase
|
|
33
42
|
"#{file_name}_helper.rb")
|
34
43
|
end
|
35
44
|
end
|
45
|
+
|
36
46
|
end
|
@@ -16,7 +16,7 @@ var Hobo = {
|
|
16
16
|
searchRequest: null,
|
17
17
|
uidCounter: 0,
|
18
18
|
ipeOldValues: {},
|
19
|
-
spinnerMinTime:
|
19
|
+
spinnerMinTime: 500, // milliseconds
|
20
20
|
|
21
21
|
uid: function() {
|
22
22
|
Hobo.uidCounter += 1
|
@@ -101,9 +101,10 @@ var Hobo = {
|
|
101
101
|
params.push(Form.serialize(form))
|
102
102
|
}
|
103
103
|
|
104
|
-
Hobo.showSpinner(options.message, options.spinnerNextTo)
|
104
|
+
if (options.message != false) Hobo.showSpinner(options.message, options.spinnerNextTo)
|
105
|
+
|
105
106
|
var complete = function() {
|
106
|
-
Hobo.hideSpinner();
|
107
|
+
if (options.message != false) Hobo.hideSpinner();
|
107
108
|
if (options.onComplete) options.onComplete.apply(this, arguments)
|
108
109
|
if (form && options.refocusForm) Form.focusFirstElement(form)
|
109
110
|
Event.addBehavior.reload()
|
@@ -154,15 +155,6 @@ var Hobo = {
|
|
154
155
|
}
|
155
156
|
},
|
156
157
|
|
157
|
-
getClassData: function(el, name) {
|
158
|
-
var match = el.className.match(new RegExp("(^| )" + name + ":(\\S+)($| )"))
|
159
|
-
return match && match[2]
|
160
|
-
},
|
161
|
-
|
162
|
-
getModelId: function(el) {
|
163
|
-
return Hobo.getClassData(el, 'model')
|
164
|
-
},
|
165
|
-
|
166
158
|
onFieldEditComplete: function(el, newValue) {
|
167
159
|
el = $(el)
|
168
160
|
var oldValue = Hobo.ipeOldValues[el.id]
|
@@ -203,7 +195,7 @@ var Hobo = {
|
|
203
195
|
old = val
|
204
196
|
return (Hobo.fieldSetParam(el, val) + "&" + updateParams)
|
205
197
|
},
|
206
|
-
onFailure: function(resp) {
|
198
|
+
onFailure: function(_, resp) {
|
207
199
|
alert(resp.responseText); el.innerHTML = old
|
208
200
|
},
|
209
201
|
onEnterEditMode: function() {
|
@@ -260,13 +252,13 @@ var Hobo = {
|
|
260
252
|
|
261
253
|
|
262
254
|
putUrl: function(el) {
|
263
|
-
var spec = Hobo.
|
255
|
+
var spec = Hobo.modelSpecForElement(el)
|
264
256
|
return urlBase + "/" + Hobo.pluralise(spec.name) + "/" + spec.id + "?_method=PUT"
|
265
257
|
},
|
266
258
|
|
267
259
|
|
268
260
|
urlForId: function(id) {
|
269
|
-
var spec = Hobo.
|
261
|
+
var spec = Hobo.parseModelSpec(id)
|
270
262
|
var url = urlBase + "/" + Hobo.pluralise(spec.name)
|
271
263
|
if (spec.id) { url += "/" + spec.id }
|
272
264
|
return url
|
@@ -274,7 +266,7 @@ var Hobo = {
|
|
274
266
|
|
275
267
|
|
276
268
|
fieldSetParam: function(el, val) {
|
277
|
-
var spec = Hobo.
|
269
|
+
var spec = Hobo.modelSpecForElement(el)
|
278
270
|
var res = spec.name + '[' + spec.field + ']=' + encodeURIComponent(val)
|
279
271
|
if (typeof(formAuthToken) != "undefined") {
|
280
272
|
res = res + "&" + formAuthToken.name + "=" + formAuthToken.value
|
@@ -300,7 +292,7 @@ var Hobo = {
|
|
300
292
|
var objEl = Hobo.objectElementFor(el)
|
301
293
|
Hobo.showSpinner('Removing');
|
302
294
|
function complete() {
|
303
|
-
if (options.fade) { Hobo.fadeObjectElement(
|
295
|
+
if (options.fade) { Hobo.fadeObjectElement(objEl) }
|
304
296
|
Hobo.hideSpinner()
|
305
297
|
}
|
306
298
|
if (updates && updates.length > 0) {
|
@@ -319,7 +311,7 @@ var Hobo = {
|
|
319
311
|
ajaxUpdateField: function(element, field, value, updates) {
|
320
312
|
var objectElement = Hobo.objectElementFor(element)
|
321
313
|
var url = Hobo.putUrl(objectElement)
|
322
|
-
var spec = Hobo.
|
314
|
+
var spec = Hobo.modelSpecForElement(objectElement)
|
323
315
|
var params = spec.name + '[' + field + ']=' + encodeURIComponent(value)
|
324
316
|
new Hobo.ajaxRequest(url, updates, { method:'put', message: "Saving...", params: params });
|
325
317
|
},
|
@@ -333,16 +325,27 @@ var Hobo = {
|
|
333
325
|
new Effect.Appear(empty, {delay:0.3})
|
334
326
|
}
|
335
327
|
},
|
328
|
+
|
329
|
+
|
330
|
+
getClassData: function(el, name) {
|
331
|
+
var match = el.className.match(new RegExp("(^| )" + name + "::(\\S+)($| )"))
|
332
|
+
return match && match[2]
|
333
|
+
},
|
334
|
+
|
335
|
+
|
336
|
+
getModelId: function(el) {
|
337
|
+
return Hobo.getClassData(el, 'model')
|
338
|
+
},
|
336
339
|
|
337
340
|
|
338
|
-
|
341
|
+
modelSpecForElement: function(el) {
|
339
342
|
var id = Hobo.getModelId(el)
|
340
|
-
return id && Hobo.
|
343
|
+
return id && Hobo.parseModelSpec(id)
|
341
344
|
},
|
342
345
|
|
343
346
|
|
344
|
-
|
345
|
-
m = id.gsub('-', '_').match(/^([
|
347
|
+
parseModelSpec: function(id) {
|
348
|
+
m = id.gsub('-', '_').match(/^([^:]+)(?::([^:]+)(?::([^:]+))?)?$/)
|
346
349
|
if (m) return { name: m[1], id: m[2], field: m[3] }
|
347
350
|
},
|
348
351
|
|
@@ -351,7 +354,7 @@ var Hobo = {
|
|
351
354
|
var m
|
352
355
|
while(el.getAttribute) {
|
353
356
|
id = Hobo.getModelId(el)
|
354
|
-
if (id) m = id.match(/^
|
357
|
+
if (id) m = id.match(/^[^:]+:[^:]+$/);
|
355
358
|
if (m) break;
|
356
359
|
el = el.parentNode;
|
357
360
|
}
|
@@ -367,12 +370,19 @@ var Hobo = {
|
|
367
370
|
showSpinner: function(message, nextTo) {
|
368
371
|
clearTimeout(Hobo.spinnerTimer)
|
369
372
|
Hobo.spinnerHideAt = new Date().getTime() + Hobo.spinnerMinTime;
|
370
|
-
if(t = $('ajax-progress-text'))
|
371
|
-
|
373
|
+
if (t = $('ajax-progress-text')) {
|
374
|
+
if (!message || message.length == 0) {
|
375
|
+
t.hide()
|
376
|
+
} else {
|
377
|
+
Element.update(t, message);
|
378
|
+
t.show()
|
379
|
+
}
|
380
|
+
}
|
381
|
+
if (e = $('ajax-progress')) {
|
372
382
|
if (nextTo) {
|
373
383
|
var pos = $(nextTo).cumulativeOffset()
|
374
|
-
e.style.top = pos.top + "px"
|
375
|
-
e.style.left = (pos.left + nextTo.offsetWidth) + "px"
|
384
|
+
e.style.top = pos.top - nextTo.offsetHeight + "px"
|
385
|
+
e.style.left = (pos.left + nextTo.offsetWidth + 5) + "px"
|
376
386
|
}
|
377
387
|
e.style.display = "block";
|
378
388
|
}
|
@@ -443,8 +453,13 @@ var Hobo = {
|
|
443
453
|
var table= "<table cellpadding='0' cellspacing='0' border='0' style='border-collapse: collapse; border-spacing: 0'" + attrs + ">" +
|
444
454
|
rows + "</table>"
|
445
455
|
e.outerHTML = table
|
456
|
+
},
|
457
|
+
|
458
|
+
makeHtmlEditor: function(textarea) {
|
459
|
+
// do nothing - plugins can overwrite this method
|
446
460
|
}
|
447
461
|
|
462
|
+
|
448
463
|
}
|
449
464
|
|
450
465
|
Element.findContaining = function(el, tag) {
|
@@ -549,7 +564,7 @@ new HoboBehavior("ul.input-many", {
|
|
549
564
|
"</div></li>"
|
550
565
|
var newItem = DOM.Builder.fromHTML(newItem)
|
551
566
|
ul.appendChild(newItem);
|
552
|
-
|
567
|
+
this.clearInputs(newItem);
|
553
568
|
|
554
569
|
this.updateButtons()
|
555
570
|
this.updateInputNames()
|
@@ -561,21 +576,35 @@ new HoboBehavior("ul.input-many", {
|
|
561
576
|
Event.stop(ev)
|
562
577
|
var self = this;
|
563
578
|
var li = el.up('li')
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
579
|
+
if (li.parentNode.childElements().length == 1) {
|
580
|
+
// It's the last one - don't remove it, just clear it
|
581
|
+
this.clearInputs(li)
|
582
|
+
} else {
|
583
|
+
new Effect.BlindUp(li, { duration: 0.3, afterFinish: function (ef) {
|
584
|
+
li.remove()
|
585
|
+
self.updateButtons()
|
586
|
+
self.updateInputNames()
|
587
|
+
} });
|
588
|
+
}
|
569
589
|
},
|
570
590
|
|
591
|
+
clearInputs: function(item) {
|
592
|
+
$(item).select('input').each(function(input){
|
593
|
+
if (input.getAttribute('type').toLowerCase() == 'hidden') {
|
594
|
+
input.remove()
|
595
|
+
} else {
|
596
|
+
input.value = ""
|
597
|
+
}
|
598
|
+
})
|
599
|
+
},
|
600
|
+
|
571
601
|
updateButtons: function() {
|
572
602
|
var removeButton = "<button class='remove-item'>-</button>"
|
573
|
-
var addButton
|
574
|
-
|
575
|
-
|
603
|
+
var addButton = "<button class='add-item'>+</button>"
|
604
|
+
|
576
605
|
var ul = this.element
|
577
606
|
if (ul.childElements().length == 1) {
|
578
|
-
ul.down('li').down('div.buttons').innerHTML = addButton
|
607
|
+
ul.down('li').down('div.buttons').innerHTML = removeButton + ' ' + addButton
|
579
608
|
} else {
|
580
609
|
var add = ul.selectChildren('li').selectChildren('div.buttons').down('button.add-item')
|
581
610
|
if (add) add.remove()
|
@@ -619,26 +648,32 @@ SelectManyInput = Behavior.create({
|
|
619
648
|
selected.disabled = true
|
620
649
|
select.value = ""
|
621
650
|
Event.addBehavior.reload()
|
651
|
+
this.element.fire("rapid:add", { element: newItem })
|
652
|
+
this.element.fire("rapid:change", { element: newItem })
|
622
653
|
}
|
623
654
|
},
|
624
655
|
|
625
|
-
onclick : function(
|
626
|
-
var el = Event.element(
|
627
|
-
Event.stop(e);
|
656
|
+
onclick : function(ev) {
|
657
|
+
var el = Event.element(ev);
|
628
658
|
if (el.match(".remove-item")) { this.removeOne(el.parentNode) }
|
629
659
|
},
|
630
660
|
|
631
661
|
removeOne : function(el) {
|
662
|
+
var element = this.element
|
632
663
|
new Effect.BlindUp(el,
|
633
664
|
{ duration: 0.3,
|
634
|
-
afterFinish: function (ef) {
|
665
|
+
afterFinish: function (ef) {
|
666
|
+
ef.element.remove()
|
667
|
+
element.fire("rapid:remove", { element: el })
|
668
|
+
element.fire("rapid:change", { element: el })
|
669
|
+
} } )
|
635
670
|
var label = el.down('span').innerHTML
|
636
|
-
var option = $A(
|
671
|
+
var option = $A(element.getElementsByTagName('option')).find(function(o) { return o.innerHTML == label })
|
637
672
|
option.disabled = false
|
638
673
|
},
|
639
674
|
|
640
675
|
itemAdded: function(item, option) {
|
641
|
-
this.hiddenField(item).value = option.
|
676
|
+
this.hiddenField(item).value = option.value
|
642
677
|
},
|
643
678
|
|
644
679
|
hiddenField: function(item) {
|
@@ -668,11 +703,12 @@ NameManyInput = Object.extend(SelectManyInput, {
|
|
668
703
|
|
669
704
|
AutocompleteBehavior = Behavior.create({
|
670
705
|
initialize : function() {
|
671
|
-
var
|
672
|
-
var
|
706
|
+
var match = this.element.className.match(/complete-on::([\S]+)/)
|
707
|
+
var target = match[1].split('::')
|
708
|
+
var typedId = target[0]
|
673
709
|
var completer = target[1]
|
674
710
|
|
675
|
-
var spec = Hobo.
|
711
|
+
var spec = Hobo.parseModelSpec(typedId)
|
676
712
|
var url = urlBase + "/" + Hobo.pluralise(spec.name) + "/complete_" + completer
|
677
713
|
var parameters = spec.id ? "id=" + spec.id : ""
|
678
714
|
new Ajax.Autocompleter(this.element,
|
@@ -692,13 +728,12 @@ Event.addBehavior({
|
|
692
728
|
|
693
729
|
'div.select-many.input' : SelectManyInput(),
|
694
730
|
|
695
|
-
'.
|
696
|
-
|
697
|
-
Event.stop(e);
|
731
|
+
'textarea.html' : function() {
|
732
|
+
Hobo.makeHtmlEditor(this)
|
698
733
|
},
|
699
734
|
|
700
735
|
'form.filter-menu select:change': function(event) {
|
701
|
-
var paramName = this.
|
736
|
+
var paramName = this.getAttribute('name')
|
702
737
|
var params = {}
|
703
738
|
var remove = [ 'page' ]
|
704
739
|
if ($F(this) == '') {
|
@@ -713,10 +748,11 @@ Event.addBehavior({
|
|
713
748
|
|
714
749
|
'.string.in-place-edit, .datetime.in-place-edit, .date.in-place-edit, .integer.in-place-edit, .float.in-place.edit, big-integer.in-place-edit' :
|
715
750
|
function (ev) {
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
751
|
+
|
752
|
+
var ipe = Hobo._makeInPlaceEditor(this)
|
753
|
+
ipe.getText = function() {
|
754
|
+
return this.element.innerHTML.gsub(/<br\s*\/?>/, "\n").unescapeHTML()
|
755
|
+
}
|
720
756
|
},
|
721
757
|
|
722
758
|
'.text.in-place-edit, .markdown.in-place-edit, .textile.in-place-edit' : function (ev) {
|
@@ -773,7 +809,7 @@ ElementSet = Class.create(Enumerable, {
|
|
773
809
|
select: function(selector) {
|
774
810
|
return new ElementSet(this.items.invoke('select', selector).flatten())
|
775
811
|
},
|
776
|
-
|
812
|
+
|
777
813
|
down: function(selector) {
|
778
814
|
for (var i = 0; i < this.items.length; i++) {
|
779
815
|
var match = this.items[i].down(selector)
|
@@ -801,4 +837,3 @@ Element.addMethods({
|
|
801
837
|
return new ElementSet(Selector.matchElements(element.childElements(), selector))
|
802
838
|
}
|
803
839
|
})
|
804
|
-
|