Refactored to separate files for each class

WIP: Added project-planner provider
This commit is contained in:
Ray 2023-12-23 16:27:49 +00:00
parent 7491df9c75
commit d36b98a20c
13 changed files with 1024 additions and 411 deletions

406
ryjsxt.js
View File

@ -1,406 +0,0 @@
/**
* Ray's JavaScript Extension
* @version v0.1.0.021 (2023/12/11 0056)
*/
Array.prototype.index = function (propName, value) {
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
continue;
}
if (this[i][propName] == value){
return i;
}
}
return -1;
};
Array.prototype.insert = function(index, item) {
if (index < 0) {
this.splice(0, 0, item);
} else if (index >= this.length) {
this.push(0, 0, item);
} else {
this.splice(index, 0, item);
}
return this;
};
Array.prototype.joinIfNotNullOrWhitespace = function (separator) {
const a = this;
let result = "";
for (let i = 0; i < this.length; i++) {
if (String.isNullOrWhitespace(this[i])) {
continue;
}
if (!String.isNullOrWhitespace(result)) {
result += separator;
}
result += this[i];
};
return result;
};
Array.prototype.first = function (propName, value) {
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
continue;
}
if (this[i][propName] == value){
return this[i];
}
}
return null;
};
Array.prototype.indexes = function (propName, value) {
let result = [];
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
continue;
}
if (this[i][propName] == value){
result.push(i);
}
}
return result;
};
Array.prototype.orderBy = function (propName) {
this.sort(function(a, b) {
if (a[propName] < b[propName]) {
return -1;
} else if (a[propName] > b[propName]) {
return 1;
} else {
return 0;
}
});
return this;
};
Array.prototype.orderByDesc = function (propName) {
this.sort(function(a, b) {
if (a[propName] < b[propName]) {
return 1;
} else if (a[propName] > b[propName]) {
return -1;
} else {
return 0;
}
});
return this;
};
Array.prototype.removeAt = function(index) {
if ((index < 0) || (index >= this.length)) {
return this;
}
this.splice(index, 1);
return this;
};
Array.prototype.select = function (propName, value) {
let result = [];
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
continue;
}
if (this[i][propName] == value){
result.push(this[i]);
}
}
return result;
};
Boolean.isFalse = function(value) {
const a = this;
if (String.isNullOrUndefined(value)) {
return true;
}
return value.toString().containsCI("false", "f", "y", "0", "x");
};
Boolean.isTrue = function(value) {
const a = this;
if (String.isNullOrUndefined(value)) {
return false;
}
return value.toString().containsCI("true", "t", "n", "1", "o");
};
Boolean.ifTrue = function(value, trueValue, falseValue) {
const a = this;
return (Boolean.isTrue(value) ? trueValue : falseValue);
};
Date.addDays = function (date, days) {
let result = new Date(date);
result.addDays(days);
return result;
};
Date.addMonths = function (date, months) {
let result = new Date(date);
result.addMonths(months);
return result;
};
Date.addYears = function (date, years) {
let result = new Date(date);
result.addYears(years);
return result;
};
Date.prototype.addDays = function (days) {
this.setDate(this.getDate() + parseInt(days));
}
Date.prototype.addMonths = function (months) {
this.setMonth(this.getMonth() + parseInt(months));
}
Date.prototype.addYears = function (years) {
this.setFullYear(this.getFullYear() + parseInt(years));
}
Date.prototype.toCString = function(pattern) {
let result = pattern;
result = result.replace("fffffff", this.getMilliseconds().toString().padStart(7, '0'));
result = result.replace("ffffff", this.getMilliseconds().toString().padStart(6, '0'));
result = result.replace("fffff", this.getMilliseconds().toString().padStart(5, '0'));
result = result.replace("yyyy", this.getFullYear().toString().padStart(4, '0'));
result = result.replace("MMMM", "{1}");
result = result.replace("dddd", "{2}");
result = result.replace("ffff", this.getMilliseconds().toString().padStart(4, '0'));
result = result.replace("yyy", this.getFullYear().toString().padStart(3, '0'));
result = result.replace("MMM", "{3}");
result = result.replace("ddd", "{4}");
result = result.replace("fff", this.getMilliseconds().toString().padStart(3, '0'));
result = result.replace("zzz", "");
result = result.replace("yy", this.getFullYear().toString().slice(-2));
result = result.replace("MM", (this.getMonth() + 1).toString().padStart(2, '0'));
result = result.replace("dd", this.getDate().toString().padStart(2, '0'));
result = result.replace("HH", this.getHours().toString().padStart(2, '0'));
result = result.replace("hh", (this.getHours() > 12 ? (this.getHours() - 12) : this.getHours()).toString().padStart(2, '0'));
result = result.replace("mm", this.getMinutes().toString().padStart(2, '0'));
result = result.replace("ss", this.getSeconds().toString().padStart(2, '0'));
result = result.replace("ff", this.getMilliseconds().toString().padStart(2, '0'));
result = result.replace("tt", "{5}");
result = result.replace("zz", "");
result = result.replace("y", this.getFullYear().toString());
result = result.replace("M", (this.getMonth() + 1).toString());
result = result.replace("d", this.getDate().toString());
result = result.replace("H", this.getHours().toString());
result = result.replace("h", (this.getHours() > 12 ? (this.getHours() - 12) : this.getHours()).toString());
result = result.replace("m", this.getMinutes().toString());
result = result.replace("s", this.getSeconds().toString());
result = result.replace("z", "");
result = result.replace("t", "{6}");
result = result.replace("Z", "");
result = result.replace("{1}", this.toLocaleString('default', { month: 'long' }));
result = result.replace("{2}", this.toLocaleString('default', { weekday: 'long' }));
result = result.replace("{3}", this.toLocaleString('default', { month: 'short' }));
result = result.replace("{4}", this.toLocaleString('default', { weekday: 'short' }));
result = result.replace("{5}", (this.getHours() >= 12 ? "PM" : "AM"));
result = result.replace("{6}", (this.getHours() >= 12 ? "P" : "A"));
return result;
}
Document.ready = async function(fn) {
(async function() {
(document.readyState !== 'loading') ?
fn() : document.addEventListener('DOMContentLoaded',
function() {
fn();
});
})();
}
Math.randomN = function (min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min);
};
String.isNullOrUndefined = function(value) {
if (typeof (value) == "undefined") {
return true;
}
if (value == null) {
return true;
}
return false;
};
String.isNullOrWhitespace = function(value) {
const a = this;
if (String.isNullOrUndefined(value)) {
return true;
}
if (typeof(value) == "string") {
return (value.trim().length <= 0);
} else {
return (value.toString().trim().length <= 0);
}
};
String.joinIfNotNullOrWhitespace = function (separator, ...values) {
const a = this;
let result = "";
for (let i = 0; i < values.length; i++) {
if (String.isNullOrWhitespace(values[i])) {
continue;
}
if (!String.isNullOrWhitespace(result)) {
result += separator;
}
result += values[i];
};
return result;
};
String.prototype.contains = function(...args) {
for (let arg of args) {
if (this == arg) {
return true;
}
}
return false;
};
String.prototype.containsCI = function(...args) {
for (let arg of args) {
if (this.toLowerCase() == arg.toLowerCase()) {
return true;
}
}
return false;
};
String.prototype.encodeHtmlLinks = function() {
return value.replace(/(http[s]{0,1}:\/\/[^\s]+)/g, "<a href='$1'>$1</a>");
};
String.prototype.toTitleCase = function () {
let result = this;
result = result.replace(/([A-Z]{1})/g, " $1");
result = result.trim();
result = result.charAt(0).toUpperCase() + result.substr(1);
return result;
};
String.prototype.getFilename = function () {
return this.substring(this.lastIndexOf('/') + 1);
};
Window.goToTop = function() {
Window.scrollTo(0, 0);
};
Window.fragment = {
get: function() {
if (!window.location.hash) {
return null;
}
const n = window.location.hash.indexOf("?");
if (n < 0) {
return window.location.hash.substring(1);
} else {
return window.location.hash.substring(1, n);
}
},
getQuery: function() {
if (!window.location.hash) {
return null;
}
let hashQueryString = window.location.hash;
const n = hashQueryString.indexOf("?");
if (n < 0) {
return null;
}
hashQueryString = hasQueryString.substring(n + 1);
const params = new URLSearchParams(hashQueryString);
const result = {}
for(const [key, value] of params.entries()) {
result[key] = value;
}
return result;
},
clear: function() {
location.hash = "";
history.replaceState("", "", location.pathname);
}
};

