<div class="comparison">
    <div class="comparison-form">
        <input hidden name="moduleName" value="grants">
        <input hidden name="irmaWebServiceLookupID" value="123456">
        <input hidden name="irmaTesting" value="yes">
    </div>

    <div class="comparison-heading">
        <div class="comparison-inner">
            <div class="comparison-section comparison-before">
                <h4 class="card-subheading">Original answers</h4>
            </div>

            <div class="comparison-section comparison-after">
                <h4 class="card-subheading">Revised answers</h4>
            </div>
        </div>
    </div>

    <div class="comparison-main">
        <div class="comparison-container">
            <div class="comparison-list"></div>
        </div>
    </div>

    <div class="comparison-scrollbar">
        <div class="scrollbar-main"></div>

        <button type="button" class="btn scrollbar-handle js-comparison-scroll"></button>
    </div>
</div>
<div class="comparison">
	<div class="comparison-form">
		<input hidden name="moduleName" value="grants">
		<input hidden name="irmaWebServiceLookupID" value="123456">
		<input hidden name="irmaTesting" value="yes">
	</div>

	<div class="comparison-heading">
		<div class="comparison-inner">
			<div class="comparison-section comparison-before">
				<h4 class="card-subheading">Original answers</h4>
			</div>

			<div class="comparison-section comparison-after">
				<h4 class="card-subheading">Revised answers</h4>
			</div>
		</div>
	</div>

	<div class="comparison-main">
		<div class="comparison-container">
			<div class="comparison-list"></div>
		</div>
	</div>

	<div class="comparison-scrollbar">
		<div class="scrollbar-main"></div>

		<button type="button" class="btn scrollbar-handle js-comparison-scroll"></button>
	</div>
