diff --git a/CHANGELOG.md b/CHANGELOG.md index 0940043..241cbf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.3 (WIP) + +* Add `Trail#ifNull(fallback)` method + ## 0.9.2 (2024-02-25) * Clear the entire `Develry.Request.cache` as soon as a non-GET request is made diff --git a/lib/trail.js b/lib/trail.js index 77704e4..964e224 100644 --- a/lib/trail.js +++ b/lib/trail.js @@ -1,5 +1,7 @@ const CHAIN = Symbol('chain'), - GET_OR_EVALUATE = Symbol('getOrEvaluate'); + GET_OR_EVALUATE = Symbol('getOrEvaluate'), + HAS_FALLBACK = Symbol('hasFallback'), + FALLBACK = Symbol('fallback'); /** * Class that represents a path @@ -21,6 +23,10 @@ const Trail = Fn.inherits('Develry.Placeholder', function Trail(chain) { // The path pieces this[CHAIN] = chain; + // There is no fallback by default + this[HAS_FALLBACK] = false; + this[FALLBACK] = undefined; + // Is this a root path? this.is_root = chain[0] === ''; @@ -45,6 +51,12 @@ Trail.setStatic(function unDry(value) { let result = Object.create(this.prototype); result[CHAIN] = value.chain; result.is_root = value.is_root; + + if (value.fallback) { + result[HAS_FALLBACK] = true; + result[FALLBACK] = value.fallback.value; + } + return result; }); @@ -133,7 +145,7 @@ Trail.setStatic(function fromSlash(path) { * * @author Jelle De Loecker * @since 0.9.0 - * @version 0.9.0 + * @version 0.9.3 */ Trail.setMethod(function toDry() { @@ -145,18 +157,58 @@ Trail.setMethod(function toDry() { value.is_root = true; } + if (this[HAS_FALLBACK]) { + value.fallback = {value: this[FALLBACK]}; + } + return { value: value, }; }); +/** + * Create a shallow clone + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + * + * @return {Trail} + */ +Trail.setMethod(function shallowClone() { + let result = Object.create(this.constructor.prototype); + result[CHAIN] = this[CHAIN].slice(0); + result.is_root = this.is_root; + result[HAS_FALLBACK] = this[HAS_FALLBACK]; + result[FALLBACK] = this[FALLBACK]; + return result; +}); + +/** + * Set the fallback value for this trail. + * This will then be returned in case the value is null or undefined. + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + * + * @param {*} fallback + * + * @return {Trail} + */ +Trail.setMethod(function ifNull(fallback) { + this[HAS_FALLBACK] = true; + this[FALLBACK] = fallback; + return this; +}); + /** * Get the value of the given path. * If `evaluate` is true and the last piece is a function, it will be called. * * @author Jelle De Loecker * @since 0.9.0 - * @version 0.9.0 + * @version 0.9.3 * * @param {Object} context * @param {boolean} evaluate @@ -180,14 +232,14 @@ Trail.setMethod([GET_OR_EVALUATE], function internalGetOrEvaluate(context, evalu for (index = 0; index < length; index++) { if (context == null) { - return; + break; } key = chain[index]; value = context[key]; if (value == null) { - return; + break; } if (evaluate && index == last && typeof value == 'function') { @@ -197,6 +249,10 @@ Trail.setMethod([GET_OR_EVALUATE], function internalGetOrEvaluate(context, evalu } } + if (value == null && this[HAS_FALLBACK]) { + value = this[FALLBACK]; + } + return value; }); diff --git a/package.json b/package.json index 31314b8..cb4a9f4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "protoblast", "description": "Native object expansion library", - "version": "0.9.2", + "version": "0.9.3-alpha", "author": "Jelle De Loecker ", "keywords": [ "prototype",