Youtube Player Speed Slider

Add Speed Slider to Youtube Player Settings

当前为 2017-02-02 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Youtube Player Speed Slider
  3. // @namespace youtube_player_speed_slider
  4. // @version 0.2.2
  5. // @description Add Speed Slider to Youtube Player Settings
  6. // @author Łukasz
  7. // @match https://*.youtube.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. var yts = {};
  12.  
  13. // yts.env = "dev";
  14. yts.env = "prod";
  15.  
  16. yts.option = {
  17. timeoutBuild: 500,
  18. timeoutRemove: 1000,
  19. lastClick: 0
  20. };
  21.  
  22. yts.elements = {
  23. menu : null,
  24. speedMenu: null,
  25. slider: null,
  26. sliderLabel: null,
  27. annot: null
  28. };
  29.  
  30. yts.event = {
  31. speedRemove: false,
  32. playerObserve: false,
  33. addEnd: true
  34. };
  35.  
  36. yts.modules = {
  37. 'before':[
  38. 'click',
  39. 'setting',
  40. 'i18n',
  41. 'ad'
  42. ],
  43. 'after':[
  44. 'slider',
  45. 'menu',
  46. 'annot',
  47. 'player',
  48. 'appmenu'
  49. ],
  50. 'spfdone':[
  51. 'appmenu',
  52. 'player',
  53. 'annot'
  54. ]
  55. };
  56.  
  57. /*************************************
  58. * TRANSLATION *
  59. ************************************/
  60. yts.i18n = {};
  61.  
  62. yts.i18n.dic = {
  63. pl: {
  64. 'Speed': 'Szybkość',
  65. 'Settings': 'Ustawienia',
  66. 'Language': 'Język',
  67. 'Switch off advertisement': 'Wyłączaj reklamy',
  68. 'Hide annotation': 'Ukryj adnotacje',
  69. 'Remember speed': 'Pamiętaj szybkość'
  70. },
  71. de: {
  72. 'Speed' : 'Geschwindigkeit',
  73. 'Settings': 'Einstellungen',
  74. 'Language': 'Sprache',
  75. 'Switch off advertisement': 'Abschalten Werbung',
  76. 'Hide annotation': 'Ausblenden Anmerkungen',
  77. 'Remember speed': 'Erinnern Geschwindigkeit'
  78. },
  79. fr:{
  80. 'Speed':'Vitesse',
  81. 'Settings':'Paramètres',
  82. 'Language': 'La langue',
  83. 'Switch off advertisement': 'Désactiver la publicité',
  84. 'Hide annotation': 'Cacher les annotations',
  85. 'Remember speed': 'Rappelez-vous la vitesse'
  86. },
  87. en:{}
  88. };
  89.  
  90. yts.i18n.opt = {
  91. lang: 'en',
  92. default: 'en',
  93. map:{
  94. pl: 'pl',
  95. pl_pl: 'pl',
  96. en: 'en',
  97. en_gb: 'en',
  98. de: 'de',
  99. fr: 'fr'
  100. }
  101. };
  102.  
  103. yts.i18n.init = function () {
  104. yts.i18n.opt.lang = yts.i18n.getLang();
  105. yts.setting.change('lang', function (val) {
  106. yts.i18n.opt.lang = yts.i18n.getLang();
  107. });
  108. };
  109.  
  110. yts.i18n.getLang = function () {
  111. var lang = yts.i18n.filter(yts.setting.get('lang'));
  112. if(lang !== '' && yts.i18n.isAllow(lang)){
  113. return yts.i18n.map(lang);
  114. }
  115.  
  116. lang = yts.i18n.filter(yts.$.get('html').getAttribute('lang'));
  117. if(lang !== '' && yts.i18n.isAllow(lang)){
  118. return yts.i18n.map(lang);
  119. }
  120.  
  121. return yts.i18n.opt.default;
  122. };
  123.  
  124. yts.i18n.isAllow = function (lang) {
  125. return yts.i18n.opt.map.hasOwnProperty(lang);
  126. };
  127.  
  128. yts.i18n.t = function (pattern) {
  129. if(yts.i18n.dic.hasOwnProperty(yts.i18n.opt.lang) &&
  130. yts.i18n.dic[yts.i18n.opt.lang].hasOwnProperty(pattern)){
  131. return yts.i18n.dic[yts.i18n.opt.lang][pattern];
  132. }
  133. else {
  134. return pattern;
  135. }
  136. };
  137.  
  138. yts.i18n.filter = function (lang) {
  139. return lang ? lang.replace('-', '_').toLowerCase() : '';
  140. };
  141.  
  142. yts.i18n.map = function (lang) {
  143. return yts.i18n.opt.map[lang]
  144. };
  145.  
  146. yts.i18n.all = function () {
  147. var ret=[];
  148. for(var p in yts.i18n.dic) if(yts.i18n.dic.hasOwnProperty(p)) ret.push(p);
  149. return ret;
  150. };
  151.  
  152. /*************************************
  153. * INIT *
  154. ************************************/
  155. yts.init = function () {
  156. yts.log('Init App');
  157. yts.modules.before.forEach(function (module) {
  158. yts.run(module);
  159. });
  160. yts.$.event(document, "spfdone", function () {
  161. yts.modules.spfdone.forEach(function (module) {
  162. yts.run(module);
  163. });
  164. });
  165.  
  166. yts.option.lastClick = (new Date()).getTime();
  167. yts.menu.reopen();
  168. yts.buildApp(0);
  169. };
  170.  
  171. yts.run = function (module) {
  172. try{
  173. yts.log('Init ' + module + ' module');
  174. yts[module].init();
  175. }
  176. catch (e){
  177. yts.log('Error in ' + module + ' module');
  178. }
  179. };
  180.  
  181. yts.buildApp = function (num) {
  182. num++;
  183. yts.elements.menu = yts.$.get('.ytp-panel-menu');
  184. if (yts.elements.menu !== null) {
  185. yts.log('Init Build Menu after ' + num + ' attempt(s)');
  186. setTimeout(yts.menu.removeDefaultSpeed, yts.option.timeoutRemove);
  187. yts.modules.after.forEach(function (module) {
  188. yts.run(module);
  189. });
  190. }
  191. else {
  192. yts.log('Settimeout buildApp attempt: ' + num);
  193. setTimeout(yts.buildApp, yts.option.timeoutBuild, num);
  194. }
  195. };
  196.  
  197.  
  198. /*************************************
  199. * MENU *
  200. ************************************/
  201. yts.menu = {};
  202.  
  203. yts.menu.init = function () {
  204.  
  205. var speedMenu = yts.$.new('div', {'className': 'ytp-menuitem', id:'yts-menu'});
  206. var right = yts.$.new('div', {'className': 'ytp-menuitem-content'});
  207.  
  208. speedMenu.appendChild(yts.elements.sliderLabel);
  209. speedMenu.appendChild(right.appendChild(yts.elements.slider));
  210. yts.elements.menu.appendChild(speedMenu);
  211. yts.menu.event();
  212. };
  213.  
  214. yts.menu.event = function () {
  215. yts.elements.menu.addEventListener('click', yts.menu.click);
  216. };
  217.  
  218. yts.menu.removeDefaultSpeed = function(){
  219. var switchers = yts.$.getOpt(".ytp-menuitem", {role:'menuitemcheckbox'});
  220. var toRemove = null;
  221.  
  222. if(!yts.player.hasClass('ad-interrupting') &&
  223. switchers &&
  224. switchers.length &&
  225. !yts.event.speedRemove
  226. ){
  227. toRemove = switchers[switchers.length-1].nextElementSibling;
  228. if(toRemove && toRemove.id !== 'yts-menu'){
  229.  
  230. yts.log('Remove default speed menu item');
  231. yts.$.style(toRemove, 'display', 'none');
  232. yts.event.speedRemove = true;
  233. }
  234. }
  235. };
  236.  
  237. yts.menu.reopen = function () {
  238. var settings_button = yts.$.get(".ytp-settings-button");
  239. settings_button && settings_button.click();
  240. settings_button && settings_button.click();
  241. };
  242.  
  243. yts.menu.click = function () {
  244. yts.option.lastClick = (new Date()).getTime();
  245. };
  246.  
  247. /*************************************
  248. * SLIDER *
  249. ************************************/
  250. yts.slider = {};
  251.  
  252. yts.slider.init = function () {
  253. var speed = yts.setting.get('speed') || 1;
  254. speed = yts.setting.get('rem') ? speed : 1;
  255. yts.elements.sliderLabel = yts.$.new('div', {'className': 'ytp-menuitem-label'});
  256. yts.elements.slider = yts.$.new('input', {
  257. 'className': '',
  258. 'type': 'range',
  259. 'min': 0.5,
  260. 'max': 4,
  261. 'step': 0.1,
  262. 'value': speed,
  263. style:{
  264. 'width': '90%',
  265. 'margin':'0 5%',
  266. 'padding': '6px 0'
  267. }
  268. });
  269. yts.$.event(yts.elements.slider, 'change', yts.slider.change);
  270. yts.$.event(yts.elements.slider, 'input', yts.slider.move);
  271. yts.$.event(yts.elements.slider, 'wheel', yts.slider.wheel);
  272.  
  273. yts.slider.updateLabel(speed);
  274. };
  275.  
  276. yts.slider.move = function (event) {
  277. yts.slider.updateLabel(event.target.value);
  278. };
  279.  
  280. yts.slider.wheel = function (event) {
  281. var val = parseFloat(event.target.value) + (event.wheelDelta > 0 ? 0.1 : -0.1);
  282. val = val < 0.5 ? 0.5 : (val > 4 ? 4 : val);
  283. if(event.target.value != val){
  284. event.target.value = val;
  285. yts.player.duration(val);
  286. yts.slider.updateLabel(val);
  287. }
  288. event.preventDefault();
  289. };
  290.  
  291. yts.slider.change = function (event) {
  292. yts.player.duration(event.target.value);
  293. };
  294.  
  295. yts.slider.updateLabel = function (val) {
  296. yts.elements.sliderLabel.innerHTML = yts.i18n.t('Speed') + ': ' + parseFloat(val).toFixed(1);
  297. };
  298.  
  299.  
  300. /*************************************
  301. * PLAYER *
  302. ************************************/
  303. yts.player = {};
  304.  
  305. yts.player.init = function(){
  306. yts.elements.player = yts.$.get('.html5-main-video');
  307. yts.player.observe();
  308. if(yts.setting.get('speed') && yts.setting.get('rem')){
  309. yts.player.duration(yts.setting.get('speed'));
  310. yts.slider.updateLabel(yts.setting.get('speed'));
  311. }
  312.  
  313. };
  314.  
  315. yts.player.hasClass = function (cls) {
  316. yts.player.init();
  317. return yts.elements.player && yts.elements.player.classList.contains(cls)
  318. };
  319.  
  320. yts.player.duration = function(value){
  321. yts.setting.set('speed', value);
  322. yts.elements.player.playbackRate = value;
  323. };
  324.  
  325. yts.player.observe = function () {
  326. if(!yts.event.playerObserve){
  327. yts.observer.init(yts.elements.player.parentNode.parentNode, function (mutation) {
  328. if(/html5-video-player/.test(mutation.target.className) && !yts.event.speedRemove) {
  329. yts.menu.removeDefaultSpeed();
  330. }
  331. });
  332. yts.event.playerObserve = true;
  333. }
  334. };
  335.  
  336. /*************************************
  337. * ANNOTATION *
  338. ************************************/
  339. yts.annot = {};
  340. yts.annot.init = function(){
  341. yts.elements.annot = yts.$.get('.video-annotations');
  342. if(yts.setting.get('annot')){
  343. yts.annot.switch("off");
  344. }
  345. yts.setting.change('annot', function (val) {
  346. if(val){
  347. yts.annot.switch("off");
  348. }
  349. else{
  350. yts.annot.switch("on");
  351. }
  352. });
  353. };
  354.  
  355. yts.annot.change = function (mutation) {
  356. if(mutation.type == "attributes" && mutation.target.getAttribute('role')=="menuitemcheckbox"){
  357. yts.annot.switch("off");
  358. }
  359. };
  360.  
  361. yts.annot.switch = function(type){
  362. if(yts.elements.annot && type == 'off'){
  363. yts.$.style(yts.elements.annot, 'display', 'none', 'important');
  364. }
  365. else if(yts.elements.annot && type == 'on'){
  366. yts.$.style(yts.elements.annot, 'display', 'block');
  367. }
  368. };
  369.  
  370. /*************************************
  371. * COOKIE *
  372. ************************************/
  373. yts.cookie ={};
  374.  
  375. yts.cookie.set = function (name, value, option) {
  376. var d = new Date();
  377. option = option || {};
  378. option.expires = option.expires || 366;
  379. d.setTime(d.getTime() + (option.expires*24*60*60*1000));
  380. option.expires = d.toUTCString();
  381. option.path = option.path || '/';
  382.  
  383. var cookie = name + "=" + value + "; ";
  384. for(var prop in option){
  385. cookie += prop + "=" + option[prop] +"; ";
  386. }
  387. document.cookie = cookie;
  388. };
  389.  
  390. yts.cookie.get = function (name) {
  391. name += "=";
  392. var ca = document.cookie.split(';');
  393. for(var i = 0; i <ca.length; i++) {
  394. var c = ca[i];
  395. while (c.charAt(0)==' ') {
  396. c = c.substring(1);
  397. }
  398. if (c.indexOf(name) == 0) {
  399. return c.substring(name.length,c.length);
  400. }
  401. }
  402. return null;
  403. };
  404.  
  405. /************************************
  406. * DOM *
  407. ************************************/
  408. yts.$ = {};
  409.  
  410. yts.$.event = function (obj, event, callback) {
  411. obj.addEventListener(event, callback);
  412. };
  413.  
  414. yts.$.new = function (tag, option) {
  415. var element = document.createElement(tag);
  416. for (var param in option) {
  417. if(param == 'data' || param == 'style'|| param == 'attr'){
  418. for(var data in option[param]){
  419. yts.$[param](element, data, option[param][data]);
  420. }
  421. }
  422. else{
  423. element[param] = option[param];
  424. }
  425. }
  426. return element;
  427. };
  428.  
  429. yts.$.get = function (tselector, all) {
  430. all = all || false;
  431. var type = tselector.substring(0, 1);
  432. var selector = tselector.substring(1);
  433. var elements;
  434. if (type == "#") {
  435. return document.getElementById(selector);
  436. }
  437. else if (type == ".") {
  438. elements = document.getElementsByClassName(selector);
  439. }
  440. else{
  441. elements = document.querySelectorAll(tselector);
  442. }
  443.  
  444. if (all) {
  445. return elements;
  446. }
  447. else {
  448. return elements.length ? elements[0] : null;
  449. }
  450. };
  451.  
  452. yts.$.data = function (elem, key, val) {
  453. key = key.replace(/-(\w)/gi, function(x){return x.charAt(1).toUpperCase()});
  454. if(typeof val !== 'undefined'){
  455. elem.dataset[key] = val;
  456. }
  457. return elem.dataset[key];
  458.  
  459. };
  460.  
  461. yts.$.style = function (elem, key, val, priority) {
  462. priority = priority || '';
  463. if(typeof val !== 'undefined'){
  464. elem.style.setProperty(key, val, priority);
  465. }
  466. return elem.style.getPropertyValue(key);
  467.  
  468. };
  469.  
  470. yts.$.attr = function (elem, key, val) {
  471. if(typeof val !== 'undefined'){
  472. elem.setAttribute(key, val);
  473. }
  474. return elem.getAttribute(key);
  475.  
  476. };
  477.  
  478. yts.$.getOpt = function(selector, option){
  479. var el = yts.$.get(selector, true);
  480. var pass = [];
  481. var correct;
  482. for(var i =0; i< el.length; i++){
  483. correct = true;
  484. for(var prop in option){
  485. if(!yts.$.has(el[i], prop, option[prop])){
  486. correct = false;
  487. break;
  488. }
  489. }
  490. if(correct){
  491. pass.push(el[i]);
  492. }
  493. }
  494. return pass;
  495. };
  496.  
  497. yts.$.has = function (elem, key, val) {
  498. if(elem.hasAttribute(key)){
  499. var attr = elem.getAttribute(key);
  500. if(val !== null){
  501. return attr == val;
  502. }
  503. return true;
  504. }
  505. return false;
  506. };
  507.  
  508.  
  509. /*************************************
  510. * OBSERVER *
  511. ************************************/
  512. yts.observer= {};
  513.  
  514. yts.observer.obj = null;
  515.  
  516. yts.observer.get = function () {
  517. return window.MutationObserver || window.WebKitMutationObserver;
  518. };
  519.  
  520. yts.observer.init = function (element, callback) {
  521. var MutationObserver = yts.observer.get();
  522. if( MutationObserver ){
  523. var obs = new MutationObserver(function(mutations, observer){
  524. callback(mutations[0]);
  525. });
  526.  
  527. obs.observe( element, {
  528. childList: true,
  529. subtree: true,
  530. attributes:true,
  531. characterData:true,
  532. attributeOldValue:true,
  533. characterDataOldValue:true
  534. });
  535. }
  536. };
  537.  
  538.  
  539. /*************************************
  540. * SETTINGS *
  541. ************************************/
  542. yts.setting = {};
  543. yts.setting.item = {
  544. rem:{
  545. label: 'Remember speed',
  546. type: 'switcher'
  547. },
  548. annot:{
  549. label: 'Hide annotation',
  550. type: 'switcher'
  551. },
  552. ad:{
  553. label: 'Switch off advertisement',
  554. type: 'switcher'
  555. },
  556. lang:{
  557. label: 'Language',
  558. type: 'radio',
  559. items: yts.i18n.all()
  560. }
  561. };
  562. yts.setting.settings = null;
  563. yts.setting.event = {};
  564.  
  565. yts.setting.init = function(){
  566. var setting = localStorage.getItem('yts');
  567. yts.setting.settings = JSON.parse(setting === null ? '{}' : setting);
  568. };
  569.  
  570. yts.setting.set = function(key, val){
  571. yts.setting.settings[key] = val;
  572.  
  573. if(yts.setting.event.hasOwnProperty(key)){
  574. yts.setting.event[key](val);
  575. }
  576. localStorage.setItem('yts', JSON.stringify(yts.setting.settings));
  577. };
  578.  
  579. yts.setting.get = function(kay){
  580. return yts.setting.settings.hasOwnProperty(kay) ?
  581. yts.setting.settings[kay] : null;
  582. };
  583.  
  584. yts.setting.change = function(key, callback){
  585. yts.setting.event[key] = callback;
  586. };
  587.  
  588. /*************************************
  589. * CLICK *
  590. ************************************/
  591. yts.click = {};
  592. yts.click.fun = [];
  593. yts.click.init = function(){
  594. yts.$.event(yts.$.get('body'), 'click', function(event){
  595. for(var i =0; i<yts.click.fun.length; i++){
  596. yts.click.fun[i](event);
  597. }
  598. })
  599. };
  600.  
  601. yts.click.add = function(fun){
  602. yts.click.fun.push(fun);
  603. };
  604.  
  605. /*************************************
  606. * LOGGER *
  607. ************************************/
  608.  
  609. yts.log = function (text, type) {
  610. if(yts.env == 'prod') return 1;
  611. type = type || 'l';
  612. var app = "[YT SPEED SLIDER] ";
  613. if(type == "l") console.log(app, text);
  614. else if(type == "e") console.error(app, text);
  615. else if(type == "i") console.info(app, text);
  616. else if(type == "w") console.warn(app, text);
  617. };
  618.  
  619. /*************************************
  620. * ADVERTISEMENT *
  621. ************************************/
  622. yts.ad = {};
  623. yts.ad.init = function(){
  624. if(yts.setting.get('ad')){
  625. yts.ad.switch('off');
  626. }
  627. yts.setting.change('ad', function (val) {
  628. if(val){
  629. yts.ad.switch('off');
  630. }
  631. else{
  632. yts.ad.switch('on');
  633. }
  634. });
  635. };
  636.  
  637. yts.ad.switch = function (type) {
  638. var ad = yts.$.get(".video-ads");
  639. if(type == "off"){
  640. yts.cookie.set("VISITOR_INFO1_LIVE", "oKckVSqvaGw", {domain: "youtube.com"});
  641. ad && yts.$.style(ad, 'display', 'none', 'important');
  642. }
  643. else {
  644. yts.cookie.set("VISITOR_INFO1_LIVE", "", {domain: "youtube.com", expires: -1});
  645. ad && yts.$.style(ad, 'display', 'block');
  646. }
  647. };
  648.  
  649.  
  650. /*************************************
  651. * APP MENU *
  652. ************************************/
  653. yts.appmenu = {};
  654.  
  655. yts.appmenu.init = function(){
  656. yts.appmenu.build();
  657. };
  658.  
  659. yts.appmenu.build = function(){
  660.  
  661. yts.appmenu.panel();
  662. var menu = yts.$.get("#watch8-secondary-actions");
  663. if(menu){
  664. menu.appendChild(yts.appmenu.button());
  665. }
  666. };
  667.  
  668. yts.appmenu.button = function(){
  669. var button = yts.$.new('button', {
  670. 'className':'yt-uix-button yt-uix-button-opacity action-panel-trigger yt-uix-button-toggled',
  671. 'title' : yts.i18n.t('Settings'),
  672. 'type':'button',
  673. 'innerHTML':'<span class="yt-uix-button-content">Yts</span>',
  674. 'data': {
  675. 'tooltip-text':yts.i18n.t('Settings'),
  676. 'button-toggle':'true',
  677. 'trigger-for':'action-panel-yts'
  678. }
  679. });
  680.  
  681. return button;
  682. };
  683.  
  684. yts.appmenu.panel = function(){
  685. var panel = yts.$.new('div', {
  686. 'id':'action-panel-yts',
  687. 'className':'action-panel-content',
  688. data: {'panel-loaded':'true'},
  689. style: {'display':'none'}
  690. });
  691.  
  692. var list = yts.$.new('ul', {'className':'yt-uix-kbd-nav yt-uix-kbd-nav-list'});
  693. yts.appmenu.addSettingItems(list);
  694. panel.appendChild(list);
  695. var panels = yts.$.get('#watch-action-panels');
  696. if(panels){
  697. panels.appendChild(panel);
  698. }
  699. };
  700.  
  701. yts.appmenu.addSettingItems = function (list) {
  702. for(var item in yts.setting.item){
  703. var li = yts.$.new('li', {
  704. 'className':'ytp-menuitem',
  705. 'role':"menuitemcheckbox",
  706. attr: {
  707. 'aria-checked': yts.setting.get(item) ? "true" : "false",
  708. }
  709. });
  710. var type = yts.setting.item[item].type;
  711. if(type === 'switcher'){
  712. li = yts.appmenu.switcherItem(li, item);
  713. }
  714. if(type === 'radio'){
  715. li = yts.appmenu.radioItem(li, item);
  716. }
  717.  
  718. list.appendChild(li);
  719. }
  720. };
  721.  
  722.  
  723. yts.appmenu.switcherItem = function(li, item){
  724. var switcher = yts.$.new('div', {
  725. 'className':'ytp-menuitem-toggle-checkbox',
  726. style: {
  727. 'background-color':'#d2d2d2',
  728. 'margin-left': '10px'
  729. },
  730. data: {
  731. 'name': item
  732. },
  733. 'onclick' : function (event) {
  734. var el = event.target;
  735. var parent = el.parentNode;
  736. var stat = parent.getAttribute('aria-checked');
  737. if(stat == 'false'){
  738. yts.$.attr(parent, 'aria-checked' , 'true');
  739. yts.setting.set(yts.$.data(el, 'name'), true);
  740. }
  741. else{
  742. yts.$.attr(parent, 'aria-checked' , 'false');
  743. yts.setting.set(yts.$.data(el, 'name'), false);
  744. }
  745. }
  746. });
  747. var span = yts.$.new('span', {'innerHTML':yts.i18n.t(yts.setting.item[item].label)});
  748.  
  749.  
  750. li.appendChild(switcher);
  751. li.appendChild(span);
  752. return li;
  753. };
  754.  
  755. yts.appmenu.radioItem = function(li, item){
  756. var list = yts.setting.item[item].items;
  757. var checked = yts.setting.get(item);
  758. li.appendChild(yts.$.new('div',{'innerHTML':yts.i18n.t(yts.setting.item[item].label), style:{'margin-bottom':'5px'}}));
  759.  
  760. for(var i =0; i< list.length; i++){
  761. var label = yts.$.new('label',{style:{'margin-right':'5px'}});
  762. var spanInput = yts.$.new('span', {
  763. 'className': 'yt-uix-form-input-radio-container'
  764. });
  765. var input = yts.$.new('input', {
  766. 'type': 'radio',
  767. 'name': 'yts-' + item,
  768. 'checked': list[i] == checked,
  769. data: {
  770. 'name': item,
  771. 'val': list[i]
  772. },
  773. 'onchange': function (event) {
  774. var el = event.target;
  775. yts.setting.set(yts.$.data(el, 'name'), yts.$.data(el, 'val'));
  776. }
  777. });
  778. var spanCheck = yts.$.new('span', {'className': 'yt-uix-form-input-radio-element'});
  779. var spanLabel = yts.$.new('span', {'innerHTML': list[i]});
  780.  
  781. spanInput.appendChild(input);
  782. spanInput.appendChild(spanCheck);
  783.  
  784. label.appendChild(spanInput);
  785. label.appendChild(spanLabel);
  786.  
  787. li.appendChild(label);
  788.  
  789. }
  790. return li;
  791. };
  792.  
  793.  
  794. yts.init();