display.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. "use strict";
  2. const parsers = require("../parsers");
  3. const property = "display";
  4. /* keywords */
  5. const displayOutside = ["block", "inline", "run-in"];
  6. const displayFlow = ["flow", "flow-root"];
  7. module.exports.parse = (v, opt = {}) => {
  8. const { globalObject } = opt;
  9. if (v === "") {
  10. return v;
  11. }
  12. const { AST_TYPES } = parsers;
  13. const value = parsers.parsePropertyValue(property, v, {
  14. globalObject,
  15. inArray: true
  16. });
  17. if (Array.isArray(value) && value.length) {
  18. switch (value.length) {
  19. case 1: {
  20. const [{ name, type }] = value;
  21. switch (type) {
  22. case AST_TYPES.GLOBAL_KEYWORD: {
  23. return name;
  24. }
  25. case AST_TYPES.IDENTIFIER: {
  26. if (name === "flow") {
  27. return "block";
  28. }
  29. return name;
  30. }
  31. default:
  32. }
  33. break;
  34. }
  35. case 2: {
  36. const [part1, part2] = value;
  37. const val1 = part1.type === AST_TYPES.IDENTIFIER && part1.name;
  38. const val2 = part2.type === AST_TYPES.IDENTIFIER && part2.name;
  39. if (val1 && val2) {
  40. let outerValue = "";
  41. let innerValue = "";
  42. if (val1 === "list-item") {
  43. outerValue = val2;
  44. innerValue = val1;
  45. } else if (val2 === "list-item") {
  46. outerValue = val1;
  47. innerValue = val2;
  48. } else if (displayOutside.includes(val1)) {
  49. outerValue = val1;
  50. innerValue = val2;
  51. } else if (displayOutside.includes(val2)) {
  52. outerValue = val2;
  53. innerValue = val1;
  54. }
  55. if (innerValue === "list-item") {
  56. switch (outerValue) {
  57. case "block":
  58. case "flow": {
  59. return innerValue;
  60. }
  61. case "flow-root":
  62. case "inline":
  63. case "run-in": {
  64. return `${outerValue} ${innerValue}`;
  65. }
  66. default:
  67. }
  68. } else if (outerValue === "block") {
  69. switch (innerValue) {
  70. case "flow": {
  71. return outerValue;
  72. }
  73. case "flow-root":
  74. case "flex":
  75. case "grid":
  76. case "table": {
  77. return innerValue;
  78. }
  79. case "ruby": {
  80. return `${outerValue} ${innerValue}`;
  81. }
  82. default:
  83. }
  84. } else if (outerValue === "inline") {
  85. switch (innerValue) {
  86. case "flow": {
  87. return outerValue;
  88. }
  89. case "flow-root": {
  90. return `${outerValue}-block`;
  91. }
  92. case "flex":
  93. case "grid":
  94. case "table": {
  95. return `${outerValue}-${innerValue}`;
  96. }
  97. case "ruby": {
  98. return innerValue;
  99. }
  100. default:
  101. }
  102. } else if (outerValue === "run-in") {
  103. switch (innerValue) {
  104. case "flow": {
  105. return outerValue;
  106. }
  107. case "flow-root":
  108. case "flex":
  109. case "grid":
  110. case "table":
  111. case "ruby": {
  112. return `${outerValue} ${innerValue}`;
  113. }
  114. default:
  115. }
  116. }
  117. }
  118. break;
  119. }
  120. case 3: {
  121. const [part1, part2, part3] = value;
  122. const val1 = part1.type === AST_TYPES.IDENTIFIER && part1.name;
  123. const val2 = part2.type === AST_TYPES.IDENTIFIER && part2.name;
  124. const val3 = part3.type === AST_TYPES.IDENTIFIER && part3.name;
  125. if (val1 && val2 && part3) {
  126. let outerValue = "";
  127. let flowValue = "";
  128. let listItemValue = "";
  129. if (val1 === "list-item") {
  130. listItemValue = val1;
  131. if (displayFlow.includes(val2)) {
  132. flowValue = val2;
  133. outerValue = val3;
  134. } else if (displayFlow.includes(val3)) {
  135. flowValue = val3;
  136. outerValue = val2;
  137. }
  138. } else if (val2 === "list-item") {
  139. listItemValue = val2;
  140. if (displayFlow.includes(val1)) {
  141. flowValue = val1;
  142. outerValue = val3;
  143. } else if (displayFlow.includes(val3)) {
  144. flowValue = val3;
  145. outerValue = val1;
  146. }
  147. } else if (val3 === "list-item") {
  148. listItemValue = val3;
  149. if (displayFlow.includes(val1)) {
  150. flowValue = val1;
  151. outerValue = val2;
  152. } else if (displayFlow.includes(val2)) {
  153. flowValue = val2;
  154. outerValue = val1;
  155. }
  156. }
  157. if (outerValue && flowValue && listItemValue) {
  158. switch (outerValue) {
  159. case "block": {
  160. if (flowValue === "flow") {
  161. return listItemValue;
  162. }
  163. return `${flowValue} ${listItemValue}`;
  164. }
  165. case "inline":
  166. case "run-in": {
  167. if (flowValue === "flow") {
  168. return `${outerValue} ${listItemValue}`;
  169. }
  170. return `${outerValue} ${flowValue} ${listItemValue}`;
  171. }
  172. }
  173. }
  174. }
  175. break;
  176. }
  177. default:
  178. }
  179. } else if (typeof value === "string") {
  180. return value;
  181. }
  182. };
  183. module.exports.definition = {
  184. set(v) {
  185. v = parsers.prepareValue(v);
  186. if (parsers.hasVarFunc(v)) {
  187. this._setProperty(property, v);
  188. } else {
  189. const val = module.exports.parse(v, {
  190. globalObject: this._global
  191. });
  192. if (typeof val === "string") {
  193. const priority = this._priorities.get(property) ?? "";
  194. this._setProperty(property, val, priority);
  195. }
  196. }
  197. },
  198. get() {
  199. return this.getPropertyValue(property);
  200. },
  201. enumerable: true,
  202. configurable: true
  203. };
  204. module.exports.property = property;