1 /*global window: true, GCN: true, jQuery: true */ 2 3 /** 4 * IMPORTANT NOTE CONCERNING JSDOC-TOOLKIT WORKAROUNDS: 5 * 6 * It is necessary to define a local function and then write extra code to 7 * expose it in the TagParts object rather than just doing it directy. Thi is 8 * because of a bug in JsDoc-Toolkit prevents the function documentation from 9 * being parsed correctly otherwise. 10 * 11 * function MULTISELECT(part, value) { 12 * return TagParts.SELECT(part, value); 13 * } 14 * TagParts.MULTISELECT = MULTISELECT; 15 */ 16 17 (function (GCN) { 18 'use strict'; 19 20 /** 21 * Retrieves a copy of the properties of the select options which 22 * corresponds to the given value. 23 * 24 * @ignore 25 * @private 26 * @param {string} value Search for property of this value 27 * @param {object} part The part inwhich to search for select options. 28 * @return {object|null} A copy of properties or null if none is found for 29 * `value'. 30 * @throws VALUE_DOES_NOT_EXIST 31 */ 32 function getSelectPartOption(value, part) { 33 var options = part.options; 34 var i; 35 for (i = 0; i < options.length; i++) { 36 if (options[i].value === value) { 37 return jQuery.extend({}, options[i]); 38 } 39 } 40 GCN.error( 41 'VALUE_DOES_NOT_EXIST', 42 'The value `' + value + '\' does not exist in this part', 43 part 44 ); 45 return null; 46 } 47 48 /** 49 * Creates a basic getter/setter function for the given field. 50 * 51 * @private 52 * @ignore 53 * @param {string} field; 54 * @return {function(object, *=)} A getter/setter function. 55 */ 56 function createGetterSetter(field) { 57 return function () { 58 var args = Array.prototype.slice.call(arguments); 59 var obj = args[0]; 60 if (args.length > 1) { 61 obj[field] = args[1]; 62 } 63 return obj[field]; 64 }; 65 } 66 67 /** 68 * <p> 69 * Functions to access and modify various tag part types. 70 * 71 * <p> 72 * <b>IMPORTANT</b>: Getter and setters for the various part types should 73 * never be accessed directly. If absolutely necessary it should be done 74 * via {@link TagParts.get} and {@link TagParts.set}. 75 * 76 * @public 77 * @namespace 78 * @name TagParts 79 * @type {object<string, function(object, (number|string|boolean|object)=)>} 80 */ 81 var TagParts = {}; 82 83 /** 84 * Gets or sets the value of a STRING tag part. 85 * 86 * @public 87 * @function 88 * @memberOf TagParts 89 * @name STRING 90 * @param {object} part The part whose value is to be accessed. 91 * @param {string=} value Optional. The value to set for this part. 92 * @return {string} The value held by this part. 93 */ 94 TagParts.STRING = createGetterSetter('stringValue'); 95 96 /** 97 * Gets or sets the value of a RICHTEXT tag part. 98 * 99 * @public 100 * @function 101 * @memberOf TagParts 102 * @name RICHTEXT 103 * @param {object} part The part whose value is to be accessed. 104 * @param {string=} value Optional. The value to set for this part. 105 * @return {string} The value held by this part. 106 */ 107 TagParts.RICHTEXT = createGetterSetter('stringValue'); 108 109 /** 110 * Gets or sets the value of a BOOLEAN tag part. 111 * 112 * @public 113 * @function 114 * @memberOf TagParts 115 * @name BOOLEAN 116 * @param {object} part The part whose value is to be accessed. 117 * @param {boolean=} value Optional. The value to set for this part. 118 * @return {boolean} The value held by this part. 119 */ 120 TagParts.BOOLEAN = createGetterSetter('booleanValue'); 121 122 /** 123 * Gets or sets the value of an IMAGE tag part. 124 * 125 * @public 126 * @function 127 * @memberOf TagParts 128 * @name IMAGE 129 * @param {object} part The part whose value is to be accessed. 130 * @param {number=} value Optional. The value to set for this part. 131 * @return {number} The value held by this part. 132 */ 133 TagParts.IMAGE = createGetterSetter('imageId'); 134 135 /** 136 * Gets or sets the value of a FILE tag part. 137 * 138 * @public 139 * @function 140 * @memberOf TagParts 141 * @name FILE 142 * @param {object} part The part whose value is to be accessed. 143 * @param {number=} value Optional. The value to set for this part. 144 * @return {number} The value held by this part. 145 */ 146 // (URL) file is the same as File (upload). 147 TagParts.FILE = createGetterSetter('fileId'); 148 149 /** 150 * Gets or sets the value of a FOLDER tag part. 151 * 152 * @public 153 * @function 154 * @memberOf TagParts 155 * @name FOLDER 156 * @param {object} part The part whose value is to be accessed. 157 * @param {number=} value Optional. The value to set for this part. 158 * @return {number} The value held by this part. 159 */ 160 // (URL) folder is the same as Folder (upload). 161 TagParts.FOLDER = createGetterSetter('folderId'); 162 163 /** 164 * Gets or sets the value of an OVERVIEW tag part. 165 * 166 * @public 167 * @function 168 * @memberOf TagParts 169 * @name OVERVIEW 170 * @param {object} part The part whose value is to be accessed. 171 * @param {object=} value Optional. The value to set for this part. 172 * @return {object} The value held by this part. 173 */ 174 TagParts.OVERVIEW = createGetterSetter('overview'); 175 176 /** 177 * Gets or sets the value of a PAGE tag part. 178 * 179 * @public 180 * @function 181 * @memberOf TagParts 182 * @name PAGE 183 * @param {object} part The part whose value is to be accessed. 184 * @param {(number|string)=} value Optional. A number denotes and internal 185 * page within Content.Node, whereas a 186 * string denotes an external url. 187 * @return {number|string} The value held by this part. 188 */ 189 function PAGE(part, value) { 190 if (jQuery.type(value) === 'number') { 191 part.pageId = value; 192 delete part.stringValue; 193 return value; 194 } 195 196 if (typeof value !== 'undefined' && value !== null) { 197 part.stringValue = value.toString(); 198 delete part.pageId; 199 return value; 200 } 201 202 return part[ 203 jQuery.type(part.stringValue) === 'string' ? 'stringValue' 204 : 'pageId' 205 ]; 206 } 207 TagParts.PAGE = PAGE; 208 209 /** 210 * <p> 211 * Gets or sets the value of a SELECT tag part. 212 * 213 * <p> 214 * There are several possible values that can be passed to this function: 215 * 216 * <pre> 217 * undefined : When value arguments is not provided, then none of this 218 * part's data is changed. 219 * 220 * null : selectedOptions will set to an empty array. 221 * 222 * object : selectedOptions will be set to contain a single select 223 * option that corresponds with that of the 224 * `selectedOptions' property in the given object. This 225 * allowance exists for backwards compatibility, and is not 226 * recommended. 227 * 228 * string : selectedOptions will be set to contain a single select 229 * option whose `value' property corresponds with that of 230 * the argument. 231 * 232 * string[] : selectedOptions will be set to contain zero or more 233 * select option whose `value' property corresponds with 234 * that of those in the given array. 235 * </pre> 236 * 237 * @public 238 * @function 239 * @memberOf TagParts 240 * @name SELECT 241 * @param {object} part The part whose value is to be accessed. 242 * @param {(string|string[]|object|null)=} value The values with which to 243 * determined what this part's 244 * `selectedOptions' property should 245 * hold. 246 * @return {object} An object containing a copy of the value of this part. 247 * @throws VALUE_DOES_NOT_EXIST 248 */ 249 function SELECT(part, value) { 250 var options = []; 251 var option; 252 var i; 253 switch (jQuery.type(value)) { 254 case 'string': 255 option = getSelectPartOption(value, part); 256 if (option) { 257 options.push(option); 258 } else { 259 return part; 260 } 261 break; 262 case 'array': 263 for (i = 0; i < value.length; i++) { 264 option = getSelectPartOption(value[i], part); 265 if (option) { 266 options.push(option); 267 } else { 268 return part; 269 } 270 } 271 break; 272 case 'object': 273 for (i = 0; i < value.selectedOptions.length; i++) { 274 option = getSelectPartOption(value.selectedOptions[i].value, 275 part); 276 if (option) { 277 options.push(option); 278 } else { 279 return part; 280 } 281 } 282 break; 283 case 'undefined': 284 options = part.selectedOptions; 285 break; 286 } 287 288 part.selectedOptions = options; 289 290 return { 291 datasourceId: part.datasourceId, 292 options: part.options, 293 selectedOptions: part.selectedOptions 294 }; 295 } 296 TagParts.SELECT = SELECT; 297 298 /** 299 * Gets or sets the value of a MULTISELECT tag part. 300 * Operates in the same was as {@link TagParts.SELECT}. 301 * 302 * @public 303 * @function 304 * @memberOf TagParts 305 * @name MULTISELECT 306 * @param {object} part The part whose value is to be accessed. 307 * @param {(string|string[]|object|null)=} value The values with which to 308 * determined what this part's 309 * `selectedOptions' property should 310 * hold. 311 * @return {object} An object containing a copy of the value of this part. 312 */ 313 function MULTISELECT(part, value) { 314 return TagParts.SELECT(part, value); 315 } 316 TagParts.MULTISELECT = MULTISELECT; 317 318 /** 319 * Gets or sets the value of a TEMPLATETAG tag part. 320 * 321 * @public 322 * @function 323 * @memberOf TagParts 324 * @name TEMPLATETAG 325 * @param {object} part The part whose value is to be accessed. 326 * @param {object=} value An object with the either the property `templateId' 327 * or `templateTagId'. 328 * @return {object} An object containing a copy of the value of this part. 329 * 330 */ 331 function TEMPLATETAG(part, value) { 332 if (value) { 333 if (typeof value.templateId !== 'undefined') { 334 part.templateId = value.templateId; 335 } 336 337 if (typeof value.templateTagId !== 'undefined') { 338 part.templateTagId = value.templateTagId; 339 } 340 } 341 342 return { 343 templateId: part.templateId, 344 templateTagId: part.templateTagId 345 }; 346 } 347 TagParts.TEMPLATETAG = TEMPLATETAG; 348 349 /** 350 * Gets or sets the value of a PAGETAG tag part. 351 * 352 * @public 353 * @function 354 * @memberOf TagParts 355 * @name PAGETAG 356 * @param {object} part The part whose value is to be accessed. 357 * @param {object=} value An object with the the property `pageId' 358 * and/or one of `contentTagId' or `templateTagId'. 359 * @return {object} An object containing a copy of the value of this 360 * part. 361 */ 362 function PAGETAG(part, value) { 363 if (value) { 364 if (typeof value.pageId !== 'undefined') { 365 part.pageId = value.pageId; 366 } 367 368 var newContentTagIdValue; 369 // support wrongly named 'pageTagId' property for backwards compatibility 370 if (typeof value.pageTagId !== 'undefined') { 371 newContentTagIdValue = value.pageTagId; 372 } else if (typeof value.contentTagId !== 'undefined') { 373 newContentTagIdValue = value.contentTagId; 374 } 375 376 // either a contenttag OR a templatetag must be specified 377 if (typeof newContentTagIdValue !== 'undefined') { 378 part.contentTagId = newContentTagIdValue; 379 delete part.templateTagId; 380 } else if (typeof value.templateTagId !== 'undefined') { 381 part.templateTagId = value.templateTagId; 382 delete part.contentTagId; 383 } 384 } 385 386 var result = { pageId: part.pageId }; 387 388 if (typeof part.contentTagId !== 'undefined') { 389 result.contentTagId = part.contentTagId; 390 } else if (typeof part.templateTagId !== 'undefined') { 391 result.templateTagId = part.templateTagId; 392 } 393 394 return result; 395 } 396 TagParts.PAGETAG = PAGETAG; 397 398 /** 399 * Gets or sets the value of the given tag part. 400 * 401 * @private 402 * @ignore 403 * @param {object} part The part whose value is to be accessed. 404 * @param {*=} value The value to set the part to. 405 * @throws CANNOT_READ_TAG_PART 406 */ 407 function accessor() { 408 var args = Array.prototype.slice.call(arguments); 409 var part = args[0]; 410 if (!TagParts[part.type]) { 411 GCN.error( 412 'CANNOT_READ_TAG_PART', 413 'Cannot read or write to tag part', 414 part 415 ); 416 return null; 417 } 418 return ( 419 args.length > 1 420 ? TagParts[part.type](part, args[1]) 421 : TagParts[part.type](part) 422 ); 423 } 424 425 /** 426 * Gets the value of the given tag part. 427 * 428 * @param {object} part The part whose value is to be retrieved. 429 * @param {*=} value The value to set the part to. 430 * @return {*} The value held in the given part. 431 * @throws CANNOT_READ_TAG_PART 432 */ 433 TagParts.get = function (part) { 434 return accessor(part); 435 }; 436 437 /** 438 * Sets the value of the given tag part. 439 * 440 * @param {object} part The part whose value is to be set. 441 * @param {*=} value The value to set the part to. 442 * @return {*} The value set to the given part. 443 * @throws CANNOT_READ_TAG_PART 444 */ 445 TagParts.set = function (part, value) { 446 return accessor(part, value); 447 }; 448 449 GCN.TagParts = TagParts; 450 451 }(GCN)); 452