zena 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +18 -0
- data/README.txt +133 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/comments_controller.rb +141 -0
- data/app/controllers/data_entries_controller.rb +81 -0
- data/app/controllers/discussions_controller.rb +48 -0
- data/app/controllers/documents_controller.rb +136 -0
- data/app/controllers/groups_controller.rb +99 -0
- data/app/controllers/iformats_controller.rb +78 -0
- data/app/controllers/links_controller.rb +98 -0
- data/app/controllers/nodes_controller.rb +497 -0
- data/app/controllers/preferences_controller.rb +52 -0
- data/app/controllers/relations_controller.rb +95 -0
- data/app/controllers/sessions_controller.rb +41 -0
- data/app/controllers/sites_controller.rb +112 -0
- data/app/controllers/users_controller.rb +139 -0
- data/app/controllers/versions_controller.rb +268 -0
- data/app/controllers/virtual_classes_controller.rb +95 -0
- data/app/helpers/application_helper.rb +4 -0
- data/app/helpers/documents_helper.rb +13 -0
- data/app/helpers/nodes_helper.rb +20 -0
- data/app/helpers/versions_helper.rb +18 -0
- data/app/models/book.rb +242 -0
- data/app/models/cache.rb +52 -0
- data/app/models/cached_page.rb +134 -0
- data/app/models/comment.rb +125 -0
- data/app/models/contact.rb +32 -0
- data/app/models/contact_content.rb +70 -0
- data/app/models/contact_version.rb +40 -0
- data/app/models/data_entry.rb +162 -0
- data/app/models/discussion.rb +65 -0
- data/app/models/document.rb +146 -0
- data/app/models/document_content.rb +186 -0
- data/app/models/document_version.rb +13 -0
- data/app/models/dyn_attribute.rb +4 -0
- data/app/models/group.rb +142 -0
- data/app/models/iformat.rb +146 -0
- data/app/models/image.rb +96 -0
- data/app/models/image_content.rb +189 -0
- data/app/models/image_version.rb +21 -0
- data/app/models/link.rb +121 -0
- data/app/models/node.rb +1752 -0
- data/app/models/note.rb +58 -0
- data/app/models/page.rb +53 -0
- data/app/models/project.rb +10 -0
- data/app/models/reference.rb +18 -0
- data/app/models/relation.rb +18 -0
- data/app/models/relation_proxy.rb +379 -0
- data/app/models/section.rb +5 -0
- data/app/models/site.rb +355 -0
- data/app/models/skin.rb +20 -0
- data/app/models/template.rb +134 -0
- data/app/models/template_content.rb +112 -0
- data/app/models/template_version.rb +37 -0
- data/app/models/text_document.rb +162 -0
- data/app/models/text_document_content.rb +46 -0
- data/app/models/text_document_version.rb +21 -0
- data/app/models/user.rb +412 -0
- data/app/models/version.rb +328 -0
- data/app/models/virtual_class.rb +134 -0
- data/app/models/zip.rb +6 -0
- data/app/views/comments/_add.rhtml +6 -0
- data/app/views/comments/_bin.rhtml +5 -0
- data/app/views/comments/_form.rhtml +26 -0
- data/app/views/comments/_li.rhtml +13 -0
- data/app/views/comments/_li_simple.rhtml +3 -0
- data/app/views/comments/_list.rhtml +13 -0
- data/app/views/comments/create.rjs +32 -0
- data/app/views/comments/edit.rjs +2 -0
- data/app/views/comments/empty_bin.rjs +1 -0
- data/app/views/comments/index.rhtml +12 -0
- data/app/views/comments/publish.rjs +7 -0
- data/app/views/comments/remove.rjs +9 -0
- data/app/views/comments/reply_to.rjs +2 -0
- data/app/views/comments/update.rjs +1 -0
- data/app/views/data_entries/_li.html.erb +9 -0
- data/app/views/data_entries/create.rjs +1 -0
- data/app/views/data_entries/destroy.rjs +1 -0
- data/app/views/data_entries/edit.rjs +1 -0
- data/app/views/data_entries/index.html.erb +5 -0
- data/app/views/data_entries/show.html.erb +5 -0
- data/app/views/data_entries/show.rjs +1 -0
- data/app/views/data_entries/update.rjs +1 -0
- data/app/views/discussions/_add.rhtml +6 -0
- data/app/views/discussions/_form.rhtml +21 -0
- data/app/views/discussions/_li.rhtml +9 -0
- data/app/views/discussions/_list.rhtml +4 -0
- data/app/views/discussions/create.rjs +10 -0
- data/app/views/discussions/remove.rjs +7 -0
- data/app/views/discussions/show.rjs +1 -0
- data/app/views/discussions/update.rjs +2 -0
- data/app/views/documents/_crop.rhtml +10 -0
- data/app/views/documents/crop_form.rjs +4 -0
- data/app/views/documents/new.rhtml +18 -0
- data/app/views/documents/show.rhtml +17 -0
- data/app/views/groups/_add.rhtml +6 -0
- data/app/views/groups/_form.rhtml +44 -0
- data/app/views/groups/_li.rhtml +13 -0
- data/app/views/groups/create.rjs +8 -0
- data/app/views/groups/destroy.rjs +2 -0
- data/app/views/groups/edit.html.erb +5 -0
- data/app/views/groups/index.rhtml +6 -0
- data/app/views/groups/show.html.erb +5 -0
- data/app/views/groups/show.rjs +1 -0
- data/app/views/iformats/_add.rhtml +6 -0
- data/app/views/iformats/_form.rhtml +29 -0
- data/app/views/iformats/_li.rhtml +15 -0
- data/app/views/iformats/create.rjs +8 -0
- data/app/views/iformats/destroy.rjs +11 -0
- data/app/views/iformats/edit.html.erb +5 -0
- data/app/views/iformats/index.rhtml +7 -0
- data/app/views/iformats/show.html.erb +5 -0
- data/app/views/iformats/show.rjs +1 -0
- data/app/views/iformats/update.rjs +5 -0
- data/app/views/image/_title.rhtml +8 -0
- data/app/views/links/_add.rhtml +6 -0
- data/app/views/links/_form.rhtml +34 -0
- data/app/views/links/_li.rhtml +7 -0
- data/app/views/links/_list.rhtml +9 -0
- data/app/views/links/create.rjs +5 -0
- data/app/views/links/destroy.rjs +11 -0
- data/app/views/links/show.rjs +5 -0
- data/app/views/nodes/404.html +15 -0
- data/app/views/nodes/500.html +15 -0
- data/app/views/nodes/_dates.rhtml +13 -0
- data/app/views/nodes/_edit_attribute.rhtml +32 -0
- data/app/views/nodes/_gallery.rhtml +16 -0
- data/app/views/nodes/_groups.rhtml +25 -0
- data/app/views/nodes/_import_results.rhtml +20 -0
- data/app/views/nodes/_list_nodes.rhtml +9 -0
- data/app/views/nodes/_parent.rhtml +15 -0
- data/app/views/nodes/_position.rhtml +22 -0
- data/app/views/nodes/_results.rhtml +29 -0
- data/app/views/nodes/_show_attr.rhtml +6 -0
- data/app/views/nodes/_table.rhtml +14 -0
- data/app/views/nodes/clear_order.rjs +7 -0
- data/app/views/nodes/create.rjs +17 -0
- data/app/views/nodes/drive.rjs +2 -0
- data/app/views/nodes/drop.rjs +1 -0
- data/app/views/nodes/edit.html.erb +17 -0
- data/app/views/nodes/edit.rjs +7 -0
- data/app/views/nodes/import.rhtml +10 -0
- data/app/views/nodes/save_text.rjs +13 -0
- data/app/views/nodes/search.rjs +3 -0
- data/app/views/nodes/show.rjs +1 -0
- data/app/views/nodes/table_update.rjs +8 -0
- data/app/views/nodes/update.rjs +29 -0
- data/app/views/nodes/zafu.rjs +1 -0
- data/app/views/relations/_add.erb +6 -0
- data/app/views/relations/_form.erb +43 -0
- data/app/views/relations/_li.erb +16 -0
- data/app/views/relations/create.rjs +8 -0
- data/app/views/relations/destroy.rjs +6 -0
- data/app/views/relations/edit.erb +2 -0
- data/app/views/relations/index.erb +6 -0
- data/app/views/relations/new.erb +2 -0
- data/app/views/relations/show.rjs +1 -0
- data/app/views/relations/update.rjs +5 -0
- data/app/views/search/_form.rhtml +13 -0
- data/app/views/sites/_form.erb +37 -0
- data/app/views/sites/_li.erb +13 -0
- data/app/views/sites/clear_cache.rjs +2 -0
- data/app/views/sites/edit.erb +2 -0
- data/app/views/sites/index.erb +6 -0
- data/app/views/sites/show.rjs +1 -0
- data/app/views/sites/update.rjs +5 -0
- data/app/views/sites/zena_up.html.erb +11 -0
- data/app/views/templates/defaults/+adminLayout.zafu +69 -0
- data/app/views/templates/defaults/+login.zafu +32 -0
- data/app/views/templates/document_create_tabs/_file.rhtml +13 -0
- data/app/views/templates/document_create_tabs/_import.rhtml +9 -0
- data/app/views/templates/document_create_tabs/_template.rhtml +22 -0
- data/app/views/templates/document_create_tabs/_text_doc.rhtml +14 -0
- data/app/views/templates/drive_tabs/_drive.rhtml +11 -0
- data/app/views/templates/drive_tabs/_help.rhtml +0 -0
- data/app/views/templates/drive_tabs/_links.rhtml +8 -0
- data/app/views/templates/edit_tabs/_contact.rhtml +8 -0
- data/app/views/templates/edit_tabs/_custom.rhtml +6 -0
- data/app/views/templates/edit_tabs/_document.rhtml +8 -0
- data/app/views/templates/edit_tabs/_help.rhtml +7 -0
- data/app/views/templates/edit_tabs/_image.rhtml +19 -0
- data/app/views/templates/edit_tabs/_template.rhtml +8 -0
- data/app/views/templates/edit_tabs/_text.rhtml +1 -0
- data/app/views/templates/edit_tabs/_textdocument.rhtml +16 -0
- data/app/views/templates/edit_tabs/_title.rhtml +27 -0
- data/app/views/users/_add.rhtml +6 -0
- data/app/views/users/_form.rhtml +49 -0
- data/app/views/users/_li.rhtml +18 -0
- data/app/views/users/change_info.rjs +7 -0
- data/app/views/users/change_password.rjs +7 -0
- data/app/views/users/create.rjs +8 -0
- data/app/views/users/index.rhtml +7 -0
- data/app/views/users/preferences.html.erb +40 -0
- data/app/views/users/show.rjs +1 -0
- data/app/views/users/update.rjs +16 -0
- data/app/views/versions/_li.rhtml +3 -0
- data/app/views/versions/_list.rhtml +5 -0
- data/app/views/versions/_tr.rhtml +10 -0
- data/app/views/versions/backup.rjs +16 -0
- data/app/views/versions/css_preview.rjs +2 -0
- data/app/views/versions/destroy.rjs +6 -0
- data/app/views/versions/diff.rjs +3 -0
- data/app/views/versions/edit.rhtml +55 -0
- data/app/views/versions/preview.rjs +9 -0
- data/app/views/versions/show.rjs +5 -0
- data/app/views/versions/update.rjs +9 -0
- data/app/views/virtual_classes/_add.erb +6 -0
- data/app/views/virtual_classes/_form.erb +30 -0
- data/app/views/virtual_classes/_li.erb +12 -0
- data/app/views/virtual_classes/create.rjs +8 -0
- data/app/views/virtual_classes/destroy.rjs +6 -0
- data/app/views/virtual_classes/index.erb +7 -0
- data/app/views/virtual_classes/new.erb +2 -0
- data/app/views/virtual_classes/show.rjs +1 -0
- data/app/views/virtual_classes/update.rjs +5 -0
- data/bin/zena +5 -0
- data/bricks/captcha/MIT-LICENSE +19 -0
- data/bricks/captcha/README +11 -0
- data/bricks/captcha/patch/application_controller.rb +10 -0
- data/bricks/captcha/patch/application_helper.rb +32 -0
- data/bricks/captcha/patch/site.rb +2 -0
- data/bricks/captcha/zafu/captcha.rb +29 -0
- data/bricks/math/patch/application_helper.rb +95 -0
- data/bricks/tags/README +31 -0
- data/bricks/tags/lib/has_tags.rb +164 -0
- data/bricks/tags/patch/node.rb +15 -0
- data/bricks/tags/test/sites/zena/links.yml +11 -0
- data/bricks/tags/test/unit/tags_test.rb +103 -0
- data/bricks/tags/test/zafu/tags.yml +28 -0
- data/bricks/toto.zip +0 -0
- data/config/awstats.conf.rhtml +1497 -0
- data/config/boot.rb +109 -0
- data/config/database.rhtml +25 -0
- data/config/database.yml +40 -0
- data/config/database_example.yml +27 -0
- data/config/deploy.rb +382 -0
- data/config/deploy_config_example.rb +7 -0
- data/config/environment.rb +13 -0
- data/config/environments/development.rb +21 -0
- data/config/environments/production.rb +27 -0
- data/config/environments/test.rb +22 -0
- data/config/gems.yml +46 -0
- data/config/httpd.rhtml +18 -0
- data/config/initializers/mime_types.rb +10 -0
- data/config/initializers/zena.rb +1 -0
- data/config/locales/de.yml +120 -0
- data/config/locales/fr-CH.yml +123 -0
- data/config/locales/fr.yml +123 -0
- data/config/mongrel_upload_progress.conf +7 -0
- data/config/routes.rb +3 -0
- data/config/start.html +44 -0
- data/config/stats.vhost.rhtml +40 -0
- data/config/vhost.rhtml +84 -0
- data/config/vhost_www.rhtml +10 -0
- data/config/zena.rb +39 -0
- data/db/init/base/help.en.zml +94 -0
- data/db/init/base/help.fr.zml +88 -0
- data/db/init/base/skins.zml +3 -0
- data/db/init/base/skins/default.zml +10 -0
- data/db/init/base/skins/default/Node-+adminLayout.zafu +45 -0
- data/db/init/base/skins/default/Node-+index.zafu +1 -0
- data/db/init/base/skins/default/Node-+login.zafu +25 -0
- data/db/init/base/skins/default/Node-+notFound.zafu +14 -0
- data/db/init/base/skins/default/Node-+popupLayout.zafu +39 -0
- data/db/init/base/skins/default/Node-+search.zafu +20 -0
- data/db/init/base/skins/default/Node-tree.zafu +19 -0
- data/db/init/base/skins/default/Node.zafu +95 -0
- data/db/init/base/skins/default/Project.zafu +8 -0
- data/db/init/base/skins/default/favicon.png +0 -0
- data/db/init/base/skins/default/notes.zafu +22 -0
- data/db/init/base/skins/default/style.css +80 -0
- data/db/migrate/001_create_base.rb +156 -0
- data/db/migrate/002_add_time_zone_to_users.rb +9 -0
- data/db/migrate/003_add_custom_base_flag.rb +11 -0
- data/db/migrate/004_rename_template_skin.rb +9 -0
- data/db/migrate/005_create_cached_pages.rb +20 -0
- data/db/migrate/006_create_sites.rb +60 -0
- data/db/migrate/007_replace_id_by_zip.rb +17 -0
- data/db/migrate/008_user_status.rb +10 -0
- data/db/migrate/009_fulltext.rb +13 -0
- data/db/migrate/010_create_template_content.rb +17 -0
- data/db/migrate/011_project_to_section.rb +9 -0
- data/db/migrate/012_add_project_id.rb +12 -0
- data/db/migrate/013_remove_defaults.rb +29 -0
- data/db/migrate/014_add_sort_field.rb +10 -0
- data/db/migrate/015_add_dyn_attributes.rb +18 -0
- data/db/migrate/016_remove_translations.rb +20 -0
- data/db/migrate/017_rename_authorize.rb +9 -0
- data/db/migrate/018_add_auth_option.rb +9 -0
- data/db/migrate/019_remove_user_status.rb +25 -0
- data/db/migrate/020_create_participation.rb +30 -0
- data/db/migrate/021_create_relations.rb +23 -0
- data/db/migrate/022_create_virtual_classes.rb +20 -0
- data/db/migrate/023_ip_on_anonymous_comment.rb +9 -0
- data/db/migrate/024_correct_vclass_kpath.rb +11 -0
- data/db/migrate/025_move_tag_into_vclass.rb +13 -0
- data/db/migrate/026_rename_templates.rb +47 -0
- data/db/migrate/027_add_country_to_contacts.rb +9 -0
- data/db/migrate/028_change_size_of_conten_type_field.rb +9 -0
- data/db/migrate/029_create_data_entries.rb +21 -0
- data/db/migrate/030_redit_auto_publish_site_settings.rb +13 -0
- data/db/migrate/031_create_iformats.rb +21 -0
- data/db/migrate/032_caches_context_as_hash.rb +10 -0
- data/db/migrate/033_documents_kpath_change.rb +17 -0
- data/db/migrate/034_change_file_storage.rb +38 -0
- data/db/migrate/035_add_status_to_link.rb +13 -0
- data/db/migrate/036_add_flag_fields_on_nodes.rb +11 -0
- data/db/migrate/037_add_auto_create_discussion_to_v_class.rb +11 -0
- data/db/migrate/038_create_site_attributes.rb +15 -0
- data/db/migrate/039_default_position.rb +10 -0
- data/db/migrate/040_second_value_for_data_entry.rb +11 -0
- data/db/migrate/041_add_attributes_to_v_class.rb +9 -0
- data/db/migrate/042_fix_position_should_be_float.rb +8 -0
- data/db/migrate/043_move_user_lang_into_participation.rb +15 -0
- data/db/migrate/044_remove_monolingual_site_option.rb +9 -0
- data/db/migrate/045_avoid_star_in_templates.rb +13 -0
- data/db/migrate/046_fix_zazen_image_tag.rb +47 -0
- data/db/migrate/047_change_default_link_id_to_zero.rb +12 -0
- data/db/migrate/048_link_source_target_can_be_null.rb +11 -0
- data/db/migrate/049_fix_publish_from_is_null.rb +9 -0
- data/db/migrate/050_date_in_links.rb +9 -0
- data/db/migrate/051_add_exif_tags_to_images.rb +9 -0
- data/db/migrate/20090825201159_insert_zero_link.rb +8 -0
- data/db/migrate/20090825201200_merge_bricks_migrations_with_std_migrations.rb +19 -0
- data/db/migrate/20090924141459_zafu_fix_sept09.rb +19 -0
- data/db/migrate/20090927125912_allow_null_in_text_fields.rb +17 -0
- data/db/migrate/20090928133440_no_more_private_nodes.rb +25 -0
- data/db/migrate/20090928143754_version_status_change.rb +24 -0
- data/db/migrate/20091001084025_change_status_values_for_comments.rb +22 -0
- data/db/migrate/20091009084057_add_vhash_in_node.rb +13 -0
- data/db/migrate/20091013100351_rename_publish_group_to_drive_group.rb +12 -0
- data/db/migrate/20091014130833_fix_template_title.rb +16 -0
- data/db/migrate/20091014183726_merge_participation_into_users.rb +21 -0
- data/db/production.sqlite3 +0 -0
- data/db/schema.rb +281 -0
- data/lib/base_additions.rb +7 -0
- data/lib/bricks/patcher.rb +68 -0
- data/lib/comment_query.rb +92 -0
- data/lib/core_ext/date_time.rb +5 -0
- data/lib/core_ext/dir.rb +12 -0
- data/lib/core_ext/fixnum.rb +20 -0
- data/lib/core_ext/string.rb +74 -0
- data/lib/exif_data.rb +54 -0
- data/lib/fix_rails_layouts.rb +9 -0
- data/lib/gettext_strings.rb +160 -0
- data/lib/image_builder.rb +325 -0
- data/lib/log_recorder/lib/log_recorder.rb +138 -0
- data/lib/log_recorder/test/log_recorder_test.rb +0 -0
- data/lib/parser.rb +1 -0
- data/lib/tasks/capistrano.rake +99 -0
- data/lib/tasks/zena.rake +358 -0
- data/lib/tasks/zena.rb +2 -0
- data/lib/upload_progress_server.rb +24 -0
- data/lib/webdav_adapter.rb +172 -0
- data/lib/zafu_parser.rb +3 -0
- data/lib/zazen_parser.rb +1 -0
- data/lib/zena.rb +398 -0
- data/lib/zena/acts/multiversion.rb +755 -0
- data/lib/zena/acts/secure.rb +774 -0
- data/lib/zena/app.rb +39 -0
- data/lib/zena/code_syntax.rb +275 -0
- data/lib/zena/controller/test_case.rb +32 -0
- data/lib/zena/db.rb +252 -0
- data/lib/zena/fix/mysql_connection.rb +17 -0
- data/lib/zena/foxy_parser.rb +845 -0
- data/lib/zena/migrator.rb +109 -0
- data/lib/zena/parser.rb +601 -0
- data/lib/zena/parser/zafu_rules.rb +232 -0
- data/lib/zena/parser/zafu_tags.rb +197 -0
- data/lib/zena/parser/zazen_rules.rb +427 -0
- data/lib/zena/parser/zazen_tags.rb +44 -0
- data/lib/zena/parser/zena_rules.rb +29 -0
- data/lib/zena/parser/zena_tags.rb +3559 -0
- data/lib/zena/root.rb +3 -0
- data/lib/zena/routes.rb +73 -0
- data/lib/zena/test_controller.rb +74 -0
- data/lib/zena/unit/test_case.rb +24 -0
- data/lib/zena/use/ajax.rb +119 -0
- data/lib/zena/use/authentification.rb +120 -0
- data/lib/zena/use/calendar.rb +130 -0
- data/lib/zena/use/custom_queries/complex.host.yml +173 -0
- data/lib/zena/use/dates.rb +230 -0
- data/lib/zena/use/dyn_attributes.rb +256 -0
- data/lib/zena/use/error_rendering.rb +52 -0
- data/lib/zena/use/fixtures.rb +133 -0
- data/lib/zena/use/grid.rb +148 -0
- data/lib/zena/use/html_tags.rb +603 -0
- data/lib/zena/use/i18n.rb +247 -0
- data/lib/zena/use/nested_attributes_alias.rb +201 -0
- data/lib/zena/use/node_query_finders.rb +491 -0
- data/lib/zena/use/refactor.rb +231 -0
- data/lib/zena/use/relations.rb +360 -0
- data/lib/zena/use/rendering.rb +248 -0
- data/lib/zena/use/test_helper.rb +151 -0
- data/lib/zena/use/urls.rb +180 -0
- data/lib/zena/use/zafu.rb +549 -0
- data/lib/zena/use/zazen.rb +230 -0
- data/lib/zena/view/test_case.rb +23 -0
- data/locale/en/LC_MESSAGES/zena.mo +0 -0
- data/locale/en/zena.po +2116 -0
- data/locale/fr/LC_MESSAGES/zena.mo +0 -0
- data/locale/fr/zena.po +2172 -0
- data/locale/zena.pot +1915 -0
- data/public/calendar/calendar-brown.css +225 -0
- data/public/calendar/calendar-setup.js +153 -0
- data/public/calendar/calendar.js +1817 -0
- data/public/calendar/iconCalendar.gif +0 -0
- data/public/calendar/lang/calendar-en-utf8.js +128 -0
- data/public/calendar/lang/calendar-fr-utf8.js +120 -0
- data/public/calendar/lang/lang.zip +0 -0
- data/public/dispatch.cgi +10 -0
- data/public/dispatch.fcgi +24 -0
- data/public/dispatch.rb +10 -0
- data/public/favicon.ico +0 -0
- data/public/images/accept.png +0 -0
- data/public/images/action.png +0 -0
- data/public/images/add.png +0 -0
- data/public/images/ajax-loader.gif +0 -0
- data/public/images/anchor.png +0 -0
- data/public/images/application.png +0 -0
- data/public/images/application_add.png +0 -0
- data/public/images/application_cascade.png +0 -0
- data/public/images/application_delete.png +0 -0
- data/public/images/application_double.png +0 -0
- data/public/images/application_edit.png +0 -0
- data/public/images/application_error.png +0 -0
- data/public/images/application_form.png +0 -0
- data/public/images/application_form_add.png +0 -0
- data/public/images/application_form_delete.png +0 -0
- data/public/images/application_form_edit.png +0 -0
- data/public/images/application_form_magnify.png +0 -0
- data/public/images/application_get.png +0 -0
- data/public/images/application_go.png +0 -0
- data/public/images/application_home.png +0 -0
- data/public/images/application_key.png +0 -0
- data/public/images/application_lightning.png +0 -0
- data/public/images/application_link.png +0 -0
- data/public/images/application_osx.png +0 -0
- data/public/images/application_osx_terminal.png +0 -0
- data/public/images/application_put.png +0 -0
- data/public/images/application_side_boxes.png +0 -0
- data/public/images/application_side_contract.png +0 -0
- data/public/images/application_side_expand.png +0 -0
- data/public/images/application_side_list.png +0 -0
- data/public/images/application_side_tree.png +0 -0
- data/public/images/application_split.png +0 -0
- data/public/images/application_tile_horizontal.png +0 -0
- data/public/images/application_tile_vertical.png +0 -0
- data/public/images/application_view_columns.png +0 -0
- data/public/images/application_view_detail.png +0 -0
- data/public/images/application_view_gallery.png +0 -0
- data/public/images/application_view_icons.png +0 -0
- data/public/images/application_view_list.png +0 -0
- data/public/images/application_view_tile.png +0 -0
- data/public/images/application_xp.png +0 -0
- data/public/images/application_xp_terminal.png +0 -0
- data/public/images/arrow_branch.png +0 -0
- data/public/images/arrow_divide.png +0 -0
- data/public/images/arrow_down.png +0 -0
- data/public/images/arrow_in.png +0 -0
- data/public/images/arrow_inout.png +0 -0
- data/public/images/arrow_join.png +0 -0
- data/public/images/arrow_left.png +0 -0
- data/public/images/arrow_merge.png +0 -0
- data/public/images/arrow_out.png +0 -0
- data/public/images/arrow_redo.png +0 -0
- data/public/images/arrow_refresh.png +0 -0
- data/public/images/arrow_refresh_small.png +0 -0
- data/public/images/arrow_right.png +0 -0
- data/public/images/arrow_rotate_anticlockwise.png +0 -0
- data/public/images/arrow_rotate_clockwise.png +0 -0
- data/public/images/arrow_switch.png +0 -0
- data/public/images/arrow_turn_left.png +0 -0
- data/public/images/arrow_turn_right.png +0 -0
- data/public/images/arrow_undo.png +0 -0
- data/public/images/arrow_up.png +0 -0
- data/public/images/asterisk_orange.png +0 -0
- data/public/images/asterisk_yellow.png +0 -0
- data/public/images/attach.png +0 -0
- data/public/images/award_star_add.png +0 -0
- data/public/images/award_star_bronze_1.png +0 -0
- data/public/images/award_star_bronze_2.png +0 -0
- data/public/images/award_star_bronze_3.png +0 -0
- data/public/images/award_star_delete.png +0 -0
- data/public/images/award_star_gold_1.png +0 -0
- data/public/images/award_star_gold_2.png +0 -0
- data/public/images/award_star_gold_3.png +0 -0
- data/public/images/award_star_silver_1.png +0 -0
- data/public/images/award_star_silver_2.png +0 -0
- data/public/images/award_star_silver_3.png +0 -0
- data/public/images/basket.png +0 -0
- data/public/images/basket_add.png +0 -0
- data/public/images/basket_delete.png +0 -0
- data/public/images/basket_edit.png +0 -0
- data/public/images/basket_error.png +0 -0
- data/public/images/basket_go.png +0 -0
- data/public/images/basket_put.png +0 -0
- data/public/images/basket_remove.png +0 -0
- data/public/images/bell.png +0 -0
- data/public/images/bell_add.png +0 -0
- data/public/images/bell_delete.png +0 -0
- data/public/images/bell_error.png +0 -0
- data/public/images/bell_go.png +0 -0
- data/public/images/bell_link.png +0 -0
- data/public/images/bin.png +0 -0
- data/public/images/bin_closed.png +0 -0
- data/public/images/bin_empty.gif +0 -0
- data/public/images/bin_empty.png +0 -0
- data/public/images/bin_full.gif +0 -0
- data/public/images/bomb.png +0 -0
- data/public/images/book.png +0 -0
- data/public/images/book_add.png +0 -0
- data/public/images/book_addresses.png +0 -0
- data/public/images/book_delete.png +0 -0
- data/public/images/book_edit.png +0 -0
- data/public/images/book_error.png +0 -0
- data/public/images/book_go.png +0 -0
- data/public/images/book_key.png +0 -0
- data/public/images/book_link.png +0 -0
- data/public/images/book_next.png +0 -0
- data/public/images/book_open.png +0 -0
- data/public/images/book_previous.png +0 -0
- data/public/images/box.png +0 -0
- data/public/images/brick.png +0 -0
- data/public/images/brick_add.png +0 -0
- data/public/images/brick_delete.png +0 -0
- data/public/images/brick_edit.png +0 -0
- data/public/images/brick_error.png +0 -0
- data/public/images/brick_go.png +0 -0
- data/public/images/brick_link.png +0 -0
- data/public/images/bricks.png +0 -0
- data/public/images/briefcase.png +0 -0
- data/public/images/bug.png +0 -0
- data/public/images/bug_add.png +0 -0
- data/public/images/bug_delete.png +0 -0
- data/public/images/bug_edit.png +0 -0
- data/public/images/bug_error.png +0 -0
- data/public/images/bug_go.png +0 -0
- data/public/images/bug_link.png +0 -0
- data/public/images/building.png +0 -0
- data/public/images/building_add.png +0 -0
- data/public/images/building_delete.png +0 -0
- data/public/images/building_edit.png +0 -0
- data/public/images/building_error.png +0 -0
- data/public/images/building_go.png +0 -0
- data/public/images/building_key.png +0 -0
- data/public/images/building_link.png +0 -0
- data/public/images/bullet_add.png +0 -0
- data/public/images/bullet_arrow_bottom.png +0 -0
- data/public/images/bullet_arrow_down.png +0 -0
- data/public/images/bullet_arrow_top.png +0 -0
- data/public/images/bullet_arrow_up.png +0 -0
- data/public/images/bullet_black.png +0 -0
- data/public/images/bullet_blue.png +0 -0
- data/public/images/bullet_delete.png +0 -0
- data/public/images/bullet_disk.png +0 -0
- data/public/images/bullet_error.png +0 -0
- data/public/images/bullet_feed.png +0 -0
- data/public/images/bullet_go.png +0 -0
- data/public/images/bullet_green.png +0 -0
- data/public/images/bullet_key.png +0 -0
- data/public/images/bullet_orange.png +0 -0
- data/public/images/bullet_picture.png +0 -0
- data/public/images/bullet_pink.png +0 -0
- data/public/images/bullet_purple.png +0 -0
- data/public/images/bullet_red.png +0 -0
- data/public/images/bullet_star.png +0 -0
- data/public/images/bullet_toggle_minus.png +0 -0
- data/public/images/bullet_toggle_plus.png +0 -0
- data/public/images/bullet_white.png +0 -0
- data/public/images/bullet_wrench.png +0 -0
- data/public/images/bullet_yellow.png +0 -0
- data/public/images/cake.png +0 -0
- data/public/images/calculator.png +0 -0
- data/public/images/calculator_add.png +0 -0
- data/public/images/calculator_delete.png +0 -0
- data/public/images/calculator_edit.png +0 -0
- data/public/images/calculator_error.png +0 -0
- data/public/images/calculator_link.png +0 -0
- data/public/images/calendar.png +0 -0
- data/public/images/calendar_add.png +0 -0
- data/public/images/calendar_delete.png +0 -0
- data/public/images/calendar_edit.png +0 -0
- data/public/images/calendar_link.png +0 -0
- data/public/images/calendar_view_day.png +0 -0
- data/public/images/calendar_view_month.png +0 -0
- data/public/images/calendar_view_week.png +0 -0
- data/public/images/camera.png +0 -0
- data/public/images/camera_add.png +0 -0
- data/public/images/camera_delete.png +0 -0
- data/public/images/camera_edit.png +0 -0
- data/public/images/camera_error.png +0 -0
- data/public/images/camera_go.png +0 -0
- data/public/images/camera_link.png +0 -0
- data/public/images/camera_small.png +0 -0
- data/public/images/cancel.png +0 -0
- data/public/images/car.png +0 -0
- data/public/images/car_add.png +0 -0
- data/public/images/car_delete.png +0 -0
- data/public/images/cart.png +0 -0
- data/public/images/cart_add.png +0 -0
- data/public/images/cart_delete.png +0 -0
- data/public/images/cart_edit.png +0 -0
- data/public/images/cart_error.png +0 -0
- data/public/images/cart_go.png +0 -0
- data/public/images/cart_put.png +0 -0
- data/public/images/cart_remove.png +0 -0
- data/public/images/cd.png +0 -0
- data/public/images/cd_add.png +0 -0
- data/public/images/cd_burn.png +0 -0
- data/public/images/cd_delete.png +0 -0
- data/public/images/cd_edit.png +0 -0
- data/public/images/cd_eject.png +0 -0
- data/public/images/cd_go.png +0 -0
- data/public/images/chart_bar.png +0 -0
- data/public/images/chart_bar_add.png +0 -0
- data/public/images/chart_bar_delete.png +0 -0
- data/public/images/chart_bar_edit.png +0 -0
- data/public/images/chart_bar_error.png +0 -0
- data/public/images/chart_bar_link.png +0 -0
- data/public/images/chart_curve.png +0 -0
- data/public/images/chart_curve_add.png +0 -0
- data/public/images/chart_curve_delete.png +0 -0
- data/public/images/chart_curve_edit.png +0 -0
- data/public/images/chart_curve_error.png +0 -0
- data/public/images/chart_curve_go.png +0 -0
- data/public/images/chart_curve_link.png +0 -0
- data/public/images/chart_line.png +0 -0
- data/public/images/chart_line_add.png +0 -0
- data/public/images/chart_line_delete.png +0 -0
- data/public/images/chart_line_edit.png +0 -0
- data/public/images/chart_line_error.png +0 -0
- data/public/images/chart_line_link.png +0 -0
- data/public/images/chart_organisation.png +0 -0
- data/public/images/chart_organisation_add.png +0 -0
- data/public/images/chart_organisation_delete.png +0 -0
- data/public/images/chart_pie.png +0 -0
- data/public/images/chart_pie_add.png +0 -0
- data/public/images/chart_pie_delete.png +0 -0
- data/public/images/chart_pie_edit.png +0 -0
- data/public/images/chart_pie_error.png +0 -0
- data/public/images/chart_pie_link.png +0 -0
- data/public/images/clock.png +0 -0
- data/public/images/clock_add.png +0 -0
- data/public/images/clock_delete.png +0 -0
- data/public/images/clock_edit.png +0 -0
- data/public/images/clock_error.png +0 -0
- data/public/images/clock_go.png +0 -0
- data/public/images/clock_link.png +0 -0
- data/public/images/clock_pause.png +0 -0
- data/public/images/clock_play.png +0 -0
- data/public/images/clock_red.png +0 -0
- data/public/images/clock_stop.png +0 -0
- data/public/images/cog.png +0 -0
- data/public/images/cog_add.png +0 -0
- data/public/images/cog_delete.png +0 -0
- data/public/images/cog_edit.png +0 -0
- data/public/images/cog_error.png +0 -0
- data/public/images/cog_go.png +0 -0
- data/public/images/coins.png +0 -0
- data/public/images/coins_add.png +0 -0
- data/public/images/coins_delete.png +0 -0
- data/public/images/collection.png +0 -0
- data/public/images/color_swatch.png +0 -0
- data/public/images/color_wheel.png +0 -0
- data/public/images/column_add.png +0 -0
- data/public/images/column_delete.png +0 -0
- data/public/images/comment.png +0 -0
- data/public/images/comment_add.png +0 -0
- data/public/images/comment_delete.png +0 -0
- data/public/images/comment_edit.png +0 -0
- data/public/images/comments.png +0 -0
- data/public/images/comments_add.png +0 -0
- data/public/images/comments_delete.png +0 -0
- data/public/images/comments_red.png +0 -0
- data/public/images/compress.png +0 -0
- data/public/images/computer.png +0 -0
- data/public/images/computer_add.png +0 -0
- data/public/images/computer_delete.png +0 -0
- data/public/images/computer_edit.png +0 -0
- data/public/images/computer_error.png +0 -0
- data/public/images/computer_go.png +0 -0
- data/public/images/computer_key.png +0 -0
- data/public/images/computer_link.png +0 -0
- data/public/images/connect.png +0 -0
- data/public/images/contrast.png +0 -0
- data/public/images/contrast_decrease.png +0 -0
- data/public/images/contrast_high.png +0 -0
- data/public/images/contrast_increase.png +0 -0
- data/public/images/contrast_low.png +0 -0
- data/public/images/control_eject.png +0 -0
- data/public/images/control_eject_blue.png +0 -0
- data/public/images/control_end.png +0 -0
- data/public/images/control_end_blue.png +0 -0
- data/public/images/control_equalizer.png +0 -0
- data/public/images/control_equalizer_blue.png +0 -0
- data/public/images/control_fastforward.png +0 -0
- data/public/images/control_fastforward_blue.png +0 -0
- data/public/images/control_pause.png +0 -0
- data/public/images/control_pause_blue.png +0 -0
- data/public/images/control_play.png +0 -0
- data/public/images/control_play_blue.png +0 -0
- data/public/images/control_repeat.png +0 -0
- data/public/images/control_repeat_blue.png +0 -0
- data/public/images/control_rewind.png +0 -0
- data/public/images/control_rewind_blue.png +0 -0
- data/public/images/control_start.png +0 -0
- data/public/images/control_start_blue.png +0 -0
- data/public/images/control_stop.png +0 -0
- data/public/images/control_stop_blue.png +0 -0
- data/public/images/controller.png +0 -0
- data/public/images/controller_add.png +0 -0
- data/public/images/controller_delete.png +0 -0
- data/public/images/controller_error.png +0 -0
- data/public/images/creditcards.png +0 -0
- data/public/images/cross.png +0 -0
- data/public/images/css.png +0 -0
- data/public/images/css_add.png +0 -0
- data/public/images/css_delete.png +0 -0
- data/public/images/css_go.png +0 -0
- data/public/images/css_valid.png +0 -0
- data/public/images/cup.png +0 -0
- data/public/images/cup_add.png +0 -0
- data/public/images/cup_delete.png +0 -0
- data/public/images/cup_edit.png +0 -0
- data/public/images/cup_error.png +0 -0
- data/public/images/cup_go.png +0 -0
- data/public/images/cup_key.png +0 -0
- data/public/images/cup_link.png +0 -0
- data/public/images/cursor.png +0 -0
- data/public/images/cut.png +0 -0
- data/public/images/cut_red.png +0 -0
- data/public/images/database.png +0 -0
- data/public/images/database_add.png +0 -0
- data/public/images/database_connect.png +0 -0
- data/public/images/database_delete.png +0 -0
- data/public/images/database_edit.png +0 -0
- data/public/images/database_error.png +0 -0
- data/public/images/database_gear.png +0 -0
- data/public/images/database_go.png +0 -0
- data/public/images/database_key.png +0 -0
- data/public/images/database_lightning.png +0 -0
- data/public/images/database_link.png +0 -0
- data/public/images/database_refresh.png +0 -0
- data/public/images/database_save.png +0 -0
- data/public/images/database_table.png +0 -0
- data/public/images/date.png +0 -0
- data/public/images/date_add.png +0 -0
- data/public/images/date_delete.png +0 -0
- data/public/images/date_edit.png +0 -0
- data/public/images/date_error.png +0 -0
- data/public/images/date_go.png +0 -0
- data/public/images/date_link.png +0 -0
- data/public/images/date_magnify.png +0 -0
- data/public/images/date_next.png +0 -0
- data/public/images/date_previous.png +0 -0
- data/public/images/delete.png +0 -0
- data/public/images/disconnect.png +0 -0
- data/public/images/disk.png +0 -0
- data/public/images/disk_multiple.png +0 -0
- data/public/images/door.png +0 -0
- data/public/images/door_in.png +0 -0
- data/public/images/door_open.png +0 -0
- data/public/images/door_out.png +0 -0
- data/public/images/drink.png +0 -0
- data/public/images/drink_empty.png +0 -0
- data/public/images/drive.png +0 -0
- data/public/images/drive_add.png +0 -0
- data/public/images/drive_burn.png +0 -0
- data/public/images/drive_cd.png +0 -0
- data/public/images/drive_cd_empty.png +0 -0
- data/public/images/drive_delete.png +0 -0
- data/public/images/drive_disk.png +0 -0
- data/public/images/drive_edit.png +0 -0
- data/public/images/drive_error.png +0 -0
- data/public/images/drive_go.png +0 -0
- data/public/images/drive_key.png +0 -0
- data/public/images/drive_link.png +0 -0
- data/public/images/drive_magnify.png +0 -0
- data/public/images/drive_network.png +0 -0
- data/public/images/drive_rename.png +0 -0
- data/public/images/drive_user.png +0 -0
- data/public/images/drive_web.png +0 -0
- data/public/images/dvd.png +0 -0
- data/public/images/dvd_add.png +0 -0
- data/public/images/dvd_delete.png +0 -0
- data/public/images/dvd_edit.png +0 -0
- data/public/images/dvd_error.png +0 -0
- data/public/images/dvd_go.png +0 -0
- data/public/images/dvd_key.png +0 -0
- data/public/images/dvd_link.png +0 -0
- data/public/images/email.png +0 -0
- data/public/images/email_add.png +0 -0
- data/public/images/email_attach.png +0 -0
- data/public/images/email_delete.png +0 -0
- data/public/images/email_edit.png +0 -0
- data/public/images/email_error.png +0 -0
- data/public/images/email_go.png +0 -0
- data/public/images/email_link.png +0 -0
- data/public/images/email_open.png +0 -0
- data/public/images/email_open_image.png +0 -0
- data/public/images/emoticon_evilgrin.png +0 -0
- data/public/images/emoticon_grin.png +0 -0
- data/public/images/emoticon_happy.png +0 -0
- data/public/images/emoticon_smile.png +0 -0
- data/public/images/emoticon_surprised.png +0 -0
- data/public/images/emoticon_tongue.png +0 -0
- data/public/images/emoticon_unhappy.png +0 -0
- data/public/images/emoticon_waii.png +0 -0
- data/public/images/emoticon_wink.png +0 -0
- data/public/images/error.png +0 -0
- data/public/images/error_add.png +0 -0
- data/public/images/error_delete.png +0 -0
- data/public/images/error_go.png +0 -0
- data/public/images/exclamation.png +0 -0
- data/public/images/ext/contact.png +0 -0
- data/public/images/ext/contact_pv.png +0 -0
- data/public/images/ext/doc.png +0 -0
- data/public/images/ext/doc_tiny.png +0 -0
- data/public/images/ext/jpg.png +0 -0
- data/public/images/ext/jpg_tiny.png +0 -0
- data/public/images/ext/other.png +0 -0
- data/public/images/ext/other_pv.png +0 -0
- data/public/images/ext/other_tiny.png +0 -0
- data/public/images/ext/page.png +0 -0
- data/public/images/ext/page_pv.png +0 -0
- data/public/images/ext/page_tiny.png +0 -0
- data/public/images/ext/pdf.png +0 -0
- data/public/images/ext/pdf_pv.png +0 -0
- data/public/images/ext/pdf_tiny.png +0 -0
- data/public/images/ext/png.png +0 -0
- data/public/images/ext/png_tiny.png +0 -0
- data/public/images/ext/post.png +0 -0
- data/public/images/ext/post_pv.png +0 -0
- data/public/images/ext/post_tiny.png +0 -0
- data/public/images/ext/project.png +0 -0
- data/public/images/ext/project_pv.png +0 -0
- data/public/images/ext/project_tiny.png +0 -0
- data/public/images/ext/rtf.png +0 -0
- data/public/images/ext/rtf_tiny.png +0 -0
- data/public/images/ext/tag.png +0 -0
- data/public/images/ext/tag_pv.png +0 -0
- data/public/images/ext/xls.png +0 -0
- data/public/images/ext/xls_tiny.png +0 -0
- data/public/images/ext/zip.png +0 -0
- data/public/images/ext/zip_pv.png +0 -0
- data/public/images/ext/zip_tiny.png +0 -0
- data/public/images/eye.png +0 -0
- data/public/images/feed.png +0 -0
- data/public/images/feed_add.png +0 -0
- data/public/images/feed_delete.png +0 -0
- data/public/images/feed_disk.png +0 -0
- data/public/images/feed_edit.png +0 -0
- data/public/images/feed_error.png +0 -0
- data/public/images/feed_go.png +0 -0
- data/public/images/feed_key.png +0 -0
- data/public/images/feed_link.png +0 -0
- data/public/images/feed_magnify.png +0 -0
- data/public/images/female.png +0 -0
- data/public/images/film.png +0 -0
- data/public/images/film_add.png +0 -0
- data/public/images/film_delete.png +0 -0
- data/public/images/film_edit.png +0 -0
- data/public/images/film_error.png +0 -0
- data/public/images/film_go.png +0 -0
- data/public/images/film_key.png +0 -0
- data/public/images/film_link.png +0 -0
- data/public/images/film_save.png +0 -0
- data/public/images/find.png +0 -0
- data/public/images/flag_blue.png +0 -0
- data/public/images/flag_green.png +0 -0
- data/public/images/flag_orange.png +0 -0
- data/public/images/flag_pink.png +0 -0
- data/public/images/flag_purple.png +0 -0
- data/public/images/flag_red.png +0 -0
- data/public/images/flag_yellow.png +0 -0
- data/public/images/folder.png +0 -0
- data/public/images/folder_add.png +0 -0
- data/public/images/folder_bell.png +0 -0
- data/public/images/folder_brick.png +0 -0
- data/public/images/folder_bug.png +0 -0
- data/public/images/folder_camera.png +0 -0
- data/public/images/folder_database.png +0 -0
- data/public/images/folder_delete.png +0 -0
- data/public/images/folder_edit.png +0 -0
- data/public/images/folder_error.png +0 -0
- data/public/images/folder_explore.png +0 -0
- data/public/images/folder_feed.png +0 -0
- data/public/images/folder_find.png +0 -0
- data/public/images/folder_go.png +0 -0
- data/public/images/folder_heart.png +0 -0
- data/public/images/folder_image.png +0 -0
- data/public/images/folder_key.png +0 -0
- data/public/images/folder_lightbulb.png +0 -0
- data/public/images/folder_link.png +0 -0
- data/public/images/folder_magnify.png +0 -0
- data/public/images/folder_page.png +0 -0
- data/public/images/folder_page_white.png +0 -0
- data/public/images/folder_palette.png +0 -0
- data/public/images/folder_picture.png +0 -0
- data/public/images/folder_star.png +0 -0
- data/public/images/folder_table.png +0 -0
- data/public/images/folder_user.png +0 -0
- data/public/images/folder_wrench.png +0 -0
- data/public/images/font.png +0 -0
- data/public/images/font_add.png +0 -0
- data/public/images/font_delete.png +0 -0
- data/public/images/font_go.png +0 -0
- data/public/images/group.png +0 -0
- data/public/images/group_add.png +0 -0
- data/public/images/group_admin.png +0 -0
- data/public/images/group_delete.png +0 -0
- data/public/images/group_edit.png +0 -0
- data/public/images/group_error.png +0 -0
- data/public/images/group_gear.png +0 -0
- data/public/images/group_go.png +0 -0
- data/public/images/group_key.png +0 -0
- data/public/images/group_link.png +0 -0
- data/public/images/group_pub.png +0 -0
- data/public/images/group_site.png +0 -0
- data/public/images/heart.png +0 -0
- data/public/images/heart_add.png +0 -0
- data/public/images/heart_delete.png +0 -0
- data/public/images/help.png +0 -0
- data/public/images/home.png +0 -0
- data/public/images/hourglass.png +0 -0
- data/public/images/hourglass_add.png +0 -0
- data/public/images/hourglass_delete.png +0 -0
- data/public/images/hourglass_go.png +0 -0
- data/public/images/hourglass_link.png +0 -0
- data/public/images/house.png +0 -0
- data/public/images/house_go.png +0 -0
- data/public/images/house_link.png +0 -0
- data/public/images/html.png +0 -0
- data/public/images/html_add.png +0 -0
- data/public/images/html_delete.png +0 -0
- data/public/images/html_go.png +0 -0
- data/public/images/html_valid.png +0 -0
- data/public/images/image.png +0 -0
- data/public/images/image_add.png +0 -0
- data/public/images/image_delete.png +0 -0
- data/public/images/image_edit.png +0 -0
- data/public/images/image_link.png +0 -0
- data/public/images/images.png +0 -0
- data/public/images/img_not_found.png +0 -0
- data/public/images/information.png +0 -0
- data/public/images/ipod.png +0 -0
- data/public/images/ipod_cast.png +0 -0
- data/public/images/ipod_cast_add.png +0 -0
- data/public/images/ipod_cast_delete.png +0 -0
- data/public/images/ipod_sound.png +0 -0
- data/public/images/joystick.png +0 -0
- data/public/images/joystick_add.png +0 -0
- data/public/images/joystick_delete.png +0 -0
- data/public/images/joystick_error.png +0 -0
- data/public/images/key.png +0 -0
- data/public/images/key_add.png +0 -0
- data/public/images/key_delete.png +0 -0
- data/public/images/key_go.png +0 -0
- data/public/images/keyboard.png +0 -0
- data/public/images/keyboard_add.png +0 -0
- data/public/images/keyboard_delete.png +0 -0
- data/public/images/keyboard_magnify.png +0 -0
- data/public/images/latex_error.png +0 -0
- data/public/images/layers.png +0 -0
- data/public/images/layout.png +0 -0
- data/public/images/layout_add.png +0 -0
- data/public/images/layout_content.png +0 -0
- data/public/images/layout_delete.png +0 -0
- data/public/images/layout_edit.png +0 -0
- data/public/images/layout_error.png +0 -0
- data/public/images/layout_header.png +0 -0
- data/public/images/layout_link.png +0 -0
- data/public/images/layout_sidebar.png +0 -0
- data/public/images/lightbulb.png +0 -0
- data/public/images/lightbulb_add.png +0 -0
- data/public/images/lightbulb_delete.png +0 -0
- data/public/images/lightbulb_off.png +0 -0
- data/public/images/lightning.png +0 -0
- data/public/images/lightning_add.png +0 -0
- data/public/images/lightning_delete.png +0 -0
- data/public/images/lightning_go.png +0 -0
- data/public/images/link.png +0 -0
- data/public/images/link_add.png +0 -0
- data/public/images/link_break.png +0 -0
- data/public/images/link_delete.png +0 -0
- data/public/images/link_edit.png +0 -0
- data/public/images/link_error.png +0 -0
- data/public/images/link_go.png +0 -0
- data/public/images/lock.png +0 -0
- data/public/images/lock_add.png +0 -0
- data/public/images/lock_break.png +0 -0
- data/public/images/lock_delete.png +0 -0
- data/public/images/lock_edit.png +0 -0
- data/public/images/lock_go.png +0 -0
- data/public/images/lock_open.png +0 -0
- data/public/images/lorry.png +0 -0
- data/public/images/lorry_add.png +0 -0
- data/public/images/lorry_delete.png +0 -0
- data/public/images/lorry_error.png +0 -0
- data/public/images/lorry_flatbed.png +0 -0
- data/public/images/lorry_go.png +0 -0
- data/public/images/lorry_link.png +0 -0
- data/public/images/magifier_zoom_out.png +0 -0
- data/public/images/magnifier.png +0 -0
- data/public/images/magnifier_zoom_in.png +0 -0
- data/public/images/male.png +0 -0
- data/public/images/map.png +0 -0
- data/public/images/map_add.png +0 -0
- data/public/images/map_delete.png +0 -0
- data/public/images/map_edit.png +0 -0
- data/public/images/map_go.png +0 -0
- data/public/images/map_magnify.png +0 -0
- data/public/images/medal_bronze_1.png +0 -0
- data/public/images/medal_bronze_2.png +0 -0
- data/public/images/medal_bronze_3.png +0 -0
- data/public/images/medal_bronze_add.png +0 -0
- data/public/images/medal_bronze_delete.png +0 -0
- data/public/images/medal_gold_1.png +0 -0
- data/public/images/medal_gold_2.png +0 -0
- data/public/images/medal_gold_3.png +0 -0
- data/public/images/medal_gold_add.png +0 -0
- data/public/images/medal_gold_delete.png +0 -0
- data/public/images/medal_silver_1.png +0 -0
- data/public/images/medal_silver_2.png +0 -0
- data/public/images/medal_silver_3.png +0 -0
- data/public/images/medal_silver_add.png +0 -0
- data/public/images/medal_silver_delete.png +0 -0
- data/public/images/money.png +0 -0
- data/public/images/money_add.png +0 -0
- data/public/images/money_delete.png +0 -0
- data/public/images/money_dollar.png +0 -0
- data/public/images/money_euro.png +0 -0
- data/public/images/money_pound.png +0 -0
- data/public/images/money_yen.png +0 -0
- data/public/images/monitor.png +0 -0
- data/public/images/monitor_add.png +0 -0
- data/public/images/monitor_delete.png +0 -0
- data/public/images/monitor_edit.png +0 -0
- data/public/images/monitor_error.png +0 -0
- data/public/images/monitor_go.png +0 -0
- data/public/images/monitor_lightning.png +0 -0
- data/public/images/monitor_link.png +0 -0
- data/public/images/mouse.png +0 -0
- data/public/images/mouse_add.png +0 -0
- data/public/images/mouse_delete.png +0 -0
- data/public/images/mouse_error.png +0 -0
- data/public/images/music.png +0 -0
- data/public/images/new.png +0 -0
- data/public/images/newspaper.png +0 -0
- data/public/images/newspaper_add.png +0 -0
- data/public/images/newspaper_delete.png +0 -0
- data/public/images/newspaper_go.png +0 -0
- data/public/images/newspaper_link.png +0 -0
- data/public/images/note.png +0 -0
- data/public/images/note_add.png +0 -0
- data/public/images/note_delete.png +0 -0
- data/public/images/note_edit.png +0 -0
- data/public/images/note_error.png +0 -0
- data/public/images/note_go.png +0 -0
- data/public/images/overlays.png +0 -0
- data/public/images/package.png +0 -0
- data/public/images/package_add.png +0 -0
- data/public/images/package_delete.png +0 -0
- data/public/images/package_go.png +0 -0
- data/public/images/package_green.png +0 -0
- data/public/images/package_link.png +0 -0
- data/public/images/page.png +0 -0
- data/public/images/page_add.png +0 -0
- data/public/images/page_attach.png +0 -0
- data/public/images/page_code.png +0 -0
- data/public/images/page_copy.png +0 -0
- data/public/images/page_delete.png +0 -0
- data/public/images/page_edit.png +0 -0
- data/public/images/page_error.png +0 -0
- data/public/images/page_excel.png +0 -0
- data/public/images/page_find.png +0 -0
- data/public/images/page_gear.png +0 -0
- data/public/images/page_go.png +0 -0
- data/public/images/page_green.png +0 -0
- data/public/images/page_key.png +0 -0
- data/public/images/page_lightning.png +0 -0
- data/public/images/page_link.png +0 -0
- data/public/images/page_paintbrush.png +0 -0
- data/public/images/page_paste.png +0 -0
- data/public/images/page_red.png +0 -0
- data/public/images/page_refresh.png +0 -0
- data/public/images/page_save.png +0 -0
- data/public/images/page_white.png +0 -0
- data/public/images/page_white_acrobat.png +0 -0
- data/public/images/page_white_actionscript.png +0 -0
- data/public/images/page_white_add.png +0 -0
- data/public/images/page_white_c.png +0 -0
- data/public/images/page_white_camera.png +0 -0
- data/public/images/page_white_cd.png +0 -0
- data/public/images/page_white_code.png +0 -0
- data/public/images/page_white_code_red.png +0 -0
- data/public/images/page_white_coldfusion.png +0 -0
- data/public/images/page_white_compressed.png +0 -0
- data/public/images/page_white_copy.png +0 -0
- data/public/images/page_white_cplusplus.png +0 -0
- data/public/images/page_white_csharp.png +0 -0
- data/public/images/page_white_cup.png +0 -0
- data/public/images/page_white_database.png +0 -0
- data/public/images/page_white_delete.png +0 -0
- data/public/images/page_white_dvd.png +0 -0
- data/public/images/page_white_edit.png +0 -0
- data/public/images/page_white_error.png +0 -0
- data/public/images/page_white_excel.png +0 -0
- data/public/images/page_white_find.png +0 -0
- data/public/images/page_white_flash.png +0 -0
- data/public/images/page_white_freehand.png +0 -0
- data/public/images/page_white_gear.png +0 -0
- data/public/images/page_white_get.png +0 -0
- data/public/images/page_white_go.png +0 -0
- data/public/images/page_white_h.png +0 -0
- data/public/images/page_white_horizontal.png +0 -0
- data/public/images/page_white_key.png +0 -0
- data/public/images/page_white_lightning.png +0 -0
- data/public/images/page_white_link.png +0 -0
- data/public/images/page_white_magnify.png +0 -0
- data/public/images/page_white_medal.png +0 -0
- data/public/images/page_white_office.png +0 -0
- data/public/images/page_white_paint.png +0 -0
- data/public/images/page_white_paintbrush.png +0 -0
- data/public/images/page_white_paste.png +0 -0
- data/public/images/page_white_php.png +0 -0
- data/public/images/page_white_picture.png +0 -0
- data/public/images/page_white_powerpoint.png +0 -0
- data/public/images/page_white_put.png +0 -0
- data/public/images/page_white_ruby.png +0 -0
- data/public/images/page_white_stack.png +0 -0
- data/public/images/page_white_star.png +0 -0
- data/public/images/page_white_swoosh.png +0 -0
- data/public/images/page_white_text.png +0 -0
- data/public/images/page_white_text_width.png +0 -0
- data/public/images/page_white_tux.png +0 -0
- data/public/images/page_white_vector.png +0 -0
- data/public/images/page_white_visualstudio.png +0 -0
- data/public/images/page_white_width.png +0 -0
- data/public/images/page_white_word.png +0 -0
- data/public/images/page_white_world.png +0 -0
- data/public/images/page_white_wrench.png +0 -0
- data/public/images/page_white_zip.png +0 -0
- data/public/images/page_word.png +0 -0
- data/public/images/page_world.png +0 -0
- data/public/images/paintbrush.png +0 -0
- data/public/images/paintcan.png +0 -0
- data/public/images/palette.png +0 -0
- data/public/images/paste_plain.png +0 -0
- data/public/images/paste_word.png +0 -0
- data/public/images/pencil.png +0 -0
- data/public/images/pencil_add.png +0 -0
- data/public/images/pencil_delete.png +0 -0
- data/public/images/pencil_go.png +0 -0
- data/public/images/phone.png +0 -0
- data/public/images/phone_add.png +0 -0
- data/public/images/phone_delete.png +0 -0
- data/public/images/phone_sound.png +0 -0
- data/public/images/photo.png +0 -0
- data/public/images/photo_add.png +0 -0
- data/public/images/photo_blue.png +0 -0
- data/public/images/photo_delete.png +0 -0
- data/public/images/photo_grey.png +0 -0
- data/public/images/photo_link.png +0 -0
- data/public/images/photos.png +0 -0
- data/public/images/picture.png +0 -0
- data/public/images/picture_add.png +0 -0
- data/public/images/picture_delete.png +0 -0
- data/public/images/picture_edit.png +0 -0
- data/public/images/picture_empty.png +0 -0
- data/public/images/picture_error.png +0 -0
- data/public/images/picture_go.png +0 -0
- data/public/images/picture_key.png +0 -0
- data/public/images/picture_link.png +0 -0
- data/public/images/picture_save.png +0 -0
- data/public/images/pictures.png +0 -0
- data/public/images/pilcrow.png +0 -0
- data/public/images/pill.png +0 -0
- data/public/images/pill_add.png +0 -0
- data/public/images/pill_delete.png +0 -0
- data/public/images/pill_go.png +0 -0
- data/public/images/plugin.png +0 -0
- data/public/images/plugin_add.png +0 -0
- data/public/images/plugin_delete.png +0 -0
- data/public/images/plugin_disabled.png +0 -0
- data/public/images/plugin_edit.png +0 -0
- data/public/images/plugin_error.png +0 -0
- data/public/images/plugin_go.png +0 -0
- data/public/images/plugin_link.png +0 -0
- data/public/images/printer.png +0 -0
- data/public/images/printer_add.png +0 -0
- data/public/images/printer_delete.png +0 -0
- data/public/images/printer_empty.png +0 -0
- data/public/images/printer_error.png +0 -0
- data/public/images/project.png +0 -0
- data/public/images/rails.png +0 -0
- data/public/images/rainbow.png +0 -0
- data/public/images/report.png +0 -0
- data/public/images/report_add.png +0 -0
- data/public/images/report_delete.png +0 -0
- data/public/images/report_disk.png +0 -0
- data/public/images/report_edit.png +0 -0
- data/public/images/report_go.png +0 -0
- data/public/images/report_key.png +0 -0
- data/public/images/report_link.png +0 -0
- data/public/images/report_magnify.png +0 -0
- data/public/images/report_picture.png +0 -0
- data/public/images/report_user.png +0 -0
- data/public/images/report_word.png +0 -0
- data/public/images/resultset_first.png +0 -0
- data/public/images/resultset_last.png +0 -0
- data/public/images/resultset_next.png +0 -0
- data/public/images/resultset_previous.png +0 -0
- data/public/images/rosette.png +0 -0
- data/public/images/row_add.png +0 -0
- data/public/images/row_delete.png +0 -0
- data/public/images/rss.png +0 -0
- data/public/images/rss_add.png +0 -0
- data/public/images/rss_delete.png +0 -0
- data/public/images/rss_go.png +0 -0
- data/public/images/rss_valid.png +0 -0
- data/public/images/ruby.png +0 -0
- data/public/images/ruby_add.png +0 -0
- data/public/images/ruby_delete.png +0 -0
- data/public/images/ruby_gear.png +0 -0
- data/public/images/ruby_get.png +0 -0
- data/public/images/ruby_go.png +0 -0
- data/public/images/ruby_key.png +0 -0
- data/public/images/ruby_link.png +0 -0
- data/public/images/ruby_put.png +0 -0
- data/public/images/script.png +0 -0
- data/public/images/script_add.png +0 -0
- data/public/images/script_code.png +0 -0
- data/public/images/script_code_red.png +0 -0
- data/public/images/script_delete.png +0 -0
- data/public/images/script_edit.png +0 -0
- data/public/images/script_error.png +0 -0
- data/public/images/script_gear.png +0 -0
- data/public/images/script_go.png +0 -0
- data/public/images/script_key.png +0 -0
- data/public/images/script_lightning.png +0 -0
- data/public/images/script_link.png +0 -0
- data/public/images/script_palette.png +0 -0
- data/public/images/script_save.png +0 -0
- data/public/images/server.png +0 -0
- data/public/images/server_add.png +0 -0
- data/public/images/server_chart.png +0 -0
- data/public/images/server_compressed.png +0 -0
- data/public/images/server_connect.png +0 -0
- data/public/images/server_database.png +0 -0
- data/public/images/server_delete.png +0 -0
- data/public/images/server_edit.png +0 -0
- data/public/images/server_error.png +0 -0
- data/public/images/server_go.png +0 -0
- data/public/images/server_key.png +0 -0
- data/public/images/server_lightning.png +0 -0
- data/public/images/server_link.png +0 -0
- data/public/images/server_uncompressed.png +0 -0
- data/public/images/shading.png +0 -0
- data/public/images/shape_align_bottom.png +0 -0
- data/public/images/shape_align_center.png +0 -0
- data/public/images/shape_align_left.png +0 -0
- data/public/images/shape_align_middle.png +0 -0
- data/public/images/shape_align_right.png +0 -0
- data/public/images/shape_align_top.png +0 -0
- data/public/images/shape_flip_horizontal.png +0 -0
- data/public/images/shape_flip_vertical.png +0 -0
- data/public/images/shape_group.png +0 -0
- data/public/images/shape_handles.png +0 -0
- data/public/images/shape_move_back.png +0 -0
- data/public/images/shape_move_backwards.png +0 -0
- data/public/images/shape_move_forwards.png +0 -0
- data/public/images/shape_move_front.png +0 -0
- data/public/images/shape_rotate_anticlockwise.png +0 -0
- data/public/images/shape_rotate_clockwise.png +0 -0
- data/public/images/shape_square.png +0 -0
- data/public/images/shape_square_add.png +0 -0
- data/public/images/shape_square_delete.png +0 -0
- data/public/images/shape_square_edit.png +0 -0
- data/public/images/shape_square_error.png +0 -0
- data/public/images/shape_square_go.png +0 -0
- data/public/images/shape_square_key.png +0 -0
- data/public/images/shape_square_link.png +0 -0
- data/public/images/shape_ungroup.png +0 -0
- data/public/images/shield.png +0 -0
- data/public/images/shield_add.png +0 -0
- data/public/images/shield_delete.png +0 -0
- data/public/images/shield_go.png +0 -0
- data/public/images/silk.html +1495 -0
- data/public/images/sitemap.png +0 -0
- data/public/images/sitemap_color.png +0 -0
- data/public/images/sound.png +0 -0
- data/public/images/sound_add.png +0 -0
- data/public/images/sound_delete.png +0 -0
- data/public/images/sound_low.png +0 -0
- data/public/images/sound_mute.png +0 -0
- data/public/images/sound_none.png +0 -0
- data/public/images/spellcheck.png +0 -0
- data/public/images/sport_8ball.png +0 -0
- data/public/images/sport_basketball.png +0 -0
- data/public/images/sport_football.png +0 -0
- data/public/images/sport_golf.png +0 -0
- data/public/images/sport_raquet.png +0 -0
- data/public/images/sport_shuttlecock.png +0 -0
- data/public/images/sport_soccer.png +0 -0
- data/public/images/sport_tennis.png +0 -0
- data/public/images/star.png +0 -0
- data/public/images/status_away.png +0 -0
- data/public/images/status_busy.png +0 -0
- data/public/images/status_offline.png +0 -0
- data/public/images/status_online.png +0 -0
- data/public/images/stop.png +0 -0
- data/public/images/style.png +0 -0
- data/public/images/style_add.png +0 -0
- data/public/images/style_delete.png +0 -0
- data/public/images/style_edit.png +0 -0
- data/public/images/style_go.png +0 -0
- data/public/images/sum.png +0 -0
- data/public/images/swf/xspf/Main.as +55 -0
- data/public/images/swf/xspf/com/zuardi/musicplayer/MusicButton.as +557 -0
- data/public/images/swf/xspf/com/zuardi/musicplayer/MusicPlayer.as +118 -0
- data/public/images/swf/xspf/com/zuardi/musicplayer/Playlist.as +127 -0
- data/public/images/swf/xspf/com/zuardi/musicplayer/ProgressiveSlider.as +66 -0
- data/public/images/swf/xspf/license.txt +10 -0
- data/public/images/swf/xspf/musicplayer.swf +0 -0
- data/public/images/swf/xspf/musicplayer_f6.swf +0 -0
- data/public/images/swf/xspf/musicplayerbtn.fla +0 -0
- data/public/images/swf/xspf/parameters.as +39 -0
- data/public/images/tab.png +0 -0
- data/public/images/tab_add.png +0 -0
- data/public/images/tab_delete.png +0 -0
- data/public/images/tab_edit.png +0 -0
- data/public/images/tab_go.png +0 -0
- data/public/images/table.png +0 -0
- data/public/images/table_add.png +0 -0
- data/public/images/table_delete.png +0 -0
- data/public/images/table_edit.png +0 -0
- data/public/images/table_error.png +0 -0
- data/public/images/table_gear.png +0 -0
- data/public/images/table_go.png +0 -0
- data/public/images/table_key.png +0 -0
- data/public/images/table_lightning.png +0 -0
- data/public/images/table_link.png +0 -0
- data/public/images/table_multiple.png +0 -0
- data/public/images/table_refresh.png +0 -0
- data/public/images/table_relationship.png +0 -0
- data/public/images/table_row_delete.png +0 -0
- data/public/images/table_row_insert.png +0 -0
- data/public/images/table_save.png +0 -0
- data/public/images/table_sort.png +0 -0
- data/public/images/tag.png +0 -0
- data/public/images/tag_blue.png +0 -0
- data/public/images/tag_blue_add.png +0 -0
- data/public/images/tag_blue_delete.png +0 -0
- data/public/images/tag_blue_edit.png +0 -0
- data/public/images/tag_green.png +0 -0
- data/public/images/tag_orange.png +0 -0
- data/public/images/tag_pink.png +0 -0
- data/public/images/tag_purple.png +0 -0
- data/public/images/tag_red.png +0 -0
- data/public/images/tag_yellow.png +0 -0
- data/public/images/target.png +0 -0
- data/public/images/telephone.png +0 -0
- data/public/images/telephone_add.png +0 -0
- data/public/images/telephone_delete.png +0 -0
- data/public/images/telephone_edit.png +0 -0
- data/public/images/telephone_error.png +0 -0
- data/public/images/telephone_go.png +0 -0
- data/public/images/telephone_key.png +0 -0
- data/public/images/telephone_link.png +0 -0
- data/public/images/television.png +0 -0
- data/public/images/television_add.png +0 -0
- data/public/images/television_delete.png +0 -0
- data/public/images/text_align_center.png +0 -0
- data/public/images/text_align_justify.png +0 -0
- data/public/images/text_align_left.png +0 -0
- data/public/images/text_align_right.png +0 -0
- data/public/images/text_allcaps.png +0 -0
- data/public/images/text_bold.png +0 -0
- data/public/images/text_columns.png +0 -0
- data/public/images/text_dropcaps.png +0 -0
- data/public/images/text_heading_1.png +0 -0
- data/public/images/text_heading_2.png +0 -0
- data/public/images/text_heading_3.png +0 -0
- data/public/images/text_heading_4.png +0 -0
- data/public/images/text_heading_5.png +0 -0
- data/public/images/text_heading_6.png +0 -0
- data/public/images/text_horizontalrule.png +0 -0
- data/public/images/text_indent.png +0 -0
- data/public/images/text_indent_remove.png +0 -0
- data/public/images/text_italic.png +0 -0
- data/public/images/text_kerning.png +0 -0
- data/public/images/text_letter_omega.png +0 -0
- data/public/images/text_letterspacing.png +0 -0
- data/public/images/text_linespacing.png +0 -0
- data/public/images/text_list_bullets.png +0 -0
- data/public/images/text_list_numbers.png +0 -0
- data/public/images/text_lowercase.png +0 -0
- data/public/images/text_padding_bottom.png +0 -0
- data/public/images/text_padding_left.png +0 -0
- data/public/images/text_padding_right.png +0 -0
- data/public/images/text_padding_top.png +0 -0
- data/public/images/text_replace.png +0 -0
- data/public/images/text_signature.png +0 -0
- data/public/images/text_smallcaps.png +0 -0
- data/public/images/text_strikethrough.png +0 -0
- data/public/images/text_subscript.png +0 -0
- data/public/images/text_superscript.png +0 -0
- data/public/images/text_underline.png +0 -0
- data/public/images/text_uppercase.png +0 -0
- data/public/images/textfield.png +0 -0
- data/public/images/textfield_add.png +0 -0
- data/public/images/textfield_delete.png +0 -0
- data/public/images/textfield_key.png +0 -0
- data/public/images/textfield_rename.png +0 -0
- data/public/images/thumb_down.png +0 -0
- data/public/images/thumb_up.png +0 -0
- data/public/images/tick.png +0 -0
- data/public/images/time.png +0 -0
- data/public/images/time_add.png +0 -0
- data/public/images/time_delete.png +0 -0
- data/public/images/time_go.png +0 -0
- data/public/images/timeline_marker.png +0 -0
- data/public/images/transmit.png +0 -0
- data/public/images/transmit_add.png +0 -0
- data/public/images/transmit_blue.png +0 -0
- data/public/images/transmit_delete.png +0 -0
- data/public/images/transmit_edit.png +0 -0
- data/public/images/transmit_error.png +0 -0
- data/public/images/transmit_go.png +0 -0
- data/public/images/tux.png +0 -0
- data/public/images/user.png +0 -0
- data/public/images/user_add.png +0 -0
- data/public/images/user_admin.png +0 -0
- data/public/images/user_comment.png +0 -0
- data/public/images/user_delete.png +0 -0
- data/public/images/user_edit.png +0 -0
- data/public/images/user_female.png +0 -0
- data/public/images/user_go.png +0 -0
- data/public/images/user_gray.png +0 -0
- data/public/images/user_green.png +0 -0
- data/public/images/user_orange.png +0 -0
- data/public/images/user_pub.png +0 -0
- data/public/images/user_red.png +0 -0
- data/public/images/user_su.png +0 -0
- data/public/images/user_suit.png +0 -0
- data/public/images/validate.png +0 -0
- data/public/images/valider.png +0 -0
- data/public/images/vcard.png +0 -0
- data/public/images/vcard_add.png +0 -0
- data/public/images/vcard_delete.png +0 -0
- data/public/images/vcard_edit.png +0 -0
- data/public/images/vector.png +0 -0
- data/public/images/vector_add.png +0 -0
- data/public/images/vector_delete.png +0 -0
- data/public/images/wand.png +0 -0
- data/public/images/weather_clouds.png +0 -0
- data/public/images/weather_cloudy.png +0 -0
- data/public/images/weather_lightning.png +0 -0
- data/public/images/weather_rain.png +0 -0
- data/public/images/weather_snow.png +0 -0
- data/public/images/weather_sun.png +0 -0
- data/public/images/webcam.png +0 -0
- data/public/images/webcam_add.png +0 -0
- data/public/images/webcam_delete.png +0 -0
- data/public/images/webcam_error.png +0 -0
- data/public/images/world.png +0 -0
- data/public/images/world_add.png +0 -0
- data/public/images/world_delete.png +0 -0
- data/public/images/world_edit.png +0 -0
- data/public/images/world_go.png +0 -0
- data/public/images/world_link.png +0 -0
- data/public/images/wrench.png +0 -0
- data/public/images/wrench_orange.png +0 -0
- data/public/images/xhtml.png +0 -0
- data/public/images/xhtml_add.png +0 -0
- data/public/images/xhtml_delete.png +0 -0
- data/public/images/xhtml_go.png +0 -0
- data/public/images/xhtml_valid.png +0 -0
- data/public/images/zoom.png +0 -0
- data/public/images/zoom_in.png +0 -0
- data/public/images/zoom_out.png +0 -0
- data/public/img/logo.png +0 -0
- data/public/javascripts/application.js +2 -0
- data/public/javascripts/builder.js +136 -0
- data/public/javascripts/controls.js +965 -0
- data/public/javascripts/dragdrop.js +975 -0
- data/public/javascripts/effects.js +1130 -0
- data/public/javascripts/prototype.js +4320 -0
- data/public/javascripts/scriptaculous.js +60 -0
- data/public/javascripts/slider.js +275 -0
- data/public/javascripts/sound.js +55 -0
- data/public/javascripts/tablekit.js +965 -0
- data/public/javascripts/unittest.js +568 -0
- data/public/javascripts/upload-progress.js +133 -0
- data/public/javascripts/zena.js +501 -0
- data/public/robots.txt +1 -0
- data/public/stylesheets/admin.css +77 -0
- data/public/stylesheets/calendar.css +55 -0
- data/public/stylesheets/code.css +67 -0
- data/public/stylesheets/comment.css +43 -0
- data/public/stylesheets/csshover2.htc +121 -0
- data/public/stylesheets/default.css +85 -0
- data/public/stylesheets/popup.css +200 -0
- data/public/stylesheets/reset.css +33 -0
- data/public/stylesheets/search.css +19 -0
- data/public/stylesheets/upload-progress.css +4 -0
- data/public/stylesheets/wiki.css +100 -0
- data/public/stylesheets/zen.css +230 -0
- data/public/stylesheets/zena.css +78 -0
- data/rails/init.rb +2 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/fixtures/comments.yml +126 -0
- data/test/fixtures/contact_contents.yml +132 -0
- data/test/fixtures/data_entries.yml +65 -0
- data/test/fixtures/discussions.yml +48 -0
- data/test/fixtures/document_contents.yml +108 -0
- data/test/fixtures/dyn_attributes.yml +66 -0
- data/test/fixtures/files/Node-test.zafu +307 -0
- data/test/fixtures/files/bird.jpg +0 -0
- data/test/fixtures/files/bomb.png +0 -0
- data/test/fixtures/files/exif_sample.jpg +0 -0
- data/test/fixtures/files/flower.jpg +0 -0
- data/test/fixtures/files/forest.pdf +0 -0
- data/test/fixtures/files/import.tgz +0 -0
- data/test/fixtures/files/jet_30.zip +0 -0
- data/test/fixtures/files/lake.jpg +0 -0
- data/test/fixtures/files/letter.zip +0 -0
- data/test/fixtures/files/other.txt +1 -0
- data/test/fixtures/files/simple.zml.gz +0 -0
- data/test/fixtures/files/some.txt +1 -0
- data/test/fixtures/files/translations_de.yml +4 -0
- data/test/fixtures/files/translations_fr.yml +4 -0
- data/test/fixtures/files/tree.jpg +0 -0
- data/test/fixtures/files/water.pdf +0 -0
- data/test/fixtures/groups.yml +86 -0
- data/test/fixtures/groups_users.yml +81 -0
- data/test/fixtures/iformats.yml +28 -0
- data/test/fixtures/import/photos.en.zml +11 -0
- data/test/fixtures/import/photos/bird.jpg +0 -0
- data/test/fixtures/import/photos/bird.jpg.en.zml +1 -0
- data/test/fixtures/import/photos/bird.jpg.fr.zml +1 -0
- data/test/fixtures/import/photos/document.yml.en +4 -0
- data/test/fixtures/import/photos/document.yml.fr +4 -0
- data/test/fixtures/import/simple.zml +8 -0
- data/test/fixtures/links.yml +313 -0
- data/test/fixtures/nodes.yml +2592 -0
- data/test/fixtures/relations.yml +126 -0
- data/test/fixtures/sites.yml +58 -0
- data/test/fixtures/template_contents.yml +172 -0
- data/test/fixtures/users.yml +167 -0
- data/test/fixtures/versions.yml +1909 -0
- data/test/fixtures/virtual_classes.yml +87 -0
- data/test/fixtures/zips.yml +15 -0
- data/test/functional/application_controller_test.rb +136 -0
- data/test/functional/calendar_controller_test.rb +25 -0
- data/test/functional/comments_controller_test.rb +59 -0
- data/test/functional/data_entries_controller_test.rb +22 -0
- data/test/functional/discussion_controller_test.rb +20 -0
- data/test/functional/documents_controller_test.rb +155 -0
- data/test/functional/groups_controller_test.rb +109 -0
- data/test/functional/iformats_controller_test.rb +115 -0
- data/test/functional/links_controller_test.rb +26 -0
- data/test/functional/nodes_controller_test.rb +448 -0
- data/test/functional/note_controller_test.rb +53 -0
- data/test/functional/preferences_controller_test.rb +11 -0
- data/test/functional/relations_controller_test.rb +55 -0
- data/test/functional/search_controller_test.rb +41 -0
- data/test/functional/sessions_controller_test.rb +73 -0
- data/test/functional/sites_controller_test.rb +102 -0
- data/test/functional/users_controller_test.rb +28 -0
- data/test/functional/versions_controller_test.rb +99 -0
- data/test/functional/virtual_classes_controller_test.rb +62 -0
- data/test/helpers/node_query/basic.yml +149 -0
- data/test/helpers/node_query/comments.yml +18 -0
- data/test/helpers/node_query/complex.yml +98 -0
- data/test/helpers/node_query/filters.yml +105 -0
- data/test/helpers/node_query/relations.yml +43 -0
- data/test/helpers/node_query_test.rb +117 -0
- data/test/integration/multiple_hosts_test.rb +98 -0
- data/test/integration/multiversion_test.rb +164 -0
- data/test/integration/navigation_test.rb +283 -0
- data/test/sites/README +2 -0
- data/test/sites/complex/complex.png +0 -0
- data/test/sites/complex/groups.yml +9 -0
- data/test/sites/complex/links.yml +75 -0
- data/test/sites/complex/nodes.yml +253 -0
- data/test/sites/complex/relations.yml +11 -0
- data/test/sites/complex/sites.yml +13 -0
- data/test/sites/complex/users.yml +20 -0
- data/test/sites/complex/versions.yml +1 -0
- data/test/sites/complex/virtual_classes.yml +19 -0
- data/test/sites/ocean/contact_contents.yml +19 -0
- data/test/sites/ocean/groups.yml +9 -0
- data/test/sites/ocean/iformats.yml +7 -0
- data/test/sites/ocean/nodes.yml +36 -0
- data/test/sites/ocean/sites.yml +14 -0
- data/test/sites/ocean/template_contents.yml +8 -0
- data/test/sites/ocean/users.yml +33 -0
- data/test/sites/ocean/versions.yml +48 -0
- data/test/sites/zena/comments.yml +82 -0
- data/test/sites/zena/contact_contents.yml +55 -0
- data/test/sites/zena/data_entries.yml +42 -0
- data/test/sites/zena/discussions.yml +30 -0
- data/test/sites/zena/document_contents.yml +76 -0
- data/test/sites/zena/dyn_attributes.yml +43 -0
- data/test/sites/zena/groups.yml +11 -0
- data/test/sites/zena/iformats.yml +6 -0
- data/test/sites/zena/links.yml +49 -0
- data/test/sites/zena/nodes.yml +338 -0
- data/test/sites/zena/relations.yml +66 -0
- data/test/sites/zena/sites.yml +13 -0
- data/test/sites/zena/template_contents.yml +103 -0
- data/test/sites/zena/users.yml +48 -0
- data/test/sites/zena/versions.yml +558 -0
- data/test/sites/zena/virtual_classes.yml +23 -0
- data/test/test_helper.rb +62 -0
- data/test/test_zena.rb +138 -0
- data/test/unit/cache_test.rb +62 -0
- data/test/unit/cached_page_test.rb +165 -0
- data/test/unit/comment_test.rb +185 -0
- data/test/unit/contact_content_test.rb +33 -0
- data/test/unit/contact_test.rb +39 -0
- data/test/unit/contact_version_test.rb +48 -0
- data/test/unit/core_ext_test.rb +48 -0
- data/test/unit/data_entry_test.rb +92 -0
- data/test/unit/discussion_test.rb +59 -0
- data/test/unit/document_content_test.rb +110 -0
- data/test/unit/document_test.rb +234 -0
- data/test/unit/document_version_test.rb +11 -0
- data/test/unit/dyn_attributes_test.rb +229 -0
- data/test/unit/exif_data_test.rb +66 -0
- data/test/unit/group_test.rb +142 -0
- data/test/unit/iformat_test.rb +190 -0
- data/test/unit/image_builder_test.rb +214 -0
- data/test/unit/image_content_test.rb +154 -0
- data/test/unit/image_test.rb +311 -0
- data/test/unit/image_version_test.rb +18 -0
- data/test/unit/letter_test.rb +9 -0
- data/test/unit/link_test.rb +32 -0
- data/test/unit/multiversion_test.rb +1008 -0
- data/test/unit/node_test.rb +1578 -0
- data/test/unit/note_test.rb +85 -0
- data/test/unit/page_test.rb +79 -0
- data/test/unit/project_test.rb +32 -0
- data/test/unit/reference_test.rb +9 -0
- data/test/unit/relation_proxy_test.rb +409 -0
- data/test/unit/relation_test.rb +48 -0
- data/test/unit/section_test.rb +32 -0
- data/test/unit/secure_test.rb +939 -0
- data/test/unit/site_test.rb +236 -0
- data/test/unit/skin_test.rb +18 -0
- data/test/unit/template_content_test.rb +9 -0
- data/test/unit/template_test.rb +357 -0
- data/test/unit/template_version_test.rb +7 -0
- data/test/unit/text_document_content_test.rb +8 -0
- data/test/unit/text_document_test.rb +139 -0
- data/test/unit/text_document_version_test.rb +37 -0
- data/test/unit/user_test.rb +295 -0
- data/test/unit/version_test.rb +312 -0
- data/test/unit/virtual_class_test.rb +242 -0
- data/test/unit/zena/db_test.rb +94 -0
- data/test/unit/zena/parser/latex.yml +14 -0
- data/test/unit/zena/parser/zafu.yml +391 -0
- data/test/unit/zena/parser/zafu_asset.yml +43 -0
- data/test/unit/zena/parser/zafu_insight.yml +3 -0
- data/test/unit/zena/parser/zazen.yml +211 -0
- data/test/unit/zena/parser_test.rb +184 -0
- data/test/unit/zena/unit/test_case_test.rb +12 -0
- data/test/unit/zena/use/calendar_test.rb +49 -0
- data/test/unit/zena/use/dates_model_methods_test.rb +41 -0
- data/test/unit/zena/use/dates_string_methods_test.rb +94 -0
- data/test/unit/zena/use/dates_view_methods_test.rb +158 -0
- data/test/unit/zena/use/html_tags_test.rb +244 -0
- data/test/unit/zena/use/i18n_test.rb +34 -0
- data/test/unit/zena/use/nested_attributes_alias_model_test.rb +104 -0
- data/test/unit/zena/use/nested_attributes_alias_view_test.rb +99 -0
- data/test/unit/zena/use/refactor_test.rb +52 -0
- data/test/unit/zena/use/rendering_test.rb +23 -0
- data/test/unit/zena/use/urls_test.rb +119 -0
- data/test/unit/zena/use/zafu_test.rb +21 -0
- data/test/unit/zena/use/zazen_test.rb +230 -0
- data/test/unit/zena/zena_tags/ajax.yml +233 -0
- data/test/unit/zena/zena_tags/apphelper.yml +85 -0
- data/test/unit/zena/zena_tags/basic.yml +1295 -0
- data/test/unit/zena/zena_tags/complex.yml +249 -0
- data/test/unit/zena/zena_tags/data.yml +73 -0
- data/test/unit/zena/zena_tags/errors.yml +71 -0
- data/test/unit/zena/zena_tags/eval.yml +51 -0
- data/test/unit/zena/zena_tags/relations.yml +411 -0
- data/test/unit/zena/zena_tags/zazen.yml +84 -0
- data/test/unit/zena/zena_tags_test.rb +235 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run 2.tmCommand +24 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run Context.tmCommand +58 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run Focused Should.tmCommand +88 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run.tmCommand +27 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/YAML to Shoulda.tmCommand +23 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Preferences/Symbol List: Context.tmPreferences +19 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Preferences/Symbol List: Should.tmPreferences +19 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory attributes for.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory build.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_define with class.tmSnippet +18 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_define.tmSnippet +18 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_next.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_sequence.tmSnippet +18 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_bad_value.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_contains.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_does_not_contain.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_good_value.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_same_elements.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_save.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_sent_email.tmSnippet +18 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_valid.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/association.tmSnippet +17 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/attribute.tmSnippet +17 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/before_should block.tmSnippet +18 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/context block get.tmSnippet +22 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/context block post.tmSnippet +23 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/context block with setup.tmSnippet +25 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/setup.tmSnippet +18 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should block with before proc.tmSnippet +18 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should block.tmSnippet +18 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_allow_values_for.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_assign_to.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_be_restful denied.tmSnippet +20 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_be_restful.tmSnippet +20 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_belong_to.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_change by.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_change from to.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_length_at_least.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_length_in_range.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_length_is.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_value_in_range.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_eventually.tmSnippet +18 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_filter_params.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_and_belong_to_many.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_class_methods.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_db_column.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_db_columns.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_index.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_indices.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_instance_methods.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_many.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_named_scope.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_one.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_readonly_attributes.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_allow_mass_assignment_of.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_allow_values_for.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_assign_to.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_change.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_set_the_flash.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_redirect_to.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_a_form.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_template.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_with_layout.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_without_layout.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_respond_with.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_respond_with_content_type.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_return_from_session.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_route.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_set_the_flash_to.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_acceptance_of.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_numericality_of.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_presence_of.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_uniqueness_of with scope.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_uniqueness_of.tmSnippet +16 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/catch_exception.rb +39 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/run_script.rb +104 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/stdin_dialog.rb +14 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/test.rb +17 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/todo.txt +13 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/bin/yaml_to_shoulda.rb +25 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/Syntaxes/Ruby on Rails (Shoulda).tmLanguage +166 -0
- data/vendor/TextMate/Ruby Shoulda.tmbundle/info.plist +304 -0
- data/vendor/TextMate/Zena.tmbundle/Commands/Run all yaml tests.tmCommand +37 -0
- data/vendor/TextMate/Zena.tmbundle/Commands/Run focused yaml test.tmCommand +53 -0
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/run_script.rb +74 -0
- data/vendor/TextMate/Zena.tmbundle/info.plist +15 -0
- data/vendor/apache_upload/mod_upload_progress.c +813 -0
- data/vendor/bricks/20070122-172926.txt +282 -0
- data/vendor/plugins/ar_mysql_full_text/README +15 -0
- data/vendor/plugins/ar_mysql_full_text/init.rb +1 -0
- data/vendor/plugins/ar_mysql_full_text/lib/ar_mysql_full_text.rb +69 -0
- data/vendor/plugins/gettext_i18n_rails/README.markdown +139 -0
- data/vendor/plugins/gettext_i18n_rails/Rakefile +6 -0
- data/vendor/plugins/gettext_i18n_rails/init.rb +10 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails.rb +21 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/action_controller.rb +6 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/active_record.rb +17 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/backend.rb +47 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/haml_parser.rb +43 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/i18n_hacks.rb +10 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/model_attributes_finder.rb +46 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/ruby_gettext_extractor.rb +136 -0
- data/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/action_controller_spec.rb +36 -0
- data/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/active_record_spec.rb +50 -0
- data/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/backend_spec.rb +41 -0
- data/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails_spec.rb +43 -0
- data/vendor/plugins/gettext_i18n_rails/spec/spec_helper.rb +15 -0
- data/vendor/plugins/gettext_i18n_rails/tasks/gettext_rails_i18n.rake +73 -0
- data/vendor/plugins/responds_to_parent/MIT-LICENSE +20 -0
- data/vendor/plugins/responds_to_parent/README +42 -0
- data/vendor/plugins/responds_to_parent/Rakefile +22 -0
- data/vendor/plugins/responds_to_parent/init.rb +1 -0
- data/vendor/plugins/responds_to_parent/lib/responds_to_parent.rb +46 -0
- data/vendor/plugins/responds_to_parent/test/responds_to_parent_test.rb +115 -0
- data/vendor/plugins/rjs-assertions/MIT-LICENSE +20 -0
- data/vendor/plugins/rjs-assertions/README +64 -0
- data/vendor/plugins/rjs-assertions/init.rb +1 -0
- data/vendor/plugins/rjs-assertions/lib/rjs-assertions.rb +99 -0
- data/vendor/rails_patches/support_for_inverse_relationships_on_active_record_objects.diff +739 -0
- metadata +2075 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'redcloth'
|
2
|
+
|
3
|
+
module Zena
|
4
|
+
module Parser
|
5
|
+
module ZazenTags
|
6
|
+
# This is not exactly how compile/render is meant to work with Parser, but there is no real need for a two step
|
7
|
+
# rendering, so we compile here (enter(:void)) instead of doing this whith 'start'. This also lets us have the
|
8
|
+
# context during compilation which makes it easier to manage the callbacks to the helper.
|
9
|
+
def r_void
|
10
|
+
@context = {:images => true, :pretty_code=>true, :output => 'html'}.merge(@context)
|
11
|
+
@translate_ids = @context[:translate_ids]
|
12
|
+
@text = @text.gsub("\r\n","\n") # this also creates our own 'working' copy of the text
|
13
|
+
@blocks = "" # same reason as why we rewrite 'store'
|
14
|
+
|
15
|
+
extract_code(@text)
|
16
|
+
|
17
|
+
# set whether the first paragraphe is spaced preserved.
|
18
|
+
@in_space_pre = (@text[0..0] == ' ')
|
19
|
+
|
20
|
+
enter(:void) # <== parse here
|
21
|
+
|
22
|
+
unless @translate_ids
|
23
|
+
store '</pre>' if @in_space_pre
|
24
|
+
|
25
|
+
case @context[:output]
|
26
|
+
when 'html'
|
27
|
+
# TODO: we should write our own parser for textile with rendering formats...
|
28
|
+
@text = RedCloth.new(@blocks).to_html
|
29
|
+
when 'latex'
|
30
|
+
# replace RedCloth markup by latex equivalent
|
31
|
+
@text = RedCloth.new(@blocks).to_latex
|
32
|
+
end
|
33
|
+
|
34
|
+
# Replace placeholders by their real values
|
35
|
+
@helper.replace_placeholders(@text) if @helper.respond_to?('replace_placeholders')
|
36
|
+
@blocks = ""
|
37
|
+
enter(:wiki)
|
38
|
+
end
|
39
|
+
render_code(@blocks)
|
40
|
+
@blocks
|
41
|
+
end
|
42
|
+
end # ZazenTags
|
43
|
+
end # Parser
|
44
|
+
end # Zena
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Zena
|
2
|
+
module Parser
|
3
|
+
module ZenaRules
|
4
|
+
def start(mode)
|
5
|
+
super
|
6
|
+
if @method =~ /^\[(.*)\]$/
|
7
|
+
# do='[text]
|
8
|
+
@method = 'show'
|
9
|
+
@params[:attr_or_date] = $1
|
10
|
+
elsif @method =~ /^\{(.*)\}$/
|
11
|
+
# do='{v_text}'
|
12
|
+
@method = 'zazen'
|
13
|
+
@params[:attr] = $1
|
14
|
+
elsif @method =~ /\A(\w+)\s+(\w+)\s+(.+)$/
|
15
|
+
# 'pages where name ...'
|
16
|
+
@params[:select] = @method
|
17
|
+
@method = 'context'
|
18
|
+
end
|
19
|
+
|
20
|
+
if @method == 'with' || self.respond_to?("r_#{@method}")
|
21
|
+
# ok
|
22
|
+
else
|
23
|
+
@params[:select] = @method
|
24
|
+
@method = 'context'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end # ZenaRules
|
28
|
+
end # Parser
|
29
|
+
end # Zena
|
@@ -0,0 +1,3559 @@
|
|
1
|
+
=begin
|
2
|
+
Thoughts for ajax related stuff cleanup (dom_id, erb_dom_id, ...)
|
3
|
+
|
4
|
+
When we open a list context:
|
5
|
+
- we change the context_dom_id => unique name => "page"
|
6
|
+
|
7
|
+
When we open a single context (do_var, each, block):
|
8
|
+
- we change the context_dom_id => unique name with id => "page_{parent_id}"
|
9
|
+
|
10
|
+
Any 'id' is set with:
|
11
|
+
- "{context_dom_id}_{id}" => 'page_34' (if not in list) or 'page_12_34' if in list.
|
12
|
+
|
13
|
+
|
14
|
+
List in list (initial node zip = 12):
|
15
|
+
context_dom_id dom_id (context_erb_dom_id, erb_dom_id)
|
16
|
+
<ul> page_12 page_12 [pages in='site'] new unique name
|
17
|
+
<li id='page_12_13'> page_12 page_12_13 [each] expand_with(:context_dom_id => 'page_13')
|
18
|
+
<ul> page_13
|
19
|
+
<li id='page_13_23'/> page_13 page_13_23 [each]
|
20
|
+
<li id='page_13_24'/> page_13 page_13_24 [each]
|
21
|
+
<li id='page_13_25'/> page_13 page_13_25 [each]
|
22
|
+
</ul>
|
23
|
+
</li>
|
24
|
+
<li id='page_12_14'> page_12 page_12_14 [each] expand_with(:context_dom_id => 'page_14')
|
25
|
+
<ul>
|
26
|
+
<li id='page_14_23'/> page_14 page_14_23 [each] expand_with(:context_dom_id => 'page_23')
|
27
|
+
<li id='page_14_27'/> page_14 page_14_27 [each] ...
|
28
|
+
</ul>
|
29
|
+
</li>
|
30
|
+
</ul>
|
31
|
+
|
32
|
+
<div id='page1_12'> page1_12 page1_12 [block] new unique name
|
33
|
+
<ul>
|
34
|
+
<li id='page1_12_24'/> page1_12 page1_12_24 [each]
|
35
|
+
<li id='page1_12_32'/> page1_12 page1_12_32 [each]
|
36
|
+
</ul>
|
37
|
+
</div>
|
38
|
+
=end
|
39
|
+
|
40
|
+
require 'yaml'
|
41
|
+
|
42
|
+
module Zena
|
43
|
+
module Parser
|
44
|
+
# Zafu tags used to display / edit nodes and versions
|
45
|
+
module ZenaTags
|
46
|
+
PSEUDO_ATTRIBUTES = {
|
47
|
+
'now' => 'Time.now',
|
48
|
+
'start.id' => '(params[:s] || @node[:zip])',
|
49
|
+
'nil' => 'nil',
|
50
|
+
}
|
51
|
+
|
52
|
+
class << self
|
53
|
+
def inline_methods(*args)
|
54
|
+
args.each do |name|
|
55
|
+
class_eval <<-END
|
56
|
+
def r_#{name}
|
57
|
+
"<%= #{name}(:node=>\#{node}\#{params_to_erb(@params)}) %>"
|
58
|
+
end
|
59
|
+
END
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def direct_methods(*args)
|
64
|
+
args.each do |name|
|
65
|
+
class_eval <<-END
|
66
|
+
def r_#{name}
|
67
|
+
helper.#{name}
|
68
|
+
end
|
69
|
+
END
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
inline_methods :login_link, :visitor_link, :search_box, :show_menu, :show_path, :lang_links
|
74
|
+
direct_methods :uses_datebox
|
75
|
+
|
76
|
+
def before_render
|
77
|
+
return unless super
|
78
|
+
|
79
|
+
@var = nil # reset var counter
|
80
|
+
|
81
|
+
if key = @params[:store]
|
82
|
+
set_stored(Node, key, node)
|
83
|
+
end
|
84
|
+
|
85
|
+
if key = @params[:store_date]
|
86
|
+
set_stored(Date, key, current_date)
|
87
|
+
end
|
88
|
+
@anchor_param = @params[:anchor]
|
89
|
+
|
90
|
+
true
|
91
|
+
end
|
92
|
+
|
93
|
+
def do_method(sym)
|
94
|
+
method = sym
|
95
|
+
pre, post = '', ''
|
96
|
+
|
97
|
+
# do we need recursion ?
|
98
|
+
inc = descendant('include')
|
99
|
+
if inc && inc.params[:part] == @name
|
100
|
+
@context["#{@name}_method".to_sym] = method_name = template_url[1..-1].gsub(/[\/-]/,'_')
|
101
|
+
pre << "<% def #{method_name}(depth, node, list); return '' if depth > #{inc.params[:depth] ? [inc.params[:depth].to_i,30].min : 5}; _erbout = '' -%>"
|
102
|
+
post << "<% _erbout; end -%><%= #{method_name}(0,#{node},#{list || "[#{node}]"}) %>"
|
103
|
+
@context[:node] = 'node'
|
104
|
+
@context[:list] = 'list'
|
105
|
+
end
|
106
|
+
|
107
|
+
if @context[:make_form]
|
108
|
+
res = case method
|
109
|
+
when :r_title
|
110
|
+
make_input(:name => 'v_title')
|
111
|
+
when :r_link
|
112
|
+
make_input(:name => (@params[:attr] || 'v_title'))
|
113
|
+
when :r_show
|
114
|
+
make_input(:name => (@params[:attr] || @params[:tattr]), :date => @params[:date])
|
115
|
+
when :r_text
|
116
|
+
make_textarea(:name => 'v_text')
|
117
|
+
when :r_summary
|
118
|
+
make_textarea(:name => 'v_summary')
|
119
|
+
when :r_zazen
|
120
|
+
make_textarea(:name => @params[:attr])
|
121
|
+
else
|
122
|
+
if node_kind_of?(DataEntry) && @method.to_s =~ /node_/
|
123
|
+
# select node_id
|
124
|
+
"<%= select_id('#{base_class.to_s.underscore}', '#{@method}_id') %>"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
res = "<#{@html_tag || 'div'} class='zazen'>#{res}</#{@html_tag || 'div'}>" if [:r_summary, :r_text].include?(sym)
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
res ||= super(method)
|
132
|
+
"#{pre}#{res}#{post}"
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
def after_render(text)
|
137
|
+
if @anchor_param
|
138
|
+
@params[:anchor] = @anchor_param # set back in case of double rendering so it is computed again
|
139
|
+
res = r_anchor + super
|
140
|
+
else
|
141
|
+
res = super
|
142
|
+
end
|
143
|
+
res
|
144
|
+
end
|
145
|
+
|
146
|
+
# Our special version of r_expand_with tag with "set_" parsing.
|
147
|
+
def r_expand_with
|
148
|
+
hash = {}
|
149
|
+
@params.each do |k,v|
|
150
|
+
if k.to_s =~ /^set_(.+)$/
|
151
|
+
# TODO: DRY with render_html_tag
|
152
|
+
k = $1
|
153
|
+
value, static = parse_attributes_in_value(v, :erb => false)
|
154
|
+
hash["exp_#{k}"] = static ? value.inspect : "\"#{value}\""
|
155
|
+
else
|
156
|
+
hash["exp_#{k}"] = v.inspect
|
157
|
+
end
|
158
|
+
end
|
159
|
+
@params = {}
|
160
|
+
expand_with(hash)
|
161
|
+
end
|
162
|
+
|
163
|
+
def r_show
|
164
|
+
if attr_or_date = @params[:attr_or_date]
|
165
|
+
# using [var] shortcut. Can be either a date or an attribute/var
|
166
|
+
if attr_or_date == 'current_date' || attr_or_date =~ /_at$/
|
167
|
+
@params[:date] = attr_or_date
|
168
|
+
else
|
169
|
+
@params[:attr] = attr_or_date
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
if var_name = @params[:var]
|
174
|
+
return parser_error("var #{@params[:var].inspect} not set") unless @context[:vars] && @context[:vars].include?(var_name)
|
175
|
+
attribute_method = "set_#{var_name}"
|
176
|
+
elsif @params[:eval]
|
177
|
+
return unless attribute_method = parse_eval_parameter(@params[:eval])
|
178
|
+
elsif @params[:tattr]
|
179
|
+
attribute_method = "_(#{node_attribute(@params[:tattr], :else=>@params[:else], :default=>@params[:default])})"
|
180
|
+
elsif @params[:attr]
|
181
|
+
attribute_method = node_attribute(@params[:attr], :else=>@params[:else], :default=>@params[:default])
|
182
|
+
elsif p = @params[:param]
|
183
|
+
return "<%= params[#{p.to_sym.inspect}] %>"
|
184
|
+
elsif @params[:date]
|
185
|
+
# date can be any attribute v_created_at or updated_at etc.
|
186
|
+
# TODO format with @params[:format] and @params[:tformat] << translated format
|
187
|
+
# TODO: test
|
188
|
+
if @params[:tformat]
|
189
|
+
format = _(@params[:tformat])
|
190
|
+
elsif @params[:format]
|
191
|
+
format = @params[:format]
|
192
|
+
else
|
193
|
+
format = "%Y-%m-%d"
|
194
|
+
end
|
195
|
+
|
196
|
+
tz = ''
|
197
|
+
lang = ''
|
198
|
+
if tz_name = @params[:time_zone]
|
199
|
+
tz_list = @params.reject {|k,v| !(k.to_s =~ /^time_zone\d*$/)}.to_a.sort {|a,b| a[0].to_s <=> b[0].to_s }.map do |k,tz_name|
|
200
|
+
if tz_name =~ /^\[(\w+)\]$/
|
201
|
+
node_attribute($1)
|
202
|
+
else
|
203
|
+
begin
|
204
|
+
TZInfo::Timezone.get(tz_name)
|
205
|
+
rescue TZInfo::InvalidTimezoneIdentifier
|
206
|
+
return parser_error("invalid timezone #{tz_name.inspect}")
|
207
|
+
end
|
208
|
+
tz_name.inspect
|
209
|
+
end
|
210
|
+
end
|
211
|
+
tz = ", #{tz_list.join(' || ')}"
|
212
|
+
end
|
213
|
+
if lang = @params[:lang]
|
214
|
+
tz = ', nil' if tz == ''
|
215
|
+
lang = ", #{lang.inspect}"
|
216
|
+
end
|
217
|
+
attribute_method = "format_date(#{node_attribute(@params[:date])}, #{format.inspect}#{tz}#{lang})"
|
218
|
+
elsif @context[:trans]
|
219
|
+
# error
|
220
|
+
return "no attribute for 'show'".inspect
|
221
|
+
else
|
222
|
+
return parser_error("missing attribute")
|
223
|
+
end
|
224
|
+
|
225
|
+
if !@params[:date] && fmt = @params[:format]
|
226
|
+
begin
|
227
|
+
# test argument
|
228
|
+
sprintf(fmt, 123.45)
|
229
|
+
rescue ArgumentError
|
230
|
+
return parser_error("incorect format #{fmt.inspect}")
|
231
|
+
end
|
232
|
+
if fmt =~ /%[\d\.]*f/
|
233
|
+
modifier = ".to_f"
|
234
|
+
elsif fmt =~ /%[\d\.]*i/
|
235
|
+
modifier = ".to_i"
|
236
|
+
else
|
237
|
+
modifier = ''
|
238
|
+
end
|
239
|
+
|
240
|
+
if @params[:zero] == 'hide'
|
241
|
+
attribute_method = "sprintf_unless_zero(#{fmt.inspect}, #{attribute_method}#{modifier})"
|
242
|
+
else
|
243
|
+
attribute_method = "sprintf(#{fmt.inspect}, #{attribute_method}#{modifier})"
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
|
248
|
+
if @context[:trans]
|
249
|
+
# TODO: what do we do here with gsubs, url ?
|
250
|
+
return attribute_method
|
251
|
+
end
|
252
|
+
|
253
|
+
if gsub = @params[:gsub]
|
254
|
+
if gsub =~ /\A\/(.+)\/(.+)\/\Z/
|
255
|
+
value = $2
|
256
|
+
key = $1.gsub(/\#([\{\$\@])/,'# \1') # FIXME: SECURITY.
|
257
|
+
# Please note that .gsub(/#([\{\$\@])/,'\#\1') won't work, since '\#{blah}' will become '\\#{blah}' and 'blah' will be evaluated.
|
258
|
+
regexp_ok = begin
|
259
|
+
output = StringIO.open('','w')
|
260
|
+
$stderr = output
|
261
|
+
re = /#{key}/
|
262
|
+
output.string !~ /warning:/
|
263
|
+
rescue
|
264
|
+
false
|
265
|
+
ensure
|
266
|
+
$stderr = STDERR
|
267
|
+
false
|
268
|
+
end
|
269
|
+
|
270
|
+
if regexp_ok
|
271
|
+
attribute_method = "#{attribute_method}.to_s.gsub(/#{key}/,#{value.inspect})"
|
272
|
+
else
|
273
|
+
# invalid regexp
|
274
|
+
return parser_error("invalid gsub #{gsub.inspect}")
|
275
|
+
end
|
276
|
+
else
|
277
|
+
# error
|
278
|
+
return parser_error("invalid gsub #{gsub.inspect}")
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
if @params[:actions]
|
283
|
+
actions = "<%= node_actions(:node=>#{node}#{params_to_erb(:actions=>@params[:actions], :publish_after_save=>auto_publish_param)}) %>"
|
284
|
+
else
|
285
|
+
actions = ''
|
286
|
+
end
|
287
|
+
|
288
|
+
attribute = @params[:attr] || @params[:tattr] || @params[:date]
|
289
|
+
|
290
|
+
if (@params[:edit_preview] || @params[:ep]) == 'true'
|
291
|
+
@html_tag_params[:id] = "#{attribute}#{erb_node_id}"
|
292
|
+
@html_tag ||= 'span'
|
293
|
+
end
|
294
|
+
|
295
|
+
if @params[:edit] == 'true' && !['url','path'].include?(attribute)
|
296
|
+
"<% if #{node}.can_write? -%><span class='show_edit' id='#{erb_dom_id("_#{attribute}")}'>#{actions}<%= link_to_remote(#{attribute_method}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&dom_id=#{dom_id("_#{attribute}")}#{auto_publish_param(true)}\", :method => :get) %></span><% else -%>#{actions}<%= #{attribute_method} %><% end -%>"
|
297
|
+
else
|
298
|
+
"#{actions}<%= #{attribute_method} %>"
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def r_zazen
|
303
|
+
attribute = @params[:attr] || @params[:tattr]
|
304
|
+
limit = @params[:limit] ? ", :limit=>#{@params[:limit].to_i}" : ""
|
305
|
+
if @context[:trans]
|
306
|
+
# TODO: what do we do here with dates ?
|
307
|
+
return "#{node_attribute(attribute)}"
|
308
|
+
elsif @params[:tattr]
|
309
|
+
return "<%= zazen(_(#{node_attribute(attribute)})#{limit}, :node=>#{node(Node)}) %>"
|
310
|
+
elsif @params[:attr]
|
311
|
+
if output_format == 'html'
|
312
|
+
res = "<%= zazen(#{node_attribute(attribute)}#{limit}, :node=>#{node(Node)}) %>"
|
313
|
+
else
|
314
|
+
return "<%= zazen(#{node_attribute(attribute)}#{limit}, :node=>#{node(Node)}, :output=>#{output_format.inspect}) %>"
|
315
|
+
end
|
316
|
+
elsif @params[:date]
|
317
|
+
# date can be any attribute v_created_at or updated_at etc.
|
318
|
+
# TODO format with @params[:format] and @params[:tformat] << translated format
|
319
|
+
else
|
320
|
+
# error
|
321
|
+
end
|
322
|
+
|
323
|
+
@html_tag ||= 'div'
|
324
|
+
|
325
|
+
add_html_class('zazen')
|
326
|
+
|
327
|
+
if (@params[:edit_preview] || @params[:ep]) == 'true'
|
328
|
+
@html_tag_params[:id] = "#{attribute}#{erb_node_id}"
|
329
|
+
end
|
330
|
+
|
331
|
+
if @params[:edit] == 'true' && !['url','path'].include?(attribute)
|
332
|
+
edit_text = _('edit')
|
333
|
+
@html_tag_params[:id] = erb_dom_id("_#{attribute}")
|
334
|
+
res = "<% if #{node}.can_write? -%><span class='zazen_edit'><%= link_to_remote(#{edit_text.inspect}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&dom_id=#{dom_id("_#{attribute}")}#{auto_publish_param(true)}&zazen=true\", :method => :get) %></span><% end -%>#{res}"
|
335
|
+
else
|
336
|
+
res
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# TODO: test, rename ?
|
341
|
+
def r_search_results
|
342
|
+
do_list("@nodes")
|
343
|
+
end
|
344
|
+
|
345
|
+
|
346
|
+
def r_set
|
347
|
+
return parser_error("'var' missing") unless var_name = @params[:var]
|
348
|
+
return parser_error("bad value for 'var' (#{var_name.inspect})") unless var_name =~ /^[a-zA-Z_]+$/
|
349
|
+
return '' unless @context[:set]
|
350
|
+
if @params[:value]
|
351
|
+
out "<% set_#{var_name} = #{@params[:value].inspect} -%>"
|
352
|
+
# TODO: isn't @context[:vars] = @params[:value].inspect missing here ?
|
353
|
+
elsif @params[:eval]
|
354
|
+
return unless eval_string = parse_eval_parameter(@params[:eval])
|
355
|
+
out "<% set_#{var_name} = #{eval_string} -%>"
|
356
|
+
else
|
357
|
+
out "<% set_#{var_name} = capture do %>"
|
358
|
+
out expand_with(:set => false) # do not propagate
|
359
|
+
out "<% end -%>"
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
|
364
|
+
# TODO: write a test (please)
|
365
|
+
# FIXME: we should use a single way to change a whole context into a template (applies to 'each', 'form', 'block'). Then 'swap' could use the 'each' block.
|
366
|
+
# Define a block of elements to be used by ajax calls (edit/filter)
|
367
|
+
def r_block
|
368
|
+
if @context[:block] == self
|
369
|
+
# called from self (storing template)
|
370
|
+
@context.reject! do |k,v|
|
371
|
+
# FIXME: reject all stored elements in a better way then this
|
372
|
+
k.kind_of?(String) && k =~ /\ANode_\w/
|
373
|
+
end
|
374
|
+
@html_tag_done = false
|
375
|
+
@html_tag_params.merge!(:id=>erb_dom_id)
|
376
|
+
@context[:scope_node] = node if @context[:scope_node]
|
377
|
+
out expand_with(:node => node)
|
378
|
+
if @method == 'drop' && !@context[:make_form]
|
379
|
+
out drop_javascript
|
380
|
+
end
|
381
|
+
else
|
382
|
+
if parent.method == 'each' && @method == parent.single_child_method
|
383
|
+
# use parent as block
|
384
|
+
# FIXME: will not work with block as distant target...
|
385
|
+
# do nothing
|
386
|
+
else
|
387
|
+
@html_tag ||= 'div'
|
388
|
+
new_dom_scope
|
389
|
+
|
390
|
+
unless @context[:make_form]
|
391
|
+
# STORE TEMPLATE ========
|
392
|
+
|
393
|
+
context_bak = @context.dup # avoid side effects when rendering the same block
|
394
|
+
ignore_list = @method == 'block' ? ['form'] : [] # do not show the form in the normal template of a block
|
395
|
+
template = expand_block(self, :block=>self, :list=>false, :saved_template=>true, :ignore => ignore_list)
|
396
|
+
@context = context_bak
|
397
|
+
@result = ''
|
398
|
+
out helper.save_erb_to_url(template, template_url)
|
399
|
+
|
400
|
+
# STORE FORM ============
|
401
|
+
if edit = descendant('edit')
|
402
|
+
publish_after_save = (edit.params[:publish] == 'true')
|
403
|
+
if form = descendant('form')
|
404
|
+
# USE BLOCK FORM ========
|
405
|
+
form_text = expand_block(form, :saved_template=>true, :publish_after_save => publish_after_save)
|
406
|
+
else
|
407
|
+
# MAKE A FORM FROM BLOCK ========
|
408
|
+
form = self.dup
|
409
|
+
form.method = 'form'
|
410
|
+
form_text = expand_block(form, :make_form => true, :list => false, :saved_template => true, :publish_after_save => publish_after_save)
|
411
|
+
end
|
412
|
+
out helper.save_erb_to_url(form_text, form_url)
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
# RENDER
|
417
|
+
@html_tag_done = false
|
418
|
+
@html_tag_params.merge!(:id=>erb_dom_id)
|
419
|
+
end
|
420
|
+
|
421
|
+
out expand_with
|
422
|
+
if @method == 'drop' && !@context[:make_form]
|
423
|
+
out drop_javascript
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
# TODO: test
|
429
|
+
def r_filter
|
430
|
+
if upd = @params[:update]
|
431
|
+
return unless block = find_target(upd)
|
432
|
+
else
|
433
|
+
return parser_error("missing 'block' in same parent") unless parent && block = parent.descendant('block')
|
434
|
+
end
|
435
|
+
return parser_error("cannot use 's' as key (used by start_node)") if @params[:key] == 's'
|
436
|
+
out "<%= form_remote_tag(:url => zafu_node_path(#{node_id}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %><div class='hidden'><input type='hidden' name='t_url' value='#{block.template_url}'/><input type='hidden' name='dom_id' value='#{block.erb_dom_id}'/>#{start_node_s_param(:input)}</div><div class='wrapper'>"
|
437
|
+
if @blocks == []
|
438
|
+
out "<input type='text' name='#{@params[:key] || 'f'}' value='<%= params[#{(@params[:key] || 'f').to_sym.inspect}] %>'/>"
|
439
|
+
else
|
440
|
+
out expand_with(:in_filter => true)
|
441
|
+
end
|
442
|
+
out "</div></form>"
|
443
|
+
if @params[:live] || @params[:update]
|
444
|
+
out "<%= observe_form( \"#{dom_id}_f\" , :method => :get, :frequency => 1, :submit =>\"#{dom_id}_f\", :url => zafu_node_path(#{node_id})) %>"
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
# swap an attribute
|
449
|
+
# TODO: test
|
450
|
+
def r_swap
|
451
|
+
if upd = @params[:update]
|
452
|
+
if upd == '_page'
|
453
|
+
block = nil
|
454
|
+
elsif block = find_target(upd)
|
455
|
+
# ok
|
456
|
+
if ancestor('block') || ancestor('each')
|
457
|
+
upd_both = '&upd_both=true'
|
458
|
+
else
|
459
|
+
upd_both = ''
|
460
|
+
end
|
461
|
+
else
|
462
|
+
return
|
463
|
+
end
|
464
|
+
elsif ancestor('block') || ancestor('each')
|
465
|
+
# ancestor: ok
|
466
|
+
block = self
|
467
|
+
elsif parent && block = parent.descendant('block')
|
468
|
+
# sibling: ok
|
469
|
+
upd_both = ''
|
470
|
+
else
|
471
|
+
return parser_error("missing 'block' in same parent")
|
472
|
+
end
|
473
|
+
|
474
|
+
states = ((@params[:states] || 'todo, done') + ' ').split(',').map(&:strip)
|
475
|
+
|
476
|
+
query_params = "node[#{@params[:attr]}]=\#{#{states.inspect}[ ((#{states.inspect}.index(#{node_attribute(@params[:attr])}.to_s) || 0)+1) % #{states.size}]}#{upd_both}"
|
477
|
+
out link_to_update(block, :query_params => query_params, :method => :put, :html_params => get_html_params(@params, :link))
|
478
|
+
end
|
479
|
+
|
480
|
+
def r_load
|
481
|
+
if dict = @params[:dictionary]
|
482
|
+
dict_content, absolute_url, doc = self.class.get_template_text(dict, @options[:helper], @options[:current_folder])
|
483
|
+
return parser_error("dictionary #{dict.inspect} not found") unless doc
|
484
|
+
@context[:dict] ||= {}
|
485
|
+
begin
|
486
|
+
definitions = YAML::load(dict_content)
|
487
|
+
definitions['translations'].each do |elem|
|
488
|
+
@context[:dict][elem[0]] = elem[1]
|
489
|
+
end
|
490
|
+
rescue
|
491
|
+
return parser_error("invalid dictionary content #{dict.inspect}")
|
492
|
+
end
|
493
|
+
else
|
494
|
+
return parser_error("missing 'dictionary'")
|
495
|
+
end
|
496
|
+
expand_with
|
497
|
+
end
|
498
|
+
|
499
|
+
def r_trans
|
500
|
+
static = true
|
501
|
+
if @params[:text]
|
502
|
+
text = @params[:text]
|
503
|
+
elsif @params[:attr]
|
504
|
+
text = "#{node_attribute(@params[:attr])}"
|
505
|
+
static = false
|
506
|
+
else
|
507
|
+
res = []
|
508
|
+
text = ""
|
509
|
+
@blocks.each do |b|
|
510
|
+
if b.kind_of?(String)
|
511
|
+
res << b.inspect
|
512
|
+
text << b
|
513
|
+
elsif ['show', 'current_date'].include?(b.method)
|
514
|
+
res << expand_block(b, :trans=>true)
|
515
|
+
static = false
|
516
|
+
else
|
517
|
+
# ignore
|
518
|
+
end
|
519
|
+
end
|
520
|
+
unless static
|
521
|
+
text = res.join(' + ')
|
522
|
+
end
|
523
|
+
end
|
524
|
+
if static
|
525
|
+
_(text)
|
526
|
+
else
|
527
|
+
"<%= _(#{text}) %>"
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
alias r_t r_trans
|
532
|
+
|
533
|
+
def r_anchor(obj=node)
|
534
|
+
"<a name='#{anchor_name(@anchor_param, obj)}'></a>"
|
535
|
+
end
|
536
|
+
|
537
|
+
def anchor_name(p, obj=node)
|
538
|
+
if p =~ /\[(.+)\]/
|
539
|
+
"<%= #{node_attribute($1)} %>"
|
540
|
+
else
|
541
|
+
"#{base_class.to_s.underscore}#{erb_node_id(obj)}"
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
def r_content_for_layout
|
546
|
+
"<% if content_for_layout = yield -%><%= content_for_layout %><% else -%>" +
|
547
|
+
expand_with +
|
548
|
+
"<% end -%>"
|
549
|
+
end
|
550
|
+
|
551
|
+
def r_title_for_layout
|
552
|
+
"<% if @title_for_layout -%><%= @title_for_layout %><% elsif @node && !@node.new_record? -%><%= @node.rootpath %><% elsif @node.parent -%><%= @node.parent.rootpath %><% else -%>" +
|
553
|
+
expand_with +
|
554
|
+
"<% end -%>"
|
555
|
+
end
|
556
|
+
|
557
|
+
def r_check_lang
|
558
|
+
text = @params[:text] || expand_with
|
559
|
+
klass = @params[:class] || @html_tag_params[:class]
|
560
|
+
text = nil if text.blank?
|
561
|
+
klas = nil if klass.blank?
|
562
|
+
@html_tag_done = true
|
563
|
+
"#{@space_before}<%= check_lang(#{node},:text=>#{text.inspect},:class=>#{klass.inspect},:wrap=>#{@html_tag.inspect}) %>"
|
564
|
+
end
|
565
|
+
|
566
|
+
def r_title
|
567
|
+
if node_kind_of?(Version)
|
568
|
+
node = "#{self.node}.node"
|
569
|
+
elsif node_kind_of?(Node)
|
570
|
+
node = self.node
|
571
|
+
else
|
572
|
+
return parser_error('title','only works with nodes')
|
573
|
+
end
|
574
|
+
title_params = {}
|
575
|
+
|
576
|
+
title_params[:check_lang] = @params[:check_lang] if @params.include?(:check_lang)
|
577
|
+
|
578
|
+
if @params[:link]
|
579
|
+
value, static = parse_attributes_in_value(@params[:link], :erb => false)
|
580
|
+
link_param = ", :link=>\"#{value}\""
|
581
|
+
else
|
582
|
+
link_param = ''
|
583
|
+
end
|
584
|
+
|
585
|
+
res = "<%= show_title(:node=>#{node}#{link_param}#{params_to_erb(title_params)}"
|
586
|
+
if @params[:text]
|
587
|
+
res << ", :text=>#{@params[:text].inspect}"
|
588
|
+
elsif @params[:attr]
|
589
|
+
res << ", :text=>#{node_attribute(@params[:attr])}"
|
590
|
+
end
|
591
|
+
|
592
|
+
if @params.include?(:project)
|
593
|
+
res << ", :project=>#{@params[:project] == 'true'}"
|
594
|
+
end
|
595
|
+
res << ")"
|
596
|
+
if @params[:actions]
|
597
|
+
res << " + node_actions(:node=>#{node}#{params_to_erb(:actions=>@params[:actions], :publish_after_save=>auto_publish_param)})"
|
598
|
+
end
|
599
|
+
res << "%>"
|
600
|
+
if @params[:status] == 'true' || (@params[:status].nil? && @params[:actions])
|
601
|
+
@html_tag ||= 'span'
|
602
|
+
add_html_class("s<%= #{node}.version.status %>")
|
603
|
+
end
|
604
|
+
res
|
605
|
+
end
|
606
|
+
|
607
|
+
# TODO: test
|
608
|
+
def r_actions
|
609
|
+
out expand_with
|
610
|
+
out "<%= node_actions(:node=>#{node}#{params_to_erb(:actions=>@params[:select], :publish_after_save=>auto_publish_param)}) %>"
|
611
|
+
end
|
612
|
+
|
613
|
+
# TODO: test
|
614
|
+
def r_admin_links
|
615
|
+
"<%= show_link(:admin_links).join('</#{@html_tag}><#{@html_tag}>') %>"
|
616
|
+
end
|
617
|
+
|
618
|
+
def r_text
|
619
|
+
text = @params[:text] ? @params[:text].inspect : "#{node_attribute('v_text')}"
|
620
|
+
limit = @params[:limit] ? ", :limit=>#{@params[:limit].to_i}" : ""
|
621
|
+
|
622
|
+
@html_tag ||= 'div'
|
623
|
+
|
624
|
+
if @html_tag_params[:id]
|
625
|
+
# add a sub-div
|
626
|
+
pre = "<div id='v_text#{erb_node_id}'>"
|
627
|
+
post = "</div>"
|
628
|
+
else
|
629
|
+
pre = post = ''
|
630
|
+
@html_tag_params[:id] = "v_text#{erb_node_id}"
|
631
|
+
end
|
632
|
+
|
633
|
+
add_html_class('zazen')
|
634
|
+
|
635
|
+
unless @params[:empty] == 'true'
|
636
|
+
out "#{pre}<% if #{node}.kind_of?(TextDocument); l = #{node}.content_lang -%>"
|
637
|
+
out "<%= zazen(\"<code\#{l ? \" lang='\#{l}'\" : ''} class=\\'full\\'>\#{#{text}}</code>\") %>"
|
638
|
+
out "<% else -%>"
|
639
|
+
out "<%= zazen(#{text}#{limit}, :node=>#{node(Node)}) %>"
|
640
|
+
out "<% end -%>#{post}"
|
641
|
+
else
|
642
|
+
out "#{pre}#{post}"
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
def r_inspect
|
647
|
+
out ["params: #{@params.inspect}",
|
648
|
+
"name: #{@context[:name]}",
|
649
|
+
"node: #{node}",
|
650
|
+
"list: #{list}"].join("<br/>")
|
651
|
+
end
|
652
|
+
|
653
|
+
# TODO: replace with a more general 'zazen' or 'show' with id ?
|
654
|
+
def r_summary
|
655
|
+
limit = @params[:limit] ? ", :limit=>#{@params[:limit].to_i}" : ""
|
656
|
+
@html_tag ||= 'div'
|
657
|
+
if @html_tag_params[:id]
|
658
|
+
# add a sub-div
|
659
|
+
pre = "<div id='v_summary#{erb_node_id}'>"
|
660
|
+
post = "</div>"
|
661
|
+
else
|
662
|
+
pre = post = ''
|
663
|
+
@html_tag_params[:id] = "v_summary#{erb_node_id}"
|
664
|
+
end
|
665
|
+
|
666
|
+
add_html_class('zazen')
|
667
|
+
|
668
|
+
unless @params[:or]
|
669
|
+
text = @params[:text] ? @params[:text].inspect : node_attribute('v_summary')
|
670
|
+
out "#{pre}<%= zazen(#{text}#{limit}, :node=>#{node(Node)}) %>#{post}"
|
671
|
+
else
|
672
|
+
limit ||= ', :limit => 2'
|
673
|
+
first_name = 'v_summary'
|
674
|
+
first = node_attribute(first_name)
|
675
|
+
|
676
|
+
second_name = @params[:or].gsub(/[^a-z_]/,'') # FIXME: ist this still needed ? (ERB injection)
|
677
|
+
second = node_attribute(second_name)
|
678
|
+
out "#{pre}<% if #{first} != '' %>"
|
679
|
+
out "<%= zazen(#{first}, :node=>#{node(Node)}) %>"
|
680
|
+
out "<% else %>"
|
681
|
+
out "<%= zazen(#{second}#{limit}, :node=>#{node(Node)}) %>"
|
682
|
+
out "<% end %>#{post}"
|
683
|
+
end
|
684
|
+
end
|
685
|
+
|
686
|
+
def r_show_author
|
687
|
+
if @params[:size] == 'large'
|
688
|
+
out "#{_("posted by")} <b><%= #{node}.author.fullname %></b>"
|
689
|
+
out "<% if #{node}[:user_id] != #{node}.version[:user_id] -%>"
|
690
|
+
out "<% if #{node}[:ref_lang] != #{node}.version[:lang] -%>"
|
691
|
+
out "#{_("traduction by")} <b><%= #{node}.version.author.fullname %></b>"
|
692
|
+
out "<% else -%>"
|
693
|
+
out "#{_("modified by")} <b><%= #{node}.version.author.fullname %></b>"
|
694
|
+
out "<% end"
|
695
|
+
out " end -%>"
|
696
|
+
out " #{_("on")} <%= format_date(#{node}.version.updated_at, #{_('short_date').inspect}) %>."
|
697
|
+
if @params[:traductions] == 'true'
|
698
|
+
out " #{_("Traductions")} : <span class='traductions'><%= helper.traductions(:node=>#{node}).join(', ') %></span>"
|
699
|
+
end
|
700
|
+
else
|
701
|
+
out "<b><%= #{node}.version.author.initials %></b> - <%= format_date(#{node}.version.updated_at, #{_('short_date').inspect}) %>"
|
702
|
+
if @params[:traductions] == 'true'
|
703
|
+
out " <span class='traductions'>(<%= helper.traductions(:node=>#{node}).join(', ') %>)</span>"
|
704
|
+
end
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
def r_comments_to_publish
|
709
|
+
open_context("visitor.comments_to_publish", :node_class => [Comment])
|
710
|
+
end
|
711
|
+
|
712
|
+
def r_to_publish
|
713
|
+
open_context("visitor.to_publish", :node_class => [Version])
|
714
|
+
end
|
715
|
+
|
716
|
+
def r_proposed
|
717
|
+
open_context("visitor.proposed", :node_class => [Version])
|
718
|
+
end
|
719
|
+
|
720
|
+
def r_redactions
|
721
|
+
open_context("visitor.redactions", :node_class => [Version])
|
722
|
+
end
|
723
|
+
|
724
|
+
def r_edit
|
725
|
+
|
726
|
+
if @context[:dom_prefix]
|
727
|
+
# ajax
|
728
|
+
if @context[:in_form]
|
729
|
+
# cancel button
|
730
|
+
@context[:form_cancel] || ''
|
731
|
+
else
|
732
|
+
# edit button
|
733
|
+
|
734
|
+
# TODO: show 'reply' instead of 'edit' in comments if visitor != author
|
735
|
+
out link_to_update(self, :default_text => _('edit'), :url => "\#{edit_#{base_class.to_s.underscore}_path(#{node_id})}", :html_params => get_html_params(@params, :link), :method => :get, :cond => "#{node}.can_write?", :else => :void)
|
736
|
+
end
|
737
|
+
else
|
738
|
+
# FIXME: we could link to some html page to edit the item.
|
739
|
+
""
|
740
|
+
end
|
741
|
+
end
|
742
|
+
|
743
|
+
alias r_cancel r_edit
|
744
|
+
|
745
|
+
def r_textarea
|
746
|
+
out make_textarea(@html_tag_params.merge(@params))
|
747
|
+
@html_tag_done = true
|
748
|
+
end
|
749
|
+
|
750
|
+
|
751
|
+
# <r:select name='klass' root_class='...'/>
|
752
|
+
# <r:select name='parent_id' values='projects in site'/>
|
753
|
+
# TODO: optimization (avoid loading full AR to only use [id, name])
|
754
|
+
def r_select
|
755
|
+
html_attributes, attribute = get_input_params()
|
756
|
+
return parser_error("missing name") unless attribute
|
757
|
+
if value = @params[:selected]
|
758
|
+
# FIXME: DRY with html_attributes
|
759
|
+
value = value.gsub(/\[([^\]]+)\]/) do
|
760
|
+
node_attr = $1
|
761
|
+
res = node_attribute(node_attr)
|
762
|
+
"\#{#{res}}"
|
763
|
+
end
|
764
|
+
selected = value.inspect
|
765
|
+
elsif @context[:in_filter]
|
766
|
+
selected = "params[#{attribute.to_sym.inspect}].to_s"
|
767
|
+
else
|
768
|
+
selected = "#{node_attribute(attribute)}.to_s"
|
769
|
+
end
|
770
|
+
html_id = html_attributes[:id] ? " id='#{html_attributes[:id]}'" : ''
|
771
|
+
if @context[:in_filter]
|
772
|
+
select_tag = "<select#{html_id} name='#{attribute}'>"
|
773
|
+
else
|
774
|
+
select_tag = "<select#{html_id} name='#{base_class.to_s.underscore}[#{attribute}]'>"
|
775
|
+
end
|
776
|
+
|
777
|
+
if klass = @params[:root_class]
|
778
|
+
class_opts = {}
|
779
|
+
class_opts[:without] = @params[:without] if @params[:without]
|
780
|
+
# do not use 'selected' if the node is not new
|
781
|
+
"#{select_tag}<%= options_for_select(Node.classes_for_form(:class => #{klass.inspect}#{params_to_erb(class_opts)}), (#{node}.new_record? ? #{selected} : #{node}.klass)) %></select>"
|
782
|
+
elsif @params[:type] == 'time_zone'
|
783
|
+
# <r:select name='d_tz' type='time_zone'/>
|
784
|
+
"#{select_tag}<%= options_for_select(TZInfo::Timezone.all_identifiers, #{selected}) %></select>"
|
785
|
+
elsif options_list = get_options_for_select
|
786
|
+
"#{select_tag}<%= options_for_select(#{options_list}, #{selected}) %></select>"
|
787
|
+
else
|
788
|
+
parser_error("missing 'nodes', 'root_class' or 'values'")
|
789
|
+
end
|
790
|
+
end
|
791
|
+
|
792
|
+
|
793
|
+
def r_input
|
794
|
+
html_attributes, attribute = get_input_params()
|
795
|
+
case @params[:type]
|
796
|
+
when 'select' # FIXME: why is this only for classes ?
|
797
|
+
out parser_error("please use [select] here")
|
798
|
+
r_select
|
799
|
+
when 'date_box', 'date'
|
800
|
+
return parser_error("date_box without name") unless attribute
|
801
|
+
input_id = @context[:dom_prefix] ? ", :id=>\"#{dom_id}_#{attribute}\"" : ''
|
802
|
+
"<%= date_box '#{base_class.to_s.underscore}', #{attribute.inspect}, :size=>15#{@context[:in_add] ? ", :value=>''" : ''}#{input_id} %>"
|
803
|
+
when 'id'
|
804
|
+
return parser_error("select id without name") unless attribute
|
805
|
+
name = "#{attribute}_id" unless attribute[-3..-1] == '_id'
|
806
|
+
input_id = @context[:erb_dom_id] ? ", :input_id =>\"#{erb_dom_id}_#{attribute}\"" : ''
|
807
|
+
"<%= select_id('#{base_class.to_s.underscore}', #{attribute.inspect}#{input_id}) %>"
|
808
|
+
when 'time_zone'
|
809
|
+
out parser_error("please use [select] here")
|
810
|
+
r_select
|
811
|
+
when 'submit'
|
812
|
+
@html_tag = 'input'
|
813
|
+
@html_tag_params[:type] = @params[:type]
|
814
|
+
@html_tag_params[:text] = @params[:text] if @params[:text]
|
815
|
+
@html_tag_params.merge!(html_attributes)
|
816
|
+
render_html_tag(nil)
|
817
|
+
else
|
818
|
+
# 'text', 'hidden', ...
|
819
|
+
@html_tag = 'input'
|
820
|
+
@html_tag_params[:type] = @params[:type] || 'text'
|
821
|
+
if checked = html_attributes.delete(:checked)
|
822
|
+
@html_tag_params.merge!(html_attributes)
|
823
|
+
render_html_tag(nil, checked)
|
824
|
+
else
|
825
|
+
@html_tag_params.merge!(html_attributes)
|
826
|
+
render_html_tag(nil)
|
827
|
+
end
|
828
|
+
end
|
829
|
+
end
|
830
|
+
|
831
|
+
def r_form_tag
|
832
|
+
# replace <form> with constructed form
|
833
|
+
"#{@context[:form_tag]}#{expand_with(:form_tag => nil)}</form>"
|
834
|
+
end
|
835
|
+
|
836
|
+
# TODO: add parent_id into the form !
|
837
|
+
# TODO: add <div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div> if method == put
|
838
|
+
# FIXME: use <r:form href='self'> or <r:form action='...'>
|
839
|
+
def r_form
|
840
|
+
hidden_fields = {}
|
841
|
+
set_fields = []
|
842
|
+
id_hash = {:class => @html_tag_params[:class] || @params[:class] || 'form'}
|
843
|
+
var_name = base_class.to_s.underscore
|
844
|
+
(descendants('input') + descendants('select')).each do |tag|
|
845
|
+
set_fields << "#{var_name}[#{tag.params[:name]}]"
|
846
|
+
end
|
847
|
+
|
848
|
+
if @context[:dom_prefix] || @params[:update]
|
849
|
+
# ajax
|
850
|
+
if @context[:in_add]
|
851
|
+
# inline form used to create new elements: set values to '' and 'parent_id' from context
|
852
|
+
id_hash[:id] = "#{erb_dom_id}_form"
|
853
|
+
id_hash[:style] = "display:none;"
|
854
|
+
|
855
|
+
cancel = "<p class='btn_x'><a href='#' onclick='[\"#{erb_dom_id}_add\", \"#{erb_dom_id}_form\"].each(Element.toggle);return false;'>#{_('btn_x')}</a></p>\n"
|
856
|
+
form = "<%= form_remote_tag(:url => #{base_class.to_s.underscore.pluralize}_path, :html => {:id => \"#{dom_id}_form_t\"}) %>\n"
|
857
|
+
else
|
858
|
+
# saved form
|
859
|
+
|
860
|
+
id_hash[:id] = erb_dom_id
|
861
|
+
|
862
|
+
cancel = !@context[:dom_prefix] ? "" : <<-END_TXT
|
863
|
+
<% if #{node}.new_record? -%>
|
864
|
+
<p class='btn_x'><a href='#' onclick='[\"<%= params[:dom_id] %>_add\", \"<%= params[:dom_id] %>_form\"].each(Element.toggle);return false;'>#{_('btn_x')}</a></p>
|
865
|
+
<% else -%>
|
866
|
+
<p class='btn_x'><%= link_to_remote(#{_('btn_x').inspect}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=\#{params[:dom_id]}#{@context[:need_link_id] ? "&link_id=\#{#{node}.link_id}" : ''}\", :method => :get) %></p>
|
867
|
+
<% end -%>
|
868
|
+
END_TXT
|
869
|
+
form =<<-END_TXT
|
870
|
+
<% if #{node}.new_record? -%>
|
871
|
+
<%= form_remote_tag(:url => #{base_class.to_s.underscore.pluralize}_path, :html => {:id => \"\#{params[:dom_id]}_form_t\"}) %>
|
872
|
+
<% else -%>
|
873
|
+
<%= form_remote_tag(:url => #{base_class.to_s.underscore}_path(#{node_id}), :method => :put, :html => {:id => \"#{dom_id}_form_t\"}) %>
|
874
|
+
<% end -%>
|
875
|
+
END_TXT
|
876
|
+
end
|
877
|
+
|
878
|
+
if (descendants('input') || []).select{|elem| elem.params[:type] == 'submit'} != []
|
879
|
+
# has submit
|
880
|
+
else
|
881
|
+
hidden_submit = "<input type='submit'/>" # hidden submit for Firefox compatibility
|
882
|
+
end
|
883
|
+
|
884
|
+
hidden_fields['link_id'] = "<%= #{node}.link_id %>" if @context[:need_link_id]
|
885
|
+
|
886
|
+
if @params[:update] || (@context[:add] && @context[:add].params[:update])
|
887
|
+
upd = @params[:update] || @context[:add].params[:update]
|
888
|
+
if target = find_target(upd)
|
889
|
+
hidden_fields['u_url'] = target.template_url
|
890
|
+
hidden_fields['udom_id'] = target.erb_dom_id
|
891
|
+
hidden_fields['u_id'] = "<%= #{@context[:parent_node]}.zip %>" if @context[:in_add]
|
892
|
+
hidden_fields['s'] = start_node_s_param(:value)
|
893
|
+
end
|
894
|
+
elsif (block = ancestor('block')) && node_kind_of?(DataEntry)
|
895
|
+
# updates template url
|
896
|
+
hidden_fields['u_url'] = block.template_url
|
897
|
+
hidden_fields['udom_id'] = block.erb_dom_id
|
898
|
+
end
|
899
|
+
|
900
|
+
hidden_fields['t_url'] = template_url
|
901
|
+
if t_id = @params[:t_id]
|
902
|
+
hidden_fields['t_id'] = parse_attributes_in_value(t_id)
|
903
|
+
end
|
904
|
+
|
905
|
+
erb_dom_id = @context[:saved_template] ? '<%= params[:dom_id] %>' : self.erb_dom_id
|
906
|
+
|
907
|
+
hidden_fields['dom_id'] = erb_dom_id
|
908
|
+
|
909
|
+
if node_kind_of?(Node)
|
910
|
+
hidden_fields['node[parent_id]'] = "<%= #{@context[:in_add] ? "#{@context[:parent_node]}.zip" : "#{node}.parent_zip"} %>"
|
911
|
+
elsif node_kind_of?(Comment)
|
912
|
+
# FIXME: the "... || '@node'" is a hack and I don't understand why it's needed...
|
913
|
+
hidden_fields['node_id'] = "<%= #{@context[:parent_node] || '@node'}.zip %>"
|
914
|
+
elsif node_kind_of?(DataEntry)
|
915
|
+
hidden_fields["data_entry[#{@context[:data_root]}_id]"] = "<%= #{@context[:in_add] ? @context[:parent_node] : "#{node}.#{@context[:data_root]}"}.zip %>"
|
916
|
+
end
|
917
|
+
|
918
|
+
if add_block = @context[:add]
|
919
|
+
params = add_block.params
|
920
|
+
[:after, :before, :top, :bottom].each do |sym|
|
921
|
+
if params[sym]
|
922
|
+
hidden_fields['position'] = sym.to_s
|
923
|
+
if params[sym] == 'self'
|
924
|
+
if sym == :before
|
925
|
+
hidden_fields['reference'] = "#{erb_dom_id}_add"
|
926
|
+
else
|
927
|
+
hidden_fields['reference'] = "#{erb_dom_id}_form"
|
928
|
+
end
|
929
|
+
else
|
930
|
+
hidden_fields['reference'] = params[sym]
|
931
|
+
end
|
932
|
+
break
|
933
|
+
end
|
934
|
+
end
|
935
|
+
if params[:done] == 'focus'
|
936
|
+
if params[:focus]
|
937
|
+
hidden_fields['done'] = "'$(\"#{erb_dom_id}_#{@params[:focus]}\").focus();'"
|
938
|
+
else
|
939
|
+
hidden_fields['done'] = "'$(\"#{erb_dom_id}_form_t\").focusFirstElement();'"
|
940
|
+
end
|
941
|
+
elsif params[:done]
|
942
|
+
hidden_fields['done'] = CGI.escape(params[:done]) # .gsub("NODE_ID", @node.zip).gsub("PARENT_ID", @node.parent_zip)
|
943
|
+
end
|
944
|
+
else
|
945
|
+
# ajax form, not in 'add'
|
946
|
+
hidden_fields['done'] = CGI.escape(@params[:done]) if @params[:done]
|
947
|
+
end
|
948
|
+
else
|
949
|
+
# no ajax
|
950
|
+
# FIXME
|
951
|
+
cancel = "" # link to normal node ?
|
952
|
+
form = "<form method='post' action='/nodes/#{erb_node_id}'><div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div>"
|
953
|
+
end
|
954
|
+
|
955
|
+
if node_kind_of?(Node) && (@params[:klass] || @context[:klass])
|
956
|
+
hidden_fields['node[klass]'] = @params[:klass] || @context[:klass]
|
957
|
+
end
|
958
|
+
|
959
|
+
if node_kind_of?(Node) && @params[:mode]
|
960
|
+
hidden_fields['mode'] = @params[:mode]
|
961
|
+
end
|
962
|
+
|
963
|
+
hidden_fields['node[v_status]'] = Zena::Status[:pub] if @context[:publish_after_save] || auto_publish_param
|
964
|
+
|
965
|
+
form << "<div class='hidden'>"
|
966
|
+
hidden_fields.each do |k,v|
|
967
|
+
next if set_fields.include?(k)
|
968
|
+
v = "'#{v}'" unless v.kind_of?(String) && ['"', "'"].include?(v[0..0])
|
969
|
+
form << "<input type='hidden' name='#{k}' value=#{v}/>\n"
|
970
|
+
end
|
971
|
+
form << hidden_submit << "\n" if hidden_submit
|
972
|
+
form << "</div>"
|
973
|
+
|
974
|
+
form << "<%= error_messages_for(#{node}) %>"
|
975
|
+
|
976
|
+
if !descendant('cancel') && !descendant('edit')
|
977
|
+
if !descendant('form_tag')
|
978
|
+
# add a descendant before blocks.
|
979
|
+
blocks_bak = @blocks
|
980
|
+
@blocks = @blocks.dup
|
981
|
+
@blocks = [make(:void, :method=>'void', :text=>cancel)] + blocks_bak
|
982
|
+
else
|
983
|
+
form = cancel + form
|
984
|
+
cancel = ''
|
985
|
+
end
|
986
|
+
end
|
987
|
+
|
988
|
+
if descendant('form_tag')
|
989
|
+
res = expand_with(:form_tag => form, :in_form => true, :form_cancel => cancel, :erb_dom_id => erb_dom_id, :dom_id => dom_id)
|
990
|
+
else
|
991
|
+
res = form + expand_with(:in_form => true, :form_cancel => cancel, :erb_dom_id => erb_dom_id, :dom_id => dom_id) + '</form>'
|
992
|
+
end
|
993
|
+
|
994
|
+
@blocks = blocks_bak if blocks_bak
|
995
|
+
|
996
|
+
@html_tag_done = false
|
997
|
+
@html_tag_params.merge!(id_hash)
|
998
|
+
out render_html_tag(res)
|
999
|
+
end
|
1000
|
+
|
1001
|
+
# <r:checkbox role='collaborator_for' values='projects' in='site'/>"
|
1002
|
+
# TODO: implement checkbox in the same spirit as 'r_select'
|
1003
|
+
def r_checkbox
|
1004
|
+
return parser_error("missing 'nodes'") unless values = @params[:values] || @params[:nodes]
|
1005
|
+
return parser_error("missing 'role'") unless role = (@params[:role] || @params[:name])
|
1006
|
+
attribute = @params[:attr] || 'name'
|
1007
|
+
if role =~ /(.*)_ids?\Z/
|
1008
|
+
role = $1
|
1009
|
+
end
|
1010
|
+
meth = role.singularize
|
1011
|
+
|
1012
|
+
if values =~ /^\d+\s*($|,)/
|
1013
|
+
# ids
|
1014
|
+
# TODO generate the full query instead of using secure.
|
1015
|
+
values = values.split(',').map{|v| v.to_i}
|
1016
|
+
list_finder = "(secure(Node) { Node.find(:all, :conditions => 'zip IN (#{values.join(',')})') })"
|
1017
|
+
else
|
1018
|
+
# relation
|
1019
|
+
list_finder, klass = build_finder_for(:all, values)
|
1020
|
+
return unless list_finder
|
1021
|
+
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
1022
|
+
end
|
1023
|
+
out "<% if (#{list_var} = #{list_finder}) && (#{list_var}_relation = #{node}.relation_proxy(#{role.inspect})) -%>"
|
1024
|
+
out "<% if #{list_var}_relation.unique? -%>"
|
1025
|
+
|
1026
|
+
out "<% #{list_var}_id = #{list_var}_relation.other_id -%>"
|
1027
|
+
out "<div class='input_radio'><% #{list_var}.each do |#{var}| -%>"
|
1028
|
+
out "<span><input type='radio' name='node[#{meth}_id]' value='#{erb_node_id(var)}'<%= #{list_var}_id == #{var}[:id] ? \" checked='checked'\" : '' %>/> <%= #{node_attribute(attribute, :node=>var)} %></span> "
|
1029
|
+
out "<% end -%></div>"
|
1030
|
+
out "<input type='radio' name='node[#{meth}_id]' value=''/> #{_('none')}"
|
1031
|
+
|
1032
|
+
out "<% else -%>"
|
1033
|
+
|
1034
|
+
out "<% #{list_var}_ids = #{list_var}_relation.other_ids -%>"
|
1035
|
+
out "<div class='input_checkbox'><% #{list_var}.each do |#{var}| -%>"
|
1036
|
+
out "<span><input type='checkbox' name='node[#{meth}_ids][]' value='#{erb_node_id(var)}'<%= #{list_var}_ids.include?(#{var}[:id]) ? \" checked='checked'\" : '' %>/> <%= #{node_attribute(attribute, :node=>var)} %></span> "
|
1037
|
+
out "<% end -%></div>"
|
1038
|
+
out "<input type='hidden' name='node[#{meth}_ids][]' value=''/>"
|
1039
|
+
|
1040
|
+
out "<% end -%><% end -%>"
|
1041
|
+
end
|
1042
|
+
|
1043
|
+
alias r_radio r_checkbox
|
1044
|
+
|
1045
|
+
# TODO: test
|
1046
|
+
def r_add
|
1047
|
+
return parser_error("should not be called from within 'each'") if parent.method == 'each'
|
1048
|
+
return '' if @context[:make_form]
|
1049
|
+
|
1050
|
+
# why is node = @node (which we need) but we are supposed to have Comments ?
|
1051
|
+
# FIXME: during rewrite, replace 'node' by 'node(klass = node_class)' so the ugly lines below would be
|
1052
|
+
# if node_kind_of?(Comment)
|
1053
|
+
# out "<% if #{node(Node)}.can_comment? -%>"
|
1054
|
+
# Refs #198.
|
1055
|
+
if node_kind_of?(Comment)
|
1056
|
+
out "<% if #{node}.can_comment? -%>"
|
1057
|
+
else
|
1058
|
+
out "<% if #{node}.can_write? -%>"
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
unless descendant('add_btn')
|
1062
|
+
# add a descendant between self and blocks.
|
1063
|
+
blocks = @blocks.dup
|
1064
|
+
@blocks = []
|
1065
|
+
add_btn = make(:void, :method=>'add_btn', :params=>@params.dup, :text=>'')
|
1066
|
+
add_btn.blocks = blocks
|
1067
|
+
remove_instance_variable(:@all_descendants)
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
if @context[:form] && @context[:dom_prefix]
|
1071
|
+
# ajax add
|
1072
|
+
|
1073
|
+
@html_tag_params.merge!(:id => "#{erb_dom_id}_add")
|
1074
|
+
@html_tag_params[:class] ||= 'btn_add'
|
1075
|
+
if @params[:focus]
|
1076
|
+
focus = "$(\"#{erb_dom_id}_#{@params[:focus]}\").focus();"
|
1077
|
+
else
|
1078
|
+
focus = "$(\"#{erb_dom_id}_form_t\").focusFirstElement();"
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
out render_html_tag("#{expand_with(:onclick=>"[\"#{erb_dom_id}_add\", \"#{erb_dom_id}_form\"].each(Element.toggle);#{focus}return false;")}")
|
1082
|
+
|
1083
|
+
if node_kind_of?(Node)
|
1084
|
+
# FIXME: BUG if we set <r:form klass='Post'/> the user cannot select class with menu...
|
1085
|
+
klass = @context[:klass] || 'Node'
|
1086
|
+
# FIXME: inspect '@context[:form]' to see if it contains v_klass ?
|
1087
|
+
out "<% if #{var}_new = secure(Node) { Node.new_from_class(#{klass.inspect}) } -%>"
|
1088
|
+
else
|
1089
|
+
out "<% if #{var}_new = #{node_class}.new -%>"
|
1090
|
+
end
|
1091
|
+
|
1092
|
+
if @context[:form].method == 'form'
|
1093
|
+
out expand_block(@context[:form], :in_add => true, :no_ignore => ['form'], :add=>self, :node => "#{var}_new", :parent_node => node, :klass => klass, :publish_after_save => auto_publish_param)
|
1094
|
+
else
|
1095
|
+
# build form from 'each'
|
1096
|
+
out expand_block(@context[:form], :in_add => true, :no_ignore => ['form'], :add=>self, :make_form => true, :node => "#{var}_new", :parent_node => node, :klass => klass, :publish_after_save => auto_publish_param)
|
1097
|
+
end
|
1098
|
+
out "<% end -%>"
|
1099
|
+
else
|
1100
|
+
# no ajax
|
1101
|
+
@html_tag_params[:class] ||= 'btn_add' if @html_tag
|
1102
|
+
out render_html_tag(expand_with)
|
1103
|
+
end
|
1104
|
+
out "<% end -%>"
|
1105
|
+
@html_tag_done = true
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
def r_add_btn
|
1109
|
+
if @params[:text]
|
1110
|
+
text = @params[:text]
|
1111
|
+
text = "<div>#{text}</div>" unless @html_tag
|
1112
|
+
elsif @params[:trans]
|
1113
|
+
text = _(@params[:trans])
|
1114
|
+
text = "<div>#{text}</div>" unless @html_tag
|
1115
|
+
elsif @blocks != []
|
1116
|
+
text = expand_with
|
1117
|
+
else
|
1118
|
+
text = node_class == Comment ? _("btn_add_comment") : _("btn_add")
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
out "<a href='#' onclick='#{@context[:onclick]}'>#{text}</a>"
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
# Show html to add open a popup window to add a document.
|
1125
|
+
# TODO: inline ajax for upload ?
|
1126
|
+
def r_add_document
|
1127
|
+
return parser_error("only works with nodes (not with #{node_class})") unless node_kind_of?(Node)
|
1128
|
+
@html_tag_params[:class] ||= 'btn_add'
|
1129
|
+
res = "<a href='/documents/new?parent_id=#{erb_node_id}' onclick='uploader=window.open(\"/documents/new?parent_id=#{erb_node_id}\", \"upload\", \"width=400,height=300\");return false;'>#{_('btn_add_doc')}</a>"
|
1130
|
+
"<% if #{node}.can_write? -%>#{render_html_tag(res)}<% end -%>"
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
#if RAILS_ENV == 'test'
|
1134
|
+
# def r_test
|
1135
|
+
# inspect
|
1136
|
+
# end
|
1137
|
+
#end
|
1138
|
+
|
1139
|
+
def r_drop
|
1140
|
+
if parent.method == 'each' && @method == parent.single_child_method
|
1141
|
+
parent.add_html_class('drop')
|
1142
|
+
else
|
1143
|
+
@html_tag_params[:class] ||= 'drop'
|
1144
|
+
end
|
1145
|
+
r_block
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
def drop_javascript
|
1149
|
+
hover = @params[:hover]
|
1150
|
+
change = @params[:change]
|
1151
|
+
|
1152
|
+
if role = @params[:set] || @params[:add]
|
1153
|
+
query_params = ["node[#{role}_id]=[id]"]
|
1154
|
+
else
|
1155
|
+
query_params = []
|
1156
|
+
# set='icon_for=[id], v_status='50', v_title='[v_title]'
|
1157
|
+
@params.each do |k, v|
|
1158
|
+
next if [:hover, :change, :done].include?(k)
|
1159
|
+
value, static = parse_attributes_in_value(v, :erb => false, :skip_node_attributes => true)
|
1160
|
+
key = change == 'params' ? "params[#{k}]" : "node[#{k}]"
|
1161
|
+
query_params << "#{key}=#{CGI.escape(value)}"
|
1162
|
+
end
|
1163
|
+
return parser_error("missing parameters to set values") if query_params == []
|
1164
|
+
end
|
1165
|
+
|
1166
|
+
query_params << "change=#{change}" if change == 'receiver'
|
1167
|
+
query_params << "t_url=#{CGI.escape(template_url)}"
|
1168
|
+
query_params << "dom_id=#{erb_dom_id}"
|
1169
|
+
query_params << start_node_s_param(:erb)
|
1170
|
+
query_params << "done=#{CGI.escape(@params[:done])}" if @params[:done]
|
1171
|
+
|
1172
|
+
"<script type='text/javascript'>
|
1173
|
+
//<![CDATA[
|
1174
|
+
Droppables.add('#{erb_dom_id}', {hoverclass:'#{hover || 'drop_hover'}', onDrop:function(element){new Ajax.Request('/nodes/#{erb_node_id}/drop?#{query_params.join('&')}', {asynchronous:true, evalScripts:true, method:'put', parameters:'drop=' + encodeURIComponent(element.id)})}})
|
1175
|
+
//]]>
|
1176
|
+
</script>"
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
def r_draggable
|
1180
|
+
new_dom_scope
|
1181
|
+
@html_tag ||= 'div'
|
1182
|
+
case @params[:revert]
|
1183
|
+
when 'move'
|
1184
|
+
revert_effect = 'Element.move'
|
1185
|
+
when 'remove'
|
1186
|
+
revert_effect = 'Element.remove'
|
1187
|
+
else
|
1188
|
+
revert_effect = 'Element.move'
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
res, drag_handle = set_drag_handle_and_id(expand_with, @params, :id => erb_dom_id)
|
1192
|
+
|
1193
|
+
out render_html_tag(res)
|
1194
|
+
|
1195
|
+
if drag_handle
|
1196
|
+
out "<script type='text/javascript'>\n//<![CDATA[\n
|
1197
|
+
new Draggable('#{erb_dom_id}', {ghosting:true, revert:true, revertEffect:#{revert_effect}, handle:$('#{erb_dom_id}').select('.#{drag_handle}')[0]});\n//]]>\n</script>"
|
1198
|
+
else
|
1199
|
+
out "<script type='text/javascript'>\n//<![CDATA[\nZena.draggable('#{erb_dom_id}',0,true,true,#{revert_effect})\n//]]>\n</script>"
|
1200
|
+
end
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
def r_unlink
|
1204
|
+
return "" if @context[:make_form]
|
1205
|
+
opts = {}
|
1206
|
+
|
1207
|
+
if upd = @params[:update]
|
1208
|
+
if upd == '_page'
|
1209
|
+
target = nil
|
1210
|
+
elsif target = find_target(upd)
|
1211
|
+
# ok
|
1212
|
+
else
|
1213
|
+
return
|
1214
|
+
end
|
1215
|
+
elsif target = ancestor('block')
|
1216
|
+
# ok
|
1217
|
+
else
|
1218
|
+
target = self
|
1219
|
+
end
|
1220
|
+
|
1221
|
+
if node_kind_of?(Node)
|
1222
|
+
opts[:cond] = "#{node}.can_write? && #{node}.link_id"
|
1223
|
+
opts[:url] = "/nodes/\#{#{node_id}}/links/\#{#{node}.link_id}"
|
1224
|
+
elsif node_kind_of?(Link)
|
1225
|
+
opts[:url] = "/nodes/\#{#{node}.this_zip}/links/\#{#{node}.zip}"
|
1226
|
+
end
|
1227
|
+
|
1228
|
+
opts[:method] = :delete
|
1229
|
+
opts[:default_text] = _('btn_tiny_del')
|
1230
|
+
opts[:html_params] = get_html_params({:class => 'unlink'}.merge(@params), :link)
|
1231
|
+
|
1232
|
+
out link_to_update(target, opts)
|
1233
|
+
|
1234
|
+
#tag_to_remote
|
1235
|
+
#"<%= tag_to_remote({:url => node_path(#{node_id}) + \"#{opts[:method] != :put ? '/zafu' : ''}?#{action.join('&')}\", :method => #{opts[:method].inspect}}) %>"
|
1236
|
+
# out "<a class='#{@params[:class] || 'unlink'}' href='/nodes/#{erb_node_id}/links/<%= #{node}.link_id %>?#{action}' onclick=\"new Ajax.Request('/nodes/#{erb_node_id}/links/<%= #{node}.link_id %>?#{action}', {asynchronous:true, evalScripts:true, method:'delete'}); return false;\">"
|
1237
|
+
# if !@blocks.empty?
|
1238
|
+
# inner = expand_with
|
1239
|
+
# else
|
1240
|
+
# inner = _('btn_tiny_del')
|
1241
|
+
# end
|
1242
|
+
# out "#{inner}</a><% else -%>#{inner}<% end -%>"
|
1243
|
+
#elsif node_kind_of?(DataEntry)
|
1244
|
+
# text = get_text_for_erb
|
1245
|
+
# if text.blank?
|
1246
|
+
# text = _('btn_tiny_del')
|
1247
|
+
# end
|
1248
|
+
# out "<%= link_to_remote(#{text.inspect}, {:url => \"/data_entries/\#{#{node}[:id]}?dom_id=#{dom_id}#{upd_url}\", :method => :delete}, :class=>#{(@params[:class] || 'unlink').inspect}) %>"
|
1249
|
+
#end
|
1250
|
+
end
|
1251
|
+
|
1252
|
+
# Group elements in a list. Use :order to specify order.
|
1253
|
+
def r_group
|
1254
|
+
return parser_error("cannot be used outside of a list") unless list_var = @context[:list]
|
1255
|
+
return parser_error("missing 'by' clause") unless key = @params[:by]
|
1256
|
+
|
1257
|
+
sort_key = @params[:sort] || 'name'
|
1258
|
+
if node_kind_of?(DataEntry) && DataEntry::NodeLinkSymbols.include?(key.to_sym)
|
1259
|
+
key = "#{key}_id"
|
1260
|
+
sort_block = "{|e| (e.#{key} || {})[#{sort_key.to_sym.inspect}]}"
|
1261
|
+
group_array = "group_array(#{list_var}) {|e| e.#{key}}"
|
1262
|
+
elsif node_kind_of?(Node)
|
1263
|
+
if ['project', 'parent', 'section'].include?(key)
|
1264
|
+
sort_block = "{|e| (e.#{key} || {})[#{sort_key.to_sym.inspect}]}"
|
1265
|
+
group_array = "group_array(#{list_var}) {|e| e.#{key}_id}"
|
1266
|
+
end
|
1267
|
+
end
|
1268
|
+
|
1269
|
+
group_array ||= "group_array(#{list_var}) {|e| #{node_attribute(key, :node => 'e')}}"
|
1270
|
+
|
1271
|
+
if sort_block
|
1272
|
+
out "<% grp_#{list_var} = sort_array(#{group_array}) #{sort_block} -%>"
|
1273
|
+
else
|
1274
|
+
out "<% grp_#{list_var} = #{group_array} -%>"
|
1275
|
+
end
|
1276
|
+
|
1277
|
+
if descendant('each_group')
|
1278
|
+
out expand_with(:group => "grp_#{list_var}")
|
1279
|
+
else
|
1280
|
+
@context[:group] = "grp_#{list_var}"
|
1281
|
+
r_each_group
|
1282
|
+
end
|
1283
|
+
end
|
1284
|
+
|
1285
|
+
|
1286
|
+
# Compute statistics on elements in the current list context.
|
1287
|
+
def r_stat
|
1288
|
+
return parser_error("must be used inside a list context") unless list
|
1289
|
+
find = @params[:find] || @params[:date] || 'count'
|
1290
|
+
key = @params[:of] || @params[:from] || 'value'
|
1291
|
+
case find
|
1292
|
+
when 'sum'
|
1293
|
+
value = "#{list}.flatten.inject(0) {|#{var}_sum,#{var}| #{var}_sum + #{node_attribute(key, :node => var)}.to_f}"
|
1294
|
+
when 'min'
|
1295
|
+
value = "#{node_attribute(key, :node => "min_array(#{list}) {|e| #{node_attribute(key, :node => 'e')}}")}"
|
1296
|
+
when 'max'
|
1297
|
+
value = "#{node_attribute(key, :node => "max_array(#{list}) {|e| #{node_attribute(key, :node => 'e')}}")}"
|
1298
|
+
when 'count'
|
1299
|
+
return "<%= #{list}.size %>"
|
1300
|
+
end
|
1301
|
+
if @params[:date]
|
1302
|
+
# FIXME: DRY (r_show)
|
1303
|
+
if @params[:tformat]
|
1304
|
+
format = _(@params[:tformat])
|
1305
|
+
elsif @params[:format]
|
1306
|
+
format = @params[:format]
|
1307
|
+
else
|
1308
|
+
format = "%Y-%m-%d"
|
1309
|
+
end
|
1310
|
+
"<%= #{list}==[] ? '' : format_date(#{value}, #{format.inspect}) %>"
|
1311
|
+
elsif format = @params[:format]
|
1312
|
+
|
1313
|
+
if @params[:zero] == 'hide'
|
1314
|
+
"<%= #{list}==[] ? '' : sprintf_unless_zero(#{@params[:format].inspect}, #{value}) %>"
|
1315
|
+
else
|
1316
|
+
"<%= #{list}==[] ? '' : sprintf(#{@params[:format].inspect}, #{value}) %>"
|
1317
|
+
end
|
1318
|
+
else
|
1319
|
+
"<%= #{list}==[] ? '' : #{value} %>"
|
1320
|
+
end
|
1321
|
+
end
|
1322
|
+
|
1323
|
+
def r_each_group
|
1324
|
+
return parser_error("must be used inside a group context") unless group = @context[:group]
|
1325
|
+
if join = @params[:join]
|
1326
|
+
join = join.gsub(/<([^%])/, '<\1').gsub(/([^%])>/, '\1>')
|
1327
|
+
out "<% #{group}.each_index do |#{list_var}_index| -%>"
|
1328
|
+
out "<%= #{list_var}=#{group}[#{list_var}_index]; #{var} = #{list_var}[0]; #{list_var}_index > 0 ? #{join.inspect} : '' %>"
|
1329
|
+
else
|
1330
|
+
out "<% #{group}.each do |#{list_var}|; #{var} = #{list_var}[0]; -%>"
|
1331
|
+
end
|
1332
|
+
out render_html_tag(expand_with(:group => nil, :list => list_var, :node => var, :scope_node => var))
|
1333
|
+
out "<% end -%>"
|
1334
|
+
end
|
1335
|
+
|
1336
|
+
def r_each
|
1337
|
+
is_draggable = @params[:draggable] == 'true' || @params[:drag_handle]
|
1338
|
+
|
1339
|
+
if descendant('edit') || descendant('unlink') || descendant('swap') || ['block', 'drop'].include?(single_child_method) || is_draggable
|
1340
|
+
id_hash = {:id => erb_dom_id}
|
1341
|
+
else
|
1342
|
+
id_hash = nil
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
|
1346
|
+
if @context[:make_form]
|
1347
|
+
# use the elements inside 'each' loop to produce the edit form
|
1348
|
+
r_form
|
1349
|
+
elsif @context[:list]
|
1350
|
+
# normal rendering: not the start of a saved template
|
1351
|
+
if is_draggable || descendant('unlink')
|
1352
|
+
out "<% #{var}_dom_ids = [] -%>"
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
@params[:alt_class] ||= @html_tag_params.delete(:alt_class)
|
1356
|
+
# FIXME: add alt_reverse='true' to start counting from bottom (if order last on top...)
|
1357
|
+
if @params[:alt_class] || @params[:join]
|
1358
|
+
join = @params[:join] || ''
|
1359
|
+
join = join.gsub(/<([^%])/, '<\1').gsub(/([^%])>/, '\1>')
|
1360
|
+
out "<% #{var}_max_index = #{list}.size - 1 -%>" if @params[:alt_reverse]
|
1361
|
+
out "<% #{list}.each_with_index do |#{var},#{var}_index| -%>"
|
1362
|
+
|
1363
|
+
if join_clause = @params[:join_if]
|
1364
|
+
set_stored(Node, 'prev', "#{var}_prev")
|
1365
|
+
cond = get_test_condition(var, :test=>join_clause)
|
1366
|
+
out "<%= #{var}_prev = #{list}[#{var}_index - 1]; (#{var}_index > 0 && #{cond}) ? #{join.inspect} : '' %>"
|
1367
|
+
else
|
1368
|
+
out "<%= #{var}_index > 0 ? #{join.inspect} : '' %>"
|
1369
|
+
end
|
1370
|
+
|
1371
|
+
if alt_class = @params[:alt_class]
|
1372
|
+
alt_test = @params[:alt_reverse] == 'true' ? "(#{var}_max_index - #{var}_index) % 2 != 0" : "#{var}_index % 2 != 0"
|
1373
|
+
if html_class = @html_tag_params.delete(:class)
|
1374
|
+
html_append = " class='#{html_class}<%= #{alt_test} ? #{(' ' + alt_class).inspect} : '' %>'"
|
1375
|
+
else
|
1376
|
+
html_append = "<%= #{alt_test} ? ' class=#{alt_class.inspect}' : '' %>"
|
1377
|
+
end
|
1378
|
+
else
|
1379
|
+
html_append = nil
|
1380
|
+
end
|
1381
|
+
else
|
1382
|
+
out "<% #{list}.each do |#{var}| -%>"
|
1383
|
+
html_append = nil
|
1384
|
+
end
|
1385
|
+
|
1386
|
+
if is_draggable
|
1387
|
+
out "<% #{var}_dom_ids << \"#{dom_id}\" -%>"
|
1388
|
+
end
|
1389
|
+
|
1390
|
+
out r_anchor(var) if @anchor_param # insert anchor inside the each loop
|
1391
|
+
@params[:anchor] = @anchor_param # set back in case we double render
|
1392
|
+
@anchor_param = nil
|
1393
|
+
|
1394
|
+
res, drag_handle = set_drag_handle_and_id(expand_with(:node => var, :scope_node => var), @params, id_hash)
|
1395
|
+
|
1396
|
+
out render_html_tag(res, html_append)
|
1397
|
+
|
1398
|
+
out "<% end -%>"
|
1399
|
+
|
1400
|
+
if is_draggable
|
1401
|
+
if drag_handle
|
1402
|
+
out "<script type='text/javascript'>\n//<![CDATA[\n<%= #{var}_dom_ids.inspect %>.each(function(dom_id, index) {
|
1403
|
+
new Draggable(dom_id, {ghosting:true, revert:true, handle:$(dom_id).select('.#{drag_handle}')[0]});
|
1404
|
+
});\n//]]>\n</script>"
|
1405
|
+
else
|
1406
|
+
out "<script type='text/javascript'>\n//<![CDATA[\n<%= #{var}_dom_ids.inspect %>.each(Zena.draggable)\n//]]>\n</script>"
|
1407
|
+
end
|
1408
|
+
end
|
1409
|
+
|
1410
|
+
elsif @context[:saved_template]
|
1411
|
+
# render to start a saved template
|
1412
|
+
res, drag_handle = set_drag_handle_and_id(expand_with(:scope_node => node), @params, id_hash)
|
1413
|
+
|
1414
|
+
out render_html_tag(res)
|
1415
|
+
|
1416
|
+
if is_draggable
|
1417
|
+
if drag_handle
|
1418
|
+
out "<script type='text/javascript'>\n//<![CDATA[\nnew Draggable('#{erb_dom_id}', {ghosting:true, revert:true, handle:$('#{erb_dom_id}').select('.#{drag_handle}')[0]});\n//]]>\n</script>"
|
1419
|
+
else
|
1420
|
+
out "<script type='text/javascript'>\n//<![CDATA[\nZena.draggable('#{erb_dom_id}')\n//]]>\n</script>"
|
1421
|
+
end
|
1422
|
+
end
|
1423
|
+
else
|
1424
|
+
# TODO: make a single list ?
|
1425
|
+
@context[:list] = "[#{node}]"
|
1426
|
+
r_each
|
1427
|
+
end
|
1428
|
+
end
|
1429
|
+
|
1430
|
+
def r_case
|
1431
|
+
out "<% if false -%>"
|
1432
|
+
out expand_with(:in_if=>true, :only=>['when', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
1433
|
+
@html_tag_done = true
|
1434
|
+
out "<% end -%>"
|
1435
|
+
end
|
1436
|
+
|
1437
|
+
# TODO: test
|
1438
|
+
def r_if
|
1439
|
+
cond = get_test_condition
|
1440
|
+
return parser_error("condition error") unless cond
|
1441
|
+
|
1442
|
+
if cond == 'true'
|
1443
|
+
return expand_with(:in_if => false)
|
1444
|
+
elsif cond == 'false'
|
1445
|
+
if descendant('else') || descendant('elsif')
|
1446
|
+
return expand_with(:in_if=>true, :only=>['elsif', 'else'])
|
1447
|
+
else
|
1448
|
+
@html_tag_done = true
|
1449
|
+
return ''
|
1450
|
+
end
|
1451
|
+
end
|
1452
|
+
|
1453
|
+
out "<% if #{cond} -%>"
|
1454
|
+
out render_html_tag(expand_with(:in_if=>false))
|
1455
|
+
out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
1456
|
+
out "<% end -%>"
|
1457
|
+
end
|
1458
|
+
|
1459
|
+
def r_else
|
1460
|
+
if @context[:in_if]
|
1461
|
+
@html_tag = @context[:html_tag]
|
1462
|
+
@html_tag_params = @context[:html_tag_params] || {}
|
1463
|
+
out "<% elsif true -%>"
|
1464
|
+
if @params[:text]
|
1465
|
+
out render_html_tag(@params[:text])
|
1466
|
+
else
|
1467
|
+
out render_html_tag(expand_with(:in_if=>false, :only => nil)) # do not propagate :only from ancestor 'if' clause
|
1468
|
+
end
|
1469
|
+
else
|
1470
|
+
""
|
1471
|
+
end
|
1472
|
+
end
|
1473
|
+
|
1474
|
+
def r_elsif
|
1475
|
+
return '' unless @context[:in_if]
|
1476
|
+
@html_tag = @context[:html_tag]
|
1477
|
+
@html_tag_params = @context[:html_tag_params] || {}
|
1478
|
+
cond = get_test_condition
|
1479
|
+
return parser_error("condition error") unless cond
|
1480
|
+
out "<% elsif #{cond} -%>"
|
1481
|
+
out render_html_tag(expand_with(:in_if=>false, :only => nil)) # do not propagate :only from ancestor 'if' clause
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
def r_when
|
1485
|
+
r_elsif
|
1486
|
+
end
|
1487
|
+
|
1488
|
+
# be carefull, this gives a list of 'versions', not 'nodes'
|
1489
|
+
def r_traductions
|
1490
|
+
if @params[:except]
|
1491
|
+
case @params[:except]
|
1492
|
+
when 'current'
|
1493
|
+
opts = "(:conditions=>\"lang != '#{helper.lang}'\")"
|
1494
|
+
else
|
1495
|
+
# list of lang
|
1496
|
+
# TODO: test
|
1497
|
+
langs = @params[:except].split(',').map{|l| l.gsub(/[^a-z]/,'').strip }
|
1498
|
+
opts = "(:conditions=>\"lang NOT IN ('#{langs.join("','")}')\")"
|
1499
|
+
end
|
1500
|
+
elsif @params[:only]
|
1501
|
+
# TODO: test
|
1502
|
+
case @params[:only]
|
1503
|
+
when 'current'
|
1504
|
+
opts = "(:conditions=>\"lang = '#{helper.lang}'\")"
|
1505
|
+
else
|
1506
|
+
# list of lang
|
1507
|
+
# TODO: test
|
1508
|
+
langs = @params[:only].split(',').map{|l| l.gsub(/[^a-z]/,'').strip }
|
1509
|
+
opts = "(:conditions=>\"lang IN ('#{langs.join("','")}')\")"
|
1510
|
+
end
|
1511
|
+
else
|
1512
|
+
opts = ""
|
1513
|
+
end
|
1514
|
+
out "<% if #{list_var} = #{node}.traductions#{opts} -%>"
|
1515
|
+
out expand_with(:list=>list_var, :node_class => Version)
|
1516
|
+
out "<% end -%>"
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
# TODO: test
|
1520
|
+
def r_show_traductions
|
1521
|
+
"<% if #{list_var} = #{node}.traductions -%>"
|
1522
|
+
"#{_("Traductions:")} <span class='traductions'><%= #{list_var}.join(', ') %></span>"
|
1523
|
+
"<%= traductions(:node=>#{node}).join(', ') %>"
|
1524
|
+
end
|
1525
|
+
|
1526
|
+
def r_node
|
1527
|
+
@method = @params[:select] || 'node' # 'node' is for version.node
|
1528
|
+
r_unknown
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
# icon or first image (defined using build_finder_for instead of zafu_known_context for performance reasons).
|
1532
|
+
def r_icon
|
1533
|
+
if !@params[:in] && !@params[:where] && !@params[:from] && !@params[:find]
|
1534
|
+
finder, klass = build_finder_for(:first, 'icon', @params.merge(:or => 'image', :order => 'l_id desc, position asc, name asc', :group => 'id,l_id'))
|
1535
|
+
return unless finder
|
1536
|
+
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
1537
|
+
do_var(finder, :node_class => klass)
|
1538
|
+
else
|
1539
|
+
r_unknown
|
1540
|
+
end
|
1541
|
+
end
|
1542
|
+
|
1543
|
+
def r_date
|
1544
|
+
select = @params[:select]
|
1545
|
+
case select
|
1546
|
+
when 'main'
|
1547
|
+
expand_with(:date=>'main_date')
|
1548
|
+
when 'now'
|
1549
|
+
expand_with(:date=>'Time.now')
|
1550
|
+
else
|
1551
|
+
if select =~ /^\d{4}-\d{1,2}-\d{1,2}$/
|
1552
|
+
begin
|
1553
|
+
d = Date.parse(select)
|
1554
|
+
expand_with(:date=>select.inspect)
|
1555
|
+
rescue
|
1556
|
+
parser_error("invalid date '#{select}' should be 'YYYY-MM-DD'")
|
1557
|
+
end
|
1558
|
+
elsif date = find_stored(Date, select)
|
1559
|
+
if date[0..0] == '"'
|
1560
|
+
begin
|
1561
|
+
d = Date.parse(date[1..-2])
|
1562
|
+
expand_with(:date=>date)
|
1563
|
+
rescue
|
1564
|
+
parser_error("invalid date #{select} (#{date}) should be 'YYYY-MM-DD'")
|
1565
|
+
end
|
1566
|
+
else
|
1567
|
+
expand_with(:date=>select)
|
1568
|
+
end
|
1569
|
+
elsif select =~ /\[(.*)\]/
|
1570
|
+
date, static = parse_attributes_in_value(select, :erb => false)
|
1571
|
+
expand_with(:date => "\"#{date}\"")
|
1572
|
+
else
|
1573
|
+
parser_error("bad parameter '#{select}'")
|
1574
|
+
end
|
1575
|
+
end
|
1576
|
+
end
|
1577
|
+
|
1578
|
+
def r_javascripts
|
1579
|
+
if @params[:list].nil?
|
1580
|
+
list = %w{ prototype effects tablekit zena }
|
1581
|
+
elsif @params[:list] == 'all'
|
1582
|
+
list = %w{ prototype effects dragdrop tablekit zena }
|
1583
|
+
else
|
1584
|
+
list = @params[:list].split(',').map{|e| e.strip}
|
1585
|
+
end
|
1586
|
+
helper.javascript_include_tag(*list)
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
def r_stylesheets
|
1590
|
+
if @params[:list] == 'all' || @params[:list].nil?
|
1591
|
+
list = %w{ zena code }
|
1592
|
+
else
|
1593
|
+
list = @params[:list].split(',').map{|e| e.strip}
|
1594
|
+
end
|
1595
|
+
list << {:media => @params[:media]} if @params[:media]
|
1596
|
+
helper.stylesheet_link_tag(*list)
|
1597
|
+
end
|
1598
|
+
|
1599
|
+
def r_flash_messages
|
1600
|
+
type = @params[:show] || 'both'
|
1601
|
+
"<div id='messages'>" +
|
1602
|
+
if (type == 'notice' || type == 'both')
|
1603
|
+
"<% if flash[:notice] -%><div id='notice' class='flash' onclick='new Effect.Fade(\"error\")'><%= flash[:notice] %></div><% end -%>"
|
1604
|
+
else
|
1605
|
+
''
|
1606
|
+
end +
|
1607
|
+
if (type == 'error' || type == 'both')
|
1608
|
+
"<% if flash[:error] -%><div id='error' class='flash' onclick='new Effect.Fade(\"error\")'><%= flash[:error] %></div><% end -%>"
|
1609
|
+
else
|
1610
|
+
''
|
1611
|
+
end +
|
1612
|
+
"</div>"
|
1613
|
+
end
|
1614
|
+
|
1615
|
+
# Shows a 'made with zena' link or logo. ;-) Thanks for using this !
|
1616
|
+
# TODO: test and add translation.
|
1617
|
+
# <r:zena show='logo'/> or <r:zena show='text'/> == <r:zena/>
|
1618
|
+
def r_zena
|
1619
|
+
if logo = @params[:logo]
|
1620
|
+
# FIXME
|
1621
|
+
case logo
|
1622
|
+
when 'tiny'
|
1623
|
+
else
|
1624
|
+
end
|
1625
|
+
else
|
1626
|
+
text = case @params[:type]
|
1627
|
+
when 'riding'
|
1628
|
+
_("riding zena")
|
1629
|
+
when 'peace'
|
1630
|
+
_("in peace with zena")
|
1631
|
+
when 'garden'
|
1632
|
+
_("a zen garden")
|
1633
|
+
else
|
1634
|
+
_("made with zena")
|
1635
|
+
end
|
1636
|
+
"<a class='zena' href='http://zenadmin.org' title='zena <%= Zena::VERSION %>'>#{text}</a>"
|
1637
|
+
end
|
1638
|
+
end
|
1639
|
+
|
1640
|
+
def r_design
|
1641
|
+
if @params[:by]
|
1642
|
+
by = "<a href='#{@params[:href]}'>#{@params[:by]}</a>"
|
1643
|
+
else
|
1644
|
+
by = expand_with(:trans => true)
|
1645
|
+
end
|
1646
|
+
unless skin = @params[:skin]
|
1647
|
+
skin = helper.instance_variable_get(:@controller).instance_variable_get(:@skin_name)
|
1648
|
+
end
|
1649
|
+
skin = "<i>#{skin}</i>" unless skin.blank?
|
1650
|
+
_("%{skin}, design by %{name}") % {:name => by, :skin => skin}
|
1651
|
+
end
|
1652
|
+
|
1653
|
+
# creates a link. Options are:
|
1654
|
+
# :href (node, parent, project, root)
|
1655
|
+
# :tattr (translated attribute used as text link)
|
1656
|
+
# :attr (attribute used as text link)
|
1657
|
+
# <r:link href='node'><r:trans attr='lang'/></r:link>
|
1658
|
+
# <r:link href='node' tattr='lang'/>
|
1659
|
+
# <r:link update='dom_id'/>
|
1660
|
+
# <r:link page='next'/> <r:link page='previous'/> <r:link page='list'/>
|
1661
|
+
def r_link
|
1662
|
+
if @params[:page]
|
1663
|
+
pagination_links
|
1664
|
+
else
|
1665
|
+
make_link
|
1666
|
+
end
|
1667
|
+
end
|
1668
|
+
|
1669
|
+
def make_link(options = {})
|
1670
|
+
query_params = options[:query_params] || {}
|
1671
|
+
default_text = options[:default_text]
|
1672
|
+
params = @params.dup
|
1673
|
+
|
1674
|
+
opts = {}
|
1675
|
+
if upd = params.delete(:update)
|
1676
|
+
return unless remote_target = find_target(upd)
|
1677
|
+
end
|
1678
|
+
|
1679
|
+
if href = params.delete(:href)
|
1680
|
+
if lnode = find_stored(Node, href)
|
1681
|
+
# using stored node
|
1682
|
+
else
|
1683
|
+
lnode, klass = build_finder_for(:first, href, {})
|
1684
|
+
return unless lnode
|
1685
|
+
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
1686
|
+
end
|
1687
|
+
else
|
1688
|
+
# obj
|
1689
|
+
if node_class == Version
|
1690
|
+
lnode = "#{node}.node"
|
1691
|
+
opts[:lang] = "#{node}.lang"
|
1692
|
+
elsif node_kind_of?(Node)
|
1693
|
+
lnode = node
|
1694
|
+
else
|
1695
|
+
lnode = @context[:previous_node]
|
1696
|
+
end
|
1697
|
+
end
|
1698
|
+
|
1699
|
+
if fmt = params.delete(:format)
|
1700
|
+
if fmt == 'data'
|
1701
|
+
opts[:format] = "#{node}.c_ext"
|
1702
|
+
else
|
1703
|
+
opts[:format] = fmt.inspect
|
1704
|
+
end
|
1705
|
+
end
|
1706
|
+
|
1707
|
+
if mode = params.delete(:mode)
|
1708
|
+
opts[:mode] = mode.inspect
|
1709
|
+
end
|
1710
|
+
|
1711
|
+
if sharp = params.delete(:sharp)
|
1712
|
+
opts[:sharp] = sharp.inspect
|
1713
|
+
end
|
1714
|
+
|
1715
|
+
if sharp_in = params.delete(:in)
|
1716
|
+
finder, klass = build_finder_for(:first, sharp_in, {})
|
1717
|
+
return unless finder
|
1718
|
+
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
1719
|
+
opts[:sharp_in] = finder
|
1720
|
+
end
|
1721
|
+
|
1722
|
+
if @html_tag && @html_tag != 'a'
|
1723
|
+
# FIXME: can we remove this ?
|
1724
|
+
# html attributes do not belong to anchor
|
1725
|
+
pre_space = ''
|
1726
|
+
html_params = {}
|
1727
|
+
else
|
1728
|
+
html_params = get_html_params(params.merge(@html_tag_params), :link)
|
1729
|
+
pre_space = @space_before || ''
|
1730
|
+
@html_tag_done = true
|
1731
|
+
end
|
1732
|
+
|
1733
|
+
(params.keys - [:style, :class, :id, :rel, :name, :anchor, :attr, :tattr, :trans, :text, :page]).each do |k|
|
1734
|
+
next if k.to_s =~ /if_|set_/
|
1735
|
+
query_params[k] = params[k]
|
1736
|
+
end
|
1737
|
+
|
1738
|
+
# TODO: merge these two query_params cleanup things into something cleaner.
|
1739
|
+
if remote_target
|
1740
|
+
# ajax
|
1741
|
+
query_params_list = []
|
1742
|
+
query_params.each do |k,v|
|
1743
|
+
if k == :date
|
1744
|
+
if v == 'current_date'
|
1745
|
+
str = "\#{#{current_date}}"
|
1746
|
+
elsif v =~ /\A\d/
|
1747
|
+
str = CGI.escape(v.gsub('"',''))
|
1748
|
+
elsif v =~ /\[/
|
1749
|
+
attribute, static = parse_attributes_in_value(v.gsub('"',''), :erb => false)
|
1750
|
+
str = static ? CGI.escape(attribute) : "\#{CGI.escape(\"#{attribute}\")}"
|
1751
|
+
else
|
1752
|
+
str = "\#{CGI.escape(#{node_attribute(v)})}"
|
1753
|
+
end
|
1754
|
+
else
|
1755
|
+
attribute, static = parse_attributes_in_value(v.gsub('"',''), :erb => false)
|
1756
|
+
str = static ? CGI.escape(attribute) : "\#{CGI.escape(\"#{attribute}\")}"
|
1757
|
+
end
|
1758
|
+
query_params_list << "#{k.to_s.gsub('"','')}=#{str}"
|
1759
|
+
end
|
1760
|
+
pre_space + link_to_update(remote_target, :node_id => "#{lnode}.zip", :query_params => query_params_list, :default_text => default_text, :html_params => html_params)
|
1761
|
+
else
|
1762
|
+
# direct link
|
1763
|
+
query_params.each do |k,v|
|
1764
|
+
if k == :date
|
1765
|
+
if v == 'current_date'
|
1766
|
+
query_params[k] = current_date
|
1767
|
+
elsif v =~ /\A\d/
|
1768
|
+
query_params[k] = v.inspect
|
1769
|
+
elsif v =~ /\[/
|
1770
|
+
attribute, static = parse_attributes_in_value(v.gsub('"',''), :erb => false)
|
1771
|
+
query_params[k] = "\"#{attribute}\""
|
1772
|
+
else
|
1773
|
+
query_params[k] = node_attribute(v)
|
1774
|
+
end
|
1775
|
+
else
|
1776
|
+
attribute, static = parse_attributes_in_value(v.gsub('"',''), :erb => false)
|
1777
|
+
query_params[k] = "\"#{attribute}\""
|
1778
|
+
end
|
1779
|
+
end
|
1780
|
+
|
1781
|
+
query_params.merge!(opts)
|
1782
|
+
|
1783
|
+
opts_str = ''
|
1784
|
+
query_params.keys.sort {|a,b| a.to_s <=> b.to_s }.each do |k|
|
1785
|
+
opts_str << ",:#{k.to_s.gsub(/[^a-z_A-Z_]/,'')}=>#{query_params[k]}"
|
1786
|
+
end
|
1787
|
+
|
1788
|
+
opts_str += ", :host => #{@context["exp_host"]}" if @context["exp_host"]
|
1789
|
+
|
1790
|
+
pre_space + "<a#{params_to_html(html_params)} href='<%= zen_path(#{lnode}#{opts_str}) %>'>#{text_for_link(default_text)}</a>"
|
1791
|
+
end
|
1792
|
+
end
|
1793
|
+
|
1794
|
+
# <r:link page='next'/> <r:link page='previous'/> <r:link page='list'/>
|
1795
|
+
def pagination_links
|
1796
|
+
return parser_error("not in pagination scope") unless pagination_key = @context[:paginate]
|
1797
|
+
case @params[:page]
|
1798
|
+
when 'previous'
|
1799
|
+
out "<% if set_#{pagination_key}_previous = (set_#{pagination_key} > 1 ? set_#{pagination_key} - 1 : nil) -%>"
|
1800
|
+
@context[:vars] ||= []
|
1801
|
+
@context[:vars] << "#{pagination_key}_previous"
|
1802
|
+
out make_link(:default_text => "<%= set_#{pagination_key}_previous %>", :query_params => {pagination_key => "[#{pagination_key}_previous]"})
|
1803
|
+
if descendant('else')
|
1804
|
+
out expand_with(:in_if => true, :only => ['else', 'elsif'])
|
1805
|
+
end
|
1806
|
+
out "<% end -%>"
|
1807
|
+
when 'next'
|
1808
|
+
out "<% if set_#{pagination_key}_next = (set_#{pagination_key}_count - set_#{pagination_key} > 0 ? set_#{pagination_key} + 1 : nil) -%>"
|
1809
|
+
@context[:vars] ||= []
|
1810
|
+
@context[:vars] << "#{pagination_key}_next"
|
1811
|
+
out make_link(:default_text => "<%= set_#{pagination_key}_next %>", :query_params => {pagination_key => "[#{pagination_key}_next]"})
|
1812
|
+
if descendant('else')
|
1813
|
+
out expand_with(:in_if => true, :only => ['else', 'elsif'])
|
1814
|
+
end
|
1815
|
+
out "<% end -%>"
|
1816
|
+
when 'list'
|
1817
|
+
@context[:vars] ||= []
|
1818
|
+
@context[:vars] << "#{pagination_key}_page"
|
1819
|
+
if @blocks == [] || (@blocks.size == 1 && !@blocks.first.kind_of?(String) && @blocks.first.method == 'else')
|
1820
|
+
# add a default block
|
1821
|
+
if tag = @params[:tag]
|
1822
|
+
open_tag = "<#{tag}>"
|
1823
|
+
close_tag = "</#{tag}>"
|
1824
|
+
else
|
1825
|
+
open_tag = close_tag = ''
|
1826
|
+
end
|
1827
|
+
link_params = {}
|
1828
|
+
@params.each do |k,v|
|
1829
|
+
next if [:tag, :page, :join, :page_count].include?(k)
|
1830
|
+
link_params[k] = v
|
1831
|
+
end
|
1832
|
+
text = "#{open_tag}<r:link #{params_to_html(link_params)} #{pagination_key}='[#{pagination_key}_page]' do='[#{pagination_key}_page]'/>#{close_tag}"
|
1833
|
+
@blocks = [make(:void, :method=>'void', :text=>text)]
|
1834
|
+
remove_instance_variable(:@all_descendants)
|
1835
|
+
end
|
1836
|
+
|
1837
|
+
if !descendant('else')
|
1838
|
+
@blocks += [make(:void, :method=>'void', :text=>"<r:else>#{open_tag}<r:show var='#{pagination_key}_page'/>#{close_tag}</r:else>")]
|
1839
|
+
remove_instance_variable(:@all_descendants)
|
1840
|
+
end
|
1841
|
+
|
1842
|
+
out "<% page_numbers(set_#{pagination_key}, set_#{pagination_key}_count, #{(@params[:join] || ' ').inspect}, #{@params[:page_count] ? @params[:page_count].to_i : 'nil'}) do |set_#{pagination_key}_page, #{pagination_key}_page_join| %>"
|
1843
|
+
out "<%= #{pagination_key}_page_join %>"
|
1844
|
+
out "<% if set_#{pagination_key}_page != set_#{pagination_key} -%>"
|
1845
|
+
out expand_with(:in_if => true)
|
1846
|
+
out "<% end; end -%>"
|
1847
|
+
else
|
1848
|
+
parser_error("unkown 'page' option #{@params[:page].inspect} should be ('previous', 'next' or 'list')")
|
1849
|
+
end
|
1850
|
+
end
|
1851
|
+
|
1852
|
+
def r_img
|
1853
|
+
return unless node_kind_of?(Node)
|
1854
|
+
if @params[:src]
|
1855
|
+
finder, klass = build_finder_for(:first, @params[:src])
|
1856
|
+
return unless finder
|
1857
|
+
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
1858
|
+
img = finder
|
1859
|
+
else
|
1860
|
+
img = node
|
1861
|
+
end
|
1862
|
+
mode = @params[:mode] || 'std'
|
1863
|
+
# FIXME: replace this call by something that integrates better with html_tag_params and such.
|
1864
|
+
res = "img_tag(#{img}, :mode=>#{mode.inspect}"
|
1865
|
+
[:class, :alt_src, :id, :border, :style].each do |k|
|
1866
|
+
res += ", :#{k}=>#{@params[k].inspect}" if @params[k]
|
1867
|
+
end
|
1868
|
+
res += ", :host => #{@context["exp_host"]}" if @context["exp_host"]
|
1869
|
+
res += ")"
|
1870
|
+
if @params[:link]
|
1871
|
+
finder, klass = build_finder_for(:first, @params[:link])
|
1872
|
+
return unless finder
|
1873
|
+
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
1874
|
+
|
1875
|
+
opts_str = @context["exp_host"] ? ", :host => #{@context["exp_host"]}" : ""
|
1876
|
+
|
1877
|
+
"<a href='<%= zen_path(#{finder}#{opts_str}) %>'><%= #{res} %></a>"
|
1878
|
+
else
|
1879
|
+
"<%= #{res} %>"
|
1880
|
+
end
|
1881
|
+
end
|
1882
|
+
|
1883
|
+
def r_calendar
|
1884
|
+
if @context[:block] == self
|
1885
|
+
# called from self (storing template / rendering)
|
1886
|
+
if role = @params[:assign_as]
|
1887
|
+
assign_calendar(role)
|
1888
|
+
else
|
1889
|
+
display_calendar
|
1890
|
+
end
|
1891
|
+
else
|
1892
|
+
# This is called first to prepare calendar
|
1893
|
+
if @params[:assign_as]
|
1894
|
+
fld = 'date'
|
1895
|
+
table_name = 'links'
|
1896
|
+
else
|
1897
|
+
fld = @params[:date] || 'event_at'
|
1898
|
+
if ['log_at', 'created_at', 'updated_at', 'event_at'].include?(fld) # TODO: use rubyless to learn type
|
1899
|
+
table_name = 'nodes'
|
1900
|
+
elsif fld == 'l_date'
|
1901
|
+
fld = 'date'
|
1902
|
+
table_name = 'links'
|
1903
|
+
else
|
1904
|
+
return parser_error("Invalid 'date' value for calendar (#{fld.inspect}).")
|
1905
|
+
end
|
1906
|
+
end
|
1907
|
+
|
1908
|
+
@date_scope = "TABLE_NAME[#{table_name}].#{fld} >= '\#{start_date.strftime('%Y-%m-%d')}' AND TABLE_NAME[#{table_name}].#{fld} <= '\#{end_date.strftime('%Y-%m-%d')}'"
|
1909
|
+
|
1910
|
+
new_dom_scope
|
1911
|
+
|
1912
|
+
# SAVED TEMPLATE
|
1913
|
+
template = expand_block(self, :block => self, :saved_template => true)
|
1914
|
+
out helper.save_erb_to_url(template, template_url)
|
1915
|
+
|
1916
|
+
# INLINE
|
1917
|
+
out expand_block(self, :block => self, :saved_template => false)
|
1918
|
+
end
|
1919
|
+
end
|
1920
|
+
|
1921
|
+
def display_calendar
|
1922
|
+
size = (params[:size] || 'large').to_sym
|
1923
|
+
finder = params[:select] || 'notes in project'
|
1924
|
+
|
1925
|
+
if @blocks == []
|
1926
|
+
# add a default <r:link/> block
|
1927
|
+
if size == :tiny
|
1928
|
+
@blocks = [make(:void, :method=>'void', :text=>"<em do='link' date='current_date' do='[current_date]' format='%d'/><r:else do='[current_date]' format='%d'/>")]
|
1929
|
+
else
|
1930
|
+
@blocks = [make(:void, :method=>'void', :text=>"<span do='show' date='current_date' format='%d'/><ul><li do='each' do='link' attr='name'/></ul><r:else do='[current_date]' format='%d'/>")]
|
1931
|
+
end
|
1932
|
+
remove_instance_variable(:@all_descendants)
|
1933
|
+
elsif !descendant('else')
|
1934
|
+
@blocks += [make(:void, :method=>'void', :text=>"<r:else do='[current_date]' format='%d'/>")]
|
1935
|
+
remove_instance_variable(:@all_descendants)
|
1936
|
+
end
|
1937
|
+
|
1938
|
+
@html_tag_done = false
|
1939
|
+
@html_tag_params[:id] = erb_dom_id
|
1940
|
+
@html_tag_params[:class] ||= "#{size}cal"
|
1941
|
+
@html_tag ||= 'div'
|
1942
|
+
|
1943
|
+
finder, klass = build_finder_for(:all, finder, @params, [@date_scope])
|
1944
|
+
return unless finder
|
1945
|
+
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
1946
|
+
|
1947
|
+
cell_code = "<% if #{list_var} = nodes_#{list_var}[cal_#{list_var}.strftime('%Y-%m-%d %H')] -%>#{expand_with(:in_if => true, :list => list_var, :date => "cal_#{list_var}", :saved_template => nil, :dom_prefix => nil, :in_calendar => true)}<% end -%>"
|
1948
|
+
|
1949
|
+
render_html_tag(calendar_code(finder, "", cell_code, "", params))
|
1950
|
+
end
|
1951
|
+
|
1952
|
+
# manage links from @node ---- reference ----> ...
|
1953
|
+
# <div do='calendar' assign='reference' to='main' split_hours='12' />
|
1954
|
+
def assign_calendar(as_role)
|
1955
|
+
size = (params[:size] || 'large').to_sym
|
1956
|
+
@html_tag_done = false
|
1957
|
+
@html_tag_params[:id] = erb_dom_id
|
1958
|
+
@html_tag_params[:class] ||= "#{size}cal"
|
1959
|
+
@html_tag ||= 'div'
|
1960
|
+
if rel = RelationProxy.find_by_role(as_role.singularize)
|
1961
|
+
role = rel.this_role
|
1962
|
+
else
|
1963
|
+
return parser_error("Invalid role #{as_role.inspect}.")
|
1964
|
+
end
|
1965
|
+
finder, klass = build_finder_for(:all, role, @params, [@date_scope])
|
1966
|
+
return unless finder
|
1967
|
+
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
1968
|
+
|
1969
|
+
# SAVED TEMPLATE ========
|
1970
|
+
template_url = self.template_url + 'cell'
|
1971
|
+
template = "<%= cal_assign_cell(@node, #{role.inspect}, #{@params[:used].inspect}) %>"
|
1972
|
+
out helper.save_erb_to_url(template, template_url)
|
1973
|
+
|
1974
|
+
# we call update on node 'B'
|
1975
|
+
# A (main)
|
1976
|
+
# ... B (other node)
|
1977
|
+
# calendar (in B context) ---- role --->
|
1978
|
+
|
1979
|
+
cell_prefix_code = "<span><%= day_#{list_var}.strftime('%d').to_i -%></span><ul>"
|
1980
|
+
cell_code = "<%= #{list_var} = nodes_#{list_var}[cal_#{list_var}.strftime('%Y-%m-%d %H')]; #{node}.linked_node = #{list_var} ? #{list_var}.first : nil; cal_assign_cell(#{node}, #{role.inspect}, #{@params[:used].inspect}, params[:s] || @node.zip, cal_#{list_var}, #{template_url.inspect}) %>"
|
1981
|
+
cell_postfix_code = "</ul>"
|
1982
|
+
render_html_tag(calendar_code(finder, cell_prefix_code, cell_code, cell_postfix_code, params))
|
1983
|
+
end
|
1984
|
+
|
1985
|
+
def calendar_code(finder, cell_prefix_code, cell_code, cell_postfix_code, params)
|
1986
|
+
type = params[:type] ? params[:type].to_sym : :month
|
1987
|
+
size = (params[:size] || 'large').to_sym
|
1988
|
+
ref_date = params[:assign_as] ? 'l_date' : (params[:date] || 'event_at')
|
1989
|
+
|
1990
|
+
case type
|
1991
|
+
when :month
|
1992
|
+
title = "\"\#{_(Date::MONTHNAMES[main_date.mon])} \#{main_date.year}\""
|
1993
|
+
prev_date = "\#{main_date.advance(:months => -1).strftime(\"%Y-%m-%d\")}"
|
1994
|
+
next_date = "\#{main_date.advance(:months => 1).strftime(\"%Y-%m-%d\")}"
|
1995
|
+
when :week
|
1996
|
+
title = "\"\#{_(Date::MONTHNAMES[main_date.mon])} \#{main_date.year}\""
|
1997
|
+
prev_date = "\#{main_date.advance(:days => -7).strftime(\"%Y-%m-%d\")}"
|
1998
|
+
next_date = "\#{main_date.advance(:days => +7).strftime(\"%Y-%m-%d\")}"
|
1999
|
+
else
|
2000
|
+
return parser_error("invalid type (should be 'month' or 'week')")
|
2001
|
+
end
|
2002
|
+
|
2003
|
+
if hours = @params[:split_hours]
|
2004
|
+
hours = hours.split(',').map{|l| l.to_i}
|
2005
|
+
hours << 0
|
2006
|
+
hours = hours.uniq.sort
|
2007
|
+
# I feel all this would be much better if we could use "each_group" but then how do we access hours ?
|
2008
|
+
week_code = "<% week.step(week+6,1) do |day_#{list_var}| -%>
|
2009
|
+
<td<%= cal_class(day_#{list_var},#{current_date}) %>>#{cell_prefix_code}<% #{hours.inspect}.each do |set_hour|; cal_#{list_var} = Time.utc(day_#{list_var}.year,day_#{list_var}.month,day_#{list_var}.day,set_hour) -%>#{cell_code}<% end -%>#{cell_postfix_code}</td>
|
2010
|
+
<% end -%>"
|
2011
|
+
(@context[:vars] ||= []) << "hour"
|
2012
|
+
else
|
2013
|
+
hours = nil
|
2014
|
+
week_code = "<% week.step(week+6,1) do |day_#{list_var}| -%>
|
2015
|
+
<td<%= cal_class(day_#{list_var},#{current_date}) %>><% cal_#{list_var} = Time.utc(day_#{list_var}.year,day_#{list_var}.month,day_#{list_var}.day) -%>#{cell_prefix_code}#{cell_code}#{cell_postfix_code}</td>
|
2016
|
+
<% end -%>"
|
2017
|
+
end
|
2018
|
+
|
2019
|
+
res = <<-END_TXT
|
2020
|
+
<h3 class='title'>
|
2021
|
+
<span><%= link_to_remote(#{_('img_prev_page').inspect}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=#{dom_id}&date=#{prev_date}&#{start_node_s_param(:string)}\", :method => :get) %></span>
|
2022
|
+
<span class='date'><%= link_to_remote(#{title}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=#{dom_id}&#{start_node_s_param(:string)}\", :method => :get) %></span>
|
2023
|
+
<span><%= link_to_remote(#{_('img_next_page').inspect}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=#{dom_id}&date=#{next_date}&#{start_node_s_param(:string)}\", :method => :get) %></span>
|
2024
|
+
</h3>
|
2025
|
+
<table cellspacing='0' class='#{size}cal#{@params[:assign_as] ? " assign" : ''}'>
|
2026
|
+
<tr class='head'><%= cal_day_names(#{size.inspect}) %></tr>
|
2027
|
+
<% start_date, end_date = cal_start_end(#{current_date}, #{type.inspect}) -%>
|
2028
|
+
<% cal_weeks(#{ref_date.to_sym.inspect}, #{finder}, start_date, end_date, #{hours.inspect}) do |week, nodes_#{list_var}| -%>
|
2029
|
+
<tr class='body'>
|
2030
|
+
#{week_code}
|
2031
|
+
</tr>
|
2032
|
+
<% end -%>
|
2033
|
+
</table>
|
2034
|
+
END_TXT
|
2035
|
+
end
|
2036
|
+
|
2037
|
+
# part caching
|
2038
|
+
def r_cache
|
2039
|
+
kpath = @params[:kpath] || Page.kpath
|
2040
|
+
out "<% #{cache} = Cache.with(visitor.id, visitor.group_ids, #{kpath.inspect}, #{helper.send(:lang).inspect}, #{template_url.inspect}) do capture do %>"
|
2041
|
+
out expand_with
|
2042
|
+
out "<% end; end %><%= #{cache} %>"
|
2043
|
+
end
|
2044
|
+
|
2045
|
+
# recursion
|
2046
|
+
def r_include
|
2047
|
+
return '' if @context[:saved_template]
|
2048
|
+
return super if @params[:template] || !@params[:part]
|
2049
|
+
part = @params[:part].gsub(/[^a-zA-Z_]/,'')
|
2050
|
+
method_name = @context["#{part}_method".to_sym]
|
2051
|
+
return parser_error("no parent named '#{part}'") unless method_name
|
2052
|
+
"<%= #{method_name}(depth+1,#{node},#{list}) %>"
|
2053
|
+
end
|
2054
|
+
|
2055
|
+
# use all other tags as relations
|
2056
|
+
def r_unknown
|
2057
|
+
@params[:select] = @method
|
2058
|
+
r_context
|
2059
|
+
end
|
2060
|
+
|
2061
|
+
# Enter a new context (<r:context find='all' method='pages'>). This is the same as '<r:pages>...</r:pages>'). It is
|
2062
|
+
# considered better style to use '<r:pages>...</r:pages>' instead of the more general '<r:context>' because the tags
|
2063
|
+
# give a clue on the context at start and end. Another way to open a context is the 'do' syntax: "<div do='pages'>...</div>".
|
2064
|
+
# FIXME: 'else' clause has been removed, find a solution to put it back.
|
2065
|
+
def r_context
|
2066
|
+
# DRY ! (build_finder_for, block)
|
2067
|
+
return parser_error("missing 'method' parameter") unless method = @params[:select]
|
2068
|
+
|
2069
|
+
context = node_class.zafu_known_contexts[method]
|
2070
|
+
if context && @params.keys == [:select]
|
2071
|
+
open_context("#{node}.#{method}", context)
|
2072
|
+
elsif node_kind_of?(Node)
|
2073
|
+
count = ['first','all','count'].include?(@params[:find]) ? @params[:find].to_sym : nil
|
2074
|
+
count ||= Node.plural_relation?(method) ? :all : :first
|
2075
|
+
finder, klass, query = build_finder_for(count, method, @params)
|
2076
|
+
return unless finder
|
2077
|
+
if node_kind_of?(Node) && !klass.ancestors.include?(Node)
|
2078
|
+
# moving out of node: store last Node
|
2079
|
+
@context[:previous_node] = node
|
2080
|
+
end
|
2081
|
+
if count == :all
|
2082
|
+
# plural
|
2083
|
+
do_list( finder, query, :node_class => klass)
|
2084
|
+
# elsif count == :count
|
2085
|
+
# "<%= #{build_finder_for(count, method, @params)} %>"
|
2086
|
+
else
|
2087
|
+
# singular
|
2088
|
+
do_var( finder, :node_class => klass)
|
2089
|
+
end
|
2090
|
+
else
|
2091
|
+
"unknown relation (#{method}) for #{node_class} class"
|
2092
|
+
end
|
2093
|
+
end
|
2094
|
+
|
2095
|
+
def open_context(finder, context)
|
2096
|
+
klass = context[:node_class]
|
2097
|
+
# hack to store last 'Node' context until we fix node(Node) stuff:
|
2098
|
+
previous_node = node_kind_of?(Node) ? node : @context[:previous_node]
|
2099
|
+
if klass.kind_of?(Array)
|
2100
|
+
# plural
|
2101
|
+
do_list( finder, nil, context.merge(:node_class => klass[0], :previous_node => previous_node) )
|
2102
|
+
else
|
2103
|
+
# singular
|
2104
|
+
do_var( finder, context.merge(:previous_node => previous_node) )
|
2105
|
+
end
|
2106
|
+
end
|
2107
|
+
|
2108
|
+
# Prepare stylesheet and xml content for xsl-fo post-processor
|
2109
|
+
def r_fop
|
2110
|
+
return parser_error("missing 'stylesheet' argument") unless @params[:stylesheet]
|
2111
|
+
# get stylesheet text
|
2112
|
+
xsl_content, absolute_url, doc = self.class.get_template_text(@params[:stylesheet], @options[:helper], @options[:current_folder])
|
2113
|
+
return parser_error("stylesheet #{@params[:stylesheet].inspect} not found") unless doc
|
2114
|
+
|
2115
|
+
template_url = (self.template_url.split('/')[0..-2] + ['_main.xsl']).join('/')
|
2116
|
+
helper.save_erb_to_url(xsl_content, template_url)
|
2117
|
+
out "<?xml version='1.0' encoding='utf-8'?>\n"
|
2118
|
+
out "<!-- xsl_id:#{doc[:id] } -->\n" if doc
|
2119
|
+
out expand_with
|
2120
|
+
end
|
2121
|
+
|
2122
|
+
# Prepare content for LateX post-processor
|
2123
|
+
def r_latex
|
2124
|
+
out "% latex\n"
|
2125
|
+
# all content inside this will be informed to render for Latex output
|
2126
|
+
out expand_with(:output_format => 'latex')
|
2127
|
+
end
|
2128
|
+
|
2129
|
+
def r_debug
|
2130
|
+
return '' unless @context[:dev]
|
2131
|
+
add_html_class('debug')
|
2132
|
+
out "<p>#{@params[:title]}</p>" if @params[:title]
|
2133
|
+
(@params[:show] || '').split(',').map(&:strip).each do |what|
|
2134
|
+
case what
|
2135
|
+
when 'params'
|
2136
|
+
out "<pre><%= params.inspect %></pre>"
|
2137
|
+
else
|
2138
|
+
parser_error("invalid element to show. Options are ['params'].")
|
2139
|
+
end
|
2140
|
+
end
|
2141
|
+
out expand_with
|
2142
|
+
end
|
2143
|
+
|
2144
|
+
# ================== HELPER METHODS ================
|
2145
|
+
|
2146
|
+
# Create an sql query to open a new context (passes its arguments to HasRelations#build_find)
|
2147
|
+
def build_finder_for(count, rel, params=@params, raw_filters = [])
|
2148
|
+
if (context = node_class.zafu_known_contexts[rel]) && !params[:in] && !params[:where] && !params[:from] && !params[:order] && raw_filters == []
|
2149
|
+
klass = context[:node_class]
|
2150
|
+
|
2151
|
+
if klass.kind_of?(Array) && count == :all
|
2152
|
+
return ["#{node}.#{rel}", klass[0]]
|
2153
|
+
else
|
2154
|
+
return [(count == :all ? "[#{node}.#{rel}]" : "#{node}.#{rel}"), klass]
|
2155
|
+
end
|
2156
|
+
end
|
2157
|
+
|
2158
|
+
rel ||= 'self'
|
2159
|
+
if (count == :first)
|
2160
|
+
if rel == 'self'
|
2161
|
+
return [node, node_class]
|
2162
|
+
elsif rel == 'main'
|
2163
|
+
return ["@node", Node]
|
2164
|
+
elsif rel == 'root'
|
2165
|
+
return ["(secure(Node) { Node.find(#{current_site[:root_id]})})", Node]
|
2166
|
+
elsif rel == 'start'
|
2167
|
+
return ["start_node", Node]
|
2168
|
+
elsif rel == 'visitor'
|
2169
|
+
return ["visitor.contact", Node]
|
2170
|
+
elsif rel =~ /^\d+$/
|
2171
|
+
return ["(secure(Node) { Node.find_by_zip(#{rel.inspect})})", Node]
|
2172
|
+
elsif node_name = find_stored(Node, rel)
|
2173
|
+
return [node_name, Node]
|
2174
|
+
elsif rel[0..0] == '/'
|
2175
|
+
rel = rel[1..-1]
|
2176
|
+
return ["(secure(Node) { Node.find_by_path(#{rel.inspect})})", Node]
|
2177
|
+
end
|
2178
|
+
end
|
2179
|
+
|
2180
|
+
pseudo_sql, add_raw_filters = make_pseudo_sql(rel, params)
|
2181
|
+
raw_filters += add_raw_filters if add_raw_filters
|
2182
|
+
|
2183
|
+
# FIXME: stored should be clarified and managed in a single way through links and contexts.
|
2184
|
+
# <r:void store='foo'>...
|
2185
|
+
# <r:link href='foo'/>
|
2186
|
+
# <r:pages from='foo'/> <-- this is just a matter of changing node parameter
|
2187
|
+
# <r:pages from='site' project='foo'/>
|
2188
|
+
# <r:img link='foo'/>
|
2189
|
+
# ...
|
2190
|
+
|
2191
|
+
if node_kind_of?(Node)
|
2192
|
+
node_name = @context[:parent_node] || node
|
2193
|
+
else
|
2194
|
+
node_name = @context[:previous_node]
|
2195
|
+
end
|
2196
|
+
|
2197
|
+
# make sure we do not use a new record in a find query:
|
2198
|
+
query = Node.build_find(count, pseudo_sql, :node_name => node_name, :raw_filters => raw_filters, :ref_date => "\#{#{current_date}}")
|
2199
|
+
|
2200
|
+
unless query.valid?
|
2201
|
+
out parser_error(query.errors.join(' '), pseudo_sql.join(', '))
|
2202
|
+
return nil
|
2203
|
+
end
|
2204
|
+
|
2205
|
+
|
2206
|
+
if count == :count
|
2207
|
+
out "<%= #{query.finder(:count)} %>"
|
2208
|
+
return nil
|
2209
|
+
end
|
2210
|
+
|
2211
|
+
klass = query.main_class
|
2212
|
+
|
2213
|
+
if params[:else]
|
2214
|
+
# FIXME: else not working with zafu_known_contexts
|
2215
|
+
finder, else_class, else_query = build_finder_for(count, params[:else], {})
|
2216
|
+
if finder && (else_query.nil? || else_query.valid?) && (else_class == klass || klass.ancestors.include?(else_class) || else_class.ancestors.include?(klass))
|
2217
|
+
["(#{query.finder(count)} || #{finder})", klass, query]
|
2218
|
+
else
|
2219
|
+
[query.finder(count), query.main_class, query]
|
2220
|
+
end
|
2221
|
+
else
|
2222
|
+
[query.finder(count), query.main_class, query]
|
2223
|
+
end
|
2224
|
+
end
|
2225
|
+
|
2226
|
+
# Build pseudo sql from the parameters
|
2227
|
+
# comments where ... from ... in ... order ... limit
|
2228
|
+
def make_pseudo_sql(rel, params=@params)
|
2229
|
+
parts = [rel.dup]
|
2230
|
+
filters = []
|
2231
|
+
|
2232
|
+
if params[:from]
|
2233
|
+
parts << params[:from]
|
2234
|
+
|
2235
|
+
key_counter = 1
|
2236
|
+
while sub_part = params["from#{key_counter}".to_sym]
|
2237
|
+
key_counter += 1
|
2238
|
+
parts << sub_part
|
2239
|
+
end
|
2240
|
+
end
|
2241
|
+
|
2242
|
+
if params[:where]
|
2243
|
+
parts[0] << " where #{params[:where]}"
|
2244
|
+
end
|
2245
|
+
|
2246
|
+
if params[:in]
|
2247
|
+
parts[-1] << " in #{params[:in]}"
|
2248
|
+
end
|
2249
|
+
|
2250
|
+
if group = params[:group]
|
2251
|
+
parts[-1] << " group by #{group}" unless parts[0] =~ /group by/
|
2252
|
+
end
|
2253
|
+
|
2254
|
+
if order = params[:order]
|
2255
|
+
parts[-1] << " order by #{order}" unless parts[0] =~ /order by/
|
2256
|
+
end
|
2257
|
+
|
2258
|
+
if paginate = params[:paginate]
|
2259
|
+
page_size = params[:limit].to_i
|
2260
|
+
page_size = 20 if page_size < 1
|
2261
|
+
parts[-1] << " limit #{page_size} paginate #{paginate.gsub(/[^a-z_A-Z]/,'')}"
|
2262
|
+
else
|
2263
|
+
[:limit, :offset].each do |k|
|
2264
|
+
next unless params[k]
|
2265
|
+
parts[-1] << " #{k} #{params[k]}" unless parts[0] =~ / #{k} /
|
2266
|
+
end
|
2267
|
+
end
|
2268
|
+
|
2269
|
+
finders = [parts.join(' from ')]
|
2270
|
+
if params[:or]
|
2271
|
+
finders << params[:or]
|
2272
|
+
|
2273
|
+
key_counter = 1
|
2274
|
+
while sub_or = params["or#{key_counter}".to_sym]
|
2275
|
+
key_counter += 1
|
2276
|
+
finders << sub_or
|
2277
|
+
end
|
2278
|
+
else
|
2279
|
+
or_clause = nil
|
2280
|
+
end
|
2281
|
+
|
2282
|
+
return [finders, parse_raw_filters(params)]
|
2283
|
+
end
|
2284
|
+
|
2285
|
+
# Parse special filters
|
2286
|
+
def parse_raw_filters(params)
|
2287
|
+
filters = []
|
2288
|
+
|
2289
|
+
if value = params[:author]
|
2290
|
+
if stored = find_stored(User, value)
|
2291
|
+
filters << "TABLE_NAME.user_id = '\#{#{stored}.id}'"
|
2292
|
+
elsif value == 'current'
|
2293
|
+
filters << "TABLE_NAME.user_id = '\#{#{node}[:user_id]}'"
|
2294
|
+
elsif value == 'visitor'
|
2295
|
+
filters << "TABLE_NAME.user_id = '\#{visitor[:id]}'"
|
2296
|
+
elsif value =~ /\A\d+\Z/
|
2297
|
+
filters << "TABLE_NAME.user_id = '#{value.to_i}'"
|
2298
|
+
elsif value =~ /\A[\w\/]+\Z/
|
2299
|
+
# TODO: path, not implemented yet
|
2300
|
+
end
|
2301
|
+
end
|
2302
|
+
|
2303
|
+
if value = params[:project]
|
2304
|
+
if stored = find_stored(Node, value)
|
2305
|
+
filters << "TABLE_NAME.project_id = '\#{#{stored}.get_project_id}'"
|
2306
|
+
elsif value == 'current'
|
2307
|
+
filters << "TABLE_NAME.project_id = '\#{#{node}.get_project_id}'"
|
2308
|
+
elsif value =~ /\A\d+\Z/
|
2309
|
+
filters << "TABLE_NAME.project_id = '#{value.to_i}'"
|
2310
|
+
elsif value =~ /\A[\w\/]+\Z/
|
2311
|
+
# TODO: path, not implemented yet
|
2312
|
+
end
|
2313
|
+
end
|
2314
|
+
|
2315
|
+
if value = params[:section]
|
2316
|
+
if stored = find_stored(Node, value)
|
2317
|
+
filters << "TABLE_NAME.section_id = '\#{#{stored}.get_section_id}'"
|
2318
|
+
elsif value == 'current'
|
2319
|
+
filters << "TABLE_NAME.section_id = '\#{#{node}.get_section_id}'"
|
2320
|
+
elsif value =~ /\A\d+\Z/
|
2321
|
+
filters << "TABLE_NAME.section_id = '#{value.to_i}'"
|
2322
|
+
elsif value =~ /\A[\w\/]+\Z/
|
2323
|
+
# not implemented yet
|
2324
|
+
end
|
2325
|
+
end
|
2326
|
+
|
2327
|
+
[:updated, :created, :event, :log].each do |k|
|
2328
|
+
if value = params[k]
|
2329
|
+
# current, same are synonym for 'today'
|
2330
|
+
filters << date_condition(value,"TABLE_NAME.#{k}_at",current_date)
|
2331
|
+
end
|
2332
|
+
end
|
2333
|
+
|
2334
|
+
filters == [] ? nil : filters
|
2335
|
+
end
|
2336
|
+
|
2337
|
+
# helpers
|
2338
|
+
# get current output format
|
2339
|
+
def output_format
|
2340
|
+
@context[:output_format] || 'html'
|
2341
|
+
end
|
2342
|
+
|
2343
|
+
# find the current node name in the context
|
2344
|
+
def node(klass = self.node_class)
|
2345
|
+
if klass == self.node_class
|
2346
|
+
(@context[:saved_template] && @context[:main_node]) ? "@#{base_class.to_s.underscore}" : (@context[:node] || '@node')
|
2347
|
+
elsif klass == Node
|
2348
|
+
@context[:previous_node] || '@node'
|
2349
|
+
else
|
2350
|
+
# ?
|
2351
|
+
out parser_error("could not find node_name for #{klass} (current class is #{node_class})")
|
2352
|
+
'@node'
|
2353
|
+
end
|
2354
|
+
end
|
2355
|
+
|
2356
|
+
def erb_node_id(obj = node)
|
2357
|
+
if node_kind_of?(Version)
|
2358
|
+
"<%= #{obj}.node.zip %>.<%= #{obj}.number %>"
|
2359
|
+
else
|
2360
|
+
"<%= #{node_id(obj)} %>"
|
2361
|
+
end
|
2362
|
+
end
|
2363
|
+
|
2364
|
+
def node_id(obj = node)
|
2365
|
+
"#{obj}.zip"
|
2366
|
+
end
|
2367
|
+
|
2368
|
+
def current_date
|
2369
|
+
@context[:date] || 'main_date'
|
2370
|
+
end
|
2371
|
+
|
2372
|
+
def var
|
2373
|
+
return @var if @var
|
2374
|
+
if node =~ /^var(\d+)$/
|
2375
|
+
@var = "var#{$1.to_i + 1}"
|
2376
|
+
else
|
2377
|
+
@var = "var1"
|
2378
|
+
end
|
2379
|
+
end
|
2380
|
+
|
2381
|
+
def cache
|
2382
|
+
return @cache if @cache
|
2383
|
+
if @context[:cache] =~ /^cache(\d+)$/
|
2384
|
+
@cache = "cache#{$1.to_i + 1}"
|
2385
|
+
else
|
2386
|
+
@cache = "cache1"
|
2387
|
+
end
|
2388
|
+
end
|
2389
|
+
|
2390
|
+
def list_var
|
2391
|
+
return @list_var if @list_var
|
2392
|
+
if (list || "") =~ /^list(\d+)$/
|
2393
|
+
@list_var = "list#{$1.to_i + 1}"
|
2394
|
+
else
|
2395
|
+
@list_var = "list1"
|
2396
|
+
end
|
2397
|
+
end
|
2398
|
+
|
2399
|
+
# Class of the current 'node' object (can be Version, Comment, Node, DataEntry, etc)
|
2400
|
+
def node_class
|
2401
|
+
@context[:node_class] || Node
|
2402
|
+
end
|
2403
|
+
|
2404
|
+
def base_class
|
2405
|
+
if node_kind_of?(Node)
|
2406
|
+
Node
|
2407
|
+
elsif node_kind_of?(Version)
|
2408
|
+
Version
|
2409
|
+
else
|
2410
|
+
node_class
|
2411
|
+
end
|
2412
|
+
end
|
2413
|
+
|
2414
|
+
def node_kind_of?(ancestor)
|
2415
|
+
node_class.ancestors.include?(ancestor)
|
2416
|
+
end
|
2417
|
+
|
2418
|
+
def list
|
2419
|
+
@context[:list]
|
2420
|
+
end
|
2421
|
+
|
2422
|
+
def helper
|
2423
|
+
@options[:helper]
|
2424
|
+
end
|
2425
|
+
|
2426
|
+
def params_to_erb(params, initial_comma = true)
|
2427
|
+
res = initial_comma ? [""] : []
|
2428
|
+
params.each do |k,v|
|
2429
|
+
if v =~ /<%=/ && !(v =~ /"/)
|
2430
|
+
# replace by #{}
|
2431
|
+
val = v.gsub('#{', '# {').gsub(/<%=(.*?)%>/,'#{\1}')
|
2432
|
+
res << "#{k.inspect}=>\"#{val}\""
|
2433
|
+
else
|
2434
|
+
res << "#{k.inspect}=>#{v.inspect}"
|
2435
|
+
end
|
2436
|
+
end
|
2437
|
+
res.join(', ')
|
2438
|
+
end
|
2439
|
+
|
2440
|
+
def do_var(var_finder=nil, opts={})
|
2441
|
+
clear_dom_scope
|
2442
|
+
if var_finder == 'nil'
|
2443
|
+
out "<% if nil -%>"
|
2444
|
+
elsif var_finder
|
2445
|
+
out "<% if #{var} = #{var_finder} -%>"
|
2446
|
+
end
|
2447
|
+
|
2448
|
+
if descendant('unlink')
|
2449
|
+
@html_tag ||= 'div'
|
2450
|
+
new_dom_scope
|
2451
|
+
@html_tag_params[:id] = erb_dom_id
|
2452
|
+
end
|
2453
|
+
|
2454
|
+
res = expand_with(opts.merge(:node=>var, :in_if => false))
|
2455
|
+
|
2456
|
+
if var_finder
|
2457
|
+
res += expand_with(opts.merge(:in_if => true, :only => ['else', 'elsif'], :html_tag_params => @html_tag_params, :html_tag => @html_tag))
|
2458
|
+
end
|
2459
|
+
out render_html_tag(res)
|
2460
|
+
out "<% end -%>" if var_finder
|
2461
|
+
end
|
2462
|
+
|
2463
|
+
def do_list(list_finder, query = nil, opts={})
|
2464
|
+
clear_dom_scope
|
2465
|
+
|
2466
|
+
@context.merge!(opts) # pass options from 'zafu_known_contexts' to @context
|
2467
|
+
|
2468
|
+
if (each_block = descendant('each')) && (each_block.descendant('edit') || descendant('add') || descendant('add_document') || (descendant('swap') && descendant('swap').parent.method != 'block') || ['block', 'drop'].include?(each_block.single_child_method))
|
2469
|
+
new_dom_scope
|
2470
|
+
# ajax, build template. We could merge the following code with 'r_block'.
|
2471
|
+
add_block = descendant('add')
|
2472
|
+
form_block = descendant('form') || each_block
|
2473
|
+
|
2474
|
+
@context[:need_link_id] = form_block.need_link_id
|
2475
|
+
|
2476
|
+
out "<% if (#{list_var} = #{list_finder}) || (#{node}.#{node_kind_of?(Comment) ? "can_comment?" : "can_write?"} && #{list_var}=[]) -%>"
|
2477
|
+
if query && (pagination_key = query.pagination_key)
|
2478
|
+
out "<% set_#{pagination_key}_nodes = #{query.finder(:count)}; set_#{pagination_key}_count = (set_#{pagination_key}_nodes / #{query.page_size.to_f}).ceil; set_#{pagination_key} = [1,params[:#{pagination_key}].to_i].max -%>"
|
2479
|
+
@context[:paginate] = pagination_key
|
2480
|
+
@context[:vars] ||= []
|
2481
|
+
@context[:vars] << "#{pagination_key}_nodes"
|
2482
|
+
@context[:vars] << "#{pagination_key}_count"
|
2483
|
+
@context[:vars] << "#{pagination_key}"
|
2484
|
+
end
|
2485
|
+
|
2486
|
+
# should we publish ?
|
2487
|
+
publish_after_save ||= form_block ? form_block.params[:publish] : nil
|
2488
|
+
publish_after_save ||= descendant('edit') ? descendant('edit').params[:publish] : nil
|
2489
|
+
|
2490
|
+
# class name for create form
|
2491
|
+
klass = add_block ? add_block.params[:klass] : nil
|
2492
|
+
klass ||= form_block ? form_block.params[:klass] : nil
|
2493
|
+
|
2494
|
+
# INLINE ==========
|
2495
|
+
# 'r_add' needs the form when rendering. Send with :form.
|
2496
|
+
out render_html_tag(expand_with(:list=>list_var, :in_if => false, :form=>form_block, :publish_after_save => publish_after_save, :ignore => ['form'], :klass => klass))
|
2497
|
+
out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
2498
|
+
out "<% end -%>"
|
2499
|
+
|
2500
|
+
# SAVED TEMPLATE ========
|
2501
|
+
template = expand_block(each_block, :list=>false, :klass => klass, :saved_template => true)
|
2502
|
+
out helper.save_erb_to_url(template, template_url)
|
2503
|
+
|
2504
|
+
# FORM ============
|
2505
|
+
if each_block != form_block
|
2506
|
+
form = expand_block(form_block, :klass => klass, :add=>add_block, :publish_after_save => publish_after_save, :saved_template => true)
|
2507
|
+
else
|
2508
|
+
form = expand_block(form_block, :klass => klass, :add=>add_block, :make_form=>true, :publish_after_save => publish_after_save, :saved_template => true)
|
2509
|
+
end
|
2510
|
+
out helper.save_erb_to_url(form, form_url)
|
2511
|
+
else
|
2512
|
+
# no form, render, edit and add are not ajax
|
2513
|
+
if descendant('add') || descendant('add_document')
|
2514
|
+
out "<% if (#{list_var} = #{list_finder}) || (#{node}.#{node_kind_of?(Comment) ? "can_comment?" : "can_write?"} && #{list_var}=[]) -%>"
|
2515
|
+
elsif list_finder != 'nil'
|
2516
|
+
out "<% if #{list_var} = #{list_finder} -%>"
|
2517
|
+
else
|
2518
|
+
out "<% if nil -%>"
|
2519
|
+
end
|
2520
|
+
|
2521
|
+
if query && (pagination_key = query.pagination_key)
|
2522
|
+
out "<% set_#{pagination_key}_nodes = #{query.finder(:count)}; set_#{pagination_key}_count = (set_#{pagination_key}_nodes / #{query.page_size.to_f}).ceil; set_#{pagination_key} = [1,params[:#{pagination_key}].to_i].max -%>"
|
2523
|
+
@context[:paginate] = pagination_key
|
2524
|
+
@context[:vars] ||= []
|
2525
|
+
@context[:vars] << "#{pagination_key}_nodes"
|
2526
|
+
@context[:vars] << "#{pagination_key}_count"
|
2527
|
+
@context[:vars] << "#{pagination_key}"
|
2528
|
+
end
|
2529
|
+
|
2530
|
+
out render_html_tag(expand_with(:list=>list_var, :in_if => false))
|
2531
|
+
out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
2532
|
+
out "<% end -%>"
|
2533
|
+
end
|
2534
|
+
end
|
2535
|
+
|
2536
|
+
def _(text)
|
2537
|
+
if @context[:dict]
|
2538
|
+
@context[:dict][text] || helper.send(:_,text)
|
2539
|
+
else
|
2540
|
+
helper.send(:_,text)
|
2541
|
+
end
|
2542
|
+
end
|
2543
|
+
|
2544
|
+
# Find a block to update on the page
|
2545
|
+
def find_target(name)
|
2546
|
+
# find dom_id / template_url
|
2547
|
+
target = nil
|
2548
|
+
root.descendants('block').each do |b|
|
2549
|
+
if b.name == name
|
2550
|
+
target = b
|
2551
|
+
break
|
2552
|
+
end
|
2553
|
+
end
|
2554
|
+
out parser_error("could not find a block named '#{name}'") if target.nil?
|
2555
|
+
target
|
2556
|
+
end
|
2557
|
+
|
2558
|
+
# DOM id for the current context
|
2559
|
+
def dom_id(suffix='')
|
2560
|
+
return "\#{dom_id(#{node})}" if @context && (@context[:saved_template] && @context[:main_node])
|
2561
|
+
if @context && scope_node = @context[:scope_node]
|
2562
|
+
res = "#{dom_prefix}_\#{#{scope_node}.zip}"
|
2563
|
+
else
|
2564
|
+
res = dom_prefix
|
2565
|
+
end
|
2566
|
+
if (method == 'each' || method == 'each_group') && !@context[:make_form]
|
2567
|
+
"#{res}_\#{#{var}.zip}"
|
2568
|
+
elsif @context && @context[:in_calendar]
|
2569
|
+
"#{res}_\#{#{current_date}.to_i}"
|
2570
|
+
elsif method == 'unlink' || method == 'edit'
|
2571
|
+
target = nil
|
2572
|
+
parent = self.parent
|
2573
|
+
while parent
|
2574
|
+
if ['block', 'each', 'context', 'icon'].include?(parent.method)
|
2575
|
+
target = parent
|
2576
|
+
break
|
2577
|
+
end
|
2578
|
+
parent = parent.parent
|
2579
|
+
end
|
2580
|
+
target ? target.dom_id(suffix) : (res + suffix)
|
2581
|
+
else
|
2582
|
+
res + suffix
|
2583
|
+
end
|
2584
|
+
end
|
2585
|
+
|
2586
|
+
def erb_dom_id(suffix='')
|
2587
|
+
return "<%= dom_id(#{node}) %>" if @context && (@context[:saved_template] && @context[:main_node])
|
2588
|
+
if @context && scope_node = @context[:scope_node]
|
2589
|
+
res = "#{dom_prefix}_<%= #{scope_node}.zip %>"
|
2590
|
+
else
|
2591
|
+
res = dom_prefix
|
2592
|
+
end
|
2593
|
+
if (method == 'each' || method == 'each_group') && !@context[:make_form]
|
2594
|
+
"#{res}_<%= #{var}.zip %>"
|
2595
|
+
elsif method == 'draggable'
|
2596
|
+
"#{res}_<%= #{node}.zip %>"
|
2597
|
+
elsif @context && @context[:in_calendar]
|
2598
|
+
"#{res}_<%= #{current_date}.to_i %>"
|
2599
|
+
elsif method == 'unlink'
|
2600
|
+
target = nil
|
2601
|
+
parent = self.parent
|
2602
|
+
while parent
|
2603
|
+
if ['block', 'each', 'context', 'icon'].include?(parent.method)
|
2604
|
+
target = parent
|
2605
|
+
break
|
2606
|
+
end
|
2607
|
+
parent = parent.parent
|
2608
|
+
end
|
2609
|
+
target ? target.erb_dom_id(suffix) : (res + suffix)
|
2610
|
+
else
|
2611
|
+
res + suffix
|
2612
|
+
end
|
2613
|
+
end
|
2614
|
+
|
2615
|
+
# Unique template_url, ending with dom_id
|
2616
|
+
def template_url
|
2617
|
+
"#{@options[:root]}/#{dom_prefix}"
|
2618
|
+
end
|
2619
|
+
|
2620
|
+
def form_url
|
2621
|
+
template_url + '_form'
|
2622
|
+
end
|
2623
|
+
|
2624
|
+
# Return parameter value accessor
|
2625
|
+
def get_param(key)
|
2626
|
+
"params[:#{key}]"
|
2627
|
+
end
|
2628
|
+
|
2629
|
+
def context
|
2630
|
+
return @context if @context
|
2631
|
+
# not rendered yet, find first parent with context
|
2632
|
+
@context = parent ? parent.context : {}
|
2633
|
+
end
|
2634
|
+
|
2635
|
+
# prefix for DOM id
|
2636
|
+
def dom_prefix
|
2637
|
+
(@context ? @context[:dom_prefix] : nil) || (@dom_prefix ||= unique_name)
|
2638
|
+
end
|
2639
|
+
|
2640
|
+
# use our own scope
|
2641
|
+
def clear_dom_scope
|
2642
|
+
@context.delete(:make_form) # should not propagate
|
2643
|
+
@context.delete(:main_node) # should not propagate
|
2644
|
+
end
|
2645
|
+
|
2646
|
+
# create our own ajax DOM scope
|
2647
|
+
def new_dom_scope
|
2648
|
+
clear_dom_scope
|
2649
|
+
@context.delete(:saved_template) # should not propagate on fresh template
|
2650
|
+
@context.delete(:dom_prefix) # should not propagate on fresh template
|
2651
|
+
@context[:main_node] = true # the current context will be rendered with a fresh '@node'
|
2652
|
+
@context[:dom_prefix] = self.dom_prefix
|
2653
|
+
end
|
2654
|
+
|
2655
|
+
# Return a different name on each call
|
2656
|
+
def unique_name(base = context_name)
|
2657
|
+
root.next_name_index(base, base == @name).gsub(/[^\d\w\/]/,'_')
|
2658
|
+
end
|
2659
|
+
|
2660
|
+
def context_name
|
2661
|
+
@name || if @context
|
2662
|
+
@context[:name] || 'list'
|
2663
|
+
elsif parent
|
2664
|
+
parent.context_name
|
2665
|
+
else
|
2666
|
+
'root'
|
2667
|
+
end
|
2668
|
+
end
|
2669
|
+
|
2670
|
+
def next_name_index(key, own_id = false)
|
2671
|
+
@next_name_index ||= {}
|
2672
|
+
if @next_name_index[key]
|
2673
|
+
@next_name_index[key] += 1
|
2674
|
+
key + @next_name_index[key].to_s
|
2675
|
+
elsif own_id
|
2676
|
+
@next_name_index[key] = 0
|
2677
|
+
key
|
2678
|
+
else
|
2679
|
+
@next_name_index[key] = 1
|
2680
|
+
key + '1'
|
2681
|
+
end
|
2682
|
+
end
|
2683
|
+
|
2684
|
+
def add_params(text, opts={}, inner = '')
|
2685
|
+
text.sub(/\A([^<]*)<(\w+)(( .*?)[^%]|)>/) do
|
2686
|
+
# we must set the first tag id
|
2687
|
+
before = $1
|
2688
|
+
tag = $2
|
2689
|
+
params = parse_params($3)
|
2690
|
+
opts.each do |k,v|
|
2691
|
+
next unless v
|
2692
|
+
params[k] = v
|
2693
|
+
end
|
2694
|
+
"#{before}<#{tag}#{params_to_html(params)}>#{inner}"
|
2695
|
+
end
|
2696
|
+
end
|
2697
|
+
|
2698
|
+
# TODO: RUBYLESS
|
2699
|
+
def get_test_condition(node = self.node, params = @params)
|
2700
|
+
tests = []
|
2701
|
+
params.each do |k,v|
|
2702
|
+
if k.to_s =~ /^(or_|)([a-zA-Z_]+)(\d*)$/
|
2703
|
+
k = $2.to_sym
|
2704
|
+
end #tagged undocumented
|
2705
|
+
if [:kind_of, :klass, :status, :lang, :can, :tagged, :node, :in, :visitor, :has].include?(k)
|
2706
|
+
tests << [k, v]
|
2707
|
+
elsif k == :test
|
2708
|
+
if v =~ /\s/
|
2709
|
+
tests << [:test, v]
|
2710
|
+
else
|
2711
|
+
tests << [:attribute, v]
|
2712
|
+
end
|
2713
|
+
end
|
2714
|
+
end
|
2715
|
+
|
2716
|
+
|
2717
|
+
tests.map! do |type,value|
|
2718
|
+
case type
|
2719
|
+
when :kind_of
|
2720
|
+
"#{node}.vkind_of?(#{value.inspect})"
|
2721
|
+
when :klass
|
2722
|
+
klass = begin Module::const_get(value) rescue "NilClass" end
|
2723
|
+
"#{node}.klass == #{value.inspect}"
|
2724
|
+
when :status
|
2725
|
+
"#{node}.version.status == #{Zena::Status[value.to_sym]}"
|
2726
|
+
when :tagged
|
2727
|
+
# TODO: undocumented: remove and use rubyless !
|
2728
|
+
"#{node}.tagged[#{value.inspect}]"
|
2729
|
+
when :lang
|
2730
|
+
"#{node}.version.lang == #{value.inspect}"
|
2731
|
+
when :can
|
2732
|
+
# TODO: test
|
2733
|
+
case value
|
2734
|
+
when 'write', 'edit'
|
2735
|
+
"#{node}.can_write?"
|
2736
|
+
when 'drive', 'publish'
|
2737
|
+
"#{node}.can_drive?"
|
2738
|
+
else
|
2739
|
+
nil
|
2740
|
+
end
|
2741
|
+
when :has
|
2742
|
+
case value
|
2743
|
+
when 'discussion'
|
2744
|
+
"#{node}.discussion"
|
2745
|
+
else
|
2746
|
+
nil
|
2747
|
+
end
|
2748
|
+
when :test
|
2749
|
+
parse_condition(value, node)
|
2750
|
+
when :attribute
|
2751
|
+
'!' + node_attribute(value, :node => node) + '.blank?'
|
2752
|
+
when :node
|
2753
|
+
if node_kind_of?(Node)
|
2754
|
+
value, node_name = get_attribute_and_node(value)
|
2755
|
+
node_name ||= '@node'
|
2756
|
+
if value
|
2757
|
+
case value
|
2758
|
+
when 'main'
|
2759
|
+
"#{node}[:id] == #{node_name}[:id]"
|
2760
|
+
when 'start'
|
2761
|
+
"#{node}[:zip] == (params[:s] || @node[:zip]).to_i"
|
2762
|
+
when 'parent'
|
2763
|
+
"#{node}[:id] == #{node_name}[:parent_id]"
|
2764
|
+
when 'project'
|
2765
|
+
"#{node}[:id] == #{node_name}[:project_id]"
|
2766
|
+
when 'section'
|
2767
|
+
"#{node}[:id] == #{node_name}[:section_id]"
|
2768
|
+
when 'ancestor'
|
2769
|
+
"#{node_name}.fullpath =~ /\\A\#{#{node}.fullpath}/"
|
2770
|
+
else
|
2771
|
+
if stored = find_stored(Node, value)
|
2772
|
+
"#{node}[:id] == #{stored}[:id]"
|
2773
|
+
else
|
2774
|
+
nil
|
2775
|
+
end
|
2776
|
+
end
|
2777
|
+
else
|
2778
|
+
# bad node_name
|
2779
|
+
nil
|
2780
|
+
end
|
2781
|
+
else
|
2782
|
+
nil
|
2783
|
+
end
|
2784
|
+
when :in
|
2785
|
+
if @context["in_#{value}".to_sym] # FIXME: || ancestors.include?(value) ==> ancestors is a list of zafu tags, not a list of names !
|
2786
|
+
'true'
|
2787
|
+
else
|
2788
|
+
'false'
|
2789
|
+
end
|
2790
|
+
when :visitor
|
2791
|
+
if value == 'anon'
|
2792
|
+
"visitor.is_anon?"
|
2793
|
+
else
|
2794
|
+
nil
|
2795
|
+
end
|
2796
|
+
else
|
2797
|
+
nil
|
2798
|
+
end
|
2799
|
+
end.compact!
|
2800
|
+
tests == [] ? nil : tests.join(' || ')
|
2801
|
+
end
|
2802
|
+
|
2803
|
+
def parse_condition_error(clause, rest, res)
|
2804
|
+
out parser_error("invalid clause #{clause.inspect} near \"#{res[-2..-1]}#{rest[0..1]}\"")
|
2805
|
+
end
|
2806
|
+
|
2807
|
+
def parse_condition(clause, node_name)
|
2808
|
+
rest = clause.strip
|
2809
|
+
types = [:par_open, :value, :bool_op, :op, :par_close]
|
2810
|
+
allowed = [:par_open, :value]
|
2811
|
+
par_count = 0
|
2812
|
+
uses_bool_op = false
|
2813
|
+
segment = [] # value op value
|
2814
|
+
after_value = lambda { segment.size == 3 ? [:bool_op, :par_close] : [:op, :bool_op, :par_close]}
|
2815
|
+
res = ""
|
2816
|
+
while rest != ''
|
2817
|
+
# puts rest.inspect
|
2818
|
+
if rest =~ /\A\s+/
|
2819
|
+
rest = rest[$&.size..-1]
|
2820
|
+
elsif rest[0..0] == '('
|
2821
|
+
unless allowed.include?(:par_open)
|
2822
|
+
parse_condition_error(clause, rest, res)
|
2823
|
+
return nil
|
2824
|
+
end
|
2825
|
+
res << '('
|
2826
|
+
rest = rest[1..-1]
|
2827
|
+
par_count += 1
|
2828
|
+
elsif rest[0..0] == ')'
|
2829
|
+
unless allowed.include?(:par_close)
|
2830
|
+
parse_condition_error(clause, rest, res)
|
2831
|
+
return nil
|
2832
|
+
end
|
2833
|
+
res << ')'
|
2834
|
+
rest = rest[1..-1]
|
2835
|
+
par_count -= 1
|
2836
|
+
if par_count < 0
|
2837
|
+
parse_condition_error(clause, rest, res)
|
2838
|
+
return nil
|
2839
|
+
end
|
2840
|
+
allowed = [:bool_op]
|
2841
|
+
elsif rest =~ /\A(lt|le|eq|ne|ge|gt)\s+/
|
2842
|
+
unless allowed.include?(:op)
|
2843
|
+
parse_condition_error(clause, rest, res)
|
2844
|
+
return nil
|
2845
|
+
end
|
2846
|
+
op = $1.strip
|
2847
|
+
rest = rest[op.size..-1]
|
2848
|
+
op = {'lt' => '<', 'le' => '<=', 'eq' => '==', 'ne' => '!=', 'ge' => '>=', 'gt' => '>'}[op]
|
2849
|
+
segment << [op, :op]
|
2850
|
+
allowed = [:value]
|
2851
|
+
elsif rest =~ /\A("|')([^\1]*?)\1/
|
2852
|
+
# string
|
2853
|
+
unless allowed.include?(:value)
|
2854
|
+
parse_condition_error(clause, rest, res)
|
2855
|
+
return nil
|
2856
|
+
end
|
2857
|
+
rest = rest[$&.size..-1]
|
2858
|
+
segment << [$2.inspect, :string]
|
2859
|
+
allowed = after_value.call
|
2860
|
+
elsif rest =~ /\A(-?\d+)/
|
2861
|
+
# number
|
2862
|
+
unless allowed.include?(:value)
|
2863
|
+
parse_condition_error(clause, rest, res)
|
2864
|
+
return nil
|
2865
|
+
end
|
2866
|
+
rest = rest[$&.size..-1]
|
2867
|
+
segment << [$1, :number]
|
2868
|
+
allowed = after_value.call
|
2869
|
+
elsif rest =~ /\A(and|or)/
|
2870
|
+
unless allowed.include?(:bool_op)
|
2871
|
+
parse_condition_error(clause, rest, res)
|
2872
|
+
return nil
|
2873
|
+
end
|
2874
|
+
uses_bool_op = true
|
2875
|
+
rest = rest[$&.size..-1]
|
2876
|
+
res << " #{$1} "
|
2877
|
+
allowed = [:par_open, :value]
|
2878
|
+
elsif rest =~ /\A([\w:\.\-]+)/
|
2879
|
+
# variable
|
2880
|
+
unless allowed.include?(:value)
|
2881
|
+
parse_condition_error(clause, rest, res)
|
2882
|
+
return nil
|
2883
|
+
end
|
2884
|
+
rest = rest[$&.size..-1]
|
2885
|
+
fld = $1
|
2886
|
+
unless node_attr = node_attribute(fld, :node => node_name)
|
2887
|
+
parser_error("invalid field #{fld.inspect}")
|
2888
|
+
return nil
|
2889
|
+
end
|
2890
|
+
segment << [node_attr, :var]
|
2891
|
+
allowed = after_value.call
|
2892
|
+
else
|
2893
|
+
parse_condition_error(clause, rest, res)
|
2894
|
+
return nil
|
2895
|
+
end
|
2896
|
+
if segment.size == 3
|
2897
|
+
toi = (segment[1][0] =~ /(>|<)/ || (segment[0][1] == :number || segment[2][1] == :number))
|
2898
|
+
segment.map! do |part, type|
|
2899
|
+
if type == :var
|
2900
|
+
toi ? "#{part}.to_i" : part
|
2901
|
+
elsif type == :string
|
2902
|
+
toi ? part[1..-2].to_i : part
|
2903
|
+
else
|
2904
|
+
part
|
2905
|
+
end
|
2906
|
+
end
|
2907
|
+
res << segment.join(" ")
|
2908
|
+
segment = []
|
2909
|
+
end
|
2910
|
+
end
|
2911
|
+
|
2912
|
+
if par_count > 0
|
2913
|
+
parser_error("invalid clause #{clause.inspect}: missing closing ')'")
|
2914
|
+
return nil
|
2915
|
+
elsif allowed.include?(:value)
|
2916
|
+
parser_error("invalid clause #{clause.inspect}")
|
2917
|
+
return nil
|
2918
|
+
else
|
2919
|
+
return uses_bool_op ? "(#{res})" : res
|
2920
|
+
end
|
2921
|
+
end
|
2922
|
+
|
2923
|
+
# Block visibility of descendance with 'do_list'.
|
2924
|
+
def public_descendants
|
2925
|
+
all = super
|
2926
|
+
if ['context', 'each', 'block'].include?(self.method)
|
2927
|
+
# do not propagate 'form',etc up
|
2928
|
+
all.reject do |k,v|
|
2929
|
+
['form','unlink'].include?(k)
|
2930
|
+
end
|
2931
|
+
elsif ['if', 'case'].include?(self.method)
|
2932
|
+
all.reject do |k,v|
|
2933
|
+
['else', 'elsif', 'when'].include?(k)
|
2934
|
+
end
|
2935
|
+
else
|
2936
|
+
all
|
2937
|
+
end
|
2938
|
+
end
|
2939
|
+
|
2940
|
+
def single_child_method
|
2941
|
+
return @single_child_method if defined?(@single_child_method)
|
2942
|
+
@single_child_method = if @blocks.size == 1
|
2943
|
+
single_child = @blocks[0]
|
2944
|
+
return nil if single_child.kind_of?(String)
|
2945
|
+
single_child.html_tag ? nil : single_child.method
|
2946
|
+
else
|
2947
|
+
nil
|
2948
|
+
end
|
2949
|
+
end
|
2950
|
+
|
2951
|
+
def get_attribute_and_node(str)
|
2952
|
+
if str =~ /([^\.]+)\.(.+)/
|
2953
|
+
node_name = $1
|
2954
|
+
node_attr = $2
|
2955
|
+
if att_node = find_stored(Node, node_name)
|
2956
|
+
return [node_attr, att_node, Node]
|
2957
|
+
elsif node_name == 'main'
|
2958
|
+
return [node_attr, '@node', Node]
|
2959
|
+
elsif node_name == 'visitor'
|
2960
|
+
return [node_attr, 'visitor.contact', Contact]
|
2961
|
+
elsif node_name == 'site'
|
2962
|
+
return [node_attr, 'current_site', Site]
|
2963
|
+
else
|
2964
|
+
out parser_error("invalid node name #{node_name.inspect} in attribute #{str.inspect}")
|
2965
|
+
return [nil]
|
2966
|
+
end
|
2967
|
+
else
|
2968
|
+
return [str]
|
2969
|
+
end
|
2970
|
+
end
|
2971
|
+
|
2972
|
+
def parse_attributes_in_value(v, opts = {})
|
2973
|
+
opts = {:erb => true}.merge(opts)
|
2974
|
+
static = true
|
2975
|
+
|
2976
|
+
use_node = @var || node
|
2977
|
+
res = v.gsub(/\[([^\]]+)\]/) do
|
2978
|
+
static = false
|
2979
|
+
res = nil
|
2980
|
+
attribute = $1
|
2981
|
+
|
2982
|
+
if opts[:skip_node_attributes]
|
2983
|
+
if attribute =~ /^param:(\w+)$/
|
2984
|
+
attribute = get_param($1)
|
2985
|
+
elsif attribute == 'current_date'
|
2986
|
+
attribute = current_date
|
2987
|
+
else
|
2988
|
+
res = "[#{attribute}]"
|
2989
|
+
end
|
2990
|
+
else
|
2991
|
+
attribute = node_attribute(attribute, :node => use_node )
|
2992
|
+
end
|
2993
|
+
|
2994
|
+
res ||= if opts[:erb]
|
2995
|
+
"<%= #{attribute} %>"
|
2996
|
+
else
|
2997
|
+
"\#{#{attribute}}"
|
2998
|
+
end
|
2999
|
+
res
|
3000
|
+
end
|
3001
|
+
[res, static]
|
3002
|
+
end
|
3003
|
+
|
3004
|
+
def node_attribute(str, opts={})
|
3005
|
+
|
3006
|
+
if @context[:vars] && @context[:vars].include?(str)
|
3007
|
+
return "set_#{str}"
|
3008
|
+
end
|
3009
|
+
|
3010
|
+
res = PSEUDO_ATTRIBUTES[str]
|
3011
|
+
return res if res
|
3012
|
+
return current_date if str == 'current_date'
|
3013
|
+
return get_param($1) if str =~ /^param:(\w+)$/
|
3014
|
+
|
3015
|
+
attribute, att_node, klass = get_attribute_and_node(str)
|
3016
|
+
|
3017
|
+
return 'nil' unless attribute
|
3018
|
+
|
3019
|
+
|
3020
|
+
att_node ||= opts[:node] || node
|
3021
|
+
klass ||= opts[:node_class] || node_class
|
3022
|
+
|
3023
|
+
real_attribute = attribute =~ /\Ad_/ ? attribute : attribute.gsub(/\A(|[\w_]+)id(s?)\Z/, '\1zip\2')
|
3024
|
+
|
3025
|
+
res = if klass.ancestors.include?(Node)
|
3026
|
+
if ['url','path'].include?(real_attribute)
|
3027
|
+
# pseudo attribute 'url'
|
3028
|
+
params = {}
|
3029
|
+
params[:mode] = @params[:mode] if @params[:mode]
|
3030
|
+
params[:format] = @params[:format] if @params[:format]
|
3031
|
+
"zen_#{real_attribute}(#{node}#{params_to_erb(params)})"
|
3032
|
+
elsif type = klass.safe_method_type([real_attribute])
|
3033
|
+
"#{att_node}.#{type[:method]}"
|
3034
|
+
else
|
3035
|
+
"#{att_node}.safe_read(#{real_attribute.inspect})"
|
3036
|
+
end
|
3037
|
+
elsif type = klass.safe_method_type([real_attribute])
|
3038
|
+
"#{att_node}.#{type[:method]}"
|
3039
|
+
else
|
3040
|
+
# unknown class, resolve at runtime
|
3041
|
+
"#{att_node}.safe_read(#{real_attribute.inspect})"
|
3042
|
+
end
|
3043
|
+
|
3044
|
+
res = "(#{res} || #{node_attribute(opts[:else])})" if opts[:else]
|
3045
|
+
res = "(#{res} || #{opts[:default].inspect})" if opts[:default]
|
3046
|
+
res
|
3047
|
+
end
|
3048
|
+
|
3049
|
+
# Add a class name to the html_tag
|
3050
|
+
def add_html_class(class_name)
|
3051
|
+
if klass = @html_tag_params[:class]
|
3052
|
+
@html_tag_params[:class] = "#{class_name} #{klass}"
|
3053
|
+
else
|
3054
|
+
@html_tag_params[:class] = class_name
|
3055
|
+
end
|
3056
|
+
end
|
3057
|
+
|
3058
|
+
def render_html_tag(text,*append)
|
3059
|
+
append ||= []
|
3060
|
+
return text if @html_tag_done
|
3061
|
+
set_params = {}
|
3062
|
+
if_params = {}
|
3063
|
+
@params.each do |k,v|
|
3064
|
+
if k.to_s =~ /^t?set_/
|
3065
|
+
set_params[k] = v
|
3066
|
+
end
|
3067
|
+
end
|
3068
|
+
tag_class = @html_tag_params[:class] || @params[:class]
|
3069
|
+
if node_kind_of?(Node)
|
3070
|
+
|
3071
|
+
if @context[:make_form]
|
3072
|
+
node_name = node
|
3073
|
+
elsif (@method == 'each' || @method == 'each_group') && @context[:list]
|
3074
|
+
node_name = var
|
3075
|
+
elsif @method == 'context'
|
3076
|
+
node_name = @var || node
|
3077
|
+
else
|
3078
|
+
node_name = node
|
3079
|
+
end
|
3080
|
+
|
3081
|
+
class_cond = nil
|
3082
|
+
@params.each do |k,v|
|
3083
|
+
if k.to_s =~ /^(.+)_if$/
|
3084
|
+
klass = $1
|
3085
|
+
cond = get_test_condition(node_name, :test => v)
|
3086
|
+
elsif k.to_s =~ /^(.+)_if_(test|node|kind_of|klass|status|lang|can|in)$/
|
3087
|
+
klass = $1
|
3088
|
+
cond = get_test_condition(node_name, $2.to_sym => v)
|
3089
|
+
end
|
3090
|
+
if cond
|
3091
|
+
class_cond = "#{cond} ? \" class='#{klass}'\" : #{class_cond}" # (x = 3) ? "class='foo'" :
|
3092
|
+
end
|
3093
|
+
end
|
3094
|
+
|
3095
|
+
if class_cond
|
3096
|
+
append << "<%= #{class_cond}\"#{tag_class ? " class='#{tag_class}'" : ""}\" %>"
|
3097
|
+
@html_tag_params.delete(:class)
|
3098
|
+
end
|
3099
|
+
end
|
3100
|
+
|
3101
|
+
@html_tag = 'div' if !@html_tag && (set_params != {} || @html_tag_params != {})
|
3102
|
+
|
3103
|
+
bak = @html_tag_params.dup
|
3104
|
+
@html_tag_params = get_html_params(set_params.merge(@html_tag_params), @html_tag)
|
3105
|
+
res = super(text,*append)
|
3106
|
+
@html_tag_params = bak
|
3107
|
+
res
|
3108
|
+
end
|
3109
|
+
|
3110
|
+
def link_to_update(target, opts = {})
|
3111
|
+
method = opts[:method] || :get
|
3112
|
+
|
3113
|
+
html_params = opts[:html_params] || {}
|
3114
|
+
node_id = opts[:node_id] || self.node_id
|
3115
|
+
|
3116
|
+
url = opts[:url] || "/#{base_class.to_s.pluralize.underscore}/\#{#{node_id}}#{method == :get ? '/zafu' : ''}"
|
3117
|
+
opts[:cond] ||= "#{node}.can_write?" if method != :get
|
3118
|
+
|
3119
|
+
query_params = [opts[:query_params]].flatten.compact
|
3120
|
+
|
3121
|
+
if method == :get
|
3122
|
+
if target
|
3123
|
+
query_params << "t_url=#{CGI.escape(target.template_url)}"
|
3124
|
+
query_params << "dom_id=#{target.dom_id}"
|
3125
|
+
else
|
3126
|
+
query_params << "dom_id=_page"
|
3127
|
+
end
|
3128
|
+
else
|
3129
|
+
query_params << "t_url=#{CGI.escape(template_url)}" if method != :delete
|
3130
|
+
|
3131
|
+
query_params << "dom_id=#{dom_id}"
|
3132
|
+
if target != self
|
3133
|
+
if target
|
3134
|
+
query_params << "u_url=#{CGI.escape(target.template_url)}"
|
3135
|
+
query_params << "udom_id=#{target.dom_id}"
|
3136
|
+
else
|
3137
|
+
query_params << "udom_id=_page"
|
3138
|
+
end
|
3139
|
+
end
|
3140
|
+
end
|
3141
|
+
|
3142
|
+
query_params << "link_id=\#{#{node}.link_id}" if @context[:need_link_id] && node_kind_of?(Node)
|
3143
|
+
query_params << "node[v_status]=#{Zena::Status[:pub]}" if @params[:publish] # FIXME: this acts like publish = 'force'
|
3144
|
+
query_params << start_node_s_param(:string)
|
3145
|
+
|
3146
|
+
res = ''
|
3147
|
+
res += "<% if #{opts[:cond]} -%>" if opts[:cond]
|
3148
|
+
res += "<%= tag_to_remote({:url => \"#{url}?#{query_params.join('&')}\", :method => #{method.inspect}}#{params_to_erb(html_params)}) %>"
|
3149
|
+
res += text_for_link(opts[:default_text])
|
3150
|
+
res += "</a>"
|
3151
|
+
if opts[:cond]
|
3152
|
+
if opts[:else] != :void
|
3153
|
+
res += "<% else -%>"
|
3154
|
+
res += text_for_link(opts[:default_text])
|
3155
|
+
end
|
3156
|
+
res += "<% end -%>"
|
3157
|
+
end
|
3158
|
+
res
|
3159
|
+
end
|
3160
|
+
|
3161
|
+
def text_for_link(default = nil)
|
3162
|
+
if @blocks.size > 1 || (@blocks.size == 1 && !(@blocks.first.kind_of?(String) || ['else','elsif'].include?(@blocks.first.method)))
|
3163
|
+
expand_with
|
3164
|
+
elsif default
|
3165
|
+
default
|
3166
|
+
elsif erb_text = get_text_for_erb(@params, false, :string)
|
3167
|
+
erb_text
|
3168
|
+
elsif node_kind_of?(Node)
|
3169
|
+
"<%= #{node}.version.title %>"
|
3170
|
+
elsif node_kind_of?(Version)
|
3171
|
+
"<%= #{node}.title %>"
|
3172
|
+
elsif node_kind_of?(Link)
|
3173
|
+
"<%= #{node}.name %>"
|
3174
|
+
else
|
3175
|
+
_('edit')
|
3176
|
+
end
|
3177
|
+
end
|
3178
|
+
|
3179
|
+
def get_text_for_erb(params = @params, use_blocks = true, context = :erb)
|
3180
|
+
string_context = context == :string
|
3181
|
+
if params[:attr]
|
3182
|
+
string_context ? "<%= #{node_attribute(params[:attr])} %>" : node_attribute(params[:attr])
|
3183
|
+
elsif params[:tattr]
|
3184
|
+
string_context ? "<%= _(#{node_attribute(params[:tattr])}) %>" : "_(#{node_attribute(params[:tattr])})"
|
3185
|
+
elsif params[:trans]
|
3186
|
+
string_context ? _(params[:trans]) : _(params[:trans]).inspect
|
3187
|
+
elsif params[:text]
|
3188
|
+
string_context ? params[:text] : params[:text].inspect
|
3189
|
+
elsif use_blocks && @blocks != []
|
3190
|
+
res = []
|
3191
|
+
text = ""
|
3192
|
+
static = true
|
3193
|
+
@blocks.each do |b|
|
3194
|
+
# FIXME: this is a little too hacky
|
3195
|
+
if b.kind_of?(String)
|
3196
|
+
res << b.inspect
|
3197
|
+
text << b
|
3198
|
+
elsif ['show', 'img'].include?(b.method)
|
3199
|
+
res << expand_block(b, :trans=>true)
|
3200
|
+
static = false
|
3201
|
+
elsif ['rename_asset', 'trans'].include?(b.method)
|
3202
|
+
# FIXME: if a trans contains non-static: static should become false
|
3203
|
+
res << expand_block(b).inspect
|
3204
|
+
text << expand_block(b)
|
3205
|
+
else
|
3206
|
+
# ignore
|
3207
|
+
end
|
3208
|
+
end
|
3209
|
+
if static
|
3210
|
+
# "just plain text"
|
3211
|
+
string_context ? text : text.inspect
|
3212
|
+
else
|
3213
|
+
# function(...) + "blah" + function()
|
3214
|
+
string_context ? "<%= #{res.join(' + ')} %>" : res.join(' + ')
|
3215
|
+
end
|
3216
|
+
else
|
3217
|
+
nil
|
3218
|
+
end
|
3219
|
+
end
|
3220
|
+
|
3221
|
+
def get_input_params(params = @params)
|
3222
|
+
res = {}
|
3223
|
+
if res[:name] = (params[:name] || params[:date])
|
3224
|
+
if res[:name] =~ /\A([\w_]+)\[(.*?)\]/
|
3225
|
+
attribute, sub_attr = $1, $2
|
3226
|
+
else
|
3227
|
+
attribute = res[:name]
|
3228
|
+
end
|
3229
|
+
|
3230
|
+
unless @context[:in_filter] || attribute == 's'
|
3231
|
+
if sub_attr
|
3232
|
+
res[:name] = "#{base_class.to_s.underscore}[#{attribute}][#{sub_attr}]"
|
3233
|
+
else
|
3234
|
+
res[:name] = "#{base_class.to_s.underscore}[#{attribute}]"
|
3235
|
+
end
|
3236
|
+
end
|
3237
|
+
|
3238
|
+
if sub_attr
|
3239
|
+
if (nattr = node_attribute(attribute)) != 'nil'
|
3240
|
+
nattr = "#{nattr}[#{sub_attr.inspect}]"
|
3241
|
+
end
|
3242
|
+
else
|
3243
|
+
nattr = node_attribute(attribute)
|
3244
|
+
end
|
3245
|
+
|
3246
|
+
if sub_attr && params[:type] == 'checkbox' && !params[:value]
|
3247
|
+
# Special case when we have a sub_attribute: default value for "tagged[foobar]" is "foobar"
|
3248
|
+
params[:value] = sub_attr
|
3249
|
+
end
|
3250
|
+
|
3251
|
+
if @context[:in_add]
|
3252
|
+
res[:value] = (params[:value] || params[:set_value]) ? ["'#{ helper.fquote(params[:value])}'"] : ["''"]
|
3253
|
+
elsif @context[:in_filter]
|
3254
|
+
res[:value] = attribute ? ["'<%= fquote params[#{attribute.to_sym.inspect}] %>'"] : ["''"]
|
3255
|
+
elsif params[:value]
|
3256
|
+
res[:value] = ["'#{ helper.fquote(params[:value])}'"]
|
3257
|
+
else
|
3258
|
+
if nattr != 'nil'
|
3259
|
+
res[:value] = ["'<%= fquote #{nattr} %>'"]
|
3260
|
+
else
|
3261
|
+
res[:value] = ["''"]
|
3262
|
+
end
|
3263
|
+
end
|
3264
|
+
end
|
3265
|
+
|
3266
|
+
if @context[:dom_prefix]
|
3267
|
+
res[:id] = "#{erb_dom_id}_#{attribute}"
|
3268
|
+
else
|
3269
|
+
res[:id] = params[:id] if params[:id]
|
3270
|
+
end
|
3271
|
+
|
3272
|
+
if params[:type] == 'checkbox' && nattr
|
3273
|
+
if value = params[:value]
|
3274
|
+
res[:checked] = "<%= #{nattr} == #{value.inspect} ? \" checked='checked'\" : '' %>"
|
3275
|
+
else
|
3276
|
+
res[:checked] = "<%= #{nattr}.blank? ? '' : \" checked='checked'\" %>"
|
3277
|
+
end
|
3278
|
+
end
|
3279
|
+
|
3280
|
+
[:size, :style, :class].each do |k|
|
3281
|
+
res[k] = params[k] if params[k]
|
3282
|
+
end
|
3283
|
+
|
3284
|
+
return [res, attribute]
|
3285
|
+
end
|
3286
|
+
|
3287
|
+
def get_html_params(params, tag_type)
|
3288
|
+
res = {}
|
3289
|
+
params.each do |k,v|
|
3290
|
+
next unless v
|
3291
|
+
if k.to_s =~ /\A(t?)set_(.+)$/
|
3292
|
+
key = $2
|
3293
|
+
trans = $1 == 't'
|
3294
|
+
value, static = parse_attributes_in_value(v, :erb => !trans)
|
3295
|
+
|
3296
|
+
if trans
|
3297
|
+
if static
|
3298
|
+
value = ["'#{_(value)}'"] # array so it is not escaped on render
|
3299
|
+
else
|
3300
|
+
value = ["'<%= _(\"#{value}\") %>'"] # FIXME: use dict ! array so it is not escaped on render
|
3301
|
+
end
|
3302
|
+
end
|
3303
|
+
res[key.to_sym] = value
|
3304
|
+
elsif tag_type == :link && ![:style, :class, :id, :title].include?(k)
|
3305
|
+
# bad html parameter for links (some keys for link tags are used as query parameters)
|
3306
|
+
# filter out
|
3307
|
+
else
|
3308
|
+
res[k] ||= v
|
3309
|
+
end
|
3310
|
+
end
|
3311
|
+
|
3312
|
+
if params[:anchor]
|
3313
|
+
@anchor_param = nil
|
3314
|
+
res[:name] = anchor_name(params[:anchor], node)
|
3315
|
+
end
|
3316
|
+
|
3317
|
+
res
|
3318
|
+
end
|
3319
|
+
|
3320
|
+
def get_options_for_select
|
3321
|
+
if nodes = @params[:nodes]
|
3322
|
+
# TODO: dry with r_checkbox
|
3323
|
+
if nodes =~ /^\d+\s*($|,)/
|
3324
|
+
# ids
|
3325
|
+
# TODO: optimization generate the full query instead of using secure.
|
3326
|
+
nodes = nodes.split(',').map{|v| v.to_i}
|
3327
|
+
nodes = "(secure(Node) { Node.find(:all, :conditions => 'zip IN (#{nodes.join(',')})') })"
|
3328
|
+
else
|
3329
|
+
# relation
|
3330
|
+
nodes, klass = build_finder_for(:all, nodes)
|
3331
|
+
return unless nodes
|
3332
|
+
return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
|
3333
|
+
end
|
3334
|
+
set_attr = @params[:attr] || 'id'
|
3335
|
+
show_attr = @params[:show] || 'name'
|
3336
|
+
options_list = "[['','']] + (#{nodes} || []).map{|r| [#{node_attribute(show_attr, :node => 'r', :node_class => Node)}, #{node_attribute(set_attr, :node => 'r', :node_class => Node)}.to_s]}"
|
3337
|
+
elsif values = @params[:values]
|
3338
|
+
options_list = values.split(',').map(&:strip)
|
3339
|
+
|
3340
|
+
if show = @params[:show]
|
3341
|
+
show_values = show.split(',').map(&:strip)
|
3342
|
+
elsif show = @params[:tshow]
|
3343
|
+
show_values = show.split(',').map do |s|
|
3344
|
+
_(s.strip)
|
3345
|
+
end
|
3346
|
+
end
|
3347
|
+
|
3348
|
+
if show_values
|
3349
|
+
options_list.each_index do |i|
|
3350
|
+
options_list[i] = [show_values[i], options_list[i]]
|
3351
|
+
end
|
3352
|
+
end
|
3353
|
+
options_list.inspect
|
3354
|
+
end
|
3355
|
+
end
|
3356
|
+
|
3357
|
+
def parse_eval_parameter(str)
|
3358
|
+
# evaluate an expression. Can only contain vars, '(', ')', '*', '+', '/', '-', '[attr]'
|
3359
|
+
# FIXME: SECURITY (audit this)
|
3360
|
+
vars = @context[:vars] || []
|
3361
|
+
parts = str.split(/\s+/)
|
3362
|
+
res = []
|
3363
|
+
test = []
|
3364
|
+
parts.each do |p|
|
3365
|
+
if p =~ /\[([\w_]+)\]/
|
3366
|
+
test << 1
|
3367
|
+
res << (node_attribute($1) + '.to_f')
|
3368
|
+
elsif p =~ /^[a-zA-Z_]+$/
|
3369
|
+
unless vars.include?(p)
|
3370
|
+
out parser_error("var #{p.inspect} not set in eval")
|
3371
|
+
return nil
|
3372
|
+
end
|
3373
|
+
test << 1
|
3374
|
+
res << "set_#{p}.to_f"
|
3375
|
+
elsif ['(', ')', '*', '+', '/', '-'].include?(p)
|
3376
|
+
res << p
|
3377
|
+
test << p
|
3378
|
+
elsif p =~ /^[0-9\.]+$/
|
3379
|
+
res << p
|
3380
|
+
test << p
|
3381
|
+
else
|
3382
|
+
out parser_error("bad argument #{p.inspect} in eval")
|
3383
|
+
return nil
|
3384
|
+
end
|
3385
|
+
end
|
3386
|
+
begin
|
3387
|
+
begin
|
3388
|
+
eval test.join(' ')
|
3389
|
+
rescue
|
3390
|
+
# rescue evaluation error
|
3391
|
+
out parser_error("error in eval")
|
3392
|
+
return nil
|
3393
|
+
end
|
3394
|
+
"(#{res.join(' ')})"
|
3395
|
+
rescue SyntaxError => err
|
3396
|
+
# rescue compilation error
|
3397
|
+
out parser_error("compilation error in eval")
|
3398
|
+
return nil
|
3399
|
+
end
|
3400
|
+
end
|
3401
|
+
|
3402
|
+
def find_stored(klass, key)
|
3403
|
+
if "#{klass}_#{key}" == "Node_start_node"
|
3404
|
+
# main node before ajax stuff (the one in browser url)
|
3405
|
+
"start_node"
|
3406
|
+
else
|
3407
|
+
@context["#{klass}_#{key}"]
|
3408
|
+
end
|
3409
|
+
end
|
3410
|
+
|
3411
|
+
def set_stored(klass, key, obj)
|
3412
|
+
@context["#{klass}_#{key}"] = obj
|
3413
|
+
end
|
3414
|
+
|
3415
|
+
# transform a 'show' tag into an input field.
|
3416
|
+
def make_input(params = @params)
|
3417
|
+
input, attribute = get_input_params(params)
|
3418
|
+
return parser_error("missing 'name'") unless attribute
|
3419
|
+
return '' if attribute == 'parent_id' # set with 'r_form'
|
3420
|
+
return '' if ['url','path'].include?(attribute) # cannot be set with a form
|
3421
|
+
if params[:date]
|
3422
|
+
input_id = @context[:dom_prefix] ? ", :id=>\"#{dom_id}_#{attribute}\"" : ''
|
3423
|
+
return "<%= date_box('#{base_class.to_s.underscore}', #{params[:date].inspect}#{input_id}) %>"
|
3424
|
+
end
|
3425
|
+
input_id = @context[:dom_prefix] ? " id='#{erb_dom_id}_#{attribute}'" : ''
|
3426
|
+
"<input type='#{params[:type] || 'text'}'#{input_id} name='#{input[:name]}' value=#{input[:value]}/>"
|
3427
|
+
end
|
3428
|
+
|
3429
|
+
# transform a 'zazen' tag into a textarea input field.
|
3430
|
+
def make_textarea(params)
|
3431
|
+
return parser_error("missing 'name'") unless name = params[:name]
|
3432
|
+
if name =~ /\A([\w_]+)\[(.*?)\]/
|
3433
|
+
attribute = $2
|
3434
|
+
else
|
3435
|
+
attribute = name
|
3436
|
+
name = "#{base_class.to_s.underscore}[#{attribute}]"
|
3437
|
+
end
|
3438
|
+
return '' if attribute == 'parent_id' # set with 'r_form'
|
3439
|
+
|
3440
|
+
if @blocks == [] || @blocks == ['']
|
3441
|
+
if @context[:in_add]
|
3442
|
+
value = ''
|
3443
|
+
else
|
3444
|
+
value = attribute ? "<%= #{node_attribute(attribute)} %>" : ""
|
3445
|
+
end
|
3446
|
+
else
|
3447
|
+
value = expand_with
|
3448
|
+
end
|
3449
|
+
html_id = @context[:dom_prefix] ? " id='#{erb_dom_id}_#{attribute}'" : ''
|
3450
|
+
"<textarea#{html_id} name='#{name}'>#{value}</textarea>"
|
3451
|
+
end
|
3452
|
+
|
3453
|
+
def default_focus_field
|
3454
|
+
if (input_fields = descendants('input')) != []
|
3455
|
+
field = input_fields.first.params[:name]
|
3456
|
+
elsif (show_fields = descendants('show')) != []
|
3457
|
+
field = show_fields.first.params[:attr]
|
3458
|
+
elsif node_kind_of?(Node)
|
3459
|
+
field = 'v_title'
|
3460
|
+
else
|
3461
|
+
field = 'text'
|
3462
|
+
end
|
3463
|
+
end
|
3464
|
+
|
3465
|
+
# Returns true if a form/edit needs to keep track of link_id (l_status or l_comment used).
|
3466
|
+
def need_link_id
|
3467
|
+
if (input_fields = (descendants('input') + descendants('select'))) != []
|
3468
|
+
input_fields.each do |f|
|
3469
|
+
return true if f.params[:name] =~ /\Al_/
|
3470
|
+
end
|
3471
|
+
elsif (show_fields = descendants('show')) != []
|
3472
|
+
show_fields.each do |f|
|
3473
|
+
return true if f.params[:attr] =~ /\Al_/
|
3474
|
+
end
|
3475
|
+
end
|
3476
|
+
return false
|
3477
|
+
end
|
3478
|
+
|
3479
|
+
def start_node_s_param(type = :input)
|
3480
|
+
if type == :input
|
3481
|
+
"<input type='hidden' name='s' value='<%= params[:s] || @node[:zip] %>'/>"
|
3482
|
+
elsif type == :erb
|
3483
|
+
"s=<%= params[:s] || @node[:zip] %>"
|
3484
|
+
elsif type == :value
|
3485
|
+
"<%= params[:s] || @node[:zip] %>"
|
3486
|
+
else
|
3487
|
+
"s=\#{params[:s] || @node[:zip]}"
|
3488
|
+
end
|
3489
|
+
end
|
3490
|
+
|
3491
|
+
def parser_error(message, tag=@method)
|
3492
|
+
"<span class='parser_error'>[#{tag}] #{message}</span>"
|
3493
|
+
end
|
3494
|
+
|
3495
|
+
# Used by [each] and [draggable] to insert 'id' and drag handle span
|
3496
|
+
def set_drag_handle_and_id(text, params, id_hash)
|
3497
|
+
res, drag_handle = text, nil
|
3498
|
+
if params[:drag_handle]
|
3499
|
+
drag_handle = params[:drag_handle] == 'true' ? 'drag_handle' : params[:drag_handle]
|
3500
|
+
if text =~ /class\s*=\s*['"]#{drag_handle}/
|
3501
|
+
# nothing to do
|
3502
|
+
insert = ''
|
3503
|
+
else
|
3504
|
+
insert = "<span class='#{drag_handle}'> </span>"
|
3505
|
+
end
|
3506
|
+
else
|
3507
|
+
insert = ''
|
3508
|
+
end
|
3509
|
+
|
3510
|
+
res = insert + text
|
3511
|
+
|
3512
|
+
if id_hash
|
3513
|
+
@html_tag ||= 'div'
|
3514
|
+
@html_tag_params.merge!(id_hash)
|
3515
|
+
end
|
3516
|
+
|
3517
|
+
[res, drag_handle]
|
3518
|
+
end
|
3519
|
+
|
3520
|
+
def expand_with(acontext={})
|
3521
|
+
# set variables
|
3522
|
+
context = nil
|
3523
|
+
pre = ''
|
3524
|
+
@blocks.each do |block|
|
3525
|
+
next if block.kind_of?(String) || block.method != 'set'
|
3526
|
+
@context[:vars] ||= []
|
3527
|
+
context ||= @context.merge(acontext).merge(:set => true)
|
3528
|
+
pre << expand_block(block, context)
|
3529
|
+
@context[:vars] << block.params[:var]
|
3530
|
+
end
|
3531
|
+
|
3532
|
+
pre + super
|
3533
|
+
end
|
3534
|
+
|
3535
|
+
def auto_publish_param(in_string = false)
|
3536
|
+
if in_string
|
3537
|
+
['true','force'].include?(@params[:publish]) ? "&publish=#{@params[:publish]}" : ''
|
3538
|
+
else
|
3539
|
+
@params[:publish]
|
3540
|
+
end
|
3541
|
+
end
|
3542
|
+
|
3543
|
+
# This is used by zafu and it's a mess.
|
3544
|
+
# ref_date can be a string ('2005-05-03') or ruby ('Time.now'). It should not come uncleaned from evil web.
|
3545
|
+
def date_condition(date_cond, field, ref_date='today')
|
3546
|
+
if date_cond == 'today' || ref_date == 'today'
|
3547
|
+
ref_date = Zena::Db::NOW
|
3548
|
+
elsif ref_date =~ /(\d{4}-\d{1,2}-\d{1,2}( \d{1,2}:\d{1,2}(:\d{1,2})?)?)/
|
3549
|
+
ref_date = "'#{$1}'"
|
3550
|
+
elsif ref_date =~ /\A"/
|
3551
|
+
ref_date = "'\#{format_date(#{ref_date})}'"
|
3552
|
+
else
|
3553
|
+
ref_date = "'\#{#{ref_date}.strftime('%Y-%m-%d %H:%M:%S')}'"
|
3554
|
+
end
|
3555
|
+
Zena::Db.date_condition(date_cond, field, ref_date)
|
3556
|
+
end
|
3557
|
+
end # ZenaTags
|
3558
|
+
end # Parser
|
3559
|
+
end # Zena
|