fix(XmbSerializer): add meaning attribute, escape attribute values
This commit is contained in:
parent
e38e04c1c2
commit
c9c81e1fbc
|
@ -51,14 +51,14 @@ export class ReplacePipe implements PipeTransform {
|
||||||
if (!this._supportedReplacement(replacement)) {
|
if (!this._supportedReplacement(replacement)) {
|
||||||
throw new InvalidPipeArgumentException(ReplacePipe, replacement);
|
throw new InvalidPipeArgumentException(ReplacePipe, replacement);
|
||||||
}
|
}
|
||||||
// template fails with literal RegExp e.g /pattern/igm
|
|
||||||
// var rgx = pattern instanceof RegExp ? pattern : RegExpWrapper.create(pattern);
|
|
||||||
|
|
||||||
if (isFunction(replacement)) {
|
if (isFunction(replacement)) {
|
||||||
var rgxPattern = isString(pattern) ? RegExpWrapper.create(<string>pattern) : <RegExp>pattern;
|
const rgxPattern = isString(pattern) ? RegExpWrapper.create(pattern) : pattern;
|
||||||
|
|
||||||
return StringWrapper.replaceAllMapped(input, rgxPattern, <Function>replacement);
|
return StringWrapper.replaceAllMapped(
|
||||||
|
input, rgxPattern, <(m: string[]) => string>replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pattern instanceof RegExp) {
|
if (pattern instanceof RegExp) {
|
||||||
// use the replaceAll variant
|
// use the replaceAll variant
|
||||||
return StringWrapper.replaceAll(input, pattern, <string>replacement);
|
return StringWrapper.replaceAll(input, pattern, <string>replacement);
|
||||||
|
|
|
@ -85,8 +85,9 @@ function _id(el: HtmlElementAst): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
function _serializeMessage(m: Message): string {
|
function _serializeMessage(m: Message): string {
|
||||||
let desc = isPresent(m.description) ? ` desc='${m.description}'` : '';
|
const desc = isPresent(m.description) ? ` desc='${_escapeXml(m.description)}'` : '';
|
||||||
return `<msg id='${id(m)}'${desc}>${m.content}</msg>`;
|
const meaning = isPresent(m.meaning) ? ` meaning='${_escapeXml(m.meaning)}'` : '';
|
||||||
|
return `<msg id='${id(m)}'${desc}${meaning}>${m.content}</msg>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _expandPlaceholder(input: string): string {
|
function _expandPlaceholder(input: string): string {
|
||||||
|
@ -95,3 +96,15 @@ function _expandPlaceholder(input: string): string {
|
||||||
return `<ph name=${nameWithQuotes}></ph>`;
|
return `<ph name=${nameWithQuotes}></ph>`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _XML_ESCAPED_CHARS: [RegExp, string][] = [
|
||||||
|
[/&/g, '&'],
|
||||||
|
[/"/g, '"'],
|
||||||
|
[/'/g, '''],
|
||||||
|
[/</g, '<'],
|
||||||
|
[/>/g, '>'],
|
||||||
|
];
|
||||||
|
|
||||||
|
function _escapeXml(value: string): string {
|
||||||
|
return _XML_ESCAPED_CHARS.reduce((value, escape) => value.replace(escape[0], escape[1]), value);
|
||||||
|
}
|
||||||
|
|
|
@ -10,16 +10,23 @@ export function main() {
|
||||||
it('should return an empty message bundle for an empty list of messages',
|
it('should return an empty message bundle for an empty list of messages',
|
||||||
() => { expect(serializeXmb([])).toEqual('<message-bundle></message-bundle>'); });
|
() => { expect(serializeXmb([])).toEqual('<message-bundle></message-bundle>'); });
|
||||||
|
|
||||||
it('should serializeXmb messages without desc', () => {
|
it('should serialize messages without desc nor meaning', () => {
|
||||||
let m = new Message('content', 'meaning', null);
|
let m = new Message('content', null, null);
|
||||||
let expected = `<message-bundle><msg id='${id(m)}'>content</msg></message-bundle>`;
|
let expected = `<message-bundle><msg id='${id(m)}'>content</msg></message-bundle>`;
|
||||||
expect(serializeXmb([m])).toEqual(expected);
|
expect(serializeXmb([m])).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should serializeXmb messages with desc', () => {
|
it('should serialize messages with desc and meaning', () => {
|
||||||
let m = new Message('content', 'meaning', 'description');
|
let m = new Message('content', 'meaning', 'description');
|
||||||
let expected =
|
let expected =
|
||||||
`<message-bundle><msg id='${id(m)}' desc='description'>content</msg></message-bundle>`;
|
`<message-bundle><msg id='${id(m)}' desc='description' meaning='meaning'>content</msg></message-bundle>`;
|
||||||
|
expect(serializeXmb([m])).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should escape the desc and meaning', () => {
|
||||||
|
let m = new Message('content', '"\'&<>"\'&<>', '"\'&<>"\'&<>');
|
||||||
|
let expected =
|
||||||
|
`<message-bundle><msg id='${id(m)}' desc='"'&<>"'&<>' meaning='"'&<>"'&<>'>content</msg></message-bundle>`;
|
||||||
expect(serializeXmb([m])).toEqual(expected);
|
expect(serializeXmb([m])).toEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -216,7 +216,7 @@ export class StringWrapper {
|
||||||
return s.slice(from, to === null ? undefined : to);
|
return s.slice(from, to === null ? undefined : to);
|
||||||
}
|
}
|
||||||
|
|
||||||
static replaceAllMapped(s: string, from: RegExp, cb: Function): string {
|
static replaceAllMapped(s: string, from: RegExp, cb: (m: string[]) => string): string {
|
||||||
return s.replace(from, function(...matches: any[]) {
|
return s.replace(from, function(...matches: any[]) {
|
||||||
// Remove offset & string from the result array
|
// Remove offset & string from the result array
|
||||||
matches.splice(-2, 2);
|
matches.splice(-2, 2);
|
||||||
|
|
Loading…
Reference in New Issue