Compute things with sublists and display values on an item name.
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/22313/141757/Workflowy%20computable%20values.js
var parseSelector = window.Parser.parse
window.funCache = {}
window.nodeCache = {}
var observer
// observe dom mutations to make it run every time an item is opened / closed
function start () {
GM_addStyle(`
.project .content {
display: inline-block !important;
}
.project .result {
display: inline;
color: blue;
margin-left: 10px;
}
`)
// observer = new MutationObserver(function (mutations) {
// itemOpenedOrClosed()
// })
document.body.addEventListener('click', function (e) {
if (e.target.id === 'expandButton') {
setTimeout(itemOpenedOrClosed, 1000)
}
})
itemOpenedOrClosed()
}
function watchNodes () {
var nodes = document.querySelectorAll('.project')
for (let i = 0; i < nodes.length; i++) {
let node = nodes[i]
let projectid = node.getAttribute('projectid')
if (!nodeCache[projectid]) {
var list = node.querySelector('.children')
observer.observe(list, {childList: true})
console.log('watching ' + projectid + '.')
nodeCache[projectid] = true
}
}
}
function itemOpenedOrClosed () {
for (let id in funCache) {
let script = funCache[id]
execScript(script)
}
// watchNodes()
}
function execScript ({script, selector, id, color}) {
let items = findItems(selector)
console.log('items', items)
for (let i = 0; i < items.length; i++) {
execForItem(items[i], script, id, color)
}
}
function execForItem(item, fun, id, color) {
var children = []
let par = item.querySelector('.children')
for (let p = 0; p < par.children.length; p++) {
if (par.children[p].classList.contains('project')) {
children.push(par.children[p])
}
}
var args = []
for (let i = 0; i < children.length; i++) {
let child = children[i]
let name = child.querySelector('.name .content').innerText.trim()
let note = child.querySelector('.notes').innerText.trim()
var arg = {name, note}
let results = child.querySelector('.name').querySelectorAll('.result')
for (let r = 0; r < results.length; r++) {
let result = results[r]
arg[result.classList.item(1)] = result.innerText.trim()
}
args.push(arg)
}
console.log('args', args)
var result = item.querySelector('.result.script-' + id)
if (!result) {
let content = item.querySelector('.name .content')
result = document.createElement('span')
result.className = 'result script-' + id
result.title = id
result.style.color = color
content.parentNode.insertBefore(result, content.nextSibling)
}
let resultvalue = fun(args)
console.log('resultvalue', resultvalue)
result.innerHTML = (resultvalue || '').toString()
}
function findItems (selector) {
let parsed = parseSelector(selector)
var items = null
for (let l = 0; l < parsed.length; l++) {
let layer = parsed[l]
items = select(layer, items)
}
console.log('found items', items)
return items || []
}
function select (layer, base) {
if (!base) {
base = document.querySelectorAll('.mainTreeRoot')
}
let [connector, selector] = layer
return getChildren(base, selector, connector === 'directchild')
}
function getChildren (base, selector, onlydirect=false) {
var filter
switch (selector.type) {
case 'id':
filter = node =>
node.getAttribute('projectid') === selector.val ||
node.querySelector('.bullet').href.split('#/')[1] === selector.val
break
case 'regex':
filter = node =>
node.querySelector('.name .content').innerText.search(selector.val) !== -1
break
case 'name':
filter = node =>
node.querySelector('.name .content').innerText.trim() === selector.val
break
case 'any':
filter = () => true
break
default:
throw new Error('INVALID SELECTOR: ', selector)
}
var children = []
for (let i = 0; i < base.length; i++) {
if (onlydirect) {
let par = base[i].querySelector('.children')
for (let p = 0; p < par.children.length; p++) {
if (par.children[p].classList.contains('project') && par.children[p].classList.contains('open')) {
children.push(par.children[p])
}
}
} else {
let all = base[i].querySelectorAll('.children > .project.open')
for (let i = 0; i < all.length; i++) {
children.push(all[i])
}
}
}
return children.filter(filter)
}
function registerScript (s) {
funCache[s.id] = s
}
function waitFor (selector, callback) {
let res = document.querySelector(selector)
if (res) return callback()
setTimeout(() => {
waitFor(selector, callback)
}, 1000)
}