diff --git a/xp/boot/assets/logo.png b/xp/boot/assets/logo.png
new file mode 100644
index 00000000..21f3cacc
Binary files /dev/null and b/xp/boot/assets/logo.png differ
diff --git a/xp/boot/assets/progress.gif b/xp/boot/assets/progress.gif
new file mode 100644
index 00000000..ccc66a56
Binary files /dev/null and b/xp/boot/assets/progress.gif differ
diff --git a/xp/boot/boot.css b/xp/boot/boot.css
new file mode 100644
index 00000000..bf0d970a
--- /dev/null
+++ b/xp/boot/boot.css
@@ -0,0 +1,29 @@
+body {
+ padding: 0;
+ margin: 0;
+}
+._ui_boot {
+ background: #000000;
+ width: 100%;
+ height: 100%;
+}
+._ui_boot_logo {
+ height: 150px;
+ width: 126px;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin: -75px 0 0 -63px;
+}
+._ui_boot_winlogo {
+ background-image: url("assets/logo.png");
+ width: 118px;
+ height: 104px;
+}
+._ui_boot_progress {
+ background-image: url("assets/progress.gif");
+ width: 126px;
+ height: 15px;
+ position: absolute;
+ bottom: 0;
+}
diff --git a/xp/boot/load.js b/xp/boot/load.js
new file mode 100644
index 00000000..86ffbdd9
--- /dev/null
+++ b/xp/boot/load.js
@@ -0,0 +1,150 @@
+var scripts = [
+ 'system/core.js',
+ 'system/window-api.js',
+ 'system/contextmenus.js',
+ 'system/filesystem.js',
+ 'system/xp.js',
+ 'system/jquery.terminal-2.0.0.min.js',
+ 'system/unix_formatting.js',
+ 'program/terminal.js',
+ 'system/script.js',
+ 'system/explorer.js',
+ 'system/help.js',
+ 'program/browser.js',
+ 'program/notepad.js',
+ 'program/imageviewer.js',
+ 'program/mediaplayer.js',
+ 'system/config.js',
+ 'system/controlpanel.js',
+ 'system/uac.js',
+ 'system/uac_app.js',
+ 'system/audio.js',
+ 'system/lambda.js',
+ 'program/minesweeper.js',
+ 'program/paint.js',
+ '//xpstore.glitch.me/appstore.js',
+ 'boot/boot.js'
+];
+var stylesheets = [
+ 'system/fonts.css',
+ 'system/xp.css',
+ 'system/icons.css',
+ 'system/widgets.css',
+ 'system/window.css',
+ 'system/contextmenus.css',
+ 'system/cursors.css',
+ 'system/desktop.css',
+ 'system/startmenu.css',
+ 'system/explorer.css',
+ 'system/jquery.terminal-2.0.0.min.css'
+];
+var requiredDirectories = [];
+
+$(function() {
+ $('windows').html(`
+
`);
+ console.log('Loading scripts and stylesheets...');
+ $('', {rel: 'stylesheet', href: 'boot/boot.css'}).appendTo('head');
+ var scriptsindex = 0;
+ var stylesindex = 0;
+
+ function loadStylesheets() {
+ $.ajax({
+ url: stylesheets[stylesindex],
+ dataType: "script",
+ success: function(data){
+ $("head").append("");
+ stylesindex ++;
+ if (stylesindex < stylesheets.length) {
+ loadStylesheets();
+ } else {
+ loadScripts();
+ }
+ }
+ });
+ }
+
+ function loadScripts() {
+ $.ajax({
+ url: scripts[scriptsindex],
+ dataType: "script",
+ success: function(data){
+ scriptsindex ++;
+ if (scriptsindex < scripts.length) {
+ loadScripts();
+ } else {
+ console.log('Finished loading');
+ console.log('Checking for necessary directories');
+
+ function checkDir(path, callback) {
+ var times = 0;
+ xp.filesystem.listDir(path, (e) => {
+ if (times === 0)
+ callback(typeof e === 'string');
+ times ++;
+ });
+ }
+
+ var i = 0;
+ function checkNextDir(t) {
+ var dirToCreate = requiredDirectories[i];
+ if (dirToCreate !== undefined) {
+ xp.filesystem.createDir(dirToCreate, (e) => {
+ i ++;
+ checkNextDir();
+ });
+ } else {
+ xp.audio.init();
+ var event = new Event('xpboot');
+ window.dispatchEvent(event);
+ console.log('Dispatched boot event');
+ $('windows').html('');
+ $.getScript('system/login.js');
+ xp.audio.playURL('boot/assets/startup.wav');
+ }
+ }
+
+ xp.filesystem.create(512*1024*1024, () => {
+ xp.filesystem.fs.root.getDirectory('/', {create: false}, function(dirEntry) {
+ var dirReader = dirEntry.createReader();
+ var entries = [];
+
+ function readEntries() {
+ dirReader.readEntries (function(results) {
+ if (results.length === 0) {
+ $('._ui_boot').remove();
+ $('windows').html('');
+ $.getScript('setup/setup.js');
+ } else {
+ xp.filesystem.createDir('/WINDOWS', (e) => {
+ requiredDirectories = [
+ '/WINDOWS',
+ '/WINDOWS/system32',
+ '/WINDOWS/startup',
+ '/Program Files',
+ '/Documents and Settings'
+ ];
+ checkNextDir();
+ });
+ }
+ }, console.error);
+ };
+
+ readEntries();
+ }, console.error);
+ });
+ }
+ }
+ });
+ }
+
+ loadStylesheets();
+});
diff --git a/xp/index.html b/xp/index.html
new file mode 100644
index 00000000..d43f93dd
--- /dev/null
+++ b/xp/index.html
@@ -0,0 +1,24 @@
+
+
+ RebornXP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xp/program/browser.js b/xp/program/browser.js
new file mode 100644
index 00000000..e5412e65
--- /dev/null
+++ b/xp/program/browser.js
@@ -0,0 +1,102 @@
+function browserGo(loc, guid) {
+ if(!loc){
+ loc = document.getElementById('url_' + guid).value;
+ }
+ if (loc.indexOf('http://') == -1 && loc.indexOf('https://') == -1) {
+ loc = location.protocol + '//' + loc;
+ }
+ document.getElementById('webPage_' + guid).src = loc;
+ document.getElementById('url_' + guid).value = loc;
+ document.getElementById('loading_' + guid).style.display = 'block';
+ document.getElementById('webPage_' + guid).style.display = 'none';
+}
+function iframeContentUnload(guid) {
+ document.getElementById('loading_' + guid).style.display = 'block';
+ document.getElementById('webPage_' + guid).style.display = 'none';
+}
+function iframeContentLoaded(guid) {
+ document.getElementById('loading_' + guid).style.display = 'none';
+ document.getElementById('webPage_' + guid).style.display = 'block';
+}
+
+$(window).on('xpboot', function() {
+ xp.applications.add('browser', (args) => {
+ var guid = generate_guid();
+ var el = $.parseHTML(`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `);
+ document.body.appendChild(el[0]);
+ $(el).updateWindow();
+ var widthOffset = 30;
+ var heightOffset = 80;
+ window.iFrameChanges = -1;
+ });
+
+ xp.applications.add('html', (args) => {
+ var el = $.parseHTML(`
+
+
+
+
+ `);
+ document.body.appendChild(el[0]);
+ $(el).updateWindow();
+ });
+
+ xp.startmenu.add('browser', 'Idiot Explorer 6', 'program/assets/ie.webp');
+});
diff --git a/xp/program/imageviewer.js b/xp/program/imageviewer.js
new file mode 100644
index 00000000..9183d264
--- /dev/null
+++ b/xp/program/imageviewer.js
@@ -0,0 +1,18 @@
+$(window).on('xpboot', () => {
+ xp.applications.add('image-viewer', (args) => {
+ var image = args.length > 1 ? xp.filesystem.addPaths(args[0], args[1]) : '';
+ var imagename = xp.filesystem.basename(image);
+ var win = new Window({
+ width: 640,
+ height: 480,
+ title: image === '' ? 'Image Viewer' : (imagename + ' - Image Viewer')
+ });
+ xp.filesystem.toURL(image, (url) => {
+ win.content('');
+ });
+ });
+ explorer.fileHandlers.add('png', (f) => openApp('image-viewer', ['', f]));
+ explorer.fileHandlers.add('jpg', (f) => openApp('image-viewer', ['', f]));
+ explorer.fileHandlers.add('jpeg', (f) => openApp('image-viewer', ['', f]));
+ explorer.fileHandlers.add('gif', (f) => openApp('image-viewer', ['', f]));
+});
\ No newline at end of file
diff --git a/xp/program/mediaplayer.js b/xp/program/mediaplayer.js
new file mode 100644
index 00000000..0a079d2b
--- /dev/null
+++ b/xp/program/mediaplayer.js
@@ -0,0 +1,23 @@
+$(window).on('xpboot', () => {
+ xp.applications.add('media-player', (args) => {
+ var video = args.length > 1 ? xp.filesystem.addPaths(args[0], args[1]) : '';
+ var videoname = xp.filesystem.basename(video);
+ var win = new Window({
+ width: 480,
+ height: 360,
+ title: video === '' ? 'Media Player' : (videoname + ' - Media Player')
+ });
+ xp.filesystem.toURL(video, (url) => {
+ win.content(``);
+ });
+ });
+ explorer.fileHandlers.add('webm', (f) => openApp('media-player', ['', f]));
+ explorer.fileHandlers.add('wav', (f) => openApp('media-player', ['', f]));
+ explorer.fileHandlers.add('ogg', (f) => openApp('media-player', ['', f]));
+ explorer.fileHandlers.add('ogv', (f) => openApp('media-player', ['', f]));
+ explorer.fileHandlers.add('mp3', (f) => openApp('media-player', ['', f]));
+ explorer.fileHandlers.add('mp4', (f) => openApp('media-player', ['', f]));
+ explorer.fileHandlers.add('flac', (f) => openApp('media-player', ['', f]));
+});
\ No newline at end of file
diff --git a/xp/program/minesweeper.js b/xp/program/minesweeper.js
new file mode 100644
index 00000000..bae4a8c9
--- /dev/null
+++ b/xp/program/minesweeper.js
@@ -0,0 +1,30 @@
+$(window).on('xpboot', () => {
+ xp.applications.add('minesweeper', () => {
+ var el = $.parseHTML(`
+
+
+
+
+
+
+ `);
+ document.body.appendChild(el[0]);
+ $(el).updateWindow();
+ });
+ xp.startmenu.add('minesweeper', 'Minesweeper', 'https://w7.pngwing.com/pngs/337/559/png-transparent-minesweeper-computer-icons-bing-maps-video-game-mines-miscellaneous-game-angle.png');
+});
diff --git a/xp/program/notepad.js b/xp/program/notepad.js
new file mode 100644
index 00000000..d5dd927a
--- /dev/null
+++ b/xp/program/notepad.js
@@ -0,0 +1,56 @@
+$(window).on('xpboot', () => {
+ xp.applications.add('notepad', (args) => {
+ var guid = generate_guid();
+ var el = $.parseHTML(`
+
+`);
+ document.body.appendChild(el[0]);
+ $(el).updateWindow();
+ $(el).addMenu("File", [
+ ["New", function() {
+ $("#notepad_" + guid).val("");
+ $("#notepad_" + guid).attr('filename', '');
+ }],
+ ["Open", function() {
+ xp.filesystem.openFileDialog((filename) => {
+ xp.filesystem.readFile(filename, function(e) {
+ //e = e.split("\0")[0];
+ $("#notepad_" + guid).val(e);
+ $("#notepad_" + guid).attr("filename", filename);
+ });
+ });
+ }],
+ ["Save", function() {
+ var filename = $("#notepad_" + guid).attr("filename");
+ if (filename === "") {
+ xp.filesystem.saveFileDialog((filename) => {
+ xp.filesystem.writeFile(filename, new Blob([$("#notepad_" + guid).val()], {type: 'text/plain'}), (e) => {
+ if (e) xp.dialog('Error', e);
+ });
+ });
+ } else {
+ xp.filesystem.writeFile(filename, new Blob([$("#notepad_" + guid).val()], {type: 'text/plain'}), (e) => {
+ if (e) xp.dialog('Error', e);
+ });
+ }
+ }],
+ ["Save As", function() {
+ xp.filesystem.saveFileDialog((filename) => {
+ xp.filesystem.writeFile(filename, new Blob([$("#notepad_" + guid).val()], {type: 'text/plain'}), (e) => {
+ if (e) xp.dialog('Error', e);
+ });
+ });
+ }]
+ ]);
+
+ if (args !== undefined && args[1] !== undefined) {
+ var filename = xp.filesystem.addPaths(args[0], args[1]);
+ xp.filesystem.readFile(filename, function(e) {
+ //e = e.split("\0")[0];
+ $("#notepad_" + guid).val(e);
+ $("#notepad_" + guid).attr("filename", filename);
+ });
+ }
+ });
+ xp.startmenu.add('notepad', 'Notepad', '//cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fnotepad.png?1521328884236');
+});
\ No newline at end of file
diff --git a/xp/program/paint.js b/xp/program/paint.js
new file mode 100644
index 00000000..88e6e05b
--- /dev/null
+++ b/xp/program/paint.js
@@ -0,0 +1,30 @@
+$(window).on('xpboot', () => {
+ xp.applications.add('paint', () => {
+ var el = $.parseHTML(`
+
+
+
+
+
+
+ `);
+ document.body.appendChild(el[0]);
+ $(el).updateWindow();
+ });
+ xp.startmenu.add('paint', 'Paint', 'https://raw.githubusercontent.com/1j01/jspaint/master/images/icons/512x512.png');
+});
diff --git a/xp/program/terminal.js b/xp/program/terminal.js
new file mode 100644
index 00000000..43618d48
--- /dev/null
+++ b/xp/program/terminal.js
@@ -0,0 +1,94 @@
+var terminalicon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACOUlEQVRYhe2Xv2sTYRjHP8/lvSRN27QipUr9UQLFLhVLRVrN4CQ5cKjg6uIgpQgObi6d+0/o0NHBpZCAVQqigw4VC9GAixAbpNGmMUnT/LjXoV4IJk3AXFLBfuG45w6e5/u55+6euxf+U4kTGEdiPzOjWFoyDkiu3ptDzAfjI9MWWqRdbif6sv3uhbGXe+zPbL0NFgM/U6nVgvLJ5dfjE2MycWmym94EzX1Ob47M5zOF+cTGk4WMKqwCBTU+OSYJdYrEx0zHJgN+xcObE6zH08STWRZvhFiPpwl+WuOResYd7vLhcxa/Lfd1pRIHvqpE31kYGurYHACfB0wvDA7Aibp4eBhKXuYC22z09yO71WBVjGnglbp2DsJX+twBAIr8YDYEsyGzFhMKs0KYQeDk5hp5W5uGiBdAhdUWy9cvugbQThdurZAXEWxtwFG9hnU6BmgAiEQiaK1rWyQSaUjSWncPIBqNYlkWIoJlWUSj0aaJzcBcAQCIxWK1vdRNZ+fKW4G5AnCYHBgH0I0uNAVwCjvPQzO51QXVrrBlWbVYa93QBef8YZI2H9gGgD/ve6tiznE7k1b69+bAMcAxQK+l0rtlpqamemaYK9u/B4doAPXyfarI+UVTS6+6UcDQdr7iMfYBVCr+dEFKxduCDoJuGExdUEWQHY/HnwRQYujnVY+8Mcu2F1s8Xbc3dLXis4umLmYB1F5VfT9Tyu2UywUDRrvuD98wdcBOju5X4GCR2NXlWBu592v1t/oFx8vJxHIFQMwAAAAASUVORK5CYII=';
+
+$(window).on('xpboot', () => {
+ xp.applications.add("terminal", () => {
+ var guid = generate_guid();
+ var el = $.parseHTML(`
+
+ `);
+ document.body.appendChild(el[0]);
+ el = $(el);
+ el.updateWindow();
+ $("#terminal_" + guid).terminal(function(command) {
+ var term = this;
+ if (command !== '') {
+ try {
+ var args = command.split(" ");
+ if (this.dir === undefined)
+ this.dir = [""];
+ if (args[0] === "ls") {
+ xp.filesystem.listDir(xp.filesystem.getDir(this.dir), function(e){if(e){term.echo(e)}});
+ } else if (args[0] === "cd") {
+ if (args[1] === undefined) {
+ this.error("Not enough arguments");
+ } else {
+ let input = args.slice(1).join(' ');
+ if (input !== ".") {
+ if (input.charAt(0) === "/") {
+ this.dir = input.split("/");
+ } else {
+ var foo = input.split("/");
+ var _this = this;
+ foo.forEach(function(val, i) {
+ if (val === "..") {
+ _this.dir.splice(-1,1)
+ } else {
+ _this.dir = _this.dir.concat(val);
+ }
+ });
+ }
+ }
+ }
+ } else if (args[0] === "pwd") {
+ this.echo(xp.filesystem.getDir(this.dir));
+ } else if (args[0] === "touch") {
+ xp.filesystem.createFile(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
+ } else if (args[0] === "rm") {
+ xp.filesystem.deleteFile(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
+ } else if (args[0] === "mkdir") {
+ xp.filesystem.createDir(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
+ } else if (args[0] === "rmdir") {
+ xp.filesystem.deleteDir(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
+ } else if (args[0] === "cat") {
+ xp.filesystem.readFile(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
+ } else if (args[0] === "help") {
+ this.echo("DE: XPerience");
+ this.echo("Kernel: RXP vOS.2023");
+ this.echo("Shell: JQuery Terminal");
+ this.echo("GitHub: github.com/shoaib-jamal/RebornXP");
+ this.echo("\nInstalled applications:");
+ var foo = "";
+ for (var name in xp.applications.apps) {
+ foo += name + ", ";
+ }
+ foo = foo.slice(0, -2);
+ this.echo(foo);
+ this.echo("\nSystem commands:");
+ this.echo("ls, cd, pwd, touch, rm, mkdir, rmdir, cat, help");
+ } else if (xp.applications.apps[args[0]] !== undefined) {
+ xp.applications.apps[args[0]]([xp.filesystem.getDir(this.dir)].concat(args.slice(1)));
+ } else {
+ var result = window.eval(command);
+ if (result !== undefined) {
+ this.echo(new String(result));
+ }
+ }
+ } catch(e) {
+ this.error(new String(e));
+ }
+ } else {
+ this.echo('');
+ }
+ }, {
+ greetings: `
+ RebornXP [vOS.2023]
+ (c) RebornXP Open-Source Project. All rights reserved.
+`,
+ name: 'xpjs_terminal',
+ width: '100%',
+ height: '100%',
+ prompt: '> '
+ });
+ });
+ xp.startmenu.add("terminal", "Terminal", terminalicon);
+});
diff --git a/xp/system/audio.js b/xp/system/audio.js
new file mode 100644
index 00000000..63b91c1b
--- /dev/null
+++ b/xp/system/audio.js
@@ -0,0 +1,38 @@
+xp.audio = {
+ context: null,
+ cache: {},
+ init: function() {
+ try {
+ window.AudioContext = window.AudioContext || window.webkitAudioContext;
+ xp.audio.context = new AudioContext();
+ }
+ catch(e) {
+ console.error('Web Audio API is not supported in this browser');
+ }
+ },
+ playURL: function(url) {
+ if (xp.audio.cache[url] !== undefined) {
+ var source = xp.audio.context.createBufferSource();
+ source.buffer = xp.audio.cache[url];
+ source.connect(xp.audio.context.destination);
+ source.start(0);
+ } else {
+ var request = new XMLHttpRequest();
+ request.open('GET', url, true);
+ request.responseType = 'arraybuffer';
+ request.onload = function() {
+ if (xp.audio.context === null) {
+ xp.audio.init();
+ }
+ xp.audio.context.decodeAudioData(request.response, function(buffer) {
+ var source = xp.audio.context.createBufferSource();
+ source.buffer = buffer;
+ xp.audio.cache[url] = buffer;
+ source.connect(xp.audio.context.destination);
+ source.start(0);
+ }, console.error);
+ }
+ request.send();
+ }
+ }
+};
\ No newline at end of file
diff --git a/xp/system/config.js b/xp/system/config.js
new file mode 100644
index 00000000..a71602b3
--- /dev/null
+++ b/xp/system/config.js
@@ -0,0 +1,34 @@
+var configFile = '';
+var config = {};
+var loadingconfig = false;
+
+function saveConfig(callback) {
+ if (!loadingconfig) {
+ config.wallpaper = xp.wallpaper.href;
+ config.profile = xp.profile;
+ config.theme = xp.theme.name;
+ xp.filesystem.writeFile(configFile, new Blob([JSON.stringify(config)], {type: 'text/plain'}), (e) => {
+ if (e) xp.error(e);
+ else if (callback !== undefined) callback()
+ });
+ }
+}
+
+function loadConfig(callback) {
+ loadingconfig = true;
+ xp.filesystem.readFile(configFile, (text) => {
+ try {
+ config = JSON.parse(text);
+ console.log(config);
+ xp.wallpaper.set('https://rebornxp.js.org/system/themes/XP.jpg');
+ xp.profile = config.profile;
+ xp.theme.set('reborn');
+ } catch(e) {
+ xp.wallpaper.set('https://rebornxp.js.org/system/themes/XP.jpg');
+ loadingconfig = false;
+ saveConfig();
+ }
+ loadingconfig = false;
+ if (callback !== undefined) callback();
+ });
+}
diff --git a/xp/system/contextmenus.css b/xp/system/contextmenus.css
new file mode 100644
index 00000000..22093e85
--- /dev/null
+++ b/xp/system/contextmenus.css
@@ -0,0 +1,19 @@
+.contextMenu {
+ box-shadow: 0px 0px 20px -5px #000;
+ clip-path: inset(0 -20px -20px 0);
+}
+
+.contextMenuItem {
+ color: #000000;
+ background-color: transparent;
+ font-size: 11px;
+}
+
+.contextMenuItem:hover {
+ color: #ffffff;
+ background-color: #0A246A;
+}
+
+.contextMenuItem.hr {
+ border-top: 1px solid #979797;
+}
\ No newline at end of file
diff --git a/xp/system/contextmenus.js b/xp/system/contextmenus.js
new file mode 100644
index 00000000..9513b75f
--- /dev/null
+++ b/xp/system/contextmenus.js
@@ -0,0 +1,196 @@
+var vContextMenu = Array();
+var isContextMenu = false;
+var CurX;
+var CurY;
+var tContextMenu;
+
+function fMouseDown(event) {
+ try {
+ if(window.event) event = window.event;
+ CurX = event.clientX;
+ CurY = event.clientY;
+ if (document.getElementById('lContextMenu').style.visibility === 'hidden')
+ tContextMenu = event.target;
+ } catch(e) {}
+}
+
+function rcContextMenu() {
+ try {
+ if (vContextMenu.length != 0) {
+
+ drawContextMenu();
+
+ var targX = CurX; //0; //event.clientX;
+ var targY = CurY; //0; //event.clientY;
+
+ //alert
+
+ var testW = document.getElementById('lContextMenu').offsetWidth;
+ var testH = document.getElementById('lContextMenu').offsetHeight;
+
+ var testX = targX + document.getElementById('lContextMenu').offsetWidth;
+ var testY = targY + document.getElementById('lContextMenu').offsetHeight;
+
+ var sW = document.body.clientWidth;//document.body.clientWidth;
+ var sH = document.body.clientHeight;//document.body.clientHeight;
+
+ if (testX >= sW) { targX = targX - testW; }
+ if (testY >= sH) { targY = targY - testH; }
+
+ document.getElementById('lContextMenu').style.left = targX;
+ document.getElementById('lContextMenu').style.top = targY;
+ document.getElementById('lContextMenu').style.visibility = 'visible';
+
+ }
+ } catch (e) {}
+}
+
+function rcCloseContext() {
+ try {
+ document.getElementById('lContextMenu').style.left = 0;
+ document.getElementById('lContextMenu').style.top = 0;
+ document.getElementById('lContextMenu').style.visibility = 'hidden';
+ } catch (e) {}
+}
+
+function drawContextMenu() {
+ try {
+ var outMsg = '![]() | ';
+
+ var len = vContextMenu.length - 1;
+
+ var inMsg = vContextMenu[0];
+ var inCmd = vContextMenu[1];
+ if (typeof inCmd !== 'string') {
+ outMsg = outMsg + ' ';
+ } else {
+ outMsg = outMsg + '';
+ }
+
+ for (var i = 2; i <= len; i ++) {
+ inMsg = vContextMenu[i];
+ inCmd = vContextMenu[i+1];
+
+ if (inMsg != '-HR-') {
+ if (typeof inCmd !== 'string') {
+ var outMsg = outMsg + '';
+ } else {
+ var outMsg = outMsg + '';
+ }
+ i ++;
+ } else {
+ i ++;
+ inMsg = vContextMenu[i];
+ inCmd = vContextMenu[i+1];
+ if (typeof inCmd !== 'string') {
+ outMsg = outMsg + '';
+ } else {
+ outMsg = outMsg + '';
+ }
+ i ++;
+ }
+ }
+
+ outMsg = outMsg + '
|
|
';
+
+ document.getElementById('lContextMenu').innerHTML = outMsg;
+
+ // JQuery magic
+ $('#lContextMenu').find('td[commandindex]').each(function() {
+ $(this).on('click', function() {
+ rcCloseContext();
+ vContextMenu[parseInt($(this).attr('commandindex'))]();
+ });
+ });
+ } catch(e) {}
+}
+
+function desktopContextMenu(e) {
+ var el = $(e.target);
+ if (el.closest('windowbutton').length > 0) {
+ var guid = el.closest('windowbutton').attr('guid');
+ vContextMenu = Array();
+ if ($('window[guid=' + guid + ']').attr('maximized') === 'true') {
+ vContextMenu.push('Restore');
+ vContextMenu.push('maximizeWindow(\'' + guid + '\')');
+ } else if ($('window[guid=' + guid + ']').find('.maximize').length > 0 || $('window[guid=' + guid + ']').find('.restore').length > 0) {
+ vContextMenu.push('Maximize');
+ vContextMenu.push('maximizeWindow(\'' + guid + '\')');
+ }
+ if ($('window[guid=' + guid + ']').attr('minimized') === 'true') {
+ vContextMenu.push('Restore');
+ vContextMenu.push('moveWindowToTop(\'' + guid + '\')');
+ } else if ($('window[guid=' + guid + ']').find('.minimize').length > 0) {
+ vContextMenu.push('Minimize');
+ vContextMenu.push('minimizeWindow(\'' + guid + '\')');
+ }
+ if ($('window[guid=' + guid + ']').find('.close').length > 0) {
+ vContextMenu.push('Close');
+ vContextMenu.push('closeWindow(\'' + guid + '\')');
+ }
+ rcContextMenu();
+ } else if (el.closest('.ui_icon').length > 0) {
+ el = el.closest('.ui_icon');
+ vContextMenu = Array('Open', () => eval(el.data('exe')), 'Explore', () => openLocation(el.data('target')), '-HR-', 'Create Shortcut', '', 'Delete',() => el.remove(), 'Rename', () => xp.prompt('Rename', 'Enter the new name:', (t) => {el.find('span').html(t)}), '-HR-');
+ rcContextMenu();
+ }
+}
+
+function getSelectionText() {
+ var text = "";
+ var activeEl = document.activeElement;
+ var activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
+ if (
+ (activeElTagName == "textarea") || (activeElTagName == "input" &&
+ /^(?:text|search|password|tel|url)$/i.test(activeEl.type)) &&
+ (typeof activeEl.selectionStart == "number")
+ ) {
+ text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
+ } else if (window.getSelection) {
+ text = window.getSelection().toString();
+ }
+ return text;
+}
+
+function windowContextMenu(e, guid) {
+ var el = $('window[guid=' + guid + ']');
+ var t = e.target.nodeName;
+ console.log(t);
+ vContextMenu = Array();
+ var type = ($(e.target).attr('type') || '').toLowerCase();
+ if (t === 'TEXTAREA' || (t === 'INPUT' && (type === 'text' || type === 'number'))) {
+ vContextMenu.push('Copy');
+ vContextMenu.push('document.execCommand(\'copy\')');
+ vContextMenu.push('Paste');
+ vContextMenu.push('document.execCommand(\'paste\')');
+ vContextMenu.push('-HR-');
+ }
+ if (el.attr('maximized') === 'true') {
+ vContextMenu.push('Restore');
+ vContextMenu.push('maximizeWindow(\'' + guid + '\')');
+ } else if (el.find('.maximize').length > 0) {
+ vContextMenu.push('Maximize');
+ vContextMenu.push('maximizeWindow(\'' + guid + '\')');
+ }
+ if (el.attr('minimized') === 'true') {
+ vContextMenu.push('Restore');
+ vContextMenu.push('moveWindowToTop(\'' + guid + '\')');
+ } else if (el.find('.minimize').length > 0) {
+ vContextMenu.push('Minimize');
+ vContextMenu.push('minimizeWindow(\'' + guid + '\')');
+ }
+ if (el.find('.close').length > 0) {
+ vContextMenu.push('Close');
+ vContextMenu.push('closeWindow(\'' + guid + '\')');
+ }
+ rcContextMenu();
+}
+
+function startContextMenu(e) {
+ var el = $(e.target);
+ if (!(el.is('li.startmenuitem') || el.is('li.startmenuitem>img') || el.is('li.startmenuitem>div') || el.is('li.startmenuitem>div>div') || el.is('li.startmenuitem>div>div>b'))) return;
+ if (!el.is('li.startmenuitem'))
+ el = el.closest('li');
+ vContextMenu = Array('Open', el.attr('onclick'), 'Explore', el.attr('onclick'), '-HR-', 'Create Shortcut', '', 'Delete',() => el.remove(), 'Rename', () => xp.prompt('Rename', 'Enter the new name:', (t) => {el.find('div>div>b').html(t)}), '-HR-');
+ rcContextMenu();
+}
\ No newline at end of file
diff --git a/xp/system/controlpanel.js b/xp/system/controlpanel.js
new file mode 100644
index 00000000..d8ff8c62
--- /dev/null
+++ b/xp/system/controlpanel.js
@@ -0,0 +1,254 @@
+var configFile = 'config.json';
+
+// Load the config on startup
+$(window).on('xpboot', function() {
+ loadConfig();
+});
+
+function saveConfig(callback) {
+ if (!loadingconfig) {
+ config.wallpaper = xp.wallpaper.href;
+ config.profile = xp.profile;
+ config.theme = xp.theme.name;
+ xp.filesystem.writeFile(configFile, new Blob([JSON.stringify(config)], {type: 'text/plain'}), (e) => {
+ if (e) xp.error(e);
+ else if (callback !== undefined) callback();
+ });
+ }
+}
+
+function loadConfig(callback) {
+ loadingconfig = true;
+ xp.filesystem.readFile(configFile, (text) => {
+ try {
+ config = JSON.parse(text);
+ xp.wallpaper.set(config.wallpaper || 'https://rebornxp.js.org/system/themes/XP.jpg');
+ xp.profile = config.profile;
+ xp.theme.set(config.theme || 'reborn');
+ } catch (e) {
+ xp.wallpaper.set('https://rebornxp.js.org/system/themes/XP.jpg');
+ loadingconfig = false;
+ saveConfig();
+ }
+ loadingconfig = false;
+ if (callback !== undefined) callback();
+ });
+}
+
+// Add theme chooser to Control Panel
+xp.controlpanel.add('Themes', () => {
+ var win = new Window({
+ width: 400,
+ height: 200, // Increased height to accommodate the wallpaper change option
+ title: 'Change Theme',
+ canResize: false,
+ });
+
+ win.content(`
+
+
Theme Chooser
+
Choose a new theme to apply:
+
+
+
+
+
+ `);
+
+ win.el.find('#applyThemeBtn').on('click', function() {
+ const selectedTheme = win.el.find('#themeSelect').val();
+ xp.theme.set(selectedTheme);
+ saveConfig();
+ win.close();
+ });
+
+ win.el.find('#changeWallpaperBtn').on('click', function() {
+ const wallpaperDialog = new Window({
+ width: 400,
+ height: 250,
+ title: 'Change Wallpaper',
+ canResize: false,
+ });
+
+ wallpaperDialog.content(`
+
+
Wallpaper Chooser
+
Select a wallpaper:
+
+
+
+
+
+
+
+ `);
+
+ const thumbnailsContainer = wallpaperDialog.el.find('.wallpaper-thumbnails');
+
+ // Add your wallpaper thumbnails here using the following format
+ const wallpaperThumbnails = [
+ 'system/themes/XP.jpg',
+ 'system/themes/wallpapers/anniversary.png',
+ 'system/themes/wallpapers/3.jpg',
+ 'system/themes/wallpapers/4.jpg',
+ 'system/themes/wallpapers/5.jpg',
+ 'system/themes/wallpapers/6.jpg',
+ ];
+
+ wallpaperThumbnails.forEach(thumbnail => {
+ const thumbnailElement = $('
')
+ .attr('src', thumbnail)
+ .addClass('wallpaper-thumbnail')
+ .attr('width', "100px")
+ .attr('height', "60px")
+
+
+ .on('click', function() {
+ const selectedWallpaper = $(this).attr('src');
+ xp.wallpaper.set(selectedWallpaper);
+ saveConfig();
+ });
+ thumbnailsContainer.append(thumbnailElement);
+ });
+
+ wallpaperDialog.el.find('#applyWallpaperBtn').on('click', function() {
+ const wallpaperLink = wallpaperDialog.el.find('#wallpaperLink').val();
+ if (wallpaperLink) {
+ xp.wallpaper.set(wallpaperLink);
+ saveConfig();
+ }
+ wallpaperDialog.close();
+ });
+
+
+ });
+
+ // Calculate window position to center it on the screen
+ const screenWidth = $(window).width();
+ const screenHeight = $(window).height();
+ const windowWidth = win.el.outerWidth();
+ const windowHeight = win.el.outerHeight();
+ const left = (screenWidth - windowWidth) / 2;
+ const top = (screenHeight - windowHeight) / 2;
+
+ win.el.css({
+ position: 'absolute',
+ left: left + 'px',
+ top: top + 'px',
+ });
+
+ win.el.find('.content').css({
+ padding: '20px', // Adjust the padding value as needed
+ });
+});
+
+// Add theme chooser as an application
+xp.applications.add('themes', () => {
+ var win = new Window({
+ width: 400,
+ height: 200, // Increased height to accommodate the wallpaper change option
+ title: 'Change Theme',
+ canResize: false,
+ });
+
+ win.content(`
+
+
Theme Chooser
+
Choose a new theme to apply:
+
+
+
+
+
+ `);
+
+ win.el.find('#applyThemeBtn').on('click', function() {
+ const selectedTheme = win.el.find('#themeSelect').val();
+ xp.theme.set(selectedTheme);
+ saveConfig();
+ win.close();
+ });
+
+ win.el.find('#changeWallpaperBtn').on('click', function() {
+ const wallpaperDialog = new Window({
+ width: 400,
+ height: 250,
+ title: 'Change Wallpaper',
+ canResize: false,
+ });
+
+ wallpaperDialog.content(`
+
+
Wallpaper Chooser
+
Select a wallpaper:
+
+
+
+
+
+
+
+ `);
+
+ const thumbnailsContainer = wallpaperDialog.el.find('.wallpaper-thumbnails');
+
+ // Add your wallpaper thumbnails here using the following format
+ const wallpaperThumbnails = [
+ 'system/themes/XP.jpg',
+ 'system/themes/wallpapers/anniversary.png',
+ 'system/themes/wallpapers/3.jpg',
+ 'system/themes/wallpapers/4.jpg',
+ 'system/themes/wallpapers/5.jpg',
+ 'system/themes/wallpapers/6.jpg',
+ ];
+
+ wallpaperThumbnails.forEach(thumbnail => {
+ const thumbnailElement = $('
')
+ .attr('src', thumbnail)
+ .addClass('wallpaper-thumbnail')
+ .attr('width', "100px")
+ .attr('height', "60px")
+
+
+ .on('click', function() {
+ const selectedWallpaper = $(this).attr('src');
+ xp.wallpaper.set(selectedWallpaper);
+ saveConfig();
+ });
+ thumbnailsContainer.append(thumbnailElement);
+ });
+
+ wallpaperDialog.el.find('#applyWallpaperBtn').on('click', function() {
+ const wallpaperLink = wallpaperDialog.el.find('#wallpaperLink').val();
+ if (wallpaperLink) {
+ xp.wallpaper.set(wallpaperLink);
+ saveConfig();
+ }
+ wallpaperDialog.close();
+ });
+
+
+ });
+
+ // Calculate window position to center it on the screen
+ const screenWidth = $(window).width();
+ const screenHeight = $(window).height();
+ const windowWidth = win.el.outerWidth();
+ const windowHeight = win.el.outerHeight();
+ const left = (screenWidth - windowWidth) / 2;
+ const top = (screenHeight - windowHeight) / 2;
+
+ win.el.css({
+ position: 'absolute',
+ left: left + 'px',
+ top: top + 'px',
+ });
+
+ win.el.find('.content').css({
+ padding: '20px', // Adjust the padding value as needed
+ });
+});
diff --git a/xp/system/core.js b/xp/system/core.js
new file mode 100644
index 00000000..f9c96498
--- /dev/null
+++ b/xp/system/core.js
@@ -0,0 +1,620 @@
+var xp = {
+ post: true,
+ version: "2.0-beta",
+ openFileHandler: (path) => {},
+ applications: {
+ apps: {},
+ add: function(name, func) {
+ xp.applications.apps[name] = func;
+ },
+ remove: function(name) {
+ delete xp.applications.apps[name];
+ }
+ },
+ themes: ['reborn', 'classic', 'luna', 'silver', 'vista'],
+ theme: {
+ name: 'luna',
+ set: function(name) {
+ xp.theme.name = name;
+ if (xp.theme.name !== 'default') {
+ $('#theme').attr('href', 'system/themes/' + xp.theme.name + '.css');
+ } else {
+ $('#theme').attr('href', '');
+ }
+ if (saveConfig) saveConfig();
+ }
+ },
+ wallpaper: {
+ href: "",
+ set: function(name) {
+ if (name === undefined) {
+ xp.wallpaper.set(xp.wallpaper.href);
+ } else if (name === "") {
+ $("._ui_wallpaper_image").attr("src", "");
+ xp.wallpaper.href = "";
+ } else {
+ $("._ui_wallpaper_image").attr("src", name);
+ xp.wallpaper.href = name;
+ }
+ if (saveConfig) saveConfig();
+ },
+ setLocal: function(path) {
+ xp.filesystem.toURL(path, (url) => {
+ xp.wallpaper.set(url);
+ });
+ }
+ },
+ icons: {
+ error: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAIWklEQVRYw52Xa4xV1RXHf/uce+6LyzwY7lgZZHBkgHaoKAYDihlBjEVjGRolQ6wZJK1KfbQW05p+aGqr/dKk8UM/GFtNmtKkLfh+UG2HKUUF5GkVhQ6oCDoDzlwud+beex770Q9nX7zgo8STrOyTffbZ//967LXWFpzjE2Sz85iQ+TaTJl/i5POz3YkTz0frhCqVjutC4bA+ObqPU2P9R4NgYCYE57qv+H8LqqnUXd706T912tsvENOmQVMT5HKQSEAYQrkMxSIUi5iREaKjR8sjx4+vf6xcfuhBOPaVCVRhceLCC/+QmDGjgwsugPPOg5YWaGyETAaMAd+HsbGYQKEAp07F4+goxaEhtn/00c+XSfmrLyPgft6kn80+kJw580/u7NnNtLfDlCnQ2grNzZBOg+uCUhBFsUgJWsekAFyXtOcxI51evNz3r/tzFD0XQuWcLFBpyD2SufCiHzJtGpx/fgxc09pxYsAggPHx2AVRFINHUWyRajV2y9jYaevsHho6dsXY2LUhHPhSAmOZzH0TOjp+K9raYpM3N8PEieB5IEQMWirFZh4fj63gOJBMxuK6MbkgiIn4PlVLZmB4+IPv+P7SAA5/LoEizE9Pn/5Gqq0NJk2Ktc5mUVoTRRHpSiUGLhRin/t+bPJEIrZOLgfJJNVkkrSUCOuWKAgoBgG6XObR4eF//0LrlcDxz8TAT1paXs7m860il4s1lhJZKvHr5mZeTaVY9NprOO+9ByMjRMUi1fFxgmoVVanglMs4J09SDgJ+PH8+hxsbWTA4CFGE0ZqqlPjG0CFE+z99XxXgVUCeJjCc9r7rTM7fmc1kYo2iiKBc5o8XX8wld93F1AULGBgdpXPLFnQYckopfK2JtCZUCjeKOBaG/GbZMrpWryZ9+eUMjo4yZ/9+VBhSMYaKUiSFIBdFc1/R+nXg/dME7s01bPByuZZsLbp9n/XXXUfrmjV8a9YsLmppYXzOHDYHAVN27cIDDKCBJPFhf3TVKrruuIPvX3MNl7S38/asWYxKyZSdO6kAvtZUteZrQqQGwlAUYQtQdYeho9rY+EvP8/CMwZUSgoBUQwNy6VJam5rwgOmNjfhdXbzhurRt20bKsh8C/tK3mrm3305fd/fpwJqdz+M+8QT6rbcIHYfAWiENHIqiSe8asxs47P4gnfxekJ1wbcoYXKVIGIMjJfnt2xGDgxy5+moaJ04kCbQ3NaHmzWNfMsnkrVsZAzatW8c31qyhd+HCM45XqacH/dRTROk0IVBVCt8YjOPgat34d6U+BLYmfOHO1VISak1VCHAcXECn00x4/nlKUcSh9evpbGkhC8zP58mtW8eH2Swlx2HRypUs7Og4A/zo8uUUn3uOjOehhSDUGmkMEgiNIQ8kYI6ENrE7l9vjpFKXpo0hKwRpa9ooCAjGx5HAqe5uvA0bmJHPk6klLBsDubMSy+GlSyn095MGnGQSk0gQaY0PlI0hEAKjNbdE0f6SMfc4gdZTQ6UIpCSIInwpqUhJYAyh6xICqS1bCHp7ef/EifjsANk6cAOEwPvXX8+J/n4cIBKCCJBKEWmNUgqpNYHWeELgQQPQ4ATQEEhJoBQVpahadwRKxRtYTTObN1Psu5VPwvCztQPYf+WVDG/ahAcoQDkOkTFEWsejFWkMQmsEZIC0E2ld9JUiUIpQKXyl8KUkMgZlwR2gABxfspSE1rHWxmBs8XGBcNWqGNiKtH6PgFBrfK0JrZSFwMTbuo7W+mhkDIH9GFjtpTEoY0jYvPnqvffS2NNDPp2Oj5oQCBFn8iQwac0ajjz4IOO1HGE1DrQmNIbQuklDnMhi9sYRWr/j2wVVrQlq5lIKV2s+Bl657TY6e3tZ0tn5hXW9M5vl63feycH776dkgWQ9uDEE1jon4vcQkE5C6l01zWuMAylxlGIIeGHlSi7u6+Oms875vkWLOLBiBRGfFvp5ra1cdvfdHLjnHorw6X4WPDIGjOHjOLYqgO+uxZwYcZwfmTq/OsYwAgysXs3CtWvpveqqM8EXL+bDrVs5eeAApb17ET09pDwPD5ja1ETi0kvZDyS2bUMTN4i+EPhC4AIvGMMx2A884z4OxZuF6JUwWcfRhQYOPfAAnX193LxgAU4d+N6eHj54+WWSNjjHDh6kvG8f3HgjuVSKBDAll2NCdzfFZJLKwAChJaCFoAI8hdE+/At40gHoV+rhphpTK1M3baJNCPw68J1LlvDes8/iWR+rWi/x4oscWrGCI4XC6bVdqRTimWcYA8pxj4kD7DCGomEY2AcMOwCPw/qTxhzEMqwA/ptv8smtt5K0G+644QYGBwZwbW6IhEAJgbJRX+zv5/Att5wm8HRnJx/s2UNkwQFGjWFTfHTfAXac0RHdAVd3O85AAUBrklbLWcuW4WWzHHzySbJWi9rxM1aUzRk+0NXXR2FwkHdffx0BRICyKX6jMeyAj4HfAY8A1TN6wrVCPHylED8btcFYM7ULpADvrF7O1PUF0kqtRtTScwTkhGCHMWyMjfES8JB1wZlt+S7YnIeuDiG6qvbn2lPzubTzuu69NoZ1a0I7ZoTgP8bw1/jTTuD3wMAX3gt2w8YsdE6Hb5paQbEbh3WpNqoTv45ATQTgCMEbxrAh/mUv8CjwdK0f/MKLydvw7CnIThbiimYbaOFZwPIs0NqcsKn5pBC8ZAxbYq/sBB4D/lYXk+d0N7xpkRD3LYQrmi1baQOu5v96TQwwIgRvAtuNkQF8RNz7bQRe4XMureIcLrAdwPKpcGMXXN4qxIRGIG0MwqpTEoIhYNAYjsC4gU9skPUD/wD++5Vvx3UKzgQuA+YCM4BJxDVd2Jj0bdUejL3IHuKrmPyyjf8HLQN3CAGzdR8AAAAASUVORK5CYII=',
+ warning: 'data:image/png;base64,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',
+ info: 'data:image/png;base64,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'
+ },
+ dialog: function(title, text, callback, isyesno, type, nocallback) {
+ if (type === undefined) type = 'info';
+ var icon = undefined;
+ if (type === 'info') icon = xp.icons.info;
+ if (type === 'warning') icon = xp.icons.warning;
+ if (type === 'error') icon = xp.icons.error;
+ if (type === 'info') xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Ding.wav?1522624603096');
+ if (type === 'warning') xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Error.wav?1522624607974');
+ if (type === 'error') xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Critical%20Stop.wav?1522624592867');
+ var win = new Window({
+ width: 340,
+ height: 154,
+ title: title,
+ canResize: false,
+ canMinimize: false
+ });
+ if (isyesno) {
+ win.content(`
+ ` + text + `
+
+
+
+ `);
+ } else {
+ win.content(`
+ ` + text + `
+
+
+ `);
+ }
+ if (isyesno) {
+ win.el.find('.no').on('click', function() {
+ win.close();
+ if (nocallback !== undefined) nocallback();
+ });
+ win.el.find('.yes').on('click', function() {
+ win.close();
+ if (callback !== undefined) callback();
+ }).focus();
+ } else {
+ win.el.find('.ok').on('click', function() {
+ win.close();
+ if (callback !== undefined) callback();
+ }).focus();
+ }
+ },
+ alert: function(msg, callback, nocallback) {
+ xp.dialog('Alert', msg, callback, false, 'info', nocallback);
+ },
+ error: function(msg, callback, nocallback) {
+ xp.dialog('Error', msg, callback, false, 'error', nocallback);
+ },
+ prompt: function(title, text, callback, defaulttext, nocallback) {
+ xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Ding.wav?1522624603096');
+ var guid = generate_guid();
+ var temp = document.createElement('div');
+ if (defaulttext === undefined) defaulttext = "";
+ var win = new Window({
+ width: 340,
+ height: 154,
+ title: title,
+ canResize: false,
+ canMinimize: false
+ });
+ win.content(`` + text + `
+
+
+
+
+ `);
+ win.el.find('.prompttext').val(defaulttext);
+ win.el.find('.cancel').on('click', function() {
+ win.close();
+ if (nocallback !== undefined) nocallback();
+ });
+ win.el.find('.ok').on('click', function() {
+ win.close();
+ callback(win.el.find('.prompttext').val());
+ });
+ },
+ chooser: function(title, text, options, callback, nocallback) {
+ xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Ding.wav?1522624603096');
+ var guid = generate_guid();
+
+ var optionstext = '';
+ for (var i = 0; i < options.length; i ++) {
+ optionstext += '';
+ }
+
+ var win = new Window({
+ width: 340,
+ height: 154,
+ title: title,
+ canResize: false,
+ canMinimize: false
+ });
+ win.content(`` + text + `
+
+
+
+
+ `);
+ win.el.find('.cancel').on('click', function() {
+ win.close();
+ if (nocallback !== undefined) nocallback();
+ });
+ win.el.find('.ok').on('click', function() {
+ win.close();
+ callback(win.el.find('.select').val());
+ });
+ }
+};
+
+$.fn.closeWindow = function() {
+ closeWindow($(this).attr('guid'));
+}
+
+$.fn.setTitle = function(title) {
+ var guid = $(this).attr('guid');
+ if (title === '') title = ' ';
+ title = title.replace(/&/g,'&').replace(//g,'>');
+ $('window[guid=' + guid + ']').attr('title', title);
+ $('window[guid=' + guid + ']').find('.windowTitle').html(title.replace(/ /g,' '));
+ $('windowbutton[guid=' + guid + '] div').html(title);
+};
+
+function maximizeWindow(guid, force) {
+ var el = $('window[guid=' + guid + ']');
+ if (el.attr('maximized') === 'true' && force !== true) {
+ el.attr('maximized', 'false');
+ el.attr('width', el.attr('prevwidth'));
+ el.attr('height', el.attr('prevheight'));
+ el.css('left', el.attr('prevleft'));
+ el.css('top', el.attr('prevtop'));
+ } else {
+ el.attr('maximized', 'true');
+ if (!force) {
+ el.attr('prevwidth', el.attr('width'));
+ el.attr('prevheight', el.attr('height'));
+ el.attr('prevleft', el.css('left'));
+ el.attr('prevtop', el.css('top'));
+ }
+ el.attr('width', $(window).width());
+ el.attr('height', $(window).height() - (el.find('.windowTitle').closest('table').height() + $('taskbar').height()) + parseInt(el.find('.windowBody').css("border-bottom-width")));
+ el.css('left', -parseInt(el.find('.windowBody').css("border-left-width")));
+ el.css('top', -parseInt(el.find('.windowBody').css("border-right-width")));
+ }
+ el.updateWindow();
+ var event = new Event('resize');
+ el[0].dispatchEvent(event);
+}
+
+// Generate GUID
+function generate_guid() {
+ function s4() {
+ return Math.floor((1 + Math.random()) * 0x10000)
+ .toString(16)
+ .substring(1);
+ }
+ return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
+ s4() + '-' + s4() + s4() + s4();
+}
+
+// Window control
+function closeWindow(guid) {
+ var el = $('[guid=' + guid + ']');
+ $('window[guid=' + guid + ']')[0].dispatchEvent(new Event('close'));
+ setTimeout(function() {
+ el.remove();
+ }, 50);
+}
+
+function minimizeWindow(guid) {
+ var el = $('[guid=' + guid + ']');
+ el.attr("minimized", "true");
+ el.attr("inactive", "true");
+ updateAllWindows();
+}
+
+function sortProperties(obj) {
+ // convert object into array
+ var sortable=[];
+ for(var key in obj)
+ if(obj.hasOwnProperty(key))
+ sortable.push([key, obj[key]]); // each item is an array in format [key, value]
+
+ // sort items by value
+ sortable.sort(function(a, b) {
+ return a[1]-b[1]; // compare numbers
+ });
+ return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ]
+}
+
+var createdIndexes = 0;
+
+function updateIndexes(topGuid) {
+ var newIndexes = {};
+ var maxIndex = 0;
+ $("window").each(function(index) {
+ var el = $(this);
+ var index = parseInt(el.attr("index"));
+ var guid = el.attr("guid");
+ newIndexes[guid] = index;
+ if (index > maxIndex)
+ maxIndex = index;
+ });
+ if (topGuid === undefined) {
+ topGuid = Object.keys(newIndexes).find(key => newIndexes[key] === maxIndex);
+ }
+ newIndexes[topGuid] = maxIndex + 1;
+ newIndexes = sortProperties(newIndexes);
+ var index = 0;
+ for (var i = 0, len = newIndexes.length; i < len; i++) {
+ var guid = newIndexes[i][0];
+ var inactive = i === len - 1 ? "false" : "true"
+ index ++;
+ $("window[guid=" + guid + "]").attr("index", index);
+ $("window[guid=" + guid + "]").attr("inactive", inactive);
+ }
+ createdIndexes = index;
+}
+
+$.fn.updateWindow = function() {
+ updateWindow(this, true);
+ updateIndexes();
+ updateAllWindows();
+}
+
+function hideMenu(name, guid) {
+ $("#" + name.replace(/ /g,"_") + "_menu_" + guid).css("display", "none");
+ $("#" + name.replace(/ /g,"_") + "_menubutton_" + guid).removeClass('_ui_menu_item_active');
+}
+
+$.fn.addMenu = function(name, items) {
+ var guid = generate_guid();
+ var el = `