├── .gitignore ├── LICENSE.md ├── README.md ├── electronica.js ├── exercises ├── application_packaging │ ├── exercise.js │ ├── problem.ja.md │ └── solution │ │ └── solution.js ├── electron_packager │ ├── exercise.js │ ├── problem.ja.md │ ├── problem.md │ └── solution │ │ └── solution.js ├── hello_electron │ ├── exercise.js │ ├── problem.ja.md │ ├── problem.md │ └── solution │ │ └── solution.js ├── menu.json ├── online_offline │ ├── exercise.js │ ├── problem.ja.md │ ├── problem.md │ └── solution │ │ └── solution.js ├── photon_kit │ ├── exercise.js │ ├── problem.ja.md │ └── solution │ │ └── solution.js ├── program.js ├── verify.js ├── webview │ ├── exercise.js │ ├── problem.ja.md │ └── solution │ │ └── solution.js └── webview_favorite │ ├── exercise.js │ ├── problem.ja.md │ ├── problem.md │ └── solution │ └── solution.js ├── i18n └── ja.json ├── index.js ├── package.json └── script └── copyToTmp.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.swp 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 yosuke-furukawa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # electronica 2 | 3 | electronica is a workshop application for Electron. 4 | 5 | # How to start 6 | 7 | ``` 8 | $ npm install electronica -g 9 | $ electronica 10 | ``` 11 | 12 | ![img1](https://cloud.githubusercontent.com/assets/555645/12064131/9a279644-affe-11e5-865a-86f91264f28f.png) 13 | 14 | if you solved all exercise, you can create a mini-browser like this. 15 | 16 | ![img2](https://cloud.githubusercontent.com/assets/555645/12064132/9f267cd2-affe-11e5-88d8-179ce0769c89.png) 17 | 18 | -------------------------------------------------------------------------------- /electronica.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const workshopper = require('workshopper-adventure'); 4 | const path = require('path'); 5 | 6 | function fpath (f) { 7 | return path.join(__dirname, f); 8 | } 9 | 10 | workshopper({ 11 | name : 'electronica', 12 | title : 'Electronica', 13 | subtitle : 'Rock and Roll, Electronica!', 14 | appDir : __dirname, 15 | languages : ['ja'], 16 | exerciseDir : fpath('./exercises/') 17 | }); 18 | -------------------------------------------------------------------------------- /exercises/application_packaging/exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var exercise = require('workshopper-exercise')(); 4 | var filecheck = require('workshopper-exercise/filecheck'); 5 | var execute = require('workshopper-exercise/execute'); 6 | var comparestdout = require('workshopper-exercise/comparestdout'); 7 | 8 | module.exports = comparestdout(execute(filecheck(exercise))); 9 | 10 | module.exports.addSetup(function(mode, cb) { 11 | process.nextTick(cb); 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /exercises/application_packaging/problem.ja.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Application を packaging する方法を学びましょう。 4 | ココで言うapplication packaging とは、ファイルを1つに結合してまとめることを指します。 5 | 6 | まとめることで、Windows の 255バイト以上のパスを持つファイルを作成できない問題や require の高速化に繋がります。 7 | 8 | # パッケージを作成するには 9 | 10 | `asar` アーカイブを作成します。 `asar` というのは `tar` と同じように複数のファイルを1つのファイルに繋げて保存する形式です。パッケージを解凍しなくても任意のファイルを読み込むことができます。 11 | 12 | では実際にパッケージを作ってみましょう。 13 | 14 | 1. asar ユーティリティをインストールします 15 | 16 | ``` 17 | $ npm install -g asar 18 | ``` 19 | 20 | 2. `asar pack` でパッケージングする 21 | 22 | ``` 23 | $ asar pack your-app app.asar 24 | ``` 25 | 26 | 3. `asar list` でパッケージ化された中身を見る。 27 | 28 | ``` 29 | $ asar list app.asar 30 | ``` 31 | 32 | こうして作られた `asar` パッケージはファイルとして読み込むこともできますが、直接 `electron` から実行することもできます。 33 | 34 | ``` 35 | $ electron app.asar 36 | ``` 37 | 38 | # 問題 39 | 40 | `Hello electron` で作ったボタンだけのアプリケーションを `asar` でパッケージングしてみましょう。 41 | 42 | パッケージングしたアプリケーションを実際に実行して、中の`DONE`ボタンを押し、実行完了させてください。 43 | -------------------------------------------------------------------------------- /exercises/application_packaging/solution/solution.js: -------------------------------------------------------------------------------- 1 | const parentFile = process.env.parent_filename; 2 | const fs = require('fs'); 3 | const keywords = ['asar']; 4 | 5 | const result = keywords.filter((keyword) => parentFile.indexOf(keyword) !== -1); 6 | 7 | if (result.length === keywords.length) { 8 | console.log("Congrats!!!"); 9 | } else { 10 | console.error("Your file does not have keywords"); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /exercises/electron_packager/exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var exercise = require('workshopper-exercise')(); 4 | var filecheck = require('workshopper-exercise/filecheck'); 5 | var execute = require('workshopper-exercise/execute'); 6 | var comparestdout = require('workshopper-exercise/comparestdout'); 7 | 8 | module.exports = comparestdout(execute(filecheck(exercise))); 9 | 10 | module.exports.addSetup(function(mode, cb) { 11 | process.nextTick(cb); 12 | }); 13 | -------------------------------------------------------------------------------- /exercises/electron_packager/problem.ja.md: -------------------------------------------------------------------------------- 1 | # Electron Packager 2 | 3 | `asar` でパッケージングしたファイルは `electron` が入っているユーザーにしか実行できません。この回では、 作ったアプリを配布する方法を学びましょう。 4 | 5 | # そもそもアプリケーションを配布するとは 6 | 7 | アプリケーションを実行可能な環境で配布するにはいくつかの前提知識が必要になります。 8 | 9 | Mac OS の場合、以下の様なフォルダ構成でファイルが存在している必要があります。 10 | 11 | ``` 12 | electron/Electron.app/Contents/Resources/app/ 13 | ├── package.json 14 | ├── main.js 15 | └── index.html 16 | ``` 17 | 18 | WindowsやLinuxの場合は以下の様なフォルダ構成でファイルが存在している必要があります。 19 | 20 | ``` 21 | electron/resources/app 22 | ├── package.json 23 | ├── main.js 24 | └── index.html 25 | ``` 26 | 27 | asar を使っておくと以下のようにまとめることができるようになるので、まとめておきましょう。 28 | 29 | ``` 30 | electron/resources/ 31 | └── app.asar 32 | ``` 33 | 34 | windows の場合は255文字までしかパスに含められないので、こういう場合には必須になります。 35 | さらにこの上で electron の実行ファイルを内包する必要があります。 36 | 37 | # electron-packagerを利用する 38 | 39 | 上記のようなことを手でやるのはとても面倒なので、ライブラリを利用しましょう。 40 | 41 | Electronの実行環境を `asar` と一緒にコンパイルして実行してくれる、`electron-packager` というライブラリを利用します。 42 | 43 | 実際に活用してみましょう。 44 | 45 | ``` 46 | $ npm install electron-packager -g 47 | ``` 48 | 49 | ``` 50 | $ electron-packager --platform= --arch= --version= 51 | ``` 52 | 53 | 54 | # 問題 55 | 56 | 実際に先ほど作ったアプリを `electron-packager` で配布可能なパッケージにしてみましょう。 57 | 自分のローカルに保存し、ファイルを実行してみましょう。 58 | -------------------------------------------------------------------------------- /exercises/electron_packager/problem.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | これから `Electron` に関してのエクササイズを開始します。 `Electron` はデスクトップアプリケーションを作るためのフレームワークです。本フレームワークを活用することでJavaScript/HTML/CSSでデスクトップアプリケーションを作ることができるようになります。 4 | 5 | 概要を解説するために、[Quick start](https://github.com/atom/electron/blob/master/docs-translations/jp/tutorial/quick-start.md) をよく読んでおくことをおすすめします。 6 | まず最初に `Electron` を作るための環境構築をしましょう。 7 | 8 | ``` 9 | $ mkdir electronica1 10 | $ cd electronica1 11 | $ npm init -y 12 | ``` 13 | 14 | # Hello Electron アプリケーションを作る 15 | 16 | electronica1 フォルダの中で `index.js` という名前のファイルを作り中身を下記のように記述してください。 17 | 18 | ```javascript 19 | 'use strict'; 20 | const electron = require('electron'); 21 | const app = electron.app; 22 | const BrowserWindow = electron.BrowserWindow; 23 | 24 | // Report crashes to our server. 25 | electron.crashReporter.start(); 26 | 27 | // Keep a global reference of the window object, if you don't, the window will 28 | // be closed automatically when the JavaScript object is garbage collected. 29 | var mainWindow = null; 30 | 31 | // Quit when all windows are closed. 32 | app.on('window-all-closed', function() { 33 | // Mac OS だったらアプリケーションを殺さない 34 | if (process.platform != 'darwin') { 35 | app.quit(); 36 | } 37 | }); 38 | 39 | app.on('ready', function() { 40 | // Create the browser window. 41 | mainWindow = new BrowserWindow({width: 800, height: 600}); 42 | 43 | // and load the index.html of the app. 44 | mainWindow.loadURL('file://' + __dirname + '/index.html'); 45 | 46 | // Open the DevTools. 47 | mainWindow.webContents.openDevTools(); 48 | 49 | mainWindow.on('closed', function() { 50 | mainWindow = null; 51 | }); 52 | }); 53 | ``` 54 | 55 | 同じフォルダの中で `index.html` を作成し、下記のように記述してください。 56 | 57 | ```html 58 | 59 | 60 | 61 | 62 | Hello Electron! 63 | 64 | 65 |

