Skip to content

Commit

Permalink
Ensure IE11 search works (#1077)
Browse files Browse the repository at this point in the history
Prior to this change the search in IE11 did not function properly

This change fixes the search.  Turns out querySelectorAll behaviour in IE11 is weird.  So additional checks and balances were added to detect when/if IE acts up.

[Issue discovered as part of fixing tickets for the latest feedback round](https://wiki.surfnet.nl/display/coininfra/Bevindingen+nav+tests+door+supportteam)
  • Loading branch information
Koen Cornelis authored Feb 4, 2021
1 parent 48b4744 commit e962df4
Show file tree
Hide file tree
Showing 23 changed files with 186 additions and 77 deletions.
8 changes: 3 additions & 5 deletions theme/base/javascripts/selectors.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/***
* TAGS
* ***/
export const idpElement = 'ARTICLE';

/***
* INDEX SELECTORS
* ***/
Expand Down Expand Up @@ -50,7 +45,9 @@ export const addAccountButtonClass = 'previousSelection__addAccount';
export const addAccountButtonSelector = `.${addAccountButtonClass}`;
export const idpClass = 'wayf__idp';
export const idpSelector = `.${idpClass}`;
export const idpTemplateSelector = 'idpTemplate';
export const selectedIdpsSelector = `${selectedIdpsSectionSelector} ${idpSelector}`;
export const unconnectedLiClass = 'idpItem--noAccess';
export const unconnectedIdpClass = 'wayf__idp--noAccess';
export const idpContentClass = 'idp__content';
export const idpTitleClass = 'idp__title';
Expand Down Expand Up @@ -101,6 +98,7 @@ export const defaultIdpItemSelector = '#defaultIdp';
export const defaultIdpInformational = '.remainingIdps__defaultIdp';
export const remainingIdpCutoffMetSelector = '.wayf__remainingIdps .wayf__idpList--cutoffMet';
export const remainingIdpLiSelector = '.wayf__remainingIdps .wayf__idpList > li';
export const remainingIdpAfterSearchSelector = '.wayf__remainingIdps .wayf__idpList > li:not([data-weight="0"]) .wayf__idp';
export const firstRemainingIdpAfterSearchSelector = '.wayf__remainingIdps .wayf__idpList > li:not([data-weight="0"]):first-of-type .wayf__idp';
export const lastRemainingIdpAfterSearchSelector = '.wayf__remainingIdps .wayf__idpList > li:not([data-weight="0"]):last-of-type .wayf__idp';
export const noMatchSelector = '.wayf__remainingIdps .wayf__idp[data-weight="0"]';
Expand Down
12 changes: 8 additions & 4 deletions theme/base/javascripts/wayf/handleClickingDisabledIdp.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import {hideSuccessMessage} from './noAccess/hideSuccessMessage';
import {attachClickHandlerToRequestButton} from './noAccess/attachClickHandlerToRequestButton';
import {setConnectability} from './deleteDisable/setConnectability';
import {getData} from '../utility/getData';
import {noAccessFormSelector, noAccessLi, noAccessSectionSelector} from '../selectors';
import {idpClass, idpSelector, noAccessFormSelector, noAccessLi, noAccessSectionSelector} from '../selectors';

export const handleClickingDisabledIdp = (element) => {
let target = element;
const noAccess = document.querySelector(noAccessSectionSelector);
const li = noAccess.querySelector(noAccessLi);
const form = noAccess.querySelector(noAccessFormSelector);
const parentSection = element.closest('section');
const cloneOfIdp = cloneIdp(element);
const connectable = getData(element, 'connectable') === 'true';
if (!element.classList.contains(idpClass)) {
target = element.closest(idpSelector);
}
const cloneOfIdp = cloneIdp(target);
const connectable = getData(target, 'connectable') === 'true';

setConnectability(noAccess, connectable);
toggleVisibility(parentSection);
Expand All @@ -28,7 +32,7 @@ export const handleClickingDisabledIdp = (element) => {
hideSuccessMessage();

// add idp entityId
setHiddenFieldValues(element, form);
setHiddenFieldValues(target, form);

// attach clickHandler for cancel button
attachClickHandlerToCancelButton(parentSection, noAccess);
Expand Down
4 changes: 2 additions & 2 deletions theme/base/javascripts/wayf/handleIdpBanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ export const handleIdpBanner = async (event) => {

const searchField = document.querySelector(searchFieldSelector);
const defaultIdp = document.getElementById(defaultIdpId);
const defaultIdpTitle = getData(defaultIdp, 'title');
const defaultIdpTitle = getData(defaultIdp.parentNode, 'title');
const remainingIdps = document.querySelectorAll(remainingIdpSelector);
const searchButton = document.querySelector(searchSubmitSelector);
const resetButton = document.querySelector(searchResetSelector);

for (const idp of remainingIdps) {
if(getData(idp, 'title').localeCompare(defaultIdpTitle) !== 0) {
if(getData(idp.parentNode, 'title').localeCompare(defaultIdpTitle) !== 0) {
idp.setAttribute('data-weight', '0');
}
}
Expand Down
11 changes: 10 additions & 1 deletion theme/base/javascripts/wayf/handlePreviousSelectionVisible.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import {hasSelectedIdpsInList} from './utility/hasSelectedIdpsInList';
import {attachDeleteHandlers} from './deleteDisable/attachDeleteHandlers';
import {switchIdpSection} from './utility/switchIdpSection';
import {focusOn} from "../utility/focusOn";
import {addAccountButtonSelector, previousSelectionFirstIdp, selectedIdpsListSelector} from '../selectors';
import {
addAccountButtonSelector,
previousSelectionFirstIdp,
searchFieldSelector,
selectedIdpsListSelector
} from '../selectors';
import {addClickHandlerOnce} from '../utility/addClickHandlerOnce';
import {idpSubmitHandler} from '../handlers';
import {matchPreviouslySelectedWithCookie} from './matchPreviouslySelectedWithCookie';
Expand All @@ -19,7 +24,11 @@ export const handlePreviousSelectionVisible = () => {
mouseHandlersHiddenIdps();
// put focus on the first IDP, so you can just hit enter & go
focusOn(previousSelectionFirstIdp);
return;
}

// if no selected accounts exist, focus on the searchfield
focusOn(searchFieldSelector);
};

/**
Expand Down
8 changes: 4 additions & 4 deletions theme/base/javascripts/wayf/idpFocus/arrowDown.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {focusOnNextIdp} from './focusOnNextIdp';
import {
defaultIdpSelector,
firstRemainingIdpAfterSearchSelector,
lastRemainingIdpAfterSearchSelector,
remainingIdpAfterSearchSelector,
searchFieldSelector,
searchResetSelector
} from '../../selectors';
Expand All @@ -26,8 +25,9 @@ export const arrowDown = () => {
const searchBar = document.querySelector(searchFieldSelector);
const resetButton = document.querySelector(searchResetSelector);
const defaultIdp = document.querySelector(defaultIdpSelector);
const firstIdp = document.querySelector(firstRemainingIdpAfterSearchSelector);
const lastIdp = document.querySelector(lastRemainingIdpAfterSearchSelector);
const remainingIdps = document.querySelectorAll(remainingIdpAfterSearchSelector);
const firstIdp = remainingIdps[0];
const lastIdp = remainingIdps[remainingIdps.length - 1];

if (isFocusOn(searchBar) || isFocusOn(resetButton)) {
if(!!defaultIdp && isVisibleElement(defaultIdp)) {
Expand Down
9 changes: 5 additions & 4 deletions theme/base/javascripts/wayf/idpFocus/arrowUp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import {isFocusOn} from '../../utility/isFocusOn';
import {focusOnPreviousIdp} from './focusOnPreviousIdp';
import {
defaultIdpSelector,
firstRemainingIdpAfterSearchSelector,
lastRemainingIdpAfterSearchSelector,
remainingIdpAfterSearchSelector,
searchFieldSelector,
searchResetSelector
} from '../../selectors';
Expand All @@ -26,10 +25,12 @@ export const arrowUp = () => {
const searchBar = document.querySelector(searchFieldSelector);
const resetButton = document.querySelector(searchResetSelector);
const defaultIdp = document.querySelector(defaultIdpSelector);
const firstIdp = document.querySelector(firstRemainingIdpAfterSearchSelector);
const lastIdp = document.querySelector(lastRemainingIdpAfterSearchSelector);
const remainingIdps = document.querySelectorAll(remainingIdpAfterSearchSelector);
const firstIdp = remainingIdps[0];
const lastIdp = remainingIdps[remainingIdps.length - 1];

if (isFocusOn(searchBar) || isFocusOn(resetButton)) {
console.log({lastIdp});
focusAndSmoothScroll(lastIdp);
return;
} else if (isFocusOn(firstIdp)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ export const matchPreviouslySelectedWithCookie = () => {
}

cookie = JSON.parse(cookie);

// check if each idp in the cookie is in the list, if not add it
cookie.forEach(idp => {
const id = `[data-entityid="${idp.idp}"]`;
const inPreviouslySelected = document.querySelector(`${selectedIdpsSelector}${id}`);
const inPreviouslySelected = document.querySelector(`${selectedIdpsSelector}${id}:first-of-type`);

if (!inPreviouslySelected) {
const deleteButtonTemplate = document.getElementById(deleteButtonTemplateId);
Expand Down
9 changes: 6 additions & 3 deletions theme/base/javascripts/wayf/search/assignWeight.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import {findWeight} from './findWeight';
* @param searchTerm string
*/
export const assignWeight = (idpArray, searchTerm) => {
idpArray.forEach(li => {
const idp = li.children[0];
idpArray.forEach(idp => {
const searchTerms = searchTerm.trim().split(' ');
let weight = 0;

Expand All @@ -34,7 +33,11 @@ export const assignWeight = (idpArray, searchTerm) => {
});
}

setWeight(li, weight);
setWeight(idp, weight);
try{
setWeight(idp.firstElementChild, weight);
} catch (e) {
console.log(e);
}
});
};
1 change: 1 addition & 0 deletions theme/base/javascripts/wayf/search/clearWeight.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import {removeWeight} from './removeWeight';
export const clearWeight = (idpArray) => {
idpArray.forEach(li => {
removeWeight(li.children[0]);
removeWeight(li);
});
};
6 changes: 5 additions & 1 deletion theme/base/javascripts/wayf/searchBehaviour.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {searchAndSortIdps} from './search/searchAndSortIdps';
import {toggleDefaultIdPLinkVisibility} from "./search/toggleDefaultIdPLinkVisibility";
import {toggleSearchAndResetButton} from "./search/toggleSearchAndResetButton";
import {remainingIdpLiSelector, searchFieldSelector, searchResetSelector} from '../selectors';
import {focusAndSmoothScroll} from '../utility/focusAndSmoothScroll';

export const searchBehaviour = () => {
const idpList = document.querySelectorAll(remainingIdpLiSelector);
Expand All @@ -18,7 +19,10 @@ export const searchBehaviour = () => {
searchBar.addEventListener('click', event => searchAndSortIdps(idpArray, event.target.value));
searchBar.addEventListener('input', event => searchAndSortIdps(idpArray, event.target.value));

resetButton.addEventListener('click', event => toggleSearchAndResetButton(idpArray, ''));
resetButton.addEventListener('click', () => {
toggleSearchAndResetButton(idpArray, '');
focusAndSmoothScroll(searchBar);
});
// attach handler to search form
document.querySelector('.wayf__search').addEventListener('submit', event => {
event.preventDefault();
Expand Down
10 changes: 7 additions & 3 deletions theme/base/javascripts/wayf/submitForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {addSelectedIdp} from './deleteDisable/addSelectedIdp';
import {handleClickingDisabledIdp} from './handleClickingDisabledIdp';
import {hasVisibleDisabledButtonAsTarget} from './utility/hasVisibleDisabledButtonAsTarget';
import {hasVisibleDeleteButtonAsTarget} from './utility/hasVisibleDeleteButtonAsTarget';
import {idpElement, idpFormSelector, idpSelector} from '../selectors';
import {idpFormSelector, idpSelector} from '../selectors';

/**
* Submit the form for the selected idp.
Expand All @@ -15,12 +15,16 @@ import {idpElement, idpFormSelector, idpSelector} from '../selectors';
export const submitForm = (e) => {
e.preventDefault();
let element = e.target;

if (hasVisibleDeleteButtonAsTarget(element)) {
return;
}

if (element.tagName !== idpElement) {
if (hasVisibleDisabledButtonAsTarget(element)) {
handleClickingDisabledIdp(element);
return;
}

if (!element.classList.contains(idpSelector)) {
element = element.closest(idpSelector);
}

Expand Down
40 changes: 38 additions & 2 deletions theme/base/javascripts/wayf/utility/convertIdpArrayToHtml.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {idpSelector} from '../../selectors';
import {idpClass, idpTitleClass, idpTemplateSelector, unconnectedIdpClass, unconnectedLiClass} from '../../selectors';
import {getData} from '../../utility/getData';

/**
* Convert an array of li's containing idps to an html string.
Expand All @@ -10,9 +11,44 @@ import {idpSelector} from '../../selectors';
export const convertIdpArraytoHtml = (idpArray) => {
let idpHtml = '';
idpArray.forEach((idp, index) => {
idp.querySelector(idpSelector).setAttribute('data-index', String(index + 1));
idp.setAttribute('data-index', String(index + 1));
if (!idp.firstElementChild) {
try {
idp.innerHtml = '';
idp.appendChild(getIdpContent(idp));
} catch (e) {
console.log(e);
}
}
idpHtml += idp.outerHTML;
});

return idpHtml;
};

function getIdpContent(idp) {
const template = document.getElementById(idpTemplateSelector).firstElementChild;
const count = getData(idp, 'count');
const title = getData(idp, 'title');
const describedby = getData(idp, 'describedby');
const weight = getData(idp, 'weight');
const id = getData(idp, 'entityid');
const connectable = getData(idp, 'connectable');
const defaultIdp = getData(idp, 'defaultidp');
const className = idp.classList.contains(unconnectedLiClass) ? `${idpClass} ${unconnectedIdpClass}` : idpClass;
const clone = template.cloneNode(true);

clone.setAttribute('data-count', count);
clone.setAttribute('data-weight', weight);
clone.setAttribute('data-entityid', id);
clone.setAttribute('data-connectable', connectable);
clone.setAttribute('class', className);
clone.setAttribute('aria-describedby', describedby);
if (defaultIdp) {
clone.setAttribute('id', 'defaultIdp');
}
clone.querySelector(`.${idpTitleClass}`).innerText = title;
clone.querySelector('[name="idp"]').value = id;

return clone;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {isVisibleElement} from '../../utility/isVisibleElement';
import {idpDisabledSelector} from '../../selectors';
import {idpDisabledClass, idpDisabledSelector} from '../../selectors';

/**
* Checks if an element has a visible disable button.
Expand All @@ -9,6 +9,10 @@ import {idpDisabledSelector} from '../../selectors';
* @returns {boolean}
*/
export const hasVisibleDisabledButtonAsTarget = (element) => {
if (element.classList.contains(idpDisabledClass)) {
return isVisibleElement(element);
}

const idpDisabled = element.querySelector(idpDisabledSelector);
if (!Boolean(idpDisabled)) {
return false;
Expand Down
35 changes: 29 additions & 6 deletions theme/base/javascripts/wayf/utility/sortArrayList.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
import {idpSelector, unconnectedIdpClass} from '../../selectors';
import {idpSelector, remainingIdpLiSelector, unconnectedIdpClass} from '../../selectors';
import {nodeListToArray} from '../../utility/nodeListToArray';

export const sortArrayList = (idpArray, sortFunction) => {
const withAccess = idpArray.filter(node => !node.querySelector(idpSelector).classList.contains(unconnectedIdpClass));
export const sortArrayList = (passedIdpArray, sortFunction) => {
let idpArray = passedIdpArray;
let withAccess;
let noAccess;
try {
withAccess = getWithAccess(idpArray);
noAccess = getNoAccess(idpArray);
} catch (e) {
idpArray = nodeListToArray(document.querySelectorAll(remainingIdpLiSelector));
withAccess = idpArray.filter(node => !node.querySelector(idpSelector).classList.contains(unconnectedIdpClass));
noAccess = getNoAccess(idpArray);
}

const noAccess = idpArray.filter(node => node.querySelector(idpSelector).classList.contains(unconnectedIdpClass));
withAccess.sort(sortFunction);
noAccess.sort(sortFunction);
if (withAccess) {
withAccess.sort(sortFunction);
}

if (noAccess) {
noAccess.sort(sortFunction);
}

return [...withAccess, ...noAccess];
};

function getWithAccess(idpArray) {
return idpArray.filter(node => !node.classList.contains('idpItem--noAccess'));
}

function getNoAccess(idpArray) {
return idpArray.filter(node => node.classList.contains('idpItem--noAccess'));
}
8 changes: 4 additions & 4 deletions theme/base/javascripts/wayf/utility/sortIdpMethods.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {getData} from '../../utility/getData';
* @returns {number}
*/
export const sortByTitle = (firstElement, secondElement) => {
const titleOne = getTitle(firstElement.children[0]);
const titleTwo = getTitle(secondElement.children[0]);
const titleOne = getTitle(firstElement);
const titleTwo = getTitle(secondElement);
const lang = document.querySelector('html').getAttribute('lang') || 'nl';

return titleOne.localeCompare(titleTwo, lang);
Expand All @@ -36,8 +36,8 @@ function getTitle(element) {
* @returns {number}
*/
export const sortByNumber = (firstElement, secondElement, attributeName) => {
const numberOne = getNumberAttribute(firstElement.children[0], attributeName);
const numberTwo = getNumberAttribute(secondElement.children[0], attributeName);
const numberOne = getNumberAttribute(firstElement, attributeName);
const numberTwo = getNumberAttribute(secondElement, attributeName);

if (numberOne > numberTwo) return -1;
if (numberOne < numberTwo) return 1;
Expand Down
1 change: 0 additions & 1 deletion theme/base/stylesheets/pages/wayf/previousSelection.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
@include display-grid;
@include grid-template-columns(calc(100% - 7rem) 7rem);
@include grid-template-rows(min-content min-content min-content);
display: block;
max-height: fit-content;

> .previousSelection__title {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@
aria-describedby="idp__title{{ listName }}{{ loop.index }}"
class="wayf__idp{% if idp['connected'] is defined and not idp['connected'] %} wayf__idp--noAccess{% endif %}"
data-connectable="{{ connectable }}"
data-count="{% if idp['count'] is defined %}{{ idp['count'] }}{% else %}0{% endif %}"
data-entityid="{{ idp['entityId'] }}"
data-index="{{ loop.index }}"
data-keywords="{{ idp['keywords']|lower }}"
data-title="{{ idp['displayTitle']|lower }}"
data-count="{% if idp['count'] is defined %}{{ idp['count'] }}{% else %}0{% endif %}"
{% if idp['isDefaultIdp'] %}id="defaultIdp"{% endif %}
tabindex="0"
data-entityid="{{ idp['entityId'] }}"
>
<div class="idp__logo">
{% if idp.logo is not null %}
Expand Down
Loading

0 comments on commit e962df4

Please sign in to comment.