5
ryjsxt.min.js vendored

File diff suppressed because one or more lines are too long

157
ryz-gantts-test.html Normal file
View File

@ -0,0 +1,157 @@
<!doctype html>
<html lang="en-GB">
<head>
<meta charset="UTF-8" />
<meta http-equiv="content-type" content="text/html" charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="" />
<meta name="keyword" content="" />
<script src="ryz-js-ext/ryz-js-ext-array.js"></script>
<script src="ryz-js-ext/ryz-js-ext-boolean.js"></script>
<script src="ryz-js-ext/ryz-js-ext-date.js"></script>
<script src="ryz-js-ext/ryz-js-ext-document.js"></script>
<script src="ryz-js-ext/ryz-js-ext-math.js"></script>
<script src="ryz-js-ext/ryz-js-ext-string.js"></script>
<script src="ryz-js-ext/ryz-js-ext-window.js"></script>
<!-- <script src="ryzjsext.min.js"></script> -->
<script src="ryz-gantts.js"></script>
<!-- <script src="bsdialog4.min.js"></script> -->
<title></title>
<style>
.text-sm {
font-size: 0.8em;
}
</style>
<script>
var gantt1 = new RyzGantt({ Name: "New Project 1" });
gantt1.AddTask({
ID: 1,
Name: "Task A",
StartDelay: 0,
Duration: 1,
DependsOnTaskID: null,
IsCollated: false,
CollatedTaskID: null
});
gantt1.AddTask({
ID: 2,
Name: "Task B",
StartDelay: 1,
Duration: 1,
DependsOnTaskID: 1,
IsCollated: false,
CollatedTaskID: null
});
gantt1.AddTask({
ID: 3,
Name: "Task C",
StartDelay: 5,
Duration: 1,
DependsOnTaskID: null,
IsCollated: false,
CollatedTaskID: null
});
gantt1.AddTask({
ID: 4,
Name: "Task D",
StartDelay: 1,
Duration: 1,
DependsOnTaskID: 3,
IsCollated: false,
CollatedTaskID: null
});
gantt1.AddTask({
ID: 5,
Name: "Task B1",
StartDelay: 4,
Duration: 1,
DependsOnTaskID: 2,
IsCollated: true,
CollatedTaskID: null
});
gantt1.AddTask({
ID: 6,
Name: "Task B11",
StartDelay: 0,
Duration: 1,
DependsOnTaskID: null,
IsCollated: false,
CollatedTaskID: 5
});
gantt1.AddTask({
ID: 7,
Name: "Task B12",
StartDelay: 0,
Duration: 7,
DependsOnTaskID: null,
IsCollated: false,
CollatedTaskID: 5
});
gantt1.AddTask({
ID: 8,
Name: "Task E",
StartDelay: 3,
Duration: 1,
DependsOnTaskID: null,
IsCollated: true,
CollatedTaskID: null
});
gantt1.AddTask({
ID: 9,
Name: "Task E1",
StartDelay: 3,
Duration: 1,
DependsOnTaskID: null,
IsCollated: false,
CollatedTaskID: 8
});
gantt1.InvalidateTasks();
console.log(gantt1.ExportTasks);
// console.log(gantt1.Tasks);
// var dataSet = [
// { key: "b", value: "B2", num: 2, f: 2.2, date: new Date(2001, 2, 2) },
// { key: "d", value: "D4", num: 4, f: 4.4, date: new Date(2001, 4, 4) },
// { key: "a", value: "A1", num: 1, f: 1.1, date: new Date(2001, 10, 1) },
// { key: "e", value: "E5", num: 5, f: 5.5, date: new Date(2001, 5, 5) },
// { key: "c", value: "C3", num: 3, f: 3.3, date: new Date(2001, 3, 3) }
// ];
// // let result = dataSet.index("key", "d");
// //dataSet = dataSet.orderBy("date");
// dataSet = dataSet.orderByDesc("date");
// console.log(result);
// console.log(dataSet);
</script>
</head>
<body>
</body>
</html>

421
ryz-gantts.js Normal file
View File

@ -0,0 +1,421 @@
class RyzGantt {
constructor(options) {
const a = this;
const _options = Object.assign(a.NewProject, options);
a.Project = _options;
a.Tasks = [];
}
initialiseComponents() {
const a = this;
}
get NewProject() {
return {
Name: "",
Description: "",
StartDate: Date.today(),
Tag: null,
StartOfWeek: 1, // Monday
WorkHours: [0, 7.5, 7.5, 7.5, 7.5, 7.5, 0] // 0 = Sunday
};
}
get NewTask() {
return {
// Order: null,
ID: null,
Name: "",
Description: "",
Tag: null,
// StartDate: null, // new Date(),
// FinishDate: null, // new Date(),
StartDelay: 0, // Days
Duration: 1, // Days
DependsOnTaskID: null,
IsCollated: false,
CollatedTaskID: null,
// CalcWorkHours: 0,
ActuWorkHours: null
};
}
get NewTaskNode() {
return {
Order: null,
ID: null,
Name: "",
Description: "",
Tag: null,
StartDate: null, // new Date(),
FinishDate: null, // new Date(),
StartDelay: 0, // Days
Duration: 1, // Days
DependsOnTaskID: null,
IsCollated: false,
CollatedTaskID: null,
CalcWorkHours: 0,
ActuWorkHours: null,
Tasks: []
};
}
get ExportTasks() {
const a = this;
let result = [];
a.#exportTasks(result, a.Tasks.copy());
for (var i=0; i<result.length; i++) {
result[i].Order = (i + 1);
delete result[i].Tasks;
}
return result;
}
AddTask(task) {
const a = this;
const newTask = Object.assign(a.NewTask, task);
const newTaskNode = Object.assign(a.NewTaskNode, newTask);
if ((newTaskNode.DependsOnTaskID == null) && (newTaskNode.CollatedTaskID == null)) {
a.Tasks.push(newTaskNode);
} else if (newTaskNode.DependsOnTaskID != null) {
const node = a.FindTask(newTaskNode.DependsOnTaskID);
if (node != null) {
node.Tasks.push(newTaskNode);
} else {
a.#log("Task not found (" + newTaskNode.DependsOnTaskID + ")");
}
} else if (newTaskNode.CollatedTaskID != null) {
const node = a.FindTask(newTaskNode.CollatedTaskID);
if (node != null) {
node.Tasks.push(newTaskNode);
} else {
a.#log("Task not found (" + newTaskNode.CollatedTaskID + ")");
}
} else {
a.#log("Task not found (" + newTaskNode.ID + ")");
}
}
ClearTasks() {
const a = this;
a.Tasks = [];
}
FindTask(id) {
const a = this;
return a.#searchForTaskID(a.Tasks, id);
}
/**
* Get node type.
* @returns {int} enum
*
* 0 = orphan
* 1 = task no-parent/root
* 2 = task no-parent/root, collated/group
* 3 = task with parent
* 4 = task with parent, collated/group
* 5 = sub-task
* 6 = sub-task, collated/group
*
*/
GetNodeType(node) {
if (node == null) {
// 0 = orphan
return 0;
}
if ((node.DependsOnTaskID == null) && (node.CollatedTaskID == null) && (node.IsCollated == false)) {
// 1 = task no-parent/root
return 1;
}
if ((node.DependsOnTaskID == null) && (node.CollatedTaskID == null) && (node.IsCollated == true)) {
// 2 = task no-parent/root, collated/group
return 2;
}
if ((node.DependsOnTaskID != null) && (node.CollatedTaskID == null) && (node.IsCollated == false)) {
// 3 = task with parent
return 3;
}
if ((node.DependsOnTaskID != null) && (node.CollatedTaskID == null) && (node.IsCollated == true)) {
// 4 = task with parent, collated/group
return 4;
}
if ((node.CollatedTaskID != null) && (node.IsCollated == false)) {
// 5 = sub-task
return 5;
}
if ((node.CollatedTaskID != null) && (node.IsCollated == true)) {
// 6 = sub-task, collated/group
return 6;
}
return 0;
}
InvalidateTasks() {
const a = this;
// a.#log(a.Tasks.copy());
a.Recalc();
// a.#log(a.Tasks.copy());
// return;
// a.#resetTasks();
// console.log("Original");
// console.log(a.Tasks.copy());
// // Get root nodes
// let nodes = a.Tasks.selectMany(
// { propName: "DependsOnTaskID", value: null },
// { propName: "CollatedTaskID", value: null }
// );
// nodes.orderBy("StartDelay");
// a.Tasks.removeRange(nodes);
// console.log("Root");
// console.log(a.Tasks.copy());
// console.log(nodes.copy());
// //
// for (let i=(nodes.length - 1); i>=0; i--) {
// // Find dependent tasks
// let foundNodes = a.Tasks.select("DependsOnTaskID", nodes[i].ID);
// foundNodes.forEach(e => {
// nodes.insert((i + 1), e);
// });
// a.Tasks.removeRange(foundNodes);
// // Add child tasks
// if (nodes[i].IsCollated == true) {
// foundNodes = a.Tasks.select("CollatedTaskID", nodes[i].ID);
// foundNodes.forEach(e => {
// nodes.insert((i + 1), e);
// });
// a.Tasks.removeRange(foundNodes);
// }
// }
// // console.log(a.Tasks.copy());
// // a.Tasks = a.#findTasksL0(a.Tasks);
// console.log("Final");
// console.log(a.Tasks.copy());
// console.log(nodes.copy());
}
// #popL0Tasks(array) {
// const a = this;
// let nodes = array.selectMany(
// { propName: "DependsOnTaskID", value: null },
// { propName: "CollatedTaskID", value: null }
// );
// nodes = nodes.orderBy("StartDelay");
// array.removeRange(nodes);
// return nodes;
// }
// #addTasks(sourceTasksArray, targetTasksArray, index) {
// const a = this;
// const nodes = sourceTasksArray.select("DependsOnTaskID", targetTasksArray[index].ID);
// for (let i=0; i<nodes.length; i++) {
// targetTasksArray.insert((index + 1), nodes[i]);
// }
// sourceTasksArray.removeRange(nodes);
// }
Recalc() {
const a = this;
a.Sort();
// Get flat reference
let result = [];
a.#exportTasks(result, a.Tasks);
// Reset calculated values
for (var i=0; i<result.length; i++) {
result[i].Order = (i + 1);
result[i].StartDate = null;
result[i].FinishDate = null;
result[i].CalcWorkHours = null;
}
for (var i=0; i<result.length; i++) {
const nodeType = a.GetNodeType(result[i]);
switch (nodeType) {
case 1: // task no-parent/root
result[i].StartDate = Date.addDays(a.Project.StartDate, result[i].StartDelay);
result[i].FinishDate = Date.addDays(result[i].StartDate, result[i].Duration);
break;
case 2: // task no-parent/root, collated/group
break;
case 3: // task with parent
const node = result.first("ID", result[i].DependsOnTaskID);
if (node != null) {
if (node.FinishDate != null) {
result[i].StartDate = Date.addDays(node.FinishDate, result[i].StartDelay);
result[i].FinishDate = Date.addDays(result[i].StartDate, result[i].Duration);
}
}
break;
case 4: // task with parent, collated/group
break;
case 5: // sub-task
break;
case 6: // sub-task, collated/group
break;
default: // orphan
break;
}
}
// a.#resetTasks(a.Tasks);
// a.#recalcTasks(a.Project.StartDate, a.Tasks);
}
Sort() {
const a = this;
a.#sortTasks(a.Tasks);
}
#exportTasks(outputArray, array) {
const a = this;
for (let i=0; i<array.length; i++) {
outputArray.push(array[i]);
if (array[i].Tasks.length > 0) {
a.#exportTasks(outputArray, array[i].Tasks);
}
}
}
#log(message) {
console.log(message);
}
// #recalcTasks(startDate, array) {
// const a = this;
// for (let i=0; i<array.length; i++) {
// array[i].Order = null;
// array[i].StartDate = Date.addDays(startDate, array[i].StartDelay);
// array[i].FinishDate = null;
// // array[i].CalcWorkHours = null;
// if (array[i].IsCollated == true) {
// if (array[i].Tasks.length > 0) {
// a.#recalcTasks(array[i].StartDate, array[i].Tasks);
// }
// } else {
// array[i].FinishDate = Date.addDays(array[i].StartDate, array[i].Duration);
// if (array[i].Tasks.length > 0) {
// a.#recalcTasks(array[i].FinishDate, array[i].Tasks);
// }
// }
// // if (array[i].Tasks.length > 0) {
// // a.#recalcTasks(array[i].StartDate, array[i].Tasks);
// // }
// }
// }
// #resetTasks(array) {
// const a = this;
// for (let i=0; i<array.length; i++) {
// array[i].Order = null;
// array[i].StartDate = null;
// array[i].FinishDate = null;
// array[i].CalcWorkHours = null;
// if (array[i].Tasks.length > 0) {
// a.#resetTasks(array[i].Tasks);
// }
// }
// }
#searchForTaskID(array, id) {
const a = this;
for (let i=0; i<array.length; i++) {
if (array[i].ID == id) {
return array[i];
}
if (array[i].Tasks.length > 0) {
const result = a.#searchForTaskID(array[i].Tasks, id);
if (result != null) {
return result;
}
}
}
return null;
}
#sortTasks(array) {
const a = this;
array.orderBy("StartDelay");
for (let i=0; i<array.length; i++) {
if (array[i].Tasks.length <= 0) {
continue;
}
array[i].Tasks.orderBy("StartDelay");
}
}
}

View File

@ -0,0 +1,183 @@
Array.prototype.addRange = function (array) {
if (array == null) {
return this;
}
for (let i = 0; i < array.length; i++) {
this.push(array[i]);
}
return this;
};
Array.prototype.copy = function () {
return JSON.parse(JSON.stringify(this));
};
Array.prototype.index = function (propName, value) {
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
continue;
}
if (this[i][propName] == value){
return i;
}
}
return -1;
};
Array.prototype.insert = function(index, item) {
if (index < 0) {
this.splice(0, 0, item);
} else if (index >= this.length) {
this.push(item);
} else {
this.splice(index, 0, item);
}
return this;
};
Array.prototype.joinIfNotNullOrWhitespace = function (separator) {
const a = this;
let result = "";
for (let i = 0; i < this.length; i++) {
if (String.isNullOrWhitespace(this[i])) {
continue;
}
if (!String.isNullOrWhitespace(result)) {
result += separator;
}
result += this[i];
};
return result;
};
Array.prototype.first = function (propName, value) {
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
continue;
}
if (this[i][propName] == value){
return this[i];
}
}
return null;
};
Array.prototype.indexes = function (propName, value) {
let result = [];
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
continue;
}
if (this[i][propName] == value){
result.push(i);
}
}
return result;
};
Array.prototype.orderBy = function (propName) {
this.sort(function(a, b) {
if (a[propName] < b[propName]) {
return -1;
} else if (a[propName] > b[propName]) {
return 1;
} else {
return 0;
}
});
return this;
};
Array.prototype.orderByDesc = function (propName) {
this.sort(function(a, b) {
if (a[propName] < b[propName]) {
return 1;
} else if (a[propName] > b[propName]) {
return -1;
} else {
return 0;
}
});
return this;
};
Array.prototype.remove = function (element) {
let result = [];
for (let i=0; i<this.length; i++) {
if (this[i] == element) {
result.push(i);
}
}
for (let i=(result.length - 1); i>=0; i--) {
this.removeAt(result[i]);
}
return this;
};
Array.prototype.removeAt = function(index) {
if ((index < 0) || (index >= this.length)) {
return this;
}
this.splice(index, 1);
return this;
};
Array.prototype.removeRange = function (array) {
for (let i=0; i<array.length; i++) {
this.remove(array[i]);
}
return this;
};
/**
* Find elements where a property equals a value.
* @returns {Array} Of elements found.
*/
Array.prototype.select = function (propName, value) {
let result = [];
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
continue;
}
if (this[i][propName] == value){
result.push(this[i]);
}
}
return result;
};
Array.prototype.selectMany = function (...filters) {
let result = this;
filters.forEach(e => {
result = result.select(e.propName, e.value);
});
return result;
};

