summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Magorsch <arzano@gentoo.org>2020-04-18 02:38:35 +0200
committerMax Magorsch <arzano@gentoo.org>2020-04-18 02:50:54 +0200
commit35a41e63ebd5f6cf9d17419c150eb53a005d2e87 (patch)
treee0bcc21bbb1e7e200857cfbd52acb82b008a3a6d
parentDisplay version and last update in the footer (diff)
downloadglsamaker-35a41e63ebd5f6cf9d17419c150eb53a005d2e87.tar.gz
glsamaker-35a41e63ebd5f6cf9d17419c150eb53a005d2e87.tar.bz2
glsamaker-35a41e63ebd5f6cf9d17419c150eb53a005d2e87.zip
Add the initial version of the rewritten glsamaker
The glsamaker has been completly rewritten in go. It is using postgres instead of mysql now. The look and feel is based on tyrian. Signed-off-by: Max Magorsch <arzano@gentoo.org>
-rw-r--r--.gitignore26
-rw-r--r--.gitlab-ci.yml32
-rw-r--r--.rubocop.yml27
-rw-r--r--.rubocop_todo.yml1369
-rw-r--r--.travis.yml29
-rw-r--r--Capfile4
-rw-r--r--Dockerfile26
-rw-r--r--Dockerfile.dev10
-rw-r--r--Gemfile60
-rw-r--r--Gemfile.lock206
-rw-r--r--LICENSE661
-rw-r--r--README243
-rw-r--r--Rakefile12
-rw-r--r--app/assets/images/biglogo.pngbin23122 -> 0 bytes
-rw-r--r--app/assets/images/cvetool-logo.pngbin5036 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/access.pngbin729 -> 0 bytes
-rw-r--r--app/assets/images/icons/admin.pngbin584 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/affected.pngbin768 -> 0 bytes
-rw-r--r--app/assets/images/icons/approval.pngbin754 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/approved.pngbin724 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/arch.pngbin740 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/atom.pngbin760 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/auto.pngbin652 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/background-go.pngbin558 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/background.pngbin371 -> 0 bytes
-rw-r--r--app/assets/images/icons/bug-grey.pngbin1444 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/bug.pngbin704 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/bug_add.pngbin773 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/bug_new.pngbin817 -> 0 bytes
-rw-r--r--app/assets/images/icons/calendar-select-month.pngbin627 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/checkboxes.pngbin512 -> 0 bytes
-rw-r--r--app/assets/images/icons/close.pngbin321 -> 0 bytes
-rw-r--r--app/assets/images/icons/comment.pngbin413 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/commented.pngbin744 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/confidential.pngbin778 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/delete.pngbin663 -> 0 bytes
-rw-r--r--app/assets/images/icons/diff.pngbin616 -> 0 bytes
-rw-r--r--app/assets/images/icons/dock-right.pngbin622 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/document-go.pngbin613 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/document.pngbin485 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/draft.pngbin805 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/edit-small.pngbin384 -> 0 bytes
-rw-r--r--app/assets/images/icons/edit.pngbin450 -> 0 bytes
-rw-r--r--app/assets/images/icons/error.pngbin874 -> 0 bytes
-rw-r--r--app/assets/images/icons/flag-green.pngbin777 -> 0 bytes
-rw-r--r--app/assets/images/icons/flag.pngbin728 -> 0 bytes
-rw-r--r--app/assets/images/icons/glsa.pngbin649 -> 0 bytes
-rw-r--r--app/assets/images/icons/glsa_draft.pngbin762 -> 0 bytes
-rw-r--r--app/assets/images/icons/glsa_new.pngbin714 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/glsa_ready.pngbin812 -> 0 bytes
-rw-r--r--app/assets/images/icons/glsa_request.pngbin756 -> 0 bytes
-rw-r--r--app/assets/images/icons/glsa_sent.pngbin760 -> 0 bytes
-rw-r--r--app/assets/images/icons/impact.pngbin742 -> 0 bytes
-rw-r--r--app/assets/images/icons/info.pngbin723 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/keyword.pngbin730 -> 0 bytes
-rw-r--r--app/assets/images/icons/larr.pngbin539 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/less_width.pngbin391 -> 0 bytes
-rw-r--r--app/assets/images/icons/logout.pngbin688 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/metadata.pngbin470 -> 0 bytes
-rw-r--r--app/assets/images/icons/minus-small.pngbin908 -> 0 bytes
-rw-r--r--app/assets/images/icons/minus.pngbin259 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/more_width.pngbin440 -> 0 bytes
-rw-r--r--app/assets/images/icons/next.pngbin658 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/not-approved.pngbin729 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/note.pngbin435 -> 0 bytes
-rw-r--r--app/assets/images/icons/ok.pngbin744 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/package-add.pngbin634 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/package-go.pngbin656 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/package-remove.pngbin554 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/package.pngbin524 -> 0 bytes
-rw-r--r--app/assets/images/icons/paste.pngbin605 -> 0 bytes
-rw-r--r--app/assets/images/icons/pending.pngbin748 -> 0 bytes
-rw-r--r--app/assets/images/icons/permission.pngbin612 -> 0 bytes
-rw-r--r--app/assets/images/icons/plus-small.pngbin992 -> 0 bytes
-rw-r--r--app/assets/images/icons/plus.pngbin476 -> 0 bytes
-rw-r--r--app/assets/images/icons/profile.pngbin533 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/public.pngbin687 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/reference-add.pngbin630 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/reference-remove.pngbin585 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/reference.pngbin537 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/refresh.pngbin835 -> 0 bytes
-rw-r--r--app/assets/images/icons/rejection.pngbin866 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/request.pngbin703 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/resolution-go.pngbin845 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/resolution.pngbin687 -> 0 bytes
-rw-r--r--app/assets/images/icons/restricted.pngbin501 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/sent.pngbin640 -> 0 bytes
-rw-r--r--app/assets/images/icons/severity.pngbin621 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/stamp.pngbin621 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/status-green.pngbin433 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/status-grey.pngbin448 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/status-red.pngbin439 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/status-yellow.pngbin457 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/switch.pngbin541 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/synopsis.pngbin522 -> 0 bytes
-rw-r--r--app/assets/images/icons/template.pngbin630 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/time.pngbin854 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/title.pngbin534 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/toolbox.pngbin501 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/txt.pngbin592 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/unaffected.pngbin801 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/user.pngbin511 -> 0 bytes
-rw-r--r--app/assets/images/icons/user_add.pngbin746 -> 0 bytes
-rw-r--r--app/assets/images/icons/warning.pngbin666 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/workaround-no.pngbin789 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/workaround.pngbin778 -> 0 bytes
-rw-r--r--app/assets/images/icons/xml.pngbin630 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/zoom_100.pngbin772 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/zoom_in.pngbin765 -> 0 bytes
-rwxr-xr-xapp/assets/images/icons/zoom_out.pngbin742 -> 0 bytes
-rw-r--r--app/assets/images/intel-editor.pngbin1316 -> 0 bytes
-rw-r--r--app/assets/images/line.pngbin42782 -> 0 bytes
-rw-r--r--app/assets/images/login-bg.pngbin32753 -> 0 bytes
-rw-r--r--app/assets/images/logo.pngbin10091 -> 0 bytes
-rw-r--r--app/assets/images/menu-left.pngbin1314 -> 0 bytes
-rw-r--r--app/assets/images/menu-right.pngbin1398 -> 0 bytes
-rw-r--r--app/assets/images/menubg.pngbin1412 -> 0 bytes
-rw-r--r--app/assets/images/rails.pngbin6646 -> 0 bytes
-rw-r--r--app/assets/images/separator.pngbin212 -> 0 bytes
-rw-r--r--app/assets/images/spinner.gifbin7823 -> 0 bytes
-rw-r--r--app/assets/javascripts/application.js14
-rw-r--r--app/assets/javascripts/glsamaker.js.erb151
-rw-r--r--app/assets/javascripts/glsamaker_edit.js181
-rw-r--r--app/assets/javascripts/glsamaker_misc.js102
-rw-r--r--app/assets/javascripts/jsui.js8
-rw-r--r--app/assets/javascripts/modalbox.js593
-rw-r--r--app/assets/javascripts/searchable.js71
-rw-r--r--app/assets/javascripts/uki-more.js827
-rw-r--r--app/assets/javascripts/uki.js8022
-rw-r--r--app/assets/stylesheets/admin.css54
-rw-r--r--app/assets/stylesheets/application.css10
-rw-r--r--app/assets/stylesheets/cve.css23
-rw-r--r--app/assets/stylesheets/login.css91
-rw-r--r--app/assets/stylesheets/modalbox.css122
-rw-r--r--app/assets/stylesheets/screen.css.erb662
-rw-r--r--app/controllers/admin/index_controller.rb6
-rw-r--r--app/controllers/admin/templates_controller.rb85
-rw-r--r--app/controllers/admin/users_controller.rb71
-rw-r--r--app/controllers/application_controller.rb32
-rw-r--r--app/controllers/bug_controller.rb39
-rw-r--r--app/controllers/bugs_controller.rb59
-rw-r--r--app/controllers/comments_controller.rb76
-rw-r--r--app/controllers/cve_controller.rb323
-rw-r--r--app/controllers/glsa_controller.rb562
-rw-r--r--app/controllers/index_controller.rb65
-rw-r--r--app/controllers/search_controller.rb37
-rw-r--r--app/controllers/tools_controller.rb86
-rw-r--r--app/helpers/admin/index_helper.rb2
-rw-r--r--app/helpers/admin/templates_helper.rb6
-rw-r--r--app/helpers/admin/users_helper.rb18
-rw-r--r--app/helpers/application_helper.rb168
-rw-r--r--app/helpers/bug_helper.rb8
-rw-r--r--app/helpers/bugs_helper.rb2
-rw-r--r--app/helpers/comments_helper.rb2
-rw-r--r--app/helpers/cve_helper.rb14
-rw-r--r--app/helpers/glsa_helper.rb200
-rw-r--r--app/helpers/index_helper.rb14
-rw-r--r--app/helpers/search_helper.rb2
-rw-r--r--app/helpers/tools_helper.rb14
-rw-r--r--app/indices/indices.rb34
-rw-r--r--app/mailers/glsa_mailer.rb45
-rw-r--r--app/models/bug.rb46
-rw-r--r--app/models/comment.rb44
-rw-r--r--app/models/cpe.rb29
-rw-r--r--app/models/cve.rb177
-rw-r--r--app/models/cve_assignment.rb3
-rw-r--r--app/models/cve_change.rb4
-rw-r--r--app/models/cve_comment.rb4
-rw-r--r--app/models/cve_reference.rb3
-rw-r--r--app/models/glsa.rb311
-rw-r--r--app/models/package.rb48
-rw-r--r--app/models/reference.rb15
-rw-r--r--app/models/revision.rb103
-rw-r--r--app/models/template.rb2
-rw-r--r--app/models/user.rb65
-rw-r--r--app/views/admin/index/index.html.erb6
-rw-r--r--app/views/admin/templates/_form.html.erb35
-rw-r--r--app/views/admin/templates/edit.html.erb8
-rw-r--r--app/views/admin/templates/index.html.erb23
-rw-r--r--app/views/admin/templates/new.html.erb7
-rw-r--r--app/views/admin/templates/show.html.erb26
-rw-r--r--app/views/admin/users/_user.html.erb9
-rw-r--r--app/views/admin/users/create.html.erb2
-rw-r--r--app/views/admin/users/destroy.html.erb2
-rw-r--r--app/views/admin/users/edit.html.erb50
-rw-r--r--app/views/admin/users/index.html.erb19
-rw-r--r--app/views/admin/users/new.html.erb47
-rw-r--r--app/views/admin/users/show.html.erb34
-rw-r--r--app/views/admin/users/update.html.erb2
-rw-r--r--app/views/bug/bug.html.erb58
-rw-r--r--app/views/bug/history.html.erb43
-rw-r--r--app/views/bugs/create.html.erb2
-rw-r--r--app/views/bugs/create.js.erb6
-rw-r--r--app/views/bugs/destroy.html.erb2
-rw-r--r--app/views/bugs/new.html.erb34
-rw-r--r--app/views/bugs/show.html.erb2
-rw-r--r--app/views/comments/create.js.erb10
-rw-r--r--app/views/comments/destroy.html.erb2
-rw-r--r--app/views/comments/new.html.erb25
-rw-r--r--app/views/comments/show.html.erb2
-rw-r--r--app/views/cve/_assigning.js.erb94
-rw-r--r--app/views/cve/_filing.js.erb170
-rw-r--r--app/views/cve/_invalidate.js.erb71
-rw-r--r--app/views/cve/_key_events.js.erb71
-rw-r--r--app/views/cve/_later.js.erb65
-rw-r--r--app/views/cve/_new.js.erb75
-rw-r--r--app/views/cve/_nfu.js.erb65
-rw-r--r--app/views/cve/_toolbar.js.erb54
-rw-r--r--app/views/cve/_ui_misc.js.erb115
-rw-r--r--app/views/cve/actions.html.erb5
-rw-r--r--app/views/cve/assign_preview.html.erb17
-rw-r--r--app/views/cve/bug_preview.html.erb81
-rw-r--r--app/views/cve/changes.html.erb10
-rw-r--r--app/views/cve/comments.html.erb10
-rw-r--r--app/views/cve/general_info.html.erb11
-rw-r--r--app/views/cve/index.html.erb0
-rw-r--r--app/views/cve/info.html.erb140
-rw-r--r--app/views/cve/info.json.jbuilder5
-rw-r--r--app/views/cve/list.html.erb135
-rw-r--r--app/views/cve/new_preview.html.erb7
-rw-r--r--app/views/cve/packages.html.erb22
-rw-r--r--app/views/cve/references.html.erb10
-rw-r--r--app/views/glsa/_approval_row.erb5
-rw-r--r--app/views/glsa/_close_msg.txt.erb3
-rw-r--r--app/views/glsa/_comment.html.erb27
-rw-r--r--app/views/glsa/_comments.html.erb11
-rw-r--r--app/views/glsa/_edit_bug_row.html.erb13
-rw-r--r--app/views/glsa/_email_headers.txt.erb3
-rw-r--r--app/views/glsa/_glsa.xml.builder74
-rw-r--r--app/views/glsa/_glsa_row.html.erb31
-rw-r--r--app/views/glsa/_package.html.erb16
-rw-r--r--app/views/glsa/_reference.html.erb10
-rw-r--r--app/views/glsa/_show_bug_row.html.erb7
-rw-r--r--app/views/glsa/_show_package_row.txt.erb49
-rw-r--r--app/views/glsa/_show_reference.txt.erb2
-rw-r--r--app/views/glsa/_status_legend.html.erb38
-rw-r--r--app/views/glsa/_template_popups.html.erb8
-rw-r--r--app/views/glsa/archive.html.erb26
-rw-r--r--app/views/glsa/archive.js.erb2
-rw-r--r--app/views/glsa/comment.html.erb2
-rw-r--r--app/views/glsa/create.html.erb2
-rw-r--r--app/views/glsa/destroy.html.erb2
-rw-r--r--app/views/glsa/diff.html.erb19
-rw-r--r--app/views/glsa/drafts.html.erb16
-rw-r--r--app/views/glsa/edit.html.erb177
-rw-r--r--app/views/glsa/finalize_release.html.erb29
-rw-r--r--app/views/glsa/import_references.html.erb16
-rw-r--r--app/views/glsa/new-draft.html.erb1
-rw-r--r--app/views/glsa/new-request.html.erb60
-rw-r--r--app/views/glsa/new.html.erb11
-rw-r--r--app/views/glsa/prepare_release.html.erb112
-rw-r--r--app/views/glsa/release.html.erb31
-rw-r--r--app/views/glsa/requests.html.erb16
-rw-r--r--app/views/glsa/show.html.erb158
-rw-r--r--app/views/glsa/show.txt.erb116
-rw-r--r--app/views/glsa/show.xml.erb1
-rw-r--r--app/views/glsa/update.html.erb2
-rw-r--r--app/views/glsa_mailer/approval.text.erb23
-rw-r--r--app/views/glsa_mailer/comment.text.erb8
-rw-r--r--app/views/glsa_mailer/edit.text.erb8
-rw-r--r--app/views/glsa_mailer/new_request.text.erb13
-rw-r--r--app/views/glsa_mailer/text.text.erb4
-rw-r--r--app/views/index/about.html.erb29
-rw-r--r--app/views/index/error-access.html.erb7
-rw-r--r--app/views/index/error-disabled.html.erb5
-rw-r--r--app/views/index/error-system.html.erb8
-rw-r--r--app/views/index/error-user.html.erb7
-rw-r--r--app/views/index/index.html.erb18
-rw-r--r--app/views/index/profile.html.erb34
-rw-r--r--app/views/layouts/application.html.erb96
-rw-r--r--app/views/layouts/cve.html.erb16
-rw-r--r--app/views/layouts/none.html.erb1
-rw-r--r--app/views/layouts/notice.html.erb24
-rw-r--r--app/views/search/_cve_row.html.erb6
-rw-r--r--app/views/search/_cves.html.erb13
-rw-r--r--app/views/search/_glsas.html.erb14
-rw-r--r--app/views/search/results.html.erb19
-rw-r--r--app/views/tools/_cve.html.erb4
-rw-r--r--app/views/tools/ajaxbugs.html.erb10
-rw-r--r--app/views/tools/ajaxdescr.html.erb3
-rw-r--r--app/views/tools/background.html.erb3
-rw-r--r--app/views/tools/template.js.erb7
-rw-r--r--assets/.keep (renamed from app/mailers/.gitkeep)0
-rw-r--r--bin/.keep (renamed from app/models/.gitkeep)0
-rwxr-xr-xbin/bundle3
-rwxr-xr-xbin/rails4
-rwxr-xr-xbin/rake4
-rwxr-xr-xbin/setup29
-rw-r--r--config.ru4
-rw-r--r--config/application.rb38
-rw-r--r--config/boot.rb3
-rw-r--r--config/database.yml.mysql42
-rw-r--r--config/deploy.rb37
-rw-r--r--config/environment.rb9
-rw-r--r--config/environments/development.rb41
-rw-r--r--config/environments/production.rb83
-rw-r--r--config/environments/test.rb42
-rw-r--r--config/initializers/assets.rb11
-rw-r--r--config/initializers/backtrace_silencers.rb7
-rw-r--r--config/initializers/cookies_serializer.rb3
-rw-r--r--config/initializers/filter_parameter_logging.rb4
-rw-r--r--config/initializers/glsamaker-global.rb2
-rw-r--r--config/initializers/glsamaker.rb.sample48
-rw-r--r--config/initializers/glsamaker_constants.rb1
-rw-r--r--config/initializers/inflections.rb20
-rw-r--r--config/initializers/mime_types.rb7
-rw-r--r--config/initializers/session_store.rb3
-rw-r--r--config/initializers/time_formats.rb1
-rw-r--r--config/initializers/wrap_parameters.rb14
-rw-r--r--config/locales/en.yml23
-rw-r--r--config/routes.rb96
-rw-r--r--config/secrets.yml22
-rw-r--r--config/thinking_sphinx.yml9
-rw-r--r--db/migrate/20090314092539_create_users.rb21
-rw-r--r--db/migrate/20090314191650_create_glsas.rb22
-rw-r--r--db/migrate/20090314194257_add_glsa_user_constraints.rb13
-rw-r--r--db/migrate/20090314194659_create_revisions.rb32
-rw-r--r--db/migrate/20090314230516_create_references.rb18
-rw-r--r--db/migrate/20090315105049_create_bugs.rb19
-rw-r--r--db/migrate/20090315105326_add_references_revisions_constraint.rb9
-rw-r--r--db/migrate/20090315110025_create_comments.rb18
-rw-r--r--db/migrate/20090315110119_add_comment_constraints.rb11
-rw-r--r--db/migrate/20090410212514_add_user_id_to_revisions.rb9
-rw-r--r--db/migrate/20090410212600_add_revisions_user_id_constraint.rb9
-rw-r--r--db/migrate/20090419140216_create_sessions.rb16
-rw-r--r--db/migrate/20090501114107_add_status_cache_to_bugs.rb11
-rw-r--r--db/migrate/20100511192546_change_comment_type_to_rating.rb9
-rw-r--r--db/migrate/20100513183324_create_packages.rb21
-rw-r--r--db/migrate/20100813183543_create_cves.rb19
-rw-r--r--db/migrate/20100814103856_create_cve_references.rb19
-rw-r--r--db/migrate/20100814105152_create_cve_comments.rb21
-rw-r--r--db/migrate/20100814105345_create_cve_changes.rb20
-rw-r--r--db/migrate/20100814142647_create_cpes.rb27
-rw-r--r--db/migrate/20100902093457_create_cve_assignments.rb23
-rw-r--r--db/migrate/20100918223549_add_system_user.rb12
-rw-r--r--db/migrate/20110226204724_add_release_flag_to_revisions.rb11
-rw-r--r--db/migrate/20110827143514_create_templates.rb12
-rw-r--r--db/migrate/20110829174909_add_first_release_date_to_glsa.rb5
-rw-r--r--db/migrate/20170418102638_add_slots_to_packages.rb11
-rw-r--r--db/schema.rb239
-rw-r--r--db/seeds.rb7
-rw-r--r--doc/README_FOR_APP29
-rw-r--r--doc/app/Admin.html278
-rw-r--r--doc/app/Admin/IndexController.html317
-rw-r--r--doc/app/Admin/IndexHelper.html261
-rw-r--r--doc/app/Admin/TemplatesController.html569
-rw-r--r--doc/app/Admin/TemplatesHelper.html310
-rw-r--r--doc/app/Admin/UsersController.html568
-rw-r--r--doc/app/Admin/UsersHelper.html354
-rw-r--r--doc/app/ApplicationController.html344
-rw-r--r--doc/app/ApplicationHelper.html661
-rw-r--r--doc/app/Authentication.html464
-rw-r--r--doc/app/Authorization.html435
-rw-r--r--doc/app/Bug.html423
-rw-r--r--doc/app/BugController.html383
-rw-r--r--doc/app/BugHelper.html311
-rw-r--r--doc/app/BugsController.html449
-rw-r--r--doc/app/BugsHelper.html261
-rw-r--r--doc/app/Bugzilla.html619
-rw-r--r--doc/app/Bugzilla/Bug.html859
-rw-r--r--doc/app/Bugzilla/Bugzilla.html268
-rw-r--r--doc/app/Bugzilla/Bugzilla/Bugzilla.html268
-rw-r--r--doc/app/Bugzilla/Bugzilla/Bugzilla/Change.html461
-rw-r--r--doc/app/Bugzilla/Comment.html372
-rw-r--r--doc/app/Bugzilla/History.html470
-rw-r--r--doc/app/Comment.html293
-rw-r--r--doc/app/Comment/CommentValidator.html328
-rw-r--r--doc/app/CommentsController.html459
-rw-r--r--doc/app/CommentsHelper.html261
-rw-r--r--doc/app/Cpe.html434
-rw-r--r--doc/app/Cve.html821
-rw-r--r--doc/app/CveAssignment.html269
-rw-r--r--doc/app/CveChange.html269
-rw-r--r--doc/app/CveComment.html269
-rw-r--r--doc/app/CveController.html1175
-rw-r--r--doc/app/CveHelper.html318
-rw-r--r--doc/app/CveReference.html269
-rw-r--r--doc/app/GLSAReleaseError.html269
-rw-r--r--doc/app/Glsa.html1086
-rw-r--r--doc/app/GlsaController.html1231
-rw-r--r--doc/app/GlsaHelper.html876
-rw-r--r--doc/app/GlsaMailer.html440
-rw-r--r--doc/app/Glsamaker.html388
-rw-r--r--doc/app/Glsamaker/Bugs.html279
-rw-r--r--doc/app/Glsamaker/Bugs/ArchesMixin.html310
-rw-r--r--doc/app/Glsamaker/Bugs/Bug.html376
-rw-r--r--doc/app/Glsamaker/Bugs/BugReadyMixin.html317
-rw-r--r--doc/app/Glsamaker/Bugs/Status.html580
-rw-r--r--doc/app/Glsamaker/Bugs/StatusMixin.html320
-rw-r--r--doc/app/Glsamaker/Diff.html338
-rw-r--r--doc/app/Glsamaker/HTTP.html323
-rw-r--r--doc/app/Glsamaker/Helper.html285
-rw-r--r--doc/app/Glsamaker/Mail.html498
-rw-r--r--doc/app/Glsamaker/Portage.html567
-rw-r--r--doc/app/Glsamaker/Portage/Description.html436
-rw-r--r--doc/app/Glsamaker/XML.html323
-rw-r--r--doc/app/IndexController.html487
-rw-r--r--doc/app/IndexHelper.html263
-rw-r--r--doc/app/Package.html332
-rw-r--r--doc/app/Reference.html271
-rw-r--r--doc/app/Revision.html524
-rw-r--r--doc/app/SearchController.html378
-rw-r--r--doc/app/SearchHelper.html261
-rw-r--r--doc/app/String.html435
-rw-r--r--doc/app/Template.html269
-rw-r--r--doc/app/ToolsController.html448
-rw-r--r--doc/app/ToolsHelper.html263
-rw-r--r--doc/app/User.html444
-rw-r--r--doc/app/app/controllers/admin/index_controller_rb.html52
-rw-r--r--doc/app/app/controllers/admin/templates_controller_rb.html52
-rw-r--r--doc/app/app/controllers/admin/users_controller_rb.html52
-rw-r--r--doc/app/app/controllers/application_controller_rb.html64
-rw-r--r--doc/app/app/controllers/bug_controller_rb.html64
-rw-r--r--doc/app/app/controllers/bugs_controller_rb.html63
-rw-r--r--doc/app/app/controllers/comments_controller_rb.html63
-rw-r--r--doc/app/app/controllers/cve_controller_rb.html52
-rw-r--r--doc/app/app/controllers/glsa_controller_rb.html64
-rw-r--r--doc/app/app/controllers/index_controller_rb.html64
-rw-r--r--doc/app/app/controllers/search_controller_rb.html52
-rw-r--r--doc/app/app/controllers/tools_controller_rb.html64
-rw-r--r--doc/app/app/helpers/admin/index_helper_rb.html52
-rw-r--r--doc/app/app/helpers/admin/templates_helper_rb.html52
-rw-r--r--doc/app/app/helpers/admin/users_helper_rb.html52
-rw-r--r--doc/app/app/helpers/application_helper_rb.html65
-rw-r--r--doc/app/app/helpers/bug_helper_rb.html52
-rw-r--r--doc/app/app/helpers/bugs_helper_rb.html52
-rw-r--r--doc/app/app/helpers/comments_helper_rb.html52
-rw-r--r--doc/app/app/helpers/cve_helper_rb.html52
-rw-r--r--doc/app/app/helpers/glsa_helper_rb.html64
-rw-r--r--doc/app/app/helpers/index_helper_rb.html64
-rw-r--r--doc/app/app/helpers/search_helper_rb.html52
-rw-r--r--doc/app/app/helpers/tools_helper_rb.html64
-rw-r--r--doc/app/app/mailers/glsa_mailer_rb.html52
-rw-r--r--doc/app/app/models/bug_rb.html64
-rw-r--r--doc/app/app/models/comment_rb.html64
-rw-r--r--doc/app/app/models/cpe_rb.html63
-rw-r--r--doc/app/app/models/cve_assignment_rb.html52
-rw-r--r--doc/app/app/models/cve_change_rb.html52
-rw-r--r--doc/app/app/models/cve_comment_rb.html52
-rw-r--r--doc/app/app/models/cve_rb.html65
-rw-r--r--doc/app/app/models/cve_reference_rb.html52
-rw-r--r--doc/app/app/models/glsa_rb.html64
-rw-r--r--doc/app/app/models/package_rb.html64
-rw-r--r--doc/app/app/models/reference_rb.html64
-rw-r--r--doc/app/app/models/revision_rb.html66
-rw-r--r--doc/app/app/models/template_rb.html52
-rw-r--r--doc/app/app/models/user_rb.html64
-rw-r--r--doc/app/created.rid56
-rw-r--r--doc/app/doc/README_FOR_APP.html260
-rw-r--r--doc/app/images/brick.pngbin452 -> 0 bytes
-rw-r--r--doc/app/images/brick_link.pngbin764 -> 0 bytes
-rw-r--r--doc/app/images/bug.pngbin774 -> 0 bytes
-rw-r--r--doc/app/images/bullet_black.pngbin211 -> 0 bytes
-rw-r--r--doc/app/images/bullet_toggle_minus.pngbin207 -> 0 bytes
-rw-r--r--doc/app/images/bullet_toggle_plus.pngbin209 -> 0 bytes
-rw-r--r--doc/app/images/date.pngbin626 -> 0 bytes
-rw-r--r--doc/app/images/find.pngbin659 -> 0 bytes
-rw-r--r--doc/app/images/loadingAnimation.gifbin5886 -> 0 bytes
-rw-r--r--doc/app/images/macFFBgHack.pngbin207 -> 0 bytes
-rw-r--r--doc/app/images/package.pngbin853 -> 0 bytes
-rw-r--r--doc/app/images/page_green.pngbin621 -> 0 bytes
-rw-r--r--doc/app/images/page_white_text.pngbin342 -> 0 bytes
-rw-r--r--doc/app/images/page_white_width.pngbin309 -> 0 bytes
-rw-r--r--doc/app/images/plugin.pngbin591 -> 0 bytes
-rw-r--r--doc/app/images/ruby.pngbin592 -> 0 bytes
-rw-r--r--doc/app/images/tag_green.pngbin613 -> 0 bytes
-rw-r--r--doc/app/images/wrench.pngbin610 -> 0 bytes
-rw-r--r--doc/app/images/wrench_orange.pngbin584 -> 0 bytes
-rw-r--r--doc/app/images/zoom.pngbin692 -> 0 bytes
-rw-r--r--doc/app/index.html612
-rw-r--r--doc/app/js/darkfish.js116
-rw-r--r--doc/app/js/jquery.js32
-rw-r--r--doc/app/js/quicksearch.js114
-rw-r--r--doc/app/js/thickbox-compressed.js10
-rw-r--r--doc/app/lib/authentication_rb.html64
-rw-r--r--doc/app/lib/authorization_rb.html63
-rw-r--r--doc/app/lib/bugzilla/bug_rb.html63
-rw-r--r--doc/app/lib/bugzilla/comment_rb.html63
-rw-r--r--doc/app/lib/bugzilla/history_rb.html54
-rw-r--r--doc/app/lib/bugzilla_rb.html72
-rw-r--r--doc/app/lib/glsamaker/bugs_rb.html66
-rw-r--r--doc/app/lib/glsamaker/diff_rb.html69
-rw-r--r--doc/app/lib/glsamaker/helpers_rb.html63
-rw-r--r--doc/app/lib/glsamaker/http_rb.html68
-rw-r--r--doc/app/lib/glsamaker/mail_rb.html63
-rw-r--r--doc/app/lib/glsamaker/portage_rb.html66
-rw-r--r--doc/app/lib/glsamaker/xml_rb.html63
-rw-r--r--doc/app/lib/glsamaker_rb.html76
-rw-r--r--doc/app/lib/tasks/utils_rb.html64
-rw-r--r--doc/app/rdoc.css763
-rw-r--r--doc/diagrams/models.dot18
-rw-r--r--doc/diagrams/models.pngbin112432 -> 0 bytes
-rw-r--r--docker-compose.override.yml60
-rw-r--r--docker-compose.yml55
-rw-r--r--glsamaker.go60
-rw-r--r--go.mod13
-rw-r--r--go.sum739
-rw-r--r--lib/assets/.gitkeep0
-rw-r--r--lib/authentication.rb111
-rw-r--r--lib/authorization.rb49
-rw-r--r--lib/bugzilla.rb195
-rw-r--r--lib/bugzilla/bug.rb143
-rw-r--r--lib/bugzilla/comment.rb22
-rw-r--r--lib/bugzilla/history.rb104
-rw-r--r--lib/glsamaker.rb23
-rw-r--r--lib/glsamaker/bugs.rb182
-rw-r--r--lib/glsamaker/diff.rb53
-rw-r--r--lib/glsamaker/helpers.rb21
-rw-r--r--lib/glsamaker/http.rb37
-rw-r--r--lib/glsamaker/mail.rb106
-rw-r--r--lib/glsamaker/portage.rb194
-rw-r--r--lib/glsamaker/spelling.rb48
-rw-r--r--lib/glsamaker/xml.rb31
-rw-r--r--lib/kramdown_ext.rb20
-rw-r--r--lib/tasks/.gitkeep0
-rw-r--r--lib/tasks/cve.rake366
-rw-r--r--lib/tasks/import.rake256
-rw-r--r--lib/tasks/rcov.rake81
-rw-r--r--lib/tasks/utils.rb35
-rw-r--r--package-lock.json8682
-rw-r--r--package.json41
-rw-r--r--pkg/app/handler/about/index.go28
-rw-r--r--pkg/app/handler/about/utils.go58
-rw-r--r--pkg/app/handler/account/password.go109
-rw-r--r--pkg/app/handler/account/twofactor.go200
-rw-r--r--pkg/app/handler/admin/edit.go293
-rw-r--r--pkg/app/handler/admin/index.go27
-rw-r--r--pkg/app/handler/admin/passwordreset.go73
-rw-r--r--pkg/app/handler/admin/utils.go112
-rw-r--r--pkg/app/handler/all/index.go40
-rw-r--r--pkg/app/handler/all/utils.go36
-rw-r--r--pkg/app/handler/archive/index.go44
-rw-r--r--pkg/app/handler/archive/utils.go36
-rw-r--r--pkg/app/handler/authentication/accessDenied.go10
-rw-r--r--pkg/app/handler/authentication/auth_session/authsession.go177
-rw-r--r--pkg/app/handler/authentication/login.go100
-rw-r--r--pkg/app/handler/authentication/logout.go29
-rw-r--r--pkg/app/handler/authentication/templates/admin.go36
-rw-r--r--pkg/app/handler/authentication/templates/login.go32
-rw-r--r--pkg/app/handler/authentication/templates/totp.go23
-rw-r--r--pkg/app/handler/authentication/templates/webauthn.go23
-rw-r--r--pkg/app/handler/authentication/totp/totp.go60
-rw-r--r--pkg/app/handler/authentication/utils/utils.go81
-rw-r--r--pkg/app/handler/authentication/webauthn/login.go118
-rw-r--r--pkg/app/handler/authentication/webauthn/register.go111
-rw-r--r--pkg/app/handler/cvetool/bug.go85
-rw-r--r--pkg/app/handler/cvetool/comments.go74
-rw-r--r--pkg/app/handler/cvetool/index.go169
-rw-r--r--pkg/app/handler/cvetool/state.go75
-rw-r--r--pkg/app/handler/cvetool/update.go23
-rw-r--r--pkg/app/handler/cvetool/utils.go47
-rw-r--r--pkg/app/handler/dashboard/index.go58
-rw-r--r--pkg/app/handler/dashboard/utils.go44
-rw-r--r--pkg/app/handler/drafts/index.go44
-rw-r--r--pkg/app/handler/drafts/utils.go37
-rw-r--r--pkg/app/handler/glsa/bugs.go63
-rw-r--r--pkg/app/handler/glsa/comments.go110
-rw-r--r--pkg/app/handler/glsa/delete.go42
-rw-r--r--pkg/app/handler/glsa/edit.go185
-rw-r--r--pkg/app/handler/glsa/release.go70
-rw-r--r--pkg/app/handler/glsa/utils.go79
-rw-r--r--pkg/app/handler/glsa/view.go48
-rw-r--r--pkg/app/handler/home/index.go16
-rw-r--r--pkg/app/handler/home/utils.go34
-rw-r--r--pkg/app/handler/newRequest/index.go186
-rw-r--r--pkg/app/handler/newRequest/utils.go36
-rw-r--r--pkg/app/handler/requests/index.go44
-rw-r--r--pkg/app/handler/requests/utils.go36
-rw-r--r--pkg/app/handler/search/index.go126
-rw-r--r--pkg/app/handler/search/utils.go38
-rw-r--r--pkg/app/handler/statistics/index.go42
-rw-r--r--pkg/app/handler/statistics/utils.go48
-rw-r--r--pkg/app/serve.go214
-rw-r--r--pkg/app/utils.go89
-rw-r--r--pkg/config/config.go63
-rw-r--r--pkg/cveimport/update.go96
-rw-r--r--pkg/database/connection/connection.go42
-rw-r--r--pkg/database/init.go23
-rw-r--r--pkg/database/schema/create.go36
-rw-r--r--pkg/logger/loggers.go39
-rw-r--r--pkg/models/application.go69
-rw-r--r--pkg/models/bugzilla/bugs.go156
-rw-r--r--pkg/models/cve/cve.go86
-rw-r--r--pkg/models/cve/cvss.go62
-rw-r--r--pkg/models/cve/feed.go116
-rw-r--r--pkg/models/glsa.go115
-rw-r--r--pkg/models/gpackage/package.go11
-rw-r--r--pkg/models/session.go15
-rw-r--r--pkg/models/users/user.go214
-rw-r--r--public/404.html30
-rw-r--r--public/422.html26
-rw-r--r--public/500.html29
-rw-r--r--public/error-404.pngbin18691 -> 0 bytes
-rw-r--r--public/error-500.pngbin7810 -> 0 bytes
-rw-r--r--public/favicon.ico0
-rw-r--r--public/robots.txt5
-rw-r--r--public/xsl/ads.xsl103
-rw-r--r--public/xsl/content.xsl35
-rw-r--r--public/xsl/devmap.xsl86
-rw-r--r--public/xsl/doc-struct.xsl185
-rw-r--r--public/xsl/glsa.xsl412
-rw-r--r--public/xsl/guide.xsl2015
-rw-r--r--public/xsl/handbook.xsl323
-rw-r--r--public/xsl/inserts.xsl401
-rw-r--r--public/xsl/mail.xsl183
-rw-r--r--public/xsl/menu.xsl57
-rw-r--r--public/xsl/util.xsl62
-rwxr-xr-xscript/config_init44
-rwxr-xr-xscript/db-backup29
-rwxr-xr-xscript/rails6
-rwxr-xr-xscript/update-portage-cache14
-rw-r--r--test/fixtures/.gitkeep0
-rw-r--r--test/fixtures/bugs.yml11
-rw-r--r--test/fixtures/comments.yml13
-rw-r--r--test/fixtures/cpes.yml7
-rw-r--r--test/fixtures/cve_assignments.yml9
-rw-r--r--test/fixtures/cve_changes.yml7
-rw-r--r--test/fixtures/cve_comments.yml7
-rw-r--r--test/fixtures/cve_references.yml7
-rw-r--r--test/fixtures/cves.yml13
-rw-r--r--test/fixtures/glsa_mailer/approval3
-rw-r--r--test/fixtures/glsa_mailer/comment3
-rw-r--r--test/fixtures/glsa_mailer/edit3
-rw-r--r--test/fixtures/glsa_mailer/request3
-rw-r--r--test/fixtures/glsa_mailer/sent3
-rw-r--r--test/fixtures/glsas.yml24
-rw-r--r--test/fixtures/packages.yml19
-rw-r--r--test/fixtures/references.yml11
-rw-r--r--test/fixtures/revisions.yml58
-rw-r--r--test/fixtures/templates.yml13
-rw-r--r--test/fixtures/users.yml49
-rw-r--r--test/functional/.gitkeep0
-rw-r--r--test/functional/admin/index_controller_test.rb15
-rw-r--r--test/functional/admin/templates_controller_test.rb56
-rw-r--r--test/functional/admin/users_controller_test.rb15
-rw-r--r--test/functional/bug_controller_test.rb8
-rw-r--r--test/functional/bugs_controller_test.rb4
-rw-r--r--test/functional/comments_controller_test.rb4
-rw-r--r--test/functional/cve_controller_test.rb8
-rw-r--r--test/functional/glsa_controller_test.rb83
-rw-r--r--test/functional/glsa_mailer_test.rb7
-rw-r--r--test/functional/index_controller_test.rb8
-rw-r--r--test/functional/search_controller_test.rb7
-rw-r--r--test/functional/tools_controller_test.rb8
-rw-r--r--test/integration/.gitkeep0
-rw-r--r--test/integration/authentication_test.rb20
-rw-r--r--test/test_helper.rb48
-rw-r--r--test/unit/.gitkeep0
-rw-r--r--test/unit/bug_test.rb8
-rw-r--r--test/unit/comment_test.rb54
-rw-r--r--test/unit/cpe_test.rb8
-rw-r--r--test/unit/cve_assignment_test.rb8
-rw-r--r--test/unit/cve_change_test.rb8
-rw-r--r--test/unit/cve_comment_test.rb8
-rw-r--r--test/unit/cve_reference_test.rb8
-rw-r--r--test/unit/cve_test.rb92
-rw-r--r--test/unit/glsa_mailer_test.rb4
-rw-r--r--test/unit/glsa_test.rb55
-rw-r--r--test/unit/helpers/bug_helper_test.rb4
-rw-r--r--test/unit/helpers/bugs_helper_test.rb4
-rw-r--r--test/unit/helpers/comments_helper_test.rb4
-rw-r--r--test/unit/helpers/cve_helper_test.rb4
-rw-r--r--test/unit/helpers/glsa_helper_test.rb4
-rw-r--r--test/unit/helpers/index_helper_test.rb4
-rw-r--r--test/unit/helpers/search_helper_test.rb4
-rw-r--r--test/unit/helpers/templates_helper_test.rb4
-rw-r--r--test/unit/helpers/tools_helper_test.rb4
-rw-r--r--test/unit/helpers/user_helper_test.rb4
-rw-r--r--test/unit/package_test.rb8
-rw-r--r--test/unit/reference_test.rb8
-rw-r--r--test/unit/revision_test.rb47
-rw-r--r--test/unit/template_test.rb7
-rw-r--r--test/unit/user_test.rb47
-rw-r--r--tmp/cache/.gitignore0
-rw-r--r--tmp/pids/.gitignore0
-rw-r--r--tmp/sessions/.gitignore0
-rw-r--r--tmp/sockets/.gitignore0
-rw-r--r--vendor/assets/stylesheets/.gitkeep0
-rw-r--r--vendor/dictionaries/README_en_US.txt278
-rw-r--r--vendor/dictionaries/en_US.aff3107
-rw-r--r--vendor/dictionaries/en_US.dic52895
-rw-r--r--vendor/plugins/.gitignore0
-rw-r--r--vendor/plugins/.gitkeep0
-rw-r--r--web/packs/account.js81
-rw-r--r--web/packs/admin.js60
-rw-r--r--web/packs/application.js69
-rw-r--r--web/packs/edit.js235
-rw-r--r--web/packs/glsa.js114
-rw-r--r--web/packs/newglsa.js58
-rw-r--r--web/packs/src/javascript/all.js37
-rw-r--r--web/packs/src/javascript/archive.js42
-rw-r--r--web/packs/src/javascript/cvetool.js535
-rw-r--r--web/packs/src/javascript/drafts.js38
-rw-r--r--web/packs/src/javascript/requests.js37
-rw-r--r--web/packs/src/stylesheets/application.scss11
-rw-r--r--web/packs/src/stylesheets/index.scss27
-rw-r--r--web/packs/statistics.js15
-rw-r--r--web/packs/stylesheets.js1
-rw-r--r--web/templates/about/about.tmpl31
-rw-r--r--web/templates/about/aboutCLI.tmpl30
-rw-r--r--web/templates/about/aboutSearch.tmpl71
-rw-r--r--web/templates/account/2fa.tmpl186
-rw-r--r--web/templates/account/password/forcedchange.tmpl98
-rw-r--r--web/templates/account/password/normalchange.tmpl45
-rw-r--r--web/templates/account/password/password.tmpl5
-rw-r--r--web/templates/admin/components/global.tmpl45
-rw-r--r--web/templates/admin/components/permissions.tmpl424
-rw-r--r--web/templates/admin/components/templates.tmpl10
-rw-r--r--web/templates/admin/components/users.tmpl226
-rw-r--r--web/templates/admin/edit/permissions.tmpl36
-rw-r--r--web/templates/admin/edit/users.tmpl37
-rw-r--r--web/templates/admin/passwordreset.tmpl35
-rw-r--r--web/templates/admin/view.tmpl41
-rw-r--r--web/templates/all/all.tmpl86
-rw-r--r--web/templates/archive/archive.tmpl75
-rw-r--r--web/templates/authentication/accessDenied.tmpl26
-rw-r--r--web/templates/authentication/login.tmpl113
-rw-r--r--web/templates/authentication/totp.tmpl94
-rw-r--r--web/templates/authentication/webauthn.tmpl204
-rw-r--r--web/templates/dashboard/dashboard.tmpl158
-rw-r--r--web/templates/drafts/drafts.tmpl84
-rw-r--r--web/templates/glsa/edit.tmpl768
-rw-r--r--web/templates/glsa/show.tmpl495
-rw-r--r--web/templates/home/home.tmpl166
-rw-r--r--web/templates/index/show.tmpl85
-rw-r--r--web/templates/index/showFullscreen.tmpl80
-rw-r--r--web/templates/layout/footer.tmpl50
-rw-r--r--web/templates/layout/head.tmpl12
-rw-r--r--web/templates/layout/header.tmpl6
-rw-r--r--web/templates/layout/sitetitle.tmpl37
-rw-r--r--web/templates/layout/tyriannav.tmpl72
-rw-r--r--web/templates/new/new.tmpl282
-rw-r--r--web/templates/requests/requests.tmpl84
-rw-r--r--web/templates/search/search.tmpl84
-rw-r--r--web/templates/statistics/statistics.tmpl89
-rw-r--r--webpack.config.js90
736 files changed, 20803 insertions, 117936 deletions
diff --git a/.gitignore b/.gitignore
index 66aa48d..07a09c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,23 +1,5 @@
-*.swp
-.DS_Store
-log/*
-tmp/*
-db/*.sqlite*
-config/database.yml
-config/*private*
-config/initializers/glsamaker.rb
-config/initializers/secret_token.rb
-public/stylesheets/all.css
-public/javascripts/all.js
-/.loadpath
-/MYTODO
-coverage
+node_modules/
+assets/
.idea
-.rvmrc
-*.tmproj
-*.sphinx.conf
-db/sphinx
-.bundle
-vendor
-Gemfile.lock
-doc/app/.cache/*
+
+.bin/glsamaker
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..d739110
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,32 @@
+stages:
+ - build
+ - test
+
+info:
+ stage: .pre
+ script:
+ - docker info
+
+build:
+ stage: build
+ variables:
+ IMAGE_TAG: $CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:$CI_COMMIT_SHA
+ LATEST_IMAGE_TAG: $CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:latest
+ script:
+ - echo $IMAGE_TAG
+ - echo $LATEST_IMAGE_TAG
+ - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin
+ - docker pull $LATEST_IMAGE_TAG || true
+ - docker build --cache-from $LATEST_IMAGE_TAG -t $IMAGE_TAG -t $LATEST_IMAGE_TAG .
+ - docker push $LATEST_IMAGE_TAG
+ - docker push $IMAGE_TAG
+
+include:
+ - template: Dependency-Scanning.gitlab-ci.yml
+ - template: Container-Scanning.gitlab-ci.yml
+ - template: SAST.gitlab-ci.yml
+
+variables:
+ DS_DISABLE_DIND: "true"
+ SAST_DISABLE_DIND: "true"
+
diff --git a/.rubocop.yml b/.rubocop.yml
deleted file mode 100644
index d379a78..0000000
--- a/.rubocop.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-inherit_from: .rubocop_todo.yml
-
-require:
- - rubocop-performance
- - rubocop-rails
-
-AllCops:
- TargetRubyVersion: 2.4
- TargetRailsVersion: 4.2
-
-Rails:
- Enabled: true
-
-Style/AsciiComments:
- Enabled: false
-
-Style/FormatString:
- Enabled: false
-
-Style/Documentation:
- Enabled: false
-
-Style/PerlBackrefs:
- Enabled: false
-
-Metrics/ModuleLength:
- Max: 200
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
deleted file mode 100644
index e265d63..0000000
--- a/.rubocop_todo.yml
+++ /dev/null
@@ -1,1369 +0,0 @@
-# This configuration was generated by
-# `rubocop --auto-gen-config`
-# on 2019-07-23 23:27:07 +0200 using RuboCop version 0.73.0.
-# The point is for the user to remove these configuration records
-# one by one as the offenses are removed from the code base.
-# Note that changes in the inspected code, or installation of new
-# versions of RuboCop, may require this file to be generated again.
-
-# Offense count: 7
-# Cop supports --auto-correct.
-# Configuration parameters: TreatCommentsAsGroupSeparators, Include.
-# Include: **/*.gemfile, **/Gemfile, **/gems.rb
-Bundler/OrderedGems:
- Exclude:
- - 'Gemfile'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, IndentationWidth.
-# SupportedStyles: outdent, indent
-Layout/AccessModifierIndentation:
- Exclude:
- - 'app/helpers/glsa_helper.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-Layout/AlignArray:
- Exclude:
- - 'lib/glsamaker/bugs.rb'
-
-# Offense count: 22
-# Cop supports --auto-correct.
-# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
-# SupportedHashRocketStyles: key, separator, table
-# SupportedColonStyles: key, separator, table
-# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
-Layout/AlignHash:
- Exclude:
- - 'app/mailers/glsa_mailer.rb'
- - 'app/models/package.rb'
- - 'app/views/glsa/_glsa.xml.builder'
- - 'lib/glsamaker/portage.rb'
- - 'lib/tasks/cve.rake'
- - 'test/unit/user_test.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Layout/BlockEndNewline:
- Exclude:
- - 'app/controllers/cve_controller.rb'
-
-# Offense count: 11
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, IndentOneStep, IndentationWidth.
-# SupportedStyles: case, end
-Layout/CaseIndentation:
- Exclude:
- - 'lib/tasks/rcov.rake'
- - 'test/test_helper.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-Layout/ClosingParenthesisIndentation:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'app/helpers/application_helper.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Layout/CommentIndentation:
- Exclude:
- - 'Gemfile'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: leading, trailing
-Layout/DotPosition:
- Exclude:
- - 'app/helpers/application_helper.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Layout/ElseAlignment:
- Exclude:
- - 'app/views/glsa/_glsa.xml.builder'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: AllowBorderComment, AllowMarginComment.
-Layout/EmptyComment:
- Exclude:
- - 'config/routes.rb'
-
-# Offense count: 16
-# Cop supports --auto-correct.
-Layout/EmptyLineAfterGuardClause:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'app/models/glsa.rb'
- - 'lib/glsamaker/portage.rb'
- - 'test/test_helper.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Layout/EmptyLineAfterMagicComment:
- Exclude:
- - 'db/schema.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: AllowAdjacentOneLineDefs, NumberOfEmptyLines.
-Layout/EmptyLineBetweenDefs:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Layout/EmptyLines:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
-
-# Offense count: 14
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: around, only_before
-Layout/EmptyLinesAroundAccessModifier:
- Exclude:
- - 'app/controllers/application_controller.rb'
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/helpers/glsa_helper.rb'
- - 'lib/authentication.rb'
- - 'lib/bugzilla.rb'
- - 'lib/bugzilla/bug.rb'
- - 'lib/glsamaker/bugs.rb'
- - 'lib/glsamaker/helpers.rb'
- - 'lib/glsamaker/mail.rb'
- - 'lib/glsamaker/portage.rb'
- - 'lib/glsamaker/xml.rb'
- - 'lib/tasks/utils.rb'
-
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: empty_lines, no_empty_lines
-Layout/EmptyLinesAroundBlockBody:
- Exclude:
- - 'config/environments/production.rb'
- - 'config/routes.rb'
- - 'db/schema.rb'
- - 'lib/tasks/import.rake'
-
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only
-Layout/EmptyLinesAroundClassBody:
- Exclude:
- - 'app/controllers/bug_controller.rb'
- - 'app/controllers/comments_controller.rb'
- - 'app/controllers/cve_controller.rb'
- - 'app/models/glsa.rb'
- - 'lib/glsamaker/bugs.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-Layout/EmptyLinesAroundMethodBody:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'lib/bugzilla.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines
-Layout/EmptyLinesAroundModuleBody:
- Exclude:
- - 'lib/glsamaker/diff.rb'
- - 'lib/glsamaker/mail.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyleAlignWith, AutoCorrect, Severity.
-# SupportedStylesAlignWith: keyword, variable, start_of_line
-Layout/EndAlignment:
- Exclude:
- - 'lib/tasks/rcov.rake'
-
-# Offense count: 18
-# Cop supports --auto-correct.
-# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
-Layout/ExtraSpacing:
- Exclude:
- - 'app/controllers/comments_controller.rb'
- - 'app/helpers/glsa_helper.rb'
- - 'app/views/cve/info.json.jbuilder'
- - 'bin/setup'
- - 'config.ru'
- - 'db/schema.rb'
- - 'script/db-backup'
- - 'script/rails'
-
-# Offense count: 4
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, IndentationWidth.
-# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
-Layout/IndentFirstArgument:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'app/helpers/application_helper.rb'
- - 'app/helpers/glsa_helper.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: IndentationWidth.
-# SupportedStyles: special_inside_parentheses, consistent, align_brackets
-Layout/IndentFirstArrayElement:
- EnforcedStyle: consistent
-
-# Offense count: 7
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, IndentationWidth.
-# SupportedStyles: special_inside_parentheses, consistent, align_braces
-Layout/IndentFirstHashElement:
- Exclude:
- - 'app/models/package.rb'
- - 'lib/bugzilla.rb'
- - 'lib/glsamaker/portage.rb'
-
-# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: normal, indented_internal_methods
-Layout/IndentationConsistency:
- Exclude:
- - 'app/models/glsa.rb'
- - 'lib/authentication.rb'
- - 'lib/tasks/import.rake'
-
-# Offense count: 25
-# Cop supports --auto-correct.
-# Configuration parameters: Width, IgnoredPatterns.
-Layout/IndentationWidth:
- Exclude:
- - 'app/views/glsa/_glsa.xml.builder'
- - 'db/migrate/20100814103856_create_cve_references.rb'
- - 'lib/authentication.rb'
- - 'lib/glsamaker/spelling.rb'
- - 'lib/tasks/import.rake'
-
-# Offense count: 31
-# Cop supports --auto-correct.
-# Configuration parameters: AllowDoxygenCommentStyle.
-Layout/LeadingCommentSpace:
- Exclude:
- - 'Gemfile'
- - 'app/controllers/application_controller.rb'
- - 'lib/bugzilla.rb'
- - 'lib/glsamaker.rb'
- - 'lib/tasks/import.rake'
- - 'script/db-backup'
- - 'test/unit/revision_test.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: symmetrical, new_line, same_line
-Layout/MultilineMethodCallBraceLayout:
- Exclude:
- - 'app/helpers/glsa_helper.rb'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, IndentationWidth.
-# SupportedStyles: aligned, indented, indented_relative_to_receiver
-Layout/MultilineMethodCallIndentation:
- Exclude:
- - 'app/helpers/application_helper.rb'
-
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, IndentationWidth.
-# SupportedStyles: aligned, indented
-Layout/MultilineOperationIndentation:
- Exclude:
- - 'db/migrate/20100918223549_add_system_user.rb'
- - 'lib/glsamaker/portage.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Layout/RescueEnsureAlignment:
- Exclude:
- - 'app/controllers/cve_controller.rb'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-Layout/SpaceAfterComma:
- Exclude:
- - 'app/helpers/glsa_helper.rb'
- - 'config/deploy.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyleInsidePipes.
-# SupportedStylesInsidePipes: space, no_space
-Layout/SpaceAroundBlockParameters:
- Exclude:
- - 'lib/tasks/rcov.rake'
-
-# Offense count: 11
-# Cop supports --auto-correct.
-# Configuration parameters: AllowForAlignment.
-Layout/SpaceAroundOperators:
- Exclude:
- - 'app/controllers/comments_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/helpers/glsa_helper.rb'
- - 'app/models/cve.rb'
- - 'app/models/package.rb'
- - 'script/db-backup'
-
-# Offense count: 22
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces.
-# SupportedStyles: space, no_space
-# SupportedStylesForEmptyBraces: space, no_space
-Layout/SpaceBeforeBlockBraces:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/helpers/admin/templates_helper.rb'
- - 'app/helpers/admin/users_helper.rb'
- - 'lib/tasks/rcov.rake'
- - 'test/unit/glsa_test.rb'
- - 'test/unit/revision_test.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Layout/SpaceBeforeComma:
- Exclude:
- - 'config/routes.rb'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-Layout/SpaceBeforeSemicolon:
- Exclude:
- - 'config/deploy.rb'
- - 'lib/bugzilla.rb'
-
-# Offense count: 72
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
-# SupportedStyles: space, no_space
-# SupportedStylesForEmptyBraces: space, no_space
-Layout/SpaceInsideBlockBraces:
- Enabled: false
-
-# Offense count: 67
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces.
-# SupportedStyles: space, no_space, compact
-# SupportedStylesForEmptyBraces: space, no_space
-Layout/SpaceInsideHashLiteralBraces:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/controllers/index_controller.rb'
- - 'app/controllers/tools_controller.rb'
- - 'app/helpers/glsa_helper.rb'
- - 'app/models/comment.rb'
- - 'app/models/glsa.rb'
- - 'app/views/glsa/_glsa.xml.builder'
- - 'config/deploy.rb'
- - 'lib/bugzilla.rb'
- - 'lib/glsamaker/http.rb'
- - 'lib/glsamaker/xml.rb'
- - 'test/test_helper.rb'
- - 'test/unit/glsa_test.rb'
-
-# Offense count: 8
-# Cop supports --auto-correct.
-Layout/SpaceInsidePercentLiteralDelimiters:
- Exclude:
- - 'config/application.rb'
- - 'config/initializers/glsamaker-global.rb'
- - 'lib/bugzilla.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 7
-# Cop supports --auto-correct.
-# Configuration parameters: IndentationWidth.
-Layout/Tab:
- Exclude:
- - 'app/views/glsa/_glsa.xml.builder'
-
-# Offense count: 286
-# Cop supports --auto-correct.
-# Configuration parameters: AllowInHeredoc.
-Layout/TrailingWhitespace:
- Enabled: false
-
-# Offense count: 1
-Lint/AmbiguousBlockAssociation:
- Exclude:
- - 'app/views/cve/info.json.jbuilder'
-
-# Offense count: 1
-Lint/DuplicateMethods:
- Exclude:
- - 'lib/bugzilla/bug.rb'
-
-# Offense count: 2
-# Configuration parameters: AllowComments.
-Lint/HandleExceptions:
- Exclude:
- - 'Rakefile'
- - 'app/controllers/bugs_controller.rb'
-
-# Offense count: 1
-Lint/IneffectiveAccessModifier:
- Exclude:
- - 'lib/authentication.rb'
-
-# Offense count: 2
-Lint/NestedMethodDefinition:
- Exclude:
- - 'app/models/cve.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 3
-Lint/NonLocalExitFromIterator:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
-
-# Offense count: 38
-Lint/RescueException:
- Exclude:
- - 'app/controllers/bugs_controller.rb'
- - 'app/controllers/comments_controller.rb'
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/controllers/tools_controller.rb'
- - 'app/models/bug.rb'
- - 'app/models/glsa.rb'
- - 'lib/bugzilla/bug.rb'
- - 'lib/bugzilla/history.rb'
- - 'lib/glsamaker/bugs.rb'
- - 'lib/tasks/rcov.rake'
- - 'script/config_init'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Lint/ScriptPermission:
- Exclude:
- - 'Rakefile'
-
-# Offense count: 7
-# Cop supports --auto-correct.
-Lint/StringConversionInInterpolation:
- Exclude:
- - 'lib/bugzilla/history.rb'
- - 'test/functional/glsa_controller_test.rb'
-
-# Offense count: 2
-# Configuration parameters: AllowKeywordBlockArguments.
-Lint/UnderscorePrefixedVariableName:
- Exclude:
- - 'lib/glsamaker/bugs.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 2
-Lint/UnreachableCode:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
-
-# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
-Lint/UnusedBlockArgument:
- Exclude:
- - 'app/helpers/glsa_helper.rb'
- - 'app/models/glsa.rb'
- - 'lib/glsamaker/portage.rb'
-
-# Offense count: 4
-# Cop supports --auto-correct.
-# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
-Lint/UnusedMethodArgument:
- Exclude:
- - 'app/models/glsa.rb'
- - 'lib/glsamaker/portage.rb'
- - 'lib/kramdown_ext.rb'
-
-# Offense count: 16
-Lint/UselessAssignment:
- Exclude:
- - 'app/controllers/bug_controller.rb'
- - 'app/controllers/bugs_controller.rb'
- - 'app/controllers/comments_controller.rb'
- - 'app/controllers/search_controller.rb'
- - 'app/models/cve.rb'
- - 'lib/bugzilla.rb'
- - 'lib/bugzilla/bug.rb'
- - 'lib/bugzilla/history.rb'
- - 'lib/glsamaker/bugs.rb'
- - 'lib/tasks/cve.rake'
- - 'lib/tasks/import.rake'
-
-# Offense count: 6
-Metrics/AbcSize:
- Max: 172
-
-# Offense count: 14
-# Configuration parameters: CountComments, ExcludedMethods.
-# ExcludedMethods: refine
-Metrics/BlockLength:
- Max: 192
-
-# Offense count: 3
-# Configuration parameters: CountBlocks.
-Metrics/BlockNesting:
- Max: 4
-
-# Offense count: 5
-# Configuration parameters: CountComments.
-Metrics/ClassLength:
- Max: 441
-
-# Offense count: 18
-Metrics/CyclomaticComplexity:
- Max: 24
-
-# Offense count: 24
-# Cop supports --auto-correct.
-# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
-# URISchemes: http, https
-Metrics/LineLength:
- Max: 312
-
-# Offense count: 26
-# Configuration parameters: CountComments, ExcludedMethods.
-Metrics/MethodLength:
- Max: 105
-
-# Offense count: 1
-# Configuration parameters: CountKeywordArgs.
-Metrics/ParameterLists:
- Max: 6
-
-# Offense count: 14
-Metrics/PerceivedComplexity:
- Max: 19
-
-# Offense count: 1
-Naming/AccessorMethodName:
- Exclude:
- - 'app/models/revision.rb'
-
-# Offense count: 1
-# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
-# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
-Naming/FileName:
- Exclude:
- - 'config/initializers/glsamaker-global.rb'
-
-# Offense count: 1
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: snake_case, camelCase
-Naming/MethodName:
- Exclude:
- - 'lib/bugzilla/bug.rb'
-
-# Offense count: 7
-# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist, MethodDefinitionMacros.
-# NamePrefix: is_, has_, have_
-# NamePrefixBlacklist: is_, has_, have_
-# NameWhitelist: is_a?
-# MethodDefinitionMacros: define_method, define_singleton_method
-Naming/PredicateName:
- Exclude:
- - 'spec/**/*'
- - 'app/helpers/glsa_helper.rb'
- - 'app/models/glsa.rb'
- - 'app/models/user.rb'
- - 'lib/glsamaker/portage.rb'
-
-# Offense count: 8
-# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
-# AllowedNames: io, id, to, by, on, in, at, ip, db
-Naming/UncommunicativeMethodParamName:
- Exclude:
- - 'app/helpers/application_helper.rb'
- - 'app/helpers/glsa_helper.rb'
- - 'app/models/cve.rb'
- - 'lib/glsamaker/portage.rb'
- - 'lib/kramdown_ext.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 18
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: snake_case, camelCase
-Naming/VariableName:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/controllers/index_controller.rb'
-
-# Offense count: 1
-Performance/Caller:
- Exclude:
- - 'app/controllers/application_controller.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-Performance/CompareWithBlock:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Performance/RedundantBlockCall:
- Exclude:
- - 'app/helpers/application_helper.rb'
-
-# Offense count: 5
-# Cop supports --auto-correct.
-Performance/RegexpMatch:
- Exclude:
- - 'lib/glsamaker/spelling.rb'
- - 'lib/tasks/cve.rake'
- - 'lib/tasks/rcov.rake'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Performance/StringReplacement:
- Exclude:
- - 'lib/glsamaker/xml.rb'
-
-# Offense count: 1
-Performance/UnfreezeString:
- Exclude:
- - 'lib/tasks/rcov.rake'
-
-# Offense count: 6
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, Include.
-# SupportedStyles: action, filter
-# Include: app/controllers/**/*.rb
-Rails/ActionFilter:
- Exclude:
- - 'app/controllers/admin/index_controller.rb'
- - 'app/controllers/admin/templates_controller.rb'
- - 'app/controllers/admin/users_controller.rb'
- - 'app/controllers/application_controller.rb'
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/index_controller.rb'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-Rails/ActiveRecordAliases:
- Exclude:
- - 'app/controllers/admin/templates_controller.rb'
- - 'app/controllers/admin/users_controller.rb'
- - 'app/models/bug.rb'
-
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: Include.
-# Include: **/test/**/*
-Rails/AssertNot:
- Exclude:
- - 'test/unit/glsa_test.rb'
- - 'test/unit/user_test.rb'
-
-# Offense count: 3
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: strict, flexible
-Rails/Date:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: Whitelist.
-# Whitelist: find_by_sql
-Rails/DynamicFindBy:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'lib/authentication.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 4
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: slashes, arguments
-Rails/FilePath:
- Exclude:
- - 'lib/bugzilla.rb'
- - 'lib/glsamaker/spelling.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: Include.
-# Include: app/models/**/*.rb
-Rails/FindEach:
- Exclude:
- - 'app/models/revision.rb'
-
-# Offense count: 2
-# Configuration parameters: Include.
-# Include: app/models/**/*.rb
-Rails/HasAndBelongsToMany:
- Exclude:
- - 'app/models/cpe.rb'
- - 'app/models/cve.rb'
-
-# Offense count: 9
-# Configuration parameters: Include.
-# Include: app/models/**/*.rb
-Rails/HasManyOrHasOneDependent:
- Exclude:
- - 'app/models/cve.rb'
- - 'app/models/user.rb'
-
-# Offense count: 1
-# Configuration parameters: Include.
-# Include: app/helpers/**/*.rb
-Rails/HelperInstanceVariable:
- Exclude:
- - 'app/helpers/glsa_helper.rb'
-
-# Offense count: 21
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: numeric, symbolic
-Rails/HttpStatus:
- Exclude:
- - 'app/controllers/bugs_controller.rb'
- - 'app/controllers/comments_controller.rb'
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/controllers/tools_controller.rb'
-
-# Offense count: 15
-# Configuration parameters: Include.
-# Include: app/models/**/*.rb
-Rails/InverseOf:
- Exclude:
- - 'app/models/comment.rb'
- - 'app/models/cve.rb'
- - 'app/models/cve_change.rb'
- - 'app/models/cve_comment.rb'
- - 'app/models/glsa.rb'
- - 'app/models/revision.rb'
- - 'app/models/user.rb'
-
-# Offense count: 4
-Rails/OutputSafety:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'app/helpers/application_helper.rb'
- - 'lib/glsamaker/spelling.rb'
-
-# Offense count: 1
-# Configuration parameters: Blacklist, Whitelist.
-# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
-Rails/SkipsModelValidations:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
-
-# Offense count: 11
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: strict, flexible
-Rails/TimeZone:
- Exclude:
- - 'app/models/glsa.rb'
- - 'lib/authorization.rb'
- - 'lib/bugzilla/bug.rb'
- - 'lib/bugzilla/comment.rb'
- - 'lib/bugzilla/history.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: Include.
-# Include: app/models/**/*.rb
-Rails/Validation:
- Exclude:
- - 'app/models/glsa.rb'
- - 'app/models/revision.rb'
- - 'app/models/user.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Security/YAMLLoad:
- Exclude:
- - 'script/config_init'
-
-# Offense count: 1
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: inline, group
-Style/AccessModifierDeclarations:
- Exclude:
- - 'lib/glsamaker/http.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: prefer_alias, prefer_alias_method
-Style/Alias:
- Exclude:
- - 'lib/bugzilla/bug.rb'
-
-# Offense count: 28
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: always, conditionals
-Style/AndOr:
- Exclude:
- - 'app/controllers/application_controller.rb'
- - 'app/controllers/comments_controller.rb'
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/helpers/application_helper.rb'
- - 'app/models/cve.rb'
- - 'app/models/glsa.rb'
- - 'app/models/user.rb'
- - 'lib/authentication.rb'
- - 'lib/bugzilla.rb'
- - 'lib/glsamaker/bugs.rb'
- - 'lib/glsamaker/diff.rb'
- - 'lib/glsamaker/portage.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Style/BlockComments:
- Exclude:
- - 'app/models/revision.rb'
-
-# Offense count: 13
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods, AllowBracesOnProceduralOneLiners.
-# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
-# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
-# FunctionalMethods: let, let!, subject, watch
-# IgnoredMethods: lambda, proc, it
-Style/BlockDelimiters:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'config/deploy.rb'
- - 'lib/glsamaker/http.rb'
- - 'test/unit/cve_test.rb'
-
-# Offense count: 13
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: braces, no_braces, context_dependent
-Style/BracesAroundHashParameters:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/views/glsa/_glsa.xml.builder'
- - 'config/deploy.rb'
- - 'lib/bugzilla.rb'
- - 'lib/glsamaker/http.rb'
- - 'test/integration/authentication_test.rb'
-
-# Offense count: 11
-# Cop supports --auto-correct.
-# Configuration parameters: AutoCorrect, EnforcedStyle.
-# SupportedStyles: nested, compact
-Style/ClassAndModuleChildren:
- Exclude:
- - 'app/controllers/admin/index_controller.rb'
- - 'app/controllers/admin/templates_controller.rb'
- - 'app/controllers/admin/users_controller.rb'
- - 'app/helpers/admin/index_helper.rb'
- - 'app/helpers/admin/templates_helper.rb'
- - 'app/helpers/admin/users_helper.rb'
- - 'lib/bugzilla/history.rb'
- - 'test/functional/admin/index_controller_test.rb'
- - 'test/functional/admin/templates_controller_test.rb'
- - 'test/functional/admin/users_controller_test.rb'
- - 'test/test_helper.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Style/ColonMethodCall:
- Exclude:
- - 'app/models/cve.rb'
-
-# Offense count: 13
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
-# SupportedStyles: assign_to_condition, assign_inside_condition
-Style/ConditionalAssignment:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'app/helpers/application_helper.rb'
- - 'app/models/cve.rb'
- - 'lib/glsamaker/bugs.rb'
- - 'lib/glsamaker/portage.rb'
- - 'lib/glsamaker/spelling.rb'
- - 'lib/tasks/import.rake'
- - 'lib/tasks/rcov.rake'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Style/DefWithParentheses:
- Exclude:
- - 'lib/bugzilla/bug.rb'
-
-# Offense count: 4
-# Cop supports --auto-correct.
-Style/EmptyLiteral:
- Exclude:
- - 'lib/tasks/import.rake'
- - 'lib/tasks/rcov.rake'
-
-# Offense count: 6
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: compact, expanded
-Style/EmptyMethod:
- Exclude:
- - 'app/controllers/admin/index_controller.rb'
- - 'app/controllers/bugs_controller.rb'
- - 'app/controllers/comments_controller.rb'
- - 'app/controllers/search_controller.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Style/Encoding:
- Exclude:
- - 'db/schema.rb'
-
-# Offense count: 10
-# Cop supports --auto-correct.
-Style/ExpandPathArguments:
- Exclude:
- - 'Rakefile'
- - 'bin/bundle'
- - 'bin/rails'
- - 'bin/setup'
- - 'config/application.rb'
- - 'config/boot.rb'
- - 'config/environment.rb'
- - 'script/rails'
- - 'test/test_helper.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: each, for
-Style/For:
- Exclude:
- - 'lib/tasks/rcov.rake'
-
-# Offense count: 13
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: annotated, template, unannotated
-Style/FormatStringToken:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/helpers/application_helper.rb'
- - 'app/models/cve.rb'
-
-# Offense count: 159
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: always, never
-Style/FrozenStringLiteralComment:
- Enabled: false
-
-# Offense count: 17
-# Configuration parameters: MinBodyLength.
-Style/GuardClause:
- Exclude:
- - 'app/controllers/admin/users_controller.rb'
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/models/comment.rb'
- - 'app/models/glsa.rb'
- - 'lib/authentication.rb'
- - 'lib/bugzilla.rb'
- - 'lib/bugzilla/bug.rb'
- - 'lib/glsamaker/bugs.rb'
- - 'lib/glsamaker/mail.rb'
- - 'lib/glsamaker/portage.rb'
-
-# Offense count: 550
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
-# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
-Style/HashSyntax:
- Enabled: false
-
-# Offense count: 5
-# Configuration parameters: AllowIfModifier.
-Style/IfInsideElse:
- Exclude:
- - 'app/helpers/application_helper.rb'
- - 'lib/glsamaker/bugs.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 40
-# Cop supports --auto-correct.
-Style/IfUnlessModifier:
- Enabled: false
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: InverseMethods, InverseBlocks.
-Style/InverseMethods:
- Exclude:
- - 'app/views/glsa/_glsa.xml.builder'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Style/LineEndConcatenation:
- Exclude:
- - 'db/migrate/20100918223549_add_system_user.rb'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-# Configuration parameters: IgnoredMethods.
-Style/MethodCallWithoutArgsParentheses:
- Exclude:
- - 'app/helpers/glsa_helper.rb'
- - 'lib/tasks/import.rake'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-Style/MultilineIfThen:
- Exclude:
- - 'lib/authentication.rb'
- - 'script/db-backup'
-
-# Offense count: 18
-# Cop supports --auto-correct.
-Style/MultilineWhenThen:
- Exclude:
- - 'lib/bugzilla/bug.rb'
-
-# Offense count: 14
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: literals, strict
-Style/MutableConstant:
- Exclude:
- - 'config/environment.rb'
- - 'config/initializers/glsamaker-global.rb'
- - 'config/initializers/glsamaker.rb'
- - 'lib/kramdown_ext.rb'
- - 'lib/tasks/cve.rake'
- - 'lib/tasks/import.rake'
- - 'script/db-backup'
-
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: both, prefix, postfix
-Style/NegatedIf:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'app/models/glsa.rb'
- - 'lib/tasks/import.rake'
-
-# Offense count: 4
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, MinBodyLength.
-# SupportedStyles: skip_modifier_ifs, always
-Style/Next:
- Exclude:
- - 'app/controllers/tools_controller.rb'
- - 'lib/tasks/import.rake'
-
-# Offense count: 18
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: predicate, comparison
-Style/NilComparison:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/controllers/index_controller.rb'
- - 'app/controllers/tools_controller.rb'
- - 'app/models/user.rb'
- - 'lib/authentication.rb'
- - 'lib/bugzilla/history.rb'
- - 'lib/tasks/import.rake'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-# Configuration parameters: IncludeSemanticChanges.
-Style/NonNilCheck:
- Exclude:
- - 'lib/glsamaker/bugs.rb'
- - 'lib/glsamaker/portage.rb'
-
-# Offense count: 10
-# Cop supports --auto-correct.
-Style/Not:
- Exclude:
- - 'app/controllers/search_controller.rb'
- - 'app/models/glsa.rb'
- - 'app/models/user.rb'
- - 'lib/glsamaker/bugs.rb'
- - 'lib/tasks/import.rake'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedOctalStyle.
-# SupportedOctalStyles: zero_with_o, zero_only
-Style/NumericLiteralPrefix:
- Exclude:
- - 'lib/bugzilla.rb'
- - 'script/config_init'
-
-# Offense count: 24
-# Cop supports --auto-correct.
-# Configuration parameters: Strict.
-Style/NumericLiterals:
- MinDigits: 15
-
-# Offense count: 28
-# Cop supports --auto-correct.
-# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
-# SupportedStyles: predicate, comparison
-Style/NumericPredicate:
- Exclude:
- - 'spec/**/*'
- - 'app/controllers/admin/users_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/controllers/tools_controller.rb'
- - 'app/models/glsa.rb'
- - 'app/models/user.rb'
- - 'app/views/glsa/_glsa.xml.builder'
- - 'lib/authorization.rb'
- - 'lib/bugzilla/bug.rb'
- - 'lib/glsamaker/bugs.rb'
- - 'lib/glsamaker/diff.rb'
- - 'lib/tasks/cve.rake'
- - 'lib/tasks/import.rake'
-
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: PreferredDelimiters.
-Style/PercentLiteralDelimiters:
- Exclude:
- - 'app/models/package.rb'
- - 'config/application.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 38
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: short, verbose
-Style/PreferredHashMethods:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'app/helpers/application_helper.rb'
- - 'lib/bugzilla.rb'
- - 'lib/bugzilla/history.rb'
- - 'lib/glsamaker/xml.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Style/Proc:
- Exclude:
- - 'app/models/comment.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-Style/RedundantBegin:
- Exclude:
- - 'app/controllers/bugs_controller.rb'
- - 'app/controllers/comments_controller.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Style/RedundantException:
- Exclude:
- - 'lib/authentication.rb'
-
-# Offense count: 8
-# Cop supports --auto-correct.
-# Configuration parameters: AllowMultipleReturnValues.
-Style/RedundantReturn:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/models/glsa.rb'
- - 'app/models/revision.rb'
- - 'lib/authentication.rb'
- - 'lib/glsamaker/bugs.rb'
-
-# Offense count: 38
-# Cop supports --auto-correct.
-Style/RedundantSelf:
- Exclude:
- - 'app/models/bug.rb'
- - 'app/models/cpe.rb'
- - 'app/models/cve.rb'
- - 'app/models/glsa.rb'
- - 'app/models/package.rb'
- - 'app/models/revision.rb'
- - 'app/models/user.rb'
- - 'lib/bugzilla/bug.rb'
- - 'lib/glsamaker/bugs.rb'
-
-# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
-# SupportedStyles: slashes, percent_r, mixed
-Style/RegexpLiteral:
- Exclude:
- - 'app/controllers/tools_controller.rb'
- - 'app/helpers/glsa_helper.rb'
- - 'app/models/glsa.rb'
- - 'app/models/package.rb'
- - 'lib/glsamaker/portage.rb'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: implicit, explicit
-Style/RescueStandardError:
- Exclude:
- - 'app/helpers/application_helper.rb'
- - 'lib/tasks/import.rake'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Style/SelfAssignment:
- Exclude:
- - 'lib/tasks/rcov.rake'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: only_raise, only_fail, semantic
-Style/SignalException:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'lib/tasks/cve.rake'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: .
-# SupportedStyles: use_perl_names, use_english_names
-Style/SpecialGlobalVars:
- EnforcedStyle: use_perl_names
-
-# Offense count: 4
-# Cop supports --auto-correct.
-Style/StderrPuts:
- Exclude:
- - 'lib/tasks/cve.rake'
- - 'lib/tasks/rcov.rake'
- - 'script/config_init'
-
-# Offense count: 809
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
-# SupportedStyles: single_quotes, double_quotes
-Style/StringLiterals:
- Enabled: false
-
-# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: single_quotes, double_quotes
-Style/StringLiteralsInInterpolation:
- Exclude:
- - 'app/helpers/glsa_helper.rb'
- - 'app/models/cve.rb'
- - 'app/models/glsa.rb'
-
-# Offense count: 11
-# Cop supports --auto-correct.
-# Configuration parameters: MinSize.
-# SupportedStyles: percent, brackets
-Style/SymbolArray:
- EnforcedStyle: brackets
-
-# Offense count: 17
-# Cop supports --auto-correct.
-# Configuration parameters: IgnoredMethods.
-# IgnoredMethods: respond_to, define_method
-Style/SymbolProc:
- Exclude:
- - 'app/controllers/cve_controller.rb'
- - 'app/controllers/glsa_controller.rb'
- - 'app/models/cve.rb'
- - 'app/models/glsa.rb'
- - 'app/models/revision.rb'
- - 'app/views/cve/info.json.jbuilder'
- - 'lib/glsamaker/diff.rb'
- - 'lib/tasks/rcov.rake'
- - 'test/unit/glsa_test.rb'
- - 'test/unit/revision_test.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
-# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
-Style/TernaryParentheses:
- Exclude:
- - 'app/views/glsa/_glsa.xml.builder'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyleForMultiline.
-# SupportedStylesForMultiline: comma, consistent_comma, no_comma
-Style/TrailingCommaInHashLiteral:
- Exclude:
- - 'lib/bugzilla.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist.
-# Whitelist: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym
-Style/TrivialAccessors:
- Exclude:
- - 'lib/glsamaker/bugs.rb'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-Style/UnlessElse:
- Exclude:
- - 'app/controllers/bugs_controller.rb'
- - 'app/controllers/comments_controller.rb'
- - 'lib/bugzilla/history.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-Style/UnneededInterpolation:
- Exclude:
- - 'app/views/glsa/_glsa.xml.builder'
- - 'lib/tasks/rcov.rake'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Style/UnpackFirst:
- Exclude:
- - 'lib/authentication.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: WordRegex.
-# SupportedStyles: percent, brackets
-Style/WordArray:
- EnforcedStyle: percent
- MinSize: 6
-
-# Offense count: 11
-# Cop supports --auto-correct.
-Style/ZeroLengthPredicate:
- Exclude:
- - 'app/controllers/glsa_controller.rb'
- - 'app/controllers/tools_controller.rb'
- - 'app/models/glsa.rb'
- - 'app/views/glsa/_glsa.xml.builder'
- - 'lib/bugzilla/bug.rb'
- - 'lib/tasks/cve.rake'
- - 'lib/tasks/import.rake'
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index d69e055..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-language: ruby
-cache: bundler
-rvm:
- - 2.4
- - 2.5
-
-gemfiles:
- - Gemfile
-
-branches:
- only:
- - master
-
-addons:
- mariadb: '10.2'
-
-before_install:
- - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
- - gem install bundler -v '< 2'
-
-
-before_script:
- - sed 's/i_forgot_to_set_this/"test-secret"/' < config/initializers/glsamaker.rb.sample > config/initializers/glsamaker.rb
- - cp config/database.yml.mysql config/database.yml
- - mysql -e 'CREATE DATABASE glsamaker_test;'
-
-script:
- - bundle exec rubocop
- - bundle exec rake test RAILS_ENV=test
diff --git a/Capfile b/Capfile
deleted file mode 100644
index 1a98f3c..0000000
--- a/Capfile
+++ /dev/null
@@ -1,4 +0,0 @@
-load 'deploy' if respond_to?(:namespace) # cap2 differentiator
-Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
-
-load 'config/deploy' # remove this line to skip loading any of the default tasks
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..9a13fa3
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,26 @@
+FROM golang:1.14.0 AS builder
+WORKDIR /go/src/glsamaker
+COPY . /go/src/glsamaker
+RUN go get github.com/go-pg/pg/v9
+RUN go get github.com/google/uuid
+RUN go get github.com/skip2/go-qrcode
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin .
+
+FROM node:13 AS assetsbuilder
+WORKDIR /go/src/glsamaker
+COPY . /go/src/glsamaker
+RUN npm install && cd node_modules/@gentoo/tyrian && npm install && npm run dist && cd /go/src/glsamaker
+RUN npx webpack
+
+FROM alpine:latest as certs
+RUN apk --update add ca-certificates
+
+FROM scratch
+WORKDIR /go/src/glsamaker
+COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
+COPY --from=assetsbuilder /go/src/glsamaker/assets /go/src/glsamaker/assets
+COPY --from=builder /go/src/glsamaker/bin /go/src/glsamaker/bin
+COPY --from=builder /go/src/glsamaker/pkg /go/src/glsamaker/pkg
+COPY --from=builder /go/src/glsamaker/web /go/src/glsamaker/web
+
+CMD ["/go/src/glsamaker/bin/glsamaker"]
diff --git a/Dockerfile.dev b/Dockerfile.dev
new file mode 100644
index 0000000..902fd47
--- /dev/null
+++ b/Dockerfile.dev
@@ -0,0 +1,10 @@
+FROM golang:1.14.0
+RUN apt update && apt install -y ca-certificates ntp ntpdate
+WORKDIR /go/src/glsamaker
+COPY . /go/src/glsamaker
+RUN go get github.com/go-pg/pg/v9
+RUN go get github.com/google/uuid
+RUN go get github.com/skip2/go-qrcode
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin .
+
+CMD ["/go/src/glsamaker/bin/glsamaker"]
diff --git a/Gemfile b/Gemfile
deleted file mode 100644
index ea8c8dc..0000000
--- a/Gemfile
+++ /dev/null
@@ -1,60 +0,0 @@
-source 'https://rubygems.org'
-
-gem 'rails', '~> 4.2'
-gem 'xmlrpc'
-gem 'rake'
-
-gem 'mysql2', '~> 0.4.10'
-
-gem 'json', '~> 2.0'
-gem 'jbuilder', '~> 2.0'
-
-# Gems used only for assets and not required
-# in production environments by default.
-#group :assets do
-# gem 'sass-rails', "~> 3.2.0"
-# gem 'coffee-rails', "~> 3.2.0"
-# gem 'uglifier'
-#end
-
-gem 'prototype-rails', github: 'rails/prototype-rails', branch: '4.2'
-
-# Use unicorn as the web server
-#gem 'unicorn'
-gem 'thin'
-
-# Deploy with Capistrano
-gem 'capistrano'
-
-# gem 'exception_notification'
-
-group :development do
-# No debugger at the moment because of the stupid build system of a dependency of ruby-debug19
-# gem 'ruby-debug', :platforms => :ruby_18
-# gem 'ruby-debug19', :platforms => :ruby_19
-# gem 'require_relative'
-end
-
-gem 'diff-lcs', require: 'diff/lcs'
-gem 'nokogiri'
-gem 'text-format-revised', require: 'text/format'
-gem 'kramdown'
-
-gem 'thinking-sphinx', '~> 3.1.4'
-
-#FIXME: runspell 0.0.1 is dead since 2011, we may need
-#to create a new spelling module
-
-#gem 'runspell'
-
-# gem "rdoc"
-
-group :test do
- gem 'simplecov'
- gem 'ci_reporter'
- gem 'minitest-reporters'
-
- gem 'rubocop'
- gem 'rubocop-performance'
- gem 'rubocop-rails'
-end
diff --git a/Gemfile.lock b/Gemfile.lock
deleted file mode 100644
index 48a2d90..0000000
--- a/Gemfile.lock
+++ /dev/null
@@ -1,206 +0,0 @@
-GIT
- remote: git://github.com/rails/prototype-rails.git
- revision: 0fed929ff48c10c3b978edd3baa983a81f404dbf
- branch: 4.2
- specs:
- prototype-rails (4.0.0)
- rails (~> 4.0)
-
-GEM
- remote: https://rubygems.org/
- specs:
- actionmailer (4.2.11.1)
- actionpack (= 4.2.11.1)
- actionview (= 4.2.11.1)
- activejob (= 4.2.11.1)
- mail (~> 2.5, >= 2.5.4)
- rails-dom-testing (~> 1.0, >= 1.0.5)
- actionpack (4.2.11.1)
- actionview (= 4.2.11.1)
- activesupport (= 4.2.11.1)
- rack (~> 1.6)
- rack-test (~> 0.6.2)
- rails-dom-testing (~> 1.0, >= 1.0.5)
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
- actionview (4.2.11.1)
- activesupport (= 4.2.11.1)
- builder (~> 3.1)
- erubis (~> 2.7.0)
- rails-dom-testing (~> 1.0, >= 1.0.5)
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
- activejob (4.2.11.1)
- activesupport (= 4.2.11.1)
- globalid (>= 0.3.0)
- activemodel (4.2.11.1)
- activesupport (= 4.2.11.1)
- builder (~> 3.1)
- activerecord (4.2.11.1)
- activemodel (= 4.2.11.1)
- activesupport (= 4.2.11.1)
- arel (~> 6.0)
- activesupport (4.2.11.1)
- i18n (~> 0.7)
- minitest (~> 5.1)
- thread_safe (~> 0.3, >= 0.3.4)
- tzinfo (~> 1.1)
- airbrussh (1.3.2)
- sshkit (>= 1.6.1, != 1.7.0)
- ansi (1.5.0)
- arel (6.0.4)
- ast (2.4.0)
- builder (3.2.3)
- capistrano (3.11.0)
- airbrussh (>= 1.0.0)
- i18n
- rake (>= 10.0.0)
- sshkit (>= 1.9.0)
- ci_reporter (2.0.0)
- builder (>= 2.1.2)
- concurrent-ruby (1.1.5)
- crass (1.0.4)
- daemons (1.3.1)
- diff-lcs (1.3)
- docile (1.3.2)
- erubis (2.7.0)
- eventmachine (1.2.7)
- globalid (0.4.2)
- activesupport (>= 4.2.0)
- i18n (0.9.5)
- concurrent-ruby (~> 1.0)
- innertube (1.1.0)
- jaro_winkler (1.5.3)
- jbuilder (2.9.1)
- activesupport (>= 4.2.0)
- joiner (0.3.4)
- activerecord (>= 4.1.0)
- json (2.2.0)
- kramdown (2.1.0)
- loofah (2.2.3)
- crass (~> 1.0.2)
- nokogiri (>= 1.5.9)
- mail (2.7.1)
- mini_mime (>= 0.1.1)
- middleware (0.1.0)
- mini_mime (1.0.2)
- mini_portile2 (2.4.0)
- minitest (5.11.3)
- minitest-reporters (1.3.6)
- ansi
- builder
- minitest (>= 5.0)
- ruby-progressbar
- mysql2 (0.4.10)
- net-scp (2.0.0)
- net-ssh (>= 2.6.5, < 6.0.0)
- net-ssh (5.2.0)
- nokogiri (1.10.3)
- mini_portile2 (~> 2.4.0)
- parallel (1.17.0)
- parser (2.6.3.0)
- ast (~> 2.4.0)
- rack (1.6.11)
- rack-test (0.6.3)
- rack (>= 1.0)
- rails (4.2.11.1)
- actionmailer (= 4.2.11.1)
- actionpack (= 4.2.11.1)
- actionview (= 4.2.11.1)
- activejob (= 4.2.11.1)
- activemodel (= 4.2.11.1)
- activerecord (= 4.2.11.1)
- activesupport (= 4.2.11.1)
- bundler (>= 1.3.0, < 2.0)
- railties (= 4.2.11.1)
- sprockets-rails
- rails-deprecated_sanitizer (1.0.3)
- activesupport (>= 4.2.0.alpha)
- rails-dom-testing (1.0.9)
- activesupport (>= 4.2.0, < 5.0)
- nokogiri (~> 1.6)
- rails-deprecated_sanitizer (>= 1.0.1)
- rails-html-sanitizer (1.0.4)
- loofah (~> 2.2, >= 2.2.2)
- railties (4.2.11.1)
- actionpack (= 4.2.11.1)
- activesupport (= 4.2.11.1)
- rake (>= 0.8.7)
- thor (>= 0.18.1, < 2.0)
- rainbow (3.0.0)
- rake (12.3.3)
- riddle (2.3.2)
- rubocop (0.73.0)
- jaro_winkler (~> 1.5.1)
- parallel (~> 1.10)
- parser (>= 2.6)
- rainbow (>= 2.2.2, < 4.0)
- ruby-progressbar (~> 1.7)
- unicode-display_width (>= 1.4.0, < 1.7)
- rubocop-performance (1.4.0)
- rubocop (>= 0.71.0)
- rubocop-rails (2.2.1)
- rack (>= 1.1)
- rubocop (>= 0.72.0)
- ruby-progressbar (1.10.1)
- simplecov (0.17.0)
- docile (~> 1.1)
- json (>= 1.8, < 3)
- simplecov-html (~> 0.10.0)
- simplecov-html (0.10.2)
- sprockets (3.7.2)
- concurrent-ruby (~> 1.0)
- rack (> 1, < 3)
- sprockets-rails (3.2.1)
- actionpack (>= 4.0)
- activesupport (>= 4.0)
- sprockets (>= 3.0.0)
- sshkit (1.19.1)
- net-scp (>= 1.1.2)
- net-ssh (>= 2.8.0)
- text-format-revised (1.1.0)
- text-hyphen (~> 1.2.0)
- text-hyphen (1.2)
- thin (1.7.2)
- daemons (~> 1.0, >= 1.0.9)
- eventmachine (~> 1.0, >= 1.0.4)
- rack (>= 1, < 3)
- thinking-sphinx (3.1.4)
- activerecord (>= 3.1.0)
- builder (>= 2.1.2)
- innertube (>= 1.0.2)
- joiner (>= 0.2.0)
- middleware (>= 0.1.0)
- riddle (>= 1.5.11)
- thor (0.20.3)
- thread_safe (0.3.6)
- tzinfo (1.2.5)
- thread_safe (~> 0.1)
- unicode-display_width (1.6.0)
- xmlrpc (0.3.0)
-
-PLATFORMS
- ruby
-
-DEPENDENCIES
- capistrano
- ci_reporter
- diff-lcs
- jbuilder (~> 2.0)
- json (~> 2.0)
- kramdown
- minitest-reporters
- mysql2 (~> 0.4.10)
- nokogiri
- prototype-rails!
- rails (~> 4.2)
- rake
- rubocop
- rubocop-performance
- rubocop-rails
- simplecov
- text-format-revised
- thin
- thinking-sphinx (~> 3.1.4)
- xmlrpc
-
-BUNDLED WITH
- 1.17.3
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 2def0e8..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,661 +0,0 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
- A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate. Many developers of free software are heartened and
-encouraged by the resulting cooperation. However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
- The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community. It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server. Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
- An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals. This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU Affero General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Remote Network Interaction; Use with the GNU General Public License.
-
- Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software. This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source. For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code. There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-<http://www.gnu.org/licenses/>. \ No newline at end of file
diff --git a/README b/README
deleted file mode 100644
index 37ec8ea..0000000
--- a/README
+++ /dev/null
@@ -1,243 +0,0 @@
-== Welcome to Rails
-
-Rails is a web-application framework that includes everything needed to create
-database-backed web applications according to the Model-View-Control pattern.
-
-This pattern splits the view (also called the presentation) into "dumb" templates
-that are primarily responsible for inserting pre-built data in between HTML tags.
-The model contains the "smart" domain objects (such as Account, Product, Person,
-Post) that holds all the business logic and knows how to persist themselves to
-a database. The controller handles the incoming requests (such as Save New Account,
-Update Product, Show Post) by manipulating the model and directing data to the view.
-
-In Rails, the model is handled by what's called an object-relational mapping
-layer entitled Active Record. This layer allows you to present the data from
-database rows as objects and embellish these data objects with business logic
-methods. You can read more about Active Record in
-link:files/vendor/rails/activerecord/README.html.
-
-The controller and view are handled by the Action Pack, which handles both
-layers by its two parts: Action View and Action Controller. These two layers
-are bundled in a single package due to their heavy interdependence. This is
-unlike the relationship between the Active Record and Action Pack that is much
-more separate. Each of these packages can be used independently outside of
-Rails. You can read more about Action Pack in
-link:files/vendor/rails/actionpack/README.html.
-
-
-== Getting Started
-
-1. At the command prompt, start a new Rails application using the <tt>rails</tt> command
- and your application name. Ex: rails myapp
-2. Change directory into myapp and start the web server: <tt>script/server</tt> (run with --help for options)
-3. Go to http://localhost:3000/ and get "Welcome aboard: You're riding the Rails!"
-4. Follow the guidelines to start developing your application
-
-
-== Web Servers
-
-By default, Rails will try to use Mongrel if it's are installed when started with script/server, otherwise Rails will use WEBrick, the webserver that ships with Ruby. But you can also use Rails
-with a variety of other web servers.
-
-Mongrel is a Ruby-based webserver with a C component (which requires compilation) that is
-suitable for development and deployment of Rails applications. If you have Ruby Gems installed,
-getting up and running with mongrel is as easy as: <tt>gem install mongrel</tt>.
-More info at: http://mongrel.rubyforge.org
-
-Say other Ruby web servers like Thin and Ebb or regular web servers like Apache or LiteSpeed or
-Lighttpd or IIS. The Ruby web servers are run through Rack and the latter can either be setup to use
-FCGI or proxy to a pack of Mongrels/Thin/Ebb servers.
-
-== Apache .htaccess example for FCGI/CGI
-
-# General Apache options
-AddHandler fastcgi-script .fcgi
-AddHandler cgi-script .cgi
-Options +FollowSymLinks +ExecCGI
-
-# If you don't want Rails to look in certain directories,
-# use the following rewrite rules so that Apache won't rewrite certain requests
-#
-# Example:
-# RewriteCond %{REQUEST_URI} ^/notrails.*
-# RewriteRule .* - [L]
-
-# Redirect all requests not available on the filesystem to Rails
-# By default the cgi dispatcher is used which is very slow
-#
-# For better performance replace the dispatcher with the fastcgi one
-#
-# Example:
-# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
-RewriteEngine On
-
-# If your Rails application is accessed via an Alias directive,
-# then you MUST also set the RewriteBase in this htaccess file.
-#
-# Example:
-# Alias /myrailsapp /path/to/myrailsapp/public
-# RewriteBase /myrailsapp
-
-RewriteRule ^$ index.html [QSA]
-RewriteRule ^([^.]+)$ $1.html [QSA]
-RewriteCond %{REQUEST_FILENAME} !-f
-RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
-
-# In case Rails experiences terminal errors
-# Instead of displaying this message you can supply a file here which will be rendered instead
-#
-# Example:
-# ErrorDocument 500 /500.html
-
-ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"
-
-
-== Debugging Rails
-
-Sometimes your application goes wrong. Fortunately there are a lot of tools that
-will help you debug it and get it back on the rails.
-
-First area to check is the application log files. Have "tail -f" commands running
-on the server.log and development.log. Rails will automatically display debugging
-and runtime information to these files. Debugging info will also be shown in the
-browser on requests from 127.0.0.1.
-
-You can also log your own messages directly into the log file from your code using
-the Ruby logger class from inside your controllers. Example:
-
- class WeblogController < ActionController::Base
- def destroy
- @weblog = Weblog.find(params[:id])
- @weblog.destroy
- logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
- end
- end
-
-The result will be a message in your log file along the lines of:
-
- Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1
-
-More information on how to use the logger is at http://www.ruby-doc.org/core/
-
-Also, Ruby documentation can be found at http://www.ruby-lang.org/ including:
-
-* The Learning Ruby (Pickaxe) Book: http://www.ruby-doc.org/docs/ProgrammingRuby/
-* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
-
-These two online (and free) books will bring you up to speed on the Ruby language
-and also on programming in general.
-
-
-== Debugger
-
-Debugger support is available through the debugger command when you start your Mongrel or
-Webrick server with --debugger. This means that you can break out of execution at any point
-in the code, investigate and change the model, AND then resume execution!
-You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'
-Example:
-
- class WeblogController < ActionController::Base
- def index
- @posts = Post.find(:all)
- debugger
- end
- end
-
-So the controller will accept the action, run the first line, then present you
-with a IRB prompt in the server window. Here you can do things like:
-
- >> @posts.inspect
- => "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
- #<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
- >> @posts.first.title = "hello from a debugger"
- => "hello from a debugger"
-
-...and even better is that you can examine how your runtime objects actually work:
-
- >> f = @posts.first
- => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
- >> f.
- Display all 152 possibilities? (y or n)
-
-Finally, when you're ready to resume execution, you enter "cont"
-
-
-== Console
-
-You can interact with the domain model by starting the console through <tt>script/console</tt>.
-Here you'll have all parts of the application configured, just like it is when the
-application is running. You can inspect domain models, change values, and save to the
-database. Starting the script without arguments will launch it in the development environment.
-Passing an argument will specify a different environment, like <tt>script/console production</tt>.
-
-To reload your controllers and models after launching the console run <tt>reload!</tt>
-
-== dbconsole
-
-You can go to the command line of your database directly through <tt>script/dbconsole</tt>.
-You would be connected to the database with the credentials defined in database.yml.
-Starting the script without arguments will connect you to the development database. Passing an
-argument will connect you to a different database, like <tt>script/dbconsole production</tt>.
-Currently works for mysql, postgresql and sqlite.
-
-== Description of Contents
-
-app
- Holds all the code that's specific to this particular application.
-
-app/controllers
- Holds controllers that should be named like weblogs_controller.rb for
- automated URL mapping. All controllers should descend from ApplicationController
- which itself descends from ActionController::Base.
-
-app/models
- Holds models that should be named like post.rb.
- Most models will descend from ActiveRecord::Base.
-
-app/views
- Holds the template files for the view that should be named like
- weblogs/index.html.erb for the WeblogsController#index action. All views use eRuby
- syntax.
-
-app/views/layouts
- Holds the template files for layouts to be used with views. This models the common
- header/footer method of wrapping views. In your views, define a layout using the
- <tt>layout :default</tt> and create a file named default.html.erb. Inside default.html.erb,
- call <% yield %> to render the view using this layout.
-
-app/helpers
- Holds view helpers that should be named like weblogs_helper.rb. These are generated
- for you automatically when using script/generate for controllers. Helpers can be used to
- wrap functionality for your views into methods.
-
-config
- Configuration files for the Rails environment, the routing map, the database, and other dependencies.
-
-db
- Contains the database schema in schema.rb. db/migrate contains all
- the sequence of Migrations for your schema.
-
-doc
- This directory is where your application documentation will be stored when generated
- using <tt>rake doc:app</tt>
-
-lib
- Application specific libraries. Basically, any kind of custom code that doesn't
- belong under controllers, models, or helpers. This directory is in the load path.
-
-public
- The directory available for the web server. Contains subdirectories for images, stylesheets,
- and javascripts. Also contains the dispatchers and the default HTML files. This should be
- set as the DOCUMENT_ROOT of your web server.
-
-script
- Helper scripts for automation and generation.
-
-test
- Unit and functional tests along with fixtures. When using the script/generate scripts, template
- test files will be generated for you and placed in this directory.
-
-vendor
- External libraries that the application depends on. Also includes the plugins subdirectory.
- If the app has frozen rails, those gems also go here, under vendor/rails/.
- This directory is in the load path.
diff --git a/Rakefile b/Rakefile
deleted file mode 100644
index 463f2f4..0000000
--- a/Rakefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env rake
-# Add your own tasks in files placed in lib/tasks ending in .rake,
-# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
-
-require File.expand_path('../config/application', __FILE__)
-
-Glsamaker::Application.load_tasks
-
-begin
- require 'ci/reporter/rake/test_unit'
-rescue LoadError
-end
diff --git a/app/assets/images/biglogo.png b/app/assets/images/biglogo.png
deleted file mode 100644
index 58fc589..0000000
--- a/app/assets/images/biglogo.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/cvetool-logo.png b/app/assets/images/cvetool-logo.png
deleted file mode 100644
index 2546cc7..0000000
--- a/app/assets/images/cvetool-logo.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/access.png b/app/assets/images/icons/access.png
deleted file mode 100755
index a9e1d4a..0000000
--- a/app/assets/images/icons/access.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/admin.png b/app/assets/images/icons/admin.png
deleted file mode 100644
index 565a933..0000000
--- a/app/assets/images/icons/admin.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/affected.png b/app/assets/images/icons/affected.png
deleted file mode 100755
index 25ea793..0000000
--- a/app/assets/images/icons/affected.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/approval.png b/app/assets/images/icons/approval.png
deleted file mode 100644
index a12a1d0..0000000
--- a/app/assets/images/icons/approval.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/approved.png b/app/assets/images/icons/approved.png
deleted file mode 100755
index 210b1a6..0000000
--- a/app/assets/images/icons/approved.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/arch.png b/app/assets/images/icons/arch.png
deleted file mode 100755
index 9db64b5..0000000
--- a/app/assets/images/icons/arch.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/atom.png b/app/assets/images/icons/atom.png
deleted file mode 100755
index 200a5fd..0000000
--- a/app/assets/images/icons/atom.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/auto.png b/app/assets/images/icons/auto.png
deleted file mode 100755
index 19dfc93..0000000
--- a/app/assets/images/icons/auto.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/background-go.png b/app/assets/images/icons/background-go.png
deleted file mode 100755
index acaea0f..0000000
--- a/app/assets/images/icons/background-go.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/background.png b/app/assets/images/icons/background.png
deleted file mode 100755
index be7001f..0000000
--- a/app/assets/images/icons/background.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/bug-grey.png b/app/assets/images/icons/bug-grey.png
deleted file mode 100644
index a6f8396..0000000
--- a/app/assets/images/icons/bug-grey.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/bug.png b/app/assets/images/icons/bug.png
deleted file mode 100755
index 242d539..0000000
--- a/app/assets/images/icons/bug.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/bug_add.png b/app/assets/images/icons/bug_add.png
deleted file mode 100755
index fe12b19..0000000
--- a/app/assets/images/icons/bug_add.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/bug_new.png b/app/assets/images/icons/bug_new.png
deleted file mode 100755
index 9076cc5..0000000
--- a/app/assets/images/icons/bug_new.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/calendar-select-month.png b/app/assets/images/icons/calendar-select-month.png
deleted file mode 100644
index 4f5ed55..0000000
--- a/app/assets/images/icons/calendar-select-month.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/checkboxes.png b/app/assets/images/icons/checkboxes.png
deleted file mode 100755
index 05eed23..0000000
--- a/app/assets/images/icons/checkboxes.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/close.png b/app/assets/images/icons/close.png
deleted file mode 100644
index 237ae2a..0000000
--- a/app/assets/images/icons/close.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/comment.png b/app/assets/images/icons/comment.png
deleted file mode 100644
index 7bc9233..0000000
--- a/app/assets/images/icons/comment.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/commented.png b/app/assets/images/icons/commented.png
deleted file mode 100755
index 9926e5d..0000000
--- a/app/assets/images/icons/commented.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/confidential.png b/app/assets/images/icons/confidential.png
deleted file mode 100755
index ec71aec..0000000
--- a/app/assets/images/icons/confidential.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/delete.png b/app/assets/images/icons/delete.png
deleted file mode 100755
index 70b59dc..0000000
--- a/app/assets/images/icons/delete.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/diff.png b/app/assets/images/icons/diff.png
deleted file mode 100644
index d4d1b56..0000000
--- a/app/assets/images/icons/diff.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/dock-right.png b/app/assets/images/icons/dock-right.png
deleted file mode 100644
index 0e51904..0000000
--- a/app/assets/images/icons/dock-right.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/document-go.png b/app/assets/images/icons/document-go.png
deleted file mode 100755
index f3e265d..0000000
--- a/app/assets/images/icons/document-go.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/document.png b/app/assets/images/icons/document.png
deleted file mode 100755
index 75f92b0..0000000
--- a/app/assets/images/icons/document.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/draft.png b/app/assets/images/icons/draft.png
deleted file mode 100755
index 0e2b42d..0000000
--- a/app/assets/images/icons/draft.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/edit-small.png b/app/assets/images/icons/edit-small.png
deleted file mode 100755
index 3d81c2f..0000000
--- a/app/assets/images/icons/edit-small.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/edit.png b/app/assets/images/icons/edit.png
deleted file mode 100644
index 0bfecd5..0000000
--- a/app/assets/images/icons/edit.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/error.png b/app/assets/images/icons/error.png
deleted file mode 100644
index 0496522..0000000
--- a/app/assets/images/icons/error.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/flag-green.png b/app/assets/images/icons/flag-green.png
deleted file mode 100644
index 6747730..0000000
--- a/app/assets/images/icons/flag-green.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/flag.png b/app/assets/images/icons/flag.png
deleted file mode 100644
index 5c008b0..0000000
--- a/app/assets/images/icons/flag.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/glsa.png b/app/assets/images/icons/glsa.png
deleted file mode 100644
index 779ad58..0000000
--- a/app/assets/images/icons/glsa.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/glsa_draft.png b/app/assets/images/icons/glsa_draft.png
deleted file mode 100644
index c61a6d8..0000000
--- a/app/assets/images/icons/glsa_draft.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/glsa_new.png b/app/assets/images/icons/glsa_new.png
deleted file mode 100644
index d5eac9b..0000000
--- a/app/assets/images/icons/glsa_new.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/glsa_ready.png b/app/assets/images/icons/glsa_ready.png
deleted file mode 100755
index c17bb7d..0000000
--- a/app/assets/images/icons/glsa_ready.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/glsa_request.png b/app/assets/images/icons/glsa_request.png
deleted file mode 100644
index f35a979..0000000
--- a/app/assets/images/icons/glsa_request.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/glsa_sent.png b/app/assets/images/icons/glsa_sent.png
deleted file mode 100644
index 1c856cd..0000000
--- a/app/assets/images/icons/glsa_sent.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/impact.png b/app/assets/images/icons/impact.png
deleted file mode 100644
index fa96cdd..0000000
--- a/app/assets/images/icons/impact.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/info.png b/app/assets/images/icons/info.png
deleted file mode 100644
index bd9fd94..0000000
--- a/app/assets/images/icons/info.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/keyword.png b/app/assets/images/icons/keyword.png
deleted file mode 100755
index ab11ce2..0000000
--- a/app/assets/images/icons/keyword.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/larr.png b/app/assets/images/icons/larr.png
deleted file mode 100644
index cdf1fb0..0000000
--- a/app/assets/images/icons/larr.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/less_width.png b/app/assets/images/icons/less_width.png
deleted file mode 100755
index 868cd87..0000000
--- a/app/assets/images/icons/less_width.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/logout.png b/app/assets/images/icons/logout.png
deleted file mode 100644
index 2541d2b..0000000
--- a/app/assets/images/icons/logout.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/metadata.png b/app/assets/images/icons/metadata.png
deleted file mode 100755
index 83f17cc..0000000
--- a/app/assets/images/icons/metadata.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/minus-small.png b/app/assets/images/icons/minus-small.png
deleted file mode 100644
index 46c4c0d..0000000
--- a/app/assets/images/icons/minus-small.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/minus.png b/app/assets/images/icons/minus.png
deleted file mode 100644
index f953427..0000000
--- a/app/assets/images/icons/minus.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/more_width.png b/app/assets/images/icons/more_width.png
deleted file mode 100755
index 2af50ef..0000000
--- a/app/assets/images/icons/more_width.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/next.png b/app/assets/images/icons/next.png
deleted file mode 100644
index 5102071..0000000
--- a/app/assets/images/icons/next.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/not-approved.png b/app/assets/images/icons/not-approved.png
deleted file mode 100755
index 20d6f5e..0000000
--- a/app/assets/images/icons/not-approved.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/note.png b/app/assets/images/icons/note.png
deleted file mode 100755
index adaf4f0..0000000
--- a/app/assets/images/icons/note.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/ok.png b/app/assets/images/icons/ok.png
deleted file mode 100644
index dff03da..0000000
--- a/app/assets/images/icons/ok.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/package-add.png b/app/assets/images/icons/package-add.png
deleted file mode 100755
index 9cea3b8..0000000
--- a/app/assets/images/icons/package-add.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/package-go.png b/app/assets/images/icons/package-go.png
deleted file mode 100755
index 4b8d163..0000000
--- a/app/assets/images/icons/package-go.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/package-remove.png b/app/assets/images/icons/package-remove.png
deleted file mode 100755
index 16c299f..0000000
--- a/app/assets/images/icons/package-remove.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/package.png b/app/assets/images/icons/package.png
deleted file mode 100755
index 78578c0..0000000
--- a/app/assets/images/icons/package.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/paste.png b/app/assets/images/icons/paste.png
deleted file mode 100644
index c0490eb..0000000
--- a/app/assets/images/icons/paste.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/pending.png b/app/assets/images/icons/pending.png
deleted file mode 100644
index c28a746..0000000
--- a/app/assets/images/icons/pending.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/permission.png b/app/assets/images/icons/permission.png
deleted file mode 100644
index 4ec1a92..0000000
--- a/app/assets/images/icons/permission.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/plus-small.png b/app/assets/images/icons/plus-small.png
deleted file mode 100644
index 33cf9af..0000000
--- a/app/assets/images/icons/plus-small.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/plus.png b/app/assets/images/icons/plus.png
deleted file mode 100644
index 3f2e8f7..0000000
--- a/app/assets/images/icons/plus.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/profile.png b/app/assets/images/icons/profile.png
deleted file mode 100644
index c02f315..0000000
--- a/app/assets/images/icons/profile.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/public.png b/app/assets/images/icons/public.png
deleted file mode 100755
index 1fff57c..0000000
--- a/app/assets/images/icons/public.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/reference-add.png b/app/assets/images/icons/reference-add.png
deleted file mode 100755
index 689c34c..0000000
--- a/app/assets/images/icons/reference-add.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/reference-remove.png b/app/assets/images/icons/reference-remove.png
deleted file mode 100755
index 8565b4d..0000000
--- a/app/assets/images/icons/reference-remove.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/reference.png b/app/assets/images/icons/reference.png
deleted file mode 100755
index 449037c..0000000
--- a/app/assets/images/icons/reference.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/refresh.png b/app/assets/images/icons/refresh.png
deleted file mode 100755
index 6d68b75..0000000
--- a/app/assets/images/icons/refresh.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/rejection.png b/app/assets/images/icons/rejection.png
deleted file mode 100644
index 558b7d0..0000000
--- a/app/assets/images/icons/rejection.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/request.png b/app/assets/images/icons/request.png
deleted file mode 100755
index 1e55e3f..0000000
--- a/app/assets/images/icons/request.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/resolution-go.png b/app/assets/images/icons/resolution-go.png
deleted file mode 100755
index bfbe022..0000000
--- a/app/assets/images/icons/resolution-go.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/resolution.png b/app/assets/images/icons/resolution.png
deleted file mode 100755
index f2af438..0000000
--- a/app/assets/images/icons/resolution.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/restricted.png b/app/assets/images/icons/restricted.png
deleted file mode 100644
index 282c64a..0000000
--- a/app/assets/images/icons/restricted.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/sent.png b/app/assets/images/icons/sent.png
deleted file mode 100755
index 95b0da4..0000000
--- a/app/assets/images/icons/sent.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/severity.png b/app/assets/images/icons/severity.png
deleted file mode 100644
index f250029..0000000
--- a/app/assets/images/icons/severity.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/stamp.png b/app/assets/images/icons/stamp.png
deleted file mode 100755
index 9d556de..0000000
--- a/app/assets/images/icons/stamp.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/status-green.png b/app/assets/images/icons/status-green.png
deleted file mode 100755
index 680bb8a..0000000
--- a/app/assets/images/icons/status-green.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/status-grey.png b/app/assets/images/icons/status-grey.png
deleted file mode 100755
index f148af4..0000000
--- a/app/assets/images/icons/status-grey.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/status-red.png b/app/assets/images/icons/status-red.png
deleted file mode 100755
index a9d5f4d..0000000
--- a/app/assets/images/icons/status-red.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/status-yellow.png b/app/assets/images/icons/status-yellow.png
deleted file mode 100755
index c7be0ab..0000000
--- a/app/assets/images/icons/status-yellow.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/switch.png b/app/assets/images/icons/switch.png
deleted file mode 100755
index 04bb1e0..0000000
--- a/app/assets/images/icons/switch.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/synopsis.png b/app/assets/images/icons/synopsis.png
deleted file mode 100755
index 363394b..0000000
--- a/app/assets/images/icons/synopsis.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/template.png b/app/assets/images/icons/template.png
deleted file mode 100644
index ed7ec0e..0000000
--- a/app/assets/images/icons/template.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/time.png b/app/assets/images/icons/time.png
deleted file mode 100755
index e4535fa..0000000
--- a/app/assets/images/icons/time.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/title.png b/app/assets/images/icons/title.png
deleted file mode 100755
index d0d2843..0000000
--- a/app/assets/images/icons/title.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/toolbox.png b/app/assets/images/icons/toolbox.png
deleted file mode 100755
index b581d77..0000000
--- a/app/assets/images/icons/toolbox.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/txt.png b/app/assets/images/icons/txt.png
deleted file mode 100755
index ed841a0..0000000
--- a/app/assets/images/icons/txt.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/unaffected.png b/app/assets/images/icons/unaffected.png
deleted file mode 100755
index 8889996..0000000
--- a/app/assets/images/icons/unaffected.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/user.png b/app/assets/images/icons/user.png
deleted file mode 100755
index f6e4dc8..0000000
--- a/app/assets/images/icons/user.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/user_add.png b/app/assets/images/icons/user_add.png
deleted file mode 100644
index deae99b..0000000
--- a/app/assets/images/icons/user_add.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/warning.png b/app/assets/images/icons/warning.png
deleted file mode 100644
index 628cf2d..0000000
--- a/app/assets/images/icons/warning.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/workaround-no.png b/app/assets/images/icons/workaround-no.png
deleted file mode 100755
index c08fc6e..0000000
--- a/app/assets/images/icons/workaround-no.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/workaround.png b/app/assets/images/icons/workaround.png
deleted file mode 100755
index dafa648..0000000
--- a/app/assets/images/icons/workaround.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/xml.png b/app/assets/images/icons/xml.png
deleted file mode 100644
index b5769e6..0000000
--- a/app/assets/images/icons/xml.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/zoom_100.png b/app/assets/images/icons/zoom_100.png
deleted file mode 100755
index a445ea6..0000000
--- a/app/assets/images/icons/zoom_100.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/zoom_in.png b/app/assets/images/icons/zoom_in.png
deleted file mode 100755
index a46dcc8..0000000
--- a/app/assets/images/icons/zoom_in.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/zoom_out.png b/app/assets/images/icons/zoom_out.png
deleted file mode 100755
index 49bb8f2..0000000
--- a/app/assets/images/icons/zoom_out.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/intel-editor.png b/app/assets/images/intel-editor.png
deleted file mode 100644
index 7db46a6..0000000
--- a/app/assets/images/intel-editor.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/line.png b/app/assets/images/line.png
deleted file mode 100644
index 1a8469c..0000000
--- a/app/assets/images/line.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/login-bg.png b/app/assets/images/login-bg.png
deleted file mode 100644
index d2876a9..0000000
--- a/app/assets/images/login-bg.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/logo.png b/app/assets/images/logo.png
deleted file mode 100644
index 9bc7bd5..0000000
--- a/app/assets/images/logo.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/menu-left.png b/app/assets/images/menu-left.png
deleted file mode 100644
index d741c7e..0000000
--- a/app/assets/images/menu-left.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/menu-right.png b/app/assets/images/menu-right.png
deleted file mode 100644
index cf42427..0000000
--- a/app/assets/images/menu-right.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/menubg.png b/app/assets/images/menubg.png
deleted file mode 100644
index 19aba57..0000000
--- a/app/assets/images/menubg.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/rails.png b/app/assets/images/rails.png
deleted file mode 100644
index d5edc04..0000000
--- a/app/assets/images/rails.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/separator.png b/app/assets/images/separator.png
deleted file mode 100644
index 5a009e5..0000000
--- a/app/assets/images/separator.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/spinner.gif b/app/assets/images/spinner.gif
deleted file mode 100644
index 39615c8..0000000
--- a/app/assets/images/spinner.gif
+++ /dev/null
Binary files differ
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
deleted file mode 100644
index d6f4b40..0000000
--- a/app/assets/javascripts/application.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// This is a manifest file that'll be compiled into including all the files listed below.
-// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
-// be included in the compiled file accessible from http://example.com/assets/application.js
-// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
-// the compiled file.
-//
-//= require prototype
-//= require prototype_ujs
-//= require effects
-//= require glsamaker
-//= require glsamaker_misc
-//= require glsamaker_edit
-//= require modalbox
-//= require_self \ No newline at end of file
diff --git a/app/assets/javascripts/glsamaker.js.erb b/app/assets/javascripts/glsamaker.js.erb
deleted file mode 100644
index 92bc6ab..0000000
--- a/app/assets/javascripts/glsamaker.js.erb
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- Sets the count of lines if more than 5 or less than 50.
-*/
-function lines(id, amount) {
-// if ($(id).rows > 0 && $(id).rows <= 50) {
- $(id).rows += amount;
-// }
-}
-
-/**
- Toggles extra-wide input fields
-**/
-function toggleWide(id) {
- if ($(id).style.width == "140%") {
- $(id).style.width = "";
- $(id + "-widebtn").childNodes[1].src = "/images/icons/more_width.png";
- $(id + "-widebtn").title = "More columns";
- } else {
- $(id).style.width = "140%";
- $(id + "-widebtn").childNodes[1].src = "/images/icons/less_width.png";
- $(id + "-widebtn").title = "Fewer columns";
- }
-}
-
-function addBugDialog(glsaid) {
- alert('deprecated. use GLSAMaker.editing.bugs.add_dialog() instead.');
-}
-
-function addCommentDialog(glsaid) {
- Modalbox.show("/glsas/"+glsaid+"/comments/new", {title: "Add comment", width: 600});
-}
-
-function backgroundDialog() {
- Modalbox.show("/tools/background/?id=dev-lang/ruby", {title: "Get background", width: 600});
-}
-
-
-function getClientWidth() {
- return document.compatMode=='CSS1Compat' && !window.opera?document.documentElement.clientWidth:document.body.clientWidth;
-}
-
-function buginfo(bugid) {
- Modalbox.show("/bug/" + bugid, {title: "Bug " + bugid, width: 800});
-}
-
-function generateResolution() {
- $('resolution').value = "";
- var resolution = "";
- var unaffected_atoms = new Array();
- var name, atom, comp, version;
-
- // First find and list all upgrade paths...
- for (i = 0; i < $('packages_table_unaffected').select('.entry').length; i++) {
- if ($('packages_table_unaffected').down(".entry", i).select('input[type=hidden][value=ignore]').length > 0)
- continue;
-
- atom = $('packages_table_unaffected').down(".entry", i).down("#glsa_package__atom").value;
- name = atom.split("/")[1];
- if (name == undefined)
- name = "UNDEFINED";
- comp = $('packages_table_unaffected').down(".entry", i).down("#glsa_package__comp").value.replace('*', '');
- version = $('packages_table_unaffected').down(".entry", i).down("#glsa_package__version").value;
-
- resolution += "All " + name + " users should upgrade to the latest version:\n\n\
-<code>\n\
-# emerge --sync\n\
-# emerge --ask --oneshot --verbose \"" + comp + atom + "-" + version + "\"</code>\n\n";
-
- unaffected_atoms.push(atom);
- }
-
- // Check if there are any packages that only have vulnerable entries.
- // These need to be unmerged.
- for (i = 0; i < $('packages_table_vulnerable').select('.entry').length; i++) {
- if ($('packages_table_vulnerable').down(".entry", i).select('input[type=hidden][value=ignore]').length > 0)
- continue;
-
- atom = $('packages_table_vulnerable').down(".entry", i).down("#glsa_package__atom").value;
- if (unaffected_atoms.indexOf(atom) == -1) {
- name = atom.split("/")[1];
- if (name == undefined)
- name = "UNDEFINED";
-
- resolution += "We recommend that users unmerge " + name + ":\n\n\
-<code>\n\
-# emerge --unmerge \"" + atom + "\"</code>";
- }
- }
-
- $('resolution').value = resolution;
-}
-
-function generateDescription() {
- // This code is pretty ugly. You have been warned.
- // cnt is the number of 'entry's
- // act_cnt is cnt minus the number of to be ignored 'entry's
- // i is used to walk down into the i'th entry element
- // act_i is used to keep track of how many packages have been / will be added
-
- var name = "";
- var cnt = $('packages_table_vulnerable').select('.entry').length;
- var act_cnt = cnt - $('packages_table_vulnerable').select('.entry input[type=hidden][value=ignore]').length;
-
- var act_i = 0;
- for (var i = 0; i < cnt; i++) {
- if ($('packages_table_vulnerable').down(".entry", i).select('input[type=hidden][value=ignore]').length > 0)
- continue;
-
- var atom = $('packages_table_vulnerable').down(".entry", i).down("#glsa_package__atom").value;
-
- if (act_cnt > 1 && act_i == act_cnt - 1) {
- name += ", and ";
- } else if (act_cnt > 1 && act_i != 0) {
- name += ", ";
- }
- act_i++;
- name += atom.split("/")[1];
- }
-
- if (name == "undefined")
- name = "UNDEFINED";
-
- $('description').value = "Multiple vulnerabilities have been discovered in " + name + ". Please review the CVE identifiers referenced below for details.";
-}
-
-function toggleCommentRead(comment) {
- if ($('commentread-' + comment).value == "true") {
- $('commentread-' + comment).value = "false";
- $('commentflag-' + comment).update('<img src="<%= asset_path 'icons/flag.png' %>" alt="Todo" />');
- }
- else {
- $('commentread-' + comment).value = "true";
- $('commentflag-' + comment).update('<img src="<%= asset_path 'icons/flag-green.png' %>" alt="Done." />');
- }
-}
-
-function cveinfo(cveid) {
- Modalbox.show("/cve/info/" + cveid, {title: cveid, width: 800});
-}
-
-function cvepopup(cveid) {
- window.open("/cve/info/" + escapeHTML(cveid), "cvepopup-" + cveid, "width=500, height=600,status=no,menubar=no,toolbar=no,resizable=no");
-}
-
-function escapeHTML(str) {
- return str.replace(/(<([^>]+)>)/ig,"");
-}
-
-//document.observe('dom:loaded', function() {
-
-//});
diff --git a/app/assets/javascripts/glsamaker_edit.js b/app/assets/javascripts/glsamaker_edit.js
deleted file mode 100644
index cc77621..0000000
--- a/app/assets/javascripts/glsamaker_edit.js
+++ /dev/null
@@ -1,181 +0,0 @@
-/**
- * GLSAMaker 2
- * Draft editing JS
- */
-
-if (typeof GLSAMaker == "undefined" || !GLSAMaker) {
- var GLSAMaker = {};
-}
-
-if (typeof GLSAMaker.editing == "undefined" || !GLSAMaker.editing) {
- GLSAMaker.editing = function() {
- return {};
- }();
-}
-
-GLSAMaker.editing.bugs = function() {
- return {
- /**
- * Removes a bug from a draft being edited
- */
- del : function(bug_id) {
- // no such bug, or already removed
- if (!$('bug-' + bug_id)) {
- return;
- }
-
- Effect.Fade('bug-' + bug_id, {
- duration: .75,
- afterFinish: function(e) {
- $('bug-' + bug_id).remove();
- }
- });
- },
- /**
- * Opens a dialog to add bugs
- */
- add_dialog : function(glsa_id) {
- Modalbox.show("/glsas/" + glsa_id + "/bugs/new", {title: "Add bugs", width: 600});
- }
- };
-}();
-
-GLSAMaker.editing.references = function() {
- return {
- /**
- * Removes a reference from a draft being edited
- */
- del : function(ref) {
- // no such reference, or already removed
- if (!ref) {
- return;
- }
-
- var td = ref.up(".entry")
-
- Effect.Fade(td, {
- duration: .75,
- afterFinish: function(e) {
- td.remove();
- }
- });
- },
- /**
- * Opens a dialog to import references from external data
- */
- import_dialog : function(glsa_id) {
- Modalbox.show("/glsa/import_references/" + glsa_id, {title: "Import references", width: 800});
- }
- };
-}();
-
-GLSAMaker.editing.packages = function() {
- return {
- /**
- * Removes a reference from a draft being edited
- */
- del : function(ref) {
- // no such reference, or already removed
- if (!ref) {
- return;
- }
-
- var td = ref.up(".entry");
-
- Effect.Fade(td, {
- duration: .75,
- afterFinish: function(e) {
- td.remove();
- }
- });
- }
- };
-}();
-
-GLSAMaker.editing.templates = function() {
- return {
- /**
- * Displays a drop down menu to select a template to append
- */
- dropdown : function(button, target) {
- var div = $('templates-' + target);
-
- if (!div) {
- return;
- }
-
- // Close the popup if it's already open
- if (div.getStyle('display') != 'none') {
- GLSAMaker.editing.templates.close(div);
- return;
- }
-
- var btn_layout = button.getLayout();
-
- div.setStyle({
- position: 'absolute',
- right: btn_layout.get('right') + "px",
- top: btn_layout.get('top') + btn_layout.get('height') + 5 + "px"
- });
-
- Effect.SlideDown(div, {
- duration: .15
- });
- },
- /**
- * Closes a popup
- *
- * @param target The popup to close
- */
- close : function(target) {
- Effect.SlideUp(target, {
- duration: .2
- });
- },
- /**
- * Observes a field for clicks into template fields and sets the
- * @param elem
- */
- observeClick : function(elem) {
- elem.observe('click', function(event) {
- var before = '[';
- var after = ']';
-
- var selection_info = GLSAMaker.misc.getInputSelection(this);
- var text = this.getValue();
-
- // If the user clicked and did not select
- if (selection_info.start == selection_info.end) {
- var text_before = text.substring(0, selection_info.start);
- var text_after = text.substring(selection_info.end, text.length - 1);
-
- // check if there is any template before this
- var pos_prev = text_before.search(GLSAMaker.misc.escapeRegExp(after));
- var pos_comp = 0;
-
- while (pos_prev > 0) {
- pos_comp += pos_prev;
- text_before = text_before.slice(pos_prev);
- pos_prev = text_before.search(GLSAMaker.misc.escapeRegExp(after));
- }
-
- var pos_before = text_before.search(GLSAMaker.misc.escapeRegExp(before));
- if (pos_before == -1) {
- return;
- }
-
- // pos_before is our selection start.
- var pos_after = text_after.search(GLSAMaker.misc.escapeRegExp(after));
- if (pos_after == -1) {
- return;
- }
-
- pos_before += pos_comp;
- pos_after += selection_info.end + 1;
-
- GLSAMaker.misc.setInputSelection(this, {start: pos_before, end: pos_after});
- }
- })
- }
- };
-}(); \ No newline at end of file
diff --git a/app/assets/javascripts/glsamaker_misc.js b/app/assets/javascripts/glsamaker_misc.js
deleted file mode 100644
index fb04be3..0000000
--- a/app/assets/javascripts/glsamaker_misc.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * GLSAMaker 2
- * Draft editing JS
- */
-
-if (typeof GLSAMaker == "undefined" || !GLSAMaker) {
- var GLSAMaker = {};
-}
-
-if (typeof GLSAMaker.misc == "undefined" || !GLSAMaker.misc) {
- GLSAMaker.misc = function() {
- return {
- /**
- * Find out the selection position in a text field
- * via: http://stackoverflow.com/questions/4928586/get-caret-position-in-html-input
- *
- * @param el
- */
- getInputSelection : function(el) {
- var start = 0, end = 0, normalizedValue, range,
- textInputRange, len, endRange;
-
- if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
- start = el.selectionStart;
- end = el.selectionEnd;
- } else {
- range = document.selection.createRange();
-
- if (range && range.parentElement() == el) {
- len = el.value.length;
- normalizedValue = el.value.replace(/\r\n/g, "\n");
-
- // Create a working TextRange that lives only in the input
- textInputRange = el.createTextRange();
- textInputRange.moveToBookmark(range.getBookmark());
-
- // Check if the start and end of the selection are at the very end
- // of the input, since moveStart/moveEnd doesn't return what we want
- // in those cases
- endRange = el.createTextRange();
- endRange.collapse(false);
-
- if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
- start = end = len;
- } else {
- start = -textInputRange.moveStart("character", -len);
- start += normalizedValue.slice(0, start).split("\n").length - 1;
-
- if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
- end = len;
- } else {
- end = -textInputRange.moveEnd("character", -len);
- end += normalizedValue.slice(0, end).split("\n").length - 1;
- }
- }
- }
- }
-
- return {
- start: start,
- end: end
- };
- },
- /**
- * Sets the caret position of a control
- * @param ctrl
- * @param pos
- */
- setInputSelection: function (ctrl, data) {
- if (ctrl.setSelectionRange) {
- ctrl.focus();
- ctrl.setSelectionRange(data.start, data.end);
- }
- else if (ctrl.createTextRange) {
- var range = ctrl.createTextRange();
- range.collapse(true);
- range.moveEnd('character', data.end);
- range.moveStart('character', data.start);
- range.select();
- }
- },
- escapeRegExp : function(text) {
- return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
- }
- };
- }();
-}
-
-GLSAMaker.misc.ui = function() {
- return {
- /**
- * Docks an element to the right
- */
- dock : function(elem) {
- if (!elem) {
- return;
- }
-
- elem.toggleClassName('docked-right');
- }
- };
-}();
diff --git a/app/assets/javascripts/jsui.js b/app/assets/javascripts/jsui.js
deleted file mode 100644
index 039f727..0000000
--- a/app/assets/javascripts/jsui.js
+++ /dev/null
@@ -1,8 +0,0 @@
-//= require prototype
-//= require prototype_ujs
-//= require effects
-//= require uki
-//= require uki-more
-//= require searchable
-//= require glsamaker
-//= require glsamaker_misc \ No newline at end of file
diff --git a/app/assets/javascripts/modalbox.js b/app/assets/javascripts/modalbox.js
deleted file mode 100644
index 611c226..0000000
--- a/app/assets/javascripts/modalbox.js
+++ /dev/null
@@ -1,593 +0,0 @@
-//
-// ModalBox - The pop-up window thingie with AJAX, based on Prototype JS framework.
-//
-// Created by Andrew Okonetchnikov
-// Copyright 2006-2010 okonet.ru. All rights reserved.
-//
-// Licensed under MIT license.
-//
-
-if (Object.isUndefined(Prototype.Browser.IE6)) {
- Prototype.Browser.IE6 = (navigator.appName.indexOf("Microsoft Internet Explorer") != -1 && navigator.appVersion.indexOf("MSIE 6.0") != -1 && !window.XMLHttpRequest);
-}
-
-if (!window.Modalbox)
- var Modalbox = {};
-
-Modalbox.Methods = {
- overrideAlert: false, // Override standard browser alert message with ModalBox
- focusableElements: [],
- currFocused: 0,
- initialized: false, // Modalbox is visible
- active: true, // Modalbox is visible and active
- options: {
- title: "ModalBox Window", // Title of the ModalBox window
- overlayClose: true, // Close modal box by clicking on overlay
- width: 500, // Default width in px
- height: 90, // Default height in px
- overlayOpacity: 0.65, // Default overlay opacity
- overlayDuration: 0.25, // Default overlay fade in/out duration in seconds
- slideDownDuration: 0.5, // Default Modalbox appear slide down effect in seconds
- slideUpDuration: 0.5, // Default Modalbox hiding slide up effect in seconds
- resizeDuration: 0.25, // Default resize duration seconds
- inactiveFade: true, // Fades MB window on inactive state
- transitions: true, // Toggles transition effects. Transitions are enabled by default
- loadingString: "Please wait. Loading...", // Default loading string message
- closeString: "Close window", // Default title attribute for close window link
- closeValue: "&times;", // Default string for close link in the header
- params: {},
- method: 'get', // Default Ajax request method
- autoFocusing: true, // Toggles auto-focusing for form elements. Disable for long text pages.
- aspnet: false, // Should be true when using with ASP.NET controls. When true Modalbox window will be injected into the first form element.
- resizeCSSID: ''
- },
- _options: {},
-
- setOptions: function(options) {
- Object.extend(this.options, options || {});
- },
-
- _init: function(options) {
- // Setting up original options with default options
- Object.extend(this._options, this.options);
- this.setOptions(options);
-
- // Creating the overlay
- this.MBoverlay = new Element("div", {id: "MB_overlay", style: "opacity: 0"});
-
- // Creating the modal window
- this.MBwindowwrapper = new Element("div", {id: "MB_windowwrapper"}).update(
- this.MBwindow = new Element("div", {id: "MB_window", style: "display: none"}).update(
- this.MBframe = new Element("div", {id: "MB_frame"}).update(
- this.MBheader = new Element("div", {id: "MB_header"}).update(
- this.MBcaption = new Element("div", {id: "MB_caption"})
- )
- )
- )
- );
-
- this.MBclose = new Element("a", {id: "MB_close", title: this.options.closeString, href: "#"}).update("<span>" + this.options.closeValue + "</span>");
- this.MBheader.insert({'bottom':this.MBclose});
-
- this.MBcontent = new Element("div", {id: "MB_content"}).update(
- this.MBloading = new Element("div", {id: "MB_loading"}).update(this.options.loadingString)
- );
- this.MBframe.insert({'bottom':this.MBcontent});
-
- // Inserting into DOM. If parameter set and form element have been found will inject into it. Otherwise will inject into body as topmost element.
- // Be sure to set padding and marging to null via CSS for both body and (in case of asp.net) form elements.
- var injectToEl = this.options.aspnet ? $(document.body).down('form') : $(document.body);
- injectToEl.insert({'top':this.MBwindowwrapper});
- injectToEl.insert({'top':this.MBoverlay});
-
- var scrollOffsets = document.viewport.getScrollOffsets();
- if (scrollOffsets[1] > 0) {
- $('MB_window').setStyle({top:scrollOffsets[1] + 'px'});
- }
-
- Event.observe(window, 'scroll', function() {
- scrollOffsets = document.viewport.getScrollOffsets();
- $('MB_window').setStyle({top:scrollOffsets[1] + 'px'});
- });
-
- // Initial scrolling position of the window. To be used for remove scrolling effect during ModalBox appearing
- this.initScrollX = window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft;
- this.initScrollY = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
-
- //Adding event observers
- this.hideObserver = this._hide.bindAsEventListener(this);
- this.kbdObserver = this._kbdHandler.bindAsEventListener(this);
- this.resizeObserver = this._setWidthAndPosition.bindAsEventListener(this);
- this._initObservers();
-
- this.initialized = true; // Mark as initialized
- },
-
- show: function(content, options) {
- if (!this.initialized) this._init(options); // Check if MB is already initialized
-
- this._cleanUpContentIDs();
-
- this.content = content;
- this.setOptions(options);
-
- if (this.options.title) { // Updating title of the MB
- this.MBcaption.update(this.options.title);
- } else { // If title isn't given, the header will not displayed
- this.MBheader.hide();
- this.MBcaption.hide();
- }
-
- if (this.MBwindow.style.display == "none") { // First modal box appearing
- this._appear();
- this.event("onShow"); // Passing onShow callback
- } else { // If MB already on the screen, update it
- this._update();
- this.event("onUpdate"); // Passing onUpdate callback
- }
- },
-
- hide: function(options) { // External hide method to use from external HTML and JS
- if (this.initialized) {
- // Reading for options/callbacks except if event given as a parameter
- if (options && !Object.isFunction(options.element))
- Object.extend(this.options, options);
- this.event("beforeHide"); // Passing beforeHide callback
- if (this.options.transitions) {
- Effect.SlideUp(this.MBwindow, { duration: this.options.slideUpDuration, transition: Effect.Transitions.sinoidal, afterFinish: this._deinit.bind(this) });
- } else {
- this.MBwindow.hide();
- this._deinit();
- }
- Event.stopObserving(window, 'scroll');
- } else {
- throw("Modalbox is not initialized.");
- }
- },
-
- _hide: function(event) { // Internal hide method to use with overlay and close link
- event.stop(); // Stop event propagation for link elements
- // When clicked on overlay we'll check the option and in case of overlayClose == false we'll break hiding execution [Fix for #139]
- if (event.element().id == 'MB_overlay' && !this.options.overlayClose) return false;
- this.hide();
- },
-
- alert: function(message){
- var html = '<div class="MB_alert"><p>' + message + '</p><input type="button" onclick="Modalbox.hide()" value="OK" /></div>';
- Modalbox.show(html, {title: 'Alert: ' + document.title, width: 300});
- },
-
- _appear: function() { // First appearing of MB
- if (Prototype.Browser.IE6) { // Preparing IE 6 for showing modalbox
- window.scrollTo(0,0);
- this._prepareIEHtml("100%", "hidden");
- this._prepareIESelects("hidden");
- }
- this._setWidth();
- if(this.options.transitions) {
- this.MBoverlay.setOpacity(0);
- new Effect.Fade(this.MBoverlay, {
- from: 0,
- to: this.options.overlayOpacity,
- duration: this.options.overlayDuration,
- afterFinish: (function() {
- new Effect.SlideDown(this.MBwindow, {
- duration: this.options.slideDownDuration,
- transition: Effect.Transitions.sinoidal,
- afterFinish: this.loadContent.bind(this)
- });
- }).bind(this)
- });
- } else {
- this.MBoverlay.setOpacity(this.options.overlayOpacity);
- this.MBwindow.show();
- this.loadContent();
- }
- Event.observe(window, "resize", this.resizeObserver);
- },
-
- resize: function(byWidth, byHeight, options) { // Change size of MB without content reloading
- var oWidth = $(this.MBoverlay).getWidth();
- var wHeight = $(this.MBwindow).getHeight();
- var wWidth = $(this.MBwindow).getWidth();
- var hHeight = $(this.MBheader).getHeight();
- var cHeight = $(this.MBcontent).getHeight();
- var newHeight = ((wHeight - hHeight + byHeight) < cHeight) ? (cHeight + hHeight) : (wHeight + byHeight);
-
- var el = $(this.MBwindow);
- var contentEl = $(this.MBcontent);
- var windowBottomMargin = 10;
- newHeight += windowBottomMargin;
- var windowOffset = (parseInt(el.getStyle('margin-top'), 0) + parseInt(el.getStyle('margin-bottom'), 0) + parseInt(el.getStyle('border-top-width'), 0) + parseInt(el.getStyle('border-bottom-width'), 0)) + windowBottomMargin;
- var contentPadding = (parseInt(contentEl.getStyle('padding-top')) + parseInt(contentEl.getStyle('padding-bottom')));
-
- if ((newHeight + windowOffset + contentPadding) > document.viewport.getHeight()) {
- // adjust window height to account for margins and border widths
- newHeight = document.viewport.getHeight() - windowOffset - windowBottomMargin;
- // calculate content height including header height and padding values
- newcHeight = newHeight - hHeight - parseInt($(this.MBframe).getStyle('padding-bottom'), 0) - parseInt($(this.MBcontent).getStyle('padding-bottom'), 0);
- $(this.MBcontent).setStyle({height:newcHeight + 'px'});
- } else if ($(this.MBcontent).getStyle('height')) {
- // release any MB_content height set prior to establish scrollbars in content area
- $(this.MBcontent).setStyle({height:''});
- }
-
- var newWidth = wWidth + byWidth;
- //var newStyle = {width: newWidth + "px", height: newHeight + "px", left: (o.width - newWidth)/2 + "px"};
- var newStyle = {width: newWidth + "px", height: newHeight + "px"};
- this.options.width = newWidth;
- if (options) this.setOptions(options); // Passing callbacks
- if (this.options.transitions && !Modalbox.animating) {
- Modalbox.animating = true;
- new Effect.Morph(this.MBwindow, {
- style: newStyle,
- duration: this.options.resizeDuration,
- beforeStart: function(fx){
- fx.element.setStyle({overflow: "hidden"}); // Fix for MSIE 6 to resize correctly
- },
- afterFinish: (function(fx) {
- fx.element.setStyle({overflow: "visible"});
- this.event("_afterResize"); // Passing internal callback
- this.event("afterResize"); // Passing callback
- Modalbox.animating = false;
- }).bind(this)
- });
- } else {
- this.MBwindow.setStyle(newStyle);
- (function() {
- this.event("_afterResize"); // Passing internal callback
- this.event("afterResize"); // Passing callback
- }).bind(this).defer();
- }
- },
-
- resizeToContent: function(options){
- // Resizes the modalbox window to the actual content height.
- // This might be useful to resize modalbox after some content modifications which were changed content height.
-
- if (typeof options == "undefined") {
- options = {};
- }
-
- // check to see if MB_content includes any images
- var mbimages = $('MB_content').select('img');
- var totalimages = mbimages.length;
- if (mbimages[0]) {
- if (typeof options.imagesloaded == "undefined") {
-
- var loadedImages = $A();
- var loadedImageTotal = 0;
- mbimages.each(function(o,idx) {
- loadedImages[idx] = new Image();
- loadedImages[idx].src = o.src;
- loadedImages[idx].onload = function() {
- loadedImageTotal++;
- if (loadedImageTotal == totalimages) {
- // make sure all images have been rendered by checking their height
- var imageincomplete = false;
- mbimages.each(function(i) {
- if (i.height == 0) {
- imageincomplete = true;
- }
- });
- if (imageincomplete || Modalbox.animating) {
- // some image hasn't been rendered yet, trigger resize loop until it is
- Modalbox.resizeToContent();
- } else {
- // trigger one final resize, but set imagesloaded option to skip inspection of images
- options.imagesloaded = true;
- Modalbox.resizeToContent(options);
- }
- }
- }
- })
- }
- }
-
- var byWidth = 0, byHeight = this.options.height - this.MBwindow.getHeight();
- if (options.resizeCSSID && $(options.resizeCSSID)) {
- // byWidth is the amount of pixels needed to increase/decrease window to meet width of options.resizeCSSID
- // plus a 10 pixel margin to accommodate scrollbars
- byWidth = $(options.resizeCSSID).getWidth() - $(this.MBwindow).getWidth() + (parseInt($(this.MBcontent).getStyle('padding-left'), 0) + parseInt($(this.MBcontent).getStyle('padding-right'), 0)) + 15;
- }
- if (byHeight != 0) {
- this.resize(byWidth, byHeight, options);
- }
- },
-
- resizeToInclude: function(element, options){
- // Resizes the modalbox window to the cumulative height of element. Calculations are using CSS properties for margins and border.
- // This method might be useful to resize modalbox before including or updating content.
-
- var el = $(element);
- var elHeight = el.getHeight() + parseInt(el.getStyle('margin-top'), 0) + parseInt(el.getStyle('margin-bottom'), 0) + parseInt(el.getStyle('border-top-width'), 0) + parseInt(el.getStyle('border-bottom-width'), 0);
- if (elHeight > 0) {
- this.resize(0, elHeight, options);
- }
- },
-
- _update: function() { // Updating MB in case of wizards
- this.MBcontent.update($(this.MBloading).update(this.options.loadingString));
- this.loadContent();
- },
-
- loadContent: function() {
- if (this.event("beforeLoad") != false) { // If callback passed false, skip loading of the content
- if (typeof this.content == 'string') {
- var htmlRegExp = new RegExp(/<\/?[^>]+>/gi);
- if (htmlRegExp.test(this.content)) { // Plain HTML given as a parameter
- this._processContent(this.content);
- } else { // URL given as a parameter. We'll request it via Ajax
- new Ajax.Request(this.content, {
- method: this.options.method.toLowerCase(),
- parameters: this.options.params,
- onComplete: (function(response) {
- this._processContent(response.responseText);
- }).bind(this),
- onException: function(instance, exception){
- Modalbox.hide();
- throw('Modalbox Loading Error: ' + exception);
- }
- });
- }
- } else if (typeof this.content == 'object') { // HTML Object is given
- this._insertContent(this.content);
- } else {
- this.hide();
- throw('Modalbox Parameters Error: Please specify correct URL or HTML element (plain HTML or object)');
- }
- }
- },
-
- _processContent: function(content) {
- var html = content.stripScripts(), scripts = content.extractScripts();
- this._insertContent(html, function() {
- scripts.map(function(script) {
- return eval(script.replace("<!--", "").replace("// -->", ""));
- }, window);
- });
- },
-
- _insertContent: function(content, callback) {
- this.MBcontent.hide().update();
-
- if (typeof content == 'string') { // Plain HTML is given
- this.MBcontent.insert(new Element("div", { style: "display: none" }).update(content)).down().show();
- } else if (typeof content == 'object') { // HTML Object is given
- var _htmlObj = content.cloneNode(true); // If node is already a part of DOM we'll clone it
- // If cloneable element has ID attribute defined, modify it to prevent duplicates
- if (content.id) content.id = "MB_" + content.id;
- // Add prefix for IDs on all elements inside the DOM node
- $(content).select('*[id]').each(function(el) { el.id = "MB_" + el.id; });
- this.MBcontent.insert(_htmlObj).down('div').show();
- if (Prototype.Browser.IE6) { // Toggling back visibility for hidden selects in IE
- this._prepareIESelects("", "#MB_content ");
- }
- }
-
- // Prepare and resize modal box for content
- if (this.options.height == this._options.height) {
- this.resize((this.options.width - $(this.MBwindow).getWidth()), this.MBcontent.getHeight() - $(this.MBwindow).getHeight() + this.MBheader.getHeight(), {
- afterResize: (function() {
- this._putContent.bind(this, callback).defer(); // MSIE fix
- }).bind(this)
- });
- } else { // Height is defined. Creating a scrollable window
- this._setWidth();
- this.MBcontent.setStyle({
- overflow: 'auto',
- height: this.MBwindow.getHeight() - this.MBheader.getHeight() - 13 + 'px'
- });
- this._putContent.bind(this, callback).defer(); // MSIE fix
- }
- },
-
- _putContent: function(callback) {
- this.MBcontent.show();
- this._findFocusableElements();
- this._setFocus(); // Setting focus on first 'focusable' element in content (input, select, textarea, link or button)
- if (Object.isFunction(callback))
- callback(); // Executing internal JS from loaded content
- this.event("afterLoad"); // Passing callback
- },
-
- activate: function(options) {
- this.setOptions(options);
- this.active = true;
- if (this.options.overlayClose)
- this.MBoverlay.observe("click", this.hideObserver);
- this.MBclose.observe("click", this.hideObserver).show();
- if (this.options.transitions && this.options.inactiveFade)
- new Effect.Appear(this.MBwindow, {duration: this.options.slideUpDuration});
- },
-
- deactivate: function(options) {
- this.setOptions(options);
- this.active = false;
- if (this.options.overlayClose)
- this.MBoverlay.stopObserving("click", this.hideObserver);
- this.MBclose.stopObserving("click", this.hideObserver).hide();
- if (this.options.transitions && this.options.inactiveFade)
- new Effect.Fade(this.MBwindow, {duration: this.options.slideUpDuration, to: 0.75});
- },
-
- _initObservers: function() {
- this.MBclose.observe("click", this.hideObserver);
- if (this.options.overlayClose)
- this.MBoverlay.observe("click", this.hideObserver);
- // Gecko and Opera are moving focus a way too fast, all other browsers are okay with keydown
- var kbdEvent = (Prototype.Browser.Gecko || Prototype.Browser.Opera) ? "keypress" : "keydown";
- Event.observe(document, kbdEvent, this.kbdObserver);
- },
-
- _removeObservers: function() {
- this.MBclose.stopObserving("click", this.hideObserver);
- if (this.options.overlayClose)
- this.MBoverlay.stopObserving("click", this.hideObserver);
- var kbdEvent = (Prototype.Browser.Gecko || Prototype.Browser.Opera) ? "keypress" : "keydown";
- Event.stopObserving(document, kbdEvent, this.kbdObserver);
- },
-
- _setFocus: function() {
- // Setting focus to the first 'focusable' element which is one with tabindex = 1 or the first in the form loaded.
- if (this.focusableElements.length > 0 && this.options.autoFocusing == true) {
- var firstEl = this.focusableElements.find(function (el){
- return el.tabIndex == 1;
- }) || this.focusableElements.first();
- this.currFocused = this.focusableElements.toArray().indexOf(firstEl);
- firstEl.focus(); // Focus on first focusable element except close button
- } else if (this.MBclose.visible()) {
- this.MBclose.focus(); // If no focusable elements exist focus on close button
- }
- },
-
- _findFocusableElements: function() { // Collect form elements and links from MB content
- if (this.options.autoFocusing === true) {
- // TODO maybe add :enabled to select and textarea elements
- this.MBcontent.select('input:not([type=hidden]):enabled, select, textarea, button, a[href]').invoke('addClassName', 'MB_focusable');
- this.focusableElements = this.MBcontent.select('.MB_focusable');
- }
- },
-
- _kbdHandler: function(event) {
- var node = event.element();
- switch(event.keyCode) {
- case Event.KEY_TAB:
- event.stop();
-
- // Switching currFocused to the element which was focused by mouse instead of TAB-key. Fix for #134
- if (node != this.focusableElements[this.currFocused])
- this.currFocused = this.focusableElements.indexOf(node);
-
- if (!event.shiftKey) { // Focusing in direct order
- if (this.currFocused >= this.focusableElements.length - 1) {
- this.currFocused = 0;
- } else {
- this.currFocused++;
- }
- } else { // Shift key is pressed. Focusing in reverse order
- if (this.currFocused <= 0) {
- this.currFocused = this.focusableElements.length - 1;
- } else {
- this.currFocused--;
- }
- }
- this.focusableElements[this.currFocused].focus();
- break;
- case Event.KEY_ESC:
- if (this.active) this._hide(event);
- break;
- case 32:
- this._preventScroll(event);
- break;
- case 0: // For Gecko browsers compatibility
- if (event.which == 32) this._preventScroll(event);
- break;
- case Event.KEY_UP:
- case Event.KEY_DOWN:
- case Event.KEY_PAGEDOWN:
- case Event.KEY_PAGEUP:
- case Event.KEY_HOME:
- case Event.KEY_END:
- var tagName = node.tagName.toLowerCase();
- // Safari operates in slightly different way. This realization is still buggy in Safari.
- if (Prototype.Browser.WebKit && !["textarea", "select"].include(tagName)) {
- event.stop();
- } else if ((tagName == "input" && ["submit", "button"].include(node.type)) || (tagName == "a")) {
- event.stop();
- }
- break;
- }
- },
-
- _preventScroll: function(event) { // Disabling scrolling by "space" key
- if (!["input", "textarea", "select", "button"].include(event.element().tagName.toLowerCase()))
- event.stop();
- },
-
- _deinit: function() {
- this._removeObservers();
- Event.stopObserving(window, "resize", this.resizeObserver);
- if (this.options.transitions) {
- Effect.toggle(this.MBoverlay, 'appear', {duration: this.options.overlayDuration, afterFinish: this._removeElements.bind(this) });
- } else {
- this.MBoverlay.hide();
- this._removeElements();
- }
- this.MBcontent.setStyle({overflow: '', height: ''});
- },
-
- _cleanUpContentIDs: function() {
- // Replace prefixes 'MB_' in IDs for the original content
- if (typeof this.content == 'object') {
- if (this.content.id && this.content.id.match(/MB_/)) {
- this.content.id = this.content.id.replace(/MB_/, "");
- }
-
- this.content.select('*[id]').each(function(el) {
- el.id = el.id.replace(/MB_/, "");
- });
- }
- },
-
- _removeElements: function() {
- if (Prototype.Browser.Opera) { // Remove overlay after-effects in Opera
- window.scrollBy(0, 0);
- }
- this.MBoverlay.remove();
- $(this.MBwindowwrapper).remove();
- if (Prototype.Browser.IE6) {
- this._prepareIEHtml("", ""); // If set to auto MSIE will show horizontal scrolling
- this._prepareIESelects("");
- window.scrollTo(this.initScrollX, this.initScrollY);
- }
-
- this._cleanUpContentIDs();
-
- // Initialized will be set to false
- this.initialized = false;
- this.event("afterHide"); // Passing afterHide callback
- this.setOptions(this._options); // Settings options object into initial state
- },
-
- _setWidth: function() { // Set size
- this.MBwindow.setStyle({width: this.options.width + "px", height: this.options.height + "px"});
- },
-
- _setWidthAndPosition: function() {
- this.MBwindow.setStyle({
- width: this.options.width + "px"
- });
- },
-
- _prepareIEHtml: function(height, overflow) {
- // IE6 requires width and height set to 100% and overflow hidden
- $$('html, body').invoke('setStyle', {
- width: height,
- height: height,
- overflow: overflow
- });
- },
-
- _prepareIESelects: function(visibility, prefix) {
- // Toggle visibility for select elements
- $$((prefix || "") + "select").invoke('setStyle', {
- 'visibility': visibility
- });
- },
-
- event: function(eventName) {
- var r = true;
- if (this.options[eventName]) {
- var returnValue = this.options[eventName](); // Executing callback
- this.options[eventName] = null; // Removing callback after execution
- if (!Object.isUndefined(returnValue))
- r = returnValue;
- }
- return r;
- }
-};
-
-Object.extend(Modalbox, Modalbox.Methods);
-
-if (Modalbox.overrideAlert) window.alert = Modalbox.alert;
diff --git a/app/assets/javascripts/searchable.js b/app/assets/javascripts/searchable.js
deleted file mode 100644
index 6ef683d..0000000
--- a/app/assets/javascripts/searchable.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Search with chunks
- */
-window.Searchable = uki.newClass(uki.view.Observable, new function() {
- this.chunkSize = 100;
- this.chunkTimeout = 20;
-
- this.init = function(data) {
- this.items = data;
- };
-
- this.search = function(query, callback) {
- stopSearch.call(this);
-
- this._query = query;
- var iterator = this.createIterator(query, callback);
-
- this.trigger('search.start', iterator);
- filterChunk.call(this, iterator);
- };
-
- this.matchRow = function( row, iterator ) { return false; };
-
- this.createIterator = function(query, callback) {
- return {
- query: query,
- iteration: 0,
- found: 0,
- callback: callback
- };
- };
-
- this._bindToDom = function() { return true };
-
- function filterChunk(iterator) {
- var filtered = 0,
- _this = this,
- foundInChunk = [],
- item;
-
- while(iterator.iteration < this.items.length) {
- if (filtered == this.chunkSize) {
- if (foundInChunk.length) this.trigger('search.foundInChunk', foundInChunk);
- this._searchTimer = setTimeout(function() { filterChunk.call(_this, iterator); }, this.chunkTimeout);
- return;
- }
- item = this.items[iterator.iteration];
- if (this.matchRow( item, iterator )) {
- iterator.found++;
- foundInChunk.push(item);
- this.trigger('search.found', item, iterator);
- if (iterator.callback) iterator.callback(item, iterator);
- } else {
- this.trigger('search.missed', item, iterator);
- }
- iterator.iteration++;
- filtered++;
- }
- this.trigger('search.foundInChunk', foundInChunk);
-
- stopSearch.call(this);
- this.trigger('search.finish', iterator);
- };
-
- function stopSearch () {
- if (this._searchTimer) {
- clearTimeout(this._searchTimer);
- this._searchTimer = false;
- }
- }
-}); \ No newline at end of file
diff --git a/app/assets/javascripts/uki-more.js b/app/assets/javascripts/uki-more.js
deleted file mode 100644
index 9f75423..0000000
--- a/app/assets/javascripts/uki-more.js
+++ /dev/null
@@ -1,827 +0,0 @@
-uki.more = {};
-
-uki.more.utils = {
- range: function (from, to) {
- var result = new Array(to - from), idx = 0;
- for (; from <= to; from++, idx++) {
- result[idx] = from;
- };
- return result;
- }
-};
-
-uki.extend(uki, uki.more.utils);
-
-uki.more.view = {};
-
-uki.viewNamespaces.push('uki.more.view.');
-
-// really basic tree list implementation
-uki.more.view.treeList = {};
-
-uki.view.declare('uki.more.view.TreeList', uki.view.List, function(Base) {
- this._setup = function() {
- Base._setup.call(this);
- this._render = new uki.more.view.treeList.Render();
- };
-
- this.listData = Base.data;
-
- this.data = uki.newProp('_treeData', function(v) {
- this._treeData = v;
- this._data = this._treeNodeToListData(v);
- var children = this.listData(), opened = false;
- for (var i=children.length - 1; i >= 0 ; i--) {
- if (this._data[i].__opened) {
- opened = true;
- this._openSubElement(i);
- }
- };
- this.listData(this._data);
- if (opened) this.trigger('open');
- });
-
- this._treeNodeToListData = function(node, indent) {
- indent = indent || 0;
- return uki.map(node, function(row) {
- row.__indent = indent;
- return row;
- });
- };
-
- this.toggle = function(index) {
- this._data[index].__opened ? this.close(index) : this.open(index);
- };
-
- function offsetFrom (array, from, offset) {
- for (var i = from; i < array.length; i++) {
- array[i] += offset;
- };
- }
-
- function recursiveLength (item) {
- var children = uki.attr(item, 'children'),
- length = children.length;
-
- for (var i=0; i < children.length; i++) {
- if (children[i].__opened) length += recursiveLength(children[i]);
- };
- return length;
- }
-
- this._openSubElement = function(index) {
- var item = this._data[index],
- children = uki.attr(item, 'children');
-
- if (!children || !children.length) return 0;
- var length = children.length;
-
- item.__opened = true;
- this._data.splice.apply(this._data, [index+1, 0].concat( this._treeNodeToListData(children, item.__indent + 1) ));
-
- for (var i=children.length - 1; i >= 0 ; i--) {
- if (this._data[index+1+i].__opened) {
- length += this._openSubElement(index+1+i);
- }
- };
- return length;
- };
-
- this.open = function(index) {
- if (this._data[index].__opened) return this;
-
- var length = this._openSubElement(index),
- positionInSelection = uki.binarySearch(index, this._selectedIndexes),
- clickIndex = this._lastClickIndex,
- indexes = this._selectedIndexes;
-
- this.clearSelection(true);
- offsetFrom(
- indexes,
- positionInSelection + (indexes[positionInSelection] == index ? 1 : 0),
- length
- );
-
- this.listData(this._data);
- this.selectedIndexes(indexes);
- this._lastClickIndex = clickIndex > index ? clickIndex + length : clickIndex;
- this.trigger('open');
- return this;
- };
-
- this.close = function(index) {
- var item = this._data[index],
- indexes = this._selectedIndexes,
- children = uki.attr(item, 'children');
- if (!children || !children.length || !item.__opened) return;
-
- var length = recursiveLength(item);
-
- item.__opened = false;
- this._data.splice(index+1, length);
-
- var positionInSelection = uki.binarySearch(index, indexes),
- removeFrom = positionInSelection + (indexes[positionInSelection] == index ? 1 : 0),
- toRemove = 0,
- clickIndex = this._lastClickIndex;
- while (indexes[removeFrom + toRemove] && indexes[removeFrom + toRemove] <= index + length) toRemove++;
-
- this.clearSelection(true);
- offsetFrom(indexes, removeFrom, -length);
- if (toRemove > 0) {
- indexes.splice(positionInSelection, toRemove);
- }
-
- this.listData(this._data);
- this.selectedIndexes(indexes);
- this._lastClickIndex = clickIndex > index ? clickIndex - length : clickIndex;
- this.trigger('close');
- };
-
- this._mousedown = function(e) {
- if (e.target.className.indexOf('toggle-tree') > -1) {
- var o = uki.dom.offset(this._dom),
- y = e.pageY - o.y,
- p = y / this._rowHeight << 0;
- this.toggle(p);
- } else {
- Base._mousedown.call(this, e);
- }
- };
-
- this._keypress = function(e) {
- Base._keypress.call(this, e);
- e = e.domEvent;
- if (e.which == 39 || e.keyCode == 39) { // RIGHT
- this.open(this._lastClickIndex);
- } else if (e.which == 37 || e.keyCode == 37) { // LEFT
- this.close(this._lastClickIndex);
- }
- };
-
-});
-// tree list render
-uki.more.view.treeList.Render = uki.newClass(uki.view.list.Render, new function() {
- this._parentTemplate = new uki.theme.Template(
- '<div class="${classPrefix}-row ${classPrefix}-${opened}" style="margin-left:${indent}px">' +
- '<div class="${classPrefix}-toggle"><i class="toggle-tree"></i></div>${text}' +
- '</div>'
- );
-
- this._leafTemplate = new uki.theme.Template(
- '<div class="${classPrefix}-row" style="margin-left:${indent}px">${text}</div>'
- );
-
- this.initStyles = function() {
- this.classPrefix = 'treeList-' + uki.guid++;
- var style = new uki.theme.Template(
- '.${classPrefix}-row { color: #333; position:relative; padding-top:3px; } ' +
- '.${classPrefix}-toggle { overflow: hidden; position:absolute; left:-15px; top:5px; width: 10px; height:9px; } ' +
- '.${classPrefix}-toggle i { display: block; position:absolute; left: 0; top: 0; width:20px; height:18px; background: url(${imageSrc});} ' +
- '.${classPrefix}-selected { background: #3875D7; } ' +
- '.${classPrefix}-selected .${classPrefix}-row { color: #FFF; } ' +
- '.${classPrefix}-selected i { left: -10px; } ' +
- '.${classPrefix}-selected-blured { background: #CCCCCC; } ' +
- '.${classPrefix}-opened i { top: -9px; }'
- ).render({
- classPrefix: this.classPrefix,
- imageSrc: 'i/arrows.png' // should call uki.image here
- });
- uki.dom.createStylesheet(style);
- };
-
- this.render = function(row, rect, i) {
- this.classPrefix || this.initStyles();
- var text = row.data,
- children = uki.attr(row, 'children');
- if (children && children.length) {
- return this._parentTemplate.render({
- text: text,
- indent: row.__indent*18 + 22,
- classPrefix: this.classPrefix,
- opened: row.__opened ? 'opened' : ''
- });
- } else {
- return this._leafTemplate.render({
- text: text,
- indent: row.__indent*18 + 22,
- classPrefix: this.classPrefix
- });
- }
- };
-
- this.setSelected = function(container, data, state, focus) {
- container.className = !state ? '' : focus ? this.classPrefix + '-selected' : this.classPrefix + '-selected-blured';
- };
-});
-
-uki.view.declare('uki.more.view.ToggleButton', uki.view.Button, function(Base) {
-
- this._setup = function() {
- Base._setup.call(this);
- this._focusable = false;
- };
-
- this.value = this.checked = uki.newProp('_checked', function(state) {
- this._checked = !!state;
- this._updateBg();
- });
-
- this._updateBg = function() {
- var name = this._disabled ? 'disabled' : this._down || this._checked ? 'down' : this._over ? 'hover' : 'normal';
- this._backgroundByName(name);
- };
-
- this._mouseup = function(e) {
- if (!this._down) return;
- this._down = false;
- if (!this._disabled) this.checked(!this.checked())
- };
-
-});
-
-
-uki.view.declare('uki.more.view.RadioButton', uki.more.view.ToggleButton, function(base) {
- var manager = uki.view.Radio;
-
- this.group = uki.newProp('_group', function(g) {
- manager.unregisterGroup(this);
- this._group = g;
- manager.registerGroup(this);
- if (this.checked()) manager.clearGroup(this);
- });
-
- this.value = this.checked = uki.newProp('_checked', function(state) {
- this._checked = !!state;
- if (state) manager.clearGroup(this);
- this._updateBg();
- });
-
- this._mouseup = function() {
- if (!this._down) return;
- this._down = false;
- if (!this._checked && !this._disabled) {
- this.checked(!this._checked);
- this.trigger('change', {checked: this._checked, source: this});
- }
- }
-});
-uki.more.view.splitTable = {};
-
-uki.view.declare('uki.more.view.SplitTable', uki.view.Container, function(Base) {
- var Rect = uki.geometry.Rect,
- Size = uki.geometry.Size;
-
- var propertiesToDelegate = 'rowHeight data packSize visibleRectExt render selectedIndex focusable textSelectable multiselect'.split(' ');
-
-
- this._defaultHandlePosition = 200;
- this._headerHeight = 17;
-
- this._style = function(name, value) {
- this._leftHeader.style(name, value);
- this._rightHeader.style(name, value);
- return Base._style.call(this, name, value);
- };
-
- this.columns = uki.newProp('_columns', function(c) {
- this._columns = uki.build(c);
- this._totalWidth = 0;
- this._leftHeader.columns([this._columns[0]]);
-
- this._columns[0].bind('beforeResize', uki.proxy(this._syncHandlePosition, this, this._columns[0]));
-
- for (var i = 1; i < this._columns.length; i++) {
- this._columns[i].position(i - 1);
- this._columns[i].bind('beforeResize', uki.proxy(this._rightColumnResized, this, this._columns[i]));
- };
- this._updateTotalWidth();
- this._rightHeader.columns(Array.prototype.slice.call(this._columns, 1));
- this._splitPane.leftMin(this._columns[0].minWidth() - 1)
- // this._splitPane.handlePosition(this._columns[0].width());
- this._syncHandlePosition(this._splitPane);
- });
-
- uki.each(propertiesToDelegate, function(i, name) {
- this[name] = function(v) {
- if (v === undefined) return this._leftList[name]();
- this._leftList[name](v);
- this._rightList[name](v);
- return this;
- };
- }, this);
-
- this.hasFocus = function() {
- return this._leftList.hasFocus() || this._rightList.hasFocus();
- };
-
- this.rightColumns = function() {
- return this._rightHeader.columns();
- };
-
- this._rightColumnResized = function(column) {
- this._updateTotalWidth();
- this._horizontalScroll.layout();
- };
-
- this.rowHeight = function(value) {
- if (value === undefined) return this._leftList.rowHeight();
- this._leftList.rowHeight(value);
- this._rightList.rowHeight(value);
- return this;
- };
-
- this.data = function(d) {
- if (d === undefined) return uki.map(this._leftList.data(), function(value, i) {
- return [value].concat(this._rightList.data()[i]);
- }, this);
-
- this._leftList.data(uki.map(d, function(value) {
- return [value[0]];
- }));
-
- this._rightList.data(uki.map(d, function(value) {
- return value.slice(1);
- }));
-
- this._splitPane.minSize(new Size(0, this._leftList.minSize().height));
- this._verticalScroll.layout();
- };
-
- this._createDom = function() {
- Base._createDom.call(this);
- var scrollWidth = uki.view.ScrollPane.initScrollWidth(),
- bodyHeight = this.rect().height - this._headerHeight - scrollWidth,
- contents = uki(
- [
- {
- view: 'table.Header',
- rect: new Rect(this._defaultHandlePosition, this._headerHeight),
- anchors: 'left top'
- },
- {
- view: 'Box',
- className: 'table-header-container',
- style: { overflow: 'hidden' },
- rect: new Rect(this._defaultHandlePosition, 0, this.rect().width - this._defaultHandlePosition - 1, this._headerHeight),
- anchors: 'left top right',
- childViews: {
- view: 'table.Header',
- rect: new Rect(this.rect().width - this._defaultHandlePosition - 1, this._headerHeight),
- anchors: 'top left right',
- className: 'table-header'
- }
- },
- {
- view: 'ScrollPane',
- rect: new Rect(0, this._headerHeight, this.rect().width, bodyHeight),
- anchors: 'left top right bottom',
- className: 'table-v-scroll',
- scrollV: true,
- childViews: [
- {
- view: 'HSplitPane',
- rect: new Rect(this.rect().width, bodyHeight),
- anchors: 'left top right bottom',
- className: 'table-horizontal-split-pane',
- handlePosition: this._defaultHandlePosition,
- handleWidth: 1,
- leftChildViews: [
- {
- view: 'List',
- rect: new Rect(this._defaultHandlePosition, bodyHeight),
- anchors: 'left top right bottom',
- className: 'table-list-left'
- }
- ],
- rightChildViews: [
- {
- view: 'Box',
- rect: '0 0 100 100',
- anchors: 'left top right bottom',
- style: { overflow: 'hidden' },
- rect: new Rect(this.rect().width - this._defaultHandlePosition - 1, bodyHeight),
- childViews: {
- view: 'ScrollPane',
- rect: new Rect(this.rect().width - this._defaultHandlePosition - 1, bodyHeight + scrollWidth),
- scrollableV: false,
- scrollableH: true,
- anchors: 'left top right bottom',
- className: 'table-h-scroll',
- childViews: [
- {
- view: 'List',
- rect: new Rect(this.rect().width - this._defaultHandlePosition - 1, bodyHeight + scrollWidth),
- anchors: 'left top right bottom'
- }
- ]
- }
-
- }
- ]
- }
- ]
- },
- {
- view: 'ScrollPane',
- rect: new Rect(this._defaultHandlePosition + 1, bodyHeight + this._headerHeight, this.rect().width - this._defaultHandlePosition - 1, scrollWidth),
- anchors: 'left bottom right',
- scrollableH: true,
- scrollableV: false,
- scrollH: true,
- className: 'table-h-scroll-bar',
- childViews: { view: 'Box', rect: '1 1', anchors: 'left top' }
- }
- ]).appendTo(this);
-
- this._verticalScroll = uki('ScrollPane[className=table-v-scroll]', this)[0];
- this._horizontalScroll = uki('ScrollPane[className=table-h-scroll]', this)[0];
- this._horizontalScrollBar = uki('ScrollPane[className=table-h-scroll-bar]', this)[0];
- this._leftList = uki('List:eq(0)', this)[0];
- this._rightList = uki('List:eq(1)', this)[0];
- this._splitPane = uki('HSplitPane', this)[0];
- this._leftHeader = uki('table.Header:eq(0)', this)[0];
- this._rightHeader = uki('table.Header:eq(1)', this)[0];
- this._rightHeaderContainer = uki('[className=table-header-container]', this)[0];
- this._dummyScrollContents = uki('Box', this._horizontalScrollBar);
-
- this._leftList._scrollableParent = this._verticalScroll;
- this._rightList._scrollableParent = this._verticalScroll;
- this._verticalScroll.bind('scroll', uki.proxy(this._leftList._scrollableParentScroll, this._leftList));
- this._verticalScroll.bind('scroll', uki.proxy(this._rightList._scrollableParentScroll, this._rightList));
-
- this._leftList.render(new uki.more.view.splitTable.Render(this._leftHeader));
- this._rightList.render(new uki.more.view.splitTable.Render(this._rightHeader));
- this._bindEvents();
- };
-
- this._bindEvents = function() {
- this._splitPane.bind('handleMove', uki.proxy(this._syncHandlePosition, this, this._splitPane));
- this._horizontalScroll.bind('scroll', uki.proxy(this._syncHScroll, this, this._horizontalScroll));
- this._horizontalScrollBar.bind('scroll', uki.proxy(this._syncHScroll, this, this._horizontalScrollBar));
- this._leftList.bind('selection', uki.proxy(this._syncSelection, this, this._leftList));
- this._rightList.bind('selection', uki.proxy(this._syncSelection, this, this._rightList));
- };
-
- var updatingHandlePosition = false;
- this._syncHandlePosition = function(source) {
- if (updatingHandlePosition) return;
- updatingHandlePosition = true;
- var w, rect;
- if (source == this._splitPane) {
- w = this._splitPane.handlePosition() + 1;
- this.columns()[0].width(w);
- } else {
- var w = this.columns()[0].width();
- this._splitPane.handlePosition(w - 1).layout();
- }
-
- this._leftHeader.rect(new Rect(w, this._headerHeight)).layout();
-
- rect = this._rightHeaderContainer.rect().clone();
- rect.x = w;
- rect.width = this._rect.width - w - uki.view.ScrollPane.initScrollWidth();
- this._rightHeaderContainer.rect(rect).layout();
- rect = this._horizontalScrollBar.rect().clone();
- rect.x = w;
- rect.width = this._rect.width - w - uki.view.ScrollPane.initScrollWidth();
- this._horizontalScrollBar.rect(rect).layout();
- updatingHandlePosition = false;
- };
-
- var updatingHScroll = false;
- this._syncHScroll = function(source) {
- if (updatingHScroll) return;
- updatingHScroll = true;
- var scroll, target = source == this._horizontalScroll ? this._horizontalScrollBar : this._horizontalScroll;
- scroll = source.scrollLeft();
- target.scrollLeft(scroll);
- this._rightHeader.dom().style.marginLeft = -scroll + 'px';
- updatingHScroll = false;
- };
-
- var updatingSelection = false;
- this._syncSelection = function(source) {
- if (updatingSelection) return;
- updatingSelection = true;
- var target = source == this._leftList ? this._rightList : this._leftList;
- target.selectedIndexes(source.selectedIndexes());
- updatingSelection = false;
- };
-
- this._updateTotalWidth = function() {
- this._totalWidth = 0;
- for (var i=1; i < this._columns.length; i++) {
- this._totalWidth += this._columns[i].width();
- };
- this._rightHeader.minSize(new Size(this._totalWidth, 0));
- this._rightList.minSize(new Size(this._totalWidth, this._rightList.minSize().height));
- this._dummyScrollContents.rect(new Rect(this._totalWidth, 1)).parent().layout();
- this._rightHeader.minSize(new Size(this._totalWidth, 0));
- this._horizontalScroll.layout();
- };
-
-});
-uki.more.view.splitTable.Render = uki.newClass(uki.view.table.Render, new function() {
-
- this.setSelected = function(container, data, state, focus) {
- focus = true;
- container.style.backgroundColor = state && focus ? '#3875D7' : state ? '#CCC' : '';
- container.style.color = state && focus ? '#FFF' : '#000';
- }
-
-});
-
-
-uki.view.declare('uki.more.view.Form', uki.view.Container, function(Base) {
-
- this._setup = function() {
- Base._setup.call(this);
- uki.extend(this, {
- _method: 'GET',
- _action: ''
- });
- };
-
- this.action = uki.newProp('_action', function(action) {
- this._dom.action = this._action = action;
- });
- this.method = uki.newProp('_method', function(method) {
- this._dom.method = this._method = method;
- });
-
- this.submit = function() { this._dom.submit(); }
- this.reset = function() { this._dom.reset(); }
-
- this._createDom = function() {
- this._dom = uki.createElement('form', Base.defaultCss);
- this._initClassName();
- this._dom.action = this._action;
- this._dom.method = this._method;
- };
-
-});
-
-
-uki.view.declare('uki.more.view.Select', uki.view.Checkbox, function(Base) {
- this._backgroundPrefix = 'select-';
- this._popupBackground = 'theme(select-popup)';
- this._listBackground = 'theme(select-list)';
- this._popupOffset = 0;
-
- this._setup = function() {
- Base._setup.call(this);
- this._inset = new uki.geometry.Inset(0, 20, 0, 4);
- this._selectFirst = true;
- this._focusable = true;
- this._options = [];
- this._maxPopupHeight = 200;
- this._lastScroll = 0;
- };
-
- this.Render = uki.newClass(uki.view.list.Render, function(Base) {
- this.render = function(data, rect, i) {
- return '<span style="line-height: 22px; text-align: left; white-space: nowrap; margin: 0 4px; cursor: default">' + data + '</span>';
- }
-
- this.setSelected = function(container, data, state, focus) {
- container.style.backgroundColor = state ? '#3875D7' : '';
- container.style.color = state ? '#FFF' : '#000';
- }
- });
-
- this.selectFirst = uki.newProp('_selectFirst');
-
- this.opened = function() {
- return this._popup.visible() && this._popup.parent();
- };
-
- this.popupAnchors = function(v) {
- if (v === undefined) return this._popup.anchors();
- this._popup.anchors(v);
- return this;
- };
-
- this._createDom = function() {
- Base._createDom.call(this);
- this.style({ fontWeight: 'normal', textAlign: 'left' });
-
- this._label.style.overflow = 'hidden';
- this._popup = uki(
- { view: 'Popup', anchors: 'left top', rect: '100 100', style: {zIndex: 1000}, offset: this._popupOffset,
- background: this._popupBackground, relativeTo: this, visible: false,
- childViews: [
- { view: 'ScrollPane', rect: '100 100', anchors: 'left top right bottom', childViews: [
- { view: 'List', rect: '100 100', anchors: 'left top right bottom', rowHeight: 22,
- textSelectable: false, focusable: true, background: this._listBackground,
- render: new this.Render(), style: { fontSize: '12px' } }
- ] }
- ] }
- )[0];
-
- this._popup.hide();
-
- this._list = uki('List', this._popup)[0];
- this._scroll = uki('ScrollPane', this._popup)[0];
-
- this._popup.bind('toggle', uki.proxy(function(e) {
- this._down = this._popup.visible();
- if (this._popup.visible()) {
- this._updateWidth();
- this._scroll.scrollTop(this._lastScroll);
- }
- this._checked = this._popup.visible();
- this._updateBg();
- }, this));
-
- this.bind(this._list.keyPressEvent(), function(e) {
- if (this.preventTransfer) {
- this.preventTransfer = false;
- return;
- }
- if (this._popup.visible()) {
- this._list.trigger(e.type, e);
- }
- });
-
- this.bind('blur', function() {
- setTimeout(uki.proxy(function() {
- if (!this._hasFocus && this.opened()) {
- this._lastScroll = this._scroll.scrollTop();
- this._popup.hide();
- }
- }, this), 50)
- });
-
- // refocus on list click
- this._list.bind('focus', uki.proxy(function() {
- this._hasFocus = false;
- this.focus();
- // setTimeout(uki.proxy(this.focus, this), 5);
- }, this));
-
- this._list.bind('click', uki.proxy(this.selectCurrent, this));
- };
-
- this.contentsSize = function(autosize) {
- var html = this.html(), size;
- this.html(this._longestText);
- size = Base.contentsSize.call(this, autosize);
- this.html(html);
- return size;
- };
-
- this._keydown = function(e) {
- if ((e.which == 32 || e.which == 13) && this._popup.visible()) {
- this.selectCurrent(e);
- } else if ((e.which == 40 || e.which == 38) && !this._popup.visible()) {
- this._popup.toggle();
- e.preventDefault();
- this.preventTransfer = true;
- } else {
- Base._keydown.call(this, e);
- }
- };
-
- this.selectCurrent = function(e) {
- if (this.selectedIndex() == -1) {
- this.text(this._selectFirst && this._options[0] ? this._options[0].text : '');
- } else {
- this.text(this._options[this.selectedIndex()].text);
- }
- this._lastScroll = this._scroll.scrollTop();
- this._popup.hide();
- if (e) this.trigger('change', { source: this });
- };
-
- this.value = function(v) {
- if (v === undefined) {
- return this._options[this.selectedIndex()] ? this._options[this.selectedIndex()].value : undefined;
- } else {
- var index = -1,
- option,
- l = this._options.length,
- i;
- for (i=0; i < l; i++) {
- option = this._options[i];
- if (option.value == v) {
- index = i;
- break;
- }
- };
- this.selectedIndex(index);
- this.selectCurrent();
- }
- };
-
- this.maxPopupHeight = uki.newProp('_maxPopupHeight');
-
- this._updateWidth = function() {
- if (this._widthCached || !this._options.length) return;
- var source = this._list.dom().firstChild.firstChild.firstChild, /// omg!
- html = source.innerHTML;
-
- source.innerHTML = this._longestText;
- this._widthCached = source.offsetWidth + 8;
- source.innerHTML = html;
- this._popup.rect(new uki.geometry.Rect(
- this._popup.rect().x,
- this._popup.rect().y,
- Math.max(this._widthCached, this.rect().width),
- Math.min(this._maxPopupHeight, this._options.length * 22)
- )).layout();
- };
-
- this.options = uki.newProp('_options', function(o) {
- this._options = o;
- this._list
- .data(uki.map(o, 'text'))
- .selectedIndex(0);
-
- if (this._selectFirst && (o.length > 0)) this.text(o[0].text);
- this._longestText = '';
- uki.each(o, function(i, row) {
- if (row.text.length > this._longestText.length) this._longestText = row.text;
- }, this);
- this._widthCached = false;
- this._lastScroll = 0;
- });
-
- uki.delegateProp(this, 'selectedIndex', '_list');
-
- this._updateBg = function() {
- return Base._updateBg.call(this);
- };
-
- this._mousedown = function(e) {
- Base._mousedown.call(this, e);
- if (this.disabled()) return;
- this._popup.toggle();
- this.trigger('toggle', { opened: this.opened() });
- // if (this._popup.visible()) this._list.focus();
- };
-
- this._mouseup = function(e) {
- if (!this._down) return;
- this._down = false;
- };
-
-});
-
-uki.Collection.addAttrs(['options']);
-
-
-(function() {
- function selectHandle (image, css) {
- return new uki.background.CssBox((css || '') + 'background: url(' + uki.theme.imageSrc(image) + '); background-position: 100% 50%; background-repeat: no-repeat;');
- }
-
- var theme = uki.extend({}, uki.theme.Base, {
- backgrounds: {
- // 'select-list': function() {
- //
- // },
- // 'select-popup': function() {
- //
- // },
- 'select-normal': function() {
- return new uki.background.Multi(
- selectHandle('select-handle-normal'),
- uki.theme.background('button-normal')
- );
- },
- 'select-hover': function() {
- return new uki.background.Multi(
- selectHandle('select-handle-normal'),
- uki.theme.background('button-hover')
- );
- },
- 'select-checked-normal': function() {
- return new uki.background.Multi(
- selectHandle('select-handle-normal'),
- uki.theme.background('button-down')
- );
- },
- 'select-disabled': function() {
- return new uki.background.Multi(
- selectHandle('select-handle-normal', 'opacity:0.4;'),
- uki.theme.background('button-disabled')
- );
- },
-
- 'select-popup': function() {
- return uki.theme.background('popup-normal');
- }
- },
-
- imageSrcs: {
- 'select-handle-normal': function() {
- return ["select-down-m.png", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAABkCAYAAABtnKvPAAAAeUlEQVRo3u3SMQ2AMBAFUCQgAQlIQUKTthq6IhEpOIAOTIWFABPvkr/c8IZ/15VStu6rgcPhcDgcDofD4XA4HA6HnybnvNRsF1ke4yGEoUJrA691379SS4xxavDx1c5TSvMBh08Oegv253A4HA6Hw+FwOBwOh8P/ie9z0RuWFOYPhAAAAABJRU5ErkJggg==", "select-down-m.gif"];
- }
- }
- });
- theme.backgrounds['select-checked-hover'] = theme.backgrounds['select-checked-normal'];
-
- uki.theme.register(theme);
-})();
-
diff --git a/app/assets/javascripts/uki.js b/app/assets/javascripts/uki.js
deleted file mode 100644
index e748c85..0000000
--- a/app/assets/javascripts/uki.js
+++ /dev/null
@@ -1,8022 +0,0 @@
-/*!
- * uki JavaScript Library
- * Licensed under the MIT license http://ukijs.org/LICENSE
- *
- * Copyright (c) 2010 Vladimir Kolesnikov
- *
- * Parts of code derived from jQuery JavaScript Library
- * Copyright (c) 2009 John Resig
- */
-(function() {
- /**
- * Global uki constants, for speed optimization and better merging
- */
-/** @ignore */
-var root = this,
- doc = document,
- nav = navigator,
- ua = nav.userAgent,
- expando = 'uki' + (+new Date),
-
- MAX = Math.max,
- MIN = Math.min,
- FLOOR = Math.floor,
- CEIL = Math.ceil,
-
- PX = 'px';
-
-
-
-/**
- * Shortcut access to uki.build, uki.Selector.find and uki.Collection constructor
- * uki('#id') is also a shortcut for search by id
- *
- * @param {String|uki.view.Base|Object|Array.<uki.view.Base>} val
- * @param {Array.<uki.view.Base>=} optional context for selector
- * @class
- * @namespace
- * @name uki
- * @return {uki.Collection}
- */
-root.uki = root.uki || function(val, context) {
- if (typeof val === "string") {
-
- var m = val.match(/^#((?:[\w\u00c0-\uFFFF_-]|\\.)+)$/),
- e = m && uki._ids[m[1]];
- if (m && !context) {
- return new uki.Collection( e ? [e] : [] );
- }
- return uki.find(val, context);
-
- }
- if (val.length === undefined) val = [val];
- if (val.length > 0 && uki.isFunction(val[0].typeName)) return new uki.Collection(val);
-
- return uki.build(val);
-};
-
-/**
- * @type string
- * @field
- */
-uki.version = '0.3.8';
-uki.guid = 1;
-
-/**
- * Empty function
- * @type function():boolean
- */
-uki.F = function() { return false; };
-uki._ids = {};
-
-uki.registerId = function(comp) {
- uki._ids[ uki.attr(comp, 'id') ] = comp;
-};
-uki.unregisterId = function(comp) {
- uki._ids[ uki.attr(comp, 'id') ] = undefined;
-};
-
-
-
-(function() {
-
-var toString = Object.prototype.toString,
- trim = String.prototype.trim,
- slice = Array.prototype.slice,
-
- trimRe = /^\s+|\s+$/g;
-
-var marked = '__uki_marked';
-
-// dummy subclass
-/** @ignore */
-function inheritance () {}
-
-/**
- * Utility functions.
- */
-var utils = {
-
- /**
- * Sets or retrieves attribute on an object.
- * <p>If target has function with attr it will be called target[attr](value=)
- * If no function present attribute will be set/get directly: target[attr] = value or return target[attr]</p>
- *
- * @example
- * uki.attr(view, 'name', 'funny') // sets name to funny on view
- * uki.attr(view, 'id') // gets id attribute of view
- *
- * @param {object} target
- * @param {string} attr Attribute name
- * @param {object=} value Value to set
- * @returns {object} target if value is being set, retrieved value otherwise
- */
- attr: function(target, attr, value) {
- if (value !== undefined) {
- if (target[attr] && target[attr].apply) {
- // if (uki.isFunction(target[attr])) {
- target[attr](value);
- } else {
- target[attr] = value;
- }
- return target;
- } else {
- if (target[attr] && target[attr].apply) {
- // if (uki.isFunction(target[attr])) {
- return target[attr]();
- } else {
- return target[attr];
- }
- }
- },
-
- /**
- * Runs a function in a given context
- *
- * @param {function()} fn
- * @param {object} context
- */
- proxy: function(fn, context) {
- var args = slice.call(arguments, 2),
- result = function() {
- return fn.apply(context, args.concat(slice.call(arguments, 0)));
- };
- result.huid = fn.huid = fn.huid || uki.guid++;
- return result;
- },
-
- /**
- * Checks if obj is a function
- *
- * @param {object} object Object to check
- * @returns {boolean}
- */
- isFunction: function( obj ) {
- return toString.call(obj) === "[object Function]";
- },
-
- /**
- * Checks if obj is an Array
- *
- * @param {object} object Object to check
- * @returns {boolean}
- */
- isArray: function( obj ) {
- return toString.call(obj) === "[object Array]";
- },
-
- /**
- * Trims the string
- *
- * @param {string} text
- * @returns {string} trimmed text
- */
- trim: function( text ) {
- text = text || '';
- return trim ? trim.call(text) : text.replace( trimRe, "" );
- },
-
- /**
- * Converts unsafe symbols to entities
- *
- * @param {string} html
- * @returns {string} escaped html
- */
- escapeHTML: function( html ) {
- var trans = {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- '"': '&quot;',
- "'": '&#x27;'
- };
- return (html + '').replace(/[&<>\"\']/g, function(c) { return trans[c]; });
- },
-
- /**
- * Iterates through all non empty values of object or an Array
- *
- * @param {object|Array} object Object to iterate through
- * @param {function(number, object):boolean} callback Called for every item, may return false to stop iteration
- * @param {object} context Context in which callback should called. If not specified context will be set to
- * current item
- * @returns {object}
- */
- each: function( object, callback, context ) {
- var name, i = 0, length = object.length;
-
- if ( length === undefined ) {
- for ( name in object ) {
- if ( !name || object[ name ] === undefined || !object.hasOwnProperty(name) ) continue;
- if ( callback.call( context || object[ name ], name, object[ name ] ) === false ) { break; }
- }
- } else {
- for ( var value = object[0]; i < length && callback.call( context || value, i, value ) !== false; value = object[++i] ){}
- }
- return object;
- },
-
- /**
- * Checks if elem is in array
- *
- * @param {object} elem
- * @param {object} array
- * @returns {boolean}
- */
- inArray: function( elem, array ) {
- for ( var i = 0, length = array.length; i < length; i++ ) {
- if ( array[ i ] === elem ) { return i; }
- }
-
- return -1;
- },
-
- /**
- * Returns unique elements in array
- *
- * @param {Array} array
- * @returns {Array}
- */
- unique: function( array ) {
- if (array.length && (typeof array[0] == 'object' || typeof array[0] == 'function')) {
- var result = [],
- i;
-
- for (i = 0; i < array.length; i++) {
- if (!array[i][marked]) { result[result.length] = array[i]; }
- array[i][marked] = true;
- };
- for (i = 0; i < result.length; i++) {
- delete result[i][marked];
- };
- return result;
-
- } else {
-
- var ret = [],
- done = {};
-
- for ( var i = 0, length = array.length; i < length; i++ ) {
- var id = array[ i ];
-
- if ( !done[ id ] ) {
- done[ id ] = true;
- ret.push( array[ i ] );
- }
- }
-
- return ret;
- }
- },
-
- /**
- * Searches for all items matching given criteria
- *
- * @param {Array} elems Element to search through
- * @param {function(object, number)} callback Returns true for every matched element
- * @returns {Array} matched elements
- */
- grep: function( elems, callback ) {
- var ret = [];
-
- for ( var i = 0, length = elems.length; i < length; i++ ) {
- if ( callback( elems[ i ], i ) ) { ret.push( elems[ i ] ); }
- }
-
- return ret;
- },
-
- /**
- * Maps elements passing them to callback
- * @example
- * x = uki.map([1, 2, 3], function(item) { return -item });
- *
- * @param {Array} elems Elements to map
- * @param {function(object, number)} mapping function
- * @param {object} context Context in which callback should called. If not specified context will be set to
- * current item
- * @returns {Array} mapped values
- */
- map: function( elems, callback, context ) {
- var ret = [],
- mapper = uki.isFunction(callback) ? callback :
- function(e) { return uki.attr(e, callback); };
-
- for ( var i = 0, length = elems.length; i < length; i++ ) {
- var value = mapper.call( context || elems[ i ], elems[ i ], i );
-
- if ( value != null ) { ret[ ret.length ] = value; }
- }
-
- return ret;
- },
-
- /**
- * Reduces array
- * @example
- * x = uki.reduce(1, [1, 2, 3], function(p, x) { return p * x}) // calculates product
- *
- * @param {object} initial Initial value
- * @param {Array} elems Elements to reduce
- * @param {function(object, number)} reduce function
- * @param {object} context Context in which callback should called. If not specified context will be set to
- * current item
- * @returns {object}
- */
- reduce: function( initial, elems, callback, context ) {
- for ( var i = 0, length = elems.length; i < length; i++ ) {
- initial = callback.call( context || elems[ i ], initial, elems[ i ], i );
- }
- return initial;
- },
-
- /**
- * Copies properties from one object to another
- * @example
- * uki.extend(x, { width: 13, height: 14 }) // sets x.width = 13, x.height = 14
- * options = uki.extend({}, defaultOptions, options)
- *
- * @param {object} target Object to copy properties into
- * @param {...object} sources Objects to take properties from
- * @returns Describe what it returns
- */
- extend: function() {
- var target = arguments[0] || {}, i = 1, length = arguments.length, options;
-
- for ( ; i < length; i++ ) {
- if ( (options = arguments[i]) != null ) {
-
- for ( var name in options ) {
- var copy = options[ name ];
-
- if ( copy !== undefined ) {
- target[ name ] = copy;
- }
-
- }
- }
- }
-
- return target;
- },
-
- /**
- * Creates a new class inherited from base classes. Init function is used as constructor
- * @example
- * baseClass = uki.newClass({
- * init: function() { this.x = 3 }
- * });
- *
- * childClass = uki.newClass(baseClass, {
- * getSqrt: function() { return this.x*this.x }
- * });
- *
- * @param {object=} superClass If superClass has prototype "real" prototype base inheritance is used,
- * otherwise superClass properties are simply copied to newClass prototype
- * @param {Array.<object>=} mixins
- * @param {object} methods
- * @returns Describe what it returns
- */
- newClass: function(/* [[superClass], mixin1, mixin2, ..] */ methods) {
- var klass = function() {
- this.init.apply(this, arguments);
- },
-
- i, startFrom = 0, tmp, baseClasses = [], base, name, copy, $arguments = arguments, length;
-
- if ((length = $arguments.length) > 1) {
- base = $arguments[0];
- if (base.prototype) { // real inheritance
- inheritance.prototype = base.prototype;
- klass.prototype = new inheritance();
- startFrom = 1;
- baseClasses = [inheritance.prototype];
-
- // class method inheritance
- for ( name in base ) {
- copy = base[ name ];
- if ( !base.hasOwnProperty(name) || copy === undefined || name == 'prototype' ) continue;
- klass[ name ] = copy;
- }
- }
- }
-
- for (i=startFrom; i < length; i++) {
- base = $arguments[i];
- if (this.isFunction(base)) {
- tmp = {};
- base.apply(tmp, baseClasses);
- base = tmp;
- }
- baseClasses[ baseClasses.length ] = base;
-
- uki.extend(klass.prototype, base);
- };
- if (!klass.prototype.init) klass.prototype.init = function() {};
- return klass;
- },
-
- /**
- * Search closest value in a sorted array
- * @param {nubmer} value to search
- * @param {array} array sorted array
- * @returns {number} index of closest value
- */
- binarySearch: function (value, array) {
- var low = 0, high = array.length, mid;
-
- while (low < high) {
- mid = (low + high) >> 1;
- array[mid] < value ? low = mid + 1 : high = mid;
- }
-
- return low;
- },
-
-
- /**
- * Creates default uki property function
- * <p>If value is given to this function it sets property to value
- * If no arguments given than function returns current property value</p>
- *
- * <p>Optional setter can be given. In this case setter will be called instead
- * of simple this[field] = value</p>
- *
- * <p>If used as setter function returns self</p>
- *
- * @example
- * x.width = uki.newProperty('_width');
- * x.width(12); // x._width = 12
- * x.width(); // return 12
- *
- * @param {string} field Field name
- * @param {function(object)=} setter
- * @returns {function(object=):object}
- */
- newProp: function(field, setter) {
- return function(value) {
- if (value === undefined) return this[field];
- if (setter) { setter.call(this, value); } else { this[field] = value; };
- return this;
- };
- },
-
- /**
- * Adds several properties (uki.newProp) to a given object.
- * <p>Field name equals to '_' + property name</p>
- *
- * @example
- * uki.addProps(x, ['width', 'height'])
- *
- * @param {object} proto Object to add properties to
- * @param {Array.<string>} props Property names
- */
- addProps: function(proto, props) {
- for (var i =0, len = props.length; i<len; i++)
- proto[ props[i] ] = uki.newProp('_' + props[i]);
- },
-
- toArray: function(arr) {
- return slice.call(arr, 0);
- },
-
- delegateProp: function(proto, name, target) {
- var propName = '_' + name;
- proto[name] = function(value) {
- if (value === undefined) {
- if (this[target]) return uki.attr(this[target], name, value);
- return this[propName];
- }
- if (this[target]) {
- uki.attr(this[target], name, value);
- } else {
- this[propName] = value;
- }
- return this;
- };
- },
-
- camalize: function(string) {
- return string.replace(/[-_]\S/g, function(v) {
- return v.substr(1).toUpperCase();
- });
- },
-
- dasherize: function(string) {
- return string.replace(/[A-Z]/g, function(v) {
- return '-' + v.toLowerCase();
- });
- }
-};
-utils.extend(uki, utils);
-
-})();
-
-
-/**
- * Geometry
- *
- * @namespace
- */
-uki.geometry = {};
-
-
-/**
- * Point with x and y properties
- *
- * @author voloko
- * @name uki.geometry.Point
- * @constructor
- *
- * @param {Integer=} x defaults to 0
- * @param {Integer=} y defaults to 0
- */
-var Point = uki.geometry.Point = function(x, y) {
- this.x = x*1.0 || 0.0;
- this.y = y*1.0 || 0.0;
-};
-
-Point.prototype = /** @lends uki.geometry.Point.prototype */ {
-
- /**
- * Converts to "100 50" string
- *
- * @this {uki.geometry.Point}
- * @return {string}
- */
- toString: function() {
- return this.x + ' ' + this.y;
- },
-
- /**
- * Creates a new Point with the same properties
- *
- * @this {uki.geometry.Point}
- * @return {uki.geometry.Point}
- */
- clone: function() {
- return new Point(this.x, this.y);
- },
-
- /**
- * Checks if this equals to another Point
- *
- * @param {uki.geometry.Point} point Point to compare with
- * @this {uki.geometry.Point}
- * @return {boolean}
- */
- eq: function(point) {
- return this.x == point.x && this.y == point.y;
- },
-
- /**
- * Moves point by x, y
- *
- * @this {uki.geometry.Point}
- * @return {uki.geometry.Point} self
- */
- offset: function(x, y) {
- if (typeof x == 'object') {
- y = x.y;
- x = x.x;
- }
- this.x += x;
- this.y += y;
- return this;
- },
-
- constructor: Point
-};
-
-/**
- * Creates point from "x y" string
- *
- * @memberOf uki.geometry.Point
- * @name fromString
- * @function
- *
- * @param {string} string String representation of point
- *
- * @returns {uki.geometry.Point} created point
- */
-Point.fromString = function(string) {
- var parts = string.split(/\s+/);
- return new Point( parts[0], parts[1] );
-};
-
-
-/**
- * Size with width and height properties
- *
- * @param {number=} width defaults to 0
- * @param {number=} height defaults to 0
- * @name uki.geometry.Size
- * @constructor
- */
-var Size = uki.geometry.Size = function(width, height) {
- this.width = width*1.0 || 0.0;
- this.height = height*1.0 || 0.0;
-};
-
-Size.prototype = /** @lends uki.geometry.Size.prototype */ {
- /**
- * Converts size to "300 100" string
- *
- * @this {uki.geometry.Size}
- * @return {string}
- */
- toString: function() {
- return this.width + ' ' + this.height;
- },
-
- /**
- * Creates a new Size with same properties
- *
- * @this {uki.geometry.Size}
- * @return {uki.geometry.Size} new Size
- */
- clone: function() {
- return new Size(this.width, this.height);
- },
-
- /**
- * Checks if this equals to another Size
- *
- * @param {uki.geometry.Size} size Size to compare with
- * @this {uki.geometry.Size}
- * @return {boolean}
- */
- eq: function(size) {
- return this.width == size.width && this.height == size.height;
- },
-
- /**
- * Checks if this size has non-positive width or height
- *
- * @this {uki.geometry.Size}
- * @return {boolean}
- */
- empty: function() {
- return this.width <= 0 || this.height <= 0;
- },
-
- constructor: Size
-};
-
-/**
- * Creates size from "width height" string
- *
- * @memberOf uki.geometry.Size
- * @name fromString
- * @function
- *
- * @param {string} string String representation of size
- *
- * @returns {uki.geometry.Size} created size
- */
-Size.fromString = function(string) {
- var parts = string.split(/\s+/);
- return new Size( parts[0], parts[1] );
-};
-
-/**
- * Creates size from different representations
- * - if no params given returns null
- * - if uki.geometry.Size given returns it
- * - if "200 300" string converts it to size
- * - if two params given creates size from them
- *
- * @memberOf uki.geometry.Size
- * @name create
- * @function
- *
- * @param {...string|number|uki.geometry.Size} var_args Size representation
- *
- * @returns {uki.geometry.Size} created size
- */
-Size.create = function(a1, a2) {
- if (a1 === undefined) return null;
- if (a1.width !== undefined) return a1;
- if (/\S+\s+\S+/.test(a1 + '')) return Size.fromString(a1, a2);
- return new Size(a1, a2);
-};
-
-
-/**
- * Rectangle with x, y, width and height properties
- * May be used as uki.geometry.Point or uki.geometry.Size
- * - if 4 arguments given creates size with x,y,width,height set to the given arguments
- * - if 2 number arguments given creates size with x = y = 0 and width and height set
- * set to the given arguments
- * - if a Point and a Size given creates rect with point as an origin and given size
- *
- * @param {...number|uki.geometry.Point|uki.geometry.Size} var_args
- * @name uki.geometry.Rect
- * @augments uki.geometry.Size
- * @augments uki.geometry.Point
- * @constructor
- */
-var Rect = uki.geometry.Rect = function(a1, a2, a3, a4) {
- if (a3 !== undefined) {
- this.x = a1*1.0 || 0.0;
- this.y = a2*1.0 || 0.0;
- this.width = a3*1.0 || 0.0;
- this.height = a4*1.0 || 0.0;
- } else if (a1 === undefined || a1.x === undefined) {
- this.x = 0;
- this.y = 0;
- this.width = a1*1.0 || 0.0;
- this.height = a2*1.0 || 0.0;
- } else {
- this.x = a1 ? a1.x*1.0 : 0;
- this.y = a1 ? a1.y*1.0 : 0;
- this.width = a2 ? a2.width*1.0 : 0;
- this.height = a2 ? a2.height*1.0 : 0;
- }
-};
-
-Rect.prototype = /** @lends uki.geometry.Rect.prototype */ {
- /**
- * Converts Rect to "x y width height" string
- *
- * @this {uki.geometry.Rect}
- * @returns {string}
- */
- toString: function() {
- return [this.x, this.y, this.width, this.height].join(' ');
- },
-
- /**
- * Converts Rect to "x y maxX maxY" string
- *
- * @this {uki.geometry.Rect}
- * @returns {string}
- */
- toCoordsString: function() {
- return [this.x, this.y, this.maxX(), this.maxY()].join(' ');
- },
-
- /**
- * Creates a new Rect with same properties
- *
- * @this {uki.geometry.Size}
- * @return {uki.geometry.Size} new Size
- */
- clone: function() {
- return new Rect(this.x, this.y, this.width, this.height);
- },
-
- /**
- * Equals to .x
- *
- * @this {uki.geometry.Rect}
- * @returns {number}
- */
- minX: function() {
- return this.x;
- },
-
- /**
- * Equals to x + width
- *
- * @this {uki.geometry.Rect}
- * @returns {number}
- */
- maxX: function() {
- return this.x + this.width;
- },
-
- /**
- * Point between minX and maxX
- *
- * @this {uki.geometry.Rect}
- * @returns {number}
- */
- midX: function() {
- return this.x + this.width / 2.0;
- },
-
- /**
- * Equals to .y
- *
- * @this {uki.geometry.Rect}
- * @returns {number}
- */
- minY: function() {
- return this.y;
- },
-
- /**
- * Point between minY and maxY
- *
- * @this {uki.geometry.Rect}
- * @returns {number}
- */
- midY: function() {
- return this.y + this.height / 2.0;
- },
-
- /**
- * Equals to y + height
- *
- * @this {uki.geometry.Rect}
- * @returns {number}
- */
- maxY: function() {
- return this.y + this.height;
- },
-
- /**
- * Moves origin to 0,0 point
- *
- * @this {uki.geometry.Rect}
- * @returns {uki.geometry.Point} self
- */
- normalize: function() {
- this.x = this.y = 0;
- return this;
- },
-
- /**
- * Checks if this rect has non-positive width or height
- *
- * @this {uki.geometry.Rect}
- * @function
- * @return {boolean}
- */
- empty: Size.prototype.empty,
-
- /**
- * Checks if this equals to another Rect
- *
- * @param {uki.geometry.Rect} rect Rect to compare with
- * @this {uki.geometry.Rect}
- * @return {boolean}
- */
- eq: function(rect) {
- return rect && this.x == rect.x && this.y == rect.y && this.height == rect.height && this.width == rect.width;
- },
-
- /**
- * Insets size with dx and dy
- *
- * @param {number} dx
- * @param {number} dy
- * @this {uki.geometry.Rect}
- * @returns {uki.geometry.Rect} sefl
- */
- inset: function(dx, dy) {
- this.x += dx;
- this.y += dy;
- this.width -= dx*2.0;
- this.height -= dy*2.0;
- return this;
- },
-
- /**
- * Moves origin point by x, y
- *
- * @this {uki.geometry.Rect}
- * @function
- * @return {uki.geometry.Rect} self
- */
- offset: Point.prototype.offset,
-
- /**
- * Intersects this with given rect
- *
- * @this {uki.geometry.Rect}
- * @param {uki.geometry.Rect} rect Rect to intersect with
- * @returns {uki.geometry.Rect} intersection
- */
- intersection: function(rect) {
- var origin = new Point(
- MAX(this.x, rect.x),
- MAX(this.y, rect.y)
- ),
- size = new Size(
- MIN(this.maxX(), rect.maxX()) - origin.x,
- MIN(this.maxY(), rect.maxY()) - origin.y
- );
- return size.empty() ? new Rect() : new Rect(origin, size);
- },
-
- /**
- * Union rect of this and given rect
- *
- * @this {uki.geometry.Rect}
- * @param {uki.geometry.Rect} rect
- * @returns {uki.geometry.Rect} union
- */
- union: function(rect) {
- return Rect.fromCoords(
- MIN(this.x, rect.x),
- MIN(this.y, rect.y),
- MAX(this.maxX(), rect.maxX()),
- MAX(this.maxY(), rect.maxY())
- );
- },
-
- /**
- * Checks if point is within this
- *
- * @this {uki.geometry.Rect}
- * @param {uki.geometry.Point} point
- * @returns {boolean}
- */
- containsPoint: function(point) {
- return point.x >= this.minX() &&
- point.x <= this.maxX() &&
- point.y >= this.minY() &&
- point.y <= this.maxY();
- },
-
- /**
- * Checks if this contains given rect
- *
- * @this {uki.geometry.Rect}
- * @param {uki.geometry.Rect} rect
- * @returns {boolean}
- */
- containsRect: function(rect) {
- return this.eq(this.union(rect));
- },
-
- constructor: Rect
-};
-
-Rect.prototype.left = Rect.prototype.minX;
-Rect.prototype.top = Rect.prototype.minY;
-
-/**
- * Creates Rect from minX, minY, maxX, maxY
- *
- * @memberOf uki.geometry.Rect
- * @name fromCoords
- * @function
- *
- * @param {number} minX
- * @param {number} maxX
- * @param {number} minY
- * @param {number} maxY
- * @returns {uki.geometry.Rect}
- */
-Rect.fromCoords = function(minX, minY, maxX, maxY) {
- if (maxX === undefined) {
- return new Rect(
- minX.x,
- minX.y,
- minY.x - minX.x,
- minY.y - minX.y
- );
- }
- return new Rect(minX, minY, maxX - minX, maxY - minY);
-};
-
-/**
- * Creates Rect from "minX minY maxX maxY" string
- *
- * @memberOf uki.geometry.Rect
- * @name fromCoordsString
- * @function
- *
- * @param {string} string
- * @returns {uki.geometry.Rect}
- */
-Rect.fromCoordsString = function(string) {
- var parts = string.split(/\s+/);
- return Rect.fromCoords(
- parts[0],
- parts[1],
- parts[2],
- parts[3]
- ) ;
-};
-
-/**
- * Creates Rect from "x y width height" or "width height" string
- *
- * @memberOf uki.geometry.Rect
- * @name fromString
- * @function
- *
- * @param {string} string
- * @returns {uki.geometry.Rect}
- */
-Rect.fromString = function(string) {
- var parts = string.split(/\s+/);
-
- if (parts.length > 2) return new Rect(
- parts[0],
- parts[1],
- parts[2],
- parts[3]
- );
- return new Rect(
- parts[0],
- parts[1]
- ) ;
-};
-
-/**
- * Creates rect from different representations
- * - if no params given returns null
- * - if uki.geometry.Rect given returns it
- * - if "200 300" or "0 10 200 300" string converts it to rect
- * - if two or four params given creates rect from them
- *
- * @memberOf uki.geometry.Rect
- * @name creates
- * @function
- *
- * @param {...string|number|uki.geometry.Rect} var_args Rect representation
- *
- * @returns {uki.geometry.Rect} created size
- */
-Rect.create = function(a1, a2, a3, a4) {
- if (a1 === undefined) return null;
- if (a1.x !== undefined) return a1;
- if (/\S+\s+\S+/.test(a1 + '')) return Rect.fromString(a1, a2);
- if (a3 === undefined) return new Rect(a1, a2);
- return new Rect(a1, a2, a3, a4);
-};
-
-
-/**
- * Inset with top, right, bottom and left properties
- * - if no params given top = right = bottom = left = 0
- * - if two params given top = bottom and right = left
- *
- * @param {number=} top
- * @param {number=} right
- * @param {number=} bottom
- * @param {number=} left
- *
- * @name uki.geometry.Inset
- * @constructor
- */
-var Inset = uki.geometry.Inset = function(top, right, bottom, left) {
- this.top = top*1.0 || 0;
- this.right = right*1.0 || 0;
- this.bottom = bottom === undefined ? this.top*1.0 : bottom*1.0;
- this.left = left === undefined ? this.right*1.0 : left*1.0;
-};
-
-Inset.prototype = /** @lends uki.geometry.Inset.prototype */ {
-
- /**
- * Converts Inset to "top right bottom left" string
- *
- * @returns {string}
- */
- toString: function() {
- return [this.top, this.right, this.bottom, this.left].join(' ');
- },
-
- /**
- * Creates a new Inset with same properties
- *
- * @this {uki.geometry.Inset}
- * @return {uki.geometry.Inset} new Inset
- */
- clone: function() {
- return new Inset(this.top, this.right, this.bottom, this.left);
- },
-
- /**
- * left + right
- *
- * @this {uki.geometry.Inset}
- * @return {number}
- */
- width: function() {
- return this.left + this.right;
- },
-
- /**
- * top + bottom
- *
- * @this {uki.geometry.Inset}
- * @return {number}
- */
- height: function() {
- return this.top + this.bottom;
- },
-
- /**
- * True if any property < 0
- *
- * @this {uki.geometry.Inset}
- * @return {boolean}
- */
- negative: function() {
- return this.top < 0 || this.left < 0 || this.right < 0 || this.bottom < 0;
- },
-
- /**
- * True if all properties = 0
- *
- * @this {uki.geometry.Inset}
- * @return {boolean}
- */
- empty: function() {
- return !this.top && !this.left && !this.right && !this.bottom;
- }
-};
-
-/**
- * Creates Rect from "top right bottom left" or "top right" string
- *
- * @memberOf uki.geometry.Inset
- * @name fromString
- * @function
- *
- * @param {string} string
- * @returns {uki.geometry.Inset}
- */
-Inset.fromString = function(string) {
- var parts = string.split(/\s+/);
- if (parts.length < 3) parts[2] = parts[0];
- if (parts.length < 4) parts[3] = parts[1];
-
- return new Inset(
- parts[0],
- parts[1],
- parts[2],
- parts[3]
- );
-};
-
-/**
- * Creates rect from different representations
- * - if no params given returns null
- * - if uki.geometry.Inset given returns it
- * - if "200 300" or "0 10 200 300" string converts it to inset
- * - if two or four params given creates inset from them
- *
- * @memberOf uki.geometry.Inset
- * @name create
- * @function
- *
- * @param {...string|number|uki.geometry.Inset} var_args Rect representation
- *
- * @returns {uki.geometry.Inset} created inset
- */
-Inset.create = function(a1, a2, a3, a4) {
- if (a1 === undefined) return null;
- if (a1.top !== undefined) return a1;
- if (/\S+\s+\S+/.test(a1 + '')) return Inset.fromString(a1, a2);
- if (a3 === undefined) return new Inset(a1, a2);
- return new Inset(a1, a2, a3, a4);
-};
-
-
-
-
-/**
- * Basic utils to work with the dom tree
- * @namespace
- * @author voloko
- */
-uki.dom = {
- /**
- * Convenience wrapper around document.createElement
- * Creates dom element with given tagName, cssText and innerHTML
- *
- * @param {string} tagName
- * @param {string=} cssText
- * @param {string=} innerHTML
- * @returns {Element} created element
- */
- createElement: function(tagName, cssText, innerHTML) {
- var e = doc.createElement(tagName);
- if (cssText) e.style.cssText = cssText;
- if (innerHTML) e.innerHTML = innerHTML;
- e[expando] = uki.guid++;
- return e;
- },
-
- /**
- * Adds a probe element to page dom tree, callbacks, removes the element
- *
- * @param {Element} dom Probing dom element
- * @param {function(Element)} callback
- */
- probe: function(dom, callback) {
- var target = doc.body;
- target.appendChild(dom);
- var result = callback(dom);
- target.removeChild(dom);
- return result;
- },
-
- /**
- * Assigns layout style properties to an element
- *
- * @param {CSSStyleDeclaration} style Target declaration
- * @param {object} layout Properties to assign
- * @param {object=} prevLayout If given assigns only difference between layout and prevLayout
- */
- layout: function(style, layout, prevLayout) {
- prevLayout = prevLayout || {};
- if (prevLayout.left != layout.left) style.left = layout.left + PX;
- if (prevLayout.top != layout.top) style.top = layout.top + PX;
- if (prevLayout.right != layout.right) style.right = layout.right + PX;
- if (prevLayout.bottom != layout.bottom) style.bottom = layout.bottom + PX;
- if (prevLayout.width != layout.width) style.width = MAX(layout.width, 0) + PX;
- if (prevLayout.height != layout.height) style.height = MAX(layout.height, 0) + PX;
- return layout;
- },
-
- /**
- * Computed style for a give element
- *
- * @param {Element} el
- * @returns {CSSStyleDeclaration} style declaration
- */
- computedStyle: function(el) {
- if (doc && doc.defaultView && doc.defaultView.getComputedStyle) {
- return doc.defaultView.getComputedStyle( el, null );
- } else if (el.currentStyle) {
- return el.currentStyle;
- }
- },
-
- /**
- * Checks if parent contains child
- *
- * @param {Element} parent
- * @param {Element} child
- * @return {Boolean}
- */
- contains: function(parent, child) {
- try {
- if (parent.contains) return parent.contains(child);
- if (parent.compareDocumentPosition) return !!(parent.compareDocumentPosition(child) & 16);
- } catch (e) {}
- while ( child && child != parent ) {
- try { child = child.parentNode } catch(e) { child = null };
- }
- return parent == child;
- },
-
- createStylesheet: function(code) {
- var style = doc.createElement('style');
- doc.getElementsByTagName('head')[0].appendChild(style);
- if (style.styleSheet) { //IE
- style.styleSheet.cssText = code;
- } else {
- style.appendChild(document.createTextNode(code));
- }
- return style;
- }
-
-};
-
-uki.each(['createElement'], function(i, name) {
- uki[name] = uki.dom[name];
-});
-
-uki.dom.special = {};
-
-uki.dom.Event = function( domEvent ) {
- domEvent = domEvent || {};
- this.domEvent = domEvent.domEvent || domEvent;
-
- for ( var i = uki.dom.props.length, prop; i; ){
- prop = uki.dom.props[ --i ];
- this[ prop ] = domEvent[ prop ];
- }
-
- // this.dataTransfer = new uki.dom.DataTransfer(domEvent);
-};
-
-uki.dom.Event.prototype = new function() {
- function returnTrue () {
- return true;
- }
-
- this.preventDefault = function() {
- var domEvent = this.domEvent;
- domEvent.preventDefault && domEvent.preventDefault();
- domEvent.returnValue = false;
-
- this.isDefaultPrevented = returnTrue;
- }
-
- this.stopPropagation = function() {
- var domEvent = this.domEvent;
- domEvent.stopPropagation && domEvent.stopPropagation();
- domEvent.cancelBubble = true;
-
- this.isPropagationStopped = returnTrue;
- }
-
- this.isDefaultPrevented = this.isPropagationStopped = uki.F;
-}
-
-uki.extend(uki.dom, /** @lends uki.dom */ {
- bound: {},
- handlers: {},
-
- props: "type altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which dragOffset dataTransfer".split(" "),
-
- events: "blur focus load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error draggesturestart draggestureend draggesture dragstart dragend drag drop dragenter dragleave dragover".split(" "),
-
- bind: function(el, types, listener) {
- if ( el.setInterval && el != window )
- el = window;
-
- listener.huid = listener.huid || uki.guid++;
-
- var id = el[expando] = el[expando] || uki.guid++,
- handler = uki.dom.handlers[id] = uki.dom.handlers[id] || function() {
- uki.dom.handler.apply(arguments.callee.elem, arguments);
- },
- i, type;
-
- handler.elem = el;
-
- if (!uki.dom.bound[id]) uki.dom.bound[id] = {};
-
- types = types.split(' ');
- for (i=0; i < types.length; i++) {
- type = types[i];
- if (!uki.dom.bound[id][type]) {
- uki.dom.bound[id][type] = [];
- if ( !uki.dom.special[type] || uki.dom.special[type].setup.call(el) === false ) {
- el.addEventListener ? el.addEventListener(type, handler, false) : el.attachEvent('on' + type, handler);
- }
- }
- uki.dom.bound[id][type].push(listener);
- };
- listener = handler = el = null;
- },
-
- unbind: function(el, types, listener) {
- var id = el[expando],
- huid = listener && listener.huid,
- i, type;
- if (types) {
- types = types.split(' ');
- } else {
- types = [];
- uki.each(uki.dom.bound[id] || [], function(k, v) { types.push(k); });
- }
- for (i=0; i < types.length; i++) {
- type = types[i];
- if (!id || !uki.dom.bound[id] || !uki.dom.bound[id][type]) continue;
- uki.dom.bound[id][type] = listener ? uki.grep(uki.dom.bound[id][type], function(h) { return h.huid !== huid; }) : [];
-
- if (uki.dom.bound[id][type].length == 0) {
- var handler = uki.dom.handlers[id];
- if ( !uki.dom.special[type] || uki.dom.special[type].teardown.call(el) === false ) {
- el.removeEventListener ? el.removeEventListener(type, handler, false) : el.detachEvent('on' + type, handler);
- }
- uki.dom.bound[id][type] = null;
- }
- }
- },
-
- /** @ignore */
- handler: function( e ) {
-
- e = e || root.event;
-
- var type = e.type,
- id = this[expando],
- handlers = uki.dom.bound[id],
- i;
-
- if (!e.domEvent) {
- e = new uki.dom.Event(e);
- e = uki.dom.fix( e );
- }
-
- if (!id || !handlers || !handlers[type]) return;
-
- uki.after.start();
- for (i=0, handlers = handlers[type]; i < handlers.length; i++) {
- handlers[i].call(this, e);
- };
- uki.after.stop();
- },
-
- /**
- * Taken from jQuery
- * @ignore
- */
- fix: function( event ) {
- // Fix target property, if necessary
- if ( !event.target )
- event.target = event.srcElement || doc;
-
- // check if target is a textnode (safari)
- if ( event.target.nodeType == 3 )
- event.target = event.target.parentNode;
-
- // Add relatedTarget, if necessary
- if ( !event.relatedTarget && event.fromElement )
- event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && event.clientX != null ) {
- var de = doc.documentElement, body = doc.body;
- event.pageX = event.clientX + (de && de.scrollLeft || body && body.scrollLeft || 0) - (de.clientLeft || 0);
- event.pageY = event.clientY + (de && de.scrollTop || body && body.scrollTop || 0) - (de.clientTop || 0);
- }
-
- // Add which for key events
- if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
- event.which = event.charCode || event.keyCode;
-
- // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
- if ( !event.metaKey && event.ctrlKey )
- try { event.metaKey = event.ctrlKey; } catch(e){};
-
- // Add which for click: 1 == left; 2 == middle; 3 == right
- // Note: button is not normalized, so don't use it
- if ( !event.which && event.button )
- event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
-
- return event;
- },
-
- preventDefaultHandler: function(e) {
- e && e.preventDefault();
- return false;
- }
-});
-
-uki.each({
- mouseover: 'mouseenter',
- mouseout: 'mouseleave'
-}, function( orig, fix ){
- var handler = function(e) {
- if (!uki.dom.contains(this, e.relatedTarget)) {
- e.type = fix;
- uki.dom.handler.apply(this, arguments);
- }
- };
-
- uki.dom.special[ fix ] = {
- setup: function() {
- uki.dom.bind( this, orig, handler );
- },
- teardown: function(){
- uki.dom.unbind( this, orig, handler );
- }
- };
-});
-
-
-if (root.attachEvent) {
- root.attachEvent('onunload', function() {
- uki.each(uki.dom.bound, function(id, types) {
- uki.each(types, function(type, handlers) {
- try {
- uki.dom.handlers[id].elem.detachEvent('on' + type, uki.dom.handlers[id]);
- } catch (e) {};
- });
- });
- });
-};
-
-
-
-(function() {
-/**
- * Drag and Drop support for uki
- * @namespace
- */
-var dnd = uki.dom.dnd = {
- draggable: null,
- nativeDnD: false,
- position: null
-};
-
-// detect if native DnD is supported
-try {
- if (
- // typeof doc.createElement('div').ondragstart == 'object' || // ie support
- typeof doc.createEvent('MouseEvent').dataTransfer == 'object' || // safari
- doc.createEvent('DragEvent').initDragEvent // w3c support
- ) {
- // Google Chrome has to many issues with native d&d. It is simpler to disable than to fix
- dnd.nativeDnD = !ua.match(/Chrome\/4/);
- }
-} catch (e) {}
-
-// bind single drag set of drag events for an element
-// regardless of the number of listeners
-var bindDraggestures = {
- setup: function() {
- if (this.__draggesturebound) {
- this.__draggesturebound++;
- } else {
- this.__draggesturebound = 1;
- uki.dom.bind( this, 'mousedown', draggesturestart );
- // prevent interference with ie drag events
- if (!dnd.nativeDnD && typeof this.ondragstart == 'object')
- this.ondragstart = function() { event.returnValue = false; };
- }
- },
- teardown: function() {
- this.__draggesturebound--;
- if (!this.__draggesturebound) uki.dom.unbind( this, 'mousedown', draggesturestart );
- }
-};
-
-// drag gestures
-uki.extend(uki.dom.special, {
- draggesturestart: bindDraggestures,
- draggestureend: bindDraggestures,
- draggesture: bindDraggestures
-});
-
-var dragEndEvents = 'mouseup ' + (dnd.nativeDnD ? ' dragend' : '');
-// if (window.attachEvent && !window.opera) dragEndEvents += ' mouseleave';
-
-function startGesture (el) {
- if (dnd.draggable) return;
- dnd.draggable = el;
- uki.dom.bind(doc, 'mousemove scroll', draggesture);
- uki.dom.bind(doc, dragEndEvents, draggestureend);
- uki.dom.bind(doc, 'selectstart mousedown', uki.dom.preventDefaultHandler);
-}
-
-function stopGesture () {
- dnd.draggable = null;
- uki.dom.unbind(doc, 'mousemove scroll', draggesture);
- uki.dom.unbind(doc, dragEndEvents, draggestureend);
- uki.dom.unbind(doc, 'selectstart mousedown', uki.dom.preventDefaultHandler);
-}
-
-function draggesturestart (e) {
- e = new uki.dom.Event(e);
- e.type = 'draggesturestart';
- uki.dom.handler.apply(this, arguments);
- if (!e.isDefaultPrevented()) {
- startGesture(this);
- dnd.position = new Point(-e.pageX, -e.pageY);
- }
-}
-
-function draggesture (e) {
- e = new uki.dom.Event(e);
- e.type = 'draggesture';
- e.dragOffset = (new Point(e.pageX, e.pageY)).offset(dnd.position);
- uki.dom.handler.apply(dnd.draggable, arguments);
- if (e.isDefaultPrevented()) stopGesture(dnd.draggable);
-}
-
-function draggestureend (e) {
- e = new uki.dom.Event(e);
- e.type = 'draggestureend';
- e.dragOffset = (new Point(e.pageX, e.pageY)).offset(dnd.position);
- uki.dom.handler.apply(dnd.draggable, arguments);
- stopGesture(dnd.draggable);
-}
-
-})();
-
-
-
-(function() {
-
- var dnd = uki.dom.dnd,
- retriggering = false;
-
- // common properties
- uki.extend(dnd, {
- dragDelta: 5,
- initNativeDnD: function() {
- // moz needs the drag image to be appended to document
- // so create an offscreen container to hold drag images.
- // note that it can't have overflow:hidden, since drag image will be cutted to container
- var container = uki.createElement('div', 'position: absolute;left:-999em;');
- doc.body.appendChild(container);
- dnd.dragImageContainer = container;
- dnd.initNativeDnD = uki.F;
- return true;
- },
- dragImageContainer: null,
- dataTransfer: null,
- target: null,
- dragOver: null
- });
-
-
- function viewToDom (element) {
- if (uki.isFunction(element.dom)) {
- if (element.parent().length) return element.dom();
- var container = uki.createElement('div', 'width:1px;height:1px;position:absolute;left:-999em;top:0');
- doc.body.appendChild(container);
- element.attachTo(container);
- return container;
- }
- return element;
- }
-
- var dataTransferProps = ['dropEffect', 'effectAllowed', 'types', 'files'];
-
- uki.dom.DataTransferWrapper = uki.newClass(new function() {
- this.init = function(dataTransfer) {
- this.dataTransfer = dataTransfer;
- for (var i = dataTransferProps.length - 1; i >= 0; i--){
- this[ dataTransferProps[i] ] = dataTransfer[ dataTransferProps[i] ];
- };
- };
-
- this.setData = function(format, data) {
- return this.dataTransfer.setData(format, data);
- };
-
- this.clearData = function(format) {
- return this.dataTransfer.clearData(format);
- };
-
- this.getData = function(format) {
- return this.dataTransfer.getData(format);
- };
-
- this.setDragImage = function(image, x, y) {
- dnd.initNativeDnD();
- image = viewToDom(image);
- var clone = image.cloneNode(true),
- style = clone.style;
- style.left = style.right = style.top = style.bottom = '';
- style.position = 'static';
- dnd.dragImageContainer.appendChild(clone);
- setTimeout(function() {
- dnd.dragImageContainer.removeChild(clone);
- }, 1);
- return this.dataTransfer.setDragImage(clone, x, y);
- };
- })
-
- // w3c spec based dataTransfer implementation
- uki.dom.DataTransfer = uki.newClass(new function() {
- this.init = function() {
- uki.extend(this, {
- dropEffect: 'none',
- effectAllowed: 'none',
- types: [],
- files: [],
- dragImage: new Image(),
- imagePosition: new Point(),
- data: {}
- });
- };
-
- this.setData = function(format, data) {
- this.data[format] = data;
- if (uki.inArray(format, this.types) == -1) this.types.push(format);
- };
-
- this.clearData = function(format) {
- if (format) {
- delete this.data[format];
- this.types = uki.grep(this.types, function(x) { return x != format; });
- } else {
- this.data = {};
- this.types = [];
- }
- };
-
- this.getData = function(format) {
- return this.data[format];
- };
-
- this.setDragImage = function(image, x, y) {
- this._dragImage = this._initDragImage(image);
- this._imagePosition = new Point(x || 0, y || 0);
- };
-
- this.update = function(e) {
- if (!this._dragImage) return;
- this._dragImage.style.left = e.pageX - this._imagePosition.x + 'px';
- this._dragImage.style.top = e.pageY - this._imagePosition.y + 'px';
- };
-
- this.cleanup = function() {
- this._dragImage && this._dragImage.parentNode.removeChild(this._dragImage);
- this._dragImage = undefined;
- };
-
- this._initDragImage = function(image) {
- image = viewToDom(image);
- var clone = image.cloneNode(true),
- style = clone.style;
-
- style.left = style.right = style.top = style.bottom = '';
- style.position = 'absolute';
- style.left = '-999em';
- style.zIndex = '9999';
- doc.body.appendChild(clone);
- return clone;
- };
- });
-
-
- var bindW3CDrag = {
- setup: function() {
- if (this.__w3cdragbound) {
- this.__w3cdragbound++;
- } else {
- this.__w3cdragbound = 1;
- uki.dom.bind( this, 'draggesture', drag );
- }
- },
- teardown: function() {
- this.__w3cdragbound--;
- if (!this.__draggesturebound) uki.dom.unbind( this, 'draggesture', drag );
- }
- };
-
- if (dnd.nativeDnD) {
- uki.extend(uki.dom.special, {
- dragstart: {
- setup: function() {
- this.addEventListener('dragstart', nativeDragWrapper, false);
- },
- teardown: function() {
- this.removeEventListener('dragstart', nativeDragWrapper, false);
- }
- }
- })
-
- } else {
- uki.extend(uki.dom.special, {
- dragstart: bindW3CDrag,
- drag: bindW3CDrag,
- dragend: bindW3CDrag
- });
-
- uki.each({
- dragover: 'mousemove',
- drop: 'mouseup'
- }, function( source, target ){
-
- var handler = function(e) {
- if (dnd.dataTransfer && retriggering) {
- e = new uki.dom.Event(e);
- e.type = source;
- e.dataTransfer = dnd.dataTransfer;
- if (source == 'dragover') {
- dnd.__canDrop = false;
- } else {
- stopW3Cdrag(this);
- if (!dnd.__canDrop) return;
- }
- uki.dom.handler.apply(this, arguments);
- if (e.isDefaultPrevented()) {
- dnd.__canDrop = true;
- }
- }
- };
-
- uki.dom.special[ source ] = {
- setup: function() {
- uki.dom.bind( this, target, handler );
- },
- teardown: function(){
- uki.dom.unbind( this, target, handler );
- }
- };
- });
-
- uki.dom.special.dragenter = {
- setup: function() {
- uki.dom.bind( this, 'mousemove', dragenter );
- },
- teardown: function(){
- uki.dom.unbind( this, 'mousemove', dragenter );
- }
- };
- uki.dom.special.dragleave = { setup: function() {}, teardown: function() {} }
- }
-
- function nativeDragWrapper (e) {
- e = new uki.dom.Event(e);
- var dataTransfer = e.dataTransfer;
- e.dataTransfer = new uki.dom.DataTransferWrapper(dataTransfer);
- uki.dom.handler.apply(this, arguments);
- dataTransfer.effectAllowed = e.dataTransfer.effectAllowed;
- dataTransfer.dropEffect = e.dataTransfer.dropEffect;
- }
-
- function startW3Cdrag (element) {
- uki.dom.bind( element, 'draggestureend', dragend );
- }
-
- function stopW3Cdrag (element) {
- if (!dnd.dataTransfer) return;
- dnd.dataTransfer.cleanup();
- dnd.dragOver = dnd.dataTransfer = dnd.target = null;
- uki.dom.unbind( element, 'draggestureend', dragend );
- }
-
- function dragenter (e) {
- if (!dnd.dataTransfer || e.domEvent.__dragEntered || !retriggering) return;
- e = new uki.dom.Event(e);
- e.domEvent.__dragEntered = true;
- if (dnd.dragOver == this) return;
- dnd.dragOver = this;
- e.type = 'dragenter';
- uki.dom.handler.apply(this, arguments);
- }
-
- function drag (e) {
- if (retriggering) {
- if (!e.domEvent.__dragEntered && dnd.dragOver) {
- e = new uki.dom.Event(e);
- e.type = 'dragleave';
- uki.dom.handler.apply(dnd.dragOver, arguments);
- dnd.dragOver = null;
- }
- return;
- };
-
- if (dnd.dataTransfer) { // dragging
- e.type = 'drag';
- e.target = dnd.target;
- } else if (e.dragOffset.x > dnd.dragDelta || e.dragOffset.y > dnd.dragDelta) { // start drag
- var target = e.target,
- parent = this.parentNode;
- try {
- while (target && target != parent && !target.getAttribute('draggable')) target = target.parentNode;
- } catch (ex) { target = null; }
- if (target && target.getAttribute('draggable')) {
- dnd.target = e.target = target;
- e.type = 'dragstart';
- dnd.dataTransfer = e.dataTransfer = new uki.dom.DataTransfer(e.domEvent.dataTransfer);
- startW3Cdrag(this);
- } else {
- return;
- }
- } else {
- return;
- }
- e = new uki.dom.Event(e);
- uki.dom.handler.apply(this, arguments);
- if (e.isDefaultPrevented()) {
- stopW3Cdrag(this);
- } else {
- retriggerMouseEvent(e);
- }
-
- }
-
- var props = 'detail screenX screenY clientX clientY ctrlKey altKey shiftKey metaKey button'.split(' ');
-
- function retriggerMouseEvent (e) {
- var imageStyle = dnd.dataTransfer._dragImage.style,
- type = e.domEvent.type, target;
- e.stopPropagation();
- e.preventDefault();
- imageStyle.left = '-999em';
- target = doc.elementFromPoint(e.pageX, e.pageY);
- dnd.dataTransfer.update(e);
-
- try {
- var newEvent;
- retriggering = true;
- try {
- if (doc.createEventObject) {
- newEvent = doc.createEventObject();
- for ( var i = props.length, prop; i; ){
- prop = uki.dom.props[ --i ];
- newEvent[ prop ] = e.domEvent[ prop ];
- }
- target.fireEvent('on' + type, newEvent)
- } else {
- newEvent = doc.createEvent('MouseEvents');
- newEvent.initMouseEvent(
- type,
- true,
- true,
- doc.defaultView,
- e.detail,
- e.screenX,
- e.screenY,
- e.clientX,
- e.clientY,
- e.ctrlKey,
- e.altKey,
- e.shiftKey,
- e.metaKey,
- e.button,
- null
- );
- target.dispatchEvent(newEvent)
- }
- } catch (e) {}
- retriggering = false;
- } catch (e) {}
- }
-
- function dragend (e) {
- if (retriggering) return;
- if (dnd.dataTransfer) { // drag started
- e.type = 'dragend';
- e.target = dnd.target;
- e.dataTransfer = dnd.dataTransfer;
- uki.dom.handler.apply(this, arguments);
- retriggerMouseEvent(e);
- stopW3Cdrag(this);
- }
- }
-})();
-
-
-(function() {
- var self;
-
- if ( doc.documentElement["getBoundingClientRect"] ) {
- self = uki.dom.offset = function( elem ) {
- if ( !elem || elem == root ) return new Point();
- if ( elem === elem.ownerDocument.body ) return self.bodyOffset( elem );
- self.boxModel === undefined && self.initializeBoxModel();
- var box = elem.getBoundingClientRect(),
- doc = elem.ownerDocument,
- body = doc.body,
- docElem = doc.documentElement,
- clientTop = docElem.clientTop || body.clientTop || 0,
- clientLeft = docElem.clientLeft || body.clientLeft || 0,
- top = box.top + (self.pageYOffset || self.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
- left = box.left + (self.pageXOffset || self.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
-
- return new Point(left, top);
- };
- } else {
- self = uki.dom.offset = function( elem ) {
- if ( !elem || elem == root ) return new Point();
- if ( elem === elem.ownerDocument.body ) return self.bodyOffset( elem );
- self.initialized || self.initialize();
-
- var offsetParent = elem.offsetParent,
- prevOffsetParent = elem,
- doc = elem.ownerDocument,
- computedStyle,
- docElem = doc.documentElement,
- body = doc.body,
- defaultView = doc.defaultView,
- prevComputedStyle = defaultView.getComputedStyle(elem, null),
- top = elem.offsetTop,
- left = elem.offsetLeft;
-
- while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
- computedStyle = defaultView.getComputedStyle(elem, null);
- top -= elem.scrollTop;
- left -= elem.scrollLeft;
-
- if ( elem === offsetParent ) {
- top += elem.offsetTop;
- left += elem.offsetLeft;
-
- if ( self.doesNotAddBorder && !(self.doesAddBorderForTableAndCells && (/^t(able|d|h)$/i).test(elem.tagName)) ) {
- top += parseInt( computedStyle.borderTopWidth, 10) || 0;
- left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
- }
- prevOffsetParent = offsetParent;
- offsetParent = elem.offsetParent;
- }
- if ( self.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
- top += parseInt( computedStyle.borderTopWidth, 10) || 0;
- left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
- }
- prevComputedStyle = computedStyle;
- }
-
- if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
- top += body.offsetTop;
- left += body.offsetLeft;
- }
-
- if ( prevComputedStyle.position === "fixed" ) {
- top += MAX(docElem.scrollTop, body.scrollTop);
- left += MAX(docElem.scrollLeft, body.scrollLeft);
- }
-
- return new Point(left, top);
- };
- }
-
- uki.extend(self, {
- initialize: function() {
- if ( this.initialized ) return;
- var body = doc.body,
- container = doc.createElement('div'),
- innerDiv, checkDiv, table, td, rules, prop,
- bodyMarginTop = body.style.marginTop,
- html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
-
- rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
- for ( prop in rules ) container.style[prop] = rules[prop];
-
- container.innerHTML = html;
- body.insertBefore(container, body.firstChild);
- innerDiv = container.firstChild;
- checkDiv = innerDiv.firstChild;
- td = innerDiv.nextSibling.firstChild.firstChild;
-
- this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
- this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
-
- innerDiv.style.overflow = 'hidden';
- innerDiv.style.position = 'relative';
- this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
-
- body.style.marginTop = '1px';
- this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
- body.style.marginTop = bodyMarginTop;
-
- body.removeChild(container);
- this.boxModel === undefined && this.initializeBoxModel();
- this.initialized = true;
- },
-
- initializeBoxModel: function() {
- if (this.boxModel !== undefined) return;
- var div = doc.createElement("div");
- div.style.width = div.style.paddingLeft = "1px";
-
- doc.body.appendChild( div );
- this.boxModel = div.offsetWidth === 2;
- doc.body.removeChild( div ).style.display = 'none';
- },
-
- bodyOffset: function(body) {
- self.initialized || self.initialize();
- var top = body.offsetTop, left = body.offsetLeft;
- if ( uki.dom.doesNotIncludeMarginInBodyOffset ) {
- top += parseInt( uki.dom.elem.currentStyle(body).marginTop, 10 ) || 0;
- left += parseInt( uki.dom.elem.currentStyle(body).marginLeft, 10 ) || 0;
- }
- return new Point(left, top);
- }
- });
-})();
-
-
-
-uki.browser = new function() {
-
- var boxShadow;
- this.cssBoxShadow = function() {
- // Opera 10.5 consistently fails to redraw shadows. Easier to switch off
- boxShadow = boxShadow || (root.opera ? 'unsupported' : checkPrefixes('box-shadow'));
- return boxShadow;
- };
-
- var borderRadius;
- this.cssBorderRadius = function() {
- borderRadius = borderRadius || checkPrefixes('border-radius');
- return borderRadius;
- };
-
- var userSelect;
- this.cssUserSelect = function() {
- userSelect = userSelect || checkPrefixes('user-select');
- return userSelect;
- };
-
- var linearGradient;
- this.cssLinearGradient = function() {
- linearGradient = linearGradient || initLinearGradient();
- return linearGradient;
- };
-
- var canvas;
- this.canvas = function() {
- if (canvas === undefined) canvas = !!uki.createElement('canvas').getContext;
- return canvas;
- };
-
- var filter;
- this.cssFilter = function() {
- if (filter === undefined) filter = typeof uki.createElement('div').style.filter != 'undefined';
- return filter;
- };
-
- function swap (obj, src, dst) {
- var v = obj[src];
- obj[src] = undefined;
- obj[dst] = v;
- }
- this.css = function(css) {
- if (!css) return '';
- if (typeof css == 'string') {
- return css.replace(/(^|[^-])(box-shadow|border-radius|user-select)/g, function(value) {
- var p;
- if ((p = value.indexOf('box-shadow')) > -1) return value.substr(0, p) + uki.browser.cssBoxShadow();
- if ((p = value.indexOf('border-radius')) > -1) return value.substr(0, p) + uki.browser.cssBorderRadius();
- if ((p = value.indexOf('user-select')) > -1) return value.substr(0, p) + uki.browser.cssUserSelect();
- });
- }
-
- uki.each(['boxShadow', 'borderRadius', 'userSelect'], function(k, v) {
- if (css[v]) swap(css, v, uki.camalize( uki.browser[ uki.camalize('css-' + v) ]() ) );
- });
- return css;
- };
-
- this.textStyles = 'font fontFamily fontWeight fontSize textDecoration textOverflow textAlign textShadow overflow color'.split(' ');
-
- function checkPrefixes (dashProp) {
- var e = uki.createElement('div'),
- style = e.style,
- prefixes = ['', '-webkit-', '-moz-'];
-
- for (var i=0; i < prefixes.length; i++) {
- if (style[ uki.camalize(prefixes[i] + dashProp) ] !== undefined) return prefixes[i] + dashProp;
- };
- return 'unsupported';
- }
-
- function initLinearGradient () {
- var e = uki.createElement(
- 'div',
- 'background-image:-moz-linear-gradient(right,red,red);'+
- 'background-image:linear-gradient(right,red,red);'+
- 'background-image:-webkit-gradient(linear,0 0,100% 0,from(red),to(red))'
- ),
- style = e.style,
- bgi = style.backgroundImage + '';
-
- if (bgi.indexOf('-moz-linear-gradient') > -1) {
- return '-moz-linear-gradient';
- } else if (bgi.indexOf('-webkit-gradient') > -1) {
- return '-webkit-gradient';
- } else if (bgi.indexOf('linear-gradient') > -1) {
- return 'linear-gradient';
- } else {
- return 'unsupported';
- }
- }
-};
-
-uki.initNativeLayout = function() {
- if (uki.supportNativeLayout === undefined) {
- uki.dom.probe(
- uki.createElement(
- 'div',
- 'position:absolute;width:100px;height:100px;left:-999em;',
- '<div style="position:absolute;left:0;right:0"></div>'
- ),
- function(div) {
- uki.supportNativeLayout = div.childNodes[0].offsetWidth == 100 && !root.opera;
- }
- );
- }
-};
-
-// uki.supportNativeLayout = false;
-
-
-
-
-
-/**
- * Executes callback at or after the end of processing.
- * Example: execute flow layout after all child views were added.
- * Runs either at the end of event handling or after a timeout.
- * Each callback (by huid) is executed once
- * @function
- * @param {function()} callback
- */
-uki.after = (function() {
- var after = function(callback) {
- callback.huid = callback.huid || uki.guid++;
- if (after._bound[callback.huid]) return;
- after._bound[callback.huid] = true;
- after._queue.push(callback);
- if (!after._running) after._startTimer();
- };
-
- after._bound = {};
- after._running = false;
- after._timer = 0;
- after._queue = [];
-
- after.start = function() {
- after._clearTimer();
- after._running++;
- };
-
- after.stop = function() {
- if (--after._running) return;
- after._runCallbacks();
- };
-
-
-
- after._runCallbacks = function() {
- after._clearTimer();
- var queue = after._queue;
- after._queue = [];
- after._bound = {};
- for (var i=0; i < queue.length; i++) queue[i]();
- };
-
- after._startTimer = function() {
- if (after._timer) return;
- after._timer = setTimeout(after._runCallbacks, 1);
- };
-
- after._clearTimer = function() {
- if (!after._timer) return;
- clearTimeout(after._timer);
- after._timer = 0;
- };
-
- return after;
-})();
-
-
-
-
-/** @namespace */
-uki.view = {
- declare: function(/*name, baseClasses, implementation*/) {
- var args = uki.toArray(arguments),
- name = args.shift(),
- klass = uki.newClass.apply(uki, args),
- parts = name.split('.'),
- obj = root,
- i, part, l = parts.length - 1;
-
- klass.prototype.typeName = function() { return name; };
-
- for ( i= 0; i < l; i++ ) {
- part = parts[i];
- if (!obj[part]) obj[part] = {};
- obj = obj[part];
-
- };
-
- obj[ parts[l] ] = klass;
- return klass;
- }
-};
-
-/**
- * @class
- */
-uki.view.Observable = /** @lends uki.view.Observable.prototype */ {
- // dom: function() {
- // return null; // should implement
- // },
-
- /**
- * @param {String} name Event name
- * @param {function()} callback
- */
- bind: function(name, callback) {
- callback.huid = callback.huid || uki.guid++;
- uki.each(name.split(' '), function(i, name) {
- if (!this._bound(name)) this._bindToDom(name);
- this._observersFor(name).push(callback);
- }, this);
- return this;
- },
-
- unbind: function(name, callback) {
- if (!this._observers) return;
- var names;
- if (name) {
- names = name.split(' ');
- } else {
- names = [];
- uki.each(this._observers, function(k, v) { names.push(k) });
- }
- uki.each(names, function(i, name) {
- this._observers[name] = !callback ? [] : uki.grep(this._observersFor(name, true), function(observer) {
- return observer != callback && observer.huid != callback.huid;
- });
- if (this._observers[name].length == 0) {
- this._observers[name] = undefined;
- this._unbindFromDom(name);
- }
- }, this);
- return this;
- },
-
- trigger: function(name/*, data1, data2*/) {
- var attrs = Array.prototype.slice.call(arguments, 1);
- uki.each(this._observersFor(name, true), function(i, callback) {
- callback.apply(this, attrs);
- }, this);
- return this;
- },
-
- _unbindFromDom: function(name) {
- if (!this._domHander || !this._eventTargets[name]) return;
- uki.dom.unbind(this._eventTargets[name], name, this._domHander);
- },
-
- _bindToDom: function(name, target) {
- if (!target && !this.dom) return false;
- this._domHander = this._domHander || uki.proxy(function(e) {
- e.source = this;
- this.trigger(e.type, e);
- }, this);
- this._eventTargets = this._eventTargets || {};
- this._eventTargets[name] = target || this.dom();
- uki.dom.bind(this._eventTargets[name], name, this._domHander);
- return true;
- },
-
- _bound: function(name) {
- return this._observers && this._observers[name];
- },
-
- _observersFor: function(name, skipCreate) {
- if (skipCreate && (!this._observers || !this._observers[name])) return [];
- if (!this._observers) this._observers = {};
- if (!this._observers[name]) this._observers[name] = [];
- return this._observers[name];
- }
-};
-
-(function() {
- var self = uki.Attachment = uki.newClass(uki.view.Observable, /** @lends uki.Attachment.prototype */ {
- /**
- * Attachment serves as a connection between a uki view and a dom container.
- * It notifies its view with parentResized on window resize.
- * Attachment supports part of uki.view.Base API like #domForChild or #rectForChild
- *
- * @param {Element} dom Container element
- * @param {uki.view.Base} view Attached view
- * @param {uki.geometry.Rect} rect Initial size
- *
- * @see uki.view.Base#parentResized
- * @name uki.Attachment
- * @augments uki.view.Observable
- * @constructor
- */
- init: function( dom, view, rect ) {
- uki.initNativeLayout();
-
- this._dom = dom = dom || root;
- this._view = view;
- this._rect = Rect.create(rect) || this.rect();
-
- uki.dom.offset.initialize();
-
- view.parent(this);
- this.domForChild().appendChild(view.dom());
-
- if (dom != root && dom.tagName != 'BODY') {
- var computedStyle = dom.runtimeStyle || dom.ownerDocument.defaultView.getComputedStyle(dom, null);
- if (!computedStyle.position || computedStyle.position == 'static') dom.style.position = 'relative';
- }
- self.register(this);
-
- this.layout();
- },
-
- /**
- * Returns document.body if attached to window. Otherwise returns dom
- * uki.view.Base api
- *
- * @type Element
- */
- domForChild: function() {
- return this._dom === root ? doc.body : this._dom;
- },
-
- /**
- * uki.view.Base api
- *
- * @type uki.geometry.Rect
- */
- rectForChild: function(child) {
- return this.rect();
- },
-
- /**
- * uki.view.Base api
- */
- scroll: function() {
- // TODO: support window scrolling
- },
-
- /**
- * uki.view.Base api
- */
- scrollTop: function() {
- // TODO: support window scrolling
- return this._dom.scrollTop || 0;
- },
-
- /**
- * uki.view.Base api
- */
- scrollLeft: function() {
- // TODO: support window scrolling
- return this._dom.scrollLeft || 0;
- },
-
- /**
- * uki.view.Base api
- */
- parent: uki.F,
-
- /**
- * uki.view.Base api
- */
- childResized: uki.F,
-
- /**
- * On window resize resizes and layout its child view
- * @fires event:layout
- */
- layout: function() {
- var oldRect = this._rect;
-
- // if (rect.eq(this._rect)) return;
- var newRect = this._rect = this.rect();
- this._view.parentResized(oldRect, newRect);
- if (this._view._needsLayout) this._view.layout();
- this.trigger('layout', {source: this, rect: newRect});
- },
-
- /**
- * @return {Element} Container dom
- */
- dom: function() {
- return this._dom;
- },
-
- /**
- * @return {Element} Child view
- */
- view: function() {
- return this._view;
- },
-
- /**
- * @private
- * @return {uki.geometry.Rect} Size of the container
- */
- rect: function() {
- var width = this._dom === root || this._dom === doc.body ?
- MAX(getRootElement().clientWidth, this._dom.offsetWidth || 0) :
- this._dom.offsetWidth,
- height = this._dom === root || this._dom === doc.body ?
- MAX(getRootElement().clientHeight, this._dom.offsetHeight || 0) :
- this._dom.offsetHeight;
-
- return new Rect(width, height);
- }
- });
-
- function getRootElement() {
- return doc.compatMode == "CSS1Compat" && doc.documentElement || doc.body;
- }
-
- self.instances = [];
-
- /**
- * @memberOf uki.Attachment
- */
- self.register = function(a) {
- if (self.instances.length == 0) {
- var timeout = false;
- uki.dom.bind(root, 'resize', function() {
- if (!timeout) {
- timeout = true;
- setTimeout(function(i,len) {
- uki.after.start();
-
- timeout = false;
- for (i=0,len=self.instances.length;i<len;i++)
- self.instances[i].layout();
-
- uki.after.stop();
- }, 1);
- }
- });
- }
- self.instances.push(a);
- };
-
- /**
- * @memberOf uki.Attachment
- */
- self.childViews = function() {
- return uki.map(self.instances, 'view');
- };
-
- /**
- * @memberOf uki.Attachment
- */
- uki.top = function() {
- return [self];
- };
-})();
-
-
-
-
-
-
-
-/**
- * Collection performs group operations on uki.view objects.
- * <p>Behaves much like result jQuery(dom nodes).
- * Most methods are chainable like .attr('text', 'somevalue').bind('click', function() { ... })</p>
- *
- * <p>Its easier to call uki([view1, view2]) or uki('selector') instead of creating collection directly</p>
- *
- * @author voloko
- * @constructor
- * @class
- */
-uki.Collection = function( elems ) {
- this.length = 0;
- Array.prototype.push.apply( this, elems );
-};
-
-uki.fn = uki.Collection.prototype = new function() {
- var proto = this;
-
- /**#@+ @memberOf uki.Collection# */
- /**
- * Iterates trough all items within itself
- *
- * @function
- *
- * @param {function(this:uki.view.Base, number, uki.view.Base)} callback Callback to call for every item
- * @returns {uki.view.Collection} self
- */
- this.each = function( callback ) {
- return uki.each( this, callback );
- };
-
- /**
- * Creates a new uki.Collection populated with found items
- *
- * @function
- *
- * @param {function(uki.view.Base, number):boolean} callback Callback to call for every item
- * @returns {uki.view.Collection} created collection
- */
- this.grep = function( callback ) {
- return new uki.Collection( uki.grep(this, callback) );
- };
-
- /**
- * Sets an attribute on all views or gets the value of the attribute on the first view
- *
- * @example
- * c.attr('text', 'my text') // sets text to 'my text' on all collection views
- * c.attr('name') // gets name attribute on the first view
- *
- * @function
- *
- * @param {string} name Name of the attribute
- * @param {object=} value Value to set
- * @returns {uki.view.Collection|Object} Self or attribute value
- */
- this.attr = function( name, value ) {
- if (value !== undefined) {
- for (var i=this.length-1; i >= 0; i--) {
- uki.attr( this[i], name, value );
- };
- return this;
- } else {
- return this[0] ? uki.attr( this[0], name ) : "";
- }
- };
-
- /**
- * Finds views within collection context
- * @example
- * c.find('Button')
- *
- * @function
- *
- * @param {string} selector
- * @returns {uki.view.Collection} Collection of found items
- */
- this.find = function( selector ) {
- return uki.find( selector, this );
- };
-
- /**
- * Attaches all child views to dom container
- *
- * @function
- *
- * @param {Element} dom Container dom element
- * @param {uki.geometry.Rect} rect Default size
- * @returns {uki.view.Collection} self
- */
- this.attachTo = function( dom, rect ) {
- this.each(function() {
- new uki.Attachment( dom, this, rect );
- });
- return this;
- };
-
- /**
- * Appends views to the first item in collection
- *
- * @function
- *
- * @param {Array.<uki.view.Base>} views Views to append
- * @returns {uki.view.Collection} self
- */
- this.append = function( views ) {
- var target = this[0];
- if (!target) return this;
-
- views = views.length !== undefined ? views : [views];
-
- for (var i = views.length-1; i >= 0; i--) {
- target.appendChild(views[i]);
- };
-
- return this;
- };
-
- this.appendTo = function( target ) {
- target = uki(target)[0];
- this.each(function() {
- target.appendChild(this);
- });
- return this;
-
- };
-
- /**#@-*/
-
- /**
- * @function
- */
- uki.Collection.addAttrs = function(attrNames) {
- uki.each(attrNames, function(i, name) {
- proto[name] = function( value ) { return this.attr( name, value ); };
- });
- };
-
- /** @function
- @name uki.Collection#html */
- /** @function
- @name uki.Collection#text */
- /** @function
- @name uki.Collection#background */
- /** @function
- @name uki.Collection#value */
- /** @function
- @name uki.Collection#rect */
- /** @function
- @name uki.Collection#checked */
- /** @function
- @name uki.Collection#anchors */
- /** @function
- @name uki.Collection#childViews */
- /** @function
- @name uki.Collection#typeName */
- /** @function
- @name uki.Collection#id */
- /** @function
- @name uki.Collection#name */
- /** @function
- @name uki.Collection#visible */
- /** @function
- @name uki.Collection#disabled */
- /** @function
- @name uki.Collection#focusable */
- /** @function
- @name uki.Collection#style */
- uki.Collection.addAttrs('dom html text background value rect checked anchors childViews typeName id name visible disabled focusable style draggable textSelectable width height minX maxX minY maxY left top x y contentsSize'.split(' '));
-
-
- /** @function
- @name uki.Collection#parent */
- /** @function
- @name uki.Collection#next */
- /** @function
- @name uki.Collection#prev */
- uki.each([
- ['parent', 'parent'],
- ['next', 'nextView'],
- ['prev', 'prevView']
- ], function(i, desc) {
- proto[ desc[0] ] = function() {
- return new uki.Collection( uki.unique( uki.map(this, desc[1]) ) );
- };
- });
-
-
- /** @function
- @name uki.Collection#bind */
- /** @function
- @name uki.Collection#unload */
- /** @function
- @name uki.Collection#trigger */
- /** @function
- @name uki.Collection#layout */
- /** @function
- @name uki.Collection#appendChild */
- /** @function
- @name uki.Collection#removeChild */
- /** @function
- @name uki.Collection#insertBefore */
- /** @function
- @name uki.Collection#addRow */
- /** @function
- @name uki.Collection#removeRow */
- /** @function
- @name uki.Collection#resizeToContents */
- /** @function
- @name uki.Collection#toggle */
- uki.each('bind unbind trigger layout appendChild removeChild insertBefore addRow removeRow resizeToContents toggle'.split(' '), function(i, name) {
- proto[name] = function() {
- for (var i=this.length-1; i >=0; i--) {
- this[i][name].apply(this[i], arguments);
- };
- return this;
- };
- });
-
- /** @function
- @name uki.Collection#blur */
- /** @function
- @name uki.Collection#focus */
- /** @function
- @name uki.Collection#load */
- /** @function
- @name uki.Collection#resize */
- /** @function
- @name uki.Collection#scroll */
- /** @function
- @name uki.Collection#unload */
- /** @function
- @name uki.Collection#click */
- /** @function
- @name uki.Collection#dblclick */
- /** @function
- @name uki.Collection#mousedown */
- /** @function
- @name uki.Collection#mouseup */
- /** @function
- @name uki.Collection#mousemove */
- /** @function
- @name uki.Collection#mouseover */
- /** @function
- @name uki.Collection#mouseout */
- /** @function
- @name uki.Collection#mouseenter */
- /** @function
- @name uki.Collection#mouseleave */
- /** @function
- @name uki.Collection#change */
- /** @function
- @name uki.Collection#select */
- /** @function
- @name uki.Collection#submit */
- /** @function
- @name uki.Collection#keydown */
- /** @function
- @name uki.Collection#keypress */
- /** @function
- @name uki.Collection#keyup */
- /** @function
- @name uki.Collection#error */
- uki.each( uki.dom.events, function(i, name){
- proto[name] = function( handler ){
- if (handler) {
- this.bind(name, handler);
- } else {
- for (var i=this.length-1; i >=0; i--) {
- this[i][name] ? this[i][name]() : this[i].trigger(name);
- };
- }
- return this;
- };
- });
-};
-
-
-
-
-(function() {
-
- /**
- * Creates uki view tree from JSON-like markup
- *
- * @example
- * uki.build( {view: 'Button', rect: '100 100 100 24', text: 'Hello world' } )
- * // Creates uki.view.Button with '100 100 100 24' passed to constructor,
- * // and calls text('Hello world') on it
- *
- * @function
- * @name uki.build
- *
- * @param {object} ml JSON-like markup
- * @returns {uki.view.Collection} collection of created elements
- */
- uki.build = function(ml) {
-
- return new uki.Collection( createMulti( (ml.length === undefined) ? [ml] : ml ) );
-
- };
-
- uki.viewNamespaces = ['uki.view.', ''];
-
- function createMulti (ml) {
- return uki.map(ml, function(mlRow) { return createSingle(mlRow); });
- }
-
- function createSingle (mlRow) {
- if (uki.isFunction(mlRow.typeName)) {
- return mlRow;
- }
-
- var c = mlRow.view || mlRow.type,
- result;
- if (uki.isFunction(c)) {
- result = new c(mlRow.rect);
- } else if (typeof c === 'string') {
- for (var i=0, ns = uki.viewNamespaces, ns$length = ns.length; i < ns$length; i++) {
- var parts = (ns[i] + c).split('.'),
- obj = root;
-
- for (var j=0, parts$length = parts.length; obj && j < parts$length; j++) {
- obj = obj[parts[j]];
- };
- if (obj) {
- result = new obj(mlRow.rect);
- break;
- }
- };
- if (!obj) throw 'No view of type ' + c + ' found';
- } else {
- result = c;
- }
-
- copyAttrs(result, mlRow);
- return result;
- }
-
- function copyAttrs(comp, mlRow) {
- uki.each(mlRow, function(name, value) {
- if (name == 'view' || name == 'type' || name == 'rect') return;
- uki.attr(comp, name, value);
- });
- return comp;
- }
-
- uki.build.copyAttrs = copyAttrs;
-})();
-
-
-
-
-/* Ideas and code parts borrowed from Sizzle (http://sizzlejs.com/) */
-(function() {
- /**#@+ @ignore */
- var self,
- attr = uki.attr,
- chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
- regexps = [ // enforce order
- { name: 'ID', regexp: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/ },
- { name: 'ATTR', regexp: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/ },
- { name: 'TYPE', regexp: /^((?:[\w\u00c0-\uFFFF\*_\.-]|\\.)+)/ },
- { name: 'POS', regexp: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/ }
- ],
- posRegexp = regexps.POS,
- posFilters = {
- first: function(i){
- return i === 0;
- },
- last: function(i, match, array){
- return i === array.length - 1;
- },
- even: function(i){
- return i % 2 === 0;
- },
- odd: function(i){
- return i % 2 === 1;
- },
- lt: function(i, match){
- return i < match[2] - 0;
- },
- gt: function(i, match){
- return i > match[2] - 0;
- },
- nth: function(i, match){
- return match[2] - 0 == i;
- },
- eq: function(i, match){
- return match[2] - 0 == i;
- }
- },
- reducers = {
- TYPE: function(comp, match) {
- var expected = match[1];
- if (expected == '*') return true;
- var typeName = attr(comp, 'typeName');
- return typeName && typeName.length >= expected.length &&
- ('.' + typeName).indexOf('.' + expected) == (typeName.length - expected.length);
- },
-
- ATTR: function(comp, match) {
- var result = attr(comp, match[1]),
- value = result + '',
- type = match[2],
- check = match[4];
-
- return result == null ? type === "!=" :
- type === "=" ? value === check :
- type === "*=" ? value.indexOf(check) >= 0 :
- type === "~=" ? (" " + value + " ").indexOf(check) >= 0 :
- !check ? value && result !== false :
- type === "!=" ? value != check :
- type === "^=" ? value.indexOf(check) === 0 :
- type === "$=" ? value.substr(value.length - check.length) === check :
- false;
- },
-
- ID: function(comp, match) {
- return reducers.ATTR(comp, ['', 'id', '=', '', match[1]]);
- },
-
- POS: function(comp, match, i, array) {
- var filter = posFilters[match[1]];
- return filter ? filter( i, match, array ) : false;
- }
- },
- mappers = {
- "+": function(context){
- return uki.unique( uki.map(context, 'nextView') );
- },
-
- ">": function(context){
- return uki.unique( flatten(uki.map(context, 'childViews')) );
- },
-
- "": function(context) {
- return uki.unique( recChildren(flatten(uki.map(context, 'childViews'))) );
- },
-
- "~": function(context){
- return uki.unique( flatten( uki.map(context, nextViews) ) );
- }
- };
-
- function nextViews (view) {
- return view.parent().childViews().slice((view._viewIndex || 0) + 1);
- }
-
- function recChildren (comps) {
- return flatten(uki.map(comps, function(comp) {
- return [comp].concat( recChildren(attr(comp, 'childViews')) );
- }));
- }
-
- function flatten (array) {
- return uki.reduce( [], array, reduceFlatten );
- }
-
- function reduceFlatten (x, e) {
- return x.concat(e);
- }
- /**#@-*/
-
- self =
- /**
- * @namespace
- */
- uki.Selector = {
- /**
- * Finds views by CSS3 selectors in view tree.
- * <p>Can be called as uki(selector) instead of uki.Selector.find(selector)</p>
- *
- * @example
- * uki('Label') find all labels on page
- * uki('Box[name=main] > Label') find all immediate descendant Labels in a box with name = "main"
- * uki('> Slider', context) find all direct descendant Sliders within given context
- * uki('Slider,Checkbox') find all Sliders and Checkboxes
- * uki('Slider:eq(3)') find 3-d slider
- *
- * @param {string} selector
- * @param {Array.<uki.view.Base>} context to search in
- *
- * @return {uki.Collection} found views
- */
- find: function(selector, context, skipFiltering) {
- context = context || uki.top();
- if (context.length === undefined) context = [context];
-
- var tokens = self.tokenize(selector),
- expr = tokens[0],
- extra = tokens[1],
- result = context,
- mapper;
-
- while (expr.length > 0) {
- mapper = mappers[expr[0]] ? mappers[expr.shift()] : mappers[''];
- result = mapper(result);
- if (expr.length == 0) break;
- result = self.reduce(expr.shift(), result);
- }
-
- if (extra) {
- result = result.concat(self.find(extra, context, true));
- }
-
- return skipFiltering ? result : new uki.Collection(uki.unique(result));
- },
-
- /** @ignore */
- reduce: function(exprItem, context) {
- if (!context || !context.length) return [];
-
- var match, found;
-
- while (exprItem != '') {
- found = false;
- uki.each(regexps, function(index, row) {
-
- /*jsl:ignore*/
- if (match = exprItem.match(row.regexp)) {
- /*jsl:end*/
- found = true;
- context = uki.grep(context, function(comp, index) {
- return reducers[row.name](comp, match, index, context);
- });
- exprItem = exprItem.replace(row.regexp, '');
- return false;
- }
- });
- if (!found) break;
- }
- return context;
- },
-
- /** @ignore */
- tokenize: function(expr) {
- var parts = [], match, extra;
-
- chunker.lastIndex = 0;
-
- while ( (match = chunker.exec(expr)) !== null ) {
- parts.push( match[1] );
-
- if ( match[2] ) {
- extra = RegExp.rightContext;
- break;
- }
- }
-
- return [parts, extra];
- }
- };
-
- uki.find = self.find;
-})();
-
-
-
-
-/**
- * Creates image element from url
- *
- * @param {string} url Image url
- * @param {string=} dataUrl Data url representation of image, used if supported
- * @param {string=} alphaUrl Gif image url for IE6
- *
- * @namespace
- * @function
- *
- * @returns {Element}
- */
-uki.image = function(url, dataUrl, alphaUrl) {
- var result = new Image();
- result.src = uki.imageSrc(url, dataUrl, alphaUrl);
- return result;
-};
-/**
- * Selects image src depending on browser
- *
- * @param {string} url Image url
- * @param {string=} dataUrl Data url representation of image, used if supported
- * @param {string=} alphaUrl Gif image url for IE6
- *
- * @returns {string}
- */
-uki.imageSrc = function(url, dataUrl, alphaUrl) {
- if (uki.image.dataUrlSupported && dataUrl) return dataUrl;
- if (alphaUrl && uki.image.needAlphaFix) return alphaUrl;
- return url;
-};
-
-/**
- * Image html representation: '<img src="">'
- *
- * @param {string} url Image url
- * @param {string=} dataUrl Data url representation of image, used if supported
- * @param {boolean=} alphaUrl Gif image url for IE6
- * @param {string=} html Additional html
- *
- * @returns {string} html
- */
-uki.imageHTML = function(url, dataUrl, alphaUrl, html) {
- if (uki.image.needAlphaFix && alphaUrl) {
- url = alphaUrl;
- } else if (uki.image.dataUrlSupported) {
- url = dataUrl;
- }
- return '<img' + (html || '') + ' src="' + url + '" />';
-};
-
-
-/**
- * @type boolean
- */
-uki.image.dataUrlSupported = doc.createElement('canvas').toDataURL || (/MSIE (8)/).test(ua);
-
-/**
- * @type boolean
- */
-uki.image.needAlphaFix = /MSIE 6/.test(ua);
-if(uki.image.needAlphaFix) try { doc.execCommand("BackgroundImageCache", false, true); } catch(e){}
-
-
-
-
-(function() {
- var nullRegexp = /^\s*null\s*$/,
- themeRegexp = /theme\s*\(\s*(.*\s*)\)/,
- rowsRegexp = /rows\s*\(\s*(.*\s*)\)/,
- cssBoxRegexp = /cssBox\s*\(\s*(.*\s*)\)/;
-
- /**
- * Transforms a bg string into a background object
- * <p>Supported strings:<br />
- * theme(bg-name) Takes background with bg-name from uki.theme<br />
- * rows(30, #CCFFFF, #FFCCFF, #FFFFCC) Creates Rows background with 30px rowHeight and 3 colors<br />
- * cssBox(border:1px solid red;background:blue) Creates CssBox background with given cssText<br />
- * url(i.png) or #FFFFFF Creates Css background with single property</p>
- *
- * @param {String} bg
- * @name uki.background
- * @namespace
- * @returns {uki.background.Base} created background
- */
- var self = uki.background = function(bg) {
- if (typeof(bg) === 'string') {
- var match;
- /*jsl:ignore*/
- if ( match = bg.match(nullRegexp) ) return new self.Null();
-
- if ( match = bg.match(themeRegexp) ) return uki.theme.background( match[1] );
- if ( match = bg.match(rowsRegexp) ) return new self.Rows( match[1].split(',')[0], match[1].split(/\s*,\s*/).slice(1) );
- if ( match = bg.match(cssBoxRegexp) ) return new self.CssBox( match[1] );
- /*jsl:end*/
- return new self.Css(bg);
- }
- return bg;
- };
-})();
-
-
-
-/**
- * @class
- */
-uki.background.Base = uki.background.Null = uki.newClass({
- init: uki.F,
- attachTo: uki.F,
- detach: uki.F
-});
-
-
-
-/**
- * Adds a div with 9 sliced images in the corners, sides and center
- *
- * @class
- */
-uki.background.Sliced9 = uki.newClass(new function() {
- var nativeCss = ['MozBorderImage', 'WebkitBorderImage', 'borderImage'],
- dom = uki.dom;
-
- var LEFT = 'left:',
- TOP = 'top:',
- RIGHT = 'right:',
- BOTTOM = 'bottom:',
- WIDTH = 'width:',
- HEIGHT = 'height:',
- PX = 'px',
- P100 = '100%';
-
- var cache = {};
-
- /**#@+ @memberOf uki.background.Sliced9.prototype */
-
- this.init = function(partSettings, inset, options) {
- this._settings = uki.extend({}, partSettings);
- this._inset = Inset.create(inset);
- this._size = null;
- this._inited = false;
-
- options = options || {};
- this._fixedSize = Size.create(options.fixedSize) || new Size();
- this._bgInset = Inset.create(options.inset) || new Inset();
- this._zIndex = options.zIndex || -1;
-
- this._container = this._getContainer();
- this._container.style.zIndex = this._zIndex;
- };
-
- /** @ignore */
- function makeDiv (name, style, setting, imgStyle, bgSettings) {
- var inner = setting[3] ? img(setting, imgStyle) : '';
- if (!setting[3]) style += bgStyle(setting, bgSettings);
- return '<div class="' + name + '" style="position:absolute;overflow:hidden;' + style + '">' + inner + '</div>';
- }
-
- /** @ignore */
- function bgStyle (setting, bgSettings) {
- return ';background: url(' + uki.imageSrc(setting[0], setting[1], setting[2]) + ') ' + bgSettings;
- }
-
- /** @ignore */
- function img (setting, style) {
- return uki.imageHTML(setting[0], setting[1], setting[2], ' ondragstart="return false;" galleryimg="no" style="-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;position:absolute;' + style + '"');
- }
-
- /** @ignore */
- this._getContainer = function() {
- var key = this._getKey();
- if (!cache[key]) {
- return cache[key] = this._createContainer();
- }
- return cache[key].cloneNode(true);
- };
-
- /** @ignore */
- this._createContainer = function() {
- var inset = this._inset,
- bgInset = this._bgInset,
- settings = this._settings,
- width = inset.left + inset.right,
- height = inset.top + inset.bottom,
- css = [LEFT + bgInset.left + PX, RIGHT + bgInset.right + PX, TOP + bgInset.top + PX, BOTTOM + bgInset.bottom + PX].join(';'),
- html = [];
-
- if (inset.top && inset.left) {
- html[html.length] = makeDiv('tl',
- [LEFT + 0, TOP + 0, WIDTH + inset.left + PX, HEIGHT + inset.top + PX].join(';'),
- settings.c, [LEFT + 0, TOP + 0, WIDTH + width + PX, HEIGHT + height + PX].join(';'), 'top left'
- );
- }
- if (inset.top) {
- html[html.length] = makeDiv('t',
- [LEFT + inset.left + PX, TOP + 0, HEIGHT + inset.top + PX, RIGHT + inset.right + PX].join(';'),
- settings.h, [LEFT + 0, TOP + 0, WIDTH + P100, HEIGHT + height + PX].join(';'), 'repeat-x top'
- );
- }
- if (inset.top && inset.right) {
- html[html.length] = makeDiv('tr',
- [RIGHT + 0, TOP + 0, WIDTH + inset.right + PX, HEIGHT + inset.top + PX].join(';'),
- settings.c, [LEFT + '-' + inset.left + PX, TOP + 0, WIDTH + width + PX, HEIGHT + height + PX].join(';'), 'top right'
- );
- }
-
- if (inset.left) {
- html[html.length] = makeDiv('l',
- [LEFT + 0, TOP + inset.top + PX, WIDTH + inset.left + PX, BOTTOM + inset.bottom + PX].join(';'),
- settings.v, [LEFT + 0, TOP + 0, HEIGHT + P100, WIDTH + width + PX].join(';'), 'repeat-y left'
- );
- }
- if (settings.m) {
- html[html.length] = makeDiv('m',
- [LEFT + inset.left + PX, TOP + inset.top + PX, RIGHT + inset.right + PX, BOTTOM + inset.bottom + PX].join(';'),
- settings.m, [LEFT + 0, TOP + 0, HEIGHT + P100, WIDTH + P100].join(';'), ''
- );
- }
- if (inset.right) {
- html[html.length] = makeDiv('r',
- [RIGHT + 0, TOP + inset.top + PX, WIDTH + inset.right + PX, BOTTOM + inset.bottom + PX].join(';'),
- settings.v, [LEFT + '-' + inset.left + PX, TOP + 0, HEIGHT + P100, WIDTH + width + PX].join(';'), 'repeat-y right'
- );
- }
-
- if (inset.bottom && inset.left) {
- html[html.length] = makeDiv('bl',
- [LEFT + 0, BOTTOM + 0, WIDTH + inset.left + PX, HEIGHT + inset.bottom + PX].join(';'),
- settings.c, [LEFT + 0, TOP + '-' + inset.top + PX, WIDTH + width + PX, HEIGHT + height + PX].join(';'), 'left -' + inset.top + PX
- );
- }
- if (inset.bottom) {
- html[html.length] = makeDiv('b',
- [LEFT + inset.left + PX, BOTTOM + 0, HEIGHT + inset.bottom + PX, RIGHT + inset.right + PX].join(';'),
- settings.h, [LEFT + 0, TOP + '-' + inset.top + PX, WIDTH + P100, HEIGHT + height + PX].join(';'), 'repeat-x 0 -' + inset.top + PX
- );
- }
- if (inset.bottom && inset.right) {
- html[html.length] = makeDiv('br',
- [RIGHT + 0, BOTTOM + 0, WIDTH + inset.right + PX, HEIGHT + inset.bottom + PX].join(';'),
- settings.c, [LEFT + '-' + inset.left + PX, TOP + '-' + inset.top + PX, WIDTH + width + PX, HEIGHT + height + PX].join(';'), 'right -' + inset.top + PX
- );
- }
- var container = uki.createElement('div', 'position:absolute;overflow:hidden;' + css, html.join(''));
- container.className = 'uki-background-Sliced9';
- return container;
- };
-
- /** @ignore */
- this._getKey = function() {
- return uki.map(['v', 'h', 'm', 'c'], function(x) {
- return this._settings[x] && this._settings[x][0] || '';
- }, this).concat([this._inset, this._bgInset, this._fixedSize]).join(',');
- };
-
- this.attachTo = function(comp) {
- this._comp = comp;
-
- this._container.style.visibility = 'visible';
- this._comp.dom().insertBefore(this._container, this._comp.dom().firstChild);
- // this._comp.dom().appendChild(this._container);
-
- if (!uki.supportNativeLayout) {
- this._layoutHandler = this._layoutHandler || uki.proxy(function(e) {
- if (this._size && this._size.eq(e.rect)) return;
- this._size = e.rect;
- this.layout();
- }, this);
- this._comp.bind('layout', this._layoutHandler);
- this.layout();
- }
- };
-
- this.detach = function() {
- if (this._comp) {
- // this._comp.dom().removeChild(this._container);
- this._container.style.visibility = 'hidden';
- if (!uki.supportNativeLayout) this._comp.unbind('layout', this._layoutHandler);
- this._size = this._comp = null;
- this._attached = this._inited = false;
- }
- };
-
- this.layout = function(e) {
- var size = this._comp.rect(),
- parts = this._parts,
- inset = this._inset,
- bgInset = this._bgInset,
- fixedSize = this._fixedSize,
- width = FLOOR(fixedSize.width || size.width - bgInset.left - bgInset.right),
- height = FLOOR(fixedSize.height || size.height - bgInset.top - bgInset.bottom),
- insetWidth = inset.left + inset.right,
- insetHeight = inset.top + inset.bottom;
-
- if (!parts) {
- parts = {};
- uki.each(this._container.childNodes, function() {
- if (this.className) parts[this.className] = this;
- });
- this._parts = parts;
- }
- // parts.b.style.bottom = ''
- // parts.b.style.top = '100%';
- // parts.b.style.marginTop = - inset.bottom + 'px';
- if (parts.t) dom.layout(parts.t.style, { width: width - insetWidth });
- if (parts.b) dom.layout(parts.b.style, { width: width - insetWidth });
- if (parts.l) dom.layout(parts.l.style, { height: height - insetHeight });
- if (parts.r) dom.layout(parts.r.style, { height: height - insetHeight });
- if (parts.m) dom.layout(parts.m.style, {
- height: height - insetHeight,
- width: width - insetWidth
- });
- dom.layout(this._container.style, {
- width: width,
- height: height
- });
- };
-
- /**#@-*/
-});
-
-
-
-/**
- * Writes css properties to targets dom()
- *
- * @class
- */
-uki.background.Css = uki.newClass(new function() {
-
- /**#@+ @memberOf uki.background.Css.prototype */
- this.init = function(options) {
- this._options = typeof options == 'string' ? {background: options} : options;
- this._options = uki.browser.css(this._options);
- };
-
- this.attachTo = function(comp) {
- this._comp = comp;
- this._originalValues = {};
-
- uki.each(this._options, function(name, value) {
- // this._originalValues[name] = dom.style[name];
- // dom.style[name] = value;
- this._originalValues[name] = comp.style(name);
- comp.style(name, value);
- }, this);
- };
-
- this.detach = function() {
- if (this._comp) {
- uki.each(this._options, function(name, value) {
- this._comp.style(name, this._originalValues[name]);
- }, this);
- }
-
- };
- /**#@-*/
-});
-
-
-
-/**
- * Adds a div with given cssText to dom()
- *
- * @class
- */
-uki.background.CssBox = uki.newClass(new function() {
-
- var cache = {};
- /** @ignore */
- function getInsets(options) {
- if (!cache[options]) {
- uki.dom.probe(
- uki.createElement('div', options + ';position:absolute;overflow:hidden;left:-999em;width:10px;height:10px;'),
- function(c) {
- cache[options] = new Inset(
- c.offsetHeight - 10,
- c.offsetWidth - 10
- );
- }
- );
- }
- return cache[options];
- }
-
- /**#@+ @memberOf uki.background.CssBox.prototype */
-
- this.init = function(options, ext) {
- this._options = options;
- ext = ext || {};
- this._inset = inset = Inset.create(ext.inset) || new Inset();
- this._insetWidth = getInsets(options).left + inset.left + inset.right;
- this._insetHeight = getInsets(options).top + inset.top + inset.bottom;
-
- this._container = uki.createElement(
- 'div',
- 'position:absolute;overflow:hidden;z-index:' + (ext.zIndex || '-1') + ';' +
- 'left:' + inset.left + 'px;top:' + inset.top + 'px;right:' + inset.right + 'px;bottom:' + inset.bottom + 'px;' +
- uki.browser.css(options),
- ext.innerHTML
- );
- this._container.className = 'uki-background-CssBox';
- this._attached = false;
- };
-
- this.attachTo = function(comp) {
- this._comp = comp;
- this._comp.dom().insertBefore(this._container, this._comp.dom().firstChild);
-
- if (uki.supportNativeLayout) return;
-
- this._layoutHandler = this._layoutHandler || uki.proxy(function(e) { this.layout(e.rect); }, this);
- this._comp.bind('layout', this._layoutHandler);
- this.layout(this._comp.rect());
- };
-
- this.layout = function(size) {
- this._prevLayout = uki.dom.layout(this._container.style, {
- width: size.width - this._insetWidth,
- height: size.height - this._insetHeight
- }, this._prevLayout);
- };
-
- this.detach = function() {
- if (this._comp) {
- this._comp.dom().removeChild(this._container);
- if (!uki.supportNativeLayout) this._comp.unbind('layout', this._layoutHandler);
- this._attached = false;
- }
- };
-
- /**#@-*/
-});
-
-
-/**
- * Adds a div with given cssText to dom()
- *
- * @class
- */
-uki.background.LinearGradient = uki.newClass(uki.background.CssBox, new function() {
-
- var CANVAS_GRADIENT_SIZE = 200;
-
- /**
- * @param options Object { startColor: '#FFFFFF', endColor: '#CCCCCC', horizontal: true, css: 'border: 1px solid #CCC' }
- */
- this.init = function(options) {
- this._options = options;
- var inset = this._inset = uki.geometry.Inset.create(this._options.inset) || new uki.geometry.Inset();
-
- this._container = this._createContainer();
- var clone = this._container.cloneNode(true);
- clone.style.cssText += ';width:100px;height:100px;';
- uki.dom.probe(clone, uki.proxy(function(c) {
- this._insetWidth = c.offsetWidth - 100 + inset.width();
- this._insetHeight = c.offsetHeight - 100 + inset.height();
- }, this));
- this._container.style.cssText += ';left:' + inset.left + 'px;top:' + inset.top + 'px;right:' + inset.right + 'px;bottom:' + inset.bottom + 'px;';
-
- this._attached = false;
- };
-
- var urlCache = {};
- function getGradientURL (startColor, endColor, horizontal, stops) {
- var key = startColor + endColor + (horizontal ? 1 : 0) + uki.map(stops, function(stop) { return stop.pos + '-' + stop.color; });
- if (!urlCache[key]) {
-
- var canvas = document.createElement('canvas');
- canvas.width = canvas.height = CANVAS_GRADIENT_SIZE;
-
- var context = canvas.getContext('2d'),
- gradient = context.createLinearGradient(0, 0, horizontal ? CANVAS_GRADIENT_SIZE : 0, horizontal ? 0 : CANVAS_GRADIENT_SIZE);
-
- gradient.addColorStop(0, startColor);
- gradient.addColorStop(1, endColor);
- for (var i=0; i < stops.length; i++) {
- gradient.addColorStop(stops[i].pos, stops[i].color);
- };
- context.fillStyle = gradient;
- context.fillRect(0, 0, CANVAS_GRADIENT_SIZE, CANVAS_GRADIENT_SIZE);
- urlCache[key] = canvas.toDataURL && canvas.toDataURL();
- }
- return urlCache[key];
- }
-
- function mosFilter (horizontal, startColor, endColor) {
- return 'filter:progid:DXImageTransform.Microsoft.gradient(gradientType=' + (horizontal ? '1' : '0') + ', startColorstr=#FF' + startColor.substr(1) + ', endColorstr=#FF' + endColor.substr(1) + ');';
- }
-
-
- this._createContainer = function() {
- var startColor = this._options.startColor || '#FFFFFF',
- endColor = this._options.endColor || '#CCCCCC',
- horizontal = this._options.horizontal,
- stops = this._options.stops || [],
- css = '',
- i = 0,
- cssProp = uki.browser.cssLinearGradient(),
- url;
-
- if (cssProp == '-moz-linear-gradient' || cssProp == 'linear-gradient') {
- css += 'background-image:' + cssProp + '(' + (horizontal ? 'left' : 'top') + ', ' + startColor;
- for (;i<stops.length;i++) {
- css += ',' + stops[i].color + ' ' + (stops[i].pos * 100) + '%';
- }
- css += ', ' + endColor + ');';
- } else if (cssProp == '-webkit-gradient') {
- css += 'background-image:' + cssProp + '(linear, 0% 0%, ' + (horizontal ? '100% 0%' : '0% 100%') + ', from(' + startColor + '), to(' + endColor + ')';
- for (;i<stops.length;i++) {
- css += ',color-stop(' + (stops[i].pos * 100) + '%,' + stops[i].color +')';
- }
- css += ');';
- } else if (!uki.browser.canvas() && uki.browser.cssFilter() && stops.length == 0) {
- css += mosFilter(horizontal, startColor, endColor);
- }
-
- var container = uki.createElement('div', uki.browser.css(this._options.css) + ';position:absolute;overflow:hidden;z-index:' + (this._options.zIndex || '-1') + ';' + css, this._options.innerHTML);
- container.className = 'uki-background-CssBox';
- if (css) return container;
-
- if (uki.browser.canvas() && (url = getGradientURL(startColor, endColor, horizontal, stops))) {
- var img = uki.createElement('img', 'position:absolute;left:0;top:0;width:100%;height:100%;z-index:0;');
- img.src = url;
- container.appendChild(img);
- } else if (uki.browser.cssFilter() && stops.length > 0) {
- stops.unshift({ pos: 0, color: startColor });
- stops.push({ pos: 1, color: endColor });
- var child;
- for (;i<stops.length-1;i++) {
- child = uki.createElement('div', 'position:absolute;z-index:-1' +
- ';left:' + (horizontal ? stops[i].pos * 100 - (i && 1) + '%' : '0') +
- ';top:' + (horizontal ? '0' : stops[i].pos * 100 - (i && 1) + '%') +
- ';width:' + (horizontal ? (stops[i+1].pos - stops[i].pos) * 100 + 1 + '%' : '100%') +
- ';height:' + (horizontal ? '100%' : (stops[i+1].pos - stops[i].pos) * 100 + 1 + '%') +
- ';' + mosFilter(horizontal, stops[i].color, stops[i+1].color)
- );
- container.appendChild(child);
- }
- }
- return container;
- };
-
- /**#@-*/
-});
-
-
-/**
- * Adds a div with colored rows to dom
- *
- * @class
- */
-uki.background.Rows = uki.newClass(new function() {
- var cache = [],
- packSize = 100;
-
- /**#@+ @memberOf uki.background.Rows.prototype */
-
- this.init = function(height, colors) {
- this._height = height || 20;
- this._colors = uki.isArray(colors) ? colors : colors.split(' ');
- this._packSize = CEIL(packSize/this._colors.length)*this._colors.length;
- this._renderedHeight = 0;
- this._visibleExt = 200;
- if (this._colors.length == 1) this._colors = this._colors.concat(['#FFF']);
- };
-
- this.attachTo = function(comp) {
- this._comp && this.detach();
- this._comp = comp;
- if (!this._container) {
- this._container = uki.createElement(
- 'div',
- 'position:absolute;left:0;top:0;width:100%;z-index:-1'
- );
- this._container.className = 'uki-background-Rows' ;
- }
- this._layoutHandler = this._layoutHandler || uki.proxy(function(e) { this.layout(e.rect, e.visibleRect); }, this);
- this._comp.dom().appendChild(this._container);
- this._comp.bind('layout', this._layoutHandler);
- };
-
- this.layout = function(rect, visibleRect) {
- var height = visibleRect ? visibleRect.height + this._visibleExt*2 : rect.maxY();
- while (this._renderedHeight < height) {
- var h = packSize * this._height,
- c = uki.createElement('div', 'height:' + h + 'px;overflow:hidden;width:100%;', getPackHTML(this._height, this._colors));
- this._renderedHeight += h;
- this._container.appendChild(c);
- }
- if (visibleRect) {
- this._container.style.top = CEIL((visibleRect.y - this._visibleExt)/this._height/this._colors.length)*this._height*this._colors.length + 'px';
- }
- };
-
- this.detach = function() {
- if (!this._comp) return;
- this._comp.dom().removeChild(this._container);
- this._comp.unbind('layout', this._layoutHandler);
- this._comp = null;
- };
-
- /**#@-*/
-
- function getPackHTML (height, colors) {
- var key = height + ' ' + colors.join(' '),
- rows = [],
- html = [],
- i, l = colors.length;
- if (!cache[key]) {
- for (i=0; i < l; i++) {
- rows[i] = ['<div style="height:', height, 'px;width:100%;overflow:hidden;',
- (colors[i] ? 'background:' + colors[i] : ''),
- '"></div>'].join('');
- };
- for (i=0; i < packSize; i++) {
- html[i] = rows[i%l];
- };
- cache[key] = html.join('');
- }
- return cache[key];
- }
-});
-
-
-/**
- * @class
- */
-uki.background.Multi = uki.newClass({
- init: function() {
- this._bgs = Array.prototype.slice.call(arguments, 0);
- },
- attachTo: function(comp) {
- for (var i=0, $this$_bgs$length = this._bgs.length; i < $this$_bgs$length; i++) {
- this._bgs[i].attachTo(comp);
- };
- },
- detach: function() {
- for (var i=0, $this$_bgs$length = this._bgs.length; i < $this$_bgs$length; i++) {
- this._bgs[i].detach();
- };
- }
-});
-
-
-/**
- * @namespace
- */
-(function() {
-var self = uki.theme = {
- themes: [],
-
- register: function(theme, /* internal */ themes) {
- (themes = self.themes)[ themes.length] = theme;
- },
-
- background: function(name, params) {
- return self._namedResource(name, 'background', params) || new uki.background.Null();
- },
-
- image: function(name, params) {
- return self._namedResource(name, 'image', params) || new Image();
- },
-
- imageSrc: function(name, params) {
- return self._namedResource(name, 'imageSrc', params) || '';
- },
-
- style: function(name, params) {
- return self._namedResource(name, 'style', params) || '';
- },
-
- dom: function(name, params) {
- return self._namedResource(name, 'dom', params) || uki.createElement('div');
- },
-
- template: function(name, params) {
- return self._namedResource(name, 'template', params) || '';
- },
-
- _namedResource: function(name, type, params, i, result) {
- for ( i = self.themes.length - 1 ; i >= 0; i--) {
- if (result = (self.themes[i] [type](name, params)))
- return result;
- };
- return null;
- }
-};
-})();
-
-
-
-/**
- * @class
- */
-uki.theme.Base = {
- images: [],
- imageSrcs: [],
- backgrounds: [],
- doms: [],
- styles: [],
- templates: [],
-
- background: function(name, params) {
- return this.backgrounds[name] && this.backgrounds[name](params);
- },
-
- image: function(name, params) {
- if (this.images[name]) return this.images[name](params);
- return this.imageSrcs[name] && uki.image.apply(uki, this.imageSrcs[name](params));
- },
-
- imageSrc: function(name, params) {
- if (this.imageSrcs[name]) return uki.imageSrc.apply(uki, this.imageSrcs[name](params));
- return this.images[name] && this.images[name](params).src;
- },
-
- dom: function(name, params) {
- return this.doms[name] && this.doms[name](params);
- },
-
- style: function(name, params) {
- return this.styles[name] && this.styles[name](params);
- },
-
- template: function(name, params) {
- return this.templates[name] && this.templates[name](params);
- }
-};
-
-
-/**
- * Simple and fast (2x-15x faster than regexp) html template
- * @example
- * var t = new uki.theme.Template('<p class="${className}">${value}</p>')
- * t.render({className: 'myClass', value: 'some html'})
- */
-uki.theme.Template = function(code) {
- var parts = code.split('${'), i, l, tmp;
- this.parts = [parts[0]];
- this.names = [];
- for (i=1, l = parts.length; i < l; i++) {
- tmp = parts[i].split('}');
- this.names.push(tmp.shift());
- this.parts.push('');
- this.parts.push(tmp.join('}'));
- };
-};
-
-uki.theme.Template.prototype.render = function(values) {
- for (var i=0, names = this.names, l = names.length; i < l; i++) {
- this.parts[i*2+1] = values[names[i]] || '';
- };
- return this.parts.join('');
-};
-
-
-/**
- * @namespace
- */
-uki.view.utils = new function() {
- this.visibleRect = function (from, upTo) {
- var queue = [],
- rect, i, tmpRect, c = from;
-
- do {
- queue[queue.length] = c;
- c = c.parent();
- } while (c && c != upTo);
-
- if (upTo && upTo != from) queue[queue.length] = upTo;
-
- for (i = queue.length - 1; i >= 0; i--){
- c = queue[i];
- tmpRect = visibleRect(c);
- rect = rect ? rect.intersection(tmpRect) : tmpRect;
- rect.x -= c.rect().x;
- rect.y -= c.rect().y;
-
- };
- return rect;
- };
-
- this.top = function(c) {
- while (c.parent()) c = c.parent();
- return c;
- };
-
- this.offset = function(c, upTo) {
- var offset = new Point(),
- rect;
-
- while (c && c != upTo) {
- rect = c.rect();
- offset.x += rect.x;
- offset.y += rect.y;
- if (c.scrollTop) {
- offset.x -= c.scrollLeft();
- offset.y -= c.scrollTop();
- }
- c = c.parent();
- }
- return offset;
- };
-
- this.scrollableParent = function(c) {
- do {
- if (uki.isFunction(c.scrollTop)) return c;
- c = c.parent();
- } while (c);
- return null;
- };
-
- /** @inner */
- function visibleRect (c) {
- return c.visibleRect ? c.visibleRect() : c.rect().clone();
- }
- /**#@-*/
-};
-
-uki.extend(uki.view, uki.view.utils);
-
-
-/**
- * @class
- */
-uki.view.Styleable = new function() {
- /** @scope uki.view.Styleable.prototype */
-
- /**
- * @name style
- * @memberOf uki.view.Styleable#
- * @function
- */
- this.style = function(name, value) {
- if (typeof name == 'string') return this._style(name, value);
-
- uki.each(name, function(name, value) {
- this._style(name, value);
- }, this);
- return this;
- };
-
- this._style = function(name, value) {
- if (value === undefined) return this._dom.style[name];
- this._dom.style[name] = value;
- return this;
- };
-
- // TODO: is this really needed?
- // uki.each('fontSize,textAlign,color,fontFamily,fontWeight,lineHeight,zIndex'.split(','), function(i, name) {
- // proto[name] = function(value) {
- // return this._style(name, value);
- // };
- // });
-
- /**
- * Sets whether text of the view can be selected.
- *
- * @memberOf uki.view.Styleable#
- * @name textSelectable
- * @function
- * @param {boolean=} state
- * @returns {boolean|uki.view.Base} current textSelectable state of self
- */
- this.textSelectable = uki.newProp('_textSelectable', function(state) {
- this._textSelectable = state;
- if (uki.browser.cssUserSelect() != 'unsupported') {
- this._dom.style[uki.camalize(uki.browser.cssUserSelect())] = (state ? '' : uki.browser.cssUserSelect() == '-moz-user-select' ? '-moz-none' : 'none');
- } else {
- uki.dom[state ? 'unbind' : 'bind'](this.dom(), 'selectstart', uki.dom.preventDefaultHandler);
- }
- this._dom.style.cursor = state ? '' : 'default';
- });
-
- this.draggable = function(state) {
- if (state === undefined) return this._dom.getAttribute('draggable');
- this._dom.setAttribute('draggable', true);
- this._dom.style.WebkitUserDrag = 'element';
- return this;
- };
-
- /**#@-*/
-};
-
-
-
-
-/**
- * @interface
- */
-uki.view.Focusable = new function() {/** @lends uki.view.Focusable.prototype */
-
- // dom: function() {
- // return null; // should implement
- // },
- this._focusable = true; // default value
- this._focusOnClick = true;
-
- this.focusOnClick = uki.newProp('_focusOnClick');
-
- this.focusable = uki.newProp('_focusable', function(v) {
- this._focusable = v;
- if (v) this._initFocusable();
- this._updateFocusable();
- }),
-
- this.disabled = uki.newProp('_disabled', function(d) {
- var changed = d !== !!this._disabled;
- this._disabled = d;
- if (d) this.blur();
- this._updateFocusable();
- if (changed && this._updateBg) this._updateBg();
- }),
-
- this._updateFocusable = function() {
- if (this._preCreatedFocusTarget || !this._focusTarget) return;
-
- if (this._focusable && !this._disabled) {
- this._focusTarget.style.display = 'block';
- } else {
- this._focusTarget.style.display = 'none';
- }
- },
-
- this._initFocusable = function(preCreatedFocusTarget) {
- if ((!preCreatedFocusTarget && !this._focusable) || this._focusTarget) return;
- this._focusTarget = preCreatedFocusTarget;
- this._preCreatedFocusTarget = preCreatedFocusTarget;
-
- if (!preCreatedFocusTarget) {
- this._focusTarget = uki.createElement('input', 'position:absolute;left:-9999px;top:0;width:1px;height:1px;');
- this._focusTarget.className = 'uki-view-Focusable';
- this.dom().appendChild(this._focusTarget);
- }
- this._hasFocus = false;
- this._firstFocus = true;
-
- uki.dom.bind(this._focusTarget, 'focus', uki.proxy(function(e) {
- this._stopWatingForBlur();
- if (!this._hasFocus) this._focus(e);
- }, this));
-
- uki.dom.bind(this._focusTarget, 'blur', uki.proxy(function(e) {
- if (this._hasFocus) {
- this._hasFocus = false;
- this._waitingForBlur =
- setTimeout(uki.proxy(function() { // wait for mousedown refocusing
- this._waitingForBlur = false;
- if (!this._hasFocus) this._blur();
- }, this), 1);
- }
- }, this));
-
- if (!preCreatedFocusTarget) this.bind('mousedown', function(e) {
- if (this._focusOnClick) this.focus();
- });
- this._updateFocusable();
- }
-
- this._focus = function(e) {
- this._hasFocus = true;
- this._firstFocus = false;
- }
-
- this._blur = function(e) {
- this._hasFocus = false;
- }
-
- this._stopWatingForBlur = function() {
- if (this._waitingForBlur) {
- clearTimeout(this._waitingForBlur);
- this._waitingForBlur = false;
- this._hasFocus = true;
- }
- };
-
- this.focus = function() {
- if (this._focusable && !this._disabled) {
- this._stopWatingForBlur();
- if (!this._hasFocus) this._focus();
- var target = this._focusTarget;
- setTimeout(function() {
- try {
- target.focus();
- } catch(e) { }
- target = null;
- }, 1);
- }
- return this;
- },
-
- this.blur = function() {
- try {
- this._focusTarget.blur();
- } catch(e) {}
- return this;
- }
-
- this.hasFocus = function() {
- return this._hasFocus;
- }
-
- this._bindToDom = function(name) {
- if (!this._focusTarget || 'keyup keydown keypress focus blur'.indexOf(name) == -1) return false;
-
- return uki.view.Observable._bindToDom.call(this, name, this._focusTarget);
- }
-
-
-};
-
-
-
-
-
-
-
-
-var ANCHOR_TOP = 1,
- ANCHOR_RIGHT = 2,
- ANCHOR_BOTTOM = 4,
- ANCHOR_LEFT = 8,
- ANCHOR_WIDTH = 16,
- ANCHOR_HEIGHT = 32;
-
-uki.view.declare('uki.view.Base', uki.view.Observable, uki.view.Styleable, function(Observable, Styleable) {
-
- var layoutId = 1;
-
- this.defaultCss = 'position:absolute;z-index:100;-moz-user-focus:none;';
-
- /**
- * Base class for all uki views.
- *
- * <p>View creates and layouts dom nodes. uki.view.Base defines basic API for other views.
- * It also defines common layout algorithms.</p>
- *
- * Layout
- *
- * <p>View layout is defined by rectangle and anchors.
- * Rectangle is passed to constructor, anchors are set through the #anchors attribute.</p>
- *
- * <p>Rectangle defines initial position and size. Anchors specify how view will move and
- * resize when its parent is resized.</p>
- *
- * 2 phases of layout
- *
- * <p>Layout process has 2 phases.
- * First views rectangles are recalculated. This may happen several times before dom
- * is touched. This is done either explicitly through #rect attribute or through
- * #parentResized callbacks.
- * After rectangles are set #layout is called. This actually updates dom styles.</p>
- *
- * @example
- * uki({ view: 'Base', rect: '10 20 100 50', anchors: 'left top right' })
- * // Creates Base view with initial x = 10px, y = 20px, width = 100px, height = 50px.
- * // When parent resizes x, y and height will stay the same. Width will resize with parent.
- *
- *
- * @see uki.view.Base#anchors
- * @constructor
- * @augments uki.view.Observable
- * @augments uki.view.Styleable
- *
- * @name uki.view.Base
- * @implements uki.view.Observable
- * @param {uki.geometry.Rect} rect initial position and size
- */
- this.init = function(rect) {
- this._parentRect = this._rect = Rect.create(rect);
- this._setup();
- uki.initNativeLayout();
- this._createDom();
- };
-
- /**#@+ @memberOf uki.view.Base# */
-
- /** @private */
- this._setup = function() {
- uki.extend(this, {
- _anchors: 0,
- _parent: null,
- _visible: true,
- _needsLayout: true,
- _textSelectable: false,
- _styleH: 'left',
- _styleV: 'top',
- _firstLayout: true
- });
- this.defaultCss += uki.theme.style('base');
- };
-
- /**
- * Get views container dom node.
- * @returns {Element} dom
- */
- this.dom = function() {
- return this._dom;
- };
-
- /* ------------------------------- Common settings --------------------------------*/
- /**
- * Used for fast (on hash lookup) view searches: uki('#view_id');
- *
- * @param {string=} id New id value
- * @returns {string|uki.view.Base} current id or self
- */
- this.id = function(id) {
- if (id === undefined) return this._dom.id;
- if (this._dom.id) uki.unregisterId(this);
- this._dom.id = id;
- uki.registerId(this);
- return this;
- };
-
- /**
- * Accessor for dom().className
- * @param {string=} className
- *
- * @returns {string|uki.view.Base} className or self
- */
- uki.delegateProp(this, 'className', '_dom');
-
- /**
- * Accessor for view visibility.
- *
- * @param {boolean=} state
- * @returns {boolean|uki.view.Base} current visibility state of self
- */
- this.visible = function(state) {
- if (state === undefined) return this._dom.style.display != 'none';
-
- this._dom.style.display = state ? 'block' : 'none';
- return this;
- };
-
- /**
- * Accessor for background attribute.
- * @param {string|uki.background.Base=} background
- * @returns {uki.background.Base|uki.view.Base} current background or self
- */
- this.background = function(val) {
- if (val === undefined && !this._background && this.defaultBackground) this._background = this.defaultBackground();
- if (val === undefined) return this._background;
- val = uki.background(val);
-
- if (val == this._background) return this;
- if (this._background) this._background.detach(this);
- val.attachTo(this);
-
- this._background = val;
- return this;
- };
-
- /**
- * Accessor for default background attribute.
- * @name defaultBackground
- * @function
- * @returns {uki.background.Base} default background if not overridden through attribute
- */
- this.defaultBackground = function() {
- return this._defaultBackground && uki.background(this._defaultBackground);
- };
-
- /* ----------------------------- Container api ------------------------------*/
-
- /**
- * Accessor attribute for parent view. When parent is set view appends its #dom
- * to parents #domForChild
- *
- * @param {?uki.view.Base=} parent
- * @returns {uki.view.Base} parent or self
- */
- this.parent = function(parent) {
- if (parent === undefined) return this._parent;
-
- // if (this._parent) this._dom.parentNode.removeChild(this._dom);
- this._parent = parent;
- // if (this._parent) this._parent.domForChild(this).appendChild(this._dom);
- return this;
- };
-
- /**
- * Accessor for childViews. @see uki.view.Container for implementation
- * @returns {Array.<uki.view.Base>}
- */
- this.childViews = function() {
- return [];
- };
-
- /**
- * Reader for previous view
- * @returns {uki.view.Base}
- */
- this.prevView = function() {
- if (!this.parent()) return null;
- return this.parent().childViews()[this._viewIndex - 1] || null;
- };
-
- /**
- * Reader for next view
- * @returns {uki.view.Base}
- */
- this.nextView = function() {
- if (!this.parent()) return null;
- return this.parent().childViews()[this._viewIndex + 1] || null;
- };
-
-
- /* ----------------------------- Layout ------------------------------*/
-
- /**
- * Sets or retrieves view's position and size.
- *
- * @param {string|uki.geometry.Rect} newRect
- * @returns {uki.view.Base} self
- */
- this.rect = function(newRect) {
- if (newRect === undefined) return this._rect;
-
- newRect = Rect.create(newRect);
- this._parentRect = newRect;
- this._rect = this._normalizeRect(newRect);
- this._needsLayout = this._needsLayout || layoutId++;
- return this;
- };
-
- /**
- * Set or get sides which the view should be attached to.
- * When a view is attached to a side the distance between this side and views border
- * will remain constant on resize. Anchor can be any combination of
- * "top", "right", "bottom", "left", "width" and "height".
- * If you set both "right" and "left" than "width" is assumed.
- *
- * Anchors are stored as a bit mask. Though its easier to set them using strings
- *
- * @function
- * @param {string|number} anchors
- * @returns {number|uki.view.Base} anchors or self
- */
- this.anchors = uki.newProp('_anchors', function(anchors) {
- if (anchors.indexOf) {
- var tmp = 0;
- if (anchors.indexOf('right' ) > -1) tmp |= ANCHOR_RIGHT;
- if (anchors.indexOf('bottom' ) > -1) tmp |= ANCHOR_BOTTOM;
- if (anchors.indexOf('top' ) > -1) tmp |= ANCHOR_TOP;
- if (anchors.indexOf('left' ) > -1) tmp |= ANCHOR_LEFT;
- if (anchors.indexOf('width' ) > -1 || (tmp & ANCHOR_LEFT && tmp & ANCHOR_RIGHT)) tmp |= ANCHOR_WIDTH;
- if (anchors.indexOf('height' ) > -1 || (tmp & ANCHOR_BOTTOM && tmp & ANCHOR_TOP)) tmp |= ANCHOR_HEIGHT;
- anchors = tmp;
- }
- this._anchors = anchors;
- this._styleH = anchors & ANCHOR_LEFT ? 'left' : 'right';
- this._styleV = anchors & ANCHOR_TOP ? 'top' : 'bottom';
- });
-
- /**
- * Returns rectangle for child layout. Usually equals to #rect. Though in some cases,
- * client rectangle my differ from #rect. Example uki.view.ScrollPane.
- *
- * @param {uki.view.Base} child
- * @returns {uki.geometry.Rect}
- */
- this.rectForChild = function(child) {
- return this.rect();
- };
-
- /**
- * Updates dom to match #rect property.
- *
- * Layout is designed to minimize dom writes. If view is anchored to the right then
- * style.right is used, style.left for left anchor, etc. If browser supports this
- * both style.right and style.left are used. Otherwise style.width will be updated
- * manually on each resize.
- *
- * @fires event:layout
- * @see uki.dom.initNativeLayout
- */
- this.layout = function() {
- this._layoutDom(this._rect);
- this._needsLayout = false;
- this.trigger('layout', {rect: this._rect, source: this});
- this._firstLayout = false;
- };
-
- this.layoutIfNeeded = function() {
- if (this._needsLayout && this.visible()) this.layout();
- };
-
-
- /**
- * @function uki.view.Base#minSize
- * @function uki.view.Base#maxSize
- */
- uki.each(['min', 'max'], function(i, name) {
- var attr = name + 'Size',
- prop = '_' + attr;
- this[attr] = function(s) {
- if (s === undefined) return this[prop] || new Size();
- this[prop] = Size.create(s);
- this.rect(this._parentRect);
- this._dom.style[name + 'Width'] = this[prop].width ? this[prop].width + PX : '';
- this._dom.style[name + 'Height'] = this[prop].height ? this[prop].height + PX : '';
- return this;
- };
- }, this);
-
- /**
- * Resizes view when parent changes size according to anchors.
- * Called from parent view. Usually after parent's #rect is called.
- *
- * @param {uki.geometry.Rect} oldSize
- * @param {uki.geometry.Rect} newSize
- */
- this.parentResized = function(oldSize, newSize) {
- var newRect = this._parentRect.clone(),
- dX = (newSize.width - oldSize.width) /
- ((this._anchors & ANCHOR_LEFT ^ ANCHOR_LEFT ? 1 : 0) + // flexible left
- (this._anchors & ANCHOR_WIDTH ? 1 : 0) +
- (this._anchors & ANCHOR_RIGHT ^ ANCHOR_RIGHT ? 1 : 0)), // flexible right
- dY = (newSize.height - oldSize.height) /
- ((this._anchors & ANCHOR_TOP ^ ANCHOR_TOP ? 1 : 0) + // flexible top
- (this._anchors & ANCHOR_HEIGHT ? 1 : 0) +
- (this._anchors & ANCHOR_BOTTOM ^ ANCHOR_BOTTOM ? 1 : 0)); // flexible right
-
- if (this._anchors & ANCHOR_LEFT ^ ANCHOR_LEFT) newRect.x += dX;
- if (this._anchors & ANCHOR_WIDTH) newRect.width += dX;
-
- if (this._anchors & ANCHOR_TOP ^ ANCHOR_TOP) newRect.y += dY;
- if (this._anchors & ANCHOR_HEIGHT) newRect.height += dY;
- this.rect(newRect);
- };
-
- /**
- * Called when child changes it's size
- */
- this.childResized = function(child) {
- // do nothing, extend in subviews
- };
-
- /**
- * Resizes view to its contents. Contents size is determined by view.
- * View can be resized by width, height or both. This is specified through
- * autosizeStr param.
- * View will grow shrink according to its #anchors.
- *
- * @param {autosizeStr} autosize
- * @returns {uki.view.Base} self
- */
- this.resizeToContents = function(autosizeStr) {
- var autosize = decodeAutosize(autosizeStr);
- if (0 == autosize) return this;
-
- var oldRect = this.rect(),
- newRect = this._calcRectOnContentResize(autosize);
- // if (newRect.eq(oldRect)) return this;
- // this.rect(newRect);
- this._rect = this._parentRect = newRect;
- this._needsLayout = true;
- return this;
- };
-
- /**
- * Calculates view's contents size. Redefined in subclasses.
- *
- * @param {number} autosize Bitmask
- * @returns {uki.geometry.Rect}
- */
- this.contentsSize = function(autosize) {
- return this.rect();
- };
-
- /** @private */
- this._normalizeRect = function(rect) {
- if (this._minSize) {
- rect = new Rect(rect.x, rect.y, MAX(this._minSize.width, rect.width), MAX(this._minSize.height, rect.height));
- }
- if (this._maxSize) {
- rect = new Rect(rect.x, rect.y, MIN(this._maxSize.width, rect.width), MIN(this._maxSize.height, rect.height));
- }
- return rect;
- };
-
-
-
- /** @ignore */
- function decodeAutosize (autosizeStr) {
- if (!autosizeStr) return 0;
- var autosize = 0;
- if (autosizeStr.indexOf('width' ) > -1) autosize = autosize | ANCHOR_WIDTH;
- if (autosizeStr.indexOf('height') > -1) autosize = autosize | ANCHOR_HEIGHT;
- return autosize;
- }
-
-
- /** @private */
- this._initBackgrounds = function() {
- if (this.background()) this.background().attachTo(this);
- };
-
- /** @private */
- this._calcRectOnContentResize = function(autosize) {
- var newSize = this.contentsSize( autosize ),
- oldSize = this.rect();
-
- if (newSize.eq(oldSize)) return oldSize; // nothing changed
-
- // calculate where to resize
- var newRect = this.rect().clone(),
- dX = newSize.width - oldSize.width,
- dY = newSize.height - oldSize.height;
-
- if (autosize & ANCHOR_WIDTH) {
- if (this._anchors & ANCHOR_LEFT ^ ANCHOR_LEFT && this._anchors & ANCHOR_RIGHT ^ ANCHOR_RIGHT) {
- newRect.x -= dX/2;
- } else if (this._anchors & ANCHOR_LEFT ^ ANCHOR_LEFT) {
- newRect.x -= dX;
- }
- newRect.width += dX;
- }
-
- if (autosize & ANCHOR_HEIGHT) {
- if (this._anchors & ANCHOR_TOP ^ ANCHOR_TOP && this._anchors & ANCHOR_BOTTOM ^ ANCHOR_BOTTOM) {
- newRect.y -= dY/2;
- } else if (this._anchors & ANCHOR_TOP ^ ANCHOR_TOP) {
- newRect.y -= dY;
- }
- newRect.height += dY;
- }
-
- return newRect;
- };
-
- /** @function
- @name uki.view.Base#width */
- /** @function
- @name uki.view.Base#height */
- /** @function
- @name uki.view.Base#minX */
- /** @function
- @name uki.view.Base#maxX */
- /** @function
- @name uki.view.Base#minY */
- /** @function
- @name uki.view.Base#maxY */
- /** @function
- @name uki.view.Base#left */
- /** @function
- @name uki.view.Base#top */
- uki.each(['width', 'height', 'minX', 'maxX', 'minY', 'maxY', 'x', 'y', 'left', 'top'], function(index, attr) {
- this[attr] = function(value) {
- if (value === undefined) return uki.attr(this.rect(), attr);
- uki.attr(this.rect(), attr, value);
- return this;
- };
- }, this);
-
- /* ---------------------------------- Dom --------------------------------*/
- /**
- * Called through a second layout pass when _dom should be created
- * @private
- */
- this._createDom = function() {
- this._dom = uki.createElement('div', this.defaultCss);
- this._initClassName();
- };
-
- this._initClassName = function() {
- this._dom.className = this.typeName().replace(/\./g, '-');
- };
-
- /**
- * Called through a second layout pass when _dom is already created
- * @private
- */
- this._layoutDom = function(rect) {
- var l = {}, s = uki.supportNativeLayout, relativeRect = this.parent().rectForChild(this);
- if (s && this._anchors & ANCHOR_LEFT && this._anchors & ANCHOR_RIGHT) {
- l.left = rect.x;
- l.right = relativeRect.width - rect.x - rect.width;
- } else {
- l.width = rect.width;
- l[this._styleH] = this._styleH == 'left' ? rect.x : relativeRect.width - rect.x - rect.width;
- }
-
- if (s && this._anchors & ANCHOR_TOP && this._anchors & ANCHOR_BOTTOM) {
- l.top = rect.y;
- l.bottom = relativeRect.height - rect.y - rect.height;
- } else {
- l.height = rect.height;
- l[this._styleV] = this._styleV == 'top' ? rect.y : relativeRect.height - rect.y - rect.height;
- }
- this._lastLayout = uki.dom.layout(this._dom.style, l, this._lastLayout);
- if (this._firstLayout) this._initBackgrounds();
- return true;
- };
-
- /** @private */
- this._bindToDom = function(name) {
- if ('resize layout'.indexOf(name) > -1) return true;
- return uki.view.Observable._bindToDom.call(this, name);
- };
-
- /**#@-*/
-});
-
-
-
-/**
- * @class
- * @augments uki.view.Base
- * @name uki.view.Container
- */
-uki.view.declare('uki.view.Container', uki.view.Base, function(Base) {
- /**#@+ @memberOf uki.view.Container# */
-
- this._inset = new Inset();
-
- /** @private */
- this._setup = function() {
- this._childViews = [];
- Base._setup.call(this);
- };
-
- /** @ignore */
- function maxProp (c, prop) {
- var val = 0, i, l;
- for (i = c._childViews.length - 1; i >= 0; i--){
- if (!c._childViews[i].visible()) continue;
- val = MAX(val, c._childViews[i].rect()[prop]());
- };
- return val;
- }
-
- this.contentsWidth = function() {
- return maxProp(this, 'maxX') + this.inset().right;
- };
-
- this.contentsHeight = function() {
- return maxProp(this, 'maxY') + this.inset().bottom;
- };
-
- this.contentsSize = function() {
- return new Size(this.contentsWidth(), this.contentsHeight());
- };
-
- /**
- * Sets or retrieves view child view.
- * @param anything uki.build can parse
- *
- * Note: if setting on view with child views, all child view will be removed
- */
- this.childViews = function(val) {
- if (val === undefined) return this._childViews;
- uki.each(this._childViews, function(i, child) {
- this.removeChild(child);
- }, this);
- uki.each(uki.build(val), function(tmp, child) {
- this.appendChild(child);
- }, this);
- return this;
- };
-
- /**
- * Remove particular child
- */
- this.removeChild = function(child) {
- child.parent(null);
- this.domForChild(child).removeChild(child.dom());
- var index = child._viewIndex,
- i, l;
- for (i=index+1, l = this._childViews.length; i < l; i++) {
- this._childViews[i]._viewIndex--;
- };
- this._childViews = uki.grep(this._childViews, function(elem) { return elem != child; });
- this._contentChanged();
- };
-
- /**
- * Adds a child.
- */
- this.appendChild = function(child) {
- child._viewIndex = this._childViews.length;
- this._childViews.push(child);
- child.parent(this);
- this.domForChild(child).appendChild(child.dom());
- this._contentChanged();
- };
-
- /**
- * Insert child before target beforeChild
- * @param {uki.view.Base} child Child to insert
- * @param {uki.view.Base} beforeChild Existent child before which we should insert
- */
- this.insertBefore = function(child, beforeChild) {
- var i, l;
- child._viewIndex = beforeChild._viewIndex;
- for (i=beforeChild._viewIndex, l = this._childViews.length; i < l; i++) {
- this._childViews[i]._viewIndex++;
- };
- this._childViews.splice(beforeChild._viewIndex-1, 0, child);
- child.parent(this);
- this.domForChild(child).insertBefore(child.dom(), beforeChild.dom());
- this._contentChanged();
- };
-
- /**
- * Should return a dom node for a child.
- * Child should append itself to this dom node
- */
- this.domForChild = function(child) {
- return this._dom;
- };
-
- this.inset = uki.newProp('_inset', function(v) {
- this._inset = Inset.create(v);
- });
-
- /** @private */
- this._contentChanged = function() {
- // called on every insertBefore, appendChild, removeChild
- };
-
- this._layoutDom = function(rect) {
- Base._layoutDom.call(this, rect);
- this._layoutChildViews(rect);
- };
-
- /** @private */
- this._layoutChildViews = function() {
- for (var i=0, childViews = this.childViews(); i < childViews.length; i++) {
- childViews[i].layoutIfNeeded();
- };
- };
-
- /**
- * @fires event:resize
- */
- this.rect = function(newRect) {
- if (newRect === undefined) return this._rect;
-
- newRect = Rect.create(newRect);
- this._parentRect = newRect;
- var oldRect = this._rect;
- if (!this._resizeSelf(newRect)) return this;
- this._needsLayout = true;
-
- if (oldRect.width != newRect.width || oldRect.height != newRect.height) this._resizeChildViews(oldRect);
- this.trigger('resize', {oldRect: oldRect, newRect: this._rect, source: this});
- return this;
- };
-
- /** @private */
- this._resizeSelf = function(newRect) {
- // if (newRect.eq(this._rect)) return false;
- this._rect = this._normalizeRect(newRect);
- return true;
- };
-
- /**
- * Called to notify all interested parties: childViews and observers
- * @private
- */
- this._resizeChildViews = function(oldRect) {
- for (var i=0, childViews = this.childViews(); i < childViews.length; i++) {
- childViews[i].parentResized(oldRect, this._rect);
- };
- };
-
- /**#@-*/
-});
-/**
- * Basic container view
- *
- *
- * @author voloko
- * @name uki.view.Box
- * @class
- * @extends uki.view.Container
- */
-uki.view.declare('uki.view.Box', uki.view.Container, {});
-
-/**
- * Image
- *
- * @author voloko
- * @name uki.view.Image
- * @class
- * @extends uki.view.Base
- */
-uki.view.declare('uki.view.Image', uki.view.Base, function() {
- this.typeName = function() { return 'uki.view.Image'; };
-
- /**
- * @function
- * @name uki.view.Image#src
- */
- uki.delegateProp(this, 'src', '_dom');
-
- this._createDom = function() {
- this._dom = uki.createElement('img', this.defaultCss);
- this._initClassName();
- };
-});
-
-
-
-/**
- * Label View
- * Contains any html
- *
- * @author voloko
- * @name uki.view.Label
- * @class
- * @extends uki.view.Base
- */
-uki.view.declare('uki.view.Label', uki.view.Base, function(Base) {
-
- this._setup = function() {
- Base._setup.call(this);
- uki.extend(this, {
- _scrollable: false,
- _textSelectable: false,
- _inset: new Inset()
- });
- this.defaultCss += uki.theme.style('label');
- };
-
- this._style = function(name, value) {
- if (value !== undefined && uki.inArray(name, uki.browser.textStyles) != -1) {
- this._label.style[name] = value;
- }
- return Base._style.call(this, name, value);
- };
-
- this.adaptToContents = uki.newProp('_adaptToContents');
-
- this.textSelectable = function(state) {
- if (state !== undefined && !this._textSelectProp) {
- this._label.unselectable = state ? '' : 'on';
- }
- return Base.textSelectable.call(this, state);
- };
-
- /**
- * Warning! this operation is expensive
- */
- this.contentsSize = function(autosize) {
- var clone = this._createLabelClone(autosize), inset = this.inset(), size;
-
- uki.dom.probe(clone, function() {
- size = new Size(clone.offsetWidth + inset.width(), clone.offsetHeight + inset.height());
- });
- return size;
- };
-
- /**
- * Read/write escaped html contents
- * @function
- * @name uki.view.Label#text
- */
- this.text = function(text) {
- return text === undefined ? this.html() : this.html(uki.escapeHTML(text));
- };
-
- /**
- * Read/write html contents
- * @function
- * @name uki.view.Label#html
- */
- this.html = function(html) {
- if (html === undefined) return this._label.innerHTML;
- this._label.innerHTML = html;
- return this;
- };
-
- /**
- * Insets between text and view borders
- * @function
- * @name uki.view.Label#inset
- */
- this.inset = uki.newProp('_inset', function(inset) {
- this._inset = Inset.create(inset);
- });
-
- /**
- * Whether label have inline scrollbars on not
- * @function
- * @name uki.view.Label#scrollable
- */
- this.scrollable = uki.newProp('_scrollable', function(state) {
- this._scrollable = state;
- this._label.style.overflow = state ? 'auto' : 'hidden';
- });
-
- /**
- * Whether can have multiline lines or not
- * @function
- * @name uki.view.Label#multiline
- */
- this.multiline = uki.newProp('_multiline', function(state) {
- this._multiline = state;
- this._label.style.whiteSpace = state ? '' : 'nowrap';
- });
-
- this._createLabelClone = function(autosize) {
- var clone = this._label.cloneNode(true),
- inset = this.inset(), rect = this.rect();
-
- if (autosize & ANCHOR_WIDTH) {
- clone.style.width = clone.style.right = '';
- } else if (uki.supportNativeLayout) {
- clone.style.right = '';
- clone.style.width = rect.width - inset.width() + 'px';
- }
- if (autosize & ANCHOR_HEIGHT) {
- clone.style.height = clone.style.bottom = '';
- } else if (uki.supportNativeLayout) {
- clone.style.bottom = '';
- clone.style.height = rect.height - inset.height() + 'px';
- }
- clone.style.paddingTop = 0;
- clone.style.visibility = 'hidden';
- return clone;
- };
-
- this._createDom = function() {
- Base._createDom.call(this);
- this._label = uki.createElement('div', this.defaultCss + 'white-space:nowrap;'); // text-shadow:0 1px 0px rgba(255,255,255,0.8);
- this._dom.appendChild(this._label);
- this.textSelectable(this.textSelectable());
- };
-
- this._layoutDom = function() {
- var inset = this._inset,
- l,
- a = this._anchors,
- watchField = '', watchValue;
-
- if (uki.supportNativeLayout) {
- l = {
- left: inset.left,
- top: inset.top,
- right: inset.right,
- bottom: inset.bottom
- };
- } else {
- l = {
- left: inset.left,
- top: inset.top,
- width: this._rect.width - inset.width(),
- height: this._rect.height - inset.height()
- };
- }
-
- if (!(a & ANCHOR_BOTTOM)) {
- l.height = l.bottom = undefined;
- watchField = 'offsetHeight';
- } else if (!(a & ANCHOR_TOP)) {
- l.height = l.bottom = undefined;
- watchField = 'offsetHeight';
- } else if (!(a & ANCHOR_RIGHT)) {
- l.right = l.width = undefined;
- watchField = 'offsetWidth';
- } else if (!(a & ANCHOR_LEFT)) {
- l.left = l.width = undefined;
- watchField = 'offsetWidth';
- }
-
- Base._layoutDom.apply(this, arguments);
-
- if (!this.multiline()) {
- var fz = parseInt(this.style('fontSize'), 10) || 12;
- this._label.style.lineHeight = (this._rect.height - inset.top - inset.bottom) + 'px';
- // this._label.style.paddingTop = MAX(0, this._rect.height/2 - fz/2) + 'px';
- }
- this._lastLabelLayout = uki.dom.layout(this._label.style, l, this._lastLabelLayout);
-
- if (this.adaptToContents() && watchField) {
- watchValue = this._label[watchField];
- if (watchValue != this._lastWatchValue && this.parent()) {
- this.resizeToContents(watchField == 'offsetWidth' ? 'width' : 'height');
- this.parent().childResized(this);
- }
- this._lastWatchValue = watchValue;
- }
- };
-
-});
-
-
-/**
- * Button view
- *
- *
- * @author voloko
- * @name uki.view.Button
- * @class
- * @extends uki.view.Label
- * @implements uki.view.Focusable
- */
-uki.view.declare('uki.view.Button', uki.view.Label, uki.view.Focusable, function(Base, Focusable) {
- /** @lends uki.view.Button.prototype */
-
- this._backgroundPrefix = 'button-';
-
- this._setup = function() {
- Base._setup.call(this);
- uki.extend(this, {
- _inset: new Inset(0, 4)
- });
- this.defaultCss += "cursor:default;-moz-user-select:none;-webkit-user-select:none;" + uki.theme.style('button');
- };
-
- /**
- * @function
- * @name uki.view.Button#backgroundPrefix
- */
- uki.addProps(this, ['backgroundPrefix']);
-
- /**
- * @function
- * @name uki.view.Button#"normal-background"
- */
- /**
- * @function
- * @name uki.view.Button#"hover-background"
- */
- /**
- * @function
- * @name uki.view.Button#"down-background"
- */
- /**
- * @function
- * @name uki.view.Button#"focus-background"
- */
- /**
- * @function
- * @name uki.view.Button#"disabled-background"
- */
- uki.each(['normal', 'hover', 'down', 'focus', 'disabled'], function(i, name) {
- var property = name + '-background';
- this[property] = function(bg) {
- if (bg) this['_' + property] = bg;
- return this['_' + property] = this['_' + property] ||
- uki.theme.background(this._backgroundPrefix + name, {height: this.rect().height, view: this});
- };
- }, this);
-
- this._createLabelClone = function(autosize) {
- var clone = Base._createLabelClone.call(this, autosize);
- // clone.style.fontWeight = this.style('fontWeight');
- return clone;
- };
-
- this._layoutDom = function(rect) {
- Base._layoutDom.call(this, rect);
- if (this._firstLayout) {
- this['hover-background']();
- this['down-background']();
-
- this._backgroundByName(this._backgroundName || 'normal');
- }
- };
-
- this._updateBg = function() {
- var name = this._disabled ? 'disabled' : this._down ? 'down' : this._over ? 'hover' : 'normal';
- this._backgroundByName(name);
- };
-
- this._createDom = function() {
- // dom
- this._dom = uki.createElement('div', this.defaultCss);
- this._initClassName();
- this._label = uki.createElement('div', this.defaultCss); // text-shadow:0 1px 0px rgba(255,255,255,0.8);
- this._dom.appendChild(this._label);
-
- this._dom.appendChild(uki.createElement('div', 'left:0;top:0;width:100%;height:100%;position:absolute;background:url(' + uki.theme.imageSrc('x') + ');'));
-
- this.textSelectable(this.textSelectable());
- this._initFocusable();
-
- uki.dom.bind(document, 'mouseup', uki.proxy(this._mouseup, this));
- this.bind('mousedown', this._mousedown);
- this.bind('mouseenter', this._mouseenter);
- this.bind('mouseleave', this._mouseleave);
- this.bind('keyup', this._keyup);
- this.bind('keydown', this._keydown);
- };
-
- this._mouseup = function(e) {
- if (!this._down) return;
- this._down = false;
- this._updateBg();
- };
-
- this._mousedown = function(e) {
- this._down = true;
- this._updateBg();
- };
-
- this._mouseenter = function(e) {
- this._over = true;
- this._updateBg();
- };
-
- this._mouseleave = function(e) {
- this._over = false;
- this._updateBg();
- };
-
- this._focus = function(e) {
- this['focus-background']().attachTo(this);
- Focusable._focus.call(this, e);
- };
-
- this._keydown = function(e) {
- if ((e.which == 32 || e.which == 13) && !this._down) this._mousedown();
- };
-
- this._keyup = function(e) {
- if ((e.which == 32 || e.which == 13) && this._down) {
- this._mouseup();
- this.trigger('click', {domEvent: e, source: this});
- }
- if (e.which == 27 && this._down) {
- this._mouseup();
- }
- };
-
- this._blur = function(e) {
- this['focus-background']().detach();
- Focusable._blur.call(this, e);
- };
-
- this._backgroundByName = function(name) {
- var bg = this[name + '-background']();
- if (this._background == bg) return;
- if (this._background) this._background.detach();
- bg.attachTo(this);
- this._background = bg;
- this._backgroundName = name;
- };
-
- this._bindToDom = function(name) {
- return uki.view.Focusable._bindToDom.call(this, name) || uki.view.Label.prototype._bindToDom.call(this, name);
- };
-});
-/**
- * Checkbox
- *
- * @author voloko
- * @name uki.view.Checkbox
- * @class
- * @extends uki.view.Button
- */
-uki.view.declare('uki.view.Checkbox', uki.view.Button, function(Base) {
-
- this._backgroundPrefix = 'checkbox-';
-
- /**
- * @function
- * @name uki.view.Button#"checked-normal-background"
- */
- /**
- * @function
- * @name uki.view.Button#"checked-hover-background"
- */
- /**
- * @function
- * @name uki.view.Button#"checked-disabled-background"
- */
- uki.each(['checked-normal', 'checked-hover', 'checked-disabled'], function(i, name) {
- var property = name + '-background';
- this[property] = function(bg) {
- if (bg) this['_' + property] = bg;
- return this['_' + property] = this['_' + property] ||
- uki.theme.background(this._backgroundPrefix + name, {height: this.rect().height, view: this});
- };
- }, this);
-
- this._setup = function() {
- Base._setup.call(this);
- this._focusable = false;
- };
-
- this._updateBg = function() {
- var name = this._disabled ? 'disabled' : this._over ? 'hover' : 'normal';
- if (this._checked) name = 'checked-' + name;
- this._backgroundByName(name);
- };
-
- /**
- * @function
- * @name uki.view.Button#value
- */
- /**
- * @function
- * @name uki.view.Button#checked
- */
- this.value = this.checked = uki.newProp('_checked', function(state) {
- this._checked = !!state;
- this._updateBg();
- });
-
- this._mouseup = function(e) {
- if (!this._down) return;
- this._down = false;
- if (!this._disabled) {
- this.checked(!this.checked())
- this.trigger('change', {checked: this._checked, source: this});
- }
- };
-
-});
-
-
-
-(function() {
- /**
- * Radio button
- *
- * @author voloko
- * @name uki.view.Radio
- * @class
- * @extends uki.view.Checkbox
- */
- var manager = uki.view.declare('uki.view.Radio', uki.view.Checkbox, function(base) {
-
- this._backgroundPrefix = 'radio-';
-
- /**
- * @function
- * @param {String} group
- * @name uki.view.Popup#hide
- */
- this.group = uki.newProp('_group', function(g) {
- manager.unregisterGroup(this);
- this._group = g;
- manager.registerGroup(this);
- if (this.checked()) manager.clearGroup(this);
- });
-
- this.value = this.checked = uki.newProp('_checked', function(state) {
- this._checked = !!state;
- if (state) manager.clearGroup(this);
- this._updateBg();
- });
-
- this._mouseup = function() {
- if (!this._down) return;
- this._down = false;
- if (!this._checked && !this._disabled) {
- this.checked(!this._checked);
- this.trigger('change', { checked: this._checked, source: this });
- }
- }
- });
-
-
- manager.groups = {};
-
- manager.registerGroup = function(radio) {
- var group = radio.group();
- if (!manager.groups[group]) {
- manager.groups[group] = [radio];
- } else {
- manager.groups[group].push(radio);
- }
- };
-
- manager.unregisterGroup = function(radio) {
- var group = radio.group();
- if (manager.groups[group]) manager.groups[group] = uki.grep(manager.groups[group], function(registered) {
- return registered != radio;
- });
- };
-
- manager.clearGroup = function(radio) {
- uki.each(manager.groups[radio.group()] || [], function(i, registered) {
- if (registered == radio) return;
- if (registered.checked()) {
- registered.checked(false);
- this.trigger('change', { checked: false, source: registered });
- }
- });
- };
-
-})();
-/**
-* Editable Text Field
-*
-* @author voloko
-* @name uki.view.TextField
-* @class
-* @extends uki.view.Base
-* @implements uki.view.Focusable
-*/
-uki.view.declare('uki.view.TextField', uki.view.Base, uki.view.Focusable, function(Base, Focusable) {
- var emptyInputHeight = {};
-
- function getEmptyInputHeight (css) {
- if (!emptyInputHeight[css]) {
- var node = uki.createElement('input', Base.defaultCss + "border:none;padding:0;border:0;margin:0;overflow:hidden;left:-999em;top:0;line-height:1;" + css);
- uki.dom.probe(
- node,
- function(probe) {
- emptyInputHeight[css] = probe.offsetHeight;
- }
- );
- }
- return emptyInputHeight[css];
- }
-
- function nativePlaceholder (node) {
- return typeof node.placeholder == 'string';
- }
-
- this._backgroundPrefix = '';
- this._tagName = 'input';
- this._type = 'text';
-
- this._setup = function() {
- Base._setup.apply(this, arguments);
- uki.extend(this, {
- _value: '',
- _multiline: false,
- _placeholder: ''
- });
- this.defaultCss += "margin:0;border:none;outline:none;padding:0;left:2px;top:0;z-index:100;-moz-resize:none;resize:none;background: url(" + uki.theme.imageSrc('x') + ");" + uki.theme.style('input');
- };
-
- this._updateBg = function() {
- this._input.style.color = this._disabled ? '#999' : '#000';
- };
-
- /**
- * @function
- * @name uki.view.TextField#name
- */
- uki.delegateProp(this, 'name', '_input');
-
- /**
- * @function
- * @name uki.view.TextField#value
- */
- this.value = function(value) {
- if (value === undefined) return this._input.value;
-
- this._input.value = value;
- this._updatePlaceholderVis();
- return this;
- };
-
- /**
- * Cross browser placeholder implementation
- * @function
- * @name uki.view.TextField#placeholder
- */
- this.placeholder = uki.newProp('_placeholder', function(v) {
- this._placeholder = v;
- if (!this._multiline && nativePlaceholder(this._input)) {
- this._input.placeholder = v;
- } else {
- if (!this._placeholderDom) {
- this._placeholderDom = uki.createElement('div', this.defaultCss + 'z-input:103;color:#999;cursor:text;-moz-user-select:none;', v);
- if (!this._multiline) this._placeholderDom.style.whiteSpace = 'nowrap';
- this._dom.appendChild(this._placeholderDom);
- this._updatePlaceholderVis();
- uki.each(['fontSize', 'fontFamily', 'fontWeight'], function(i, name) {
- this._placeholderDom.style[name] = this._input.style[name];
- }, this);
-
- uki.dom.bind(this._placeholderDom, 'mousedown', uki.proxy(function(e) {
- this.focus();
- e.preventDefault();
- }, this));
- } else {
- this._placeholderDom.innerHTML = v;
- }
- }
- });
-
- this._style = function(name, value) {
- if (uki.inArray(name, uki.browser.textStyles) != -1) {
- if (value === undefined) return this._input.style[name];
- this._input.style[name] = value;
- if (this._placeholderDom) this._placeholderDom.style[name] = value;
- }
- return Base._style.call(this, name, value);
- };
-
- /**
- * @function
- * @name uki.view.TextField#backgroundPrefix
- */
- uki.addProps(this, ['backgroundPrefix']);
-
- /**
- * @function
- * @name uki.view.TextField#defaultBackground
- */
- this.defaultBackground = function() {
- return uki.theme.background(this._backgroundPrefix + 'input');
- };
-
- this._createDom = function() {
- this._dom = uki.createElement('div', Base.defaultCss + ';cursor:text;overflow:visible;');
- this._initClassName();
- this._input = uki.createElement(this._tagName, this.defaultCss + (this._multiline ? '' : ';overflow:hidden;'));
-
- this._input.value = this._value;
- if (this._type) this._input.type = this._type;
- this._dom.appendChild(this._input);
-
- this._input.value = this.value();
-
- this._initFocusable(this._input);
- this.bind('mousedown', function(e) {
- if (e.target == this._input) return;
- this.focus();
- });
- };
-
- this._layoutDom = function(rect) {
- Base._layoutDom.apply(this, arguments);
- uki.dom.layout(this._input.style, {
- width: this._rect.width - 4
- });
- var margin;
- if (this._multiline) {
- this._input.style.height = this._rect.height - 4 + PX;
- this._input.style.top = 2 + PX;
- margin = '2px 0';
- } else {
- var o = (this._rect.height - getEmptyInputHeight( 'font-size:' + this.style('fontSize') + ';font-family:' + this.style('fontFamily') )) / 2;
- margin = CEIL(o) + 'px 0 ' + FLOOR(o) + 'px 0';
- this._input.style.padding = margin;
- }
- if (this._placeholderDom) this._placeholderDom.style.padding = margin;
- };
-
- this._updatePlaceholderVis = function() {
- if (this._placeholderDom) this._placeholderDom.style.display = this.value() ? 'none' : 'block';
- };
-
- this._focus = function(e) {
- this._focusBackground = this._focusBackground || uki.theme.background(this._backgroundPrefix + 'input-focus');
- this._focusBackground.attachTo(this);
- if (this._placeholderDom) this._placeholderDom.style.display = 'none';
- Focusable._focus.call(this, e);
- };
-
- this._blur = function(e) {
- this._focusBackground.detach();
- this._updatePlaceholderVis();
- Focusable._blur.call(this, e);
- };
-
- this._bindToDom = function(name) {
- return Focusable._bindToDom.call(this, name) || Base._bindToDom.call(this, name);
- };
-});
-
-/**
-* Multiline Editable Text Field (textarea)
-*
-* @author voloko
-* @name uki.view.MultilineTextField
-* @class
-* @extends uki.view.TextField
-*/
-uki.view.declare('uki.view.MultilineTextField', uki.view.TextField, function(Base) {
- this._tagName = 'textarea';
- this._type = '';
-
- this._setup = function() {
- Base._setup.call(this);
- this._multiline = true;
- };
-});
-
-/**
-* Password Field
-*
-* @author voloko
-* @name uki.view.PasswordTextField
-* @class
-* @extends uki.view.TextField
-*/
-uki.view.declare('uki.view.PasswordTextField', uki.view.TextField, function(Base) {
- this._setup = function() {
- Base._setup.call(this);
- this._type = 'password';
- };
-});
-
-uki.Collection.addAttrs(['placeholder']);
-
-(function() {
- var scrollWidth, widthIncludesScrollBar;
-
- function initScrollWidth () {
- if (!scrollWidth) {
- uki.dom.probe(
- uki.createElement(
- 'div',
- 'position:absolute;left:-99em;width:100px;height:100px;overflow:scroll;',
- '<div style="position:absolute;left:0;width:100%;"></div>'
- ),
- function( probe ) {
- scrollWidth = probe.offsetWidth - probe.clientWidth;
- widthIncludesScrollBar = probe.firstChild.offsetWidth == 100;
- }
- );
- }
- return scrollWidth;
- }
-
- /**
- * Scroll pane.
- * Pane with scrollbars with content overflowing the borders.
- * Works consistently across all supported browsers.
- *
- * @author voloko
- * @name uki.view.ScrollPane
- * @class
- * @extends uki.view.Container
- */
- uki.view.declare('uki.view.ScrollPane', uki.view.Container, function(Base) {
- uki.extend(this, {
- _scrollableY: true,
- _scrollableX: false,
- _scrollY: false,
- _scrollX: false,
- _sbY: false,
- _sbX: false
- });
-
- this._setup = function() {
- Base._setup.call(this);
-
- this._clientRect = this.rect().clone();
- this._rectForChild = this.rect().clone();
- };
-
- /**
- * @function
- * @name uki.view.ScrollPane#scrollableY
- */
- /**
- * @function
- * @name uki.view.ScrollPane#scrollableX
- */
- /**
- * @function
- * @name uki.view.ScrollPane#scrollX
- */
- /**
- * @function
- * @name uki.view.ScrollPane#scrollY
- */
- uki.addProps(this, ['scrollableY', 'scrollableX', 'scrollX', 'scrollY']);
- this.scrollV = this.scrollY;
- this.scrollH = this.scrollX;
-
- this.scrollableV = this.scrollableY;
- this.scrollableH = this.scrollableX;
-
- this.rectForChild = function() { return this._rectForChild; };
- this.clientRect = function() { return this._clientRect; };
-
- /**
- * @function
- * @param {Number} dx
- * @param {Number} dy
- * @name uki.view.ScrollPane#scroll
- */
- this.scroll = function(dx, dy) {
- if (dx) this.scrollLeft(this.scrollLeft() + dx);
- if (dy) this.scrollTop(this.scrollTop() + dy);
- };
-
- /**
- * @function
- * @name uki.view.ScrollPane#scrollTop
- */
- /**
- * @function
- * @name uki.view.ScrollPane#scrollLeft
- */
- uki.each(['scrollTop', 'scrollLeft'], function(i, name) {
- this[name] = function(v) {
- if (v == undefined) return this._dom[name];
- this._dom[name] = v;
- this.trigger('scroll', { source: this });
- return this;
- };
- }, this);
-
- /**
- * @function
- * @return {uki.geometry.Rect}
- * @name uki.view.ScrollPane#visibleRect
- */
- this.visibleRect = function() {
- var tmpRect = this._clientRect.clone();
- tmpRect.x = this.rect().x + this.scrollLeft();
- tmpRect.y = this.rect().y + this.scrollTop();
- return tmpRect;
- };
-
- this.rect = function(newRect) {
- if (newRect === undefined) return this._rect;
-
- newRect = Rect.create(newRect);
- var oldRect = this._rect;
- this._parentRect = newRect;
- if (!this._resizeSelf(newRect)) return this;
- this._updateClientRects();
- this._needsLayout = true;
- this.trigger('resize', {oldRect: oldRect, newRect: this._rect, source: this});
- return this;
- };
-
- this._createDom = function() {
- Base._createDom.call(this);
- if (ua.indexOf('Gecko/') > -1) this._dom.tabIndex = '-1';
- };
-
- this._recalcClientRects = function() {
- initScrollWidth();
-
- var cw = this.contentsWidth(),
- ch = this.contentsHeight(),
- sx = this._scrollableX ? cw > this._rect.width : false,
- sy = this._scrollableY ? ch > this._rect.height : false;
-
- this._sbX = sx || this._scrollX;
- this._sbY = sy || this._scrollY;
- this._clientRect = new Rect( this._rect.width + (sy ? -1 : 0) * scrollWidth,
- this._rect.height + (sx ? -1 : 0) * scrollWidth );
- this._rectForChild = new Rect( this._rect.width + ((sy && !widthIncludesScrollBar) ? -1 : 0) * scrollWidth,
- this._rect.height + ((sx && !widthIncludesScrollBar) ? -1 : 0) * scrollWidth );
- };
-
- this._updateClientRects = function() {
- var oldClientRect = this._clientRect;
- this._recalcClientRects();
-
- if (oldClientRect.width != this._clientRect.width || oldClientRect.height != this._clientRect.height) {
- this._resizeChildViews(oldClientRect);
- }
- };
-
- this._resizeChildViews = function(oldClientRect) {
- for (var i=0, childViews = this.childViews(); i < childViews.length; i++) {
- childViews[i].parentResized(oldClientRect, this._clientRect);
- };
- };
-
- this._layoutChildViews = function() {
- for (var i=0, childViews = this.childViews(); i < childViews.length; i++) {
- if (childViews[i]._needsLayout && childViews[i].visible()) {
- childViews[i].layout();
- }
- };
- };
-
- this._layoutDom = function(rect) {
- this._updateClientRects();
-
- if (this._layoutScrollX !== this._sbX) {
- this._dom.style.overflowX = this._sbX ? 'scroll' : 'hidden';
- this._layoutScrollX = this._sbX;
- }
-
- if (this._layoutScrollY !== this._sbY) {
- this._dom.style.overflowY = this._sbY ? 'scroll' : 'hidden';
- this._layoutScrollY = this._sbY;
- }
-
- Base._layoutDom.call(this, rect);
- };
-
- this.childResized = function() {
- this._needsLayout = true;
- uki.after(uki.proxy(this.layoutIfNeeded, this));
- };
-
- this._contentChanged = this.childResized;
-
- });
-
- uki.view.ScrollPane.initScrollWidth = initScrollWidth;
-})();
-
-uki.Collection.addAttrs(['scrollTop', 'scrollLeft']);
-uki.fn.scroll = function(dx, dy) {
- this.each(function() {
- this.scroll(dx, dy);
- });
-};
-
-uki.view.list = {};
-/**
- * List View
- * Progressevly renders list data. Support selection and drag&drop.
- * Renders rows with plain html.
- *
- * @author voloko
- * @name uki.view.List
- * @class
- * @extends uki.view.Base
- * @implements uki.view.Focusable
- */
-uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Base, Focusable) {
-
- this._throttle = 42; // do not try to render more often than every 42ms
- this._visibleRectExt = 300; // extend visible rect by 300 px overflow
- this._defaultBackground = 'theme(list)';
-
- this._setup = function() {
- Base._setup.call(this);
- uki.extend(this, {
- _rowHeight: 30,
- _render: new uki.view.list.Render(),
- _data: [],
- _lastClickIndex: -1,
- _selectedIndexes: []
- });
- };
-
- /**
- * @function
- * @name uki.view.List#defaultBackground
- */
- this.defaultBackground = function() {
- return uki.theme.background('list', this._rowHeight);
- };
-
- /**
- * @type uki.view.list.Render
- * @function
- * @name uki.view.List#render
- */
- /**
- * @function
- * @name uki.view.List#packSize
- */
- /**
- * @function
- * @name uki.view.List#visibleRectExt
- */
- /**
- * @function
- * @name uki.view.List#throttle
- */
- /**
- * @function
- * @name uki.view.List#lastClickIndex
- */
- /**
- * @function
- * @name uki.view.List#multiselect
- */
- uki.addProps(this, ['render', 'packSize', 'visibleRectExt', 'throttle', 'lastClickIndex', 'multiselect']);
-
- /**
- * @function
- * @name uki.view.List#rowHeight
- */
- this.rowHeight = uki.newProp('_rowHeight', function(val) {
- this._rowHeight = val;
- this.minSize(new Size(this.minSize().width, this._rowHeight * this._data.length));
- if (this._background) this._background.detach();
- this._background = null;
- if (this.background()) this.background().attachTo(this);
- this._contentChanged();
- });
-
- /**
- * @example list.data(['row1', 'row2', ...])
- * @function
- * @name uki.view.List#data
- */
- this.data = function(d) {
- if (d === undefined) return this._data;
- this.clearSelection();
- this._data = d;
- this._packs[0].itemFrom = this._packs[0].itemTo = this._packs[1].itemFrom = this._packs[1].itemTo = 0;
-
- this.minSize(new Size(this.minSize().width, this._rowHeight * this._data.length));
- this.trigger('selection', {source: this});
- this._contentChanged();
- return this;
- };
-
- /**
- * Forces list content update
- * @function
- * @name uki.view.List#relayout
- */
- this.relayout = function() {
- this._packs[0].itemFrom = this._packs[0].itemTo = this._packs[1].itemFrom = this._packs[1].itemTo = 0;
- this.layout();
- };
-
- this.contentsSize = function() {
- return new Size(this.rect().width, this._rowHeight * this._data.length);
- };
-
- /**
- * used in search. should be fast
- * @function
- * @param {Number} position
- * @param {String} data
- * @name uki.view.List#addRow
- */
- this.addRow = function(position, data) {
- this._data.splice(position, 0, data);
- var item = this._itemAt(position);
- var container = doc.createElement('div');
-
- container.innerHTML = this._rowTemplate.render({
- height: this._rowHeight,
- text: this._render.render(this._data[position], this._rowRect(position), position)
- });
- if (item) {
- item.parentNode.insertBefore(container.firstChild, item);
- } else {
- this._dom.childNodes[0].appendChild(container.firstChild);
- }
-
- if (position <= this._packs[0].itemTo) {
- this._packs[0].itemTo++;
- this._packs[1].itemFrom++;
- this._packs[1].itemTo++;
- this._packs[1].dom.style.top = this._packs[1].itemFrom*this._rowHeight + 'px';
- } else {
- this._packs[1].itemTo++;
- }
-
- // offset selection
- var selectionPosition = uki.binarySearch(position, this.selectedIndexes());
- for (var i = selectionPosition; i < this._selectedIndexes.length; i++) {
- this._selectedIndexes[i]++;
- };
-
- // needed for scrollbar
- this.minSize(new Size(this.minSize().width, this._rowHeight * this._data.length));
- this._contentChanged();
-
- return this;
- };
-
- /**
- * @function
- * @param {Number} position
- * @name uki.view.List#removeRow
- */
- this.removeRow = function(position) {
- this._data.splice(position, 1);
- this.data(this._data);
- return this;
- };
-
- /**
- * Forces one particular row to be redrawn
- * @function
- * @param {Number} position
- * @name uki.view.List#removeRow
- */
- this.redrawRow = function(position) {
- var item = this._itemAt(position);
- if (item) item.innerHTML = this._render.render(this._data[position], this._rowRect(position), position);
- return this;
- };
-
- /**
- * Read/write current selected index for selectable lists
- * @function
- * @param {Number} position
- * @name uki.view.List#selectedIndex
- */
- this.selectedIndex = function(position) {
- if (position === undefined) return this._selectedIndexes.length ? this._selectedIndexes[0] : -1;
- this.selectedIndexes([position]);
- this._scrollToPosition(position);
- return this;
- };
-
- /**
- * Read/write all selected indexes for multiselectable lists
- * @function
- * @param {Array.<Number>} position
- * @name uki.view.List#selectedIndex
- */
- this.selectedIndexes = function(indexes) {
- if (indexes === undefined) return this._selectedIndexes;
- this.clearSelection(true);
- this._selectedIndexes = indexes;
- for (var i=0; i < this._selectedIndexes.length; i++) {
- this._setSelected(this._selectedIndexes[i], true);
- };
- this.trigger('selection', {source: this});
- return this;
- };
-
- /**
- * Read contents of selected row
- * @function
- * @name uki.view.List#selectedRow
- */
- this.selectedRow = function() {
- return this._data[this.selectedIndex()];
- };
-
- /**
- * Read contents of all selected rows
- * @function
- * @name uki.view.List#selectedRows
- */
- this.selectedRows = function() {
- return uki.map(this.selectedIndexes(), function(index) {
- return this._data[index];
- }, this)
- };
-
- /**
- * @function
- * @name uki.view.List#clearSelection
- */
- this.clearSelection = function(skipClickIndex) {
- for (var i=0; i < this._selectedIndexes.length; i++) {
- this._setSelected(this._selectedIndexes[i], false);
- };
- this._selectedIndexes = [];
- if (!skipClickIndex) this._lastClickIndex = -1;
- };
-
- /**
- * @function
- * @param {Number} index
- * @name uki.view.List#isSelected
- */
- this.isSelected = function(index) {
- var found = uki.binarySearch(index, this._selectedIndexes);
- return this._selectedIndexes[found] == index;
- };
-
- this.layout = function() {
- this._layoutDom(this._rect);
- this._needsLayout = false;
- // send visibleRect with layout
- this.trigger('layout', { rect: this._rect, source: this, visibleRect: this._visibleRect });
- this._firstLayout = false;
- };
-
- function range (from, to) {
- var result = new Array(to - from);
- for (var idx = 0; from <= to; from++, idx++) {
- result[idx] = from;
- };
- return result;
- }
-
- function removeRange (array, from, to) {
- var p = uki.binarySearch(from, array),
- initialP = p;
- while (array[p] <= to) p++;
- if (p > initialP) array.splice(initialP, p - initialP);
- }
-
- this._rowRect = function(p) {
- return new Rect(0, p*this._rowHeight, this.rect().width, this._rowHeight);
- };
-
- this._toggleSelection = function(p) {
- var indexes = [].concat(this._selectedIndexes);
- var addTo = uki.binarySearch(p, indexes);
- if (indexes[addTo] == p) {
- indexes.splice(addTo, 1);
- } else {
- indexes.splice(addTo, 0, p);
- }
- this.selectedIndexes(indexes);
- };
-
- var updatingScroll = false;
- this._scrollableParentScroll = function() {
- if (updatingScroll) return;
- if (this._throttle) {
- if (this._throttleStarted) return;
- this._throttleStarted = true;
- setTimeout(uki.proxy(function() {
- this._throttleStarted = false;
- this.layout();
- }, this), this._throttle);
- } else {
- this.layout();
- }
- };
-
- this._contentChanged = function() {
- this._needsLayout = true;
- uki.after(uki.proxy(this._relayoutParent, this));
- };
-
- this._relayoutParent = function() {
- this.parent().childResized(this);
- if (!this._scrollableParent) return;
- var c = this;
- while ( c && c != this._scrollableParent) {
- c._needsLayout = true;
- c = c.parent();
- }
- c.layout();
- };
-
-
- this.keyPressEvent = function() {
- var useKeyPress = root.opera || (/mozilla/i.test( ua ) && !(/(compatible|webkit)/i).test( ua ));
- return useKeyPress ? 'keypress' : 'keydown';
- };
-
- this._bindSelectionEvents = function() {
- this.bind('mousedown', this._mousedown);
- this.bind('mouseup', this._mouseup);
- this.bind(this.keyPressEvent(), this._keypress);
- };
-
- this._mouseup = function(e) {
- if (!this._multiselect) return;
-
- var o = uki.dom.offset(this._dom),
- y = e.pageY - o.y,
- p = y / this._rowHeight << 0;
-
- if (this._selectionInProcess && this._lastClickIndex == p && this.isSelected(p)) this.selectedIndexes([p]);
- this._selectionInProcess = false;
- };
-
- this._mousedown = function(e) {
- var o = uki.dom.offset(this._dom),
- y = e.pageY - o.y,
- p = y / this._rowHeight << 0,
- indexes = this._selectedIndexes;
-
- if (this._multiselect) {
- this._selectionInProcess = false;
- if (e.shiftKey && indexes.length > 0) {
- if (this.isSelected(p)) {
- indexes = [].concat(indexes);
- removeRange(indexes, Math.min(p+1, this._lastClickIndex), Math.max(p-1, this._lastClickIndex));
- this.selectedIndexes(indexes);
- } else {
- this.selectedIndexes(range(
- Math.min(p, indexes[0]),
- Math.max(p, indexes[indexes.length - 1])
- ));
- }
- } else if (e.metaKey) {
- this._toggleSelection(p);
- } else {
- if (!this.isSelected(p)) {
- this.selectedIndexes([p]);
- } else {
- this._selectionInProcess = true;
- }
- }
- } else {
- this.selectedIndexes([p]);
- }
- this._lastClickIndex = p;
- };
-
- this._keypress = function(e) {
- var indexes = this._selectedIndexes,
- nextIndex = -1;
- if (e.which == 38 || e.keyCode == 38) { // UP
- nextIndex = Math.max(0, this._lastClickIndex - 1);
- e.preventDefault();
- } else if (e.which == 40 || e.keyCode == 40) { // DOWN
- nextIndex = Math.min(this._data.length-1, this._lastClickIndex + 1);
- e.preventDefault();
- } else if (this._multiselect && (e.which == 97 || e.which == 65) && e.metaKey) {
- e.preventDefault();
- this.selectedIndexes(range(0, this._data.length -1));
- }
- if (nextIndex > -1 && nextIndex != this._lastClickIndex) {
- if (e.shiftKey && this._multiselect) {
- if (this.isSelected(nextIndex)) {
- this._toggleSelection(this._lastClickIndex);
- } else {
- this._toggleSelection(nextIndex);
- }
- this._scrollToPosition(nextIndex);
- } else {
- this.selectedIndex(nextIndex);
- }
- this._lastClickIndex = nextIndex;
- }
- };
-
- this._createDom = function() {
- this._dom = uki.createElement('div', this.defaultCss + 'overflow:hidden');
- this._initClassName();
-
- var packDom = uki.createElement('div', 'position:absolute;left:0;top:0px;width:100%;overflow:hidden');
- this._packs = [
- {
- dom: packDom,
- itemTo: 0,
- itemFrom: 0
- },
- {
- dom: packDom.cloneNode(false),
- itemTo: 0,
- itemFrom: 0
- }
- ];
- this._dom.appendChild(this._packs[0].dom);
- this._dom.appendChild(this._packs[1].dom);
-
- this._initFocusable();
- this._bindSelectionEvents();
- };
-
- this._setSelected = function(position, state) {
- var item = this._itemAt(position);
- if (item) this._render.setSelected(item, this._data[position], state, this.hasFocus());
- };
-
- this._scrollToPosition = function(position) {
- if (!this._visibleRect) return;
- var maxY, minY;
- maxY = (position+1)*this._rowHeight;
- minY = position*this._rowHeight;
- updatingScroll = true;
- if (maxY >= this._visibleRect.maxY()) {
- this._scrollableParent.scroll(0, maxY - this._visibleRect.maxY());
- } else if (minY < this._visibleRect.y) {
- this._scrollableParent.scroll(0, minY - this._visibleRect.y);
- }
- updatingScroll = false;
- this.layout();
- };
-
- this._itemAt = function(position) {
- if (position < this._packs[1].itemTo && position >= this._packs[1].itemFrom) {
- return this._packs[1].dom.childNodes[position - this._packs[1].itemFrom];
- } else if (position < this._packs[0].itemTo && position >= this._packs[0].itemFrom) {
- return this._packs[0].dom.childNodes[position - this._packs[0].itemFrom];
- }
- return null;
- };
-
- this._rowTemplate = new uki.theme.Template('<div style="width:100%;height:${height}px;overflow:hidden;">${text}</div>')
-
- this._renderPack = function(pack, itemFrom, itemTo) {
- var html = [], position;
- for (i=itemFrom; i < itemTo; i++) {
- html[html.length] = this._rowTemplate.render({
- height: this._rowHeight,
- text: this._render.render(this._data[i], this._rowRect(i), i)
- });
- };
- pack.dom.innerHTML = html.join('');
- pack.itemFrom = itemFrom;
- pack.itemTo = itemTo;
- pack.dom.style.top = itemFrom*this._rowHeight + 'px';
- this._restorePackSelection(pack, itemFrom, itemTo);
- };
-
- // xxxxx | xxxxx | xxxxxxxx | xxx
- // yyyyy | yyyyy | yyyy | yyyyyyy
- this._restorePackSelection = function(pack) {
- var indexes = this._selectedIndexes;
-
- if (
- (indexes[0] <= pack.itemFrom && indexes[indexes.length - 1] >= pack.itemFrom) || // left index
- (indexes[0] <= pack.itemTo && indexes[indexes.length - 1] >= pack.itemTo) || // right index
- (indexes[0] >= pack.itemFrom && indexes[indexes.length - 1] <= pack.itemTo) // within
- ) {
- var currentSelection = uki.binarySearch(pack.itemFrom, indexes);
- currentSelection = Math.max(currentSelection, 0);
- while(indexes[currentSelection] !== null && indexes[currentSelection] < pack.itemTo) {
- var position = indexes[currentSelection] - pack.itemFrom;
- this._render.setSelected(pack.dom.childNodes[position], this._data[position], true, this.hasFocus());
- currentSelection++;
- }
- }
- };
-
- this._swapPacks = function() {
- var tmp = this._packs[0];
- this._packs[0] = this._packs[1];
- this._packs[1] = tmp;
- };
-
- this._layoutDom = function(rect) {
- if (!this._scrollableParent) {
- this._scrollableParent = uki.view.scrollableParent(this);
- this._scrollableParent.bind('scroll', uki.proxy(this._scrollableParentScroll, this));
- }
-
- var totalHeight = this._rowHeight * this._data.length,
- scrollableParent = this._scrollableParent;
-
- this._visibleRect = uki.view.visibleRect(this, scrollableParent);
- if (this._focusTarget) this._focusTarget.style.top = this._visibleRect.y + 'px';
- var prefferedPackSize = CEIL((this._visibleRect.height + this._visibleRectExt*2) / this._rowHeight),
-
- minVisibleY = MAX(0, this._visibleRect.y - this._visibleRectExt),
- maxVisibleY = MIN(totalHeight, this._visibleRect.maxY() + this._visibleRectExt),
- minRenderedY = this._packs[0].itemFrom * this._rowHeight,
- maxRenderedY = this._packs[1].itemTo * this._rowHeight,
-
- itemFrom, itemTo, startAt, updated = true;
-
- Base._layoutDom.call(this, rect);
- if (
- maxVisibleY <= minRenderedY || minVisibleY >= maxRenderedY || // both packs below/above visible area
- (maxVisibleY > maxRenderedY && this._packs[1].itemFrom * this._rowHeight > this._visibleRect.y && this._packs[1].itemTo > this._packs[1].itemFrom) || // need to render below, and pack 2 is not enough to cover
- (minVisibleY < minRenderedY && this._packs[0].itemTo * this._rowHeight < this._visibleRect.maxY()) // need to render above, and pack 1 is not enough to cover the area
- // || prefferedPackSize is not enough to cover the area above/below, can this actually happen?
- ) {
- // this happens a) on first render b) on scroll jumps c) on container resize
- // render both packs, move them to be at the center of visible area
- // startAt = minVisibleY + (maxVisibleY - minVisibleY - prefferedPackSize*this._rowHeight*2) / 2;
- startAt = minVisibleY - this._visibleRectExt / 2;
- itemFrom = MAX(0, Math.round(startAt / this._rowHeight));
- itemTo = MIN(this._data.length, itemFrom + prefferedPackSize);
-
- this._renderPack(this._packs[0], itemFrom, itemTo);
- this._renderPack(this._packs[1], itemTo, itemTo);
- // this._renderPack(this._packs[1], itemTo, MIN(this._data.length, itemTo + prefferedPackSize));
- } else if (maxVisibleY > maxRenderedY && this._packs[1].itemTo > this._packs[1].itemFrom) { // we need to render below current area
- // this happens on normal scroll down
- // re-render bottom, swap
- itemFrom = this._packs[1].itemTo;
- itemTo = MIN(this._data.length, this._packs[1].itemTo + prefferedPackSize);
-
- this._renderPack(this._packs[0], itemFrom, itemTo);
- this._swapPacks();
- } else if (maxVisibleY > maxRenderedY) { // we need to render below current area
- itemFrom = this._packs[0].itemTo;
- itemTo = MIN(this._data.length, this._packs[1].itemTo + prefferedPackSize);
-
- this._renderPack(this._packs[1], itemFrom, itemTo);
- } else if (minVisibleY < minRenderedY) { // we need to render above current area
- // this happens on normal scroll up
- // re-render top, swap
- itemFrom = MAX(this._packs[0].itemFrom - prefferedPackSize, 0);
- itemTo = this._packs[0].itemFrom;
-
- this._renderPack(this._packs[1], itemFrom, itemTo);
- this._swapPacks();
- } else {
- updated = false;
- }
- if (updated && /MSIE 6|7/.test(ua)) this.dom().className += '';
- };
-
- this._bindToDom = function(name) {
- return Focusable._bindToDom.call(this, name) || Base._bindToDom.call(this, name);
- };
-
- this._focus = function(e) {
- Focusable._focus.call(this, e);
- if (this._selectedIndexes.length == 0 && this._data.length > 0) {
- this.selectedIndexes([0]);
- } else {
- this.selectedIndexes(this.selectedIndexes());
- }
- };
-
- this._blur = function(e) {
- Focusable._blur.call(this, e);
- this.selectedIndexes(this.selectedIndexes());
- };
-
-});
-
-/** @function
-@name uki.Collection#data */
-/** @function
-@name uki.Collection#selectedIndex */
-/** @function
-@name uki.Collection#selectedIndexes */
-/** @function
-@name uki.Collection#selectedRow */
-/** @function
-@name uki.Collection#selectedRows */
-/** @function
-@name uki.Collection#lastClickIndex */
-uki.Collection.addAttrs(['data', 'selectedIndex', 'selectedIndexes', 'selectedRow', 'selectedRows', 'lastClickIndex']);
-
-/**
- * Scrollable List View
- * Puts a list into a scroll pane
- *
- * @author voloko
- * @name uki.view.ScrollableList
- * @class
- * @extends uki.view.ScrollPane
- */
-uki.view.declare('uki.view.ScrollableList', uki.view.ScrollPane, function(Base) {
-
- this._createDom = function() {
- Base._createDom.call(this);
- this._list = uki({ view: 'List', rect: this.rect().clone().normalize(), anchors: 'left top right bottom' })[0];
- this.appendChild(this._list);
- };
-
- uki.each('data rowHeight render packSize visibleRectExt throttle focusable selectedIndex selectedIndexes selectedRow selectedRows multiselect draggable textSelectable'.split(' '),
- function(i, name) {
- uki.delegateProp(this, name, '_list');
- }, this);
-
-});
-
-
-/**
- * Flyweight view rendering
- * Used in lists, tables, grids
- * @class
- */
-uki.view.list.Render = uki.newClass({
- init: function() {},
-
- /**
- * Renders data to an html string
- * @param Object data Data to render
- * @return String html
- */
- render: function(data, rect, i) {
- return '<div style="line-height: ' + rect.height + 'px; font-size: 12px; padding: 0 4px;">' + data + '</div>';
- },
-
- setSelected: function(container, data, state, focus) {
- container.style.backgroundColor = state && focus ? '#3875D7' : state ? '#CCC' : '';
- container.style.color = state && focus ? '#FFF' : '#000';
- }
-});
-
-
-
-
-uki.view.table = {};
-
-/**
-* Table
-*
-* Uses uki.view.List to render data. Wraps it into scroll pane and ads a header
-* @author voloko
-* @name uki.view.Table
-* @class
-* @extends uki.view.Container
-*
-* @lends uki.view.List#rowHeight as rowHeight
-* @lends uki.view.List#data as data
-* @lends uki.view.List#packSize as packSize
-* @lends uki.view.List#visibleRectExt as visibleRectExt
-* @lends uki.view.List#render as render
-* @lends uki.view.List#selectedIndex as selectedIndex
-* @lends uki.view.List#selectedIndexes as selectedIndexes
-* @lends uki.view.List#selectedRow as selectedRow
-* @lends uki.view.List#selectedRows as selectedRows
-* @lends uki.view.List#lastClickIndex as lastClickIndex
-* @lends uki.view.List#textSelectable as textSelectable
-* @lends uki.view.List#multiselect as multiselect
-* @lends uki.view.List#redrawRow as redrawRow
-* @lends uki.view.List#addRow as addRow
-* @lends uki.view.List#removeRow as removeRow
-* @lends uki.view.List#focusable as lastClickIndex
-* @lends uki.view.List#focus as focus
-* @lends uki.view.List#blur as blur
-* @lends uki.view.List#hasFocus as hasFocus
-*
-*/
-uki.view.declare('uki.view.Table', uki.view.Container, function(Base) {
- var propertiesToDelegate = 'rowHeight data packSize visibleRectExt render selectedIndex selectedIndexes selectedRows selectedRow focus blur hasFocus lastClickIndex focusable textSelectable multiselect'.split(' ');
-
- this._rowHeight = 17;
- this._headerHeight = 17;
- this._listImpl = 'uki.view.List';
-
- uki.each(propertiesToDelegate, function(i, name) { uki.delegateProp(this, name, '_list'); }, this);
-
- this._setup = function() {
- Base._setup.call(this);
- this._columns = [];
- this.defaultCss += 'overflow:hidden;';
- };
-
- this._style = function(name, value) {
- this._header.style(name, value);
- return Base._style.call(this, name, value);
- };
-
- /**
- * @function
- * @return {uki.view.List}
- * @name uki.view.Table#list
- */
- this.list = function() {
- return this._list;
- };
-
- /**
- * @function
- * @return {uki.view.table.Header}
- * @name uki.view.Table#header
- */
- this.header = function() {
- return this._header;
- };
-
- /**
- * @function
- * @param {Array.<uki.view.table.Column>} c
- * @name uki.view.Table#columns
- */
- this.columns = uki.newProp('_columns', function(c) {
- for (var i = 0; i < this._columns.length; i++) {
- this._columns[i].unbind();
- }
- this._columns = uki.build(c);
- this._totalWidth = 0;
- for (i = 0; i < this._columns.length; i++) {
- this._columns[i].position(i);
- this._columns[i].bind('beforeResize', uki.proxy(function() {
- this._updateTotalWidth();
- this._scrollPane.layout();
- }, this));
- };
- this._updateTotalWidth();
- this._header.columns(this._columns);
- });
-
- /**
- * @function
- * @param {Number} row
- * @param {Number} col
- * @name uki.view.Table#redrawCell
- */
- this.redrawCell = function(row, col) {
- var item = this._list._itemAt(row);
- if (item) {
- var cell, container = doc.createElement('div');
- container.innerHTML = this.columns()[col].render(
- this.data()[row],
- new Rect(0, row*this.rowHeight(), this.list().width(), this.rowHeight()),
- row
- );
- cell = container.firstChild;
- item.replaceChild(cell, item.childNodes[col]);
- }
- return this;
- };
-
- uki.each(['redrawRow', 'addRow', 'removeRow'], function(i, name) {
- this[name] = function() {
- this.list()[name].apply(this.list(), arguments);
- return this;
- };
- }, this);
-
- /**
- * @function
- * @param {Number} col
- * @name uki.view.Table#redrawColumn
- */
- this.redrawColumn = function(col) {
- var from = this._list._packs[0].itemFrom,
- to = this._list._packs[1].itemTo;
- for (var i=from; i < to; i++) {
- this.redrawCell(i, col);
- };
- return this;
- };
-
- this._updateTotalWidth = function() {
- this._totalWidth = 0;
- for (var i=0; i < this._columns.length; i++) {
- this._columns[i].position(i);
- this._totalWidth += this._columns[i].width();
- };
- this._list.minSize(new Size(this._totalWidth, this._list.minSize().height));
- // this._list.rect(new Rect(this._totalWidth, this._list.height()));
- this._header.minSize(new Size(this._totalWidth, 0));
- };
-
- this._createDom = function() {
- Base._createDom.call(this);
- this._initClassName();
- var scrollPaneRect = new Rect(0, this._headerHeight, this.rect().width, this.rect().height - this._headerHeight),
- listRect = scrollPaneRect.clone().normalize(),
- headerRect = new Rect(0, 0, this.rect().width, this._headerHeight),
- listML = { view: this._listImpl, rect: listRect, anchors: 'left top bottom right', render: new uki.view.table.Render(this), className: 'table-list' },
- paneML = { view: 'ScrollPane', rect: scrollPaneRect, anchors: 'left top right bottom', scrollableH: true, childViews: [listML], className: 'table-scroll-pane'},
- headerML = { view: 'table.Header', rect: headerRect, anchors: 'top left right', className: 'table-header' };
-
- uki.each(propertiesToDelegate, function(i, name) {
- if (this['_' + name] !== undefined) listML[name] = this['_' + name];
- }, this);
- this._scrollPane = uki.build(paneML)[0];
- this._list = this._scrollPane.childViews()[0];
- this._header = uki.build(headerML)[0];
- this._scrollPane.resizeToContents();
- this.appendChild(this._header);
- this.appendChild(this._scrollPane);
-
- this._scrollPane.bind('scroll', uki.proxy(function() {
- // this is kinda wrong but faster than calling rect() + layout()
- this._header.dom().style.left = -this._scrollPane.scrollLeft() + 'px';
- }, this));
-
- };
-});
-
-uki.Collection.addAttrs(['columns']);
-
-
-/**
- * @class
- * @extends uki.view.list.Render
- */
-uki.view.table.Render = uki.newClass(uki.view.list.Render, new function() {
- this.init = function(table) {
- this._table = table;
- };
-
- this.render = function(row, rect, i) {
- var table = this._table,
- columns = table.columns();
- return uki.map(columns, function(val, j) {
- return columns[j].render(row, rect, i);
- }).join('');
- };
-});
-/**
- * @class
- * @extends uki.view.Observable
- */
-uki.view.table.Column = uki.newClass(uki.view.Observable, new function() {
- this._width = 100;
- this._offset = 0;
- this._position = 0;
- this._minWidth = 0;
- this._maxWidth = 0;
- this._css = 'float:left;white-space:nowrap;text-overflow:ellipsis;';
- this._inset = new Inset(3, 5);
- this._templatePrefix = 'table-';
-
- this.init = function() {};
-
- uki.addProps(this, ['position', 'css', 'formatter', 'label', 'resizable', 'maxWidth', 'minWidth', 'maxWidth', 'key', 'sort']);
-
- this.template = function() {
- // cache
- return this._template || (this._template = uki.theme.template(this._templatePrefix + 'cell'));
- };
-
- this.headerTemplate = function() {
- var suffix = '';
- if (this.sort() == 'ASC') suffix = '-asc';
- if (this.sort() == 'DESC') suffix = '-desc';
- return uki.theme.template(this._templatePrefix + 'header-cell' + suffix);
- };
-
- this.sortData = function(data) {
- var _this = this;
- return data.sort(function(a, b) {
- return _this._key ?
- _this.compare(uki.attr(a, _this._key), uki.attr(b, _this._key)) :
- _this.compare(a[_this._position], b[_this._position]);
- });
-
- };
-
- this.compare = function(a, b) {
- return (a >= b ? 1 : a == b ? 0 : -1) * (this._sort == 'DESC' ? -1 : 1);
- };
-
- /**
- * @fires event:beforeResize
- * @fires event:resize
- */
- this.width = uki.newProp('_width', function(w) {
- var e = {
- oldWidth: this._width,
- source: this
- };
- this._width = this._normailizeWidth(w);
- e.newWidth = this._width;
- this.trigger('beforeResize', e);
- if (this._stylesheet && e.newWidth != e.oldWidth) {
- var rules = this._stylesheet.styleSheet ? this._stylesheet.styleSheet.rules : this._stylesheet.sheet.cssRules;
- rules[0].style.width = this._clientWidth() + PX;
- }
- this.trigger('resize', e);
- });
-
- this._bindToDom = uki.F;
-
- this._normailizeWidth = function(w) {
- if (this._maxWidth) w = MIN(this._maxWidth, w);
- if (this._minWidth) w = MAX(this._minWidth, w);
- return w;
- };
-
- this.inset = uki.newProp('_inset', function(i) {
- this._inset = Inset.create(i);
- });
-
- this.render = function(row, rect, i) {
- this._prerenderedTemplate || this._prerenderTemplate(rect);
- var value = this._key ? uki.attr(row, this._key) : row[this._position];
- this._prerenderedTemplate[1] = this._formatter ? this._formatter(value, row, i) : value;
- return this._prerenderedTemplate.join('');
- };
-
- this.appendResizer = function(dom, height) {
- var resizer = uki.theme.dom('resizer', height);
- dom.appendChild(resizer);
- return resizer;
- };
-
- this.renderHeader = function(height) {
- this._className || this._initStylesheet();
- var x = this.headerTemplate().render({
- data: '<div style="overflow:hidden;text-overflow:ellipsis;*width:100%;height:100%;padding-top:' + this._inset.top + 'px">' + this.label() + '</div>',
- style: '*overflow-y:hidden;' + this._cellStyle(true, height),
- className: this._className
- });
- return x;
- };
-
- this._prerenderTemplate = function(rect) {
- this._className || this._initStylesheet();
- this._prerenderedTemplate = this.template().render({
- data: '\u0001\u0001',
- style: 'overflow:hidden;' + this._cellStyle(false, rect.height),
- className: this._className
- }).split('\u0001');
- };
-
- this._cellPadding = function(skipVertical) {
- var inset = this._inset;
- return ['padding:', (skipVertical ? '0' : inset.top), 'px ', inset.right, 'px ', (skipVertical ? '0' : inset.bottom), 'px ', inset.left, 'px;'].join('');
- };
-
- this._cellHeight = function(skipVertical, height) {
- return 'height:' + (height - (uki.dom.offset.boxModel && !skipVertical ? this._inset.height() : 0)) + 'px;';
- };
-
- this._cellStyle = function(skipVertical, height) {
- return this._css + this._cellPadding(skipVertical) + ';' + this._cellHeight(skipVertical, height);
- };
-
- this._clientWidth = function() {
- return this._width - (uki.dom.offset.boxModel ? this._inset.width() + 1 : 0);
- };
-
- this._initStylesheet = function() {
- if (!this._className) {
- uki.dom.offset.initializeBoxModel();
- this._className = 'uki-table-column-' + (uki.guid++);
- var css = '.' + this._className + ' {width:' + this._clientWidth() + 'px;}';
- this._stylesheet = uki.dom.createStylesheet(css);
- }
- };
-});
-
-uki.view.table.NumberColumn = uki.newClass(uki.view.table.Column, new function() {
- var Base = uki.view.table.Column.prototype;
-
- this._css = Base._css + 'text-align:right;';
-
- this.compare = function(a, b) {
- a*=1;
- b*=1;
- return (a >= b ? 1 : a == b ? 0 : -1) * (this._sort == 'DESC' ? -1 : 1);
- };
-});
-
-uki.view.table.CustomColumn = uki.view.table.Column;
-
-
-/**
- * @class
- * @extends uki.view.Label
- */
-uki.view.declare('uki.view.table.Header', uki.view.Label, function(Base) {
- this._defaultBackground = 'theme(table-header)';
-
- this._setup = function() {
- Base._setup.call(this);
- this._multiline = true;
- this._resizers = [];
- };
-
- this.columns = uki.newProp('_columns', function(v) {
- this._columns = v;
- this.html(this._createColumns());
- this._createResizers();
- });
-
- this._createDom = function() {
- Base._createDom.call(this);
- this.bind('click', this._click);
- };
-
- this._click = function(e) {
- if (this._dragging) return;
-
- var target = e.target;
- if (target == this.dom() || target == this._label) return;
- while (target.parentNode != this._label) target = target.parentNode;
- var i = uki.inArray(target, this._label.childNodes);
- if (i > -1) {
- this.trigger('columnClick', { source: this, columnIndex: i, column: this._columns[i] });
- }
- };
-
- this.redrawColumn = function(col) {
- if (this._resizers[col]) uki.dom.unbind(this._resizers[col]);
- var container = doc.createElement('div');
- container.innerHTML = this._columns[col].renderHeader(this.rect().height);
- this._label.replaceChild(container.firstChild, this._label.childNodes[col]);
- if (this._columns[col].resizable()) this._createResizers(col);
- };
-
- this._createColumns = function() {
- var html = [];
- for(var i = 0, offset = 0, columns = this._columns, l = columns.length; i < l; i++) {
- html[html.length] = columns[i].renderHeader(this.rect().height);
- }
- return html.join('');
- };
-
- this._createResizer = function(i) {
- var column = this._columns[i];
- if (column.resizable()) {
- var resizer = column.appendResizer(this._label.childNodes[i], this.rect().height);
- this._bindResizerDrag(resizer, i);
- this._resizers[i] = resizer;
- }
- };
-
- this._createResizers = function() {
- uki.each(this._columns, this._createResizer, this);
- };
-
- this._bindResizerDrag = function(resizer, columnIndex) {
- var _this = this;
-
- uki.dom.bind(resizer, 'draggesture', function(e) {
- _this._dragging = true;
- var headerOffset = uki.dom.offset(_this.dom()),
- offsetWithinHeader = e.pageX - headerOffset.x,
- columnOffset = 0, i, column = _this._columns[columnIndex];
- for (i=0; i < columnIndex; i++) {
- columnOffset += _this._columns[i].width();
- };
- column.width(offsetWithinHeader - columnOffset);
- });
-
- uki.dom.bind(resizer, 'draggestureend', function() {
- setTimeout(function() {
- _this._dragging = false;
- }, 1);
- });
- };
-});
-
-/**
-* Horizontal Slider.
-*
-* @author voloko
-* @name uki.view.Slider
-* @class
-* @extends uki.view.Base
-* @implements uki.view.Focusable
-*/
-uki.view.declare('uki.view.Slider', uki.view.Container, uki.view.Focusable, function(Base, Focusable) {
-
- this._handleSize = new Size(10,18);
-
- this._setup = function() {
- Base._setup.call(this);
- uki.extend(this, {
- _min: 0,
- _max: 1,
- _value: 0,
- _values: null,
- _keyStep: 0.01
- });
- };
-
- /**
- * @function
- * @name uki.view.Slider#min
- */
- /**
- * @function
- * @name uki.view.Slider#max
- */
- /**
- * @function
- * @name uki.view.Slider#values
- */
- /**
- * @function
- * @name uki.view.Slider#keyStep
- */
- uki.addProps(this, ['min', 'max', 'values', 'keyStep']);
-
- this.values = uki.newProp('_values', function(val) {
- this._values = val;
- this._min = val[0];
- this._max = val[val.length - 1];
- });
-
- /**
- * @function
- * @fires event:change
- * @name uki.view.Slider#value
- */
- this.value = uki.newProp('_value', function(val) {
- this._value = MAX(this._min, MIN(this._max, val));
- this._position = this._val2pos(this._value);
- this._moveHandle();
- });
-
- this._pos2val = function(pos, cacheIndex) {
- if (this._values) {
- var index = Math.round(1.0 * pos / (this._rect.width - this._handleSize.width) * (this._values.length - 1));
- if (cacheIndex) this._cachedIndex = index;
- return this._values[index];
- }
- return pos / (this._rect.width - this._handleSize.width) * (this._max - this._min) + this._min;
- };
-
- this._val2pos = function(val) {
- if (this._values) {
- var index = this._cachedIndex !== undefined ? this._cachedIndex : uki.binarySearch(val, this._values);
- return index / (this._values.length - 1) * (this._rect.width - this._handleSize.width);
- }
- return (val - this._min) / (this._max - this._min) * (this._rect.width - this._handleSize.width);
- };
-
- this._createDom = function() {
- this._dom = uki.createElement('div', this.defaultCss + 'height:18px;-moz-user-select:none;-webkit-user-select:none;overflow:visible;');
- this._initClassName();
- this._handle = uki({
- view: 'SliderHandle',
- rect: new Rect(0, (this._rect.height-this._handleSize.height)/2, this._handleSize.width, this._handleSize.height),
- anchors: 'left top'
- })[0];
- this.appendChild(this._handle);
-
- uki.theme.background('slider-bar').attachTo(this);
- uki.each(['draggesturestart', 'draggesture', 'draggestureend'], function(i, name) {
- this._handle.bind(name, uki.proxy(this['_' + name], this));
- }, this);
-
- this.bind(uki.view.List.prototype.keyPressEvent(), this._keypress);
- this.bind('click', this._click);
-
- this._initFocusable();
- };
-
- this._focus = function(e) {
- this._handle._focus();
- Focusable._focus.call(this, e);
- };
-
- this._blur = function(e) {
- this._handle._blur();
- Focusable._blur.call(this, e);
- };
-
- this._click = function(e) {
- var x = e.pageX - uki.dom.offset(this._dom).x - this._handleSize.width/2;
- this.value(this._pos2val(x, true));
- this._cachedIndex = undefined;
- this.trigger('change', {source: this, value: this._value});
- };
-
- this._keypress = function(e) {
- if (e.which == 39 || e.keyCode == 39) {
- this.value(this.value() + this._keyStep * (this._max - this._min));
- } else if (e.which == 37 || e.keyCode == 37) {
- this.value(this.value() - this._keyStep * (this._max - this._min));
- }
- };
-
- this._moveHandle = function() {
- var rect = this._handle.rect().clone();
- rect.x = this._position;
- rect.y = (this._rect.height - this._handleSize.height) / 2;
- this._handle.rect(rect).layout();
- };
-
- this._draggesturestart = function(e) {
- this._dragging = true;
- this._initialPosition = this._handle.rect().clone();
- return true;
- };
-
- /**
- * @fires event:change
- */
- this._draggesture = function(e) {
- var position = MAX(0, MIN(this._rect.width - this._handleSize.width, this._initialPosition.x + e.dragOffset.x));
- this.value(this._pos2val(position, true));
- this._cachedIndex = undefined;
- };
-
- this._draggestureend = function(e) {
- this._dragging = false;
- this._initialPosition = null;
- this.value(this._pos2val(this._position, true));
- this._cachedIndex = undefined;
- this.trigger('change', {source: this, value: this._value});
- };
-
- this._layoutDom = function(rect) {
- Base._layoutDom.call(this, rect);
- this._position = this._val2pos(this._value);
- this._moveHandle();
- return true;
- };
-
- this._bindToDom = function(name) {
- if (name == 'change') return true;
- return uki.view.Focusable._bindToDom.call(this, name) || Base._bindToDom.call(this, name);
- };
-
-});
-
-uki.view.declare('uki.view.SliderHandle', uki.view.Button, { _backgroundPrefix: 'slider-handle-', _focusable: false });
-
-/**
-* Horizontal Split Pane
-*
-* @author voloko
-* @name uki.view.HSplitPane
-* @class
-* @extends uki.view.Container
-*/
-uki.view.declare('uki.view.HSplitPane', uki.view.Container, function(Base) {
- this._throttle = 0; // do not try to render more often than every Xms
-
- this._setup = function() {
- Base._setup.call(this);
- this._originalRect = this._rect;
- uki.extend(this, {
- _vertical: false,
- _handlePosition: 200,
- _autogrowLeft: false,
- _autogrowRight: true,
- _handleWidth: 7,
- _leftMin: 100,
- _rightMin: 100,
-
- _panes: []
- });
- };
-
- /**
- * @function
- * @name uki.view.HSplitPane#leftMin
- */
- /**
- * @function
- * @name uki.view.HSplitPane#rightMin
- */
- /**
- * @function
- * @name uki.view.HSplitPane#autogrowLeft
- */
- /**
- * @function
- * @name uki.view.HSplitPane#autogrowRight
- */
- /**
- * @function
- * @name uki.view.HSplitPane#throttle
- */
- uki.addProps(this, ['leftMin', 'rightMin', 'autogrowLeft', 'autogrowRight', 'throttle']);
- this.topMin = this.leftMin;
- this.bottomMin = this.rightMin;
-
- /**
- * @function
- * @fires event:handleMove
- * @name uki.view.HSplitPane#handlePosition
- */
- this.handlePosition = uki.newProp('_handlePosition', function(val) {
- this._handlePosition = this._normalizePosition(val);
- this.trigger('handleMove', {source: this, handlePosition: this._handlePosition, dragValue: val });
- this._resizeChildViews();
- });
-
- /**
- * @function
- * @name uki.view.HSplitPane#handleWidth
- */
- this.handleWidth = uki.newProp('_handleWidth', function(val) {
- if (this._handleWidth != val) {
- this._handleWidth = val;
- var handle = this._createHandle();
- this._dom.insertBefore(handle, this._handle);
- this._removeHandle();
- this._handle = handle;
- this._resizeChildViews();
- }
- });
-
-
- this._normalizePosition = function(val) {
- var prop = this._vertical ? 'height' : 'width';
- return MAX(
- this._leftMin,
- MIN(
- this._rect[prop] - this._rightMin - this._handleWidth,
- MAX(0, MIN(this._rect ? this._rect[prop] : 1000, val * 1))
- ));
- };
-
-
- this._removeHandle = function() {
- this._dom.removeChild(this._handle);
- };
-
- this._createHandle = function() {
- var handle;
- if (this._vertical) {
- handle = uki.theme.dom('splitPane-vertical', {handleWidth: this._handleWidth});
- handle.style.top = this._handlePosition + PX;
- } else {
- handle = uki.theme.dom('splitPane-horizontal', {handleWidth: this._handleWidth});
- handle.style.left = this._handlePosition + PX;
- }
-
- uki.each(['draggesturestart', 'draggesture', 'draggestureend'], function(i, name) {
- uki.dom.bind(handle, name, uki.proxy(this['_' + name], this));
- }, this);
-
- return handle;
- };
-
- this._createDom = function() {
- this._dom = uki.createElement('div', this.defaultCss);
- this._initClassName();
- for (var i=0, paneML; i < 2; i++) {
- paneML = { view: 'Container' };
- paneML.anchors = i == 1 ? 'left top bottom right' :
- this._vertical ? 'left top right' :
- 'left top bottom';
- paneML.rect = i == 0 ? this._leftRect() : this._rightRect();
- this._panes[i] = uki.build(paneML)[0];
- this.appendChild(this._panes[i]);
- };
- this._dom.appendChild(this._handle = this._createHandle());
- };
-
- this._normalizeRect = function(rect) {
- rect = Base._normalizeRect.call(this, rect);
- var newRect = rect.clone();
- if (this._vertical) {
- newRect.height = MAX(newRect.height, this._leftMin + this._rightMin); // force min width
- } else {
- newRect.width = MAX(newRect.width, this._leftMin + this._rightMin); // force min width
- }
- return newRect;
- };
-
- this._resizeSelf = function(newRect) {
- var oldRect = this._rect,
- dx, prop = this._vertical ? 'height' : 'width';
- if (!Base._resizeSelf.call(this, newRect)) return false;
- if (this._autogrowLeft) {
- dx = newRect[prop] - oldRect[prop];
- this._handlePosition = this._normalizePosition(this._handlePosition + (this._autogrowRight ? dx / 2 : dx));
- }
- if (this._vertical) {
- if (newRect.height - this._handlePosition < this._rightMin) {
- this._handlePosition = MAX(this._leftMin, newRect.height - this._rightMin);
- }
- } else {
- if (newRect.width - this._handlePosition < this._rightMin) {
- this._handlePosition = MAX(this._leftMin, newRect.width - this._rightMin);
- }
- }
- return true;
- };
-
- this._draggesturestart = function(e) {
- var offset = uki.dom.offset(this.dom());
- this._posWithinHandle = (e[this._vertical ? 'pageY' : 'pageX'] - offset[this._vertical ? 'y' : 'x']) - this._handlePosition;
- return true;
- };
-
- this._draggesture = function(e) {
- this._updatePositionOnDrag(e);
- };
-
- this._draggestureend = function(e, offset) {
- this._updatePositionOnDrag(e);
- };
-
- this._updatePositionOnDrag = function(e) {
- var offset = uki.dom.offset(this.dom());
- this.handlePosition(e[this._vertical ? 'pageY' : 'pageX'] - offset[this._vertical ? 'y' : 'x'] - this._posWithinHandle);
- if (this._throttle) {
- this._throttleHandler = this._throttleHandler || uki.proxy(function() {
- this.layout();
- this._trottling = false;
- }, this);
- if (this._trottling) return;
- this._trottling = true;
- setTimeout(this._throttleHandler, this._throttle);
- } else {
- this.layout();
- }
- };
-
-
- /**
- * @function
- * @name uki.view.HSplitPane#topPane
- */
- /**
- * @function
- * @name uki.view.HSplitPane#leftPane
- */
- this.topPane = this.leftPane = function(pane) {
- return this._paneAt(0, pane);
- };
-
- /**
- * @function
- * @name uki.view.HSplitPane#bottomPane
- */
- /**
- * @function
- * @name uki.view.HSplitPane#rightPane
- */
- this.bottomPane = this.rightPane = function(pane) {
- return this._paneAt(1, pane);
- };
-
- /**
- * @function
- * @name uki.view.HSplitPane#topChildViews
- */
- /**
- * @function
- * @name uki.view.HSplitPane#leftChildViews
- */
- this.topChildViews = this.leftChildViews = function(views) {
- return this._childViewsAt(0, views);
- };
-
- /**
- * @function
- * @name uki.view.HSplitPane#rightChildViews
- */
- /**
- * @function
- * @name uki.view.HSplitPane#bottomChildViews
- */
- this.bottomChildViews = this.rightChildViews = function(views) {
- return this._childViewsAt(1, views);
- };
-
- this._childViewsAt = function(i, views) {
- if (views === undefined) return this._panes[i].childViews();
- this._panes[i].childViews(views);
- return this;
- };
-
- this._paneAt = function(i, pane) {
- if (pane === undefined) return this._panes[i];
- uki.build.copyAttrs(this._panes[i], pane);
- return this;
- };
-
- this._leftRect = function() {
- if (this._vertical) {
- return new Rect(this._rect.width, this._handlePosition);
- } else {
- return new Rect(this._handlePosition, this._rect.height);
- }
- };
-
- this._rightRect = function() {
- if (this._vertical) {
- return new Rect(
- 0, this._handlePosition + this._handleWidth,
- this._rect.width, this._rect.height - this._handleWidth - this._handlePosition
- );
- } else {
- return new Rect(
- this._handlePosition + this._handleWidth, 0,
- this._rect.width - this._handleWidth - this._handlePosition, this._rect.height
- );
- }
- };
-
- this._resizeChildViews = function() {
- this._panes[0].rect(this._leftRect());
- this._panes[1].rect(this._rightRect());
- };
-
- this._layoutDom = function(rect) {
- Base._layoutDom.call(this, rect);
- this._handle.style[this._vertical ? 'top' : 'left'] = this._handlePosition + 'px';
- };
-
- this._bindToDom = function(name) {
- if (name == 'handleMove') return true;
- return Base._bindToDom.call(this, name);
- };
-
-});
-
-/**
-* Vertical Split Pane
-*
-* @author voloko
-* @name uki.view.VSplitPane
-* @class
-* @extends uki.view.HSplitPane
-*/
-uki.view.declare('uki.view.VSplitPane', uki.view.HSplitPane, function(Base) {
- this._setup = function() {
- Base._setup.call(this);
- this._vertical = true;
- };
-});
-
-
-uki.Collection.addAttrs(['handlePosition']);
-
-
-/**
- * Popup
- *
- * @author voloko
- * @name uki.view.Popup
- * @class
- * @extends uki.view.Container
- */
-uki.view.declare('uki.view.Popup', uki.view.Container, function(Base) {
-
- this._setup = function() {
- Base._setup.call(this);
- uki.extend(this, {
- _offset: 2,
- _relativeTo: null,
- _horizontal: false,
- _flipOnResize: true,
- _defaultBackground: 'theme(popup-normal)'
- });
- };
-
- this._createDom = function() {
- Base._createDom.call(this);
- this.hideOnClick(true);
- };
-
- /**
- * @function
- * @name uki.view.Popup#offset
- */
- /**
- * @function
- * @name uki.view.Popup#relativeTo
- */
- /**
- * @function
- * @name uki.view.Popup#horizontal
- */
- /**
- * @function
- * @name uki.view.Popup#flipOnResize
- */
- uki.addProps(this, ['offset', 'relativeTo', 'horizontal', 'flipOnResize']);
-
- /**
- * @function
- * @name uki.view.Popup#hideOnClick
- */
- this.hideOnClick = function(state) {
- if (state === undefined) return this._clickHandler;
- if (state != !!this._clickHandler) {
- if (state) {
- this._clickHandler = this._clickHandler || uki.proxy(function(e) {
- if (uki.dom.contains(this._relativeTo.dom(), e.target)) return;
- if (uki.dom.contains(this.dom(), e.target)) return;
- this.hide();
- }, this);
- uki.dom.bind(doc.body, 'mousedown', this._clickHandler);
- uki.dom.bind(root, 'resize', this._clickHandler);
- } else {
- uki.dom.unbind(doc.body, 'mousedown', this._clickHandler);
- uki.dom.unbind(root, 'resize', this._clickHandler);
- this._clickHandler = false;
- }
- }
- return this;
- };
-
- /**
- * @function
- * @name uki.view.Popup#toggle
- */
- this.toggle = function() {
- if (this.parent() && this.visible()) {
- this.hide();
- } else {
- this.show();
- }
- };
-
- /**
- * @function
- * @name uki.view.Popup#show
- */
- this.show = function() {
- this.visible(true);
- if (!this.parent()) {
- new uki.Attachment( root, this );
- } else {
- this.rect(this._recalculateRect());
- this.layout(this._rect);
- }
- this.trigger('toggle', { source: this });
- };
-
- /**
- * @function
- * @name uki.view.Popup#hide
- */
- this.hide = function() {
- this.visible(false);
- this.trigger('toggle', { source: this });
- };
-
- this.parentResized = function() {
- this.rect(this._recalculateRect());
- };
-
- this._resizeSelf = function(newRect) {
- this._rect = this._normalizeRect(newRect);
- return true;
- };
-
- this._layoutDom = function(rect) {
- return Base._layoutDom.call(this, rect);
- };
-
- this._recalculateRect = function() {
- if (!this.visible()) return this._rect;
- var relativeOffset = uki.dom.offset(this._relativeTo.dom()),
- relativeRect = this._relativeTo.rect(),
- rect = this.rect().clone(),
- attachment = uki.view.top(this),
- attachmentRect = attachment.rect(),
- attachmentOffset = uki.dom.offset(attachment.dom()),
- position = new Point(),
- hOffset = this._horizontal ? this._offset : 0,
- vOffset = this._horizontal ? 0 : this._offset;
-
- relativeOffset.offset(-attachmentOffset.x, -attachmentOffset.y);
-
- if (this._anchors & ANCHOR_RIGHT) {
- position.x = relativeOffset.x + relativeRect.width - (this._horizontal ? 0 : rect.width) + hOffset;
- } else if (this._anchors & ANCHOR_LEFT) {
- position.x = relativeOffset.x - (this._horizontal ? rect.width : 0) - hOffset;
- } else {
- position.x = relativeOffset.x + ((relativeRect.width - rect.width) >> 1) - hOffset;
- }
-
- if (this._anchors & ANCHOR_BOTTOM) {
- position.y = relativeOffset.y + (this._horizontal ? relativeRect.height : 0) - rect.height - vOffset;
- } else if (this._anchors & ANCHOR_TOP) {
- position.y = relativeOffset.y + (this._horizontal ? 0 : relativeRect.height) + vOffset;
- } else {
- position.y = relativeOffset.y + ((relativeRect.height - rect.height) >> 1) + vOffset;
- }
-
- return new Rect(position.x, position.y, rect.width, rect.height);
- };
-});
-
-
-uki.each(['show', 'hide', 'toggle'], function(i, name) {
- uki.fn[name] = function() {
- this.each(function() { this[name](); });
- };
-});
-/**
- * Vertical Flow
- * Arranges child views verticaly, one after another
- *
- * @author voloko
- * @name uki.view.VFlow
- * @class
- * @extends uki.view.Container
- */
-uki.view.declare('uki.view.VFlow', uki.view.Container, function(Base) {
- this.contentsSize = function() {
- var value = uki.reduce(0, this._childViews, function(sum, e) {
- return sum + (e.visible() ? e.rect().height : 0);
- } );
- return new Size( this.contentsWidth(), value );
- };
-
- this.hidePartlyVisible = uki.newProp('_hidePartlyVisible');
-
- this.resizeToContents = function(autosizeStr) {
- this._resizeChildViews(this._rect);
- return Base.resizeToContents.call(this, autosizeStr);
- }
-
- this.layout = function() {
- return Base.layout.call(this);
- };
-
- // resize in layout
- this._resizeChildViews = function(oldRect) {
- var offset = 0, rect, view;
- for (var i=0, childViews = this.childViews(); i < childViews.length; i++) {
- view = childViews[i];
- view.parentResized(oldRect, this._rect);
- view.rect().y = offset;
- // view.rect(new Rect(view._rect.x, offset, view._rect.width, view._rect.height));
- if (this._hidePartlyVisible) {
- view.visible(view._rect.height + offset <= this._rect.height);
- }
- if (view.visible()) offset += view._rect.height;
- };
- };
-
- this.childResized = function() {
- this._needsLayout = true;
- uki.after(uki.proxy(this._afterChildResized, this));
- };
-
- this._contentChanged = this.childResized;
-
- this._afterChildResized = function() {
- this.resizeToContents('height');
- this.parent().childResized(this);
- this.layoutIfNeeded();
- };
-
-});
-
-/**
- * Horizontla Flow
- * Arranges child views horizontally
- *
- * @author voloko
- * @name uki.view.HFlow
- * @class
- * @extends uki.view.VFlow
- */
-uki.view.declare('uki.view.HFlow', uki.view.VFlow, function(Base) {
- this.contentsSize = function() {
- var value = uki.reduce(0, this._childViews, function(sum, e) {
- return sum + (e.visible() ? e.rect().width : 0);
- } );
- return new Size( value, this.contentsHeight() );
- };
-
- this._resizeChildViews = function(oldRect) {
- var offset = 0, rect, view;
- for (var i=0, childViews = this.childViews(); i < childViews.length; i++) {
- view = childViews[i];
- view.parentResized(oldRect, this._rect);
- view.rect().x = offset;
- // view.rect(new Rect(offset, view._rect.y, view._rect.width, view._rect.height));
- if (this._hidePartlyVisible) {
- view.visible(view._rect.width + offset <= this._rect.width);
- }
- if (view.visible()) offset += view._rect.width;
- };
- };
-
- this._afterChildResized = function() {
- this.resizeToContents('width');
- this.parent().childResized(this);
- this.layoutIfNeeded();
- };
-});
-
-
-
-
-uki.view.toolbar = {};
-
-/**
-* Toolbar
-*
-* @author voloko
-* @name uki.view.Toolbar
-* @class
-* @extends uki.view.Container
-*/
-uki.view.declare('uki.view.Toolbar', uki.view.Container, function(Base) {
-
- this.typeName = function() { return 'uki.view.Toolbar'; };
-
- this._moreWidth = 30;
-
- this._setup = function() {
- Base._setup.call(this);
- this._buttons = [];
- this._widths = [];
- };
-
- /**
- * @function
- * @name uki.view.Toolbar#buttons
- */
- this.buttons = uki.newProp('_buttons', function(b) {
- this._buttons = b;
- var buttons = uki.build(uki.map(this._buttons, this._createButton, this)).resizeToContents('width');
- this._flow.childViews(buttons);
- this._totalWidth = uki.reduce(0, this._flow.childViews(), function(s, v) { return s + v.rect().width; });
- });
-
- /**
- * @function
- * @name uki.view.Toolbar#moreWidth
- */
- uki.moreWidth = uki.newProp('_moreWidth', function(v) {
- this._moreWidth = v;
- this._updateMoreVisible();
- });
-
- this._createDom = function() {
- Base._createDom.call(this);
-
- var rect = this.rect(),
- flowRect = rect.clone().normalize(),
- moreRect = new Rect(rect.width - this._moreWidth, 0, this._moreWidth, rect.height),
- flowML = { view: 'HFlow', rect: flowRect, anchors: 'left top right', className: 'toolbar-flow', hidePartlyVisible: true },
- moreML = { view: 'Button', rect: moreRect, anchors: 'right top', className: 'toolbar-button', visible: false, backgroundPrefix: 'toolbar-more-', text: '>>', focusable: false },
- popupML = { view: 'Popup', rect: '0 0', anchors: 'right top', className: 'toolbar-popup', background: 'theme(toolbar-popup)',
- childViews: { view: 'VFlow', rect: '0 5 0 0', anchors: 'right top left bottom' }
- };
-
- this._flow = uki.build(flowML)[0];
- this._more = uki.build(moreML)[0];
- this.appendChild(this._flow);
- this.appendChild(this._more);
- popupML.relativeTo = this._more;
- this._popup = uki.build(popupML)[0];
-
- this._more.bind('click', uki.proxy(this._showMissingButtons, this));
- };
-
- this._showMissingButtons = function() {
- var maxWith = this._flow.rect().width,
- currentWidth = 0,
- missing = [];
- for (var i=0, childViews = this._flow.childViews(), l = childViews.length; i < l; i++) {
- currentWidth += childViews[i].rect().width;
- if (currentWidth > maxWith) missing.push(i);
- };
- var newButtons = uki.map(missing, function(i) {
- var descr = { html: childViews[i].html(), backgroundPrefix: 'toolbar-popup-button-' };
- uki.each(['fontSize', 'fontWeight', 'color', 'textAlign', 'inset'], function(j, name) {
- descr[name] = uki.attr(childViews[i], name);
- });
- return this._createButton(descr);
- }, this);
- uki('VFlow', this._popup).childViews(newButtons).resizeToContents('width height');
- this._popup.resizeToContents('width height').height(this._popup.height() + 5).toggle();
- };
-
- this._updateMoreVisible = function() {
- var rect = this._rect;
- if (this._more.visible() != rect.width < this._totalWidth) {
- this._more.visible(rect.width < this._totalWidth);
- var flowRect = this._flow.rect();
- flowRect.width += (rect.width < this._totalWidth ? -1 : 1)*this._moreWidth;
- this._flow.rect(flowRect);
- }
- };
-
- this.rect = function(rect) {
- var result = Base.rect.call(this, rect);
- if (rect) this._updateMoreVisible();
- return result;
- };
-
- this._createButton = function(descr) {
- var rect = this.rect().clone().normalize();
- rect.width = 100;
- return uki.extend({
- view: 'Button', rect: rect, focusable: false, align: 'left',
- anchors: 'left top', backgroundPrefix: 'toolbar-button-', autosizeToContents: 'width', focusable: false
- }, descr);
- };
-});
-
-}());
-(function() {
- var defaultCss = 'position:absolute;z-index:100;-moz-user-focus:none;font-family:Arial,Helvetica,sans-serif;',
- reflex = '<div style="position:absolute;z-index:1;left:1px;bottom:0px;right:1px;height:1px;overflow:hidden;background:rgba(255,255,255,0.4)"></div>';
-
- uki.theme.airport = uki.extend({}, uki.theme.Base, {
- imagePath: 'http://static.ukijs.org/pkg/0.3.8/uki-theme/airport/i/',
-
- backgrounds: {
- // basic button
- 'button-normal': function() {
- return new uki.background.LinearGradient({
- startColor: '#FDFEFF',
- stops: [
- { pos: 0.15, color: '#F5F7FD' },
- { pos: 0.8, color: '#C9CACF' }
- ],
- endColor: '#C7CBD2',
- innerHTML: reflex,
- css: 'border:1px solid #666;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,0.5);'
- });
- },
-
- 'button-hover': function() {
- return new uki.background.LinearGradient({
- startColor: '#FFFFFF',
- stops: [
- { pos: 0.7, color: '#D7DAE4' }
- ],
- endColor: '#D9DEE6',
- innerHTML: reflex,
- css: 'border:1px solid #666;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,0.5);'
- });
- },
-
- 'button-down': function() {
- return new uki.background.LinearGradient({
- startColor: '#9C9DA1',
- stops: [
- { pos: 0.6, color: '#C5C7CD' }
- ],
- endColor: '#CCCFD6',
- css: 'border:1px solid #666;border-radius:3px;box-shadow:inset 0 1px 3px rgba(0,0,0,0.5);'
- });
- },
-
- 'button-focus': function() {
- if (uki.browser.cssBoxShadow() == 'unsupported') {
- return new uki.background.CssBox(
- 'background:#7594D2;' + (uki.browser.cssFilter() && uki.image.needAlphaFix ? 'filter:Alpha(opacity=70);' : 'opacity:0.7;'),
- { inset: '-2 -2', zIndex: -2 }
- );
- }
- return new uki.background.Css({
- // WebkitTransition: '-webkit-box-shadow 0.2s linear',
- boxShadow: '0 0 6px #0244D4',
- borderRadius: '3px'
- });
- },
-
- 'button-disabled': function() {
- return new uki.background.Multi(
- uki.theme.background('button-normal'),
- new uki.background.Css({ color: '#999' })
- );
- },
-
-
- // checkbox
- 'checkbox-normal': function() {
- return checkboxBg(18);
- },
-
- 'checkbox-hover': function() {
- return checkboxBg(54);
- },
-