hobo 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +22 -0
- data/README.txt +18 -0
- data/bin/hobo +81 -0
- data/hobo_files/plugin/CHANGES.txt +963 -0
- data/hobo_files/plugin/LICENSE.txt +22 -0
- data/hobo_files/plugin/README +4 -0
- data/hobo_files/plugin/Rakefile +11 -0
- data/hobo_files/plugin/generators/hobo/hobo_generator.rb +37 -0
- data/hobo_files/plugin/generators/hobo/templates/application.dryml +2 -0
- data/hobo_files/plugin/generators/hobo/templates/guest.rb +31 -0
- data/hobo_files/plugin/generators/hobo_front_controller/USAGE +11 -0
- data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +90 -0
- data/hobo_files/plugin/generators/hobo_front_controller/templates/controller.rb +51 -0
- data/hobo_files/plugin/generators/hobo_front_controller/templates/functional_test.rb +18 -0
- data/hobo_files/plugin/generators/hobo_front_controller/templates/helper.rb +2 -0
- data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +43 -0
- data/hobo_files/plugin/generators/hobo_front_controller/templates/login.dryml +44 -0
- data/hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml +18 -0
- data/hobo_files/plugin/generators/hobo_front_controller/templates/signup.dryml +45 -0
- data/hobo_files/plugin/generators/hobo_model/USAGE +26 -0
- data/hobo_files/plugin/generators/hobo_model/hobo_model_generator.rb +38 -0
- data/hobo_files/plugin/generators/hobo_model/templates/fixtures.yml +11 -0
- data/hobo_files/plugin/generators/hobo_model/templates/migration.rb +13 -0
- data/hobo_files/plugin/generators/hobo_model/templates/model.rb +24 -0
- data/hobo_files/plugin/generators/hobo_model/templates/unit_test.rb +10 -0
- data/hobo_files/plugin/generators/hobo_model_controller/USAGE +30 -0
- data/hobo_files/plugin/generators/hobo_model_controller/hobo_model_controller_generator.rb +43 -0
- data/hobo_files/plugin/generators/hobo_model_controller/templates/controller.rb +5 -0
- data/hobo_files/plugin/generators/hobo_model_controller/templates/functional_test.rb +18 -0
- data/hobo_files/plugin/generators/hobo_model_controller/templates/helper.rb +2 -0
- data/hobo_files/plugin/generators/hobo_model_controller/templates/view.rhtml +2 -0
- data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +51 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.js +436 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/default_mapping.rb +11 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/banner.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_bodytop.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_corner_01.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_corner_02.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_corner_03.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_corner_04.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_shadow_bottom.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_shadow_left.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_shadow_right.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_shadow_top.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_blue.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_dblue.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_green.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_purple.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_red.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/logo.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/spinner.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt_list_img_dblue.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt_list_img_green.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt_list_img_purple.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt_list_img_red.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_corner_01.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_corner_02.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_corner_03.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_corner_04.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_shadow_bottom.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_shadow_left.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_shadow_right.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_shadow_top.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/stylesheets/application.css +390 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +104 -0
- data/hobo_files/plugin/generators/hobo_user_model/USAGE +26 -0
- data/hobo_files/plugin/generators/hobo_user_model/hobo_user_model_generator.rb +38 -0
- data/hobo_files/plugin/generators/hobo_user_model/templates/fixtures.yml +11 -0
- data/hobo_files/plugin/generators/hobo_user_model/templates/migration.rb +15 -0
- data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +58 -0
- data/hobo_files/plugin/generators/hobo_user_model/templates/unit_test.rb +10 -0
- data/hobo_files/plugin/init.rb +44 -0
- data/hobo_files/plugin/lib/action_view_extensions/base.rb +14 -0
- data/hobo_files/plugin/lib/active_record/has_many_association.rb +54 -0
- data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +22 -0
- data/hobo_files/plugin/lib/active_record/table_definition.rb +34 -0
- data/hobo_files/plugin/lib/extensions.rb +245 -0
- data/hobo_files/plugin/lib/extensions/test_case.rb +130 -0
- data/hobo_files/plugin/lib/hobo.rb +353 -0
- data/hobo_files/plugin/lib/hobo/HtmlString +3 -0
- data/hobo_files/plugin/lib/hobo/authenticated_user.rb +106 -0
- data/hobo_files/plugin/lib/hobo/authentication_support.rb +108 -0
- data/hobo_files/plugin/lib/hobo/composite_model.rb +66 -0
- data/hobo_files/plugin/lib/hobo/controller.rb +134 -0
- data/hobo_files/plugin/lib/hobo/controller_helpers.rb +135 -0
- data/hobo_files/plugin/lib/hobo/core.rb +475 -0
- data/hobo_files/plugin/lib/hobo/define_tags.rb +56 -0
- data/hobo_files/plugin/lib/hobo/dryml.rb +161 -0
- data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +126 -0
- data/hobo_files/plugin/lib/hobo/dryml/tag_module.rb +9 -0
- data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +57 -0
- data/hobo_files/plugin/lib/hobo/dryml/template.rb +586 -0
- data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +302 -0
- data/hobo_files/plugin/lib/hobo/dryml/template_handler.rb +19 -0
- data/hobo_files/plugin/lib/hobo/generator.rb +25 -0
- data/hobo_files/plugin/lib/hobo/html_string.rb +3 -0
- data/hobo_files/plugin/lib/hobo/lazy_hash.rb +28 -0
- data/hobo_files/plugin/lib/hobo/mapping_tags.rb +262 -0
- data/hobo_files/plugin/lib/hobo/markdown_string.rb +7 -0
- data/hobo_files/plugin/lib/hobo/model.rb +391 -0
- data/hobo_files/plugin/lib/hobo/model_controller.rb +676 -0
- data/hobo_files/plugin/lib/hobo/model_queries.rb +92 -0
- data/hobo_files/plugin/lib/hobo/model_support.rb +44 -0
- data/hobo_files/plugin/lib/hobo/password_string.rb +3 -0
- data/hobo_files/plugin/lib/hobo/predicate_dispatch.rb +78 -0
- data/hobo_files/plugin/lib/hobo/proc_binding.rb +32 -0
- data/hobo_files/plugin/lib/hobo/rapid.rb +447 -0
- data/hobo_files/plugin/lib/hobo/static_tags +92 -0
- data/hobo_files/plugin/lib/hobo/text.rb +3 -0
- data/hobo_files/plugin/lib/hobo/textile_string.rb +13 -0
- data/hobo_files/plugin/lib/hobo/undefined.rb +41 -0
- data/hobo_files/plugin/lib/hobo/undefined_access_error.rb +5 -0
- data/hobo_files/plugin/lib/hobo/where_fragment.rb +23 -0
- data/hobo_files/plugin/lib/rexml.rb +345 -0
- data/hobo_files/plugin/tags/core.dryml +6 -0
- data/hobo_files/plugin/tags/rapid.dryml +177 -0
- data/hobo_files/plugin/tags/rapid_editing.dryml +168 -0
- data/hobo_files/plugin/tags/rapid_navigation.dryml +95 -0
- data/hobo_files/plugin/tags/rapid_pages.dryml +175 -0
- data/hobo_files/plugin/tasks/environments.rake +19 -0
- data/hobo_files/plugin/tasks/hobo_tasks.rake +4 -0
- data/hobo_files/plugin/test/hobo_dryml_template_test.rb +7 -0
- data/hobo_files/plugin/test/hobo_test.rb +7 -0
- data/hobo_files/plugin/uninstall.rb +1 -0
- metadata +206 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
Description:
|
2
|
+
The model generator creates stubs for a new model.
|
3
|
+
|
4
|
+
The generator takes a model name as its argument. The model name may be given in CamelCase or under_score and
|
5
|
+
should not be suffixed with 'Model'.
|
6
|
+
|
7
|
+
As additional parameters, the generator will take attribute pairs described by name and type. These attributes will
|
8
|
+
be used to prepopulate the migration to create the table for the model and give you a set of predefined fixture.
|
9
|
+
You don't have to think up all attributes up front, but it's a good idea of adding just the baseline of what's
|
10
|
+
needed to start really working with the resource.
|
11
|
+
|
12
|
+
The generator creates a model class in app/models, a test suite in test/unit, test fixtures in
|
13
|
+
test/fixtures/singular_name.yml, and a migration in db/migrate.
|
14
|
+
|
15
|
+
Examples:
|
16
|
+
./script/generate model account
|
17
|
+
|
18
|
+
This will create an Account model:
|
19
|
+
Model: app/models/account.rb
|
20
|
+
Test: test/unit/account_test.rb
|
21
|
+
Fixtures: test/fixtures/accounts.yml
|
22
|
+
Migration: db/migrate/XXX_add_accounts.rb
|
23
|
+
|
24
|
+
./script/generate model post title:string created_on:date body:text published:boolean
|
25
|
+
|
26
|
+
Creates post model with predefined attributes.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class HoboModelGenerator < Rails::Generator::NamedBase
|
2
|
+
default_options :skip_migration => false
|
3
|
+
|
4
|
+
def manifest
|
5
|
+
record do |m|
|
6
|
+
# Check for class naming collisions.
|
7
|
+
m.class_collisions class_path, class_name, "#{class_name}Test"
|
8
|
+
|
9
|
+
# Model, test, and fixture directories.
|
10
|
+
m.directory File.join('app/models', class_path)
|
11
|
+
m.directory File.join('test/unit', class_path)
|
12
|
+
m.directory File.join('test/fixtures', class_path)
|
13
|
+
|
14
|
+
# Model class, unit test, and fixtures.
|
15
|
+
m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
16
|
+
m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
|
17
|
+
m.template 'fixtures.yml', File.join('test/fixtures', class_path, "#{table_name}.yml")
|
18
|
+
|
19
|
+
unless options[:skip_migration]
|
20
|
+
m.migration_template 'migration.rb', 'db/migrate', :assigns => {
|
21
|
+
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
|
22
|
+
}, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
def banner
|
29
|
+
"Usage: #{$0} generate ModelName [field:type, field:type]"
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_options!(opt)
|
33
|
+
opt.separator ''
|
34
|
+
opt.separator 'Options:'
|
35
|
+
opt.on("--skip-migration",
|
36
|
+
"Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
2
|
+
one:
|
3
|
+
id: 1
|
4
|
+
<% for attribute in attributes -%>
|
5
|
+
<%= attribute.name %>: <%= attribute.default %>
|
6
|
+
<% end -%>
|
7
|
+
two:
|
8
|
+
id: 2
|
9
|
+
<% for attribute in attributes -%>
|
10
|
+
<%= attribute.name %>: <%= attribute.default %>
|
11
|
+
<% end -%>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class <%= migration_name %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :<%= table_name %> do |t|
|
4
|
+
<% for attribute in attributes -%>
|
5
|
+
t.column :<%= attribute.name %>, :<%= attribute.type %>
|
6
|
+
<% end -%>
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
drop_table :<%= table_name %>
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class <%= class_name %> < ActiveRecord::Base
|
2
|
+
|
3
|
+
hobo_model
|
4
|
+
|
5
|
+
|
6
|
+
# --- Hobo Permissions --- #
|
7
|
+
|
8
|
+
def creatable_by?(creator)
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
def updatable_by?(updater, new)
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def deletable_by?(deleter)
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def viewable_by?(viewer, field)
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Description:
|
2
|
+
The controller generator creates stubs for a new controller and its views.
|
3
|
+
|
4
|
+
The generator takes a controller name and a list of views as arguments.
|
5
|
+
The controller name may be given in CamelCase or under_score and should
|
6
|
+
not be suffixed with 'Controller'. To create a controller within a
|
7
|
+
module, specify the controller name as 'module/controller'.
|
8
|
+
|
9
|
+
The generator creates a controller class in app/controllers with view
|
10
|
+
templates in app/views/controller_name, a helper class in app/helpers,
|
11
|
+
and a functional test suite in test/functional.
|
12
|
+
|
13
|
+
Example:
|
14
|
+
./script/generate controller CreditCard open debit credit close
|
15
|
+
|
16
|
+
Credit card controller with URLs like /credit_card/debit.
|
17
|
+
Controller: app/controllers/credit_card_controller.rb
|
18
|
+
Views: app/views/credit_card/debit.rhtml [...]
|
19
|
+
Helper: app/helpers/credit_card_helper.rb
|
20
|
+
Test: test/functional/credit_card_controller_test.rb
|
21
|
+
|
22
|
+
Modules Example:
|
23
|
+
./script/generate controller 'admin/credit_card' suspend late_fee
|
24
|
+
|
25
|
+
Credit card admin controller with URLs /admin/credit_card/suspend.
|
26
|
+
Controller: app/controllers/admin/credit_card_controller.rb
|
27
|
+
Views: app/views/admin/credit_card/debit.rhtml [...]
|
28
|
+
Helper: app/helpers/admin/credit_card_helper.rb
|
29
|
+
Test: test/functional/admin/credit_card_controller_test.rb
|
30
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class HoboModelControllerGenerator < Rails::Generator::NamedBase
|
2
|
+
|
3
|
+
def initialize(args, options)
|
4
|
+
args[0] = args[0].pluralize
|
5
|
+
super(args, options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def manifest
|
9
|
+
record do |m|
|
10
|
+
# Check for class naming collisions.
|
11
|
+
m.class_collisions class_path, "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper"
|
12
|
+
|
13
|
+
# Controller, helper, views, and test directories.
|
14
|
+
m.directory File.join('app/controllers', class_path)
|
15
|
+
m.directory File.join('app/helpers', class_path)
|
16
|
+
m.directory File.join('app/views', class_path, file_name)
|
17
|
+
m.directory File.join('test/functional', class_path)
|
18
|
+
|
19
|
+
# Controller class, functional test, and helper class.
|
20
|
+
m.template 'controller.rb',
|
21
|
+
File.join('app/controllers',
|
22
|
+
class_path,
|
23
|
+
"#{file_name}_controller.rb")
|
24
|
+
|
25
|
+
m.template 'functional_test.rb',
|
26
|
+
File.join('test/functional',
|
27
|
+
class_path,
|
28
|
+
"#{file_name}_controller_test.rb")
|
29
|
+
|
30
|
+
m.template 'helper.rb',
|
31
|
+
File.join('app/helpers',
|
32
|
+
class_path,
|
33
|
+
"#{file_name}_helper.rb")
|
34
|
+
|
35
|
+
# View template for each action.
|
36
|
+
actions.each do |action|
|
37
|
+
path = File.join('app/views', class_path, file_name, "#{action}.rhtml")
|
38
|
+
m.template 'view.rhtml', path,
|
39
|
+
:assigns => { :action => action, :path => path }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
|
2
|
+
require '<%= file_path %>_controller'
|
3
|
+
|
4
|
+
# Re-raise errors caught by the controller.
|
5
|
+
class <%= class_name %>Controller; def rescue_action(e) raise e end; end
|
6
|
+
|
7
|
+
class <%= class_name %>ControllerTest < Test::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
@controller = <%= class_name %>Controller.new
|
10
|
+
@request = ActionController::TestRequest.new
|
11
|
+
@response = ActionController::TestResponse.new
|
12
|
+
end
|
13
|
+
|
14
|
+
# Replace this with your real tests.
|
15
|
+
def test_truth
|
16
|
+
assert true
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
3
|
+
class HoboRapidGenerator < Hobo::Generator
|
4
|
+
|
5
|
+
default_options :import_tags => false
|
6
|
+
|
7
|
+
def manifest
|
8
|
+
if options[:command] == :create
|
9
|
+
import_tags if options[:import_tags]
|
10
|
+
end
|
11
|
+
|
12
|
+
record do |m|
|
13
|
+
m.file "hobo_rapid.js", "public/javascripts/hobo_rapid.js"
|
14
|
+
m.file "themes/default/default_mapping.rb", "app/views/hobolib/default_mapping.rb"
|
15
|
+
create_all(m, "themes/default/public", "public/hobothemes/default")
|
16
|
+
create_all(m, "themes/default/views", "app/views/hobolib/themes/default")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def import_tags
|
21
|
+
path = File.join(RAILS_ROOT, "app/views/hobolib/application.dryml")
|
22
|
+
|
23
|
+
tag = "<taglib src=\"plugins/hobo/tags/rapid\"/>\n\n<set_theme name=\"default\"/>\n"
|
24
|
+
|
25
|
+
src = File.read(path)
|
26
|
+
return if src.include?(tag)
|
27
|
+
|
28
|
+
# first try putting it before the first tag
|
29
|
+
done = src.sub!(/<(?!!)/, tag + "\n<")
|
30
|
+
|
31
|
+
# otherwise append it
|
32
|
+
src << tag unless done
|
33
|
+
|
34
|
+
File.open(path, 'w') {|f| f.write(src) }
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
protected
|
39
|
+
def banner
|
40
|
+
"Usage: #{$0} generate [--import-tags]"
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_options!(opt)
|
44
|
+
opt.separator ''
|
45
|
+
opt.separator 'Options:'
|
46
|
+
opt.on("--import-tags",
|
47
|
+
"Modify hobolib/application.dryml to import hobo-rapid and theme tags ") do |v|
|
48
|
+
options[:import_tags] = true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,436 @@
|
|
1
|
+
|
2
|
+
Object.extend = function(destination) {
|
3
|
+
$A(arguments).slice(1).each(function (src) {
|
4
|
+
for (var property in src) {
|
5
|
+
destination[property] = src[property];
|
6
|
+
}
|
7
|
+
})
|
8
|
+
return destination
|
9
|
+
}
|
10
|
+
|
11
|
+
Object.merge = function() {
|
12
|
+
return Object.extend.apply(this, [{}].concat($A(arguments)))
|
13
|
+
}
|
14
|
+
|
15
|
+
var Hobo = {
|
16
|
+
|
17
|
+
searchRequest: null,
|
18
|
+
uidCounter: 0,
|
19
|
+
ipeOldValues: {},
|
20
|
+
|
21
|
+
uid: function() {
|
22
|
+
Hobo.uidCounter += 1
|
23
|
+
return "uid" + Hobo.uidCounter
|
24
|
+
},
|
25
|
+
|
26
|
+
updatesForElement: function(el) {
|
27
|
+
el = $(el)
|
28
|
+
var updates = el.getAttribute("hobo_update")
|
29
|
+
return updates ? updates.split(/\s*,\s*/) : []
|
30
|
+
},
|
31
|
+
|
32
|
+
ajaxSetFieldForElement: function(el, val, options) {
|
33
|
+
var updates = Hobo.updatesForElement(el)
|
34
|
+
var params = Hobo.fieldSetParam(el, val)
|
35
|
+
var p = el.getAttribute("hobo_ajax_params")
|
36
|
+
if (p) params = params + "&" + p
|
37
|
+
|
38
|
+
var opts = Object.merge(options || {}, { params: params})
|
39
|
+
Hobo.ajaxRequest(Hobo.putUrl(el),
|
40
|
+
el.getAttribute("hobo_ajax_message") || "Changing...",
|
41
|
+
updates,
|
42
|
+
opts)
|
43
|
+
},
|
44
|
+
|
45
|
+
ajaxUpdateParams: function(updates, resultUpdates) {
|
46
|
+
var params = []
|
47
|
+
var i = 0
|
48
|
+
if (updates.length > 0) {
|
49
|
+
updates.each(function(dom_id) {
|
50
|
+
params.push("render["+i+"][part]=" + hoboParts[dom_id][0])
|
51
|
+
params.push("render["+i+"][id]=" + dom_id)
|
52
|
+
params.push("render["+i+"][object]=" + hoboParts[dom_id][1])
|
53
|
+
i += 1
|
54
|
+
})
|
55
|
+
params.push("part_page=" + hoboPartPage)
|
56
|
+
}
|
57
|
+
|
58
|
+
if (resultUpdates) {
|
59
|
+
resultUpdates.each(function (resultUpdate) {
|
60
|
+
params.push("render["+i+"][id]=" + resultUpdate.id)
|
61
|
+
params.push("render["+i+"][result]=" + resultUpdate.result)
|
62
|
+
if (resultUpdate.func) {
|
63
|
+
params.push("render["+i+"][function]=" + resultUpdate.func)
|
64
|
+
}
|
65
|
+
i += 1
|
66
|
+
})
|
67
|
+
}
|
68
|
+
return params.join('&')
|
69
|
+
},
|
70
|
+
|
71
|
+
ajaxRequest: function(url_or_form, message, updates, options) {
|
72
|
+
options = Object.merge({ asynchronous:true,
|
73
|
+
evalScripts:true,
|
74
|
+
resetForm: true,
|
75
|
+
refocusForm: true
|
76
|
+
}, options)
|
77
|
+
if (typeof url_or_form == "string") {
|
78
|
+
var url = url_or_form
|
79
|
+
var form = false
|
80
|
+
} else {
|
81
|
+
var form = url_or_form
|
82
|
+
var url = form.action
|
83
|
+
}
|
84
|
+
var params = []
|
85
|
+
|
86
|
+
updateParams = Hobo.ajaxUpdateParams(updates, options.resultUpdate)
|
87
|
+
if (updateParams != "") { params.push(updateParams) }
|
88
|
+
|
89
|
+
if (options.params) {
|
90
|
+
params.push(options.params)
|
91
|
+
delete options.params
|
92
|
+
}
|
93
|
+
|
94
|
+
if (form) {
|
95
|
+
params.push(Form.serialize(form))
|
96
|
+
}
|
97
|
+
|
98
|
+
Hobo.showSpinner(message)
|
99
|
+
var complete = function() {
|
100
|
+
if (form && options.resetForm) form.reset();
|
101
|
+
Hobo.hideSpinner();
|
102
|
+
|
103
|
+
if (options.onComplete)
|
104
|
+
options.onComplete.apply(this, arguments)
|
105
|
+
if (form && options) Form.focusFirstElement(form)
|
106
|
+
}
|
107
|
+
if (options.method && options.method.toLowerCase() == "put") {
|
108
|
+
delete options.method
|
109
|
+
params.push("_method=PUT")
|
110
|
+
}
|
111
|
+
|
112
|
+
if (!options.onFailure) {
|
113
|
+
options.onFailure = function(response) {
|
114
|
+
alert(response.responseText)
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
new Ajax.Request(url, Object.merge(options, { parameters: params.join("&"), onComplete: complete }))
|
119
|
+
},
|
120
|
+
|
121
|
+
hide: function() {
|
122
|
+
for (i = 0; i < arguments.length; i++) {
|
123
|
+
if ($(arguments[i])) {
|
124
|
+
Element.addClassName(arguments[i], 'hidden')
|
125
|
+
}
|
126
|
+
}
|
127
|
+
},
|
128
|
+
|
129
|
+
show: function() {
|
130
|
+
for (i = 0; i < arguments.length; i++) {
|
131
|
+
if ($(arguments[i])) {
|
132
|
+
Element.removeClassName(arguments[i], 'hidden')
|
133
|
+
}
|
134
|
+
}
|
135
|
+
},
|
136
|
+
|
137
|
+
toggle: function() {
|
138
|
+
for (i = 0; i < arguments.length; i++) {
|
139
|
+
if ($(arguments[i])) {
|
140
|
+
if(Element.hasClassName(arguments[i], 'hidden')) {
|
141
|
+
Element.removeClassName(arguments[i], 'hidden')
|
142
|
+
} else {
|
143
|
+
Element.addClassName(arguments[i], 'hidden')
|
144
|
+
}
|
145
|
+
}
|
146
|
+
}
|
147
|
+
},
|
148
|
+
|
149
|
+
onFieldEditComplete: function(el, newValue) {
|
150
|
+
el = $(el)
|
151
|
+
var oldValue = Hobo.ipeOldValues[el.id]
|
152
|
+
delete Hobo.ipeOldValues[el.id]
|
153
|
+
|
154
|
+
var blank = el.getAttribute("hobo_blank_message")
|
155
|
+
if (blank && newValue.strip().length == 0) {
|
156
|
+
el.update(blank)
|
157
|
+
} else {
|
158
|
+
el.update(newValue)
|
159
|
+
}
|
160
|
+
|
161
|
+
var modelId = el.getAttribute('hobo_model_id')
|
162
|
+
if (oldValue) {
|
163
|
+
$$("*[hobo_model_id=" + modelId + "]").each(function(e) {
|
164
|
+
if (e != el && e.innerHTML == oldValue) e.update(newValue)
|
165
|
+
})
|
166
|
+
}
|
167
|
+
},
|
168
|
+
|
169
|
+
_makeInPlaceEditor: function(el, options) {
|
170
|
+
var old
|
171
|
+
var spec = Hobo.parseFieldId(el)
|
172
|
+
var updates = Hobo.updatesForElement(el)
|
173
|
+
var id = el.id
|
174
|
+
if (!id) { id = el.id = Hobo.uid() }
|
175
|
+
var updateParams = Hobo.ajaxUpdateParams(updates, [{id: id,
|
176
|
+
result: 'new_field_value',
|
177
|
+
func: "Hobo.onFieldEditComplete"}])
|
178
|
+
opts = {okButton: false,
|
179
|
+
cancelLink: false,
|
180
|
+
submitOnBlur: true,
|
181
|
+
callback: function(form, val) {
|
182
|
+
old = val
|
183
|
+
return (Hobo.fieldSetParam(el, val) + "&" + updateParams)
|
184
|
+
},
|
185
|
+
highlightcolor: '#ffffff',
|
186
|
+
highlightendcolor: Hobo.backgroundColor(el),
|
187
|
+
onFailure: function(resp) { alert(resp.responseText); el.innerHTML = old },
|
188
|
+
evalScripts: true
|
189
|
+
}
|
190
|
+
Object.extend(opts, options)
|
191
|
+
var ipe = new Ajax.InPlaceEditor(el, Hobo.putUrl(el), opts)
|
192
|
+
ipe.onEnterEditMode = function() {
|
193
|
+
var blank_message = el.getAttribute("hobo_blank_message")
|
194
|
+
if (el.innerHTML.gsub(" ", " ") == blank_message) {
|
195
|
+
el.innerHTML = ""
|
196
|
+
} else {
|
197
|
+
Hobo.ipeOldValues[el.id] = el.innerHTML
|
198
|
+
}
|
199
|
+
}
|
200
|
+
return ipe
|
201
|
+
},
|
202
|
+
|
203
|
+
applyEvents: function(root) {
|
204
|
+
root = $(root)
|
205
|
+
function select(p) {
|
206
|
+
return new Selector(p).findElements(root)
|
207
|
+
}
|
208
|
+
|
209
|
+
select(".in_place_textfield_bhv").each(function (el) {
|
210
|
+
ipe = Hobo._makeInPlaceEditor(el)
|
211
|
+
ipe.getText = function() {
|
212
|
+
return this.element.innerHTML.gsub(/<br\s*\/?>/, "\n").unescapeHTML()
|
213
|
+
}
|
214
|
+
})
|
215
|
+
|
216
|
+
select(".in_place_textarea_bhv").each(function (el) {
|
217
|
+
ipe = Hobo._makeInPlaceEditor(el, {rows: 2})
|
218
|
+
ipe.getText = function() {
|
219
|
+
return this.element.innerHTML.gsub(/<br\s*\/?>/, "\n").unescapeHTML()
|
220
|
+
}
|
221
|
+
})
|
222
|
+
|
223
|
+
select(".in_place_html_textarea_bhv").each(function (el) {
|
224
|
+
var ipe = Hobo._makeInPlaceEditor(el, {rows: 2, handleLineBreaks: false})
|
225
|
+
if (typeof(tinyMCE) != "undefined") {
|
226
|
+
ipe.afterEnterEditMode = function() {
|
227
|
+
var id = this.form.id = Hobo.uid()
|
228
|
+
|
229
|
+
// 'orrible 'ack
|
230
|
+
// What is the correct way to individually configure a tinyMCE instace?
|
231
|
+
var old = tinyMCE.settings.theme_advanced_buttons1
|
232
|
+
tinyMCE.settings.theme_advanced_buttons1 += ", separator, save"
|
233
|
+
tinyMCE.addMCEControl(this.editField, id);
|
234
|
+
tinyMCE.settings.theme_advanced_buttons1 = old
|
235
|
+
|
236
|
+
this.form.onsubmit = function() {
|
237
|
+
tinyMCE.removeMCEControl(ipe.form.id)
|
238
|
+
setTimeout(ipe.onSubmit.bind(ipe), 10)
|
239
|
+
return false
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}
|
243
|
+
})
|
244
|
+
|
245
|
+
select("select.number_editor_bhv").each(function(el) {
|
246
|
+
el.onchange = function() {
|
247
|
+
Hobo.ajaxSetFieldForElement(el, el.value)
|
248
|
+
}
|
249
|
+
})
|
250
|
+
|
251
|
+
select(".autocomplete_bhv").each(function (el) {
|
252
|
+
options = {paramName: "query", minChars: 3, method: 'get' }
|
253
|
+
if (el.hasClassName("autosubmit")) {
|
254
|
+
options.afterUpdateElement = function(el, item) { el.form.onsubmit(); }
|
255
|
+
}
|
256
|
+
new Ajax.Autocompleter(el, el.id + "_completions", el.getAttribute("autocomplete_url"),
|
257
|
+
options);
|
258
|
+
});
|
259
|
+
|
260
|
+
select(".search_bhv").each(function(el) {
|
261
|
+
new Form.Element.Observer(el, 1.0, function() { Hobo.doSearch(el) })
|
262
|
+
});
|
263
|
+
},
|
264
|
+
|
265
|
+
|
266
|
+
doSearch: function(el) {
|
267
|
+
el = $(el)
|
268
|
+
var spinner = $(el.getAttribute("search_spinner") || "search_spinner")
|
269
|
+
var search_results = $(el.getAttribute("search_results") || "search_results")
|
270
|
+
var search_results_panel = $(el.getAttribute("search_results_panel") || "search_results_panel")
|
271
|
+
var url = el.getAttribute("search_url") || (urlBase + "/search")
|
272
|
+
|
273
|
+
el.focus();
|
274
|
+
var value = $F(el)
|
275
|
+
if (Hobo.searchRequest) { Hobo.searchRequest.transport.abort() }
|
276
|
+
if (value.length >= 3) {
|
277
|
+
if (spinner) Hobo.show(spinner);
|
278
|
+
Hobo.searchRequest = new Ajax.Updater(search_results,
|
279
|
+
url,
|
280
|
+
{ asynchronous:true,
|
281
|
+
evalScripts:true,
|
282
|
+
onSuccess:function(request) {
|
283
|
+
if (spinner) Hobo.hide(spinner)
|
284
|
+
if (search_results_panel) {
|
285
|
+
Hobo.show(search_results_panel)
|
286
|
+
}
|
287
|
+
},
|
288
|
+
parameters:"query=" + value });
|
289
|
+
} else {
|
290
|
+
Hobo.updateElement(search_results, '')
|
291
|
+
Hobo.hide(search_results_panel)
|
292
|
+
}
|
293
|
+
},
|
294
|
+
|
295
|
+
|
296
|
+
putUrl: function(el) {
|
297
|
+
spec = Hobo.parseFieldId(el)
|
298
|
+
return urlBase + "/" + controllerNames[spec.name] + "/" + spec.id + "?_method=PUT"
|
299
|
+
},
|
300
|
+
|
301
|
+
|
302
|
+
fieldSetParam: function(el, val) {
|
303
|
+
spec = Hobo.parseFieldId(el)
|
304
|
+
return spec.name + '[' + spec.field + ']=' + escape(val)
|
305
|
+
},
|
306
|
+
|
307
|
+
fadeObjectElement: function(el) {
|
308
|
+
new Effect.Fade(Hobo.objectElementFor(el),
|
309
|
+
{ duration: 0.5,
|
310
|
+
afterFinish: function (ef) { ef.element.remove() } });
|
311
|
+
},
|
312
|
+
|
313
|
+
removeButton: function(el, url, updates, fade) {
|
314
|
+
if (fade == null) { fade = true; }
|
315
|
+
if (confirm("Are you sure?")) {
|
316
|
+
objEl = Hobo.objectElementFor(el)
|
317
|
+
Hobo.showSpinner('Removing');
|
318
|
+
function complete() {
|
319
|
+
if (fade) { Hobo.fadeObjectElement(el) }
|
320
|
+
Hobo.hideSpinner()
|
321
|
+
}
|
322
|
+
if (updates && updates.length > 0) {
|
323
|
+
new Hobo.ajaxRequest(url, "Removing", updates, { method:'delete',
|
324
|
+
onComplete: complete});
|
325
|
+
} else {
|
326
|
+
new Ajax.Request(url, {asynchronous:true, evalScripts:true, method:'delete',
|
327
|
+
onComplete: complete});
|
328
|
+
}
|
329
|
+
}
|
330
|
+
},
|
331
|
+
|
332
|
+
|
333
|
+
parseFieldId: function(el) {
|
334
|
+
id = el.getAttribute("hobo_model_id")
|
335
|
+
if (!id) return
|
336
|
+
m = id.match(/^([a-z_]+)_([0-9]+)_([a-z_]+)$/)
|
337
|
+
if (m) return { name: m[1], id: m[2], field: m[3] }
|
338
|
+
},
|
339
|
+
|
340
|
+
appendRow: function(el, rowSrc) {
|
341
|
+
// IE friendly method to add a <tr> (from html source) to a table
|
342
|
+
// el should be an element that contains *only* a table
|
343
|
+
el = $(el);
|
344
|
+
el.innerHTML = el.innerHTML.replace("</table>", "") + rowSrc + "</table>";
|
345
|
+
Hobo.applyEvents(el)
|
346
|
+
},
|
347
|
+
|
348
|
+
objectElementFor: function(el) {
|
349
|
+
var m
|
350
|
+
while(el.getAttribute) {
|
351
|
+
id = el.getAttribute("hobo_model_id");
|
352
|
+
if (id) m = id.match(/^([a-z_]+)_([0-9]+)(_[a-z0-9_]*)?$/);
|
353
|
+
if (m) break;
|
354
|
+
el = el.parentNode;
|
355
|
+
}
|
356
|
+
if (m) return el;
|
357
|
+
},
|
358
|
+
|
359
|
+
|
360
|
+
showSpinner: function(message) {
|
361
|
+
if(t = $('ajax_progress_text')) Element.update(t, message);
|
362
|
+
if(e = $('ajax_progress')) e.style.display = "block";
|
363
|
+
},
|
364
|
+
|
365
|
+
|
366
|
+
hideSpinner: function() {
|
367
|
+
if(e = $('ajax_progress')) e.style.display = "none";
|
368
|
+
},
|
369
|
+
|
370
|
+
|
371
|
+
updateElement: function(id, content) {
|
372
|
+
Element.update(id, content)
|
373
|
+
Hobo.applyEvents(id)
|
374
|
+
},
|
375
|
+
|
376
|
+
rgbColorToHex: function(color) {
|
377
|
+
parts = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)/.exec(color)
|
378
|
+
function hexPart(s) {
|
379
|
+
var res = (s * 1).toString(16)
|
380
|
+
return res.length == 1 ? '0' + res : res
|
381
|
+
}
|
382
|
+
if (parts) {
|
383
|
+
return '#' + hexPart(parts[1]) + hexPart(parts[2]) + hexPart(parts[3])
|
384
|
+
} else {
|
385
|
+
return color
|
386
|
+
}
|
387
|
+
},
|
388
|
+
|
389
|
+
getStyle: function(el, styleProp) {
|
390
|
+
if (el.currentStyle)
|
391
|
+
var y = el.currentStyle[styleProp];
|
392
|
+
else if (window.getComputedStyle)
|
393
|
+
var y = document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
|
394
|
+
return y;
|
395
|
+
},
|
396
|
+
|
397
|
+
backgroundColor: function(el) {
|
398
|
+
return Hobo.rgbColorToHex(Hobo.getStyle(el, 'background-color'))
|
399
|
+
}
|
400
|
+
|
401
|
+
}
|
402
|
+
|
403
|
+
Element.findContaining = function(el, tag) {
|
404
|
+
el = $(el)
|
405
|
+
tag = tag.toLowerCase()
|
406
|
+
e = el.parentNode
|
407
|
+
while (el) {
|
408
|
+
if (el.nodeName.toLowerCase() == tag) {
|
409
|
+
return el;
|
410
|
+
}
|
411
|
+
e = el.parentNode
|
412
|
+
}
|
413
|
+
return null;
|
414
|
+
}
|
415
|
+
|
416
|
+
// Fix scriptaculous - don't remove <p> tags please!
|
417
|
+
Ajax.InPlaceEditor.prototype.convertHTMLLineBreaks = function(string) {
|
418
|
+
return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n");
|
419
|
+
}
|
420
|
+
|
421
|
+
|
422
|
+
origEnterEditMode = Ajax.InPlaceEditor.prototype.enterEditMode
|
423
|
+
Ajax.InPlaceEditor.prototype.enterEditMode = function(evt) {
|
424
|
+
origEnterEditMode.bind(this)(evt)
|
425
|
+
if (this.afterEnterEditMode) this.afterEnterEditMode()
|
426
|
+
return false
|
427
|
+
}
|
428
|
+
|
429
|
+
// Silence errors from IE :-(
|
430
|
+
Field.scrollFreeActivate = function(field) {
|
431
|
+
setTimeout(function() {
|
432
|
+
try {
|
433
|
+
Field.activate(field);
|
434
|
+
} catch(e) {}
|
435
|
+
}, 1);
|
436
|
+
}
|