aloha-vue 1.2.89 → 1.2.91
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/docs/src/views/Functions/PageFilterLimitTo/i18n/hr.json +3 -4
- package/docs/src/views/Functions/PageFilterList/i18n/hr.json +9 -10
- package/package.json +1 -1
- package/src/plugins/ASelectPlugin.js +1 -0
- package/src/plugins/ATinymcePlugin.js +7 -2
- package/src/styles/components/ui/ASelect.scss +11 -6
- package/src/ui/ASelect/ASelect.js +13 -1
- package/src/ui/ATinymce/ATinymce.js +5 -0
- package/src/ui/ATinymce/compositionAPI/ATinymceAPI.js +6 -0
- package/src/ui/ATinymce/plugins/MyPowerPaste.js +187 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_PAGE_FILTER_LIMIT_TO_ARGUMENTS_TEXT_": "
|
|
3
|
-
"_PAGE_FILTER_LIMIT_TO_ARGUMENTS_LIMIT_": "
|
|
4
|
-
"_PAGE_FILTER_LIMIT_TO_ARGUMENTS_MAX_THREE_DOTS_": "
|
|
5
|
-
"_PAGE_FILTER_LIMIT_TO_ARGUMENTS_": "# Argumenti: \ntext (string): Ulazni string čija će duljina biti ograničena\n[limit=30] (cijeli broj): Maksimalna duljina povratnog stringa\n[maxThreeDots=true] (boolean): Određuje hoće li se najviše tri točke vratiti na kraju povratnog stringa\n",
|
|
2
|
+
"_PAGE_FILTER_LIMIT_TO_ARGUMENTS_TEXT_": "Ulazni string čija će duljina biti ograničena.",
|
|
3
|
+
"_PAGE_FILTER_LIMIT_TO_ARGUMENTS_LIMIT_": "Maksimalna duljina povratnog stringa",
|
|
4
|
+
"_PAGE_FILTER_LIMIT_TO_ARGUMENTS_MAX_THREE_DOTS_": "Određuje hoće li se najviše tri točke vratiti na kraju povratnog stringa.",
|
|
6
5
|
"_PAGE_FILTER_LIMIT_TO_DESCRIPTION_": "Funkcija <strong>filterLimitTo</strong> koristi se za ograničavanje duljine ulaznog stringa na zadanu maksimalnu vrijednost, kao i za opcionalno primjenjivanje posebne logike točaka na kraju stringa."
|
|
7
6
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_ARRAY_": "
|
|
3
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_IS_HTML_": "
|
|
4
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_IS_SIMPLE_ARRAY_": "
|
|
5
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_KEY_CHILDREN_": "
|
|
6
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_KEY_LABEL_": "
|
|
7
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_KEY_LABEL_CALLBACK_": "
|
|
8
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_SEPARATOR_": "Separator
|
|
9
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_TAG_": "HTML
|
|
10
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_LIST_CLASS_": "CSS
|
|
11
|
-
"_PAGE_FILTER_LIST_ARGUMENTS_": "# Argumenti: \narray (niz): Niz od kojeg se kreira lista\n[isHtml=true] (boolean): Za istinitu vrijednost će se kreirati lista u HTML formatu (<ul><li>...</li></ul>). U suprotnom će se kreirati lista u tekstualnom formatu (<span>...</span>)\n[isSimpleArray=false] (boolean): Određuje hoće li se koristiti jednostavan niz bez objekata\n[keyChildren=\"\"] (string): Ključ za podelemente (samo ako je isSimpleArray=false)\n[keyLabel=\"\"] (string): Ključ teksta koji će biti prikazan (samo ako je isSimpleArray=false)\n[keyLabelCallback] (funkcija): Funkcija za generiranje oznaka s dva parametra (item, itemIndex)\n[separator=\", \"] (string): separator između elemenata (samo ako je isHtml=false)\n[tag=\"ul\"] (string): HTML oznaka za cijelu listu\n[listClass=\"\"] (sString): CSS klasa (a_list_without_styles)",
|
|
2
|
+
"_PAGE_FILTER_LIST_ARGUMENTS_ARRAY_": "Niz od kojeg se kreira lista",
|
|
3
|
+
"_PAGE_FILTER_LIST_ARGUMENTS_IS_HTML_": "Za <strong>istinitu</strong> vrijednost će se kreirati lista u HTML formatu (<ul><li>...</li></ul>). U suprotnom će se kreirati lista u tekstualnom formatu.",
|
|
4
|
+
"_PAGE_FILTER_LIST_ARGUMENTS_IS_SIMPLE_ARRAY_": "Određuje hoće li se koristiti jednostavan niz bez objekata.",
|
|
5
|
+
"_PAGE_FILTER_LIST_ARGUMENTS_KEY_CHILDREN_": "Ključ za podelemente (samo ako je <strong>isSimpleArray=false</strong>)",
|
|
6
|
+
"_PAGE_FILTER_LIST_ARGUMENTS_KEY_LABEL_": "Ključ teksta koji će biti prikazan (samo ako je <strong>isSimpleArray=false</strong>)",
|
|
7
|
+
"_PAGE_FILTER_LIST_ARGUMENTS_KEY_LABEL_CALLBACK_": "Funkcija za generiranje oznaka s dva parametra (<strong>item</strong>, <strong>itemIndex</strong>).",
|
|
8
|
+
"_PAGE_FILTER_LIST_ARGUMENTS_SEPARATOR_": "Separator separator između elemenata (samo ako je <strong>isHtml=false</strong>)",
|
|
9
|
+
"_PAGE_FILTER_LIST_ARGUMENTS_TAG_": "HTML oznaka za cijelu listu",
|
|
10
|
+
"_PAGE_FILTER_LIST_ARGUMENTS_LIST_CLASS_": "CSS klasa (Npr. a_list_without_styles)",
|
|
12
11
|
"_PAGE_FILTER_LIST_DESCRIPTION_": "Ova funkcija kreira listu od niza.",
|
|
13
12
|
"_PAGE_FILTER_LIST_IS_SIMPLE_ARRAY_TREE_HEADER_": "Struktura stabla isSimpleArray=true"
|
|
14
13
|
}
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@ export const tinymcePluginOptions = ref({
|
|
|
18
18
|
maxlength: undefined,
|
|
19
19
|
menu: undefined,
|
|
20
20
|
menubar: false,
|
|
21
|
-
plugins: "advlist code emoticons link lists table help",
|
|
21
|
+
plugins: "advlist code emoticons link lists table help example",
|
|
22
22
|
promotion: false,
|
|
23
23
|
rows: undefined,
|
|
24
24
|
toolbar: [
|
|
@@ -32,7 +32,12 @@ export const tinymcePluginOptions = ref({
|
|
|
32
32
|
{ name: "Hilfe", items: ["help"] },
|
|
33
33
|
],
|
|
34
34
|
toolbarMode: "wrap",
|
|
35
|
-
validElements: "@[style],a[href|target|title],strong/b,em/i,
|
|
35
|
+
validElements: "@[style],a[href|target|title],strong/b[style],em/i[style],br[style],p[style],span[style],ul[style],ol[style],li[style],table[],thead[],tbody[],th[],tr[],td[]",
|
|
36
|
+
validStyles: {
|
|
37
|
+
"*": "text-align,padding-left,text-decoration",
|
|
38
|
+
ul: "list-style-type",
|
|
39
|
+
ol: "list-style-type",
|
|
40
|
+
},
|
|
36
41
|
},
|
|
37
42
|
});
|
|
38
43
|
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
.a_select_toggle {
|
|
12
12
|
position: relative;
|
|
13
13
|
min-width: var(--a_select_min_width);
|
|
14
|
+
min-height: calc(26px + 0.375rem * 2);
|
|
15
|
+
padding-right: 30px;
|
|
14
16
|
text-align: left;
|
|
15
17
|
}
|
|
16
18
|
.a_select_toggle_closeable {
|
|
@@ -18,12 +20,14 @@
|
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
.a_caret {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
position: absolute;
|
|
27
|
+
right: 0;
|
|
28
|
+
top: 0;
|
|
29
|
+
height: 100%;
|
|
30
|
+
width: 30px;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
.a_select__search {
|
|
@@ -161,6 +165,7 @@
|
|
|
161
165
|
overflow-x: hidden;
|
|
162
166
|
text-overflow: ellipsis;
|
|
163
167
|
white-space: nowrap;
|
|
168
|
+
padding-right: 18px;
|
|
164
169
|
}
|
|
165
170
|
|
|
166
171
|
.a_select__ul_closeable {
|
|
@@ -56,6 +56,11 @@ export default {
|
|
|
56
56
|
required: false,
|
|
57
57
|
default: () => selectPluginOptions.value.propsDefault.buttonClass,
|
|
58
58
|
},
|
|
59
|
+
caretIcon: {
|
|
60
|
+
type: [String, Object],
|
|
61
|
+
required: false,
|
|
62
|
+
default: () => selectPluginOptions.value.propsDefault.caretIcon,
|
|
63
|
+
},
|
|
59
64
|
change: {
|
|
60
65
|
type: Function,
|
|
61
66
|
required: false,
|
|
@@ -614,7 +619,7 @@ export default {
|
|
|
614
619
|
h("div", {
|
|
615
620
|
ref: "buttonRef",
|
|
616
621
|
id: this.htmlIdLocal,
|
|
617
|
-
class: ["a_form_control a_select_toggle
|
|
622
|
+
class: ["a_form_control a_select_toggle", this.buttonClass, {
|
|
618
623
|
disabled: this.disabled,
|
|
619
624
|
a_select_toggle_closeable: this.isMultiselect && this.isSelectionCloseable,
|
|
620
625
|
a_form_control_invalid: this.isErrors,
|
|
@@ -853,6 +858,13 @@ export default {
|
|
|
853
858
|
]),
|
|
854
859
|
]),
|
|
855
860
|
]),
|
|
861
|
+
h("span", {
|
|
862
|
+
class: "a_caret",
|
|
863
|
+
}, [
|
|
864
|
+
h(AIcon, {
|
|
865
|
+
icon: this.caretIcon,
|
|
866
|
+
}),
|
|
867
|
+
])
|
|
856
868
|
]),
|
|
857
869
|
]),
|
|
858
870
|
]),
|
|
@@ -96,6 +96,11 @@ export default {
|
|
|
96
96
|
required: false,
|
|
97
97
|
default: () => tinymcePluginOptions.value.propsDefault.validElements,
|
|
98
98
|
},
|
|
99
|
+
validStyles: {
|
|
100
|
+
type: Object,
|
|
101
|
+
required: false,
|
|
102
|
+
default: () => tinymcePluginOptions.value.propsDefault.validStyles,
|
|
103
|
+
},
|
|
99
104
|
},
|
|
100
105
|
setup(props, context) {
|
|
101
106
|
const {
|
|
@@ -5,8 +5,11 @@ import {
|
|
|
5
5
|
watch,
|
|
6
6
|
} from "vue";
|
|
7
7
|
|
|
8
|
+
import MyPowerPaste from "../plugins/MyPowerPaste";
|
|
9
|
+
|
|
8
10
|
/* Import TinyMCE */
|
|
9
11
|
import tinymce from "tinymce";
|
|
12
|
+
tinymce.PluginManager.add("example", MyPowerPaste);
|
|
10
13
|
|
|
11
14
|
/* Default icons are required. After that, import custom icons if applicable */
|
|
12
15
|
import "tinymce/icons/default";
|
|
@@ -57,6 +60,7 @@ export default function ATinymceAPI(props, context, {
|
|
|
57
60
|
const toolbar = toRef(props, "toolbar");
|
|
58
61
|
const toolbarMode = toRef(props, "toolbarMode");
|
|
59
62
|
const validElements = toRef(props, "validElements");
|
|
63
|
+
const validStyles = toRef(props, "validStyles");
|
|
60
64
|
|
|
61
65
|
let vueEditor = null;
|
|
62
66
|
let modelValueLocal = undefined;
|
|
@@ -89,6 +93,8 @@ export default function ATinymceAPI(props, context, {
|
|
|
89
93
|
menubar: menubar.value,
|
|
90
94
|
readonly: !!disabled.value,
|
|
91
95
|
valid_elements: validElements.value,
|
|
96
|
+
valid_styles: validStyles.value,
|
|
97
|
+
|
|
92
98
|
setup: editor => {
|
|
93
99
|
vueEditor = editor;
|
|
94
100
|
editor.on("change input undo redo", () => {
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forEach,
|
|
3
|
+
} from "lodash-es";
|
|
4
|
+
|
|
5
|
+
export default function(editor) {
|
|
6
|
+
// Event-Handler für Einfügevorgänge
|
|
7
|
+
editor.on("paste", function(e) {
|
|
8
|
+
const clipboardData = (e.clipboardData || window.clipboardData);
|
|
9
|
+
e.stopPropagation();
|
|
10
|
+
e.preventDefault();
|
|
11
|
+
|
|
12
|
+
const PAGE_HTML = clipboardData.getData("text/html");
|
|
13
|
+
const HTML_FRAGMENT = extractTextBetween({
|
|
14
|
+
html: PAGE_HTML,
|
|
15
|
+
start: "<!--StartFragment-->",
|
|
16
|
+
end: "<!--EndFragment-->",
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
if (isMsWord({ html: PAGE_HTML })) {
|
|
20
|
+
editor.insertContent(parseWord({ html: HTML_FRAGMENT }));
|
|
21
|
+
} else {
|
|
22
|
+
const cleanedHtml = HTML_FRAGMENT.replace(/\sdata-[a-z0-9-]+="[^"]*"/gi, "").replace(/\saria-[a-z0-9-]+="[^"]*"/gi, "");
|
|
23
|
+
|
|
24
|
+
editor.insertContent(cleanedHtml);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
/* Return the metadata for the help plugin */
|
|
28
|
+
return {
|
|
29
|
+
getMetadata: () => ({
|
|
30
|
+
name: "My power paste",
|
|
31
|
+
url: "https://ilia-brykin.github.io/aloha/#/"
|
|
32
|
+
})
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function extractTextBetween({ html, start, end }) {
|
|
37
|
+
const startIndex = html.indexOf(start);
|
|
38
|
+
const endIndex = html.indexOf(end);
|
|
39
|
+
|
|
40
|
+
if (startIndex !== -1 && endIndex !== -1) {
|
|
41
|
+
return html.substring(startIndex + start.length, endIndex).trim();
|
|
42
|
+
}
|
|
43
|
+
return html;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isMsWord({ html }) {
|
|
47
|
+
const HTML_TAG = extractTextBetween({
|
|
48
|
+
html,
|
|
49
|
+
start: "<html",
|
|
50
|
+
end: ">",
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return HTML_TAG.indexOf(":office:word") !== -1;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function parseWord({ html }) {
|
|
57
|
+
const parser = new DOMParser();
|
|
58
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
59
|
+
const allChildren = doc.body.querySelectorAll(":scope > *");
|
|
60
|
+
|
|
61
|
+
const rootElement = document.createElement("div");
|
|
62
|
+
let currentList = null;
|
|
63
|
+
let lastLevel = 0;
|
|
64
|
+
const listStack = [];
|
|
65
|
+
|
|
66
|
+
forEach(allChildren, element => {
|
|
67
|
+
const isTagP = element.tagName === "P";
|
|
68
|
+
if (!isTagP) {
|
|
69
|
+
rootElement.appendChild(element);
|
|
70
|
+
lastLevel = 0;
|
|
71
|
+
currentList = null;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const isNormalParagraph = element.className.includes("MsoNormal");
|
|
76
|
+
const htmlContent = element.innerHTML.trim()
|
|
77
|
+
.replace(/<u>/g, "<span style=\"text-decoration: underline;\">")
|
|
78
|
+
.replace(/<\/u>/g, "</span>")
|
|
79
|
+
.replace(/<!--\[if !supportLists]-->.*?<!--\[endif]-->/gs, "")
|
|
80
|
+
.replace(/ /g, " ")
|
|
81
|
+
.replace(/^[\s·o§1-9]+[.)]?/g, "");
|
|
82
|
+
|
|
83
|
+
if (isTagP && isNormalParagraph && !element.className.includes("MsoListParagraph")) {
|
|
84
|
+
const newParagraph = document.createElement("p");
|
|
85
|
+
newParagraph.innerHTML = htmlContent;
|
|
86
|
+
rootElement.appendChild(newParagraph);
|
|
87
|
+
lastLevel = 0;
|
|
88
|
+
currentList = null;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const LIST_LEVEL = getCurrentLevelForList(element);
|
|
93
|
+
const { type, style } = getListTypeAndStyleFromSpanContent(element);
|
|
94
|
+
|
|
95
|
+
if (!currentList || LIST_LEVEL > lastLevel) {
|
|
96
|
+
const newList = document.createElement(type);
|
|
97
|
+
if (style) {
|
|
98
|
+
newList.style.listStyleType = style;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (currentList) {
|
|
102
|
+
currentList.appendChild(newList);
|
|
103
|
+
} else {
|
|
104
|
+
rootElement.appendChild(newList);
|
|
105
|
+
}
|
|
106
|
+
currentList = newList;
|
|
107
|
+
listStack.push({ element: newList, level: LIST_LEVEL });
|
|
108
|
+
} else if (LIST_LEVEL < lastLevel) {
|
|
109
|
+
while (listStack.length > 1 && LIST_LEVEL < listStack[listStack.length - 1].level) {
|
|
110
|
+
listStack.pop();
|
|
111
|
+
currentList = listStack[listStack.length - 1].element;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const li = document.createElement("li");
|
|
116
|
+
li.innerHTML = htmlContent;
|
|
117
|
+
currentList.appendChild(li);
|
|
118
|
+
|
|
119
|
+
lastLevel = LIST_LEVEL;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
return rootElement.innerHTML;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function getListTypeAndStyleFromSpanContent(p) {
|
|
126
|
+
const spans = p.querySelectorAll("span");
|
|
127
|
+
let spanContent = "";
|
|
128
|
+
forEach(spans, span => {
|
|
129
|
+
const styleAttr = span.getAttribute("style");
|
|
130
|
+
if (styleAttr && styleAttr.includes("mso-list:Ignore")) {
|
|
131
|
+
spanContent = span.textContent || "";
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
spanContent = spanContent.trim();
|
|
137
|
+
if (!spanContent) {
|
|
138
|
+
return { type: "ul", style: "" };
|
|
139
|
+
}
|
|
140
|
+
// Check for ordered list with Arabic numerals or numbers within parentheses
|
|
141
|
+
if (/^\d+[.)]/.test(spanContent) || /^\(\d+\)/.test(spanContent)) {
|
|
142
|
+
return { type: "ol", style: "" }; // Default style for <ol>
|
|
143
|
+
}
|
|
144
|
+
// Check for ordered list with uppercase Roman numerals
|
|
145
|
+
if (/^[IVXLCDM]+\./.test(spanContent)) {
|
|
146
|
+
return { type: "ol", style: "upper-roman" };
|
|
147
|
+
}
|
|
148
|
+
// Check for ordered list with lowercase Roman numerals
|
|
149
|
+
if (/^[ivxlcdm]+\./.test(spanContent)) {
|
|
150
|
+
return { type: "ol", style: "lower-roman" };
|
|
151
|
+
}
|
|
152
|
+
// Check for ordered list with uppercase letters
|
|
153
|
+
if (/^[A-Z]+[.)]/.test(spanContent)) {
|
|
154
|
+
return { type: "ol", style: "upper-alpha" };
|
|
155
|
+
}
|
|
156
|
+
// Check for ordered list with lowercase letters
|
|
157
|
+
if (/^[a-z]+[.)]/.test(spanContent)) {
|
|
158
|
+
return { type: "ol", style: "lower-alpha" };
|
|
159
|
+
}
|
|
160
|
+
// Check for unordered list with various symbols
|
|
161
|
+
if (/^[·o§]/.test(spanContent)) {
|
|
162
|
+
// Determine list style based on the symbol
|
|
163
|
+
let style;
|
|
164
|
+
switch (spanContent.trim()[0]) {
|
|
165
|
+
case "·": style = "disc"; break;
|
|
166
|
+
case "o": style = "circle"; break;
|
|
167
|
+
case "§": style = "square"; break;
|
|
168
|
+
default: style = "";
|
|
169
|
+
}
|
|
170
|
+
return { type: "ul", style: style };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return { type: "ul", style: "" };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function getCurrentLevelForList(p) {
|
|
177
|
+
const styleAttr = p.getAttribute("style");
|
|
178
|
+
let level = 1;
|
|
179
|
+
if (styleAttr) {
|
|
180
|
+
const levelMatch = styleAttr.match(/mso-list:l\d+ level(\d+)/);
|
|
181
|
+
if (levelMatch) {
|
|
182
|
+
level = parseInt(levelMatch[1], 10);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return level;
|
|
187
|
+
}
|