if( !localStorage.getItem( "kit-appdir" ) ) localStorage.setItem( "kit-appdir", "./app/" );
S.appdir = localStorage.getItem( "kit-appdir" );
- if( localStorage.getItem( "kit-installed" ) ) System.installed = JSON.parse( localStorage.getItem( "kit-installed" ) );
+ if( localStorage.getItem('kit-installed') ) System.installed = JSON.parse( localStorage.getItem('kit-installed') );
+
+ if( localStorage.getItem('kit-screentime') ) KWS.screenTime = JSON.parse( localStorage.getItem('kit-screentime') );
if( localStorage["kit-userarea"] ) System.userarea = JSON.parse(localStorage["kit-userarea"]);
if( localStorage["kit-recycle"] ) System.recycle = JSON.parse(localStorage["kit-recycle"]);
else clockmove = setInterval( System.clock, 10 );
if ( localStorage.getItem("kit-shutted-down") == "false" ) {
- Notification.push( "お知らせ", "kitは前回終了時、正しくシャットダウンされませんでした。", "system" );
+ Notification.push("お知らせ", "kitは前回終了時、正しくシャットダウンされませんでした。", "system");
}
localStorage.setItem("kit-shutted-down", false);
- Notification.push( "kitへようこそ", localStorage["kit-username"] + "さん、こんにちは。", "system", null, null, 'documents/icon.png', [
+ Notification.push("kitへようこそ", localStorage["kit-username"] + "さん、こんにちは。", "system", null, null, 'documents/icon.png', [
{
label: 'kitについて',
func: () => System.launch( 'settings', {'view': 'about'} )
try{
$.getJSON( S.launchpath[_pid] + '/define.json', appData ).fail( () => {
Notification.push('kitアプリをロードできません。', `${str}を展開できませんでした。`, 'system');
+ System.launchLock = false;
+ pid++;
} );
}
catch(error){
Notification.push( "System Error", error, "system" );
+ System.launchLock = false;
}
}
}
-async function appData( data ) {
+async function appData(data) {
+ let _support = {
+ fullscreen: false,
+ resize: false,
+ darkmode: false,
+ kaf: true,
+ multiple: true
+ }, _size = {}, _resize = false;
+ if (data.support) _support = {
+ fullscreen: typeof data.support.fullscreen == "undefined" ? false : data.support.fullscreen,
+ resize: typeof data.support.resize == "undefined" ? false : data.support.resize,
+ darkmode: typeof data.support.darkmode == "undefined" ? false : data.support.darkmode,
+ kaf: typeof data.support.kaf == "undefined" ? true : data.support.kaf,
+ multiple: typeof data.support.multiple == "undefined" ? true : data.support.multiple
+ }
+ if (data.size) _size = {
+ width: data.size.width || 'auto',
+ height: data.size.height || 'auto'
+ };
+ if (data.resize) _resize = data.resize;
+ const defobj = {
+ id: data.id || null,
+ name: data.name || 'アプリ名なし',
+ icon: data.icon || 'none',
+ version: data.version || null,
+ author: data.author || null,
+ support: _support,
+ size: _size,
+ resize: _resize,
+ view: data.view || 'default.html',
+ script: data.script || 'none',
+ css: data.css || 'none'
+ }
+ if (!data.id || !data.version || !data.author) {
+ Notification.push('起動エラー', '起動に失敗しました。詳細情報を得るためには、デバッグモードを有効化してください。', 'system');
+ Notification.push('debug', '起動エラー:id, version, authorは必須定義項目です。', 'system');
+ System.launchLock = false;
+ return;
+ }
+ if (defobj.support.multiple == false) {
+ if (Object.values(process).map(p => p.id).includes(defobj.id)) {
+ Notification.push('多重起動エラー', `アプリケーション「${defobj.name}」の多重起動は許可されていません。`, 'system');
+ System.launchLock = false;
+ return;
+ }
+ }
let _pid = pid;
- process[String( _pid )] = {
- id: data.id,
+ process[String(_pid)] = {
+ id: defobj.id,
time: System.time.obj.toLocaleString(),
isactive: false,
preventclose: false,
- title: data.name
+ title: defobj.name
};
System.appCache[System.launchpath[pid]] = data;
app = new App(_pid);
let _taskAppend = `<span id='t${_pid}'>`;
- if( data.icon && data.icon != "none" ) _taskAppend += `<img src='${S.launchpath[_pid]}/${data.icon}'>`;
- _taskAppend += `<span id='tname${_pid}'>${data.name}<span></span>`;
- $( "#tasks" ).append( _taskAppend );
- $( "#t" + _pid ).addClass( "task" ).on({
+ const _iconPath = app.getPath(defobj.icon).toString();
+ const _viewPath = app.getPath(defobj.view).toString();
+ if(defobj.icon != 'none') _taskAppend += `<img src='${_iconPath}'>`;
+ _taskAppend += `<span id='tname${_pid}'>${defobj.name}<span></span>`;
+ $("#tasks").append(_taskAppend);
+ $("#t" + _pid).addClass("task").on({
click: function() {
- if( $(this).hasClass("t-active") || $(this).hasClass("task-min") ) KWS.min( _pid );
- else{
+ if ( process[_pid].isactive || $(this).hasClass("task-min") ) KWS.min(_pid);
+ else {
$("#w"+_pid).css("z-index", KWS.windowIndex + 1);
KWS.refreshWindowIndex();
}
},
mouseenter: function() {
- $( "#task-ctx-name" ).text( data.name );
- if( data.icon && data.icon != "none" ) $( "#task-ctx-img" ).attr( "src", System.launchpath[_pid] + "/" + data.icon );
- else $( "#task-ctx-img" ).hide();
- $( "#task-ctx-ver" ).text( data.version + "/pid:" + _pid );
- $( "#task-ctx-info" ).off().on( "click", function() { System.appInfo( _pid )} );
- $( "#task-ctx-sshot" ).off().on( "click", function() { S.screenshot(_pid, true) } );
- $( "#task-ctx-min" ).off().on( "click", function() { KWS.min( String(_pid) ) } );
- if( $(this).hasClass("t-active") ) $( "#task-ctx-front" ).hide();
- else $( "#task-ctx-front" ).show();
- $( "#task-ctx-front" ).off().on( "click", function() {
- $("#w"+_pid).css("z-index", KWS.windowIndex + 1);
+ $("#task-ctx-name").text(defobj.name);
+ if(defobj.icon != "none") $("#task-ctx-img").show().attr("src", _iconPath);
+ else $("#task-ctx-img").hide();
+ $("#task-ctx-ver").text(`v${defobj.version} pid${_pid}`);
+ $("#task-ctx-info").off().on("click", function() { System.appInfo(_pid)});
+ $("#task-ctx-sshot").off().on("click", function() { System.screenshot(_pid, true) });
+ $("#task-ctx-min").off().on("click", function() { KWS.min(String(_pid)) });
+ if($(this).hasClass('t-active')) $('#task-ctx-front').hide();
+ else $('#task-ctx-front').show();
+ $("#task-ctx-front").off().on('click', function() {
+ $("#w"+_pid).css("z-index", KWS.windowIndex+1);
KWS.refreshWindowIndex();
- } );
- $( "#task-ctx-close" ).off().on("click", () => System.close(_pid));
- $( "#task-ctx-kill" ).off().on("click", () => System.kill( data.id));
+ });
+ $("#task-ctx-close").off().on("click", () => System.close(_pid));
+ $("#task-ctx-kill").off().on("click", () => System.kill(defobj.id));
const _ctxleft = $(this).offset().left, _ctxtop = window.innerHeight - $(this).offset().top;
- if( _ctxleft != $( "#task-ctx" ).offset().left ) $( "#task-ctx" ).hide();
- $( "#task-ctx" ).css( "left", _ctxleft ).css( "bottom", _ctxtop ).show();
+ if( _ctxleft != $("#task-ctx").offset().left ) $("#task-ctx").hide();
+ $("#task-ctx").css("left", _ctxleft).css("bottom", _ctxtop).show();
}
} );
- $( "section, #kit-tasks" ).on( "mouseenter", function() {
- $( "#task-ctx" ).fadeOut( 200 );
- } );
- $( "#t" + _pid ).on({
+ $("section, #kit-tasks").on('mouseenter', function() { $('#task-ctx').fadeOut(200) });
+ $("#t" + _pid).on({
mouseenter: () => {
- prevWindowIndex = $( "#w" + _pid ).css( "z-index" );
- $( "#w" + _pid ).addClass( "win-highlight" );
+ prevWindowIndex = $("#w" + _pid).css('z-index');
+ $("#w" + _pid).addClass('win-highlight');
},
- mouseleave: () => $( "#w" + _pid ).removeClass( "win-highlight" )
+ mouseleave: () => $("#w" + _pid).removeClass('win-highlight')
});
-
let _windowAppend = "<div id='w" + _pid + "'><div id='wt" + _pid + "' class='wt'><i class='wmzx'><span id='wm" + _pid + "'></span>";
- if( data.support && data.support['fullscreen'] == true ) _windowAppend += "<span id='wz" + _pid + "'></span>";
+ if( defobj.support.fullscreen == true ) _windowAppend += "<span id='wz" + _pid + "'></span>";
_windowAppend += "<span id='wx" + _pid + "'></span></i>";
- if( data.icon && data.icon != "none" ) _windowAppend += "<img src='" + S.launchpath[_pid] + "/" + data.icon + "'>";
- _windowAppend += "<span id='wtname" + _pid + "'>" + data.name + "</span></div><div class='winc winc-" + data.id + "' id='winc" + _pid + "'></div></div>";
- $( "#desktop-" + currentDesktop ).append( _windowAppend );
+ if( defobj.icon != "none" ) _windowAppend += "<img src='" + _iconPath + "'>";
+ _windowAppend += "<span id='wtname" + _pid + "'>" + defobj.name + "</span></div><div class='winc winc-" + defobj.id + "' id='winc" + _pid + "'></div></div>";
+ $("#desktop-" + currentDesktop).append(_windowAppend);
- if( data.support && data.support['darkmode'] == true ) $("#winc"+_pid).addClass("winc-darkmode");
+ if( defobj.support.darkmode == true ) $("#winc"+_pid).addClass('winc-darkmode');
if( KWS.darkmode ) $("#winc"+_pid).addClass("kit-darkmode");
-
- if( data.size ){
- $("#winc"+_pid).css("width", data.size.width).css("height", data.size.height);
- }
- if( data.resize ){
- let _minwidth = 200, _minheight = 40;
- if( data.resize.minWidth ) _minwidth = data.resize.minWidth;
- if( data.resize.minHeight ) _minheight = data.resize.minHeight;
+
+ $("#winc"+_pid).css("width", defobj.size.width).css("height", defobj.size.height);
+ if( defobj.resize ){
+ let _minwidth = defobj.resize.minWidth ? defobj.resize.minWidth : 200;
+ let _minheight = defobj.resize.minHeight ? defobj.resize.minHeight : 40;
$("#winc"+_pid).windowResizable({
minWidth: _minwidth,
minHeight: _minheight
KWS.refreshWindowIndex();
} ).css( "left", windowPos + "px" ).css( "top", windowPos + "px" ).css( "z-index", KWS.windowIndex );
KWS.refreshWindowIndex();
- $( `#wm${_pid}` ).addClass( "wm fa fa-window-minimize" ).on("click", () => KWS.min( _pid ) );
- $( `#wz${_pid}` ).addClass( "wz fas fa-square" ).on("click", () => KWS.max( _pid ) );
- $( `#wx${_pid}` ).addClass( "wx fa fa-times" ).on("click", () => System.close( _pid ) );
- $( "#winc" + _pid ).resizable( {
- minWidth: "200"
- } ).load( System.launchpath[_pid] + "/" + data.view, (r, s, x) => {
- if( s == "error" ){
- Notification.push("起動に失敗:" + x.status, x.statusText);
+ if(defobj.support.fullscreen == true) $(`#wt${_pid}`).on("dblclick", () => KWS.max(_pid));
+ $( `#wm${_pid}` ).addClass("wm fa fa-window-minimize").on("click", () => KWS.min( _pid ));
+ $( `#wz${_pid}` ).addClass("wz fas fa-square").on("click", () => KWS.max( _pid ));
+ $( `#wx${_pid}` ).addClass("wx fa fa-times").on("click", () => System.close( _pid ));
+ $( "#winc" + _pid ).resizable().load(app.getPath(defobj.view), (r, s, x) => {
+ if(s == "error"){
+ Notification.push("起動に失敗しました " + x.status, 'テンプレートにアクセスできません。' + x.statusText, 'system');
+ System.launchLock = false;
+ pid++;
return false;
}
- if( !data.script || data.script != "none" ) $.getScript( System.launchpath[_pid] + "/" + data.script, () => {
- if( !data.support || data.support['kaf'] != false ) App.kaf(_pid);
- pid++;
- }).fail( () => {
- App.kaf(_pid);
+ if( defobj.css != "none" && !document.querySelector(`#kit-style-${defobj.id}`) ){
+ $("head").append('<link href="' + app.getPath(defobj.css) + '" rel="stylesheet" id="kit-style-' + data.id + '"></link>');
+ }
+ if(defobj.script != "none") $.getScript(app.getPath(defobj.script), () => {
+ if( defobj.support.kaf == true ) App.kaf(_pid);
pid++;
+ }).fail(() => {
+ if( defobj.support.kaf == true ) App.kaf(_pid)
+ pid ++;
});
- else if( !data.support || data.support['kaf'] != false ){
+ else if( defobj.support.kaf == true ){
App.kaf(_pid);
pid++;
}
else pid++;
- if( data.css != "none" && $("#kit-style-"+data.id).length == 0 ){
- $( "head" ).append( '<link href="' + System.launchpath[_pid] + '/' + data.css + '" rel="stylesheet" id="kit-style-' + data.id + '"></link>' );
- }
localStorage.setItem( "kit-pid", pid );
System.launchLock = false;
- } );
+ });
}
const System = new function() {
this.noop = () => {}
this.launchLock = false;
-
- this.waitLaunchUnlock = (callback) => {
- setTimeout(()=>{
- if(this.ajaxLock){
- this.waitLaunchUnlock(callback);
- }else{
- return callback();
- }
- }, 100)
- }
this.ajaxWait = () =>{
return new Promise(resolve =>{
- System.waitLaunchUnlock(resolve);
+ let interval = setInterval(()=>{
+ if(this.launchLock === false) {
+ clearInterval(interval);
+ resolve();
+ }
+ }, 100)
});
}
try{
$.getJSON( _path + '/define.json', appData ).fail( () => {
Notification.push('kitアプリをロードできません。', `${_path}を展開できませんでした。`, 'system');
+ System.launchLock = false;
} );
}
catch(error){
Notification.push( "System Error", error, "system" );
+ System.launchLock = false;
}
}
}
}
const KWS = new function(){
- this.version = "3.2.2";
+ this.version = "3.2.3";
this.active = null;
this.darkmode = false;
}
this.max = function( _pid ){
- if( KWS.fullscreen.pid ){
- Notification.push("最大化に失敗", "最大化しているウィンドウがあります。");
+ let _appcache = System.appCache[System.launchpath[_pid]];
+ if( KWS.fullscreen.pid || _appcache.support.fullscreen != true ){
+ Notification.push('最大化に失敗', 'ウィンドウの最大化に失敗しました。', 'system');
return;
}
+ KWS.fullscreen.prevWidth = $("#winc"+_pid).outerWidth();
+ KWS.fullscreen.prevHeight = $("#winc"+_pid).outerHeight();
+ KWS.fullscreen.prevTop = $("#w"+_pid).offset().top;
+ KWS.fullscreen.prevLeft = $("#w"+_pid).offset().left;
+ KWS.fullscreen.pid = _pid;
$( "#wt"+_pid ).addClass("wtmaximize");
$( "#w"+_pid ).css({
"top": "0px",
.addClass("windowmaximize")
.css("z-index", KWS.windowIndex + 1);
KWS.refreshWindowIndex();
-
- KWS.fullscreen.prevWidth = $("#winc"+_pid).outerWidth();
- KWS.fullscreen.prevHeight = $("#winc"+_pid).outerHeight();
- KWS.fullscreen.prevTop = $("#w"+_pid).offset().top;
- KWS.fullscreen.prevLeft = $("#w"+_pid).offset().left;
-
KWS.resize( _pid, System.display.width, System.display.height - 30 );
$("footer").hide();
- $("#kit-header-fullscreen").show().on("click", () => {
- KWS.unmax( _pid );
- });
- KWS.fullscreen.pid = _pid;
+ $("#kit-header-fullscreen").show().on('click', () => KWS.unmax( _pid ));
}
this.unmax = function( _pid ){
Notification.push("最大化解除に失敗", "対象がフルスクリーンウィンドウではありません。");
return;
}
- $( "#wt"+_pid ).removeClass("wtmaximize");
- $( "#w"+_pid ).css({
+ $('#wt'+_pid).removeClass("wtmaximize");
+ $('#w'+_pid).css({
"top": KWS.fullscreen.prevTop,
"left": KWS.fullscreen.prevLeft
})
KWS.fullscreen.prevHeight = null;
KWS.fullscreen.prevTop = null;
KWS.fullscreen.prevLeft = null;
+
+ if( !System.appCache[System.launchpath[_pid]].size.height ) {
+ System.qs(_pid)[0].style.height = "auto";
+ }
}
this.vacuum = function( _left, _top ){
} );
for( let i in array ){
document.getElementById(array[i].id).style.zIndex = i;
+ let _pid = String(array[i].id).substring(1);
if( i == num-1 ){
$("#"+array[i].id).addClass("windowactive");
- $("#t"+String(array[i].id).substring(1)).addClass("t-active");
- KWS.active = String(array[i].id).substring(1);
- process[array[i].id.substring(1)].isactive = true;
+ $("#t"+_pid).addClass("t-active");
+ KWS.active = _pid;
+ process[_pid].isactive = true;
+ KWS.screenPrevSwitched = new Date();
+ localStorage.setItem('kit-screentime', JSON.stringify(KWS.screenTime));
}
else{
$("#"+array[i].id).removeClass("windowactive");
- $("#t"+String(array[i].id).substring(1)).removeClass("t-active");
- process[array[i].id.substring(1)].isactive = false;
+ $("#t"+_pid).removeClass("t-active");
+ process[_pid].isactive = false;
+ if( KWS.active == _pid ){
+ let _diff = (new Date() - KWS.screenPrevSwitched);
+ let _appid = process[_pid].id
+ if( !KWS.screenTime[_appid] ) KWS.screenTime[_appid] = new Number();
+ if( _diff < 0 ) Notification.push('debug', 'スクリーンタイムの記録に失敗しました。', 'system')
+ else KWS.screenTime[_appid] += _diff;
+ }
}
}
KWS.windowIndex = num;
if( _height ) $("#winc"+_pid).css("height", _height);
}
+ this.setTheme = function(_name){
+ localStorage.setItem('kit-theme', _name);
+ if(_name != 'none') $('#kit-theme-file').attr('href', `./system/theme/${localStorage.getItem('kit-theme')}`);
+ else $('#kit-theme-file').attr('href', '');
+ System.moveDesktop(currentDesktop);
+ }
+
+ this.screenTime = new Object();
+
+ this.screenPrevSwitched = new Date();
+
this.fusen = new function(){
this.fid = 0;
this.list = new Object();
}
})
$(".kit-fusen-textarea").off().on("change",function(){
- Notification.push($(this).attr("data-fid"), $(this).val(), "debug");
KWS.fusen.list[$(this).attr("data-fid")] = $(this).val();
localStorage.setItem("kit-fusen", JSON.stringify( KWS.fusen.list ));
});
if( _value !== undefined ) {
S.dom(_pid, `[kit\\:bind=${_name}]`).val( _value );
S.dom(_pid, `[kit\\:observe=${_name}]`).text( _value );
- if( _value ) S.dom(_pid, `[kit\\:if=${_name}]`).show();
- else S.dom(_pid, `[kit\\:if=${_name}]`).hide();
+ S.dom(_pid, `template[kit\\:for=${_name}] + kit-for`).text('');
+ if (typeof _value == 'object'){
+ for(let elem of S.qs(_pid, `template[kit\\:for=${_name}] + kit-for`)){
+ let _rep = App.d[_pid][`__kaf_node_id_${elem.getAttribute('kaf-node-id')}`], _result = '';
+ for(let i in _value) {
+ _result += _rep.replace(/{{\s*key\s*}}/g, i).replace(/{{\s*value\s*}}/g, _value[i]);
+ }
+ elem.innerHTML = _result;
+ }
+ }
+ if( _value ) {
+ S.dom(_pid, `[kit\\:if=${_name}]`).show();
+ S.dom(_pid, `[kit\\:disabled=${_name}]`).prop('disabled', true);
+ }
+ else{
+ S.dom(_pid, `[kit\\:if=${_name}]`).hide();
+ S.dom(_pid, `[kit\\:disabled=${_name}]`).prop('disabled', false).removeClass('-disabled');
+ }
return App.d[_pid][_name] = _value;
}
else if( _name ) return App.d[_pid][_name];
- else return App.d[_pid];
+ else return Object.fromEntries( Object.entries(App.d[_pid] || {}).filter(d => d[0].indexOf("__") != 0) );
}
static event( _pid, _name, _event ) {
if( !App.e[_pid] ) App.e[_pid] = new Object();
- App.e[_pid][_name] = _event;
+ if( !_event && App.e[_pid][_name] ) App.e[_pid][_name].call();
+ else App.e[_pid][_name] = _event;
return App;
}
"[kit-value]",
"[kit-color]",
"[kit\\:if]",
- "[kit-if]"
+ "[kit-if]",
+ "[kit\\:for]"
]
const PID = _pid;
const DATA = App.data(_pid);
const ARGS = System.args[_pid];
+ let _kaf_node_id = 0;
for( let i of S.qs(_pid, ...attrs) ){
if( i.hasAttribute("kit-ref") ){
$(i).on("click", () => App.load(_pid, i.getAttribute("kit-ref")) );
let _eqs = i.getAttribute("kit-e").split(",");
for( let k of _eqs ){
let _eq = k.split(" ");
- $(i).on( _eq[1]||"click", App.e[_pid][_eq[0]] );
+ $(i).on( _eq[1]||'click', (e) => {
+ if(e.target.classList.contains('-disabled') === false) App.e[_pid][_eq[0]]();
+ } );
}
}
if( i.hasAttribute("kit-src") ){
let _name = i.getAttribute("kit:bind");
App.d[_pid][_name] = i.value;
S.dom(_pid, `[kit\\:observe=${_name}]`).text( i.value );
- if( i.value ) S.dom(_pid, `[kit\\:if=${_name}]`).show();
- else S.dom(_pid, `[kit\\:if=${_name}]`).hide();
+ if( i.value ){
+ S.dom(_pid, `[kit\\:if=${_name}]`).show();
+ S.dom(_pid, `[kit\\:disabled=${_name}]`).prop('disabled', true).addClass('-disabled');
+ }
+ else{
+ S.dom(_pid, `[kit\\:if=${_name}]`).hide();
+ S.dom(_pid, `[kit\\:disabled=${_name}]`).prop('disabled', false).removeClass('-disabled');
+ }
} );
}
if( i.hasAttribute("kit:observe") ){
}
else $(i).hide();
}
+ if( i.hasAttribute("kit:disabled") ){
+ if( App.d[_pid][i.getAttribute("kit:if")] ){
+ i.disabled = true;
+ i.classList.add('-disabled');
+ }
+ else i.disabled = false;
+ }
if( i.hasAttribute("kit-if") ){
if( eval( i.getAttribute("kit-if")) ){
$(i).show();
}
else $(i).hide();
}
+ if( i.hasAttribute("kit:for") ){
+ if ('content' in document.createElement('template')) {
+ i.setAttribute('kaf-node-id', _kaf_node_id);
+ App.d[_pid][`__kaf_node_id_${_kaf_node_id}`] = i.innerHTML;
+ i.insertAdjacentHTML('afterend', `<kit-for kaf-node-id="${_kaf_node_id}"></kit-for>`);
+ }
+ else i.style.display = 'none';
+ }
+ _kaf_node_id ++;
}
}
_path = System.launchpath[_pid] + _path;
S.dom(_pid).load( _path, () => {
App.kaf(_pid);
+ let _appcache = System.appCache[System.launchpath[_pid]];
+ if( !KWS.fullscreen.pid && !_appcache.size.height ) {
+ System.qs(_pid)[0].style.height = "auto";
+ }
} );
return App;
}