{{ setTitle( translate('ERROR.TITLE') ) }}
5 | 6 |{{ 'ERROR.INTRO' | translate }}
7 | 8 |-
9 |
- {{ 'ERROR.SUGGESTION1' | translate }} 10 | 13 | 16 |
├── .bowerrc
├── .editorconfig
├── .eslintrc.js
├── .gitattributes
├── .github
└── workflows
│ └── run-tests.yml
├── .gitignore
├── .nvmrc
├── CODE_OF_CONDUCT.md
├── Gruntfile.js
├── LICENSE
├── README.md
├── app
├── .buildignore
├── dummy.html
├── images
│ ├── copy.png
│ ├── fail.png
│ ├── pass.png
│ ├── w3c.svg
│ ├── wai.svg
│ └── wip.png
├── index.html
├── locale
│ ├── EN
│ │ ├── audit.json
│ │ ├── common.json
│ │ ├── download.json
│ │ ├── earl.json
│ │ ├── error.json
│ │ ├── explore.json
│ │ ├── html_report.json
│ │ ├── import.json
│ │ ├── nav.json
│ │ ├── open.json
│ │ ├── report.json
│ │ ├── sample.json
│ │ ├── save.json
│ │ ├── scope.json
│ │ └── start.json
│ └── NL
│ │ ├── audit.json
│ │ ├── common.json
│ │ ├── download.json
│ │ ├── earl.json
│ │ ├── error.json
│ │ ├── explore.json
│ │ ├── html_report.json
│ │ ├── nav.json
│ │ ├── open.json
│ │ ├── report.json
│ │ ├── sample.json
│ │ ├── save.json
│ │ ├── scope.json
│ │ └── start.json
├── scripts
│ ├── app.js
│ ├── app.language.js
│ ├── app.run.js
│ ├── controllers
│ │ ├── evaluation
│ │ │ ├── audit.js
│ │ │ ├── audit
│ │ │ │ ├── criteria.js
│ │ │ │ └── samplePages.js
│ │ │ ├── explore.js
│ │ │ ├── report.js
│ │ │ ├── sample.js
│ │ │ └── scope.js
│ │ ├── footer.js
│ │ ├── import.js
│ │ ├── navigation.js
│ │ ├── open.js
│ │ ├── report
│ │ │ ├── findings.js
│ │ │ └── score.js
│ │ ├── save.js
│ │ ├── start.js
│ │ ├── stepButtons.js
│ │ └── viewReport.js
│ ├── directives
│ │ ├── autoResize.js
│ │ ├── buttonCollapse.js
│ │ ├── collapse.js
│ │ ├── criterion
│ │ │ ├── criterionBody.js
│ │ │ ├── earlAssert.js
│ │ │ ├── macroResults.js
│ │ │ ├── pageResults.js
│ │ │ ├── pageSelect.js
│ │ │ └── resultDescription.js
│ │ ├── dropdownToggle.js
│ │ ├── evaluate
│ │ │ ├── iconButton.js
│ │ │ ├── infoButton.js
│ │ │ ├── infoField.js
│ │ │ ├── inputPages.js
│ │ │ └── techSelect.js
│ │ ├── fullReport.js
│ │ ├── shyPlaceholder.js
│ │ └── successCriterion.js
│ ├── filters
│ │ ├── getUrl.js
│ │ ├── rdfToLabel.js
│ │ ├── selectedCasesOnly.js
│ │ └── txtToHtml.js
│ ├── libs
│ │ ├── jsonld.js
│ │ └── promise-1.0.0.js
│ ├── models
│ │ ├── AppState.js
│ │ ├── class
│ │ │ ├── CriterionAssert.js
│ │ │ ├── Page.js
│ │ │ └── TestCaseAssert.js
│ │ ├── evaluation.js
│ │ ├── evaluation
│ │ │ ├── audit.js
│ │ │ ├── currentUser.js
│ │ │ ├── explore.js
│ │ │ ├── report.js
│ │ │ ├── sample.js
│ │ │ └── scope.js
│ │ ├── export.js
│ │ ├── import.js
│ │ ├── import
│ │ │ └── importV1.js
│ │ └── wcag2spec.js
│ ├── services
│ │ ├── changeLanguage.js
│ │ ├── context
│ │ │ ├── evalContextV1.js
│ │ │ ├── evalContextV2.js
│ │ │ └── evalContextV3.js
│ │ ├── directivePlugin.js
│ │ ├── evalLoader.js
│ │ ├── evalWindow.js
│ │ ├── fileReader.js
│ │ ├── helpers
│ │ │ └── isObjectLiteral.js
│ │ ├── knownTechnologies.js
│ │ ├── pkgData.js
│ │ ├── reportStorage.js
│ │ ├── showSave.js
│ │ ├── toggleCriterionText.js
│ │ ├── types.js
│ │ └── wcagSpecIdMap.js
│ └── templates.js
├── styles
│ ├── animation.scss
│ ├── bootstrap-extend.scss
│ ├── evaluate.scss
│ ├── hint.scss
│ ├── main.scss
│ ├── report.scss
│ └── wizard.scss
├── views
│ ├── directives
│ │ ├── buttonCollapse.html
│ │ ├── criterion
│ │ │ ├── criterionBody.html
│ │ │ ├── earlAssert.html
│ │ │ ├── macroResults.html
│ │ │ ├── pageResults.html
│ │ │ ├── pageSelect.html
│ │ │ └── resultDescription.html
│ │ ├── evaluate
│ │ │ ├── iconButton.html
│ │ │ ├── infoButton.html
│ │ │ ├── infoField.html
│ │ │ ├── inputPages.html
│ │ │ └── techSelect.html
│ │ ├── fullReport.html
│ │ └── successCriterion.html
│ ├── error.html
│ ├── evaluation
│ │ ├── audit.html
│ │ ├── audit
│ │ │ ├── criteria-tools.html
│ │ │ ├── criteria.html
│ │ │ └── samplePages.html
│ │ ├── explore.html
│ │ ├── report.html
│ │ ├── sample.html
│ │ ├── scope.html
│ │ └── stepbar.html
│ ├── footer.html
│ ├── import.html
│ ├── messages.html
│ ├── navigation.html
│ ├── open.html
│ ├── report
│ │ ├── findings.html
│ │ ├── sample.html
│ │ ├── scope.html
│ │ └── score.html
│ ├── save.html
│ ├── start.html
│ ├── step-buttons.html
│ └── viewReport.html
└── wcag2spec
│ ├── wcag2-en.json
│ └── wcag2-nl.json
├── bower.json
├── changelog.md
├── docs
├── EARL+JSON-LD.md
├── contribute.md
├── developer-docs.md
├── examples
│ ├── example_export_v1.ld.json
│ ├── example_export_v2.ld.json
│ ├── example_export_v3.ld.json
│ └── importable-json
│ │ ├── axe-earl-report-example.json
│ │ └── example_simple_import.ld.json
└── translation.md
├── karma-e2e.conf.js
├── karma.conf.js
├── package-lock.json
├── package.json
├── plugin-guide.md
├── structure redesign
├── stylelint.config.js
├── test
├── .eslintrc.js
├── dummyData
│ ├── v1-data.js
│ ├── v2-data.js
│ └── v3-data.js
├── runner.html
├── setup.js
└── spec
│ ├── controllers
│ └── evaluation
│ │ ├── audit
│ │ ├── criteria.js
│ │ └── samplePages.js
│ │ ├── explore.js
│ │ ├── report.js
│ │ ├── sample.js
│ │ └── scope.js
│ ├── models
│ ├── export.js
│ ├── import.js
│ └── wcag2spec.js
│ ├── services
│ └── evalContext.js
│ └── v2-data.js
└── w3c.json
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "app/bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | [*.json]
15 | indent_size = 4
16 |
17 | # We recommend you to keep these unchanged
18 | end_of_line = lf
19 | charset = utf-8
20 | trim_trailing_whitespace = true
21 | insert_final_newline = true
22 |
23 | [*.md]
24 | trim_trailing_whitespace = false
25 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ESlint configuration for WCAG-EM Reporting tool
3 | * ---
4 | * Intended to increase readability of code with rules adding
5 | * whitespace, empty lines and newlines to the code.
6 | *
7 | * @type {Object}
8 | */
9 | module.exports = {
10 | env: {
11 | browser: true,
12 | es6: true,
13 | jquery: true
14 | },
15 | extends: 'standard',
16 | globals: {
17 | Atomics: 'readonly',
18 | SharedArrayBuffer: 'readonly',
19 | angular: 'readonly'
20 | },
21 | parserOptions: {
22 | ecmaVersion: 2018
23 | },
24 | rules: {
25 |
26 | /*
27 | ** Array notation:
28 | ** [1] or
29 | ** [
30 | ** 1,
31 | ** 2
32 | ** ]
33 | */
34 | 'array-bracket-newline': [
35 | 'error',
36 | {
37 | multiline: true,
38 | minItems: 2
39 | }
40 | ],
41 | 'array-element-newline': [
42 | 'error',
43 | 'always'
44 | ],
45 |
46 | /**
47 | * Function notation:
48 | *
49 | * fn(a, b) {…}
50 | *
51 | * or
52 | *
53 | * fn(
54 | * a,
55 | * b,
56 | * c
57 | * ) {…}
58 | */
59 | 'function-paren-newline': [
60 | 'error',
61 | 'multiline-arguments'
62 | ],
63 |
64 | /**
65 | * Chained call notation like:
66 | *
67 | * object.method();
68 | *
69 | * or
70 | *
71 | * object
72 | * .method()
73 | * .method();
74 | */
75 | 'newline-per-chained-call': [
76 | 'error',
77 | {
78 | ignoreChainWithDepth: 1
79 | }
80 | ],
81 |
82 | /**
83 | * One statement at a time like:
84 | *
85 | * var a;
86 | * var b;
87 | *
88 | * not
89 | *
90 | * var a; var b;
91 | */
92 | 'max-statements-per-line': [
93 | 'error',
94 | {
95 | max: 1
96 | }
97 | ],
98 |
99 | /**
100 | * Semicolon usage always add after statement endings like:
101 | *
102 | * execute();
103 | */
104 | semi: [
105 | 'error',
106 | 'always'
107 | ]
108 | }
109 | };
110 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
--------------------------------------------------------------------------------
/.github/workflows/run-tests.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | pull_request: {}
5 | push:
6 | branches: [master]
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: ubuntu-latest
12 |
13 | strategy:
14 | matrix:
15 | node-version: [16.3.0]
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Build
20 | uses: actions/setup-node@v1
21 | with:
22 | node-version: ${{ matrix.node-version }}
23 | - run: sudo chmod -R a+w /var/lib/gems # makes writable by all
24 | - run: sudo chmod -R a+w /usr/local/bin # makes writable by all
25 | - run: npm ci
26 | - run: npm install -g bower grunt-cli
27 | - run: bower install
28 | - run: npm test
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .tmp
3 | .sass-cache
4 | app/bower_components
5 | app/styles/bootstrap
6 | dist/
7 | .sublime-project
8 | .sublime-workspace
9 | .dropbox
10 | desktop.ini
11 | Thumbs.db
12 | /.project
13 | npm-debug.log
14 | .DS_Store
15 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/*
2 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/).
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The W3C SOFTWARE NOTICE AND LICENSE (W3C)
2 |
3 | https://www.w3.org/Consortium/Legal/copyright-software
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | _Note: this tool is replaced by_ [WCAG-EM Report Tool, version 3.0.0](https://w3.org/WAI/eval/report-tool) (the code lives in the [wai-wcag-em-report-tool](https://github.com/w3c/wai-wcag-em-report-tool/) repository)
2 |
3 | WCAG-EM Report tool is an assistant that takes the user
4 | through the process of evaluating the accessibility of a
5 | website, using the WCAG-EM Evaluation Methodology. The Report
6 | Tool runs entirely on the client and so it can be used offline
7 | and in any server configuration available to you.
8 |
9 | The Report Tool does not save files to a server or in local
10 | storage. Rather, load and save functions are available for
11 | storing an evaluation to your local file system.
12 |
13 | Important references:
14 |
15 | -
The chainlink icon opens the web page in a separate browser window.",
20 | "INTRO": "Record the outcome from evaluating the web pages selected in the previous step. Compare the results between the structured page and randomly selected pages, and if needed, adjust the selected sample in the previous step. More guidance on this step is provided in WCAG-EM Step 4: Audit the Selected Sample.
Note: For each WCAG 2 success criteria, you can enter 'Results for the entire sample' and you can enter results for individual web pages. You can choose to enter either or both. To enter individual results, select the web page(s) under 'Sample to Evaluate' (in the left column); then under the specific success criteria, select 'Show web pages to enter individual results'",
21 | "LABEL_OUTCOME": "Outcome",
22 | "LABEL_PAGE_HANDLE": "Short page name",
23 | "NO_PAGE_SELECTED": "No pages selected under Sample to Evaluate",
24 | "NO_SAMPLE": "No sample available. Create a sample in step 2 and step 3.",
25 | "NOTE": "Note",
26 | "PRINCIPLE": "Principle",
27 | "RESULTS_FOR": "Results for",
28 | "SAMPLE_FINDINGS": "Results for the entire sample",
29 | "SELECT_ALL": "Select all web pages",
30 | "TESTED": "Tested",
31 | "TITLE": "Step 4: Audit the Selected Sample",
32 | "UNDERSTAND": "Understanding",
33 | "UNTESTED": "{{critCount}} untested"
34 | }
35 |
--------------------------------------------------------------------------------
/app/locale/EN/common.json:
--------------------------------------------------------------------------------
1 | {
2 | "BROWSER_NOT_SUPPORTED": "The web browser you are using does not support some functionality, such as saving and loading reports. You can continue to use the Report Tool with limited functionality. Update or use a different web browser to make use of all functionality of this report tool.",
3 | "WARNING_BEFORE_UNLOAD": "The data you entered is not automatically saved. It will be lost if you close this web browser window. Use the 'Save' link (Ctrl + S or ⌘ S) that is at the top of all pages to save your data in a file locally on your computer, and reload it later to continue working on it.",
4 | "MORE_INFO": "For more information, see {{name}}.",
5 | "HIDE_MESSAGE": "Hide message",
6 | "BTN_INFO": "Info expand",
7 | "BTN_CLOSE_INFO": "Close info",
8 | "YES": "Yes",
9 | "NO": "No",
10 | "CLICK_EXPAND": "Click to show section",
11 | "CLICK_COLLAPSE": "Click to hide section",
12 | "TO_TOP": "Back to top",
13 | "ACTIVE": "Active"
14 | }
--------------------------------------------------------------------------------
/app/locale/EN/download.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Website Accessibility Evaluation Report",
3 | "INTRO": "Below is the evaluation report based on the input that you provided in previous steps. You can go back to previous steps now and change any of this information. You can download the evaluation data so that you can work on it later. (This is the same as the 'Save' functionality.)
This report is intended to be downloaded. You can download the Evaluation Report HTML and CSS files below. You can then change the report content and visual design to meet your needs.",
4 | "DOWNLOAD_REPORT": "Download and customize this report",
5 | "BTN_SAVE_HTML": "Download the evaluation report (HTML)",
6 | "BTN_SAVE_CSS": "Download the report stylesheet (CSS)",
7 | "BTN_SAVE_JSON": "Save the evaluation data (JSON)"
8 | }
--------------------------------------------------------------------------------
/app/locale/EN/earl.json:
--------------------------------------------------------------------------------
1 | {
2 | "PASSED": "Passed",
3 | "FAILED": "Failed",
4 | "CANT_TELL": "Cannot tell",
5 | "NOT_PRESENT": "Not present",
6 | "NOT_CHECKED": "Not checked",
7 | "LEVEL_A": "Level A",
8 | "LEVEL_AA": "Level AA",
9 | "LEVEL_AAA": "Level AAA"
10 | }
--------------------------------------------------------------------------------
/app/locale/EN/error.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Oops! Something went wrong",
3 | "INTRO": "This is not the page you are looking for. Try one of these solutions to solve the problem.",
4 | "SUGGESTION1": "If you typed the URL, make sure it is exactly what it should be.",
5 | "SUGGESTION2": "Go back to the previous page and try again.",
6 | "SUGGESTION3": "Make sure the files you are working from follow the wcag-em format.",
7 | "BUG_REPORT": "To report any bugs or feature suggestions, leave an issue on our Github project page."
8 | }
--------------------------------------------------------------------------------
/app/locale/EN/explore.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Step 2: Explore the Target Website",
3 | "INTRO": "Explore the website to understand its purpose, functionality, and use. This step helps you determine which web pages to use for the evaluation in the next steps. Identify the web technologies used to provide the website and, if you want, take notes on other aspects of the website. Usually it is best to get input from the website owners and developers for this step. More guidance on this step is provided in WCAG-EM Step 2: Explore the Target Website.",
4 | "HD_RELIEDUP_TECH": "Web Technologies Relied Upon",
5 | "INF_RELIEDUP_TECH": "Identify the web technologies relied upon according to WCAG 2 to provide the website. For more information, see WCAG-EM Step 2.d: Identify Web Technologies Relied Upon.
Note: To add other technologies, select 'Others' and use the 'Web Technology' and 'Specification Address (URL)' field. The 'Specification Address (URL)' field should identify the web technology specification.",
6 | "LABEL_TECH": "Web Technology",
7 | "LABEL_TECH_SPEC": "Specification Address (URL)",
8 | "PLH_TECH": "E.g. HTML5, CSS, DOM",
9 | "PLH_TECH_SPEC": "Address (URL) or description for the web technology specification",
10 | "BTN_REMOVE_TECH": "Remove technology",
11 | "BTN_ADD_TECH": "Add web technology",
12 | "HD_NOTE_TAKING": "Optional Exploration Notes",
13 | "INF_NOTE_TAKING": "This section lets you record information during your website exploration. These notes are provided in the next step, to help you select a sample of web pages for evaluation. These notes are not included in the final report. They are saved when you save the file, and available when you later reload the file",
14 | "LABEL_ESSENT_FUNC": "Essential functionality of the website",
15 | "INF_ESSENT_FUNC": "You can use this field to take notes about essential functionality of the website. Examples of essential functionality include:
'selecting and purchasing a product from the shop area of the website'
'completing and submitting a form provided on the website'
'registering for an account on the website'
For more information, see WCAG-EM Step 2.b: Identify Essential Functionality of the Website.",
16 | "LABEL_VARIETY_PAGE_TYPES": "Variety of web page types",
17 | "INF_VARIETY_PAGE_TYPES": "You can use this field to take notes about the types (as opposed to instances) of web pages that you find on the web site. This includes notes about different styles, layouts, structures, and functionality provided on the website. For more information, see WCAG-EM Step 2.c: Identify the Variety of Web Page Types.
Note: 'Web pages' include different 'web page states'; see definition of web page states.",
18 | "LABEL_OTHER": "Others..."
19 | }
20 |
--------------------------------------------------------------------------------
/app/locale/EN/html_report.json:
--------------------------------------------------------------------------------
1 | {
2 | "BY" : "Report Creator:",
3 | "COMMISION_BY": "Evaluation Commissioner:",
4 | "HD_SUMMARY": "Summary of the evaluation findings",
5 | "HD_SCOPE": "Scope of the evaluation",
6 | "LABEL_SITE_NAME": "Website name",
7 | "LABEL_SITE_SCOPE": "Scope of the website",
8 | "LABEL_CONFORMANCE_TGT": "Conformance target",
9 | "LABEL_EXTRA_REQUIREMENTS": "Additional evaluation requirements",
10 | "LABEL_SUPPORT_BASE": "Accessibility support baseline",
11 | "LABEL_RELIEDUP_TECH": "Relied upon technologies",
12 | "HD_SCORE": "Overview of audit results",
13 | "RESULTS_OF": "Results of",
14 | "PRINCIPLE": "Principle",
15 | "TOTAL_SCORE": "Total",
16 | "HD_CRITERIA_REPORT": "Detailed audit results",
17 | "LABEL_DESCR": "Findings",
18 | "HD_SAMPLE": "Sample of audited web pages",
19 | "HD_SPECIFICS": "Recording of evaluation specifics",
20 | "HD_DOCS": "Related WCAG 2 resources"
21 | }
22 |
--------------------------------------------------------------------------------
/app/locale/EN/import.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Import a WCAG EARL report",
3 | "INTRO": "If you have used another application to generate a WCAG EARL-report that falls into the scope of this evaluation, you may be able to import these and add them to the evaluation audit result. The file itself should be: JSON-LD parseable, consist of objects in EARL format and evaluation tests should be related to WCAG.",
4 | "LABEL_SELECT_FILE": "Select a JSON-LD file"
5 | }
6 |
--------------------------------------------------------------------------------
/app/locale/EN/nav.json:
--------------------------------------------------------------------------------
1 | {
2 | "MENU": "Menu",
3 | "MENU_IMPORT": "Import",
4 | "MENU_IMPORT_TITLE": "Start EARL report import wizzard",
5 | "MENU_NEW": "New Report",
6 | "MENU_OPEN": "Open",
7 | "MENU_SAVE": "Save",
8 | "MENU_SAVE_TITLE": "Ctrl + S or ⌘ S",
9 | "MENU_RESOURCES": "Key Resources",
10 | "MENU_LANGUAGE": "Language",
11 | "WZRD_LABEL": "Evaluation steps",
12 | "WZRD_START": "Start",
13 | "WZRD_SCOPE": "1. Define Scope",
14 | "WZRD_EXPLORE": "2. Explore Website",
15 | "WZRD_SAMPLE": "3. Select Sample",
16 | "WZRD_AUDIT": "4. Audit Sample",
17 | "WZRD_REPORT": "5. Report Findings",
18 | "WZRD_ACTIVE": "Active",
19 | "WZRD_VIEWREPORT": "View Report",
20 | "PREV_STEP": "Previous step",
21 | "NEXT_STEP": "Next step",
22 | "STEP_START": "Start",
23 | "STEP_SCOPE": "Define Scope",
24 | "STEP_EXPLORE": "Explore Website",
25 | "STEP_SAMPLE": "Select Sample",
26 | "STEP_AUDIT": "Audit Sample",
27 | "STEP_REPORT": "Report Findings",
28 | "STEP_VIEWREPORT": "View Report",
29 | "BTN_BACK_TO_EVAL": "Back"
30 | }
31 |
--------------------------------------------------------------------------------
/app/locale/EN/open.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Open Evaluation Report",
3 | "INTRO": "To reload a saved file, click the 'Find and select the data file' button and locate the JSON file that you previously saved.",
4 | "LABEL_SELECT_FILE": "Find and select the data file",
5 | "MSG_LOADING": "Loading the evaluation, please wait...",
6 | "BTN_LOAD_FILE": "Load data from selected file"
7 | }
--------------------------------------------------------------------------------
/app/locale/EN/report.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Step 5: Report the Evaluation Findings",
3 | "INTRO": "Provide additional information about the evaluation that you want included in the report. The evaluation findings that you entered in the previous step are included below under 'Detailed audit results' for review and to help you write the executive summary. More guidance on this step is provided in WCAG-EM Step 5: Report the Evaluation Findings.",
4 | "LABEL_TITLE": "Report title",
5 | "TITLE_PREFIX": "Report for",
6 | "INF_TITLE": "Provide a title for the website accessibility evaluation report. For example:
'Evaluation Report for Example Organization'
'Webshop Accessibility Analysis and Repair Suggestions'",
7 | "LABEL_COMMISSIONER": "Evaluation commissioner",
8 | "INF_COMMISSIONER": "The person, team of people, organization, in-house department, or other entity that commissioned the evaluation.",
9 | "LABEL_CREATOR": "Evaluator",
10 | "INF_CREATOR": "The person, team of people, organization, in-house department, or other entity responsible for carrying out the evaluation.",
11 | "LABEL_DATE": "Evaluation date",
12 | "INF_DATE": "Provide the completion date or duration dates of this evaluation. You can use any date format.",
13 | "LABEL_SUMMARY": "Executive summary",
14 | "INF_SUMMARY": "Provide a brief summary of the evaluation findings to give an overview on the results. For example, describe the overall accessibility of the website and key observations you made during the evaluation, such as frequently occurring issues and patterns.",
15 | "LABEL_SPECIFICS": "Record of evaluation specifics (optional)",
16 | "INF_SPECIFICS": "WCAG-EM suggests that you archive the web pages audited. For more information, see WCAG-EM Step 5.b: Record the Evaluation Specifics. You can use this text field to record the evaluation tools, web browsers, assistive technologies, other software, and methods used for the evaluation. What you enter here will be included in the generated report. After you download the report, you could delete or edit this information in the HTML file before submitting the report.",
17 | "HD_CRITERIA_REPORT": "Detailed audit results"
18 | }
--------------------------------------------------------------------------------
/app/locale/EN/sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Step 3: Select a Representative Sample",
3 | "INTRO": "Select web pages for evaluation. The notes that you took during exploration in the previous step are provided here, to help you select the web pages. Ensure that the web pages selected are representative of the target website. More guidance on this step is provided in WCAG-EM Step 3: Select a Representative Sample.",
4 | "HD_STRUCT_SAMPLE": "Structured Sample",
5 | "HD_ESSENT_FUNC": "Essential functionality (optional notes from previous step)",
6 | "HD_VARIETY_PAGE_TYPES": "Variety of web page types (optional notes from previous step)",
7 | "HD_STRUCT_SAMPLE_SUB": "Structured Sample Web Pages",
8 | "INF_STRUCT_SAMPLE": "Select web pages that reflect all identified (1) common web pages, (2) essential functionality, (3) types of web pages, (4) web technologies relied upon, and (5) other relevant web pages. For more information, see WCAG-EM Step 3.a: Include a Structured Sample.
Note: 'Web pages' include different 'web page states'; see definition of web page states.",
9 | "HD_RANDOM_SAMPLE": "Randomly Selected Sample",
10 | "INF_RAND_SAMPLE": "Randomly select sample web pages; select 10% of the structured sample selected above. For more information, see WCAG-EM Step 3.b: Include a Randomly Selected Sample.
Note: 'Web pages' include different 'web page states'; see definition of web page states.",
11 | "RAND_SAMPLE_LENGTH": "Based on your structured sample of {{total}} web pages, choose at least {{count}} randomly selected web pages (to meet the 10% requirement in WCAG-EM).",
12 | "LABEL_HANDLE": "Short name",
13 | "LABEL_PAGE": "Address (URL) or description",
14 | "NO_PAGES_DEFINED": "No pages defined for this list",
15 | "ITEM": "Web page",
16 | "PLH_TITLE": "Identifier for the web page",
17 | "PLH_PAGE_URL": "Address (URL) or description of how to get there",
18 | "BTN_ADD_PAGE": "Add web page",
19 | "BTN_REMOVE_PAGE": "Remove page",
20 | "STRUCTURED_PAGE": "Structured page",
21 | "RANDOM_PAGE": "Random page",
22 | "SAMPLE_PAGE": "Sample page"
23 | }
24 |
--------------------------------------------------------------------------------
/app/locale/EN/save.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Save Evaluation Report",
3 | "INTRO": "Use the link below to save the evaluation report information that you have entered in a JSON data file locally on your computer.",
4 | "BTN_DOWNLOAD_DATA_FILE": "Save data file locally to your computer",
5 | "TIPS": "You can save partially-complete reports (and notes) and work on them later. You can open them from any web browser and you can transfer the data file to another computer.
You can Save periodically as you work to avoid losing data if your web browser closes. You can use Windows shortcut keys Ctrl+S or Mac shortcut keys ⌘S to open the Save dialog (or automatically save it in your downloads folder depending on your web browser settings).
When you are done entering your evaluation report information, you can download an HTML file of the completed report from the View Report page."
6 | }
--------------------------------------------------------------------------------
/app/locale/EN/scope.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Step 1: Define the Evaluation Scope",
3 | "INTRO": "Define the overall parameters and scope of the evaluation. Ideally, this is done with the person who commissioned the evaluation (who may or may not be the website owner), to ensure common expectations about the scope of the evaluation. More guidance on this step is provided in WCAG-EM Step 1: Define the Evaluation Scope.",
4 | "LABEL_SITE_NAME": "Website name",
5 | "INF_SITE_NAME": "Provide a name for the website that you would like to evaluate. For example:
'Public Website of Example Organization'
'Webshop of Example Company'
'Intranet of Example University'",
6 | "LABEL_SITE_SCOPE": "Scope of the website",
7 | "INF_SITE_SCOPE_0": "Define the scope of the website, so it is clear which web pages are included in the evaluation. For example:",
8 | "INF_SITE_SCOPE_LI0": "'All web content of the public website of Example Org. located at http://www.example.org'",
9 | "INF_SITE_SCOPE_LI1": "'All web content of the online shop of Example Org. located at http://www.example.org/shop/'",
10 | "INF_SITE_SCOPE_LI2": "'All web content of the mobile version of the public website of Example Org. located at http://m.example.org'",
11 | "INF_SITE_SCOPE_1": "WCAG-EM Step 1.a: Define the Scope of the Website",
12 | "LABEL_WCAG_VERSION": "WCAG Version",
13 | "INFO_WCAG_VERSION": "Select the WCAG version to use. Version 2.1 (default) or 2.0",
14 | "WCAG21": "WCAG 2.1",
15 | "WCAG20": "WCAG 2.0",
16 | "LABEL_CONFORMANCE_TGT": "Conformance target",
17 | "INF_CONF_TGT": "Select a target WCAG 2 conformance level ('A', 'AA', or 'AAA') for the evaluation. For more information, see WCAG-EM Step 1.b: Define the Conformance Target. This selection determines which conformance level filters are active by default in 'step 4: Audit the Sample'.",
18 | "LABEL_SUPPORT_BASE": "Accessibility support baseline",
19 | "INF_SUPPORT_BASE": "Define the web browsers, assistive technologies, and other user agents that will be accessibility supported by the website. For example, 'Internet Explorer (IE) with JAWS', 'FireFox with NVDA', and 'Apple with VoiceOver' could be basic definitions. For more information, see WCAG-EM Step 1.c: Define an Accessibility Support Baseline.",
20 | "LABEL_EXTRA_REQUIREMENTS": "Additional evaluation requirements",
21 | "INF_EXTRA_REQUIREMENTS_0": "Define any additional evaluation requirements. For example:",
22 | "INF_EXTRA_REQUIREMENTS_LI0": "'The report will include a list of all errors identified by the evaluator, rather than examples only'",
23 | "INF_EXTRA_REQUIREMENTS_LI1": "'The report will include a description of the problem and repair suggestions for any errors listed'",
24 | "INF_EXTRA_REQUIREMENTS_LI2": "'The evaluation will cover all web pages and web content of the website, rather than a selected sample only'",
25 | "INF_EXTRA_REQUIREMENTS_1": "WCAG-EM Step 1.d: Define Additional Evaluation Requirements"
26 | }
27 |
--------------------------------------------------------------------------------
/app/locale/EN/start.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "WCAG-EM Report Tool",
3 | "SUBTITLE": "Website Accessibility Evaluation Report Generator",
4 | "INTRO_HD": "What this tool does",
5 | "INTRO_1": "This tool helps you generate a report according to the Website Accessibility Conformance Evaluation Methodology (WCAG-EM). It does not perform any accessibility checks. It helps you follow the steps of WCAG-EM, to generate a structured report from the input that you provide. It is designed for experienced evaluators who know Web Content Accessibility Guidelines (WCAG) 2 and are somewhat familiar with WCAG-EM. For an introduction to WCAG-EM, see the WCAG-EM Overview.",
6 | "INTRO_2": "Note: This tool does not automatically save the information that you enter. To save your data in a file locally on your computer, use Windows shortcut keys Ctrl+S or Mac shortcut keys {{mac}} to open the Save dialog. (Or the 'Save' link at the top of the page will open the Save Evaluation Report page and from there the 'Save data file locally to your computer' link will open the Save dialog.)",
7 | "USAGE_HD": "How this tool works",
8 | "USAGE_LI1": "All functionality provided by this tool is now loaded and running locally in your web browser. You don't need an Internet connection beyond this point. When you close your web browser window, any unsaved data is lost.",
9 | "USAGE_LI2": "All input that you provide through this tool is recorded as JSON data in the background (in your web browser, not on any server). You can Save periodically as you work to avoid losing data if your web browser closes.",
10 | "USAGE_LI3": "You can save partially-complete reports and work on them later. To reload a saved file, use the 'Open' link at the top and find the file that you previously saved.",
11 | "USAGE_LI4": "Links that are not part of the navigation or functionality (links to external resources) open in a new web browser windows.",
12 | "TIPS_HD": "Tips for using this tool",
13 | "TIPS_LI1": "You can go back and forth between the steps in any order. None of the fields are required.",
14 | "TIPS_LI2": "To get more information about a field, select the {{info}} icon next to the field label.",
15 | "TIPS_LI3": "The tool provides your report as HTML and CSS files. You can download these files from the 'View Report' page. You can then change the report content and visual design.",
16 | "TIPS_LI4": "You can include in your report WCAG 2 success criteria beyond the conformance target. For example, the website is only required to meet Level AA, yet you want to also include Level AAA success criteria in the report. In step 4, use the level filter to show higher level criteria. Any criteria with a result will always be included in the report."
17 | }
18 |
--------------------------------------------------------------------------------
/app/locale/NL/audit.json:
--------------------------------------------------------------------------------
1 | {
2 | "ASSERTION_RESULT_DESCRIPTION_LABEL": "Bevindingen",
3 | "ASSERTION_RESULT_DESCRIPTION_PLACEHOLDER": "Bevindingen uit de evaluatie",
4 | "BTN_COLLAPSE_PAGES": "Invoer voor per-pagina-resultaten verbergen",
5 | "BTN_COMPLETE_SELECTED": "Markeer selectie als voltooid",
6 | "BTN_EXPAND_PAGES": "Invoer voor per-pagina-resultaten weergeven",
7 | "BTN_OPEN_SELECTED": "Open geselecteerde pagina's",
8 | "BTN_SHOW_TEXT": "criteriumtekst weergeven",
9 | "BTN_UNCOMPLETE_SELECTED": "Markeer selectie als onvoltooid",
10 | "CLICK_TO_DELETE": "Klik om te verwijderen",
11 | "FILTER_LEVEL_LEGEND": "Toon conformiteitsniveau",
12 | "FILTER_NEW_IN_WCAG21": "Added in WCAG 2.1",
13 | "FILTER_VERSION_LEGEND": "Toon versie",
14 | "FILTER": "Toon",
15 | "HD_CRITERIA": "Succescriteria om te evalueren",
16 | "HD_SAMPLE_SELECT": "Te evalueren sample",
17 | "HOW_TO": "Hoe te voldoen",
18 | "INF_AUDIT_CRITERIA": "In dit onderdeel vindt u de WCAG 2.0 succescriteria. Gebruik de filter om succescriteria van niveaus (A, AA en AAA) te tonen of verbergen. Kies 'Voldoende', 'Onvoldoende', 'Niet van toepassing', en 'Onbekend' als resultaat. U kunt bevindingen en andere opmerkingen uit de evaluatie in het tekstveld invullen.",
19 | "INF_AUDIT_SAMPLE": "In dit onderdeel vindt u de webpagina's uit de vorige stap. De webpagina's die in dit onderdeel geselecteerd worden zullen onder 'Invoer voor per-pagina-resultaten weergeven' worden weergegeven wanneer deze uitgeklapt is in het onderdeel 'Succescriteria om te evalueren'. U kunt per pagina, of meerdere webpagina's tegelijk weergeven. Met het linkicoon kunt u pagina's in een nieuw venster openen.",
20 | "INTRO": "Beschrijf de resultaten uit de evaluatie van de webpagina's geselecteerd in de vorige stap. Vergelijk de resultaten tussen de geordende pagina's en de willekeurig gekozen pagina's, en waar nodig pas de geselecteerde sample in de vorige stap aan. Meer informatie over deze stap is te vinden in WCAG-EM Stap 4: Toets de sample.
Opmerking: Voor elk WCAG 2.0 succescriterium, kunt u resultaten voor de volledige sample invullen, evenals resultaten voor specifieke pagina's. Om individuele resultaten in te vullen, selecteer pagina's onder 'Te evalueren sample' (in de linker kolom); vervolgens onder de succescriteria, kies 'Invoer voor per-pagina-resultaten weergeven'",
21 | "LABEL_OUTCOME": "Uitkomst",
22 | "LABEL_PAGE_HANDLE": "Korte paginatitel",
23 | "NO_PAGE_SELECTED": "Geen pagina geselecteerd onder 'Te evalueren sample'",
24 | "NO_SAMPLE": "Geen sample beschikbaar. Maak een sample in stap 2 en stap 3.",
25 | "NOTE": "Opmerking",
26 | "PRINCIPLE": "Principe",
27 | "RESULTS_FOR": "Uitkomst voor",
28 | "SAMPLE_FINDINGS": "Resultaat van de hele sample",
29 | "SELECT_ALL": "Selecteer alle pagina's",
30 | "TESTED": "Getest",
31 | "TITLE": "Stap 4: Toets de sample",
32 | "UNDERSTAND": "Toelichting",
33 | "UNTESTED": "{{critCount}} niet getest"
34 | }
35 |
--------------------------------------------------------------------------------
/app/locale/NL/common.json:
--------------------------------------------------------------------------------
1 | {
2 | "BROWSER_NOT_SUPPORTED": "Enkele functionaliteiten zijn niet door uw webbrowser ondersteund, zoals het opslaan en openen van rapporten. Je kunt de rapport tool met beperkte functionaliteit gebruiken. Update of gebruik een andere webbrowser om van alle functionaliteiten in de Report Tool gebruik te kunnen maken.",
3 | "WARNING_BEFORE_UNLOAD": "Uw data worden niet automatisch opgeslagen. Wanneer het venster van uw web browser sluit is de data verloren. Gebruik de 'Opslaan' link (Ctrl + S of ⌘ S) bovenaan iedere pagina om uw data in een bestand op uw locale computer te bewaren en open deze later om door te werken.",
4 | "MORE_INFO": "Voor meer informatie, zie {{name}}.",
5 | "HIDE_MESSAGE": "Verberg bericht",
6 | "BTN_INFO": "Info uitklappen",
7 | "BTN_CLOSE_INFO": "Sluit info",
8 | "YES": "Ja",
9 | "NO": "Nee",
10 | "CLICK_EXPAND": "Klik om sectie te tonen",
11 | "CLICK_COLLAPSE": "Klik om sectie te verbergen",
12 | "TO_TOP": "Naar boven"
13 | }
--------------------------------------------------------------------------------
/app/locale/NL/download.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Website Toegankelijkheid Evaluatie Rapport",
3 | "INTRO": "Hieronder vindt u het evaluatierapport gebaseerd op de gegevens die u in vorige stappen heeft ingevuld. U kunt teruggaan naar vorige stappen voor verdere aanpassingen. U kunt de evaluatiedata downloaden zodat u hier later aan door kunt werken. (Hetzelfde als bij 'Opslaan'.)
Dit rapport is bedoeld als download. U kunt de HTML en CSS bestanden van het rapport hieronder downloaden. Daarna kunt u de presentatie en de inhoud van het rapport verder bewerken.",
4 | "DOWNLOAD_REPORT": "Download het rapport",
5 | "BTN_SAVE_HTML": "Download het evaluatierapport (HTML)",
6 | "BTN_SAVE_CSS": "Download de stylesheet van het rapport (CSS)",
7 | "BTN_SAVE_JSON": "Bewaar de evaluatiedata (JSON)"
8 | }
--------------------------------------------------------------------------------
/app/locale/NL/earl.json:
--------------------------------------------------------------------------------
1 | {
2 | "PASSED": "Voldoende",
3 | "FAILED": "Onvoldoende",
4 | "CANT_TELL": "Onbekend",
5 | "NOT_PRESENT": "Niet van toepassing",
6 | "NOT_CHECKED": "Niet getoetst",
7 | "LEVEL_A": "Niveau A",
8 | "LEVEL_AA": "Niveau AA",
9 | "LEVEL_AAA": "Niveau AAA"
10 | }
--------------------------------------------------------------------------------
/app/locale/NL/error.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Oeps! Er ging iets mis",
3 | "INTRO": "U bent op de verkeerde plek beland. Probeer een van de volgende oplossingen om het probleem op te lossen.",
4 | "SUGGESTION1": "Als u de URL heeft getypet, controleer of deze juist is.",
5 | "SUGGESTION2": "Ga terug naar de vorige pagina en probeer het nog eens.",
6 | "SUGGESTION3": "Zorg dat de bestanden waarmee u werkt het wcag-em format volgen.",
7 | "BUG_REPORT": "Om een bug of suggestie voor nieuwe functionaliteit te rapporteren laat een issue achter op onze Github-projectpagina."
8 | }
--------------------------------------------------------------------------------
/app/locale/NL/explore.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Stap 2: Verken de te onderzoeken website",
3 | "INTRO": "Verken de website om zo het doel en de functie van de website te achterhalen. Deze stap helpt u te bepalen welke webpagina's te bekijken in de volgende stappen. Achterhaal welke webtechnologieën in de website zijn gebruikt, en als u wilt, neem notities over belangrijke aspecten van de website. Het is gebruikelijk om voor deze stap input van de eigenaar en ontwikkelaars van de website mee te nemen. Meer informatie over deze stap vindt u in WCAG-EM Stap 2: Verken de te onderzoeken website.",
4 | "HD_RELIEDUP_TECH": "technologieën waarop gesteund wordt",
5 | "INF_RELIEDUP_TECH": "Bepaal op welke webtechnologieën de website steund volgens WCAG 2.0. Voor meer informatie, zie WCAG-EM Stap 2.d: Identificeer technologieën waarop gesteund wordt.
Merk op: om andere technologieën toe te voegen, kies 'Anders' and gebruik de velden 'Webtechnologie' en 'Specificatie adres (URL)'. In het veld 'Specificatie adres (URL)' dient te verwijzen naar de specificatie van de technologie.",
6 | "LABEL_TECH": "Webtechnologie",
7 | "LABEL_TECH_SPEC": "Specificatie adres (URL)",
8 | "PLH_TECH": "Bv. HTML5, CSS, DOM",
9 | "PLH_TECH_SPEC": "Locatie (URL) of instructie naar de specificatie",
10 | "BTN_REMOVE_TECH": "Webtechnologie verwijderen",
11 | "BTN_ADD_TECH": "Webtechnologie toevoegen",
12 | "HD_NOTE_TAKING": "Eventuele aantekeningen uit verkenning",
13 | "INF_NOTE_TAKING": "In dit onderdeel kunt u aantekeningen zetten die u maakt bij het verkennen van de website. Deze aantekeningen kunt u in de volgende stap gebruiken om webpagina's voor de sample te selecteren voor de evaluatie. Deze notities komen niet in het eindrapport. Wel worden ze bewaard wanneer u het onderzoek opslaat en het bestand later opent.",
14 | "LABEL_ESSENT_FUNC": "Functionaliteiten essentieel voor de website",
15 | "INF_ESSENT_FUNC": "Gebruik dit veld om essentiële functionaliteiten van de website te noteren. Voorbeelden van essentiële functionaliteiten zijn:
'Selecteer en bestel een product uit de webwinkel van de website'
'Afronden en versturen van een formulier op de website'
'Een account op de website registreren'
Meer informatie vindt u in WCAG-EM Stap 2.b: Identificeer essentiële functionaliteiten van de website",
16 | "LABEL_VARIETY_PAGE_TYPES": "Diverse paginatypes",
17 | "INF_VARIETY_PAGE_TYPES": "Gebruik dit veld om bij te houden welke diverse typen webpagina's u op de website heeft gevonden. Het gaat hier bijvoorbeeld om verschillende (opmaak)stijlen, layouts, indelingen en functionaliteiten op de website. Meer informatie vindt u in WCAG-EM Stap 2.c: Identificeer diverse paginatypes.
Merk op: Een 'webpagina' kan in verschillende 'webpagina-toestanden' bestaan; zie de definitie webpagina-toestanden.",
18 | "LABEL_OTHER": "Anders..."
19 | }
--------------------------------------------------------------------------------
/app/locale/NL/html_report.json:
--------------------------------------------------------------------------------
1 | {
2 | "BY" : "Rapport auteur",
3 | "COMMISION_BY": "Evaluatie opdrachtgever",
4 | "HD_SUMMARY": "Samenvatting Evaluatieresultaten",
5 | "HD_SCOPE": "Scope van de evaluatie",
6 | "LABEL_SITE_NAME": "Website naam",
7 | "LABEL_SITE_SCOPE": "Scope van de website",
8 | "LABEL_CONFORMANCE_TGT": "Conformiteitsdoel",
9 | "LABEL_EXTRA_REQUIREMENTS": "Verdere evaluatievereisten",
10 | "LABEL_SUPPORT_BASE": "Basisniveau van toegankelijkheid ondersteund",
11 | "LABEL_RELIEDUP_TECH": "technologieën waarop gesteund wordt",
12 | "HD_SCORE": "Overzicht toetsresultaten",
13 | "RESULTS_OF": "Resultaat voor",
14 | "PRINCIPLE": "Principe",
15 | "TOTAL_SCORE": "Totaal",
16 | "HD_CRITERIA_REPORT": "Uitgebreide toetsresultaten",
17 | "LABEL_DESCR": "Bevindingen",
18 | "HD_SAMPLE": "Sample met getoetste webpagina's",
19 | "HD_SPECIFICS": "Onderbouwing van de evaluatie",
20 | "HD_DOCS": "Informatie over WCAG 2.0"
21 | }
--------------------------------------------------------------------------------
/app/locale/NL/nav.json:
--------------------------------------------------------------------------------
1 | {
2 | "MENU": "Menu",
3 | "MENU_RESOURCES": "Relevante links",
4 | "MENU_NEW": "Nieuw rapport",
5 | "MENU_OPEN": "Open",
6 | "MENU_SAVE": "Opslaan",
7 | "MENU_SAVE_TITLE": "Ctrl + S of ⌘ S",
8 | "MENU_LANGUAGE": "Taalkeuze",
9 | "WZRD_LABEL": "Evaluatiestappen",
10 | "WZRD_START": "Start",
11 | "WZRD_SCOPE": "1. Bepaal Scope",
12 | "WZRD_EXPLORE": "2. Verken Website",
13 | "WZRD_SAMPLE": "3. Selecteer Sample",
14 | "WZRD_AUDIT": "4. Toets Sample",
15 | "WZRD_REPORT": "5. Rapporteer Resultaat",
16 | "WZRD_ACTIVE": "Actief",
17 | "WZRD_VIEWREPORT": "Bekijk Rapport",
18 | "PREV_STEP": "Vorige stap",
19 | "NEXT_STEP": "Volgende stap",
20 | "STEP_START": "Start",
21 | "STEP_SCOPE": "Bepaal scope",
22 | "STEP_EXPLORE": "Verken website",
23 | "STEP_SAMPLE": "Selecteer Sample",
24 | "STEP_AUDIT": "Toets Sample",
25 | "STEP_REPORT": "Rapporteer Resultaat",
26 | "STEP_VIEWREPORT": "Bekijk Rapport",
27 | "BTN_BACK_TO_EVAL": "Terug"
28 | }
--------------------------------------------------------------------------------
/app/locale/NL/open.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Open Evaluatierapport",
3 | "INTRO": "Om een opgeslagen bestand opnieuw te openen, klik op 'Selecteer het evaluatie-databestand', en zoek het JSON bestand op dat u voorheen hebt opgeslagen.",
4 | "LABEL_SELECT_FILE": "Selecteer het evaluatie-databestand",
5 | "MSG_LOADING": "De evaluatie wordt geladen, even geduld a.u.b.",
6 | "BTN_LOAD_FILE": "Open data uit geselecteerd bestand"
7 | }
--------------------------------------------------------------------------------
/app/locale/NL/report.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Stap 5: Evaluatiebevindingen rapporteren",
3 | "INTRO": "Benoem verdere bevindingen uit de evaluatie die u in het rapport wilt hebben. De toetsresultaten uit de vorige stap vindt u onder 'Uitgebreide toetsresultaten' ter review en om u te helpen bij het schrijven van de samenvatting. Meer informatie over deze stap vindt u in WCAG-EM Stap 5: Evaluatiebevindingen rapporteren.",
4 | "LABEL_TITLE": "Rapporttitel",
5 | "TITLE_PREFIX": "Rapportage van",
6 | "INF_TITLE": "Vul hier de titel in van het evaluatierapport van de toegankelijkheid van de website. Bijvoorbeeld:
'Evaluatierapport voor Voorbeeldorganisatie'
'Webshop Toegankelijkheidsanalyse en verbetersuggesties'",
7 | "LABEL_COMMISSIONER": "Evaluatieopdrachtgever",
8 | "INF_COMMISSIONER": "De persoon, het team, de organisatie, het departement of andere entiteit die opdracht voor de evaluatie gaf.",
9 | "LABEL_CREATOR": "Evaluator",
10 | "INF_CREATOR": "De persoon, het team, de organisatie, het departement of andere entiteit verantwoordelijk voor het uitvoeren van de evaluatie.",
11 | "LABEL_DATE": "Evaluatiedatum",
12 | "INF_DATE": "Vul hier de datum in waarop de evaluatie werd afgerond, of de datums waarop de evaluatie plaats vond. U kunt elk datumformaat gebruiken.",
13 | "LABEL_SUMMARY": "Managementsamenvatting",
14 | "INF_SUMMARY": "Geef een korte samenvatting van de bevindingen uit de evaluatie om zo een overzicht van de resultaten te krijgen. Benoem bijvoorbeeld de algehele toegankelijkheid van de website, met enkele concrete voorbeelden uit het onderzoek, zoals de frequentie van bepaalde verbeterpunten.",
15 | "LABEL_SPECIFICS": "Benoem de onderbouwing van de evaluatie (optioneel)",
16 | "INF_SPECIFICS": "WCAG-EM raadt aan dat u de getoetste webpagina's bewaart. Meer informatie hierover vindt u in WCAG-EM Stap 5.b: Benoem de onderbouwing van de evaluatie. Gebruik dit tekstveld tevens om de gebruikte evaluatietools, webbrowsers, hulptechnologieën, andere software en toetsmethodes vast te leggen. Dit zal tevens in het eindrapport staan. U kunt deze informatie na het downloaden van het rapport als HTML-bestand nog bijwerken.",
17 | "HD_CRITERIA_REPORT": "Uitgebreide toetsresultaten"
18 | }
--------------------------------------------------------------------------------
/app/locale/NL/sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Stap 3: Selecteer een representatieve sample",
3 | "INTRO": "Selecteer webpagina's voor de evaluatie. U vindt hier uw aantekeningen uit de vorige stap, om u te helpen webpagina's voor de sample te selecteren. Zorg ervoor dat de gekozen webpagina's representatief zijn voor de te toetsen website. Meer informatie over deze stap vindt u in WCAG-EM Stap 3: Selecteer een representatieve sample.",
4 | "HD_STRUCT_SAMPLE": "Geordende sample",
5 | "HD_ESSENT_FUNC": "Essentiële functionaliteiten (optionele notities uit vorige stap)",
6 | "HD_VARIETY_PAGE_TYPES": "Diverse paginatypes (optionele notities uit vorige stap)",
7 | "HD_STRUCT_SAMPLE_SUB": "Geordende samplepagina's",
8 | "INF_STRUCT_SAMPLE": "Selecteer webpagina's representatief voor alle (1) veelgebruikte webpagina's, (2) essentiële functionaliteiten, (3) typen pagina's, (4) webtechnologieën waarop gesteund wordt, en (5) overige relevante pagina's. Meer informatie vindt u in WCAG-EM Stap 3.a: Gebruik een geordende sample.
Opmerking: 'webpagina's' kunnen in verschillende 'toestanden' (states) bestaan; zie de definitie van webpagina-toestand",
9 | "HD_RANDOM_SAMPLE": "Willekeurige sample",
10 | "INF_RAND_SAMPLE": "Selecteer willekeurig samplepagina's; gebruik 10% van de grootte van de geordende sample. Meer informatie vindt u in WCAG-EM Stap 3.b: Gebruik een willekeurige sample.
Opmerking: 'webpagina's' kunnen in verschillende 'toestanden' (states) bestaan; zie de definitie van webpagina toestand",
11 | "RAND_SAMPLE_LENGTH": "Op basis van de geordende sample van {{total}} webpagina's, selecteer tenminste {{count}} willekeurige webpagina's (om te voldoen aan de 10% eis uit WCAG-EM).",
12 | "LABEL_HANDLE": "korte titel",
13 | "LABEL_PAGE": "Locatie (URL) of instructie",
14 | "NO_PAGES_DEFINED": "Er is geen pagina in deze lijst",
15 | "ITEM": "Webpagina",
16 | "PLH_TITLE": "Identificerende naam voor de webpagina",
17 | "PLH_PAGE_URL": "Locatie (URL) of instructie van het te volgen pad",
18 | "BTN_ADD_PAGE": "Pagina toevoegen",
19 | "BTN_REMOVE_PAGE": "Pagina verwijderen",
20 | "STRUCTURED_PAGE": "Geordende pagina",
21 | "RANDOM_PAGE": "Willekeurige pagina",
22 | "SAMPLE_PAGE": "Samplepagina"
23 | }
--------------------------------------------------------------------------------
/app/locale/NL/save.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Evaluatierapport opslaan",
3 | "INTRO": "Gebruik onderstaande link om de door u ingevoerde gegevens van het evaluatierapport als JSON databestand lokaal op uw computer te bewaren.",
4 | "BTN_DOWNLOAD_DATA_FILE": "Bewaar databestand lokaal op uw computer",
5 | "TIPS": "U kunt onvoltooide rapporten (en aantekeningen) bewaren en hier later aan verder werken. U kunt deze openen in iedere webbrowser en het databestand naar een andere computer sturen.
U dient uw werk regelmatig op te slaan om te voorkomen dat u werk verliest, mocht de webbrowser sluiten. U kunt de sneltoets Ctrl+S voor windows of ⌘S voor Mac gebruiken om het opslaan-scherm te starten (of om automatisch naar uw downloads folder te plaatsen, afhankelijk van uw browserinstellingen).
Wanneer u het evaluatierapport heeft afgerond, kunt u een HTML-bestand met het volledige rapport downloaden de 'Bekijk rapport'-pagina."
6 | }
--------------------------------------------------------------------------------
/app/locale/NL/scope.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "Stap 1: Bepaal de scope van de evaluatie",
3 | "INTRO": "Bepaal de basiseisen en scope van de evaluatie. Dit wordt bij voorkeur gedaan door de opdrachtgever van de evaluatie (dit kan, maar hoeft niet de eigenaar van de website te zijn), om ervoor te zorgen dat de verwachtingen op de opdracht aansluiten. Meer informatie over deze stap vindt u in WCAG-EM Stap 1: Bepaal de scope van de evaluatie.",
4 | "LABEL_SITE_NAME": "Website naam",
5 | "INF_SITE_NAME": "Vul een naam in van de te evalueren website. Bijvoorbeeld:
'Publieke website van Voorbeeld Organisatie'
'Webshop van Voorbeeld Bedrijf'
'Intranet van Voorbeeld Universiteit'",
6 | "LABEL_SITE_SCOPE": "Scope van de website",
7 | "INF_SITE_SCOPE_0": "Leg de scope van de website vast, zodat duidelijk is welke webpagina's binnen de evaluatie vallen. Bijvoorbeeld:",
8 | "INF_SITE_SCOPE_LI0": "'Alle webcontent van de publieke website van Voorbeeld Org. op http://www.example.org'",
9 | "INF_SITE_SCOPE_LI1": "'Alle webcontent van de webwinkel van Voorbeeld Org. op http://www.example.org/shop/'",
10 | "INF_SITE_SCOPE_LI2": "'Alle webcontent op de mobiele versie van de publieke website van Voorbeeld Org. op http://m.example.org'",
11 | "INF_SITE_SCOPE_1": "WCAG-EM Stap 1.a: Definieer de scope van de website",
12 | "LABEL_CONFORMANCE_TGT": "Conformiteitsdoel",
13 | "INF_CONF_TGT": "Bepaal het te behalen WCAG 2.0 conformiteitsniveau ('A', 'AA' of 'AAA') voor de evaluatie. Voor meer informatie, zie WCAG-EM Stap 1.b: Bepaal het conformiteitsdoel. Deze keuze bepaald welke niveaufilters in stap 4 standaard aan zullen staan.",
14 | "LABEL_SUPPORT_BASE": "Basisniveau van toegankelijkheid-ondersteuning",
15 | "INF_SUPPORT_BASE": "Bepaal welke webbrowser, hulptechnologieën en andere user agents door toegankelijkheid ondersteund zijn door de website. Bijvoorbeeld: 'Internet Explorer (IE) met JAWS', 'Firefox met NVDA', en 'iOS met VoiceOver' zou het basisniveau kunnen zijn. Voor meer informatie, zie WCAG-EM Stap 1.c: Bepaal het Basisniveau van toegankelijkheid-ondersteuning.",
16 | "LABEL_EXTRA_REQUIREMENTS": "Verdere onderzoeksvereisten",
17 | "INF_EXTRA_REQUIREMENTS_0": "Bepaal overige onderzoeksvereisten. Bijvoorbeeld:",
18 | "INF_EXTRA_REQUIREMENTS_LI0": "'In het rapport wordt een volledige lijst van de gevonden problemen opgenomen, in plaats van slechts enkele voorbeelden'",
19 | "INF_EXTRA_REQUIREMENTS_LI1": "'In het rapport zal een omschrijving van de problemen gegeven worden, samen met suggesties voor het oplossen van de problemen'",
20 | "INF_EXTRA_REQUIREMENTS_LI2": "'Alle webpagina's en webcontent van de website zullen in de evaluatie getest worden, in plaats van enkel de steekproef",
21 | "INF_EXTRA_REQUIREMENTS_1": "WCAG-EM Stap 1.d: Bepaal verdere onderzoeksvereisten",
22 | "WCAG21": "WCAG 2.1",
23 | "WCAG20": "WCAG 2.0"
24 | }
25 |
--------------------------------------------------------------------------------
/app/locale/NL/start.json:
--------------------------------------------------------------------------------
1 | {
2 | "TITLE": "WCAG-EM Report Tool",
3 | "SUBTITLE": "Website Toegankelijkheid Evaluatie Rapport Generator",
4 | "INTRO_HD": "Wat de tool doet",
5 | "INTRO_1": "Deze tool helpt u bij het maken van rapporten volgens de Website Accessibility Conformance Evaluation Methodology (WCAG-EM). Het voert geen toegankelijkheidstests voor u uit. Het begeleidt je door de stappen van WCAG-EM, om een gestructureerd rapport te genereren op basis van de gegevens die u invult. De tool is ontworpen voor ervaren inspecteurs bekend met Richtlijnen voor Toegankelijkheid van Webcontent (WCAG) 2.0 en met enige kennis van WCAG-EM. U kunt een WCAG-EM introductie vinden in het WCAG-EM Overzicht.",
6 | "INTRO_2": "Let op: Deze tool bewaart niet automatisch uw werk. U kunt uw gegevens lokaal op uw computer bewaren met de sneltoets Ctrl+S in windows, of {{mac}} op Mac. Dit start het opslaan scherm. (U kunt dit ook doen door de 'Opslaan' link bovenaan de pagina te klikken, en vervolgens op de link 'Bewaar databestand lokaal op uw computer' te klikken.)",
7 | "USAGE_HD": "Hoe deze tool werkt",
8 | "USAGE_LI1": "Alle functionaliteit is direct in uw webbrowser beschikbaar. U heeft geen internetverbinding nodig vanaf dit punt. Wanneer u het venster van de webbrowser sluit, raken gegevens die u niet heeft bewaard verloren.",
9 | "USAGE_LI2": "Alle gegevens die u invult worden als JSON data op de achtergrond bewaard (in uw webbrowser, niet op een server). U kunt periodiek opslaan terwijl u werkt, om te voorkomen dat u data verliest mocht uw webbrowser sluiten.",
10 | "USAGE_LI3": "U kunt tussentijdse rapporten bewaren en er later aan verder werken. Klik op de 'Open' link bovenin de pagina en laad daar het bestand dat u eerder hebt opgeslagen.",
11 | "USAGE_LI4": "Links naar externe pagina's (buiten de tool) openen in een nieuw browser venster.",
12 | "TIPS_HD": "Tips om de tool te gebruiken",
13 | "TIPS_LI1": "U kunt heen en weer tussen de stappen schakelen. Geen van de velden is verplicht.",
14 | "TIPS_LI2": "Voor meer informatie over een veld, klik op het {{info}} icoon naast het veld.",
15 | "TIPS_LI3": "De tool creëert uw rapport als HTML en CSS bestanden. U kunt deze bestanden downloaden op de 'Bekijk rapport'-pagina. Daarna kunt u de presentatie en de inhoud van het rapport verder bewerken.",
16 | "TIPS_LI4": "U kunt succescriteria aan uw WCAG 2.0 rapport toevoegen die hoger zijn dan het conformiteitsdoel. Bijvoorbeeld, de website dient aan niveau AA te voldoen, maar u wilt ook enkele AAA criteria in het rapport benoemen. In stap 4 kunt u de niveaufilter gebruiken om succescriteria van een hoger niveau te tonen. Criteria met een ingevuld resultaat zullen altijd in het rapport komen."
17 | }
--------------------------------------------------------------------------------
/app/scripts/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | angular.module('wcagReporter', [
3 | 'ngResource',
4 | 'ngSanitize',
5 | 'ngRoute',
6 | 'ngAnimate',
7 | 'pascalprecht.translate',
8 | 'wert-templates'
9 | ])
10 | .config(function ($routeProvider, $compileProvider) {
11 | $compileProvider
12 | .aHrefSanitizationWhitelist(/^\s*(https?|data|blob):/);
13 |
14 | $routeProvider
15 | .when('/', {
16 | templateUrl: 'views/start.html',
17 | controller: 'StartCtrl'
18 | })
19 | .when('/evaluation/scope', {
20 | templateUrl: 'views/evaluation/scope.html',
21 | controller: 'EvalScopeCtrl'
22 | })
23 | .when('/evaluation/explore', {
24 | templateUrl: 'views/evaluation/explore.html',
25 | controller: 'EvalExploreCtrl'
26 | })
27 | .when('/evaluation/sample', {
28 | templateUrl: 'views/evaluation/sample.html',
29 | controller: 'EvalSampleCtrl'
30 | })
31 | .when('/evaluation/audit', {
32 | templateUrl: 'views/evaluation/audit.html',
33 | controller: 'EvalAuditCtrl'
34 | })
35 | .when('/evaluation/report', {
36 | templateUrl: 'views/evaluation/report.html',
37 | controller: 'EvalReportCtrl'
38 | })
39 | .when('/view_report', {
40 | templateUrl: 'views/viewReport.html',
41 | controller: 'ViewReportCtrl'
42 | })
43 | .when('/open', {
44 | templateUrl: 'views/open.html',
45 | controller: 'OpenCtrl'
46 | })
47 | .when('/save', {
48 | templateUrl: 'views/save.html',
49 | controller: 'SaveCtrl'
50 | })
51 | .when('/error', {
52 | templateUrl: 'views/error.html'
53 | })
54 | .when('/import', {
55 | templateUrl: 'views/import.html',
56 | controller: 'ImportCtrl'
57 | })
58 | .otherwise({
59 | redirectTo: '/error'
60 | });
61 | });
62 |
--------------------------------------------------------------------------------
/app/scripts/app.language.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .value('supportedLanguages', [
5 | {
6 | code: 'en',
7 | localName: 'English'
8 | },
9 | {
10 | code: 'nl',
11 | localName: 'Nederlands'
12 | }
13 | ])
14 | .config(function ($translateProvider, wcag2specProvider) {
15 | var lang;
16 | function createCookie (name, value) {
17 | document.cookie = name + '=' + value + '; path=/';
18 | }
19 |
20 | function readCookie (name) {
21 | var nameEQ = name + '=';
22 | var ca = document.cookie.split(';');
23 | for (var i = 0; i < ca.length; i++) {
24 | var c = ca[i];
25 | while (c.charAt(0) == ' ') c = c.substring(1, c.length);
26 | if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
27 | }
28 | return null;
29 | }
30 |
31 | try {
32 | lang = readCookie('wcagReporter-lang');
33 | if (!lang) {
34 | lang = jQuery('*[ng-app="wcagReporter"]')
35 | .attr('lang') || 'en';
36 | lang = lang.substr(0, 2);
37 | createCookie('wcagReporter-lang', lang);
38 | }
39 | } catch (e) {
40 | lang = 'en';
41 | }
42 |
43 | $translateProvider.useSanitizeValueStrategy(null);
44 | $translateProvider.useStaticFilesLoader({
45 | prefix: 'locale/',
46 | suffix: '.json'
47 | });
48 |
49 | wcag2specProvider.setSpecPath('wcag2spec/wcag2-${lang}.json');
50 | wcag2specProvider.loadLanguage(lang);
51 | $translateProvider.preferredLanguage(lang);
52 | })
53 | .run(function ($rootScope, $rootElement, translateFilter) {
54 | $rootScope.translate = translateFilter;
55 |
56 | $rootElement.addClass('app-loading');
57 | $rootScope.$on('$translateChangeSuccess', function (e, change) {
58 | // Update the lang data
59 | $rootElement.attr('lang', change.language);
60 | $rootScope.lang = change.language;
61 | $rootElement.removeClass('app-loading');
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/app/scripts/controllers/evaluation/audit.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller('EvalAuditCtrl', function ($scope, appState) {
5 | $scope.state = appState.moveToState('audit');
6 | });
7 |
--------------------------------------------------------------------------------
/app/scripts/controllers/evaluation/audit/samplePages.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller(
5 | 'AuditSamplePagesCtrl',
6 | function ($scope, evalSampleModel, Page, $rootScope) {
7 | var getSelected = evalSampleModel.getSelectedPages;
8 | var getPages = evalSampleModel.getPages;
9 |
10 | $scope.structuredSample = evalSampleModel.structuredSample;
11 | $scope.randomSample = evalSampleModel.randomSample;
12 |
13 | $scope.filledPages = function () {
14 | return evalSampleModel.getFilledPages();
15 | };
16 |
17 | $scope.auditSize = getSelected.length;
18 | $scope.anySelect = $scope.auditSize !== 0;
19 |
20 | $scope.openSelected = function () {
21 | getSelected()
22 | .forEach(function (page) {
23 | Page.openInWindow(page);
24 | });
25 | };
26 |
27 | $scope.openPage = Page.openInWindow;
28 |
29 | $scope.changeAll = function () {
30 | var pages = getPages();
31 | pages.forEach(function (page) {
32 | page.selected = $scope.anySelect;
33 | });
34 | $scope.sampleChange();
35 | };
36 |
37 | var previousSelection;
38 | $scope.multiSelect = function (index, event) {
39 | if (event.toElement.nodeName.toLowerCase() !== 'input') {
40 | return;
41 | }
42 |
43 | if (typeof previousSelection !== 'undefined' && event.shiftKey) {
44 | var pages = evalSampleModel.getFilledPages();
45 | var start = Math.min(previousSelection, index);
46 | var end = Math.max(previousSelection, index);
47 | var state = pages[index].selected;
48 |
49 | for (var i = start; i <= end; i++) {
50 | pages[i].selected = state;
51 | }
52 | $scope.sampleChange();
53 | }
54 | previousSelection = index;
55 | };
56 |
57 | $scope.sampleChange = function () {
58 | var selected = getSelected().length;
59 | $scope.auditSize = selected;
60 | $scope.anySelect = selected > 0;
61 | $rootScope.$broadcast('audit:sample-change');
62 | };
63 |
64 | $scope.completePages = function () {
65 | getSelected()
66 | .forEach(function (page) {
67 | page.tested = true;
68 | });
69 | };
70 |
71 | $scope.uncompletePages = function () {
72 | getSelected()
73 | .forEach(function (page) {
74 | page.tested = false;
75 | });
76 | };
77 | }
78 | );
79 |
--------------------------------------------------------------------------------
/app/scripts/controllers/evaluation/report.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller(
5 | 'EvalReportCtrl',
6 | function ($scope, appState, evalReportModel) {
7 | $scope.state = appState.moveToState('report');
8 | $scope.reportModel = evalReportModel;
9 | }
10 | );
11 |
--------------------------------------------------------------------------------
/app/scripts/controllers/evaluation/sample.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller(
5 | 'EvalSampleCtrl',
6 | function (
7 | $scope,
8 | appState,
9 | evalExploreModel,
10 | evalSampleModel,
11 | evalAuditModel
12 | ) {
13 | $scope.state = appState.moveToState('sample');
14 |
15 | $scope.structuredSample = evalSampleModel.structuredSample;
16 | $scope.randomSample = evalSampleModel.randomSample;
17 |
18 | $scope.exploreModel = evalExploreModel;
19 |
20 | if ($scope.structuredSample &&
21 | $scope.structuredSample.webpage.length === 0) {
22 | var strPage = evalSampleModel.addNewStructuredPage();
23 | evalAuditModel.addPageForAsserts(strPage);
24 |
25 | if ($scope.randomSample &&
26 | $scope.randomSample.webpage.length === 0) {
27 | var rndPage = evalSampleModel.addNewRandomPage();
28 | evalAuditModel.addPageForAsserts(rndPage);
29 | }
30 | }
31 |
32 | $scope.getPageAdder = function (sample) {
33 | return function () {
34 | var strPage = evalSampleModel.addNewPage(sample);
35 | evalAuditModel.addPageForAsserts(strPage);
36 | var strSize = $scope.structuredSample.webpage.length;
37 |
38 | // Add a random page if it's one off
39 | var randomSampleSize = Math.ceil(strSize / 10);
40 | if ($scope.randomSample.webpage.length + 1 === randomSampleSize &&
41 | strSize % 10 === 1) {
42 | var rndPage = evalSampleModel
43 | .addNewPage($scope.randomSample);
44 | evalAuditModel.addPageForAsserts(rndPage);
45 | }
46 |
47 | return strPage;
48 | };
49 | };
50 |
51 | $scope.getPageRemover = function (sample) {
52 | return function (index) {
53 | var page = evalSampleModel.removePage(sample, index);
54 | evalAuditModel.removePageFromAsserts(page);
55 | };
56 | };
57 |
58 | $scope.randPageCount = function () {
59 | return Math
60 | .ceil($scope.structuredSample.webpage.length / 10);
61 | };
62 | }
63 | );
64 |
--------------------------------------------------------------------------------
/app/scripts/controllers/evaluation/scope.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller(
5 | 'EvalScopeCtrl',
6 | function (
7 | $scope,
8 | appState,
9 | evalScopeModel,
10 | evalReportModel,
11 | $filter
12 | ) {
13 | $scope.state = appState.moveToState('scope');
14 | $scope.scopeModel = evalScopeModel;
15 |
16 | $scope.wcagVersionOptions = evalScopeModel.wcagVersionOptions
17 | .reduce(function (versions, version) {
18 | var translateKey = 'SCOPE.' + version;
19 |
20 | versions[version] = $filter('translate')(translateKey);
21 |
22 | return versions;
23 | }, {});
24 |
25 | $scope.conformanceOptions = evalScopeModel.conformanceOptions
26 | .reduce(function (tgt, lvl) {
27 | tgt[lvl] = $filter('rdfToLabel')(lvl);
28 | return tgt;
29 | }, {});
30 |
31 | // Give the report a default title
32 | // (won't if one is already set)
33 | $scope.$on('$routeChangeStart', function () {
34 | if (evalScopeModel.website.siteName) {
35 | var translate = $filter('translate');
36 | var siteName = translate('REPORT.TITLE_PREFIX') + ' ' +
37 | evalScopeModel.website.siteName;
38 | evalReportModel.setDefaultTitle(siteName);
39 | }
40 | });
41 | }
42 | );
43 |
--------------------------------------------------------------------------------
/app/scripts/controllers/footer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller(
5 | 'FooterCtrl',
6 | function ($scope, pkgData) {
7 | $scope.pkg = pkgData;
8 | }
9 | );
10 |
--------------------------------------------------------------------------------
/app/scripts/controllers/navigation.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller(
5 | 'NavigationCtrl',
6 | function ($scope, $rootScope, supportedLanguages, changeLanguage) {
7 | $scope.languages = supportedLanguages;
8 | $scope.currentLang = $rootScope.lang;
9 |
10 | $rootScope.$on('$translateChangeSuccess', function (e, change) {
11 | $scope.currentLang = change.language.toLowerCase();
12 | });
13 |
14 | $scope.changeLanguage = changeLanguage;
15 | }
16 | );
17 |
--------------------------------------------------------------------------------
/app/scripts/controllers/open.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller('OpenCtrl', function ($scope, reportStorage, evalLoader, $rootScope) {
5 | $scope.postSettings = reportStorage.settings;
6 | $scope.fileFeedback = {
7 | posted: false, failures: false
8 | };
9 | $scope.evalFile = '';
10 |
11 | $scope.urlFeedback = {
12 | posted: false, failures: false
13 | };
14 |
15 | function handleLoad (defer, feedback) {
16 | feedback.posted = true;
17 | feedback.failure = false;
18 |
19 | defer.then(function success () {
20 | feedback.posted = false;
21 | $rootScope.setEvalLocation();
22 | }, function error (e) {
23 | feedback.posted = false;
24 | if (e.message) {
25 | feedback.failure = e.message;
26 | } else {
27 | feedback.failure = e;
28 | }
29 | });
30 | }
31 |
32 | $scope.loadFile = function (filePath) {
33 | var uploadResponse = evalLoader.openFromFile(filePath);
34 | handleLoad(uploadResponse, $scope.fileFeedback);
35 | };
36 |
37 | $scope.loadUrl = function () {
38 | handleLoad(evalLoader.openFromUrl($scope.postSettings.url), $scope.urlFeedback);
39 | };
40 |
41 | $scope.updateSettings = function () {
42 | reportStorage.updateSettings();
43 | };
44 | });
45 |
--------------------------------------------------------------------------------
/app/scripts/controllers/report/findings.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller(
5 | 'ReportFindingsCtrl',
6 | function ($scope, wcag2spec, evalAuditModel, evalScopeModel, CriterionAssert) {
7 | if (wcag2spec.isLoaded()) {
8 | $scope.principles = wcag2spec.getPrinciples();
9 | } else {
10 | $scope.principles = [];
11 | wcag2spec.onLangChange(function () {
12 | $scope.principles = wcag2spec.getPrinciples();
13 | });
14 | }
15 |
16 | $scope.auditModel = evalAuditModel;
17 | $scope.critOpt = {
18 | editable: false,
19 | collapsed: false,
20 | showallpages: false,
21 | hideCollapseBtn: true
22 | };
23 |
24 | $scope.getCritAssert = evalAuditModel.getCritAssert;
25 | $scope.shouldCritRender = function (critSpec) {
26 | if (evalScopeModel.matchConformTarget(critSpec.level)) {
27 | return true;
28 | } else {
29 | var critAssert = $scope.getCritAssert(critSpec.id);
30 | return CriterionAssert.isDefined(critAssert);
31 | }
32 | };
33 | }
34 | );
35 |
--------------------------------------------------------------------------------
/app/scripts/controllers/report/score.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller('ReportScoreCtrl', function ($scope, wcag2spec, evalAuditModel) {
5 | $scope.principles = wcag2spec.getPrinciples();
6 | var totals = {
7 | 'earl:passed': 0,
8 | 'earl:failed': 0,
9 | 'earl:inapplicable': 0,
10 | 'earl:untested': 0,
11 | 'earl:cantTell': 0,
12 | level_a: { pass: 0, total: 0 },
13 | level_aa: { pass: 0, total: 0 },
14 | level_aaa: { pass: 0, total: 0 }
15 | };
16 | $scope.totals = totals;
17 |
18 | $scope.getScores = function () {
19 | return wcag2spec.getPrinciples()
20 | .map(function (p) {
21 | var result = {
22 | name: p.num + '. ' + p.handle,
23 | 'earl:passed': 0,
24 | 'earl:failed': 0,
25 | 'earl:inapplicable': 0,
26 | 'earl:untested': 0,
27 | 'earl:cantTell': 0,
28 | tested: 0,
29 | level_a: { pass: 0, total: 0 },
30 | level_aa: { pass: 0, total: 0 },
31 | level_aaa: { pass: 0, total: 0 }
32 | };
33 |
34 | // Get all criteria of this principle:
35 | p.guidelines.reduce(function (list, guide) {
36 | list.push.apply(list, guide.successcriteria);
37 | return list;
38 | }, [])
39 | .forEach(function (crit) {
40 | // For each, set the result
41 | var critResult = evalAuditModel.getCritAssert(crit.id);
42 | if (critResult) {
43 | var outcome = critResult.result.outcome;
44 |
45 | var level = crit.level
46 | .replace('wai:WCAG2', '')
47 | .replace('-Conformance', '')
48 | .toLowerCase();
49 |
50 | result[outcome] += 1;
51 | $scope.totals[outcome] += 1;
52 | if (outcome === 'earl:passed' ||
53 | outcome === 'earl:inapplicable') {
54 | result['level_' + level].pass += 1;
55 | totals['level_' + level].pass += 1;
56 | }
57 | if (outcome !== 'earl:untested') {
58 | result.tested += 1;
59 | result['level_' + level].total += 1;
60 | totals['level_' + level].total += 1;
61 | }
62 | }
63 | });
64 | return result;
65 | });
66 | };
67 |
68 | $scope.scores = $scope.getScores();
69 | // Update the score name when the language changes
70 | $scope.$on('wcag2spec:langChange', function () {
71 | $scope.scores = $scope.getScores();
72 | });
73 | });
74 |
--------------------------------------------------------------------------------
/app/scripts/controllers/save.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller('SaveCtrl', function ($scope, wcagReporterExport, appState) {
5 | $scope.exportUrl = wcagReporterExport.getBlobUrl();
6 | $scope.exportFile = wcagReporterExport.getFileName();
7 | $scope.postSettings = wcagReporterExport.storage.settings;
8 | $scope.posted = false;
9 | $scope.failure = false;
10 | $scope.success = false;
11 |
12 | $scope.postJson = function () {
13 | $scope.posted = true;
14 | $scope.failure = false;
15 |
16 | wcagReporterExport.saveToUrl()
17 | .then(function () {
18 | $scope.success = true;
19 | $scope.posted = false;
20 | }, function (data) {
21 | $scope.failure = (data || true);
22 | $scope.posted = false;
23 | });
24 | };
25 |
26 | $scope.downloadStart = function () {
27 | wcagReporterExport.saveBlobIE();
28 | appState.setPrestineState();
29 | };
30 |
31 | $scope.updateSettings = function () {
32 | wcagReporterExport.storage.updateSettings();
33 | };
34 | });
35 |
--------------------------------------------------------------------------------
/app/scripts/controllers/start.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller(
5 | 'StartCtrl',
6 | function ($scope, $location, appState, $timeout, $rootScope) {
7 | $scope.state = appState.moveToState('start');
8 |
9 | if (typeof $rootScope.rootHide.start1 === 'undefined') {
10 | $scope.initial = 'hidden';
11 | $timeout(function () {
12 | $scope.initial = '';
13 | }, 500);
14 | $timeout(function () {
15 | $rootScope.rootHide.start1 = false;
16 | }, 700);
17 | }
18 |
19 | $scope.nextStep = function () {
20 | $location.path('/evaluation/scope');
21 | };
22 |
23 | $scope.nextStepName = 'STEP_SCOPE';
24 | }
25 | );
26 |
--------------------------------------------------------------------------------
/app/scripts/controllers/stepButtons.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller(
5 | 'StepButtonsCtrl',
6 | function ($scope, $location, appState) {
7 | var previous = appState.getPreviousState();
8 | var next = appState.getNextState();
9 |
10 | if (next) {
11 | $scope.nextStep = function () {
12 | $location.path(next.route);
13 | };
14 | $scope.nextStepName = 'STEP_' + (next.name).toUpperCase();
15 | }
16 |
17 | if (previous) {
18 | $scope.previousStep = function () {
19 | $location.path(previous.route);
20 | };
21 | $scope.previousStepName = 'STEP_' + (previous.name).toUpperCase();
22 | }
23 | }
24 | );
25 |
--------------------------------------------------------------------------------
/app/scripts/controllers/viewReport.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('wcagReporter')
4 | .controller('ViewReportCtrl', function (
5 | $scope,
6 | $document,
7 | wcag2spec,
8 | evalModel,
9 | appState,
10 | wcagReporterExport,
11 | toggleCriterionText
12 | ) {
13 | var htmlBlob;
14 |
15 | $scope.state = appState.moveToState('viewReport');
16 | $scope.scope = evalModel.scopeModel;
17 | $scope.explore = evalModel.exploreModel;
18 |
19 | $scope.filledPages = function () {
20 | return evalModel.sampleModel.getFilledPages();
21 | };
22 |
23 | $scope.wcag2specReady = wcag2spec.isLoaded();
24 | $scope.$on('wcag2spec:langChange', function () {
25 | $scope.wcag2specReady = true;
26 | });
27 |
28 | $scope.report = evalModel.reportModel;
29 | var tpl = [
30 | '
' + $filter('translate')('HTML_REPORT.LABEL_DESCR') + ': ' + 40 | $filter('txtToHtml')(text) 41 | .substr(3); 42 | }; 43 | scope.htmlResult = scope.getStaticHtmlResult(scope.result.description); 44 | }, 45 | templateUrl: 'views/directives/criterion/earlAssert.html' 46 | }); 47 | } 48 | ); 49 | -------------------------------------------------------------------------------- /app/scripts/directives/criterion/macroResults.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .directive('macroResults', function (directivePlugin) { 4 | return directivePlugin({ 5 | restrict: 'E', 6 | replace: true, 7 | scope: { 8 | criterion: '=value', 9 | asserts: '=', 10 | opt: '=options' 11 | }, 12 | 13 | link: function (scope) { 14 | scope.removeAssert = function (assert) { 15 | var index = scope.criterion.hasPart.indexOf(assert); 16 | if (index >= 0) { 17 | scope.criterion.hasPart.splice(index, 1); 18 | } 19 | index = scope.asserts.indexOf(assert); 20 | if (index >= 0) { 21 | scope.asserts.splice(index, 1); 22 | } 23 | }; 24 | 25 | scope.transferMacroData = function (macroAssert) { 26 | // Get all single page asserts where a tag is part of this macro assert 27 | scope.criterion.transferMacroData(macroAssert); 28 | scope.removeAssert(macroAssert); 29 | }; 30 | 31 | scope.getAllTitles = function (assert) { 32 | return assert.subject.map(function (page) { 33 | return page.displayTitle(); 34 | }) 35 | .join(', '); 36 | }; 37 | }, 38 | templateUrl: 'views/directives/criterion/macroResults.html' 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /app/scripts/directives/criterion/pageResults.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .directive('pageResults', function (directivePlugin) { 4 | return directivePlugin({ 5 | restrict: 'E', 6 | replace: true, 7 | scope: { 8 | criterion: '=value', 9 | asserts: '=', 10 | opt: '=options' 11 | }, 12 | link: function (scope) { 13 | scope.createMacro = function (assert) { 14 | scope.criterion.addTestCaseAssertion({ 15 | result: { 16 | description: assert.result.description, 17 | outcome: assert.result.outcome 18 | }, 19 | multiPage: true 20 | }); 21 | }; 22 | }, 23 | templateUrl: 'views/directives/criterion/pageResults.html' 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /app/scripts/directives/criterion/pageSelect.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .directive('pageSelect', function (directivePlugin, evalSampleModel) { 4 | var sample; 5 | return directivePlugin({ 6 | restrict: 'E', 7 | replace: true, 8 | scope: { 9 | pages: '=' 10 | }, 11 | controller: [ 12 | '$scope', 13 | function ($scope) { 14 | $scope.updateSampleList = function () { 15 | $scope.unselectedPages = sample.filter(function (page) { 16 | return $scope.pages.indexOf(page) === -1; 17 | }); 18 | }; 19 | 20 | $scope.removePage = function (page) { 21 | var index = $scope.pages.indexOf(page); 22 | if (index >= 0) { 23 | $scope.pages.splice(index, 1); 24 | $scope.updateSampleList(); 25 | } 26 | }; 27 | 28 | $scope.addPageToAssert = function () { 29 | var page = evalSampleModel.getPageByTitle($scope.newPage); 30 | 31 | if (page && $scope.pages.indexOf(page) === -1) { 32 | $scope.unselectedPages.splice($scope.unselectedPages.indexOf(page), 1); 33 | $scope.pages.push(page); 34 | $scope.newPage = ''; 35 | } 36 | }; 37 | 38 | sample = evalSampleModel.getPages(); 39 | $scope.updateSampleList(); 40 | } 41 | ], 42 | templateUrl: 'views/directives/criterion/pageSelect.html' 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /app/scripts/directives/criterion/resultDescription.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .directive('resultDescription', function (directivePlugin) { 4 | return directivePlugin({ 5 | restrict: 'E', 6 | replace: true, 7 | scope: { 8 | value: '=', 9 | updateMetadata: '=' 10 | }, 11 | templateUrl: 'views/directives/criterion/resultDescription.html' 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /app/scripts/directives/evaluate/iconButton.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .directive('iconButton', function (directivePlugin) { 5 | return directivePlugin({ 6 | restrict: 'E', 7 | replace: true, 8 | scope: { 9 | label: '=', 10 | icon: '=', 11 | click: '&' 12 | }, 13 | templateUrl: 'views/directives/evaluate/iconButton.html' 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /app/scripts/directives/evaluate/infoButton.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .directive('infoButton', function (directivePlugin) { 4 | return directivePlugin({ 5 | restrict: 'E', 6 | scope: { 7 | label: '@', 8 | target: '@' 9 | }, 10 | link: function (scope, elm) { 11 | var tgt; 12 | 13 | elm.on('click', function () { 14 | if (!tgt) { 15 | if (typeof scope.target === 'undefined') { 16 | tgt = elm.next(); 17 | } else { 18 | tgt = angular.element('#' + scope.target); 19 | } 20 | tgt.find('.close') 21 | .on( 22 | 'click', 23 | elm.attr.bind(elm, 'aria-expanded', false) 24 | ); 25 | } 26 | tgt.toggle(200, function () { 27 | tgt.focus(); 28 | elm.attr('aria-expanded', tgt.is(':visible')); 29 | }); 30 | }); 31 | }, 32 | replace: true, 33 | templateUrl: 'views/directives/evaluate/infoButton.html' 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /app/scripts/directives/evaluate/infoField.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .directive('infoField', function (directivePlugin, $document) { 4 | /** 5 | * Get the next visible element that can receive focus outside the .alert-info 6 | */ 7 | function getNextFocusElement (elm) { 8 | var selector = ':input:visible, a[href]:visible'; 9 | var focusable = $document.find(selector); 10 | 11 | elm = angular.element(elm) 12 | .closest('.alert-info') 13 | .find(selector) 14 | .last(); 15 | return focusable[focusable.index(elm) + 1]; 16 | } 17 | 18 | return directivePlugin({ 19 | restrict: 'E', 20 | scope: { 21 | ref: '@', 22 | button: '@', 23 | exitto: '@' 24 | }, 25 | link: function (scope, elm) { 26 | elm.hide(0); 27 | scope.close = function ($event) { 28 | var nextElm; 29 | 30 | if ($event.type === 'keyup' && 31 | ($event.keyCode !== 13 && $event.keyCode !== 27)) { 32 | return; 33 | } 34 | if (scope.exitto) { 35 | nextElm = angular.element('#' + scope.exitto); 36 | } 37 | if (!nextElm || nextElm.length === 0) { 38 | nextElm = getNextFocusElement($event.target); 39 | } 40 | nextElm.focus(); 41 | elm.hide(200); 42 | }; 43 | }, 44 | replace: true, 45 | transclude: true, 46 | templateUrl: 'views/directives/evaluate/infoField.html' 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /app/scripts/directives/evaluate/inputPages.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .directive('inputPages', function (directivePlugin, $timeout, Page) { 4 | return directivePlugin({ 5 | restrict: 'E', 6 | replace: true, 7 | scope: { 8 | pages: '=', 9 | addPage: '&', 10 | removePage: '&' 11 | }, 12 | link: function (scope) { 13 | var addPageFunc = scope.addPage(); 14 | var removePageFunc = scope.removePage(); 15 | scope.addPage = function ($event) { 16 | var button = angular.element($event.delegateTarget); 17 | addPageFunc(); 18 | 19 | $timeout(function () { 20 | var inputs = button.prev() 21 | .find('input'); 22 | inputs[inputs.length - 2].select(); 23 | }, 100); 24 | }; 25 | 26 | scope.processPage = function (page) { 27 | Page.prependProtocol(page); 28 | Page.updateSource(page); 29 | }; 30 | 31 | scope.removePage = function ($index, $event) { 32 | removePageFunc($index); 33 | // We need this timeout to prevent Angular UI from throwing an error 34 | $timeout(function () { 35 | angular.element($event.delegateTarget) 36 | .closest('fieldset') 37 | .parent() 38 | .children() 39 | .last() 40 | .focus(); 41 | }); 42 | }; 43 | }, 44 | templateUrl: 'views/directives/evaluate/inputPages.html' 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /app/scripts/directives/evaluate/techSelect.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .directive('techSelect', function () { 5 | var knownTechnologies = [ 6 | { title: 'HTML5', specs: 'http://www.w3.org/TR/html5/' }, 7 | { title: 'CSS', specs: 'http://www.w3.org/Style/CSS/specs/' }, 8 | { title: 'HTML 4.01', specs: 'http://www.w3.org/TR/html401/' } 9 | ]; 10 | 11 | function updateTech (reliedUponTech, prop1, prop2) { 12 | knownTechnologies.forEach(function (tech) { 13 | if (reliedUponTech[prop1] === tech[prop1]) { 14 | reliedUponTech[prop2] = tech[prop2]; 15 | } 16 | }); 17 | } 18 | 19 | return { 20 | restrict: 'E', 21 | replace: true, 22 | scope: { selected: '=' }, 23 | link: function (scope) { 24 | scope.technolgies = knownTechnologies; 25 | scope.updateTitle = function (select) { 26 | updateTech(select, 'specs', 'title'); 27 | }; 28 | scope.updateSpec = function (select) { 29 | updateTech(select, 'title', 'specs'); 30 | }; 31 | }, 32 | templateUrl: 'views/directives/evaluate/techSelect.html' 33 | }; 34 | }); 35 | -------------------------------------------------------------------------------- /app/scripts/directives/fullReport.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .directive('fullReport', function (directivePlugin, $interval) { 4 | function testFilter (element) { 5 | return function (query) { 6 | return element.find(query).length === 0; 7 | }; 8 | } 9 | 10 | return directivePlugin({ 11 | restrict: 'E', 12 | replace: true, 13 | link: function (scope, element) { 14 | var tests = [ 15 | '.panel-heading', 16 | '.sample_narrow', 17 | '.score-total' 18 | ]; 19 | var stop = $interval(function () { 20 | tests = tests.filter(testFilter(element)); 21 | if (tests.length === 0) { 22 | scope.$emit('reportReady', element); 23 | $interval.cancel(stop); 24 | } 25 | }, 200); 26 | }, 27 | templateUrl: 'views/directives/fullReport.html' 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /app/scripts/directives/shyPlaceholder.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .directive('shyPlaceholder', function (directivePlugin) { 4 | var ph = 'placeholder'; 5 | 6 | return directivePlugin({ 7 | restrict: 'A', 8 | scope: { 9 | shyPlaceholder: '=' 10 | }, 11 | compile: function (elm, attrs) { 12 | return function (scope, elm) { 13 | var phValue = scope.$eval(attrs.shyPlaceholder); 14 | 15 | elm.attr(ph, phValue) 16 | .bind({ 17 | focus: elm.attr.bind(elm, ph, ''), 18 | blur: elm.attr.bind(elm, ph, phValue) 19 | }); 20 | }; 21 | } 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /app/scripts/directives/successCriterion.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .directive('successCriterion', function (directivePlugin, $rootScope, toggleCriterionText) { 5 | var className = { 6 | 'earl:untested': 'untested', 7 | 'earl:passed': 'passed', 8 | 'earl:failed': 'failed', 9 | 'earl:inapplicable': 'inapplicable', 10 | 'earl:cantTell': 'canttell' 11 | }; 12 | 13 | return directivePlugin({ 14 | restrict: 'E', 15 | replace: true, 16 | scope: { 17 | assert: '=assertion', 18 | spec: '=requirement', 19 | opt: '=options' 20 | }, 21 | link: function (scope) { 22 | window.toggleCriterionText = toggleCriterionText; 23 | // scope.outcomes = outcomes; 24 | scope.rootHide = $rootScope.rootHide; 25 | scope.critHide = scope.spec.id + '-cb'; 26 | scope.getClassName = function (state) { 27 | return className[state]; 28 | }; 29 | }, 30 | toggleCriterionText: toggleCriterionText, 31 | templateUrl: 'views/directives/successCriterion.html' 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /app/scripts/filters/getUrl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('wcagReporter') 3 | .filter('getUrl', function () { 4 | var linkReg = /((https?):\/\/)([\da-z\.-]+)\.([a-z\.]{2,6})([\-\w\d@:%_\+.~#?,&\/\/=]+)/g; 5 | 6 | return function (text) { 7 | var match; 8 | if (typeof text === 'string') { 9 | match = text.match(linkReg); 10 | } 11 | if (match) { 12 | return match[0]; 13 | } else { 14 | return false; 15 | } 16 | }; 17 | }); 18 | -------------------------------------------------------------------------------- /app/scripts/filters/rdfToLabel.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .filter('rdfToLabel', function ($filter) { 5 | var rdfToLabel; 6 | var keymap = { 7 | 'earl:passed': 'PASSED', 8 | 'earl:failed': 'FAILED', 9 | 'earl:cantTell': 'CANT_TELL', 10 | 'earl:inapplicable': 'NOT_PRESENT', 11 | 'earl:untested': 'NOT_CHECKED', 12 | A: 'LEVEL_A', 13 | AA: 'LEVEL_AA', 14 | AAA: 'LEVEL_AAA', 15 | 'wai:WCAG2A-Conformance': 'LEVEL_A', 16 | 'wai:WCAG2AA-Conformance': 'LEVEL_AA', 17 | 'wai:WCAG2AAA-Conformance': 'LEVEL_AAA' 18 | }; 19 | 20 | rdfToLabel = function (earl) { 21 | return $filter('translate')('EARL.' + keymap[earl]); 22 | }; 23 | rdfToLabel.keymap = keymap; 24 | rdfToLabel.$stateful = true; 25 | 26 | return rdfToLabel; 27 | }); 28 | -------------------------------------------------------------------------------- /app/scripts/filters/selectedCasesOnly.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .filter('selectedCasesOnly', function () { 5 | function critHasSelectedPages (criterion) { 6 | for (var i = 0; i < criterion.subject.length; i++) { 7 | var page = criterion.subject[i]; 8 | if (page.selected && (page.title || page.description)) { 9 | return true; 10 | } 11 | } 12 | return false; 13 | } 14 | 15 | return function (criterion) { 16 | if (criterion) { 17 | return criterion.filter(critHasSelectedPages); 18 | } 19 | }; 20 | }); 21 | -------------------------------------------------------------------------------- /app/scripts/filters/txtToHtml.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .filter('txtToHtml', function ($filter) { 5 | return function (text) { 6 | if (typeof text !== 'string') { 7 | return ''; 8 | } 9 | return text.split('\n') 10 | .reduce(function (cur, line) { 11 | if (line.trim() === '') { 12 | return cur + '
'; 13 | } else { 14 | line = $filter('linky')(line, '_blank'); 15 | return cur + (cur.substr(-3) === '
' ? '' : '
') + line;
16 | }
17 | }, '
') + '
'; 18 | }; 19 | }); 20 | -------------------------------------------------------------------------------- /app/scripts/models/class/Page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .service('Page', function ($filter) { 5 | var translateFilter = $filter('translate'); 6 | 7 | function Page () { 8 | this.type = [ 9 | 'TestSubject', 10 | 'WebPage' 11 | ]; 12 | } 13 | 14 | Page.updateSource = function (page) { 15 | var source = $filter('getUrl')(page.description); 16 | if (source) { 17 | page.source = source; 18 | } else { 19 | delete page.source; 20 | } 21 | return source; 22 | }; 23 | 24 | Page.prependProtocol = function (page) { 25 | if (page.description && page.description.match(/^([\da-z\.-]+)\.([a-z\.]{2,6})/)) { 26 | page.description = 'http://' + page.description; 27 | } 28 | }; 29 | 30 | Page.openInWindow = function (page, target) { 31 | target = target || '_blank'; 32 | if (page.source) { 33 | window.open(page.source, target); 34 | } 35 | }; 36 | 37 | Page.prototype = { 38 | type: [ 39 | 'TestSubject', 40 | 'WebPage' 41 | ], 42 | id: '', 43 | description: undefined, 44 | title: '', 45 | tested: false, 46 | selected: false, 47 | displayTitle: function () { 48 | var num = 0; 49 | if (this.title.trim()) { 50 | return this.title; 51 | } else if (this.id.substr(0, 9) === '_:struct_') { 52 | num = +this.id.substr(9); 53 | return translateFilter('SAMPLE.STRUCTURED_PAGE') + ' ' + (num + 1); 54 | } else if (this.id.substr(0, 7) === '_:rand_') { 55 | num = +this.id.substr(7); 56 | return translateFilter('SAMPLE.RANDOM_PAGE') + ' ' + (num + 1); 57 | } else { 58 | return translateFilter('SAMPLE.SAMPLE_PAGE'); 59 | } 60 | } 61 | }; 62 | 63 | return Page; 64 | }); 65 | -------------------------------------------------------------------------------- /app/scripts/models/class/TestCaseAssert.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular 4 | .module('wcagReporter') 5 | .service('TestCaseAssert', function ( 6 | types, 7 | evalSampleModel, 8 | currentUser 9 | ) { 10 | var protoResult = { 11 | type: types.EARL.RESULT.class, 12 | description: '', 13 | outcome: types.EARL.OUTCOME.UNTESTED 14 | }; 15 | 16 | function TestCaseAssert () { 17 | // Copy prototype onto the object - prevents problems with JSON.stringify() 18 | for (var key in TestCaseAssert.prototype) { 19 | if (!this.hasOwnProperty(key)) { 20 | this[key] = TestCaseAssert.prototype[key]; 21 | } 22 | } 23 | 24 | this.subject = []; 25 | this.result = angular.copy(protoResult); 26 | } 27 | 28 | TestCaseAssert.isDefined = function (tc) { 29 | var hasPage = false; 30 | tc.subject.forEach(function (page) { 31 | hasPage = (hasPage || page.title || page.description); 32 | }); 33 | return ((tc.result.description || tc.result.outcome !== protoResult.outcome) && hasPage); 34 | }; 35 | 36 | TestCaseAssert.prototype = { 37 | type: 'Assertion', 38 | assertedBy: currentUser.id, 39 | subject: undefined, 40 | testCase: undefined, 41 | result: undefined, 42 | multiPage: false, 43 | mode: types.EARL.MODE.MANUAL, 44 | isDefined: function () { 45 | return TestCaseAssert.isDefined(this); 46 | }, 47 | 48 | addNewPage: function (page) { 49 | this.subject.push(page); 50 | }, 51 | 52 | removePage: function (i) { 53 | this.subject.splice(i, 1); 54 | }, 55 | 56 | setSubject: function (pages) { 57 | var subject = []; 58 | this.subject = subject; 59 | if (pages && !angular.isArray(pages)) { 60 | pages = [pages]; 61 | } 62 | pages.forEach(function (page) { 63 | if (typeof page === 'string') { 64 | page = evalSampleModel.getPageById(page); 65 | } 66 | if (typeof page === 'object') { 67 | subject.push(page); 68 | } 69 | }); 70 | } 71 | }; 72 | 73 | return TestCaseAssert; 74 | }); 75 | -------------------------------------------------------------------------------- /app/scripts/models/evaluation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular 4 | .module('wcagReporter') 5 | .factory('evalModel', function ( 6 | evalScopeModel, 7 | evalExploreModel, 8 | evalSampleModel, 9 | evalAuditModel, 10 | evalReportModel, 11 | evalContextV3, 12 | currentUser 13 | ) { 14 | var evalModel = { 15 | id: undefined, 16 | type: 'Evaluation', 17 | context: evalContextV3, 18 | scopeModel: evalScopeModel, 19 | exploreModel: evalExploreModel, 20 | sampleModel: evalSampleModel, 21 | auditModel: evalAuditModel, 22 | reportModel: evalReportModel, 23 | // This array collects data that is outside the evaluation 24 | // For example the author and external rdf data 25 | otherData: [currentUser] 26 | }; 27 | 28 | return evalModel; 29 | }); 30 | -------------------------------------------------------------------------------- /app/scripts/models/evaluation/currentUser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .service('currentUser', function () { 5 | return { 6 | '@context': { 7 | '@vocab': 'http://xmlns.com/foaf/0.1/', 8 | id: '@id', 9 | type: '@type' 10 | }, 11 | id: '_:evaluator', 12 | type: 'Person', 13 | name: '' 14 | }; 15 | }); 16 | -------------------------------------------------------------------------------- /app/scripts/models/evaluation/explore.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular 4 | .module('wcagReporter') 5 | .service('evalExploreModel', function ( 6 | knownTech, 7 | evalSampleModel 8 | ) { 9 | var exploreModel = { 10 | knownTech: knownTech 11 | }; 12 | var basicProps = [ 13 | 'reliedUponTechnology', 14 | 'essentialFunctionality', 15 | 'pageTypeVariety', 16 | 'commonPages', 17 | 'otherRelevantPages' 18 | ]; 19 | 20 | // add all properties to this 21 | basicProps 22 | .forEach(function (prop) { 23 | exploreModel[prop] = undefined; 24 | }); 25 | 26 | exploreModel.reliedUponTechnology = []; 27 | 28 | exploreModel.importData = function (evalData) { 29 | if (!angular.isArray(evalData.reliedUponTechnology)) { 30 | evalData.reliedUponTechnology = [evalData.reliedUponTechnology]; 31 | } 32 | 33 | basicProps 34 | .forEach(function (prop) { 35 | if (evalData[prop]) { 36 | exploreModel[prop] = evalData[prop]; 37 | } 38 | }); 39 | }; 40 | 41 | exploreModel.exportData = function () { 42 | var exportData = {}; 43 | 44 | basicProps 45 | .forEach(function (prop) { 46 | exportData[prop] = exploreModel[prop]; 47 | }); 48 | 49 | return exportData; 50 | }; 51 | 52 | /** 53 | * Returns an array of errors indicating which (if any) properties are invalid 54 | */ 55 | exploreModel.validate = function () { 56 | return []; 57 | }; 58 | 59 | // Lock up the object, for a little more dev security 60 | Object.preventExtensions(exploreModel); 61 | 62 | return exploreModel; 63 | }); 64 | -------------------------------------------------------------------------------- /app/scripts/models/evaluation/report.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .service('evalReportModel', function ($filter, currentUser) { 5 | var protoModel = { 6 | creator: currentUser, 7 | title: '', 8 | summary: '', 9 | specifics: '', 10 | commissioner: '' 11 | }; 12 | var reportModel = Object.create(protoModel); 13 | protoModel.date = $filter('date')(new Date(), 'longDate'); 14 | 15 | reportModel.exportData = function () { 16 | var res = angular.copy(reportModel); 17 | res.creator = res.creator.id; 18 | return res; 19 | }; 20 | 21 | reportModel.importData = function (evalData) { 22 | Object.keys(protoModel) 23 | .forEach(function (key) { 24 | if (angular.isDefined(evalData[key])) { 25 | reportModel[key] = evalData[key]; 26 | } 27 | }); 28 | }; 29 | 30 | reportModel.setDefaultTitle = function (title) { 31 | if (!reportModel.title) { 32 | reportModel.title = title; 33 | } 34 | }; 35 | 36 | return reportModel; 37 | }); 38 | -------------------------------------------------------------------------------- /app/scripts/models/evaluation/scope.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .service('evalScopeModel', function () { 5 | var scopeModel = { 6 | type: 'EvaluationScope', 7 | wcagVersion: 'WCAG21', 8 | conformanceTarget: 'wai:WCAG2AA-Conformance', 9 | additionalEvalRequirement: '', 10 | website: { 11 | type: [ 12 | 'TestSubject', 13 | 'WebSite' 14 | ], 15 | id: '_:website', 16 | siteName: '', 17 | siteScope: '' 18 | }, 19 | accessibilitySupportBaseline: '' 20 | }; 21 | 22 | scopeModel.exportData = function () { 23 | return { 24 | type: scopeModel.type, 25 | conformanceTarget: scopeModel.conformanceTarget, 26 | additionalEvalRequirement: scopeModel.additionalEvalRequirement, 27 | website: { 28 | type: scopeModel.website.type, 29 | id: scopeModel.website.id, 30 | siteName: scopeModel.website.siteName, 31 | siteScope: scopeModel.website.siteScope 32 | }, 33 | accessibilitySupportBaseline: scopeModel.accessibilitySupportBaseline 34 | }; 35 | }; 36 | 37 | scopeModel.wcagVersionOptions = [ 38 | 'WCAG21', 39 | 'WCAG20' 40 | ]; 41 | 42 | scopeModel.conformanceOptions = [ 43 | 'wai:WCAG2A-Conformance', 44 | 'wai:WCAG2AA-Conformance', 45 | 'wai:WCAG2AAA-Conformance' 46 | ]; 47 | 48 | /** 49 | * Returns an array of errors indicating which (if any) properties are invalid 50 | */ 51 | scopeModel.validate = function () { 52 | return []; 53 | }; 54 | 55 | scopeModel.matchConformTarget = function (level) { 56 | return scopeModel.conformanceTarget.length >= level.length; 57 | }; 58 | 59 | // Lock up the object, for a little more dev security 60 | Object.preventExtensions(scopeModel.website); 61 | Object.preventExtensions(scopeModel); 62 | 63 | return scopeModel; 64 | }); 65 | -------------------------------------------------------------------------------- /app/scripts/models/export.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * 4 | */ 5 | angular.module('wcagReporter') 6 | .factory('wcagReporterExport', function (evalModel, reportStorage, pkgData, $rootScope) { 7 | function getJsonLd () { 8 | var jsonLd = { 9 | '@context': evalModel.context, 10 | type: evalModel.type, 11 | id: evalModel.id, 12 | publisher: 'reporter:releases/tag/' + pkgData.version, 13 | lang: $rootScope.lang 14 | }; 15 | 16 | jsonLd.evaluationScope = evalModel.scopeModel.exportData(); 17 | jsonLd.auditResult = evalModel.auditModel.exportData(); 18 | 19 | angular.extend( 20 | jsonLd, 21 | evalModel.reportModel.exportData(), 22 | evalModel.sampleModel.exportData(), 23 | evalModel.exploreModel.exportData() 24 | ); 25 | 26 | return jsonLd; 27 | } 28 | 29 | var exportModel = { 30 | 31 | storage: reportStorage, 32 | 33 | saveToUrl: function () { 34 | return reportStorage.post(exportModel.getJson()); 35 | }, 36 | 37 | getJson: function () { 38 | return { 39 | '@graph': [getJsonLd()].concat(evalModel.otherData) 40 | }; 41 | }, 42 | 43 | getString: function () { 44 | return angular.toJson(exportModel.getJson(), true); 45 | }, 46 | 47 | getBlobUrl: function (blob) { 48 | try { 49 | blob = blob || exportModel.getBlob(); 50 | return (window.URL || window.webkitURL).createObjectURL(blob); 51 | } catch (e) { 52 | console.error(e); 53 | } 54 | }, 55 | 56 | saveBlobIE: function (blob, filename) { 57 | blob = blob || exportModel.getBlob(); 58 | filename = filename || exportModel.getFileName(); 59 | 60 | if (window.navigator.msSaveOrOpenBlob) { 61 | window.navigator.msSaveBlob(blob, filename); 62 | } 63 | }, 64 | 65 | getBlob: function (data, type) { 66 | data = data || exportModel.getString(); 67 | type = type || 'application/json;charset=utf-8'; 68 | return new Blob([data], { type: type }); 69 | }, 70 | 71 | getFileName: function (ext) { 72 | var title = (evalModel.scopeModel.website.siteName + 73 | ' evaluation report'); 74 | ext = ext || 'json'; 75 | title = title.trim(); 76 | 77 | return title.replace(/(^\-+|[^a-zA-Z0-9\/_| -]+|\-+$)/g, '') 78 | .toLowerCase() 79 | .replace(/[\/_| -]+/g, '-') + '.' + ext; 80 | } 81 | }; 82 | 83 | reportStorage.exportModel = exportModel; 84 | 85 | return exportModel; 86 | }); 87 | -------------------------------------------------------------------------------- /app/scripts/services/changeLanguage.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .service('changeLanguage', function ($translate, wcag2spec, $rootScope) { 5 | function createCookie (name, value) { 6 | document.cookie = name + '=' + value + '; path=/'; 7 | } 8 | 9 | return function changeLanguage (lang) { 10 | if ($rootScope.lang === lang) { 11 | return; 12 | } 13 | 14 | if (document) { 15 | createCookie('wcagReporter-lang', lang); 16 | } 17 | $translate.use(lang); 18 | wcag2spec.loadLanguage(lang); 19 | }; 20 | }); 21 | -------------------------------------------------------------------------------- /app/scripts/services/context/evalContextV1.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .constant('evalContextV1', { 5 | '@vocab': 'http://www.w3.org/TR/WCAG-EM/#', 6 | wcag20: 'http://www.w3.org/TR/WCAG20/#', 7 | earl: 'http://www.w3.org/ns/earl#', 8 | dct: 'http://purl.org/dc/terms/', 9 | reporter: 'https://github.com/w3c/wcag-em-report-tool/blob/master/dataformat.md#', 10 | conformanceTarget: { id: 'step1b', type: 'id' }, 11 | evaluationScope: { id: 'step1' }, 12 | accessibilitySupportBaseline: { id: 'step1c' }, 13 | additionalEvalRequirement: { id: 'step1d' }, 14 | siteScope: { id: 'step1a' }, 15 | commonPages: { id: 'step2a' }, 16 | essentialFunctionality: { id: 'step2b' }, 17 | pageTypeVariety: { id: 'step2c' }, 18 | otherRelevantPages: { id: 'step2e' }, 19 | structuredSample: { id: 'step3a' }, 20 | randomSample: { id: 'step3b' }, 21 | specifics: { id: 'step5b' }, 22 | auditResult: { id: 'step4' }, 23 | outcome: { type: 'id' }, 24 | subject: { type: 'id' }, 25 | assertedBy: { type: 'id' }, 26 | testRequirement: { type: 'id' }, 27 | creator: { type: 'id' }, 28 | handle: 'reporter:handle', 29 | description: 'reporter:description', 30 | tested: 'reporter:tested', 31 | id: '@id', 32 | type: '@type', 33 | title: 'dct:title', 34 | hasPart: 'dct:hasPart', 35 | specs: '@id', 36 | reliedUponTechnology: 'wcag20:reliedupondef' 37 | }); 38 | -------------------------------------------------------------------------------- /app/scripts/services/context/evalContextV3.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular 4 | .module('wcagReporter') 5 | .constant('evalContextV3', { 6 | // Current namespace 7 | '@vocab': 'http://www.w3.org/TR/WCAG-EM/#', 8 | 9 | // Namespaces 10 | reporter: 'https://github.com/w3c/wcag-em-report-tool/', 11 | wcagem: 'http://www.w3.org/TR/WCAG-EM/#', 12 | WCAG2: 'http://www.w3.org/TR/WCAG21/#', 13 | earl: 'http://www.w3.org/ns/earl#', 14 | dct: 'http://purl.org/dc/terms/', 15 | wai: 'http://www.w3.org/WAI/', 16 | sch: 'http://schema.org/', 17 | 18 | // Classes 19 | Evaluation: 'wcagem:Evaluation', 20 | EvaluationScope: 'wcagem:EvaluationScope', 21 | TestSubject: 'earl:TestSubject', 22 | WebSite: 'sch:WebSite', 23 | Sample: 'wcagem:Sample', 24 | WebPage: 'sch:WebPage', 25 | Technology: 'WCAG2:dfn-technologies', 26 | Assertion: 'earl:Assertion', 27 | Assertor: 'earl:Assertor', 28 | TestResult: 'earl:TestResult', 29 | 30 | // Evaluation class properties 31 | title: 'dct:title', 32 | summary: 'dct:summary', 33 | creator: { 34 | '@id': 'dct:creator', 35 | '@type': '@id' 36 | }, 37 | date: 'dct:date', 38 | commissioner: 'wcagem:commissioner', 39 | reliedUponTechnology: 'WCAG2:dfn-relied-upon', 40 | evaluationScope: 'step1', 41 | commonPages: 'step2a', 42 | essentialFunctionality: 'step2b', 43 | pageTypeVariety: 'step2c', 44 | otherRelevantPages: 'step2e', 45 | structuredSample: 'step3a', 46 | randomSample: 'step3b', 47 | auditResult: 'step4', 48 | specifics: 'step5b', 49 | publisher: { 50 | '@id': 'dct:publisher', 51 | '@type': '@id' 52 | }, 53 | 54 | // EvaluationScope class properties 55 | conformanceTarget: { 56 | '@id': 'step1b', 57 | '@type': '@id' 58 | }, 59 | accessibilitySupportBaseline: 'step1c', 60 | additionalEvalRequirement: 'step1d', 61 | website: 'WCAG2:dfn-set-of-web-pages', 62 | 63 | // sch:WebSite class properties 64 | siteScope: 'step1a', 65 | siteName: 'sch:name', 66 | 67 | // Sample class properties 68 | // sch:WebPage class properties 69 | webpage: 'WCAG2:dfn-web-page-s', 70 | description: 'dct:description', 71 | source: { 72 | '@id': 'dct:source', 73 | '@type': '@id' 74 | }, 75 | tested: 'reporter:blob/master/docs/EARL%2BJSON-LD.md#tested', 76 | 77 | // earl:Assertion class properties 78 | test: { 79 | '@id': 'earl:test', 80 | '@type': '@id' 81 | }, 82 | assertedBy: { 83 | '@id': 'earl:assertedBy', 84 | '@type': '@id' 85 | }, 86 | subject: { 87 | '@id': 'earl:subject', 88 | '@type': '@id' 89 | }, 90 | result: 'earl:result', 91 | mode: { 92 | '@id': 'earl:mode', 93 | '@type': '@id' 94 | }, 95 | hasPart: 'dct:hasPart', 96 | 97 | // earl:TestResult class properties 98 | outcome: { 99 | '@id': 'earl:outcome', 100 | '@type': '@id' 101 | }, 102 | 103 | // shorthand, because @ can't be used in dot notation 104 | id: '@id', 105 | type: '@type', 106 | lang: '@language' 107 | }); 108 | -------------------------------------------------------------------------------- /app/scripts/services/directivePlugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Allow developers to create plugins for a directive 5 | * 6 | * Fow now, only additional link functions are supported 7 | */ 8 | angular.module('wcagReporter') 9 | .factory('directivePlugin', function () { 10 | var func = function (directive) { 11 | var link = directive.link || function () {}; 12 | 13 | if (!directive.plugins) { 14 | directive.plugins = []; 15 | } 16 | 17 | directive.link = function () { 18 | var args = arguments; 19 | link.apply(undefined, args); 20 | 21 | directive.plugins.forEach(function (plugin) { 22 | if (plugin.link) { 23 | plugin.link.apply(undefined, args); 24 | } 25 | }); 26 | }; 27 | 28 | return directive; 29 | }; 30 | return func; 31 | }); 32 | -------------------------------------------------------------------------------- /app/scripts/services/evalLoader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .service('evalLoader', function (evalWindow, appState, fileReader, wcagReporterImport, $q) { 5 | function loadFactory (promiseGen) { 6 | var importTarget; 7 | 8 | return function () { 9 | var promise = promiseGen.apply(null, arguments); 10 | var defer = $q.defer(); 11 | 12 | function reject (e) { 13 | defer.reject(e); 14 | if (importTarget) { 15 | importTarget.abort(); 16 | } 17 | } 18 | 19 | if (!appState.empty) { 20 | try { 21 | importTarget = evalWindow.openEmptyWindow(); 22 | } catch (e) { 23 | reject('Popup blocker detected. Please allow popups so the evaluation can open in a new window.'); 24 | } 25 | } else { 26 | importTarget = evalWindow; 27 | } 28 | 29 | promise.then(function (data) { 30 | try { 31 | importTarget.loadJson(data); 32 | appState.setDirtyState(); 33 | defer.resolve(); 34 | } catch (e) { 35 | reject(e); 36 | } 37 | }, reject); 38 | 39 | return defer.promise; 40 | }; 41 | } 42 | 43 | return { 44 | openFromFile: loadFactory(function (file) { 45 | return fileReader.readAsText(file); 46 | }), 47 | 48 | openFromUrl: loadFactory(function () { 49 | return wcagReporterImport.getFromUrl(); 50 | }) 51 | }; 52 | }); 53 | -------------------------------------------------------------------------------- /app/scripts/services/evalWindow.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .service('evalWindow', function ($http, wcagReporterImport, $rootScope) { 5 | var curWindow; 6 | var waitingForEvaluation = 'waitingForEvaluation'; 7 | var loadEvaluationData = 'loadEvaluationData'; 8 | var evaluateDataWhenReady = 'evaluateDataWhenReady'; 9 | 10 | function EvalWindow () {} 11 | 12 | EvalWindow.prototype = { 13 | openEmptyWindow: function () { 14 | var newRunner = new EvalWindow(); 15 | var newWindow = window.open(window.location.href, '_blank'); 16 | 17 | newWindow[waitingForEvaluation] = true; 18 | 19 | // open a window 20 | newRunner.abort = function () { 21 | newWindow.close(); 22 | }; 23 | 24 | newRunner.loadJson = function (data) { 25 | if (newWindow[loadEvaluationData]) { 26 | newWindow[loadEvaluationData](data); 27 | } else { 28 | newWindow[evaluateDataWhenReady] = data; 29 | } 30 | // Tell the new window where to look 31 | }; 32 | 33 | return newRunner; 34 | }, 35 | 36 | loadJson: function (data) { 37 | wcagReporterImport.fromJson(data); 38 | }, 39 | 40 | abort: angular.noop 41 | }; 42 | 43 | function processPageData (data) { 44 | curWindow.loadJson(data); 45 | $rootScope.setEvalLocation(); 46 | } 47 | 48 | curWindow = new EvalWindow(); 49 | 50 | if (window[waitingForEvaluation]) { 51 | window[waitingForEvaluation] = undefined; 52 | 53 | if (window[evaluateDataWhenReady]) { 54 | processPageData(window[evaluateDataWhenReady]); 55 | } else { 56 | window[loadEvaluationData] = processPageData; 57 | } 58 | } 59 | 60 | return curWindow; 61 | }); 62 | -------------------------------------------------------------------------------- /app/scripts/services/fileReader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Original module by K. Scott Allen 3 | * http://odetocode.com/blogs/scott/archive/2013/07/03/building-a-filereader-service-for-angularjs-the-service.aspx 4 | */ 5 | (function (module) { 6 | 'use strict'; 7 | 8 | var fileReader = function ($q, $rootScope) { 9 | var onLoad = function (reader, deferred, scope) { 10 | return function () { 11 | scope.$apply(function () { 12 | deferred.resolve(reader.result); 13 | }); 14 | }; 15 | }; 16 | 17 | var onError = function (reader, deferred, scope) { 18 | return function () { 19 | scope.$apply(function () { 20 | deferred.reject(reader.result); 21 | }); 22 | }; 23 | }; 24 | 25 | var onProgress = function (reader, scope) { 26 | return function (event) { 27 | scope.$broadcast( 28 | 'fileProgress', 29 | { 30 | total: event.total, 31 | loaded: event.loaded 32 | } 33 | ); 34 | }; 35 | }; 36 | 37 | var getReader = function (deferred, scope) { 38 | var reader = new FileReader(); 39 | reader.onload = onLoad(reader, deferred, scope); 40 | reader.onerror = onError(reader, deferred, scope); 41 | reader.onprogress = onProgress(reader, scope); 42 | return reader; 43 | }; 44 | 45 | var readAsText = function (file, scope) { 46 | scope = scope || $rootScope; 47 | var deferred = $q.defer(); 48 | var reader = getReader(deferred, scope); 49 | 50 | scope.$evalAsync(function () { 51 | try { 52 | reader.readAsText(file); 53 | } catch (e) { 54 | deferred.reject(e); 55 | } 56 | }); 57 | 58 | return deferred.promise; 59 | }; 60 | 61 | var readAsDataURL = function (file, scope) { 62 | scope = scope || $rootScope; 63 | var deferred = $q.defer(); 64 | var reader = getReader(deferred, scope); 65 | 66 | scope.$evalAsync(function () { 67 | try { 68 | reader.readAsDataURL(file); 69 | } catch (e) { 70 | deferred.reject(e); 71 | } 72 | }); 73 | 74 | return deferred.promise; 75 | }; 76 | 77 | return { 78 | readAsDataUrl: readAsDataURL, 79 | readAsText: readAsText 80 | }; 81 | }; 82 | 83 | module.factory('fileReader', [ 84 | '$q', 85 | '$rootScope', 86 | fileReader 87 | ]); 88 | }(angular.module('wcagReporter'))); 89 | -------------------------------------------------------------------------------- /app/scripts/services/helpers/isObjectLiteral.js: -------------------------------------------------------------------------------- 1 | angular 2 | .module('wcagReporter') 3 | .service('isObjectLiteral', function () { 4 | /** 5 | * isObjectLiteral tests if parameter is an object literal like: 6 | * { 7 | * key1: value1, 8 | * …, 9 | * keyN: valueN 10 | * } 11 | * @param {any} test [parameter to test] 12 | * @return {Boolean} 13 | */ 14 | function isObjectLiteral (test) { 15 | if ( 16 | typeof test === 'object' && 17 | Object.prototype.toString.call(test) === '[object Object]' 18 | ) { 19 | return true; 20 | } 21 | 22 | return false; 23 | } 24 | 25 | return isObjectLiteral; 26 | }); 27 | -------------------------------------------------------------------------------- /app/scripts/services/knownTechnologies.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .constant('knownTech', [ 5 | { title: 'HTML5', id: 'http://www.w3.org/TR/html5/', type: 'Technology' }, 6 | { title: 'XHTML 1.0', id: 'http://www.w3.org/TR/xhtml1/', type: 'Technology' }, 7 | { title: 'HTML 4.01', id: 'http://www.w3.org/TR/html401/', type: 'Technology' }, 8 | { title: 'CSS', id: 'http://www.w3.org/Style/CSS/specs/', type: 'Technology' }, 9 | { title: 'WAI-ARIA', id: 'http://www.w3.org/TR/wai-aria/', type: 'Technology' }, 10 | { title: 'ECMAScript 3', id: 'http://www.ecma-international.org/publications/standards/Ecma-327.htm', type: 'Technology' }, 11 | { title: 'ECMAScript 5', id: 'http://www.ecma-international.org/publications/standards/Ecma-262.htm', type: 'Technology' }, 12 | { title: 'DOM', id: 'http://www.w3.org/DOM/', type: 'Technology' }, 13 | { title: 'Flash', id: 'http://get.adobe.com/nl/flashplayer/', type: 'Technology' }, 14 | { title: 'Silverlight', id: 'http://www.microsoft.com/silverlight/', type: 'Technology' }, 15 | { title: 'OOXML', id: 'http://www.ecma-international.org/publications/standards/Ecma-376.htm', type: 'Technology' }, 16 | { title: 'ODF 1.2', id: 'https://www.oasis-open.org/standards#opendocumentv1.2', type: 'Technology' }, 17 | { title: 'SVG', id: 'http://www.w3.org/TR/SVG/', type: 'Technology' } 18 | ]); 19 | -------------------------------------------------------------------------------- /app/scripts/services/pkgData.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .value('pkgData', { 5 | name: '<%= pkg.name =%>', 6 | version: '<%= pkg.version =%>', 7 | buildDate: '<%= pkg.buildDate =%>' 8 | }); 9 | -------------------------------------------------------------------------------- /app/scripts/services/reportStorage.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .service('reportStorage', function ($http, $rootScope, appState, $timeout) { 5 | var reportStorage; var autosave; var loading; 6 | var failedSaveAttempts = 0; 7 | var settings = { 8 | url: undefined, 9 | revisionId: undefined, 10 | autosave: false, 11 | saveDelay: 3000 12 | }; 13 | 14 | function startAutosave () { 15 | if (!settings.url) { 16 | settings.autosave = false; 17 | return; 18 | } 19 | autosave = $timeout(function autosaveFunc () { 20 | reportStorage.exportModel.saveToUrl() 21 | .then(function () { 22 | failedSaveAttempts = 0; 23 | }, function () { 24 | failedSaveAttempts += 1; 25 | if (settings.autosave) { 26 | autosave = $timeout( 27 | autosaveFunc, 28 | settings.saveDelay * failedSaveAttempts, 29 | 0, 30 | false 31 | ); 32 | } 33 | }); 34 | }, settings.saveDelay, 0, false); 35 | } 36 | 37 | $rootScope.$on('appstate:prestine', function () { 38 | if (autosave) { 39 | $timeout.cancel(autosave); 40 | autosave = undefined; 41 | } 42 | }); 43 | 44 | $rootScope.$on('appstate:dirty', function () { 45 | if (settings.autosave && autosave === undefined) { 46 | startAutosave(); 47 | } 48 | }); 49 | 50 | reportStorage = { 51 | settings: settings, 52 | 53 | exportModel: undefined, 54 | 55 | init: function (obj) { 56 | reportStorage.updateSettings(obj); 57 | }, 58 | 59 | updateSettings: function (obj) { 60 | if (obj) { 61 | angular.extend(settings, obj); 62 | } 63 | 64 | if (settings.autosave && loading) { 65 | loading.then(startAutosave); 66 | } else if (settings.autosave) { 67 | startAutosave(); 68 | } 69 | }, 70 | 71 | post: function (json) { 72 | if (settings.revisionId) { 73 | json._rev = settings.revisionId; 74 | } 75 | return $http.put(settings.url, json, {}, { 76 | withCredentials: true 77 | }) 78 | .then(function (response) { 79 | if (response && response.data && response.data.rev) { 80 | settings.revisionId = response.data.rev; 81 | } 82 | appState.setPrestineState(); 83 | return response.data; 84 | }); 85 | }, 86 | 87 | get: function () { 88 | $timeout.cancel(autosave); 89 | loading = $http.get(settings.url, {}, { 90 | withCredentials: true 91 | }) 92 | .then(function (response) { 93 | if (response.data._rev) { 94 | settings.revisionId = response.data._rev; 95 | } 96 | appState.setPrestineState(); 97 | return response.data; 98 | }); 99 | return loading; 100 | } 101 | }; 102 | 103 | return reportStorage; 104 | }); 105 | -------------------------------------------------------------------------------- /app/scripts/services/toggleCriterionText.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('wcagReporter') 4 | .value('toggleCriterionText', function toggleCriterionText (elm) { 5 | var expandState = [ 6 | true, 7 | 'true' 8 | ].indexOf(elm.getAttribute('aria-expanded')) !== -1; 9 | elm.setAttribute('aria-expanded', !expandState); 10 | 11 | var section = elm.parentNode.parentNode.nextSibling; 12 | section.classList.toggle('collapsed'); 13 | }); 14 | -------------------------------------------------------------------------------- /app/scripts/services/types.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular 4 | .module('wcagReporter') 5 | .constant('types', { 6 | EARL: { 7 | type: 'earl', 8 | MODE: { 9 | type: 'earl:TestMode', 10 | MANUAL: 'earl:manual' 11 | }, 12 | OUTCOME: { 13 | type: 'earl:OutcomeValue', 14 | CANNOT_TELL: 'earl:CannotTell', 15 | CANT_TELL: 'earl:cantTell', 16 | INAPPLICABLE: 'earl:inapplicable', 17 | FAIL: 'earl:Fail', 18 | FAILED: 'earl:failed', 19 | NOT_APPLICABLE: 'earl:NotApplicable', 20 | NOT_TESTED: 'earl:NotTested', 21 | PASS: 'earl:Pass', 22 | PASSED: 'earl:passed', 23 | UNTESTED: 'earl:untested' 24 | }, 25 | RESULT: { 26 | class: 'TestResult', 27 | type: 'earl:TestResult' 28 | } 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /app/scripts/templates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a dummy script. When the app is build the module in this script 3 | * is replaced with a auto-generated compilation of all the templates. 4 | */ 5 | angular.module('wert-templates', []); 6 | -------------------------------------------------------------------------------- /app/styles/animation.scss: -------------------------------------------------------------------------------- 1 | @import "../bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap/_mixins.scss"; 2 | @import "../bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap/_variables.scss"; 3 | 4 | .appear, 5 | .appear-tall { 6 | 7 | &.ng-enter, 8 | &.ng-leave { 9 | @include transition(200ms linear all); 10 | 11 | position: relative; 12 | display: block; 13 | overflow: hidden; 14 | text-overflow: clip; 15 | white-space: nowrap; 16 | } 17 | } 18 | 19 | 20 | .reporter-view { 21 | 22 | &.ng-enter, 23 | &.ng-leave { 24 | @include transition(200ms linear opacity); 25 | } 26 | 27 | /* When leaving, put the element in the same place, but don't let it take 28 | up screen space. This is for the new view */ 29 | &.ng-leave {/* starting animations for enter */ 30 | position: absolute; 31 | left: 50%; 32 | 33 | @include translate(-50%, 0); 34 | } 35 | 36 | &.ng-leave, 37 | &.ng-enter.ng-enter-active { 38 | 39 | /* terminal animations for leave */ 40 | opacity: 1; 41 | } 42 | 43 | &.ng-enter, 44 | &.ng-leave.ng-leave-active { 45 | 46 | /* terminal animations for leave */ 47 | opacity: 0; 48 | } 49 | } 50 | 51 | .appear, 52 | .appear-tall { 53 | 54 | &.ng-enter, 55 | &.ng-leave.ng-leave-active { 56 | 57 | /* terminal animations for leave */ 58 | opacity: 0; 59 | max-height: 0; 60 | } 61 | } 62 | 63 | .appear.ng-leave, /* starting animations for leave */ 64 | .appear.ng-enter.ng-enter-active { 65 | 66 | /* terminal animations for enter */ 67 | opacity: 1; 68 | max-height: 60px; 69 | } 70 | 71 | .appear-tall.ng-leave, /* starting animations for leave */ 72 | .appear-tall.ng-enter.ng-enter-active { 73 | 74 | /* terminal animations for enter */ 75 | opacity: 1; 76 | max-height: 400px; 77 | } 78 | -------------------------------------------------------------------------------- /app/styles/bootstrap-extend.scss: -------------------------------------------------------------------------------- 1 | @import "../bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap/_mixins.scss"; 2 | @import "../bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap/_variables.scss"; 3 | 4 | $focus-color: #477ba5; 5 | 6 | 7 | .dropdown-menu.lang-menu > li > a { 8 | padding-left: 10px; 9 | } 10 | 11 | body { 12 | 13 | .form-horizontal .control-label { 14 | text-align: left; 15 | } 16 | 17 | .alert { 18 | margin-bottom: 10px; 19 | } 20 | 21 | .btn > button { 22 | border: none; 23 | background: transparent; 24 | margin: -1px -5px; 25 | padding: 1px 5px; 26 | } 27 | 28 | .btn-default { 29 | border-color: #888; 30 | background-color: $body-bg; 31 | } 32 | 33 | .btn-group > input { 34 | float: left; 35 | } 36 | 37 | .btn.btn-primary-invert { 38 | background-color: $body-bg; 39 | } 40 | 41 | .navbar-nav > li > a { 42 | text-decoration: none; 43 | } 44 | 45 | .key-value-group { 46 | text-indent: 0; 47 | } 48 | } 49 | 50 | .alert { 51 | position: relative; 52 | 53 | .floater { 54 | width: 30px; 55 | height: 30px; 56 | float: right; 57 | } 58 | 59 | .close { 60 | position: absolute; 61 | top: 15px; 62 | right: 15px; 63 | } 64 | } 65 | 66 | label { 67 | display: inline; 68 | 69 | &::after { 70 | content: "\200B"; 71 | display: inline-block; 72 | margin-bottom: 5px; 73 | } 74 | } 75 | 76 | .alert p:last-child { 77 | margin-bottom: 0; 78 | } 79 | 80 | * a:focus, 81 | * button:focus, 82 | * .dropdown-toggle:focus { 83 | outline: thin solid $focus-color; 84 | } 85 | 86 | .form-control:focus { 87 | border-color: $focus-color; 88 | } 89 | 90 | .active *:focus { 91 | outline-color: white; 92 | } 93 | 94 | .dropdown-menu a { 95 | text-decoration: none; 96 | } 97 | 98 | @media (min-width: $screen-sm-min) { 99 | 100 | .visible-xs-and-sr { 101 | position: absolute !important; 102 | top: -9999em; 103 | } 104 | 105 | body .navbar-nav > li > a { 106 | border-left: solid 1px #ccc; 107 | } 108 | } 109 | 110 | @media (max-width: $screen-sm-min) { 111 | 112 | body .visible-xs-and-sr { 113 | position: relative !important; 114 | clear: left; 115 | } 116 | 117 | body .navbar-nav { 118 | margin: 0; 119 | 120 | & > li > a { 121 | border-top: solid 1px #ccc; 122 | } 123 | 124 | .dropdown-menu { 125 | padding: 0; 126 | 127 | > li > a { 128 | border-top: solid 1px #ccc; 129 | } 130 | } 131 | } 132 | 133 | label { 134 | line-height: 1em; 135 | } 136 | 137 | .expanding { 138 | margin-top: 5px; 139 | } 140 | 141 | .form-block .form-control { 142 | margin-top: -5px; 143 | margin-bottom: 5px; 144 | } 145 | } 146 | 147 | .crit-detail-btn { 148 | padding: 2px; 149 | 150 | .btn { 151 | width: 100%; 152 | padding: 4px; 153 | } 154 | } 155 | 156 | .form-group .alert { 157 | margin-top: 1em; 158 | } 159 | -------------------------------------------------------------------------------- /app/styles/hint.scss: -------------------------------------------------------------------------------- 1 | @import "../bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap/_variables.scss"; 2 | 3 | $hint-back: $text-color; 4 | $hint-color: white; 5 | $hint-arrow-size: 10px; 6 | $hint-font: sans-serif; 7 | $hint-overlap: 3px; 8 | $hint-border-radius: 4px; 9 | $hint-padding-h: 10px; 10 | $hint-padding-v: 7px; 11 | $hint-speed: 0.2s; 12 | $hint-delay: 0.2s; 13 | 14 | * > .hint { 15 | float: left; 16 | pointer-events: none; 17 | display: none; 18 | cursor: default; 19 | line-height: 1em; 20 | opacity: 0; 21 | transition: opacity $hint-speed; 22 | transition-delay: 0s; 23 | position: absolute; 24 | display: block; 25 | top: $hint-overlap - $hint-arrow-size; 26 | background: $hint-back; 27 | border-radius: $hint-border-radius; 28 | padding: $hint-padding-v $hint-padding-h; 29 | left: 50%; 30 | transform: translate(-50%, -100%); 31 | font-family: $hint-font; 32 | color: $hint-color; 33 | z-index: 100; 34 | 35 | &::before { 36 | content: " "; 37 | width: 100%; 38 | height: $hint-arrow-size - $hint-overlap; 39 | position: absolute; 40 | top: 100%; 41 | left: 0; 42 | } 43 | 44 | &::after { 45 | content: " "; 46 | width: 0; 47 | height: 0; 48 | border-left: 1+$hint-arrow-size solid transparent; 49 | border-right: 1+$hint-arrow-size solid transparent; 50 | border-top: 1+$hint-arrow-size solid $hint-back; 51 | position: absolute; 52 | bottom: 0 - $hint-arrow-size; 53 | left: 50%; 54 | transform: translateX(-50%); 55 | } 56 | } 57 | 58 | *:focus, 59 | *:hover { 60 | 61 | > .hint { 62 | pointer-events: auto; 63 | opacity: 1; 64 | transition-delay: $hint-delay; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/styles/wizard.scss: -------------------------------------------------------------------------------- 1 | @import "../bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap/_mixins.scss"; 2 | @import "../bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap/_variables.scss"; 3 | 4 | $wzrd-v-padding: 8px; 5 | $wzrd-h-padding: 5px; 6 | $wzrd-border-rad: 8px; 7 | $wzrd-gap: 5px; 8 | $wzrd-arrow-size: floor($wzrd-v-padding + ($font-size-base/2) + 3px); 9 | $wzrd-v-padding-outer: 12px; 10 | $wzrd-bg: #dfdfdf; 11 | $wzrd-indent: 1em; 12 | 13 | .wizard { 14 | margin: 0 0 0 $wzrd-indent; 15 | padding: 0; 16 | list-style: none; 17 | 18 | .wizard-step { 19 | padding: $wzrd-v-padding ($wzrd-h-padding + 1) $wzrd-v-padding $wzrd-h-padding; 20 | padding-left: $wzrd-arrow-size + $wzrd-h-padding; 21 | margin: ($wzrd-gap/2) 0 ($wzrd-gap/2) $wzrd-gap; 22 | background: $wzrd-bg; 23 | position: relative; 24 | display: inline-block; 25 | 26 | @include border-right-radius(3px); 27 | 28 | a { 29 | margin: (0-$wzrd-v-padding) (0-$wzrd-h-padding); 30 | padding: $wzrd-v-padding $wzrd-h-padding; 31 | display: block; 32 | color: $link-hover-color; 33 | } 34 | 35 | a:hover { 36 | color: black; 37 | } 38 | 39 | &::before, 40 | &::after { 41 | width: 0; 42 | height: 0; 43 | top: 0; 44 | position: absolute; 45 | content: ""; 46 | border-top: $wzrd-arrow-size inset transparent; 47 | border-bottom: $wzrd-arrow-size inset transparent; 48 | } 49 | 50 | &::before { 51 | border-left: $wzrd-arrow-size solid $body-bg; 52 | left: 0; 53 | } 54 | 55 | &::after { 56 | border-left: $wzrd-arrow-size solid $wzrd-bg; 57 | right: (1 - $wzrd-arrow-size); 58 | z-index: 2; 59 | } 60 | 61 | &:first-child::before, 62 | &:last-child::after { 63 | border: none; 64 | } 65 | 66 | &:first-child { 67 | @include border-left-radius($wzrd-border-rad); 68 | 69 | padding-left: $wzrd-v-padding-outer; 70 | margin-left: (0 - $wzrd-indent); 71 | } 72 | 73 | &:last-child { 74 | @include border-right-radius($wzrd-border-rad); 75 | 76 | padding-right: $wzrd-v-padding-outer; 77 | } 78 | 79 | &.active { 80 | background: $brand-primary; 81 | color: $btn-primary-color; 82 | 83 | a { 84 | color: $btn-primary-color; 85 | text-decoration: none; 86 | } 87 | 88 | &::after { 89 | border-left-color: $brand-primary; 90 | } 91 | } 92 | 93 | &.disabled a { 94 | font-style: italic; 95 | color: $btn-link-disabled-color; 96 | 97 | &:hover { 98 | text-decoration: none; 99 | } 100 | } 101 | } 102 | 103 | .badge { 104 | margin-right: 5px; 105 | position: relative; 106 | top: -1px; 107 | } 108 | 109 | .wizard-step:first-child .badge { 110 | margin-left: 0; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /app/views/directives/buttonCollapse.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/views/directives/criterion/criterionBody.html: -------------------------------------------------------------------------------- 1 |17 | {{ 'SAMPLE.NO_PAGES_DEFINED' | translate}} 18 |
19 | 20 | 51 | 52 | 56 |4 | {{'HTML_REPORT.BY' | translate }} {{report.creator.name}}, 5 | {{report.date | date: shortDate}} 6 |
7 |8 | {{'HTML_REPORT.COMMISION_BY' | translate }} {{report.commissioner}} 9 |
10 | 11 |{{spec.text}}
18 |
36 | {{ "AUDIT.NOTE" | translate }}: {{ details.text}} 37 |
38 |40 | {{ "AUDIT.UNDERSTAND" | translate }} {{spec.number}} 44 | 45 | {{ "AUDIT.HOW_TO" | translate }} {{spec.number}} 49 | 50 |
51 |{{ 'ERROR.INTRO' | translate }}
7 | 8 |{{ 'AUDIT.INF_AUDIT_CRITERIA' | translate }}
11 |{{ 'AUDIT.NO_SAMPLE' | translate }}
33 | 34 |{{ feedback.message }}
8 |{{ 'IMPORT.INTRO' | translate }}
13 |14 | 17 | 18 |
19 |File “{{importFile.name}}” is ready to be imported.
24 |We have found 25 | {{ assertionImport.length }} 26 | asserertions that can be inserted into the evaluation audit results
27 | 28 |Imported 38 | {{ assertionImport.length }} 39 | asserertions and inserted to the audit results.
40 | 41 | 42 |45 | {{'NAV.BTN_BACK_TO_EVAL' | translate}} 46 |
47 |{{ 'OPEN.INTRO' | translate }}
7 | 8 |{{ 'OPEN.MSG_LOADING' | translate }}
10 |{{fileFeedback.failure}}
13 |{{ 'OPEN.' + showError | translate }} 27 |
{{'HTML_REPORT.LABEL_SITE_NAME' | translate}} | 3 |{{scope.website.siteName}} |
---|---|
{{'HTML_REPORT.LABEL_SITE_SCOPE' | translate}} | 7 |8 | |
{{ 'SCOPE.LABEL_WCAG_VERSION' | translate }} | 11 |{{ 'SCOPE.' + scope.wcagVersion | translate }} |
{{ 'HTML_REPORT.LABEL_CONFORMANCE_TGT' | translate }} | 14 |{{scope.conformanceTarget | rdfToLabel}} |
{{ 'HTML_REPORT.LABEL_EXTRA_REQUIREMENTS' | translate }} | 17 ||
{{ 'HTML_REPORT.LABEL_SUPPORT_BASE' | translate }} | 20 ||
{{ 'HTML_REPORT.LABEL_RELIEDUP_TECH' | translate }} | 24 |
|
31 |
{{ 'HTML_REPORT.PRINCIPLE' | translate }} | 11 |{{ 'EARL.LEVEL_A' | translate }} | 12 |{{ 13 | 'EARL.LEVEL_AA' | translate 14 | }} | 15 |{{ 16 | 'EARL.LEVEL_AAA' | translate 17 | }} | 18 |
---|---|---|---|
{{score.name}} | 22 |{{ 23 | score['level_a'].pass + ' / ' + 24 | score['level_a'].total 25 | }} | 26 |{{ 27 | score['level_aa'].pass + ' / ' + 28 | score['level_aa'].total 29 | }} | 30 |{{ 31 | score['level_aaa'].pass + ' / ' + 32 | score['level_aaa'].total 33 | }} | 34 |
{{ 'HTML_REPORT.TOTAL_SCORE' | translate }} | 37 |{{ 38 | totals['level_a'].pass + ' / ' + 39 | totals['level_a'].total 40 | }} | 41 |{{ 42 | totals['level_aa'].pass + ' / ' + 43 | totals['level_aa'].total 44 | }} | 45 |{{ 46 | totals['level_aaa'].pass + ' / ' + 47 | totals['level_aaa'].total 48 | }} | 49 |
{{ 'SAVE.INTRO' | translate }}
7 | 8 | 13 | 14 | 17 | 18 | 19 |