Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #17093 from comoyo/tempkeyboardreflow
Browse files Browse the repository at this point in the history
Bug 982269 - Fix keyboard reflows. r=RudyL
  • Loading branch information
janjongboom committed Mar 14, 2014
2 parents 6495e20 + 7df34c2 commit 2f0ef53
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 74 deletions.
11 changes: 8 additions & 3 deletions apps/keyboard/js/keyboard.js
Expand Up @@ -190,6 +190,11 @@ var isKeyboardRendered = false;
var currentCandidates = [];
var candidatePanelScrollTimer = null;

var cachedIMEDimensions = {
height: 0,
width: 0
};

// Show accent char menu (if there is one) after ACCENT_CHAR_MENU_TIMEOUT
const ACCENT_CHAR_MENU_TIMEOUT = 700;

Expand Down Expand Up @@ -868,8 +873,8 @@ function setLayoutPage(newpage) {
// Inform about a change in the displayed application via mutation observer
// http://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/
function updateTargetWindowHeight(hide) {
var imeHeight = IMERender.ime.scrollHeight;
var imeWidth = IMERender.getWidth();
var imeHeight = cachedIMEDimensions.height = IMERender.ime.scrollHeight;
var imeWidth = cachedIMEDimensions.width = IMERender.getWidth();
window.resizeTo(imeWidth, imeHeight);
}

Expand Down Expand Up @@ -1135,7 +1140,7 @@ function onTouchEnd(evt) {
var dt = evt.timeStamp - touchStartCoordinate.timeStamp;
var vy = dy / dt;

var keyboardHeight = IMERender.ime.scrollHeight;
var keyboardHeight = cachedIMEDimensions.height;
var hasCandidateScrolled = (IMERender.isFullCandidataPanelShown() &&
(Math.abs(dx) > 3 || Math.abs(dy) > 3));

Expand Down
68 changes: 47 additions & 21 deletions apps/keyboard/js/render.js
Expand Up @@ -337,33 +337,35 @@ const IMERender = (function() {
if (candidatePanel) {
candidatePanel.dataset.candidateIndicator = 0;

candidatePanel.innerHTML = '';
candidatePanel.scrollTop = candidatePanel.scrollLeft = 0;

var docFragment = document.createDocumentFragment();

if (inputMethodName == 'latin') {
if (candidates.length) {
var dismissButton = document.createElement('div');
dismissButton.classList.add('dismiss-suggestions-button');
candidatePanel.appendChild(dismissButton);
var candidateWidth =
(candidatePanel.clientWidth - dismissButton.clientWidth);
candidateWidth /= candidates.length;
candidateWidth -= 6; // 3px margin on each side
var dismissButton =
candidatePanel.querySelector('.dismiss-suggestions-button');
dismissButton.classList.add('hide');

// hide dismiss button
if (candidates.length > 0) {
dismissButton.classList.remove('hide');
}

var suggestContainer =
candidatePanel.querySelector('.suggestions-container');

// we want to do all width calculation in CSS, so add a class here
suggestContainer.innerHTML = '';
for (var i = 0; i < 4; i++) {
suggestContainer.classList.remove('has' + i);
}
suggestContainer.classList.add('has' + candidates.length);

candidates.forEach(function buildCandidateEntry(candidate) {
// Make sure all of the candidates are defined
if (!candidate) return;

// Each candidate gets its own div
var div = document.createElement('div');

// Size the div based on the # of candidates
div.style.width = candidateWidth + 'px';

candidatePanel.appendChild(div);
suggestContainer.appendChild(div);

var text, data, correction = false;
if (typeof candidate === 'string') {
Expand Down Expand Up @@ -394,7 +396,7 @@ const IMERender = (function() {
container.appendChild(span);

var limit = .6; // Dont use a scale smaller than this
var scale = IMERender.getScale(span, container);
var scale = IMERender.getScale(span, candidates.length);

// If the text does not fit within the scaling limit,
// reduce the length of the text by replacing characters in
Expand All @@ -407,7 +409,7 @@ const IMERender = (function() {
span.textContent = text.substring(0, halflen) +
'…' +
text.substring(text.length - halflen);
scale = IMERender.getScale(span, container);
scale = IMERender.getScale(span, candidates.length);
}
}

Expand All @@ -427,6 +429,8 @@ const IMERender = (function() {
}
});
} else {
candidatePanel.innerHTML = '';

candidatePanelToggleButton.style.display = 'none';
toggleCandidatePanel(false);
docFragment = candidatesFragmentCode(1, candidates, true);
Expand Down Expand Up @@ -778,6 +782,15 @@ const IMERender = (function() {
if (inputMethodName)
candidatePanel.classList.add(inputMethodName);

var dismissButton = document.createElement('div');
dismissButton.classList.add('dismiss-suggestions-button');
dismissButton.classList.add('hide');
candidatePanel.appendChild(dismissButton);

var suggestionContainer = document.createElement('div');
suggestionContainer.classList.add('suggestions-container');
candidatePanel.appendChild(suggestionContainer);

return candidatePanel;
};

Expand Down Expand Up @@ -891,9 +904,21 @@ const IMERender = (function() {
// we use in Gaia.
//
// Note that this only works if the element is display:inline
var getScale = function(element, container) {
var elementWidth = element.getBoundingClientRect().width;
var s = container.clientWidth / elementWidth;
var scaleContext = null;
var getScale = function(element, noOfSuggestions) {
if (!scaleContext) {
scaleContext = document.createElement('canvas').getContext('2d');
scaleContext.font = '2rem sans-serif';
}

var elementWidth = scaleContext.measureText(element.textContent).width;

// container width is window width - 36 (for the dismiss button) and then
// depending on the number of suggestions there are
var cw = (cachedWindowWidth - 36) / noOfSuggestions | 0;
cw -= 6; // 6 pixels margin on both sides

var s = cw / elementWidth;
if (s >= 1)
return 1; // 10pt font "Body Large"
if (s >= .8)
Expand Down Expand Up @@ -951,6 +976,7 @@ const IMERender = (function() {
'toggleCandidatePanel': toggleCandidatePanel,
'isFullCandidataPanelShown': isFullCandidataPanelShown,
'getNumberOfCandidatesPerRow': getNumberOfCandidatesPerRow,
'candidatePanelCode': candidatePanelCode,
get activeIme() {
return activeIme;
},
Expand Down
72 changes: 47 additions & 25 deletions apps/keyboard/style/keyboard.css
Expand Up @@ -177,11 +177,6 @@ button::-moz-focus-inner {
font: 500 1.5rem/4.3rem 'Keyboard Symbols', sans-serif;
}

.keyboard-key.special-key.highlighted > .visual-wrapper > span:after {
font-size: 2.0rem;
}


/* Highlight for special keys */
.keyboard-key.special-key.highlighted > .visual-wrapper > span {
color: #00b8d6;
Expand All @@ -192,7 +187,7 @@ button::-moz-focus-inner {
.keyboard-key.special-key.highlighted > .visual-wrapper > span:after,
.keyboard-key.highlighted[data-keycode="32"] > .visual-wrapper > span:after,
#keyboard-accent-char-menu .keyboard-key > .visual-wrapper:before {
display: none;
opacity: 0;
}


Expand Down Expand Up @@ -447,7 +442,7 @@ bubble above the key when you tap and hold. */

/* for latin suggestions we don't need such a tall box */
/* and in latin we hide the toggle button, so we can be full-width */
#keyboard.candidate-panel .keyboard-candidate-panel.latin {
.candidate-panel .keyboard-candidate-panel.latin {
display: block;
white-space: nowrap;
height: 3rem;
Expand All @@ -459,7 +454,7 @@ bubble above the key when you tap and hold. */
overflow: hidden;
}

#keyboard.full-candidate-panel .keyboard-candidate-panel[data-truncated]::after {
.full-candidate-panel .keyboard-candidate-panel[data-truncated]::after {
content: '…';
background: none ! important;
border-color: transparent ! important;
Expand All @@ -473,23 +468,8 @@ bubble above the key when you tap and hold. */
line-height: 2.8rem;
}

.keyboard-candidate-panel.latin > div {
display: inline-block;
height: 100%; /* width set in render.js */
margin: 0 3px; /* px instead of rem because we use this in render.js */
padding: 0;
border: 0;
overflow: hidden;
-moz-box-sizing: border-box;
}

.keyboard-candidate-panel.latin span {
/*
* We start inline, so we can measure the length of the text, and then
* convert (in render.js) to inline-block so we can transform the text
* and make it fit.
*/
display: inline;
display: inline-block;
font-size: 2.0rem;
font-weight: normal;
line-height: 3rem;
Expand All @@ -500,6 +480,9 @@ bubble above the key when you tap and hold. */
background: none;
color: #fff;
text-align: center;
overflow: hidden;
white-space: nowrap;
width: 100%;
}

.keyboard-candidate-panel.latin span.autocorrect {
Expand Down Expand Up @@ -633,10 +616,16 @@ bubble above the key when you tap and hold. */
color: #333;
}

.suggestions-container {
display: none;
}
.dismiss-suggestions-button {
visibility: hidden;
}

/*
* Styles for the dismiss suggestions button in the candidate panel
*/

.keyboard-candidate-panel.latin > .dismiss-suggestions-button {
display:inline-block;
height: 100%;
Expand All @@ -650,8 +639,41 @@ bubble above the key when you tap and hold. */
background: url('images/icon_dismiss.png') 0.5rem center /2.4rem no-repeat;
margin: 0;
padding: 0;
float: left;
visibility: visible;
}

.keyboard-candidate-panel.latin > .dismiss-suggestions-button.hide {
visibility: hidden;
}

.keyboard-candidate-panel.latin > .suggestions-container {
display: block;
width: calc(100% - 3.6rem);
float: left;
}
.keyboard-candidate-panel.latin > .suggestions-container > div {
text-align: center;
display: inline-block;
height: 100%;
margin: 0 0.3rem;
padding: 0;
border: 0;
overflow: hidden;
-moz-box-sizing: border-box;
}

.keyboard-candidate-panel.latin > .suggestions-container.has1 > div {
width: calc(100% - 0.6rem);
}
.keyboard-candidate-panel.latin > .suggestions-container.has2 > div {
width: calc(50% - 0.6rem);
}
.keyboard-candidate-panel.latin > .suggestions-container.has3 > div {
width: calc(33% - 0.6rem);
}


/* Bangla Probhat */
.keyboard-key > .visual-wrapper > span[data-label="ো"] {
font-size: 1.6rem;
Expand Down
31 changes: 6 additions & 25 deletions apps/keyboard/test/unit/render_test.js
Expand Up @@ -458,8 +458,7 @@ suite('Renderer', function() {

suite('showCandidates', function() {
test('Has dismiss-suggestions-button', function() {
var el = document.createElement('div');
el.classList.add('keyboard-candidate-panel');
var el = IMERender.candidatePanelCode();
activeIme.appendChild(el);

IMERender.setInputMethodName('latin');
Expand All @@ -470,8 +469,7 @@ suite('Renderer', function() {
});

test('Three candidates', function() {
var el = document.createElement('div');
el.classList.add('keyboard-candidate-panel');
var el = IMERender.candidatePanelCode();
activeIme.appendChild(el);

IMERender.setInputMethodName('latin');
Expand All @@ -485,24 +483,10 @@ suite('Renderer', function() {
assert.equal(spans[1].dataset.data, 'lah', 'data 1');
assert.equal(spans[2].textContent, 'lo', 'textContent 2');
assert.equal(spans[2].dataset.data, 'lo', 'data 2');

// total width is (innerWidth - width of dismiss button) / 3
var dismissWidth =
el.querySelector('.dismiss-suggestions-button').offsetWidth;
// 3 px margin on both sides
var expected = ((el.offsetWidth - dismissWidth) / 3) - 6 | 0;
for (var i = 0; i < spans.length; i++) {
// it can differ 1 pixel because of outlining here, depending
// on window size
assert.equal(
Math.abs(spans[i].parentNode.offsetWidth - expected) <= 1,
true);
}
});

test('Zero candidates', function() {
var el = document.createElement('div');
el.classList.add('keyboard-candidate-panel');
var el = IMERender.candidatePanelCode();
activeIme.appendChild(el);

IMERender.setInputMethodName('latin');
Expand All @@ -513,8 +497,7 @@ suite('Renderer', function() {
});

test('Candidate with star', function() {
var el = document.createElement('div');
el.classList.add('keyboard-candidate-panel');
var el = IMERender.candidatePanelCode();
activeIme.appendChild(el);

var can = ['*awesome', 'moar', 'whoo'];
Expand All @@ -529,8 +512,7 @@ suite('Renderer', function() {
});

test('Scaling to 0.6', function() {
var el = document.createElement('div');
el.classList.add('keyboard-candidate-panel');
var el = IMERender.candidatePanelCode();
activeIme.appendChild(el);

IMERender.setInputMethodName('latin');
Expand All @@ -552,8 +534,7 @@ suite('Renderer', function() {
});

test('Scaling to 0.5', function() {
var el = document.createElement('div');
el.classList.add('keyboard-candidate-panel');
var el = IMERender.candidatePanelCode();
activeIme.appendChild(el);

IMERender.setInputMethodName('latin');
Expand Down

0 comments on commit 2f0ef53

Please sign in to comment.