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 = function (part, value) { 134 if (jQuery.type(value) === 'object') { 135 if (value.imageId) { 136 part.imageId = value.imageId; 137 } else { 138 delete part.imageId; 139 } 140 if (value.nodeId) { 141 part.nodeId = value.nodeId; 142 } else { 143 delete part.nodeId; 144 } 145 return value; 146 } 147 148 if (typeof value !== 'undefined' && value !== null) { 149 part.imageId = value; 150 delete part.nodeId; 151 return value; 152 } 153 154 return part.imageId; 155 }; 156 157 /** 158 * Gets or sets the value of a FILE tag part. 159 * 160 * @public 161 * @function 162 * @memberOf TagParts 163 * @name FILE 164 * @param {object} part The part whose value is to be accessed. 165 * @param {number=} value Optional. The value to set for this part. 166 * @return {number} The value held by this part. 167 */ 168 // (URL) file is the same as File (upload). 169 TagParts.FILE = function (part, value) { 170 if (jQuery.type(value) === 'object') { 171 if (value.fileId) { 172 part.fileId = value.fileId; 173 } else { 174 delete part.fileId; 175 } 176 if (value.nodeId) { 177 part.nodeId = value.nodeId; 178 } else { 179 delete part.nodeId; 180 } 181 return value; 182 } 183 184 if (typeof value !== 'undefined' && value !== null) { 185 part.fileId = value; 186 delete part.nodeId; 187 return value; 188 } 189 190 return part.fileId; 191 }; 192 193 /** 194 * Gets or sets the value of a FOLDER tag part. 195 * 196 * @public 197 * @function 198 * @memberOf TagParts 199 * @name FOLDER 200 * @param {object} part The part whose value is to be accessed. 201 * @param {number=} value Optional. The value to set for this part. 202 * @return {number} The value held by this part. 203 */ 204 // (URL) folder is the same as Folder (upload). 205 TagParts.FOLDER = function (part, value) { 206 if (jQuery.type(value) === 'object') { 207 if (value.folderId) { 208 part.folderId = value.folderId; 209 } else { 210 delete part.folderId; 211 } 212 if (value.nodeId) { 213 part.nodeId = value.nodeId; 214 } else { 215 delete part.nodeId; 216 } 217 return value; 218 } 219 220 if (typeof value !== 'undefined' && value !== null) { 221 part.folderId = value; 222 delete part.nodeId; 223 return value; 224 } 225 226 return part.folderId; 227 }; 228 229 /** 230 * Gets or sets the value of a NODE tag part. 231 * 232 * @public 233 * @function 234 * @memberOf TagParts 235 * @name NODE 236 * @param {object} part The part whose value is to be accessed. 237 * @param {number=} value Optional. The value to set for this part. 238 * @return {number} The value held by this part. 239 */ 240 TagParts.NODE = createGetterSetter('nodeId'); 241 242 /** 243 * Gets or sets the value of an OVERVIEW tag part. 244 * 245 * @public 246 * @function 247 * @memberOf TagParts 248 * @name OVERVIEW 249 * @param {object} part The part whose value is to be accessed. 250 * @param {object=} value Optional. The value to set for this part. 251 * @return {object} The value held by this part. 252 */ 253 TagParts.OVERVIEW = createGetterSetter('overview'); 254 255 /** 256 * Gets or sets the value of a PAGE tag part. 257 * 258 * @public 259 * @function 260 * @memberOf TagParts 261 * @name PAGE 262 * @param {object} part The part whose value is to be accessed. 263 * @param {(number|string)=} value Optional. A number denotes and internal 264 * page within Content.Node, whereas a 265 * string denotes an external url. 266 * @return {number|string} The value held by this part. 267 */ 268 function PAGE(part, value) { 269 if (jQuery.type(value) === 'number') { 270 part.pageId = value; 271 delete part.stringValue; 272 delete part.nodeId; 273 return value; 274 } 275 276 if (jQuery.type(value) === 'string') { 277 part.stringValue = value; 278 delete part.pageId; 279 delete part.nodeId; 280 return value; 281 } 282 283 if (jQuery.type(value) === 'object') { 284 if (value.pageId) { 285 part.pageId = value.pageId; 286 } else { 287 delete part.pageId; 288 } 289 if (value.nodeId) { 290 part.nodeId = value.nodeId; 291 } else { 292 delete part.nodeId; 293 } 294 delete part.stringValue; 295 return value; 296 } 297 298 return part[ 299 jQuery.type(part.stringValue) === 'string' ? 'stringValue' 300 : 'pageId' 301 ]; 302 } 303 TagParts.PAGE = PAGE; 304 305 /** 306 * <p> 307 * Gets or sets the value of a SELECT tag part. 308 * 309 * <p> 310 * There are several possible values that can be passed to this function: 311 * 312 * <pre> 313 * undefined : When value arguments is not provided, then none of this 314 * part's data is changed. 315 * 316 * null : selectedOptions will set to an empty array. 317 * 318 * object : selectedOptions will be set to contain a single select 319 * option that corresponds with that of the 320 * `selectedOptions' property in the given object. This 321 * allowance exists for backwards compatibility, and is not 322 * recommended. 323 * 324 * string : selectedOptions will be set to contain a single select 325 * option whose `value' property corresponds with that of 326 * the argument. 327 * 328 * string[] : selectedOptions will be set to contain zero or more 329 * select option whose `value' property corresponds with 330 * that of those in the given array. 331 * </pre> 332 * 333 * @public 334 * @function 335 * @memberOf TagParts 336 * @name SELECT 337 * @param {object} part The part whose value is to be accessed. 338 * @param {(string|string[]|object|null)=} value The values with which to 339 * determined what this part's 340 * `selectedOptions' property should 341 * hold. 342 * @return {object} An object containing a copy of the value of this part. 343 * @throws VALUE_DOES_NOT_EXIST 344 */ 345 function SELECT(part, value) { 346 var options = []; 347 var option; 348 var i; 349 switch (jQuery.type(value)) { 350 case 'string': 351 option = getSelectPartOption(value, part); 352 if (option) { 353 options.push(option); 354 } else { 355 return part; 356 } 357 break; 358 case 'array': 359 for (i = 0; i < value.length; i++) { 360 option = getSelectPartOption(value[i], part); 361 if (option) { 362 options.push(option); 363 } else { 364 return part; 365 } 366 } 367 break; 368 case 'object': 369 for (i = 0; i < value.selectedOptions.length; i++) { 370 option = getSelectPartOption(value.selectedOptions[i].value, 371 part); 372 if (option) { 373 options.push(option); 374 } else { 375 return part; 376 } 377 } 378 break; 379 case 'undefined': 380 options = part.selectedOptions; 381 break; 382 } 383 384 part.selectedOptions = options; 385 386 return { 387 datasourceId: part.datasourceId, 388 options: part.options, 389 selectedOptions: part.selectedOptions 390 }; 391 } 392 TagParts.SELECT = SELECT; 393 394 /** 395 * Gets or sets the value of a MULTISELECT tag part. 396 * Operates in the same was as {@link TagParts.SELECT}. 397 * 398 * @public 399 * @function 400 * @memberOf TagParts 401 * @name MULTISELECT 402 * @param {object} part The part whose value is to be accessed. 403 * @param {(string|string[]|object|null)=} value The values with which to 404 * determined what this part's 405 * `selectedOptions' property should 406 * hold. 407 * @return {object} An object containing a copy of the value of this part. 408 */ 409 function MULTISELECT(part, value) { 410 return TagParts.SELECT(part, value); 411 } 412 TagParts.MULTISELECT = MULTISELECT; 413 414 /** 415 * Gets or sets the value of a TEMPLATETAG tag part. 416 * 417 * @public 418 * @function 419 * @memberOf TagParts 420 * @name TEMPLATETAG 421 * @param {object} part The part whose value is to be accessed. 422 * @param {object=} value An object with the either the property `templateId' 423 * or `templateTagId'. 424 * @return {object} An object containing a copy of the value of this part. 425 * 426 */ 427 function TEMPLATETAG(part, value) { 428 if (value) { 429 if (typeof value.templateId !== 'undefined') { 430 part.templateId = value.templateId; 431 } 432 433 if (typeof value.templateTagId !== 'undefined') { 434 part.templateTagId = value.templateTagId; 435 } 436 } 437 438 return { 439 templateId: part.templateId, 440 templateTagId: part.templateTagId 441 }; 442 } 443 TagParts.TEMPLATETAG = TEMPLATETAG; 444 445 /** 446 * Gets or sets the value of a PAGETAG tag part. 447 * 448 * @public 449 * @function 450 * @memberOf TagParts 451 * @name PAGETAG 452 * @param {object} part The part whose value is to be accessed. 453 * @param {object=} value An object with the the property `pageId' 454 * and/or one of `contentTagId' or `templateTagId'. 455 * @return {object} An object containing a copy of the value of this 456 * part. 457 */ 458 function PAGETAG(part, value) { 459 if (value) { 460 if (typeof value.pageId !== 'undefined') { 461 part.pageId = value.pageId; 462 } 463 464 var newContentTagIdValue; 465 // support wrongly named 'pageTagId' property for backwards compatibility 466 if (typeof value.pageTagId !== 'undefined') { 467 newContentTagIdValue = value.pageTagId; 468 } else if (typeof value.contentTagId !== 'undefined') { 469 newContentTagIdValue = value.contentTagId; 470 } 471 472 // either a contenttag OR a templatetag must be specified 473 if (typeof newContentTagIdValue !== 'undefined') { 474 part.contentTagId = newContentTagIdValue; 475 delete part.templateTagId; 476 } else if (typeof value.templateTagId !== 'undefined') { 477 part.templateTagId = value.templateTagId; 478 delete part.contentTagId; 479 } 480 } 481 482 var result = { pageId: part.pageId }; 483 484 if (typeof part.contentTagId !== 'undefined') { 485 result.contentTagId = part.contentTagId; 486 } else if (typeof part.templateTagId !== 'undefined') { 487 result.templateTagId = part.templateTagId; 488 } 489 490 return result; 491 } 492 TagParts.PAGETAG = PAGETAG; 493 494 /** 495 * Gets or sets the value of the given tag part. 496 * 497 * @private 498 * @ignore 499 * @param {object} part The part whose value is to be accessed. 500 * @param {*=} value The value to set the part to. 501 * @throws CANNOT_READ_TAG_PART 502 */ 503 function accessor() { 504 var args = Array.prototype.slice.call(arguments); 505 var part = args[0]; 506 if (!TagParts[part.type]) { 507 GCN.error( 508 'CANNOT_READ_TAG_PART', 509 'Cannot read or write to tag part', 510 part 511 ); 512 return null; 513 } 514 return ( 515 args.length > 1 516 ? TagParts[part.type](part, args[1]) 517 : TagParts[part.type](part) 518 ); 519 } 520 521 /** 522 * Gets the value of the given tag part. 523 * 524 * @param {object} part The part whose value is to be retrieved. 525 * @param {*=} value The value to set the part to. 526 * @return {*} The value held in the given part. 527 * @throws CANNOT_READ_TAG_PART 528 */ 529 TagParts.get = function (part) { 530 return accessor(part); 531 }; 532 533 /** 534 * Sets the value of the given tag part. 535 * 536 * @param {object} part The part whose value is to be set. 537 * @param {*=} value The value to set the part to. 538 * @return {*} The value set to the given part. 539 * @throws CANNOT_READ_TAG_PART 540 */ 541 TagParts.set = function (part, value) { 542 return accessor(part, value); 543 }; 544 545 GCN.TagParts = TagParts; 546 547 }(GCN)); 548