├── Chapter01 └── Chapter01 │ └── B07154_01_Codes │ └── SRC │ ├── func-dir-service │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── defenitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── index.html │ ├── js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ └── Dir.spec.js │ │ ├── View │ │ │ └── TitleBarActions.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── func-titlebar │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── defenitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── index.html │ ├── js │ │ ├── View │ │ │ └── TitleBarActions.js │ │ └── app.js │ └── package.json │ ├── func-views │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── defenitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── index.html │ ├── js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ └── Dir.spec.js │ │ ├── View │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── TitleBarActions.js │ │ │ └── TitleBarPath.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── static-proto-content │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── defenitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── index.html │ └── package.json │ ├── static-proto-custom-prop │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── defenitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── index.html │ └── package.json │ ├── static-proto-layout │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ └── base.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── index.html │ └── package.json │ └── static-proto-pos-sticky │ ├── assets │ └── css │ │ ├── Base │ │ ├── base.css │ │ └── defenitions.css │ │ ├── Component │ │ ├── dir-list.css │ │ ├── file-list.css │ │ ├── footer.css │ │ ├── l-app.css │ │ ├── l-main.css │ │ └── titlebar.css │ │ └── app.css │ ├── index.html │ └── package.json ├── Chapter02 └── Chapter02 │ └── CH2 │ ├── func-autoupdate-1 │ ├── client │ │ ├── assets │ │ │ └── css │ │ │ │ ├── Base │ │ │ │ ├── base.css │ │ │ │ └── definitions.css │ │ │ │ ├── Component │ │ │ │ ├── dir-list.css │ │ │ │ ├── file-list.css │ │ │ │ ├── footer.css │ │ │ │ ├── icon.css │ │ │ │ ├── l-app.css │ │ │ │ ├── l-main.css │ │ │ │ ├── modal.css │ │ │ │ └── titlebar.css │ │ │ │ └── app.css │ │ ├── icon-16x16.png │ │ ├── icon-32x32.png │ │ ├── icon-32x32@2x.png │ │ ├── icon-48x48.png │ │ ├── index.html │ │ ├── js │ │ │ ├── Data │ │ │ │ └── dictionary.js │ │ │ ├── Service │ │ │ │ ├── Autoupdate.js │ │ │ │ ├── Dir.js │ │ │ │ ├── Dir.spec.js │ │ │ │ ├── File.js │ │ │ │ └── I18n.js │ │ │ ├── View │ │ │ │ ├── ConextMenu.js │ │ │ │ ├── DirList.js │ │ │ │ ├── DirList.spec.js │ │ │ │ ├── FileList.js │ │ │ │ ├── LangSelector.js │ │ │ │ ├── TitleBarActions.js │ │ │ │ ├── TitleBarPath.js │ │ │ │ └── Tray.js │ │ │ └── app.js │ │ └── package.json │ └── server │ │ ├── README.md │ │ ├── package.json │ │ └── update.js │ ├── func-autoupdate-2 │ ├── client │ │ ├── assets │ │ │ └── css │ │ │ │ ├── Base │ │ │ │ ├── base.css │ │ │ │ └── definitions.css │ │ │ │ ├── Component │ │ │ │ ├── dir-list.css │ │ │ │ ├── file-list.css │ │ │ │ ├── footer.css │ │ │ │ ├── icon.css │ │ │ │ ├── l-app.css │ │ │ │ ├── l-main.css │ │ │ │ ├── modal.css │ │ │ │ └── titlebar.css │ │ │ │ └── app.css │ │ ├── icon-16x16.png │ │ ├── icon-32x32.png │ │ ├── icon-32x32@2x.png │ │ ├── icon-48x48.png │ │ ├── index.html │ │ ├── js │ │ │ ├── Data │ │ │ │ └── dictionary.js │ │ │ ├── Service │ │ │ │ ├── Autoupdate.js │ │ │ │ ├── Dir.js │ │ │ │ ├── Dir.spec.js │ │ │ │ ├── File.js │ │ │ │ └── I18n.js │ │ │ ├── View │ │ │ │ ├── ConextMenu.js │ │ │ │ ├── DirList.js │ │ │ │ ├── DirList.spec.js │ │ │ │ ├── FileList.js │ │ │ │ ├── LangSelector.js │ │ │ │ ├── Modal.js │ │ │ │ ├── Modal │ │ │ │ │ └── constants.js │ │ │ │ ├── TitleBarActions.js │ │ │ │ ├── TitleBarPath.js │ │ │ │ └── Tray.js │ │ │ └── app.js │ │ └── package.json │ └── server │ │ ├── README.md │ │ ├── package.json │ │ └── update.js │ ├── func-cli │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ ├── js │ │ ├── Data │ │ │ └── dictionary.js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ ├── Dir.spec.js │ │ │ ├── File.js │ │ │ └── I18n.js │ │ ├── View │ │ │ ├── ConextMenu.js │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── LangSelector.js │ │ │ ├── TitleBarActions.js │ │ │ ├── TitleBarPath.js │ │ │ └── Tray.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── func-clipboard-1 │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ ├── js │ │ ├── Data │ │ │ └── dictionary.js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ ├── Dir.spec.js │ │ │ ├── File.js │ │ │ └── I18n.js │ │ ├── View │ │ │ ├── ConextMenu.js │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── LangSelector.js │ │ │ ├── TitleBarActions.js │ │ │ └── TitleBarPath.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── func-clipboard-2 │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ ├── js │ │ ├── Data │ │ │ ├── dictionary.js │ │ │ ├── dictionary.js~ddc7415 │ │ │ └── dictionary.js~ddc7415_0 │ │ ├── Service │ │ │ ├── Dir.js │ │ │ ├── Dir.spec.js │ │ │ ├── File.js │ │ │ └── I18n.js │ │ ├── View │ │ │ ├── ConextMenu.js │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── LangSelector.js │ │ │ ├── TitleBarActions.js │ │ │ └── TitleBarPath.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── func-context-menu │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ ├── js │ │ ├── Data │ │ │ └── dictionary.js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ ├── Dir.spec.js │ │ │ ├── File.js │ │ │ └── I18n.js │ │ ├── View │ │ │ ├── ConextMenu.js │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── LangSelector.js │ │ │ ├── TitleBarActions.js │ │ │ └── TitleBarPath.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── func-i18n-1 │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ ├── js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ ├── Dir.spec.js │ │ │ └── I18n.js │ │ ├── View │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── LangSelector.js │ │ │ ├── TitleBarActions.js │ │ │ └── TitleBarPath.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── func-i18n-2 │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ ├── js │ │ ├── Data │ │ │ └── dictionary.js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ ├── Dir.spec.js │ │ │ └── I18n.js │ │ ├── View │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── LangSelector.js │ │ │ ├── TitleBarActions.js │ │ │ └── TitleBarPath.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── func-menu-1 │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ ├── js │ │ ├── Data │ │ │ └── dictionary.js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ ├── Dir.spec.js │ │ │ ├── File.js │ │ │ └── I18n.js │ │ ├── View │ │ │ ├── ConextMenu.js │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── LangSelector.js │ │ │ ├── TitleBarActions.js │ │ │ ├── TitleBarPath.js │ │ │ └── Tray.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── func-menu-2 │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ ├── js │ │ ├── Data │ │ │ └── dictionary.js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ ├── Dir.spec.js │ │ │ ├── File.js │ │ │ └── I18n.js │ │ ├── View │ │ │ ├── ConextMenu.js │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── LangSelector.js │ │ │ ├── TitleBarActions.js │ │ │ ├── TitleBarPath.js │ │ │ └── Tray.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ ├── func-native │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ ├── js │ │ ├── Data │ │ │ └── dictionary.js │ │ ├── Service │ │ │ ├── Dir.js │ │ │ ├── Dir.spec.js │ │ │ ├── File.js │ │ │ └── I18n.js │ │ ├── View │ │ │ ├── ConextMenu.js │ │ │ ├── DirList.js │ │ │ ├── DirList.spec.js │ │ │ ├── FileList.js │ │ │ ├── LangSelector.js │ │ │ ├── TitleBarActions.js │ │ │ ├── TitleBarPath.js │ │ │ └── Tray.js │ │ └── app.js │ ├── package.json │ └── tests │ │ └── unit-tests │ │ ├── package.json │ │ └── specs.html │ └── func-packaging │ ├── app │ ├── app.bin │ ├── assets │ │ └── css │ │ │ ├── Base │ │ │ ├── base.css │ │ │ └── definitions.css │ │ │ ├── Component │ │ │ ├── dir-list.css │ │ │ ├── file-list.css │ │ │ ├── footer.css │ │ │ ├── icon.css │ │ │ ├── l-app.css │ │ │ ├── l-main.css │ │ │ └── titlebar.css │ │ │ └── app.css │ ├── icon-16x16.png │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ ├── index.html │ └── package.json │ ├── package.json │ ├── src │ └── js │ │ ├── Data │ │ └── dictionary.js │ │ ├── Service │ │ ├── Dir.js │ │ ├── Dir.spec.js │ │ ├── File.js │ │ └── I18n.js │ │ ├── View │ │ ├── ConextMenu.js │ │ ├── DirList.js │ │ ├── DirList.spec.js │ │ ├── FileList.js │ │ ├── LangSelector.js │ │ ├── TitleBarActions.js │ │ ├── TitleBarPath.js │ │ └── Tray.js │ │ └── app.js │ └── webpack.config.js ├── Chapter03 ├── electron-intro │ ├── README.md │ ├── app │ │ ├── index.html │ │ ├── main.js │ │ └── renderer.js │ └── package.json ├── react-intro │ ├── README.md │ ├── app │ │ ├── Components │ │ │ ├── Copycat.jsx │ │ │ └── Header.jsx │ │ ├── build │ │ │ ├── 1382c29cdb72f6c99043675d6e13b625.ttf │ │ │ ├── 2614e058b2dcb9d6e2e964730d795540.eot │ │ │ ├── renderer.js │ │ │ └── renderer.js.map │ │ ├── index.html │ │ ├── main.js │ │ └── renderer.jsx │ ├── package.json │ └── webpack.config.js └── static-proto │ ├── README.md │ ├── app │ ├── assets │ │ └── css │ │ │ └── custom.css │ ├── build │ │ ├── 1382c29cdb72f6c99043675d6e13b625.ttf │ │ ├── 2614e058b2dcb9d6e2e964730d795540.eot │ │ ├── bf614256dbc49f4bf2cf786706bb0712.woff │ │ ├── renderer.js │ │ └── renderer.js.map │ ├── index.html │ ├── js │ │ ├── Components │ │ │ ├── ChatPane.jsx │ │ │ ├── Conversation.jsx │ │ │ ├── Footer.jsx │ │ │ ├── Header.jsx │ │ │ ├── Participants.jsx │ │ │ └── Welcome.jsx │ │ ├── Containers │ │ │ └── App.jsx │ │ └── renderer.jsx │ └── main.js │ ├── package.json │ └── webpack.config.js ├── Chapter04 ├── autoupdate │ ├── README.md │ ├── app │ │ ├── assets │ │ │ └── css │ │ │ │ └── custom.css │ │ ├── build │ │ │ ├── 1382c29cdb72f6c99043675d6e13b625.ttf │ │ │ ├── 2614e058b2dcb9d6e2e964730d795540.eot │ │ │ ├── photon-entypo.eot │ │ │ ├── photon-entypo.ttf │ │ │ ├── photon-entypo.woff │ │ │ ├── renderer.js │ │ │ └── renderer.js.map │ │ ├── icon-64x64.png │ │ ├── index.html │ │ ├── js │ │ │ ├── Components │ │ │ │ ├── ChatPane.jsx │ │ │ │ ├── Conversation.jsx │ │ │ │ ├── Footer.jsx │ │ │ │ ├── Header.jsx │ │ │ │ ├── Participants.jsx │ │ │ │ └── Welcome.jsx │ │ │ ├── Containers │ │ │ │ └── App.jsx │ │ │ ├── Service │ │ │ │ ├── Client.js │ │ │ │ ├── Message.js │ │ │ │ └── Server.js │ │ │ └── renderer.jsx │ │ └── main.js │ ├── build │ │ └── icon.ico │ ├── package.json │ └── webpack.config.js ├── functional │ ├── README.md │ ├── app │ │ ├── assets │ │ │ └── css │ │ │ │ └── custom.css │ │ ├── build │ │ │ ├── 1382c29cdb72f6c99043675d6e13b625.ttf │ │ │ ├── 2614e058b2dcb9d6e2e964730d795540.eot │ │ │ ├── photon-entypo.eot │ │ │ ├── photon-entypo.ttf │ │ │ ├── photon-entypo.woff │ │ │ ├── renderer.js │ │ │ └── renderer.js.map │ │ ├── index.html │ │ ├── js │ │ │ ├── Components │ │ │ │ ├── ChatPane.jsx │ │ │ │ ├── Conversation.jsx │ │ │ │ ├── Footer.jsx │ │ │ │ ├── Header.jsx │ │ │ │ ├── Participants.jsx │ │ │ │ └── Welcome.jsx │ │ │ ├── Containers │ │ │ │ └── App.jsx │ │ │ ├── Service │ │ │ │ ├── Client.js │ │ │ │ ├── Message.js │ │ │ │ └── Server.js │ │ │ └── renderer.jsx │ │ └── main.js │ ├── package.json │ └── webpack.config.js ├── jest │ ├── README.md │ ├── package.json │ ├── unit.js │ └── unit.spec.js ├── packaging │ ├── README.md │ ├── app │ │ ├── assets │ │ │ └── css │ │ │ │ └── custom.css │ │ ├── build │ │ │ ├── 1382c29cdb72f6c99043675d6e13b625.ttf │ │ │ ├── 2614e058b2dcb9d6e2e964730d795540.eot │ │ │ ├── photon-entypo.eot │ │ │ ├── photon-entypo.ttf │ │ │ ├── photon-entypo.woff │ │ │ ├── renderer.js │ │ │ └── renderer.js.map │ │ ├── icon-64x64.png │ │ ├── index.html │ │ ├── js │ │ │ ├── Components │ │ │ │ ├── ChatPane.jsx │ │ │ │ ├── Conversation.jsx │ │ │ │ ├── Footer.jsx │ │ │ │ ├── Header.jsx │ │ │ │ ├── Participants.jsx │ │ │ │ └── Welcome.jsx │ │ │ ├── Containers │ │ │ │ └── App.jsx │ │ │ ├── Service │ │ │ │ ├── Client.js │ │ │ │ ├── Message.js │ │ │ │ └── Server.js │ │ │ └── renderer.jsx │ │ └── main.js │ ├── build │ │ ├── icon.ico │ │ └── icons │ │ │ ├── 144x144.png │ │ │ ├── 16x16.png │ │ │ ├── 192x192.png │ │ │ ├── 32x32.png │ │ │ ├── 64x64.png │ │ │ └── 96x96.png │ ├── package.json │ └── webpack.config.js ├── unit-test │ ├── .babelrc │ ├── README.md │ ├── app │ │ ├── assets │ │ │ └── css │ │ │ │ └── custom.css │ │ ├── build │ │ │ ├── photon-entypo.eot │ │ │ ├── photon-entypo.ttf │ │ │ ├── photon-entypo.woff │ │ │ ├── renderer.js │ │ │ └── renderer.js.map │ │ ├── index.html │ │ ├── js │ │ │ ├── Components │ │ │ │ ├── ChatPane.jsx │ │ │ │ ├── Conversation.jsx │ │ │ │ ├── Footer.jsx │ │ │ │ ├── Footer.spec.jsx │ │ │ │ ├── Header.jsx │ │ │ │ ├── Participants.jsx │ │ │ │ ├── Participants.spec.jsx │ │ │ │ └── Welcome.jsx │ │ │ ├── Containers │ │ │ │ └── App.jsx │ │ │ ├── Service │ │ │ │ ├── Client.js │ │ │ │ ├── Message.js │ │ │ │ └── Server.js │ │ │ └── renderer.jsx │ │ └── main.js │ ├── package.json │ └── webpack.config.js └── ws │ ├── README.md │ ├── index.html │ ├── package.json │ └── server.js ├── Chapter05 └── Chapter05 │ ├── func-redux │ ├── assets │ │ ├── icon-32x32.png │ │ ├── icon-32x32@2x.png │ │ ├── icon-48x48.png │ │ └── main.css │ ├── index.html │ ├── js │ │ ├── Actions │ │ │ └── index.js │ │ ├── Components │ │ │ ├── AnimationTab.jsx │ │ │ ├── Main.jsx │ │ │ ├── ScreenshotTab.jsx │ │ │ └── TitleBar.jsx │ │ ├── Constants │ │ │ └── index.js │ │ ├── Containers │ │ │ └── App.jsx │ │ ├── Reducers │ │ │ └── index.js │ │ └── app.jsx │ ├── package.json │ └── webpack.config.js │ └── static-proto │ ├── assets │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ └── main.css │ ├── index.html │ ├── js │ ├── Components │ │ ├── AnimationTab.jsx │ │ ├── Main.jsx │ │ ├── ScreenshotTab.jsx │ │ └── TitleBar.jsx │ ├── Containers │ │ └── App.jsx │ └── app.jsx │ ├── package.json │ └── webpack.config.js ├── Chapter06 └── Chapter06 │ ├── func-services │ ├── assets │ │ ├── icon-32x32.png │ │ ├── icon-32x32@2x.png │ │ ├── icon-48x48.png │ │ └── main.css │ ├── build │ │ ├── app.js │ │ └── app.js.map │ ├── index.html │ ├── js │ │ ├── Actions │ │ │ └── index.js │ │ ├── Components │ │ │ ├── AnimationTab.jsx │ │ │ ├── Main.jsx │ │ │ ├── ScreenshotTab.jsx │ │ │ └── TitleBar.jsx │ │ ├── Constants │ │ │ └── index.js │ │ ├── Containers │ │ │ └── App.jsx │ │ ├── Reducers │ │ │ └── index.js │ │ ├── Service │ │ │ ├── Capturer.js │ │ │ ├── Capturer │ │ │ │ ├── Dom.js │ │ │ │ └── Fsys.js │ │ │ ├── Shortcut.js │ │ │ └── Tray.js │ │ └── app.jsx │ ├── package.json │ ├── screenshot1.png │ └── webpack.config.js │ ├── func-tools │ ├── assets │ │ ├── icon-32x32.png │ │ ├── icon-32x32@2x.png │ │ ├── icon-48x48.png │ │ └── main.css │ ├── index.html │ ├── js │ │ ├── Actions │ │ │ └── index.js │ │ ├── Components │ │ │ ├── AnimationTab.jsx │ │ │ ├── DevTools.jsx │ │ │ ├── Main.jsx │ │ │ ├── ScreenshotTab.jsx │ │ │ └── TitleBar.jsx │ │ ├── Constants │ │ │ └── index.js │ │ ├── Containers │ │ │ └── App.jsx │ │ ├── Reducers │ │ │ └── index.js │ │ └── app.jsx │ ├── package.json │ └── webpack.config.js │ └── unit-test │ ├── .babelrc │ ├── assets │ ├── icon-32x32.png │ ├── icon-32x32@2x.png │ ├── icon-48x48.png │ └── main.css │ ├── build │ ├── app.js │ └── app.js.map │ ├── index.html │ ├── js │ ├── Actions │ │ ├── index.js │ │ └── index.spec.js │ ├── Components │ │ ├── AnimationTab.jsx │ │ ├── Main.jsx │ │ ├── ScreenshotTab.jsx │ │ └── TitleBar.jsx │ ├── Constants │ │ └── index.js │ ├── Containers │ │ └── App.jsx │ ├── Reducers │ │ ├── index.js │ │ └── index.spec.js │ ├── Service │ │ ├── Capturer.js │ │ ├── Capturer │ │ │ ├── Dom.js │ │ │ └── Fsys.js │ │ ├── Shortcut.js │ │ └── Tray.js │ └── app.jsx │ ├── package.json │ └── webpack.config.js ├── Chapter07 ├── static-proto │ ├── README.md │ ├── app │ │ ├── build │ │ │ └── js │ │ │ │ ├── bundle.js │ │ │ │ └── bundle.js.map │ │ ├── icon-64x64.png │ │ ├── index.html │ │ ├── main.js │ │ ├── sass │ │ │ └── app.scss │ │ └── ts │ │ │ ├── Components │ │ │ ├── Feed.tsx │ │ │ ├── Menu.tsx │ │ │ └── TitleBar.tsx │ │ │ ├── Containers │ │ │ └── App.tsx │ │ │ └── index.tsx │ ├── package.json │ ├── tsconfig.json │ └── webpack.config.js ├── ts-globals │ ├── README.md │ ├── build │ │ ├── example.js │ │ └── example.js.map │ ├── example.ts │ ├── feedme.d.ts │ ├── package.json │ └── tsconfig.json └── ts-introduction │ ├── .alm │ └── sessionsV2.json │ ├── README.md │ ├── build │ ├── example-basic-types.js │ ├── example-basic-types.js.map │ ├── example-classes.js │ ├── example-classes.js.map │ ├── example-enum.js │ ├── example-enum.js.map │ ├── example-function-types.js │ ├── example-function-types.js.map │ ├── example-generics.js │ ├── example-generics.js.map │ ├── example-indexable-types.js │ ├── example-indexable-types.js.map │ ├── example-mapped-types.js │ ├── example-mapped-types.js.map │ ├── example-overloading.js │ ├── example-overloading.js.map │ ├── example-reusable-types.js │ ├── example-reusable-types.js.map │ ├── example-string-literal-types.js │ ├── example-string-literal-types.js.map │ ├── example-union-types.js │ ├── example-union-types.js.map │ ├── example.js │ └── example.js.map │ ├── example-basic-types.ts │ ├── example-classes.ts │ ├── example-enum.ts │ ├── example-function-types.ts │ ├── example-generics.ts │ ├── example-indexable-types.ts │ ├── example-mapped-types.ts │ ├── example-overloading.ts │ ├── example-reusable-types.ts │ ├── example-string-literal-types.ts │ ├── example-union-types.ts │ ├── example.ts │ ├── package.json │ └── tsconfig.json ├── Chapter08 └── functional │ ├── README.md │ ├── app │ ├── build │ │ └── js │ │ │ ├── bundle.js │ │ │ └── bundle.js.map │ ├── icon-64x64.png │ ├── index.html │ ├── main.js │ ├── sass │ │ └── app.scss │ └── ts │ │ ├── Actions │ │ ├── actions.spec.ts │ │ ├── actions.ts │ │ └── fixture │ │ │ └── rss.xml │ │ ├── Components │ │ ├── AddFeedDialog.tsx │ │ ├── ErrorAlert.tsx │ │ ├── Feed.tsx │ │ ├── Menu.tsx │ │ ├── TitleBar.tsx │ │ ├── TitleBars.spec.tsx │ │ └── __snapshots__ │ │ │ └── TitleBars.spec.tsx.snap │ │ ├── Constants │ │ └── index.ts │ │ ├── Containers │ │ └── App.tsx │ │ ├── Interfaces │ │ ├── Rss.ts │ │ └── index.ts │ │ ├── Reducers │ │ ├── app.spec.ts │ │ ├── app.ts │ │ └── index.ts │ │ ├── Services │ │ ├── IFeedMe.ts │ │ ├── IMenu.ts │ │ ├── Menu.ts │ │ ├── Router.ts │ │ └── rss.ts │ │ └── index.tsx │ ├── jest-preprocessor.js │ ├── package-lock.json │ ├── package.json │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── LICENSE └── README.md /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/assets/css/Base/defenitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/defenitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/js/app.js: -------------------------------------------------------------------------------- 1 | const { TitleBarActionsView } = require( "./js/View/TitleBarActions" ); 2 | 3 | new TitleBarActionsView( document.querySelector( "[data-bind=titlebar]" ) ); 4 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-dir-service/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/assets/css/Base/defenitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/defenitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/js/app.js: -------------------------------------------------------------------------------- 1 | const { TitleBarActionsView } = require( "./js/View/TitleBarActions" ); 2 | 3 | new TitleBarActionsView( document.querySelector( "[data-bind=titlebar]" ) ); 4 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-titlebar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "nw .", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "chromium-args": "--mixed-context", 11 | "window": { 12 | "show": true, 13 | "frame": true, 14 | "width": 1000, 15 | "height": 600, 16 | "min_width": 800, 17 | "min_height": 400, 18 | "position": "center", 19 | "resizable": true 20 | }, 21 | "keywords": [], 22 | "author": "", 23 | "license": "ISC", 24 | "devDependencies": { 25 | "nw": "^0.20.3-sdk" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/assets/css/Base/defenitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/defenitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/func-views/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-content/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-content/assets/css/Base/defenitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-content/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-content/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-content/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-content/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-content/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-content/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/defenitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/l-app.css"); 4 | @import url("./Component/l-main.css"); 5 | @import url("./Component/titlebar.css"); 6 | @import url("./Component/footer.css"); 7 | @import url("./Component/dir-list.css"); 8 | @import url("./Component/file-list.css"); 9 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-content/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "nw .", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "chromium-args": "--mixed-context", 11 | "window": { 12 | "show": true, 13 | "frame": true, 14 | "width": 1000, 15 | "height": 600, 16 | "min_width": 800, 17 | "min_height": 400, 18 | "position": "center", 19 | "resizable": true 20 | }, 21 | "keywords": [], 22 | "author": "", 23 | "license": "ISC", 24 | "devDependencies": { 25 | "nw": "^0.20.3-sdk" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-custom-prop/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-custom-prop/assets/css/Base/defenitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-custom-prop/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-custom-prop/assets/css/Component/file-list.css: -------------------------------------------------------------------------------- 1 | .file-list { 2 | background-color: var(--filelist-bg-color); 3 | color: var(--filelist-fg-color); 4 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-custom-prop/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | } 6 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-custom-prop/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-custom-prop/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-custom-prop/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-custom-prop/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/defenitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/l-app.css"); 4 | @import url("./Component/l-main.css"); 5 | @import url("./Component/titlebar.css"); 6 | @import url("./Component/footer.css"); 7 | @import url("./Component/dir-list.css"); 8 | @import url("./Component/file-list.css"); 9 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-layout/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-layout/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: #dedede; 4 | color: #ffffff; 5 | border-right: 1px solid #2d2d2d; 6 | } 7 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-layout/assets/css/Component/file-list.css: -------------------------------------------------------------------------------- 1 | .file-list { 2 | background-color: #f9f9f9; 3 | color: #333341; 4 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-layout/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid #2d2d2d; 3 | background-color: #dedede; 4 | padding: 0.4em 0.6em; 5 | } 6 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-layout/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 40px; 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app__footer { 16 | flex: 0 0 40px; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-layout/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 250px; 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-layout/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: #2d2d2d; 3 | color: #dcdcdc; 4 | padding: 0.8em 0.6em; 5 | } 6 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-layout/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/base.css"); 2 | @import url("./Component/l-app.css"); 3 | @import url("./Component/l-main.css"); 4 | @import url("./Component/titlebar.css"); 5 | @import url("./Component/footer.css"); 6 | @import url("./Component/dir-list.css"); 7 | @import url("./Component/file-list.css"); 8 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-layout/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "nw .", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "chromium-args": "--mixed-context", 11 | "window": { 12 | "show": true, 13 | "frame": true, 14 | "width": 1000, 15 | "height": 600, 16 | "min_width": 800, 17 | "min_height": 400, 18 | "position": "center", 19 | "resizable": true 20 | }, 21 | "keywords": [], 22 | "author": "", 23 | "license": "ISC", 24 | "devDependencies": { 25 | "nw": "^0.20.3-sdk" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-pos-sticky/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-pos-sticky/assets/css/Base/defenitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-pos-sticky/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-pos-sticky/assets/css/Component/file-list.css: -------------------------------------------------------------------------------- 1 | .file-list { 2 | background-color: var(--filelist-bg-color); 3 | color: var(--filelist-fg-color); 4 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-pos-sticky/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-pos-sticky/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-pos-sticky/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-pos-sticky/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | } -------------------------------------------------------------------------------- /Chapter01/Chapter01/B07154_01_Codes/SRC/static-proto-pos-sticky/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/defenitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/l-app.css"); 4 | @import url("./Component/l-main.css"); 5 | @import url("./Component/titlebar.css"); 6 | @import url("./Component/footer.css"); 7 | @import url("./Component/dir-list.css"); 8 | @import url("./Component/file-list.css"); 9 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: rgba(45, 45, 45, 0.9); 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: rgba(222, 222, 222, 0.95); 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: rgba(249, 249, 249, 0.95); 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: rgba(222, 222, 222, 0.95); 12 | --separator-color: #2d2d2d; 13 | --border-radius: 0; 14 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | border-radius: 0 0 var(--border-radius) var(--border-radius); 11 | } 12 | 13 | .footer__label { 14 | margin-right: 0.2em; 15 | font-size: 1.4em; 16 | margin-top: 0.1em; 17 | } 18 | .footer__header { 19 | margin: 0.2em auto 0 0; 20 | font-size: 1em; 21 | } 22 | .footer__select { 23 | font-size: 1em; 24 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | border-radius: var(--border-radius) var(--border-radius) 0 0; 14 | } 15 | .titlebar__path { 16 | flex: 1 1 auto; 17 | } 18 | .titlebar__btn { 19 | flex: 0 0 25px; 20 | cursor: pointer; 21 | -webkit-app-region: no-drag; 22 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/modal.css"); 8 | @import url("./Component/footer.css"); 9 | @import url("./Component/dir-list.css"); 10 | @import url("./Component/file-list.css"); 11 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-autoupdate-1/client/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-autoupdate-1/client/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-autoupdate-1/client/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-autoupdate-1/client/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/js/Data/dictionary.js: -------------------------------------------------------------------------------- 1 | exports.dictionary = { 2 | "en-US": { 3 | NAME: "Name", 4 | SIZE: "Size", 5 | MODIFIED: "Modified", 6 | MINIMIZE_WIN: "Minimize window", 7 | RESTORE_WIN: "Restore window", 8 | MAXIMIZE_WIN: "Maximize window", 9 | CLOSE_WIN: "Close window" 10 | }, 11 | "de-DE": { 12 | NAME: "Dateiname", 13 | SIZE: "Größe", 14 | MODIFIED: "Geändert am", 15 | MINIMIZE_WIN: "Fenster minimieren", 16 | RESTORE_WIN: "Fenster wiederherstellen", 17 | MAXIMIZE_WIN: "Fenster maximieren", 18 | CLOSE_WIN: "Fenster schließen" 19 | } 20 | }; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/client/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-1/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "release-server", 3 | "version": "1.0.3", 4 | "description": "", 5 | "main": "index.js", 6 | "packages": { 7 | "linux64": { 8 | "url": "http://localhost:8080/releases/file-explorer-linux-x64.zip", 9 | "size": 98451101 10 | } 11 | }, 12 | "scripts": { 13 | "start": "http-server .", 14 | "update": "node update.js" 15 | }, 16 | "keywords": [], 17 | "author": "", 18 | "license": "ISC", 19 | "dependencies": { 20 | "http-server": "^0.9.0" 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: rgba(45, 45, 45, 0.9); 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: rgba(222, 222, 222, 0.95); 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: rgba(249, 249, 249, 0.95); 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: rgba(222, 222, 222, 0.95); 12 | --separator-color: #2d2d2d; 13 | --border-radius: 0; 14 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | border-radius: 0 0 var(--border-radius) var(--border-radius); 11 | } 12 | 13 | .footer__label { 14 | margin-right: 0.2em; 15 | font-size: 1.4em; 16 | margin-top: 0.1em; 17 | } 18 | .footer__header { 19 | margin: 0.2em auto 0 0; 20 | font-size: 1em; 21 | } 22 | .footer__select { 23 | font-size: 1em; 24 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | border-radius: var(--border-radius) var(--border-radius) 0 0; 14 | } 15 | .titlebar__path { 16 | flex: 1 1 auto; 17 | } 18 | .titlebar__btn { 19 | flex: 0 0 25px; 20 | cursor: pointer; 21 | -webkit-app-region: no-drag; 22 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/modal.css"); 8 | @import url("./Component/footer.css"); 9 | @import url("./Component/dir-list.css"); 10 | @import url("./Component/file-list.css"); 11 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-autoupdate-2/client/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-autoupdate-2/client/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-autoupdate-2/client/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-autoupdate-2/client/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/js/View/Modal/constants.js: -------------------------------------------------------------------------------- 1 | const NEW_VERSION = "NEW_VERSION", 2 | DOWNLOADING = "DOWNLOADING", 3 | INSTALLING = "INSTALLING", 4 | SWAPPING = "SWAPPING", 5 | RESTARTING = "RESTARTING"; 6 | 7 | 8 | exports.NEW_VERSION = NEW_VERSION; 9 | exports.DOWNLOADING = DOWNLOADING; 10 | exports.INSTALLING = INSTALLING; 11 | exports.SWAPPING = SWAPPING; 12 | exports.RESTARTING = RESTARTING; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/client/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-autoupdate-2/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "release-server", 3 | "version": "1.0.3", 4 | "description": "", 5 | "main": "index.js", 6 | "packages": { 7 | "linux64": { 8 | "url": "http://localhost:8080/releases/file-explorer-linux-x64.zip", 9 | "size": 98443303 10 | } 11 | }, 12 | "scripts": { 13 | "start": "http-server .", 14 | "update": "node update.js" 15 | }, 16 | "keywords": [], 17 | "author": "", 18 | "license": "ISC", 19 | "dependencies": { 20 | "http-server": "^0.9.0" 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } 21 | .footer__select { 22 | font-size: 1em; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/assets/css/Component/icon.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-family: 'Material Icons'; 3 | font-weight: normal; 4 | font-style: normal; 5 | font-size: 16px; 6 | display: inline-block; 7 | line-height: 1; 8 | text-transform: none; 9 | letter-spacing: normal; 10 | word-wrap: normal; 11 | white-space: nowrap; 12 | direction: ltr; 13 | 14 | /* Support for all WebKit browsers. */ 15 | -webkit-font-smoothing: antialiased; 16 | /* Support for Safari and Chrome. */ 17 | text-rendering: optimizeLegibility; 18 | 19 | /* Support for Firefox. */ 20 | -moz-osx-font-smoothing: grayscale; 21 | 22 | /* Support for IE. */ 23 | font-feature-settings: 'liga'; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-cli/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-cli/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-cli/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-cli/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/js/Data/dictionary.js: -------------------------------------------------------------------------------- 1 | exports.dictionary = { 2 | "en-US": { 3 | NAME: "Name", 4 | SIZE: "Size", 5 | MODIFIED: "Modified", 6 | MINIMIZE_WIN: "Minimize window", 7 | RESTORE_WIN: "Restore window", 8 | MAXIMIZE_WIN: "Maximize window", 9 | CLOSE_WIN: "Close window" 10 | }, 11 | "de-DE": { 12 | NAME: "Dateiname", 13 | SIZE: "Größe", 14 | MODIFIED: "Geändert am", 15 | MINIMIZE_WIN: "Fenster minimieren", 16 | RESTORE_WIN: "Fenster wiederherstellen", 17 | MAXIMIZE_WIN: "Fenster maximieren", 18 | CLOSE_WIN: "Fenster schließen" 19 | } 20 | }; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/js/View/LangSelector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class to handle language selector 3 | */ 4 | class LangSelectorView { 5 | /** 6 | * create LangSelectorView 7 | * @param {HTMLElement} boundingEl 8 | * @param {I18n} i18n 9 | */ 10 | constructor( boundingEl, i18n ){ 11 | boundingEl.addEventListener( "change", this.onChanged.bind( this ), false ); 12 | this.i18n = i18n; 13 | } 14 | /** 15 | * Handle when select gets changed 16 | * @param {Event} e 17 | */ 18 | onChanged( e ){ 19 | const selectEl = e.target; 20 | this.i18n.locale = selectEl.value; 21 | this.i18n.notify(); 22 | } 23 | } 24 | 25 | exports.LangSelectorView = LangSelectorView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-cli/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } 21 | 22 | .footer__select { 23 | font-size: 1em; 24 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/assets/css/Component/icon.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-family: 'Material Icons'; 3 | font-weight: normal; 4 | font-style: normal; 5 | font-size: 16px; 6 | display: inline-block; 7 | line-height: 1; 8 | text-transform: none; 9 | letter-spacing: normal; 10 | word-wrap: normal; 11 | white-space: nowrap; 12 | direction: ltr; 13 | 14 | /* Support for all WebKit browsers. */ 15 | -webkit-font-smoothing: antialiased; 16 | /* Support for Safari and Chrome. */ 17 | text-rendering: optimizeLegibility; 18 | 19 | /* Support for Firefox. */ 20 | -moz-osx-font-smoothing: grayscale; 21 | 22 | /* Support for IE. */ 23 | font-feature-settings: 'liga'; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-clipboard-1/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-clipboard-1/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-clipboard-1/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-clipboard-1/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-1/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } 21 | 22 | .footer__select { 23 | font-size: 1em; 24 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-clipboard-2/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-clipboard-2/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-clipboard-2/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-clipboard-2/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-clipboard-2/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } 21 | 22 | .footer__select { 23 | font-size: 1em; 24 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-context-menu/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-context-menu/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-context-menu/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-context-menu/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-context-menu/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } 21 | .footer__select { 22 | font-size: 1em; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/assets/css/Component/icon.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-family: 'Material Icons'; 3 | font-weight: normal; 4 | font-style: normal; 5 | font-size: 16px; 6 | display: inline-block; 7 | line-height: 1; 8 | text-transform: none; 9 | letter-spacing: normal; 10 | word-wrap: normal; 11 | white-space: nowrap; 12 | direction: ltr; 13 | 14 | /* Support for all WebKit browsers. */ 15 | -webkit-font-smoothing: antialiased; 16 | /* Support for Safari and Chrome. */ 17 | text-rendering: optimizeLegibility; 18 | 19 | /* Support for Firefox. */ 20 | -moz-osx-font-smoothing: grayscale; 21 | 22 | /* Support for IE. */ 23 | font-feature-settings: 'liga'; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-i18n-1/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-i18n-1/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-i18n-1/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-i18n-1/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/js/View/LangSelector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class to handle language selector 3 | */ 4 | class LangSelectorView { 5 | /** 6 | * create LangSelectorView 7 | * @param {HTMLElement} boundingEl 8 | * @param {I18n} i18n 9 | */ 10 | constructor( boundingEl, i18n ){ 11 | boundingEl.addEventListener( "change", this.onChanged.bind( this ), false ); 12 | this.i18n = i18n; 13 | } 14 | /** 15 | * Handle when select gets changed 16 | * @param {Event} e 17 | */ 18 | onChanged( e ){ 19 | const selectEl = e.target; 20 | this.i18n.locale = selectEl.value; 21 | this.i18n.notify(); 22 | } 23 | } 24 | 25 | exports.LangSelectorView = LangSelectorView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-1/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } 21 | 22 | .footer__select { 23 | font-size: 1em; 24 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/assets/css/Component/icon.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-family: 'Material Icons'; 3 | font-weight: normal; 4 | font-style: normal; 5 | font-size: 16px; 6 | display: inline-block; 7 | line-height: 1; 8 | text-transform: none; 9 | letter-spacing: normal; 10 | word-wrap: normal; 11 | white-space: nowrap; 12 | direction: ltr; 13 | 14 | /* Support for all WebKit browsers. */ 15 | -webkit-font-smoothing: antialiased; 16 | /* Support for Safari and Chrome. */ 17 | text-rendering: optimizeLegibility; 18 | 19 | /* Support for Firefox. */ 20 | -moz-osx-font-smoothing: grayscale; 21 | 22 | /* Support for IE. */ 23 | font-feature-settings: 'liga'; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-i18n-2/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-i18n-2/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-i18n-2/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-i18n-2/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/js/Data/dictionary.js: -------------------------------------------------------------------------------- 1 | exports.dictionary = { 2 | "en-US": { 3 | NAME: "Name", 4 | SIZE: "Size", 5 | MODIFIED: "Modified", 6 | MINIMIZE_WIN: "Minimize window", 7 | RESTORE_WIN: "Restore window", 8 | MAXIMIZE_WIN: "Maximize window", 9 | CLOSE_WIN: "Close window" 10 | }, 11 | "de-DE": { 12 | NAME: "Dateiname", 13 | SIZE: "Größe", 14 | MODIFIED: "Geändert am", 15 | MINIMIZE_WIN: "Fenster minimieren", 16 | RESTORE_WIN: "Fenster wiederherstellen", 17 | MAXIMIZE_WIN: "Fenster maximieren", 18 | CLOSE_WIN: "Fenster schließen" 19 | } 20 | }; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/js/View/LangSelector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class to handle language selector 3 | */ 4 | class LangSelectorView { 5 | /** 6 | * create LangSelectorView 7 | * @param {HTMLElement} boundingEl 8 | * @param {I18n} i18n 9 | */ 10 | constructor( boundingEl, i18n ){ 11 | boundingEl.addEventListener( "change", this.onChanged.bind( this ), false ); 12 | this.i18n = i18n; 13 | } 14 | /** 15 | * Handle when select gets changed 16 | * @param {Event} e 17 | */ 18 | onChanged( e ){ 19 | const selectEl = e.target; 20 | this.i18n.locale = selectEl.value; 21 | this.i18n.notify(); 22 | } 23 | } 24 | 25 | exports.LangSelectorView = LangSelectorView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-i18n-2/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } 21 | .footer__select { 22 | font-size: 1em; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/assets/css/Component/icon.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-family: 'Material Icons'; 3 | font-weight: normal; 4 | font-style: normal; 5 | font-size: 16px; 6 | display: inline-block; 7 | line-height: 1; 8 | text-transform: none; 9 | letter-spacing: normal; 10 | word-wrap: normal; 11 | white-space: nowrap; 12 | direction: ltr; 13 | 14 | /* Support for all WebKit browsers. */ 15 | -webkit-font-smoothing: antialiased; 16 | /* Support for Safari and Chrome. */ 17 | text-rendering: optimizeLegibility; 18 | 19 | /* Support for Firefox. */ 20 | -moz-osx-font-smoothing: grayscale; 21 | 22 | /* Support for IE. */ 23 | font-feature-settings: 'liga'; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-menu-1/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-menu-1/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-menu-1/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-menu-1/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/js/Data/dictionary.js: -------------------------------------------------------------------------------- 1 | exports.dictionary = { 2 | "en-US": { 3 | NAME: "Name", 4 | SIZE: "Size", 5 | MODIFIED: "Modified", 6 | MINIMIZE_WIN: "Minimize window", 7 | RESTORE_WIN: "Restore window", 8 | MAXIMIZE_WIN: "Maximize window", 9 | CLOSE_WIN: "Close window" 10 | }, 11 | "de-DE": { 12 | NAME: "Dateiname", 13 | SIZE: "Größe", 14 | MODIFIED: "Geändert am", 15 | MINIMIZE_WIN: "Fenster minimieren", 16 | RESTORE_WIN: "Fenster wiederherstellen", 17 | MAXIMIZE_WIN: "Fenster maximieren", 18 | CLOSE_WIN: "Fenster schließen" 19 | } 20 | }; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/js/View/LangSelector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class to handle language selector 3 | */ 4 | class LangSelectorView { 5 | /** 6 | * create LangSelectorView 7 | * @param {HTMLElement} boundingEl 8 | * @param {I18n} i18n 9 | */ 10 | constructor( boundingEl, i18n ){ 11 | boundingEl.addEventListener( "change", this.onChanged.bind( this ), false ); 12 | this.i18n = i18n; 13 | } 14 | /** 15 | * Handle when select gets changed 16 | * @param {Event} e 17 | */ 18 | onChanged( e ){ 19 | const selectEl = e.target; 20 | this.i18n.locale = selectEl.value; 21 | this.i18n.notify(); 22 | } 23 | } 24 | 25 | exports.LangSelectorView = LangSelectorView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-1/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: #2d2d2d; 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: #dedede; 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: #f9f9f9; 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: #dedede; 12 | --separator-color: #2d2d2d; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | } 11 | 12 | .footer__label { 13 | margin-right: 0.2em; 14 | font-size: 1.4em; 15 | margin-top: 0.1em; 16 | } 17 | .footer__header { 18 | margin: 0.2em auto 0 0; 19 | font-size: 1em; 20 | } 21 | .footer__select { 22 | font-size: 1em; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/assets/css/Component/icon.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-family: 'Material Icons'; 3 | font-weight: normal; 4 | font-style: normal; 5 | font-size: 16px; 6 | display: inline-block; 7 | line-height: 1; 8 | text-transform: none; 9 | letter-spacing: normal; 10 | word-wrap: normal; 11 | white-space: nowrap; 12 | direction: ltr; 13 | 14 | /* Support for all WebKit browsers. */ 15 | -webkit-font-smoothing: antialiased; 16 | /* Support for Safari and Chrome. */ 17 | text-rendering: optimizeLegibility; 18 | 19 | /* Support for Firefox. */ 20 | -moz-osx-font-smoothing: grayscale; 21 | 22 | /* Support for IE. */ 23 | font-feature-settings: 'liga'; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | } 14 | .titlebar__path { 15 | flex: 1 1 auto; 16 | } 17 | .titlebar__btn { 18 | flex: 0 0 25px; 19 | cursor: pointer; 20 | -webkit-app-region: no-drag; 21 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-menu-2/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-menu-2/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-menu-2/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-menu-2/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/js/Data/dictionary.js: -------------------------------------------------------------------------------- 1 | exports.dictionary = { 2 | "en-US": { 3 | NAME: "Name", 4 | SIZE: "Size", 5 | MODIFIED: "Modified", 6 | MINIMIZE_WIN: "Minimize window", 7 | RESTORE_WIN: "Restore window", 8 | MAXIMIZE_WIN: "Maximize window", 9 | CLOSE_WIN: "Close window" 10 | }, 11 | "de-DE": { 12 | NAME: "Dateiname", 13 | SIZE: "Größe", 14 | MODIFIED: "Geändert am", 15 | MINIMIZE_WIN: "Fenster minimieren", 16 | RESTORE_WIN: "Fenster wiederherstellen", 17 | MAXIMIZE_WIN: "Fenster maximieren", 18 | CLOSE_WIN: "Fenster schließen" 19 | } 20 | }; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/js/View/LangSelector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class to handle language selector 3 | */ 4 | class LangSelectorView { 5 | /** 6 | * create LangSelectorView 7 | * @param {HTMLElement} boundingEl 8 | * @param {I18n} i18n 9 | */ 10 | constructor( boundingEl, i18n ){ 11 | boundingEl.addEventListener( "change", this.onChanged.bind( this ), false ); 12 | this.i18n = i18n; 13 | } 14 | /** 15 | * Handle when select gets changed 16 | * @param {Event} e 17 | */ 18 | onChanged( e ){ 19 | const selectEl = e.target; 20 | this.i18n.locale = selectEl.value; 21 | this.i18n.notify(); 22 | } 23 | } 24 | 25 | exports.LangSelectorView = LangSelectorView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-menu-2/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: rgba(45, 45, 45, 0.7); 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: rgba(222, 222, 222, 0.9); 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: rgba(249, 249, 249, 0.9); 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: rgba(222, 222, 222, 0.9); 12 | --separator-color: #2d2d2d; 13 | --border-radius: 1em; 14 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | border-radius: 0 0 var(--border-radius) var(--border-radius); 11 | } 12 | 13 | .footer__label { 14 | margin-right: 0.2em; 15 | font-size: 1.4em; 16 | margin-top: 0.1em; 17 | } 18 | .footer__header { 19 | margin: 0.2em auto 0 0; 20 | font-size: 1em; 21 | } 22 | .footer__select { 23 | font-size: 1em; 24 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/assets/css/Component/icon.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-family: 'Material Icons'; 3 | font-weight: normal; 4 | font-style: normal; 5 | font-size: 16px; 6 | display: inline-block; 7 | line-height: 1; 8 | text-transform: none; 9 | letter-spacing: normal; 10 | word-wrap: normal; 11 | white-space: nowrap; 12 | direction: ltr; 13 | 14 | /* Support for all WebKit browsers. */ 15 | -webkit-font-smoothing: antialiased; 16 | /* Support for Safari and Chrome. */ 17 | text-rendering: optimizeLegibility; 18 | 19 | /* Support for Firefox. */ 20 | -moz-osx-font-smoothing: grayscale; 21 | 22 | /* Support for IE. */ 23 | font-feature-settings: 'liga'; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | border-radius: var(--border-radius) var(--border-radius) 0 0; 14 | } 15 | .titlebar__path { 16 | flex: 1 1 auto; 17 | } 18 | .titlebar__btn { 19 | flex: 0 0 25px; 20 | cursor: pointer; 21 | -webkit-app-region: no-drag; 22 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-native/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-native/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-native/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-native/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/js/Data/dictionary.js: -------------------------------------------------------------------------------- 1 | exports.dictionary = { 2 | "en-US": { 3 | NAME: "Name", 4 | SIZE: "Size", 5 | MODIFIED: "Modified", 6 | MINIMIZE_WIN: "Minimize window", 7 | RESTORE_WIN: "Restore window", 8 | MAXIMIZE_WIN: "Maximize window", 9 | CLOSE_WIN: "Close window" 10 | }, 11 | "de-DE": { 12 | NAME: "Dateiname", 13 | SIZE: "Größe", 14 | MODIFIED: "Geändert am", 15 | MINIMIZE_WIN: "Fenster minimieren", 16 | RESTORE_WIN: "Fenster wiederherstellen", 17 | MAXIMIZE_WIN: "Fenster maximieren", 18 | CLOSE_WIN: "Fenster schließen" 19 | } 20 | }; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/js/View/LangSelector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class to handle language selector 3 | */ 4 | class LangSelectorView { 5 | /** 6 | * create LangSelectorView 7 | * @param {HTMLElement} boundingEl 8 | * @param {I18n} i18n 9 | */ 10 | constructor( boundingEl, i18n ){ 11 | boundingEl.addEventListener( "change", this.onChanged.bind( this ), false ); 12 | this.i18n = i18n; 13 | } 14 | /** 15 | * Handle when select gets changed 16 | * @param {Event} e 17 | */ 18 | onChanged( e ){ 19 | const selectEl = e.target; 20 | this.i18n.locale = selectEl.value; 21 | this.i18n.notify(); 22 | } 23 | } 24 | 25 | exports.LangSelectorView = LangSelectorView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-native/tests/unit-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer", 3 | "main": "specs.html", 4 | "chromium-args": "--mixed-context" 5 | } 6 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/app.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-packaging/app/app.bin -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/assets/css/Base/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | -webkit-font-smoothing: antialiased; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | nav > ul { 10 | list-style: none; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | body { 16 | min-height: 100vh; 17 | margin: 0; 18 | font-family: Arial; 19 | } 20 | 21 | .is-hidden { 22 | display: none !important; 23 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/assets/css/Base/definitions.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --titlebar-bg-color: rgba(45, 45, 45, 0.9); 3 | --titlebar-fg-color: #dcdcdc; 4 | --dirlist-bg-color: rgba(222, 222, 222, 0.95); 5 | --dirlist-fg-color: #636363; 6 | --filelist-bg-color: rgba(249, 249, 249, 0.95); 7 | --filelist-fg-color: #333341; 8 | --dirlist-w: 250px; 9 | --titlebar-h: 40px; 10 | --footer-h: 40px; 11 | --footer-bg-color: rgba(222, 222, 222, 0.95); 12 | --separator-color: #2d2d2d; 13 | --border-radius: 1em; 14 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/assets/css/Component/dir-list.css: -------------------------------------------------------------------------------- 1 | .dir-list { 2 | padding: 0; 3 | background-color: var(--dirlist-bg-color); 4 | color: var(--dirlist-fg-color); 5 | border-right: 1px solid var(--separator-color); 6 | } 7 | 8 | .dir-list__li { 9 | padding: 0.8em 0.6em; 10 | cursor: pointer; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | 16 | .dir-list__li:hover { 17 | background-color: var(--dirlist-bg-hover-color); 18 | color: var(--dirlist-fg-hover-color); 19 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/assets/css/Component/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | border-top: 1px solid var(--separator-color); 3 | background-color: var(--footer-bg-color); 4 | padding: 0.4em 0.6em; 5 | position: sticky; 6 | bottom: 0; 7 | display: flex; 8 | flex-flow: row nowrap; 9 | justify-content: flex-end; 10 | border-radius: 0 0 var(--border-radius) var(--border-radius); 11 | } 12 | 13 | .footer__label { 14 | margin-right: 0.2em; 15 | font-size: 1.4em; 16 | margin-top: 0.1em; 17 | } 18 | .footer__header { 19 | margin: 0.2em auto 0 0; 20 | font-size: 1em; 21 | } 22 | .footer__select { 23 | font-size: 1em; 24 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/assets/css/Component/l-app.css: -------------------------------------------------------------------------------- 1 | .l-app { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-app__titlebar { 8 | flex: 0 0 var(--titlebar-h); 9 | } 10 | 11 | .l-app__main { 12 | flex: 1 1 auto; 13 | } 14 | 15 | .l-app_footer { 16 | flex: 0 0 var(--footer-h); 17 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/assets/css/Component/l-main.css: -------------------------------------------------------------------------------- 1 | .l-main { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | align-items: stretch; 5 | } 6 | 7 | .l-main__dir-list { 8 | flex: 0 0 var(--dirlist-w); 9 | } 10 | 11 | .l-main__file-list { 12 | flex: 1 1 auto; 13 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/assets/css/Component/titlebar.css: -------------------------------------------------------------------------------- 1 | .titlebar { 2 | background-color: var(--titlebar-bg-color); 3 | color: var(--titlebar-fg-color); 4 | padding: 0.8em 0.6em; 5 | position: sticky; 6 | top: 0; 7 | 8 | display: flex; 9 | flex-flow: row nowrap; 10 | align-items: stretch; 11 | -webkit-user-select: none; 12 | -webkit-app-region: drag; 13 | border-radius: var(--border-radius) var(--border-radius) 0 0; 14 | } 15 | .titlebar__path { 16 | flex: 1 1 auto; 17 | } 18 | .titlebar__btn { 19 | flex: 0 0 25px; 20 | cursor: pointer; 21 | -webkit-app-region: no-drag; 22 | } -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/assets/css/app.css: -------------------------------------------------------------------------------- 1 | @import url("./Base/definitions.css"); 2 | @import url("./Base/base.css"); 3 | @import url("./Component/icon.css"); 4 | @import url("./Component/l-app.css"); 5 | @import url("./Component/l-main.css"); 6 | @import url("./Component/titlebar.css"); 7 | @import url("./Component/footer.css"); 8 | @import url("./Component/dir-list.css"); 9 | @import url("./Component/file-list.css"); 10 | -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-packaging/app/icon-16x16.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-packaging/app/icon-32x32.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/icon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-packaging/app/icon-32x32@2x.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/app/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Cross-platform-Desktop-Application-Development-Electron-Node-NW.js-and-React/b59f6f5a0b97629e7c112297309ac754a229109d/Chapter02/Chapter02/CH2/func-packaging/app/icon-48x48.png -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/src/js/Data/dictionary.js: -------------------------------------------------------------------------------- 1 | exports.dictionary = { 2 | "en-US": { 3 | NAME: "Name", 4 | SIZE: "Size", 5 | MODIFIED: "Modified", 6 | MINIMIZE_WIN: "Minimize window", 7 | RESTORE_WIN: "Restore window", 8 | MAXIMIZE_WIN: "Maximize window", 9 | CLOSE_WIN: "Close window" 10 | }, 11 | "de-DE": { 12 | NAME: "Dateiname", 13 | SIZE: "Größe", 14 | MODIFIED: "Geändert am", 15 | MINIMIZE_WIN: "Fenster minimieren", 16 | RESTORE_WIN: "Fenster wiederherstellen", 17 | MAXIMIZE_WIN: "Fenster maximieren", 18 | CLOSE_WIN: "Fenster schließen" 19 | } 20 | }; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/src/js/View/TitleBarPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * View class that keeps the path in the titlebar in sync with DirService 3 | */ 4 | class TitleBarPathView { 5 | /** 6 | * Create TitleBarPath 7 | * @param {HTMLElement} boundingEl 8 | * @param {DirService} dirService 9 | */ 10 | constructor( boundingEl, dirService ){ 11 | this.el = boundingEl; 12 | dirService.on( "update", () => this.render( dirService.getDir() ) ); 13 | } 14 | /** 15 | * Updates the path 16 | * @param {string} dir 17 | */ 18 | render( dir ) { 19 | this.el.innerHTML = dir; 20 | } 21 | } 22 | 23 | exports.TitleBarPathView = TitleBarPathView; -------------------------------------------------------------------------------- /Chapter02/Chapter02/CH2/func-packaging/webpack.config.js: -------------------------------------------------------------------------------- 1 | const { join } = require( "path" ), 2 | webpack = require( "webpack" ); 3 | 4 | module.exports = { 5 | entry: join( __dirname, "src/js/app.js" ), 6 | target: "node-webkit", 7 | output: { 8 | path: join( __dirname, "app" ), 9 | filename: "bundle.js" 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /Chapter03/electron-intro/README.md: -------------------------------------------------------------------------------- 1 | This example relates to section "Electron" of chapter 3 2 | 3 | Available NPM commands: 4 | - `npm start` - runs the application 5 | 6 | Installing dependencies 7 | ``` 8 | npm install 9 | ``` 10 | 11 | Tested with: 12 | - npm v.5.2.0 13 | - node v.8.1.1 14 | - nw v.0.23.6-sdk 15 | - Ubuntu 16.04 LTS, Windows 10, macOS Sierra 10.12 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Chapter03/electron-intro/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |Joined 2 min ago
13 |