VulpesOS/assets/webapps/settings.gaiamobile.org/shared/js/keyboard_helper.js
OverSu b38dea0597 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.
2026-09-30 23:13:03 +02:00

53 lines
No EOL
13 KiB
JavaScript

(function(exports){var BASE_TYPES=new Set(['text','url','email','password','number','option']);var SETTINGS_KEYS={ENABLED:'keyboard.enabled-layouts',DEFAULT:'keyboard.default-layouts'};var DEPRECATE_KEYBOARD_SETTINGS={en:'keyboard.layouts.english','en-Dvorak':'keyboard.layouts.dvorak',cs:'keyboard.layouts.czech',fr:'keyboard.layouts.french',de:'keyboard.layouts.german',hu:'keyboard.layouts.hungarian',nb:'keyboard.layouts.norwegian',my:'keyboard.layouts.myanmar',sl:'keyboard.layouts.slovak',tr:'keyboard.layouts.turkish',ro:'keyboard.layouts.romanian',ru:'keyboard.layouts.russian',ar:'keyboard.layouts.arabic',he:'keyboard.layouts.hebrew','zh-Hant-Zhuyin':'keyboard.layouts.zhuyin','zh-Hans-Pinyin':'keyboard.layouts.pinyin',el:'keyboard.layouts.greek','jp-kanji':'keyboard.layouts.japanese',pl:'keyboard.layouts.polish','pt-BR':'keyboard.layouts.portuguese',sr:'keyboard.layouts.serbian',es:'keyboard.layouts.spanish',ca:'keyboard.layouts.catalan'};var MULTI_LAYOUT_MAP={sr:['sr-Cyrl','sr-Latn']};var defaultKeyboardManifestURL='app://keyboard.gaiamobile.org/manifest.webapp';var currentSettings={defaultLayouts:{}};currentSettings.defaultLayouts[defaultKeyboardManifestURL]={en:true,number:true};currentSettings.enabledLayouts=map2dClone(currentSettings.defaultLayouts);function map2dIs(manifestURL,layoutId){return!!(this[manifestURL]&&this[manifestURL][layoutId]);}
function map2dSet(manifestURL,layoutId){if(!this[manifestURL]){this[manifestURL]={};}
this[manifestURL][layoutId]=true;}
function map2dUnset(manifestURL,layoutId){if(!this[manifestURL]){return;}
delete this[manifestURL][layoutId];if(!Object.keys(this[manifestURL]).length){delete this[manifestURL];}}
function map2dClone(obj){var result={};for(var key1 in obj){result[key1]={};for(var key2 in obj[key1]){result[key1][key2]=obj[key1][key2];}}
return result;}
var watchQueries=[];var defaultLayoutConfig;function kh_updateWatchers(reason){if(watchQueries.length){KeyboardHelper.getApps(function withApps(){watchQueries.forEach(function eachWatchQuery(watch){KeyboardHelper.getLayouts(watch.query,function withLayouts(layouts){watch.callback(layouts,reason);});});});}}
var waitingForSettings=[];var loadedSettings=new Set();function kh_loadedSetting(setting){loadedSettings.add(setting);if(loadedSettings.size>=Object.keys(SETTINGS_KEYS).length){waitingForSettings.forEach(function(callback){callback();});waitingForSettings=[];kh_updateWatchers({settings:true});}}
function kh_withSettings(callback){if(loadedSettings.size>=Object.keys(SETTINGS_KEYS).length){callback();}else{waitingForSettings.push(callback);}}
function kh_getSettings(){loadedSettings=new Set();var lock=window.navigator.mozSettings.createLock();lock.get(SETTINGS_KEYS.DEFAULT).onsuccess=kh_parseDefault;lock.get(SETTINGS_KEYS.ENABLED).onsuccess=kh_parseEnabled;}
function kh_parseDefault(){var value=this.result[SETTINGS_KEYS.DEFAULT];if(value){currentSettings.defaultLayouts=value;}
kh_loadedSetting(SETTINGS_KEYS.DEFAULT);}
function kh_parseEnabled(){var value=this.result[SETTINGS_KEYS.ENABLED];var needsSave=false;if(!value){currentSettings.enabledLayouts=map2dClone(currentSettings.defaultLayouts);needsSave=true;}else{var type=typeof value;if(type==='string'){try{currentSettings.enabledLayouts={};var oldSettings=JSON.parse(value);oldSettings.forEach(function(layout){if(layout.enabled){var manifestURL=layout.manifestURL;if(!manifestURL){manifestURL=layout.appOrigin+'/manifest.webapp';}
map2dSet.call(currentSettings.enabledLayouts,manifestURL,layout.layoutId);}});}catch(e){currentSettings.enabledLayouts=map2dClone(currentSettings.defaultLayouts);needsSave=true;}}else{currentSettings.enabledLayouts=value;}}
kh_loadedSetting(SETTINGS_KEYS.ENABLED);if(needsSave){KeyboardHelper.saveToSettings();}}
function kh_migrateDeprecatedSettings(deprecatedSettings){var settingEntry=DEPRECATE_KEYBOARD_SETTINGS.en;if(deprecatedSettings[settingEntry]===undefined){return;}
currentSettings.enabledLayouts[defaultKeyboardManifestURL]={number:true};var hasEnabledLayout=false;for(var key in DEPRECATE_KEYBOARD_SETTINGS){settingEntry=DEPRECATE_KEYBOARD_SETTINGS[key];if(deprecatedSettings[settingEntry]){hasEnabledLayout=true;if(key in MULTI_LAYOUT_MAP){MULTI_LAYOUT_MAP[key].forEach(function enableLayout(layoutId){map2dSet.call(currentSettings.enabledLayouts,defaultKeyboardManifestURL,layoutId);});}else{map2dSet.call(currentSettings.enabledLayouts,defaultKeyboardManifestURL,key);}}}
if(!hasEnabledLayout){map2dSet.call(currentSettings.enabledLayouts,defaultKeyboardManifestURL,'en');}
var deprecatedSettingsQuery={};for(key in DEPRECATE_KEYBOARD_SETTINGS){settingEntry=DEPRECATE_KEYBOARD_SETTINGS[key];deprecatedSettingsQuery[settingEntry]=null;}
window.navigator.mozSettings.createLock().set(deprecatedSettingsQuery);KeyboardHelper.saveToSettings();}
function kh_loadJSON(href,callback){if(!callback){return;}
var xhr=new XMLHttpRequest();xhr.onerror=function(){console.error('Failed to fetch file: '+href,xhr.statusText);};xhr.onload=function(){callback(xhr.response);};xhr.open('GET',href,true);xhr.responseType='json';xhr.send();}
function kh_getMultiSettings(settings,callback){var results={};try{var lock=navigator.mozSettings.createLock();}
catch(e){console.warn('Exception in mozSettings.createLock():',e,'\nUsing default values');for(var p in settings){results[p]=settings[p];}
callback(results);}
var settingNames=Object.keys(settings);var numSettings=settingNames.length;var numResults=0;for(var i=0;i<numSettings;i++){requestSetting(settingNames[i]);}
function requestSetting(name){var request;try{request=lock.get(name);}
catch(e){console.warn('Exception querying setting',name,':',e,'\nUsing default value');recordResult(name,settings[name]);return;}
request.onsuccess=function(){var value=request.result[name];if(value===undefined){value=settings[name];}
recordResult(name,value);};request.onerror=function(evt){console.warn('Error querying setting',name,':',evt.error);recordResult(name,settings[name]);};}
function recordResult(name,value){results[name]=value;numResults++;if(numResults===numSettings){callback(results);}}}
function KeyboardLayout(options){for(var key in options){this[key]=options[key];}}
Object.defineProperties(KeyboardLayout.prototype,{'default':{get:function kh_getLayoutIsDefault(){return map2dIs.call(currentSettings.defaultLayouts,this.app.manifestURL,this.layoutId);}},enabled:{get:function kh_getLayoutIsEnabled(){return map2dIs.call(currentSettings.enabledLayouts,this.app.manifestURL,this.layoutId);},set:function kh_setLayoutIsDefault(value){var method=value?map2dSet:map2dUnset;method.call(currentSettings.enabledLayouts,this.app.manifestURL,this.layoutId);}}});var kh_SettingsHelper={};Object.defineProperties(kh_SettingsHelper,{'default':{get:function(){return map2dClone(currentSettings.defaultLayouts);},set:function(value){currentSettings.defaultLayouts=map2dClone(value);},enumerable:true},'enabled':{get:function(){return map2dClone(currentSettings.enabledLayouts);},set:function(value){currentSettings.enabledLayouts=map2dClone(value);},enumerable:true}});var KeyboardHelper=exports.KeyboardHelper={settings:kh_SettingsHelper,fallbackLayoutNames:{password:'en'},fallbackLayouts:{},inputAppList:null,init:function kh_init(){watchQueries=[];this.inputAppList=new InputAppList();this.inputAppList.onupdate=kh_updateWatchers.bind(undefined,{apps:true});this.inputAppList.start();var settings=window.navigator.mozSettings;if(settings){kh_getSettings();settings.addObserver(SETTINGS_KEYS.ENABLED,kh_getSettings);settings.addObserver(SETTINGS_KEYS.DEFAULT,kh_getSettings);var deprecatedSettingsQuery={};for(var key in DEPRECATE_KEYBOARD_SETTINGS){var settingEntry=DEPRECATE_KEYBOARD_SETTINGS[key];deprecatedSettingsQuery[settingEntry]=undefined;}
kh_getMultiSettings(deprecatedSettingsQuery,kh_migrateDeprecatedSettings);}
window.addEventListener('applicationinstallsuccess',this);},handleEvent:function(event){kh_updateWatchers({apps:true});},isKeyboardType:function kh_isKeyboardType(type){return BASE_TYPES.has(type);},setLayoutEnabled:function kh_setLayoutEnabled(manifestURL,layoutId,enabled){var method=enabled?map2dSet:map2dUnset;method.call(currentSettings.enabledLayouts,manifestURL,layoutId);},getLayoutEnabled:function kh_getLayoutEnabled(manifestURL,layoutId){return map2dIs.call(currentSettings.enabledLayouts,manifestURL,layoutId);},setLayoutIsDefault:function kh_setLayoutIsDefault(manifestURL,layoutId,enabled){var method=enabled?map2dSet:map2dUnset;method.call(currentSettings.defaultLayouts,manifestURL,layoutId);},getLayoutIsDefault:function kh_getLayoutIsDefault(manifestURL,layoutId){return map2dIs.call(currentSettings.defaultLayouts,manifestURL,layoutId);},checkDefaults:function kh_checkDefaults(callback){var layoutsEnabled=[];var missingTypes=[];['text','url','number'].forEach(function eachType(type){var enabled;this.getLayouts({type:type,enabled:true},function(layouts){enabled=layouts.length;});if(!enabled){missingTypes.push(type);this.getLayouts({type:type,'default':true},function(layouts){if(layouts[0]){layouts[0].enabled=true;layoutsEnabled.push(layouts[0]);}});}},this);if(layoutsEnabled.length){if(callback){callback(layoutsEnabled,missingTypes);}}},saveToSettings:function ke_saveToSettings(){var toSet={};toSet[SETTINGS_KEYS.ENABLED]=currentSettings.enabledLayouts;toSet[SETTINGS_KEYS.DEFAULT]=currentSettings.defaultLayouts;window.navigator.mozSettings.createLock().set(toSet);},getApps:function kh_getApps(callback){var cleanupSettings=function(inputApps){Object.keys(currentSettings.enabledLayouts).concat(Object.keys(currentSettings.defaultLayouts)).forEach(function(manifestURL){if(!inputApps.some(function(inputApp){return(inputApp.domApp.manifestURL===manifestURL);})){delete currentSettings.enabledLayouts[manifestURL];delete currentSettings.defaultLayouts[manifestURL];}});};if(this.inputAppList.ready){var inputApps=this.inputAppList.getListSync();cleanupSettings(inputApps);callback(inputApps);return;}
this.inputAppList.getList().then(function(inputApps){cleanupSettings(inputApps);callback(inputApps);})['catch'](function(e){console.error(e);});},getLayouts:function kh_getLayouts(options,callback){if(typeof options==='function'){callback=options;options={};}
function withApps(inputApps){var fallbackLayoutNames={};for(var group in this.fallbackLayoutNames){fallbackLayoutNames[group]=this.fallbackLayoutNames[group];}
this.fallbackLayouts={};var layouts=inputApps.reduce(function eachApp(result,inputApp){var domApp=inputApp.domApp;var manifest=new ManifestHelper(domApp.manifest);var inputs=inputApp.getInputs();for(var layoutId in inputs){var inputManifest=inputs[layoutId];if(!inputManifest.types){console.warn(domApp.manifestURL,layoutId,'did not declare type.');continue;}
var layout=new KeyboardLayout({app:domApp,inputApp:inputApp,manifest:manifest,inputManifest:inputManifest,layoutId:layoutId});if(domApp.manifestURL===defaultKeyboardManifestURL){for(var group in fallbackLayoutNames){if(layoutId===fallbackLayoutNames[group]){this.fallbackLayouts[group]=layout;delete fallbackLayoutNames[group];}}}
if(options['default']&&!layout['default']){continue;}
if(options.enabled&&!layout.enabled){continue;}
if(options.type){options.type=[].concat(options.type);if(!options.type.some(function(type){return inputManifest.types.indexOf(type)!==-1;})){continue;}}
result.push(layout);}
if(options['default']){result.sort(function(a,b){return a.inputManifest.types.length-b.inputManifest.types.length;});}
return result;}.bind(this),[]);kh_withSettings(callback.bind(null,layouts));}
this.getApps(withApps.bind(this));},stopWatching:function(){watchQueries=[];},watchLayouts:function(query,callback){if(typeof query==='function'){callback=query;query={};}
var watch={query:query,callback:callback};watchQueries.push(watch);this.getLayouts(query,function initialCall(layouts){watch.layouts=layouts;callback(layouts,{apps:true,settings:true});});},getDefaultLayoutConfig:function kh_getDefaultLayoutConfig(callback){if(!callback){return;}
if(defaultLayoutConfig){callback(defaultLayoutConfig);}else{var KEYBOARDS='/shared/resources/keyboard_layouts.json';kh_loadJSON(KEYBOARDS,function loadKeyboardLayouts(data){if(data){defaultLayoutConfig=data;callback(defaultLayoutConfig);}});}},changeDefaultLayouts:function kh_changeDefaultLayouts(language,reset){this.getDefaultLayoutConfig(function gotDefaultLayouts(keyboards){var newKbLayouts=keyboards.layout[language];var kbManifestURL=defaultKeyboardManifestURL;currentSettings.defaultLayouts={};var langIndependentLayouts=keyboards.langIndependentLayouts;for(var i=langIndependentLayouts.length-1;i>=0;i--){this.setLayoutIsDefault(kbManifestURL,langIndependentLayouts[i].layoutId,true);}
if(reset){currentSettings.enabledLayouts=map2dClone(currentSettings.defaultLayouts);}
for(i=newKbLayouts.length-1;i>=0;i--){this.setLayoutIsDefault(kbManifestURL,newKbLayouts[i].layoutId,true);this.setLayoutEnabled(kbManifestURL,newKbLayouts[i].layoutId,true);}
this.saveToSettings();}.bind(this));}};KeyboardHelper.init();}(window));