View File

@ -0,0 +1,25 @@
Boolean.isFalse = function(value) {
const a = this;
if (String.isNullOrUndefined(value)) {
return true;
}
return value.toString().containsCI("false", "f", "y", "0", "x");
};
Boolean.isTrue = function(value) {
const a = this;
if (String.isNullOrUndefined(value)) {
return false;
}
return value.toString().containsCI("true", "t", "n", "1", "o");
};
Boolean.ifTrue = function(value, trueValue, falseValue) {
const a = this;
return (Boolean.isTrue(value) ? trueValue : falseValue);
};

View File

@ -0,0 +1,93 @@
Date.addDays = function (date, days) {
let result = new Date(date);
result.addDays(days);
return result;
};
Date.addMonths = function (date, months) {
let result = new Date(date);
result.addMonths(months);
return result;
};
Date.addYears = function (date, years) {
let result = new Date(date);
result.addYears(years);
return result;
};
Date.today = function () {
let result = new Date();
result.setHours(0);
result.setMinutes(0);
result.setSeconds(0);
result.setMilliseconds(0);
return result;
};
Date.prototype.addDays = function (days) {
this.setDate(this.getDate() + parseInt(days));
}
Date.prototype.addMonths = function (months) {
this.setMonth(this.getMonth() + parseInt(months));
}
Date.prototype.addYears = function (years) {
this.setFullYear(this.getFullYear() + parseInt(years));
}
Date.prototype.toCString = function(pattern) {
let result = pattern;
result = result.replace("fffffff", this.getMilliseconds().toString().padStart(7, '0'));
result = result.replace("ffffff", this.getMilliseconds().toString().padStart(6, '0'));
result = result.replace("fffff", this.getMilliseconds().toString().padStart(5, '0'));
result = result.replace("yyyy", this.getFullYear().toString().padStart(4, '0'));
result = result.replace("MMMM", "{1}");
result = result.replace("dddd", "{2}");
result = result.replace("ffff", this.getMilliseconds().toString().padStart(4, '0'));
result = result.replace("yyy", this.getFullYear().toString().padStart(3, '0'));
result = result.replace("MMM", "{3}");
result = result.replace("ddd", "{4}");
result = result.replace("fff", this.getMilliseconds().toString().padStart(3, '0'));
result = result.replace("zzz", "");
result = result.replace("yy", this.getFullYear().toString().slice(-2));
result = result.replace("MM", (this.getMonth() + 1).toString().padStart(2, '0'));
result = result.replace("dd", this.getDate().toString().padStart(2, '0'));
result = result.replace("HH", this.getHours().toString().padStart(2, '0'));
result = result.replace("hh", (this.getHours() > 12 ? (this.getHours() - 12) : this.getHours()).toString().padStart(2, '0'));
result = result.replace("mm", this.getMinutes().toString().padStart(2, '0'));
result = result.replace("ss", this.getSeconds().toString().padStart(2, '0'));
result = result.replace("ff", this.getMilliseconds().toString().padStart(2, '0'));
result = result.replace("tt", "{5}");
result = result.replace("zz", "");
result = result.replace("y", this.getFullYear().toString());
result = result.replace("M", (this.getMonth() + 1).toString());
result = result.replace("d", this.getDate().toString());
result = result.replace("H", this.getHours().toString());
result = result.replace("h", (this.getHours() > 12 ? (this.getHours() - 12) : this.getHours()).toString());
result = result.replace("m", this.getMinutes().toString());
result = result.replace("s", this.getSeconds().toString());
result = result.replace("z", "");
result = result.replace("t", "{6}");
result = result.replace("Z", "");
result = result.replace("{1}", this.toLocaleString('default', { month: 'long' }));
result = result.replace("{2}", this.toLocaleString('default', { weekday: 'long' }));
result = result.replace("{3}", this.toLocaleString('default', { month: 'short' }));
result = result.replace("{4}", this.toLocaleString('default', { weekday: 'short' }));
result = result.replace("{5}", (this.getHours() >= 12 ? "PM" : "AM"));
result = result.replace("{6}", (this.getHours() >= 12 ? "P" : "A"));
return result;
}

