store regexp as variable instead of defining it inline

pull/7716/head
Ivan Hofer 4 years ago committed by tanhauhau
parent 220325cd9f
commit 0c05510677

@ -13,8 +13,10 @@ interface SourceUpdate {
dependencies?: string[]; dependencies?: string[];
} }
const regex_filepath_separator = /[/\\]/;
function get_file_basename(filename: string) { function get_file_basename(filename: string) {
return filename.split(/[/\\]/).pop(); return filename.split(regex_filepath_separator).pop();
} }
/** /**
@ -120,20 +122,27 @@ function processed_tag_to_code(
return tag_open_code.concat(content_code).concat(tag_close_code); return tag_open_code.concat(content_code).concat(tag_close_code);
} }
const regex_whitespace = /\s+/;
const regex_unquoted_value = /^['"](.*)['"]$/;
function parse_tag_attributes(str: string) { function parse_tag_attributes(str: string) {
// note: won't work with attribute values containing spaces. // note: won't work with attribute values containing spaces.
return str return str
.split(/\s+/) .split(regex_whitespace)
.filter(Boolean) .filter(Boolean)
.reduce((attrs, attr) => { .reduce((attrs, attr) => {
const i = attr.indexOf('='); const i = attr.indexOf('=');
const [key, value] = i > 0 ? [attr.slice(0, i), attr.slice(i + 1)] : [attr]; const [key, value] = i > 0 ? [attr.slice(0, i), attr.slice(i + 1)] : [attr];
const [, unquoted] = (value && value.match(/^['"](.*)['"]$/)) || []; const [, unquoted] = (value && value.match(regex_unquoted_value)) || [];
return { ...attrs, [key]: unquoted ?? value ?? true }; return { ...attrs, [key]: unquoted ?? value ?? true };
}, {}); }, {});
} }
const regex_style_tags = /<!--[^]*?-->|<style(\s[^]*?)?(?:>([^]*?)<\/style>|\/>)/gi;
const regex_script_tags = /<!--[^]*?-->|<script(\s[^]*?)?(?:>([^]*?)<\/script>|\/>)/gi;
/** /**
* Calculate the updates required to process all instances of the specified tag. * Calculate the updates required to process all instances of the specified tag.
*/ */
@ -143,10 +152,7 @@ async function process_tag(
source: Source source: Source
): Promise<SourceUpdate> { ): Promise<SourceUpdate> {
const { filename, source: markup } = source; const { filename, source: markup } = source;
const tag_regex = const tag_regex = tag_name === 'style' ? regex_style_tags : regex_script_tags;
tag_name === 'style'
? /<!--[^]*?-->|<style(\s[^]*?)?(?:>([^]*?)<\/style>|\/>)/gi
: /<!--[^]*?-->|<script(\s[^]*?)?(?:>([^]*?)<\/script>|\/>)/gi;
const dependencies: string[] = []; const dependencies: string[] = [];
@ -190,7 +196,7 @@ async function process_markup(process: MarkupPreprocessor, source: Source) {
string: processed.code, string: processed.code,
map: processed.map map: processed.map
? // TODO: can we use decode_sourcemap? ? // TODO: can we use decode_sourcemap?
typeof processed.map === 'string' typeof processed.map === 'string'
? JSON.parse(processed.map) ? JSON.parse(processed.map)
: processed.map : processed.map
: undefined, : undefined,

@ -3,9 +3,11 @@ import { flatten } from './flatten';
const pattern = /^\s*svelte-ignore\s+([\s\S]+)\s*$/m; const pattern = /^\s*svelte-ignore\s+([\s\S]+)\s*$/m;
const regex_no_whitespace_character = /[^\S]/;
export function extract_svelte_ignore(text: string): string[] { export function extract_svelte_ignore(text: string): string[] {
const match = pattern.exec(text); const match = pattern.exec(text);
return match ? match[1].split(/[^\S]/).map(x => x.trim()).filter(Boolean) : []; return match ? match[1].split(regex_no_whitespace_character).map(x => x.trim()).filter(Boolean) : [];
} }
export function extract_svelte_ignore_from_comments<Node extends { leadingComments?: Array<{value: string}> }>(node: Node): string[] { export function extract_svelte_ignore_from_comments<Node extends { leadingComments?: Array<{value: string}> }>(node: Node): string[] {

@ -1,5 +1,7 @@
const regex_tabs = /^\t+/;
function tabs_to_spaces(str: string) { function tabs_to_spaces(str: string) {
return str.replace(/^\t+/, match => match.split('\t').join(' ')); return str.replace(regex_tabs, match => match.split('\t').join(' '));
} }
export default function get_code_frame( export default function get_code_frame(

@ -182,6 +182,8 @@ export class MappedCode {
return new MappedCode(string, map); return new MappedCode(string, map);
} }
private static regex_line_token = /([^\d\w\s]|\s+)/g;
static from_source({ source, file_basename, get_location }: Source): MappedCode { static from_source({ source, file_basename, get_location }: Source): MappedCode {
let offset: SourceLocation = get_location(0); let offset: SourceLocation = get_location(0);
@ -195,7 +197,7 @@ export class MappedCode {
const line_list = source.split('\n'); const line_list = source.split('\n');
for (let line = 0; line < line_list.length; line++) { for (let line = 0; line < line_list.length; line++) {
map.mappings.push([]); map.mappings.push([]);
const token_list = line_list[line].split(/([^\d\w\s]|\s+)/g); const token_list = line_list[line].split(this.regex_line_token);
for (let token = 0, column = 0; token < token_list.length; token++) { for (let token = 0, column = 0; token < token_list.length; token++) {
if (token_list[token] == '') continue; if (token_list[token] == '') continue;
map.mappings[line].push([column, 0, offset.line + line, column]); map.mappings[line].push([column, 0, offset.line + line, column]);
@ -245,7 +247,7 @@ export function combine_sourcemaps(
if (!map.file) delete map.file; // skip optional field `file` if (!map.file) delete map.file; // skip optional field `file`
// When source maps are combined and the leading map is empty, sources is not set. // When source maps are combined and the leading map is empty, sources is not set.
// Add the filename to the empty array in this case. // Add the filename to the empty array in this case.
// Further improvements to remapping may help address this as well https://github.com/ampproject/remapping/issues/116 // Further improvements to remapping may help address this as well https://github.com/ampproject/remapping/issues/116
if (!map.sources.length) map.sources = [filename]; if (!map.sources.length) map.sources = [filename];
@ -289,6 +291,8 @@ export function apply_preprocessor_sourcemap(filename: string, svelte_map: Sourc
return result_map as SourceMap; return result_map as SourceMap;
} }
const regex_data_uri = /data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(\S*)/;
// parse attached sourcemap in processed.code // parse attached sourcemap in processed.code
export function parse_attached_sourcemap(processed: Processed, tag_name: 'script' | 'style'): void { export function parse_attached_sourcemap(processed: Processed, tag_name: 'script' | 'style'): void {
const r_in = '[#@]\\s*sourceMappingURL\\s*=\\s*(\\S*)'; const r_in = '[#@]\\s*sourceMappingURL\\s*=\\s*(\\S*)';
@ -302,7 +306,7 @@ export function parse_attached_sourcemap(processed: Processed, tag_name: 'script
} }
processed.code = processed.code.replace(regex, (_, match1, match2) => { processed.code = processed.code.replace(regex, (_, match1, match2) => {
const map_url = (tag_name == 'script') ? (match1 || match2) : match1; const map_url = (tag_name == 'script') ? (match1 || match2) : match1;
const map_data = (map_url.match(/data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(\S*)/) || [])[1]; const map_data = (map_url.match(regex_data_uri) || [])[1];
if (map_data) { if (map_data) {
// sourceMappingURL is data URL // sourceMappingURL is data URL
if (processed.map) { if (processed.map) {

@ -65,10 +65,15 @@ export function is_valid(str: string): boolean {
return true; return true;
} }
const regex_non_standard_characters = /[^a-zA-Z0-9_]+/g;
const regex_starts_with_underscore = /^_/;
const regex_ends_with_underscore = /_$/;
const regex_starts_with_number = /^[0-9]/;
export function sanitize(name: string) { export function sanitize(name: string) {
return name return name
.replace(/[^a-zA-Z0-9_]+/g, '_') .replace(regex_non_standard_characters, '_')
.replace(/^_/, '') .replace(regex_starts_with_underscore, '')
.replace(/_$/, '') .replace(regex_ends_with_underscore, '')
.replace(/^[0-9]/, '_$&'); .replace(regex_starts_with_number, '_$&');
} }

Loading…
Cancel
Save