Add packages to optimize svgs dynamically

These packages will be used to dynamically optimize SVG images
during the build.

R=jacktfranklin@chromium.org

Bug: 1216402
Change-Id: I04e95aa7d79c9d67beaf8a7861182c52b16b7d0f
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2939992
Reviewed-by: Jack Franklin <jacktfranklin@chromium.org>
Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org>
diff --git a/node_modules/css-tree/lib/walker/create.js b/node_modules/css-tree/lib/walker/create.js
new file mode 100644
index 0000000..1731465
--- /dev/null
+++ b/node_modules/css-tree/lib/walker/create.js
@@ -0,0 +1,284 @@
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+var noop = function() {};
+
+function ensureFunction(value) {
+    return typeof value === 'function' ? value : noop;
+}
+
+function invokeForType(fn, type) {
+    return function(node, item, list) {
+        if (node.type === type) {
+            fn.call(this, node, item, list);
+        }
+    };
+}
+
+function getWalkersFromStructure(name, nodeType) {
+    var structure = nodeType.structure;
+    var walkers = [];
+
+    for (var key in structure) {
+        if (hasOwnProperty.call(structure, key) === false) {
+            continue;
+        }
+
+        var fieldTypes = structure[key];
+        var walker = {
+            name: key,
+            type: false,
+            nullable: false
+        };
+
+        if (!Array.isArray(structure[key])) {
+            fieldTypes = [structure[key]];
+        }
+
+        for (var i = 0; i < fieldTypes.length; i++) {
+            var fieldType = fieldTypes[i];
+            if (fieldType === null) {
+                walker.nullable = true;
+            } else if (typeof fieldType === 'string') {
+                walker.type = 'node';
+            } else if (Array.isArray(fieldType)) {
+                walker.type = 'list';
+            }
+        }
+
+        if (walker.type) {
+            walkers.push(walker);
+        }
+    }
+
+    if (walkers.length) {
+        return {
+            context: nodeType.walkContext,
+            fields: walkers
+        };
+    }
+
+    return null;
+}
+
+function getTypesFromConfig(config) {
+    var types = {};
+
+    for (var name in config.node) {
+        if (hasOwnProperty.call(config.node, name)) {
+            var nodeType = config.node[name];
+
+            if (!nodeType.structure) {
+                throw new Error('Missed `structure` field in `' + name + '` node type definition');
+            }
+
+            types[name] = getWalkersFromStructure(name, nodeType);
+        }
+    }
+
+    return types;
+}
+
+function createTypeIterator(config, reverse) {
+    var fields = config.fields.slice();
+    var contextName = config.context;
+    var useContext = typeof contextName === 'string';
+
+    if (reverse) {
+        fields.reverse();
+    }
+
+    return function(node, context, walk, walkReducer) {
+        var prevContextValue;
+
+        if (useContext) {
+            prevContextValue = context[contextName];
+            context[contextName] = node;
+        }
+
+        for (var i = 0; i < fields.length; i++) {
+            var field = fields[i];
+            var ref = node[field.name];
+
+            if (!field.nullable || ref) {
+                if (field.type === 'list') {
+                    var breakWalk = reverse
+                        ? ref.reduceRight(walkReducer, false)
+                        : ref.reduce(walkReducer, false);
+
+                    if (breakWalk) {
+                        return true;
+                    }
+                } else if (walk(ref)) {
+                    return true;
+                }
+            }
+        }
+
+        if (useContext) {
+            context[contextName] = prevContextValue;
+        }
+    };
+}
+
+function createFastTraveralMap(iterators) {
+    return {
+        Atrule: {
+            StyleSheet: iterators.StyleSheet,
+            Atrule: iterators.Atrule,
+            Rule: iterators.Rule,
+            Block: iterators.Block
+        },
+        Rule: {
+            StyleSheet: iterators.StyleSheet,
+            Atrule: iterators.Atrule,
+            Rule: iterators.Rule,
+            Block: iterators.Block
+        },
+        Declaration: {
+            StyleSheet: iterators.StyleSheet,
+            Atrule: iterators.Atrule,
+            Rule: iterators.Rule,
+            Block: iterators.Block,
+            DeclarationList: iterators.DeclarationList
+        }
+    };
+}
+
+module.exports = function createWalker(config) {
+    var types = getTypesFromConfig(config);
+    var iteratorsNatural = {};
+    var iteratorsReverse = {};
+    var breakWalk = Symbol('break-walk');
+    var skipNode = Symbol('skip-node');
+
+    for (var name in types) {
+        if (hasOwnProperty.call(types, name) && types[name] !== null) {
+            iteratorsNatural[name] = createTypeIterator(types[name], false);
+            iteratorsReverse[name] = createTypeIterator(types[name], true);
+        }
+    }
+
+    var fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
+    var fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
+
+    var walk = function(root, options) {
+        function walkNode(node, item, list) {
+            var enterRet = enter.call(context, node, item, list);
+
+            if (enterRet === breakWalk) {
+                debugger;
+                return true;
+            }
+
+            if (enterRet === skipNode) {
+                return false;
+            }
+
+            if (iterators.hasOwnProperty(node.type)) {
+                if (iterators[node.type](node, context, walkNode, walkReducer)) {
+                    return true;
+                }
+            }
+
+            if (leave.call(context, node, item, list) === breakWalk) {
+                return true;
+            }
+
+            return false;
+        }
+
+        var walkReducer = (ret, data, item, list) => ret || walkNode(data, item, list);
+        var enter = noop;
+        var leave = noop;
+        var iterators = iteratorsNatural;
+        var context = {
+            break: breakWalk,
+            skip: skipNode,
+
+            root: root,
+            stylesheet: null,
+            atrule: null,
+            atrulePrelude: null,
+            rule: null,
+            selector: null,
+            block: null,
+            declaration: null,
+            function: null
+        };
+
+        if (typeof options === 'function') {
+            enter = options;
+        } else if (options) {
+            enter = ensureFunction(options.enter);
+            leave = ensureFunction(options.leave);
+
+            if (options.reverse) {
+                iterators = iteratorsReverse;
+            }
+
+            if (options.visit) {
+                if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
+                    iterators = options.reverse
+                        ? fastTraversalIteratorsReverse[options.visit]
+                        : fastTraversalIteratorsNatural[options.visit];
+                } else if (!types.hasOwnProperty(options.visit)) {
+                    throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).join(', ') + ')');
+                }
+
+                enter = invokeForType(enter, options.visit);
+                leave = invokeForType(leave, options.visit);
+            }
+        }
+
+        if (enter === noop && leave === noop) {
+            throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
+        }
+
+        walkNode(root);
+    };
+
+    walk.break = breakWalk;
+    walk.skip = skipNode;
+
+    walk.find = function(ast, fn) {
+        var found = null;
+
+        walk(ast, function(node, item, list) {
+            if (fn.call(this, node, item, list)) {
+                found = node;
+                return breakWalk;
+            }
+        });
+
+        return found;
+    };
+
+    walk.findLast = function(ast, fn) {
+        var found = null;
+
+        walk(ast, {
+            reverse: true,
+            enter: function(node, item, list) {
+                if (fn.call(this, node, item, list)) {
+                    found = node;
+                    return breakWalk;
+                }
+            }
+        });
+
+        return found;
+    };
+
+    walk.findAll = function(ast, fn) {
+        var found = [];
+
+        walk(ast, function(node, item, list) {
+            if (fn.call(this, node, item, list)) {
+                found.push(node);
+            }
+        });
+
+        return found;
+    };
+
+    return walk;
+};