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 a LIST tag part. 496 * 497 * @public 498 * @function 499 * @memberOf TagParts 500 * @name LIST 501 * @param {object} part The part whose value is to be accessed. 502 * @param {(string|string[]|object|boolean|null)=} value A string or string[] to set the listed values, 503 * or a boolean to set the 'ordered' flag or an object with the properties 504 * 'booleanValue' and/or 'stringValues' 505 * @return {object} An object containing a copy of the value of this part. 506 */ 507 function LIST(part, value) { 508 switch (jQuery.type(value)) { 509 case 'array': 510 part.stringValues = value; 511 break; 512 case 'string': 513 part.stringValues = [value]; 514 break; 515 case 'object': 516 if (typeof value.stringValues !== 'undefined') { 517 part.stringValues = value.stringValues; 518 } 519 if (typeof value.booleanValue !== 'undefined') { 520 part.booleanValue = value.booleanValue; 521 } 522 break; 523 case 'boolean': 524 part.booleanValue = value; 525 break; 526 } 527 528 var result = { 529 booleanValue: part.booleanValue, 530 stringValues: part.stringValues 531 }; 532 return result; 533 } 534 TagParts.LIST = LIST; 535 536 /** 537 * Gets or sets the value of a ORDEREDLIST tag part. 538 * 539 * @public 540 * @function 541 * @memberOf TagParts 542 * @name ORDEREDLIST 543 * @param {object} part The part whose value is to be accessed. 544 * @param {object=} value A string or string[] to set the listed values 545 * or an object with the property 'stringValues' 546 * @return {object} An object containing a copy of the value of this part. 547 */ 548 function ORDEREDLIST(part, value) { 549 switch (jQuery.type(value)) { 550 case 'array': 551 part.stringValues = value; 552 break; 553 case 'string': 554 part.stringValues = [value]; 555 break; 556 case 'object': 557 if (typeof value.stringValues !== 'undefined') { 558 part.stringValues = value.stringValues; 559 } 560 break; 561 } 562 563 var result = { stringValues: part.stringValues }; 564 return result; 565 } 566 TagParts.ORDEREDLIST = ORDEREDLIST; 567 568 /** 569 * Gets or sets the value of a UNORDEREDLIST tag part. 570 * 571 * @public 572 * @function 573 * @memberOf TagParts 574 * @name UNORDEREDLIST 575 * @param {object} part The part whose value is to be accessed. 576 * @param {object=} value A string or string[] to set the listed values 577 * or an object with the property 'stringValues' 578 * @return {object} An object containing a copy of the value of this part. 579 */ 580 function UNORDEREDLIST(part, value) { 581 return TagParts.ORDEREDLIST(part, value); 582 } 583 TagParts.UNORDEREDLIST = UNORDEREDLIST; 584 585 /** 586 * Gets or sets the value of a DATASOURCE tag part. 587 * 588 * @public 589 * @function 590 * @memberOf TagParts 591 * @name DATASOURCE 592 * @param {object} part The part whose value is to be accessed. 593 * @param {object=} value An object containing the property 'options' 594 * @return {object} An object containing a copy of the value of this part. 595 */ 596 function DATASOURCE(part, value) { 597 if (jQuery.type(value) === 'object') { 598 part.options = value.options; 599 } 600 601 return { options: part.options }; 602 } 603 TagParts.DATASOURCE = DATASOURCE; 604 605 /** 606 * Gets or sets the value of the given tag part. 607 * 608 * @private 609 * @ignore 610 * @param {object} part The part whose value is to be accessed. 611 * @param {*=} value The value to set the part to. 612 * @throws CANNOT_READ_TAG_PART 613 */ 614 function accessor() { 615 var args = Array.prototype.slice.call(arguments); 616 var part = args[0]; 617 if (!TagParts[part.type]) { 618 GCN.error( 619 'CANNOT_READ_TAG_PART', 620 'Cannot read or write to tag part', 621 part 622 ); 623 return null; 624 } 625 return ( 626 args.length > 1 627 ? TagParts[part.type](part, args[1]) 628 : TagParts[part.type](part) 629 ); 630 } 631 632 /** 633 * Gets the value of the given tag part. 634 * 635 * @param {object} part The part whose value is to be retrieved. 636 * @param {*=} value The value to set the part to. 637 * @return {*} The value held in the given part. 638 * @throws CANNOT_READ_TAG_PART 639 */ 640 TagParts.get = function (part) { 641 return accessor(part); 642 }; 643 644 /** 645 * Sets the value of the given tag part. 646 * 647 * @param {object} part The part whose value is to be set. 648 * @param {*=} value The value to set the part to. 649 * @return {*} The value set to the given part. 650 * @throws CANNOT_READ_TAG_PART 651 */ 652 TagParts.set = function (part, value) { 653 return accessor(part, value); 654 }; 655 656 GCN.TagParts = TagParts; 657 658 }(GCN)); 659