├── .babelrc ├── .flowconfig ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── TODO.md ├── examples ├── accept-first-mouse.js ├── default-position.js ├── default-size.js ├── dynamic-menu.js ├── fixed-position.js ├── fixed-size.js ├── index.html ├── main.js ├── menu.js ├── position.js └── size.js ├── flow-typed └── npm │ ├── babel-core_vx.x.x.js │ ├── babel-loader_vx.x.x.js │ ├── babel-plugin-check-es2015-constants_vx.x.x.js │ ├── babel-plugin-transform-es2015-destructuring_vx.x.x.js │ ├── babel-plugin-transform-es2015-spread_vx.x.x.js │ ├── babel-preset-es2015_vx.x.x.js │ ├── babel-preset-react_vx.x.x.js │ ├── babel-preset-stage-0_vx.x.x.js │ ├── babel-register_vx.x.x.js │ ├── chai_v3.5.x.js │ ├── css-loader_vx.x.x.js │ ├── electron-builder_vx.x.x.js │ ├── electron_vx.x.x.js │ ├── express_v4.x.x.js │ ├── file-loader_vx.x.x.js │ ├── flow-bin_v0.x.x.js │ ├── flow-typed_vx.x.x.js │ ├── html-webpack-plugin_vx.x.x.js │ ├── json-loader_vx.x.x.js │ ├── mocha-webpack_vx.x.x.js │ ├── mocha_v3.1.x.js │ ├── postcss-cssnext_vx.x.x.js │ ├── postcss-loader_vx.x.x.js │ ├── postcss-smart-import_vx.x.x.js │ ├── sinon-chai_vx.x.x.js │ ├── sinon_vx.x.x.js │ ├── source-map-support_vx.x.x.js │ ├── style-loader_vx.x.x.js │ ├── url-loader_vx.x.x.js │ ├── webpack-dev-middleware_vx.x.x.js │ └── webpack_vx.x.x.js ├── interfaces ├── electron.js └── global.js ├── mocha-webpack.opts ├── package.json ├── src ├── .babelrc ├── IonizeContainer.js ├── IonizeFiber.js ├── IonizeHostConfig.js ├── elements │ ├── AppElement.js │ ├── BaseElement.js │ ├── GenericElement.js │ ├── MenuElement.js │ ├── MenuItemElement.js │ ├── SubmenuElement.js │ ├── TextElement.js │ ├── WindowElement.js │ └── index.js ├── index.js └── util │ └── configureWrappedEventHandler.js ├── test ├── app.spec.js ├── lib │ └── electron.js ├── main.spec.js ├── menu.spec.js ├── test-setup.js └── window.spec.js ├── webpack.examples.config.js ├── webpack.test.config.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ['es2015', 'react', 'stage-0'] 3 | } 4 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | [include] 4 | 5 | [libs] 6 | flow-typed 7 | interfaces 8 | 9 | [options] 10 | module.name_mapper='react-ionize' -> '/src/index.js' 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | lib/ 4 | .tmp/ 5 | *.log 6 | /.idea 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "javascript.validate.enable": false 4 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Matt Hink 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-ionize 2 | 3 | react-ionize is a library which lets you build the "non-browser" parts of an Electron app using React components to manage your application's state. 4 | 5 | [Electron](https://electron.atom.io) applications consist of two types of process: a *main process* which manages the lifecycle of the application, and several *renderer processes*, which display webpages which comprise the application's GUI. While it's fairly common to use React and ReactDOM to build an HTML/CSS/JS interface in the renderer process, `react-ionize` runs in the main process, managing things like window size/position, menu contents, and application-wide events. 6 | 7 | ![react-ionize demo](https://cloud.githubusercontent.com/assets/780461/24886483/b5f61e70-1e09-11e7-8e44-9179a5dc8ab7.gif) 8 | 9 | ## Caveat Developer 10 | react-ionize is still an EXPERIMENTAL, PRE-ALPHA library, and is not yet 11 | suitable for for use in a production app! It's a custom renderer built on top 12 | of the React Fiber reconciliation API, which itself is still under active 13 | development. (Not to mention, I've got a whole crop of Electron features yet 14 | to add.) 15 | 16 | ## Getting Started 17 | 18 | ``` 19 | * npm install --save electron 20 | * npm install --save react@16.0.0-alpha.5 21 | * npm install --save react-ionize 22 | ``` 23 | 24 | Take a look at [Ionize Example App](https://github.com/mhink/ionize-example-app) to get started. 25 | 26 | ## Hello, world! 27 | 28 | ```js 29 | const React = require('react'); 30 | const Ionize = require('react-ionize'); 31 | const path = require('path'); 32 | const fs = require('fs'); 33 | 34 | const INDEX_HTML_PATH = path.resolve(__dirname, 'index.html'); 35 | const INDEX_HTML_SOURCE = ` 36 | 37 | 38 | 39 | 40 | Hello, Electron! 41 | 42 | 43 |

Hello, Electron!

44 | 45 | 46 | `; 47 | 48 | fs.writeFileSync(INDEX_HTML_PATH, INDEX_HTML_SOURCE); 49 | 50 | Ionize.start( 51 | 52 | 53 | 54 | ); 55 | ``` 56 | 57 | (Normally, you'd build and distribute an `index.html` along with your JS during your build process, but I wanted this example to be as independent of build processes as possible.) 58 | 59 | ## API 60 | ### `Ionize.start(element, [callback])` 61 | 62 | Starts up an Electron application under Ionize. (Note: this will wait on the 63 | 'ready' Electron event before starting to render any elements.) 64 | 65 | ## Elements 66 | Generally speaking, the presence of an Ionize element in your component tree 67 | indicates that you _want_ it to be there, and that Ionize should ensure its 68 | presence when rendering. This can lead to slightly surprising behavior if 69 | you're unfamiliar with React- for instance, if you want a window to actually 70 | go away when you close it, you need to make sure that the corresponding `` 71 | element actually gets unmounted! 72 | 73 | ### `` 74 | Attachment point for event handlers related to the global app. Not strictly 75 | necessary if you don't need to register any of these (since React Fiber now 76 | supports multiple children without a parent element). 77 | 78 | Generally speaking, children of `` are things related to the entire 79 | application: browser windows, dialogs, tray elements, and so forth. (Or at 80 | least, they will be once I get a chance to implement them.) 81 | 82 | * Event Handlers 83 | * onReady- Fired immediately when the component is mounted. Under the hood, Ionize actually waits for 'ready' before even trying to start mounting everything, but this is here for the sake of API compatibility. 84 | 85 | ### `` 86 | Represents an Electron BrowserWindow object. 87 | 88 | * file 89 | * The HTML file you want to render in the Chrome browser instance. (Note 90 | that Ionize looks up this file relative to the _runtime_ location of 91 | your project!) 92 | 93 | * show 94 | * When this prop transitions from false -> true, Ionize displays the 95 | browser window. When it transitions from true -> false, Ionize hides 96 | (but does not close) the browser window. If this is true when the 97 | element is mounted, Ionize will immediately show the window. 98 | 99 | * onReadyToShow 100 | * Called when the window's `ready-to-show` event is triggered. You can use this to keep the window hidden until it's ready. 101 | 102 | * showDevTools 103 | * If this is true when the element is mounted, Ionize will open 104 | the Chrome Developer Tools when opening the browser window. 105 | 106 | * size 107 | * This is a controlled prop, and behaves much like an `` element in traditional React apps. That is to say, if you provide `size` by itself, the user will not be able to resize the window- it will simply *be* that size, unless you provide an `onResize` handler to update the value provided. 108 | * See also: https://facebook.github.io/react/docs/forms.html#controlled-components 109 | 110 | * onResize 111 | * This event handler is called with the new window size when the window size changes. If provided in conjunction with the `size` prop, it will allow the window to be resized (although you will need to update the value of the `size` prop accordingly). 112 | 113 | * defaultSize 114 | * If you don't care about tracking the window's size manually, you may provide a `defaultSize` prop to set the window to an initial size when it's mounted. 115 | 116 | * position 117 | * onMove 118 | * onMoved 119 | * defaultPosition 120 | * These props work pretty much the same as `size`, `onResize`, and `defaultSize`, except they represent the position on the screen. 121 | * Keep in mind that these values might be funky if you're dealing with multiple monitors. 122 | 123 | ### `` 124 | The `` element defines an Electron application menu. By nesting ``s inside it, you can construct your menu. 125 | 126 | TODO: When nested inside a `` element, this should attach the menu to 127 | that window, specifically- and I'd like to have something like a `` 128 | element for right-clicks. 129 | 130 | ### `` 131 | * label 132 | * The label of the submenu. (Keep in mind that on OSX, the first submenu in the list will take the application's name, no matter what label you might give it.) 133 | * children 134 | * `` and `` elements only! 135 | 136 | ### `` and related 137 | Pretty much equivalent to `new MenuItem({ type: 'normal' })` in vanilla Electron. 138 | 139 | * label 140 | * The text shown for this menu item 141 | 142 | * onClick 143 | * An onclick handler for this menu item. 144 | 145 | There are a couple special-case elements related to ``. 146 | 147 | #### `` 148 | A *separator* menu item. Equivalent to `new MenuItem({ type: 'separator' })` in vanilla Electron. 149 | 150 | #### Role-based elements 151 | In the Electron API, you can create MenuItems with a "role", which assigns them some OS-native functionality (think copy, paste, select all, and so on.) As a shorthand, you can use these directly as an element name within a ``. For instance, 152 | 153 | ``` 154 | 155 | ``` 156 | 157 | is equivalent to 158 | 159 | `new MenuItem({ role: 'pasteandmatchstyle' })` in vanilla Electron. 160 | 161 | ## Feedback and Contributions 162 | Feedback is welcome! Add an issue or hit me up on [Twitter](https://twitter.com/mhink1103). I'm still working out how all this should work, but I would love to hear your suggestions. 163 | 164 | If you'd like to contribute, right now we could really use some more feature implementations. Basically, what I've been doing is picking Electron APIs and figuring out how to turn them into either elements or props on existing elements. For instance, the [`app.setBadge(text)`](https://electron.atom.io/docs/api/app/#appdocksetbadgetext-macos) API call would make for a pretty good prop on ``. 165 | 166 | To assist the would-be contributor, I've included a bunch of documentation and notes about React Fiber in the comments of [`IonizeHostConfig.js`](https://github.com/mhink/react-ionize/blob/master/src/IonizeHostConfig.js). For further reading, I'd basically recommend cloning down the React repo and digging through its `/src/renderers` directory, starting with `/src/renderers/shared/fiber/ReactFiberReconciler.js` and going from there. 167 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # Existing elements 2 | 3 | ## 4 | * Support more/all event types 5 | * Work on 'smart ref' (user-facing API) 6 | 7 | ## 8 | * Support more/all event types 9 | * Work on 'smart ref' 10 | * Properly handle nesting, using HostContext (maybe?) 11 | * Add prop for frameless windows? (low-priority) 12 | 13 | ## 14 | * Properly handle nesting! 15 | 16 | ## 17 | 18 | ## 19 | * Work on 'smart ref' 20 | * Detect appropriate window to which to attach dialog 21 | 22 | # Planned elements 23 | 24 | ## 25 | 26 | ## 27 | * Properly support events! 28 | 29 | ## 30 | * Meant to be nested under a 31 | 32 | ## 33 | * Set up event handlers for IPC events sent to the main process. 34 | 35 | ## 36 | * Low priority, but cool. 37 | 38 | # Other improvements 39 | 40 | ## Validate nesting 41 | -------------------------------------------------------------------------------- /examples/accept-first-mouse.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | Ionize.start( 8 | 13 | ); 14 | -------------------------------------------------------------------------------- /examples/default-position.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | Ionize.start( 8 | 12 | ); 13 | -------------------------------------------------------------------------------- /examples/default-size.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | Ionize.start( 8 | 12 | ); 13 | -------------------------------------------------------------------------------- /examples/dynamic-menu.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | const LABELS = [ 8 | 'Hello!', 9 | 'World!', 10 | 'Foo the bars!', 11 | 'Baz the quuxes!', 12 | 'Something else, I guess' 13 | ]; 14 | 15 | class ExampleApp extends React.Component { 16 | constructor(props) { 17 | super(props); 18 | 19 | this.state = { 20 | counter: 0 21 | }; 22 | } 23 | 24 | render() { 25 | const { counter } = this.state; 26 | const customLabel = LABELS[counter % 5]; 27 | 28 | return ( 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | this.setState({ counter: counter+1 })} 40 | /> 41 | 42 | 43 | 48 | 49 | ); 50 | } 51 | } 52 | 53 | Ionize.start( 54 | 55 | ); 56 | -------------------------------------------------------------------------------- /examples/fixed-position.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | Ionize.start( 8 | 12 | ); 13 | -------------------------------------------------------------------------------- /examples/fixed-size.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | Ionize.start( 8 | 12 | ); 13 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello, Electron! 6 | 7 | 8 |

Hello, Electron!

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | class ExampleApp extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | show: false, 12 | size: [300, 300], 13 | position: [100, 100], 14 | }; 15 | } 16 | 17 | render() { 18 | return 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | this.setState({ show: true })} 37 | onResize={size => this.setState({ size })} 38 | onMoved={position => this.setState({ position })} 39 | /> 40 | 41 | } 42 | } 43 | 44 | Ionize.start( 45 | 46 | ); 47 | -------------------------------------------------------------------------------- /examples/menu.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | Ionize.start( 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 40 | 41 | ); 42 | -------------------------------------------------------------------------------- /examples/position.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | const DefaultPositionApp = () => ( 8 | 12 | ); 13 | 14 | const FixedPositionApp = () => ( 15 | 19 | ); 20 | 21 | class MovableApp extends React.Component { 22 | constructor(props) { 23 | super(props); 24 | this.state = { 25 | position: [300, 300], 26 | }; 27 | } 28 | 29 | render() { 30 | return this.setState({ position })} 34 | /> 35 | } 36 | } 37 | 38 | Ionize.start(); 39 | -------------------------------------------------------------------------------- /examples/size.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Ionize from 'react-ionize'; 3 | import path from 'path'; 4 | 5 | import 'index.html'; 6 | 7 | const DefaultSizeApp = () => ( 8 | 12 | ); 13 | 14 | const FixedSizeApp = () => ( 15 | 19 | ); 20 | 21 | class ResizableApp extends React.Component { 22 | constructor(props) { 23 | super(props); 24 | this.state = { 25 | size: [300, 300], 26 | }; 27 | } 28 | 29 | render() { 30 | return this.setState({ size })} 34 | /> 35 | } 36 | } 37 | 38 | Ionize.start( 39 | 40 | ); 41 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-core_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: a28b6ecc117250e4cfe88ef81490822b 2 | // flow-typed version: <>/babel-core_v^6.24.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-core' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-core' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-core/lib/api/browser' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'babel-core/lib/api/node' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'babel-core/lib/helpers/get-possible-plugin-names' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'babel-core/lib/helpers/get-possible-preset-names' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'babel-core/lib/helpers/merge' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'babel-core/lib/helpers/normalize-ast' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'babel-core/lib/helpers/resolve-from-possible-names' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'babel-core/lib/helpers/resolve-plugin' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'babel-core/lib/helpers/resolve-preset' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'babel-core/lib/helpers/resolve' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'babel-core/lib/store' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'babel-core/lib/tools/build-external-helpers' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'babel-core/lib/transformation/file/index' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'babel-core/lib/transformation/file/logger' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'babel-core/lib/transformation/file/metadata' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module 'babel-core/lib/transformation/file/options/build-config-chain' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module 'babel-core/lib/transformation/file/options/config' { 90 | declare module.exports: any; 91 | } 92 | 93 | declare module 'babel-core/lib/transformation/file/options/index' { 94 | declare module.exports: any; 95 | } 96 | 97 | declare module 'babel-core/lib/transformation/file/options/option-manager' { 98 | declare module.exports: any; 99 | } 100 | 101 | declare module 'babel-core/lib/transformation/file/options/parsers' { 102 | declare module.exports: any; 103 | } 104 | 105 | declare module 'babel-core/lib/transformation/file/options/removed' { 106 | declare module.exports: any; 107 | } 108 | 109 | declare module 'babel-core/lib/transformation/internal-plugins/block-hoist' { 110 | declare module.exports: any; 111 | } 112 | 113 | declare module 'babel-core/lib/transformation/internal-plugins/shadow-functions' { 114 | declare module.exports: any; 115 | } 116 | 117 | declare module 'babel-core/lib/transformation/pipeline' { 118 | declare module.exports: any; 119 | } 120 | 121 | declare module 'babel-core/lib/transformation/plugin-pass' { 122 | declare module.exports: any; 123 | } 124 | 125 | declare module 'babel-core/lib/transformation/plugin' { 126 | declare module.exports: any; 127 | } 128 | 129 | declare module 'babel-core/lib/util' { 130 | declare module.exports: any; 131 | } 132 | 133 | declare module 'babel-core/register' { 134 | declare module.exports: any; 135 | } 136 | 137 | // Filename aliases 138 | declare module 'babel-core/index' { 139 | declare module.exports: $Exports<'babel-core'>; 140 | } 141 | declare module 'babel-core/index.js' { 142 | declare module.exports: $Exports<'babel-core'>; 143 | } 144 | declare module 'babel-core/lib/api/browser.js' { 145 | declare module.exports: $Exports<'babel-core/lib/api/browser'>; 146 | } 147 | declare module 'babel-core/lib/api/node.js' { 148 | declare module.exports: $Exports<'babel-core/lib/api/node'>; 149 | } 150 | declare module 'babel-core/lib/helpers/get-possible-plugin-names.js' { 151 | declare module.exports: $Exports<'babel-core/lib/helpers/get-possible-plugin-names'>; 152 | } 153 | declare module 'babel-core/lib/helpers/get-possible-preset-names.js' { 154 | declare module.exports: $Exports<'babel-core/lib/helpers/get-possible-preset-names'>; 155 | } 156 | declare module 'babel-core/lib/helpers/merge.js' { 157 | declare module.exports: $Exports<'babel-core/lib/helpers/merge'>; 158 | } 159 | declare module 'babel-core/lib/helpers/normalize-ast.js' { 160 | declare module.exports: $Exports<'babel-core/lib/helpers/normalize-ast'>; 161 | } 162 | declare module 'babel-core/lib/helpers/resolve-from-possible-names.js' { 163 | declare module.exports: $Exports<'babel-core/lib/helpers/resolve-from-possible-names'>; 164 | } 165 | declare module 'babel-core/lib/helpers/resolve-plugin.js' { 166 | declare module.exports: $Exports<'babel-core/lib/helpers/resolve-plugin'>; 167 | } 168 | declare module 'babel-core/lib/helpers/resolve-preset.js' { 169 | declare module.exports: $Exports<'babel-core/lib/helpers/resolve-preset'>; 170 | } 171 | declare module 'babel-core/lib/helpers/resolve.js' { 172 | declare module.exports: $Exports<'babel-core/lib/helpers/resolve'>; 173 | } 174 | declare module 'babel-core/lib/store.js' { 175 | declare module.exports: $Exports<'babel-core/lib/store'>; 176 | } 177 | declare module 'babel-core/lib/tools/build-external-helpers.js' { 178 | declare module.exports: $Exports<'babel-core/lib/tools/build-external-helpers'>; 179 | } 180 | declare module 'babel-core/lib/transformation/file/index.js' { 181 | declare module.exports: $Exports<'babel-core/lib/transformation/file/index'>; 182 | } 183 | declare module 'babel-core/lib/transformation/file/logger.js' { 184 | declare module.exports: $Exports<'babel-core/lib/transformation/file/logger'>; 185 | } 186 | declare module 'babel-core/lib/transformation/file/metadata.js' { 187 | declare module.exports: $Exports<'babel-core/lib/transformation/file/metadata'>; 188 | } 189 | declare module 'babel-core/lib/transformation/file/options/build-config-chain.js' { 190 | declare module.exports: $Exports<'babel-core/lib/transformation/file/options/build-config-chain'>; 191 | } 192 | declare module 'babel-core/lib/transformation/file/options/config.js' { 193 | declare module.exports: $Exports<'babel-core/lib/transformation/file/options/config'>; 194 | } 195 | declare module 'babel-core/lib/transformation/file/options/index.js' { 196 | declare module.exports: $Exports<'babel-core/lib/transformation/file/options/index'>; 197 | } 198 | declare module 'babel-core/lib/transformation/file/options/option-manager.js' { 199 | declare module.exports: $Exports<'babel-core/lib/transformation/file/options/option-manager'>; 200 | } 201 | declare module 'babel-core/lib/transformation/file/options/parsers.js' { 202 | declare module.exports: $Exports<'babel-core/lib/transformation/file/options/parsers'>; 203 | } 204 | declare module 'babel-core/lib/transformation/file/options/removed.js' { 205 | declare module.exports: $Exports<'babel-core/lib/transformation/file/options/removed'>; 206 | } 207 | declare module 'babel-core/lib/transformation/internal-plugins/block-hoist.js' { 208 | declare module.exports: $Exports<'babel-core/lib/transformation/internal-plugins/block-hoist'>; 209 | } 210 | declare module 'babel-core/lib/transformation/internal-plugins/shadow-functions.js' { 211 | declare module.exports: $Exports<'babel-core/lib/transformation/internal-plugins/shadow-functions'>; 212 | } 213 | declare module 'babel-core/lib/transformation/pipeline.js' { 214 | declare module.exports: $Exports<'babel-core/lib/transformation/pipeline'>; 215 | } 216 | declare module 'babel-core/lib/transformation/plugin-pass.js' { 217 | declare module.exports: $Exports<'babel-core/lib/transformation/plugin-pass'>; 218 | } 219 | declare module 'babel-core/lib/transformation/plugin.js' { 220 | declare module.exports: $Exports<'babel-core/lib/transformation/plugin'>; 221 | } 222 | declare module 'babel-core/lib/util.js' { 223 | declare module.exports: $Exports<'babel-core/lib/util'>; 224 | } 225 | declare module 'babel-core/register.js' { 226 | declare module.exports: $Exports<'babel-core/register'>; 227 | } 228 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-loader_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: f755f7e0d9e73c6367d4a54099b5d929 2 | // flow-typed version: <>/babel-loader_v7.0.0-beta.1/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-loader' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-loader' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-loader/lib/fs-cache' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'babel-loader/lib/index' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'babel-loader/lib/resolve-rc' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'babel-loader/lib/utils/exists' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'babel-loader/lib/utils/read' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'babel-loader/lib/utils/relative' { 46 | declare module.exports: any; 47 | } 48 | 49 | // Filename aliases 50 | declare module 'babel-loader/lib/fs-cache.js' { 51 | declare module.exports: $Exports<'babel-loader/lib/fs-cache'>; 52 | } 53 | declare module 'babel-loader/lib/index.js' { 54 | declare module.exports: $Exports<'babel-loader/lib/index'>; 55 | } 56 | declare module 'babel-loader/lib/resolve-rc.js' { 57 | declare module.exports: $Exports<'babel-loader/lib/resolve-rc'>; 58 | } 59 | declare module 'babel-loader/lib/utils/exists.js' { 60 | declare module.exports: $Exports<'babel-loader/lib/utils/exists'>; 61 | } 62 | declare module 'babel-loader/lib/utils/read.js' { 63 | declare module.exports: $Exports<'babel-loader/lib/utils/read'>; 64 | } 65 | declare module 'babel-loader/lib/utils/relative.js' { 66 | declare module.exports: $Exports<'babel-loader/lib/utils/relative'>; 67 | } 68 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-plugin-check-es2015-constants_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 499605b0f6c9037034d6e96c02c14718 2 | // flow-typed version: <>/babel-plugin-check-es2015-constants_v^6.22.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-plugin-check-es2015-constants' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-plugin-check-es2015-constants' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-plugin-check-es2015-constants/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-plugin-check-es2015-constants/lib/index.js' { 31 | declare module.exports: $Exports<'babel-plugin-check-es2015-constants/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-plugin-transform-es2015-destructuring_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 1bef64e62bf4100c1fa2f50bd86dab97 2 | // flow-typed version: <>/babel-plugin-transform-es2015-destructuring_v^6.23.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-plugin-transform-es2015-destructuring' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-plugin-transform-es2015-destructuring' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-plugin-transform-es2015-destructuring/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-plugin-transform-es2015-destructuring/lib/index.js' { 31 | declare module.exports: $Exports<'babel-plugin-transform-es2015-destructuring/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-plugin-transform-es2015-spread_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 7cedad3e1b829d7ac36d135b72ad49cf 2 | // flow-typed version: <>/babel-plugin-transform-es2015-spread_v^6.22.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-plugin-transform-es2015-spread' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-plugin-transform-es2015-spread' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-plugin-transform-es2015-spread/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-plugin-transform-es2015-spread/lib/index.js' { 31 | declare module.exports: $Exports<'babel-plugin-transform-es2015-spread/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-preset-es2015_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: f7e46bf77d2b98cacafa866f00a492a5 2 | // flow-typed version: <>/babel-preset-es2015_v^6.24.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-preset-es2015' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-preset-es2015' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-preset-es2015/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-preset-es2015/lib/index.js' { 31 | declare module.exports: $Exports<'babel-preset-es2015/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-preset-react_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 37b5c757e8232e26c7c69d79e973681b 2 | // flow-typed version: <>/babel-preset-react_v^6.23.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-preset-react' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-preset-react' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-preset-react/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-preset-react/lib/index.js' { 31 | declare module.exports: $Exports<'babel-preset-react/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-preset-stage-0_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 8fe7265d2cc935a5c7c5c537f79ca01f 2 | // flow-typed version: <>/babel-preset-stage-0_v^6.22.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-preset-stage-0' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-preset-stage-0' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-preset-stage-0/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-preset-stage-0/lib/index.js' { 31 | declare module.exports: $Exports<'babel-preset-stage-0/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-register_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6326a2e8fb534e5008c001f4248ec6b0 2 | // flow-typed version: <>/babel-register_v^6.24.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-register' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-register' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-register/lib/browser' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'babel-register/lib/cache' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'babel-register/lib/node' { 34 | declare module.exports: any; 35 | } 36 | 37 | // Filename aliases 38 | declare module 'babel-register/lib/browser.js' { 39 | declare module.exports: $Exports<'babel-register/lib/browser'>; 40 | } 41 | declare module 'babel-register/lib/cache.js' { 42 | declare module.exports: $Exports<'babel-register/lib/cache'>; 43 | } 44 | declare module 'babel-register/lib/node.js' { 45 | declare module.exports: $Exports<'babel-register/lib/node'>; 46 | } 47 | -------------------------------------------------------------------------------- /flow-typed/npm/chai_v3.5.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 777eee7cfcb8f77109f8148b4251bf2d 2 | // flow-typed version: 85e99047c5/chai_v3.5.x/flow_>=v0.24.0 3 | 4 | declare module "chai" { 5 | 6 | declare type ExpectChain = { 7 | and: ExpectChain, 8 | at: ExpectChain, 9 | be: ExpectChain, 10 | been: ExpectChain, 11 | have: ExpectChain, 12 | has: ExpectChain, 13 | is: ExpectChain, 14 | of: ExpectChain, 15 | same: ExpectChain, 16 | that: ExpectChain, 17 | to: ExpectChain, 18 | which: ExpectChain, 19 | with: ExpectChain, 20 | 21 | not: ExpectChain, 22 | deep: ExpectChain, 23 | any: ExpectChain, 24 | all: ExpectChain, 25 | 26 | a: ExpectChain & (type: string) => ExpectChain, 27 | an: ExpectChain & (type: string) => ExpectChain, 28 | 29 | include: ExpectChain & (value: mixed) => ExpectChain, 30 | includes: ExpectChain & (value: mixed) => ExpectChain, 31 | contain: ExpectChain & (value: mixed) => ExpectChain, 32 | contains: ExpectChain & (value: mixed) => ExpectChain, 33 | 34 | eql: (value: T) => ExpectChain, 35 | equal: (value: T) => ExpectChain, 36 | equals: (value: T) => ExpectChain, 37 | 38 | above: (value: T & number) => ExpectChain, 39 | least: (value: T & number) => ExpectChain, 40 | below: (value: T & number) => ExpectChain, 41 | most: (value: T & number) => ExpectChain, 42 | within: (start: T & number, finish: T & number) => ExpectChain, 43 | 44 | instanceof: (constructor: mixed) => ExpectChain, 45 | property: ( 46 |

