From fa0942ab4b531943f0a5a80511981c5692812d37 Mon Sep 17 00:00:00 2001 From: njadbe Date: Wed, 14 Dec 2011 12:40:21 -0800 Subject: [PATCH 01/12] Implementation of opening file from the tree, using a simple CommandManager to start to decouple different parts of the app. --- src/CommandManager.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/CommandManager.js diff --git a/src/CommandManager.js b/src/CommandManager.js new file mode 100644 index 00000000000..c99d86cea9d --- /dev/null +++ b/src/CommandManager.js @@ -0,0 +1,32 @@ +/* + * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved. + */ + +var CommandManager = {}; + +CommandManager._commands = {}; + +/** + * Registers a global command. + * + * @param id {string} The ID of the command. + * @param command {function} The function to call when the command is executed. + */ +CommandManager.register = function(id, command) { + CommandManager._commands[id] = command; +} + +/** + * Runs a global command. Additional arguments are passed to the command. + * + * @param id {string} 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); + } +} From ffbe5fc6e00eac6696e14389b34b293ef44db2ff Mon Sep 17 00:00:00 2001 From: njadbe Date: Wed, 14 Dec 2011 12:40:21 -0800 Subject: [PATCH 02/12] Implementation of opening file from the tree, using a simple CommandManager to start to decouple different parts of the app. --- src/CommandManager.js | 32 ++++++++++++++++++++++++++++++++ src/ProjectManager.js | 3 +++ src/brackets.js | 34 +++++++++++++++++++++++++++++++--- src/index.html | 3 ++- 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 src/CommandManager.js diff --git a/src/CommandManager.js b/src/CommandManager.js new file mode 100644 index 00000000000..c99d86cea9d --- /dev/null +++ b/src/CommandManager.js @@ -0,0 +1,32 @@ +/* + * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved. + */ + +var CommandManager = {}; + +CommandManager._commands = {}; + +/** + * Registers a global command. + * + * @param id {string} The ID of the command. + * @param command {function} The function to call when the command is executed. + */ +CommandManager.register = function(id, command) { + CommandManager._commands[id] = command; +} + +/** + * Runs a global command. Additional arguments are passed to the command. + * + * @param id {string} 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); + } +} diff --git a/src/ProjectManager.js b/src/ProjectManager.js index d6ca91f67af..e1c381b7b35 100644 --- a/src/ProjectManager.js +++ b/src/ProjectManager.js @@ -174,5 +174,8 @@ ProjectManager._renderTree = function(treeDataProvider) { // file because jsTree insists on loading one itself) strings : { loading : "Loading ...", new_node : "New node" } // TODO: localization + }) + .bind("select_node.jstree", function(event, data) { + CommandManager.execute("file.open", data.rslt.obj.data("entry").fullPath); }); }; \ No newline at end of file diff --git a/src/brackets.js b/src/brackets.js index 198d5260ea7..c6f64229aff 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -10,9 +10,7 @@ brackets.inBrowser = !brackets.hasOwnProperty("fs"); $(document).ready(function() { - 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) { @@ -30,6 +28,10 @@ $(document).ready(function() { ProjectManager.openProject(); }); + // Implements the "Open File" menu + $("#menu-file-open").click(function() { + CommandManager.execute("file.open"); + }); // Implements the 'Run Tests' menu to bring up the Jasmine unit test window var testWindow = null; @@ -48,4 +50,30 @@ $(document).ready(function() { } }); + // Register global commands + CommandManager.register("file.open", function(fullPath) { + if (!fullPath) { + // Prompt the user with a dialog + NativeFileSystem.showOpenDialog(false, false, "Open File", ProjectManager.projectRoot.fullPath, + ["htm", "html", "js", "css"], function(files) { + if (files.length > 0) { + fullPath = files[0]; + } + }) + } + + if (fullPath) { + // TODO: use higher-level file API instead of raw API + brackets.fs.readFile(fullPath, "utf8", function(err, content) { + if (err) { + // TODO--this will change with the real file API implementation + } + else { + // TODO: have a real controller object for the editor + editor.setValue(content); + } + }); + } + }); + }); diff --git a/src/index.html b/src/index.html index 779334b8f9b..3d61476045c 100644 --- a/src/index.html +++ b/src/index.html @@ -20,8 +20,9 @@ - + + -
will-brackets-be-awesome.js
+
Untitled
From 6ab2c44a2ac08db856146219ff92028faa2664a8 Mon Sep 17 00:00:00 2001 From: njadbe Date: Wed, 14 Dec 2011 14:48:01 -0800 Subject: [PATCH 05/12] Created Commands file for command ID constants. Fixed async handling in file open command. Small code review fixes. --- src/CommandManager.js | 9 ++++++--- src/Commands.js | 8 ++++++++ src/ProjectManager.js | 2 +- src/brackets.js | 34 ++++++++++++++++++++-------------- src/index.html | 1 + 5 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 src/Commands.js diff --git a/src/CommandManager.js b/src/CommandManager.js index c99d86cea9d..d0e4805d8b4 100644 --- a/src/CommandManager.js +++ b/src/CommandManager.js @@ -9,17 +9,20 @@ CommandManager._commands = {}; /** * Registers a global command. * - * @param id {string} The ID of the command. - * @param command {function} The function to call when the command is executed. + * @param {string} id The ID of the command. + * @param {function} command The function to call when the command is executed. */ 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 id {string} The ID of the command to run. + * @param {string} id The ID of the command to run. */ CommandManager.execute = function(id) { var command = CommandManager._commands[id]; diff --git a/src/Commands.js b/src/Commands.js new file mode 100644 index 00000000000..f7927341a80 --- /dev/null +++ b/src/Commands.js @@ -0,0 +1,8 @@ +/* + * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved. + */ + +// List of constants for global command IDs. +var Commands = { + FILE_OPEN: "file.open" +}; diff --git a/src/ProjectManager.js b/src/ProjectManager.js index 2c801872eeb..2d0d26a8f3d 100644 --- a/src/ProjectManager.js +++ b/src/ProjectManager.js @@ -184,6 +184,6 @@ ProjectManager._renderTree = function(treeDataProvider) { strings : { loading : "Loading ...", new_node : "New node" } // TODO: localization }) .bind("select_node.jstree", function(event, data) { - CommandManager.execute("file.open", data.rslt.obj.data("entry").fullPath); + CommandManager.execute(Commands.FILE_OPEN, data.rslt.obj.data("entry").fullPath); }); }; \ No newline at end of file diff --git a/src/brackets.js b/src/brackets.js index bacf04c3ef3..4423ca4d2bb 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -30,7 +30,7 @@ $(document).ready(function() { // Implements the "Open File" menu $("#menu-file-open").click(function() { - CommandManager.execute("file.open"); + CommandManager.execute(Commands.FILE_OPEN); }); // Implements the 'Run Tests' menu to bring up the Jasmine unit test window @@ -50,18 +50,8 @@ $(document).ready(function() { } }); - // Register global commands - CommandManager.register("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) { - fullPath = files[0]; - } - }) - } - + // Utility functions + function doOpen(fullPath) { if (fullPath) { // TODO: use higher-level file API instead of raw API brackets.fs.readFile(fullPath, "utf8", function(err, content) { @@ -71,7 +61,7 @@ $(document).ready(function() { else { // TODO: have a real controller object for the editor editor.setValue(content); - + var projectRootPath = ProjectManager.getProjectRoot().fullPath; if (fullPath.indexOf(projectRootPath) == 0) { fullPath = fullPath.slice(projectRootPath.length); @@ -83,6 +73,22 @@ $(document).ready(function() { } }); } + } + + // 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); + } }); }); diff --git a/src/index.html b/src/index.html index 5493e7a8414..beb7a91ff62 100644 --- a/src/index.html +++ b/src/index.html @@ -21,6 +21,7 @@ + From 0ae3aa919729c1879df95c2bcbfaa62c710a3300 Mon Sep 17 00:00:00 2001 From: njadbe Date: Wed, 14 Dec 2011 15:48:26 -0800 Subject: [PATCH 06/12] Improve handling of title bar path --- src/brackets.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/brackets.js b/src/brackets.js index 4423ca4d2bb..8bcd4dd4c38 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -62,7 +62,12 @@ $(document).ready(function() { // TODO: have a real controller object for the editor editor.setValue(content); + // In the titlebar, 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; + if (projectRootPath.length > 1 && projectRootPath.charAt(projectRootPath.length - 1) != "/") { + projectRootPath += "/"; + } if (fullPath.indexOf(projectRootPath) == 0) { fullPath = fullPath.slice(projectRootPath.length); if (fullPath.charAt(0) == '/') { From 1531bc2f5851ddffcc6c2e631471a87611e8d382 Mon Sep 17 00:00:00 2001 From: njadbe Date: Wed, 14 Dec 2011 17:16:37 -0800 Subject: [PATCH 07/12] Changed file-open code to use HTML API --- src/NativeFileSystem.js | 2 +- src/brackets.js | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/NativeFileSystem.js b/src/NativeFileSystem.js index 4e2b81af9a9..18e06bfe436 100644 --- a/src/NativeFileSystem.js +++ b/src/NativeFileSystem.js @@ -144,7 +144,7 @@ NativeFileSystem.FileEntry = function( name ) { * * @param {function} successCallback * @param {function} errorCallback -/* + */ NativeFileSystem.FileEntry.prototype.file = function( successCallback, errorCallback ){ var newFile = new NativeFileSystem.File( this ); successCallback( newFile ); diff --git a/src/brackets.js b/src/brackets.js index 49fcfe43097..934101081a0 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -98,14 +98,17 @@ $(document).ready(function() { // Utility functions function doOpen(fullPath) { if (fullPath) { - // TODO: use higher-level file API instead of raw API - brackets.fs.readFile(fullPath, "utf8", function(err, content) { - if (err) { - // TODO--this will change with the real file API implementation - } - else { + 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(content); + editor.setValue(event.target.result); // In the titlebar, 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). @@ -119,8 +122,13 @@ $(document).ready(function() { fullPath = fullPath.slice(1); } } - $("#main-toolbar .title").text(fullPath); + $("#main-toolbar .title").text(fullPath); + }; + reader.onerror = function(event) { + // TODO--display meaningful error } + + reader.readAsText(file, "utf8"); }); } } From 31a4b789260079c2ffc493c89b1a58d12ec9f179 Mon Sep 17 00:00:00 2001 From: njadbe Date: Thu, 15 Dec 2011 14:09:11 -0800 Subject: [PATCH 08/12] Clear history after opening a new file --- src/brackets.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/brackets.js b/src/brackets.js index 934101081a0..b2361f11930 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -109,6 +109,7 @@ $(document).ready(function() { reader.onload = function(event) { // TODO: have a real controller object for the editor editor.setValue(event.target.result); + editor.clearHistory(); // In the titlebar, 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). From 0ad40b82d8e0e6646ea95ca16843fd737bf63dab Mon Sep 17 00:00:00 2001 From: njadbe Date: Thu, 15 Dec 2011 18:02:40 -0800 Subject: [PATCH 09/12] Code review cleanup --- src/CommandManager.js | 3 ++- src/Commands.js | 4 +++- src/brackets.js | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/CommandManager.js b/src/CommandManager.js index d0e4805d8b4..fa4e20f51e4 100644 --- a/src/CommandManager.js +++ b/src/CommandManager.js @@ -10,7 +10,8 @@ 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. + * @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]) { diff --git a/src/Commands.js b/src/Commands.js index f7927341a80..9c955ce484f 100644 --- a/src/Commands.js +++ b/src/Commands.js @@ -2,7 +2,9 @@ * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved. */ -// List of constants for global command IDs. +/** + * List of constants for global command IDs. + */ var Commands = { FILE_OPEN: "file.open" }; diff --git a/src/brackets.js b/src/brackets.js index 276bc69e85b..1330e342cd0 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -112,7 +112,7 @@ $(document).ready(function() { // In the titlebar, 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; - if (projectRootPath.length > 1 && projectRootPath.charAt(projectRootPath.length - 1) != "/") { + if (projectRootPath.length > 0 && projectRootPath.charAt(projectRootPath.length - 1) != "/") { projectRootPath += "/"; } if (fullPath.indexOf(projectRootPath) == 0) { From 9fa9d1c170f3ebcccade20f216e30b278b6ed9ee Mon Sep 17 00:00:00 2001 From: njadbe Date: Thu, 15 Dec 2011 18:32:25 -0800 Subject: [PATCH 10/12] Move definition of showErrorDialog out of document.ready into top level --- src/brackets.js | 53 +++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/brackets.js b/src/brackets.js index f39e2ca66c0..3795816dcd3 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -2,40 +2,41 @@ * 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 editor = CodeMirror($('#editor').get(0)); var myCodeMirror = CodeMirror($('#editor').get(0), { From 2241ef9187fbfa77071972e871a068c900cee729 Mon Sep 17 00:00:00 2001 From: njadbe Date: Thu, 15 Dec 2011 18:37:02 -0800 Subject: [PATCH 11/12] Fixed bug in previous merge --- src/brackets.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/brackets.js b/src/brackets.js index 3795816dcd3..cfbc9553933 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -39,10 +39,6 @@ $(document).ready(function() { var editor = CodeMirror($('#editor').get(0)); - var myCodeMirror = CodeMirror($('#editor').get(0), { - value: 'var myResponse="Yes, it will be!"\n' - }); - // Load a default project into the tree if (brackets.inBrowser) { // In browser: dummy folder tree (hardcoded in ProjectManager) From c38918f1ba0ab597519c70c094699943b6b3eaea Mon Sep 17 00:00:00 2001 From: njadbe Date: Thu, 15 Dec 2011 18:40:07 -0800 Subject: [PATCH 12/12] Final code review cleanup --- src/brackets.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/brackets.js b/src/brackets.js index cfbc9553933..57dbf8a0432 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -136,7 +136,7 @@ $(document).ready(function() { editor.setValue(event.target.result); editor.clearHistory(); - // In the titlebar, show the project-relative path (if the file is inside the current project) + // 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; if (projectRootPath.length > 0 && projectRootPath.charAt(projectRootPath.length - 1) != "/") { @@ -151,10 +151,13 @@ $(document).ready(function() { $("#main-toolbar .title").text(fullPath); }; reader.onerror = function(event) { - // TODO--display meaningful error + // TODO: display meaningful error } reader.readAsText(file, "utf8"); + }, + function (error) { + // TODO: display meaningful error }); } }