style-to-js.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  3. typeof define === 'function' && define.amd ? define(factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.StyleToJS = factory());
  5. })(this, (function () { 'use strict';
  6. function getDefaultExportFromCjs (x) {
  7. return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
  8. }
  9. var cjs$2 = {};
  10. var cjs$1;
  11. var hasRequiredCjs$2;
  12. function requireCjs$2 () {
  13. if (hasRequiredCjs$2) return cjs$1;
  14. hasRequiredCjs$2 = 1;
  15. // http://www.w3.org/TR/CSS21/grammar.html
  16. // https://github.com/visionmedia/css-parse/pull/49#issuecomment-30088027
  17. var COMMENT_REGEX = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g;
  18. var NEWLINE_REGEX = /\n/g;
  19. var WHITESPACE_REGEX = /^\s*/;
  20. // declaration
  21. var PROPERTY_REGEX = /^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/;
  22. var COLON_REGEX = /^:\s*/;
  23. var VALUE_REGEX = /^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/;
  24. var SEMICOLON_REGEX = /^[;\s]*/;
  25. // https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
  26. var TRIM_REGEX = /^\s+|\s+$/g;
  27. // strings
  28. var NEWLINE = '\n';
  29. var FORWARD_SLASH = '/';
  30. var ASTERISK = '*';
  31. var EMPTY_STRING = '';
  32. // types
  33. var TYPE_COMMENT = 'comment';
  34. var TYPE_DECLARATION = 'declaration';
  35. /**
  36. * @param {String} style
  37. * @param {Object} [options]
  38. * @return {Object[]}
  39. * @throws {TypeError}
  40. * @throws {Error}
  41. */
  42. function index (style, options) {
  43. if (typeof style !== 'string') {
  44. throw new TypeError('First argument must be a string');
  45. }
  46. if (!style) return [];
  47. options = options || {};
  48. /**
  49. * Positional.
  50. */
  51. var lineno = 1;
  52. var column = 1;
  53. /**
  54. * Update lineno and column based on `str`.
  55. *
  56. * @param {String} str
  57. */
  58. function updatePosition(str) {
  59. var lines = str.match(NEWLINE_REGEX);
  60. if (lines) lineno += lines.length;
  61. var i = str.lastIndexOf(NEWLINE);
  62. column = ~i ? str.length - i : column + str.length;
  63. }
  64. /**
  65. * Mark position and patch `node.position`.
  66. *
  67. * @return {Function}
  68. */
  69. function position() {
  70. var start = { line: lineno, column: column };
  71. return function (node) {
  72. node.position = new Position(start);
  73. whitespace();
  74. return node;
  75. };
  76. }
  77. /**
  78. * Store position information for a node.
  79. *
  80. * @constructor
  81. * @property {Object} start
  82. * @property {Object} end
  83. * @property {undefined|String} source
  84. */
  85. function Position(start) {
  86. this.start = start;
  87. this.end = { line: lineno, column: column };
  88. this.source = options.source;
  89. }
  90. /**
  91. * Non-enumerable source string.
  92. */
  93. Position.prototype.content = style;
  94. /**
  95. * Error `msg`.
  96. *
  97. * @param {String} msg
  98. * @throws {Error}
  99. */
  100. function error(msg) {
  101. var err = new Error(
  102. options.source + ':' + lineno + ':' + column + ': ' + msg
  103. );
  104. err.reason = msg;
  105. err.filename = options.source;
  106. err.line = lineno;
  107. err.column = column;
  108. err.source = style;
  109. if (options.silent) ; else {
  110. throw err;
  111. }
  112. }
  113. /**
  114. * Match `re` and return captures.
  115. *
  116. * @param {RegExp} re
  117. * @return {undefined|Array}
  118. */
  119. function match(re) {
  120. var m = re.exec(style);
  121. if (!m) return;
  122. var str = m[0];
  123. updatePosition(str);
  124. style = style.slice(str.length);
  125. return m;
  126. }
  127. /**
  128. * Parse whitespace.
  129. */
  130. function whitespace() {
  131. match(WHITESPACE_REGEX);
  132. }
  133. /**
  134. * Parse comments.
  135. *
  136. * @param {Object[]} [rules]
  137. * @return {Object[]}
  138. */
  139. function comments(rules) {
  140. var c;
  141. rules = rules || [];
  142. while ((c = comment())) {
  143. if (c !== false) {
  144. rules.push(c);
  145. }
  146. }
  147. return rules;
  148. }
  149. /**
  150. * Parse comment.
  151. *
  152. * @return {Object}
  153. * @throws {Error}
  154. */
  155. function comment() {
  156. var pos = position();
  157. if (FORWARD_SLASH != style.charAt(0) || ASTERISK != style.charAt(1)) return;
  158. var i = 2;
  159. while (
  160. EMPTY_STRING != style.charAt(i) &&
  161. (ASTERISK != style.charAt(i) || FORWARD_SLASH != style.charAt(i + 1))
  162. ) {
  163. ++i;
  164. }
  165. i += 2;
  166. if (EMPTY_STRING === style.charAt(i - 1)) {
  167. return error('End of comment missing');
  168. }
  169. var str = style.slice(2, i - 2);
  170. column += 2;
  171. updatePosition(str);
  172. style = style.slice(i);
  173. column += 2;
  174. return pos({
  175. type: TYPE_COMMENT,
  176. comment: str
  177. });
  178. }
  179. /**
  180. * Parse declaration.
  181. *
  182. * @return {Object}
  183. * @throws {Error}
  184. */
  185. function declaration() {
  186. var pos = position();
  187. // prop
  188. var prop = match(PROPERTY_REGEX);
  189. if (!prop) return;
  190. comment();
  191. // :
  192. if (!match(COLON_REGEX)) return error("property missing ':'");
  193. // val
  194. var val = match(VALUE_REGEX);
  195. var ret = pos({
  196. type: TYPE_DECLARATION,
  197. property: trim(prop[0].replace(COMMENT_REGEX, EMPTY_STRING)),
  198. value: val
  199. ? trim(val[0].replace(COMMENT_REGEX, EMPTY_STRING))
  200. : EMPTY_STRING
  201. });
  202. // ;
  203. match(SEMICOLON_REGEX);
  204. return ret;
  205. }
  206. /**
  207. * Parse declarations.
  208. *
  209. * @return {Object[]}
  210. */
  211. function declarations() {
  212. var decls = [];
  213. comments(decls);
  214. // declarations
  215. var decl;
  216. while ((decl = declaration())) {
  217. if (decl !== false) {
  218. decls.push(decl);
  219. comments(decls);
  220. }
  221. }
  222. return decls;
  223. }
  224. whitespace();
  225. return declarations();
  226. }
  227. /**
  228. * Trim `str`.
  229. *
  230. * @param {String} str
  231. * @return {String}
  232. */
  233. function trim(str) {
  234. return str ? str.replace(TRIM_REGEX, EMPTY_STRING) : EMPTY_STRING;
  235. }
  236. cjs$1 = index;
  237. return cjs$1;
  238. }
  239. var hasRequiredCjs$1;
  240. function requireCjs$1 () {
  241. if (hasRequiredCjs$1) return cjs$2;
  242. hasRequiredCjs$1 = 1;
  243. var __importDefault = (cjs$2 && cjs$2.__importDefault) || function (mod) {
  244. return (mod && mod.__esModule) ? mod : { "default": mod };
  245. };
  246. Object.defineProperty(cjs$2, "__esModule", { value: true });
  247. cjs$2.default = StyleToObject;
  248. const inline_style_parser_1 = __importDefault(requireCjs$2());
  249. /**
  250. * Parses inline style to object.
  251. *
  252. * @param style - Inline style.
  253. * @param iterator - Iterator.
  254. * @returns - Style object or null.
  255. *
  256. * @example Parsing inline style to object:
  257. *
  258. * ```js
  259. * import parse from 'style-to-object';
  260. * parse('line-height: 42;'); // { 'line-height': '42' }
  261. * ```
  262. */
  263. function StyleToObject(style, iterator) {
  264. let styleObject = null;
  265. if (!style || typeof style !== 'string') {
  266. return styleObject;
  267. }
  268. const declarations = (0, inline_style_parser_1.default)(style);
  269. const hasIterator = typeof iterator === 'function';
  270. declarations.forEach((declaration) => {
  271. if (declaration.type !== 'declaration') {
  272. return;
  273. }
  274. const { property, value } = declaration;
  275. if (hasIterator) {
  276. iterator(property, value, declaration);
  277. }
  278. else if (value) {
  279. styleObject = styleObject || {};
  280. styleObject[property] = value;
  281. }
  282. });
  283. return styleObject;
  284. }
  285. return cjs$2;
  286. }
  287. var utilities = {};
  288. var hasRequiredUtilities;
  289. function requireUtilities () {
  290. if (hasRequiredUtilities) return utilities;
  291. hasRequiredUtilities = 1;
  292. Object.defineProperty(utilities, "__esModule", { value: true });
  293. utilities.camelCase = void 0;
  294. var CUSTOM_PROPERTY_REGEX = /^--[a-zA-Z0-9_-]+$/;
  295. var HYPHEN_REGEX = /-([a-z])/g;
  296. var NO_HYPHEN_REGEX = /^[^-]+$/;
  297. var VENDOR_PREFIX_REGEX = /^-(webkit|moz|ms|o|khtml)-/;
  298. var MS_VENDOR_PREFIX_REGEX = /^-(ms)-/;
  299. /**
  300. * Checks whether to skip camelCase.
  301. */
  302. var skipCamelCase = function (property) {
  303. return !property ||
  304. NO_HYPHEN_REGEX.test(property) ||
  305. CUSTOM_PROPERTY_REGEX.test(property);
  306. };
  307. /**
  308. * Replacer that capitalizes first character.
  309. */
  310. var capitalize = function (match, character) {
  311. return character.toUpperCase();
  312. };
  313. /**
  314. * Replacer that removes beginning hyphen of vendor prefix property.
  315. */
  316. var trimHyphen = function (match, prefix) { return "".concat(prefix, "-"); };
  317. /**
  318. * CamelCases a CSS property.
  319. */
  320. var camelCase = function (property, options) {
  321. if (options === void 0) { options = {}; }
  322. if (skipCamelCase(property)) {
  323. return property;
  324. }
  325. property = property.toLowerCase();
  326. if (options.reactCompat) {
  327. // `-ms` vendor prefix should not be capitalized
  328. property = property.replace(MS_VENDOR_PREFIX_REGEX, trimHyphen);
  329. }
  330. else {
  331. // for non-React, remove first hyphen so vendor prefix is not capitalized
  332. property = property.replace(VENDOR_PREFIX_REGEX, trimHyphen);
  333. }
  334. return property.replace(HYPHEN_REGEX, capitalize);
  335. };
  336. utilities.camelCase = camelCase;
  337. return utilities;
  338. }
  339. var cjs;
  340. var hasRequiredCjs;
  341. function requireCjs () {
  342. if (hasRequiredCjs) return cjs;
  343. hasRequiredCjs = 1;
  344. var __importDefault = (cjs && cjs.__importDefault) || function (mod) {
  345. return (mod && mod.__esModule) ? mod : { "default": mod };
  346. };
  347. var style_to_object_1 = __importDefault(requireCjs$1());
  348. var utilities_1 = requireUtilities();
  349. /**
  350. * Parses CSS inline style to JavaScript object (camelCased).
  351. */
  352. function StyleToJS(style, options) {
  353. var output = {};
  354. if (!style || typeof style !== 'string') {
  355. return output;
  356. }
  357. (0, style_to_object_1.default)(style, function (property, value) {
  358. // skip CSS comment
  359. if (property && value) {
  360. output[(0, utilities_1.camelCase)(property, options)] = value;
  361. }
  362. });
  363. return output;
  364. }
  365. StyleToJS.default = StyleToJS;
  366. cjs = StyleToJS;
  367. return cjs;
  368. }
  369. var cjsExports = requireCjs();
  370. var index = /*@__PURE__*/getDefaultExportFromCjs(cjsExports);
  371. return index;
  372. }));
  373. //# sourceMappingURL=style-to-js.js.map