Hello Electron!

66 | node version , 67 | Chrome version , 68 | Electron version . 69 | 70 | 71 | ``` 72 | 73 | フォルダ全体の構成が下記のようになっていることを確認してください。 74 | 75 | ```tree 76 | electronica1/ 77 | ├── package.json 78 | ├── index.js 79 | └── index.html 80 | ``` 81 | 82 | さらに `Electron` を実行するためのモジュールをインストールします。 83 | 84 | ``` 85 | $ npm install electron-prebuilt --save 86 | ``` 87 | 88 | 終わったら `package.json` を開き下記のようにファイルを修正してください。 89 | 90 | ``` 91 | { 92 | "name": "electroinca1", 93 | "version": "0.0.1", 94 | "main": "index.js", 95 | "scripts": { 96 | "start": "electron index.js" // scriptsに electron index.js を足す 97 | }, 98 | "devDependencies": { 99 | "electron-prebuilt": "^0.35.0" 100 | } 101 | } 102 | ``` 103 | 104 | -------------------------------------------------------------------------------- /exercises/electron_packager/solution/solution.js: -------------------------------------------------------------------------------- 1 | const parentFile = process.env.parent_filename; 2 | const fs = require('fs'); 3 | const file = fs.readFileSync(parentFile).toString(); 4 | const keywords = ['button', 'html', 'body', 'script']; 5 | 6 | const result = keywords.filter((keyword) => file.indexOf(keyword) !== -1); 7 | 8 | if (result.length === keywords.length) { 9 | console.log("Congrats!!!"); 10 | } else { 11 | console.error("Your file does not have keywords"); 12 | } 13 | -------------------------------------------------------------------------------- /exercises/hello_electron/exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var exercise = require('workshopper-exercise')(); 4 | var filecheck = require('workshopper-exercise/filecheck'); 5 | var execute = require('workshopper-exercise/execute'); 6 | var comparestdout = require('workshopper-exercise/comparestdout'); 7 | 8 | module.exports = comparestdout(execute(filecheck(exercise))); 9 | 10 | module.exports.addSetup(function(mode, cb) { 11 | process.nextTick(cb); 12 | }); 13 | -------------------------------------------------------------------------------- /exercises/hello_electron/problem.ja.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | これから `Electron` に関してのエクササイズを開始します。 `Electron` はデスクトップアプリケーションを作るためのフレームワークです。本フレームワークを活用することでJavaScript/HTML/CSSでデスクトップアプリケーションを作ることができるようになります。 4 | 5 | 概要を解説するために、[Quick start](https://github.com/atom/electron/blob/master/docs-translations/jp/tutorial/quick-start.md) をよく読んでおくことをおすすめします。 6 | まず最初に `Electron` を作るための環境構築をしましょう。 7 | 8 | ``` 9 | $ mkdir electronica_test 10 | $ cd electronica_test 11 | $ npm init -y 12 | ``` 13 | 14 | # Hello Electron アプリケーションを作る 15 | 16 | `electronica_test` フォルダの中で `index.js` という名前のファイルを作り中身を下記のように記述してください。 17 | 18 | ```javascript 19 | 'use strict'; 20 | const electron = require('electron'); 21 | const app = electron.app; 22 | const BrowserWindow = electron.BrowserWindow; 23 | 24 | // Report crashes to our server. 25 | electron.crashReporter.start( 26 | 'companyName': '', 27 | 'submitURL': '' 28 | ); 29 | 30 | // Keep a global reference of the window object, if you don't, the window will 31 | // be closed automatically when the JavaScript object is garbage collected. 32 | var mainWindow = null; 33 | 34 | // Quit when all windows are closed. 35 | app.on('window-all-closed', function() { 36 | app.quit(); 37 | }); 38 | 39 | app.on('ready', function() { 40 | // Create the browser window. 41 | mainWindow = new BrowserWindow({width: 800, height: 600}); 42 | 43 | // and load the index.html of the app. 44 | mainWindow.loadURL('file://' + __dirname + '/index.html'); 45 | 46 | // Open the DevTools. 47 | mainWindow.webContents.openDevTools(); 48 | 49 | mainWindow.on('closed', function() { 50 | mainWindow = null; 51 | }); 52 | }); 53 | ``` 54 | 55 | 同じフォルダの中で `index.html` を作成し、下記のように記述してください。 56 | 57 | ```html 58 | 59 | 60 | 61 | 62 | Hello Electron! 63 | 64 | 65 |

Hello Electron!

66 | node version
, 67 | Chrome version
, 68 | Electron version
. 69 | 70 | 71 | ``` 72 | 73 | フォルダ全体の構成が下記のようになっていることを確認してください。 74 | 75 | ```tree 76 | electronica/ 77 | ├── package.json 78 | ├── index.js 79 | └── index.html 80 | ``` 81 | 82 | さらに `Electron` を実行するためのモジュールをインストールします。 83 | 84 | ``` 85 | $ npm install electron-prebuilt --save 86 | ``` 87 | 88 | 終わったら `package.json` を開き下記のようにファイルを修正してください。 89 | 90 | ``` 91 | { 92 | "name": "electroinca", 93 | "version": "0.0.1", 94 | "main": "index.js", 95 | "scripts": { 96 | "start": "electron index.js" 97 | }, 98 | "devDependencies": { 99 | "electron-prebuilt": "^0.35.0" 100 | } 101 | } 102 | ``` 103 | 104 | ``` 105 | $ npm start 106 | ``` 107 | 108 | 実行したら、ブラウザが起動し、下記のような情報が表示されていることを確認してください。 109 | 110 | ``` 111 | node version 4.1.1 112 | Chrome version 45.0.2454.85 113 | Electron version 0.35.1 114 | ``` 115 | 116 | # 問題 117 | 118 | 今作成したプロジェクトに`DONE`ボタンを配置し、`DONE`が押下されたら検証をパスするようにしてみましょう。 119 | 120 | まずは `electronica` をローカルにインストールしてください。 121 | 122 | ``` 123 | $ npm install electronica --save 124 | ``` 125 | 126 | 127 | 下記のような script タグを持つファイルを index.html に書きましょう。 128 | 129 | ```html 130 | 136 | ``` 137 | 138 | buttonタグをindex.htmlに配置し、クリックしたら`done`関数を呼び出すように追加してください。 139 | 140 | -------------------------------------------------------------------------------- /exercises/hello_electron/problem.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | これから `Electron` に関してのエクササイズを開始します。 `Electron` はデスクトップアプリケーションを作るためのフレームワークです。本フレームワークを活用することでJavaScript/HTML/CSSでデスクトップアプリケーションを作ることができるようになります。 4 | 5 | 概要を解説するために、[Quick start](https://github.com/atom/electron/blob/master/docs-translations/jp/tutorial/quick-start.md) をよく読んでおくことをおすすめします。 6 | まず最初に `Electron` を作るための環境構築をしましょう。 7 | 8 | ``` 9 | $ mkdir electronica1 10 | $ cd electronica1 11 | $ npm init -y 12 | ``` 13 | 14 | # Hello Electron アプリケーションを作る 15 | 16 | electronica1 フォルダの中で `index.js` という名前のファイルを作り中身を下記のように記述してください。 17 | 18 | ```javascript 19 | 'use strict'; 20 | const electron = require('electron'); 21 | const app = electron.app; 22 | const BrowserWindow = electron.BrowserWindow; 23 | 24 | // Report crashes to our server. 25 | electron.crashReporter.start({ 26 | 'companyName': '', 27 | 'submitURL': '' 28 | }); 29 | 30 | // Keep a global reference of the window object, if you don't, the window will 31 | // be closed automatically when the JavaScript object is garbage collected. 32 | var mainWindow = null; 33 | 34 | // Quit when all windows are closed. 35 | app.on('window-all-closed', function() { 36 | // Mac OS だったらアプリケーションを殺さない 37 | if (process.platform != 'darwin') { 38 | app.quit(); 39 | } 40 | }); 41 | 42 | app.on('ready', function() { 43 | // Create the browser window. 44 | mainWindow = new BrowserWindow({width: 800, height: 600}); 45 | 46 | // and load the index.html of the app. 47 | mainWindow.loadURL('file://' + __dirname + '/index.html'); 48 | 49 | // Open the DevTools. 50 | mainWindow.webContents.openDevTools(); 51 | 52 | mainWindow.on('closed', function() { 53 | mainWindow = null; 54 | }); 55 | }); 56 | ``` 57 | 58 | 同じフォルダの中で `index.html` を作成し、下記のように記述してください。 59 | 60 | ```html 61 | 62 | 63 | 64 | 65 | Hello Electron! 66 | 67 | 68 |

Hello Electron!

69 | node version , 70 | Chrome version , 71 | Electron version . 72 | 73 | 74 | ``` 75 | 76 | フォルダ全体の構成が下記のようになっていることを確認してください。 77 | 78 | ```tree 79 | electronica1/ 80 | ├── package.json 81 | ├── index.js 82 | └── index.html 83 | ``` 84 | 85 | さらに `Electron` を実行するためのモジュールをインストールします。 86 | 87 | ``` 88 | $ npm install electron-prebuilt --save 89 | ``` 90 | 91 | 終わったら `package.json` を開き下記のようにファイルを修正してください。 92 | 93 | ``` 94 | { 95 | "name": "electroinca1", 96 | "version": "0.0.1", 97 | "main": "index.js", 98 | "scripts": { 99 | "start": "electron index.js" // scriptsに electron index.js を足す 100 | }, 101 | "devDependencies": { 102 | "electron-prebuilt": "^0.35.0" 103 | } 104 | } 105 | ``` 106 | 107 | -------------------------------------------------------------------------------- /exercises/hello_electron/solution/solution.js: -------------------------------------------------------------------------------- 1 | const parentFile = process.env.parent_filename; 2 | const fs = require('fs'); 3 | const file = fs.readFileSync(parentFile).toString(); 4 | const keywords = ['button', 'html', 'body', 'script']; 5 | 6 | const result = keywords.filter((keyword) => file.indexOf(keyword) !== -1); 7 | 8 | if (result.length === keywords.length) { 9 | console.log("Congrats!!!"); 10 | } else { 11 | console.error("Your file does not have keywords"); 12 | } 13 | -------------------------------------------------------------------------------- /exercises/menu.json: -------------------------------------------------------------------------------- 1 | [ 2 | "HELLO ELECTRON", 3 | "APPLICATION PACKAGING", 4 | "ELECTRON PACKAGER", 5 | "PHOTON KIT", 6 | "ONLINE OFFLINE", 7 | "WEBVIEW", 8 | "WEBVIEW_FAVORITE" 9 | ] 10 | -------------------------------------------------------------------------------- /exercises/online_offline/exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var exercise = require('workshopper-exercise')(); 4 | var filecheck = require('workshopper-exercise/filecheck'); 5 | var execute = require('workshopper-exercise/execute'); 6 | var comparestdout = require('workshopper-exercise/comparestdout'); 7 | 8 | module.exports = comparestdout(execute(filecheck(exercise))); 9 | 10 | module.exports.addSetup(function(mode, cb) { 11 | process.nextTick(cb); 12 | }); 13 | -------------------------------------------------------------------------------- /exercises/online_offline/problem.ja.md: -------------------------------------------------------------------------------- 1 | # Online Offline 2 | 3 | Online か Offline かを示すイベントがあります。実際には 普通に `online` と `offline` を示すイベントを受け取るか、 `navigator.onLine` というメソッドを呼び出すと実施できます。 4 | 5 | 6 | ```html 7 | 17 | ``` 18 | 19 | # 問題 20 | 21 | オンラインイベントを受け取り、画面上にオンラインかオフラインかを表示させてみましょう。 22 | 23 | オンラインだったらFooterに`online` オフラインだったら `offline` と書くようにしてみましょう。 24 | 25 | -------------------------------------------------------------------------------- /exercises/online_offline/problem.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | これから `Electron` に関してのエクササイズを開始します。 `Electron` はデスクトップアプリケーションを作るためのフレームワークです。本フレームワークを活用することでJavaScript/HTML/CSSでデスクトップアプリケーションを作ることができるようになります。 4 | 5 | 概要を解説するために、[Quick start](https://github.com/atom/electron/blob/master/docs-translations/jp/tutorial/quick-start.md) をよく読んでおくことをおすすめします。 6 | まず最初に `Electron` を作るための環境構築をしましょう。 7 | 8 | ``` 9 | $ mkdir electronica1 10 | $ cd electronica1 11 | $ npm init -y 12 | ``` 13 | 14 | # Hello Electron アプリケーションを作る 15 | 16 | electronica1 フォルダの中で `index.js` という名前のファイルを作り中身を下記のように記述してください。 17 | 18 | ```javascript 19 | 'use strict'; 20 | const electron = require('electron'); 21 | const app = electron.app; 22 | const BrowserWindow = electron.BrowserWindow; 23 | 24 | // Report crashes to our server. 25 | electron.crashReporter.start(); 26 | 27 | // Keep a global reference of the window object, if you don't, the window will 28 | // be closed automatically when the JavaScript object is garbage collected. 29 | var mainWindow = null; 30 | 31 | // Quit when all windows are closed. 32 | app.on('window-all-closed', function() { 33 | // Mac OS だったらアプリケーションを殺さない 34 | if (process.platform != 'darwin') { 35 | app.quit(); 36 | } 37 | }); 38 | 39 | app.on('ready', function() { 40 | // Create the browser window. 41 | mainWindow = new BrowserWindow({width: 800, height: 600}); 42 | 43 | // and load the index.html of the app. 44 | mainWindow.loadURL('file://' + __dirname + '/index.html'); 45 | 46 | // Open the DevTools. 47 | mainWindow.webContents.openDevTools(); 48 | 49 | mainWindow.on('closed', function() { 50 | mainWindow = null; 51 | }); 52 | }); 53 | ``` 54 | 55 | 同じフォルダの中で `index.html` を作成し、下記のように記述してください。 56 | 57 | ```html 58 | 59 | 60 | 61 | 62 | Hello Electron! 63 | 64 | 65 |

Hello Electron!

66 | node version , 67 | Chrome version , 68 | Electron version . 69 | 70 | 71 | ``` 72 | 73 | フォルダ全体の構成が下記のようになっていることを確認してください。 74 | 75 | ```tree 76 | electronica1/ 77 | ├── package.json 78 | ├── index.js 79 | └── index.html 80 | ``` 81 | 82 | さらに `Electron` を実行するためのモジュールをインストールします。 83 | 84 | ``` 85 | $ npm install electron-prebuilt --save 86 | ``` 87 | 88 | 終わったら `package.json` を開き下記のようにファイルを修正してください。 89 | 90 | ``` 91 | { 92 | "name": "electroinca1", 93 | "version": "0.0.1", 94 | "main": "index.js", 95 | "scripts": { 96 | "start": "electron index.js" // scriptsに electron index.js を足す 97 | }, 98 | "devDependencies": { 99 | "electron-prebuilt": "^0.35.0" 100 | } 101 | } 102 | ``` 103 | 104 | -------------------------------------------------------------------------------- /exercises/online_offline/solution/solution.js: -------------------------------------------------------------------------------- 1 | const parentFile = process.env.parent_filename; 2 | const fs = require('fs'); 3 | const file = fs.readFileSync(parentFile).toString(); 4 | const keywords = ['button', 'html', 'body', 'script']; 5 | 6 | const result = keywords.filter((keyword) => file.indexOf(keyword) !== -1); 7 | 8 | if (result.length === keywords.length) { 9 | console.log("Congrats!!!"); 10 | } else { 11 | console.error("Your file does not have keywords"); 12 | } 13 | -------------------------------------------------------------------------------- /exercises/photon_kit/exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var exercise = require('workshopper-exercise')(); 4 | var filecheck = require('workshopper-exercise/filecheck'); 5 | var execute = require('workshopper-exercise/execute'); 6 | var comparestdout = require('workshopper-exercise/comparestdout'); 7 | 8 | module.exports = comparestdout(execute(filecheck(exercise))); 9 | 10 | module.exports.addSetup(function(mode, cb) { 11 | process.nextTick(cb); 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /exercises/photon_kit/problem.ja.md: -------------------------------------------------------------------------------- 1 | # Photon を使って UI を作ってみる。 2 | 3 | Photonというのは、Mac OS 風のUIを提供するツールキットです。これを利用することで一気に普通のWebからデスクトップアプリケーションっぽいUIを持ったアプリが作成できます。 4 | 5 | Photonをダウンロードするところから始めてみましょう。 6 | 7 | まずは `Getting Started` のページに行きましょう。 8 | 9 | ``` 10 | $ open http://photonkit.com/getting-started/ 11 | ``` 12 | 13 | `Download` のボタンを押して、zipファイルを展開し、任意のフォルダに保存してください。 14 | 15 | ``` 16 | $ cp -r /path/to/photon-dist photon 17 | ``` 18 | 19 | フォルダの中が以下のようになっていることを確認してください。 20 | 21 | ``` 22 | photon/ 23 | ├── css/ 24 | │ ├── photon.css 25 | │ ├── photon.min.css 26 | ├── fonts/ 27 | │ ├── photon-entypo.eot 28 | │ ├── photon-entypo.svg 29 | │ ├── photon-entypo.ttf 30 | │ └── photon-entypo.woff 31 | └── template-app/ 32 | ├── js/ 33 | │ └── menu.js 34 | ├── app.js 35 | ├── index.html 36 | └── package.json 37 | ``` 38 | 39 | この cssフォルダと font フォルダを使って読み込みます。 40 | 41 | css と font フォルダを自分が作ったプロジェクトに移動し、下記のようなフォルダ構成になるようにしてください。 42 | 43 | ``` 44 | electronica/ 45 | ├── css/ 46 | │ ├── photon.css 47 | │ ├── photon.min.css 48 | ├── fonts/ 49 | │ ├── photon-entypo.eot 50 | │ ├── photon-entypo.svg 51 | │ ├── photon-entypo.ttf 52 | │ └── photon-entypo.woff 53 | ├── package.json 54 | ├── index.js 55 | └── index.html 56 | ``` 57 | 58 | # index.html に css を読みこませる 59 | 60 | CSS ファイルを HTMLから読み込ませてみましょう。 61 | 62 | ```html 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Hello Electron! 71 | 72 | 73 |

Hello Electron!

74 | node version
, 75 | Chrome version
, 76 | Electron version
. 77 | 78 | 79 | ``` 80 | 81 | これで準備完了です。試していきましょう。 82 | 83 | # .window .window-content でウィンドウを作る。 84 | 85 | ```html 86 | 87 | 88 | 89 | 90 | 91 | 92 | Hello Electron! 93 | 94 | 95 |

Hello Electron!

96 |
97 |
98 | Main Window Content 99 |
100 |
101 | 102 | 103 | ``` 104 | 105 | これが一番初期の `window-content` しかない状態です。実際に表示させてどうなるか確認してください。 106 | 107 | # .pane-group .pane で複数ペインを持つウィンドウを作る。 108 | 109 | ```html 110 | 111 | 112 | 113 | 114 | 115 | 116 | Hello Electron! 117 | 118 | 119 |

Hello Electron!

120 |
121 |
122 |
123 |
first pane
124 |
second pane
125 |
third pane
126 |
127 |
128 |
129 | 130 | 131 | ``` 132 | 133 | 3つの pane が横に並んだ状態です。実際に表示させてどうなるか確認してください。 134 | 135 | # Sidebar layout 136 | 137 | ```html 138 | 139 | 140 | 141 | 142 | 143 | 144 | Hello Electron! 145 | 146 | 147 |

Hello Electron!

148 |
149 |
150 |
151 | 152 |
main pane
153 |
154 |
155 |
156 | 157 | 158 | ``` 159 | 160 | サイドに少しだけせまいpaneを作ります。これを使うとサイドバーのようなバーが作れます。 161 | 162 | # toolbar layout 163 | 164 | ```html 165 | 166 | 167 | 168 | 169 | 170 | 171 | Hello Electron! 172 | 173 | 174 |
175 |
176 |

Hello Electron!

177 |
178 |
179 |
180 | 181 |
main pane
182 |
183 |
184 |
185 |

Footer

186 |
187 |
188 | 189 | 190 | ``` 191 | 192 | # 問題 193 | 194 | toolbar に リロードボタンを付けてみましょう。 195 | 196 | toolbar にアイコンを追加するには、`toolbar-actions` class を利用します。 197 | 198 | 199 | ```html 200 |
201 | 205 |
206 | ``` 207 | 208 | またリロードボタンを押したらちゃんとページがリロードされるようにしてみましょう。 209 | 210 | ```javascript 211 | 217 | ``` 218 | 219 | 220 | -------------------------------------------------------------------------------- /exercises/photon_kit/solution/solution.js: -------------------------------------------------------------------------------- 1 | const parentFile = process.env.parent_filename; 2 | const fs = require('fs'); 3 | const keywords = ['icon-arrows-ccw', 'window-content', 'toolbar-actions']; 4 | 5 | const result = keywords.filter((keyword) => parentFile.indexOf(keyword) !== -1); 6 | 7 | if (result.length === keywords.length) { 8 | console.log("Congrats!!!"); 9 | } else { 10 | console.error("Your file does not have keywords"); 11 | } 12 | 13 | 14 | -------------------------------------------------------------------------------- /exercises/program.js: -------------------------------------------------------------------------------- 1 | console.log("Congrats!!!"); 2 | 3 | -------------------------------------------------------------------------------- /exercises/verify.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const workshopperExercise = require('workshopper-exercise'); 6 | const expectedKeywords = [/done/i, /button/i, /script/i]; 7 | 8 | module.exports = function() { 9 | const file = module.parent.parent.filename; 10 | const content = fs.readFileSync(file).toString(); 11 | const answers = expectedKeywords.filter((keyword) => content.match(keyword)); 12 | console.log(workshopperExercise); 13 | if (answers.length === expectedKeywords.length) { 14 | console.log(`Congrats`); 15 | } else { 16 | console.log(`Failure`); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /exercises/webview/exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var exercise = require('workshopper-exercise')(); 4 | var filecheck = require('workshopper-exercise/filecheck'); 5 | var execute = require('workshopper-exercise/execute'); 6 | var comparestdout = require('workshopper-exercise/comparestdout'); 7 | 8 | module.exports = comparestdout(execute(filecheck(exercise))); 9 | 10 | module.exports.addSetup(function(mode, cb) { 11 | process.nextTick(cb); 12 | }); 13 | -------------------------------------------------------------------------------- /exercises/webview/problem.ja.md: -------------------------------------------------------------------------------- 1 | # WebView 2 | 3 | `electron` のwebview タグの機能を使って既存のウェブサイトを埋め込んでみましょう。この機能を使うことで、いわゆる `iframe` を使ってウェブサイトをくるんだような状態にして、既存のウェブサイトのクライアントを作ることができるようになります。 4 | 5 | 6 | # webview タグ 7 | 8 | electron の html 上には `webview` というタグが有効になっています。 9 | 10 | ```html 11 | 12 | ``` 13 | 14 | `src` にウェブサイトのURLを設定します。 15 | `autosize` は縦横幅の変更に自動的に追従する属性です。 16 | `minwidth` `minheight` は最小の横幅と高さです。 17 | 18 | webview タグは普通のdom要素なので、JavaScriptで操作することも可能です。 19 | 20 | ```html 21 | 36 | ``` 37 | 38 | # 問題 39 | 40 | webview タグを利用して、任意のウェブサイトを読み込んでみましょう。 41 | 前回作成したアプリケーションのmain paneに対してwebview タグが表示されるようにしましょう。 42 | 43 | ちょっとブラウザっぽくするために先ほど作った `reload` ボタンを webview の中が更新されるようにして、 戻るための `back` ボタンと進むための `forward` ボタンも追加してみましょう。 44 | 45 | # ヒント 46 | 47 | `webview` のメソッドとして `reload()` と `goBack()` と `goForward()` というメソッドが存在します。 48 | これを使うと戻る、進む、更新がwebview内で実現できます。 49 | 50 | # ヒント 51 | 52 | `webview` の高さのサイズがうまくいかない場合は `height:100%;` をwebviewタグに設定してみましょう。  53 | -------------------------------------------------------------------------------- /exercises/webview/solution/solution.js: -------------------------------------------------------------------------------- 1 | const parentFile = process.env.parent_filename; 2 | const fs = require('fs'); 3 | const file = fs.readFileSync(parentFile).toString(); 4 | const keywords = ['button', 'html', 'body', 'script']; 5 | 6 | const result = keywords.filter((keyword) => file.indexOf(keyword) !== -1); 7 | 8 | if (result.length === keywords.length) { 9 | console.log("Congrats!!!"); 10 | } else { 11 | console.error("Your file does not have keywords"); 12 | } 13 | -------------------------------------------------------------------------------- /exercises/webview_favorite/exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var exercise = require('workshopper-exercise')(); 4 | var filecheck = require('workshopper-exercise/filecheck'); 5 | var execute = require('workshopper-exercise/execute'); 6 | var comparestdout = require('workshopper-exercise/comparestdout'); 7 | 8 | module.exports = comparestdout(execute(filecheck(exercise))); 9 | 10 | module.exports.addSetup(function(mode, cb) { 11 | process.nextTick(cb); 12 | }); 13 | -------------------------------------------------------------------------------- /exercises/webview_favorite/problem.ja.md: -------------------------------------------------------------------------------- 1 | # Webview を使ってブラウザを作る 2 | 3 | さて、webview の使い方も分かってきたところで、 `ミニブラウザ` なら作れるようになったかと思います。ここから小さいブラウザを作ってみましょう。 4 | 5 | まず、先ほど作ったリロードボタン、戻る、進むボタンの最後に URL フォームを入れてみましょう。 6 | 7 | ```html 8 | 9 | 10 | ``` 11 | 12 | このURLフォームはエンターキーを押したら操作できるようにします。 13 | 14 | main.js を下記のように編集しましょう。 15 | 16 | ```javascript 17 | const urlbar = document.getElementById('urlbar'); 18 | urlbar.addEventListener('keypress', (e) => { 19 | if (e.keyIdentifier === 'Enter') { 20 | webview.setAttribute('src', urlbar.value); 21 | } 22 | }); 23 | ``` 24 | 25 | # 問題 26 | 下記の機能を持つブラウザを作りましょう。 27 | 28 | 1. お気に入りボタンを入れてみましょう。お気に入りを押したらside pain にお気に入りで押したURLがリストとして並ぶようにしてください。 29 | 2. side pain のお気に入りに入れたURLをクリックしたら `webview` の `src` を書き換えて遷移するようにしてください。 30 | 31 | # ヒント1 32 | 33 | お気に入りを入れるためにサイドパネルを使いましょう。 34 | サイドパネルには以下のようにURLが並ぶようにしてください。 35 | 36 | ```html 37 |
    38 |
  • 39 |

    https://github.com/

    40 |
  • 41 |
  • 42 |

    https://google.com/

    43 |
  • 44 |
  • 45 |

    https://yahoo.com/

    46 |
  • 47 |
48 | ``` 49 | 50 | # ヒント2 51 | 52 | お気に入りリストがクリックされたらwebviewのURLに反映してみてください。 53 | main.js でお気に入りがクリックされるタイミングでリストアイテムがクリックされた時のイベントを作っておき、 webview に反映します。 54 | 55 | ```js 56 | const favoriteButton = document.getElementById('favorite'); 57 | favoriteButton.addEventListener('click', () => { 58 | const listItem = document.createElement('li'); 59 | listItem.addEventListener('click', () => { 60 | // ... リストの内容を url として取得する。 61 | webview.setAttribute('src', url); 62 | }); 63 | }); 64 | ``` 65 | -------------------------------------------------------------------------------- /exercises/webview_favorite/problem.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | これから `Electron` に関してのエクササイズを開始します。 `Electron` はデスクトップアプリケーションを作るためのフレームワークです。本フレームワークを活用することでJavaScript/HTML/CSSでデスクトップアプリケーションを作ることができるようになります。 4 | 5 | 概要を解説するために、[Quick start](https://github.com/atom/electron/blob/master/docs-translations/jp/tutorial/quick-start.md) をよく読んでおくことをおすすめします。 6 | まず最初に `Electron` を作るための環境構築をしましょう。 7 | 8 | ``` 9 | $ mkdir electronica1 10 | $ cd electronica1 11 | $ npm init -y 12 | ``` 13 | 14 | # Hello Electron アプリケーションを作る 15 | 16 | electronica1 フォルダの中で `index.js` という名前のファイルを作り中身を下記のように記述してください。 17 | 18 | ```javascript 19 | 'use strict'; 20 | const electron = require('electron'); 21 | const app = electron.app; 22 | const BrowserWindow = electron.BrowserWindow; 23 | 24 | // Report crashes to our server. 25 | electron.crashReporter.start(); 26 | 27 | // Keep a global reference of the window object, if you don't, the window will 28 | // be closed automatically when the JavaScript object is garbage collected. 29 | var mainWindow = null; 30 | 31 | // Quit when all windows are closed. 32 | app.on('window-all-closed', function() { 33 | // Mac OS だったらアプリケーションを殺さない 34 | if (process.platform != 'darwin') { 35 | app.quit(); 36 | } 37 | }); 38 | 39 | app.on('ready', function() { 40 | // Create the browser window. 41 | mainWindow = new BrowserWindow({width: 800, height: 600}); 42 | 43 | // and load the index.html of the app. 44 | mainWindow.loadURL('file://' + __dirname + '/index.html'); 45 | 46 | // Open the DevTools. 47 | mainWindow.webContents.openDevTools(); 48 | 49 | mainWindow.on('closed', function() { 50 | mainWindow = null; 51 | }); 52 | }); 53 | ``` 54 | 55 | 同じフォルダの中で `index.html` を作成し、下記のように記述してください。 56 | 57 | ```html 58 | 59 | 60 | 61 | 62 | Hello Electron! 63 | 64 | 65 |

Hello Electron!

66 | node version , 67 | Chrome version , 68 | Electron version . 69 | 70 | 71 | ``` 72 | 73 | フォルダ全体の構成が下記のようになっていることを確認してください。 74 | 75 | ```tree 76 | electronica1/ 77 | ├── package.json 78 | ├── index.js 79 | └── index.html 80 | ``` 81 | 82 | さらに `Electron` を実行するためのモジュールをインストールします。 83 | 84 | ``` 85 | $ npm install electron-prebuilt --save 86 | ``` 87 | 88 | 終わったら `package.json` を開き下記のようにファイルを修正してください。 89 | 90 | ``` 91 | { 92 | "name": "electroinca1", 93 | "version": "0.0.1", 94 | "main": "index.js", 95 | "scripts": { 96 | "start": "electron index.js" // scriptsに electron index.js を足す 97 | }, 98 | "devDependencies": { 99 | "electron-prebuilt": "^0.35.0" 100 | } 101 | } 102 | ``` 103 | 104 | -------------------------------------------------------------------------------- /exercises/webview_favorite/solution/solution.js: -------------------------------------------------------------------------------- 1 | const parentFile = process.env.parent_filename; 2 | const fs = require('fs'); 3 | const file = fs.readFileSync(parentFile).toString(); 4 | const keywords = ['button', 'html', 'body', 'script']; 5 | 6 | const result = keywords.filter((keyword) => file.indexOf(keyword) !== -1); 7 | 8 | if (result.length === keywords.length) { 9 | console.log("Congrats!!!"); 10 | } else { 11 | console.error("Your file does not have keywords"); 12 | } 13 | -------------------------------------------------------------------------------- /i18n/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | "subtitle": "Electron workshop", 3 | "exercise": { 4 | "HELLO ELECTRON": "HELLO ELECTRON", 5 | "APPLICATION PACKAGING": "APPLICATION PACKAGING", 6 | "ELECTRON PACKAGER": "ELECTRON PACKAGER", 7 | "PHOTON KIT": "PHOTON KIT", 8 | "ONLINE OFFLINE": "ONLINE OFFLINE", 9 | "WEBVIEW": "WEBVIEW" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports.verify = require('./exercises/verify'); 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electronica", 3 | "version": "0.3.0", 4 | "description": "Electron workshop application", 5 | "main": "./index.js", 6 | "bin": "./electronica.js", 7 | "script": { 8 | "postinstall": "./script/copyToTmp.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/yosuke-furukawa/electronica.git" 13 | }, 14 | "keywords": [ 15 | "electron", 16 | "workshopper" 17 | ], 18 | "author": "yosuke-furukawa", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/yosuke-furukawa/electronica/issues" 22 | }, 23 | "homepage": "https://github.com/yosuke-furukawa/electronica#readme", 24 | "dependencies": { 25 | "workshopper-adventure": "^3.4.5", 26 | "workshopper-exercise": "^2.5.3" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /script/copyToTmp.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const os = require('os'); 4 | const path = require('path'); 5 | const fs = require('fs'); 6 | const source = path.join(__dirname, '../exercises/program.js'); 7 | const target = path.join(os.tmpDir(), './program.js'); 8 | fs.createReadStream(source).pipe(fs.createWriteStream(target)); 9 | --------------------------------------------------------------------------------