mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-30 03:27:44 +00:00
Merge pull request #2045 from keymanapp/web-1460-osk-default-keycaps
[Web] Removes default key cap text behavior
This commit is contained in:
commit
a2bf4d53ee
5 changed files with 171 additions and 8 deletions
|
|
@ -3,6 +3,9 @@
|
|||
## 13.0 alpha
|
||||
* Start version 13.0
|
||||
|
||||
## 2019-09-06 12.0.81 beta
|
||||
* For keyboards compiled with Developer 12.0 onward, default key caps will no longer be provided. (#2045)
|
||||
|
||||
## 2019-09-04 12.0.80 beta
|
||||
* Fixed issue with 'pt' and unitless font size specifications for keyboard layouts (#2033)
|
||||
* Slightly enhanced error logging for internal events (#2037)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
Copyright 2017 SIL International
|
||||
***/
|
||||
|
||||
///<reference path="../utils/version.ts"/>
|
||||
|
||||
namespace com.keyman.osk {
|
||||
let Codes = com.keyman.text.Codes;
|
||||
|
||||
|
|
@ -109,12 +111,13 @@ namespace com.keyman.osk {
|
|||
/**
|
||||
* Build a default layout for keyboards with no explicit layout
|
||||
*
|
||||
* @param {Object} PVK keyboard object (as loaded)
|
||||
* @param {number} kbdBitmask keyboard modifier bitmask
|
||||
* @param {Object} PVK keyboard object (as loaded)
|
||||
* @param {Object} kbdDevVersion object representing the version of Developer that compiled the keyboard
|
||||
* @param {number} kbdBitmask keyboard modifier bitmask
|
||||
* @param {string} formFactor
|
||||
* @return {Object}
|
||||
*/
|
||||
static buildDefaultLayout(PVK, kbdBitmask: number, formFactor: string): LayoutFormFactor {
|
||||
static buildDefaultLayout(PVK, kbdDevVersion: utils.Version, kbdBitmask: number, formFactor: string): LayoutFormFactor {
|
||||
let keyman = com.keyman.singleton;
|
||||
let util = keyman.util;
|
||||
|
||||
|
|
@ -248,9 +251,9 @@ namespace com.keyman.osk {
|
|||
if(kx >= 0 && kx < layerSpec.length) key['text']=layerSpec[kx];
|
||||
}
|
||||
|
||||
// Fall back to US English keycap text as default for the base two layers if not otherwise defined.
|
||||
// (Any 'ghost' keys must be explicitly defined in layout for these layers.)
|
||||
if(isDefault) {
|
||||
// Legacy (pre 12.0) behavior: fall back to US English keycap text as default for the base two layers
|
||||
// if a key cap is not otherwise defined. (Any intentional 'ghost' keys must be explicitly defined.)
|
||||
if(isDefault && kbdDevVersion.precedes(utils.Version.NO_DEFAULT_KEYCAPS)) {
|
||||
if(key['id'] != 'K_SPACE' && kx+65 * isShift < Layouts.dfltText.length && key['text'] !== null) {
|
||||
key['text'] = key['text'] || Layouts.dfltText[kx+65*isShift];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/// <reference path="activeLayout.ts" />
|
||||
/// <reference path="../utils/version.ts" />
|
||||
|
||||
namespace com.keyman.osk {
|
||||
let Codes = com.keyman.text.Codes;
|
||||
|
|
@ -591,7 +592,8 @@ namespace com.keyman.osk {
|
|||
|
||||
// Build a layout using the default for the device
|
||||
if(typeof layout != 'object' || layout == null) {
|
||||
layout=Layouts.buildDefaultLayout(PVK,kbdBitmask, formFactor);
|
||||
let kbdDevVersion = new utils.Version(activeKeyboard['KVER']);
|
||||
layout=Layouts.buildDefaultLayout(PVK, kbdDevVersion, kbdBitmask, formFactor);
|
||||
}
|
||||
|
||||
// Create the collection of HTML elements from the device-dependent layout object
|
||||
|
|
@ -2093,7 +2095,8 @@ namespace com.keyman.osk {
|
|||
|
||||
// Else get a default layout for the device for this keyboard
|
||||
if(layout == null && PVK != null) {
|
||||
layout=Layouts.buildDefaultLayout(PVK,keymanweb.keyboardManager.getKeyboardModifierBitmask(PKbd),formFactor);
|
||||
let kbdDevVersion = new utils.Version(PKbd['KVER']);
|
||||
layout=Layouts.buildDefaultLayout(PVK, kbdDevVersion, keymanweb.keyboardManager.getKeyboardModifierBitmask(PKbd),formFactor);
|
||||
}
|
||||
|
||||
// Cannot create an OSK if no layout defined, just return empty DIV
|
||||
|
|
|
|||
101
web/source/utils/version.ts
Normal file
101
web/source/utils/version.ts
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
namespace com.keyman.utils {
|
||||
// Dotted-decimal version
|
||||
export class Version {
|
||||
// Represents a default version value for keyboards compiled before this was compiled into keyboards.
|
||||
// The exact version is unknown at this point, but the value is "good enough" for what we need.
|
||||
public static readonly DEVELOPER_VERSION_FALLBACK = new Version([9, 0, 0]);
|
||||
|
||||
// For 12.0, the old default behavior of adding missing keycaps to the default layers was removed,
|
||||
// as it results in unexpected, bug-like behavior for keyboard designers when it is unwanted.
|
||||
public static readonly NO_DEFAULT_KEYCAPS = new Version([12, 0]);
|
||||
|
||||
private readonly components: number[]
|
||||
|
||||
/**
|
||||
* Parses version information, preparing it for use in comparisons.
|
||||
* @param text Either a string representing a version number (ex: "9.0.0") or an array representing
|
||||
* its components (ex: [9, 0, 0]).
|
||||
*/
|
||||
constructor(text: String | number[]) {
|
||||
// If a keyboard doesn't specify a version, use the DEVELOPER_VERSION_FALLBACK values.
|
||||
if(text === undefined || text === null) {
|
||||
this.components = [].concat(Version.DEVELOPER_VERSION_FALLBACK.components);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Array.isArray(text)) {
|
||||
let components = text as number[];
|
||||
if(components.length < 2) {
|
||||
throw new Error("Version string must have at least a major and minor component!");
|
||||
} else {
|
||||
this.components = [].concat(components);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// else, standard constructor path.
|
||||
let parts = text.split('.');
|
||||
let componentArray: number[] = [];
|
||||
|
||||
if(parts.length < 2) {
|
||||
throw new Error("Version string must have at least a major and minor component!");
|
||||
}
|
||||
|
||||
for(let i=0; i < parts.length; i++) {
|
||||
let value = parseInt(parts[i], 10);
|
||||
if(isNaN(value)) {
|
||||
throw new Error("Version string components must be numerical!");
|
||||
}
|
||||
|
||||
componentArray.push(value);
|
||||
}
|
||||
|
||||
this.components = componentArray;
|
||||
}
|
||||
|
||||
get major(): number {
|
||||
return this.components[0];
|
||||
}
|
||||
|
||||
get minor(): number {
|
||||
return this.components[1];
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.components.join('.');
|
||||
}
|
||||
|
||||
equals(other: Version): boolean {
|
||||
return this.compareTo(other) == 0;
|
||||
}
|
||||
|
||||
precedes(other: Version): boolean {
|
||||
return this.compareTo(other) < 0;
|
||||
}
|
||||
|
||||
compareTo(other: Version): number {
|
||||
// If the version info depth differs, we need a flag to indicate which instance is shorter.
|
||||
var isShorter: boolean = this.components.length < other.components.length;
|
||||
var maxDepth: number = (this.components.length < other.components.length) ? this.components.length : other.components.length;
|
||||
|
||||
var i: number;
|
||||
for(i = 0; i < maxDepth; i++) {
|
||||
let delta = this.components[i] - other.components[i];
|
||||
if(delta != 0) {
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
|
||||
var longList = isShorter ? other.components : this.components;
|
||||
do {
|
||||
if(longList[i] > 0) {
|
||||
return isShorter ? -1 : 1;
|
||||
}
|
||||
i++;
|
||||
} while (i < longList.length);
|
||||
|
||||
// Equal.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
web/unit_tests/cases/versions.js
Normal file
53
web/unit_tests/cases/versions.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
var assert = chai.assert;
|
||||
|
||||
describe('Version Logic', function() {
|
||||
this.timeout(kmwconfig.timeouts.standard);
|
||||
|
||||
before(function(done) {
|
||||
this.timeout(kmwconfig.timeouts.scriptLoad);
|
||||
setupKMW(null, done, kmwconfig.timeouts.scriptLoad);
|
||||
});
|
||||
|
||||
after(function() {
|
||||
teardownKMW();
|
||||
});
|
||||
|
||||
it('Should provide a default, fallback value when nothing is specified', function() {
|
||||
var fallback = new com.keyman.utils.Version(undefined);
|
||||
assert.isTrue(fallback.equals(com.keyman.utils.Version.DEVELOPER_VERSION_FALLBACK));
|
||||
});
|
||||
|
||||
it('Should properly process a simple major.minor version string.', function() {
|
||||
var version = new com.keyman.utils.Version("1.2");
|
||||
assert.equal(version.major, 1);
|
||||
assert.equal(version.minor, 2);
|
||||
});
|
||||
|
||||
it('Should handle long/deep version specifications.', function() {
|
||||
var version = new com.keyman.utils.Version("1.2.3.4.5.6");
|
||||
assert.equal(version.components.length, 6);
|
||||
assert.equal(version.major, 1);
|
||||
assert.equal(version.minor, 2);
|
||||
});
|
||||
|
||||
it('Should properly compare two versions.', function() {
|
||||
var v9_0_1 = new com.keyman.utils.Version("9.0.1");
|
||||
var v9_1_0 = new com.keyman.utils.Version("9.1.0");
|
||||
var v10_0 = new com.keyman.utils.Version("10.0");
|
||||
var v10_0_0 = new com.keyman.utils.Version("10.0.0");
|
||||
|
||||
// "Precede" checks
|
||||
assert.equal(v9_0_1.compareTo(v9_1_0), -1);
|
||||
assert.equal(v9_1_0.compareTo(v10_0_0), -1);
|
||||
assert.equal(v9_0_1.compareTo(v10_0_0), -1);
|
||||
|
||||
// Equality checks
|
||||
assert.equal(v9_0_1.compareTo(v9_0_1), 0);
|
||||
// Tests equal versions where one omits the build number.
|
||||
assert.equal( v10_0.compareTo(v10_0_0), 0);
|
||||
|
||||
// Ensures the first "precede" check's return is flipped when the order's flipped.
|
||||
assert.equal(v9_1_0.compareTo(v9_0_1), 1);
|
||||
});
|
||||
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue