Skip to content

Commit

Permalink
Ticket #212 - Finalize changes for bug where the editor should use th…
Browse files Browse the repository at this point in the history
…e content

in the textarea as the content in EpicEditor's editor if content exists in the
textarea on page load. Commit adds tests on this as well as notes in the docs.
It also pulls out the textarea option into a private (on the prototype) method
to clean up the load method.
  • Loading branch information
OscarGodson committed Apr 7, 2013
1 parent 49d21bf commit e667e94
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 108 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ var editor = new EpicEditor(opts);
</tr>
<tr>
<td><code>textarea</code></td>
<td>The ID (string) or element (object) of a textarea you would like to sync the editor's content with.</td>
<td>The ID (string) or element (object) of a textarea you would like to sync the editor's content with. On page load if there is content in the textarea, the editor will use that as it's content.</td>
<td></td>
</tr>
<tr>
Expand Down Expand Up @@ -140,7 +140,7 @@ var editor = new EpicEditor(opts);
</tr>
<tr>
<td><code>file.defaultContent</code></td>
<td>The content to show if no content exists for a file.</td>
<td>The content to show if no content exists for a file. NOTE: if the <code>textarea</code> option is used, the textarea's value will take precedence over <code>defaultContent</code>.</td>
<td></td>
</tr>
<tr>
Expand Down
96 changes: 60 additions & 36 deletions epiceditor/js/epiceditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@
, keypressTimer
, mousePos = { y: -1, x: -1 }
, _elementStates
, _syncTextarea
, _isInEdit
, nativeFs = false
, nativeFsWebkit = false
Expand All @@ -474,7 +473,6 @@
, isMod = false
, isCtrl = false
, eventableIframes
, textareaFileName
, i; // i is reused for loops

if (self.settings.useNativeFullscreen) {
Expand Down Expand Up @@ -605,6 +603,7 @@

utilBtns = self.iframe.getElementById('epiceditor-utilbar');

// TODO: Move into fullscreen setup function (_setupFullscreen)
_elementStates = {}
self._goFullscreen = function (el) {

Expand Down Expand Up @@ -799,6 +798,7 @@
}, false);
}

// TODO: Move utilBar stuff into a utilBar setup function (_setupUtilBar)
utilBar = self.iframe.getElementById('epiceditor-utilbar');

// Hide it at first until they move their mouse
Expand Down Expand Up @@ -902,6 +902,7 @@
}

