/jotted

Environment for showcasing HTML, CSS and JavaScript, with editable source.

Primary LanguageJavaScriptMIT LicenseMIT

Jotted

Build Status

Environment for showcasing HTML, CSS and JavaScript, with editable source. It's like JSFiddle or JS Bin for self-hosted demos.

Install

<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/jotted@latest/jotted.min.css">
<script src="https://cdn.jsdelivr.net/npm/jotted@latest/jotted.min.js"></script>

Features

  • Lightweight: No dependencies, uses textareas for editing by default.
  • Plugins: Flexible plugin architecture for custom editors, preprocessors or anything else.
  • Code editors: Includes plugins for code editors like Ace and CodeMirror.
  • Preprocessors: Includes plugins for preprocessors (ES6, CoffeeScript, Less, Stylus, Markdown).

How to use

Quick use

<link rel="stylesheet" href="jotted.css">
<script src="jotted.js"></script>

<div id="editor"></div>
<script>
  new Jotted(document.querySelector('#editor'), {
    files: [{
      type: 'html',
      url: 'index.html'
    }]
  })
</script>

Options

Initialize Jotted with new Jotted(elementNode, optionsHash).

The first argument is a DOM container where the editor will be created. The second argument is a hash of options.

Available options are:

files

Type: Array Default: []

Array of Objects specifying files that will be loaded. Objects inside the array must follow this pattern:

{
  type: "html", // can be "html", "css", or "js"
  url: "/index.html", // load the file from a url (restricted by the same-domain policy), OR
  content: "<h1>HTML Content</h1>" // insert file content as string
}

Use either url or content, not both.

showBlank

Type: Boolean Default: false

Specifies if panes/tabs without content/files should be visible.

runScripts

Type: Boolean Default: true

Specifies if script tags inside HTML content should be ran.

pane

Type: String Default: result

Specifies which pane/tab should be the default one opened. Can be result, html, css or js.

debounce

Type: Number Default: 250

Sets the debounce interval used by the change event (eg. render changes in the Result pane after a change in an editor).

plugins

Type: Array Default: []

Array of Strings or Objects setting the plugins used by this editor instance.

If String, specify plugin name.

If Object, follow this pattern:

{
  name: 'less', // plugin name
  options: {} // options hash to be passed to plugin
}

Example

new Jotted(document.querySelector('#demo'), {
  files: [{
    type: 'css',
    url: 'index.styl'
  }, {
    type: 'html',
    content: '<h1>Demo</h1>'
  }],
  showBlank: true,
  plugins: [
    'stylus',
    {
      name: 'codemirror',
      options: {
        lineNumbers: false
      }
    }
  ]

Plugins

Editors

  • ace: Uses the Ace editor if it's available.
  • codemirror: Uses the CodeMirror editor if it's available.

Preprocessors

  • babel: Compiles ES6 to ES5 with Babel.
  • coffeescript: Compiles CoffeeScript.
  • less: Compiles Less.
  • markdown: Compiles Markdown using marked.
  • stylus: Compiles Stylus.

Other

  • console: Lightweight JavaScript console, similar to the one in the browser's developer tools.

Plugin API

You can quickly create Jotted plugins with:

Jotted.plugin('demoPlugin', function (jotted, options) {
  // do stuff
});

A plugin is a constructor function that will be called with new when a Jotted instance using the plugin is initialized.

The plugin function gets two arguments:

  • The first argument is the current Jotted instance.
  • The second argument is the plugin's hash of options.

Events API

The Jotted instance exposes a PubSub-like API, for attaching custom plugin-specific events.

on (eventName, function(params, callback) {}, priority)

Use the on method to attach methods to an event.

  • The first argument is a String event name. Jotted only uses the change event internally.

  • The second argument is a subscriber Function.

Unlike most PubSub systems, subscriber functions are run sequentially, not in parallel. This allows a function to modify the parameters received from a different, previously run, function, and pass them on.

The functions gets two arguments. The first one is a hash with the format:

{
  file: 'index.html', // changed file's url, if specified
  content: '<h1>Demo</h1>' // file's content
}

The second one is a callback that should be called with two arguments: an error object, if there was an error, and the params object received by the subscriber.

You can modify the params object before sending it with the callback.

jotted.on('change', function (params, callback) {
  params.content += 'Content added by plugin.'
  callback(null, params)
})

Remember to always call the callback in the function, or the queue will break.

  • The third argument is an optional Number, specifying the function's place in the queue. Functions are sorted based on their priority. If the priority is not specified, the method will be placed at the end of the queue.

off (eventName, subscriberFunction)

Use the off method to remove a subscriber function from an event.

var subscriber = function (params, callback) {}
jotted.on('change', subscriber)
jotted.off('change', subscriber)

trigger (eventName, params)

Use the trigger method to trigger the function queue on an event.

The first argument is the event name, while the second is the params hash sent to the attached subscriber functions.

jotted.trigger('change', {
  type: 'html', // can be 'html', 'css' or 'js'
  file: 'index.html', // file url
  content: '<h1>Demo</h1>' // file content
})

done (eventName, function(errors, params) {})

Use the done method to trigger a function once an event queue has finished.

The first argument is the event name, while the second is a Function receiving an Array of errors and the params hash.

jotted.done('done', function (errs, params) {
  if (errs.length) {
    // show errors
  }
})

Examples

For a preprocessor plugin, see the less plugin.

For a code editor plugin, see the codemirror plugin.

Browser support

  • Internet Explorer 9+
  • Modern browsers

Contributing

  • Install Node.js and npm.
  • Install grunt-cli.
  • Run npm install in the project folder.
  • Run grunt server for a live-reload server with everything you need.
  • Use ES2015.
  • Follow the JavaScript Standard Style.
  • Send pull requests.
  • Thanks! 🍻

Who's using it

License

Jotted is licensed under the MIT license.