Skip to content

Instantly share code, notes, and snippets.

@omarstreak
Last active September 26, 2016 18:38
Show Gist options
  • Save omarstreak/9d2de91fdbcb758f98e6f842e4b729e1 to your computer and use it in GitHub Desktop.
Save omarstreak/9d2de91fdbcb758f98e6f842e4b729e1 to your computer and use it in GitHub Desktop.
/*
To inject a button into composes there's 5 main strategies an extension developer can use, each strategy has large tradeoffs
mainly around performance and ease of implementation. The result is that most extension developers opt for the
easy to implement but poor performing strategy.
*/
/*
Strategy 1
DOMInsertionNode
Pros:
- Relatively easy to implement
- Responsive (no popping when making modifications to new composes)
Cons:
- MASSIVE performance degredation
method used by popular gmail.js library
*/
document.addEventListener('DOMNodeInserted', function(e){
if(elementMatchesCompose(e.target)){
broadcastCompose(e.target);
}
});
// ========================
/*
Strategy 2
Global Mutation Observer
Similar to DOMInsertionNode
Pros:
- Responsive
- Easy to implement
Cons:
- Very bad performance
*/
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if(doesMutationMatchCompose(mutation)){
var compose = getComposeFromMutation(mutation);
broadcastCompose(compose);
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
// ========================
/*
Strategy 3
Timer
Pros:
- Relatively easy to implement
Cons:
- Can be buggy because have to keep track of what composes have been seen and not
- Horrible performance
- Not responsive. Compose will come up, and then timer will fire so you'll see "popping"
*/
setInterval(function(){
var composes = document.querySelectorAll(COMPOSE_SELECTOR);
for(compose in composes){
if(haveNotSeenComposeBefore(compose)){
broadcastCompose(compose);
}
}
}, 100);
// ========================
/*
Strategy 4
CSS Animation Detection
(http://developer.streak.com/2012/11/how-to-detect-dom-changes-in-css.html)
Pros:
- Responsive
Cons:
- Technique is not well known
- Implementation is sufficiently difficult that most extension developers don't do it
and easy to generate a buggy result
For implementation refer to above blog post
*/
// ========================
/*
Strategy 5
Chained mutation observers
Pros:
- Responsive
- Little performance overhead
Cons:
- Hard to implement
- have to deal with a lot of cases (standalone compose, inline replies, preview pane, toggling between fullscreen compose, etc)
This is what the InboxSDK does, and does it very well. Implementation is too involved to
show in a small snippet
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment