├── .github └── dependabot.yml ├── .gitattributes ├── package.json ├── LICENSE ├── .gitignore ├── README.md ├── CODE_OF_CONDUCT.md ├── src └── dev.js └── nw-dev-logo.svg /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "." 5 | schedule: 6 | interval: "weekly" 7 | day: "saturday" 8 | versioning-strategy: increase 9 | groups: 10 | npm: 11 | patterns: 12 | - "*" 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nw-dev", 3 | "description": "A drop-in library for nw.js development", 4 | "version": "3.0.1", 5 | "repository": { 6 | "type": "git", 7 | "url": "http://github.com/nwutils/nw-dev.git" 8 | }, 9 | "bugs": { 10 | "url": "http://github.com/nwutils/nw-dev/issues" 11 | }, 12 | "author": "Isaiah Odhner", 13 | "license": "MIT", 14 | "keywords": [ 15 | "live-reload", 16 | "dev-reload", 17 | "auto-reload", 18 | "reload", 19 | "webkit", 20 | "node-webkit", 21 | "nw.js", 22 | "nwjs", 23 | "nw", 24 | "app", 25 | "desktop", 26 | "dev", 27 | "developer", 28 | "development" 29 | ], 30 | "main": "src/dev.js", 31 | "dependencies": { 32 | "chokidar": "^4.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 NW.js Utilities 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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | node_modules/ 3 | 4 | # Logs 5 | logs 6 | *.log 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # Commenting this out is preferred by some people, see 27 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 28 | node_modules 29 | 30 | # Users Environment Variables 31 | .lock-wscript 32 | 33 | # ========================= 34 | # Operating System Files 35 | # ========================= 36 | 37 | # OSX 38 | # ========================= 39 | 40 | .DS_Store 41 | .AppleDouble 42 | .LSOverride 43 | 44 | # Thumbnails 45 | ._* 46 | 47 | # Files that might appear on external disk 48 | .Spotlight-V100 49 | .Trashes 50 | 51 | # Directories potentially created on remote AFP share 52 | .AppleDB 53 | .AppleDesktop 54 | Network Trash Folder 55 | Temporary Items 56 | .apdisk 57 | 58 | # Windows 59 | # ========================= 60 | 61 | # Windows image file caches 62 | Thumbs.db 63 | ehthumbs.db 64 | 65 | # Folder config file 66 | Desktop.ini 67 | 68 | # Recycle Bin used on file shares 69 | $RECYCLE.BIN/ 70 | 71 | # Windows Installer files 72 | *.cab 73 | *.msi 74 | *.msm 75 | *.msp 76 | 77 | # Windows shortcuts 78 | *.lnk 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > This repository is in maintainance mode. Bug fixes will be provided on a best effort basis. If you use this project, please consider contributing back. 2 | 3 | # nw-dev 4 | 5 | A drop-in library for [nw.js][] development 6 | 7 | * Live-reloads upon save 8 | 9 | * Reloads when you press F5 10 | 11 | * Opens the devtools when you press F12 (`nw@>=0.13.0` does this for you) 12 | 13 | * Opens the devtools upon error 14 | 15 | * Sets `window.CRASHED` upon error, 16 | so you can stop an animation loop for example 17 | (and not flood the console with errors) 18 | 19 | * Clears the require cache, 20 | so reloading works with modules 21 | 22 | * When you change `package.json`, it closes and reopens the window 23 | with the new values, so you don't even have to restart 24 | to change things like `window.frame` 25 | (not working in latest nw.js) 26 | 27 | * When loaded in a browser (non-nw.js), 28 | it only tries to do error handling 29 | 30 | 31 | ## Install 32 | 33 | `npm i nw-dev --save-dev` 34 | 35 | Put this script before any other scripts 36 | (or at least ones you're developing): 37 | 38 | ```html 39 | 40 | ``` 41 | 42 | 43 | ## Exclude some files from being watched 44 | 45 | By default `node_modules`, `npm-debug.log`, `.git`, `.hg`, and `.svn` are ignored. 46 | 47 | You can ignore additional paths by adding a `data-ignore` attribute to the script: 48 | 49 | ```html 50 | 51 | ``` 52 | 53 | The ignore pattern will be passed to [chokidar][] and interpreted by [micromatch][]. 54 | 55 | 56 | ## Usage with `win.show()` 57 | 58 | If you use `win.show()` to show your app's window only once it finishes loading, 59 | it may also *focus* the window, depending on the platform. 60 | 61 | This can be annoying if you want to keep editing after saving, as it will steal focus from your code editor — especially if you use autosave. 62 | 63 | To avoid this behavior, you can guard against calling `win.show()` more than once like so: 64 | 65 | ```js 66 | if(!win.shown){ 67 | win.show(); 68 | win.shown = true; 69 | } 70 | ``` 71 | 72 | Note that `win.shown` is a made-up property (using Javascript's [expando](https://developer.mozilla.org/en-US/docs/Glossary/Expando) feature), but it's attached to the NW.js window object rather than using a simple global variable, in order to persist across reloads. 73 | 74 | ## Develop nw-dev 75 | 76 | * `npm i` 77 | 78 | * `npm link`, and `npm link nw-dev` from an nw.js project 79 | 80 | * `npm run prepublish` to recompile 81 | 82 | [nw.js]: https://github.com/nwjs/nw.js 83 | [chokidar]: https://github.com/paulmillr/chokidar 84 | [micromatch]: https://github.com/jonschlinkert/micromatch 85 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # "No Ideologies" Code of Conduct 2 | 3 | The following are the guidelines we expect our community members and maintainers to follow. 4 | 5 | * * * 6 | 7 | ## Terminology and Scope 8 | 9 | **What defines a "maintainer"?** 10 | 11 | * A maintainer is anyone that interacts with the community on behalf of this project. Amount of code written is not a qualifier. A maintainer may include those who solely help in support roles such as in resolving issues, improving documentation, administrating or moderating forums/chatrooms, or any other non-coding specific roles. Maintainers also include those that are responsible for the building and upkeep of the project. 12 | 13 | **What defines a "community member"?** 14 | 15 | * Anyone interacting with this project directly, including maintainers. 16 | 17 | **What is the scope of these guidelines?** 18 | 19 | * These guidelines apply only to this project and forms of communication directly related to it, such as issue trackers, forums, chatrooms, and in person events specific to this project. If a member is violating these guidelines outside of this project or on other platforms, that is beyond our scope and any grievances should be handled on those platforms. 20 | 21 | **Discussing the guidelines:** 22 | 23 | * Discussions around these guidelines, improving, updating, or altering them, is permitted so long as the discussions do not violate any existing guidelines. 24 | 25 | * * * 26 | 27 | ## Guidelines 28 | 29 | ### Guidelines for community members 30 | 31 | This project is technical in nature and not based around any particular non-technical ideology. As such, communication that is based primarily around ideologies unrelated to the technologies used by this repository are not permitted. 32 | 33 | Any discussion or communication that is primarily focused around an ideology, be it about race, gender, politics, religion, or anything else non-technical, is not allowed. Everyone has their own ideological preferences, beliefs, and opinions. We do not seek to marginalize, exclude, or judge anyone for their ideologies. To prevent conflict between those with differing or opposing ideologies, all communication on these subjects are prohibited. Some discussions around these topics may be important, however this project is not the proper channel for these discussions. 34 | 35 | ### Guidelines for maintainers 36 | 37 | * Maintainers must abide by the same rules as all other community members mentioned above. However, in addition, maintainers are held to a higher standard, explained below. 38 | * Maintainers should answer all questions politely. 39 | * If someone is upset or angry about something, it's probably because it's difficult to use, so thank them for bringing it to your attention and address ways to solve the problem. Maintainers should focus on the content of the message, and not on how it was delivered. 40 | * A maintainer should seek to update members when an issue they brought up is resolved. 41 | 42 | * * * 43 | 44 | ## Appropriate response to violations 45 | 46 | How to respond to a community member or maintainer violating a guideline. 47 | 48 | 1. If an issue is created that violates a guideline a maintainer should close and lock the issue, explaining "This issue is in violation of our code of conduct. Please review it before posting again." with a link to this document. 49 | 1. If a member repeatedly violates the guidelines established in this document, they should be politely warned that continuing to violate the rules may result in being banned from the community. This means revoking access and support to interactions relating directly to the project (issue trackers, chatrooms, forums, in person events, etc.). However, they may continue to use the technology in accordance with its license. 50 | 1. If a maintainer is in violation of a guideline, they should be informed of such with a link to this document. If additional actions are required of the maintainer but not taken, then other maintainers should be informed of these inactions. 51 | 1. If a maintainer repeatedly violates the guidelines established in this document, they should be politely warned that continuing to violate the rules may result in being banned from the community. This means revoking access and support to interactions relating directly to the project (issue trackers, chatrooms, forums, in person events, etc.). However, they may continue to use the technology in accordance with its license. In addition, future contributions to this project may be ignored as well. 52 | 53 | * * * 54 | 55 | Based on version 1.0.3 from https://github.com/CodifiedConduct/coc-no-ideologies 56 | -------------------------------------------------------------------------------- /src/dev.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 2.7.0 2 | (function() { 3 | var chokidar, err1, err2, ignore, ignored, nwgui, nwwin, watcher, 4 | hasProp = {}.hasOwnProperty; 5 | 6 | window.CRASHED = false; 7 | 8 | if (typeof process !== "undefined" && process !== null) { 9 | nwgui = window.require("nw.gui"); 10 | nwwin = nwgui.Window.get(window); 11 | 12 | // Get rid of the default error handler 13 | process.removeAllListeners("uncaughtException"); 14 | 15 | // Add our own handler 16 | process.on("uncaughtException", function(e) { 17 | var ref; 18 | if (!window.CRASHED) { 19 | window.CRASHED = true; 20 | if (typeof console !== "undefined" && console !== null) { 21 | if (typeof console.warn === "function") { 22 | console.warn("CRASH"); 23 | } 24 | } 25 | nwwin.showDevTools(); 26 | } 27 | if (((ref = nwgui.App.manifest.window) != null ? ref.show : void 0) === false) { 28 | return nwwin.show(); 29 | } 30 | }); 31 | 32 | // Keyboard shortcuts 33 | window.addEventListener("keydown", function(e) { 34 | var ref; 35 | switch ((ref = e.key) != null ? ref : e.keyIdentifier) { 36 | case "F12": 37 | return nwwin.showDevTools(); 38 | case "F5": 39 | return window.location.reload(); 40 | } 41 | }); 42 | ignored = [/node_modules|npm-debug\.log|\.git|\.hg|\.svn/]; 43 | ignore = document.currentScript.dataset.ignore; 44 | if (ignore) { 45 | ignored.push(ignore); 46 | } 47 | try { 48 | 49 | // Live reload 50 | chokidar = window.require("nw-dev/node_modules/chokidar/"); 51 | } catch (error) { 52 | err1 = error; 53 | try { 54 | chokidar = window.require("chokidar"); 55 | } catch (error) { 56 | err2 = error; 57 | console.warn("Live reload disabled:", [err1.stack, err2.stack]); 58 | } 59 | } 60 | if (chokidar) { 61 | watcher = chokidar.watch(".", {ignored}); 62 | // @TODO: watch linked dependencies and bundled dependencies 63 | // and make a package called watch-package 64 | watcher.on("change", function(path) { 65 | var fs, height, k, newwin, newwin_options, pkg, ref, ref1, ref2, v, width, x, y; 66 | watcher.close(); 67 | ref = global.require.cache; 68 | for (k in ref) { 69 | if (!hasProp.call(ref, k)) continue; 70 | delete global.require.cache[k]; 71 | } 72 | // very obscure cases 73 | // overall, it's very helpful 74 | 75 | // this could cause issues in somewhat less obscure cases 76 | // where another page/context has listeners on this window 77 | nwwin.removeAllListeners(); 78 | // but it fixes event listeners being leaked between reloads 79 | // which cause errors that wouldn't occur without reloading 80 | nwwin.closeDevTools(); 81 | if (path === "package.json") { 82 | // we want to do a full reload 83 | fs = require("fs"); 84 | pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); 85 | 86 | // override the getter by redefining the property 87 | Object.defineProperty(nwgui.App, "manifest", { 88 | value: pkg, 89 | configurable: true // (so this will work a second time) 90 | }); 91 | ({x, y} = nwwin); 92 | width = window.innerWidth; 93 | height = window.innerHeight; 94 | window.close(); 95 | newwin_options = {}; 96 | ref1 = pkg.window; 97 | for (k in ref1) { 98 | v = ref1[k]; 99 | newwin_options[k] = v; 100 | } 101 | ref2 = {x, y, width, height}; 102 | for (k in ref2) { 103 | v = ref2[k]; 104 | newwin_options[k] = v; 105 | } 106 | return newwin = nwgui.Window.open(window.location.href, newwin_options); 107 | } else { 108 | return typeof location !== "undefined" && location !== null ? location.reload() : void 0; 109 | } 110 | }); 111 | } 112 | } 113 | 114 | window.onerror = function(e) { 115 | if (!window.CRASHED) { 116 | window.CRASHED = true; 117 | if (typeof console !== "undefined" && console !== null) { 118 | if (typeof console.warn === "function") { 119 | console.warn("CRASH"); 120 | } 121 | } 122 | if (nwwin != null) { 123 | nwwin.showDevTools(); 124 | } 125 | } 126 | return false; 127 | }; 128 | 129 | }).call(this); 130 | -------------------------------------------------------------------------------- /nw-dev-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | nw-dev logonw-dev logoIsaiah Odhnerreloadrefreshdevelopmentnw.jsA circular arrow on a blue hexagon 116 | --------------------------------------------------------------------------------