View File

@ -0,0 +1,9 @@
Document.ready = async function(fn) {
(async function() {
(document.readyState !== 'loading') ?
fn() : document.addEventListener('DOMContentLoaded',
function() {
fn();
});
})();
}

View File

@ -0,0 +1,6 @@
Math.randomN = function (min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min);
};

View File

@ -0,0 +1,83 @@
String.isNullOrUndefined = function(value) {
if (typeof (value) == "undefined") {
return true;
}
if (value == null) {
return true;
}
return false;
};
String.isNullOrWhitespace = function(value) {
const a = this;
if (String.isNullOrUndefined(value)) {
return true;
}
if (typeof(value) == "string") {
return (value.trim().length <= 0);
} else {
return (value.toString().trim().length <= 0);
}
};
String.joinIfNotNullOrWhitespace = function (separator, ...values) {
const a = this;
let result = "";
for (let i = 0; i < values.length; i++) {
if (String.isNullOrWhitespace(values[i])) {
continue;
}
if (!String.isNullOrWhitespace(result)) {
result += separator;
}
result += values[i];
};
return result;
};
String.prototype.contains = function(...args) {
for (let arg of args) {
if (this == arg) {
return true;
}
}
return false;
};
String.prototype.containsCI = function(...args) {
for (let arg of args) {
if (this.toLowerCase() == arg.toLowerCase()) {
return true;
}
}
return false;
};
String.prototype.encodeHtmlLinks = function() {
return value.replace(/(http[s]{0,1}:\/\/[^\s]+)/g, "<a href='$1'>$1</a>");
};
String.prototype.toTitleCase = function () {
let result = this;
result = result.replace(/([A-Z]{1})/g, " $1");
result = result.trim();
result = result.charAt(0).toUpperCase() + result.substr(1);
return result;
};
String.prototype.getFilename = function () {
return this.substring(this.lastIndexOf('/') + 1);
};

View File

@ -0,0 +1,43 @@
Window.goToTop = function() {
Window.scrollTo(0, 0);
};
Window.fragment = {
get: function() {
if (!window.location.hash) {
return null;
}
const n = window.location.hash.indexOf("?");
if (n < 0) {
return window.location.hash.substring(1);
} else {
return window.location.hash.substring(1, n);
}
},
getQuery: function() {
if (!window.location.hash) {
return null;
}
let hashQueryString = window.location.hash;
const n = hashQueryString.indexOf("?");
if (n < 0) {
return null;
}
hashQueryString = hasQueryString.substring(n + 1);
const params = new URLSearchParams(hashQueryString);
const result = {}
for(const [key, value] of params.entries()) {
result[key] = value;
}
return result;
},
clear: function() {
location.hash = "";
history.replaceState("", "", location.pathname);
}
};

4
ryzjsext.min.js vendored Normal file
View File

@ -0,0 +1,4 @@
/**
* Ray's JavaScript Extension
* @version v0.1.0.021 (2023/12/11 0056)
*/