PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/share/spice/currency/currency.js

http://github.com/duckduckgo/zeroclickinfo-spice
JavaScript | 461 lines | 373 code | 48 blank | 40 comment | 28 complexity | fec35afb17334a5276d4d7845ad1be92 MD5 | raw file
Possible License(s): Apache-2.0
  1. (function(env) {
  2. "use strict";
  3. var initialized = false;
  4. // We hardcode the currency symbols here for 2 reasons rather than read it in
  5. // 1. To vastly mitigate the risk of (very probable) runtime errors
  6. // 2. Slight performance betterment
  7. var currencies = [
  8. { symbol: "AED", name: "UAE Dirham"},
  9. { symbol: "AFN", name: "Afghan Afghani"},
  10. { symbol: "ALL", name: "Albanian Lek"},
  11. { symbol: "AMD", name: "Armenian Dram"},
  12. { symbol: "ANG", name: "Netherlands Antillean Guilder"},
  13. { symbol: "AOA", name: "Angola Kwanza"},
  14. { symbol: "ARS", name: "Argentine Peso"},
  15. { symbol: "AUD", name: "Australian Dollar"},
  16. { symbol: "AWG", name: "Aruban Florin"},
  17. { symbol: "AZN", name: "Azerbaijanian Manat"},
  18. { symbol: "BAM", name: "Bosnian Convertible Marka"},
  19. { symbol: "BBD", name: "Barbadian Dollars"},
  20. { symbol: "BDT", name: "Bangladesh Taka"},
  21. { symbol: "BGN", name: "Bulgaria Lev"},
  22. { symbol: "BHD", name: "Bahraini Dinar"},
  23. { symbol: "BIF", name: "Burundian Franc"},
  24. { symbol: "BMD", name: "Bermudian Dollar"},
  25. { symbol: "BND", name: "Bruneian Dollar"},
  26. { symbol: "BOB", name: "Bolivian BolĂ­viano"},
  27. { symbol: "BRL", name: "Brazilian Real"},
  28. { symbol: "BSD", name: "Bahamian Dollar"},
  29. { symbol: "BTN", name: "Bhutanese Ngultrum"},
  30. { symbol: "BWP", name: "Botswana Pula"},
  31. { symbol: "BYR", name: "Belarusian Ruble"},
  32. { symbol: "BZD", name: "Belizean Dollar"},
  33. { symbol: "CAD", name: "Canadian Dollar"},
  34. { symbol: "CDF", name: "Congolese Franc"},
  35. { symbol: "CHF", name: "Swiss Franc"},
  36. { symbol: "CLP", name: "Chilean Peso"},
  37. { symbol: "CNY", name: "Chinese Yuan"},
  38. { symbol: "COP", name: "Colombian Peso"},
  39. { symbol: "CRC", name: "Costa Rican Colon"},
  40. { symbol: "CUC", name: "Cuban Convertible"},
  41. { symbol: "CUP", name: "Cuban Peso"},
  42. { symbol: "CVE", name: "Cape Verdean Escudo"},
  43. { symbol: "CZK", name: "Czech Koruna"},
  44. { symbol: "DJF", name: "Djiboutian Franc"},
  45. { symbol: "DKK", name: "Danish Krone"},
  46. { symbol: "DOP", name: "Dominican Peso"},
  47. { symbol: "DZD", name: "Algerian Dinar"},
  48. { symbol: "EGP", name: "Egyptian Pound"},
  49. { symbol: "ERN", name: "Eritrean Nakfa"},
  50. { symbol: "ETB", name: "Ethiopian Birr"},
  51. { symbol: "EUR", name: "Euro"},
  52. { symbol: "FJD", name: "Fijian Dollar"},
  53. { symbol: "FKP", name: "Falkland Island Pound"},
  54. { symbol: "GBP", name: "Great British Pound"},
  55. { symbol: "GEL", name: "Georgian Lari"},
  56. { symbol: "GGP", name: "Guernsey Pound"},
  57. { symbol: "GHS", name: "Ghanaian Cedi"},
  58. { symbol: "GIP", name: "Gibraltar Pound"},
  59. { symbol: "GMD", name: "Gambian Dalasi"},
  60. { symbol: "GNF", name: "Guinean Franc"},
  61. { symbol: "GTQ", name: "Guatemalan Quetzal"},
  62. { symbol: "GYD", name: "Guyanese Dollar"},
  63. { symbol: "HKD", name: "Hong Kong Dollar"},
  64. { symbol: "HNL", name: "Honduran Lempira"},
  65. { symbol: "HRK", name: "Croatian Kuna"},
  66. { symbol: "HTG", name: "Haitian Gourde"},
  67. { symbol: "HUF", name: "Hungarian Forint"},
  68. { symbol: "IDR", name: "Indonesian Rupiah"},
  69. { symbol: "ILS", name: "Israeli Shekel"},
  70. { symbol: "IMP", name: "Isle of Man Pound"},
  71. { symbol: "INR", name: "Indian Rupee"},
  72. { symbol: "IQD", name: "Iraqi Dinar"},
  73. { symbol: "IRR", name: "Iranian Rial"},
  74. { symbol: "ISK", name: "Icelandic Krona"},
  75. { symbol: "JEP", name: "Jersey Pound"},
  76. { symbol: "JMD", name: "Jamaican Dollar"},
  77. { symbol: "JOD", name: "Jordanian Dinar"},
  78. { symbol: "JPY", name: "Japanese Yen"},
  79. { symbol: "KES", name: "Kenyan Shilling"},
  80. { symbol: "KGS", name: "Kyrgyzstani Som"},
  81. { symbol: "KHR", name: "Cambodian Riel"},
  82. { symbol: "KMF", name: "Comoran Franc"},
  83. { symbol: "KPW", name: "North Korean Won"},
  84. { symbol: "KRW", name: "South Korean Won"},
  85. { symbol: "KWD", name: "Kuwaiti Dinar"},
  86. { symbol: "KYD", name: "Caymanian Dollar"},
  87. { symbol: "KZT", name: "Kazakhstani Tenge"},
  88. { symbol: "LAK", name: "Laotian Kip"},
  89. { symbol: "LBP", name: "Lebanese Pound"},
  90. { symbol: "LKR", name: "Sri Lankan Rupee"},
  91. { symbol: "LRD", name: "Liberian Dollar"},
  92. { symbol: "LSL", name: "Basotho Loti"},
  93. { symbol: "LTL", name: "Lithuanian Litas"},
  94. { symbol: "LVL", name: "Latvian Lat"},
  95. { symbol: "LYD", name: "Libyan Dinar"},
  96. { symbol: "MAD", name: "Moroccan Dirham"},
  97. { symbol: "MDL", name: "Moldovan Leu"},
  98. { symbol: "MGA", name: "Malagasy Ariary"},
  99. { symbol: "MKD", name: "Macedonian Denar"},
  100. { symbol: "MMK", name: "Burmese Kyat"},
  101. { symbol: "MNT", name: "Mongolian Tughrik"},
  102. { symbol: "MOP", name: "Macau Pataca"},
  103. { symbol: "MRO", name: "Mauritanian Ouguiya"},
  104. { symbol: "MUR", name: "Mauritian Rupee"},
  105. { symbol: "MVR", name: "Maldivian Rufiyaa"},
  106. { symbol: "MWK", name: "Malawian Kwacha"},
  107. { symbol: "MXN", name: "Mexican Peso"},
  108. { symbol: "MYR", name: "Malaysian Ringgit"},
  109. { symbol: "MZN", name: "Mozambican Metical"},
  110. { symbol: "NAD", name: "Namibian Dollar"},
  111. { symbol: "NGN", name: "Nigerian Naira"},
  112. { symbol: "NIO", name: "Nicaraguan Cordoba"},
  113. { symbol: "NOK", name: "Norwegian Krone"},
  114. { symbol: "NPR", name: "Nepalese Rupee"},
  115. { symbol: "NZD", name: "New Zealand Dollar"},
  116. { symbol: "OMR", name: "Omani Rial"},
  117. { symbol: "PAB", name: "Panamanian Balboa"},
  118. { symbol: "PEN", name: "Peruvian Sol"},
  119. { symbol: "PGK", name: "Papua New Guinean Kina"},
  120. { symbol: "PHP", name: "Philippine Peso"},
  121. { symbol: "PKR", name: "Pakistani Rupee"},
  122. { symbol: "PLN", name: "Polish Zloty"},
  123. { symbol: "PYG", name: "Paraguayan Guarani"},
  124. { symbol: "QAR", name: "Qatari Riyal"},
  125. { symbol: "RON", name: "Romanian New Leu"},
  126. { symbol: "RSD", name: "Serbian Dinar"},
  127. { symbol: "RUB", name: "Russian Ruble"},
  128. { symbol: "RWF", name: "Rwandan Franc"},
  129. { symbol: "SAR", name: "Saudi Arabian Riyal"},
  130. { symbol: "SBD", name: "Solomon Islander Dollar"},
  131. { symbol: "SCR", name: "Seychellois Rupee"},
  132. { symbol: "SDG", name: "Sudanese Pound"},
  133. { symbol: "SEK", name: "Swedish Krona"},
  134. { symbol: "SGD", name: "Singapore Dollar"},
  135. { symbol: "SHP", name: "Saint Helenian Pound"},
  136. { symbol: "SLL", name: "Leonean Leone"},
  137. { symbol: "SOS", name: "Somali Shilling"},
  138. { symbol: "SPL", name: "Seborgan Luigino"},
  139. { symbol: "SRD", name: "Surinamese Dollar"},
  140. { symbol: "STD", name: "Sao Tomean Dobra"},
  141. { symbol: "SVC", name: "Salvadoran Colon"},
  142. { symbol: "SYP", name: "Syrian Pound"},
  143. { symbol: "SZL", name: "Swazi Lilangeni"},
  144. { symbol: "THB", name: "Thai Baht"},
  145. { symbol: "TJS", name: "Tajikistani Somoni"},
  146. { symbol: "TMT", name: "Turkmenistani Manat"},
  147. { symbol: "TND", name: "Tunisian Dinar"},
  148. { symbol: "TOP", name: "Tongan Pa'anga"},
  149. { symbol: "TRY", name: "Turkish Lira"},
  150. { symbol: "TTD", name: "Trinidadian Dollar"},
  151. { symbol: "TVD", name: "Tuvaluan Dollar"},
  152. { symbol: "TWD", name: "Taiwan New Dollar"},
  153. { symbol: "TZS", name: "Tanzanian Shilling"},
  154. { symbol: "UAH", name: "Ukrainian Hryvnia"},
  155. { symbol: "UGX", name: "Ugandan Shilling"},
  156. { symbol: "USD", name: "US Dollar"},
  157. { symbol: "UYU", name: "Uruguayan Peso"},
  158. { symbol: "UZS", name: "Uzbekistani Som"},
  159. { symbol: "VEB", name: "Venezuelan Bolivar"},
  160. { symbol: "VEF", name: "Venezuelan Bolivar"},
  161. { symbol: "VND", name: "Vietnamese Dong"},
  162. { symbol: "VUV", name: "Ni-Vanuatu Vatu"},
  163. { symbol: "WST", name: "Samoan Tala"},
  164. { symbol: "XBT", name: "Bitcoin"},
  165. { symbol: "XAG", name: "Silver Ounce"},
  166. { symbol: "XAU", name: "Gold Ounce"},
  167. { symbol: "XPD", name: "Palladium Ounce"},
  168. { symbol: "XPT", name: "Platinum Ounce"},
  169. { symbol: "YER", name: "Yemeni Rial"},
  170. { symbol: "ZAR", name: "South African Rand"},
  171. { symbol: "ZMW", name: "Zambian Kwacha"},
  172. { symbol: "ZWD", name: "Zimbabwean Dollar"},
  173. ]
  174. //
  175. // The various jQuery objects representing the zci--currency UI
  176. //
  177. var $currency_input_left,
  178. $currency_input_right,
  179. $left_select,
  180. $right_select,
  181. $selects,
  182. $more_at_link_normal,
  183. $more_at_link_charts;
  184. // Currency Converter
  185. var Converter = {
  186. from_currency: undefined,
  187. to_currency: undefined,
  188. rate: undefined,
  189. inverseRate: undefined,
  190. //
  191. // Retrieves conversion info from JSONP payload
  192. //
  193. getConversionRate: function(payload) {
  194. return +$(payload["conversion-rate"].split(" ")).get(-2);
  195. },
  196. getInverseConversionRate: function(payload) {
  197. return +$(payload["conversion-inverse"].split(" ")).get(-2);
  198. },
  199. getFromCurrencyName: function(payload) {
  200. return payload["from-currency-symbol"];
  201. },
  202. getToCurrencyName: function(payload) {
  203. return payload["to-currency-symbol"];
  204. },
  205. getConversionLabel: function(payload) {
  206. return payload["conversion-rate"];
  207. },
  208. getInverseConversionLabel: function(payload) {
  209. return payload["conversion-inverse"]
  210. },
  211. // If there is really small exchange rates, then we need to display the
  212. // appropriate significate figures. For example HUF -> EUR = 0.0032. However,
  213. // once the conversion to is high enough (1) we will fall back to 2 sig figs.
  214. getSignificantFigures: function(rate, value, curr) {
  215. // if Bitcoin, keep it at 8
  216. if(curr === "XBT") {
  217. return 8;
  218. }
  219. // else we'll set the decimals based on heuristics
  220. if(rate <= 0.001 && value < 1) {
  221. return 6;
  222. } else if(rate <= 0.01 && value < 1) {
  223. return 4;
  224. } else {
  225. return 2;
  226. }
  227. },
  228. //
  229. // Calculates the rates
  230. //
  231. calculateRate: function() {
  232. if($currency_input_left.val() !== '') {
  233. var left_input = $currency_input_left.val();
  234. left_input = left_input.replace(/,/g, '');
  235. var rightval = parseFloat(left_input) * Converter.rate;
  236. var decimals = Converter.getSignificantFigures(Converter.rate, rightval, Converter.to_currency);
  237. $currency_input_right.val(
  238. rightval.toFixed(decimals)
  239. );
  240. } else {
  241. $currency_input_right.val("");
  242. }
  243. },
  244. calculateInverseRate: function() {
  245. if($currency_input_right.val() !== '') {
  246. var right_input = $currency_input_right.val()
  247. right_input = right_input.replace(/,/g, '');
  248. var leftval = parseFloat(right_input) * Converter.inverseRate;
  249. var decimals = Converter.getSignificantFigures(Converter.inverseRate, leftval, Converter.from_currency);
  250. $currency_input_left.val(
  251. leftval.toFixed(decimals)
  252. );
  253. } else {
  254. $currency_input_left.val("");
  255. }
  256. },
  257. getRatesFromAPI: function() {
  258. var from = $left_select.val();
  259. var to = $right_select.val();
  260. // We'll flip the currencies if the user tries to compare the same symbol
  261. if (from === to) {
  262. from = Converter.to_currency;
  263. to = Converter.from_currency;
  264. $right_select.val(to);
  265. $left_select.val(from);
  266. }
  267. var endpoint = "/js/spice/currency/1/" + from + "/" + to;
  268. $.ajax({
  269. url: endpoint,
  270. dataType: 'text',
  271. success: function(payload) {
  272. var response = JSON.parse(payload.trim().replace(/^[^\(]*\(/, '').replace(/\);$/, ''));
  273. response = response.conversion;
  274. Converter.resetConverter(response);
  275. }
  276. });
  277. },
  278. //
  279. // Resets the converter based on new info
  280. //
  281. resetConverter: function(json) {
  282. // gets the to/from currencies
  283. Converter.from_currency = Converter.getFromCurrencyName(json);
  284. Converter.to_currency = Converter.getToCurrencyName(json);
  285. // gets the conversion rates
  286. Converter.rate = Converter.getConversionRate(json)
  287. Converter.inverseRate = Converter.getInverseConversionRate(json);
  288. Converter.calculateRate();
  289. Converter.setMoreAtLinks();
  290. },
  291. //
  292. // Sets Link / Information Labels
  293. //
  294. setMoreAtLinks: function() {
  295. // the url strings
  296. var more_at_url = "http://www.xe.com/currencyconverter/convert/?Amount=1&From=" + Converter.from_currency + "&To=" + Converter.to_currency;
  297. var chart_url = "http://www.xe.com/currencycharts/?from=" + Converter.from_currency + "&to=" + Converter.to_currency;
  298. $more_at_link_normal.attr("href", more_at_url);
  299. $more_at_link_charts.attr("href", chart_url);
  300. },
  301. } // Converter
  302. env.ddg_spice_currency = function(api_result) {
  303. // Check if there are any errors in the response.
  304. if(!api_result || !api_result.conversion || !api_result.topConversions ||
  305. !api_result.conversion || Object.keys(api_result.conversion).length === 0 ||
  306. !api_result.topConversions.length || api_result.topConversions.length === 0) {
  307. return Spice.failed('currency');
  308. }
  309. var results = [];
  310. var mainConv = api_result.conversion;
  311. var topCovs = api_result.topConversions;
  312. var templates = {};
  313. // caches the retrieved information in the UI
  314. Converter.rate = Converter.getConversionRate(mainConv)
  315. Converter.inverseRate = Converter.getInverseConversionRate(mainConv);
  316. if(mainConv["from-currency-symbol"] !== mainConv["to-currency-symbol"]) {
  317. // Flag the input to get different output
  318. // if is pair get paris tile layout
  319. results = [mainConv];
  320. } else {
  321. // Mark which item is the first one.
  322. // Since HandlebarsJS (with the way we use them) is unaware of the current index.
  323. mainConv.initial = true;
  324. results.push(mainConv);
  325. for(var i = 0; i < topCovs.length; i++) {
  326. results.push(topCovs[i]);
  327. }
  328. }
  329. // Format the time and date.
  330. var timestr = mainConv["rate-utc-timestamp"].split(/\s+/);
  331. var xeDate = timestr[0];
  332. var xeTime = timestr[1].match(/\d{2}\:\d{2}\b/);
  333. var liveUrl = 'http://www.xe.com/currencyconverter/convert/?Amount=1&From=' + mainConv["from-currency-symbol"] + '&To=' + mainConv["to-currency-symbol"];
  334. var templateObj = {
  335. detail: Spice.currency.detail,
  336. item_detail: false
  337. };
  338. // Set favicon
  339. var icon = ((DDG.is3x || DDG.is2x) ? DDG.get_asset_path('currency',"assets/xe.png") : "http://www.xe.com/favicon.ico");
  340. Spice.add({
  341. id: 'currency',
  342. name: 'Currency',
  343. data: results,
  344. signal: 'high',
  345. meta: {
  346. sourceUrl: "http://www.xe.com",
  347. sourceName: "xe.com",
  348. itemType: "Conversions"
  349. },
  350. normalize: function(item) {
  351. // Return null if the results aren't numbers.
  352. if(!DDG.isNumber(+item["from-amount"]) || !DDG.isNumber(+item["converted-amount"])) {
  353. return null;
  354. }
  355. Converter.from_currency = item["from-currency-symbol"];
  356. Converter.to_currency = item["to-currency-symbol"];
  357. return {
  358. fromCurrencySymbol: item["from-currency-symbol"],
  359. toCurrencySymbol: item["to-currency-symbol"],
  360. amount: +item["from-amount"],
  361. convertedAmount: +item["converted-amount"],
  362. rate: item["conversion-rate"],
  363. inverseRate: item["conversion-inverse"],
  364. xeUrl: 'http://www.xe.com/currencycharts/?from=' + item["from-currency-symbol"] + '&to=' + item["to-currency-symbol"],
  365. currencyName: item["to-currency-name"],
  366. liveUrl: liveUrl,
  367. xeTime: xeTime,
  368. xeDate: xeDate,
  369. moreAtIcon: icon
  370. };
  371. },
  372. templates: templateObj,
  373. onShow: function() {
  374. if(!initialized) {
  375. var $currency = $("#zci-currency");
  376. $currency_input_left = $currency.find("#zci--currency-amount-left");
  377. $currency_input_right = $currency.find("#zci--currency-amount-right");
  378. $left_select = $currency.find("#zci--currency-symbol-left");
  379. $right_select = $currency.find("#zci--currency-symbol-right");
  380. $selects = $currency.find("select.zci--currency-symbol");
  381. $more_at_link_normal = $currency.find(".zci__more-at");
  382. $more_at_link_charts = $currency.find(".zci__more-at--info");
  383. // apends all the currency names to the selects
  384. for( var i = 0 ; i < currencies.length ; i ++ ) {
  385. $selects.append(
  386. "<option value="
  387. + currencies[i].symbol
  388. + ">"
  389. + currencies[i].name
  390. + "</strong> ("
  391. + currencies[i].symbol
  392. + ")"
  393. + "</option>"
  394. );
  395. }
  396. // sets the default
  397. $left_select.val(Converter.from_currency);
  398. $right_select.val(Converter.to_currency);
  399. }
  400. $currency_input_left.bind('change keyup mousewheel', Converter.calculateRate);
  401. $currency_input_right.bind('change keyup mousewheel', Converter.calculateInverseRate);
  402. $selects.change(function(_e) {
  403. Converter.getRatesFromAPI();
  404. });
  405. // Perform conversion on the first pass
  406. if(!initialized) {
  407. Converter.calculateRate();
  408. initialized = true;
  409. }
  410. }
  411. });
  412. };
  413. }(this));