Skip to content

Change Stash's default avatar to username initials #2

@bpceee

Description

@bpceee

If you are using Atlassian's Stash at work, you must be annoyed by so many co-workers using the default avatar, which makes it so different to recognize different users. And you just couldn't ask them all to upload an avatar!

So here I write a small tampermonkey script to change the default avatar to their name initials.

const styleEl = document.createElement('style');
document.head.appendChild(styleEl);
styleEl.sheet.insertRule('.aui-avatar-inner { background-color: lightgray; color: white; font-weight: 700; line-height: 32px; }', 0);
styleEl.sheet.insertRule('.aui-avatar-small .aui-avatar-inner { line-height: 24px; }', 0);

const observer = new MutationObserver(function(mutations) {
    document.querySelectorAll('img[src^="https://secure.gravatar.com"]').forEach((img) => {
        const parent = img.parentElement;
        const initials = img.alt.split(' ').map(s=>s[0]).join('');
        parent.textContent = initials;
    })
})
observer.observe(document, { childList: true, subtree: true });

Before:
image
After:
image

Surely it would be much better if we could just use css without javascript. However, :has() pseudo-class is still can not be used within stylesheets but only with functions like document.querySelector().

And the MutationObserver used here is much faster than the conventional DOMNodeInserted event. Just a reminder, in real life, a proper debounce to the callback is much appropriate here!


Update:

Just saw a brilliant way to detect DOM Node Insertion without using MutationObserver: Detect DOM Node Insertions with JavaScript and CSS Animations. So I updated the script as this:

let insertionObserver = function(selector, callback) {
  const styleEl = document.createElement('style');
  document.head.appendChild(styleEl);
  const KeyframeName = 'insertionObserver';
  const keyframesRule = `@keyframes ${KeyframeName} { from { opacity: 0.99; } to { opacity: 1; } }`;
  const styleRule = `${selector} { animation-duration: 0.001s; animation-name: ${KeyframeName}; }`;

  styleEl.sheet.insertRule(keyframesRule);
  styleEl.sheet.insertRule(styleRule);

  document.addEventListener('animationstart', (event) => {
    if (event.animationName === KeyframeName) {
      callback(event);
    }
  }, false);
}

insertionObserver('.aui-avatar-inner img[src^="https://secure.gravatar.com"]', (event) => {
  let img = event.target;
  const parent = img.parentElement;
  const initials = img.alt.split(' ').map(s=>s[0]).join('');
  const height = getComputedStyle(parent).height;
  parent.setAttribute("style", `background-color: lightgray; color: white; line-height: ${height}`);
  parent.textContent = initials;
});

Maybe it's time to create a repo to for these little helper functions, as my arsenal..

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions