Testing on older browsers and add polyfill; API continuation
This commit is contained in:
parent
7585f3fe14
commit
9e9464e297
|
@ -1 +1,4 @@
|
||||||
|
Build/*
|
||||||
Dist/*
|
Dist/*
|
||||||
|
node_modules/*
|
||||||
|
*.bak
|
||||||
|
|
|
@ -6,7 +6,7 @@ stages:
|
||||||
|
|
||||||
before_script: |
|
before_script: |
|
||||||
apk update
|
apk update
|
||||||
apk add python3
|
apk add python3 nodejs npm
|
||||||
|
|
||||||
sast:
|
sast:
|
||||||
stage: test
|
stage: test
|
||||||
|
@ -16,7 +16,8 @@ include:
|
||||||
pages:
|
pages:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
script: |
|
script: |
|
||||||
python3 ./Build.py
|
npm install . --save-dev
|
||||||
|
sh ./Build.sh
|
||||||
mv ./Dist ./public
|
mv ./Dist ./public
|
||||||
cp ./public/Friendiiverse.html ./public/index.html
|
cp ./public/Friendiiverse.html ./public/index.html
|
||||||
artifacts:
|
artifacts:
|
||||||
|
|
|
@ -22,11 +22,12 @@ var TransSchemas = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var ApiSchema = {
|
var ApiSchema = {
|
||||||
//__All__: {
|
__All__: {
|
||||||
// __Software__: {
|
ServerSoftware: { //TODO: Handle this in JsonTransform
|
||||||
// __EvalSet__: "TypeOld",
|
Mastodon: {__Set__: "Mastodon"},
|
||||||
// },
|
Misskey: {__Set__: "Misskey"},
|
||||||
//},
|
},
|
||||||
|
},
|
||||||
Note: {
|
Note: {
|
||||||
Content: {
|
Content: {
|
||||||
Mastodon: "content",
|
Mastodon: "content",
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<link rel="stylesheet" href="./Style.css"/>
|
<link rel="stylesheet" href="./Style.css"/>
|
||||||
|
<script folder="./Polyfill"></script>
|
||||||
<script>
|
<script>
|
||||||
// Credentials hardcoding for now
|
// Credentials hardcoding for now
|
||||||
var MastodonUrl = 'https://mastodon.social';
|
var MastodonUrl = 'https://mastodon.social';
|
||||||
|
@ -43,10 +44,10 @@ var Assets = {
|
||||||
<span>(Pre-Alpha Development Version)</span>
|
<span>(Pre-Alpha Development Version)</span>
|
||||||
</div>
|
</div>
|
||||||
<script>NoscriptView.remove();</script>
|
<script>NoscriptView.remove();</script>
|
||||||
<script folder="./Polyfill"></script>
|
|
||||||
<script src="./Lib/lodash.min.js"></script>
|
<script src="./Lib/lodash.min.js"></script>
|
||||||
<script src="./Lib/cleanHTML.js"></script>
|
<script src="./Lib/cleanHTML.js"></script>
|
||||||
<script src="./Utils.js"></script>
|
<script src="./Utils.js"></script>
|
||||||
|
<script src="./JsonTransform.js"></script>
|
||||||
<script src="./Strings.js"></script>
|
<script src="./Strings.js"></script>
|
||||||
<script src="./ApiTransform.js"></script>
|
<script src="./ApiTransform.js"></script>
|
||||||
<script src="./ApiStatic.js"></script>
|
<script src="./ApiStatic.js"></script>
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
// Transform JSON tree into a new using a template schema
|
||||||
|
// DEVNOTE: Unsafe, should check for colliding "__" keys from input tree and act accordingly
|
||||||
|
function JsonTransformA(TreesOld, SchemaCurr, SchemaRoot) {
|
||||||
|
if (Array.isArray(TreesOld)) {
|
||||||
|
var ListNew = [];
|
||||||
|
ForceList(TreesOld).forEach(function(TreeOld){
|
||||||
|
ListNew.push(JsonTransformCycleA(TreeOld, SchemaCurr, SchemaRoot));
|
||||||
|
});
|
||||||
|
return ListNew;
|
||||||
|
} else {
|
||||||
|
return JsonTransformCycleA(TreesOld, SchemaCurr, SchemaRoot);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function JsonTransformCycleA(TreeOld, SchemaCurr, SchemaRoot) {
|
||||||
|
var TreeNew = {};
|
||||||
|
Object.keys(TreeOld).forEach(function(KeyOld){
|
||||||
|
var Content = TreeOld[KeyOld];
|
||||||
|
var KeyNew = ((IsObj(SchemaCurr) && KeyOld in SchemaCurr) ? SchemaCurr[KeyOld] : KeyOld);
|
||||||
|
if (IsObj(Content) && Content !== null) {
|
||||||
|
if (Array.isArray(Content)) {
|
||||||
|
// Lists
|
||||||
|
/* var ListNew = [];
|
||||||
|
Content.forEach(function(Value){
|
||||||
|
ListNew.push(JsonTransform(Value, KeyNew));
|
||||||
|
});
|
||||||
|
TreeNew[KeyNew] = ListNew;*/
|
||||||
|
} else {
|
||||||
|
// Dicts
|
||||||
|
// Strange bug, in this context we can't assign new value to child of the object, we use a variable
|
||||||
|
NameKeyNew = KeyNew.__;
|
||||||
|
if (!NameKeyNew) {
|
||||||
|
NameKeyNew = KeyOld;
|
||||||
|
};
|
||||||
|
TreeNew[NameKeyNew] = JsonTransformA(Content, SchemaRoot[NameKeyNew], SchemaRoot);
|
||||||
|
if (NameKeyNew !== KeyOld) {
|
||||||
|
TreeNew[SchemaRoot[NameKeyNew].__] = TreeNew[NameKeyNew];
|
||||||
|
delete TreeNew[NameKeyNew];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// Values
|
||||||
|
TreeNew[KeyNew] = Content;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return TreeNew;
|
||||||
|
};
|
||||||
|
|
||||||
|
function JsonTransformB(TreesOld, SchemaNew, NodeNew, TypeOld) {
|
||||||
|
LogDebug([TreesOld, SchemaNew, NodeNew, TypeOld]);
|
||||||
|
if (Array.isArray(TreesOld)) {
|
||||||
|
// List of values
|
||||||
|
var ListNew = [];
|
||||||
|
ForceList(TreesOld).forEach(function(TreeOld){
|
||||||
|
ListNew.push(JsonTransformCycleB(TreeOld, SchemaNew, NodeNew, TypeOld));
|
||||||
|
});
|
||||||
|
return ListNew;
|
||||||
|
} else {
|
||||||
|
// Object
|
||||||
|
if (TreesOld) {
|
||||||
|
return JsonTransformCycleB(TreesOld, SchemaNew, NodeNew, TypeOld);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function JsonTransformCycleB(TreeOld, SchemaNew, NodeNew, TypeOld) {
|
||||||
|
var TreeNew = CopyObj(NodeNew);
|
||||||
|
if (SchemaNew.__All__) {
|
||||||
|
TreeNew.__All__ = CopyObj(SchemaNew.__All__);
|
||||||
|
};
|
||||||
|
_.forOwn(TreeNew, function(KeyNewVal, KeyNew){
|
||||||
|
if (KeyNewVal[TypeOld]) {
|
||||||
|
var KeyOld = KeyNewVal[TypeOld];
|
||||||
|
var ObjOld = TreeOld[KeyOld];
|
||||||
|
if (IsObj(KeyOld)) {
|
||||||
|
// Object in NodeNew / Deep nested children in TreeOld
|
||||||
|
_.forOwn(KeyOld, function(KeyObjVal, KeyObj){
|
||||||
|
//if (KeyObj === '__All__') { //NOTE: This must be handle as directly nested, not deep (how?)
|
||||||
|
// console.log('__All__')
|
||||||
|
// //TreeNew.__All__ = SchemaNew.__All__;
|
||||||
|
//};
|
||||||
|
if (KeyObj === '__Eval__') {
|
||||||
|
eval(KeyObjVal);
|
||||||
|
} else
|
||||||
|
if (KeyObj === '__EvalSet__') {
|
||||||
|
TreeNew[KeyNew] = eval(KeyObjVal);
|
||||||
|
} else
|
||||||
|
if (KeyObj === '__Set__') {
|
||||||
|
TreeNew[KeyNew] = KeyObjVal;
|
||||||
|
} else
|
||||||
|
if (KeyObj === '__OldOr__') {
|
||||||
|
var Keys = KeyObjVal;
|
||||||
|
for (var i=0; i<Keys.length; i++) {
|
||||||
|
var Key = TreeOld[Keys[i]];
|
||||||
|
if (Key !== undefined) {
|
||||||
|
TreeNew[KeyNew] = Key;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Value in NodeNew / Direct children in TreeOld
|
||||||
|
if (IsObj(ObjOld)) {
|
||||||
|
TreeNew[KeyNew] = JsonTransformB(ObjOld, SchemaNew, SchemaNew[KeyNew], TypeOld);
|
||||||
|
} else {
|
||||||
|
TreeNew[KeyNew] = ObjOld;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
TreeNew.__TreeOld__ = TreeOld;
|
||||||
|
return TreeNew;
|
||||||
|
};
|
41
App/Main.js
41
App/Main.js
|
@ -97,16 +97,16 @@ function TransNetCall(Data, FromSource, DestType, Proc) {
|
||||||
CallFine: function(Res){
|
CallFine: function(Res){
|
||||||
Res.responseJsonOld = Res.responseJson;
|
Res.responseJsonOld = Res.responseJson;
|
||||||
Res.responseJson = ApiTransform(Res.responseJson, FromSource, DestType);
|
Res.responseJson = ApiTransform(Res.responseJson, FromSource, DestType);
|
||||||
Res.response = Res.responseJson;
|
|
||||||
CallFun(Data.CallFineOld, Res);
|
CallFun(Data.CallFineOld, Res);
|
||||||
}, //CallFail: function(Res){ CallFun(Data.CallFail, Res); },
|
}, //CallFail: function(Res){ CallFun(Data.CallFail, Res); },
|
||||||
}), Proc);
|
}), Proc);
|
||||||
};
|
};
|
||||||
|
|
||||||
function DisplayProfile(Profile) {
|
function DisplayProfile(Profile) {
|
||||||
Profile = UrlObj(Profile);
|
Profile = UrlObj(Profile, DisplayProfile);
|
||||||
|
//if (Profile) {
|
||||||
var Window = MkWindow({className: "Profile"});
|
var Window = MkWindow({className: "Profile"});
|
||||||
Window.innerHTML += `<div class="" style="display: inline-block;">
|
Window.innerHTML += `<div class="Profile" style="display: inline-block;">
|
||||||
<a href="${Profile.Url}">
|
<a href="${Profile.Url}">
|
||||||
<div>
|
<div>
|
||||||
<img class="" src="${Profile.Banner}"/>
|
<img class="" src="${Profile.Banner}"/>
|
||||||
|
@ -119,27 +119,15 @@ function DisplayProfile(Profile) {
|
||||||
</div>`;
|
</div>`;
|
||||||
// TODO: Handle fetching notes of non-standard profiles like servers timelines
|
// TODO: Handle fetching notes of non-standard profiles like servers timelines
|
||||||
DoAsync(FetchNotes, FillTimeline, Profile);
|
DoAsync(FetchNotes, FillTimeline, Profile);
|
||||||
};
|
//};
|
||||||
|
|
||||||
function DisplayMastodonTimeline(Data) {
|
|
||||||
var Window = MkWindow();
|
|
||||||
Window.innerHTML += `<div class="" style="display: inline-block;">
|
|
||||||
<a href="${Profile.Url}">
|
|
||||||
<div>
|
|
||||||
<img class="" src="${Profile.Banner}"/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<img class="" src="${Profile.Icon}"/>
|
|
||||||
${Profile.Name}
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>`;
|
|
||||||
DoAsync(FetchNotes, FillTimeline, Profile);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function FetchNotes(Profile, Proc) {
|
function FetchNotes(Profile, Proc) {
|
||||||
var Soft = Profile.__Software__;
|
var Soft = Profile.ServerSoftware;
|
||||||
NetCall({Target: UrlBase(Profile.Url), Method: ApiEndpoints.FetchNotes['Mastodon'](Profile), CallFine: function(Res){
|
var Method = Profile.Type == 'Server'
|
||||||
|
? ApiEndpoints.ServerTimeline[Soft]
|
||||||
|
: ApiEndpoints.FetchNotes[Soft](Profile);
|
||||||
|
NetCall({Target: UrlBase(Profile.Url), Method: Method, CallFine: function(Res){
|
||||||
var Notes = ApiTransform(Res.responseJson, Soft, 'Note');
|
var Notes = ApiTransform(Res.responseJson, Soft, 'Note');
|
||||||
LogDebug(Notes, 'l');
|
LogDebug(Notes, 'l');
|
||||||
Tasker[Res.Proc[0]].Return(Notes);
|
Tasker[Res.Proc[0]].Return(Notes);
|
||||||
|
@ -163,7 +151,7 @@ function FillTimeline(Notes) {
|
||||||
Notes.forEach(function(Note){
|
Notes.forEach(function(Note){
|
||||||
ApiCache.__UrlStore__(Note.Profile);
|
ApiCache.__UrlStore__(Note.Profile);
|
||||||
Root.lastChild.innerHTML += `<div class="View Note">
|
Root.lastChild.innerHTML += `<div class="View Note">
|
||||||
<a href="${Note.Profile.Url}" onclick="DisplayProfile(ApiCache.Urls['${Note.Profile.Url}']); return false;">
|
<a href="${Note.Profile.Url}" onclick="DisplayProfile('${Note.Profile.Url}'); return false;">
|
||||||
<img class="Profile Icon" src="${Note.Profile.Icon}"/>
|
<img class="Profile Icon" src="${Note.Profile.Icon}"/>
|
||||||
${Note.Profile.Name}
|
${Note.Profile.Name}
|
||||||
</a>
|
</a>
|
||||||
|
@ -173,9 +161,14 @@ function FillTimeline(Notes) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function DisplayThread() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
function FillHome() {
|
function FillHome() {
|
||||||
var Window = MkWindow({className: "Gallery"});
|
var Window = MkWindow({className: "Gallery"});
|
||||||
var Categories = ApiStatic.Featured;
|
var Categories = ApiStatic.Featured;
|
||||||
|
//_.forOwn(Categories, function(CategoryVal, Category){
|
||||||
Object.keys(Categories).forEach(function(Category){
|
Object.keys(Categories).forEach(function(Category){
|
||||||
Window.innerHTML += `<h2>Featured ${Category}</h2><ul></ul>`;
|
Window.innerHTML += `<h2>Featured ${Category}</h2><ul></ul>`;
|
||||||
Categories[Category].forEach(function(Profile){
|
Categories[Category].forEach(function(Profile){
|
||||||
|
@ -207,10 +200,6 @@ PlazasView.innerHTML = `
|
||||||
<ul>
|
<ul>
|
||||||
<li onclick="DisplayFriendicaTimeline('statuses/networkpublic_timeline');">Federation</li>
|
<li onclick="DisplayFriendicaTimeline('statuses/networkpublic_timeline');">Federation</li>
|
||||||
<li onclick="DisplayFriendicaTimeline('statuses/public_timeline');">${FriendicaUrl}</li>
|
<li onclick="DisplayFriendicaTimeline('statuses/public_timeline');">${FriendicaUrl}</li>
|
||||||
<li onclick="DoAsync(FetchMastodon, FillTimeline);">
|
|
||||||
<img src=""/>
|
|
||||||
${MastodonUrl}
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -6,10 +6,10 @@ function NetCall(Data, Proc) {
|
||||||
Req.onloadend = function(){
|
Req.onloadend = function(){
|
||||||
try {
|
try {
|
||||||
this.responseJson = JSON.parse(this.responseText);
|
this.responseJson = JSON.parse(this.responseText);
|
||||||
this.response = this.responseJson;
|
|
||||||
this.responseLog = this.responseJson;
|
this.responseLog = this.responseJson;
|
||||||
} catch(Ex) {
|
} catch(Ex) {
|
||||||
this.responseLog = this.responseText;
|
this.responseLog = this.responseText;
|
||||||
|
LogDebug(Ex, 'e');
|
||||||
};
|
};
|
||||||
if (Data.Call) {
|
if (Data.Call) {
|
||||||
Data.Call(this);
|
Data.Call(this);
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* ChildNode.remove() polyfill
|
||||||
|
* https://gomakethings.com/removing-an-element-from-the-dom-the-es6-way/
|
||||||
|
* @author Chris Ferdinandi
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
(function (elem) {
|
||||||
|
for (var i = 0; i < elem.length; i++) {
|
||||||
|
if (!window[elem[i]] || 'remove' in window[elem[i]].prototype) continue;
|
||||||
|
window[elem[i]].prototype.remove = function () {
|
||||||
|
this.parentNode.removeChild(this);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})(['Element', 'CharacterData', 'DocumentType']);
|
|
@ -0,0 +1,491 @@
|
||||||
|
/**
|
||||||
|
* URL Polyfill
|
||||||
|
* Draft specification: https://url.spec.whatwg.org
|
||||||
|
* https://polyfill.io/
|
||||||
|
*/
|
||||||
|
(function (global) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function isSequence(o) {
|
||||||
|
if (!o) return false;
|
||||||
|
if ('Symbol' in global && 'iterator' in global.Symbol &&
|
||||||
|
typeof o[Symbol.iterator] === 'function') return true;
|
||||||
|
if (Array.isArray(o)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toArray(iter) {
|
||||||
|
return ('from' in Array) ? Array.from(iter) : Array.prototype.slice.call(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
// Browsers may have:
|
||||||
|
// * No global URL object
|
||||||
|
// * URL with static methods only - may have a dummy constructor
|
||||||
|
// * URL with members except searchParams
|
||||||
|
// * Full URL API support
|
||||||
|
var origURL = global.URL;
|
||||||
|
var nativeURL;
|
||||||
|
try {
|
||||||
|
if (origURL) {
|
||||||
|
nativeURL = new global.URL('http://example.com');
|
||||||
|
if ('searchParams' in nativeURL) {
|
||||||
|
var url = new URL('http://example.com');
|
||||||
|
url.search = 'a=1&b=2';
|
||||||
|
if (url.href === 'http://example.com/?a=1&b=2') {
|
||||||
|
url.search = '';
|
||||||
|
if (url.href === 'http://example.com/') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!('href' in nativeURL)) {
|
||||||
|
nativeURL = undefined;
|
||||||
|
}
|
||||||
|
nativeURL = undefined;
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-empty
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
// NOTE: Doesn't do the encoding/decoding dance
|
||||||
|
function urlencoded_serialize(pairs) {
|
||||||
|
var output = '', first = true;
|
||||||
|
pairs.forEach(function (pair) {
|
||||||
|
var name = encodeURIComponent(pair.name);
|
||||||
|
var value = encodeURIComponent(pair.value);
|
||||||
|
if (!first) output += '&';
|
||||||
|
output += name + '=' + value;
|
||||||
|
first = false;
|
||||||
|
});
|
||||||
|
return output.replace(/%20/g, '+');
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Doesn't do the encoding/decoding dance
|
||||||
|
function urlencoded_parse(input, isindex) {
|
||||||
|
var sequences = input.split('&');
|
||||||
|
if (isindex && sequences[0].indexOf('=') === -1)
|
||||||
|
sequences[0] = '=' + sequences[0];
|
||||||
|
var pairs = [];
|
||||||
|
sequences.forEach(function (bytes) {
|
||||||
|
if (bytes.length === 0) return;
|
||||||
|
var index = bytes.indexOf('=');
|
||||||
|
if (index !== -1) {
|
||||||
|
var name = bytes.substring(0, index);
|
||||||
|
var value = bytes.substring(index + 1);
|
||||||
|
} else {
|
||||||
|
name = bytes;
|
||||||
|
value = '';
|
||||||
|
}
|
||||||
|
name = name.replace(/\+/g, ' ');
|
||||||
|
value = value.replace(/\+/g, ' ');
|
||||||
|
pairs.push({ name: name, value: value });
|
||||||
|
});
|
||||||
|
var output = [];
|
||||||
|
pairs.forEach(function (pair) {
|
||||||
|
output.push({
|
||||||
|
name: decodeURIComponent(pair.name),
|
||||||
|
value: decodeURIComponent(pair.value)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
function URLUtils(url) {
|
||||||
|
if (nativeURL)
|
||||||
|
return new origURL(url);
|
||||||
|
var anchor = document.createElement('a');
|
||||||
|
anchor.href = url;
|
||||||
|
return anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
function URLSearchParams(init) {
|
||||||
|
var $this = this;
|
||||||
|
this._list = [];
|
||||||
|
|
||||||
|
if (init === undefined || init === null) {
|
||||||
|
// no-op
|
||||||
|
} else if (init instanceof URLSearchParams) {
|
||||||
|
// In ES6 init would be a sequence, but special case for ES5.
|
||||||
|
this._list = urlencoded_parse(String(init));
|
||||||
|
} else if (typeof init === 'object' && isSequence(init)) {
|
||||||
|
toArray(init).forEach(function(e) {
|
||||||
|
if (!isSequence(e)) throw TypeError();
|
||||||
|
var nv = toArray(e);
|
||||||
|
if (nv.length !== 2) throw TypeError();
|
||||||
|
$this._list.push({name: String(nv[0]), value: String(nv[1])});
|
||||||
|
});
|
||||||
|
} else if (typeof init === 'object' && init) {
|
||||||
|
Object.keys(init).forEach(function(key) {
|
||||||
|
$this._list.push({name: String(key), value: String(init[key])});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
init = String(init);
|
||||||
|
if (init.substring(0, 1) === '?')
|
||||||
|
init = init.substring(1);
|
||||||
|
this._list = urlencoded_parse(init);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._url_object = null;
|
||||||
|
this._setList = function (list) { if (!updating) $this._list = list; };
|
||||||
|
|
||||||
|
var updating = false;
|
||||||
|
this._update_steps = function() {
|
||||||
|
if (updating) return;
|
||||||
|
updating = true;
|
||||||
|
|
||||||
|
if (!$this._url_object) return;
|
||||||
|
|
||||||
|
// Partial workaround for IE issue with 'about:'
|
||||||
|
if ($this._url_object.protocol === 'about:' &&
|
||||||
|
$this._url_object.pathname.indexOf('?') !== -1) {
|
||||||
|
$this._url_object.pathname = $this._url_object.pathname.split('?')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this._url_object.search = urlencoded_serialize($this._list);
|
||||||
|
|
||||||
|
updating = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperties(URLSearchParams.prototype, {
|
||||||
|
append: {
|
||||||
|
value: function (name, value) {
|
||||||
|
this._list.push({ name: name, value: value });
|
||||||
|
this._update_steps();
|
||||||
|
}, writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
'delete': {
|
||||||
|
value: function (name) {
|
||||||
|
for (var i = 0; i < this._list.length;) {
|
||||||
|
if (this._list[i].name === name)
|
||||||
|
this._list.splice(i, 1);
|
||||||
|
else
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
this._update_steps();
|
||||||
|
}, writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
get: {
|
||||||
|
value: function (name) {
|
||||||
|
for (var i = 0; i < this._list.length; ++i) {
|
||||||
|
if (this._list[i].name === name)
|
||||||
|
return this._list[i].value;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}, writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
getAll: {
|
||||||
|
value: function (name) {
|
||||||
|
var result = [];
|
||||||
|
for (var i = 0; i < this._list.length; ++i) {
|
||||||
|
if (this._list[i].name === name)
|
||||||
|
result.push(this._list[i].value);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}, writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
has: {
|
||||||
|
value: function (name) {
|
||||||
|
for (var i = 0; i < this._list.length; ++i) {
|
||||||
|
if (this._list[i].name === name)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}, writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
set: {
|
||||||
|
value: function (name, value) {
|
||||||
|
var found = false;
|
||||||
|
for (var i = 0; i < this._list.length;) {
|
||||||
|
if (this._list[i].name === name) {
|
||||||
|
if (!found) {
|
||||||
|
this._list[i].value = value;
|
||||||
|
found = true;
|
||||||
|
++i;
|
||||||
|
} else {
|
||||||
|
this._list.splice(i, 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
this._list.push({ name: name, value: value });
|
||||||
|
|
||||||
|
this._update_steps();
|
||||||
|
}, writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
entries: {
|
||||||
|
value: function() { return new Iterator(this._list, 'key+value'); },
|
||||||
|
writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
keys: {
|
||||||
|
value: function() { return new Iterator(this._list, 'key'); },
|
||||||
|
writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
values: {
|
||||||
|
value: function() { return new Iterator(this._list, 'value'); },
|
||||||
|
writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
forEach: {
|
||||||
|
value: function(callback) {
|
||||||
|
var thisArg = (arguments.length > 1) ? arguments[1] : undefined;
|
||||||
|
this._list.forEach(function(pair) {
|
||||||
|
callback.call(thisArg, pair.value, pair.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
}, writable: true, enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
toString: {
|
||||||
|
value: function () {
|
||||||
|
return urlencoded_serialize(this._list);
|
||||||
|
}, writable: true, enumerable: false, configurable: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function Iterator(source, kind) {
|
||||||
|
var index = 0;
|
||||||
|
this.next = function() {
|
||||||
|
if (index >= source.length)
|
||||||
|
return {done: true, value: undefined};
|
||||||
|
var pair = source[index++];
|
||||||
|
return {done: false, value:
|
||||||
|
kind === 'key' ? pair.name :
|
||||||
|
kind === 'value' ? pair.value :
|
||||||
|
[pair.name, pair.value]};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('Symbol' in global && 'iterator' in global.Symbol) {
|
||||||
|
Object.defineProperty(URLSearchParams.prototype, global.Symbol.iterator, {
|
||||||
|
value: URLSearchParams.prototype.entries,
|
||||||
|
writable: true, enumerable: true, configurable: true});
|
||||||
|
Object.defineProperty(Iterator.prototype, global.Symbol.iterator, {
|
||||||
|
value: function() { return this; },
|
||||||
|
writable: true, enumerable: true, configurable: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
function URL(url, base) {
|
||||||
|
if (!(this instanceof global.URL))
|
||||||
|
throw new TypeError("Failed to construct 'URL': Please use the 'new' operator.");
|
||||||
|
|
||||||
|
if (base) {
|
||||||
|
url = (function () {
|
||||||
|
if (nativeURL) return new origURL(url, base).href;
|
||||||
|
var iframe;
|
||||||
|
try {
|
||||||
|
var doc;
|
||||||
|
// Use another document/base tag/anchor for relative URL resolution, if possible
|
||||||
|
if (Object.prototype.toString.call(window.operamini) === "[object OperaMini]") {
|
||||||
|
iframe = document.createElement('iframe');
|
||||||
|
iframe.style.display = 'none';
|
||||||
|
document.documentElement.appendChild(iframe);
|
||||||
|
doc = iframe.contentWindow.document;
|
||||||
|
} else if (document.implementation && document.implementation.createHTMLDocument) {
|
||||||
|
doc = document.implementation.createHTMLDocument('');
|
||||||
|
} else if (document.implementation && document.implementation.createDocument) {
|
||||||
|
doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
|
||||||
|
doc.documentElement.appendChild(doc.createElement('head'));
|
||||||
|
doc.documentElement.appendChild(doc.createElement('body'));
|
||||||
|
} else if (window.ActiveXObject) {
|
||||||
|
doc = new window.ActiveXObject('htmlfile');
|
||||||
|
doc.write('<head></head><body></body>');
|
||||||
|
doc.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc) throw Error('base not supported');
|
||||||
|
|
||||||
|
var baseTag = doc.createElement('base');
|
||||||
|
baseTag.href = base;
|
||||||
|
doc.getElementsByTagName('head')[0].appendChild(baseTag);
|
||||||
|
var anchor = doc.createElement('a');
|
||||||
|
anchor.href = url;
|
||||||
|
return anchor.href;
|
||||||
|
} finally {
|
||||||
|
if (iframe)
|
||||||
|
iframe.parentNode.removeChild(iframe);
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
|
||||||
|
// An inner object implementing URLUtils (either a native URL
|
||||||
|
// object or an HTMLAnchorElement instance) is used to perform the
|
||||||
|
// URL algorithms. With full ES5 getter/setter support, return a
|
||||||
|
// regular object For IE8's limited getter/setter support, a
|
||||||
|
// different HTMLAnchorElement is returned with properties
|
||||||
|
// overridden
|
||||||
|
|
||||||
|
var instance = URLUtils(url || '');
|
||||||
|
|
||||||
|
// Detect for ES5 getter/setter support
|
||||||
|
// (an Object.defineProperties polyfill that doesn't support getters/setters may throw)
|
||||||
|
var ES5_GET_SET = (function() {
|
||||||
|
if (!('defineProperties' in Object)) return false;
|
||||||
|
try {
|
||||||
|
var obj = {};
|
||||||
|
Object.defineProperties(obj, { prop: { get: function () { return true; } } });
|
||||||
|
return obj.prop;
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
|
||||||
|
var self = ES5_GET_SET ? this : document.createElement('a');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var query_object = new URLSearchParams(
|
||||||
|
instance.search ? instance.search.substring(1) : null);
|
||||||
|
query_object._url_object = self;
|
||||||
|
|
||||||
|
Object.defineProperties(self, {
|
||||||
|
href: {
|
||||||
|
get: function () { return instance.href; },
|
||||||
|
set: function (v) { instance.href = v; tidy_instance(); update_steps(); },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
origin: {
|
||||||
|
get: function () {
|
||||||
|
if ('origin' in instance) return instance.origin;
|
||||||
|
return this.protocol + '//' + this.host;
|
||||||
|
},
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
protocol: {
|
||||||
|
get: function () { return instance.protocol; },
|
||||||
|
set: function (v) { instance.protocol = v; },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
username: {
|
||||||
|
get: function () { return instance.username; },
|
||||||
|
set: function (v) { instance.username = v; },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
get: function () { return instance.password; },
|
||||||
|
set: function (v) { instance.password = v; },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
host: {
|
||||||
|
get: function () {
|
||||||
|
// IE returns default port in |host|
|
||||||
|
var re = {'http:': /:80$/, 'https:': /:443$/, 'ftp:': /:21$/}[instance.protocol];
|
||||||
|
return re ? instance.host.replace(re, '') : instance.host;
|
||||||
|
},
|
||||||
|
set: function (v) { instance.host = v; },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
hostname: {
|
||||||
|
get: function () { return instance.hostname; },
|
||||||
|
set: function (v) { instance.hostname = v; },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
port: {
|
||||||
|
get: function () { return instance.port; },
|
||||||
|
set: function (v) { instance.port = v; },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
pathname: {
|
||||||
|
get: function () {
|
||||||
|
// IE does not include leading '/' in |pathname|
|
||||||
|
if (instance.pathname.charAt(0) !== '/') return '/' + instance.pathname;
|
||||||
|
return instance.pathname;
|
||||||
|
},
|
||||||
|
set: function (v) { instance.pathname = v; },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
get: function () { return instance.search; },
|
||||||
|
set: function (v) {
|
||||||
|
if (instance.search === v) return;
|
||||||
|
instance.search = v; tidy_instance(); update_steps();
|
||||||
|
},
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
searchParams: {
|
||||||
|
get: function () { return query_object; },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
hash: {
|
||||||
|
get: function () { return instance.hash; },
|
||||||
|
set: function (v) { instance.hash = v; tidy_instance(); },
|
||||||
|
enumerable: true, configurable: true
|
||||||
|
},
|
||||||
|
toString: {
|
||||||
|
value: function() { return instance.toString(); },
|
||||||
|
enumerable: false, configurable: true
|
||||||
|
},
|
||||||
|
valueOf: {
|
||||||
|
value: function() { return instance.valueOf(); },
|
||||||
|
enumerable: false, configurable: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function tidy_instance() {
|
||||||
|
var href = instance.href.replace(/#$|\?$|\?(?=#)/g, '');
|
||||||
|
if (instance.href !== href)
|
||||||
|
instance.href = href;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_steps() {
|
||||||
|
query_object._setList(instance.search ? urlencoded_parse(instance.search.substring(1)) : []);
|
||||||
|
query_object._update_steps();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (origURL) {
|
||||||
|
for (var i in origURL) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(origURL, i) && typeof origURL[i] === 'function')
|
||||||
|
URL[i] = origURL[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global.URL = URL;
|
||||||
|
global.URLSearchParams = URLSearchParams;
|
||||||
|
}());
|
||||||
|
|
||||||
|
// Patch native URLSearchParams constructor to handle sequences/records
|
||||||
|
// if necessary.
|
||||||
|
(function() {
|
||||||
|
if (new global.URLSearchParams([['a', 1]]).get('a') === '1' &&
|
||||||
|
new global.URLSearchParams({a: 1}).get('a') === '1')
|
||||||
|
return;
|
||||||
|
var orig = global.URLSearchParams;
|
||||||
|
global.URLSearchParams = function(init) {
|
||||||
|
if (init && typeof init === 'object' && isSequence(init)) {
|
||||||
|
var o = new orig();
|
||||||
|
toArray(init).forEach(function(e) {
|
||||||
|
if (!isSequence(e)) throw TypeError();
|
||||||
|
var nv = toArray(e);
|
||||||
|
if (nv.length !== 2) throw TypeError();
|
||||||
|
o.append(nv[0], nv[1]);
|
||||||
|
});
|
||||||
|
return o;
|
||||||
|
} else if (init && typeof init === 'object') {
|
||||||
|
o = new orig();
|
||||||
|
Object.keys(init).forEach(function(key) {
|
||||||
|
o.set(key, init[key]);
|
||||||
|
});
|
||||||
|
return o;
|
||||||
|
} else {
|
||||||
|
return new orig(init);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
|
||||||
|
}(self));
|
|
@ -1,9 +0,0 @@
|
||||||
if (!Array.prototype.from) {
|
|
||||||
Array.prototype.from = function from(List) {
|
|
||||||
var Arr = [];
|
|
||||||
for (var i=0; i<List.length; i++) {
|
|
||||||
Arr.push(List[i]);
|
|
||||||
};
|
|
||||||
return Arr;
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -52,10 +52,10 @@ img, video {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
|
|
||||||
height: 100vh;
|
height: calc(100vh - var(--BarHeight));
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: var(--WindowMargin);
|
padding: var(--WindowMargin);
|
||||||
padding-bottom: calc(var(--WindowMargin) + (var(--BarHeight) * 2));
|
/*padding-bottom: calc(var(--WindowMargin) + (var(--BarHeight) * 2));*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.View.Note {
|
.View.Note {
|
||||||
|
|
125
App/Utils.js
125
App/Utils.js
|
@ -23,11 +23,13 @@ function UrlDomain(Url) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function FuncName(Fun) {
|
function FuncName(Fun) {
|
||||||
|
if (Fun) {
|
||||||
Fun = Fun.toString();
|
Fun = Fun.toString();
|
||||||
var Name = Fun.split(' ')[1].split('(')[0].split('{')[0];
|
var Name = Fun.split(' ')[1].split('(')[0].split('{')[0];
|
||||||
var Hash = Fun.hashCode();
|
var Hash = Fun.hashCode();
|
||||||
return `f:${Name} (${Fun.hashCode()})`;
|
return `f:${Name} (${Fun.hashCode()})`;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
function CallFun(f, a, b, c, d) {
|
function CallFun(f, a, b, c, d) {
|
||||||
if (typeof(f) === 'function') {
|
if (typeof(f) === 'function') {
|
||||||
|
@ -37,15 +39,19 @@ function CallFun(f, a, b, c, d) {
|
||||||
|
|
||||||
function LogDebug(Data, Status) {
|
function LogDebug(Data, Status) {
|
||||||
if (Debug) {
|
if (Debug) {
|
||||||
|
var Caller;
|
||||||
if (!Status) {
|
if (!Status) {
|
||||||
Status = 'l';
|
Status = 'l';
|
||||||
};
|
};
|
||||||
for (var i=0; i<Data.length; i++) {
|
for (var i=0; i<Data.length; i++) {
|
||||||
try {
|
try {
|
||||||
Data[i] = JSON.parse(Data[i]);
|
Data[i] = JSON.parse(Data[i]);
|
||||||
} catch(_){};
|
} catch(Ex){};
|
||||||
};
|
};
|
||||||
console[{l: "log", e: "error"}[Status.toLowerCase()]](FuncName(LogDebug.caller), Data);
|
try {
|
||||||
|
var Caller = LogDebug.caller;
|
||||||
|
} catch(Ex){};
|
||||||
|
console[{l: "log", e: "error"}[Status.toLowerCase()]](FuncName(Caller), Data);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,13 +71,16 @@ function ExtrimObj(Obj) {
|
||||||
return Obj;
|
return Obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
function UrlObj(Val) {
|
function UrlObj(Val, NetData) {
|
||||||
if (IsObj(Val)) {
|
if (IsObj(Val)) {
|
||||||
return Obj;
|
return Val;
|
||||||
} else
|
} else
|
||||||
if (typeof(Val) === 'string') {
|
if (typeof(Val) === 'string') {
|
||||||
// TODO: fetch from Internet if key missing in cache
|
if (ApiCache.Urls[Val]) {
|
||||||
return ApiCache.Urls[Val];
|
return ApiCache.Urls[Val];
|
||||||
|
} else {
|
||||||
|
// TODO: fetch from Internet if key missing in cache
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,112 +91,6 @@ function UnB64Obj(Obj) {
|
||||||
return JSON.parse(atob(Obj));
|
return JSON.parse(atob(Obj));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Transform JSON tree into a new using a template schema
|
|
||||||
// DEVNOTE: Unsafe, should check for colliding "__" keys from input tree and act accordingly
|
|
||||||
function JsonTransformA(TreesOld, SchemaCurr, SchemaRoot) {
|
|
||||||
if (Array.isArray(TreesOld)) {
|
|
||||||
var ListNew = [];
|
|
||||||
ForceList(TreesOld).forEach(function(TreeOld){
|
|
||||||
ListNew.push(JsonTransformCycleA(TreeOld, SchemaCurr, SchemaRoot));
|
|
||||||
});
|
|
||||||
return ListNew;
|
|
||||||
} else {
|
|
||||||
return JsonTransformCycleA(TreesOld, SchemaCurr, SchemaRoot);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
function JsonTransformCycleA(TreeOld, SchemaCurr, SchemaRoot) {
|
|
||||||
var TreeNew = {};
|
|
||||||
Object.keys(TreeOld).forEach(function(KeyOld){
|
|
||||||
var Content = TreeOld[KeyOld];
|
|
||||||
var KeyNew = ((IsObj(SchemaCurr) && KeyOld in SchemaCurr) ? SchemaCurr[KeyOld] : KeyOld);
|
|
||||||
if (IsObj(Content) && Content !== null) {
|
|
||||||
if (Array.isArray(Content)) {
|
|
||||||
// Lists
|
|
||||||
/* var ListNew = [];
|
|
||||||
Content.forEach(function(Value){
|
|
||||||
ListNew.push(JsonTransform(Value, KeyNew));
|
|
||||||
});
|
|
||||||
TreeNew[KeyNew] = ListNew;*/
|
|
||||||
} else {
|
|
||||||
// Dicts
|
|
||||||
// Strange bug, in this context we can't assign new value to child of the object, we use a variable
|
|
||||||
NameKeyNew = KeyNew.__;
|
|
||||||
if (!NameKeyNew) {
|
|
||||||
NameKeyNew = KeyOld;
|
|
||||||
};
|
|
||||||
TreeNew[NameKeyNew] = JsonTransformA(Content, SchemaRoot[NameKeyNew], SchemaRoot);
|
|
||||||
if (NameKeyNew !== KeyOld) {
|
|
||||||
TreeNew[SchemaRoot[NameKeyNew].__] = TreeNew[NameKeyNew];
|
|
||||||
delete TreeNew[NameKeyNew];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// Values
|
|
||||||
TreeNew[KeyNew] = Content;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return TreeNew;
|
|
||||||
};
|
|
||||||
|
|
||||||
function JsonTransformB(TreesOld, SchemaNew, NodeNew, TypeOld) {
|
|
||||||
LogDebug([TreesOld, SchemaNew, NodeNew, TypeOld]);
|
|
||||||
if (Array.isArray(TreesOld)) {
|
|
||||||
// List of values
|
|
||||||
var ListNew = [];
|
|
||||||
ForceList(TreesOld).forEach(function(TreeOld){
|
|
||||||
ListNew.push(JsonTransformCycleB(TreeOld, SchemaNew, NodeNew, TypeOld));
|
|
||||||
});
|
|
||||||
return ListNew;
|
|
||||||
} else {
|
|
||||||
// Object
|
|
||||||
if (TreesOld) {
|
|
||||||
return JsonTransformCycleB(TreesOld, SchemaNew, NodeNew, TypeOld);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
function JsonTransformCycleB(TreeOld, SchemaNew, NodeNew, TypeOld) {
|
|
||||||
var TreeNew = CopyObj(NodeNew);
|
|
||||||
Object.keys(TreeNew).forEach(function(KeyNew){
|
|
||||||
if (TypeOld in TreeNew[KeyNew]) {
|
|
||||||
var KeyOld = TreeNew[KeyNew][TypeOld];
|
|
||||||
var ObjOld = TreeOld[KeyOld];
|
|
||||||
if (IsObj(KeyOld)) {
|
|
||||||
// Object in SchemaNew / Deep nested children in TreeOld
|
|
||||||
Object.keys(KeyOld).forEach(function(KeyObj){
|
|
||||||
//if (SchemaNew.__All__) {
|
|
||||||
// TreeNew.__All__ = SchemaNew.__All__;
|
|
||||||
//};
|
|
||||||
if (KeyObj === '__Eval__') {
|
|
||||||
eval(KeyOld[KeyObj]);
|
|
||||||
} else
|
|
||||||
if (KeyObj === '__EvalSet__') {
|
|
||||||
TreeNew[KeyNew] = eval(KeyOld[KeyObj]);
|
|
||||||
} else
|
|
||||||
if (KeyObj === '__OldOr__') {
|
|
||||||
var Keys = KeyOld[KeyObj];
|
|
||||||
for (var i=0; i<Keys.length; i++) {
|
|
||||||
var Key = TreeOld[Keys[i]];
|
|
||||||
if (Key !== undefined) {
|
|
||||||
TreeNew[KeyNew] = Key;
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Value in SchemaNew / Direct children in TreeOld
|
|
||||||
if (IsObj(ObjOld)) {
|
|
||||||
TreeNew[KeyNew] = JsonTransformB(ObjOld, SchemaNew, SchemaNew[KeyNew], TypeOld);
|
|
||||||
} else {
|
|
||||||
TreeNew[KeyNew] = ObjOld;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
TreeNew.__TreeOld__ = TreeOld;
|
|
||||||
return TreeNew;
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://stackoverflow.com/a/7616484
|
// https://stackoverflow.com/a/7616484
|
||||||
String.prototype.hashCode = function() {
|
String.prototype.hashCode = function() {
|
||||||
var hash = 0, i, chr;
|
var hash = 0, i, chr;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
rm -rf ./Build || true && \
|
||||||
|
cp -r ./App ./Build && \
|
||||||
|
npx babel ./App -d ./Build && \
|
||||||
|
python3 ./Bundle.py
|
|
@ -4,10 +4,22 @@ from base64 import b64encode
|
||||||
from mimetypes import guess_type
|
from mimetypes import guess_type
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
#def MinifyJs(Js):
|
||||||
|
# New = ''
|
||||||
|
# Js = Js.replace('\\\n', '\n')
|
||||||
|
# BlockOpen = False
|
||||||
|
# for Line in Js.splitlines():
|
||||||
|
# if '/*' in Line: BlockOpen = True
|
||||||
|
# if '*/' in Line: BlockOpen = False
|
||||||
|
# if '//' in Line and not BlockOpen:
|
||||||
|
# Line = Line.replace('//', '/*') + '*/'
|
||||||
|
# New += Line
|
||||||
|
# return New.replace('\n', ' ')
|
||||||
|
|
||||||
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||||
os.makedirs('./Dist', exist_ok=True)
|
os.makedirs('./Dist', exist_ok=True)
|
||||||
|
|
||||||
os.chdir('./App')
|
os.chdir('./Build')
|
||||||
|
|
||||||
with open(f'./Friendiiverse.html', 'r') as Base:
|
with open(f'./Friendiiverse.html', 'r') as Base:
|
||||||
Base = Base.read()
|
Base = Base.read()
|
||||||
|
@ -17,7 +29,10 @@ def FragReplace(Find, Replace, Pattern='*.*'):
|
||||||
for File in Path('./').rglob(Pattern):
|
for File in Path('./').rglob(Pattern):
|
||||||
File = str(File)
|
File = str(File)
|
||||||
with open(File, 'r') as Frag:
|
with open(File, 'r') as Frag:
|
||||||
Frag = Replace.format(File=File, Frag=Frag.read())
|
Frag = Frag.read()
|
||||||
|
#if Pattern.endswith('*.js') and not File.startswith('Lib/'):
|
||||||
|
# Frag = MinifyJs(Frag)
|
||||||
|
Frag = Replace.format(File=File, Frag=Frag)
|
||||||
for Prefix in ('', './'):
|
for Prefix in ('', './'):
|
||||||
Name = Prefix + File
|
Name = Prefix + File
|
||||||
Base = Base.replace(Find.format(File=Name), Frag)
|
Base = Base.replace(Find.format(File=Name), Frag)
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"targets": {
|
||||||
|
"chrome": "4",
|
||||||
|
"edge": "12",
|
||||||
|
"firefox": "2",
|
||||||
|
"ie": "6",
|
||||||
|
"safari": "3.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"name": "Friendiiverse",
|
||||||
|
"version": "Pre-Alpha Development",
|
||||||
|
"scripts": {
|
||||||
|
"build": "sh ./Build.sh"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/cli": "^7.21.0",
|
||||||
|
"@babel/core": "^7.21.4",
|
||||||
|
"@babel/preset-env": "^7.21.4"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue