Greasy Fork

Greasy Fork is available in English.

蓝奏云无障碍优化

蓝奏云无障碍优化脚本

当前为 2021-11-03 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name  蓝奏云无障碍优化
// @namespace    https://accjs.org/
// @version      0.1
// @description  蓝奏云无障碍优化脚本
// @author  杨永全
// @updated  2021-11-03 09:28:10
// @match  https://*.woozooo.com/*
// @grant  none
// ==/UserScript==

(function() {
function amo(proc, target, options) {
target = target || document.body;
options = options || {
      'childList': true,
      'subtree': true
    };
    let mo = new MutationObserver((records) => {proc();});
    mo.observe(target, options);
return mo;
}

  function isVisible(t) {
    return !! (!t.hasAttribute('disabled') && t.getAttribute('aria-hidden') !== 'true' && t.offsetParent !== null);
  }

  function gi(i, len, op) {
    let n = op == '+' ? +1 : -1;
    i = i + n;
    if (i >= len) {
      i = 0;
    }
    if (i < 0) {
      i = len - 1;
    }
    return i;
  }

  function _toFocus(el) {
    let tagName = el.tagName.toLowerCase();
    let tagNames = ['div', 'p', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'form', 'img', 'nav', 'header', 'main', 'footer', 'section', 'aside'];
    if (tagNames.includes(tagName) || (tagName == 'a' && !el.hasAttribute('href'))) {
      if (!el.hasAttribute('tabindex')) {
        el.setAttribute('tabindex', '-1');
      }
    }
    el.focus();
  }

  function toFocus(focusSelector, op) {
    let els = Array.prototype.slice.call(document.body.querySelectorAll('*'));
    let len = els.length;
    let aeIndex = Math.max(0, els.indexOf(document.activeElement));
    let i = aeIndex == 0 ? 0 : gi(aeIndex, len, op);
    do {
      if (els[i].matches(focusSelector) && isVisible(els[i])) {
        _toFocus(els[i]);
        break;
      }
      i = gi(i, len, op);
    } while ( i != aeIndex );
  }

  function nextFocus(selector) {
    toFocus(selector, '+');
  }

  function previousFocus(selector) {
    toFocus(selector, '-');
  }

//get label from attributes
function getLabel(labels, src) {
let label = '';
if(typeof src != 'string' || src == '') {
return label;
}
label = src;
for(let key in labels) {
if(src.includes(labels[key])) {
label = key;
break;
}
}
return label;
}


function proc() {

//label map
let labels = {
"关闭": "f_cl",
"操作": "f_sela",
"删除": "f_selb",
"启用": "f_pwdon",
"禁用": "f_pwdoff"
};

//开始上传按钮、等待上传的文件列表、当前位置、文件和文件夹名、文件和文件夹的操作链接以及操作菜单、对话框的关闭按钮、移动对话框里选择文件夹
document.querySelectorAll('.uploadBtn, .filelist .title, .filelist .cancel, .f_tp .f_tpspan, .f_name2 .follink, .f_name .aspanlink, .f_sel a, .f_sel .f_view > div, div.f_cl, div.f_midf6').forEach(function(el) {
el.setAttribute('tabindex', '0');
el.setAttribute('role', 'link');
});

//需要添加 label 的元素
document.querySelectorAll('div.f_cl, .f_sel a').forEach(function(el) {
el.setAttribute('aria-label', getLabel(labels, el.getAttribute('class')));
});


//设置密码的开关
document.querySelectorAll('.f_pwdon, .f_pwdoff').forEach(function(el) {
el.setAttribute('role', 'checkbox');
el.setAttribute('aria-checked', 'true');
el.setAttribute('tabindex', '0');
el.setAttribute('aria-label', getLabel(labels, el.getAttribute('class')));
});

//文件浏览按钮在谷歌浏览器的提示不够友好,处理一下
document.querySelectorAll('input[type="file"]').forEach(function(el) {
el.setAttribute('aria-label', '浏览');
});

//页面底部有个上传按钮,看起来没什么用,隐藏掉
document.querySelectorAll('input[id*="html5"]').forEach(function(el) {
el.setAttribute('tabindex', '-1');
el.setAttribute('aria-hidden', 'true');
});

}
document.addEventListener('keydown', function(e) {
let t = e.target || null;
let xSelector = '.f_name a, .f_name2 .follink, .f_name .aspanlink';
let xKey = e.keyCode == 88;
let zSelector = '.uploadBtn, div.f_cl';
let zKey = e.keyCode == 90;
        if (e.altKey && e.shiftKey && xKey) {
          e.preventDefault();
          previousFocus(xSelector);
        } else if (e.altKey && xKey) {
          e.preventDefault();
          nextFocus(xSelector);
        } else         if (e.altKey && e.shiftKey && zKey) {
          e.preventDefault();
          previousFocus(zSelector);
        } else if (e.altKey && zKey) {
          e.preventDefault();
          nextFocus(zSelector);
        } else if(e.keyCode == 32 || e.keyCode == 13) {
if(t.matches('[role="checkbox"], [role="button"], [role="link"]')) {
t.click();
}
}
}, null);
amo(proc);
proc();
})();