Giter Club home page Giter Club logo

brackets's Introduction

Bramble is based on Brackets

Brackets is a modern open-source code editor for HTML, CSS and JavaScript that is built in HTML, CSS and JavaScript.

Brackets is at 1.0 and we're not stopping there. We have many feature ideas on our trello board that we're anxious to add and other innovative web development workflows that we're planning to build into Brackets. So take Brackets out for a spin and let us know how we can make it your favorite editor.

You can see some screenshots of Brackets on the wiki, intro videos on YouTube, and news on the Brackets blog.

The text editor inside Brackets is based on CodeMirror—thanks to Marijn for taking our pull requests, implementing feature requests and fixing bugs! See Notes on CodeMirror for info on how we're using CodeMirror.

How to setup Bramble (Brackets) in your local machine

Step 1: Make sure you fork and clone Brackets.

$ git clone https://github.com/[yourusername]/brackets --recursive

Step 2: Install its dependencies

Navigate to the root of the directory you cloned and run:

$ npm install

NOTE: if you are running on Windows, and experience a build error with the iltorb package, consider adding the --no-optional flag to have npm skip installing iltorb, which is optional and requires python, gyp and a working c++ build environment. See comment in #588 (comment)

Step 3: Run Bramble:

The easiest way to run Bramble is to simply use:

$ npm start

