-
Notifications
You must be signed in to change notification settings - Fork 7.5k
Open file from tree #12
Changes from all commits
fa0942a
ffbe5fc
66dc4db
bee53cb
e222f45
9820db4
0ebaefe
6ab2c44
0ae3aa9
0fa72df
e448ecc
1531bc2
31a4b78
0862720
ead9cd5
338b2eb
35da1ef
0ad40b8
2c707fa
9fa9d1c
2241ef9
c38918f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /* | ||
| * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved. | ||
| */ | ||
|
|
||
| var CommandManager = {}; | ||
|
|
||
| CommandManager._commands = {}; | ||
|
|
||
| /** | ||
| * Registers a global command. | ||
| * | ||
| * @param {string} id The ID of the command. | ||
| * @param {function} command The function to call when the command is executed. Any arguments passed to | ||
| * execute() (after the id) are passed as arguments to the function. | ||
| */ | ||
| CommandManager.register = function(id, command) { | ||
| if (CommandManager._commands[id]) { | ||
| throw new Error("Attempting to register an already-registered command: " + id); | ||
| } | ||
| CommandManager._commands[id] = command; | ||
| } | ||
|
|
||
| /** | ||
| * Runs a global command. Additional arguments are passed to the command. | ||
| * | ||
| * @param {string} id The ID of the command to run. | ||
| */ | ||
| CommandManager.execute = function(id) { | ||
| var command = CommandManager._commands[id]; | ||
| if (command) { | ||
| command.apply(null, Array.prototype.slice.call(arguments, 1)); | ||
| } | ||
| else { | ||
| console.log("Attempted to call unregistered command: " + id); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| /* | ||
| * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved. | ||
| */ | ||
|
|
||
| /** | ||
| * List of constants for global command IDs. | ||
| */ | ||
| var Commands = { | ||
| FILE_OPEN: "file.open" | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,43 +2,42 @@ | |
| * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved. | ||
| */ | ||
|
|
||
| // TODO: break out the definition of brackets into a separate module from the application controller logic | ||
|
|
||
| // Define core brackets namespace | ||
| brackets = window.brackets || {}; | ||
|
|
||
| brackets.inBrowser = !brackets.hasOwnProperty("fs"); | ||
|
|
||
| /** | ||
| * General purpose modal error dialog. | ||
| * | ||
| * @param {string} title The title of the error dialog. Can contain HTML markup. | ||
| * @param {string} message The message to display in the error dialog. Can contain HTML markup. | ||
| */ | ||
| brackets.showErrorDialog = function(title, message) { | ||
| var dlg = $("#error-dialog"); | ||
|
|
||
| // Set title and message | ||
| $("#error-dialog-title").html(title); | ||
| $("#error-dialog-message").html(message); | ||
|
|
||
| // Click handler for OK button | ||
| dlg.delegate("#error-dialog-ok", "click", function(e) { | ||
| dlg.modal(true).hide(); | ||
| }); | ||
|
|
||
| // Run the dialog | ||
| dlg.modal( | ||
| { backdrop: "static" | ||
| , show: true | ||
| } | ||
| ); | ||
| } | ||
|
|
||
| $(document).ready(function() { | ||
|
|
||
| /** | ||
| * General purpose modal error dialog. | ||
| * | ||
| * @param {string} title The title of the error dialog. Can contain HTML markup. | ||
| * @param {string} message The message to display in the error dialog. Can contain HTML markup. | ||
| */ | ||
| brackets.showErrorDialog = function(title, message) { | ||
| var dlg = $("#error-dialog"); | ||
|
|
||
| // Set title and message | ||
| $("#error-dialog-title").html(title); | ||
| $("#error-dialog-message").html(message); | ||
|
|
||
| // Click handler for OK button | ||
| dlg.delegate("#error-dialog-ok", "click", function(e) { | ||
| dlg.modal(true).hide(); | ||
| }); | ||
|
|
||
| // Run the dialog | ||
| dlg.modal( | ||
| { backdrop: "static" | ||
| , show: true | ||
| } | ||
| ); | ||
| } | ||
|
|
||
| var myCodeMirror = CodeMirror($('#editor').get(0), { | ||
| value: 'var myResponse="Yes, it will be!"\n' | ||
| }); | ||
| var editor = CodeMirror($('#editor').get(0)); | ||
|
|
||
| // Load a default project into the tree | ||
| if (brackets.inBrowser) { | ||
|
|
@@ -56,6 +55,10 @@ $(document).ready(function() { | |
| ProjectManager.openProject(); | ||
| }); | ||
|
|
||
| // Implements the "Open File" menu | ||
| $("#menu-file-open").click(function() { | ||
| CommandManager.execute(Commands.FILE_OPEN); | ||
| }); | ||
|
|
||
| // Implements the 'Run Tests' menu to bring up the Jasmine unit test window | ||
| var testWindow = null; | ||
|
|
@@ -117,4 +120,62 @@ $(document).ready(function() { | |
| }); | ||
| });*/ | ||
|
|
||
| // Utility functions | ||
| function doOpen(fullPath) { | ||
| if (fullPath) { | ||
| var reader = new NativeFileSystem.FileReader(); | ||
|
|
||
| // TODO: we should implement something like NativeFileSystem.resolveNativeFileSystemURL() (similar | ||
| // to what's in the standard file API) to get a FileEntry, rather than manually constructing it | ||
| var fileEntry = new NativeFileSystem.FileEntry(fullPath); | ||
|
|
||
| // TODO: it's weird to have to construct a FileEntry just to get a File. | ||
| fileEntry.file(function(file) { | ||
| reader.onload = function(event) { | ||
| // TODO: have a real controller object for the editor | ||
| editor.setValue(event.target.result); | ||
| editor.clearHistory(); | ||
|
|
||
| // In the main toolbar, show the project-relative path (if the file is inside the current project) | ||
| // or the full absolute path (if it's not in the project). | ||
| var projectRootPath = ProjectManager.getProjectRoot().fullPath; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just for the titlebar. The idea is that if the file is in the project, the title shows the path relative to the project to avoid redundancy, whereas if it's outside the project, it shows the full path. I'll add a comment. |
||
| if (projectRootPath.length > 0 && projectRootPath.charAt(projectRootPath.length - 1) != "/") { | ||
| projectRootPath += "/"; | ||
| } | ||
| if (fullPath.indexOf(projectRootPath) == 0) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe a little overly edge-casey, but will this fail for cases like: projectRootPath="/a/b", fullPath="/a/bfoo" ? (this issue couldn't happen if projectRootPath is guaranteed to end in a "/", but I'm not sure if that's true)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
| fullPath = fullPath.slice(projectRootPath.length); | ||
| if (fullPath.charAt(0) == '/') { | ||
| fullPath = fullPath.slice(1); | ||
| } | ||
| } | ||
| $("#main-toolbar .title").text(fullPath); | ||
| }; | ||
| reader.onerror = function(event) { | ||
| // TODO: display meaningful error | ||
| } | ||
|
|
||
| reader.readAsText(file, "utf8"); | ||
| }, | ||
| function (error) { | ||
| // TODO: display meaningful error | ||
| }); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does our FileEntry.file() take an error callback as a 2nd arg, like the PhoneGap one? If so, I wonder if we should add a "TODO" error callback like you did above with the reader. That way we'll have TODOs for all known cases of missing error handling. |
||
| } | ||
| } | ||
|
|
||
| // Register global commands | ||
| CommandManager.register(Commands.FILE_OPEN, function(fullPath) { | ||
| if (!fullPath) { | ||
| // Prompt the user with a dialog | ||
| NativeFileSystem.showOpenDialog(false, false, "Open File", ProjectManager.getProjectRoot().fullPath, | ||
| ["htm", "html", "js", "css"], function(files) { | ||
| if (files.length > 0) { | ||
| doOpen(files[0]); | ||
| } | ||
| }); | ||
| } | ||
| else { | ||
| doOpen(fullPath); | ||
| } | ||
| }); | ||
|
|
||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,8 +21,10 @@ | |
| <script src="thirdparty/jstree_pre1.0_fix_1/jquery.jstree.js"></script> | ||
|
|
||
| <script src="NativeFileSystem.js"></script> | ||
| <script src="brackets.js"></script> | ||
| <script src="CommandManager.js"></script> | ||
| <script src="Commands.js"></script> | ||
| <script src="ProjectManager.js"></script> | ||
| <script src="brackets.js"></script> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm.. currently, brackets.js has a few bootstrappy things that feel like they should come before other files (declaring the brackets namespace and setting up the isBrowser flag). But it also has business logic stuff (the commands) that feel like they should come after other files. Should we maybe split this into two separate files?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leaving this the way it is for now--no real top level code should be running before $(document).ready() anyway, and stuff like the brackets namespace will be taken care of properly when we move to modules. |
||
| <script src="strings.js"></script> | ||
| </head> | ||
| <body> | ||
|
|
@@ -73,7 +75,7 @@ | |
| <input class="settings" type="button" value="Settings"/> | ||
| --> | ||
| </div> | ||
| <div class="title">will-brackets-be-awesome.js</div> | ||
| <div class="title">Untitled</div> | ||
| </div> | ||
| <div id="editor"></div> | ||
| </div> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably assert/throw here if the same id has already been registered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll do that for now...though we should think about whether we want to allow people to redefine existing commands. (I can think of reasons not to allow that :), but it's worth considering.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree -- eventually extensions at least will need to be able to overwrite. But for maintainability, it's also really nice to get warnings if you accidentally register the same command id twice. Maybe eventually we could ask callers to explicitly specify whether they intend to override an existing handler (a la "@OverRide" in Java / "override" in AS)?