mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-13 11:07:42 +00:00
feat(web): standalone osk tech demo / 'test' page
This commit is contained in:
parent
921d0da4b7
commit
f94cd9f5dd
6 changed files with 687 additions and 0 deletions
|
|
@ -2,6 +2,7 @@ export { DeviceSpec } from '@keymanapp/web-utils/build/obj/deviceSpec.js';
|
|||
export { default as Keyboard } from '@keymanapp/keyboard-processor/build/obj/keyboards/keyboard.js';
|
||||
export { default as Codes } from '@keymanapp/keyboard-processor/build/obj/text/codes.js';
|
||||
|
||||
export { default as KeyboardProperties } from './keyboardProperties.js';
|
||||
export { default as FloatingOSKView } from './views/floatingOskView.js';
|
||||
export { default as FloatingOSKViewCookie } from './views/floatingOskCookie.js';
|
||||
export { default as AnchoredOSKView } from './views/anchoredOskView.js';
|
||||
|
|
@ -9,6 +10,7 @@ export { default as InlinedOSKView } from './views/inlinedOskView.js';
|
|||
export { BannerController } from './banner/bannerView.js';
|
||||
export { default as VisualKeyboard } from './visualKeyboard.js';
|
||||
export type { default as ViewConfiguration } from './config/viewConfiguration.js';
|
||||
export type { default as SpacebarText } from './spacebarText.js';
|
||||
|
||||
export { default as Activator } from './views/activator.js';
|
||||
export { default as SimpleActivator } from './views/simpleActivator.js';
|
||||
|
|
|
|||
82
web/src/test/manual/web/osk/kbdLoader.mjs
Normal file
82
web/src/test/manual/web/osk/kbdLoader.mjs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import { Keyboard, KeyboardProperties, Codes } from '../../../../../build/engine/osk/lib/index.mjs';
|
||||
|
||||
// This script may or may not be temporary; the KMW "KeyboardManager" class may be spun off in a manner
|
||||
// that could replace this.
|
||||
|
||||
export function loadKeyboardFromPath(path) {
|
||||
const window_KeymanWeb = window['KeymanWeb'];
|
||||
const window_keyman = window['keyman'];
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
const loader = window['KeymanWeb'] = {
|
||||
KR(kbdObj) {
|
||||
this.keyboard = kbdObj;
|
||||
},
|
||||
keyboard: null,
|
||||
};
|
||||
|
||||
// Needed for some debug-compiled keyboards. Also, the `keyman` top-level var itself is
|
||||
// needed for any KMW 10+ keyboards.
|
||||
window['keyman'] = {
|
||||
osk: {
|
||||
modifierCodes: Codes.modifierCodes,
|
||||
keyCodes: Codes.keyCodes
|
||||
}
|
||||
};
|
||||
|
||||
const script = document.createElement('script');
|
||||
document.head.appendChild(script);
|
||||
script.onerror = reject;
|
||||
script.onload = () => {
|
||||
if(loader.keyboard) {
|
||||
resolve(loader.keyboard);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/37393041 - totally safe.
|
||||
script.remove();
|
||||
}
|
||||
|
||||
// Now that EVERYTHING ELSE is ready, establish the link to the keyboard's script.
|
||||
script.src = path;
|
||||
});
|
||||
|
||||
promise.finally(() => {
|
||||
window['KeymanWeb'] = window_KeymanWeb;
|
||||
window['keyman'] = window_keyman;
|
||||
|
||||
if(window['KeymanWeb'] === undefined) {
|
||||
delete window['KeymanWeb'];
|
||||
}
|
||||
|
||||
if(window['keyman'] === undefined) {
|
||||
delete window['keyman'];
|
||||
}
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
export function loadKeyboardsFromStubs(apiStubs) {
|
||||
let keyboards = {};
|
||||
let priorPromise = Promise.resolve();
|
||||
for(let stub of apiStubs) {
|
||||
priorPromise = priorPromise.then(() => {
|
||||
// Adds closure to capture 'id' for async completion use.
|
||||
let overwriteLoader = (id, path) => {
|
||||
let loader = loadKeyboardFromPath(path);
|
||||
return loader.then(kbd => {
|
||||
keyboards[stub.id].keyboard = new Keyboard(kbd)
|
||||
});
|
||||
}
|
||||
keyboards[stub.id] = {
|
||||
keyboard: overwriteLoader(stub.id, stub.filename),
|
||||
metadata: new KeyboardProperties(stub)
|
||||
};
|
||||
return keyboards[stub.id].keyboard;
|
||||
});
|
||||
}
|
||||
|
||||
return priorPromise.then(() => keyboards);
|
||||
}
|
||||
265
web/src/test/manual/web/osk/scratchspace/commands.js
Normal file
265
web/src/test/manual/web/osk/scratchspace/commands.js
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
// Reference to the currently-active OSK.
|
||||
var currentOSK = null;
|
||||
var currentOSKMode = null;
|
||||
|
||||
// The currently-selected keyboard + metadata pairing.
|
||||
var keyboard = null; // Cannot immediately initialized, as module-scripts use defer loading.
|
||||
|
||||
function log(str) {
|
||||
document.getElementById('eventlog').textContent += str + '\n\n';
|
||||
}
|
||||
|
||||
// NOT a module - so we can declare a few event listener methods.
|
||||
function setOSK(mode) {
|
||||
let modeList = ['floating', 'anchored', 'inline'];
|
||||
|
||||
if(currentOSK) {
|
||||
if(mode) {
|
||||
if(!modeList.includes(mode)) {
|
||||
console.warn(`Invalid OSK mode requested: "${mode}"`);
|
||||
}
|
||||
}
|
||||
|
||||
// Close out the previous one.
|
||||
currentOSK.shutdown();
|
||||
if(currentOSK.element) {
|
||||
try {
|
||||
currentOSK.element.remove();
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showOSK(true); // Reset related CSS classes for UI elements.
|
||||
|
||||
modeList.forEach((panel) => {
|
||||
let panelElement = document.getElementById(panel + "-mode");
|
||||
|
||||
if(panel == mode) {
|
||||
panelElement.classList.remove('inactive');
|
||||
panelElement.classList.add('active');
|
||||
} else {
|
||||
panelElement.classList.remove('active');
|
||||
panelElement.classList.add('inactive');
|
||||
}
|
||||
});
|
||||
|
||||
let config = {
|
||||
...BaseConfiguration,
|
||||
device: window.targetDevice,
|
||||
hostDevice: window.HOST_DEVICE
|
||||
};
|
||||
|
||||
// Find the buttons & highlight accordingly.
|
||||
const oskGroup = document.getElementById('osk-select');
|
||||
const buttons = ['floating', 'anchored', 'inline'];
|
||||
highlightGroupSelection(oskGroup, buttons, mode);
|
||||
|
||||
// Possible if there's no active OSK yet.
|
||||
currentOSK = null;
|
||||
currentOSKMode = mode;
|
||||
if(!mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up the new one.
|
||||
switch(mode) {
|
||||
case 'floating':
|
||||
currentOSK = new modules.osk.FloatingOSKView(config);
|
||||
setTarget('text');
|
||||
break;
|
||||
case 'anchored':
|
||||
currentOSK = new modules.osk.AnchoredOSKView(config);
|
||||
setTarget('text');
|
||||
break;
|
||||
case 'inline':
|
||||
currentOSK = new modules.osk.InlinedOSKView(config);
|
||||
document.getElementById('inline-container').appendChild(currentOSK.element);
|
||||
|
||||
// Default: 8px for most browsers.
|
||||
const bodyMargin = parseInt(getComputedStyle(document.body).margin, 10);
|
||||
const maxWidth = screen.width - 2 * bodyMargin;
|
||||
|
||||
// Check page width & constrain the OSK's width if necessary
|
||||
let targetWidth = 800;
|
||||
if(targetWidth > maxWidth) {
|
||||
targetWidth = maxWidth;
|
||||
}
|
||||
|
||||
// Finally, set the OSK's size.
|
||||
currentOSK.setSize(targetWidth, targetWidth / 2);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
if(!keyboard) {
|
||||
keyboard = setKeyboard('us');
|
||||
}
|
||||
currentOSK.activeKeyboard = keyboard;
|
||||
currentOSK.on('keyEvent', (event) => {
|
||||
let eventText = JSON.stringify(event, (key, value) => {
|
||||
switch(key) {
|
||||
case 'srcKeyboard':
|
||||
case 'source':
|
||||
case 'device':
|
||||
case 'keyDistribution':
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
log(eventText);
|
||||
});
|
||||
|
||||
currentOSK.on('shouldShowLanguageMenu', () => {
|
||||
log("(language menu requested)");
|
||||
});
|
||||
|
||||
currentOSK.on('onshow', () => {
|
||||
log("(osk shown)");
|
||||
});
|
||||
|
||||
currentOSK.on('onhide', () => {
|
||||
log("(osk hidden)");
|
||||
})
|
||||
}
|
||||
|
||||
function highlightGroupSelection(group, names, selected) {
|
||||
for(let i = 0; i < names.length; i++) {
|
||||
const button = group.children.item(i);
|
||||
|
||||
if(names[i] == selected) {
|
||||
button.classList.add('selected');
|
||||
} else {
|
||||
button.classList.remove('selected');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function inlineSetSize() {
|
||||
currentOSK.setSize(document.getElementById('set-width').value + 'px', document.getElementById('set-height').value + 'px');
|
||||
}
|
||||
|
||||
function setTarget(type) {
|
||||
let target = null;
|
||||
const textarea = document.getElementById('ta1');
|
||||
const input = document.getElementById('in1');
|
||||
|
||||
textarea.classList.remove('selected');
|
||||
input.classList.remove('selected');
|
||||
|
||||
// Find the buttons & highlight accordingly.
|
||||
const floatTarget = document.getElementById('float-target');
|
||||
const anchorTarget = document.getElementById('anchor-target');
|
||||
const buttons = ['text', 'input', 'none'];
|
||||
highlightGroupSelection(floatTarget, buttons, type);
|
||||
highlightGroupSelection(anchorTarget, buttons, type);
|
||||
|
||||
if(type == 'text') {
|
||||
target = textarea;
|
||||
} else if(type == 'input') {
|
||||
target = input;
|
||||
}
|
||||
|
||||
currentOSK.activationModel.activationTrigger = target;
|
||||
if(target) {
|
||||
target.classList.add('selected');
|
||||
}
|
||||
}
|
||||
|
||||
function showOSK(mode) {
|
||||
// Find the buttons & highlight accordingly.
|
||||
const floatShow = document.getElementById('float-show');
|
||||
const anchorShow = document.getElementById('anchor-show');
|
||||
const buttons = [true, false];
|
||||
highlightGroupSelection(floatShow, buttons, mode);
|
||||
highlightGroupSelection(anchorShow, buttons, mode);
|
||||
|
||||
if(!currentOSK) {
|
||||
return;
|
||||
}
|
||||
|
||||
const visibleAtStart = currentOSK.isVisible();
|
||||
|
||||
if(mode !== undefined) {
|
||||
currentOSK.show(mode);
|
||||
} else {
|
||||
currentOSK.show();
|
||||
highlightGroupSelection(floatShow, buttons, !visibleAtStart);
|
||||
highlightGroupSelection(anchorShow, buttons, visibleAtStart);
|
||||
}
|
||||
}
|
||||
|
||||
function setKeyboard(kbdId) {
|
||||
if(kbdId) {
|
||||
const keyboardGroup = document.getElementById('keyboard-select');
|
||||
const buttons = ['us', 'lao_2008_basic', 'obolo_chwerty_6351'];
|
||||
highlightGroupSelection(keyboardGroup, buttons, kbdId);
|
||||
|
||||
keyboard = window.keyboards[kbdId];
|
||||
} else if(!window.keyboard) {
|
||||
setKeyboard('us');
|
||||
return;
|
||||
}
|
||||
|
||||
// Build the layer commands.
|
||||
const layerButtonGroup = document.getElementById('layer-select');
|
||||
const layout = keyboard.keyboard.layout(window.targetDevice.formFactor);
|
||||
const layerNames = Object.keys(layout.layerMap);
|
||||
layerButtonGroup.innerHTML = ''; // clear all children
|
||||
for(let layer of layerNames) {
|
||||
const button = document.createElement('button');
|
||||
button.textContent = layer;
|
||||
button.onclick = () => {
|
||||
if(currentOSK && currentOSK.vkbd) {
|
||||
currentOSK.vkbd.layerId = layer;
|
||||
|
||||
for(let i = 0; i < layerButtonGroup.children.length; i++) {
|
||||
const btn = layerButtonGroup.children.item(i);
|
||||
|
||||
if(btn == button) {
|
||||
btn.classList.add('selected');
|
||||
} else {
|
||||
btn.classList.remove('selected');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(layer == 'default') {
|
||||
button.classList.add('selected');
|
||||
}
|
||||
|
||||
layerButtonGroup.appendChild(button);
|
||||
}
|
||||
|
||||
if(!currentOSK) {
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
// From here out, rely on the global var `keyboard`.
|
||||
currentOSK.activeKeyboard = keyboard;
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
function setTargetDevice(target) {
|
||||
const devices = {
|
||||
windows: new modules.osk.DeviceSpec('chrome', 'desktop', 'windows', false),
|
||||
aPhone: new modules.osk.DeviceSpec('chrome', 'phone', 'android', true),
|
||||
aPad: new modules.osk.DeviceSpec('chrome', 'tablet', 'android', true),
|
||||
iPhone: new modules.osk.DeviceSpec('safari', 'phone', 'ios', true),
|
||||
iPad: new modules.osk.DeviceSpec('safari', 'tablet', 'ios', true),
|
||||
};
|
||||
|
||||
if(target) {
|
||||
const deviceGroup = document.getElementById('device-select');
|
||||
const buttons = ['windows', 'aPhone', 'aPad', 'iPhone', 'iPad'];
|
||||
highlightGroupSelection(deviceGroup, buttons, target);
|
||||
|
||||
window.targetDevice = devices[target];
|
||||
}
|
||||
|
||||
setOSK(currentOSKMode);
|
||||
}
|
||||
113
web/src/test/manual/web/osk/scratchspace/index.css
Normal file
113
web/src/test/manual/web/osk/scratchspace/index.css
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
body {font-family: Tahoma,helvetica;}
|
||||
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
|
||||
.test {font-size: 24px; width:80%; min-height:30px; border: 1px solid gray;}
|
||||
#KeymanWebControl {width:50%;min-width:600px;}
|
||||
|
||||
.inactive {
|
||||
display: none;
|
||||
}
|
||||
|
||||
textarea.selected, input.selected {
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
#keyboard-controller,
|
||||
#osk-selector {
|
||||
width: fit-content;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
|
||||
body.phone #keyboard-controller,
|
||||
body.phone #osk-selector {
|
||||
width: unset;
|
||||
height: unset;
|
||||
}
|
||||
|
||||
#keyboard-controller button,
|
||||
#osk-selector button {
|
||||
min-width: fit-content;
|
||||
}
|
||||
|
||||
div.panel {
|
||||
padding: 4px;
|
||||
background-color: lightgray;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
div.panel p.category {
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
margin-top: 0.25em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
div.panel .group {
|
||||
border: 1px darkgray solid;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
div.panel div {
|
||||
min-width: fit-content;
|
||||
padding: 4px 0px;
|
||||
}
|
||||
|
||||
body.phone div.panel {
|
||||
width: calc(100% - 8px); /* 4px padding on div.panel, both sides */
|
||||
}
|
||||
|
||||
div.panel .gap {
|
||||
width: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
div.panel div input {
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.flex {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: 4px;
|
||||
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
div.flex.inactive {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.flex button {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
div.flex .group {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#eventlog {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body.touch .notouch {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body .touch {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.touch div.touch {
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.disabled {
|
||||
font-size: 0.9em;
|
||||
font-style:italic;
|
||||
color:darkslategray"
|
||||
}
|
||||
|
||||
button.selected {
|
||||
font-weight: bold;
|
||||
}
|
||||
179
web/src/test/manual/web/osk/scratchspace/index.html
Normal file
179
web/src/test/manual/web/osk/scratchspace/index.html
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<!-- Set the viewport width to match phone and tablet device widths -->
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
|
||||
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>Testing Page - standalone OSK</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="index.css"/>
|
||||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script type="module" src="setup.mjs"></script>
|
||||
|
||||
<script src="commands.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>KeymanWeb OSK Module Testing</h2>
|
||||
<p>
|
||||
Note: if hosted via an IIS setup, you may need to add the 'mjs' extension under
|
||||
"MIME Types" for it to properly serve related module-based JS files.
|
||||
</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div id="controllers">
|
||||
<div id="keyboard-controller" class="flex panel">
|
||||
<div class="group">
|
||||
<p class="category">Keyboard</p>
|
||||
<div id="keyboard-select" class="flex">
|
||||
<button onclick="setKeyboard('us');">US English</button>
|
||||
<button onclick="setKeyboard('lao_2008_basic');">Lao</button>
|
||||
<button onclick="setKeyboard('obolo_chwerty_6351');">Obolo Chwerty</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- select keyboard to use -->
|
||||
<!-- select active layer -->
|
||||
<div class="group">
|
||||
<p class="category">Layer</p>
|
||||
<div id="layer-select" class="flex">
|
||||
<button>default</button>
|
||||
<button>shift</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="osk-selector" class="flex panel" style="flex-direction:column">
|
||||
<div class="group">
|
||||
<p class="category">OSK Mode</p>
|
||||
<div id="osk-select" class="flex">
|
||||
<button onclick="setOSK('floating');">Floating (desktop) OSK</button>
|
||||
<button onclick="setOSK('anchored');">Anchored (touch) OSK</button>
|
||||
<button onclick="setOSK('inline');">Inline OSK</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<p class="category">Target Device</p>
|
||||
<div id="device-select" class="flex">
|
||||
<button onclick="setTargetDevice('windows');">Windows desktop</button>
|
||||
<button onclick="setTargetDevice('aPhone');">Android phone</button>
|
||||
<button onclick="setTargetDevice('aPad');">Android tablet</button>
|
||||
<button onclick="setTargetDevice('iPhone');" class="selected">iPhone</button>
|
||||
<button onclick="setTargetDevice('iPad');">iPad</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="floating-mode" class="flex panel inactive">
|
||||
<div class="group">
|
||||
<!-- OutputTarget selector (text vs input) -->
|
||||
<p class="category">Active Element</p>
|
||||
<div id="float-target" class="flex">
|
||||
<button onclick="setTarget('text')">Textarea</button>
|
||||
<button onclick="setTarget('input')">Input</button>
|
||||
<button onclick="setTarget('none')">None</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<!-- show / hide -->
|
||||
<p class="category">Visibility</p>
|
||||
<div id="float-show" class="notouch flex">
|
||||
<button onclick="showOSK(true)">Show</button>
|
||||
<button onclick="showOSK(false)">Hide</button>
|
||||
<button onclick="showOSK()">Toggle</button>
|
||||
</div>
|
||||
<div class="touch disabled">
|
||||
Disabled (touch-based)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="anchored-mode" class="flex panel inactive">
|
||||
<div class="group">
|
||||
<!-- OutputTarget selector (text vs input) -->
|
||||
<p class="category">Active Element</p>
|
||||
<div id="anchor-target" class="flex">
|
||||
<button onclick="setTarget('text')">Textarea</button>
|
||||
<button onclick="setTarget('input')">Input</button>
|
||||
<button onclick="setTarget('none')">None</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<!-- show / hide -->
|
||||
<p class="category">Visibility</p>
|
||||
<div id="anchor-show" class="flex notouch">
|
||||
<button onclick="showOSK(true)">Show</button>
|
||||
<button onclick="showOSK(false)">Hide</button>
|
||||
<button onclick="showOSK()">Toggle</button>
|
||||
</div>
|
||||
<div class="touch disabled">
|
||||
Disabled (touch-based)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="inline-mode" class="flex panel inactive">
|
||||
<div class="group">
|
||||
<p class="category">OSK Sizing</p>
|
||||
<div>Width: <span class='gap'></span><input id="set-width" value='800'/></div>
|
||||
<div>Height: <span class='gap'></span><input id="set-height" value='400'/></div>
|
||||
<button onclick="inlineSetSize()" style="width:100%; margin-top: 4px;">Apply</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div id="inline-container" style="width: 80%; height: 40%"></div>
|
||||
|
||||
<p>Textbox target:</p>
|
||||
<textarea id='ta1' class='test'></textarea>
|
||||
|
||||
<p>Input target:</p>
|
||||
<input id='in1' class='test' value=''/>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h3>Event log:</h3>
|
||||
<textarea id="eventlog" rows="10" readonly></textarea>
|
||||
|
||||
<button onclick="document.getElementById('eventlog').textContent = '';">Clear</button>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h3><a href="../..">Return to testing home page</a></h3>
|
||||
|
||||
<!-- include a blank div to enable scrolling -->
|
||||
<div style="height:1000px"></div>
|
||||
<p>--End of Document--</p>
|
||||
|
||||
</body>
|
||||
|
||||
<!--
|
||||
*** DEVELOPER NOTE -- FIREFOX CONFIGURATION FOR TESTING ***
|
||||
*
|
||||
* If the URL bar starts with <b>file://</b>, Firefox may not load the font used
|
||||
* to display the special characters used in the On-Screen Keyboard.
|
||||
*
|
||||
* To work around this Firefox bug, navigate to <b>about:config</b>
|
||||
* and set <b>security.fileuri.strict_origin_policy</b> to <b>false</b>
|
||||
* while testing.
|
||||
*
|
||||
* Firefox resolves website-based CSS URI references correctly without needing
|
||||
* any configuration change, so this change should only be made for file-based testing.
|
||||
*
|
||||
***
|
||||
-->
|
||||
</html>
|
||||
46
web/src/test/manual/web/osk/scratchspace/setup.mjs
Normal file
46
web/src/test/manual/web/osk/scratchspace/setup.mjs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import * as KeymanOSK from '../../../../../../build/engine/osk/lib/index.mjs';
|
||||
import Device from '../../../../../../build/engine/device-detect/lib/index.mjs';
|
||||
import { loadKeyboardFromPath, loadKeyboardsFromStubs } from '../kbdLoader.mjs';
|
||||
|
||||
// NOTE: we must actually set these in this manner to have accessibility outside of
|
||||
// this script tag!
|
||||
window.modules = {
|
||||
osk: KeymanOSK,
|
||||
device: Device
|
||||
};
|
||||
|
||||
let prefix = '../../';
|
||||
const stubs = [
|
||||
{id:'us',name:'English',languages:{id:'en',name:'English'}, filename:(prefix + 'us-1.0.js')},
|
||||
{id:'obolo_chwerty_6351',name:'obolo_chwerty_6351',languages:{id:'en',name:'English'},
|
||||
filename:(prefix + 'obolo_chwerty_6351.js')},
|
||||
{id:'lao_2008_basic',name:'Lao Basic', languages: {id:'lo',name:'Lao',region:'Asia'},
|
||||
filename:(prefix + 'lao_2008_basic-1.2.js')}
|
||||
]
|
||||
|
||||
window.keyboards = loadKeyboardsFromStubs(stubs).then((keyboards) => {
|
||||
window.keyboards = keyboards;
|
||||
});
|
||||
|
||||
let device = new Device();
|
||||
device.detect();
|
||||
|
||||
if(device.formFactor == 'phone') {
|
||||
document.body.classList.add('phone');
|
||||
}
|
||||
|
||||
if(device.touchable) {
|
||||
document.body.classList.add('touch');
|
||||
}
|
||||
|
||||
window.HOST_DEVICE = device.coreSpec;
|
||||
window.targetDevice = new modules.osk.DeviceSpec('safari', 'phone', 'ios', true);
|
||||
|
||||
window.BaseConfiguration = {
|
||||
isEmbedded: false,
|
||||
fontRootPath: '',
|
||||
// Relative path to the resources' original versions.
|
||||
commonStyleSheetRefs: ['../../../../../resources/osk/kmwosk.css', '../../../../../resources/osk/globe-hint.css']
|
||||
};
|
||||
|
||||
window.keyboardLoader = loadKeyboardFromPath;
|
||||
Loading…
Add table
Reference in a new issue