Mutant $tyle $heets from $paaaaaaaace

http://github.com/trifacta/mutantsss

aka → $$$

Motivation

Spreadsheet Resizing

Doing this with HTML/CSS is Easy

Doing this with HTML/CSS is Easy

Doing this quickly with HTML/CSS is Hard™

Problem

"Multi-class addressing"


...
...
...
...
...

Chicken, meet egg (ಠ_ಠ)


...
.row-23    {  top: 230px; height: 32px; } /* ??? */
...
.column-42 { left: 420px;  width: 24px; } /* ??? */
...
          

Naive


// O(#rows)
for (var i = 0; i < NUM_ROWS; i++) {
  ...

  // O(#columns)
  cells.querySelectorAll('.cell.row-' + i)
      .forEach(function(cell) {
        cell.style.top = offset + 'px';
        cell.style.height = height + 'px';
      });
}
                    
 → 

...
...
...
...
...
O(n2)

...even with D3


// O(#rows)
for (var i = 0; i < NUM_ROWS; i++) {
  ...

  // O(#columns)
  d3.selectAll('.cell.row-' + i).style({
    'top': function(d, i) {
      return offset + 'px';
    },
    'height': function(d, i) {
      return height + 'px';
    }
  });
}
                    
 → 

...
...
...
...
...

$$$


var $$$ = require('mutantsss'),
    $$$cope = $$$(cells);
                    
 → 


...
...

// O(#rows)
for (var i = 0; i < NUM_ROWS; i++) {
  ...
        
  // O(1)
  $$$cope.select('.cell.row-' + i).style({
    top: offset + 'px',
    height: height + 'px'
  });
}
                    
 → 

[data-mutantsss-root="1"] .cell.row-0 {
  top: 0px;
  height: 10px;
}
...
[data-mutantsss-root="1"] .cell.row-99 {
  top: 1000px;
  height: 14px;
}
                    
O(n)

But...how?


var newStyles = document.createElement('style');
document.head.appendChild(newStyles);
            


newStyles.sheet.deleteRule(...);
newStyles.sheet.insertRule(...);
            

≈ 2,000% Speedup!

Naive

≈140ms
Naive Time
        

$$$

≈7ms
Clever Time

(Demo)

GitHub

npm install mutantsss

Fin.