fix: String.split(str, n) stops after n separator (#10408)
This commit is contained in:
parent
e73d0511cf
commit
13c8211065
|
@ -33,13 +33,13 @@ export function splitNsName(elementName: string): [string, string] {
|
||||||
return [null, elementName];
|
return [null, elementName];
|
||||||
}
|
}
|
||||||
|
|
||||||
const parts = elementName.substring(1).split(':', 2);
|
const colonIndex = elementName.indexOf(':', 1);
|
||||||
|
|
||||||
if (parts.length != 2) {
|
if (colonIndex == -1) {
|
||||||
throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
|
throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parts as[string, string];
|
return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNsPrefix(fullName: string): string {
|
export function getNsPrefix(fullName: string): string {
|
||||||
|
|
|
@ -195,7 +195,8 @@ class _ExtractVisitor implements html.Visitor {
|
||||||
// Do not create empty messages
|
// Do not create empty messages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
messages.push(new Message(ast, _meaning(meaningAndDesc), _description(meaningAndDesc)));
|
const [meaning, description] = _splitMeaningAndDesc(meaningAndDesc);
|
||||||
|
messages.push(new Message(ast, meaning, description));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -285,13 +286,8 @@ function _getI18nAttr(p: html.Element): html.Attribute {
|
||||||
return p.attrs.find(attr => attr.name === _I18N_ATTR) || null;
|
return p.attrs.find(attr => attr.name === _I18N_ATTR) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _meaning(i18n: string): string {
|
function _splitMeaningAndDesc(i18n: string): [string, string] {
|
||||||
if (!i18n || i18n == '') return '';
|
if (!i18n) return ['', ''];
|
||||||
return i18n.split('|', 2)[0];
|
const pipeIndex = i18n.indexOf('|');
|
||||||
}
|
return pipeIndex == -1 ? ['', i18n] : [i18n.slice(0, pipeIndex), i18n.slice(pipeIndex + 1)];
|
||||||
|
|
||||||
function _description(i18n: string): string {
|
|
||||||
if (!i18n || i18n == '') return '';
|
|
||||||
const parts = i18n.split('|', 2);
|
|
||||||
return parts.length > 1 ? parts[1] : '';
|
|
||||||
}
|
}
|
|
@ -21,8 +21,9 @@ export function camelCaseToDashCase(input: string): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function splitAtColon(input: string, defaultValues: string[]): string[] {
|
export function splitAtColon(input: string, defaultValues: string[]): string[] {
|
||||||
var parts = input.split(':', 2).map((s: string) => s.trim());
|
const colonIndex = input.indexOf(':');
|
||||||
return parts.length > 1 ? parts : defaultValues;
|
if (colonIndex == -1) return defaultValues;
|
||||||
|
return [input.slice(0, colonIndex).trim(), input.slice(colonIndex + 1).trim()];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sanitizeIdentifier(name: string): string {
|
export function sanitizeIdentifier(name: string): string {
|
||||||
|
|
|
@ -16,8 +16,8 @@ export function main() {
|
||||||
describe('MessageExtractor', () => {
|
describe('MessageExtractor', () => {
|
||||||
describe('elements', () => {
|
describe('elements', () => {
|
||||||
it('should extract from elements', () => {
|
it('should extract from elements', () => {
|
||||||
expect(extract('<div i18n="m|d">text<span>nested</span></div>')).toEqual([
|
expect(extract('<div i18n="m|d|e">text<span>nested</span></div>')).toEqual([
|
||||||
[['text', '<span>nested</span>'], 'm', 'd'],
|
[['text', '<span>nested</span>'], 'm', 'd|e'],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,11 +28,11 @@ export function main() {
|
||||||
describe('blocks', () => {
|
describe('blocks', () => {
|
||||||
it('should extract from blocks', () => {
|
it('should extract from blocks', () => {
|
||||||
expect(extract(`<!-- i18n: meaning1|desc1 -->message1<!-- /i18n -->
|
expect(extract(`<!-- i18n: meaning1|desc1 -->message1<!-- /i18n -->
|
||||||
<!-- i18n: meaning2 -->message2<!-- /i18n -->
|
<!-- i18n: desc2 -->message2<!-- /i18n -->
|
||||||
<!-- i18n -->message3<!-- /i18n -->`))
|
<!-- i18n -->message3<!-- /i18n -->`))
|
||||||
.toEqual([
|
.toEqual([
|
||||||
[['message1'], 'meaning1', 'desc1'],
|
[['message1'], 'meaning1', 'desc1'],
|
||||||
[['message2'], 'meaning2', ''],
|
[['message2'], '', 'desc2'],
|
||||||
[['message3'], '', ''],
|
[['message3'], '', ''],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -133,11 +133,11 @@ export function main() {
|
||||||
describe('blocks', () => {
|
describe('blocks', () => {
|
||||||
it('should extract from blocks', () => {
|
it('should extract from blocks', () => {
|
||||||
expect(_humanizeMessages(`<!-- i18n: meaning1|desc1 -->message1<!-- /i18n -->
|
expect(_humanizeMessages(`<!-- i18n: meaning1|desc1 -->message1<!-- /i18n -->
|
||||||
<!-- i18n: meaning2 -->message2<!-- /i18n -->
|
<!-- i18n: desc2 -->message2<!-- /i18n -->
|
||||||
<!-- i18n -->message3<!-- /i18n -->`))
|
<!-- i18n -->message3<!-- /i18n -->`))
|
||||||
.toEqual([
|
.toEqual([
|
||||||
[['message1'], 'meaning1', 'desc1'],
|
[['message1'], 'meaning1', 'desc1'],
|
||||||
[['message2'], 'meaning2', ''],
|
[['message2'], '', 'desc2'],
|
||||||
[['message3'], '', ''],
|
[['message3'], '', ''],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
import {fakeAsync} from '@angular/core/testing/fake_async';
|
import {fakeAsync} from '@angular/core/testing/fake_async';
|
||||||
import {beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
|
import {beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
|
||||||
|
|
||||||
import {SyncAsyncResult} from '../src/util';
|
import {SyncAsyncResult, splitAtColon} from '../src/util';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('util', () => {
|
describe('util', () => {
|
||||||
|
@ -20,5 +20,21 @@ export function main() {
|
||||||
sar.asyncResult.then((v: any) => expect(v).toBe(syncValue));
|
sar.asyncResult.then((v: any) => expect(v).toBe(syncValue));
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('splitAtColon', () => {
|
||||||
|
it('should split when a single ":" is present', () => {
|
||||||
|
expect(splitAtColon('a:b', [])).toEqual(['a', 'b']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should trim parts', () => { expect(splitAtColon(' a : b ', [])).toEqual(['a', 'b']); });
|
||||||
|
|
||||||
|
it('should support multiple ":"', () => {
|
||||||
|
expect(splitAtColon('a:b:c', [])).toEqual(['a', 'b:c']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use the default value when no ":" is present', () => {
|
||||||
|
expect(splitAtColon('ab', ['c', 'd'])).toEqual(['c', 'd']);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,14 @@ import {ListWrapper, Map, isListLikeIterable} from '../src/facade/collection';
|
||||||
import {isPresent} from '../src/facade/lang';
|
import {isPresent} from '../src/facade/lang';
|
||||||
|
|
||||||
function paramParser(rawParams: string = ''): Map<string, string[]> {
|
function paramParser(rawParams: string = ''): Map<string, string[]> {
|
||||||
var map = new Map<string, string[]>();
|
const map = new Map<string, string[]>();
|
||||||
if (rawParams.length > 0) {
|
if (rawParams.length > 0) {
|
||||||
var params: string[] = rawParams.split('&');
|
const params: string[] = rawParams.split('&');
|
||||||
params.forEach((param: string) => {
|
params.forEach((param: string) => {
|
||||||
var split: string[] = param.split('=', 2);
|
const eqIdx = param.indexOf('=');
|
||||||
var key = split[0];
|
const [key, val]: string[] =
|
||||||
var val = split[1];
|
eqIdx == -1 ? [param, ''] : [param.slice(0, eqIdx), param.slice(eqIdx + 1)];
|
||||||
var list = isPresent(map.get(key)) ? map.get(key) : [];
|
const list = map.get(key) || [];
|
||||||
list.push(val);
|
list.push(val);
|
||||||
map.set(key, list);
|
map.set(key, list);
|
||||||
});
|
});
|
||||||
|
|
|
@ -443,13 +443,14 @@ function relativePath(url: any /** TODO #9100 */): string {
|
||||||
'/' + urlParsingNode.pathname;
|
'/' + urlParsingNode.pathname;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseCookieValue(cookie: string, name: string): string {
|
export function parseCookieValue(cookieStr: string, name: string): string {
|
||||||
name = encodeURIComponent(name);
|
name = encodeURIComponent(name);
|
||||||
let cookies = cookie.split(';');
|
for (const cookie of cookieStr.split(';')) {
|
||||||
for (let cookie of cookies) {
|
const eqIndex = cookie.indexOf('=');
|
||||||
let [key, value] = cookie.split('=', 2);
|
const [cookieName, cookieValue]: string[] =
|
||||||
if (key.trim() === name) {
|
eqIndex == -1 ? [cookie, ''] : [cookie.slice(0, eqIndex), cookie.slice(eqIndex + 1)];
|
||||||
return decodeURIComponent(value);
|
if (cookieName.trim() === name) {
|
||||||
|
return decodeURIComponent(cookieValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
Loading…
Reference in New Issue