</div>
/* No context defined for this component. */
  • Content:
    .comparison {
    	position: relative;
    	overflow: hidden;
    
    	.comparison-inner {
    		display: flex;
    		width: 100%;
    
    		.comparison-section {
    			display: flex;
    			flex-direction: column;
    			width: 50%;
    			flex: 0 0 auto;
    		}
    
    		.comparison-before {
    			padding-right: 16rem;
    		}
    
    		.comparison-after {
    			padding-left: 16rem;
    		}
    
    		.card-subheading {
    			height: 6rem;
    			flex: 0 0 auto;
    		}
    	}
    
    	.comparison-main {
    		box-shadow: 0 0 0 1px $color-irma-silver inset;
    
    		.comparison-container {
    			padding-right: 30px;
    			max-height: calc(100vh - 72rem);
    			width: calc(100% + 30px);
    			overflow-y: scroll;
    		}
    
    		.comparison-list {
    			padding: 5rem;
    		}
    
    		.comparison-inner {
    			& + .comparison-inner {
    				margin-top: 7.5rem;
    
    				.comparison-body {
    					padding-top: 7.5rem;
    
    					border-top: 1px solid $color-irma-silver;
    				}
    			}
    		}
    	}
    
    	.comparison-body {
    		color: rgba($color-irma-slate, 0.7);
    
    		* {
    			line-height: 1.5;
    		}
    
    		br {
    			line-height: 200%;
    		}
    
    		h4 {
    			color: rgba($color-irma-slate, 0.9);
    
    			@include font-size-other(16px);
    
    			& + * {
    				margin-top: 3rem;
    			}
    		}
    
    		.added, .removed {
    			padding: 0 1px;
    		}
    
    		.added {
    			background: rgba(#01C853, 0.15);
    		}
    
    		.removed {
    			background: rgba($color-irma-danger, 0.15);
    		}
    	}
    
    	.comparison-scrollbar {
    		position: absolute;
    		left: 50%;
    		bottom: 0;
    		transform: translateX(-50%);
    
    		width: 14rem;
    		padding: 1px 2rem;
    		height: calc(100% - 6rem);
    		overflow: hidden;
    		box-shadow: 0 -1px 0 $color-irma-silver inset,
    			0 1px 0 $color-irma-silver;
    
    		.scrollbar-main {
    			height: 100%;
    
    			box-shadow: 0 0 0 1px $color-irma-aluminium;
    			background: #F8F8F8;
    
    		}
    
    		.scrollbar-inner {
    			position: relative;
    
    			display: flex;
    			width: 100%;
    			height: 100%;
    
    			& + .scrollbar-inner {
    				padding-top: 4rem;
    				border-top: 1px dotted rgba($color-irma-aluminium, 0.5);
    			}
    
    			&:not(:last-child) {
    				padding-bottom: 4rem;
    			}
    
    			&::after {
    				content: '';
    
    				position: absolute;
    				top: 0;
    				left: 50%;
    				transform: translateX(-50%) translateZ(0);
    
    				width: 1px;
    				height: 100%;
    
    				background: $color-irma-aluminium;
    			}
    		}
    
    		.scrollbar-handle {
    			position: absolute;
    			top: 0;
    			left: 1px;
    
    			width: calc(100% - 2px);
    
    			box-shadow: 0 0 0 1px $color-irma-ocean inset,
    					0 0 0 3px rgba($color-irma-sky, 0) inset;
    			border-radius: 2px;
    
    			transition-duration: $transition;
    			transition-property: box-shadow, height;
    
    			&:hover, &:focus {
    				box-shadow: 0 0 0 1px $color-irma-ocean inset,
    					0 0 0 3px rgba($color-irma-sky, 0.3) inset;
    			}
    
    			&::before, &::after {
    				content: '';
    
    				position: absolute;
    				left: 50%; 
    				transform: translateX(-50%);
    
    				width: calc(100% - 4rem + 4px);
    				height: 100vh;
    
    				background: rgba(#F8F8F8, 0.66);
    
    				pointer-events: none;
    			}
    
    			&::before {
    				bottom: 100%;
    			}
    
    			&::after {
    				top: 100%;
    			}
    		}
    
    		.scrollbar-section {
    			width: 50%;
    			padding: 0.5rem;
    			flex: 0 0 auto;
    		}
    
    		span {
    			position: relative;
    
    			display: block;
    		}
    
    		.removed, .added {
    			&::before {
    				content: '';
    
    				position: absolute;
    				left: 0;
    				top: 50%;
    				transform: translateY(-50%);
    
    				display: block;
    				width: 100%;
    				height: calc(100% + 1rem);
    			}
    		}
    
    		.removed {
    			&::before {
    				background: $color-irma-danger;
    			}
    		}
    
    		.added {
    			&::before {
    				background: #01C853;
    			}
    		}
    	}
    }
  • URL: /components/raw/comparison/_comparison.scss
  • Filesystem Path: components/01-components/comparison/_comparison.scss
  • Size: 3.4 KB
  • Content:
    /* 
     *	_comparison.js
     */
    
    irma.comparison = (function () {
    	'use strict';
    
    	var scrollPanel = {
    			$handle: $('')
    		}, 
    		dragging = false,
    		dragStart;
    
    	var getComparison = function ($comparison) {
    		var url = irma.baseURL + "irmaTextComparison.asp?" + irma.urlParams,
    			data = $comparison.find('.comparison-form input').serialize();
    
    		$.ajax({
    			url: url,
    			data: data
    		}).done(function (res) {
    			makeComparison($comparison, res.data);
    		}).fail(function (error) {
    			// makeComparison(testData);
    		});
    	};
    
    	var getState = function (isSource) {
    		return isSource ? "removed" : "added";
    	};
    
    	var mapPhrase = function (phrase, isSource) {
    		if (phrase[getState(isSource)]) {
    			return "<span class=\'" + getState(isSource) + "\'>" + phrase.value + "</span>";
    		}
    		// else if (phrase[getState(!isSource)]) {
    		// 	return "";
    		// }
    		return phrase.value;
    	};
    
    	var mapScrollbar = function (row, phrase, isSource) {
    		var sourceLength = row.Block_answer_source.length > row.Block_answer_target.length ? row.Block_answer_source.length : row.Block_answer_target.length;
    		var height = phrase.value.length / sourceLength * 100;
    
    		if (phrase[getState(isSource)]) {
    			return $("<span/>").addClass(getState(isSource)).height("" + height + "%");
    		}
    		else if (phrase[getState(!isSource)]) {
    			return $("<span></span>");
    		}
    		return $("<span/>").height("" + height + "%");
    	};
    
    	var setScrollbarHeight = function ($comparison) {
    		var $main = $comparison.find('.comparison-main'),
    			$list = $main.find('.comparison-list'),
    			$scrollbar = $comparison.find('.scrollbar-main'),
    			listHeight = $list.height(),
    			scrollbarHeight = $main.height() / listHeight * 100;
    
    		$('.scrollbar-handle').height('' + scrollbarHeight + '%');
    
    		$('.comparison .comparison-main .comparison-inner').each(function (index) {
    			var $scrollbarSection = $('.comparison .comparison-scrollbar .scrollbar-main .scrollbar-inner').eq(index),
    				scrollbarSectionHeight = $(this).outerHeight(true) / listHeight * 100;
    
    			$scrollbarSection.css('height', '' + scrollbarSectionHeight + '%');
    
    		});
    	};
    
    	var makeComparison = function ($comparison, data) {
    		var $main = $comparison.find('.comparison-main'),
    			$list = $main.find('.comparison-list'),
    			$scrollbar = $comparison.find('.scrollbar-main');
    
    		_.forEach(data, function (row, i) {
    			var diff = {
    				question: JsDiff.diffWords(row.Block_question_source, row.Block_question_target),
    				answer: JsDiff.diffWords(row.Block_answer_source, row.Block_answer_target)
    			};
    
    			var scrollbar = {
    				before: {
    					question: _.map(diff.question, function (phrase) {
    						return mapScrollbar(row, phrase, true);
    					}),
    					answer: _.map(diff.answer, function (phrase) {
    						return mapScrollbar(row, phrase, true);
    					})
    				},
    				after: {
    					question: _.map(diff.question, function (phrase) {
    						return mapScrollbar(row, phrase, false);
    					}),
    					answer: _.map(diff.answer, function (phrase) {
    						return mapScrollbar(row, phrase, false);
    					})
    				}
    			};
    
    			var body = {
    					before: {
    						question: _.map(_.reject(diff.question, { added: true }), function (phrase) {
    							return mapPhrase(phrase, true);
    						}).join(''),
    						answer: _.map(_.reject(diff.answer, { added: true }), function (phrase) {
    							return mapPhrase(phrase, true);
    						}).join('')
    					},
    					after: {
    						question: _.map(_.reject(diff.question, { removed: true }), function (phrase) {
    							return mapPhrase(phrase, false);
    						}).join(''),
    						answer: _.map(_.reject(diff.answer, { removed: true }), function (phrase) {
    							return mapPhrase(phrase, false);
    						}).join('')
    					}
    				};
    
    			var $section = $('<div />').addClass('comparison-inner'),
    				$before = $('<div />').addClass('comparison-section comparison-before'),
    				$after = $('<div />').addClass('comparison-section comparison-after');
    
    			$before.html("<div class='comparison-body'><h4>" + body.before.question + "</h4><p>" + body.before.answer + "</p></div>");
    			$after.html("<div class='comparison-body'><h4>" + body.after.question + "</h4><p>" + body.after.answer + "</p></div>");
    			$section.append($before, $after);
    			$list.append($section);
    
    			var $scrollSection = $('<div />').addClass('scrollbar-inner'),
    				$scrollBefore = $('<div />').addClass('scrollbar-section scrollbar-before').append(scrollbar.before.question, scrollbar.before.answer),
    				$scrollAfter = $('<div />').addClass('scrollbar-section scrollbar-after').append(scrollbar.after.question, scrollbar.after.answer);
    
    			$scrollSection.append($scrollBefore, $scrollAfter);
    			$scrollbar.append($scrollSection);
    
    		});
    
    		setScrollbarHeight($comparison);
    	};
    
    	var scrollComparison = function (e) {
    		var translateY = scrollPanel.translateY + e.pageY - scrollPanel.mouseY;
    
    		if (translateY > scrollPanel.translateMax) {
    			translateY = scrollPanel.translateMax;
    		}
    		else if (translateY < 0) {
    			translateY = 0;
    		}
    
    		var scrollTop = translateY * scrollPanel.scrollMax / scrollPanel.translateMax;
    
    		scrollPanel.$handle.css('transform', 'translateY(' + translateY + 'px)');
    		scrollPanel.$target.scrollTop(scrollTop);
    	};
    
    	var initScroll = function ($btn) {
    		scrollPanel = {
    			$handle: $btn,
    			$target: $btn.closest('.comparison').find('.comparison-main .comparison-container'),
    			handleHeight: $btn.height()
    		};
    
    		scrollPanel.translateMax = scrollPanel.$target.height() - $btn.height();
    		scrollPanel.scrollMax = scrollPanel.$target.get(0).scrollHeight - scrollPanel.$target.height();
    
    		scrollPanel.translateY = scrollPanel.$target.scrollTop() / scrollPanel.scrollMax * scrollPanel.translateMax;
    
    		scrollPanel.$handle.css('transform', 'translateY(' + scrollPanel.translateY + 'px) translateZ(0)');
    	};
    
    	var init = function () {
    		var $comparisons = $('.comparison');
    
    		if ($comparisons.length) {
    			$comparisons.each(function () {
    				getComparison($(this));
    			});
    
    			$(document).on('mousedown', '.js-comparison-scroll', function (e) {
    				initScroll($(this), e);
    
    				scrollPanel.mouseY = e.pageY;
    
    				scrollPanel.$target.css('user-select', 'none');
    
    				dragStart = setTimeout(function () {
    					dragging = true;
    				}, 200);
    			}).on('mousemove', function (e) {
    				if (dragging) {
    					scrollComparison(e);
    				}
    
    			}).on('mouseup', function (e) {
    				clearInterval(dragStart);
    
    				if (dragging) {
    					dragging = false;
    				}
    
    				if (scrollPanel.$target) {
    					scrollPanel.$target.css('user-select', 'auto');
    				}
    
    				scrollPanel = {
    					$handle: $('')
    				};
    			
    			}).on('click', '.js-comparison-scroll', function () {
    				$(this).focus();
    
    			}).on('keydown', function (e) {
    				var $focus = $(':focus');
    
    				if ([38, 40].includes(e.which) && $focus.is('.js-comparison-scroll')) {
    					var $container = $focus.closest('.comparison').find('.comparison-container');
    					var delta = 40 * (e.which - 39);
    
    					$container.scrollTop($container.scrollTop() + delta);
    
    					e.preventDefault();
    					e.stopPropagation();
    				}
    
    			});
    
    			$('.comparison-container').on('scroll', function () {
    				if (!scrollPanel.$handle.is($(this).closest('.comparison').find('.js-comparison-scroll').eq(0))) {
    					initScroll($(this).closest('.comparison').find('.js-comparison-scroll').eq(0));
    				}
    
    				var translateY = $(this).scrollTop() / scrollPanel.scrollMax * scrollPanel.translateMax;
    
    				scrollPanel.$handle.css('transform', 'translateY(' + translateY + 'px) translateZ(0)');
    			});
    
    			$('.comparison-scrollbar').on('mousewheel', function (e) {
    				var $container = $(this).closest('.comparison').find('.comparison-container');
    
    				$container.scrollTop($container.scrollTop() - e.deltaY * e.deltaFactor);
    
    				e.preventDefault();
    				e.stopPropagation();
    			});
    
    			$(window).resize(function () {
    				$('.comparison').each(function () {
    					setScrollbarHeight($(this));
    				});
    			});
    
    			$(document).on('click', '.js-collapse-nav', function () {
    				setTimeout(function () {
    					$('.comparison').each(function () {
    						setScrollbarHeight($(this));
    					});
    				}, 300);
    			});
    		}
    	};
    
    	return {
    		init: init
    	};
    
    }());
  • URL: /components/raw/comparison/comparison.js
  • Filesystem Path: components/01-components/comparison/comparison.js
  • Size: 8 KB

There are no notes for this item.