diff --git a/lib-es5/utils/index.js b/lib-es5/utils/index.js index 30e447f7..022db5e2 100644 --- a/lib-es5/utils/index.js +++ b/lib-es5/utils/index.js @@ -320,7 +320,32 @@ function process_layer(layer) { return result; } +/** + * Parse radius options + * @private + * @param {Array|string|number} radius The radius to parse + * @return {string} radius transformation string + */ +function process_radius(radius) { + if (!radius) { + return radius; + } + if (!isArray(radius)) { + radius = [radius]; + } + if (radius.length === 0 || radius.length > 4) { + throw new Error("Radius array should contain between 1 and 4 values"); + } + if (radius.findIndex(function (x) { + return x === null; + }) >= 0) { + throw new Error("Corner: Cannot be null"); + } + return radius.map(normalize_expression).join(':'); +} + function base64EncodeURL(sourceUrl) { + var ignore; try { sourceUrl = decodeURI(sourceUrl); } catch (error) { @@ -554,6 +579,7 @@ function generate_transformation_string(options) { options.end_offset = _split_range2[1]; } var overlay = process_layer(utils.option_consume(options, "overlay")); + var radius = process_radius(utils.option_consume(options, "radius")); var underlay = process_layer(utils.option_consume(options, "underlay")); var ifValue = process_if(utils.option_consume(options, "if")); var custom_function = process_custom_function(utils.option_consume(options, "custom_function")); @@ -579,7 +605,7 @@ function generate_transformation_string(options) { l: overlay, o: normalize_expression(utils.option_consume(options, "opacity")), q: normalize_expression(utils.option_consume(options, "quality")), - r: normalize_expression(utils.option_consume(options, "radius")), + r: radius, t: named_transformation, u: underlay, w: normalize_expression(width), diff --git a/lib/utils/index.js b/lib/utils/index.js index 9404a6d3..ef55e07b 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -312,6 +312,28 @@ function process_layer(layer) { return result; } +/** + * Parse radius options + * @private + * @param {Array|string|number} radius The radius to parse + * @return {string} radius transformation string + */ +function process_radius(radius) { + if (!radius) { + return radius; + } + if (!isArray(radius)) { + radius = [radius]; + } + if (radius.length === 0 || radius.length > 4) { + throw new Error("Radius array should contain between 1 and 4 values"); + } + if (radius.findIndex(x => x === null) >= 0) { + throw new Error("Corner: Cannot be null"); + } + return radius.map(normalize_expression).join(':'); +} + function base64EncodeURL(sourceUrl) { try { sourceUrl = decodeURI(sourceUrl); @@ -550,6 +572,7 @@ function generate_transformation_string(options) { [options.start_offset, options.end_offset] = split_range(utils.option_consume(options, "offset")); } let overlay = process_layer(utils.option_consume(options, "overlay")); + let radius = process_radius(utils.option_consume(options, "radius")); let underlay = process_layer(utils.option_consume(options, "underlay")); let ifValue = process_if(utils.option_consume(options, "if")); let custom_function = process_custom_function(utils.option_consume(options, "custom_function")); @@ -575,7 +598,7 @@ function generate_transformation_string(options) { l: overlay, o: normalize_expression(utils.option_consume(options, "opacity")), q: normalize_expression(utils.option_consume(options, "quality")), - r: normalize_expression(utils.option_consume(options, "radius")), + r: radius, t: named_transformation, u: underlay, w: normalize_expression(width), diff --git a/test/cloudinary_spec.js b/test/cloudinary_spec.js index 8d6f0937..8449d518 100644 --- a/test/cloudinary_spec.js +++ b/test/cloudinary_spec.js @@ -180,7 +180,44 @@ describe("cloudinary", function () { }), `${upload_path}/g_center,p_a,q_auto:good,r_3,x_1,y_2/test`); }); }); - it("should support named transformation", function () { + describe(":radius", function() { + const upload_path = 'http://res.cloudinary.com/test123/image/upload'; + it("should support a single value", function() { + expect(cloudinary.utils.url("test", { + radius: 10 + })).to.eql(`${upload_path}/r_10/test`); + expect(cloudinary.utils.url("test", { + radius: '10' + })).to.eql(`${upload_path}/r_10/test`); + expect(cloudinary.utils.url("test", { + variables: [['$v', 10]], + radius: '$v', + })).to.eql(`${upload_path}/$v_10,r_$v/test`); + }); + it("should support an array of values", function() { + expect(cloudinary.utils.url("test", { + radius: [10,20,30] + })).to.eql(`${upload_path}/r_10:20:30/test`); + expect(cloudinary.utils.url("test", { + variables: [['$v', 10]], + radius: [10,20,'$v'], + })).to.eql(`${upload_path}/$v_10,r_10:20:$v/test`); + expect(cloudinary.utils.url("test", { + variables: [['$v', 10]], + radius: [10,20,'$v',40], + })).to.eql(`${upload_path}/$v_10,r_10:20:$v:40/test`); + }) + it("should support colon separated values", function() { + expect(cloudinary.utils.url("test", { + radius: "10:20" + })).to.eql(`${upload_path}/r_10:20/test`); + expect(cloudinary.utils.url("test", { + variables: [['$v', 10]], + radius: "10:20:$v:40" + })).to.eql(`${upload_path}/$v_10,r_10:20:$v:40/test`); + }) + }) + it("should support named transformation", function() { var options, result; options = { transformation: "blip", diff --git a/test/utils_spec.js b/test/utils_spec.js index 3e517fbb..f0a6690e 100644 --- a/test/utils_spec.js +++ b/test/utils_spec.js @@ -343,6 +343,25 @@ describe("utils", function () { angle: 'auto', }, `http://res.cloudinary.com/${cloud_name}/image/upload/a_auto,c_scale,h_100,w_100/test`, {}); }); + it("should disallow radius arrays that contain 0 or more than 4 values", function () { + expect(function () { + return utils.url("test", { + radius: [10, 20, 30, 10, 20] + }); + }).to.throwError(/Radius array should contain between 1 and 4 values/); + expect(function () { + return utils.url("test", { + radius: [] + }); + }).to.throwError(/Radius array should contain between 1 and 4 values/); + }); + it("should disallow radius arrays containing null values", function () { + expect(function () { + return utils.url("test", { + radius: [null, 20, 30, 10] + }); + }).to.throwError(/Corner: Cannot be null/); + }); it("should use x, y, radius, prefix, gravity and quality from options", function () { test_cloudinary_url("test", { x: 1, @@ -1520,3 +1539,4 @@ describe("utils", function () { }); }); }); +