diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/README.md b/README.md
index 96e832f..870d664 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,6 @@
-# electron-quick-start
+# xkcd-simplewriter
-**Clone and run for a quick way to see an Electron in action.**
+![](https://blogdotxkcddotcom.files.wordpress.com/2015/09/blag_words2.png)
-This is a minimal Electron application based on the [Quick Start Guide](http://electron.atom.io/docs/latest/tutorial/quick-start) within the Electron documentation.
+A desktop app version of the [XKCD simplewriter](http://xkcd.com/simplewriter/)
-A basic Electron application needs just these files:
-
-- `index.html` - A web page to render.
-- `main.js` - Starts the app and creates a browser window to render HTML.
-- `package.json` - Points to the app's main file and lists its details and dependencies.
-
-You can learn more about each of these components within the [Quick Start Guide](http://electron.atom.io/docs/latest/tutorial/quick-start).
-
-## To Use
-
-To clone and run this repository you'll need [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en/download/) (which comes with [npm](http://npmjs.com)) installed on your computer. From your command line:
-
-```bash
-# Clone this repository
-$ git clone https://github.com/atom/electron-quick-start
-# Go into the repository
-$ cd electron-quick-start
-# Install dependencies and run the app
-$ npm install && npm start
-```
-
-Learn more about Electron and its API in the [documentation](http://electron.atom.io/docs/latest).
-
-#### License [MIT](LICENSE.md)
diff --git a/index.html b/index.html
index 726aecb..fb400a6 100644
--- a/index.html
+++ b/index.html
@@ -1,9 +1,9 @@
-
-
+
+ SimpleWriter
upwriter
@@ -15,23 +15,17 @@ upwriter
+
diff --git a/main.css b/main.css
index cac98f4..95461bf 100644
--- a/main.css
+++ b/main.css
@@ -6,6 +6,7 @@ body {
line-height: 36px;
font-family: monospace;
}
+
#editor-wrapper {
margin: 0;
position: absolute;
@@ -15,6 +16,7 @@ body {
right: 0;
background: #F45C1A;
}
+
#editor {
margin: 0;
position: absolute;
@@ -28,20 +30,25 @@ body {
color: #444;
-webkit-transition: bottom .4s ease-in;
}
+
.ace_gutter {
display: none
}
+
.ace_disallowed,
.ace_disallowed + .ace_suffix {
color: #F45C1A
}
+
h1 {
visibility: hidden
}
+
#erroneous {
position: absolute;
bottom: 0;
}
+
#erroneous a {
color: #D0EACC;
display: inline-block;
diff --git a/main.js b/main.js
index f5755a2..275aec2 100644
--- a/main.js
+++ b/main.js
@@ -1,9 +1,12 @@
'use strict';
+const fs = require('fs');
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow; // Module to create native browser window.
-const ipcMain = electron.ipcMain;
+const dialog = electron.dialog;
+const Menu = electron.Menu;
+const MenuItem = electron.MenuItem;
// Report crashes to our server.
electron.crashReporter.start();
@@ -16,8 +19,7 @@ function createMainWindow() {
// Create the browser window.
const win = new BrowserWindow({
width: 800,
- height: 600,
- title: 'simplewriter'
+ height: 600
});
// and load the index.html of the app.
@@ -30,10 +32,148 @@ function createMainWindow() {
// when you should delete the corresponding element.
mainWindow = null;
});
-
return win;
}
+function setMenu() {
+ let template = [
+ {
+ label: 'File',
+ submenu: [
+ {
+ label: 'Open..',
+ accelerator: 'CmdOrCtrl+O',
+ click(item, focusedWindow) {
+ dialog.showOpenDialog(fileNames => {
+ if(fileNames === undefined) return;
+ let fileName = fileNames[0];
+ fs.readFile(fileName, 'utf-8', (err, data) => {
+ mainWindow.webContents.send('setText', data);
+ });
+ });
+ }
+ },
+ {
+ label: 'Save As..',
+ accelerator: 'CmdOrCtrl+S',
+ click(item, focusedWindow) {
+ dialog.showSaveDialog(fileName => {
+ if(fileName === undefined) return;
+ let arg = mainWindow.webContents.send('getText', '');
+ fs.writeFile(fileName, arg, err => {});
+ });
+ }
+ }
+ ]
+ },
+ {
+ label: 'View',
+ submenu: [
+ {
+ label: 'Reload',
+ accelerator: 'CmdOrCtrl+R',
+ click(item, focusedWindow) {
+ if(focusedWindow) focusedWindow.reload();
+ }
+ },
+ {
+ label: 'Toggle Full Screen',
+ accelerator: (() => (process.platform == 'darwin') ? 'Ctrl+Command+F' : 'F11')(),
+ click(item, focusedWin) {
+ if(focusedWin) focusedWin.setFullScreen(!focusedWin.isFullScreen());
+ }
+ },
+ {
+ label: 'Toggle Developer Tools',
+ accelerator: (() => (process.platform == 'darwin') ? 'Alt+Command+I' : 'Ctrl+Shift+I')(),
+ click(item, focusedWindow) {
+ if(focusedWindow) focusedWindow.toggleDevTools();
+ }
+ },
+ ]
+ },
+ {
+ label: 'Window',
+ role: 'window',
+ submenu: [
+ {
+ label: 'Minimize',
+ accelerator: 'CmdOrCtrl+M',
+ role: 'minimize'
+ },
+ {
+ label: 'Close',
+ accelerator: 'CmdOrCtrl+W',
+ role: 'close'
+ },
+ ]
+ },
+ {
+ label: 'Help',
+ role: 'help',
+ submenu: [
+ {
+ label: 'Learn More',
+ click() {
+ electron.shell.openExternal('http://electron.atom.io');
+ }
+ },
+ ]
+ },
+ ];
+
+ if (process.platform == 'darwin') {
+ let name = app.getName();
+ template.unshift({
+ label: name,
+ submenu: [
+ {
+ label: `About ${name}`,
+ role: 'about'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: `Hide ${name}`,
+ accelerator: 'Command+H',
+ role: 'hide'
+ },
+ {
+ label: 'Hide Others',
+ accelerator: 'Command+Shift+H',
+ role: 'hideothers'
+ },
+ {
+ label: 'Show All',
+ role: 'unhide'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Quit',
+ accelerator: 'Command+Q',
+ click() { app.quit(); }
+ },
+ ]
+ });
+ // Window menu.
+ template[3].submenu.push(
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Bring All to Front',
+ role: 'front'
+ }
+ );
+ }
+
+ let menu = Menu.buildFromTemplate(template);
+ Menu.setApplicationMenu(menu);
+}
+
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On OS X it is common for applications and their menu bar
@@ -51,4 +191,5 @@ app.on('activate', () => {
app.on('ready', () => {
mainWindow = createMainWindow();
-});
+ setMenu();
+});
\ No newline at end of file
diff --git a/mode-upwriter.js b/mode-upwriter.js
index 4475162..7b305b9 100644
--- a/mode-upwriter.js
+++ b/mode-upwriter.js
@@ -1,97 +1,93 @@
define("ace/mode/upwriter_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
-"use strict";
+ "use strict";
-var oop = require("../lib/oop");
-var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
-
-var UpwriterHighlightRules = function() {
+ const oop = require("../lib/oop");
+ const TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+ const UpwriterHighlightRules = function() {
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
-
- this.$rules =
- {
- "start": [
+ this.$rules = {
+ "start": [
{
- "token" : "suffix",
- "regex" : "['’][a-zA-Z]+"
+ "token" : "suffix",
+ "regex" : "['’][a-zA-Z]+"
},
{
- "token" : "allowed",
- "regex" : "\\b(?:" + window.__WORDS + ")\\b",
- "caseInsensitive": true
+ "token" : "allowed",
+ "regex" : "\\b(?:" + window.__WORDS + ")\\b",
+ "caseInsensitive": true
},
{
- "token" : "disallowed",
- "regex" : "[a-zA-Z]+"
+ "token" : "disallowed",
+ "regex" : "[a-zA-Z]+"
}
- ]
-}
-
-};
+ ]
+ }
+ };
-oop.inherits(UpwriterHighlightRules, TextHighlightRules);
+ oop.inherits(UpwriterHighlightRules, TextHighlightRules);
-exports.UpwriterHighlightRules = UpwriterHighlightRules;
+ exports.UpwriterHighlightRules = UpwriterHighlightRules;
});
define("ace/mode/upwriter",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/upwriter_highlight_rules"], function(require, exports, module) {
-"use strict";
+ "use strict";
-var oop = require("../lib/oop");
-var TextMode = require("./text").Mode;
-var UpwriterHighlightRules = require("./upwriter_highlight_rules").UpwriterHighlightRules;
+ const oop = require("../lib/oop");
+ const TextMode = require("./text").Mode;
+ const UpwriterHighlightRules = require("./upwriter_highlight_rules").UpwriterHighlightRules;
-var Mode = function() {
+ let Mode = function() {
this.HighlightRules = UpwriterHighlightRules;
-};
-oop.inherits(Mode, TextMode);
-
-Mode.prototype.$id = "ace/mode/upwriter";
-
-// // optimized, hence ugly for loops
-// Mode.prototype.getFirstDisallowed = function(editor) {
-// var session = editor.getSession();
-// var i, j, line, first, lines = session.doc.getAllLines();
-// outer: for (i = 0; i < lines.length; i++) {
-// line = session.getTokens(i);
-// for (j = 0; j < line.length; j++) {
-// if (line[j].type === "disallowed") {
-// first = line[j].value;
-// break outer;
-// }
-// }
-// }
-// return first;
-// };
-
-Mode.prototype.getDisallowed = function (editor) {
- var session = editor.getSession();
- return Object.keys(Array.apply(this, Array(session.doc.getAllLines().length)).reduce(function(m, _nil, i) {
- session.getTokens(i).forEach(function(token) {
- if (token.type === "disallowed") m[token.value] = true;
- });
- return m;
- }, {}));
-}
-
-
-Mode.prototype.onRecalculateAllowed = function(editor, cb) {
- var self = this;
- editor.getSession().on('change', debounce(function() {
- cb(self.getDisallowed(editor));
- }, 500));
-};
-
-exports.Mode = Mode;
-
-function debounce(fn, delay) {
- return function() {
- fn.args = arguments;
- fn.timeout_id && clearTimeout(fn.timeout_id);
- fn.timeout_id = setTimeout(function() { return fn.apply(fn, fn.args); }, delay);
};
-}
+ oop.inherits(Mode, TextMode);
+
+ Mode.prototype.$id = "ace/mode/upwriter";
+
+ // // optimized, hence ugly for loops
+ // Mode.prototype.getFirstDisallowed = function(editor) {
+ // var session = editor.getSession();
+ // var i, j, line, first, lines = session.doc.getAllLines();
+ // outer: for (i = 0; i < lines.length; i++) {
+ // line = session.getTokens(i);
+ // for (j = 0; j < line.length; j++) {
+ // if (line[j].type === "disallowed") {
+ // first = line[j].value;
+ // break outer;
+ // }
+ // }
+ // }
+ // return first;
+ // };
+
+ Mode.prototype.getDisallowed = function(editor) {
+ let session = editor.getSession();
+ return Object.keys(Array.apply(this, Array(session.doc.getAllLines().length)).reduce(function(m, _nil, i) {
+ session.getTokens(i).forEach(function(token) {
+ if (token.type === "disallowed") m[token.value] = true;
+ });
+ return m;
+ }, {}));
+ };
+
+
+ Mode.prototype.onRecalculateAllowed = function(editor, cb) {
+ let self = this;
+ editor.getSession().on('change', debounce(function() {
+ cb(self.getDisallowed(editor));
+ }, 500));
+ };
+
+ exports.Mode = Mode;
+
+ function debounce(fn, delay) {
+ return function() {
+ fn.args = arguments;
+ fn.timeout_id && clearTimeout(fn.timeout_id);
+ fn.timeout_id = setTimeout(function() { return fn.apply(fn, fn.args); }, delay);
+ };
+ }
});
\ No newline at end of file
diff --git a/package.json b/package.json
index 3dcf3c2..e8f5438 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,6 @@
{
"name": "xkcd-simplewriter",
+ "productName": "SimpleWriter",
"version": "1.0.0",
"description": "An Electron App of the XKCD Simple Writer",
"main": "main.js",
@@ -27,5 +28,6 @@
"homepage": "https://github.com/tcyrus/xkcd-simplewriter#readme",
"devDependencies": {
"electron-prebuilt": "^0.34.0"
- }
+ },
+ "dependencies": {}
}