88 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| 
 | |
| Object.defineProperty(exports, "__esModule", {
 | |
|   value: true
 | |
| });
 | |
| exports.attributesWithLists = void 0;
 | |
| exports.default = collapseAttributeWhitespace;
 | |
| 
 | |
| var _helpers = require("../helpers");
 | |
| 
 | |
| const attributesWithLists = new Set(['class', 'dropzone', 'rel', // a, area, link
 | |
| 'ping', // a, area
 | |
| 'sandbox', // iframe
 | |
| 'sizes', // link
 | |
| 'headers' // td, th
 | |
| ]);
 | |
| /** @type Record<string, string[] | null> */
 | |
| 
 | |
| exports.attributesWithLists = attributesWithLists;
 | |
| const attributesWithSingleValue = {
 | |
|   accept: ['input'],
 | |
|   action: ['form'],
 | |
|   accesskey: null,
 | |
|   'accept-charset': ['form'],
 | |
|   cite: ['blockquote', 'del', 'ins', 'q'],
 | |
|   cols: ['textarea'],
 | |
|   colspan: ['td', 'th'],
 | |
|   data: ['object'],
 | |
|   dropzone: null,
 | |
|   formaction: ['button', 'input'],
 | |
|   height: ['canvas', 'embed', 'iframe', 'img', 'input', 'object', 'video'],
 | |
|   high: ['meter'],
 | |
|   href: ['a', 'area', 'base', 'link'],
 | |
|   itemid: null,
 | |
|   low: ['meter'],
 | |
|   manifest: ['html'],
 | |
|   max: ['meter', 'progress'],
 | |
|   maxlength: ['input', 'textarea'],
 | |
|   media: ['source'],
 | |
|   min: ['meter'],
 | |
|   minlength: ['input', 'textarea'],
 | |
|   optimum: ['meter'],
 | |
|   ping: ['a', 'area'],
 | |
|   poster: ['video'],
 | |
|   profile: ['head'],
 | |
|   rows: ['textarea'],
 | |
|   rowspan: ['td', 'th'],
 | |
|   size: ['input', 'select'],
 | |
|   span: ['col', 'colgroup'],
 | |
|   src: ['audio', 'embed', 'iframe', 'img', 'input', 'script', 'source', 'track', 'video'],
 | |
|   start: ['ol'],
 | |
|   step: ['input'],
 | |
|   style: null,
 | |
|   tabindex: null,
 | |
|   usemap: ['img', 'object'],
 | |
|   value: ['li', 'meter', 'progress'],
 | |
|   width: ['canvas', 'embed', 'iframe', 'img', 'input', 'object', 'video']
 | |
| };
 | |
| /** Collapse whitespaces inside list-like attributes (e.g. class, rel) */
 | |
| 
 | |
| function collapseAttributeWhitespace(tree) {
 | |
|   tree.walk(node => {
 | |
|     if (!node.attrs) {
 | |
|       return node;
 | |
|     }
 | |
| 
 | |
|     Object.entries(node.attrs).forEach(([attrName, attrValue]) => {
 | |
|       const attrNameLower = attrName.toLowerCase();
 | |
| 
 | |
|       if (attributesWithLists.has(attrNameLower)) {
 | |
|         const newAttrValue = attrValue.replace(/\s+/g, ' ').trim();
 | |
|         node.attrs[attrName] = newAttrValue;
 | |
|         return node;
 | |
|       }
 | |
| 
 | |
|       if ((0, _helpers.isEventHandler)(attrNameLower) || Object.hasOwnProperty.call(attributesWithSingleValue, attrNameLower) && (attributesWithSingleValue[attrNameLower] === null || attributesWithSingleValue[attrNameLower].includes(node.tag))) {
 | |
|         node.attrs[attrName] = minifySingleAttributeValue(attrValue);
 | |
|         return node;
 | |
|       }
 | |
|     });
 | |
|     return node;
 | |
|   });
 | |
|   return tree;
 | |
| }
 | |
| 
 | |
| function minifySingleAttributeValue(value) {
 | |
|   return typeof value === 'string' ? String(value).trim() : value;
 | |
| } | 
