Skip to content

Commit

Permalink
Merge pull request #28 from ftlabs/feature/27/single_clue
Browse files Browse the repository at this point in the history
[FEATURE] Enhance single clue view
  • Loading branch information
Lily2point0 authored May 19, 2017
2 parents 6c5ce04 + 45cc4f5 commit 5a8a79a
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 56 deletions.
1 change: 0 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"o-colors": ">=2.5.0 <4",
"o-grid": "^4.0.6",
"o-typography": ">=2.0.0 <5",
"hammerjs": "^2.0.8",
"o-viewport": "^2.2.0"
},
"main": [
Expand Down
120 changes: 90 additions & 30 deletions src/js/oCrossword.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ function writeErrorsAsClues(rootEl, json) {
cluesEl.appendChild(textList);
}

const Hammer = require('hammerjs');
const HORIZ_PAN_SPRING = 0.2;

function buildGrid(
Expand Down Expand Up @@ -82,6 +81,8 @@ function buildGrid(
rootEl.parentElement.setAttribute('data-o-crossword-title', name);

if (clues) {
rootEl.parentElement.setAttribute('data-o-crossword-clue-length', clues.across.length + clues.down.length);

const acrossEl = document.createElement('ul');
acrossEl.classList.add('o-crossword-clues-across');

Expand All @@ -97,26 +98,28 @@ function buildGrid(
downWrapper.appendChild(downEl);
cluesEl.appendChild(downWrapper);

clues.across.forEach(function acrossForEach(across) {
clues.across.forEach(function acrossForEach(across, index) {
const tempLi = document.createElement('li');
const tempSpan = document.createElement('span');
const answerLength = across[2].filter(isFinite).filter(isFinite).reduce((a,b)=>a+b,0);
tempSpan.textContent = across[0] + '. ' + across[1];
tempLi.dataset.oCrosswordNumber = across[0];
tempLi.dataset.oCrosswordAnswerLength = answerLength;
tempLi.dataset.oCrosswordDirection = 'across';
tempLi.dataset.oCrosswordClueId = index;
acrossEl.appendChild(tempLi);
tempLi.appendChild(tempSpan);
});

clues.down.forEach(function acrossForEach(down) {
clues.down.forEach(function acrossForEach(down, index) {
const tempLi = document.createElement('li');
const tempSpan = document.createElement('span');
const answerLength = down[2].filter(isFinite).filter(isFinite).reduce((a,b)=>a+b,0);
tempSpan.textContent = down[0] + '. ' + down[1];
tempLi.dataset.oCrosswordNumber = down[0];
tempLi.dataset.oCrosswordAnswerLength = answerLength;
tempLi.dataset.oCrosswordDirection = 'down';
tempLi.dataset.oCrosswordClueId = clues.across.length + index;
downEl.appendChild(tempLi);
tempLi.appendChild(tempSpan);
});
Expand Down Expand Up @@ -242,6 +245,8 @@ OCrossword.prototype.assemble = function assemble() {
});
}
if (cluesEl) {
let currentClue = -1;

const cluesUlEls = Array.from(cluesEl.querySelectorAll('ul'));

const gridWrapper = document.createElement('div');
Expand All @@ -257,6 +262,27 @@ OCrossword.prototype.assemble = function assemble() {
clueDisplayer.classList.add('o-crossword-clue-displayer');
gridScaleWrapper.appendChild(clueDisplayer);

const clueDisplayerText = document.createElement('span');
clueDisplayer.appendChild(clueDisplayerText);

const clueNavigation = document.createElement('nav');
clueNavigation.classList.add('o-crossword-clue-navigation');
// clueNavigation.classList.add('hidden');

const clueNavigationPrev = document.createElement('a');
clueNavigationPrev.classList.add('o-crossword-clue-nav-prev');
clueNavigationPrev.setAttribute('href', '#');
clueNavigationPrev.textContent = 'Previous';
clueNavigation.appendChild(clueNavigationPrev);

const clueNavigationNext = document.createElement('a');
clueNavigationNext.classList.add('o-crossword-clue-nav-next');
clueNavigationNext.setAttribute('href', '#');
clueNavigationNext.textContent = 'Next';
clueNavigation.appendChild(clueNavigationNext);

clueDisplayer.appendChild(clueNavigation);

const wrapper = document.createElement('div');
wrapper.classList.add('o-crossword-clues-wrapper');
this.rootEl.insertBefore(wrapper, cluesEl);
Expand All @@ -272,12 +298,6 @@ OCrossword.prototype.assemble = function assemble() {

let blockHighlight = false;

this.hammerMC = new Hammer.Manager(this.rootEl, {
recognizers: [
[Hammer.Tap]
]
});

this.addEventListener(magicInput, 'keydown', function (e) {
if (!isAndroid()) {
e.preventDefault();
Expand Down Expand Up @@ -316,14 +336,14 @@ OCrossword.prototype.assemble = function assemble() {
return;
}

if( e.keyCode === 229) {
//fix safari press down
magicInput.value = '';
return;
}

if(!isAndroid()) {
magicInput.value = String.fromCharCode(e.keyCode);

if( e.keyCode === 229) {
//fix safari press down
magicInput.value = '';
return;
}
}

progress();
Expand Down Expand Up @@ -354,6 +374,7 @@ OCrossword.prototype.assemble = function assemble() {
magicInput.value = '';
blockHighlight = false;
}, 16);

this.addEventListener(magicInput, 'focus', magicInput.select());

function takeInput(el, nextEls) {
Expand Down Expand Up @@ -385,9 +406,14 @@ OCrossword.prototype.assemble = function assemble() {
magicInput.style.top = magicInputTargetEl.offsetTop + 'px';
magicInput.focus();
magicInput.select();

debounce(function(){
magicInput.focus();
magicInput.select();
}, 100);
}

const onResize = function onResize() {
const onResize = function onResize(init) {
var isMobile = false;
const cellSizeMax = 40;

Expand All @@ -397,6 +423,10 @@ OCrossword.prototype.assemble = function assemble() {
isMobile = true;
}

if(isMobile && !!init) {
clueNavigationNext.click();
}

const d1 = cluesEl.getBoundingClientRect();
let d2 = gridEl.getBoundingClientRect();
const width1 = d1.width;
Expand Down Expand Up @@ -476,10 +506,11 @@ OCrossword.prototype.assemble = function assemble() {
function setClue(number, direction) {
const el = cluesEl.querySelector(`li[data-o-crossword-number="${number}"][data-o-crossword-direction="${direction}"]`);
if (el) {
clueDisplayer.textContent = el.textContent;
clueDisplayerText.textContent = el.textContent;
const els = Array.from(cluesEl.getElementsByClassName('has-hover'));
els.filter(el2 => el2 !== el).forEach(el => el.classList.remove('has-hover'));
el.classList.add('has-hover');
currentClue = parseInt(el.getAttribute('data-o-crossword-clue-id'));
}
}

Expand All @@ -503,7 +534,7 @@ OCrossword.prototype.assemble = function assemble() {
}

if (el) {
clueDisplayer.textContent = '';
clueDisplayerText.textContent = '';
const els = Array.from(cluesEl.getElementsByClassName('has-hover'));
els.forEach(el => el.classList.remove('has-hover'));
el.classList.remove('has-hover');
Expand Down Expand Up @@ -550,13 +581,21 @@ OCrossword.prototype.assemble = function assemble() {
const onTap = function onTap(e) {
let target;
let clueDetails;
let isNavigation = false;
blockHighlight = false;

if (e.target.nodeName === 'TD' || e.target.nodeName === 'INPUT') {
target = e.target;
blockHighlight = true;
} else {
const defEl = (e.target.nodeName === 'SPAN')?e.target.parentElement:e.target;
let defEl;

if(e.target.nodeName === 'A') {
defEl = navigateClues(e);
isNavigation = true;
} else {
defEl = (e.target.nodeName === 'SPAN')?e.target.parentElement:e.target;
}

const num = defEl.getAttribute('data-o-crossword-number');
clueDetails = {};
Expand Down Expand Up @@ -623,20 +662,44 @@ OCrossword.prototype.assemble = function assemble() {
currentlySelectedGridItem.direction,
currentlySelectedGridItem.answerLength
);
takeInput(cell, getGridCellsByNumber(
gridEl,
currentlySelectedGridItem.number,
currentlySelectedGridItem.direction,
currentlySelectedGridItem.answerLength
));

if(!isNavigation) {
takeInput(cell, getGridCellsByNumber(
gridEl,
currentlySelectedGridItem.number,
currentlySelectedGridItem.direction,
currentlySelectedGridItem.answerLength
));
}
}
}.bind(this);

const navigateClues = function navigateClues (e) {
e.preventDefault();
const dir = (e.target === clueNavigationNext)?'forward':'backward';
const cluesTotal = parseInt(this.rootEl.parentElement.getAttribute('data-o-crossword-clue-length')) - 1;

if (dir === 'forward') {
++currentClue;

if(currentClue > cluesTotal) {
currentClue = 0;
}
} else {
--currentClue;
if(currentClue < 0) {
currentClue = cluesTotal;
}
}

return cluesEl.querySelector('li[data-o-crossword-clue-id="'+ currentClue +'"]');
}.bind(this);

this.addEventListener(cluesEl, 'mousemove', e => highlightGridByCluesEl(e.target));

this.hammerMC.on('tap', onTap);
this.rootEl.addEventListener('click', onTap, false);

onResize();
onResize(true);
this.addEventListener(window, 'resize', this.onResize);
}

Expand All @@ -662,9 +725,6 @@ OCrossword.prototype.removeAllEventListeners = function() {

OCrossword.prototype.destroy = function destroy() {
this.removeAllEventListeners();
if (this.hammerMC) {
this.hammerMC.destroy();
}

if (this._raf) {
cancelAnimationFrame(this._raf);
Expand Down
54 changes: 49 additions & 5 deletions src/scss/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@

.o-crossword-grid-wrapper {
flex-shrink: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
position: relative;
font-size: 1.5em;
text-transform: uppercase;
Expand All @@ -83,6 +81,53 @@
@include oColorsFor(o-crossword-border, border);
text-transform: none;
margin: 0 auto;
position: relative;
display: table;

span {
display: table-cell;
vertical-align: middle;
padding: 0;
width: 100%;
}
}

.o-crossword-clue-navigation {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;

a {
background: transparent;
display: inline-block;
height: 100%;
width: 50%;
font-size: 0;
vertical-align: middle;

&:before {
content: '';
display: block;
width: 30px;
height: 30px;
background-image: url('https://www.ft.com/__origami/service/image/v2/images/raw/fticon-v1:arrow-left?source=o-crossword');
background-repeat: no-repeat;
background-size: cover;
margin-top: 8px;
user-select: none;
}

&.o-crossword-clue-nav-next {
&:before {
background-image: url('https://www.ft.com/__origami/service/image/v2/images/raw/fticon-v1:arrow-right?source=o-crossword');
float: right;
}

}
}
}

.o-crossword-magic-input {
Expand Down Expand Up @@ -157,14 +202,13 @@

.o-crossword-clues-wrapper {
position: relative;
pointer-events: none;
z-index: 2;
width: 20em;
margin-top: 2em;

@include oGridRespondTo(M) {
position: relative;
float: left;
width: auto;
margin-top: 0;
}
}

Expand Down
Loading

0 comments on commit 5a8a79a

Please sign in to comment.