Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
d3f2dd4
add content-type for svg content
ylebre Nov 22, 2024
c22c73c
Merge pull request #19 from SimplyEdit/fix/svg-mime
ylebre Nov 22, 2024
1efc807
fix paths, resolve assets
ylebre Dec 4, 2024
a598128
Merge pull request #20 from SimplyEdit/fix/path-escaping
ylebre Dec 4, 2024
952d509
update simplycode, rework post install script
ylebre Dec 4, 2024
e2f5164
update simplycode
ylebre Dec 4, 2024
ade3b2c
Merge pull request #21 from SimplyEdit/feature/cleaned-simplycode
ylebre Dec 4, 2024
c51e48b
add content-type for js files
ylebre Dec 13, 2024
b7e29de
update simplyview from repo
ylebre Dec 13, 2024
43c7d1d
Merge pull request #23 from SimplyEdit/feature/js-mimetype
ylebre Dec 13, 2024
0090bdf
update simplycode
ylebre Dec 13, 2024
e9af13f
Merge branch 'main' into feature/update-simplyview
ylebre Dec 13, 2024
9002b25
added electron forge build option for mac intel build
Hoxolotl Feb 3, 2025
c9adfde
update protocol scheme to app.simplyapp and app.simplycode for oidc r…
ylebre Feb 21, 2025
c2de219
add handling for data url
ylebre Feb 21, 2025
20379ae
add simplyview
ylebre Feb 21, 2025
0bf75c5
Merge pull request #24 from SimplyEdit/feature/update-simplyview
ylebre Feb 21, 2025
79f2016
Merge branch 'main' into feature/data-and-protocol
ylebre Feb 21, 2025
581521d
update simplyedit
ylebre Feb 24, 2025
9304610
update package-lock
ylebre Feb 24, 2025
a81f81e
Merge pull request #25 from SimplyEdit/feature/data-and-protocol
ylebre Mar 3, 2025
eb3abce
adding icon
Hoxolotl Mar 21, 2025
046ec4f
typofix
ylebre Jun 19, 2025
28ef6fd
keyboard handling
ylebre Jun 20, 2025
cbd5f94
update from repo
ylebre Jun 20, 2025
fe99369
add keyboard handling
ylebre Jun 20, 2025
6d0ed60
update from upstream
ylebre Jun 20, 2025
46c37de
add access keys
ylebre Jun 20, 2025
aba4130
update with bugfix
ylebre Jun 20, 2025
088a8f0
update simplycode and simplyview from packages
ylebre Jun 20, 2025
4914e27
Merge pull request #26 from SimplyEdit/feature/keyboard-handling
ylebre Jun 20, 2025
9240fce
update simplyview
ylebre Jun 23, 2025
3d6caa0
Merge pull request #27 from SimplyEdit/feature/keyboard-handling
ylebre Jun 23, 2025
f0db90f
Icon still not working, but it should according to forge config docum…
Hoxolotl Jun 27, 2025
5b33a64
still not working
Hoxolotl Jun 27, 2025
98863df
now with absolute paths
Hoxolotl Jun 27, 2025
a73e2e6
working icons , and updated builder
Hoxolotl Jun 27, 2025
00ba82f
success and added a background
Hoxolotl Jun 27, 2025
36b5efa
removed ugly background
Hoxolotl Jun 27, 2025
1a418a8
removed ugly background - and its format
Hoxolotl Jun 27, 2025
5ac2ac8
git builder was complaining about node-abi, added it to the repo
Hoxolotl Jun 27, 2025
769b7fd
add qunit
ylebre Jul 6, 2025
344af20
Merge pull request #30 from SimplyEdit/fix/add-qunit
ylebre Jul 7, 2025
65b793d
Merge pull request #28 from SimplyEdit/feature/mac-icon
ylebre Jul 7, 2025
b786a17
install qunit from npm
ylebre Jul 8, 2025
2255b5d
Merge branch 'main' into fix/add-qunit
ylebre Jul 8, 2025
ba30f18
use simplycode from the feature/qunit-update branch
ylebre Jul 8, 2025
f2c09f4
Merge branch 'fix/add-qunit' of https://github.com/SimplyEdit/simplyc…
ylebre Jul 8, 2025
7da5e46
typofix
ylebre Jul 8, 2025
cbd96b4
fix wrong dir
ylebre Jul 8, 2025
17a1f41
Merge pull request #32 from SimplyEdit/fix/add-qunit
ylebre Jul 10, 2025
ccfd866
udpate simply-edit, pin codemirror to major 5
ylebre Jul 11, 2025
8f751e7
Merge pull request #33 from SimplyEdit/feature/update-simplyedit
ylebre Jul 11, 2025
f30cd2e
Change code in post-install.sh to be cleaner
Potherca Jul 20, 2025
3bd9f27
Merge pull request #34 from SimplyEdit/cleanup/post-install-script
Potherca Jul 22, 2025
9d115fd
Merge branch 'GovertDev' into main
Hoxolotl Sep 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions forge.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ module.exports = {
platforms: ['darwin'],
config: {
bin: 'simplycode',
},
icon: path.join(__dirname, './simplycode/assets/icons/icon.icns')
}
},
{
name: '@electron-forge/maker-deb',
Expand Down Expand Up @@ -46,5 +47,8 @@ module.exports = {
prerelease: true
}
}
]
],
packagerConfig: {
icon: path.join(__dirname, './simplycode/assets/icons/icon.icns')
}
}
240 changes: 171 additions & 69 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const createWindow = () => {
}
});
codeWindow.setMenu(defaultMenu);
codeWindow.loadURL('simplycode://index.html')
codeWindow.loadURL('app.simplycode://index.html')
codeWindow.on('close', function() {
codeWindow = false;
});
Expand All @@ -60,7 +60,7 @@ const createTestWindow = () => {
allowRunningInsecureContent : true
}
})
codeWindow.loadURL('simplycode://index.html/tests/triplebinding/index.html')
codeWindow.loadURL('app.simplycode://index.html/tests/triplebinding/index.html')
codeWindow.on('close', function() {
codeWindow = false;
});
Expand All @@ -69,7 +69,7 @@ const createTestWindow = () => {
const createSecondWindow = (dataDir) => {
if (appWindow) {
appWindow.focus();
appWindow.loadURL('simplyapp://generated.html')
appWindow.loadURL('app.simplyapp://generated.html')
return;
}
appWindow = new BrowserWindow({
Expand Down Expand Up @@ -113,7 +113,7 @@ const createSecondWindow = (dataDir) => {
}
});
appWindow.setMenu(menu);
appWindow.loadURL('simplyapp://generated.html')
appWindow.loadURL('app.simplyapp://generated.html')
appWindow.on('close', function() {
appWindow = false;
});
Expand Down Expand Up @@ -157,6 +157,41 @@ function readRecursive(componentPath) {
}
}

function readDataRecursive(componentPath) {
if(componentPath.endsWith('\/')){
componentPath = componentPath.substring(0, (componentPath.length - 1))
}
const pathicles = componentPath.split('\/');
if (pathicles[0] == ''){
pathicles.shift()
}
const componentName = pathicles.pop();
const componentDirectory = pathicles.join('/');

var target = dataDir + componentDirectory + '\/' + componentName;

if (fs.lstatSync(target).isDirectory()) {
const files = fs.readdirSync(target);
const result = [];
files.forEach((file) => {
if (file !== '.' && file !== '..' && !file.startsWith('.')) {
let entries = readDataRecursive(componentPath + '\/' + file);
let ctime = fs.lstatSync(target + '\/' + file).ctime;
let data = {
"id" : file,
"ctime" : ctime,
"ctime-human" : new Date(ctime).toISOString(),
...entries
}
result.push(data);
}
});
return result;
} else {
return JSON.parse(fs.readFileSync(target, 'utf8'));
}
}

function guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
Expand All @@ -178,15 +213,15 @@ app.commandLine.appendSwitch('disable-site-isolation-trials');

protocol.registerSchemesAsPrivileged([
{
scheme: 'simplycode',
scheme: 'app.simplycode',
privileges: {
standard: true,
secure: true,
supportFetchAPI: true
}
},
{
scheme: 'simplyapp',
scheme: 'app.simplyapp',
privileges: {
standard: true,
secure: true,
Expand Down Expand Up @@ -216,15 +251,16 @@ async function createComponentFile(componentPath, filecontent){
app.whenReady().then(() => {
if (require('electron-squirrel-startup') === true) app.quit(); // prevents Squirrel.Windows from launching your app multiple times during the installation/updating/uninstallation.

protocol.handle('simplycode', (request) => {
protocol.handle('app.simplycode', (request) => {
let componentPath = new URL(request.url).pathname
console.log('[simplycode://]' + componentPath)
console.log('[app.simplycode://]' + componentPath)
if(componentPath.endsWith('\/')){
componentPath = componentPath.substring(0, (componentPath.length - 1))
}

let pathicles = componentPath.split('\/');
let componentName = pathicles.pop();
componentName = decodeURIComponent(componentName);
if (pathicles[0] == ''){
pathicles.shift()
}
Expand Down Expand Up @@ -272,13 +308,27 @@ app.whenReady().then(() => {
case 'GET':
default:
let target = dataDir + componentDirectory + "/" + componentName;
if(fs.existsSync(target)){
if(!fs.existsSync(target)) {
target = __dirname + '/simplycode/' + componentDirectory + '\/' + componentName;
}
if (fs.existsSync(target)) {
const filestuff = fs.readFileSync(target)
let headers = {};
if (componentName.match(/\.svg$/)) {
headers = {
'content-type' : 'image/svg+xml'
}
}
if (componentName.match(/\.js$/)) {
headers = {
'content-type' : 'text/javascript'
}
}
return new Response(filestuff, {
// headers: { 'content-type': 'text/html' }
headers: headers
})
} else {
return new Response('"Not found"', { status: 404})
return new Response('"Not found"', { status: 404 })
}
break
}
Expand Down Expand Up @@ -314,84 +364,136 @@ app.whenReady().then(() => {
}
})

protocol.handle('simplyapp', (request) => {
protocol.handle('app.simplyapp', (request) => {
let componentPath = new URL(request.url).pathname
console.log('[simplyapp://]' + componentPath)
console.log('[app.simplyapp://]' + componentPath)
if(componentPath.endsWith('\/')){
componentPath = componentPath.substring(0, (componentPath.length - 1))
}

let pathicles = componentPath.split('\/'); // also splits on an empty string

let componentName = pathicles.pop();
componentName = decodeURIComponent(componentName);

if (pathicles[0] == ''){
pathicles.shift()
}
let componentDirectory = pathicles.join('/');

switch (request.method){
case 'OPTIONS':
if(fs.existsSync(dataDir + componentDirectory + "/" + componentName)){
return new Response('"ok"', { status: 200})
} else {
return new Response('"Not found"', { status: 404})
}
break
case 'DELETE':
if(fs.existsSync(dataDir + componentDirectory + "/" + componentName)){
fs.rmSync((dataDir + componentDirectory + "/" + componentName), { recursive: true, force: true })
return new Response('"deleted"', { status: 200})
} else {
return new Response('"Not found"', { status: 404})
}
break
case 'PUT':
return createComponentDirectory(componentDirectory)
.then(createComponentFile(componentDirectory + "/" + componentName, request))
.then(function() { return new Response('"ok"', { status: 200})})
.catch(function(){ return new Response('"something went wrong"', { status : 500 })}) // @TODO : return the error code
break
default:
if(componentPath.endsWith('\/')){
componentPath = componentPath.substring(0, (componentPath.length - 1))
}

if (!componentPath || componentPath === "/") {
const filestuff = fs.readFileSync(dataDir + '/generated.html')
return new Response(filestuff, {
// headers: { 'content-type': 'text/html' }
})

} else {
var target = dataDir + componentDirectory + '\/' + componentName;
let headers = {};
if (componentName.match(/\.svg$/)) {
headers = {
'content-type' : 'image/svg+xml'
}

if(pathicles[0] === "data") {
pathicles.shift();
componentDirectory = pathicles.join('/');

switch (request.method){
case 'OPTIONS':
if(fs.existsSync(dataDir + componentDirectory + "/" + componentName)){
return new Response('"ok"', { status: 200})
} else {
return new Response('"Not found"', { status: 404})
}
if(fs.existsSync(target)) {
const filestuff = fs.readFileSync(target)
break
case 'DELETE':
if(fs.existsSync(dataDir + componentDirectory + "/" + componentName)){
fs.rmSync((dataDir + componentDirectory + "/" + componentName), { recursive: true, force: true })
return new Response('"deleted"', { status: 200})
} else {
return new Response('"Not found"', { status: 404})
}
break
case 'POST':
const newId = guid();
return createComponentDirectory(componentDirectory + "/" + componentName)
.then(createComponentFile(componentDirectory + "/" + componentName + "/" + newId, request))
.then(function() { return new Response(JSON.stringify(newId), { status: 201})})
.catch(function(){ return new Response('"something went wrong"', { status : 500 })}) // @TODO : return the error code
break
case 'PUT':
return createComponentDirectory(componentDirectory)
.then(createComponentFile(componentDirectory + "/" + componentName, request))
.then(function() { return new Response('"ok"', { status: 200})})
.catch(function(){ return new Response('"something went wrong"', { status : 500 })}) // @TODO : return the error code
break
case 'GET':
default:
if(fs.existsSync(dataDir + componentDirectory + "/" + componentName)){
const filestuff = readDataRecursive(componentDirectory + "/" + componentName)
return new Response(JSON.stringify(filestuff), {})
} else {
return new Response('"Not found"', { status: 404})
}
break
}
} else {
switch (request.method){
case 'OPTIONS':
if(fs.existsSync(dataDir + componentDirectory + "/" + componentName)){
return new Response('"ok"', { status: 200})
} else {
return new Response('"Not found"', { status: 404})
}
break
case 'DELETE':
if(fs.existsSync(dataDir + componentDirectory + "/" + componentName)){
fs.rmSync((dataDir + componentDirectory + "/" + componentName), { recursive: true, force: true })
return new Response('"deleted"', { status: 200})
} else {
return new Response('"Not found"', { status: 404})
}
break
case 'PUT':
return createComponentDirectory(componentDirectory)
.then(createComponentFile(componentDirectory + "/" + componentName, request))
.then(function() { return new Response('"ok"', { status: 200})})
.catch(function(){ return new Response('"something went wrong"', { status : 500 })}) // @TODO : return the error code
break
default:
if(componentPath.endsWith('\/')){
componentPath = componentPath.substring(0, (componentPath.length - 1))
}

if (!componentPath || componentPath === "/") {
const filestuff = fs.readFileSync(dataDir + '/generated.html')
return new Response(filestuff, {
headers: headers
// headers: { 'content-type': 'text/html' }
})

} else {
if (
(componentPath.indexOf("/js/simply") === 0) ||
(componentPath.indexOf("/simply") === 0) ||
(componentPath.indexOf("/hope") === 0)
) {
const filestuff = fs.readFileSync(__dirname + '/simplycode/' + componentDirectory + '\/' + componentName)
var target = dataDir + componentDirectory + '\/' + componentName;
let headers = {};
if (componentName.match(/\.svg$/)) {
headers = {
'content-type' : 'image/svg+xml'
}
}
if (componentName.match(/\.js$/)) {
headers = {
'content-type' : 'text/javascript'
}
}
if(fs.existsSync(target)) {
const filestuff = fs.readFileSync(target)
return new Response(filestuff, {
headers: headers
})
} else {
if (
(componentPath.indexOf("/js/simply") === 0) ||
(componentPath.indexOf("/simply") === 0) ||
(componentPath.indexOf("/assets") === 0) ||
(componentPath.indexOf("/hope") === 0)
) {
const filestuff = fs.readFileSync(__dirname + '/simplycode/' + componentDirectory + '\/' + componentName)
return new Response(filestuff, {
headers: headers
})
}
return new Response("Not found", {"status" : 404})
}
return new Response("Not found", {"status" : 404})
}
}
break
}
}
break
}
}
})

if (!process.argv[0].match(/electron$/) && process.argv[1]) {
Expand Down Expand Up @@ -443,4 +545,4 @@ app.on('certificate-error', (event, webContents, url, error, certificate, callba

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
})
Loading