|
|
(не показано 20 промежуточных версий этого же участника) |
Строка 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'); |
− | '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 будет загружаться пользователям при обращении к каждой странице */ |