Created
July 11, 2018 03:29
-
-
Save JaneOri/da84cc2bb6087db5f041387b0a586e6c to your computer and use it in GitHub Desktop.
inserted and removed callbacks for given selectors. Useful for user scripts or other hacks when you don't have source access.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Given parent container selector and child selector, call inserted and removed for elements that match the selector. | |
// Inserted and removed callbacks are called with an array of the relevant matching dom nodes. | |
// Intention is to use this for User Scripts or other cases when you don't have access to source | |
//## Begin Selector Observation Code | |
var selectors = []; | |
(new MutationObserver( | |
function (mutationsList) { | |
var s, selector, nodeMatches | |
var slen = selectors.length | |
for (s = 0; s < slen; s++) { | |
selector = selectors[s] | |
nodeMatches = node => node.nodeType === 1 && node.matches(selector.childSelector) | |
mutationsList.forEach(mu => { | |
if (mu.type === "childList" && mu.target.matches(selector.parentSelector)) { | |
var addedMatches = Array.prototype.filter.call(mu.addedNodes, nodeMatches) | |
var removedMatches = Array.prototype.filter.call(mu.removedNodes, nodeMatches) | |
addedMatches.length && selector.inserted.call(null, addedMatches) | |
removedMatches.length && selector.removed.call(null, removedMatches) | |
} | |
}) | |
} | |
} | |
)).observe(document.documentElement, { | |
childList: true, | |
subtree: true | |
}) | |
// watch the parentSelector for the specific children to be added or removed, | |
// call inserted as that parentSelector > children are added and they match childSelector | |
// call removed as that parentSelector > children are removed and they match childSelector (note they won't be in the dom any more) | |
// inserted and removed callbacks are called with the matching elements passed in as the only parameter (is an array) | |
var onParentChildSelectors = function (opts) { | |
var nullFn = () => {} | |
selectors.push(Object.assign({ | |
parentSelector: "", | |
childSelector: "", | |
inserted: nullFn, | |
removed: nullFn | |
}, opts)) | |
} | |
// remove all watch selectors: | |
// offSelector({ parentSelector }) -> matching that selector | |
// offSelector({ parentSelector, childSelector }) -> matching that selector | |
// offSelector({ parentSelector, inserted }) -> matching that parentSelector && matching that inserted function | |
// offSelector({ parentSelector, childSelector, inserted }) -> matching that selector && matching that inserted function | |
// offSelector({ parentSelector, childSelector, removed }) -> matching that selector && matching that removed function | |
// offSelector({ parentSelector, childSelector, inserted, removed }) -> matching that selector, inserted function, and removed function | |
var offSelector = function (opts) { | |
for (let s = 0; s < selectors.length; s++) { | |
let selectorObj = selectors[s] | |
let comp = Object.assign({}, selectorObj, opts) | |
let matchingProps = ["parentSelector", "childSelector", "inserted", "removed"].filter(prop => selectorObj[prop] === comp[prop]) | |
if (matchingProps.length === 4) { | |
selectors.splice(s, 1) | |
s-- | |
} | |
} | |
} | |
//## End Selector Observation Code | |
var handleNewChat = function (chatEl) { | |
var escapedId = chatEl.id.replace(/%/g, "\\%") | |
var user = chatEl.querySelector("#author-name").textContent.trim() | |
var messageEl = chatEl.querySelector("#message") | |
var message = messageEl.textContent.trim() | |
userInfo[user] = { | |
user, | |
userNameRx: new RegExp("@" + escapeRegExp(user) + "\\b", "gi"), | |
lastId: chatEl.id, | |
escapedId, | |
lastMessage: message | |
} | |
decorateMessage(messageEl) | |
} | |
onParentChildSelectors({ | |
parentSelector: "yt-live-chat-renderer #chat #items", | |
childSelector: "yt-live-chat-text-message-renderer, yt-live-chat-paid-message-renderer", | |
inserted: addedChatEls => addedChatEls.forEach(handleNewChat) | |
// removed | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment