accessibility_scanner-8.x-1.0-alpha8/js/gchart-axecore-cli.js

js/gchart-axecore-cli.js
/**
 * @file
 * Provides some very basic filtering functionality for @axe-core/cli results.
 */

(function ($, Drupal, drupalSettings) {
  'use strict';

  var chartObj = {
    defaultState: {
      allTags: {},
      currentUrl: '#all_urls',
      disabledPassFail: { pass: false, fail: false },
      disabledTags: { '#all_tags': true },
      maxUrls: 50,
    },
    state: {},
    stateKey: 'axecore-cli-history-state',
    redrawTimeout: null,
    tagLabels: {
      'wcag2a': Drupal.t('WCAG 2.0 Level A'),
      'wcag2aa': Drupal.t('WCAG 2.0 Level AA'),
      'wcag21a': Drupal.t('WCAG 2.1 Level A'),
      'wcag21aa': Drupal.t('WCAG 2.1 Level AA'),
      'best-practice': Drupal.t('Common accessibility best practices'),
      'ACT': Drupal.t('W3C approved Accessibility Conformance Testing rules'),
      'section508': Drupal.t('Old Section 508 rules'),
      'experimental': Drupal.t('Cutting-edge rules'),
    },
    drawCharts: function () {
      clearTimeout(chartObj.redrawTimeout);
      setTimeout(function () {
        if (chartObj.hasHistoricalChart()) {
          chartObj.init();
          chartObj.drawHistoricalCharts();
          chartObj.generateUrlFilter();
          chartObj.generatePassFailFilter();
          chartObj.generateTagFilter();
          chartObj.generateResetButton();
          localStorage.setItem(chartObj.stateKey, JSON.stringify(chartObj.state));
        }
        if (chartObj.hasPreviewChart()) {
          chartObj.drawPreviewChart();
        }
      }, 100);
    },
    drawHistoricalChartGenericViolation: function (chart, chartTitle, violationType, countType) {
      var data = new google.visualization.DataTable();
      data.addColumn('date', 'Date');
      data.addColumn('number', Drupal.t('Critical'));
      data.addColumn('number', Drupal.t('Serious'));
      data.addColumn('number', Drupal.t('Moderate'));
      data.addColumn('number', Drupal.t('Minor'));

      Object.keys(drupalSettings.axeCoreCliReportData).forEach(function (timestamp) {
        var details = drupalSettings.axeCoreCliReportData[timestamp][chartObj.state.currentUrl];
        if (typeof details === 'undefined') {
          return;
        }

        var row = [
          new Date(1000 * timestamp),
        ];

        var totals = {
          critical: 0,
          serious: 0,
          moderate: 0,
          minor: 0,
        };
        Object.keys(totals).forEach(function (severity) {
          Object.keys(details).forEach(function (tag) {
            if (!chartObj.state.disabledTags[tag]) {
              totals[severity] += details[tag][violationType][severity][countType];
            }
          });
          row.push(totals[severity]);
        });
        data.addRow(row);
      });

      var options = {
        title: chartTitle,
        chartArea: {
          width: '90%',
        },
        curveType: 'function',
        legend: { position: 'top', maxLines: 5 }
      };

      var gChart = new google.visualization.LineChart(chart);
      gChart.draw(data, options);
    },
    drawHistoricalChartDistinctIncomplete: function (chart) {
      chartObj.drawHistoricalChartGenericViolation(chart, Drupal.t('Distinct Rules Needing Review'), 'incomplete', 'distinct');
    },
    drawHistoricalChartDistinctViolations: function (chart) {
      chartObj.drawHistoricalChartGenericViolation(chart, Drupal.t('Distinct Rule Violations'), 'violations', 'distinct');
    },
    drawHistoricalChartTotalIncomplete: function (chart) {
      chartObj.drawHistoricalChartGenericViolation(chart, Drupal.t('Total Elements Needing Review'), 'incomplete', 'total');
    },
    drawHistoricalChartTotalViolations: function (chart) {
      chartObj.drawHistoricalChartGenericViolation(chart, Drupal.t('Total Violations'), 'violations', 'total');
    },
    drawHistoricalChartPassFail: function (chart) {
      var data = new google.visualization.DataTable();
      data.addColumn('date', 'Date');
      var isFirst = true;
      var chartTags = [];

      Object.keys(drupalSettings.axeCoreCliReportData).forEach(function (timestamp) {
        var details = drupalSettings.axeCoreCliReportData[timestamp];
        var row = [new Date(1000 * timestamp)];

        isFirst && Object.keys(chartObj.state.allTags).sort().forEach(function (tag) {
          if (!chartObj.state.disabledTags[tag]) {
            if (!chartObj.state.disabledPassFail['pass']) {
              data.addColumn('number', Drupal.t('Passing @standard', { '@standard': chartObj.tagLabels[tag] }));
            }
            if (!chartObj.state.disabledPassFail['fail']) {
              data.addColumn('number', Drupal.t('Failing @standard', { '@standard': chartObj.tagLabels[tag] }));
            }
            chartTags.push(tag);
          }
        });

        chartTags.forEach(function(tag) {
          if (!chartObj.state.disabledTags[tag]) {
            if (!chartObj.state.disabledPassFail['pass']) {
              row.push(details['#passing'][tag] || 0);
            }
            if (!chartObj.state.disabledPassFail['fail']) {
              row.push(details['#failing'][tag] || 0);
            }
          }
        });
        data.addRow(row);
        isFirst && (isFirst = false);
      });

      var options = {
        title: Drupal.t('Passing/Failing URLs'),
        chartArea: {
          width: '90%',
        },
        curveType: 'function',
        legend: { position: 'top', maxLines: 5 }
      };

      var gChart = new google.visualization.LineChart(chart);
      gChart.draw(data, options);
    },
    drawHistoricalCharts: function() {
      var charts = document.getElementsByClassName('axecore-cli-history__chart');
      for (var i = 0; i < charts.length; i++) {
        var chart = charts[i];
        chart.classList.add('axecore-cli-history__chart' + chart.dataset.type);
        var chartKey = 'drawHistoricalChart' + chart.dataset.type;
        if (typeof chartObj[chartKey] === 'function') {
          chartObj[chartKey](chart);
        }
      }
    },
    drawPreviewChart: function () {
      var colorPalette = ['#bb1818', '#f46d12', '#e7b416', '#1c6e8c', '#a8a8a8', '#2dc937'];
      var charts = document.getElementsByClassName('axecore-cli-summary__chart');
      for (var i = 0; i < charts.length; i++) {
        var chart = charts[i];
        var total = +chart.dataset.violations + +chart.dataset.passes + +chart.dataset.incomplete;
        var data = [
          [Drupal.t('Type'), Drupal.t('Quantity')],
          [Drupal.t('Violations (Critical)'), +chart.dataset.violationsCritical],
          [Drupal.t('Violations (Serious)'), +chart.dataset.violationsSerious],
          [Drupal.t('Violations (Moderate)'), +chart.dataset.violationsModerate],
          [Drupal.t('Violations (Minor)'), +chart.dataset.violationsMinor],
          [Drupal.t('Needs Review'), +chart.dataset.incomplete],
          [Drupal.t('Passing'), +chart.dataset.passes],
        ];

        var dataTable = google.visualization.arrayToDataTable(data);
        var chart = new google.visualization.PieChart(chart);
        var options = {
          annotations: {
            alwaysOutside: true,
            textStyle: {
              fontSize: 16,
              auraColor: 'none',
              color: '#555'
            },
          },
          chart: {
            title: '',
            subtitle: '',
          },
          chartArea:{left:0,top:0,bottom:0,top:0, width: '100%'},
          colors: colorPalette,
        };

        chart.draw(dataTable, options);
      }
    },
    generateUrlFilter: function() {
      var filterEl = document.querySelector('.axecore_cli-history__filterUrl');
      filterEl.innerHTML = '';
      var fieldSetEl = document.createElement('fieldset');
      var legendEl = document.createElement('legend');
      legendEl.innerText = Drupal.t('Filter by URL');
      fieldSetEl.appendChild(legendEl);

      var inputEl = document.createElement('input');
      inputEl.type = 'text';
      inputEl.id = 'filterUrl';
      inputEl.name = 'filterUrl';
      inputEl.value = chartObj.state.currentUrl !== '#all_urls' ? chartObj.state.currentUrl : '';
      inputEl.classList.add('axecore_cli-history__filterUrl');

      var labelEl = document.createElement('label');
      labelEl.htmlFor = inputEl.id;
      labelEl.appendChild(document.createTextNode('URL'));

      var descriptionEl = document.createElement('div');
      descriptionEl.classList.add('description');
      descriptionEl.innerText = Drupal.t('Start typing a URL to filter the results for that URL. Empty field out if you want to see the summary report across all URLs.');

      fieldSetEl.appendChild(labelEl);
      fieldSetEl.appendChild(inputEl);
      fieldSetEl.appendChild(descriptionEl);

      filterEl.appendChild(fieldSetEl);

      // We unfortunately have to use jQuery for the autocompletion to work.
      $(inputEl).autocomplete({
        source: Object.keys(chartObj.allUrls),
        select: function (event, ui) {
          chartObj.state.currentUrl = ui.item.value;
          chartObj.drawCharts();
        },
      });

      // If we blank out the field, we need to revert back to all URLs.
      inputEl.addEventListener('keyup', function (el) {
        if (el.target.value === '') {
          chartObj.state.currentUrl = '#all_urls';
          chartObj.drawCharts();
        }
      });
    },
    generateTagFilter: function () {
      var filterEl = document.querySelector('.axecore_cli-history__filterTag');
      filterEl.innerHTML = '';
      var fieldSetEl = document.createElement('fieldset');
      var legendEl = document.createElement('legend');
      legendEl.innerText = Drupal.t('Filter by Accessibility Standard');
      fieldSetEl.appendChild(legendEl);
      Object.keys(chartObj.state.allTags).sort().forEach(function (tag) {
        if (tag === '#all_tags') { return; }
        var checkboxEl = document.createElement('input');
        checkboxEl.type = 'checkbox';
        checkboxEl.id = 'filterTag-' + tag;
        checkboxEl.name = 'filterTag';
        checkboxEl.value = tag;
        if (!chartObj.state.disabledTags[tag]) {
          checkboxEl.checked = true;
        }
        checkboxEl.addEventListener('change', chartObj.setFilterValues);
        var labelEl = document.createElement('label');
        labelEl.htmlFor = checkboxEl.id;
        labelEl.appendChild(document.createTextNode(chartObj.tagLabels[tag]));

        var checkboxWrapperEl = document.createElement('div');
        checkboxWrapperEl.classList.add('axecore_cli-history__filterCheckboxWrapper');
        checkboxWrapperEl.appendChild(checkboxEl);
        checkboxWrapperEl.appendChild(labelEl);

        fieldSetEl.appendChild(checkboxWrapperEl);
      });
      filterEl.appendChild(fieldSetEl);
    },
    generatePassFailFilter: function () {
      var filterEl = document.querySelector('.axecore_cli-history__filterPassFail');
      filterEl.innerHTML = '';
      var fieldSetEl = document.createElement('fieldset');
      var legendEl = document.createElement('legend');
      legendEl.innerText = Drupal.t('Filter by Pass/Fail Status');
      fieldSetEl.appendChild(legendEl);
      var filters = {
        pass: Drupal.t('Passing'),
        fail: Drupal.t('Failing'),
      };
      Object.keys(filters).forEach(function (val) {
        var checkboxEl = document.createElement('input');
        checkboxEl.type = 'checkbox';
        checkboxEl.id = 'filterPassFail-' + val;
        checkboxEl.name = 'filterPassFail';
        checkboxEl.value = val;
        if (!chartObj.state.disabledPassFail[val]) {
          checkboxEl.checked = true;
        }
        checkboxEl.addEventListener('change', chartObj.setFilterValues);
        var labelEl = document.createElement('label');
        labelEl.htmlFor = checkboxEl.id;
        labelEl.appendChild(document.createTextNode(filters[val]));

        var checkboxWrapperEl = document.createElement('div');
        checkboxWrapperEl.classList.add('axecore_cli-history__filterCheckboxWrapper');
        checkboxWrapperEl.appendChild(checkboxEl);
        checkboxWrapperEl.appendChild(labelEl);

        fieldSetEl.appendChild(checkboxWrapperEl);
      });
      filterEl.appendChild(fieldSetEl);
    },
    generateResetButton: function() {
      var buttonWrapperEl = document.querySelector('.axecore_cli-history__filterReset');
      buttonWrapperEl.innerHTML = '';
      var buttonEl = document.createElement('button');
      buttonEl.innerText = Drupal.t('Reset Filters');
      buttonEl.type = 'reset';
      buttonEl.addEventListener('click', function() {
        chartObj.resetState();
        chartObj.drawCharts();
      });
      buttonWrapperEl.appendChild(buttonEl);
    },
    hasHistoricalChart: function () {
      return !!document.querySelector('.axecore-cli-history__chart');
    },
    hasPreviewChart: function() {
      return !!document.querySelector('.axecore-cli-summary__chart');
    },
    setFilterValues: function(el) {
      if (el.target.name === 'filterTag') {
        chartObj.state.disabledTags[el.target.value] = !el.target.checked;
      }
      else if (el.target.name === 'filterPassFail') {
        chartObj.state.disabledPassFail[el.target.value] = !el.target.checked;
      }
      chartObj.drawCharts();
    },
    setState: function(state) {
      chartObj.state = state;
    },
    resetState: function() {
      chartObj.state = chartObj.defaultState;
    },
    loadStateFromStorage: function() {
      var state = null;
      try {
        state = JSON.parse(localStorage.getItem(chartObj.stateKey));
      }
      catch (exception) {
        console.error(Drupal.t('State was malformed. Resetting to default value.'));
      }
      finally {
        if (state) {
          chartObj.setState(state);
        }
        else {
          chartObj.resetState();
        }
      }
    },
    init: function() {
      var reportDataKeys = Object.keys(drupalSettings.axeCoreCliReportData);
      var relevantTags = [];
      chartObj.allUrls = {};

      // Set all relevant tags.
      reportDataKeys.forEach(function (timestamp) {
        var details = drupalSettings.axeCoreCliReportData[timestamp];
        Object.keys(details['#tags']).forEach(function (tag) {
          chartObj.state.allTags[tag] = true;
          if (!chartObj.state.disabledTags[tag]) {
            relevantTags[chartObj.tagLabels[tag]] = true;
          }
        });

        Object.keys(details).forEach(function(url) {
          if (url.charAt(0) !== '#') {
            chartObj.allUrls[url] = true;
          }
        })
      });

      // Set results title.
      var titleEl = document.querySelector('.axecore_cli-history__resultsTitle');
      if (chartObj.state.currentUrl === '#all_urls') {
        titleEl.innerText = Drupal.t('All Scanned URLs');
      }
      else {
        titleEl.innerText = chartObj.state.currentUrl;
      }

      // Set date range.
      var dateFrom = new Date(1000 * Math.min(...reportDataKeys));
      var dateTo = new Date(1000 * Math.max(...reportDataKeys));
      var dateRangeEl = document.querySelector('.axecore_cli-history__resultsDateRange');
      dateRangeEl.innerText = Drupal.t('@from to @to', {
        '@from': dateFrom.toLocaleDateString(),
        '@to': dateTo.toLocaleDateString(),
      });

      // Set the standards details.
      var standardsEl = document.querySelector('.axecore_cli-history__resultsStandards');
      standardsEl.innerHTML = '';
      Object.keys(relevantTags).sort().forEach(function (tag) {
        var liEl = document.createElement('li');
        liEl.innerText = tag;
        standardsEl.appendChild(liEl);
      });

      // Hide/show elements that are supposed to show only when set to all urls.
      var els = document.querySelectorAll('.axecore_cli-history__allUrlsOnly');
      els.forEach(function (el) {
        if (chartObj.state.currentUrl === '#all_urls') {
          el.style.display = 'block';

          // Update the URL list.
          var listEl = document.querySelector('.axecore_cli-history__resultsUrlList');
          listEl.innerHTML = '';
          var urlList = Object.keys(chartObj.allUrls);
          var totalUrls = urlList.length;

          if (totalUrls > chartObj.state.maxUrls) {
            var buttonEl = document.createElement('button');
            buttonEl.innerText = Drupal.t('Load Full URL List');
            buttonEl.type = 'button';
            buttonEl.addEventListener('click', function() {
              chartObj.state.maxUrls = totalUrls;
              chartObj.drawCharts();
            });
            var liEl = document.createElement('li');
            liEl.innerText = Drupal.t('There are too many URLs to show by default... ');
            liEl.appendChild(buttonEl);
            listEl.appendChild(liEl);
          }
          else {
            for (var i = 0; i < totalUrls; i++) {
              var url = urlList[i]
              var liEl = document.createElement('li');
              liEl.innerText = url;
              listEl.appendChild(liEl)
            }
          }
        }
        else {
          el.style.display = 'none';
        }
      });
    }
  }

  Drupal.behaviors.accessibilityScannerAxeCoreCliGoogleChart = {
    attached: false,
    attach: function attach(context) {
      if (!Drupal.behaviors.accessibilityScannerAxeCoreCliGoogleChart.attached) {
        Drupal.behaviors.accessibilityScannerAxeCoreCliGoogleChart.attached = true;
        chartObj.loadStateFromStorage();
        google.charts.load('current', {packages: ['corechart', 'bar']});
        google.charts.setOnLoadCallback(chartObj.drawCharts);
        window.addEventListener('resize', chartObj.drawCharts);
      }
    }
  };

})(jQuery, Drupal, drupalSettings);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc