Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
257
gaia/apps/keyboard/js/views/candidate_panel_view.js
Executable file
257
gaia/apps/keyboard/js/views/candidate_panel_view.js
Executable file
|
|
@ -0,0 +1,257 @@
|
|||
'use strict';
|
||||
|
||||
/* global BaseView */
|
||||
|
||||
(function(exports) {
|
||||
|
||||
/**
|
||||
* CandidateView handles the rendering of each candidate, i.e.
|
||||
* the word suggestion.
|
||||
*/
|
||||
function CandidateView() {
|
||||
BaseView.apply(this, arguments);
|
||||
}
|
||||
|
||||
CandidateView.prototype = Object.create(BaseView.prototype);
|
||||
|
||||
CandidateView.prototype.render = function render() {
|
||||
var span = document.createElement('span');
|
||||
span.textContent = this.target.text;
|
||||
span.style.flex = this.options.unit;
|
||||
// ui/integration test needs this
|
||||
span.dataset.data = this.target.data;
|
||||
|
||||
this.element = span;
|
||||
|
||||
this.viewManager.registerView(this.target, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* CandidateToggleButtonView represents the toggle button to show/hide
|
||||
* the full candidate panel.
|
||||
*/
|
||||
function CandidateToggleButtonView() {
|
||||
BaseView.apply(this, arguments);
|
||||
}
|
||||
|
||||
CandidateToggleButtonView.prototype = Object.create(BaseView.prototype);
|
||||
|
||||
CandidateToggleButtonView.prototype.render = function() {
|
||||
var toggleButton = document.createElement('div');
|
||||
toggleButton.classList.add('keyboard-candidate-panel-toggle-button');
|
||||
toggleButton.classList.add('hide');
|
||||
|
||||
this.element = toggleButton;
|
||||
|
||||
this.viewManager.registerView(this.target, this);
|
||||
};
|
||||
|
||||
CandidateToggleButtonView.prototype.show = function() {
|
||||
this.element.classList.remove('hide');
|
||||
};
|
||||
|
||||
CandidateToggleButtonView.prototype.hide = function() {
|
||||
this.element.classList.add('hide');
|
||||
};
|
||||
|
||||
/**
|
||||
* CandidatePanelView handles the rendering of candidate panel, used for showing
|
||||
* word suggestions.
|
||||
*/
|
||||
function CandidatePanelView(target, options, viewManager) {
|
||||
BaseView.apply(this, arguments);
|
||||
}
|
||||
|
||||
// Default value for how many candidates shown in a row.
|
||||
CandidatePanelView.prototype.COUNT_PER_ROW = 8;
|
||||
|
||||
CandidatePanelView.prototype.HEIGHT_IN_REM = 3.2;
|
||||
|
||||
CandidatePanelView.prototype.render = function render() {
|
||||
var candidatePanel = document.createElement('div');
|
||||
candidatePanel.setAttribute('role', 'group');
|
||||
candidatePanel.dataset.l10nId = 'wordSuggestions2';
|
||||
|
||||
candidatePanel.classList.add('keyboard-candidate-panel');
|
||||
if (this.options.className) {
|
||||
candidatePanel.classList.add(this.options.className);
|
||||
}
|
||||
|
||||
var suggestionsContainer = document.createElement('div');
|
||||
suggestionsContainer.classList.add('suggestions-container');
|
||||
suggestionsContainer.setAttribute('role', 'listbox');
|
||||
candidatePanel.appendChild(suggestionsContainer);
|
||||
this.suggestionsContainer = suggestionsContainer;
|
||||
|
||||
// Create toggle button
|
||||
// we're not getting reference of LayoutManager, so define this manually
|
||||
var KEYCODE_TOGGLE_CANDIDATE_PANEL = -4;
|
||||
|
||||
// TODO: we should not create a business logic object in the view,
|
||||
// let's move it to somewhere else.
|
||||
this.toggleButton = new CandidateToggleButtonView({
|
||||
keyCode: KEYCODE_TOGGLE_CANDIDATE_PANEL },
|
||||
null,
|
||||
this.viewManager);
|
||||
this.toggleButton.render();
|
||||
|
||||
candidatePanel.appendChild(this.toggleButton.element);
|
||||
this.element = candidatePanel;
|
||||
};
|
||||
|
||||
//
|
||||
// Show candidates
|
||||
// Each candidate is a string or an array of two strings
|
||||
//
|
||||
CandidatePanelView.prototype.showCandidates = function(candidates) {
|
||||
if (!this.element) {
|
||||
console.error('CandidatePanelView: CandidatePanel is not ready yet!');
|
||||
return;
|
||||
}
|
||||
|
||||
var candidatePanel = this.element;
|
||||
candidatePanel.dataset.candidateIndicator = 0;
|
||||
this.suggestionsContainer.innerHTML = '';
|
||||
this.toggleButton.hide();
|
||||
|
||||
var docFragment = this.renderCandidatePanel(1, candidates, true);
|
||||
|
||||
this.suggestionsContainer.appendChild(docFragment);
|
||||
};
|
||||
|
||||
CandidatePanelView.prototype.renderCandidatePanel = function(rowLimit,
|
||||
candidates,
|
||||
indentFirstRow) {
|
||||
var candidatePanel = this.element;
|
||||
|
||||
var docFragment = document.createDocumentFragment();
|
||||
if (candidates.length === 0) {
|
||||
candidatePanel.dataset.rowCount = 0;
|
||||
return docFragment;
|
||||
}
|
||||
|
||||
var rowDiv = document.createElement('div');
|
||||
rowDiv.classList.add('candidate-row');
|
||||
if (indentFirstRow) {
|
||||
rowDiv.classList.add('candidate-row-first');
|
||||
}
|
||||
|
||||
var nowUnit = 0;
|
||||
var rowCount = 0;
|
||||
|
||||
if (rowLimit < 0) {
|
||||
rowLimit = Number.Infinity;
|
||||
}
|
||||
|
||||
var candidatesLength = candidates.length;
|
||||
var dummyEl = null;
|
||||
var i = 0;
|
||||
|
||||
candidates.some(function(candidate, index) {
|
||||
var cand, data;
|
||||
if (typeof candidate == 'string') {
|
||||
cand = data = candidate;
|
||||
} else {
|
||||
cand = candidate[0];
|
||||
data = candidate[1];
|
||||
}
|
||||
|
||||
var unit = this.options.widthUnit ? this.options.widthUnit :
|
||||
(cand.length >> 1) + 1;
|
||||
|
||||
// TODO: we should not create a business logic object in the view,
|
||||
// let's move it to somewhere else.
|
||||
var candidateView = new CandidateView({ suggestion: true,
|
||||
selection: true,
|
||||
text: cand,
|
||||
data: data },
|
||||
{ unit: unit },
|
||||
this.viewManager);
|
||||
candidateView.render();
|
||||
|
||||
nowUnit += unit;
|
||||
i++;
|
||||
|
||||
var needBreak = false;
|
||||
if (rowCount === 0 && indentFirstRow &&
|
||||
nowUnit >= this.COUNT_PER_ROW && index != candidatesLength - 1) {
|
||||
needBreak = true;
|
||||
}
|
||||
|
||||
if (nowUnit > this.COUNT_PER_ROW || needBreak) {
|
||||
if (rowCount === 0 && needBreak) {
|
||||
this.toggleButton.show();
|
||||
// Create a dummy element to represent the toggle button to occupy
|
||||
// the space that should be taken by it.
|
||||
dummyEl = document.createElement('span');
|
||||
dummyEl.style.flex = this.COUNT_PER_ROW - (nowUnit - unit);
|
||||
rowDiv.appendChild(dummyEl);
|
||||
}
|
||||
|
||||
if (rowCount >= rowLimit - 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
docFragment.appendChild(rowDiv);
|
||||
rowCount++;
|
||||
|
||||
// Create the next row
|
||||
rowDiv = document.createElement('div');
|
||||
rowDiv.classList.add('candidate-row');
|
||||
nowUnit = unit;
|
||||
}
|
||||
|
||||
rowDiv.appendChild(candidateView.element);
|
||||
}, this);
|
||||
|
||||
// Insert a dummy element to fill up the flex box to make it look
|
||||
// like a grid.
|
||||
if (nowUnit < this.COUNT_PER_ROW &&
|
||||
typeof this.options.widthUnit === 'undefined') {
|
||||
dummyEl = document.createElement('span');
|
||||
dummyEl.style.flex = this.COUNT_PER_ROW - nowUnit;
|
||||
rowDiv.appendChild(dummyEl);
|
||||
}
|
||||
|
||||
if (i != candidatesLength) {
|
||||
candidatePanel.dataset.truncated = true;
|
||||
} else {
|
||||
delete candidatePanel.dataset.truncated;
|
||||
}
|
||||
|
||||
candidatePanel.dataset.rowCount = rowCount + 1;
|
||||
candidatePanel.dataset.candidateIndicator =
|
||||
parseInt(candidatePanel.dataset.candidateIndicator) + i;
|
||||
|
||||
docFragment.appendChild(rowDiv);
|
||||
rowDiv = null;
|
||||
|
||||
return docFragment;
|
||||
};
|
||||
|
||||
CandidatePanelView.prototype.showMoreCandidates = function(rowLimit,
|
||||
candidates) {
|
||||
if (!candidates) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rowLimit) {
|
||||
rowLimit = -1;
|
||||
}
|
||||
|
||||
this.suggestionsContainer.appendChild(
|
||||
this.renderCandidatePanel(rowLimit, candidates));
|
||||
};
|
||||
|
||||
CandidatePanelView.prototype.resetScroll = function() {
|
||||
this.suggestionsContainer.scrollTop =
|
||||
this.suggestionsContainer.scrollLeft = 0;
|
||||
};
|
||||
|
||||
CandidatePanelView.prototype.getHeight = function() {
|
||||
return this.HEIGHT_IN_REM * this.viewManager.getRemToPx();
|
||||
};
|
||||
|
||||
exports.CandidatePanelView = CandidatePanelView;
|
||||
|
||||
})(window);
|
||||
Loading…
Reference in a new issue