This will generate the strings needed for localization in your src/nls folder and allow you to access Bramble on localhost:8000 (NOTE: you need npm version 5 for the cleanup step to run properly; if it doesn't, use npm run unlocalize to restore the files in src/nls/**/*). It will also build the Bramble iframe API in dist/ if necessary. You can terminate the server with Ctrl+C which will also clean up the strings that were generated in your src/nls folder. If any changes are made in the src directory, just refresh the page hosting Bramble in your browser to reflect those changes.

If you want to simply run the server without the localized strings, run:

$ npm run server

However, if you wish to run your own static server, there are several options available:

Assuming you have Bramble running on port 8000. Now you can visit http://localhost:8000/src.

NOTE 1: Bramble expects to be run in an iframe, which hosts its filesystem. For local development, use src/hosted.html instead of src/index.html. To see how the remote end should host Bramble's iframe, see src/hosted.js.

NOTE 2: Using npm run build will overwrite contents in the src/nls folder. These changes are necessary if you access Bramble using http://localhost:8000/src. After using Bramble, you can undo the changes by running npm run unlocalize.

NOTE 3: To use Bramble in a production setting locally, you can run npm run production and access Bramble at http://localhost:8000/dist

Extension Loading

Bramble loads a set of extensions defined in src/extensions/bramble-extensions.json. You can alter which extensions Bramble loads by adding or removing items from this list. You can also temporarily disable extensions by using ?disableExtensions. For example: to disable QuickView and CSSCodeHints, load Bramble with ?disableExtensions=QuickView,CSSCodeHints on the URL.


After installation

After you have everything setup, you can now run the server you chose in the root of your local Bramble directory and see it in action by visiting http://localhost:8000/src.

Bramble IFrame API

Bramble is designed to be run in an iframe, and the hosting web app to communicate with it via postMessage and MessageChannel. In order to simplify this, a convenience API exists for creating and managing the iframe, as well as providing JavaScript functions for interacting with the editor, preview, etc.

Loading the API

The hosting app must include the Bramble IFrame API (i.e., dist/bramble.js). Note: in development you can use src/hosted.html, which does this. This script can either be used as an AMD module, or as a browser global:

<script src="bramble.js"></script>
<script>
  // Option 1: AMD loading, assumes requirejs is loaded already
  require(["bramble"], function(Bramble) {
    ...
  });

  // Option 2: Browser global
  var Bramble = window.Bramble;
</script>

Bramble

The Bramble module has a number of methods, properties, and events. During its lifetime, Bramble goes through a number of states, including:

  • Bramble.ERROR - Bramble is in an error state
  • Bramble.NOT_LOADED - Initial state, Bramble.load() has not been called
  • Bramble.LOADING - Bramble.load() has been called, loading resources has begun
  • Bramble.MOUNTABLE - Loading is done and Bramble.mount() can be begin, or is safe to start
  • Bramble.MOUNTING - Bramble.mount() is being called, mounting is in process
  • Bramble.READY - Bramble.mount() has finished, Bramble is fully ready

The current state of Bramble can be obtained by calling Bramble.getReadyState(). There are also a number of events you can listen for (i.e., Bramble is an EventEmitter):

Bramble.once("ready", function(bramble) {
  // bramble is the Bramble proxy instance, see below.
});

Bramble.on("error", function(err) {
  // Bramble is in an error state, and `err` is the error.
})

Bramble.on("readyStateChange", function(previous, current) {
  // Bramble's readyState changed from `previous` to `current`
});

NOTE: in some browsers (e.g., Firefox) when the user is in "Private Browsing" mode, the filesystem (i.e., IndexedDB) will be inaccessible, and an error will be sent via the error event (i.e., err.code === "EFILESYSTEMERROR"). This is the same error that occurs when the filesystem is corrupt (see autoRecoverFileSystem below).

Bramble Offline Support

The Bramble code is offline capable, and will indicate, via events, when it is ready to be used offline, as well as when there are updates available for existing offline cached resources. These events are triggered on Bramble vs. the bramble instance. The offline related events include:

  • "offlineReady" - triggered when Bramble has been fully cached for offline use. Users can safely work without network.
  • "updatesAvailable" - triggered when new or updated Bramble resources have been cached and are available for use. You might use this to indicate to the user that they should refresh the page to begin using the updates.

Bramble.getFileSystem()

The FileSystem is owned by the hosting application, and can be obtained at any time by calling:

var fs = Bramble.getFileSystem();

This fs instance can be used to setup the filesystem for the Bramble editor prior to loading. You can access things like Path and Buffer via Bramble.Filer.*.

Bramble.formatFileSystem(callback)

WARNING: this will destroy data, and is meant to be used in the case that the filesystem is corrupted (err.code === "EFILESYSTEMERROR"), or for when an app wants to allow a user to wipe their disk.

Bramble.on("error", function(err) {
  if(err.code === "EFILESYSTEMERROR") {
    Bramble.formatFileSystem(function(err) {
      if(err) {
        // Unable to create filesystem, fatal (and highly unlikely) error
      } else {
        // filesystem is now clean and empty, use Bramble.getFileSystem() to obtain instance
      }
    });
  }
});

NOTE: you can turn this recovery behaviour on automatically by passing autoRecoverFileSystem: true in the options to Bramble.load().

Bramble.load(elem[, options])

Once you have a reference to the Bramble object, you use it to starting loading the editor:

// Start loading Bramble
Bramble.load("#webmaker-bramble");

Bramble.once("error", function(err) {
  console.error("Bramble error", err);
});

The elem argument specifies which element in the DOM should be used to hold the iframe. This element's contents will be replaced by the iframe. You can pass a selector, a reference to an actual DOM element, or leave it blank, and document.body will be used.

The options object allows you to configure Bramble:

  • url: <String> a URL to use when loading the Bramble iframe (defaults to prod)
  • locale: <String> the locale Brackets should use
  • useLocationSearch: <Boolean> whether to copy the window's location.search string to the iframe's url
  • extensions: <Object> with the following optional properties
    • enable: <Array(String)> a list of extensions to enable
    • disable: <Array(String)> a list of extensions to disable
  • hideUntilReady: <Boolean> whether to hide Bramble until it's fully loaded.
  • disableUIState: <Boolean> by default, UI state is kept between sessions. This disables it (and clears old values), and uses the defaults from Bramble.
  • autoRecoverFileSystem: <Boolean> whether to try and autorecover the filesystem on failure (see Bramble.formatFileSystem above).
  • debug: <Boolean> whether to log debug info.
  • zipFilenamePrefix: <String> the prefix name to use for project zip files, or "thimble-project" by default.
  • capacity: <Number> the number of bytes of disk space to allow for this project. Defaults to 5MB if not set.

Bramble.mount(root[, filename])

After calling Bramble.load(), you can tell Bramble which project root directory to open, and which file to load into the editor. NOTE: the optional filename argument, if provided, should be a relative path within the project root. Bramble will use this information when it is ready to mount the filesystem. Use the "ready" event to get access to the bramble instance:

// Setup the filesystem while Bramble is loading
var fs = Bramble.getFileSystem();

Bramble.once("ready", function(bramble) {
  // The bramble instance is now usable, see below.
});

fs.mkdir("/project", function(err) {
  // If we run this multiple times, the dir will already exist
  if (err && err.code !== "EEXIST") {
    throw err;
  }

  var html = ""                    +
    "<html>\n"                     +
    "  <head>\n"                   +
    "    <title>Bramble</title>\n" +
    "  </head>\n"                  +
    "  <body>\n"                   +
    "    <p>Hello World</p>\n"     +
    "  </body>\n"                  +
    "</html>";

  fs.writeFile("/project/index.html", html, function(err) {
    if (err) {
      throw err;
    }

    // Now that fs is setup, tell Bramble which root dir to mount
    // and which file within that root to open on startup.
    Bramble.mount("/project", "index.html");
  });
});

Bramble Instance Getters

Once the Bramble instance is created (e.g., via ready event or Bramble.mount() callback), a number of read-only getters are available in order to access state information in the Bramble editor:

  • getID() - returns the iframe element's id in the DOM
  • getIFrame() - returns a reference to the iframe that hosts Bramble
  • getFullPath() - returns the absolute path of the file currently being edited
  • getFilename() - returns the filename portion (i.e., no dir info) of the file currently being edited
  • getPreviewMode() - returns one of "mobile" or "desktop", depending on current preview mode
  • getSidebarVisible() - returns true or false depending on whether the sidebar (file tree) is visible
  • getLayout() - returns an Object with three integer properties: sidebarWidth, firstPaneWidth, secondPaneWidth. The firstPaneWidth refers to the editor, where secondPaneWidth is the preview.
  • getRootDir() - returns the project root directory to which Bramble is mounted
  • getTheme() - returns the name of the current theme.
  • getFontSize() - returns the current font size as a string (e.g., "12px").
  • getWordWrap() - returns the current word wrap setting as a Boolean (i.e., enabled or disabled).
  • getAllowJavaScript() - returns the current allow javascript setting as a Boolean (i.e., enabled or disabled).
  • getAutocomplete() - returns the current autocomplete settings as a Boolean (i.e., enabled or disabled).
  • getAutoCloseTags() - returns the current close tags setting as an Object with three properties: whenOpening a boolean that determines whether opening tags are closed upon typing ">", whenClosing a boolean that determines whether closing tags are closed upon typing "/", and an array of tags indentTags, that when opened, has a blank line. These values default to, respectively: true, true, and an empty array.
  • getTutorialExists() - returns true or false depending on whether or not there is a tutorial in the project (i.e., if tutorial.html is present)
  • getTutorialVisible() - returns true or false depending on whether or not the preview browser is showing a tutorial or not.
  • getAutoUpdate() - returns true or false depending on whether or not the auto update preference is enabled or not.
  • getTotalProjectSize() - returns the current project size in bytes.
  • hasIndexFile() - returns true or false depending on whether or not there is an "index.html" file.
  • getFileCount() - returns total file count.

NOTE: calling these getters before the ready() callback on the bramble instance won't do what you want.

Bramble Instance Methods

The Bramble instance has a number of methods you can call in order to interact with the Bramble editor and preview, all of which take an optional callback argument if you want to be notified when the action completes:

  • undo([callback]) - undo the last operation in the editor (waits for focus)
  • redo([callback]) - redo the last operation that was undone in the editor (waits for focus)
  • increaseFontSize([callback]) - increases the editor's font size
  • decreaseFontSize([callback]) - decreases the editor's font size
  • restoreFontSize([callback]) - restores the editor's font size to normal
  • save([callback]) - saves the current document
  • saveAll([callback]) - saves all "dirty" documents
  • useHorizontalSplitView([callback]) - splits the editor and preview horizontally
  • useVerticalSplitView([callback]) - splits the editor and preview vertically (default)
  • find([callback]) - opens the Find dialog to search within the current document
  • findInFiles([callback]) - opens the Find in Files dialog to search in all project files
  • replace([callback]) - opens the Replace dialog to replace text in the current document
  • replaceInFiles([callback]) - opens the Replace in Files dialog to replace text in all project files
  • useLightTheme([callback]) - sets the editor to use the light theme (default)
  • useDarkTheme([callback]) - sets the editor to use the dark theme
  • showSidebar([callback]) - opens the file tree sidebar
  • hideSidebar([callback]) - hides the file tree sidebar
  • showStatusbar([callback]) - enables and shows the statusbar
  • hideStatusbar([callback]) - disables and hides the statusbar
  • showPreview([callback]) - opens the preview pane
  • hidePreview([callback]) - hides the preview pane
  • refreshPreview([callback]) - reloads the preview with the latest content in the editor and filesystem
  • useMobilePreview([callback]) - uses a Mobile view in the preview, as it would look on a smartphone
  • useDesktopPreview([callback]) - uses a Desktop view in the preview, as it would look on a desktop computer (default)
  • enableFullscreenPreview([callback]) - shows a fullscreen preview of the current file
  • disableFullscreenPreview([callback]) - turns off the fullscreen preview of the current file
  • enableAutoUpdate([callback]) - turns on auto-update for the preview (default)
  • disableAutoUpdate([callback]) - turns off auto-update for the preview (manual reloads still work)
  • enableJavaScript([callback]) - turns on JavaScript execution for the preview (default)
  • disableJavaScript([callback]) - turns off JavaScript execution for the preview
  • enableInspector([callback]) - turns on the preview inspector (shows code for hovered/clicked element)
  • disableInspector([callback]) - turns off the preview inspector (default)
  • enableWordWrap([callback]) - turns on word wrap for the editor (default)
  • disableWordWrap([callback]) - turns off word wrap for the editor
  • configureAutoCloseTags(options, [callback]) - enables/disables close tags for the editor using the provided options which consists of an Object that includes three properties: whenOpening a boolean, whenClosing a boolean, and an array indentTags.
  • showTutorial([callback]) - shows tutorial (i.e., tutorial.html) vs editor contents in preview
  • hideTutorial([callback]) - stops showing tutorial (i.e., tutorial.html) and uses editor contents in preview
  • showUploadFilesDialog([callback]) - shows the Upload Files dialog, allowing users to drag-and-drop, upload a file, or take a selfie.
  • addNewFile([options, callback]) - adds a new text file, using the provided options, which can include: filename a String with the complete filename to use; contents a String with the new text file's data; ext a String with the new file's extension; basenamePrefix a String with the basename to use when generating a new filename. NOTE: if you provide filename, basenamePrefix and ext are ignored.
  • addNewFolder([callback]) - adds a new folder.
  • export([callback]) - creates an archive .zip file of the entire project's filesystem, and downloads it to the browser.
  • addCodeSnippet(snippet, [callback]) - adds a new code snippet to the editor (if it is in focus) at the current cursor position. One required parameter (snippet) needs to be passed in which needs to be a String.
  • openSVGasXML([callback]) - treats .svg files as XML and shows them in the text editor.
  • openSVGasImage([callback]) - treats .svg files as Images and shows them in image viewer.

Bramble Instance Events

The Bramble instance is also an EventEmitter and raises the following events:

  • "layout" - triggered whenever the sidebar, editor, or preview panes are changed. It includes an Object that returns the same information as the getLayout() getter: sidebarWidth, firstPaneWidth, secondPathWidth
  • "activeEditorChange" - triggered whenever the editor changes from one file to another. It includes an Object with the current file's fullPath and filename.
  • "previewModeChange" - triggered whenever the preview mode is changed. It includes an Object with the new mode
  • "sidebarChange" - triggered whenever the sidebar is hidden or shown. It includes an Object with a visible property set to true or false
  • "themeChange" - triggered whenever the theme changes. It includes an Object with a theme property that indicates the new theme
  • "fontSizeChange" - triggered whenever the font size changes. It includes an Object with a fontSize property that indicates the new size (e.g., "12px").
  • "wordWrapChange" - triggered whenever the word wrap value changes. It includes an Object with a wordWrap property that indicates the new value (e.g., true or false).
  • "allowJavaScriptChange" - triggered whenever the allow javascript value changes. It includes an Object with a allowJavaScript property that indicates the new value (e.g., true or false).
  • "autoCloseTagsChange" - triggered whenever the close tag value changes. It includes an Object with a autoCloseTags property that indicates the new value
  • "tutorialAdded" - triggered when a new tutorial is added to the project
  • "tutorialRemoved" - triggered when an existing tutorial for the project is removed
  • "tutorialVisibilityChange" - triggered when the tutorial preview is turned on or off. It includes an Object with a visibility property that indicates whether the tutorial is visible.
  • "inspectorChange" - triggered whenever the inspector changes from enabled to disabled, or vice versa. It includes an Object with an enabled property set to true or false.
  • "autoUpdateChange" - triggered whenever the auto update preference changes from enabled to disabled, or vice versa. It includes an Object with a autoUpdate property set to true or false
  • "projectDirty" - triggered when one of the files in the project has been edited and those changes haven't been saved yet. It includes an Object with the path to the current file.
  • "projectSaved" - triggered whenever the changes are saved to the filesystem in the browser are completed.
  • "dialogOpened" - triggered whenever a modal dialog opens, like when a user is deleting a file.
  • "dialogClosed" - triggered whenever a modal dialog closes.
  • "capacityExceeded" - triggered whenever the project's files reach or exceed the maximum allowed disk capacity. Some operations will be disallowed until sufficient space has been recovered (e.g., user deletes files). A second argument, size, indicates the number of bytes the project is over capacity.
  • "capacityRestored" - triggered after a "capacityExceeded" event when sufficient space has been recovered to continue normal disk activity.
  • "projectSizeChange" - triggered when the project's size on disk changes. The event includes two arguments: size, which is the new size of the project in bytes, and percentUsed which is a percentage of disk space used out of the total available capacity.

There are also high-level events for changes to files:

  • "fileChange" - triggered whenever a file is created or updated within the project root. It includes the filename of the file that changed.
  • "fileDelete" - triggered whenever a file is deleted within the project root. It includes the filename of the file that was deleted.
  • "fileRename" - triggered whenever a file is renamed within the project root. It includes the oldFilename and the newFilename of the file that was renamed.
  • "folderRename" - triggered whenever a folder is renamed within the project root. It includes an object that looks something like this:
{
  oldPath: "/path/before/rename",
  newPath: "/path/after/rename",
  // Paths to all files contained inside the folder being renamed
  children: [ "relativeFilePath1",  "relativeFilePath2", ... ]
}

NOTE: if you want to receive generic events for file system events, especially events across windows using the same file system, use fs.watch() instead.

Troubleshooting

If you forgot to add the --recursive flag while cloning this repository, you might run into a similar error:

Tracing dependencies for: main
Error: ENOENT: no such file or directory, open '[..]/brackets/src/thirdparty/text/text.js'
In module tree:
    brackets
      language/LanguageManager
        file/FileUtils
          utils/Global

To fix it, run git submodule update --init --recursive in the main directory.

brackets's People

Contributors

bchintx avatar busykai avatar chrisbank avatar couzteau avatar dangoor avatar denniskehrig avatar eztierney avatar gideonthomas avatar gruehle avatar humphd avatar ingorichter avatar jasonsanjose avatar jbalsas avatar jdiehl avatar jeffrybooher avatar joelrbrandt avatar larz0 avatar lkcampbell avatar miguelcastillo avatar mynetx avatar njx avatar peterflynn avatar pthiess avatar raymondlim avatar redmunds avatar tommalbran avatar tvoliter avatar walfgithub avatar websitedeveloper avatar zaggino avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

brackets's Issues

Match indent width between Brackets and default content

screen shot 2015-03-10 at 1 38 51 pm
In the above screenshot, you can see that our default indent in the Brackets editor is 4 spaces, but the initial content uses 2 spaces. This means that content is always unaligned, and it looks off. We should either change the initial content to be 4-space indented, or change the editor default to use 2-spaces vs. 4-spaces.

Fix the brackets development workflow

This is a couple of things:

  1. Get rid of as many submodules as possible
  2. Add grunt tasks for:
  3. Automatically updating our submodules/packages for extensions
  4. Automatically build and deploy our latest code to heroku

PostMessageTransport: Error parsing message: process-tick

The live preview postMessage stuff is failing on a process-tick message that's being sent from somewhere:

PostMessageTransport: Error parsing message: process-tick:8000/extensions/default/brackets-browser-livedev/lib/PostMessageTransport.js:37

Connect Thimble UI to Brackets commands

There are a few Thimble UI bits that we need to connect to Brackets, specifically the Undo, Redo, Size, and reload buttons. Doing this would involve having the onclick for these cause a message to be sent to the Brackets iframe window, and then have that event get consumed by thimbleProxy such that it fired the correct command in the Brackets instance. You can probably steal code from the Brackets menu, which fires commands for these things when you click on the menu items.

Later we can expose other features via some kind of menu system in Thimble. This will be the start.

Move away from Source Code Pro web fonts in favour of system fonts

Brackets loads 300K+ of (gzipped) web fonts, and switching over to using system fonts is a pretty big saving. @peterflynn wisely suggested moving away from web fonts in adobe#10680 (comment), suggesting we use a font-family of "Menlo Regular", Consolas, Inconsolata, "Vera Sans", "Lucida Console", Courier, fixed;. I did a quick test of this, and with other size optimization things we're doing, it gets us down to ~600K (gzipped), which is pretty good for a complete desktop editor, filesystem, etc.

I'm trying to decide the best way to make this switch, specifically how to do it with the least disruption to Brackets' code. The bulk of the Brackets font stuff is in https://github.com/adobe/brackets/blob/ae17456a596965a1247b79ddb82c6e1518bc6e5e/src/styles/brackets_fonts.less. However, looking around, there are a bunch of places that assume that either SourceSansPro or SourceCodePro have been defined, and therefore downloaded:

@Pomax and/or @peterflynn, what's the best way to do this for the browser case? It's too bad that all the uses of font-family: SourceSansPro; and font-family: SourceCodePro; in the less files weren't being done with variables, font-family: @SourceSansPro; or the like.

Land upstream copy/paste patch in our fork

Brackets isn't enjoying when we completely overwrite the default html with new source code. It breaks hard and stops the preview process.

The console errors look like this:

data-brackets-id=8 not found
data-brackets-id=13 not found
data-brackets-id=12 not found

Remove the quickdocs extension

According to https://github.com/adobe/brackets/wiki/How-to-Use-Brackets#quick-edit (see the section on Quick Docs), you should be able to use Cmd+K or Ctrl+K to get documentation for the bit of html or css that you're mouse is sitting over. When I try, I see:

Unable to load CSS documentation database:  NotFoundmain.js:69
(anonymous function)jquery-2.1.3.min.js:2
n.Callbacks.jjquery-2.1.3.min.js:2 
n.Callbacks.k.fireWithjquery-2.1.3.min.js:2 
n.extend.Deferred.n.each.e.(anonymous function)FileUtils.js:85 
(anonymous function)File.js:112 
(anonymous function)FilerFileSystem.js:194 
(anonymous function)filer.js:6407 
completefiler.js:5615 
(anonymous function)filer.js:4466 
read_directory_datafiler.js:4126 
read_parent_directory_datafiler.js:4126 
read_parent_directory_datafiler.js:4126 
read_parent_directory_datafiler.js:4141 
get_node_from_parent_directory_datafiler.js:7066 
(anonymous function)filer.js:2263 (anonymous function)

The QuickDocs JSON is loaded lazily (i.e., only when you need it), and based on this stack, it looks like it's trying to get it directly from the filesystem. On desktop, with regular Brackets and a real OS filesystem, this will work fine. However, in the browser with Filer, we won't have that file in the fs at all.

Our options are to download the JSON files (there's probably more than one we need) in the background after the app starts if it's not already there, so that it will be there when it's requested. Right now we are using a RAM-backed filesystem, so it would mean having to do this every time. Other options include moving these JSON files into the require bundle and loading with the text plugin, or removing this feature altogether.

The css.json file is 390K. My vote is to rip this out, unless someone can figure out a solution.

Write extension for communication with the preview window

Thimble has sleeper code in friendlycode (inactive, disabled by a hidden preference) and it's previewloader that seems to allow two things:

  1. When a user clicks on an element in the editor, the previewwidow highlights the rendered element with added CSS
  2. When a user clicks on a rendered element in the previewwindow, the editor will scroll to that line and highlight the code

I may not have documented all of the code involved in this, but this is a feature that should eventually be replicated.

Reduce the size of jquery-ui

jQuery UI is being loaded for use in this file. This issue involves:

  1. Figuring out how it's being used, which probably means examining the jQuery UI docs
  2. Figure out how to replace the functionality it provides (if possible) or an alternative solution.

Deprecation warning in HTMLHinter's use of $().on()

We should deal with this deprecation warning:

Deprecated: Do not use $().on/off() on Brackets modules and model objects. Call on()/off() directly on the object without a $() wrapper.
    at new jQuery.fn.init (http://localhost:8000/src/brackets.js:472:36)
    at n (http://localhost:8000/src/thirdparty/jquery-2.1.3.min.js:2:405)
    at http://localhost:8000/src/extensions/default/HTMLHinter/main.js:103:9
    at _callHandler (http://localhost:8000/src/utils/AppInit.js:93:13)
    at Object._dispatchReady (http://localhost:8000/src/utils/AppInit.js:113:13)
    at Object.<anonymous> (http://localhost:8000/src/brackets.js:282:33)
    at n.Callbacks.j (http://localhost:8000/src/thirdparty/jquery-2.1.3.min.js:2:26911)
    at Object.n.Callbacks.k.fireWith [as resolveWith] (http://localhost:8000/src/thirdparty/jquery-2.1.3.min.js:2:27724)
    at Object.n.extend.Deferred.n.each.e.(anonymous function) (http://localhost:8000/src/thirdparty/jquery-2.1.3.min.js:2:28704)

Which is being caused by this:

   AppInit.appReady(function(){
        BottomDisplayVar = new BottomDisplay();
        $(EditorManager).on("activeEditorChange", activeEditorChangeHandler); // <----- here
    });

Reduce distribution size and load times for Bramble

There are a couple of things to do in this bug:

  • There is a lot that can be removed in Thimble that Brackets does instead
  • Figure out issues with Firefox loading a larger file size than Chrome
  • Follow up pruning of code that we will not use in Brackets

@sedge @humphd any thing to add?

Remove slowparse from thimble

We have two slowparse instances being loaded in super thimble because a single instance can't be shared between the iframe brackets lives in and the window containing it.

Therefore, the solution is to remove slowparse from friendlycode (thimble). Ideally, slowparse was only being kept outside of brackets because we hadn't looked closely enough at it, and it's not doing anything valuable. In this case, we can just remove it and prune any code that referenced it.

Otherwise we'll have to set up a slowparse proxy in a similar manner to our codemirror proxy.

Plug bramble into thimble in place of codemirror

This is a number of steps including:

  1. Tearing codemirror out of thimble's friendlycode module
  2. Putting bramble into an iframe in place of codemirror
  3. Building a postmessage based proxy system to trick friendlycode into thinking it's interacting with codemirror
  4. Building the other half of the proxy system as an extension for bramble

Deploy super-thimble somewhere accessible for testing

Our modified thimble is ready to be deployed. Ideally, it wouldn't be deployed into Webmaker proper, because we can't devote time to automating the process yet.

We were thinking heroku, and we need to know how best to make it usable. Can we hook it up to the rest of webmaker with environment variables? Can it stand alone without webmaker-core?

cc: @Pomax

[Brackets LiveDev] Error executing a handler for Runtime.evaluate

When I move my mouse over an <html> element in the editor, the live dev highlighting code blows up, I assume because it can't find an id for the element.:

 Runtime.evaluate
blob:http%3A//localhost%3A8000/fd6e91aa-c647-4742-a746-2d759e246aae:136 [Brackets LiveDev] Error executing a handler for Runtime.evaluate
blob:http%3A//localhost%3A8000/fd6e91aa-c647-4742-a746-2d759e246aae:137 TypeError: Cannot set property 'selector' of null
    at Object.highlightRule (blob:http%3A//localhost%3A8000/fd6e91aa-c647-4742-a746-2d759e246aae:1237:35)
    at eval (eval at <anonymous> (blob:http%3A//localhost%3A8000/fd6e91aa-c647-4742-a746-2d759e246aae:200:41), <anonymous>:1:5)
    at Runtime.evaluate (blob:http%3A//localhost%3A8000/fd6e91aa-c647-4742-a746-2d759e246aae:200:26)
    at blob:http%3A//localhost%3A8000/fd6e91aa-c647-4742-a746-2d759e246aae:133:25
    at Array.forEach (native)
    at Object.MessageBroker.trigger (blob:http%3A//localhost%3A8000/fd6e91aa-c647-4742-a746-2d759e246aae:130:29)
    at Object.ProtocolHandler.message (blob:http%3A//localhost%3A8000/fd6e91aa-c647-4742-a746-2d759e246aae:407:27)
    at blob:http%3A//localhost%3A8000/fd6e91aa-c647-4742-a746-2d759e246aae:47:37

Somewhat related to #44 I bet, and how the <html> element is being marked in the editor.

Fix JSHint issues introduced in browser-livedev extension

Running "jshint:src" (jshint) task
Linting src/extensions/default/brackets-browser-livedev/nohost/src/NoHostServer.js...ERROR
[L79:C17] W117: 'Log' is not defined.
                Log.error('unable to rewrite HTML for `' + path + '`');
Linting src/extensions/default/brackets-browser-livedev/nohost/src/NoHostServer.js...ERROR
[L81:C24] W117: 'handle404' is not defined.
                return handle404(path, callback);

Reduce size of dist/

Right now the Brackets code in dist/ (once we build it with grunt build) weighs in at 12.1M on the wire. This includes the HTML, minified JS and CSS, images, fonts, etc.

Looking at the list of things we load, there are some obvious places to start:

  • Get rid of any extensions we don't need from https://github.com/humphd/brackets/blob/bramble/src/utils/ExtensionLoader.js#L398-L420
  • Don't build/ship source maps for JS and CSS (it's ~5M)
  • Get rid of all the CodeMirror2 modes for languages we don't care about (they are all in dist/thirdparty/CodeMirror2/mode/). We probably only care about html, css, js, markdown, json, and xml to start with.
  • Investigate if there are other ways we can do our own custom build of CodeMirror2 to save space (i.e., those mode files aren't minified)
  • Figure out which parts of Brackets itself we can dump. For example, we don't need things like application auto-updating, installing new extensions, etc.

Brackets Extensions do not load within browser

Problem: Extensions do not appear to work in browser

Explaination: When running brackets with "python -m SimpleHTTPServer" or live-server, extensions within the browser do not appear to load.
To compound upon this, when trying to access the Extension Manager we receive this error:
screenshot 2015-01-26 12 54 19

Create in-browser Live Development infrastructure based on postMessage

Brackets recently started to evolve its LiveDevelopment feature to work in multiple browsers. The new architecture allows the editor to talk to a browser over a transport layer (currently WebSocket based) and communicate bi-directionally between the preview and editor document(s).

Our goal with Mozilla's editor for Thimble is to leverage this new architecture in order to create an in-browser editor with an in-browser livedev preview which substitute an iframe-based browser, a postMessage-based transport layer, and a nohost-based Blob URL Object server.

Accomplishing this will involve a bunch of things. I've started to make a list below, and I'm CC'ing @busykai for additional thoughts. This list is incomplete, but should get us started.

  • LiveDev needs to default to multi browser (i.e., the livedev.multibrowser pref should be true):

https://github.com/humphd/brackets/blob/bramble/src/LiveDevelopment/main.js#L77-L80

We can probably use PreferencesManager.set() in an extension to flip this to true at startup. We just need to make sure it happens early enough (i.e., before AppInit.appReady) so as to not miss the multibrowser init here:

https://github.com/humphd/brackets/blob/bramble/src/LiveDevelopment/main.js#L303-L314

  • Launch/open a browser to display the preview need to be altered:

https://github.com/humphd/brackets/blob/bramble/src/LiveDevelopment/LiveDevMultiBrowser.js#L517-L527

https://github.com/humphd/brackets/blob/bramble/src/LiveDevelopment/MultiBrowserImpl/launchers/Launcher.js#L47

We need to change that to not use Node, but to start the iframe-based browser. Maybe we should override the launcher, or maybe we should implement the various “open browser” bits of the appshell:

https://github.com/humphd/brackets/blob/bramble/src/thirdparty/browser-appshell.js#L74-L79

  • We need to create a LiveDevServer that implements enough of the LiveDevelopment/Servers/BaseServer base class. The FileServer is an example:

https://github.com/humphd/brackets/blob/bramble/src/LiveDevelopment/Servers/FileServer.js

We can do this in an extension. We then need to register this server with the LiveDevServerManager such that it has a high enough priority to always get used (e.g., 9001, which is higher than 0 or 99):

https://github.com/adobe/brackets/blob/14370aedfb6fdb7416a53cb0b7dc8d1a7bd7a5d4/src/LiveDevelopment/LiveDevelopment.js#L1482-L1484

  • We should be able to alter how URLs are created to our server, and instead create Blob URL Objects (i.e., override the pathToUrl method):

https://github.com/humphd/brackets/blob/bramble/src/LiveDevelopment/Servers/BaseServer.js#L92-L112

One issue to ponder is that we'll need to do this async (i.e., read path from fs), and pathToUrl is sync. The URL gets used with the launcher here:

https://github.com/adobe/brackets/blob/14370aedfb6fdb7416a53cb0b7dc8d1a7bd7a5d4/src/LiveDevelopment/LiveDevMultiBrowser.js#L537-L541

We can steal code from nohost to create the Blob URLs:

https://github.com/humphd/nohost/blob/master/src/handlers.js#L510-L530

Write deployment docs and script

Building and deploying Bramble is a multi-step process. It involves getting various repos set up, running various builds, collecting deps, etc.

We should document this, since I'm not sure everyone knows all the pieces (including me), and even better, we should write a script (maybe a custom Gruntfile?) that we use to automate the whole thing. This could include doing things like running bower/npm installs for various submodules we use (filer, filer-dialogs), etc.

Hack thimble to conceal the brackets editor until it's fully loaded

I'm not sure that there's a sane way to get brackets to load with panels hidden, rather than load with all of them visible and the user has to watch some disappear. Instead, I'm thinking Thimble should hide brackets as it loads and reveal it when it receives a postMessage from our HideUI extension saying "everything's ready!"

Write extension for context sensitive help

Thimble.webmaker.org gives technical advice about HTML elements, CSS selectors and CSS properties explaining their function and where to use them. When the editor's cursor is touching something it can advise on (e.g. screen shot 2015-01-26 at 11 35 25 am or screen shot 2015-01-26 at 11 36 20 am) an icon (screen shot 2015-01-26 at 11 39 00 am) appears on the opposite side of the gutter that can be clicked on to show help:


screen shot 2015-01-26 at 11 41 00 am


We need an extension that will provide this functionality.

Fix JSHint issues in bramble + bramble-extension code

Trying to run grunt build on our bramble branch fails with a million JSHint issues, mostly in our extension code. We need to get this all cleaned up so we can pass lint on travis, and get grunt to work for the build target.

In code we own, we should fix things. In code we don't own (e.g., slowparse) we should tell jshint to ignore the file completely.

Add unit testing to Super-Thimble

Test coverage of the new features and the proxy would be nice, and help us a lot now that we have more than one person actively developing it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.