// Save the document every 100ms by default
// TODO: Move into autosave setup function (_setupAutoSave)
if (self.settings.file.autoSave) {
self._saveIntervalTimer = window.setInterval(function () {
if (!self._canSave) {
Expand All @@ -914,40 +915,7 @@
// Update a textarea automatically if a textarea is given so you don't need
// AJAX to submit a form and instead fall back to normal form behavior
if (self.settings.textarea) {

// Even if autoSave is false, we want to make sure to keep the textarea synced
// with the editor's content. One bad thing about this tho is that we're
// creating two timers now in some configurations. We keep the textarea synced
// by saving and opening the textarea content from the draft file storage.
self._textareaSaveTimer = window.setInterval(function () {
if (!self._canSave) {
return;
}
self.save(true);
}, 100);

_syncTextarea = function () {
self._textareaElement.value = self.exportFile(textareaFileName, 'text', true);
}

textareaFileName = self.settings.file.name;

if (typeof self.settings.textarea == 'string') {
self._textareaElement = document.getElementById(self.settings.textarea);
}
else if (typeof self.settings.textarea == 'object') {
self._textareaElement = self.settings.textarea;
}

if (self._textareaElement.value !== '') {
self.importFile(textareaFileName, self._textareaElement.value);
}

// Update the textarea on load and pull from drafts
_syncTextarea();

// Make sure to keep it updated
self.on('__update', _syncTextarea);
self._setupTextareaSync();
}

window.addEventListener('resize', function () {
Expand Down Expand Up @@ -997,6 +965,62 @@
return this;
}

EpicEditor.prototype._setupTextareaSync = function () {
var self = this
, textareaFileName = self.settings.file.name
, _syncTextarea;

// Even if autoSave is false, we want to make sure to keep the textarea synced
// with the editor's content. One bad thing about this tho is that we're
// creating two timers now in some configurations. We keep the textarea synced
// by saving and opening the textarea content from the draft file storage.
self._textareaSaveTimer = window.setInterval(function () {
if (!self._canSave) {
return;
}
self.save(true);
}, 100);

_syncTextarea = function () {
self._textareaElement.value = self.exportFile(textareaFileName, 'text', true);
}

if (typeof self.settings.textarea == 'string') {
self._textareaElement = document.getElementById(self.settings.textarea);
}
else if (typeof self.settings.textarea == 'object') {
self._textareaElement = self.settings.textarea;
}

// On page load, if there's content in the textarea that means one of two
// different things:
//
// 1. The editor didn't load and the user was writing in the textarea and
// now he refreshed the page or the JS loaded and the textarea now has
// content. If this is the case the user probably expects his content is
// moved into the editor and not lose what he typed.
//
// 2. The developer put content in the textarea from some server side
// code. In this case, the textarea will take precedence.
//
// If the developer wants drafts to be recoverable they should check if
// the local file in localStorage's modified date is newer than the server.
if (self._textareaElement.value !== '') {
self.importFile(textareaFileName, self._textareaElement.value);

// manually save draft after import so there is no delay between the
// import and exporting in _syncTextarea. Without this, _syncTextarea
// will pull the saved data from localStorage which will be <=100ms old.
self.save(true);
}

// Update the textarea on load and pull from drafts
_syncTextarea();

// Make sure to keep it updated
self.on('__update', _syncTextarea);
}

/**
* Will remove the editor, but not offline files
* @returns {object} EpicEditor will be returned
Expand Down
2 changes: 1 addition & 1 deletion epiceditor/js/epiceditor.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ <h3>Options</h3>
</tr>
<tr>
<td><code>textarea</code></td>
<td>The ID (string) or element (object) of a textarea you would like to sync the editor&#39;s content with.</td>
<td>The ID (string) or element (object) of a textarea you would like to sync the editor&#39;s content with. On page load if there is content in the textarea, the editor will use that as it&#39;s content.</td>
<td></td>
</tr>
<tr>
Expand Down Expand Up @@ -143,7 +143,7 @@ <h3>Options</h3>
</tr>
<tr>
<td><code>file.defaultContent</code></td>
<td>The content to show if no content exists for a file.</td>
<td>The content to show if no content exists for a file. NOTE: if the <code>textarea</code> option is used, the textarea&#39;s value will take precedence over <code>defaultContent</code>.</td>
<td></td>
</tr>
<tr>
Expand Down
109 changes: 60 additions & 49 deletions src/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@
, keypressTimer
, mousePos = { y: -1, x: -1 }
, _elementStates
, _syncTextarea
, _isInEdit
, nativeFs = false
, nativeFsWebkit = false
Expand All @@ -474,7 +473,6 @@
, isMod = false
, isCtrl = false
, eventableIframes
, textareaFileName
, i; // i is reused for loops

if (self.settings.useNativeFullscreen) {
Expand Down Expand Up @@ -605,6 +603,7 @@

utilBtns = self.iframe.getElementById('epiceditor-utilbar');

// TODO: Move into fullscreen setup function (_setupFullscreen)
_elementStates = {}
self._goFullscreen = function (el) {

Expand Down Expand Up @@ -799,6 +798,7 @@
}, false);
}

// TODO: Move utilBar stuff into a utilBar setup function (_setupUtilBar)
utilBar = self.iframe.getElementById('epiceditor-utilbar');

// Hide it at first until they move their mouse
Expand Down Expand Up @@ -902,6 +902,7 @@
}

// Save the document every 100ms by default
// TODO: Move into autosave setup function (_setupAutoSave)
if (self.settings.file.autoSave) {
self._saveIntervalTimer = window.setInterval(function () {
if (!self._canSave) {
Expand All @@ -914,53 +915,7 @@
// Update a textarea automatically if a textarea is given so you don't need
// AJAX to submit a form and instead fall back to normal form behavior
if (self.settings.textarea) {

// Even if autoSave is false, we want to make sure to keep the textarea synced
// with the editor's content. One bad thing about this tho is that we're
// creating two timers now in some configurations. We keep the textarea synced
// by saving and opening the textarea content from the draft file storage.
self._textareaSaveTimer = window.setInterval(function () {
if (!self._canSave) {
return;
}
self.save(true);
}, 100);

_syncTextarea = function () {
self._textareaElement.value = self.exportFile(textareaFileName, 'text', true);
}

textareaFileName = self.settings.file.name;

if (typeof self.settings.textarea == 'string') {
self._textareaElement = document.getElementById(self.settings.textarea);
}
else if (typeof self.settings.textarea == 'object') {
self._textareaElement = self.settings.textarea;
}

// On page load, if there's content in the textarea that means one of two
// different things:
//
// 1. The editor didn't load and the user was writing in the textarea and
// now he refreshed the page or the JS loaded and the textarea now has
// content. If this is the case the user probably expects his content is
// moved into the editor and not lose what he typed.
//
// 2. The developer put content in the textarea from some server side
// code. In this case, the textarea will take precedence.
//
// If the developer wants drafts to be recoverable they should check if
// the local file in localStorage's modified date is newer than the server.
if (self._textareaElement.value !== '') {
self.importFile(textareaFileName, self._textareaElement.value);
}

// Update the textarea on load and pull from drafts
_syncTextarea();

// Make sure to keep it updated
self.on('__update', _syncTextarea);
self._setupTextareaSync();
}

window.addEventListener('resize', function () {
Expand Down Expand Up @@ -1010,6 +965,62 @@
return this;
}

EpicEditor.prototype._setupTextareaSync = function () {
var self = this
, textareaFileName = self.settings.file.name
, _syncTextarea;

// Even if autoSave is false, we want to make sure to keep the textarea synced
// with the editor's content. One bad thing about this tho is that we're
// creating two timers now in some configurations. We keep the textarea synced
// by saving and opening the textarea content from the draft file storage.
self._textareaSaveTimer = window.setInterval(function () {
if (!self._canSave) {
return;
}
self.save(true);
}, 100);

_syncTextarea = function () {
self._textareaElement.value = self.exportFile(textareaFileName, 'text', true);
}

if (typeof self.settings.textarea == 'string') {
self._textareaElement = document.getElementById(self.settings.textarea);
}
else if (typeof self.settings.textarea == 'object') {
self._textareaElement = self.settings.textarea;
}

// On page load, if there's content in the textarea that means one of two
// different things:
//
// 1. The editor didn't load and the user was writing in the textarea and
// now he refreshed the page or the JS loaded and the textarea now has
// content. If this is the case the user probably expects his content is
// moved into the editor and not lose what he typed.
//
// 2. The developer put content in the textarea from some server side
// code. In this case, the textarea will take precedence.
//
// If the developer wants drafts to be recoverable they should check if
// the local file in localStorage's modified date is newer than the server.
if (self._textareaElement.value !== '') {
self.importFile(textareaFileName, self._textareaElement.value);

// manually save draft after import so there is no delay between the
// import and exporting in _syncTextarea. Without this, _syncTextarea
// will pull the saved data from localStorage which will be <=100ms old.
self.save(true);
}

// Update the textarea on load and pull from drafts
_syncTextarea();

// Make sure to keep it updated
self.on('__update', _syncTextarea);
}

/**
* Will remove the editor, but not offline files
* @returns {object} EpicEditor will be returned
Expand Down
Loading

0 comments on commit e667e94

Please sign in to comment.