@lenne.tech/ng-base 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/lenne.tech-ng-base-src-lib-base.umd.js +267 -17
- package/bundles/lenne.tech-ng-base-src-lib-base.umd.js.map +1 -1
- package/bundles/lenne.tech-ng-base.umd.js +267 -17
- package/bundles/lenne.tech-ng-base.umd.js.map +1 -1
- package/esm2015/lib/base/interfaces/base-module-config.interface.js +1 -1
- package/esm2015/lib/base/services/graphql.service.js +16 -3
- package/esm2015/lib/base/services/scroll.service.js +201 -16
- package/esm2015/src/lib/base/interfaces/base-module-config.interface.js +1 -1
- package/esm2015/src/lib/base/services/graphql.service.js +16 -3
- package/esm2015/src/lib/base/services/scroll.service.js +201 -16
- package/fesm2015/lenne.tech-ng-base-src-lib-base.js +215 -17
- package/fesm2015/lenne.tech-ng-base-src-lib-base.js.map +1 -1
- package/fesm2015/lenne.tech-ng-base.js +215 -17
- package/fesm2015/lenne.tech-ng-base.js.map +1 -1
- package/lib/base/interfaces/base-module-config.interface.d.ts +5 -0
- package/lib/base/services/graphql.service.d.ts +1 -1
- package/lib/base/services/scroll.service.d.ts +66 -3
- package/package.json +12 -11
- package/src/lib/base/interfaces/base-module-config.interface.d.ts +5 -0
- package/src/lib/base/lenne.tech-ng-base-src-lib-base.metadata.json +1 -1
- package/src/lib/base/services/graphql.service.d.ts +1 -1
- package/src/lib/base/services/scroll.service.d.ts +66 -3
|
@@ -14,6 +14,7 @@ import * as i1$1 from '@angular/router';
|
|
|
14
14
|
import { Router } from '@angular/router';
|
|
15
15
|
import { buildClientSchema, getIntrospectionQuery } from 'graphql';
|
|
16
16
|
import { map } from 'rxjs/operators';
|
|
17
|
+
import { __awaiter } from 'tslib';
|
|
17
18
|
|
|
18
19
|
const BASE_MODULE_CONFIG = new InjectionToken('BASE_MODULE_CONFIG');
|
|
19
20
|
|
|
@@ -1629,14 +1630,23 @@ class GraphQLService {
|
|
|
1629
1630
|
/**
|
|
1630
1631
|
* Get fields / args from IGraphQLTypeCollection
|
|
1631
1632
|
*/
|
|
1632
|
-
graphQLTypeCollectionToStringArray(collection, current = '', result = []) {
|
|
1633
|
+
graphQLTypeCollectionToStringArray(collection, current = '', result = [], cacheNode = []) {
|
|
1633
1634
|
if (collection) {
|
|
1634
1635
|
if (collection instanceof GraphQLType) {
|
|
1635
1636
|
result.push(current);
|
|
1636
1637
|
}
|
|
1637
1638
|
else {
|
|
1639
|
+
if (current === null || current === void 0 ? void 0 : current.includes('.')) {
|
|
1640
|
+
cacheNode.push(current.split('.')[1]);
|
|
1641
|
+
}
|
|
1642
|
+
else if (current) {
|
|
1643
|
+
cacheNode.push(current);
|
|
1644
|
+
}
|
|
1638
1645
|
for (const key of Object.keys(collection)) {
|
|
1639
|
-
|
|
1646
|
+
if (current === key || cacheNode.includes(key)) {
|
|
1647
|
+
continue;
|
|
1648
|
+
}
|
|
1649
|
+
this.graphQLTypeCollectionToStringArray(collection[key], current ? current + '.' + key : key, result, cacheNode);
|
|
1640
1650
|
}
|
|
1641
1651
|
}
|
|
1642
1652
|
}
|
|
@@ -1688,6 +1698,10 @@ class GraphQLService {
|
|
|
1688
1698
|
}
|
|
1689
1699
|
// Process object
|
|
1690
1700
|
else if (typeof args === 'object') {
|
|
1701
|
+
// Check object is empty
|
|
1702
|
+
if (args && Object.keys(args).length === 0 && Object.getPrototypeOf(args) === Object.prototype) {
|
|
1703
|
+
return { argsString: '{}', schemaArgs, usedArgs };
|
|
1704
|
+
}
|
|
1691
1705
|
// Process all object entries
|
|
1692
1706
|
for (const [key, value] of Object.entries(args)) {
|
|
1693
1707
|
// Init data for current entry
|
|
@@ -1991,31 +2005,73 @@ class ScrollService {
|
|
|
1991
2005
|
this.router = router;
|
|
1992
2006
|
this.moduleConfig = moduleConfig;
|
|
1993
2007
|
/**
|
|
1994
|
-
*
|
|
2008
|
+
* Is a scroll listener set
|
|
2009
|
+
*
|
|
2010
|
+
* @protected
|
|
1995
2011
|
*/
|
|
1996
|
-
this.
|
|
2012
|
+
this.scrollListener = false;
|
|
1997
2013
|
/**
|
|
1998
|
-
*
|
|
1999
|
-
*
|
|
2014
|
+
* Current scroll timer;
|
|
2015
|
+
*
|
|
2016
|
+
* @protected
|
|
2000
2017
|
*/
|
|
2001
|
-
this.
|
|
2002
|
-
const config = Object.assign({ scrollDetectionOffset: 200, scrollOffset: 100 }, moduleConfig);
|
|
2018
|
+
this.scrollTimer = -1;
|
|
2019
|
+
const config = Object.assign({ scrollDetectionOffset: 200, scrollOffset: 100, scrollSamplingRate: 100 }, moduleConfig);
|
|
2003
2020
|
this.detectionOffset = config.scrollDetectionOffset;
|
|
2004
2021
|
this.scrollOffset = config.scrollOffset;
|
|
2022
|
+
this.scrollSamplingRate = config.scrollSamplingRate;
|
|
2005
2023
|
}
|
|
2006
2024
|
/**
|
|
2007
2025
|
* Scroll to structureElement with specific ID
|
|
2008
2026
|
*/
|
|
2009
2027
|
scrollTo(id, options = {}) {
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2028
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2029
|
+
// Prepare config
|
|
2030
|
+
const config = Object.assign({ checkUrl: true, loadImagesBefore: true, resetStyles: false, setOverflow: true, stopPropagation: true }, options);
|
|
2031
|
+
// Check current URL
|
|
2032
|
+
if (config.checkUrl && this.router.url !== '/' && !this.router.url.startsWith('/#')) {
|
|
2033
|
+
yield this.router.navigate(['/'], { fragment: id });
|
|
2034
|
+
return !config.stopPropagation;
|
|
2035
|
+
}
|
|
2036
|
+
// Check if target element exits
|
|
2037
|
+
const el = document.getElementById(id);
|
|
2038
|
+
if (!el) {
|
|
2039
|
+
console.error('Missing scroll element with ID:', id);
|
|
2040
|
+
return !config.stopPropagation;
|
|
2041
|
+
}
|
|
2042
|
+
// Check if body overflow is visible
|
|
2043
|
+
// This is necessary for scroll handling
|
|
2044
|
+
const body = document.querySelector('body');
|
|
2045
|
+
let undoOverflowChanges = false;
|
|
2046
|
+
const scrollBodyStyles = JSON.parse(JSON.stringify(window.getComputedStyle(body)));
|
|
2047
|
+
if (config.setOverflow && (scrollBodyStyles.overflowX !== 'visible' || scrollBodyStyles.overflowY !== 'visible')) {
|
|
2048
|
+
// Set body overflow to visible
|
|
2049
|
+
console.warn('Style of body element for overflowX and overflowY will be set to "visible" for scrolling!');
|
|
2050
|
+
body.style.overflowX = 'visible';
|
|
2051
|
+
body.style.overflowY = 'visible';
|
|
2052
|
+
undoOverflowChanges = true;
|
|
2053
|
+
}
|
|
2054
|
+
// Load images before scrolling (once)
|
|
2055
|
+
if (config.loadImagesBefore) {
|
|
2056
|
+
yield this.preLoadImages();
|
|
2057
|
+
}
|
|
2058
|
+
// Get get bounding rect of target element
|
|
2059
|
+
const cords = el.getBoundingClientRect();
|
|
2060
|
+
// Scroll to element
|
|
2061
|
+
window.scrollBy({ top: cords.top - this.scrollOffset, behavior: 'smooth' });
|
|
2062
|
+
yield this.scrollDone({
|
|
2063
|
+
doneFunction: () => {
|
|
2064
|
+
// Undo changes
|
|
2065
|
+
if (undoOverflowChanges && config.resetStyles) {
|
|
2066
|
+
body.style.overflowX = scrollBodyStyles.overflowX;
|
|
2067
|
+
body.style.overflowY = scrollBodyStyles.overflowY;
|
|
2068
|
+
console.warn('Original style of body element for overflowX and overflowY is set.');
|
|
2069
|
+
}
|
|
2070
|
+
},
|
|
2071
|
+
});
|
|
2072
|
+
// Return stop propagation configuration
|
|
2073
|
+
return !config.stopPropagation;
|
|
2074
|
+
});
|
|
2019
2075
|
}
|
|
2020
2076
|
/**
|
|
2021
2077
|
* Get last active structureElement
|
|
@@ -2045,6 +2101,148 @@ class ScrollService {
|
|
|
2045
2101
|
const lastActiveElement = this.getLastActiveElement(list);
|
|
2046
2102
|
return id === lastActiveElement || (lastActiveElement === null && isFirst);
|
|
2047
2103
|
}
|
|
2104
|
+
/**
|
|
2105
|
+
* Scroll done promise
|
|
2106
|
+
*/
|
|
2107
|
+
scrollDone(options = {}) {
|
|
2108
|
+
// Init configuration
|
|
2109
|
+
const config = Object.assign({ doneFunction: undefined, timeout: undefined }, options);
|
|
2110
|
+
// Return promise for scroll done
|
|
2111
|
+
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
2112
|
+
// Init variables
|
|
2113
|
+
let rejected = false;
|
|
2114
|
+
let timeoutId;
|
|
2115
|
+
// Set timeout handling if necessary
|
|
2116
|
+
if (config.timeout) {
|
|
2117
|
+
timeoutId = window.setTimeout(() => {
|
|
2118
|
+
rejected = true;
|
|
2119
|
+
reject(new Error('Timeout for scrollDone after:' + config.timeout));
|
|
2120
|
+
}, config.timeout);
|
|
2121
|
+
}
|
|
2122
|
+
// Wait for scroll done
|
|
2123
|
+
yield this.scrollDoneDetection();
|
|
2124
|
+
// Resolve promise if not already rejected
|
|
2125
|
+
if (!rejected) {
|
|
2126
|
+
// Stop timeout if set
|
|
2127
|
+
if (timeoutId) {
|
|
2128
|
+
window.clearTimeout(timeoutId);
|
|
2129
|
+
}
|
|
2130
|
+
// Get result (if doneFunction is set)
|
|
2131
|
+
let result;
|
|
2132
|
+
if (config.doneFunction) {
|
|
2133
|
+
result = yield config.doneFunction();
|
|
2134
|
+
}
|
|
2135
|
+
// Scroll done
|
|
2136
|
+
resolve(result);
|
|
2137
|
+
}
|
|
2138
|
+
}));
|
|
2139
|
+
}
|
|
2140
|
+
/**
|
|
2141
|
+
* Scroll done detecton
|
|
2142
|
+
*
|
|
2143
|
+
* @protected
|
|
2144
|
+
*/
|
|
2145
|
+
scrollDoneDetection() {
|
|
2146
|
+
// Return current scroll promise (Singelton)
|
|
2147
|
+
if (this.scrollPromise) {
|
|
2148
|
+
return this.scrollPromise;
|
|
2149
|
+
}
|
|
2150
|
+
// Create current scroll promise
|
|
2151
|
+
this.scrollPromise = new Promise((resolve) => {
|
|
2152
|
+
this.scrollPromiseResolve = resolve;
|
|
2153
|
+
if (this.scrollTimer !== -1) {
|
|
2154
|
+
window.clearTimeout(this.scrollTimer);
|
|
2155
|
+
}
|
|
2156
|
+
this.scrollTimer = window.setTimeout(() => {
|
|
2157
|
+
window.removeEventListener('scroll', this.scrollDoneDetection.bind(this));
|
|
2158
|
+
this.scrollPromise = undefined;
|
|
2159
|
+
resolve();
|
|
2160
|
+
}, this.scrollSamplingRate);
|
|
2161
|
+
});
|
|
2162
|
+
// Lisitening to scroll event;
|
|
2163
|
+
window.addEventListener('scroll', this.scrollDoneDetection.bind(this));
|
|
2164
|
+
// Return promise
|
|
2165
|
+
return this.scrollPromise;
|
|
2166
|
+
}
|
|
2167
|
+
/**
|
|
2168
|
+
* Preaload images (for lazy handling)
|
|
2169
|
+
*
|
|
2170
|
+
* @param options
|
|
2171
|
+
* @protected
|
|
2172
|
+
*/
|
|
2173
|
+
preLoadImages(options) {
|
|
2174
|
+
// Init configuration
|
|
2175
|
+
const config = Object.assign({ doneFunnction: undefined, timeout: undefined }, options);
|
|
2176
|
+
return new Promise((resolve) => {
|
|
2177
|
+
// Init variables
|
|
2178
|
+
let resolved = false;
|
|
2179
|
+
let timeoutId;
|
|
2180
|
+
// Init loading
|
|
2181
|
+
const images = Array.from(document.getElementsByTagName('img'));
|
|
2182
|
+
const promises = [];
|
|
2183
|
+
// Prepare images
|
|
2184
|
+
for (const image of images) {
|
|
2185
|
+
const src = image.getAttribute('src');
|
|
2186
|
+
// Check if changes are necessary and possible
|
|
2187
|
+
if ((image.complete && image.naturalHeight !== 0) || image.getAttribute('loading') !== 'lazy' || !src) {
|
|
2188
|
+
continue;
|
|
2189
|
+
}
|
|
2190
|
+
const newImage = document.createElement('img');
|
|
2191
|
+
Array.from(image.attributes).forEach((attr) => {
|
|
2192
|
+
if (attr.name !== 'loading' && attr.name !== 'src') {
|
|
2193
|
+
newImage.setAttribute(attr.name, attr.value);
|
|
2194
|
+
}
|
|
2195
|
+
});
|
|
2196
|
+
image.replaceWith(newImage);
|
|
2197
|
+
promises.push(this.loadImage(newImage, src));
|
|
2198
|
+
}
|
|
2199
|
+
if (config.timeout) {
|
|
2200
|
+
timeoutId = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
2201
|
+
resolved = true;
|
|
2202
|
+
if (config.doneFunnction) {
|
|
2203
|
+
yield config.doneFunction();
|
|
2204
|
+
}
|
|
2205
|
+
resolve(undefined);
|
|
2206
|
+
}));
|
|
2207
|
+
}
|
|
2208
|
+
// Wait until all images loaded
|
|
2209
|
+
Promise.all(promises)
|
|
2210
|
+
.catch((e) => console.error('Error during image loading', e))
|
|
2211
|
+
.finally(() => __awaiter(this, void 0, void 0, function* () {
|
|
2212
|
+
// Check if already resolved
|
|
2213
|
+
if (resolved) {
|
|
2214
|
+
return;
|
|
2215
|
+
}
|
|
2216
|
+
// Stop timeout
|
|
2217
|
+
if (timeoutId) {
|
|
2218
|
+
clearTimeout(timeoutId);
|
|
2219
|
+
}
|
|
2220
|
+
// Return result
|
|
2221
|
+
let result;
|
|
2222
|
+
if (config.doneFunnction) {
|
|
2223
|
+
result = yield config.doneFunction();
|
|
2224
|
+
}
|
|
2225
|
+
resolve(result);
|
|
2226
|
+
}));
|
|
2227
|
+
});
|
|
2228
|
+
}
|
|
2229
|
+
/**
|
|
2230
|
+
* Load image for image element
|
|
2231
|
+
*
|
|
2232
|
+
* @param imageElement
|
|
2233
|
+
* @param src
|
|
2234
|
+
* @protected
|
|
2235
|
+
*/
|
|
2236
|
+
loadImage(imageElement, src) {
|
|
2237
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2238
|
+
src = src || imageElement.src;
|
|
2239
|
+
return new Promise((resolve, reject) => {
|
|
2240
|
+
imageElement.onload = () => resolve(imageElement);
|
|
2241
|
+
imageElement.onerror = reject;
|
|
2242
|
+
imageElement.src = src;
|
|
2243
|
+
});
|
|
2244
|
+
});
|
|
2245
|
+
}
|
|
2048
2246
|
}
|
|
2049
2247
|
ScrollService.ɵprov = i0.ɵɵdefineInjectable({ factory: function ScrollService_Factory() { return new ScrollService(i0.ɵɵinject(i1$1.Router), i0.ɵɵinject(BASE_MODULE_CONFIG)); }, token: ScrollService, providedIn: "root" });
|
|
2050
2248
|
ScrollService.decorators = [
|