Advertisement
jordangray

Get all document pseudo-elements: a comparison

Dec 4th, 2013
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function getPseudoElementSelectors() {
  2.     var matchPseudoSelector = /:{1,2}(after|before)/,
  3.         found = { before: [], after: [] };
  4.    
  5.     if (!(document.styleSheets && document.styleSheets.length)) return found;
  6.    
  7.     return Array.from(document.styleSheets)
  8.         .reduce(function(pseudoSelectors, sheet) {
  9.             try {
  10.                 if (!sheet.cssRules) return pseudoSelectors;
  11.                
  12.                 // Get an array of all individual selectors.
  13.                 var ruleSelectors = Array.from(sheet.cssRules)
  14.                     .reduce(function(selectors, rule) {
  15.                         return (rule && rule.selectorText)
  16.                             ? selectors.concat(rule.selectorText.split(','))
  17.                             : selectors;
  18.                     }, []);
  19.                
  20.                 // Construct a dictionary of rules with pseudo-elements.
  21.                 var rulePseudoSelectors = ruleSelectors.reduce(function(selectors, selector) {
  22.                    
  23.                     // Check if this selector has a pseudo-element.
  24.                     if (matchPseudoSelector.test(selector)) {
  25.                         var pseudoElement = matchPseudoSelector.exec(selector)[1],
  26.                             cleanSelector = selector.replace(matchPseudoSelector, '').trim();
  27.                        
  28.                         selectors[pseudoElement].push(cleanSelector);
  29.                     }
  30.                    
  31.                     return selectors;
  32.                 }, { before: [], after: [] });
  33.                
  34.                 pseudoSelectors.before = pseudoSelectors.before.concat(rulePseudoSelectors.before);
  35.                 pseudoSelectors.after = pseudoSelectors.after.concat(rulePseudoSelectors.after);
  36.            
  37.             // Quietly handle errors from accessing cross-origin stylesheets.
  38.             } catch (e) { if (console && console.warn) console.warn(e); }
  39.            
  40.             return pseudoSelectors;
  41.                        
  42.         }, found);
  43. }
  44.  
  45. function getPseudoElementsByCssSelectors() {
  46.     var selectors = getPseudoElementSelectors(),
  47.         names = ['before', 'after']
  48.    
  49.     return names.reduce(function(pseudoElements, name) {
  50.         if (!selectors[name].length) return pseudoElements;
  51.        
  52.         var selector = selectors[name].join(','),
  53.             elements = Array.from(document.querySelectorAll(selector));
  54.        
  55.         return pseudoElements.concat(
  56.             elements.reduce(function(withContent, el) {
  57.                 var pseudo = getComputedStyle(el, name);
  58.                
  59.                 // Add to array if element has content defined.
  60.                 return (pseudo.content.length)
  61.                     ? withContent.concat(pseudo)
  62.                     : withContent;
  63.             }, [])
  64.         );
  65.     }, []);
  66. }
  67.  
  68. Array.from = Array.from || function(arrayish) {
  69.     return [].slice.call(arrayish);
  70. };
  71.  
  72. function getPseudoElements() {
  73.         var allElements = document.getElementsByTagName("*"),
  74.                 pseudoElements = [];
  75.  
  76.         for (var i=0, max=allElements.length; i < max; i++) {
  77.                 var before = window.getComputedStyle(allElements[i], ':before');  
  78.                 var after = window.getComputedStyle(allElements[i], ':after');
  79.                 if (before.content) {
  80.                         pseudoElements.push(before);
  81.                 }
  82.                 if (after.content) {
  83.                         pseudoElements.push(after);
  84.                 }
  85.         }
  86.         return pseudoElements;
  87. }
  88.  
  89. console.time("getPseudoElementsByCssSelectors");
  90. for (var i = 0; i < 1000; i++) getPseudoElementsByCssSelectors(); console.timeEnd("getPseudoElementsByCssSelectors");
  91.  
  92. console.time("getPseudoElements");
  93. for (var i = 0; i < 1000; i++) getPseudoElements();
  94. console.timeEnd("getPseudoElements");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement