spiderfw 0.6.22 → 0.6.23
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/VERSION +1 -1
- data/apps/app_server/controllers/app_server_controller.rb +7 -2
- data/apps/app_server/lib/git_app.rb +5 -3
- data/apps/cas_server/controllers/mixins/cas_login_mixin.rb +2 -1
- data/apps/core/admin/controllers/admin_controller.rb +4 -4
- data/apps/core/admin/controllers/app_admin_controller.rb +3 -2
- data/apps/core/admin/public/css/sass/admin.css +56 -31
- data/apps/core/admin/public/sass/admin.scss +38 -4
- data/apps/core/admin/views/_breadcrumb.shtml +8 -0
- data/apps/core/admin/views/admin.layout.shtml +8 -5
- data/apps/core/auth/controllers/login_controller.rb +3 -8
- data/apps/core/components/assets.rb +37 -1
- data/apps/core/components/public/bootstrap/LICENSE +13 -0
- data/apps/core/components/public/bootstrap/README.md +28 -0
- data/apps/core/components/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/apps/core/components/public/bootstrap/img/glyphicons-halflings.png +0 -0
- data/apps/core/components/public/bootstrap/js/README.md +106 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-alert.js +91 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-button.js +98 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-carousel.js +154 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-collapse.js +136 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-dropdown.js +92 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-modal.js +209 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-popover.js +95 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-scrollspy.js +125 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-tab.js +130 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-tooltip.js +270 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-transition.js +51 -0
- data/apps/core/components/public/bootstrap/js/bootstrap-typeahead.js +271 -0
- data/apps/core/components/public/bootstrap/js/tests/index.html +49 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-alert.js +41 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-button.js +54 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-collapse.js +25 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-dropdown.js +53 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-modal.js +85 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-popover.js +93 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-scrollspy.js +31 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-tab.js +45 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-tooltip.js +62 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-transition.js +13 -0
- data/apps/core/components/public/bootstrap/js/tests/unit/bootstrap-typeahead.js +128 -0
- data/apps/core/components/public/bootstrap/js/tests/vendor/jquery.js +9252 -0
- data/apps/core/components/public/bootstrap/js/tests/vendor/qunit.css +232 -0
- data/apps/core/components/public/bootstrap/js/tests/vendor/qunit.js +1510 -0
- data/apps/core/components/public/bootstrap/scss/_accordion.scss +28 -0
- data/apps/core/components/public/bootstrap/scss/_alerts.scss +70 -0
- data/apps/core/components/public/bootstrap/scss/_breadcrumbs.scss +22 -0
- data/apps/core/components/public/bootstrap/scss/_button-groups.scss +146 -0
- data/apps/core/components/public/bootstrap/scss/_buttons.scss +165 -0
- data/apps/core/components/public/bootstrap/scss/_carousel.scss +121 -0
- data/apps/core/components/public/bootstrap/scss/_close.scss +18 -0
- data/apps/core/components/public/bootstrap/scss/_code.scss +44 -0
- data/apps/core/components/public/bootstrap/scss/_component-animations.scss +18 -0
- data/apps/core/components/public/bootstrap/scss/_custom.css +0 -0
- data/apps/core/components/public/bootstrap/scss/_dropdowns.scss +131 -0
- data/apps/core/components/public/bootstrap/scss/_forms.scss +516 -0
- data/apps/core/components/public/bootstrap/scss/_grid.scss +8 -0
- data/apps/core/components/public/bootstrap/scss/_hero-unit.scss +20 -0
- data/apps/core/components/public/bootstrap/scss/_labels.scss +16 -0
- data/apps/core/components/public/bootstrap/scss/_layouts.scss +17 -0
- data/apps/core/components/public/bootstrap/scss/_mixins.scss +538 -0
- data/apps/core/components/public/bootstrap/scss/_modals.scss +72 -0
- data/apps/core/components/public/bootstrap/scss/_navbar.scss +292 -0
- data/apps/core/components/public/bootstrap/scss/_navs.scss +343 -0
- data/apps/core/components/public/bootstrap/scss/_pager.scss +30 -0
- data/apps/core/components/public/bootstrap/scss/_pagination.scss +64 -0
- data/apps/core/components/public/bootstrap/scss/_patterns.scss +13 -0
- data/apps/core/components/public/bootstrap/scss/_popovers.scss +49 -0
- data/apps/core/components/public/bootstrap/scss/_print.scss +18 -0
- data/apps/core/components/public/bootstrap/scss/_progress-bars.scss +95 -0
- data/apps/core/{admin/public/sass/bootstrap/reset.scss → components/public/bootstrap/scss/_reset.scss} +36 -51
- data/apps/core/components/public/bootstrap/scss/_scaffolding.scss +29 -0
- data/apps/core/components/public/bootstrap/scss/_sprites.scss +156 -0
- data/apps/core/components/public/bootstrap/scss/_tables.scss +139 -0
- data/apps/core/components/public/bootstrap/scss/_thumbnails.scss +35 -0
- data/apps/core/components/public/bootstrap/scss/_tooltip.scss +35 -0
- data/apps/core/components/public/bootstrap/scss/_type.scss +217 -0
- data/apps/core/components/public/bootstrap/scss/_utilities.scss +23 -0
- data/apps/core/components/public/bootstrap/scss/_variables.scss +99 -0
- data/apps/core/components/public/bootstrap/scss/_wells.scss +17 -0
- data/apps/core/components/public/bootstrap/scss/bootstrap-responsive.css +707 -0
- data/apps/core/components/public/bootstrap/scss/bootstrap-responsive.scss +323 -0
- data/apps/core/components/public/bootstrap/scss/bootstrap.css +4604 -0
- data/apps/core/components/public/bootstrap/scss/bootstrap.scss +62 -0
- data/apps/core/components/public/bootstrap/scss/config.rb +36 -0
- data/apps/core/components/public/css/admin.css +2 -1
- data/apps/core/components/public/css/sass/bootstrap/bootstrap.css +3107 -0
- data/apps/core/components/public/css/table_base.css +9 -0
- data/apps/core/components/public/widgets/month_calendar.js +9 -0
- data/apps/core/components/widgets/crud/crud.rb +9 -1
- data/apps/core/components/widgets/crud/crud.shtml +2 -2
- data/apps/core/components/widgets/month_calendar/month_calendar.shtml +1 -0
- data/apps/core/components/widgets/table/table.rb +84 -55
- data/apps/core/components/widgets/table/table.shtml +2 -1
- data/apps/core/forms/public/ckeditor/CHANGES.html +139 -1
- data/apps/core/forms/public/ckeditor/LICENSE.html +1 -8
- data/apps/core/forms/public/ckeditor/ckeditor.js +141 -137
- data/apps/core/forms/public/ckeditor/ckeditor_basic.js +3 -3
- data/apps/core/forms/public/ckeditor/ckeditor_basic_source.js +1 -1
- data/apps/core/forms/public/ckeditor/ckeditor_source.js +13 -3
- data/apps/core/forms/public/ckeditor/contents.css +4 -2
- data/apps/core/forms/public/ckeditor/lang/_translationstatus.txt +59 -59
- data/apps/core/forms/public/ckeditor/lang/af.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/ar.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/bg.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/bn.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/bs.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/ca.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/cs.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/cy.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/da.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/de.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/el.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/en-au.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/en-ca.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/en-gb.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/en.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/eo.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/es.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/et.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/eu.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/fa.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/fi.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/fo.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/fr-ca.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/fr.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/gl.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/gu.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/he.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/hi.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/hr.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/hu.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/is.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/it.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/ja.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/ka.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/km.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/ko.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/lt.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/lv.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/mn.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/ms.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/nb.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/nl.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/no.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/pl.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/pt-br.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/pt.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/ro.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/ru.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/sk.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/sl.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/sr-latn.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/sr.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/sv.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/th.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/tr.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/uk.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/vi.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/zh-cn.js +1 -1
- data/apps/core/forms/public/ckeditor/lang/zh.js +1 -1
- data/apps/core/forms/public/ckeditor/plugins/autogrow/plugin.js +1 -1
- data/apps/core/forms/public/ckeditor/plugins/bbcode/plugin.js +4 -4
- data/apps/core/forms/public/ckeditor/plugins/docprops/dialogs/docprops.js +2 -2
- data/apps/core/forms/public/ckeditor/plugins/find/dialogs/find.js +5 -4
- data/apps/core/forms/public/ckeditor/plugins/flash/dialogs/flash.js +4 -4
- data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/select.js +2 -2
- data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/textarea.js +1 -1
- data/apps/core/forms/public/ckeditor/plugins/iframe/dialogs/iframe.js +2 -2
- data/apps/core/forms/public/ckeditor/plugins/image/dialogs/image.js +6 -6
- data/apps/core/forms/public/ckeditor/plugins/link/dialogs/link.js +6 -5
- data/apps/core/forms/public/ckeditor/plugins/liststyle/dialogs/liststyle.js +2 -1
- data/apps/core/forms/public/ckeditor/plugins/pastefromword/filter/default.js +5 -5
- data/apps/core/forms/public/ckeditor/plugins/specialchar/dialogs/specialchar.js +1 -1
- data/apps/core/forms/public/ckeditor/plugins/specialchar/lang/en.js +1 -1
- data/apps/core/forms/public/ckeditor/plugins/table/dialogs/table.js +4 -4
- data/apps/core/forms/public/ckeditor/plugins/tableresize/plugin.js +2 -2
- data/apps/core/forms/public/ckeditor/plugins/wsc/dialogs/wsc.js +1 -1
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/README.md +26 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/dialog.css +616 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/editor.css +1088 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/icons.png +0 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/images/dialog_sides.gif +0 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/images/dialog_sides.png +0 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/images/dialog_sides_rtl.png +0 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/images/mini.png +0 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/images/noimage.png +0 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/images/sprites.png +0 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/images/sprites_ie6.png +0 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/images/toolbar_start.gif +0 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/skin.js +7 -0
- data/apps/core/forms/public/ckeditor/skins/BootstrapCK-Skin/templates.css +54 -0
- data/apps/core/forms/public/ckeditor/skins/kama/dialog.css +4 -3
- data/apps/core/forms/public/ckeditor/skins/kama/editor.css +3 -3
- data/apps/core/forms/public/ckeditor/themes/default/theme.js +2 -2
- data/apps/core/forms/public/css/form.css +5 -5
- data/apps/core/forms/public/html_area.js +5 -5
- data/apps/core/forms/tags/element_label.erb +1 -1
- data/apps/core/forms/tags/row.erb +1 -1
- data/apps/core/forms/widgets/form/form.rb +2 -1
- data/apps/core/forms/widgets/form/form.shtml +3 -3
- data/apps/core/forms/widgets/inputs/checkbox/checkbox.shtml +1 -1
- data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +1 -1
- data/apps/core/forms/widgets/inputs/file_input/file_input.shtml +1 -1
- data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +1 -1
- data/apps/core/forms/widgets/inputs/input/input.shtml +1 -1
- data/apps/core/forms/widgets/inputs/input/readonly.shtml +1 -1
- data/apps/core/forms/widgets/inputs/password/password.shtml +1 -1
- data/apps/core/forms/widgets/inputs/search_select/search_select.shtml +1 -1
- data/apps/core/forms/widgets/inputs/select/select.shtml +1 -1
- data/apps/core/forms/widgets/inputs/text/text.shtml +1 -1
- data/apps/core/forms/widgets/inputs/text_area/text_area.shtml +1 -1
- data/apps/core/forms/widgets/inputs/time_span/time_span.shtml +1 -1
- data/apps/messenger/controllers/messenger_admin_controller.rb +19 -4
- data/apps/messenger/views/admin/_admin.layout.shtml +1 -1
- data/apps/messenger/views/admin/queue.shtml +6 -6
- data/apps/messenger/views/admin/view_email.shtml +7 -0
- data/apps/messenger/views/admin/view_sms.shtml +4 -0
- data/blueprints/app/.dirs +2 -1
- data/blueprints/app/test/features/support/env.rb +4 -0
- data/data/locale/it/LC_MESSAGES/spider.mo +0 -0
- data/lib/spiderfw/cmd/commands/config.rb +6 -3
- data/lib/spiderfw/config/configuration.rb +11 -2
- data/lib/spiderfw/config/options/spider.rb +1 -1
- data/lib/spiderfw/controller/controller.rb +27 -15
- data/lib/spiderfw/controller/dispatcher.rb +8 -4
- data/lib/spiderfw/controller/http_controller.rb +9 -5
- data/lib/spiderfw/controller/mixins/static_content.rb +1 -0
- data/lib/spiderfw/controller/mixins/visual.rb +48 -31
- data/lib/spiderfw/home.rb +8 -0
- data/lib/spiderfw/i18n/cldr.rb +1 -0
- data/lib/spiderfw/model/base_model.rb +2 -2
- data/lib/spiderfw/model/mappers/db_mapper.rb +1 -0
- data/lib/spiderfw/model/unit_of_work.rb +2 -2
- data/lib/spiderfw/requires.rb +1 -0
- data/lib/spiderfw/setup/app_manager.rb +16 -8
- data/lib/spiderfw/spider.rb +2 -2
- data/lib/spiderfw/templates/layout.rb +16 -9
- data/lib/spiderfw/templates/template.rb +28 -8
- data/lib/spiderfw/utils/logger.rb +9 -9
- data/views/errors/error.layout.shtml +9 -4
- metadata +98 -13
- data/apps/core/admin/public/sass/bootstrap/bootstrap.scss +0 -29
- data/apps/core/admin/public/sass/bootstrap/forms.scss +0 -478
- data/apps/core/admin/public/sass/bootstrap/mixins.scss +0 -220
- data/apps/core/admin/public/sass/bootstrap/patterns.scss +0 -1062
- data/apps/core/admin/public/sass/bootstrap/scaffolding.scss +0 -136
- data/apps/core/admin/public/sass/bootstrap/tables.scss +0 -224
- data/apps/core/admin/public/sass/bootstrap/type.scss +0 -187
- data/apps/core/admin/public/sass/bootstrap/variables.scss +0 -60
@@ -0,0 +1,54 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-buttons")
|
4
|
+
|
5
|
+
test("should be defined on jquery object", function () {
|
6
|
+
ok($(document.body).button, 'tabs method is defined')
|
7
|
+
})
|
8
|
+
|
9
|
+
test("should return element", function () {
|
10
|
+
ok($(document.body).button()[0] == document.body, 'document.body returned')
|
11
|
+
})
|
12
|
+
|
13
|
+
test("should return set state to loading", function () {
|
14
|
+
var btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
|
15
|
+
equals(btn.html(), 'mdo', 'btn text equals mdo')
|
16
|
+
btn.button('loading')
|
17
|
+
equals(btn.html(), 'fat', 'btn text equals fat')
|
18
|
+
stop()
|
19
|
+
setTimeout(function () {
|
20
|
+
ok(btn.attr('disabled'), 'btn is disabled')
|
21
|
+
ok(btn.hasClass('disabled'), 'btn has disabled class')
|
22
|
+
start()
|
23
|
+
}, 0)
|
24
|
+
})
|
25
|
+
|
26
|
+
test("should return reset state", function () {
|
27
|
+
var btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
|
28
|
+
equals(btn.html(), 'mdo', 'btn text equals mdo')
|
29
|
+
btn.button('loading')
|
30
|
+
equals(btn.html(), 'fat', 'btn text equals fat')
|
31
|
+
stop()
|
32
|
+
setTimeout(function () {
|
33
|
+
ok(btn.attr('disabled'), 'btn is disabled')
|
34
|
+
ok(btn.hasClass('disabled'), 'btn has disabled class')
|
35
|
+
start()
|
36
|
+
stop()
|
37
|
+
}, 0)
|
38
|
+
btn.button('reset')
|
39
|
+
equals(btn.html(), 'mdo', 'btn text equals mdo')
|
40
|
+
setTimeout(function () {
|
41
|
+
ok(!btn.attr('disabled'), 'btn is not disabled')
|
42
|
+
ok(!btn.hasClass('disabled'), 'btn does not have disabled class')
|
43
|
+
start()
|
44
|
+
}, 0)
|
45
|
+
})
|
46
|
+
|
47
|
+
test("should toggle active", function () {
|
48
|
+
var btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
|
49
|
+
ok(!btn.hasClass('active'), 'btn does not have active class')
|
50
|
+
btn.button('toggle')
|
51
|
+
ok(btn.hasClass('active'), 'btn has class active')
|
52
|
+
})
|
53
|
+
|
54
|
+
})
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-collapse")
|
4
|
+
|
5
|
+
test("should be defined on jquery object", function () {
|
6
|
+
ok($(document.body).collapse, 'collapse method is defined')
|
7
|
+
})
|
8
|
+
|
9
|
+
test("should return element", function () {
|
10
|
+
ok($(document.body).collapse()[0] == document.body, 'document.body returned')
|
11
|
+
})
|
12
|
+
|
13
|
+
test("should show a collapsed element", function () {
|
14
|
+
var el = $('<div class="collapse"></div>').collapse('show')
|
15
|
+
ok(el.hasClass('in'), 'has class in')
|
16
|
+
ok(/height/.test(el.attr('style')), 'has height set')
|
17
|
+
})
|
18
|
+
|
19
|
+
test("should hide a collapsed element", function () {
|
20
|
+
var el = $('<div class="collapse"></div>').collapse('hide')
|
21
|
+
ok(!el.hasClass('in'), 'does not have class in')
|
22
|
+
ok(/height/.test(el.attr('style')), 'has height set')
|
23
|
+
})
|
24
|
+
|
25
|
+
})
|
@@ -0,0 +1,53 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-dropdowns")
|
4
|
+
|
5
|
+
test("should be defined on jquery object", function () {
|
6
|
+
ok($(document.body).dropdown, 'dropdown method is defined')
|
7
|
+
})
|
8
|
+
|
9
|
+
test("should return element", function () {
|
10
|
+
ok($(document.body).dropdown()[0] == document.body, 'document.body returned')
|
11
|
+
})
|
12
|
+
|
13
|
+
test("should add class open to menu if clicked", function () {
|
14
|
+
var dropdownHTML = '<ul class="tabs">'
|
15
|
+
+ '<li class="dropdown">'
|
16
|
+
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
|
17
|
+
+ '<ul class="dropdown-menu">'
|
18
|
+
+ '<li><a href="#">Secondary link</a></li>'
|
19
|
+
+ '<li><a href="#">Something else here</a></li>'
|
20
|
+
+ '<li class="divider"></li>'
|
21
|
+
+ '<li><a href="#">Another link</a></li>'
|
22
|
+
+ '</ul>'
|
23
|
+
+ '</li>'
|
24
|
+
+ '</ul>'
|
25
|
+
, dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').dropdown().click()
|
26
|
+
|
27
|
+
ok(dropdown.parent('.dropdown').hasClass('open'), 'open class added on click')
|
28
|
+
})
|
29
|
+
|
30
|
+
test("should remove open class if body clicked", function () {
|
31
|
+
var dropdownHTML = '<ul class="tabs">'
|
32
|
+
+ '<li class="dropdown">'
|
33
|
+
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
|
34
|
+
+ '<ul class="dropdown-menu">'
|
35
|
+
+ '<li><a href="#">Secondary link</a></li>'
|
36
|
+
+ '<li><a href="#">Something else here</a></li>'
|
37
|
+
+ '<li class="divider"></li>'
|
38
|
+
+ '<li><a href="#">Another link</a></li>'
|
39
|
+
+ '</ul>'
|
40
|
+
+ '</li>'
|
41
|
+
+ '</ul>'
|
42
|
+
, dropdown = $(dropdownHTML)
|
43
|
+
.appendTo('#qunit-fixture')
|
44
|
+
.find('[data-toggle="dropdown"]')
|
45
|
+
.dropdown()
|
46
|
+
.click()
|
47
|
+
ok(dropdown.parent('.dropdown').hasClass('open'), 'open class added on click')
|
48
|
+
$('body').click()
|
49
|
+
ok(!dropdown.parent('.dropdown').hasClass('open'), 'open class removed')
|
50
|
+
dropdown.remove()
|
51
|
+
})
|
52
|
+
|
53
|
+
})
|
@@ -0,0 +1,85 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-modal")
|
4
|
+
|
5
|
+
test("should be defined on jquery object", function () {
|
6
|
+
var div = $("<div id='modal-test'></div>")
|
7
|
+
ok(div.modal, 'modal method is defined')
|
8
|
+
})
|
9
|
+
|
10
|
+
test("should return element", function () {
|
11
|
+
var div = $("<div id='modal-test'></div>")
|
12
|
+
ok(div.modal() == div, 'document.body returned')
|
13
|
+
$('#modal-test').remove()
|
14
|
+
})
|
15
|
+
|
16
|
+
test("should expose defaults var for settings", function () {
|
17
|
+
ok($.fn.modal.defaults, 'default object exposed')
|
18
|
+
})
|
19
|
+
|
20
|
+
test("should insert into dom when show method is called", function () {
|
21
|
+
stop()
|
22
|
+
$.support.transition = false
|
23
|
+
$("<div id='modal-test'></div>")
|
24
|
+
.bind("shown", function () {
|
25
|
+
ok($('#modal-test').length, 'modal insterted into dom')
|
26
|
+
$(this).remove()
|
27
|
+
start()
|
28
|
+
})
|
29
|
+
.modal("show")
|
30
|
+
})
|
31
|
+
|
32
|
+
test("should hide modal when hide is called", function () {
|
33
|
+
stop()
|
34
|
+
$.support.transition = false
|
35
|
+
|
36
|
+
$("<div id='modal-test'></div>")
|
37
|
+
.bind("shown", function () {
|
38
|
+
ok($('#modal-test').is(":visible"), 'modal visible')
|
39
|
+
ok($('#modal-test').length, 'modal insterted into dom')
|
40
|
+
$(this).modal("hide")
|
41
|
+
})
|
42
|
+
.bind("hidden", function() {
|
43
|
+
ok(!$('#modal-test').is(":visible"), 'modal hidden')
|
44
|
+
$('#modal-test').remove()
|
45
|
+
start()
|
46
|
+
})
|
47
|
+
.modal("show")
|
48
|
+
})
|
49
|
+
|
50
|
+
test("should toggle when toggle is called", function () {
|
51
|
+
stop()
|
52
|
+
$.support.transition = false
|
53
|
+
var div = $("<div id='modal-test'></div>")
|
54
|
+
div
|
55
|
+
.bind("shown", function () {
|
56
|
+
ok($('#modal-test').is(":visible"), 'modal visible')
|
57
|
+
ok($('#modal-test').length, 'modal insterted into dom')
|
58
|
+
div.modal("toggle")
|
59
|
+
})
|
60
|
+
.bind("hidden", function() {
|
61
|
+
ok(!$('#modal-test').is(":visible"), 'modal hidden')
|
62
|
+
div.remove()
|
63
|
+
start()
|
64
|
+
})
|
65
|
+
.modal("toggle")
|
66
|
+
})
|
67
|
+
|
68
|
+
test("should remove from dom when click [data-dismiss=modal]", function () {
|
69
|
+
stop()
|
70
|
+
$.support.transition = false
|
71
|
+
var div = $("<div id='modal-test'><span class='close' data-dismiss='modal'></span></div>")
|
72
|
+
div
|
73
|
+
.bind("shown", function () {
|
74
|
+
ok($('#modal-test').is(":visible"), 'modal visible')
|
75
|
+
ok($('#modal-test').length, 'modal insterted into dom')
|
76
|
+
div.find('.close').click()
|
77
|
+
})
|
78
|
+
.bind("hidden", function() {
|
79
|
+
ok(!$('#modal-test').is(":visible"), 'modal hidden')
|
80
|
+
div.remove()
|
81
|
+
start()
|
82
|
+
})
|
83
|
+
.modal("toggle")
|
84
|
+
})
|
85
|
+
})
|
@@ -0,0 +1,93 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-popover")
|
4
|
+
|
5
|
+
test("should be defined on jquery object", function () {
|
6
|
+
var div = $('<div></div>')
|
7
|
+
ok(div.popover, 'popover method is defined')
|
8
|
+
})
|
9
|
+
|
10
|
+
test("should return element", function () {
|
11
|
+
var div = $('<div></div>')
|
12
|
+
ok(div.popover() == div, 'document.body returned')
|
13
|
+
})
|
14
|
+
|
15
|
+
test("should render popover element", function () {
|
16
|
+
$.support.transition = false
|
17
|
+
var popover = $('<a href="#" title="mdo" data-content="http://twitter.com/mdo">@mdo</a>')
|
18
|
+
.appendTo('#qunit-fixture')
|
19
|
+
.popover('show')
|
20
|
+
|
21
|
+
ok($('.popover').length, 'popover was inserted')
|
22
|
+
popover.popover('hide')
|
23
|
+
ok(!$(".popover").length, 'popover removed')
|
24
|
+
})
|
25
|
+
|
26
|
+
test("should store popover instance in popover data object", function () {
|
27
|
+
$.support.transition = false
|
28
|
+
var popover = $('<a href="#" title="mdo" data-content="http://twitter.com/mdo">@mdo</a>')
|
29
|
+
.popover()
|
30
|
+
|
31
|
+
ok(!!popover.data('popover'), 'popover instance exists')
|
32
|
+
})
|
33
|
+
|
34
|
+
test("should get title and content from options", function () {
|
35
|
+
$.support.transition = false
|
36
|
+
var popover = $('<a href="#">@fat</a>')
|
37
|
+
.appendTo('#qunit-fixture')
|
38
|
+
.popover({
|
39
|
+
title: function () {
|
40
|
+
return '@fat'
|
41
|
+
}
|
42
|
+
, content: function () {
|
43
|
+
return 'loves writing tests (╯°□°)╯︵ ┻━┻'
|
44
|
+
}
|
45
|
+
})
|
46
|
+
|
47
|
+
popover.popover('show')
|
48
|
+
|
49
|
+
ok($('.popover').length, 'popover was inserted')
|
50
|
+
equals($('.popover .popover-title').text(), '@fat', 'title correctly inserted')
|
51
|
+
equals($('.popover .popover-content').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted')
|
52
|
+
|
53
|
+
popover.popover('hide')
|
54
|
+
ok(!$('.popover').length, 'popover was removed')
|
55
|
+
$('#qunit-fixture').empty()
|
56
|
+
})
|
57
|
+
|
58
|
+
test("should get title and content from attributes", function () {
|
59
|
+
$.support.transition = false
|
60
|
+
var popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
|
61
|
+
.appendTo('#qunit-fixture')
|
62
|
+
.popover()
|
63
|
+
.popover('show')
|
64
|
+
|
65
|
+
ok($('.popover').length, 'popover was inserted')
|
66
|
+
equals($('.popover .popover-title').text(), '@mdo', 'title correctly inserted')
|
67
|
+
equals($('.popover .popover-content').text(), "loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻", 'content correctly inserted')
|
68
|
+
|
69
|
+
popover.popover('hide')
|
70
|
+
ok(!$('.popover').length, 'popover was removed')
|
71
|
+
$('#qunit-fixture').empty()
|
72
|
+
})
|
73
|
+
|
74
|
+
test("should respect custom classes", function() {
|
75
|
+
$.support.transition = false
|
76
|
+
var popover = $('<a href="#">@fat</a>')
|
77
|
+
.appendTo('#qunit-fixture')
|
78
|
+
.popover({
|
79
|
+
title: 'Test'
|
80
|
+
, content: 'Test'
|
81
|
+
, template: '<div class="popover foobar"><div class="arrow"></div><div class="inner"><h3 class="title"></h3><div class="content"><p></p></div></div></div>'
|
82
|
+
})
|
83
|
+
|
84
|
+
popover.popover('show')
|
85
|
+
|
86
|
+
ok($('.popover').length, 'popover was inserted')
|
87
|
+
ok($('.popover').hasClass('foobar'), 'custom class is present')
|
88
|
+
|
89
|
+
popover.popover('hide')
|
90
|
+
ok(!$('.popover').length, 'popover was removed')
|
91
|
+
$('#qunit-fixture').empty()
|
92
|
+
})
|
93
|
+
})
|
@@ -0,0 +1,31 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-scrollspy")
|
4
|
+
|
5
|
+
test("should be defined on jquery object", function () {
|
6
|
+
ok($(document.body).scrollspy, 'scrollspy method is defined')
|
7
|
+
})
|
8
|
+
|
9
|
+
test("should return element", function () {
|
10
|
+
ok($(document.body).scrollspy()[0] == document.body, 'document.body returned')
|
11
|
+
})
|
12
|
+
|
13
|
+
test("should switch active class on scroll", function () {
|
14
|
+
var sectionHTML = '<div id="masthead"></div>'
|
15
|
+
, $section = $(sectionHTML).append('#qunit-fixture')
|
16
|
+
, topbarHTML ='<div class="topbar">'
|
17
|
+
+ '<div class="topbar-inner">'
|
18
|
+
+ '<div class="container">'
|
19
|
+
+ '<h3><a href="#">Bootstrap</a></h3>'
|
20
|
+
+ '<ul class="nav">'
|
21
|
+
+ '<li><a href="#masthead">Overview</a></li>'
|
22
|
+
+ '</ul>'
|
23
|
+
+ '</div>'
|
24
|
+
+ '</div>'
|
25
|
+
+ '</div>'
|
26
|
+
, $topbar = $(topbarHTML).scrollspy()
|
27
|
+
|
28
|
+
ok($topbar.find('.active', true))
|
29
|
+
})
|
30
|
+
|
31
|
+
})
|
@@ -0,0 +1,45 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-tabs")
|
4
|
+
|
5
|
+
test("should be defined on jquery object", function () {
|
6
|
+
ok($(document.body).tab, 'tabs method is defined')
|
7
|
+
})
|
8
|
+
|
9
|
+
test("should return element", function () {
|
10
|
+
ok($(document.body).tab()[0] == document.body, 'document.body returned')
|
11
|
+
})
|
12
|
+
|
13
|
+
test("should activate element by tab id", function () {
|
14
|
+
var tabsHTML =
|
15
|
+
'<ul class="tabs">'
|
16
|
+
+ '<li><a href="#home">Home</a></li>'
|
17
|
+
+ '<li><a href="#profile">Profile</a></li>'
|
18
|
+
+ '</ul>'
|
19
|
+
|
20
|
+
$('<ul><li id="home"></li><li id="profile"></li></ul>').appendTo("#qunit-fixture")
|
21
|
+
|
22
|
+
$(tabsHTML).find('li:last a').tab('show')
|
23
|
+
equals($("#qunit-fixture").find('.active').attr('id'), "profile")
|
24
|
+
|
25
|
+
$(tabsHTML).find('li:first a').tab('show')
|
26
|
+
equals($("#qunit-fixture").find('.active').attr('id'), "home")
|
27
|
+
})
|
28
|
+
|
29
|
+
test("should activate element by tab id", function () {
|
30
|
+
var pillsHTML =
|
31
|
+
'<ul class="pills">'
|
32
|
+
+ '<li><a href="#home">Home</a></li>'
|
33
|
+
+ '<li><a href="#profile">Profile</a></li>'
|
34
|
+
+ '</ul>'
|
35
|
+
|
36
|
+
$('<ul><li id="home"></li><li id="profile"></li></ul>').appendTo("#qunit-fixture")
|
37
|
+
|
38
|
+
$(pillsHTML).find('li:last a').tab('show')
|
39
|
+
equals($("#qunit-fixture").find('.active').attr('id'), "profile")
|
40
|
+
|
41
|
+
$(pillsHTML).find('li:first a').tab('show')
|
42
|
+
equals($("#qunit-fixture").find('.active').attr('id'), "home")
|
43
|
+
})
|
44
|
+
|
45
|
+
})
|
@@ -0,0 +1,62 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-tooltip")
|
4
|
+
|
5
|
+
test("should be defined on jquery object", function () {
|
6
|
+
var div = $("<div></div>")
|
7
|
+
ok(div.tooltip, 'popover method is defined')
|
8
|
+
})
|
9
|
+
|
10
|
+
test("should return element", function () {
|
11
|
+
var div = $("<div></div>")
|
12
|
+
ok(div.tooltip() == div, 'document.body returned')
|
13
|
+
})
|
14
|
+
|
15
|
+
test("should expose default settings", function () {
|
16
|
+
ok(!!$.fn.tooltip.defaults, 'defaults is defined')
|
17
|
+
})
|
18
|
+
|
19
|
+
test("should remove title attribute", function () {
|
20
|
+
var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').tooltip()
|
21
|
+
ok(!tooltip.attr('title'), 'title tag was removed')
|
22
|
+
})
|
23
|
+
|
24
|
+
test("should add data attribute for referencing original title", function () {
|
25
|
+
var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').tooltip()
|
26
|
+
equals(tooltip.attr('data-original-title'), 'Another tooltip', 'original title preserved in data attribute')
|
27
|
+
})
|
28
|
+
|
29
|
+
test("should place tooltips relative to placement option", function () {
|
30
|
+
$.support.transition = false
|
31
|
+
var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
|
32
|
+
.appendTo('#qunit-fixture')
|
33
|
+
.tooltip({placement: 'bottom'})
|
34
|
+
.tooltip('show')
|
35
|
+
|
36
|
+
ok($(".tooltip").hasClass('fade bottom in'), 'has correct classes applied')
|
37
|
+
tooltip.tooltip('hide')
|
38
|
+
})
|
39
|
+
|
40
|
+
test("should always allow html entities", function () {
|
41
|
+
$.support.transition = false
|
42
|
+
var tooltip = $('<a href="#" rel="tooltip" title="<b>@fat</b>"></a>')
|
43
|
+
.appendTo('#qunit-fixture')
|
44
|
+
.tooltip('show')
|
45
|
+
|
46
|
+
ok($('.tooltip b').length, 'b tag was inserted')
|
47
|
+
tooltip.tooltip('hide')
|
48
|
+
ok(!$(".tooltip").length, 'tooltip removed')
|
49
|
+
})
|
50
|
+
|
51
|
+
test("should respect custom classes", function () {
|
52
|
+
var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
|
53
|
+
.appendTo('#qunit-fixture')
|
54
|
+
.tooltip({ template: '<div class="tooltip some-class"><div class="tooltip-arrow"/><div class="tooltip-inner"/></div>'})
|
55
|
+
.tooltip('show')
|
56
|
+
|
57
|
+
ok($('.tooltip').hasClass('some-class'), 'custom class is present')
|
58
|
+
tooltip.tooltip('hide')
|
59
|
+
ok(!$(".tooltip").length, 'tooltip removed')
|
60
|
+
})
|
61
|
+
|
62
|
+
})
|
@@ -0,0 +1,13 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-transition")
|
4
|
+
|
5
|
+
test("should be defined on jquery support object", function () {
|
6
|
+
ok($.support.transition != undefined, 'transition object is defined')
|
7
|
+
})
|
8
|
+
|
9
|
+
test("should provide an end object", function () {
|
10
|
+
ok($.support.transition ? $.support.transition.end : true, 'end string is defined')
|
11
|
+
})
|
12
|
+
|
13
|
+
})
|
@@ -0,0 +1,128 @@
|
|
1
|
+
$(function () {
|
2
|
+
|
3
|
+
module("bootstrap-typeahead")
|
4
|
+
|
5
|
+
test("should be defined on jquery object", function () {
|
6
|
+
ok($(document.body).typeahead, 'alert method is defined')
|
7
|
+
})
|
8
|
+
|
9
|
+
test("should return element", function () {
|
10
|
+
ok($(document.body).typeahead()[0] == document.body, 'document.body returned')
|
11
|
+
})
|
12
|
+
|
13
|
+
test("should listen to an input", function () {
|
14
|
+
var $input = $('<input />')
|
15
|
+
$input.typeahead()
|
16
|
+
ok($input.data('events').blur, 'has a blur event')
|
17
|
+
ok($input.data('events').keypress, 'has a keypress event')
|
18
|
+
ok($input.data('events').keyup, 'has a keyup event')
|
19
|
+
if ($.browser.webkit || $.browser.msie) {
|
20
|
+
ok($input.data('events').keydown, 'has a keydown event')
|
21
|
+
} else {
|
22
|
+
ok($input.data('events').keydown, 'does not have a keydown event')
|
23
|
+
}
|
24
|
+
})
|
25
|
+
|
26
|
+
test("should create a menu", function () {
|
27
|
+
var $input = $('<input />')
|
28
|
+
ok($input.typeahead().data('typeahead').$menu, 'has a menu')
|
29
|
+
})
|
30
|
+
|
31
|
+
test("should listen to the menu", function () {
|
32
|
+
var $input = $('<input />')
|
33
|
+
, $menu = $input.typeahead().data('typeahead').$menu
|
34
|
+
|
35
|
+
ok($menu.data('events').mouseover, 'has a mouseover(pseudo: mouseenter)')
|
36
|
+
ok($menu.data('events').click, 'has a click')
|
37
|
+
})
|
38
|
+
|
39
|
+
test("should show menu when query entered", function () {
|
40
|
+
var $input = $('<input />').typeahead({
|
41
|
+
source: ['aa', 'ab', 'ac']
|
42
|
+
})
|
43
|
+
, typeahead = $input.data('typeahead')
|
44
|
+
|
45
|
+
$input.val('a')
|
46
|
+
typeahead.lookup()
|
47
|
+
|
48
|
+
ok(typeahead.$menu.is(":visible"), 'typeahead is visible')
|
49
|
+
equals(typeahead.$menu.find('li').length, 3, 'has 3 items in menu')
|
50
|
+
equals(typeahead.$menu.find('.active').length, 1, 'one item is active')
|
51
|
+
|
52
|
+
typeahead.$menu.remove()
|
53
|
+
})
|
54
|
+
|
55
|
+
test("should hide menu when query entered", function () {
|
56
|
+
stop()
|
57
|
+
var $input = $('<input />').typeahead({
|
58
|
+
source: ['aa', 'ab', 'ac']
|
59
|
+
})
|
60
|
+
, typeahead = $input.data('typeahead')
|
61
|
+
|
62
|
+
$input.val('a')
|
63
|
+
typeahead.lookup()
|
64
|
+
|
65
|
+
ok(typeahead.$menu.is(":visible"), 'typeahead is visible')
|
66
|
+
equals(typeahead.$menu.find('li').length, 3, 'has 3 items in menu')
|
67
|
+
equals(typeahead.$menu.find('.active').length, 1, 'one item is active')
|
68
|
+
|
69
|
+
$input.blur()
|
70
|
+
|
71
|
+
setTimeout(function () {
|
72
|
+
ok(!typeahead.$menu.is(":visible"), "typeahead is no longer visible")
|
73
|
+
start()
|
74
|
+
}, 200)
|
75
|
+
|
76
|
+
typeahead.$menu.remove()
|
77
|
+
})
|
78
|
+
|
79
|
+
test("should set next item when down arrow is pressed", function () {
|
80
|
+
var $input = $('<input />').typeahead({
|
81
|
+
source: ['aa', 'ab', 'ac']
|
82
|
+
})
|
83
|
+
, typeahead = $input.data('typeahead')
|
84
|
+
|
85
|
+
$input.val('a')
|
86
|
+
typeahead.lookup()
|
87
|
+
|
88
|
+
ok(typeahead.$menu.is(":visible"), 'typeahead is visible')
|
89
|
+
equals(typeahead.$menu.find('li').length, 3, 'has 3 items in menu')
|
90
|
+
equals(typeahead.$menu.find('.active').length, 1, 'one item is active')
|
91
|
+
ok(typeahead.$menu.find('li').first().hasClass('active'), "first item is active")
|
92
|
+
|
93
|
+
$input.trigger({
|
94
|
+
type: 'keypress'
|
95
|
+
, keyCode: 40
|
96
|
+
})
|
97
|
+
|
98
|
+
ok(typeahead.$menu.find('li').first().next().hasClass('active'), "second item is active")
|
99
|
+
|
100
|
+
|
101
|
+
$input.trigger({
|
102
|
+
type: 'keypress'
|
103
|
+
, keyCode: 38
|
104
|
+
})
|
105
|
+
|
106
|
+
ok(typeahead.$menu.find('li').first().hasClass('active'), "first item is active")
|
107
|
+
|
108
|
+
typeahead.$menu.remove()
|
109
|
+
})
|
110
|
+
|
111
|
+
|
112
|
+
test("should set input value to selected item", function () {
|
113
|
+
var $input = $('<input />').typeahead({
|
114
|
+
source: ['aa', 'ab', 'ac']
|
115
|
+
})
|
116
|
+
, typeahead = $input.data('typeahead')
|
117
|
+
|
118
|
+
$input.val('a')
|
119
|
+
typeahead.lookup()
|
120
|
+
|
121
|
+
$(typeahead.$menu.find('li')[2]).mouseover().click()
|
122
|
+
|
123
|
+
equals($input.val(), 'ac', 'input value was correctly set')
|
124
|
+
ok(!typeahead.$menu.is(':visible'), 'the menu was hidden')
|
125
|
+
|
126
|
+
typeahead.$menu.remove()
|
127
|
+
})
|
128
|
+
})
|