|
|
| Строка 1: |
Строка 1: |
| − | (function (win, doc, nav, params, namespace, undefined) { | + | mw.loader.load('https://translate.yandex.net/website-widget/v1/widget.js?widgetId=ytWidget&pageLang=ru&widgetTheme=light&autoMode=false" type="text/javascript"'); |
| − | 'use strict';
| |
| | | | |
| − | var util = {
| |
| − | keycode: {
| |
| − | ESCAPE: 27
| |
| − | },
| |
| − | getRequest: function () {
| |
| − | if (win.XDomainRequest) {
| |
| − | return new win.XDomainRequest();
| |
| − | }
| |
| − | if (win.XMLHttpRequest) {
| |
| − | return new win.XMLHttpRequest();
| |
| − | }
| |
| − | return null;
| |
| − | },
| |
| − | loadScript: function (src, parent, callback) {
| |
| − | var script = doc.createElement('script');
| |
| − | script.src = src;
| |
| − |
| |
| − | script.addEventListener('load', function onLoad() {
| |
| − | this.removeEventListener('load', onLoad, false);
| |
| − | callback();
| |
| − | }, false);
| |
| − |
| |
| − | parent.appendChild(script);
| |
| − | },
| |
| − | loadResource: function (url, callback) {
| |
| − | var request = this.getRequest();
| |
| − |
| |
| − | if (!request) {
| |
| − | return null;
| |
| − | }
| |
| − |
| |
| − | request.onload = function () {
| |
| − | callback(this.responseText);
| |
| − | };
| |
| − | request.open('GET', url, true);
| |
| − |
| |
| − | win.setTimeout(function () {
| |
| − | request.send();
| |
| − | }, 0);
| |
| − |
| |
| − | return request;
| |
| − | },
| |
| − | getStyleList: function (element) {
| |
| − | var value = element.getAttribute('class');
| |
| − | if (!value) {
| |
| − | return [];
| |
| − | }
| |
| − | return value.replace(/\s+/g, ' ').trim().split(' ');
| |
| − | },
| |
| − | hasStyleName: function (element, name) {
| |
| − | var list = this.getStyleList(element);
| |
| − | return !!list.length && list.indexOf(name) >= 0;
| |
| − | },
| |
| − | addStyleName: function (element, name) {
| |
| − | var list = this.getStyleList(element);
| |
| − | list.push(name);
| |
| − | element.setAttribute('class', list.join(' '));
| |
| − | },
| |
| − | removeStyleName: function (element, name) {
| |
| − | var list = this.getStyleList(element), index = list.indexOf(name);
| |
| − | if (index >= 0) {
| |
| − | list.splice(index, 1);
| |
| − | element.setAttribute('class', list.join(' '));
| |
| − | }
| |
| − | },
| |
| − | isSupportedBrowser: function () {
| |
| − | return 'localStorage' in win &&
| |
| − | 'querySelector' in doc &&
| |
| − | 'addEventListener' in win &&
| |
| − | 'getComputedStyle' in win && doc.compatMode === 'CSS1Compat';
| |
| − | }
| |
| − | };
| |
| − |
| |
| − | // Button
| |
| − |
| |
| − | var Button = function Button(element, contentElement) {
| |
| − | var self = this;
| |
| − |
| |
| − | element.addEventListener('click', function (event) {
| |
| − | self.onClick(event);
| |
| − | }, false);
| |
| − |
| |
| − | this._element = element;
| |
| − | this._contentElement = contentElement || this._element;
| |
| − | };
| |
| − |
| |
| − | Button.prototype.onClick = function () {};
| |
| − |
| |
| − | Button.prototype.setText = function (text) {
| |
| − | this._contentElement.textContent = text;
| |
| − | return this;
| |
| − | };
| |
| − |
| |
| − | // Select
| |
| − |
| |
| − | var Select = function Select(form, itemName) {
| |
| − | var self = this;
| |
| − |
| |
| − | form.reset();
| |
| − |
| |
| − | form.addEventListener('click', function (event) {
| |
| − | var target = event.target;
| |
| − | if ('value' in target) {
| |
| − | self.onSelect(target.value);
| |
| − | }
| |
| − | }, false);
| |
| − |
| |
| − | form.addEventListener('change', function (event) {
| |
| − | var target = event.target;
| |
| − | if (target.checked) {
| |
| − | self.onChange(target.value);
| |
| − | }
| |
| − | }, false);
| |
| − |
| |
| − | this._form = form;
| |
| − | this._itemName = itemName;
| |
| − | };
| |
| − |
| |
| − | Select.prototype.onSelect = function () {};
| |
| − |
| |
| − | Select.prototype.onChange = function () {};
| |
| − |
| |
| − | Select.prototype.isHidden = function () {
| |
| − | return this._form.hasAttribute('hidden');
| |
| − | };
| |
| − |
| |
| − | Select.prototype.getItems = function () {
| |
| − | return this._form[this._itemName] || [];
| |
| − | };
| |
| − |
| |
| − | Select.prototype.getValue = function () {
| |
| − | var i, n, items = this.getItems();
| |
| − | for (i = 0, n = items.length; i < n; i++) {
| |
| − | if (items[i].checked) {
| |
| − | return items[i].value;
| |
| − | }
| |
| − | }
| |
| − | return '';
| |
| − | };
| |
| − |
| |
| − | Select.prototype.setValue = function (value) {
| |
| − | var i, n, items = this.getItems();
| |
| − | if (value === this.getValue()) {
| |
| − | return this;
| |
| − | }
| |
| − | for (i = 0, n = items.length; i < n; i++) {
| |
| − | if (items[i].value === value) {
| |
| − | items[i].checked = true;
| |
| − | this.onChange(value);
| |
| − | break;
| |
| − | }
| |
| − | }
| |
| − | return this;
| |
| − | };
| |
| − |
| |
| − | Select.prototype.setHidden = function (hidden) {
| |
| − | hidden = !!hidden;
| |
| − | if (hidden !== this.isHidden()) {
| |
| − | this._form[(hidden ? 'set' : 'remove') + 'Attribute']('hidden', '');
| |
| − | this.onHiddenChange(hidden);
| |
| − | }
| |
| − | return this;
| |
| − | };
| |
| − |
| |
| − | Select.prototype.onHiddenChange = function () {};
| |
| − |
| |
| − | // Widget
| |
| − |
| |
| − | var Widget = function Widget(options) {
| |
| − | var self = this,
| |
| − | active,
| |
| − | select = options.select,
| |
| − | element = options.element,
| |
| − | storage = options.storage,
| |
| − | autoMode = options.autoMode,
| |
| − | pageLang = options.pageLang,
| |
| − | userLang = options.userLang,
| |
| − | translator = options.translator,
| |
| − | leftButton = options.leftButton,
| |
| − | rightButton = options.rightButton,
| |
| − | closeButton = options.closeButton,
| |
| − | defaultLang;
| |
| − |
| |
| − | this._element = element;
| |
| − | this._pageLang = pageLang;
| |
| − | this._translator = translator;
| |
| − |
| |
| − | this.onStateChange = function (name, enable) {
| |
| − | if (name === 'active') {
| |
| − | storage.setValue('active', enable);
| |
| − | }
| |
| − | };
| |
| − |
| |
| − | select.onSelect = function (lang) {
| |
| − | this.setHidden(true);
| |
| − | self.translate(lang);
| |
| − | };
| |
| − |
| |
| − | select.onChange = function (lang) {
| |
| − | storage.setValue('lang', lang);
| |
| − | rightButton.setText(lang);
| |
| − | self.setState('invalid', lang === pageLang);
| |
| − | };
| |
| − |
| |
| − | select.onHiddenChange = function (hidden) {
| |
| − | var docElem = doc.documentElement, formRect;
| |
| − | self.setState('expanded', !hidden);
| |
| − | if (!hidden) {
| |
| − | self.setState('right', false)
| |
| − | .setState('bottom', false);
| |
| − | element.focus();
| |
| − | formRect = this._form.getBoundingClientRect();
| |
| − |
| |
| − | if (formRect.right + (win.pageXOffset || docElem.scrollLeft) + 1 >= Math.max(docElem.clientWidth, docElem.scrollWidth)) {
| |
| − | self.setState('right', true);
| |
| − | }
| |
| − |
| |
| − | if (formRect.bottom + (win.pageYOffset || docElem.scrollTop) + 1 >= Math.max(docElem.clientHeight, docElem.scrollHeight)) {
| |
| − | self.setState('bottom', true);
| |
| − | }
| |
| − | }
| |
| − | };
| |
| − |
| |
| − | element.addEventListener('blur', function () {
| |
| − | select.setHidden(true);
| |
| − | }, false);
| |
| − |
| |
| − | element.addEventListener('keydown', function (event) {
| |
| − | switch (event.keyCode) {
| |
| − | case util.keycode.ESCAPE:
| |
| − | select.setHidden(true);
| |
| − | break;
| |
| − | }
| |
| − | }, false);
| |
| − |
| |
| − | translator.on('error', function () {
| |
| − | this.abort();
| |
| − | self.setState('busy', false)
| |
| − | .setState('error', true);
| |
| − | });
| |
| − |
| |
| − | translator.on('progress', function (progress) {
| |
| − | switch (progress) {
| |
| − | case 0:
| |
| − | self.setState('busy', true)
| |
| − | .setState('active', true);
| |
| − | break;
| |
| − |
| |
| − | case 100:
| |
| − | self.setState('done', true)
| |
| − | .setState('busy', false);
| |
| − | break;
| |
| − | }
| |
| − | });
| |
| − |
| |
| − | leftButton.onClick = function () {
| |
| − | select.setHidden(true);
| |
| − | self.translate(select.getValue());
| |
| − | };
| |
| − |
| |
| − | rightButton.onClick = function () {
| |
| − | if (self.hasState('active')) {
| |
| − | translator.undo();
| |
| − | self.setState('busy', false)
| |
| − | .setState('done', false)
| |
| − | .setState('error', false)
| |
| − | .setState('active', false);
| |
| − | } else {
| |
| − | select.setHidden(!select.isHidden());
| |
| − | }
| |
| − | };
| |
| − |
| |
| − | closeButton.onClick = function () {
| |
| − | select.setHidden(true);
| |
| − | };
| |
| − |
| |
| − | defaultLang = storage.getValue('lang') || userLang;
| |
| − |
| |
| − | if (defaultLang) {
| |
| − | select.setValue(defaultLang);
| |
| − | active = storage.getValue('active');
| |
| − | if (active || (autoMode && active === undefined)) {
| |
| − | this.translate(defaultLang);
| |
| − | }
| |
| − | }
| |
| − | };
| |
| − |
| |
| − | Widget.prototype.hasState = function (name) {
| |
| − | return util.hasStyleName(this._element, 'yt-state_' + name);
| |
| − | };
| |
| − |
| |
| − | Widget.prototype.setState = function (name, enable) {
| |
| − | var hasState = this.hasState(name);
| |
| − | enable = !!enable;
| |
| − | if (enable === hasState) {
| |
| − | return this;
| |
| − | }
| |
| − | util[(enable ? 'add' : 'remove') + 'StyleName'](
| |
| − | this._element, 'yt-state_' + name
| |
| − | );
| |
| − | this.onStateChange(name, enable);
| |
| − | return this;
| |
| − | };
| |
| − |
| |
| − | Widget.prototype.translate = function (targetLang) {
| |
| − | if (targetLang && !this.hasState('active')) {
| |
| − | this._translator.translate(this._pageLang, targetLang);
| |
| − | }
| |
| − | return this;
| |
| − | };
| |
| − |
| |
| − | Widget.prototype.onStateChange = function () {};
| |
| − |
| |
| − | // Storage
| |
| − |
| |
| − | var Storage = function Storage(name) {
| |
| − | this._name = name;
| |
| − | try {
| |
| − | this._data = win.JSON.parse(win.localStorage[name]);
| |
| − | } catch (error) {
| |
| − | this._data = {};
| |
| − | }
| |
| − | };
| |
| − |
| |
| − | Storage.prototype.getValue = function (prop) {
| |
| − | return this._data[prop];
| |
| − | };
| |
| − |
| |
| − | Storage.prototype.setValue = function (prop, value) {
| |
| − | this._data[prop] = value;
| |
| − | try {
| |
| − | win.localStorage[this._name] = win.JSON.stringify(this._data);
| |
| − | } catch (error) {}
| |
| − | };
| |
| − |
| |
| − | var wrapper = doc.getElementById(params.widgetId);
| |
| − |
| |
| − | if (!wrapper || !util.isSupportedBrowser()) {
| |
| − | return;
| |
| − | }
| |
| − |
| |
| − | var initWidget = function () {
| |
| − | util.loadScript('https://yastatic.net/s3/translate/v18.9.4/js/tr_page.js', wrapper, function () {
| |
| − | util.loadResource('https://translate.yandex.net/website-widget/v1/widget.html',
| |
| − | function (responseText) {
| |
| − | var element;
| |
| − |
| |
| − | if (!responseText) {
| |
| − | return;
| |
| − | }
| |
| − |
| |
| − | wrapper.innerHTML = responseText;
| |
| − | element = wrapper.querySelector('.yt-widget');
| |
| − | if (params.widgetTheme) {
| |
| − | element.setAttribute('data-theme', params.widgetTheme);
| |
| − | }
| |
| − |
| |
| − | new Widget({
| |
| − | select: new Select(element.querySelector('.yt-listbox'), 'yt-lang'),
| |
| − | element: element,
| |
| − | storage: new Storage('yt-widget'),
| |
| − | autoMode: params.autoMode === 'true',
| |
| − | pageLang: params.pageLang,
| |
| − | userLang: (nav.language || nav.userLanguage || '').split('-')[0],
| |
| − | translator: new namespace.PageTranslator({
| |
| − | srv: 'tr-url-widget',
| |
| − | sid: '5d424e35.5bba81e5.19361281',
| |
| − | url: 'https://translate.yandex.net/api/v1/tr.json/translate',
| |
| − | autoSync: true,
| |
| − | maxPortionLength: 600
| |
| − | }),
| |
| − | leftButton: new Button(element.querySelector('.yt-button_type_left')),
| |
| − | rightButton: new Button(
| |
| − | element.querySelector('.yt-button_type_right'),
| |
| − | element.querySelector('.yt-button_type_right > .yt-button__text')
| |
| − | ),
| |
| − | closeButton: new Button(element.querySelector('.yt-button_type_close'))
| |
| − | });
| |
| − | }
| |
| − | );
| |
| − | });
| |
| − | };
| |
| − |
| |
| − | if (doc.readyState === 'complete' || doc.readyState === 'interactive') {
| |
| − | initWidget();
| |
| − | } else {
| |
| − | doc.addEventListener('DOMContentLoaded', initWidget, false);
| |
| − | }
| |
| − | })(this, this.document, this.navigator, {"pageLang":"","autoMode":"","widgetTheme":"","widgetId":""}, this.yt = this.yt || {});
| |
| | /* Размещённый здесь код JavaScript будет загружаться пользователям при обращении к каждой странице */ | | /* Размещённый здесь код JavaScript будет загружаться пользователям при обращении к каждой странице */ |