d7237d1a3cd101ac490a921984a2ce95629161c397a976802ff7aed9d5f1b1c4
Source Code:
var NaviApiI3 = function () {};
/**
* send Suggest information to i3
*
* @param {Object} set
* {
* rank: index(number of service or word)
* uid: uid
* word: word
* type: 'service_suggest' or 'word_suggest'
* category(option): Service Suggest only.
* }
* @param {Array} suggests
* [
* {
* suggest_rank: index(number of service or word)
* suggest_uid: uid
* suggest_word: word
* suggest_type: 'service_suggest' or 'word_suggest'
* },...
* ]
* @param {string} event 'click'...etc
* @param {function} callback
*/
NaviApiI3.send = function (set, suggests, event, callback) {
var type = 'suggest';
var tracker = [event, '_', type].join('');
// i3 Check
if (typeof i3 !== 'function') {
return;
}
/* eslint-disable */
// 1.Create Tracker
i3('create', tracker);
// 2.Set Search Word
i3(tracker + '.set', type, set);
// 3.Add Display Suggest List
suggests.forEach(function (value) {
i3(tracker + '.add', type, value);
});
// 4.Send to i3
if (typeof callback === 'function') {
i3(tracker + '.send', event, type, callback);
} else {
i3(tracker + '.send', event, type);
}
};
/**
* return object to send i3 (for suggest view)
*
* @param {string} uid selected uid
* @param {Array} suggestList Response of SuggestAPI
* @return {object} set(i3 Send object)
*/
NaviApiI3.getSet = function (uid, suggestList) {
var services = suggestList.services;
var words = suggestList.words;
var result = {};
var isService = false;
// service suggest (requires category)
isService = services.some(function (value, index) {
if (value.uid === uid) {
result.rank = (index + 1);
result.uid = uid;
result.word = value.suggest_word;
result.type = 'service_suggest';
result.category = value.service_ja;
return true;
}
return false;
});
if (isService) {
return result;
}
// word suggest
words.some(function (value, index) {
if (value.uid === uid) {
result.rank = (index + 1);
result.uid = uid;
result.word = value.suggest_word;
result.type = 'word_suggest';
return true;
}
return false;
});
return result;
};
/**
* return list to send i3 (for suggest view)
*
* [info] Currently, service suggest information will be contained if `all` is selected.
* Since it is difficult for the caller to do such operation,
* we will do it in this function instead.
*
* @param {string} uid selected uid
* @param {Array} suggestList Response of SuggestAPI
* @param {number} index select box index
* @param {string} word search word
* @return {Array} suggests(i3 Send List Objects)
*/
NaviApiI3.getSuggests = function (uid, suggestList, index, word) {
var services = suggestList.services;
var words = suggestList.words;
var result = [];
// service suggest and word suggest
if (index === 0 && word && word.length > 1) {
services.forEach(function (value, idx) {
var object = {};
object.suggest_rank = (idx + 1);
object.suggest_uid = value.uid;
object.suggest_word = value.suggest_word;
object.suggest_type = 'service_suggest';
object.suggest_category = value.service_ja;
result.push(object);
});
words.forEach(function (value, idx) {
var object = {};
object.suggest_rank = (idx + 1);
object.suggest_uid = value.uid;
object.suggest_word = value.suggest_word;
object.suggest_type = 'word_suggest';
result.push(object);
});
return result;
}
// word suggest only
words.forEach(function (value, idx) {
var object = {};
object.suggest_rank = (idx + 1);
object.suggest_uid = value.uid;
object.suggest_word = value.suggest_word;
object.suggest_type = 'word_suggest';
result.push(object);
});
return result;
};
/**
* return object to send i3 (for search button)
*
* [specification(AND condition)]
* 1.`all` is selected in pulldown
* 2.there is at least 1 service suggest for search query
*
* [return value]
* null if parameter is invalid
* otherwise, will return correct value
*
* @param {string} text input data
* @return {object} set(i3 Send object)
*/
NaviApiI3.getSetForSubmit = function (text) {
if (!text) {
return null;
}
var result = {};
result.word = text;
return result;
};
/**
* return list to send i3 (for search button)
*
* [specification(AND condition)]
* 1.`all` is selected in pulldown
* 2.there is at least 1 service suggest for search query
*
* [return value]
* empty list if parameter is invalid
* otherwise, will return correct value
*
* @param {Array} suggestList Response of SuggestAPI
* @param {number} index select box index
* @return {Array} suggests(i3 Send List Objects)
*/
NaviApiI3.getSuggestsForSubmit = function (suggestList, index) {
var services = suggestList.services;
var result = [];
if (index !== 0) {
return result;
}
if (!services) {
return result;
}
if (services.length === 0) {
return result;
}
services.forEach(function (value, idx) {
var object = {};
object.suggest_rank = (idx + 1);
object.suggest_uid = value.uid;
object.suggest_word = value.suggest_word;
object.suggest_type = 'service_assist_suggest';
object.suggest_category = value.service_ja;
result.push(object);
});
return result;
};
var NaviApiSearchSuggest = function () {};
/**
* callback for keyup event in search form
*
* @param {object} event
*/
NaviApiSearchSuggest.changedText = function (event) {
var text = NaviApiSearchSuggest.text.value;
if (text.length === 0) {
NaviApiSearchSuggest.clear();
return;
}
if (NaviApiSearchSuggest.previousInput === text) {
return;
}
// Call Suggest API
NaviApiSearchSuggest.httpRequest(event, text);
// Set word suggest data
NaviApiSearchSuggest.changedArrowKey(event);
NaviApiSearchSuggest.previousInput = text;
};
/**
* set word suggest data using arrow keys (up/down)
*
* @param {object} event
*/
NaviApiSearchSuggest.changedArrowKey = function (event) {
// KEY_UP=-1, KEY_DOWN=1
var keyIndex = (event.keyCode === NaviApiSearchSuggest.ARROW_KEYS_UP) ? -1 : 1;
var lastIndex = NaviApiSearchSuggest.SUGGEST_WORDS_INDEX;
var index = lastIndex + keyIndex;
var word = '';
var lastSelected;
// validate
if (NaviApiSearchSuggest.ARROW_KEYS.indexOf(event.keyCode) < 0) {
return;
}
if (NaviApiSearchSuggest.SUGGEST_WORDS.length === 0) {
return;
}
if (index < 0) {
index = NaviApiSearchSuggest.SUGGEST_WORDS.length - 1;
}
if (index >= NaviApiSearchSuggest.SUGGEST_WORDS.length) {
index = 0;
}
word = NaviApiSearchSuggest.SUGGEST_WORDS[index];
NaviApiSearchSuggest.text.value = word.suggest_word;
NaviApiSearchSuggest.SUGGEST_WORDS_INDEX = index;
if (lastIndex !== NaviApiSearchSuggest.SUGGEST_WORDS_NOT_EXIST) {
lastSelected = NaviApiSearchSuggest.suggestWindow.querySelector('._n4v1-search-suggest-word li:nth-of-type(' + (lastIndex + 1) + ')');
lastSelected.classList.remove('_n4v1-search-suggest-word-selected');
}
NaviApiSearchSuggest.suggestWindow.querySelector('._n4v1-search-suggest-word li:nth-of-type(' + (index + 1) + ')').classList.add('_n4v1-search-suggest-word-selected');
};
/**
* make http request
*
* @param {object} event
* @param {string} text text value in search box
*/
NaviApiSearchSuggest.httpRequest = function (event, text) {
var sc = '';
var element = '';
if (NaviApiSearchSuggest.ARROW_KEYS.indexOf(event.keyCode) >= 0) {
return;
}
sc = document.createElement('script');
sc.id = 'naviapi-suggest-script';
sc.type = 'text/javascript';
sc.src = NaviApiSearchSuggest.getEndpoint(text);
sc.async = 'true';
element = document.getElementById('naviapi-suggest-script');
element.parentNode.insertBefore(sc, element);
element.parentNode.removeChild(element);
};
/**
* return API endpoint URL
*
* @param {string} text text value in search box
* @return {string} SuggestAPI Endpoint
*/
NaviApiSearchSuggest.getEndpoint = function (text) {
var domain = NaviApiSearchSuggest.getDomain();
return 'https://' + domain + '/search/-/assist/ajax-suggest/=/q=' + encodeURIComponent(text) + '?jsoncallback=NaviApiSearchSuggest.callback';
};
/**
* return domain for API endpoint
*
* @return {string} domain
*/
NaviApiSearchSuggest.getDomain = function () {
return NaviApiSearchSuggest.isR18() ? 'www.dmm.co.jp' : 'www.dmm.com';
};
/**
* judge if the page is r18 site
*
* @return {bool} true if the page is r18 site, false otherwise
*/
NaviApiSearchSuggest.isR18 = function () {
var hostname = window.location.hostname;
return /dmm\.co\.jp$/.test(hostname);
};
/**
* callback for suggest API
*
* @param {object} data response body
*/
NaviApiSearchSuggest.callback = function (data) {
if (!data) {
NaviApiSearchSuggest.clear();
return;
}
NaviApiSearchSuggest.SUGGESTS = data;
NaviApiSearchSuggest.htmlBuilder(data);
NaviApiSearchSuggest.sendSuggestShowEvent();
};
/**
* build HTML
*
* @param {object} data response body
*/
NaviApiSearchSuggest.htmlBuilder = function (data) {
var result = [];
var services = data.services;
var words = data.words;
var serviceList = NaviApiSearchSuggest.buildService(services);
var wordList = NaviApiSearchSuggest.buildWord(words);
if ((services.length === 0) && (words.length === 0)) {
NaviApiSearchSuggest.clear();
return;
}
result.push(serviceList.join(''));
result.push(wordList.join(''));
NaviApiSearchSuggest.suggestWindow.innerHTML = result.join('');
// set service suggest
NaviApiSearchSuggest.SUGGEST_SERVICES = services;
// set word suggest
NaviApiSearchSuggest.SUGGEST_WORDS = words;
// show
NaviApiSearchSuggest.display();
};
/**
* build HTML for service suggest
*
* @param {Array} services Service Objects
* @return {Array} Service Suggest HTML
*/
NaviApiSearchSuggest.buildService = function (services) {
var result = [];
var inputText = NaviApiSearchSuggest.text.value;
var index = 0;
var colorClass = '';
if (services.length === 0) {
return result;
}
// if `all` is not selected, terminate these steps
index = NaviApiSearchSuggest.selectBox.selectedIndex;
if (index !== 0) {
return result;
}
// if word length is less than 2, terminate these steps
// (due to existing specification)
if (inputText.length <= 1) {
return result;
}
if (NaviApiSearchSuggest.isR18()) {
colorClass = '_n4v1-search-r18-color';
} else {
colorClass = '_n4v1-search-com-color';
}
result.push('<ul class="_n4v1-search-suggest-service">');
services.forEach(function (value) {
result.push('<li>');
result.push('<a class="' + colorClass + '" id="' + value.uid + '" href="' + value.detail.url + '" data-uid="' + value.uid + '">');
result.push(value.suggest_word);
result.push('<span>' + value.service_ja + '</span>');
result.push('</a>');
result.push('</li>');
});
result.push('</ul>');
return result;
};
/**
* build HTML for word suggest
*
* @param {Array} words word objects
* @return {Array} Words Suggest HTML
*/
NaviApiSearchSuggest.buildWord = function (words) {
var result = [];
if (words.length === 0) {
return result;
}
result.push('<ul class="_n4v1-search-suggest-word">');
words.forEach(function (value) {
result.push('<li id="' + value.uid + '">');
result.push(value.suggest_word);
result.push('</li>');
});
result.push('</ul>');
return result;
};
/**
* show suggest result
*/
NaviApiSearchSuggest.display = function () {
NaviApiSearchSuggest.SUGGEST_WORDS_INDEX = NaviApiSearchSuggest.SUGGEST_WORDS_NOT_EXIST;
NaviApiSearchSuggest.suggestWindow.classList.remove('_n4v1-search-suggest-hide');
};
/**
* callback for selecting suggest window
*
* @param {Object} event
*/
NaviApiSearchSuggest.selectedSuggestWindow = function (event) {
/* eslint-disable */
var id = event.target.id;
// update the input value if word suggest data exist
var text = NaviApiSearchSuggest.text.value;
var isWord = NaviApiSearchSuggest.SUGGEST_WORDS.some(function (value) {
if (value.uid === id) {
NaviApiSearchSuggest.text.value = value.suggest_word;
return true;
}
return false;
});
// 1.Get set
var i3Set = NaviApiI3.getSet(id, NaviApiSearchSuggest.SUGGESTS);
// 2.Get suggests
var i3SuggestLit = NaviApiI3.getSuggests(
id,
NaviApiSearchSuggest.SUGGESTS,
NaviApiSearchSuggest.selectBox.selectedIndex,
text
);
// 3.send
NaviApiI3.send(i3Set, i3SuggestLit, 'click');
// for word suggest
if (isWord) {
document.search_form.submit();
} else {
// update location for service suggest
NaviApiSearchSuggest.SUGGEST_SERVICES.some(function (value) {
if (value.uid === id) {
window.location.href = value.detail.url;
return true;
}
return false;
});
}
};
/**
* send `show suggest` event
*/
NaviApiSearchSuggest.sendSuggestShowEvent = function () {
/* eslint-disable */
var text = NaviApiSearchSuggest.text.value;
var selectedIndex = NaviApiSearchSuggest.selectBox.selectedIndex;
var i3Set = NaviApiI3.getSetForSubmit(text);
var i3SuggestLit = NaviApiI3.getSuggests(
null,
NaviApiSearchSuggest.SUGGESTS,
selectedIndex,
text
);
// Check
if (!i3Set) {
return;
}
if (i3SuggestLit.length === 0) {
return;
}
NaviApiI3.send(i3Set, i3SuggestLit, 'show');
};
/**
* callback for clicking search button
*
* @param {Object} event
*/
NaviApiSearchSuggest.submitSuggest = function (event) {
document.search_form.submit();
};
/**
* clear suggest result
*/
NaviApiSearchSuggest.clear = function () {
NaviApiSearchSuggest.SUGGEST_WORDS_INDEX = NaviApiSearchSuggest.SUGGEST_WORDS_NOT_EXIST;
NaviApiSearchSuggest.SUGGEST_SERVICES = [];
NaviApiSearchSuggest.SUGGEST_WORDS = [];
NaviApiSearchSuggest.previousInput = null;
NaviApiSearchSuggest.suggestWindow.innerHTML = '';
NaviApiSearchSuggest.suggestWindow.classList.add('_n4v1-search-suggest-hide');
};
// ----------------------- //
// Define
// ----------------------- //
// arrorw keys
NaviApiSearchSuggest.ARROW_KEYS = [38, 40];
NaviApiSearchSuggest.ARROW_KEYS_UP = 38;
// API response
NaviApiSearchSuggest.SUGGESTS = [];
NaviApiSearchSuggest.SUGGEST_SERVICES = [];
NaviApiSearchSuggest.SUGGEST_WORDS = [];
NaviApiSearchSuggest.SUGGEST_WORDS_NOT_EXIST = -1;
NaviApiSearchSuggest.SUGGEST_WORDS_INDEX = NaviApiSearchSuggest.SUGGEST_WORDS_NOT_EXIST;
// search query text
NaviApiSearchSuggest.previousInput = null;
// select box
NaviApiSearchSuggest.selectBox = document.getElementById('select-box');
// search box (for inputing text)
NaviApiSearchSuggest.text = document.getElementById('naviapi-search-text');
NaviApiSearchSuggest.suggestWindow = document.getElementById('naviapi-suggest-display');
// search button
NaviApiSearchSuggest.submit = document.getElementById('naviapi-search-submit');
// ---------------- /
// EventListeners
// ---------------- /
// for text input event
NaviApiSearchSuggest.text.addEventListener('keyup', NaviApiSearchSuggest.changedText);
// for clicking suggest window
NaviApiSearchSuggest.suggestWindow.addEventListener('mousedown', NaviApiSearchSuggest.selectedSuggestWindow);
// for clearing suggest display
NaviApiSearchSuggest.text.addEventListener('blur', NaviApiSearchSuggest.clear);
// for form submit
NaviApiSearchSuggest.submit.addEventListener('click', NaviApiSearchSuggest.submitSuggest);