(css: string)
| 2325 | /@charset(?:\s*(?:"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g |
| 2326 | |
| 2327 | export function hoistAtRules(css: string): string { |
| 2328 | const s = new MagicString(css) |
| 2329 | const cleanCss = emptyCssComments(css) |
| 2330 | let match: RegExpExecArray | null |
| 2331 | |
| 2332 | // #1845 |
| 2333 | // CSS @import can only appear at top of the file. We need to hoist all @import |
| 2334 | // to top when multiple files are concatenated. |
| 2335 | // match until semicolon that's not in quotes |
| 2336 | atImportRE.lastIndex = 0 |
| 2337 | while ((match = atImportRE.exec(cleanCss))) { |
| 2338 | s.remove(match.index, match.index + match[0].length) |
| 2339 | // Use `appendLeft` instead of `prepend` to preserve original @import order |
| 2340 | s.appendLeft(0, match[0]) |
| 2341 | } |
| 2342 | |
| 2343 | // #6333 |
| 2344 | // CSS @charset must be the top-first in the file, hoist the first to top |
| 2345 | atCharsetRE.lastIndex = 0 |
| 2346 | let foundCharset = false |
| 2347 | while ((match = atCharsetRE.exec(cleanCss))) { |
| 2348 | s.remove(match.index, match.index + match[0].length) |
| 2349 | if (!foundCharset) { |
| 2350 | s.prepend(match[0]) |
| 2351 | foundCharset = true |
| 2352 | } |
| 2353 | } |
| 2354 | |
| 2355 | return s.toString() |
| 2356 | } |
| 2357 | |
| 2358 | // Preprocessor support. This logic is largely replicated from @vue/compiler-sfc |
| 2359 |
no test coverage detected