Skip to content

Commit ac46779

Browse files
author
Miguel Solorio
authored
Merge branch 'master' into misolori/secondary-button-style
2 parents 46d0b33 + 4cf27bd commit ac46779

121 files changed

Lines changed: 1804 additions & 1702 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: "Rich Navigation Indexing"
2+
on:
3+
pull_request:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
richnav:
10+
runs-on: windows-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- name: Use Node.js
14+
uses: actions/setup-node@v1
15+
- name: Install dependencies
16+
run: yarn install
17+
- uses: microsoft/RichCodeNavIndexer@master
18+
with:
19+
languages: typescript

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
},
7373
"gulp.autoDetect": "off",
7474
"files.insertFinalNewline": true,
75-
"[typescript]": {
75+
"[typescript]": {
7676
"editor.defaultFormatter": "vscode.typescript-language-features"
7777
},
7878
"typescript.tsc.autoDetect": "off"

build/lib/i18n.js

Lines changed: 135 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -101,161 +101,158 @@ class TextModel {
101101
return this._lines;
102102
}
103103
}
104-
let XLF = /** @class */ (() => {
105-
class XLF {
106-
constructor(project) {
107-
this.project = project;
108-
this.buffer = [];
109-
this.files = Object.create(null);
110-
this.numberOfMessages = 0;
111-
}
112-
toString() {
113-
this.appendHeader();
114-
for (let file in this.files) {
115-
this.appendNewLine(`<file original="${file}" source-language="en" datatype="plaintext"><body>`, 2);
116-
for (let item of this.files[file]) {
117-
this.addStringItem(file, item);
118-
}
119-
this.appendNewLine('</body></file>', 2);
104+
class XLF {
105+
constructor(project) {
106+
this.project = project;
107+
this.buffer = [];
108+
this.files = Object.create(null);
109+
this.numberOfMessages = 0;
110+
}
111+
toString() {
112+
this.appendHeader();
113+
for (let file in this.files) {
114+
this.appendNewLine(`<file original="${file}" source-language="en" datatype="plaintext"><body>`, 2);
115+
for (let item of this.files[file]) {
116+
this.addStringItem(file, item);
120117
}
121-
this.appendFooter();
122-
return this.buffer.join('\r\n');
118+
this.appendNewLine('</body></file>', 2);
123119
}
124-
addFile(original, keys, messages) {
125-
if (keys.length === 0) {
126-
console.log('No keys in ' + original);
127-
return;
128-
}
129-
if (keys.length !== messages.length) {
130-
throw new Error(`Unmatching keys(${keys.length}) and messages(${messages.length}).`);
131-
}
132-
this.numberOfMessages += keys.length;
133-
this.files[original] = [];
134-
let existingKeys = new Set();
135-
for (let i = 0; i < keys.length; i++) {
136-
let key = keys[i];
137-
let realKey;
138-
let comment;
139-
if (Is.string(key)) {
140-
realKey = key;
141-
comment = undefined;
142-
}
143-
else if (LocalizeInfo.is(key)) {
144-
realKey = key.key;
145-
if (key.comment && key.comment.length > 0) {
146-
comment = key.comment.map(comment => encodeEntities(comment)).join('\r\n');
147-
}
148-
}
149-
if (!realKey || existingKeys.has(realKey)) {
150-
continue;
151-
}
152-
existingKeys.add(realKey);
153-
let message = encodeEntities(messages[i]);
154-
this.files[original].push({ id: realKey, message: message, comment: comment });
155-
}
120+
this.appendFooter();
121+
return this.buffer.join('\r\n');
122+
}
123+
addFile(original, keys, messages) {
124+
if (keys.length === 0) {
125+
console.log('No keys in ' + original);
126+
return;
156127
}
157-
addStringItem(file, item) {
158-
if (!item.id || item.message === undefined || item.message === null) {
159-
throw new Error(`No item ID or value specified: ${JSON.stringify(item)}. File: ${file}`);
128+
if (keys.length !== messages.length) {
129+
throw new Error(`Unmatching keys(${keys.length}) and messages(${messages.length}).`);
130+
}
131+
this.numberOfMessages += keys.length;
132+
this.files[original] = [];
133+
let existingKeys = new Set();
134+
for (let i = 0; i < keys.length; i++) {
135+
let key = keys[i];
136+
let realKey;
137+
let comment;
138+
if (Is.string(key)) {
139+
realKey = key;
140+
comment = undefined;
160141
}
161-
if (item.message.length === 0) {
162-
log(`Item with id ${item.id} in file ${file} has an empty message.`);
142+
else if (LocalizeInfo.is(key)) {
143+
realKey = key.key;
144+
if (key.comment && key.comment.length > 0) {
145+
comment = key.comment.map(comment => encodeEntities(comment)).join('\r\n');
146+
}
163147
}
164-
this.appendNewLine(`<trans-unit id="${item.id}">`, 4);
165-
this.appendNewLine(`<source xml:lang="en">${item.message}</source>`, 6);
166-
if (item.comment) {
167-
this.appendNewLine(`<note>${item.comment}</note>`, 6);
148+
if (!realKey || existingKeys.has(realKey)) {
149+
continue;
168150
}
169-
this.appendNewLine('</trans-unit>', 4);
151+
existingKeys.add(realKey);
152+
let message = encodeEntities(messages[i]);
153+
this.files[original].push({ id: realKey, message: message, comment: comment });
170154
}
171-
appendHeader() {
172-
this.appendNewLine('<?xml version="1.0" encoding="utf-8"?>', 0);
173-
this.appendNewLine('<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">', 0);
155+
}
156+
addStringItem(file, item) {
157+
if (!item.id || item.message === undefined || item.message === null) {
158+
throw new Error(`No item ID or value specified: ${JSON.stringify(item)}. File: ${file}`);
174159
}
175-
appendFooter() {
176-
this.appendNewLine('</xliff>', 0);
160+
if (item.message.length === 0) {
161+
log(`Item with id ${item.id} in file ${file} has an empty message.`);
177162
}
178-
appendNewLine(content, indent) {
179-
let line = new Line(indent);
180-
line.append(content);
181-
this.buffer.push(line.toString());
163+
this.appendNewLine(`<trans-unit id="${item.id}">`, 4);
164+
this.appendNewLine(`<source xml:lang="en">${item.message}</source>`, 6);
165+
if (item.comment) {
166+
this.appendNewLine(`<note>${item.comment}</note>`, 6);
182167
}
168+
this.appendNewLine('</trans-unit>', 4);
183169
}
184-
XLF.parsePseudo = function (xlfString) {
185-
return new Promise((resolve) => {
186-
let parser = new xml2js.Parser();
187-
let files = [];
188-
parser.parseString(xlfString, function (_err, result) {
189-
const fileNodes = result['xliff']['file'];
190-
fileNodes.forEach(file => {
191-
const originalFilePath = file.$.original;
192-
const messages = {};
193-
const transUnits = file.body[0]['trans-unit'];
194-
if (transUnits) {
195-
transUnits.forEach((unit) => {
196-
const key = unit.$.id;
197-
const val = pseudify(unit.source[0]['_'].toString());
198-
if (key && val) {
199-
messages[key] = decodeEntities(val);
200-
}
201-
});
202-
files.push({ messages: messages, originalFilePath: originalFilePath, language: 'ps' });
203-
}
204-
});
205-
resolve(files);
170+
appendHeader() {
171+
this.appendNewLine('<?xml version="1.0" encoding="utf-8"?>', 0);
172+
this.appendNewLine('<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">', 0);
173+
}
174+
appendFooter() {
175+
this.appendNewLine('</xliff>', 0);
176+
}
177+
appendNewLine(content, indent) {
178+
let line = new Line(indent);
179+
line.append(content);
180+
this.buffer.push(line.toString());
181+
}
182+
}
183+
exports.XLF = XLF;
184+
XLF.parsePseudo = function (xlfString) {
185+
return new Promise((resolve) => {
186+
let parser = new xml2js.Parser();
187+
let files = [];
188+
parser.parseString(xlfString, function (_err, result) {
189+
const fileNodes = result['xliff']['file'];
190+
fileNodes.forEach(file => {
191+
const originalFilePath = file.$.original;
192+
const messages = {};
193+
const transUnits = file.body[0]['trans-unit'];
194+
if (transUnits) {
195+
transUnits.forEach((unit) => {
196+
const key = unit.$.id;
197+
const val = pseudify(unit.source[0]['_'].toString());
198+
if (key && val) {
199+
messages[key] = decodeEntities(val);
200+
}
201+
});
202+
files.push({ messages: messages, originalFilePath: originalFilePath, language: 'ps' });
203+
}
206204
});
205+
resolve(files);
207206
});
208-
};
209-
XLF.parse = function (xlfString) {
210-
return new Promise((resolve, reject) => {
211-
let parser = new xml2js.Parser();
212-
let files = [];
213-
parser.parseString(xlfString, function (err, result) {
214-
if (err) {
215-
reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`));
207+
});
208+
};
209+
XLF.parse = function (xlfString) {
210+
return new Promise((resolve, reject) => {
211+
let parser = new xml2js.Parser();
212+
let files = [];
213+
parser.parseString(xlfString, function (err, result) {
214+
if (err) {
215+
reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`));
216+
}
217+
const fileNodes = result['xliff']['file'];
218+
if (!fileNodes) {
219+
reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`));
220+
}
221+
fileNodes.forEach((file) => {
222+
const originalFilePath = file.$.original;
223+
if (!originalFilePath) {
224+
reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`));
216225
}
217-
const fileNodes = result['xliff']['file'];
218-
if (!fileNodes) {
219-
reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`));
226+
let language = file.$['target-language'];
227+
if (!language) {
228+
reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`));
229+
}
230+
const messages = {};
231+
const transUnits = file.body[0]['trans-unit'];
232+
if (transUnits) {
233+
transUnits.forEach((unit) => {
234+
const key = unit.$.id;
235+
if (!unit.target) {
236+
return; // No translation available
237+
}
238+
let val = unit.target[0];
239+
if (typeof val !== 'string') {
240+
val = val._;
241+
}
242+
if (key && val) {
243+
messages[key] = decodeEntities(val);
244+
}
245+
else {
246+
reject(new Error(`XLF parsing error: XLIFF file ${originalFilePath} does not contain full localization data. ID or target translation for one of the trans-unit nodes is not present.`));
247+
}
248+
});
249+
files.push({ messages: messages, originalFilePath: originalFilePath, language: language.toLowerCase() });
220250
}
221-
fileNodes.forEach((file) => {
222-
const originalFilePath = file.$.original;
223-
if (!originalFilePath) {
224-
reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`));
225-
}
226-
let language = file.$['target-language'];
227-
if (!language) {
228-
reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`));
229-
}
230-
const messages = {};
231-
const transUnits = file.body[0]['trans-unit'];
232-
if (transUnits) {
233-
transUnits.forEach((unit) => {
234-
const key = unit.$.id;
235-
if (!unit.target) {
236-
return; // No translation available
237-
}
238-
let val = unit.target[0];
239-
if (typeof val !== 'string') {
240-
val = val._;
241-
}
242-
if (key && val) {
243-
messages[key] = decodeEntities(val);
244-
}
245-
else {
246-
reject(new Error(`XLF parsing error: XLIFF file ${originalFilePath} does not contain full localization data. ID or target translation for one of the trans-unit nodes is not present.`));
247-
}
248-
});
249-
files.push({ messages: messages, originalFilePath: originalFilePath, language: language.toLowerCase() });
250-
}
251-
});
252-
resolve(files);
253251
});
252+
resolve(files);
254253
});
255-
};
256-
return XLF;
257-
})();
258-
exports.XLF = XLF;
254+
});
255+
};
259256
class Limiter {
260257
constructor(maxDegreeOfParalellism) {
261258
this.maxDegreeOfParalellism = maxDegreeOfParalellism;

build/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"minimist": "^1.2.3",
4545
"request": "^2.85.0",
4646
"terser": "4.3.8",
47-
"typescript": "^3.9.3",
47+
"typescript": "^4.0.0-dev.20200612",
4848
"vsce": "1.48.0",
4949
"vscode-telemetry-extractor": "^1.5.4",
5050
"xml2js": "^0.4.17"

build/yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2519,10 +2519,10 @@ typescript@^3.0.1:
25192519
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977"
25202520
integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==
25212521

2522-
typescript@^3.9.3:
2523-
version "3.9.3"
2524-
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.3.tgz#d3ac8883a97c26139e42df5e93eeece33d610b8a"
2525-
integrity sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==
2522+
typescript@^4.0.0-dev.20200612:
2523+
version "4.0.0-dev.20200612"
2524+
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.0-dev.20200612.tgz#6f1f1a8508eae00ef79b57116886dc05051b398e"
2525+
integrity sha512-o69PZMHrijfGcfvPmTJjLOmYZYccfpDcpFohMmBVLZLOdtRWzjOZSfymGq1J13w6tRlvnLdREpdH40cCnhURow==
25262526

25272527
typical@^4.0.0:
25282528
version "4.0.0"

extensions/extension-editing/src/extensionLinter.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ import { languages, workspace, Disposable, TextDocument, Uri, Diagnostic, Range,
1616

1717
const product = JSON.parse(fs.readFileSync(path.join(env.appRoot, 'product.json'), { encoding: 'utf-8' }));
1818
const allowedBadgeProviders: string[] = (product.extensionAllowedBadgeProviders || []).map((s: string) => s.toLowerCase());
19+
const allowedBadgeProvidersRegex: RegExp[] = (product.extensionAllowedBadgeProvidersRegex || []).map((r: string) => new RegExp(r));
20+
21+
function isTrustedSVGSource(uri: Uri): boolean {
22+
return allowedBadgeProviders.includes(uri.authority.toLowerCase()) || allowedBadgeProvidersRegex.some(r => r.test(uri.toString()));
23+
}
1924

2025
const httpsRequired = localize('httpsRequired', "Images must use the HTTPS protocol.");
2126
const svgsNotValid = localize('svgsNotValid', "SVGs are not a valid image source.");
@@ -321,7 +326,7 @@ export class ExtensionLinter {
321326
diagnostics.push(new Diagnostic(range, message, DiagnosticSeverity.Warning));
322327
}
323328

324-
if (endsWith(uri.path.toLowerCase(), '.svg') && allowedBadgeProviders.indexOf(uri.authority.toLowerCase()) === -1) {
329+
if (endsWith(uri.path.toLowerCase(), '.svg') && !isTrustedSVGSource(uri)) {
325330
const range = new Range(document.positionAt(begin), document.positionAt(end));
326331
diagnostics.push(new Diagnostic(range, svgsNotValid, DiagnosticSeverity.Warning));
327332
}

extensions/markdown-language-features/media/preview-right-dark.svg

Lines changed: 0 additions & 4 deletions
This file was deleted.

extensions/markdown-language-features/media/preview-right-light.svg

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)