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 either the property `pageId'
358 	 *                        or `pageTagId'.
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 			if (typeof value.pageTagId !== 'undefined') {
369 				part.pageTagId = value.pageTagId;
370 			}
371 		}
372 
373 		return {
374 			templateId: part.pageId,
375 			templateTagId: part.pageTagId
376 		};
377 	}
378 	TagParts.PAGETAG = PAGETAG;
379 
380 	/**
381 	 * Gets or sets the value of the given tag part.
382 	 *
383 	 * @private
384 	 * @ignore
385 	 * @param {object} part The part whose value is to be accessed.
386 	 * @param {*=} value The value to set the part to.
387 	 * @throws CANNOT_READ_TAG_PART
388 	 */
389 	function accessor() {
390 		var args = Array.prototype.slice.call(arguments);
391 		var part = args[0];
392 		if (!TagParts[part.type]) {
393 			GCN.error(
394 				'CANNOT_READ_TAG_PART',
395 				'Cannot read or write to tag part',
396 				part
397 			);
398 			return null;
399 		}
400 		return (
401 			args.length > 1
402 				? TagParts[part.type](part, args[1])
403 				: TagParts[part.type](part)
404 		);
405 	}
406 
407 	/**
408 	 * Gets the value of the given tag part.
409 	 *
410 	 * @param {object} part The part whose value is to be retrieved.
411 	 * @param {*=} value The value to set the part to.
412 	 * @return {*} The value held in the given part.
413 	 * @throws CANNOT_READ_TAG_PART
414 	 */
415 	TagParts.get = function (part) {
416 		return accessor(part);
417 	};
418 
419 	/**
420 	 * Sets the value of the given tag part.
421 	 *
422 	 * @param {object} part The part whose value is to be set.
423 	 * @param {*=} value The value to set the part to.
424 	 * @return {*} The value set to the given part.
425 	 * @throws CANNOT_READ_TAG_PART
426 	 */
427 	TagParts.set = function (part, value) {
428 		return accessor(part, value);
429 	};
430 
431 	GCN.TagParts = TagParts;
432 
433 }(GCN));
434