alchemymvc 1.3.7 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Breadcrumb class
|
|
3
|
+
*
|
|
4
|
+
* @constructor
|
|
5
|
+
*
|
|
6
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
7
|
+
* @since 1.3.8
|
|
8
|
+
* @version 1.3.8
|
|
9
|
+
*
|
|
10
|
+
* @param {String} input
|
|
11
|
+
*/
|
|
12
|
+
const Breadcrumb = Function.inherits('Alchemy.Base', function Breadcrumb(input) {
|
|
13
|
+
|
|
14
|
+
this.trails = [];
|
|
15
|
+
|
|
16
|
+
if (input) {
|
|
17
|
+
this.addTrail(input);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get the number of trails
|
|
23
|
+
*
|
|
24
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
25
|
+
* @since 1.3.8
|
|
26
|
+
* @version 1.3.8
|
|
27
|
+
*
|
|
28
|
+
* @return {Number}
|
|
29
|
+
*/
|
|
30
|
+
Breadcrumb.setProperty(function length() {
|
|
31
|
+
return this.trails.length;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Add a breadcrumb trail
|
|
36
|
+
*
|
|
37
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
38
|
+
* @since 1.3.8
|
|
39
|
+
* @version 1.3.8
|
|
40
|
+
*
|
|
41
|
+
* @param {String} input
|
|
42
|
+
*/
|
|
43
|
+
Breadcrumb.setMethod(function addTrail(input) {
|
|
44
|
+
|
|
45
|
+
let trails;
|
|
46
|
+
|
|
47
|
+
if (!input) {
|
|
48
|
+
input = '';
|
|
49
|
+
} else if (typeof input == 'object') {
|
|
50
|
+
if (input instanceof Breadcrumb) {
|
|
51
|
+
trails = input.trails;
|
|
52
|
+
} else if (input.nodeType === 1) {
|
|
53
|
+
// Simple way to see if it's an HTMLElement
|
|
54
|
+
|
|
55
|
+
let element = input;
|
|
56
|
+
input = '';
|
|
57
|
+
|
|
58
|
+
let crumb = element.getAttribute('data-breadcrumb');
|
|
59
|
+
|
|
60
|
+
if (crumb) {
|
|
61
|
+
input = crumb;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
crumb = element.getAttribute('data-breadcrumbs');
|
|
65
|
+
|
|
66
|
+
if (crumb) {
|
|
67
|
+
input += ' ' + crumb;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!trails) {
|
|
73
|
+
// Split the string why whitespaces
|
|
74
|
+
trails = input.trim().split(/\s+|\|+/);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (trails?.length) {
|
|
78
|
+
for (let trail of trails) {
|
|
79
|
+
|
|
80
|
+
if (!trail) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// The trail has to end with a dot
|
|
85
|
+
if (!trail.endsWith('.')) {
|
|
86
|
+
trail += '.';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
this.trails.push(trail);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Do these 2 breadcrumbs match loosely?
|
|
96
|
+
*
|
|
97
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
98
|
+
* @since 1.3.8
|
|
99
|
+
* @version 1.3.8
|
|
100
|
+
*
|
|
101
|
+
* @param {Alchemy.Breadcrumb} other
|
|
102
|
+
*/
|
|
103
|
+
Breadcrumb.setMethod(function matches(other) {
|
|
104
|
+
return this.matchLevel(other) > 0;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* What leven of match is there between these 2 breadcrumbs?
|
|
109
|
+
*
|
|
110
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
111
|
+
* @since 1.3.8
|
|
112
|
+
* @version 1.3.8
|
|
113
|
+
*
|
|
114
|
+
* @param {Alchemy.Breadcrumb} other
|
|
115
|
+
*
|
|
116
|
+
* @return {Number} 1 for a strict match, 2 for a loose match
|
|
117
|
+
*/
|
|
118
|
+
Breadcrumb.setMethod(function matchLevel(other) {
|
|
119
|
+
|
|
120
|
+
if (!other || !this.trails.length) {
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!(other instanceof Breadcrumb)) {
|
|
125
|
+
other = new Breadcrumb(other);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let their_trail,
|
|
129
|
+
our_trail;
|
|
130
|
+
|
|
131
|
+
for (our_trail of this.trails) {
|
|
132
|
+
for (their_trail of other.trails) {
|
|
133
|
+
// Strict matches are always true
|
|
134
|
+
if (our_trail == their_trail) {
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (our_trail.startsWith(their_trail)) {
|
|
139
|
+
return 2;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return 0;
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Turn it into a string
|
|
149
|
+
*
|
|
150
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
151
|
+
* @since 1.3.8
|
|
152
|
+
* @version 1.3.8
|
|
153
|
+
*/
|
|
154
|
+
Breadcrumb.setMethod(function toString() {
|
|
155
|
+
return this.trails.join(' ');
|
|
156
|
+
});
|
|
@@ -147,14 +147,24 @@ Router.setMethod(function applyDirective(element, name, options) {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
let breadcrumb = config.breadcrumb;
|
|
151
|
+
|
|
152
|
+
if (options.breadcrumb) {
|
|
153
|
+
if (!breadcrumb) {
|
|
154
|
+
breadcrumb = options.breadcrumb;
|
|
155
|
+
} else {
|
|
156
|
+
breadcrumb += ' ' + options.breadcrumb;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (config.breadcrumb || options.breadcrumb) {
|
|
161
|
+
let link_breadcrumb = this.getTrail(name, {...params}, options);
|
|
152
162
|
element.setAttribute('data-breadcrumb', link_breadcrumb);
|
|
153
163
|
|
|
154
164
|
if (this.renderer && link_breadcrumb) {
|
|
155
|
-
let page_breadcrumb = this.renderer.internal('breadcrumb');
|
|
165
|
+
let page_breadcrumb = new Classes.Alchemy.Breadcrumb(this.renderer.internal('breadcrumb'));
|
|
156
166
|
|
|
157
|
-
if (page_breadcrumb
|
|
167
|
+
if (page_breadcrumb.matches(link_breadcrumb)) {
|
|
158
168
|
|
|
159
169
|
if (element.parentElement) {
|
|
160
170
|
// @TODO: We need to make sure the options (classnames & such)
|
|
@@ -492,28 +502,72 @@ Router.setMethod(function routeUrl(name, parameters, options) {
|
|
|
492
502
|
*
|
|
493
503
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
494
504
|
* @since 0.3.0
|
|
495
|
-
* @version
|
|
505
|
+
* @version 1.3.8
|
|
496
506
|
*
|
|
497
507
|
* @param {String} name
|
|
498
508
|
* @param {Object} parameters
|
|
509
|
+
* @param {Object} options
|
|
499
510
|
*
|
|
500
|
-
* @return {
|
|
511
|
+
* @return {Alchemy.Breadcrumb}
|
|
501
512
|
*/
|
|
502
|
-
Router.setMethod(function getTrail(name, parameters) {
|
|
513
|
+
Router.setMethod(function getTrail(name, parameters, options) {
|
|
503
514
|
|
|
504
|
-
|
|
515
|
+
let can_have_assignments,
|
|
516
|
+
trails = [],
|
|
505
517
|
config;
|
|
518
|
+
|
|
519
|
+
if (options?.breadcrumb) {
|
|
520
|
+
can_have_assignments = true;
|
|
521
|
+
trails.push(options.breadcrumb);
|
|
522
|
+
}
|
|
506
523
|
|
|
507
524
|
config = this.routeConfig(name);
|
|
508
525
|
|
|
509
|
-
if (!config || !config.breadcrumb) {
|
|
526
|
+
if (!trails.length && (!config || !config.breadcrumb)) {
|
|
510
527
|
return;
|
|
511
528
|
}
|
|
512
529
|
|
|
513
|
-
breadcrumb =
|
|
530
|
+
let breadcrumb = new Classes.Alchemy.Breadcrumb();
|
|
531
|
+
|
|
532
|
+
if (config?.breadcrumb) {
|
|
533
|
+
trails.push(config.breadcrumb);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
if (!can_have_assignments) {
|
|
537
|
+
can_have_assignments = config?.has_breadcrumb_assignments;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (can_have_assignments) {
|
|
541
|
+
let key;
|
|
542
|
+
parameters = {...parameters};
|
|
543
|
+
|
|
544
|
+
for (key in parameters) {
|
|
545
|
+
if (key[0] == key[0].toUpperCase()) {
|
|
546
|
+
let value = parameters[key];
|
|
547
|
+
|
|
548
|
+
if (value && typeof value == 'object') {
|
|
549
|
+
let subkey;
|
|
550
|
+
|
|
551
|
+
let context = value?.$main || value;
|
|
552
|
+
|
|
553
|
+
for (subkey in context) {
|
|
554
|
+
if (parameters[subkey] == null) {
|
|
555
|
+
parameters[subkey] = context[subkey];
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
let trail;
|
|
514
564
|
|
|
515
|
-
|
|
516
|
-
|
|
565
|
+
for (trail of trails) {
|
|
566
|
+
if (can_have_assignments) {
|
|
567
|
+
trail = Blast.Bound.String.assign(trail, parameters).toLowerCase();
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
breadcrumb.addTrail(trail);
|
|
517
571
|
}
|
|
518
572
|
|
|
519
573
|
return breadcrumb;
|
|
@@ -527,9 +581,6 @@ Router.setMethod(function getTrail(name, parameters) {
|
|
|
527
581
|
* @version 0.3.0
|
|
528
582
|
*/
|
|
529
583
|
Router.setMethod(function printBreadcrumb() {
|
|
530
|
-
|
|
531
|
-
var that = this;
|
|
532
|
-
|
|
533
584
|
this.view.print_partial('breadcrumb/wrapper');
|
|
534
585
|
});
|
|
535
586
|
|
|
@@ -739,7 +790,7 @@ Router.setMethod(function updateLanguageSwitcher(element, variables) {
|
|
|
739
790
|
*
|
|
740
791
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
741
792
|
* @since 1.2.5
|
|
742
|
-
* @version 1.3.
|
|
793
|
+
* @version 1.3.8
|
|
743
794
|
*
|
|
744
795
|
* @param {String} prefix The prefix to use
|
|
745
796
|
* @param {Object} variables
|
|
@@ -761,6 +812,15 @@ Router.setMethod(function translateCurrentRoute(prefix, variables) {
|
|
|
761
812
|
return;
|
|
762
813
|
}
|
|
763
814
|
|
|
815
|
+
// Don't just translate the last rendered route, make sure it's the current one
|
|
816
|
+
if (info.url && Blast.isBrowser) {
|
|
817
|
+
let url = RURL.parse(info.url);
|
|
818
|
+
|
|
819
|
+
if (url && !url.matchesPath(window.location)) {
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
764
824
|
let config = this.routeConfig(info.route);
|
|
765
825
|
|
|
766
826
|
if (!config) {
|
|
@@ -597,9 +597,9 @@ Model.setMethod(function getAliasModel(alias) {
|
|
|
597
597
|
/**
|
|
598
598
|
* Query the database
|
|
599
599
|
*
|
|
600
|
-
* @author Jelle De Loecker <jelle@
|
|
600
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
601
601
|
* @since 0.0.1
|
|
602
|
-
* @version 1.3.
|
|
602
|
+
* @version 1.3.8
|
|
603
603
|
*
|
|
604
604
|
* @param {String} type The type of find (first, all)
|
|
605
605
|
* @param {Criteria} criteria The criteria object
|
|
@@ -660,7 +660,7 @@ Model.setMethod(function find(type, criteria, callback) {
|
|
|
660
660
|
}
|
|
661
661
|
|
|
662
662
|
if (!criteria.options.locale && this.conduit) {
|
|
663
|
-
criteria.setOption('locale', this.conduit.
|
|
663
|
+
criteria.setOption('locale', this.conduit.active_prefix);
|
|
664
664
|
}
|
|
665
665
|
|
|
666
666
|
let that = this,
|
|
@@ -519,6 +519,59 @@ Alchemy.setMethod(function routeConfig(name) {
|
|
|
519
519
|
|
|
520
520
|
const markLinkElement = Alchemy.prototype.markLinkElement;
|
|
521
521
|
|
|
522
|
+
/**
|
|
523
|
+
* Get a live map of all the routes
|
|
524
|
+
*
|
|
525
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
526
|
+
* @since 1.3.8
|
|
527
|
+
* @version 1.3.8
|
|
528
|
+
*
|
|
529
|
+
* @return {Develry.BackedMap}
|
|
530
|
+
*/
|
|
531
|
+
Alchemy.setMethod(function getRoutes() {
|
|
532
|
+
return new Classes.Develry.BackedMap(getRoutesDict);
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* The live-map dictionary creator
|
|
537
|
+
*
|
|
538
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
539
|
+
* @since 1.3.8
|
|
540
|
+
* @version 1.3.8
|
|
541
|
+
*
|
|
542
|
+
* @return {Object}
|
|
543
|
+
*/
|
|
544
|
+
function getRoutesDict() {
|
|
545
|
+
let routes;
|
|
546
|
+
|
|
547
|
+
if (Blast.isNode) {
|
|
548
|
+
routes = {};
|
|
549
|
+
|
|
550
|
+
let roots = Router.getRoutes();
|
|
551
|
+
|
|
552
|
+
for (let key in roots) {
|
|
553
|
+
let root = roots[key];
|
|
554
|
+
|
|
555
|
+
for (let name in root) {
|
|
556
|
+
routes[name] = root[name];
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
} else {
|
|
561
|
+
routes = {};
|
|
562
|
+
|
|
563
|
+
for (let root in hawkejs.scene.exposed.routes) {
|
|
564
|
+
let section = hawkejs.scene.exposed.routes[root];
|
|
565
|
+
|
|
566
|
+
for (let key in section) {
|
|
567
|
+
routes[key] = section[key];
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return routes;
|
|
573
|
+
}
|
|
574
|
+
|
|
522
575
|
// From here on, only client-side code is added
|
|
523
576
|
if (Blast.isBrowser) {
|
|
524
577
|
window.alchemy = new Alchemy();
|
|
@@ -582,21 +635,18 @@ Alchemy.setMethod(function linkup(type, data, cb) {
|
|
|
582
635
|
*
|
|
583
636
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
584
637
|
* @since 0.3.0
|
|
585
|
-
* @version 1.3.
|
|
638
|
+
* @version 1.3.8
|
|
586
639
|
*
|
|
587
640
|
* @param {Object} variables
|
|
588
641
|
* @param {Object} render_data
|
|
589
642
|
*/
|
|
590
643
|
Alchemy.setMethod(function markLinks(variables, render_data) {
|
|
591
644
|
|
|
592
|
-
|
|
593
|
-
el_breadcrumbs,
|
|
594
|
-
el_breadcrumb,
|
|
645
|
+
let page_breadcrumb,
|
|
595
646
|
placeholder,
|
|
596
647
|
href_val,
|
|
597
648
|
elements,
|
|
598
649
|
element,
|
|
599
|
-
temp,
|
|
600
650
|
url,
|
|
601
651
|
i;
|
|
602
652
|
|
|
@@ -607,7 +657,7 @@ Alchemy.setMethod(function markLinks(variables, render_data) {
|
|
|
607
657
|
}
|
|
608
658
|
|
|
609
659
|
// Get the newly set breadcrumb
|
|
610
|
-
page_breadcrumb = variables.__breadcrumb;
|
|
660
|
+
page_breadcrumb = new Classes.Alchemy.Breadcrumb(variables.__breadcrumb);
|
|
611
661
|
|
|
612
662
|
// Get all the language switcher anchors
|
|
613
663
|
elements = document.querySelectorAll('[data-alchemy-language-switch]');
|
|
@@ -621,30 +671,7 @@ Alchemy.setMethod(function markLinks(variables, render_data) {
|
|
|
621
671
|
|
|
622
672
|
for (i = 0; i < elements.length; i++) {
|
|
623
673
|
element = elements[i];
|
|
624
|
-
|
|
625
|
-
// Create the breadcrumbs array
|
|
626
|
-
el_breadcrumbs = [];
|
|
627
|
-
|
|
628
|
-
// Get the element's set breadcrumb
|
|
629
|
-
el_breadcrumb = element.getAttribute('data-breadcrumb');
|
|
630
|
-
|
|
631
|
-
if (el_breadcrumb) {
|
|
632
|
-
el_breadcrumbs.push(el_breadcrumb);
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
el_breadcrumb = element.getAttribute('data-breadcrumbs');
|
|
636
|
-
|
|
637
|
-
if (el_breadcrumb) {
|
|
638
|
-
el_breadcrumbs.include(el_breadcrumb.split('|'));
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
if (el_breadcrumbs.indexOf(page_breadcrumb) > -1) {
|
|
642
|
-
markLinkElement(element, 1);
|
|
643
|
-
} else if (page_breadcrumb && page_breadcrumb.startsWithAny(el_breadcrumbs)) {
|
|
644
|
-
markLinkElement(element, 2);
|
|
645
|
-
} else {
|
|
646
|
-
markLinkElement(element, false);
|
|
647
|
-
}
|
|
674
|
+
markLinkElement(element, page_breadcrumb.matchLevel(element));
|
|
648
675
|
}
|
|
649
676
|
|
|
650
677
|
// Get all anchors without breadcrumbs
|
|
@@ -702,9 +729,9 @@ Alchemy.setMethod(function markLinks(variables, render_data) {
|
|
|
702
729
|
/**
|
|
703
730
|
* Reload all stylesheets
|
|
704
731
|
*
|
|
705
|
-
* @author Jelle De Loecker <jelle@
|
|
732
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
706
733
|
* @since 1.0.0
|
|
707
|
-
* @version 1.
|
|
734
|
+
* @version 1.3.8
|
|
708
735
|
*/
|
|
709
736
|
Alchemy.setMethod(function reloadStylesheets() {
|
|
710
737
|
|
|
@@ -718,15 +745,15 @@ Alchemy.setMethod(function reloadStylesheets() {
|
|
|
718
745
|
let url = new RURL(sheet.href);
|
|
719
746
|
url.param('last_reload', Date.now());
|
|
720
747
|
|
|
721
|
-
//sheet.ownerNode.href = String(url);
|
|
722
|
-
|
|
723
748
|
let new_element = alchemy.hawkejs.createElement('link');
|
|
724
749
|
new_element.setAttribute('rel', 'stylesheet');
|
|
725
750
|
new_element.setAttribute('href', String(url));
|
|
726
751
|
document.head.append(new_element);
|
|
727
752
|
|
|
728
753
|
new_element.addEventListener('load', e => {
|
|
729
|
-
sheet.ownerNode
|
|
754
|
+
if (sheet.ownerNode) {
|
|
755
|
+
sheet.ownerNode.remove();
|
|
756
|
+
}
|
|
730
757
|
});
|
|
731
758
|
}
|
|
732
759
|
});
|