PageSourceSearch

https://www.bluefjord.cz/JsWeb1693853823.js

js bluefjord.cz collected 2026-10-08 06:13:45 UTC 257,564 bytes, 8,847 lines download raw bytes

1var webroot = '/';
2var coreroot = '/Grace/';
3var filesroot = '/';
4var logged = false;
5var maxfilesize = 20971520000;
6var lang = 'cs';
7var admin = false;
8var admin_logged = false;
9var debug = false;
10var theme_path = 'Grace/Themes/BlueFjord/';
11var loglink = location.href;
12var use_service_worker = true;
13var grace_stats_key = 'f11863c2d49c69ab6a04c01cb15cb28a55fe0c39';
14var GraceObjects = {};
15function GraceWeb(dom)
16{
17if (typeof dom == 'string') {
18var dom_string = dom;
19dom = document.createElement('div');
20dom.innerHTML = dom_string;
21}
22var dom = (dom == undefined) ? [document.querySelector('html')] : (dom.nodeType == undefined ? dom : [dom]);
23if (!dom.push) {
24let d = [];
25for (let i in dom) {
26if (typeof dom[i] == 'object') {
27d.push(dom[i]);
28}
29}
30dom = d;
31}
32var self = this;
33this.dom = function(nth) {
34if (nth != undefined) {
35return dom[nth];
36}
37return dom;
38};
39this.GetTagName = function() {
40return this.dom(0).tagName.toLowerCase();
41};
42this.AddElements = function(g) {
43if (!dom.push) {
44dom = [dom];
45}
46g.each(function(el) {
47dom.push(el.dom(0));
48});
49};
50this.RemoveElements = function(g) {
51var new_dom = [];
52for (var i = 0; i < g.Count(); i++) {
53for (var j = 0; j < self.Count(); j++) {
54if (g.dom(i).isSameNode(self.dom(j))) {
55delete dom[j];
56} else {
57new_dom.push(dom[j]);
58}
59}
60}
61dom = new_dom;
62};
63this.SelectFromStart = function(cnt) {
64let gw = new GraceWeb([]);
65let i = 0;
66self.each(function(el) {
67gw.AddElements(el);
68if (i + 1 >= cnt) return false;
69i++;
70});
71return gw;
72};
73this.SelectFromEnd = function(cnt) {
74let gw = new GraceWeb([]);
75let i = 0;
76self.each(function(el) {
77gw.AddElements(el);
78if (i + 1 < self.Count() - cnt) return false;
79i++;
80});
81return gw;
82};
83this.Select = function(nth) {
84if (self.dom(nth) == undefined || typeof self.dom(nth) != 'object') return null;
85return new GraceWeb(self.dom(nth));
86};
87this.SelectLast = function() {
88let el = self.dom(self.Count() - 1);
89if (el) {
90return new GraceWeb(el);
91} else {
92return null;
93}
94};
95this.Count = function() {
96return self.dom().length;
97};
98this.Contains = function(in_el)
99{
100let is_in = false;
101this.each(function(el) {
102in_el.each(function(el_in_el) {
103if (el.dom(0).isSameNode(el_in_el.dom(0))) {
104is_in = true;
105return false;
106}
107});
108if (is_in) return false;
109});
110if (!is_in) {
111let children = this.DirectChildren();
112if (children) is_in = children.Contains(in_el);
113}
114return is_in;
115}
116this.remove = function() {
117self.each(function(el) {
118let elements = el.children('*');
119elements.AddElements(el);
120elements.e.CancelAll();
121el = el.dom(0);
122if (el.parentNode) {
123el.parentNode.removeChild(el);
124}
125});
126};
127this.FindFirstElementType = function()
128{
129let el_dom;
130self.each(function(el) {
131if (el_dom || !el.dom(0)) return;
132if (el.dom(0).nodeType == 1) el_dom = el;
133});
134return el_dom;
135};
136this.children = function(selector, test) {
137let el = self.FindFirstElementType();
138if (!el) return self;
139return new GraceWeb(el.dom(0).querySelectorAll(selector));
140};
141this.Children = function(selector, check_current) {
142let children = new GraceWeb([]);
143if (check_current == undefined) check_current = true;
144this.each(function(el) {
145el = el.FindFirstElementType();
146if (check_current && el.IsSelector(selector)) children.AddElements(el);
147if (el) {
148children.AddElements(el.children(selector));
149} else {
150children.AddElements(el);
151}
152});
153return children;
154};
155this.FindFirst = function(selector, check_current) {
156if (check_current == undefined) check_current = true;
157let found_el = null;
158this.each(function(el) {
159//el = el.FindFirstElementType();
160if (check_current && el.IsSelector(selector)) {
161found_el = el;
162return false;
163}
164if (el) {
165let found = el.dom(0).querySelector(selector);
166if (found) {
167found_el = new GraceWeb(found);
168return false;
169}
170}
171});
172return found_el;
173};
174this.SelectBySelector = function(selector) {
175let found_el = null;
176this.each(function(el) {
177//el = el.FindFirstElementType();
178if (el.IsSelector(selector)) {
179found_el = el;
180return false;
181}
182});
183return found_el;
184};
185this.DirectChildren = function() {
186let data = [];
187this.each(function(el) {
188let doms = el.dom(0).childNodes;
189for (let i in doms) {
190if (doms[i].nodeType == 1) {
191data.push(doms[i]);
192}
193}
194});
195return data.length > 0 ? new GraceWeb(data) : null;
196};
197this.parent = function(selector) {
198if (self.Count() == 0) return null;
199if (self.dom(0).closest) {
200let parent = self.dom(0).parentNode;
201if (!parent) return null;
202if (parent.closest) {
203parent = parent.closest(selector);
204} else {
205return null;
206}
207if (!parent) return null;
208return new GraceWeb(parent);
209}
210var current_element = self.dom(0);
211var g = new GraceWeb(self.dom(0).parentNode);
212var currentcount = g.children(selector).Count();
213var parent = self.Select(0).DirectParent();
214while (parent) {
215var g = parent;
216if (!g || !g.Count()) return null;
217if (g.children(selector).Count() > currentcount) {
218let chosen_e;
219g.children(selector).each(function(e) {
220if (!chosen_e && e.dom(0).contains(current_element)) {
221chosen_e = e;
222}
223});
224if (chosen_e) return chosen_e;
225}
226parent = parent.DirectParent();
227}
228return null;
229};
230this.DirectParent = function() {
231if (self.Count() == 0) return null;
232let d = self.dom(0).parentNode;
233if (!d) return null;
234return new GraceWeb(d);
235};
236this.parents = function(selector) {
237if (self.Count() == 0) return self;
238var actual_g = new GraceWeb(self.dom(0));
239var actual_selector = actual_g.dom(0).nodeName;
240if (actual_g.class.getList().length) actual_selector += '.' + actual_g.class.getList().join('.');
241if (actual_g.attr.get('id')) actual_selector += '[id="' + actual_g.attr.get('id') + '"]';
242if (actual_g.attr.get('name')) actual_selector += '[name="' + actual_g.attr.get('name') + '"]';
243var g = new GraceWeb();
244g = g.children(selector); // all possible parents
245var found;
246for (var i = 0; i < g.Count(); i++) {
247var ch = g.Select(i);
248var children = ch.children(actual_selector);
249for (var j = 0; j < children.Count(); j++) {
250if (children.Select(j).dom(0) === actual_g.dom(0)) {
251if (found) {
252found.Add(ch);
253} else {
254found = ch;
255}
256}
257}
258}
259if (!found) return null;
260return found;
261};
262this.IsSelector = function(selector)
263{
264let yes = true;
265self.each(function(el) {
266if (el.dom(0).matches) {
267if (!el.dom(0).matches(selector)) {
268yes = false;
269return false;
270}
271return;
272}
273let div = g.NewElementFromHTML('<div></div>');
274el = el.clone();
275el.SetHTML('');
276div.append(el);
277if (!div.children(selector).Count()) {
278yes = false;
279return false;
280}
281});
282return yes;
283};
284this.next = function() {
285let nexts = [];
286self.each(function(el) {
287var found = false;
288var next = el.dom(0).nextSibling;
289while (!found && next) {
290if (next.nodeType == 1) {
291found = true;
292break;
293}
294next = next.nextSibling;
295}
296if (found) {
297nexts.push(next);
298}
299});
300if (!nexts.length) return null;
301return new GraceWeb(nexts);
302};
303this.NextAll = function(selector)
304{
305let d = new GraceWeb([]);
306self.each(function(el) {
307while (el = el.next()) {
308if (!selector || el.IsSelector(selector)) d.AddElements(el);
309}
310});
311return d;
312};
313this.NextFirst = function(selector)
314{
315let d = new GraceWeb([]);
316self.each(function(el) {
317while (el = el.next()) {
318if (!selector || el.IsSelector(selector)) {
319d.AddElements(el);
320return false;
321}
322}
323});
324return d;
325};
326this.previous = function() {
327var found = false;
328if (!self.dom(0)) return null;
329var next = self.dom(0).previousSibling;
330while (!found && next) {
331if (next.nodeType == 1) {
332found = true;
333break;
334}
335next = next.previousSibling;
336}
337if (!found) return null;
338return new GraceWeb(next);
339};
340this.PreviousAll = function(selector)
341{
342let d = new GraceWeb([]);
343self.each(function(el) {
344while (el = el.previous()) {
345if (!selector || el.IsSelector(selector)) d.AddElements(el);
346}
347});
348return d;
349};
350this.PreviousFirst = function(selector)
351{
352let item;
353self.each(function(el) {
354while (el = el.previous()) {
355if (!selector || el.IsSelector(selector)) {
356item = el;
357return false;
358}
359}
360});
361return item;
362};
363this.append = function(html, clone) { // appends html string to the end of the element
364if (typeof html == 'object') {
365let ret = [];
366self.each(function(el) {
367let el_dom = el.dom(0);
368if (clone) {
369html.each(function(new_el) {
370let new_dom = new_el.dom(0);
371var node = new_dom.cloneNode(true);
372var nodes = node.querySelectorAll('*');
373for (var n in nodes) {
374if (!nodes[n].attributes) continue;
375for (a in nodes[n].attributes) {
376if (!nodes[n].attributes[a].name) continue;
377if (nodes[n].attributes[a].name.substr(0, 8) == 'data-e__') {
378nodes[n].attributes.removeNamedItem(nodes[n].attributes[a].name);
379}
380}
381}
382let appended = el_dom.appendChild(node);
383ret.push(appended);
384});
385} else {
386html.each(function(new_el) {
387let appended = el_dom.appendChild(new_el.dom(0));
388ret.push(appended);
389});
390}
391});
392return new GraceWeb(ret);
393} else {
394this.dom(0).innerHTML = this.dom(0).innerHTML + html;
395}
396};
397this.prepend = function(html, clone) { // prepends html string to the end of the element
398if (typeof html == 'object') {
399for (var i in self.dom()) {
400if (typeof self.dom(i) != 'object') continue;
401if (clone) {
402for (var j = 0; j < html.Count(); j++) {
403var node = html.dom(j).cloneNode(true);
404var nodes = node.querySelectorAll('*');
405for (var n in nodes) {
406if (!nodes[n].attributes) continue;
407for (a in nodes[n].attributes) {
408if (!nodes[n].attributes[a].name) continue;
409if (nodes[n].attributes[a].name.substr(0, 8) == 'data-e__') {
410nodes[n].attributes.removeNamedItem(nodes[n].attributes[a].name);
411}
412}
413}
414self.dom(i).insertBefore(node, self.dom(i).childNodes[0]);
415}
416} else {
417for (var j = 0; j < html.Count(); j++) {
418self.dom(i).insertBefore(html.dom(j), self.dom(i).childNodes[0]);
419}
420}
421}
422} else {
423this.dom(0).innerHTML = html + this.dom(0).innerHTML;
424}
425};
426this.AddHTMLafter = function(html) {
427var new_element = document.createElement('table');
428new_element.innerHTML = html;
429for (var i in self.dom()) {
430if (typeof self.dom(i) != 'object') continue;
431self.dom(i).parentNode.insertBefore(new_element.firstChild, self.dom(i).nextSibling);
432}
433};
434this.AddAfter = function(new_element) {
435let n = [];
436self.each(function(el) {
437new_element.each(function(inserting) {
438let res = el.dom(0).parentNode.insertBefore(inserting.dom(0), el.dom(0).nextSibling);
439n.push(res);
440el = new GraceWeb(res);
441});
442});
443return new GraceWeb(n);
444};
445this.AddBefore = function(new_element) {
446let n = [];
447self.each(function(el) {
448if (el.DirectParent()) {
449let res = el.DirectParent().dom(0).insertBefore(new_element.dom(0) ? new_element.dom(0) : new_element.dom(), el.dom(0));
450n.push(res);
451}
452});
453return new GraceWeb(n);
454};
455this.GetText = function() {
456let text = [];
457self.each(function(el) {
458text.push(el.dom(0).textContent);
459});
460return text.join(' ');
461};
462this.GetHTML = function() {
463if (!self.Count()) return '';
464let html = '';
465self.each(function(el) {
466html += el.dom(0).innerHTML;
467});
468return html;
469};
470this.GetOuterHTML = function() {
471if (!self.Count()) return '';
472let html = '';
473self.each(function(el) {
474html += el.dom(0).outerHTML;
475});
476return html;
477};
478this.SetHTML = function(html) {
479this.each(function(el) {
480if (html && typeof html == 'object') {
481el.dom(0).innerHTML = '';
482html.each(function(h) {
483el.dom(0).appendChild(h.dom(0));
484});
485} else {
486el.dom(0).innerHTML = html;
487}
488});
489};
490this.replace = function(grace_object) {
491var new_node = grace_object.dom(0);
492for (var i in self.dom()) {
493if (typeof self.dom(i) != 'object') continue;
494var actual_node = self.dom(i);
495actual_node.parentNode.insertBefore(new_node, actual_node);
496actual_node.parentNode.removeChild(actual_node);
497dom = [new_node];
498for (var i in actual_node.dataset) {
499var e = i.split('__');
500if (e.length != 3) continue;
501if (e[0] != 'e') continue;
502self.e.on(e[1], i);
503}
504}
505};
506this.clone = function(remove_events) {
507var dom = [];
508self.each(function(el) {
509dom.push(el.dom(0).cloneNode(true));
510});
511let g = new GraceWeb(dom);
512g.data.remove('uid');
513g.children('[data-uid]').data.remove('uid');
514if (remove_events) {
515g.e.CancelAll();
516g.children('*').e.CancelAll();
517}
518return g;
519};
520this.GetWidth = function() {
521if (!self.Count()) return 0;
522return self.dom(0).clientWidth;
523};
524this.GetHeight = function() {
525if (!self.Count()) return 0;
526return self.dom(0).clientHeight;
527};
528this.SetWidth = function(width) {
529self.css.set('width', width);
530};
531this.GetWindowWidth = function() {
532return window.innerWidth;
533};
534this.GetWindowHeight = function() {
535return window.innerHeight;
536};
537this.offset = function(selector) {
538var top = 0;
539var left = 0;
540var parent = self.dom(0);
541while (parent) {
542if (selector) {
543let p = new GraceWeb(parent);
544if (p.IsSelector(selector)) break;
545}
546if (parent.offsetTop) top += parent.offsetTop;
547if (parent.offsetLeft) left += parent.offsetLeft;
548if (parent.tagName == 'BODY') break;
549parent = parent.offsetParent;
550}
551return {left: left, top: top};
552};
553this.scroll = {
554get: function() {
555let d = self;
556if (d.GetTagName() == 'html') d = d.children('body');
557if (d.GetTagName() == 'body') {
558d = d.dom(0);
559var s = d.scrollTop;
560if (!s) {
561s = document.documentElement.scrollTop;
562}
563return s;
564} else {
565d = d.dom(0);
566return d.scrollTop;
567}
568},
569set: function(scroll) {
570self.each(function(d) {
571if (d.GetTagName() == 'html') d = d.children('body');
572if (d.GetTagName() == 'body') {
573d = d.dom(0);
574document.documentElement.scrollTop = scroll;
575d.scrollTop = scroll;
576} else {
577d = d.dom(0);
578d.scrollTop = scroll;
579}
580});
581},
582GetHorizontal: function() {
583let d = self;
584if (d.GetTagName() == 'html') d = d.children('body');
585if (d.GetTagName() == 'body') {
586d = d.dom(0);
587let s = d.scrollLeft;
588if (!s) {
589s = document.documentElement.scrollLeft;
590}
591return s;
592} else {
593d = d.dom(0);
594return d.scrollLeft;
595}
596},
597SetHorizontal: function(scroll) {
598self.each(function(d) {
599if (d.GetTagName() == 'html') d = d.children('body');
600if (d.GetTagName() == 'body') {
601d = d.dom(0);
602document.documentElement.scrollLeft = scroll;
603d.scrollLeft = scroll;
604} else {
605d = d.dom(0);
606d.scrollLeft = scroll;
607}
608});
609}
610};
611this.Display = function() {
612if (self.class.has('Hidden')) self.class.remove('Hidden');
613};
614this.Hide = function() {
615self.class.add('Hidden');
616};
617this.css = {
618set: function(name, value) {
619self.each(function(el) {
620el.dom(0).style[name] = value;
621});
622},
623setMultiple: function(object) {
624for (let name in object) {
625self.css.set(name, object[name]);
626}
627},
628get: function(name) {
629if (!self.Count()) return null;
630return self.dom(0).style[name];
631},
632remove: function(name) {
633for (var i in self.dom()) {
634if (typeof self.dom(i) != 'object') continue;
635if (self.dom(i).style != undefined && self.dom(i).style[name] != undefined) {
636self.dom(i).style[name] = null;
637}
638}
639},
640getList: function() {
641return self.dom(0).style;
642}
643};
644this.InternalId = function(i)
645{
646if (i == undefined) i = 0;
647if (self.dom(i).dataset == undefined) {
648self.dom(i).dataset = {};
649}
650if (self.dom(i).dataset.uid == undefined) {
651self.dom(i).dataset['uid'] = SHA1(Random(1, 10000000000000).toString());
652}
653return self.dom(i).dataset['uid'];
654};
655this.e = { // list of events
656click: function(fnc) {
657if (fnc) {
658self.e.on('click', fnc);
659} else {
660self.e.trigger('click');
661}
662},
663focus: function(fnc) {
664if (fnc) {
665self.e.on('focus', fnc);
666} else {
667for (var i = 0; i < self.Count(); i++) {
668self.dom(i).focus();
669}
670self.e.trigger('focus');
671}
672},
673scroll: function(fnc) {
674if (fnc) {
675self.e.on('scroll', fnc);
676} else {
677self.e.trigger('scroll');
678}
679},
680PageScroll: function(fnc) {
681let event = 'scroll';
682if (fnc) {
683window.addEventListener(event, fnc);
684}
685},
686mousewheel: function(fnc) {
687let event = (GetBrowserName() == 'Firefox') ? 'DOMMouseScroll' : 'mousewheel';
688if (fnc) {
689self.e.on(event, fnc);
690} else {
691self.e.trigger(event);
692}
693},
694MouseWheelUp: function(fnc) {
695let event = (GetBrowserName() == 'Firefox') ? 'DOMMouseScroll' : 'mousewheel';
696if (fnc) {
697self.e.on(event, function(el, e) {
698if (e.wheelDelta > 0) {
699return fnc(el, e);
700}
701});
702}
703},
704MouseWheelDown: function(fnc) {
705let event = (GetBrowserName() == 'Firefox') ? 'DOMMouseScroll' : 'mousewheel';
706if (fnc) {
707self.e.on(event, function(el, e) {
708if (e.wheelDelta < 0) {
709return fnc(el, e);
710}
711});
712}
713},
714LostFocus: function(fnc) {
715GraceW.children('body').e.on(['focusin', 'click'], function(el, e) {
716let focused = new GraceWeb(e.target);
717g.children('[data-focus="on"]').data.remove('focus');
718focused.data.set('focus', 'on');
719});
720self.e.on('focusout', function(el, e) {
721let new_el = new GraceWeb(e.relatedTarget ? e.relatedTarget : document.activeElement);
722g.children('[data-focus="on"]').data.remove('focus');
723new_el.data.set('focus', 'on');
724if (el.data.get('focus') == 'on' || el.children('[data-focus="on"]').Count()) return true;
725el.e.trigger('lost-focus');
726return fnc(el, e);
727});
728},
729csstransitionend: function(fnc) {
730self.e.on(['transitionend', 'webkitTransitionEnd', 'oTransitionEnd', 'otransitionend', 'MSTransitionEnd', 'transitioncancel'], fnc);
731},
732on: function(events, fnc) {
733if (typeof events == 'string') events = [events];
734for (var i in self.dom()) {
735if (typeof self.dom(i) != 'object') continue;
736for (var e in events) {
737var event = events[e].replace(/\-/g, '');
738if (event == 'domloaded') {
739self.e.domloaded(fnc);
740continue;
741}
742let str_fnc = self.e.HashFunction(fnc);
743let el = self.dom(i);
744if (!el.GEvents) el.GEvents = {};
745let found = el.GEvents[event] ? true : false;
746if (!el.GEvents[event]) el.GEvents[event] = {};
747el.GEvents[event][str_fnc] = fnc;
748if (found) continue;
749self.dom(i).removeEventListener(event, OnEventListener);
750self.dom(i).addEventListener(event, OnEventListener, false);
751}
752}
753},
754trigger: function(event) {
755return self.e.triggers.trigger(event);
756},
757cancel: function(event, fnc)
758{
759event = event.replace(/\-/g, '');
760if (fnc) fnc = self.e.HashFunction(fnc);
761self.each(function(el) {
762el = el.dom(0);
763if (el.GEvents && el.GEvents[event]) {
764if (fnc) {
765delete el.GEvents[event][fnc];
766} else {
767delete el.GEvents[event];
768}
769}
770if (!el.GEvents || !el.GEvents[event] || !Object.keys(el.GEvents[event]).length) {
771el.removeEventListener(event, OnEventListener); // TODO: not working - listener is not removed, no error message
772}
773});
774},
775HashFunction: function(fnc)
776{
777return SHA1(fnc.toString());
778},
779CancelAll: function()
780{
781self.each(function(el) {
782el = el.dom(0);
783let events = el.GEvents ? el.GEvents : [];
784for (let i in events) {
785el.removeEventListener(events[i], OnEventListener); // TODO: not working - listener is not removed, no error message
786}
787delete el.GEvents;
788});
789},
790domloaded: function(fnc) {
791document.addEventListener('DOMContentLoaded', function(e) {
792fnc(e);
793});
794},
795domadded: function(fnc) {
796(new GraceWeb()).dom(0).addEventListener('domadded', function(e) {
797fnc(e.custom_data.el, e);
798});
799},
800windowresize: function(fnc) {
801window.addEventListener('resize', function(e) {
802fnc(e);
803});
804},
805triggers: {
806trigger: function(event, custom_data) {
807if (event == 'domloaded') {
808let e = new Event('DOMContentLoaded');
809document.dispatchEvent(e);
810return true;
811} else if (event == 'windowresize') {
812let e = new Event('resize');
813window.dispatchEvent(e);
814return true;
815}
816let e = new Event(event.replace(/\-/g, ''), {
817cancelable: true
818});
819if (custom_data) {
820e.custom_data = custom_data;
821}
822let is_false = false;
823for (var i = 0; i < self.Count(); i++) {
824let res = self.dom(i).dispatchEvent(e);
825if (res === false) is_false = true;
826}
827return !is_false;
828},
829domadded: function() {
830(new GraceWeb()).e.triggers.trigger('domadded', {el: self});
831}
832}
833};
834function OnEventListener(e)
835{
836var event = e.type.replace(/\-/g, '');
837e.stopPropagation();
838var original_element = (e.srcElement ? e.srcElement : e.target);
839let oo = original_element;
840var act_el = original_element;
841var stopped = false;
842var return_values = [];
843while (act_el && typeof act_el == 'object') {
844if (stopped) break;
845if (!act_el.GEvents || !act_el.GEvents[event]) {
846if (act_el.tagName == 'BODY') break;
847act_el = act_el.parentNode;
848continue;
849}
850var test_element = new GraceWeb(act_el);
851for (let f in act_el.GEvents[event]) {
852if (stopped) break;
853original_element = act_el;
854if (!act_el.GEvents[event]) break;
855if (!act_el.GEvents[event][f]) continue;
856let res = act_el.GEvents[event][f](test_element, e);
857if (res === false) {
858e.preventDefault();
859return_values = false;
860}
861if (return_values !== false) {
862return_values.push(res);
863}
864if (e.stopped) {
865stopped = true;
866break;
867}
868}
869if (act_el.tagName == 'BODY') break;
870act_el = act_el.parentNode;
871}
872e.returnValue = return_values;
873return return_values;
874}
875this.data = {
876set: function(name, value) {
877self.attr.set('data-' + name, value);
878},
879get: function(name) {
880return self.attr.get('data-' + name);
881},
882has: function(name) {
883return self.attr.has('data-' + name);
884},
885remove: function(name) {
886self.attr.remove('data-' + name);
887},
888GetAll: function() {
889let list = {};
890let attrs = self.attr.getList();
891for (let i in attrs) {
892if (i.substr(0, 5) == 'data-') list[i.substr(5)] = attrs[i];
893}
894return list;
895}
896};
897this.attr = {
898set: function(name, value, namespace) {
899self.each(function(el) {
900let eldom = el.dom(0);
901switch (name) {
902case 'checked':
903eldom.checked = value;
904break;
905case 'value':
906eldom.value = value;
907break;
908default:
909eldom.setAttributeNS(namespace, name, value);
910break;
911}
912});
913},
914get: function(name) {
915if (self.dom().length < 1) return null;
916switch (name) {
917case 'checked':
918return self.dom(0).checked;
919case 'value':
920return self.dom(0).value;
921default:
922return self.dom(0).getAttribute(name);
923}
924},
925has: function(name) {
926for (let i in self.dom(0).attributes) {
927let attr = self.dom(0).attributes[i];
928if (!/[0-9]+/i.test(i)) continue;
929if (name == attr.name) return true;
930}
931return false;
932},
933remove: function(name) {
934for (var i in self.dom()) {
935if (typeof self.dom(i) != 'object') continue;
936self.dom(i).removeAttribute(name);
937}
938},
939getAll: function(name, key_by, include_empty) {
940var attrs = key_by ? {} : [];
941for (var i = 0; i < self.Count(); i++) {
942var attr = self.Select(i).attr.get(name);
943if (!attr && !include_empty) continue;
944if (key_by) {
945attrs[self.Select(i).attr.get(key_by)] = attr;
946} else {
947attrs.push(attr);
948}
949}
950return attrs;
951},
952getList: function() {
953let list = [];
954for (let i in self.dom(0).attributes) {
955let attr = self.dom(0).attributes[i];
956if (!/[0-9]+/i.test(i)) continue;
957list[attr.name] = attr.value;
958}
959return list;
960}
961};
962this.class = {
963add: function(name) {
964for (var i in self.dom()) {
965if (typeof self.dom(i) != 'object') continue;
966if (typeof name != 'object') name = [name];
967for (var j in name) {
968self.dom(i).classList.add(name[j]);
969}
970}
971},
972remove: function(name) {
973for (var i in self.dom()) {
974if (typeof self.dom(i) != 'object') continue;
975if (typeof name != 'object') name = [name];
976for (var j in name) {
977self.dom(i).classList.remove(name[j]);
978}
979}
980},
981has: function(name) {
982for (var i in self.dom()) {
983if (typeof self.dom(i) != 'object') continue;
984var list = self.class.getList();
985for (var j in list) {
986if (list[j] == name) return true;
987}
988}
989return false;
990},
991getList: function() {
992var list = {};
993for (var i in self.dom()) {
994if (typeof self.dom(i) != 'object') continue;
995for (var j = 0; j <= self.dom(i).classList.length; j++) {
996if (!self.dom(i).classList.item(j)) continue;
997list[self.dom(i).classList.item(j)] = 1;
998}
999}
1000var arr = [];
1001for (i in list) {
1002if (i == null || i == undefined || i == '') continue;
1003arr.push(i);
1004}
1005return arr;
1006},
1007Toggle: function(name) {
1008if (self.class.has(name)) {
1009self.class.remove(name);
1010return false;
1011} else {
1012self.class.add(name);
1013return true;
1014}
1015}
1016};
1017this.NewElementFromHTML = function(html, get_full_page) {
1018let dom_code = new DOMParser().parseFromString(html, 'text/html');
1019dom_code = dom_code.documentElement;
1020let grace = new GraceWeb([]);
1021if (!get_full_page) {
1022grace.AddElements(new GraceWeb(dom_code.querySelector('head').childNodes));
1023grace.AddElements(new GraceWeb(dom_code.querySelector('body').childNodes));
1024} else {
1025grace = new GraceWeb(dom_code);
1026}
1027return grace;
1028};
1029this.f = function(name, force_new_object) {
1030if (self.Count() > 0) {
1031var hash = self.InternalId(0) + '-' + name;
1032if (GraceObjects[hash] != undefined && !force_new_object) {
1033return GraceObjects[hash];
1034}
1035if (self[name]) {
1036var obj = new self[name](self);
1037} else {
1038var obj = eval('new ' + name + '(self);');
1039}
1040GraceObjects[hash] = obj;
1041} else {
1042if (self[name]) {
1043var obj = new self[name](self);
1044} else {
1045var obj = eval('new ' + name + '(self);');
1046}
1047}
1048return obj;
1049};
1050this.each = function(fnc, types = [1])
1051{
1052for (let i = 0; i < self.Count(); i++) {
1053let d = self.dom(i);
1054if (types && types.indexOf(d.nodeType) < 0) continue;
1055let ret = fnc(self.Select(i));
1056if (ret === false) break;
1057}
1058};
1059}
1060var g = new GraceWeb();
1061var GraceW = g;
1062if (ActualUrl == undefined)
1063{
1064var ActualUrl = location.pathname + location.search;
1065var History = [ActualUrl];
1066}
1067function NumberToDisplayFormat(number)
1068{
1069var price = number.toString().split('').reverse();
1070var i = 0;
1071var new_price = [];
1072for (j in price)
1073{
1074if (price[j] == '.' || price[j] == ',') i = -1;
1075if (i % 3 == 0 && i > 0) new_price.push(' ');
1076new_price.push(price[j]);
1077i++;
1078}
1079return new_price.reverse().join('').trim();
1080}
1081async function DisplayImages(elements)
1082{
1083let is_safari = GetBrowserName() == 'Safari';
1084elements.each(function(el) {
1085let mobile = GetWindowWidth() < 1024 && el.data.get('mobile-image');
1086let srcs = mobile ? el.data.get('mobile-image') : el.data.get('image');
1087if (srcs == undefined || srcs == null) return;
1088srcs = srcs.split('|');
1089for (let i in srcs) {
1090let src = srcs[i].trim();
1091if (is_safari && /\.webp$/.test(src)) continue;
1092if (el.data.get('image-type') == 'bg') {
1093el.css.set('background-image', 'url(\'' + src + '\')');
1094el.attr.remove(mobile ? 'data-mobile-image' : 'data-image');
1095} else {
1096let img = g.NewElementFromHTML('<img src="' + src + '" />');
1097el.attr.remove(mobile ? 'data-mobile-image' : 'data-image');
1098if (el.data.get('title')) {
1099img.attr.set('alt', el.data.get('title'));
1100img.attr.set('title', el.data.get('title'));
1101}
1102if (el.data.get('image-width')) {
1103img.attr.set('width', el.data.get('image-width'));
1104}
1105if (el.data.get('image-height')) {
1106img.attr.set('height', el.data.get('image-height'));
1107}
1108el.append(img);
1109}
1110break;
1111}
1112el.e.trigger('image-displayed');
1113});
1114}
1115function ContextMenu(items, e, name)
1116{
1117return;
1118if ($('.ContextMenu').length > 0) RemoveContext($('.ContextMenu'));
1119var context = $('<div class="ContextMenu"></div>');
1120if (name) context.append('<div class="Name">' + name + '</div>');
1121for (cl in items)
1122{
1123context.append('<div class="Item ' + cl + '">' + items[cl] + '</div>');
1124}
1125if (e != undefined)
1126{
1127context.css({top: (e.clientY + GraceW.children('body').scroll.get()) + 'px', left: e.clientX + 'px'});
1128}
1129context.css('position', 'absolute');
1130$('body').append(context);
1131$('#Main, .Dialog').Click(function(){
1132RemoveContext($('.ContextMenu'));
1133});
1134return context;
1135}
1136function RemoveContext(context)
1137{
1138if (context == undefined)
1139{
1140$('.ContextMenu').remove();
1141}
1142else
1143{
1144context.remove();
1145}
1146}
1147function Explode(cchar, str)
1148{
1149var new_arr = new Array();
1150if(str != undefined)
1151{
1152var key = 0;
1153for (i = 0; i < str.length; i++)
1154{
1155s = str.substr(i, cchar.length);
1156if (s == cchar)
1157{
1158key++;
1159}
1160else
1161{
1162if (new_arr[key] == undefined) new_arr[key] = '';
1163new_arr[key] += s.substr(0, 1);
1164}
1165}
1166}
1167return new_arr;
1168}
1169function InArray(value, arr)
1170{
1171for(i in arr)
1172{
1173if (arr[i] == value) return true;
1174}
1175return false;
1176}
1177function RemoveFromArray(arr_remove, arr)
1178{
1179for(i in arr_remove)
1180{
1181if(!InArray(arr_remove[i], arr))
1182{
1183for(j in arr)
1184{
1185if(arr[j] == arr_remove[i]) arr[j] = undefined;
1186}
1187}
1188}
1189var new_arr = new Array();
1190var j = 0;
1191for(i in arr)
1192{
1193if(arr[i] != undefined) new_arr[j++] = arr[i];
1194}
1195return new_arr;
1196}
1197var JavaScripts = {};
1198function IncludeJs(file, forced, fn)
1199{
1200if (forced == undefined) forced = false;
1201if (JavaScripts[file] == undefined || forced)
1202{
1203JavaScripts[file] = false;
1204let script = document.createElement('script');
1205script.type = 'text/javascript';
1206script.src = coreroot + file;
1207g.children('head').append(new GraceWeb(script));
1208}
1209if (JavaScripts[file])
1210{
1211if (fn != undefined) fn();
1212}
1213else
1214{
1215var check = setInterval(function(){
1216if (JavaScripts[file])
1217{
1218clearInterval(check);
1219if (fn != undefined) fn();
1220}
1221}, 50);
1222}
1223}
1224function InArray(value, array)
1225{
1226for (i in array)
1227{
1228if (array[i] == value) return true;
1229}
1230return false;
1231}
1232function GetKeyArray(value, array)
1233{
1234for (i in array)
1235{
1236if (array[i] == value) return i;
1237}
1238return false;
1239}
1240function CloneJson(obj)
1241{
1242if (null == obj || "object" != typeof obj) return obj;
1243var copy = obj.constructor();
1244for (var attr in obj) {
1245if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
1246}
1247return copy;
1248}
1249function OneNumberToTwoNumbers(number)
1250{
1251if (number < 10) return '0' + number.toString();
1252return number;
1253}
1254function GetWindowHeight()
1255{
1256if (window.innerHeight == undefined || window.innerHeight == null || !window.innerHeight) return $(window).height();
1257return window.innerHeight;
1258}
1259function GetWindowWidth()
1260{
1261if (window.innerWidth == undefined || window.innerWidth == null || !window.innerWidth) return $(window).width();
1262return window.innerWidth;
1263}
1264function GetInputsValuesByClass(cl)
1265{
1266var values = {};
1267$('.' + cl).each(function(){
1268if ($(this).attr('type') == 'checkbox')
1269{
1270var val = $(this).attr('checked') ? '1' : '0';
1271}
1272else
1273{
1274var val = $(this).val();
1275}
1276values[$(this).attr('name')] = val;
1277});
1278return values;
1279}
1280var Pages = {};
1281function DynamicUrlChange(url, name, params)
1282{
1283if (typeof window.history.pushState == 'function') {
1284if (!params) params = {};
1285window.history.pushState(params, '', url);
1286if (name != undefined) g.children('title').SetHTML(name);
1287ActualUrl = url;
1288} else {
1289location.assign(url);
1290}
1291}
1292function ObjectToString(obj)
1293{
1294var str = '';
1295for (i in obj) {
1296str += i + ': ' + obj[i] + "\n";
1297}
1298return str;
1299}
1300function IsExternal(link)
1301{
1302return (link.substr(0, 7) == 'http://' || link.substr(0, 8) == 'https://');
1303}
1304var BeforeSubmit = {};
1305function GetDataOfForm(form, simple)
1306{
1307let data = {};
1308form.children('[name]:not([aria-hidden])').each(function(el){
1309if ((el.attr.get('type') == 'checkbox' && !el.attr.get('checked')) || (el.attr.get('type') == 'radio' && !el.attr.get(':checked'))) return;
1310let name = el.attr.get('name');
1311let val = el.attr.get('value');
1312if (simple) {
1313data[name] = val;
1314return;
1315}
1316let last_name = name;
1317let n = name.split('[').reverse();
1318let v;
1319if (n.length > 1 && el.attr.get(':checked')) {
1320for (i in n) {
1321n[i] = n[i].replace(']', '');
1322if (n[i] == '') {
1323val = [val];
1324continue;
1325}
1326last_name = n[i];
1327v = {};
1328v[last_name] = val;
1329val = v;
1330}
1331data = JoinJSON(data, val);
1332} else if (n.length > 1) {
1333for (let i in n) {
1334//if (n[i] == '') continue;
1335if (n[i] == ']') {
1336v = [val];
1337v = val;
1338} else {
1339n[i] = n[i].replace(']', '');
1340if (n[i] == '') continue;
1341last_name = n[i];
1342v = {};
1343v[last_name] = val;
1344}
1345val = v;
1346}
1347data = JoinJSON(data, val);
1348} else {
1349if (typeof(val) == 'object') {
1350let new_val = {};
1351for (let i in val) {
1352new_val[i] = val[i];
1353}
1354val = new_val;
1355}
1356data[last_name.replace('[]', '')] = val;
1357}
1358});
1359return data;
1360}
1361function JoinJSON(original, add)
1362{
1363for (key in add)
1364{
1365if (original[key] == undefined)
1366{
1367original[key] = add[key];
1368}
1369else
1370{
1371if (typeof(add[key]) == 'object')
1372{
1373original[key] = JoinJSON(original[key], add[key]);
1374}
1375else
1376{
1377var new_json = [];
1378if (typeof(original[key]) == 'object')
1379{
1380var cnt = 0;
1381for (var i in original[key])
1382{
1383new_json.push(original[key][i]);
1384}
1385original[key] = new_json;
1386}
1387else
1388{
1389var cnt = 0;
1390for (var i in original) cnt++;
1391}
1392original[cnt] = add[key];
1393}
1394}
1395}
1396return original;
1397}
1398function IsDir(url)
1399{
1400return (url.substr(url.length - 1, 1) == '/');
1401}
1402function Count(arr)
1403{
1404var c = 0;
1405for (i in arr) c++;
1406return c;
1407}
1408function Init()
1409{
1410g.children('a.NewWindow').each(function(el){
1411if (el.parent('.GEditor')) return false;
1412el.e.click(function(el){
1413let href = el.attr.get('href');
1414if (href) {
1415window.open(href);
1416return false;
1417}
1418});
1419});
1420g.children('a[href^=http]').each(function(el) {
1421if (el.class.has('NoTracking') || el.parent('.GEditor') || /\.apps\./.test(location.href)) return;
1422let link = el.attr.get('href');
1423let working_link = link.replace(/http\:\/\/|https\:\/\//gi, '');
1424if (/\//.test(working_link)) {
1425working_link = working_link.split('/');
1426} else {
1427working_link = working_link.split('?');
1428}
1429working_link = working_link[0].toLowerCase();
1430let test_filesroot = filesroot.match(/http(s|)\:\/\/([^\/\?]+)/);
1431if (working_link != location.host && (!test_filesroot || working_link != test_filesroot[2])) {
1432let new_link = webroot + '?e=e&exit=' + encodeURIComponent(link.trim());
1433if (el.data.get('linkdesc')) new_link += '&exitnote=' + encodeURIComponent(el.data.get('linkdesc'));
1434el.attr.set('href', new_link);
1435el.data.set('link', link);
1436}
1437});
1438g.children('.Opener').each(function(el) {
1439let opener = el.f('Opener');
1440if (el.data.has('auto-close') == '1') opener.AutoClose = true;
1441});
1442g.children('.Calendar').each(function(el){
1443let init = el.data.get('init-calendar');
1444if (!init || init == 'auto') {
1445el.f('Calendar');
1446}
1447});
1448g.children('.TimeSelector').each(function(el){
1449el.f('TimeSelector');
1450});
1451InitGrace();
1452g.children('.geditor').each(function(editor) {
1453editor = editor.f('GEditor');
1454editor.Init();
1455});
1456g.children('.Carousel:not(section)').each(function(el) {
1457let carousel = el.f('Carousel');
1458if (el.attr.get('data-animation')) carousel.Animation = el.attr.get('data-animation');
1459carousel.Start();
1460});
1461g.children('.FileUpload').each(function(fu) {
1462fu.f('FileUpload');
1463});
1464g.Children('.ScrollBarOverlay').each(function(s) {
1465s.f('ScrollBar');
1466});
1467if (!debug && use_service_worker && 'serviceWorker' in navigator) {
1468navigator.serviceWorker.register(webroot + 'service-worker' + (/mobile/.test(navigator.userAgent) ? '-mobile' : '-desktop') + '.js');
1469}
1470}
1471function SeparateBrowsers()
1472{
1473let browser = GetBrowserName();
1474let body = g.children('body');
1475if (browser) {
1476body.class.add(browser);
1477body.class.add(browser + GetBrowserVersion());
1478} else {
1479body.class.add('NotDetected');
1480}
1481if (IsTouchable()) {
1482body.class.add('Touchable');
1483} else {
1484body.class.add('NotTouchable');
1485}
1486}
1487function ConvertToUrl(string)
1488{
1489string = string.toLowerCase();
1490var replace = {
1491'á': 'a',
1492'č': 'c',
1493'ď': 'd',
1494'ě': 'e',
1495'é': 'e',
1496'í': 'i',
1497'ň': 'n',
1498'ó': 'o',
1499'ř': 'r',
1500'Å¡': 's',
1501'Å¥': 't',
1502'ú': 'u',
1503'ů': 'u',
1504'ý': 'y',
1505'ž': 'z',
1506'ö': 'o',
1507'ü': 'u',
1508' ': '-',
1509"'": '',
1510'"': '',
1511',': '',
1512'.': '',
1513'`': '',
1514'б': 'b',
1515'в': 'v',
1516'г': 'g',
1517'д': 'd',
1518'ж': 'ž',
1519'з': 'z',
1520'и': 'i',
1521'й': 'j',
1522'к': 'k',
1523'л': 'l',
1524'е': 'e',
1525'м': 'm',
1526'н': 'n',
1527'о': 'o',
1528'п': 'p',
1529'р': 'r',
1530'с': 's',
1531'т': 't',
1532'у': 'u',
1533'ф': 'f',
1534'х': 'h',
1535'ц': 'c',
1536'ч': 'c',
1537'ш': 's',
1538'щ': 'sc',
1539'ъ': '',
1540'ь': '',
1541'ы': 'y',
1542'э': 'e',
1543'ю': 'ju',
1544'я': 'ja',
1545'а': 'a'
1546};
1547var allow_chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '-', '_', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
1548for (k in replace)
1549{
1550if ($.isFunction(replace[k]) || replace[k].substr(0, 8) == 'function') continue;
1551string = string.replace(k, replace[k]);
1552}
1553var len = string.length;
1554var replaced = false;
1555var new_url = '';
1556var split = string.split('');
1557for (i in split)
1558{
1559var char = split[i];
1560if ($.isFunction(char) || char.substr(0, 8) == 'function') continue;
1561var found = false;
1562for (a in allow_chars)
1563{
1564if (allow_chars[a] == char)
1565{
1566found = true;
1567break;
1568}
1569}
1570if (!found)
1571{
1572if (replaced)
1573{
1574char = '';
1575}
1576else
1577{
1578replaced = true;
1579char = (i && len - 1 > i) ? '_' : '';
1580}
1581}
1582else if (char == '-')
1583{
1584if (replaced || !i || len - 1 == i)
1585{
1586char = '';
1587}
1588else
1589{
1590replaced = true;
1591}
1592}
1593else
1594{
1595replaced = false;
1596}
1597new_url += char;
1598}
1599return new_url;
1600}
1601function GetTotalElHeight(el)
1602{
1603return el.height() + parseInt(el.css('padding-top')) + parseInt(el.css('padding-bottom'));
1604}
1605function GetTotalElWidth(el)
1606{
1607return el.width() + parseInt(el.css('padding-left')) + parseInt(el.css('padding-right')) + parseInt(el.css('border-left-width')) + parseInt(el.css('border-right-width'));
1608}
1609g.e.domloaded(function() {
1610Init();
1611SeparateBrowsers();
1612});
1613g.e.domadded(function() {
1614Init();
1615SeparateBrowsers();
1616});
1617setTimeout(function() {
1618let lazy_modules = g.Children('[data-lazy-load-modules-position]');
1619if (lazy_modules.Count()) {
1620lazy_modules.e.on('got-inside', function(el) {
1621el.e.CancelAll();
1622let a = el.f('Ajax');
1623a.Class = '\\Core\\Document\\Modules\\Ajax';
1624a.Method = 'LoadPosition';
1625a.Data = {position: el.data.get('lazy-load-modules-position')};
1626a.SuccessFnc = function(data) {
1627el.SetHTML(data.html);
1628el.e.triggers.domadded();
1629};
1630a.Send();
1631});
1632let lazy_modules_iw = lazy_modules.f('InViewport');
1633}
1634}, 200);
1635GoogleMapsPlaces = function()
1636{
1637}
1638GoogleMapsPlaces.prototype.Maps;
1639GoogleMapsPlaces.prototype.GPSFromAddress = function(address)
1640{
1641let promise = new Promise(function(resolve, reject) {
1642new google.maps.Geocoder().geocode({address: address}, function(result, status) {
1643if (result) {
1644resolve({lat: result[0].geometry.location.lat(), lon: result[0].geometry.location.lng()});
1645} else {
1646reject(status);
1647}
1648});
1649});
1650return promise;
1651}
1652GoogleMaps = function(g)
1653{
1654this.G = g;
1655};
1656GoogleMaps.prototype.G;
1657GoogleMaps.prototype.Key;
1658GoogleMaps.prototype.Map;
1659GoogleMaps.prototype.Load = function()
1660{
1661let self = this;
1662return new Promise(function(resolve, reject) {
1663if (self.IsInitiated()) {
1664resolve();
1665} else {
1666let script = document.createElement('script');
1667script.src = 'https://maps.googleapis.com/maps/api/js?key=' + self.Key;
1668script.defer = true;
1669let gs = new GraceWeb(script);
1670gs.e.on('load', function () {
1671resolve();
1672});
1673g.children('body').append(gs);
1674}
1675});
1676};
1677GoogleMaps.prototype.Init = function()
1678{
1679this.Map = new google.maps.Map(this.G.dom(0), {
1680center: { lat: -34.397, lng: 150.644 },
1681zoom: 8,
1682});
1683return this.Map;
1684}
1685GoogleMaps.prototype.LoadAndInit = function()
1686{
1687let self = this;
1688let loader = this.Load();
1689loader.then(function() {
1690self.Init();
1691});
1692return loader;
1693}
1694GoogleMaps.prototype.IsInitiated = function()
1695{
1696return !(typeof google === 'undefined' || typeof google.maps === 'undefined');
1697}
1698GoogleScopes = {
1699GMAIL_READONLY: 'https://www.googleapis.com/auth/gmail.readonly',
1700GMAIL_MODIFY: 'https://www.googleapis.com/auth/gmail.modify',
1701GMAIL_SEND: 'https://www.googleapis.com/auth/gmail.send',
1702USER_INFO: 'https://www.googleapis.com/auth/userinfo.profile',
1703USER_EMAIL: 'https://www.googleapis.com/auth/userinfo.email'
1704};
1705GraceWeb.prototype.Ajax = function(g) {
1706var self = this;
1707this.Async = true;
1708this.Class;
1709this.Method;
1710this.ModuleId = g ? (g.parent('[data-module]') ? g.parent('[data-module]').data.get('id') : (g.data.get('module') ? g.data.get('id') : null)) : null;
1711this.Data = {};
1712this.SuccessFnc;
1713this.ErrorFnc;
1714this.ProgressFnc;
1715this.Link = location.href + (location.search ? '&' : '?') + 'ajax=ajax';
1716this.ReturnsJson = true;
1717this.Type = 'POST';
1718this.SendAjaxInfo = true;
1719this.LastXHR;
1720let GlobalXHR;
1721let SendingChunks = null;
1722this.SeparateFileToChunks = function(file)
1723{
1724let chunks = [];
1725let bytes_per_chunk = maxfilesize / 2;
1726if (bytes_per_chunk > 100000000) bytes_per_chunk = 100000000;
1727let size = file.size;
1728let start = 0;
1729let end = bytes_per_chunk;
1730while (start < size) {
1731chunks.push(file.slice(start, end));
1732start = end;
1733end = start + bytes_per_chunk;
1734}
1735return chunks;
1736}
1737this.SendAsFilesChunks = function() {
1738let send_waves = [];
1739for (let name in this.Data) {
1740if (!this.Data[name].name) continue;
1741let chunks = this.SeparateFileToChunks(this.Data[name]);
1742for (let c in chunks) {
1743let item = {};
1744item.chunk = chunks[c];
1745item.meta = JSON.stringify({name: this.Data[name].name, type: this.Data[name].type, size: this.Data[name].size});
1746item.part = [];
1747if (c == 0) {
1748item.part.push('start');
1749} else {
1750item.part.push('part');
1751}
1752item.part = item.part.join('|');
1753send_waves.push(item);
1754}
1755let item = {
1756meta: JSON.stringify({name: this.Data[name].name, type: this.Data[name].type, size: this.Data[name].size}),
1757part: 'end'
1758};
1759send_waves.push(item);
1760}
1761let self = this;
1762new Promise(function (resolve, reject) {
1763self.SendChunk(send_waves, resolve, 0, {});
1764}).then(function (success_data) {
1765self.SuccessFnc(success_data);
1766});
1767};
1768this.SendChunk = function(send_waves, resolve, finished_size, success_data) {
1769let original_send_waves = Object.assign([], send_waves);
1770let original_finished_size = finished_size;
1771let original_success_data = success_data;
1772let self = this;
1773let chunk_ajax = new GraceWeb.prototype.Ajax();
1774chunk_ajax.ModuleId = self.ModuleId;
1775chunk_ajax.Class = self.Class;
1776chunk_ajax.Method = 'UploadChunk';
1777chunk_ajax.Link = self.Link;
1778chunk_ajax.Data = null;
1779for (let i in send_waves) {
1780chunk_ajax.Data = send_waves[i];
1781delete send_waves[i];
1782break;
1783}
1784if (!chunk_ajax.Data) {
1785resolve(success_data);
1786return;
1787}
1788let meta = JSON.parse(chunk_ajax.Data.meta);
1789chunk_ajax.SuccessFnc = function(done_data) {
1790for (let i in done_data) {
1791success_data[i] = done_data[i];
1792}
1793self.SendChunk(send_waves, resolve, finished_size + (chunk_ajax.Data.chunk ? chunk_ajax.Data.chunk.size : 0), success_data);
1794};
1795chunk_ajax.ErrorFnc = function() {
1796setTimeout(function() {
1797self.SendChunk(original_send_waves, resolve, original_finished_size, original_success_data);
1798}, 1000);
1799};
1800chunk_ajax.ProgressFnc = function(e) {
1801if (self.ProgressFnc) {
1802let new_e = new Event('progress');
1803new_e.total = meta.size;
1804new_e.loaded = finished_size + e.loaded;
1805self.ProgressFnc(new_e);
1806}
1807};
1808chunk_ajax.Send();
1809};
1810this.Send = function() {
1811var xhr = new XMLHttpRequest();
1812this.LastXHR = xhr;
1813xhr.onreadystatechange = function() {
1814if (this.readyState == 4) {
1815let data = xhr.responseText;
1816if (!data && self.ReturnsJson) data = '{}';
1817if (self.ReturnsJson) {
1818try {
1819data = JSON.parse(data);
1820} catch (e) {
1821if (self.ErrorFnc) self.ErrorFnc(xhr.responseText);
1822GlobalXHR = null;
1823return;
1824}
1825if (debug && data.__t) {
1826let d = document.createElement('div');
1827d.style.background = 'white';
1828d.style.position = 'absolute';
1829d.style.left = '10px';
1830d.style.right = '10px';
1831d.style.top = '10px';
1832d.style.bottom = '10px';
1833d.style.zIndex = '1000000';
1834let js = document.createElement('script');
1835let html = '';
1836let parts = data.__t.split(/\<script[^\>]*\>/igm);
1837html += parts[0];
1838parts = parts[1].split(/\<\/script\>/igm);
1839html += parts[1];
1840js.textContent = parts[0].replace('//<![CDATA[', '').replace('//]]>', '').trim();
1841d.innerHTML = html;
1842document.body.appendChild(d);
1843document.body.appendChild(js);
1844document.addEventListener('keyup', e => {
1845if (e.key == 'Escape') {
1846d.remove();
1847}
1848});
1849delete data.__t;
1850//eval(js.textContent);
1851}
1852}
1853if (data['grace-messages'] != undefined) {
1854if (document.Grace == undefined) document.Grace = {};
1855document.Grace.Messages = data['grace-messages'];
1856}
1857var loc = xhr.getResponseHeader('JsLocation');
1858if (loc) {
1859location.assign(loc);
1860return;
1861}
1862loc = xhr.getResponseHeader('ReplaceUrl');
1863if (loc) {
1864history.replaceState({}, '', loc);
1865}
1866InitGrace();
1867if (this.status == 200) {
1868if (self.SuccessFnc) self.SuccessFnc(data);
1869} else {
1870if (self.ErrorFnc) self.ErrorFnc(xhr.responseText);
1871}
1872GlobalXHR = null;
1873}
1874};
1875xhr.upload.addEventListener("progress", function(e){
1876//var total = (e.total != undefined) ? e.total : e.totalSize;
1877if (self.ProgressFnc) {
1878self.ProgressFnc(e);
1879}
1880});
1881xhr.open(self.Type, self.Link, self.Async);
1882if (self.SendAjaxInfo) xhr.setRequestHeader('Ajax', 'AJAX');
1883if (self.Class) xhr.setRequestHeader('Phpclass', self.Class);
1884if (self.Method) xhr.setRequestHeader('Phpmethod', self.Method);
1885if (!self.Class && self.ModuleId) xhr.setRequestHeader('Phpmoduleid', self.ModuleId);
1886if (!self.Class && !self.ModuleId && this.DefaultClass) xhr.setRequestHeader('Phpclass', this.DefaultClass);
1887xhr.setRequestHeader('Browserwidth', document.documentElement.clientWidth);
1888xhr.setRequestHeader('Browserheight', document.documentElement.clientHeight);
1889//if (this.Type == 'POST') xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
1890var data = new FormData();
1891for (var i in self.Data) {
1892if (self.Data[i] == null) continue;
1893data.append(i, self.Data[i]);
1894}
1895xhr.send(data);
1896GlobalXHR = xhr;
1897};
1898this.GetResponseHeader = function(name)
1899{
1900if (!this.LastXHR) return null;
1901let header = this.LastXHR.getResponseHeader(name);
1902return header;
1903};
1904this.Stop = function() {
1905if (GlobalXHR) GlobalXHR.abort();
1906};
1907this.Abort = function() {
1908this.Stop();
1909};
1910return this;
1911};
1912GraceWeb.prototype.Ajax.prototype.DefaultClass = null;
1913function GetBrowserName()
1914{
1915if (/OPR/.test(navigator.userAgent)) {
1916return 'Opera';
1917} else if (/Edg/.test(navigator.userAgent)) {
1918return 'Edge';
1919} else if (/Chrome/.test(navigator.userAgent)) {
1920return 'Chrome';
1921} else if (/Safari/.test(navigator.userAgent)) {
1922return 'Safari';
1923} else if (/MSIE/.test(navigator.userAgent)) {
1924return 'IE';
1925} else if (/Mozilla/.test(navigator.userAgent)) {
1926if (/like Gecko/.test(navigator.userAgent)) { // IE 11
1927return 'IE';
1928} else {
1929return 'Firefox';
1930}
1931}
1932return false;
1933}
1934function GetBrowserVersion()
1935{
1936let browser = GetBrowserName();
1937let ver;
1938switch (browser) {
1939case 'Edge':
1940ver = navigator.userAgent.split(' ');
1941for (i in ver) {
1942if (/Edge/.test(ver[i])) {
1943ver[i] = ver[i].trim().split('/');
1944return parseInt(ver[i][1]);
1945}
1946}
1947break;
1948case 'Chrome':
1949ver = navigator.userAgent.split(' ');
1950for (i in ver) {
1951if (/Chrome/.test(ver[i])) {
1952ver[i] = ver[i].trim().split('/');
1953return parseInt(ver[i][1]);
1954}
1955}
1956break;
1957case 'Safari':
1958ver = navigator.userAgent.split(' ');
1959for (i in ver) {
1960if (/Version/.test(ver[i])) {
1961ver[i] = ver[i].trim().split('/');
1962return parseInt(ver[i][1]);
1963}
1964}
1965break;
1966case 'IE':
1967ver = navigator.userAgent.split(';');
1968for (i in ver) {
1969if (/MSIE/.test(ver[i])) {
1970ver[i] = ver[i].trim().split(' ');
1971return parseInt(ver[i][1]);
1972}
1973}
1974ver = navigator.userAgent.split(' ');
1975for (i in ver) {
1976if (/rv\:/.test(ver[i])) {
1977ver[i] = ver[i].trim().split(':');
1978return parseInt(ver[i][1]);
1979}
1980}
1981break;
1982case 'Firefox':
1983ver = navigator.userAgent.split(' ');
1984for (i in ver) {
1985if (/Firefox/.test(ver[i])) {
1986ver[i] = ver[i].trim().split('/');
1987return parseInt(ver[i][1]);
1988}
1989}
1990break;
1991case 'Opera':
1992ver = navigator.userAgent.split(' ');
1993for (i in ver) {
1994if (/Opera/.test(ver[i])) {
1995ver[i] = ver[i].trim().split('/');
1996return parseInt(ver[i][1]);
1997}
1998}
1999break;
2000}
2001return false;
2002}
2003function IsTouchable()
2004{
2005let is_touchable = false;
2006if (navigator.msMaxTouchPoints != undefined && navigator.msMaxTouchPoints > 0) { // IE
2007is_touchable = true;
2008} else if (!!('ontouchstart' in window)) { // Chrome, Firefox
2009is_touchable = true;
2010}
2011return is_touchable;
2012}
2013GraceWeb.prototype.Calendar = function(g)
2014{
2015let self = this;
2016this.G = g;
2017if (!this.G.Count()) return false;
2018this.ScrollingEl = g;
2019this.CurrentDate = new Date();
2020this.MinDate = undefined;
2021this.MaxDate = undefined;
2022this.InactiveDays = []; // Date objects, e.g. [new Date(2014, 5, 15), new Date(2015, 8, 25)]
2023this.InactiveWeekDays = []; // integer of days in a week, e.g. [0, 1, 6] for Sunday, Monday and Saturday
2024this.AfterChoose = function(){};
2025this.BeforeChange = function(){};
2026this.AfterChange = function(){};
2027this.UpdatedView = function(){};
2028this.AddMonthToFirstAndLast = true;
2029this.ScrollPx = 25;
2030let touchChanged = false;
2031let touchStartM;
2032let touchY;
2033this.DayNameItem = g.children('[data-lookup="DayNameItem"]').Select(0);
2034if (this.DayNameItem) this.DayNameItem = this.DayNameItem.clone();
2035this.DaysRow = g.children('[data-lookup="DaysRow"]').Select(0);
2036if (this.DaysRow) {
2037this.DaysRow = this.DaysRow.clone();
2038this.DaysRow.SetHTML('');
2039}
2040this.DayItem = g.children('[data-lookup="DayItem"]').Select(0);
2041if (this.DayItem) {
2042this.DayItem = this.DayItem.clone();
2043}
2044g.children('.DaysOfMonth tbody').SetHTML('');
2045this.Init = function()
2046{
2047self.WriteHTML();
2048this.SetGlobalEvents();
2049};
2050function SetMonthEvents()
2051{
2052g.children('.DaysTable .Day:not(.Inactive)').e.click(function(el){
2053self.CurrentDate = new Date(el.data.get('date'));
2054self.AfterChoose(new Date(el.data.get('date')), el);
2055return false;
2056});
2057}
2058this.SetGlobalEvents = function()
2059{
2060g.children('.Previous').e.click(function(el){
2061PreviousMonth();
2062return false;
2063});
2064g.children('.Next').e.click(function(el, e){
2065NextMonth();
2066e.stopPropagation();
2067e.preventDefault();
2068e.stopped = true;
2069return false;
2070});
2071g.children('.Next').e.on('dblclick', function(el, e) {
2072e.stopPropagation();
2073e.preventDefault();
2074e.stopped = true;
2075return false;
2076});
2077this.ScrollingEl.e.MouseWheelUp(function(el, e) {
2078if (!self.CanMoveUp()) return;
2079let m = g.children('.DaysOfMonth .DaysTable').css.get('margin-top') ? parseInt(g.children('.DaysOfMonth .DaysTable').css.get('margin-top')) : 0;
2080m += self.ScrollPx;
2081g.children('.DaysOfMonth .DaysTable').css.set('margin-top', m + 'px');
2082FillEmptySpace();
2083CheckAndSetMonth();
2084return false;
2085});
2086this.ScrollingEl.e.MouseWheelDown(function(el, e) {
2087if (!self.CanMoveDown()) return;
2088let m = g.children('.DaysOfMonth .DaysTable').css.get('margin-top') ? parseInt(g.children('.DaysOfMonth .DaysTable').css.get('margin-top')) : 0;
2089m -= self.ScrollPx;
2090g.children('.DaysOfMonth .DaysTable').css.set('margin-top', m + 'px');
2091FillEmptySpace();
2092CheckAndSetMonth();
2093return false;
2094});
2095this.ScrollingEl.e.on('touchstart', function(el, e) {
2096touchY = e.touches[0].screenY;
2097touchStartM = g.children('.DaysOfMonth .DaysTable').css.get('margin-top') ? parseInt(g.children('.DaysOfMonth .DaysTable').css.get('margin-top')) : 0;
2098GraceW.children('body').e.on('touchend', TouchEnd);
2099GraceW.children('body').e.on('touchmove', TouchMove);
2100return false;
2101});
2102}
2103this.CanMoveUp = function()
2104{
2105if (!self.MinDate) return true;
2106let first_date = new Date(g.children('[data-lookup="DayItem"]').Select(0).data.get('date'));
2107if (first_date.getTime() > self.MinDate.getTime()) return true;
2108let m = g.children('.DaysOfMonth .DaysTable').css.get('margin-top') ? parseInt(g.children('.DaysOfMonth .DaysTable').css.get('margin-top')) : 0;
2109if (m < 0) return true;
2110return false;
2111};
2112this.CanMoveDown = function()
2113{
2114if (!self.MaxDate) return true;
2115let last_date = new Date(g.children('[data-lookup="DayItem"]').SelectLast().data.get('date'));
2116if (last_date.getTime() < self.MaxDate.getTime()) return true;
2117let m = g.children('.DaysOfMonth .DaysTable').css.get('margin-top') ? parseInt(g.children('.DaysOfMonth .DaysTable').css.get('margin-top')) : 0;
2118if (m < 0) m *= -1;
2119if (g.children('.DaysOfMonth .DaysTable').GetHeight() - m > g.children('.DaysOfMonth').GetHeight()) return true;
2120return false;
2121};
2122function TouchMove(el, e)
2123{
2124if (!touchY) return;
2125if (e.touches[0].screenY != touchY) {
2126touchChanged = true;
2127}
2128let m = touchStartM + e.touches[0].screenY - touchY;
2129g.children('.DaysOfMonth .DaysTable').css.set('margin-top', m + 'px');
2130FillEmptySpace();
2131CheckAndSetMonth();
2132return false;
2133}
2134function TouchEnd(el, e)
2135{
2136if (touchY) {
2137if (!touchChanged) {
2138let target = new GraceWeb(e.target);
2139target.dom(0).click();
2140return;
2141}
2142touchChanged = false;
2143touchY = null;
2144GraceW.children('body').e.cancel('touchend',TouchEnd);
2145GraceW.children('body').e.cancel('touchmove', TouchMove);
2146return false;
2147}
2148}
2149function FillEmptySpace()
2150{
2151let height = g.children('.DaysOfMonth').GetHeight();
2152let i = 0;
2153while (true) {
2154if (i++ > 10) break;
2155let m = g.children('.DaysOfMonth .DaysTable').css.get('margin-top') ? parseInt(g.children('.DaysOfMonth .DaysTable').css.get('margin-top')) : 0;
2156if (m > 0) {
2157let date = new Date(g.children('.DaysOfMonth [data-lookup="DayItem"]').Select(0).data.get('date'));
2158date.setTime(date.getTime() - 24 * 3600 * 1000);
2159WriteWeek(date, false);
2160UpdatedView();
2161} else if (m < 0 && g.children('.DaysOfMonth .DaysTable').GetHeight() + m < height) {
2162let date = new Date(g.children('.DaysOfMonth [data-lookup="DayItem"]').SelectLast().data.get('date'));
2163date.setTime(date.getTime() + 24 * 3600 * 1000);
2164WriteWeek(date);
2165UpdatedView();
2166}
2167}
2168SetMonthEvents();
2169}
2170function UpdatedView()
2171{
2172self.UpdatedView();
2173self.G.e.trigger('updated-view');
2174}
2175function CheckAndSetMonth()
2176{
2177let m = g.children('.DaysOfMonth .DaysTable').css.get('margin-top') ? parseInt(g.children('.DaysOfMonth .DaysTable').css.get('margin-top')) : 0;
2178let height = g.children('.DaysOfMonth').GetHeight();
2179let rows = g.children('[data-lookup="DaysRow"]');
2180let date = new Date();
2181if (m < 0) m = m * -1;
2182rows.each(function(r) {
2183if (r.dom(0).offsetTop - m <= height / 2 && r.dom(0).offsetTop - m + r.GetHeight() >= height / 2) {
2184date = new Date(r.children('[data-lookup="DayItem"]').Select(4).data.get('date'));
2185return false;
2186}
2187});
2188g.children('.Header .Month').SetHTML(self.MonthsText[date.getMonth()]);
2189g.children('.Header .Year').SetHTML(date.getFullYear());
2190}
2191function PreviousMonth(cal)
2192{
2193var month = self.CurrentDate.getMonth();
2194var year = self.CurrentDate.getFullYear();
2195self.CurrentDate.setDate(1);
2196month--;
2197if (month < 0)
2198{
2199month = 11;
2200year--;
2201}
2202ChangeMonth(cal, month, year);
2203}
2204function NextMonth(cal)
2205{
2206var month = self.CurrentDate.getMonth();
2207var year = self.CurrentDate.getFullYear();
2208self.CurrentDate.setDate(1);
2209month++;
2210if (month > 11)
2211{
2212month = 0;
2213year++;
2214}
2215ChangeMonth(cal, month, year);
2216}
2217function ChangeMonth(cal, month, year)
2218{
2219self.BeforeChange(self.CurrentDate.getMonth(), self.CurrentDate.getFullYear());
2220self.CurrentDate.setMonth(month);
2221self.CurrentDate.setFullYear(year);
2222self.WriteActualMonth(cal);
2223self.AfterChange(month, year);
2224}
2225this.WriteHTML = function()
2226{
2227let table = g.children('.DaysTable');
2228let tr = table.children('thead tr');
2229tr.SetHTML('');
2230for (let i in self.DaysText) {
2231if (self.DayNameItem) {
2232let item = self.DayNameItem.clone();
2233tr.append(item);
2234}
2235if (tr.children('[data-lookup="DayName"]').Count()) {
2236tr.children('[data-lookup="DayName"]').SelectLast().SetHTML(self.DaysText[i]);
2237}
2238}
2239g.children('.DaysOfMonth .DaysTable tbody').SetHTML('');
2240self.WriteActualMonth();
2241};
2242function WriteWeek(any_date, add_after = true)
2243{
2244let tr = self.DaysRow.clone();
2245tr.SetHTML('');
2246let any_week_day = any_date.getDay();
2247if (!any_week_day) any_week_day = 7;
2248any_week_day--;
2249let first_date = new Date(any_date.getTime() - (any_week_day * 3600 * 24 * 1000));
2250let last_date = new Date(first_date.getTime() + (6 * 24 * 3600 * 1000));
2251let current_date = new Date(first_date.getTime());
2252let today = new Date();
2253while (current_date.getTime() <= last_date.getTime()) {
2254let month_days = GetDaysOfMonth(current_date.getMonth(), current_date.getFullYear());
2255let td = self.DayItem.clone();
2256let in_day = td.children('[data-lookup="Day"]').SelectLast();
2257let td_content = current_date.getDate();
2258if (current_date.getDate() == 1 || current_date.getDate() == month_days) {
2259td_content += ' ' + self.MonthsShortText[current_date.getMonth()];
2260}
2261in_day.SetHTML(td_content);
2262td.data.set('date', current_date);
2263if (today.getDate() == current_date.getDate() && today.getMonth() == current_date.getMonth() && today.getFullYear() == current_date.getFullYear()) td.class.add('Today');
2264if (
2265(self.MinDate && self.MinDate.getTime() > current_date.getTime()) || (self.MaxDate && self.MaxDate.getTime() < current_date.getTime())) {
2266td.class.add('Inactive');
2267}
2268tr.append(td);
2269current_date.setTime(current_date.getTime() + 24 * 3600 * 1000);
2270}
2271let table = g.children('.DaysTable tbody');
2272if (add_after) {
2273table.append(tr);
2274} else {
2275table.prepend(tr);
2276let m = g.children('.DaysOfMonth .DaysTable').css.get('margin-top') ? parseInt(g.children('.DaysOfMonth .DaysTable').css.get('margin-top')) : 0;
2277m -= tr.GetHeight();
2278touchStartM -= tr.GetHeight();
2279g.children('.DaysOfMonth .DaysTable').css.set('margin-top', m + 'px');
2280}
2281}
2282function WriteMonth(month, year)
2283{
2284let date = new Date(year, month, 1);
2285for (let i = 1; i <= 6; i++) {
2286WriteWeek(date);
2287date.setTime(date.getTime() + 7 * 24 * 3600 * 1000);
2288}
2289FillEmptySpace();
2290SetMonthEvents();
2291CheckAndSetMonth();
2292return;
2293let table = g.children('.DaysTable tbody');
2294table.SetHTML('');
2295//let date = new Date(year, month, 1);
2296//WriteWeek(new Date(year, month, 1));
2297return;
2298let first_day = date.getDay();
2299if (first_day == 0) first_day = 7;
2300first_day = first_day - 2;
2301let days = GetDaysOfMonth(month, year);
2302let last_day = new Date();
2303last_day.setTime(date.getTime());
2304last_day.setDate(days);
2305last_day = last_day.getDay();
2306if (last_day == 0) last_day = 7;
2307let cal_days = days + (7 - last_day);
2308let today = new Date();
2309for (let day = first_day * -1; day <= cal_days; day++) {
2310let tr = table.children('tr');
2311if (tr.Count()) {
2312tr = tr.SelectLast();
2313}
2314if (tr.Count() == 0 || tr.children('td').Count() == 7) {
2315tr = self.DaysRow.clone();
2316tr.SetHTML('');
2317table.append(tr);
2318}
2319let td_content = '';
2320if (day > 0 && day <= days) td_content = day;
2321if (self.AddMonthToFirstAndLast && (td_content == 1 || td_content == days)) td_content += ' ' + self.MonthsShortText[month];
2322let td = self.DayItem.clone();
2323if (td_content) {
2324td.class.remove('Inactive');
2325} else {
2326td.class.add('Inactive');
2327}
2328tr.append(td);
2329let day_td = tr.children('[data-lookup="Day"]').SelectLast();
2330day_td.SetHTML(td_content);
2331if (today.getDate() == day && today.getMonth() == month && today.getFullYear() == year) td.class.add('Today');
2332for (let id in self.InactiveDays) {
2333if (self.InactiveDays[id].getDate() == day && self.InactiveDays[id].getMonth() == month && self.InactiveDays[id].getFullYear() == year) {
2334td.class.add('Inactive');
2335break;
2336}
2337}
2338if (self.InactiveWeekDays.indexOf(new Date(year, month, day).getDay()) != -1
2339|| (self.MinDate != undefined && self.MinDate.getTime != undefined && self.MinDate.getTime() > new Date(year, month, day).getTime())
2340|| (self.MaxDate != undefined && self.MaxDate.getTime != undefined && self.MaxDate.getTime() < new Date(year, month, day).getTime())
2341) {
2342td.class.add('Inactive');
2343}
2344td.data.set('date', new Date(year, month, day));
2345}
2346g.children('.Header .Month').SetHTML(self.MonthsText[month]);
2347g.children('.Header .Year').SetHTML(year);
2348SetMonthEvents();
2349}
2350this.WriteActualMonth = function()
2351{
2352WriteMonth(self.CurrentDate.getMonth(), self.CurrentDate.getFullYear());
2353};
2354function GetDaysOfMonth(month, year)
2355{
2356var date = new Date(year, month);
2357var day = 28;
2358for (day; day <= 31; day++) {
2359date.setDate(day);
2360if (month != date.getMonth()) {
2361day--;
2362break;
2363}
2364}
2365if (day > 31) day = 31;
2366return day;
2367}
2368this.Init();
2369};
2370GraceWeb.prototype.Calendar.prototype.DaysText = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];
2371GraceWeb.prototype.Calendar.prototype.MonthsText = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
2372GraceWeb.prototype.Calendar.prototype.MonthsShortText = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
2373GraceWeb.prototype.Carousel = function(g)
2374{
2375let self = this;
2376this.Element = g;
2377this.Animations = {
2378Slide: 'Slide',
2379Fade: 'Fade',
2380SwipeOut: 'SwipeOut'
2381};
2382this.Animation = this.Animations.Slide;
2383this.Speed = 500; // animating 0.5s
2384this.TimeInterval = 5000; // default 5s
2385this.AfterMove = function() {};
2386this.BeforeMove = function() {};
2387this.Paused = false;
2388this.MovingTimeout;
2389this.KeepHeight = true;
2390this.WaitForVideoFinished = true; // if true, time interval is ignored for video items
2391this.AutoplayVideosAfterMove = false;
2392this.AutoplayVideosWhileMoving = true;
2393this.ItemsOnScreen = 1;
2394this.MoveByItems = 1;
2395this.MoveAsWhole = false;
2396this.Init = function() {
2397this.Element.class.add('Carousel');
2398let switchers = this.Element.children('.Switchers').Count() > 0 ? this.Element.Children('.Switchers') : g.NewElementFromHTML('<div class="Switchers"></div>');
2399let index = 0;
2400this.Element.children('.Item').each(function(el) {
2401el.data.set('index', index);
2402switchers.append(g.NewElementFromHTML('<div class="Point" data-index="' + index + '"></div>'));
2403index++;
2404});
2405switchers.children('.Point').e.click(function(el){
2406self.Stop();
2407let index = el.data.get('index');
2408self.Move(self.Element.children('.Item[data-index="' + index + '"]'));
2409self.Start();
2410});
2411if (this.Element.children('.Item.Active').Count() < this.ItemsOnScreen) {
2412this.Element.children('.Item').SelectFromStart(this.ItemsOnScreen).class.add('Active');
2413//switchers.children('.Point:first').class.add('Active');
2414DisplayImages(this.Element.children('.Item.Active[data-image], .Item.Active [data-image]'));
2415} else {
2416//switchers.children('.Point').Select(this.Element.children('.Item.Active').data.get('index')).class.add('Active');
2417}
2418if (this.Element.children('.Switchers').Count() == 0) {
2419this.Element.append(switchers);
2420}
2421let arrows_prev = g.Children('.Arrow.Prev');
2422if (!arrows_prev.Count()) {
2423arrows_prev = g.NewElementFromHTML('<div class="Arrow Prev"></div>');
2424g.append(arrows_prev);
2425}
2426let arrows_next = g.Children('.Arrow.Next');
2427if (!arrows_next.Count()) {
2428arrows_next = g.NewElementFromHTML('<div class="Arrow Next"></div>');
2429g.append(arrows_next);
2430}
2431arrows_prev.e.click(function() {
2432self.Stop();
2433self.MoveToPrev();
2434self.Start();
2435});
2436arrows_next.e.click(function() {
2437self.Stop();
2438self.MoveToNext();
2439self.Start();
2440});
2441let start_mouse_moving = 0;
2442let stop_mouse_moving = 0;
2443this.Element.e.on('touchstart', function(el, e){
2444stop_mouse_moving = start_mouse_moving = e.changedTouches[0].pageX;
2445});
2446this.Element.e.on('touchend', function(){
2447if (start_mouse_moving > stop_mouse_moving + 20) {
2448self.Stop();
2449self.MoveToNext();
2450self.Start();
2451} else if (start_mouse_moving < stop_mouse_moving - 20) {
2452self.Stop();
2453self.MoveToPrev();
2454self.Start();
2455}
2456});
2457this.Element.e.on('touchmove', function(el, e){
2458stop_mouse_moving = e.changedTouches[0].pageX;
2459});
2460};
2461this.SetEvents = function() {
2462this.Stop();
2463let interval = self.GetActiveItem().data.get('interval') == undefined ? this.TimeInterval : self.GetActiveItem().data.get('interval');
2464if (interval != null) {
2465this.MovingTimeout = setTimeout(function () {
2466self.MovingTimeout = null;
2467self.AutoMove();
2468}, interval);
2469}
2470};
2471this.SetActives = function()
2472{
2473let active = this.GetActiveItem();
2474active.class.remove('Active');
2475let new_active = g.children('.Item').SelectFromStart(this.ItemsOnScreen);
2476new_active.class.add('Active');
2477};
2478this.AutoMove = function() {
2479//console.log('AutoMove');
2480if (this.MovingTimeout) clearTimeout(this.MovingTimeout);
2481this.MovingTimeout = null;
2482if (this.Paused) return;
2483if (this.Element.children('.Item').Count() > 1) {
2484self.MoveToNext();
2485}
2486this.MovingTimeout = setTimeout(function() {
2487this.MovingTimeout = null;
2488if (self.WaitForVideoFinished && self.GetActiveItem().children('video').length > 0) {
2489self.GetActiveItem().children('video').e.on('ended', function() {
2490let ended_all = true;
2491self.GetActiveItem().children('video').each(function(el) {
2492if (!el.dom(0).paused) ended_all = false;
2493});
2494if (ended_all) {
2495self.AutoMove();
2496}
2497});
2498} else {
2499if (self.TimeInterval != null) self.Start();
2500}
2501}, self.Speed + 100);
2502};
2503this.Stop = function() {
2504//console.log('Stop');
2505if (this.MovingTimeout) clearTimeout(this.MovingTimeout);
2506this.MovingTimeout = null;
2507this.Paused = true;
2508};
2509this.Start = function(process_current) {
2510if (process_current) {
2511let actual = this.GetActiveItem();
2512if (actual.children('video').Count() > 0) {
2513actual.children('video').each(function(el){
2514if (el.dom(0).play) el.dom(0).play();
2515});
2516}
2517}
2518this.SetEvents();
2519this.Paused = false;
2520};
2521this.MoveToNext = function()
2522{
2523let next = this.GetActiveItem().SelectLast().NextAll('.Item');
2524if (this.MoveAsWhole) {
2525this.MoveAsWholeTo(next.Select(0));
2526} else {
2527if (next.Count()) {
2528this.Move(next.SelectFromStart(self.ItemsOnScreen));
2529} else {
2530this.Move(this.Element.children('.Item').SelectFromStart(self.ItemsOnScreen));
2531}
2532}
2533};
2534this.MoveToPrev = function() {
2535let prev = this.GetActiveItem().PreviousAll('.Item');
2536if (prev.Count()) {
2537this.Move(prev.Select(0), false);
2538} else {
2539this.Move(this.Element.Children('.Item').SelectLast(), false);
2540}
2541};
2542this.GetActiveItem = function() {
2543return this.Element.children('.Item.Active');
2544};
2545this.MoveAsWholeTo = function(new_item)
2546{
2547let actual = this.GetActiveItem();
2548if (new_item.dom(0) == actual.dom(0)) return; // don't move to the same item
2549let previous = new_item.PreviousAll('.Item');
2550//previous.AddElements(actual);
2551let l = 0;
2552previous.each(function(el) {
2553let mr = el.css.get('margin-right');
2554mr = mr ? parseInt(mr) : 0;
2555l += mr + el.GetWidth();
2556});
2557l *= -1;
2558g.children('.Item').css.set('left', l + 'px');
2559if (self.BeforeMove) self.BeforeMove(new_item);
2560actual.e.csstransitionend(function(el) {
2561el.class.remove('Active');
2562new_item.class.add('Active');
2563if (self.AfterMove) self.AfterMove();
2564});
2565};
2566this.Move = function(new_item, direction) {
2567if (direction == undefined) direction = true;
2568let actual = this.GetActiveItem();
2569if (new_item.dom(0) == actual.dom(0)) return; // don't move to the same item
2570if (this.AutoplayVideosWhileMoving && new_item.children('video').Count() > 0) {
2571new_item.children('video').each(function(el){
2572if (el.dom(0).play) el.dom(0).play();
2573});
2574}
2575//DisplayImages(new_item.children('[data-image]').add(new_item));
2576if (self.BeforeMove) self.BeforeMove(new_item);
2577let cl = direction ? 'ToNext' : 'ToPrev';
2578actual.class.add(this.Animation + cl);
2579new_item.class.add(this.Animation + cl);
2580actual.css.set('animation-duration', this.Speed + 'ms');
2581new_item.css.set('animation-duration', this.Speed + 'ms');
2582actual.e.on(['animationend', 'webkitAnimationEnd', 'oanimationend', 'MSAnimationEnd'], function(el) {
2583actual.e.cancel('animationend');
2584actual.e.cancel('webkitAnimationEnd');
2585actual.e.cancel('oanimationend');
2586actual.e.cancel('MSAnimationEnd');
2587//$(this).unbind('animationend  webkitAnimationEnd  oanimationend  MSAnimationEnd');
2588new_item.class.add('Active');
2589new_item.class.remove(self.Animation + cl);
2590actual.class.remove('Active');
2591actual.class.remove(self.Animation + cl);
2592actual = self.GetActiveItem();
2593if (self.AutoplayVideosAfterMove && actual.children('video').Count() > 0) {
2594actual.children('video').each(function(el){
2595if (el.dom(0).play) el.dom(0).play();
2596});
2597}
2598if (self.AfterMove) self.AfterMove();
2599});
2600this.Element.children('.Switchers .Point').class.remove('Active');
2601this.Element.children('.Switchers .Point[data-index="' + new_item.data.get('index') + '"]').class.add('Active');
2602};
2603this.Init();
2604};
2605var modoptions = [];
2606var modactual = -1;
2607g.e.domloaded(function() {
2608function Ajax(moduiles_id)
2609{
2610var ajax = g.f('Ajax');
2611ajax.Class = '\\Core\\Document\\Modules\\Ajax';
2612ajax.Method = 'Reload';
2613ajax.Data = {modules_id: moduiles_id.join('|')};
2614ajax.SuccessFnc = function(data) {
2615for (var id in data) {
2616g.children('[data-module][data-id="' + id + '"]').SetHTML(data[id]);
2617}
2618g.e.trigger('domloaded');
2619};
2620ajax.Send();
2621}
2622function Check()
2623{
2624var w = document.documentElement.clientWidth;
2625var h = document.documentElement.clientHeight;
2626var device = /mobile/i.test(navigator.userAgent) ? 'mobile' : 'desktop';
2627var new_current = -1;
2628var all_modules = [];
2629var options = [[], [], [], [], []];
2630for (var i in modoptions) {
2631var opt = modoptions[i];
2632if (opt.device && opt.device != device) continue;
2633if (opt.minw && w && opt.minw > w) continue;
2634if (opt.maxw && w && opt.maxw < w) continue;
2635if (opt.minh && h && opt.minh > h) continue;
2636if (opt.maxh && h && opt.maxh < h) continue;
2637if (opt.device && ((opt.minw && opt.maxw) || (opt.minh && opt.maxh))) {
2638var priority = 0;
2639} else if ((opt.minw && opt.maxw) || (opt.minh && opt.maxh)) {
2640var priority = 1;
2641} else if (opt.minw || opt.maxw || opt.minh || opt.maxh) {
2642var priority = 2;
2643} else if (opt.device) {
2644var priority = 3;
2645} else {
2646var priority = 4;
2647}
2648opt.i = i;
2649options[priority].push(opt);
2650}
2651for (var i in options) {
2652var opts = options[i];
2653if (opts.length > 0) {
2654for (var k in opts) {
2655var opt = opts[k];
2656new_current = opt.i;
2657for (var j in opt.modules) {
2658all_modules.push(opt.modules[j]);
2659}
2660}
2661break;
2662}
2663}
2664if (new_current != modactual) {
2665modactual = new_current;
2666if (modactual == -1) {
2667var modules = all_modules;
2668} else {
2669var modules = modoptions[modactual].modules;
2670}
2671Ajax(modules);
2672}
2673}
2674Check();
2675g.e.windowresize(function() {
2676Check();
2677});
2678});
2679GraceWeb.prototype.DataTables = function(g) {
2680var self = this;
2681this.SetEvents = function() {
2682var forms;
2683g.e.on('datapreviewloaded', function() {
2684InitTooltips();
2685var tables = g.children('.DataTable');
2686for (var i = 0; i < tables.Count(); i++) {
2687var t = tables.Select(i);
2688table = t.f('DataTable');
2689table.DataBlock = g;
2690if (t.class.has('DataActionTable')) table.EditableTable = true;
2691table.Init();
2692}
2693forms = g.children('.DataForm');
2694for (var i = 0; i < forms.Count(); i++) {
2695var table = forms.Select(i);
2696table = table.f('DataForm');
2697table.DataBlock = g;
2698table.Init();
2699}
2700});
2701g.children('.ActionToAdd').e.click(function(el) {
2702var f = forms.Select(0);
2703if (!f.children('.DForm').Count()) return;
2704var f = g.children('form').Select(0);
2705var form = f.f('DataForm');
2706form.SavePartially(f);
2707f.e.on('partially-saved', function() {
2708location.assign(el.attr.get('href'));
2709});
2710return false;
2711});
2712};
2713return this;
2714};
2715GraceWeb.prototype.DataForm = function(g) {
2716var self = this;
2717this.MainForm = g.f('Form');
2718this.MainForm.ProcessSubmit = false;
2719this.G = g;
2720this.DataBlock;
2721this.ValidFunctions = [];
2722this.Init = function()
2723{
2724g.children('input, select, textarea, [contenteditable]').attr.set('tabindex', '-1');
2725g.children('form .Item').e.on(['focus'], function(el, e) {
2726self.ItemFocus(el);
2727return false;
2728});
2729var opened_tab = g.children('form .Tabs .TabItem.Active').attr.get('data-tab');
2730var first_item = g.children('form [data-tab-target="' + opened_tab + '"] .Item');
2731if (first_item.Count() > 0) {
2732setTimeout(function() {
2733first_item.Select(0).e.trigger('focus');
2734}, 100);
2735}
2736g.e.on('keydown', function(el, e) {
2737if (e.which == 9) {// 9 = TAB
2738var item = g.children('form .Item.Focused');
2739if (e.shiftKey) { // pressing with shift - tab backwards
2740//var item = (el.class.has('Item') ? el : el.parent('.Item')).previous();
2741item = item.previous();
2742if (!item || !item.Count()) return false;
2743} else { // tab forwards
2744//var item = (el.class.has('Item') ? el : el.parent('.Item')).next();
2745item = item.next();
2746if (!item || !item.Count()) return false;
2747}
2748if (item.Count() > 0) {
2749item.e.trigger('focus');
2750//self.ItemFocus(item, el);
2751return false;
2752}
2753}
2754});
2755g.children('input, select, textarea, [contenteditable]').e.on(['focu
2755s'], function(el, e) {
2756if (el.parents('form .Item')) {
2757self.ItemFocus(el.parents('form .Item'), el);
2758e.stopped = true;
2759}
2760});
2761var form = (g.dom(0).tagName == 'FORM') ? g : g.parents('form');
2762form.e.on('submit', function(form, e) {
2763self.Save(form);
2764e.stopped = true;
2765return false;
2766});
2767};
2768this.ItemFocus = function(item, el)
2769{
2770var found_el = false;
2771if (el) {
2772var tag = el.dom(0).tagName;
2773if ((tag == 'INPUT' && el.attr.get('type') != 'hidden') || tag == 'SELECT' || tag == 'TEXTAREA' || el.attr.get('contenteditable')) {
2774found_el = true;
2775}
2776}
2777if (!found_el) {
2778var input = item.children('input, select, textarea, [contenteditable]');
2779if (input.Count()) {
2780input.dom(0).focus();
2781}
2782}
2783g.children('form .Item.Focused').e.trigger('blur');
2784g.children('form .Item').class.remove('Focused');
2785item.class.add('Focused');
2786};
2787this.IsValid = function(form)
2788{
2789return this.MainForm.IsValid();
2790};
2791this.SavePartially = function(form) {
2792var data = this.MainForm.GetValues(true, true);
2793var ajax = form.f('Ajax');
2794ajax.Class = '\\Core\\Data\\DataAjax';
2795ajax.Method = 'SavePartially';
2796ajax.Data = data;
2797ajax.SuccessFnc = function(d) {
2798window.history.replaceState({}, '', d.link);
2799for (var i in d) {
2800var parts = i.split('-');
2801if (parts.length != 2) continue;
2802var link = GraceW.children('[data-tab-target="tab-' + parts[0] + '"] .ActionTo' + parts[1]);
2803if (link.Count() > 0) {
2804link.attr.set('href', d[i]);
2805link.attr.set('data-href', d[i]);
2806}
2807}
2808g.e.trigger('partially-saved');
2809};
2810ajax.Send();
2811};
2812if (this.DataBlock) {
2813this.DataBlock.e.on('datapreviewloaded', function() {
2814self.Init();
2815});
2816}
2817g.e.on('datapreviewloaded', function() {
2818self.Init();
2819});
2820};
2821GraceWeb.prototype.DataForm.prototype.DistributeErrors = function(errors)
2822{
2823if (errors == undefined) errors = this.MainForm.GetErrors();
2824this.MainForm.MarkInvalidInputs();
2825}
2826GraceWeb.prototype.DataForm.prototype.GoToFirstErrorInput = function()
2827{
2828let el = g.children('.Invalid').Select(0);
2829if (!el) return;
2830el.e.focus();
2831}
2832GraceWeb.prototype.DataForm.prototype.Save = function(form)
2833{
2834if (!this.IsValid(form)) {
2835if (debug) console.error(this.MainForm.GetErrors());
2836this.DistributeErrors();
2837this.GoToFirstErrorInput();
2838return false;
2839}
2840var data = this.MainForm.GetValues(true, true);
2841var datablock = form.parent('.DataBlock');
2842if (datablock.Count()) {
2843data.key = datablock.attr.get('data-key');
2844}
2845var ajax = form.f('Ajax');
2846ajax.Class = '\\Core\\Data\\DataAjax';
2847ajax.Method = 'ValidateAndSave';
2848ajax.Data = data;
2849ajax.SuccessFnc = function(d) {
2850if (d.errors) {
2851for (var name in d.errors) {
2852var err = d.errors[name];
2853var err_el = new GraceWeb(document.createElement('div'));
2854err_el.class.add('Error');
2855err_el.SetHTML(err);
2856var input = form.children('[name="' + name + '"]');
2857input.AddAfter(err_el);
2858input.parents('.Item').class.add('ErrorBox');
2859}
2860} else if (d.backuplink) {
2861location.assign(d.backuplink);
2862}
2863};
2864ajax.Send();
2865};
2866function HideInputsRule(inputs_names, input_name, datas_names, hide_if_value_not_empty, message)
2867{
2868var input = g.children(input_name).f('Input');
2869var other_inputs = inputs_names ? g.children(inputs_names) : null;
2870var tabs = datas_names ? g.children(datas_names) : null;
2871var value = input.GetValue();
2872let empty = !value || value.length == 0 || value == '' || value == null || (input.GraceWeb.GetTagName() == 'select' && (value == 'NULL' || value == '0')) || (input.GraceWeb.attr.get('type') == 'checkbox' && !input.GraceWeb.attr.get('checked'));
2873if ((hide_if_value_not_empty && empty) || (!hide_if_value_not_empty && !empty)) {
2874hide = true;
2875} else {
2876hide = false;
2877g.children('[data-msg-by="' + input.GetName() + '"]').remove();
2878}
2879if (other_inputs) {
2880for (var i = 0; i < other_inputs.Count(); i++) {
2881var item = other_inputs.Select(i).parents('.Item');
2882if (!item || item.Count() == 0) item = other_inputs.Select(i);
2883if (hide) {
2884if (i == 0) {
2885var msg = item.clone();
2886msg.SetHTML('<div class="InNote">' + message + '</div>');
2887msg.attr.set('data-msg-by', input.GetName());
2888item.AddAfter(msg);
2889}
2890item.attr.set('data-hidden-by', input.GetName());
2891item.Hide();
2892} else {
2893if (item.attr.get('data-hidden-by') == input.GetName()) {
2894item.Display();
2895item.attr.remove('data-hidden-by');
2896}
2897}
2898}
2899}
2900if (tabs) {
2901for (var i = 0; i < tabs.Count(); i++) {
2902var tab = tabs.Select(i);
2903var tabs_block = tab.parents('.Tabs').f('Tabs');
2904if (hide) {
2905var msg = new GraceWeb(document.createElement('div'));
2906msg.SetHTML(message);
2907msg.attr.set('data-msg-by', input.GetName());
2908var tooltip = tab.f('Tooltip');
2909tooltip.TooltipBox = msg;
2910tooltip.Init();
2911tab.attr.set('data-hidden-by', input.GetName());
2912tabs_block.DisableTab(tab.attr.get('data-tab-index'));
2913} else {
2914if (tab.attr.get('data-hidden-by') == input.GetName()) {
2915tab.attr.remove('data-hidden-by');
2916tabs_block.ActivateTab(tab.attr.get('data-tab-index'));
2917var tooltip = tab.f('Tooltip');
2918tooltip.Destroy();
2919tab.class.remove('Tooltip');
2920}
2921}
2922}
2923}
2924}
2925g.e.domloaded(function() {
2926g.children('.DataBlock, .DataForm').e.on(['datapreviewloaded'], function(el, e) {
2927ActivationButton(el);
2928});
2929function ActivationButton(el)
2930{
2931el.children('.Bool.Activation').e.click(function(eb) {
2932if (eb.parent('.DataTable')) {
2933let act_input = eb.parent('.Input').children('input');
2934let input_name = act_input.attr.get('name').split('[')[1].split(']')[0];
2935let a = eb.f('Ajax');
2936a.Class = '\\Core\\Data\\DataAjax';
2937a.Method = 'ActivationSwitch';
2938a.Data = {
2939active_field_name: input_name,
2940value: act_input.attr.get('value') > 0 ? 0 : 1,
2941id: eb.parent('.Item').attr.get('data-iid')
2942};
2943a.SuccessFnc = function (data) {
2944if (data.ok) {
2945if (eb.class.has('Booltrue')) {
2946eb.class.remove('Booltrue');
2947eb.class.add('Boolfalse');
2948} else {
2949eb.class.remove('Boolfalse');
2950eb.class.add('Booltrue');
2951}
2952eb.parent('.Input').children('input').attr.set('value', eb.class.has('Booltrue') ? 1 : 0);
2953let g = eb.parent('.Input').children('input');
2954g.e.trigger('change');
2955}
2956};
2957a.Send();
2958} else {
2959if (eb.class.has('Booltrue')) {
2960eb.class.remove('Booltrue');
2961eb.class.add('Boolfalse');
2962} else {
2963eb.class.remove('Boolfalse');
2964eb.class.add('Booltrue');
2965}
2966eb.parent('.Input, .Item').children('input').attr.set('value', eb.class.has('Booltrue') ? 1 : 0);
2967let g = eb.parent('.Input, .Item').children('input');
2968g.e.trigger('change');
2969}
2970//eb.parents('.Item').children('.InlineActions .InlineEdit a').e.trigger('submit');
2971});
2972}
2973g.children('.DataBlock, .DataForm').each(function(el) {
2974ActivationButton(el);
2975});
2976});
2977g.e.domloaded(function() {
2978g.children('.DataBlock, .DataForm').e.on(['datapreviewloaded'], function(el, e) {
2979SwitchButton(el);
2980});
2981function SwitchButton(el)
2982{
2983el.children('.Bool:not(.Activation)').e.click(function(eb, e) {
2984if (eb.class.has('Booltrue')) {
2985eb.class.remove('Booltrue');
2986eb.class.add('Boolfalse');
2987} else {
2988eb.class.remove('Boolfalse');
2989eb.class.add('Booltrue');
2990}
2991if (!eb.parent('.Input')) {
2992eb.parent('.InputColumn').children('input').attr.set('value', eb.class.has('Booltrue') ? 1 : 0);
2993let g = eb.parent('.InputColumn').children('input');
2994g.e.trigger('change');
2995return;
2996}
2997eb.parent('.Input').children('input').attr.set('value', eb.class.has('Booltrue') ? 1 : 0);
2998let g = eb.parent('.Input').children('input');
2999g.e.trigger('change');
3000if (eb.parent('.DataTable')) {
3001var a = eb.f('Ajax');
3002a.Class = '\\Core\\Data\\Inputs\\BoolSwitchAjax';
3003a.Method = 'SwitchIt';
3004a.Data = {
3005dbcolumn: eb.attr.get('data-db-dbcol'),
3006value: eb.parent('.Input').children('input').attr.get('value') > 0 ? 1 : 0,
3007id: eb.parent('.Item').attr.get('data-iid')
3008};
3009a.SuccessFnc = function (data) {
3010};
3011a.Send();
3012}
3013//eb.parents('.Item').children('.InlineActions .InlineEdit a').e.trigger('submit');
3014});
3015}
3016g.children('.DataBlock, .DataForm').each(function(el) {
3017SwitchButton(el);
3018});
3019});
3020GraceWeb.prototype.DataInputColor = function(g) {
3021g.e.click(function (el) {
3022let dialog = el.next().clone();
3023let dd = dialog.f('Dialog');
3024dd.Open();
3025dialog.children('.ColorChoice').e.click(function (cel) {
3026let color = cel.data.get('color');
3027dialog.children('.ColorChoice').class.remove('Active');
3028cel.class.add('Active');
3029g.css.set('background-color', '#' + color);
3030g.previous().attr.set('value', color);
3031dd.Close();
3032return false;
3033});
3034return false;
3035});
3036};
3037g.e.domloaded(function() {
3038g.children('.ColorBox').each(function(el) {
3039el.f('DataInputColor');
3040});
3041});
3042GraceWeb.prototype.DataInputDate = function(g)
3043{
3044let item = g.parent('.Column');
3045this.Open = function() {
3046item.class.add('Opened');
3047dialog.css.set('height', 'auto');
3048};
3049this.Close = function() {
3050item.class.remove('Opened');
3051dialog.css.remove('height');
3052};
3053GraceW.children('.Item').e.on('focus', function(it) {
3054if (!item.parent('.Item').class.has('Focused')) {
3055self.Close();
3056} else {
3057self.Open();
3058}
3059});
3060};
3061g.e.domloaded(function() {
3062g.children('[data-type="Date"] [type="text"]').each(function(el) {
3063el.f('DataInputDate');
3064});
3065});
3066function DataFile()
3067{
3068return;
3069IncludeJs('Core/Filemanager/Filemanager.js');
3070if ($('#FilemanagerFFU').length == 0) {
3071$('body').append('<div id="FilemanagerFFU"></div>');
3072}
3073function SetFilePath(name, path) {
3074$('.' + name.replace('[', '_').replace(']', '_') + 'path').html(path);
3075}
3076function ShowFilePath(name, id) {
3077Ajax('Core/FD/File.php', {type: 'file-path', id: id}, function (path) {
3078SetFilePath(name, path);
3079});
3080}
3081g.children('.FileuploadFilemanagerOpen').e.click(function (el, e) {
3082var fm = $('<div class="Filemanager"></div>');
3083fm.Filemanager({
3084onChooseFile: function (id, path, original_name, type) {
3085el.parents('.Column').children('.FileUploadIdValue').attr.set('value', id
3085);
3086$(el.parents('.Column').children('.FileUpload').dom(0)).data('FileUpload').ShowFile({
3087type: type,
3088file: path
3089});
3090fm.Dialog('Remove');
3091},
3092AfterShowItem: function () {
3093fm.Dialog('SetDimensions');
3094}
3095});
3096fm.Dialog({Maximized: true});
3097return false;
3098});
3099for (var i = 0; i < g.children('.DataForm').Count(); i++) {
3100var form = g.children('.DataForm').Select(i).f('DataForm');
3101form.ValidFunctions.push(function (form) {
3102var fus = form.children('.FileUpload .State[value="uploading"]');
3103for (var j = 0; j < fus.Count(); j++) {
3104var fu = fus.Select(j).parent('.FileUpload');
3105fu.children('.Progress').class.remove('Hidden');
3106$(fu.dom(0)).data('FileUpload').Settings.OnUploaded = function () {
3107form.f('DataForm').Save(form);
3108};
3109return false;
3110}
3111return true;
3112});
3113}
3114}
3115g.children('.DataForm').e.on('datapreviewloaded', function() {
3116DataFile();
3117});
3118function DataMultiSelect()
3119{
3120function Init()
3121{
3122g.children('.DataMultiSelect [type="checkbox"]').e.on('change', function(chk) {
3123var item = chk.parents('.Item');
3124if (chk.attr.get('checked')) {
3125item.children('.DataMultiSelect .SelectedCheckboxes').append(chk.parents('.ChkItem'), true);
3126Init();
3127} else {
3128item.children('.DataMultiSelect .ChkeckboxesItems [value="' + chk.attr.get('value') + '"]').attr.set('checked', false);
3129item.children('.DataMultiSelect .SelectedCheckboxes [value="' + chk.attr.get('value') + '"]').parents('.ChkItem').remove();
3130}
3131});
3132g.children('.DataMultiSelect .DataCheckboxsesSearch input').e.on('keyup', function(el) {
3133var value = el.attr.get('value').toLowerCase().replace(/ /g, '');
3134if (value) {
3135var chks = el.parents('.DataMultiSelect').children('.ChkItem').dom();
3136for (var i in chks) {
3137if (typeof chks[i] != 'object') continue;
3138var chk = new GraceWeb(chks[i]);
3139if (chk.GetText().toLowerCase().replace(/ /g, '').split(value).length > 1) {
3140chk.class.remove('Hidden');
3141} else {
3142chk.class.add('Hidden');
3143}
3144}
3145} else {
3146el.parents('.DataMultiSelect').children('.ChkItem').class.remove('Hidden');
3147}
3148});
3149g.children('.SelectFilter').e.click(function(f) {
3150f.children('.SearchInSelect input[type="text"]').dom(0).focus();
3151});
3152g.children('.SelectFilter .SearchInSelect input[type="text"]').e.on('keyup', function(el, e) {
3153var value = el.attr.get('value').toLowerCase().replace(/ /g, '');
3154if (value) {
3155var chks = el.parents('.Panel').children('li').dom();
3156for (var i in chks) {
3157if (typeof chks[i] != 'object') continue;
3158var chk = new GraceWeb(chks[i]);
3159if (chk.getText().toLowerCase().replace(/ /g, '').split(value).length > 1) {
3160chk.class.remove('Hidden');
3161} else {
3162chk.class.add('Hidden');
3163}
3164}
3165} else {
3166el.parents('.Panel').children('li').class.remove('Hidden');
3167}
3168});
3169var scroll = null;
3170var selects = g.children('.DataMultiSelect .ScrollBarOverlay');
3171for (var i = 0; i < selects.Count(); i++) {
3172var s = selects.Select(i);
3173scroll = s.f('ScrollBar');
3174scroll.ScrollingPanel = s.children('.ScrollBarPanel');
3175}
3176}
3177g.children('.DataBlock').e.on('datapreviewloaded', function(el, e) {
3178Init();
3179});
3180Init();
3181}
3182g.e.domloaded(function() {
3183DataMultiSelect();
3184});
3185function DataSelect()
3186{
3187function Init()
3188{
3189g.children('.DataSelect .DataSelectSearch input').e.on('keyup', function(el) {
3190var value = el.attr.get('value').toLowerCase().replace(/ /g, '');
3191if (value) {
3192var chks = el.parents('.DataSelect').children('option').dom();
3193for (var i in chks) {
3194if (typeof chks[i] != 'object') continue;
3195var chk = new GraceWeb(chks[i]);
3196if (chk.GetText().toLowerCase().replace(/ /g, '').split(value).length > 1) {
3197chk.class.remove('Hidden');
3198} else {
3199chk.class.add('Hidden');
3200}
3201}
3202} else {
3203el.parents('.DataSelect').children('option').class.remove('Hidden');
3204}
3205});
3206g.children('.SelectFilter').e.click(function(f) {
3207f.children('.SearchInSelect input[type="text"]').dom(0).focus();
3208});
3209g.children('.SelectFilter .SearchInSelect input[type="text"]').e.on('keyup', function(el, e) {
3210var value = el.attr.get('value').toLowerCase().replace(/ /g, '');
3211if (value) {
3212var chks = el.parents('.Panel').children('li').dom();
3213for (var i in chks) {
3214if (typeof chks[i] != 'object') continue;
3215var chk = new GraceWeb(chks[i]);
3216if (chk.GetText().toLowerCase().replace(/ /g, '').split(value).length > 1) {
3217chk.class.remove('Hidden');
3218} else {
3219chk.class.add('Hidden');
3220}
3221}
3222} else {
3223el.parents('.Panel').children('li').class.remove('Hidden');
3224}
3225});
3226}
3227g.children('.DataBlock').e.on('datapreviewloaded', function(el, e) {
3228Init();
3229});
3230Init();
3231}
3232DataSelect();
3233function DataSelectSmooth()
3234{
3235function Init()
3236{
3237g.children('.DataSelect [name]').e.on('change', function(el) {
3238let value = el.attr.get('value');
3239SelectItemByValue(value, el.parent('.DataSelect'));
3240//el.parent('.DataSelect').children('.SelectItem[data-value="' + val + '"]').e.click();
3241});
3242g.children('.DataSelect .DataSelectSearch input').e.on('keyup', function(el) {
3243var value = el.attr.get('value').toLowerCase().replace(/ /g, '');
3244if (value) {
3245var chks = el.parents('.DataSelect').children('.SelectItem').dom();
3246for (var i in chks) {
3247if (typeof chks[i] != 'object') continue;
3248var chk = new GraceWeb(chks[i]);
3249if (chk.GetText().toLowerCase().replace(/ /g, '').split(value).length > 1) {
3250chk.class.remove('Hidden');
3251} else {
3252chk.class.add('Hidden');
3253}
3254}
3255} else {
3256el.parents('.DataSelect').children('.SelectItem').class.remove('Hidden');
3257}
3258});
3259g.children('.SelectFilter').e.click(function(f) {
3260f.children('.SearchInSelect input[type="text"]').dom(0).focus();
3261});
3262g.children('.SelectFilter .SearchInSelect input[type="text"]').e.on('keyup', function(el, e) {
3263var value = el.attr.get('value').toLowerCase().replace(/ /g, '');
3264if (value) {
3265var chks = el.parents('.Panel').children('li').dom();
3266for (var i in chks) {
3267if (typeof chks[i] != 'object') continue;
3268var chk = new GraceWeb(chks[i]);
3269if (chk.GetText().toLowerCase().replace(/ /g, '').split(value).length > 1) {
3270chk.class.remove('Hidden');
3271} else {
3272chk.class.add('Hidden');
3273}
3274}
3275} else {
3276el.parents('.Panel').children('li').class.remove('Hidden');
3277}
3278});
3279g.children('.SelectSmooth .SelectItem').e.on('click', function(el) {
3280SelectItem(el);
3281let input = el.parent('.DataSelect').children('[name]');
3282input.attr.set('value', el.attr.get('data-value'));
3283input.e.trigger('change');
3284});
3285function SelectItemByValue(value, select)
3286{
3287let item = select.children('[data-value="' + value + '"]');
3288if (item.Count()) {
3289SelectItem(item);
3290} else {
3291DeselectAll(select.children('.SelectItem'));
3292}
3293}
3294function DeselectAll(items)
3295{
3296items.class.remove('Chosen');
3297items.class.remove('Focused');
3298}
3299function SelectItem(item)
3300{
3301let items = item.DirectParent().children('.SelectItem');
3302items.class.remove('Chosen');
3303items.class.remove('Focused');
3304item.class.add('Focused');
3305item.class.add('Chosen');
3306}
3307g.children('body').e.on('keydown', function(el, e) {
3308if (e.which != 38 && e.which != 40 && e.which != 13) return;
3309var up = e.which == 38;
3310var down = e.which == 40;
3311var enter = e.which == 13;
3312var items = g.children('.Item.Focused .SelectSmoothItems .SelectItem');
3313if (!items.Count()) return;
3314var focused = g.children('.Item.Focused .SelectSmoothItems .SelectItem.Focused');
3315if (focused.Count() && enter) {
3316items.class.remove('Chosen');
3317focused.class.add('Chosen');
3318let input = focused.parent('.DataSelect').children('[name]');
3319input.attr.set('value', focused.attr.get('data-value'));
3320input.e.trigger('change');
3321return false;
3322}
3323var new_focused;
3324if (focused.Count()) {
3325if (down && focused.next()) {
3326new_focused = focused.next();
3327} else if (up && focused.previous()) {
3328new_focused = focused.previous();
3329}
3330} else {
3331new_focused = items.Select(0);
3332}
3333if (new_focused) {
3334items.class.remove('Focused');
3335new_focused.class.add('Focused');
3336}
3337return false;
3338});
3339var scroll = null;
3340var selects = g.children('.SelectSmooth');
3341for (var i = 0; i < selects.Count(); i++) {
3342var s = selects.Select(i);
3343scroll = s.f('ScrollBar');
3344scroll.ScrollingPanel = s.children('.SelectSmoothItems');
3345}
3346}
3347g.children('.DataBlock').e.on('datapreviewloaded', function(el, e) {
3348Init();
3349});
3350Init();
3351}
3352setTimeout(function() {
3353DataSelectSmooth();
3354}, 10);
3355g.e.domloaded(function() {
3356DataSelectSmooth();
3357});
3358GraceWeb.prototype.ChoosingTree = function(g) {
3359this.Init = function() {
3360g.children('[type="checkbox"]').e.on('change', function(chk) {
3361var selected = chk.attr.get('checked');
3362var topitem = chk;
3363while (topitem.parents('.TItem') && topitem.parents('.TItem').Count()) {
3364topitem = topitem.parents('.TItem');
3365for (var i = 0; i < topitem.Count(); i++) {
3366topitem.Select(i).children('[type="checkbox"]').Select(0).attr.set('checked', selected);
3367}
3368}
3369chk.parents('.TItem').children('[type="checkbox"]').attr.set('checked', selected);
3370});
3371var scroll = null;
3372var selects = g.children('.ChoosingTree .ScrollBarOverlay');
3373for (var i = 0; i < selects.Count(); i++) {
3374var s = selects.Select(i);
3375scroll = s.f('ScrollBar');
3376scroll.ScrollingPanel = s.children('.ScrollBarPanel');
3377}
3378};
3379this.Init();
3380};
3381g.e.domloaded(function() {
3382g.children('.ChoosingTree').f('ChoosingTree');
3383});
3384GraceWeb.prototype.DataTable = function(g) {
3385let self = this;
3386this.DataBlock;
3387this.EditableTable = false;
3388this.FiltersOptions = null;
3389this.SearchingPhrase = '';
3390this.ActiveFilters = {};
3391this.ActiveSearchingPhrase = '';
3392var filter_keyup_timeout;
3393this.Init = function() {
3394g.children('.LoadMoreBtn').e.click(self.LoadMoreBtn);
3395g.children('.RowSymbol').e.click(function(el) {
3396el.parent('.ActionsCell').children('.Panel a').Select(0).e.trigger('click');
3397});
3398g.children('.ActionsCell').e.on('mouseover', function(el) {
3399var item = el.parent('.Item');
3400item.class.add('PanelOpened');
3401});
3402g.children('.Item').e.on('mouseleave', function(item) {
3403item.class.remove('PanelOpened');
3404});
3405g.children('.ToInlineEdit').e.click(function(el, e) {
3406e.stopPropagation();
3407var loading = el.parents('.Item').f('Loading');
3408loading.Set();
3409var ajax = el.f('Ajax');
3410ajax.Class = '\\Core\\Data\\DataAjax';
3411ajax.Method = 'LoadEditRow';
3412ajax.Data.id = el.attr.get('data-id');
3413ajax.SuccessFnc = function(d) {
3414$(el.parents('.Item').dom(0)).hide();
3415loading.Remove();
3416var new_element = document.createElement('table');
3417new_element.innerHTML = d.row;
3418el.parents('.Item').AddAfter(new GraceWeb(new_element.querySelector('tr')));
3419g.e.trigger('datapreviewloaded');
3420el.parents('.Item').next().children('.Cancel').e.click(function() {
3421el.parents('.Item').next().remove();
3422$(el.parents('.Item').dom()).show();
3423return false;
3424});
3425};
3426ajax.Send();
3427return false;
3428});
3429g.children('.ActionsCell .Panel a').e.click(function(el, e) {
3430//console.log(e);
3431//location.assign(el.attr.get('href'));
3432});
3433g.children('.Item .ToInlineEdit').e.on('submit', function(el) {
3434var loading = el.parents('.Item').f('Loading');
3435loading.Set();
3436var d = GetDataOfForm($(el.parents('.Item').dom()), true);
3437var a = el.parents('.Item').f('Ajax');
3438a.Link = el.attr.get('data-link');
3439a.Data = d;
3440a.Class = '\\Core\\Data\\DataAjax';
3441a.Method = 'SaveAndGetRow';
3442a.SuccessFnc = function(d) {
3443if (el.parents('.Item').class.has('EditingItem')) {
3444el.parents('.Item').previous().remove();
3445}
3446var new_element = document.createElement('table');
3447new_element.innerHTML = d.row;
3448el.parents('.Item').AddAfter(new GraceWeb(new_element.querySelector('tr')));
3449el.parents('.Item').remove();
3450g.e.trigger('datapreviewloaded');
3451loading.Remove();
3452};
3453a.Send();
3454return false;
3455});
3456g.children('.Item .Submit').e.click(function(el) {
3457el.previous().children('a').e.trigger('submit');
3458return false;
3459});
3460if (self.EditableTable) {
3461g.children('.Item [name]').e.on('change', function(el) {
3462var item = el.parent('.Item');
3463var id = item.attr.get('data-iid');
3464var a = item.f('Ajax');
3465a.Data = {};
3466a.Data[item.parent('[data-key]').attr.get('data-key') + '[id]'] = id;
3467a.Data[el.attr.get('name')] = el.attr.get('value');
3468a.Class = '\\Core\\Data\\DataAjax';
3469a.Method = 'Save';
3470a.SuccessFnc = function(d) {
3471item.attr.set('data-iid', d.id);
3472};
3473a.Send();
3474});
3475g.children('.AddToActionTable').e.click(function(el) {
3476var a = el.f('Ajax');
3477a.Class = '\\Core\\Data\\ActionTableAjax';
3478a.Method = 'NewRow';
3479a.SuccessFnc = function(d) {
3480var row = new GraceWeb('<table>' + d.row + '</table>');
3481if (g.children('.Items .Item').Count() > 0) {
3482if (el.attr.get('data-to') == 'start') {
3483g.children('.Items .Item:first-of-type').AddBefore(row.children('tr'));
3484} else {
3485g.children('.Items .Item:last-of-type').AddAfter(row.children('tr'));
3486}
3487} else {
3488g.children('.Items').append(row.children('tr'));
3489}
3490g.children('.Item[data-id=""]').children('input, select').e.trigger('focus');
3491g.e.trigger('datapreviewloaded');
3492};
3493a.Send();
3494});
3495}
3496var order_tds = g.children('.ActionsCell svg');
3497if (g.attr.get('data-order-allow') > 0) {
3498var o = order_tds.f('TableRowDnD');
3499}
3500order_tds.e.on('dropped', function(g) {
3501var orders = {};
3502var items = g.parent('.Items').children('.Item');
3503for (var i = 0; i < items.Count(); i++) {
3504var o = items.Select(i);
3505orders[o.attr.get('data-iid')] = parseInt(i) + 1;
3506}
3507var a = g.f('Ajax');
3508a.Class = '\\Core\\Data\\DataAjax';
3509a.Method = 'SaveOrder';
3510a.Data = {order: JSON.stringify(orders)};
3511a.Send();
3512});
3513this.SetEvents();
3514this.UpdateFiltersFromCode();
3515};
3516this.SetEvents = function()
3517{
3518g.children('.CloseFilter').e.click(function(el, e) {
3519delete self.ActiveFilters[el.attr.get('data-item-name')][self.ActiveFilters[el.attr.get('data-item-name')].indexOf(el.attr.get('data-item-id'))];
3520let input = el.parent('.SetFiltersInput');
3521el.remove();
3522if (!input.children('.SetFilterItem').Count()) {
3523input.remove();
3524}
3525self.FilterApply();
3526e.stopped = true;
3527return false;
3528});
3529g.children('.CancelSearch').e.click(function(el, e) {
3530self.ActiveSearchingPhrase = self.SearchingPhrase = '';
3531self.GetSearchInput().attr.set('data-value', '');
3532g.children('.SearchingSet').remove();
3533self.FilterApply();
3534e.stopped = true;
3535return false;
3536});
3537};
3538this.UpdateTable = function()
3539{
3540};
3541this.UpdateFiltersFromCode = function()
3542{
3543self.ActiveSearchingPhrase = self.GetSearchInput().attr.get('data-value');
3544self.ActiveFilters = {};
3545g.children('.SetFilterItem').each(function(el) {
3546if (!el.attr.get('data-item-name')) return;
3547if (!self.ActiveFilters[el.attr.get('data-item-name')]) self.ActiveFilters[el.attr.get('data-item-name')] = [];
3548self.ActiveFilters[el.attr.get('data-item-name')].push(el.attr.get('data-item-id'));
3549});
3550};
3551this.CancelFilter = function()
3552{
3553self.ActiveFilters = {};
3554self.SearchingPhrase = '';
3555self.ActiveSearchingPhrase = '';
3556self.GetSearchInput().attr.set('data-value', '');
3557self.FilterApply();
3558};
3559this.FilterApply = function()
3560{
3561let regexp = /(&[a-z0-9\-\_]+\[f\][^&$]*)/gi;
3562let link = location.href.replace(regexp, '');
3563regexp = /(&[a-z0-9\-\_]+\[search\][^&$]*)/gi;
3564link = link.replace(regexp, '');
3565regexp = /(&[a-z0-9\-\_]+%5Bf%5D[^&$]*)/gi;
3566link = link.replace(regexp, '');
3567regexp = /(&[a-z0-9\-\_]+%5Bsearch%5D[^&$]*)/gi;
3568link = link.replace(regexp, '');
3569if (self.ActiveSearchingPhrase) {
3570link += '&' + self.GetSearchInput().attr.get('name') + '=' + self.ActiveSearchingPhrase;
3571}
3572for (let name in self.ActiveFilters) {
3573for (let vk in self.ActiveFilters[name]) {
3574let value = self.ActiveFilters[name][vk];
3575link += '&' + name + '[' + value + ']=' + value;
3576}
3577}
3578DynamicUrlChange(link);
3579let ajax = g.children('.Filter').f('Ajax');
3580ajax.Class = '\\Core\\Data\\DataAjax';
3581ajax.Method = 'LoadMore';
3582ajax.Link = location.href;
3583ajax.SuccessFnc = function(data) {
3584g.children('.DataTable .Items').SetHTML(data.items);
3585g.children('.DataTable .SetFilters').SetHTML(data.setfilters);
3586g.parent('.DataBlock').children('.Actions').SetHTML(data.actions);
3587let btn = g.parent('.DataBlock').children('.LoadMoreBtn');
3588if (btn) {
3589if (data.btn) {
3590btn.replace(g.NewElementFromHTML(data.btn));
3591} else {
3592btn.class.add('Hidden');
3593}
3594}
3595//el.replace(new GraceWeb(data.btn));
3596g.e.trigger('datapreviewloaded');
3597};
3598ajax.Send();
3599};
3600this.ProvideFiltersOptions = function()
3601{
3602let list = g.children('.FoundOptions ul');
3603let options = self.GetFiltersOptions();
3604list.SetHTML('');
3605if (self.SearchingPhrase) {
3606list.SetHTML('<li class="JustSearch Focused">Search for "' + self.SearchingPhrase + '"</li>');
3607let no = 0;
3608for (let i in options) {
3609if (i > 50) break;
3610let filter_name = options[i].name;
3611let items = options[i].items;
3612for (let j in items) {
3613if (!items[j]) continue;
3614if (filter_name.toLowerCase().split(self.SearchingPhrase).length > 1 || items[j].toLowerCase().split(self.SearchingPhrase).length > 1) {
3615list.append('<li data-f-name="' + i + '" data-f-value="' + j + '">' + filter_name + ': ' + items[j] + '</li>');
3616no++;
3617if (no > 30) break;
3618}
3619}
3620}
3621} else if (self.ActiveSearchingPhrase || Object.keys(self.ActiveFilters).length) {
3622list.SetHTML('<li class="CancelSearch Focused">Cancel searching</li>');
3623} else {
3624return;
3625}
3626self.SetEventsForFiltersList(list);
3627};
3628this.SetEventsForFiltersList = function(list)
3629{
3630list.children('li').e.click(function(li) {
3631li.class.add('Chosen');
3632let input = self.GetSearchInput();
3633if (li.class.has('JustSearch')) {
3634self.ActiveSearchingPhrase = input.attr.get('value');
3635input.attr.set('data-value', self.ActiveSearchingPhrase);
3636input.attr.set('value', '');
3637self.FilterApply();
3638} else if (li.class.has('CancelSearch')) {
3639self.CancelFilter();
3640} else {
3641input.attr.set('value', '');
3642self.ActivateFilter(li.attr.get('data-f-name'), li.attr.get('data-f-value'));
3643}
3644});
3645};
3646this.ActivateFilter = function(name, value)
3647{
3648if (!self.ActiveFilters[name]) {
3649self.ActiveFilters[name] = [];
3650}
3651self.ActiveFilters[name].push(value);
3652self.FilterApply();
3653};
3654this.GetFiltersOptions = function()
3655{
3656if (self.FiltersOptions == null) {
3657self.FiltersOptions = [];
3658self.LoadFiltersOptionsAndProvide();
3659}
3660return self.FiltersOptions;
3661};
3662this.LoadFiltersOptions = function(provide_after)
3663{
3664let a = g.f('Ajax');
3665a.Method = 'LoadFiltersOptions';
3666a.Class = '\\Core\\Data\\DataAjax';
3667a.SuccessFnc = function(data) {
3668self.FiltersOptions = data;
3669if (provide_after) {
3670self.ProvideFiltersOptions();
3671}
3672};
3673a.Send();
3674};
3675this.LoadFiltersOptionsAndProvide = function()
3676{
3677self.LoadFiltersOptions(true);
3678};
3679this.GetSearchInput = function()
3680{
3681return g.children('[data-filter]');
3682};
3683this.LoadMoreBtn = function(el)
3684{
3685DynamicUrlChange(el.attr.get('href'));
3686var ajax = el.f('Ajax');
3687ajax.Class = '\\Core\\Data\\DataAjax';
3688ajax.Method = 'LoadMore';
3689ajax.SuccessFnc = function(data) {
3690g.children('.Items').append(GraceW.NewElementFromHTML('<table>' + data.items + '</table>').children('.Item'));
3691el.replace(g.NewElementFromHTML(data.btn));
3692g.e.trigger('datapreviewloaded');
3693};
3694ajax.Send();
3695return false;
3696};
3697if (this.DataBlock) {
3698this.DataBlock.e.on('datapreviewloaded', function() {
3699self.Init();
3700});
3701}
3702g.e.on('datapreviewloaded', function() {
3703self.Init();
3704});
3705};
3706GraceWeb.prototype.TableRowDnD = function(g) {
3707var self = this;
3708this.Dragged;
3709this.DummyRow;
3710this.DraggedX;
3711this.DraggedRowWidth;
3712this.DraggedTable;
3713this.LastDragged;
3714var mouse_y;
3715this.Init = function() {
3716g.e.on('mousedown', function(go, e) {
3717self.LastDragged = go;
3718mouse_y = e.clientY;
3719return false;
3720//self.MouseMove(go, e);
3721});
3722document.body.addEventListener('mousemove', function(e) {
3723//GraceW.children('body').e.on('mousemove', function(g, e) {
3724if (self.LastDragged && !self.DraggedRowWidth && (mouse_y != e.clientY)) {
3725var go = self.LastDragged;
3726self.DraggedRowWidth = go.parents('tr').dom(0).clientWidth;
3727self.DraggedX = e.clientX - go.parents('tr').offset().left;
3728self.DraggedTable = go.parents('tbody');
3729if (self.DraggedTable.dom().length == 0) self.DraggedTable = go.parents('table');
3730var table = go.parent('table');
3731self.Dragged = document.createElement('table');
3732self.Dragged.innerHTML = '<tbody class="Items"></tbody>';
3733self.Dragged = new GraceWeb(self.Dragged);
3734self.Dragged.children('.Items').append(go.parents('tr'));
3735self.Dragged.class.add('TableRowDnDDragged');
3736table.append(self.Dragged);
3737self.DummyRow = document.createElement('tr');
3738self.DummyRow.innerHTML = '<td colspan="' + self.Dragged.children('td').dom().length + '"></td>';
3739self.DummyRow = new GraceWeb(self.DummyRow);
3740self.DummyRow.class.add('TableRowDnDPlacement');
3741}
3742self.MouseMove(g, e);
3743});
3744document.body.addEventListener('mouseup', function(e) {
3745//GraceW.children('body').e.on('mouseup', function(go, e) {
3746var ld = self.LastDragged;
3747self.LastDragged = null;
3748if (!self.Dragged) return;
3749self.DummyRow.AddAfter(self.Dragged.children('tr'));
3750self.DummyRow.remove();
3751self.DummyRow = null;
3752self.Dragged.remove();
3753self.Dragged = null;
3754self.DraggedRowWidth = null;
3755ld.e.trigger('dropped');
3756});
3757};
3758this.MouseMove = function(gm, e) {
3759if (!self.Dragged || !self.DummyRow) return;
3760var actual_top = GraceW.dom(0).scrollTop + e.clientY;
3761self.Dragged.css.set('top', (GraceW.dom(0).scrollTop + e.clientY - self.Dragged.dom(0).clientHeight / 2) + 'px');
3762var perc = 100 / self.DraggedRowWidth * self.Dragged.dom(0).clientWidth;
3763var plus_x = self.DraggedX / 100 * perc;
3764self.Dragged.css.set('left', (e.clientX - plus_x) + 'px');
3765var first = true;
3766var items = self.DraggedTable.class.has('Items') ? self.DraggedTable : self.DraggedTable.parents('.Items');
3767if (items && items.Count() > 0) {
3768var trs = items.children('tr:not(.TableRowDnDPlacement)');
3769for (var i = 0; i < trs.Count(); i++) {
3770var tr = trs.Select(i);
3771var hh = tr.dom(0).clientHeight / 2;
3772if (first) {
3773var top_border = tr.offset().top;
3774var bottom_border = tr.offset().top + hh;
3775if (actual_top > top_border && actual_top <= bottom_border) {
3776tr.AddBefore(self.DummyRow);
3777break;
3778}
3779}
3780var top_border = tr.offset().top + hh;
3781if (tr.next() && tr.next().Count() > 0) {
3782var bottom_border = tr.next().offset().top + tr.next().dom(0).clientHeight;
3783} else {
3784var bottom_border = tr.offset().top + tr.dom(0).clientHeight;
3785}
3786if (actual_top > top_border && actual_top <= bottom_border) {
3787tr.AddAfter(self.DummyRow);
3788break;
3789}
3790}
3791}
3792};
3793this.Init();
3794};
3795GraceWeb.prototype.Dialog = function(g) {
3796var self = this;
3797this.CloseFor = 0; // Close for X miliseconds - 0 means not automatically
3798this.TopClass = '';
3799this.HeadName = '';
3800this.CloseByEsc = true;
3801this.AfterClose = function() {};
3802this.AfterOpen = function() {};
3803this.AfterSetDimensions = function() {};
3804this.PlaceAt = GraceW.children('body');
3805this.DialogElement;
3806var CloseTimeout;
3807this.Open = function() {
3808self.DialogElement = new GraceWeb(document.createElement('div'));
3809self.DialogElement.class.add('DialogModal');
3810if (g.attr.get('data-top-class')) self.DialogElement.class.add(g.attr.get('data-top-class'));
3811if (self.TopClass) self.DialogElement.class.add(self.TopClass);
3812var box = new GraceWeb(document.createElement('div'));
3813box.class.add('DialogBox');
3814var head = self.GetHeader();
3815if (head) box.append(head);
3816var dialog = g;
3817dialog.class.add('DialogContent');
3818dialog.class.remove('Hidden');
3819box.append(dialog);
3820let close_cross = g.NewElementFromHTML('\n' +
3821'<div class="Close CloseCross">\n' +
3822'\t<svg xmlns="http://www.w3.org/2000/svg" width="16.971" height="16.971" viewB
3822ox="0 0 16.971 16.971">\n' +
3823'\t\t<g transform="translate(7.071 -8.485) rotate(45)">\n' +
3824'\t\t\t<rect width="22" height="2" rx="1" transform="translate(2 10)"/>\n' +
3825'\t\t\t<rect width="22" height="2" rx="1" transform="translate(14 0) rotate(90)"/>\n' +
3826'\t\t</g>\n' +
3827'\t</svg>\n' +
3828'</div>');
3829box.append(close_cross);
3830self.DialogElement.append(box);
3831self.PlaceAt.append(self.DialogElement);
3832self.SetDimensions();
3833self.SetEvents();
3834this.AfterOpen(self.DialogElement);
3835if (self.CloseFor > 0) {
3836CloseTimeout = setTimeout(function() {
3837self.Close();
3838}, self.CloseFor);
3839}
3840GraceW.class.add('DialogOpened');
3841};
3842this.StopCloseTiming = function() {
3843clearTimeout(CloseTimeout);
3844CloseTimeout = null;
3845};
3846this.Close = function() {
3847GraceW.class.remove('DialogOpened');
3848self.DialogElement.remove();
3849this.AfterClose(self.DialogElement);
3850g.e.trigger('dialog-closed')
3851};
3852this.SetEvents = function() {
3853self.DialogElement.children('.Close').e.click(function(el, e) {
3854self.Close();
3855return false;
3856});
3857g.e.windowresize(function() {
3858self.SetDimensions();
3859});
3860if (this.CloseByEsc) {
3861self.PlaceAt.e.on('keyup', function(el, e) {
3862if (e.keyCode == 27) { // ESC key
3863self.Close();
3864}
3865});
3866}
3867};
3868this.GetHeader = function() {
3869if (g.children('.DialogHead').Count()) {
3870var head = g.children('.DialogHead').clone();
3871head.class.remove('Hidden');
3872} else {
3873var head = new GraceWeb(document.createElement('div'));
3874head.class.add('DialogHead');
3875if (g.children('.DialogHeadText').Count()) {
3876var t = g.children('.DialogHeadText').clone();
3877t.class.remove('Hidden');
3878head.append(t);
3879} else {
3880if (!self.HeadName.length) return null;
3881var text = new GraceWeb(document.createElement('div'));
3882text.class.add('DialogHeadText');
3883text.SetHTML(self.HeadName);
3884head.SetHTML(text);
3885}
3886}
3887return head;
3888}
3889this.SetDimensions = function() {
3890var box = self.DialogElement.children('.DialogBox');
3891var cont = box.children('.DialogContent');
3892cont.css.remove('max-height');
3893if (box.GetHeight() > box.GetWindowHeight()) {
3894cont.css.set('height', '0');
3895cont.css.set('max-height', (box.GetWindowHeight() - box.GetHeight()) + 'px');
3896cont.css.remove('height');
3897}
3898box.css.remove('margin-top');
3899box.css.set('margin-top', (box.GetWindowHeight() / 2 - box.GetHeight() / 2) + 'px');
3900this.AfterSetDimensions(self.DialogElement);
3901}
3902};
3903function Cache()
3904{
3905}
3906Cache.prototype.ExpirationMs = 0;
3907Cache.prototype.SaveAsJSON = true;
3908Cache.prototype.UseWebStorage = true;
3909Cache.prototype.Save = function(key, value)
3910{
3911if (this.SaveAsJSON) {
3912value = {
3913ts: new Date().getTime(),
3914value: value
3915};
3916value = JSON.stringify(value);
3917}
3918if (window.flutter_inappwebview) {
3919window.flutter_inappwebview.callHandler('StorageSave', key, value);
3920} else if (this.UseWebStorage) {
3921localStorage.setItem(key, value);
3922}
3923}
3924Cache.prototype.Load = function(key, check_expiration)
3925{
3926if (check_expiration == undefined) check_expiration = true;
3927let self = this;
3928let promise = new Promise(function(resolve, reject) {
3929if (window.flutter_inappwebview) {
3930window.flutter_inappwebview.callHandler('StorageLoad', key).then(function (result) {
3931if (!result) {
3932reject();
3933} else {
3934if (self.SaveAsJSON) {
3935result = JSON.parse(result);
3936if (!check_expiration || !self.ExpirationMs || (new Date()).getTime() - result.ts > self.ExpirationMs) {
3937resolve(result.value);
3938} else {
3939reject(result);
3940}
3941} else {
3942resolve(result);
3943}
3944}
3945}, function () {
3946reject();
3947});
3948} else if (self.UseWebStorage) {
3949let result = localStorage.getItem(key);
3950if (!result) {
3951reject();
3952} else {
3953if (self.SaveAsJSON) {
3954result = JSON.parse(result);
3955if (!check_expiration || !self.ExpirationMs || (new Date()).getTime() - result.ts < self.ExpirationMs) {
3956resolve(result.value);
3957} else {
3958reject(result);
3959}
3960} else {
3961resolve(result);
3962}
3963}
3964} else {
3965reject();
3966}
3967});
3968return promise;
3969}
3970Cache.prototype.Remove = function(key)
3971{
3972let self = this;
3973let promise = new Promise(function(resolve, reject) {
3974if (window.flutter_inappwebview) {
3975window.flutter_inappwebview.callHandler('StorageRemove', key).then(function () {
3976resolve();
3977}, function () {
3978reject();
3979});
3980} else if (self.UseWebStorage) {
3981localStorage.removeItem(key);
3982resolve();
3983} else {
3984reject();
3985}
3986});
3987return promise;
3988}
3989function DocumentMedia()
3990{
3991this.Cache = new Cache();
3992this.Cache.UseWebStorage = false;
3993}
3994DocumentMedia.prototype.Cache;
3995DocumentMedia.prototype.OfflineUse = false;
3996DocumentMedia.prototype.LoadMedia = function(link)
3997{
3998let self = this;
3999let promise = new Promise(function(resolve, reject) {
4000if (self.Cache) {
4001self.Cache.Load(link, false).then(function (data) {
4002resolve(data);
4003}, function () {
4004let a = new GraceWeb.prototype.Ajax();
4005a.Link = link;
4006a.ReturnsJson = false;
4007a.SendAjaxInfo = false;
4008a.Data = {encode: 'base64'};
4009a.SuccessFnc = function (data) {
4010if (self.Cache) self.Cache.Save(link, data);
4011resolve(data);
4012};
4013a.Send();
4014});
4015} else {
4016let a = new GraceWeb.prototype.Ajax();
4017a.Link = link;
4018a.ReturnsJson = false;
4019a.SendAjaxInfo = false;
4020a.Data = {encode: 'base64'};
4021a.SuccessFnc = function (data) {
4022if (self.Cache) self.Cache.Save(link, data);
4023resolve(data);
4024};
4025a.Send();
4026}
4027});
4028return promise;
4029}
4030DocumentMedia.prototype.DisplayImagesByElements = function(elements)
4031{
4032let self = this;
4033let is_safari = GetBrowserName() == 'Safari';
4034elements.each(function(el) {
4035let mobile = GetWindowWidth() < 1024 && el.data.get('mobile-image');
4036let srcs = mobile ? el.data.get('mobile-image') : el.data.get('image');
4037if (srcs == undefined || srcs == null) return;
4038srcs = srcs.split('|');
4039for (let i in srcs) {
4040let src = srcs[i].trim();
4041if (is_safari && /\.webp$/.test(src)) continue;
4042self.LoadMedia(src).then(function(data) {
4043if (self.OfflineUse) {
4044data = 'data:image/jpeg;base64,' + data;
4045} else {
4046data = src;
4047}
4048if (el.data.get('image-type') == 'bg') {
4049el.css.set('background-image', 'url(\'' + data + '\')');
4050el.attr.remove(mobile ? 'data-mobile-image' : 'data-image');
4051} else {
4052let img = g.NewElementFromHTML('<img src="' + data + '" />');
4053el.attr.remove(mobile ? 'data-mobile-image' : 'data-image');
4054if (el.data.get('title')) {
4055img.attr.set('alt', el.data.get('title'));
4056img.attr.set('title', el.data.get('title'));
4057}
4058el.append(img);
4059}
4060});
4061break;
4062}
4063el.e.trigger('image-displayed');
4064});
4065}
4066Page = function(use_history)
4067{
4068this.UseHistory = use_history;
4069this.SetEvents();
4070if (!this.UseHistory) {
4071this.CurrentPageId = this.WriteHistoryEntry(location.pathname + location.search);
4072this.UpdateHistoryEntryByCurrentPage();
4073}
4074this.Cache = new Cache();
4075this.Cache.UseWebStorage = false;
4076}
4077Page.prototype.UseHistory;
4078Page.prototype.CustomHistory = {};
4079Page.prototype.CachePages = {};
4080Page.prototype.CurrentPageId = 0;
4081Page.prototype.Cache;
4082Page.prototype.PrimarySourceNet = true;
4083Page.prototype.SetEvents = function()
4084{
4085if (this.UseHistory) {
4086let self = this;
4087window.addEventListener('popstate', (event) => {
4088let new_page_id = event.state.page_id ? event.state.page_id : 0;
4089if (new_page_id < this.CurrentPageId) {
4090self.GoBack(new_page_id);
4091} else {
4092self.GoForward(new_page_id);
4093}
4094this.CurrentPageId = new_page_id;
4095g.e.trigger('link-changed');
4096});
4097}
4098}
4099Page.prototype.IsCached = function(link)
4100{
4101if (this.CachePages[link]) return true;
4102return false;
4103}
4104Page.prototype.GetCachedPage = function(link)
4105{
4106return this.CachePages[link].clone();
4107}
4108Page.prototype.LoadPage = function(link)
4109{
4110let self = this;
4111return new Promise(function(resolve, reject) {
4112let a = new GraceWeb.prototype.Ajax();
4113a.Link = link;
4114a.ReturnsJson = false;
4115a.SendAjaxInfo = false;
4116a.SuccessFnc = function(html) {
4117let page = g.NewElementFromHTML(html, true);
4118self.CachePages[link] = page.clone();
4119resolve({html: page, original_page: html});
4120};
4121a.ErrorFnc = function() {
4122reject();
4123};
4124a.Send();
4125});
4126}
4127Page.prototype.ReadyNewPage = function(link, force_download)
4128{
4129let self = this;
4130if (navigator.onLine && (this.PrimarySourceNet || force_download)) {
4131this.LoadPage(link).then(function(data) {
4132let html = data.html;
4133self.SetPage(html, link);
4134g.e.trigger('link-changed');
4135self.Cache.Save(link, data.original_page);
4136});
4137} else if (this.IsCached(link)) {
4138this.SetPage(this.GetCachedPage(link), link);
4139g.e.trigger('link-changed');
4140} else {
4141this.Cache.Load(link, false).then(function(html) {
4142self.SetPage(g.NewElementFromHTML(html, true), link);
4143g.e.trigger('link-changed');
4144}, function() {
4145});
4146}
4147}
4148Page.prototype.WriteHistoryEntry = function(link, data)
4149{
4150let id = new Date().getTime();
4151this.CustomHistory[id] = {
4152id: id,
4153link: link,
4154data: data == undefined ? {} : data
4155};
4156return id;
4157}
4158Page.prototype.UpdateHistoryEntry = function(data, replace)
4159{
4160if (replace) {
4161this.CustomHistory[this.CurrentPageId].data = data;
4162} else {
4163}
4164let current_data = this.CustomHistory[this.CurrentPageId].data;
4165if (!current_data) current_data = {};
4166for (let i in data) {
4167current_data[i] = data[i];
4168}
4169this.CustomHistory[this.CurrentPageId].data = current_data;
4170}
4171Page.prototype.ClearHistory = function(latest_id)
4172{
4173if (this.UseHistory) {
4174} else {
4175let new_history = {};
4176for (let id in this.CustomHistory) {
4177if (id <= latest_id) {
4178new_history[id] = this.CustomHistory[id];
4179}
4180}
4181this.CustomHistory = new_history;
4182}
4183}
4184Page.prototype.UpdateHistoryEntryByCurrentPage = function()
4185{
4186let page_data = {swap: {}};
4187g.children('[data-lookup-page-swap]').each(function(el) {
4188let selector = el.data.get('lookup-page-swap');
4189page_data.swap[selector] = el.clone();
4190});
4191page_data.goback = g.children('[data-goback]').data.get('goback');
4192this.UpdateHistoryEntry(page_data);
4193}
4194Page.prototype.SetPage = function(html, link)
4195{
4196let self = this;
4197let current_page = g.children('[data-lookup="Page"][data-page-id="' + this.CurrentPageId + '"]').SelectLast();
4198if (!current_page) current_page = g.children('[data-lookup="Page"]').SelectLast();
4199if (!current_page.data.get('page-id')) current_page.data.set('page-id', this.CurrentPageId);
4200let pages = g.children('[data-lookup="Pages"]');
4201pages.children('[data-lookup="Page"]').each(function(page) {
4202if (parseInt(page.data.get('page-id')) > self.CurrentPageId) page.remove();
4203});
4204if (this.UseHistory) {
4205DynamicUrlChange(link, null, {page_id: ++this.CurrentPageId});
4206} else {
4207this.ClearHistory(this.CurrentPageId);
4208this.CurrentPageId = self.WriteHistoryEntry(link);
4209try {
4210window.history.replaceState({page_id: this.CurrentPageId, isBackPage: false}, '', link);
4211} catch (e) {
4212}
4213}
4214let new_page = html.children('[data-lookup="Page"]');
4215new_page.data.set('status', 'new');
4216new_page.data.set('page-id', this.CurrentPageId);
4217let observer = new MutationObserver(function(mutationsList, observer) {
4218observer.disconnect();
4219setTimeout(function() {
4220current_page.data.set('status', 'going-away');
4221new_page.data.remove('status');
4222}, 10);
4223g.e.trigger('domloaded');
4224});
4225observer.observe(pages.dom(0), {attributes: false, childList: true, subtree: true});
4226pages.append(new_page);
4227g.children('[data-lookup-page-swap]').each(function(original_el) {
4228let selector = original_el.data.get('lookup-page-swap');
4229let new_el = html.children('[data-lookup-page-swap="' + selector + '"]');
4230if (!new_el.Count()) return;
4231original_el.replace(new_el.clone());
4232});
4233g.children('[data-goback]').data.set('goback', html.children('[data-goback]').data.get('goback'));
4234this.UpdateHistoryEntryByCurrentPage();
4235}
4236Page.prototype.GoBack = function(page_id)
4237{
4238let pages = g.children('[data-lookup="Pages"]');
4239let current_page = pages.children('[data-lookup="Page"][data-page-id="' + this.CurrentPageId + '"]');
4240let new_page = pages.children('[data-lookup="Page"][data-page-id="' + page_id + '"]');
4241new_page.data.remove('status');
4242current_page.data.set('status', 'new');
4243this.UpdatePageByHistoryData(page_id);
4244}
4245Page.prototype.GoForward = function(page_id)
4246{
4247let pages = g.children('[data-lookup="Pages"]');
4248let current_page = pages.children('[data-lookup="Page"][data-page-id="' + this.CurrentPageId + '"]');
4249let new_page = pages.children('[data-lookup="Page"][data-page-id="' + page_id + '"]');
4250current_page.data.set('status', 'going-away');
4251new_page.data.remove('status');
4252this.UpdatePageByHistoryData(page_id);
4253}
4254Page.prototype.UpdatePageByHistoryData = function(page_id)
4255{
4256let page_history = this.CustomHistory[page_id];
4257for (let selector in page_history.data.swap) {
4258let val = page_history.data.swap[selector];
4259let el = g.children('[data-lookup-page-swap="' + selector + '"]');
4260el.replace(val);
4261}
4262g.children('[data-goback]').data.set('goback', page_history.data.goback);
4263}
4264Page.prototype.CanGoBack = function()
4265{
4266let prev_page;
4267for (let id in this.CustomHistory) {
4268if (id >= this.CurrentPageId) break;
4269prev_page = this.CustomHistory[id];
4270}
4271if (prev_page) return true;
4272return false;
4273}
4274Page.prototype.GoToPrevious = function()
4275{
4276if (this.UseHistory) {
4277} else {
4278let prev_page;
4279for (let id in this.CustomHistory) {
4280if (id >= this.CurrentPageId) break;
4281prev_page = this.CustomHistory[id];
4282}
4283if (prev_page) {
4284try {
4285window.history.replaceState({page_id: prev_page.id, isBackPage: false}, '', prev_page.link);
4286} catch (e) {
4287}
4288this.GoBack(prev_page.id);
4289this.CurrentPageId = prev_page.id;
4290g.e.trigger('page-went-back');
4291}
4292}
4293}
4294GraceWeb.prototype.EmbedLink = function(g)
4295{
4296let self = this;
4297this.G = g;
4298};
4299GraceWeb.prototype.EmbedLink.prototype.CheckElement = function(el)
4300{
4301let link_regexp = /(((http(s?)\:\/\/)?)[a-z0-9\-_]+\.[a-z0-9\-_\.\/\=\?\&\;\@]+)/igm;
4302let res = link_regexp.exec(el.GetText());
4303let link = res && res[1] ? res[1].trim() : '';
4304if (link) {
4305let embed = this.BuildEmbed(link);
4306return embed;
4307}
4308return null;
4309};
4310GraceWeb.prototype.EmbedLink.prototype.BuildEmbedFromElement = function(el, simple_iframe)
4311{
4312let embed;
4313let type;
4314if (el.data.get('vimeo-code')) {
4315embed = this.BuildVimeo(null, el.data.get('vimeo-code'), el.data.get('autoplay'));
4316type = 'Vimeo';
4317}
4318if (embed) {
4319let ei = g.NewElementFromHTML('<div class="EmbedIn"></div>');
4320ei.append(embed);
4321embed = ei;
4322if (simple_iframe) return embed;
4323let div = g.NewElementFromHTML('<div class="EmbedLink"></div>');
4324div.data.set('link', link);
4325div.append(embed);
4326div.class.add(type);
4327return div;
4328}
4329return null;
4330};
4331GraceWeb.prototype.EmbedLink.prototype.BuildEmbed = function(link, simple_iframe)
4332{
4333let embed;
4334let type;
4335if (/youtube|youtu\.be/i.test(link)) {
4336embed = this.BuildYoutube(link);
4337type = 'YouTube';
4338} else if (/instagram/i.test(link)) {
4339embed = this.BuildInstagram(link);
4340type = 'Instagram';
4341} else if (/twitter/i.test(link)) {
4342embed = this.BuildTwitter(link);
4343type = 'Twitter';
4344} else if (/vimeo/i.test(link)) {
4345embed = this.BuildVimeo(link);
4346type = 'Vimeo';
4347} else {
4348embed = this.BuildWebsite(link);
4349type = 'Website';
4350}
4351if (embed) {
4352let ei = g.NewElementFromHTML('<div class="EmbedIn"></div>');
4353ei.append(embed);
4354embed = ei;
4355if (simple_iframe) return embed;
4356let div = g.NewElementFromHTML('<div class="EmbedLink"></div>');
4357div.data.set('link', link);
4358div.append(embed);
4359div.class.add(type);
4360return div;
4361}
4362return null;
4363};
4364GraceWeb.prototype.EmbedLink.prototype.BuildYoutube = function(link)
4365{
4366let code = /v=([^$&]+)/.exec(link);
4367if (!code[1]) return null;
4368let frame = g.NewElementFromHTML('<iframe></iframe>');
4369frame.data.set('link', link);
4370frame.attr.set('src', 'https://www.youtube.com/embed/' + code[1] + '?enablejsapi=1');
4371return frame;
4372};
4373GraceWeb.prototype.EmbedLink.prototype.BuildInstagram = function(link)
4374{
4375if (link.split('?').length > 1) {
4376link = link.replace('?', 'embed/?');
4377} else {
4378link += 'embed/';
4379}
4380let frame = g.NewElementFromHTML('<iframe></iframe>');
4381frame.data.set('link', link);
4382frame.attr.set('src', link);
4383return frame;
4384};
4385GraceWeb.prototype.EmbedLink.prototype.BuildTwitter = function(link)
4386{
4387return null;
4388let frame = g.NewElementFromHTML('<iframe></iframe>');
4389frame.data.set('link', link);
4390frame.attr.set('src', 'https://publish.twitter.com/oembed?url=' + link);
4391return frame;
4392};
4393GraceWeb.prototype.EmbedLink.prototype.BuildVimeo = function(link, code, autoplay)
4394{
4395if (!code && link) {
4396let c = /vimeo\.com\/([0-9]+)/.exec(link);
4397if (c && c[1]) code = c[1];
4398}
4399if (autoplay) autoplay = '&autoplay=1';
4400let frame = g.NewElementFromHTML('<iframe></iframe>');
4401frame.attr.set('src', 'https://player.vimeo.com/video/' + code + '?title=1&byline=0&portrait=0' + autoplay + '&loop=false&color=&fullscreen=1');
4402return frame;
4403};
4404GraceWeb.prototype.EmbedLink.prototype.BuildWebsite = function(link)
4405{
4406let self = this;
4407let embed = g.NewElementFromHTML('<div class="Frame"></div>');
4408embed.data.set('link', link);
4409let a = embed.f('Ajax');
4410a.Class = '\\Core\\GrabData\\LinkAjax';
4411a.Method = 'Show';
4412a.Data = {link: link};
4413a.SuccessFnc = function(data) {
4414if (data && data.html) {
4415embed.SetHTML(data.html);
4416self.G.e.trigger('load');
4417}
4418};
4419a.ErrorFnc = function() {
4420embed.remove();
4421};
4422a.Send();
4423return embed;
4424};
4425File = function(path) {
4426this.Path = path;
4427};
4428File.prototype.Id;
4429File.prototype.Path;
4430File.prototype.Mime;
4431File.prototype.Name;
4432File.prototype.GetName = function()
4433{
4434if (this.Name) return this.Name;
4435return this.Path.split('/').reverse()[0];
4436};
4437File.prototype.GetMime = function()
4438{
4439if (File.prototype.Mime) return File.prototype.Mime;
4440return this.GetMimeByExtension();
4441};
4442File.prototype.GetMimeByExtension = function()
4443{
4444let types = this.GetAllMimes();
4445let ext = this.GetExtension();
4446if (types[ext]) return types[ext];
4447return '';
4448};
4449File.prototype.GetExtension = function()
4450{
4451return this.Path.split('.').reverse()[0].toLowerCase();
4452};
4453File.prototype.IsVideo = function()
4454{
4455let type = this.GetMime();
4456return /video\//.test(type);
4457};
4458File.prototype.IsImage = function()
4459{
4460let type = this.GetMime();
4461return /image\//.test(type);
4462};
4463File.prototype.GetEl = function()
4464{
4465if (this.IsImage()) {
4466return this.GetImageEl();
4467} else if (this.IsVideo()) {
4468return this.GetVideoEl();
4469} else {
4470return this.GetGenericEl();
4471}
4472};
4473File.prototype.GetImageEl = function()
4474{
4475let el = GraceW.NewElementFromHTML('<a style="background-image: url(' + this.Path + ');" data-image="' + this.Path + '" href="' + this.Path + '" class="Image NewWindow"></a>');
4476return el;
4477};
4478File.prototype.GetVideoEl = function()
4479{
4480let el = GraceW.NewElementFromHTML('<video><source src="' + this.Path + '" /></video>');
4481return el;
4482};
4483File.prototype.GetGenericEl = function()
4484{
4485let el = GraceW.NewElementFromHTML('<a href="' + this.Path + '" class="NewWindow">' + this.GetName() + '</a>');
4486return el;
4487};
4488File.prototype.GetAllMimes = function()
4489{
4490let types = {
4491'json': 'application/json',
4492'js': 'application/javascript',
4493'amo': 'artao/module',
4494'ath': 'artao/theme',
4495'ico': 'image/x-icon',
4496'ez': 'application/andrew-inset',
4497'hqx': 'application/mac-binhex40',
4498'cpt': 'application/mac-compactpro',
4499'doc': 'application/msword',
4500'docx': 'application/msword',
4501'bin': 'application/octet-stream',
4502'dms': 'application/octet-stream',
4503'lha': 'application/octet-stream',
4504'lzh': 'application/octet-stream',
4505'exe': 'application/octet-stream',
4506'class': 'application/octet-stream',
4507'so': 'application/octet-stream',
4508'dll': 'application/octet-stream',
4509'oda': 'application/oda',
4510'pdf': 'application/pdf',
4511'ai': 'application/postscript',
4512'eps': 'application/postscript',
4513'ps': 'application/postscript',
4514'psd': 'application/psd',
4515'smi': 'application/smil',
4516'smil': 'application/smil',
4517'wbxml': 'application/vnd.wap.wbxml',
4518'wmlc': 'application/vnd.wap.wmlc',
4519'wmlsc': 'application/vnd.wap.wmlscriptc',
4520'bcpio': 'application/x-bcpio',
4521'vcd': 'application/x-cdlink',
4522'pgn': 'application/x-chess-pgn',
4523'cpio': 'application/x-cpio',
4524'csh': 'application/x-csh',
4525'dcr': 'application/x-director',
4526'dir': 'application/x-director',
4527'dxr': 'application/x-director',
4528'dvi': 'application/x-dvi',
4529'spl': 'application/x-futuresplash',
4530'gtar': 'application/x-gtar',
4531'hdf': 'application/x-hdf',
4532'skp': 'application/x-koan',
4533'skd': 'application/x-koan',
4534'skt': 'application/x-koan',
4535'skm': 'application/x-koan',
4536'latex': 'application/x-latex',
4537'nc': 'application/x-netcdf',
4538'cdf': 'application/x-netcdf',
4539'sh': 'application/x-sh',
4540'shar': 'application/x-shar',
4541'swf': 'application/x-shockwave-flash',
4542'sit': 'application/x-stuffit',
4543'sv4cpio': 'application/x-sv4cpio',
4544'sv4crc': 'application/x-sv4crc',
4545'tar': 'application/x-tar',
4546'tcl': 'application/x-tcl',
4547'tex': 'application/x-tex',
4548'texinfo': 'application/x-texinfo',
4549'texi': 'application/x-texinfo',
4550't': 'application/x-troff',
4551'tr': 'application/x-troff',
4552'roff': 'application/x-troff',
4553'man': 'application/x-troff-man',
4554'me': 'application/x-troff-me',
4555'ms': 'application/x-troff-ms',
4556'ustar': 'application/x-ustar',
4557'src': 'application/x-wais-source',
4558'xhtml': 'application/xhtml+xml',
4559'xht': 'application/xhtml+xml',
4560'zip': 'application/zip',
4561'au': 'audio/basic',
4562'snd': 'audio/basic',
4563'mid': 'audio/midi',
4564'midi': 'audio/midi',
4565'kar': 'audio/midi',
4566'mpga': 'audio/mpeg',
4567'mp2': 'audio/mpeg',
4568'mp3': 'audio/mpeg',
4569'aif': 'audio/x-aiff',
4570'aiff': 'audio/x-aiff',
4571'aifc': 'audio/x-aiff',
4572'm3u': 'audio/x-mpegurl',
4573'ram': 'audio/x-pn-realaudio',
4574'rm': 'audio/x-pn-realaudio',
4575'rpm': 'audio/x-pn-realaudio-plugin',
4576'ra': 'audio/x-realaudio',
4577'wav': 'audio/x-wav',
4578'pdb': 'chemical/x-pdb',
4579'xyz': 'chemical/x-xyz',
4580'bmp': 'image/bmp',
4581'gif': 'image/gif',
4582'ief': 'image/ief',
4583'jpeg': 'image/jpeg',
4584'jpg': 'image/jpeg',
4585'jpe': 'image/jpeg',
4586'png': 'image/png',
4587'webp': 'image/webp',
4588'tiff': 'image/tiff',
4589'tif': 'image/tif',
4590'djvu': 'image/vnd.djvu',
4591'djv': 'image/vnd.djvu',
4592'wbmp': 'image/vnd.wap.wbmp',
4593'ras': 'image/x-cmu-raster',
4594'pnm': 'image/x-portable-anymap',
4595'pbm': 'image/x-portable-bitmap',
4596'pgm': 'image/x-portable-graymap',
4597'ppm': 'image/x-portable-pixmap',
4598'rgb': 'image/x-rgb',
4599'xbm': 'image/x-xbitmap',
4600'xpm': 'image/x-xpixmap',
4601'xwd': 'image/x-windowdump',
4602'igs': 'model/iges',
4603'iges': 'model/iges',
4604'msh': 'model/mesh',
4605'mesh': 'model/mesh',
4606'silo': 'model/mesh',
4607'wrl': 'model/vrml',
4608'vrml': 'model/vrml',
4609'css': 'text/css',
4610'html': 'text/html',
4611'htm': 'text/html',
4612'asc': 'text/plain',
4613'txt': 'text/plain',
4614'rtx': 'text/richtext',
4615'rtf': 'text/rtf',
4616'sgml': 'text/sgml',
4617'sgm': 'text/sgml',
4618'tsv': 'text/tab-seperated-values',
4619'wml': 'text/vnd.wap.wml',
4620'wmls': 'text/vnd.wap.wmlscript',
4621'etx': 'text/x-setext',
4622'xml': 'text/xml',
4623'xsl': 'text/xml',
4624'mpeg': 'video/mpeg',
4625'mpg': 'video/mpeg',
4626'mpe': 'video/mpeg',
4627'qt': 'video/quicktime',
4628'mov': 'video/quicktime',
4629'mxu': 'video/vnd.mpegurl',
4630'avi': 'video/x-msvideo',
4631'mp4': 'video/mp4',
4632'movie': 'video/x-sgi-movie',
4633'ice': 'x-conference-xcooltalk',
4634'php': 'application/php',
4635'csv': 'text/csv',
4636'xls': 'application/vnd.ms-excel',
4637'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
4638'svg': 'image/svg+xml',
4639};
4640return types;
4641};
4642GraceWeb.prototype.FileUpload = function(g){
4643let self = this;
4644this.G = g;
4645this.OnUploaded = function(){};
4646this.OnSelect = function(){};
4647this.OnImageDisplay = function(){};
4648this.ActualFile = false;
4649this.ShowProgress = true;
4650this.State = 'new';
4651this.Uploaded = [];
4652this.UploadingFiles;
4653g.children('.Upload').e.click(function(el, e){
4654g.children('[type="file"]').dom(0).click();
4655e.stopped = true;
4656return false;
4657});
4658this.Pasting = g.children('.Upload').f('ObjectsPasting');
4659this.Pasting.DragOverReturn = false;
4660this.Pasting.ChangeFocusOnDragover = false;
4661g.children('.Upload').e.on('drop', function(el, e){
4662e.preventDefault();
4663if (self.Pasting.HasFiles()) {
4664g.data.set('status', 'uploading');
4665let files = [];
4666for (let i in self.Pasting.GetFiles()) {
4667if (isNaN(parseInt(i))) continue;
4668files.push(self.Pasting.GetFiles()[i]);
4669}
4670self.UploadingFiles = files;
4671ChangeImage(files);
4672} else if (self.Pasting.GetByType('savedfile')) {
4673let file = JSON.parse(self.Pasting.GetByType('savedfile'));
4674let img = g.NewElementFromHTML('<img src="' + file.file + '" />');
4675img.e.on('load', function(){
4676self.OnImageDisplay();
4677});
4678let box = g.children('.ImageBox.Hidden').clone();
4679box.class.remove('Hidden');
4680box.children('.Image').SetHTML(img);
4681g.children('.Files').SetHTML(box);
4682g.children('.Id').attr.set('value', file.id);
4683}
4684});
4685g.children('.Upload').e.click(function(){
4686g.children('.LargeFileError').class.add('Hidden');
4687});
4688g.children('[type="file"]').e.on('change', function(el){
4689let files = [];
4690let total_size = 0;
4691el = el.dom(0);
4692for (let i in el.files) {
4693if (isNaN(parseInt(i))) continue;
4694files.push(el.files[i]);
4695total_size += el.files[i].size;
4696}
4697if (total_size > maxfilesize) {
4698g.children('.LargeFileError').class.remove('Hidden');
4699} else {
4700g.data.set('status', 'uploading');
4701self.UploadingFiles = files;
4702self.Pasting.DroppedData = {};
4703self.Pasting.DroppedData.files = files;
4704self.Pasting.DroppedData.types = ['Files'];
4705if (g.children('.Folder').Count()) self.Pasting.Ajax.Data['FUuploadfilefolder'] = g.children('.Folder').attr.get('value');
4706self.Pasting.UploadFiles();
4707ChangeImage(files);
4708}
4709});
4710if (self.ActualFile != false) {
4711self.ShowFile(self.ActualFile);
4712}
4713function ChangeImage(files)
4714{
4715if (files.length == 1 && files[0].type.substr(0, 5) == 'image') {
4716if (window.URL != undefined) {
4717let img = g.NewElementFromHTML('<img src="' + window.URL.createObjectURL(files[0]) + '" />');
4718img.e.on('load', function(){
4719self.OnImageDisplay();
4720});
4721let box = g.children('.ImageBox.Hidden').clone();
4722box.class.remove('Hidden');
4723box.children('.Image').SetHTML(img);
4724g.children('.Files').SetHTML(box);
4725}
4726}
4727let box = g.children('.ImageBox.Hidden').clone();
4728box.class.remove('Hidden');
4729box.children('.Image').SetHTML('<div class="UploadingFile"><div class="' + g.attr.get('id') + 'Progress Progress"><div class="' + g.attr.get('id') + 'Meter Meter"></div><div class="' + g.attr.get('id') + 'Percents Percents"></div></div></div>');
4730g.children('.Files').append(box);
4731self.OnSelect(files);
4732self.State = 'uploading';
4733self.Pasting.ProgressInfoG = self.ShowProgress ? g.children('.ProgressInfo') : null;
4734self.Pasting.Ajax.SuccessFnc = function(data) {
4735self.UploadFinished(data);
4736};
4737}
4738this.SetDeleteEvents();
4739};
4740GraceWeb.prototype.FileUpload.prototype.SetDeleteEvents = function()
4741{
4742let self = this;
4743this.G.children('.Delete').e.click(function(el) {
4744self.DeleteFile(el.parent('.File'));
4745});
4746}
4747GraceWeb.prototype.FileUpload.prototype.ShowFile = function(file)
4748{
4749let g = this.G;
4750if ((file.type && file.type.substr(0, 5) == 'image') || /\.(jpg|jpeg|png|webp|gif|ico)/.test(file.file)) {
4751let img = g.NewElementFromHTML('<img src="' + webroot + file.file + '" />');
4752img.e.on('load', function(){
4753self.OnImageDisplay();
4754});
4755let box = g.children('.ImageBox.Hidden').clone();
4756box.class.remove('Hidden');
4757box.children('.Image').SetHTML(img);
4758g.children('.Files').SetHTML(box);
4759} else if (typeof(file) == 'string' && /\.(png|jpg|webp|jpeg|gif|ico)/.test(file) && g.children('.Files img').Select(0)) {
4760g.children('.Files img').Select(0).attr.set('src', file);
4761}
4762g.children('.Id').attr.set('value', file.id);
4763};
4764GraceWeb.prototype.FileUpload.prototype.DeleteFile = function(el)
4765{
4766let id = el.data.get('id');
4767let input = this.G.children('.Id');
4768let value = input.attr.get('value') ? input.attr.get('value') : '';
4769let values = value.split('|');
4770let deleted = false;
4771for (let i in values) {
4772let val = values[i];
4773if (val == id) {
4774deleted = true;
4775delete values[i];
4776}
4777}
4778if (deleted) {
4779value = values.join('|');
4780value = value.replace('||', '|');
4781input.attr.set('value', value);
4782input.e.trigger('change');
4783}
4784el.remove();
4785}
4786GraceWeb.prototype.FileUpload.prototype.UploadFinished = function(data)
4787{
4788if (data.error) {
4789this.DisplayErrors(data.error);
4790return;
4791}
4792let g = this.G;
4793g.data.set('status', 'uploaded');
4794let ides = [];
4795let paths = [];
4796for (let id in data) {
4797if (!paths.length) {
4798this.ShowFile(filesroot + data[id]);
4799}
4800ides.push(id);
4801paths.push(data[id]);
4802}
4803if (this.UploadingFiles.length == 1 && this.UploadingFiles[0].type.substr(0, 5) == 'video') {
4804let img = g.NewElementFromHTML('<video src="' + webroot + paths[0] + '" controls="controls" />');
4805let box = g.children('.ImageBox.Hidden').clone();
4806box.class.remove('Hidden');
4807box.children('.Image').SetHTML(img);
4808g.children('.Files').SetHTML(box);
4809}
4810g.children('.Id, .FileUploadIdValue').attr.set('value', ides.join('|'));
4811self.State = 'uploaded';
4812GraceW.children('.' + g.attr.get('id') + 'Progress').class.add('Hidden');
4813this.OnUploaded(data);
4814};
4815GraceWeb.prototype.FileUpload.prototype.DisplayErrors = function(error_str)
4816{
4817let g = this.G;
4818let err = g.children('.Error').SelectLast().clone();
4819err.class.remove('Hidden');
4820err.SetHTML(error_str);
4821g.children('.Error').SelectLast().AddAfter(err);
4822};
4823GraceWeb.prototype.Form = function(g) {
4824let self = this;
4825this.Form = g;
4826this.InvalidClass = 'Invalid';
4827this.ParentInvalidSelector = '.Item';
4828this.ProcessSubmit = true;
4829this.SubmittedAndValidated = function() {};
4830this.Saved;
4831this.OnSavingError;
4832this.ValidateFunction = function() {};
4833this.SendAjax = true;
4834this.Ajax;
4835this.AjaxAdditionalData = {};
4836this.ReturnOnSubmit = false;
4837this.Disabled = false;
4838this.Init = function() {
4839this.SetEvents();
4840this.Ajax = this.Form.f('Ajax');
4841this.Ajax.Method = 'Save';
4842};
4843this.SetEvents = function() {
4844self.Form.e.on('submit', function() {
4845if (self.Disabled) return false;
4846if (!self.ProcessSubmit) return true;
4847let result = self.Submitted();
4848if (!result) return false;
4849result = self.SubmittedAndValidated(self.Form);
4850if (result === false) return false;
4851self.Form.e.trigger('valid-submit');
4852return self.ReturnOnSubmit;
4853});
4854};
4855this.Submitted = function() {
4856this.Form.children('.' + this.InvalidClass).class.remove(this.InvalidClass);
4857if (!self.IsValid()) {
4858self.MarkInvalidInputs();
4859self.GoToFirstErrorInput();
4860if (debug) {
4861console.error('Form\'s invalid', this.GetErrors());
4862}
4863return false;
4864}
4865if (this.SendAjax) {
4866if (self.Form.attr.get('method').toLowerCase() == 'get') {
4867this.Ajax.Link = self.GetLinkWithValues();
4868} else {
4869this.Ajax.Data = this.GetValues(true);
4870}
4871for (let i in self.AjaxAdditionalData) {
4872this.Ajax.Data[i] = self.AjaxAdditionalData[i];
4873}
4874this.Ajax.ErrorFnc = function(d) {
4875d = JSON.parse(d);
4876if (self.OnSavingError) self.OnSavingError(d);
4877if (d.errors) {
4878let errors = {};
4879let first = true;
4880for (let i in d.errors) {
4881let input = self.Form.children('[name="' + i + '"]');
4882if (first) {
4883input.e.focus();
4884first = false;
4885}
4886errors[i] = {input: input, msg: d.errors[i], name: i};
4887}
4888self.MarkInvalidInputs(errors);
4889} else if (d.text) {
4890alert(d.text);
4891}
4892};
4893if (self.Saved) self.Saved(self.Form);
4894this.Ajax.Send();
4895}
4896return true;
4897};
4898this.GetLinkWithValues = function()
4899{
4900let link = {};
4901let params_exist = false;
4902let current_link = self.Form.attr.get('action');
4903if (!current_link) current_link = location.href;
4904let params = location.href.split('?');
4905if (params[1]) {
4906let p = params[1].split('&');
4907for (i in p) {
4908let l = p[i].split('=');
4909link[l[0]] = l[1];
4910params_exist = true;
4911}
4912}
4913current_link = current_link.split('?')[0];
4914let data = self.GetValues(true);
4915for (let k in data) {
4916let val = data[k].trim();
4917if (!val) {
4918if (link[k]) delete link[k];
4919continue;
4920}
4921link[k] = encodeURI(val);
4922params_exist = true;
4923}
4924if (!params_exist) return current_link;
4925let first = true;
4926for (let i in link) {
4927current_link += first ? '?' : '&';
4928first = false;
4929current_link += i + '=' + link[i];
4930}
4931return current_link;
4932};
4933this.GetValues = function(simplify, emptyselect_to_null) {
4934let no_value_braces = {};
4935let data = {};
4936let inputs = g.children('[name]');
4937for (let i = 0; i < inputs.Count(); i++) {
4938let input = inputs.Select(i);
4939if ((input.attr.get('type') == 'checkbox' && !input.dom(0).checked) || (input.attr.get('type') == 'radio' && !input.dom(0).checked)) continue;
4940let value = input.attr.get('value');
4941if (value == undefined) continue;
4942if (emptyselect_to_null) {
4943if (!value && input.dom(0).tagName == 'SELECT') value = 'NULL';
4944}
4945if (simplify) {
4946let name = input.attr.get('name');
4947if (/\[\]/.test(name)) {
4948let ord = no_value_braces[name];
4949if (ord == undefined) {
4950no_value_braces[name] = ord = 0;
4951}
4952no_value_braces[name]++;
4953name = name.replace('[]', '[' + ord + ']');
4954}
4955data[name] = value;
4956} else {
4957let n = input.attr.get('name').split('[');
4958let name_str = 'data[\'' + n[0] + '\']';
4959for(let j = 1; j < n.length; j++) {
4960eval('if(' + name_str + ' == undefined) ' + name_str + ' = {};');
4961name_str += '[\'' + n[j].replace(']', '') + '\']';
4962}
4963eval(name_str + ' = \'' + value.replace(/[\r\n]/m, '--:::::::--') + '\'.replace(/--:::::::--/m, "\\r\\n")');
4964}
4965}
4966return data;
4967};
4968this.GetErrors = function() {
4969let errors = [];
4970self.Form.children('[name]').each(function(input) {
4971let methods = input.data.get('valid');
4972if (!methods) methods = '';
4973methods = methods.trim().split('|');
4974let value = '';
4975if (input.GetTagName() == 'input' && ['radio', 'checkbox'].indexOf(input.attr.get('type')) > -1) {
4976value = self.Form.children('[name="' + input.attr.get('name') + '"]:checked').attr.get('value');
4977} else {
4978value = input.attr.get('value');
4979}
4980if (value) value = value.trim();
4981let valid = true;
4982for (let m in methods) {
4983if (!valid) break;
4984m = methods[m];
4985switch (m) {
4986case 'required':
4987if (!value) {
4988errors.push({input: input, name: input.attr.get('name'), type: VALID_EMPTY});
4989valid = false;
4990}
4991break;
4992case 'number':
4993if (value && !IsValidNumber(value)) {
4994errors.push({input: input, name: input.attr.get('name'), type: VALID_NUMBER});
4995valid = false;
4996}
4997break;
4998case 'email':
4999if (value && !IsValidEmail(value)) {
5000errors.push({input: input, name: input.attr.get('name'), type: VALID_EMAIL});
5001valid = false;
5002}
5003break;
5004}
5005}
5006if (value && value.length && valid && input.data.get('valid-min-chars')) {
5007let min = parseInt(input.data.get('valid-min-chars'));
5008if (value.length < min) {
5009errors.push({input: input, name: input.attr.get('name'), type: VALID_SHORT});
5010valid = false;
5011}
5012}
5013if (value && value.length && valid && input.data.get('valid-min')) {
5014let min = parseInt(input.data.get('valid-min'));
5015let v = parseFloat(value);
5016if (v < min) {
5017errors.push({input: input, name: input.attr.get('name'), type: VALID_SMALL});
5018valid = false;
5019}
5020}
5021if (value && value.length && valid && input.data.get('valid-max')) {
5022let min = parseInt(input.data.get('valid-max'));
5023let v = parseFloat(value);
5024if (v > min) {
5025errors.push({input: input, name: input.attr.get('name'), type: VALID_BIG});
5026valid = false;
5027}
5028}
5029if (value && value.length && valid && input.data.get('pwd')) {
5030let pwds = self.Form.children('[name][data-pwd]');
5031let str = null;
5032let match = true;
5033pwds.each(function (input) {
5034let v = input.attr.get('value');
5035if (str == null) {
5036str = v;
5037return;
5038}
5039if (v != str) {
5040match = false;
5041}
5042});
5043if (!match) {
5044pwds.each(function(input) {
5045errors.push({input: input, name: input.attr.get('name'), type: input.data.get('pwd') == '1' ? VALID_PWD_DUPLI : null});
5046});
5047valid = false;
5048}
5049}
5050if (value && value.length && valid && self.ValidateFunction) {
5051let res = self.ValidateFunction(input);
5052if (res === false) {
5053errors.push({input: input, name: input.attr.get('name')});
5054valid = false;
5055}
5056}
5057});
5058return errors;
5059};
5060this.GoToFirstErrorInput = function() {
5061let el = g.children('.Invalid').Select(0);
5062if (!el) return;
5063el.children('[name]').e.focus();
5064};
5065this.Init();
5066};
5067GraceWeb.prototype.Form.prototype.IsValid = function() {
5068return !this.GetErrors().length;
5069};
5070GraceWeb.prototype.Form.prototype.MarkInvalidInputs = function(errors)
5071{
5072if (errors == undefined) errors = this.GetErrors();
5073for (let i in errors) {
5074let input = errors[i].input;
5075if (input.parent(this.ParentInvalidSelector)) {
5076input.parent(this.ParentInvalidSelector).class.add(this.InvalidClass);
5077}
5078}
5079};
5080GraceWeb.prototype.Input = function(g) {
5081var self = this;
5082this.GraceWeb = g;
5083this.SetValue = function(value) {
5084g.attr.set('value', value);
5085}
5086this.GetValue = function(value) {
5087return g.attr.get('value');
5088}
5089this.SetName = function(name) {
5090g.attr.set('name', name);
5091}
5092this.GetName = function(name) {
5093return g.attr.get('name');
5094}
5095this.GetAttribute = function(name) {
5096return g.attr.get(name);
5097}
5098};
5099GraceWeb.prototype.TextInput = GraceWeb.prototype.Input;
5100function Random(min, max, round)
5101{
5102if (min == undefined) min = 0;
5103if (max == undefined) max = 100;
5104if (min < 0 && max < 0) {
5105line = (max * -1 - min * -1) * -1;
5106} else if (min < 0) {
5107line = min * -1 + max;
5108} else { // both unsigned
5109line = max - min;
5110}
5111rand = Math.random();
5112if (round) {
5113rand *= 100;
5114return Math.round(min + ((line / 100) * rand));
5115} else {
5116return min + (line * rand);
5117}
5118}
5119function SHA1(msg){
5120function rotate_left(n,s) {
5121var t4 = ( n<<s ) | (n>>>(32-s));
5122return t4;
5123};
5124function lsb_hex(val) {
5125var str="";
5126var i;
5127var vh;
5128var vl;
5129for( i=0; i<=6; i+=2 ) {
5130vh = (val>>>(i*4+4))&0x0f;
5131vl = (val>>>(i*4))&0x0f;
5132str += vh.toString(16) + vl.toString(16);
5133}
5134return str;
5135};
5136function cvt_hex(val) {
5137var str="";
5138var i;
5139var v;
5140for( i=7; i>=0; i-- ) {
5141v = (val>>>(i*4))&0x0f;
5142str += v.toString(16);
5143}
5144return str;
5145};
5146function Utf8Encode(string) {
5147string = string.replace(/\r\n/g,"\n");
5148var utftext = "";
5149for (var n = 0; n < string.length; n++) {
5150var c = string.charCodeAt(n);
5151if (c < 128) {
5152utftext += String.fromCharCode(c);
5153}
5154else if((c > 127) && (c < 2048)) {
5155utftext += String.fromCharCode((c >> 6) | 192);
5156utftext += String.fromCharCode((c & 63) | 128);
5157}
5158else {
5159utftext += String.fromCharCode((c >> 12) | 224);
5160utftext += String.fromCharCode(((c >> 6) & 63) | 128);
5161utftext += String.fromCharCode((c & 63) | 128);
5162}
5163}
5164return utftext;
5165};
5166var blockstart;
5167var i, j;
5168var W = new Array(80);
5169var H0 = 0x67452301;
5170var H1 = 0xEFCDAB89;
5171var H2 = 0x98BADCFE;
5172var H3 = 0x10325476;
5173var H4 = 0xC3D2E1F0;
5174var A, B, C, D, E;
5175var temp;
5176msg = Utf8Encode(msg);
5177var msg_len = msg.length;
5178var word_array = new Array();
5179for( i=0; i<msg_len-3; i+=4 ) {
5180j = msg.charCodeAt(i)<<24 | msg.charCodeAt(i+1)<<16 |
5181msg.charCodeAt(i+2)<<8 | msg.charCodeAt(i+3);
5182word_array.push( j );
5183}
5184switch( msg_len % 4 ) {
5185case 0:
5186i = 0x080000000;
5187break;
5188case 1:
5189i = msg.charCodeAt(msg_len-1)<<24 | 0x0800000;
5190break;
5191case 2:
5192i = msg.charCodeAt(msg_len-2)<<24 | msg.charCodeAt(msg_len-1)<<16 | 0x08000;
5193break;
5194case 3:
5195i = msg.charCodeAt(msg_len-3)<<24 | msg.charCodeAt(msg_len-2)<<16 | msg.charCodeAt(msg_len-1)<<8| 0x80;
5196break;
5197}
5198word_array.push( i );
5199while( (word_array.length % 16) != 14 ) word_array.push( 0 );
5200word_array.push( msg_len>>>29 );
5201word_array.push((msg_len<<3)&0x0ffffffff);
5202for ( blockstart=0; blockstart<word_array.length; blockstart+=16 )
5203{
5204for(i = 0; i < 16; i++) W[i] = word_array[blockstart+i];
5205for(i = 16; i <= 79; i++) W[i] = rotate_left(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
5206A = H0;
5207B = H1;
5208C = H2;
5209D = H3;
5210E = H4;
5211for(i = 0; i <= 19; i++)
5212{
5213temp = (rotate_left(A,5) + ((B&C) | (~B&D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
5214E = D;
5215D = C;
5216C = rotate_left(B, 30);
5217B = A;
5218A = temp;
5219}
5220for(i = 20; i <= 39; i++)
5221{
5222temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
5223E = D;
5224D = C;
5225C = rotate_left(B,30);
5226B = A;
5227A = temp;
5228}
5229for(i = 40; i <= 59; i++)
5230{
5231temp = (rotate_left(A,5) + ((B&C) | (B&D) | (C&D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
5232E = D;
5233D = C;
5234C = rotate_left(B,30);
5235B = A;
5236A = temp;
5237}
5238for(i = 60; i <= 79; i++)
5239{
5240temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
5241E = D;
5242D = C;
5243C = rotate_left(B,30);
5244B = A;
5245A = temp;
5246}
5247H0 = (H0 + A) & 0x0ffffffff;
5248H1 = (H1 + B) & 0x0ffffffff;
5249H2 = (H2 + C) & 0x0ffffffff;
5250H3 = (H3 + D) & 0x0ffffffff;
5251H4 = (H4 + E) & 0x0ffffffff;
5252}
5253var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
5254return temp.toLowerCase();
5255}
5256GraceWeb.prototype.GEditor = function(el) {
5257var self = this;
5258this.Element = el;
5259this.ControlsElement;
5260this.BlockContent = true;
5261this.EditorDivClass = 'TextContent';
5262var actual_node;
5263this.Dragged;
5264this.Pasting;
5265var blocks = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div', 'ul', 'ol', 'li', 'table', 'td', 'tr', 'thead', 'tbody', 'tfoot', 'th'];
5266this.Blocks = blocks;
5267var allowed_tags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div', 'ol', 'ul', 'li', 'table', 'td', 'tr', 'thead', 'tbody', 'tfoot', 'th', 'strong', 'a', 'em', 'b', 'u', 'i', 'img', 'br', 'iframe'];
5268//var allowed_classes = ['Image', 'MediaItem', 'MediaGallery', 'MediaLeft', 'MediaRight', 'MediaRow', 'ImageLeft', 'ImageRight', 'NewWindow', 'EmbedLink', 'YouTube', 'Instagram', 'Vimeo', 'Youtube', 'Instagram', 'Twitter', 'EmbedIn', 'Website', 'GrabbedWebsite', 'GrabbedProduct', 'WebName', 'Price', 'Frame', 'Button'];
5269var allowed_attributes = ['src', 'title', 'alt', 'class', 'id', 'data-link', 'href', 'data-image', 'data-vimeo-code', 'data-youtube-code', 'poster', 'controls', 'data-link', 'rel'];
5270var change_tags = {'b': 'strong', 'i': 'em'};
5271let allow_empty = ['iframe'];
5272this.Init = function()
5273{
5274BuildEditor();
5275this.InitialLoad();
5276let icons = self.Element.children('.Icon');
5277icons.e.on('mousedown', ControlButtonClicked);
5278this.Element.dom(0).addEventListener('mouseup', this.ReadSelection);
5279this.Element.dom(0).addEventListener('keydown', this.PrepareShortcut);
5280this.Element.dom(0).addEventListener('keyup', this.ReadSelection);
5281this.Element.dom(0).querySelector('.' + self.EditorDivClass).addEventListener('mouseup', this.Save);
5282this.Element.dom(0).querySelector('.' + self.EditorDivClass).addEventListener('keyup', this.Save);
5283this.Element.dom(0).querySelector('.HTMLcode').addEventListener('mouseup', this.LoadFromHTML);
5284this.Element.dom(0).querySelector('.HTMLcode').addEventListener('keyup', this.LoadFromHTML);
5285this.Element.dom(0).querySelector('.HTMLcode').addEventListener('paste', function(e) {
5286e.preventDefault();
5287// get text representation of clipboard
5288var text = (e.originalEvent || e).clipboardData.getData('text/plain');
5289// insert text manually
5290document.execCommand("insertHTML", false, text);
5291self.LoadFromHTML();
5292self.Element.children('.' + self.EditorDivClass + ' .EmbedLink[data-link]').each(function(el) {
5293let iframe = el.f('EmbedLink').BuildEmbed(el.data.get('link'), true);
5294el.append(iframe);
5295});
5296self.Save();
5297});
5298this.Pasting = this.Element.children('.' + self.EditorDivClass).f('ObjectsPasting');
5299this.Element.children('.' + self.EditorDivClass).e.on(['dragover'], function(el, e) {
5300let res = self.PastingCheck(e);
5301return res;
5302if (GetBrowserName() == 'Safari') return false;
5303return res;
5304});
5305this.Element.children('.' + self.EditorDivClass).e.on(['paste', 'drop'], function(el, e) {
5306self.Pasting.ChangeFocusOnDragover = true;
5307if (self.Pasting.GetByType('geditorhtml')) {
5308self.PastedByInsideMove();
5309GraceW.children('.GEditor .Pasting').remove();
5310return false;
5311}
5312if (self.Pasting.GetByType('savedfile')) {
5313let data = JSON.parse(self.Pasting.GetByType('savedfile'));
5314let path = data.file;
5315let div = el.children('.Pasting').Select(0);
5316let pasting_el = el.children('.Pasting').Select(0);
5317if (div.parent('.MediaRow')) {
5318div = g.NewElementFromHTML('<div class="MediaItem"></div>');
5319pasting_el.AddAfter(div);
5320} else {
5321div = g.NewElementFromHTML('<div class="MediaGallery"><div class="MediaRow"><div class="MediaItem"></div></div></div>');
5322pasting_el.AddAfter(div);
5323div = div.Children('.MediaItem');
5324}
5325pasting_el.remove();
5326let ext = path.split('.').reverse()[0].toLowerCase();
5327switch (ext) {
5328case 'jpg':
5329case 'jpeg':
5330case 'webp':
5331case 'gif':
5332case 'png':
5333case 'ico':
5334div.SetHTML('<img src="' + path + '" />');
5335div.class.add('Image');
5336break;
5337case 'mp4':
5338div.SetHTML('<video src="' + path + '"></video>');
5339div.class.add('Video');
5340break;
5341}
5342self.ContentEvents();
5343self.Save();
5344}
5345if (self.Pasting.GetText()) {
5346self.PastedContent();
5347} else if (self.Pasting.HasFiles()) {
5348for (let i = 0; i < self.Pasting.GetFiles().length; i++) {
5349let file = self.Pasting.GetFiles()[i];
5350let paste_el = self.GetPastingEl();
5351if (!paste_el) {
5352let t = new GraceWeb(e.target);
5353}
5354let progress_div = '<div class="ProgressInfo"><div class="Uploading"><div class="Bars"><div class="Bar"></div><div class="Bar"></div><div class="Bar"></div><div class="Bar"></div><div class="Bar"></div></div><span class="Percents">0%</span></div><div class="Processing Hidden">Processing...</div></div>';
5355paste_el.SetHTML(progress_div);
5356paste_el.class.add('WaitingForContent');
5357paste_el.class.add('MediaItem');
5358paste_el.class.remove('Pasting');
5359paste_el.data.set('file', file.name);
5360paste_el.css.remove('height');
5361let mg = paste_el.parent('.MediaGallery');
5362let mr = paste_el.parent('.MediaRow');
5363if (!mg) {
5364mg = g.NewElementFromHTML('<div class="MediaGallery"><div class="MediaRow"></div></div>');
5365if (paste_el.class.has('MediaLeft')) mg.class.add('MediaLeft');
5366if (paste_el.class.has('MediaRight')) mg.class.add('MediaRight');
5367paste_el.class.remove('MediaLeft');
5368paste_el.class.remove('MediaRight');
5369mg = paste_el.AddAfter(mg);
5370mg.children('.MediaRow').append(paste_el);
5371} else if (!mr) {
5372mr = g.NewElementFromHTML('<div class="MediaRow"></div>');
5373mr = paste_el.AddAfter(mr);
5374mr.append(paste_el);
5375}
5376mg.children('[style]').attr.remove('style');
5377}
5378self.Pasting.Ajax.SuccessFnc = function(data) {
5379for (let id in data) {
5380let path = filesroot + data[id];
5381let div = el.children('.WaitingForContent').Select(0);
5382div.class.remove('WaitingForContent');
5383let ext = path.split('.').reverse()[0].toLowerCase();
5384switch (ext) {
5385case 'jpg':
5386case 'jpeg':
5387case 'webp':
5388case 'gif':
5389case 'png':
5390case 'ico':
5391div.SetHTML('<img src="' + path + '" />');
5392div.class.add('Image');
5393break;
5394case 'mp4':
5395div.SetHTML('<video src="' + path + '"></video>');
5396div.class.add('Video');
5397break;
5398}
5399}
5400self.ContentEvents();
5401self.Save();
5402};
5403self.Pasting.ProgressInfoG = el.children('.WaitingForContent .ProgressInfo');
5404self.ContentEvents();
5405GraceW.children('.GEditor .Pasting').remove();
5406}
5407});
5408this.ContentEvents();
5409};
5410this.PastedContent = function(e) {
5411setTimeout(function() {
5412//self.Element.children('.' + self.EditorDivClass).SetHTML(self.Element.children('.' + self.EditorDivClass).GetHTML().replace(/(\<!--[^\>]*\>)/g, ''));
5413//console.log(self.Element.children('.' + self.EditorDivClass + '').GetHTML());
5414console.log('---000---', self.Element.children('.' + self.EditorDivClass).GetHTML());
5415CheckPastedNodes(self.Element.children('.' + self.EditorDivClass + ' > *'));
5416if (GetBrowserName() == 'Firefox') {
5417let children = self.Element.children('.' + self.EditorDivClass).dom(0).childNodes;
5418let children_to_remove = [];
5419for (let i in children) {
5420let child = children[i];
5421if (!child || !child.nodeName) continue;
5422if (child.nodeName == '#comment') {
5423children_to_remove.push(child);
5424}
5425}
5426for (let i in children_to_remove) {
5427children_to_remove[i].remove();
5428}
5429}
5430self.CheckLinks();
5431self.Save();
5432self.ContentEvents();
5433}, 5);
5434};
5435var CheckPastedNodes = function(node) {
5436node.each(function(n) {
5437if (!n.parent('body')) return;
5438if (debug) console.log('000', n.GetOuterHTML());
5439if (change_tags[n.GetTagName()] != undefined) {
5440if (debug) console.log('aaa');
5441if (!n.DirectParent()) return;
5442let tag = GraceW.NewElementFromHTML('<' + change_tags[n.GetTagName()] + '></' + change_tags[n.GetTagName()] + '>');
5443tag.SetHTML(n.GetHTML());
5444n.AddBefore(tag);
5445let nn = n.DirectParent().dom(0);
5446n.remove();
5447nn = new GraceWeb(nn.childNodes);
5448//console.log('--------------', nn.dom());
5449CheckPastedNodes(nn);
5450return false;
5451} else if (n.css.get('font-weight') == 'bold' || n.css.get('font-weight') > 400 || n.css.get('font-style') == 'italic') {
5452if (debug) console.log('bbb');
5453let tag;
5454let tag_to_fill;
5455if ((n.css.get('font-weight') == 'bold' || n.css.get('font-weight') > 400) && n.css.get('font-style') == 'italic') {
5456tag = GraceW.NewElementFromHTML('<strong><em></em></strong>');
5457tag_to_fill = tag.FindFirst('em');
5458} else if (n.css.get('font-weight') == 'bold' || n.css.get('font-weight') > 400) {
5459tag = GraceW.NewElementFromHTML('<strong></strong>');
5460tag_to_fill = tag.FindFirst('strong');
5461} else {
5462tag = GraceW.NewElementFromHTML('<em></em>');
5463tag_to_fill = tag.FindFirst('em');
5464}
5465//tag.SetHTML(n.GetHTML());
5466while (n.dom(0).childNodes.length) {
5467tag_to_fill.dom(0).appendChild(n.dom(0).childNodes[0]);
5468}
5469n.AddBefore(tag);
5470let nn = n.DirectParent().dom(0);
5471n.remove();
5472nn = new GraceWeb(nn.childNodes);
5473//console.log('--------------', nn.dom());
5474CheckPastedNodes(nn);
5475return false;
5476} else if (n.GetTagName() != 'li' && (n.class.has('MsoListParagraphCxSpFirst') || n.class.has('MsoListParagraphCxSpMiddle') || n.class.has('MsoListParagraphCxSpLast') || /mso\-list\:[a-z0-1]+/.test(n.attr.get('style')))) {
5477if (debug) console.log('ccc');
5478let list_span = n.children('span').Select(0);
5479let list_style = (/symbol/.test(list_span.css.get('font-family').toLowerCase()) || list_span.css.get('font-family').toLowerCase() == 'wingdings') ? 'ul' : 'ol';
5480if (list_style == 'ol' || list_style == 'ul') {
5481if (list_span.previous()) {
5482list_span.previous().remove();
5483} else {
5484list_span.remove();
5485}
5486}
5487let li = GraceW.NewElementFromHTML('<ul><li></li></ul>').children('li');
5488li.SetHTML(n.GetHTML());
5489CheckPastedNodes(li);
5490let prevNode = n.previous();
5491if (prevNode) {
5492while (prevNode.dom(0).nodeType != 1) {
5493prevNode = prevNode.previous();
5494}
5495}
5496//console.log(n.dom());
5497if (prevNode && prevNode.GetTagName() == list_style) {
5498prevNode.append(li);
5499} else {
5500let ul = g.NewElementFromHTML('<' + list_style + '></' + list_style + '>');
5501ul.append(li);
5502n.AddBefore(ul);
5503}
5504n.remove();
5505} else if (allowed_tags.indexOf(n.GetTagName()) < 0) {
5506if (debug) console.log('ddd');
5507if (n.GetHTML().trim() && n.GetHTML().trim() != '&nbsp;') {
5508let children;
5509if (n.DirectChildren() && n.DirectChildren().Count()) {
5510if (n.dom(0).parentNode) {
5511for (let i in n.dom(0).childNodes) {
5512let ch = n.dom(0).childNodes[i];
5513if (typeof ch == 'object') {
5514ch = ch.cloneNode(true);
5515n.dom(0).parentNode.insertBefore(ch, n.dom(0));
5516}
5517}
5518}
5519} else if (n.parent('p') || n.parent('li')) {
5520let text = n.dom(0).childNodes[0];
5521//text.textContent += ' ';
5522text.textContent = text.textContent.replace('  ', ' ');
5523n.dom(0).parentNode.insertBefore(text, n.dom(0));
5524} else {
5525children = g.NewElementFromHTML('<p>' + n.GetText() + '</p>');
5526}
5527if (children) {
5528children = children.clone();
5529n.AddBefore(children);
5530}
5531}
5532let nn = n.DirectParent();
5533//console.log('--------', n.GetOuterHTML(), '------------');
5534n.remove();
5535if (nn && !nn.attr.has('contenteditable')) {
5536CheckPastedNodes(nn);
5537} else if (nn) {
5538CheckPastedNodes(nn.DirectChildren());
5539}
5540} else {
5541if (debug) console.log('eee');
5542if (allow_empty.indexOf(n.GetTagName()) < 0 && n.GetTagName() != 'br' && ((n.GetTagName() != 'img' && !n.GetHTML().trim()) || n.GetHTML().trim() == '&nbsp;')) {
5543//if (debug) console.log('aaaaaaaaaaaaaaaaaaaaa');
5544n.remove();
5545} else {
5546let cl = n.class.getList();
5547for (let c in cl) {
5548if (self.AllowedClasses.indexOf(cl[c]) < 0) {
5549n.class.remove(cl[c]);
5550}
5551}
5552cl = n.class.getList();
5553if (!cl || !cl.length) n.attr.remove('class');
5554let list = n.attr.getList();
5555for (let i in list) {
5556if (allowed_attributes.indexOf(i) < 0) {
5557n.attr.remove(i);
5558}
5559}
5560if (n.dom(0).childNodes) {
5561let ch = new GraceWeb(n.dom(0).childNodes);
5562CheckPastedNodes(ch);
5563}
5564}
5565}
5566});
5567};
5568var ControlButtonClicked = function(el, e) {
5569e.preventDefault();
5570e.stopImmediatePropagation();
5571e.stopPropagation();
5572let fnc = el.data.get('fnc');
5573if (fnc) {
5574if (self[fnc]) {
5575eval('self.' + fnc + '(el, self);');
5576} else {
5577eval(fnc + '(el, self);');
5578}
5579} else if (self.IsAnythingSelected()) {
5580let tag = el.data.get('tag').toUpperCase();
5581let cl = el.data.get('class') ? el.data.get('class') : '';
5582tag = CreateStrong(tag);
5583if (cl) tag.className = cl;
5584if (el.class.has('Active')) {
5585self.RemoveStrong(tag);
5586} else {
5587self.PutStrongButton(tag);
5588}
5589self.Save();
5590}
5591return false;
5592};
5593this.RemoveStrong = function(tag)
5594{
5595var range = window.getSelection().getRangeAt(0);
5596var start_offset = range.startOffset;
5597var end_offset = range.endOffset;
5598var start_node = range.startContainer;
5599actual_node = range.startContainer;
5600var end_node = range.endContainer;
5601//var top_node = range.commonAncestorContainer;
5602var top_node = self.Element.children('.' + this.EditorDivClass).dom(0);
5603var tag_name = typeof tag == 'object' ? tag.tagName : tag;
5604tag_name = tag_name.toUpperCase();
5605var class_name = typeof tag == 'object' ? tag.className : '';
5606let start_el;
5607if (start_node.parentNode.tagName == tag_name) {
5608start_el = new GraceWeb(start_node.parentNode);
5609} else {
5610let actual_el = start_node;
5611while (actual_el.parentNode) {
5612if (actual_el.tagName == tag_name) {
5613start_el = new GraceWeb(actual_el);
5614break;
5615}
5616actual_el = actual_el.parentNode;
5617}
5618}
5619let end_el;
5620if (end_node.parentNode.tagName == tag_name) {
5621end_el = new GraceWeb(end_node.parentNode);
5622} else {
5623let actual_el = end_node;
5624while (actual_el.parentNode) {
5625if (actual_el.tagName == tag_name) {
5626end_el = new GraceWeb(actual_el);
5627break;
5628}
5629actual_el = actual_el.parentNode;
5630}
5631}
5632let top_el = new GraceWeb(top_node.nodeType == 3 ? (top_node.parentNode.tagName == tag_name ? top_node.parentNode.parentNode : top_node.parentNode) : top_node);
5633let removing = false;
5634top_el.children(tag_name).each(function(el) {
5635if (el.dom(0).isSameNode(start_el.dom(0))) removing = true;
5636let remove = removing;
5637if (el.dom(0).isSameNode(end_el.dom(0))) removing = false;
5638if (remove) {
5639let actual_node = el.dom(0);
5640let children = actual_node.childNodes;
5641while (children.length) {
5642if (typeof children[0] != 'object') continue;
5643actual_node.parentNode.insertBefore(children[0], actual_node);
5644}
5645actual_node.remove();
5646}
5647});
5648if (start_node.isSameNode(end_node)) {
5649end_offset -= start_offset;
5650}
5651self.PutStrong(typeof tag == 'object' ? tag.cloneNode() : tag, start_node, start_node, 0, start_offset);
5652self.PutStrong(typeof tag == 'object' ? tag.cloneNode() : tag, end_node, end_node, end_offset, end_node.textContent.length);
5653};
5654this.PutStrongButton = function(tag)
5655{
5656var range = window.getSelection().getRangeAt(0);
5657var start_offset = range.startOffset;
5658var end_offset = range.endOffset;
5659var start_node = range.startContainer;
5660actual_node = range.startContainer;
5661var end_node = range.endContainer;
5662var top_node = range.commonAncestorContainer;
5663if (blocks.indexOf((typeof tag == 'object' ? tag.tagName : tag).toLowerCase()) < 0) {
5664this.PutStrong(tag, start_node, end_node, start_offset, end_offset);
5665} else {
5666this.ChangeBlock(tag, start_node);
5667}
5668};
5669this.ChangeBlock = function(tag, node)
5670{
5671while (node != null && node.contentEditable != 'true' && blocks.indexOf(node.nodeName.toLowerCase()) < 0) {
5672node = node.parentNode;
5673}
5674if (!node || node.contentEditable == 'true') return;
5675var el = CreateStrong(tag);
5676for (var index = node.attributes.length - 1; index >= 0; --index) {
5677el.attributes.setNamedItem(node.attributes[index].cloneNode());
5678}
5679if (typeof tag == 'object' && !tag.className) el.removeAttribute('class');
5680while (node.childNodes[0] != null) {
5681el.appendChild(node.childNodes[0]);
5682}
5683node.parentNode.insertBefore(el, node);
5684node.parentNode.removeChild(node);
5685return el;
5686};
5687this.PutStrong = function(tag, start_node, end_node, start_offset, end_offset)
5688{
5689actual_node = start_node;
5690//console.log(range);
5691if (start_node.isSameNode(end_node)) {
5692self.GiveStrongToSame(tag, start_node, start_offset, end_offset);
5693} else {
5694var both_under_same = false;
5695var sn = start_node;
5696var en = end_node;
5697if (self.HasTagParent(sn, tag) && self.HasTagParent(en, tag)) {
5698while (sn.nodeName != (typeof tag == 'object' ? tag.tagName : tag)) {
5699sn = sn.parentNode;
5700}
5701while (en.nodeName != (typeof tag == 'object' ? tag.tagName : tag)) {
5702en = en.parentNode;
5703}
5704both_under_same = sn.isSameNode(en);
5705}
5706if (!both_under_same) {
5707var strong = self.GiveStrong(tag, start_node, end_node, start_offset, end_offset);
5708if (strong != null) {
5709var stext = document.createTextNode(end_node.textContent.substr(0, end_offset));
5710var etext = document.createTextNode(end_node.textContent.substr(end_offset));
5711strong.appendChild(stext);
5712var parent = actual_node.parentNode.cloneNode(true);
5713var children = actual_node.parentNode.childNodes;
5714parent.innerHTML = '';
5715for (var i in children) {
5716if ((typeof children[i]) != 'object') continue;
5717if (children[i].isSameNode(end_node)) {
5718parent.appendChild(strong);
5719parent.appendChild(etext);
5720} else {
5721parent.appendChild(children[i].cloneNode(true));
5722}
5723}
5724actual_node.parentNode.innerHTML = parent.innerHTML;
5725}
5726}
5727}
5728};
5729this.IsAnythingSelected = function()
5730{
5731return window.getSelection().rangeCount > 0;
5732};
5733let shortcut_landed = false;
5734this.PrepareShortcut = function(e) {
5735if (e.keyCode == 9) {
5736let processed = self.CheckListAndIncreaseIndent();
5737if (processed) {
5738e.stopPropagation();
5739e.preventDefault();
5740return false;
5741}
5742}
5743if (e.key == 'Meta') return;
5744if (e.metaKey || e.ctrlKey) {
5745let tag;
5746switch (e.key) {
5747case 'b': tag = 'strong'; break;
5748case 'i': tag = 'em'; break;
5749case 'u': tag = 'u'; break;
5750}
5751if (!tag) return;
5752let btn = self.ControlsElement.children('[data-tag="' + tag + '"]');
5753if (btn.class.has('Active')) {
5754self.RemoveStrong(tag);
5755} else {
5756tag = CreateStrong(tag);
5757self.PutStrongButton(tag);
5758}
5759self.Save();
5760shortcut_landed = e;
5761return false;
5762}
5763};
5764this.ReadSelection = function(e)
5765{
5766if (shortcut_landed) {
5767shortcut_landed = false;
5768return;
5769}
5770if (!self.IsAnythingSelected()) return;
5771var range = window.getSelection().getRangeAt(0);
5772var start_node = range.startContainer;
5773var end_node = range.endContainer;
5774var icons = self.Element.children('.Icon[data-tag]');
5775icons.each(function(icon) {
5776let att = icon.data.get('tag');
5777if (!att) return;
5778let tag = CreateStrong(att.toUpperCase());
5779tag.className = (icon.data.get('class') ? icon.data.get('class') : '');
5780if (self.IsSelectedContained(tag, start_node, end_node)) {
5781icon.class.add('Active');
5782} else {
5783icon.class.remove('Active');
5784}
5785});
5786if (start_node == end_node) {
5787let block = self.GetClosestBlockParent(range.commonAncestorContainer);
5788if (!block || block.getAttribute('contenteditable')) {
5789//let p = CreateStrong('p');
5790} else if (block && block.tagName == 'DIV') {
5791self.ChangeBlock('p', block);
5792}
5793}
5794if (e.code == 'Space') {
5795let start_text = start_node.textContent;
5796let before = start_node.previousSibling;
5797if (!before && start_text) {
5798start_text = start_text.substr(0, range.startOffset);
5799let res = /^\s*([0-9a-z]+)([\.\)]+) /i.exec(start_text);
5800if (res && res[0] == start_text) {
5801start_node.textContent = start_node.textContent.substr(range.startOffset);
5802self.CreateList('ol');
5803} else {
5804res = /^\s*([\-\.]+) /i.exec(start_text);
5805if (res) {
5806start_node.textContent = start_node.textContent.substr(range.startOffset);
5807self.CreateList('ul');
5808}
5809}
5810}
5811}
5812};
5813this.IsSelectedContained = function(tag, start_node, end_node)
5814{
5815var tag_node = (typeof tag == 'object' ? tag.tagName : tag);
5816var class_name = (typeof tag == 'object' ? tag.className : '');
5817var text_node_regexp = /^[\s]*$/ig;
5818var actual = start_node;
5819while (actual != null && actual.contentEditable != 'true') {
5820if (actual.nodeName == tag_node && (actual.className == undefined || (actual.className == class_name))) break;
5821actual = actual.parentNode;
5822}
5823if (!actual) return false;
5824if (actual.nodeName == tag_node) {
5825var ended = false;
5826while (actual != null && !ended) {
5827if (actual.isSameNode(end_node)) ended = true;
5828if (actual.nodeType == 3 && !text_node_regexp.test(actual.textContent)) {
5829var act = actual;
5830while (act.contentEditable != 'true' && act.nodeName != tag_node) {
5831act = act.parentNode;
5832}
5833if (act.nodeName != tag_node) {
5834return false;
5835}
5836}
5837if (actual.childNodes.length > 0) {
5838actual = actual.childNodes[0];
5839} else if (actual.nextSibling != null) {
5840actual = actual.nextSibling;
5841} else {
5842while (actual.nextSibling == null) {
5843actual = actual.parentNode;
5844}
5845actual = actual.nextSibling;
5846}
5847}
5848return true;
5849} else {
5850return false;
5851}
5852};
5853this.GiveStrongToSame = function(tag, el, start_offset, end_offset)
5854{
5855var strong = typeof tag == 'object' ? tag : CreateStrong(tag);
5856var stext = document.createTextNode(el.textContent.substr(0, start_offset));
5857strong.textContent = el.textContent.substr(start_offset, end_offset - start_offset);
5858el.textContent = el.textContent.substr(end_offset);
5859el.parentNode.insertBefore(strong, el);
5860el.parentNode.insertBefore(stext, strong);
5861};
5862this.GiveStrong = function(tag, start_node, end_node, start_offset, end_offset)
5863{
5864var strong = (typeof tag == 'object' ? tag : CreateStrong(tag));
5865actual_node = start_node;
5866if (self.HasTagParent(actual_node, tag)) {
5867while (actual_node.nodeName != tag) {
5868actual_node = actual_node.parentNode;
5869}
5870}
5871//console.log(actual_node.parentNode.cloneNode(true));
5872var prefere_next = false;
5873while (actual_node != null && !actual_node.isSameNode(end_node)) {
5874if (actual_node.nodeName == tag) {
5875if (this.HasEndChild(actual_node, end_node)) {
5876//console.log('strong 1');
5877for (var si = strong.childNodes.length - 1; si >= 0; si--) {
5878if (typeof strong.childNodes[si] != 'object') continue;
5879actual_node.insertBefore(strong.childNodes[si], actual_node.childNodes[0]);
5880}
5881return null;
5882} else {
5883//console.log('strong 2');
5884for (var si = actual_node.childNodes.length - 1; si >= 0; si--) {
5885if (typeof actual_node.childNodes[si] != 'object') continue;
5886strong.insertBefore(actual_node.childNodes[si], strong.childNodes[0]);
5887}
5888actual_node.parentNode.insertBefore(document.createTextNode(''), actual_node);
5889actual_node = actual_node.previousSibling;
5890actual_node.parentNode.removeChild(actual_node.nextSibling);
5891}
5892}
5893if (this.HasEndChild(actual_node, end_node)) {
5894//console.log('has end child');
5895if (strong.innerHTML.length > 0) {
5896actual_node.parentNode.insertBefore(strong, actual_node);
5897strong = CreateStrong(tag);
5898}
5899} else if (actual_node.isSameNode(start_node)) {
5900if (!self.HasTagParent(actual_node, tag)) {
5901//console.log('strong 3');
5902var stext = document.createTextNode(actual_node.textContent.substr(0, start_offset));
5903actual_node.textContent = actual_node.textContent.substr(start_offset);
5904//console.log(actual_node.cloneNode(true), actual_node.previousSibling);
5905actual_node.parentNode.insertBefore(stext, actual_node);
5906actual_node = actual_node.previousSibling;
5907strong.appendChild(actual_node.nextSibling);
5908}
5909} else {
5910if (actual_node.nodeName != 'P') {
5911//console.log('append actual');
5912if (actual_node.previousSibling == null) actual_node.parentNode.insertBefore(document.createTextNode(''), actual_node);
5913actual_node = actual_node.previousSibling;
5914strong.appendChild(actual_node.nextSibling);
5915prefere_next = true;
5916}
5917}
5918if (actual_node.childNodes.length > 0 && !prefere_next) {
5919//console.log('child node');
5920actual_node = actual_node.childNodes[0];
5921} else if (actual_node.nextSibling != null) {
5922//console.log('next node');
5923actual_node = actual_node.nextSibling;
5924} else {
5925//console.log('parent node');
5926var parent = actual_node.parentNode;
5927if (strong.childNodes.length > 0) {
5928parent.appendChild(strong);
5929strong = CreateStrong(tag);
5930}
5931actual_node = parent;
5932while (actual_node.nextSibling == null) {
5933actual_node = actual_node.parentNode;
5934}
5935actual_node = actual_node.nextSibling;
5936}
5937if (prefere_next) prefere_next = false;
5938}
5939return strong;
5940};
5941var CreateStrong = function(tag)
5942{
5943if (typeof tag == 'object') {
5944if (tag.dom) tag = tag.dom(0);
5945tag = tag.cloneNode();
5946tag.innerHTML = '';
5947return tag;
5948}
5949return document.createElement(tag.toLowerCase());
5950};
5951this.HasTagParent = function(n, tag)
5952{
5953if (typeof tag == 'object') tag = tag.nodeName;
5954tag = tag.toUpperCase();
5955while (n != null && !n.isSameNode(this.Element.dom(0))) {
5956if (n.nodeName == tag) return true;
5957n = n.parentNode;
5958}
5959return false;
5960};
5961this.HasEndChild = function(n, en)
5962{
5963breaking:
5964while (n.childNodes.length > 0) {
5965for (var i in n.childNodes) {
5966if ((typeof n.childNodes[i]) != 'object') {
5967break breaking;
5968}
5969if (n.childNodes[i].isSameNode(en)) return true;
5970var r = this.HasEndChild(n.childNodes[i], en);
5971if (r) return true;
5972}
5973}
5974return false;
5975};
5976this.ChangeHTMLView = function()
5977{
5978var btn = self.ControlsElement.children('.Icon.HTML').dom(0).attributes;
5979if (!btn.getNamedItem('data-type')) {
5980var attr = document.createAttribute('data-type');
5981attr.value = '1';
5982btn.setNamedItem(attr);
5983}
5984var txt = self.Element.children('.HTMLcode').dom(0).classList;
5985var cont = self.Element.children('.' + self.EditorDivClass).dom(0).classList;
5986var val = btn.getNamedItem('data-type').value;
5987switch (val) {
5988case '1':
5989val = '2';
5990txt.add('Hidden');
5991break;
5992case '2':
5993val = '3';
5994txt.remove('Hidden');
5995cont.add('Hidden');
5996break;
5997case '3':
5998val = '1';
5999txt.remove('Hidden');
6000cont.remove('Hidden');
6001break;
6002}
6003btn.getNamedItem('data-type').value = val;
6004};
6005this.GetClosestBlockParent = function(node)
6006{
6007while (node != null && node.contentEditable != 'true' && blocks.indexOf(node.nodeName.toLowerCase()) < 0) {
6008node = node.parentNode;
6009}
6010return node;
6011};
6012this.CreateTable = function()
6013{
6014var table = CreateStrong('table');
6015var tbody = CreateStrong('tbody');
6016var tr = CreateStrong('tr');
6017var td = CreateStrong('td');
6018tr.appendChild(td.cloneNode());
6019tr.appendChild(td.cloneNode());
6020tbody.appendChild(tr);
6021table.appendChild(tbody);
6022if (self.IsAnythingSelected()) {
6023var range = window.getSelection().getRangeAt(0);
6024var node = range.startContainer;
6025node = self.GetClosestBlockParent(node);
6026} else {
6027var node = self.Element.children('.' + self.EditorDivClass).dom(0);
6028}
6029if (node.classList.contains(self.EditorDivClass)) {
6030node.appendChild(table);
6031} else {
6032node.parentNode.insertBefore(table, node);
6033}
6034self.Save();
6035};
6036this.CreateLink = function()
6037{
6038var range = window.getSelection().getRangeAt(0);
6039var start_offset = range.startOffset;
6040var end_offset = range.endOffset;
6041var start_node = range.startContainer;
6042actual_node = range.startContainer;
6043var end_node = range.endContainer;
6044var top_node = range.commonAncestorContainer;
6045var title = '';
6046var href = '';
6047var target = '';
6048let no_track = 0;
6049let rel = '';
6050let add_class = '';
6051if (self.HasTagParent(actual_node, 'a')) {
6052while (actual_node.nodeName != 'A') {
6053actual_node = actual_node.parentNode;
6054}
6055title = actual_node.title;
6056href = actual_node.href;
6057target = actual_node.classList.contains('NewWindow') ? 'NewWindow' : '';
6058if (actual_node.classList.contains('NoTracking')) no_track = 1;
6059if (actual_node.classList.contains('Button')) add_class = 'Button';
6060if (actual_node.rel) rel = actual_node.rel;
6061} else {
6062target = 'NewWindow';
6063rel = 'follow';
6064}
6065var dialog = self.Element.children('.Dialogs .LinkUpdate').clone(true);
6066dialog.SetHTML('<form method="post" action"">' + dialog.GetHTML() + '</div>');
6067dialog = dialog.f('Dialog');
6068dialog.TopClass = 'GEditorDialog';
6069dialog.Open();
6070let title_input = dialog.DialogElement.children('[name="title"]');
6071let target_input = dialog.DialogElement.children('[name="target"]');
6072let rel_input = dialog.DialogElement.children('[name="rel"]');
6073let no_track_input = dialog.DialogElement.children('[name="no_track"]');
6074let add_class_input = dialog.DialogElement.children('[name="add_class"]');
6075let target_is_select = target_input.GetTagName() == 'select';
6076title_input.attr.set('value', title);
6077if (target_is_select) {
6078target_input.attr.set('value', target);
6079} else {
6080target_input.each(function(input) {
6081if (input.attr.get('value') == target) input.attr.set('checked', true);
6082});
6083}
6084rel_input.each(function(input) {
6085if (input.attr.get('value') == rel) input.attr.set('checked', true);
6086});
6087no_track_input.each(function(input) {
6088if (input.attr.get('value') == no_track) input.attr.set('checked', true);
6089});
6090add_class_input.each(function(input) {
6091if (input.attr.get('value') == add_class) input.attr.set('checked', true);
6092});
6093dialog.DialogElement.children('[name="link"]').attr.set('value', href);
6094dialog.DialogElement.children('form').e.on('submit', function() {
6095let a = (actual_node.nodeName == 'A') ? actual_node : CreateStrong('a');
6096a.href = dialog.DialogElement.children('[type="text"]').attr.get('value');
6097let target_value;
6098if (target_is_select) {
6099target_value = target_input.attr.get('value');
6100} else {
6101target_input.each(function(input) {
6102if (input.attr.get('checked')) {
6103target_value = input.attr.get('value');
6104return false;
6105}
6106});
6107}
6108let rel_value = '';
6109rel_input.each(function(input) {
6110if (input.attr.get('checked')) {
6111rel_value = input.attr.get('value');
6112return false;
6113}
6114});
6115let no_track_value = '';
6116no_track_input.each(function(input) {
6117if (input.attr.get('checked')) {
6118no_track_value = input.attr.get('value');
6119return false;
6120}
6121});
6122let add_class_value = '';
6123add_class_input.each(function(input) {
6124if (input.attr.get('checked')) {
6125add_class_value = input.attr.get('value');
6126return false;
6127}
6128});
6129if (rel_value) {
6130a.rel = rel_value;
6131} else {
6132a.removeAttribute('rel');
6133}
6134if (no_track_value > 0) {
6135a.classList.add('NoTracking');
6136} else {
6137a.classList.remove('NoTracking');
6138}
6139if (add_class_value) {
6140a.classList.add(add_class_value);
6141} else {
6142a.classList.remove('Button');
6143}
6144if (target_value.length > 0) {
6145a.classList.add(target_value);
6146} else {
6147a.classList.remove('NewWindow');
6148}
6149let title_value = dialog.DialogElement.children('[name="title"]').attr.get('value').trim();
6150if (title_value.length > 0) a.title = title_value;
6151if (actual_node.nodeName != 'A') {
6152self.PutStrong(a, start_node, end_node, start_offset, end_offset);
6153}
6154dialog.Close();
6155self.Save();
6156return false;
6157});
6158self.Element.e.trigger('link-update-opened');
6159};
6160this.CreateListFromButton = function(btn)
6161{
6162let tag = btn.data.get('tag');
6163let range = window.getSelection().getRangeAt(0);
6164let node = new GraceWeb(this.GetClosestBlockParent(range.startContainer));
6165if (node.GetTagName() == 'li') {
6166let list = node.parent('ol, ul');
6167if (list.GetTagName() == tag) {
6168this.RemoveList(list);
6169} else {
6170this.ChangeBlock(tag, list.dom(0));
6171}
6172this.Save();
6173} else {
6174this.CreateList(tag);
6175this.Save();
6176}
6177};
6178this.RemoveList = function(list)
6179{
6180let upper_list = list.parent('ul, ol');
6181let is_upper_list = upper_list && upper_list.Count() > 0;
6182let new_paragraphs;
6183if (!is_upper_list) new_paragraphs = new GraceWeb([]);
6184list.DirectChildren().each(function(li) {
6185if (is_upper_list) {
6186list.AddBefore(li);
6187} else {
6188let p = self.ChangeBlock('p', li.dom(0));
6189new_paragraphs.AddElements(new GraceWeb(p));
6190}
6191});
6192if (new_paragraphs) list.AddAfter(new_paragraphs);
6193list.remove();
6194};
6195this.CreateList = function(tag)
6196{
6197var range = window.getSelection().getRangeAt(0);
6198var start_node = range.startContainer;
6199actual_node = range.startContainer;
6200var ul = CreateStrong(typeof tag == 'object' ? tag.data.get('tag') : tag);
6201if (typeof tag == 'object' && tag.data.get('class')) ul.className = tag.data.get('class');
6202var li = CreateStrong('li');
6203let block = new GraceWeb(self.GetClosestBlockParent(start_node));
6204if (block.GetTagName() == 'li') {
6205block.append(new GraceWeb(ul));
6206} else {
6207if (block.attr.get('contenteditable')) {
6208start_node.appendChild(li);
6209} else {
6210li = self.ChangeBlock(li, block.dom(0));
6211//li = self.GetClosestBlockParent(start_node);
6212}
6213li.parentNode.insertBefore(ul, li);
6214}
6215ul.appendChild(li);
6216};
6217this.OpenFilemanagerDialog = function() {
6218let fm = self.Element.children('.Dialogs .FilemanagerDialog').clone();
6219let dialog = fm.f('Dialog');
6220dialog.TopClass = 'GEditorDialog';
6221dialog.Open();
6222fm = GraceW.children('.DialogBox .FilemanagerDialog');
6223fm.e.on(['filemanager-loaded', 'filemanager-files-loaded'], function() {
6224dialog.SetDimensions();
6225});
6226let filemanager = fm.f('Filemanager');
6227filemanager.InitLoad();
6228//filemanager.Init();
6229return fm;
6230};
6231this.InsertFile = function(btn)
6232{
6233var range = window.getSelection().getRangeAt(0);
6234var start_offset = range.startOffset;
6235var end_offset = range.endOffset;
6236var start_node = range.startContainer;
6237actual_node = range.startContainer;
6238var end_node = range.endContainer;
6239var top_node = range.commonAncestorContainer;
6240var fm = self.OpenFilemanagerDialog();
6241var filemanager = fm.f('Filemanager');
6242filemanager.OnFileSelected = function(id, url, orig_name, type) {
6243path = url.split('.');
6244path.reverse();
6245if (type == 'image/jpeg' || type == 'image/png' || type == 'image/gif') {
6246let new_img = g.NewElementFromHTML('<div class="MediaGallery"><div class="MediaRow"><div class="MediaItem Image"><img src="' + webroot + url + '" alt="' + orig_name + '" /></div></div></div>');
6247node = new_img.dom(0);
6248var parent = self.GetClosestBlockParent(start_node);
6249parent.parentNode.insertBefore(node, parent);
6250self.ImageEvents(node.querySelector('img'));
6251self.ContentEvents();
6252} else {
6253var n = orig_name.split('.');
6254n = n.splice(n.length - 2, 1);
6255string = '<a class="FileTypeIcon FileType' + type.replace('/', '') + '" href="' + webroot + url + '">&nbsp;</a><a href="' + webroot + url + '">' + n + '</a>';
6256var node = CreateStrong('a');
6257node.href = webroot + url;
6258node.className = 'FileTypeIcon FileType' + type.replace('/', '');
6259node.textContent = ' ';
6260var node2 = CreateStrong('a');
6261node2.href = webroot + url;
6262node2.textContent = n;
6263if (start_offset > 0) {
6264var stext = document.createTextNode(actual_node.textContent.substr(0, start_offset));
6265start_node.textContent = actual_node.textContent.substr(start_offset);
6266start_node.parentNode.insertBefore(stext, start_node);
6267}
6268start_node.parentNode.insertBefore(node, start_node);
6269start_node.parentNode.insertBefore(node2, start_node);
6270}
6271fm.f('Dialog').Close();
6272self.Save();
6273}
6274};
6275this.Save = function()
6276{
6277var changed = false;
6278if (self.BlockContent) {
6279var start_node;
6280var end_node;
6281var top_nodes = self.Element.children('.' + self.EditorDivClass).dom(0).childNodes;
6282var length = top_nodes.length;
6283for (var i in top_nodes) {
6284if (typeof top_nodes[i] != 'object' || /^[\s]*$/ig.test(top_nodes[i].textContent)) continue;
6285var tag = self.GetClosestBlockParent(top_nodes[i]);
6286if (tag.contentEditable === 'true') {
6287if (top_nodes[i].tagName) {
6288let el = new GraceWeb(top_nodes[i]);
6289let children = el.DirectChildren();
6290if (children) {
6291children.each(function(ch) {
6292el.AddBefore(ch);
6293});
6294}
6295let p = g.NewElementFromHTML('<p></p>');
6296el.AddBefore(p);
6297p.append(el);
6298} else if (!start_node) {
6299start_node = top_nodes[i];
6300end_node = top_nodes[i];
6301} else {
6302end_node = top_nodes[i];
6303}
6304}
6305if (tag.contentEditable != 'true' || length - 1 == i) {
6306if (start_node && end_node) {
6307self.PutStrong('p', start_node, end_node, 0, end_node.textContent.length);
6308start_node = null;
6309end_node = null;
6310changed = true;
6311}
6312}
6313}
6314}
6315let content = self.Element.children('.' + self.EditorDivClass).clone();
6316content.children('.EmbedLink').each(function(el) {
6317el.SetHTML('');
6318});
6319content.children('*').each(function(el) {
6320let attrs = el.attr.getList();
6321for (let attr in attrs) {
6322if (allowed_attributes.indexOf(attr) < 0) {
6323el.attr.remove(attr);
6324}
6325}
6326});
6327self.UpdateTextContentOfElements(content.dom(0).childNodes);
6328content = content.GetHTML();
6329content = content.replace(/\<\/(p)\>/ig, "</p>\r");
6330content = content.replace(/\<\/(div)\>/ig, "</div>\r");
6331self.SetHTMLCode();
6332self.Element.children('textarea').attr.set('value', content);
6333self.Element.children('textarea').e.trigger('change');
6334if (changed) {
6335var p = self.Element.children('.' + self.EditorDivClass + ' p:last-of-type').dom(0);
6336var range = document.createRange();
6337range.selectNodeContents(p);
6338range.collapse(false);
6339var sel = window.getSelection();
6340sel.removeAllRanges();
6341sel.addRange(range);
6342}
6343};
6344this.UpdateTextContentOfElements = function(elements) {
6345for (let i = 0; i < elements.length; i++) {
6346let el = elements[i];
6347if (el.nodeType == 3 && el.textContent) {
6348el.textContent = el.textContent.replace(/([\s^][a-zěščřžýáíéĚŠČŘŽÝÁÍÉ]{1,2})\s+([a-zěščřžýáíéĚŠČŘŽÝÁÍÉ]{2,})/ig, '$1\u00A0$2');
6349}
6350this.UpdateTextContentOfElements(el.childNodes);
6351}
6352}
6353this.Load = function()
6354{
6355var content = self.GetValue();
6356self.Element.children('.' + self.EditorDivClass).SetHTML(content);
6357var anchors = self.Element.children('.' + self.EditorDivClass + ' a');
6358if (anchors.dom().length > 0) {
6359anchors.e.on('click', function() {
6360return false;
6361});
6362}
6363self.Element.children('img').each(function(img) {
6364self.ImageEvents(img.dom(0));
6365});
6366};
6367this.LoadFromHTML = function()
6368{
6369var html = self.Element.children('.HTMLcode').GetHTML().replace(/&lt;/g, '<').replace(/&gt;/g, '>');
6370self.Element.children('textarea').dom(0).value = html;
6371self.Load();
6372};
6373this.InitialLoad = function()
6374{
6375self.Load();
6376self.SetHTMLCode();
6377};
6378this.SetHTMLCode = function() {
6379self.Element.children('.HTMLcode').SetHTML(self.GetValue().replace(/\</gm, '&lt;').replace(/\>/gm, '&gt;'));
6380};
6381this.GetValue = function() {
6382return self.Element.children('textarea').dom(0).value;
6383};
6384var BuildEditor = function()
6385{
6386self.Element = self.Element.parent('.GEditor') ? self.Element.parent('.GEditor') : self.Element;
6387var controls = document.createElement('div');
6388controls.className = 'Controls';
6389controls = self.BuildControls(new GraceWeb(controls));
6390self.Element.prepend(controls);
6391};
6392this.BuildControls = function(controls) {
6393var buttons = self.BlockContent ? self.Controls : self.InlineControls;
6394for (var i in buttons) {
6395var iconset = document.createElement('div');
6396iconset.className = 'IconsSet';
6397if (buttons[i].Class) iconset.className += ' ' + buttons[i].Class;
6398this.Element.children('textarea').class.add('Hidden');
6399for (var j in buttons[i].Items) {
6400var btn = document.createElement('span');
6401btn.className = 'Icon ' + buttons[i].Items[j].Class;
6402if (buttons[i].Items[j].Class == 'HTML') {
6403var type = document.createAttribute('data-type');
6404type.value = '2';
6405btn.attributes.setNamedItem(type);
6406if (self.Element.dom(0).tagName == 'TEXTAREA') {
6407self.Element.dom(0).className = 'Hidden';
6408} else {
6409self.Element.children('textarea').dom(0).className = 'Hidden';
6410}
6411}
6412if (buttons[i].Items[j].Tag) {
6413var datatag = document.createAttribute('data-tag');
6414datatag.value = buttons[i].Items[j].Tag;
6415btn.attributes.setNamedItem(datatag);
6416}
6417if (buttons[i].Items[j].ClassName) {
6418var datatag = document.createAttribute('data-class');
6419datatag.value = buttons[i].Items[j].ClassName;
6420btn.attributes.setNamedItem(datatag);
6421}
6422if (buttons[i].Items[j].Fnc) {
6423var datafnc = document.createAttribute('data-fnc');
6424datafnc.value = buttons[i].Items[j].Fnc;
6425btn.attributes.setNamedItem(datafnc);
6426}
6427iconset.appendChild(btn);
6428}
6429controls.append(new GraceWeb(iconset));
6430}
6431self.ControlsElement = controls;
6432return controls;
6433};
6434this.RebuildControls = function() {
6435var controls = self.Element.children('.Controls');
6436controls.SetHTML('');
6437self.BuildControls(controls);
6438var icons = self.Element.children('.Icon');
6439icons.e.on('mousedown', ControlButtonClicked);
6440};
6441return this;
6442};
6443GraceWeb.prototype.GEditor.prototype.CheckLinks = function()
6444{
6445return;
6446let checker = new GraceWeb.prototype.EmbedLink();
6447let content = this.Element.children('.' + this.EditorDivClass);
6448content.children(this.Blocks.join(',')).each(function(block) {
6449let embed = checker.CheckElement(block);
6450if (embed && embed.Count()) {
6451embed.class.add('MediaItem');
6452let mg = g.NewElementFromHTML('<div class="MediaGallery"><div class="MediaRow"></div></div>');
6453mg.children('.MediaRow').append(embed);
6454block.AddAfter(mg);
6455}
6456});
6457};
6458GraceWeb.prototype.GEditor.prototype.ContentEvents = function()
6459{
6460let self = this;
6461this.Element.children('.' + self.EditorDivClass).children('.Image, .MediaItem').attr.set('draggable', 'true');
6462this.Element.children('.' + self.EditorDivClass).children('.Image img').attr.set('draggable', 'false');
6463self.Element.children('.' + self.EditorDivClass).children('.Image, .MediaItem').e.on('dragstart', function(el, e) {
6464self.Pasting.ChangeFocusOnDragover = false;
6465self.Dragged = el;
6466el = el.clone();
6467el.class.add('Dragging');
6468e.dataTransfer.setData('geditorhtml', el.dom(0).outerHTML);
6469});
6470this.Element.Children('img').each(function(img) {
6471self.ImageEvents(img.dom(0));
6472});
6473};
6474GraceWeb.prototype.GEditor.prototype.PastingCheck = function(e)
6475{
6476if (this.Pasting.DroppedData.types.indexOf('savedfile') < 0 && !this.Dragged && !this.Pasting.HasFiles()) return true;
6477let self = this;
6478let t = new GraceWeb(e.target);
6479if (this.Pasting.OnlyImagesInFiles()) {
6480if (t.parent('.MediaRow') && !t.parent('.MediaRow').css.get('height')) {
6481let h = t.parent('.MediaRow').GetHeight();
6482t.parent('.MediaRow').css.set('height', h + 'px');
6483}
6484let pasting_el = this.GetPastingEl(t);
6485let block = t.class.has('MediaItem') ? t : t.parent('.MediaItem');
6486let check_by;
6487if (block) {
6488check_by = block.parent('.MediaRow');
6489if (!check_by) block.parent('.MediaGallery');
6490}
6491if (!block) {
6492block = (new GraceWeb(self.GetClosestBlockParent(e.target)));
6493check_by = block;
6494}
6495if (!pasting_el) {
6496pasting_el = self.Element.children('.' + self.EditorDivClass + ' .Pasting');
6497if (!pasting_el || !pasting_el.Count()) pasting_el = g.NewElementFromHTML('<div class="Pasting">&nbsp;</div>');
6498if (block.attr.has('contenteditable')) {
6499pasting_el = block.append(pasting_el);
6500} else {
6501pasting_el = block.AddAfter(pasting_el);
6502}
6503}
6504let prev = pasting_el.PreviousAll('.MediaItem');
6505if (prev.Count()) {
6506prev = prev.Select(0);
6507} else {
6508prev = null;
6509}
6510let al = self.Element.children('.' + self.EditorDivClass + ' [data-align]');
6511if (al.Count()) {
6512al.class.remove(al.data.get('align'));
6513al.data.remove('align');
6514}
6515if (t.parent('.MediaGallery')) {
6516let offset_px = 30;
6517let bottom = check_by.offset().top + check_by.GetHeight();
6518let bottom_offset = bottom - offset_px;
6519let cursor_top = e.clientY + g.scroll.get();
6520if (cursor_top >= bottom_offset && cursor_top <= bottom) {
6521if (block.parent('.MediaRow')) block.parent('.MediaRow').AddAfter(pasting_el);
6522} else {
6523let offset_px = 30;
6524let editor_left = block.offset().left;
6525let offset_left = editor_left + offset_px;
6526let cursor_left = e.clientX;
6527let offset_right = editor_left + block.GetWidth() - offset_px;
6528if (cursor_left >= editor_left && cursor_left <= offset_left) {
6529pasting_el = block.AddBefore(pasting_el);
6530}
6531}
6532} else {
6533//let offset_px = block.GetWidth() / 100 * 25;
6534let offset_px = 50;
6535let editor_left = check_by.offset().left;
6536let offset_left = editor_left + offset_px;
6537let cursor_left = e.clientX;
6538let offset_right = editor_left + check_by.GetWidth() - offset_px;
6539if (cursor_left > offset_right) {
6540pasting_el.class.add('MediaRight');
6541} else if (cursor_left > offset_left) {
6542pasting_el.class.remove('MediaLeft');
6543pasting_el.class.remove('MediaRight');
6544} else {
6545pasting_el.class.add('MediaLeft');
6546}
6547}
6548this.ContentEvents();
6549return false;
6550} else {
6551return true;
6552}
6553};
6554GraceWeb.prototype.GEditor.prototype.GetPastingEl = function(el)
6555{
6556if (!el) {
6557el = this.Element.children('.' + this.EditorDivClass + ' .Pasting');
6558if (el && el.Count()) return el;
6559return null;
6560}
6561if (el.class.has('Pasting')) return el;
6562let p = el.parent('.Pasting');
6563if (p) return p;
6564let n;
6565let allowed_parent_classes = ['MediaItem', 'MediaRow', 'MediaGallery'];
6566for (let i in allowed_parent_classes) {
6567let cl = allowed_parent_classes[i];
6568if (el.class.has(cl)) {
6569n = el;
6570break;
6571}
6572let p = el.parent('.' + cl);
6573if (p) {
6574n = p;
6575break;
6576}
6577}
6578if (!n) n = (new GraceWeb(this.GetClosestBlockParent(el.dom(0))));
6579n = n.next();
6580if (n && n.class.has('Pasting')) return n;
6581return null;
6582};
6583GraceWeb.prototype.GEditor.prototype.PastedByInsideMove = function()
6584{
6585let paste_el = this.GetPastingEl();
6586let pasting_el = g.NewElementFromHTML(this.Pasting.GetByType('geditorhtml'));
6587pasting_el.class.remove('Dragging');
6588pasting_el.e.CancelAll();
6589pasting_el.data.remove('id');
6590pasting_el.class.remove('MediaLeft');
6591pasting_el.class.remove('MediaRight');
6592if (!pasting_el.class.has('MediaGallery') && !paste_el.parent('.MediaGallery')) {
6593let mk = g.NewElementFromHTML('<div class="MediaGallery"><div class="MediaRow"></div></div>');
6594mk.children('.MediaRow').append(pasting_el);
6595pasting_el = mk;
6596} else if (!pasting_el.class.has('MediaRow') && !paste_el.parent('.MediaRow')) {
6597let mr = g.NewElementFromHTML('<div class="MediaRow"></div>');
6598mr.append(pasting_el);
6599pasting_el = mr;
6600}
6601if (paste_el.class.has('MediaLeft')) pasting_el.class.add('MediaLeft');
6602if (paste_el.class.has('MediaRight')) pasting_el.class.add('MediaRight');
6603pasting_el = paste_el.AddAfter(pasting_el);
6604paste_el.remove();
6605let p = this.Dragged.parent('.MediaGallery');
6606if (p && p.children('.MediaItem').Count() < 2) {
6607this.Dragged = p;
6608} else {
6609p = this.Dragged.parent('.MediaRow');
6610if (p && p.children('.MediaItem').Count() < 2) {
6611this.Dragged = p;
6612}
6613}
6614this.Dragged.remove();
6615this.Dragged = null;
6616this.ContentEvents();
6617};
6618GraceWeb.prototype.GEditor.prototype.CheckListAndIncreaseIndent = function()
6619{
6620var range = window.getSelection().getRangeAt(0);
6621let actual_node = range.startContainer;
6622let el = this.GetClosestBlockParent(actual_node);
6623el = el ? new GraceWeb(el) : null;
6624if (el && el.GetTagName() == 'li') {
6625this.IncreaseListIndent(el);
6626return true;
6627}
6628return false;
6629}
6630GraceWeb.prototype.GEditor.prototype.IncreaseListIndent = function(li)
6631{
6632let list_tag = li.parent('ul, ol');
6633let list = g.NewElementFromHTML('<' + list_tag.GetTagName() + '></' + list_tag.GetTagName() + '>');
6634let prev_li = li.PreviousAll('li').Select(0);
6635if (!prev_li) return;
6636prev_li.append(list);
6637list.append(li);
6638//this.CreateList(list_tag.GetTagName());
6639this.Save();
6640}
6641GraceWeb.prototype.GEditor.prototype.ImageEvents = function(node) {
6642let self = this;
6643let n = new GraceWeb(node);
6644n.e.on('dblclick', function(el, e) {
6645//node.addEventListener('dblclick', function(e) {
6646var src = node.src;
6647var alt = node.attributes.getNamedItem('alt');
6648alt = (alt == undefined) ? '' : alt.value;
6649var title = node.attributes.getNamedItem('title');
6650title = (title == undefined) ? '' : title.value;
6651let a = node.parentNode.tagName == 'A' ? node.parentNode : null;
6652var link = a ? a.attributes.getNamedItem('href') : node.attributes.getNamedItem('href');
6653link = (link == undefined) ? '' : link.value;
6654let cl = (new GraceWeb(node)).parent('.Image').attr.get('class');
6655let target = a && a.classList.contains('NewWindow') ? 'NewWindow' : '';
6656let rel = '';
6657if (a && a.rel) rel = a.rel;
6658let dialog = self.Element.children('.Dialogs .ImageDialog').clone();
6659let rel_input = dialog.children('[name="rel"]');
6660let target_input = dialog.children('[name="target"]');
6661let target_is_select = target_input.GetTagName() == 'select';
6662if (a) {
6663if (target_is_select) {
6664target_input.attr.set('value', target);
6665} else {
6666target_input.each(function (input) {
6667if (input.attr.get('value') == target) input.attr.set('checked', true);
6668});
6669}
6670rel_input.each(function (input) {
6671if (input.attr.get('value') == rel) input.attr.set('checked', true);
6672});
6673}
6674dialog.children('[name="alt"]').attr.set('value', alt);
6675dialog.children('[name="link"]').attr.set('value', link);
6676dialog.children('[name="title"]').attr.set('value', title);
6677dialog.children('[name="align"]').attr.set('value', cl);
6678dialog.children('img').attr.set('src', src);
6679dialog = dialog.f('Dialog');
6680dialog.TopClass = ['GEditorDialog', 'ImageDialog'];
6681dialog.Open();
6682dialog.DialogElement.children('.ChangeImage').e.click(function() {
6683var fm = self.OpenFilemanagerDialog();
6684var filemanager = fm.f('Filemanager');
6685filemanager.OnFileSelected = function(id, url, orig_name, type) {
6686path = url.split('.');
6687path.reverse();
6688if (type == 'image/jpeg' || type == 'image/png' || type == 'image/gif') {
6689var new_src = webroot + url;
6690dialog.DialogElement.children('img').attr.set('src', new_src);
6691}
6692fm.parent('.DialogModal').remove();
6693};
6694});
6695dialog.DialogElement.children('.OriginalButton').e.click(function() {
6696var img = (node.tagName == 'IMG') ? node : node.querySelector('img');
6697let img_el = new GraceWeb(img);
6698let media_item = img_el.DirectParent();
6699if (!media_item.class.has('MediaItem')) media_item = null;
6700let alt = dialog.DialogElement.children('[name="alt"]').attr.get('value');
6701let title = dialog.DialogElement.children('[name="title"]').attr.get('value');
6702var link = dialog.DialogElement.children('[name="link"]').attr.get('value');
6703if (alt) {
6704img_el.attr.set('alt', alt);
6705} else {
6706img_el.attr.remove('alt');
6707}
6708if (title) {
6709img_el.attr.set('title', title);
6710} else {
6711img_el.attr.remove('title');
6712}
6713//let cl = dialog.DialogElement.children('[name="align"]').attr.get('value');
6714if (img.src != dialog.DialogElement.children('img').attr.get('src')) {
6715img.src = dialog.DialogElement.children('img').attr.get('src');
6716}
6717//var n = ((img.parentNode.tagName == 'DIV' || img.parentNode.tagName == 'A') && img.parentNode.classList.contains('MediaGallery')) ? img.parentNode : img;
6718//n.className = cl;
6719if (link) {
6720if (media_item.GetTagName() != 'a') {
6721let a_media_item = g.NewElementFromHTML('<a></a>');
6722let attrs = media_item.attr.getList();
6723for (let i in attrs) {
6724a_media_item.attr.set(i, attrs[i]);
6725}
6726a_media_item.SetHTML(media_item.GetHTML());
6727media_item.AddAfter(a_media_item);
6728media_item.remove();
6729media_item = a_media_item;
6730//self.ImageEvents(media_item.FindFirst('img').dom(0));
6731}
6732media_item.attr.set('href', link);
6733let target_value = '';
6734if (target_is_select) {
6735target_value = target_input.attr.get('value');
6736} else {
6737target_input.each(function(input) {
6738if (input.attr.get('checked')) {
6739target_value = input.attr.get('value');
6740return false;
6741}
6742});
6743}
6744let rel_value = '';
6745rel_input.each(function(input) {
6746if (input.attr.get('checked')) {
6747rel_value = input.attr.get('value');
6748return false;
6749}
6750});
6751if (rel_value) {
6752media_item.attr.set('rel', rel_value);
6753} else {
6754media_item.attr.remove('rel');
6755}
6756if (target_value.length > 0) {
6757media_item.class.add(target_value);
6758} else {
6759media_item.class.remove('NewWindow');
6760}
6761} else {
6762if (media_item.GetTagName() == 'a') {
6763let a_media_item = g.NewElementFromHTML('<div></div>');
6764let attrs = media_item.attr.getList();
6765for (let i in attrs) {
6766a_media_item.attr.set(i, attrs[i]);
6767}
6768a_media_item.SetHTML(media_item.GetHTML());
6769media_item.AddAfter(a_media_item);
6770media_item.remove();
6771media_item = a_media_item;
6772//self.ImageEvents(media_item.FindFirst('img').dom(0));
6773}
6774media_item.attr.remove('href');
6775}
6776if (media_item.GetTagName() == 'a' && title) {
6777media_item.attr.set('title', title);
6778} else {
6779media_item.attr.remove('title');
6780}
6781self.ContentEvents();
6782dialog.Close();
6783self.Save();
6784});
6785});
6786};
6787GraceWeb.prototype.GEditor.prototype.Controls = [
6788{
6789Class: 'HTML',
6790Items: [
6791{Class: 'HTML', Fnc: 'ChangeHTMLView'}
6792]
6793},
6794{
6795Items: [
6796{Class: 'Bold', Tag: 'strong'},
6797{Class: 'Italic', Tag: 'em'},
6798{Class: 'Underline', Tag: 'u'}
6799]
6800},
6801{
6802Items: [
6803{Class: 'Link', Tag: 'a', Fnc: 'CreateLink'},
6804{Class: 'Unlink', Tag: 'a'}
6805]
6806},
6807{
6808Items: [
6809{Class: 'OL', Tag: 'ol', Fnc: 'CreateListFromButton'},
6810{Class: 'UL', Tag: 'ul', Fnc: 'CreateListFromButton'}
6811]
6812},
6813{
6814Items: [
6815{Class: 'P', Tag: 'p'},
6816{Class: 'H2', Tag: 'h2'},
6817{Class: 'H3', Tag: 'h3'},
6818{Class: 'H4', Tag: 'h4'}
6819]
6820}
6821];
6822GraceWeb.prototype.GEditor.prototype.InlineControls = [
6823{
6824Class: 'HTML',
6825Items: [
6826{Class: 'HTML', Fnc: 'ChangeHTMLView'}
6827]
6828},
6829{
6830Items: [
6831{Class: 'Bold', Tag: 'strong'},
6832{Class: 'Italic', Tag: 'em'},
6833{Class: 'Underline', Tag: 'u'}
6834]
6835},
6836{
6837Items: [
6838{Class: 'Link', Tag: 'a', Fnc: 'CreateLink'},
6839{Class: 'Unlink', Tag: 'a'}
6840]
6841},
6842{
6843Items: [
6844{Class: 'File', Fnc: 'InsertFile'}
6845]
6846}
6847];
6848GraceWeb.prototype.GEditor.prototype.AllowedClasses = ['Image', 'MediaItem', 'MediaGallery', 'MediaLeft', 'MediaRight', 'MediaRow', 'ImageLeft', 'ImageRight', 'NewWindow', 'EmbedLink', 'YouTube', 'Instagram', 'Vimeo', 'Youtube', 'Instagram', 'Twitter', 'EmbedIn', 'Website', 'GrabbedWebsite', 'GrabbedProduct', 'WebName', 'Price', 'Frame', 'Button'];
6849GraceWeb.prototype.Gallery = function(g) {
6850var self = this;
6851var Dialog;
6852this.ActualIndex = 0;
6853this.Rotate = true;
6854this.View = 'auto'; // Values are auto, portrait, landscape
6855this.AfterViewChange = function() {};
6856this.AfterResize = function() {};
6857this.AfterPhotoChange = function() {};
6858this.Init = function() {
6859g.children('.Image').e.click(function(a, e) {
6860//if (/mobile/i.test(navigator.userAgent)) return false;
6861a.data.set('gallery-init-aaa', '1');
6862self.Open(a);
6863return false;
6864});
6865if (g.class.has('Image')) {
6866g.e.click(function(a) {
6867self.Open(g);
6868return false;
6869});
6870}
6871};
6872this.Open = function(init_a) {
6873var dialog_div = self.BuildHTML(init_a);
6874Dialog = dialog_div.f('Dialog');
6875Dialog.TopClass = 'GalleryDialog';
6876Dialog.Open();
6877self.SetEvents();
6878let cnt = 0;
6879if (g.Children('[data-gallery-init-aaa]').Count()) {
6880g.Children('.Image').each(function(img) {
6881if (img.data.get('gallery-init-aaa')) {
6882img.data.remove('gallery-init-aaa');
6883return false;
6884}
6885cnt++;
6886});
6887} else {
6888var a = init_a.previous();
6889while (a) {
6890cnt++;
6891a = a.previous();
6892}
6893}
6894let thumb_el = Dialog.DialogElement.children('.SideImage[data-index="' + cnt + '"]');
6895this.DisplayImage(thumb_el);
6896this.SetViewType();
6897};
6898this.BuildHTML = function(init_a) {
6899var dialog_div = new GraceWeb(document.createElement('div'));
6900var img = new GraceWeb(document.createElement('div'));
6901img.class.add('MainImage');
6902//img.css.set('background-image', 'url(' + init_a.attr.get('href') + ')');
6903dialog_div.append(img);
6904dialog_div.append(self.BuildNextPhotosBar());
6905var prev = new GraceWeb(document.createElement('div'));
6906prev.class.add('Arrow');
6907prev.class.add('Previous');
6908var next = new GraceWeb(document.createElement('div'));
6909next.class.add('Arrow');
6910next.class.add('Next');
6911img.append(prev);
6912img.append(next);
6913return dialog_div;
6914};
6915this.BuildNextPhotosBar = function() {
6916let bar = new GraceWeb(document.createElement('div'));
6917bar.class.add('GalleryImages');
6918let gal_images = g.children('.Image');
6919if (!gal_images.Count() && g.class.has('Image')) gal_images = g;
6920let i = 0;
6921gal_images.each(function(a) {
6922let image_div = new GraceWeb(document.createElement('div'));
6923image_div.class.add('SideImage');
6924let thumb = a.attr.get('data-thumb') ? a.attr.get('data-thumb') : a.children('img').attr.get('src');
6925image_div.css.set('background-image', 'url(' + thumb + ')');
6926image_div.attr.set('data-img', a.attr.get('href'));
6927image_div.attr.set('data-index', i++);
6928image_div.data.set('gallery-type', a.data.get('gallery-type') ? a.data.get('gallery-type') : 'image');
6929bar.append(image_div);
6930});
6931return bar;
6932};
6933this.DisplayImage = function(a) {
6934var img = Dialog.DialogElement.children('.MainImage');
6935if (a.data.get('gallery-type') == 'video') {
6936let video = g.NewElementFromHTML('<video controls playsinline preload="metadata"><source type="video/mp4" src="' + a.data.get('img') + '" /></video>');
6937img.Children('video').remove();
6938img.append(video);
6939video.dom(0).play();
6940} else {
6941let vid = img.FindFirst('video');
6942if (vid) vid.remove();
6943img.css.set('background-image', 'url(' + a.attr.get('data-img') + ')');
6944}
6945this.ActualIndex = parseInt(a.attr.get('data-index'));
6946Dialog.DialogElement.children('.SideImage').class.remove('Active');
6947a.class.add('Active');
6948img.attr.remove('data-type');
6949if (!this.Rotate) {
6950if (this.ActualIndex <= 0) {
6951img.attr.set('data-type', 'first');
6952} else if (this.ActualIndex >= Dialog.DialogElement.children('.SideImage').Count() - 1) {
6953img.attr.set('data-type', 'last');
6954}
6955}
6956this.AfterPhotoChange();
6957}
6958this.SetEvents = function() {
6959Dialog.DialogElement.children('.SideImage').e.click(function(a) {
6960self.DisplayImage(a);
6961});
6962Dialog.DialogElement.children('.Arrow.Next').e.click(function() {
6963self.OpenNextPhoto();
6964});
6965Dialog.DialogElement.children('.Arrow.Previous').e.click(function() {
6966self.OpenPreviousPhoto();
6967});
6968GraceW.children('body').e.on('keydown', function(el, e) {
6969if (e.keyCode == 39) { // right key
6970self.OpenNextPhoto();
6971} else if (e.keyCode == 37) { // left key
6972self.OpenPreviousPhoto();
6973}
6974});
6975Dialog.AfterSetDimensions = function() {
6976self.SetViewType();
6977self.AfterResize();
6978}
6979}
6980this.OpenNextPhoto = function() {
6981var img = Dialog.DialogElement.children('.SideImage[data-index="' + (self.ActualIndex + 1) + '"]');
6982if (img.Count()) {
6983self.DisplayImage(img);
6984return;
6985}
6986if (this.Rotate) {
6987self.DisplayImage(Dialog.DialogElement.children('.SideImage').Select(0));
6988}
6989}
6990this.OpenPreviousPhoto = function() {
6991var img = Dialog.DialogElement.children('.SideImage[data-index="' + (self.ActualIndex - 1) + '"]');
6992if (img.Count()) {
6993self.DisplayImage(img);
6994return;
6995}
6996if (this.Rotate) {
6997self.DisplayImage(Dialog.DialogElement.children('.SideImage:last-child'));
6998}
6999}
7000this.GetView = function() {
7001switch (this.View) {
7002case 'landscape':
7003case 'portrait':
7004return this.View;
7005default:
7006return (g.GetWindowWidth() >= g.GetWindowHeight()) ? 'landscape' : 'portrait';
7007}
7008}
7009this.SetViewType = function() {
7010var act_view = Dialog.DialogElement.attr.set('data-view');
7011var new_view = self.GetView();
7012Dialog.DialogElement.attr.set('data-view', new_view);
7013if (act_view != new_view) {
7014this.AfterViewChange();
7015}
7016}
7017};
7018g.e.domloaded(function() {
7019var gals = g.children('.Gallery');
7020for (var i = 0; i < gals.Count(); i++) {
7021var gallery = gals.Select(i).f('Gallery');
7022gallery.Init();
7023}
7024});
7025var BuildGraceMessageFunction = 'BuildGraceMessage';
7026function InitGrace()
7027{
7028if (document.Grace == undefined) return;
7029if (document.Grace.Messages != undefined) {
7030for (var i in document.Grace.Messages) {
7031var msg = document.Grace.Messages[i];
7032eval(BuildGraceMessageFunction + '(msg.msg, msg.type)');
7033//BuildGraceMessage(msg.msg, msg.type);
7034}
7035document.Grace.Messages = {};
7036}
7037}
7038function BuildGraceMessage(msg, type)
7039{
7040var Grace = g.NewElementFromHTML('<div class="Grace GraceMessage"><div class="Msg"></div></div>');
7041Grace.class.add('MsgType' + type);
7042Grace.children('.Msg').SetHTML(msg);
7043g.children('.GraceMessages').append(Grace);
7044setTimeout(function(){
7045//Grace.animate({width: '0'}, 400, function(){
7046Grace.remove();
7047//});
7048}, 3000);
7049//Grace.animate({width: '100%'}, 400);
7050}
7051function GraceConfirm(msg, left, top, yes_fnc, cancel_fnc)
7052{
7053var Grace = g.NewElementFromHTML('<div class="Grace GraceConfirmation"><div class="Msg"><div class="M"></div><div><button class="Btn OK"><svg width="102.984" height="20.666" viewBox="0 0 102.984 20.666"><path d="M201.072,379.272h-97.7v19.666H205.244Z" transform="translate(-102.877 -378.772)" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="1"/><text transform="translate(51.434 15.068)" font-size="14" font-family="Poppins-Regular, Poppins"><tspan x="-15.309" y="0">Ano</tspan></text></svg></button>&nbsp;<button class="Btn No"><svg height="20.666" viewBox="0 0 108.984 20.666"><path d="M314.072,379.272h-103.7l4.172,19.666h103.7V379.272Z" transform="translate(-209.76 -378.772)" fill="none" stroke="#1d1d1b" stroke-miterlimit="10" stroke-width="1"/><text transform="translate(58.388 15.068)" fill="#1d1d1b" font-size="14" font-family="Poppins-Regular, Poppins"><tspan x="-33.761" y="0">NE, nechci</tspan></text></svg></button></div></div></div>');
7054Grace.css.set('left', left + 'px');
7055Grace.css.set('top', top + 'px');
7056Grace.css.set('position', 'absolute');
7057Grace.children('.No').e.click(function(){
7058Grace.class.add('MsgType3');
7059Grace.children('.Msg').SetHTML('OK');
7060setTimeout(function(){
7061Grace.remove();
7062}, 1000);
7063if (cancel_fnc != undefined) cancel_fnc();
7064});
7065Grace.children('.OK').e.click(function(){
7066Grace.class.add('MsgType3');
7067Grace.children('.Msg').SetHTML('OK, I did it.');
7068setTimeout(function(){
7069//Grace.animate({opacity: 0}, 500, function(){
7070Grace.remove();
7071//});
7072}, 1000);
7073if (yes_fnc != undefined) yes_fnc();
7074});
7075Grace.children('.M').prepend(msg);
7076g.children('body').append(Grace);
7077//Grace.animate({opacity: 1}, 500);
7078}
7079function GraceConfirmToCursor(msg, e, yes_fnc, cancel_fnc)
7080{
7081GraceConfirm(msg, e.clientX + 50, e.clientY + document.documentElement.scrollTop, yes_fnc, cancel_fnc);
7082}
7083GraceWeb.prototype.InViewport = function(g) {
7084let self = this;
7085this.OffsetTop = 300;
7086this.OffsetBottom = 300;
7087this.ScrollElement = window;
7088this.UseObserver = 'IntersectionObserver' in window;
7089let Changes = {};
7090let Observer;
7091this.InitScrolling = function() {
7092if (this.UseObserver) {
7093Observer = new IntersectionObserver(function (changed) {
7094for (let i in changed) {
7095let ch = changed[i];
7096let el = new GraceWeb(ch.target);
7097if (ch.isIntersecting || ch.isVisible) {
7098el.e.trigger('got-inside');
7099//console.log(ch.target, ch.isIntersecting, ch.isVisible, ch.boundingClientRect, ch.intersectionRect, ch.intersectionRatio, ch.rootBounds);
7100} else {
7101el.e.trigger('got-outside');
7102}
7103}
7104}, {
7105root: null,
7106treshold: 0,
7107rootMargin: this.OffsetTop + 'px'
7108});
7109g.each(function (el) {
7110Observer.observe(el.dom(0));
7111});
7112} else {
7113this.ScrollElement.addEventListener('scroll', function () {
7114self.Check();
7115});
7116}
7117};
7118this.SetOffset = function(new_offset) {
7119this.OffsetTop = new_offset;
7120this.OffsetBottom = new_offset;
7121if (Observer) Observer.disconnect();
7122this.InitScrolling();
7123};
7124this.RemoveFromWatching = function(el) {
7125if (this.UseObserver) {
7126el.each(function(sel) {
7127Observer.unobserve(sel.dom(0));
7128});
7129el.e.cancel('got-inside');
7130}
7131};
7132this.Check = function() {
7133if (this.UseObserver) return;
7134let scroll_top = this.ScrollElement == window ? GraceW.scroll.get() : (ne
7134w GraceWeb(this.ScrollElement).scroll.get());
7135let scroll_bottom = scroll_top + (this.ScrollElement.innerHeight ? this.ScrollElement.innerHeight : this.ScrollElement.clientHeight);
7136let offset_top = scroll_top - self.OffsetTop;
7137let offset_bottom = scroll_bottom + self.OffsetBottom;
7138let i = 0;
7139g.each(function(el) {
7140let el_id = el.InternalId();
7141let el_top = el.offset().top;
7142if (el_top < 0) el_top = 0;
7143let el_bottom = el_top + el.GetHeight();
7144let status_viewport = '';
7145let status_offset = '';
7146let current_status = Changes[el_id];
7147let current_viewport = '';
7148let current_offset = '';
7149let is_in = false;
7150if (!current_status) {
7151Changes[el_id] = {};
7152} else {
7153current_viewport = current_status.viewport;
7154current_offset = current_status.offset;
7155}
7156if (el_top >= offset_top && el_bottom <= offset_bottom) {
7157el.e.trigger('fully-in-offset');
7158status_offset = 'fully-in-offset';
7159is_in = true;
7160} else if ((el_top >= offset_top && el_top <= offset_bottom) || (el_bottom >= offset_top && el_bottom <= offset_bottom)) {
7161el.e.trigger('partially-in-offset');
7162if (current_offset == 'out-of-offset') {
7163status_offset = 'partially-in-offset';
7164is_in = true;
7165} else {
7166status_offset = 'fully-out-of-offset';
7167}
7168} else {
7169status_offset = 'out-of-offset';
7170}
7171if (el_top >= scroll_top && el_bottom <= scroll_bottom) {
7172el.e.trigger('fully-in-viewport');
7173status_viewport = 'fully-in-viewport';
7174is_in = true;
7175} else if ((el_top >= scroll_top && el_top <= scroll_bottom) || (el_bottom >= scroll_top && el_bottom <= scroll_bottom)) {
7176el.e.trigger('partially-in-viewport');
7177if (!current_viewport || current_viewport == 'out-of-viewport') {
7178status_viewport = 'partially-in-viewport';
7179is_in = true;
7180} else {
7181status_viewport = 'fully-out-of-viewport';
7182}
7183} else {
7184status_viewport = 'out-of-viewport';
7185}
7186let changed = false;
7187if (current_viewport != status_viewport) {
7188Changes[el_id].viewport = status_viewport;
7189el.e.trigger('got-' + status_viewport);
7190changed = true;
7191}
7192if (current_offset != status_offset) {
7193Changes[el_id].offset = status_offset;
7194el.e.trigger('got-' + status_offset);
7195changed = true;
7196}
7197if (changed && is_in) {
7198el.e.trigger('got-inside');
7199} else if (changed && !is_in) {
7200el.e.trigger('got-outside');
7201}
7202i++
7203});
7204};
7205if (!this.UseObserver) {
7206this.Check();
7207}
7208this.InitScrolling();
7209};
7210GraceWeb.prototype.Loading = function(g) {
7211let self = this;
7212self.Panel;
7213let LoadingPanel;
7214this.Set = function() {
7215if (self.Panel) {
7216LoadingPanel = self.Panel;
7217} else {
7218LoadingPanel = g.NewElementFromHTML('<div class="Loading Absolute"></div>');
7219}
7220LoadingPanel.css.set('top', g.offset().top + 'px');
7221LoadingPanel.css.set('left', g.offset().left + 'px');
7222LoadingPanel.css.set('width', g.GetWidth() + 'px');
7223LoadingPanel.css.set('height', g.GetHeight() + 'px');
7224GraceW.children('body').append(LoadingPanel);
7225LoadingPanel.class.remove('Hidden');
7226};
7227this.Remove = function() {
7228if (self.Panel) {
7229self.Panel.class.add('Hidden');
7230} else {
7231GraceW.children('.Loading').remove();
7232}
7233};
7234return this;
7235};
7236function Notifications()
7237{
7238}
7239Notifications.prototype.AjaxRegisterLink = webroot + 'push-register/';
7240Notifications.prototype.AjaxUnregisterLink = webroot + 'push-unregister/';
7241Notifications.prototype.GetFCMToken = function() {
7242let self = this;
7243let promise = new Promise(function(resolve, reject) {
7244if (window.flutter_inappwebview) {
7245window.flutter_inappwebview.callHandler('GetFCMToken').then(function (result) {
7246if (result) {
7247resolve(result);
7248} else {
7249reject();
7250}
7251}).catch(function() {
7252reject();
7253});
7254} else {
7255reject();
7256}
7257});
7258return promise;
7259}
7260Notifications.prototype.Process = function() {
7261let self = this;
7262this.GetFCMToken().then(function(token) {
7263self.Register(token);
7264}, function() {
7265self.Unregister();
7266});
7267}
7268Notifications.prototype.PrepareFetchData = function() {
7269let headers = {
7270'Ajax': 'Ajax',
7271'Content-Type': 'text/json',
7272};
7273let fetch_data = {
7274method: 'POST',
7275headers: headers
7276};
7277return fetch_data;
7278}
7279Notifications.prototype.Register = function(token) {
7280let fetch_data = this.PrepareFetchData();
7281fetch_data.body = JSON.stringify({token: token});
7282fetch(this.AjaxRegisterLink, fetch_data);
7283}
7284Notifications.prototype.Unregister = function() {
7285let fetch_data = this.PrepareFetchData();
7286fetch(this.AjaxUnregisterLink, fetch_data);
7287}
7288GraceWeb.prototype.ObjectsPasting = function(g)
7289{
7290let self = this;
7291this.G = g;
7292this.DroppedData;
7293this.DropElements;
7294this.CurrentlyInDrag = null;
7295this.AutoUploadFiles = true;
7296this.ProgressInfoG;
7297this.ChangeFocusOnDragover = true;
7298this.DragOverReturn = true;
7299this.Ajax = g.f('Ajax');
7300this.Ajax.Class = '\\Core\\Controls\\FileUploaded';
7301this.Ajax.Method = 'Upload';
7302this.Ajax.ProgressFnc = function(e) {
7303self.UploadProgress(e);
7304};
7305g.e.on('dragover', function(el, e) {
7306if (self.CurrentlyInDrag != el && e.dataTransfer) {
7307self.CurrentlyInDrag = el;
7308el.e.triggers.trigger('dragoverstart', e);
7309}
7310self.DroppedData = e.dataTransfer;
7311if (self.ChangeFocusOnDragover && self.HasFiles() && self.GetText()) {
7312let range = document.createRange();
7313range.setStart(e.target, 0);
7314range.setEnd(e.target, 0);
7315window.getSelection().removeAllRanges();
7316window.getSelection().addRange(range);
7317}
7318return self.DragOverReturn;
7319});
7320g.e.on('mouseout', function(el, e) {
7321if (self.CurrentlyInDrag == el) {
7322self.CurrentlyInDrag = null;
7323el.e.trigger('dragoverend');
7324}
7325});
7326g.e.on('drop', function(el, e) {
7327let target = new GraceWeb(e.target);
7328let real_el;
7329self.GetDropElements().each(function(check_el) {
7330//console.log(check_el.dom(), check_el.GetOuterHTML());
7331//console.log(target.dom(), target.GetOuterHTML());
7332//console.log(check_el.Contains(target));
7333if (check_el.Contains(target)) {
7334real_el = check_el;
7335return false;
7336}
7337});
7338if (!real_el) return false;
7339self.DroppedData = e.dataTransfer;
7340self.UploadFilesIfAllowed();
7341real_el.e.trigger('dropped');
7342if (self.HasFiles() && !self.GetText()) return false;
7343});
7344g.e.on('paste', function(el, e) {
7345self.CurrentlyInDrag = false;
7346if (!self.GetDropElements().Contains(new GraceWeb(e.target))) return true;
7347self.DroppedData = e.clipboardData;
7348self.UploadFilesIfAllowed();
7349let res = (new GraceWeb(e.target)).e.trigger('dropped');
7350//let res = el.e.trigger('dropped');
7351if (res === false) return false;
7352if (self.HasFiles() && !self.GetText()) return false;
7353});
7354};
7355GraceWeb.prototype.ObjectsPasting.prototype.GetDropElements = function()
7356{
7357return this.DropElements ? this.DropElements : this.G;
7358}
7359GraceWeb.prototype.ObjectsPasting.prototype.UploadProgress = function(e)
7360{
7361let g = this.ProgressInfoG;
7362if (!g || !g.Count()) return;
7363g.class.remove('Hidden');
7364g.children('.Finished').class.add('Hidden');
7365g.children('.Bar').class.remove('Visible');
7366let total = (e.total != undefined) ? e.total : e.totalSize;
7367let perc = (100 / total) * e.loaded;
7368let bars = g.children('.Bar').Select(0);
7369if (perc >= 20) {
7370bars.AddElements(g.children('.Bar').Select(1));
7371}
7372if (perc >= 40) {
7373bars.AddElements(g.children('.Bar').Select(2));
7374}
7375if (perc >= 60) {
7376bars.AddElements(g.children('.Bar').Select(3));
7377}
7378if (perc >= 80) {
7379bars.AddElements(g.children('.Bar').Select(4));
7380}
7381if (perc >= 100) {
7382g.children('.Uploading').class.add('Hidden');
7383g.children('.Processing').class.remove('Hidden');
7384} else {
7385g.children('.Uploading').class.remove('Hidden');
7386g.children('.Processing').class.add('Hidden');
7387bars.class.add('Visible');
7388}
7389g.children('.Percents').SetHTML(Math.floor(perc) + '&nbsp;%');
7390};
7391GraceWeb.prototype.ObjectsPasting.prototype.UploadFilesIfAllowed = function()
7392{
7393if (!this.AutoUploadFiles || this.GetText()) return;
7394this.UploadFiles();
7395};
7396GraceWeb.prototype.ObjectsPasting.prototype.UploadFiles = function()
7397{
7398let files = this.GetFiles();
7399if (!files) return;
7400for (let i = 0; i < files.length; i++) {
7401let k = (i == 0) ? '' : i;
7402this.Ajax.Data['upload' + k] = files[i];
7403}
7404this.Ajax.SendAsFilesChunks();
7405};
7406GraceWeb.prototype.ObjectsPasting.prototype.GetByType = function(type)
7407{
7408if (!this.DroppedData) return;
7409return this.DroppedData.getData(type);
7410};
7411GraceWeb.prototype.ObjectsPasting.prototype.GetLink = function()
7412{
7413let data = this.GetByType('text/uri-list');
7414return data;
7415};
7416GraceWeb.prototype.ObjectsPasting.prototype.GetHTML = function()
7417{
7418let data = this.GetByType('text/html');
7419return data;
7420};
7421GraceWeb.prototype.ObjectsPasting.prototype.GetText = function()
7422{
7423let data = this.GetByType('text/plain');
7424return data;
7425};
7426GraceWeb.prototype.ObjectsPasting.prototype.GetFiles = function()
7427{
7428if (!this.DroppedData) return;
7429let data = this.DroppedData.files;
7430if (!data.length) {
7431data = [];
7432for (let i in this.DroppedData.items) {
7433if (this.DroppedData.items[i].kind == 'file') {
7434let f = this.DroppedData.items[i].getAsFile();
7435if (!f) f = {type: this.DroppedData.items[i].type};
7436data.push(f);
7437}
7438}
7439}
7440if (!data.length) return null;
7441return data;
7442};
7443GraceWeb.prototype.ObjectsPasting.prototype.OnlyImagesInFiles = function()
7444{
7445let files = this.GetFiles();
7446for (let i in files) {
7447if (!/image\//.test(files[i].type)) return false;
7448}
7449return true;
7450};
7451GraceWeb.prototype.ObjectsPasting.prototype.HasFiles = function()
7452{
7453return this.DroppedData && this.DroppedData.types && (this.DroppedData.types.indexOf('Files') > -1);
7454};
7455GraceWeb.prototype.Opener = function(g)
7456{
7457let self = this;
7458this.Element = g;
7459this.PanelElement = g.children('.Panel').Count() ? g.children('.Panel').Select(0) : g.children('.Panel');
7460this.HandlerElement = g.children('.Handler').Count() ? g.children('.Handler') : g;
7461this.HandlerElement.AddElements(this.HandlerElement.NextAll('.Handler'));
7462this.BeforeOpen = function() {};
7463this.AfterOpen = function() {};
7464this.BeforeClose = function() {};
7465this.AfterClose = function() {};
7466this.AutoHeightOnOpened = false;
7467this.Frozen = false;
7468this.AutoClose = false;
7469this.Init = function()
7470{
7471this.SetEvents();
7472if (this.Element.class.has('Opened')) this.Open(true);
7473let hidden_input = this.Element.children('.OpenerValue');
7474if (hidden_input.Count() && hidden_input.attr.get('value')) {
7475this.Choose(hidden_input.attr.get('value'));
7476}
7477GraceW.FindFirst('body').e.click(function(el, e) {
7478let t = new GraceWeb(e.target);
7479if (!t.parent('.Opened')) {
7480GraceW.Children('.Opener.Opened').each(function(o) {
7481let op = o.f('Opener');
7482if (op.Frozen || !op.AutoClose) return;
7483op.Close();
7484});
7485}
7486});
7487};
7488this.SetEvents = function()
7489{
7490let self = this;
7491this.HandlerElement.e.click(function(){
7492if (self.Frozen) return;
7493if (self.Element.class.has('Opened') || self.Element.class.has('Opening')) {
7494self.Close();
7495} else {
7496self.Open();
7497}
7498});
7499if (this.PanelElement.Count()) {
7500this.PanelElement.e.click(function (el, e) {
7501if (self.Frozen) return;
7502e.stopPropagation();
7503});
7504this.PanelElement.e.csstransitionend(function (el, e) {
7505if (self.Element.class.has('Closing')) { // just closed
7506self.Element.class.remove('Closing');
7507self.AfterClose();
7508} else if (self.Element.class.has('Opening')) { // just opened
7509self.Element.class.remove('Opening');
7510self.Element.class.add('Opened');
7511if (self.AutoHeightOnOpened) {
7512self.PanelElement.css.remove('height');
7513}
7514self.AfterOpen();
7515}
7516});
7517}
7518this.PanelElement.children('[data-value]').e.click(function(item) {
7519self.Choose(item.data.get('value'));
7520self.Close();
7521});
7522this.Element.children('.OpenerSelect').e.on('change', function(el) {
7523self.Choose(el.attr.get('value'));
7524self.Close();
7525});
7526};
7527this.Choose = function(value)
7528{
7529let text = this.Element.children('.Panel [data-value="' + value + '"]').GetHTML();
7530let handler_value = this.Element.children('[data-lookup="ValueChosenHandler"]');
7531let handler_non_value = this.Element.children('[data-lookup="NoneChosenHandler"]');
7532if (handler_value.Count() && value) {
7533handler_value.class.remove('Hidden');
7534handler_value.SetHTML(text);
7535} else {
7536handler_value.class.add('Hidden');
7537}
7538if (handler_non_value.Count() && !value) {
7539handler_non_value.class.remove('Hidden');
7540} else {
7541handler_non_value.class.add('Hidden');
7542}
7543let hidden_input = this.Element.children('.OpenerValue');
7544hidden_input.attr.set('value', value);
7545hidden_input.e.trigger('change');
7546this.Element.children('.OpenerSelect').attr.set('value', value);
7547let value_item = this.Element.Children('[data-value="' + value + '"]');
7548if (!value_item.class.has('Selected')) {
7549this.Element.Children('[data-value]').class.remove('Selected');
7550value_item.class.add('Selected');
7551}
7552};
7553this.Close = function(rapid)
7554{
7555if (rapid == undefined) rapid = false;
7556if (rapid) {
7557self.BeforeClose();
7558self.Element.class.remove('Opening');
7559self.Element.class.remove('Opened');
7560self.Element.class.remove('Closing');
7561self.PanelElement.css.remove('height');
7562//self.PanelElement.css.set('height', '0');
7563} else {
7564self.PanelElement.css.set('height', self.PanelElement.GetHeight() + 'px');
7565getComputedStyle(self.PanelElement.dom(0)).height;
7566self.BeforeClose();
7567self.Element.class.remove('Opening');
7568self.Element.class.remove('Opened');
7569self.Element.class.add('Closing');
7570self.PanelElement.css.set('height', '0');
7571}
7572};
7573this.Open = function(rapid)
7574{
7575if (rapid == undefined) rapid = false;
7576let res = self.BeforeOpen();
7577if (res === false) return;
7578let h = self.PanelElement.dom(0).scrollHeight + self.PanelElement.dom(0).offsetHeight;
7579if (rapid) {
7580self.Element.class.add('Opened');
7581self.PanelElement.css.set('height', h + 'px');
7582} else {
7583self.PanelElement.css.set('height', '0');
7584getComputedStyle(self.PanelElement.dom(0)).height;
7585self.Element.class.add('Opening');
7586self.PanelElement.css.set('height', h + 'px');
7587}
7588};
7589this.OpenIfNot = function()
7590{
7591if (!this.IsOpened()) this.Open();
7592};
7593this.IsOpened = function(allow_opening = true)
7594{
7595if (allow_opening == null) allow_opening = true;
7596if (self.Element.class.has('Opened')) return true;
7597if (allow_opening && self.Element.class.has('Opening')) return true;
7598return false;
7599};
7600this.Init();
7601};
7602GraceWeb.prototype.ScrollBar = function(g) {
7603var self = this;
7604this.G = g;
7605this.ScrollingPanel = g.children('.ScrollBarPanel').Select(0);
7606this.Scrollbar = g.children('.ScrollBar').SelectLast();
7607this.ScrollbarX = g.children('.ScrollBarX').SelectLast();
7608function Init()
7609{
7610if (self.ScrollingPanel) {
7611self.ScrollingPanel.e.scroll(function () {
7612self.SetBar();
7613if (self.ScrollbarX) self.SetBarX();
7614});
7615}
7616if (self.Scrollbar) {
7617self.Scrollbar.children('span').e.on('mousedown', function (el, e) {
7618document.draggedscrollbar = {
7619el: el,
7620barel: self.Scrollbar,
7621panelel: self.ScrollingPanel,
7622main_el: self.G,
7623eltop: el.css.get('top') ? parseInt(el.css.get('top')) : 0,
7624top: e.screenY + GraceW.children('body').scroll.get()
7625};
7626});
7627if (!self.IsContentScrollable()) {
7628self.G.class.add('NoScroll');
7629}
7630}
7631if (self.ScrollbarX) {
7632self.ScrollbarX.FindFirst('span').e.on('mousedown', function (el, e) {
7633document.draggedscrollbarX = {
7634el: el,
7635barel: self.ScrollbarX,
7636panelel: self.ScrollingPanel,
7637main_el: self.G,
7638elleft: el.css.get('left') ? parseInt(el.css.get('left')) : 0,
7639left: e.screenX + GraceW.children('body').scroll.GetHorizontal()
7640};
7641});
7642if (!self.IsContentScrollableX()) {
7643self.G.class.add('NoScrollX');
7644}
7645}
7646document.body.addEventListener('mouseleave', function(e) {
7647if (!document.draggedscrollbar) return;
7648self.SetScrollPosition(e.screenY);
7649});
7650document.body.addEventListener('mouseleave', function(e) {
7651if (!document.draggedscrollbarX) return;
7652self.SetScrollPositionX(e.screenX);
7653});
7654GraceW.children('body').e.on('mousemove', function(el, e) {
7655if (!document.draggedscrollbar) return;
7656self.SetScrollPosition(e.screenY);
7657return false;
7658});
7659GraceW.children('body').e.on('mousemove', function(el, e) {
7660if (!document.draggedscrollbarX) return;
7661self.SetScrollPositionX(e.screenX);
7662return false;
7663});
7664GraceW.children('body').e.on('mouseup', function(el, e) {
7665document.draggedscrollbar = undefined;
7666document.draggedscrollbarX = undefined;
7667});
7668window.addEventListener('mouseup', function(eL) {
7669document.draggedscrollbar = undefined;
7670document.draggedscrollbarX = undefined;
7671});
7672let observer = new MutationObserver(function(elements) {
7673self.SetScrollable();
7674});
7675observer.observe(self.G.dom(0), {
7676childList: true,
7677subtree: true,
7678//attributes: true
7679});
7680self.G.e.on('got-inside', function() {
7681self.SetScrollable();
7682});
7683let iv = self.G.f('InViewport');
7684}
7685Init();
7686};
7687GraceWeb.prototype.ScrollBar.prototype.touchChanged = false;
7688GraceWeb.prototype.ScrollBar.prototype.touchStartScroll = null;
7689GraceWeb.prototype.ScrollBar.prototype.touchY = null;
7690GraceWeb.prototype.ScrollBar.prototype.SetScrollPosition = function(y) {
7691var top = y + GraceW.children('body').scroll.get();
7692var diff = top - document.draggedscrollbar.top;
7693var old_top = document.draggedscrollbar.eltop;
7694var new_top = old_top + diff;
7695if (new_top < 0) new_top = 0;
7696var max_top = document.draggedscrollbar.barel.GetHeight() - document.draggedscrollbar.el.GetHeight();
7697if (new_top > max_top) new_top = max_top;
7698document.draggedscrollbar.el.css.set('top', new_top + 'px');
7699var si = document.draggedscrollbar.panelel;
7700let max_scroll = document.draggedscrollbar.main_el.f('ScrollBar').GetMaxScroll();
7701var perc = 100 / max_top * new_top;
7702var new_scroll = max_scroll / 100 * perc;
7703si.scroll.set(new_scroll);
7704};
7705GraceWeb.prototype.ScrollBar.prototype.SetScrollPositionX = function(y) {
7706var top = y + GraceW.children('body').scroll.GetHorizontal();
7707var diff = top - document.draggedscrollbarX.left;
7708var old_top = document.draggedscrollbarX.elleft;
7709var new_top = old_top + diff;
7710if (new_top < 0) new_top = 0;
7711var max_top = document.draggedscrollbarX.barel.GetWidth() - document.draggedscrollbarX.el.GetWidth();
7712if (new_top > max_top) new_top = max_top;
7713document.draggedscrollbarX.el.css.set('left', new_top + 'px');
7714var si = document.draggedscrollbarX.panelel;
7715let max_scroll = document.draggedscrollbarX.main_el.f('ScrollBar').GetMaxScrollX();
7716var perc = 100 / max_top * new_top;
7717var new_scroll = max_scroll / 100 * perc;
7718si.scroll.SetHorizontal(new_scroll);
7719};
7720GraceWeb.prototype.ScrollBar.prototype.SetScrollable = function() {
7721if (this.IsContentScrollable()) {
7722this.G.class.remove('NoScroll');
7723} else {
7724this.G.class.add('NoScroll');
7725}
7726if (this.IsContentScrollableX()) {
7727this.G.class.remove('NoScrollX');
7728} else {
7729this.G.class.add('NoScrollX');
7730}
7731};
7732GraceWeb.prototype.ScrollBar.prototype.IsContentScrollable = function()
7733{
7734if (!this.ScrollingPanel || !this.ScrollingPanel.Count()) return false;
7735var scroll = this.ScrollingPanel.dom(0).scrollTop;
7736this.ScrollingPanel.dom(0).scrollTop = 1000000000;
7737var max_scroll = this.ScrollingPanel.dom(0).scrollTop;
7738this.ScrollingPanel.dom(0).scrollTop = scroll;
7739if (!max_scroll) return false;
7740return true;
7741};
7742GraceWeb.prototype.ScrollBar.prototype.IsContentScrollableX = function()
7743{
7744if (!this.ScrollingPanel || !this.ScrollingPanel.Count()) return false;
7745var scroll = this.ScrollingPanel.dom(0).scrollLeft;
7746this.ScrollingPanel.dom(0).scrollLeft = 1000000000;
7747var max_scroll = this.ScrollingPanel.dom(0).scrollLeft;
7748this.ScrollingPanel.dom(0).scrollLeft = scroll;
7749if (!max_scroll) return false;
7750return true;
7751};
7752GraceWeb.prototype.ScrollBar.prototype.SetBar = function()
7753{
7754var scroll = this.ScrollingPanel.dom(0).scrollTop;
7755let max_scroll = this.GetMaxScroll();
7756var perc = 100 / max_scroll * scroll;
7757var bar_top = this.Scrollbar.GetHeight() - this.Scrollbar.children('span').GetHeight();
7758bar_top = bar_top / 100 * perc;
7759this.Scrollbar.children('span').css.set('top', bar_top + 'px');
7760}
7761GraceWeb.prototype.ScrollBar.prototype.SetBarX = function()
7762{
7763var scroll = this.ScrollingPanel.dom(0).scrollLeft;
7764let max_scroll = this.GetMaxScrollX();
7765var perc = 100 / max_scroll * scroll;
7766var bar_top = this.ScrollbarX.GetWidth() - this.ScrollbarX.FindFirst('span').GetWidth();
7767bar_top = bar_top / 100 * perc;
7768this.ScrollbarX.FindFirst('span').css.set('left', bar_top + 'px');
7769}
7770GraceWeb.prototype.ScrollBar.prototype.GetMaxScroll = function() {
7771let max = this.ScrollingPanel.dom(0).scrollHeight - this.G.GetHeight();
7772if (max < 0) return 0;
7773return max;
7774};
7775GraceWeb.prototype.ScrollBar.prototype.GetMaxScrollX = function() {
7776let max = this.ScrollingPanel.dom(0).scrollWidth - this.G.GetWidth();
7777if (max < 0) return 0;
7778return max;
7779};
7780function SeparatorInput(el, Settings)
7781{
7782var DefaultSettings = {
7783Suggesting: 0,
7784Query: '',
7785QueryParams: {}
7786};
7787var object = this;
7788object.El = el;
7789object.Settings = $.extend(DefaultSettings, Settings);
7790this.SeparatorRegexp = /[\t\,\n]/gm;
7791object.CheckText = function(e, finished){
7792if (finished == undefined) finished = false;
7793var html = object.El.find('[contenteditable]').clone();
7794html = html.text().replace(object.SeparatorRegexp, ';');
7795var parts = html.split(';');
7796if (!finished && parts.length < 2)
7797{
7798Ajax('Core/Controls/Separator.php', {type: 'search', query: object.Settings.Query, query_params: object.Settings.QueryParams, search: parts[0]}, function(data){
7799console.log(data);
7800});
7801return;
7802}
7803for (var i in parts)
7804{
7805parts[i] = $.trim(parts[i]);
7806if (parts[i].length == 0) continue;
7807object.El.find('.Tags').append('<span class="Tag">' + parts[i] + '<span class="Delete"></span></span>');
7808parts[i] = undefined;
7809}
7810var remains = '';
7811for (var i in parts)
7812{
7813if (parts[i] != undefined) remains += parts[i];
7814}
7815object.El.find('[contenteditable]').html(remains);
7816var tags_text = [];
7817object.El.find('.Tags .Tag').each(function(){
7818tags_text.push($(this).text());
7819});
7820object.El.attr('value', tags_text.join(';'));
7821object.SetTagsEvents();
7822};
7823object.SetTagsEvents = function(){
7824object.El.find('.Tags .Tag .Delete').Click(function(el){
7825el.parent('.Tag').remove();
7826});
7827};
7828object.El.keyup(object.CheckText);
7829object.El.find('.Tags').Click(function(){
7830object.El.find('[contenteditable]').focus();
7831});
7832object.El.find('.Tags .Tag').Click(function(el, e){
7833e.stopPropagation();
7834});
7835}
7836GraceWeb.prototype.ShortingText = function(g) {
7837let self = this;
7838this.EndOfLineEl;
7839this.ParentSelectorToMarkForFullText;
7840this.ClassToMarkFullTextParent;
7841this.LinesCount = 3;
7842this.SplitLongText = false;
7843this.Process = function() {
7844if (this.LinesCount > 0) {
7845g.each(function (el) {
7846self.CheckAndShorten(el);
7847});
7848} else {
7849g.each(function(el) {
7850self.ProcessChildren(el, el);
7851});
7852}
7853};
7854this.ProcessChildren = function(el, top_el) {
7855let children = el.DirectChildren();
7856if (children) {
7857children.each(function (ch) {
7858self.ProcessChildren(ch, top_el);
7859});
7860} else {
7861self.CheckAndShorten(el, top_el);
7862}
7863};
7864this.SetResizeProcessing = function() {
7865g.e.windowresize(function() {
7866self.Process();
7867setTimeout(function() {
7868self.Process();
7869}, 100);
7870})
7871};
7872this.CheckAndShorten = function(el, top_el) {
7873if (!this.LinesCount && el.offset().top - top_el.offset().top + el.GetHeight() <= top_el.GetHeight()) {
7874return;
7875}
7876let parent = this.ParentSelectorToMarkForFullText ? el.parent(this.ParentSelectorToMarkForFullText) : null;
7877let parent_class = this.ClassToMarkFullTextParent;
7878let eol;
7879let eol_from_html = false;
7880if (this.EndOfLineEl) {
7881eol = this.EndOfLineEl;
7882} else {
7883eol = el.children('.EndOfLine');
7884if (eol.Count()) {
7885eol = eol.SelectLast().clone();
7886eol_from_html = true;
7887el.children('.EndOfLine').remove();
7888eol.class.remove('Hidden');
7889} else {
7890eol = null;
7891}
7892}
7893let new_html = [];
7894let text = el.GetText().split(/\s/);
7895if (this.SplitLongText) {
7896let ntext = [];
7897for (let i in text) {
7898let w = text[i];
7899if (w.length > 20) {
7900w = w.split('');
7901let ccnt = 0;
7902let ww = '';
7903for (let c in w) {
7904ccnt++;
7905if (ccnt > 20) {
7906ntext.push(ww);
7907ccnt = 0;
7908ww = '';
7909}
7910ww += w[c];
7911}
7912if (ww.length > 0) ntext.push(ww);
7913} else {
7914ntext.push(w);
7915}
7916}
7917text = ntext;
7918}
7919for (let i in text) {
7920let w = text[i];
7921if (!w) continue;
7922let span = '<span>' + w + '</span>';
7923new_html.push(span);
7924}
7925el.SetHTML(new_html.join(' '));
7926let t;
7927let line = 0;
7928let stop_processing = false;
7929el.children('span').each(function(span) {
7930if (stop_processing) return;
7931let eol_copy;
7932if (eol) {
7933eol_copy = eol.clone();
7934span.AddBefore(eol_copy);
7935}
7936if (self.LinesCount > 0) {
7937if (self.ParentSelectorToMarkForFullText) {
7938el.parent(self.ParentSelectorToMarkForFullText).data.remove('current-rows');
7939} else {
7940el.data.remove('current-rows');
7941}
7942let span_top = span.dom(0).offsetTop;
7943if (t == undefined || t < span_top) {
7944t = span_top;
7945line++;
7946}
7947if (line > self.LinesCount) {
7948stop_processing = true;
7949if (parent && parent_class) parent.class.remove(parent_class);
7950let n = span.previous();
7951while ((n = n.next())) {
7952n.class.add('HideTheWord');
7953}
7954} else {
7955if (eol) eol_copy.remove();
7956if (parent && parent_class) parent.class.add(parent_class);
7957}
7958if (self.ParentSelectorToMarkForFullText) {
7959el.parent(self.ParentSelectorToMarkForFullText).data.set('current-rows', line);
7960} else {
7961el.data.set('current-rows', line);
7962}
7963} else {
7964let span_top = span.offset().top;
7965let off_top = span_top - top_el.offset().top;
7966span.css.set('display', 'inline-block');
7967let bottom = off_top + span.GetHeight();
7968let h = top_el.GetHeight();
7969if (bottom > h) span.class.add('HideTheWord');
7970span.css.remove('display');
7971}
7972});
7973if (eol && eol_from_html) {
7974eol.class.add('Hidden');
7975el.append(eol);
7976}
7977};
7978};
7979GraceWeb.prototype.SmoothScroll = function(g) {
7980let self = this;
7981this.StepPx = 20;
7982this.StepPxSlowest = 1;
7983this.StepPxChange = 0.3;
7984this.TimeoutTime = 5;
7985this.Timeout;
7986this.LastScroll;
7987this.StartScroll;
7988this.CurrentStepPx;
7989this.MiddleScroll;
7990this.ChangingDuringPx;
7991this.OffsetPx = 0; // stops on the element + this amount of pixels
7992this.GoToFirst = false;
7993this.ScrollingEl = GraceW;
7994this.Init = function() {
7995let self = this;
7996g.e.click(function(btn, e) {
7997if (!btn.attr.get('href')) return;
7998let url = btn.attr.get('href').trim().split('#');
7999if (url[0] && url[0] != location.pathname) return true;
8000url = '#' + url[1];
8001let target = self.ScrollingEl.children(url);
8002if (self.GoToFirst) target = target.Select(0);
8003self.GoToTarget(target);
8004if (target.Count() > 0) {
8005return false;
8006}
8007});
8008};
8009this.GoToTarget = function(target) {
8010GraceW.Children('html, body').css.set('scroll-behavior', 'auto');
8011self.StartScroll = this.ScrollingEl.scroll.get();
8012let diff = (target.offset().top + this.OffsetPx - self.StartScroll) / 2;
8013if (diff < 0) diff *= -1;
8014self.MiddleScroll = self.StartScroll + diff;
8015self.CurrentStepPx = self.StepPxSlowest;
8016self.LastScroll = null;
8017if (target.Count() > 0) {
8018self.ScrollTo(target.Select(0));
8019}
8020};
8021this.ScrollTo = function(target) {
8022//self.AnimateStep(target.offset().top + self.OffsetPx - this.ScrollingEl.offset().top, target.offset().top + self.OffsetPx > this.ScrollingEl.scroll.get());
8023self.AnimateStep(target);
8024};
8025this.AnimateStep = function(target, new_top, go_bottom)
8026{
8027let t_off = target.offset().top;
8028let scroll_top = this.ScrollingEl.scroll.get();
8029new_top = t_off + this.OffsetPx - this.ScrollingEl.offset().top;
8030go_bottom = t_off + this.OffsetPx > scroll_top;
8031let self = this;
8032let scroll = scroll_top;
8033if (scroll == self.LastScroll) {
8034GraceW.Children('html, body').css.remove('scroll-behavior');
8035return;
8036}
8037self.LastScroll = scroll;
8038if (scroll < self.MiddleScroll) {
8039if (self.CurrentStepPx != self.StepPx) {
8040self.ChangingDuringPx = scroll - self.StartScroll;
8041}
8042self.CurrentStepPx += self.StepPxChange;
8043if (self.CurrentStepPx > self.StepPx) self.CurrentStepPx = self.StepPx;
8044} else {
8045if (new_top - scroll <= self.ChangingDuringPx) {
8046self.CurrentStepPx -= self.StepPxChange;
8047if (self.CurrentStepPx < self.StepPxSlowest) self.CurrentStepPx = self.StepPxSlowest;
8048}
8049}
8050if ((go_bottom && scroll + self.CurrentStepPx > new_top) || (!go_bottom && scroll - self.CurrentStepPx < new_top)) {
8051scroll = new_top;
8052} else if (go_bottom) {
8053scroll += self.CurrentStepPx;
8054} else {
8055scroll -= self.CurrentStepPx;
8056}
8057scroll = Math.ceil(scroll);
8058this.ScrollingEl.scroll.set(scroll);
8059//if (GraceW.scroll.get() == scroll) GraceW.scroll.set(scroll + 1);
8060self.Timeout = setTimeout(function() {
8061self.ScrollingEl.scroll.set(scroll);
8062self.AnimateStep(target, new_top, go_bottom);
8063}, self.TimeoutTime);
8064};
8065this.Stop = function()
8066{
8067if (self.Timeout) {
8068clearTimeout(self.Timeout);
8069self.Timeout = null;
8070}
8071};
8072this.Init();
8073};
8074GraceWeb.prototype.Tabs = function(g) {
8075var self = this;
8076this.G = g;
8077this.Group = null;
8078this.Init = function() {
8079self.Group = g.attr.get('data-tab-group');
8080var items = this.GetAllTabItems();
8081if (!items) return;
8082GraceW.children('[data-tab-group="' + self.Group + '"][data-tab-target="' + g.attr.get('data-tab') + '"]').Hide();
8083if (g.data.get('tab-active') || g.attr.get('data-tab') == self.GetAllTabItems().Select(0).attr.get('data-tab')) {
8084self.CloseAllTabs();
8085this.OpenTab(true);
8086} else {
8087this.CloseTab();
8088}
8089this.SetEvents();
8090};
8091this.SetEvents = function() {
8092g.e.click(function(el, e) {
8093if (el.class.has('Disabled') || el.class.has('Active')) return false;
8094el.class.add('MarkedToOpen');
8095self.CloseAllTabs();
8096self.OpenTab();
8097let href = el.attr.get('href');
8098if (href == undefined) href = el.attr.get('data-href');
8099if (href != undefined) DynamicUrlChange(href);
8100el.class.remove('MarkedToOpen');
8101});
8102g.children('a').e.click(function(el, e) {
8103var tab = el.parents('[data-tab]');
8104if (tab.class.has('Disabled')) return false;
8105var href = el.attr.get('href');
8106if (href == undefined) href = el.attr.get('data-href');
8107if (href != undefined) {
8108DynamicUrlChange(href);
8109}
8110return false;
8111});
8112};
8113this.GetMaxIndexNumber = function() {
8114var max = 0;
8115var items = this.GetAllTabItems();
8116for (var i = 0; i < items.Count(); i++) {
8117var it = items.Select(i);
8118var index = parseInt(it.attr.get('data-tab-index'));
8119if (index > max) max = index;
8120}
8121return max;
8122};
8123this.AddTabItem = function(item) {
8124item = this.SetTabItem(item, this.GetMaxIndexNumber() + 1);
8125};
8126this.DisableTab = function(index) {
8127var tab = this.GetTabByIndex(index);
8128if (tab.class.has('Disabled')) return false;
8129tab.e.trigger('before-tab-disable');
8130tab.class.add('Disabled');
8131tab.e.trigger('after-tab-disable');
8132};
8133this.ActivateTab = function(index) {
8134var tab = this.GetTabByIndex(index);
8135if (!tab.class.has('Disabled')) return false;
8136tab.e.trigger('before-tab-activation');
8137tab.class.remove('Disabled');
8138tab.e.trigger('after-tab-activation');
8139};
8140this.GetTabByIndex = function(index) {
8141return self.GetAllTabItems().Select(index);
8142};
8143this.OpenTab = function(force) {
8144var target = GraceW.children('[data-tab-group="' + self.Group + '"][data-tab-target="' + g.attr.get('data-tab') + '"]');
8145if (g.class.has('Active') && !force) return false;
8146g.e.trigger('before-tab-open');
8147g.class.add('Active');
8148target.Display();
8149g.e.trigger('after-tab-open');
8150};
8151this.CloseTab = function(force) {
8152var target = GraceW.children('[data-tab-group="' + self.Group + '"][data-tab-target="' + g.attr.get('data-tab') + '"]');
8153if (!g.class.has('Active') && !force) return false;
8154g.e.trigger('before-tab-close');
8155g.class.remove('Active');
8156target.Hide();
8157g.e.trigger('after-tab-close');
8158};
8159this.GetAllTabItems = function() {
8160if (!self.Group) return g;
8161return GraceW.children('[data-tab-group="' + self.Group + '"]');
8162};
8163this.CloseAllTabs = function() {
8164var items = this.GetAllTabItems();
8165for (var i = 0; i < items.Count(); i++) {
8166var tab = items.Select(i);
8167var target = GraceW.children('[data-tab-group="' + self.Group + '"][data-tab-target="' + tab.attr.get('data-tab') + '"]');
8168if (tab.class.has('Active')) {
8169tab.e.trigger('before-tab-close');
8170tab.class.remove('Active');
8171target.Hide();
8172tab.e.trigger('after-tab-close');
8173}
8174}
8175};
8176};
8177g.e.domloaded(function() {
8178var tabs_blocks = g.children('[data-tab]');
8179tabs_blocks.each(function(tab) {
8180if (!tab.data.get('tab-init') || (tab.data.get('tab-init') == 'auto' || tab.data.get('tab-init') == 'force')) {
8181let tabs = tab.f('Tabs');
8182tabs.Init();
8183}
8184});
8185});
8186GraceWeb.prototype.TimeSelector = function(g)
8187{
8188let self = this;
8189this.ActualTime = new Date();
8190this.MinutesDelay = 5; // 1, 2, 5, 10, 15, 30
8191this.InactiveTimes = []; // arrays of inactive times, e.g. [[12, 30], 15, [18, 20]] for inactive times 12:30, complete hour of 15 and 18:20
8192this.OnChange = function(hour, minute){};
8193this.HourEl = g.children('[data-lookup="Hour"]').Select(0).clone();
8194this.MinuteEl = g.children('[data-lookup="Minute"]').Select(0).clone();
8195this.Init = function()
8196{
8197this.WriteHTML();
8198this.SetGlobalEvents();
8199};
8200this.SetGlobalEvents = function()
8201{
8202};
8203this.SetHoursEvents = function()
8204{
8205g.children('[data-lookup="Hour"]:not(.Inactive)').e.click(function(el){
8206self.ActualTime.setHours(el.GetText());
8207self.SetTextTime(el.GetText());
8208self.WriteMinutes(self.ActualTime);
8209self.OnChange(self.ActualTime.getHours(), self.ActualTime.getMinutes());
8210});
8211};
8212this.SetMinutesEvents = function()
8213{
8214g.children('[data-lookup="Minute"]:not(.Inactive)').e.click(function(el){
8215self.ActualTime.setMinutes(el.GetText());
8216self.SetTextTime(null, el.GetText());
8217self.OnChange(self.ActualTime.getHours(), self.ActualTime.getMinutes());
8218});
8219};
8220this.SetTextTime = function(new_hour, new_minute)
8221{
8222new_hour = parseInt(new_hour);
8223new_minute = parseInt(new_minute);
8224let time = '';
8225time = time.replace('.', ':').replace('-', ':').replace('/', ':');
8226time = time.split(':');
8227let hour = parseInt(time[0]);
8228if (time[1] == undefined) time[1] = 0;
8229let minute = parseInt(time[1]);
8230if (isNaN(hour) || hour < 0 || hour > 23) hour = self.ActualTime.getHours();
8231if (isNaN(minute) || minute < 0 || minute > 59) minute = self.ActualTime.getMinutes();
8232if (new_hour != undefined && new_hour != null && new_hour >= 0 && new_hour < 24) hour = new_hour;
8233if (new_minute != undefined && new_minute != null && new_minute >= 0 && new_minute < 60) minute = new_minute;
8234};
8235this.GetFormattedTime = function(hours, minutes)
8236{
8237if (hours.toString().length == 1) hours = '0' + hours;
8238if (minutes.toString().length == 1) minutes = '0' + minutes;
8239return hours + ':' + minutes;
8240};
8241this.GetFormattedTimeFromDate = function(time)
8242{
8243return self.GetFormattedTime(time.getHours(), time.getMinutes());
8244};
8245this.WriteHTML = function()
8246{
8247self.WriteHours(self.ActualTime);
8248self.WriteMinutes(self.ActualTime);
8249};
8250this.WriteHours = function(time)
8251{
8252let hours_el = g.children('[data-lookup="Hours"]');
8253hours_el.SetHTML('');
8254for (let i = 0; i <= 23; i++) {
8255let h = this.HourEl.clone();
8256h.SetHTML(i);
8257for (let ho in self.InactiveTimes) {
8258if (self.InactiveTimes[ho] == i) h.class.add('Inactive');
8259}
8260hours_el.append(h);
8261}
8262self.SetHoursEvents();
8263};
8264this.WriteMinutes = function(time)
8265{
8266let minutes_el = g.children('[data-lookup="Minutes"]');
8267minutes_el.SetHTML('');
8268let i = 0;
8269for (let m = 0; m <= 60; m = m + self.MinutesDelay) {
8270let el = this.MinuteEl.clone();
8271el.SetHTML(m);
8272for (let im in self.InactiveTimes) {
8273if (self.InactiveTimes[im][0] == time.getHours() && self.InactiveTimes[im][1] == m) el.class.add('Inactive');
8274}
8275minutes_el.append(el);
8276i++;
8277}
8278self.SetMinutesEvents();
8279};
8280self.Init();
8281};
8282GraceWeb.prototype.Tooltip = function(g) {
8283let self = this;
8284this.TooltipBox = null;
8285this.Float = true;
8286this.Delay = 0;
8287this.TooltipByLeftCorner = true;
8288this.BodyTB = null;
8289this.Timeout;
8290this.Init = function() {
8291g.e.on('mouseenter', self.ShowTooltip);
8292g.e.on('mouseleave', function(el, e) {
8293self.HideTooltip(el);
8294e.stopped = true;
8295return false;
8296});
8297if (self.Float) g.e.on('mousemove', function(g, e){ self.MouseMove(g, e); });
8298};
8299this.MouseMove = function(g, e)
8300{
8301if (self.BodyTB != null) {
8302self.BodyTB.Display();
8303self.BodyTB.css.set('top', (e.clientY + GraceW.scroll.get() + 10) + 'px');
8304if (self.TooltipByLeftCorner) {
8305self.BodyTB.css.set('left', (e.clientX + 10) + 'px');
8306} else {
8307self.BodyTB.css.set('left', (e.clientX - self.BodyTB.GetWidth() - 10) + 'px');
8308}
8309}
8310};
8311this.ShowTooltip = function(g, e) {
8312if (self.TooltipBox == null) {
8313self.TooltipBox = g.children('.TooltipBox');//.clone();
8314if (!self.TooltipBox.Count()) self.TooltipBox = g.NewElementFromHTML('<div class="TooltipBox"></div>');
8315if (g.data.get('tooltip')) self.TooltipBox.SetHTML(g.data.get('tooltip'));
8316}
8317//var body = new GraceWeb('body');
8318let body = GraceW.children('body');
8319self.BodyTB = self.TooltipBox.clone();
8320body.append(self.BodyTB);
8321self.BodyTB.Display();
8322self.BodyTB.css.set('display', 'block');
8323if (e.clientY == null) {
8324self.BodyTB.css.set('top', (g.offset().top + g.css.get('height') + 10) + 'px');
8325self.BodyTB.css.set('left', (g.offset().left + g.css.get('width') + 10) + 'px');
8326} else {
8327self.BodyTB.css.set('top', (e.clientY + GraceW.scroll.get() + 10) + 'px');
8328self.BodyTB.css.set('left', (e.clientX + 10) + 'px');
8329}
8330self.BodyTB.e.on('mouseenter', function(){
8331clearTimeout(self.Timeout);
8332self.Timeout = null;
8333});
8334self.BodyTB.e.on('mouseleave', function(){
8335self.HideTooltip(g.parents('.Tooltip'));
8336});
8337};
8338this.HideTooltip = function(e, force) {
8339if (force == undefined) force = false;
8340if (!force && self.Delay > 0) {
8341self.Timeout = setTimeout(function(){
8342self.HideTooltip(e, true);
8343}, self.Delay);
8344return;
8345}
8346self.Timeout = null;
8347if (self.BodyTB != null) {
8348self.BodyTB.remove();
8349self.BodyTB = null;
8350}
8351};
8352this.Destroy = function() {
8353g.e.cancel('mouseenter', self.ShowTooltip);
8354g.e.cancel('mouseleave', self.HideTooltip);
8355g.e.trigger('tooltip-destroyed');
8356};
8357return this;
8358};
8359g.e.domloaded(function() {
8360InitTooltips();
8361});
8362g.e.domadded(function() {
8363InitTooltips();
8364});
8365function InitTooltips()
8366{
8367g.children('.Tooltip').each(function(el) {
8368let t = el.f('Tooltip');
8369if (el.data.get('by-right')) {
8370t.TooltipByLeftCorner = false;
8371}
8372t.Init();
8373});
8374}
8375function InfoWindow(g)
8376{
8377this.G = g;
8378this.allow_close = true;
8379this.ClearAfterClose = false;
8380this.AllowClose = function(set)
8381{
8382this.allow_close = set ? true : false;
8383if (this.allow_close) {
8384this.G.children('.Close').class.remove('Hidden');
8385} else {
8386this.G.children('.Close').class.add('Hidden');
8387}
8388}
8389this.View = function(view)
8390{
8391this.G.children('[data-view]').class.add('Hidden');
8392this.G.children('[data-view="' + view + '"]').class.remove('Hidden');
8393}
8394this.Open = function()
8395{
8396let dialog = this.G;
8397dialog.class.add('Activated');
8398this.SetEvents();
8399}
8400this.Close = function()
8401{
8402let self = this;
8403this.G.class.add('Closing');
8404setTimeout(function() {
8405self.G.class.remove('Activated');
8406self.G.class.remove('Closing');
8407if (self.ClearAfterClose) {
8408let views = self.G.children('[data-view]');
8409if (!views.Count()) views = self.G.children('[data-lookup="DialogContent"]')
8410views.SetHTML('');
8411}
8412}, 1000);
8413}
8414this.SetEvents = function()
8415{
8416let self = this;
8417this.G.children('.Close').e.click(function() {
8418if (!self.allow_close) return;
8419self.Close();
8420});
8421this.G.e.mousewheel(function() {
8422//return false;
8423});
8424this.G.e.on('touchmove', function() {
8425//return false;
8426});
8427}
8428}
8429function PastingTable(g)
8430{
8431this.G = g;
8432this.Pasting;
8433this.RowNo = 1;
8434this.KeepEmptyRow = true;
8435this.Init();
8436this.GetOrCreateEmptyRow();
8437}
8438PastingTable.prototype.Init = function() {
8439//this.Pasting = this.G.Children('input').f('ObjectsPasting');
8440this.Pasting = this.G.f('ObjectsPasting');
8441this.SetEvents();
8442};
8443PastingTable.prototype.SetEvents = function() {
8444let self = this;
8445this.G.Children('input').e.on('dropped', function(el, e) {
8446self.DistributePastedContent(el.parent('.PastingTableRow'), self.Pasting.GetText());
8447return false;
8448});
8449if (this.KeepEmptyRow) {
8450this.G.Children('input').e.on('change', function(el) {
8451let row = el.parent('.PastingTableRow');
8452if (!row.NextAll('.PastingTableRow').Count()) {
8453self.AddRow();
8454}
8455});
8456}
8457};
8458PastingTable.prototype.AddRow = function(add_after_row) {
8459let row = add_after_row ? add_after_row.clone() : this.G.Children('.PastingTableRow').Select(0).clone();
8460let inputs = row.Children('input');
8461inputs.attr.set('value', '');
8462let no = this.RowNo;
8463inputs.each(function(el) {
8464if (el.data.get('name')) {
8465el.attr.set('name', el.data.get('name').replace('%index%', no));
8466}
8467});
8468this.RowNo = this.RowNo + 1;
8469if (add_after_row) {
8470add_after_row.AddAfter(row);
8471} else {
8472this.G.append(row);
8473}
8474if (this.KeepEmptyRow) {
8475let self = this;
8476row.Children('input').e.on('change', function(el) {
8477let row = el.parent('.PastingTableRow');
8478if (!row.NextAll('.PastingTableRow').Count()) {
8479self.AddRow();
8480}
8481});
8482}
8483row.e.triggers.domadded();
8484return row;
8485};
8486PastingTable.prototype.GetOrCreateEmptyRow = function() {
8487let found_row = null;
8488this.G.Children('.PastingTableRow').each(function(row) {
8489let empty = true;
8490row.Children('input').each(function(input) {
8491let val = input.attr.get('value');
8492if (val) val = val.trim();
8493if (val) {
8494empty = false;
8495return false;
8496}
8497});
8498if (empty) {
8499found_row = row;
8500return false;
8501}
8502});
8503if (found_row) {
8504if (!found_row.NextAll('.PastingTableRow').Count()) {
8505this.AddRow();
8506}
8507return found_row;
8508}
8509found_row = this.AddRow();
8510this.AddRow();
8511return found_row;
8512};
8513PastingTable.prototype.DistributePastedContent = function(first_row, c
8513ontent) {
8514let row_el = first_row;
8515content = content.split("\r\n");
8516for (let i in content) {
8517let row = content[i].trim();
8518if (!row) continue;
8519row = row.split("\t");
8520let k = 0;
8521row_el.Children('input').each(function(input) {
8522let val = row[k] ? row[k].trim() : '';
8523if (input.attr.get('type') == 'checkbox') {
8524if (val === '1') {
8525input.attr.set('checked', true);
8526k++;
8527} else if (val === '0') {
8528input.attr.set('checked', false);
8529k++;
8530}
8531} else {
8532input.attr.set('value', val);
8533k++;
8534}
8535});
8536row_el = row_el.NextAll('.PastingTableRow').Select(0);
8537if (!row_el) row_el = this.AddRow();
8538}
8539};
8540GraceWeb.prototype.SwipeActions = function(g)
8541{
8542this.G = g;
8543this.SwipeActiveClass = 'EmergeSwipeActions';
8544this.SwipeFromLeftClass = 'EmergeLeft';
8545this.SwipeFromRightClass = 'EmergeRight';
8546this.MouseOnActionsClass = 'MouseOnActions';
8547this.ActionActivated = function() {};
8548this.SetEvents();
8549}
8550GraceWeb.prototype.SwipeActions.prototype.SetEvents = function()
8551{
8552let self = this;
8553this.G.each(function(el) {
8554el.e.on('mousemove', function(el, e) {
8555return self.MouseOver(el, e);
8556});
8557el.e.on('mouseleave', function(el, e) {
8558return self.MouseOut(el, e);
8559});
8560el.children('.SwipeActions').e.on('mouseenter', function(el_actions, e) {
8561return self.MouseEntersSwipeActions(el_actions, el, e);
8562});
8563el.children('.SwipeActions').e.on('mouseleave', function(el_actions, e) {
8564return self.MouseLeavesSwipeActions(el_actions, el, e);
8565});
8566el.e.on('touchmove', function(el, e) {
8567return self.TouchMove(el, e);
8568});
8569el.e.on('touchend', function(el, e) {
8570return self.TouchEnd(el, e);
8571});
8572});
8573}
8574GraceWeb.prototype.SwipeActions.prototype.TouchEnd = function(el, e)
8575{
8576el.class.remove('NoTransition');
8577el.children('.SwipeActionsRow').css.remove('left');
8578el.children('.LeftActions, .RightActions').css.remove('width');
8579el.children('.SwipeActions .Activated').class.remove('Activated');
8580el.data.remove('touch-left');
8581return false;
8582}
8583GraceWeb.prototype.SwipeActions.prototype.TouchMove = function(el, e)
8584{
8585let touch_x = e.changedTouches[0].clientX;
8586let data_left = el.data.get('touch-left');
8587if (!data_left) {
8588data_left = touch_x;
8589el.data.set('touch-left', data_left);
8590} else {
8591data_left = parseInt(data_left);
8592}
8593let diff = touch_x - data_left;
8594el.class.add('NoTransition');
8595el.children('.SwipeActionsRow').css.set('left', diff + 'px');
8596el.children('.LeftActions').css.set('width', diff + 'px');
8597el.children('.RightActions').css.set('width', (diff * -1) + 'px');
8598let left_action = el.children('.LeftActions .Action');
8599let right_action = el.children('.RightActions .Action');
8600let action;
8601if (diff > 200 && left_action.Count() == 1) {
8602action = left_action;
8603} else if (diff < -200 && right_action.Count() == 1) {
8604action = right_action;
8605}
8606if (action && !action.class.has('Activated')) {
8607action.class.add('Activated');
8608this.ActionActivated(action);
8609}
8610//if (diff > 10 || diff < -10) return false;
8611//return false;
8612}
8613GraceWeb.prototype.SwipeActions.prototype.MouseEntersSwipeActions = function(el, main_el, e)
8614{
8615main_el.class.add(this.MouseOnActionsClass);
8616}
8617GraceWeb.prototype.SwipeActions.prototype.MouseLeavesSwipeActions = function(el, main_el, e)
8618{
8619main_el.class.remove(this.MouseOnActionsClass);
8620}
8621GraceWeb.prototype.SwipeActions.prototype.MouseOver = function(el, e)
8622{
8623let cursor_x = e.clientX - el.offset().left;
8624let width = el.GetWidth();
8625let cl;
8626if (cursor_x < width / 2) {
8627cl = this.SwipeFromLeftClass;
8628if (el.class.has(this.SwipeFromRightClass)) el.class.remove(this.SwipeFromRightClass);
8629} else {
8630cl = this.SwipeFromRightClass;
8631if (el.class.has(this.SwipeFromLeftClass)) el.class.remove(this.SwipeFromLeftClass);
8632}
8633el.class.add(cl);
8634el.class.add(this.SwipeActiveClass);
8635}
8636GraceWeb.prototype.SwipeActions.prototype.MouseOut = function(el)
8637{
8638el.class.remove(this.SwipeActiveClass);
8639el.class.remove(this.SwipeFromLeftClass);
8640el.class.remove(this.SwipeFromRightClass);
8641el.class.remove(this.MouseOnActionsClass);
8642}
8643const VALID_EMPTY = 1;
8644const VALID_NUMBER = 2;
8645const VALID_EMAIL = 3;
8646const VALID_SHORT = 4;
8647const VALID_LONG = 5;
8648const VALID_DUPLICATE = 6;
8649const VALID_PWD_DUPLI = 7;
8650const VALID_SMALL = 8;
8651const VALID_BIG = 9;
8652function IsValidNumber(str)
8653{
8654return /[0-9]/.test(str);
8655}
8656function IsValidEmail(str)
8657{
8658let regexp = /^[a-zA-Z0-9_\-\.]{1,}\@[a-zA-Z0-9_\-\.]{1,}\.[a-zA-Z0-9]{1,}$/;
8659return regexp.test(str);
8660}
8661g.children('body').class.add('PageLoaded');
8662g.e.domloaded(function() {
8663if (GraceWeb.CustomMediaLoading) return;
8664let images = g.children('[data-image], .EmbedLink');
8665images.e.on('got-inside', function(el) {
8666el.e.cancel('got-inside');
8667if (el.data.get('image')) {
8668DisplayImages(el);
8669} else if (el.class.has('EmbedLink')) {
8670let link = el.f('EmbedLink');
8671let iframe;
8672if (el.data.get('link')) {
8673iframe = link.BuildEmbed(el.data.get('link'), true);
8674} else {
8675iframe = link.BuildEmbedFromElement(el, true);
8676}
8677el.append(iframe);
8678}
8679});
8680images.f('InViewport');
8681});
8682g.e.domadded(function(g) {
8683if (GraceWeb.CustomMediaLoading) return;
8684let in_viewport;
8685let images = g.Children('[data-image], .EmbedLink');
8686images.e.on('got-inside', function(el) {
8687if (in_viewport) in_viewport.RemoveFromWatching(el);
8688if (el.data.get('image')) {
8689DisplayImages(el);
8690} else if (el.class.has('EmbedLink')) {
8691let link = el.f('EmbedLink');
8692let iframe;
8693if (el.data.get('link')) {
8694iframe = link.BuildEmbed(el.data.get('link'), true);
8695} else {
8696iframe = link.BuildEmbedFromElement(el, true);
8697}
8698el.append(iframe);
8699}
8700});
8701in_viewport = images.f('InViewport', true);
8702});
8703g.children('[data-type="DateTime"] input').e.focus(function(el) {
8704let d = g.children('.DateTimePanel');
8705d.class.add('Opened');
8706let calendar = d.children('.Calendar').f('Calendar');
8707if (el.data.get('min-date')) calendar.MinDate = new Date(parseInt(el.data.get('min-date')));
8708if (el.data.get('max-date')) calendar.MaxDate = new Date(parseInt(el.data.get('max-date')));
8709if (!/\/en\//.test(location.href)) {
8710calendar.DaysText = ['Po', 'Út', 'St', 'Čt', 'Pá', 'So', 'Ne'];
8711calendar.MonthsText = ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec'];
8712}
8713calendar.Init();
8714calendar.AfterChoose = function(date) {
8715FillInput();
8716el.dom(0).blur();
8717};
8718let time = d.children('.TimeSelector').f('TimeSelector');
8719if (el.data.get('inactive-hours')) {
8720time.InactiveTimes = JSON.parse(el.data.get('inactive-hours'));
8721time.WriteHTML();
8722}
8723time.OnChange = function(hour, minute) {
8724FillInput();
8725el.dom(0).blur();
8726};
8727function FillInput()
8728{
8729let date = calendar.CurrentDate;
8730date.setHours(time.ActualTime.getHours());
8731date.setMinutes(time.ActualTime.getMinutes());
8732let d = date.getDate() + '.' + (date.getMonth() + 1) + '.' + date.getFullYear() + ' ' + time.GetFormattedTime(date.getHours(), date.getMinutes());
8733el.attr.set('value', d);
8734el.data.set('timestamp', date.getTime());
8735}
8736g.children('body').e.on(['click', 'touchstart', 'touchend', 'focusin'], function(el, e) {
8737let target = new GraceWeb(e.target);
8738if (target.data.get('type') != 'DateTime' && !target.parent('[data-type="DateTime"]')) {
8739d.class.remove('Opened');
8740}
8741});
8742});
8743g.children('[data-type="Date"] input').e.focus(function(el) {
8744let d = g.children('.CalendarPanel');
8745d.class.add('Opened');
8746let calendar = d.children('.Calendar').f('Calendar');
8747if (el.data.get('min-date')) calendar.MinDate = new Date(parseInt(el.data.get('min-date')));
8748if (el.data.get('max-date')) calendar.MaxDate = new Date(parseInt(el.data.get('max-date')));
8749if (!/\/en\//.test(location.href)) {
8750calendar.DaysText = ['Po', 'Út', 'St', 'Čt', 'Pá', 'So', 'Ne'];
8751calendar.MonthsText = ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec'];
8752}
8753calendar.Init();
8754calendar.AfterChoose = function(date) {
8755FillInput();
8756el.dom(0).blur();
8757};
8758function FillInput()
8759{
8760let date = calendar.CurrentDate;
8761let dat = date.getDate() + '.' + (date.getMonth() + 1) + '.' + date.getFullYear();
8762el.attr.set('value', dat);
8763el.data.set('timestamp', date.getTime());
8764d.class.remove('Opened');
8765}
8766g.children('body').e.on(['click', 'touchstart', 'touchend', 'focusin'], function(el, e) {
8767let target = new GraceWeb(e.target);
8768if (target.data.get('type') != 'Date' && !target.parent('[data-type="Date"]')) {
8769d.class.remove('Opened');
8770}
8771});
8772});
8773g.children('.Calendar').data.set('init-calendar', 'no');
8774g.children('form').each(function(f) {
8775let form = f.f('Form');
8776form.Ajax.SuccessFnc = function(data) {
8777let div = g.NewElementFromHTML('<div>' + data.success + '</div>');
8778form.Form.append(div);
8779form.Form.class.add('FormSuccessful');
8780};
8781});
8782g.e.domloaded(function() {
8783let block = g.children('[data-type="LastNews"]');
8784block.children('.Item').e.click(function(item) {
8785if (!item.PreviousAll('.Item').Count()) return;
8786let first_news = block.children('.Item').Select(0);
8787first_news.SetHTML(item.GetHTML());
8788});
8789});
8790g.e.domloaded(function() {
8791g.children('.Video .Overlay, .Video .Play').e.click(function(el) {
8792let video = el.parent('.Video');
8793video.children('.Overlay, .Play').remove();
8794let iframe = g.NewElementFromHTML('<iframe width="100%" height="100%" src="' + video.data.get('youtube-link') + '?autoplay=1"></iframe>');
8795video.prepend(iframe);
8796});
8797});
8798g.e.domloaded(function() {
8799document.getElementById('MobileMenuBtn').onclick = function(){
8800this.__toggle=!this.__toggle;
8801var target=document.querySelector('.ModulesPosition[data-position="Menu"]');
8802if(this.__toggle) {
8803target.style.height=target.scrollHeight+"px";
8804} else {
8805target.style.height=0;
8806}
8807};
8808g.children('header nav a').e.click(function() {
8809var target=document.querySelector('.ModulesPosition[data-position="Menu"]');
8810target.style.height=0;
8811});
8812let images = g.children('[data-image]');
8813images.e.on('got-inside', function(el) {
8814el.e.cancel('got-inside');
8815DisplayImages(el);
8816});
8817images.f('InViewport');
8818g.children('[href^="#"]').f('SmoothScroll');
8819});
8820let header = g.children('header').Select(0);
8821g.e.PageScroll(function() {
8822PageScroll();
8823});
8824PageScroll();
8825function PageScroll()
8826{
8827header.css.set('height', '1000px');
8828let max_height = header.GetHeight();
8829header.css.set('height', '0');
8830let min_height = header.GetHeight();
8831let scroll = g.scroll.get();
8832let height = max_height - scroll;
8833if (height < 0) height = 0;
8834header.css.set('height', height + 'px');
8835height = header.GetHeight();
8836header.css.set('line-height', height + 'px');
8837header.children('nav a, #Logo, [data-position="Menu"] .Module.ModuleV
8837ariants ul li a').css.set('line-height', height + 'px');
8838g.children('.ModulesPosition[data-position="Menu"]').css.set('top', (height - 5) + 'px');
8839max_height -= min_height;
8840height -= min_height;
8841let perc = 100 / max_height * height;
8842perc = 30 - (30 / 100 * perc);
8843perc = 100 - perc;
8844header.children('#Logo img').css.set('width', perc + '%');
8845}
8846g.e.windowresize(PageScroll);
8847g.e.triggers.domadded();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.