PageSourceSearch

https://www.countries.com/odf/js/odf.js

js countries.com collected 2026-09-28 11:06:17 UTC 21,214 bytes, 781 lines download raw bytes

1/*
2Last update: 2013-2-17
3*/
4
5/*
6A shortcut to console.log
7*/
8function say(input) {
9	console.log(input);
10}
11
12(function(window, jQuery) {
13	var $ = jQuery;
14	
15	/*
16	Returns the library with the given selection saved to it, so that we can work with that
17	selection when executing other functions in the Odf library.
18	
19	@param string jquery_selector
20		The string that is used by jQuery to create a selection, e.g. "div#container".
21	*/
22	function Odf(jquery_selector) {
23		if(!$(jquery_selector).length) {
24			console.log('Error: target (' + jquery_selector + ') not found.');
25			return false;
26		}
27		else {
28			return new Odf.prototype.select(jquery_selector);
29		}
30	}
31	
32	
33	
34	// Define the Odf library's functions.
35	Odf.prototype = {
36	
37		/*
38		Saves the given selection to the object so that we can work with it later on. This function
39		is executed when the Odf() function is executed and is returned as an object containing
40		the Odf prototype.
41	
42		@param string jquery_selector
43			The string that is used by jQuery to create a selection, e.g. "div#container".
44		*/
45		select: function(jquery_selector) {
46			Odf.selection = $(jquery_selector);
47			this.length = Odf.selection.length;
48		},
49	
50		
51		settings: {
52			loading_image: 'img/loading.gif',
53			loading_image_big: 'img/loading_big.gif',
54			loading_image_black_bg: 'img/loading_black_bg.gif',
55			loading_image_black_bg_big: 'img/loading_black_bg_big.gif'
56		},
57		
58		
59		/*
60		Sets a var in this.settings, which can be retrieved through this.get() in any function
61		you'd like. I'd rather have a function for this than calling this.settings.varname all the 
62		time :).
63		
64		@param string key
65			The key for which to set the value.
66		@param mixed value
67			The value to store.
68		@return nothing
69		*/
70		set: function(key, value) {
71			Odf.settings[key] = value;
72		},
73		
74		
75		/*
76		Returns a var from Odf.settings.
77		
78		@param string key
79			The key of which to retrieve the value.
80		@return mixed
81			The value of the requested key.
82		*/
83		get: function(key) {
84			return Odf.settings[key];
85		},
86		
87		
88		/*
89		Initiates the ODF library, enabling stuff like AJAX functionality for forms with the
90		"odf_ajax" class.
91		*/
92		init: function() {
93			// Ready href class elements.
94			$('.odf_href').click(function() {
95				var href = $(this).data('href');
96				window.location.href = href;
97			});
98			
99			// Ready <tr> hovers.
100			$('.odf_hover').hover(function() {
101				$(this).addClass('hovered');
102			},
103			function() {
104				$(this).removeClass('hovered');
105			});
106			
107			// Ready forms.
108			$('form.odf_ajax').each(function() {
109				$(this).on('submit', function() {
110					Odf.ajax.submit.call(this);
111					return false;
112				});
113			});
114		},
115		
116		
117		/***********************************************************************
118		AJAX functionalities
119		*/
120		
121		ajax: {
122			
123			/*
124			Sets a target to load AJAX results in that are returned by Odf's AJAX functions.
125			
126			@param string selector
127				The jQuery selector for the target. E.g. 'div#ajax_target'.
128			@return none
129			*/
130			setTarget: function(selector) {
131				this.selectors.ajax_target = $(selector);
132			},
133			
134			
135			/*
136			Returns the target previously set by this.setTarget() as jQuery object.
137			
138			@return object
139				The target as jQuery object.
140			*/
141			getTarget: function() {
142				var r = $(this.selectors.ajax_target);
143				return r;
144			},
145			
146			
147			/*
148			Sets the HTML to be parsed by other AJAX functions.
149			
150			@param object html
151				The object used in jQuery's $.ajax() function, in its. success(html) function.
152			@return none
153			*/
154			setHtml: function(html) {
155				Odf.set('html', html);
156			},
157			
158			
159			/*
160			Returns the value of a hidden return <input> from the HTML that was set by this.setHtml().
161			
162			@param string return_name
163				The name of the hidden return input to get the status from. These inputs must be
164				have the "odf_return_" prefix.
165			@return string
166				The value of the targeted hidden <input>.
167			*/
168			getReturn: function(return_name) {
169				html = Odf.get('html');
170				
171				// Parse the HTML.
172				html = $.parseHTML(html);
173				
174				// Contain the HTML in an invisible <div> so that we can search through it.
175				var div = $('<div></div>');
176				div.html(html);
177				
178				// Get the return status.
179				var status = div.find('input[name=odf_return_' + return_name + ']').val();
180				
181				return status;
182			},
183			
184			
185			/*
186			Removes the hidden return <inputs> in the HTML set by this.setHtml().
187			
188			@return object
189				The HTML object without the hidden return <input>s.
190			*/
191			removeReturns: function() {
192				html = Odf.get('html');
193				
194				// Parse the HTML.
195				// html = $.parseHTML(html);
196				
197				// Contain the HTML in an invisible <div> so that we can search through it.
198				var div = $('<div></div>');
199				div.html(html);
200				
201				// Remove the return status from the returned HTML.
202				div.find('input[name^=odf_return_]').remove();
203				
204				// Remove the container <div> as we're done searching the returned HTML.
205				html = div.html();
206				
207				return html;
208			},
209			
210			/*
211			Create a custom XMLHttpRequest object.
212			
213			@return object
214				Returns a custom XMLHttpRequest object.
215			*/
216			createXhr: function() {
217				var xhr = new window.XMLHttpRequest();
218				
219				// Upload progress
220				xhr.upload.addEventListener('progress', function(e) {
221					if(e.lengthComputable) {
222						var progress_percentage = Math.ceil((e.loaded / e.total) * 100);
223						$('span#progress_percentage').html(progress_percentage + ' %');
224					}
225				}, false);
226				
227				// Download progress
228				xhr.addEventListener('progress', function(e) {
229					if(e.lengthComputable) {
230						var progress_percentage = Math.ceil((e.loaded / e.total) * 100);
231					}
232				}, false);
233				
234				return xhr;
235			},
236
237			removeLoadingImage: function(loading_image_id) {
238				if(loading_image_id) {
239					$('img#' + loading_image_id).remove();
240				}
241				else {
242					$('img.odf_loading_image').remove();
243				}
244			},
245			
246			
247			/*
248			Submits a form through AJAX.
249			
250			[@param object odf_return_status_functions]
251				Contains a function to execute for each status that is returned in the $.ajax()'s
252				success() function. E.g. { success: function() { ... } }
253			[@param bool use_toggle_instead_of_slide]
254				If set to true, the function will not use an animation to display the results of the
255				action.
256			*/
257			submit: function(odf_return_status_functions, use_toggle_instead_of_slide) {
258				var self = $(this); // The form that was submitted.
259				
260				if(self[0].tagName.toLowerCase() != 'form') {
261					console.log('Error: cannot submit a non-form.');
262					return false;
263				}
264				
265				var action = self.attr('action');
266				var method = self.attr('method');
267				var target = $('div#' + self.data('target'));
268				
269				$.ajax({
270					url: action,
271					type: method.toUpperCase(),
272					data: self.serialize(),
273					beforeSend: function() {
274						// Remove any existing loading images.
275						Odf.ajax.removeLoadingImage();
276					
277						// #
278						// # Display loading image.
279						// #
280							
281							var img = $('<img src="' + Odf.get('loading_image') + '" class="odf_loading_image">');
282							var submit_button = self.find('input[type=submit]:first');
283
284							if(!submit_button.length)
285								var submit_button = self.find('button[type=submit]:first');
286							
287							if(!submit_button.length) {
288								if(self.data('submit_button_id'))
289									submit_button = $('input#' + self.data('submit_button_id'));
290								else
291									submit_button = $('input[type=submit]:last');
292							}
293							
294							var offset = submit_button.offset();
295							
296							// Display the loading image.
297							$('body').prepend(img);
298							img = $('img.odf_loading_image:first');
299							
300							
301							// Offset top
302							if(submit_button.height() > img.height()) {
303								var additional_offset_top = (submit_button.height() - img.height()) / 2;
304							}
305							else {
306								var additional_offset_top = (img.height() - submit_button.height()) / 2;
307							}
308							
309							var offset_top = offset.top + additional_offset_top
310							
311							
312							// Offset left
313							var additional_offset_left = parseInt(submit_button.css('padding-left')) + parseInt(submit_button.css('padding-right'));
314							
315							if(self.hasClass('odf_loading_image_left')) {
316								//* The loading image is to be displayed to the left of the submit button.
317								var offset_left = offset.left - img.width() - 10;
318							}
319							else {
320								//* The loading image is to be displayed to the right of the submit button.
321								var offset_left = offset.left + submit_button.width() + additional_offset_left + 10;
322							}
323							
324							img.css({
325								position: 'absolute',
326								top: offset_top,
327								left: offset_left,
328								'z-index': 100
329							});
330						
331						// # --/
332						
333					},
334					success: function(html) {
335						Odf.ajax.removeLoadingImage();
336						Odf.ajax.setHtml(html);
337						var slide_speed = 300;
338						
339						
340						// Do we have to execute a redirect?
341						var redirect = Odf.ajax.getReturn('redirect');
342						
343						if(redirect) {
344							window.location.href = redirect;
345							console.log('redirect');
346							return;
347						}
348						
349						
350						// Have special return status functions been given? E.g. if a "success" return
351						// status should produce a different result as a "error" return status.
352						if(odf_return_status_functions) {
353							var status = Odf.ajax.getReturn('status');
354							var function_to_execute = odf_return_status_functions[status];
355							
356							// Has a custom function to execute been given?
357							if(function_to_execute) {
358								var r = function_to_execute(html);
359								
360								// If the function to execute returns false, this is a special sign
361								// to not execute any more default functionality.
362								if(r === false)
363									return;
364							}
365							
366							var html = Odf.ajax.removeReturns();
367						}
368						
369						
370						// Display return HTML.
371						if(target && use_toggle_instead_of_slide) {
372							target.html(html).show();
373						}
374						else if(target) {
375						
376							if(target.is(':hidden')) {
377								target.stop().html(html).slideToggle(slide_speed);
378							}
379							else {
380								// Wrap the contents of the target, so that we won't have to change
381								// the target's height during the sliding, so that the page height
382								// will remain unchanged.
383								target.wrapInner('<div id="odf_tmp_ajax_wrapper"></div>');
384								var fake_target = $('div#odf_tmp_ajax_wrapper');
385								
386								
387								// Make sure the container will keep the same height, so that the 
388								// sliding won't affect the page's height.
389								var current_height = target.height();
390								target.height(current_height);
391								
392								fake_target.stop().slideToggle(slide_speed, function() {
393									// Set the target's content.
394									$(this).stop().html(html);
395									
396									// Get the content's new height witout revealing the element.
397									$(this).show();
398									var new_height = $(this).height();
399									$(this).hide();
400									
401									// If there is a height difference, make sure the container
402									// takes on a new height.
403									if(new_height != current_height) {
404										target.animate({
405											height: new_height
406										});
407									}
408									
409									// Show the content.
410									$(this).slideToggle(slide_speed, function() {
411										fake_target.remove();
412										var contents = fake_target.html();
413										target.html(contents);
414									});
415								});
416							}
417							
418							// Make sure the displayed message is seen by scrolling to it if it is not
419							// in the current view.
420							var message_offset_top = target.offset().top;
421							
422							if(message_offset_top < $(window).scrollTop()) {
423								var new_scroll_top = message_offset_top - 10;
424								new_scroll_top = new_scroll_top < 0 ? 0 : new_scroll_top;
425								
426								$('html, body').animate({
427									scrollTop: new_scroll_top
428								});
429							}
430						}
431					},
432					error: function(error) {
433						//alert('Ouch, something has gone terribly, terribly wrong.. The requested page could not be found or loaded :\\.');
434						console.log(error.statusText);
435					}
436				});
437				
438				return false;
439			},
440			
441			
442			/*
443			Loads a specific file through AJAX using GET. Creates a neat loading overlay in the
444			process.
445			
446			@param str url
447				The URL to load.
448			@param str target_element_selector
449				The selector of the element in which to load the results. E.g. div#div_id.
450			[@param obj data]
451				Data to pass to the file that is loaded. E.g. { name: 'Stephan' }.
452			*/
453			get: function(url, target_element_selector, data) {
454				Odf.ajax.load(url, target_element_selector, data, 'get');
455			},
456			
457			/*
458			Loads a specific file through AJAX using POST. Creates a neat loading overlay in the
459			process.
460			
461			@param str url
462				The URL to load.
463			@param str target_element_selector
464				The selector of the element in which to load the results. E.g. div#div_id.
465			[@param obj data]
466				Data to pass to the file that is loaded. E.g. { name: 'Stephan' }.
467			*/
468			post: function(url, target_element_selector, data) {
469				Odf.ajax.load(url, target_element_selector, data, 'post');
470			},
471			
472			/*
473			Loads a specific file through AJAX. Creates a neat loading overlay in the process.
474			
475			@param str url
476				The URL to load.
477			@param str target_element_selector
478				The selector of the element in which to load the results. E.g. div#div_id.
479			[@param obj data]
480				Data to pass to the file that is loaded. E.g. { name: 'Stephan' }.
481			*/
482			load: function(url, target_element_selector, data, type) {
483				switch(type) {
484					default:
485						console.log('Error: invalid type (' + type + ').');
486						break;
487					
488					case 'post':
489					case 'get':
490						break;
491				}
492				
493				var selection = Odf(target_element_selector);
494				if(!selection.length) {
495					console.log('Warning: selection could not be made with ' + target_element_selector);
496					return false;
497				}
498				
499				$.ajax({
500					url: url,
501					type: type,
502					data: data,
503					beforeSend: function() {
504						Odf(target_element_selector).removeLoadingOverlay();
505						Odf(target_element_selector).createLoadingOverlay();
506					},
507					success: function(html) {
508						Odf(target_element_selector).removeLoadingOverlay();
509						$(target_element_selector).html(html);
510					},
511					error: function(error) {
512						Odf(target_element_selector).removeLoadingOverlay();
513						console.log('Error: ' + error.statusText);
514					}
515				});
516			},
517		
518			/*
519			W.I.P.!
520			
521			Calls to the file specified in results_url for search results based on what has been
522			typed in element. This file must return JSON.
523			
524			@parameter string|object options
525				If string:
526					The url to the file that will return the search results. This file must return
527					JSON.
528				If object:
529					An object containing the options for this function:
530					@key string results_url
531						The url to the file that will return the search results. This file must return
532						JSON.
533					[@key int min_length]
534						The minimum number of characters that must have been typed before the
535						search is triggered.
536			*/
537			autoComplete: function(options) {
538				var selection = Odf.selection;
539				var min_length = 3;
540				
541				console.log(selection);
542				
543				if(typeof options == 'string') {
544					var results_url = options;
545				}
546				else if(typeof options == 'object') {
547					var results_url = options.results_url;
548					min_length = options.min_length || min_length;
549				}
550				
551				
552				// We require a results url.
553				if(!results_url)
554					return false;
555				
556				
557				selection.each(function() {
558					$(this).blur(function() {
559						// alert('a');
560						$('div#odf_autocomplete_results').remove();
561					});
562					
563					$(this).keyup(function() {
564						var self = $(this);
565						var value = $.trim(self.val());
566						
567						if(value.length < min_length)
568							return;
569						
570						$.ajax({
571							type: 'POST',
572							data: { search: value },
573							url: results_url,
574							beforeSend: function() {
575								// Show loading image next to self.
576								$('body').prepend('<img src="' + Odf.get('loading_image') + '" class="odf_loading_image">');
577								
578								$('body img.odf_loading_image:first').css({
579									position: 'absolute',
580									top: Math.round(
581										self.offset().top
582										- (self.outerHeight() / 4)
583									),
584									left: Math.round(
585										self.offset().left
586										+ self.outerWidth()
587										+ 10
588									),
589									'z-index': 100
590								});
591								
592								
593							},
594							success: function(html) {
595								Odf.ajax.removeLoadingImage();
596								
597								// Remove any existing results.
598								$('div#odf_autocomplete_results').remove();
599								
600								// Wrap self in a container.
601								self.wrap('<div id="odf_autocomplete_container"></div>');
602								var container = $('div#odf_autocomplete_container');
603								
604								// Create results <div>.
605								container.append('<div id="odf_autocomplete_results"></div>');
606								var div = $('div#odf_autocomplete_results');
607								
608								div.css({
609									width: self.width(),
610									top: self.outerHeight(),
611									'z-index': 100
612								});
613								
614								
615								if(!html) {
616									div.html('<p>' + Odf.lang('no_results_found') + '</p>');
617								}
618								else {
619									// Parse JSON.
620									var json = $.parseJSON(html);
621									console.log(json);
622								}
623								
624								// Make sure focus isn't lost, which is/was somehow happening.
625								self.focus();
626							}
627						});
628					});
629				});
630			}
631			
632		},
633		
634		
635		/***********************************************************************
636		Language functions.
637		*/
638		
639		/*
640		Returns the translation with the given key.
641		
642		@param str key
643			The key for which to return the translation.
644		*/
645		translate: function(key) {
646			var language = Odf.get('language');
647			
648			if(odf_translations[language][key]) {
649				return odf_translations[language][key];
650			}
651			else {
652				console.log('No translation found for key ' + key + ' in language ' + language + '.');
653				return false;
654			}
655		},
656		
657		
658		/***********************************************************************
659		Utility functions
660		*/
661		
662		utility: {},
663		
664		
665		/***********************************************************************
666		Other/general functionalities
667		*/
668		
669		
670		/*
671		Creates a loading overlay in the ODF selection (Odf(selector)).
672		*/
673		createLoadingOverlay: function() {
674			var selection = Odf.selection;
675			if(!selection.length) {
676				console.log('Error: no selection.');
677				return false;
678			}
679			
680			selection = selection.first();
681			
682			var div = $('<div></div>');
683			div.prependTo(selection);
684			div.addClass('odf_loading_overlay');
685			div.css({
686				position: 'absolute',
687				width: selection.innerWidth(),
688				height: selection.innerHeight(),
689				'background-color': '#000',
690				opacity: 0.33,
691				'-moz-opacity': 0.33
692			});
693			
694			var loading_image = $('<img src="' + Odf.get('loading_image_black_bg_big') + '" class="odf_loading_image">');
695			loading_image.prependTo(div);
696			loading_image.css({
697				position: 'absolute',
698				top: (div.outerHeight() / 2) - (loading_image.height() / 2),
699				left: (div.outerWidth() / 2) - (loading_image.width() / 2)
700			});
701		},
702		
703		/*
704		Removes the loading overlay from the ODF selection (Odf(selector)).
705		*/
706		removeLoadingOverlay: function() {
707			var selection = Odf.selection;
708			if(!selection.length) {
709				console.log('Error: no selection.');
710				return false;
711			}
712			
713			selection = selection.first();
714			selection.find('div.odf_loading_overlay').remove();
715		},
716		
717		/*
718		Sets the text cursor position or creates a selection range.
719		
720		@this
721			The element in which the range is to be created.
722		*/
723		setTextCursorPosition: function(start_position, end_position) {
724			self = $(this);
725			
726			if(!self)
727				return false;
728
729			if(self.createTextRange) {
730				var textRange = self.createTextRange();
731				textRange.collapse(true);
732				textRange.moveStart(start_position);
733				textRange.moveEnd(end_position);
734				textRange.select();
735				return true;
736			}
737			else if(self.setSelectionRange) {
738				self.setSelectionRange(start_position, end_position);
739				return true;
740			}
741
742			return false;
743		},
744
745		/*
746		Checks if the number of characters that are being typed in an element do not
747		exceed the maximum number of allowed characters.
748		
749		@this
750			The element in which is being typed.
751		@param int max_length
752			The maximum number of characters that may be typed in the element.
753		*/
754		checkLength: function(max_length) {
755			var self = $(this), // The textarea that was typed in.
756				length = self.val().length;
757			
758			if(length >= max_length) {
759				self.val(self.val().substr(0, max_length));
760				$('#textarea_length').html('2000 / ' + max_length);
761				return false;
762			}
763			
764			$('#textarea_length').html(length + ' / ' + max_length);
765		}
766	};
767	
768	// Make sure the prototype's functions are also directly available.
769	for(var key in Odf.prototype) {
770		Odf[key] = Odf.prototype[key];
771	}
772	
773	// Make sure the Odf prototype's functions are available to the object that is returned when
774	// the Odf() function is called.
775	Odf.prototype.select.prototype = Odf.prototype;
776	
777	
778	// Make the Odf library globally available.
779	window.Odf = Odf;
780	
781})(window, jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.