зеркало из https://github.com/mozilla/FlightDeck.git
removed MooTools dependencies for FDEditor and Ace Editor
This commit is contained in:
Родитель
be4ff9b116
Коммит
0549f127b0
|
@ -385,10 +385,6 @@ module.exports = new Class({
|
|||
},
|
||||
|
||||
setupButtonTooltips: function() {
|
||||
if(typeof FloatingTips === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.tips = new FloatingTips('.UI_Editor_Menu .UI_Editor_Menu_Button', {
|
||||
position: 'top',
|
||||
balloon: true
|
||||
|
|
|
@ -5,151 +5,156 @@
|
|||
* Class: FDEditor
|
||||
*/
|
||||
var Class = require('shipyard/class/Class'),
|
||||
object = require('shipyard/utils/object'),
|
||||
ace = require('ace/ace'),
|
||||
FDEditor = require('./FDEditor');
|
||||
object = require('shipyard/utils/object'),
|
||||
log = require('shipyard/utils/log'),
|
||||
ace = require('ace/ace'),
|
||||
FDEditor = require('./FDEditor');
|
||||
|
||||
// globals: Spinner
|
||||
var JSMode = require('ace/modes/javascript').Mode,
|
||||
CSSMode = require('ace/modes/css').Mode,
|
||||
HTMLMode = require('ace/modes/html').Mode,
|
||||
TextMode = require('ace/modes/txt').Mode;
|
||||
|
||||
var Modes = {
|
||||
'javascript': new JSMode(),
|
||||
'css': new CSSMode(),
|
||||
'html': new HTMLMode(),
|
||||
'txt': new TextMode()
|
||||
};
|
||||
|
||||
var stripDeltas = function(stack) {
|
||||
// Change Stack (undo/redo) in Ace is represented as
|
||||
// [[DeltaObject1], [DeltaObject2], ... ]
|
||||
// these objects have to be copied - not referenced
|
||||
var deltas = [];
|
||||
stack.each(function(single){
|
||||
deltas.push(object.merge({}, single[0]));
|
||||
});
|
||||
return deltas;
|
||||
// Change Stack (undo/redo) in Ace is represented as
|
||||
// [[DeltaObject1], [DeltaObject2], ... ]
|
||||
// these objects have to be copied - not referenced
|
||||
var deltas = [];
|
||||
stack.each(function(single){
|
||||
deltas.push(object.merge({}, single[0]));
|
||||
});
|
||||
return deltas;
|
||||
};
|
||||
|
||||
var buildStack = function(deltas) {
|
||||
// Extract stored deltas into the stack
|
||||
var stack = [];
|
||||
deltas.each(function(delta){
|
||||
stack.push([object.merge({}, delta)]);
|
||||
});
|
||||
return stack;
|
||||
// Extract stored deltas into the stack
|
||||
var stack = [];
|
||||
deltas.each(function(delta){
|
||||
stack.push([object.merge({}, delta)]);
|
||||
});
|
||||
return stack;
|
||||
};
|
||||
|
||||
module.exports = new Class({
|
||||
|
||||
Extends: FDEditor,
|
||||
Extends: FDEditor,
|
||||
|
||||
options: {
|
||||
element_type: 'div'
|
||||
},
|
||||
options: {
|
||||
element_type: 'div'
|
||||
},
|
||||
|
||||
modes: {},
|
||||
modes: {},
|
||||
|
||||
available_modes: ['js', 'txt', 'html', 'css'],
|
||||
available_modes: ['js', 'txt', 'html', 'css'],
|
||||
|
||||
default_kind: 'txt',
|
||||
default_kind: 'txt',
|
||||
|
||||
mode_translate: {
|
||||
'js': 'javascript',
|
||||
'txt': 'text'
|
||||
},
|
||||
mode_translate: {
|
||||
'js': 'javascript',
|
||||
'txt': 'text'
|
||||
},
|
||||
|
||||
initialize: function(wrapper, options) {
|
||||
this.parent(wrapper, options);
|
||||
this.editor = ace.edit(this.element);
|
||||
this.editor.getSession().setUseWorker(false);
|
||||
this.spinner = new Spinner(this.element.getElement('.ace_scroller'), {
|
||||
maskBorder: false
|
||||
});
|
||||
var that = this;
|
||||
|
||||
['blur', 'focus'].each(function(ev) {
|
||||
that.editor.on(ev, function(){
|
||||
that.fireEvent(ev);
|
||||
});
|
||||
});
|
||||
},
|
||||
initialize: function(wrapper, options) {
|
||||
this.parent(wrapper, options);
|
||||
this.editor = ace.edit(this.element.getNode());
|
||||
this.editor.getSession().setUseWorker(false);
|
||||
this.spinner = this.element.getElement('.ace_scroller');
|
||||
|
||||
addMode: function(mode) {
|
||||
var name;
|
||||
var Mode;
|
||||
if (!this.modes[mode]) {
|
||||
name = mode;
|
||||
if (this.mode_translate[mode]) {
|
||||
name = this.mode_translate[mode];
|
||||
}
|
||||
//TODO: explicitly require the modes we plan to use up
|
||||
//above, so that they can be bundled with `shipyard build`
|
||||
Mode = require('ace/mode/' + name).Mode;
|
||||
this.modes[mode] = new Mode();
|
||||
}
|
||||
},
|
||||
var that = this;
|
||||
|
||||
['blur', 'focus'].each(function(ev) {
|
||||
that.editor.on(ev, function(){
|
||||
that.emit(ev);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
setEditable: function() {
|
||||
this.editor.setReadOnly(false);
|
||||
this.hookChangeIfNeeded();
|
||||
},
|
||||
|
||||
setReadOnly: function() {
|
||||
this.editor.setReadOnly(true);
|
||||
if (this.change_hooked) {
|
||||
this.unhookChange();
|
||||
}
|
||||
},
|
||||
|
||||
hookChange: function(){
|
||||
// hook to onChange Event
|
||||
this.editor.getSession().on('change', this.boundWhenItemChanged);
|
||||
this.change_hooked = true;
|
||||
},
|
||||
setEditable: function() {
|
||||
this.editor.setReadOnly(false);
|
||||
this.hookChangeIfNeeded();
|
||||
},
|
||||
|
||||
setReadOnly: function() {
|
||||
this.editor.setReadOnly(true);
|
||||
if (this.change_hooked) {
|
||||
this.unhookChange();
|
||||
}
|
||||
},
|
||||
|
||||
hookChange: function(){
|
||||
// hook to onChange Event
|
||||
this.editor.getSession().on('change', this.boundWhenItemChanged);
|
||||
this.change_hooked = true;
|
||||
},
|
||||
|
||||
unhookChange: function(){
|
||||
// unhook the onChange Event
|
||||
this.editor.getSession().removeEventListener('change', this.boundWhenItemChanged);
|
||||
this.change_hooked = false;
|
||||
},
|
||||
unhookChange: function(){
|
||||
// unhook the onChange Event
|
||||
this.editor.getSession().removeEventListener('change', this.boundWhenItemChanged);
|
||||
this.change_hooked = false;
|
||||
},
|
||||
|
||||
getContent: function(){
|
||||
var value = this.editor.getSession().getValue();
|
||||
return value;
|
||||
},
|
||||
getContent: function(){
|
||||
var value = this.editor.getSession().getValue();
|
||||
return value;
|
||||
},
|
||||
|
||||
_setContent: function(value){
|
||||
this.editor.getSession().setValue(value);
|
||||
var cursor = this.current.cursorPos || { row: 0, column: 0 };
|
||||
this.editor.selection.moveCursorTo(cursor.row, cursor.column);
|
||||
},
|
||||
_setContent: function(value){
|
||||
this.editor.getSession().setValue(value);
|
||||
var cursor = this.current.cursorPos || { row: 0, column: 0 };
|
||||
this.editor.selection.moveCursorTo(cursor.row, cursor.column);
|
||||
},
|
||||
|
||||
getUndoRedoStack: function() {
|
||||
var current_manager = this.editor.getSession().getUndoManager();
|
||||
return {
|
||||
redoDeltas: stripDeltas(current_manager.$redoStack),
|
||||
undoDeltas: stripDeltas(current_manager.$undoStack)
|
||||
};
|
||||
},
|
||||
setUndoRedoStack: function(obj){
|
||||
var current_manager = this.editor.getSession().getUndoManager();
|
||||
current_manager.$redoStack = buildStack(obj.redoDeltas);
|
||||
current_manager.$undoStack = buildStack(obj.undoDeltas);
|
||||
},
|
||||
getUndoRedoStack: function() {
|
||||
var current_manager = this.editor.getSession().getUndoManager();
|
||||
return {
|
||||
redoDeltas: stripDeltas(current_manager.$redoStack),
|
||||
undoDeltas: stripDeltas(current_manager.$undoStack)
|
||||
};
|
||||
},
|
||||
setUndoRedoStack: function(obj){
|
||||
var current_manager = this.editor.getSession().getUndoManager();
|
||||
current_manager.$redoStack = buildStack(obj.redoDeltas);
|
||||
current_manager.$undoStack = buildStack(obj.undoDeltas);
|
||||
},
|
||||
|
||||
dumpCurrent: function() {
|
||||
// dump undo buffers
|
||||
this.current.undo_manager = this.getUndoRedoStack();
|
||||
this.current.cursorPos = this.editor.selection.getCursor();
|
||||
this.parent();
|
||||
},
|
||||
dumpCurrent: function() {
|
||||
// dump undo buffers
|
||||
this.current.undo_manager = this.getUndoRedoStack();
|
||||
this.current.cursorPos = this.editor.selection.getCursor();
|
||||
this.parent();
|
||||
},
|
||||
|
||||
activateItem: function(item) {
|
||||
this.parent(item);
|
||||
// load undo buffers
|
||||
if (this.current.undo_manager) {
|
||||
this.setUndoRedoStack(this.current.undo_manager);
|
||||
}
|
||||
},
|
||||
activateItem: function(item) {
|
||||
this.parent(item);
|
||||
// load undo buffers
|
||||
if (this.current.undo_manager) {
|
||||
this.setUndoRedoStack(this.current.undo_manager);
|
||||
}
|
||||
},
|
||||
|
||||
setSyntax: function(kind){
|
||||
if (!this.available_modes.contains(kind)) {
|
||||
kind = this.default_kind;
|
||||
}
|
||||
this.addMode(kind);
|
||||
this.editor.getSession().setMode(this.modes[kind]);
|
||||
}
|
||||
setSyntax: function(kind){
|
||||
if (this.available_modes.indexOf(kind) === -1) {
|
||||
log.info('Mode (%s) not found. Using txt mode.', kind);
|
||||
kind = this.default_kind;
|
||||
} else if (this.mode_translate[kind]) {
|
||||
kind = this.mode_translate[kind];
|
||||
}
|
||||
|
||||
if (!Modes[kind]) {
|
||||
// This should only ever be the case if above is broken.
|
||||
// ie, available_modes and mode_translate aren't in sync
|
||||
// with Modes at the top.
|
||||
log.warn('Mode (%s) not found. Bad.');
|
||||
kind = this.default_kind;
|
||||
}
|
||||
this.editor.getSession().setMode(Modes[kind]);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -7,49 +7,48 @@
|
|||
* Otherwise standard textarea will be used.
|
||||
*/
|
||||
var Class = require('shipyard/class/Class'),
|
||||
Events = require('shipyard/class/Events'),
|
||||
Options = require('shipyard/class/Options'),
|
||||
object = require('shipyard/utils/object');
|
||||
Events = require('shipyard/class/Events'),
|
||||
Options = require('shipyard/class/Options'),
|
||||
dom = require('shipyard/dom'),
|
||||
object = require('shipyard/utils/object'),
|
||||
log = require('shipyard/utils/log');
|
||||
|
||||
// globals: Element, Spinner, fd
|
||||
var LOADING_CLASS = 'loading';
|
||||
|
||||
var FDEditor = module.exports = new Class({
|
||||
|
||||
Implements: [Options, Events],
|
||||
Implements: [Options, Events],
|
||||
|
||||
options: {
|
||||
element_type: 'textarea'
|
||||
},
|
||||
|
||||
$name: 'FlightDeckEditor',
|
||||
|
||||
items: {},
|
||||
|
||||
current: false,
|
||||
|
||||
initialize: function(wrapper, options) {
|
||||
this.setOptions(options);
|
||||
initialize: function(wrapper, options) {
|
||||
this.setOptions(options);
|
||||
wrapper = this.spinner = dom.$(wrapper);
|
||||
// create empty editor
|
||||
this.element = new Element(this.options.element_type,{
|
||||
this.element = new dom.Element(this.options.element_type,{
|
||||
'text': '',
|
||||
'class': 'UI_Editor_Area'
|
||||
});
|
||||
this.element.inject(wrapper);
|
||||
this.spinner = new Spinner('editor-wrapper');
|
||||
this.changed = false;
|
||||
wrapper.appendChild(this.element);
|
||||
this.changed = false;
|
||||
// prepare change events
|
||||
this.boundWhenItemChanged = this.whenItemChanged.bind(this);
|
||||
this.boundSetContent = this.setContent.bind(this);
|
||||
this.addEvent('setContent', function(c) {
|
||||
this.emit('setContent', function(c) {
|
||||
this.switching = false;
|
||||
});
|
||||
},
|
||||
|
||||
registerItem: function(uid, item){
|
||||
this.items[uid] = item;
|
||||
this.items[uid] = item;
|
||||
var editor = this;
|
||||
item.observe('uid', function(updated, old) {
|
||||
$log('uid changed for registed item:' + updated);
|
||||
editor.items[updated] = item;
|
||||
delete editor[old];
|
||||
});
|
||||
|
@ -60,7 +59,7 @@ var FDEditor = module.exports = new Class({
|
|||
},
|
||||
|
||||
deactivateCurrent: function(){
|
||||
// deactivate and store changes
|
||||
// deactivate and store changes
|
||||
this.current.active = false;
|
||||
// store changes
|
||||
this.dumpCurrent();
|
||||
|
@ -72,10 +71,10 @@ var FDEditor = module.exports = new Class({
|
|||
this.current = item;
|
||||
this.current.active = true;
|
||||
if (!this.current.isLoaded()) {
|
||||
this.spinner.show();
|
||||
this.setContent('', true);
|
||||
this.spinner.addClass(LOADING_CLASS);
|
||||
this.setContent('', true);
|
||||
this.current.loadContent(function(content) {
|
||||
if (item == editor.current) {
|
||||
if (item === editor.current) {
|
||||
editor.setContent(content);
|
||||
editor.spinner.hide();
|
||||
}
|
||||
|
@ -83,7 +82,7 @@ var FDEditor = module.exports = new Class({
|
|||
});
|
||||
} else {
|
||||
this.setContent(this.current.get('content'));
|
||||
this.spinner.hide();
|
||||
this.spinner.removeClass(LOADING_CLASS);
|
||||
}
|
||||
if (this.current.get('readonly')) {
|
||||
this.setReadOnly();
|
||||
|
@ -94,13 +93,13 @@ var FDEditor = module.exports = new Class({
|
|||
},
|
||||
|
||||
switchTo: function(uid){
|
||||
$log('FD: DEBUG: FDEditor.switchTo ' + uid);
|
||||
log.debug('FDEditor.switchTo ' + uid);
|
||||
var self = this;
|
||||
this.switching = true;
|
||||
var item = this.getItem(uid);
|
||||
if (!item) {
|
||||
//this.registerItem(item);
|
||||
$log('no item wtf');
|
||||
log.error('No item found in Editor with uid:', uid);
|
||||
}
|
||||
if (this.current) {
|
||||
this.deactivateCurrent();
|
||||
|
@ -122,8 +121,8 @@ var FDEditor = module.exports = new Class({
|
|||
},
|
||||
|
||||
setEditable: function() {
|
||||
if (this.element.get('readonly')) {
|
||||
this.element.erase('readonly');
|
||||
if (this.element.get('readonly')) {
|
||||
this.element.set('readonly', null);
|
||||
}
|
||||
this.hookChangeIfNeeded();
|
||||
},
|
||||
|
@ -149,21 +148,21 @@ var FDEditor = module.exports = new Class({
|
|||
},
|
||||
|
||||
hookChange: function(){
|
||||
this.element.addEvent('keyup', this.boundWhenItemChanged);
|
||||
this.element.addListener('keyup', this.boundWhenItemChanged);
|
||||
this.change_hooked = true;
|
||||
},
|
||||
},
|
||||
|
||||
unhookChange: function(){
|
||||
this.element.removeEvent('keyup', this.boundWhenItemChanged);
|
||||
this.change_hooked = false;
|
||||
$log('FD: INFO: No longer following changes');
|
||||
log.info('No longer following changes');
|
||||
},
|
||||
|
||||
whenItemChanged: function() {
|
||||
if (!this.switching && this.getContent() != this.current.original_content) {
|
||||
if (!this.switching && this.getContent() !== this.current.original_content) {
|
||||
this.current.setChanged(true);
|
||||
this.fireEvent('change');
|
||||
$log('DEBUG: changed, code is considered dirty and will remain'+
|
||||
this.emit('change');
|
||||
log.debug('changed, code is considered dirty and will remain'+
|
||||
'be treated as such even if changes are reverted');
|
||||
this.unhookChange();
|
||||
} else if (!this.switching && this.current.changed) {
|
||||
|
@ -171,19 +170,21 @@ var FDEditor = module.exports = new Class({
|
|||
}
|
||||
},
|
||||
|
||||
getContent: function() {
|
||||
return this.element.value;
|
||||
},
|
||||
getContent: function() {
|
||||
return this.element.value;
|
||||
},
|
||||
|
||||
setContent: function(value, quiet) {
|
||||
setContent: function(value, quiet) {
|
||||
this._setContent(value);
|
||||
if (!quiet) this.fireEvent('setContent', value);
|
||||
return this;
|
||||
},
|
||||
|
||||
_setContent: function(value) {
|
||||
this.element.set('value', value);
|
||||
},
|
||||
if (!quiet) {
|
||||
this.emit('setContent', value);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
_setContent: function(value) {
|
||||
this.element.set('value', value);
|
||||
},
|
||||
|
||||
isChanged: function() {
|
||||
return this.items.some(function(item) {
|
||||
|
@ -192,14 +193,14 @@ var FDEditor = module.exports = new Class({
|
|||
},
|
||||
|
||||
setSyntax: function(){},
|
||||
|
||||
focus: function() {
|
||||
this.editor.focus();
|
||||
this.fireEvent('focus');
|
||||
},
|
||||
|
||||
blur: function() {
|
||||
this.editor.blur();
|
||||
this.fireEvent('blur');
|
||||
}
|
||||
|
||||
focus: function() {
|
||||
this.editor.focus();
|
||||
this.emit('focus');
|
||||
},
|
||||
|
||||
blur: function() {
|
||||
this.editor.blur();
|
||||
this.emit('blur');
|
||||
}
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче