vendor: 36,634 bytes, lines 1-1404
1// wrap in UMD - see https://github.com/umdjs/umd/blob/master/jqueryPlugin.js 2(function(factory) { 3 if (typeof define === "function" && define.amd) { 4 define([ "jquery" ], function($) { 5 factory($, window, document); 6 }); 7 } else if (typeof module === "object" && module.exports) { 8 module.exports = factory(require("jquery"), window, document); 9 } else { 10 factory(jQuery, window, document); 11 } 12})(function($, window, document, undefined) { 13 "use strict"; 14 var pluginName = "countrySelect", id = 1, // give each instance its own ID for namespaced event handling 15 defaults = { 16 // Default country 17 defaultCountry: "", 18 // Position the selected flag inside or outside of the input 19 defaultStyling: "inside", 20 // don't display these countries 21 excludeCountries: [], 22 // Display only these countries 23 onlyCountries: [], 24 // The countries at the top of the list. Defaults to United States and United Kingdom 25 preferredCountries: [ "us", "gb" ], 26 // localized country names e.g. { 'de': 'Deutschland' } 27 localizedCountries: null, 28 // Set the dropdown's width to be the same as the input. This is automatically enabled for small screens. 29 responsiveDropdown: ($(window).width() < 768 ? true : false), 30 }, keys = { 31 UP: 38, 32 DOWN: 40, 33 ENTER: 13, 34 ESC: 27, 35 BACKSPACE: 8, 36 PLUS: 43, 37 SPACE: 32, 38 A: 65, 39 Z: 90 40 }, windowLoaded = false; 41 // keep track of if the window.load event has fired as impossible to check after the fact 42 $(window).on('load', function() { 43 windowLoaded = true; 44 }); 45 function Plugin(element, options) { 46 this.element = element; 47 this.options = $.extend({}, defaults, options); 48 this._defaults = defaults; 49 // event namespace 50 this.ns = "." + pluginName + id++; 51 this._name = pluginName; 52 this.init(); 53 } 54 Plugin.prototype = { 55 init: function() { 56 // Process all the data: onlyCountries, excludeCountries, preferredCountries, defaultCountry etc 57 this._processCountryData(); 58 // Generate the markup 59 this._generateMarkup(); 60 // Set the initial state of the input value and the selected flag 61 this._setInitialState(); 62 // Start all of the event listeners: input keyup, selectedFlag click 63 this._initListeners(); 64 // Return this when the auto country is resolved. 65 this.autoCountryDeferred = new $.Deferred(); 66 // Get auto country. 67 this._initAutoCountry(); 68 // Keep track as the user types 69 this.typedLetters = ""; 70 71 return this.autoCountryDeferred; 72 }, 73 /******************** 74 * PRIVATE METHODS 75 ********************/ 76 // prepare all of the country data, including onlyCountries, excludeCountries, preferredCountries and 77 // defaultCountry options 78 _processCountryData: function() { 79 // set the instances country data objects 80 this._setInstanceCountryData(); 81 // set the preferredCountries property 82 this._setPreferredCountries(); 83 // translate countries according to localizedCountries option 84 if (this.options.localizedCountries) this._translateCountriesByLocale(); 85 // sort countries by name 86 if (this.options.onlyCountries.length || this.options.localizedCountries) { 87 this.countries.sort(this._countryNameSort); 88 } 89 }, 90 // process onlyCountries array if present 91 _setInstanceCountryData: function() { 92 var that = this; 93 if (this.options.onlyCountries.length) { 94 var newCountries = []; 95 $.each(this.options.onlyCountries, function(i, countryCode) { 96 var countryData = that._getCountryData(countryCode, true); 97 if (countryData) { 98 newCountries.push(countryData); 99 } 100 }); 101 this.countries = newCountries; 102 } else if (this.options.excludeCountries.length) { 103 var lowerCaseExcludeCountries = this.options.excludeCountries.map(function(country) { 104 return country.toLowerCase(); 105 }); 106 this.countries = allCountries.filter(function(country) { 107 return lowerCaseExcludeCountries.indexOf(country.iso2) === -1; 108 }); 109 } else { 110 this.countries = allCountries; 111 } 112 }, 113 // Process preferred countries - iterate through the preferences, 114 // fetching the country data for each one 115 _setPreferredCountries: function() { 116 var that = this; 117 this.preferredCountries = []; 118 $.each(this.options.preferredCountries, function(i, countryCode) { 119 var countryData = that._getCountryData(countryCode, false); 120 if (countryData) { 121 that.preferredCountries.push(countryData); 122 } 123 }); 124 }, 125 // Translate Countries by object literal provided on config 126 _translateCountriesByLocale() { 127 for (let i = 0; i < this.countries.length; i++) { 128 const iso = this.countries[i].iso2.toLowerCase(); 129 if (this.options.localizedCountries.hasOwnProperty(iso)) { 130 this.countries[i].name = this.options.localizedCountries[iso]; 131 } 132 } 133 }, 134 // sort by country name 135 _countryNameSort(a, b) { 136 return a.name.localeCompare(b.name); 137 }, 138 // generate all of the markup for the plugin: the selected flag overlay, and the dropdown 139 _generateMarkup: function() { 140 // Country input 141 this.countryInput = $(this.element); 142 // containers (mostly for positioning) 143 var mainClass = "country-select"; 144 if (this.options.defaultStyling) { 145 mainClass += " " + this.options.defaultStyling; 146 } 147 this.countryInput.wrap($("<div>", { 148 "class": mainClass 149 })); 150 var flagsContainer = $("<div>", { 151 "class": "flag-dropdown" 152 }).insertAfter(this.countryInput); 153 // currently selected flag (displayed to left of input) 154 var selectedFlag = $("<div>", { 155 "class": "selected-flag" 156 }).appendTo(flagsContainer); 157 this.selectedFlagInner = $("<div>", { 158 "class": "flag" 159 }).appendTo(selectedFlag); 160 // CSS triangle 161 $("<div>", { 162 "class": "arrow" 163 }).appendTo(selectedFlag); 164 // country list contains: preferred countries, then divider, then all countries 165 this.countryList = $("<ul>", { 166 "class": "country-list v-hide" 167 }).appendTo(flagsContainer); 168 if (this.preferredCountries.length) { 169 this._appendListItems(this.preferredCountries, "preferred"); 170 $("<li>", { 171 "class": "divider" 172 }).appendTo(this.countryList); 173 } 174 this._appendListItems(this.countries, ""); 175 // Add the hidden input for the country code 176 this.countryCodeInput = $("#"+this.countryInput.attr("id")+"_code"); 177 if (!this.countryCodeInput) { 178 this.countryCodeInput = $('<input type="hidden" id="'+this.countryInput.attr("id")+'_code" name="'+this.countryInput.attr("name")+'_code" value="" />'); 179 this.countryCodeInput.insertAfter(this.countryInput); 180 } 181 // now we can grab the dropdown height, and hide it properly 182 this.dropdownHeight = this.countryList.outerHeight(); 183 // set the dropdown width according to the input if responsiveDropdown option is present or if it's a small screen 184 if (this.options.responsiveDropdown) { 185 $(window).resize(function() { 186 $('.country-select').each(function() { 187 var dropdownWidth = this.offsetWidth; 188 $(this).find('.country-list').css("width", dropdownWidth + "px"); 189 }); 190 }).resize(); 191 } 192 this.countryList.removeClass("v-hide").addClass("hide"); 193 // this is useful in lots of places 194 this.countryListItems = this.countryList.children(".country"); 195 }, 196 // add a country <li> to the countryList <ul> container 197 _appendListItems: function(countries, className) { 198 // Generate DOM elements as a large temp string, so that there is only 199 // one DOM insert event 200 var tmp = ""; 201 // for each country 202 $.each(countries, function(i, c) { 203 // open the list item 204 tmp += '<li class="country ' + className + '" data-country-code="' + c.iso2 + '">'; 205 // add the flag 206 tmp += '<div class="flag ' + c.iso2 + '"></div>'; 207 // and the country name 208 tmp += '<span class="country-name">' + c.name + '</span>'; 209 // close the list item 210 tmp += '</li>'; 211 }); 212 this.countryList.append(tmp); 213 }, 214 // set the initial state of the input value and the selected flag 215 _setInitialState: function() { 216 var flagIsSet = false; 217 // If the input is pre-populated, then just update the selected flag 218 if (this.countryInput.val()) { 219 flagIsSet = this._updateFlagFromInputVal(); 220 } 221 // If the country code input is pre-populated, update the name and the selected flag 222 var selectedCode = this.countryCodeInput.val(); 223 if (selectedCode) { 224 this.selectCountry(selectedCode); 225 } 226 if (!flagIsSet) { 227 // flag is not set, so set to the default country 228 var defaultCountry; 229 // check the defaultCountry option, else fall back to the first in the list 230 if (this.options.defaultCountry) { 231 defaultCountry = this._getCountryData(this.options.defaultCountry, false); 232 // Did we not find the requested default country? 233 if (!defaultCountry) { 234 defaultCountry = this.preferredCountries.length ? this.preferredCountries[0] : this.countries[0]; 235 } 236 } else { 237 defaultCountry = this.preferredCountries.length ? this.preferredCountries[0] : this.countries[0]; 238 } 239 this.defaultCountry = defaultCountry.iso2; 240 } 241 }, 242 // initialise the main event listeners: input keyup, and click selected flag 243 _initListeners: function() { 244 var that = this; 245 // Update flag on keyup. 246 // Use keyup instead of keypress because we want to update on backspace 247 // and instead of keydown because the value hasn't updated when that 248 // event is fired. 249 // NOTE: better to have this one listener all the time instead of 250 // starting it on focus and stopping it on blur, because then you've 251 // got two listeners (focus and blur) 252 this.countryInput.on("keyup" + this.ns, function() { 253 that._updateFlagFromInputVal(); 254 }); 255 // toggle country dropdown on click 256 var selectedFlag = this.selectedFlagInner.parent(); 257 selectedFlag.on("click" + this.ns, function(e) { 258 // only intercept this event if we're opening the dropdown 259 // else let it bubble up to the top ("click-off-to-close" listener) 260 // we cannot just stopPropagation as it may be needed to close another instance 261 if (that.countryList.hasClass("hide") && !that.countryInput.prop("disabled")) { 262 that._showDropdown(); 263 } 264 }); 265 // Despite above note, added blur to ensure partially spelled country 266 // with correctly chosen flag is spelled out on blur. Also, correctly 267 // selects flag when field is autofilled 268 this.countryInput.on("blur" + this.ns, function() { 269 if (that.countryInput.val() != that.getSelectedCountryData().name) { 270 that.setCountry(that.countryInput.val()); 271 } 272 that.countryInput.val(that.getSelectedCountryData().name); 273 }); 274 }, 275 _initAutoCountry: function() { 276 if (this.options.initialCountry === "auto") { 277 this._loadAutoCountry(); 278 } else { 279 if (this.defaultCountry) { 280 this.selectCountry(this.defaultCountry); 281 } 282 this.autoCountryDeferred.resolve(); 283 } 284 }, 285 // perform the geo ip lookup 286 _loadAutoCountry: function() { 287 var that = this; 288 289 // 3 options: 290 // 1) already loaded (we're done) 291 // 2) not already started loading (start) 292 // 3) already started loading (do nothing - just wait for loading callback to fire) 293 if ($.fn[pluginName].autoCountry) { 294 this.handleAutoCountry(); 295 } else if (!$.fn[pluginName].startedLoadingAutoCountry) { 296 // don't do this twice! 297 $.fn[pluginName].startedLoadingAutoCountry = true; 298 299 if (typeof this.options.geoIpLookup === 'function') { 300 this.options.geoIpLookup(function(countryCode) { 301 $.fn[pluginName].autoCountry = countryCode.toLowerCase(); 302 // tell all instances the auto country is ready 303 // TODO: this should just be the current instances 304 // UPDATE: use setTimeout in case their geoIpLookup function calls this callback straight away (e.g. if they have already done the geo ip lookup somewhere else). Using setTimeout means that the current thread of execution will finish before executing this, which allows the plugin to finish initialising. 305 setTimeout(function() { 306 $(".country-select input").countrySelect("handleAutoCountry"); 307 }); 308 }); 309 } 310 } 311 }, 312 // Focus input and put the cursor at the end 313 _focus: function() { 314 this.countryInput.focus(); 315 var input = this.countryInput[0]; 316 // works for Chrome, FF, Safari, IE9+ 317 if (input.setSelectionRange) { 318 var len = this.countryInput.val().length; 319 input.setSelectionRange(len, len); 320 } 321 }, 322 // Show the dropdown 323 _showDropdown: function() { 324 this._setDropdownPosition(); 325 // update highlighting and scroll to active list item 326 var activeListItem = this.countryList.children(".active"); 327 this._highlightListItem(activeListItem); 328 // show it 329 this.countryList.removeClass("hide"); 330 this._scrollTo(activeListItem); 331 // bind all the dropdown-related listeners: mouseover, click, click-off, keydown 332 this._bindDropdownListeners(); 333 // update the arrow 334 this.selectedFlagInner.parent().children(".arrow").addClass("up"); 335 }, 336 // decide where to position dropdown (depends on position within viewport, and scroll) 337 _setDropdownPosition: function() { 338 var inputTop = this.countryInput.offset().top, windowTop = $(window).scrollTop(), 339 dropdownFitsBelow = inputTop + this.countryInput.outerHeight() + this.dropdownHeight < windowTop + $(window).height(), dropdownFitsAbove = inputTop - this.dropdownHeight > windowTop; 340 // dropdownHeight - 1 for border 341 var cssTop = !dropdownFitsBelow && dropdownFitsAbove ? "-" + (this.dropdownHeight - 1) + "px" : ""; 342 this.countryList.css("top", cssTop); 343 }, 344 // we only bind dropdown listeners when the dropdown is open 345 _bindDropdownListeners: function() { 346 var that = this; 347 // when mouse over a list item, just highlight that one 348 // we add the class "highlight", so if they hit "enter" we know which one to select 349 this.countryList.on("mouseover" + this.ns, ".country", function(e) { 350 that._highlightListItem($(this)); 351 }); 352 // listen for country selection 353 this.countryList.on("click" + this.ns, ".country", function(e) { 354 that._selectListItem($(this)); 355 }); 356 // click off to close 357 // (except when this initial opening click is bubbling up) 358 // we cannot just stopPropagation as it may be needed to close another instance 359 var isOpening = true; 360 $("html").on("click" + this.ns, function(e) { 361 e.preventDefault(); 362 if (!isOpening) { 363 that._closeDropdown(); 364 } 365 isOpening = false; 366 }); 367 // Listen for up/down scrolling, enter to select, or letters to jump to country name. 368 // Use keydown as keypress doesn't fire for non-char keys and we want to catch if they 369 // just hit down and hold it to scroll down (no keyup event). 370 // Listen on the document because that's where key events are triggered if no input has focus 371 $(document).on("keydown" + this.ns, function(e) { 372 // prevent down key from scrolling the whole page, 373 // and enter key from submitting a form etc 374 e.preventDefault(); 375 if (e.which == keys.UP || e.which == keys.DOWN) { 376 // up and down to navigate 377 that._handleUpDownKey(e.which); 378 } else if (e.which == keys.ENTER) { 379 // enter to select 380 that._handleEnterKey(); 381 } else if (e.which == keys.ESC) { 382 // esc to close 383 that._closeDropdown(); 384 } else if (e.which >= keys.A && e.which <= keys.Z || e.which === keys.SPACE) { 385 that.typedLetters += String.fromCharCode(e.which); 386 that._filterCountries(that.typedLetters); 387 } else if (e.which === keys.BACKSPACE) { 388 that.typedLetters = that.typedLetters.slice(0, -1); 389 that._filterCountries(that.typedLetters); 390 } 391 }); 392 }, 393 // Highlight the next/prev item in the list (and ensure it is visible) 394 _handleUpDownKey: function(key) { 395 var current = this.countryList.children(".highlight").first(); 396 var next = key == keys.UP ? current.prev() : current.next(); 397 if (next.length) { 398 // skip the divider 399 if (next.hasClass("divider")) { 400 next = key == keys.UP ? next.prev() : next.next(); 401 } 402 this._highlightListItem(next); 403 this._scrollTo(next); 404 } 405 }, 406 // select the currently highlighted item 407 _handleEnterKey: function() { 408 var currentCountry = this.countryList.children(".highlight").first(); 409 if (currentCountry.length) { 410 this._selectListItem(currentCountry); 411 } 412 }, 413 _filterCountries: function(letters) { 414 var countries = this.countryListItems.filter(function() { 415 return $(this).text().toUpperCase().indexOf(letters) === 0 && !$(this).hasClass("preferred"); 416 }); 417 if (countries.length) { 418 // if one is already highlighted, then we want the next one 419 var highlightedCountry = countries.filter(".highlight").first(), listItem; 420 if (highlightedCountry && highlightedCountry.next() && highlightedCountry.next().text().toUpperCase().indexOf(letters) === 0) { 421 listItem = highlightedCountry.next(); 422 } else { 423 listItem = countries.first(); 424 } 425 // update highlighting and scroll 426 this._highlightListItem(listItem); 427 this._scrollTo(listItem); 428 } 429 }, 430 // Update the selected flag using the input's current value 431 _updateFlagFromInputVal: function() { 432 var that = this; 433 // try and extract valid country from input 434 var value = this.countryInput.val().replace(/(?=[() ])/g, '\\'); 435 if (value) { 436 var countryCodes = []; 437 var matcher = new RegExp(value, "i"); 438 // Check for ISO codes only 439 if(value.length <= 2) { 440 for (var i = 0; i < this.countries.length; i++) { 441 if (this.countries[i].iso2.match(matcher)) { 442 countryCodes.push(this.countries[i].iso2); 443 } 444 } 445 } 446 // If no previous matches / larger than 2 chars, then search country name 447 if(countryCodes.length == 0) { 448 for (var i = 0; i < this.countries.length; i++) { 449 if (this.countries[i].name.match(matcher)) { 450 countryCodes.push(this.countries[i].iso2); 451 } 452 } 453 } 454 // Check if one of the matching countries is already selected 455 var alreadySelected = false; 456 $.each(countryCodes, function(i, c) { 457 if (that.selectedFlagInner.hasClass(c)) { 458 alreadySelected = true; 459 } 460 }); 461 if (!alreadySelected) { 462 this._selectFlag(countryCodes[0]); 463 this.countryCodeInput.val(countryCodes[0]).trigger("change"); 464 } 465 // Matching country found 466 return true; 467 } 468 // No match found 469 return false; 470 }, 471 // remove highlighting from other list items and highlight the given item 472 _highlightListItem: function(listItem) { 473 this.countryListItems.removeClass("highlight"); 474 listItem.addClass("highlight"); 475 }, 476 // find the country data for the given country code 477 // the ignoreOnlyCountriesOption is only used during init() while parsing the onlyCountries array 478 _getCountryData: function(countryCode, ignoreOnlyCountriesOption) { 479 var countryList = ignoreOnlyCountriesOption ? allCountries : this.countries; 480 for (var i = 0; i < countryList.length; i++) { 481 if (countryList[i].iso2 == countryCode) { 482 return countryList[i]; 483 } 484 } 485 return null; 486 }, 487 // update the selected flag and the active list item 488 _selectFlag: function(countryCode) { 489 if (! countryCode) { 490 return false; 491 } 492 this.selectedFlagInner.attr("class", "flag " + countryCode); 493 // update the title attribute 494 var countryData = this._getCountryData(countryCode); 495 this.selectedFlagInner.parent().attr("title", countryData.name); 496 // update the active list item 497 var listItem = this.countryListItems.children(".flag." + countryCode).first().parent(); 498 this.countryListItems.removeClass("active"); 499 listItem.addClass("active"); 500 }, 501 // called when the user selects a list item from the dropdown 502 _selectListItem: function(listItem) { 503 // update selected flag and active list item 504 var countryCode = listItem.attr("data-country-code"); 505 this._selectFlag(countryCode); 506 this._closeDropdown(); 507 // update input value 508 this._updateName(countryCode); 509 this.countryInput.trigger("change"); 510 this.countryCodeInput.trigger("change"); 511 // focus the input 512 this._focus(); 513 }, 514 // close the dropdown and unbind any listeners 515 _closeDropdown: function() { 516 this.countryList.addClass("hide"); 517 // update the arrow 518 this.selectedFlagInner.parent().children(".arrow").removeClass("up"); 519 // unbind event listeners 520 $(document).off("keydown" + this.ns); 521 $("html").off("click" + this.ns); 522 // unbind both hover and click listeners 523 this.countryList.off(this.ns); 524 this.typedLetters = ""; 525 }, 526 // check if an element is visible within its container, else scroll until it is 527 _scrollTo: function(element) { 528 if (!element || !element.offset()) { 529 return; 530 } 531 var container = this.countryList, containerHeight = container.height(), containerTop = container.offset().top, containerBottom = containerTop + containerHeight, elementHeight = element.outerHeight(), elementTop = element.offset().top, elementBottom = elementTop + elementHeight, newScrollTop = elementTop - containerTop + container.scrollTop(); 532 if (elementTop < containerTop) { 533 // scroll up 534 container.scrollTop(newScrollTop); 535 } else if (elementBottom > containerBottom) { 536 // scroll down 537 var heightDifference = containerHeight - elementHeight; 538 container.scrollTop(newScrollTop - heightDifference); 539 } 540 }, 541 // Replace any existing country name with the new one 542 _updateName: function(countryCode) { 543 this.countryCodeInput.val(countryCode).trigger("change"); 544 this.countryInput.val(this._getCountryData(countryCode).name); 545 }, 546 /******************** 547 * PUBLIC METHODS 548 ********************/ 549 // this is called when the geoip call returns 550 handleAutoCountry: function() { 551 if (this.options.initialCountry === "auto") { 552 // we must set this even if there is an initial val in the input: in case the initial val is invalid and they delete it - they should see their auto country 553 this.defaultCountry = $.fn[pluginName].autoCountry; 554 // if there's no initial value in the input, then update the flag 555 if (!this.countryInput.val()) { 556 this.selectCountry(this.defaultCountry); 557 } 558 this.autoCountryDeferred.resolve(); 559 } 560 }, 561 // get the country data for the currently selected flag 562 getSelectedCountryData: function() { 563 // rely on the fact that we only set 2 classes on the selected flag element: 564 // the first is "flag" and the second is the 2-char country code 565 var countryCode = this.selectedFlagInner.attr("class").split(" ")[1]; 566 return this._getCountryData(countryCode); 567 }, 568 // update the selected flag 569 selectCountry: function(countryCode) { 570 countryCode = countryCode.toLowerCase(); 571 // check if already selected 572 if (!this.selectedFlagInner.hasClass(countryCode)) { 573 this._selectFlag(countryCode); 574 this._updateName(countryCode); 575 } 576 }, 577 // set the input value and update the flag 578 setCountry: function(country) { 579 this.countryInput.val(country); 580 this._updateFlagFromInputVal(); 581 }, 582 // remove plugin 583 destroy: function() { 584 // stop listeners 585 this.countryInput.off(this.ns); 586 this.selectedFlagInner.parent().off(this.ns); 587 // remove markup 588 var container = this.countryInput.parent(); 589 container.before(this.countryInput).remove(); 590 } 591 }; 592 // adapted to allow public functions 593 // using https://github.com/jquery-boilerplate/jquery-boilerplate/wiki/Extending-jQuery-Boilerplate 594 $.fn[pluginName] = function(options) { 595 var args = arguments; 596 // Is the first parameter an object (options), or was omitted, 597 // instantiate a new instance of the plugin. 598 if (options === undefined || typeof options === "object") { 599 return this.each(function() { 600 if (!$.data(this, "plugin_" + pluginName)) { 601 $.data(this, "plugin_" + pluginName, new Plugin(this, options)); 602 } 603 }); 604 } else if (typeof options === "string" && options[0] !== "_" && options !== "init") { 605 // If the first parameter is a string and it doesn't start 606 // with an underscore or "contains" the `init`-function, 607 // treat this as a call to a public method. 608 // Cache the method call to make it possible to return a value 609 var returns; 610 this.each(function() { 611 var instance = $.data(this, "plugin_" + pluginName); 612 // Tests that there's already a plugin-instance 613 // and checks that the requested public method exists 614 if (instance instanceof Plugin && typeof instance[options] === "function") { 615 // Call the method of our plugin instance, 616 // and pass it the supplied arguments. 617 returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1)); 618 } 619 // Allow instances to be destroyed via the 'destroy' method 620 if (options === "destroy") { 621 $.data(this, "plugin_" + pluginName, null); 622 } 623 }); 624 // If the earlier cached method gives a value back return the value, 625 // otherwise return this to preserve chainability. 626 return returns !== undefined ? returns : this; 627 } 628 }; 629 /******************** 630 * STATIC METHODS 631 ********************/ 632 // get the country data object 633 $.fn[pluginName].getCountryData = function() { 634 return allCountries; 635 }; 636 // set the country data object 637 $.fn[pluginName].setCountryData = function(obj) { 638 allCountries = obj; 639 }; 640 // Tell JSHint to ignore this warning: "character may get silently deleted by one or more browsers" 641 // jshint -W100 642 // Array of country objects for the flag dropdown. 643 // Each contains a name and country code (ISO 3166-1 alpha-2). 644 // 645 // Note: using single char property names to keep filesize down 646 // n = name 647 // i = iso2 (2-char country code) 648 var allCountries = $.each([ { 649 n: "Afghanistan (â«Ø§ÙØºØ§ÙØ³ØªØ§Ùâ¬â)", 650 i: "af" 651 }, { 652 n: "à land Islands (à land)", 653 i: "ax" 654 }, { 655 n: "Albania (Shqipëri)", 656 i: "al" 657 }, { 658 n: "Algeria (â«Ø§Ùجزائرâ¬â)", 659 i: "dz" 660 }, { 661 n: "American Samoa", 662 i: "as" 663 }, { 664 n: "Andorra", 665 i: "ad" 666 }, { 667 n: "Angola", 668 i: "ao" 669 }, { 670 n: "Anguilla", 671 i: "ai" 672 }, { 673 n: "Antarctica", 674 i: "aq" 675 }, { 676 n: "Antigua and Barbuda", 677 i: "ag" 678 }, { 679 n: "Argentina", 680 i: "ar" 681 }, { 682 n: "Armenia (ÕÕ¡ÕµÕ¡Õ½Õ¿Õ¡Õ¶)", 683 i: "am" 684 }, { 685 n: "Aruba", 686 i: "aw" 687 }, { 688 n: "Australia", 689 i: "au" 690 }, { 691 n: "Austria (Ãsterreich)", 692 i: "at" 693 }, { 694 n: "Azerbaijan (AzÉrbaycan)", 695 i: "az" 696 }, { 697 n: "Bahamas", 698 i: "bs" 699 }, { 700 n: "Bahrain (â«Ø§ÙØ¨ØØ±ÙÙâ¬â)", 701 i: "bh" 702 }, { 703 n: "Bangladesh (বাà¦à¦²à¦¾à¦¦à§à¦¶)", 704 i: "bd" 705 }, { 706 n: "Barbados", 707 i: "bb" 708 }, { 709 n: "Belarus (ÐелаÑÑÑÑ)", 710 i: "by" 711 }, { 712 n: "Belgium (België)", 713 i: "be" 714 }, { 715 n: "Belize", 716 i: "bz" 717 }, { 718 n: "Benin (Bénin)", 719 i: "bj" 720 }, { 721 n: "Bermuda", 722 i: "bm" 723 }, { 724 n: "Bhutan (འà½à¾²à½´à½)", 725 i: "bt" 726 }, { 727 n: "Bolivia", 728 i: "bo" 729 }, { 730 n: "Bosnia and Herzegovina (ÐоÑна и ХеÑÑеговина)", 731 i: "ba" 732 }, { 733 n: "Botswana", 734 i: "bw" 735 }, { 736 n: "Bouvet Island (Bouvetøya)", 737 i: "bv" 738 }, { 739 n: "Brazil (Brasil)", 740 i: "br" 741 }, { 742 n: "British Indian Ocean Territory", 743 i: "io" 744 }, { 745 n: "British Virgin Islands", 746 i: "vg" 747 }, { 748 n: "Brunei", 749 i: "bn" 750 }, { 751 n: "Bulgaria (ÐÑлгаÑиÑ)", 752 i: "bg" 753 }, { 754 n: "Burkina Faso", 755 i: "bf" 756 }, { 757 n: "Burundi (Uburundi)", 758 i: "bi" 759 }, { 760 n: "Cambodia (ááááá»áá¶)", 761 i: "kh" 762 }, { 763 n: "Cameroon (Cameroun)", 764 i: "cm" 765 }, { 766 n: "Canada", 767 i: "ca" 768 }, { 769 n: "Cape Verde (Kabu Verdi)", 770 i: "cv" 771 }, { 772 n: "Caribbean Netherlands", 773 i: "bq" 774 }, { 775 n: "Cayman Islands", 776 i: "ky" 777 }, { 778 n: "Central African Republic (République Centrafricaine)", 779 i: "cf" 780 }, { 781 n: "Chad (Tchad)", 782 i: "td" 783 }, { 784 n: "Chile", 785 i: "cl" 786 }, { 787 n: "China (ä¸å½)", 788 i: "cn" 789 }, { 790 n: "Christmas Island", 791 i: "cx" 792 }, { 793 n: "Cocos (Keeling) Islands (Kepulauan Cocos (Keeling))", 794 i: "cc" 795 }, { 796 n: "Colombia", 797 i: "co" 798 }, { 799 n: "Comoros (â«Ø¬Ø²Ø± اÙÙ٠رâ¬â)", 800 i: "km" 801 }, { 802 n: "Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)", 803 i: "cd" 804 }, { 805 n: "Congo (Republic) (Congo-Brazzaville)", 806 i: "cg" 807 }, { 808 n: "Cook Islands", 809 i: "ck" 810 }, { 811 n: "Costa Rica", 812 i: "cr" 813 }, { 814 n: "Côte dâIvoire", 815 i: "ci" 816 }, { 817 n: "Croatia (Hrvatska)", 818 i: "hr" 819 }, { 820 n: "Cuba", 821 i: "cu" 822 }, { 823 n: "Curaçao", 824 i: "cw" 825 }, { 826 n: "Cyprus (ÎÏÏÏοÏ)", 827 i: "cy" 828 }, { 829 n: "Czech Republic (Äeská republika)", 830 i: "cz" 831 }, { 832 n: "Denmark (Danmark)", 833 i: "dk" 834 }, { 835 n: "Djibouti", 836 i: "dj" 837 }, { 838 n: "Dominica", 839 i: "dm" 840 }, { 841 n: "Dominican Republic (República Dominicana)", 842 i: "do" 843 }, { 844 n: "Ecuador", 845 i: "ec" 846 }, { 847 n: "Egypt (â«Ù صرâ¬â)", 848 i: "eg" 849 }, { 850 n: "El Salvador", 851 i: "sv" 852 }, { 853 n: "Equatorial Guinea (Guinea Ecuatorial)", 854 i: "gq" 855 }, { 856 n: "Eritrea", 857 i: "er" 858 }, { 859 n: "Estonia (Eesti)", 860 i: "ee" 861 }, { 862 n: "Ethiopia", 863 i: "et" 864 }, { 865 n: "Falkland Islands (Islas Malvinas)", 866 i: "fk" 867 }, { 868 n: "Faroe Islands (Føroyar)", 869 i: "fo" 870 }, { 871 n: "Fiji", 872 i: "fj" 873 }, { 874 n: "Finland (Suomi)", 875 i: "fi" 876 }, { 877 n: "France", 878 i: "fr" 879 }, { 880 n: "French Guiana (Guyane française)", 881 i: "gf" 882 }, { 883 n: "French Polynesia (Polynésie française)", 884 i: "pf" 885 }, { 886 n: "French Southern Territories (Terres australes françaises)", 887 i: "tf" 888 }, { 889 n: "Gabon", 890 i: "ga" 891 }, { 892 n: "Gambia", 893 i: "gm" 894 }, { 895 n: "Georgia (á¡áá¥áá ááááá)", 896 i: "ge" 897 }, { 898 n: "Germany (Deutschland)", 899 i: "de" 900 }, { 901 n: "Ghana (Gaana)", 902 i: "gh" 903 }, { 904 n: "Gibraltar", 905 i: "gi" 906 }, { 907 n: "Greece (Îλλάδα)", 908 i: "gr" 909 }, { 910 n: "Greenland (Kalaallit Nunaat)", 911 i: "gl" 912 }, { 913 n: "Grenada", 914 i: "gd" 915 }, { 916 n: "Guadeloupe", 917 i: "gp" 918 }, { 919 n: "Guam", 920 i: "gu" 921 }, { 922 n: "Guatemala", 923 i: "gt" 924 }, { 925 n: "Guernsey", 926 i: "gg" 927 }, { 928 n: "Guinea (Guinée)", 929 i: "gn" 930 }, { 931 n: "Guinea-Bissau (Guiné Bissau)", 932 i: "gw" 933 }, { 934 n: "Guyana", 935 i: "gy" 936 }, { 937 n: "Haiti", 938 i: "ht" 939 }, { 940 n: "Heard Island and Mcdonald Islands", 941 i: "hm" 942 }, { 943 n: "Honduras", 944 i: "hn" 945 }, { 946 n: "Hong Kong (馿¸¯)", 947 i: "hk" 948 }, { 949 n: "Hungary (Magyarország)", 950 i: "hu" 951 }, { 952 n: "Iceland (Ãsland)", 953 i: "is" 954 }, { 955 n: "India (à¤à¤¾à¤°à¤¤)", 956 i: "in" 957 }, { 958 n: "Indonesia", 959 i: "id" 960 }, { 961 n: "Iran (â«Ø§ÛراÙâ¬â)", 962 i: "ir" 963 }, { 964 n: "Iraq (â«Ø§ÙعراÙâ¬â)", 965 i: "iq" 966 }, { 967 n: "Ireland", 968 i: "ie" 969 }, { 970 n: "Isle of Man", 971 i: "im" 972 }, { 973 n: "Israel (â«×שר××â¬â)", 974 i: "il" 975 }, { 976 n: "Italy (Italia)", 977 i: "it" 978 }, { 979 n: "Jamaica", 980 i: "jm" 981 }, { 982 n: "Japan (æ¥æ¬)", 983 i: "jp" 984 }, { 985 n: "Jersey", 986 i: "je" 987 }, { 988 n: "Jordan (â«Ø§ÙأردÙâ¬â)", 989 i: "jo" 990 }, { 991 n: "Kazakhstan (ÐÐ°Ð·Ð°Ñ ÑÑан)", 992 i: "kz" 993 }, { 994 n: "Kenya", 995 i: "ke" 996 }, { 997 n: "Kiribati", 998 i: "ki" 999 }, { 1000 n: "Kosovo (Kosovë)", 1001 i: "xk" 1002 }, { 1003 n: "Kuwait (â«Ø§ÙÙÙÙØªâ¬â)", 1004 i: "kw" 1005 }, { 1006 n: "Kyrgyzstan (ÐÑÑгÑзÑÑан)", 1007 i: "kg" 1008 }, { 1009 n: "Laos (ລາວ)", 1010 i: "la" 1011 }, { 1012 n: "Latvia (Latvija)", 1013 i: "lv" 1014 }, { 1015 n: "Lebanon (â«ÙØ¨ÙØ§Ùâ¬â)", 1016 i: "lb" 1017 }, { 1018 n: "Lesotho", 1019 i: "ls" 1020 }, { 1021 n: "Liberia", 1022 i: "lr" 1023 }, { 1024 n: "Libya (â«ÙÙØ¨Ùاâ¬â)", 1025 i: "ly" 1026 }, { 1027 n: "Liechtenstein", 1028 i: "li" 1029 }, { 1030 n: "Lithuania (Lietuva)", 1031 i: "lt" 1032 }, { 1033 n: "Luxembourg", 1034 i: "lu" 1035 }, { 1036 n: "Macau (æ¾³é)", 1037 i: "mo" 1038 }, { 1039 n: "Macedonia (FYROM) (ÐакедониÑа)", 1040 i: "mk" 1041 }, { 1042 n: "Madagascar (Madagasikara)", 1043 i: "mg" 1044 }, { 1045 n: "Malawi", 1046 i: "mw" 1047 }, { 1048 n: "Malaysia", 1049 i: "my" 1050 }, { 1051 n: "Maldives", 1052 i: "mv" 1053 }, { 1054 n: "Mali", 1055 i: "ml" 1056 }, { 1057 n: "Malta", 1058 i: "mt" 1059 }, { 1060 n: "Marshall Islands", 1061 i: "mh" 1062 }, { 1063 n: "Martinique", 1064 i: "mq" 1065 }, { 1066 n: "Mauritania (â«Ù ÙØ±ÙتاÙÙØ§â¬â)", 1067 i: "mr" 1068 }, { 1069 n: "Mauritius (Moris)", 1070 i: "mu" 1071 }, { 1072 n: "Mayotte", 1073 i: "yt" 1074 }, { 1075 n: "Mexico (México)", 1076 i: "mx" 1077 }, { 1078 n: "Micronesia", 1079 i: "fm" 1080 }, { 1081 n: "Moldova (Republica Moldova)", 1082 i: "md" 1083 }, { 1084 n: "Monaco", 1085 i: "mc" 1086 }, { 1087 n: "Mongolia (Ðонгол)", 1088 i: "mn" 1089 }, { 1090 n: "Montenegro (Crna Gora)", 1091 i: "me" 1092 }, { 1093 n: "Montserrat", 1094 i: "ms" 1095 }, { 1096 n: "Morocco (â«Ø§Ù٠غربâ¬â)", 1097 i: "ma" 1098 }, { 1099 n: "Mozambique (Moçambique)", 1100 i: "mz" 1101 }, { 1102 n: "Myanmar (Burma) (áá¼ááºáá¬)", 1103 i: "mm" 1104 }, { 1105 n: "Namibia (Namibië)", 1106 i: "na" 1107 }, { 1108 n: "Nauru", 1109 i: "nr" 1110 }, { 1111 n: "Nepal (नà¥à¤ªà¤¾à¤²)", 1112 i: "np" 1113 }, { 1114 n: "Netherlands (Nederland)", 1115 i: "nl" 1116 }, { 1117 n: "New Caledonia (Nouvelle-Calédonie)", 1118 i: "nc" 1119 }, { 1120 n: "New Zealand", 1121 i: "nz" 1122 }, { 1123 n: "Nicaragua", 1124 i: "ni" 1125 }, { 1126 n: "Niger (Nijar)", 1127 i: "ne" 1128 }, { 1129 n: "Nigeria", 1130 i: "ng" 1131 }, { 1132 n: "Niue", 1133 i: "nu" 1134 }, { 1135 n: "Norfolk Island", 1136 i: "nf" 1137 }, { 1138 n: "North Korea (ì¡°ì 민주주ì ì¸ë¯¼ ê³µíêµ)", 1139 i: "kp" 1140 }, { 1141 n: "Northern Mariana Islands", 1142 i: "mp" 1143 }, { 1144 n: "Norway (Norge)", 1145 i: "no" 1146 }, { 1147 n: "Oman (â«Ø¹Ù٠اÙâ¬â)", 1148 i: "om" 1149 }, { 1150 n: "Pakistan (â«Ù¾Ø§Ú©Ø³ØªØ§Ùâ¬â)", 1151 i: "pk" 1152 }, { 1153 n: "Palau", 1154 i: "pw" 1155 }, { 1156 n: "Palestine (â«ÙÙØ³Ø·ÙÙâ¬â)", 1157 i: "ps" 1158 }, { 1159 n: "Panama (Panamá)", 1160 i: "pa" 1161 }, { 1162 n: "Papua New Guinea", 1163 i: "pg" 1164 }, { 1165 n: "Paraguay", 1166 i: "py" 1167 }, { 1168 n: "Peru (Perú)", 1169 i: "pe" 1170 }, { 1171 n: "Philippines", 1172 i: "ph" 1173 }, { 1174 n: "Pitcairn Islands", 1175 i: "pn" 1176 }, { 1177 n: "Poland (Polska)", 1178 i: "pl" 1179 }, { 1180 n: "Portugal", 1181 i: "pt" 1182 }, { 1183 n: "Puerto Rico", 1184 i: "pr" 1185 }, { 1186 n: "Qatar (â«Ùطرâ¬â)", 1187 i: "qa" 1188 }, { 1189 n: "Réunion (La Réunion)", 1190 i: "re" 1191 }, { 1192 n: "Romania (România)", 1193 i: "ro" 1194 }, { 1195 n: "Russia (РоÑÑиÑ)", 1196 i: "ru" 1197 }, { 1198 n: "Rwanda", 1199 i: "rw" 1200 }, { 1201 n: "Saint Barthélemy (Saint-Barthélemy)", 1202 i: "bl" 1203 }, { 1204 n: "Saint Helena", 1205 i: "sh" 1206 }, { 1207 n: "Saint Kitts and Nevis", 1208 i: "kn" 1209 }, { 1210 n: "Saint Lucia", 1211 i: "lc" 1212 }, { 1213 n: "Saint Martin (Saint-Martin (partie française))", 1214 i: "mf" 1215 }, { 1216 n: "Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)", 1217 i: "pm" 1218 }, { 1219 n: "Saint Vincent and the Grenadines", 1220 i: "vc" 1221 }, { 1222 n: "Samoa", 1223 i: "ws" 1224 }, { 1225 n: "San Marino", 1226 i: "sm" 1227 }, { 1228 n: "São Tomé and PrÃncipe (São Tomé e PrÃncipe)", 1229 i: "st" 1230 }, { 1231 n: "Saudi Arabia (â«Ø§ÙÙ Ù ÙÙØ© Ø§ÙØ¹Ø±Ø¨ÙØ© Ø§ÙØ³Ø¹ÙØ¯ÙØ©â¬â)", 1232 i: "sa" 1233 }, { 1234 n: "Senegal (Sénégal)", 1235 i: "sn" 1236 }, { 1237 n: "Serbia (СÑбиÑа)", 1238 i: "rs" 1239 }, { 1240 n: "Seychelles", 1241 i: "sc" 1242 }, { 1243 n: "Sierra Leone", 1244 i: "sl" 1245 }, { 1246 n: "Singapore", 1247 i: "sg" 1248 }, { 1249 n: "Sint Maarten", 1250 i: "sx" 1251 }, { 1252 n: "Slovakia (Slovensko)", 1253 i: "sk" 1254 }, { 1255 n: "Slovenia (Slovenija)", 1256 i: "si" 1257 }, { 1258 n: "Solomon Islands", 1259 i: "sb" 1260 }, { 1261 n: "Somalia (Soomaaliya)", 1262 i: "so" 1263 }, { 1264 n: "South Africa", 1265 i: "za" 1266 }, { 1267 n: "South Georgia & South Sandwich Islands", 1268 i: "gs" 1269 }, { 1270 n: "South Korea (ëí민êµ)", 1271 i: "kr" 1272 }, { 1273 n: "South Sudan (â«Ø¬ÙÙØ¨ Ø§ÙØ³ÙداÙâ¬â)", 1274 i: "ss" 1275 }, { 1276 n: "Spain (España)", 1277 i: "es" 1278 }, { 1279 n: "Sri Lanka (à·à·âර෠ලà¶à¶à·à·)", 1280 i: "lk" 1281 }, { 1282 n: "Sudan (â«Ø§ÙØ³ÙØ¯Ø§Ùâ¬â)", 1283 i: "sd" 1284 }, { 1285 n: "Suriname", 1286 i: "sr" 1287 }, { 1288 n: "Svalbard and Jan Mayen (Svalbard og Jan Mayen)", 1289 i: "sj" 1290 }, { 1291 n: "Swaziland", 1292 i: "sz" 1293 }, { 1294 n: "Sweden (Sverige)", 1295 i: "se" 1296 }, { 1297 n: "Switzerland (Schweiz)", 1298 i: "ch" 1299 }, { 1300 n: "Syria (â«Ø³ÙØ±ÙØ§â¬â)", 1301 i: "sy" 1302 }, { 1303 n: "Taiwan (å°ç£)", 1304 i: "tw" 1305 }, { 1306 n: "Tajikistan", 1307 i: "tj" 1308 }, { 1309 n: "Tanzania", 1310 i: "tz" 1311 }, { 1312 n: "Thailand (à¹à¸à¸¢)", 1313 i: "th" 1314 }, { 1315 n: "Timor-Leste", 1316 i: "tl" 1317 }, { 1318 n: "Togo", 1319 i: "tg" 1320 }, { 1321 n: "Tokelau", 1322 i: "tk" 1323 }, { 1324 n: "Tonga", 1325 i: "to" 1326 }, { 1327 n: "Trinidad and Tobago", 1328 i: "tt" 1329 }, { 1330 n: "Tunisia (â«ØªÙÙØ³â¬â)", 1331 i: "tn" 1332 }, { 1333 n: "Turkey (Türkiye)", 1334 i: "tr" 1335 }, { 1336 n: "Turkmenistan", 1337 i: "tm" 1338 }, { 1339 n: "Turks and Caicos Islands", 1340 i: "tc" 1341 }, { 1342 n: "Tuvalu", 1343 i: "tv" 1344 }, { 1345 n: "Uganda", 1346 i: "ug" 1347 }, { 1348 n: "Ukraine (УкÑаÑна)", 1349 i: "ua" 1350 }, { 1351 n: "United Arab Emirates (â«Ø§Ùإ٠ارات Ø§ÙØ¹Ø±Ø¨ÙØ© اÙÙ ØªØØ¯Ø©â¬â)", 1352 i: "ae" 1353 }, { 1354 n: "United Kingdom", 1355 i: "gb" 1356 }, { 1357 n: "United States", 1358 i: "us" 1359 }, { 1360 n: "U.S. Minor Outlying Islands", 1361 i: "um" 1362 }, { 1363 n: "U.S. Virgin Islands", 1364 i: "vi" 1365 }, { 1366 n: "Uruguay", 1367 i: "uy" 1368 }, { 1369 n: "Uzbekistan (OÊ»zbekiston)", 1370 i: "uz" 1371 }, { 1372 n: "Vanuatu", 1373 i: "vu" 1374 }, { 1375 n: "Vatican City (Città del Vaticano)", 1376 i: "va" 1377 }, { 1378 n: "Venezuela", 1379 i: "ve" 1380 }, { 1381 n: "Vietnam (Viá»t Nam)", 1382 i: "vn" 1383 }, { 1384 n: "Wallis and Futuna", 1385 i: "wf" 1386 }, { 1387 n: "Western Sahara (â«Ø§ÙØµØØ±Ø§Ø¡ Ø§ÙØºØ±Ø¨ÙØ©â¬â)", 1388 i: "eh" 1389 }, { 1390 n: "Yemen (â«Ø§ÙÙÙ Ùâ¬â)", 1391 i: "ye" 1392 }, { 1393 n: "Zambia", 1394 i: "zm" 1395 }, { 1396 n: "Zimbabwe", 1397 i: "zw" 1398 } ], function(i, c) { 1399 c.name = c.n; 1400 c.iso2 = c.i; 1401 delete c.n; 1402 delete c.i; 1403 }); 1404});
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.