├── TenonAccessibilityChecker ├── Resources │ ├── custom.ico │ ├── Images_1.png │ ├── custom32.ico │ ├── activity-large.gif │ └── custom_16x16.png ├── packages.config ├── TenonAccessibilityCheckerDialog.xaml ├── TenonAccessibilityChecker.csproj.DotSettings.user ├── TenonAccessibilityChecker.csproj.user ├── TenonAccessibilityCheckerDialog.xaml.cs ├── license.txt ├── Properties │ └── AssemblyInfo.cs ├── PkgCmdId.cs ├── TenonAccessibilityBrowserExtension.js ├── Guids.cs ├── ErrorResultSet.cs ├── source.extension.vsixmanifest ├── GlobalSuppressions.cs ├── TaskManager.cs ├── TenonAccessibilityBrowserExtension.cs ├── Intellisense │ └── browserlink.intellisense.js ├── TenonAccessibilityChecker.vsct ├── TenonModal.xaml.cs ├── contents.resx ├── TenonModal.xaml ├── contents.Designer.cs ├── TenonAccessibilityChecker.csproj └── TenonAccessibilityCheckerPackage.cs ├── packages ├── repositories.config └── Newtonsoft.Json.6.0.8 │ ├── Newtonsoft.Json.6.0.8.nupkg │ ├── lib │ ├── net20 │ │ └── Newtonsoft.Json.dll │ ├── net35 │ │ └── Newtonsoft.Json.dll │ ├── net40 │ │ └── Newtonsoft.Json.dll │ ├── net45 │ │ └── Newtonsoft.Json.dll │ ├── netcore45 │ │ └── Newtonsoft.Json.dll │ ├── portable-net40+sl5+wp80+win8+wpa81 │ │ └── Newtonsoft.Json.dll │ └── portable-net45+wp80+win8+wpa81+aspnetcore50 │ │ └── Newtonsoft.Json.dll │ └── tools │ └── install.ps1 ├── LICENSE ├── TenonAccessibilityChecker.sln ├── README.md └── SECURITY.md /TenonAccessibilityChecker/Resources/custom.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/TenonAccessibilityChecker/Resources/custom.ico -------------------------------------------------------------------------------- /TenonAccessibilityChecker/Resources/Images_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/TenonAccessibilityChecker/Resources/Images_1.png -------------------------------------------------------------------------------- /TenonAccessibilityChecker/Resources/custom32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/TenonAccessibilityChecker/Resources/custom32.ico -------------------------------------------------------------------------------- /TenonAccessibilityChecker/Resources/activity-large.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/TenonAccessibilityChecker/Resources/activity-large.gif -------------------------------------------------------------------------------- /TenonAccessibilityChecker/Resources/custom_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/TenonAccessibilityChecker/Resources/custom_16x16.png -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.8/Newtonsoft.Json.6.0.8.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/packages/Newtonsoft.Json.6.0.8/Newtonsoft.Json.6.0.8.nupkg -------------------------------------------------------------------------------- /TenonAccessibilityChecker/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.8/lib/net20/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/packages/Newtonsoft.Json.6.0.8/lib/net20/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.8/lib/net35/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/packages/Newtonsoft.Json.6.0.8/lib/net35/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.8/lib/net40/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/packages/Newtonsoft.Json.6.0.8/lib/net40/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.8/lib/net45/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/packages/Newtonsoft.Json.6.0.8/lib/net45/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.8/lib/netcore45/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/packages/Newtonsoft.Json.6.0.8/lib/netcore45/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.8/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/packages/Newtonsoft.Json.6.0.8/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.8/lib/portable-net45+wp80+win8+wpa81+aspnetcore50/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/AccCheckerExtensionForVS/HEAD/packages/Newtonsoft.Json.6.0.8/lib/portable-net45+wp80+win8+wpa81+aspnetcore50/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TenonAccessibilityCheckerDialog.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TenonAccessibilityChecker.csproj.DotSettings.user: -------------------------------------------------------------------------------- 1 | 2 | A1026BAC-968D-41B2-AB76-E160165F13AA/f:contents.resx -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TenonAccessibilityChecker.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Program 5 | C:\Program Files %28x86%29\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe 6 | /rootsuffix Exp 7 | 8 | 9 | Program 10 | C:\Program Files %28x86%29\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe 11 | /rootsuffix Exp 12 | 13 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TenonAccessibilityCheckerDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Shapes; 14 | 15 | namespace Microsoft.TenonAccessibilityChecker 16 | { 17 | /// 18 | /// Interaction logic for TenonAccessibilityCheckerDialog.xaml 19 | /// 20 | public partial class TenonAccessibilityCheckerDialog : Window 21 | { 22 | public TenonAccessibilityCheckerDialog() 23 | { 24 | InitializeComponent(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Microsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/license.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Microsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /TenonAccessibilityChecker/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Resources; 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("TenonAccessibilityChecker")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("Microsoft")] 14 | [assembly: AssemblyProduct("TenonAccessibilityChecker")] 15 | [assembly: AssemblyCopyright("")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | [assembly: ComVisible(false)] 19 | [assembly: CLSCompliant(false)] 20 | [assembly: NeutralResourcesLanguage("en-US")] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Revision and Build Numbers 30 | // by using the '*' as shown below: 31 | 32 | [assembly: AssemblyVersion("0.9.0.0")] 33 | [assembly: AssemblyFileVersion("0.9.*.0")] 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30723.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TenonAccessibilityChecker", "TenonAccessibilityChecker\TenonAccessibilityChecker.csproj", "{A1026BAC-968D-41B2-AB76-E160165F13AA}" 7 | EndProject 8 | Global 9 | GlobalSection(TeamFoundationVersionControl) = preSolution 10 | SccNumberOfProjects = 2 11 | SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} 12 | SccTeamFoundationServer = https://twcdot.visualstudio.com/defaultcollection 13 | SccProjectUniqueName0 = TenonAccessibilityChecker\\TenonAccessibilityChecker.csproj 14 | SccProjectName0 = TenonAccessibilityChecker 15 | SccLocalPath0 = TenonAccessibilityChecker 16 | SccLocalPath1 = . 17 | EndGlobalSection 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|Any CPU = Debug|Any CPU 20 | Release|Any CPU = Release|Any CPU 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {A1026BAC-968D-41B2-AB76-E160165F13AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {A1026BAC-968D-41B2-AB76-E160165F13AA}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {A1026BAC-968D-41B2-AB76-E160165F13AA}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {A1026BAC-968D-41B2-AB76-E160165F13AA}.Release|Any CPU.Build.0 = Release|Any CPU 27 | EndGlobalSection 28 | GlobalSection(SolutionProperties) = preSolution 29 | HideSolutionNode = FALSE 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/PkgCmdId.cs: -------------------------------------------------------------------------------- 1 | /*------------------------------------------- START OF LICENSE ----------------------------------------- 2 | HTML Accessibility Checker 3 | Copyright (c) Microsoft Corporation 4 | All rights reserved. 5 | MIT License 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | ----------------------------------------------- END OF LICENSE ------------------------------------------*/ 10 | 11 | // PkgCmdID.cs 12 | // MUST match PkgCmdID.h 13 | 14 | namespace Microsoft.TenonAccessibilityChecker 15 | { 16 | static class PkgCmdId 17 | { 18 | public const uint CmdidMyTenonCommand = 0x100; 19 | public const uint CmdidMyBrowserExtension = 0x101; 20 | }; 21 | } -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TenonAccessibilityBrowserExtension.js: -------------------------------------------------------------------------------- 1 | /*------------------------------------------- START OF LICENSE ----------------------------------------- 2 | HTML Accessibility Checker 3 | Copyright (c) Microsoft Corporation 4 | All rights reserved. 5 | MIT License 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | ----------------------------------------------- END OF LICENSE ------------------------------------------*/ 10 | 11 | /// JS2085,JS3092 12 | (function (browserLink, $) { 13 | return { 14 | onConnected: function () { // Optional. Is called when a connection is established 15 | var data = document.documentElement.outerHTML; 16 | browserLink.invoke("SendText", data); 17 | } 18 | }; 19 | }); -------------------------------------------------------------------------------- /TenonAccessibilityChecker/Guids.cs: -------------------------------------------------------------------------------- 1 | /*------------------------------------------- START OF LICENSE ----------------------------------------- 2 | HTML Accessibility Checker 3 | Copyright (c) Microsoft Corporation 4 | All rights reserved. 5 | MIT License 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | ----------------------------------------------- END OF LICENSE ------------------------------------------*/ 10 | 11 | // Guids.cs 12 | // MUST match guids.h 13 | using System; 14 | 15 | namespace Microsoft.TenonAccessibilityChecker 16 | { 17 | static class GuidList 18 | { 19 | public const string GuidTenonAccessibilityCheckerPkgString = "3c650eb5-91b6-4984-a205-290d34fd67ae"; 20 | public const string GuidTenonAccessibilityCheckerCmdSetString = "5e621bbb-fc26-4ade-9a02-a533c042267d"; 21 | 22 | public static readonly Guid GuidTenonAccessibilityCheckerCmdSet = new Guid(GuidTenonAccessibilityCheckerCmdSetString); 23 | }; 24 | } -------------------------------------------------------------------------------- /TenonAccessibilityChecker/ErrorResultSet.cs: -------------------------------------------------------------------------------- 1 | /*------------------------------------------- START OF LICENSE ----------------------------------------- 2 | HTML Accessibility Checker 3 | Copyright (c) Microsoft Corporation 4 | All rights reserved. 5 | MIT License 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | ----------------------------------------------- END OF LICENSE ------------------------------------------*/ 10 | 11 | namespace Microsoft.TenonAccessibilityChecker 12 | { 13 | /// 14 | /// Error List collection class 15 | /// 16 | public class ErrorResultSet 17 | { 18 | public int Certainty { get; set; } 19 | 20 | public string ErrorTitle { get; set; } 21 | 22 | public string ErrorDescription { get; set; } 23 | 24 | public string Line { get; set; } 25 | 26 | public string Column { get; set; } 27 | 28 | public string Referencelink { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tenon HTML Accessibility Checker 6 | The Tenon’s HTML Accessibility Checker service makes it easier for developers to detect and resolve common accessibility issues within their HTML-based user interfaces. It takes more than static code analysis to create great experiences for people with permanent or situational disabilities; there is no tool today that fully automates accessibility standards like WCAG 2.0 or ensures a great experience. However, there is no reason to ship code with accessibility issues that can be detected automatically. 7 | http://tenon.io 8 | license.txt 9 | This an Alpha version of the Tenon HTML Accessibility Checker. 10 | Resources\custom32.ico 11 | Resources\custom32.ico 12 | Accessibility; HTML; Checker; Code Analysis 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Accessibility Checker Extension for Visual Studio 3 | 4 | The Tenon HTML Accessibility Checker makes it easier for Visual Studio developers to detect and resolve common accessibility issues with their HTML-based user interfaces. It takes more than static code analysis to create great experiences for people with permanent or situational disabilities. However, there is no reason to ship code with accessibility issues that can be detected automatically. This checker is one of many tools designed to help developers ship better code. 5 | 6 | ## Contribute 7 | 8 | There are many way to contribute to this project: 9 | * Submit new features or fixes (see "Legal stuff" below). 10 | * Submit bugs and verify fixes that are checked in. 11 | * Review source code changes. 12 | * Engage other contributors. 13 | * Comment on the relevant Visual Studio Blog. 14 | * Review the solution in the Visual Studio Gallery. 15 | 16 | 17 | ## Please leverage the code! 18 | 19 | Leverage the code to create new projects. We implemented some interesting features in this solution including: 20 | * Implementing the browser link extension to exchange information between Visual Studio and multiple browsers (so that we can evaluate dynamic HTML rather than raw code) 21 | * Implementing context-specific menu options on the Visual Studio Solution Explorer 22 | * Integrating a RESTful service with Visual Studio 23 | * Integrating results directly into the Visual Studio Error List 24 | 25 | We published this source under an MIT liscense so that you can leverage any of these patterns. 26 | 27 | 28 | ##Documentation 29 | 30 | * You can read more about the Tenon HTML Accessibility Checker on the (Visual Studio blog.)[http://blogs.msdn.com/b/visualstudio/archive/2015/03/03/improving-html-accessibility-with-visual-studio-extensions.aspx] 31 | * You can read about Tenon and the Tenon API at [http://tenon.io] 32 | * You can download the compiled extension directly from the (Visual Studio Gallery)[https://visualstudiogallery.msdn.microsoft.com/0ad320bc-80e4-402a-bf2b-d6c23a3a6730] 33 | 34 | 35 | ## Legal stuff 36 | 37 | If you want to contribute code (please do!) you will need to complete a Contributor License Agreement (CLA). Briefly, this agreement testifies that you are granting us permission to use the submitted change according to the terms of the project's license, and that the work being submitted is under appropriate copyright. 38 | 39 | Please submit a Contributor License Agreement (CLA) before submitting a pull request. You may visit https://cla.microsoft.com to sign digitally. Be sure to include your github user name along with the agreement. Once we have received the signed CLA, we'll review the request. -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. Project-level 3 | // suppressions either have no target or are given a specific target 4 | // and scoped to a namespace, type, member, etc. 5 | // 6 | // To add a suppression to this file, right-click the message in the 7 | // Error List, point to "Suppress Message(s)", and click "In Project 8 | // Suppression File". You do not need to add suppressions to this 9 | // file manually. 10 | 11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")] 12 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tenon", Scope = "type", Target = "Microsoft.TenonAccessibilityChecker.TenonModal")] 13 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "Tenon", Scope = "resource", Target = "Microsoft.TenonAccessibilityChecker.contents.resources")] 14 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "abb", Scope = "resource", Target = "Microsoft.TenonAccessibilityChecker.contents.resources")] 15 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "api", Scope = "resource", Target = "Microsoft.TenonAccessibilityChecker.contents.resources")] 16 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "php", Scope = "resource", Target = "Microsoft.TenonAccessibilityChecker.contents.resources")] 17 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "tenon", Scope = "resource", Target = "Microsoft.TenonAccessibilityChecker.contents.resources")] 18 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "tenonkey", Scope = "resource", Target = "Microsoft.TenonAccessibilityChecker.contents.resources")] 19 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tenon")] 20 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tenon", Scope = "type", Target = "Microsoft.TenonAccessibilityChecker.TenonAccessibilityBrowserExtensionFactory")] 21 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tenon", Scope = "type", Target = "Microsoft.TenonAccessibilityChecker.TenonAccessibilityBrowserExtension")] 22 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tenon", Scope = "type", Target = "Microsoft.TenonAccessibilityChecker.TenonAccessibilityCheckerPackage")] 23 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tenon", Scope = "member", Target = "Microsoft.TenonAccessibilityChecker.TenonAccessibilityCheckerPackage.#TenonStatusCode")] 24 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tenon", Scope = "member", Target = "Microsoft.TenonAccessibilityChecker.TenonAccessibilityCheckerPackage.#TenonErrorMessage")] 25 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Referencelink", Scope = "member", Target = "Microsoft.TenonAccessibilityChecker.ErrorResultSet.#Referencelink")] 26 | -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.8/tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | # open json.net splash page on package install 4 | # don't open if json.net is installed as a dependency 5 | 6 | try 7 | { 8 | $url = "http://james.newtonking.com/json/install?version=" + $package.Version 9 | $dte2 = Get-Interface $dte ([EnvDTE80.DTE2]) 10 | 11 | if ($dte2.ActiveWindow.Caption -eq "Package Manager Console") 12 | { 13 | # user is installing from VS NuGet console 14 | # get reference to the window, the console host and the input history 15 | # show webpage if "install-package newtonsoft.json" was last input 16 | 17 | $consoleWindow = $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow]) 18 | 19 | $props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor ` 20 | [System.Reflection.BindingFlags]::NonPublic) 21 | 22 | $prop = $props | ? { $_.Name -eq "ActiveHostInfo" } | select -first 1 23 | if ($prop -eq $null) { return } 24 | 25 | $hostInfo = $prop.GetValue($consoleWindow) 26 | if ($hostInfo -eq $null) { return } 27 | 28 | $history = $hostInfo.WpfConsole.InputHistory.History 29 | 30 | $lastCommand = $history | select -last 1 31 | 32 | if ($lastCommand) 33 | { 34 | $lastCommand = $lastCommand.Trim().ToLower() 35 | if ($lastCommand.StartsWith("install-package") -and $lastCommand.Contains("newtonsoft.json")) 36 | { 37 | $dte2.ItemOperations.Navigate($url) | Out-Null 38 | } 39 | } 40 | } 41 | else 42 | { 43 | # user is installing from VS NuGet dialog 44 | # get reference to the window, then smart output console provider 45 | # show webpage if messages in buffered console contains "installing...newtonsoft.json" in last operation 46 | 47 | $instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor ` 48 | [System.Reflection.BindingFlags]::NonPublic) 49 | 50 | $consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor ` 51 | [System.Reflection.BindingFlags]::NonPublic) 52 | 53 | if ($instanceField -eq $null -or $consoleField -eq $null) { return } 54 | 55 | $instance = $instanceField.GetValue($null) 56 | 57 | if ($instance -eq $null) { return } 58 | 59 | $consoleProvider = $consoleField.GetValue($instance) 60 | if ($consoleProvider -eq $null) { return } 61 | 62 | $console = $consoleProvider.CreateOutputConsole($false) 63 | 64 | $messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor ` 65 | [System.Reflection.BindingFlags]::NonPublic) 66 | if ($messagesField -eq $null) { return } 67 | 68 | $messages = $messagesField.GetValue($console) 69 | if ($messages -eq $null) { return } 70 | 71 | $operations = $messages -split "==============================" 72 | 73 | $lastOperation = $operations | select -last 1 74 | 75 | if ($lastOperation) 76 | { 77 | $lastOperation = $lastOperation.ToLower() 78 | 79 | $lines = $lastOperation -split "`r`n" 80 | 81 | $installMatch = $lines | ? { $_.StartsWith("------- installing...newtonsoft.json ") } | select -first 1 82 | 83 | if ($installMatch) 84 | { 85 | $dte2.ItemOperations.Navigate($url) | Out-Null 86 | } 87 | } 88 | } 89 | } 90 | catch 91 | { 92 | try 93 | { 94 | $pmPane = $dte2.ToolWindows.OutputWindow.OutputWindowPanes.Item("Package Manager") 95 | 96 | $selection = $pmPane.TextDocument.Selection 97 | $selection.StartOfDocument($false) 98 | $selection.EndOfDocument($true) 99 | 100 | if ($selection.Text.StartsWith("Installing 'Newtonsoft.Json ")) 101 | { 102 | $dte2.ItemOperations.Navigate($url) | Out-Null 103 | } 104 | } 105 | catch 106 | { 107 | # stop potential errors from bubbling up 108 | # worst case the splash page won't open 109 | } 110 | } 111 | 112 | # still yolo -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TaskManager.cs: -------------------------------------------------------------------------------- 1 | /*------------------------------------------- START OF LICENSE ----------------------------------------- 2 | HTML Accessibility Checker 3 | Copyright (c) Microsoft Corporation 4 | All rights reserved. 5 | MIT License 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | ----------------------------------------------- END OF LICENSE ------------------------------------------*/ 10 | using System; 11 | using Microsoft.VisualStudio.Shell; 12 | using Microsoft.VisualStudio.Shell.Interop; 13 | using System.Globalization; 14 | 15 | namespace Microsoft.TenonAccessibilityChecker 16 | { 17 | /// 18 | /// Helper class to write error to visual studio error list. 19 | /// 20 | public static class TaskManager 21 | { 22 | private static ErrorListProvider ErrorListProvider; 23 | 24 | /// 25 | /// Constructor. 26 | /// 27 | /// 28 | public static void Initialize(IServiceProvider serviceProvider) 29 | { 30 | ErrorListProvider = new ErrorListProvider(serviceProvider); 31 | } 32 | 33 | /// 34 | ///Clear the errors in the Visual Studio error List 35 | /// 36 | public static void ClearErrors() 37 | { 38 | ErrorListProvider.Tasks.Clear(); 39 | } 40 | 41 | /// 42 | /// Focus the visual studio error list 43 | /// 44 | public static void ShowErrorList() 45 | { 46 | ErrorListProvider.BringToFront(); 47 | } 48 | 49 | /// 50 | /// Add error helper method 51 | /// 52 | /// 53 | /// 54 | /// 55 | public static void AddError(ErrorResultSet message, string fileName,IVsHierarchy hierarchyItem) 56 | { 57 | AddTask(message, TaskErrorCategory.Error, fileName, hierarchyItem); 58 | } 59 | 60 | /// 61 | /// Add Warning helper method 62 | /// 63 | /// 64 | /// 65 | /// 66 | public static void AddWarning(ErrorResultSet message, string fileName,IVsHierarchy hierarchyItem) 67 | { 68 | AddTask(message, TaskErrorCategory.Warning, fileName, hierarchyItem); 69 | } 70 | 71 | /// 72 | /// This Method writes errors to visual studio 73 | /// 74 | /// 75 | /// 76 | /// 77 | /// 78 | private static void AddTask(ErrorResultSet message, TaskErrorCategory category, string filedetails, IVsHierarchy hierarchyItem) 79 | { 80 | ErrorListProvider.Tasks.Add(new ErrorTask 81 | { 82 | Category = TaskCategory.User, 83 | ErrorCategory = category, 84 | Text = message.ErrorDescription + " (" +message.Referencelink +")", 85 | HierarchyItem = hierarchyItem, 86 | Column = string.IsNullOrEmpty(message.Column) ? 0 : Int32.Parse(message.Column, CultureInfo.InvariantCulture), 87 | Line = string.IsNullOrEmpty(message.Line) ? 0 : Int32.Parse(message.Line, CultureInfo.InvariantCulture), 88 | Document = filedetails 89 | }); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TenonAccessibilityBrowserExtension.cs: -------------------------------------------------------------------------------- 1 | /*------------------------------------------- START OF LICENSE ----------------------------------------- 2 | HTML Accessibility Checker 3 | Copyright (c) Microsoft Corporation 4 | All rights reserved. 5 | MIT License 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | ----------------------------------------------- END OF LICENSE ------------------------------------------*/ 10 | 11 | using System.ComponentModel.Composition; 12 | using System.IO; 13 | using System.Windows; 14 | using Microsoft.VisualStudio.Web.BrowserLink; 15 | using Microsoft.VisualStudio.Shell.Interop; 16 | using Microsoft.VisualStudio.Shell; 17 | 18 | namespace Microsoft.TenonAccessibilityChecker 19 | { 20 | [Export(typeof(IBrowserLinkExtensionFactory))] 21 | public class TenonAccessibilityBrowserExtensionFactory : IBrowserLinkExtensionFactory 22 | { 23 | public BrowserLinkExtension CreateExtensionInstance(BrowserLinkConnection connection) 24 | { 25 | return new TenonAccessibilityBrowserExtension(); 26 | } 27 | 28 | public string GetScript() 29 | { 30 | using (Stream stream = GetType().Assembly.GetManifestResourceStream("Microsoft.TenonAccessibilityChecker.TenonAccessibilityBrowserExtension.js")) 31 | using (StreamReader reader = new StreamReader(stream)) 32 | { 33 | return reader.ReadToEnd(); 34 | } 35 | } 36 | } 37 | 38 | public class TenonAccessibilityBrowserExtension : BrowserLinkExtension 39 | { 40 | private string connectionURL { get; set; } 41 | 42 | private IVsHierarchy projectHierarchy { get; set; } 43 | 44 | public override void OnConnected(BrowserLinkConnection connection) 45 | { 46 | IVsSolution solution = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution; 47 | 48 | IVsHierarchy hierarchy1 =null; 49 | 50 | if (connection.Project != null) 51 | { 52 | int hr = solution.GetProjectOfUniqueName(connection.Project.UniqueName, out hierarchy1); 53 | } 54 | 55 | projectHierarchy = hierarchy1; 56 | connectionURL = connection.Url.ToString(); 57 | } 58 | 59 | [BrowserLinkCallback] // This method can be called from JavaScript 60 | public void SendText(string message) 61 | { 62 | if (!TenonAccessibilityCheckerPackage.TenonBrowserLinkSetting) 63 | { 64 | TenonModal.InvokedFromBrowser = true; 65 | TenonModal.RenderedContent = message; 66 | 67 | // close all the open TenonAccessibility dialogs 68 | CloseAllWindows(); 69 | 70 | var dialog = new TenonModal(); 71 | 72 | TenonAccessibilityCheckerPackage.ItemFullPath = string.Empty; 73 | TenonAccessibilityCheckerPackage.Hierarchy = null; 74 | dialog.Topmost = true; 75 | TenonAccessibilityCheckerPackage.ItemFullPath = connectionURL; 76 | TenonAccessibilityCheckerPackage.Hierarchy = projectHierarchy; 77 | 78 | //Show the tenon modal browser dialog 79 | dialog.ShowDialog(); 80 | } 81 | } 82 | 83 | /// 84 | /// close the browser extension modal window. 85 | /// 86 | private static void CloseAllWindows() 87 | { 88 | //ensure only one modal dialog is open at a time for that page. 89 | for (int intCounter = Application.Current.Windows.Count - 1; intCounter > 0; intCounter--) 90 | { 91 | var window = Application.Current.Windows[intCounter]; 92 | if (window != null) window.Close(); 93 | } 94 | } 95 | 96 | } 97 | } -------------------------------------------------------------------------------- /TenonAccessibilityChecker/Intellisense/browserlink.intellisense.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | var bl = { 5 | 6 | "invoke": function () { 7 | /// 8 | /// Calls a server method defined in the Visual Studio BrowserLink extension. 9 | /// The name of the server method 10 | /// 11 | /// 12 | /// Calls a server method defined in the Visual Studio BrowserLink extension and sends data. 13 | /// The name of the server method 14 | /// An object to send as a parameter of the server method. 15 | /// 16 | }, 17 | 18 | "invokeAsync": function () { 19 | /// 20 | /// Calls a server method defined in the Visual Studio BrowserLink extension. 21 | /// The name of the server method 22 | /// 23 | /// 24 | /// 25 | /// Calls a server method defined in the Visual Studio BrowserLink extension. 26 | /// The name of the server method 27 | /// An object to send as a parameter of the server method. 28 | /// 29 | /// 30 | }, 31 | 32 | /// The isolated BrowserLink JSON object. 33 | "json": JSON, 34 | 35 | 36 | "log": function () { 37 | /// 38 | /// Logs a message to the browser console. 39 | /// The message to log. 40 | /// 41 | }, 42 | 43 | /// The server-side source mapping data. 44 | "sourceMapping": { 45 | "canMapToSource": function () { 46 | /// 47 | /// Checks if the specified DOM element can be mapped to server source. 48 | /// The DOM element to test against server-side mapping. 49 | /// 50 | /// 51 | }, 52 | 53 | "getCompleteRange": function () { 54 | /// 55 | /// Checks if the specified DOM element can be mapped to server source. 56 | /// The DOM element to test against server-side mapping. 57 | /// 58 | /// 59 | }, 60 | 61 | "getElementAtPosition": function () { 62 | /// 63 | /// Checks if the specified DOM element can be mapped to server source. 64 | /// The absolute path to the source file. 65 | /// The position in the source file. 66 | /// 67 | /// 68 | }, 69 | 70 | "getStartTagRange": function () { 71 | /// 72 | /// Checks if the specified DOM element can be mapped to server source. 73 | /// The DOM element to test against server-side mapping. 74 | /// 75 | /// 76 | }, 77 | 78 | "selectCompleteRange": function () { 79 | /// 80 | /// Checks if the specified DOM element can be mapped to server source. 81 | /// The DOM element to test against server-side mapping. 82 | /// 83 | }, 84 | 85 | "selectStartTagRange": function () { 86 | /// 87 | /// Checks if the specified DOM element can be mapped to server source. 88 | /// The DOM element to test against server-side mapping. 89 | /// 90 | }, 91 | 92 | /// Contains information about the browser and connection. 93 | "initializationData": { 94 | 95 | /// The name of the connected browser. 96 | "appName": "", 97 | 98 | /// The ID of the SignalR connection to Visual Studio. 99 | "requestId": "", 100 | }, 101 | } 102 | }; 103 | 104 | var sourceMap = function () { 105 | return { 106 | /// The absolute file path of the file containing the element on disk. 107 | "sourcePath": "", 108 | 109 | /// The start position of the DOM element in the 'sourcePath' file. 110 | "startPosition": 1, 111 | 112 | /// The length of the DOM element in the 'sourcePath' file. 113 | "length": 1, 114 | } 115 | }; 116 | 117 | var Promise = function () { 118 | return { 119 | "continueWith": function () { 120 | /// 121 | /// Is called when the server replies with a value. 122 | /// 123 | /// 124 | /// The return value from the server. 125 | /// 126 | /// 127 | /// 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TenonAccessibilityChecker.vsct: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 57 | 58 | 67 | 68 | 75 | 76 | 77 | 78 | 79 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TenonModal.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.PlatformUI; 2 | using System; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Security.Principal; 6 | using System.Text.RegularExpressions; 7 | using System.Threading.Tasks; 8 | using System.Windows; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Navigation; 12 | 13 | namespace Microsoft.TenonAccessibilityChecker 14 | { 15 | /// 16 | /// Interaction logic for TenonModal.xaml 17 | /// 18 | public sealed partial class TenonModal : DialogWindow 19 | { 20 | private string _providedTenonkey; 21 | private string _selectedLevel; 22 | private string _selectedCertainity; 23 | public static string RenderedContent { get; set; } 24 | public static bool InvokedFromBrowser { get; set; } 25 | 26 | public TenonModal() 27 | { 28 | InitializeComponent(); 29 | 30 | //Get the TenonKey from stored in users's machine. 31 | TextBox1.Text = ReadTenonKey(); 32 | } 33 | 34 | /// 35 | /// validte the specified tenon key 36 | /// 37 | /// 38 | private bool IsValidTenonKey() 39 | { 40 | LoadingStack.Visibility = Visibility.Visible; 41 | 42 | if (string.IsNullOrEmpty(TextBox1.Text)) 43 | { 44 | LoadingStack.Visibility = Visibility.Hidden; 45 | Spinner.Visibility = Visibility.Hidden; 46 | this.processingtext.Visibility = Visibility.Hidden; 47 | this.ErrorPlaceholder.Visibility = Visibility.Visible; 48 | this.ErrorPlaceholder.Text = contents.TenonKeyValidatioMessage; 49 | this.ErrorPlaceholder.Foreground = new SolidColorBrush(Colors.Red); 50 | return false; 51 | } 52 | return true; 53 | } 54 | 55 | /// 56 | /// set the user inputs 57 | /// 58 | private void SetUserInputs() 59 | { 60 | LoadingStack.Visibility = Visibility.Visible; 61 | Spinner.Visibility = Visibility.Visible; 62 | processingtext.Visibility = Visibility.Visible; 63 | ErrorPlaceholder.Visibility = Visibility.Hidden; 64 | _providedTenonkey = TextBox1.Text; 65 | _selectedCertainity = ComboBox1.Text; 66 | _selectedLevel = ComboBox2.Text; 67 | this.BtnValidate.IsEnabled = false; 68 | } 69 | 70 | /// 71 | /// Method invoked on click of validate button 72 | /// 73 | /// 74 | /// 75 | private void btnValidate_Click(object sender, RoutedEventArgs e) 76 | { 77 | //Tenon key mandatory validation 78 | if(!IsValidTenonKey()) return; 79 | 80 | //collect the user inputs 81 | SetUserInputs(); 82 | 83 | //initate the process 84 | ProcessRequest(); 85 | } 86 | 87 | private void ProcessRequest() 88 | { 89 | // Create a background task for your work 90 | var task = Task.Factory.StartNew(InvokeTenonService); 91 | 92 | // When it completes, have it hide (on the UI thread), Spinner element 93 | task.ContinueWith(t => 94 | { 95 | Spinner.Visibility = Visibility.Hidden; 96 | this.BtnCancel.Content = contents.OKMessage; 97 | this.BtnValidate.Visibility = Visibility.Hidden; 98 | this.processingtext.Visibility = Visibility.Hidden; 99 | this.ErrorPlaceholder.Visibility = Visibility.Visible; 100 | this.ErrorPlaceholder.Text = TenonAccessibilityCheckerPackage.TenonErrorMessage; 101 | this.ErrorPlaceholder.Foreground = TenonAccessibilityCheckerPackage.TenonStatusCode == contents.TenonApiResponseSuccess ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Red); 102 | 103 | // Sets the focused element in focusScope1 focusScope1 is a StackPanel. 104 | FocusManager.SetFocusedElement(ErrorPlaceholder, ErrorPlaceholder); 105 | 106 | // Gets the focused element for focusScope 1 107 | IInputElement focusedElement = FocusManager.GetFocusedElement(ErrorPlaceholder); 108 | focusedElement.Focus(); 109 | }, 110 | TaskScheduler.FromCurrentSynchronizationContext() 111 | ); 112 | } 113 | 114 | private void btnCancel_Click(object sender, RoutedEventArgs e) 115 | { 116 | //Close the window. 117 | Close(); 118 | } 119 | 120 | /// 121 | /// Method which invokes the tenonapi service 122 | /// 123 | private void InvokeTenonService() 124 | { 125 | // Read the file contents 126 | var content = (InvokedFromBrowser ? RenderedContent : File.ReadAllText(TenonAccessibilityCheckerPackage.ItemFullPath)); 127 | 128 | //Get json from tenon io 129 | var str = TenonAccessibilityCheckerPackage.GetJson(_providedTenonkey, content, _selectedCertainity, _selectedLevel); 130 | 131 | //Parse API response 132 | var errorcollection = TenonAccessibilityCheckerPackage.ParseJson(str); 133 | 134 | if (TenonAccessibilityCheckerPackage.TenonStatusCode == contents.TenonApiResponseSuccess) 135 | { 136 | //write errors to visual studio error window 137 | TenonAccessibilityCheckerPackage.WriteErrors(TenonAccessibilityCheckerPackage.ItemFullPath, 138 | TenonAccessibilityCheckerPackage.Hierarchy, errorcollection); 139 | 140 | //Store the tenon key in c drive of your machine 141 | PersistTenonKey(_providedTenonkey); 142 | } 143 | } 144 | 145 | /// 146 | /// Read the Tenon Key stored in your locale file in C drive. 147 | /// 148 | /// string 149 | private static string ReadTenonKey() 150 | { 151 | string dataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); 152 | dataPath = Path.Combine(dataPath, "TenonAccessibilityChecker", "TenonKey.txt"); 153 | return File.Exists(dataPath) ? File.ReadAllText(dataPath) : string.Empty; 154 | } 155 | 156 | /// 157 | /// Store the provided tenon Key in C Drive of your local machine. 158 | /// 159 | /// 160 | private static void PersistTenonKey(string tenonkey) 161 | { 162 | string dataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); 163 | dataPath = Path.Combine(dataPath, "TenonAccessibilityChecker", "TenonKey.txt"); 164 | 165 | // If the directory doesn't exist, create it. 166 | if (!Directory.Exists(Path.GetDirectoryName(dataPath))) 167 | { 168 | Directory.CreateDirectory(Path.GetDirectoryName(dataPath)); 169 | } 170 | 171 | //Write the tenon key to your local file 172 | File.WriteAllText(dataPath, tenonkey); 173 | } 174 | private void OnCloseCmdExecuted(object sender, ExecutedRoutedEventArgs e) 175 | { 176 | this.Close(); 177 | } 178 | 179 | private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e) 180 | { 181 | Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); 182 | e.Handled = true; 183 | } 184 | 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/contents.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Errors and Warnings 122 | 123 | 124 | AAA 125 | 126 | 127 | TenonIo 128 | 129 | 130 | Confidence 131 | 132 | 133 | Learn about the Tenon service and how features like Confidence scores can be used 134 | 135 | 136 | https://tenon.io/documentation/understanding-request-parameters.php 137 | 138 | 139 | https://tenon.io/ 140 | 141 | 142 | http://tenon.io/register.php 143 | 144 | 145 | Success. Tenon found {0} errors and {1} warnings. Results are displayed in the Error List. 146 | 147 | 148 | Title: \n{0}\n \nStandards:{1} \nDescription:\n{2}\n \nCode Snippet:\n{3} 149 | 150 | 151 | 200 152 | 153 | 154 | https://tenon.io/api/ 155 | 156 | 157 | Error Occurred. 158 | 159 | 160 | OK 161 | 162 | 163 | Tenon Key is Mandatory. 164 | 165 | 166 | f06c7b9200dbf58e7bf7f0889b5abb97 167 | 168 | 169 | "{0} ({1})" 170 | 171 | -------------------------------------------------------------------------------- /TenonAccessibilityChecker/TenonModal.xaml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | Learn about the 22 | Tenon service and how features like Confidence scores can be used to tune the results (e.g. to find hard to discover issues and eliminate the false positives). 23 | 24 | 25 | Membership is free and registration takes about a minute. 26 | 27 | 28 | 29 | 30 | Register to get a tenon key... 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |