UNPKG

domainr-search-box

Version:
671 lines (554 loc) 15.9 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.domainr = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ 'use strict'; var util = require('./util'); var sequence = 0; // Detect CORS support var cors = false; if ('withCredentials' in xhr()) { cors = true; } // ---------- function getJSON(url, callback, failure) { if (!callback) { throw new Error('[domainr] Missing callback'); } if (cors) { getCORS(url, callback, failure); return; } getJSONP(url, callback, failure); } // ---------- // Minimal fallback for IE // http://toddmotto.com/writing-a-standalone-ajax-xhr-javascript-micro-library/ function xhr() { try { var XHR = window.XMLHttpRequest || window.ActiveXObject; return new XHR('MSXML2.XMLHTTP.3.0'); } catch (e) { return {}; } } // ---------- function getCORS(url, callback, failure) { failure = failure || function() {}; var x = xhr(); x.onreadystatechange = function() { var message; if (x.readyState != 4) { return; } if (x.status != 200) { message = 'Error fetching data: ' + x.responseText; util.error(message); failure({ message: message }); return; } var result; try { result = JSON.parse(x.responseText); } catch (e) { message = 'Unable to parse data: ' + x.responseText + '; ' + e; util.error(message); failure({ message: message }); return; } callback(result); }; x.open('GET', url, true); x.send(); } // ---------- // You must provide a success callback, but the failure callback is optional. // For each call to getJSONP, you'll get at most 1 callback (either success or failure) call. If you // don't provide a failure callback, you might not receive a call at all (if the function doesn't // succeed). If you do provide the failure callback, you'll get exactly 1 call, whichever one is // appropriate to the result. function getJSONP(url, success, failure) { var script = document.createElement('script'); script.async = true; var id = '_jsonp' + sequence++; var failureSent = false; var timeout = setTimeout(function() { var message = 'Timeout trying to retrieve ' + url; util.error(message); if (failure) { failure({ message: message }); // Here we set a flag so we won't end up sending a success callback later if the result comes // through after the timeout. failureSent = true; } }, 5000); window[id] = function(data) { clearTimeout(timeout); setTimeout(function() { var scr = document.getElementById(id); scr.parentNode.removeChild(scr); window[id] = undefined; try { delete window[id]; } catch (e) {} }, 0); if (!failureSent) { success(data); } }; var c = url.indexOf('?') >= 0 ? '&' : '?'; script.setAttribute('src', url + c + 'callback=' + id); script.id = id; var head = document.head || document.getElementsByTagName('head')[0] || document.documentElement; head.insertBefore(script, head.firstChild); } // ---------- module.exports = { getJSON: getJSON }; },{"./util":6}],2:[function(require,module,exports){ 'use strict'; var ajax = require('./ajax'); var util = require('./util'); function Client(options) { options = options || {}; this.clientId = options.clientId; this.mashapeKey = options.mashapeKey; if (!this.clientId && !this.mashapeKey) { throw new Error('[domainr] Missing mashapeKey or clientId'); } this.baseURL = options.baseURL || (this.clientId ? 'https://api.domainr.com/v2' : 'https://domainr.p.rapidapi.com/v2'); } Client.prototype = { search: function(params, callback) { this._get('/search', this.searchParams(params), callback); }, searchParams: function(p) { return util.extract(p, ['query', 'registrar', 'location', 'defaults']); }, status: function(domains, callback) { var self = this; if (!domains) { throw new Error('[domainr] domains array is required'); } util.uniq(domains); var output = { status: [] }; var completed = 0; var incrementCompleted = function() { completed++; if (completed === domains.length) { callback(output); } }; var doOne = function(domain) { var params = { domain: domain }; self._get('/status', params, function(result) { if (result && result.status && result.status[0]) { output.status.push(result.status[0]); } else { util.error('Empty status result', result); } incrementCompleted(); }, incrementCompleted); }; for (var i = 0; i < domains.length; i++) { doOne(domains[i]); } }, options: function(domain, callback) { this._get('/options', { domain: domain, }, callback); }, zones: function(callback) { this._get('/zones', {}, callback); }, registerURL: function(domain, options) { var params = util.extract(options, ['registrar']); params.domain = domain; return this._url('/register', params); }, _get: function(path, params, callback, failure) { var url = this.baseURL + path + '?' + util.qs(params || {}, this._key()); ajax.getJSON(url, callback, failure); }, _url: function (path, params) { return this.baseURL + path + '?' + util.qs(params || {}, this._key()); }, _key: function() { if (this.clientId) { return { client_id: this.clientId }; } return { 'mashape-key': this.mashapeKey }; } }; module.exports = Client; },{"./ajax":1,"./util":6}],3:[function(require,module,exports){ 'use strict' var Client = require('./client'); var SearchBox = require('./search-box'); require('./jquery'); module.exports = { Client: Client, SearchBox: SearchBox }; },{"./client":2,"./jquery":4,"./search-box":5}],4:[function(require,module,exports){ 'use strict'; var SearchBox = require('./search-box'); var util = require('./util'); if (window.jQuery) { var $ = window.jQuery; $.fn.domainrSearchBox = function(config) { this.each(function(i, el) { var searchBoxConfig = util.extract(config, ['clientId', 'mashapeKey', 'renderWith', 'limit', 'registrar', 'defaults', 'onSelect']); searchBoxConfig.observe = el; if (config.renderTo) { var $el = $(config.renderTo); if ($el.length > 0) { searchBoxConfig.renderTo = $el[0]; } } var searchBox = new domainr.SearchBox(searchBoxConfig); }); return this; }; } },{"./search-box":5,"./util":6}],5:[function(require,module,exports){ 'use strict' var Client = require('./client'); var util = require('./util'); var SearchBox = function(options) { var self = this; options = options || {}; if (!options.observe) { throw new Error('[domainr] "observe" is required'); } this._client = new Client(util.extract(options, ['clientId', 'mashapeKey'])); this._state = { query: '', results: [], limit: 20, selection: -1 }; this._seq = 0; this._last = 0; this._cache = {}; this._listeners = {}; this._searchTimeout = null; this._searchDelay = 250; this._renderer = defaultRenderer; this._in = options.observe; on(this._in, 'keyup', this._input, this); on(this._in, 'input', this._input, this); on(this._in, 'change', this._input, this); on(this._in, 'keydown', this._keydown, this); if (options.renderTo !== undefined) { this._out = options.renderTo; addClass(this._out, 'domainr-results-container'); on(this._out, 'click', this._click, this); } if (options.renderWith !== undefined) { this._renderer = options.renderWith; } if (options.limit !== undefined) { this._state.limit = options.limit; } if (options.registrar !== undefined) { this._state.registrar = options.registrar; } if (options.defaults !== undefined) { this._state.defaults = options.defaults.join(','); } if (options.searchDelay !== undefined) { this._searchDelay = options.searchDelay; } if (options.onSelect !== undefined) { this._onSelect = options.onSelect; } else { this._onSelect = function(result) { self._in.value = result.domain; window.open(self._client.registerURL(result.domain)); }; } this._input(); // In case there's something already in the input }; SearchBox.prototype = { _input: function() { if (this._state.query != this._in.value) { if (this._in.value === '') { this._state.results = []; this._update(); return; } this._state.query = this._in.value; window.clearTimeout(this._searchTimeout); this._searchTimeout = window.setTimeout(this._search.bind(this), this._searchDelay); } }, _keydown: function(event) { event = event || window.event; var handled = false; if (event.keyCode === 38) { // Up arrow handled = true; this._state.selection--; if (this._state.selection < 0) { this._state.selection = this._state.results.length - 1; } this._update(); } else if (event.keyCode === 40) { // Down arrow handled = true; this._state.selection++; if (this._state.selection >= this._state.results.length) { this._state.selection = 0; } this._update(); } else if (event.keyCode === 13) { // Enter key if (this._state.selection !== -1) { handled = true; this._choose(this._state.results[this._state.selection]); } } if (handled && event.preventDefault) { event.preventDefault(); } }, _click: function(event) { event = event || window.event; var rs = this._state.results; for (var e = event.target || event.srcElement; e && e != document; e = e.parentNode) { var d = e.getAttribute('data-domain'); if (d) { for (var i = 0; i < rs.length; i++) { var r = rs[i]; if (r.domain == d) { this._choose(r); return; } } } } }, _render: function() { if (!this._out) { return; } this._out.innerHTML = this._renderer(this._state); return this; }, _search: function() { var self = this; this._state.selection = -1; // Try cache first var key = util.qs(this._client.searchParams(this._state)); var res = this._cache[key]; if (res !== undefined) { this._state.results = res.results; this._update(); return; } // Make network request var seq = this._seq++; this._client.search(this._state, function(res) { self._cache[key] = res; if (self._last > seq) { return; } self._last = seq; self._state.results = res.results; self._update(); }); }, _update: function() { this._sort(); this._limit(); this._status(); this._render(); }, _sort: function() { if (!this._state.defaults || !this._state.results) { return; } var defaults = this._state.defaults.split(','); this._state.results.sort(function(a, b) { var aIndex = util.indexOf(defaults, a.zone); if (aIndex === -1) { aIndex = defaults.length; } var bIndex = util.indexOf(defaults, b.zone); if (bIndex === -1) { bIndex = defaults.length; } if (aIndex !== bIndex) { return aIndex - bIndex; } return a.domain - b.domain; }); }, _limit: function() { if (this._state.limit >= 0 && this._state.results.length > this._state.limit) { this._state.results.length = this._state.limit; } }, _status: function() { var self = this; // Extract domains without status var i; var d = []; var MAX_STATUS_DOMAINS = 10; var rs = this._state.results; for (i = 0; i < rs.length && d.length < MAX_STATUS_DOMAINS; i++) { var r = rs[i]; r.status = this._cache[r.domain + ':status'] || r.status; if (!r.status) { r.status = 'unknown'; d.push(r.domain); } } if (d.length === 0) { return; } util.uniq(d); var doOne = function(domain) { self._client.status([domain], function(res) { var s = res.status[0]; if (s) { self._cache[s.domain + ':status'] = s.status; self._update(); } }); }; for (i = 0; i < d.length; i++) { doOne(d[i]); } }, _choose: function(result) { if (this._onSelect) { this._onSelect(result); } } }; function defaultRenderer(state) { var rs = state.results; var l = rs.length; if (l === 0) { return ''; } var h = ['<div class="domainr-results">']; for (var i = 0; i < l; i++) { var r = rs[i]; var classNames = [ 'domainr-result', r.status ]; if (state.selection === i) { classNames.push('selected'); } h.push( '<div class="' + classNames.join(' ') + '" data-domain="' + r.domain + '">' + '<span class="domainr-result-domain">' + '<span class="domainr-result-host">' + r.host + '</span>' + '<span class="domainr-result-subdomain">' + r.subdomain + '</span>' + '<span class="domainr-result-zone">' + r.zone + '</span>' + '</span>' + '<span class="domainr-result-path">' + r.path + '</span>' + '</div>' ); } h.push('</div>'); return h.join(''); } function on(e, ev, cb, obj) { if (obj) { var original = cb; cb = function() { return original.apply(obj, arguments); }; } if (e.addEventListener) { e.addEventListener(ev, cb, false); } else if (e.attachEvent) { e.attachEvent('on' + ev, cb); } else { e['on' + ev] = cb; } } function addClass(e, className) { if (e.classList) { e.classList.add(className); } else { e.className += ' ' + className; } } module.exports = SearchBox; },{"./client":2,"./util":6}],6:[function(require,module,exports){ 'use strict' var euc = encodeURIComponent; function extract(p, keys) { var x = {}; if (p) { for (var i = 0; i < keys.length; i++) { var k = keys[i]; if (p[k] !== undefined) { x[k] = p[k]; } } } return x; } function qs() { var q = []; for (var i = 0; i < arguments.length; i++) { var p = arguments[i]; for (var k in p) { q.push(euc(k) + '=' + euc(p[k])); } } return q.sort().join('&'); } function error(message) { if (window.console && window.console.error) { window.console.error('[domainr] ' + message); } } function uniq(a) { if (!a) { return; } var i, j; for (i = 0; i < a.length; i++) { for (j = i + 1; j < a.length; j++) { if (a[i] === a[j]) { a.splice(j, 1); j--; } } } } function indexOf(a, v) { if (!a) { return -1; } var i; for (i = 0; i < a.length; i++) { if (a[i] === v) { return i; } } return -1; } module.exports = { euc: euc, extract: extract, qs: qs, error: error, uniq: uniq, indexOf: indexOf }; },{}]},{},[3])(3) });