@ohos-ports/flowbite-datepicker 2.0.0-beta.0
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/.eslintignore +2 -0
- package/.eslintrc.js +73 -0
- package/.stylelintrc +12 -0
- package/CHANGELOG.md +72 -0
- package/LICENSE +21 -0
- package/README.md +71 -0
- package/demo/index.html +582 -0
- package/demo/live-demo.js +471 -0
- package/dist/DateRangePicker.cjs.js +2996 -0
- package/dist/DateRangePicker.esm.js +2994 -0
- package/dist/DateRangePicker.umd.js +3002 -0
- package/dist/Datepicker.cjs.js +2778 -0
- package/dist/Datepicker.esm.js +2776 -0
- package/dist/Datepicker.umd.js +2784 -0
- package/dist/css/datepicker-bs4.css +276 -0
- package/dist/css/datepicker-bs4.min.css +1 -0
- package/dist/css/datepicker-bs5.css +276 -0
- package/dist/css/datepicker-bs5.min.css +1 -0
- package/dist/css/datepicker-bulma.css +258 -0
- package/dist/css/datepicker-bulma.min.css +1 -0
- package/dist/css/datepicker-foundation.css +262 -0
- package/dist/css/datepicker-foundation.min.css +1 -0
- package/dist/css/datepicker.css +306 -0
- package/dist/css/datepicker.min.css +1403 -0
- package/dist/js/datepicker-full.js +2777 -0
- package/dist/js/datepicker-full.min.js +1 -0
- package/dist/js/datepicker.js +2569 -0
- package/dist/js/datepicker.min.js +1 -0
- package/dist/js/locales/ar-tn.js +15 -0
- package/dist/js/locales/ar.js +15 -0
- package/dist/js/locales/az.js +14 -0
- package/dist/js/locales/bg.js +14 -0
- package/dist/js/locales/bm.js +18 -0
- package/dist/js/locales/bn.js +19 -0
- package/dist/js/locales/br.js +18 -0
- package/dist/js/locales/bs.js +15 -0
- package/dist/js/locales/ca.js +18 -0
- package/dist/js/locales/cs.js +19 -0
- package/dist/js/locales/cy.js +14 -0
- package/dist/js/locales/da.js +19 -0
- package/dist/js/locales/de.js +18 -0
- package/dist/js/locales/el.js +16 -0
- package/dist/js/locales/en-AU.js +18 -0
- package/dist/js/locales/en-CA.js +18 -0
- package/dist/js/locales/en-GB.js +18 -0
- package/dist/js/locales/en-IE.js +17 -0
- package/dist/js/locales/en-NZ.js +17 -0
- package/dist/js/locales/en-ZA.js +17 -0
- package/dist/js/locales/eo.js +17 -0
- package/dist/js/locales/es.js +18 -0
- package/dist/js/locales/et.js +18 -0
- package/dist/js/locales/eu.js +18 -0
- package/dist/js/locales/fa.js +17 -0
- package/dist/js/locales/fi.js +17 -0
- package/dist/js/locales/fo.js +15 -0
- package/dist/js/locales/fr-CH.js +21 -0
- package/dist/js/locales/fr.js +18 -0
- package/dist/js/locales/gl.js +16 -0
- package/dist/js/locales/he.js +15 -0
- package/dist/js/locales/hi.js +18 -0
- package/dist/js/locales/hr.js +13 -0
- package/dist/js/locales/hu.js +18 -0
- package/dist/js/locales/hy.js +18 -0
- package/dist/js/locales/id.js +15 -0
- package/dist/js/locales/is.js +14 -0
- package/dist/js/locales/it-CH.js +20 -0
- package/dist/js/locales/it.js +18 -0
- package/dist/js/locales/ja.js +17 -0
- package/dist/js/locales/ka.js +17 -0
- package/dist/js/locales/kk.js +15 -0
- package/dist/js/locales/km.js +15 -0
- package/dist/js/locales/ko.js +18 -0
- package/dist/js/locales/lt.js +19 -0
- package/dist/js/locales/lv.js +18 -0
- package/dist/js/locales/me.js +17 -0
- package/dist/js/locales/mk.js +15 -0
- package/dist/js/locales/mn.js +17 -0
- package/dist/js/locales/mr.js +18 -0
- package/dist/js/locales/ms.js +15 -0
- package/dist/js/locales/nl-BE.js +18 -0
- package/dist/js/locales/nl.js +18 -0
- package/dist/js/locales/no.js +18 -0
- package/dist/js/locales/oc.js +17 -0
- package/dist/js/locales/pl.js +17 -0
- package/dist/js/locales/pt-BR.js +17 -0
- package/dist/js/locales/pt.js +18 -0
- package/dist/js/locales/ro.js +17 -0
- package/dist/js/locales/ru.js +18 -0
- package/dist/js/locales/si.js +18 -0
- package/dist/js/locales/sk.js +18 -0
- package/dist/js/locales/sl.js +15 -0
- package/dist/js/locales/sq.js +18 -0
- package/dist/js/locales/sr-latn.js +16 -0
- package/dist/js/locales/sr.js +16 -0
- package/dist/js/locales/sv.js +17 -0
- package/dist/js/locales/sw.js +15 -0
- package/dist/js/locales/ta.js +18 -0
- package/dist/js/locales/tg.js +19 -0
- package/dist/js/locales/th.js +14 -0
- package/dist/js/locales/tk.js +18 -0
- package/dist/js/locales/tr.js +17 -0
- package/dist/js/locales/uk.js +17 -0
- package/dist/js/locales/uz-cyrl.js +18 -0
- package/dist/js/locales/uz-latn.js +18 -0
- package/dist/js/locales/vi.js +16 -0
- package/dist/js/locales/zh-CN.js +19 -0
- package/dist/js/locales/zh-TW.js +18 -0
- package/dist/locales/index.cjs.js +1028 -0
- package/dist/locales/index.esm.js +1028 -0
- package/dist/main.cjs.js +2999 -0
- package/dist/main.esm.js +2994 -0
- package/dist/main.umd.js +3005 -0
- package/docs/.nojekyll +0 -0
- package/docs/README.md +266 -0
- package/docs/_sidebar.md +6 -0
- package/docs/api.md +284 -0
- package/docs/date-string+format.md +90 -0
- package/docs/i18n.md +99 -0
- package/docs/images/datepicker-inline.jpg +0 -0
- package/docs/images/datepicker.jpg +0 -0
- package/docs/images/multidate.jpg +0 -0
- package/docs/images/picker-structure.jpg +0 -0
- package/docs/images/rangepicker.jpg +0 -0
- package/docs/images/view-days.jpg +0 -0
- package/docs/images/view-decades.jpg +0 -0
- package/docs/images/view-months.jpg +0 -0
- package/docs/images/view-years.jpg +0 -0
- package/docs/index.html +26 -0
- package/docs/options.md +354 -0
- package/docs/overview.md +174 -0
- package/extras/twoDigitToFullYear/test/twoDigitToFullYear.js +58 -0
- package/extras/twoDigitToFullYear/twoDigitToFullYear.js +26 -0
- package/js/DateRangePicker.js +210 -0
- package/js/Datepicker.js +487 -0
- package/js/datepicker-full.js +5 -0
- package/js/events/functions.js +48 -0
- package/js/events/inputFieldListeners.js +206 -0
- package/js/events/otherListeners.js +15 -0
- package/js/events/pickerListeners.js +70 -0
- package/js/i18n/base-locales.js +13 -0
- package/js/i18n/locales/ar-tn.js +15 -0
- package/js/i18n/locales/ar.js +15 -0
- package/js/i18n/locales/az.js +14 -0
- package/js/i18n/locales/bg.js +14 -0
- package/js/i18n/locales/bm.js +18 -0
- package/js/i18n/locales/bn.js +19 -0
- package/js/i18n/locales/br.js +18 -0
- package/js/i18n/locales/bs.js +15 -0
- package/js/i18n/locales/ca.js +18 -0
- package/js/i18n/locales/cs.js +19 -0
- package/js/i18n/locales/cy.js +14 -0
- package/js/i18n/locales/da.js +19 -0
- package/js/i18n/locales/de.js +18 -0
- package/js/i18n/locales/el.js +16 -0
- package/js/i18n/locales/en-AU.js +18 -0
- package/js/i18n/locales/en-CA.js +18 -0
- package/js/i18n/locales/en-GB.js +18 -0
- package/js/i18n/locales/en-IE.js +17 -0
- package/js/i18n/locales/en-NZ.js +17 -0
- package/js/i18n/locales/en-ZA.js +17 -0
- package/js/i18n/locales/eo.js +17 -0
- package/js/i18n/locales/es.js +18 -0
- package/js/i18n/locales/et.js +18 -0
- package/js/i18n/locales/eu.js +18 -0
- package/js/i18n/locales/fa.js +17 -0
- package/js/i18n/locales/fi.js +17 -0
- package/js/i18n/locales/fo.js +15 -0
- package/js/i18n/locales/fr-CH.js +21 -0
- package/js/i18n/locales/fr.js +18 -0
- package/js/i18n/locales/gl.js +16 -0
- package/js/i18n/locales/he.js +15 -0
- package/js/i18n/locales/hi.js +18 -0
- package/js/i18n/locales/hr.js +13 -0
- package/js/i18n/locales/hu.js +18 -0
- package/js/i18n/locales/hy.js +18 -0
- package/js/i18n/locales/id.js +15 -0
- package/js/i18n/locales/is.js +14 -0
- package/js/i18n/locales/it-CH.js +20 -0
- package/js/i18n/locales/it.js +18 -0
- package/js/i18n/locales/ja.js +17 -0
- package/js/i18n/locales/ka.js +17 -0
- package/js/i18n/locales/kk.js +15 -0
- package/js/i18n/locales/km.js +15 -0
- package/js/i18n/locales/ko.js +18 -0
- package/js/i18n/locales/lt.js +19 -0
- package/js/i18n/locales/lv.js +18 -0
- package/js/i18n/locales/me.js +17 -0
- package/js/i18n/locales/mk.js +15 -0
- package/js/i18n/locales/mn.js +17 -0
- package/js/i18n/locales/mr.js +18 -0
- package/js/i18n/locales/ms.js +15 -0
- package/js/i18n/locales/nl-BE.js +18 -0
- package/js/i18n/locales/nl.js +18 -0
- package/js/i18n/locales/no.js +18 -0
- package/js/i18n/locales/oc.js +17 -0
- package/js/i18n/locales/pl.js +17 -0
- package/js/i18n/locales/pt-BR.js +17 -0
- package/js/i18n/locales/pt.js +18 -0
- package/js/i18n/locales/ro.js +17 -0
- package/js/i18n/locales/ru.js +18 -0
- package/js/i18n/locales/si.js +18 -0
- package/js/i18n/locales/sk.js +18 -0
- package/js/i18n/locales/sl.js +15 -0
- package/js/i18n/locales/sq.js +18 -0
- package/js/i18n/locales/sr-latn.js +16 -0
- package/js/i18n/locales/sr.js +16 -0
- package/js/i18n/locales/sv.js +17 -0
- package/js/i18n/locales/sw.js +15 -0
- package/js/i18n/locales/ta.js +18 -0
- package/js/i18n/locales/tg.js +19 -0
- package/js/i18n/locales/th.js +14 -0
- package/js/i18n/locales/tk.js +18 -0
- package/js/i18n/locales/tr.js +17 -0
- package/js/i18n/locales/uk.js +17 -0
- package/js/i18n/locales/uz-cyrl.js +18 -0
- package/js/i18n/locales/uz-latn.js +18 -0
- package/js/i18n/locales/vi.js +16 -0
- package/js/i18n/locales/zh-CN.js +19 -0
- package/js/i18n/locales/zh-TW.js +18 -0
- package/js/lib/date-format.js +185 -0
- package/js/lib/date.js +82 -0
- package/js/lib/dom.js +55 -0
- package/js/lib/event.js +68 -0
- package/js/lib/utils.js +61 -0
- package/js/main.js +4 -0
- package/js/options/defaultOptions.js +38 -0
- package/js/options/processOptions.js +263 -0
- package/js/picker/Picker.js +334 -0
- package/js/picker/templates/calendarWeeksTemplate.js +8 -0
- package/js/picker/templates/daysTemplate.js +8 -0
- package/js/picker/templates/pickerTemplate.js +23 -0
- package/js/picker/views/DaysView.js +250 -0
- package/js/picker/views/MonthsView.js +198 -0
- package/js/picker/views/View.js +55 -0
- package/js/picker/views/YearsView.js +170 -0
- package/package.json +81 -0
- package/postcss.config.js +5 -0
- package/rollup.config.js +75 -0
- package/sass/_mixins.scss +12 -0
- package/sass/datepicker-bs4.scss +91 -0
- package/sass/datepicker-bs5.scss +91 -0
- package/sass/datepicker-bulma.scss +69 -0
- package/sass/datepicker-foundation.scss +66 -0
- package/sass/datepicker.scss +436 -0
- package/sass/index-bs4.scss +5 -0
- package/sass/index-bs5.scss +5 -0
- package/sass/index-bulma.scss +6 -0
- package/sass/index-foundation.scss +3 -0
- package/scripts/build-css.js +39 -0
- package/scripts/build-locales.js +57 -0
- package/scripts/convert-bsdp-locales.js +65 -0
- package/scripts/minify-css.js +31 -0
- package/scripts/minify-js.js +17 -0
- package/style.css +10 -0
- package/tailwind.config.js +16 -0
- package/tailwind.css +1389 -0
- package/test/DateRangePicker/DateRangePicker.js +547 -0
- package/test/DateRangePicker/api-methods.js +415 -0
- package/test/DateRangePicker/date-selection.js +472 -0
- package/test/DateRangePicker/options.js +308 -0
- package/test/Datepicker/Datepicker-object.js +236 -0
- package/test/Datepicker/api-methods.js +328 -0
- package/test/_utils/date.js +102 -0
- package/test/_utils/dom.js +70 -0
- package/test/events.js +785 -0
- package/test/inline-mode.js +45 -0
- package/test/keyboard-operation/arrow-down.js +293 -0
- package/test/keyboard-operation/arrow-left.js +255 -0
- package/test/keyboard-operation/arrow-right.js +215 -0
- package/test/keyboard-operation/arrow-up.js +461 -0
- package/test/keyboard-operation/edit-mode.js +458 -0
- package/test/keyboard-operation/keyboard-operation.js +146 -0
- package/test/mouse-operation.js +580 -0
- package/test/options/before-show.js +635 -0
- package/test/options/bulma-datepicker.sublime-workspace +1280 -0
- package/test/options/buttons.js +383 -0
- package/test/options/date-restrictions.js +802 -0
- package/test/options/format.js +281 -0
- package/test/options/multidate.js +380 -0
- package/test/options/options.js +727 -0
- package/test/options/orientation.js +410 -0
- package/test/options/pick-levle+view.js +357 -0
- package/test/test.html +94 -0
- package/test/unit/DateRangePicker.js +192 -0
- package/test/unit/Datepicker.js +307 -0
- package/test/unit/_setup.js +28 -0
- package/test/unit/lib/date-format.js +310 -0
- package/test/unit/lib/date.js +211 -0
- package/test/unit/lib/dom.js +142 -0
- package/test/unit/lib/event.js +207 -0
- package/test/unit/lib/utils.js +135 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import '../_setup.js';
|
|
2
|
+
import {
|
|
3
|
+
stripTime,
|
|
4
|
+
dateValue,
|
|
5
|
+
today,
|
|
6
|
+
addDays,
|
|
7
|
+
addWeeks,
|
|
8
|
+
addMonths,
|
|
9
|
+
addYears,
|
|
10
|
+
dayOfTheWeekOf,
|
|
11
|
+
getWeek,
|
|
12
|
+
startOfYearPeriod
|
|
13
|
+
} from '../../../js/lib/date.js';
|
|
14
|
+
|
|
15
|
+
describe('lib/date', function () {
|
|
16
|
+
describe('stripTime()', function () {
|
|
17
|
+
it('returns the time value of 00:00:00 local time of given time value or date', function () {
|
|
18
|
+
let origDate = new Date(2016, 8, 24, 13, 55, 32, 235);
|
|
19
|
+
expect(stripTime(origDate.getTime()), 'to be', new Date(2016, 8, 24).getTime());
|
|
20
|
+
|
|
21
|
+
origDate = new Date(2019, 1, 14, 20, 55);
|
|
22
|
+
expect(stripTime(origDate), 'to be', new Date(2019, 1, 14).getTime());
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('today()', function () {
|
|
27
|
+
it('returns the time value of 00:00:00 local time of current date', function () {
|
|
28
|
+
const now = new Date();
|
|
29
|
+
const timeValue = today();
|
|
30
|
+
expect(timeValue, 'to be', now.setHours(0, 0, 0, 0));
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('dateValue()', function () {
|
|
35
|
+
it('returns the time value of 00:00:00 local time of the date created by given Date constructor parameters', function () {
|
|
36
|
+
// from Date object
|
|
37
|
+
let origDate = new Date(2016, 8, 24, 13, 55, 32, 235);
|
|
38
|
+
let timeValue = dateValue(origDate);
|
|
39
|
+
expect(timeValue, 'to be', new Date(2016, 8, 24).getTime());
|
|
40
|
+
|
|
41
|
+
// from Date constructor args
|
|
42
|
+
timeValue = dateValue(2019, 1, 17, 9, 43, 18, 953);
|
|
43
|
+
expect(timeValue, 'to be', new Date(2019, 1, 17).getTime());
|
|
44
|
+
|
|
45
|
+
// from string
|
|
46
|
+
let origDateStr = '2020-04-20T02:27:15Z';
|
|
47
|
+
origDate = new Date(origDateStr);
|
|
48
|
+
timeValue = dateValue(origDateStr);
|
|
49
|
+
expect(timeValue, 'to be', origDate.setHours(0, 0, 0, 0));
|
|
50
|
+
|
|
51
|
+
// from time value
|
|
52
|
+
origDate = new Date(2016, 8, 24, 13, 55, 32, 235);
|
|
53
|
+
timeValue = dateValue(origDate.getTime());
|
|
54
|
+
expect(timeValue, 'to be', new Date(2016, 8, 24).getTime());
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('does not map 2-digit year to 1900\'s', function () {
|
|
58
|
+
let date = new Date(dateValue(86, 8, 24));
|
|
59
|
+
expect(date.getFullYear(), 'to be', 86);
|
|
60
|
+
expect(date.getMonth(), 'to be', 8);
|
|
61
|
+
expect(date.getDate(), 'to be', 24);
|
|
62
|
+
|
|
63
|
+
date = new Date(dateValue(19, 1, 17));
|
|
64
|
+
expect(date.getFullYear(), 'to be', 19);
|
|
65
|
+
expect(date.getMonth(), 'to be', 1);
|
|
66
|
+
expect(date.getDate(), 'to be', 17);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('addDays()', function () {
|
|
71
|
+
it('returns the time value of N days after a date or time value', function () {
|
|
72
|
+
let date1 = new Date(2019, 11, 31);
|
|
73
|
+
let date2 = addDays(date1, 1);
|
|
74
|
+
expect(date2, 'to be', new Date(2020, 0, 1).getTime());
|
|
75
|
+
expect(addDays(date2, 30), 'to be', new Date(2020, 0, 31).getTime());
|
|
76
|
+
|
|
77
|
+
date1 = new Date(2020, 0, 1);
|
|
78
|
+
expect(addDays(date1, -1), 'to be', new Date(2019, 11, 31).getTime());
|
|
79
|
+
expect(addDays(date1, -10), 'to be', new Date(2019, 11, 22).getTime());
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('addWeeks()', function () {
|
|
84
|
+
it('returns the time value of N weeks after a date or time value', function () {
|
|
85
|
+
let date1 = new Date(2019, 11, 28);
|
|
86
|
+
let date2 = addWeeks(date1, 1);
|
|
87
|
+
expect(date2, 'to be', new Date(2020, 0, 4).getTime());
|
|
88
|
+
expect(addWeeks(date2, 4), 'to be', new Date(2020, 1, 1).getTime());
|
|
89
|
+
|
|
90
|
+
date1 = new Date(2020, 0, 4);
|
|
91
|
+
expect(addWeeks(date1, -1), 'to be', new Date(2019, 11, 28).getTime());
|
|
92
|
+
expect(addWeeks(date1, -8), 'to be', new Date(2019, 10, 9).getTime());
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('addMonths()', function () {
|
|
97
|
+
it('returns the time value of N months after a date or time value', function () {
|
|
98
|
+
let date1 = new Date(2019, 11, 31);
|
|
99
|
+
let date2 = addMonths(date1, 1);
|
|
100
|
+
expect(date2, 'to be', new Date(2020, 0, 31).getTime());
|
|
101
|
+
expect(addMonths(date2, 29), 'to be', new Date(2022, 5, 30).getTime());
|
|
102
|
+
|
|
103
|
+
date1 = new Date(2020, 0, 1);
|
|
104
|
+
expect(addMonths(date1, -1), 'to be', new Date(2019, 11, 1).getTime());
|
|
105
|
+
expect(addMonths(date1, -18), 'to be', new Date(2018, 6, 1).getTime());
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('returns the end of the next/prev month if the day of the old date is not in the new month', function () {
|
|
109
|
+
let date = new Date(2019, 9, 31);
|
|
110
|
+
expect(addMonths(date, 1), 'to be', new Date(2019, 10, 30).getTime());
|
|
111
|
+
expect(addMonths(date, 18), 'to be', new Date(2021, 3, 30).getTime());
|
|
112
|
+
|
|
113
|
+
date = new Date(2019, 11, 31);
|
|
114
|
+
expect(addMonths(date, -1), 'to be', new Date(2019, 10, 30).getTime());
|
|
115
|
+
expect(addMonths(date, -30), 'to be', new Date(2017, 5, 30).getTime());
|
|
116
|
+
|
|
117
|
+
date = new Date(2019, 0, 31);
|
|
118
|
+
expect(addMonths(date, 1), 'to be', new Date(2019, 1, 28).getTime());
|
|
119
|
+
expect(addMonths(date, 13), 'to be', new Date(2020, 1, 29).getTime());
|
|
120
|
+
|
|
121
|
+
date = new Date(2020, 0, 31);
|
|
122
|
+
expect(addMonths(date, 1), 'to be', new Date(2020, 1, 29).getTime());
|
|
123
|
+
expect(addMonths(date, 13), 'to be', new Date(2021, 1, 28).getTime());
|
|
124
|
+
|
|
125
|
+
date = new Date(2019, 2, 30);
|
|
126
|
+
expect(addMonths(date, -1), 'to be', new Date(2019, 1, 28).getTime());
|
|
127
|
+
expect(addMonths(date, -37), 'to be', new Date(2016, 1, 29).getTime());
|
|
128
|
+
|
|
129
|
+
date = new Date(2020, 2, 30);
|
|
130
|
+
expect(addMonths(date, -1), 'to be', new Date(2020, 1, 29).getTime());
|
|
131
|
+
expect(addMonths(date, -37), 'to be', new Date(2017, 1, 28).getTime());
|
|
132
|
+
|
|
133
|
+
date = new Date(2020, 1, 29);
|
|
134
|
+
expect(addMonths(date, 12), 'to be', new Date(2021, 1, 28).getTime());
|
|
135
|
+
expect(addMonths(date, -24), 'to be', new Date(2018, 1, 28).getTime());
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
describe('addYears()', function () {
|
|
140
|
+
it('returns the time value of N years after a date or time value', function () {
|
|
141
|
+
let date1 = new Date(2019, 11, 31);
|
|
142
|
+
let date2 = addYears(date1, 1);
|
|
143
|
+
expect(date2, 'to be', new Date(2020, 11, 31).getTime());
|
|
144
|
+
expect(addYears(date2, 3), 'to be', new Date(2023, 11, 31).getTime());
|
|
145
|
+
|
|
146
|
+
date1 = new Date(2020, 0, 1);
|
|
147
|
+
expect(addYears(date1, -1), 'to be', new Date(2019, 0, 1).getTime());
|
|
148
|
+
expect(addYears(date1, -3), 'to be', new Date(2017, 0, 1).getTime());
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('returns 2/28 of the year if the old date is 2/29 and the new year is not a leap year', function () {
|
|
152
|
+
const date = new Date(2020, 1, 29);
|
|
153
|
+
expect(addYears(date, 1), 'to be', new Date(2021, 1, 28).getTime());
|
|
154
|
+
expect(addYears(date, -1), 'to be', new Date(2019, 1, 28).getTime());
|
|
155
|
+
expect(addYears(date, -4), 'to be', new Date(2016, 1, 29).getTime());
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe('dayOfTheWeekOf()', function () {
|
|
160
|
+
it('returns a date object of given day of the week of given date', function () {
|
|
161
|
+
expect(dayOfTheWeekOf(new Date(2017, 0, 1), 0), 'to be', new Date(2017, 0, 1).getTime());
|
|
162
|
+
expect(dayOfTheWeekOf(new Date(2017, 3, 5), 1), 'to be', new Date(2017, 3, 3).getTime());
|
|
163
|
+
expect(dayOfTheWeekOf(new Date(2017, 5, 8), 2), 'to be', new Date(2017, 5, 6).getTime());
|
|
164
|
+
expect(dayOfTheWeekOf(new Date(2017, 9, 31), 3), 'to be', new Date(2017, 10, 1).getTime());
|
|
165
|
+
expect(dayOfTheWeekOf(new Date(2018, 2, 10), 4), 'to be', new Date(2018, 2, 8).getTime());
|
|
166
|
+
expect(dayOfTheWeekOf(new Date(2018, 5, 19), 5), 'to be', new Date(2018, 5, 22).getTime());
|
|
167
|
+
expect(dayOfTheWeekOf(new Date(2018, 10, 20), 6), 'to be', new Date(2018, 10, 24).getTime());
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('uses sepecified start day of week if it is given', function () {
|
|
171
|
+
expect(dayOfTheWeekOf(new Date(2017, 0, 1), 0, 1), 'to be', new Date(2017, 0, 1).getTime());
|
|
172
|
+
expect(dayOfTheWeekOf(new Date(2017, 3, 5), 1, 3), 'to be', new Date(2017, 3, 10).getTime());
|
|
173
|
+
expect(dayOfTheWeekOf(new Date(2017, 5, 8), 2, 4), 'to be', new Date(2017, 5, 13).getTime());
|
|
174
|
+
expect(dayOfTheWeekOf(new Date(2017, 9, 31), 3, 6), 'to be', new Date(2017, 10, 1).getTime());
|
|
175
|
+
expect(dayOfTheWeekOf(new Date(2018, 2, 10), 4, 5), 'to be', new Date(2018, 2, 15).getTime());
|
|
176
|
+
expect(dayOfTheWeekOf(new Date(2018, 5, 19), 5, 2), 'to be', new Date(2018, 5, 22).getTime());
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe('getWeek()', function () {
|
|
181
|
+
it('returns ISO week number of given date', function () {
|
|
182
|
+
expect(getWeek(new Date(2015, 0, 1)), 'to be', 1);
|
|
183
|
+
expect(getWeek(new Date(2015, 3, 26)), 'to be', 17);
|
|
184
|
+
expect(getWeek(new Date(2015, 8, 12)), 'to be', 37);
|
|
185
|
+
expect(getWeek(new Date(2015, 10, 15)), 'to be', 46);
|
|
186
|
+
expect(getWeek(new Date(2016, 0, 1)), 'to be', 53);
|
|
187
|
+
expect(getWeek(new Date(2016, 0, 7)), 'to be', 1);
|
|
188
|
+
expect(getWeek(new Date(2016, 6, 21)), 'to be', 29);
|
|
189
|
+
expect(getWeek(new Date(2016, 8, 6)), 'to be', 36);
|
|
190
|
+
expect(getWeek(new Date(2016, 11, 1)), 'to be', 48);
|
|
191
|
+
expect(getWeek(new Date(2017, 0, 1)), 'to be', 52);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
describe('startOfYearPeriod()', function () {
|
|
196
|
+
it('returns the start year of given length of period of years', function () {
|
|
197
|
+
let date = new Date(2121, 0, 1);
|
|
198
|
+
expect(startOfYearPeriod(date, 10), 'to be', 2120);
|
|
199
|
+
expect(startOfYearPeriod(date, 100), 'to be', 2100);
|
|
200
|
+
expect(startOfYearPeriod(date, 1000), 'to be', 2000);
|
|
201
|
+
|
|
202
|
+
date = new Date(1984, 0, 1);
|
|
203
|
+
expect(startOfYearPeriod(date, 10), 'to be', 1980);
|
|
204
|
+
expect(startOfYearPeriod(date, 100), 'to be', 1900);
|
|
205
|
+
expect(startOfYearPeriod(date, 1000), 'to be', 1000);
|
|
206
|
+
|
|
207
|
+
expect(startOfYearPeriod(new Date(738, 5, 30), 20), 'to be', 720);
|
|
208
|
+
expect(startOfYearPeriod(new Date(0, 5, 30).setFullYear(88), 25), 'to be', 75);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
});
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import '../_setup.js';
|
|
2
|
+
import {
|
|
3
|
+
parseHTML,
|
|
4
|
+
isVisible,
|
|
5
|
+
hideElement,
|
|
6
|
+
showElement,
|
|
7
|
+
emptyChildNodes,
|
|
8
|
+
replaceChildNodes,
|
|
9
|
+
} from '../../../js/lib/dom.js';
|
|
10
|
+
|
|
11
|
+
describe('lib/dom', function () {
|
|
12
|
+
let el;
|
|
13
|
+
|
|
14
|
+
before(function () {
|
|
15
|
+
testContainer.innerHTML = '<div class="test"></div>';
|
|
16
|
+
el = testContainer.firstChild;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
after(function () {
|
|
20
|
+
testContainer.removeChild(el);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('parseHTML()', function () {
|
|
24
|
+
it('parses an html fragment with Range.prototype.createContextualFragment()', function () {
|
|
25
|
+
const spyFragment = sinon.spy(Range.prototype, 'createContextualFragment');
|
|
26
|
+
const html = '<div>test</div>';
|
|
27
|
+
const result = parseHTML(html);
|
|
28
|
+
|
|
29
|
+
expect(spyFragment.calledWith(html), 'to be true');
|
|
30
|
+
expect(spyFragment.returned(result), 'to be true');
|
|
31
|
+
|
|
32
|
+
spyFragment.restore();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('isVisible()', function () {
|
|
37
|
+
it('returns true if either offsetHeight > 0, offsetWidth > 0 or getClientRects() has an item', function () {
|
|
38
|
+
expect(isVisible(el), 'to be false');
|
|
39
|
+
|
|
40
|
+
let stub = sinon.stub(el, "offsetHeight").get(() => 10);
|
|
41
|
+
expect(isVisible(el), 'to be true');
|
|
42
|
+
stub.restore();
|
|
43
|
+
|
|
44
|
+
stub = sinon.stub(el, "offsetWidth").get(() => 10);
|
|
45
|
+
expect(isVisible(el), 'to be true');
|
|
46
|
+
stub.restore();
|
|
47
|
+
|
|
48
|
+
stub = sinon.stub(el, 'getClientRects').callsFake(() => [{x: 10}, {x: 20}]);
|
|
49
|
+
expect(isVisible(el), 'to be true');
|
|
50
|
+
stub.restore();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('hideElement()', function () {
|
|
55
|
+
it('sets none to style.display', function () {
|
|
56
|
+
hideElement(el);
|
|
57
|
+
expect(el.style.display, 'to be', 'none');
|
|
58
|
+
el.removeAttribute('style');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('copies style.display to data-style-display attribute if other than none is set', function () {
|
|
62
|
+
el.style.display = 'flex';
|
|
63
|
+
hideElement(el);
|
|
64
|
+
|
|
65
|
+
expect(el.style.display, 'to be', 'none');
|
|
66
|
+
expect(el.getAttribute('data-style-display'), 'to be', 'flex');
|
|
67
|
+
|
|
68
|
+
el.removeAttribute('data-style-display');
|
|
69
|
+
el.style.display = 'none';
|
|
70
|
+
hideElement(el);
|
|
71
|
+
|
|
72
|
+
expect(el.hasAttribute('data-style-display'), 'to be false');
|
|
73
|
+
|
|
74
|
+
el.removeAttribute('style');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('showElement()', function () {
|
|
79
|
+
it('clears style.display if none is set', function () {
|
|
80
|
+
el.style.display = 'none';
|
|
81
|
+
showElement(el);
|
|
82
|
+
expect(el.style.display, 'to be', '');
|
|
83
|
+
|
|
84
|
+
el.style.display = 'inline';
|
|
85
|
+
showElement(el);
|
|
86
|
+
expect(el.style.display, 'to be', 'inline');
|
|
87
|
+
|
|
88
|
+
el.removeAttribute('style');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('restores the value of data-style-display attribute to style.display if it exists', function () {
|
|
92
|
+
el.style.display = 'none';
|
|
93
|
+
el.setAttribute('data-style-display', 'flex');
|
|
94
|
+
showElement(el);
|
|
95
|
+
|
|
96
|
+
expect(el.style.display, 'to be', 'flex');
|
|
97
|
+
expect(el.hasAttribute('data-style-display'), 'to be false');
|
|
98
|
+
|
|
99
|
+
el.removeAttribute('style');
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('emptyChildNodes()', function () {
|
|
104
|
+
it('removes all child nodes', function () {
|
|
105
|
+
el.innerHTML = '<div>test</div><!-- comment--><div></div>';
|
|
106
|
+
emptyChildNodes(el);
|
|
107
|
+
|
|
108
|
+
expect(el.innerHTML, 'to be empty');
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('replaceChildNodes()', function () {
|
|
113
|
+
it('replace all child nodes with given nodes', function () {
|
|
114
|
+
const htmlBefore = '<div>test</div><!-- comment--><div></div>';
|
|
115
|
+
const htmlAfter = '<div id="foo">foo</div><div id="bar">bar</div>';
|
|
116
|
+
|
|
117
|
+
// with html
|
|
118
|
+
el.innerHTML = htmlBefore;
|
|
119
|
+
replaceChildNodes(el, htmlAfter);
|
|
120
|
+
expect(el.innerHTML, 'to be', htmlAfter);
|
|
121
|
+
|
|
122
|
+
// with DocumentFragment
|
|
123
|
+
const fragment = document.createRange().createContextualFragment(htmlAfter);
|
|
124
|
+
el.innerHTML = htmlBefore;
|
|
125
|
+
replaceChildNodes(el, fragment);
|
|
126
|
+
expect(el.innerHTML, 'to be', htmlAfter);
|
|
127
|
+
|
|
128
|
+
// with NodeList
|
|
129
|
+
const nodeList = el.querySelectorAll('div');
|
|
130
|
+
el.innerHTML = htmlBefore;
|
|
131
|
+
replaceChildNodes(el, nodeList);
|
|
132
|
+
expect(el.innerHTML, 'to be', htmlAfter);
|
|
133
|
+
|
|
134
|
+
// with array
|
|
135
|
+
el.innerHTML = htmlBefore;
|
|
136
|
+
replaceChildNodes(el, Array.from(nodeList));
|
|
137
|
+
expect(el.innerHTML, 'to be', htmlAfter);
|
|
138
|
+
|
|
139
|
+
el.innerHTML = '';
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import '../_setup.js';
|
|
2
|
+
|
|
3
|
+
describe('lib/evnet', function () {
|
|
4
|
+
let listenerRegistry;
|
|
5
|
+
let spyAEL;
|
|
6
|
+
let spyREL;
|
|
7
|
+
//
|
|
8
|
+
let registerListeners;
|
|
9
|
+
let unregisterListeners;
|
|
10
|
+
let findElementInEventPath;
|
|
11
|
+
|
|
12
|
+
before(function () {
|
|
13
|
+
spyAEL = sinon.spy(EventTarget.prototype, 'addEventListener');
|
|
14
|
+
spyREL = sinon.spy(EventTarget.prototype, 'removeEventListener');
|
|
15
|
+
|
|
16
|
+
const origWeakMap = global.WeakMap;
|
|
17
|
+
global.WeakMap = function (...args) {
|
|
18
|
+
return listenerRegistry = new origWeakMap(...args);
|
|
19
|
+
};
|
|
20
|
+
return import('../../../js/lib/event.js')
|
|
21
|
+
.then((module) => {
|
|
22
|
+
global.WeakMap = origWeakMap;
|
|
23
|
+
|
|
24
|
+
registerListeners = module.registerListeners;
|
|
25
|
+
unregisterListeners = module.unregisterListeners;
|
|
26
|
+
findElementInEventPath = module.findElementInEventPath;
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
after(function () {
|
|
31
|
+
spyAEL.restore();
|
|
32
|
+
spyREL.restore();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(function () {
|
|
36
|
+
spyAEL.resetHistory();
|
|
37
|
+
spyREL.resetHistory();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('registerListeners()', function () {
|
|
41
|
+
let target;
|
|
42
|
+
|
|
43
|
+
before(function () {
|
|
44
|
+
target = document.createElement('input');
|
|
45
|
+
testContainer.appendChild(target);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
after(function () {
|
|
49
|
+
testContainer.removeChild(target);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('registers event listeres with key object calling addEventListener()', function () {
|
|
53
|
+
const keyObj = {};
|
|
54
|
+
const onClick = sinon.spy();
|
|
55
|
+
const onKeydown = sinon.spy();
|
|
56
|
+
const onMounseEnter = () => {};
|
|
57
|
+
const listeners = [
|
|
58
|
+
[document, 'click', onClick],
|
|
59
|
+
[target, 'keydown', onKeydown, {capture: false}],
|
|
60
|
+
[target, 'mouseenter', onMounseEnter, true],
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
registerListeners(keyObj, listeners);
|
|
64
|
+
expect(listenerRegistry.get(keyObj), 'to equal', listeners);
|
|
65
|
+
expect(spyAEL.args, 'to equal', listeners.map(listener => listener.slice(1)));
|
|
66
|
+
|
|
67
|
+
testContainer.click();
|
|
68
|
+
expect(onClick.called, 'to be true');
|
|
69
|
+
simulant.fire(target, 'keydown', {key: 'enter'});
|
|
70
|
+
expect(onKeydown.called, 'to be true');
|
|
71
|
+
|
|
72
|
+
listeners.forEach((listener) => {
|
|
73
|
+
EventTarget.prototype.removeEventListener.call(...listener);
|
|
74
|
+
});
|
|
75
|
+
listenerRegistry.delete(keyObj);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('appends listeners if registration for key object already exists', function () {
|
|
79
|
+
const keyObj = {};
|
|
80
|
+
const onClick = () => {};
|
|
81
|
+
const onKeydown = () => {};
|
|
82
|
+
const onMounseEnter = () => {};
|
|
83
|
+
const listeners = [
|
|
84
|
+
[document, 'click', onClick],
|
|
85
|
+
];
|
|
86
|
+
const listenersToAdd = [
|
|
87
|
+
[target, 'keydown', onKeydown, {capture: false}],
|
|
88
|
+
[target, 'mouseenter', onMounseEnter, true],
|
|
89
|
+
];
|
|
90
|
+
listenerRegistry.set(keyObj, listeners);
|
|
91
|
+
|
|
92
|
+
registerListeners(keyObj, listenersToAdd);
|
|
93
|
+
expect(listeners.length, 'to be', 3);
|
|
94
|
+
expect(listenerRegistry.get(keyObj), 'to equal', listeners);
|
|
95
|
+
expect(spyAEL.args, 'to equal', listenersToAdd.map(listener => listener.slice(1)));
|
|
96
|
+
|
|
97
|
+
listenersToAdd.forEach((listener) => {
|
|
98
|
+
EventTarget.prototype.removeEventListener.call(...listener);
|
|
99
|
+
});
|
|
100
|
+
listenerRegistry.delete(keyObj);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('unregisterListeners()', function () {
|
|
105
|
+
let target;
|
|
106
|
+
|
|
107
|
+
before(function () {
|
|
108
|
+
target = document.createElement('input');
|
|
109
|
+
testContainer.appendChild(target);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
after(function () {
|
|
113
|
+
testContainer.removeChild(target);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('unregisters all event listeres for key object calling removeEventListener()', function () {
|
|
117
|
+
const keyObj = {};
|
|
118
|
+
const onClick = sinon.spy();
|
|
119
|
+
const onKeydown = sinon.spy();
|
|
120
|
+
const onMounseEnter = () => {};
|
|
121
|
+
const listeners = [
|
|
122
|
+
[document, 'click', onClick],
|
|
123
|
+
[target, 'keydown', onKeydown, {capture: false}],
|
|
124
|
+
[target, 'mouseenter', onMounseEnter, true],
|
|
125
|
+
];
|
|
126
|
+
listeners.forEach((listener) => {
|
|
127
|
+
EventTarget.prototype.addEventListener.call(...listener);
|
|
128
|
+
});
|
|
129
|
+
listenerRegistry.set(keyObj, listeners);
|
|
130
|
+
|
|
131
|
+
unregisterListeners(keyObj);
|
|
132
|
+
expect(listenerRegistry.get(keyObj), 'to be undefined');
|
|
133
|
+
expect(spyREL.args, 'to equal', listeners.map(listener => listener.slice(1)));
|
|
134
|
+
|
|
135
|
+
testContainer.click();
|
|
136
|
+
expect(onClick.called, 'to be false');
|
|
137
|
+
simulant.fire(target, 'keydown', {key: 'enter'});
|
|
138
|
+
expect(onKeydown.called, 'to be false');
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe('findElementInEventPath()', function () {
|
|
143
|
+
let field;
|
|
144
|
+
let control;
|
|
145
|
+
let input;
|
|
146
|
+
|
|
147
|
+
before(function () {
|
|
148
|
+
input = document.createElement('input');
|
|
149
|
+
control = document.createElement('div');
|
|
150
|
+
control.className = 'control';
|
|
151
|
+
control.appendChild(input);
|
|
152
|
+
field = document.createElement('div');
|
|
153
|
+
field.className = 'field';
|
|
154
|
+
field.appendChild(control);
|
|
155
|
+
testContainer.appendChild(field);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
after(function () {
|
|
159
|
+
testContainer.removeChild(field);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('returns the first element in event\'s path that matches given selector', function () {
|
|
163
|
+
const test = (ev) => {
|
|
164
|
+
expect(findElementInEventPath(ev, '.control'), 'to be', control);
|
|
165
|
+
expect(findElementInEventPath(ev, '.field'), 'to be', field);
|
|
166
|
+
expect(findElementInEventPath(ev, 'div'), 'to be', control);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
document.addEventListener('click', test);
|
|
170
|
+
simulant.fire(input, 'click');
|
|
171
|
+
document.removeEventListener('click', test);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('returns undefined if no matched element is in event\'s path', function () {
|
|
175
|
+
const test = (ev) => {
|
|
176
|
+
expect(findElementInEventPath(ev, '.foo'), 'to be undefined',);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
document.addEventListener('click', test);
|
|
180
|
+
simulant.fire(input, 'click');
|
|
181
|
+
document.removeEventListener('click', test);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('stops searching when it reaches event\'s currentTarget', function () {
|
|
185
|
+
const test = (ev) => {
|
|
186
|
+
expect(findElementInEventPath(ev, '.control'), 'to be', control);
|
|
187
|
+
expect(findElementInEventPath(ev, '.field'), 'to be undefined',);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
control.addEventListener('click', test);
|
|
191
|
+
simulant.fire(input, 'click');
|
|
192
|
+
control.removeEventListener('click', test);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('function can be used to evaluate the condition instead of css selector', function () {
|
|
196
|
+
const test = (ev) => {
|
|
197
|
+
expect(findElementInEventPath(ev, target => [field, control].includes(target)), 'to be', control);
|
|
198
|
+
expect(findElementInEventPath(ev, target => target === field), 'to be', field);
|
|
199
|
+
expect(findElementInEventPath(ev, target => target.tagName === 'DIV'), 'to be', control);
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
document.addEventListener('click', test);
|
|
203
|
+
simulant.fire(input, 'click');
|
|
204
|
+
document.removeEventListener('click', test);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
});
|