@oat-sa/tao-core-ui 1.64.1 → 1.64.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +339 -339
- package/README.md +22 -22
- package/dist/actionbar.js +92 -92
- package/dist/adder.js +109 -109
- package/dist/animable/absorbable/absorbable.js +29 -29
- package/dist/animable/absorbable/css/absorb.css +7 -7
- package/dist/animable/absorbable/css/absorb.css.map +1 -1
- package/dist/animable/pulsable/css/pulse.css +7 -7
- package/dist/animable/pulsable/css/pulse.css.map +1 -1
- package/dist/animable/pulsable/pulsable.js +23 -23
- package/dist/areaBroker.js +51 -51
- package/dist/autocomplete/css/autocomplete.css +7 -7
- package/dist/autocomplete/css/autocomplete.css.map +1 -1
- package/dist/autocomplete.js +384 -384
- package/dist/autoscroll.js +22 -22
- package/dist/badge/badge.js +35 -35
- package/dist/badge/css/badge.css +7 -7
- package/dist/badge/css/badge.css.map +1 -1
- package/dist/breadcrumbs/css/breadcrumbs.css +7 -7
- package/dist/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/dist/breadcrumbs.js +57 -57
- package/dist/btngrouper.js +64 -64
- package/dist/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/dist/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/dist/bulkActionPopup.js +91 -91
- package/dist/button.js +89 -89
- package/dist/calculator/css/calculator.css +10 -10
- package/dist/calculator/css/calculator.css.map +1 -1
- package/dist/calculator.js +51 -51
- package/dist/cascadingComboBox.js +34 -34
- package/dist/ckeditor/ckConfigurator.js +49 -49
- package/dist/ckeditor/dtdHandler.js +110 -110
- package/dist/class/css/selector.css +7 -7
- package/dist/class/css/selector.css.map +1 -1
- package/dist/class/selector.js +98 -98
- package/dist/component/alignable.js +81 -81
- package/dist/component/containable.js +37 -37
- package/dist/component/css/components.css +7 -7
- package/dist/component/css/components.css.map +1 -1
- package/dist/component/css/windowComponent.css +7 -7
- package/dist/component/css/windowComponent.css.map +1 -1
- package/dist/component/draggable.js +25 -25
- package/dist/component/placeable.js +70 -70
- package/dist/component/resizable.js +61 -61
- package/dist/component/stackable.js +20 -20
- package/dist/component/windowed.js +46 -46
- package/dist/component.js +140 -140
- package/dist/container.js +76 -76
- package/dist/contextualPopup/css/contextualPopup.css +7 -7
- package/dist/contextualPopup/css/contextualPopup.css.map +1 -1
- package/dist/contextualPopup.js +100 -100
- package/dist/dashboard/css/dashboard.css +7 -7
- package/dist/dashboard/css/dashboard.css.map +1 -1
- package/dist/dashboard.js +62 -62
- package/dist/datalist/css/datalist.css +7 -7
- package/dist/datalist/css/datalist.css.map +1 -1
- package/dist/datalist.js +147 -147
- package/dist/datatable/css/datatable.css +7 -7
- package/dist/datatable/css/datatable.css.map +1 -1
- package/dist/datatable/filterStrategy/filterStrategy.js +27 -27
- package/dist/datatable/filterStrategy/multiple.js +25 -25
- package/dist/datatable/filterStrategy/single.js +25 -25
- package/dist/datatable.js +377 -377
- package/dist/dateRange/css/dateRange.css +7 -7
- package/dist/dateRange/css/dateRange.css.map +1 -1
- package/dist/dateRange/dateRange.js +97 -97
- package/dist/datetime/css/picker.css +7 -7
- package/dist/datetime/css/picker.css.map +1 -1
- package/dist/datetime/picker.js +161 -161
- package/dist/deleter.js +79 -79
- package/dist/destination/css/selector.css +7 -7
- package/dist/destination/css/selector.css.map +1 -1
- package/dist/destination/selector.js +52 -52
- package/dist/dialog/alert.js +26 -26
- package/dist/dialog/confirm.js +27 -27
- package/dist/dialog/confirmDelete.js +31 -31
- package/dist/dialog.js +141 -141
- package/dist/disabler.js +90 -90
- package/dist/documentViewer/css/documentViewer.css +7 -7
- package/dist/documentViewer/css/documentViewer.css.map +1 -1
- package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +30 -30
- package/dist/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +25 -25
- package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +120 -120
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +89 -89
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +52 -52
- package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +112 -112
- package/dist/documentViewer/providers/pdfViewer/pdfjs/textManager.js +67 -67
- package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +81 -81
- package/dist/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +111 -111
- package/dist/documentViewer/providers/pdfViewer.js +29 -29
- package/dist/documentViewer/viewerFactory.js +71 -71
- package/dist/documentViewer.js +86 -86
- package/dist/dropdown/css/dropdown.css +7 -7
- package/dist/dropdown/css/dropdown.css.map +1 -1
- package/dist/dropdown.js +84 -84
- package/dist/durationer.js +58 -58
- package/dist/dynamicComponent/css/dynamicComponent.css +7 -7
- package/dist/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/dist/dynamicComponent.js +103 -103
- package/dist/feedback.js +84 -84
- package/dist/figure/FigureStateActive.js +111 -111
- package/dist/filesender.js +26 -26
- package/dist/filter.js +34 -34
- package/dist/form/css/dropdownForm.css +7 -7
- package/dist/form/css/dropdownForm.css.map +1 -1
- package/dist/form/css/form.css +7 -7
- package/dist/form/css/form.css.map +1 -1
- package/dist/form/dropdownForm.js +99 -99
- package/dist/form/form.js +248 -248
- package/dist/form/simpleForm.js +71 -71
- package/dist/form/validator/css/validator.css +7 -7
- package/dist/form/validator/css/validator.css.map +1 -1
- package/dist/form/validator/renderer.js +52 -52
- package/dist/form/validator/validator.js +103 -103
- package/dist/form/widget/css/widget.css +7 -7
- package/dist/form/widget/css/widget.css.map +1 -1
- package/dist/form/widget/definitions.js +24 -24
- package/dist/form/widget/loader.js +16 -16
- package/dist/form/widget/providers/checkBox.js +62 -62
- package/dist/form/widget/providers/comboBox.js +46 -46
- package/dist/form/widget/providers/default.js +35 -35
- package/dist/form/widget/providers/hidden.js +37 -37
- package/dist/form/widget/providers/hiddenBox.js +58 -58
- package/dist/form/widget/providers/radioBox.js +57 -57
- package/dist/form/widget/providers/textArea.js +35 -35
- package/dist/form/widget/providers/textBox.js +34 -34
- package/dist/form/widget/widget.js +141 -141
- package/dist/form.js +10 -10
- package/dist/formValidator/formValidator.js +61 -61
- package/dist/formValidator/highlighters/highlighter.js +41 -41
- package/dist/formValidator/highlighters/message.js +29 -29
- package/dist/formValidator/highlighters/tooltip.js +32 -32
- package/dist/generis/form/css/form.css +7 -7
- package/dist/generis/form/css/form.css.map +1 -1
- package/dist/generis/form/form.js +73 -73
- package/dist/generis/validator/css/validator.css +7 -7
- package/dist/generis/validator/css/validator.css.map +1 -1
- package/dist/generis/validator/validator.js +38 -38
- package/dist/generis/widget/checkBox/checkBox.js +39 -39
- package/dist/generis/widget/comboBox/comboBox.js +32 -32
- package/dist/generis/widget/css/widget.css +7 -7
- package/dist/generis/widget/css/widget.css.map +1 -1
- package/dist/generis/widget/hiddenBox/hiddenBox.js +40 -40
- package/dist/generis/widget/loader.js +20 -20
- package/dist/generis/widget/textBox/textBox.js +27 -27
- package/dist/generis/widget/widget.js +47 -47
- package/dist/groupedComboBox.js +36 -36
- package/dist/groupvalidator.js +19 -19
- package/dist/hider.js +41 -41
- package/dist/highlighter.js +278 -278
- package/dist/image/ImgStateActive/extractLabel.js +20 -20
- package/dist/image/ImgStateActive/helper.js +16 -16
- package/dist/image/ImgStateActive/initHelper.js +85 -85
- package/dist/image/ImgStateActive/initMediaEditor.js +48 -48
- package/dist/image/ImgStateActive/mediaSizer.js +32 -32
- package/dist/image/ImgStateActive.js +104 -104
- package/dist/incrementer.js +58 -58
- package/dist/inplacer.js +87 -87
- package/dist/interactUtils.js +42 -42
- package/dist/itemButtonList/css/item-button-list.css +23 -23
- package/dist/itemButtonList/css/item-button-list.css.map +1 -1
- package/dist/itemButtonList.js +102 -102
- package/dist/keyNavigation/navigableDomElement.js +76 -76
- package/dist/keyNavigation/navigator.js +158 -158
- package/dist/listbox/css/listbox.css +7 -7
- package/dist/listbox/css/listbox.css.map +1 -1
- package/dist/listbox.js +84 -84
- package/dist/liststyler.js +57 -57
- package/dist/loadingButton/css/button.css +7 -7
- package/dist/loadingButton/css/button.css.map +1 -1
- package/dist/loadingButton/loadingButton.js +35 -35
- package/dist/lock.js +112 -112
- package/dist/login/login.js +87 -87
- package/dist/maths/calculator/basicCalculator.js +50 -50
- package/dist/maths/calculator/calculatorComponent.js +29 -29
- package/dist/maths/calculator/core/areaBroker.js +25 -25
- package/dist/maths/calculator/core/board.js +300 -300
- package/dist/maths/calculator/core/expression.js +98 -98
- package/dist/maths/calculator/core/labels.js +16 -16
- package/dist/maths/calculator/core/plugin.js +19 -19
- package/dist/maths/calculator/core/terms.js +26 -26
- package/dist/maths/calculator/core/tokenizer.js +98 -98
- package/dist/maths/calculator/core/tokens.js +75 -75
- package/dist/maths/calculator/css/calculator.css +7 -7
- package/dist/maths/calculator/css/calculator.css.map +1 -1
- package/dist/maths/calculator/defaultCalculator.js +23 -23
- package/dist/maths/calculator/plugins/core/degrad.js +22 -22
- package/dist/maths/calculator/plugins/core/history.js +45 -45
- package/dist/maths/calculator/plugins/core/remind.js +22 -22
- package/dist/maths/calculator/plugins/core/stepNavigation.js +31 -31
- package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +48 -48
- package/dist/maths/calculator/plugins/modifiers/pow10.js +35 -35
- package/dist/maths/calculator/plugins/modifiers/sign.js +90 -90
- package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +47 -47
- package/dist/maths/calculator/pluginsLoader.js +21 -21
- package/dist/maths/calculator/scientificCalculator.js +78 -78
- package/dist/mediaEditor/mediaEditorComponent.js +51 -51
- package/dist/mediaEditor/plugins/mediaAlignment/helper.js +16 -16
- package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +47 -47
- package/dist/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/dist/mediaEditor/plugins/mediaDimension/helper.js +70 -70
- package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +140 -140
- package/dist/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/dist/mediaplayer/css/player.css +7 -7
- package/dist/mediaplayer/css/player.css.map +1 -1
- package/dist/mediaplayer/players/html5.js +52 -52
- package/dist/mediaplayer/players/youtube.js +39 -39
- package/dist/mediaplayer/players.js +18 -18
- package/dist/mediaplayer/support.js +55 -55
- package/dist/mediaplayer/utils/reminder.js +100 -100
- package/dist/mediaplayer/utils/timeObserver.js +92 -92
- package/dist/mediaplayer/youtubeManager.js +51 -51
- package/dist/mediaplayer.js +447 -447
- package/dist/mediasizer.js +122 -122
- package/dist/modal.js +87 -87
- package/dist/movableComponent.js +35 -35
- package/dist/pageSizeSelector.js +31 -31
- package/dist/pageStatus.js +33 -33
- package/dist/pagination/css/pagination.css +7 -7
- package/dist/pagination/css/pagination.css.map +1 -1
- package/dist/pagination/paginationStrategy.js +23 -23
- package/dist/pagination/providers/pages.js +24 -24
- package/dist/pagination/providers/simple.js +22 -22
- package/dist/pagination.js +45 -45
- package/dist/previewer.js +67 -67
- package/dist/progressbar.js +58 -58
- package/dist/propertySelector/css/propertySelector.css +7 -7
- package/dist/propertySelector/css/propertySelector.css.map +1 -1
- package/dist/propertySelector/propertySelector.js +86 -86
- package/dist/report.js +73 -73
- package/dist/resource/css/selector.css +7 -7
- package/dist/resource/css/selector.css.map +1 -1
- package/dist/resource/filters.js +60 -60
- package/dist/resource/list.js +53 -53
- package/dist/resource/selectable.js +92 -92
- package/dist/resource/selector.js +182 -182
- package/dist/resource/tree.js +91 -91
- package/dist/resourcemgr/css/resourcemgr.css +7 -7
- package/dist/resourcemgr/css/resourcemgr.css.map +1 -1
- package/dist/resourcemgr/fileBrowser.js +75 -75
- package/dist/resourcemgr/fileSelector.js +45 -45
- package/dist/resourcemgr/util/updatePermissions.js +4 -4
- package/dist/resourcemgr.js +49 -49
- package/dist/scroller.js +26 -26
- package/dist/searchModal/advancedSearch.js +155 -155
- package/dist/searchModal/css/advancedSearch.css +7 -7
- package/dist/searchModal/css/advancedSearch.css.map +1 -1
- package/dist/searchModal/css/searchModal.css +7 -7
- package/dist/searchModal/css/searchModal.css.map +1 -1
- package/dist/searchModal.js +134 -134
- package/dist/selecter.js +6 -6
- package/dist/stacker.js +43 -43
- package/dist/switch/css/switch.css +7 -7
- package/dist/switch/css/switch.css.map +1 -1
- package/dist/switch/switch.js +62 -62
- package/dist/tableModel.js +33 -33
- package/dist/tabs/css/tabs.css +12 -12
- package/dist/tabs/css/tabs.css.map +1 -1
- package/dist/tabs.js +220 -220
- package/dist/taskQueue/css/taskQueue.css +7 -7
- package/dist/taskQueue/css/taskQueue.css.map +1 -1
- package/dist/taskQueue/status.js +59 -59
- package/dist/taskQueue/table.js +54 -54
- package/dist/taskQueue/taskQueue.js +18 -18
- package/dist/taskQueue/taskQueueModel.js +102 -102
- package/dist/taskQueue.js +47 -47
- package/dist/taskQueueButton/css/taskable.css +7 -7
- package/dist/taskQueueButton/css/taskable.css.map +1 -1
- package/dist/taskQueueButton/css/treeButton.css +7 -7
- package/dist/taskQueueButton/css/treeButton.css.map +1 -1
- package/dist/taskQueueButton/standardButton.js +39 -39
- package/dist/taskQueueButton/taskable.js +41 -41
- package/dist/taskQueueButton/treeButton.js +43 -43
- package/dist/themeLoader.js +75 -75
- package/dist/themes.js +84 -84
- package/dist/toggler.js +57 -57
- package/dist/tooltip.js +41 -41
- package/dist/tooltipster.js +17 -17
- package/dist/transformer.js +117 -117
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/dist/tristateCheckboxGroup.js +62 -62
- package/dist/uploader.js +145 -145
- package/dist/validator/validators.js +48 -48
- package/dist/validator.js +23 -23
- package/dist/waitForMedia.js +33 -33
- package/dist/waitingDialog/css/waitingDialog.css +7 -7
- package/dist/waitingDialog/css/waitingDialog.css.map +1 -1
- package/dist/waitingDialog/waitingDialog.js +54 -54
- package/package.json +110 -110
- package/scss/basic.scss +16 -16
- package/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +60 -60
- package/scss/ckeditor/skins/tao/scss/inc/_tao.scss +59 -59
- package/scss/font/tao/tao.svg +235 -235
- package/scss/inc/_base.scss +495 -495
- package/scss/inc/_bootstrap.scss +6 -6
- package/scss/inc/_buttons.scss +114 -114
- package/scss/inc/_colors.scss +93 -93
- package/scss/inc/_feedback.scss +154 -154
- package/scss/inc/_flex-grid.scss +15 -15
- package/scss/inc/_fonts.scss +4 -4
- package/scss/inc/_forms.scss +832 -832
- package/scss/inc/_functions.scss +283 -283
- package/scss/inc/_jquery.nouislider.scss +254 -254
- package/scss/inc/_normalize.scss +528 -528
- package/scss/inc/_report.scss +67 -67
- package/scss/inc/_secondary-properties.scss +89 -89
- package/scss/inc/_select2.scss +634 -634
- package/scss/inc/_toolbars.scss +155 -155
- package/scss/inc/_tooltip.scss +312 -312
- package/scss/inc/_variables.scss +21 -21
- package/scss/inc/base/_highlight.scss +5 -5
- package/scss/inc/base/_list-style.scss +58 -58
- package/scss/inc/base/_svg.scss +3 -3
- package/scss/inc/base/_table.scss +62 -62
- package/scss/inc/fonts/_source-sans-pro.scss +29 -29
- package/scss/inc/fonts/_tao-icon-classes.scss +227 -227
- package/scss/inc/fonts/_tao-icon-def.scss +12 -12
- package/scss/inc/fonts/_tao-icon-vars.scss +241 -241
- package/src/actionbar/tpl/main.tpl +8 -8
- package/src/actionbar.js +251 -251
- package/src/adder.js +250 -250
- package/src/animable/absorbable/absorbable.js +134 -134
- package/src/animable/absorbable/css/absorb.css +7 -7
- package/src/animable/absorbable/css/absorb.css.map +1 -1
- package/src/animable/absorbable/scss/absorb.scss +37 -37
- package/src/animable/pulsable/css/pulse.css +7 -7
- package/src/animable/pulsable/css/pulse.css.map +1 -1
- package/src/animable/pulsable/pulsable.js +90 -90
- package/src/animable/pulsable/scss/pulse.scss +22 -22
- package/src/areaBroker.js +160 -160
- package/src/autocomplete/css/autocomplete.css +7 -7
- package/src/autocomplete/css/autocomplete.css.map +1 -1
- package/src/autocomplete/scss/autocomplete.scss +37 -37
- package/src/autocomplete.js +1027 -1027
- package/src/autoscroll.js +57 -57
- package/src/badge/badge.js +119 -119
- package/src/badge/css/badge.css +7 -7
- package/src/badge/css/badge.css.map +1 -1
- package/src/badge/scss/badge.scss +92 -92
- package/src/badge/tpl/badge.tpl +4 -4
- package/src/breadcrumbs/css/breadcrumbs.css +7 -7
- package/src/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/src/breadcrumbs/scss/breadcrumbs.scss +52 -52
- package/src/breadcrumbs/tpl/breadcrumbs.tpl +20 -20
- package/src/breadcrumbs.js +99 -99
- package/src/btngrouper.js +213 -213
- package/src/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/src/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/src/bulkActionPopup/scss/bulkActionPopup.scss +63 -63
- package/src/bulkActionPopup/tpl/layout.tpl +76 -76
- package/src/bulkActionPopup/tpl/select.tpl +8 -8
- package/src/bulkActionPopup.js +274 -274
- package/src/button/tpl/button.tpl +4 -4
- package/src/button.js +135 -135
- package/src/calculator/css/calculator.css +10 -10
- package/src/calculator/css/calculator.css.map +1 -1
- package/src/calculator/scss/calculator.scss +139 -139
- package/src/calculator.js +188 -188
- package/src/cascadingComboBox.js +126 -126
- package/src/ckeditor/ckConfigurator.js +742 -742
- package/src/ckeditor/dtdHandler.js +1030 -1030
- package/src/class/css/selector.css +7 -7
- package/src/class/css/selector.css.map +1 -1
- package/src/class/scss/selector.scss +101 -101
- package/src/class/selector.js +329 -329
- package/src/class/tpl/listItem.tpl +9 -9
- package/src/class/tpl/selector.tpl +10 -10
- package/src/component/alignable.js +274 -274
- package/src/component/containable.js +122 -122
- package/src/component/css/components.css +7 -7
- package/src/component/css/components.css.map +1 -1
- package/src/component/css/windowComponent.css +7 -7
- package/src/component/css/windowComponent.css.map +1 -1
- package/src/component/draggable.js +104 -104
- package/src/component/placeable.js +233 -233
- package/src/component/resizable.js +195 -195
- package/src/component/scss/components.scss +507 -507
- package/src/component/scss/windowComponent.scss +62 -62
- package/src/component/stackable.js +67 -67
- package/src/component/tpl/window.tpl +7 -7
- package/src/component/windowed.js +206 -206
- package/src/component.js +401 -401
- package/src/container.js +200 -200
- package/src/contextualPopup/css/contextualPopup.css +7 -7
- package/src/contextualPopup/css/contextualPopup.css.map +1 -1
- package/src/contextualPopup/scss/contextualPopup.scss +78 -78
- package/src/contextualPopup/tpl/popup.tpl +10 -10
- package/src/contextualPopup.js +294 -294
- package/src/css/basic.css +104 -104
- package/src/css/basic.css.map +1 -1
- package/src/dashboard/css/dashboard.css +7 -7
- package/src/dashboard/css/dashboard.css.map +1 -1
- package/src/dashboard/scss/dashboard.scss +93 -93
- package/src/dashboard/tpl/dashboard.tpl +16 -16
- package/src/dashboard/tpl/dashboardMetricsList.tpl +15 -15
- package/src/dashboard.js +179 -179
- package/src/datalist/css/datalist.css +7 -7
- package/src/datalist/css/datalist.css.map +1 -1
- package/src/datalist/scss/datalist.scss +116 -116
- package/src/datalist/tpl/list.tpl +24 -24
- package/src/datalist/tpl/main.tpl +44 -44
- package/src/datalist.js +500 -500
- package/src/datatable/css/datatable.css +7 -7
- package/src/datatable/css/datatable.css.map +1 -1
- package/src/datatable/filterStrategy/filterStrategy.js +70 -70
- package/src/datatable/filterStrategy/multiple.js +126 -126
- package/src/datatable/filterStrategy/single.js +108 -108
- package/src/datatable/scss/datatable.scss +149 -149
- package/src/datatable/tpl/button.tpl +6 -6
- package/src/datatable/tpl/layout.tpl +158 -158
- package/src/datatable.js +1056 -1056
- package/src/dateRange/css/dateRange.css +7 -7
- package/src/dateRange/css/dateRange.css.map +1 -1
- package/src/dateRange/dateRange.js +341 -341
- package/src/dateRange/scss/dateRange.scss +7 -7
- package/src/dateRange/tpl/select.tpl +18 -18
- package/src/datetime/css/picker.css +7 -7
- package/src/datetime/css/picker.css.map +1 -1
- package/src/datetime/picker.js +576 -576
- package/src/datetime/scss/picker.scss +192 -192
- package/src/datetime/tpl/picker.tpl +18 -18
- package/src/deleter/undo.tpl +6 -6
- package/src/deleter.js +296 -296
- package/src/destination/css/selector.css +7 -7
- package/src/destination/css/selector.css.map +1 -1
- package/src/destination/scss/selector.scss +36 -36
- package/src/destination/selector.js +195 -195
- package/src/destination/tpl/selector.tpl +13 -13
- package/src/dialog/alert.js +70 -70
- package/src/dialog/confirm.js +85 -85
- package/src/dialog/confirmDelete.js +95 -95
- package/src/dialog/tpl/body.tpl +24 -24
- package/src/dialog/tpl/buttons.tpl +6 -6
- package/src/dialog/tpl/checkbox.tpl +5 -5
- package/src/dialog.js +517 -517
- package/src/disabler.js +230 -230
- package/src/documentViewer/css/documentViewer.css +7 -7
- package/src/documentViewer/css/documentViewer.css.map +1 -1
- package/src/documentViewer/providers/pdfViewer/fallback/viewer.js +69 -69
- package/src/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +41 -41
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.js +475 -475
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.tpl +20 -20
- package/src/documentViewer/providers/pdfViewer/pdfjs/match.tpl +1 -1
- package/src/documentViewer/providers/pdfViewer/pdfjs/page.tpl +4 -4
- package/src/documentViewer/providers/pdfViewer/pdfjs/pageView.js +318 -318
- package/src/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +167 -167
- package/src/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +451 -451
- package/src/documentViewer/providers/pdfViewer/pdfjs/textManager.js +252 -252
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.js +299 -299
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.tpl +16 -16
- package/src/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +351 -351
- package/src/documentViewer/providers/pdfViewer.js +93 -93
- package/src/documentViewer/scss/documentViewer.scss +184 -184
- package/src/documentViewer/viewerFactory.js +191 -191
- package/src/documentViewer.js +238 -238
- package/src/dropdown/css/dropdown.css +7 -7
- package/src/dropdown/css/dropdown.css.map +1 -1
- package/src/dropdown/scss/dropdown.scss +99 -99
- package/src/dropdown/tpl/dropdown.tpl +8 -8
- package/src/dropdown/tpl/list-item.tpl +4 -4
- package/src/dropdown.js +255 -255
- package/src/durationer.js +220 -220
- package/src/dynamicComponent/css/dynamicComponent.css +7 -7
- package/src/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/src/dynamicComponent/scss/dynamicComponent.scss +98 -98
- package/src/dynamicComponent/tpl/layout.tpl +17 -17
- package/src/dynamicComponent.js +553 -553
- package/src/feedback/feedback.tpl +7 -7
- package/src/feedback.js +295 -295
- package/src/figure/FigureStateActive.js +184 -184
- package/src/filesender.js +112 -112
- package/src/filter/template.tpl +5 -5
- package/src/filter.js +129 -129
- package/src/form/css/dropdownForm.css +7 -7
- package/src/form/css/dropdownForm.css.map +1 -1
- package/src/form/css/form.css +7 -7
- package/src/form/css/form.css.map +1 -1
- package/src/form/dropdownForm.js +281 -281
- package/src/form/form.js +688 -688
- package/src/form/scss/dropdownForm.scss +60 -60
- package/src/form/scss/form.scss +25 -25
- package/src/form/simpleForm.js +125 -125
- package/src/form/tpl/dropdownForm.tpl +4 -4
- package/src/form/tpl/form.tpl +7 -7
- package/src/form/validator/css/validator.css +7 -7
- package/src/form/validator/css/validator.css.map +1 -1
- package/src/form/validator/renderer.js +118 -118
- package/src/form/validator/scss/validator.scss +14 -14
- package/src/form/validator/tpl/message.tpl +1 -1
- package/src/form/validator/tpl/validator.tpl +1 -1
- package/src/form/validator/validator.js +220 -220
- package/src/form/widget/css/widget.css +7 -7
- package/src/form/widget/css/widget.css.map +1 -1
- package/src/form/widget/definitions.js +51 -51
- package/src/form/widget/loader.js +40 -40
- package/src/form/widget/providers/checkBox.js +138 -138
- package/src/form/widget/providers/comboBox.js +63 -63
- package/src/form/widget/providers/default.js +90 -90
- package/src/form/widget/providers/hidden.js +62 -62
- package/src/form/widget/providers/hiddenBox.js +152 -152
- package/src/form/widget/providers/radioBox.js +99 -99
- package/src/form/widget/providers/textArea.js +52 -52
- package/src/form/widget/providers/textBox.js +48 -48
- package/src/form/widget/scss/widget.scss +55 -55
- package/src/form/widget/tpl/checkBox.tpl +25 -25
- package/src/form/widget/tpl/comboBox.tpl +13 -13
- package/src/form/widget/tpl/hidden.tpl +1 -1
- package/src/form/widget/tpl/hiddenBox.tpl +17 -17
- package/src/form/widget/tpl/label.tpl +6 -6
- package/src/form/widget/tpl/radioBox.tpl +25 -25
- package/src/form/widget/tpl/textArea.tpl +8 -8
- package/src/form/widget/tpl/widget.tpl +8 -8
- package/src/form/widget/widget.js +372 -372
- package/src/form.js +47 -47
- package/src/formValidator/formValidator.js +253 -253
- package/src/formValidator/highlighters/highlighter.js +103 -103
- package/src/formValidator/highlighters/message.js +68 -68
- package/src/formValidator/highlighters/tooltip.js +78 -78
- package/src/generis/form/css/form.css +7 -7
- package/src/generis/form/css/form.css.map +1 -1
- package/src/generis/form/form.js +239 -239
- package/src/generis/form/readme.md +70 -70
- package/src/generis/form/scss/form.scss +23 -23
- package/src/generis/form/tpl/form.tpl +16 -16
- package/src/generis/validator/css/validator.css +7 -7
- package/src/generis/validator/css/validator.css.map +1 -1
- package/src/generis/validator/readme.md +46 -46
- package/src/generis/validator/scss/validator.scss +13 -13
- package/src/generis/validator/validator.js +128 -128
- package/src/generis/widget/checkBox/checkBox.js +112 -112
- package/src/generis/widget/checkBox/checkBox.tpl +18 -18
- package/src/generis/widget/comboBox/comboBox.js +66 -66
- package/src/generis/widget/comboBox/comboBox.tpl +12 -12
- package/src/generis/widget/css/widget.css +7 -7
- package/src/generis/widget/css/widget.css.map +1 -1
- package/src/generis/widget/hiddenBox/hiddenBox.js +131 -131
- package/src/generis/widget/hiddenBox/hiddenBox.tpl +16 -16
- package/src/generis/widget/loader.js +49 -49
- package/src/generis/widget/readme.md +59 -59
- package/src/generis/widget/scss/widget.scss +61 -61
- package/src/generis/widget/textBox/textBox.js +64 -64
- package/src/generis/widget/textBox/textBox.tpl +7 -7
- package/src/generis/widget/widget.js +164 -164
- package/src/generis/widget/widget.tpl +5 -5
- package/src/groupedComboBox.js +99 -99
- package/src/groupvalidator.js +84 -84
- package/src/hider.js +88 -88
- package/src/highlighter.js +1192 -1192
- package/src/image/ImgStateActive/extractLabel.js +29 -29
- package/src/image/ImgStateActive/helper.js +36 -36
- package/src/image/ImgStateActive/initHelper.js +137 -137
- package/src/image/ImgStateActive/initMediaEditor.js +92 -92
- package/src/image/ImgStateActive/mediaSizer.js +63 -63
- package/src/image/ImgStateActive.js +115 -115
- package/src/incrementer.js +309 -309
- package/src/inplacer.js +315 -315
- package/src/interactUtils.js +140 -140
- package/src/itemButtonList/css/item-button-list.css +23 -23
- package/src/itemButtonList/css/item-button-list.css.map +1 -1
- package/src/itemButtonList/scss/item-button-list.scss +236 -236
- package/src/itemButtonList/tpl/itemButtonList.tpl +21 -21
- package/src/itemButtonList.js +274 -274
- package/src/keyNavigation/navigableDomElement.js +285 -285
- package/src/keyNavigation/navigator.js +535 -535
- package/src/listbox/css/listbox.css +7 -7
- package/src/listbox/css/listbox.css.map +1 -1
- package/src/listbox/scss/listbox.scss +116 -116
- package/src/listbox/tpl/list.tpl +14 -14
- package/src/listbox/tpl/main.tpl +9 -9
- package/src/listbox.js +252 -252
- package/src/liststyler.js +155 -155
- package/src/loadingButton/css/button.css +7 -7
- package/src/loadingButton/css/button.css.map +1 -1
- package/src/loadingButton/loadingButton.js +110 -110
- package/src/loadingButton/scss/button.scss +41 -41
- package/src/loadingButton/tpl/button.tpl +5 -5
- package/src/lock/lock.tpl +16 -16
- package/src/lock.js +393 -393
- package/src/login/login.js +317 -317
- package/src/login/tpl/login.tpl +29 -29
- package/src/login/tpl/passwordReveal.tpl +7 -7
- package/src/maths/calculator/basicCalculator.js +55 -55
- package/src/maths/calculator/calculatorComponent.js +128 -128
- package/src/maths/calculator/core/areaBroker.js +38 -38
- package/src/maths/calculator/core/board.js +841 -841
- package/src/maths/calculator/core/expression.js +430 -430
- package/src/maths/calculator/core/labels.js +116 -116
- package/src/maths/calculator/core/plugin.js +40 -40
- package/src/maths/calculator/core/terms.js +459 -459
- package/src/maths/calculator/core/tokenizer.js +245 -245
- package/src/maths/calculator/core/tokens.js +178 -178
- package/src/maths/calculator/core/tpl/board.tpl +4 -4
- package/src/maths/calculator/css/calculator.css +7 -7
- package/src/maths/calculator/css/calculator.css.map +1 -1
- package/src/maths/calculator/defaultCalculator.js +66 -66
- package/src/maths/calculator/plugins/core/degrad.js +90 -90
- package/src/maths/calculator/plugins/core/history.js +166 -166
- package/src/maths/calculator/plugins/core/remind.js +96 -96
- package/src/maths/calculator/plugins/core/stepNavigation.js +175 -175
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/defaultTemplate.tpl +36 -36
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +91 -91
- package/src/maths/calculator/plugins/modifiers/pow10.js +143 -143
- package/src/maths/calculator/plugins/modifiers/sign.js +339 -339
- package/src/maths/calculator/plugins/screen/simpleScreen/defaultTemplate.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/history.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +190 -190
- package/src/maths/calculator/pluginsLoader.js +46 -46
- package/src/maths/calculator/scientificCalculator.js +74 -74
- package/src/maths/calculator/scss/calculator.scss +396 -396
- package/src/maths/calculator/tpl/basicKeyboard.tpl +37 -37
- package/src/maths/calculator/tpl/basicScreen.tpl +2 -2
- package/src/maths/calculator/tpl/scientificKeyboard.tpl +61 -61
- package/src/maths/calculator/tpl/scientificScreen.tpl +3 -3
- package/src/mediaEditor/mediaEditorComponent.js +141 -141
- package/src/mediaEditor/plugins/mediaAlignment/helper.js +110 -110
- package/src/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +99 -99
- package/src/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/src/mediaEditor/plugins/mediaAlignment/tpl/mediaAlignment.tpl +25 -25
- package/src/mediaEditor/plugins/mediaDimension/helper.js +190 -190
- package/src/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +561 -561
- package/src/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/src/mediaEditor/plugins/mediaDimension/tpl/mediaDimension.tpl +55 -55
- package/src/mediaEditor/tpl/editor.tpl +4 -4
- package/src/mediaplayer/css/player.css +7 -7
- package/src/mediaplayer/css/player.css.map +1 -1
- package/src/mediaplayer/players/html5.js +564 -564
- package/src/mediaplayer/players/youtube.js +323 -323
- package/src/mediaplayer/players.js +29 -29
- package/src/mediaplayer/readme.md +305 -305
- package/src/mediaplayer/scss/player.scss +569 -569
- package/src/mediaplayer/support.js +126 -126
- package/src/mediaplayer/tpl/audio.tpl +6 -6
- package/src/mediaplayer/tpl/player.tpl +37 -37
- package/src/mediaplayer/tpl/source.tpl +1 -1
- package/src/mediaplayer/tpl/video.tpl +6 -6
- package/src/mediaplayer/tpl/youtube.tpl +1 -1
- package/src/mediaplayer/utils/reminder.js +184 -184
- package/src/mediaplayer/utils/timeObserver.js +143 -143
- package/src/mediaplayer/youtubeManager.js +161 -161
- package/src/mediaplayer.js +1606 -1606
- package/src/mediasizer/mediasizer.tpl +55 -55
- package/src/mediasizer.js +635 -635
- package/src/modal.js +365 -365
- package/src/movableComponent.js +78 -78
- package/src/pageSizeSelector/tpl/pageSizeSelector.tpl +9 -9
- package/src/pageSizeSelector.js +106 -106
- package/src/pageStatus.js +147 -147
- package/src/pagination/css/pagination.css +7 -7
- package/src/pagination/css/pagination.css.map +1 -1
- package/src/pagination/paginationStrategy.js +53 -53
- package/src/pagination/providers/pages.js +161 -161
- package/src/pagination/providers/simple.js +74 -74
- package/src/pagination/providers/tpl/pages/page.tpl +1 -1
- package/src/pagination/providers/tpl/pages.tpl +8 -8
- package/src/pagination/providers/tpl/simple.tpl +7 -7
- package/src/pagination/scss/pagination.scss +111 -111
- package/src/pagination.js +237 -237
- package/src/previewer.js +300 -300
- package/src/progressbar.js +165 -165
- package/src/propertySelector/css/propertySelector.css +7 -7
- package/src/propertySelector/css/propertySelector.css.map +1 -1
- package/src/propertySelector/propertySelector.js +286 -286
- package/src/propertySelector/scss/propertySelector.scss +66 -66
- package/src/propertySelector/tpl/property-description.tpl +12 -12
- package/src/propertySelector/tpl/property-selector.tpl +6 -6
- package/src/report/feedback.tpl +11 -11
- package/src/report/layout.tpl +10 -10
- package/src/report.js +184 -184
- package/src/resource/css/selector.css +7 -7
- package/src/resource/css/selector.css.map +1 -1
- package/src/resource/filters.js +208 -208
- package/src/resource/list.js +200 -200
- package/src/resource/scss/_filters.scss +26 -26
- package/src/resource/scss/_resource-list.scss +107 -107
- package/src/resource/scss/_resource-tree.scss +205 -205
- package/src/resource/scss/selector.scss +187 -187
- package/src/resource/selectable.js +322 -322
- package/src/resource/selector.js +871 -871
- package/src/resource/tpl/filters.tpl +2 -2
- package/src/resource/tpl/list.tpl +7 -7
- package/src/resource/tpl/listNode.tpl +4 -4
- package/src/resource/tpl/selector.tpl +46 -46
- package/src/resource/tpl/tree.tpl +4 -4
- package/src/resource/tpl/treeNode.tpl +30 -30
- package/src/resource/tree.js +398 -398
- package/src/resourcemgr/css/resourcemgr.css +7 -7
- package/src/resourcemgr/css/resourcemgr.css.map +1 -1
- package/src/resourcemgr/fileBrowser.js +381 -381
- package/src/resourcemgr/filePreview.js +73 -73
- package/src/resourcemgr/fileSelector.js +322 -322
- package/src/resourcemgr/scss/resourcemgr.scss +254 -254
- package/src/resourcemgr/tpl/fileSelect.tpl +39 -39
- package/src/resourcemgr/tpl/folder.tpl +11 -11
- package/src/resourcemgr/tpl/layout.tpl +84 -84
- package/src/resourcemgr/tpl/rootFolder.tpl +13 -13
- package/src/resourcemgr/util/updatePermissions.js +53 -53
- package/src/resourcemgr.js +216 -216
- package/src/scroller.js +94 -94
- package/src/scss/basic.scss +16 -16
- package/src/searchModal/advancedSearch.js +638 -638
- package/src/searchModal/css/advancedSearch.css +7 -7
- package/src/searchModal/css/advancedSearch.css.map +1 -1
- package/src/searchModal/css/searchModal.css +7 -7
- package/src/searchModal/css/searchModal.css.map +1 -1
- package/src/searchModal/scss/advancedSearch.scss +171 -171
- package/src/searchModal/scss/searchModal.scss +393 -393
- package/src/searchModal/tpl/advanced-search.tpl +9 -9
- package/src/searchModal/tpl/info-message.tpl +3 -3
- package/src/searchModal/tpl/invalid-criteria-warning.tpl +10 -10
- package/src/searchModal/tpl/layout.tpl +27 -27
- package/src/searchModal/tpl/list-checkbox-criterion.tpl +17 -17
- package/src/searchModal/tpl/list-select-criterion.tpl +12 -12
- package/src/searchModal/tpl/text-criterion.tpl +11 -11
- package/src/searchModal.js +760 -760
- package/src/selecter.js +43 -43
- package/src/stacker.js +133 -133
- package/src/switch/css/switch.css +7 -7
- package/src/switch/css/switch.css.map +1 -1
- package/src/switch/scss/switch.scss +83 -83
- package/src/switch/switch.js +195 -195
- package/src/switch/tpl/switch.tpl +7 -7
- package/src/tableModel.js +112 -112
- package/src/tabs/css/tabs.css +12 -12
- package/src/tabs/css/tabs.css.map +1 -1
- package/src/tabs/scss/tabs.scss +50 -50
- package/src/tabs/tpl/panel.tpl +3 -3
- package/src/tabs/tpl/tabs.tpl +10 -10
- package/src/tabs.js +528 -528
- package/src/taskQueue/css/taskQueue.css +7 -7
- package/src/taskQueue/css/taskQueue.css.map +1 -1
- package/src/taskQueue/scss/taskQueue.scss +47 -47
- package/src/taskQueue/status.js +228 -228
- package/src/taskQueue/table.js +350 -350
- package/src/taskQueue/taskQueue.js +33 -33
- package/src/taskQueue/taskQueueModel.js +548 -548
- package/src/taskQueue/tpl/statusMessage.tpl +7 -7
- package/src/taskQueue.js +216 -216
- package/src/taskQueueButton/css/taskable.css +7 -7
- package/src/taskQueueButton/css/taskable.css.map +1 -1
- package/src/taskQueueButton/css/treeButton.css +7 -7
- package/src/taskQueueButton/css/treeButton.css.map +1 -1
- package/src/taskQueueButton/scss/taskable.scss +4 -4
- package/src/taskQueueButton/scss/treeButton.scss +34 -34
- package/src/taskQueueButton/standardButton.js +108 -108
- package/src/taskQueueButton/taskable.js +202 -202
- package/src/taskQueueButton/tpl/report.tpl +5 -5
- package/src/taskQueueButton/tpl/treeButton.tpl +6 -6
- package/src/taskQueueButton/treeButton.js +108 -108
- package/src/themeLoader.js +252 -252
- package/src/themes.js +162 -162
- package/src/toggler.js +200 -200
- package/src/tooltip/default.tpl +3 -3
- package/src/tooltip.js +160 -160
- package/src/tooltipster.js +25 -25
- package/src/transformer.js +327 -327
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/src/tristateCheckboxGroup/scss/tristateCheckboxGroup.scss +15 -15
- package/src/tristateCheckboxGroup/tpl/li.tpl +6 -6
- package/src/tristateCheckboxGroup.js +207 -207
- package/src/uploader/fileEntry.tpl +6 -6
- package/src/uploader/uploader.tpl +32 -32
- package/src/uploader.js +594 -594
- package/src/validator/Report.js +10 -10
- package/src/validator/Validator.js +108 -108
- package/src/validator/validators.js +217 -217
- package/src/validator.js +262 -262
- package/src/waitForMedia.js +82 -82
- package/src/waitingDialog/css/waitingDialog.css +7 -7
- package/src/waitingDialog/css/waitingDialog.css.map +1 -1
- package/src/waitingDialog/scss/waitingDialog.scss +34 -34
- package/src/waitingDialog/waitingDialog.js +240 -240
|
@@ -1,535 +1,535 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This program is free software; you can redistribute it and/or
|
|
3
|
-
* modify it under the terms of the GNU General Public License
|
|
4
|
-
* as published by the Free Software Foundation; under version 2
|
|
5
|
-
* of the License (non-upgradable).
|
|
6
|
-
*
|
|
7
|
-
* This program is distributed in the hope that it will be useful,
|
|
8
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
-
* GNU General Public License for more details.
|
|
11
|
-
*
|
|
12
|
-
* You should have received a copy of the GNU General Public License
|
|
13
|
-
* along with this program; if not, write to the Free Software
|
|
14
|
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
15
|
-
*
|
|
16
|
-
* Copyright (c) 2017-2020 (original work) Open Assessment Technologies SA;
|
|
17
|
-
*
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
-
* Create a navigator group to enable keyboard navigation between elements
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* const $navigationBar = $('#navigation-bar');
|
|
26
|
-
* const $buttons = $navigationBar.find('li');
|
|
27
|
-
* const navigableElements = domNavigableElement.createFromDoms($buttons);
|
|
28
|
-
* keyNavigator({
|
|
29
|
-
* id : 'navigation-toolbar',
|
|
30
|
-
* group : $navigationBar,
|
|
31
|
-
* elements : navigableElements,
|
|
32
|
-
* defaultPosition : 0
|
|
33
|
-
* }).on('right down', function(){
|
|
34
|
-
* this.next();
|
|
35
|
-
* }).on('left up', function(){
|
|
36
|
-
* this.previous();
|
|
37
|
-
* }).on('activate', function(cursor){
|
|
38
|
-
* cursor.navigable.getElement().click();
|
|
39
|
-
* });
|
|
40
|
-
*
|
|
41
|
-
* @author Sam <sam@taotesting.com>
|
|
42
|
-
*/
|
|
43
|
-
import $ from 'jquery';
|
|
44
|
-
import _ from 'lodash';
|
|
45
|
-
import eventifier from 'core/eventifier';
|
|
46
|
-
import navigableDomElement from 'ui/keyNavigation/navigableDomElement';
|
|
47
|
-
|
|
48
|
-
const defaults = {
|
|
49
|
-
defaultPosition: -1,
|
|
50
|
-
keepState: false,
|
|
51
|
-
loop: false,
|
|
52
|
-
propagateTab: true
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Create a keyNavigator
|
|
57
|
-
*
|
|
58
|
-
* @param config - the config
|
|
59
|
-
* @param {String} config.id - global unique id to define this group
|
|
60
|
-
* @param {jQuery} config.elements - the group of element to be keyboard-navigated
|
|
61
|
-
* @param {jQuery} [config.group] - the container the group of elements belong to
|
|
62
|
-
* @param {Number|Function} [config.defaultPosition=0] - the default position the group should set the focus on (could be a function to compute the position)
|
|
63
|
-
* @param {Boolean} [config.keepState=false] - define if the position should be saved in memory after the group blurs and re-focuses
|
|
64
|
-
* @param {Boolean} [config.loop=false] - define if the navigation should loop after reaching the last or the first element
|
|
65
|
-
* @param {Boolean} [config.propagateTab=true] - allows the key event to propagate when the Tab key is pressed.
|
|
66
|
-
* @returns {keyNavigator}
|
|
67
|
-
*/
|
|
68
|
-
export default function keyNavigatorFactory(config) {
|
|
69
|
-
const navigatorConfig = Object.assign({}, defaults, config || {});
|
|
70
|
-
|
|
71
|
-
const id = navigatorConfig.id || _.uniqueId('navigator_');
|
|
72
|
-
const $group =
|
|
73
|
-
navigatorConfig.group &&
|
|
74
|
-
$(navigatorConfig.group).addClass('key-navigation-group').attr('data-navigation-id', id);
|
|
75
|
-
if (navigatorConfig.group && (!$group.length || !$.contains(document.body, $group.get(0)))) {
|
|
76
|
-
throw new TypeError('group element does not exist');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const navigableElements = navigatorConfig.elements || [];
|
|
80
|
-
let lastPosition = -1;
|
|
81
|
-
let focusOutObserver;
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Checks if the navigable element is available
|
|
85
|
-
* @param {navigableDomElement} navigable
|
|
86
|
-
* @returns {Boolean}
|
|
87
|
-
*/
|
|
88
|
-
const isNavigableAvailable = navigable => navigable && navigable.isVisible() && navigable.isEnabled();
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Checks if the navigable element is focused
|
|
92
|
-
* @param {navigableDomElement} navigable
|
|
93
|
-
* @returns {Boolean}
|
|
94
|
-
*/
|
|
95
|
-
const isNavigableFocused = navigable => isNavigableAvailable(navigable) && navigable.isFocused();
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Gets the closest allowed position to the right
|
|
99
|
-
*
|
|
100
|
-
* @param {Number} fromPosition - the starting position
|
|
101
|
-
* @returns {Number}
|
|
102
|
-
*/
|
|
103
|
-
const getClosestPositionRight = fromPosition => {
|
|
104
|
-
for (let pos = fromPosition; pos < navigableElements.length; pos++) {
|
|
105
|
-
if (isNavigableAvailable(navigableElements[pos])) {
|
|
106
|
-
return pos;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return -1;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Gets the closest allowed position to the left
|
|
114
|
-
*
|
|
115
|
-
* @param {Number} fromPosition - the starting position
|
|
116
|
-
* @returns {Number}
|
|
117
|
-
*/
|
|
118
|
-
const getClosestPositionLeft = fromPosition => {
|
|
119
|
-
for (let pos = fromPosition; pos >= 0; pos--) {
|
|
120
|
-
if (isNavigableAvailable(navigableElements[pos])) {
|
|
121
|
-
return pos;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return -1;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* The navigation group object
|
|
129
|
-
*
|
|
130
|
-
* @typedef keyNavigator
|
|
131
|
-
*/
|
|
132
|
-
const keyNavigator = eventifier({
|
|
133
|
-
/**
|
|
134
|
-
* Setups the navigator
|
|
135
|
-
* @returns {keyNavigator}
|
|
136
|
-
*/
|
|
137
|
-
init() {
|
|
138
|
-
if ($group) {
|
|
139
|
-
//add the focusin and focus out class for group highlighting
|
|
140
|
-
$group
|
|
141
|
-
.on(`focusin.${this.getId()}`, () => {
|
|
142
|
-
if (this.isFocused()) {
|
|
143
|
-
$group.addClass('focusin');
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
.on(`focusout.${this.getId()}`, () => {
|
|
147
|
-
if (!this.isFocused()) {
|
|
148
|
-
$group.removeClass('focusin');
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
focusOutObserver = new MutationObserver(() => {
|
|
153
|
-
if (!this.isVisible() && $group.hasClass('focusin')) {
|
|
154
|
-
$group.removeClass('focusin');
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
$group.each(index => {
|
|
158
|
-
focusOutObserver.observe($group.get(index), {
|
|
159
|
-
childList: true,
|
|
160
|
-
subtree: true
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
navigableElements.forEach(navigable => {
|
|
166
|
-
if (!navigableDomElement.isNavigableElement(navigable)) {
|
|
167
|
-
throw new TypeError('not a valid navigable element');
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (navigable.getType() === 'element') {
|
|
171
|
-
navigable.init({ propagateTab: navigatorConfig.propagateTab });
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
navigable
|
|
175
|
-
.off(`.${this.getId()}`)
|
|
176
|
-
.on(`key.${this.getId()}`, (key, el) => this.trigger('key', key, el))
|
|
177
|
-
.on(`focus.${this.getId()}`, () => {
|
|
178
|
-
lastPosition = this.getCurrentPosition();
|
|
179
|
-
})
|
|
180
|
-
.on(`blur.${this.getId()}`, () => {
|
|
181
|
-
const cursor = this.getCursorAt(lastPosition);
|
|
182
|
-
if (cursor.navigable) {
|
|
183
|
-
this.trigger('blur', cursor);
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
return this;
|
|
189
|
-
},
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Destroys and cleanup
|
|
193
|
-
* @returns {keyNavigator}
|
|
194
|
-
*/
|
|
195
|
-
destroy() {
|
|
196
|
-
if ($group) {
|
|
197
|
-
$group.off(`.${this.getId()}`).removeClass('focusin');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (focusOutObserver) {
|
|
201
|
-
focusOutObserver.disconnect();
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
navigableElements.forEach(navigable => {
|
|
205
|
-
navigable.off(`.${this.getId}`);
|
|
206
|
-
|
|
207
|
-
if (navigable.getType() === 'element') {
|
|
208
|
-
navigable.destroy();
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
lastPosition = -1;
|
|
213
|
-
|
|
214
|
-
return this;
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Gets the navigation group id
|
|
219
|
-
* @returns {String}
|
|
220
|
-
*/
|
|
221
|
-
getId() {
|
|
222
|
-
return id;
|
|
223
|
-
},
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Gets the type of navigable element
|
|
227
|
-
* @returns {String}
|
|
228
|
-
*/
|
|
229
|
-
getType() {
|
|
230
|
-
return 'navigator';
|
|
231
|
-
},
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Gets the defined group the navigator group belongs to
|
|
235
|
-
* @returns {jQuery}
|
|
236
|
-
*/
|
|
237
|
-
getElement() {
|
|
238
|
-
return $group;
|
|
239
|
-
},
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Returns the current cursor of the navigator
|
|
243
|
-
* @returns {Object}
|
|
244
|
-
*/
|
|
245
|
-
getCursor() {
|
|
246
|
-
return this.getCursorAt(this.getCurrentPosition());
|
|
247
|
-
},
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Gets a navigable at a given position
|
|
251
|
-
* @param {Number} position
|
|
252
|
-
* @returns {navigableDomElement}
|
|
253
|
-
*/
|
|
254
|
-
getNavigableAt(position) {
|
|
255
|
-
if (position >= 0 && navigableElements[position]) {
|
|
256
|
-
return navigableElements[position];
|
|
257
|
-
}
|
|
258
|
-
return null;
|
|
259
|
-
},
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Gets the cursor at a given position
|
|
263
|
-
* @param {Number} position
|
|
264
|
-
* @returns {Object}
|
|
265
|
-
*/
|
|
266
|
-
getCursorAt(position) {
|
|
267
|
-
const navigable = this.getNavigableAt(position);
|
|
268
|
-
return { position: navigable ? position : -1, navigable };
|
|
269
|
-
},
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Sets the focus to the element at the given position
|
|
273
|
-
*
|
|
274
|
-
* @param {Number} position
|
|
275
|
-
* @returns {keyNavigator}
|
|
276
|
-
* @fires blur on the previous cursor
|
|
277
|
-
* @fires focus on the new cursor
|
|
278
|
-
*/
|
|
279
|
-
setCursorAt(position) {
|
|
280
|
-
if (navigableElements[position]) {
|
|
281
|
-
const cursor = this.getCursorAt(lastPosition);
|
|
282
|
-
if (cursor.navigable) {
|
|
283
|
-
/**
|
|
284
|
-
* @event blur
|
|
285
|
-
* @param {Object} cursor
|
|
286
|
-
*/
|
|
287
|
-
this.trigger('blur', cursor);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const direction = position - lastPosition;
|
|
291
|
-
lastPosition = position;
|
|
292
|
-
navigableElements[position].focus(direction);
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* @event focus
|
|
296
|
-
* @param {Object} cursor
|
|
297
|
-
*/
|
|
298
|
-
this.trigger('focus', this.getCursor());
|
|
299
|
-
}
|
|
300
|
-
return this;
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Returns the current position in the navigator
|
|
305
|
-
* @returns {Number}
|
|
306
|
-
*/
|
|
307
|
-
getCurrentPosition() {
|
|
308
|
-
if (document.activeElement) {
|
|
309
|
-
return _.findIndex(navigableElements, isNavigableFocused);
|
|
310
|
-
}
|
|
311
|
-
return -1;
|
|
312
|
-
},
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Returns the current navigable in the navigator
|
|
316
|
-
* @returns {Object}
|
|
317
|
-
*/
|
|
318
|
-
getCurrentNavigable() {
|
|
319
|
-
const position = this.getCurrentPosition();
|
|
320
|
-
if (position >= 0) {
|
|
321
|
-
return navigableElements[position];
|
|
322
|
-
}
|
|
323
|
-
return null;
|
|
324
|
-
},
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Returns the array of navigable objects composing the navigator
|
|
328
|
-
* @returns {Array}
|
|
329
|
-
*/
|
|
330
|
-
getNavigableElements() {
|
|
331
|
-
return navigableElements.slice();
|
|
332
|
-
},
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Checks if the group and at least one navigable element is visible
|
|
336
|
-
* @returns {boolean}
|
|
337
|
-
*/
|
|
338
|
-
isVisible() {
|
|
339
|
-
if (!$group || $group.is(':visible')) {
|
|
340
|
-
return navigableElements.some(navigable => navigable.isVisible());
|
|
341
|
-
}
|
|
342
|
-
return false;
|
|
343
|
-
},
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Checks if the group and at least one navigable element is enabled
|
|
347
|
-
* @returns {Boolean}
|
|
348
|
-
*/
|
|
349
|
-
isEnabled() {
|
|
350
|
-
if (!$group || !$group.is(':disabled')) {
|
|
351
|
-
return navigableElements.some(navigable => navigable.isEnabled());
|
|
352
|
-
}
|
|
353
|
-
return false;
|
|
354
|
-
},
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Checks if at least one navigable element is focused
|
|
358
|
-
* @returns {Boolean}
|
|
359
|
-
*/
|
|
360
|
-
isFocused() {
|
|
361
|
-
if (document.activeElement) {
|
|
362
|
-
return navigableElements.some(navigable => navigable.isFocused());
|
|
363
|
-
}
|
|
364
|
-
return false;
|
|
365
|
-
},
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Sets the focus on the first available focusable element
|
|
369
|
-
* @returns {keyNavigator}
|
|
370
|
-
*/
|
|
371
|
-
first() {
|
|
372
|
-
this.setCursorAt(getClosestPositionRight(0));
|
|
373
|
-
return this;
|
|
374
|
-
},
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Sets the focus on the last available focusable element
|
|
378
|
-
* @returns {keyNavigator}
|
|
379
|
-
*/
|
|
380
|
-
last() {
|
|
381
|
-
this.setCursorAt(getClosestPositionLeft(navigableElements.length - 1));
|
|
382
|
-
return this;
|
|
383
|
-
},
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Moves the cursor to the next position
|
|
387
|
-
*
|
|
388
|
-
* @returns {keyNavigator}
|
|
389
|
-
* @fires upperbound when we cannot move further
|
|
390
|
-
* @fires next when the cursor successfully moved to the next position
|
|
391
|
-
*/
|
|
392
|
-
next() {
|
|
393
|
-
let position = this.getCurrentPosition();
|
|
394
|
-
if (position >= 0) {
|
|
395
|
-
position = getClosestPositionRight(position + 1);
|
|
396
|
-
if (position >= 0) {
|
|
397
|
-
this.setCursorAt(position);
|
|
398
|
-
} else if (navigatorConfig.loop) {
|
|
399
|
-
this.first();
|
|
400
|
-
} else {
|
|
401
|
-
/**
|
|
402
|
-
* reaching the end of the list
|
|
403
|
-
* @event upperbound
|
|
404
|
-
*/
|
|
405
|
-
this.trigger('upperbound');
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
const cursor = this.getCursor();
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* @event next
|
|
412
|
-
* @param {Object} cursor
|
|
413
|
-
*/
|
|
414
|
-
this.trigger('next', cursor);
|
|
415
|
-
} else {
|
|
416
|
-
this.first();
|
|
417
|
-
}
|
|
418
|
-
return this;
|
|
419
|
-
},
|
|
420
|
-
|
|
421
|
-
/**
|
|
422
|
-
* Moves the cursor to the previous position
|
|
423
|
-
*
|
|
424
|
-
* @returns {keyNavigator}
|
|
425
|
-
* @fires lowerbound when we cannot move lower
|
|
426
|
-
* @fires previous when the cursor successfully moved to the previous position
|
|
427
|
-
*/
|
|
428
|
-
previous() {
|
|
429
|
-
let position = this.getCurrentPosition();
|
|
430
|
-
if (position >= 0) {
|
|
431
|
-
position = getClosestPositionLeft(position - 1);
|
|
432
|
-
if (position >= 0) {
|
|
433
|
-
this.setCursorAt(position);
|
|
434
|
-
} else if (navigatorConfig.loop) {
|
|
435
|
-
this.last();
|
|
436
|
-
} else {
|
|
437
|
-
/**
|
|
438
|
-
* reaching the end of the list
|
|
439
|
-
* @event lowerbound
|
|
440
|
-
*/
|
|
441
|
-
this.trigger('lowerbound');
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
const cursor = this.getCursor();
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* @event previous
|
|
448
|
-
* @param {Object} cursor
|
|
449
|
-
*/
|
|
450
|
-
this.trigger('previous', cursor);
|
|
451
|
-
} else {
|
|
452
|
-
this.first();
|
|
453
|
-
}
|
|
454
|
-
return this;
|
|
455
|
-
},
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* Activates the focused element, if any
|
|
459
|
-
*
|
|
460
|
-
* @param {Object} target
|
|
461
|
-
* @returns {keyNavigator}
|
|
462
|
-
* @fires activate
|
|
463
|
-
*/
|
|
464
|
-
activate(target) {
|
|
465
|
-
const cursor = this.getCursor();
|
|
466
|
-
if (cursor.navigable) {
|
|
467
|
-
/**
|
|
468
|
-
* @event activate
|
|
469
|
-
* @param {Object} cursor
|
|
470
|
-
* @param {Object} target
|
|
471
|
-
*/
|
|
472
|
-
this.trigger('activate', cursor, target);
|
|
473
|
-
}
|
|
474
|
-
return this;
|
|
475
|
-
},
|
|
476
|
-
|
|
477
|
-
/**
|
|
478
|
-
* Blurs the focused element, if any
|
|
479
|
-
* @returns {keyNavigator}
|
|
480
|
-
*/
|
|
481
|
-
blur() {
|
|
482
|
-
const cursor = this.getCursorAt(lastPosition);
|
|
483
|
-
if (cursor.navigable) {
|
|
484
|
-
cursor.navigable.blur();
|
|
485
|
-
}
|
|
486
|
-
return this;
|
|
487
|
-
},
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Sets the focus to the current element
|
|
491
|
-
* @param {Number} [direction=1] - The direction that lead to this navigator.
|
|
492
|
-
* This will condition which element to focus if there is no default.
|
|
493
|
-
* A positive direction (or null) will lead to the first focusable element.
|
|
494
|
-
* A negative direction will lead to the last focusable element.
|
|
495
|
-
* @returns {keyNavigator}
|
|
496
|
-
*/
|
|
497
|
-
focus(direction = 1) {
|
|
498
|
-
let position = -1;
|
|
499
|
-
|
|
500
|
-
// try to get the default position
|
|
501
|
-
if (navigatorConfig.keepState && this.getNavigableAt(lastPosition)) {
|
|
502
|
-
position = lastPosition;
|
|
503
|
-
} else {
|
|
504
|
-
lastPosition = -1;
|
|
505
|
-
if ('undefined' !== typeof navigatorConfig.defaultPosition) {
|
|
506
|
-
if (_.isFunction(navigatorConfig.defaultPosition)) {
|
|
507
|
-
position = navigatorConfig.defaultPosition(this.getNavigableElements(), direction);
|
|
508
|
-
} else {
|
|
509
|
-
position = navigatorConfig.defaultPosition;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
// select the default position with respect to the movement direction
|
|
515
|
-
if (position === -1) {
|
|
516
|
-
if (direction < 0) {
|
|
517
|
-
position = getClosestPositionLeft(navigableElements.length - 1);
|
|
518
|
-
} else {
|
|
519
|
-
position = 0;
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
this.setCursorAt(getClosestPositionRight(position));
|
|
524
|
-
return this;
|
|
525
|
-
}
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
return keyNavigator.init().on('key', (key, el) => {
|
|
529
|
-
if (key === 'space' || key === 'enter') {
|
|
530
|
-
keyNavigator.activate(el);
|
|
531
|
-
} else {
|
|
532
|
-
keyNavigator.trigger(key, el);
|
|
533
|
-
}
|
|
534
|
-
});
|
|
535
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* This program is free software; you can redistribute it and/or
|
|
3
|
+
* modify it under the terms of the GNU General Public License
|
|
4
|
+
* as published by the Free Software Foundation; under version 2
|
|
5
|
+
* of the License (non-upgradable).
|
|
6
|
+
*
|
|
7
|
+
* This program is distributed in the hope that it will be useful,
|
|
8
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
* GNU General Public License for more details.
|
|
11
|
+
*
|
|
12
|
+
* You should have received a copy of the GNU General Public License
|
|
13
|
+
* along with this program; if not, write to the Free Software
|
|
14
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
15
|
+
*
|
|
16
|
+
* Copyright (c) 2017-2020 (original work) Open Assessment Technologies SA;
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* Create a navigator group to enable keyboard navigation between elements
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const $navigationBar = $('#navigation-bar');
|
|
26
|
+
* const $buttons = $navigationBar.find('li');
|
|
27
|
+
* const navigableElements = domNavigableElement.createFromDoms($buttons);
|
|
28
|
+
* keyNavigator({
|
|
29
|
+
* id : 'navigation-toolbar',
|
|
30
|
+
* group : $navigationBar,
|
|
31
|
+
* elements : navigableElements,
|
|
32
|
+
* defaultPosition : 0
|
|
33
|
+
* }).on('right down', function(){
|
|
34
|
+
* this.next();
|
|
35
|
+
* }).on('left up', function(){
|
|
36
|
+
* this.previous();
|
|
37
|
+
* }).on('activate', function(cursor){
|
|
38
|
+
* cursor.navigable.getElement().click();
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* @author Sam <sam@taotesting.com>
|
|
42
|
+
*/
|
|
43
|
+
import $ from 'jquery';
|
|
44
|
+
import _ from 'lodash';
|
|
45
|
+
import eventifier from 'core/eventifier';
|
|
46
|
+
import navigableDomElement from 'ui/keyNavigation/navigableDomElement';
|
|
47
|
+
|
|
48
|
+
const defaults = {
|
|
49
|
+
defaultPosition: -1,
|
|
50
|
+
keepState: false,
|
|
51
|
+
loop: false,
|
|
52
|
+
propagateTab: true
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create a keyNavigator
|
|
57
|
+
*
|
|
58
|
+
* @param config - the config
|
|
59
|
+
* @param {String} config.id - global unique id to define this group
|
|
60
|
+
* @param {jQuery} config.elements - the group of element to be keyboard-navigated
|
|
61
|
+
* @param {jQuery} [config.group] - the container the group of elements belong to
|
|
62
|
+
* @param {Number|Function} [config.defaultPosition=0] - the default position the group should set the focus on (could be a function to compute the position)
|
|
63
|
+
* @param {Boolean} [config.keepState=false] - define if the position should be saved in memory after the group blurs and re-focuses
|
|
64
|
+
* @param {Boolean} [config.loop=false] - define if the navigation should loop after reaching the last or the first element
|
|
65
|
+
* @param {Boolean} [config.propagateTab=true] - allows the key event to propagate when the Tab key is pressed.
|
|
66
|
+
* @returns {keyNavigator}
|
|
67
|
+
*/
|
|
68
|
+
export default function keyNavigatorFactory(config) {
|
|
69
|
+
const navigatorConfig = Object.assign({}, defaults, config || {});
|
|
70
|
+
|
|
71
|
+
const id = navigatorConfig.id || _.uniqueId('navigator_');
|
|
72
|
+
const $group =
|
|
73
|
+
navigatorConfig.group &&
|
|
74
|
+
$(navigatorConfig.group).addClass('key-navigation-group').attr('data-navigation-id', id);
|
|
75
|
+
if (navigatorConfig.group && (!$group.length || !$.contains(document.body, $group.get(0)))) {
|
|
76
|
+
throw new TypeError('group element does not exist');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const navigableElements = navigatorConfig.elements || [];
|
|
80
|
+
let lastPosition = -1;
|
|
81
|
+
let focusOutObserver;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Checks if the navigable element is available
|
|
85
|
+
* @param {navigableDomElement} navigable
|
|
86
|
+
* @returns {Boolean}
|
|
87
|
+
*/
|
|
88
|
+
const isNavigableAvailable = navigable => navigable && navigable.isVisible() && navigable.isEnabled();
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Checks if the navigable element is focused
|
|
92
|
+
* @param {navigableDomElement} navigable
|
|
93
|
+
* @returns {Boolean}
|
|
94
|
+
*/
|
|
95
|
+
const isNavigableFocused = navigable => isNavigableAvailable(navigable) && navigable.isFocused();
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Gets the closest allowed position to the right
|
|
99
|
+
*
|
|
100
|
+
* @param {Number} fromPosition - the starting position
|
|
101
|
+
* @returns {Number}
|
|
102
|
+
*/
|
|
103
|
+
const getClosestPositionRight = fromPosition => {
|
|
104
|
+
for (let pos = fromPosition; pos < navigableElements.length; pos++) {
|
|
105
|
+
if (isNavigableAvailable(navigableElements[pos])) {
|
|
106
|
+
return pos;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return -1;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Gets the closest allowed position to the left
|
|
114
|
+
*
|
|
115
|
+
* @param {Number} fromPosition - the starting position
|
|
116
|
+
* @returns {Number}
|
|
117
|
+
*/
|
|
118
|
+
const getClosestPositionLeft = fromPosition => {
|
|
119
|
+
for (let pos = fromPosition; pos >= 0; pos--) {
|
|
120
|
+
if (isNavigableAvailable(navigableElements[pos])) {
|
|
121
|
+
return pos;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return -1;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The navigation group object
|
|
129
|
+
*
|
|
130
|
+
* @typedef keyNavigator
|
|
131
|
+
*/
|
|
132
|
+
const keyNavigator = eventifier({
|
|
133
|
+
/**
|
|
134
|
+
* Setups the navigator
|
|
135
|
+
* @returns {keyNavigator}
|
|
136
|
+
*/
|
|
137
|
+
init() {
|
|
138
|
+
if ($group) {
|
|
139
|
+
//add the focusin and focus out class for group highlighting
|
|
140
|
+
$group
|
|
141
|
+
.on(`focusin.${this.getId()}`, () => {
|
|
142
|
+
if (this.isFocused()) {
|
|
143
|
+
$group.addClass('focusin');
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
.on(`focusout.${this.getId()}`, () => {
|
|
147
|
+
if (!this.isFocused()) {
|
|
148
|
+
$group.removeClass('focusin');
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
focusOutObserver = new MutationObserver(() => {
|
|
153
|
+
if (!this.isVisible() && $group.hasClass('focusin')) {
|
|
154
|
+
$group.removeClass('focusin');
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
$group.each(index => {
|
|
158
|
+
focusOutObserver.observe($group.get(index), {
|
|
159
|
+
childList: true,
|
|
160
|
+
subtree: true
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
navigableElements.forEach(navigable => {
|
|
166
|
+
if (!navigableDomElement.isNavigableElement(navigable)) {
|
|
167
|
+
throw new TypeError('not a valid navigable element');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (navigable.getType() === 'element') {
|
|
171
|
+
navigable.init({ propagateTab: navigatorConfig.propagateTab });
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
navigable
|
|
175
|
+
.off(`.${this.getId()}`)
|
|
176
|
+
.on(`key.${this.getId()}`, (key, el) => this.trigger('key', key, el))
|
|
177
|
+
.on(`focus.${this.getId()}`, () => {
|
|
178
|
+
lastPosition = this.getCurrentPosition();
|
|
179
|
+
})
|
|
180
|
+
.on(`blur.${this.getId()}`, () => {
|
|
181
|
+
const cursor = this.getCursorAt(lastPosition);
|
|
182
|
+
if (cursor.navigable) {
|
|
183
|
+
this.trigger('blur', cursor);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
return this;
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Destroys and cleanup
|
|
193
|
+
* @returns {keyNavigator}
|
|
194
|
+
*/
|
|
195
|
+
destroy() {
|
|
196
|
+
if ($group) {
|
|
197
|
+
$group.off(`.${this.getId()}`).removeClass('focusin');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (focusOutObserver) {
|
|
201
|
+
focusOutObserver.disconnect();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
navigableElements.forEach(navigable => {
|
|
205
|
+
navigable.off(`.${this.getId}`);
|
|
206
|
+
|
|
207
|
+
if (navigable.getType() === 'element') {
|
|
208
|
+
navigable.destroy();
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
lastPosition = -1;
|
|
213
|
+
|
|
214
|
+
return this;
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Gets the navigation group id
|
|
219
|
+
* @returns {String}
|
|
220
|
+
*/
|
|
221
|
+
getId() {
|
|
222
|
+
return id;
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Gets the type of navigable element
|
|
227
|
+
* @returns {String}
|
|
228
|
+
*/
|
|
229
|
+
getType() {
|
|
230
|
+
return 'navigator';
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Gets the defined group the navigator group belongs to
|
|
235
|
+
* @returns {jQuery}
|
|
236
|
+
*/
|
|
237
|
+
getElement() {
|
|
238
|
+
return $group;
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Returns the current cursor of the navigator
|
|
243
|
+
* @returns {Object}
|
|
244
|
+
*/
|
|
245
|
+
getCursor() {
|
|
246
|
+
return this.getCursorAt(this.getCurrentPosition());
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Gets a navigable at a given position
|
|
251
|
+
* @param {Number} position
|
|
252
|
+
* @returns {navigableDomElement}
|
|
253
|
+
*/
|
|
254
|
+
getNavigableAt(position) {
|
|
255
|
+
if (position >= 0 && navigableElements[position]) {
|
|
256
|
+
return navigableElements[position];
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Gets the cursor at a given position
|
|
263
|
+
* @param {Number} position
|
|
264
|
+
* @returns {Object}
|
|
265
|
+
*/
|
|
266
|
+
getCursorAt(position) {
|
|
267
|
+
const navigable = this.getNavigableAt(position);
|
|
268
|
+
return { position: navigable ? position : -1, navigable };
|
|
269
|
+
},
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Sets the focus to the element at the given position
|
|
273
|
+
*
|
|
274
|
+
* @param {Number} position
|
|
275
|
+
* @returns {keyNavigator}
|
|
276
|
+
* @fires blur on the previous cursor
|
|
277
|
+
* @fires focus on the new cursor
|
|
278
|
+
*/
|
|
279
|
+
setCursorAt(position) {
|
|
280
|
+
if (navigableElements[position]) {
|
|
281
|
+
const cursor = this.getCursorAt(lastPosition);
|
|
282
|
+
if (cursor.navigable) {
|
|
283
|
+
/**
|
|
284
|
+
* @event blur
|
|
285
|
+
* @param {Object} cursor
|
|
286
|
+
*/
|
|
287
|
+
this.trigger('blur', cursor);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const direction = position - lastPosition;
|
|
291
|
+
lastPosition = position;
|
|
292
|
+
navigableElements[position].focus(direction);
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* @event focus
|
|
296
|
+
* @param {Object} cursor
|
|
297
|
+
*/
|
|
298
|
+
this.trigger('focus', this.getCursor());
|
|
299
|
+
}
|
|
300
|
+
return this;
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Returns the current position in the navigator
|
|
305
|
+
* @returns {Number}
|
|
306
|
+
*/
|
|
307
|
+
getCurrentPosition() {
|
|
308
|
+
if (document.activeElement) {
|
|
309
|
+
return _.findIndex(navigableElements, isNavigableFocused);
|
|
310
|
+
}
|
|
311
|
+
return -1;
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Returns the current navigable in the navigator
|
|
316
|
+
* @returns {Object}
|
|
317
|
+
*/
|
|
318
|
+
getCurrentNavigable() {
|
|
319
|
+
const position = this.getCurrentPosition();
|
|
320
|
+
if (position >= 0) {
|
|
321
|
+
return navigableElements[position];
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
},
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Returns the array of navigable objects composing the navigator
|
|
328
|
+
* @returns {Array}
|
|
329
|
+
*/
|
|
330
|
+
getNavigableElements() {
|
|
331
|
+
return navigableElements.slice();
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Checks if the group and at least one navigable element is visible
|
|
336
|
+
* @returns {boolean}
|
|
337
|
+
*/
|
|
338
|
+
isVisible() {
|
|
339
|
+
if (!$group || $group.is(':visible')) {
|
|
340
|
+
return navigableElements.some(navigable => navigable.isVisible());
|
|
341
|
+
}
|
|
342
|
+
return false;
|
|
343
|
+
},
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Checks if the group and at least one navigable element is enabled
|
|
347
|
+
* @returns {Boolean}
|
|
348
|
+
*/
|
|
349
|
+
isEnabled() {
|
|
350
|
+
if (!$group || !$group.is(':disabled')) {
|
|
351
|
+
return navigableElements.some(navigable => navigable.isEnabled());
|
|
352
|
+
}
|
|
353
|
+
return false;
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Checks if at least one navigable element is focused
|
|
358
|
+
* @returns {Boolean}
|
|
359
|
+
*/
|
|
360
|
+
isFocused() {
|
|
361
|
+
if (document.activeElement) {
|
|
362
|
+
return navigableElements.some(navigable => navigable.isFocused());
|
|
363
|
+
}
|
|
364
|
+
return false;
|
|
365
|
+
},
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Sets the focus on the first available focusable element
|
|
369
|
+
* @returns {keyNavigator}
|
|
370
|
+
*/
|
|
371
|
+
first() {
|
|
372
|
+
this.setCursorAt(getClosestPositionRight(0));
|
|
373
|
+
return this;
|
|
374
|
+
},
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Sets the focus on the last available focusable element
|
|
378
|
+
* @returns {keyNavigator}
|
|
379
|
+
*/
|
|
380
|
+
last() {
|
|
381
|
+
this.setCursorAt(getClosestPositionLeft(navigableElements.length - 1));
|
|
382
|
+
return this;
|
|
383
|
+
},
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Moves the cursor to the next position
|
|
387
|
+
*
|
|
388
|
+
* @returns {keyNavigator}
|
|
389
|
+
* @fires upperbound when we cannot move further
|
|
390
|
+
* @fires next when the cursor successfully moved to the next position
|
|
391
|
+
*/
|
|
392
|
+
next() {
|
|
393
|
+
let position = this.getCurrentPosition();
|
|
394
|
+
if (position >= 0) {
|
|
395
|
+
position = getClosestPositionRight(position + 1);
|
|
396
|
+
if (position >= 0) {
|
|
397
|
+
this.setCursorAt(position);
|
|
398
|
+
} else if (navigatorConfig.loop) {
|
|
399
|
+
this.first();
|
|
400
|
+
} else {
|
|
401
|
+
/**
|
|
402
|
+
* reaching the end of the list
|
|
403
|
+
* @event upperbound
|
|
404
|
+
*/
|
|
405
|
+
this.trigger('upperbound');
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const cursor = this.getCursor();
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* @event next
|
|
412
|
+
* @param {Object} cursor
|
|
413
|
+
*/
|
|
414
|
+
this.trigger('next', cursor);
|
|
415
|
+
} else {
|
|
416
|
+
this.first();
|
|
417
|
+
}
|
|
418
|
+
return this;
|
|
419
|
+
},
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Moves the cursor to the previous position
|
|
423
|
+
*
|
|
424
|
+
* @returns {keyNavigator}
|
|
425
|
+
* @fires lowerbound when we cannot move lower
|
|
426
|
+
* @fires previous when the cursor successfully moved to the previous position
|
|
427
|
+
*/
|
|
428
|
+
previous() {
|
|
429
|
+
let position = this.getCurrentPosition();
|
|
430
|
+
if (position >= 0) {
|
|
431
|
+
position = getClosestPositionLeft(position - 1);
|
|
432
|
+
if (position >= 0) {
|
|
433
|
+
this.setCursorAt(position);
|
|
434
|
+
} else if (navigatorConfig.loop) {
|
|
435
|
+
this.last();
|
|
436
|
+
} else {
|
|
437
|
+
/**
|
|
438
|
+
* reaching the end of the list
|
|
439
|
+
* @event lowerbound
|
|
440
|
+
*/
|
|
441
|
+
this.trigger('lowerbound');
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const cursor = this.getCursor();
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* @event previous
|
|
448
|
+
* @param {Object} cursor
|
|
449
|
+
*/
|
|
450
|
+
this.trigger('previous', cursor);
|
|
451
|
+
} else {
|
|
452
|
+
this.first();
|
|
453
|
+
}
|
|
454
|
+
return this;
|
|
455
|
+
},
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Activates the focused element, if any
|
|
459
|
+
*
|
|
460
|
+
* @param {Object} target
|
|
461
|
+
* @returns {keyNavigator}
|
|
462
|
+
* @fires activate
|
|
463
|
+
*/
|
|
464
|
+
activate(target) {
|
|
465
|
+
const cursor = this.getCursor();
|
|
466
|
+
if (cursor.navigable) {
|
|
467
|
+
/**
|
|
468
|
+
* @event activate
|
|
469
|
+
* @param {Object} cursor
|
|
470
|
+
* @param {Object} target
|
|
471
|
+
*/
|
|
472
|
+
this.trigger('activate', cursor, target);
|
|
473
|
+
}
|
|
474
|
+
return this;
|
|
475
|
+
},
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Blurs the focused element, if any
|
|
479
|
+
* @returns {keyNavigator}
|
|
480
|
+
*/
|
|
481
|
+
blur() {
|
|
482
|
+
const cursor = this.getCursorAt(lastPosition);
|
|
483
|
+
if (cursor.navigable) {
|
|
484
|
+
cursor.navigable.blur();
|
|
485
|
+
}
|
|
486
|
+
return this;
|
|
487
|
+
},
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Sets the focus to the current element
|
|
491
|
+
* @param {Number} [direction=1] - The direction that lead to this navigator.
|
|
492
|
+
* This will condition which element to focus if there is no default.
|
|
493
|
+
* A positive direction (or null) will lead to the first focusable element.
|
|
494
|
+
* A negative direction will lead to the last focusable element.
|
|
495
|
+
* @returns {keyNavigator}
|
|
496
|
+
*/
|
|
497
|
+
focus(direction = 1) {
|
|
498
|
+
let position = -1;
|
|
499
|
+
|
|
500
|
+
// try to get the default position
|
|
501
|
+
if (navigatorConfig.keepState && this.getNavigableAt(lastPosition)) {
|
|
502
|
+
position = lastPosition;
|
|
503
|
+
} else {
|
|
504
|
+
lastPosition = -1;
|
|
505
|
+
if ('undefined' !== typeof navigatorConfig.defaultPosition) {
|
|
506
|
+
if (_.isFunction(navigatorConfig.defaultPosition)) {
|
|
507
|
+
position = navigatorConfig.defaultPosition(this.getNavigableElements(), direction);
|
|
508
|
+
} else {
|
|
509
|
+
position = navigatorConfig.defaultPosition;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// select the default position with respect to the movement direction
|
|
515
|
+
if (position === -1) {
|
|
516
|
+
if (direction < 0) {
|
|
517
|
+
position = getClosestPositionLeft(navigableElements.length - 1);
|
|
518
|
+
} else {
|
|
519
|
+
position = 0;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
this.setCursorAt(getClosestPositionRight(position));
|
|
524
|
+
return this;
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
return keyNavigator.init().on('key', (key, el) => {
|
|
529
|
+
if (key === 'space' || key === 'enter') {
|
|
530
|
+
keyNavigator.activate(el);
|
|
531
|
+
} else {
|
|
532
|
+
keyNavigator.trigger(key, el);
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
}
|