Firepad was designed to be embedded inside larger applications. Since it uses the Firebase Realtime Database as a backend it requires no server-side code and can be added to any web app simply by including the JavaScript files. Here we'll explain how to do this.
Firepad uses CodeMirror as the underlying text editor. If you'd like to use Ace as your code editor instead, skip to Getting Started with Ace.
In order to embed Firepad into your own application, you must first sign up for a free Firebase account. This will automatically create a new Firebase project for you whose config you will use below.
Include Firebase, CodeMirror, and Firepad in the <head> section of your page.
<!-- CodeMirror --> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.17.0/codemirror.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.17.0/codemirror.css" />
<!-- Firepad --> <link rel="stylesheet" href="https://firepad.io/releases/v1.5.10/firepad.css" /> <script src="https://firepad.io/releases/v1.5.10/firepad.min.js"></script>
To create a Firepad, you must initialize Firebase, CodeMirror and then Firepad. Here is a typical setup for rich-text editing:
<span class="c1">// Get Firebase Database reference.</span>
<span class="kd">var</span> <span class="nx">firepadRef</span> <span class="o">=</span> <span class="nx">firebase</span><span class="p">.</span><span class="nx">database</span><span class="p">().</span><span class="nx">ref</span><span class="p">();</span>
<span class="c1">// Create CodeMirror (with lineWrapping on).</span>
<span class="kd">var</span> <span class="nx">codeMirror</span> <span class="o">=</span> <span class="nx">CodeMirror</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">firepad</span><span class="dl">'</span><span class="p">),</span> <span class="p">{</span> <span class="na">lineWrapping</span><span class="p">:</span> <span class="kc">true</span> <span class="p">});</span>
<span class="c1">// Create Firepad (with rich text toolbar and shortcuts enabled).</span>
<span class="kd">var</span> <span class="nx">firepad</span> <span class="o">=</span> <span class="nx">Firepad</span><span class="p">.</span><span class="nx">fromCodeMirror</span><span class="p">(</span><span class="nx">firepadRef</span><span class="p">,</span> <span class="nx">codeMirror</span><span class="p">,</span> <span class="p">{</span>
<span class="na">richTextShortcuts</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="na">richTextToolbar</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="na">defaultText</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Hello, World!</span><span class="dl">'</span>
<span class="p">});</span>
<span class="p">}</span>
</script> </body>
Make sure to replace the contents of config
with your own Firebase project's config. Note that
you can easily store multiple Firepads in your Firebase Realtime Database by giving them each a
unique URL (e.g. https://<YOUR FIREBASE>/firepads/<unique id>
).
See the API section below for details on Firepad.fromCodeMirror()
and the methods / events it provides.
You can check out codemirror.net for details on CodeMirror's API
(for turning on/off line numbers, line wrapping, code syntax highlighting, etc.).
To customize the size / position of the Firepad or customize its look and feel, you can use CSS:
/ Note: CodeMirror applies its own styles which can be customized in the same way. To apply a background to the entire editor, we need to also apply it to CodeMirror. / .CodeMirror { background-color: #f62; }
The toolbar and other aspects can also be customized. Take a look at firepad.css for a starting point.
To use Ace as the underlying code editor, follow the steps below. Note that you cannot use Firepad with Ace for rich-text editing. If you want rich-text editing, go to Getting Started with CodeMirror instead.
In order to embed Firepad into your own application, you must first sign up for a free Firebase account. This will automatically create a new Firebase project for you whose config you will use below.
Include Firebase, Ace, and Firepad in the <head> section of your page.
<!-- Ace --> <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.5/ace.js"></script>
<!-- Firepad --> <link rel="stylesheet" href="https://firepad.io/releases/v1.5.10/firepad.css" /> <script src="https://firepad.io/releases/v1.5.10/firepad.min.js"></script>
To create a Firepad, you must initialize Firebase, Ace and then Firepad. Here is a typical setup for code editing with Ace:
<span class="c1">// Get Firebase Database reference.</span>
<span class="kd">var</span> <span class="nx">firepadRef</span> <span class="o">=</span> <span class="nx">firebase</span><span class="p">.</span><span class="nx">database</span><span class="p">().</span><span class="nx">ref</span><span class="p">();</span>
<span class="c1">// Create Ace editor.</span>
<span class="kd">var</span> <span class="nx">editor</span> <span class="o">=</span> <span class="nx">ace</span><span class="p">.</span><span class="nx">edit</span><span class="p">(</span><span class="dl">'</span><span class="s1">firepad</span><span class="dl">'</span><span class="p">);</span>
<span class="c1">// Create Firepad.</span>
<span class="kd">var</span> <span class="nx">firepad</span> <span class="o">=</span> <span class="nx">Firepad</span><span class="p">.</span><span class="nx">fromACE</span><span class="p">(</span><span class="nx">firepadRef</span><span class="p">,</span> <span class="nx">editor</span><span class="p">);</span>
<span class="p">}</span>
</script> </body>
Make sure to replace the contents of config
with your own Firebase project's config. Note that
you can easily store multiple Firepads in your Firebase Realtime Database by giving them each a
unique URL (e.g. https://<YOUR FIREBASE>/firepads/<unique id>
).
See the API section below for details on Firepad.fromACE()
and the methods / events
it provides. You can check out [Ace] (http://ace.c9.io/) for details on Ace's API (for setting themes,
line highlighting, etc.)
To customize the size / position of the Firepad or customize its look and feel, you can use CSS:
Firepad.fromCodeMirror(firebaseRef, codeMirror, options)
Creates a new Firepad from the specified CodeMirror instance using the specified Firebase location to store data. The options hash can be used to customize behavior.
Available Options:
richTextToolbar
(default: false) - Adds a toolbar with buttons for bold, italic, etc.richTextShortcuts
(default: false) - Maps Ctrl-B to bold, etc.userId
(default: random) - The user ID for the person editing.userColor
(default: generated from userId) - A css color (e.g. "#ccc") for this user's cursor.defaultText
(default: null) - Text to initialize the Firepad with if history is empty.
Firepad.fromACE(firebaseRef, ace, options)
Creates a new Firepad from the specified Ace instance using the specified Firebase location to store data. The options hash can be used to customize behavior.
Available Options:
userId
(default: random) - The user ID for the person editing.userColor
(default: generated from userId) - A css color (e.g. "#ccc") for this user's cursor.defaultText
(default: null) - Text to initialize the Firepad with if history is empty.
firepad.on(eventType, callback);
Attaches a callback for the given event type. There are two events available for listening.
The first, 'ready' fires once Firepad has retrieved the initial editor contents. You must wait for this event to fire before calling any other methods.
The second, 'synced', is fired when your local client edits the document and when those edits have been successfully written to Firebase.
firepad.off(eventType, callback)
Removes the specified callback for the specified event type.
firepad.getText()
Returns the current contents of Firepad as a string.
firepad.setText(text)
Sets the contents of Firepad as a string.
firepad.getHtml()
Gets the contents of Firepad as HTML.
firepad.setHtml(text)
Sets the contents of Firepad as HTML.
firepad.isHistoryEmpty()
Returns true if the Firepad has never had any content. Useful for doing first-time initialization if defaultText is not specified.
firepad.setUserId(userId)
Sets the user id to use for writing operations and storing cursor data.
firepad.setUserColor(color)
Sets the color (as a css color, e.g. "#333") to use for this user's cursor.
firepad.dispose()
Cleans everything up (clears presence data, DOM elements, Firebase listeners etc.) and returns CodeMirror to its original state.
firepad.insertEntity(type, attributes, origin)
Inserts an entity of the specified type and with the specified attributes dictionary. To insert images, type = 'img' and attributes must contain 'src'; other attributes that can be provided are 'alt', 'width', 'height', 'style' and 'class'.
Firepad also provides a headless mode for interacting with documents without a GUI. It runs in either NodeJS or the browser. In the former case, simply install the firepad
npm module:
npm install firepad
and in your code:
Alternatively, you can load Headless Firepad with a Firebase ref you create on your own. This is useful if you need to use push()
to create a Firebaes Database reference or if you need to do any
custom authentication.
In Node.js, you'll also have to npm install firebase
, and then:
// Initialize Firebase. // TODO: replace with your Firebase project configuration. var config = { apiKey: "<API_KEY>", authDomain: "<AUTH_DOMAIN>.firebaseapp.com", databaseURL: "https://<DATABASE_NAME>.firebaseio.com" }; firebase.initializeApp(config);
var rootRef = firebase.database().ref(); var firepadRef = rootRef.push(); var headless = new Firepad.Headless(firepadRef);
Headless supports a few methods with similar call signatures as regular Firepad, with the notable addition of a callback parameter.
headless.getText(callback)
and headless.getHtml(callback)
both function as follows:
headless.setText(text, callback)
and headless.setHtml(html, callback)
as well:
When you don't need it any more, you should explicitly destroy it:
If you just drop your references to the Headless
object without calling dispose()
, it will still listen to any changes in the underlying Firebase data and apply the changes in-memory. Besides a memory leak you'll have a bandwidth and CPU leak.
Firepad uses the Firebase Realtime Database for its data storage and synchronization. This means you don't need to run any server code and you benefit from all the features of the Firebase Database (first-class data security, data accessibility, automatic scaling, etc.). It also means you own all of the data and can interact with it in a variety of ways.
Firepad stores your data at the Firebase Database location you specify using the following data structure:
users/
<user id>/
- You can specify this when initializing Firepad, else it will be random.
cursor
- The location of the user's cursor (and selection).color
- The CSS color (e.g. "#2043df") for the user's cursor.history/
- The sequence of revisions that make up the document.
<revision id>/
a
- userid of the user that made the revision.o/
- array of operations that make up the revision. See
text-operation.js for details.checkpoint/
a
- userid of the user that created the checkpoint.rev
- revision at the time the checkpoint was taken.op/
- array of operations that made up the document at that revision.You may find it useful to interact directly with the Firebase data when building related features on your site. For
example, the user list shown in the Firepad examples monitors the user data stored by Firepad and even adds its own
name
data when you pick a username.
See the code or view the data in the Firebase console (just enter your Firebase Database URL in a browser) for more details.
To lock down your Firepad data, you can use the Firebase Database's built-in Security Rules. For some example Security Rules, see these example rules on GitHub.
Firepad is an open source project and is meant to be extended and customized. We'd love for the community to help add support for more editors, extend the rich text capabilities, etc. If you want to take the plunge, all of the instructions to check out the code and start modifying it are in the README on the Firepad GitHub repo. Check it out!
This website is also open source and is checked into the gh-pages branch of the Firepad repository. Most of it is static HTML, but the docs page is generated from Markdown using jekyll.