diff --git a/core/modules/filters/json-ops.js b/core/modules/filters/json-ops.js index 2be9ec7549..b4c5b3fee3 100644 --- a/core/modules/filters/json-ops.js +++ b/core/modules/filters/json-ops.js @@ -68,6 +68,20 @@ exports["jsontype"] = function(source,operator,options) { return results; }; +exports["jsonset"] = function(source,operator,options) { + var indexes = operator.operands.slice(0,-1), + value = operator.operands[operator.operands.length - 1] || "", + results = []; + source(function(tiddler,title) { + var data = $tw.utils.parseJSONSafe(title,title); + if(data) { + data = setDataItem(data,indexes,value); + results.push(JSON.stringify(data)); + } + }); + return results; +}; + /* Given a JSON data structure and an array of index strings, return an array of the string representation of the values at the end of the index chain, or "undefined" if any of the index strings are invalid */ @@ -186,5 +200,30 @@ function getDataItem(data,indexes) { return item; } +/* +Given a JSON data structure, an array of index strings and a value, return the data structure with the value added at the end of the index chain. If any of the index strings are invalid then the JSON data structure is returned unmodified. If the root item is targetted then a different data object will be returned +*/ +function setDataItem(data,indexes,value) { + // Check for the root item + if(indexes.length === 0 || (indexes.length === 1 && indexes[0] === "")) { + return value; + } + // Traverse the JSON data structure using the index chain + var current = data; + for(var i = 0; i < indexes.length - 1; i++) { + var index = indexes[i]; + if($tw.utils.hop(current,index)) { + current = current[index]; + } else { + // Return the original JSON data structure if any of the index strings are invalid + return data; + } + } + // Add the value to the end of the index chain + var lastIndex = indexes[indexes.length - 1]; + current[lastIndex] = value; + return data; +} + })(); \ No newline at end of file diff --git a/editions/test/tiddlers/tests/test-json-filters.js b/editions/test/tiddlers/tests/test-json-filters.js index 68a82e7744..4a451df80f 100644 --- a/editions/test/tiddlers/tests/test-json-filters.js +++ b/editions/test/tiddlers/tests/test-json-filters.js @@ -103,6 +103,12 @@ describe("json filter tests", function() { expect(wiki.filterTiddlers("[{First}jsontype[d],[f],[4]]")).toEqual(["null"]); }); + it("should support the jsonset operator", function() { + expect(wiki.filterTiddlers("[{First}jsonset[],[Antelope]]")).toEqual(['"Antelope"']); + expect(wiki.filterTiddlers("[{First}jsonset[id],[Antelope]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]},"id":"Antelope"}']); + expect(wiki.filterTiddlers("[{First}jsonset[missing],[id],[Antelope]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]}}']); + }); + it("should support the format:json operator", function() { expect(wiki.filterTiddlers("[{First}format:json[]]")).toEqual(["{\"a\":\"one\",\"b\":\"\",\"c\":1.618,\"d\":{\"e\":\"four\",\"f\":[\"five\",\"six\",true,false,null]}}"]); expect(wiki.filterTiddlers("[{First}format:json[4]]")).toEqual(["{\n \"a\": \"one\",\n \"b\": \"\",\n \"c\": 1.618,\n \"d\": {\n \"e\": \"four\",\n \"f\": [\n \"five\",\n \"six\",\n true,\n false,\n null\n ]\n }\n}"]); diff --git a/plugins/tiddlywiki/geospatial/tests/operators/geopoint.tid b/plugins/tiddlywiki/geospatial/tests/operators/geopoint.tid index c628548981..81dad90c5e 100644 --- a/plugins/tiddlywiki/geospatial/tests/operators/geopoint.tid +++ b/plugins/tiddlywiki/geospatial/tests/operators/geopoint.tid @@ -7,9 +7,11 @@ title: Output <$text text={{{ [geopoint[51.751944],[-1.257778]] }}}/> +<$text text={{{ [geopoint[51.751944],[-1.257778]jsonset[id],[Oxford]] }}}/> + <$text text={{{ [geopoint[51.751944],[-1.257778],[2]] }}}/> + title: ExpectedResult -{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[51.751944,-1.257778,0]}}{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[51.751944,-1.257778,2]}} \ No newline at end of file +{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[51.751944,-1.257778,0]}}{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[51.751944,-1.257778,0]},"id":"Oxford"}{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[51.751944,-1.257778,2]}} \ No newline at end of file