Ignore:
Timestamp:
11/25/21 22:08:24 (3 years ago)
Author:
Ema <ema_spirova@…>
Branches:
master
Children:
8d391a1
Parents:
59329aa
Message:

primeNG components

Location:
trip-planner-front/node_modules/svgo/plugins
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trip-planner-front/node_modules/svgo/plugins/inlineStyles.js

    r59329aa re29cc2e  
    11'use strict';
    22
     3/**
     4 * @typedef {import('../lib/types').Specificity} Specificity
     5 * @typedef {import('../lib/types').XastElement} XastElement
     6 * @typedef {import('../lib/types').XastParent} XastParent
     7 */
     8
    39const csstree = require('css-tree');
    4 const { querySelectorAll, closestByName } = require('../lib/xast.js');
    5 const cssTools = require('../lib/css-tools');
    6 
     10// @ts-ignore not defined in @types/csso
     11const specificity = require('csso/lib/restructure/prepare/specificity');
     12const stable = require('stable');
     13const {
     14  visitSkip,
     15  querySelectorAll,
     16  detachNodeFromParent,
     17} = require('../lib/xast.js');
     18
     19exports.type = 'visitor';
    720exports.name = 'inlineStyles';
    8 
    9 exports.type = 'full';
    10 
    1121exports.active = true;
    12 
    13 exports.params = {
    14   onlyMatchedOnce: true,
    15   removeMatchedSelectors: true,
    16   useMqs: ['', 'screen'],
    17   usePseudos: [''],
     22exports.description = 'inline styles (additional options)';
     23
     24/**
     25 * Compares two selector specificities.
     26 * extracted from https://github.com/keeganstreet/specificity/blob/master/specificity.js#L211
     27 *
     28 * @type {(a: Specificity, b: Specificity) => number}
     29 */
     30const compareSpecificity = (a, b) => {
     31  for (var i = 0; i < 4; i += 1) {
     32    if (a[i] < b[i]) {
     33      return -1;
     34    } else if (a[i] > b[i]) {
     35      return 1;
     36    }
     37  }
     38  return 0;
    1839};
    19 
    20 exports.description = 'inline styles (additional options)';
    2140
    2241/**
     
    3958 *     empty string element for all non-pseudo-classes and/or -elements
    4059 *
    41  * @param {Object} root document element
    42  * @param {Object} opts plugin params
    43  *
    4460 * @author strarsis <strarsis@gmail.com>
     61 *
     62 * @type {import('../lib/types').Plugin<{
     63 *   onlyMatchedOnce?: boolean,
     64 *   removeMatchedSelectors?: boolean,
     65 *   useMqs?: Array<string>,
     66 *   usePseudos?: Array<string>
     67 * }>}
    4568 */
    46 exports.fn = function (root, opts) {
    47   // collect <style/>s
    48   var styleEls = querySelectorAll(root, 'style');
    49 
    50   //no <styles/>s, nothing to do
    51   if (styleEls.length === 0) {
    52     return root;
    53   }
    54 
    55   var styles = [],
    56     selectors = [];
    57 
    58   for (var styleEl of styleEls) {
    59     // values other than the empty string or text/css are not used
    60     if (
    61       styleEl.attributes.type != null &&
    62       styleEl.attributes.type !== '' &&
    63       styleEl.attributes.type !== 'text/css'
    64     ) {
    65       continue;
    66     }
    67     // skip empty <style/>s or <foreignObject> content.
    68     if (
    69       styleEl.children.length === 0 ||
    70       closestByName(styleEl, 'foreignObject')
    71     ) {
    72       continue;
    73     }
    74 
    75     var cssStr = cssTools.getCssStr(styleEl);
    76 
    77     // collect <style/>s and their css ast
    78     var cssAst = {};
    79     try {
    80       cssAst = csstree.parse(cssStr, {
    81         parseValue: false,
    82         parseCustomProperty: false,
    83       });
    84     } catch (parseError) {
    85       // console.warn('Warning: Parse error of styles of <style/> element, skipped. Error details: ' + parseError);
    86       continue;
    87     }
    88 
    89     styles.push({
    90       styleEl: styleEl,
    91       cssAst: cssAst,
    92     });
    93 
    94     selectors = selectors.concat(cssTools.flattenToSelectors(cssAst));
    95   }
    96 
    97   // filter for mediaqueries to be used or without any mediaquery
    98   var selectorsMq = cssTools.filterByMqs(selectors, opts.useMqs);
    99 
    100   // filter for pseudo elements to be used
    101   var selectorsPseudo = cssTools.filterByPseudos(selectorsMq, opts.usePseudos);
    102 
    103   // remove PseudoClass from its SimpleSelector for proper matching
    104   cssTools.cleanPseudos(selectorsPseudo);
    105 
    106   // stable sort selectors
    107   var sortedSelectors = cssTools.sortSelectors(selectorsPseudo).reverse();
    108 
    109   var selector, selectedEl;
    110 
    111   // match selectors
    112   for (selector of sortedSelectors) {
    113     var selectorStr = csstree.generate(selector.item.data),
    114       selectedEls = null;
    115 
    116     try {
    117       selectedEls = querySelectorAll(root, selectorStr);
    118     } catch (selectError) {
    119       // console.warn('Warning: Syntax error when trying to select \n\n' + selectorStr + '\n\n, skipped. Error details: ' + selectError);
    120       continue;
    121     }
    122 
    123     if (selectedEls.length === 0) {
    124       // nothing selected
    125       continue;
    126     }
    127 
    128     selector.selectedEls = selectedEls;
    129   }
    130 
    131   // apply <style/> styles to matched elements
    132   for (selector of sortedSelectors) {
    133     if (!selector.selectedEls) {
    134       continue;
    135     }
    136 
    137     if (
    138       opts.onlyMatchedOnce &&
    139       selector.selectedEls !== null &&
    140       selector.selectedEls.length > 1
    141     ) {
    142       // skip selectors that match more than once if option onlyMatchedOnce is enabled
    143       continue;
    144     }
    145 
    146     // apply <style/> to matched elements
    147     for (selectedEl of selector.selectedEls) {
    148       if (selector.rule === null) {
    149         continue;
    150       }
    151       const styleDeclarationList = csstree.parse(
    152         selectedEl.attributes.style == null ? '' : selectedEl.attributes.style,
    153         {
    154           context: 'declarationList',
    155           parseValue: false,
    156         }
    157       );
    158       const styleDeclarationItems = new Map();
    159       csstree.walk(styleDeclarationList, {
    160         visit: 'Declaration',
    161         enter(node, item) {
    162           styleDeclarationItems.set(node.property, item);
    163         },
    164       });
    165       // merge declarations
    166       csstree.walk(selector.rule, {
    167         visit: 'Declaration',
    168         enter(ruleDeclaration) {
    169           // existing inline styles have higher priority
    170           // no inline styles, external styles,                                    external styles used
    171           // inline styles,    external styles same   priority as inline styles,   inline   styles used
    172           // inline styles,    external styles higher priority than inline styles, external styles used
    173           const matchedItem = styleDeclarationItems.get(
    174             ruleDeclaration.property
    175           );
    176           const ruleDeclarationItem =
    177             styleDeclarationList.children.createItem(ruleDeclaration);
    178           if (matchedItem == null) {
    179             styleDeclarationList.children.append(ruleDeclarationItem);
    180           } else if (
    181             matchedItem.data.important !== true &&
    182             ruleDeclaration.important === true
     69exports.fn = (root, params) => {
     70  const {
     71    onlyMatchedOnce = true,
     72    removeMatchedSelectors = true,
     73    useMqs = ['', 'screen'],
     74    usePseudos = [''],
     75  } = params;
     76
     77  /**
     78   * @type {Array<{ node: XastElement, parentNode: XastParent, cssAst: csstree.StyleSheet }>}
     79   */
     80  const styles = [];
     81  /**
     82   * @type {Array<{
     83   *   node: csstree.Selector,
     84   *   item: csstree.ListItem<csstree.CssNode>,
     85   *   rule: csstree.Rule,
     86   *   matchedElements?: Array<XastElement>
     87   * }>}
     88   */
     89  let selectors = [];
     90
     91  return {
     92    element: {
     93      enter: (node, parentNode) => {
     94        // skip <foreignObject /> content
     95        if (node.name === 'foreignObject') {
     96          return visitSkip;
     97        }
     98        // collect only non-empty <style /> elements
     99        if (node.name !== 'style' || node.children.length === 0) {
     100          return;
     101        }
     102        // values other than the empty string or text/css are not used
     103        if (
     104          node.attributes.type != null &&
     105          node.attributes.type !== '' &&
     106          node.attributes.type !== 'text/css'
     107        ) {
     108          return;
     109        }
     110        // parse css in style element
     111        let cssText = '';
     112        for (const child of node.children) {
     113          if (child.type === 'text' || child.type === 'cdata') {
     114            cssText += child.value;
     115          }
     116        }
     117        /**
     118         * @type {null | csstree.CssNode}
     119         */
     120        let cssAst = null;
     121        try {
     122          cssAst = csstree.parse(cssText, {
     123            parseValue: false,
     124            parseCustomProperty: false,
     125          });
     126        } catch {
     127          return;
     128        }
     129        if (cssAst.type === 'StyleSheet') {
     130          styles.push({ node, parentNode, cssAst });
     131        }
     132
     133        // collect selectors
     134        csstree.walk(cssAst, {
     135          visit: 'Selector',
     136          enter(node, item) {
     137            const atrule = this.atrule;
     138            const rule = this.rule;
     139            if (rule == null) {
     140              return;
     141            }
     142
     143            // skip media queries not included into useMqs param
     144            let mq = '';
     145            if (atrule != null) {
     146              mq = atrule.name;
     147              if (atrule.prelude != null) {
     148                mq += ` ${csstree.generate(atrule.prelude)}`;
     149              }
     150            }
     151            if (useMqs.includes(mq) === false) {
     152              return;
     153            }
     154
     155            /**
     156             * @type {Array<{
     157             *   item: csstree.ListItem<csstree.CssNode>,
     158             *   list: csstree.List<csstree.CssNode>
     159             * }>}
     160             */
     161            const pseudos = [];
     162            if (node.type === 'Selector') {
     163              node.children.each((childNode, childItem, childList) => {
     164                if (
     165                  childNode.type === 'PseudoClassSelector' ||
     166                  childNode.type === 'PseudoElementSelector'
     167                ) {
     168                  pseudos.push({ item: childItem, list: childList });
     169                }
     170              });
     171            }
     172
     173            // skip pseudo classes and pseudo elements not includes into usePseudos param
     174            const pseudoSelectors = csstree.generate({
     175              type: 'Selector',
     176              children: new csstree.List().fromArray(
     177                pseudos.map((pseudo) => pseudo.item.data)
     178              ),
     179            });
     180            if (usePseudos.includes(pseudoSelectors) === false) {
     181              return;
     182            }
     183
     184            // remove pseudo classes and elements to allow querySelector match elements
     185            // TODO this is not very accurate since some pseudo classes like first-child
     186            // are used for selection
     187            for (const pseudo of pseudos) {
     188              pseudo.list.remove(pseudo.item);
     189            }
     190
     191            selectors.push({ node, item, rule });
     192          },
     193        });
     194      },
     195    },
     196
     197    root: {
     198      exit: () => {
     199        if (styles.length === 0) {
     200          return;
     201        }
     202        // stable sort selectors
     203        const sortedSelectors = stable(selectors, (a, b) => {
     204          const aSpecificity = specificity(a.item.data);
     205          const bSpecificity = specificity(b.item.data);
     206          return compareSpecificity(aSpecificity, bSpecificity);
     207        }).reverse();
     208
     209        for (const selector of sortedSelectors) {
     210          // match selectors
     211          const selectorText = csstree.generate(selector.item.data);
     212          /**
     213           * @type {Array<XastElement>}
     214           */
     215          const matchedElements = [];
     216          try {
     217            for (const node of querySelectorAll(root, selectorText)) {
     218              if (node.type === 'element') {
     219                matchedElements.push(node);
     220              }
     221            }
     222          } catch (selectError) {
     223            continue;
     224          }
     225          // nothing selected
     226          if (matchedElements.length === 0) {
     227            continue;
     228          }
     229
     230          // apply styles to matched elements
     231          // skip selectors that match more than once if option onlyMatchedOnce is enabled
     232          if (onlyMatchedOnce && matchedElements.length > 1) {
     233            continue;
     234          }
     235
     236          // apply <style/> to matched elements
     237          for (const selectedEl of matchedElements) {
     238            const styleDeclarationList = csstree.parse(
     239              selectedEl.attributes.style == null
     240                ? ''
     241                : selectedEl.attributes.style,
     242              {
     243                context: 'declarationList',
     244                parseValue: false,
     245              }
     246            );
     247            if (styleDeclarationList.type !== 'DeclarationList') {
     248              continue;
     249            }
     250            const styleDeclarationItems = new Map();
     251            csstree.walk(styleDeclarationList, {
     252              visit: 'Declaration',
     253              enter(node, item) {
     254                styleDeclarationItems.set(node.property, item);
     255              },
     256            });
     257            // merge declarations
     258            csstree.walk(selector.rule, {
     259              visit: 'Declaration',
     260              enter(ruleDeclaration) {
     261                // existing inline styles have higher priority
     262                // no inline styles, external styles,                                    external styles used
     263                // inline styles,    external styles same   priority as inline styles,   inline   styles used
     264                // inline styles,    external styles higher priority than inline styles, external styles used
     265                const matchedItem = styleDeclarationItems.get(
     266                  ruleDeclaration.property
     267                );
     268                const ruleDeclarationItem =
     269                  styleDeclarationList.children.createItem(ruleDeclaration);
     270                if (matchedItem == null) {
     271                  styleDeclarationList.children.append(ruleDeclarationItem);
     272                } else if (
     273                  matchedItem.data.important !== true &&
     274                  ruleDeclaration.important === true
     275                ) {
     276                  styleDeclarationList.children.replace(
     277                    matchedItem,
     278                    ruleDeclarationItem
     279                  );
     280                  styleDeclarationItems.set(
     281                    ruleDeclaration.property,
     282                    ruleDeclarationItem
     283                  );
     284                }
     285              },
     286            });
     287            selectedEl.attributes.style =
     288              csstree.generate(styleDeclarationList);
     289          }
     290
     291          if (
     292            removeMatchedSelectors &&
     293            matchedElements.length !== 0 &&
     294            selector.rule.prelude.type === 'SelectorList'
    183295          ) {
    184             styleDeclarationList.children.replace(
    185               matchedItem,
    186               ruleDeclarationItem
     296            // clean up matching simple selectors if option removeMatchedSelectors is enabled
     297            selector.rule.prelude.children.remove(selector.item);
     298          }
     299          selector.matchedElements = matchedElements;
     300        }
     301
     302        // no further processing required
     303        if (removeMatchedSelectors === false) {
     304          return;
     305        }
     306
     307        // clean up matched class + ID attribute values
     308        for (const selector of sortedSelectors) {
     309          if (selector.matchedElements == null) {
     310            continue;
     311          }
     312
     313          if (onlyMatchedOnce && selector.matchedElements.length > 1) {
     314            // skip selectors that match more than once if option onlyMatchedOnce is enabled
     315            continue;
     316          }
     317
     318          for (const selectedEl of selector.matchedElements) {
     319            // class
     320            const classList = new Set(
     321              selectedEl.attributes.class == null
     322                ? null
     323                : selectedEl.attributes.class.split(' ')
    187324            );
    188             styleDeclarationItems.set(
    189               ruleDeclaration.property,
    190               ruleDeclarationItem
    191             );
    192           }
    193         },
    194       });
    195       selectedEl.attributes.style = csstree.generate(styleDeclarationList);
    196     }
    197 
    198     if (
    199       opts.removeMatchedSelectors &&
    200       selector.selectedEls !== null &&
    201       selector.selectedEls.length > 0
    202     ) {
    203       // clean up matching simple selectors if option removeMatchedSelectors is enabled
    204       selector.rule.prelude.children.remove(selector.item);
    205     }
    206   }
    207 
    208   if (!opts.removeMatchedSelectors) {
    209     return root; // no further processing required
    210   }
    211 
    212   // clean up matched class + ID attribute values
    213   for (selector of sortedSelectors) {
    214     if (!selector.selectedEls) {
    215       continue;
    216     }
    217 
    218     if (
    219       opts.onlyMatchedOnce &&
    220       selector.selectedEls !== null &&
    221       selector.selectedEls.length > 1
    222     ) {
    223       // skip selectors that match more than once if option onlyMatchedOnce is enabled
    224       continue;
    225     }
    226 
    227     for (selectedEl of selector.selectedEls) {
    228       // class
    229       const classList = new Set(
    230         selectedEl.attributes.class == null
    231           ? null
    232           : selectedEl.attributes.class.split(' ')
    233       );
    234       const firstSubSelector = selector.item.data.children.first();
    235       if (firstSubSelector.type === 'ClassSelector') {
    236         classList.delete(firstSubSelector.name);
    237       }
    238       if (classList.size === 0) {
    239         delete selectedEl.attributes.class;
    240       } else {
    241         selectedEl.attributes.class = Array.from(classList).join(' ');
    242       }
    243 
    244       // ID
    245       if (firstSubSelector.type === 'IdSelector') {
    246         if (selectedEl.attributes.id === firstSubSelector.name) {
    247           delete selectedEl.attributes.id;
    248         }
    249       }
    250     }
    251   }
    252 
    253   // clean up now empty elements
    254   for (var style of styles) {
    255     csstree.walk(style.cssAst, {
    256       visit: 'Rule',
    257       enter: function (node, item, list) {
    258         // clean up <style/> atrules without any rulesets left
    259         if (
    260           node.type === 'Atrule' &&
    261           // only Atrules containing rulesets
    262           node.block !== null &&
    263           node.block.children.isEmpty()
    264         ) {
    265           list.remove(item);
    266           return;
    267         }
    268 
    269         // clean up <style/> rulesets without any css selectors left
    270         if (node.type === 'Rule' && node.prelude.children.isEmpty()) {
    271           list.remove(item);
     325            const firstSubSelector = selector.node.children.first();
     326            if (
     327              firstSubSelector != null &&
     328              firstSubSelector.type === 'ClassSelector'
     329            ) {
     330              classList.delete(firstSubSelector.name);
     331            }
     332            if (classList.size === 0) {
     333              delete selectedEl.attributes.class;
     334            } else {
     335              selectedEl.attributes.class = Array.from(classList).join(' ');
     336            }
     337
     338            // ID
     339            if (
     340              firstSubSelector != null &&
     341              firstSubSelector.type === 'IdSelector'
     342            ) {
     343              if (selectedEl.attributes.id === firstSubSelector.name) {
     344                delete selectedEl.attributes.id;
     345              }
     346            }
     347          }
     348        }
     349
     350        for (const style of styles) {
     351          csstree.walk(style.cssAst, {
     352            visit: 'Rule',
     353            enter: function (node, item, list) {
     354              // clean up <style/> rulesets without any css selectors left
     355              if (
     356                node.type === 'Rule' &&
     357                node.prelude.type === 'SelectorList' &&
     358                node.prelude.children.isEmpty()
     359              ) {
     360                list.remove(item);
     361              }
     362            },
     363          });
     364
     365          if (style.cssAst.children.isEmpty()) {
     366            // remove emtpy style element
     367            detachNodeFromParent(style.node, style.parentNode);
     368          } else {
     369            // update style element if any styles left
     370            const firstChild = style.node.children[0];
     371            if (firstChild.type === 'text' || firstChild.type === 'cdata') {
     372              firstChild.value = csstree.generate(style.cssAst);
     373            }
     374          }
    272375        }
    273376      },
    274     });
    275 
    276     if (style.cssAst.children.isEmpty()) {
    277       // clean up now emtpy <style/>s
    278       var styleParentEl = style.styleEl.parentNode;
    279       styleParentEl.spliceContent(
    280         styleParentEl.children.indexOf(style.styleEl),
    281         1
    282       );
    283 
    284       if (
    285         styleParentEl.name === 'defs' &&
    286         styleParentEl.children.length === 0
    287       ) {
    288         // also clean up now empty <def/>s
    289         var defsParentEl = styleParentEl.parentNode;
    290         defsParentEl.spliceContent(
    291           defsParentEl.children.indexOf(styleParentEl),
    292           1
    293         );
    294       }
    295 
    296       continue;
    297     }
    298 
    299     // update existing, left over <style>s
    300     cssTools.setCssStr(style.styleEl, csstree.generate(style.cssAst));
    301   }
    302 
    303   return root;
     377    },
     378  };
    304379};
  • trip-planner-front/node_modules/svgo/plugins/prefixIds.js

    r59329aa re29cc2e  
    207207            node.attributes[name].length !== 0
    208208          ) {
    209             // extract id reference from url(...) value
    210             const matches = /url\((.*?)\)/gi.exec(node.attributes[name]);
    211             if (matches != null) {
    212               const value = matches[1];
    213               const prefixed = prefixReference(prefix, value);
    214               if (prefixed != null) {
    215                 node.attributes[name] = `url(${prefixed})`;
     209            node.attributes[name] = node.attributes[name].replace(
     210              /url\((.*?)\)/gi,
     211              (match, url) => {
     212                const prefixed = prefixReference(prefix, url);
     213                if (prefixed == null) {
     214                  return match;
     215                }
     216                return `url(${prefixed})`;
    216217              }
    217             }
     218            );
    218219          }
    219220        }
  • trip-planner-front/node_modules/svgo/plugins/removeEmptyAttrs.js

    r59329aa re29cc2e  
    33const { attrsGroups } = require('./_collections.js');
    44
     5exports.type = 'visitor';
    56exports.name = 'removeEmptyAttrs';
    6 
    7 exports.type = 'perItem';
    8 
    97exports.active = true;
    10 
    118exports.description = 'removes empty attributes';
    129
     
    1411 * Remove attributes with empty values.
    1512 *
    16  * @param {Object} item current iteration item
    17  * @return {Boolean} if false, item will be filtered out
     13 * @author Kir Belevich
    1814 *
    19  * @author Kir Belevich
     15 * @type {import('../lib/types').Plugin<void>}
    2016 */
    21 exports.fn = function (item) {
    22   if (item.type === 'element') {
    23     for (const [name, value] of Object.entries(item.attributes)) {
    24       if (
    25         value === '' &&
    26         // empty conditional processing attributes prevents elements from rendering
    27         attrsGroups.conditionalProcessing.includes(name) === false
    28       ) {
    29         delete item.attributes[name];
    30       }
    31     }
    32   }
     17exports.fn = () => {
     18  return {
     19    element: {
     20      enter: (node) => {
     21        for (const [name, value] of Object.entries(node.attributes)) {
     22          if (
     23            value === '' &&
     24            // empty conditional processing attributes prevents elements from rendering
     25            attrsGroups.conditionalProcessing.includes(name) === false
     26          ) {
     27            delete node.attributes[name];
     28          }
     29        }
     30      },
     31    },
     32  };
    3333};
  • trip-planner-front/node_modules/svgo/plugins/removeXMLNS.js

    r59329aa re29cc2e  
    2626  if (item.type === 'element' && item.name === 'svg') {
    2727    delete item.attributes.xmlns;
     28    delete item.attributes['xmlns:xlink'];
    2829  }
    2930};
Note: See TracChangeset for help on using the changeset viewer.