@@ -32,15 +32,46 @@ const errorTypes: Record<ValidationErrorType, string> = {
3232 'Markup Compatibility validation error' ,
3333} ;
3434
35+ const header = document . querySelector < HTMLElement > ( 'header' ) ! ;
36+ const title = header . querySelector < HTMLHeadingElement > ( 'h1' ) ! ;
3537const chooseFileButton =
3638 document . querySelector < HTMLButtonElement > ( '#choose-file' ) ! ;
39+ const inputContainer = document . querySelector < HTMLFormElement > ( '#input' ) ! ;
3740const fileInput = document . querySelector < HTMLInputElement > ( '#file' ) ! ;
3841const output = document . querySelector < HTMLDivElement > ( '#output' ) ! ;
3942
43+ // We do this dynamically based on HTML + CSS so that we don't need to
44+ // change anything on TS side if we add new file formats and/or change colors
45+ // Get the main stylesheet rules
46+ const mainStyleSheet = Array . from ( document . styleSheets ) . find ( s => ! ! s . href ) ! ;
47+ const mainStyleSheetRules = Array . from ( mainStyleSheet . cssRules ) ;
48+ // Get the supported input extensions
49+ const supportedExts = fileInput . accept . split ( ',' ) . map ( ext => ext . slice ( 1 ) ) ;
50+ // Based on the supported extensions, get the corresponding CSS rules
51+ // For each supported extension we expect a CSS rule with the selector `header.ext`
52+ const headerExtStyleRules = mainStyleSheetRules . filter (
53+ r =>
54+ r instanceof CSSStyleRule &&
55+ supportedExts . some ( ext => r . selectorText === `header.${ ext } ` ) ,
56+ ) as CSSStyleRule [ ] ;
57+ // Create a map of extension to color
58+ const extToColorMap = new Map (
59+ headerExtStyleRules . map ( r => [
60+ r . selectorText . slice ( 'header' . length + 1 ) ,
61+ r . style . backgroundColor ,
62+ ] ) ,
63+ ) ;
64+ // Get the meta theme color element, which we will update based on the file extension
65+ const metaThemeColor = document . querySelector < HTMLMetaElement > (
66+ 'meta[name="theme-color"]' ,
67+ ) ! ;
68+
4069fileInput . addEventListener ( 'change' , async ( ) => {
4170 if ( ! fileInput . files ?. length ) {
4271 return ;
4372 }
73+ const fileName = fileInput . files [ 0 ] . name ;
74+ inputContainer . hidden = true ;
4475 output . innerHTML = /* html */ `
4576 <div id="loading-container">
4677 <label for="loading">Loading...</label>
@@ -54,10 +85,21 @@ fileInput.addEventListener('change', async () => {
5485 reader . readAsArrayBuffer ( fileInput . files [ 0 ] ) ;
5586 const buffer = await readerResult . promise ;
5687 const validationResult = exports . WordprocessingDocumentValidator . Validate (
88+ fileName ,
5789 new Uint8Array ( buffer ) ,
5890 ) ;
5991 const parsedValidationResult : ValidationError [ ] =
6092 JSON . parse ( validationResult ) ;
93+ const extension = fileName . slice ( fileName . lastIndexOf ( '.' ) + 1 ) ;
94+ metaThemeColor . content = extToColorMap . get ( extension ) ?? '#000' ;
95+ header . className = extension ;
96+ title . textContent = fileName ;
97+ if ( parsedValidationResult . length === 0 ) {
98+ output . innerHTML = /* html */ `
99+ <div style="margin: 35vh auto; text-align: center;">No errors found!</div>
100+ ` ;
101+ return ;
102+ }
61103 const dataGrid = document . createElement ( 'fluent-data-grid' ) as DataGrid ;
62104 dataGrid . generateHeader = 'sticky' ;
63105 dataGrid . rowsData = parsedValidationResult . map ( ( error , index ) => ( {
0 commit comments