@evolvere/sgp-ui 1.6.8 → 1.6.10
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/lib/alert.js +420 -0
- package/lib/aside.js +277 -0
- package/lib/autocomplete.js +952 -0
- package/lib/avatar.js +363 -0
- package/lib/backtop.js +404 -0
- package/lib/badge.js +334 -0
- package/lib/breadcrumb-item.js +322 -0
- package/lib/breadcrumb.js +293 -0
- package/lib/button-group.js +262 -0
- package/lib/button.js +357 -0
- package/lib/calendar.js +933 -0
- package/lib/card.js +297 -0
- package/lib/carousel-item.js +434 -0
- package/lib/carousel.js +707 -0
- package/lib/cascader-panel.js +1557 -0
- package/lib/cascader.js +1438 -0
- package/lib/checkbox-button.js +583 -0
- package/lib/checkbox-group.js +313 -0
- package/lib/checkbox.js +627 -0
- package/lib/col.js +177 -0
- package/lib/collapse-item.js +497 -0
- package/lib/collapse.js +329 -0
- package/lib/color-picker.js +1943 -0
- package/lib/container.js +288 -0
- package/lib/date-picker.js +6228 -0
- package/lib/descriptions-item.js +140 -0
- package/lib/descriptions.js +457 -0
- package/lib/dialog.js +598 -0
- package/lib/directives/mousewheel.js +26 -0
- package/lib/directives/repeat-click.js +30 -0
- package/lib/divider.js +313 -0
- package/lib/drawer.js +592 -0
- package/lib/dropdown-item.js +316 -0
- package/lib/dropdown-menu.js +351 -0
- package/lib/dropdown.js +643 -0
- package/lib/editor.js +946 -0
- package/lib/empty.js +730 -0
- package/lib/footer.js +277 -0
- package/lib/form-item.js +821 -0
- package/lib/form.js +466 -0
- package/lib/header.js +277 -0
- package/lib/icon.js +265 -0
- package/lib/image.js +1131 -0
- package/lib/index.js +1 -0
- package/lib/infinite-scroll.js +301 -0
- package/lib/input-number.js +741 -0
- package/lib/input.js +995 -0
- package/lib/link.js +332 -0
- package/lib/loading.js +631 -0
- package/lib/locale/format.js +56 -0
- package/lib/locale/index.js +63 -0
- package/lib/locale/lang/af-ZA.js +123 -0
- package/lib/locale/lang/ar.js +122 -0
- package/lib/locale/lang/bg.js +123 -0
- package/lib/locale/lang/ca.js +122 -0
- package/lib/locale/lang/cs-CZ.js +125 -0
- package/lib/locale/lang/da.js +122 -0
- package/lib/locale/lang/de.js +124 -0
- package/lib/locale/lang/ee.js +123 -0
- package/lib/locale/lang/el.js +123 -0
- package/lib/locale/lang/en.js +123 -0
- package/lib/locale/lang/eo.js +123 -0
- package/lib/locale/lang/es.js +122 -0
- package/lib/locale/lang/eu.js +123 -0
- package/lib/locale/lang/fa.js +123 -0
- package/lib/locale/lang/fi.js +123 -0
- package/lib/locale/lang/fr.js +122 -0
- package/lib/locale/lang/he.js +123 -0
- package/lib/locale/lang/hr.js +123 -0
- package/lib/locale/lang/hu.js +122 -0
- package/lib/locale/lang/hy-AM.js +123 -0
- package/lib/locale/lang/id.js +123 -0
- package/lib/locale/lang/it.js +122 -0
- package/lib/locale/lang/ja.js +123 -0
- package/lib/locale/lang/kg.js +123 -0
- package/lib/locale/lang/km.js +123 -0
- package/lib/locale/lang/ko.js +123 -0
- package/lib/locale/lang/ku.js +123 -0
- package/lib/locale/lang/kz.js +123 -0
- package/lib/locale/lang/lt.js +123 -0
- package/lib/locale/lang/lv.js +123 -0
- package/lib/locale/lang/mn.js +123 -0
- package/lib/locale/lang/nb-NO.js +122 -0
- package/lib/locale/lang/nl.js +123 -0
- package/lib/locale/lang/pl.js +123 -0
- package/lib/locale/lang/pt-br.js +123 -0
- package/lib/locale/lang/pt.js +123 -0
- package/lib/locale/lang/ro.js +123 -0
- package/lib/locale/lang/ru-RU.js +123 -0
- package/lib/locale/lang/sk.js +125 -0
- package/lib/locale/lang/sl.js +123 -0
- package/lib/locale/lang/sr.js +123 -0
- package/lib/locale/lang/sv-SE.js +123 -0
- package/lib/locale/lang/ta.js +122 -0
- package/lib/locale/lang/th.js +123 -0
- package/lib/locale/lang/tk.js +123 -0
- package/lib/locale/lang/tr-TR.js +123 -0
- package/lib/locale/lang/ua.js +123 -0
- package/lib/locale/lang/ug-CN.js +123 -0
- package/lib/locale/lang/uz-UZ.js +123 -0
- package/lib/locale/lang/vi.js +123 -0
- package/lib/locale/lang/zh-CN.js +123 -0
- package/lib/locale/lang/zh-TW.js +123 -0
- package/lib/main.js +264 -0
- package/lib/menu-item-group.js +308 -0
- package/lib/menu-item.js +491 -0
- package/lib/menu.js +865 -0
- package/lib/message-box.js +1192 -0
- package/lib/message.js +548 -0
- package/lib/mixins/emitter.js +36 -0
- package/lib/mixins/focus.js +15 -0
- package/lib/mixins/locale.js +17 -0
- package/lib/mixins/migrating.js +69 -0
- package/lib/notification.js +615 -0
- package/lib/option-group.js +344 -0
- package/lib/option.js +474 -0
- package/lib/page-header.js +319 -0
- package/lib/pagination.js +950 -0
- package/lib/popconfirm.js +457 -0
- package/lib/popover.js +617 -0
- package/lib/progress.js +578 -0
- package/lib/radio-button.js +463 -0
- package/lib/radio-group.js +391 -0
- package/lib/radio.js +497 -0
- package/lib/rate.js +670 -0
- package/lib/rdc-sgp-ui.common.js +43848 -0
- package/lib/result.js +578 -0
- package/lib/row.js +149 -0
- package/lib/scrollbar.js +423 -0
- package/lib/select.js +2156 -0
- package/lib/skeleton-item.js +342 -0
- package/lib/skeleton.js +372 -0
- package/lib/slider.js +1199 -0
- package/lib/spinner.js +301 -0
- package/lib/step.js +522 -0
- package/lib/steps.js +342 -0
- package/lib/submenu.js +701 -0
- package/lib/switch.js +552 -0
- package/lib/tab-pane.js +332 -0
- package/lib/table-column.js +931 -0
- package/lib/table.js +4919 -0
- package/lib/tabs.js +920 -0
- package/lib/tag.js +304 -0
- package/lib/theme-chalk/alert.css +1 -0
- package/lib/theme-chalk/aside.css +1 -0
- package/lib/theme-chalk/autocomplete.css +1 -0
- package/lib/theme-chalk/avatar.css +1 -0
- package/lib/theme-chalk/backtop.css +1 -0
- package/lib/theme-chalk/badge.css +1 -0
- package/lib/theme-chalk/base.css +1 -0
- package/lib/theme-chalk/breadcrumb-item.css +0 -0
- package/lib/theme-chalk/breadcrumb.css +1 -0
- package/lib/theme-chalk/button-group.css +0 -0
- package/lib/theme-chalk/button.css +1 -0
- package/lib/theme-chalk/calendar.css +1 -0
- package/lib/theme-chalk/card.css +1 -0
- package/lib/theme-chalk/carousel-item.css +1 -0
- package/lib/theme-chalk/carousel.css +1 -0
- package/lib/theme-chalk/cascader-panel.css +1 -0
- package/lib/theme-chalk/cascader.css +1 -0
- package/lib/theme-chalk/checkbox-button.css +0 -0
- package/lib/theme-chalk/checkbox-group.css +0 -0
- package/lib/theme-chalk/checkbox.css +1 -0
- package/lib/theme-chalk/col.css +1 -0
- package/lib/theme-chalk/collapse-item.css +0 -0
- package/lib/theme-chalk/collapse.css +1 -0
- package/lib/theme-chalk/color-picker.css +1 -0
- package/lib/theme-chalk/container.css +1 -0
- package/lib/theme-chalk/date-picker.css +1 -0
- package/lib/theme-chalk/descriptions-item.css +1 -0
- package/lib/theme-chalk/descriptions.css +1 -0
- package/lib/theme-chalk/dialog.css +1 -0
- package/lib/theme-chalk/display.css +1 -0
- package/lib/theme-chalk/divider.css +1 -0
- package/lib/theme-chalk/drawer.css +1 -0
- package/lib/theme-chalk/dropdown-item.css +0 -0
- package/lib/theme-chalk/dropdown-menu.css +0 -0
- package/lib/theme-chalk/dropdown.css +1 -0
- package/lib/theme-chalk/editor.css +1 -0
- package/lib/theme-chalk/empty.css +1 -0
- package/lib/theme-chalk/fonts/element-icons.ttf +0 -0
- package/lib/theme-chalk/fonts/element-icons.woff +0 -0
- package/lib/theme-chalk/fonts/w-e-icon.woff +0 -0
- package/lib/theme-chalk/footer.css +1 -0
- package/lib/theme-chalk/form-item.css +0 -0
- package/lib/theme-chalk/form.css +1 -0
- package/lib/theme-chalk/header.css +1 -0
- package/lib/theme-chalk/icon.css +1 -0
- package/lib/theme-chalk/image.css +1 -0
- package/lib/theme-chalk/index.css +1 -0
- package/lib/theme-chalk/infinite-scroll.css +0 -0
- package/lib/theme-chalk/infiniteScroll.css +0 -0
- package/lib/theme-chalk/input-number.css +1 -0
- package/lib/theme-chalk/input.css +1 -0
- package/lib/theme-chalk/link.css +1 -0
- package/lib/theme-chalk/loading.css +1 -0
- package/lib/theme-chalk/main.css +1 -0
- package/lib/theme-chalk/menu-item-group.css +0 -0
- package/lib/theme-chalk/menu-item.css +0 -0
- package/lib/theme-chalk/menu.css +1 -0
- package/lib/theme-chalk/message-box.css +1 -0
- package/lib/theme-chalk/message.css +1 -0
- package/lib/theme-chalk/notification.css +1 -0
- package/lib/theme-chalk/option-group.css +1 -0
- package/lib/theme-chalk/option.css +1 -0
- package/lib/theme-chalk/page-header.css +1 -0
- package/lib/theme-chalk/pagination.css +1 -0
- package/lib/theme-chalk/popconfirm.css +1 -0
- package/lib/theme-chalk/popover.css +1 -0
- package/lib/theme-chalk/popper.css +1 -0
- package/lib/theme-chalk/progress.css +1 -0
- package/lib/theme-chalk/radio-button.css +1 -0
- package/lib/theme-chalk/radio-group.css +1 -0
- package/lib/theme-chalk/radio.css +1 -0
- package/lib/theme-chalk/rate.css +1 -0
- package/lib/theme-chalk/reset.css +1 -0
- package/lib/theme-chalk/result.css +1 -0
- package/lib/theme-chalk/row.css +1 -0
- package/lib/theme-chalk/scrollbar.css +1 -0
- package/lib/theme-chalk/select-dropdown.css +1 -0
- package/lib/theme-chalk/select.css +1 -0
- package/lib/theme-chalk/skeleton-item.css +1 -0
- package/lib/theme-chalk/skeleton.css +1 -0
- package/lib/theme-chalk/slider.css +1 -0
- package/lib/theme-chalk/spinner.css +1 -0
- package/lib/theme-chalk/step.css +1 -0
- package/lib/theme-chalk/steps.css +1 -0
- package/lib/theme-chalk/submenu.css +0 -0
- package/lib/theme-chalk/switch.css +1 -0
- package/lib/theme-chalk/tab-pane.css +0 -0
- package/lib/theme-chalk/table-column.css +1 -0
- package/lib/theme-chalk/table.css +1 -0
- package/lib/theme-chalk/tabs.css +1 -0
- package/lib/theme-chalk/tag.css +1 -0
- package/lib/theme-chalk/time-picker.css +1 -0
- package/lib/theme-chalk/time-select.css +1 -0
- package/lib/theme-chalk/timeline-item.css +1 -0
- package/lib/theme-chalk/timeline.css +1 -0
- package/lib/theme-chalk/tooltip.css +1 -0
- package/lib/theme-chalk/transfer.css +1 -0
- package/lib/theme-chalk/tree.css +1 -0
- package/lib/theme-chalk/upload.css +1 -0
- package/lib/time-picker.js +2923 -0
- package/lib/time-select.js +1732 -0
- package/lib/timeline-item.js +371 -0
- package/lib/timeline.js +275 -0
- package/lib/tooltip.js +424 -0
- package/lib/transfer.js +1102 -0
- package/lib/transitions/collapse-transition.js +91 -0
- package/lib/tree.js +2264 -0
- package/lib/umd/locale/af-ZA.js +139 -0
- package/lib/umd/locale/ar.js +138 -0
- package/lib/umd/locale/bg.js +139 -0
- package/lib/umd/locale/ca.js +138 -0
- package/lib/umd/locale/cs-CZ.js +141 -0
- package/lib/umd/locale/da.js +138 -0
- package/lib/umd/locale/de.js +140 -0
- package/lib/umd/locale/ee.js +139 -0
- package/lib/umd/locale/el.js +139 -0
- package/lib/umd/locale/en.js +139 -0
- package/lib/umd/locale/eo.js +139 -0
- package/lib/umd/locale/es.js +138 -0
- package/lib/umd/locale/eu.js +139 -0
- package/lib/umd/locale/fa.js +139 -0
- package/lib/umd/locale/fi.js +139 -0
- package/lib/umd/locale/fr.js +138 -0
- package/lib/umd/locale/he.js +139 -0
- package/lib/umd/locale/hr.js +139 -0
- package/lib/umd/locale/hu.js +138 -0
- package/lib/umd/locale/hy-AM.js +139 -0
- package/lib/umd/locale/id.js +139 -0
- package/lib/umd/locale/it.js +138 -0
- package/lib/umd/locale/ja.js +139 -0
- package/lib/umd/locale/kg.js +139 -0
- package/lib/umd/locale/km.js +139 -0
- package/lib/umd/locale/ko.js +139 -0
- package/lib/umd/locale/ku.js +139 -0
- package/lib/umd/locale/kz.js +139 -0
- package/lib/umd/locale/lt.js +139 -0
- package/lib/umd/locale/lv.js +139 -0
- package/lib/umd/locale/mn.js +139 -0
- package/lib/umd/locale/nb-NO.js +138 -0
- package/lib/umd/locale/nl.js +139 -0
- package/lib/umd/locale/pl.js +139 -0
- package/lib/umd/locale/pt-br.js +139 -0
- package/lib/umd/locale/pt.js +139 -0
- package/lib/umd/locale/ro.js +139 -0
- package/lib/umd/locale/ru-RU.js +139 -0
- package/lib/umd/locale/sk.js +141 -0
- package/lib/umd/locale/sl.js +139 -0
- package/lib/umd/locale/sr.js +139 -0
- package/lib/umd/locale/sv-SE.js +139 -0
- package/lib/umd/locale/ta.js +138 -0
- package/lib/umd/locale/th.js +139 -0
- package/lib/umd/locale/tk.js +139 -0
- package/lib/umd/locale/tr-TR.js +139 -0
- package/lib/umd/locale/ua.js +139 -0
- package/lib/umd/locale/ug-CN.js +139 -0
- package/lib/umd/locale/uz-UZ.js +139 -0
- package/lib/umd/locale/vi.js +139 -0
- package/lib/umd/locale/zh-CN.js +139 -0
- package/lib/umd/locale/zh-TW.js +139 -0
- package/lib/upload.js +1488 -0
- package/lib/utils/after-leave.js +35 -0
- package/lib/utils/aria-dialog.js +104 -0
- package/lib/utils/aria-utils.js +126 -0
- package/lib/utils/clickoutside.js +79 -0
- package/lib/utils/date-util.js +320 -0
- package/lib/utils/date.js +369 -0
- package/lib/utils/dom.js +234 -0
- package/lib/utils/menu/aria-menubar.js +24 -0
- package/lib/utils/menu/aria-menuitem.js +62 -0
- package/lib/utils/menu/aria-submenu.js +69 -0
- package/lib/utils/merge.js +21 -0
- package/lib/utils/popper.js +1261 -0
- package/lib/utils/popup/index.js +233 -0
- package/lib/utils/popup/popup-manager.js +205 -0
- package/lib/utils/resize-event.js +57 -0
- package/lib/utils/scroll-into-view.js +38 -0
- package/lib/utils/scrollbar-width.js +39 -0
- package/lib/utils/shared.js +12 -0
- package/lib/utils/types.js +30 -0
- package/lib/utils/util.js +268 -0
- package/lib/utils/vdom.js +13 -0
- package/lib/utils/vue-popper.js +202 -0
- package/package.json +4 -2
- package/packages/editor/src/html-security.js +180 -0
- package/packages/editor/src/index.vue +68 -15
- package/packages/editor/src/video-security.js +1 -0
- package/packages/theme-chalk/package.json +1 -1
- package/src/index.js +1 -1
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.isEmpty = exports.isEqual = exports.arrayEquals = exports.looseEqual = exports.capitalize = exports.kebabCase = exports.autoprefixer = exports.isFirefox = exports.isEdge = exports.isIE = exports.coerceTruthyValueToArray = exports.arrayFind = exports.arrayFindIndex = exports.escapeRegexpString = exports.valueEquals = exports.generateId = exports.getValueByPath = undefined;
|
|
5
|
+
|
|
6
|
+
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
7
|
+
|
|
8
|
+
exports.noop = noop;
|
|
9
|
+
exports.hasOwn = hasOwn;
|
|
10
|
+
exports.toObject = toObject;
|
|
11
|
+
exports.getPropByPath = getPropByPath;
|
|
12
|
+
exports.rafThrottle = rafThrottle;
|
|
13
|
+
exports.objToArray = objToArray;
|
|
14
|
+
|
|
15
|
+
var _vue = require('vue');
|
|
16
|
+
|
|
17
|
+
var _vue2 = _interopRequireDefault(_vue);
|
|
18
|
+
|
|
19
|
+
var _types = require('@evolvere/sgp-ui/lib/utils/types');
|
|
20
|
+
|
|
21
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
22
|
+
|
|
23
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
24
|
+
|
|
25
|
+
function noop() {};
|
|
26
|
+
|
|
27
|
+
function hasOwn(obj, key) {
|
|
28
|
+
return hasOwnProperty.call(obj, key);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function extend(to, _from) {
|
|
32
|
+
for (var key in _from) {
|
|
33
|
+
to[key] = _from[key];
|
|
34
|
+
}
|
|
35
|
+
return to;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
function toObject(arr) {
|
|
39
|
+
var res = {};
|
|
40
|
+
for (var i = 0; i < arr.length; i++) {
|
|
41
|
+
if (arr[i]) {
|
|
42
|
+
extend(res, arr[i]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return res;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
var getValueByPath = exports.getValueByPath = function getValueByPath(object, prop) {
|
|
49
|
+
prop = prop || '';
|
|
50
|
+
var paths = prop.split('.');
|
|
51
|
+
var current = object;
|
|
52
|
+
var result = null;
|
|
53
|
+
for (var i = 0, j = paths.length; i < j; i++) {
|
|
54
|
+
var path = paths[i];
|
|
55
|
+
if (!current) break;
|
|
56
|
+
|
|
57
|
+
if (i === j - 1) {
|
|
58
|
+
result = current[path];
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
current = current[path];
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
function getPropByPath(obj, path, strict) {
|
|
67
|
+
var tempObj = obj;
|
|
68
|
+
path = path.replace(/\[(\w+)\]/g, '.$1');
|
|
69
|
+
path = path.replace(/^\./, '');
|
|
70
|
+
|
|
71
|
+
var keyArr = path.split('.');
|
|
72
|
+
var i = 0;
|
|
73
|
+
for (var len = keyArr.length; i < len - 1; ++i) {
|
|
74
|
+
if (!tempObj && !strict) break;
|
|
75
|
+
var key = keyArr[i];
|
|
76
|
+
if (key in tempObj) {
|
|
77
|
+
tempObj = tempObj[key];
|
|
78
|
+
} else {
|
|
79
|
+
if (strict) {
|
|
80
|
+
throw new Error('please transfer a valid prop path to form item!');
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
o: tempObj,
|
|
87
|
+
k: keyArr[i],
|
|
88
|
+
v: tempObj ? tempObj[keyArr[i]] : null
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
var generateId = exports.generateId = function generateId() {
|
|
93
|
+
return Math.floor(Math.random() * 10000);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
var valueEquals = exports.valueEquals = function valueEquals(a, b) {
|
|
97
|
+
// see: https://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript
|
|
98
|
+
if (a === b) return true;
|
|
99
|
+
if (!(a instanceof Array)) return false;
|
|
100
|
+
if (!(b instanceof Array)) return false;
|
|
101
|
+
if (a.length !== b.length) return false;
|
|
102
|
+
for (var i = 0; i !== a.length; ++i) {
|
|
103
|
+
if (a[i] !== b[i]) return false;
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
var escapeRegexpString = exports.escapeRegexpString = function escapeRegexpString() {
|
|
109
|
+
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
110
|
+
return String(value).replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// TODO: use native Array.find, Array.findIndex when IE support is dropped
|
|
114
|
+
var arrayFindIndex = exports.arrayFindIndex = function arrayFindIndex(arr, pred) {
|
|
115
|
+
for (var i = 0; i !== arr.length; ++i) {
|
|
116
|
+
if (pred(arr[i])) {
|
|
117
|
+
return i;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return -1;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
var arrayFind = exports.arrayFind = function arrayFind(arr, pred) {
|
|
124
|
+
var idx = arrayFindIndex(arr, pred);
|
|
125
|
+
return idx !== -1 ? arr[idx] : undefined;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// coerce truthy value to array
|
|
129
|
+
var coerceTruthyValueToArray = exports.coerceTruthyValueToArray = function coerceTruthyValueToArray(val) {
|
|
130
|
+
if (Array.isArray(val)) {
|
|
131
|
+
return val;
|
|
132
|
+
} else if (val) {
|
|
133
|
+
return [val];
|
|
134
|
+
} else {
|
|
135
|
+
return [];
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
var isIE = exports.isIE = function isIE() {
|
|
140
|
+
return !_vue2.default.prototype.$isServer && !isNaN(Number(document.documentMode));
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
var isEdge = exports.isEdge = function isEdge() {
|
|
144
|
+
return !_vue2.default.prototype.$isServer && navigator.userAgent.indexOf('Edge') > -1;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
var isFirefox = exports.isFirefox = function isFirefox() {
|
|
148
|
+
return !_vue2.default.prototype.$isServer && !!window.navigator.userAgent.match(/firefox/i);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
var autoprefixer = exports.autoprefixer = function autoprefixer(style) {
|
|
152
|
+
if ((typeof style === 'undefined' ? 'undefined' : _typeof(style)) !== 'object') return style;
|
|
153
|
+
var rules = ['transform', 'transition', 'animation'];
|
|
154
|
+
var prefixes = ['ms-', 'webkit-'];
|
|
155
|
+
rules.forEach(function (rule) {
|
|
156
|
+
var value = style[rule];
|
|
157
|
+
if (rule && value) {
|
|
158
|
+
prefixes.forEach(function (prefix) {
|
|
159
|
+
style[prefix + rule] = value;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
return style;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
var kebabCase = exports.kebabCase = function kebabCase(str) {
|
|
167
|
+
var hyphenateRE = /([^-])([A-Z])/g;
|
|
168
|
+
return str.replace(hyphenateRE, '$1-$2').replace(hyphenateRE, '$1-$2').toLowerCase();
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
var capitalize = exports.capitalize = function capitalize(str) {
|
|
172
|
+
if (!(0, _types.isString)(str)) return str;
|
|
173
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
var looseEqual = exports.looseEqual = function looseEqual(a, b) {
|
|
177
|
+
var isObjectA = (0, _types.isObject)(a);
|
|
178
|
+
var isObjectB = (0, _types.isObject)(b);
|
|
179
|
+
if (isObjectA && isObjectB) {
|
|
180
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
181
|
+
} else if (!isObjectA && !isObjectB) {
|
|
182
|
+
return String(a) === String(b);
|
|
183
|
+
} else {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
var arrayEquals = exports.arrayEquals = function arrayEquals(arrayA, arrayB) {
|
|
189
|
+
arrayA = arrayA || [];
|
|
190
|
+
arrayB = arrayB || [];
|
|
191
|
+
|
|
192
|
+
if (arrayA.length !== arrayB.length) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
for (var i = 0; i < arrayA.length; i++) {
|
|
197
|
+
if (!looseEqual(arrayA[i], arrayB[i])) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return true;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
var isEqual = exports.isEqual = function isEqual(value1, value2) {
|
|
206
|
+
if (Array.isArray(value1) && Array.isArray(value2)) {
|
|
207
|
+
return arrayEquals(value1, value2);
|
|
208
|
+
}
|
|
209
|
+
return looseEqual(value1, value2);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
var isEmpty = exports.isEmpty = function isEmpty(val) {
|
|
213
|
+
// null or undefined
|
|
214
|
+
if (val == null) return true;
|
|
215
|
+
|
|
216
|
+
if (typeof val === 'boolean') return false;
|
|
217
|
+
|
|
218
|
+
if (typeof val === 'number') return !val;
|
|
219
|
+
|
|
220
|
+
if (val instanceof Error) return val.message === '';
|
|
221
|
+
|
|
222
|
+
switch (Object.prototype.toString.call(val)) {
|
|
223
|
+
// String or Array
|
|
224
|
+
case '[object String]':
|
|
225
|
+
case '[object Array]':
|
|
226
|
+
return !val.length;
|
|
227
|
+
|
|
228
|
+
// Map or Set or File
|
|
229
|
+
case '[object File]':
|
|
230
|
+
case '[object Map]':
|
|
231
|
+
case '[object Set]':
|
|
232
|
+
{
|
|
233
|
+
return !val.size;
|
|
234
|
+
}
|
|
235
|
+
// Plain Object
|
|
236
|
+
case '[object Object]':
|
|
237
|
+
{
|
|
238
|
+
return !Object.keys(val).length;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return false;
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
function rafThrottle(fn) {
|
|
246
|
+
var locked = false;
|
|
247
|
+
return function () {
|
|
248
|
+
var _this = this;
|
|
249
|
+
|
|
250
|
+
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
|
251
|
+
args[_key] = arguments[_key];
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (locked) return;
|
|
255
|
+
locked = true;
|
|
256
|
+
window.requestAnimationFrame(function (_) {
|
|
257
|
+
fn.apply(_this, args);
|
|
258
|
+
locked = false;
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function objToArray(obj) {
|
|
264
|
+
if (Array.isArray(obj)) {
|
|
265
|
+
return obj;
|
|
266
|
+
}
|
|
267
|
+
return isEmpty(obj) ? [] : [obj];
|
|
268
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
|
|
5
|
+
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
6
|
+
|
|
7
|
+
exports.isVNode = isVNode;
|
|
8
|
+
|
|
9
|
+
var _util = require('@evolvere/sgp-ui/lib/utils/util');
|
|
10
|
+
|
|
11
|
+
function isVNode(node) {
|
|
12
|
+
return node !== null && (typeof node === 'undefined' ? 'undefined' : _typeof(node)) === 'object' && (0, _util.hasOwn)(node, 'componentOptions');
|
|
13
|
+
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
|
|
5
|
+
var _vue = require('vue');
|
|
6
|
+
|
|
7
|
+
var _vue2 = _interopRequireDefault(_vue);
|
|
8
|
+
|
|
9
|
+
var _popup = require('@evolvere/sgp-ui/lib/utils/popup');
|
|
10
|
+
|
|
11
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
|
+
|
|
13
|
+
var PopperJS = _vue2.default.prototype.$isServer ? function () {} : require('./popper');
|
|
14
|
+
var stop = function stop(e) {
|
|
15
|
+
return e.stopPropagation();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {HTMLElement} [reference=$refs.reference] - The reference element used to position the popper.
|
|
20
|
+
* @param {HTMLElement} [popper=$refs.popper] - The HTML element used as popper, or a configuration used to generate the popper.
|
|
21
|
+
* @param {String} [placement=button] - Placement of the popper accepted values: top(-start, -end), right(-start, -end), bottom(-start, -end), left(-start, -end)
|
|
22
|
+
* @param {Number} [offset=0] - Amount of pixels the popper will be shifted (can be negative).
|
|
23
|
+
* @param {Boolean} [visible=false] Visibility of the popup element.
|
|
24
|
+
* @param {Boolean} [visible-arrow=false] Visibility of the arrow, no style.
|
|
25
|
+
*/
|
|
26
|
+
exports.default = {
|
|
27
|
+
props: {
|
|
28
|
+
transformOrigin: {
|
|
29
|
+
type: [Boolean, String],
|
|
30
|
+
default: true
|
|
31
|
+
},
|
|
32
|
+
placement: {
|
|
33
|
+
type: String,
|
|
34
|
+
default: 'bottom'
|
|
35
|
+
},
|
|
36
|
+
boundariesPadding: {
|
|
37
|
+
type: Number,
|
|
38
|
+
default: 5
|
|
39
|
+
},
|
|
40
|
+
reference: {},
|
|
41
|
+
popper: {},
|
|
42
|
+
offset: {
|
|
43
|
+
default: 0
|
|
44
|
+
},
|
|
45
|
+
value: Boolean,
|
|
46
|
+
visibleArrow: Boolean,
|
|
47
|
+
arrowOffset: {
|
|
48
|
+
type: Number,
|
|
49
|
+
default: 35
|
|
50
|
+
},
|
|
51
|
+
appendToBody: {
|
|
52
|
+
type: Boolean,
|
|
53
|
+
default: true
|
|
54
|
+
},
|
|
55
|
+
popperOptions: {
|
|
56
|
+
type: Object,
|
|
57
|
+
default: function _default() {
|
|
58
|
+
return {
|
|
59
|
+
gpuAcceleration: false
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
data: function data() {
|
|
66
|
+
return {
|
|
67
|
+
showPopper: false,
|
|
68
|
+
currentPlacement: ''
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
watch: {
|
|
74
|
+
value: {
|
|
75
|
+
immediate: true,
|
|
76
|
+
handler: function handler(val) {
|
|
77
|
+
this.showPopper = val;
|
|
78
|
+
this.$emit('input', val);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
showPopper: function showPopper(val) {
|
|
83
|
+
if (this.disabled) return;
|
|
84
|
+
val ? this.updatePopper() : this.destroyPopper();
|
|
85
|
+
this.$emit('input', val);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
methods: {
|
|
90
|
+
createPopper: function createPopper() {
|
|
91
|
+
var _this = this;
|
|
92
|
+
|
|
93
|
+
if (this.$isServer) return;
|
|
94
|
+
this.currentPlacement = this.currentPlacement || this.placement;
|
|
95
|
+
if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.currentPlacement)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
var options = this.popperOptions;
|
|
100
|
+
var popper = this.popperElm = this.popperElm || this.popper || this.$refs.popper;
|
|
101
|
+
var reference = this.referenceElm = this.referenceElm || this.reference || this.$refs.reference;
|
|
102
|
+
|
|
103
|
+
if (!reference && this.$slots.reference && this.$slots.reference[0]) {
|
|
104
|
+
reference = this.referenceElm = this.$slots.reference[0].elm;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!popper || !reference) return;
|
|
108
|
+
if (this.visibleArrow) this.appendArrow(popper);
|
|
109
|
+
if (this.appendToBody) document.body.appendChild(this.popperElm);
|
|
110
|
+
if (this.popperJS && this.popperJS.destroy) {
|
|
111
|
+
this.popperJS.destroy();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
options.placement = this.currentPlacement;
|
|
115
|
+
options.offset = this.offset;
|
|
116
|
+
options.arrowOffset = this.arrowOffset;
|
|
117
|
+
this.popperJS = new PopperJS(reference, popper, options);
|
|
118
|
+
this.popperJS.onCreate(function (_) {
|
|
119
|
+
_this.$emit('created', _this);
|
|
120
|
+
_this.resetTransformOrigin();
|
|
121
|
+
_this.$nextTick(_this.updatePopper);
|
|
122
|
+
});
|
|
123
|
+
if (typeof options.onUpdate === 'function') {
|
|
124
|
+
this.popperJS.onUpdate(options.onUpdate);
|
|
125
|
+
}
|
|
126
|
+
this.popperJS._popper.style.zIndex = _popup.PopupManager.nextZIndex();
|
|
127
|
+
this.popperElm.addEventListener('click', stop);
|
|
128
|
+
},
|
|
129
|
+
updatePopper: function updatePopper() {
|
|
130
|
+
var popperJS = this.popperJS;
|
|
131
|
+
if (popperJS) {
|
|
132
|
+
popperJS.update();
|
|
133
|
+
if (popperJS._popper) {
|
|
134
|
+
popperJS._popper.style.zIndex = _popup.PopupManager.nextZIndex();
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
this.createPopper();
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
doDestroy: function doDestroy(forceDestroy) {
|
|
141
|
+
/* istanbul ignore if */
|
|
142
|
+
if (!this.popperJS || this.showPopper && !forceDestroy) return;
|
|
143
|
+
this.popperJS.destroy();
|
|
144
|
+
this.popperJS = null;
|
|
145
|
+
},
|
|
146
|
+
destroyPopper: function destroyPopper() {
|
|
147
|
+
if (this.popperJS) {
|
|
148
|
+
this.resetTransformOrigin();
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
resetTransformOrigin: function resetTransformOrigin() {
|
|
152
|
+
if (!this.transformOrigin) return;
|
|
153
|
+
var placementMap = {
|
|
154
|
+
top: 'bottom',
|
|
155
|
+
bottom: 'top',
|
|
156
|
+
left: 'right',
|
|
157
|
+
right: 'left'
|
|
158
|
+
};
|
|
159
|
+
var placement = this.popperJS._popper.getAttribute('x-placement').split('-')[0];
|
|
160
|
+
var origin = placementMap[placement];
|
|
161
|
+
this.popperJS._popper.style.transformOrigin = typeof this.transformOrigin === 'string' ? this.transformOrigin : ['top', 'bottom'].indexOf(placement) > -1 ? 'center ' + origin : origin + ' center';
|
|
162
|
+
},
|
|
163
|
+
appendArrow: function appendArrow(element) {
|
|
164
|
+
var hash = void 0;
|
|
165
|
+
if (this.appended) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
this.appended = true;
|
|
170
|
+
|
|
171
|
+
for (var item in element.attributes) {
|
|
172
|
+
if (/^_v-/.test(element.attributes[item].name)) {
|
|
173
|
+
hash = element.attributes[item].name;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
var arrow = document.createElement('div');
|
|
179
|
+
|
|
180
|
+
if (hash) {
|
|
181
|
+
arrow.setAttribute(hash, '');
|
|
182
|
+
}
|
|
183
|
+
arrow.setAttribute('x-arrow', '');
|
|
184
|
+
arrow.className = 'popper__arrow';
|
|
185
|
+
element.appendChild(arrow);
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
beforeDestroy: function beforeDestroy() {
|
|
190
|
+
this.doDestroy(true);
|
|
191
|
+
if (this.popperElm && this.popperElm.parentNode === document.body) {
|
|
192
|
+
this.popperElm.removeEventListener('click', stop);
|
|
193
|
+
document.body.removeChild(this.popperElm);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
// call destroy in keep-alive mode
|
|
199
|
+
deactivated: function deactivated() {
|
|
200
|
+
this.$options.beforeDestroy[0].call(this);
|
|
201
|
+
}
|
|
202
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evolvere/sgp-ui",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.10",
|
|
4
4
|
"description": "A Component Library for Vue.js.",
|
|
5
5
|
"main": "lib/rdc-sgp-ui.common.js",
|
|
6
6
|
"files": [
|
|
@@ -27,8 +27,9 @@
|
|
|
27
27
|
"lint": "eslint src/**/* test/**/* packages/**/* build/**/* --quiet",
|
|
28
28
|
"pub1": "npm run bootstrap && sh build/git-release.sh && sh build/release.sh && node build/bin/gen-indices.js && sh build/deploy-faas.sh",
|
|
29
29
|
"test": "npm run lint && npm run build:theme && cross-env CI_ENV=/dev/ BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
|
|
30
|
+
"test:editor-security": "cross-env BABEL_ENV=test karma start test/unit/karma.editor-security.conf.js --single-run",
|
|
30
31
|
"test:watch": "npm run build:theme && cross-env BABEL_ENV=test karma start test/unit/karma.conf.js",
|
|
31
|
-
"pub": "sh build/release.sh
|
|
32
|
+
"pub": "sh build/release.sh"
|
|
32
33
|
},
|
|
33
34
|
"faas": [
|
|
34
35
|
{
|
|
@@ -64,6 +65,7 @@
|
|
|
64
65
|
"async-validator": "~1.8.1",
|
|
65
66
|
"babel-helper-vue-jsx-merge-props": "^2.0.0",
|
|
66
67
|
"deepmerge": "^1.2.0",
|
|
68
|
+
"dompurify": "3.4.14",
|
|
67
69
|
"normalize-wheel": "^1.0.1",
|
|
68
70
|
"resize-observer-polyfill": "^1.5.0",
|
|
69
71
|
"throttle-debounce": "^1.0.1",
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import DOMPurify from 'dompurify';
|
|
2
|
+
|
|
3
|
+
export const MAX_EDITOR_HTML_LENGTH = 1024 * 1024;
|
|
4
|
+
export const MAX_IMAGE_SIZE = 5 * 1024 * 1024;
|
|
5
|
+
export const MAX_IMAGE_COUNT = 10;
|
|
6
|
+
|
|
7
|
+
const SAFE_PROTOCOLS = ['http:', 'https:'];
|
|
8
|
+
const SAFE_LINK_PROTOCOLS = SAFE_PROTOCOLS.concat(['mailto:', 'tel:']);
|
|
9
|
+
const SAFE_URI_PATTERN = /^(?:(?:https?|mailto|tel):|(?:\.{0,2}\/|#))/i;
|
|
10
|
+
|
|
11
|
+
const PURIFY_OPTIONS = {
|
|
12
|
+
ALLOWED_TAGS: [
|
|
13
|
+
'a', 'b', 'blockquote', 'br', 'code', 'del', 'div', 'em', 'h1', 'h2',
|
|
14
|
+
'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'iframe', 'img', 'li', 'ol', 'p',
|
|
15
|
+
'pre', 's', 'span', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody',
|
|
16
|
+
'td', 'tfoot', 'th', 'thead', 'tr', 'u', 'ul', 'video', 'source'
|
|
17
|
+
],
|
|
18
|
+
ALLOWED_ATTR: [
|
|
19
|
+
'allow', 'allowfullscreen', 'alt', 'colspan', 'controls', 'frameborder',
|
|
20
|
+
'height', 'href', 'loading', 'loop', 'muted', 'playsinline', 'poster',
|
|
21
|
+
'preload', 'referrerpolicy', 'rel', 'rowspan', 'sandbox', 'src', 'style',
|
|
22
|
+
'target', 'title', 'webkitallowfullscreen', 'width'
|
|
23
|
+
],
|
|
24
|
+
// These attributes carry fixed policy tokens rather than URLs. DOMPurify
|
|
25
|
+
// otherwise applies its URI value check and removes the security settings.
|
|
26
|
+
ADD_URI_SAFE_ATTR: ['loading', 'referrerpolicy', 'rel', 'sandbox', 'target'],
|
|
27
|
+
ALLOW_ARIA_ATTR: false,
|
|
28
|
+
ALLOW_DATA_ATTR: false,
|
|
29
|
+
ALLOW_UNKNOWN_PROTOCOLS: false,
|
|
30
|
+
ALLOWED_URI_REGEXP: SAFE_URI_PATTERN,
|
|
31
|
+
FORBID_TAGS: [
|
|
32
|
+
'base', 'button', 'embed', 'form', 'input', 'link', 'math', 'meta',
|
|
33
|
+
'noscript', 'object', 'option', 'script', 'select', 'style', 'svg',
|
|
34
|
+
'template', 'textarea'
|
|
35
|
+
],
|
|
36
|
+
FORBID_ATTR: ['formaction', 'id', 'name', 'srcdoc', 'xlink:href'],
|
|
37
|
+
KEEP_CONTENT: true,
|
|
38
|
+
RETURN_TRUSTED_TYPE: false,
|
|
39
|
+
SANITIZE_DOM: true,
|
|
40
|
+
SANITIZE_NAMED_PROPS: true
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const COLOR_VALUE = /^(?:#[0-9a-f]{3,8}|[a-z]{1,20}|rgba?\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}(?:\s*,\s*(?:0|1|0?\.\d+))?\s*\))$/i;
|
|
44
|
+
const LENGTH_VALUE = /^\d+(?:\.\d+)?(?:px|em|rem|%)?$/i;
|
|
45
|
+
const FONT_FAMILY_VALUE = /^[a-z0-9\u4e00-\u9fff ,'-]{1,120}$/i;
|
|
46
|
+
|
|
47
|
+
const SAFE_STYLE_RULES = {
|
|
48
|
+
'background-color': COLOR_VALUE,
|
|
49
|
+
color: COLOR_VALUE,
|
|
50
|
+
'font-family': FONT_FAMILY_VALUE,
|
|
51
|
+
'font-size': LENGTH_VALUE,
|
|
52
|
+
'font-style': /^(?:normal|italic|oblique)$/i,
|
|
53
|
+
'font-weight': /^(?:normal|bold|bolder|lighter|[1-9]00)$/i,
|
|
54
|
+
'line-height': LENGTH_VALUE,
|
|
55
|
+
'list-style-type': /^(?:disc|circle|square|decimal|lower-alpha|upper-alpha|lower-roman|upper-roman|none)$/i,
|
|
56
|
+
'margin-left': LENGTH_VALUE,
|
|
57
|
+
'max-width': LENGTH_VALUE,
|
|
58
|
+
'padding-left': LENGTH_VALUE,
|
|
59
|
+
'text-align': /^(?:left|right|center|justify)$/i,
|
|
60
|
+
'text-decoration': /^(?:none|underline|line-through)(?:\s+(?:underline|line-through))*$/i,
|
|
61
|
+
'text-indent': LENGTH_VALUE,
|
|
62
|
+
'vertical-align': /^(?:baseline|sub|super|top|text-top|middle|bottom|text-bottom)$/i,
|
|
63
|
+
'white-space': /^(?:normal|nowrap|pre|pre-wrap|pre-line)$/i
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
function parseUrl(value) {
|
|
67
|
+
const url = (value || '').trim();
|
|
68
|
+
if (!url || /[\u0000-\u001f\u007f]/.test(url)) return null;
|
|
69
|
+
|
|
70
|
+
const parser = document.createElement('a');
|
|
71
|
+
parser.href = url;
|
|
72
|
+
return parser;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function hasSafeProtocol(value, protocols) {
|
|
76
|
+
const parser = parseUrl(value);
|
|
77
|
+
return !!parser && protocols.indexOf(parser.protocol.toLowerCase()) !== -1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function isSafeLink(link) {
|
|
81
|
+
return hasSafeProtocol(link, SAFE_LINK_PROTOCOLS);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function isSafeMediaSource(source) {
|
|
85
|
+
return hasSafeProtocol(source, SAFE_PROTOCOLS);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function sanitizeStyle(styleText) {
|
|
89
|
+
if (!styleText || styleText.length > 500 || /[\\<>{}]|url\s*\(|expression\s*\(|@import|javascript\s*:|data\s*:|-moz-binding|behavior\s*:/i.test(styleText)) {
|
|
90
|
+
return '';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return styleText.split(';').reduce((rules, declaration) => {
|
|
94
|
+
const separator = declaration.indexOf(':');
|
|
95
|
+
if (separator === -1) return rules;
|
|
96
|
+
|
|
97
|
+
const property = declaration.slice(0, separator).trim().toLowerCase();
|
|
98
|
+
const value = declaration.slice(separator + 1).trim();
|
|
99
|
+
const rule = SAFE_STYLE_RULES[property];
|
|
100
|
+
if (rule && rule.test(value)) rules.push(`${property}: ${value}`);
|
|
101
|
+
return rules;
|
|
102
|
+
}, []).join('; ');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function normalizeDimension(element, attribute) {
|
|
106
|
+
if (!element.hasAttribute(attribute)) return;
|
|
107
|
+
const value = Number(element.getAttribute(attribute));
|
|
108
|
+
if (!Number.isInteger(value) || value < 1 || value > 10000) {
|
|
109
|
+
element.removeAttribute(attribute);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function normalizeRichText(html) {
|
|
114
|
+
const template = document.createElement('template');
|
|
115
|
+
template.innerHTML = html;
|
|
116
|
+
const elements = Array.prototype.slice.call(template.content.querySelectorAll('*'));
|
|
117
|
+
|
|
118
|
+
elements.forEach(element => {
|
|
119
|
+
const style = sanitizeStyle(element.getAttribute('style'));
|
|
120
|
+
if (style) element.setAttribute('style', style);
|
|
121
|
+
else element.removeAttribute('style');
|
|
122
|
+
|
|
123
|
+
normalizeDimension(element, 'width');
|
|
124
|
+
normalizeDimension(element, 'height');
|
|
125
|
+
|
|
126
|
+
if (element.tagName === 'A') {
|
|
127
|
+
if (!isSafeLink(element.getAttribute('href'))) element.removeAttribute('href');
|
|
128
|
+
if (element.getAttribute('target') === '_blank') {
|
|
129
|
+
element.setAttribute('rel', 'noopener noreferrer');
|
|
130
|
+
} else {
|
|
131
|
+
element.removeAttribute('target');
|
|
132
|
+
element.removeAttribute('rel');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (element.tagName === 'IMG') {
|
|
137
|
+
if (!isSafeMediaSource(element.getAttribute('src'))) {
|
|
138
|
+
element.parentNode.removeChild(element);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
element.setAttribute('loading', 'lazy');
|
|
142
|
+
element.setAttribute('referrerpolicy', 'no-referrer');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (element.tagName === 'IFRAME') {
|
|
146
|
+
if (!isSafeMediaSource(element.getAttribute('src'))) {
|
|
147
|
+
element.parentNode.removeChild(element);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
element.setAttribute('sandbox', 'allow-scripts allow-presentation allow-popups');
|
|
151
|
+
element.setAttribute('referrerpolicy', 'no-referrer');
|
|
152
|
+
element.setAttribute('loading', 'lazy');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if ((element.tagName === 'VIDEO' || element.tagName === 'SOURCE') &&
|
|
156
|
+
!isSafeMediaSource(element.getAttribute('src'))) {
|
|
157
|
+
element.parentNode.removeChild(element);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
return template.innerHTML;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function sanitizeEditorHtml(html) {
|
|
165
|
+
if (typeof html !== 'string' || html.length > MAX_EDITOR_HTML_LENGTH) return '';
|
|
166
|
+
|
|
167
|
+
const sanitized = DOMPurify.sanitize(html, PURIFY_OPTIONS);
|
|
168
|
+
const normalized = normalizeRichText(sanitized);
|
|
169
|
+
return DOMPurify.sanitize(normalized, PURIFY_OPTIONS);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function validateImageFiles(files) {
|
|
173
|
+
if (!files || files.length < 1 || files.length > MAX_IMAGE_COUNT) return false;
|
|
174
|
+
return Array.prototype.every.call(files, file => (
|
|
175
|
+
!!file &&
|
|
176
|
+
file.size > 0 &&
|
|
177
|
+
file.size <= MAX_IMAGE_SIZE &&
|
|
178
|
+
/^(?:image\/jpeg|image\/png|image\/gif)$/i.test(file.type || '')
|
|
179
|
+
));
|
|
180
|
+
}
|