(name: string, value?: P) => ExpectChain

47 | & (name: string) => ExpectChain 48 | ), 49 | 50 | length: (value: number) => ExpectChain | ExpectChain, 51 | lengthOf: (value: number) => ExpectChain, 52 | 53 | match: (regex: RegExp) => ExpectChain, 54 | string: (string: string) => ExpectChain, 55 | 56 | key: (key: string) => ExpectChain, 57 | keys: (key: string | Array, ...keys: Array) => ExpectChain, 58 | 59 | throw: ( 60 | err: Class | Error | RegExp | string, 61 | errMsgMatcher?: RegExp | string, 62 | msg?: string) => ExpectChain, 63 | 64 | respondTo: (method: string) => ExpectChain, 65 | itself: ExpectChain, 66 | 67 | satisfy: (method: (value: T) => bool) => ExpectChain, 68 | 69 | closeTo: (expected: T & number, delta: number) => ExpectChain, 70 | 71 | members: (set: mixed) => ExpectChain, 72 | oneOf: (list: Array) => ExpectChain, 73 | 74 | change: (obj: mixed, key: string) => ExpectChain, 75 | increase: (obj: mixed, key: string) => ExpectChain, 76 | decrease: (obj: mixed, key: string) => ExpectChain, 77 | 78 | // dirty-chai 79 | ok: () => ExpectChain, 80 | true: () => ExpectChain, 81 | false: () => ExpectChain, 82 | null: () => ExpectChain, 83 | undefined: () => ExpectChain, 84 | exist: () => ExpectChain, 85 | empty: () => ExpectChain, 86 | 87 | // chai-immutable 88 | size: (n: number) => ExpectChain, 89 | 90 | // sinon-chai 91 | called: () => ExpectChain, 92 | callCount: (n: number) => ExpectChain, 93 | calledOnce: () => ExpectChain, 94 | calledBefore: (spy: mixed) => ExpectChain, 95 | calledAfter: (spy: mixed) => ExpectChain, 96 | calledWith: (...args: Array) => ExpectChain, 97 | calledWithMatch: (...args: Array) => ExpectChain, 98 | calledWithExactly: (...args: Array) => ExpectChain, 99 | 100 | // chai-as-promised 101 | eventually: ExpectChain, 102 | resolvedWith: (value: mixed) => Promise & ExpectChain, 103 | resolved: () => Promise & ExpectChain, 104 | rejectedWith: (value: mixed) => Promise & ExpectChain, 105 | rejected: () => Promise & ExpectChain, 106 | notify: (callback: () => mixed) => ExpectChain, 107 | }; 108 | 109 | declare function expect(actual: T): ExpectChain; 110 | 111 | declare function use(plugin: (chai: Object, utils: Object) => void): void; 112 | 113 | declare class assert { 114 | static(expression: mixed, message?: string): void; 115 | static fail(actual: mixed, expected: mixed, message?: string, operator?: string): void; 116 | 117 | static isOk(object: mixed, message?: string): void; 118 | static isNotOk(object: mixed, message?: string): void; 119 | 120 | static equal(actual: mixed, expected: mixed, message?: string): void; 121 | static notEqual(actual: mixed, expected: mixed, message?: string): void; 122 | 123 | static strictEqual(act: mixed, exp: mixed, msg?: string): void; 124 | static notStrictEqual(act: mixed, exp: mixed, msg?: string): void; 125 | 126 | static deepEqual(act: mixed, exp: mixed, msg?: string): void; 127 | static notDeepEqual(act: mixed, exp: mixed, msg?: string): void; 128 | 129 | static isTrue(val: mixed, msg?: string): void; 130 | static isNotTrue(val: mixed, msg?: string): void; 131 | static isFalse(val: mixed, msg?: string): void; 132 | static isNotFalse(val: mixed, msg?: string): void; 133 | 134 | static isNull(val: mixed, msg?: string): void; 135 | static isNotNull(val: mixed, msg?: string): void; 136 | 137 | static isUndefined(val: mixed, msg?: string): void; 138 | static isDefined(val: mixed, msg?: string): void; 139 | 140 | static isNaN(val: mixed, msg?: string): void; 141 | static isNotNaN(val: mixed, msg?: string): void; 142 | 143 | static isAbove(val: number, abv: number, msg?: string): void; 144 | static isBelow(val: number, blw: number, msg?: string): void; 145 | 146 | static isAtMost(val: number, atmst: number, msg?: string): void; 147 | static isAtLeast(val: number, atlst: number, msg?: string): void; 148 | 149 | static isFunction(val: mixed, msg?: string): void; 150 | static isNotFunction(val: mixed, msg?: string): void; 151 | 152 | static isObject(val: mixed, msg?: string): void; 153 | static isNotObject(val: mixed, msg?: string): void; 154 | 155 | static isArray(val: mixed, msg?: string): void; 156 | static isNotArray(val: mixed, msg?: string): void; 157 | 158 | static isString(val: mixed, msg?: string): void; 159 | static isNotString(val: mixed, msg?: string): void; 160 | 161 | static isNumber(val: mixed, msg?: string): void; 162 | static isNotNumber(val: mixed, msg?: string): void; 163 | 164 | static isBoolean(val: mixed, msg?: string): void; 165 | static isNotBoolean(val: mixed, msg?: string): void; 166 | 167 | static typeOf(val: mixed, type: string, msg?: string): void; 168 | static notTypeOf(val: mixed, type: string, msg?: string): void; 169 | 170 | static instanceOf(val: mixed, constructor: Function, msg?: string): void; 171 | static notInstanceOf(val: mixed, constructor: Function, msg?: string): void; 172 | 173 | static include(exp: string, inc: mixed, msg?: string): void; 174 | static include(exp: Array, inc: T, msg?: string): void; 175 | 176 | static notInclude(exp: string, inc: mixed, msg?: string): void; 177 | static notInclude(exp: Array, inc: T, msg?: string): void; 178 | 179 | static match(exp: mixed, re: RegExp, msg?: string): void; 180 | static notMatch(exp: mixed, re: RegExp, msg?: string): void; 181 | 182 | static property(obj: Object, prop: string, msg?: string): void; 183 | static notProperty(obj: Object, prop: string, msg?: string): void; 184 | static deepProperty(obj: Object, prop: string, msg?: string): void; 185 | static notDeepProperty(obj: Object, prop: string, msg?: string): void; 186 | 187 | static propertyVal(obj: Object, prop: string, val: mixed, msg?: string): void; 188 | static propertyNotVal(obj: Object, prop: string, val: mixed, msg?: string): void; 189 | 190 | static deepPropertyVal(obj: Object, prop: string, val: mixed, msg?: string): void; 191 | static deepPropertyNotVal(obj: Object, prop: string, val: mixed, msg?: string): void; 192 | 193 | static lengthOf(exp: mixed, len: number, msg?: string): void; 194 | 195 | static throws( 196 | func: () => any, 197 | err?: Class | Error | RegExp | string, 198 | errorMsgMatcher?: string | RegExp, 199 | msg?: string): void; 200 | static doesNotThrow( 201 | func: () => any, 202 | err?: Class | Error | RegExp | string, 203 | errorMsgMatcher?: string | RegExp, 204 | msg?: string): void; 205 | } 206 | 207 | declare var config: { 208 | includeStack: boolean, 209 | showDiff: boolean, 210 | truncateThreshold: number 211 | }; 212 | } 213 | -------------------------------------------------------------------------------- /flow-typed/npm/css-loader_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 1374ac485e2f00db7b4fe91c8595fa47 2 | // flow-typed version: <>/css-loader_v^0.27.3/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'css-loader' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'css-loader' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'css-loader/lib/compile-exports' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'css-loader/lib/css-base' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'css-loader/lib/getImportPrefix' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'css-loader/lib/getLocalIdent' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'css-loader/lib/loader' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'css-loader/lib/localsLoader' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'css-loader/lib/processCss' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'css-loader/locals' { 54 | declare module.exports: any; 55 | } 56 | 57 | // Filename aliases 58 | declare module 'css-loader/index' { 59 | declare module.exports: $Exports<'css-loader'>; 60 | } 61 | declare module 'css-loader/index.js' { 62 | declare module.exports: $Exports<'css-loader'>; 63 | } 64 | declare module 'css-loader/lib/compile-exports.js' { 65 | declare module.exports: $Exports<'css-loader/lib/compile-exports'>; 66 | } 67 | declare module 'css-loader/lib/css-base.js' { 68 | declare module.exports: $Exports<'css-loader/lib/css-base'>; 69 | } 70 | declare module 'css-loader/lib/getImportPrefix.js' { 71 | declare module.exports: $Exports<'css-loader/lib/getImportPrefix'>; 72 | } 73 | declare module 'css-loader/lib/getLocalIdent.js' { 74 | declare module.exports: $Exports<'css-loader/lib/getLocalIdent'>; 75 | } 76 | declare module 'css-loader/lib/loader.js' { 77 | declare module.exports: $Exports<'css-loader/lib/loader'>; 78 | } 79 | declare module 'css-loader/lib/localsLoader.js' { 80 | declare module.exports: $Exports<'css-loader/lib/localsLoader'>; 81 | } 82 | declare module 'css-loader/lib/processCss.js' { 83 | declare module.exports: $Exports<'css-loader/lib/processCss'>; 84 | } 85 | declare module 'css-loader/locals.js' { 86 | declare module.exports: $Exports<'css-loader/locals'>; 87 | } 88 | -------------------------------------------------------------------------------- /flow-typed/npm/electron-builder_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: a5e6afdd8aac06bba8eefba1fcecaeb3 2 | // flow-typed version: <>/electron-builder_v^16.2.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'electron-builder' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'electron-builder' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'electron-builder/out/appInfo' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'electron-builder/out/asar' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'electron-builder/out/asarUtil' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'electron-builder/out/builder' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'electron-builder/out/cli/build-cli' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'electron-builder/out/cli/cliOptions' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'electron-builder/out/cli/create-self-signed-cert' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'electron-builder/out/cli/install-app-deps' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'electron-builder/out/cli/node-gyp-rebuild' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'electron-builder/out/codeSign' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'electron-builder/out/errorMessages' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'electron-builder/out/fileMatcher' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'electron-builder/out/fileTransformer' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'electron-builder/out/forge/forge-maker' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'electron-builder/out/index' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module 'electron-builder/out/linuxPackager' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module 'electron-builder/out/macPackager' { 90 | declare module.exports: any; 91 | } 92 | 93 | declare module 'electron-builder/out/metadata' { 94 | declare module.exports: any; 95 | } 96 | 97 | declare module 'electron-builder/out/options/linuxOptions' { 98 | declare module.exports: any; 99 | } 100 | 101 | declare module 'electron-builder/out/options/macOptions' { 102 | declare module.exports: any; 103 | } 104 | 105 | declare module 'electron-builder/out/options/winOptions' { 106 | declare module.exports: any; 107 | } 108 | 109 | declare module 'electron-builder/out/packager' { 110 | declare module.exports: any; 111 | } 112 | 113 | declare module 'electron-builder/out/packager/dirPackager' { 114 | declare module.exports: any; 115 | } 116 | 117 | declare module 'electron-builder/out/packager/mac' { 118 | declare module.exports: any; 119 | } 120 | 121 | declare module 'electron-builder/out/packagerApi' { 122 | declare module.exports: any; 123 | } 124 | 125 | declare module 'electron-builder/out/platformPackager' { 126 | declare module.exports: any; 127 | } 128 | 129 | declare module 'electron-builder/out/publish/PublishManager' { 130 | declare module.exports: any; 131 | } 132 | 133 | declare module 'electron-builder/out/readInstalled' { 134 | declare module.exports: any; 135 | } 136 | 137 | declare module 'electron-builder/out/repositoryInfo' { 138 | declare module.exports: any; 139 | } 140 | 141 | declare module 'electron-builder/out/targets/appImage' { 142 | declare module.exports: any; 143 | } 144 | 145 | declare module 'electron-builder/out/targets/appx' { 146 | declare module.exports: any; 147 | } 148 | 149 | declare module 'electron-builder/out/targets/archive' { 150 | declare module.exports: any; 151 | } 152 | 153 | declare module 'electron-builder/out/targets/ArchiveTarget' { 154 | declare module.exports: any; 155 | } 156 | 157 | declare module 'electron-builder/out/targets/dmg' { 158 | declare module.exports: any; 159 | } 160 | 161 | declare module 'electron-builder/out/targets/fpm' { 162 | declare module.exports: any; 163 | } 164 | 165 | declare module 'electron-builder/out/targets/LinuxTargetHelper' { 166 | declare module.exports: any; 167 | } 168 | 169 | declare module 'electron-builder/out/targets/nsis' { 170 | declare module.exports: any; 171 | } 172 | 173 | declare module 'electron-builder/out/targets/pkg' { 174 | declare module.exports: any; 175 | } 176 | 177 | declare module 'electron-builder/out/targets/snap' { 178 | declare module.exports: any; 179 | } 180 | 181 | declare module 'electron-builder/out/targets/targetFactory' { 182 | declare module.exports: any; 183 | } 184 | 185 | declare module 'electron-builder/out/targets/WebInstaller' { 186 | declare module.exports: any; 187 | } 188 | 189 | declare module 'electron-builder/out/util/filter' { 190 | declare module.exports: any; 191 | } 192 | 193 | declare module 'electron-builder/out/util/readPackageJson' { 194 | declare module.exports: any; 195 | } 196 | 197 | declare module 'electron-builder/out/windowsCodeSign' { 198 | declare module.exports: any; 199 | } 200 | 201 | declare module 'electron-builder/out/winPackager' { 202 | declare module.exports: any; 203 | } 204 | 205 | declare module 'electron-builder/out/yarn' { 206 | declare module.exports: any; 207 | } 208 | 209 | // Filename aliases 210 | declare module 'electron-builder/out/appInfo.js' { 211 | declare module.exports: $Exports<'electron-builder/out/appInfo'>; 212 | } 213 | declare module 'electron-builder/out/asar.js' { 214 | declare module.exports: $Exports<'electron-builder/out/asar'>; 215 | } 216 | declare module 'electron-builder/out/asarUtil.js' { 217 | declare module.exports: $Exports<'electron-builder/out/asarUtil'>; 218 | } 219 | declare module 'electron-builder/out/builder.js' { 220 | declare module.exports: $Exports<'electron-builder/out/builder'>; 221 | } 222 | declare module 'electron-builder/out/cli/build-cli.js' { 223 | declare module.exports: $Exports<'electron-builder/out/cli/build-cli'>; 224 | } 225 | declare module 'electron-builder/out/cli/cliOptions.js' { 226 | declare module.exports: $Exports<'electron-builder/out/cli/cliOptions'>; 227 | } 228 | declare module 'electron-builder/out/cli/create-self-signed-cert.js' { 229 | declare module.exports: $Exports<'electron-builder/out/cli/create-self-signed-cert'>; 230 | } 231 | declare module 'electron-builder/out/cli/install-app-deps.js' { 232 | declare module.exports: $Exports<'electron-builder/out/cli/install-app-deps'>; 233 | } 234 | declare module 'electron-builder/out/cli/node-gyp-rebuild.js' { 235 | declare module.exports: $Exports<'electron-builder/out/cli/node-gyp-rebuild'>; 236 | } 237 | declare module 'electron-builder/out/codeSign.js' { 238 | declare module.exports: $Exports<'electron-builder/out/codeSign'>; 239 | } 240 | declare module 'electron-builder/out/errorMessages.js' { 241 | declare module.exports: $Exports<'electron-builder/out/errorMessages'>; 242 | } 243 | declare module 'electron-builder/out/fileMatcher.js' { 244 | declare module.exports: $Exports<'electron-builder/out/fileMatcher'>; 245 | } 246 | declare module 'electron-builder/out/fileTransformer.js' { 247 | declare module.exports: $Exports<'electron-builder/out/fileTransformer'>; 248 | } 249 | declare module 'electron-builder/out/forge/forge-maker.js' { 250 | declare module.exports: $Exports<'electron-builder/out/forge/forge-maker'>; 251 | } 252 | declare module 'electron-builder/out/index.js' { 253 | declare module.exports: $Exports<'electron-builder/out/index'>; 254 | } 255 | declare module 'electron-builder/out/linuxPackager.js' { 256 | declare module.exports: $Exports<'electron-builder/out/linuxPackager'>; 257 | } 258 | declare module 'electron-builder/out/macPackager.js' { 259 | declare module.exports: $Exports<'electron-builder/out/macPackager'>; 260 | } 261 | declare module 'electron-builder/out/metadata.js' { 262 | declare module.exports: $Exports<'electron-builder/out/metadata'>; 263 | } 264 | declare module 'electron-builder/out/options/linuxOptions.js' { 265 | declare module.exports: $Exports<'electron-builder/out/options/linuxOptions'>; 266 | } 267 | declare module 'electron-builder/out/options/macOptions.js' { 268 | declare module.exports: $Exports<'electron-builder/out/options/macOptions'>; 269 | } 270 | declare module 'electron-builder/out/options/winOptions.js' { 271 | declare module.exports: $Exports<'electron-builder/out/options/winOptions'>; 272 | } 273 | declare module 'electron-builder/out/packager.js' { 274 | declare module.exports: $Exports<'electron-builder/out/packager'>; 275 | } 276 | declare module 'electron-builder/out/packager/dirPackager.js' { 277 | declare module.exports: $Exports<'electron-builder/out/packager/dirPackager'>; 278 | } 279 | declare module 'electron-builder/out/packager/mac.js' { 280 | declare module.exports: $Exports<'electron-builder/out/packager/mac'>; 281 | } 282 | declare module 'electron-builder/out/packagerApi.js' { 283 | declare module.exports: $Exports<'electron-builder/out/packagerApi'>; 284 | } 285 | declare module 'electron-builder/out/platformPackager.js' { 286 | declare module.exports: $Exports<'electron-builder/out/platformPackager'>; 287 | } 288 | declare module 'electron-builder/out/publish/PublishManager.js' { 289 | declare module.exports: $Exports<'electron-builder/out/publish/PublishManager'>; 290 | } 291 | declare module 'electron-builder/out/readInstalled.js' { 292 | declare module.exports: $Exports<'electron-builder/out/readInstalled'>; 293 | } 294 | declare module 'electron-builder/out/repositoryInfo.js' { 295 | declare module.exports: $Exports<'electron-builder/out/repositoryInfo'>; 296 | } 297 | declare module 'electron-builder/out/targets/appImage.js' { 298 | declare module.exports: $Exports<'electron-builder/out/targets/appImage'>; 299 | } 300 | declare module 'electron-builder/out/targets/appx.js' { 301 | declare module.exports: $Exports<'electron-builder/out/targets/appx'>; 302 | } 303 | declare module 'electron-builder/out/targets/archive.js' { 304 | declare module.exports: $Exports<'electron-builder/out/targets/archive'>; 305 | } 306 | declare module 'electron-builder/out/targets/ArchiveTarget.js' { 307 | declare module.exports: $Exports<'electron-builder/out/targets/ArchiveTarget'>; 308 | } 309 | declare module 'electron-builder/out/targets/dmg.js' { 310 | declare module.exports: $Exports<'electron-builder/out/targets/dmg'>; 311 | } 312 | declare module 'electron-builder/out/targets/fpm.js' { 313 | declare module.exports: $Exports<'electron-builder/out/targets/fpm'>; 314 | } 315 | declare module 'electron-builder/out/targets/LinuxTargetHelper.js' { 316 | declare module.exports: $Exports<'electron-builder/out/targets/LinuxTargetHelper'>; 317 | } 318 | declare module 'electron-builder/out/targets/nsis.js' { 319 | declare module.exports: $Exports<'electron-builder/out/targets/nsis'>; 320 | } 321 | declare module 'electron-builder/out/targets/pkg.js' { 322 | declare module.exports: $Exports<'electron-builder/out/targets/pkg'>; 323 | } 324 | declare module 'electron-builder/out/targets/snap.js' { 325 | declare module.exports: $Exports<'electron-builder/out/targets/snap'>; 326 | } 327 | declare module 'electron-builder/out/targets/targetFactory.js' { 328 | declare module.exports: $Exports<'electron-builder/out/targets/targetFactory'>; 329 | } 330 | declare module 'electron-builder/out/targets/WebInstaller.js' { 331 | declare module.exports: $Exports<'electron-builder/out/targets/WebInstaller'>; 332 | } 333 | declare module 'electron-builder/out/util/filter.js' { 334 | declare module.exports: $Exports<'electron-builder/out/util/filter'>; 335 | } 336 | declare module 'electron-builder/out/util/readPackageJson.js' { 337 | declare module.exports: $Exports<'electron-builder/out/util/readPackageJson'>; 338 | } 339 | declare module 'electron-builder/out/windowsCodeSign.js' { 340 | declare module.exports: $Exports<'electron-builder/out/windowsCodeSign'>; 341 | } 342 | declare module 'electron-builder/out/winPackager.js' { 343 | declare module.exports: $Exports<'electron-builder/out/winPackager'>; 344 | } 345 | declare module 'electron-builder/out/yarn.js' { 346 | declare module.exports: $Exports<'electron-builder/out/yarn'>; 347 | } 348 | -------------------------------------------------------------------------------- /flow-typed/npm/electron_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 3c7af70aae9b5987e729a69891fc4347 2 | // flow-typed version: <>/electron_v^1.6.2/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'electron' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'electron' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'electron/cli' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'electron/install' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'electron/test/errors' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'electron/test/index' { 38 | declare module.exports: any; 39 | } 40 | 41 | // Filename aliases 42 | declare module 'electron/cli.js' { 43 | declare module.exports: $Exports<'electron/cli'>; 44 | } 45 | declare module 'electron/index' { 46 | declare module.exports: $Exports<'electron'>; 47 | } 48 | declare module 'electron/index.js' { 49 | declare module.exports: $Exports<'electron'>; 50 | } 51 | declare module 'electron/install.js' { 52 | declare module.exports: $Exports<'electron/install'>; 53 | } 54 | declare module 'electron/test/errors.js' { 55 | declare module.exports: $Exports<'electron/test/errors'>; 56 | } 57 | declare module 'electron/test/index.js' { 58 | declare module.exports: $Exports<'electron/test/index'>; 59 | } 60 | -------------------------------------------------------------------------------- /flow-typed/npm/express_v4.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 5800b9dee6b8969ab2b5fa338d02a89f 2 | // flow-typed version: 473c121609/express_v4.x.x/flow_>=v0.32.x 3 | 4 | import type { Server } from 'http'; 5 | 6 | declare type express$RouterOptions = { 7 | caseSensitive?: boolean, 8 | mergeParams?: boolean, 9 | strict?: boolean 10 | }; 11 | 12 | declare class express$RequestResponseBase { 13 | app: express$Application; 14 | get(field: string): string | void; 15 | } 16 | 17 | declare class express$Request extends http$IncomingMessage mixins express$RequestResponseBase { 18 | baseUrl: string; 19 | body: mixed; 20 | cookies: {[cookie: string]: string}; 21 | fresh: boolean; 22 | hostname: string; 23 | ip: string; 24 | ips: Array; 25 | method: string; 26 | originalUrl: string; 27 | params: {[param: string]: string}; 28 | path: string; 29 | protocol: 'https' | 'http'; 30 | query: {[name: string]: string}; 31 | route: string; 32 | secure: boolean; 33 | signedCookies: {[signedCookie: string]: string}; 34 | stale: boolean; 35 | subdomains: Array; 36 | xhr: boolean; 37 | accepts(types: string): string | false; 38 | acceptsCharsets(...charsets: Array): string | false; 39 | acceptsEncodings(...encoding: Array): string | false; 40 | acceptsLanguages(...lang: Array): string | false; 41 | header(field: string): string | void; 42 | is(type: string): boolean; 43 | param(name: string, defaultValue?: string): string | void; 44 | } 45 | 46 | declare type express$CookieOptions = { 47 | domain?: string, 48 | encode?: (value: string) => string, 49 | expires?: Date, 50 | httpOnly?: boolean, 51 | maxAge?: number, 52 | path?: string, 53 | secure?: boolean, 54 | signed?: boolean 55 | }; 56 | 57 | declare type express$RenderCallback = (err: Error | null, html?: string) => mixed; 58 | 59 | declare type express$SendFileOptions = { 60 | maxAge?: number, 61 | root?: string, 62 | lastModified?: boolean, 63 | headers?: {[name: string]: string}, 64 | dotfiles?: 'allow' | 'deny' | 'ignore' 65 | }; 66 | 67 | declare class express$Response extends http$ServerResponse mixins express$RequestResponseBase { 68 | headersSent: boolean; 69 | locals: {[name: string]: mixed}; 70 | append(field: string, value?: string): this; 71 | attachment(filename?: string): this; 72 | cookie(name: string, value: string, options?: express$CookieOptions): this; 73 | clearCookie(name: string, options?: express$CookieOptions): this; 74 | download(path: string, filename?: string, callback?: (err?: ?Error) => void): this; 75 | format(typesObject: {[type: string]: Function}): this; 76 | json(body?: mixed): this; 77 | jsonp(body?: mixed): this; 78 | links(links: {[name: string]: string}): this; 79 | location(path: string): this; 80 | redirect(url: string, ...args: Array): this; 81 | redirect(status: number, url: string, ...args: Array): this; 82 | render(view: string, locals?: {[name: string]: mixed}, callback?: express$RenderCallback): this; 83 | send(body?: mixed): this; 84 | sendFile(path: string, options?: express$SendFileOptions, callback?: (err?: ?Error) => mixed): this; 85 | sendStatus(statusCode: number): this; 86 | header(field: string, value?: string): this; 87 | header(headers: {[name: string]: string}): this; 88 | set(field: string, value?: string): this; 89 | set(headers: {[name: string]: string}): this; 90 | status(statusCode: number): this; 91 | type(type: string): this; 92 | vary(field: string): this; 93 | } 94 | 95 | declare type express$NextFunction = (err?: ?Error) => mixed; 96 | declare type express$Middleware = 97 | ((req: express$Request, res: express$Response, next: express$NextFunction) => mixed) | 98 | ((error: ?Error, req: express$Request, res: express$Response, next: express$NextFunction) => mixed); 99 | declare interface express$RouteMethodType { 100 | (middleware: express$Middleware): T; 101 | (...middleware: Array): T; 102 | (path: string|RegExp|string[], ...middleware: Array): T; 103 | } 104 | declare class express$Route { 105 | all: express$RouteMethodType; 106 | get: express$RouteMethodType; 107 | post: express$RouteMethodType; 108 | put: express$RouteMethodType; 109 | head: express$RouteMethodType; 110 | delete: express$RouteMethodType; 111 | options: express$RouteMethodType; 112 | trace: express$RouteMethodType; 113 | copy: express$RouteMethodType; 114 | lock: express$RouteMethodType; 115 | mkcol: express$RouteMethodType; 116 | move: express$RouteMethodType; 117 | purge: express$RouteMethodType; 118 | propfind: express$RouteMethodType; 119 | proppatch: express$RouteMethodType; 120 | unlock: express$RouteMethodType; 121 | report: express$RouteMethodType; 122 | mkactivity: express$RouteMethodType; 123 | checkout: express$RouteMethodType; 124 | merge: express$RouteMethodType; 125 | 126 | // @TODO Missing 'm-search' but get flow illegal name error. 127 | 128 | notify: express$RouteMethodType; 129 | subscribe: express$RouteMethodType; 130 | unsubscribe: express$RouteMethodType; 131 | patch: express$RouteMethodType; 132 | search: express$RouteMethodType; 133 | connect: express$RouteMethodType; 134 | } 135 | 136 | declare class express$Router extends express$Route { 137 | constructor(options?: express$RouterOptions): void; 138 | route(path: string): express$Route; 139 | static (): express$Router; 140 | use(middleware: express$Middleware): this; 141 | use(...middleware: Array): this; 142 | use(path: string|RegExp|string[], ...middleware: Array): this; 143 | use(path: string, router: express$Router): this; 144 | handle(req: http$IncomingMessage, res: http$ServerResponse, next: express$NextFunction): void; 145 | 146 | // Can't use regular callable signature syntax due to https://github.com/facebook/flow/issues/3084 147 | $call: (req: http$IncomingMessage, res: http$ServerResponse, next?: ?express$NextFunction) => void; 148 | } 149 | 150 | declare class express$Application extends express$Router mixins events$EventEmitter { 151 | constructor(): void; 152 | locals: {[name: string]: mixed}; 153 | mountpath: string; 154 | listen(port: number, hostname?: string, backlog?: number, callback?: (err?: ?Error) => mixed): Server; 155 | listen(port: number, hostname?: string, callback?: (err?: ?Error) => mixed): Server; 156 | listen(port: number, callback?: (err?: ?Error) => mixed): Server; 157 | listen(path: string, callback?: (err?: ?Error) => mixed): Server; 158 | listen(handle: Object, callback?: (err?: ?Error) => mixed): Server; 159 | disable(name: string): void; 160 | disabled(name: string): boolean; 161 | enable(name: string): void; 162 | enabled(name: string): boolean; 163 | engine(name: string, callback: Function): void; 164 | /** 165 | * Mixed will not be taken as a value option. Issue around using the GET http method name and the get for settings. 166 | */ 167 | // get(name: string): mixed; 168 | set(name: string, value: mixed): mixed; 169 | render(name: string, optionsOrFunction: {[name: string]: mixed}, callback: express$RenderCallback): void; 170 | handle(req: http$IncomingMessage, res: http$ServerResponse, next?: ?express$NextFunction): void; 171 | } 172 | 173 | declare module 'express' { 174 | declare function serveStatic(root: string, options?: Object): express$Middleware; 175 | 176 | declare type RouterOptions = express$RouterOptions; 177 | declare type CookieOptions = express$CookieOptions; 178 | declare type Middleware = express$Middleware; 179 | declare type NextFunction = express$NextFunction; 180 | declare type $Response = express$Response; 181 | declare type $Request = express$Request; 182 | declare type $Application = express$Application; 183 | 184 | declare module.exports: { 185 | (): express$Application, // If you try to call like a function, it will use this signature 186 | static: serveStatic, // `static` property on the function 187 | Router: typeof express$Router, // `Router` property on the function 188 | }; 189 | } 190 | -------------------------------------------------------------------------------- /flow-typed/npm/file-loader_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 682b78ca577539915ebadd4b3ada6bad 2 | // flow-typed version: <>/file-loader_v^0.10.1/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'file-loader' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'file-loader' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | 26 | 27 | // Filename aliases 28 | declare module 'file-loader/index' { 29 | declare module.exports: $Exports<'file-loader'>; 30 | } 31 | declare module 'file-loader/index.js' { 32 | declare module.exports: $Exports<'file-loader'>; 33 | } 34 | -------------------------------------------------------------------------------- /flow-typed/npm/flow-bin_v0.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583 2 | // flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x 3 | 4 | declare module "flow-bin" { 5 | declare module.exports: string; 6 | } 7 | -------------------------------------------------------------------------------- /flow-typed/npm/flow-typed_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: d208dc449ce18eef386c90095e4b24fc 2 | // flow-typed version: <>/flow-typed_v^2.0.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'flow-typed' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'flow-typed' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'flow-typed/dist/cli' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'flow-typed/dist/commands/create-stub' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'flow-typed/dist/commands/install' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'flow-typed/dist/commands/runTests' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'flow-typed/dist/commands/search' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'flow-typed/dist/commands/update-cache' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'flow-typed/dist/commands/update' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'flow-typed/dist/commands/validateDefs' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'flow-typed/dist/commands/version' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'flow-typed/dist/lib/codeSign' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'flow-typed/dist/lib/fileUtils' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'flow-typed/dist/lib/flowProjectUtils' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'flow-typed/dist/lib/git' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'flow-typed/dist/lib/github' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'flow-typed/dist/lib/libDefs' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module 'flow-typed/dist/lib/node' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module 'flow-typed/dist/lib/npmProjectUtils' { 90 | declare module.exports: any; 91 | } 92 | 93 | declare module 'flow-typed/dist/lib/semver' { 94 | declare module.exports: any; 95 | } 96 | 97 | declare module 'flow-typed/dist/lib/stubUtils' { 98 | declare module.exports: any; 99 | } 100 | 101 | // Filename aliases 102 | declare module 'flow-typed/dist/cli.js' { 103 | declare module.exports: $Exports<'flow-typed/dist/cli'>; 104 | } 105 | declare module 'flow-typed/dist/commands/create-stub.js' { 106 | declare module.exports: $Exports<'flow-typed/dist/commands/create-stub'>; 107 | } 108 | declare module 'flow-typed/dist/commands/install.js' { 109 | declare module.exports: $Exports<'flow-typed/dist/commands/install'>; 110 | } 111 | declare module 'flow-typed/dist/commands/runTests.js' { 112 | declare module.exports: $Exports<'flow-typed/dist/commands/runTests'>; 113 | } 114 | declare module 'flow-typed/dist/commands/search.js' { 115 | declare module.exports: $Exports<'flow-typed/dist/commands/search'>; 116 | } 117 | declare module 'flow-typed/dist/commands/update-cache.js' { 118 | declare module.exports: $Exports<'flow-typed/dist/commands/update-cache'>; 119 | } 120 | declare module 'flow-typed/dist/commands/update.js' { 121 | declare module.exports: $Exports<'flow-typed/dist/commands/update'>; 122 | } 123 | declare module 'flow-typed/dist/commands/validateDefs.js' { 124 | declare module.exports: $Exports<'flow-typed/dist/commands/validateDefs'>; 125 | } 126 | declare module 'flow-typed/dist/commands/version.js' { 127 | declare module.exports: $Exports<'flow-typed/dist/commands/version'>; 128 | } 129 | declare module 'flow-typed/dist/lib/codeSign.js' { 130 | declare module.exports: $Exports<'flow-typed/dist/lib/codeSign'>; 131 | } 132 | declare module 'flow-typed/dist/lib/fileUtils.js' { 133 | declare module.exports: $Exports<'flow-typed/dist/lib/fileUtils'>; 134 | } 135 | declare module 'flow-typed/dist/lib/flowProjectUtils.js' { 136 | declare module.exports: $Exports<'flow-typed/dist/lib/flowProjectUtils'>; 137 | } 138 | declare module 'flow-typed/dist/lib/git.js' { 139 | declare module.exports: $Exports<'flow-typed/dist/lib/git'>; 140 | } 141 | declare module 'flow-typed/dist/lib/github.js' { 142 | declare module.exports: $Exports<'flow-typed/dist/lib/github'>; 143 | } 144 | declare module 'flow-typed/dist/lib/libDefs.js' { 145 | declare module.exports: $Exports<'flow-typed/dist/lib/libDefs'>; 146 | } 147 | declare module 'flow-typed/dist/lib/node.js' { 148 | declare module.exports: $Exports<'flow-typed/dist/lib/node'>; 149 | } 150 | declare module 'flow-typed/dist/lib/npmProjectUtils.js' { 151 | declare module.exports: $Exports<'flow-typed/dist/lib/npmProjectUtils'>; 152 | } 153 | declare module 'flow-typed/dist/lib/semver.js' { 154 | declare module.exports: $Exports<'flow-typed/dist/lib/semver'>; 155 | } 156 | declare module 'flow-typed/dist/lib/stubUtils.js' { 157 | declare module.exports: $Exports<'flow-typed/dist/lib/stubUtils'>; 158 | } 159 | -------------------------------------------------------------------------------- /flow-typed/npm/html-webpack-plugin_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: f054d5c8e131390bece3b43f1da76f6f 2 | // flow-typed version: <>/html-webpack-plugin_v^2.28.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'html-webpack-plugin' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'html-webpack-plugin' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'html-webpack-plugin/lib/chunksorter' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'html-webpack-plugin/lib/compiler' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'html-webpack-plugin/lib/errors' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'html-webpack-plugin/lib/loader' { 38 | declare module.exports: any; 39 | } 40 | 41 | // Filename aliases 42 | declare module 'html-webpack-plugin/index' { 43 | declare module.exports: $Exports<'html-webpack-plugin'>; 44 | } 45 | declare module 'html-webpack-plugin/index.js' { 46 | declare module.exports: $Exports<'html-webpack-plugin'>; 47 | } 48 | declare module 'html-webpack-plugin/lib/chunksorter.js' { 49 | declare module.exports: $Exports<'html-webpack-plugin/lib/chunksorter'>; 50 | } 51 | declare module 'html-webpack-plugin/lib/compiler.js' { 52 | declare module.exports: $Exports<'html-webpack-plugin/lib/compiler'>; 53 | } 54 | declare module 'html-webpack-plugin/lib/errors.js' { 55 | declare module.exports: $Exports<'html-webpack-plugin/lib/errors'>; 56 | } 57 | declare module 'html-webpack-plugin/lib/loader.js' { 58 | declare module.exports: $Exports<'html-webpack-plugin/lib/loader'>; 59 | } 60 | -------------------------------------------------------------------------------- /flow-typed/npm/json-loader_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: e3baa315cc326b6970ff976b78a213c4 2 | // flow-typed version: <>/json-loader_v^0.5.4/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'json-loader' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'json-loader' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | 26 | 27 | // Filename aliases 28 | declare module 'json-loader/index' { 29 | declare module.exports: $Exports<'json-loader'>; 30 | } 31 | declare module 'json-loader/index.js' { 32 | declare module.exports: $Exports<'json-loader'>; 33 | } 34 | -------------------------------------------------------------------------------- /flow-typed/npm/mocha-webpack_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 5a69b7448475b9ffc6f22106242a2930 2 | // flow-typed version: <>/mocha-webpack_v^0.7.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'mocha-webpack' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'mocha-webpack' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'mocha-webpack/lib/cli/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'mocha-webpack/lib/cli/parseArgv' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'mocha-webpack/lib/cli/parseConfig' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'mocha-webpack/lib/cli/prepareWebpack' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'mocha-webpack/lib/cli/requireWebpackConfig' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'mocha-webpack/lib/cli/runner' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'mocha-webpack/lib/mocha/checkReporter' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'mocha-webpack/lib/mocha/configureMocha' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'mocha-webpack/lib/mocha/resetMocha' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'mocha-webpack/lib/reporters/base' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'mocha-webpack/lib/util/exists' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'mocha-webpack/lib/utils' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'mocha-webpack/lib/webpack/build' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'mocha-webpack/lib/webpack/contextReplacementPlugin' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'mocha-webpack/lib/webpack/createCompiler' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module 'mocha-webpack/lib/webpack/includeFilesLoader' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module 'mocha-webpack/lib/webpack/InjectChangedFilesPlugin' { 90 | declare module.exports: any; 91 | } 92 | 93 | declare module 'mocha-webpack/lib/webpack/prepareEntry' { 94 | declare module.exports: any; 95 | } 96 | 97 | declare module 'mocha-webpack/lib/webpack/watch' { 98 | declare module.exports: any; 99 | } 100 | 101 | declare module 'mocha-webpack/src/cli/index' { 102 | declare module.exports: any; 103 | } 104 | 105 | declare module 'mocha-webpack/src/cli/parseArgv' { 106 | declare module.exports: any; 107 | } 108 | 109 | declare module 'mocha-webpack/src/cli/parseConfig' { 110 | declare module.exports: any; 111 | } 112 | 113 | declare module 'mocha-webpack/src/cli/prepareWebpack' { 114 | declare module.exports: any; 115 | } 116 | 117 | declare module 'mocha-webpack/src/cli/requireWebpackConfig' { 118 | declare module.exports: any; 119 | } 120 | 121 | declare module 'mocha-webpack/src/cli/runner' { 122 | declare module.exports: any; 123 | } 124 | 125 | declare module 'mocha-webpack/src/mocha/checkReporter' { 126 | declare module.exports: any; 127 | } 128 | 129 | declare module 'mocha-webpack/src/mocha/configureMocha' { 130 | declare module.exports: any; 131 | } 132 | 133 | declare module 'mocha-webpack/src/mocha/resetMocha' { 134 | declare module.exports: any; 135 | } 136 | 137 | declare module 'mocha-webpack/src/util/exists' { 138 | declare module.exports: any; 139 | } 140 | 141 | declare module 'mocha-webpack/src/webpack/build' { 142 | declare module.exports: any; 143 | } 144 | 145 | declare module 'mocha-webpack/src/webpack/contextReplacementPlugin' { 146 | declare module.exports: any; 147 | } 148 | 149 | declare module 'mocha-webpack/src/webpack/createCompiler' { 150 | declare module.exports: any; 151 | } 152 | 153 | declare module 'mocha-webpack/src/webpack/includeFilesLoader' { 154 | declare module.exports: any; 155 | } 156 | 157 | declare module 'mocha-webpack/src/webpack/InjectChangedFilesPlugin' { 158 | declare module.exports: any; 159 | } 160 | 161 | declare module 'mocha-webpack/src/webpack/prepareEntry' { 162 | declare module.exports: any; 163 | } 164 | 165 | declare module 'mocha-webpack/src/webpack/watch' { 166 | declare module.exports: any; 167 | } 168 | 169 | // Filename aliases 170 | declare module 'mocha-webpack/lib/cli/index.js' { 171 | declare module.exports: $Exports<'mocha-webpack/lib/cli/index'>; 172 | } 173 | declare module 'mocha-webpack/lib/cli/parseArgv.js' { 174 | declare module.exports: $Exports<'mocha-webpack/lib/cli/parseArgv'>; 175 | } 176 | declare module 'mocha-webpack/lib/cli/parseConfig.js' { 177 | declare module.exports: $Exports<'mocha-webpack/lib/cli/parseConfig'>; 178 | } 179 | declare module 'mocha-webpack/lib/cli/prepareWebpack.js' { 180 | declare module.exports: $Exports<'mocha-webpack/lib/cli/prepareWebpack'>; 181 | } 182 | declare module 'mocha-webpack/lib/cli/requireWebpackConfig.js' { 183 | declare module.exports: $Exports<'mocha-webpack/lib/cli/requireWebpackConfig'>; 184 | } 185 | declare module 'mocha-webpack/lib/cli/runner.js' { 186 | declare module.exports: $Exports<'mocha-webpack/lib/cli/runner'>; 187 | } 188 | declare module 'mocha-webpack/lib/mocha/checkReporter.js' { 189 | declare module.exports: $Exports<'mocha-webpack/lib/mocha/checkReporter'>; 190 | } 191 | declare module 'mocha-webpack/lib/mocha/configureMocha.js' { 192 | declare module.exports: $Exports<'mocha-webpack/lib/mocha/configureMocha'>; 193 | } 194 | declare module 'mocha-webpack/lib/mocha/resetMocha.js' { 195 | declare module.exports: $Exports<'mocha-webpack/lib/mocha/resetMocha'>; 196 | } 197 | declare module 'mocha-webpack/lib/reporters/base.js' { 198 | declare module.exports: $Exports<'mocha-webpack/lib/reporters/base'>; 199 | } 200 | declare module 'mocha-webpack/lib/util/exists.js' { 201 | declare module.exports: $Exports<'mocha-webpack/lib/util/exists'>; 202 | } 203 | declare module 'mocha-webpack/lib/utils.js' { 204 | declare module.exports: $Exports<'mocha-webpack/lib/utils'>; 205 | } 206 | declare module 'mocha-webpack/lib/webpack/build.js' { 207 | declare module.exports: $Exports<'mocha-webpack/lib/webpack/build'>; 208 | } 209 | declare module 'mocha-webpack/lib/webpack/contextReplacementPlugin.js' { 210 | declare module.exports: $Exports<'mocha-webpack/lib/webpack/contextReplacementPlugin'>; 211 | } 212 | declare module 'mocha-webpack/lib/webpack/createCompiler.js' { 213 | declare module.exports: $Exports<'mocha-webpack/lib/webpack/createCompiler'>; 214 | } 215 | declare module 'mocha-webpack/lib/webpack/includeFilesLoader.js' { 216 | declare module.exports: $Exports<'mocha-webpack/lib/webpack/includeFilesLoader'>; 217 | } 218 | declare module 'mocha-webpack/lib/webpack/InjectChangedFilesPlugin.js' { 219 | declare module.exports: $Exports<'mocha-webpack/lib/webpack/InjectChangedFilesPlugin'>; 220 | } 221 | declare module 'mocha-webpack/lib/webpack/prepareEntry.js' { 222 | declare module.exports: $Exports<'mocha-webpack/lib/webpack/prepareEntry'>; 223 | } 224 | declare module 'mocha-webpack/lib/webpack/watch.js' { 225 | declare module.exports: $Exports<'mocha-webpack/lib/webpack/watch'>; 226 | } 227 | declare module 'mocha-webpack/src/cli/index.js' { 228 | declare module.exports: $Exports<'mocha-webpack/src/cli/index'>; 229 | } 230 | declare module 'mocha-webpack/src/cli/parseArgv.js' { 231 | declare module.exports: $Exports<'mocha-webpack/src/cli/parseArgv'>; 232 | } 233 | declare module 'mocha-webpack/src/cli/parseConfig.js' { 234 | declare module.exports: $Exports<'mocha-webpack/src/cli/parseConfig'>; 235 | } 236 | declare module 'mocha-webpack/src/cli/prepareWebpack.js' { 237 | declare module.exports: $Exports<'mocha-webpack/src/cli/prepareWebpack'>; 238 | } 239 | declare module 'mocha-webpack/src/cli/requireWebpackConfig.js' { 240 | declare module.exports: $Exports<'mocha-webpack/src/cli/requireWebpackConfig'>; 241 | } 242 | declare module 'mocha-webpack/src/cli/runner.js' { 243 | declare module.exports: $Exports<'mocha-webpack/src/cli/runner'>; 244 | } 245 | declare module 'mocha-webpack/src/mocha/checkReporter.js' { 246 | declare module.exports: $Exports<'mocha-webpack/src/mocha/checkReporter'>; 247 | } 248 | declare module 'mocha-webpack/src/mocha/configureMocha.js' { 249 | declare module.exports: $Exports<'mocha-webpack/src/mocha/configureMocha'>; 250 | } 251 | declare module 'mocha-webpack/src/mocha/resetMocha.js' { 252 | declare module.exports: $Exports<'mocha-webpack/src/mocha/resetMocha'>; 253 | } 254 | declare module 'mocha-webpack/src/util/exists.js' { 255 | declare module.exports: $Exports<'mocha-webpack/src/util/exists'>; 256 | } 257 | declare module 'mocha-webpack/src/webpack/build.js' { 258 | declare module.exports: $Exports<'mocha-webpack/src/webpack/build'>; 259 | } 260 | declare module 'mocha-webpack/src/webpack/contextReplacementPlugin.js' { 261 | declare module.exports: $Exports<'mocha-webpack/src/webpack/contextReplacementPlugin'>; 262 | } 263 | declare module 'mocha-webpack/src/webpack/createCompiler.js' { 264 | declare module.exports: $Exports<'mocha-webpack/src/webpack/createCompiler'>; 265 | } 266 | declare module 'mocha-webpack/src/webpack/includeFilesLoader.js' { 267 | declare module.exports: $Exports<'mocha-webpack/src/webpack/includeFilesLoader'>; 268 | } 269 | declare module 'mocha-webpack/src/webpack/InjectChangedFilesPlugin.js' { 270 | declare module.exports: $Exports<'mocha-webpack/src/webpack/InjectChangedFilesPlugin'>; 271 | } 272 | declare module 'mocha-webpack/src/webpack/prepareEntry.js' { 273 | declare module.exports: $Exports<'mocha-webpack/src/webpack/prepareEntry'>; 274 | } 275 | declare module 'mocha-webpack/src/webpack/watch.js' { 276 | declare module.exports: $Exports<'mocha-webpack/src/webpack/watch'>; 277 | } 278 | -------------------------------------------------------------------------------- /flow-typed/npm/mocha_v3.1.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6b82cf8c1da27b4f0fa7a58e5ed5babf 2 | // flow-typed version: edf70dde46/mocha_v3.1.x/flow_>=v0.22.x 3 | 4 | type TestFunction = ((done: () => void) => void | Promise); 5 | 6 | declare var describe : { 7 | (name:string, spec:() => void): void; 8 | only(description:string, spec:() => void): void; 9 | skip(description:string, spec:() => void): void; 10 | timeout(ms:number): void; 11 | }; 12 | 13 | declare var context : typeof describe; 14 | 15 | declare var it : { 16 | (name:string, spec?:TestFunction): void; 17 | only(description:string, spec:TestFunction): void; 18 | skip(description:string, spec:TestFunction): void; 19 | timeout(ms:number): void; 20 | }; 21 | 22 | declare function before(method : TestFunction):void; 23 | declare function beforeEach(method : TestFunction):void; 24 | declare function after(method : TestFunction):void; 25 | declare function afterEach(method : TestFunction):void; 26 | -------------------------------------------------------------------------------- /flow-typed/npm/postcss-cssnext_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 4993313c46db4a6b8f9af09512450caa 2 | // flow-typed version: <>/postcss-cssnext_v^2.10.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'postcss-cssnext' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'postcss-cssnext' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'postcss-cssnext/lib/features-activation-map' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'postcss-cssnext/lib/features' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'postcss-cssnext/lib/index' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'postcss-cssnext/lib/warn-for-duplicates' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'postcss-cssnext/src/features-activation-map' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'postcss-cssnext/src/features' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'postcss-cssnext/src/index' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'postcss-cssnext/src/warn-for-duplicates' { 54 | declare module.exports: any; 55 | } 56 | 57 | // Filename aliases 58 | declare module 'postcss-cssnext/lib/features-activation-map.js' { 59 | declare module.exports: $Exports<'postcss-cssnext/lib/features-activation-map'>; 60 | } 61 | declare module 'postcss-cssnext/lib/features.js' { 62 | declare module.exports: $Exports<'postcss-cssnext/lib/features'>; 63 | } 64 | declare module 'postcss-cssnext/lib/index.js' { 65 | declare module.exports: $Exports<'postcss-cssnext/lib/index'>; 66 | } 67 | declare module 'postcss-cssnext/lib/warn-for-duplicates.js' { 68 | declare module.exports: $Exports<'postcss-cssnext/lib/warn-for-duplicates'>; 69 | } 70 | declare module 'postcss-cssnext/src/features-activation-map.js' { 71 | declare module.exports: $Exports<'postcss-cssnext/src/features-activation-map'>; 72 | } 73 | declare module 'postcss-cssnext/src/features.js' { 74 | declare module.exports: $Exports<'postcss-cssnext/src/features'>; 75 | } 76 | declare module 'postcss-cssnext/src/index.js' { 77 | declare module.exports: $Exports<'postcss-cssnext/src/index'>; 78 | } 79 | declare module 'postcss-cssnext/src/warn-for-duplicates.js' { 80 | declare module.exports: $Exports<'postcss-cssnext/src/warn-for-duplicates'>; 81 | } 82 | -------------------------------------------------------------------------------- /flow-typed/npm/postcss-loader_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: a5b91252623a1d0d1022604164faf2e8 2 | // flow-typed version: <>/postcss-loader_v^1.3.3/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'postcss-loader' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'postcss-loader' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'postcss-loader/error' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'postcss-loader/error.js' { 31 | declare module.exports: $Exports<'postcss-loader/error'>; 32 | } 33 | declare module 'postcss-loader/index' { 34 | declare module.exports: $Exports<'postcss-loader'>; 35 | } 36 | declare module 'postcss-loader/index.js' { 37 | declare module.exports: $Exports<'postcss-loader'>; 38 | } 39 | -------------------------------------------------------------------------------- /flow-typed/npm/postcss-smart-import_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: cdaad50580edc9f61ae459204115a5d2 2 | // flow-typed version: <>/postcss-smart-import_v^0.6.10/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'postcss-smart-import' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'postcss-smart-import' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'postcss-smart-import/gulpfile' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'postcss-smart-import/lib/index.classic.commonjs' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'postcss-smart-import/lib/index.classic.esmodule' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'postcss-smart-import/lib/index.modern.commonjs' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'postcss-smart-import/lib/index.modern.esmodule' { 42 | declare module.exports: any; 43 | } 44 | 45 | // Filename aliases 46 | declare module 'postcss-smart-import/gulpfile.js' { 47 | declare module.exports: $Exports<'postcss-smart-import/gulpfile'>; 48 | } 49 | declare module 'postcss-smart-import/lib/index.classic.commonjs.js' { 50 | declare module.exports: $Exports<'postcss-smart-import/lib/index.classic.commonjs'>; 51 | } 52 | declare module 'postcss-smart-import/lib/index.classic.esmodule.js' { 53 | declare module.exports: $Exports<'postcss-smart-import/lib/index.classic.esmodule'>; 54 | } 55 | declare module 'postcss-smart-import/lib/index.modern.commonjs.js' { 56 | declare module.exports: $Exports<'postcss-smart-import/lib/index.modern.commonjs'>; 57 | } 58 | declare module 'postcss-smart-import/lib/index.modern.esmodule.js' { 59 | declare module.exports: $Exports<'postcss-smart-import/lib/index.modern.esmodule'>; 60 | } 61 | -------------------------------------------------------------------------------- /flow-typed/npm/sinon-chai_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: be07383a7ba06a5b6a8033f981cf8bfc 2 | // flow-typed version: <>/sinon-chai_v^2.9.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'sinon-chai' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'sinon-chai' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'sinon-chai/lib/sinon-chai' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'sinon-chai/lib/sinon-chai.js' { 31 | declare module.exports: $Exports<'sinon-chai/lib/sinon-chai'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/sinon_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 56eb46e79aa88f3ad3ec248c671a3858 2 | // flow-typed version: <>/sinon_v^2.1.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'sinon' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'sinon' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'sinon/lib/sinon' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'sinon/lib/sinon/assert' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'sinon/lib/sinon/behavior' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'sinon/lib/sinon/blob' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'sinon/lib/sinon/call' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'sinon/lib/sinon/collect-own-methods' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'sinon/lib/sinon/collection' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'sinon/lib/sinon/color' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'sinon/lib/sinon/default-behaviors' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'sinon/lib/sinon/match' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'sinon/lib/sinon/mock-expectation' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'sinon/lib/sinon/mock' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'sinon/lib/sinon/sandbox' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'sinon/lib/sinon/spy-formatters' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'sinon/lib/sinon/spy' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module 'sinon/lib/sinon/stub-descriptor' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module 'sinon/lib/sinon/stub-entire-object' { 90 | declare module.exports: any; 91 | } 92 | 93 | declare module 'sinon/lib/sinon/stub-non-function-property' { 94 | declare module.exports: any; 95 | } 96 | 97 | declare module 'sinon/lib/sinon/stub' { 98 | declare module.exports: any; 99 | } 100 | 101 | declare module 'sinon/lib/sinon/throw-on-falsy-object' { 102 | declare module.exports: any; 103 | } 104 | 105 | declare module 'sinon/lib/sinon/util/core/called-in-order' { 106 | declare module.exports: any; 107 | } 108 | 109 | declare module 'sinon/lib/sinon/util/core/deep-equal' { 110 | declare module.exports: any; 111 | } 112 | 113 | declare module 'sinon/lib/sinon/util/core/default-config' { 114 | declare module.exports: any; 115 | } 116 | 117 | declare module 'sinon/lib/sinon/util/core/deprecated' { 118 | declare module.exports: any; 119 | } 120 | 121 | declare module 'sinon/lib/sinon/util/core/every' { 122 | declare module.exports: any; 123 | } 124 | 125 | declare module 'sinon/lib/sinon/util/core/extend' { 126 | declare module.exports: any; 127 | } 128 | 129 | declare module 'sinon/lib/sinon/util/core/format' { 130 | declare module.exports: any; 131 | } 132 | 133 | declare module 'sinon/lib/sinon/util/core/function-name' { 134 | declare module.exports: any; 135 | } 136 | 137 | declare module 'sinon/lib/sinon/util/core/function-to-string' { 138 | declare module.exports: any; 139 | } 140 | 141 | declare module 'sinon/lib/sinon/util/core/get-config' { 142 | declare module.exports: any; 143 | } 144 | 145 | declare module 'sinon/lib/sinon/util/core/get-property-descriptor' { 146 | declare module.exports: any; 147 | } 148 | 149 | declare module 'sinon/lib/sinon/util/core/index' { 150 | declare module.exports: any; 151 | } 152 | 153 | declare module 'sinon/lib/sinon/util/core/iterable-to-string' { 154 | declare module.exports: any; 155 | } 156 | 157 | declare module 'sinon/lib/sinon/util/core/log_error' { 158 | declare module.exports: any; 159 | } 160 | 161 | declare module 'sinon/lib/sinon/util/core/order-by-first-call' { 162 | declare module.exports: any; 163 | } 164 | 165 | declare module 'sinon/lib/sinon/util/core/restore' { 166 | declare module.exports: any; 167 | } 168 | 169 | declare module 'sinon/lib/sinon/util/core/times-in-words' { 170 | declare module.exports: any; 171 | } 172 | 173 | declare module 'sinon/lib/sinon/util/core/typeOf' { 174 | declare module.exports: any; 175 | } 176 | 177 | declare module 'sinon/lib/sinon/util/core/value-to-string' { 178 | declare module.exports: any; 179 | } 180 | 181 | declare module 'sinon/lib/sinon/util/core/walk' { 182 | declare module.exports: any; 183 | } 184 | 185 | declare module 'sinon/lib/sinon/util/core/wrap-method' { 186 | declare module.exports: any; 187 | } 188 | 189 | declare module 'sinon/lib/sinon/util/event' { 190 | declare module.exports: any; 191 | } 192 | 193 | declare module 'sinon/lib/sinon/util/fake_server_with_clock' { 194 | declare module.exports: any; 195 | } 196 | 197 | declare module 'sinon/lib/sinon/util/fake_server' { 198 | declare module.exports: any; 199 | } 200 | 201 | declare module 'sinon/lib/sinon/util/fake_timers' { 202 | declare module.exports: any; 203 | } 204 | 205 | declare module 'sinon/lib/sinon/util/fake_xml_http_request' { 206 | declare module.exports: any; 207 | } 208 | 209 | declare module 'sinon/pkg/sinon-2.1.0' { 210 | declare module.exports: any; 211 | } 212 | 213 | declare module 'sinon/pkg/sinon-no-sourcemaps-2.1.0' { 214 | declare module.exports: any; 215 | } 216 | 217 | declare module 'sinon/pkg/sinon-no-sourcemaps' { 218 | declare module.exports: any; 219 | } 220 | 221 | declare module 'sinon/pkg/sinon' { 222 | declare module.exports: any; 223 | } 224 | 225 | // Filename aliases 226 | declare module 'sinon/lib/sinon.js' { 227 | declare module.exports: $Exports<'sinon/lib/sinon'>; 228 | } 229 | declare module 'sinon/lib/sinon/assert.js' { 230 | declare module.exports: $Exports<'sinon/lib/sinon/assert'>; 231 | } 232 | declare module 'sinon/lib/sinon/behavior.js' { 233 | declare module.exports: $Exports<'sinon/lib/sinon/behavior'>; 234 | } 235 | declare module 'sinon/lib/sinon/blob.js' { 236 | declare module.exports: $Exports<'sinon/lib/sinon/blob'>; 237 | } 238 | declare module 'sinon/lib/sinon/call.js' { 239 | declare module.exports: $Exports<'sinon/lib/sinon/call'>; 240 | } 241 | declare module 'sinon/lib/sinon/collect-own-methods.js' { 242 | declare module.exports: $Exports<'sinon/lib/sinon/collect-own-methods'>; 243 | } 244 | declare module 'sinon/lib/sinon/collection.js' { 245 | declare module.exports: $Exports<'sinon/lib/sinon/collection'>; 246 | } 247 | declare module 'sinon/lib/sinon/color.js' { 248 | declare module.exports: $Exports<'sinon/lib/sinon/color'>; 249 | } 250 | declare module 'sinon/lib/sinon/default-behaviors.js' { 251 | declare module.exports: $Exports<'sinon/lib/sinon/default-behaviors'>; 252 | } 253 | declare module 'sinon/lib/sinon/match.js' { 254 | declare module.exports: $Exports<'sinon/lib/sinon/match'>; 255 | } 256 | declare module 'sinon/lib/sinon/mock-expectation.js' { 257 | declare module.exports: $Exports<'sinon/lib/sinon/mock-expectation'>; 258 | } 259 | declare module 'sinon/lib/sinon/mock.js' { 260 | declare module.exports: $Exports<'sinon/lib/sinon/mock'>; 261 | } 262 | declare module 'sinon/lib/sinon/sandbox.js' { 263 | declare module.exports: $Exports<'sinon/lib/sinon/sandbox'>; 264 | } 265 | declare module 'sinon/lib/sinon/spy-formatters.js' { 266 | declare module.exports: $Exports<'sinon/lib/sinon/spy-formatters'>; 267 | } 268 | declare module 'sinon/lib/sinon/spy.js' { 269 | declare module.exports: $Exports<'sinon/lib/sinon/spy'>; 270 | } 271 | declare module 'sinon/lib/sinon/stub-descriptor.js' { 272 | declare module.exports: $Exports<'sinon/lib/sinon/stub-descriptor'>; 273 | } 274 | declare module 'sinon/lib/sinon/stub-entire-object.js' { 275 | declare module.exports: $Exports<'sinon/lib/sinon/stub-entire-object'>; 276 | } 277 | declare module 'sinon/lib/sinon/stub-non-function-property.js' { 278 | declare module.exports: $Exports<'sinon/lib/sinon/stub-non-function-property'>; 279 | } 280 | declare module 'sinon/lib/sinon/stub.js' { 281 | declare module.exports: $Exports<'sinon/lib/sinon/stub'>; 282 | } 283 | declare module 'sinon/lib/sinon/throw-on-falsy-object.js' { 284 | declare module.exports: $Exports<'sinon/lib/sinon/throw-on-falsy-object'>; 285 | } 286 | declare module 'sinon/lib/sinon/util/core/called-in-order.js' { 287 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/called-in-order'>; 288 | } 289 | declare module 'sinon/lib/sinon/util/core/deep-equal.js' { 290 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/deep-equal'>; 291 | } 292 | declare module 'sinon/lib/sinon/util/core/default-config.js' { 293 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/default-config'>; 294 | } 295 | declare module 'sinon/lib/sinon/util/core/deprecated.js' { 296 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/deprecated'>; 297 | } 298 | declare module 'sinon/lib/sinon/util/core/every.js' { 299 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/every'>; 300 | } 301 | declare module 'sinon/lib/sinon/util/core/extend.js' { 302 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/extend'>; 303 | } 304 | declare module 'sinon/lib/sinon/util/core/format.js' { 305 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/format'>; 306 | } 307 | declare module 'sinon/lib/sinon/util/core/function-name.js' { 308 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/function-name'>; 309 | } 310 | declare module 'sinon/lib/sinon/util/core/function-to-string.js' { 311 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/function-to-string'>; 312 | } 313 | declare module 'sinon/lib/sinon/util/core/get-config.js' { 314 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/get-config'>; 315 | } 316 | declare module 'sinon/lib/sinon/util/core/get-property-descriptor.js' { 317 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/get-property-descriptor'>; 318 | } 319 | declare module 'sinon/lib/sinon/util/core/index.js' { 320 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/index'>; 321 | } 322 | declare module 'sinon/lib/sinon/util/core/iterable-to-string.js' { 323 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/iterable-to-string'>; 324 | } 325 | declare module 'sinon/lib/sinon/util/core/log_error.js' { 326 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/log_error'>; 327 | } 328 | declare module 'sinon/lib/sinon/util/core/order-by-first-call.js' { 329 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/order-by-first-call'>; 330 | } 331 | declare module 'sinon/lib/sinon/util/core/restore.js' { 332 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/restore'>; 333 | } 334 | declare module 'sinon/lib/sinon/util/core/times-in-words.js' { 335 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/times-in-words'>; 336 | } 337 | declare module 'sinon/lib/sinon/util/core/typeOf.js' { 338 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/typeOf'>; 339 | } 340 | declare module 'sinon/lib/sinon/util/core/value-to-string.js' { 341 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/value-to-string'>; 342 | } 343 | declare module 'sinon/lib/sinon/util/core/walk.js' { 344 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/walk'>; 345 | } 346 | declare module 'sinon/lib/sinon/util/core/wrap-method.js' { 347 | declare module.exports: $Exports<'sinon/lib/sinon/util/core/wrap-method'>; 348 | } 349 | declare module 'sinon/lib/sinon/util/event.js' { 350 | declare module.exports: $Exports<'sinon/lib/sinon/util/event'>; 351 | } 352 | declare module 'sinon/lib/sinon/util/fake_server_with_clock.js' { 353 | declare module.exports: $Exports<'sinon/lib/sinon/util/fake_server_with_clock'>; 354 | } 355 | declare module 'sinon/lib/sinon/util/fake_server.js' { 356 | declare module.exports: $Exports<'sinon/lib/sinon/util/fake_server'>; 357 | } 358 | declare module 'sinon/lib/sinon/util/fake_timers.js' { 359 | declare module.exports: $Exports<'sinon/lib/sinon/util/fake_timers'>; 360 | } 361 | declare module 'sinon/lib/sinon/util/fake_xml_http_request.js' { 362 | declare module.exports: $Exports<'sinon/lib/sinon/util/fake_xml_http_request'>; 363 | } 364 | declare module 'sinon/pkg/sinon-2.1.0.js' { 365 | declare module.exports: $Exports<'sinon/pkg/sinon-2.1.0'>; 366 | } 367 | declare module 'sinon/pkg/sinon-no-sourcemaps-2.1.0.js' { 368 | declare module.exports: $Exports<'sinon/pkg/sinon-no-sourcemaps-2.1.0'>; 369 | } 370 | declare module 'sinon/pkg/sinon-no-sourcemaps.js' { 371 | declare module.exports: $Exports<'sinon/pkg/sinon-no-sourcemaps'>; 372 | } 373 | declare module 'sinon/pkg/sinon.js' { 374 | declare module.exports: $Exports<'sinon/pkg/sinon'>; 375 | } 376 | -------------------------------------------------------------------------------- /flow-typed/npm/source-map-support_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: e82dd141ebc180ff749eab3ec47fd0f0 2 | // flow-typed version: <>/source-map-support_v^0.4.14/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'source-map-support' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'source-map-support' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'source-map-support/browser-source-map-support' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'source-map-support/build' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'source-map-support/register' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'source-map-support/source-map-support' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'source-map-support/test' { 42 | declare module.exports: any; 43 | } 44 | 45 | // Filename aliases 46 | declare module 'source-map-support/browser-source-map-support.js' { 47 | declare module.exports: $Exports<'source-map-support/browser-source-map-support'>; 48 | } 49 | declare module 'source-map-support/build.js' { 50 | declare module.exports: $Exports<'source-map-support/build'>; 51 | } 52 | declare module 'source-map-support/register.js' { 53 | declare module.exports: $Exports<'source-map-support/register'>; 54 | } 55 | declare module 'source-map-support/source-map-support.js' { 56 | declare module.exports: $Exports<'source-map-support/source-map-support'>; 57 | } 58 | declare module 'source-map-support/test.js' { 59 | declare module.exports: $Exports<'source-map-support/test'>; 60 | } 61 | -------------------------------------------------------------------------------- /flow-typed/npm/style-loader_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 208f651d7c34ce3b628cca1627c38d8d 2 | // flow-typed version: <>/style-loader_v^0.16.0/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'style-loader' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'style-loader' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'style-loader/addStyles' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'style-loader/addStyleUrl' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'style-loader/fixUrls' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'style-loader/test/basicTest' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'style-loader/test/fixUrlsTest' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'style-loader/test/utils' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'style-loader/url' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'style-loader/useable' { 54 | declare module.exports: any; 55 | } 56 | 57 | // Filename aliases 58 | declare module 'style-loader/addStyles.js' { 59 | declare module.exports: $Exports<'style-loader/addStyles'>; 60 | } 61 | declare module 'style-loader/addStyleUrl.js' { 62 | declare module.exports: $Exports<'style-loader/addStyleUrl'>; 63 | } 64 | declare module 'style-loader/fixUrls.js' { 65 | declare module.exports: $Exports<'style-loader/fixUrls'>; 66 | } 67 | declare module 'style-loader/index' { 68 | declare module.exports: $Exports<'style-loader'>; 69 | } 70 | declare module 'style-loader/index.js' { 71 | declare module.exports: $Exports<'style-loader'>; 72 | } 73 | declare module 'style-loader/test/basicTest.js' { 74 | declare module.exports: $Exports<'style-loader/test/basicTest'>; 75 | } 76 | declare module 'style-loader/test/fixUrlsTest.js' { 77 | declare module.exports: $Exports<'style-loader/test/fixUrlsTest'>; 78 | } 79 | declare module 'style-loader/test/utils.js' { 80 | declare module.exports: $Exports<'style-loader/test/utils'>; 81 | } 82 | declare module 'style-loader/url.js' { 83 | declare module.exports: $Exports<'style-loader/url'>; 84 | } 85 | declare module 'style-loader/useable.js' { 86 | declare module.exports: $Exports<'style-loader/useable'>; 87 | } 88 | -------------------------------------------------------------------------------- /flow-typed/npm/url-loader_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 1c7ac8300681f9056f0f1b819f989e98 2 | // flow-typed version: <>/url-loader_v^0.5.8/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'url-loader' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'url-loader' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | 26 | 27 | // Filename aliases 28 | declare module 'url-loader/index' { 29 | declare module.exports: $Exports<'url-loader'>; 30 | } 31 | declare module 'url-loader/index.js' { 32 | declare module.exports: $Exports<'url-loader'>; 33 | } 34 | -------------------------------------------------------------------------------- /flow-typed/npm/webpack-dev-middleware_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: afddef5723a1d407c1334a5772792324 2 | // flow-typed version: <>/webpack-dev-middleware_v^1.10.1/flow_v0.38.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'webpack-dev-middleware' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'webpack-dev-middleware' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'webpack-dev-middleware/lib/GetFilenameFromUrl' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'webpack-dev-middleware/lib/PathJoin' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'webpack-dev-middleware/lib/Shared' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'webpack-dev-middleware/middleware' { 38 | declare module.exports: any; 39 | } 40 | 41 | // Filename aliases 42 | declare module 'webpack-dev-middleware/lib/GetFilenameFromUrl.js' { 43 | declare module.exports: $Exports<'webpack-dev-middleware/lib/GetFilenameFromUrl'>; 44 | } 45 | declare module 'webpack-dev-middleware/lib/PathJoin.js' { 46 | declare module.exports: $Exports<'webpack-dev-middleware/lib/PathJoin'>; 47 | } 48 | declare module 'webpack-dev-middleware/lib/Shared.js' { 49 | declare module.exports: $Exports<'webpack-dev-middleware/lib/Shared'>; 50 | } 51 | declare module 'webpack-dev-middleware/middleware.js' { 52 | declare module.exports: $Exports<'webpack-dev-middleware/middleware'>; 53 | } 54 | -------------------------------------------------------------------------------- /interfaces/electron.js: -------------------------------------------------------------------------------- 1 | declare module 'electron' { 2 | declare var dialog: any; 3 | 4 | declare type ElectronApp = {| 5 | isReady: () => boolean, 6 | on: (string, Function) => ElectronApp, 7 | once: (string, Function) => ElectronApp, 8 | removeListener: (string, Function) => ElectronApp, 9 | 10 | test_makeReady: () => void, 11 | |}; 12 | 13 | declare var app: ElectronApp; 14 | 15 | declare class BrowserWindow { 16 | on: (string, Function) => BrowserWindow; 17 | once: (string, Function) => BrowserWindow; 18 | removeListener: (string, Function) => BrowserWindow; 19 | removeAllListeners: (string) => BrowserWindow; 20 | setParentWindow: (?BrowserWindow) => void; 21 | getParentWindow: () => BrowserWindow; 22 | show: () => void; 23 | hide: () => void; 24 | close: () => void; 25 | loadURL: (string, ?Object) => void; 26 | id: number; 27 | 28 | webContents: any; // TODO 29 | setPosition: (number, number, ?boolean) => void; 30 | getPosition: () => [number, number]; 31 | setMovable: (boolean) => void; 32 | setSize: (number, number, ?boolean) => void; 33 | getSize: () => [number, number]; 34 | setResizable: (boolean) => void; 35 | } 36 | 37 | declare class Menu { 38 | static setApplicationMenu: (Menu) => void; 39 | append: (MenuItem) => void; 40 | } 41 | 42 | declare class MenuItem { 43 | } 44 | 45 | declare var ElectronTestUtils: {| 46 | getWindow: (number) => BrowserWindow, 47 | getMenu: (number) => Menu, 48 | getMenuItem: (number) => MenuItem, 49 | reset: () => void, 50 | |}; 51 | 52 | 53 | }; 54 | -------------------------------------------------------------------------------- /interfaces/global.js: -------------------------------------------------------------------------------- 1 | declare var sinon: any; 2 | declare var expect: any; 3 | -------------------------------------------------------------------------------- /mocha-webpack.opts: -------------------------------------------------------------------------------- 1 | --require source-map-support/register 2 | --require test/test-setup.js 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-ionize", 3 | "version": "1.5.0", 4 | "description": "An experimental React renderer for Electron apps", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "start": "EXAMPLE_ENTRY=main.js npm run start:example", 8 | "start:example": "webpack --bail --config webpack.examples.config.js && electron ./dist/main.js", 9 | "build": "babel -d lib/ src/", 10 | "test": "mocha-webpack --webpack-config webpack.test.config.js \"test/**/*.spec.js\"", 11 | "preversion": "yarn flow && yarn test && yarn build", 12 | "postversion": "npm publish && git push origin --tags" 13 | }, 14 | "author": "Matt Hink ", 15 | "license": "MIT", 16 | "dependencies": { 17 | "electron": "^1.6.2", 18 | "react-dom": "16.0.0-alpha.5" 19 | }, 20 | "peerDependencies": { 21 | "react": "16.0.0-alpha.5" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/mhink/ionize" 26 | }, 27 | "bugs": { 28 | "url": "https://github.com/mhink/ionize/issues" 29 | }, 30 | "homepage": "https://github.com/mhink/ionize", 31 | "files": [ 32 | "lib", 33 | "package.json", 34 | "README.md" 35 | ], 36 | "keywords": [ 37 | "react", 38 | "reactjs", 39 | "electron", 40 | "desktop", 41 | "app", 42 | "atom", 43 | "osx", 44 | "windows" 45 | ], 46 | "devDependencies": { 47 | "babel-cli": "^6.24.0", 48 | "babel-core": "^6.24.0", 49 | "babel-loader": "7.0.0-beta.1", 50 | "babel-plugin-check-es2015-constants": "^6.22.0", 51 | "babel-plugin-transform-es2015-destructuring": "^6.23.0", 52 | "babel-plugin-transform-es2015-spread": "^6.22.0", 53 | "babel-preset-es2015": "^6.24.0", 54 | "babel-preset-react": "^6.23.0", 55 | "babel-preset-stage-0": "^6.22.0", 56 | "babel-register": "^6.24.0", 57 | "chai": "^3.5.0", 58 | "css-loader": "^0.27.3", 59 | "electron-builder": "^16.2.0", 60 | "express": "^4.15.2", 61 | "file-loader": "^0.10.1", 62 | "flow-bin": "0.38.0", 63 | "flow-typed": "^2.0.0", 64 | "html-webpack-plugin": "^2.28.0", 65 | "json-loader": "^0.5.4", 66 | "mocha": "^3.2.0", 67 | "mocha-webpack": "^0.7.0", 68 | "postcss-cssnext": "^2.10.0", 69 | "postcss-loader": "^1.3.3", 70 | "postcss-smart-import": "^0.6.10", 71 | "sinon": "^2.1.0", 72 | "sinon-chai": "^2.9.0", 73 | "source-map-support": "^0.4.14", 74 | "style-loader": "^0.16.0", 75 | "url-loader": "^0.5.8", 76 | "webpack": "^2.3.1", 77 | "webpack-dev-middleware": "^1.10.1", 78 | "webpack-node-externals": "^1.5.4", 79 | "electron": "^1.6.2", 80 | "react-dom": "16.0.0-alpha.5", 81 | "react": "16.0.0-alpha.5" 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "react"] 3 | } 4 | -------------------------------------------------------------------------------- /src/IonizeContainer.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import type { ElectronApp } from 'electron'; 4 | import { AppElement, BaseElement, TextElement } from './elements'; 5 | 6 | export default class IonizeContainer { 7 | app : ElectronApp; 8 | appElement : ?AppElement; 9 | 10 | constructor( 11 | electronApp : ElectronApp 12 | ) { 13 | this.app = electronApp; 14 | this.appElement = null; 15 | } 16 | 17 | appendChild( 18 | child: (BaseElement | TextElement) 19 | ): void { 20 | if (child instanceof AppElement) { 21 | this.appElement = child; 22 | } 23 | } 24 | 25 | insertBefore( 26 | child: (BaseElement | TextElement) 27 | ): void { 28 | } 29 | 30 | removeChild( 31 | child: (BaseElement | TextElement) 32 | ): void { 33 | if (child instanceof (typeof AppElement)) { 34 | this.appElement = null; 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/IonizeFiber.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import ReactFiberReconciler from 'react-dom/lib/ReactFiberReconciler'; 4 | import type { FiberRoot } from 'react-dom/lib/ReactFiberRoot'; 5 | import * as IonizeHostConfig from './IonizeHostConfig'; 6 | import { app } from 'electron'; 7 | import IonizeContainer from './IonizeContainer'; 8 | 9 | export const IonizeRenderer = ReactFiberReconciler(IonizeHostConfig); 10 | 11 | export const IonizeFiber: {| 12 | container : ?IonizeContainer, 13 | root : ?FiberRoot, 14 | start : (React$Element, ?Function) => void, 15 | update : (React$Element, ?Function) => void, 16 | chain : (any) => void, 17 | reset : () => void, 18 | |} = { 19 | container: null, 20 | root: null, 21 | 22 | start(element, callback) { 23 | this.container = new IonizeContainer(app); 24 | this.root = IonizeRenderer.createContainer(this.container); 25 | return this.update(element, callback); 26 | }, 27 | 28 | update(element, callback) { 29 | if (!this.root) { 30 | return this.start(element, callback); 31 | } 32 | 33 | const startIonize = () => { 34 | IonizeRenderer.updateContainer( 35 | element, 36 | this.root, 37 | null, 38 | callback, 39 | ); 40 | }; 41 | 42 | if (app.isReady()) { 43 | startIonize(); 44 | } else { 45 | app.once('ready', startIonize); 46 | } 47 | }, 48 | 49 | chain(el, cbOrEl, ...restPairs) { 50 | if (el) { 51 | this.update(el, () => { 52 | if (typeof cbOrEl === 'function') { 53 | cbOrEl(); 54 | this.chain(...restPairs); 55 | } else if (typeof cbOrEl === 'object') { 56 | this.chain(cbOrEl, ...restPairs); 57 | } 58 | }); 59 | } 60 | }, 61 | 62 | reset() { 63 | delete this.container; 64 | delete this.root; 65 | } 66 | }; 67 | -------------------------------------------------------------------------------- /src/IonizeHostConfig.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import type { ElectronApp } from 'electron'; 3 | import type IonizeContainer from './IonizeContainer'; 4 | 5 | import { 6 | createElectronInstance, 7 | TextElement, 8 | BaseElement, 9 | } from './elements'; 10 | 11 | /* IonizeHostConfig 12 | * 13 | * These functions constitute a module, which is the 'piece' of Ionize which 14 | * integrates with React Fiber. RF calls into these at specific times during 15 | * the rendering lifecycle when React elements have changed in order to allow 16 | * the underlying layer (Electron) to be updated accordingly. (Yup, in true 17 | * React fashion, these are basically just lifecycle methods.) 18 | * 19 | * NOTE: It behooves us BIG TIME to play by the rules here, because React Fiber 20 | * is doing a bunch of deep-magic shit underneath us in order to orchestrate 21 | * all the things. For the most part, these methods should only be doing "what 22 | * they're supposed to do". What is that? Well, that's what I've been trying to 23 | * figure out as I go along. 24 | * 25 | * The approach we take here is to represent each 'element' with an instance 26 | * of a subclass of BaseElement. (The only reason we use inheritance here is 27 | * to make it easier to implement- and typecheck- new elements.) 28 | * 29 | * Most methods are called from the 'inside-out', or starting at the most 30 | * deeply nested child element and proceeding outward. Conceptually, this makes 31 | * sense: for instance, if we have... 32 | * 33 | * 34 | * 35 | * 36 | * 37 | * ...then what will happen, in order, is the following: 38 | * - Create an instance (B) of "the thing represented by " 39 | * - Create an instance (F) of "the thing represented by " 40 | * - Do something which semantically links B to F in a child-parent relationship 41 | * 42 | * I've done my best to document further below, but much of it is basically 43 | * just my observations of what these things signify, based on their behavior 44 | * and what I've been able to glean from digging through ReactDOM and other 45 | * renderer implementations. 46 | */ 47 | 48 | // Create the actual "thing" described by the type and props of the element 49 | // we're looking at. (It will be 'attached' to the thing represented by its 50 | // parent element later on, in appendInitialChild/appendChild/insertBefore.) 51 | export function createInstance( 52 | type : string, 53 | props : Object, 54 | rootContainerInstance : IonizeContainer, 55 | hostContext : HostContext, 56 | internalInstanceHandle : Object 57 | ): BaseElement { 58 | let element = createElectronInstance(type, props, rootContainerInstance, hostContext); 59 | 60 | return element; 61 | } 62 | 63 | // In this context, the method name means 'append the child elements of 64 | // parentInstance which are present as the parent element is being mounted' 65 | // rather than 'append the first child'. I've renamed it in the hope that it'll 66 | // make a little more sense. 67 | export function appendInitialChild( 68 | parentInstance : BaseElement, 69 | child : BaseElement| TextElement 70 | ): void { 71 | parentInstance.appendChildBeforeMount(child); 72 | } 73 | 74 | // Likewise, this is meant to finalize an element *after* it has had a chance 75 | // to 'attach' its children (i.e. after `appendInitialChild` has run for all 76 | // its child elements.) 77 | // 78 | // The return value of this function determines whether React Fiber will run 79 | // `commitMount` for the newly created element. (I can't *quite* tell why this 80 | // final, optional pass is necessary. Any hints are welcome.) 81 | export function finalizeInitialChildren( 82 | newElement : BaseElement, 83 | type : string, 84 | props : Object, 85 | rootContainerInstance : ElectronApp, 86 | ): boolean { 87 | return newElement.finalizeBeforeMount(type, props, rootContainerInstance); 88 | } 89 | 90 | // The difference between this is confusing, but this actually signifies that 91 | // we're appending a child element at some point AFTER parentInstance has been 92 | // mounted (for instance, in response to an update which causes a new child to 93 | // appear in the component tree.) 94 | export function appendChild( 95 | parentInstance : BaseElement | IonizeContainer, 96 | child : BaseElement | TextElement 97 | ): void { 98 | parentInstance.appendChild(child); 99 | } 100 | 101 | // As above, but for the case where the new child element is getting stuck 102 | // in between two existing elements. 103 | export function insertBefore( 104 | parentInstance : BaseElement | IonizeContainer, 105 | child : BaseElement | TextElement, 106 | beforeChild : BaseElement | TextElement 107 | ): void { 108 | parentInstance.insertBefore(child, beforeChild); 109 | } 110 | 111 | // As above, but for the case where the an existing child element is being 112 | // removed. 113 | export function removeChild( 114 | parentInstance : BaseElement | IonizeContainer, 115 | child : BaseElement | TextElement 116 | ): void { 117 | child.finalizeBeforeRemoval(); 118 | parentInstance.removeChild(child); 119 | } 120 | 121 | // To be honest, I haven't worked much with this, and if I ever took notes on 122 | // when in the rendering lifecycle it occurs, I've lost them. At any rate, this 123 | // method (and the ones that follow) are related to the case where text gets 124 | // inserted in between elements. For instance, if you had the following JSX 125 | // under react-dom... 126 | // 127 | // `

