diff --git a/core/modules/filters/json-ops.js b/core/modules/filters/json-ops.js index 2be9ec754..b4c5b3fee 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 68a82e774..4a451df80 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 c62854898..81dad90c5 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