SkyEng - тестовое задание

by russianpenguin

HTML

<p>
    In the battle to dominate Europe’s cloud computing market, American tech giants are spending big to build up their
    local credibility.
</p>

<p>
    Amazon Web Services, the largest player, announced last week that it would soon open multiple data centers in France
    and Britain. Google, which already has sites in countries like Finland and Belgium, is expected to finish a new
    multimillion-dollar data complex in the Netherlands by the end of the year.
</p>

<p>
    And Microsoft, by some measures the second-largest cloud computing provider in Europe, said on Monday that it had
    spent $1 billion in the last 12 months to expand its offerings, taking its total investment in European-based cloud
    services to $3 billion since 2005.
</p>

<p>
    “We’re building our global cloud infrastructure in Europe so it can be trusted by the multiple constituents,” Satya
    Nadella, Microsoft’s chief executive, said in an interview. “We can meet the data residency needs of our European
    customers.”
</p>

<p>
    With many in Europe questioning why America’s largest tech companies control how many of the region’s 500 million
    citizens use everyday digital services, it is not surprising that the likes of Microsoft and Amazon are eager to
    play up their local roots.
</p>

<p>
    As the European Union continues to clamp down on the perceived misuse of people’s digital information, analysts also
    say that many Silicon Valley giants are responding to these privacy concerns by increasingly offering individuals
    and companies the ability to keep information close to home, whereas in the past, data might have been stored solely
    in the United States.
</p>
“Countries like Germany are well aware of data privacy, and it has made them more wary of where data is kept,” said
Gregor Petri, a cloud computing analyst at the technology research firm Gartner in Veghel, the Netherlands. “Local data
sovereignty has become important, and American companies are...

CSS

.skyeng-box {
    background: #fff;
    position:absolute;
    width: 160px;
    height: auto;
    box-shadow: 0px 0px 10px 5px rgba(184,184,184,1);
}

.skyeng-box .content {
    margin: 10px;
}

.skyeng-box .content .value {
    color: lightgray;
}

.skyeng-box ul.meanings {
    list-style: none;
    margin: 10px 0px;
    padding: 0px;
}

.skyeng-box .meanings li.active {
    margin: 5px 0px;
    font-weight: bold;
    font-size: 110%;
}

.skyeng-box.hidden {
    display:none;
}

JavaScript

(function() {
    /*
     * представим на минутку, что шаблон попапа уже есть в странице.
     * для плагина потребуется реализовать динамическую подгрузку шаблона
     *
     * поэтому формируем класс, который инкапсулирует в себе все управление.
     * требуется:
     * - навеcить событие на шевеление мышкой по списку (перевешивает класс active)
     * - навесить событие на окончание выделение текста на странице
     * - навесить событие на документ для закрытия всплывашки
     */
    var CLASS_ACTIVE_LI = "active";
    var CLASS_INACTIVE_LI = "";
    // пробел в имени класса (для удобства)
    var CLASS_HIDDEN_POPUP = " hidden";
    var DIALOG_WIDTH = 160;

    /**
     * Билдим адрес для перевода word на другой язык
     * @param word
     * @returns {string}
     */
    function translateUrl(word) {
        return "https://dictionary.skyeng.ru/api/v2/search-word-translation?text=" + encodeURI(word);
    }

    var translate = function() {
        var self = this;
        // считаем, что элемент подгружен
        this.element = document.getElementById('skyeng');
        this.meaningsList = this.element.getElementsByTagName('ul')[0];
        this.valueElement = this.element.querySelector('.value');
        this.img = this.element.getElementsByTagName('img')[0];
        this.xhr = new XMLHttpRequest();
        this.bindEvents();
    };

    translate.prototype = {

        /**
         * биндинг листенеров на элемент попапа
         * и на страничку для выделения\скрытия попапа
         */
        bindEvents: function() {
            var self = this;
            this.element.addEventListener('mouseover', function(e) {
                if(e.target.nodeType == 1 && e.target.nodeName == 'LI') {
                    self.activate(e.target);
                }
            });

            // предотвратим всплывание
            this.element.addEventListener('click', function(e) {
                e.stopPropagation();
            });

            // выделение и клики в...