Hello, !

` 128 | // 129 | // ...then the `

` would have three children: 130 | // - a TextElement with the value "Hello, " 131 | // - an DOMElement (represented by ) 132 | // - a TextElement with the value "!" 133 | // 134 | // As of right now, Ionize doesn't use these. For the sake of keeping things 135 | // tidy and well-accounted-for, however, I *have* created an element type for 136 | // them. (I should probably go make it throw an exception or something.) 137 | export function shouldSetTextContent( 138 | props : Object 139 | ): boolean { 140 | return false; 141 | } 142 | 143 | export function resetTextContent( 144 | element : BaseElement 145 | ): void { 146 | // noop 147 | } 148 | 149 | export function createTextInstance( 150 | text : string, 151 | rootContainerInstance : IonizeContainer, 152 | hostContext : Object, 153 | internalInstanceHandle: Object 154 | ): TextElement { 155 | throw new Error("TextElements are not supported yet! (do you have some text in your JSX?)"); 156 | // return new TextElement(text, rootContainerInstance); 157 | } 158 | 159 | export function commitTextUpdate( 160 | textElement : TextElement, 161 | oldText : string, 162 | newText : string 163 | ): void { 164 | throw new Error("how did you even get a TextElement into the component tree?!"); 165 | // return textElement.commitUpdate(oldText, newText); 166 | } 167 | 168 | export type HostContext = {| 169 | isMenu: boolean, 170 | |}; 171 | 172 | const DEFAULT_HOST_CONTEXT: HostContext = ({}: any); 173 | 174 | // Now, this is an interesting piece of functionality. This basically works 175 | // like context in React components, except it's for _instances_. 176 | // 177 | // Basically, before any element gets instantiated, it has the opportunity 178 | // to create a new HostContext which will be provided to its own children. The 179 | // 'container' (that is, the root under which every element gets mounted). 180 | export function getRootHostContext( 181 | rootContainerInstance: IonizeContainer, 182 | ): HostContext { 183 | return DEFAULT_HOST_CONTEXT; 184 | } 185 | 186 | export function getChildHostContext( 187 | parentHostContext : HostContext, 188 | type : string, 189 | ): HostContext { 190 | return parentHostContext; 191 | } 192 | 193 | // Before/after hooks to allow us to manipulate module-specific app state 194 | // ReactDOM uses this to disable its event system before making changes to 195 | // the DOM. I haven't found a particularly important use for it, so it's 196 | // no-opped for now. 197 | export function prepareForCommit(): void { 198 | } 199 | 200 | // ReactDOM uses this to focus any input elements it just created. 201 | export function commitMount( 202 | instance : BaseElement, 203 | type : string, 204 | newProps : Object, 205 | internalInstanceHandle: Object 206 | ) : void { 207 | instance.commitMount(newProps); 208 | } 209 | 210 | // In this function, we figure out 'what props changed'. This is sort of like 211 | // 'shouldComponentUpdate' in React proper, but with considerably more detail 212 | // required. 213 | // 214 | // Basically, it's a diff of the props that changed. If nothing changed, we 215 | // return 'null', in which case React Fiber will NOT call commitUpdate. If 216 | // relevant props DID change, then we return an object representing that diff, 217 | // in which case React Fiber WILL call commitUpdate, with that object. 218 | // 219 | // ...or rather, it WILL call commitUpdate, with some object or another, at 220 | // some point in time. You see, this is where Fiber's prioritization scheme 221 | // comes into play. This may actually get called many times, but Fiber will- 222 | // in certain cases- batch updates so that they all happen at once. (I'm still 223 | // unclear as to the precise mechanics here.) At any rate, my understanding is 224 | // that React Fiber is capable of batching multiple "update payloads" together 225 | // into a single call to 'commitUpdate'. I could be wrong. 226 | // 227 | // Only ReactDOM seems to implement this with any significant complexity, so 228 | // I've chosen to implement it in the same fashion, with an array of 229 | // alternating keys/values. (See BaseElement.prepareUpdate for more details.) 230 | // 231 | // From what I can tell, it's completely possible to simply return a non-null 232 | // value from this method, in which case any prop change will eventually result 233 | // in a commitUpdate call. 234 | export function prepareUpdate( 235 | instance : BaseElement, 236 | type : string, 237 | oldProps : Object, 238 | newProps : Object, 239 | rootContainerInstance : IonizeContainer, 240 | hostContext : HostContext, 241 | ) : null | Array { 242 | return instance.prepareUpdate( 243 | oldProps, 244 | newProps, 245 | rootContainerInstance, 246 | ); 247 | } 248 | 249 | // This function is where updates are actually flushed to the underlying 250 | // abstraction layer- where we actually Do The Thing. 251 | export function commitUpdate( 252 | instance : BaseElement, 253 | updatePayload : Array, // Provided by prepareUpdate 254 | type : string, 255 | oldProps : Object, 256 | newProps : Object, 257 | internalInstanceHandle: Object, 258 | ): void { 259 | instance.commitUpdate(updatePayload, oldProps, newProps); 260 | } 261 | 262 | // The dual of prepareForCommit, this is where ReactDOM turns its event 263 | // handlers and such back on. 264 | export function resetAfterCommit(): void { 265 | } 266 | 267 | // These functions have something to do with how updates are prioritized and 268 | // scheduled. I have NO idea how the 'timeRemaining' piece works, but I've 269 | // pretty much lifted it wholesale from ReactTestRendererFiber and it seems to 270 | // work OK. For an interesting look at these, take a look at the ReactNoop 271 | // renderer's implementation in the React codebase, and then look at how the 272 | // _tests_ for Fiber code work. Apparently, they got things hooked up so they 273 | // can manually poke the 'clock' along and assert that updates happen at the 274 | // right time. 275 | export function scheduleAnimationCallback(fn: Function): void { 276 | setTimeout(fn); 277 | } 278 | 279 | // See above. Lifted wholesale from ReactTestRendererFiber. 280 | export function scheduleDeferredCallback(fn: Function): void { 281 | setTimeout(fn, 0, { timeRemaining: () => Infinity }); 282 | } 283 | 284 | // This value is called when client code is trying to get a ref to an 285 | // instantiated element. The easiest way to explain: ReactDOM returns the 286 | // actual DOM node object itself. In our case, we allow our 'element instances' 287 | // to decide what the user gets. 288 | // 289 | // This is actually pretty cool. I'm planning to use this to implement 'smart 290 | // refs', which will proxy Electron API calls in a way which corresponds to the 291 | // React element's position in the tree. 292 | export function getPublicInstance( 293 | instance: BaseElement 294 | ): (ElectronApp | BaseElement) { 295 | return instance.getPublicInstance(); 296 | } 297 | 298 | // For these last two, I got nothin'. That's why they're at the bottom. 299 | export const useSyncScheduling = false; 300 | 301 | export function shouldDeprioritizeSubtree( 302 | type : string, 303 | props : Object, 304 | ): boolean { 305 | return false; 306 | } 307 | -------------------------------------------------------------------------------- /src/elements/AppElement.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import BaseElement from './BaseElement'; 4 | 5 | import type { ElectronApp } from 'electron'; 6 | import TextElement from './TextElement'; 7 | import type IonizeContainer from '../IonizeContainer'; 8 | import type { HostContext } from '../IonizeHostConfig'; 9 | 10 | const PROP_TO_APP_EVENT_NAME = { 11 | 'onReady' : 'ready', 12 | }; 13 | 14 | export default class AppElement extends BaseElement { 15 | rootContainer : IonizeContainer; 16 | attachedHandlers: {[string]: Function}; 17 | 18 | constructor( 19 | props : Object, 20 | rootContainer : IonizeContainer, 21 | ) { 22 | super(props, rootContainer); 23 | 24 | this.rootContainer = rootContainer; 25 | this.attachedHandlers = {}; 26 | } 27 | 28 | getPublicInstance( 29 | ): ElectronApp { 30 | // TODO: We should probably return a proxy object so the user can't go 31 | // crazy with the possibilities here. 32 | return this.rootContainer.app; 33 | } 34 | 35 | // Hook up event handlers, if they exist 36 | finalizeBeforeMount( 37 | type : string, 38 | props : Object, 39 | ): boolean { 40 | let willCommit = false; 41 | 42 | for (const propKey in props) { 43 | // For the sake of simplicity, we wait until the Electron app is ready 44 | // before starting the process of mounting React elements. However, it's 45 | // a useful enough pattern that we'll go ahead and fire the onReady 46 | // handler if it's provided when gets mounted. 47 | if (propKey === 'onReady') { 48 | willCommit = true; 49 | continue; 50 | } 51 | 52 | if (PROP_TO_APP_EVENT_NAME.hasOwnProperty(propKey)) { 53 | const handler = props[propKey]; 54 | const eventKey = PROP_TO_APP_EVENT_NAME[propKey]; 55 | 56 | this.rootContainer.app.on(eventKey, handler); 57 | this.attachedHandlers[eventKey] = handler; 58 | } 59 | } 60 | 61 | return willCommit; 62 | } 63 | 64 | commitMount( 65 | newProps : Object 66 | ) { 67 | if (newProps.onReady !== undefined) { 68 | newProps.onReady(); 69 | } 70 | } 71 | 72 | finalizeBeforeRemoval(): void { 73 | for (const eventKey in this.attachedHandlers) { 74 | const handler = this.attachedHandlers[eventKey]; 75 | this.rootContainer.app.removeListener(eventKey, handler); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/elements/BaseElement.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import type IonizeContainer from '../IonizeContainer'; 4 | import type { HostContext } from '../IonizeHostConfig'; 5 | import type TextElement from './TextElement'; 6 | 7 | const SUPPORTED_PROPS: { [string]: boolean } = {}; 8 | 9 | export default class BaseElement { 10 | constructor( 11 | props : Object, 12 | rootContainer : IonizeContainer, 13 | ) { } 14 | 15 | appendChildBeforeMount( 16 | child : (BaseElement | TextElement) 17 | ): void { } 18 | 19 | finalizeBeforeMount( 20 | type : string, 21 | props : Object, 22 | rootContainerInstance : IonizeContainer 23 | ): boolean { 24 | return false; 25 | } 26 | 27 | finalizeBeforeRemoval( 28 | ): void { } 29 | 30 | commitMount( 31 | newProps : Object, 32 | ): void { } 33 | 34 | // TODO: There's probably a better way 35 | getPublicInstance(): mixed { 36 | return this; 37 | } 38 | 39 | getSupportedProps( 40 | ): { [string]: boolean } { 41 | return SUPPORTED_PROPS; 42 | } 43 | 44 | prepareUpdate( 45 | oldProps : Object, 46 | newProps : Object, 47 | rootContainerInstance : IonizeContainer, 48 | ): null | Array { 49 | const updatePayload: Array = []; 50 | 51 | const mergedProps = {}; 52 | for (const propKey in oldProps) { 53 | mergedProps[propKey] = [oldProps[propKey], null]; 54 | } 55 | for (const propKey in newProps) { 56 | if (mergedProps[propKey] !== undefined) { 57 | mergedProps[propKey][1] = newProps[propKey]; 58 | } else { 59 | mergedProps[propKey] = [null, newProps[propKey]]; 60 | } 61 | } 62 | 63 | const supportedProps = this.getSupportedProps(); 64 | 65 | for (const propKey in mergedProps) { 66 | if (!supportedProps[propKey]) { 67 | continue; 68 | } 69 | const [oldVal, newVal] = mergedProps[propKey]; 70 | if (oldVal !== newVal) { 71 | updatePayload.push(propKey, newVal); 72 | } 73 | } 74 | 75 | if (updatePayload.length === 0) { 76 | return null; 77 | } else { 78 | return updatePayload; 79 | } 80 | } 81 | 82 | commitUpdate( 83 | updatePayload : Array, 84 | oldProps : Object, 85 | newProps : Object, 86 | ): void { 87 | } 88 | 89 | appendChild( 90 | child : (BaseElement | TextElement) 91 | ): void { } 92 | 93 | insertBefore( 94 | child : (BaseElement | TextElement) 95 | ): void { } 96 | 97 | removeChild( 98 | child : (BaseElement | TextElement) 99 | ): void { } 100 | } 101 | -------------------------------------------------------------------------------- /src/elements/GenericElement.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import type IonizeContainer from '../IonizeContainer'; 4 | import type { HostContext } from '../IonizeHostConfig'; 5 | 6 | import BaseElement from './BaseElement'; 7 | import TextElement from './TextElement'; 8 | 9 | export default class GenericElement extends BaseElement { 10 | _type: string; 11 | props: Object; 12 | 13 | constructor( 14 | type : string, 15 | props : Object, 16 | rootContainer : IonizeContainer, 17 | ) { 18 | super(props, rootContainer); 19 | this._type = type; 20 | this.props = props; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/elements/MenuElement.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import { 4 | Menu, 5 | MenuItem 6 | } from 'electron'; 7 | 8 | import type IonizeContainer from '../IonizeContainer'; 9 | import type { HostContext } from '../IonizeHostConfig'; 10 | 11 | import BaseElement from './BaseElement'; 12 | import TextElement from './TextElement'; 13 | import SubmenuElement from './SubmenuElement'; 14 | import GenericElement from './GenericElement'; 15 | 16 | function commitApplicationMenu(menu: Menu, menuElements: Array) { 17 | for (const el of menuElements) { 18 | if (el instanceof SubmenuElement) { 19 | if (el.menuItem) { 20 | menu.append(el.menuItem); 21 | } 22 | } 23 | if (el instanceof GenericElement) { 24 | menu.append( 25 | new MenuItem({ label: el.props.label }) 26 | ); 27 | } 28 | } 29 | 30 | Menu.setApplicationMenu(menu); 31 | } 32 | 33 | export default class MenuElement extends BaseElement { 34 | menu: (null | Menu); 35 | menuElements: Array; 36 | 37 | getPublicInstance(): (null | Menu) { 38 | return this.menu; 39 | } 40 | 41 | constructor( 42 | props : Object, 43 | rootContainer : IonizeContainer, 44 | ) { 45 | super(props, rootContainer); 46 | this.menu = null; 47 | this.menuElements = []; 48 | } 49 | 50 | appendChildBeforeMount( 51 | child : (BaseElement | TextElement) 52 | ): void { 53 | if (child instanceof SubmenuElement 54 | || child instanceof GenericElement) { 55 | this.menuElements.push(child); 56 | } 57 | } 58 | 59 | finalizeBeforeMount( 60 | type : string, 61 | props : Object 62 | ): boolean { 63 | return true; 64 | } 65 | 66 | commitMount( 67 | newProps : Object 68 | ) { 69 | this.menu = new Menu(); 70 | commitApplicationMenu(this.menu, this.menuElements); 71 | } 72 | 73 | prepareUpdate( 74 | oldProps : Object, 75 | newProps : Object, 76 | rootContainerInstance : IonizeContainer 77 | ): null | Array { 78 | let updatePayload: (null | Array) = ['forceCommit', true]; 79 | return updatePayload; 80 | } 81 | 82 | appendChild( 83 | child : (BaseElement | TextElement) 84 | ): void { 85 | if (child instanceof SubmenuElement 86 | || child instanceof GenericElement) { 87 | this.menuElements.push(child); 88 | } 89 | } 90 | 91 | insertBefore( 92 | child : (BaseElement | TextElement), 93 | beforeChild : (BaseElement | TextElement), 94 | ): void { 95 | if (child instanceof SubmenuElement 96 | || child instanceof GenericElement) { 97 | const ix = this.menuElements.indexOf(child); 98 | if (ix !== -1) { 99 | this.menuElements.splice(ix, 1) 100 | } 101 | const bIx = this.menuElements.indexOf(beforeChild); 102 | if (bIx === -1) { 103 | throw new Error('This child does not exist.'); 104 | } 105 | this.menuElements.splice(bIx, 0, child); 106 | } 107 | } 108 | 109 | removeChild( 110 | child : (BaseElement | TextElement), 111 | ): void { 112 | const ix = this.menuElements.indexOf(child); 113 | this.menuElements.splice(ix, 1); 114 | } 115 | 116 | commitUpdate( 117 | updatePayload : Array, 118 | oldProps : Object, 119 | newProps : Object 120 | ): void { 121 | this.menu = new Menu(); 122 | commitApplicationMenu(this.menu, this.menuElements); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/elements/MenuItemElement.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import { MenuItem } from 'electron'; 4 | import type IonizeContainer from '../IonizeContainer'; 5 | import type { HostContext } from '../IonizeHostConfig'; 6 | import EventEmitter from 'events'; 7 | 8 | import BaseElement from './BaseElement'; 9 | import TextElement from './TextElement'; 10 | import configureWrappedEventHandler from '../util/configureWrappedEventHandler'; 11 | 12 | export const GENERIC_ELEMENT_ROLE_TYPES = [ 13 | "undo", "redo", "cut", "copy", "paste", "pasteandmatchstyle", "selectall", 14 | "delete", "minimize", "close", "quit", "reload", "forcereload", 15 | "toggledevtools", "togglefullscreen", "resetzoom", "zoomin", "zoomout" 16 | ]; 17 | 18 | export const OSX_GENERIC_ELEMENT_ROLE_TYPES = [ 19 | "about", "hide", "hideothers", "unhide", "startspeaking", "stopspeaking", 20 | "front", "zoom", "window", "help", "services" 21 | ]; 22 | 23 | export class MenuItemElement extends BaseElement { 24 | menuItem: MenuItem; 25 | getPublicInstance(): MenuItem { 26 | return this.menuItem; 27 | }; 28 | } 29 | 30 | export class SeparatorElement extends MenuItemElement { 31 | constructor( 32 | props : Object, 33 | rootContainer : IonizeContainer, 34 | ) { 35 | super(props, rootContainer); 36 | this.menuItem = new MenuItem({ 37 | type: 'separator' 38 | }); 39 | } 40 | } 41 | 42 | export class RoleMenuItemElement extends MenuItemElement { 43 | constructor( 44 | role : string, 45 | props : Object, 46 | rootContainer : IonizeContainer, 47 | ) { 48 | super(props, rootContainer); 49 | this.menuItem = new MenuItem({ role }); 50 | } 51 | } 52 | 53 | const SUPPORTED_PROPS = { 54 | label: true, 55 | onClick: true 56 | }; 57 | 58 | export class CustomMenuItemElement extends MenuItemElement { 59 | emitter: EventEmitter; 60 | attachedHandlers: { [string]: Function }; 61 | 62 | constructor( 63 | props : Object, 64 | rootContainer : IonizeContainer, 65 | ) { 66 | super(props, rootContainer); 67 | this.attachedHandlers = {}; 68 | this.emitter = new EventEmitter(); 69 | this.menuItem = new MenuItem({ 70 | type: 'normal', 71 | label: props.label, 72 | click: (menuItem, browserWindow, event) => { 73 | this.emitter.emit('click', event); 74 | } 75 | }); 76 | } 77 | 78 | finalizeBeforeMount( 79 | type : string, 80 | props : Object, 81 | ): boolean { 82 | if (props.onClick) { 83 | configureWrappedEventHandler( 84 | this.emitter, 85 | this.attachedHandlers, 86 | 'onClick', 87 | 'click', 88 | props.onClick, 89 | (rawHandler) => rawHandler() 90 | ); 91 | } 92 | return false; 93 | } 94 | 95 | getSupportedProps(): { [string]: boolean } { 96 | return SUPPORTED_PROPS; 97 | } 98 | 99 | commitUpdate( 100 | updatePayload : Array, 101 | oldProps : Object, 102 | newProps : Object 103 | ): void { 104 | for (let i = 0; i < updatePayload.length; i += 2) { 105 | let propKey = ((updatePayload[i]: any): string); 106 | let propVal = updatePayload[i+1]; 107 | switch (propKey) { 108 | case 'onClick': { 109 | propVal = ((propVal: any): Function); 110 | configureWrappedEventHandler( 111 | this.emitter, 112 | this.attachedHandlers, 113 | 'onClick', 114 | 'click', 115 | propVal, 116 | (rawHandler) => rawHandler() 117 | ); 118 | break; 119 | } 120 | } 121 | } 122 | 123 | this.menuItem = new MenuItem({ 124 | type: 'normal', 125 | label: newProps.label, 126 | click: (menuItem, browserWindow, event) => { 127 | this.emitter.emit('click', event); 128 | } 129 | }); 130 | } 131 | } 132 | 133 | export const isRoleMenuItemType = (type: string) => { 134 | if (GENERIC_ELEMENT_ROLE_TYPES.indexOf(type) !== -1) { 135 | return true; 136 | } 137 | if (process.platform === 'darwin' 138 | && OSX_GENERIC_ELEMENT_ROLE_TYPES.indexOf(type) !== -1) { 139 | return true; 140 | } 141 | 142 | return false; 143 | } 144 | -------------------------------------------------------------------------------- /src/elements/SubmenuElement.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import { 4 | Menu, 5 | MenuItem, 6 | } from 'electron'; 7 | 8 | import type IonizeContainer from '../IonizeContainer'; 9 | import type { HostContext } from '../IonizeHostConfig'; 10 | 11 | import BaseElement from './BaseElement'; 12 | import TextElement from './TextElement'; 13 | import GenericElement from './GenericElement'; 14 | import { MenuItemElement } from './MenuItemElement'; 15 | 16 | export default class SubmenuElement extends BaseElement { 17 | menuItem: (null | MenuItem); 18 | menuElements: Array; 19 | 20 | getPublicInstance(): (null | MenuItem) { 21 | return this.menuItem; 22 | } 23 | 24 | constructor( 25 | props : Object, 26 | rootContainer : IonizeContainer, 27 | ) { 28 | super(props, rootContainer); 29 | this.menuItem = null; 30 | this.menuElements = []; 31 | } 32 | 33 | appendChildBeforeMount( 34 | child: (BaseElement | TextElement) 35 | ): void { 36 | if (child instanceof SubmenuElement 37 | || child instanceof MenuItemElement) { 38 | this.menuElements.push(child); 39 | } 40 | } 41 | 42 | finalizeBeforeMount( 43 | type : string, 44 | props : Object, 45 | ): boolean { 46 | return true; 47 | } 48 | 49 | commitMount( 50 | newProps : Object, 51 | ): void { 52 | const submenu = new Menu(); 53 | 54 | for (const el of this.menuElements) { 55 | if (el.menuItem) { 56 | submenu.append(el.menuItem); 57 | } 58 | } 59 | 60 | this.menuItem = new MenuItem({ 61 | label: newProps.label, 62 | submenu 63 | }); 64 | } 65 | 66 | prepareUpdate( 67 | oldProps : Object, 68 | newProps : Object, 69 | rootContainerInstance : IonizeContainer 70 | ): null | Array { 71 | let updatePayload: Array = ['forceCommit', true]; 72 | return updatePayload; 73 | } 74 | 75 | appendChild( 76 | child : (BaseElement | TextElement) 77 | ): void { 78 | if (child instanceof SubmenuElement 79 | || child instanceof MenuItemElement) { 80 | this.menuElements.push(child); 81 | } 82 | } 83 | 84 | insertBefore( 85 | child : (BaseElement | TextElement), 86 | beforeChild : (BaseElement | TextElement), 87 | ): void { 88 | if (child instanceof SubmenuElement 89 | || child instanceof MenuItemElement) { 90 | const ix = this.menuElements.indexOf(child); 91 | if (ix !== -1) { 92 | this.menuElements.splice(ix, 1) 93 | } 94 | const bIx = this.menuElements.indexOf(beforeChild); 95 | if (bIx === -1) { 96 | throw new Error('This child does not exist.'); 97 | } 98 | this.menuElements.splice(bIx, 0, child); 99 | } 100 | } 101 | 102 | removeChild( 103 | child : (BaseElement | TextElement), 104 | ): void { 105 | const ix = this.menuElements.indexOf(child); 106 | this.menuElements.splice(ix, 1); 107 | } 108 | 109 | commitUpdate( 110 | updatePayload : Array, 111 | oldProps : Object, 112 | newProps : Object, 113 | ): void { 114 | const submenu = new Menu(); 115 | 116 | for (const el of this.menuElements) { 117 | if (el.menuItem) { 118 | submenu.append(el.menuItem); 119 | } 120 | } 121 | 122 | this.menuItem = new MenuItem({ 123 | label: newProps.label, 124 | submenu 125 | }); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/elements/TextElement.js: -------------------------------------------------------------------------------- 1 | export default class TextElement { 2 | constructor( 3 | text : string, 4 | rootContainer : IonizeContainer, 5 | ) { 6 | this.text = text; 7 | } 8 | 9 | commitUpdate( 10 | oldText : string, 11 | newText : string, 12 | ) { 13 | this.text = newText; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/elements/WindowElement.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import path from 'path'; 4 | import { BrowserWindow } from 'electron'; 5 | import BaseElement from './BaseElement'; 6 | import TextElement from './TextElement'; 7 | 8 | import type { ElectronApp } from 'electron'; 9 | import type IonizeContainer from '../IonizeContainer'; 10 | import type { HostContext } from '../IonizeHostConfig'; 11 | import configureWrappedEventHandler from '../util/configureWrappedEventHandler'; 12 | import { getCurrentFiberStackAddendum } from 'react-dom/lib/ReactDebugCurrentFiber'; 13 | 14 | /* PROPS NEEDED 15 | * title 16 | * minSize 17 | * maxSize 18 | * 19 | * NOTE: ABOUT CONTROLLED ATTRIBUTES 20 | * Controlled attributes behave in similar fashion to the tag in React 21 | * DOM. Specifically, if you include a prop which specifies the value of a 22 | * controlled attribute, you must also include an event handler which updates 23 | * the value of that prop. 24 | * 25 | * For instance, If you define the 'size' prop, the window will be set to 26 | * 'resizable: false', and the user will not be allowed to change it UNLESS 27 | * you also define the 'onResize' event handler, which should cause the size 28 | * to change. In this case, you should ensure that the `size` prop is updated 29 | * accordingly. 30 | * 31 | * If you do NOT define a controlled attribute, but you would still like to 32 | * define an initial value, most controlled attributes have a 'defaultXXX' 33 | * analogue that simply sets the value when the element is created and then 34 | * allows the user to adjust it as they please. 35 | * 36 | * Props that behave this way are marked as such below. 37 | * 38 | * size (controlled) 39 | * onResize 40 | * resizable 41 | * defaultSize 42 | * 43 | * * position (controlled) 44 | * onMove 45 | * onMoved 46 | * defaultPosition 47 | * movable 48 | * 49 | * fullscreen (controlled) 50 | * onEnterFullScreen 51 | * onLeaveFullScreen 52 | * fullscreenable 53 | * 54 | * minimized (controlled) 55 | * onMinimize 56 | * onRestore 57 | * minimizable 58 | * 59 | * maximized (controlled) 60 | * onMaximize 61 | * onUnmaximize 62 | * maximizable 63 | * 64 | * focused (controlled) 65 | * onBlur 66 | * onFocus 67 | * focusable 68 | * 69 | * - By default, the show() method on a BrowserWindow should be called 70 | * immediately upon mount. 71 | * show (controlled) 72 | * onReadyToShow 73 | * onShow 74 | * onHide 75 | * 76 | * closable 77 | * onClose 78 | * onClosed (???) 79 | * 80 | * TBD props 81 | * alwaysOnTop 82 | * skipTaskbar 83 | * autoHideMenuBar 84 | * onPageTitleUpdated 85 | * onUnresponsive 86 | * onResponsive 87 | * onAppCommand 88 | * onScrollTouchBegin 89 | * onScrollTouchEnd 90 | * onScrollTouchEdge 91 | * onSwipe 92 | */ 93 | 94 | const SUPPORTED_PROPS = { 95 | 'show': true, 96 | 'position': true, 97 | 'size': true, 98 | 'file': true, 99 | 'onReadyToShow': true, 100 | 'onResize': true, 101 | 'showDevTools': true, 102 | 'acceptFirstMouse': true, 103 | }; 104 | 105 | const PROP_TO_APP_EVENT_NAME = { 106 | 'onReadyToShow' : 'ready-to-show', 107 | 'onResize' : 'resize', 108 | 'onMove' : 'move', 109 | 'onMoved' : 'moved', 110 | }; 111 | 112 | export default class WindowElement extends BaseElement { 113 | parentWindow: (null | BrowserWindow); 114 | window: BrowserWindow; 115 | attachedHandlers: {[string]: Function}; 116 | 117 | constructor( 118 | props : Object, 119 | rootContainer : IonizeContainer, 120 | ) { 121 | super(props, rootContainer); 122 | 123 | this.window = new BrowserWindow({ 124 | show: false, 125 | acceptFirstMouse: !!props.acceptFirstMouse 126 | }); 127 | this.parentWindow = null; 128 | this.attachedHandlers = {}; 129 | } 130 | 131 | appendChildBeforeMount( 132 | child : (BaseElement | TextElement) 133 | ): void { 134 | if (child instanceof DialogElement 135 | || child instanceof WindowElement) { 136 | child.parentWindow = this.window; 137 | } 138 | } 139 | 140 | // Hook up event handlers, if they exist 141 | finalizeBeforeMount( 142 | type : string, 143 | props : Object, 144 | ): boolean { 145 | if (props.onReadyToShow !== undefined) { 146 | configureWrappedEventHandler( 147 | this.window, 148 | this.attachedHandlers, 149 | 'onReadyToShow', 150 | 'ready-to-show', 151 | props.onReadyToShow, 152 | (rawHandler) => rawHandler() 153 | ); 154 | } 155 | 156 | if (props.showDevTools) { 157 | this.window.webContents.openDevTools(); 158 | } 159 | 160 | configureSize.call(this, props); 161 | configurePosition.call(this, props); 162 | configureFile.call(this, props); 163 | 164 | if (this.parentWindow) { 165 | this.window.setParentWindow(this.parentWindow); 166 | } 167 | 168 | return true; 169 | } 170 | 171 | commitMount( 172 | newProps : Object, 173 | ) { 174 | if (newProps.show) { 175 | this.window.show(); 176 | } 177 | } 178 | 179 | finalizeBeforeRemoval(): void { 180 | this.window.close(); 181 | for (const eventKey in this.attachedHandlers) { 182 | const handler = this.attachedHandlers[eventKey]; 183 | this.window.removeListener(eventKey, handler); 184 | } 185 | } 186 | 187 | getPublicInstance(): BrowserWindow { 188 | // TBD: Make this a 'smart ref' so users can't modify window state that 189 | // we control. 190 | return this.window; 191 | } 192 | 193 | getSupportedProps(): {[string]: boolean} { 194 | return SUPPORTED_PROPS; 195 | } 196 | 197 | commitUpdate( 198 | updatePayload : Array, 199 | oldProps : Object, 200 | newProps : Object, 201 | ): void { 202 | for (let i = 0; i < updatePayload.length; i += 2) { 203 | let propKey = ((updatePayload[i]: any): string); 204 | let propVal = updatePayload[i+1]; 205 | 206 | // If we hit this point, we KNOW the prop changed, so we don't need to do 207 | // any checking. Just update to the new value. 208 | switch (propKey) { 209 | case 'onReadyToShow': { 210 | propVal = ((propVal: any): Function); 211 | configureWrappedEventHandler( 212 | this.window, 213 | this.attachedHandlers, 214 | 'onReadyToShow', 215 | 'ready-to-show', 216 | propVal, 217 | (rawHandler) => rawHandler() 218 | ); 219 | break; 220 | } 221 | case 'show': { 222 | if (propVal) { 223 | this.window.show(); 224 | } else { 225 | this.window.hide(); 226 | } 227 | break; 228 | } 229 | case 'size': 230 | case 'defaultSize': 231 | case 'onResize': { 232 | // TODO: figure out if we can avoid calling this multiple times 233 | configureSize.call(this, newProps); 234 | break; 235 | } 236 | case 'position': 237 | case 'defaultPosition': 238 | case 'onMove': 239 | case 'onMoved': { 240 | // TODO: figure out if we can avoid calling this multiple times 241 | configurePosition.call(this, newProps); 242 | break; 243 | } 244 | case 'file': { 245 | configureFile.call(this, newProps); 246 | break; 247 | } 248 | case 'acceptFirstMouse': 249 | if (process.env.NODE_ENV !== 'production') { 250 | console.warn( 251 | 'A component is changing the acceptFirstMouse prop of a window. ' + 252 | 'The acceptFirstMouse prop only has effect when the window is first rendered, ' + 253 | 'changing it after the first render does nothing. ' + 254 | getCurrentFiberStackAddendum() 255 | ); 256 | } 257 | break; 258 | } 259 | } 260 | } 261 | 262 | appendChildBeforeMount( 263 | child : (BaseElement | TextElement) 264 | ): void { 265 | if (child instanceof WindowElement) { 266 | child.parentWindow = this.window; 267 | } 268 | } 269 | 270 | appendChild( 271 | child : (BaseElement | TextElement) 272 | ): void { 273 | if (child instanceof WindowElement) { 274 | child.parentWindow = this.window; 275 | } 276 | } 277 | 278 | insertBefore( 279 | child : (BaseElement | TextElement), 280 | beforeChild : (BaseElement | TextElement) 281 | ): void { 282 | if (child instanceof WindowElement) { 283 | child.parentWindow = this.window; 284 | } 285 | } 286 | 287 | removeChild( 288 | child : (BaseElement | TextElement) 289 | ): void { 290 | if (child instanceof WindowElement) { 291 | child.parentWindow = null; 292 | } 293 | } 294 | 295 | } 296 | 297 | function configureFile({ file }: Object) { 298 | if (file) { 299 | const filePath = path.resolve(file); 300 | this.window.loadURL(`file://${filePath}`); 301 | } 302 | } 303 | 304 | function configureSize({ size, onResize, defaultSize }: Object) { 305 | configureWrappedEventHandler( 306 | this.window, 307 | this.attachedHandlers, 308 | 'onResize', 309 | 'resize', 310 | onResize, 311 | (rawHandler) => { 312 | const size = this.window.getSize(); 313 | rawHandler(size); 314 | } 315 | ); 316 | 317 | if (!size && defaultSize) { 318 | this.window.setSize(...defaultSize); 319 | this.window.setResizable(true); 320 | return; 321 | } 322 | if (!size && !defaultSize) { 323 | this.window.setResizable(true); 324 | return; 325 | } 326 | if (size && onResize) { 327 | this.window.setSize(...size); 328 | this.window.setResizable(true); 329 | return; 330 | } 331 | if (size && !onResize) { 332 | this.window.setSize(...size); 333 | this.window.setResizable(false); 334 | return; 335 | } 336 | } 337 | 338 | function configurePosition({ 339 | position, 340 | onMove, 341 | onMoved, 342 | defaultPosition 343 | }: Object) { 344 | 345 | configureWrappedEventHandler( 346 | this.window, 347 | this.attachedHandlers, 348 | 'onMove', 349 | 'move', 350 | onMove, 351 | (rawHandler) => { 352 | const position = this.window.getPosition(); 353 | rawHandler(position); 354 | } 355 | ); 356 | 357 | configureWrappedEventHandler( 358 | this.window, 359 | this.attachedHandlers, 360 | 'onMoved', 361 | 'moved', 362 | onMoved, 363 | (rawHandler) => { 364 | const position = this.window.getPosition(); 365 | rawHandler(position); 366 | } 367 | ); 368 | 369 | if (!position && defaultPosition) { 370 | this.window.setPosition(...defaultPosition); 371 | this.window.setMovable(true); 372 | return; 373 | } 374 | if (!position && !defaultPosition) { 375 | this.window.setMovable(true); 376 | return; 377 | } 378 | if (position && (onMove || onMoved)) { 379 | this.window.setPosition(...position); 380 | this.window.setMovable(true); 381 | return; 382 | } 383 | if (position && !(onMove || onMoved)) { 384 | this.window.setPosition(...position); 385 | this.window.setMovable(false); 386 | return; 387 | } 388 | } 389 | -------------------------------------------------------------------------------- /src/elements/index.js: -------------------------------------------------------------------------------- 1 | import BaseElement from './BaseElement'; 2 | import AppElement from './AppElement'; 3 | import WindowElement from './WindowElement'; 4 | import GenericElement from './GenericElement'; 5 | import TextElement from './TextElement'; 6 | import MenuElement from './MenuElement'; 7 | import SubmenuElement from './SubmenuElement'; 8 | import { 9 | SeparatorElement, 10 | RoleMenuItemElement, 11 | CustomMenuItemElement, 12 | isRoleMenuItemType, 13 | } from './MenuItemElement'; 14 | 15 | export { 16 | BaseElement, 17 | AppElement, 18 | WindowElement, 19 | GenericElement, 20 | TextElement, 21 | MenuElement, 22 | SubmenuElement, 23 | }; 24 | 25 | export function createElectronInstance( 26 | type : string, 27 | props : Object, 28 | container : IonizeContainer, 29 | context : HostContext, 30 | ): BaseElement { 31 | switch (type) { 32 | case 'app': { 33 | return new AppElement(props, container); 34 | } 35 | case 'window': { 36 | return new WindowElement(props, container); 37 | } 38 | case 'menu': { 39 | return new MenuElement(props, container); 40 | } 41 | case 'submenu': { 42 | return new SubmenuElement(props, container); 43 | } 44 | case 'sep': { 45 | return new SeparatorElement(props, container); 46 | } 47 | case 'item': { 48 | return new CustomMenuItemElement(props, container); 49 | } 50 | default: { 51 | if (isRoleMenuItemType(type)) { 52 | return new RoleMenuItemElement(type, props, container); 53 | } else { 54 | return new GenericElement(type, props, container); 55 | } 56 | } 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | IonizeFiber, 3 | IonizeRenderer, 4 | } from './IonizeFiber.js'; 5 | 6 | export { IonizeRenderer }; 7 | export default IonizeFiber; 8 | -------------------------------------------------------------------------------- /src/util/configureWrappedEventHandler.js: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'events'; 2 | import BaseElement from '../elements/BaseElement'; 3 | 4 | export default function configureWrappedEventHandler( 5 | emitter: EventEmitter, 6 | attachedHandlers: { [string]: Function }, 7 | propKey: string, 8 | eventKey: string, 9 | rawHandler: Function, 10 | wrapper: Function 11 | ) { 12 | const rawEventKey = `${eventKey}_raw` 13 | const removingHandler = ( 14 | rawHandler === undefined && 15 | attachedHandlers[rawEventKey] !== undefined 16 | ); 17 | 18 | const changingHandler = ( 19 | rawHandler !== undefined && 20 | attachedHandlers[rawEventKey] !== undefined && 21 | rawHandler !== attachedHandlers[rawEventKey] 22 | ); 23 | 24 | const newHandler = ( 25 | rawHandler !== undefined && 26 | attachedHandlers[rawEventKey] === undefined 27 | ); 28 | 29 | if (removingHandler || changingHandler) { 30 | const existingHandler = attachedHandlers[eventKey]; 31 | emitter.removeListener(eventKey, existingHandler); 32 | delete attachedHandlers[eventKey]; 33 | delete attachedHandlers[rawEventKey]; 34 | } 35 | 36 | if (changingHandler || newHandler) { 37 | const handler = () => wrapper(rawHandler); 38 | attachedHandlers[eventKey] = handler; 39 | attachedHandlers[rawEventKey] = rawHandler; 40 | emitter.on(eventKey, handler); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/app.spec.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from 'react'; 4 | import Ionize from 'react-ionize'; 5 | import { 6 | app as electronApp, 7 | ElectronTestUtils 8 | } from 'electron'; 9 | 10 | describe('', function() { 11 | beforeEach(() => { 12 | Ionize.reset(); 13 | ElectronTestUtils.reset(); 14 | }); 15 | 16 | describe('props', function() { 17 | describe('onReady', function() { 18 | it("should be triggered when the app is first mounted", function(done) { 19 | let onReadySpy = sinon.spy(); 20 | 21 | electronApp.test_makeReady(); 22 | 23 | Ionize.start( 24 | , 25 | () => { 26 | expect(onReadySpy).to.have.been.calledOnce; 27 | done(); 28 | } 29 | ); 30 | }); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /test/lib/electron.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | console.log("Loading dummy electron.js"); 4 | import EventEmitter from 'events'; 5 | 6 | class ElectronApp extends EventEmitter { 7 | _isReady: boolean; 8 | 9 | constructor() { 10 | super(); 11 | this._isReady = false; 12 | } 13 | 14 | isReady(): boolean { 15 | return this._isReady; 16 | } 17 | 18 | test_makeReady() { 19 | this._isReady = true; 20 | this.emit('ready'); 21 | } 22 | } 23 | 24 | export let app = new ElectronApp(); 25 | 26 | class _BrowserWindow { 27 | show() {} 28 | hide() {} 29 | on() {} 30 | setParentWindow(parentWindow: _BrowserWindow) {} 31 | removeAllListeners(eventType: string) {} 32 | setPosition(x: number, y: number) {} 33 | setMovable(isMovable: boolean) {} 34 | setSize(width: number, height: number) {} 35 | setResizable(isResizable: boolean) {} 36 | } 37 | 38 | let i_win = 0; 39 | export let windows = [ 40 | new _BrowserWindow() 41 | ]; 42 | 43 | export const BrowserWindow = () => { 44 | const rval = windows[i_win]; 45 | 46 | i_win += 1; 47 | if (!windows[i_win]) { 48 | windows.push(new _BrowserWindow()) 49 | } 50 | 51 | return rval; 52 | } 53 | 54 | class _Menu { 55 | _id: number; 56 | _children: Array<_MenuItem>; 57 | 58 | static setApplicationMenu; 59 | constructor(i: number) { 60 | this._id = i; 61 | this._children = []; 62 | } 63 | 64 | append(menuItem: _MenuItem) { 65 | this._children.push(menuItem); 66 | } 67 | 68 | flush() { 69 | const obj = { 70 | items: [] 71 | }; 72 | 73 | for (const child of this._children) { 74 | obj.items.push(child.flush()) 75 | } 76 | 77 | return obj; 78 | } 79 | }; 80 | 81 | let i_menu = 0; 82 | export let menus = [ 83 | new _Menu(i_menu) 84 | ]; 85 | 86 | export const Menu = () => { 87 | const rval = menus[i_menu]; 88 | 89 | i_menu += 1; 90 | if (!menus[i_menu]) { 91 | menus.push(new _Menu(i_menu)) 92 | } 93 | 94 | return rval; 95 | } 96 | 97 | Menu.setApplicationMenu = () => {} 98 | 99 | 100 | class _MenuItem { 101 | _id: number; 102 | opts: { 103 | submenu?: (_Menu) 104 | }; 105 | constructor(i: number) { 106 | this._id = i; 107 | } 108 | 109 | _reconstruct(opts: Object) { 110 | this.opts = opts; 111 | } 112 | 113 | flush() { 114 | const obj = {} 115 | if (this.opts.role) { 116 | obj.role = this.opts.role; 117 | } 118 | if (this.opts.label) { 119 | obj.label = this.opts.label; 120 | } 121 | if(this.opts.submenu) { 122 | obj.submenu = this.opts.submenu.flush(); 123 | } 124 | return obj; 125 | } 126 | } 127 | 128 | let i_menuItem = 0; 129 | export let menuItems = [ 130 | new _MenuItem(i_menuItem) 131 | ]; 132 | 133 | export const MenuItem = (opts: Object) => { 134 | const rval = menuItems[i_menuItem]; 135 | rval._reconstruct(opts); 136 | 137 | i_menuItem += 1; 138 | if (!menuItems[i_menuItem]) { 139 | menuItems.push(new _MenuItem(i_menuItem)) 140 | } 141 | 142 | return rval; 143 | } 144 | 145 | export const ElectronTestUtils = { 146 | getWindow(i: number) { 147 | if (!windows[i]) { 148 | windows[i] = new _BrowserWindow(); 149 | } 150 | return windows[i]; 151 | }, 152 | 153 | getMenu(i: number) { 154 | if (!menus[i]) { 155 | menus[i] = new _Menu(i); 156 | } 157 | return menus[i]; 158 | }, 159 | 160 | getMenuItem(i: number) { 161 | if (!menuItems[i]) { 162 | menuItems[i] = new _MenuItem(i); 163 | } 164 | return menuItems[i]; 165 | }, 166 | 167 | 168 | reset: () => { 169 | i_win = 0; 170 | i_menu = 0; 171 | i_menuItem = 0; 172 | windows = [ 173 | new _BrowserWindow() 174 | ]; 175 | menus = [ 176 | new _Menu(0) 177 | ]; 178 | menuItems = [ 179 | new _MenuItem(0) 180 | ]; 181 | 182 | app = new ElectronApp(); 183 | } 184 | }; 185 | -------------------------------------------------------------------------------- /test/main.spec.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from 'react'; 4 | import Ionize, { IonizeRenderer } from 'react-ionize'; 5 | import { 6 | app, 7 | ElectronTestUtils 8 | } from 'electron'; 9 | 10 | describe('Ionize', function() { 11 | let createContainerSpy; 12 | let updateContainerSpy; 13 | 14 | beforeEach(() => { 15 | Ionize.reset(); 16 | ElectronTestUtils.reset(); 17 | createContainerSpy = sinon.spy(IonizeRenderer, 'createContainer'); 18 | updateContainerSpy = sinon.spy(IonizeRenderer, 'updateContainer'); 19 | }); 20 | 21 | afterEach(() => { 22 | createContainerSpy.restore(); 23 | updateContainerSpy.restore(); 24 | }); 25 | 26 | describe('start()', function () { 27 | context('when the Electron app is ready', function() { 28 | it('should call isReady', function() { 29 | app.test_makeReady(); 30 | Ionize.start(); 31 | 32 | expect(createContainerSpy).to.have.been.calledOnce; 33 | expect(updateContainerSpy).to.have.been.calledOnce; 34 | }); 35 | }); 36 | 37 | context('before the Electron app is ready', function() { 38 | it('should call isReady, then register an event handler', function() { 39 | app.test_makeReady(); 40 | Ionize.start(); 41 | 42 | expect(createContainerSpy).to.have.been.calledOnce; 43 | expect(updateContainerSpy).to.have.been.calledOnce; 44 | }); 45 | 46 | it('should never call createContainer/updateContainer if the app isn\'t ready', function() { 47 | Ionize.start(); 48 | 49 | expect(createContainerSpy).to.have.been.calledOnce; 50 | expect(updateContainerSpy).not.to.have.been.called; 51 | }); 52 | }); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /test/menu.spec.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from 'react'; 4 | import Ionize from 'react-ionize'; 5 | import { 6 | app, 7 | ElectronTestUtils, 8 | Menu 9 | } from 'electron'; 10 | 11 | describe('', function() { 12 | beforeEach(() => { 13 | Ionize.reset(); 14 | ElectronTestUtils.reset(); 15 | app.test_makeReady(); 16 | sinon.stub(Menu, 'setApplicationMenu'); 17 | }); 18 | 19 | afterEach(() => { 20 | Menu.setApplicationMenu.restore(); 21 | }); 22 | 23 | it('should only call Menu.setApplicationMenu with the root menu', function(done) { 24 | const rootMenu = ElectronTestUtils.getMenu(1); 25 | 26 | Ionize.start( 27 | 28 | 29 | , 30 | () => { 31 | expect(Menu.setApplicationMenu).to.have.been.calledOnce; 32 | expect(Menu.setApplicationMenu).to.have.been.calledWith(rootMenu); 33 | done(); 34 | } 35 | ); 36 | }); 37 | 38 | it('should be possible to modify item labels', function(done) { 39 | let menuItem; 40 | Ionize.chain( 41 | 42 | 43 | { menuItem = c;}} /> 44 | 45 | , 46 | () => { 47 | expect(menuItem.flush()) 48 | .to.deep.equal({ 49 | label: 'Foo' 50 | }) 51 | }, 52 | 53 | 54 | { menuItem = c;}} /> 55 | 56 | , 57 | () => { 58 | expect(menuItem.flush()) 59 | .to.deep.equal({ 60 | label: 'Bar' 61 | }) 62 | done(); 63 | } 64 | ); 65 | }); 66 | 67 | it('should be possible to add items to a submenu', function(done) { 68 | let subMenu; 69 | 70 | Ionize.chain( 71 | 72 | { subMenu = c;}}> 73 | 74 | , 75 | 76 | { subMenu = c;}}> 77 | 78 | 79 | , 80 | () => { 81 | expect(subMenu.flush()) 82 | .to.deep.equal({ 83 | submenu: { 84 | items: [ 85 | { label: 'One' } 86 | ] 87 | }, 88 | }); 89 | done(); 90 | }); 91 | }); 92 | 93 | it('should be possible to add/remove items from a submenu', function(done) { 94 | let subMenu; 95 | 96 | Ionize.chain( 97 | 98 | { subMenu = c;}}> 99 | 100 | 101 | , 102 | () => { 103 | expect(subMenu.flush()) 104 | .to.deep.equal({ 105 | submenu: { 106 | items: [ 107 | { label: 'One' } 108 | ] 109 | }, 110 | }); 111 | }, 112 | 113 | { subMenu = c;}}> 114 | 115 | 116 | 117 | , 118 | () => { 119 | expect(subMenu.flush()) 120 | .to.deep.equal({ 121 | submenu: { 122 | items: [ 123 | { label: 'One' }, 124 | { label: 'Two' } 125 | ] 126 | } 127 | }); 128 | }, 129 | 130 | { subMenu = c;}}> 131 | 132 | 133 | , 134 | () => { 135 | expect(subMenu.flush()) 136 | .to.deep.equal({ 137 | submenu: { 138 | items: [ 139 | { label: 'One' }, 140 | ] 141 | } 142 | }); 143 | done(); 144 | } 145 | ); 146 | 147 | }); 148 | 149 | it('should call rootMenu.append with a MenuItem built from the submenu', function(done) { 150 | let rootMenu; 151 | 152 | Ionize.start( 153 | { rootMenu = c; }}> 154 | 155 | 156 | 157 | 158 | 159 | 160 | , 161 | () => { 162 | expect(rootMenu.flush()) 163 | .to.deep.equal({ 164 | items: [ 165 | { label: 'Magic', 166 | submenu: { 167 | items: [ 168 | { label: 'One' }, 169 | { label: 'More Magic', 170 | submenu: { 171 | items: [ 172 | { label: 'Two' } 173 | ] 174 | } 175 | } 176 | ] 177 | } 178 | } 179 | ] 180 | }); 181 | done(); 182 | } 183 | ); 184 | }); 185 | 186 | }); 187 | -------------------------------------------------------------------------------- /test/test-setup.js: -------------------------------------------------------------------------------- 1 | const chai = require('chai'); 2 | const sinon = require('sinon'); 3 | 4 | chai.use(require('sinon-chai')); 5 | 6 | global.chai = chai; 7 | global.expect = chai.expect; 8 | global.sinon = sinon; 9 | -------------------------------------------------------------------------------- /test/window.spec.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from 'react'; 4 | import Ionize, { IonizeRenderer } from 'react-ionize'; 5 | import { 6 | app, 7 | ElectronTestUtils 8 | } from 'electron'; 9 | 10 | describe('', function() { 11 | beforeEach(() => { 12 | Ionize.reset(); 13 | ElectronTestUtils.reset(); 14 | app.test_makeReady(); 15 | }); 16 | 17 | describe('props', function() { 18 | describe('show', function() { 19 | context('during the initial mount', function() { 20 | context('when true', function() { 21 | it('the window should immediately become visible', function(done) { 22 | const win = ElectronTestUtils.getWindow(0); 23 | const show = sinon.stub(win, 'show'); 24 | 25 | Ionize.start( 26 | , 27 | () => { 28 | expect(show).to.have.been.calledOnce; 29 | done(); 30 | } 31 | ); 32 | }); 33 | }); 34 | 35 | context('when false', function() { 36 | it('the window should NOT become visible', function(done) { 37 | const win = ElectronTestUtils.getWindow(0); 38 | const show = sinon.stub(win, 'show'); 39 | 40 | Ionize.start( 41 | , 42 | () => { 43 | expect(show).not.to.have.been.called; 44 | done(); 45 | } 46 | ); 47 | }); 48 | }); 49 | 50 | context('when an updated is committed', () => { 51 | context('when it transitions from FALSE to TRUE', function() { 52 | it('should cause the window to become visible', function(done) { 53 | const win = ElectronTestUtils.getWindow(0); 54 | const show = sinon.stub(win, 'show'); 55 | 56 | Ionize.chain( 57 | , 58 | () => { 59 | expect(show).not.to.have.been.called; 60 | }, 61 | , 62 | () => { 63 | expect(show).to.have.been.calledOnce; 64 | done(); 65 | } 66 | ); 67 | }) 68 | }); 69 | 70 | context('when it transitions from TRUE to FALSE', function() { 71 | it('should cause the window to become hidden', function(done) { 72 | const win = ElectronTestUtils.getWindow(0); 73 | const show = sinon.stub(win, 'show'); 74 | const hide = sinon.stub(win, 'hide'); 75 | 76 | Ionize.chain( 77 | , 78 | () => { 79 | expect(show).to.have.been.calledOnce; 80 | expect(hide).not.to.have.been.called; 81 | }, 82 | , 83 | () => { 84 | expect(hide).to.have.been.calledOnce; 85 | done(); 86 | } 87 | ); 88 | }) 89 | }); 90 | }); 91 | }); 92 | }); 93 | }); 94 | }); 95 | -------------------------------------------------------------------------------- /webpack.examples.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | 4 | if (process.env.EXAMPLE_ENTRY === undefined) { 5 | throw new Error('You must provide an example entry file!'); 6 | } 7 | 8 | const base = path.resolve(__dirname); 9 | const paths = { 10 | base, 11 | src : path.resolve(base, 'examples'), 12 | lib : path.resolve(base, 'src'), 13 | dist : path.resolve(base, 'dist'), 14 | }; 15 | 16 | // Configuration for Ionize examples 17 | module.exports = { 18 | performance: { 19 | hints: false, 20 | }, 21 | target: 'electron', 22 | devtool: 'source-map', 23 | entry: process.env.EXAMPLE_ENTRY, 24 | context: paths.src, 25 | output: { 26 | filename: 'main.js', 27 | path: paths.dist, 28 | }, 29 | resolve: { 30 | extensions: ['.js'], 31 | modules: [ 32 | paths.src, 33 | paths.lib, 34 | 'node_modules' 35 | ], 36 | alias: { 37 | 'react-ionize': path.resolve(paths.lib, 'index.js') 38 | } 39 | }, 40 | node: { 41 | __dirname: false, 42 | __filename: false, 43 | }, 44 | externals: { 45 | '7zip': 'commonjs 7zip' 46 | }, 47 | module: { 48 | rules: [ 49 | { 50 | test: /\.html$/, 51 | exclude: /node_modules/, 52 | use: { 53 | loader: 'file-loader', 54 | options: { 55 | name: '[name].html' 56 | } 57 | } 58 | }, 59 | { 60 | test: /\.js$/, 61 | exclude: /node_modules/, 62 | use: { 63 | loader: 'babel-loader', 64 | options: { 65 | presets: ['react'], 66 | } 67 | } 68 | }, 69 | { 70 | test: /\.json$/, 71 | loader: 'json-loader', 72 | }, 73 | ], 74 | }, 75 | }; 76 | -------------------------------------------------------------------------------- /webpack.test.config.js: -------------------------------------------------------------------------------- 1 | // Electron Main Process configuration 2 | const path = require('path'); 3 | const webpack = require('webpack'); 4 | 5 | const base = path.resolve(__dirname); 6 | const paths = { 7 | base, 8 | src : path.resolve(base, 'test'), 9 | lib : path.resolve(base, 'src'), 10 | libtest : path.resolve(base, 'test', 'lib'), 11 | }; 12 | 13 | module.exports = { 14 | performance: { 15 | hints: false, 16 | }, 17 | target: 'node', 18 | devtool: 'cheap-module-source-map', 19 | context: paths.src, 20 | resolve: { 21 | extensions: ['.js'], 22 | modules: [ 23 | paths.src, 24 | paths.lib, 25 | 'node_modules' 26 | ], 27 | alias: { 28 | 'electron': path.resolve(paths.libtest, 'electron.js'), 29 | 'react-ionize': path.resolve(paths.lib, 'index.js'), 30 | } 31 | }, 32 | module: { 33 | rules: [ 34 | { 35 | test: /\.js$/, 36 | exclude: /node_modules/, 37 | use: { 38 | loader: 'babel-loader', 39 | options: { 40 | presets: ['react'], 41 | } 42 | } 43 | }, 44 | { 45 | test: /\.json$/, 46 | loader: 'json-loader', 47 | }, 48 | ], 49 | }, 50 | node: { 51 | __dirname: false, 52 | __filename: false, 53 | }, 54 | }; 55 | --------------------------------------------------------------------------------