├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── NOTICE
├── README.md
├── app
├── README.md
├── main
│ ├── .eslintrc
│ ├── browser-window.js
│ ├── browser.js
│ ├── certificates.js
│ ├── command-line.js
│ ├── downloads.js
│ ├── hotkeys.js
│ ├── index.js
│ ├── menu
│ │ ├── index.js
│ │ ├── menus.js
│ │ ├── submenu-items.js
│ │ └── template.js
│ ├── paths-util.js
│ ├── pinned-tabs.js
│ ├── protocols.js
│ ├── session-io.js
│ ├── session-restore.js
│ ├── spawn.js
│ ├── state.js
│ └── updater.js
├── package.json
├── services
│ ├── .eslintrc
│ └── content-service
│ │ ├── index.js
│ │ ├── server.js
│ │ └── util.js
├── shared
│ ├── constants
│ │ ├── content-pages-locations.js
│ │ ├── endpoints.js
│ │ └── profile-diff-types.js
│ ├── deferred.js
│ ├── electron.js
│ ├── environment.js
│ ├── logging.js
│ ├── perf.js
│ ├── queue.js
│ ├── user-agent-client.js
│ ├── user-agent-http-client.js
│ └── uuid-util.js
└── ui
│ ├── .eslintrc
│ ├── browser-alt
│ ├── browser.html
│ └── index.js
│ ├── browser-modern
│ ├── actions
│ │ ├── clipboard-effects.js
│ │ ├── developer-effects.js
│ │ ├── external-effects.js
│ │ ├── page-actions.js
│ │ ├── page-effects.js
│ │ ├── profile-actions.js
│ │ ├── profile-effects.js
│ │ ├── root-actions.js
│ │ ├── session-effects.js
│ │ ├── ui-actions.js
│ │ └── ui-effects.js
│ ├── browser.html
│ ├── constants
│ │ ├── action-types.js
│ │ ├── effect-types.js
│ │ └── ui.js
│ ├── css
│ │ ├── browser.css
│ │ └── theme.css
│ ├── index.js
│ ├── model
│ │ ├── active-element.js
│ │ ├── index.js
│ │ ├── location-autocompletion.js
│ │ ├── page-local-history-item.js
│ │ ├── page-meta.js
│ │ ├── page-state.js
│ │ ├── page-ui-state.js
│ │ ├── page.js
│ │ ├── pages.js
│ │ ├── profile.js
│ │ ├── restorable-page.js
│ │ ├── shared-prop-types.js
│ │ ├── ssl-certificate.js
│ │ └── ui.js
│ ├── reducers
│ │ ├── index.js
│ │ ├── pages.js
│ │ ├── profile.js
│ │ ├── root.js
│ │ ├── ui.js
│ │ └── window-id.js
│ ├── sagas
│ │ ├── clipboard-sagas.js
│ │ ├── developer-sagas.js
│ │ ├── index.js
│ │ ├── page-sagas.js
│ │ ├── profile-sagas.js
│ │ ├── session-sagas.js
│ │ ├── ui-sagas.js
│ │ └── window-sagas.js
│ ├── selectors
│ │ ├── pages.js
│ │ ├── profile.js
│ │ ├── root.js
│ │ └── ui.js
│ ├── setup-frontend.jsx
│ ├── setup-ipc.js
│ ├── setup-uac.js
│ ├── store
│ │ └── index.js
│ ├── util
│ │ ├── dom-getters.js
│ │ ├── notifications.js
│ │ ├── record-constructors.js
│ │ ├── session-migrate.js
│ │ └── session-util.js
│ └── views
│ │ ├── app.jsx
│ │ ├── browser
│ │ ├── chrome-area.jsx
│ │ ├── content-area.jsx
│ │ ├── decorations
│ │ │ ├── developerbar.jsx
│ │ │ ├── notificationbar.jsx
│ │ │ ├── searchbar.jsx
│ │ │ ├── statusbar.jsx
│ │ │ └── window-controls.jsx
│ │ ├── location
│ │ │ ├── autocompletion-list-item.jsx
│ │ │ ├── index.jsx
│ │ │ ├── location-buttons.jsx
│ │ │ ├── location-info.jsx
│ │ │ └── security-badge.jsx
│ │ ├── navbar
│ │ │ ├── history-list-item.jsx
│ │ │ ├── index.jsx
│ │ │ ├── navigation-buttons.jsx
│ │ │ └── toolbar-buttons.jsx
│ │ ├── overview
│ │ │ ├── cards.jsx
│ │ │ └── index.jsx
│ │ ├── page
│ │ │ ├── cert-error.jsx
│ │ │ ├── error-page.jsx
│ │ │ ├── index.jsx
│ │ │ └── net-error.jsx
│ │ ├── tabbar
│ │ │ ├── index.jsx
│ │ │ ├── new-tab-btn.jsx
│ │ │ ├── tab-contents.jsx
│ │ │ ├── tab-pointer-area.jsx
│ │ │ ├── tab-visuals.jsx
│ │ │ ├── tab.jsx
│ │ │ └── tabs-list.jsx
│ │ └── window.jsx
│ │ └── menus
│ │ └── page-context-menu.js
│ ├── content
│ ├── actions
│ │ ├── main-actions.js
│ │ └── main-effects.js
│ ├── constants
│ │ ├── action-types.js
│ │ └── effect-types.js
│ ├── credits.html
│ ├── css
│ │ ├── content.css
│ │ └── theme.css
│ ├── favicon.ico
│ ├── historyrestore.html
│ ├── index.html
│ ├── index.jsx
│ ├── model
│ │ ├── content-prop-types.js
│ │ └── index.js
│ ├── reducers
│ │ └── index.js
│ ├── sagas
│ │ └── index.js
│ ├── scripts
│ │ └── historyrestore.js
│ ├── selectors
│ │ └── index.js
│ ├── store
│ │ └── index.js
│ └── views
│ │ ├── app.jsx
│ │ ├── errors
│ │ └── nomatch.jsx
│ │ ├── history
│ │ ├── history-item.jsx
│ │ └── index.jsx
│ │ ├── routes.jsx
│ │ └── stars
│ │ ├── index.jsx
│ │ └── star-item.jsx
│ ├── preload
│ ├── active-element.js
│ ├── context-menu.js
│ ├── index.js
│ ├── metadata-parsing.js
│ ├── metadata-rules.js
│ ├── readability.js
│ ├── reader.js
│ └── reload.js
│ └── shared
│ ├── assets
│ ├── checkboard-background.png
│ ├── devtools
│ │ ├── tool-profiler-active.svg
│ │ └── tool-profiler.svg
│ ├── generic-icons
│ │ ├── globe.svg
│ │ ├── spinner-blue.png
│ │ ├── spinner-gray.png
│ │ └── warning.svg
│ ├── navbar
│ │ ├── identity-icon.svg
│ │ ├── reload-stop-go.png
│ │ ├── ssl-insecure.svg
│ │ ├── ssl-secure.svg
│ │ ├── ssl-unknown.svg
│ │ ├── tofino-page-icon.png
│ │ └── toolbar.png
│ ├── overview
│ │ ├── glyph-ratings-empty.svg
│ │ ├── glyph-ratings-full.svg
│ │ └── glyph-ratings-half.svg
│ ├── tabbar
│ │ ├── close.png
│ │ ├── newtab.png
│ │ ├── tab-background-end.png
│ │ ├── tab-background-middle.png
│ │ ├── tab-background-start.png
│ │ ├── tab-selected-end.svg
│ │ ├── tab-selected-middle.png
│ │ ├── tab-selected-start.svg
│ │ ├── tab-stroke-end.png
│ │ └── tab-stroke-start.png
│ └── window
│ │ ├── glyph-window-close.svg
│ │ ├── glyph-window-maximize.svg
│ │ ├── glyph-window-minimize.svg
│ │ └── osx-controls.png
│ ├── css
│ ├── common.css
│ └── font-awesome.css
│ ├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ └── fontawesome-webfont.woff2
│ ├── style.js
│ ├── util
│ ├── cert.js
│ ├── component-util.js
│ ├── content-script-utils.js
│ ├── dom-serializers.js
│ ├── gestures.js
│ ├── location-util.js
│ ├── redux
│ │ ├── configure-store.js
│ │ └── middleware
│ │ │ ├── history.js
│ │ │ └── thunk.js
│ ├── saga-util.js
│ └── url-util.js
│ └── widgets
│ ├── autocompleted-search.jsx
│ ├── btn.jsx
│ ├── dropdown-menu-btn.jsx
│ ├── fitted-image.jsx
│ ├── icon-globe.jsx
│ ├── icon-warning.jsx
│ ├── list-item.jsx
│ ├── list.jsx
│ ├── overview
│ ├── cards
│ │ ├── base-card.jsx
│ │ ├── overview-card.jsx
│ │ ├── product-card.jsx
│ │ └── simple-card.jsx
│ └── summaries
│ │ ├── product-summary.jsx
│ │ ├── ratings.jsx
│ │ ├── simple-summary.jsx
│ │ └── star.jsx
│ ├── search.jsx
│ ├── selection-list.jsx
│ ├── spinner-blue.jsx
│ ├── spinner-gray.jsx
│ ├── thumbnail.jsx
│ └── vertical-separator.jsx
├── appveyor.yml
├── branding
├── app-icon.icns
├── app-icon.ico
└── iconset
│ ├── tofino-128x128.png
│ ├── tofino-128x128@2x.png
│ ├── tofino-16x16.png
│ ├── tofino-16x16@2x.png
│ ├── tofino-256x256.png
│ ├── tofino-256x256@2x.png
│ ├── tofino-32x32.png
│ ├── tofino-32x32@2x.png
│ ├── tofino-512x512.png
│ └── tofino-512x512@2x.png
├── build
├── config
│ ├── frontends.json
│ ├── webpack.base.js
│ ├── webpack.base.snippets.dev.js
│ ├── webpack.base.snippets.prod.js
│ ├── webpack.base.snippets.ui-shared.js
│ ├── webpack.browser-alt.js
│ ├── webpack.browser-modern.js
│ ├── webpack.content.js
│ ├── webpack.main.js
│ ├── webpack.preload.js
│ └── webpack.services.content.js
├── logging.js
├── main.js
├── task-build-browser.js
├── task-build-content.js
├── task-build-deps.js
├── task-build-main-process.js
├── task-build-modules.js
├── task-build-preload.js
├── task-build-service-content.js
├── task-clean-package.js
├── task-config-builder.js
├── task-package.js
├── task-run.js
├── task-serve.js
├── task-test.js
├── tasks.js
└── utils
│ ├── argv.js
│ ├── base-config.js
│ ├── const.js
│ ├── electron.js
│ ├── empty_module.js
│ ├── index.js
│ ├── process.js
│ ├── rebuild.js
│ ├── runtime.js
│ ├── webpack-process.js
│ └── webpack.js
├── docs
├── UA-service.md
├── building.md
├── diagrams
│ ├── UA-bookmark-star.graffle
│ ├── UA-bookmark-star.png
│ ├── UA-service-architecture.graffle
│ └── UA-service-architecture.png
├── package-manifests.md
└── testing.md
├── package.json
├── scripts
├── bootstrap.py
└── bootstrap.sh
└── test
├── .eslintrc
├── fixtures
├── history.html
├── links.html
├── mozilla.html
└── simple.html
├── mocha.opts
├── renderer
├── .eslintrc
└── mocha.opts
├── unit
├── browser-modern
│ ├── actions
│ │ ├── ui-actions-test.js
│ │ └── ui-effects-test.js
│ ├── constants
│ │ └── constants-test.js
│ ├── model
│ │ └── page-test.js
│ ├── reducers
│ │ ├── root-reducers-test.js
│ │ └── ui-reducers-test.js
│ ├── sagas
│ │ ├── clipboard-sagas-test.js
│ │ ├── developer-sagas-test.js
│ │ ├── page-sagas-test.js
│ │ ├── profile-sagas-test.js
│ │ ├── session-sagas-test.js
│ │ ├── ui-sagas-test.js
│ │ └── window-sagas-test.js
│ ├── selectors
│ │ └── ui-selectors-test.js
│ └── util
│ │ └── dom-getters-test.js
├── build
│ ├── test-tasks.js
│ └── test-utils.js
├── lint
│ ├── shared.js
│ ├── test-dependencies.js
│ ├── test-eslint.js
│ ├── test-pinned-deps.js
│ └── test-version.js
├── shared
│ └── test-url.js
└── user-agent-service
│ └── test-server.js
├── utils
├── driver.js
├── renderer-setup.js
├── server.js
└── thunk-util.js
└── webdriver
└── test-basic.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "production": {
4 | "presets": ["react", "react-optimize"]
5 | },
6 | "development": {
7 | "presets": ["react"]
8 | },
9 | "test": {
10 | "presets": ["react"]
11 | }
12 | },
13 | "only": [
14 | "app/main/**",
15 | "app/services/**",
16 | "app/shared/**",
17 | "app/ui/**",
18 | "build/**",
19 | "test/**"
20 | ],
21 | "plugins": [
22 | "transform-es2015-destructuring",
23 | "transform-es2015-parameters",
24 | "transform-es2015-modules-commonjs",
25 | "transform-async-to-generator",
26 | "transform-object-rest-spread",
27 | "transform-class-properties",
28 | "transform-runtime"
29 | ],
30 | "sourceMaps": "inline",
31 | "retainLines": true
32 | }
33 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/**
2 | app/node_modules/**
3 | lib/**
4 | dist/**
5 | app/ui/preload/readability.js
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/
2 | npm-debug.log
3 | node_modules
4 | dist
5 | *.sw*
6 | /lib
7 | app/build-config.json
8 | .DS_Store
9 | .nyc_output/
10 | *~
11 | /browser.db
12 | .electron
13 | .cache
14 | .vscode
15 | *.log
16 | profile
17 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | Project Tofino
2 | Copyright 2016 Mozilla.
3 |
4 | This product includes software developed at Mozilla (http://www.mozilla.org/).
5 |
--------------------------------------------------------------------------------
/app/README.md:
--------------------------------------------------------------------------------
1 | # src/
2 |
3 | ## main
4 |
5 | Node code that runs in the main process and has access to Electron APIs. Spawns render processes with Electron.
6 |
7 | ## services
8 |
9 | Services used for the main and renderer processes.
10 |
11 | ## ui
12 |
13 | The source for webapps running in the render process. In `ui/browser`, the Redux/React app for the browser chrome UI.
14 | In `ui/content`, the "tofino://" pages like history or bookmarks. Finally, `ui/shared` is to be used by any app in `ui/*`
15 |
16 | ## shared
17 |
18 | Anything used by 'main', 'services' and 'ui'. Also `shared/preload` contains scripts injected in content.`
19 |
--------------------------------------------------------------------------------
/app/main/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": false,
4 | "node": true,
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/app/main/certificates.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | /* eslint-disable no-unused-vars */
14 |
15 | import electron from 'electron';
16 |
17 | const app = electron.app;
18 | const ipc = electron.ipcMain;
19 |
20 | const certificateErrors = new Map();
21 |
22 | export function setupCertificateHandlers() {
23 | // http://electron.atom.io/docs/api/app/#event-certificate-error
24 | app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
25 | // Call false to continue to not trust the certifcate
26 | certificateErrors.set(url, { error, certificate });
27 |
28 | // Calling `false` on the callback explicitly rejects the cert, which causes
29 | // errorCode === -3 for the `did-fail-load` events on webviews, and if we don't do it,
30 | // the cert will fail with the appropriate error information, so do not explicitly
31 | // call `callback(false)`. If we wanted to make an exception, we could check
32 | // here and call the callback with `true`.
33 | // callback(false);
34 | });
35 |
36 | ipc.on('get-certificate-error', (event, { url, id }) => {
37 | const data = certificateErrors.get(url) || {};
38 | data.id = id;
39 | event.sender.send('get-certificate-error-response', data);
40 | });
41 | }
42 |
--------------------------------------------------------------------------------
/app/main/downloads.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export function registerDownloadHandlers(bw) {
14 | bw.webContents.session.on('will-download', (event, item) => {
15 | const itemData = {
16 | url: item.getURL(),
17 | filename: item.getFilename(),
18 | };
19 | item.once('done', (_event, state) => {
20 | // Set `path` after the item is done, since it is not yet
21 | // set by the time `will-download` is fired.
22 | itemData.path = item.getSavePath();
23 |
24 | if (state === 'completed') {
25 | bw.send('download-completed', itemData);
26 | } else if (state === 'interrupted') {
27 | bw.send('download-error', itemData);
28 | }
29 | });
30 | });
31 | }
32 |
--------------------------------------------------------------------------------
/app/main/menu/template.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import menus from './menus';
14 |
15 | export const MinimalAppMenuTemplate = [
16 | menus.file,
17 | menus.edit,
18 | menus.window,
19 | menus.help,
20 | ];
21 |
22 | export const AppMenuTemplate = [
23 | menus.file,
24 | menus.edit,
25 | menus.view,
26 | menus.history,
27 | menus.bookmarks,
28 | menus.tools,
29 | menus.window,
30 | menus.help,
31 | ];
32 |
33 | export const WindowMenuTemplate = [
34 | ...menus.file.submenu,
35 | menus.edit,
36 | menus.view,
37 | menus.history,
38 | menus.bookmarks,
39 | menus.tools,
40 | menus.window,
41 | menus.help,
42 | ];
43 |
44 | if (process.platform === 'darwin') {
45 | MinimalAppMenuTemplate.unshift(menus.osx);
46 | AppMenuTemplate.unshift(menus.osx);
47 | }
48 |
--------------------------------------------------------------------------------
/app/main/paths-util.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import path from 'path';
14 |
15 | export function fileUrl(str) {
16 | let pathName = path.resolve(str).replace(/\\/g, '/');
17 |
18 | // Windows drive letter must be prefixed with a slash.
19 | if (pathName[0] !== '/') {
20 | pathName = `/${pathName}`;
21 | }
22 |
23 | return encodeURI(`file://${pathName}`);
24 | }
25 |
--------------------------------------------------------------------------------
/app/main/pinned-tabs.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { ipcMain, webContents } from 'electron';
14 | import url from 'url';
15 |
16 | function handleWillNavigate(wc, renderer, event, newUrl) {
17 | const currentUrl = url.parse(wc.getURL());
18 |
19 | if (url.parse(newUrl).host !== currentUrl.host) {
20 | event.preventDefault();
21 | renderer.send('new-tab', newUrl);
22 | }
23 | }
24 |
25 | const handlerMap = new WeakMap();
26 |
27 | ipcMain.on('guest-pinned-state', (event, id, pinned) => {
28 | const wc = webContents.fromId(id);
29 | if (pinned) {
30 | const handler = handleWillNavigate.bind(null, wc, event.sender);
31 |
32 | wc.on('will-navigate', handler);
33 | handlerMap.set(wc, handler);
34 | } else {
35 | const handler = handlerMap.get(wc);
36 | if (handler) {
37 | wc.removeListener('will-navigate', handler);
38 | }
39 | }
40 | });
41 |
--------------------------------------------------------------------------------
/app/main/session-restore.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as BW from './browser-window';
14 | import { getSessionKey } from './session-io';
15 |
16 | export async function performApplicationSessionRestore() {
17 | const browserWindows = Object.entries(getSessionKey('browserWindows', { default: {} }));
18 |
19 | if (!browserWindows.length) {
20 | const browserWindow = await BW.createBrowserWindow();
21 | browserWindow.webContents.send('new-tab');
22 | return;
23 | }
24 |
25 | for (const [windowId, appState] of browserWindows) {
26 | await BW.createBrowserWindow({ windowId, appState });
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/main/state.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | /**
14 | * This module is to expose constants that need to be accessible
15 | * throughout the main process, like electron.app state and
16 | * singleton classes, like UserAgentService.
17 | */
18 |
19 | import electron from 'electron';
20 | import Deferred from '../shared/deferred';
21 | import UserAgentClient from '../shared/user-agent-client';
22 |
23 | const { ipcMain } = electron;
24 |
25 | // Expose the UserAgentClient singleton
26 | export const userAgentClient = new UserAgentClient();
27 |
28 | // Constant promise used to signal elsewhere in the main process
29 | // that the application has launched and finished loading
30 | // the initial browser window
31 | const appInitializedDeferred = new Deferred();
32 | export const INITIALIZED = appInitializedDeferred.promise;
33 | ipcMain.once('main:first-window-created', appInitializedDeferred.resolve);
34 |
--------------------------------------------------------------------------------
/app/main/updater.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import os from 'os';
14 | import { setInterval } from 'timers';
15 | import { app, autoUpdater, dialog } from 'electron';
16 | import { version as appVersion, name as appName } from '../../package.json';
17 |
18 | // Check once an hour
19 | const UPDATE_CHECK_TIME = 1000 * 60 * 60;
20 |
21 | // Exe name is set to the same as the package name
22 | app.setAppUserModelId(`com.squirrel.${appName}.${appName}`);
23 |
24 | try {
25 | autoUpdater.setFeedURL(`https://tofino-update-server.herokuapp.com/update/${os.platform()}_${os.arch()}/${appVersion}`);
26 | } catch (e) {
27 | // This happens when the application isn't code signed on OSX.
28 | }
29 |
30 | autoUpdater.on('update-downloaded', () => {
31 | dialog.showMessageBox({
32 | type: 'question',
33 | title: 'Update Available',
34 | message: 'An update is available, would you like to install it?',
35 | buttons: ['Yes', 'No'],
36 | defaultId: 0,
37 | cancelId: 1,
38 | }, response => {
39 | if (response === 0) {
40 | autoUpdater.quitAndInstall();
41 | }
42 | });
43 | });
44 |
45 | function checkForUpdates() {
46 | try {
47 | autoUpdater.checkForUpdates();
48 | } catch (e) {
49 | // This happens if the app isn't installed
50 | }
51 | }
52 |
53 | export function startUpdateChecks() {
54 | checkForUpdates();
55 |
56 | setInterval(checkForUpdates, UPDATE_CHECK_TIME);
57 | }
58 |
--------------------------------------------------------------------------------
/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Tofino",
3 | "productName": "tofino",
4 | "version": "0.2.0",
5 | "author": {
6 | "name": "Mozilla",
7 | "email": "tofino-dev@mozilla.org",
8 | "url": "https://mozilla.github.io/tofino/"
9 | },
10 | "description": "Project Tofino",
11 | "main": "main/index.js",
12 | "license": "Apache-2.0",
13 | "dependencies": {
14 | "datomish-user-agent-service": "0.0.5",
15 | "fs-promise": "0.5.0",
16 | "thenify": "3.2.0",
17 | "yargs": "6.0.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/services/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": false,
4 | "node": true,
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/app/services/content-service/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import fs from 'fs';
14 | import path from 'path';
15 | import colors from 'colors/safe';
16 | import { logger, pipeToStream } from '../../shared/logging';
17 | import * as contentService from './server';
18 | import * as endpoints from '../../shared/constants/endpoints';
19 | import { parseArgs } from '../../shared/environment';
20 |
21 | process.on('uncaughtException', err => {
22 | logger.error(err.stack);
23 | process.exit(1);
24 | });
25 |
26 | process.on('unhandledRejection', (reason, p) => {
27 | logger.error(`Unhandled Rejection at: Promise ${JSON.stringify(p)}`);
28 | logger.error(reason.stack);
29 | process.exit(2);
30 | });
31 |
32 | const fileStream = fs.createWriteStream(path.join(parseArgs().profile, 'content-service.log'));
33 | logger.addStream(pipeToStream(fileStream, 'debug'));
34 |
35 | // Start the content service, serving `tofino://` pages.
36 | contentService.start().then(() => {
37 | const msg = `Started a Content service running on ${endpoints.CONTENT_SERVER_PORT}.`;
38 | logger.info(colors.green(msg));
39 | });
40 |
--------------------------------------------------------------------------------
/app/shared/constants/content-pages-locations.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as endpoints from './endpoints';
14 |
15 | export const HISTORY_PAGE = `${endpoints.TOFINO_PROTOCOL}://history`;
16 | export const STARS_PAGE = `${endpoints.TOFINO_PROTOCOL}://stars`;
17 | export const CREDITS_PAGE = `${endpoints.TOFINO_PROTOCOL}://credits`;
18 |
--------------------------------------------------------------------------------
/app/shared/constants/endpoints.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import BUILD_CONFIG from '../../build-config';
14 |
15 | export const TOFINO_PROTOCOL = 'tofino';
16 |
17 | export const HISTORY_RESTORE_ADDR = `${TOFINO_PROTOCOL}://historyrestore`;
18 |
19 | export const UA_SERVICE_ADDR = 'localhost';
20 | export const UA_SERVICE_PORT = BUILD_CONFIG.packaged ? 9091 : 9090;
21 | export const UA_SERVICE_VERSION = 'v1';
22 |
23 | export const UA_SERVICE_ORIGIN = `http://${UA_SERVICE_ADDR}:${UA_SERVICE_PORT}`;
24 | export const UA_SERVICE_HTTP = `${UA_SERVICE_ORIGIN}/${UA_SERVICE_VERSION}`;
25 | export const UA_SERVICE_WS = `ws://${UA_SERVICE_ADDR}:${UA_SERVICE_PORT}/${UA_SERVICE_VERSION}/ws`;
26 |
27 | export const CONTENT_SERVER_ADDR = 'localhost';
28 | export const CONTENT_SERVER_PORT = BUILD_CONFIG.packaged ? 9192 : 9191;
29 | export const CONTENT_SERVER_VERSION = 'v1';
30 |
31 | export const CONTENT_SERVER_ORIGIN = `http://${CONTENT_SERVER_ADDR}:${CONTENT_SERVER_PORT}`;
32 | export const CONTENT_SERVER_HTTP = `${CONTENT_SERVER_ORIGIN}/${CONTENT_SERVER_VERSION}`;
33 |
--------------------------------------------------------------------------------
/app/shared/constants/profile-diff-types.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export const BOOKMARKS = 'PROFILE_DIFF_BOOKMARKS';
14 | export const RECENT_BOOKMARKS = 'PROFILE_DIFF_RECENT_BOOKMARKS';
15 |
--------------------------------------------------------------------------------
/app/shared/deferred.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export default class Deferred {
14 | constructor() {
15 | this.promise = new Promise((resolve, reject) => {
16 | this.reject = reject;
17 | this.resolve = resolve;
18 | });
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/shared/electron.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | /* eslint global-require: 0 */
14 |
15 | // Stub out ipcRenderer when electron cannot be found (unit tests)
16 | let electron;
17 | try {
18 | electron = require('electron');
19 | } catch (e) {
20 | const { ipcMain, ipcRenderer } = require('electron-ipc-mock')();
21 |
22 | electron = {
23 | ipcMain,
24 | ipcRenderer,
25 | remote: {
26 | Menu() {},
27 | MenuItem() {},
28 | getCurrentWindow() {},
29 | },
30 | clipboard: {
31 | writeText() {},
32 | readText() {},
33 | },
34 | };
35 | }
36 |
37 | const { ipcMain, ipcRenderer, remote, clipboard } = electron;
38 | export { ipcMain, ipcRenderer, remote, clipboard };
39 |
--------------------------------------------------------------------------------
/app/shared/perf.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | /* eslint global-require: 0 */
14 | /* eslint import/no-mutable-exports: 0 */
15 |
16 | import BUILD_CONFIG from '../build-config';
17 |
18 | let perf;
19 | if (BUILD_CONFIG.development) {
20 | perf = require('react-addons-perf'); // eslint-disable-line
21 | } else {
22 | perf = {
23 | start() {},
24 | stop() {},
25 | printWasted() {},
26 | getLastMeasurements() {},
27 | };
28 | }
29 |
30 | export default perf;
31 |
--------------------------------------------------------------------------------
/app/shared/queue.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import queue from 'queue';
14 |
15 | export default class Queue {
16 | constructor(options) {
17 | this._q = queue(options);
18 | }
19 |
20 | push(fn) {
21 | this._q.push(fn);
22 |
23 | // Always start draining the queue if previously empty. This is an
24 | // oddity with the underlying queue implementation itself: when empty,
25 | // need to manually restart after pushing.
26 | this._q.start();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/shared/uuid-util.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | const UUID_REGEX = /[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/;
14 |
15 | export function isUUID(uuidString) {
16 | return UUID_REGEX.test(uuidString);
17 | }
18 |
--------------------------------------------------------------------------------
/app/ui/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "node": false,
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/app/ui/browser-alt/browser.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Nothing to see here
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/ui/browser-alt/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/browser-alt/index.js
--------------------------------------------------------------------------------
/app/ui/browser-modern/actions/clipboard-effects.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as EffectTypes from '../constants/effect-types';
14 |
15 | export function copyTextToClipboard(text) {
16 | return {
17 | type: EffectTypes.COPY_TEXT_TO_CLIPBOARD,
18 | text,
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/actions/developer-effects.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as EffectTypes from '../constants/effect-types';
14 |
15 | export function perfRecordStart() {
16 | return {
17 | type: EffectTypes.PERF_RECORD_START,
18 | };
19 | }
20 |
21 | export function perfRecordStop() {
22 | return {
23 | type: EffectTypes.PERF_RECORD_STOP,
24 | };
25 | }
26 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/actions/external-effects.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as EffectTypes from '../constants/effect-types';
14 |
15 | export function maximizeWindow() {
16 | return {
17 | type: EffectTypes.MAXIMIZE_WINDOW,
18 | };
19 | }
20 |
21 | export function minimizeWindow() {
22 | return {
23 | type: EffectTypes.MINIMIZE_WINDOW,
24 | };
25 | }
26 |
27 | export function closeWindow() {
28 | return {
29 | type: EffectTypes.CLOSE_WINDOW,
30 | };
31 | }
32 |
33 | export function reloadWindow() {
34 | return {
35 | type: EffectTypes.RELOAD_WINDOW,
36 | };
37 | }
38 |
39 | export function openAppMenu() {
40 | return {
41 | type: EffectTypes.OPEN_APP_MENU,
42 | };
43 | }
44 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/actions/profile-actions.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as ActionTypes from '../constants/action-types';
14 |
15 | export function setLocalBookmarkState(url, bookmarked) {
16 | return {
17 | type: ActionTypes.SET_LOCAL_BOOKMARK_STATE,
18 | url,
19 | bookmarked,
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/actions/profile-effects.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as EffectTypes from '../constants/effect-types';
14 | import * as PagesSelectors from '../selectors/pages';
15 |
16 | export function fetchLocationAutocompletions(pageId, text) {
17 | return {
18 | type: EffectTypes.FETCH_LOCATION_AUTOCOMPLETIONS,
19 | pageId,
20 | text,
21 | };
22 | }
23 |
24 | export function setRemoteBookmarkState(pageId, bookmarked) {
25 | return (dispatch, getState) => {
26 | dispatch({
27 | type: EffectTypes.SET_REMOTE_BOOKMARK_STATE,
28 | page: PagesSelectors.getPageById(getState(), pageId),
29 | bookmarked,
30 | });
31 | };
32 | }
33 |
34 | export function addRemoteHistory(pageId) {
35 | return (dispatch, getState) => {
36 | dispatch({
37 | type: EffectTypes.ADD_REMOTE_HISTORY,
38 | page: PagesSelectors.getPageById(getState(), pageId),
39 | });
40 | };
41 | }
42 |
43 | export function addRemoteCapturedPage(pageId, readerResult) {
44 | return (dispatch, getState) => {
45 | dispatch({
46 | type: EffectTypes.ADD_REMOTE_CAPTURED_PAGE,
47 | page: PagesSelectors.getPageById(getState(), pageId),
48 | readerResult,
49 | });
50 | };
51 | }
52 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/actions/root-actions.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as ActionTypes from '../constants/action-types';
14 |
15 | export function setWindowId(windowId) {
16 | return {
17 | type: ActionTypes.SET_WINDOW_ID,
18 | windowId,
19 | };
20 | }
21 |
22 | export function overwriteAppState(state, options = {}) {
23 | return {
24 | type: ActionTypes.OVERWRITE_APP_STATE,
25 | options,
26 | state,
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/actions/ui-actions.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as ActionTypes from '../constants/action-types';
14 |
15 | export function setActiveElement(owner, details) {
16 | return {
17 | type: ActionTypes.SET_ACTIVE_ELEMENT,
18 | owner,
19 | details,
20 | };
21 | }
22 |
23 | export function setStatusText(statusText) {
24 | return {
25 | type: ActionTypes.SET_STATUS_TEXT,
26 | statusText,
27 | };
28 | }
29 |
30 | export function showOverview() {
31 | return {
32 | type: ActionTypes.SET_OVERVIEW_VISIBILITY,
33 | visibility: true,
34 | };
35 | }
36 |
37 | export function hideOverview() {
38 | return {
39 | type: ActionTypes.SET_OVERVIEW_VISIBILITY,
40 | visibility: false,
41 | };
42 | }
43 |
44 | export function setLocationAutocompletions(pageId, autocompletions) {
45 | return {
46 | type: ActionTypes.SET_LOCATION_AUTOCOMPLETIONS,
47 | pageId,
48 | autocompletions,
49 | };
50 | }
51 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/browser.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/constants/action-types.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | // Root actions
14 |
15 | export const SET_WINDOW_ID = 'SET_WINDOW_ID';
16 | export const OVERWRITE_APP_STATE = 'OVERWRITE_APP_STATE';
17 |
18 | // Profile actions
19 |
20 | export const SET_LOCAL_BOOKMARK_STATE = 'SET_LOCAL_BOOKMARK_STATE';
21 |
22 | // Page actions
23 |
24 | export const CREATE_PAGE = 'CREATE_PAGE';
25 | export const REMOVE_PAGE = 'REMOVE_PAGE';
26 | export const SET_SELECTED_PAGE = 'SET_SELECTED_PAGE';
27 | export const RESET_PAGE_DATA = 'RESET_PAGE_DATA';
28 | export const SET_PAGE_INDEX = 'SET_PAGE_INDEX';
29 | export const SET_PAGE_DETAILS = 'SET_PAGE_DETAILS';
30 | export const SET_PAGE_META = 'SET_PAGE_META';
31 | export const SET_PAGE_STATE = 'SET_PAGE_STATE';
32 | export const SET_PAGE_UI_STATE = 'SET_PAGE_UI_STATE';
33 | export const SET_LOCATION_AUTOCOMPLETIONS = 'SET_LOCATION_AUTOCOMPLETIONS';
34 | export const SET_LOCAL_PAGE_HISTORY = 'SET_LOCAL_PAGE_HISTORY';
35 | export const POP_RECENTLY_CLOSED_PAGE = 'POP_RECENTLY_CLOSED_PAGE';
36 | export const SAVE_RESTORABLE_PAGE = 'SAVE_RESTORABLE_PAGE';
37 |
38 | // UI actions
39 |
40 | export const SET_ACTIVE_ELEMENT = 'SET_ACTIVE_ELEMENT';
41 | export const SET_STATUS_TEXT = 'SET_STATUS_TEXT';
42 | export const SET_OVERVIEW_VISIBILITY = 'SET_OVERVIEW_VISIBILITY';
43 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/css/browser.css:
--------------------------------------------------------------------------------
1 | #browser-container {
2 | width: 100%;
3 | height: 100%;
4 | }
5 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | /* eslint import/imports-first: "off" */
14 |
15 | import { ipcRenderer } from '../../shared/electron';
16 |
17 | // In the case of uncaught error, which is often due to compilation failures,
18 | // be sure to tell the main process that this window is ready to display
19 | // even if it really isn't. The main process will then show the window (if it
20 | // hasn't already) which allows the browser devtools to debug the underlying issue.
21 | const sendWindowReady = (error = false) => ipcRenderer.send('window-ready', error);
22 | window.onerror = () => sendWindowReady(true);
23 |
24 | // import whyDidYouUpdate from 'why-did-you-update';
25 | // import BUILD_CONFIG from '../../build-config';
26 |
27 | import { createBrowserStore } from './store';
28 | import setupFrontend from './setup-frontend';
29 | import setupUserAgentClient from './setup-uac';
30 | import setupIPCCommunication from './setup-ipc';
31 |
32 | // Currently the `why-did-you-update` library suffers from an uncaught
33 | // "Maximum call stack size exceeded" error, so disable it for now.
34 | // if (BUILD_CONFIG.development) {
35 | // whyDidYouUpdate(React);
36 | // }
37 |
38 | const store = createBrowserStore();
39 | const userAgentClient = setupUserAgentClient({
40 | onConnected: sendWindowReady,
41 | onDiff: store.dispatch,
42 | });
43 |
44 | setupFrontend({ store, userAgentClient });
45 | setupIPCCommunication({ store, userAgentClient });
46 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/active-element.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 |
17 | const VERSION = 1;
18 |
19 | const ActiveElement = register(Immutable.Record({
20 | owner: '', // ActiveElement.OWNER
21 | nodeName: '',
22 | }, `ActiveElement_v${VERSION}`));
23 |
24 |
25 | ActiveElement.OWNER = {
26 | CHROME: 'chrome',
27 | CONTENT: 'content',
28 | };
29 |
30 | export default ActiveElement;
31 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 | import Profile from './profile';
17 | import Pages from './pages';
18 | import UIState from './ui';
19 |
20 | const VERSION = 1;
21 |
22 | export default register(Immutable.Record({
23 | windowId: null,
24 | profile: new Profile(),
25 | pages: new Pages(),
26 | ui: new UIState(),
27 | }, `State_v${VERSION}`));
28 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/location-autocompletion.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 |
17 | const VERSION = 1;
18 |
19 | export default register(Immutable.Record({
20 | url: '',
21 | title: '',
22 | }, `LocationAutocompletion_v${VERSION}`));
23 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/page-local-history-item.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 |
17 | const VERSION = 1;
18 |
19 | export default register(Immutable.Record({
20 | url: '',
21 | active: false,
22 | }, `LocalHistoryItem_v${VERSION}`));
23 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/page-meta.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 |
17 | const VERSION = 1;
18 |
19 | export default register(Immutable.Record({
20 | // Page data.
21 | url: undefined,
22 | title: undefined,
23 |
24 | // Page media.
25 | icon_url: undefined,
26 | image_url: undefined,
27 |
28 | // Page info.
29 | type: undefined,
30 | description: undefined,
31 | keywords: undefined,
32 |
33 | // Product pages properties.
34 | rating: undefined,
35 | worst_rating: undefined,
36 | best_rating: undefined,
37 | review_count: undefined,
38 | price: undefined,
39 | currency: undefined,
40 | }, `PageMeta_v${VERSION}`));
41 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/page-state.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 | import SSLCertificate from './ssl-certificate';
17 |
18 | const VERSION = 1;
19 |
20 | const PageState = register(Immutable.Record({
21 | load: '', // PageState.STATES
22 | navigationType: '', // PageState.NAVIGATION_TYPES
23 | code: -1, // HTTP code
24 | description: '', // HTTP description
25 |
26 | // https://github.com/electron/electron/blob/master/docs/api/app.md#event-certificate-error
27 | error: '',
28 | certificate: new SSLCertificate(),
29 |
30 | }, `PageState_v${VERSION}`));
31 |
32 | PageState.STATES = {
33 | CONNECTING: 'connecting',
34 | LOADING: 'loading',
35 | LOADED: 'loaded',
36 | FAILED: 'failed',
37 | };
38 |
39 | PageState.NAVIGATION_TYPES = {
40 | NAVIGATED_TO_LOCATION: 'navigated-to-location',
41 | NAVIGATED_BACK: 'navigated-back',
42 | NAVIGATED_FORWARD: 'navigated-forward',
43 | REFRESHED: 'refreshed',
44 | NAVIGATED_IN_HISTORY: 'navigated-in-history',
45 | };
46 |
47 | export default PageState;
48 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/page-ui-state.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 |
17 | const VERSION = 1;
18 |
19 | const PageUIState = register(Immutable.Record({
20 | preventInteraction: false,
21 | zoomLevel: 0,
22 | searchVisible: false,
23 | searchFocused: false,
24 | pinned: false,
25 | }, `PageUIState_v${VERSION}`));
26 |
27 | // See http://electron.atom.io/docs/api/web-view-tag/#webviewsetzoomlevellevel
28 | PageUIState.ZOOM_LEVEL_DEFAULT = 0;
29 | PageUIState.ZOOM_LEVEL_10_PERCENT = 0.5;
30 |
31 | export default PageUIState;
32 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/page.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 | import uuid from 'uuid';
15 |
16 | import { register } from '../util/record-constructors';
17 | import { logger } from '../../../shared/logging';
18 | import PageMeta from './page-meta';
19 | import PageState from './page-state';
20 | import PageUIState from './page-ui-state';
21 | import { isHistoryRestoreUrl } from '../../shared/util/url-util';
22 |
23 | const VERSION = 1;
24 | const LOADING_TITLE = 'Loading…';
25 |
26 | export default class Page extends register(Immutable.Record({
27 | id: '',
28 | location: '',
29 | title: '',
30 | faviconUrl: '',
31 | meta: new PageMeta(),
32 | state: new PageState(),
33 | uiState: new PageUIState(),
34 | history: Immutable.List(),
35 | historyIndex: -1,
36 | getTabTitle() {
37 | if (isHistoryRestoreUrl(this.location)) {
38 | return LOADING_TITLE;
39 | }
40 | return this.title || this.meta.title || this.location || LOADING_TITLE;
41 | },
42 | }, `Page_v${VERSION}`)) {
43 | constructor(data) {
44 | if (!data || !data.id) {
45 | logger.warn('Required property `id` missing from page constructor.');
46 | super({ id: uuid.v4(), ...data });
47 | } else {
48 | super(data);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/profile.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 |
17 | const VERSION = 1;
18 |
19 | export default register(Immutable.Record({
20 | bookmarks: Immutable.Set(),
21 | }, `Profile_v${VERSION}`));
22 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/restorable-page.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 |
17 | const VERSION = 1;
18 |
19 | const RestorablePage = register(Immutable.Record({
20 | restoreURL: '',
21 | pageIndex: -1,
22 | id: -1, // Session ID
23 | }, `RestorablePage_v${VERSION}`));
24 |
25 | export default RestorablePage;
26 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/ssl-certificate.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 |
17 | const VERSION = 1;
18 |
19 | export default register(Immutable.Record({
20 | // https://github.com/electron/electron/blob/master/docs/api/structures/certificate.md
21 | data: '',
22 | issuerName: '',
23 | subjectName: '',
24 | serialNumber: '',
25 | validStart: -1,
26 | validExpiry: -1,
27 | fingerprint: '',
28 | }, `SSLCertificate_v${VERSION}`));
29 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/model/ui.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import { register } from '../util/record-constructors';
16 | import ActiveElement from './active-element';
17 |
18 | const VERSION = 1;
19 |
20 | export default register(Immutable.Record({
21 | activeElement: new ActiveElement(),
22 | statusText: '',
23 | overviewVisible: false,
24 | locationAutocompletions: Immutable.Map(),
25 | }, `UIState_v${VERSION}`));
26 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/reducers/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { combineReducers } from 'redux-immutable';
14 | import reduceReducers from 'reduce-reducers';
15 |
16 | import root from './root';
17 | import windowId from './window-id';
18 | import profile from './profile';
19 | import pages from './pages';
20 | import ui from './ui';
21 |
22 | export default reduceReducers(
23 | root,
24 | combineReducers({
25 | windowId,
26 | profile,
27 | pages,
28 | ui,
29 | }),
30 | );
31 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/reducers/profile.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import Profile from '../model/profile';
16 | import * as ActionTypes from '../constants/action-types';
17 | import * as ProfileDiffTypes from '../../../shared/constants/profile-diff-types';
18 |
19 | export default function(state = new Profile(), action) {
20 | switch (action.type) {
21 |
22 | // Actions coming from the profile service.
23 |
24 | case ProfileDiffTypes.BOOKMARKS:
25 | return setBookmarks(state, action.payload);
26 |
27 | // Actions dispatched by the frontend.
28 |
29 | case ActionTypes.SET_LOCAL_BOOKMARK_STATE:
30 | return setLocalBookmarkState(state, action.url, action.bookmarked);
31 |
32 | default:
33 | return state;
34 | }
35 | }
36 |
37 | function setBookmarks(state, bookmarks) {
38 | return state.set('bookmarks', Immutable.Set(bookmarks));
39 | }
40 |
41 | function setLocalBookmarkState(state, url, bookmarked) {
42 | return state.set('bookmarks', bookmarked
43 | ? state.bookmarks.add(url)
44 | : state.bookmarks.delete(url));
45 | }
46 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/reducers/root.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as ActionTypes from '../constants/action-types';
14 | import * as PagesSelectors from '../selectors/pages';
15 | import { createHistoryRestoreUrl } from '../../shared/util/url-util';
16 |
17 | export default function(state, action) {
18 | switch (action.type) {
19 | case ActionTypes.OVERWRITE_APP_STATE:
20 | return overwriteAppState(state, action.state, action.options);
21 |
22 | default:
23 | return state;
24 | }
25 | }
26 |
27 | function overwriteAppState(prevState, nextState, options = {}) {
28 | if (!options.restoreHistory) {
29 | return nextState;
30 | }
31 |
32 | return nextState.withMutations(mut => {
33 | const ids = mut.getIn(['pages', 'ids']);
34 | for (const pageId of ids) {
35 | const history = PagesSelectors.getPageHistoryURLs(mut, pageId);
36 | const historyIndex = PagesSelectors.getPageHistoryIndex(mut, pageId);
37 | const restoreURL = createHistoryRestoreUrl(history, historyIndex);
38 | mut.setIn(['pages', 'map', pageId, 'location'], restoreURL);
39 | }
40 | });
41 | }
42 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/reducers/window-id.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as ActionTypes from '../constants/action-types';
14 |
15 | export default function(state = null, action) {
16 | switch (action.type) {
17 | case ActionTypes.SET_WINDOW_ID:
18 | return setWindowId(state, action.windowId);
19 |
20 | default:
21 | return state;
22 | }
23 | }
24 |
25 | function setWindowId(prevWindowId, nextWindowId) {
26 | return nextWindowId;
27 | }
28 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/sagas/clipboard-sagas.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { apply } from 'redux-saga/effects';
14 |
15 | import { logger } from '../../../shared/logging';
16 | import { infallible, takeLatestMultiple } from '../../shared/util/saga-util';
17 | import { clipboard } from '../../../shared/electron';
18 | import * as EffectTypes from '../constants/effect-types';
19 |
20 | export default function*() {
21 | yield takeLatestMultiple({ infallible, logger },
22 | [EffectTypes.COPY_TEXT_TO_CLIPBOARD, copyTextToClipboard],
23 | );
24 | }
25 |
26 | export function* copyTextToClipboard({ text }) {
27 | yield apply(clipboard, clipboard.writeText, [text]);
28 | }
29 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/sagas/developer-sagas.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { call } from 'redux-saga/effects';
14 |
15 | import { logger } from '../../../shared/logging';
16 | import { infallible, takeLatestMultiple } from '../../shared/util/saga-util';
17 | import * as EffectTypes from '../constants/effect-types';
18 | import Perf from '../../../shared/perf';
19 |
20 | export default function*() {
21 | yield takeLatestMultiple({ infallible, logger },
22 | [EffectTypes.PERF_RECORD_START, perfStart],
23 | [EffectTypes.PERF_RECORD_STOP, perfStop],
24 | );
25 | }
26 |
27 | export function* perfStart() {
28 | yield call(Perf.start);
29 | }
30 |
31 | export function* perfStop() {
32 | yield call(Perf.stop);
33 | yield call(Perf.printWasted, yield call(Perf.getLastMeasurements));
34 | }
35 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/sagas/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import developer from './developer-sagas';
14 | import window from './window-sagas';
15 | import session from './session-sagas';
16 | import profile from './profile-sagas';
17 | import page from './page-sagas';
18 | import ui from './ui-sagas';
19 |
20 | export default function*() {
21 | yield [
22 | developer(),
23 | window(),
24 | session(),
25 | profile(),
26 | page(),
27 | ui(),
28 | ];
29 | }
30 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/selectors/profile.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export function getProfile(state) {
14 | return state.profile;
15 | }
16 |
17 | export function getBookmarks(state) {
18 | return state.profile.bookmarks;
19 | }
20 |
21 | export function isBookmarked(state, url) {
22 | return getBookmarks(state).has(url);
23 | }
24 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/selectors/root.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export function getWindowId(state) {
14 | return state.windowId;
15 | }
16 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/selectors/ui.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export function getActiveElement(state) {
14 | return state.ui.activeElement;
15 | }
16 |
17 | export function getStatusText(state) {
18 | return state.ui.statusText;
19 | }
20 |
21 | export function getOverviewVisible(state) {
22 | return state.ui.overviewVisible;
23 | }
24 |
25 | export function getLocationAutocompletions(state, pageId) {
26 | return state.ui.locationAutocompletions.get(pageId);
27 | }
28 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/setup-frontend.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React from 'react';
14 | import ReactDOM from 'react-dom';
15 | import { Provider } from 'react-redux';
16 |
17 | import App from './views/app';
18 | import { serializeNode } from '../shared/util/dom-serializers';
19 | import * as UIEffects from './actions/ui-effects';
20 |
21 | export default function({ store }) {
22 | const container = document.getElementById('browser-container');
23 |
24 | // Track details about the currently focused elements in the app state.
25 | document.addEventListener('blur', () => {
26 | store.dispatch(UIEffects.setChromeActiveElement(null));
27 | }, true);
28 |
29 | document.addEventListener('focus', () => {
30 | // We shouldn't send the element itself, only some data about it, since
31 | // app state is intended to be immutable and easily serializable.
32 | // Furthermore, when focus is in the page content, we won't be able to send
33 | // the dom node itself via ipc anyway.
34 | store.dispatch(UIEffects.setChromeActiveElement(serializeNode(document.activeElement)));
35 | }, true);
36 |
37 | // We start rendering before we connect to the UA service and before we receive
38 | // the initial state so that if an error occurs while we connect, we at least
39 | // have some UI in place.
40 | ReactDOM.render(, container);
41 | }
42 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/setup-uac.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import UserAgentClient from '../../shared/user-agent-client';
14 |
15 | export default function({ onConnected, onDiff }) {
16 | const userAgentClient = new UserAgentClient();
17 |
18 | // When we've connected to the UA service and (synchronously) rendered
19 | // the initial UI, this window is ready to display.
20 | userAgentClient.on('connected', onConnected);
21 |
22 | // It's dangerous to trust the service in this way, but good enough for now.
23 | userAgentClient.on('diff', onDiff);
24 |
25 | return userAgentClient;
26 | }
27 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/store/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import createSagaMiddleware from 'redux-saga';
14 | import configureStore from '../../shared/util/redux/configure-store';
15 | import rootReducer from '../reducers';
16 | import rootSaga from '../sagas';
17 | import State from '../model';
18 |
19 | export function createBrowserStore() {
20 | const initialState = new State(rootReducer(undefined, { type: null }));
21 | const saga = createSagaMiddleware();
22 | const store = configureStore(rootReducer, initialState, [saga]);
23 | saga.run(rootSaga);
24 | return store;
25 | }
26 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/util/dom-getters.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export function getWebViewForPageId(doc, pageId) {
14 | return doc.querySelector(
15 | `#browser-page-${pageId} webview`);
16 | }
17 |
18 | export function getURLBarForPageId(doc, pageId) {
19 | return doc.querySelector(
20 | `#browser-navbar-${pageId} .browser-location input`);
21 | }
22 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/util/record-constructors.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | const RECORDS = new Set();
14 |
15 | export function register(record) {
16 | RECORDS.add(record);
17 | return record;
18 | }
19 |
20 | export function getAllRegisteredRecords() {
21 | return [...RECORDS];
22 | }
23 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/util/session-util.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import transit from 'transit-immutable-js';
14 |
15 | import { getAllRegisteredRecords } from './record-constructors';
16 | import { migrateObsoleteOrDeprecatedRecord } from './session-migrate';
17 |
18 | export function serializeAppState(state) {
19 | // Save the entire app state for now. If for some reason we need to
20 | // filter or massage the current store shape before saving, do it here.
21 | const records = getAllRegisteredRecords();
22 | return transit.withRecords(records).toJSON(state);
23 | }
24 |
25 | export function deserializeAppState(string) {
26 | const records = getAllRegisteredRecords();
27 | return transit.withRecords(records, migrateObsoleteOrDeprecatedRecord).fromJSON(string);
28 | }
29 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/views/app.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component } from 'react';
14 | import PureRenderMixin from 'react-addons-pure-render-mixin';
15 |
16 | import { StyleUtil } from '../../shared/style';
17 | import BrowserWindow from './browser/window';
18 |
19 | class App extends Component {
20 | constructor(props) {
21 | super(props);
22 | this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
23 | }
24 |
25 | render() {
26 | return ;
27 | }
28 | }
29 |
30 | App.displayName = 'App';
31 |
32 | export default StyleUtil.wrap(App);
33 |
--------------------------------------------------------------------------------
/app/ui/browser-modern/views/browser/window.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component } from 'react';
14 | import PureRenderMixin from 'react-addons-pure-render-mixin';
15 |
16 | import Style from '../../../shared/style';
17 | import ChromeArea from './chrome-area';
18 | import ContentArea from './content-area';
19 | import Overview from './overview';
20 |
21 | const BROWSER_WINDOW_STYLE = Style.registerStyle({
22 | flexDirection: 'column',
23 | overflow: 'hidden',
24 | width: '100%',
25 | height: '100%',
26 | background: 'var(--theme-window-background)',
27 | });
28 |
29 | class BrowserWindow extends Component {
30 | constructor(props) {
31 | super(props);
32 | this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
33 | }
34 |
35 | render() {
36 | return (
37 |
39 |
40 |
41 |
42 |
43 | );
44 | }
45 | }
46 |
47 | BrowserWindow.displayName = 'BrowserWindow';
48 |
49 | export default BrowserWindow;
50 |
--------------------------------------------------------------------------------
/app/ui/content/actions/main-actions.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as ActionTypes from '../constants/action-types';
14 |
15 | export function showHistory(visitedPages) {
16 | return {
17 | type: ActionTypes.SHOW_HISTORY,
18 | visitedPages,
19 | };
20 | }
21 |
22 | export function showStars(starredItems) {
23 | return {
24 | type: ActionTypes.SHOW_STARS,
25 | starredItems,
26 | };
27 | }
28 |
--------------------------------------------------------------------------------
/app/ui/content/actions/main-effects.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as EffectTypes from '../constants/effect-types';
14 |
15 | export function fetchHistory({ query, limit }) {
16 | return {
17 | type: EffectTypes.FETCH_HISTORY,
18 | query,
19 | limit,
20 | };
21 | }
22 |
23 | export function fetchStars({ limit }) {
24 | return {
25 | type: EffectTypes.FETCH_STARS,
26 | limit,
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/app/ui/content/constants/action-types.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export const SHOW_HISTORY = 'SHOW_HISTORY';
14 | export const SHOW_STARS = 'SHOW_STARS';
15 |
--------------------------------------------------------------------------------
/app/ui/content/constants/effect-types.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export const FETCH_HISTORY = 'FETCH_HISTORY';
14 | export const FETCH_STARS = 'FETCH_STARS';
15 |
--------------------------------------------------------------------------------
/app/ui/content/css/content.css:
--------------------------------------------------------------------------------
1 | #content-container {
2 | width: 100%;
3 | height: 100%;
4 | }
5 |
--------------------------------------------------------------------------------
/app/ui/content/css/theme.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /* Content */
3 |
4 | --theme-content-background: #fff;
5 | --theme-content-color: #222;
6 |
7 | --theme-content-border-color: rgba(128,128,128,0.5);
8 | --theme-content-selected-border-color: #2a86e3;
9 | }
10 |
--------------------------------------------------------------------------------
/app/ui/content/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/content/favicon.ico
--------------------------------------------------------------------------------
/app/ui/content/historyrestore.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/ui/content/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/ui/content/index.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React from 'react';
14 | import ReactDOM from 'react-dom';
15 | import { Provider } from 'react-redux';
16 |
17 | import App from './views/app';
18 | import { createContentStore } from './store';
19 |
20 | const store = createContentStore();
21 |
22 | const chrome = (
23 |
24 |
25 |
26 | );
27 |
28 | const container = document.getElementById('content-container');
29 | ReactDOM.render(chrome, container);
30 |
--------------------------------------------------------------------------------
/app/ui/content/model/content-prop-types.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { PropTypes } from 'react';
14 | import ImmutablePropTypes from 'react-immutable-proptypes';
15 |
16 | import * as Model from './';
17 |
18 | export const VisitedPage = PropTypes.instanceOf(Model.VisitedPage);
19 | export const VisitedPages = ImmutablePropTypes.listOf(VisitedPage.isRequired);
20 |
21 | export const StarredItem = PropTypes.instanceOf(Model.StarredItem);
22 | export const StarredItems = ImmutablePropTypes.listOf(StarredItem.isRequired);
23 |
--------------------------------------------------------------------------------
/app/ui/content/model/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | /**
16 | * The saved data directly related to a "visited page", part of the
17 | * browser history.
18 | */
19 | export const VisitedPage = Immutable.Record({
20 | uri: null,
21 | title: null,
22 | snippet: null,
23 | }, 'VisitedPage');
24 |
25 | /**
26 | * The saved data directly related to a "starred item".
27 | */
28 | export const StarredItem = Immutable.Record({
29 | location: null,
30 | title: null,
31 | }, 'StarredItem');
32 |
33 | /**
34 | * The UI state.
35 | */
36 | export const UIState = Immutable.Record({
37 | visitedPages: Immutable.List(),
38 | starredItems: Immutable.List(),
39 | }, 'UIState');
40 |
41 | /**
42 | * Aggregate state. Keep this synchronized with ../reducers/index.js!
43 | */
44 | export const State = Immutable.Record({
45 | uiState: new UIState(),
46 | }, 'State');
47 |
--------------------------------------------------------------------------------
/app/ui/content/reducers/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import Immutable from 'immutable';
14 |
15 | import * as types from '../constants/action-types';
16 | import { State, VisitedPage, StarredItem } from '../model';
17 |
18 | const initialState = new State({
19 | visitedPages: Immutable.List(),
20 | });
21 |
22 | export default function(state = initialState, action) {
23 | switch (action.type) {
24 | case types.SHOW_HISTORY:
25 | return showHistory(state, action.visitedPages);
26 |
27 | case types.SHOW_STARS:
28 | return showStars(state, action.starredItems);
29 |
30 | default:
31 | return state;
32 | }
33 | }
34 |
35 | function showHistory(state, visitedPages) {
36 | const records = visitedPages.map(p => new VisitedPage({ uri: p.url, ...p }));
37 | return state.setIn(['uiState', 'visitedPages'], Immutable.List.of(...records));
38 | }
39 |
40 | function showStars(state, starredItems) {
41 | const records = starredItems.map(p => new StarredItem({ location: p.url, ...p }));
42 | return state.setIn(['uiState', 'starredItems'], Immutable.List.of(...records));
43 | }
44 |
--------------------------------------------------------------------------------
/app/ui/content/sagas/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { put, apply } from 'redux-saga/effects';
14 |
15 | import { infallible, takeLatestMultiple } from '../../shared/util/saga-util';
16 | import userAgentHttpClient from '../../../shared/user-agent-http-client';
17 | import * as EffectTypes from '../constants/effect-types';
18 | import * as MainActions from '../actions/main-actions';
19 |
20 | export default function*() {
21 | yield takeLatestMultiple({ infallible, logger: console },
22 | [EffectTypes.FETCH_HISTORY, fetchHistory],
23 | [EffectTypes.FETCH_STARS, fetchStars],
24 | );
25 | }
26 |
27 | export function* fetchHistory({ query, limit }) {
28 | const visitedPages = query
29 | ? yield apply(userAgentHttpClient, userAgentHttpClient.query, [{
30 | limit,
31 | text: query,
32 | snippetSize: 'large',
33 | }])
34 | : yield apply(userAgentHttpClient, userAgentHttpClient.visited, [{
35 | limit,
36 | }]);
37 |
38 | yield put(MainActions.showHistory(visitedPages.results));
39 | }
40 |
41 | export function* fetchStars({ limit }) {
42 | const starredItems = yield apply(userAgentHttpClient, userAgentHttpClient.stars, [{
43 | limit,
44 | }]);
45 |
46 | yield put(MainActions.showStars(starredItems.results));
47 | }
48 |
--------------------------------------------------------------------------------
/app/ui/content/selectors/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export function getVisitedPages(state) {
14 | return state.uiState.visitedPages;
15 | }
16 |
17 | export function getStarredItems(state) {
18 | return state.uiState.starredItems;
19 | }
20 |
--------------------------------------------------------------------------------
/app/ui/content/store/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import createSagaMiddleware from 'redux-saga';
14 | import configureStore from '../../shared/util/redux/configure-store';
15 | import rootReducer from '../reducers';
16 | import rootSaga from '../sagas';
17 | import { State } from '../model/index';
18 |
19 | export function createContentStore() {
20 | const initialState = new State(rootReducer(undefined, { type: null }));
21 | const saga = createSagaMiddleware();
22 | const store = configureStore(rootReducer, initialState, [saga]);
23 | saga.run(rootSaga);
24 | return store;
25 | }
26 |
--------------------------------------------------------------------------------
/app/ui/content/views/app.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component } from 'react';
14 | import PureRenderMixin from 'react-addons-pure-render-mixin';
15 |
16 | import { StyleUtil } from '../../shared/style';
17 | import Routes from './routes';
18 |
19 | class App extends Component {
20 | constructor(props) {
21 | super(props);
22 | this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
23 | }
24 |
25 | render() {
26 | return ;
27 | }
28 | }
29 |
30 | App.displayName = 'App';
31 |
32 | export default StyleUtil.wrap(App);
33 |
--------------------------------------------------------------------------------
/app/ui/content/views/errors/nomatch.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component } from 'react';
14 | import PureRenderMixin from 'react-addons-pure-render-mixin';
15 |
16 | import Style from '../../../shared/style';
17 |
18 | const NO_MATCH_STYLE = Style.registerStyle({
19 | flex: 1,
20 | paddingTop: '20vh',
21 | justifyContent: 'center',
22 | color: 'var(--theme-content-color)',
23 | fontSize: '500%',
24 | });
25 |
26 | class NoMatch extends Component {
27 | constructor(props) {
28 | super(props);
29 | this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
30 | }
31 |
32 | render() {
33 | return (
34 |
35 | 404
36 |
37 | );
38 | }
39 | }
40 |
41 | NoMatch.displayName = 'NoMatch';
42 |
43 | export default NoMatch;
44 |
--------------------------------------------------------------------------------
/app/ui/content/views/routes.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component } from 'react';
14 | import PureRenderMixin from 'react-addons-pure-render-mixin';
15 |
16 | import History from './history';
17 | import Stars from './stars';
18 | import NoMatch from './errors/nomatch';
19 |
20 | const VALID_COMPONENTS = {
21 | history: History,
22 | stars: Stars,
23 | };
24 |
25 | class Routes extends Component {
26 | constructor(props) {
27 | super(props);
28 | this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
29 | }
30 |
31 | render() {
32 | // TODO: We'd like to use `react-router` here, but can't yet because of
33 | // custom schemes, which aren't yet supported by the `history` library.
34 | // See https://github.com/ReactJSTraining/history/issues/311
35 | const page = document.location.hostname;
36 | if (page in VALID_COMPONENTS) {
37 | const Subpage = VALID_COMPONENTS[page];
38 | return ;
39 | }
40 | return ;
41 | }
42 | }
43 |
44 | Routes.displayName = 'Routes';
45 |
46 | export default Routes;
47 |
--------------------------------------------------------------------------------
/app/ui/preload/active-element.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { ipcRenderer as ipc } from '../../shared/electron';
14 | import { serializeNode } from '../shared/util/dom-serializers';
15 |
16 | document.addEventListener('blur', () => {
17 | ipc.sendToHost('focus-data', null);
18 | }, true);
19 |
20 | document.addEventListener('focus', () => {
21 | // We shouldn't send the element itself, only some data about it, since
22 | // app state is intended to be immutable and easily serializable.
23 | // Furthermore, we can't send the dom node itself via ipc anyway.
24 | ipc.sendToHost('focus-data', serializeNode(document.activeElement));
25 | }, true);
26 |
--------------------------------------------------------------------------------
/app/ui/preload/context-menu.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { ipcRenderer as ipc } from '../../shared/electron';
14 |
15 | function triggerMenu(data) {
16 | ipc.sendToHost('contextmenu-data', data);
17 | }
18 |
19 | ipc.on('get-contextmenu-data', (event, pos) => {
20 | const data = {
21 | x: pos.x,
22 | y: pos.y,
23 | hasSelection: !!window.getSelection().toString(),
24 | href: false,
25 | img: false,
26 | video: false,
27 | };
28 |
29 | let el = document.elementFromPoint(pos.x, pos.y);
30 | while (el && el.tagName) {
31 | if (!data.img && el.tagName === 'IMG') {
32 | data.img = el.src;
33 | }
34 | if (!data.href && el.href) {
35 | data.href = el.href;
36 | }
37 | el = el.parentNode;
38 | }
39 |
40 | triggerMenu(data);
41 | });
42 |
--------------------------------------------------------------------------------
/app/ui/preload/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import './context-menu';
14 | import './active-element';
15 | import Readability from './readability';
16 | import { readerify } from './reader';
17 | import { parseMetadata } from './metadata-parsing';
18 | import { reload } from './reload';
19 |
20 | window._readerify = readerify.bind(null, Readability);
21 | window._parseMetadata = parseMetadata;
22 | // Expose _TOFINO_RELOAD for the tofino://sessionrestore URLs that need
23 | // the webview to reload itself
24 | window._TOFINO_RELOAD = reload;
25 |
--------------------------------------------------------------------------------
/app/ui/preload/metadata-parsing.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { metadataRules, getMetadata } from 'page-metadata-parser';
14 | import tofinoRules from './metadata-rules';
15 |
16 | // Use our own rules, as well as those provided from `page-metadata-parser`.
17 | const RULES = {
18 | ...metadataRules,
19 | ...tofinoRules,
20 | };
21 |
22 | const URL_PROPERTIES = [
23 | 'icon_url',
24 | 'image_url',
25 | 'url',
26 | ];
27 |
28 | export function parseMetadata(document) {
29 | const meta = getMetadata(document, RULES);
30 |
31 | if (!meta) {
32 | return meta;
33 | }
34 |
35 | // Handle URLs that lack protocol and append appropriate
36 | // 'http:' or 'https:'
37 | for (const prop of URL_PROPERTIES) {
38 | const value = meta[prop];
39 | if (value && value.substr(0, 2) === '//') {
40 | meta[prop] = `${document.location.protocol}${value}`;
41 | }
42 | }
43 |
44 | return meta;
45 | }
46 |
--------------------------------------------------------------------------------
/app/ui/preload/reader.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export function readerify(Readability, document) {
14 | const location = document.location;
15 | const documentClone = document.cloneNode(true);
16 | const base = location.pathname.substr(0, location.pathname.lastIndexOf('/') + 1);
17 | const uri = {
18 | spec: location.href,
19 | host: location.host,
20 |
21 | // TODO This is incomplete, needs username/password and port
22 | prePath: `${location.protocol}//${location.host}`,
23 | scheme: location.protocol.substr(0, location.protocol.indexOf(':')),
24 | pathBase: `${location.protocol}//${location.host}${base}`,
25 | };
26 |
27 | const article = new Readability(uri, documentClone).parse();
28 | if (!article) {
29 | return undefined;
30 | }
31 |
32 | return {
33 | uri: location.toString(),
34 | title: article.title,
35 | content: article.content,
36 | textContent: article.textContent,
37 | length: article.length,
38 | excerpt: article.excerpt,
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/app/ui/preload/reload.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { ipcRenderer as ipc } from '../../shared/electron';
14 |
15 | export function reload() {
16 | ipc.sendToHost('reload');
17 | }
18 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/checkboard-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/checkboard-background.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/devtools/tool-profiler-active.svg:
--------------------------------------------------------------------------------
1 |
4 |
16 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/devtools/tool-profiler.svg:
--------------------------------------------------------------------------------
1 |
4 |
16 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/generic-icons/spinner-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/generic-icons/spinner-blue.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/generic-icons/spinner-gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/generic-icons/spinner-gray.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/generic-icons/warning.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
14 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/navbar/identity-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
32 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/navbar/reload-stop-go.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/navbar/reload-stop-go.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/navbar/ssl-insecure.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
39 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/navbar/ssl-secure.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
28 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/navbar/tofino-page-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/navbar/tofino-page-icon.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/navbar/toolbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/navbar/toolbar.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/tabbar/close.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/newtab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/tabbar/newtab.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/tab-background-end.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/tabbar/tab-background-end.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/tab-background-middle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/tabbar/tab-background-middle.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/tab-background-start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/tabbar/tab-background-start.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/tab-selected-end.svg:
--------------------------------------------------------------------------------
1 |
4 |
35 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/tab-selected-middle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/tabbar/tab-selected-middle.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/tab-selected-start.svg:
--------------------------------------------------------------------------------
1 |
4 |
35 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/tab-stroke-end.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/tabbar/tab-stroke-end.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/tabbar/tab-stroke-start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/tabbar/tab-stroke-start.png
--------------------------------------------------------------------------------
/app/ui/shared/assets/window/glyph-window-close.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
14 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/window/glyph-window-maximize.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
15 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/window/glyph-window-minimize.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
14 |
--------------------------------------------------------------------------------
/app/ui/shared/assets/window/osx-controls.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/assets/window/osx-controls.png
--------------------------------------------------------------------------------
/app/ui/shared/css/common.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | height: 100%;
3 | }
4 |
5 | body {
6 | margin: 0;
7 | /* Use a default system font in the entire application */
8 | font: 11px BlinkMacSystemFont, sans-serif;
9 | }
10 |
11 | div {
12 | display: flex;
13 | }
14 |
15 | [hidden] {
16 | display: none !important;
17 | }
18 |
19 | :focus {
20 | outline-style: none;
21 | }
22 |
--------------------------------------------------------------------------------
/app/ui/shared/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/app/ui/shared/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/app/ui/shared/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/app/ui/shared/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/app/ui/shared/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/app/ui/shared/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/app/ui/shared/style.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import * as ReactFreeStyle from 'react-free-style';
14 |
15 | const Style = ReactFreeStyle.create();
16 |
17 | export default Style;
18 |
19 | export const StyleUtil = {
20 | wrap: component => ReactFreeStyle.wrap(component, Style),
21 | };
22 |
--------------------------------------------------------------------------------
/app/ui/shared/util/cert.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { ipcRenderer as ipc } from '../../../shared/electron';
14 |
15 | let ID = 0;
16 | export const getCertificateError = async function(url) {
17 | const requestId = ID++;
18 | return new Promise(resolve => {
19 | ipc.on('get-certificate-error-response', function handle(_, { error, certificate, id }) {
20 | if (id === requestId) {
21 | ipc.removeListener('get-certificate-error-response', handle);
22 | resolve({ error, certificate });
23 | }
24 | });
25 | ipc.send('get-certificate-error', { url, id: requestId });
26 | });
27 | };
28 |
--------------------------------------------------------------------------------
/app/ui/shared/util/content-script-utils.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export const executeJS = function(webview, script) {
14 | return new Promise((resolve, reject) => {
15 | webview.executeJavaScript(script, false, result => {
16 | if (!result) {
17 | reject(new Error(`Could execute script ${script}.`));
18 | } else {
19 | resolve(result);
20 | }
21 | });
22 | });
23 | };
24 |
--------------------------------------------------------------------------------
/app/ui/shared/util/dom-serializers.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export function serializeNode(node) {
14 | if (!node) {
15 | return null;
16 | }
17 | return {
18 | nodeName: node.nodeName,
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/app/ui/shared/util/location-util.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export function getSearchURL(query) {
14 | // See https://dxr.mozilla.org/mozilla-central/source/browser/locales/en-US/searchplugins
15 | return `https://www.duckduckgo.com/?q=${encodeURIComponent(query)}`;
16 | }
17 |
18 | export function fixURL(typed) {
19 | if (typed.includes('://') || typed.trim().startsWith('data:')) {
20 | return typed;
21 | }
22 |
23 | if (!typed.includes(' ') && typed.includes('.')) {
24 | return `http://${typed}`;
25 | }
26 |
27 | return getSearchURL(typed);
28 | }
29 |
--------------------------------------------------------------------------------
/app/ui/shared/util/redux/configure-store.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import { applyMiddleware, createStore } from 'redux';
14 | import createLogger from 'redux-logger';
15 | import thunk from './middleware/thunk';
16 | import history from './middleware/history';
17 | import BUILD_CONFIG from '../../../../build-config';
18 |
19 | // In webpacked environments, a `process.env.TEST` global will be created,
20 | // with the value set to the current `TEST` flag on the environment variables.
21 | /* eslint-disable no-undef */
22 | const TEST = process.env.TEST;
23 | /* eslint-enable no-undef */
24 |
25 | export default function(rootReducer, initialState, customMiddleware = []) {
26 | const middleware = [thunk, ...customMiddleware];
27 | const historyStore = [];
28 |
29 | if (BUILD_CONFIG.development && !TEST) {
30 | middleware.unshift(createLogger({
31 | duration: true,
32 | collapsed: true,
33 | predicate: (getState, action) => typeof action !== 'function',
34 | stateTransformer: state => state.toJS(),
35 | }));
36 | }
37 |
38 | if (TEST) {
39 | middleware.unshift(history(historyStore));
40 | }
41 |
42 | const store = createStore(rootReducer, initialState, applyMiddleware(...middleware));
43 |
44 | // Store action history on the exposed store for tests.
45 | if (TEST) {
46 | store.history = historyStore;
47 | }
48 |
49 | return store;
50 | }
51 |
--------------------------------------------------------------------------------
/app/ui/shared/util/redux/middleware/history.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | export default historyStore => _store => next => action => {
14 | if (typeof action !== 'function') {
15 | historyStore.push(action);
16 | }
17 |
18 | return next(action);
19 | };
20 |
--------------------------------------------------------------------------------
/app/ui/shared/util/redux/middleware/thunk.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | /**
14 | * A middleware that allows thunks (functions) to be dispatched.
15 | * If it's a thunk, it is called with `dispatch` and `getState`,
16 | * allowing the action to create multiple actions (most likely
17 | * asynchronously).
18 | */
19 | function thunk({ dispatch, getState }) {
20 | return next => action => {
21 | if (typeof action === 'function') {
22 | return action(dispatch, getState);
23 | }
24 |
25 | return next(action);
26 | };
27 | }
28 |
29 | export default thunk;
30 |
--------------------------------------------------------------------------------
/app/ui/shared/widgets/icon-globe.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component, PropTypes } from 'react';
14 | import * as ComponentUtil from '../util/component-util';
15 |
16 | import FittedImage from './fitted-image';
17 |
18 | class GlobeIcon extends Component {
19 | constructor(props) {
20 | super(props);
21 | this.shouldComponentUpdate = ComponentUtil.shouldPlainJsPropsComponentUpdate.bind(this);
22 | }
23 |
24 | render() {
25 | return (
26 |
32 | );
33 | }
34 | }
35 |
36 | GlobeIcon.displayName = 'GlobeIcon';
37 |
38 | GlobeIcon.propTypes = {
39 | className: PropTypes.string,
40 | };
41 |
42 | export default GlobeIcon;
43 |
--------------------------------------------------------------------------------
/app/ui/shared/widgets/icon-warning.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component, PropTypes } from 'react';
14 | import * as ComponentUtil from '../util/component-util';
15 |
16 | import FittedImage from './fitted-image';
17 |
18 | class WarningIcon extends Component {
19 | constructor(props) {
20 | super(props);
21 | this.shouldComponentUpdate = ComponentUtil.shouldPlainJsPropsComponentUpdate.bind(this);
22 | }
23 |
24 | render() {
25 | return (
26 |
32 | );
33 | }
34 | }
35 |
36 | WarningIcon.displayName = 'WarningIcon';
37 |
38 | WarningIcon.propTypes = {
39 | className: PropTypes.string,
40 | };
41 |
42 | export default WarningIcon;
43 |
--------------------------------------------------------------------------------
/app/ui/shared/widgets/list.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component, PropTypes } from 'react';
14 | import omit from 'lodash/omit';
15 | import * as ComponentUtil from '../util/component-util';
16 |
17 | import Style from '../style';
18 |
19 | const LIST_STYLE = Style.registerStyle({
20 | display: 'flex',
21 | flexDirection: 'column',
22 | listStyleType: 'none',
23 | margin: 0,
24 | padding: 0,
25 | });
26 |
27 | class List extends Component {
28 | constructor(props) {
29 | super(props);
30 | this.shouldComponentUpdate = ComponentUtil.shouldPlainJsPropsComponentUpdate.bind(this);
31 | }
32 |
33 | render() {
34 | const childrenArray = React.Children.toArray(this.props.children);
35 | const childrenView = this.props.reversed ? childrenArray.reverse() : childrenArray;
36 | return (
37 |
39 | {childrenView}
40 |
41 | );
42 | }
43 | }
44 |
45 | List.displayName = 'List';
46 |
47 | const OmittedContainerProps = {
48 | reversed: PropTypes.bool,
49 | };
50 |
51 | List.propTypes = {
52 | ...OmittedContainerProps,
53 | className: PropTypes.string,
54 | children: PropTypes.oneOfType([
55 | PropTypes.arrayOf(PropTypes.node),
56 | PropTypes.node,
57 | ]),
58 | };
59 |
60 | export default List;
61 |
--------------------------------------------------------------------------------
/app/ui/shared/widgets/overview/cards/overview-card.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component, PropTypes } from 'react';
14 | import PureRenderMixin from 'react-addons-pure-render-mixin';
15 |
16 | /**
17 | * A factory class used to instantiate Cards displayed in the overview.
18 | * Calls the appropriate underlying card subclass, depending on metadata.
19 | */
20 | import SimpleCard from './simple-card';
21 | import ProductCard from './product-card';
22 |
23 | class OverviewCard extends Component {
24 | constructor(props) {
25 | super(props);
26 | this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
27 | }
28 |
29 | render() {
30 | const meta = this.props.page.meta;
31 |
32 | if (meta.price ||
33 | (meta.rating && parseFloat(meta.rating) > 0)) {
34 | return ();
35 | }
36 |
37 | return ();
38 | }
39 | }
40 |
41 | OverviewCard.displayName = 'OverviewCard';
42 |
43 | OverviewCard.propTypes = {
44 | // FIXME: Don't use object prop types for this component.
45 | page: PropTypes.object.isRequired, // eslint-disable-line
46 | };
47 |
48 | export default OverviewCard;
49 |
--------------------------------------------------------------------------------
/app/ui/shared/widgets/overview/cards/simple-card.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component, PropTypes } from 'react';
14 | import PureRenderMixin from 'react-addons-pure-render-mixin';
15 |
16 | import BaseCard from './base-card';
17 | import SimpleSummary from '../summaries/simple-summary';
18 | import { prettyUrl } from '../../../util/url-util';
19 |
20 | class SimpleCard extends Component {
21 | constructor(props) {
22 | super(props);
23 | this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
24 | }
25 |
26 | render() {
27 | const meta = this.props.page.meta;
28 | const title = meta.title || this.props.page.title;
29 | const url = prettyUrl(this.props.page.location);
30 |
31 | return (
32 |
33 |
35 |
36 | );
37 | }
38 | }
39 |
40 | SimpleCard.displayName = 'SimpleCard';
41 |
42 | SimpleCard.propTypes = {
43 | // FIXME: Don't use object prop types for this component.
44 | page: PropTypes.object.isRequired, // eslint-disable-line
45 | };
46 |
47 | export default SimpleCard;
48 |
--------------------------------------------------------------------------------
/app/ui/shared/widgets/overview/summaries/star.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component, PropTypes } from 'react';
14 | import PureRenderMixin from 'react-addons-pure-render-mixin';
15 |
16 | import Btn from '../../../../shared/widgets/btn';
17 |
18 | const STAR_IMAGES = {
19 | full: 'glyph-ratings-full.svg',
20 | half: 'glyph-ratings-half.svg',
21 | empty: 'glyph-ratings-empty.svg',
22 | };
23 |
24 | class Star extends Component {
25 | constructor(props) {
26 | super(props);
27 | this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
28 | }
29 |
30 | handleClick = () => {
31 | }
32 |
33 | render() {
34 | const image = STAR_IMAGES[this.props.type];
35 | return (
36 |
42 | );
43 | }
44 | }
45 |
46 | Star.displayName = 'Star';
47 |
48 | Star.propTypes = {
49 | title: PropTypes.string.isRequired,
50 | type: PropTypes.string.isRequired,
51 | };
52 |
53 | export default Star;
54 |
--------------------------------------------------------------------------------
/app/ui/shared/widgets/spinner-blue.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component, PropTypes } from 'react';
14 | import * as ComponentUtil from '../util/component-util';
15 |
16 | import Style from '../style';
17 | import FittedImage from './fitted-image';
18 |
19 | const SPIN_KEYFRAMES = Style.registerKeyframes({
20 | from: {
21 | transform: 'rotate(0deg)',
22 | },
23 | to: {
24 | transform: 'rotate(360deg)',
25 | },
26 | });
27 |
28 | const SPINNER_STYLE = Style.registerStyle({
29 | animation: `${SPIN_KEYFRAMES} 1s linear infinite`,
30 | });
31 |
32 | class SpinnerBlue extends Component {
33 | constructor(props) {
34 | super(props);
35 | this.shouldComponentUpdate = ComponentUtil.shouldPlainJsPropsComponentUpdate.bind(this);
36 | }
37 |
38 | render() {
39 | return (
40 |
46 | );
47 | }
48 | }
49 |
50 | SpinnerBlue.displayName = 'SpinnerBlue';
51 |
52 | SpinnerBlue.propTypes = {
53 | className: PropTypes.string,
54 | };
55 |
56 | export default SpinnerBlue;
57 |
--------------------------------------------------------------------------------
/app/ui/shared/widgets/spinner-gray.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component, PropTypes } from 'react';
14 | import * as ComponentUtil from '../util/component-util';
15 |
16 | import Style from '../style';
17 | import FittedImage from './fitted-image';
18 |
19 | const SPIN_KEYFRAMES = Style.registerKeyframes({
20 | from: {
21 | transform: 'rotate(0deg)',
22 | },
23 | to: {
24 | transform: 'rotate(360deg)',
25 | },
26 | });
27 |
28 | const SPINNER_STYLE = Style.registerStyle({
29 | animation: `${SPIN_KEYFRAMES} 1s linear infinite reverse`,
30 | });
31 |
32 | class SpinnerGray extends Component {
33 | constructor(props) {
34 | super(props);
35 | this.shouldComponentUpdate = ComponentUtil.shouldPlainJsPropsComponentUpdate.bind(this);
36 | }
37 |
38 | render() {
39 | return (
40 |
46 | );
47 | }
48 | }
49 |
50 | SpinnerGray.displayName = 'SpinnerGray';
51 |
52 | SpinnerGray.propTypes = {
53 | className: PropTypes.string,
54 | };
55 |
56 | export default SpinnerGray;
57 |
--------------------------------------------------------------------------------
/app/ui/shared/widgets/vertical-separator.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { Component, PropTypes } from 'react';
14 | import * as ComponentUtil from '../util/component-util';
15 |
16 | import Style from '../style';
17 |
18 | const VERTICAL_SEPARATOR_STYLE = Style.registerStyle({
19 | alignSelf: 'stretch',
20 | flexShrink: 0,
21 | width: '1px',
22 | margin: '3px 0',
23 | backgroundColor: 'var(--theme-separator-color)',
24 | });
25 |
26 | class VerticalSeparator extends Component {
27 | constructor(props) {
28 | super(props);
29 | this.shouldComponentUpdate = ComponentUtil.shouldPlainJsPropsComponentUpdate.bind(this);
30 | }
31 |
32 | render() {
33 | return (
34 |
36 | );
37 | }
38 | }
39 |
40 | VerticalSeparator.displayName = 'VerticalSeparator';
41 |
42 | VerticalSeparator.propTypes = {
43 | className: PropTypes.string,
44 | };
45 |
46 | export default VerticalSeparator;
47 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | platform:
2 | - x86
3 |
4 | os: Previous Visual Studio 2015
5 |
6 | environment:
7 | nodejs_version: "6.1"
8 |
9 | skip_commits:
10 | message: /\[ci skip\]/
11 |
12 | branches:
13 | except:
14 | - /^greenkeeper-.*$/
15 |
16 | pull_requests:
17 | do_not_increment_build_number: true
18 |
19 | cache:
20 | - node_modules
21 |
22 | install:
23 | - ps: Install-Product node $env:nodejs_version $env:PLATFORM
24 | - node --version
25 | - npm --version
26 | - set npm_config_arch=%PLATFORM:x86=ia32%
27 | - npm prune
28 | - npm install --progress false --depth 0
29 | - npm install --progress false --depth 0
30 | - cd app
31 | - npm dedupe
32 | - cd ..
33 |
34 | build: off
35 |
36 | test_script:
37 | - npm run test-ci
38 | - npm run package
39 |
40 | before_deploy:
41 | - ps: Get-ChildItem dist\RELEASES | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
42 | - ps: Get-ChildItem dist\*.nupkg | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
43 | - ps: Get-ChildItem dist\*.exe | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
44 | - ps: Get-ChildItem dist\*.zip | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
45 |
46 | deploy:
47 | - provider: S3
48 | access_key_id:
49 | secure: xsHB6zN4IRGJy9uUocU3+6/nZPa408ARYut11Wg30CA=
50 | secret_access_key:
51 | secure: 8L4sC5l97dY13Jnv/6Gd8Fe//FpnOuMQWu7st2LNLRhX4LjQ9uSLfObqRT0HsBqw
52 | bucket:
53 | secure: a/ijSslVXIxT1KRgwK6oWBJiOYD2DS5KCC5JpEDtXaU=
54 | set_public: true
55 | folder: mozilla/tofino/builds/$(appveyor_repo_branch)
56 | artifact: /^.*\.(zip|exe)$/
57 | - provider: GitHub
58 | description: 'Draft release'
59 | draft: true
60 | auth_token:
61 | secure: hJqkl2Amid9oaQZO9z0jedpQ3lNObygSTGPHDqOE+EEtnqQa0DkRDVJ3/i8i1YYg
62 | artifact: /^(RELEASES|.*\.(nupkg|exe))$/
63 | force_update: true
64 | on:
65 | appveyor_repo_tag: true
66 |
--------------------------------------------------------------------------------
/branding/app-icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/app-icon.icns
--------------------------------------------------------------------------------
/branding/app-icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/app-icon.ico
--------------------------------------------------------------------------------
/branding/iconset/tofino-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-128x128.png
--------------------------------------------------------------------------------
/branding/iconset/tofino-128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-128x128@2x.png
--------------------------------------------------------------------------------
/branding/iconset/tofino-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-16x16.png
--------------------------------------------------------------------------------
/branding/iconset/tofino-16x16@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-16x16@2x.png
--------------------------------------------------------------------------------
/branding/iconset/tofino-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-256x256.png
--------------------------------------------------------------------------------
/branding/iconset/tofino-256x256@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-256x256@2x.png
--------------------------------------------------------------------------------
/branding/iconset/tofino-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-32x32.png
--------------------------------------------------------------------------------
/branding/iconset/tofino-32x32@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-32x32@2x.png
--------------------------------------------------------------------------------
/branding/iconset/tofino-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-512x512.png
--------------------------------------------------------------------------------
/branding/iconset/tofino-512x512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/branding/iconset/tofino-512x512@2x.png
--------------------------------------------------------------------------------
/build/config/frontends.json:
--------------------------------------------------------------------------------
1 | [
2 | "browser-modern",
3 | "browser-alt"
4 | ]
5 |
--------------------------------------------------------------------------------
/build/config/webpack.base.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import webpack from 'webpack';
5 | import path from 'path';
6 | import devConfig from './webpack.base.snippets.dev';
7 | import prodConfig from './webpack.base.snippets.prod';
8 | import * as Const from '../utils/const';
9 |
10 | const root = Const.ROOT;
11 |
12 | export default {
13 | output: {
14 | },
15 | module: {
16 | loaders: [{
17 | test: /\.jsx?$/,
18 | include: [
19 | path.join(root, 'app'),
20 | ],
21 | exclude: [
22 | path.join(root, 'node_modules'),
23 | path.join(root, 'app', 'node_modules'),
24 | ],
25 | loader: 'babel-loader',
26 | }, {
27 | test: /\.json$/,
28 | loader: 'json',
29 | }],
30 | },
31 | resolve: {
32 | root,
33 | extensions: ['', '.js', '.jsx', '.json'],
34 | alias: {
35 | 'dtrace-provider': path.join(Const.BUILD_UTILS_PATH, 'empty_module.js'),
36 | 'app/shared/environment': path.join(Const.BUILD_UTILS_PATH, 'empty_module.js'),
37 | },
38 | },
39 | plugins: [
40 | new webpack.NoErrorsPlugin(),
41 | new webpack.DefinePlugin({
42 | 'process.env.TEST': process.env.TEST,
43 | }),
44 | ],
45 | externals: [
46 | ],
47 | };
48 |
49 | export const makeDevConfig = baseConfig => ({
50 | ...devConfig,
51 | ...baseConfig,
52 | output: {
53 | ...devConfig.output,
54 | ...baseConfig.output,
55 | },
56 | plugins: [
57 | ...devConfig.plugins,
58 | ...baseConfig.plugins,
59 | ],
60 | });
61 |
62 | export const makeProdConfig = baseConfig => ({
63 | ...prodConfig,
64 | ...baseConfig,
65 | plugins: [
66 | ...prodConfig.plugins,
67 | ...baseConfig.plugins,
68 | ],
69 | });
70 |
--------------------------------------------------------------------------------
/build/config/webpack.base.snippets.dev.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import webpack from 'webpack';
5 |
6 | export default {
7 | output: {
8 | pathinfo: true,
9 | },
10 | devtool: 'eval',
11 | plugins: [
12 | new webpack.DefinePlugin({
13 | 'process.env.NODE_ENV': '"development"',
14 | }),
15 | ],
16 | };
17 |
--------------------------------------------------------------------------------
/build/config/webpack.base.snippets.prod.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import webpack from 'webpack';
5 |
6 | export default {
7 | devtool: 'source-map',
8 | plugins: [
9 | new webpack.DefinePlugin({
10 | 'process.env.NODE_ENV': '"production"',
11 | }),
12 | // @TODO https://github.com/mozilla/tofino/issues/742
13 | // new webpack.optimize.UglifyJsPlugin({
14 | // compress: {
15 | // warnings: false,
16 | // },
17 | // }),
18 | ],
19 | };
20 |
--------------------------------------------------------------------------------
/build/config/webpack.base.snippets.ui-shared.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import path from 'path';
5 | import CopyWebpackPlugin from 'copy-webpack-plugin';
6 |
7 | export const uiFiles = (srcDir, dstDir) => ([
8 | new CopyWebpackPlugin([{
9 | from: path.join(srcDir, '*.html'),
10 | to: dstDir,
11 | flatten: true,
12 | }]),
13 | new CopyWebpackPlugin([{
14 | from: path.join(srcDir, 'css', '*.css'),
15 | to: path.join(dstDir, 'css'),
16 | flatten: true,
17 | }]),
18 | new CopyWebpackPlugin([{
19 | from: path.join(srcDir, 'scripts', '*.js'),
20 | to: path.join(dstDir, 'scripts'),
21 | flatten: true,
22 | }]),
23 | new CopyWebpackPlugin([{
24 | from: path.join(srcDir, '*.ico'),
25 | to: path.join(dstDir),
26 | flatten: true,
27 | }]),
28 | ]);
29 |
30 | export const sharedFiles = (sharedDir, dstDir) => ([
31 | new CopyWebpackPlugin([{
32 | from: path.join(sharedDir, 'css', '*.css'),
33 | to: path.join(dstDir, 'css'),
34 | flatten: true,
35 | }]),
36 | new CopyWebpackPlugin([{
37 | from: path.join(sharedDir, 'assets'),
38 | to: path.join(dstDir, 'assets'),
39 | flatten: true,
40 | }]),
41 | new CopyWebpackPlugin([{
42 | from: path.join(sharedDir, 'fonts'),
43 | to: path.join(dstDir, 'fonts'),
44 | flatten: true,
45 | }]),
46 | ]);
47 |
--------------------------------------------------------------------------------
/build/config/webpack.browser-alt.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import path from 'path';
5 | import webpack from 'webpack';
6 | import defaultConfig from './webpack.base';
7 | import { uiFiles, sharedFiles } from './webpack.base.snippets.ui-shared';
8 | import * as Const from '../utils/const';
9 |
10 | export const SHARED_DIR = path.join(Const.SRC_DIR, 'ui', 'shared');
11 | export const SRC_DIR = path.join(Const.SRC_DIR, 'ui', 'browser-alt');
12 | export const DST_DIR = path.join(Const.LIB_DIR, 'ui', 'browser-alt');
13 |
14 | export default {
15 | ...defaultConfig,
16 | entry: path.join(SRC_DIR, 'index.js'),
17 | output: {
18 | ...defaultConfig.output,
19 | path: DST_DIR,
20 | filename: 'index.js',
21 | sourceMapFilename: 'index.map',
22 | },
23 | plugins: [
24 | ...defaultConfig.plugins,
25 | ...uiFiles(SRC_DIR, DST_DIR),
26 | ...sharedFiles(SHARED_DIR, DST_DIR),
27 | new webpack.DefinePlugin({
28 | PROCESS_TYPE: '"ui"',
29 | }),
30 | ],
31 | target: 'electron-renderer',
32 | };
33 |
--------------------------------------------------------------------------------
/build/config/webpack.browser-modern.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import path from 'path';
5 | import webpack from 'webpack';
6 | import defaultConfig from './webpack.base';
7 | import { uiFiles, sharedFiles } from './webpack.base.snippets.ui-shared';
8 | import * as Const from '../utils/const';
9 |
10 | export const SHARED_DIR = path.join(Const.SRC_DIR, 'ui', 'shared');
11 | export const SRC_DIR = path.join(Const.SRC_DIR, 'ui', 'browser-modern');
12 | export const DST_DIR = path.join(Const.LIB_DIR, 'ui', 'browser-modern');
13 |
14 | export default {
15 | ...defaultConfig,
16 | entry: path.join(SRC_DIR, 'index.js'),
17 | output: {
18 | ...defaultConfig.output,
19 | path: DST_DIR,
20 | filename: 'index.js',
21 | sourceMapFilename: 'index.map',
22 | },
23 | plugins: [
24 | ...defaultConfig.plugins,
25 | ...uiFiles(SRC_DIR, DST_DIR),
26 | ...sharedFiles(SHARED_DIR, DST_DIR),
27 | new webpack.DefinePlugin({
28 | PROCESS_TYPE: '"ui"',
29 | }),
30 | ],
31 | target: 'electron-renderer',
32 | };
33 |
--------------------------------------------------------------------------------
/build/config/webpack.content.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import path from 'path';
5 | import webpack from 'webpack';
6 | import defaultConfig from './webpack.base';
7 | import { uiFiles, sharedFiles } from './webpack.base.snippets.ui-shared';
8 | import * as Const from '../utils/const';
9 |
10 | export const SHARED_DIR = path.join(Const.SRC_DIR, 'ui', 'shared');
11 | export const SRC_DIR = path.join(Const.SRC_DIR, 'ui', 'content');
12 | export const DST_DIR = path.join(Const.LIB_DIR, 'ui', 'content');
13 |
14 | export default {
15 | ...defaultConfig,
16 | entry: path.join(SRC_DIR, 'index.jsx'),
17 | output: {
18 | ...defaultConfig.output,
19 | path: DST_DIR,
20 | filename: 'index.js',
21 | sourceMapFilename: 'index.map',
22 | },
23 | plugins: [
24 | ...defaultConfig.plugins,
25 | ...uiFiles(SRC_DIR, DST_DIR),
26 | ...sharedFiles(SHARED_DIR, DST_DIR),
27 | new webpack.DefinePlugin({
28 | PROCESS_TYPE: '"content"',
29 | }),
30 | ],
31 | target: 'web',
32 | };
33 |
--------------------------------------------------------------------------------
/build/config/webpack.main.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import webpack from 'webpack';
5 | import path from 'path';
6 | import defaultConfig from './webpack.base';
7 | import * as Const from '../utils/const';
8 | import { nodeExternals } from '../utils/webpack';
9 |
10 | export const SRC_DIR = path.join(Const.SRC_DIR, 'main');
11 | export const DST_DIR = path.join(Const.LIB_DIR, 'main');
12 |
13 | export default {
14 | ...defaultConfig,
15 | entry: path.join(SRC_DIR, 'index.js'),
16 | output: {
17 | ...defaultConfig.output,
18 | path: DST_DIR,
19 | filename: 'index.js',
20 | sourceMapFilename: 'index.map',
21 | libraryTarget: 'commonjs',
22 | },
23 | target: 'electron',
24 | plugins: [
25 | ...defaultConfig.plugins,
26 | new webpack.DefinePlugin({
27 | PROCESS_TYPE: '"main"',
28 | }),
29 | new webpack.DefinePlugin({
30 | LIBDIR: 'require("path").join(__dirname, "..")',
31 | }),
32 | ],
33 | resolve: {
34 | ...defaultConfig.resolve,
35 | alias: {
36 | ...defaultConfig.resolve.alias,
37 | 'app/shared/environment': path.join(Const.SRC_DIR, 'shared', 'environment.js'),
38 | },
39 | },
40 | externals: [
41 | ...defaultConfig.externals,
42 | nodeExternals,
43 | ],
44 | };
45 |
--------------------------------------------------------------------------------
/build/config/webpack.preload.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import path from 'path';
5 | import webpack from 'webpack';
6 | import defaultConfig from './webpack.base';
7 | import * as Const from '../utils/const';
8 |
9 | export const SRC_DIR = path.join(Const.SRC_DIR, 'ui', 'preload');
10 | export const DST_DIR = path.join(Const.LIB_DIR, 'ui', 'preload');
11 |
12 | export default {
13 | ...defaultConfig,
14 | entry: path.join(SRC_DIR, 'index.js'),
15 | output: {
16 | path: DST_DIR,
17 | filename: 'index.js',
18 | sourceMapFilename: 'index.map',
19 | },
20 | devtool: 'cheap-module-source-map',
21 | plugins: [
22 | ...defaultConfig.plugins,
23 | new webpack.DefinePlugin({
24 | PROCESS_TYPE: '"preload"',
25 | }),
26 | ],
27 | target: 'electron-renderer',
28 | };
29 |
--------------------------------------------------------------------------------
/build/config/webpack.services.content.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import webpack from 'webpack';
5 | import path from 'path';
6 | import defaultConfig from './webpack.base';
7 | import * as Const from '../utils/const';
8 | import { nodeExternals } from '../utils/webpack';
9 |
10 | export const SRC_DIR = path.join(Const.SRC_DIR, 'services', 'content-service');
11 | export const DST_DIR = path.join(Const.LIB_DIR, 'services', 'content-service');
12 |
13 | export default {
14 | ...defaultConfig,
15 | entry: path.join(SRC_DIR, 'index.js'),
16 | output: {
17 | ...defaultConfig.output,
18 | path: DST_DIR,
19 | filename: 'index.js',
20 | sourceMapFilename: 'index.map',
21 | libraryTarget: 'commonjs',
22 | },
23 | target: 'node',
24 | plugins: [
25 | ...defaultConfig.plugins,
26 | new webpack.DefinePlugin({
27 | PROCESS_TYPE: '"content-service"',
28 | }),
29 | new webpack.DefinePlugin({
30 | LIBDIR: 'require("path").join(__dirname, "..", "..")',
31 | }),
32 | ],
33 | resolve: {
34 | ...defaultConfig.resolve,
35 | alias: {
36 | ...defaultConfig.resolve.alias,
37 | 'app/shared/environment': path.join(Const.SRC_DIR, 'shared', 'environment.js'),
38 | },
39 | },
40 | externals: [
41 | ...defaultConfig.externals,
42 | nodeExternals,
43 | ],
44 | };
45 |
--------------------------------------------------------------------------------
/build/logging.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016 Mozilla
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5 | this file except in compliance with the License. You may obtain a copy of the
6 | License at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software distributed
8 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 | specific language governing permissions and limitations under the License.
11 | */
12 |
13 | import bunyan from 'bunyan';
14 | import { pipeToStream } from '../app/shared/logging';
15 |
16 | export const logger = bunyan.createLogger({
17 | name: 'build',
18 | streams: [
19 | pipeToStream(process.stdout, 'debug'),
20 | ],
21 | });
22 |
--------------------------------------------------------------------------------
/build/main.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | /**
5 | * Disable the eslint "strict" and "no-commonjs" rules, since this is a script
6 | * that runs in node without any babel support, so it's not not a module
7 | * implicitly running in strict mode, and we can't use the import syntax.
8 | */
9 | /* eslint-disable strict */
10 | /* eslint-disable import/no-commonjs */
11 |
12 | 'use strict';
13 |
14 | require('babel-polyfill');
15 | require('babel-register')();
16 |
17 | const Tasks = require('./tasks');
18 | const Runtime = require('./utils/runtime');
19 | const { logger } = require('./logging');
20 |
21 | const handleTaskFailed = err => {
22 | logger.error('Build failed.');
23 | logger.error(err);
24 | process.exit(1);
25 | };
26 |
27 | const handleDepsCheckFailed = result => {
28 | logger.error('Dependency checks failed.');
29 | result.error.forEach(err => logger.error(err));
30 | process.exit(1);
31 | };
32 |
33 | const handleDepsCheckSucceeded = () => {
34 | Tasks.run().then(null, handleTaskFailed);
35 | };
36 |
37 | // Only auto-run `checkDependencies` if this is *not* imported as a module.
38 | // If `require.main` is `module`, then this is ran as a script.
39 | if (require.main === module) {
40 | Runtime.checkNodeVersion(process.version);
41 | Runtime.checkDependencies().then(handleDepsCheckSucceeded, handleDepsCheckFailed);
42 | }
43 |
--------------------------------------------------------------------------------
/build/task-build-browser.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import colors from 'colors/safe';
5 | import fs from 'fs-promise';
6 | import path from 'path';
7 |
8 | import { BUILD_WEBPACK_CONFIGS_PATH, BROWSER_FRONTENDS_PATH } from './utils/const';
9 | import { shouldRebuild } from './utils/rebuild';
10 | import { webpackBuild } from './utils/webpack';
11 | import { logger } from './logging';
12 |
13 | export default async function(options) {
14 | const frontends = fs.readJsonSync(BROWSER_FRONTENDS_PATH);
15 | const builders = [];
16 |
17 | for (const id of frontends) {
18 | builders.push(await buildFrontend(id, options));
19 | }
20 |
21 | return {
22 | close: () => Promise.all(builders.map(w => w.close())),
23 | };
24 | }
25 |
26 | async function buildFrontend(id, options) {
27 | const configPath = path.resolve(BUILD_WEBPACK_CONFIGS_PATH, `webpack.${id}`);
28 | const { SRC_DIR, SHARED_DIR } = require(configPath); // eslint-disable-line
29 |
30 | if (!(await shouldRebuild(id, SRC_DIR, SHARED_DIR))) {
31 | logger.info(colors.green(`No changes in ${id}.`));
32 | return { close: () => {} };
33 | }
34 |
35 | logger.info(colors.cyan(`Building ${id}...`));
36 | return await webpackBuild(configPath, options);
37 | }
38 |
--------------------------------------------------------------------------------
/build/task-build-content.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import colors from 'colors/safe';
5 | import path from 'path';
6 |
7 | import { BUILD_WEBPACK_CONFIGS_PATH } from './utils/const';
8 | import { shouldRebuild } from './utils/rebuild';
9 | import { webpackBuild } from './utils/webpack';
10 | import { logger } from './logging';
11 |
12 | export default async function(options) {
13 | const id = 'content';
14 | const configPath = path.resolve(BUILD_WEBPACK_CONFIGS_PATH, 'webpack.content');
15 | const { SRC_DIR, SHARED_DIR } = require(configPath); // eslint-disable-line
16 |
17 | if (!(await shouldRebuild(id, SRC_DIR, SHARED_DIR))) {
18 | logger.info(colors.green(`No changes in ${id}.`));
19 | return { close: () => {} };
20 | }
21 |
22 | logger.info(colors.cyan(`Building ${id}...`));
23 | return await webpackBuild(configPath, options);
24 | }
25 |
--------------------------------------------------------------------------------
/build/task-build-deps.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import path from 'path';
5 | import fs from 'fs-promise';
6 | import os from 'os';
7 |
8 | import download from 'electron-download';
9 | import unzip from 'extract-zip';
10 | import { thenify } from 'thenify-all';
11 |
12 | import * as BuildUtils from './utils';
13 | import * as ElectronUtils from './utils/electron';
14 |
15 | async function downloadElectron() {
16 | const tmpDir = path.join(os.tmpdir(), 'tofino-tmp');
17 | await fs.mkdirs(tmpDir);
18 |
19 | try {
20 | const zipPath = await thenify(download)(ElectronUtils.getDownloadOptions());
21 | await thenify(unzip)(zipPath, { dir: tmpDir });
22 |
23 | // Some tools like electron-rebuild rely on this to find the executable
24 | await fs.writeFile(path.join(tmpDir, 'path.txt'), ElectronUtils.getOSElectronExecutable());
25 |
26 | const targetDir = ElectronUtils.getElectronRoot();
27 | await fs.remove(targetDir);
28 | await fs.move(tmpDir, targetDir);
29 | } finally {
30 | if (await fs.exists(tmpDir)) {
31 | fs.remove(tmpDir);
32 | }
33 | }
34 | }
35 |
36 | export default async function() {
37 | let currentElectronVersion = null;
38 | try {
39 | currentElectronVersion = ElectronUtils.getElectronVersion();
40 | } catch (e) {
41 | // Fall through and download
42 | }
43 |
44 | const electron = BuildUtils.getManifest()._electron;
45 | if (electron.version !== currentElectronVersion) {
46 | await downloadElectron();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/build/task-build-main-process.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import colors from 'colors/safe';
5 | import path from 'path';
6 |
7 | import { BUILD_WEBPACK_CONFIGS_PATH } from './utils/const';
8 | import { shouldRebuild } from './utils/rebuild';
9 | import { webpackBuild } from './utils/webpack';
10 | import { logger } from './logging';
11 |
12 | export default async function(options) {
13 | const id = 'main process';
14 | const configPath = path.resolve(BUILD_WEBPACK_CONFIGS_PATH, 'webpack.main');
15 | const { SRC_DIR } = require(configPath); // eslint-disable-line
16 |
17 | if (!(await shouldRebuild(id, SRC_DIR))) {
18 | logger.info(colors.green(`No changes in ${id}.`));
19 | return { close: () => {} };
20 | }
21 |
22 | logger.info(colors.cyan(`Building ${id}...`));
23 | return await webpackBuild(configPath, options);
24 | }
25 |
--------------------------------------------------------------------------------
/build/task-build-modules.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import path from 'path';
5 | import fs from 'fs-promise';
6 | import colors from 'colors/safe';
7 |
8 | import { SRC_DIR, LIB_DIR, BUILD_CONFIG_PATH } from './utils/const';
9 | import { logger } from './logging';
10 |
11 | function copy(src) {
12 | return fs.copy(src, path.join(LIB_DIR, path.basename(src)));
13 | }
14 |
15 | export default async function() {
16 | logger.info(colors.cyan('Building node environment...'));
17 |
18 | // copy node
19 | await copy(process.execPath);
20 | // copy package.json
21 | await copy(path.join(SRC_DIR, 'package.json'));
22 | // copy build-config.json
23 | await copy(BUILD_CONFIG_PATH);
24 | // copy node_modules
25 | await copy(path.join(SRC_DIR, 'node_modules'));
26 |
27 | return { close: () => {} };
28 | }
29 |
--------------------------------------------------------------------------------
/build/task-build-preload.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import colors from 'colors/safe';
5 | import path from 'path';
6 |
7 | import { BUILD_WEBPACK_CONFIGS_PATH } from './utils/const';
8 | import { shouldRebuild } from './utils/rebuild';
9 | import { webpackBuild } from './utils/webpack';
10 | import { logger } from './logging';
11 |
12 | export default async function(options) {
13 | const id = 'preload';
14 | const configPath = path.resolve(BUILD_WEBPACK_CONFIGS_PATH, 'webpack.preload');
15 | const { SRC_DIR } = require(configPath); // eslint-disable-line
16 |
17 | if (!(await shouldRebuild(id, SRC_DIR))) {
18 | logger.info(colors.green(`No changes in ${id}.`));
19 | return { close: () => {} };
20 | }
21 |
22 | logger.info(colors.cyan(`Building ${id}...`));
23 | return await webpackBuild(configPath, options);
24 | }
25 |
--------------------------------------------------------------------------------
/build/task-build-service-content.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import colors from 'colors/safe';
5 | import path from 'path';
6 |
7 | import { BUILD_WEBPACK_CONFIGS_PATH } from './utils/const';
8 | import { shouldRebuild } from './utils/rebuild';
9 | import { webpackBuild } from './utils/webpack';
10 | import { logger } from './logging';
11 |
12 | export default async function(options = {}) {
13 | const id = 'content service';
14 | const configPath = path.resolve(BUILD_WEBPACK_CONFIGS_PATH, 'webpack.services.content');
15 | const { SRC_DIR } = require(configPath); // eslint-disable-line
16 |
17 | if (!(await shouldRebuild(id, SRC_DIR))) {
18 | logger.info(colors.green(`No changes in ${id}.`));
19 | return { close: () => {} };
20 | }
21 |
22 | logger.info(colors.cyan(`Building ${id}...`));
23 | return await webpackBuild(configPath, options);
24 | }
25 |
--------------------------------------------------------------------------------
/build/task-clean-package.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import rimraf from 'rimraf';
5 | import * as Const from './utils/const';
6 |
7 | export default () => new Promise((resolve, reject) => {
8 | rimraf(Const.PACKAGED_DIST_DIR, err => {
9 | if (err) {
10 | reject(err);
11 | }
12 | resolve();
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/build/task-config-builder.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | /**
5 | * Creates a `build-config.json` in the lib directory for runtime access to
6 | * build configurations.
7 | */
8 |
9 | import pick from 'lodash/pick';
10 | import { getBuildConfig, writeBuildConfig } from './utils';
11 | import baseConfig from './utils/base-config';
12 |
13 | export function overwriteConfig(customConfig) {
14 | let currentConfig = {};
15 |
16 | try {
17 | currentConfig = getBuildConfig();
18 | } catch (e) {
19 | // Ignore missing file errors.
20 | }
21 |
22 | writeBuildConfig({
23 | ...currentConfig,
24 | ...baseConfig,
25 | ...customConfig,
26 | });
27 | }
28 |
29 | export function saveConfigAsPrev() {
30 | const currentConfig = getBuildConfig();
31 | const sanitizedConfig = pick(currentConfig, Object.keys(baseConfig));
32 |
33 | writeBuildConfig({
34 | ...currentConfig,
35 | prev: sanitizedConfig,
36 | });
37 | }
38 |
--------------------------------------------------------------------------------
/build/task-run.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import colors from 'colors/safe';
5 | import path from 'path';
6 |
7 | import * as Const from './utils/const';
8 | import { getAppManifest } from './utils';
9 | import { getElectronPath } from './utils/electron';
10 | import { spawn } from './utils/process';
11 | import { logger } from './logging';
12 |
13 | export default async function(args = []) {
14 | const manifest = getAppManifest();
15 | const command = getElectronPath();
16 | const script = path.join(Const.LIB_DIR, manifest.main);
17 |
18 | logger.info(colors.cyan('Executing'), colors.gray(command));
19 |
20 | await spawn(command, [script, ...args], {
21 | stdio: 'inherit',
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/build/task-serve.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import * as spawn from '../app/main/spawn';
5 | import { LIB_DIR, PROFILE_DIR } from './utils/const';
6 |
7 | export function startUserAgentService(options = {}) {
8 | spawn.startUserAgentService(null, options);
9 | }
10 |
11 | export function startContentService(options = {}) {
12 | spawn.startContentService(options);
13 | }
14 |
15 | export default function() {
16 | startUserAgentService({ attached: true, libdir: LIB_DIR, profiledir: PROFILE_DIR });
17 | startContentService({ attached: true, libdir: LIB_DIR, profiledir: PROFILE_DIR });
18 | }
19 |
--------------------------------------------------------------------------------
/build/utils/argv.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import yargs from 'yargs';
5 |
6 | export default yargs
7 | .usage('Usage: $0 [options]')
8 | .option('i', {
9 | alias: 'build-deps',
10 | describe: 'Install all dependencies.',
11 | type: 'boolean',
12 | })
13 | .option('b', {
14 | alias: 'build',
15 | describe: 'Build the app.',
16 | type: 'boolean',
17 | })
18 | .option('s', {
19 | alias: 'serve',
20 | describe: 'Start the app services standalone.',
21 | type: 'boolean',
22 | })
23 | .option('r', {
24 | alias: 'run',
25 | describe: 'Build and start the app.',
26 | type: 'boolean',
27 | })
28 | .option('d', {
29 | alias: 'run-dev',
30 | describe: 'Build and start the app in development mode.',
31 | type: 'boolean',
32 | })
33 | .option('p', {
34 | alias: 'package',
35 | describe: 'Package the app.',
36 | type: 'boolean',
37 | })
38 | .option('t', {
39 | alias: 'test',
40 | describe: 'Run tests.',
41 | type: 'boolean',
42 | })
43 | .option('T', {
44 | alias: 'test-ci',
45 | describe: 'Run tests on both production and development builds.',
46 | type: 'boolean',
47 | })
48 | .argv;
49 |
--------------------------------------------------------------------------------
/build/utils/base-config.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import os from 'os';
5 | import { getElectronVersion } from './electron';
6 |
7 | export default {
8 | // Platform information.
9 | platform: os.platform(),
10 |
11 | // Electron information.
12 | electron: getElectronVersion(),
13 |
14 | // The `development` option indicates whether or not the build is
15 | // using unoptimized, unminified content and other things like that.
16 | development: false,
17 |
18 | // Whether to offer to set Tofino as the default browser.
19 | offerDefault: false,
20 |
21 | // The `packaged` flag indicates whether or not the build
22 | // is a distributed, standalone exexcutable or not.
23 | packaged: false,
24 | };
25 |
--------------------------------------------------------------------------------
/build/utils/const.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import path from 'path';
5 |
6 | export const ROOT = path.resolve(path.dirname(path.join(__dirname, '..')));
7 |
8 | export const BUILD_SYSTEM_DIR = path.join(ROOT, 'build');
9 | export const SRC_DIR = path.join(ROOT, 'app');
10 | export const LIB_DIR = path.join(ROOT, 'lib');
11 | export const PROFILE_DIR = path.join(ROOT, 'profile');
12 | export const PACKAGED_DIST_DIR = path.join(ROOT, 'dist');
13 |
14 | export const APP_SHARED_DIR = path.join(SRC_DIR, 'shared');
15 | export const BUILD_CONFIG_PATH = path.join(SRC_DIR, 'build-config.json');
16 | export const BUILD_UTILS_PATH = path.join(BUILD_SYSTEM_DIR, 'utils');
17 | export const BUILD_WEBPACK_CONFIGS_PATH = path.join(BUILD_SYSTEM_DIR, 'config');
18 | export const BROWSER_FRONTENDS_PATH = path.join(BUILD_WEBPACK_CONFIGS_PATH, 'frontends.json');
19 |
20 | export const CACHE_DIR = path.join(ROOT, '.cache');
21 | export const ELECTRON_ROOT_DIR = path.join(ROOT, '.electron');
22 | export const NODE_MODULES_DIR = path.join(ROOT, 'node_modules');
23 |
--------------------------------------------------------------------------------
/build/utils/electron.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import path from 'path';
5 | import os from 'os';
6 | import fs from 'fs-promise';
7 | import * as Const from './const';
8 | import * as BuildUtils from './';
9 |
10 | export function getElectronExecutable() {
11 | return {
12 | win32: 'electron.exe',
13 | darwin: path.join('Electron.app', 'Contents', 'MacOS', 'Electron'),
14 | linux: 'electron',
15 | };
16 | }
17 |
18 | export function getOSElectronExecutable() {
19 | return getElectronExecutable()[os.platform()];
20 | }
21 |
22 | export function getElectronRoot() {
23 | return Const.ELECTRON_ROOT_DIR;
24 | }
25 |
26 | export function getElectronPath() {
27 | return path.join(getElectronRoot(), getOSElectronExecutable());
28 | }
29 |
30 | // This intentionally throws an exception if electron hasn't been downloaded yet.
31 | export function getElectronVersion() {
32 | const versionFile = path.join(Const.ELECTRON_ROOT_DIR, 'version');
33 | const version = fs.readFileSync(versionFile, { encoding: 'utf8' });
34 |
35 | // Trim off the leading 'v'.
36 | return version.trim().substring(1);
37 | }
38 |
39 | // We cache the download in a private place since these builds may not be
40 | // official Electron builds.
41 | export function getDownloadOptions() {
42 | const manifest = BuildUtils.getManifest();
43 | return {
44 | mirror: manifest._electron.mirror,
45 | customDir: manifest._electron.revision,
46 | version: manifest._electron.version,
47 | cache: Const.CACHE_DIR,
48 | strictSSL: true,
49 | };
50 | }
51 |
--------------------------------------------------------------------------------
/build/utils/empty_module.js:
--------------------------------------------------------------------------------
1 | // An empty module used to override optional modules from packages.
2 | /* eslint import/no-commonjs: "off" */
3 | module.exports = null;
4 |
--------------------------------------------------------------------------------
/build/utils/index.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import fs from 'fs-promise';
5 | import manifest from '../../package.json';
6 | import appManifest from '../../app/package.json';
7 | import { BUILD_CONFIG_PATH } from './const';
8 |
9 | export const IS_TRAVIS = process.env.TRAVIS === 'true';
10 | export const IS_APPVEYOR = process.env.APPVEYOR === 'True';
11 |
12 | export function getManifest() {
13 | return manifest;
14 | }
15 |
16 | export function getAppManifest() {
17 | return appManifest;
18 | }
19 |
20 | export function safeGetBuildConfig() {
21 | try { return getBuildConfig(); } catch (e) { return {}; }
22 | }
23 |
24 | export function getBuildConfig() {
25 | return fs.readJsonSync(BUILD_CONFIG_PATH);
26 | }
27 |
28 | export function writeBuildConfig(obj) {
29 | return fs.writeJsonSync(BUILD_CONFIG_PATH, obj, { spaces: 2 });
30 | }
31 |
--------------------------------------------------------------------------------
/build/utils/process.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import os from 'os';
5 | import fs from 'fs-promise';
6 | import childProcess from 'child_process';
7 |
8 | // Use a windows `.cmd` command if available.
9 | export async function normalizeCommand(command) {
10 | if (os.type() === 'Windows_NT') {
11 | try {
12 | // Prefer a cmd version if available
13 | const testCommand = `${command}.cmd`;
14 | const stats = await fs.stat(testCommand);
15 | if (stats.isFile()) {
16 | command = testCommand;
17 | }
18 | } catch (e) {
19 | // Ignore missing files.
20 | }
21 | }
22 | return command;
23 | }
24 |
25 | export async function spawn(command, args, options = {}) {
26 | command = await normalizeCommand(command);
27 |
28 | return new Promise((resolve, reject) => {
29 | const child = childProcess.spawn(command, args, options);
30 |
31 | child.on('error', reject);
32 | child.on('exit', code => {
33 | if (code !== 0) {
34 | reject(new Error(`Child process ${command} exited with exit code ${code}`));
35 | } else {
36 | resolve();
37 | }
38 | });
39 | });
40 | }
41 |
--------------------------------------------------------------------------------
/build/utils/runtime.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | import semver from 'semver';
5 | import cd from 'check-dependencies';
6 | import manifest from '../../package.json';
7 | import { logger } from '../logging';
8 |
9 | export const VALID_NODE_VERSION_RANGE = manifest.engines.node;
10 |
11 | export function checkNodeVersion(version) {
12 | // Strip out the 'v' in version, since `process.version`
13 | // returns `v5.8.0`.
14 | version = version.replace(/v/g, '');
15 |
16 | if (semver.satisfies(version, VALID_NODE_VERSION_RANGE)) {
17 | return true;
18 | }
19 |
20 | /* eslint-disable quotes */
21 | logger.error(`\n` +
22 | `*****\n` +
23 | `You are currently running node ${process.version}.\nYour version of node ` +
24 | `must satisfy ${VALID_NODE_VERSION_RANGE}, or else strange things ` +
25 | `could happen.\nPlease upgrade your version of node, or use a ` +
26 | `node version manager, such as nvm:\nhttps://github.com/creationix/nvm\n` +
27 | `*****\n`);
28 | /* eslint-enable quotes */
29 |
30 | return false;
31 | }
32 |
33 | export function checkDependencies() {
34 | return new Promise((resolve, reject) => {
35 | cd(result => result.depsWereOk ? resolve() : reject(result));
36 | });
37 | }
38 |
--------------------------------------------------------------------------------
/build/utils/webpack.js:
--------------------------------------------------------------------------------
1 | // Any copyright is dedicated to the Public Domain.
2 | // http://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | /* eslint-disable no-shadow */
5 |
6 | import path from 'path';
7 | import childProcess from 'child_process';
8 |
9 | import * as Const from '../utils/const';
10 | import { dependencies } from '../../app/package.json';
11 |
12 | export const nodeExternals = (context, request, cb) => {
13 | if (request.startsWith('.')) {
14 | cb(null, false);
15 | return;
16 | }
17 |
18 | for (const dependency of Object.keys(dependencies)) {
19 | if ((request === dependency) || request.startsWith(`${dependency}/`)) {
20 | cb(null, true);
21 | return;
22 | }
23 | }
24 |
25 | cb(null, false);
26 | };
27 |
28 | export const webpackBuild = (configPath, options) => new Promise((resolve, reject) => {
29 | const child = childProcess.fork(path.join(Const.BUILD_UTILS_PATH, 'webpack-process'));
30 |
31 | const once = expected => new Promise(resolve => {
32 | child.on('message', e => {
33 | if (e.message === expected) {
34 | resolve(e);
35 | }
36 | });
37 | });
38 |
39 | once('fatal-error', e => reject(e.err));
40 | once('build-error', e => reject(e.err));
41 |
42 | const build = () => {
43 | const finishedBuild = once('finished-build');
44 | child.send({ message: 'build', configPath, options });
45 | return finishedBuild;
46 | };
47 |
48 | const close = () => {
49 | const cleanedUp = once('cleaned-up');
50 | child.send({ message: 'will-close' });
51 | return cleanedUp.then(() => child.kill());
52 | };
53 |
54 | build().then(() => resolve({ close }));
55 | });
56 |
--------------------------------------------------------------------------------
/docs/building.md:
--------------------------------------------------------------------------------
1 | # Building Tofino
2 |
3 | ## All platforms
4 |
5 | Ensure you have the following installed and accessible in your `PATH` environment variable.
6 |
7 | * [Node.js](https://nodejs.org) >= 6.1.0
8 | * To manage multiple node installations, consider using [nvm](https://github.com/creationix/nvm)
9 | * [Python 2.7](https://www.python.org/) (`python` must be in path)
10 |
11 | ### Windows
12 |
13 | * Install [Visual Studio 2013](https://www.visualstudio.com/news/vs2013-community-vs)
14 | * Use the [VS2013 Developer Command Prompt](http://stackoverflow.com/a/22702405), or otherwise have your environment variables set correctly.
15 |
16 | ### Linux
17 |
18 | * Install your platform's build essentials, i.e. `sudo apt-get install build-essential`
19 |
20 | ### OSX
21 |
22 | Installation instructions here use [Homebrew](http://brew.sh/). You don't need `nvm`, but makes installing and managing node versions simple.
23 |
24 | ```
25 | $ brew install node python
26 | ```
27 |
28 | ## Building
29 |
30 | Once all dependencies are installed, you should be able to just install the node dependencies via npm:
31 |
32 | ```
33 | npm install
34 | ```
35 |
36 | At this point you can run a build via:
37 |
38 | ```
39 | npm run dev
40 | ```
41 |
--------------------------------------------------------------------------------
/docs/diagrams/UA-bookmark-star.graffle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/docs/diagrams/UA-bookmark-star.graffle
--------------------------------------------------------------------------------
/docs/diagrams/UA-bookmark-star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/docs/diagrams/UA-bookmark-star.png
--------------------------------------------------------------------------------
/docs/diagrams/UA-service-architecture.graffle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/docs/diagrams/UA-service-architecture.graffle
--------------------------------------------------------------------------------
/docs/diagrams/UA-service-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/tofino/e03652fc15fcb883885e42c2c195d58055073598/docs/diagrams/UA-service-architecture.png
--------------------------------------------------------------------------------
/docs/package-manifests.md:
--------------------------------------------------------------------------------
1 | Tofino uses a two package manifest setup where node modules required to ship as-is with the
2 | application are included in the `app/package.json` while those that are webpacked or otherwise used
3 | at build or test time are included in the main `package.json` manifest.
4 |
5 | Use the following to decide where to put a new module dependency:
6 |
7 | * Packages used by the application itself (content service, UA service, main process, renderer
8 | process, preload scripts) should be placed in the `dependencies` section of `package.json` where
9 | possible.
10 | * Native modules should only be used in the UA or content service code and should be placed in
11 | the `dependencies` section of `app/package.json`.
12 | * Some modules aren't compatible with webpack and should also be placed in the `dependencies`
13 | section of `app/package.json` but this will only work for the UA and content service code.
14 | * Packages used only by build and test code should be placed in the `devDependencies` section of
15 | `package.json`
16 |
17 | When the application is built all of the processes are webpacked with the modules listed in
18 | `app/package.json` marked as externals. These are copied into `lib/node_modules` and then bundled
19 | with the packaged application.
20 |
--------------------------------------------------------------------------------
/scripts/bootstrap.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import os
4 | import subprocess
5 | import sys
6 |
7 | SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
8 |
9 | def main():
10 | is_appveyor = (os.getenv("APPVEYOR") == "True")
11 | is_travis = (os.getenv("TRAVIS") == "true")
12 |
13 | platform = "win32"
14 | if is_travis:
15 | platform = os.getenv("TRAVIS_OS_NAME")
16 |
17 | if platform == "osx":
18 | run(["brew", "update"])
19 | run(["brew", "install", "nvm"])
20 | elif platform == "linux":
21 | run(["sh", "-e", "/etc/init.d/xvfb", "start"])
22 |
23 | def run(args = []):
24 | sys.stderr.write("Running %s\n" % (" ".join(args)))
25 | sys.stderr.flush()
26 | try:
27 | subprocess.check_call(args)
28 | except:
29 | sys.stderr.write("Exited with non-zero exit code.")
30 | sys.stderr.flush()
31 |
32 | if __name__ == '__main__':
33 | sys.exit(main())
34 |
--------------------------------------------------------------------------------
/scripts/bootstrap.sh:
--------------------------------------------------------------------------------
1 | scripts/bootstrap.py
2 |
3 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then
4 | export NVM_DIR=~/.nvm
5 | . $(brew --prefix nvm)/nvm.sh
6 | fi
7 |
--------------------------------------------------------------------------------
/test/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "mocha": true
4 | },
5 |
6 | "rules": {
7 | "prefer-arrow-callback": ["off"]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test/fixtures/history.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 | HTML5 History Fixture
9 |
10 |
11 |
12 | red
13 | blue
14 | green
15 | no-title
16 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test/fixtures/links.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 | A Very Simple Page With Links
9 |
10 |
11 |
12 | Open simple in this tab
13 | Open simple in a background tab
14 |
15 |
16 |
--------------------------------------------------------------------------------
/test/fixtures/mozilla.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 | The Book of Mozilla, 15:1
9 |
10 |
43 |
44 |
45 |
46 |
47 |
48 | The twins of Mammon quarrelled. Their warring plunged the world into a new darkness, and the beast abhorred the darkness. So it began to move swiftly, and grew more powerful, and went forth and multiplied. And the beasts brought fire and light to the darkness.
49 |