Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for Chrome. Extracted common functionality to jsreload.js.
- Loading branch information
Showing
6 changed files
with
179 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,12 +1,27 @@ | |||
# JSReload | # JSReload | ||
|
|
||
This project contains several scripts that help with automatically reloading a tab in Safari whenever a file changes: | This project contains several scripts that help with automatically reloading a tab in a browser whenever a file changes: | ||
|
|
||
1. `tools/watchdir.js` watches all .html and .css files in a directory and reloads the first tab in the first window when one of them changes. | 1. `tools/watchdir.js` watches all webdev files (.html, .css, .js) in a directory and reloads the first tab of the frontmost browser window when one of them changes. | ||
2. `grunt.js` watches all .asc files in its directory. If one of them changes, it converts it to HTML via the `asciidoc` command and then reloads Safari. | 2. `tools/watchfile.js` opens a file in a web browser, watches it and reloads the first tab of the frontmost browser window if it changes. | ||
3. `grunt.js` is a Grunt build script. You put it inside a project directory. Its `watch` task is invoked as follows. | |||
|
|
||
Prerequisites: | grunt watch | ||
This task watches all .asc files in the project directory. If one of them changes, it is converted to HTML via the `asciidoc` command. Afterwards, the first tab of the frontmost browser window is reloaded. | |||
|
|
||
All scripts depend on `node_modules/jsreload`. Safari is currently used by the scripts, but that can easily be changed to Chrome by replacing | |||
|
|||
jsreload.runReloadSafari(...); | |||
|
|||
with | |||
|
|||
jsreload.runReloadChrome(...); | |||
|
|||
## Requirements | |||
|
|||
- Supported browsers: Safari, Chrome | |||
- Mac OS X (reloading a browser currently depends on AppleScript) | |||
- Node.js | - Node.js | ||
- Package: underscore (trivial to install via npm) | |||
- [Grunt](http://gruntjs.com/) (only needed for option #2) | - [Grunt](http://gruntjs.com/) (only needed for option #2) | ||
- Mac OS X (reloading Safari is done via AppleScript) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,9 @@ | |||
module.exports = function(grunt) { | |||
|
|||
var jsreload = require('jsreload'); | |||
|
|||
grunt.registerTask('reloadchrome', 'Reloads the first tab of the first window of Google Chrome', function() { | |||
var taskDone = this.async(); | |||
jsreload.runReloadChrome(taskDone); | |||
}); | |||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,40 +1,9 @@ | |||
module.exports = function(grunt) { | module.exports = function(grunt) { | ||
|
|
||
var spawn = require('child_process').spawn; | var jsreload = require('jsreload'); | ||
|
|
||
grunt.registerTask('reloadsafari', 'Reloads the first tab of the first window of Safari', function() { | grunt.registerTask('reloadsafari', 'Reloads the first tab of the first window of Safari', function() { | ||
var taskDone = this.async(); | var taskDone = this.async(); | ||
reloadSafari(taskDone); | jsreload.runReloadSafari(taskDone); | ||
}); | }); | ||
|
|||
// Inspiration: http://brettterpstra.com/watch-for-file-changes-and-refresh-your-browser-automatically/ | |||
var code = '\ | |||
tell application "Safari"\n\ | |||
set mytab to first tab of first window\n\ | |||
tell mytab to do javascript "window.location.reload()"\n\ | |||
end tell\n\ | |||
'; | |||
function reloadSafari(callback) { | |||
var osa = spawn("osascript", ["-e", code]); | |||
var out = ""; | |||
var err = ""; | |||
osa.stdout.on('data', function (data) { | |||
out += data; | |||
}); | |||
osa.stderr.on('data', function (data) { | |||
err += data; | |||
}); | |||
osa.on('exit', function (code) { | |||
// Ignore stdout (which shows the return value of the AppleScript code) | |||
if (err.length > 0) { | |||
grunt.log.error("STDERR: "+err); | |||
} | |||
callback(); | |||
}); | |||
} | |||
|
|||
}; | }; | ||
|
|||
|
|||
|
|||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,96 +1,6 @@ | |||
#!/usr/bin/env node | #!/usr/bin/env node | ||
|
|
||
var fs = require('fs'); | var jsreload = require("jsreload"); | ||
var spawn = require('child_process').spawn; | |||
var path = require('path'); | |||
var _ = require("underscore"); | |||
|
|||
var extensions = { | |||
".html": 1, | |||
".css": 1, | |||
}; | |||
var mtimes = {}; | |||
var watchers = {}; | |||
|
|
||
var dirname = process.argv[2]; | var dirname = process.argv[2]; | ||
traverseFiles(dirname); | jsreload.watchDir(dirname, jsreload.runReloadSafari); | ||
|
|||
function traverseFiles(dir) { | |||
fs.readdirSync(dir).forEach(function (filename) { | |||
var absolute = path.resolve(dir, filename); | |||
|
|||
var stats = fs.statSync(absolute); | |||
if (stats.isDirectory()) { | |||
traverseFiles(absolute); | |||
} else if (stats.isFile()) { | |||
if (path.basename(absolute).indexOf(".") !== 0 && path.extname(absolute) in extensions) { | |||
console.log("WATCH: "+absolute); | |||
watchFile(absolute); | |||
} | |||
} | |||
}); | |||
} | |||
|
|||
function watchFile(filename) { | |||
// Most editors trigger a series of events whenever a single file is saved | |||
// Via debouncing, we only take action after the last event. | |||
watchers[filename] = fs.watch(filename, _.debounce(handleFileChanges.bind(null, filename), 250)); | |||
} | |||
|
|||
function handleFileChanges(absName, event, filename) { | |||
// On Mac OS X, filename is always null | |||
|
|||
switch (event) { | |||
case 'rename': | |||
// Some editors (vi) rename the file when swapping it with the new version | |||
watchers[absName].close(); | |||
if (fs.existsSync(absName)) { | |||
watchFile(absName); | |||
} else { | |||
// With debouncing, this shouldn’t happen, warn about it | |||
console.log("STOPPED WATCHING: "+absName); | |||
return; | |||
} | |||
fileChanged(event, absName); | |||
break; | |||
case 'change': | |||
fileChanged(event, absName); | |||
break; | |||
} | |||
} | |||
|
|||
function fileChanged(event, absName) { | |||
// Check the date of last modification to make sure that there really was a change | |||
var mtime = +fs.statSync(absName).mtime; | |||
if (mtime !== mtimes[absName]) { | |||
mtimes[absName] = mtime; | |||
console.log(event.toUpperCase()+": "+absName); | |||
reloadSafari(); | |||
} | |||
} | |||
|
|||
// Inspiration: http://brettterpstra.com/watch-for-file-changes-and-refresh-your-browser-automatically/ | |||
var code = '\ | |||
tell application "Safari"\n\ | |||
set mytab to first tab of first window\n\ | |||
tell mytab to do javascript "window.location.reload()"\n\ | |||
end tell\n\ | |||
'; | |||
function reloadSafari() { | |||
var osa = spawn("osascript", ["-e", code]); | |||
var out = ""; | |||
var err = ""; | |||
osa.stdout.on('data', function (data) { | |||
out += data; | |||
}); | |||
osa.stderr.on('data', function (data) { | |||
err += data; | |||
}); | |||
osa.on('exit', function (code) { | |||
// Ignore stdout (which shows the return value of the AppleScript code) | |||
if (err.length > 0) { | |||
console.log("STDERR: "+err); | |||
} | |||
console.log("RELOADED"); | |||
}); | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,7 @@ | |||
#!/usr/bin/env node | |||
|
|||
var jsreload = require("jsreload"); | |||
var fileName = process.argv[2]; | |||
jsreload.runOpen(jsreload.safariAppName, fileName, function () { | |||
jsreload.watchFile(fileName, jsreload.runReloadSafari); | |||
}); |