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