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 a NODE tag part. 165 * 166 * @public 167 * @function 168 * @memberOf TagParts 169 * @name NODE 170 * @param {object} part The part whose value is to be accessed. 171 * @param {number=} value Optional. The value to set for this part. 172 * @return {number} The value held by this part. 173 */ 174 TagParts.NODE = createGetterSetter('nodeId'); 175 176 /** 177 * Gets or sets the value of an OVERVIEW tag part. 178 * 179 * @public 180 * @function 181 * @memberOf TagParts 182 * @name OVERVIEW 183 * @param {object} part The part whose value is to be accessed. 184 * @param {object=} value Optional. The value to set for this part. 185 * @return {object} The value held by this part. 186 */ 187 TagParts.OVERVIEW = createGetterSetter('overview'); 188 189 /** 190 * Gets or sets the value of a PAGE tag part. 191 * 192 * @public 193 * @function 194 * @memberOf TagParts 195 * @name PAGE 196 * @param {object} part The part whose value is to be accessed. 197 * @param {(number|string)=} value Optional. A number denotes and internal 198 * page within Content.Node, whereas a 199 * string denotes an external url. 200 * @return {number|string} The value held by this part. 201 */ 202 function PAGE(part, value) { 203 if (jQuery.type(value) === 'number') { 204 part.pageId = value; 205 delete part.stringValue; 206 return value; 207 } 208 209 if (typeof value !== 'undefined' && value !== null) { 210 part.stringValue = value.toString(); 211 delete part.pageId; 212 return value; 213 } 214 215 return part[ 216 jQuery.type(part.stringValue) === 'string' ? 'stringValue' 217 : 'pageId' 218 ]; 219 } 220 TagParts.PAGE = PAGE; 221 222 /** 223 * <p> 224 * Gets or sets the value of a SELECT tag part. 225 * 226 * <p> 227 * There are several possible values that can be passed to this function: 228 * 229 * <pre> 230 * undefined : When value arguments is not provided, then none of this 231 * part's data is changed. 232 * 233 * null : selectedOptions will set to an empty array. 234 * 235 * object : selectedOptions will be set to contain a single select 236 * option that corresponds with that of the 237 * `selectedOptions' property in the given object. This 238 * allowance exists for backwards compatibility, and is not 239 * recommended. 240 * 241 * string : selectedOptions will be set to contain a single select 242 * option whose `value' property corresponds with that of 243 * the argument. 244 * 245 * string[] : selectedOptions will be set to contain zero or more 246 * select option whose `value' property corresponds with 247 * that of those in the given array. 248 * </pre> 249 * 250 * @public 251 * @function 252 * @memberOf TagParts 253 * @name SELECT 254 * @param {object} part The part whose value is to be accessed. 255 * @param {(string|string[]|object|null)=} value The values with which to 256 * determined what this part's 257 * `selectedOptions' property should 258 * hold. 259 * @return {object} An object containing a copy of the value of this part. 260 * @throws VALUE_DOES_NOT_EXIST 261 */ 262 function SELECT(part, value) { 263 var options = []; 264 var option; 265 var i; 266 switch (jQuery.type(value)) { 267 case 'string': 268 option = getSelectPartOption(value, part); 269 if (option) { 270 options.push(option); 271 } else { 272 return part; 273 } 274 break; 275 case 'array': 276 for (i = 0; i < value.length; i++) { 277 option = getSelectPartOption(value[i], part); 278 if (option) { 279 options.push(option); 280 } else { 281 return part; 282 } 283 } 284 break; 285 case 'object': 286 for (i = 0; i < value.selectedOptions.length; i++) { 287 option = getSelectPartOption(value.selectedOptions[i].value, 288 part); 289 if (option) { 290 options.push(option); 291 } else { 292 return part; 293 } 294 } 295 break; 296 case 'undefined': 297 options = part.selectedOptions; 298 break; 299 } 300 301 part.selectedOptions = options; 302 303 return { 304 datasourceId: part.datasourceId, 305 options: part.options, 306 selectedOptions: part.selectedOptions 307 }; 308 } 309 TagParts.SELECT = SELECT; 310 311 /** 312 * Gets or sets the value of a MULTISELECT tag part. 313 * Operates in the same was as {@link TagParts.SELECT}. 314 * 315 * @public 316 * @function 317 * @memberOf TagParts 318 * @name MULTISELECT 319 * @param {object} part The part whose value is to be accessed. 320 * @param {(string|string[]|object|null)=} value The values with which to 321 * determined what this part's 322 * `selectedOptions' property should 323 * hold. 324 * @return {object} An object containing a copy of the value of this part. 325 */ 326 function MULTISELECT(part, value) { 327 return TagParts.SELECT(part, value); 328 } 329 TagParts.MULTISELECT = MULTISELECT; 330 331 /** 332 * Gets or sets the value of a TEMPLATETAG tag part. 333 * 334 * @public 335 * @function 336 * @memberOf TagParts 337 * @name TEMPLATETAG 338 * @param {object} part The part whose value is to be accessed. 339 * @param {object=} value An object with the either the property `templateId' 340 * or `templateTagId'. 341 * @return {object} An object containing a copy of the value of this part. 342 * 343 */ 344 function TEMPLATETAG(part, value) { 345 if (value) { 346 if (typeof value.templateId !== 'undefined') { 347 part.templateId = value.templateId; 348 } 349 350 if (typeof value.templateTagId !== 'undefined') { 351 part.templateTagId = value.templateTagId; 352 } 353 } 354 355 return { 356 templateId: part.templateId, 357 templateTagId: part.templateTagId 358 }; 359 } 360 TagParts.TEMPLATETAG = TEMPLATETAG; 361 362 /** 363 * Gets or sets the value of a PAGETAG tag part. 364 * 365 * @public 366 * @function 367 * @memberOf TagParts 368 * @name PAGETAG 369 * @param {object} part The part whose value is to be accessed. 370 * @param {object=} value An object with the the property `pageId' 371 * and/or one of `contentTagId' or `templateTagId'. 372 * @return {object} An object containing a copy of the value of this 373 * part. 374 */ 375 function PAGETAG(part, value) { 376 if (value) { 377 if (typeof value.pageId !== 'undefined') { 378 part.pageId = value.pageId; 379 } 380 381 var newContentTagIdValue; 382 // support wrongly named 'pageTagId' property for backwards compatibility 383 if (typeof value.pageTagId !== 'undefined') { 384 newContentTagIdValue = value.pageTagId; 385 } else if (typeof value.contentTagId !== 'undefined') { 386 newContentTagIdValue = value.contentTagId; 387 } 388 389 // either a contenttag OR a templatetag must be specified 390 if (typeof newContentTagIdValue !== 'undefined') { 391 part.contentTagId = newContentTagIdValue; 392 delete part.templateTagId; 393 } else if (typeof value.templateTagId !== 'undefined') { 394 part.templateTagId = value.templateTagId; 395 delete part.contentTagId; 396 } 397 } 398 399 var result = { pageId: part.pageId }; 400 401 if (typeof part.contentTagId !== 'undefined') { 402 result.contentTagId = part.contentTagId; 403 } else if (typeof part.templateTagId !== 'undefined') { 404 result.templateTagId = part.templateTagId; 405 } 406 407 return result; 408 } 409 TagParts.PAGETAG = PAGETAG; 410 411 /** 412 * Gets or sets the value of the given tag part. 413 * 414 * @private 415 * @ignore 416 * @param {object} part The part whose value is to be accessed. 417 * @param {*=} value The value to set the part to. 418 * @throws CANNOT_READ_TAG_PART 419 */ 420 function accessor() { 421 var args = Array.prototype.slice.call(arguments); 422 var part = args[0]; 423 if (!TagParts[part.type]) { 424 GCN.error( 425 'CANNOT_READ_TAG_PART', 426 'Cannot read or write to tag part', 427 part 428 ); 429 return null; 430 } 431 return ( 432 args.length > 1 433 ? TagParts[part.type](part, args[1]) 434 : TagParts[part.type](part) 435 ); 436 } 437 438 /** 439 * Gets the value of the given tag part. 440 * 441 * @param {object} part The part whose value is to be retrieved. 442 * @param {*=} value The value to set the part to. 443 * @return {*} The value held in the given part. 444 * @throws CANNOT_READ_TAG_PART 445 */ 446 TagParts.get = function (part) { 447 return accessor(part); 448 }; 449 450 /** 451 * Sets the value of the given tag part. 452 * 453 * @param {object} part The part whose value is to be set. 454 * @param {*=} value The value to set the part to. 455 * @return {*} The value set to the given part. 456 * @throws CANNOT_READ_TAG_PART 457 */ 458 TagParts.set = function (part, value) { 459 return accessor(part, value); 460 }; 461 462 GCN.TagParts = TagParts; 463 464 }(GCN)); 465